From: Marc Fiuczynski <mef@cs.princeton.edu>
Date: Mon, 13 Nov 2006 15:58:54 +0000 (+0000)
Subject: Initial revision
X-Git-Tag: before-fedora-2_6_18-1_2239_FC5-vs2_0_2_2-rc6-merge~5
X-Git-Url: http://git.onelab.eu/?a=commitdiff_plain;h=2bc4a4c2110abc597495800841793d38a2e6a0b1;p=linux-2.6.git

Initial revision
---

diff --git a/Documentation/ABI/README b/Documentation/ABI/README
new file mode 100644
index 000000000..9feaf16f1
--- /dev/null
+++ b/Documentation/ABI/README
@@ -0,0 +1,77 @@
+This directory attempts to document the ABI between the Linux kernel and
+userspace, and the relative stability of these interfaces.  Due to the
+everchanging nature of Linux, and the differing maturity levels, these
+interfaces should be used by userspace programs in different ways.
+
+We have four different levels of ABI stability, as shown by the four
+different subdirectories in this location.  Interfaces may change levels
+of stability according to the rules described below.
+
+The different levels of stability are:
+
+  stable/
+	This directory documents the interfaces that the developer has
+	defined to be stable.  Userspace programs are free to use these
+	interfaces with no restrictions, and backward compatibility for
+	them will be guaranteed for at least 2 years.  Most interfaces
+	(like syscalls) are expected to never change and always be
+	available.
+
+  testing/
+	This directory documents interfaces that are felt to be stable,
+	as the main development of this interface has been completed.
+	The interface can be changed to add new features, but the
+	current interface will not break by doing this, unless grave
+	errors or security problems are found in them.  Userspace
+	programs can start to rely on these interfaces, but they must be
+	aware of changes that can occur before these interfaces move to
+	be marked stable.  Programs that use these interfaces are
+	strongly encouraged to add their name to the description of
+	these interfaces, so that the kernel developers can easily
+	notify them if any changes occur (see the description of the
+	layout of the files below for details on how to do this.)
+
+  obsolete/
+  	This directory documents interfaces that are still remaining in
+	the kernel, but are marked to be removed at some later point in
+	time.  The description of the interface will document the reason
+	why it is obsolete and when it can be expected to be removed.
+	The file Documentation/feature-removal-schedule.txt may describe
+	some of these interfaces, giving a schedule for when they will
+	be removed.
+
+  removed/
+	This directory contains a list of the old interfaces that have
+	been removed from the kernel.
+
+Every file in these directories will contain the following information:
+
+What:		Short description of the interface
+Date:		Date created
+KernelVersion:	Kernel version this feature first showed up in.
+Contact:	Primary contact for this interface (may be a mailing list)
+Description:	Long description of the interface and how to use it.
+Users:		All users of this interface who wish to be notified when
+		it changes.  This is very important for interfaces in
+		the "testing" stage, so that kernel developers can work
+		with userspace developers to ensure that things do not
+		break in ways that are unacceptable.  It is also
+		important to get feedback for these interfaces to make
+		sure they are working in a proper way and do not need to
+		be changed further.
+
+
+How things move between levels:
+
+Interfaces in stable may move to obsolete, as long as the proper
+notification is given.
+
+Interfaces may be removed from obsolete and the kernel as long as the
+documented amount of time has gone by.
+
+Interfaces in the testing state can move to the stable state when the
+developers feel they are finished.  They cannot be removed from the
+kernel tree without going through the obsolete state first.
+
+It's up to the developer to place their interfaces in the category they
+wish for it to start out in.
diff --git a/Documentation/ABI/obsolete/devfs b/Documentation/ABI/obsolete/devfs
new file mode 100644
index 000000000..b8b87399b
--- /dev/null
+++ b/Documentation/ABI/obsolete/devfs
@@ -0,0 +1,13 @@
+What:		devfs
+Date:		July 2005
+Contact:	Greg Kroah-Hartman <gregkh@suse.de>
+Description:
+	devfs has been unmaintained for a number of years, has unfixable
+	races, contains a naming policy within the kernel that is
+	against the LSB, and can be replaced by using udev.
+	The files fs/devfs/*, include/linux/devfs_fs*.h will be removed,
+	along with the the assorted devfs function calls throughout the
+	kernel tree.
+
+Users:
+
diff --git a/Documentation/ABI/stable/syscalls b/Documentation/ABI/stable/syscalls
new file mode 100644
index 000000000..c3ae3e7d6
--- /dev/null
+++ b/Documentation/ABI/stable/syscalls
@@ -0,0 +1,10 @@
+What:		The kernel syscall interface
+Description:
+	This interface matches much of the POSIX interface and is based
+	on it and other Unix based interfaces.  It will only be added to
+	over time, and not have things removed from it.
+
+	Note that this interface is different for every architecture
+	that Linux supports.  Please see the architecture-specific
+	documentation for details on the syscall numbers that are to be
+	mapped to each syscall.
diff --git a/Documentation/ABI/stable/sysfs-module b/Documentation/ABI/stable/sysfs-module
new file mode 100644
index 000000000..75be43118
--- /dev/null
+++ b/Documentation/ABI/stable/sysfs-module
@@ -0,0 +1,30 @@
+What:		/sys/module
+Description:
+	The /sys/module tree consists of the following structure:
+
+	/sys/module/MODULENAME
+		The name of the module that is in the kernel.  This
+		module name will show up either if the module is built
+		directly into the kernel, or if it is loaded as a
+		dyanmic module.
+
+	/sys/module/MODULENAME/parameters
+		This directory contains individual files that are each
+		individual parameters of the module that are able to be
+		changed at runtime.  See the individual module
+		documentation as to the contents of these parameters and
+		what they accomplish.
+
+		Note: The individual parameter names and values are not
+		considered stable, only the fact that they will be
+		placed in this location within sysfs.  See the
+		individual driver documentation for details as to the
+		stability of the different parameters.
+
+	/sys/module/MODULENAME/refcnt
+		If the module is able to be unloaded from the kernel, this file
+		will contain the current reference count of the module.
+
+		Note: If the module is built into the kernel, or if the
+		CONFIG_MODULE_UNLOAD kernel configuration value is not enabled,
+		this file will not be present.
diff --git a/Documentation/ABI/testing/sysfs-class b/Documentation/ABI/testing/sysfs-class
new file mode 100644
index 000000000..4b0cb891e
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-class
@@ -0,0 +1,16 @@
+What:		/sys/class/
+Date:		Febuary 2006
+Contact:	Greg Kroah-Hartman <gregkh@suse.de>
+Description:
+		The /sys/class directory will consist of a group of
+		subdirectories describing individual classes of devices
+		in the kernel.  The individual directories will consist
+		of either subdirectories, or symlinks to other
+		directories.
+
+		All programs that use this directory tree must be able
+		to handle both subdirectories or symlinks in order to
+		work properly.
+
+Users:
+	udev <linux-hotplug-devel@lists.sourceforge.net>
diff --git a/Documentation/ABI/testing/sysfs-devices b/Documentation/ABI/testing/sysfs-devices
new file mode 100644
index 000000000..6a25671ee
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-devices
@@ -0,0 +1,25 @@
+What:		/sys/devices
+Date:		February 2006
+Contact:	Greg Kroah-Hartman <gregkh@suse.de>
+Description:
+		The /sys/devices tree contains a snapshot of the
+		internal state of the kernel device tree.  Devices will
+		be added and removed dynamically as the machine runs,
+		and between different kernel versions, the layout of the
+		devices within this tree will change.
+
+		Please do not rely on the format of this tree because of
+		this.  If a program wishes to find different things in
+		the tree, please use the /sys/class structure and rely
+		on the symlinks there to point to the proper location
+		within the /sys/devices tree of the individual devices.
+		Or rely on the uevent messages to notify programs of
+		devices being added and removed from this tree to find
+		the location of those devices.
+
+		Note that sometimes not all devices along the directory
+		chain will have emitted uevent messages, so userspace
+		programs must be able to handle such occurrences.
+
+Users:
+	udev <linux-hotplug-devel@lists.sourceforge.net>
diff --git a/Documentation/DocBook/genericirq.tmpl b/Documentation/DocBook/genericirq.tmpl
new file mode 100644
index 000000000..0f4a4b632
--- /dev/null
+++ b/Documentation/DocBook/genericirq.tmpl
@@ -0,0 +1,474 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
+	"http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" []>
+
+<book id="Generic-IRQ-Guide">
+ <bookinfo>
+  <title>Linux generic IRQ handling</title>
+
+  <authorgroup>
+   <author>
+    <firstname>Thomas</firstname>
+    <surname>Gleixner</surname>
+    <affiliation>
+     <address>
+      <email>tglx@linutronix.de</email>
+     </address>
+    </affiliation>
+   </author>
+   <author>
+    <firstname>Ingo</firstname>
+    <surname>Molnar</surname>
+    <affiliation>
+     <address>
+      <email>mingo@elte.hu</email>
+     </address>
+    </affiliation>
+   </author>
+  </authorgroup>
+
+  <copyright>
+   <year>2005-2006</year>
+   <holder>Thomas Gleixner</holder>
+  </copyright>
+  <copyright>
+   <year>2005-2006</year>
+   <holder>Ingo Molnar</holder>
+  </copyright>
+
+  <legalnotice>
+   <para>
+     This documentation is free software; you can redistribute
+     it and/or modify it under the terms of the GNU General Public
+     License version 2 as published by the Free Software Foundation.
+   </para>
+
+   <para>
+     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.
+   </para>
+
+   <para>
+     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
+   </para>
+
+   <para>
+     For more details see the file COPYING in the source
+     distribution of Linux.
+   </para>
+  </legalnotice>
+ </bookinfo>
+
+<toc></toc>
+
+  <chapter id="intro">
+    <title>Introduction</title>
+    <para>
+	The generic interrupt handling layer is designed to provide a
+	complete abstraction of interrupt handling for device drivers.
+	It is able to handle all the different types of interrupt controller
+	hardware. Device drivers use generic API functions to request, enable,
+	disable and free interrupts. The drivers do not have to know anything
+	about interrupt hardware details, so they can be used on different
+	platforms without code changes.
+    </para>
+    <para>
+  	This documentation is provided to developers who want to implement
+	an interrupt subsystem based for their architecture, with the help
+	of the generic IRQ handling layer.
+    </para>
+  </chapter>
+
+  <chapter id="rationale">
+    <title>Rationale</title>
+	<para>
+	The original implementation of interrupt handling in Linux is using
+	the __do_IRQ() super-handler, which is able to deal with every
+	type of interrupt logic.
+	</para>
+	<para>
+	Originally, Russell King identified different types of handlers to
+	build a quite universal set for the ARM interrupt handler
+	implementation in Linux 2.5/2.6. He distinguished between:
+	<itemizedlist>
+	  <listitem><para>Level type</para></listitem>
+	  <listitem><para>Edge type</para></listitem>
+	  <listitem><para>Simple type</para></listitem>
+	</itemizedlist>
+	In the SMP world of the __do_IRQ() super-handler another type
+	was identified:
+	<itemizedlist>
+	  <listitem><para>Per CPU type</para></listitem>
+	</itemizedlist>
+	</para>
+	<para>
+	This split implementation of highlevel IRQ handlers allows us to
+	optimize the flow of the interrupt handling for each specific
+	interrupt type. This reduces complexity in that particular codepath
+	and allows the optimized handling of a given type.
+	</para>
+	<para>
+	The original general IRQ implementation used hw_interrupt_type
+	structures and their ->ack(), ->end() [etc.] callbacks to
+	differentiate the flow control in the super-handler. This leads to
+	a mix of flow logic and lowlevel hardware logic, and it also leads
+	to unnecessary code duplication: for example in i386, there is a
+	ioapic_level_irq and a ioapic_edge_irq irq-type which share many
+	of the lowlevel details but have different flow handling.
+	</para>
+	<para>
+	A more natural abstraction is the clean separation of the
+	'irq flow' and the 'chip details'.
+	</para>
+	<para>
+	Analysing a couple of architecture's IRQ subsystem implementations
+	reveals that most of them can use a generic set of 'irq flow'
+	methods and only need to add the chip level specific code.
+	The separation is also valuable for (sub)architectures
+	which need specific quirks in the irq flow itself but not in the
+	chip-details - and thus provides a more transparent IRQ subsystem
+	design.
+	</para>
+	<para>
+	Each interrupt descriptor is assigned its own highlevel flow
+	handler, which is normally one of the generic
+	implementations. (This highlevel flow handler implementation also
+	makes it simple to provide demultiplexing handlers which can be
+	found in embedded platforms on various architectures.)
+	</para>
+	<para>
+	The separation makes the generic interrupt handling layer more
+	flexible and extensible. For example, an (sub)architecture can
+	use a generic irq-flow implementation for 'level type' interrupts
+	and add a (sub)architecture specific 'edge type' implementation.
+	</para>
+	<para>
+	To make the transition to the new model easier and prevent the
+	breakage of existing implementations, the __do_IRQ() super-handler
+	is still available. This leads to a kind of duality for the time
+	being. Over time the new model should be used in more and more
+	architectures, as it enables smaller and cleaner IRQ subsystems.
+	</para>
+  </chapter>
+  <chapter id="bugs">
+    <title>Known Bugs And Assumptions</title>
+    <para>
+	None (knock on wood).
+    </para>
+  </chapter>
+
+  <chapter id="Abstraction">
+    <title>Abstraction layers</title>
+    <para>
+	There are three main levels of abstraction in the interrupt code:
+	<orderedlist>
+	  <listitem><para>Highlevel driver API</para></listitem>
+	  <listitem><para>Highlevel IRQ flow handlers</para></listitem>
+	  <listitem><para>Chiplevel hardware encapsulation</para></listitem>
+	</orderedlist>
+    </para>
+    <sect1>
+	<title>Interrupt control flow</title>
+	<para>
+	Each interrupt is described by an interrupt descriptor structure
+	irq_desc. The interrupt is referenced by an 'unsigned int' numeric
+	value which selects the corresponding interrupt decription structure
+	in the descriptor structures array.
+	The descriptor structure contains status information and pointers
+	to the interrupt flow method and the interrupt chip structure
+	which are assigned to this interrupt.
+	</para>
+	<para>
+	Whenever an interrupt triggers, the lowlevel arch code calls into
+	the generic interrupt code by calling desc->handle_irq().
+	This highlevel IRQ handling function only uses desc->chip primitives
+	referenced by the assigned chip descriptor structure.
+	</para>
+    </sect1>
+    <sect1>
+	<title>Highlevel Driver API</title>
+	<para>
+	  The highlevel Driver API consists of following functions:
+	  <itemizedlist>
+	  <listitem><para>request_irq()</para></listitem>
+	  <listitem><para>free_irq()</para></listitem>
+	  <listitem><para>disable_irq()</para></listitem>
+	  <listitem><para>enable_irq()</para></listitem>
+	  <listitem><para>disable_irq_nosync() (SMP only)</para></listitem>
+	  <listitem><para>synchronize_irq() (SMP only)</para></listitem>
+	  <listitem><para>set_irq_type()</para></listitem>
+	  <listitem><para>set_irq_wake()</para></listitem>
+	  <listitem><para>set_irq_data()</para></listitem>
+	  <listitem><para>set_irq_chip()</para></listitem>
+	  <listitem><para>set_irq_chip_data()</para></listitem>
+          </itemizedlist>
+	  See the autogenerated function documentation for details.
+	</para>
+    </sect1>
+    <sect1>
+	<title>Highlevel IRQ flow handlers</title>
+	<para>
+	  The generic layer provides a set of pre-defined irq-flow methods:
+	  <itemizedlist>
+	  <listitem><para>handle_level_irq</para></listitem>
+	  <listitem><para>handle_edge_irq</para></listitem>
+	  <listitem><para>handle_simple_irq</para></listitem>
+	  <listitem><para>handle_percpu_irq</para></listitem>
+	  </itemizedlist>
+	  The interrupt flow handlers (either predefined or architecture
+	  specific) are assigned to specific interrupts by the architecture
+	  either during bootup or during device initialization.
+	</para>
+	<sect2>
+	<title>Default flow implementations</title>
+	    <sect3>
+	 	<title>Helper functions</title>
+		<para>
+		The helper functions call the chip primitives and
+		are used by the default flow implementations.
+		The following helper functions are implemented (simplified excerpt):
+		<programlisting>
+default_enable(irq)
+{
+	desc->chip->unmask(irq);
+}
+
+default_disable(irq)
+{
+	if (!delay_disable(irq))
+		desc->chip->mask(irq);
+}
+
+default_ack(irq)
+{
+	chip->ack(irq);
+}
+
+default_mask_ack(irq)
+{
+	if (chip->mask_ack) {
+		chip->mask_ack(irq);
+	} else {
+		chip->mask(irq);
+		chip->ack(irq);
+	}
+}
+
+noop(irq)
+{
+}
+
+		</programlisting>
+	        </para>
+	    </sect3>
+	</sect2>
+	<sect2>
+	<title>Default flow handler implementations</title>
+	    <sect3>
+	 	<title>Default Level IRQ flow handler</title>
+		<para>
+		handle_level_irq provides a generic implementation
+		for level-triggered interrupts.
+		</para>
+		<para>
+		The following control flow is implemented (simplified excerpt):
+		<programlisting>
+desc->chip->start();
+handle_IRQ_event(desc->action);
+desc->chip->end();
+		</programlisting>
+		</para>
+   	    </sect3>
+	    <sect3>
+	 	<title>Default Edge IRQ flow handler</title>
+		<para>
+		handle_edge_irq provides a generic implementation
+		for edge-triggered interrupts.
+		</para>
+		<para>
+		The following control flow is implemented (simplified excerpt):
+		<programlisting>
+if (desc->status &amp; running) {
+	desc->chip->hold();
+	desc->status |= pending | masked;
+	return;
+}
+desc->chip->start();
+desc->status |= running;
+do {
+	if (desc->status &amp; masked)
+		desc->chip->enable();
+	desc-status &amp;= ~pending;
+	handle_IRQ_event(desc->action);
+} while (status &amp; pending);
+desc-status &amp;= ~running;
+desc->chip->end();
+		</programlisting>
+		</para>
+   	    </sect3>
+	    <sect3>
+	 	<title>Default simple IRQ flow handler</title>
+		<para>
+		handle_simple_irq provides a generic implementation
+		for simple interrupts.
+		</para>
+		<para>
+		Note: The simple flow handler does not call any
+		handler/chip primitives.
+		</para>
+		<para>
+		The following control flow is implemented (simplified excerpt):
+		<programlisting>
+handle_IRQ_event(desc->action);
+		</programlisting>
+		</para>
+   	    </sect3>
+	    <sect3>
+	 	<title>Default per CPU flow handler</title>
+		<para>
+		handle_percpu_irq provides a generic implementation
+		for per CPU interrupts.
+		</para>
+		<para>
+		Per CPU interrupts are only available on SMP and
+		the handler provides a simplified version without
+		locking.
+		</para>
+		<para>
+		The following control flow is implemented (simplified excerpt):
+		<programlisting>
+desc->chip->start();
+handle_IRQ_event(desc->action);
+desc->chip->end();
+		</programlisting>
+		</para>
+   	    </sect3>
+	</sect2>
+	<sect2>
+	<title>Quirks and optimizations</title>
+	<para>
+	The generic functions are intended for 'clean' architectures and chips,
+	which have no platform-specific IRQ handling quirks. If an architecture
+	needs to implement quirks on the 'flow' level then it can do so by
+	overriding the highlevel irq-flow handler.
+	</para>
+	</sect2>
+	<sect2>
+	<title>Delayed interrupt disable</title>
+	<para>
+	This per interrupt selectable feature, which was introduced by Russell
+	King in the ARM interrupt implementation, does not mask an interrupt
+	at the hardware level when disable_irq() is called. The interrupt is
+	kept enabled and is masked in the flow handler when an interrupt event
+	happens. This prevents losing edge interrupts on hardware which does
+	not store an edge interrupt event while the interrupt is disabled at
+	the hardware level. When an interrupt arrives while the IRQ_DISABLED
+	flag is set, then the interrupt is masked at the hardware level and
+	the IRQ_PENDING bit is set. When the interrupt is re-enabled by
+	enable_irq() the pending bit is checked and if it is set, the
+	interrupt is resent either via hardware or by a software resend
+	mechanism. (It's necessary to enable CONFIG_HARDIRQS_SW_RESEND when
+	you want to use the delayed interrupt disable feature and your
+	hardware is not capable of retriggering	an interrupt.)
+	The delayed interrupt disable can be runtime enabled, per interrupt,
+	by setting the IRQ_DELAYED_DISABLE flag in the irq_desc status field.
+	</para>
+	</sect2>
+    </sect1>
+    <sect1>
+	<title>Chiplevel hardware encapsulation</title>
+	<para>
+	The chip level hardware descriptor structure irq_chip
+	contains all the direct chip relevant functions, which
+	can be utilized by the irq flow implementations.
+	  <itemizedlist>
+	  <listitem><para>ack()</para></listitem>
+	  <listitem><para>mask_ack() - Optional, recommended for performance</para></listitem>
+	  <listitem><para>mask()</para></listitem>
+	  <listitem><para>unmask()</para></listitem>
+	  <listitem><para>retrigger() - Optional</para></listitem>
+	  <listitem><para>set_type() - Optional</para></listitem>
+	  <listitem><para>set_wake() - Optional</para></listitem>
+	  </itemizedlist>
+	These primitives are strictly intended to mean what they say: ack means
+	ACK, masking means masking of an IRQ line, etc. It is up to the flow
+	handler(s) to use these basic units of lowlevel functionality.
+	</para>
+    </sect1>
+  </chapter>
+
+  <chapter id="doirq">
+     <title>__do_IRQ entry point</title>
+     <para>
+ 	The original implementation __do_IRQ() is an alternative entry
+	point for all types of interrupts.
+     </para>
+     <para>
+	This handler turned out to be not suitable for all
+	interrupt hardware and was therefore reimplemented with split
+	functionality for egde/level/simple/percpu interrupts. This is not
+	only a functional optimization. It also shortens code paths for
+	interrupts.
+      </para>
+      <para>
+	To make use of the split implementation, replace the call to
+	__do_IRQ by a call to desc->chip->handle_irq() and associate
+        the appropriate handler function to desc->chip->handle_irq().
+	In most cases the generic handler implementations should
+	be sufficient.
+     </para>
+  </chapter>
+
+  <chapter id="locking">
+     <title>Locking on SMP</title>
+     <para>
+	The locking of chip registers is up to the architecture that
+	defines the chip primitives. There is a chip->lock field that can be used
+	for serialization, but the generic layer does not touch it. The per-irq
+	structure is protected via desc->lock, by the generic layer.
+     </para>
+  </chapter>
+  <chapter id="structs">
+     <title>Structures</title>
+     <para>
+     This chapter contains the autogenerated documentation of the structures which are
+     used in the generic IRQ layer.
+     </para>
+!Iinclude/linux/irq.h
+  </chapter>
+
+  <chapter id="pubfunctions">
+     <title>Public Functions Provided</title>
+     <para>
+     This chapter contains the autogenerated documentation of the kernel API functions
+      which are exported.
+     </para>
+!Ekernel/irq/manage.c
+!Ekernel/irq/chip.c
+  </chapter>
+
+  <chapter id="intfunctions">
+     <title>Internal Functions Provided</title>
+     <para>
+     This chapter contains the autogenerated documentation of the internal functions.
+     </para>
+!Ikernel/irq/handle.c
+!Ikernel/irq/chip.c
+  </chapter>
+
+  <chapter id="credits">
+     <title>Credits</title>
+	<para>
+		The following people have contributed to this document:
+		<orderedlist>
+			<listitem><para>Thomas Gleixner<email>tglx@linutronix.de</email></para></listitem>
+			<listitem><para>Ingo Molnar<email>mingo@elte.hu</email></para></listitem>
+		</orderedlist>
+	</para>
+  </chapter>
+</book>
diff --git a/Documentation/IRQ.txt b/Documentation/IRQ.txt
new file mode 100644
index 000000000..1011e7175
--- /dev/null
+++ b/Documentation/IRQ.txt
@@ -0,0 +1,22 @@
+What is an IRQ?
+
+An IRQ is an interrupt request from a device.
+Currently they can come in over a pin, or over a packet.
+Several devices may be connected to the same pin thus
+sharing an IRQ.
+
+An IRQ number is a kernel identifier used to talk about a hardware
+interrupt source.  Typically this is an index into the global irq_desc
+array, but except for what linux/interrupt.h implements the details
+are architecture specific.
+
+An IRQ number is an enumeration of the possible interrupt sources on a
+machine.  Typically what is enumerated is the number of input pins on
+all of the interrupt controller in the system.  In the case of ISA
+what is enumerated are the 16 input pins on the two i8259 interrupt
+controllers.
+
+Architectures can assign additional meaning to the IRQ numbers, and
+are encouraged to in the case  where there is any manual configuration
+of the hardware involved.  The ISA IRQs are a classic example of
+assigning this kind of additional meaning.
diff --git a/Documentation/SubmitChecklist b/Documentation/SubmitChecklist
new file mode 100644
index 000000000..a10bfb6ec
--- /dev/null
+++ b/Documentation/SubmitChecklist
@@ -0,0 +1,63 @@
+Linux Kernel patch sumbittal checklist
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here are some basic things that developers should do if they want to see their
+kernel patch submissions accepted more quickly.
+
+These are all above and beyond the documentation that is provided in
+Documentation/SubmittingPatches and elsewhere regarding submitting Linux
+kernel patches.
+
+
+
+1: Builds cleanly with applicable or modified CONFIG options =y, =m, and
+   =n.  No gcc warnings/errors, no linker warnings/errors.
+
+2: Passes allnoconfig, allmodconfig
+
+3: Builds on multiple CPU architectures by using local cross-compile tools
+   or something like PLM at OSDL.
+
+4: ppc64 is a good architecture for cross-compilation checking because it
+   tends to use `unsigned long' for 64-bit quantities.
+
+5: Matches kernel coding style(!)
+
+6: Any new or modified CONFIG options don't muck up the config menu.
+
+7: All new Kconfig options have help text.
+
+8: Has been carefully reviewed with respect to relevant Kconfig
+   combinations.  This is very hard to get right with testing -- brainpower
+   pays off here.
+
+9: Check cleanly with sparse.
+
+10: Use 'make checkstack' and 'make namespacecheck' and fix any problems
+    that they find.  Note: checkstack does not point out problems explicitly,
+    but any one function that uses more than 512 bytes on the stack is a
+    candidate for change.
+
+11: Include kernel-doc to document global kernel APIs.  (Not required for
+    static functions, but OK there also.) Use 'make htmldocs' or 'make
+    mandocs' to check the kernel-doc and fix any issues.
+
+12: Has been tested with CONFIG_PREEMPT, CONFIG_DEBUG_PREEMPT,
+    CONFIG_DEBUG_SLAB, CONFIG_DEBUG_PAGEALLOC, CONFIG_DEBUG_MUTEXES,
+    CONFIG_DEBUG_SPINLOCK, CONFIG_DEBUG_SPINLOCK_SLEEP all simultaneously
+    enabled.
+
+13: Has been build- and runtime tested with and without CONFIG_SMP and
+    CONFIG_PREEMPT.
+
+14: If the patch affects IO/Disk, etc: has been tested with and without
+    CONFIG_LBD.
+
+15: All codepaths have been exercised with all lockdep features enabled.
+
+16: All new /proc entries are documented under Documentation/
+
+17: All new kernel boot parameters are documented in
+    Documentation/kernel-parameters.txt.
+
+18: All new module parameters are documented with MODULE_PARM_DESC()
diff --git a/Documentation/accounting/delay-accounting.txt b/Documentation/accounting/delay-accounting.txt
new file mode 100644
index 000000000..1443cd71d
--- /dev/null
+++ b/Documentation/accounting/delay-accounting.txt
@@ -0,0 +1,112 @@
+Delay accounting
+----------------
+
+Tasks encounter delays in execution when they wait
+for some kernel resource to become available e.g. a
+runnable task may wait for a free CPU to run on.
+
+The per-task delay accounting functionality measures
+the delays experienced by a task while
+
+a) waiting for a CPU (while being runnable)
+b) completion of synchronous block I/O initiated by the task
+c) swapping in pages
+
+and makes these statistics available to userspace through
+the taskstats interface.
+
+Such delays provide feedback for setting a task's cpu priority,
+io priority and rss limit values appropriately. Long delays for
+important tasks could be a trigger for raising its corresponding priority.
+
+The functionality, through its use of the taskstats interface, also provides
+delay statistics aggregated for all tasks (or threads) belonging to a
+thread group (corresponding to a traditional Unix process). This is a commonly
+needed aggregation that is more efficiently done by the kernel.
+
+Userspace utilities, particularly resource management applications, can also
+aggregate delay statistics into arbitrary groups. To enable this, delay
+statistics of a task are available both during its lifetime as well as on its
+exit, ensuring continuous and complete monitoring can be done.
+
+
+Interface
+---------
+
+Delay accounting uses the taskstats interface which is described
+in detail in a separate document in this directory. Taskstats returns a
+generic data structure to userspace corresponding to per-pid and per-tgid
+statistics. The delay accounting functionality populates specific fields of
+this structure. See
+     include/linux/taskstats.h
+for a description of the fields pertaining to delay accounting.
+It will generally be in the form of counters returning the cumulative
+delay seen for cpu, sync block I/O, swapin etc.
+
+Taking the difference of two successive readings of a given
+counter (say cpu_delay_total) for a task will give the delay
+experienced by the task waiting for the corresponding resource
+in that interval.
+
+When a task exits, records containing the per-task statistics
+are sent to userspace without requiring a command. If it is the last exiting
+task of a thread group, the per-tgid statistics are also sent. More details
+are given in the taskstats interface description.
+
+The getdelays.c userspace utility in this directory allows simple commands to
+be run and the corresponding delay statistics to be displayed. It also serves
+as an example of using the taskstats interface.
+
+Usage
+-----
+
+Compile the kernel with
+	CONFIG_TASK_DELAY_ACCT=y
+	CONFIG_TASKSTATS=y
+
+Delay accounting is enabled by default at boot up.
+To disable, add
+   nodelayacct
+to the kernel boot options. The rest of the instructions
+below assume this has not been done.
+
+After the system has booted up, use a utility
+similar to  getdelays.c to access the delays
+seen by a given task or a task group (tgid).
+The utility also allows a given command to be
+executed and the corresponding delays to be
+seen.
+
+General format of the getdelays command
+
+getdelays [-t tgid] [-p pid] [-c cmd...]
+
+
+Get delays, since system boot, for pid 10
+# ./getdelays -p 10
+(output similar to next case)
+
+Get sum of delays, since system boot, for all pids with tgid 5
+# ./getdelays -t 5
+
+
+CPU	count	real total	virtual total	delay total
+	7876	92005750	100000000	24001500
+IO	count	delay total
+	0	0
+MEM	count	delay total
+	0	0
+
+Get delays seen in executing a given simple command
+# ./getdelays -c ls /
+
+bin   data1  data3  data5  dev  home  media  opt   root  srv        sys  usr
+boot  data2  data4  data6  etc  lib   mnt    proc  sbin  subdomain  tmp  var
+
+
+CPU	count	real total	virtual total	delay total
+	6	4000250		4000000		0
+IO	count	delay total
+	0	0
+MEM	count	delay total
+	0	0
diff --git a/Documentation/accounting/getdelays.c b/Documentation/accounting/getdelays.c
new file mode 100644
index 000000000..795ca3911
--- /dev/null
+++ b/Documentation/accounting/getdelays.c
@@ -0,0 +1,396 @@
+/* getdelays.c
+ *
+ * Utility to get per-pid and per-tgid delay accounting statistics
+ * Also illustrates usage of the taskstats interface
+ *
+ * Copyright (C) Shailabh Nagar, IBM Corp. 2005
+ * Copyright (C) Balbir Singh, IBM Corp. 2006
+ * Copyright (c) Jay Lan, SGI. 2006
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <unistd.h>
+#include <poll.h>
+#include <string.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <signal.h>
+
+#include <linux/genetlink.h>
+#include <linux/taskstats.h>
+
+/*
+ * Generic macros for dealing with netlink sockets. Might be duplicated
+ * elsewhere. It is recommended that commercial grade applications use
+ * libnl or libnetlink and use the interfaces provided by the library
+ */
+#define GENLMSG_DATA(glh)	((void *)(NLMSG_DATA(glh) + GENL_HDRLEN))
+#define GENLMSG_PAYLOAD(glh)	(NLMSG_PAYLOAD(glh, 0) - GENL_HDRLEN)
+#define NLA_DATA(na)		((void *)((char*)(na) + NLA_HDRLEN))
+#define NLA_PAYLOAD(len)	(len - NLA_HDRLEN)
+
+#define err(code, fmt, arg...) do { printf(fmt, ##arg); exit(code); } while (0)
+int done = 0;
+int rcvbufsz=0;
+
+    char name[100];
+int dbg=0, print_delays=0;
+__u64 stime, utime;
+#define PRINTF(fmt, arg...) {			\
+	    if (dbg) {				\
+		printf(fmt, ##arg);		\
+	    }					\
+	}
+
+/* Maximum size of response requested or message sent */
+#define MAX_MSG_SIZE	256
+/* Maximum number of cpus expected to be specified in a cpumask */
+#define MAX_CPUS	32
+/* Maximum length of pathname to log file */
+#define MAX_FILENAME	256
+
+struct msgtemplate {
+	struct nlmsghdr n;
+	struct genlmsghdr g;
+	char buf[MAX_MSG_SIZE];
+};
+
+char cpumask[100+6*MAX_CPUS];
+
+/*
+ * Create a raw netlink socket and bind
+ */
+static int create_nl_socket(int protocol)
+{
+	int fd;
+	struct sockaddr_nl local;
+
+	fd = socket(AF_NETLINK, SOCK_RAW, protocol);
+	if (fd < 0)
+		return -1;
+
+	if (rcvbufsz)
+		if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF,
+				&rcvbufsz, sizeof(rcvbufsz)) < 0) {
+			printf("Unable to set socket rcv buf size to %d\n",
+			       rcvbufsz);
+			return -1;
+		}
+
+	memset(&local, 0, sizeof(local));
+	local.nl_family = AF_NETLINK;
+
+	if (bind(fd, (struct sockaddr *) &local, sizeof(local)) < 0)
+		goto error;
+
+	return fd;
+error:
+	close(fd);
+	return -1;
+}
+
+
+int send_cmd(int sd, __u16 nlmsg_type, __u32 nlmsg_pid,
+	     __u8 genl_cmd, __u16 nla_type,
+	     void *nla_data, int nla_len)
+{
+	struct nlattr *na;
+	struct sockaddr_nl nladdr;
+	int r, buflen;
+	char *buf;
+
+	struct msgtemplate msg;
+
+	msg.n.nlmsg_len = NLMSG_LENGTH(GENL_HDRLEN);
+	msg.n.nlmsg_type = nlmsg_type;
+	msg.n.nlmsg_flags = NLM_F_REQUEST;
+	msg.n.nlmsg_seq = 0;
+	msg.n.nlmsg_pid = nlmsg_pid;
+	msg.g.cmd = genl_cmd;
+	msg.g.version = 0x1;
+	na = (struct nlattr *) GENLMSG_DATA(&msg);
+	na->nla_type = nla_type;
+	na->nla_len = nla_len + 1 + NLA_HDRLEN;
+	memcpy(NLA_DATA(na), nla_data, nla_len);
+	msg.n.nlmsg_len += NLMSG_ALIGN(na->nla_len);
+
+	buf = (char *) &msg;
+	buflen = msg.n.nlmsg_len ;
+	memset(&nladdr, 0, sizeof(nladdr));
+	nladdr.nl_family = AF_NETLINK;
+	while ((r = sendto(sd, buf, buflen, 0, (struct sockaddr *) &nladdr,
+			   sizeof(nladdr))) < buflen) {
+		if (r > 0) {
+			buf += r;
+			buflen -= r;
+		} else if (errno != EAGAIN)
+			return -1;
+	}
+	return 0;
+}
+
+
+/*
+ * Probe the controller in genetlink to find the family id
+ * for the TASKSTATS family
+ */
+int get_family_id(int sd)
+{
+	struct {
+		struct nlmsghdr n;
+		struct genlmsghdr g;
+		char buf[256];
+	} ans;
+
+	int id, rc;
+	struct nlattr *na;
+	int rep_len;
+
+	strcpy(name, TASKSTATS_GENL_NAME);
+	rc = send_cmd(sd, GENL_ID_CTRL, getpid(), CTRL_CMD_GETFAMILY,
+			CTRL_ATTR_FAMILY_NAME, (void *)name,
+			strlen(TASKSTATS_GENL_NAME)+1);
+
+	rep_len = recv(sd, &ans, sizeof(ans), 0);
+	if (ans.n.nlmsg_type == NLMSG_ERROR ||
+	    (rep_len < 0) || !NLMSG_OK((&ans.n), rep_len))
+		return 0;
+
+	na = (struct nlattr *) GENLMSG_DATA(&ans);
+	na = (struct nlattr *) ((char *) na + NLA_ALIGN(na->nla_len));
+	if (na->nla_type == CTRL_ATTR_FAMILY_ID) {
+		id = *(__u16 *) NLA_DATA(na);
+	}
+	return id;
+}
+
+void print_delayacct(struct taskstats *t)
+{
+	printf("\n\nCPU   %15s%15s%15s%15s\n"
+	       "      %15llu%15llu%15llu%15llu\n"
+	       "IO    %15s%15s\n"
+	       "      %15llu%15llu\n"
+	       "MEM   %15s%15s\n"
+	       "      %15llu%15llu\n\n",
+	       "count", "real total", "virtual total", "delay total",
+	       t->cpu_count, t->cpu_run_real_total, t->cpu_run_virtual_total,
+	       t->cpu_delay_total,
+	       "count", "delay total",
+	       t->blkio_count, t->blkio_delay_total,
+	       "count", "delay total", t->swapin_count, t->swapin_delay_total);
+}
+
+int main(int argc, char *argv[])
+{
+	int c, rc, rep_len, aggr_len, len2, cmd_type;
+	__u16 id;
+	__u32 mypid;
+
+	struct nlattr *na;
+	int nl_sd = -1;
+	int len = 0;
+	pid_t tid = 0;
+	pid_t rtid = 0;
+
+	int fd = 0;
+	int count = 0;
+	int write_file = 0;
+	int maskset = 0;
+	char logfile[128];
+	int loop = 0;
+
+	struct msgtemplate msg;
+
+	while (1) {
+		c = getopt(argc, argv, "dw:r:m:t:p:v:l");
+		if (c < 0)
+			break;
+
+		switch (c) {
+		case 'd':
+			printf("print delayacct stats ON\n");
+			print_delays = 1;
+			break;
+		case 'w':
+			strncpy(logfile, optarg, MAX_FILENAME);
+			printf("write to file %s\n", logfile);
+			write_file = 1;
+			break;
+		case 'r':
+			rcvbufsz = atoi(optarg);
+			printf("receive buf size %d\n", rcvbufsz);
+			if (rcvbufsz < 0)
+				err(1, "Invalid rcv buf size\n");
+			break;
+		case 'm':
+			strncpy(cpumask, optarg, sizeof(cpumask));
+			maskset = 1;
+			printf("cpumask %s maskset %d\n", cpumask, maskset);
+			break;
+		case 't':
+			tid = atoi(optarg);
+			if (!tid)
+				err(1, "Invalid tgid\n");
+			cmd_type = TASKSTATS_CMD_ATTR_TGID;
+			print_delays = 1;
+			break;
+		case 'p':
+			tid = atoi(optarg);
+			if (!tid)
+				err(1, "Invalid pid\n");
+			cmd_type = TASKSTATS_CMD_ATTR_PID;
+			print_delays = 1;
+			break;
+		case 'v':
+			printf("debug on\n");
+			dbg = 1;
+			break;
+		case 'l':
+			printf("listen forever\n");
+			loop = 1;
+			break;
+		default:
+			printf("Unknown option %d\n", c);
+			exit(-1);
+		}
+	}
+
+	if (write_file) {
+		fd = open(logfile, O_WRONLY | O_CREAT | O_TRUNC,
+			  S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
+		if (fd == -1) {
+			perror("Cannot open output file\n");
+			exit(1);
+		}
+	}
+
+	if ((nl_sd = create_nl_socket(NETLINK_GENERIC)) < 0)
+		err(1, "error creating Netlink socket\n");
+
+
+	mypid = getpid();
+	id = get_family_id(nl_sd);
+	if (!id) {
+		printf("Error getting family id, errno %d", errno);
+		goto err;
+	}
+	PRINTF("family id %d\n", id);
+
+	if (maskset) {
+		rc = send_cmd(nl_sd, id, mypid, TASKSTATS_CMD_GET,
+			      TASKSTATS_CMD_ATTR_REGISTER_CPUMASK,
+			      &cpumask, sizeof(cpumask));
+		PRINTF("Sent register cpumask, retval %d\n", rc);
+		if (rc < 0) {
+			printf("error sending register cpumask\n");
+			goto err;
+		}
+	}
+
+	if (tid) {
+		rc = send_cmd(nl_sd, id, mypid, TASKSTATS_CMD_GET,
+			      cmd_type, &tid, sizeof(__u32));
+		PRINTF("Sent pid/tgid, retval %d\n", rc);
+		if (rc < 0) {
+			printf("error sending tid/tgid cmd\n");
+			goto done;
+		}
+	}
+
+	do {
+		int i;
+
+		rep_len = recv(nl_sd, &msg, sizeof(msg), 0);
+		PRINTF("received %d bytes\n", rep_len);
+
+		if (rep_len < 0) {
+			printf("nonfatal reply error: errno %d\n", errno);
+			continue;
+		}
+		if (msg.n.nlmsg_type == NLMSG_ERROR ||
+		    !NLMSG_OK((&msg.n), rep_len)) {
+			printf("fatal reply error,  errno %d\n", errno);
+			goto done;
+		}
+
+		PRINTF("nlmsghdr size=%d, nlmsg_len=%d, rep_len=%d\n",
+		       sizeof(struct nlmsghdr), msg.n.nlmsg_len, rep_len);
+
+
+		rep_len = GENLMSG_PAYLOAD(&msg.n);
+
+		na = (struct nlattr *) GENLMSG_DATA(&msg);
+		len = 0;
+		i = 0;
+		while (len < rep_len) {
+			len += NLA_ALIGN(na->nla_len);
+			switch (na->nla_type) {
+			case TASKSTATS_TYPE_AGGR_TGID:
+				/* Fall through */
+			case TASKSTATS_TYPE_AGGR_PID:
+				aggr_len = NLA_PAYLOAD(na->nla_len);
+				len2 = 0;
+				/* For nested attributes, na follows */
+				na = (struct nlattr *) NLA_DATA(na);
+				done = 0;
+				while (len2 < aggr_len) {
+					switch (na->nla_type) {
+					case TASKSTATS_TYPE_PID:
+						rtid = *(int *) NLA_DATA(na);
+						if (print_delays)
+							printf("PID\t%d\n", rtid);
+						break;
+					case TASKSTATS_TYPE_TGID:
+						rtid = *(int *) NLA_DATA(na);
+						if (print_delays)
+							printf("TGID\t%d\n", rtid);
+						break;
+					case TASKSTATS_TYPE_STATS:
+						count++;
+						if (print_delays)
+							print_delayacct((struct taskstats *) NLA_DATA(na));
+						if (fd) {
+							if (write(fd, NLA_DATA(na), na->nla_len) < 0) {
+								err(1,"write error\n");
+							}
+						}
+						if (!loop)
+							goto done;
+						break;
+					default:
+						printf("Unknown nested nla_type %d\n", na->nla_type);
+						break;
+					}
+					len2 += NLA_ALIGN(na->nla_len);
+					na = (struct nlattr *) ((char *) na + len2);
+				}
+				break;
+
+			default:
+				printf("Unknown nla_type %d\n", na->nla_type);
+				break;
+			}
+			na = (struct nlattr *) (GENLMSG_DATA(&msg) + len);
+		}
+	} while (loop);
+done:
+	if (maskset) {
+		rc = send_cmd(nl_sd, id, mypid, TASKSTATS_CMD_GET,
+			      TASKSTATS_CMD_ATTR_DEREGISTER_CPUMASK,
+			      &cpumask, sizeof(cpumask));
+		printf("Sent deregister mask, retval %d\n", rc);
+		if (rc < 0)
+			err(rc, "error sending deregister cpumask\n");
+	}
+err:
+	close(nl_sd);
+	if (fd)
+		close(fd);
+	return 0;
+}
diff --git a/Documentation/accounting/taskstats.txt b/Documentation/accounting/taskstats.txt
new file mode 100644
index 000000000..92ebf29e9
--- /dev/null
+++ b/Documentation/accounting/taskstats.txt
@@ -0,0 +1,181 @@
+Per-task statistics interface
+-----------------------------
+
+
+Taskstats is a netlink-based interface for sending per-task and
+per-process statistics from the kernel to userspace.
+
+Taskstats was designed for the following benefits:
+
+- efficiently provide statistics during lifetime of a task and on its exit
+- unified interface for multiple accounting subsystems
+- extensibility for use by future accounting patches
+
+Terminology
+-----------
+
+"pid", "tid" and "task" are used interchangeably and refer to the standard
+Linux task defined by struct task_struct.  per-pid stats are the same as
+per-task stats.
+
+"tgid", "process" and "thread group" are used interchangeably and refer to the
+tasks that share an mm_struct i.e. the traditional Unix process. Despite the
+use of tgid, there is no special treatment for the task that is thread group
+leader - a process is deemed alive as long as it has any task belonging to it.
+
+Usage
+-----
+
+To get statistics during a task's lifetime, userspace opens a unicast netlink
+socket (NETLINK_GENERIC family) and sends commands specifying a pid or a tgid.
+The response contains statistics for a task (if pid is specified) or the sum of
+statistics for all tasks of the process (if tgid is specified).
+
+To obtain statistics for tasks which are exiting, the userspace listener
+sends a register command and specifies a cpumask. Whenever a task exits on
+one of the cpus in the cpumask, its per-pid statistics are sent to the
+registered listener. Using cpumasks allows the data received by one listener
+to be limited and assists in flow control over the netlink interface and is
+explained in more detail below.
+
+If the exiting task is the last thread exiting its thread group,
+an additional record containing the per-tgid stats is also sent to userspace.
+The latter contains the sum of per-pid stats for all threads in the thread
+group, both past and present.
+
+getdelays.c is a simple utility demonstrating usage of the taskstats interface
+for reporting delay accounting statistics. Users can register cpumasks,
+send commands and process responses, listen for per-tid/tgid exit data,
+write the data received to a file and do basic flow control by increasing
+receive buffer sizes.
+
+Interface
+---------
+
+The user-kernel interface is encapsulated in include/linux/taskstats.h
+
+To avoid this documentation becoming obsolete as the interface evolves, only
+an outline of the current version is given. taskstats.h always overrides the
+description here.
+
+struct taskstats is the common accounting structure for both per-pid and
+per-tgid data. It is versioned and can be extended by each accounting subsystem
+that is added to the kernel. The fields and their semantics are defined in the
+taskstats.h file.
+
+The data exchanged between user and kernel space is a netlink message belonging
+to the NETLINK_GENERIC family and using the netlink attributes interface.
+The messages are in the format
+
+    +----------+- - -+-------------+-------------------+
+    | nlmsghdr | Pad |  genlmsghdr | taskstats payload |
+    +----------+- - -+-------------+-------------------+
+
+
+The taskstats payload is one of the following three kinds:
+
+1. Commands: Sent from user to kernel. Commands to get data on
+a pid/tgid consist of one attribute, of type TASKSTATS_CMD_ATTR_PID/TGID,
+containing a u32 pid or tgid in the attribute payload. The pid/tgid denotes
+the task/process for which userspace wants statistics.
+
+Commands to register/deregister interest in exit data from a set of cpus
+consist of one attribute, of type
+TASKSTATS_CMD_ATTR_REGISTER/DEREGISTER_CPUMASK and contain a cpumask in the
+attribute payload. The cpumask is specified as an ascii string of
+comma-separated cpu ranges e.g. to listen to exit data from cpus 1,2,3,5,7,8
+the cpumask would be "1-3,5,7-8". If userspace forgets to deregister interest
+in cpus before closing the listening socket, the kernel cleans up its interest
+set over time. However, for the sake of efficiency, an explicit deregistration
+is advisable.
+
+2. Response for a command: sent from the kernel in response to a userspace
+command. The payload is a series of three attributes of type:
+
+a) TASKSTATS_TYPE_AGGR_PID/TGID : attribute containing no payload but indicates
+a pid/tgid will be followed by some stats.
+
+b) TASKSTATS_TYPE_PID/TGID: attribute whose payload is the pid/tgid whose stats
+is being returned.
+
+c) TASKSTATS_TYPE_STATS: attribute with a struct taskstsats as payload. The
+same structure is used for both per-pid and per-tgid stats.
+
+3. New message sent by kernel whenever a task exits. The payload consists of a
+   series of attributes of the following type:
+
+a) TASKSTATS_TYPE_AGGR_PID: indicates next two attributes will be pid+stats
+b) TASKSTATS_TYPE_PID: contains exiting task's pid
+c) TASKSTATS_TYPE_STATS: contains the exiting task's per-pid stats
+d) TASKSTATS_TYPE_AGGR_TGID: indicates next two attributes will be tgid+stats
+e) TASKSTATS_TYPE_TGID: contains tgid of process to which task belongs
+f) TASKSTATS_TYPE_STATS: contains the per-tgid stats for exiting task's process
+
+
+per-tgid stats
+--------------
+
+Taskstats provides per-process stats, in addition to per-task stats, since
+resource management is often done at a process granularity and aggregating task
+stats in userspace alone is inefficient and potentially inaccurate (due to lack
+of atomicity).
+
+However, maintaining per-process, in addition to per-task stats, within the
+kernel has space and time overheads. To address this, the taskstats code
+accumalates each exiting task's statistics into a process-wide data structure.
+When the last task of a process exits, the process level data accumalated also
+gets sent to userspace (along with the per-task data).
+
+When a user queries to get per-tgid data, the sum of all other live threads in
+the group is added up and added to the accumalated total for previously exited
+threads of the same thread group.
+
+Extending taskstats
+-------------------
+
+There are two ways to extend the taskstats interface to export more
+per-task/process stats as patches to collect them get added to the kernel
+in future:
+
+1. Adding more fields to the end of the existing struct taskstats. Backward
+   compatibility is ensured by the version number within the
+   structure. Userspace will use only the fields of the struct that correspond
+   to the version its using.
+
+2. Defining separate statistic structs and using the netlink attributes
+   interface to return them. Since userspace processes each netlink attribute
+   independently, it can always ignore attributes whose type it does not
+   understand (because it is using an older version of the interface).
+
+
+Choosing between 1. and 2. is a matter of trading off flexibility and
+overhead. If only a few fields need to be added, then 1. is the preferable
+path since the kernel and userspace don't need to incur the overhead of
+processing new netlink attributes. But if the new fields expand the existing
+struct too much, requiring disparate userspace accounting utilities to
+unnecessarily receive large structures whose fields are of no interest, then
+extending the attributes structure would be worthwhile.
+
+Flow control for taskstats
+--------------------------
+
+When the rate of task exits becomes large, a listener may not be able to keep
+up with the kernel's rate of sending per-tid/tgid exit data leading to data
+loss. This possibility gets compounded when the taskstats structure gets
+extended and the number of cpus grows large.
+
+To avoid losing statistics, userspace should do one or more of the following:
+
+- increase the receive buffer sizes for the netlink sockets opened by
+listeners to receive exit data.
+
+- create more listeners and reduce the number of cpus being listened to by
+each listener. In the extreme case, there could be one listener for each cpu.
+Users may also consider setting the cpu affinity of the listener to the subset
+of cpus to which it listens, especially if they are listening to just one cpu.
+
+Despite these measures, if the userspace receives ENOBUFS error messages
+indicated overflow of receive buffers, it should take measures to handle the
+loss of data.
+
+----
diff --git a/Documentation/arm/Samsung-S3C24XX/S3C2412.txt b/Documentation/arm/Samsung-S3C24XX/S3C2412.txt
new file mode 100644
index 000000000..cb82a7fc7
--- /dev/null
+++ b/Documentation/arm/Samsung-S3C24XX/S3C2412.txt
@@ -0,0 +1,120 @@
+		S3C2412 ARM Linux Overview
+		==========================
+
+Introduction
+------------
+
+  The S3C2412 is part of the S3C24XX range of ARM9 System-on-Chip CPUs
+  from Samsung. This part has an ARM926-EJS core, capable of running up
+  to 266MHz (see data-sheet for more information)
+
+
+Clock
+-----
+
+  The core clock code provides a set of clocks to the drivers, and allows
+  for source selection and a number of other features.
+
+
+Power
+-----
+
+  No support for suspend/resume to RAM in the current system.
+
+
+DMA
+---
+
+  No current support for DMA.
+
+
+GPIO
+----
+
+  There is support for setting the GPIO to input/output/special function
+  and reading or writing to them.
+
+
+UART
+----
+
+  The UART hardware is similar to the S3C2440, and is supported by the
+  s3c2410 driver in the drivers/serial directory.
+
+
+NAND
+----
+
+  The NAND hardware is similar to the S3C2440, and is supported by the
+  s3c2410 driver in the drivers/mtd/nand directory.
+
+
+USB Host
+--------
+
+  The USB hardware is similar to the S3C2410, with extended clock source
+  control. The OHCI portion is supported by the ohci-s3c2410 driver, and
+  the clock control selection is supported by the core clock code.
+
+
+USB Device
+----------
+
+  No current support in the kernel
+
+
+IRQs
+----
+
+  All the standard, and external interrupt sources are supported. The
+  extra sub-sources are not yet supported.
+
+
+RTC
+---
+
+  The RTC hardware is similar to the S3C2410, and is supported by the
+  s3c2410-rtc driver.
+
+
+Watchdog
+--------
+
+  The watchdog harware is the same as the S3C2410, and is supported by
+  the s3c2410_wdt driver.
+
+
+MMC/SD/SDIO
+-----------
+
+  No current support for the MMC/SD/SDIO block.
+
+IIC
+---
+
+  The IIC hardware is the same as the S3C2410, and is supported by the
+  i2c-s3c24xx driver.
+
+
+IIS
+---
+
+  No current support for the IIS interface.
+
+
+SPI
+---
+
+  No current support for the SPI interfaces.
+
+
+ATA
+---
+
+  No current support for the on-board ATA block.
+
+
+Document Author
+---------------
+
+Ben Dooks, (c) 2006 Simtec Electronics
diff --git a/Documentation/arm/Samsung-S3C24XX/S3C2413.txt b/Documentation/arm/Samsung-S3C24XX/S3C2413.txt
new file mode 100644
index 000000000..ab2a88858
--- /dev/null
+++ b/Documentation/arm/Samsung-S3C24XX/S3C2413.txt
@@ -0,0 +1,21 @@
+		S3C2413 ARM Linux Overview
+		==========================
+
+Introduction
+------------
+
+  The S3C2413 is an extended version of the S3C2412, with an camera
+  interface and mobile DDR memory support. See the S3C2412 support
+  documentation for more information.
+
+
+Camera Interface
+---------------
+
+  This block is currently not supported.
+
+
+Document Author
+---------------
+
+Ben Dooks, (c) 2006 Simtec Electronics
diff --git a/Documentation/arm/Sharp-LH/ADC-LH7-Touchscreen b/Documentation/arm/Sharp-LH/ADC-LH7-Touchscreen
new file mode 100644
index 000000000..1e6a23fdf
--- /dev/null
+++ b/Documentation/arm/Sharp-LH/ADC-LH7-Touchscreen
@@ -0,0 +1,61 @@
+README on the ADC/Touchscreen Controller
+========================================
+
+The LH79524 and LH7A404 include a built-in Analog to Digital
+controller (ADC) that is used to process input from a touchscreen.
+The driver only implements a four-wire touch panel protocol.
+
+The touchscreen driver is maintenance free except for the pen-down or
+touch threshold.  Some resistive displays and board combinations may
+require tuning of this threshold.  The driver exposes some of it's
+internal state in the sys filesystem.  If the kernel is configured
+with it, CONFIG_SYSFS, and sysfs is mounted at /sys, there will be a
+directory
+
+  /sys/devices/platform/adc-lh7.0
+
+containing these files.
+
+  -r--r--r--    1 root     root         4096 Jan  1 00:00 samples
+  -rw-r--r--    1 root     root         4096 Jan  1 00:00 threshold
+  -r--r--r--    1 root     root         4096 Jan  1 00:00 threshold_range
+
+The threshold is the current touch threshold.  It defaults to 750 on
+most targets.
+
+  # cat threshold
+ 750
+
+The threshold_range contains the range of valid values for the
+threshold.  Values outside of this range will be silently ignored.
+
+  # cat threshold_range
+  0 1023
+
+To change the threshold, write a value to the threshold file.
+
+  # echo 500 > threshold
+  # cat threshold
+  500
+
+The samples file contains the most recently sampled values from the
+ADC.  There are 12.  Below are typical of the last sampled values when
+the pen has been released.  The first two and last two samples are for
+detecting whether or not the pen is down.  The third through sixth are
+X coordinate samples.  The seventh through tenth are Y coordinate
+samples.
+
+  # cat samples
+  1023 1023 0 0 0 0 530 529 530 529 1023 1023
+
+To determine a reasonable threshold, press on the touch panel with an
+appropriate stylus and read the values from samples.
+
+  # cat samples
+  1023 676 92 103 101 102 855 919 922 922 1023 679
+
+The first and eleventh samples are discarded.  Thus, the important
+values are the second and twelfth which are used to determine if the
+pen is down.  When both are below the threshold, the driver registers
+that the pen is down.  When either is above the threshold, it
+registers then pen is up.
diff --git a/Documentation/arm/Sharp-LH/LCDPanels b/Documentation/arm/Sharp-LH/LCDPanels
new file mode 100644
index 000000000..fb1b21c2f
--- /dev/null
+++ b/Documentation/arm/Sharp-LH/LCDPanels
@@ -0,0 +1,59 @@
+README on the LCD Panels
+========================
+
+Configuration options for several LCD panels, available from Logic PD,
+are included in the kernel source.  This README will help you
+understand the configuration data and give you some guidance for
+adding support for other panels if you wish.
+
+
+lcd-panels.h
+------------
+
+There is no way, at present, to detect which panel is attached to the
+system at runtime.  Thus the kernel configuration is static.  The file
+arch/arm/mach-ld7a40x/lcd-panels.h (or similar) defines all of the
+panel specific parameters.
+
+It should be possible for this data to be shared among several device
+families.  The current layout may be insufficiently general, but it is
+amenable to improvement.
+
+
+PIXEL_CLOCK
+-----------
+
+The panel data sheets will give a range of acceptable pixel clocks.
+The fundamental LCDCLK input frequency is divided down by a PCD
+constant in field '.tim2'.  It may happen that it is impossible to set
+the pixel clock within this range.  A clock which is too slow will
+tend to flicker.  For the highest quality image, set the clock as high
+as possible.
+
+
+MARGINS
+-------
+
+These values may be difficult to glean from the panel data sheet.  In
+the case of the Sharp panels, the upper margin is explicitly called
+out as a specific number of lines from the top of the frame.  The
+other values may not matter as much as the panels tend to
+automatically center the image.
+
+
+Sync Sense
+----------
+
+The sense of the hsync and vsync pulses may be called out in the data
+sheet.  On one panel, the sense of these pulses determine the height
+of the visible region on the panel.  Most of the Sharp panels use
+negative sense sync pulses set by the TIM2_IHS and TIM2_IVS bits in
+'.tim2'.
+
+
+Pel Layout
+----------
+
+The Sharp color TFT panels are all configured for 16 bit direct color
+modes.  The amba-lcd driver sets the pel mode to 565 for 5 bits of
+each red and blue and 6 bits of green.
diff --git a/Documentation/connector/ucon.c b/Documentation/connector/ucon.c
new file mode 100644
index 000000000..d738cde2a
--- /dev/null
+++ b/Documentation/connector/ucon.c
@@ -0,0 +1,206 @@
+/*
+ * 	ucon.c
+ *
+ * Copyright (c) 2004+ Evgeniy Polyakov <johnpol@2ka.mipt.ru>
+ *
+ *
+ * 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 <asm/types.h>
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/poll.h>
+
+#include <linux/netlink.h>
+#include <linux/rtnetlink.h>
+
+#include <arpa/inet.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include <time.h>
+
+#include <linux/connector.h>
+
+#define DEBUG
+#define NETLINK_CONNECTOR 	11
+
+#ifdef DEBUG
+#define ulog(f, a...) fprintf(stdout, f, ##a)
+#else
+#define ulog(f, a...) do {} while (0)
+#endif
+
+static int need_exit;
+static __u32 seq;
+
+static int netlink_send(int s, struct cn_msg *msg)
+{
+	struct nlmsghdr *nlh;
+	unsigned int size;
+	int err;
+	char buf[128];
+	struct cn_msg *m;
+
+	size = NLMSG_SPACE(sizeof(struct cn_msg) + msg->len);
+
+	nlh = (struct nlmsghdr *)buf;
+	nlh->nlmsg_seq = seq++;
+	nlh->nlmsg_pid = getpid();
+	nlh->nlmsg_type = NLMSG_DONE;
+	nlh->nlmsg_len = NLMSG_LENGTH(size - sizeof(*nlh));
+	nlh->nlmsg_flags = 0;
+
+	m = NLMSG_DATA(nlh);
+#if 0
+	ulog("%s: [%08x.%08x] len=%u, seq=%u, ack=%u.\n",
+	       __func__, msg->id.idx, msg->id.val, msg->len, msg->seq, msg->ack);
+#endif
+	memcpy(m, msg, sizeof(*m) + msg->len);
+
+	err = send(s, nlh, size, 0);
+	if (err == -1)
+		ulog("Failed to send: %s [%d].\n",
+			strerror(errno), errno);
+
+	return err;
+}
+
+int main(int argc, char *argv[])
+{
+	int s;
+	char buf[1024];
+	int len;
+	struct nlmsghdr *reply;
+	struct sockaddr_nl l_local;
+	struct cn_msg *data;
+	FILE *out;
+	time_t tm;
+	struct pollfd pfd;
+
+	if (argc < 2)
+		out = stdout;
+	else {
+		out = fopen(argv[1], "a+");
+		if (!out) {
+			ulog("Unable to open %s for writing: %s\n",
+				argv[1], strerror(errno));
+			out = stdout;
+		}
+	}
+
+	memset(buf, 0, sizeof(buf));
+
+	s = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_CONNECTOR);
+	if (s == -1) {
+		perror("socket");
+		return -1;
+	}
+
+	l_local.nl_family = AF_NETLINK;
+	l_local.nl_groups = 0x123; /* bitmask of requested groups */
+	l_local.nl_pid = 0;
+
+	if (bind(s, (struct sockaddr *)&l_local, sizeof(struct sockaddr_nl)) == -1) {
+		perror("bind");
+		close(s);
+		return -1;
+	}
+
+#if 0
+	{
+		int on = 0x57; /* Additional group number */
+		setsockopt(s, SOL_NETLINK, NETLINK_ADD_MEMBERSHIP, &on, sizeof(on));
+	}
+#endif
+	if (0) {
+		int i, j;
+
+		memset(buf, 0, sizeof(buf));
+
+		data = (struct cn_msg *)buf;
+
+		data->id.idx = 0x123;
+		data->id.val = 0x456;
+		data->seq = seq++;
+		data->ack = 0;
+		data->len = 0;
+
+		for (j=0; j<10; ++j) {
+			for (i=0; i<1000; ++i) {
+				len = netlink_send(s, data);
+			}
+
+			ulog("%d messages have been sent to %08x.%08x.\n", i, data->id.idx, data->id.val);
+		}
+
+		return 0;
+	}
+
+
+	pfd.fd = s;
+
+	while (!need_exit) {
+		pfd.events = POLLIN;
+		pfd.revents = 0;
+		switch (poll(&pfd, 1, -1)) {
+			case 0:
+				need_exit = 1;
+				break;
+			case -1:
+				if (errno != EINTR) {
+					need_exit = 1;
+					break;
+				}
+				continue;
+		}
+		if (need_exit)
+			break;
+
+		memset(buf, 0, sizeof(buf));
+		len = recv(s, buf, sizeof(buf), 0);
+		if (len == -1) {
+			perror("recv buf");
+			close(s);
+			return -1;
+		}
+		reply = (struct nlmsghdr *)buf;
+
+		switch (reply->nlmsg_type) {
+		case NLMSG_ERROR:
+			fprintf(out, "Error message received.\n");
+			fflush(out);
+			break;
+		case NLMSG_DONE:
+			data = (struct cn_msg *)NLMSG_DATA(reply);
+
+			time(&tm);
+			fprintf(out, "%.24s : [%x.%x] [%08u.%08u].\n",
+				ctime(&tm), data->id.idx, data->id.val, data->seq, data->ack);
+			fflush(out);
+			break;
+		default:
+			break;
+		}
+	}
+
+	close(s);
+	return 0;
+}
diff --git a/Documentation/console/console.txt b/Documentation/console/console.txt
new file mode 100644
index 000000000..d3e174473
--- /dev/null
+++ b/Documentation/console/console.txt
@@ -0,0 +1,144 @@
+Console Drivers
+===============
+
+The linux kernel has 2 general types of console drivers.  The first type is
+assigned by the kernel to all the virtual consoles during the boot process.
+This type will be called 'system driver', and only one system driver is allowed
+to exist. The system driver is persistent and it can never be unloaded, though
+it may become inactive.
+
+The second type has to be explicitly loaded and unloaded. This will be called
+'modular driver' by this document. Multiple modular drivers can coexist at
+any time with each driver sharing the console with other drivers including
+the system driver. However, modular drivers cannot take over the console
+that is currently occupied by another modular driver. (Exception: Drivers that
+call take_over_console() will succeed in the takeover regardless of the type
+of driver occupying the consoles.) They can only take over the console that is
+occupied by the system driver. In the same token, if the modular driver is
+released by the console, the system driver will take over.
+
+Modular drivers, from the programmer's point of view, has to call:
+
+	 take_over_console() - load and bind driver to console layer
+	 give_up_console() - unbind and unload driver
+
+In newer kernels, the following are also available:
+
+	 register_con_driver()
+	 unregister_con_driver()
+
+If sysfs is enabled, the contents of /sys/class/vtconsole can be
+examined. This shows the console backends currently registered by the
+system which are named vtcon<n> where <n> is an integer fro 0 to 15. Thus:
+
+       ls /sys/class/vtconsole
+       .  ..  vtcon0  vtcon1
+
+Each directory in /sys/class/vtconsole has 3 files:
+
+     ls /sys/class/vtconsole/vtcon0
+     .  ..  bind  name  uevent
+
+What do these files signify?
+
+     1. bind - this is a read/write file. It shows the status of the driver if
+        read, or acts to bind or unbind the driver to the virtual consoles
+        when written to. The possible values are:
+
+	0 - means the driver is not bound and if echo'ed, commands the driver
+	    to unbind
+
+        1 - means the driver is bound and if echo'ed, commands the driver to
+	    bind
+
+     2. name - read-only file. Shows the name of the driver in this format:
+
+	cat /sys/class/vtconsole/vtcon0/name
+	(S) VGA+
+
+	    '(S)' stands for a (S)ystem driver, ie, it cannot be directly
+	    commanded to bind or unbind
+
+	    'VGA+' is the name of the driver
+
+	cat /sys/class/vtconsole/vtcon1/name
+	(M) frame buffer device
+
+	    In this case, '(M)' stands for a (M)odular driver, one that can be
+	    directly commanded to bind or unbind.
+
+     3. uevent - ignore this file
+
+When unbinding, the modular driver is detached first, and then the system
+driver takes over the consoles vacated by the driver. Binding, on the other
+hand, will bind the driver to the consoles that are currently occupied by a
+system driver.
+
+NOTE1: Binding and binding must be selected in Kconfig. It's under:
+
+Device Drivers -> Character devices -> Support for binding and unbinding
+console drivers
+
+NOTE2: If any of the virtual consoles are in KD_GRAPHICS mode, then binding or
+unbinding will not succeed. An example of an application that sets the console
+to KD_GRAPHICS is X.
+
+How useful is this feature? This is very useful for console driver
+developers. By unbinding the driver from the console layer, one can unload the
+driver, make changes, recompile, reload and rebind the driver without any need
+for rebooting the kernel. For regular users who may want to switch from
+framebuffer console to VGA console and vice versa, this feature also makes
+this possible. (NOTE NOTE NOTE: Please read fbcon.txt under Documentation/fb
+for more details).
+
+Notes for developers:
+=====================
+
+take_over_console() is now broken up into:
+
+     register_con_driver()
+     bind_con_driver() - private function
+
+give_up_console() is a wrapper to unregister_con_driver(), and a driver must
+be fully unbound for this call to succeed. con_is_bound() will check if the
+driver is bound or not.
+
+Guidelines for console driver writers:
+=====================================
+
+In order for binding to and unbinding from the console to properly work,
+console drivers must follow these guidelines:
+
+1. All drivers, except system drivers, must call either register_con_driver()
+   or take_over_console(). register_con_driver() will just add the driver to
+   the console's internal list. It won't take over the
+   console. take_over_console(), as it name implies, will also take over (or
+   bind to) the console.
+
+2. All resources allocated during con->con_init() must be released in
+   con->con_deinit().
+
+3. All resources allocated in con->con_startup() must be released when the
+   driver, which was previously bound, becomes unbound.  The console layer
+   does not have a complementary call to con->con_startup() so it's up to the
+   driver to check when it's legal to release these resources. Calling
+   con_is_bound() in con->con_deinit() will help.  If the call returned
+   false(), then it's safe to release the resources.  This balance has to be
+   ensured because con->con_startup() can be called again when a request to
+   rebind the driver to the console arrives.
+
+4. Upon exit of the driver, ensure that the driver is totally unbound. If the
+   condition is satisfied, then the driver must call unregister_con_driver()
+   or give_up_console().
+
+5. unregister_con_driver() can also be called on conditions which make it
+   impossible for the driver to service console requests.  This can happen
+   with the framebuffer console that suddenly lost all of its drivers.
+
+The current crop of console drivers should still work correctly, but binding
+and unbinding them may cause problems. With minimal fixes, these drivers can
+be made to work correctly.
+
+==========================
+Antonino Daplas <adaplas@pol.net>
+
diff --git a/Documentation/fb/imacfb.txt b/Documentation/fb/imacfb.txt
new file mode 100644
index 000000000..759028545
--- /dev/null
+++ b/Documentation/fb/imacfb.txt
@@ -0,0 +1,31 @@
+
+What is imacfb?
+===============
+
+This is a generic EFI platform driver for Intel based Apple computers.
+Imacfb is only for EFI booted Intel Macs.
+
+Supported Hardware
+==================
+
+iMac 17"/20"
+Macbook
+Macbook Pro 15"/17"
+MacMini
+
+How to use it?
+==============
+
+Imacfb does not have any kind of autodetection of your machine.
+You have to add the fillowing kernel parameters in your elilo.conf:
+	Macbook :
+		video=imacfb:macbook
+	MacMini :
+		video=imacfb:mini
+	Macbook Pro 15", iMac 17" :
+		video=imacfb:i17
+	Macbook Pro 17", iMac 20" :
+		video=imacfb:i20
+
+--
+Edgar Hucek <gimli@dark-green.com>
diff --git a/Documentation/filesystems/caching/backend-api.txt b/Documentation/filesystems/caching/backend-api.txt
new file mode 100644
index 000000000..1dd601b50
--- /dev/null
+++ b/Documentation/filesystems/caching/backend-api.txt
@@ -0,0 +1,357 @@
+			  ==========================
+			  FS-CACHE CACHE BACKEND API
+			  ==========================
+
+The FS-Cache system provides an API by which actual caches can be supplied to
+FS-Cache for it to then serve out to network filesystems and other interested
+parties.
+
+This API is declared in <linux/fscache-cache.h>.
+
+
+====================================
+INITIALISING AND REGISTERING A CACHE
+====================================
+
+To start off, a cache definition must be initialised and registered for each
+cache the backend wants to make available.  For instance, CacheFS does this in
+the fill_super() operation on mounting.
+
+The cache definition (struct fscache_cache) should be initialised by calling:
+
+	void fscache_init_cache(struct fscache_cache *cache,
+				struct fscache_cache_ops *ops,
+				const char *idfmt,
+				...)
+
+Where:
+
+ (*) "cache" is a pointer to the cache definition;
+
+ (*) "ops" is a pointer to the table of operations that the backend supports on
+     this cache;
+
+ (*) and a format and printf-style arguments for constructing a label for the
+     cache.
+
+
+The cache should then be registered with FS-Cache by passing a pointer to the
+previously initialised cache definition to:
+
+	int fscache_add_cache(struct fscache_cache *cache,
+			      struct fscache_object *fsdef,
+			      const char *tagname);
+
+Two extra arguments should also be supplied:
+
+ (*) "fsdef" which should point to the object representation for the FS-Cache
+     master index in this cache.  Netfs primary index entries will be created
+     here.
+
+ (*) "tagname" which, if given, should be a text string naming this cache.  If
+     this is NULL, the identifier will be used instead.  For CacheFS, the
+     identifier is set to name the underlying block device and the tag can be
+     supplied by mount.
+
+This function may return -ENOMEM if it ran out of memory or -EEXIST if the tag
+is already in use.  0 will be returned on success.
+
+
+=====================
+UNREGISTERING A CACHE
+=====================
+
+A cache can be withdrawn from the system by calling this function with a
+pointer to the cache definition:
+
+	void fscache_withdraw_cache(struct fscache_cache *cache)
+
+In CacheFS's case, this is called by put_super().
+
+
+==================
+FS-CACHE UTILITIES
+==================
+
+FS-Cache provides some utilities that a cache backend may make use of:
+
+ (*) Find the parent of an object:
+
+	struct fscache_object *
+	fscache_find_parent_object(struct fscache_object *object)
+
+     This allows a backend to find the logical parent of an index or data file
+     in the cache hierarchy.
+
+ (*) Note occurrence of an I/O error in a cache:
+
+	void fscache_io_error(struct fscache_cache *cache)
+
+     This tells FS-Cache that an I/O error occurred in the cache.  After this
+     has been called, only resource dissociation operations (object and page
+     release) will be passed from the netfs to the cache backend for the
+     specified cache.
+
+     This does not actually withdraw the cache.  That must be done separately.
+
+ (*) Get an extra reference to a read or write context:
+
+	void *fscache_get_context(struct fscache_cookie *cookie, void *context)
+
+     and release a reference:
+
+	void *fscache_put_context(struct fscache_cookie *cookie, void *context)
+
+     These should be used to maintain the presence of the read or write context
+     passed to the cache read/write functions.  This context must then be
+     passed to the I/O completion function.
+
+
+========================
+RELEVANT DATA STRUCTURES
+========================
+
+ (*) Index/Data file FS-Cache representation cookie:
+
+	struct fscache_cookie {
+		struct fscache_object_def	*def;
+		struct fscache_netfs		*netfs;
+		void				*netfs_data;
+		...
+	};
+
+     The fields that might be of use to the backend describe the object
+     definition, the netfs definition and the netfs's data for this cookie.
+     The object definition contain functions supplied by the netfs for loading
+     and matching index entries; these are required to provide some of the
+     cache operations.
+
+ (*) In-cache object representation:
+
+	struct fscache_object {
+		struct fscache_cache		*cache;
+		struct fscache_cookie		*cookie;
+		unsigned long			flags;
+	#define FSCACHE_OBJECT_RECYCLING	1
+		...
+	};
+
+     Structures of this type should be allocated by the cache backend and
+     passed to FS-Cache when requested by the appropriate cache operation.  In
+     the case of CacheFS, they're embedded in CacheFS's internal object
+     structures.
+
+     Each object contains a pointer to the cookie that represents the object it
+     is backing.  It also contains a flag that indicates whether the object is
+     being retired when put_object() is called.  This should be initialised by
+     calling fscache_object_init(object).
+
+
+================
+CACHE OPERATIONS
+================
+
+The cache backend provides FS-Cache with a table of operations that can be
+performed on the denizens of the cache.  These are held in a structure of type:
+
+	struct fscache_cache_ops
+
+ (*) Name of cache provider [mandatory]:
+
+	const char *name
+
+     This isn't strictly an operation, but should be pointed at a string naming
+     the backend.
+
+ (*) Object lookup [mandatory]:
+
+	struct fscache_object *(*lookup_object)(struct fscache_cache *cache,
+						struct fscache_object *parent,
+						struct fscache_cookie *cookie)
+
+     This method is used to look up an object in the specified cache, given a
+     pointer to the parent object and the cookie to which the object will be
+     attached.  This should instantiate that object in the cache if it can, or
+     return -ENOBUFS or -ENOMEM if it can't.
+
+ (*) Increment object refcount [mandatory]:
+
+	struct fscache_object *(*grab_object)(struct fscache_object *object)
+
+     This method is called to increment the reference count on an object.  It
+     may fail (for instance if the cache is being withdrawn) by returning NULL.
+     It should return the object pointer if successful.
+
+ (*) Lock/Unlock object [mandatory]:
+
+	void (*lock_object)(struct fscache_object *object)
+	void (*unlock_object)(struct fscache_object *object)
+
+     These methods are used to exclusively lock an object.  It must be possible
+     to schedule with the lock held, so a spinlock isn't sufficient.
+
+ (*) Pin/Unpin object [optional]:
+
+	int (*pin_object)(struct fscache_object *object)
+	void (*unpin_object)(struct fscache_object *object)
+
+     These methods are used to pin an object into the cache.  Once pinned an
+     object cannot be reclaimed to make space.  Return -ENOSPC if there's not
+     enough space in the cache to permit this.
+
+ (*) Update object [mandatory]:
+
+	int (*update_object)(struct fscache_object *object)
+
+     This is called to update the index entry for the specified object.  The
+     new information should be in object->cookie->netfs_data.  This can be
+     obtained by calling object->cookie->def->get_aux()/get_attr().
+
+ (*) Release object reference [mandatory]:
+
+	void (*put_object)(struct fscache_object *object)
+
+     This method is used to discard a reference to an object.  The object may
+     be destroyed when all the references held by FS-Cache are released.
+
+ (*) Synchronise a cache [mandatory]:
+
+	void (*sync)(struct fscache_cache *cache)
+
+     This is called to ask the backend to synchronise a cache with its backing
+     device.
+
+ (*) Dissociate a cache [mandatory]:
+
+	void (*dissociate_pages)(struct fscache_cache *cache)
+
+     This is called to ask a cache to perform any page dissociations as part of
+     cache withdrawal.
+
+ (*) Set the data size on a cache file [mandatory]:
+
+	int (*set_i_size)(struct fscache_object *object, loff_t i_size);
+
+     This is called to indicate to the cache the maximum size a file may reach.
+     The cache may use this to reserve space on the cache.  It may also return
+     -ENOBUFS to indicate that insufficient space is available to expand the
+     metadata used to track the data.  It should return 0 if successful or
+     -ENOMEM or -EIO on error.
+
+ (*) Reserve cache space for an object's data [optional]:
+
+	int (*reserve_space)(struct fscache_object *object, loff_t size);
+
+     This is called to request that cache space be reserved to hold the data
+     for an object and the metadata used to track it.  Zero size should be
+     taken as request to cancel a reservation.
+
+     This should return 0 if successful, -ENOSPC if there isn't enough space
+     available, or -ENOMEM or -EIO on other errors.
+
+     The reservation may exceed the size of the object, thus permitting future
+     expansion.  If the amount of space consumed by an object would exceed the
+     reservation, it's permitted to refuse requests to allocate pages, but not
+     required.  An object may be pruned down to its reservation size if larger
+     than that already.
+
+ (*) Request page be read from cache [mandatory]:
+
+	int (*read_or_alloc_page)(struct fscache_object *object,
+				  struct page *page,
+				  fscache_rw_complete_t end_io_func,
+				  void *end_io_data,
+				  gfp_t gfp)
+
+     This is called to attempt to read a netfs page from the cache, or to
+     reserve a backing block if not.  FS-Cache will have done as much checking
+     as it can before calling, but most of the work belongs to the backend.
+
+     If there's no page in the cache, then -ENODATA should be returned if the
+     backend managed to reserve a backing block; -ENOBUFS, -ENOMEM or -EIO if
+     it didn't.
+
+     If there is a page in the cache, then a read operation should be queued
+     and 0 returned.  When the read finishes, end_io_func() should be called
+     with the following arguments:
+
+	(*end_io_func)(object->cookie->netfs_data,
+		       page,
+		       end_io_data,
+		       error);
+
+     The mark_pages_cached() cookie operation should be called for the page if
+     any cache metadata is retained.  This will indicate to the netfs that the
+     page needs explicit uncaching.  This operation takes a pagevec, thus
+     allowing several pages to be marked at once.
+
+ (*) Request pages be read from cache [mandatory]:
+
+	int (*read_or_alloc_pages)(struct fscache_object *object,
+				   struct address_space *mapping,
+				   struct list_head *pages,
+				   unsigned *nr_pages,
+				   fscache_rw_complete_t end_io_func,
+				   void *end_io_data,
+				   gfp_t gfp)
+
+     This is like the previous operation, except it will be handed a list of
+     pages instead of one page.  Any pages on which a read operation is started
+     must be added to the page cache for the specified mapping and also to the
+     LRU.  Such pages must also be removed from the pages list and nr_pages
+     decremented per page.
+
+     If there was an error such as -ENOMEM, then that should be returned; else
+     if one or more pages couldn't be read or allocated, then -ENOBUFS should
+     be returned; else if one or more pages couldn't be read, then -ENODATA
+     should be returned.  If all the pages are dispatched then 0 should be
+     returned.
+
+ (*) Request page be allocated in the cache [mandatory]:
+
+	int (*allocate_page)(struct fscache_object *object,
+			     struct page *page,
+			     gfp_t gfp)
+
+     This is like read_or_alloc_page(), except that it shouldn't read from the
+     cache, even if there's data there that could be retrieved.  It should,
+     however, set up any internal metadata required such that write_page() can
+     write to the cache.
+
+     If there's no backing block available, then -ENOBUFS should be returned
+     (or -ENOMEM or -EIO if there were other problems).  If a block is
+     successfully allocated, then the netfs page should be marked and 0
+     returned.
+
+ (*) Request page be written to cache [mandatory]:
+
+	int (*write_page)(struct fscache_object *object,
+			  struct page *page,
+			  fscache_rw_complete_t end_io_func,
+			  void *end_io_data,
+			  gfp_t gfp)
+
+     This is called to write from a page on which there was a previously
+     successful read_or_alloc_page() call.  FS-Cache filters out pages that
+     don't have mappings.
+
+     If there's no backing block available, then -ENOBUFS should be returned
+     (or -ENOMEM or -EIO if there were other problems).
+
+     If the write operation could be queued, then 0 should be returned.  When
+     the write completes, end_io_func() should be called with the following
+     arguments:
+
+	(*end_io_func)(object->cookie->netfs_data,
+		       page,
+		       end_io_data,
+		       error);
+
+ (*) Discard retained per-page metadata [mandatory]:
+
+	void (*uncache_pages)(struct fscache_object *object,
+			      struct pagevec *pagevec)
+
+     This is called when one or more netfs pages are being evicted from the
+     pagecache.  The cache backend should tear down any internal representation
+     or tracking it maintains.
diff --git a/Documentation/filesystems/caching/cachefiles.txt b/Documentation/filesystems/caching/cachefiles.txt
new file mode 100644
index 000000000..37b6385e0
--- /dev/null
+++ b/Documentation/filesystems/caching/cachefiles.txt
@@ -0,0 +1,281 @@
+	       ===============================================
+	       CacheFiles: CACHE ON ALREADY MOUNTED FILESYSTEM
+	       ===============================================
+
+Contents:
+
+ (*) Overview.
+
+ (*) Requirements.
+
+ (*) Configuration.
+
+ (*) Starting the cache.
+
+ (*) Things to avoid.
+
+
+========
+OVERVIEW
+========
+
+CacheFiles is a caching backend that's meant to use as a cache a directory on
+an already mounted filesystem of a local type (such as Ext3).
+
+CacheFiles uses a userspace daemon to do some of the cache management - such as
+reaping stale nodes and culling.  This is called cachefilesd and lives in
+/sbin.
+
+The filesystem and data integrity of the cache are only as good as those of the
+filesystem providing the backing services.  Note that CacheFiles does not
+attempt to journal anything since the journalling interfaces of the various
+filesystems are very specific in nature.
+
+CacheFiles creates a proc-file - "/proc/fs/cachefiles" - that is used for
+communication with the daemon.  Only one thing may have this open at once, and
+whilst it is open, a cache is at least partially in existence.  The daemon
+opens this and sends commands down it to control the cache.
+
+CacheFiles is currently limited to a single cache.
+
+CacheFiles attempts to maintain at least a certain percentage of free space on
+the filesystem, shrinking the cache by culling the objects it contains to make
+space if necessary - see the "Cache Culling" section.  This means it can be
+placed on the same medium as a live set of data, and will expand to make use of
+spare space and automatically contract when the set of data requires more
+space.
+
+
+============
+REQUIREMENTS
+============
+
+The use of CacheFiles and its daemon requires the following features to be
+available in the system and in the cache filesystem:
+
+	- dnotify.
+
+	- extended attributes (xattrs).
+
+	- openat() and friends.
+
+	- bmap() support on files in the filesystem (FIBMAP ioctl).
+
+	- The use of bmap() to detect a partial page at the end of the file.
+
+It is strongly recommended that the "dir_index" option is enabled on Ext3
+filesystems being used as a cache.
+
+
+=============
+CONFIGURATION
+=============
+
+The cache is configured by a script in /etc/cachefilesd.conf.  These commands
+set up cache ready for use.  The following script commands are available:
+
+ (*) brun <N>%
+ (*) bcull <N>%
+ (*) bstop <N>%
+
+	Configure the culling limits.  Optional.  See the section on culling
+	The defaults are 7%, 5% and 1% respectively.
+
+ (*) dir <path>
+
+	Specify the directory containing the root of the cache.  Mandatory.
+
+ (*) tag <name>
+
+	Specify a tag to FS-Cache to use in distinguishing multiple caches.
+	Optional.  The default is "CacheFiles".
+
+ (*) debug <mask>
+
+	Specify a numeric bitmask to control debugging in the kernel module.
+	Optional.  The default is zero (all off).  The following values can be
+	OR'd into the mask to collect various information:
+
+		1	Turn on trace of function entry (_enter() macros)
+		2	Turn on trace of function exit (_leave() macros)
+		4	Turn on trace of internal debug points (_debug())
+
+	This mask can also be set through /proc/sys/fs/cachefiles/debug.
+
+
+==================
+STARTING THE CACHE
+==================
+
+The cache is started by running the daemon.  The daemon opens the cache proc
+file, configures the cache and tells it to begin caching.  At that point the
+cache binds to fscache and the cache becomes live.
+
+The daemon is run as follows:
+
+	/sbin/cachefilesd [-d]* [-s] [-n] [-f <configfile>]
+
+The flags are:
+
+ (*) -d
+
+	Increase the debugging level.  This can be specified multiple times and
+	is cumulative with itself.
+
+ (*) -s
+
+	Send messages to stderr instead of syslog.
+
+ (*) -n
+
+	Don't daemonise and go into background.
+
+ (*) -f <configfile>
+
+	Use an alternative configuration file rather than the default one.
+
+
+===============
+THINGS TO AVOID
+===============
+
+Do not mount other things within the cache as this will cause problems.  The
+kernel module contains its own very cut-down path walking facility that ignores
+mountpoints, but the daemon can't avoid them.
+
+Do not create, rename or unlink files and directories in the cache whilst the
+cache is active, as this may cause the state to become uncertain.
+
+Renaming files in the cache might make objects appear to be other objects (the
+filename is part of the lookup key).
+
+Do not change or remove the extended attributes attached to cache files by the
+cache as this will cause the cache state management to get confused.
+
+Do not create files or directories in the cache, lest the cache get confused or
+serve incorrect data.
+
+Do not chmod files in the cache.  The module creates things with minimal
+permissions to prevent random users being able to access them directly.
+
+
+=============
+CACHE CULLING
+=============
+
+The cache may need culling occasionally to make space.  This involves
+discarding objects from the cache that have been used less recently than
+anything else.  Culling is based on the access time of data objects.  Empty
+directories are culled if not in use.
+
+Cache culling is done on the basis of the percentage of blocks available in the
+underlying filesystem.  There are three "limits":
+
+ (*) brun
+
+     If the amount of available space in the cache rises above this limit, then
+     culling is turned off.
+
+ (*) bcull
+
+     If the amount of available space in the cache falls below this limit, then
+     culling is started.
+
+ (*) bstop
+
+     If the amount of available space in the cache falls below this limit, then
+     no further allocation of disk space is permitted until culling has raised
+     the amount above this limit again.
+
+These must be configured thusly:
+
+	0 <= bstop < bcull < brun < 100
+
+Note that these are percentages of available space, and do _not_ appear as 100
+minus the percentage displayed by the "df" program.
+
+The userspace daemon scans the cache to build up a table of cullable objects.
+These are then culled in least recently used order.  A new scan of the cache is
+started as soon as space is made in the table.  Objects will be skipped if
+their atimes have changed or if the kernel module says it is still using them.
+
+
+===============
+CACHE STRUCTURE
+===============
+
+The CacheFiles module will create two directories in the directory it was
+given:
+
+ (*) cache/
+
+ (*) graveyard/
+
+The active cache objects all reside in the first directory.  The CacheFiles
+kernel module moves any retired or culled objects that it can't simply unlink
+to the graveyard from which the daemon will actually delete them.
+
+The daemon uses dnotify to monitor the graveyard directory, and will delete
+anything that appears therein.
+
+
+The module represents index objects as directories with the filename "I..." or
+"J...".  Note that the "cache/" directory is itself a special index.
+
+Data objects are represented as files if they have no children, or directories
+if they do.  Their filenames all begin "D..." or "E...".  If represented as a
+directory, data objects will have a file in the directory called "data" that
+actually holds the data.
+
+Special objects are similar to data objects, except their filenames begin
+"S..." or "T...".
+
+
+If an object has children, then it will be represented as a directory.
+Immediately in the representative directory are a collection of directories
+named for hash values of the child object keys with an '@' prepended.  Into
+this directory, if possible, will be placed the representations of the child
+objects:
+
+	INDEX     INDEX      INDEX                             DATA FILES
+	========= ========== ================================= ================
+	cache/@4a/I03nfs/@30/Ji000000000000000--fHg8hi8400
+	cache/@4a/I03nfs/@30/Ji000000000000000--fHg8hi8400/@75/Es0g000w...DB1ry
+	cache/@4a/I03nfs/@30/Ji000000000000000--fHg8hi8400/@75/Es0g000w...N22ry
+	cache/@4a/I03nfs/@30/Ji000000000000000--fHg8hi8400/@75/Es0g000w...FP1ry
+
+
+If the key is so long that it exceeds NAME_MAX with the decorations added on to
+it, then it will be cut into pieces, the first few of which will be used to
+make a nest of directories, and the last one of which will be the objects
+inside the last directory.  The names of the intermediate directories will have
+'+' prepended:
+
+	J1223/@23/+xy...z/+kl...m/Epqr
+
+
+Note that keys are raw data, and not only may they exceed NAME_MAX in size,
+they may also contain things like '/' and NUL characters, and so they may not
+be suitable for turning directly into a filename.
+
+To handle this, CacheFiles will use a suitably printable filename directly and
+"base-64" encode ones that aren't directly suitable.  The two versions of
+object filenames indicate the encoding:
+
+	OBJECT TYPE	PRINTABLE	ENCODED
+	===============	===============	===============
+	Index		"I..."		"J..."
+	Data		"D..."		"E..."
+	Special		"S..."		"T..."
+
+Intermediate directories are always "@" or "+" as appropriate.
+
+
+Each object in the cache has an extended attribute label that holds the object
+type ID (required to distinguish special objects) and the auxiliary data from
+the netfs.  The latter is used to detect stale objects in the cache and update
+or retire them.
+
+
+Note that CacheFiles will erase from the cache any file it doesn't recognise or
+any file of an incorrect type (such as a FIFO file or a device file).
diff --git a/Documentation/filesystems/caching/fscache.txt b/Documentation/filesystems/caching/fscache.txt
new file mode 100644
index 000000000..82c31682e
--- /dev/null
+++ b/Documentation/filesystems/caching/fscache.txt
@@ -0,0 +1,151 @@
+			  ==========================
+			  General Filesystem Caching
+			  ==========================
+
+========
+OVERVIEW
+========
+
+This facility is a general purpose cache for network filesystems, though it
+could be used for caching other things such as ISO9660 filesystems too.
+
+FS-Cache mediates between cache backends (such as CacheFS) and network
+filesystems:
+
+	+---------+
+	|         |                        +--------------+
+	|   NFS   |--+                     |              |
+	|         |  |                 +-->|   CacheFS    |
+	+---------+  |   +----------+  |   |  /dev/hda5   |
+	             |   |          |  |   +--------------+
+	+---------+  +-->|          |  |
+	|         |      |          |--+
+	|   AFS   |----->| FS-Cache |
+	|         |      |          |--+
+	+---------+  +-->|          |  |
+	             |   |          |  |   +--------------+
+	+---------+  |   +----------+  |   |              |
+	|         |  |                 +-->|  CacheFiles  |
+	|  ISOFS  |--+                     |  /var/cache  |
+	|         |                        +--------------+
+	+---------+
+
+
+FS-Cache does not follow the idea of completely loading every netfs file
+opened in its entirety into a cache before permitting it to be accessed and
+then serving the pages out of that cache rather than the netfs inode because:
+
+ (1) It must be practical to operate without a cache.
+
+ (2) The size of any accessible file must not be limited to the size of the
+     cache.
+
+ (3) The combined size of all opened files (this includes mapped libraries)
+     must not be limited to the size of the cache.
+
+ (4) The user should not be forced to download an entire file just to do a
+     one-off access of a small portion of it (such as might be done with the
+     "file" program).
+
+It instead serves the cache out in PAGE_SIZE chunks as and when requested by
+the netfs('s) using it.
+
+
+FS-Cache provides the following facilities:
+
+ (1) More than one cache can be used at once.  Caches can be selected
+     explicitly by use of tags.
+
+ (2) Caches can be added / removed at any time.
+
+ (3) The netfs is provided with an interface that allows either party to
+     withdraw caching facilities from a file (required for (2)).
+
+ (4) The interface to the netfs returns as few errors as possible, preferring
+     rather to let the netfs remain oblivious.
+
+ (5) Cookies are used to represent indices, files and other objects to the
+     netfs.  The simplest cookie is just a NULL pointer - indicating nothing
+     cached there.
+
+ (6) The netfs is allowed to propose - dynamically - any index hierarchy it
+     desires, though it must be aware that the index search function is
+     recursive, stack space is limited, and indices can only be children of
+     indices.
+
+ (7) Data I/O is done direct to and from the netfs's pages.  The netfs
+     indicates that page A is at index B of the data-file represented by cookie
+     C, and that it should be read or written.  The cache backend may or may
+     not start I/O on that page, but if it does, a netfs callback will be
+     invoked to indicate completion.  The I/O may be either synchronous or
+     asynchronous.
+
+ (8) Cookies can be "retired" upon release.  At this point FS-Cache will mark
+     them as obsolete and the index hierarchy rooted at that point will get
+     recycled.
+
+ (9) The netfs provides a "match" function for index searches.  In addition to
+     saying whether a match was made or not, this can also specify that an
+     entry should be updated or deleted.
+
+
+FS-Cache maintains a virtual indexing tree in which all indices, files, objects
+and pages are kept.  Bits of this tree may actually reside in one or more
+caches.
+
+                                           FSDEF
+                                             |
+                        +------------------------------------+
+                        |                                    |
+                       NFS                                  AFS
+                        |                                    |
+           +--------------------------+                +-----------+
+           |                          |                |           |
+        homedir                     mirror          afs.org   redhat.com
+           |                          |                            |
+     +------------+           +---------------+              +----------+
+     |            |           |               |              |          |
+   00001        00002       00007           00125        vol00001   vol00002
+     |            |           |               |                         |
+ +---+---+     +-----+      +---+      +------+------+            +-----+----+
+ |   |   |     |     |      |   |      |      |      |            |     |    |
+PG0 PG1 PG2   PG0  XATTR   PG0 PG1   DIRENT DIRENT DIRENT        R/W   R/O  Bak
+                     |                                            |
+                    PG0                                       +-------+
+                                                              |       |
+                                                            00001   00003
+                                                              |
+                                                          +---+---+
+                                                          |   |   |
+                                                         PG0 PG1 PG2
+
+In the example above, you can see two netfs's being backed: NFS and AFS.  These
+have different index hierarchies:
+
+ (*) The NFS primary index contains per-server indices.  Each server index is
+     indexed by NFS file handles to get data file objects.  Each data file
+     objects can have an array of pages, but may also have further child
+     objects, such as extended attributes and directory entries.  Extended
+     attribute objects themselves have page-array contents.
+
+ (*) The AFS primary index contains per-cell indices.  Each cell index contains
+     per-logical-volume indices.  Each of volume index contains up to three
+     indices for the read-write, read-only and backup mirrors of those volumes.
+     Each of these contains vnode data file objects, each of which contains an
+     array of pages.
+
+The very top index is the FS-Cache master index in which individual netfs's
+have entries.
+
+Any index object may reside in more than one cache, provided it only has index
+children.  Any index with non-index object children will be assumed to only
+reside in one cache.
+
+
+The netfs API to FS-Cache can be found in:
+
+	Documentation/filesystems/caching/netfs-api.txt
+
+The cache backend API to FS-Cache can be found in:
+
+	Documentation/filesystems/caching/backend-api.txt
diff --git a/Documentation/filesystems/caching/netfs-api.txt b/Documentation/filesystems/caching/netfs-api.txt
new file mode 100644
index 000000000..a1a182beb
--- /dev/null
+++ b/Documentation/filesystems/caching/netfs-api.txt
@@ -0,0 +1,752 @@
+			===============================
+			FS-CACHE NETWORK FILESYSTEM API
+			===============================
+
+There's an API by which a network filesystem can make use of the FS-Cache
+facilities.  This is based around a number of principles:
+
+ (1) Caches can store a number of different object types.  There are two main
+     object types: indices and files.  The first is a special type used by
+     FS-Cache to make finding objects faster and to make retiring of groups of
+     objects easier.
+
+ (2) Every index, file or other object is represented by a cookie.  This cookie
+     may or may not have anything associated with it, but the netfs doesn't
+     need to care.
+
+ (3) Barring the top-level index (one entry per cached netfs), the index
+     hierarchy for each netfs is structured according the whim of the netfs.
+
+This API is declared in <linux/fscache.h>.
+
+This document contains the following sections:
+
+	 (1) Network filesystem definition
+	 (2) Index definition
+	 (3) Object definition
+	 (4) Network filesystem (un)registration
+	 (5) Cache tag lookup
+	 (6) Index registration
+	 (7) Data file registration
+	 (8) Miscellaneous object registration
+	 (9) Setting the data file size
+	(10) Page alloc/read/write
+	(11) Page uncaching
+	(12) Index and data file update
+	(13) Miscellaneous cookie operations
+	(14) Cookie unregistration
+	(15) Index and data file invalidation
+
+
+=============================
+NETWORK FILESYSTEM DEFINITION
+=============================
+
+FS-Cache needs a description of the network filesystem.  This is specified
+using a record of the following structure:
+
+	struct fscache_netfs {
+		uint32_t			version;
+		const char			*name;
+		struct fscache_netfs_operations	*ops;
+		struct fscache_cookie		*primary_index;
+		...
+	};
+
+This first three fields should be filled in before registration, and the fourth
+will be filled in by the registration function; any other fields should just be
+ignored and are for internal use only.
+
+The fields are:
+
+ (1) The name of the netfs (used as the key in the toplevel index).
+
+ (2) The version of the netfs (if the name matches but the version doesn't, the
+     entire in-cache hierarchy for this netfs will be scrapped and begun
+     afresh).
+
+ (3) The operations table is defined as follows:
+
+	struct fscache_netfs_operations {
+	};
+
+     Currently there aren't any functions here.
+
+ (4) The cookie representing the primary index will be allocated according to
+     another parameter passed into the registration function.
+
+For example, kAFS (linux/fs/afs/) uses the following definitions to describe
+itself:
+
+	static struct fscache_netfs_operations afs_cache_ops = {
+	};
+
+	struct fscache_netfs afs_cache_netfs = {
+		.version	= 0,
+		.name		= "afs",
+		.ops		= &afs_cache_ops,
+	};
+
+
+================
+INDEX DEFINITION
+================
+
+Indices are used for two purposes:
+
+ (1) To aid the finding of a file based on a series of keys (such as AFS's
+     "cell", "volume ID", "vnode ID").
+
+ (2) To make it easier to discard a subset of all the files cached based around
+     a particular key - for instance to mirror the removal of an AFS volume.
+
+However, since it's unlikely that any two netfs's are going to want to define
+their index hierarchies in quite the same way, FS-Cache tries to impose as few
+restraints as possible on how an index is structured and where it is placed in
+the tree.  The netfs can even mix indices and data files at the same level, but
+it's not recommended.
+
+Each index entry consists of a key of indeterminate length plus some auxilliary
+data, also of indeterminate length.
+
+There are some limits on indices:
+
+ (1) Any index containing non-index objects should be restricted to a single
+     cache.  Any such objects created within an index will be created in the
+     first cache only.  The cache in which an index is created can be
+     controlled by cache tags (see below).
+
+ (2) The entry data must be atomically journallable, so it is limited to about
+     400 bytes at present.  At least 400 bytes will be available.
+
+ (3) The depth of the index tree should be judged with care as the search
+     function is recursive.  Too many layers will run the kernel out of stack.
+
+
+=================
+OBJECT DEFINITION
+=================
+
+To define an object, a structure of the following type should be filled out:
+
+	struct fscache_object_def
+	{
+		uint8_t name[16];
+		uint8_t type;
+
+		struct fscache_cache_tag *(*select_cache)(
+			const void *parent_netfs_data,
+			const void *cookie_netfs_data);
+
+		uint16_t (*get_key)(const void *cookie_netfs_data,
+				    void *buffer,
+				    uint16_t bufmax);
+
+		void (*get_attr)(const void *cookie_netfs_data,
+				 uint64_t *size);
+
+		uint16_t (*get_aux)(const void *cookie_netfs_data,
+				    void *buffer,
+				    uint16_t bufmax);
+
+		fscache_checkaux_t (*check_aux)(void *cookie_netfs_data,
+						const void *data,
+						uint16_t datalen);
+
+		void (*get_context)(void *cookie_netfs_data, void *context);
+
+		void (*put_context)(void *cookie_netfs_data, void *context);
+
+		void (*mark_pages_cached)(void *cookie_netfs_data,
+					  struct address_space *mapping,
+					  struct pagevec *cached_pvec);
+
+		void (*now_uncached)(void *cookie_netfs_data);
+	};
+
+This has the following fields:
+
+ (1) The type of the object [mandatory].
+
+     This is one of the following values:
+
+	(*) FSCACHE_COOKIE_TYPE_INDEX
+
+	    This defines an index, which is a special FS-Cache type.
+
+	(*) FSCACHE_COOKIE_TYPE_DATAFILE
+
+	    This defines an ordinary data file.
+
+	(*) Any other value between 2 and 255
+
+	    This defines an extraordinary object such as an XATTR.
+
+ (2) The name of the object type (NUL terminated unless all 16 chars are used)
+     [optional].
+
+ (3) A function to select the cache in which to store an index [optional].
+
+     This function is invoked when an index needs to be instantiated in a cache
+     during the instantiation of a non-index object.  Only the immediate index
+     parent for the non-index object will be queried.  Any indices above that
+     in the hierarchy may be stored in multiple caches.  This function does not
+     need to be supplied for any non-index object or any index that will only
+     have index children.
+
+     If this function is not supplied or if it returns NULL then the first
+     cache in the parent's list will be chosed, or failing that, the first
+     cache in the master list.
+
+ (4) A function to retrieve an object's key from the netfs [mandatory].
+
+     This function will be called with the netfs data that was passed to the
+     cookie acquisition function and the maximum length of key data that it may
+     provide.  It should write the required key data into the given buffer and
+     return the quantity it wrote.
+
+ (5) A function to retrieve attribute data from the netfs [optional].
+
+     This function will be called with the netfs data that was passed to the
+     cookie acquisition function.  It should return the size of the file if
+     this is a data file.  The size may be used to govern how much cache must
+     be reserved for this file in the cache.
+
+     If the function is absent, a file size of 0 is assumed.
+
+ (6) A function to retrieve auxilliary data from the netfs [optional].
+
+     This function will be called with the netfs data that was passed to the
+     cookie acquisition function and the maximum length of auxilliary data that
+     it may provide.  It should write the auxilliary data into the given buffer
+     and return the quantity it wrote.
+
+     If this function is absent, the auxilliary data length will be set to 0.
+
+     The length of the auxilliary data buffer may be dependent on the key
+     length.  A netfs mustn't rely on being able to provide more than 400 bytes
+     for both.
+
+ (7) A function to check the auxilliary data [optional].
+
+     This function will be called to check that a match found in the cache for
+     this object is valid.  For instance with AFS it could check the auxilliary
+     data against the data version number returned by the server to determine
+     whether the index entry in a cache is still valid.
+
+     If this function is absent, it will be assumed that matching objects in a
+     cache are always valid.
+
+     If present, the function should return one of the following values:
+
+	(*) FSCACHE_CHECKAUX_OKAY		- the entry is okay as is
+	(*) FSCACHE_CHECKAUX_NEEDS_UPDATE	- the entry requires update
+	(*) FSCACHE_CHECKAUX_OBSOLETE		- the entry should be deleted
+
+     This function can also be used to extract data from the auxilliary data in
+     the cache and copy it into the netfs's structures.
+
+ (8) A pair of functions to manage contexts for the completion callback
+     [optional].
+
+     The cache read/write functions are passed a context which is then passed
+     to the I/O completion callback function.  To ensure this context remains
+     valid until after the I/O completion is called, two functions may be
+     provided: one to get an extra reference on the context, and one to drop a
+     reference to it.
+
+     If the context is not used or is a type of object that won't go out of
+     scope, then these functions are not required.  These functions are not
+     required for indices as indices may not contain data.  These functions may
+     be called in interrupt context and so may not sleep.
+
+ (9) A function to mark a page as retaining cache metadata [mandatory].
+
+     This is called by the cache to indicate that it is retaining in-memory
+     information for this page and that the netfs should uncache the page when
+     it has finished.  This does not indicate whether there's data on the disk
+     or not.  Note that several pages at once may be presented for marking.
+
+     kAFS and NFS use the PG_private bit on the page structure for this, but
+     that may not be appropriate in all cases.
+
+     This function is not required for indices as they're not permitted data.
+
+(10) A function to unmark all the pages retaining cache metadata [mandatory].
+
+     This is called by FS-Cache to indicate that a backing store is being
+     unbound from a cookie and that all the marks on the pages should be
+     cleared to prevent confusion.  Note that the cache will have torn down all
+     its tracking information so that the pages don't need to be explicitly
+     uncached.
+
+     This function is not required for indices as they're not permitted data.
+
+
+===================================
+NETWORK FILESYSTEM (UN)REGISTRATION
+===================================
+
+The first step is to declare the network filesystem to the cache.  This also
+involves specifying the layout of the primary index (for AFS, this would be the
+"cell" level).
+
+The registration function is:
+
+	int fscache_register_netfs(struct fscache_netfs *netfs);
+
+It just takes a pointer to the netfs definition.  It returns 0 or an error as
+appropriate.
+
+For kAFS, registration is done as follows:
+
+	ret = fscache_register_netfs(&afs_cache_netfs);
+
+The last step is, of course, unregistration:
+
+	void fscache_unregister_netfs(struct fscache_netfs *netfs);
+
+
+================
+CACHE TAG LOOKUP
+================
+
+FS-Cache permits the use of more than one cache.  To permit particular index
+subtrees to be bound to particular caches, the second step is to look up cache
+representation tags.  This step is optional; it can be left entirely up to
+FS-Cache as to which cache should be used.  The problem with doing that is that
+FS-Cache will always pick the first cache that was registered.
+
+To get the representation for a named tag:
+
+	struct fscache_cache_tag *fscache_lookup_cache_tag(const char *name);
+
+This takes a text string as the name and returns a representation of a tag.  It
+will never return an error.  It may return a dummy tag, however, if it runs out
+of memory; this will inhibit caching with this tag.
+
+Any representation so obtained must be released by passing it to this function:
+
+	void fscache_release_cache_tag(struct fscache_cache_tag *tag);
+
+The tag will be retrieved by FS-Cache when it calls the object definition
+operation select_cache().
+
+
+==================
+INDEX REGISTRATION
+==================
+
+The third step is to inform FS-Cache about part of an index hierarchy that can
+be used to locate files.  This is done by requesting a cookie for each index in
+the path to the file:
+
+	struct fscache_cookie *
+	fscache_acquire_cookie(struct fscache_cookie *parent,
+			       struct fscache_object_def *def,
+			       void *netfs_data);
+
+This function creates an index entry in the index represented by parent,
+filling in the index entry by calling the operations pointed to by def.
+
+Note that this function never returns an error - all errors are handled
+internally.  It may also return NULL to indicate no cookie.  It is quite
+acceptable to pass this token back to this function as the parent to another
+acquisition (or even to the relinquish cookie, read page and write page
+functions - see below).
+
+Note also that no indices are actually created in a cache until a non-index
+object needs to be created somewhere down the hierarchy.  Furthermore, an index
+may be created in several different caches independently at different times.
+This is all handled transparently, and the netfs doesn't see any of it.
+
+For example, with AFS, a cell would be added to the primary index.  This index
+entry would have a dependent inode containing a volume location index for the
+volume mappings within this cell:
+
+	cell->cache =
+		fscache_acquire_cookie(afs_cache_netfs.primary_index,
+				       &afs_cell_cache_index_def,
+				       cell);
+
+Then when a volume location was accessed, it would be entered into the cell's
+index and an inode would be allocated that acts as a volume type and hash chain
+combination:
+
+	vlocation->cache =
+		fscache_acquire_cookie(cell->cache,
+				       &afs_vlocation_cache_index_def,
+				       vlocation);
+
+And then a particular flavour of volume (R/O for example) could be added to
+that index, creating another index for vnodes (AFS inode equivalents):
+
+	volume->cache =
+		fscache_acquire_cookie(vlocation->cache,
+				       &afs_volume_cache_index_def,
+				       volume);
+
+
+======================
+DATA FILE REGISTRATION
+======================
+
+The fourth step is to request a data file be created in the cache.  This is
+identical to index cookie acquisition.  The only difference is that the type in
+the object definition should be something other than index type.
+
+	vnode->cache =
+		fscache_acquire_cookie(volume->cache,
+				       &afs_vnode_cache_object_def,
+				       vnode);
+
+
+=================================
+MISCELLANEOUS OBJECT REGISTRATION
+=================================
+
+An optional step is to request an object of miscellaneous type be created in
+the cache.  This is almost identical to index cookie acquisition.  The only
+difference is that the type in the object definition should be something other
+than index type.  Whilst the parent object could be an index, it's more likely
+it would be some other type of object such as a data file.
+
+	xattr->cache =
+		fscache_acquire_cookie(vnode->cache,
+				       &afs_xattr_cache_object_def,
+				       xattr);
+
+Miscellaneous objects might be used to store extended attributes or directory
+entries for example.
+
+
+==========================
+SETTING THE DATA FILE SIZE
+==========================
+
+The fifth step is to set the size of the file.  This doesn't automatically
+reserve any space in the cache, but permits the cache to adjust its metadata
+for data tracking appropriately:
+
+	int fscache_set_i_size(struct fscache_cookie *cookie, loff_t i_size);
+
+The cache will return -ENOBUFS if there is no backing cache or if there is no
+space to allocate any extra metadata required in the cache.
+
+Note that attempts to read or write data pages in the cache over this size may
+be rebuffed with -ENOBUFS.
+
+
+=====================
+PAGE READ/ALLOC/WRITE
+=====================
+
+And the sixth step is to store and retrieve pages in the cache.  There are
+three functions that are used to do this.
+
+Note:
+
+ (1) A page should not be re-read or re-allocated without uncaching it first.
+
+ (2) A read or allocated page must be uncached when the netfs page is released
+     from the pagecache.
+
+ (3) A page should only be written to the cache if previous read or allocated.
+
+This permits the cache to maintain its page tracking in proper order.
+
+
+PAGE READ
+---------
+
+Firstly, the netfs should ask FS-Cache to examine the caches and read the
+contents cached for a particular page of a particular file if present, or else
+allocate space to store the contents if not:
+
+	typedef
+	void (*fscache_rw_complete_t)(struct page *page,
+				      void *context,
+				      int error);
+
+	int fscache_read_or_alloc_page(struct fscache_cookie *cookie,
+				       struct page *page,
+				       fscache_rw_complete_t end_io_func,
+				       void *end_io_data,
+				       gfp_t gfp);
+
+The cookie argument must specify a cookie for an object that isn't an index,
+the page specified will have the data loaded into it (and is also used to
+specify the page number), and the gfp argument is used to control how any
+memory allocations made are satisfied.
+
+If the cookie indicates the inode is not cached:
+
+ (1) The function will return -ENOBUFS.
+
+Else if there's a copy of the page resident in the cache:
+
+ (1) The mark_pages_cached() cookie operation will be called on that page.
+
+ (2) The function will submit a request to read the data from the cache's
+     backing device directly into the page specified.
+
+ (3) The function will return 0.
+
+ (4) When the read is complete, end_io_func() will be invoked with:
+
+     (*) The netfs data supplied when the cookie was created.
+
+     (*) The page descriptor.
+
+     (*) The context argument passed to the above function.  This will be
+     	 maintained with the get_context/put_context functions mentioned above.
+
+     (*) An argument that's 0 on success or negative for an error code.
+
+     If an error occurs, it should be assumed that the page contains no usable
+     data.
+
+     end_io_func() will be called in process context if the read is results in
+     an error, but it might be called in interrupt context if the read is
+     successful.
+
+Otherwise, if there's not a copy available in cache, but the cache may be able
+to store the page:
+
+ (1) The mark_pages_cached() cookie operation will be called on that page.
+
+ (2) A block may be reserved in the cache and attached to the object at the
+     appropriate place.
+
+ (3) The function will return -ENODATA.
+
+This function may also return -ENOMEM or -EINTR, in which case it won't have
+read any data from the cache.
+
+
+PAGE ALLOCATE
+-------------
+
+Alternatively, if there's not expected to be any data in the cache for a page
+because the file has been extended, a block can simply be allocated instead:
+
+	int fscache_alloc_page(struct fscache_cookie *cookie,
+			       struct page *page,
+			       gfp_t gfp);
+
+This is similar to the fscache_read_or_alloc_page() function, except that it
+never reads from the cache.  It will return 0 if a block has been allocated,
+rather than -ENODATA as the other would.  One or the other must be performed
+before writing to the cache.
+
+The mark_pages_cached() cookie operation will be called on the page if
+successful.
+
+
+PAGE WRITE
+----------
+
+Secondly, if the netfs changes the contents of the page (either due to an
+initial download or if a user performs a write), then the page should be
+written back to the cache:
+
+	int fscache_write_page(struct fscache_cookie *cookie,
+			       struct page *page,
+			       fscache_rw_complete_t end_io_func,
+			       void *context,
+			       gfp_t gfp);
+
+The cookie argument must specify a data file cookie, the page specified should
+contain the data to be written (and is also used to specify the page number),
+and the gfp argument is used to control how any memory allocations made are
+satisfied.
+
+The page must have first been read or allocated successfully and must not have
+been uncached before writing is performed.
+
+If the cookie indicates the inode is not cached then:
+
+ (1) The function will return -ENOBUFS.
+
+Else if space can be allocated in the cache to hold this page:
+
+ (1) The function will submit a request to write the data to cache's backing
+     device directly from the page specified.
+
+ (2) The function will return 0.
+
+ (3) When the write is complete the end_io_func() will be invoked with:
+
+     (*) The netfs data supplied when the cookie was created.
+
+     (*) The page descriptor.
+
+     (*) The context argument passed to the function.  This will be maintained
+     	 with the get_context/put_context functions mentioned above.
+
+     (*) An argument that's 0 on success or negative for an error.
+
+     If an error occurs, it can be assumed that the page has not been written
+     to the cache, and that either there's a block containing the old data or
+     no block at all in the cache.
+
+     end_io_func() might be called in interrupt context.
+
+Else if there's no space available in the cache, -ENOBUFS will be returned.
+
+
+MULTIPLE PAGE READ
+------------------
+
+A facility is provided to read several pages at once, as requested by the
+readpages() address space operation:
+
+	int fscache_read_or_alloc_pages(struct fscache_cookie *cookie,
+					struct address_space *mapping,
+					struct list_head *pages,
+					int *nr_pages,
+					fscache_rw_complete_t end_io_func,
+					void *context,
+					gfp_t gfp);
+
+This works in a similar way to fscache_read_or_alloc_page(), except:
+
+ (1) Any page it can retrieve data for is removed from pages and nr_pages and
+     dispatched for reading to the disk.  Reads of adjacent pages on disk may
+     be merged for greater efficiency.
+
+ (2) The mark_pages_cached() cookie operation will be called on several pages
+     at once if they're being read or allocated.
+
+ (3) If there was an general error, then that error will be returned.
+
+     Else if some pages couldn't be allocated or read, then -ENOBUFS will be
+     returned.
+
+     Else if some pages couldn't be read but were allocated, then -ENODATA will
+     be returned.
+
+     Otherwise, if all pages had reads dispatched, then 0 will be returned, the
+     list will be empty and *nr_pages will be 0.
+
+ (4) end_io_func will be called once for each page being read as the reads
+     complete.  It will be called in process context if error != 0, but it may
+     be called in interrupt context if there is no error.
+
+Note that a return of -ENODATA, -ENOBUFS or any other error does not preclude
+some of the pages being read and some being allocated.  Those pages will have
+been marked appropriately and will need uncaching.
+
+
+==============
+PAGE UNCACHING
+==============
+
+To uncache a page, this function should be called:
+
+	void fscache_uncache_page(struct fscache_cookie *cookie,
+				  struct page *page);
+
+This function permits the cache to release any in-memory representation it
+might be holding for this netfs page.  This function must be called once for
+each page on which the read or write page functions above have been called to
+make sure the cache's in-memory tracking information gets torn down.
+
+Note that pages can't be explicitly deleted from the a data file.  The whole
+data file must be retired (see the relinquish cookie function below).
+
+Furthermore, note that this does not cancel the asynchronous read or write
+operation started by the read/alloc and write functions.
+
+There is another unbinding operation similar to the above that takes a set of
+pages to unbind in one go:
+
+	void fscache_uncache_pagevec(struct fscache_cookie *cookie,
+				     struct pagevec *pagevec);
+
+
+==========================
+INDEX AND DATA FILE UPDATE
+==========================
+
+To request an update of the index data for an index or other object, the
+following function should be called:
+
+	void fscache_update_cookie(struct fscache_cookie *cookie);
+
+This function will refer back to the netfs_data pointer stored in the cookie by
+the acquisition function to obtain the data to write into each revised index
+entry.  The update method in the parent index definition will be called to
+transfer the data.
+
+Note that partial updates may happen automatically at other times, such as when
+data blocks are added to a data file object.
+
+
+===============================
+MISCELLANEOUS COOKIE OPERATIONS
+===============================
+
+There are a number of operations that can be used to control cookies:
+
+ (*) Cookie pinning:
+
+	int fscache_pin_cookie(struct fscache_cookie *cookie);
+	void fscache_unpin_cookie(struct fscache_cookie *cookie);
+
+     These operations permit data cookies to be pinned into the cache and to
+     have the pinning removed.  They are not permitted on index cookies.
+
+     The pinning function will return 0 if successful, -ENOBUFS in the cookie
+     isn't backed by a cache, -EOPNOTSUPP if the cache doesn't support pinning,
+     -ENOSPC if there isn't enough space to honour the operation, -ENOMEM or
+     -EIO if there's any other problem.
+
+ (*) Data space reservation:
+
+	int fscache_reserve_space(struct fscache_cookie *cookie, loff_t size);
+
+     This permits a netfs to request cache space be reserved to store up to the
+     given amount of a file.  It is permitted to ask for more than the current
+     size of the file to allow for future file expansion.
+
+     If size is given as zero then the reservation will be cancelled.
+
+     The function will return 0 if successful, -ENOBUFS in the cookie isn't
+     backed by a cache, -EOPNOTSUPP if the cache doesn't support reservations,
+     -ENOSPC if there isn't enough space to honour the operation, -ENOMEM or
+     -EIO if there's any other problem.
+
+     Note that this doesn't pin an object in a cache; it can still be culled to
+     make space if it's not in use.
+
+
+=====================
+COOKIE UNREGISTRATION
+=====================
+
+To get rid of a cookie, this function should be called.
+
+	void fscache_relinquish_cookie(struct fscache_cookie *cookie,
+				       int retire);
+
+If retire is non-zero, then the object will be marked for recycling, and all
+copies of it will be removed from all active caches in which it is present.
+Not only that but all child objects will also be retired.
+
+If retire is zero, then the object may be available again when next the
+acquisition function is called.  Retirement here will overrule the pinning on a
+cookie.
+
+One very important note - relinquish must NOT be called for a cookie unless all
+the cookies for "child" indices, objects and pages have been relinquished
+first.
+
+
+================================
+INDEX AND DATA FILE INVALIDATION
+================================
+
+There is no direct way to invalidate an index subtree or a data file.  To do
+this, the caller should relinquish and retire the cookie they have, and then
+acquire a new one.
diff --git a/Documentation/filesystems/relay.txt b/Documentation/filesystems/relay.txt
new file mode 100644
index 000000000..d6788dae0
--- /dev/null
+++ b/Documentation/filesystems/relay.txt
@@ -0,0 +1,479 @@
+relay interface (formerly relayfs)
+==================================
+
+The relay interface provides a means for kernel applications to
+efficiently log and transfer large quantities of data from the kernel
+to userspace via user-defined 'relay channels'.
+
+A 'relay channel' is a kernel->user data relay mechanism implemented
+as a set of per-cpu kernel buffers ('channel buffers'), each
+represented as a regular file ('relay file') in user space.  Kernel
+clients write into the channel buffers using efficient write
+functions; these automatically log into the current cpu's channel
+buffer.  User space applications mmap() or read() from the relay files
+and retrieve the data as it becomes available.  The relay files
+themselves are files created in a host filesystem, e.g. debugfs, and
+are associated with the channel buffers using the API described below.
+
+The format of the data logged into the channel buffers is completely
+up to the kernel client; the relay interface does however provide
+hooks which allow kernel clients to impose some structure on the
+buffer data.  The relay interface doesn't implement any form of data
+filtering - this also is left to the kernel client.  The purpose is to
+keep things as simple as possible.
+
+This document provides an overview of the relay interface API.  The
+details of the function parameters are documented along with the
+functions in the relay interface code - please see that for details.
+
+Semantics
+=========
+
+Each relay channel has one buffer per CPU, each buffer has one or more
+sub-buffers.  Messages are written to the first sub-buffer until it is
+too full to contain a new message, in which case it it is written to
+the next (if available).  Messages are never split across sub-buffers.
+At this point, userspace can be notified so it empties the first
+sub-buffer, while the kernel continues writing to the next.
+
+When notified that a sub-buffer is full, the kernel knows how many
+bytes of it are padding i.e. unused space occurring because a complete
+message couldn't fit into a sub-buffer.  Userspace can use this
+knowledge to copy only valid data.
+
+After copying it, userspace can notify the kernel that a sub-buffer
+has been consumed.
+
+A relay channel can operate in a mode where it will overwrite data not
+yet collected by userspace, and not wait for it to be consumed.
+
+The relay channel itself does not provide for communication of such
+data between userspace and kernel, allowing the kernel side to remain
+simple and not impose a single interface on userspace.  It does
+provide a set of examples and a separate helper though, described
+below.
+
+The read() interface both removes padding and internally consumes the
+read sub-buffers; thus in cases where read(2) is being used to drain
+the channel buffers, special-purpose communication between kernel and
+user isn't necessary for basic operation.
+
+One of the major goals of the relay interface is to provide a low
+overhead mechanism for conveying kernel data to userspace.  While the
+read() interface is easy to use, it's not as efficient as the mmap()
+approach; the example code attempts to make the tradeoff between the
+two approaches as small as possible.
+
+klog and relay-apps example code
+================================
+
+The relay interface itself is ready to use, but to make things easier,
+a couple simple utility functions and a set of examples are provided.
+
+The relay-apps example tarball, available on the relay sourceforge
+site, contains a set of self-contained examples, each consisting of a
+pair of .c files containing boilerplate code for each of the user and
+kernel sides of a relay application.  When combined these two sets of
+boilerplate code provide glue to easily stream data to disk, without
+having to bother with mundane housekeeping chores.
+
+The 'klog debugging functions' patch (klog.patch in the relay-apps
+tarball) provides a couple of high-level logging functions to the
+kernel which allow writing formatted text or raw data to a channel,
+regardless of whether a channel to write into exists or not, or even
+whether the relay interface is compiled into the kernel or not.  These
+functions allow you to put unconditional 'trace' statements anywhere
+in the kernel or kernel modules; only when there is a 'klog handler'
+registered will data actually be logged (see the klog and kleak
+examples for details).
+
+It is of course possible to use the relay interface from scratch,
+i.e. without using any of the relay-apps example code or klog, but
+you'll have to implement communication between userspace and kernel,
+allowing both to convey the state of buffers (full, empty, amount of
+padding).  The read() interface both removes padding and internally
+consumes the read sub-buffers; thus in cases where read(2) is being
+used to drain the channel buffers, special-purpose communication
+between kernel and user isn't necessary for basic operation.  Things
+such as buffer-full conditions would still need to be communicated via
+some channel though.
+
+klog and the relay-apps examples can be found in the relay-apps
+tarball on http://relayfs.sourceforge.net
+
+The relay interface user space API
+==================================
+
+The relay interface implements basic file operations for user space
+access to relay channel buffer data.  Here are the file operations
+that are available and some comments regarding their behavior:
+
+open()	    enables user to open an _existing_ channel buffer.
+
+mmap()      results in channel buffer being mapped into the caller's
+	    memory space. Note that you can't do a partial mmap - you
+	    must map the entire file, which is NRBUF * SUBBUFSIZE.
+
+read()      read the contents of a channel buffer.  The bytes read are
+	    'consumed' by the reader, i.e. they won't be available
+	    again to subsequent reads.  If the channel is being used
+	    in no-overwrite mode (the default), it can be read at any
+	    time even if there's an active kernel writer.  If the
+	    channel is being used in overwrite mode and there are
+	    active channel writers, results may be unpredictable -
+	    users should make sure that all logging to the channel has
+	    ended before using read() with overwrite mode.  Sub-buffer
+	    padding is automatically removed and will not be seen by
+	    the reader.
+
+sendfile()  transfer data from a channel buffer to an output file
+	    descriptor. Sub-buffer padding is automatically removed
+	    and will not be seen by the reader.
+
+poll()      POLLIN/POLLRDNORM/POLLERR supported.  User applications are
+	    notified when sub-buffer boundaries are crossed.
+
+close()     decrements the channel buffer's refcount.  When the refcount
+	    reaches 0, i.e. when no process or kernel client has the
+	    buffer open, the channel buffer is freed.
+
+In order for a user application to make use of relay files, the
+host filesystem must be mounted.  For example,
+
+	mount -t debugfs debugfs /debug
+
+NOTE:   the host filesystem doesn't need to be mounted for kernel
+	clients to create or use channels - it only needs to be
+	mounted when user space applications need access to the buffer
+	data.
+
+
+The relay interface kernel API
+==============================
+
+Here's a summary of the API the relay interface provides to in-kernel clients:
+
+TBD(curr. line MT:/API/)
+  channel management functions:
+
+    relay_open(base_filename, parent, subbuf_size, n_subbufs,
+               callbacks)
+    relay_close(chan)
+    relay_flush(chan)
+    relay_reset(chan)
+
+  channel management typically called on instigation of userspace:
+
+    relay_subbufs_consumed(chan, cpu, subbufs_consumed)
+
+  write functions:
+
+    relay_write(chan, data, length)
+    __relay_write(chan, data, length)
+    relay_reserve(chan, length)
+
+  callbacks:
+
+    subbuf_start(buf, subbuf, prev_subbuf, prev_padding)
+    buf_mapped(buf, filp)
+    buf_unmapped(buf, filp)
+    create_buf_file(filename, parent, mode, buf, is_global)
+    remove_buf_file(dentry)
+
+  helper functions:
+
+    relay_buf_full(buf)
+    subbuf_start_reserve(buf, length)
+
+
+Creating a channel
+------------------
+
+relay_open() is used to create a channel, along with its per-cpu
+channel buffers.  Each channel buffer will have an associated file
+created for it in the host filesystem, which can be and mmapped or
+read from in user space.  The files are named basename0...basenameN-1
+where N is the number of online cpus, and by default will be created
+in the root of the filesystem (if the parent param is NULL).  If you
+want a directory structure to contain your relay files, you should
+create it using the host filesystem's directory creation function,
+e.g. debugfs_create_dir(), and pass the parent directory to
+relay_open().  Users are responsible for cleaning up any directory
+structure they create, when the channel is closed - again the host
+filesystem's directory removal functions should be used for that,
+e.g. debugfs_remove().
+
+In order for a channel to be created and the host filesystem's files
+associated with its channel buffers, the user must provide definitions
+for two callback functions, create_buf_file() and remove_buf_file().
+create_buf_file() is called once for each per-cpu buffer from
+relay_open() and allows the user to create the file which will be used
+to represent the corresponding channel buffer.  The callback should
+return the dentry of the file created to represent the channel buffer.
+remove_buf_file() must also be defined; it's responsible for deleting
+the file(s) created in create_buf_file() and is called during
+relay_close().
+
+Here are some typical definitions for these callbacks, in this case
+using debugfs:
+
+/*
+ * create_buf_file() callback.  Creates relay file in debugfs.
+ */
+static struct dentry *create_buf_file_handler(const char *filename,
+                                              struct dentry *parent,
+                                              int mode,
+                                              struct rchan_buf *buf,
+                                              int *is_global)
+{
+        return debugfs_create_file(filename, mode, parent, buf,
+	                           &relay_file_operations);
+}
+
+/*
+ * remove_buf_file() callback.  Removes relay file from debugfs.
+ */
+static int remove_buf_file_handler(struct dentry *dentry)
+{
+        debugfs_remove(dentry);
+
+        return 0;
+}
+
+/*
+ * relay interface callbacks
+ */
+static struct rchan_callbacks relay_callbacks =
+{
+        .create_buf_file = create_buf_file_handler,
+        .remove_buf_file = remove_buf_file_handler,
+};
+
+And an example relay_open() invocation using them:
+
+  chan = relay_open("cpu", NULL, SUBBUF_SIZE, N_SUBBUFS, &relay_callbacks);
+
+If the create_buf_file() callback fails, or isn't defined, channel
+creation and thus relay_open() will fail.
+
+The total size of each per-cpu buffer is calculated by multiplying the
+number of sub-buffers by the sub-buffer size passed into relay_open().
+The idea behind sub-buffers is that they're basically an extension of
+double-buffering to N buffers, and they also allow applications to
+easily implement random-access-on-buffer-boundary schemes, which can
+be important for some high-volume applications.  The number and size
+of sub-buffers is completely dependent on the application and even for
+the same application, different conditions will warrant different
+values for these parameters at different times.  Typically, the right
+values to use are best decided after some experimentation; in general,
+though, it's safe to assume that having only 1 sub-buffer is a bad
+idea - you're guaranteed to either overwrite data or lose events
+depending on the channel mode being used.
+
+The create_buf_file() implementation can also be defined in such a way
+as to allow the creation of a single 'global' buffer instead of the
+default per-cpu set.  This can be useful for applications interested
+mainly in seeing the relative ordering of system-wide events without
+the need to bother with saving explicit timestamps for the purpose of
+merging/sorting per-cpu files in a postprocessing step.
+
+To have relay_open() create a global buffer, the create_buf_file()
+implementation should set the value of the is_global outparam to a
+non-zero value in addition to creating the file that will be used to
+represent the single buffer.  In the case of a global buffer,
+create_buf_file() and remove_buf_file() will be called only once.  The
+normal channel-writing functions, e.g. relay_write(), can still be
+used - writes from any cpu will transparently end up in the global
+buffer - but since it is a global buffer, callers should make sure
+they use the proper locking for such a buffer, either by wrapping
+writes in a spinlock, or by copying a write function from relay.h and
+creating a local version that internally does the proper locking.
+
+Channel 'modes'
+---------------
+
+relay channels can be used in either of two modes - 'overwrite' or
+'no-overwrite'.  The mode is entirely determined by the implementation
+of the subbuf_start() callback, as described below.  The default if no
+subbuf_start() callback is defined is 'no-overwrite' mode.  If the
+default mode suits your needs, and you plan to use the read()
+interface to retrieve channel data, you can ignore the details of this
+section, as it pertains mainly to mmap() implementations.
+
+In 'overwrite' mode, also known as 'flight recorder' mode, writes
+continuously cycle around the buffer and will never fail, but will
+unconditionally overwrite old data regardless of whether it's actually
+been consumed.  In no-overwrite mode, writes will fail, i.e. data will
+be lost, if the number of unconsumed sub-buffers equals the total
+number of sub-buffers in the channel.  It should be clear that if
+there is no consumer or if the consumer can't consume sub-buffers fast
+enough, data will be lost in either case; the only difference is
+whether data is lost from the beginning or the end of a buffer.
+
+As explained above, a relay channel is made of up one or more
+per-cpu channel buffers, each implemented as a circular buffer
+subdivided into one or more sub-buffers.  Messages are written into
+the current sub-buffer of the channel's current per-cpu buffer via the
+write functions described below.  Whenever a message can't fit into
+the current sub-buffer, because there's no room left for it, the
+client is notified via the subbuf_start() callback that a switch to a
+new sub-buffer is about to occur.  The client uses this callback to 1)
+initialize the next sub-buffer if appropriate 2) finalize the previous
+sub-buffer if appropriate and 3) return a boolean value indicating
+whether or not to actually move on to the next sub-buffer.
+
+To implement 'no-overwrite' mode, the userspace client would provide
+an implementation of the subbuf_start() callback something like the
+following:
+
+static int subbuf_start(struct rchan_buf *buf,
+                        void *subbuf,
+			void *prev_subbuf,
+			unsigned int prev_padding)
+{
+	if (prev_subbuf)
+		*((unsigned *)prev_subbuf) = prev_padding;
+
+	if (relay_buf_full(buf))
+		return 0;
+
+	subbuf_start_reserve(buf, sizeof(unsigned int));
+
+	return 1;
+}
+
+If the current buffer is full, i.e. all sub-buffers remain unconsumed,
+the callback returns 0 to indicate that the buffer switch should not
+occur yet, i.e. until the consumer has had a chance to read the
+current set of ready sub-buffers.  For the relay_buf_full() function
+to make sense, the consumer is reponsible for notifying the relay
+interface when sub-buffers have been consumed via
+relay_subbufs_consumed().  Any subsequent attempts to write into the
+buffer will again invoke the subbuf_start() callback with the same
+parameters; only when the consumer has consumed one or more of the
+ready sub-buffers will relay_buf_full() return 0, in which case the
+buffer switch can continue.
+
+The implementation of the subbuf_start() callback for 'overwrite' mode
+would be very similar:
+
+static int subbuf_start(struct rchan_buf *buf,
+                        void *subbuf,
+			void *prev_subbuf,
+			unsigned int prev_padding)
+{
+	if (prev_subbuf)
+		*((unsigned *)prev_subbuf) = prev_padding;
+
+	subbuf_start_reserve(buf, sizeof(unsigned int));
+
+	return 1;
+}
+
+In this case, the relay_buf_full() check is meaningless and the
+callback always returns 1, causing the buffer switch to occur
+unconditionally.  It's also meaningless for the client to use the
+relay_subbufs_consumed() function in this mode, as it's never
+consulted.
+
+The default subbuf_start() implementation, used if the client doesn't
+define any callbacks, or doesn't define the subbuf_start() callback,
+implements the simplest possible 'no-overwrite' mode, i.e. it does
+nothing but return 0.
+
+Header information can be reserved at the beginning of each sub-buffer
+by calling the subbuf_start_reserve() helper function from within the
+subbuf_start() callback.  This reserved area can be used to store
+whatever information the client wants.  In the example above, room is
+reserved in each sub-buffer to store the padding count for that
+sub-buffer.  This is filled in for the previous sub-buffer in the
+subbuf_start() implementation; the padding value for the previous
+sub-buffer is passed into the subbuf_start() callback along with a
+pointer to the previous sub-buffer, since the padding value isn't
+known until a sub-buffer is filled.  The subbuf_start() callback is
+also called for the first sub-buffer when the channel is opened, to
+give the client a chance to reserve space in it.  In this case the
+previous sub-buffer pointer passed into the callback will be NULL, so
+the client should check the value of the prev_subbuf pointer before
+writing into the previous sub-buffer.
+
+Writing to a channel
+--------------------
+
+Kernel clients write data into the current cpu's channel buffer using
+relay_write() or __relay_write().  relay_write() is the main logging
+function - it uses local_irqsave() to protect the buffer and should be
+used if you might be logging from interrupt context.  If you know
+you'll never be logging from interrupt context, you can use
+__relay_write(), which only disables preemption.  These functions
+don't return a value, so you can't determine whether or not they
+failed - the assumption is that you wouldn't want to check a return
+value in the fast logging path anyway, and that they'll always succeed
+unless the buffer is full and no-overwrite mode is being used, in
+which case you can detect a failed write in the subbuf_start()
+callback by calling the relay_buf_full() helper function.
+
+relay_reserve() is used to reserve a slot in a channel buffer which
+can be written to later.  This would typically be used in applications
+that need to write directly into a channel buffer without having to
+stage data in a temporary buffer beforehand.  Because the actual write
+may not happen immediately after the slot is reserved, applications
+using relay_reserve() can keep a count of the number of bytes actually
+written, either in space reserved in the sub-buffers themselves or as
+a separate array.  See the 'reserve' example in the relay-apps tarball
+at http://relayfs.sourceforge.net for an example of how this can be
+done.  Because the write is under control of the client and is
+separated from the reserve, relay_reserve() doesn't protect the buffer
+at all - it's up to the client to provide the appropriate
+synchronization when using relay_reserve().
+
+Closing a channel
+-----------------
+
+The client calls relay_close() when it's finished using the channel.
+The channel and its associated buffers are destroyed when there are no
+longer any references to any of the channel buffers.  relay_flush()
+forces a sub-buffer switch on all the channel buffers, and can be used
+to finalize and process the last sub-buffers before the channel is
+closed.
+
+Misc
+----
+
+Some applications may want to keep a channel around and re-use it
+rather than open and close a new channel for each use.  relay_reset()
+can be used for this purpose - it resets a channel to its initial
+state without reallocating channel buffer memory or destroying
+existing mappings.  It should however only be called when it's safe to
+do so, i.e. when the channel isn't currently being written to.
+
+Finally, there are a couple of utility callbacks that can be used for
+different purposes.  buf_mapped() is called whenever a channel buffer
+is mmapped from user space and buf_unmapped() is called when it's
+unmapped.  The client can use this notification to trigger actions
+within the kernel application, such as enabling/disabling logging to
+the channel.
+
+
+Resources
+=========
+
+For news, example code, mailing list, etc. see the relay interface homepage:
+
+    http://relayfs.sourceforge.net
+
+
+Credits
+=======
+
+The ideas and specs for the relay interface came about as a result of
+discussions on tracing involving the following:
+
+Michel Dagenais		<michel.dagenais@polymtl.ca>
+Richard Moore		<richardj_moore@uk.ibm.com>
+Bob Wisniewski		<bob@watson.ibm.com>
+Karim Yaghmour		<karim@opersys.com>
+Tom Zanussi		<zanussi@us.ibm.com>
+
+Also thanks to Hubertus Franke for a lot of useful suggestions and bug
+reports.
diff --git a/Documentation/hwmon/abituguru b/Documentation/hwmon/abituguru
new file mode 100644
index 000000000..b2c0d61b3
--- /dev/null
+++ b/Documentation/hwmon/abituguru
@@ -0,0 +1,87 @@
+Kernel driver abituguru
+=======================
+
+Supported chips:
+  * Abit uGuru revision 1-3 (Hardware Monitor part only)
+    Prefix: 'abituguru'
+    Addresses scanned: ISA 0x0E0
+    Datasheet: Not available, this driver is based on reverse engineering.
+	A "Datasheet" has been written based on the reverse engineering it
+	should be available in the same dir as this file under the name
+	abituguru-datasheet.
+    Note:
+	The uGuru is a microcontroller with onboard firmware which programs
+	it to behave as a hwmon IC. There are many different revisions of the
+	firmware and thus effectivly many different revisions of the uGuru.
+	Below is an incomplete list with which revisions are used for which
+	Motherboards:
+	uGuru 1.00    ~ 1.24    (AI7, KV8-MAX3, AN7) (1)
+	uGuru 2.0.0.0 ~ 2.0.4.2 (KV8-PRO)
+	uGuru 2.1.0.0 ~ 2.1.2.8 (AS8, AV8, AA8, AG8, AA8XE, AX8)
+	uGuru 2.2.0.0 ~ 2.2.0.6 (AA8 Fatal1ty)
+	uGuru 2.3.0.0 ~ 2.3.0.9 (AN8)
+	uGuru 3.0.0.0 ~ 3.0.1.2 (AW8, AL8, NI8)
+	uGuru 4.xxxxx?          (AT8 32X) (2)
+	1) For revisions 2 and 3 uGuru's the driver can autodetect the
+	   sensortype (Volt or Temp) for bank1 sensors, for revision 1 uGuru's
+	   this doesnot always work. For these uGuru's the autodection can
+	   be overriden with the bank1_types module param. For all 3 known
+	   revison 1 motherboards the correct use of this param is:
+	   bank1_types=1,1,0,0,0,0,0,2,0,0,0,0,2,0,0,1
+	   You may also need to specify the fan_sensors option for these boards
+	   fan_sensors=5
+	2) The current version of the abituguru driver is known to NOT work
+	   on these Motherboards
+
+Authors:
+	Hans de Goede <j.w.r.degoede@hhs.nl>,
+	(Initial reverse engineering done by Olle Sandberg
+	 <ollebull@gmail.com>)
+
+
+Module Parameters
+-----------------
+
+* force: bool		Force detection. Note this parameter only causes the
+			detection to be skipped, if the uGuru can't be read
+			the module initialization (insmod) will still fail.
+* bank1_types: int[]	Bank1 sensortype autodetection override:
+			  -1 autodetect (default)
+			   0 volt sensor
+			   1 temp sensor
+			   2 not connected
+* fan_sensors: int	Tell the driver how many fan speed sensors there are
+			on your motherboard. Default: 0 (autodetect).
+* pwms: int		Tell the driver how many fan speed controls (fan
+			pwms) your motherboard has. Default: 0 (autodetect).
+* verbose: int		How verbose should the driver be? (0-3):
+			   0 normal output
+			   1 + verbose error reporting
+			   2 + sensors type probing info (default)
+			   3 + retryable error reporting
+			Default: 2 (the driver is still in the testing phase)
+
+Notice if you need any of the first three options above please insmod the
+driver with verbose set to 3 and mail me <j.w.r.degoede@hhs.nl> the output of:
+dmesg | grep abituguru
+
+
+Description
+-----------
+
+This driver supports the hardware monitoring features of the Abit uGuru chip
+found on Abit uGuru featuring motherboards (most modern Abit motherboards).
+
+The uGuru chip in reality is a Winbond W83L950D in disguise (despite Abit
+claiming it is "a new microprocessor designed by the ABIT Engineers").
+Unfortunatly this doesn't help since the W83L950D is a generic
+microcontroller with a custom Abit application running on it.
+
+Despite Abit not releasing any information regarding the uGuru, Olle
+Sandberg <ollebull@gmail.com> has managed to reverse engineer the sensor part
+of the uGuru. Without his work this driver would not have been possible.
+
+Known Issues
+------------
+
+The voltage and frequency control parts of the Abit uGuru are not supported.
diff --git a/Documentation/hwmon/abituguru-datasheet b/Documentation/hwmon/abituguru-datasheet
new file mode 100644
index 000000000..aef5a9b36
--- /dev/null
+++ b/Documentation/hwmon/abituguru-datasheet
@@ -0,0 +1,312 @@
+uGuru datasheet
+===============
+
+First of all, what I know about uGuru is no fact based on any help, hints or
+datasheet from Abit. The data I have got on uGuru have I assembled through
+my weak knowledge in "backwards engineering".
+And just for the record, you may have noticed uGuru isn't a chip developed by
+Abit, as they claim it to be. It's realy just an microprocessor (uC) created by
+Winbond (W83L950D). And no, reading the manual for this specific uC or
+mailing  Windbond for help won't give any usefull data about uGuru, as it is
+the program inside the uC that is responding to calls.
+
+Olle Sandberg <ollebull@gmail.com>, 2005-05-25
+
+
+Original version by Olle Sandberg who did the heavy lifting of the initial
+reverse engineering. This version has been almost fully rewritten for clarity
+and extended with write support and info on more databanks, the write support
+is once again reverse engineered by Olle the additional databanks have been
+reverse engineered by me. I would like to express my thanks to Olle, this
+document and the Linux driver could not have been written without his efforts.
+
+Note: because of the lack of specs only the sensors part of the uGuru is
+described here and not the CPU / RAM / etc voltage & frequency control.
+
+Hans de Goede <j.w.r.degoede@hhs.nl>, 28-01-2006
+
+
+Detection
+=========
+
+As far as known the uGuru is always placed at and using the (ISA) I/O-ports
+0xE0 and 0xE4, so we don't have to scan any port-range, just check what the two
+ports are holding for detection. We will refer to 0xE0 as CMD (command-port)
+and 0xE4 as DATA because Abit refers to them with these names.
+
+If DATA holds 0x00 or 0x08 and CMD holds 0x00 or 0xAC an uGuru could be
+present. We have to check for two different values at data-port, because
+after a reboot uGuru will hold 0x00 here, but if the driver is removed and
+later on attached again data-port will hold 0x08, more about this later.
+
+After wider testing of the Linux kernel driver some variants of the uGuru have
+turned up which will hold 0x00 instead of 0xAC at the CMD port, thus we also
+have to test CMD for two different values. On these uGuru's DATA will initally
+hold 0x09 and will only hold 0x08 after reading CMD first, so CMD must be read
+first!
+
+To be really sure an uGuru is present a test read of one or more register
+sets should be done.
+
+
+Reading / Writing
+=================
+
+Addressing
+----------
+
+The uGuru has a number of different addressing levels. The first addressing
+level we will call banks. A bank holds data for one or more sensors. The data
+in a bank for a sensor is one or more bytes large.
+
+The number of bytes is fixed for a given bank, you should always read or write
+that many bytes, reading / writing more will fail, the results when writing
+less then the number of bytes for a given bank are undetermined.
+
+See below for all known bank addresses, numbers of sensors in that bank,
+number of bytes data per sensor and contents/meaning of those bytes.
+
+Although both this document and the kernel driver have kept the sensor
+terminoligy for the addressing within a bank this is not 100% correct, in
+bank 0x24 for example the addressing within the bank selects a PWM output not
+a sensor.
+
+Notice that some banks have both a read and a write address this is how the
+uGuru determines if a read from or a write to the bank is taking place, thus
+when reading you should always use the read address and when writing the
+write address. The write address is always one (1) more then the read address.
+
+
+uGuru ready
+-----------
+
+Before you can read from or write to the uGuru you must first put the uGuru
+in "ready" mode.
+
+To put the uGuru in ready mode first write 0x00 to DATA and then wait for DATA
+to hold 0x09, DATA should read 0x09 within 250 read cycles.
+
+Next CMD _must_ be read and should hold 0xAC, usually CMD will hold 0xAC the
+first read but sometimes it takes a while before CMD holds 0xAC and thus it
+has to be read a number of times (max 50).
+
+After reading CMD, DATA should hold 0x08 which means that the uGuru is ready
+for input. As above DATA will usually hold 0x08 the first read but not always.
+This step can be skipped, but it is undetermined what happens if the uGuru has
+not yet reported 0x08 at DATA and you proceed with writing a bank address.
+
+
+Sending bank and sensor addresses to the uGuru
+----------------------------------------------
+
+First the uGuru must be in "ready" mode as described above, DATA should hold
+0x08 indicating that the uGuru wants input, in this case the bank address.
+
+Next write the bank address to DATA. After the bank address has been written
+wait for to DATA to hold 0x08 again indicating that it wants / is ready for
+more input (max 250 reads).
+
+Once DATA holds 0x08 again write the sensor address to CMD.
+
+
+Reading
+-------
+
+First send the bank and sensor addresses as described above.
+Then for each byte of data you want to read wait for DATA to hold 0x01
+which indicates that the uGuru is ready to be read (max 250 reads) and once
+DATA holds 0x01 read the byte from CMD.
+
+Once all bytes have been read data will hold 0x09, but there is no reason to
+test for this. Notice that the number of bytes is bank address dependent see
+above and below.
+
+After completing a successfull read it is advised to put the uGuru back in
+ready mode, so that it is ready for the next read / write cycle. This way
+if your program / driver is unloaded and later loaded again the detection
+algorithm described above will still work.
+
+
+
+Writing
+-------
+
+First send the bank and sensor addresses as described above.
+Then for each byte of data you want to write wait for DATA to hold 0x00
+which indicates that the uGuru is ready to be written (max 250 reads) and
+once DATA holds 0x00 write the byte to CMD.
+
+Once all bytes have been written wait for DATA to hold 0x01 (max 250 reads)
+don't ask why this is the way it is.
+
+Once DATA holds 0x01 read CMD it should hold 0xAC now.
+
+After completing a successfull write it is advised to put the uGuru back in
+ready mode, so that it is ready for the next read / write cycle. This way
+if your program / driver is unloaded and later loaded again the detection
+algorithm described above will still work.
+
+
+Gotchas
+-------
+
+After wider testing of the Linux kernel driver some variants of the uGuru have
+turned up which do not hold 0x08 at DATA within 250 reads after writing the
+bank address. With these versions this happens quite frequent, using larger
+timeouts doesn't help, they just go offline for a second or 2, doing some
+internal callibration or whatever. Your code should be prepared to handle
+this and in case of no response in this specific case just goto sleep for a
+while and then retry.
+
+
+Address Map
+===========
+
+Bank 0x20 Alarms (R)
+--------------------
+This bank contains 0 sensors, iow the sensor address is ignored (but must be
+written) just use 0. Bank 0x20 contains 3 bytes:
+
+Byte 0:
+This byte holds the alarm flags for sensor 0-7 of Sensor Bank1, with bit 0
+corresponding to sensor 0, 1 to 1, etc.
+
+Byte 1:
+This byte holds the alarm flags for sensor 8-15 of Sensor Bank1, with bit 0
+corresponding to sensor 8, 1 to 9, etc.
+
+Byte 2:
+This byte holds the alarm flags for sensor 0-5 of Sensor Bank2, with bit 0
+corresponding to sensor 0, 1 to 1, etc.
+
+
+Bank 0x21 Sensor Bank1 Values / Readings (R)
+--------------------------------------------
+This bank contains 16 sensors, for each sensor it contains 1 byte.
+So far the following sensors are known to be available on all motherboards:
+Sensor  0 CPU temp
+Sensor  1 SYS temp
+Sensor  3 CPU core volt
+Sensor  4 DDR volt
+Sensor 10 DDR Vtt volt
+Sensor 15 PWM temp
+
+Byte 0:
+This byte holds the reading from the sensor. Sensors in Bank1 can be both
+volt and temp sensors, this is motherboard specific. The uGuru however does
+seem to know (be programmed with) what kindoff sensor is attached see Sensor
+Bank1 Settings description.
+
+Volt sensors use a linear scale, a reading 0 corresponds with 0 volt and a
+reading of 255 with 3494 mV. The sensors for higher voltages however are
+connected through a division circuit. The currently known division circuits
+in use result in ranges of: 0-4361mV, 0-6248mV or 0-14510mV. 3.3 volt sources
+use the 0-4361mV range, 5 volt the 0-6248mV and 12 volt the 0-14510mV .
+
+Temp sensors also use a linear scale, a reading of 0 corresponds with 0 degree
+Celsius and a reading of 255 with a reading of 255 degrees Celsius.
+
+
+Bank 0x22 Sensor Bank1 Settings (R)
+Bank 0x23 Sensor Bank1 Settings (W)
+-----------------------------------
+
+This bank contains 16 sensors, for each sensor it contains 3 bytes. Each
+set of 3 bytes contains the settings for the sensor with the same sensor
+address in Bank 0x21 .
+
+Byte 0:
+Alarm behaviour for the selected sensor. A 1 enables the described behaviour.
+Bit 0: Give an alarm if measured temp is over the warning threshold	(RW) *
+Bit 1: Give an alarm if measured volt is over the max threshold		(RW) **
+Bit 2: Give an alarm if measured volt is under the min threshold	(RW) **
+Bit 3: Beep if alarm							(RW)
+Bit 4: 1 if alarm cause measured temp is over the warning threshold	(R)
+Bit 5: 1 if alarm cause measured volt is over the max threshold		(R)
+Bit 6: 1 if alarm cause measured volt is under the min threshold	(R)
+Bit 7: Volt sensor: Shutdown if alarm persist for more then 4 seconds	(RW)
+       Temp sensor: Shutdown if temp is over the shutdown threshold	(RW)
+
+*  This bit is only honored/used by the uGuru if a temp sensor is connected
+** This bit is only honored/used by the uGuru if a volt sensor is connected
+Note with some trickery this can be used to find out what kinda sensor is
+detected see the Linux kernel driver for an example with many comments on
+how todo this.
+
+Byte 1:
+Temp sensor: warning threshold  (scale as bank 0x21)
+Volt sensor: min threshold      (scale as bank 0x21)
+
+Byte 2:
+Temp sensor: shutdown threshold (scale as bank 0x21)
+Volt sensor: max threshold      (scale as bank 0x21)
+
+
+Bank 0x24 PWM outputs for FAN's (R)
+Bank 0x25 PWM outputs for FAN's (W)
+-----------------------------------
+
+This bank contains 3 "sensors", for each sensor it contains 5 bytes.
+Sensor 0 usually controls the CPU fan
+Sensor 1 usually controls the NB (or chipset for single chip) fan
+Sensor 2 usually controls the System fan
+
+Byte 0:
+Flag 0x80 to enable control, Fan runs at 100% when disabled.
+low nibble (temp)sensor address at bank 0x21 used for control.
+
+Byte 1:
+0-255 = 0-12v (linear), specify voltage at which fan will rotate when under
+low threshold temp (specified in byte 3)
+
+Byte 2:
+0-255 = 0-12v (linear), specify voltage at which fan will rotate when above
+high threshold temp (specified in byte 4)
+
+Byte 3:
+Low threshold temp  (scale as bank 0x21)
+
+byte 4:
+High threshold temp (scale as bank 0x21)
+
+
+Bank 0x26 Sensors Bank2 Values / Readings (R)
+---------------------------------------------
+
+This bank contains 6 sensors (AFAIK), for each sensor it contains 1 byte.
+So far the following sensors are known to be available on all motherboards:
+Sensor 0: CPU fan speed
+Sensor 1: NB (or chipset for single chip) fan speed
+Sensor 2: SYS fan speed
+
+Byte 0:
+This byte holds the reading from the sensor. 0-255 = 0-15300 (linear)
+
+
+Bank 0x27 Sensors Bank2 Settings (R)
+Bank 0x28 Sensors Bank2 Settings (W)
+------------------------------------
+
+This bank contains 6 sensors (AFAIK), for each sensor it contains 2 bytes.
+
+Byte 0:
+Alarm behaviour for the selected sensor. A 1 enables the described behaviour.
+Bit 0: Give an alarm if measured rpm is under the min threshold	(RW)
+Bit 3: Beep if alarm						(RW)
+Bit 7: Shutdown if alarm persist for more then 4 seconds	(RW)
+
+Byte 1:
+min threshold (scale as bank 0x26)
+
+
+Warning for the adventerous
+===========================
+
+A word of caution to those who want to experiment and see if they can figure
+the voltage / clock programming out, I tried reading and only reading banks
+0-0x30 with the reading code used for the sensor banks (0x20-0x28) and this
+resulted in a _permanent_ reprogramming of the voltages, luckily I had the
+sensors part configured so that it would shutdown my system on any out of spec
+voltages which proprably safed my computer (after a reboot I managed to
+immediatly enter the bios and reload the defaults). This probably means that
+the read/write cycle for the non sensor part is different from the sensor part.
diff --git a/Documentation/hwmon/lm70 b/Documentation/hwmon/lm70
new file mode 100644
index 000000000..2bdd3feeb
--- /dev/null
+++ b/Documentation/hwmon/lm70
@@ -0,0 +1,31 @@
+Kernel driver lm70
+==================
+
+Supported chip:
+  * National Semiconductor LM70
+    Datasheet: http://www.national.com/pf/LM/LM70.html
+
+Author:
+        Kaiwan N Billimoria <kaiwan@designergraphix.com>
+
+Description
+-----------
+
+This driver implements support for the National Semiconductor LM70
+temperature sensor.
+
+The LM70 temperature sensor chip supports a single temperature sensor.
+It communicates with a host processor (or microcontroller) via an
+SPI/Microwire Bus interface.
+
+Communication with the LM70 is simple: when the temperature is to be sensed,
+the driver accesses the LM70 using SPI communication: 16 SCLK cycles
+comprise the MOSI/MISO loop. At the end of the transfer, the 11-bit 2's
+complement digital temperature (sent via the SIO line), is available in the
+driver for interpretation. This driver makes use of the kernel's in-core
+SPI support.
+
+Thanks to
+---------
+Jean Delvare <khali@linux-fr.org> for mentoring the hwmon-side driver
+development.
diff --git a/Documentation/hwmon/smsc47m192 b/Documentation/hwmon/smsc47m192
new file mode 100644
index 000000000..45d6453cd
--- /dev/null
+++ b/Documentation/hwmon/smsc47m192
@@ -0,0 +1,102 @@
+Kernel driver smsc47m192
+========================
+
+Supported chips:
+  * SMSC LPC47M192 and LPC47M997
+    Prefix: 'smsc47m192'
+    Addresses scanned: I2C 0x2c - 0x2d
+    Datasheet: The datasheet for LPC47M192 is publicly available from
+               http://www.smsc.com/
+               The LPC47M997 is compatible for hardware monitoring.
+
+Author: Hartmut Rick <linux@rick.claranet.de>
+        Special thanks to Jean Delvare for careful checking
+        of the code and many helpful comments and suggestions.
+
+
+Description
+-----------
+
+This driver implements support for the hardware sensor capabilities
+of the SMSC LPC47M192 and LPC47M997 Super-I/O chips.
+
+These chips support 3 temperature channels and 8 voltage inputs
+as well as CPU voltage VID input.
+
+They do also have fan monitoring and control capabilities, but the
+these features are accessed via ISA bus and are not supported by this
+driver. Use the 'smsc47m1' driver for fan monitoring and control.
+
+Voltages and temperatures are measured by an 8-bit ADC, the resolution
+of the temperatures is 1 bit per degree C.
+Voltages are scaled such that the nominal voltage corresponds to
+192 counts, i.e. 3/4 of the full range. Thus the available range for
+each voltage channel is 0V ... 255/192*(nominal voltage), the resolution
+is 1 bit per (nominal voltage)/192.
+Both voltage and temperature values are scaled by 1000, the sys files
+show voltages in mV and temperatures in units of 0.001 degC.
+
+The +12V analog voltage input channel (in4_input) is multiplexed with
+bit 4 of the encoded CPU voltage. This means that you either get
+a +12V voltage measurement or a 5 bit CPU VID, but not both.
+The default setting is to use the pin as 12V input, and use only 4 bit VID.
+This driver assumes that the information in the configuration register
+is correct, i.e. that the BIOS has updated the configuration if
+the motherboard has this input wired to VID4.
+
+The temperature and voltage readings are updated once every 1.5 seconds.
+Reading them more often repeats the same values.
+
+
+sysfs interface
+---------------
+
+in0_input	- +2.5V voltage input
+in1_input	- CPU voltage input (nominal 2.25V)
+in2_input	- +3.3V voltage input
+in3_input	- +5V voltage input
+in4_input	- +12V voltage input (may be missing if used as VID4)
+in5_input	- Vcc voltage input (nominal 3.3V)
+		  This is the supply voltage of the sensor chip itself.
+in6_input	- +1.5V voltage input
+in7_input	- +1.8V voltage input
+
+in[0-7]_min,
+in[0-7]_max	- lower and upper alarm thresholds for in[0-7]_input reading
+
+		  All voltages are read and written in mV.
+
+in[0-7]_alarm	- alarm flags for voltage inputs
+		  These files read '1' in case of alarm, '0' otherwise.
+
+temp1_input	- chip temperature measured by on-chip diode
+temp[2-3]_input	- temperature measured by external diodes (one of these would
+		  typically be wired to the diode inside the CPU)
+
+temp[1-3]_min,
+temp[1-3]_max	- lower and upper alarm thresholds for temperatures
+
+temp[1-3]_offset - temperature offset registers
+		  The chip adds the offsets stored in these registers to
+		  the corresponding temperature readings.
+		  Note that temp1 and temp2 offsets share the same register,
+		  they cannot both be different from zero at the same time.
+		  Writing a non-zero number to one of them will reset the other
+		  offset to zero.
+
+		  All temperatures and offsets are read and written in
+		  units of 0.001 degC.
+
+temp[1-3]_alarm - alarm flags for temperature inputs, '1' in case of alarm,
+		  '0' otherwise.
+temp[2-3]_input_fault - diode fault flags for temperature inputs 2 and 3.
+		  A fault is detected if the two pins for the corresponding
+		  sensor are open or shorted, or any of the two is shorted
+		  to ground or Vcc. '1' indicates a diode fault.
+
+cpu0_vid	- CPU voltage as received from the CPU
+
+vrm		- CPU VID standard used for decoding CPU voltage
+
+		  The *_min, *_max, *_offset and vrm files can be read and
+		  written, all others are read-only.
diff --git a/Documentation/hwmon/w83791d b/Documentation/hwmon/w83791d
new file mode 100644
index 000000000..83a383628
--- /dev/null
+++ b/Documentation/hwmon/w83791d
@@ -0,0 +1,113 @@
+Kernel driver w83791d
+=====================
+
+Supported chips:
+  * Winbond W83791D
+    Prefix: 'w83791d'
+    Addresses scanned: I2C 0x2c - 0x2f
+    Datasheet: http://www.winbond-usa.com/products/winbond_products/pdfs/PCIC/W83791Da.pdf
+
+Author: Charles Spirakis <bezaur@gmail.com>
+
+This driver was derived from the w83781d.c and w83792d.c source files.
+
+Credits:
+  w83781d.c:
+    Frodo Looijaard <frodol@dds.nl>,
+    Philip Edelbrock <phil@netroedge.com>,
+    and Mark Studebaker <mdsxyz123@yahoo.com>
+  w83792d.c:
+    Chunhao Huang <DZShen@Winbond.com.tw>,
+    Rudolf Marek <r.marek@sh.cvut.cz>
+
+Module Parameters
+-----------------
+
+* init boolean
+  (default 0)
+  Use 'init=1' to have the driver do extra software initializations.
+  The default behavior is to do the minimum initialization possible
+  and depend on the BIOS to properly setup the chip. If you know you
+  have a w83791d and you're having problems, try init=1 before trying
+  reset=1.
+
+* reset boolean
+  (default 0)
+  Use 'reset=1' to reset the chip (via index 0x40, bit 7). The default
+  behavior is no chip reset to preserve BIOS settings.
+
+* force_subclients=bus,caddr,saddr,saddr
+  This is used to force the i2c addresses for subclients of
+  a certain chip. Example usage is `force_subclients=0,0x2f,0x4a,0x4b'
+  to force the subclients of chip 0x2f on bus 0 to i2c addresses
+  0x4a and 0x4b.
+
+
+Description
+-----------
+
+This driver implements support for the Winbond W83791D chip.
+
+Detection of the chip can sometimes be foiled because it can be in an
+internal state that allows no clean access (Bank with ID register is not
+currently selected). If you know the address of the chip, use a 'force'
+parameter; this will put it into a more well-behaved state first.
+
+The driver implements three temperature sensors, five fan rotation speed
+sensors, and ten voltage sensors.
+
+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
+the temperature gets higher than the Overtemperature Shutdown value; it stays
+on until the temperature falls below the Hysteresis value.
+
+Fan rotation speeds are reported in RPM (rotations per minute). An alarm is
+triggered if the rotation speed has dropped below a programmable limit. Fan
+readings can be divided by a programmable divider (1, 2, 4, 8 for fan 1/2/3
+and 1, 2, 4, 8, 16, 32, 64 or 128 for fan 4/5) to give the readings more
+range or accuracy.
+
+Voltage sensors (also known as IN sensors) report their values in millivolts.
+An alarm is triggered if the voltage has crossed a programmable minimum
+or maximum limit.
+
+Alarms are provided as output from a "realtime status register". The
+following bits are defined:
+
+bit - alarm on:
+0  - Vcore
+1  - VINR0
+2  - +3.3VIN
+3  - 5VDD
+4  - temp1
+5  - temp2
+6  - fan1
+7  - fan2
+8  - +12VIN
+9  - -12VIN
+10 - -5VIN
+11 - fan3
+12 - chassis
+13 - temp3
+14 - VINR1
+15 - reserved
+16 - tart1
+17 - tart2
+18 - tart3
+19 - VSB
+20 - VBAT
+21 - fan4
+22 - fan5
+23 - reserved
+
+When an alarm goes off, you can be warned by a beeping signal through your
+computer speaker. It is possible to enable all beeping globally, or only
+the beeping for some alarms.
+
+The driver only reads the chip values each 3 seconds; reading them more
+often will do no harm, but will return 'old' values.
+
+W83791D TODO:
+---------------
+Provide a patch for per-file alarms as discussed on the mailing list
+Provide a patch for smart-fan control (still need appropriate motherboard/fans)
diff --git a/Documentation/i2c/busses/i2c-ocores b/Documentation/i2c/busses/i2c-ocores
new file mode 100644
index 000000000..cfcebb10d
--- /dev/null
+++ b/Documentation/i2c/busses/i2c-ocores
@@ -0,0 +1,51 @@
+Kernel driver i2c-ocores
+
+Supported adapters:
+  * OpenCores.org I2C controller by Richard Herveille (see datasheet link)
+    Datasheet: http://www.opencores.org/projects.cgi/web/i2c/overview
+
+Author: Peter Korsgaard <jacmet@sunsite.dk>
+
+Description
+-----------
+
+i2c-ocores is an i2c bus driver for the OpenCores.org I2C controller
+IP core by Richard Herveille.
+
+Usage
+-----
+
+i2c-ocores uses the platform bus, so you need to provide a struct
+platform_device with the base address and interrupt number. The
+dev.platform_data of the device should also point to a struct
+ocores_i2c_platform_data (see linux/i2c-ocores.h) describing the
+distance between registers and the input clock speed.
+
+E.G. something like:
+
+static struct resource ocores_resources[] = {
+	[0] = {
+		.start	= MYI2C_BASEADDR,
+		.end	= MYI2C_BASEADDR + 8,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= MYI2C_IRQ,
+		.end	= MYI2C_IRQ,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct ocores_i2c_platform_data myi2c_data = {
+	.regstep	= 2,		/* two bytes between registers */
+	.clock_khz	= 50000,	/* input clock of 50MHz */
+};
+
+static struct platform_device myi2c = {
+	.name			= "ocores-i2c",
+	.dev = {
+		.platform_data	= &myi2c_data,
+	},
+	.num_resources		= ARRAY_SIZE(ocores_resources),
+	.resource		= ocores_resources,
+};
diff --git a/Documentation/ia64/aliasing.txt b/Documentation/ia64/aliasing.txt
new file mode 100644
index 000000000..38f9a52d1
--- /dev/null
+++ b/Documentation/ia64/aliasing.txt
@@ -0,0 +1,208 @@
+	         MEMORY ATTRIBUTE ALIASING ON IA-64
+
+			   Bjorn Helgaas
+		       <bjorn.helgaas@hp.com>
+			    May 4, 2006
+
+
+MEMORY ATTRIBUTES
+
+    Itanium supports several attributes for virtual memory references.
+    The attribute is part of the virtual translation, i.e., it is
+    contained in the TLB entry.  The ones of most interest to the Linux
+    kernel are:
+
+	WB		Write-back (cacheable)
+	UC		Uncacheable
+	WC		Write-coalescing
+
+    System memory typically uses the WB attribute.  The UC attribute is
+    used for memory-mapped I/O devices.  The WC attribute is uncacheable
+    like UC is, but writes may be delayed and combined to increase
+    performance for things like frame buffers.
+
+    The Itanium architecture requires that we avoid accessing the same
+    page with both a cacheable mapping and an uncacheable mapping[1].
+
+    The design of the chipset determines which attributes are supported
+    on which regions of the address space.  For example, some chipsets
+    support either WB or UC access to main memory, while others support
+    only WB access.
+
+MEMORY MAP
+
+    Platform firmware describes the physical memory map and the
+    supported attributes for each region.  At boot-time, the kernel uses
+    the EFI GetMemoryMap() interface.  ACPI can also describe memory
+    devices and the attributes they support, but Linux/ia64 currently
+    doesn't use this information.
+
+    The kernel uses the efi_memmap table returned from GetMemoryMap() to
+    learn the attributes supported by each region of physical address
+    space.  Unfortunately, this table does not completely describe the
+    address space because some machines omit some or all of the MMIO
+    regions from the map.
+
+    The kernel maintains another table, kern_memmap, which describes the
+    memory Linux is actually using and the attribute for each region.
+    This contains only system memory; it does not contain MMIO space.
+
+    The kern_memmap table typically contains only a subset of the system
+    memory described by the efi_memmap.  Linux/ia64 can't use all memory
+    in the system because of constraints imposed by the identity mapping
+    scheme.
+
+    The efi_memmap table is preserved unmodified because the original
+    boot-time information is required for kexec.
+
+KERNEL IDENTITY MAPPINGS
+
+    Linux/ia64 identity mappings are done with large pages, currently
+    either 16MB or 64MB, referred to as "granules."  Cacheable mappings
+    are speculative[2], so the processor can read any location in the
+    page at any time, independent of the programmer's intentions.  This
+    means that to avoid attribute aliasing, Linux can create a cacheable
+    identity mapping only when the entire granule supports cacheable
+    access.
+
+    Therefore, kern_memmap contains only full granule-sized regions that
+    can referenced safely by an identity mapping.
+
+    Uncacheable mappings are not speculative, so the processor will
+    generate UC accesses only to locations explicitly referenced by
+    software.  This allows UC identity mappings to cover granules that
+    are only partially populated, or populated with a combination of UC
+    and WB regions.
+
+USER MAPPINGS
+
+    User mappings are typically done with 16K or 64K pages.  The smaller
+    page size allows more flexibility because only 16K or 64K has to be
+    homogeneous with respect to memory attributes.
+
+POTENTIAL ATTRIBUTE ALIASING CASES
+
+    There are several ways the kernel creates new mappings:
+
+    mmap of /dev/mem
+
+	This uses remap_pfn_range(), which creates user mappings.  These
+	mappings may be either WB or UC.  If the region being mapped
+	happens to be in kern_memmap, meaning that it may also be mapped
+	by a kernel identity mapping, the user mapping must use the same
+	attribute as the kernel mapping.
+
+	If the region is not in kern_memmap, the user mapping should use
+	an attribute reported as being supported in the EFI memory map.
+
+	Since the EFI memory map does not describe MMIO on some
+	machines, this should use an uncacheable mapping as a fallback.
+
+    mmap of /sys/class/pci_bus/.../legacy_mem
+
+	This is very similar to mmap of /dev/mem, except that legacy_mem
+	only allows mmap of the one megabyte "legacy MMIO" area for a
+	specific PCI bus.  Typically this is the first megabyte of
+	physical address space, but it may be different on machines with
+	several VGA devices.
+
+	"X" uses this to access VGA frame buffers.  Using legacy_mem
+	rather than /dev/mem allows multiple instances of X to talk to
+	different VGA cards.
+
+	The /dev/mem mmap constraints apply.
+
+	However, since this is for mapping legacy MMIO space, WB access
+	does not make sense.  This matters on machines without legacy
+	VGA support: these machines may have WB memory for the entire
+	first megabyte (or even the entire first granule).
+
+	On these machines, we could mmap legacy_mem as WB, which would
+	be safe in terms of attribute aliasing, but X has no way of
+	knowing that it is accessing regular memory, not a frame buffer,
+	so the kernel should fail the mmap rather than doing it with WB.
+
+    read/write of /dev/mem
+
+	This uses copy_from_user(), which implicitly uses a kernel
+	identity mapping.  This is obviously safe for things in
+	kern_memmap.
+
+	There may be corner cases of things that are not in kern_memmap,
+	but could be accessed this way.  For example, registers in MMIO
+	space are not in kern_memmap, but could be accessed with a UC
+	mapping.  This would not cause attribute aliasing.  But
+	registers typically can be accessed only with four-byte or
+	eight-byte accesses, and the copy_from_user() path doesn't allow
+	any control over the access size, so this would be dangerous.
+
+    ioremap()
+
+	This returns a kernel identity mapping for use inside the
+	kernel.
+
+	If the region is in kern_memmap, we should use the attribute
+	specified there.  Otherwise, if the EFI memory map reports that
+	the entire granule supports WB, we should use that (granules
+	that are partially reserved or occupied by firmware do not appear
+	in kern_memmap).  Otherwise, we should use a UC mapping.
+
+PAST PROBLEM CASES
+
+    mmap of various MMIO regions from /dev/mem by "X" on Intel platforms
+
+      The EFI memory map may not report these MMIO regions.
+
+      These must be allowed so that X will work.  This means that
+      when the EFI memory map is incomplete, every /dev/mem mmap must
+      succeed.  It may create either WB or UC user mappings, depending
+      on whether the region is in kern_memmap or the EFI memory map.
+
+    mmap of 0x0-0xA0000 /dev/mem by "hwinfo" on HP sx1000 with VGA enabled
+
+      See https://bugzilla.novell.com/show_bug.cgi?id=140858.
+
+      The EFI memory map reports the following attributes:
+        0x00000-0x9FFFF WB only
+        0xA0000-0xBFFFF UC only (VGA frame buffer)
+        0xC0000-0xFFFFF WB only
+
+      This mmap is done with user pages, not kernel identity mappings,
+      so it is safe to use WB mappings.
+
+      The kernel VGA driver may ioremap the VGA frame buffer at 0xA0000,
+      which will use a granule-sized UC mapping covering 0-0xFFFFF.  This
+      granule covers some WB-only memory, but since UC is non-speculative,
+      the processor will never generate an uncacheable reference to the
+      WB-only areas unless the driver explicitly touches them.
+
+    mmap of 0x0-0xFFFFF legacy_mem by "X"
+
+      If the EFI memory map reports this entire range as WB, there
+      is no VGA MMIO hole, and the mmap should fail or be done with
+      a WB mapping.
+
+      There's no easy way for X to determine whether the 0xA0000-0xBFFFF
+      region is a frame buffer or just memory, so I think it's best to
+      just fail this mmap request rather than using a WB mapping.  As
+      far as I know, there's no need to map legacy_mem with WB
+      mappings.
+
+      Otherwise, a UC mapping of the entire region is probably safe.
+      The VGA hole means the region will not be in kern_memmap.  The
+      HP sx1000 chipset doesn't support UC access to the memory surrounding
+      the VGA hole, but X doesn't need that area anyway and should not
+      reference it.
+
+    mmap of 0xA0000-0xBFFFF legacy_mem by "X" on HP sx1000 with VGA disabled
+
+      The EFI memory map reports the following attributes:
+        0x00000-0xFFFFF WB only (no VGA MMIO hole)
+
+      This is a special case of the previous case, and the mmap should
+      fail for the same reason as above.
+
+NOTES
+
+    [1] SDM rev 2.2, vol 2, sec 4.4.1.
+    [2] SDM rev 2.2, vol 2, sec 4.4.6.
diff --git a/Documentation/irqflags-tracing.txt b/Documentation/irqflags-tracing.txt
new file mode 100644
index 000000000..6a444877e
--- /dev/null
+++ b/Documentation/irqflags-tracing.txt
@@ -0,0 +1,57 @@
+IRQ-flags state tracing
+
+started by Ingo Molnar <mingo@redhat.com>
+
+the "irq-flags tracing" feature "traces" hardirq and softirq state, in
+that it gives interested subsystems an opportunity to be notified of
+every hardirqs-off/hardirqs-on, softirqs-off/softirqs-on event that
+happens in the kernel.
+
+CONFIG_TRACE_IRQFLAGS_SUPPORT is needed for CONFIG_PROVE_SPIN_LOCKING
+and CONFIG_PROVE_RW_LOCKING to be offered by the generic lock debugging
+code. Otherwise only CONFIG_PROVE_MUTEX_LOCKING and
+CONFIG_PROVE_RWSEM_LOCKING will be offered on an architecture - these
+are locking APIs that are not used in IRQ context. (the one exception
+for rwsems is worked around)
+
+architecture support for this is certainly not in the "trivial"
+category, because lots of lowlevel assembly code deal with irq-flags
+state changes. But an architecture can be irq-flags-tracing enabled in a
+rather straightforward and risk-free manner.
+
+Architectures that want to support this need to do a couple of
+code-organizational changes first:
+
+- move their irq-flags manipulation code from their asm/system.h header
+  to asm/irqflags.h
+
+- rename local_irq_disable()/etc to raw_local_irq_disable()/etc. so that
+  the linux/irqflags.h code can inject callbacks and can construct the
+  real local_irq_disable()/etc APIs.
+
+- add and enable TRACE_IRQFLAGS_SUPPORT in their arch level Kconfig file
+
+and then a couple of functional changes are needed as well to implement
+irq-flags-tracing support:
+
+- in lowlevel entry code add (build-conditional) calls to the
+  trace_hardirqs_off()/trace_hardirqs_on() functions. The lock validator
+  closely guards whether the 'real' irq-flags matches the 'virtual'
+  irq-flags state, and complains loudly (and turns itself off) if the
+  two do not match. Usually most of the time for arch support for
+  irq-flags-tracing is spent in this state: look at the lockdep
+  complaint, try to figure out the assembly code we did not cover yet,
+  fix and repeat. Once the system has booted up and works without a
+  lockdep complaint in the irq-flags-tracing functions arch support is
+  complete.
+- if the architecture has non-maskable interrupts then those need to be
+  excluded from the irq-tracing [and lock validation] mechanism via
+  lockdep_off()/lockdep_on().
+
+in general there is no risk from having an incomplete irq-flags-tracing
+implementation in an architecture: lockdep will detect that and will
+turn itself off. I.e. the lock validator will still be reliable. There
+should be no crashes due to irq-tracing bugs. (except if the assembly
+changes break other code by modifying conditions or registers that
+shouldnt be)
+
diff --git a/Documentation/lockdep-design.txt b/Documentation/lockdep-design.txt
new file mode 100644
index 000000000..00d93605b
--- /dev/null
+++ b/Documentation/lockdep-design.txt
@@ -0,0 +1,197 @@
+Runtime locking correctness validator
+=====================================
+
+started by Ingo Molnar <mingo@redhat.com>
+additions by Arjan van de Ven <arjan@linux.intel.com>
+
+Lock-class
+----------
+
+The basic object the validator operates upon is a 'class' of locks.
+
+A class of locks is a group of locks that are logically the same with
+respect to locking rules, even if the locks may have multiple (possibly
+tens of thousands of) instantiations. For example a lock in the inode
+struct is one class, while each inode has its own instantiation of that
+lock class.
+
+The validator tracks the 'state' of lock-classes, and it tracks
+dependencies between different lock-classes. The validator maintains a
+rolling proof that the state and the dependencies are correct.
+
+Unlike an lock instantiation, the lock-class itself never goes away: when
+a lock-class is used for the first time after bootup it gets registered,
+and all subsequent uses of that lock-class will be attached to this
+lock-class.
+
+State
+-----
+
+The validator tracks lock-class usage history into 5 separate state bits:
+
+- 'ever held in hardirq context'                    [ == hardirq-safe   ]
+- 'ever held in softirq context'                    [ == softirq-safe   ]
+- 'ever held with hardirqs enabled'                 [ == hardirq-unsafe ]
+- 'ever held with softirqs and hardirqs enabled'    [ == softirq-unsafe ]
+
+- 'ever used'                                       [ == !unused        ]
+
+Single-lock state rules:
+------------------------
+
+A softirq-unsafe lock-class is automatically hardirq-unsafe as well. The
+following states are exclusive, and only one of them is allowed to be
+set for any lock-class:
+
+ <hardirq-safe> and <hardirq-unsafe>
+ <softirq-safe> and <softirq-unsafe>
+
+The validator detects and reports lock usage that violate these
+single-lock state rules.
+
+Multi-lock dependency rules:
+----------------------------
+
+The same lock-class must not be acquired twice, because this could lead
+to lock recursion deadlocks.
+
+Furthermore, two locks may not be taken in different order:
+
+ <L1> -> <L2>
+ <L2> -> <L1>
+
+because this could lead to lock inversion deadlocks. (The validator
+finds such dependencies in arbitrary complexity, i.e. there can be any
+other locking sequence between the acquire-lock operations, the
+validator will still track all dependencies between locks.)
+
+Furthermore, the following usage based lock dependencies are not allowed
+between any two lock-classes:
+
+   <hardirq-safe>   ->  <hardirq-unsafe>
+   <softirq-safe>   ->  <softirq-unsafe>
+
+The first rule comes from the fact the a hardirq-safe lock could be
+taken by a hardirq context, interrupting a hardirq-unsafe lock - and
+thus could result in a lock inversion deadlock. Likewise, a softirq-safe
+lock could be taken by an softirq context, interrupting a softirq-unsafe
+lock.
+
+The above rules are enforced for any locking sequence that occurs in the
+kernel: when acquiring a new lock, the validator checks whether there is
+any rule violation between the new lock and any of the held locks.
+
+When a lock-class changes its state, the following aspects of the above
+dependency rules are enforced:
+
+- if a new hardirq-safe lock is discovered, we check whether it
+  took any hardirq-unsafe lock in the past.
+
+- if a new softirq-safe lock is discovered, we check whether it took
+  any softirq-unsafe lock in the past.
+
+- if a new hardirq-unsafe lock is discovered, we check whether any
+  hardirq-safe lock took it in the past.
+
+- if a new softirq-unsafe lock is discovered, we check whether any
+  softirq-safe lock took it in the past.
+
+(Again, we do these checks too on the basis that an interrupt context
+could interrupt _any_ of the irq-unsafe or hardirq-unsafe locks, which
+could lead to a lock inversion deadlock - even if that lock scenario did
+not trigger in practice yet.)
+
+Exception: Nested data dependencies leading to nested locking
+-------------------------------------------------------------
+
+There are a few cases where the Linux kernel acquires more than one
+instance of the same lock-class. Such cases typically happen when there
+is some sort of hierarchy within objects of the same type. In these
+cases there is an inherent "natural" ordering between the two objects
+(defined by the properties of the hierarchy), and the kernel grabs the
+locks in this fixed order on each of the objects.
+
+An example of such an object hieararchy that results in "nested locking"
+is that of a "whole disk" block-dev object and a "partition" block-dev
+object; the partition is "part of" the whole device and as long as one
+always takes the whole disk lock as a higher lock than the partition
+lock, the lock ordering is fully correct. The validator does not
+automatically detect this natural ordering, as the locking rule behind
+the ordering is not static.
+
+In order to teach the validator about this correct usage model, new
+versions of the various locking primitives were added that allow you to
+specify a "nesting level". An example call, for the block device mutex,
+looks like this:
+
+enum bdev_bd_mutex_lock_class
+{
+       BD_MUTEX_NORMAL,
+       BD_MUTEX_WHOLE,
+       BD_MUTEX_PARTITION
+};
+
+ mutex_lock_nested(&bdev->bd_contains->bd_mutex, BD_MUTEX_PARTITION);
+
+In this case the locking is done on a bdev object that is known to be a
+partition.
+
+The validator treats a lock that is taken in such a nested fasion as a
+separate (sub)class for the purposes of validation.
+
+Note: When changing code to use the _nested() primitives, be careful and
+check really thoroughly that the hiearchy is correctly mapped; otherwise
+you can get false positives or false negatives.
+
+Proof of 100% correctness:
+--------------------------
+
+The validator achieves perfect, mathematical 'closure' (proof of locking
+correctness) in the sense that for every simple, standalone single-task
+locking sequence that occured at least once during the lifetime of the
+kernel, the validator proves it with a 100% certainty that no
+combination and timing of these locking sequences can cause any class of
+lock related deadlock. [*]
+
+I.e. complex multi-CPU and multi-task locking scenarios do not have to
+occur in practice to prove a deadlock: only the simple 'component'
+locking chains have to occur at least once (anytime, in any
+task/context) for the validator to be able to prove correctness. (For
+example, complex deadlocks that would normally need more than 3 CPUs and
+a very unlikely constellation of tasks, irq-contexts and timings to
+occur, can be detected on a plain, lightly loaded single-CPU system as
+well!)
+
+This radically decreases the complexity of locking related QA of the
+kernel: what has to be done during QA is to trigger as many "simple"
+single-task locking dependencies in the kernel as possible, at least
+once, to prove locking correctness - instead of having to trigger every
+possible combination of locking interaction between CPUs, combined with
+every possible hardirq and softirq nesting scenario (which is impossible
+to do in practice).
+
+[*] assuming that the validator itself is 100% correct, and no other
+    part of the system corrupts the state of the validator in any way.
+    We also assume that all NMI/SMM paths [which could interrupt
+    even hardirq-disabled codepaths] are correct and do not interfere
+    with the validator. We also assume that the 64-bit 'chain hash'
+    value is unique for every lock-chain in the system. Also, lock
+    recursion must not be higher than 20.
+
+Performance:
+------------
+
+The above rules require _massive_ amounts of runtime checking. If we did
+that for every lock taken and for every irqs-enable event, it would
+render the system practically unusably slow. The complexity of checking
+is O(N^2), so even with just a few hundred lock-classes we'd have to do
+tens of thousands of checks for every event.
+
+This problem is solved by checking any given 'locking scenario' (unique
+sequence of locks taken after each other) only once. A simple stack of
+held locks is maintained, and a lightweight 64-bit hash value is
+calculated, which hash is unique for every lock chain. The hash value,
+when the chain is validated for the first time, is then put into a hash
+table, which hash-table can be checked in a lockfree manner. If the
+locking chain occurs again later on, the hash table tells us that we
+dont have to validate the chain again.
diff --git a/Documentation/networking/ipvs-sysctl.txt b/Documentation/networking/ipvs-sysctl.txt
new file mode 100644
index 000000000..4ccdbca03
--- /dev/null
+++ b/Documentation/networking/ipvs-sysctl.txt
@@ -0,0 +1,143 @@
+/proc/sys/net/ipv4/vs/* Variables:
+
+am_droprate - INTEGER
+        default 10
+
+        It sets the always mode drop rate, which is used in the mode 3
+        of the drop_rate defense.
+
+amemthresh - INTEGER
+        default 1024
+
+        It sets the available memory threshold (in pages), which is
+        used in the automatic modes of defense. When there is no
+        enough available memory, the respective strategy will be
+        enabled and the variable is automatically set to 2, otherwise
+        the strategy is disabled and the variable is  set  to 1.
+
+cache_bypass - BOOLEAN
+        0 - disabled (default)
+        not 0 - enabled
+
+        If it is enabled, forward packets to the original destination
+        directly when no cache server is available and destination
+        address is not local (iph->daddr is RTN_UNICAST). It is mostly
+        used in transparent web cache cluster.
+
+debug_level - INTEGER
+	0          - transmission error messages (default)
+	1          - non-fatal error messages
+	2          - configuration
+	3          - destination trash
+	4          - drop entry
+	5          - service lookup
+	6          - scheduling
+	7          - connection new/expire, lookup and synchronization
+	8          - state transition
+	9          - binding destination, template checks and applications
+	10         - IPVS packet transmission
+	11         - IPVS packet handling (ip_vs_in/ip_vs_out)
+	12 or more - packet traversal
+
+	Only available when IPVS is compiled with the CONFIG_IPVS_DEBUG
+
+	Higher debugging levels include the messages for lower debugging
+	levels, so setting debug level 2, includes level 0, 1 and 2
+	messages. Thus, logging becomes more and more verbose the higher
+	the level.
+
+drop_entry - INTEGER
+        0  - disabled (default)
+
+        The drop_entry defense is to randomly drop entries in the
+        connection hash table, just in order to collect back some
+        memory for new connections. In the current code, the
+        drop_entry procedure can be activated every second, then it
+        randomly scans 1/32 of the whole and drops entries that are in
+        the SYN-RECV/SYNACK state, which should be effective against
+        syn-flooding attack.
+
+        The valid values of drop_entry are from 0 to 3, where 0 means
+        that this strategy is always disabled, 1 and 2 mean automatic
+        modes (when there is no enough available memory, the strategy
+        is enabled and the variable is automatically set to 2,
+        otherwise the strategy is disabled and the variable is set to
+        1), and 3 means that that the strategy is always enabled.
+
+drop_packet - INTEGER
+        0  - disabled (default)
+
+        The drop_packet defense is designed to drop 1/rate packets
+        before forwarding them to real servers. If the rate is 1, then
+        drop all the incoming packets.
+
+        The value definition is the same as that of the drop_entry. In
+        the automatic mode, the rate is determined by the follow
+        formula: rate = amemthresh / (amemthresh - available_memory)
+        when available memory is less than the available memory
+        threshold. When the mode 3 is set, the always mode drop rate
+        is controlled by the /proc/sys/net/ipv4/vs/am_droprate.
+
+expire_nodest_conn - BOOLEAN
+        0 - disabled (default)
+        not 0 - enabled
+
+        The default value is 0, the load balancer will silently drop
+        packets when its destination server is not available. It may
+        be useful, when user-space monitoring program deletes the
+        destination server (because of server overload or wrong
+        detection) and add back the server later, and the connections
+        to the server can continue.
+
+        If this feature is enabled, the load balancer will expire the
+        connection immediately when a packet arrives and its
+        destination server is not available, then the client program
+        will be notified that the connection is closed. This is
+        equivalent to the feature some people requires to flush
+        connections when its destination is not available.
+
+expire_quiescent_template - BOOLEAN
+	0 - disabled (default)
+	not 0 - enabled
+
+	When set to a non-zero value, the load balancer will expire
+	persistent templates when the destination server is quiescent.
+	This may be useful, when a user makes a destination server
+	quiescent by setting its weight to 0 and it is desired that
+	subsequent otherwise persistent connections are sent to a
+	different destination server.  By default new persistent
+	connections are allowed to quiescent destination servers.
+
+	If this feature is enabled, the load balancer will expire the
+	persistence template if it is to be used to schedule a new
+	connection and the destination server is quiescent.
+
+nat_icmp_send - BOOLEAN
+        0 - disabled (default)
+        not 0 - enabled
+
+        It controls sending icmp error messages (ICMP_DEST_UNREACH)
+        for VS/NAT when the load balancer receives packets from real
+        servers but the connection entries don't exist.
+
+secure_tcp - INTEGER
+        0  - disabled (default)
+
+        The secure_tcp defense is to use a more complicated state
+        transition table and some possible short timeouts of each
+        state. In the VS/NAT, it delays the entering the ESTABLISHED
+        until the real server starts to send data and ACK packet
+        (after 3-way handshake).
+
+        The value definition is the same as that of drop_entry or
+        drop_packet.
+
+sync_threshold - INTEGER
+        default 3
+
+        It sets synchronization threshold, which is the minimum number
+        of incoming packets that a connection needs to receive before
+        the connection will be synchronized. A connection will be
+        synchronized, every time the number of its incoming packets
+        modulus 50 equals the threshold. The range of the threshold is
+        from 0 to 49.
diff --git a/Documentation/pcmcia/crc32hash.c b/Documentation/pcmcia/crc32hash.c
new file mode 100644
index 000000000..cbc36d299
--- /dev/null
+++ b/Documentation/pcmcia/crc32hash.c
@@ -0,0 +1,32 @@
+/* crc32hash.c - derived from linux/lib/crc32.c, GNU GPL v2 */
+/* Usage example:
+$ ./crc32hash "Dual Speed"
+*/
+
+#include <string.h>
+#include <stdio.h>
+#include <ctype.h>
+#include <stdlib.h>
+
+unsigned int crc32(unsigned char const *p, unsigned int len)
+{
+	int i;
+	unsigned int crc = 0;
+	while (len--) {
+		crc ^= *p++;
+		for (i = 0; i < 8; i++)
+			crc = (crc >> 1) ^ ((crc & 1) ? 0xedb88320 : 0);
+	}
+	return crc;
+}
+
+int main(int argc, char **argv) {
+	unsigned int result;
+	if (argc != 2) {
+		printf("no string passed as argument\n");
+		return -1;
+	}
+	result = crc32(argv[1], strlen(argv[1]));
+	printf("0x%x\n", result);
+	return 0;
+}
diff --git a/Documentation/pi-futex.txt b/Documentation/pi-futex.txt
new file mode 100644
index 000000000..5d61dacd2
--- /dev/null
+++ b/Documentation/pi-futex.txt
@@ -0,0 +1,121 @@
+Lightweight PI-futexes
+----------------------
+
+We are calling them lightweight for 3 reasons:
+
+ - in the user-space fastpath a PI-enabled futex involves no kernel work
+   (or any other PI complexity) at all. No registration, no extra kernel
+   calls - just pure fast atomic ops in userspace.
+
+ - even in the slowpath, the system call and scheduling pattern is very
+   similar to normal futexes.
+
+ - the in-kernel PI implementation is streamlined around the mutex
+   abstraction, with strict rules that keep the implementation
+   relatively simple: only a single owner may own a lock (i.e. no
+   read-write lock support), only the owner may unlock a lock, no
+   recursive locking, etc.
+
+Priority Inheritance - why?
+---------------------------
+
+The short reply: user-space PI helps achieving/improving determinism for
+user-space applications. In the best-case, it can help achieve
+determinism and well-bound latencies. Even in the worst-case, PI will
+improve the statistical distribution of locking related application
+delays.
+
+The longer reply:
+-----------------
+
+Firstly, sharing locks between multiple tasks is a common programming
+technique that often cannot be replaced with lockless algorithms. As we
+can see it in the kernel [which is a quite complex program in itself],
+lockless structures are rather the exception than the norm - the current
+ratio of lockless vs. locky code for shared data structures is somewhere
+between 1:10 and 1:100. Lockless is hard, and the complexity of lockless
+algorithms often endangers to ability to do robust reviews of said code.
+I.e. critical RT apps often choose lock structures to protect critical
+data structures, instead of lockless algorithms. Furthermore, there are
+cases (like shared hardware, or other resource limits) where lockless
+access is mathematically impossible.
+
+Media players (such as Jack) are an example of reasonable application
+design with multiple tasks (with multiple priority levels) sharing
+short-held locks: for example, a highprio audio playback thread is
+combined with medium-prio construct-audio-data threads and low-prio
+display-colory-stuff threads. Add video and decoding to the mix and
+we've got even more priority levels.
+
+So once we accept that synchronization objects (locks) are an
+unavoidable fact of life, and once we accept that multi-task userspace
+apps have a very fair expectation of being able to use locks, we've got
+to think about how to offer the option of a deterministic locking
+implementation to user-space.
+
+Most of the technical counter-arguments against doing priority
+inheritance only apply to kernel-space locks. But user-space locks are
+different, there we cannot disable interrupts or make the task
+non-preemptible in a critical section, so the 'use spinlocks' argument
+does not apply (user-space spinlocks have the same priority inversion
+problems as other user-space locking constructs). Fact is, pretty much
+the only technique that currently enables good determinism for userspace
+locks (such as futex-based pthread mutexes) is priority inheritance:
+
+Currently (without PI), if a high-prio and a low-prio task shares a lock
+[this is a quite common scenario for most non-trivial RT applications],
+even if all critical sections are coded carefully to be deterministic
+(i.e. all critical sections are short in duration and only execute a
+limited number of instructions), the kernel cannot guarantee any
+deterministic execution of the high-prio task: any medium-priority task
+could preempt the low-prio task while it holds the shared lock and
+executes the critical section, and could delay it indefinitely.
+
+Implementation:
+---------------
+
+As mentioned before, the userspace fastpath of PI-enabled pthread
+mutexes involves no kernel work at all - they behave quite similarly to
+normal futex-based locks: a 0 value means unlocked, and a value==TID
+means locked. (This is the same method as used by list-based robust
+futexes.) Userspace uses atomic ops to lock/unlock these mutexes without
+entering the kernel.
+
+To handle the slowpath, we have added two new futex ops:
+
+  FUTEX_LOCK_PI
+  FUTEX_UNLOCK_PI
+
+If the lock-acquire fastpath fails, [i.e. an atomic transition from 0 to
+TID fails], then FUTEX_LOCK_PI is called. The kernel does all the
+remaining work: if there is no futex-queue attached to the futex address
+yet then the code looks up the task that owns the futex [it has put its
+own TID into the futex value], and attaches a 'PI state' structure to
+the futex-queue. The pi_state includes an rt-mutex, which is a PI-aware,
+kernel-based synchronization object. The 'other' task is made the owner
+of the rt-mutex, and the FUTEX_WAITERS bit is atomically set in the
+futex value. Then this task tries to lock the rt-mutex, on which it
+blocks. Once it returns, it has the mutex acquired, and it sets the
+futex value to its own TID and returns. Userspace has no other work to
+perform - it now owns the lock, and futex value contains
+FUTEX_WAITERS|TID.
+
+If the unlock side fastpath succeeds, [i.e. userspace manages to do a
+TID -> 0 atomic transition of the futex value], then no kernel work is
+triggered.
+
+If the unlock fastpath fails (because the FUTEX_WAITERS bit is set),
+then FUTEX_UNLOCK_PI is called, and the kernel unlocks the futex on the
+behalf of userspace - and it also unlocks the attached
+pi_state->rt_mutex and thus wakes up any potential waiters.
+
+Note that under this approach, contrary to previous PI-futex approaches,
+there is no prior 'registration' of a PI-futex. [which is not quite
+possible anyway, due to existing ABI properties of pthread mutexes.]
+
+Also, under this scheme, 'robustness' and 'PI' are two orthogonal
+properties of futexes, and all four combinations are possible: futex,
+robust-futex, PI-futex, robust+PI-futex.
+
+More details about priority inheritance can be found in
+Documentation/rtmutex.txt.
diff --git a/Documentation/rt-mutex-design.txt b/Documentation/rt-mutex-design.txt
new file mode 100644
index 000000000..c472ffacc
--- /dev/null
+++ b/Documentation/rt-mutex-design.txt
@@ -0,0 +1,781 @@
+#
+# Copyright (c) 2006 Steven Rostedt
+# Licensed under the GNU Free Documentation License, Version 1.2
+#
+
+RT-mutex implementation design
+------------------------------
+
+This document tries to describe the design of the rtmutex.c implementation.
+It doesn't describe the reasons why rtmutex.c exists. For that please see
+Documentation/rt-mutex.txt.  Although this document does explain problems
+that happen without this code, but that is in the concept to understand
+what the code actually is doing.
+
+The goal of this document is to help others understand the priority
+inheritance (PI) algorithm that is used, as well as reasons for the
+decisions that were made to implement PI in the manner that was done.
+
+
+Unbounded Priority Inversion
+----------------------------
+
+Priority inversion is when a lower priority process executes while a higher
+priority process wants to run.  This happens for several reasons, and
+most of the time it can't be helped.  Anytime a high priority process wants
+to use a resource that a lower priority process has (a mutex for example),
+the high priority process must wait until the lower priority process is done
+with the resource.  This is a priority inversion.  What we want to prevent
+is something called unbounded priority inversion.  That is when the high
+priority process is prevented from running by a lower priority process for
+an undetermined amount of time.
+
+The classic example of unbounded priority inversion is were you have three
+processes, let's call them processes A, B, and C, where A is the highest
+priority process, C is the lowest, and B is in between. A tries to grab a lock
+that C owns and must wait and lets C run to release the lock. But in the
+meantime, B executes, and since B is of a higher priority than C, it preempts C,
+but by doing so, it is in fact preempting A which is a higher priority process.
+Now there's no way of knowing how long A will be sleeping waiting for C
+to release the lock, because for all we know, B is a CPU hog and will
+never give C a chance to release the lock.  This is called unbounded priority
+inversion.
+
+Here's a little ASCII art to show the problem.
+
+   grab lock L1 (owned by C)
+     |
+A ---+
+        C preempted by B
+          |
+C    +----+
+
+B         +-------->
+                B now keeps A from running.
+
+
+Priority Inheritance (PI)
+-------------------------
+
+There are several ways to solve this issue, but other ways are out of scope
+for this document.  Here we only discuss PI.
+
+PI is where a process inherits the priority of another process if the other
+process blocks on a lock owned by the current process.  To make this easier
+to understand, let's use the previous example, with processes A, B, and C again.
+
+This time, when A blocks on the lock owned by C, C would inherit the priority
+of A.  So now if B becomes runnable, it would not preempt C, since C now has
+the high priority of A.  As soon as C releases the lock, it loses its
+inherited priority, and A then can continue with the resource that C had.
+
+Terminology
+-----------
+
+Here I explain some terminology that is used in this document to help describe
+the design that is used to implement PI.
+
+PI chain - The PI chain is an ordered series of locks and processes that cause
+           processes to inherit priorities from a previous process that is
+           blocked on one of its locks.  This is described in more detail
+           later in this document.
+
+mutex    - In this document, to differentiate from locks that implement
+           PI and spin locks that are used in the PI code, from now on
+           the PI locks will be called a mutex.
+
+lock     - In this document from now on, I will use the term lock when
+           referring to spin locks that are used to protect parts of the PI
+           algorithm.  These locks disable preemption for UP (when
+           CONFIG_PREEMPT is enabled) and on SMP prevents multiple CPUs from
+           entering critical sections simultaneously.
+
+spin lock - Same as lock above.
+
+waiter   - A waiter is a struct that is stored on the stack of a blocked
+           process.  Since the scope of the waiter is within the code for
+           a process being blocked on the mutex, it is fine to allocate
+           the waiter on the process's stack (local variable).  This
+           structure holds a pointer to the task, as well as the mutex that
+           the task is blocked on.  It also has the plist node structures to
+           place the task in the waiter_list of a mutex as well as the
+           pi_list of a mutex owner task (described below).
+
+           waiter is sometimes used in reference to the task that is waiting
+           on a mutex. This is the same as waiter->task.
+
+waiters  - A list of processes that are blocked on a mutex.
+
+top waiter - The highest priority process waiting on a specific mutex.
+
+top pi waiter - The highest priority process waiting on one of the mutexes
+                that a specific process owns.
+
+Note:  task and process are used interchangeably in this document, mostly to
+       differentiate between two processes that are being described together.
+
+
+PI chain
+--------
+
+The PI chain is a list of processes and mutexes that may cause priority
+inheritance to take place.  Multiple chains may converge, but a chain
+would never diverge, since a process can't be blocked on more than one
+mutex at a time.
+
+Example:
+
+   Process:  A, B, C, D, E
+   Mutexes:  L1, L2, L3, L4
+
+   A owns: L1
+           B blocked on L1
+           B owns L2
+                  C blocked on L2
+                  C owns L3
+                         D blocked on L3
+                         D owns L4
+                                E blocked on L4
+
+The chain would be:
+
+   E->L4->D->L3->C->L2->B->L1->A
+
+To show where two chains merge, we could add another process F and
+another mutex L5 where B owns L5 and F is blocked on mutex L5.
+
+The chain for F would be:
+
+   F->L5->B->L1->A
+
+Since a process may own more than one mutex, but never be blocked on more than
+one, the chains merge.
+
+Here we show both chains:
+
+   E->L4->D->L3->C->L2-+
+                       |
+                       +->B->L1->A
+                       |
+                 F->L5-+
+
+For PI to work, the processes at the right end of these chains (or we may
+also call it the Top of the chain) must be equal to or higher in priority
+than the processes to the left or below in the chain.
+
+Also since a mutex may have more than one process blocked on it, we can
+have multiple chains merge at mutexes.  If we add another process G that is
+blocked on mutex L2:
+
+  G->L2->B->L1->A
+
+And once again, to show how this can grow I will show the merging chains
+again.
+
+   E->L4->D->L3->C-+
+                   +->L2-+
+                   |     |
+                 G-+     +->B->L1->A
+                         |
+                   F->L5-+
+
+
+Plist
+-----
+
+Before I go further and talk about how the PI chain is stored through lists
+on both mutexes and processes, I'll explain the plist.  This is similar to
+the struct list_head functionality that is already in the kernel.
+The implementation of plist is out of scope for this document, but it is
+very important to understand what it does.
+
+There are a few differences between plist and list, the most important one
+being that plist is a priority sorted linked list.  This means that the
+priorities of the plist are sorted, such that it takes O(1) to retrieve the
+highest priority item in the list.  Obviously this is useful to store processes
+based on their priorities.
+
+Another difference, which is important for implementation, is that, unlike
+list, the head of the list is a different element than the nodes of a list.
+So the head of the list is declared as struct plist_head and nodes that will
+be added to the list are declared as struct plist_node.
+
+
+Mutex Waiter List
+-----------------
+
+Every mutex keeps track of all the waiters that are blocked on itself. The mutex
+has a plist to store these waiters by priority.  This list is protected by
+a spin lock that is located in the struct of the mutex. This lock is called
+wait_lock.  Since the modification of the waiter list is never done in
+interrupt context, the wait_lock can be taken without disabling interrupts.
+
+
+Task PI List
+------------
+
+To keep track of the PI chains, each process has its own PI list.  This is
+a list of all top waiters of the mutexes that are owned by the process.
+Note that this list only holds the top waiters and not all waiters that are
+blocked on mutexes owned by the process.
+
+The top of the task's PI list is always the highest priority task that
+is waiting on a mutex that is owned by the task.  So if the task has
+inherited a priority, it will always be the priority of the task that is
+at the top of this list.
+
+This list is stored in the task structure of a process as a plist called
+pi_list.  This list is protected by a spin lock also in the task structure,
+called pi_lock.  This lock may also be taken in interrupt context, so when
+locking the pi_lock, interrupts must be disabled.
+
+
+Depth of the PI Chain
+---------------------
+
+The maximum depth of the PI chain is not dynamic, and could actually be
+defined.  But is very complex to figure it out, since it depends on all
+the nesting of mutexes.  Let's look at the example where we have 3 mutexes,
+L1, L2, and L3, and four separate functions func1, func2, func3 and func4.
+The following shows a locking order of L1->L2->L3, but may not actually
+be directly nested that way.
+
+void func1(void)
+{
+	mutex_lock(L1);
+
+	/* do anything */
+
+	mutex_unlock(L1);
+}
+
+void func2(void)
+{
+	mutex_lock(L1);
+	mutex_lock(L2);
+
+	/* do something */
+
+	mutex_unlock(L2);
+	mutex_unlock(L1);
+}
+
+void func3(void)
+{
+	mutex_lock(L2);
+	mutex_lock(L3);
+
+	/* do something else */
+
+	mutex_unlock(L3);
+	mutex_unlock(L2);
+}
+
+void func4(void)
+{
+	mutex_lock(L3);
+
+	/* do something again */
+
+	mutex_unlock(L3);
+}
+
+Now we add 4 processes that run each of these functions separately.
+Processes A, B, C, and D which run functions func1, func2, func3 and func4
+respectively, and such that D runs first and A last.  With D being preempted
+in func4 in the "do something again" area, we have a locking that follows:
+
+D owns L3
+       C blocked on L3
+       C owns L2
+              B blocked on L2
+              B owns L1
+                     A blocked on L1
+
+And thus we have the chain A->L1->B->L2->C->L3->D.
+
+This gives us a PI depth of 4 (four processes), but looking at any of the
+functions individually, it seems as though they only have at most a locking
+depth of two.  So, although the locking depth is defined at compile time,
+it still is very difficult to find the possibilities of that depth.
+
+Now since mutexes can be defined by user-land applications, we don't want a DOS
+type of application that nests large amounts of mutexes to create a large
+PI chain, and have the code holding spin locks while looking at a large
+amount of data.  So to prevent this, the implementation not only implements
+a maximum lock depth, but also only holds at most two different locks at a
+time, as it walks the PI chain.  More about this below.
+
+
+Mutex owner and flags
+---------------------
+
+The mutex structure contains a pointer to the owner of the mutex.  If the
+mutex is not owned, this owner is set to NULL.  Since all architectures
+have the task structure on at least a four byte alignment (and if this is
+not true, the rtmutex.c code will be broken!), this allows for the two
+least significant bits to be used as flags.  This part is also described
+in Documentation/rt-mutex.txt, but will also be briefly described here.
+
+Bit 0 is used as the "Pending Owner" flag.  This is described later.
+Bit 1 is used as the "Has Waiters" flags.  This is also described later
+  in more detail, but is set whenever there are waiters on a mutex.
+
+
+cmpxchg Tricks
+--------------
+
+Some architectures implement an atomic cmpxchg (Compare and Exchange).  This
+is used (when applicable) to keep the fast path of grabbing and releasing
+mutexes short.
+
+cmpxchg is basically the following function performed atomically:
+
+unsigned long _cmpxchg(unsigned long *A, unsigned long *B, unsigned long *C)
+{
+        unsigned long T = *A;
+        if (*A == *B) {
+                *A = *C;
+        }
+        return T;
+}
+#define cmpxchg(a,b,c) _cmpxchg(&a,&b,&c)
+
+This is really nice to have, since it allows you to only update a variable
+if the variable is what you expect it to be.  You know if it succeeded if
+the return value (the old value of A) is equal to B.
+
+The macro rt_mutex_cmpxchg is used to try to lock and unlock mutexes. If
+the architecture does not support CMPXCHG, then this macro is simply set
+to fail every time.  But if CMPXCHG is supported, then this will
+help out extremely to keep the fast path short.
+
+The use of rt_mutex_cmpxchg with the flags in the owner field help optimize
+the system for architectures that support it.  This will also be explained
+later in this document.
+
+
+Priority adjustments
+--------------------
+
+The implementation of the PI code in rtmutex.c has several places that a
+process must adjust its priority.  With the help of the pi_list of a
+process this is rather easy to know what needs to be adjusted.
+
+The functions implementing the task adjustments are rt_mutex_adjust_prio,
+__rt_mutex_adjust_prio (same as the former, but expects the task pi_lock
+to already be taken), rt_mutex_get_prio, and rt_mutex_setprio.
+
+rt_mutex_getprio and rt_mutex_setprio are only used in __rt_mutex_adjust_prio.
+
+rt_mutex_getprio returns the priority that the task should have.  Either the
+task's own normal priority, or if a process of a higher priority is waiting on
+a mutex owned by the task, then that higher priority should be returned.
+Since the pi_list of a task holds an order by priority list of all the top
+waiters of all the mutexes that the task owns, rt_mutex_getprio simply needs
+to compare the top pi waiter to its own normal priority, and return the higher
+priority back.
+
+(Note:  if looking at the code, you will notice that the lower number of
+        prio is returned.  This is because the prio field in the task structure
+        is an inverse order of the actual priority.  So a "prio" of 5 is
+        of higher priority than a "prio" of 10.)
+
+__rt_mutex_adjust_prio examines the result of rt_mutex_getprio, and if the
+result does not equal the task's current priority, then rt_mutex_setprio
+is called to adjust the priority of the task to the new priority.
+Note that rt_mutex_setprio is defined in kernel/sched.c to implement the
+actual change in priority.
+
+It is interesting to note that __rt_mutex_adjust_prio can either increase
+or decrease the priority of the task.  In the case that a higher priority
+process has just blocked on a mutex owned by the task, __rt_mutex_adjust_prio
+would increase/boost the task's priority.  But if a higher priority task
+were for some reason to leave the mutex (timeout or signal), this same function
+would decrease/unboost the priority of the task.  That is because the pi_list
+always contains the highest priority task that is waiting on a mutex owned
+by the task, so we only need to compare the priority of that top pi waiter
+to the normal priority of the given task.
+
+
+High level overview of the PI chain walk
+----------------------------------------
+
+The PI chain walk is implemented by the function rt_mutex_adjust_prio_chain.
+
+The implementation has gone through several iterations, and has ended up
+with what we believe is the best.  It walks the PI chain by only grabbing
+at most two locks at a time, and is very efficient.
+
+The rt_mutex_adjust_prio_chain can be used either to boost or lower process
+priorities.
+
+rt_mutex_adjust_prio_chain is called with a task to be checked for PI
+(de)boosting (the owner of a mutex that a process is blocking on), a flag to
+check for deadlocking, the mutex that the task owns, and a pointer to a waiter
+that is the process's waiter struct that is blocked on the mutex (although this
+parameter may be NULL for deboosting).
+
+For this explanation, I will not mention deadlock detection. This explanation
+will try to stay at a high level.
+
+When this function is called, there are no locks held.  That also means
+that the state of the owner and lock can change when entered into this function.
+
+Before this function is called, the task has already had rt_mutex_adjust_prio
+performed on it.  This means that the task is set to the priority that it
+should be at, but the plist nodes of the task's waiter have not been updated
+with the new priorities, and that this task may not be in the proper locations
+in the pi_lists and wait_lists that the task is blocked on.  This function
+solves all that.
+
+A loop is entered, where task is the owner to be checked for PI changes that
+was passed by parameter (for the first iteration).  The pi_lock of this task is
+taken to prevent any more changes to the pi_list of the task.  This also
+prevents new tasks from completing the blocking on a mutex that is owned by this
+task.
+
+If the task is not blocked on a mutex then the loop is exited.  We are at
+the top of the PI chain.
+
+A check is now done to see if the original waiter (the process that is blocked
+on the current mutex) is the top pi waiter of the task.  That is, is this
+waiter on the top of the task's pi_list.  If it is not, it either means that
+there is another process higher in priority that is blocked on one of the
+mutexes that the task owns, or that the waiter has just woken up via a signal
+or timeout and has left the PI chain.  In either case, the loop is exited, since
+we don't need to do any more changes to the priority of the current task, or any
+task that owns a mutex that this current task is waiting on.  A priority chain
+walk is only needed when a new top pi waiter is made to a task.
+
+The next check sees if the task's waiter plist node has the priority equal to
+the priority the task is set at.  If they are equal, then we are done with
+the loop.  Remember that the function started with the priority of the
+task adjusted, but the plist nodes that hold the task in other processes
+pi_lists have not been adjusted.
+
+Next, we look at the mutex that the task is blocked on. The mutex's wait_lock
+is taken.  This is done by a spin_trylock, because the locking order of the
+pi_lock and wait_lock goes in the opposite direction. If we fail to grab the
+lock, the pi_lock is released, and we restart the loop.
+
+Now that we have both the pi_lock of the task as well as the wait_lock of
+the mutex the task is blocked on, we update the task's waiter's plist node
+that is located on the mutex's wait_list.
+
+Now we release the pi_lock of the task.
+
+Next the owner of the mutex has its pi_lock taken, so we can update the
+task's entry in the owner's pi_list.  If the task is the highest priority
+process on the mutex's wait_list, then we remove the previous top waiter
+from the owner's pi_list, and replace it with the task.
+
+Note: It is possible that the task was the current top waiter on the mutex,
+      in which case the task is not yet on the pi_list of the waiter.  This
+      is OK, since plist_del does nothing if the plist node is not on any
+      list.
+
+If the task was not the top waiter of the mutex, but it was before we
+did the priority updates, that means we are deboosting/lowering the
+task.  In this case, the task is removed from the pi_list of the owner,
+and the new top waiter is added.
+
+Lastly, we unlock both the pi_lock of the task, as well as the mutex's
+wait_lock, and continue the loop again.  On the next iteration of the
+loop, the previous owner of the mutex will be the task that will be
+processed.
+
+Note: One might think that the owner of this mutex might have changed
+      since we just grab the mutex's wait_lock. And one could be right.
+      The important thing to remember is that the owner could not have
+      become the task that is being processed in the PI chain, since
+      we have taken that task's pi_lock at the beginning of the loop.
+      So as long as there is an owner of this mutex that is not the same
+      process as the tasked being worked on, we are OK.
+
+      Looking closely at the code, one might be confused.  The check for the
+      end of the PI chain is when the task isn't blocked on anything or the
+      task's waiter structure "task" element is NULL.  This check is
+      protected only by the task's pi_lock.  But the code to unlock the mutex
+      sets the task's waiter structure "task" element to NULL with only
+      the protection of the mutex's wait_lock, which was not taken yet.
+      Isn't this a race condition if the task becomes the new owner?
+
+      The answer is No!  The trick is the spin_trylock of the mutex's
+      wait_lock.  If we fail that lock, we release the pi_lock of the
+      task and continue the loop, doing the end of PI chain check again.
+
+      In the code to release the lock, the wait_lock of the mutex is held
+      the entire time, and it is not let go when we grab the pi_lock of the
+      new owner of the mutex.  So if the switch of a new owner were to happen
+      after the check for end of the PI chain and the grabbing of the
+      wait_lock, the unlocking code would spin on the new owner's pi_lock
+      but never give up the wait_lock.  So the PI chain loop is guaranteed to
+      fail the spin_trylock on the wait_lock, release the pi_lock, and
+      try again.
+
+      If you don't quite understand the above, that's OK. You don't have to,
+      unless you really want to make a proof out of it ;)
+
+
+Pending Owners and Lock stealing
+--------------------------------
+
+One of the flags in the owner field of the mutex structure is "Pending Owner".
+What this means is that an owner was chosen by the process releasing the
+mutex, but that owner has yet to wake up and actually take the mutex.
+
+Why is this important?  Why can't we just give the mutex to another process
+and be done with it?
+
+The PI code is to help with real-time processes, and to let the highest
+priority process run as long as possible with little latencies and delays.
+If a high priority process owns a mutex that a lower priority process is
+blocked on, when the mutex is released it would be given to the lower priority
+process.  What if the higher priority process wants to take that mutex again.
+The high priority process would fail to take that mutex that it just gave up
+and it would need to boost the lower priority process to run with full
+latency of that critical section (since the low priority process just entered
+it).
+
+There's no reason a high priority process that gives up a mutex should be
+penalized if it tries to take that mutex again.  If the new owner of the
+mutex has not woken up yet, there's no reason that the higher priority process
+could not take that mutex away.
+
+To solve this, we introduced Pending Ownership and Lock Stealing.  When a
+new process is given a mutex that it was blocked on, it is only given
+pending ownership.  This means that it's the new owner, unless a higher
+priority process comes in and tries to grab that mutex.  If a higher priority
+process does come along and wants that mutex, we let the higher priority
+process "steal" the mutex from the pending owner (only if it is still pending)
+and continue with the mutex.
+
+
+Taking of a mutex (The walk through)
+------------------------------------
+
+OK, now let's take a look at the detailed walk through of what happens when
+taking a mutex.
+
+The first thing that is tried is the fast taking of the mutex.  This is
+done when we have CMPXCHG enabled (otherwise the fast taking automatically
+fails).  Only when the owner field of the mutex is NULL can the lock be
+taken with the CMPXCHG and nothing else needs to be done.
+
+If there is contention on the lock, whether it is owned or pending owner
+we go about the slow path (rt_mutex_slowlock).
+
+The slow path function is where the task's waiter structure is created on
+the stack.  This is because the waiter structure is only needed for the
+scope of this function.  The waiter structure holds the nodes to store
+the task on the wait_list of the mutex, and if need be, the pi_list of
+the owner.
+
+The wait_lock of the mutex is taken since the slow path of unlocking the
+mutex also takes this lock.
+
+We then call try_to_take_rt_mutex.  This is where the architecture that
+does not implement CMPXCHG would always grab the lock (if there's no
+contention).
+
+try_to_take_rt_mutex is used every time the task tries to grab a mutex in the
+slow path.  The first thing that is done here is an atomic setting of
+the "Has Waiters" flag of the mutex's owner field.  Yes, this could really
+be false, because if the the mutex has no owner, there are no waiters and
+the current task also won't have any waiters.  But we don't have the lock
+yet, so we assume we are going to be a waiter.  The reason for this is to
+play nice for those architectures that do have CMPXCHG.  By setting this flag
+now, the owner of the mutex can't release the mutex without going into the
+slow unlock path, and it would then need to grab the wait_lock, which this
+code currently holds.  So setting the "Has Waiters" flag forces the owner
+to synchronize with this code.
+
+Now that we know that we can't have any races with the owner releasing the
+mutex, we check to see if we can take the ownership.  This is done if the
+mutex doesn't have a owner, or if we can steal the mutex from a pending
+owner.  Let's look at the situations we have here.
+
+  1) Has owner that is pending
+  ----------------------------
+
+  The mutex has a owner, but it hasn't woken up and the mutex flag
+  "Pending Owner" is set.  The first check is to see if the owner isn't the
+  current task.  This is because this function is also used for the pending
+  owner to grab the mutex.  When a pending owner wakes up, it checks to see
+  if it can take the mutex, and this is done if the owner is already set to
+  itself.  If so, we succeed and leave the function, clearing the "Pending
+  Owner" bit.
+
+  If the pending owner is not current, we check to see if the current priority is
+  higher than the pending owner.  If not, we fail the function and return.
+
+  There's also something special about a pending owner.  That is a pending owner
+  is never blocked on a mutex.  So there is no PI chain to worry about.  It also
+  means that if the mutex doesn't have any waiters, there's no accounting needed
+  to update the pending owner's pi_list, since we only worry about processes
+  blocked on the current mutex.
+
+  If there are waiters on this mutex, and we just stole the ownership, we need
+  to take the top waiter, remove it from the pi_list of the pending owner, and
+  add it to the current pi_list.  Note that at this moment, the pending owner
+  is no longer on the list of waiters.  This is fine, since the pending owner
+  would add itself back when it realizes that it had the ownership stolen
+  from itself.  When the pending owner tries to grab the mutex, it will fail
+  in try_to_take_rt_mutex if the owner field points to another process.
+
+  2) No owner
+  -----------
+
+  If there is no owner (or we successfully stole the lock), we set the owner
+  of the mutex to current, and set the flag of "Has Waiters" if the current
+  mutex actually has waiters, or we clear the flag if it doesn't.  See, it was
+  OK that we set that flag early, since now it is cleared.
+
+  3) Failed to grab ownership
+  ---------------------------
+
+  The most interesting case is when we fail to take ownership. This means that
+  there exists an owner, or there's a pending owner with equal or higher
+  priority than the current task.
+
+We'll continue on the failed case.
+
+If the mutex has a timeout, we set up a timer to go off to break us out
+of this mutex if we failed to get it after a specified amount of time.
+
+Now we enter a loop that will continue to try to take ownership of the mutex, or
+fail from a timeout or signal.
+
+Once again we try to take the mutex.  This will usually fail the first time
+in the loop, since it had just failed to get the mutex.  But the second time
+in the loop, this would likely succeed, since the task would likely be
+the pending owner.
+
+If the mutex is TASK_INTERRUPTIBLE a check for signals and timeout is done
+here.
+
+The waiter structure has a "task" field that points to the task that is blocked
+on the mutex.  This field can be NULL the first time it goes through the loop
+or if the task is a pending owner and had it's mutex stolen.  If the "task"
+field is NULL then we need to set up the accounting for it.
+
+Task blocks on mutex
+--------------------
+
+The accounting of a mutex and process is done with the waiter structure of
+the process.  The "task" field is set to the process, and the "lock" field
+to the mutex.  The plist nodes are initialized to the processes current
+priority.
+
+Since the wait_lock was taken at the entry of the slow lock, we can safely
+add the waiter to the wait_list.  If the current process is the highest
+priority process currently waiting on this mutex, then we remove the
+previous top waiter process (if it exists) from the pi_list of the owner,
+and add the current process to that list.  Since the pi_list of the owner
+has changed, we call rt_mutex_adjust_prio on the owner to see if the owner
+should adjust its priority accordingly.
+
+If the owner is also blocked on a lock, and had its pi_list changed
+(or deadlock checking is on), we unlock the wait_lock of the mutex and go ahead
+and run rt_mutex_adjust_prio_chain on the owner, as described earlier.
+
+Now all locks are released, and if the current process is still blocked on a
+mutex (waiter "task" field is not NULL), then we go to sleep (call schedule).
+
+Waking up in the loop
+---------------------
+
+The schedule can then wake up for a few reasons.
+  1) we were given pending ownership of the mutex.
+  2) we received a signal and was TASK_INTERRUPTIBLE
+  3) we had a timeout and was TASK_INTERRUPTIBLE
+
+In any of these cases, we continue the loop and once again try to grab the
+ownership of the mutex.  If we succeed, we exit the loop, otherwise we continue
+and on signal and timeout, will exit the loop, or if we had the mutex stolen
+we just simply add ourselves back on the lists and go back to sleep.
+
+Note: For various reasons, because of timeout and signals, the steal mutex
+      algorithm needs to be careful. This is because the current process is
+      still on the wait_list. And because of dynamic changing of priorities,
+      especially on SCHED_OTHER tasks, the current process can be the
+      highest priority task on the wait_list.
+
+Failed to get mutex on Timeout or Signal
+----------------------------------------
+
+If a timeout or signal occurred, the waiter's "task" field would not be
+NULL and the task needs to be taken off the wait_list of the mutex and perhaps
+pi_list of the owner.  If this process was a high priority process, then
+the rt_mutex_adjust_prio_chain needs to be executed again on the owner,
+but this time it will be lowering the priorities.
+
+
+Unlocking the Mutex
+-------------------
+
+The unlocking of a mutex also has a fast path for those architectures with
+CMPXCHG.  Since the taking of a mutex on contention always sets the
+"Has Waiters" flag of the mutex's owner, we use this to know if we need to
+take the slow path when unlocking the mutex.  If the mutex doesn't have any
+waiters, the owner field of the mutex would equal the current process and
+the mutex can be unlocked by just replacing the owner field with NULL.
+
+If the owner field has the "Has Waiters" bit set (or CMPXCHG is not available),
+the slow unlock path is taken.
+
+The first thing done in the slow unlock path is to take the wait_lock of the
+mutex.  This synchronizes the locking and unlocking of the mutex.
+
+A check is made to see if the mutex has waiters or not.  On architectures that
+do not have CMPXCHG, this is the location that the owner of the mutex will
+determine if a waiter needs to be awoken or not.  On architectures that
+do have CMPXCHG, that check is done in the fast path, but it is still needed
+in the slow path too.  If a waiter of a mutex woke up because of a signal
+or timeout between the time the owner failed the fast path CMPXCHG check and
+the grabbing of the wait_lock, the mutex may not have any waiters, thus the
+owner still needs to make this check. If there are no waiters than the mutex
+owner field is set to NULL, the wait_lock is released and nothing more is
+needed.
+
+If there are waiters, then we need to wake one up and give that waiter
+pending ownership.
+
+On the wake up code, the pi_lock of the current owner is taken.  The top
+waiter of the lock is found and removed from the wait_list of the mutex
+as well as the pi_list of the current owner.  The task field of the new
+pending owner's waiter structure is set to NULL, and the owner field of the
+mutex is set to the new owner with the "Pending Owner" bit set, as well
+as the "Has Waiters" bit if there still are other processes blocked on the
+mutex.
+
+The pi_lock of the previous owner is released, and the new pending owner's
+pi_lock is taken.  Remember that this is the trick to prevent the race
+condition in rt_mutex_adjust_prio_chain from adding itself as a waiter
+on the mutex.
+
+We now clear the "pi_blocked_on" field of the new pending owner, and if
+the mutex still has waiters pending, we add the new top waiter to the pi_list
+of the pending owner.
+
+Finally we unlock the pi_lock of the pending owner and wake it up.
+
+
+Contact
+-------
+
+For updates on this document, please email Steven Rostedt <rostedt@goodmis.org>
+
+
+Credits
+-------
+
+Author:  Steven Rostedt <rostedt@goodmis.org>
+
+Reviewers:  Ingo Molnar, Thomas Gleixner, Thomas Duetsch, and Randy Dunlap
+
+Updates
+-------
+
+This document was originally written for 2.6.17-rc3-mm1
diff --git a/Documentation/rt-mutex.txt b/Documentation/rt-mutex.txt
new file mode 100644
index 000000000..243393d88
--- /dev/null
+++ b/Documentation/rt-mutex.txt
@@ -0,0 +1,79 @@
+RT-mutex subsystem with PI support
+----------------------------------
+
+RT-mutexes with priority inheritance are used to support PI-futexes,
+which enable pthread_mutex_t priority inheritance attributes
+(PTHREAD_PRIO_INHERIT). [See Documentation/pi-futex.txt for more details
+about PI-futexes.]
+
+This technology was developed in the -rt tree and streamlined for
+pthread_mutex support.
+
+Basic principles:
+-----------------
+
+RT-mutexes extend the semantics of simple mutexes by the priority
+inheritance protocol.
+
+A low priority owner of a rt-mutex inherits the priority of a higher
+priority waiter until the rt-mutex is released. If the temporarily
+boosted owner blocks on a rt-mutex itself it propagates the priority
+boosting to the owner of the other rt_mutex it gets blocked on. The
+priority boosting is immediately removed once the rt_mutex has been
+unlocked.
+
+This approach allows us to shorten the block of high-prio tasks on
+mutexes which protect shared resources. Priority inheritance is not a
+magic bullet for poorly designed applications, but it allows
+well-designed applications to use userspace locks in critical parts of
+an high priority thread, without losing determinism.
+
+The enqueueing of the waiters into the rtmutex waiter list is done in
+priority order. For same priorities FIFO order is chosen. For each
+rtmutex, only the top priority waiter is enqueued into the owner's
+priority waiters list. This list too queues in priority order. Whenever
+the top priority waiter of a task changes (for example it timed out or
+got a signal), the priority of the owner task is readjusted. [The
+priority enqueueing is handled by "plists", see include/linux/plist.h
+for more details.]
+
+RT-mutexes are optimized for fastpath operations and have no internal
+locking overhead when locking an uncontended mutex or unlocking a mutex
+without waiters. The optimized fastpath operations require cmpxchg
+support. [If that is not available then the rt-mutex internal spinlock
+is used]
+
+The state of the rt-mutex is tracked via the owner field of the rt-mutex
+structure:
+
+rt_mutex->owner holds the task_struct pointer of the owner. Bit 0 and 1
+are used to keep track of the "owner is pending" and "rtmutex has
+waiters" state.
+
+ owner		bit1	bit0
+ NULL		0	0	mutex is free (fast acquire possible)
+ NULL		0	1	invalid state
+ NULL		1	0	Transitional state*
+ NULL		1	1	invalid state
+ taskpointer	0	0	mutex is held (fast release possible)
+ taskpointer	0	1	task is pending owner
+ taskpointer	1	0	mutex is held and has waiters
+ taskpointer	1	1	task is pending owner and mutex has waiters
+
+Pending-ownership handling is a performance optimization:
+pending-ownership is assigned to the first (highest priority) waiter of
+the mutex, when the mutex is released. The thread is woken up and once
+it starts executing it can acquire the mutex. Until the mutex is taken
+by it (bit 0 is cleared) a competing higher priority thread can "steal"
+the mutex which puts the woken up thread back on the waiters list.
+
+The pending-ownership optimization is especially important for the
+uninterrupted workflow of high-prio tasks which repeatedly
+takes/releases locks that have lower-prio waiters. Without this
+optimization the higher-prio thread would ping-pong to the lower-prio
+task [because at unlock time we always assign a new owner].
+
+(*) The "mutex has waiters" bit gets set to take the lock. If the lock
+doesn't already have an owner, this bit is quickly cleared if there are
+no waiters.  So this is a transitional state to synchronize with looking
+at the owner field of the mutex and the mutex owner releasing the lock.
diff --git a/Documentation/scsi/hptiop.txt b/Documentation/scsi/hptiop.txt
new file mode 100644
index 000000000..d28a31247
--- /dev/null
+++ b/Documentation/scsi/hptiop.txt
@@ -0,0 +1,92 @@
+HIGHPOINT ROCKETRAID 3xxx RAID DRIVER (hptiop)
+
+Controller Register Map
+-------------------------
+
+The controller IOP is accessed via PCI BAR0.
+
+     BAR0 offset    Register
+            0x10    Inbound Message Register 0
+            0x14    Inbound Message Register 1
+            0x18    Outbound Message Register 0
+            0x1C    Outbound Message Register 1
+            0x20    Inbound Doorbell Register
+            0x24    Inbound Interrupt Status Register
+            0x28    Inbound Interrupt Mask Register
+            0x30    Outbound Interrupt Status Register
+            0x34    Outbound Interrupt Mask Register
+            0x40    Inbound Queue Port
+            0x44    Outbound Queue Port
+
+
+I/O Request Workflow
+----------------------
+
+All queued requests are handled via inbound/outbound queue port.
+A request packet can be allocated in either IOP or host memory.
+
+To send a request to the controller:
+
+    - Get a free request packet by reading the inbound queue port or
+      allocate a free request in host DMA coherent memory.
+
+      The value returned from the inbound queue port is an offset
+      relative to the IOP BAR0.
+
+      Requests allocated in host memory must be aligned on 32-bytes boundary.
+
+    - Fill the packet.
+
+    - Post the packet to IOP by writing it to inbound queue. For requests
+      allocated in IOP memory, write the offset to inbound queue port. For
+      requests allocated in host memory, write (0x80000000|(bus_addr>>5))
+      to the inbound queue port.
+
+    - The IOP process the request. When the request is completed, it
+      will be put into outbound queue. An outbound interrupt will be
+      generated.
+
+      For requests allocated in IOP memory, the request offset is posted to
+      outbound queue.
+
+      For requests allocated in host memory, (0x80000000|(bus_addr>>5))
+      is posted to the outbound queue. If IOP_REQUEST_FLAG_OUTPUT_CONTEXT
+      flag is set in the request, the low 32-bit context value will be
+      posted instead.
+
+    - The host read the outbound queue and complete the request.
+
+      For requests allocated in IOP memory, the host driver free the request
+      by writing it to the outbound queue.
+
+Non-queued requests (reset/flush etc) can be sent via inbound message
+register 0. An outbound message with the same value indicates the completion
+of an inbound message.
+
+
+User-level Interface
+---------------------
+
+The driver exposes following sysfs attributes:
+
+     NAME                 R/W    Description
+     driver-version        R     driver version string
+     firmware-version      R     firmware version string
+
+The driver registers char device "hptiop" to communicate with HighPoint RAID
+management software. Its ioctl routine acts as a general binary interface 
+between the IOP firmware and HighPoint RAID management software. New management
+functions can be implemented in application/firmware without modification
+in driver code.
+
+
+-----------------------------------------------------------------------------
+Copyright (C) 2006 HighPoint Technologies, Inc. All Rights Reserved.
+
+  This file 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.
+
+  linux@highpoint-tech.com
+  http://www.highpoint-tech.com
diff --git a/Documentation/utrace.txt b/Documentation/utrace.txt
new file mode 100644
index 000000000..73858ed6e
--- /dev/null
+++ b/Documentation/utrace.txt
@@ -0,0 +1,455 @@
+DRAFT DRAFT DRAFT	WORK IN PROGRESS	DRAFT DRAFT DRAFT
+
+This is work in progress and likely to change.
+
+
+	Roland McGrath <roland@redhat.com>
+
+---
+
+		User Debugging Data & Event Rendezvous
+		---- --------- ---- - ----- ----------
+
+See linux/utrace.h for all the declarations used here.
+See also linux/tracehook.h for the utrace_regset declarations.
+
+The UTRACE is infrastructure code for tracing and controlling user
+threads.  This is the foundation for writing tracing engines, which
+can be loadable kernel modules.  The UTRACE interfaces provide three
+basic facilities:
+
+* Thread event reporting
+
+  Tracing engines can request callbacks for events of interest in
+  the thread: signals, system calls, exit, exec, clone, etc.
+
+* Core thread control
+
+  Tracing engines can prevent a thread from running (keeping it in
+  TASK_TRACED state), or make it single-step or block-step (when
+  hardware supports it).  Engines can cause a thread to abort system
+  calls, they change the behaviors of signals, and they can inject
+  signal-style actions at will.
+
+* Thread machine state access
+
+  Tracing engines can read and write a thread's registers and
+  similar per-thread CPU state.
+
+
+	Tracing engines
+	------- -------
+
+The basic actors in UTRACE are the thread and the tracing engine.
+A tracing engine is some body of code that calls into the utrace_*
+interfaces, represented by a struct utrace_engine_ops.  (Usually it's a
+kernel module, though the legacy ptrace support is a tracing engine
+that is not in a kernel module.)  The UTRACE interface operates on
+individual threads (struct task_struct).  If an engine wants to
+treat several threads as a group, that is up to its higher-level
+code.  Using the UTRACE starts out by attaching an engine to a thread.
+
+	struct utrace_attached_engine *
+	utrace_attach(struct task_struct *target, int flags,
+		      const struct utrace_engine_ops *ops, unsigned long data);
+
+Calling utrace_attach is what sets up a tracing engine to trace a
+thread.  Use UTRACE_ATTACH_CREATE in flags, and pass your engine's ops.
+Check the return value with IS_ERR.  If successful, it returns a
+struct pointer that is the handle used in all other utrace_* calls.
+The data argument is stored in the utrace_attached_engine structure,
+for your code to use however it wants.
+
+	void utrace_detach(struct task_struct *target,
+			   struct utrace_attached_engine *engine);
+
+The utrace_detach call removes an engine from a thread.
+No more callbacks will be made after this returns.
+
+
+An attached engine does nothing by default.
+An engine makes something happen by setting its flags.
+
+	void utrace_set_flags(struct task_struct *target,
+			      struct utrace_attached_engine *engine,
+			      unsigned long flags);
+
+
+	Action Flags
+	------ -----
+
+There are two kinds of flags that an attached engine can set: event
+flags, and action flags.  Event flags register interest in particular
+events; when an event happens and an engine has the right event flag
+set, it gets a callback.  Action flags change the normal behavior of
+the thread.  The action flags available are:
+
+	UTRACE_ACTION_QUIESCE
+
+		The thread will stay quiescent (see below).
+		As long as any engine asserts the QUIESCE action flag,
+		the thread will not resume running in user mode.
+		(Usually it will be in TASK_TRACED state.)
+		Nothing will wake the thread up except for SIGKILL
+		(and implicit SIGKILLs such as a core dump in
+		another thread sharing the same address space, or a
+		group exit or fatal signal in another thread in the
+		same thread group).
+
+	UTRACE_ACTION_SINGLESTEP
+
+		When the thread runs, it will run one instruction
+		and then trap.  (Exiting a system call or entering a
+		signal handler is considered "an instruction" for this.)
+		This can be used only if ARCH_HAS_SINGLE_STEP #define'd
+		by <asm/tracehook.h> and evaluates to nonzero.
+
+	UTRACE_ACTION_BLOCKSTEP
+
+		When the thread runs, it will run until the next branch,
+		and then trap.  (Exiting a system call or entering a
+		signal handler is considered a branch for this.)
+		When the SINGLESTEP flag is set, BLOCKSTEP has no effect.
+		This is only available on some machines (actually none yet).
+		This can be used only if ARCH_HAS_BLOCK_STEP #define'd
+		by <asm/tracehook.h> and evaluates to nonzero.
+
+	UTRACE_ACTION_NOREAP
+
+		When the thread exits or stops for job control, its
+		parent process will not receive a SIGCHLD and the
+		parent's wait calls will not wake up or report the
+		child as dead.  A well-behaved tracing engine does not
+		want to interfere with the parent's normal notifications.
+		This is provided mainly for the ptrace compatibility
+		code to implement the traditional behavior.
+
+Event flags are specified using the macro UTRACE_EVENT(TYPE).
+Each event type is associated with a report_* callback in struct
+utrace_engine_ops.  A tracing engine can leave unused callbacks NULL.
+The only callbacks required are those used by the event flags it sets.
+
+Many engines can be attached to each thread.  When a thread has an
+event, each engine gets a report_* callback if it has set the event flag
+for that event type.  Engines are called in the order they attached.
+
+Each callback takes arguments giving the details of the particular
+event.  The first two arguments two every callback are the struct
+utrace_attached_engine and struct task_struct pointers for the engine
+and the thread producing the event.  Usually this will be the current
+thread that is running the callback functions.
+
+The return value of report_* callbacks is a bitmask.  Some bits are
+common to all callbacks, and some are particular to that callback and
+event type.  The value zero (UTRACE_ACTION_RESUME) always means the
+simplest thing: do what would have happened with no tracing engine here.
+These are the flags that can be set in any report_* return value:
+
+	UTRACE_ACTION_NEWSTATE
+
+		Update the action state flags, described above.  Those
+		bits from the return value (UTRACE_ACTION_STATE_MASK)
+		replace those bits in the engine's flags.  This has the
+		same effect as calling utrace_set_flags, but is a more
+		efficient short-cut.  To change the event flags, you must
+		call utrace_set_flags.
+
+	UTRACE_ACTION_DETACH
+
+		Detach this engine.  This has the effect of calling
+		utrace_detach, but is a more efficient short-cut.
+
+	UTRACE_ACTION_HIDE
+
+		Hide this event from other tracing engines.  This is
+		only appropriate to do when the event was induced by
+		some action of this engine, such as a breakpoint trap.
+		Some events cannot be hidden, since every engine has to
+		know about them: exit, death, reap.
+
+The return value bits in UTRACE_ACTION_OP_MASK indicate a change to the
+normal behavior of the event taking place.  If zero, the thread does
+whatever that event normally means.  For report_signal, other values
+control the disposition of the signal.
+
+
+	Quiescence
+	----------
+
+To control another thread and access its state, it must be "quiescent".
+This means that it is stopped and won't start running again while we access
+it.  A quiescent thread is stopped in a place close to user mode, where the
+user state can be accessed safely; either it's about to return to user
+mode, or it's just entered the kernel from user mode, or it has already
+finished exiting (TASK_ZOMBIE).  Setting the UTRACE_ACTION_QUIESCE action
+flag will force the attached thread to become quiescent soon.  After
+setting the flag, an engine must wait for an event callback when the thread
+becomes quiescent.  The thread may be running on another CPU, or may be in
+an uninterruptible wait.  When it is ready to be examined, it will make
+callbacks to engines that set the UTRACE_EVENT(QUIESCE) event flag.
+
+As long as some engine has UTRACE_ACTION_QUIESCE set, then the thread will
+remain stopped.  SIGKILL will wake it up, but it will not run user code.
+When the flag is cleared via utrace_set_flags or a callback return value,
+the thread starts running again.
+
+During the event callbacks (report_*), the thread in question makes the
+callback from a safe place.  It is not quiescent, but it can safely access
+its own state.  Callbacks can access thread state directly without setting
+the QUIESCE action flag.  If a callback does want to prevent the thread
+from resuming normal execution, it *must* use the QUIESCE action state
+rather than simply blocking; see "Core Events & Callbacks", below.
+
+
+	Thread control
+	------ -------
+
+These calls must be made on a quiescent thread (or the current thread):
+
+	int utrace_inject_signal(struct task_struct *target,
+				 struct utrace_attached_engine *engine,
+				 u32 action, siginfo_t *info,
+				 const struct k_sigaction *ka);
+
+Cause a specified signal delivery in the target thread.  This is not
+like kill, which generates a signal to be dequeued and delivered later.
+Injection directs the thread to deliver a signal now, before it next
+resumes in user mode or dequeues any other pending signal.  It's as if
+the tracing engine intercepted a signal event and its report_signal
+callback returned the action argument as its value (see below).  The
+info and ka arguments serve the same purposes as their counterparts in
+a report_signal callback.
+
+	const struct utrace_regset *
+	utrace_regset(struct task_struct *target,
+		      struct utrace_attached_engine *engine,
+		      const struct utrace_regset_view *view,
+		      int which);
+
+Get access to machine state for the thread.  The struct utrace_regset_view
+indicates a view of machine state, corresponding to a user mode
+architecture personality (such as 32-bit or 64-bit versions of a machine).
+The which argument selects one of the register sets available in that view.
+The utrace_regset call must be made before accessing any machine state,
+each time the thread has been running and has then become quiescent.
+It ensures that the thread's state is ready to be accessed, and returns
+the struct utrace_regset giving its accessor functions.
+
+XXX needs front ends for argument checks, export utrace_native_view
+
+
+	Core Events & Callbacks
+	---- ------ - ---------
+
+Event reporting callbacks have details particular to the event type, but
+are all called in similar environments and have the same constraints.
+Callbacks are made from safe spots, where no locks are held, no special
+resources are pinned, and the user-mode state of the thread is accessible.
+So, callback code has a pretty free hand.  But to be a good citizen,
+callback code should never block for long periods.  It is fine to block in
+kmalloc and the like, but never wait for i/o or for user mode to do
+something.  If you need the thread to wait, set UTRACE_ACTION_QUIESCE and
+return from the callback quickly.  When your i/o finishes or whatever, you
+can use utrace_set_flags to resume the thread.
+
+Well-behaved callbacks are important to maintain two essential properties
+of the interface.  The first of these is that unrelated tracing engines not
+interfere with each other.  If your engine's event callback does not return
+quickly, then another engine won't get the event notification in a timely
+manner.  The second important property is that tracing be as noninvasive as
+possible to the normal operation of the system overall and of the traced
+thread in particular.  That is, attached tracing engines should not perturb
+a thread's behavior, except to the extent that changing its user-visible
+state is explicitly what you want to do.  (Obviously some perturbation is
+unavoidable, primarily timing changes, ranging from small delays due to the
+overhead of tracing, to arbitrary pauses in user code execution when a user
+stops a thread with a debugger for examination.  When doing asynchronous
+utrace_attach to a thread doing a system call, more troublesome side
+effects are possible.)  Even when you explicitly want the pertrubation of
+making the traced thread block, just blocking directly in your callback has
+more unwanted effects.  For example, the CLONE event callbacks are called
+when the new child thread has been created but not yet started running; the
+child can never be scheduled until the CLONE tracing callbacks return.
+(This allows engines tracing the parent to attach to the child.)  If a
+CLONE event callback blocks the parent thread, it also prevents the child
+thread from running (even to process a SIGKILL).  If what you want is to
+make both the parent and child block, then use utrace_attach on the child
+and then set the QUIESCE action state flag on both threads.  A more crucial
+problem with blocking in callbacks is that it can prevent SIGKILL from
+working.  A thread that is blocking due to UTRACE_ACTION_QUIESCE will still
+wake up and die immediately when sent a SIGKILL, as all threads should.
+Relying on the utrace infrastructure rather than on private synchronization
+calls in event callbacks is an important way to help keep tracing robustly
+noninvasive.
+
+
+EVENT(REAP)		Dead thread has been reaped
+Callback:
+	void (*report_reap)(struct utrace_attached_engine *engine,
+			    struct task_struct *tsk);
+
+This means the parent called wait, or else this was a detached thread or
+a process whose parent ignores SIGCHLD.  This cannot happen while the
+UTRACE_ACTION_NOREAP flag is set.  This is the only callback you are
+guaranteed to get (if you set the flag).
+
+Unlike other callbacks, this can be called from the parent's context
+rather than from the traced thread itself--it must not delay the parent by
+blocking.  This callback is different from all others, it returns void.
+Once you get this callback, your engine is automatically detached and you
+cannot access this thread or use this struct utrace_attached_engine handle
+any longer.  This is the place to clean up your data structures and
+synchronize with your code that might try to make utrace_* calls using this
+engine data structure.  The struct is still valid during this callback,
+but will be freed soon after it returns (via RCU).
+
+In all other callbacks, the return value is as described above.
+The common UTRACE_ACTION_* flags in the return value are always observed.
+Unless otherwise specified below, other bits in the return value are ignored.
+
+
+EVENT(QUIESCE)		Thread is quiescent
+Callback:
+	u32 (*report_quiesce)(struct utrace_attached_engine *engine,
+			      struct task_struct *tsk);
+
+This is the least interesting callback.  It happens at any safe spot,
+including after any other event callback.  This lets the tracing engine
+know that it is safe to access the thread's state, or to report to users
+that it has stopped running user code.
+
+EVENT(CLONE)		Thread is creating a child
+Callback:
+	u32 (*report_clone)(struct utrace_attached_engine *engine,
+			    struct task_struct *parent,
+			    unsigned long clone_flags,
+			    struct task_struct *child);
+
+A clone/clone2/fork/vfork system call has succeeded in creating a new
+thread or child process.  The new process is fully formed, but not yet
+running.  During this callback, other tracing engines are prevented from
+using utrace_attach asynchronously on the child, so that engines tracing
+the parent get the first opportunity to attach.  After this callback
+returns, the child will start and the parent's system call will return.
+If CLONE_VFORK is set, the parent will block before returning.
+
+EVENT(VFORK_DONE)	Finished waiting for CLONE_VFORK child
+Callback:
+	u32 (*report_vfork_done)(struct utrace_attached_engine *engine,
+				 struct task_struct *parent, pid_t child_pid);
+
+Event reported for parent using CLONE_VFORK or vfork system call.
+The child has died or exec'd, so the vfork parent has unblocked
+and is about to return child_pid.
+
+UTRACE_EVENT(EXEC)		Completed exec
+Callback:
+	u32 (*report_exec)(struct utrace_attached_engine *engine,
+			   struct task_struct *tsk,
+			   const struct linux_binprm *bprm,
+			   struct pt_regs *regs);
+
+An execve system call has succeeded and the new program is about to
+start running.  The initial user register state is handy to be tweaked
+directly, or utrace_regset can be used for full machine state access.
+
+UTRACE_EVENT(EXIT)		Thread is exiting
+Callback:
+	u32 (*report_exit)(struct utrace_attached_engine *engine,
+			   struct task_struct *tsk,
+			   long orig_code, long *code);
+
+The thread is exiting and cannot be prevented from doing so, but all its
+state is still live.  The *code value will be the wait result seen by
+the parent, and can be changed by this engine or others.  The orig_code
+value is the real status, not changed by any tracing engine.
+
+UTRACE_EVENT(DEATH)		Thread has finished exiting
+Callback:
+	u32 (*report_death)(struct utrace_attached_engine *engine,
+			    struct task_struct *tsk);
+
+The thread is really dead now.  If the UTRACE_ACTION_NOREAP flag is set
+after this callback, it remains an unreported zombie.  Otherwise, it might
+be reaped by its parent, or self-reap immediately.  Though the actual
+reaping may happen in parallel, a report_reap callback will always be
+ordered after a report_death callback.
+
+UTRACE_EVENT(SYSCALL_ENTRY)	Thread has entered kernel for a system call
+Callback:
+	u32 (*report_syscall_entry)(struct utrace_attached_engine *engine,
+				    struct task_struct *tsk,
+				    struct pt_regs *regs);
+
+The system call number and arguments can be seen and modified in the
+registers.  The return value register has -ENOSYS, which will be
+returned for an invalid system call.  The macro tracehook_abort_syscall(regs)
+will abort the system call so that we go immediately to syscall exit,
+and return -ENOSYS (or whatever the register state is changed to).  If
+tracing enginges keep the thread quiescent here, the system call will
+not be performed until it resumes.
+
+UTRACE_EVENT(SYSCALL_EXIT)	Thread is leaving kernel after a system call
+Callback:
+	u32 (*report_syscall_exit)(struct utrace_attached_engine *engine,
+				   struct task_struct *tsk,
+				   struct pt_regs *regs);
+
+The return value can be seen and modified in the registers.  If the
+thread is allowed to resume, it will see any pending signals and then
+return to user mode.
+
+UTRACE_EVENT(SIGNAL)		Signal caught by user handler
+UTRACE_EVENT(SIGNAL_IGN)		Signal with no effect (SIG_IGN or default)
+UTRACE_EVENT(SIGNAL_STOP)	Job control stop signal
+UTRACE_EVENT(SIGNAL_TERM)	Fatal termination signal
+UTRACE_EVENT(SIGNAL_CORE)	Fatal core-dump signal
+UTRACE_EVENT_SIGNAL_ALL		All of the above (bitmask)
+Callback:
+	u32 (*report_signal)(struct utrace_attached_engine *engine,
+			     struct task_struct *tsk,
+			     u32 action, siginfo_t *info,
+			     const struct k_sigaction *orig_ka,
+			     struct k_sigaction *return_ka);
+
+There are five types of signal events, but all use the same callback.
+These happen when a thread is dequeuing a signal to be delivered.
+(Not immediately when the signal is sent, and not when the signal is
+blocked.)  No signal event is reported for SIGKILL; no tracing engine
+can prevent it from killing the thread immediately.  The specific
+event types allow an engine to trace signals based on what they do.
+UTRACE_EVENT_SIGNAL_ALL is all of them OR'd together, to trace all
+signals (except SIGKILL).  A subset of these event flags can be used
+e.g. to catch only fatal signals, not handled ones, or to catch only
+core-dump signals, not normal termination signals.
+
+The action argument says what the signal's default disposition is:
+
+	UTRACE_SIGNAL_DELIVER	Run the user handler from sigaction.
+	UTRACE_SIGNAL_IGN	Do nothing, ignore the signal.
+	UTRACE_SIGNAL_TERM	Terminate the process.
+	UTRACE_SIGNAL_CORE	Terminate the process a write a core dump.
+	UTRACE_SIGNAL_STOP	Absolutely stop the process, a la SIGSTOP.
+	UTRACE_SIGNAL_TSTP	Job control stop (no stop if orphaned).
+
+This selection is made from consulting the process's sigaction and the
+default action for the signal number, but may already have been
+changed by an earlier tracing engine (in which case you see its override).
+A return value of UTRACE_ACTION_RESUME means to carry out this action.
+If instead UTRACE_SIGNAL_* bits are in the return value, that overrides
+the normal behavior of the signal.
+
+The signal number and other details of the signal are in info, and
+this data can be changed to make the thread see a different signal.
+A return value of UTRACE_SIGNAL_DELIVER says to follow the sigaction in
+return_ka, which can specify a user handler or SIG_IGN to ignore the
+signal or SIG_DFL to follow the default action for info->si_signo.
+The orig_ka parameter shows the process's sigaction at the time the
+signal was dequeued, and return_ka initially contains this.  Tracing
+engines can modify return_ka to change the effects of delivery.
+For other UTRACE_SIGNAL_* return values, return_ka is ignored.
+
+UTRACE_SIGNAL_HOLD is a flag bit that can be OR'd into the return
+value.  It says to push the signal back on the thread's queue, with
+the signal number and details possibly changed in info.  When the
+thread is allowed to resume, it will dequeue and report it again.
diff --git a/Documentation/video4linux/README.pvrusb2 b/Documentation/video4linux/README.pvrusb2
new file mode 100644
index 000000000..c73a32c34
--- /dev/null
+++ b/Documentation/video4linux/README.pvrusb2
@@ -0,0 +1,212 @@
+
+$Id$
+Mike Isely <isely@pobox.com>
+
+			    pvrusb2 driver
+
+Background:
+
+  This driver is intended for the "Hauppauge WinTV PVR USB 2.0", which
+  is a USB 2.0 hosted TV Tuner.  This driver is a work in progress.
+  Its history started with the reverse-engineering effort by Björn
+  Danielsson <pvrusb2@dax.nu> whose web page can be found here:
+
+    http://pvrusb2.dax.nu/
+
+  From there Aurelien Alleaume <slts@free.fr> began an effort to
+  create a video4linux compatible driver.  I began with Aurelien's
+  last known snapshot and evolved the driver to the state it is in
+  here.
+
+  More information on this driver can be found at:
+
+    http://www.isely.net/pvrusb2.html
+
+
+  This driver has a strong separation of layers.  They are very
+  roughly:
+
+  1a. Low level wire-protocol implementation with the device.
+
+  1b. I2C adaptor implementation and corresponding I2C client drivers
+      implemented elsewhere in V4L.
+
+  1c. High level hardware driver implementation which coordinates all
+      activities that ensure correct operation of the device.
+
+  2.  A "context" layer which manages instancing of driver, setup,
+      tear-down, arbitration, and interaction with high level
+      interfaces appropriately as devices are hotplugged in the
+      system.
+
+  3.  High level interfaces which glue the driver to various published
+      Linux APIs (V4L, sysfs, maybe DVB in the future).
+
+  The most important shearing layer is between the top 2 layers.  A
+  lot of work went into the driver to ensure that any kind of
+  conceivable API can be laid on top of the core driver.  (Yes, the
+  driver internally leverages V4L to do its work but that really has
+  nothing to do with the API published by the driver to the outside
+  world.)  The architecture allows for different APIs to
+  simultaneously access the driver.  I have a strong sense of fairness
+  about APIs and also feel that it is a good design principle to keep
+  implementation and interface isolated from each other.  Thus while
+  right now the V4L high level interface is the most complete, the
+  sysfs high level interface will work equally well for similar
+  functions, and there's no reason I see right now why it shouldn't be
+  possible to produce a DVB high level interface that can sit right
+  alongside V4L.
+
+  NOTE: Complete documentation on the pvrusb2 driver is contained in
+  the html files within the doc directory; these are exactly the same
+  as what is on the web site at the time.  Browse those files
+  (especially the FAQ) before asking questions.
+
+
+Building
+
+  To build these modules essentially amounts to just running "Make",
+  but you need the kernel source tree nearby and you will likely also
+  want to set a few controlling environment variables first in order
+  to link things up with that source tree.  Please see the Makefile
+  here for comments that explain how to do that.
+
+
+Source file list / functional overview:
+
+  (Note: The term "module" used below generally refers to loosely
+  defined functional units within the pvrusb2 driver and bears no
+  relation to the Linux kernel's concept of a loadable module.)
+
+  pvrusb2-audio.[ch] - This is glue logic that resides between this
+    driver and the msp3400.ko I2C client driver (which is found
+    elsewhere in V4L).
+
+  pvrusb2-context.[ch] - This module implements the context for an
+    instance of the driver.  Everything else eventually ties back to
+    or is otherwise instanced within the data structures implemented
+    here.  Hotplugging is ultimately coordinated here.  All high level
+    interfaces tie into the driver through this module.  This module
+    helps arbitrate each interface's access to the actual driver core,
+    and is designed to allow concurrent access through multiple
+    instances of multiple interfaces (thus you can for example change
+    the tuner's frequency through sysfs while simultaneously streaming
+    video through V4L out to an instance of mplayer).
+
+  pvrusb2-debug.h - This header defines a printk() wrapper and a mask
+    of debugging bit definitions for the various kinds of debug
+    messages that can be enabled within the driver.
+
+  pvrusb2-debugifc.[ch] - This module implements a crude command line
+    oriented debug interface into the driver.  Aside from being part
+    of the process for implementing manual firmware extraction (see
+    the pvrusb2 web site mentioned earlier), probably I'm the only one
+    who has ever used this.  It is mainly a debugging aid.
+
+  pvrusb2-eeprom.[ch] - This is glue logic that resides between this
+    driver the tveeprom.ko module, which is itself implemented
+    elsewhere in V4L.
+
+  pvrusb2-encoder.[ch] - This module implements all protocol needed to
+    interact with the Conexant mpeg2 encoder chip within the pvrusb2
+    device.  It is a crude echo of corresponding logic in ivtv,
+    however the design goals (strict isolation) and physical layer
+    (proxy through USB instead of PCI) are enough different that this
+    implementation had to be completely different.
+
+  pvrusb2-hdw-internal.h - This header defines the core data structure
+    in the driver used to track ALL internal state related to control
+    of the hardware.  Nobody outside of the core hardware-handling
+    modules should have any business using this header.  All external
+    access to the driver should be through one of the high level
+    interfaces (e.g. V4L, sysfs, etc), and in fact even those high
+    level interfaces are restricted to the API defined in
+    pvrusb2-hdw.h and NOT this header.
+
+  pvrusb2-hdw.h - This header defines the full internal API for
+    controlling the hardware.  High level interfaces (e.g. V4L, sysfs)
+    will work through here.
+
+  pvrusb2-hdw.c - This module implements all the various bits of logic
+    that handle overall control of a specific pvrusb2 device.
+    (Policy, instantiation, and arbitration of pvrusb2 devices fall
+    within the jurisdiction of pvrusb-context not here).
+
+  pvrusb2-i2c-chips-*.c - These modules implement the glue logic to
+    tie together and configure various I2C modules as they attach to
+    the I2C bus.  There are two versions of this file.  The "v4l2"
+    version is intended to be used in-tree alongside V4L, where we
+    implement just the logic that makes sense for a pure V4L
+    environment.  The "all" version is intended for use outside of
+    V4L, where we might encounter other possibly "challenging" modules
+    from ivtv or older kernel snapshots (or even the support modules
+    in the standalone snapshot).
+
+  pvrusb2-i2c-cmd-v4l1.[ch] - This module implements generic V4L1
+    compatible commands to the I2C modules.  It is here where state
+    changes inside the pvrusb2 driver are translated into V4L1
+    commands that are in turn send to the various I2C modules.
+
+  pvrusb2-i2c-cmd-v4l2.[ch] - This module implements generic V4L2
+    compatible commands to the I2C modules.  It is here where state
+    changes inside the pvrusb2 driver are translated into V4L2
+    commands that are in turn send to the various I2C modules.
+
+  pvrusb2-i2c-core.[ch] - This module provides an implementation of a
+    kernel-friendly I2C adaptor driver, through which other external
+    I2C client drivers (e.g. msp3400, tuner, lirc) may connect and
+    operate corresponding chips within the the pvrusb2 device.  It is
+    through here that other V4L modules can reach into this driver to
+    operate specific pieces (and those modules are in turn driven by
+    glue logic which is coordinated by pvrusb2-hdw, doled out by
+    pvrusb2-context, and then ultimately made available to users
+    through one of the high level interfaces).
+
+  pvrusb2-io.[ch] - This module implements a very low level ring of
+    transfer buffers, required in order to stream data from the
+    device.  This module is *very* low level.  It only operates the
+    buffers and makes no attempt to define any policy or mechanism for
+    how such buffers might be used.
+
+  pvrusb2-ioread.[ch] - This module layers on top of pvrusb2-io.[ch]
+    to provide a streaming API usable by a read() system call style of
+    I/O.  Right now this is the only layer on top of pvrusb2-io.[ch],
+    however the underlying architecture here was intended to allow for
+    other styles of I/O to be implemented with additonal modules, like
+    mmap()'ed buffers or something even more exotic.
+
+  pvrusb2-main.c - This is the top level of the driver.  Module level
+    and USB core entry points are here.  This is our "main".
+
+  pvrusb2-sysfs.[ch] - This is the high level interface which ties the
+    pvrusb2 driver into sysfs.  Through this interface you can do
+    everything with the driver except actually stream data.
+
+  pvrusb2-tuner.[ch] - This is glue logic that resides between this
+    driver and the tuner.ko I2C client driver (which is found
+    elsewhere in V4L).
+
+  pvrusb2-util.h - This header defines some common macros used
+    throughout the driver.  These macros are not really specific to
+    the driver, but they had to go somewhere.
+
+  pvrusb2-v4l2.[ch] - This is the high level interface which ties the
+    pvrusb2 driver into video4linux.  It is through here that V4L
+    applications can open and operate the driver in the usual V4L
+    ways.  Note that **ALL** V4L functionality is published only
+    through here and nowhere else.
+
+  pvrusb2-video-*.[ch] - This is glue logic that resides between this
+    driver and the saa711x.ko I2C client driver (which is found
+    elsewhere in V4L).  Note that saa711x.ko used to be known as
+    saa7115.ko in ivtv.  There are two versions of this; one is
+    selected depending on the particular saa711[5x].ko that is found.
+
+  pvrusb2.h - This header contains compile time tunable parameters
+    (and at the moment the driver has very little that needs to be
+    tuned).
+
+
+  -Mike Isely
+  isely@pobox.com
+
diff --git a/Documentation/video4linux/cx2341x/fw-calling.txt b/Documentation/video4linux/cx2341x/fw-calling.txt
new file mode 100644
index 000000000..8d21181de
--- /dev/null
+++ b/Documentation/video4linux/cx2341x/fw-calling.txt
@@ -0,0 +1,69 @@
+This page describes how to make calls to the firmware api.
+
+How to call
+===========
+
+The preferred calling convention is known as the firmware mailbox. The
+mailboxes are basically a fixed length array that serves as the call-stack.
+
+Firmware mailboxes can be located by searching the encoder and decoder memory
+for a 16 byte signature. That signature will be located on a 256-byte boundary.
+
+Signature:
+0x78, 0x56, 0x34, 0x12, 0x12, 0x78, 0x56, 0x34,
+0x34, 0x12, 0x78, 0x56, 0x56, 0x34, 0x12, 0x78
+
+The firmware implements 20 mailboxes of 20 32-bit words. The first 10 are
+reserved for API calls. The second 10 are used by the firmware for event
+notification.
+
+  Index  Name
+  -----  ----
+  0      Flags
+  1      Command
+  2      Return value
+  3      Timeout
+  4-19   Parameter/Result
+
+
+The flags are defined in the following table. The direction is from the
+perspective of the firmware.
+
+  Bit  Direction  Purpose
+  ---  ---------  -------
+  2    O          Firmware has processed the command.
+  1    I          Driver has finished setting the parameters.
+  0    I          Driver is using this mailbox.
+
+
+The command is a 32-bit enumerator. The API specifics may be found in the
+fw-*-api.txt documents.
+
+The return value is a 32-bit enumerator. Only two values are currently defined:
+0=success and -1=command undefined.
+
+There are 16 parameters/results 32-bit fields. The driver populates these fields
+with values for all the parameters required by the call. The driver overwrites
+these fields with result values returned by the call. The API specifics may be
+found in the fw-*-api.txt documents.
+
+The timeout value protects the card from a hung driver thread. If the driver
+doesn't handle the completed call within the timeout specified, the firmware
+will reset that mailbox.
+
+To make an API call, the driver iterates over each mailbox looking for the
+first one available (bit 0 has been cleared). The driver sets that bit, fills
+in the command enumerator, the timeout value and any required parameters. The
+driver then sets the parameter ready bit (bit 1). The firmware scans the
+mailboxes for pending commands, processes them, sets the result code, populates
+the result value array with that call's return values and sets the call
+complete bit (bit 2). Once bit 2 is set, the driver should retrieve the results
+and clear all the flags. If the driver does not perform this task within the
+time set in the timeout register, the firmware will reset that mailbox.
+
+Event notifications are sent from the firmware to the host. The host tells the
+firmware which events it is interested in via an API call. That call tells the
+firmware which notification mailbox to use. The firmware signals the host via
+an interrupt. Only the 16 Results fields are used, the Flags, Command, Return
+value and Timeout words are not used.
+
diff --git a/Documentation/video4linux/cx2341x/fw-decoder-api.txt b/Documentation/video4linux/cx2341x/fw-decoder-api.txt
new file mode 100644
index 000000000..9df4fb3ea
--- /dev/null
+++ b/Documentation/video4linux/cx2341x/fw-decoder-api.txt
@@ -0,0 +1,319 @@
+Decoder firmware API description
+================================
+
+Note: this API is part of the decoder firmware, so it's cx23415 only.
+
+-------------------------------------------------------------------------------
+
+Name 	CX2341X_DEC_PING_FW
+Enum 	0/0x00
+Description
+	This API call does nothing. It may be used to check if the firmware
+	is responding.
+
+-------------------------------------------------------------------------------
+
+Name 	CX2341X_DEC_START_PLAYBACK
+Enum 	1/0x01
+Description
+	Begin or resume playback.
+Param[0]
+	0 based frame number in GOP to begin playback from.
+Param[1]
+	Specifies the number of muted audio frames to play before normal
+	audio resumes.
+
+-------------------------------------------------------------------------------
+
+Name 	CX2341X_DEC_STOP_PLAYBACK
+Enum 	2/0x02
+Description
+	Ends playback and clears all decoder buffers. If PTS is not zero,
+	playback stops at specified PTS.
+Param[0]
+	Display 0=last frame, 1=black
+Param[1]
+	PTS low
+Param[2]
+	PTS high
+
+-------------------------------------------------------------------------------
+
+Name 	CX2341X_DEC_SET_PLAYBACK_SPEED
+Enum 	3/0x03
+Description
+	Playback stream at speed other than normal. There are two modes of
+	operation:
+	    Smooth: host transfers entire stream and firmware drops unused
+		    frames.
+	    Coarse: host drops frames based on indexing as required to achieve
+		    desired speed.
+Param[0]
+	Bitmap:
+	    0:7  0 normal
+		 1 fast only "1.5 times"
+		 n nX fast, 1/nX slow
+	    30   Framedrop:
+		     '0' during 1.5 times play, every other B frame is dropped
+		     '1' during 1.5 times play, stream is unchanged (bitrate
+			 must not exceed 8mbps)
+	    31   Speed:
+		     '0' slow
+		     '1' fast
+Param[1]
+	Direction: 0=forward, 1=reverse
+Param[2]
+	Picture mask:
+	    1=I frames
+	    3=I, P frames
+	    7=I, P, B frames
+Param[3]
+	B frames per GOP (for reverse play only)
+Param[4]
+	Mute audio: 0=disable, 1=enable
+Param[5]
+	Display 0=frame, 1=field
+Param[6]
+	Specifies the number of muted audio frames to play before normal audio
+	resumes.
+
+-------------------------------------------------------------------------------
+
+Name 	CX2341X_DEC_STEP_VIDEO
+Enum 	5/0x05
+Description
+	Each call to this API steps the playback to the next unit defined below
+	in the current playback direction.
+Param[0]
+	0=frame, 1=top field, 2=bottom field
+
+-------------------------------------------------------------------------------
+
+Name 	CX2341X_DEC_SET_DMA_BLOCK_SIZE
+Enum 	8/0x08
+Description
+	Set DMA transfer block size. Counterpart to API 0xC9
+Param[0]
+	DMA transfer block size in bytes. A different size may be specified
+	when issuing the DMA transfer command.
+
+-------------------------------------------------------------------------------
+
+Name 	CX2341X_DEC_GET_XFER_INFO
+Enum 	9/0x09
+Description
+	This API call may be used to detect an end of stream condtion.
+Result[0]
+	Stream type
+Result[1]
+	Address offset
+Result[2]
+	Maximum bytes to transfer
+Result[3]
+	Buffer fullness
+
+-------------------------------------------------------------------------------
+
+Name 	CX2341X_DEC_GET_DMA_STATUS
+Enum 	10/0x0A
+Description
+	Status of the last DMA transfer
+Result[0]
+	Bit 1 set means transfer complete
+	Bit 2 set means DMA error
+	Bit 3 set means linked list error
+Result[1]
+	DMA type: 0=MPEG, 1=OSD, 2=YUV
+
+-------------------------------------------------------------------------------
+
+Name 	CX2341X_DEC_SCHED_DMA_FROM_HOST
+Enum 	11/0x0B
+Description
+	Setup DMA from host operation. Counterpart to API 0xCC
+Param[0]
+	Memory address of link list
+Param[1]
+	Total # of bytes to transfer
+Param[2]
+	DMA type (0=MPEG, 1=OSD, 2=YUV)
+
+-------------------------------------------------------------------------------
+
+Name 	CX2341X_DEC_PAUSE_PLAYBACK
+Enum 	13/0x0D
+Description
+	Freeze playback immediately. In this mode, when internal buffers are
+	full, no more data will be accepted and data request IRQs will be
+	masked.
+Param[0]
+	Display: 0=last frame, 1=black
+
+-------------------------------------------------------------------------------
+
+Name 	CX2341X_DEC_HALT_FW
+Enum 	14/0x0E
+Description
+	The firmware is halted and no further API calls are serviced until
+	the firmware is uploaded again.
+
+-------------------------------------------------------------------------------
+
+Name 	CX2341X_DEC_SET_STANDARD
+Enum 	16/0x10
+Description
+	Selects display standard
+Param[0]
+	0=NTSC, 1=PAL
+
+-------------------------------------------------------------------------------
+
+Name 	CX2341X_DEC_GET_VERSION
+Enum 	17/0x11
+Description
+	Returns decoder firmware version information
+Result[0]
+	Version bitmask:
+	    Bits  0:15 build
+	    Bits 16:23 minor
+	    Bits 24:31 major
+
+-------------------------------------------------------------------------------
+
+Name 	CX2341X_DEC_SET_STREAM_INPUT
+Enum 	20/0x14
+Description
+	Select decoder stream input port
+Param[0]
+	0=memory (default), 1=streaming
+
+-------------------------------------------------------------------------------
+
+Name 	CX2341X_DEC_GET_TIMING_INFO
+Enum 	21/0x15
+Description
+	Returns timing information from start of playback
+Result[0]
+	Frame count by decode order
+Result[1]
+	Video PTS bits 0:31 by display order
+Result[2]
+	Video PTS bit 32 by display order
+Result[3]
+	SCR bits 0:31 by display order
+Result[4]
+	SCR bit 32 by display order
+
+-------------------------------------------------------------------------------
+
+Name 	CX2341X_DEC_SET_AUDIO_MODE
+Enum 	22/0x16
+Description
+	Select audio mode
+Param[0]
+	Dual mono mode action
+Param[1]
+	Stereo mode action:
+	    0=Stereo, 1=Left, 2=Right, 3=Mono, 4=Swap, -1=Unchanged
+
+-------------------------------------------------------------------------------
+
+Name 	CX2341X_DEC_SET_EVENT_NOTIFICATION
+Enum 	23/0x17
+Description
+	Setup firmware to notify the host about a particular event.
+	Counterpart to API 0xD5
+Param[0]
+	Event: 0=Audio mode change between stereo and dual channel
+Param[1]
+	Notification 0=disabled, 1=enabled
+Param[2]
+	Interrupt bit
+Param[3]
+	Mailbox slot, -1 if no mailbox required.
+
+-------------------------------------------------------------------------------
+
+Name 	CX2341X_DEC_SET_DISPLAY_BUFFERS
+Enum 	24/0x18
+Description
+	Number of display buffers. To decode all frames in reverse playback you
+	must use nine buffers.
+Param[0]
+	0=six buffers, 1=nine buffers
+
+-------------------------------------------------------------------------------
+
+Name 	CX2341X_DEC_EXTRACT_VBI
+Enum 	25/0x19
+Description
+	Extracts VBI data
+Param[0]
+	0=extract from extension & user data, 1=extract from private packets
+Result[0]
+	VBI table location
+Result[1]
+	VBI table size
+
+-------------------------------------------------------------------------------
+
+Name 	CX2341X_DEC_SET_DECODER_SOURCE
+Enum 	26/0x1A
+Description
+	Selects decoder source. Ensure that the parameters passed to this
+	API match the encoder settings.
+Param[0]
+	Mode: 0=MPEG from host, 1=YUV from encoder, 2=YUV from host
+Param[1]
+	YUV picture width
+Param[2]
+	YUV picture height
+Param[3]
+	Bitmap: see Param[0] of API 0xBD
+
+-------------------------------------------------------------------------------
+
+Name 	CX2341X_DEC_SET_AUDIO_OUTPUT
+Enum 	27/0x1B
+Description
+	Select audio output format
+Param[0]
+	Bitmask:
+	     0:1  Data size:
+		      '00' 16 bit
+		      '01' 20 bit
+		      '10' 24 bit
+	     2:7  Unused
+	     8:9  Mode:
+		      '00' 2 channels
+		      '01' 4 channels
+		      '10' 6 channels
+		      '11' 6 channels with one line data mode
+			   (for left justified MSB first mode, 20 bit only)
+	    10:11 Unused
+	    12:13 Channel format:
+		      '00' right justified MSB first mode
+		      '01' left justified MSB first mode
+		      '10' I2S mode
+	    14:15 Unused
+	    16:21 Right justify bit count
+	    22:31 Unused
+
+-------------------------------------------------------------------------------
+
+Name 	CX2341X_DEC_SET_AV_DELAY
+Enum 	28/0x1C
+Description
+	Set audio/video delay in 90Khz ticks
+Param[0]
+	0=A/V in sync, negative=audio lags, positive=video lags
+
+-------------------------------------------------------------------------------
+
+Name 	CX2341X_DEC_SET_PREBUFFERING
+Enum 	30/0x1E
+Description
+	Decoder prebuffering, when enabled up to 128KB are buffered for
+	streams <8mpbs or 640KB for streams >8mbps
+Param[0]
+	0=off, 1=on
diff --git a/Documentation/video4linux/cx2341x/fw-dma.txt b/Documentation/video4linux/cx2341x/fw-dma.txt
new file mode 100644
index 000000000..8123e262d
--- /dev/null
+++ b/Documentation/video4linux/cx2341x/fw-dma.txt
@@ -0,0 +1,94 @@
+This page describes the structures and procedures used by the cx2341x DMA
+engine.
+
+Introduction
+============
+
+The cx2341x PCI interface is busmaster capable. This means it has a DMA
+engine to efficiently transfer large volumes of data between the card and main
+memory without requiring help from a CPU. Like most hardware, it must operate
+on contiguous physical memory. This is difficult to come by in large quantities
+on virtual memory machines.
+
+Therefore, it also supports a technique called "scatter-gather". The card can
+transfer multiple buffers in one operation. Instead of allocating one large
+contiguous buffer, the driver can allocate several smaller buffers.
+
+In practice, I've seen the average transfer to be roughly 80K, but transfers
+above 128K were not uncommon, particularly at startup. The 128K figure is
+important, because that is the largest block that the kernel can normally
+allocate. Even still, 128K blocks are hard to come by, so the driver writer is
+urged to choose a smaller block size and learn the scatter-gather technique.
+
+Mailbox #10 is reserved for DMA transfer information.
+
+Flow
+====
+
+This section describes, in general, the order of events when handling DMA
+transfers. Detailed information follows this section.
+
+- The card raises the Encoder interrupt.
+- The driver reads the transfer type, offset and size from Mailbox #10.
+- The driver constructs the scatter-gather array from enough free dma buffers
+  to cover the size.
+- The driver schedules the DMA transfer via the ScheduleDMAtoHost API call.
+- The card raises the DMA Complete interrupt.
+- The driver checks the DMA status register for any errors.
+- The driver post-processes the newly transferred buffers.
+
+NOTE! It is possible that the Encoder and DMA Complete interrupts get raised
+simultaneously. (End of the last, start of the next, etc.)
+
+Mailbox #10
+===========
+
+The Flags, Command, Return Value and Timeout fields are ignored.
+
+Name:       Mailbox #10
+Results[0]: Type: 0: MPEG.
+Results[1]: Offset: The position relative to the card's memory space.
+Results[2]: Size: The exact number of bytes to transfer.
+
+My speculation is that since the StartCapture API has a capture type of "RAW"
+available, that the type field will have other values that correspond to YUV
+and PCM data.
+
+Scatter-Gather Array
+====================
+
+The scatter-gather array is a contiguously allocated block of memory that
+tells the card the source and destination of each data-block to transfer.
+Card "addresses" are derived from the offset supplied by Mailbox #10. Host
+addresses are the physical memory location of the target DMA buffer.
+
+Each S-G array element is a struct of three 32-bit words. The first word is
+the source address, the second is the destination address. Both take up the
+entire 32 bits. The lowest 16 bits of the third word is the transfer byte
+count. The high-bit of the third word is the "last" flag. The last-flag tells
+the card to raise the DMA_DONE interrupt. From hard personal experience, if
+you forget to set this bit, the card will still "work" but the stream will
+most likely get corrupted.
+
+The transfer count must be a multiple of 256. Therefore, the driver will need
+to track how much data in the target buffer is valid and deal with it
+accordingly.
+
+Array Element:
+
+- 32-bit Source Address
+- 32-bit Destination Address
+- 16-bit reserved (high bit is the last flag)
+- 16-bit byte count
+
+DMA Transfer Status
+===================
+
+Register 0x0004 holds the DMA Transfer Status:
+
+Bit
+4   Scatter-Gather array error
+3   DMA write error
+2   DMA read error
+1   write completed
+0   read completed
diff --git a/Documentation/video4linux/cx2341x/fw-encoder-api.txt b/Documentation/video4linux/cx2341x/fw-encoder-api.txt
new file mode 100644
index 000000000..001c68644
--- /dev/null
+++ b/Documentation/video4linux/cx2341x/fw-encoder-api.txt
@@ -0,0 +1,694 @@
+Encoder firmware API description
+================================
+
+-------------------------------------------------------------------------------
+
+Name 	CX2341X_ENC_PING_FW
+Enum 	128/0x80
+Description
+	Does nothing. Can be used to check if the firmware is responding.
+
+-------------------------------------------------------------------------------
+
+Name 	CX2341X_ENC_START_CAPTURE
+Enum 	129/0x81
+Description
+	Commences the capture of video, audio and/or VBI data. All encoding
+	parameters must be initialized prior to this API call. Captures frames
+	continuously or until a predefined number of frames have been captured.
+Param[0]
+	Capture stream type:
+	    0=MPEG
+	    1=Raw
+	    2=Raw passthrough
+	    3=VBI
+
+Param[1]
+	Bitmask:
+	    Bit 0 when set, captures YUV
+	    Bit 1 when set, captures PCM audio
+	    Bit 2 when set, captures VBI (same as param[0]=3)
+	    Bit 3 when set, the capture destination is the decoder
+		(same as param[0]=2)
+	    Bit 4 when set, the capture destination is the host
+	Note: this parameter is only meaningful for RAW capture type.
+
+-------------------------------------------------------------------------------
+
+Name 	CX2341X_ENC_STOP_CAPTURE
+Enum 	130/0x82
+Description
+	Ends a capture in progress
+Param[0]
+	0=stop at end of GOP (generates IRQ)
+	1=stop immediate (no IRQ)
+Param[1]
+	Stream type to stop, see param[0] of API 0x81
+Param[2]
+	Subtype, see param[1] of API 0x81
+
+-------------------------------------------------------------------------------
+
+Name 	CX2341X_ENC_SET_AUDIO_ID
+Enum 	137/0x89
+Description
+	Assigns the transport stream ID of the encoded audio stream
+Param[0]
+	Audio Stream ID
+
+-------------------------------------------------------------------------------
+
+Name 	CX2341X_ENC_SET_VIDEO_ID
+Enum 	139/0x8B
+Description
+	Set video transport stream ID
+Param[0]
+	Video stream ID
+
+-------------------------------------------------------------------------------
+
+Name 	CX2341X_ENC_SET_PCR_ID
+Enum 	141/0x8D
+Description
+	Assigns the transport stream ID for PCR packets
+Param[0]
+	PCR Stream ID
+
+-------------------------------------------------------------------------------
+
+Name 	CX2341X_ENC_SET_FRAME_RATE
+Enum 	143/0x8F
+Description
+	Set video frames per second. Change occurs at start of new GOP.
+Param[0]
+	0=30fps
+	1=25fps
+
+-------------------------------------------------------------------------------
+
+Name 	CX2341X_ENC_SET_FRAME_SIZE
+Enum 	145/0x91
+Description
+	Select video stream encoding resolution.
+Param[0]
+	Height in lines. Default 480
+Param[1]
+	Width in pixels. Default 720
+
+-------------------------------------------------------------------------------
+
+Name 	CX2341X_ENC_SET_BIT_RATE
+Enum 	149/0x95
+Description
+	Assign average video stream bitrate. Note on the last three params:
+	Param[3] and [4] seem to be always 0, param [5] doesn't seem to be used.
+Param[0]
+	0=variable bitrate, 1=constant bitrate
+Param[1]
+	bitrate in bits per second
+Param[2]
+	peak bitrate in bits per second, divided by 400
+Param[3]
+	Mux bitrate in bits per second, divided by 400. May be 0 (default).
+Param[4]
+	Rate Control VBR Padding
+Param[5]
+	VBV Buffer used by encoder
+
+-------------------------------------------------------------------------------
+
+Name 	CX2341X_ENC_SET_GOP_PROPERTIES
+Enum 	151/0x97
+Description
+	Setup the GOP structure
+Param[0]
+	GOP size (maximum is 34)
+Param[1]
+	Number of B frames between the I and P frame, plus 1.
+	For example: IBBPBBPBBPBB --> GOP size: 12, number of B frames: 2+1 = 3
+	Note that GOP size must be a multiple of (B-frames + 1).
+
+-------------------------------------------------------------------------------
+
+Name 	CX2341X_ENC_SET_ASPECT_RATIO
+Enum 	153/0x99
+Description
+	Sets the encoding aspect ratio. Changes in the aspect ratio take effect
+	at the start of the next GOP.
+Param[0]
+	'0000' forbidden
+	'0001' 1:1 square
+	'0010' 4:3
+	'0011' 16:9
+	'0100' 2.21:1
+	'0101' reserved
+	 ....
+	'1111' reserved
+
+-------------------------------------------------------------------------------
+
+Name 	CX2341X_ENC_SET_DNR_FILTER_MODE
+Enum 	155/0x9B
+Description
+	Assign Dynamic Noise Reduction operating mode
+Param[0]
+	Bit0: Spatial filter, set=auto, clear=manual
+	Bit1: Temporal filter, set=auto, clear=manual
+Param[1]
+	Median filter:
+	    0=Disabled
+	    1=Horizontal
+	    2=Vertical
+	    3=Horiz/Vert
+	    4=Diagonal
+
+-------------------------------------------------------------------------------
+
+Name 	CX2341X_ENC_SET_DNR_FILTER_PROPS
+Enum 	157/0x9D
+Description
+	These Dynamic Noise Reduction filter values are only meaningful when
+	the respective filter is set to "manual" (See API 0x9B)
+Param[0]
+	Spatial filter: default 0, range 0:15
+Param[1]
+	Temporal filter: default 0, range 0:31
+
+-------------------------------------------------------------------------------
+
+Name 	CX2341X_ENC_SET_CORING_LEVELS
+Enum 	159/0x9F
+Description
+	Assign Dynamic Noise Reduction median filter properties.
+Param[0]
+	Threshold above which the luminance median filter is enabled.
+	Default: 0, range 0:255
+Param[1]
+	Threshold below which the luminance median filter is enabled.
+	Default: 255, range 0:255
+Param[2]
+	Threshold above which the chrominance median filter is enabled.
+	Default: 0, range 0:255
+Param[3]
+	Threshold below which the chrominance median filter is enabled.
+	Default: 255, range 0:255
+
+-------------------------------------------------------------------------------
+
+Name 	CX2341X_ENC_SET_SPATIAL_FILTER_TYPE
+Enum 	161/0xA1
+Description
+	Assign spatial prefilter parameters
+Param[0]
+	Luminance filter
+	    0=Off
+	    1=1D Horizontal
+	    2=1D Vertical
+	    3=2D H/V Separable (default)
+	    4=2D Symmetric non-separable
+Param[1]
+	Chrominance filter
+	    0=Off
+	    1=1D Horizontal (default)
+
+-------------------------------------------------------------------------------
+
+Name 	CX2341X_ENC_SET_3_2_PULLDOWN
+Enum 	177/0xB1
+Description
+	3:2 pulldown properties
+Param[0]
+	0=enabled
+	1=disabled
+
+-------------------------------------------------------------------------------
+
+Name 	CX2341X_ENC_SET_VBI_LINE
+Enum 	183/0xB7
+Description
+	Selects VBI line number.
+Param[0]
+	Bits 0:4 	line number
+	Bit  31		0=top_field, 1=bottom_field
+	Bits 0:31 	all set specifies "all lines"
+Param[1]
+	VBI line information features: 0=disabled, 1=enabled
+Param[2]
+	Slicing: 0=None, 1=Closed Caption
+	Almost certainly not implemented. Set to 0.
+Param[3]
+	Luminance samples in this line.
+	Almost certainly not implemented. Set to 0.
+Param[4]
+	Chrominance samples in this line
+	Almost certainly not implemented. Set to 0.
+
+-------------------------------------------------------------------------------
+
+Name 	CX2341X_ENC_SET_STREAM_TYPE
+Enum 	185/0xB9
+Description
+	Assign stream type
+	Note: Transport stream is not working in recent firmwares.
+	And in older firmwares the timestamps in the TS seem to be
+	unreliable.
+Param[0]
+	 0=Program stream
+	 1=Transport stream
+	 2=MPEG1 stream
+	 3=PES A/V stream
+	 5=PES Video stream
+	 7=PES Audio stream
+	10=DVD stream
+	11=VCD stream
+	12=SVCD stream
+	13=DVD_S1 stream
+	14=DVD_S2 stream
+
+-------------------------------------------------------------------------------
+
+Name 	CX2341X_ENC_SET_OUTPUT_PORT
+Enum 	187/0xBB
+Description
+	Assign stream output port. Normally 0 when the data is copied through
+	the PCI bus (DMA), and 1 when the data is streamed to another chip
+	(pvrusb and cx88-blackbird).
+Param[0]
+	0=Memory (default)
+	1=Streaming
+	2=Serial
+Param[1]
+	Unknown, but leaving this to 0 seems to work best. Indications are that
+	this might have to do with USB support, although passing anything but 0
+	onl breaks things.
+
+-------------------------------------------------------------------------------
+
+Name 	CX2341X_ENC_SET_AUDIO_PROPERTIES
+Enum 	189/0xBD
+Description
+	Set audio stream properties, may be called while encoding is in progress.
+	Note: all bitfields are consistent with ISO11172 documentation except
+	bits 2:3 which ISO docs define as:
+		'11' Layer I
+		'10' Layer II
+		'01' Layer III
+		'00' Undefined
+	This discrepancy may indicate a possible error in the documentation.
+	Testing indicated that only Layer II is actually working, and that
+	the minimum bitrate should be 192 kbps.
+Param[0]
+	Bitmask:
+	   0:1  '00' 44.1Khz
+		'01' 48Khz
+		'10' 32Khz
+		'11' reserved
+
+	   2:3  '01'=Layer I
+		'10'=Layer II
+
+	   4:7  Bitrate:
+		     Index | Layer I     | Layer II
+		     ------+-------------+------------
+		    '0000' | free format | free format
+		    '0001' |  32 kbit/s  |  32 kbit/s
+		    '0010' |  64 kbit/s  |  48 kbit/s
+		    '0011' |  96 kbit/s  |  56 kbit/s
+		    '0100' | 128 kbit/s  |  64 kbit/s
+		    '0101' | 160 kbit/s  |  80 kbit/s
+		    '0110' | 192 kbit/s  |  96 kbit/s
+		    '0111' | 224 kbit/s  | 112 kbit/s
+		    '1000' | 256 kbit/s  | 128 kbit/s
+		    '1001' | 288 kbit/s  | 160 kbit/s
+		    '1010' | 320 kbit/s  | 192 kbit/s
+		    '1011' | 352 kbit/s  | 224 kbit/s
+		    '1100' | 384 kbit/s  | 256 kbit/s
+		    '1101' | 416 kbit/s  | 320 kbit/s
+		    '1110' | 448 kbit/s  | 384 kbit/s
+		Note: For Layer II, not all combinations of total bitrate
+		and mode are allowed. See ISO11172-3 3-Annex B, Table 3-B.2
+
+	   8:9  '00'=Stereo
+		'01'=JointStereo
+		'10'=Dual
+		'11'=Mono
+		Note: testing seems to indicate that Mono and possibly
+		JointStereo are not working (default to stereo).
+		Dual does work, though.
+
+	  10:11 Mode Extension used in joint_stereo mode.
+		In Layer I and II they indicate which subbands are in
+		intensity_stereo. All other subbands are coded in stereo.
+		    '00' subbands 4-31 in intensity_stereo, bound==4
+		    '01' subbands 8-31 in intensity_stereo, bound==8
+		    '10' subbands 12-31 in intensity_stereo, bound==12
+		    '11' subbands 16-31 in intensity_stereo, bound==16
+
+	  12:13 Emphasis:
+		    '00' None
+		    '01' 50/15uS
+		    '10' reserved
+		    '11' CCITT J.17
+
+	  14 	CRC:
+		    '0' off
+		    '1' on
+
+	  15    Copyright:
+		    '0' off
+		    '1' on
+
+	  16    Generation:
+		    '0' copy
+		    '1' original
+
+-------------------------------------------------------------------------------
+
+Name 	CX2341X_ENC_HALT_FW
+Enum 	195/0xC3
+Description
+	The firmware is halted and no further API calls are serviced until the
+	firmware is uploaded again.
+
+-------------------------------------------------------------------------------
+
+Name 	CX2341X_ENC_GET_VERSION
+Enum 	196/0xC4
+Description
+	Returns the version of the encoder firmware.
+Result[0]
+	Version bitmask:
+	    Bits  0:15 build
+	    Bits 16:23 minor
+	    Bits 24:31 major
+
+-------------------------------------------------------------------------------
+
+Name 	CX2341X_ENC_SET_GOP_CLOSURE
+Enum 	197/0xC5
+Description
+	Assigns the GOP open/close property.
+Param[0]
+	0=Open
+	1=Closed
+
+-------------------------------------------------------------------------------
+
+Name 	CX2341X_ENC_GET_SEQ_END
+Enum 	198/0xC6
+Description
+	Obtains the sequence end code of the encoder's buffer. When a capture
+	is started a number of interrupts are still generated, the last of
+	which will have Result[0] set to 1 and Result[1] will contain the size
+	of the buffer.
+Result[0]
+	State of the transfer (1 if last buffer)
+Result[1]
+	If Result[0] is 1, this contains the size of the last buffer, undefined
+	otherwise.
+
+-------------------------------------------------------------------------------
+
+Name 	CX2341X_ENC_SET_PGM_INDEX_INFO
+Enum 	199/0xC7
+Description
+	Sets the Program Index Information.
+Param[0]
+	Picture Mask:
+	    0=No index capture
+	    1=I frames
+	    3=I,P frames
+	    7=I,P,B frames
+Param[1]
+	Elements requested (up to 400)
+Result[0]
+	Offset in SDF memory of the table.
+Result[1]
+	Number of allocated elements up to a maximum of Param[1]
+
+-------------------------------------------------------------------------------
+
+Name 	CX2341X_ENC_SET_VBI_CONFIG
+Enum 	200/0xC8
+Description
+	Configure VBI settings
+Param[0]
+	Bitmap:
+	    0    Mode '0' Sliced, '1' Raw
+	    1:3  Insertion:
+		     '000' insert in extension & user data
+		     '001' insert in private packets
+		     '010' separate stream and user data
+		     '111' separate stream and private data
+	    8:15 Stream ID (normally 0xBD)
+Param[1]
+	Frames per interrupt (max 8). Only valid in raw mode.
+Param[2]
+	Total raw VBI frames. Only valid in raw mode.
+Param[3]
+	Start codes
+Param[4]
+	Stop codes
+Param[5]
+	Lines per frame
+Param[6]
+	Byte per line
+Result[0]
+	Observed frames per interrupt in raw mode only. Rage 1 to Param[1]
+Result[1]
+	Observed number of frames in raw mode. Range 1 to Param[2]
+Result[2]
+	Memory offset to start or raw VBI data
+
+-------------------------------------------------------------------------------
+
+Name 	CX2341X_ENC_SET_DMA_BLOCK_SIZE
+Enum 	201/0xC9
+Description
+	Set DMA transfer block size
+Param[0]
+	DMA transfer block size in bytes or frames. When unit is bytes,
+	supported block sizes are 2^7, 2^8 and 2^9 bytes.
+Param[1]
+	Unit: 0=bytes, 1=frames
+
+-------------------------------------------------------------------------------
+
+Name 	CX2341X_ENC_GET_PREV_DMA_INFO_MB_10
+Enum 	202/0xCA
+Description
+	Returns information on the previous DMA transfer in conjunction with
+	bit 27 of the interrupt mask. Uses mailbox 10.
+Result[0]
+	Type of stream
+Result[1]
+	Address Offset
+Result[2]
+	Maximum size of transfer
+
+-------------------------------------------------------------------------------
+
+Name 	CX2341X_ENC_GET_PREV_DMA_INFO_MB_9
+Enum 	203/0xCB
+Description
+	Returns information on the previous DMA transfer in conjunction with
+	bit 27 of the interrupt mask. Uses mailbox 9.
+Result[0]
+	Status bits:
+	    Bit 0 set indicates transfer complete
+	    Bit 2 set indicates transfer error
+	    Bit 4 set indicates linked list error
+Result[1]
+	DMA type
+Result[2]
+	Presentation Time Stamp bits 0..31
+Result[3]
+	Presentation Time Stamp bit 32
+
+-------------------------------------------------------------------------------
+
+Name 	CX2341X_ENC_SCHED_DMA_TO_HOST
+Enum 	204/0xCC
+Description
+	Setup DMA to host operation
+Param[0]
+	Memory address of link list
+Param[1]
+	Length of link list (wtf: what units ???)
+Param[2]
+	DMA type (0=MPEG)
+
+-------------------------------------------------------------------------------
+
+Name 	CX2341X_ENC_INITIALIZE_INPUT
+Enum 	205/0xCD
+Description
+	Initializes the video input
+
+-------------------------------------------------------------------------------
+
+Name 	CX2341X_ENC_SET_FRAME_DROP_RATE
+Enum 	208/0xD0
+Description
+	For each frame captured, skip specified number of frames.
+Param[0]
+	Number of frames to skip
+
+-------------------------------------------------------------------------------
+
+Name 	CX2341X_ENC_PAUSE_ENCODER
+Enum 	210/0xD2
+Description
+	During a pause condition, all frames are dropped instead of being encoded.
+Param[0]
+	0=Pause encoding
+	1=Continue encoding
+
+-------------------------------------------------------------------------------
+
+Name 	CX2341X_ENC_REFRESH_INPUT
+Enum 	211/0xD3
+Description
+	Refreshes the video input
+
+-------------------------------------------------------------------------------
+
+Name 	CX2341X_ENC_SET_COPYRIGHT
+Enum 	212/0xD4
+Description
+	Sets stream copyright property
+Param[0]
+	0=Stream is not copyrighted
+	1=Stream is copyrighted
+
+-------------------------------------------------------------------------------
+
+Name 	CX2341X_ENC_SET_EVENT_NOTIFICATION
+Enum 	213/0xD5
+Description
+	Setup firmware to notify the host about a particular event. Host must
+	unmask the interrupt bit.
+Param[0]
+	Event (0=refresh encoder input)
+Param[1]
+	Notification 0=disabled 1=enabled
+Param[2]
+	Interrupt bit
+Param[3]
+	Mailbox slot, -1 if no mailbox required.
+
+-------------------------------------------------------------------------------
+
+Name 	CX2341X_ENC_SET_NUM_VSYNC_LINES
+Enum 	214/0xD6
+Description
+	Depending on the analog video decoder used, this assigns the number
+	of lines for field 1 and 2.
+Param[0]
+	Field 1 number of lines:
+	    0x00EF for SAA7114
+	    0x00F0 for SAA7115
+	    0x0105 for Micronas
+Param[1]
+	Field 2 number of lines:
+	    0x00EF for SAA7114
+	    0x00F0 for SAA7115
+	    0x0106 for Micronas
+
+-------------------------------------------------------------------------------
+
+Name 	CX2341X_ENC_SET_PLACEHOLDER
+Enum 	215/0xD7
+Description
+	Provides a mechanism of inserting custom user data in the MPEG stream.
+Param[0]
+	0=extension & user data
+	1=private packet with stream ID 0xBD
+Param[1]
+	Rate at which to insert data, in units of frames (for private packet)
+	or GOPs (for ext. & user data)
+Param[2]
+	Number of data DWORDs (below) to insert
+Param[3]
+	Custom data 0
+Param[4]
+	Custom data 1
+Param[5]
+	Custom data 2
+Param[6]
+	Custom data 3
+Param[7]
+	Custom data 4
+Param[8]
+	Custom data 5
+Param[9]
+	Custom data 6
+Param[10]
+	Custom data 7
+Param[11]
+	Custom data 8
+
+-------------------------------------------------------------------------------
+
+Name 	CX2341X_ENC_MUTE_VIDEO
+Enum 	217/0xD9
+Description
+	Video muting
+Param[0]
+	Bit usage:
+	 0    	'0'=video not muted
+		'1'=video muted, creates frames with the YUV color defined below
+	 1:7  	Unused
+	 8:15 	V chrominance information
+	16:23 	U chrominance information
+	24:31 	Y luminance information
+
+-------------------------------------------------------------------------------
+
+Name 	CX2341X_ENC_MUTE_AUDIO
+Enum 	218/0xDA
+Description
+	Audio muting
+Param[0]
+	0=audio not muted
+	1=audio muted (produces silent mpeg audio stream)
+
+-------------------------------------------------------------------------------
+
+Name 	CX2341X_ENC_UNKNOWN
+Enum 	219/0xDB
+Description
+	Unknown API, it's used by Hauppauge though.
+Param[0]
+	0 This is the value Hauppauge uses, Unknown what it means.
+
+-------------------------------------------------------------------------------
+
+Name 	CX2341X_ENC_MISC
+Enum 	220/0xDC
+Description
+	Miscellaneous actions. Not known for 100% what it does. It's really a
+	sort of ioctl call. The first parameter is a command number, the second
+	the value.
+Param[0]
+	Command number:
+	 1=set initial SCR value when starting encoding.
+	 2=set quality mode (apparently some test setting).
+	 3=setup advanced VIM protection handling (supposedly only for the cx23416
+	   for raw YUV).
+	   Actually it looks like this should be 0 for saa7114/5 based card and 1
+	   for cx25840 based cards.
+	 4=generate artificial PTS timestamps
+	 5=USB flush mode
+	 6=something to do with the quantization matrix
+	 7=set navigation pack insertion for DVD
+	 8=enable scene change detection (seems to be a failure)
+	 9=set history parameters of the video input module
+	10=set input field order of VIM
+	11=set quantization matrix
+	12=reset audio interface
+	13=set audio volume delay
+	14=set audio delay
+
+Param[1]
+	Command value.
diff --git a/Documentation/video4linux/cx2341x/fw-memory.txt b/Documentation/video4linux/cx2341x/fw-memory.txt
new file mode 100644
index 000000000..ef0aad3f8
--- /dev/null
+++ b/Documentation/video4linux/cx2341x/fw-memory.txt
@@ -0,0 +1,141 @@
+This document describes the cx2341x memory map and documents some of the register
+space.
+
+Warning! This information was figured out from searching through the memory and
+registers, this information may not be correct and is certainly not complete, and
+was not derived from anything more than searching through the memory space with
+commands like:
+
+	ivtvctl -O min=0x02000000,max=0x020000ff
+
+So take this as is, I'm always searching for more stuff, it's a large
+register space :-).
+
+Memory Map
+==========
+
+The cx2341x exposes its entire 64M memory space to the PCI host via the PCI BAR0
+(Base Address Register 0). The addresses here are offsets relative to the
+address held in BAR0.
+
+0x00000000-0x00ffffff Encoder memory space
+0x00000000-0x0003ffff Encode.rom
+      ???-???         MPEG buffer(s)
+      ???-???         Raw video capture buffer(s)
+      ???-???         Raw audio capture buffer(s)
+      ???-???         Display buffers (6 or 9)
+
+0x01000000-0x01ffffff Decoder memory space
+0x01000000-0x0103ffff Decode.rom
+      ???-???         MPEG buffers(s)
+0x0114b000-0x0115afff Audio.rom (deprecated?)
+
+0x02000000-0x0200ffff Register Space
+
+Registers
+=========
+
+The registers occupy the 64k space starting at the 0x02000000 offset from BAR0.
+All of these registers are 32 bits wide.
+
+DMA Registers 0x000-0xff:
+
+ 0x00 - Control:
+	0=reset/cancel, 1=read, 2=write, 4=stop
+ 0x04 - DMA status:
+	1=read busy, 2=write busy, 4=read error, 8=write error, 16=link list error
+ 0x08 - pci DMA pointer for read link list
+ 0x0c - pci DMA pointer for write link list
+ 0x10 - read/write DMA enable:
+	1=read enable, 2=write enable
+ 0x14 - always 0xffffffff, if set any lower instability occurs, 0x00 crashes
+ 0x18 - ??
+ 0x1c - always 0x20 or 32, smaller values slow down DMA transactions
+ 0x20 - always value of 0x780a010a
+ 0x24-0x3c - usually just random values???
+ 0x40 - Interrupt status
+ 0x44 - Write a bit here and shows up in Interrupt status 0x40
+ 0x48 - Interrupt Mask
+ 0x4C - always value of 0xfffdffff,
+	if changed to 0xffffffff DMA write interrupts break.
+ 0x50 - always 0xffffffff
+ 0x54 - always 0xffffffff (0x4c, 0x50, 0x54 seem like interrupt masks, are
+	3 processors on chip, Java ones, VPU, SPU, APU, maybe these are the
+	interrupt masks???).
+ 0x60-0x7C - random values
+ 0x80 - first write linked list reg, for Encoder Memory addr
+ 0x84 - first write linked list reg, for pci memory addr
+ 0x88 - first write linked list reg, for length of buffer in memory addr
+	(|0x80000000 or this for last link)
+ 0x8c-0xcc - rest of write linked list reg, 8 sets of 3 total, DMA goes here
+	from linked list addr in reg 0x0c, firmware must push through or
+	something.
+ 0xe0 - first (and only) read linked list reg, for pci memory addr
+ 0xe4 - first (and only) read linked list reg, for Decoder memory addr
+ 0xe8 - first (and only) read linked list reg, for length of buffer
+ 0xec-0xff - Nothing seems to be in these registers, 0xec-f4 are 0x00000000.
+
+Memory locations for Encoder Buffers 0x700-0x7ff:
+
+These registers show offsets of memory locations pertaining to each
+buffer area used for encoding, have to shift them by <<1 first.
+
+0x07F8: Encoder SDRAM refresh
+0x07FC: Encoder SDRAM pre-charge
+
+Memory locations for Decoder Buffers 0x800-0x8ff:
+
+These registers show offsets of memory locations pertaining to each
+buffer area used for decoding, have to shift them by <<1 first.
+
+0x08F8: Decoder SDRAM refresh
+0x08FC: Decoder SDRAM pre-charge
+
+Other memory locations:
+
+0x2800: Video Display Module control
+0x2D00: AO (audio output?) control
+0x2D24: Bytes Flushed
+0x7000: LSB I2C write clock bit (inverted)
+0x7004: LSB I2C write data bit (inverted)
+0x7008: LSB I2C read clock bit
+0x700c: LSB I2C read data bit
+0x9008: GPIO get input state
+0x900c: GPIO set output state
+0x9020: GPIO direction (Bit7 (GPIO 0..7) - 0:input, 1:output)
+0x9050: SPU control
+0x9054: Reset HW blocks
+0x9058: VPU control
+0xA018: Bit6: interrupt pending?
+0xA064: APU command
+
+
+Interrupt Status Register
+=========================
+
+The definition of the bits in the interrupt status register 0x0040, and the
+interrupt mask 0x0048. If a bit is cleared in the mask, then we want our ISR to
+execute.
+
+Bit
+31 Encoder Start Capture
+30 Encoder EOS
+29 Encoder VBI capture
+28 Encoder Video Input Module reset event
+27 Encoder DMA complete
+26
+25 Decoder copy protect detection event
+24 Decoder audio mode change detection event
+23
+22 Decoder data request
+21 Decoder I-Frame? done
+20 Decoder DMA complete
+19 Decoder VBI re-insertion
+18 Decoder DMA err (linked-list bad)
+
+Missing
+Encoder API call completed
+Decoder API call completed
+Encoder API post(?)
+Decoder API post(?)
+Decoder VTRACE event
diff --git a/Documentation/video4linux/cx2341x/fw-osd-api.txt b/Documentation/video4linux/cx2341x/fw-osd-api.txt
new file mode 100644
index 000000000..da98ae30a
--- /dev/null
+++ b/Documentation/video4linux/cx2341x/fw-osd-api.txt
@@ -0,0 +1,342 @@
+OSD firmware API description
+============================
+
+Note: this API is part of the decoder firmware, so it's cx23415 only.
+
+-------------------------------------------------------------------------------
+
+Name 	CX2341X_OSD_GET_FRAMEBUFFER
+Enum 	65/0x41
+Description
+	Return base and length of contiguous OSD memory.
+Result[0]
+	OSD base address
+Result[1]
+	OSD length
+
+-------------------------------------------------------------------------------
+
+Name 	CX2341X_OSD_GET_PIXEL_FORMAT
+Enum 	66/0x42
+Description
+	Query OSD format
+Result[0]
+	0=8bit index, 4=AlphaRGB 8:8:8:8
+
+-------------------------------------------------------------------------------
+
+Name 	CX2341X_OSD_SET_PIXEL_FORMAT
+Enum 	67/0x43
+Description
+	Assign pixel format
+Param[0]
+	0=8bit index, 4=AlphaRGB 8:8:8:8
+
+-------------------------------------------------------------------------------
+
+Name 	CX2341X_OSD_GET_STATE
+Enum 	68/0x44
+Description
+	Query OSD state
+Result[0]
+	Bit  0   0=off, 1=on
+	Bits 1:2 alpha control
+	Bits 3:5 pixel format
+
+-------------------------------------------------------------------------------
+
+Name 	CX2341X_OSD_SET_STATE
+Enum 	69/0x45
+Description
+	OSD switch
+Param[0]
+	0=off, 1=on
+
+-------------------------------------------------------------------------------
+
+Name 	CX2341X_OSD_GET_OSD_COORDS
+Enum 	70/0x46
+Description
+	Retrieve coordinates of OSD area blended with video
+Result[0]
+	OSD buffer address
+Result[1]
+	Stride in pixels
+Result[2]
+	Lines in OSD buffer
+Result[3]
+	Horizontal offset in buffer
+Result[4]
+	Vertical offset in buffer
+
+-------------------------------------------------------------------------------
+
+Name 	CX2341X_OSD_SET_OSD_COORDS
+Enum 	71/0x47
+Description
+	Assign the coordinates of the OSD area to blend with video
+Param[0]
+	buffer address
+Param[1]
+	buffer stride in pixels
+Param[2]
+	lines in buffer
+Param[3]
+	horizontal offset
+Param[4]
+	vertical offset
+
+-------------------------------------------------------------------------------
+
+Name 	CX2341X_OSD_GET_SCREEN_COORDS
+Enum 	72/0x48
+Description
+	Retrieve OSD screen area coordinates
+Result[0]
+	top left horizontal offset
+Result[1]
+	top left vertical offset
+Result[2]
+	bottom right hotizontal offset
+Result[3]
+	bottom right vertical offset
+
+-------------------------------------------------------------------------------
+
+Name 	CX2341X_OSD_SET_SCREEN_COORDS
+Enum 	73/0x49
+Description
+	Assign the coordinates of the screen area to blend with video
+Param[0]
+	top left horizontal offset
+Param[1]
+	top left vertical offset
+Param[2]
+	bottom left horizontal offset
+Param[3]
+	bottom left vertical offset
+
+-------------------------------------------------------------------------------
+
+Name 	CX2341X_OSD_GET_GLOBAL_ALPHA
+Enum 	74/0x4A
+Description
+	Retrieve OSD global alpha
+Result[0]
+	global alpha: 0=off, 1=on
+Result[1]
+	bits 0:7 global alpha
+
+-------------------------------------------------------------------------------
+
+Name 	CX2341X_OSD_SET_GLOBAL_ALPHA
+Enum 	75/0x4B
+Description
+	Update global alpha
+Param[0]
+	global alpha: 0=off, 1=on
+Param[1]
+	global alpha (8 bits)
+Param[2]
+	local alpha: 0=on, 1=off
+
+-------------------------------------------------------------------------------
+
+Name 	CX2341X_OSD_SET_BLEND_COORDS
+Enum 	78/0x4C
+Description
+	Move start of blending area within display buffer
+Param[0]
+	horizontal offset in buffer
+Param[1]
+	vertical offset in buffer
+
+-------------------------------------------------------------------------------
+
+Name 	CX2341X_OSD_GET_FLICKER_STATE
+Enum 	79/0x4F
+Description
+	Retrieve flicker reduction module state
+Result[0]
+	flicker state: 0=off, 1=on
+
+-------------------------------------------------------------------------------
+
+Name 	CX2341X_OSD_SET_FLICKER_STATE
+Enum 	80/0x50
+Description
+	Set flicker reduction module state
+Param[0]
+	State: 0=off, 1=on
+
+-------------------------------------------------------------------------------
+
+Name 	CX2341X_OSD_BLT_COPY
+Enum 	82/0x52
+Description
+	BLT copy
+Param[0]
+'0000'  zero
+'0001' ~destination AND ~source
+'0010' ~destination AND  source
+'0011' ~destination
+'0100'  destination AND ~source
+'0101'                  ~source
+'0110'  destination XOR  source
+'0111' ~destination OR  ~source
+'1000' ~destination AND ~source
+'1001'  destination XNOR source
+'1010'                   source
+'1011' ~destination OR   source
+'1100'  destination
+'1101'  destination OR  ~source
+'1110'  destination OR   source
+'1111'  one
+
+Param[1]
+	Resulting alpha blending
+	    '01' source_alpha
+	    '10' destination_alpha
+	    '11' source_alpha*destination_alpha+1
+		 (zero if both source and destination alpha are zero)
+Param[2]
+	'00' output_pixel = source_pixel
+
+	'01' if source_alpha=0:
+		 output_pixel = destination_pixel
+	     if 256 > source_alpha > 1:
+		 output_pixel = ((source_alpha + 1)*source_pixel +
+				 (255 - source_alpha)*destination_pixel)/256
+
+	'10' if destination_alpha=0:
+		 output_pixel = source_pixel
+	      if 255 > destination_alpha > 0:
+		 output_pixel = ((255 - destination_alpha)*source_pixel +
+				 (destination_alpha + 1)*destination_pixel)/256
+
+	'11' if source_alpha=0:
+		 source_temp = 0
+	     if source_alpha=255:
+		 source_temp = source_pixel*256
+	     if 255 > source_alpha > 0:
+		 source_temp = source_pixel*(source_alpha + 1)
+	     if destination_alpha=0:
+		 destination_temp = 0
+	     if destination_alpha=255:
+		 destination_temp = destination_pixel*256
+	     if 255 > destination_alpha > 0:
+		 destination_temp = destination_pixel*(destination_alpha + 1)
+	     output_pixel = (source_temp + destination_temp)/256
+Param[3]
+	width
+Param[4]
+	height
+Param[5]
+	destination pixel mask
+Param[6]
+	destination rectangle start address
+Param[7]
+	destination stride in dwords
+Param[8]
+	source stride in dwords
+Param[9]
+	source rectangle start address
+
+-------------------------------------------------------------------------------
+
+Name 	CX2341X_OSD_BLT_FILL
+Enum 	83/0x53
+Description
+	BLT fill color
+Param[0]
+	Same as Param[0] on API 0x52
+Param[1]
+	Same as Param[1] on API 0x52
+Param[2]
+	Same as Param[2] on API 0x52
+Param[3]
+	width
+Param[4]
+	height
+Param[5]
+	destination pixel mask
+Param[6]
+	destination rectangle start address
+Param[7]
+	destination stride in dwords
+Param[8]
+	color fill value
+
+-------------------------------------------------------------------------------
+
+Name 	CX2341X_OSD_BLT_TEXT
+Enum 	84/0x54
+Description
+	BLT for 8 bit alpha text source
+Param[0]
+	Same as Param[0] on API 0x52
+Param[1]
+	Same as Param[1] on API 0x52
+Param[2]
+	Same as Param[2] on API 0x52
+Param[3]
+	width
+Param[4]
+	height
+Param[5]
+	destination pixel mask
+Param[6]
+	destination rectangle start address
+Param[7]
+	destination stride in dwords
+Param[8]
+	source stride in dwords
+Param[9]
+	source rectangle start address
+Param[10]
+	color fill value
+
+-------------------------------------------------------------------------------
+
+Name 	CX2341X_OSD_SET_FRAMEBUFFER_WINDOW
+Enum 	86/0x56
+Description
+	Positions the main output window on the screen. The coordinates must be
+	such that the entire window fits on the screen.
+Param[0]
+	window width
+Param[1]
+	window height
+Param[2]
+	top left window corner horizontal offset
+Param[3]
+	top left window corner vertical offset
+
+-------------------------------------------------------------------------------
+
+Name 	CX2341X_OSD_SET_CHROMA_KEY
+Enum 	96/0x60
+Description
+	Chroma key switch and color
+Param[0]
+	state: 0=off, 1=on
+Param[1]
+	color
+
+-------------------------------------------------------------------------------
+
+Name 	CX2341X_OSD_GET_ALPHA_CONTENT_INDEX
+Enum 	97/0x61
+Description
+	Retrieve alpha content index
+Result[0]
+	alpha content index, Range 0:15
+
+-------------------------------------------------------------------------------
+
+Name 	CX2341X_OSD_SET_ALPHA_CONTENT_INDEX
+Enum 	98/0x62
+Description
+	Assign alpha content index
+Param[0]
+	alpha content index, range 0:15
diff --git a/Documentation/video4linux/cx2341x/fw-upload.txt b/Documentation/video4linux/cx2341x/fw-upload.txt
new file mode 100644
index 000000000..60c502ce3
--- /dev/null
+++ b/Documentation/video4linux/cx2341x/fw-upload.txt
@@ -0,0 +1,49 @@
+This document describes how to upload the cx2341x firmware to the card.
+
+How to find
+===========
+
+See the web pages of the various projects that uses this chip for information
+on how to obtain the firmware.
+
+The firmware stored in a Windows driver can be detected as follows:
+
+- Each firmware image is 256k bytes.
+- The 1st 32-bit word of the Encoder image is 0x0000da7
+- The 1st 32-bit word of the Decoder image is 0x00003a7
+- The 2nd 32-bit word of both images is 0xaa55bb66
+
+How to load
+===========
+
+- Issue the FWapi command to stop the encoder if it is running. Wait for the
+  command to complete.
+- Issue the FWapi command to stop the decoder if it is running. Wait for the
+  command to complete.
+- Issue the I2C command to the digitizer to stop emitting VSYNC events.
+- Issue the FWapi command to halt the encoder's firmware.
+- Sleep for 10ms.
+- Issue the FWapi command to halt the decoder's firmware.
+- Sleep for 10ms.
+- Write 0x00000000 to register 0x2800 to stop the Video Display Module.
+- Write 0x00000005 to register 0x2D00 to stop the AO (audio output?).
+- Write 0x00000000 to register 0xA064 to ping? the APU.
+- Write 0xFFFFFFFE to register 0x9058 to stop the VPU.
+- Write 0xFFFFFFFF to register 0x9054 to reset the HW blocks.
+- Write 0x00000001 to register 0x9050 to stop the SPU.
+- Sleep for 10ms.
+- Write 0x0000001A to register 0x07FC to init the Encoder SDRAM's pre-charge.
+- Write 0x80000640 to register 0x07F8 to init the Encoder SDRAM's refresh to 1us.
+- Write 0x0000001A to register 0x08FC to init the Decoder SDRAM's pre-charge.
+- Write 0x80000640 to register 0x08F8 to init the Decoder SDRAM's refresh to 1us.
+- Sleep for 512ms. (600ms is recommended)
+- Transfer the encoder's firmware image to offset 0 in Encoder memory space.
+- Transfer the decoder's firmware image to offset 0 in Decoder memory space.
+- Use a read-modify-write operation to Clear bit 0 of register 0x9050 to
+  re-enable the SPU.
+- Sleep for 1 second.
+- Use a read-modify-write operation to Clear bits 3 and 0 of register 0x9058
+  to re-enable the VPU.
+- Sleep for 1 second.
+- Issue status API commands to both firmware images to verify.
+
diff --git a/Documentation/video4linux/cx88/hauppauge-wintv-cx88-ir.txt b/Documentation/video4linux/cx88/hauppauge-wintv-cx88-ir.txt
new file mode 100644
index 000000000..93fec32a1
--- /dev/null
+++ b/Documentation/video4linux/cx88/hauppauge-wintv-cx88-ir.txt
@@ -0,0 +1,54 @@
+The controls for the mux are GPIO [0,1] for source, and GPIO 2 for muting.
+
+GPIO0  GPIO1
+  0        0    TV Audio
+  1        0    FM radio
+  0        1    Line-In
+  1        1    Mono tuner bypass or CD passthru (tuner specific)
+
+GPIO 16(i believe) is tied to the IR port (if present).
+
+------------------------------------------------------------------------------------
+
+>From the data sheet:
+ Register 24'h20004  PCI Interrupt Status
+  bit [18]  IR_SMP_INT Set when 32 input samples have been collected over
+  gpio[16] pin into GP_SAMPLE register.
+
+What's missing from the data sheet:
+
+Setup 4KHz sampling rate (roughly 2x oversampled; good enough for our RC5
+compat remote)
+set register 0x35C050 to  0xa80a80
+
+enable sampling
+set register 0x35C054 to 0x5
+
+Of course, enable the IRQ bit 18 in the interrupt mask register .(and
+provide for a handler)
+
+GP_SAMPLE register is at 0x35C058
+
+Bits are then right shifted into the GP_SAMPLE register at the specified
+rate; you get an interrupt when a full DWORD is recieved.
+You need to recover the actual RC5 bits out of the (oversampled) IR sensor
+bits. (Hint: look for the 0/1and 1/0 crossings of the RC5 bi-phase data)  An
+actual raw RC5 code will span 2-3 DWORDS, depending on the actual alignment.
+
+I'm pretty sure when no IR signal is present the receiver is always in a
+marking state(1); but stray light, etc can cause intermittent noise values
+as well.  Remember, this is a free running sample of the IR receiver state
+over time, so don't assume any sample starts at any particular place.
+
+http://www.atmel.com/dyn/resources/prod_documents/doc2817.pdf
+This data sheet (google search) seems to have a lovely description of the
+RC5 basics
+
+http://users.pandora.be/nenya/electronics/rc5/  and more data
+
+http://www.ee.washington.edu/circuit_archive/text/ir_decode.txt
+and even a reference to how to decode a bi-phase data stream.
+
+http://www.xs4all.nl/~sbp/knowledge/ir/rc5.htm
+still more info
+
diff --git a/Documentation/video4linux/v4lgrab.c b/Documentation/video4linux/v4lgrab.c
new file mode 100644
index 000000000..079b62848
--- /dev/null
+++ b/Documentation/video4linux/v4lgrab.c
@@ -0,0 +1,192 @@
+/* Simple Video4Linux image grabber. */
+/*
+ *	Video4Linux Driver Test/Example Framegrabbing Program
+ *
+ *	Compile with:
+ *		gcc -s -Wall -Wstrict-prototypes v4lgrab.c -o v4lgrab
+ *      Use as:
+ *              v4lgrab >image.ppm
+ *
+ *	Copyright (C) 1998-05-03, Phil Blundell <philb@gnu.org>
+ *      Copied from http://www.tazenda.demon.co.uk/phil/vgrabber.c
+ *      with minor modifications (Dave Forrest, drf5n@virginia.edu).
+ *
+ */
+
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <sys/ioctl.h>
+#include <stdlib.h>
+
+#include <linux/types.h>
+#include <linux/videodev.h>
+
+#define FILE "/dev/video0"
+
+/* Stole this from tvset.c */
+
+#define READ_VIDEO_PIXEL(buf, format, depth, r, g, b)                   \
+{                                                                       \
+	switch (format)                                                 \
+	{                                                               \
+		case VIDEO_PALETTE_GREY:                                \
+			switch (depth)                                  \
+			{                                               \
+				case 4:                                 \
+				case 6:                                 \
+				case 8:                                 \
+					(r) = (g) = (b) = (*buf++ << 8);\
+					break;                          \
+									\
+				case 16:                                \
+					(r) = (g) = (b) =               \
+						*((unsigned short *) buf);      \
+					buf += 2;                       \
+					break;                          \
+			}                                               \
+			break;                                          \
+									\
+									\
+		case VIDEO_PALETTE_RGB565:                              \
+		{                                                       \
+			unsigned short tmp = *(unsigned short *)buf;    \
+			(r) = tmp&0xF800;                               \
+			(g) = (tmp<<5)&0xFC00;                          \
+			(b) = (tmp<<11)&0xF800;                         \
+			buf += 2;                                       \
+		}                                                       \
+		break;                                                  \
+									\
+		case VIDEO_PALETTE_RGB555:                              \
+			(r) = (buf[0]&0xF8)<<8;                         \
+			(g) = ((buf[0] << 5 | buf[1] >> 3)&0xF8)<<8;    \
+			(b) = ((buf[1] << 2 ) & 0xF8)<<8;               \
+			buf += 2;                                       \
+			break;                                          \
+									\
+		case VIDEO_PALETTE_RGB24:                               \
+			(r) = buf[0] << 8; (g) = buf[1] << 8;           \
+			(b) = buf[2] << 8;                              \
+			buf += 3;                                       \
+			break;                                          \
+									\
+		default:                                                \
+			fprintf(stderr,                                 \
+				"Format %d not yet supported\n",        \
+				format);                                \
+	}                                                               \
+}
+
+int get_brightness_adj(unsigned char *image, long size, int *brightness) {
+  long i, tot = 0;
+  for (i=0;i<size*3;i++)
+    tot += image[i];
+  *brightness = (128 - tot/(size*3))/3;
+  return !((tot/(size*3)) >= 126 && (tot/(size*3)) <= 130);
+}
+
+int main(int argc, char ** argv)
+{
+  int fd = open(FILE, O_RDONLY), f;
+  struct video_capability cap;
+  struct video_window win;
+  struct video_picture vpic;
+
+  unsigned char *buffer, *src;
+  int bpp = 24, r, g, b;
+  unsigned int i, src_depth;
+
+  if (fd < 0) {
+    perror(FILE);
+    exit(1);
+  }
+
+  if (ioctl(fd, VIDIOCGCAP, &cap) < 0) {
+    perror("VIDIOGCAP");
+    fprintf(stderr, "(" FILE " not a video4linux device?)\n");
+    close(fd);
+    exit(1);
+  }
+
+  if (ioctl(fd, VIDIOCGWIN, &win) < 0) {
+    perror("VIDIOCGWIN");
+    close(fd);
+    exit(1);
+  }
+
+  if (ioctl(fd, VIDIOCGPICT, &vpic) < 0) {
+    perror("VIDIOCGPICT");
+    close(fd);
+    exit(1);
+  }
+
+  if (cap.type & VID_TYPE_MONOCHROME) {
+    vpic.depth=8;
+    vpic.palette=VIDEO_PALETTE_GREY;    /* 8bit grey */
+    if(ioctl(fd, VIDIOCSPICT, &vpic) < 0) {
+      vpic.depth=6;
+      if(ioctl(fd, VIDIOCSPICT, &vpic) < 0) {
+	vpic.depth=4;
+	if(ioctl(fd, VIDIOCSPICT, &vpic) < 0) {
+	  fprintf(stderr, "Unable to find a supported capture format.\n");
+	  close(fd);
+	  exit(1);
+	}
+      }
+    }
+  } else {
+    vpic.depth=24;
+    vpic.palette=VIDEO_PALETTE_RGB24;
+
+    if(ioctl(fd, VIDIOCSPICT, &vpic) < 0) {
+      vpic.palette=VIDEO_PALETTE_RGB565;
+      vpic.depth=16;
+
+      if(ioctl(fd, VIDIOCSPICT, &vpic)==-1) {
+	vpic.palette=VIDEO_PALETTE_RGB555;
+	vpic.depth=15;
+
+	if(ioctl(fd, VIDIOCSPICT, &vpic)==-1) {
+	  fprintf(stderr, "Unable to find a supported capture format.\n");
+	  return -1;
+	}
+      }
+    }
+  }
+
+  buffer = malloc(win.width * win.height * bpp);
+  if (!buffer) {
+    fprintf(stderr, "Out of memory.\n");
+    exit(1);
+  }
+
+  do {
+    int newbright;
+    read(fd, buffer, win.width * win.height * bpp);
+    f = get_brightness_adj(buffer, win.width * win.height, &newbright);
+    if (f) {
+      vpic.brightness += (newbright << 8);
+      if(ioctl(fd, VIDIOCSPICT, &vpic)==-1) {
+	perror("VIDIOSPICT");
+	break;
+      }
+    }
+  } while (f);
+
+  fprintf(stdout, "P6\n%d %d 255\n", win.width, win.height);
+
+  src = buffer;
+
+  for (i = 0; i < win.width * win.height; i++) {
+    READ_VIDEO_PIXEL(src, vpic.palette, src_depth, r, g, b);
+    fputc(r>>8, stdout);
+    fputc(g>>8, stdout);
+    fputc(b>>8, stdout);
+  }
+
+  close(fd);
+  return 0;
+}
diff --git a/Documentation/w1/masters/ds2490 b/Documentation/w1/masters/ds2490
new file mode 100644
index 000000000..44a4918bd
--- /dev/null
+++ b/Documentation/w1/masters/ds2490
@@ -0,0 +1,18 @@
+Kernel driver ds2490
+====================
+
+Supported chips:
+  * Maxim DS2490 based
+
+Author: Evgeniy Polyakov <johnpol@2ka.mipt.ru>
+
+
+Description
+-----------
+
+The Maixm/Dallas Semiconductor DS2490 is a chip
+which allows to build USB <-> W1 bridges.
+
+DS9490(R) is a USB <-> W1 bus master device
+which has 0x81 family ID integrated chip and DS2490
+low-level operational chip.
diff --git a/Documentation/w1/w1.netlink b/Documentation/w1/w1.netlink
new file mode 100644
index 000000000..3640c7c87
--- /dev/null
+++ b/Documentation/w1/w1.netlink
@@ -0,0 +1,98 @@
+Userspace communication protocol over connector [1].
+
+
+Message types.
+=============
+
+There are three types of messages between w1 core and userspace:
+1. Events. They are generated each time new master or slave device found
+	either due to automatic or requested search.
+2. Userspace commands. Includes read/write and search/alarm search comamnds.
+3. Replies to userspace commands.
+
+
+Protocol.
+========
+
+[struct cn_msg] - connector header. It's length field is equal to size of the attached data.
+[struct w1_netlink_msg] - w1 netlink header.
+	__u8 type 	- message type.
+			W1_SLAVE_ADD/W1_SLAVE_REMOVE - slave add/remove events.
+			W1_MASTER_ADD/W1_MASTER_REMOVE - master add/remove events.
+			W1_MASTER_CMD - userspace command for bus master device (search/alarm search).
+			W1_SLAVE_CMD - userspace command for slave device (read/write/ search/alarm search
+					for bus master device where given slave device found).
+	__u8 res	- reserved
+	__u16 len	- size of attached to this header data.
+	union {
+		__u8 id;			 - slave unique device id
+		struct w1_mst {
+			__u32		id;	 - master's id.
+			__u32		res;	 - reserved
+		} mst;
+	} id;
+
+[strucrt w1_netlink_cmd] - command for gived master or slave device.
+	__u8 cmd	- command opcode.
+			W1_CMD_READ 	- read command.
+			W1_CMD_WRITE	- write command.
+			W1_CMD_SEARCH	- search command.
+			W1_CMD_ALARM_SEARCH - alarm search command.
+	__u8 res	- reserved
+	__u16 len	- length of data for this command.
+			For read command data must be allocated like for write command.
+	__u8 data[0]	- data for this command.
+
+
+Each connector message can include one or more w1_netlink_msg with zero of more attached w1_netlink_cmd messages.
+
+For event messages there are no w1_netlink_cmd embedded structures, only connector header
+and w1_netlink_msg strucutre with "len" field being zero and filled type (one of event types)
+and id - either 8 bytes of slave unique id in host order, or master's id, which is assigned
+to bus master device when it is added to w1 core.
+
+Currently replies to userspace commands are only generated for read command request.
+One reply is generated exactly for one w1_netlink_cmd read request.
+Replies are not combined when sent - i.e. typical reply messages looks like the following:
+[cn_msg][w1_netlink_msg][w1_netlink_cmd]
+cn_msg.len = sizeof(struct w1_netlink_msg) + sizeof(struct w1_netlink_cmd) + cmd->len;
+w1_netlink_msg.len = sizeof(struct w1_netlink_cmd) + cmd->len;
+w1_netlink_cmd.len = cmd->len;
+
+
+Operation steps in w1 core when new command is received.
+=======================================================
+
+When new message (w1_netlink_msg) is received w1 core detects if it is master of slave request,
+according to w1_netlink_msg.type field.
+Then master or slave device is searched for.
+When found, master device (requested or those one on where slave device is found) is locked.
+If slave command is requested, then reset/select procedure is started to select given device.
+
+Then all requested in w1_netlink_msg operations are performed one by one.
+If command requires reply (like read command) it is sent on command completion.
+
+When all commands (w1_netlink_cmd) are processed muster device is unlocked
+and next w1_netlink_msg header processing started.
+
+
+Connector [1] specific documentation.
+====================================
+
+Each connector message includes two u32 fields as "address".
+w1 uses CN_W1_IDX and CN_W1_VAL defined in include/linux/connector.h header.
+Each message also includes sequence and acknowledge numbers.
+Sequence number for event messages is appropriate bus master sequence number increased with
+each event message sent "through" this master.
+Sequence number for userspace requests is set by userspace application.
+Sequence number for reply is the same as was in request, and
+acknowledge number is set to seq+1.
+
+
+Additional documantion, source code examples.
+============================================
+
+1. Documentation/connector
+2. http://tservice.net.ru/~s0mbre/archive/w1
+This archive includes userspace application w1d.c which
+uses read/write/search commands for all master/slave devices found on the bus.
diff --git a/Documentation/watchdog/src/watchdog-simple.c b/Documentation/watchdog/src/watchdog-simple.c
new file mode 100644
index 000000000..85cf17c48
--- /dev/null
+++ b/Documentation/watchdog/src/watchdog-simple.c
@@ -0,0 +1,15 @@
+#include <stdlib.h>
+#include <fcntl.h>
+
+int main(int argc, const char *argv[]) {
+	int fd = open("/dev/watchdog", O_WRONLY);
+	if (fd == -1) {
+		perror("watchdog");
+		exit(1);
+	}
+	while (1) {
+		write(fd, "\0", 1);
+		fsync(fd);
+		sleep(10);
+	}
+}
diff --git a/Documentation/watchdog/src/watchdog-test.c b/Documentation/watchdog/src/watchdog-test.c
new file mode 100644
index 000000000..65f6c19cb
--- /dev/null
+++ b/Documentation/watchdog/src/watchdog-test.c
@@ -0,0 +1,68 @@
+/*
+ * Watchdog Driver Test Program
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <linux/types.h>
+#include <linux/watchdog.h>
+
+int fd;
+
+/*
+ * This function simply sends an IOCTL to the driver, which in turn ticks
+ * the PC Watchdog card to reset its internal timer so it doesn't trigger
+ * a computer reset.
+ */
+void keep_alive(void)
+{
+    int dummy;
+
+    ioctl(fd, WDIOC_KEEPALIVE, &dummy);
+}
+
+/*
+ * The main program.  Run the program with "-d" to disable the card,
+ * or "-e" to enable the card.
+ */
+int main(int argc, char *argv[])
+{
+    fd = open("/dev/watchdog", O_WRONLY);
+
+    if (fd == -1) {
+	fprintf(stderr, "Watchdog device not enabled.\n");
+	fflush(stderr);
+	exit(-1);
+    }
+
+    if (argc > 1) {
+	if (!strncasecmp(argv[1], "-d", 2)) {
+	    ioctl(fd, WDIOC_SETOPTIONS, WDIOS_DISABLECARD);
+	    fprintf(stderr, "Watchdog card disabled.\n");
+	    fflush(stderr);
+	    exit(0);
+	} else if (!strncasecmp(argv[1], "-e", 2)) {
+	    ioctl(fd, WDIOC_SETOPTIONS, WDIOS_ENABLECARD);
+	    fprintf(stderr, "Watchdog card enabled.\n");
+	    fflush(stderr);
+	    exit(0);
+	} else {
+	    fprintf(stderr, "-d to disable, -e to enable.\n");
+	    fprintf(stderr, "run by itself to tick the card.\n");
+	    fflush(stderr);
+	    exit(0);
+	}
+    } else {
+	fprintf(stderr, "Watchdog Ticking Away!\n");
+	fflush(stderr);
+    }
+
+    while(1) {
+	keep_alive();
+	sleep(1);
+    }
+}
diff --git a/arch/arm/configs/ateb9200_defconfig b/arch/arm/configs/ateb9200_defconfig
new file mode 100644
index 000000000..bee7813d0
--- /dev/null
+++ b/arch/arm/configs/ateb9200_defconfig
@@ -0,0 +1,1313 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.17-rc3
+# Sun May  7 16:53:18 2006
+#
+CONFIG_ARM=y
+CONFIG_MMU=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_VECTORS_BASE=0xffff0000
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+# CONFIG_AUDIT is not set
+# CONFIG_IKCONFIG is not set
+# CONFIG_RELAY is not set
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_UID16=y
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_EMBEDDED=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SHMEM=y
+CONFIG_SLAB=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_BLK_DEV_IO_TRACE is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+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_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_INTEGRATOR is not set
+# CONFIG_ARCH_IOP3XX 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_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
+# CONFIG_ARCH_VERSATILE is not set
+# CONFIG_ARCH_REALVIEW is not set
+# CONFIG_ARCH_IMX is not set
+# CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_AAEC2000 is not set
+CONFIG_ARCH_AT91=y
+CONFIG_ARCH_AT91RM9200=y
+
+#
+# AT91RM9200 Implementations
+#
+
+#
+# AT91RM9200 Board Type
+#
+# CONFIG_ARCH_AT91RM9200DK is not set
+# CONFIG_MACH_AT91RM9200EK is not set
+# CONFIG_MACH_CSB337 is not set
+# CONFIG_MACH_CSB637 is not set
+# CONFIG_MACH_CARMEVA is not set
+# CONFIG_MACH_KB9200 is not set
+CONFIG_MACH_ATEB9200=y
+# CONFIG_MACH_KAFA is not set
+
+#
+# AT91 Feature Selections
+#
+# CONFIG_AT91_PROGRAMMABLE_CLOCKS is not set
+
+#
+# Processor Type
+#
+CONFIG_CPU_32=y
+CONFIG_CPU_ARM920T=y
+CONFIG_CPU_32v4=y
+CONFIG_CPU_ABRT_EV4T=y
+CONFIG_CPU_CACHE_V4WT=y
+CONFIG_CPU_CACHE_VIVT=y
+CONFIG_CPU_COPY_V4WB=y
+CONFIG_CPU_TLB_V4WBI=y
+
+#
+# Processor Features
+#
+CONFIG_ARM_THUMB=y
+# CONFIG_CPU_ICACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_WRITETHROUGH is not set
+
+#
+# Bus support
+#
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+CONFIG_PCCARD=m
+# CONFIG_PCMCIA_DEBUG is not set
+CONFIG_PCMCIA=m
+CONFIG_PCMCIA_LOAD_CIS=y
+CONFIG_PCMCIA_IOCTL=y
+
+#
+# PC-card bridges
+#
+CONFIG_AT91_CF=m
+
+#
+# Kernel Features
+#
+CONFIG_PREEMPT=y
+CONFIG_NO_IDLE_HZ=y
+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_LEDS 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
+
+#
+# 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=y
+CONFIG_PM_LEGACY=y
+# CONFIG_PM_DEBUG 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_XFRM=y
+# CONFIG_XFRM_USER is not set
+CONFIG_NET_KEY=y
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+# CONFIG_IP_PNP is not set
+# 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_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
+# CONFIG_IPV6 is not set
+# CONFIG_INET6_XFRM_TUNNEL is not set
+# CONFIG_INET6_TUNNEL 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=m
+CONFIG_VLAN_8021Q=m
+# CONFIG_DECNET is not set
+CONFIG_LLC=m
+# 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_NET_DIVERT 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=m
+# CONFIG_IEEE80211_DEBUG is not set
+CONFIG_IEEE80211_CRYPT_WEP=m
+CONFIG_IEEE80211_CRYPT_CCMP=m
+CONFIG_IEEE80211_CRYPT_TKIP=m
+# CONFIG_IEEE80211_SOFTMAC is not set
+CONFIG_WIRELESS_EXT=y
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+
+#
+# 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_BLOCK is not set
+CONFIG_MTD_BLOCK_RO=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL 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_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
+CONFIG_MTD_AT91_DATAFLASH=y
+# CONFIG_MTD_AT91_DATAFLASH_CARD is not set
+
+#
+# NAND Flash Device Drivers
+#
+# CONFIG_MTD_NAND 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=m
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+CONFIG_BLK_DEV_NBD=m
+# CONFIG_BLK_DEV_UB is not set
+# CONFIG_BLK_DEV_RAM is not set
+# CONFIG_BLK_DEV_INITRD is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+CONFIG_SCSI=m
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=m
+# CONFIG_CHR_DEV_ST is not set
+# CONFIG_CHR_DEV_OSST is not set
+CONFIG_BLK_DEV_SR=m
+CONFIG_BLK_DEV_SR_VENDOR=y
+CONFIG_CHR_DEV_SG=m
+# 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
+
+#
+# SCSI Transport Attributes
+#
+# 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
+
+#
+# SCSI low-level drivers
+#
+# CONFIG_ISCSI_TCP is not set
+# CONFIG_SCSI_SATA is not set
+# CONFIG_SCSI_DEBUG is not set
+
+#
+# PCMCIA SCSI adapter support
+#
+# CONFIG_PCMCIA_AHA152X is not set
+# CONFIG_PCMCIA_FDOMAIN is not set
+# CONFIG_PCMCIA_NINJA_SCSI is not set
+# CONFIG_PCMCIA_QLOGIC is not set
+# CONFIG_PCMCIA_SYM53C500 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=m
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+CONFIG_TUN=m
+
+#
+# PHY device support
+#
+CONFIG_PHYLIB=y
+
+#
+# MII PHY device drivers
+#
+# CONFIG_MARVELL_PHY is not set
+CONFIG_DAVICOM_PHY=y
+# CONFIG_QSEMI_PHY is not set
+# CONFIG_LXT_PHY is not set
+# CONFIG_CICADA_PHY is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+CONFIG_ARM_AT91_ETHER=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=y
+# CONFIG_NET_WIRELESS_RTNETLINK is not set
+
+#
+# Obsolete Wireless cards support (pre-802.11)
+#
+# CONFIG_STRIP is not set
+# CONFIG_PCMCIA_WAVELAN is not set
+# CONFIG_PCMCIA_NETWAVE is not set
+
+#
+# Wireless 802.11 Frequency Hopping cards support
+#
+# CONFIG_PCMCIA_RAYCS is not set
+
+#
+# Wireless 802.11b ISA/PCI cards support
+#
+# CONFIG_HERMES is not set
+# CONFIG_ATMEL is not set
+
+#
+# Wireless 802.11b Pcmcia/Cardbus cards support
+#
+# CONFIG_AIRO_CS is not set
+# CONFIG_PCMCIA_WL3501 is not set
+# CONFIG_HOSTAP is not set
+CONFIG_NET_WIRELESS=y
+
+#
+# PCMCIA network device support
+#
+# CONFIG_NET_PCMCIA is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+CONFIG_PPP=m
+# CONFIG_PPP_MULTILINK is not set
+# CONFIG_PPP_FILTER is not set
+CONFIG_PPP_ASYNC=m
+CONFIG_PPP_SYNC_TTY=m
+CONFIG_PPP_DEFLATE=m
+CONFIG_PPP_BSDCOMP=m
+# CONFIG_PPP_MPPE is not set
+CONFIG_PPPOE=m
+# 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
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
+CONFIG_INPUT_MOUSEDEV_PSAUX=y
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_TSDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+CONFIG_KEYBOARD_ATKBD=y
+# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_KEYBOARD_LKKBD is not set
+# CONFIG_KEYBOARD_XTKBD is not set
+# CONFIG_KEYBOARD_NEWTON is not set
+CONFIG_INPUT_MOUSE=y
+CONFIG_MOUSE_PS2=y
+# CONFIG_MOUSE_SERIAL is not set
+# CONFIG_MOUSE_VSXXXAA 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=y
+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_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_AT91=y
+CONFIG_SERIAL_AT91_CONSOLE=y
+# CONFIG_SERIAL_AT91_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 is not set
+# CONFIG_NVRAM is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+
+#
+# PCMCIA character devices
+#
+# CONFIG_SYNCLINK_CS is not set
+# CONFIG_CARDMAN_4000 is not set
+# CONFIG_CARDMAN_4040 is not set
+# CONFIG_RAW_DRIVER is not set
+
+#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+# CONFIG_TELCLOCK is not set
+CONFIG_AT91_SPI=y
+CONFIG_AT91_SPIDEV=y
+
+#
+# I2C support
+#
+CONFIG_I2C=m
+CONFIG_I2C_CHARDEV=m
+
+#
+# I2C Algorithms
+#
+CONFIG_I2C_ALGOBIT=m
+CONFIG_I2C_ALGOPCF=m
+CONFIG_I2C_ALGOPCA=m
+
+#
+# I2C Hardware Bus support
+#
+CONFIG_I2C_AT91=m
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_STUB 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 is not set
+# CONFIG_SPI_MASTER is not set
+
+#
+# Dallas's 1-wire bus
+#
+# CONFIG_W1 is not set
+
+#
+# Hardware Monitoring support
+#
+CONFIG_HWMON=y
+# CONFIG_HWMON_VID is not set
+# CONFIG_SENSORS_ADM1021 is not set
+# CONFIG_SENSORS_ADM1025 is not set
+# CONFIG_SENSORS_ADM1026 is not set
+# CONFIG_SENSORS_ADM1031 is not set
+# CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ASB100 is not set
+# CONFIG_SENSORS_ATXP1 is not set
+# CONFIG_SENSORS_DS1621 is not set
+# CONFIG_SENSORS_F71805F is not set
+# CONFIG_SENSORS_FSCHER is not set
+# CONFIG_SENSORS_FSCPOS is not set
+# CONFIG_SENSORS_GL518SM is not set
+# CONFIG_SENSORS_GL520SM is not set
+# CONFIG_SENSORS_IT87 is not set
+# CONFIG_SENSORS_LM63 is not set
+# CONFIG_SENSORS_LM75 is not set
+# CONFIG_SENSORS_LM77 is not set
+# CONFIG_SENSORS_LM78 is not set
+# CONFIG_SENSORS_LM80 is not set
+# CONFIG_SENSORS_LM83 is not set
+# CONFIG_SENSORS_LM85 is not set
+# CONFIG_SENSORS_LM87 is not set
+# CONFIG_SENSORS_LM90 is not set
+# CONFIG_SENSORS_LM92 is not set
+# CONFIG_SENSORS_MAX1619 is not set
+# CONFIG_SENSORS_PC87360 is not set
+# CONFIG_SENSORS_SMSC47M1 is not set
+# CONFIG_SENSORS_SMSC47B397 is not set
+# CONFIG_SENSORS_W83781D is not set
+# CONFIG_SENSORS_W83792D 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
+#
+
+#
+# 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_FB is not set
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+
+#
+# Sound
+#
+CONFIG_SOUND=y
+
+#
+# Advanced Linux Sound Architecture
+#
+# CONFIG_SND is not set
+
+#
+# Open Sound System
+#
+# CONFIG_SOUND_PRIME is not set
+
+#
+# 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_SUSPEND 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=m
+CONFIG_USB_PRINTER=m
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+#
+
+#
+# may also be needed; see USB_STORAGE Help for more information
+#
+CONFIG_USB_STORAGE=m
+# CONFIG_USB_STORAGE_DEBUG is not set
+CONFIG_USB_STORAGE_DATAFAB=y
+CONFIG_USB_STORAGE_FREECOM=y
+CONFIG_USB_STORAGE_DPCM=y
+CONFIG_USB_STORAGE_USBAT=y
+CONFIG_USB_STORAGE_SDDR09=y
+CONFIG_USB_STORAGE_SDDR55=y
+CONFIG_USB_STORAGE_JUMPSHOT=y
+# CONFIG_USB_STORAGE_ALAUDA 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_THRUSTMASTER_FF=y
+CONFIG_USB_HIDDEV=y
+
+#
+# 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=y
+CONFIG_USB_NET_AX8817X=y
+CONFIG_USB_NET_CDCETHER=y
+CONFIG_USB_NET_GL620A=y
+CONFIG_USB_NET_NET1080=y
+CONFIG_USB_NET_PLUSB=y
+CONFIG_USB_NET_RNDIS_HOST=y
+CONFIG_USB_NET_CDC_SUBSET=y
+CONFIG_USB_ALI_M5632=y
+CONFIG_USB_AN2720=y
+CONFIG_USB_BELKIN=y
+CONFIG_USB_ARMLINUX=y
+CONFIG_USB_EPSON2888=y
+CONFIG_USB_NET_ZAURUS=y
+# CONFIG_USB_ZD1201 is not set
+CONFIG_USB_MON=y
+
+#
+# USB port drivers
+#
+
+#
+# USB Serial Converter support
+#
+CONFIG_USB_SERIAL=m
+CONFIG_USB_SERIAL_GENERIC=y
+# CONFIG_USB_SERIAL_AIRPRIME is not set
+# CONFIG_USB_SERIAL_ANYDATA is not set
+# CONFIG_USB_SERIAL_BELKIN is not set
+# CONFIG_USB_SERIAL_WHITEHEAT is not set
+# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
+CONFIG_USB_SERIAL_CP2101=m
+# CONFIG_USB_SERIAL_CYPRESS_M8 is not set
+# CONFIG_USB_SERIAL_EMPEG is not set
+CONFIG_USB_SERIAL_FTDI_SIO=m
+# CONFIG_USB_SERIAL_FUNSOFT is not set
+# CONFIG_USB_SERIAL_VISOR is not set
+# CONFIG_USB_SERIAL_IPAQ is not set
+# CONFIG_USB_SERIAL_IR is not set
+# CONFIG_USB_SERIAL_EDGEPORT is not set
+# CONFIG_USB_SERIAL_EDGEPORT_TI is not set
+# CONFIG_USB_SERIAL_GARMIN is not set
+# CONFIG_USB_SERIAL_IPW is not set
+# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set
+# CONFIG_USB_SERIAL_KEYSPAN is not set
+# CONFIG_USB_SERIAL_KLSI is not set
+# CONFIG_USB_SERIAL_KOBIL_SCT is not set
+# CONFIG_USB_SERIAL_MCT_U232 is not set
+# CONFIG_USB_SERIAL_NAVMAN is not set
+CONFIG_USB_SERIAL_PL2303=m
+# CONFIG_USB_SERIAL_HP4X is not set
+# CONFIG_USB_SERIAL_SAFE is not set
+# CONFIG_USB_SERIAL_TI is not set
+# CONFIG_USB_SERIAL_CYBERJACK is not set
+# CONFIG_USB_SERIAL_XIRCOM is not set
+# CONFIG_USB_SERIAL_OPTION is not set
+# CONFIG_USB_SERIAL_OMNINET is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_EMI62 is not set
+# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_AUERSWALD is not set
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_LEGOTOWER is not set
+# CONFIG_USB_LCD is not set
+# CONFIG_USB_LED is not set
+# CONFIG_USB_CYTHERM is not set
+# CONFIG_USB_PHIDGETKIT is not set
+# CONFIG_USB_PHIDGETSERVO is not set
+# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_LD is not set
+# CONFIG_USB_TEST is not set
+
+#
+# USB DSL modem support
+#
+
+#
+# USB Gadget Support
+#
+CONFIG_USB_GADGET=m
+# 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=m
+# CONFIG_USB_GADGET_DUMMY_HCD is not set
+# CONFIG_USB_GADGET_DUALSPEED is not set
+# CONFIG_USB_ZERO is not set
+CONFIG_USB_ETH=m
+CONFIG_USB_ETH_RNDIS=y
+CONFIG_USB_GADGETFS=m
+CONFIG_USB_FILE_STORAGE=m
+# CONFIG_USB_FILE_STORAGE_TEST is not set
+CONFIG_USB_G_SERIAL=m
+
+#
+# MMC/SD Card support
+#
+CONFIG_MMC=m
+CONFIG_MMC_DEBUG=y
+CONFIG_MMC_BLOCK=m
+CONFIG_MMC_AT91RM9200=m
+
+#
+# Real Time Clock
+#
+CONFIG_RTC_LIB=y
+CONFIG_RTC_CLASS=y
+# CONFIG_RTC_HCTOSYS is not set
+
+#
+# RTC interfaces
+#
+CONFIG_RTC_INTF_SYSFS=y
+CONFIG_RTC_INTF_PROC=y
+CONFIG_RTC_INTF_DEV=y
+
+#
+# RTC drivers
+#
+# CONFIG_RTC_DRV_X1205 is not set
+# CONFIG_RTC_DRV_DS1672 is not set
+# 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_TEST is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=m
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
+CONFIG_EXT3_FS=m
+CONFIG_EXT3_FS_XATTR=y
+# CONFIG_EXT3_FS_POSIX_ACL is not set
+# CONFIG_EXT3_FS_SECURITY is not set
+CONFIG_JBD=m
+# CONFIG_JBD_DEBUG is not set
+CONFIG_FS_MBCACHE=m
+CONFIG_REISERFS_FS=m
+# CONFIG_REISERFS_CHECK is not set
+# CONFIG_REISERFS_PROC_INFO is not set
+# CONFIG_REISERFS_FS_XATTR is not set
+# CONFIG_JFS_FS is not set
+CONFIG_FS_POSIX_ACL=y
+# CONFIG_XFS_FS is not set
+# CONFIG_OCFS2_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=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=m
+CONFIG_JOLIET=y
+CONFIG_ZISOFS=y
+CONFIG_ZISOFS_FS=m
+CONFIG_UDF_FS=m
+CONFIG_UDF_NLS=y
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=m
+CONFIG_MSDOS_FS=m
+CONFIG_VFAT_FS=m
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+CONFIG_NTFS_FS=m
+# CONFIG_NTFS_DEBUG is not set
+CONFIG_NTFS_RW=y
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# 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_JFFS_FS is not set
+# CONFIG_JFFS2_FS 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=m
+CONFIG_NFS_V3=y
+CONFIG_NFS_V3_ACL=y
+CONFIG_NFS_V4=y
+CONFIG_NFS_DIRECTIO=y
+CONFIG_NFSD=m
+CONFIG_NFSD_V3=y
+# CONFIG_NFSD_V3_ACL is not set
+CONFIG_NFSD_V4=y
+CONFIG_NFSD_TCP=y
+CONFIG_LOCKD=m
+CONFIG_LOCKD_V4=y
+CONFIG_EXPORTFS=m
+CONFIG_NFS_ACL_SUPPORT=m
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=m
+CONFIG_SUNRPC_GSS=m
+CONFIG_RPCSEC_GSS_KRB5=m
+# 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=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+CONFIG_MAC_PARTITION=y
+CONFIG_MSDOS_PARTITION=y
+CONFIG_BSD_DISKLABEL=y
+CONFIG_MINIX_SUBPARTITION=y
+CONFIG_SOLARIS_X86_PARTITION=y
+CONFIG_UNIXWARE_DISKLABEL=y
+# CONFIG_LDM_PARTITION is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_KARMA_PARTITION is not set
+# CONFIG_EFI_PARTITION is not set
+
+#
+# Native Language Support
+#
+CONFIG_NLS=m
+CONFIG_NLS_DEFAULT="iso8859-1"
+# CONFIG_NLS_CODEPAGE_437 is not set
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+CONFIG_NLS_CODEPAGE_932=m
+# 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=m
+# CONFIG_NLS_ISO8859_1 is not set
+# 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=m
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+CONFIG_NLS_UTF8=m
+
+#
+# Profiling support
+#
+CONFIG_PROFILING=y
+CONFIG_OPROFILE=m
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_DEBUG_KERNEL is not set
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_DEBUG_BUGVERBOSE is not set
+# CONFIG_DEBUG_FS is not set
+CONFIG_FRAME_POINTER=y
+# CONFIG_UNWIND_INFO is not set
+# CONFIG_DEBUG_USER is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+
+#
+# Cryptographic options
+#
+CONFIG_CRYPTO=y
+# CONFIG_CRYPTO_HMAC is not set
+# CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_MD4 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_DES=m
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+# CONFIG_CRYPTO_SERPENT is not set
+CONFIG_CRYPTO_AES=m
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+# CONFIG_CRYPTO_TEA is not set
+CONFIG_CRYPTO_ARC4=m
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_DEFLATE is not set
+CONFIG_CRYPTO_MICHAEL_MIC=m
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Hardware crypto devices
+#
+
+#
+# Library routines
+#
+CONFIG_CRC_CCITT=m
+CONFIG_CRC16=m
+CONFIG_CRC32=y
+CONFIG_LIBCRC32C=m
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=m
diff --git a/arch/arm/configs/carmeva_defconfig b/arch/arm/configs/carmeva_defconfig
new file mode 100644
index 000000000..8a075c8ec
--- /dev/null
+++ b/arch/arm/configs/carmeva_defconfig
@@ -0,0 +1,724 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.12-rc4
+# Tue Jun 14 12:05:24 2005
+#
+CONFIG_ARM=y
+CONFIG_MMU=y
+CONFIG_UID16=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_IOMAP=y
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_CLEAN_COMPILE=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+CONFIG_SWAP=y
+# CONFIG_SYSVIPC is not set
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_SYSCTL is not set
+# CONFIG_AUDIT is not set
+# CONFIG_HOTPLUG is not set
+CONFIG_KOBJECT_UEVENT=y
+# CONFIG_IKCONFIG is not set
+CONFIG_EMBEDDED=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SHMEM=y
+CONFIG_CC_ALIGN_FUNCTIONS=0
+CONFIG_CC_ALIGN_LABELS=0
+CONFIG_CC_ALIGN_LOOPS=0
+CONFIG_CC_ALIGN_JUMPS=0
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODULE_FORCE_UNLOAD=y
+CONFIG_OBSOLETE_MODPARM=y
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+# CONFIG_KMOD is not set
+
+#
+# System Type
+#
+# 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_FOOTBRIDGE is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_IOP3XX is not set
+# CONFIG_ARCH_IXP4XX is not set
+# CONFIG_ARCH_IXP2000 is not set
+# CONFIG_ARCH_L7200 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
+# CONFIG_ARCH_VERSATILE is not set
+# CONFIG_ARCH_IMX is not set
+# CONFIG_ARCH_H720X is not set
+CONFIG_ARCH_AT91=y
+CONFIG_ARCH_AT91RM9200=y
+
+#
+# AT91RM9200 Implementations
+#
+# CONFIG_ARCH_AT91RM9200DK is not set
+# CONFIG_MACH_AT91RM9200EK is not set
+# CONFIG_MACH_CSB337 is not set
+# CONFIG_MACH_CSB637 is not set
+CONFIG_MACH_CARMEVA=y
+
+#
+# Processor Type
+#
+CONFIG_CPU_32=y
+CONFIG_CPU_ARM920T=y
+CONFIG_CPU_32v4=y
+CONFIG_CPU_ABRT_EV4T=y
+CONFIG_CPU_CACHE_V4WT=y
+CONFIG_CPU_CACHE_VIVT=y
+CONFIG_CPU_COPY_V4WB=y
+CONFIG_CPU_TLB_V4WBI=y
+
+#
+# Processor Features
+#
+CONFIG_ARM_THUMB=y
+# CONFIG_CPU_ICACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_WRITETHROUGH is not set
+
+#
+# Bus support
+#
+CONFIG_ISA_DMA_API=y
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# Kernel Features
+#
+# CONFIG_SMP is not set
+# CONFIG_PREEMPT is not set
+# CONFIG_DISCONTIGMEM 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=""
+# 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
+
+#
+# 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
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_FW_LOADER 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_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL 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
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLKMTD 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
+CONFIG_MTD_AT91_DATAFLASH=y
+# CONFIG_MTD_AT91_DATAFLASH_CARD is not set
+
+#
+# NAND Flash Device Drivers
+#
+# CONFIG_MTD_NAND 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_NBD is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=4096
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_CDROM_PKTCDVD is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_ATA_OVER_ETH is not set
+
+#
+# SCSI device support
+#
+# CONFIG_SCSI is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+
+#
+# Fusion MPT device support
+#
+
+#
+# IEEE 1394 (FireWire) support
+#
+
+#
+# I2O device support
+#
+
+#
+# Networking support
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+# CONFIG_PACKET is not set
+CONFIG_UNIX=y
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_PNP=y
+# CONFIG_IP_PNP_DHCP is not set
+# CONFIG_IP_PNP_BOOTP is not set
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_TUNNEL is not set
+CONFIG_IP_TCPDIAG=y
+# CONFIG_IP_TCPDIAG_IPV6 is not set
+# CONFIG_IPV6 is not set
+# CONFIG_NETFILTER is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP 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_NET_DIVERT 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
+# CONFIG_NET_CLS_ROUTE is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+CONFIG_ARM_AT91_ETHER=y
+CONFIG_ARM_AT91_ETHER_RMII=y
+# CONFIG_SMC91X 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
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+
+#
+# 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=m
+CONFIG_SERIO_SERPORT=m
+# CONFIG_SERIO_LIBPS2 is not set
+# CONFIG_SERIO_RAW is not set
+# CONFIG_GAMEPORT is not set
+CONFIG_SOUND_GAMEPORT=y
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_AT91=y
+CONFIG_SERIAL_AT91_CONSOLE=y
+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 is not set
+# CONFIG_NVRAM is not set
+# CONFIG_RTC is not set
+# CONFIG_AT91_RTC is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_DRM is not set
+# CONFIG_RAW_DRIVER is not set
+
+#
+# TPM devices
+#
+CONFIG_AT91_SPI=y
+CONFIG_AT91_SPIDEV=y
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# Misc devices
+#
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# Digital Video Broadcasting Devices
+#
+# CONFIG_DVB is not set
+
+#
+# Graphics support
+#
+# CONFIG_FB is not set
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
+#
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+# CONFIG_USB is not set
+
+#
+# USB Gadget Support
+#
+# CONFIG_USB_GADGET is not set
+
+#
+# MMC/SD Card support
+#
+CONFIG_MMC=m
+CONFIG_MMC_DEBUG=y
+CONFIG_MMC_BLOCK=m
+CONFIG_MMC_AT91RM9200=m
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+# CONFIG_EXT2_FS_POSIX_ACL is not set
+# CONFIG_EXT2_FS_SECURITY is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_JBD is not set
+CONFIG_FS_MBCACHE=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+
+#
+# XFS support
+#
+# CONFIG_XFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_QUOTA is not set
+# CONFIG_DNOTIFY is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_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_SYSFS=y
+# CONFIG_DEVFS_FS is not set
+CONFIG_DEVPTS_FS_XATTR=y
+CONFIG_DEVPTS_FS_SECURITY=y
+# CONFIG_TMPFS is not set
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_RAMFS=y
+
+#
+# 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_JFFS_FS=y
+CONFIG_JFFS_FS_VERBOSE=0
+CONFIG_JFFS_PROC_FS=y
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_FS_DEBUG=0
+CONFIG_JFFS2_FS_NAND=y
+# CONFIG_JFFS2_FS_NOR_ECC is not set
+CONFIG_JFFS2_COMPRESSION_OPTIONS=y
+CONFIG_JFFS2_ZLIB=y
+CONFIG_JFFS2_RTIME=y
+# CONFIG_JFFS2_RUBIN is not set
+# CONFIG_JFFS2_CMODE_NONE is not set
+CONFIG_JFFS2_CMODE_PRIORITY=y
+# CONFIG_JFFS2_CMODE_SIZE 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
+
+#
+# Network File Systems
+#
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+CONFIG_NFS_V4=y
+# CONFIG_NFS_DIRECTIO is not set
+CONFIG_NFSD=y
+# CONFIG_NFSD_V3 is not set
+CONFIG_NFSD_TCP=y
+CONFIG_ROOT_NFS=y
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_EXPORTFS=y
+CONFIG_SUNRPC=y
+CONFIG_SUNRPC_GSS=y
+CONFIG_RPCSEC_GSS_KRB5=y
+# 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
+
+#
+# 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_DEBUG_KERNEL is not set
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_DEBUG_BUGVERBOSE is not set
+CONFIG_FRAME_POINTER=y
+# CONFIG_DEBUG_USER is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+
+#
+# Cryptographic options
+#
+CONFIG_CRYPTO=y
+# CONFIG_CRYPTO_HMAC is not set
+# CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_MD4 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_DES=y
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_AES is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_ARC4 is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Hardware crypto devices
+#
+
+#
+# Library routines
+#
+# CONFIG_CRC_CCITT is not set
+CONFIG_CRC32=y
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
diff --git a/arch/arm/configs/kafa_defconfig b/arch/arm/configs/kafa_defconfig
new file mode 100644
index 000000000..1db633e2c
--- /dev/null
+++ b/arch/arm/configs/kafa_defconfig
@@ -0,0 +1,885 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.17-rc3
+# Sun May  7 16:54:53 2006
+#
+CONFIG_ARM=y
+CONFIG_MMU=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_VECTORS_BASE=0xffff0000
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_LOCK_KERNEL=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_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+# CONFIG_AUDIT is not set
+# CONFIG_IKCONFIG is not set
+# CONFIG_RELAY is not set
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_UID16=y
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+# CONFIG_EMBEDDED is not set
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SHMEM=y
+CONFIG_SLAB=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 is not set
+
+#
+# Block layer
+#
+# CONFIG_BLK_DEV_IO_TRACE is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+# CONFIG_IOSCHED_AS is not set
+CONFIG_IOSCHED_DEADLINE=y
+# CONFIG_IOSCHED_CFQ is not set
+# CONFIG_DEFAULT_AS is not set
+CONFIG_DEFAULT_DEADLINE=y
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="deadline"
+
+#
+# System Type
+#
+# 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_INTEGRATOR is not set
+# CONFIG_ARCH_IOP3XX 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_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
+# CONFIG_ARCH_VERSATILE is not set
+# CONFIG_ARCH_REALVIEW is not set
+# CONFIG_ARCH_IMX is not set
+# CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_AAEC2000 is not set
+CONFIG_ARCH_AT91=y
+CONFIG_ARCH_AT91RM9200=y
+
+#
+# AT91RM9200 Implementations
+#
+
+#
+# AT91RM9200 Board Type
+#
+# CONFIG_ARCH_AT91RM9200DK is not set
+# CONFIG_MACH_AT91RM9200EK is not set
+# CONFIG_MACH_CSB337 is not set
+# CONFIG_MACH_CSB637 is not set
+# CONFIG_MACH_CARMEVA is not set
+# CONFIG_MACH_KB9200 is not set
+# CONFIG_MACH_ATEB9200 is not set
+CONFIG_MACH_KAFA=y
+
+#
+# AT91 Feature Selections
+#
+# CONFIG_AT91_PROGRAMMABLE_CLOCKS is not set
+
+#
+# Processor Type
+#
+CONFIG_CPU_32=y
+CONFIG_CPU_ARM920T=y
+CONFIG_CPU_32v4=y
+CONFIG_CPU_ABRT_EV4T=y
+CONFIG_CPU_CACHE_V4WT=y
+CONFIG_CPU_CACHE_VIVT=y
+CONFIG_CPU_COPY_V4WB=y
+CONFIG_CPU_TLB_V4WBI=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
+
+#
+# Bus support
+#
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# Kernel Features
+#
+CONFIG_PREEMPT=y
+# 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_LEDS=y
+# CONFIG_LEDS_TIMER is not set
+CONFIG_LEDS_CPU=y
+CONFIG_ALIGNMENT_TRAP=y
+
+#
+# Boot options
+#
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="mem=32M console=ttyS0,115200 initrd=0x20800000,10M 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
+
+#
+# Userspace binary formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_AOUT is not set
+CONFIG_BINFMT_MISC=y
+# 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 is not set
+# 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_DIAG is not set
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
+# CONFIG_IPV6 is not set
+# CONFIG_INET6_XFRM_TUNNEL is not set
+# CONFIG_INET6_TUNNEL 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_NET_DIVERT 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
+
+#
+# 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 is not set
+# CONFIG_MTD_AFS_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+# CONFIG_MTD_BLOCK is not set
+CONFIG_MTD_BLOCK_RO=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL 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_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
+CONFIG_MTD_AT91_DATAFLASH=y
+# CONFIG_MTD_AT91_DATAFLASH_CARD is not set
+
+#
+# NAND Flash Device Drivers
+#
+# CONFIG_MTD_NAND 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 is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_RAM is not set
+# CONFIG_BLK_DEV_INITRD is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+# CONFIG_SCSI 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=y
+
+#
+# MII PHY device drivers
+#
+# CONFIG_MARVELL_PHY is not set
+CONFIG_DAVICOM_PHY=y
+# CONFIG_QSEMI_PHY is not set
+# CONFIG_LXT_PHY is not set
+# CONFIG_CICADA_PHY is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+CONFIG_ARM_AT91_ETHER=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
+
+#
+# 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 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 is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_AT91=y
+CONFIG_SERIAL_AT91_CONSOLE=y
+# CONFIG_SERIAL_AT91_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=32
+
+#
+# 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
+CONFIG_AT91_WATCHDOG=y
+# 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
+
+#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+# CONFIG_TELCLOCK is not set
+CONFIG_AT91_SPI=y
+CONFIG_AT91_SPIDEV=y
+
+#
+# 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_PARPORT_LIGHT is not set
+# CONFIG_I2C_STUB 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 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
+#
+
+#
+# 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
+
+#
+# Graphics support
+#
+# CONFIG_FB is not set
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
+#
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+# 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=y
+# CONFIG_RTC_HCTOSYS is not set
+
+#
+# RTC interfaces
+#
+CONFIG_RTC_INTF_SYSFS=y
+CONFIG_RTC_INTF_PROC=y
+CONFIG_RTC_INTF_DEV=y
+
+#
+# RTC drivers
+#
+# CONFIG_RTC_DRV_X1205 is not set
+# CONFIG_RTC_DRV_DS1672 is not set
+# 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_TEST is not set
+
+#
+# File systems
+#
+# CONFIG_EXT2_FS is not set
+CONFIG_EXT3_FS=y
+# CONFIG_EXT3_FS_XATTR is not set
+CONFIG_JBD=y
+# CONFIG_JBD_DEBUG 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_OCFS2_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_INOTIFY is not set
+# 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_MSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# 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_JFFS_FS is not set
+# CONFIG_JFFS2_FS 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=m
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
+# CONFIG_NFS_V4 is not set
+# CONFIG_NFS_DIRECTIO is not set
+# CONFIG_NFSD is not set
+CONFIG_LOCKD=m
+CONFIG_LOCKD_V4=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=m
+# 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 is not set
+
+#
+# Profiling support
+#
+# CONFIG_PROFILING is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_DEBUG_KERNEL is not set
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_DEBUG_BUGVERBOSE=y
+# CONFIG_DEBUG_FS is not set
+CONFIG_FRAME_POINTER=y
+# CONFIG_UNWIND_INFO is not set
+# CONFIG_DEBUG_USER is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+
+#
+# Cryptographic options
+#
+CONFIG_CRYPTO=y
+# CONFIG_CRYPTO_HMAC is not set
+# CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_MD4 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_DES=y
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_AES is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_ARC4 is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Hardware crypto devices
+#
+
+#
+# Library routines
+#
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
+CONFIG_CRC32=y
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=y
diff --git a/arch/arm/configs/kb9202_defconfig b/arch/arm/configs/kb9202_defconfig
new file mode 100644
index 000000000..45396e087
--- /dev/null
+++ b/arch/arm/configs/kb9202_defconfig
@@ -0,0 +1,781 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.13-rc2
+# Sun Aug 14 19:26:59 2005
+#
+CONFIG_ARM=y
+CONFIG_MMU=y
+CONFIG_UID16=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+
+#
+# Code maturity level options
+#
+# CONFIG_EXPERIMENTAL is not set
+CONFIG_CLEAN_COMPILE=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+# CONFIG_SWAP is not set
+# CONFIG_SYSVIPC is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+# CONFIG_AUDIT is not set
+CONFIG_HOTPLUG=y
+# CONFIG_KOBJECT_UEVENT is not set
+# CONFIG_IKCONFIG is not set
+# CONFIG_EMBEDDED is not set
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SHMEM=y
+CONFIG_CC_ALIGN_FUNCTIONS=0
+CONFIG_CC_ALIGN_LABELS=0
+CONFIG_CC_ALIGN_LOOPS=0
+CONFIG_CC_ALIGN_JUMPS=0
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_OBSOLETE_MODPARM=y
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_KMOD=y
+
+#
+# System Type
+#
+# 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_FOOTBRIDGE is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_IOP3XX is not set
+# CONFIG_ARCH_IXP4XX is not set
+# CONFIG_ARCH_IXP2000 is not set
+# CONFIG_ARCH_L7200 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
+# CONFIG_ARCH_VERSATILE is not set
+# CONFIG_ARCH_IMX is not set
+# CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_AAEC2000 is not set
+CONFIG_ARCH_AT91=y
+CONFIG_ARCH_AT91RM9200=y
+
+#
+# AT91RM9200 Implementations
+#
+# CONFIG_ARCH_AT91RM9200DK is not set
+# CONFIG_MACH_AT91RM9200EK is not set
+# CONFIG_MACH_CSB337 is not set
+# CONFIG_MACH_CSB637 is not set
+# CONFIG_MACH_CARMEVA is not set
+CONFIG_MACH_KB9200=y
+
+#
+# Processor Type
+#
+CONFIG_CPU_32=y
+CONFIG_CPU_ARM920T=y
+CONFIG_CPU_32v4=y
+CONFIG_CPU_ABRT_EV4T=y
+CONFIG_CPU_CACHE_V4WT=y
+CONFIG_CPU_CACHE_VIVT=y
+CONFIG_CPU_COPY_V4WB=y
+CONFIG_CPU_TLB_V4WBI=y
+
+#
+# Processor Features
+#
+CONFIG_ARM_THUMB=y
+# CONFIG_CPU_ICACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_WRITETHROUGH is not set
+
+#
+# Bus support
+#
+CONFIG_ISA_DMA_API=y
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# Kernel Features
+#
+# CONFIG_NO_IDLE_HZ is not set
+# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_LEDS is not set
+CONFIG_ALIGNMENT_TRAP=y
+
+#
+# Boot options
+#
+CONFIG_ZBOOT_ROM_TEXT=0x10000000
+CONFIG_ZBOOT_ROM_BSS=0x20040000
+CONFIG_ZBOOT_ROM=y
+CONFIG_CMDLINE="console=ttyS0,115200 root=/dev/ram rw initrd=0x20210000,654933"
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+CONFIG_FPE_NWFPE=y
+# CONFIG_FPE_NWFPE_XP is not set
+
+#
+# Userspace binary formats
+#
+CONFIG_BINFMT_ELF=y
+CONFIG_BINFMT_AOUT=y
+CONFIG_BINFMT_MISC=y
+# CONFIG_ARTHUR is not set
+
+#
+# Power management options
+#
+# CONFIG_PM 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=y
+
+#
+# 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=y
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+CONFIG_BLK_DEV_NBD=y
+# CONFIG_BLK_DEV_UB is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=4096
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_CDROM_PKTCDVD is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_ATA_OVER_ETH is not set
+
+#
+# SCSI device support
+#
+CONFIG_SCSI=y
+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=y
+# CONFIG_CHR_DEV_SCH is not set
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+# CONFIG_SCSI_MULTI_LUN is not set
+# CONFIG_SCSI_CONSTANTS is not set
+# CONFIG_SCSI_LOGGING is not set
+
+#
+# SCSI Transport Attributes
+#
+# CONFIG_SCSI_SPI_ATTRS is not set
+# CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
+
+#
+# SCSI low-level drivers
+#
+# CONFIG_SCSI_SATA is not set
+# CONFIG_SCSI_DEBUG 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
+#
+
+#
+# Networking support
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+# CONFIG_IP_PNP_BOOTP is not set
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_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_TUNNEL is not set
+# CONFIG_IP_TCPDIAG is not set
+# CONFIG_IP_TCPDIAG_IPV6 is not set
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
+# CONFIG_IPV6 is not set
+# CONFIG_NETFILTER 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
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+# CONFIG_NET_CLS_ROUTE is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+CONFIG_ARM_AT91_ETHER=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
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+
+#
+# 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 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_RAW is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_AT91=y
+CONFIG_SERIAL_AT91_CONSOLE=y
+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 is not set
+# CONFIG_NVRAM is not set
+# CONFIG_RTC is not set
+# CONFIG_AT91_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_AT91_SPI is not set
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# Misc devices
+#
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# Digital Video Broadcasting Devices
+#
+# CONFIG_DVB is not set
+
+#
+# Graphics support
+#
+# CONFIG_FB is not set
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
+#
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB=y
+CONFIG_USB_DEBUG=y
+
+#
+# Miscellaneous USB options
+#
+CONFIG_USB_DEVICEFS=y
+
+#
+# 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_BLUETOOTH_TTY is not set
+# 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=y
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_DPCM 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_MTOUCH is not set
+# CONFIG_USB_ITMTOUCH is not set
+# CONFIG_USB_EGALAX is not set
+# CONFIG_USB_XPAD is not set
+# CONFIG_USB_ATI_REMOTE is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MICROTEK is not set
+
+#
+# USB Multimedia devices
+#
+# CONFIG_USB_DABUSB is not set
+
+#
+# Video4Linux support is needed for USB Multimedia device support
+#
+
+#
+# USB Network Adapters
+#
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_USBNET is not set
+# CONFIG_USB_MON is not set
+
+#
+# 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_LCD is not set
+# CONFIG_USB_LED is not set
+# CONFIG_USB_CYTHERM is not set
+# CONFIG_USB_PHIDGETKIT is not set
+# CONFIG_USB_PHIDGETSERVO is not set
+# CONFIG_USB_IDMOUSE is not set
+
+#
+# USB DSL modem support
+#
+
+#
+# USB Gadget Support
+#
+# CONFIG_USB_GADGET is not set
+
+#
+# MMC/SD Card support
+#
+# CONFIG_MMC is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+# CONFIG_EXT2_FS_POSIX_ACL is not set
+# CONFIG_EXT2_FS_SECURITY is not set
+# CONFIG_EXT2_FS_XIP is not set
+CONFIG_EXT3_FS=y
+CONFIG_EXT3_FS_XATTR=y
+# CONFIG_EXT3_FS_POSIX_ACL is not set
+# CONFIG_EXT3_FS_SECURITY 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
+
+#
+# XFS support
+#
+# CONFIG_XFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_QUOTA is not set
+CONFIG_DNOTIFY=y
+CONFIG_AUTOFS_FS=y
+CONFIG_AUTOFS4_FS=y
+
+#
+# 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=y
+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_SYSFS=y
+CONFIG_DEVPTS_FS_XATTR=y
+# CONFIG_DEVPTS_FS_SECURITY is not set
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_XATTR is not set
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_RAMFS=y
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_HFSPLUS_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
+
+#
+# Network File Systems
+#
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
+# CONFIG_NFSD is not set
+CONFIG_ROOT_NFS=y
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_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="utf8"
+CONFIG_NLS_CODEPAGE_437=y
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+CONFIG_NLS_ASCII=y
+# CONFIG_NLS_ISO8859_1 is not set
+# 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
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_MAGIC_SYSRQ is not set
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_KOBJECT is not set
+CONFIG_DEBUG_BUGVERBOSE=y
+# CONFIG_DEBUG_INFO is not set
+# CONFIG_DEBUG_FS is not set
+CONFIG_FRAME_POINTER=y
+CONFIG_DEBUG_USER=y
+# CONFIG_DEBUG_WAITQ is not set
+CONFIG_DEBUG_ERRORS=y
+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
+
+#
+# Hardware crypto devices
+#
+
+#
+# Library routines
+#
+# CONFIG_CRC_CCITT is not set
+CONFIG_CRC32=y
+# CONFIG_LIBCRC32C is not set
diff --git a/arch/arm/configs/lpd270_defconfig b/arch/arm/configs/lpd270_defconfig
new file mode 100644
index 000000000..4b29e0996
--- /dev/null
+++ b/arch/arm/configs/lpd270_defconfig
@@ -0,0 +1,981 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.18-rc1
+# Sun Jul  9 14:15:23 2006
+#
+CONFIG_ARM=y
+CONFIG_MMU=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_ARCH_MTD_XIP=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_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+# CONFIG_AUDIT is not set
+# CONFIG_IKCONFIG is not set
+# CONFIG_RELAY is not set
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_UID16=y
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+# CONFIG_EMBEDDED 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_RT_MUTEXES=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SHMEM=y
+CONFIG_SLAB=y
+CONFIG_VM_EVENT_COUNTERS=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 is not set
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+# CONFIG_KMOD is not set
+
+#
+# Block layer
+#
+# CONFIG_BLK_DEV_IO_TRACE is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+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 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_IOP3XX 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=y
+# 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
+
+#
+# Intel PXA2xx Implementations
+#
+# CONFIG_ARCH_LUBBOCK is not set
+CONFIG_MACH_LOGICPD_PXA270=y
+# CONFIG_MACH_MAINSTONE is not set
+# CONFIG_ARCH_PXA_IDP is not set
+# CONFIG_PXA_SHARPSL is not set
+# CONFIG_MACH_TRIZEPS4 is not set
+CONFIG_PXA27x=y
+CONFIG_IWMMXT=y
+
+#
+# Processor Type
+#
+CONFIG_CPU_32=y
+CONFIG_CPU_XSCALE=y
+CONFIG_CPU_32v5=y
+CONFIG_CPU_ABRT_EV5T=y
+CONFIG_CPU_CACHE_VIVT=y
+CONFIG_CPU_TLB_V4WBI=y
+
+#
+# Processor Features
+#
+# CONFIG_ARM_THUMB is not set
+CONFIG_XSCALE_PMU=y
+
+#
+# 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="root=/dev/nfs ip=bootp console=ttyS0,115200 mem=64M"
+# 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
+
+#
+# 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 is not set
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+# 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 is not set
+# 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=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
+# 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_NET_DIVERT 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=y
+CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1
+# CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED is not set
+# CONFIG_MTD_REDBOOT_PARTS_READONLY is not set
+# CONFIG_MTD_CMDLINE_PARTS is not set
+# CONFIG_MTD_AFS_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=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
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=y
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_GEN_PROBE=y
+CONFIG_MTD_CFI_ADV_OPTIONS=y
+CONFIG_MTD_CFI_NOSWAP=y
+# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set
+# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set
+CONFIG_MTD_CFI_GEOMETRY=y
+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 is not set
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+# CONFIG_MTD_OTP is not set
+CONFIG_MTD_CFI_INTELEXT=y
+# CONFIG_MTD_CFI_AMDSTD is not set
+# CONFIG_MTD_CFI_STAA is not set
+CONFIG_MTD_CFI_UTIL=y
+# 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
+# CONFIG_MTD_XIP is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+# CONFIG_MTD_PHYSMAP is not set
+# CONFIG_MTD_ARM_INTEGRATOR is not set
+# CONFIG_MTD_SHARP_SL is not set
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# 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 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 is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_RAM is not set
+# CONFIG_BLK_DEV_INITRD is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+CONFIG_IDE=y
+CONFIG_BLK_DEV_IDE=y
+
+#
+# Please see Documentation/ide.txt for help/info on IDE drives
+#
+# CONFIG_BLK_DEV_IDE_SATA is not set
+CONFIG_BLK_DEV_IDEDISK=y
+# CONFIG_IDEDISK_MULTI_MODE is not set
+# CONFIG_BLK_DEV_IDECD is not set
+# CONFIG_BLK_DEV_IDETAPE is not set
+# CONFIG_BLK_DEV_IDEFLOPPY is not set
+# CONFIG_IDE_TASK_IOCTL is not set
+
+#
+# IDE chipset support/bugfixes
+#
+# CONFIG_IDE_GENERIC is not set
+# CONFIG_IDE_ARM is not set
+# CONFIG_BLK_DEV_IDEDMA is not set
+# CONFIG_IDEDMA_AUTO is not set
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+# CONFIG_SCSI 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=y
+# CONFIG_DM9000 is not set
+# CONFIG_SMC911X 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
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
+CONFIG_INPUT_MOUSEDEV_PSAUX=y
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_TSDEV is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+CONFIG_KEYBOARD_ATKBD=y
+# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_KEYBOARD_LKKBD is not set
+# CONFIG_KEYBOARD_XTKBD is not set
+# CONFIG_KEYBOARD_NEWTON 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 is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_PXA=y
+CONFIG_SERIAL_PXA_CONSOLE=y
+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 is not set
+# CONFIG_HW_RANDOM is not set
+# 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
+
+#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+# CONFIG_TELCLOCK 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
+#
+
+#
+# Hardware Monitoring support
+#
+CONFIG_HWMON=y
+# CONFIG_HWMON_VID is not set
+# CONFIG_SENSORS_ABITUGURU is not set
+# CONFIG_SENSORS_F71805F is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
+
+#
+# Misc devices
+#
+
+#
+# LED devices
+#
+# CONFIG_NEW_LEDS is not set
+
+#
+# LED drivers
+#
+
+#
+# LED Triggers
+#
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+CONFIG_VIDEO_V4L2=y
+
+#
+# Digital Video Broadcasting Devices
+#
+# CONFIG_DVB is not set
+
+#
+# Graphics support
+#
+# CONFIG_FIRMWARE_EDID is not set
+CONFIG_FB=y
+CONFIG_FB_CFB_FILLRECT=y
+CONFIG_FB_CFB_COPYAREA=y
+CONFIG_FB_CFB_IMAGEBLIT=y
+# 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_PXA=y
+# CONFIG_FB_PXA_PARAMETERS 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=y
+# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
+# CONFIG_FONTS is not set
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
+
+#
+# Logo configuration
+#
+CONFIG_LOGO=y
+CONFIG_LOGO_LINUX_MONO=y
+CONFIG_LOGO_LINUX_VGA16=y
+CONFIG_LOGO_LINUX_CLUT224=y
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Sound
+#
+CONFIG_SOUND=y
+
+#
+# Advanced Linux Sound Architecture
+#
+CONFIG_SND=y
+CONFIG_SND_TIMER=y
+CONFIG_SND_PCM=y
+# CONFIG_SND_SEQUENCER is not set
+# CONFIG_SND_MIXER_OSS is not set
+# CONFIG_SND_PCM_OSS is not set
+# CONFIG_SND_DYNAMIC_MINORS is not set
+# CONFIG_SND_SUPPORT_OLD_API is not set
+CONFIG_SND_VERBOSE_PROCFS=y
+# CONFIG_SND_VERBOSE_PRINTK is not set
+# CONFIG_SND_DEBUG is not set
+
+#
+# Generic devices
+#
+CONFIG_SND_AC97_CODEC=y
+CONFIG_SND_AC97_BUS=y
+# CONFIG_SND_DUMMY is not set
+# CONFIG_SND_MTPAV is not set
+# CONFIG_SND_SERIAL_U16550 is not set
+# CONFIG_SND_MPU401 is not set
+
+#
+# ALSA ARM devices
+#
+CONFIG_SND_PXA2XX_PCM=y
+CONFIG_SND_PXA2XX_AC97=y
+
+#
+# Open Sound System
+#
+# CONFIG_SOUND_PRIME is not set
+
+#
+# USB support
+#
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+# 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_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_OCFS2_FS is not set
+# CONFIG_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=y
+# CONFIG_VFAT_FS is not set
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_SYSFS=y
+# CONFIG_TMPFS 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_JFFS_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 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
+
+#
+# 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_CIFS_DEBUG2 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 is not set
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ASCII is not set
+CONFIG_NLS_ISO8859_1=y
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_UTF8 is not set
+
+#
+# Profiling support
+#
+# CONFIG_PROFILING is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_UNUSED_SYMBOLS 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=y
+# CONFIG_DEBUG_FS is not set
+# CONFIG_DEBUG_VM is not set
+CONFIG_FRAME_POINTER=y
+# CONFIG_UNWIND_INFO is not set
+CONFIG_FORCED_INLINING=y
+# CONFIG_RCU_TORTURE_TEST is not set
+CONFIG_DEBUG_USER=y
+# CONFIG_DEBUG_WAITQ is not set
+CONFIG_DEBUG_ERRORS=y
+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
+
+#
+# Hardware crypto devices
+#
+
+#
+# Library routines
+#
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
+CONFIG_CRC32=y
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_PLIST=y
diff --git a/arch/arm/configs/netx_defconfig b/arch/arm/configs/netx_defconfig
new file mode 100644
index 000000000..61115a773
--- /dev/null
+++ b/arch/arm/configs/netx_defconfig
@@ -0,0 +1,926 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.17-rc6
+# Tue Jun  6 15:26:53 2006
+#
+CONFIG_ARM=y
+CONFIG_MMU=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_VECTORS_BASE=0xffff0000
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_BSD_PROCESS_ACCT=y
+# CONFIG_BSD_PROCESS_ACCT_V3 is not set
+CONFIG_SYSCTL=y
+# CONFIG_AUDIT is not set
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+# CONFIG_RELAY is not set
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_UID16=y
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+# CONFIG_EMBEDDED 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_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+# CONFIG_SLOB is not set
+CONFIG_OBSOLETE_INTERMODULE=y
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODULE_FORCE_UNLOAD=y
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_KMOD=y
+
+#
+# Block layer
+#
+# CONFIG_BLK_DEV_IO_TRACE is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+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_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_INTEGRATOR is not set
+# CONFIG_ARCH_IOP3XX 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_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
+# CONFIG_ARCH_VERSATILE is not set
+# CONFIG_ARCH_REALVIEW is not set
+# CONFIG_ARCH_IMX is not set
+# CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_AAEC2000 is not set
+# CONFIG_ARCH_AT91RM9200 is not set
+CONFIG_ARCH_NETX=y
+
+#
+# NetX Implementations
+#
+CONFIG_MACH_NXDKN=y
+CONFIG_MACH_NXDB500=y
+CONFIG_MACH_NXEB500HMI=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
+
+#
+# Processor Features
+#
+CONFIG_ARM_THUMB=y
+# 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
+CONFIG_ARM_VIC=y
+
+#
+# Bus support
+#
+CONFIG_ARM_AMBA=y
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# Kernel Features
+#
+CONFIG_PREEMPT=y
+# 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_ALIGNMENT_TRAP=y
+
+#
+# Boot options
+#
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="console=ttySMX0,115200"
+# CONFIG_XIP_KERNEL is not set
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+# CONFIG_FPE_NWFPE 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=y
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=m
+CONFIG_NET_KEY=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+# CONFIG_IP_PNP_BOOTP is not set
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+CONFIG_NET_IPGRE=m
+# CONFIG_NET_IPGRE_BROADCAST is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+CONFIG_SYN_COOKIES=y
+CONFIG_INET_AH=y
+CONFIG_INET_ESP=y
+CONFIG_INET_IPCOMP=y
+CONFIG_INET_XFRM_TUNNEL=y
+CONFIG_INET_TUNNEL=y
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
+
+#
+# IP: Virtual Server Configuration
+#
+# CONFIG_IP_VS is not set
+CONFIG_IPV6=m
+# CONFIG_IPV6_PRIVACY is not set
+# CONFIG_IPV6_ROUTER_PREF is not set
+CONFIG_INET6_AH=m
+CONFIG_INET6_ESP=m
+CONFIG_INET6_IPCOMP=m
+CONFIG_INET6_XFRM_TUNNEL=m
+CONFIG_INET6_TUNNEL=m
+# CONFIG_IPV6_TUNNEL is not set
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_DEBUG is not set
+
+#
+# Core Netfilter Configuration
+#
+# CONFIG_NETFILTER_NETLINK is not set
+# CONFIG_NETFILTER_XTABLES is not set
+
+#
+# IP: Netfilter Configuration
+#
+CONFIG_IP_NF_CONNTRACK=m
+# CONFIG_IP_NF_CT_ACCT is not set
+# CONFIG_IP_NF_CONNTRACK_MARK is not set
+# CONFIG_IP_NF_CONNTRACK_EVENTS is not set
+# 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 is not set
+# CONFIG_IP_NF_H323 is not set
+CONFIG_IP_NF_QUEUE=m
+
+#
+# IPv6: Netfilter Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP6_NF_QUEUE 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_NET_DIVERT 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=m
+# 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=y
+# CONFIG_DEBUG_DRIVER 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_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=y
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_GEN_PROBE=y
+# CONFIG_MTD_CFI_ADV_OPTIONS 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_CFI_INTELEXT=y
+# CONFIG_MTD_CFI_AMDSTD is not set
+# CONFIG_MTD_CFI_STAA is not set
+CONFIG_MTD_CFI_UTIL=y
+CONFIG_MTD_RAM=y
+# 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_PHYSMAP is not set
+# CONFIG_MTD_ARM_INTEGRATOR is not set
+CONFIG_MTD_PLATRAM=y
+
+#
+# Self-contained MTD device drivers
+#
+# 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 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=m
+CONFIG_BLK_DEV_CRYPTOLOOP=m
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_RAM is not set
+# CONFIG_BLK_DEV_INITRD is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+# CONFIG_SCSI 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_NET_NETX=y
+# 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
+
+#
+# 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 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=y
+# CONFIG_SERIO_AMBAKMI is not set
+# 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_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+# CONFIG_SERIAL_AMBA_PL010 is not set
+# CONFIG_SERIAL_AMBA_PL011 is not set
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_SERIAL_NETX=y
+CONFIG_SERIAL_NETX_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 is not set
+CONFIG_NVRAM=m
+# 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
+#
+# 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
+#
+
+#
+# LED devices
+#
+# CONFIG_NEW_LEDS is not set
+
+#
+# LED drivers
+#
+
+#
+# LED Triggers
+#
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+CONFIG_VIDEO_V4L2=y
+
+#
+# Digital Video Broadcasting Devices
+#
+# CONFIG_DVB is not set
+
+#
+# Graphics support
+#
+CONFIG_FB=y
+CONFIG_FB_CFB_FILLRECT=y
+CONFIG_FB_CFB_COPYAREA=y
+CONFIG_FB_CFB_IMAGEBLIT=y
+# CONFIG_FB_MACMODES is not set
+CONFIG_FB_FIRMWARE_EDID=y
+# CONFIG_FB_MODE_HELPERS is not set
+# CONFIG_FB_TILEBLITTING is not set
+CONFIG_FB_ARMCLCD=y
+# 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=y
+# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
+# CONFIG_FONTS is not set
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
+
+#
+# Logo configuration
+#
+CONFIG_LOGO=y
+CONFIG_LOGO_LINUX_MONO=y
+CONFIG_LOGO_LINUX_VGA16=y
+CONFIG_LOGO_LINUX_CLUT224=y
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# 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=m
+
+#
+# RTC interfaces
+#
+CONFIG_RTC_INTF_SYSFS=m
+CONFIG_RTC_INTF_PROC=m
+CONFIG_RTC_INTF_DEV=m
+
+#
+# RTC drivers
+#
+# CONFIG_RTC_DRV_M48T86 is not set
+CONFIG_RTC_DRV_NETX=m
+# CONFIG_RTC_DRV_TEST is not set
+
+#
+# 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_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
+# 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_MSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# 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_JFFS_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_COMPRESSION_OPTIONS is not set
+CONFIG_JFFS2_ZLIB=y
+CONFIG_JFFS2_RTIME=y
+# CONFIG_JFFS2_RUBIN 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
+
+#
+# Network File Systems
+#
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
+CONFIG_NFS_V4=y
+CONFIG_NFS_DIRECTIO=y
+# CONFIG_NFSD is not set
+CONFIG_ROOT_NFS=y
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+CONFIG_SUNRPC_GSS=y
+CONFIG_RPCSEC_GSS_KRB5=y
+# 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 is not set
+
+#
+# Profiling support
+#
+# CONFIG_PROFILING is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_KERNEL=y
+CONFIG_LOG_BUF_SHIFT=17
+CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_DEBUG_SLAB is not set
+CONFIG_DEBUG_PREEMPT=y
+# CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_KOBJECT is not set
+CONFIG_DEBUG_BUGVERBOSE=y
+# CONFIG_DEBUG_INFO is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_DEBUG_VM is not set
+CONFIG_FRAME_POINTER=y
+# CONFIG_UNWIND_INFO is not set
+CONFIG_FORCED_INLINING=y
+# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_DEBUG_USER is not set
+# CONFIG_DEBUG_WAITQ is not set
+CONFIG_DEBUG_ERRORS=y
+# CONFIG_DEBUG_LL is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+
+#
+# Cryptographic options
+#
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_NULL=m
+CONFIG_CRYPTO_MD4=m
+CONFIG_CRYPTO_MD5=y
+CONFIG_CRYPTO_SHA1=y
+CONFIG_CRYPTO_SHA256=m
+CONFIG_CRYPTO_SHA512=m
+# CONFIG_CRYPTO_WP512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+CONFIG_CRYPTO_DES=y
+CONFIG_CRYPTO_BLOWFISH=m
+CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_SERPENT=m
+CONFIG_CRYPTO_AES=m
+CONFIG_CRYPTO_CAST5=m
+CONFIG_CRYPTO_CAST6=m
+# CONFIG_CRYPTO_TEA is not set
+CONFIG_CRYPTO_ARC4=m
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+CONFIG_CRYPTO_DEFLATE=y
+CONFIG_CRYPTO_MICHAEL_MIC=m
+CONFIG_CRYPTO_CRC32C=m
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Hardware crypto devices
+#
+
+#
+# Library routines
+#
+CONFIG_CRC_CCITT=m
+# CONFIG_CRC16 is not set
+CONFIG_CRC32=y
+CONFIG_LIBCRC32C=m
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
diff --git a/arch/arm/configs/onearm_defconfig b/arch/arm/configs/onearm_defconfig
new file mode 100644
index 000000000..6a93e3aae
--- /dev/null
+++ b/arch/arm/configs/onearm_defconfig
@@ -0,0 +1,1076 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.18-rc1
+# Sun Jul  9 14:16:20 2006
+#
+CONFIG_ARM=y
+CONFIG_MMU=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_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 is not set
+CONFIG_SYSVIPC=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+# CONFIG_AUDIT is not set
+# CONFIG_IKCONFIG is not set
+# CONFIG_RELAY is not set
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_UID16=y
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_EMBEDDED=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_RT_MUTEXES=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SHMEM=y
+CONFIG_SLAB=y
+CONFIG_VM_EVENT_COUNTERS=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_BLK_DEV_IO_TRACE 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_IOP3XX 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
+#
+
+#
+# Atmel AT91 Processors
+#
+CONFIG_ARCH_AT91RM9200=y
+# CONFIG_ARCH_AT91SAM9260 is not set
+# CONFIG_ARCH_AT91SAM9261 is not set
+
+#
+# AT91RM9200 Board Type
+#
+CONFIG_MACH_ONEARM=y
+# CONFIG_ARCH_AT91RM9200DK is not set
+# CONFIG_MACH_AT91RM9200EK is not set
+# CONFIG_MACH_CSB337 is not set
+# CONFIG_MACH_CSB637 is not set
+# CONFIG_MACH_CARMEVA is not set
+# CONFIG_MACH_ATEB9200 is not set
+# CONFIG_MACH_KB9200 is not set
+# CONFIG_MACH_KAFA is not set
+
+#
+# AT91 Feature Selections
+#
+CONFIG_AT91_PROGRAMMABLE_CLOCKS=y
+
+#
+# Processor Type
+#
+CONFIG_CPU_32=y
+CONFIG_CPU_ARM920T=y
+CONFIG_CPU_32v4=y
+CONFIG_CPU_ABRT_EV4T=y
+CONFIG_CPU_CACHE_V4WT=y
+CONFIG_CPU_CACHE_VIVT=y
+CONFIG_CPU_COPY_V4WB=y
+CONFIG_CPU_TLB_V4WBI=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
+
+#
+# Bus support
+#
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+CONFIG_PCCARD=y
+# CONFIG_PCMCIA_DEBUG is not set
+CONFIG_PCMCIA=y
+CONFIG_PCMCIA_LOAD_CIS=y
+CONFIG_PCMCIA_IOCTL=y
+
+#
+# PC-card bridges
+#
+CONFIG_AT91_CF=y
+
+#
+# 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=y
+CONFIG_LEDS_TIMER=y
+# CONFIG_LEDS_CPU is not set
+CONFIG_ALIGNMENT_TRAP=y
+
+#
+# Boot options
+#
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="console=ttyS0,115200 root=/dev/nfs ip=bootp mem=64M"
+# 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
+
+#
+# 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_XFRM=y
+# CONFIG_XFRM_USER is not set
+# 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 is not set
+# 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=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
+# 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_NET_DIVERT 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=y
+# 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_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=y
+CONFIG_MTD_JEDECPROBE=y
+CONFIG_MTD_GEN_PROBE=y
+# CONFIG_MTD_CFI_ADV_OPTIONS 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_CFI_INTELEXT is not set
+CONFIG_MTD_CFI_AMDSTD=y
+# CONFIG_MTD_CFI_STAA is not set
+CONFIG_MTD_CFI_UTIL=y
+# 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_PHYSMAP=y
+CONFIG_MTD_PHYSMAP_START=0x0
+CONFIG_MTD_PHYSMAP_LEN=0x0
+CONFIG_MTD_PHYSMAP_BANKWIDTH=0
+# CONFIG_MTD_ARM_INTEGRATOR is not set
+# CONFIG_MTD_IMPA7 is not set
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# 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 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 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_INITRD=y
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+# CONFIG_SCSI 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_ARM_AT91_ETHER=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
+
+#
+# PCMCIA network device support
+#
+# CONFIG_NET_PCMCIA 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
+
+#
+# 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 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 is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+# CONFIG_VT is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_AT91=y
+CONFIG_SERIAL_AT91_CONSOLE=y
+# CONFIG_SERIAL_AT91_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
+CONFIG_AT91_WATCHDOG=y
+
+#
+# USB-based Watchdog Cards
+#
+# CONFIG_USBPCWATCHDOG is not set
+# CONFIG_HW_RANDOM is not set
+# CONFIG_NVRAM is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+
+#
+# PCMCIA character devices
+#
+# CONFIG_SYNCLINK_CS is not set
+# CONFIG_CARDMAN_4000 is not set
+# CONFIG_CARDMAN_4040 is not set
+# CONFIG_RAW_DRIVER is not set
+
+#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+# CONFIG_TELCLOCK 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_OCORES is not set
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_STUB 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 is not set
+# CONFIG_SPI_MASTER is not set
+
+#
+# Dallas's 1-wire bus
+#
+
+#
+# Hardware Monitoring support
+#
+CONFIG_HWMON=y
+# CONFIG_HWMON_VID is not set
+# CONFIG_SENSORS_ABITUGURU is not set
+# CONFIG_SENSORS_ADM1021 is not set
+# CONFIG_SENSORS_ADM1025 is not set
+# CONFIG_SENSORS_ADM1026 is not set
+# CONFIG_SENSORS_ADM1031 is not set
+# CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ASB100 is not set
+# CONFIG_SENSORS_ATXP1 is not set
+# CONFIG_SENSORS_DS1621 is not set
+# CONFIG_SENSORS_F71805F is not set
+# CONFIG_SENSORS_FSCHER is not set
+# CONFIG_SENSORS_FSCPOS is not set
+# CONFIG_SENSORS_GL518SM is not set
+# CONFIG_SENSORS_GL520SM is not set
+# CONFIG_SENSORS_IT87 is not set
+# CONFIG_SENSORS_LM63 is not set
+# CONFIG_SENSORS_LM75 is not set
+# CONFIG_SENSORS_LM77 is not set
+# CONFIG_SENSORS_LM78 is not set
+# CONFIG_SENSORS_LM80 is not set
+# CONFIG_SENSORS_LM83 is not set
+# CONFIG_SENSORS_LM85 is not set
+# CONFIG_SENSORS_LM87 is not set
+# CONFIG_SENSORS_LM90 is not set
+# CONFIG_SENSORS_LM92 is not set
+# CONFIG_SENSORS_MAX1619 is not set
+# CONFIG_SENSORS_PC87360 is not set
+# CONFIG_SENSORS_SMSC47M1 is not set
+# CONFIG_SENSORS_SMSC47M192 is not set
+# CONFIG_SENSORS_SMSC47B397 is not set
+# CONFIG_SENSORS_W83781D is not set
+# CONFIG_SENSORS_W83791D is not set
+# CONFIG_SENSORS_W83792D 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
+#
+
+#
+# LED devices
+#
+# CONFIG_NEW_LEDS is not set
+
+#
+# LED drivers
+#
+
+#
+# LED Triggers
+#
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+CONFIG_VIDEO_V4L2=y
+
+#
+# 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 is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# 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=y
+
+#
+# Miscellaneous USB options
+#
+CONFIG_USB_DEVICEFS=y
+# CONFIG_USB_BANDWIDTH is not set
+# CONFIG_USB_DYNAMIC_MINORS 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 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
+
+#
+# USB Network Adapters
+#
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_RTL8150 is not set
+# CONFIG_USB_USBNET is not set
+CONFIG_USB_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_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_CYTHERM is not set
+# CONFIG_USB_PHIDGETKIT is not set
+# CONFIG_USB_PHIDGETSERVO is not set
+# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_APPLEDISPLAY is not set
+# CONFIG_USB_LD 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 is not set
+# CONFIG_USB_ETH is not set
+# CONFIG_USB_GADGETFS is not set
+# CONFIG_USB_FILE_STORAGE is not set
+# CONFIG_USB_G_SERIAL is not set
+
+#
+# MMC/SD Card support
+#
+CONFIG_MMC=y
+# CONFIG_MMC_DEBUG is not set
+CONFIG_MMC_BLOCK=y
+CONFIG_MMC_AT91RM9200=y
+
+#
+# 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_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+CONFIG_FS_POSIX_ACL=y
+# CONFIG_XFS_FS is not set
+# CONFIG_OCFS2_FS is not set
+# CONFIG_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_MSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# 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_JFFS_FS is not set
+# CONFIG_JFFS2_FS 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=y
+CONFIG_NFS_V3_ACL=y
+# 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_LOCKD_V4=y
+CONFIG_NFS_ACL_SUPPORT=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_CIFS_DEBUG2 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 is not set
+
+#
+# Profiling support
+#
+# CONFIG_PROFILING is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_UNUSED_SYMBOLS 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_FS is not set
+# CONFIG_DEBUG_VM is not set
+CONFIG_FRAME_POINTER=y
+# CONFIG_UNWIND_INFO is not set
+CONFIG_FORCED_INLINING=y
+# CONFIG_RCU_TORTURE_TEST is not set
+CONFIG_DEBUG_USER=y
+# CONFIG_DEBUG_WAITQ is not set
+# 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
+
+#
+# Hardware crypto devices
+#
+
+#
+# Library routines
+#
+# 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
diff --git a/arch/arm/configs/pnx4008_defconfig b/arch/arm/configs/pnx4008_defconfig
new file mode 100644
index 000000000..a4989f44b
--- /dev/null
+++ b/arch/arm/configs/pnx4008_defconfig
@@ -0,0 +1,1665 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.18-rc6
+# Mon Sep 11 13:59:24 2006
+#
+CONFIG_ARM=y
+CONFIG_MMU=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_VECTORS_BASE=0xffff0000
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_BSD_PROCESS_ACCT=y
+# CONFIG_BSD_PROCESS_ACCT_V3 is not set
+# CONFIG_TASKSTATS is not set
+CONFIG_SYSCTL=y
+CONFIG_AUDIT=y
+# CONFIG_IKCONFIG is not set
+# CONFIG_RELAY is not set
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_UID16=y
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_EMBEDDED=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_RT_MUTEXES=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SHMEM=y
+CONFIG_SLAB=y
+CONFIG_VM_EVENT_COUNTERS=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_BLK_DEV_IO_TRACE is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+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 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_IOP3XX 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=y
+# 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
+
+#
+# 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
+
+#
+# Processor Features
+#
+CONFIG_ARM_THUMB=y
+# 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=y
+# 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="mem=64M console=ttyS0,115200"
+# 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=m
+CONFIG_BINFMT_MISC=m
+# CONFIG_ARTHUR is not set
+
+#
+# Power management options
+#
+CONFIG_PM=y
+CONFIG_PM_LEGACY=y
+# CONFIG_PM_DEBUG 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=y
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_ASK_IP_FIB_HASH=y
+# 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
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+CONFIG_IP_MROUTE=y
+CONFIG_IP_PIMSM_V1=y
+CONFIG_IP_PIMSM_V2=y
+# CONFIG_ARPD is not set
+CONFIG_SYN_COOKIES=y
+CONFIG_INET_AH=m
+CONFIG_INET_ESP=m
+CONFIG_INET_IPCOMP=m
+CONFIG_INET_XFRM_TUNNEL=m
+CONFIG_INET_TUNNEL=m
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
+
+#
+# IP: Virtual Server Configuration
+#
+CONFIG_IP_VS=m
+# CONFIG_IP_VS_DEBUG is not set
+CONFIG_IP_VS_TAB_BITS=12
+
+#
+# IPVS transport protocol load balancing support
+#
+CONFIG_IP_VS_PROTO_TCP=y
+CONFIG_IP_VS_PROTO_UDP=y
+CONFIG_IP_VS_PROTO_ESP=y
+CONFIG_IP_VS_PROTO_AH=y
+
+#
+# IPVS scheduler
+#
+CONFIG_IP_VS_RR=m
+CONFIG_IP_VS_WRR=m
+CONFIG_IP_VS_LC=m
+CONFIG_IP_VS_WLC=m
+CONFIG_IP_VS_LBLC=m
+CONFIG_IP_VS_LBLCR=m
+CONFIG_IP_VS_DH=m
+CONFIG_IP_VS_SH=m
+CONFIG_IP_VS_SED=m
+CONFIG_IP_VS_NQ=m
+
+#
+# IPVS application helper
+#
+CONFIG_IP_VS_FTP=m
+CONFIG_IPV6=m
+CONFIG_IPV6_PRIVACY=y
+# CONFIG_IPV6_ROUTER_PREF is not set
+CONFIG_INET6_AH=m
+CONFIG_INET6_ESP=m
+CONFIG_INET6_IPCOMP=m
+CONFIG_INET6_XFRM_TUNNEL=m
+CONFIG_INET6_TUNNEL=m
+CONFIG_INET6_XFRM_MODE_TRANSPORT=m
+CONFIG_INET6_XFRM_MODE_TUNNEL=m
+CONFIG_IPV6_TUNNEL=m
+# CONFIG_NETWORK_SECMARK is not set
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_DEBUG is not set
+CONFIG_BRIDGE_NETFILTER=y
+
+#
+# Core Netfilter Configuration
+#
+# CONFIG_NETFILTER_NETLINK is not set
+# CONFIG_NETFILTER_XTABLES is not set
+
+#
+# IP: Netfilter Configuration
+#
+CONFIG_IP_NF_CONNTRACK=m
+CONFIG_IP_NF_CT_ACCT=y
+CONFIG_IP_NF_CONNTRACK_MARK=y
+# CONFIG_IP_NF_CONNTRACK_EVENTS is not set
+CONFIG_IP_NF_CT_PROTO_SCTP=m
+CONFIG_IP_NF_FTP=m
+CONFIG_IP_NF_IRC=m
+# CONFIG_IP_NF_NETBIOS_NS is not set
+CONFIG_IP_NF_TFTP=m
+CONFIG_IP_NF_AMANDA=m
+# CONFIG_IP_NF_PPTP is not set
+# CONFIG_IP_NF_H323 is not set
+# CONFIG_IP_NF_SIP is not set
+CONFIG_IP_NF_QUEUE=m
+
+#
+# IPv6: Netfilter Configuration (EXPERIMENTAL)
+#
+CONFIG_IP6_NF_QUEUE=m
+
+#
+# DECnet: Netfilter Configuration
+#
+CONFIG_DECNET_NF_GRABULATOR=m
+
+#
+# Bridge: Netfilter Configuration
+#
+CONFIG_BRIDGE_NF_EBTABLES=m
+CONFIG_BRIDGE_EBT_BROUTE=m
+CONFIG_BRIDGE_EBT_T_FILTER=m
+CONFIG_BRIDGE_EBT_T_NAT=m
+CONFIG_BRIDGE_EBT_802_3=m
+CONFIG_BRIDGE_EBT_AMONG=m
+CONFIG_BRIDGE_EBT_ARP=m
+CONFIG_BRIDGE_EBT_IP=m
+CONFIG_BRIDGE_EBT_LIMIT=m
+CONFIG_BRIDGE_EBT_MARK=m
+CONFIG_BRIDGE_EBT_PKTTYPE=m
+CONFIG_BRIDGE_EBT_STP=m
+CONFIG_BRIDGE_EBT_VLAN=m
+CONFIG_BRIDGE_EBT_ARPREPLY=m
+CONFIG_BRIDGE_EBT_DNAT=m
+CONFIG_BRIDGE_EBT_MARK_T=m
+CONFIG_BRIDGE_EBT_REDIRECT=m
+CONFIG_BRIDGE_EBT_SNAT=m
+CONFIG_BRIDGE_EBT_LOG=m
+# CONFIG_BRIDGE_EBT_ULOG is not set
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+CONFIG_IP_SCTP=m
+# CONFIG_SCTP_DBG_MSG is not set
+# CONFIG_SCTP_DBG_OBJCNT is not set
+# CONFIG_SCTP_HMAC_NONE is not set
+# CONFIG_SCTP_HMAC_SHA1 is not set
+CONFIG_SCTP_HMAC_MD5=y
+
+#
+# TIPC Configuration (EXPERIMENTAL)
+#
+# CONFIG_TIPC is not set
+CONFIG_ATM=y
+CONFIG_ATM_CLIP=y
+# CONFIG_ATM_CLIP_NO_ICMP is not set
+CONFIG_ATM_LANE=m
+CONFIG_ATM_MPOA=m
+CONFIG_ATM_BR2684=m
+# CONFIG_ATM_BR2684_IPFILTER is not set
+CONFIG_BRIDGE=m
+CONFIG_VLAN_8021Q=m
+CONFIG_DECNET=m
+# CONFIG_DECNET_ROUTER is not set
+CONFIG_LLC=m
+CONFIG_LLC2=m
+CONFIG_IPX=m
+# CONFIG_IPX_INTERN is not set
+CONFIG_ATALK=m
+CONFIG_DEV_APPLETALK=m
+CONFIG_IPDDP=m
+CONFIG_IPDDP_ENCAP=y
+CONFIG_IPDDP_DECAP=y
+CONFIG_X25=m
+CONFIG_LAPB=m
+# CONFIG_NET_DIVERT is not set
+CONFIG_ECONET=m
+CONFIG_ECONET_AUNUDP=y
+CONFIG_ECONET_NATIVE=y
+CONFIG_WAN_ROUTER=m
+
+#
+# QoS and/or fair queueing
+#
+CONFIG_NET_SCHED=y
+CONFIG_NET_SCH_CLK_JIFFIES=y
+# CONFIG_NET_SCH_CLK_GETTIMEOFDAY is not set
+# CONFIG_NET_SCH_CLK_CPU is not set
+
+#
+# Queueing/Scheduling
+#
+CONFIG_NET_SCH_CBQ=m
+CONFIG_NET_SCH_HTB=m
+CONFIG_NET_SCH_HFSC=m
+CONFIG_NET_SCH_ATM=m
+CONFIG_NET_SCH_PRIO=m
+CONFIG_NET_SCH_RED=m
+CONFIG_NET_SCH_SFQ=m
+CONFIG_NET_SCH_TEQL=m
+CONFIG_NET_SCH_TBF=m
+CONFIG_NET_SCH_GRED=m
+CONFIG_NET_SCH_DSMARK=m
+CONFIG_NET_SCH_NETEM=m
+CONFIG_NET_SCH_INGRESS=m
+
+#
+# Classification
+#
+CONFIG_NET_CLS=y
+# CONFIG_NET_CLS_BASIC is not set
+CONFIG_NET_CLS_TCINDEX=m
+CONFIG_NET_CLS_ROUTE4=m
+CONFIG_NET_CLS_ROUTE=y
+CONFIG_NET_CLS_FW=m
+CONFIG_NET_CLS_U32=m
+# CONFIG_CLS_U32_PERF is not set
+# CONFIG_CLS_U32_MARK is not set
+CONFIG_NET_CLS_RSVP=m
+CONFIG_NET_CLS_RSVP6=m
+# CONFIG_NET_EMATCH is not set
+# CONFIG_NET_CLS_ACT is not set
+CONFIG_NET_CLS_POLICE=y
+# CONFIG_NET_CLS_IND is not set
+CONFIG_NET_ESTIMATOR=y
+
+#
+# Network testing
+#
+CONFIG_NET_PKTGEN=m
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+CONFIG_IEEE80211=m
+# CONFIG_IEEE80211_DEBUG is not set
+# CONFIG_IEEE80211_CRYPT_WEP is not set
+CONFIG_IEEE80211_CRYPT_CCMP=m
+CONFIG_IEEE80211_CRYPT_TKIP=m
+# CONFIG_IEEE80211_SOFTMAC is not set
+CONFIG_WIRELESS_EXT=y
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+# 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=y
+CONFIG_MTD_PARTITIONS=y
+CONFIG_MTD_REDBOOT_PARTS=y
+CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1
+# CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED is not set
+# CONFIG_MTD_REDBOOT_PARTS_READONLY is not set
+# CONFIG_MTD_CMDLINE_PARTS is not set
+# CONFIG_MTD_AFS_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=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
+
+#
+# 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 is not set
+# CONFIG_MTD_M25P80 is not set
+CONFIG_MTD_SLRAM=m
+CONFIG_MTD_PHRAM=m
+CONFIG_MTD_MTDRAM=m
+CONFIG_MTDRAM_TOTAL_SIZE=4096
+CONFIG_MTDRAM_ERASE_SIZE=128
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+CONFIG_MTD_DOC2000=m
+CONFIG_MTD_DOC2001=m
+CONFIG_MTD_DOC2001PLUS=m
+CONFIG_MTD_DOCPROBE=m
+CONFIG_MTD_DOCECC=m
+# CONFIG_MTD_DOCPROBE_ADVANCED is not set
+CONFIG_MTD_DOCPROBE_ADDRESS=0
+
+#
+# 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_NANDSIM=m
+
+#
+# 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=y
+CONFIG_BLK_DEV_NBD=y
+# 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=m
+CONFIG_CDROM_PKTCDVD_BUFFERS=8
+# CONFIG_CDROM_PKTCDVD_WCACHE is not set
+# CONFIG_ATA_OVER_ETH is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+CONFIG_SCSI=m
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=m
+CONFIG_CHR_DEV_ST=m
+CONFIG_CHR_DEV_OSST=m
+CONFIG_BLK_DEV_SR=m
+# CONFIG_BLK_DEV_SR_VENDOR is not set
+CONFIG_CHR_DEV_SG=m
+CONFIG_CHR_DEV_SCH=m
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+CONFIG_SCSI_MULTI_LUN=y
+CONFIG_SCSI_CONSTANTS=y
+CONFIG_SCSI_LOGGING=y
+
+#
+# SCSI Transport Attributes
+#
+CONFIG_SCSI_SPI_ATTRS=m
+CONFIG_SCSI_FC_ATTRS=m
+# CONFIG_SCSI_ISCSI_ATTRS is not set
+# CONFIG_SCSI_SAS_ATTRS is not set
+
+#
+# SCSI low-level drivers
+#
+# CONFIG_ISCSI_TCP is not set
+CONFIG_SCSI_SATA=m
+CONFIG_SCSI_DEBUG=m
+
+#
+# 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=m
+CONFIG_BONDING=m
+CONFIG_EQUALIZER=m
+CONFIG_TUN=m
+
+#
+# PHY device support
+#
+# CONFIG_PHYLIB is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=m
+# 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=y
+# CONFIG_NET_WIRELESS_RTNETLINK is not set
+
+#
+# Obsolete Wireless cards support (pre-802.11)
+#
+CONFIG_STRIP=m
+# CONFIG_USB_ZD1201 is not set
+# CONFIG_HOSTAP is not set
+
+#
+# Wan interfaces
+#
+CONFIG_WAN=y
+CONFIG_HDLC=m
+CONFIG_HDLC_RAW=y
+CONFIG_HDLC_RAW_ETH=y
+CONFIG_HDLC_CISCO=y
+CONFIG_HDLC_FR=y
+CONFIG_HDLC_PPP=y
+CONFIG_HDLC_X25=y
+CONFIG_DLCI=m
+CONFIG_DLCI_COUNT=24
+CONFIG_DLCI_MAX=8
+CONFIG_WAN_ROUTER_DRIVERS=y
+CONFIG_LAPBETHER=m
+CONFIG_X25_ASY=m
+
+#
+# ATM drivers
+#
+# CONFIG_ATM_DUMMY is not set
+CONFIG_ATM_TCP=m
+CONFIG_PPP=m
+CONFIG_PPP_MULTILINK=y
+CONFIG_PPP_FILTER=y
+CONFIG_PPP_ASYNC=m
+CONFIG_PPP_SYNC_TTY=m
+CONFIG_PPP_DEFLATE=m
+CONFIG_PPP_BSDCOMP=m
+CONFIG_PPP_MPPE=m
+CONFIG_PPPOE=m
+CONFIG_PPPOATM=m
+CONFIG_SLIP=m
+CONFIG_SLIP_COMPRESSED=y
+CONFIG_SLIP_SMART=y
+CONFIG_SLIP_MODE_SLIP6=y
+CONFIG_SHAPER=m
+CONFIG_NETCONSOLE=m
+CONFIG_NETPOLL=y
+# CONFIG_NETPOLL_RX is not set
+# CONFIG_NETPOLL_TRAP is not set
+CONFIG_NET_POLL_CONTROLLER=y
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+
+#
+# Userland interfaces
+#
+# CONFIG_INPUT_MOUSEDEV is not set
+CONFIG_INPUT_JOYDEV=m
+CONFIG_INPUT_TSDEV=m
+CONFIG_INPUT_TSDEV_SCREEN_X=240
+CONFIG_INPUT_TSDEV_SCREEN_Y=320
+CONFIG_INPUT_EVDEV=m
+CONFIG_INPUT_EVBUG=m
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+CONFIG_KEYBOARD_ATKBD=y
+CONFIG_KEYBOARD_SUNKBD=m
+CONFIG_KEYBOARD_LKKBD=m
+CONFIG_KEYBOARD_XTKBD=m
+CONFIG_KEYBOARD_NEWTON=m
+CONFIG_INPUT_MOUSE=y
+CONFIG_MOUSE_PS2=m
+CONFIG_MOUSE_SERIAL=m
+CONFIG_MOUSE_VSXXXAA=m
+CONFIG_INPUT_JOYSTICK=y
+CONFIG_JOYSTICK_ANALOG=m
+CONFIG_JOYSTICK_A3D=m
+CONFIG_JOYSTICK_ADI=m
+CONFIG_JOYSTICK_COBRA=m
+CONFIG_JOYSTICK_GF2K=m
+CONFIG_JOYSTICK_GRIP=m
+CONFIG_JOYSTICK_GRIP_MP=m
+CONFIG_JOYSTICK_GUILLEMOT=m
+CONFIG_JOYSTICK_INTERACT=m
+CONFIG_JOYSTICK_SIDEWINDER=m
+CONFIG_JOYSTICK_TMDC=m
+CONFIG_JOYSTICK_IFORCE=m
+CONFIG_JOYSTICK_IFORCE_USB=y
+CONFIG_JOYSTICK_IFORCE_232=y
+CONFIG_JOYSTICK_WARRIOR=m
+CONFIG_JOYSTICK_MAGELLAN=m
+CONFIG_JOYSTICK_SPACEORB=m
+CONFIG_JOYSTICK_SPACEBALL=m
+CONFIG_JOYSTICK_STINGER=m
+# CONFIG_JOYSTICK_TWIDJOY is not set
+CONFIG_JOYSTICK_JOYDUMP=m
+CONFIG_INPUT_TOUCHSCREEN=y
+# CONFIG_TOUCHSCREEN_ADS7846 is not set
+CONFIG_TOUCHSCREEN_GUNZE=m
+# CONFIG_TOUCHSCREEN_ELO is not set
+# CONFIG_TOUCHSCREEN_MTOUCH is not set
+# CONFIG_TOUCHSCREEN_MK712 is not set
+CONFIG_INPUT_MISC=y
+CONFIG_INPUT_UINPUT=m
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+CONFIG_SERIO_SERPORT=m
+CONFIG_SERIO_LIBPS2=y
+CONFIG_SERIO_RAW=m
+CONFIG_GAMEPORT=m
+CONFIG_GAMEPORT_NS558=m
+CONFIG_GAMEPORT_L4=m
+
+#
+# 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=y
+CONFIG_SERIAL_8250_SHARE_IRQ=y
+# CONFIG_SERIAL_8250_DETECT_IRQ is not set
+CONFIG_SERIAL_8250_RSA=y
+
+#
+# Non-8250 serial port support
+#
+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 is not set
+
+#
+# Watchdog Device Drivers
+#
+CONFIG_SOFT_WATCHDOG=m
+
+#
+# USB-based Watchdog Cards
+#
+CONFIG_USBPCWATCHDOG=m
+CONFIG_HW_RANDOM=y
+# 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
+
+#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+# CONFIG_TELCLOCK is not set
+
+#
+# I2C support
+#
+CONFIG_I2C=y
+CONFIG_I2C_CHARDEV=y
+
+#
+# I2C Algorithms
+#
+CONFIG_I2C_ALGOBIT=m
+CONFIG_I2C_ALGOPCF=m
+CONFIG_I2C_ALGOPCA=m
+
+#
+# I2C Hardware Bus support
+#
+# CONFIG_I2C_OCORES is not set
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_STUB 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=m
+CONFIG_SENSORS_PCF8574=m
+# CONFIG_SENSORS_PCA9539 is not set
+CONFIG_SENSORS_PCF8591=m
+# 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_BITBANG=y
+
+#
+# SPI Protocol Masters
+#
+
+#
+# Dallas's 1-wire bus
+#
+
+#
+# Hardware Monitoring support
+#
+# CONFIG_HWMON is not set
+# CONFIG_HWMON_VID is not set
+
+#
+# Misc devices
+#
+
+#
+# LED devices
+#
+# CONFIG_NEW_LEDS is not set
+
+#
+# LED drivers
+#
+
+#
+# LED Triggers
+#
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+CONFIG_VIDEO_V4L2=y
+
+#
+# Digital Video Broadcasting Devices
+#
+CONFIG_DVB=y
+CONFIG_DVB_CORE=m
+
+#
+# Supported USB Adapters
+#
+# CONFIG_DVB_USB is not set
+CONFIG_DVB_TTUSB_BUDGET=m
+CONFIG_DVB_TTUSB_DEC=m
+CONFIG_DVB_CINERGYT2=m
+CONFIG_DVB_CINERGYT2_TUNING=y
+CONFIG_DVB_CINERGYT2_STREAM_URB_COUNT=32
+CONFIG_DVB_CINERGYT2_STREAM_BUF_SIZE=512
+CONFIG_DVB_CINERGYT2_QUERY_INTERVAL=250
+CONFIG_DVB_CINERGYT2_ENABLE_RC_INPUT_DEVICE=y
+CONFIG_DVB_CINERGYT2_RC_QUERY_INTERVAL=100
+
+#
+# Supported FlexCopII (B2C2) Adapters
+#
+# CONFIG_DVB_B2C2_FLEXCOP is not set
+
+#
+# Supported DVB Frontends
+#
+
+#
+# Customise DVB Frontends
+#
+
+#
+# DVB-S (satellite) frontends
+#
+CONFIG_DVB_STV0299=m
+CONFIG_DVB_CX24110=m
+# CONFIG_DVB_CX24123 is not set
+CONFIG_DVB_TDA8083=m
+CONFIG_DVB_MT312=m
+CONFIG_DVB_VES1X93=m
+# CONFIG_DVB_S5H1420 is not set
+
+#
+# DVB-T (terrestrial) frontends
+#
+CONFIG_DVB_SP8870=m
+CONFIG_DVB_SP887X=m
+CONFIG_DVB_CX22700=m
+CONFIG_DVB_CX22702=m
+CONFIG_DVB_L64781=m
+CONFIG_DVB_TDA1004X=m
+CONFIG_DVB_NXT6000=m
+CONFIG_DVB_MT352=m
+# CONFIG_DVB_ZL10353 is not set
+CONFIG_DVB_DIB3000MB=m
+CONFIG_DVB_DIB3000MC=m
+
+#
+# DVB-C (cable) frontends
+#
+CONFIG_DVB_VES1820=m
+CONFIG_DVB_TDA10021=m
+CONFIG_DVB_STV0297=m
+
+#
+# ATSC (North American/Korean Terrestrial/Cable DTV) frontends
+#
+# CONFIG_DVB_NXT200X is not set
+# CONFIG_DVB_OR51211 is not set
+# CONFIG_DVB_OR51132 is not set
+# CONFIG_DVB_BCM3510 is not set
+# CONFIG_DVB_LGDT330X is not set
+
+#
+# Miscellaneous devices
+#
+CONFIG_DVB_LNBP21=m
+# CONFIG_DVB_ISL6421 is not set
+# CONFIG_USB_DABUSB is not set
+
+#
+# Graphics support
+#
+CONFIG_FIRMWARE_EDID=y
+# 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=m
+
+#
+# Advanced Linux Sound Architecture
+#
+CONFIG_SND=m
+CONFIG_SND_TIMER=m
+CONFIG_SND_PCM=m
+CONFIG_SND_HWDEP=m
+CONFIG_SND_RAWMIDI=m
+CONFIG_SND_SEQUENCER=m
+CONFIG_SND_SEQ_DUMMY=m
+CONFIG_SND_OSSEMUL=y
+CONFIG_SND_MIXER_OSS=m
+CONFIG_SND_PCM_OSS=m
+CONFIG_SND_PCM_OSS_PLUGINS=y
+CONFIG_SND_SEQUENCER_OSS=y
+# CONFIG_SND_DYNAMIC_MINORS is not set
+CONFIG_SND_SUPPORT_OLD_API=y
+CONFIG_SND_VERBOSE_PROCFS=y
+# CONFIG_SND_VERBOSE_PRINTK is not set
+# CONFIG_SND_DEBUG is not set
+
+#
+# Generic devices
+#
+CONFIG_SND_MPU401_UART=m
+CONFIG_SND_DUMMY=m
+CONFIG_SND_VIRMIDI=m
+CONFIG_SND_MTPAV=m
+CONFIG_SND_SERIAL_U16550=m
+CONFIG_SND_MPU401=m
+
+#
+# ALSA ARM devices
+#
+
+#
+# USB devices
+#
+CONFIG_SND_USB_AUDIO=m
+
+#
+# Open Sound System
+#
+CONFIG_SOUND_PRIME=m
+# CONFIG_OSS_OBSOLETE_DRIVER is not set
+# CONFIG_SOUND_MSNDCLAS is not set
+# CONFIG_SOUND_MSNDPIN is not set
+
+#
+# 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=y
+# CONFIG_USB_DEBUG is not set
+
+#
+# Miscellaneous USB options
+#
+CONFIG_USB_DEVICEFS=y
+CONFIG_USB_BANDWIDTH=y
+# CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_SUSPEND is not set
+# CONFIG_USB_OTG is not set
+
+#
+# USB Host Controller Drivers
+#
+# CONFIG_USB_ISP116X_HCD is not set
+CONFIG_USB_SL811_HCD=m
+
+#
+# USB Device Class drivers
+#
+CONFIG_USB_ACM=m
+CONFIG_USB_PRINTER=m
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+#
+
+#
+# may also be needed; see USB_STORAGE Help for more information
+#
+CONFIG_USB_STORAGE=m
+# CONFIG_USB_STORAGE_DEBUG is not set
+CONFIG_USB_STORAGE_DATAFAB=y
+CONFIG_USB_STORAGE_FREECOM=y
+CONFIG_USB_STORAGE_DPCM=y
+CONFIG_USB_STORAGE_USBAT=y
+CONFIG_USB_STORAGE_SDDR09=y
+CONFIG_USB_STORAGE_SDDR55=y
+CONFIG_USB_STORAGE_JUMPSHOT=y
+# CONFIG_USB_STORAGE_ALAUDA 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=y
+
+#
+# USB HID Boot Protocol drivers
+#
+CONFIG_USB_KBD=m
+CONFIG_USB_MOUSE=m
+CONFIG_USB_AIPTEK=m
+CONFIG_USB_WACOM=m
+# CONFIG_USB_ACECAD is not set
+CONFIG_USB_KBTAB=m
+CONFIG_USB_POWERMATE=m
+# CONFIG_USB_TOUCHSCREEN is not set
+# CONFIG_USB_YEALINK is not set
+CONFIG_USB_XPAD=m
+CONFIG_USB_ATI_REMOTE=m
+# 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=m
+CONFIG_USB_MICROTEK=m
+
+#
+# USB Network Adapters
+#
+CONFIG_USB_CATC=m
+CONFIG_USB_KAWETH=m
+CONFIG_USB_PEGASUS=m
+CONFIG_USB_RTL8150=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_RNDIS_HOST is not set
+# CONFIG_USB_NET_CDC_SUBSET is not set
+CONFIG_USB_NET_ZAURUS=m
+CONFIG_USB_MON=y
+
+#
+# USB port drivers
+#
+
+#
+# USB Serial Converter support
+#
+CONFIG_USB_SERIAL=m
+CONFIG_USB_SERIAL_GENERIC=y
+# CONFIG_USB_SERIAL_AIRPRIME is not set
+# CONFIG_USB_SERIAL_ARK3116 is not set
+CONFIG_USB_SERIAL_BELKIN=m
+CONFIG_USB_SERIAL_WHITEHEAT=m
+CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m
+# CONFIG_USB_SERIAL_CP2101 is not set
+CONFIG_USB_SERIAL_CYPRESS_M8=m
+CONFIG_USB_SERIAL_EMPEG=m
+CONFIG_USB_SERIAL_FTDI_SIO=m
+# CONFIG_USB_SERIAL_FUNSOFT is not set
+CONFIG_USB_SERIAL_VISOR=m
+CONFIG_USB_SERIAL_IPAQ=m
+CONFIG_USB_SERIAL_IR=m
+CONFIG_USB_SERIAL_EDGEPORT=m
+CONFIG_USB_SERIAL_EDGEPORT_TI=m
+# CONFIG_USB_SERIAL_GARMIN is not set
+CONFIG_USB_SERIAL_IPW=m
+CONFIG_USB_SERIAL_KEYSPAN_PDA=m
+CONFIG_USB_SERIAL_KEYSPAN=m
+# CONFIG_USB_SERIAL_KEYSPAN_MPR is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28XA is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28XB is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA19W is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA19QW is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA19QI is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA49W is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA49WLC is not set
+CONFIG_USB_SERIAL_KLSI=m
+CONFIG_USB_SERIAL_KOBIL_SCT=m
+CONFIG_USB_SERIAL_MCT_U232=m
+# CONFIG_USB_SERIAL_NAVMAN is not set
+CONFIG_USB_SERIAL_PL2303=m
+# CONFIG_USB_SERIAL_HP4X is not set
+CONFIG_USB_SERIAL_SAFE=m
+# CONFIG_USB_SERIAL_SAFE_PADDED is not set
+# 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_EZUSB=y
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_EMI62 is not set
+# CONFIG_USB_EMI26 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_CYPRESS_CY7C63 is not set
+CONFIG_USB_CYTHERM=m
+CONFIG_USB_PHIDGETKIT=m
+CONFIG_USB_PHIDGETSERVO=m
+# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_APPLEDISPLAY is not set
+# CONFIG_USB_LD is not set
+CONFIG_USB_TEST=m
+
+#
+# USB DSL modem support
+#
+CONFIG_USB_ATM=m
+CONFIG_USB_SPEEDTOUCH=m
+# CONFIG_USB_CXACRU is not set
+# CONFIG_USB_UEAGLEATM is not set
+# CONFIG_USB_XUSBATM is not set
+
+#
+# USB Gadget Support
+#
+CONFIG_USB_GADGET=m
+# 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 is not set
+CONFIG_USB_GADGET_DUMMY_HCD=y
+CONFIG_USB_DUMMY_HCD=m
+CONFIG_USB_GADGET_DUALSPEED=y
+CONFIG_USB_ZERO=m
+CONFIG_USB_ETH=m
+CONFIG_USB_ETH_RNDIS=y
+CONFIG_USB_GADGETFS=m
+CONFIG_USB_FILE_STORAGE=m
+# CONFIG_USB_FILE_STORAGE_TEST is not set
+CONFIG_USB_G_SERIAL=m
+
+#
+# MMC/SD Card support
+#
+CONFIG_MMC=m
+# CONFIG_MMC_DEBUG is not set
+CONFIG_MMC_BLOCK=m
+
+#
+# Real Time Clock
+#
+CONFIG_RTC_LIB=y
+# CONFIG_RTC_CLASS is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+CONFIG_EXT2_FS_POSIX_ACL=y
+CONFIG_EXT2_FS_SECURITY=y
+# CONFIG_EXT2_FS_XIP is not set
+CONFIG_EXT3_FS=m
+CONFIG_EXT3_FS_XATTR=y
+CONFIG_EXT3_FS_POSIX_ACL=y
+CONFIG_EXT3_FS_SECURITY=y
+CONFIG_JBD=m
+# CONFIG_JBD_DEBUG is not set
+CONFIG_FS_MBCACHE=y
+CONFIG_REISERFS_FS=m
+# CONFIG_REISERFS_CHECK is not set
+# CONFIG_REISERFS_PROC_INFO is not set
+CONFIG_REISERFS_FS_XATTR=y
+CONFIG_REISERFS_FS_POSIX_ACL=y
+CONFIG_REISERFS_FS_SECURITY=y
+CONFIG_JFS_FS=m
+CONFIG_JFS_POSIX_ACL=y
+# CONFIG_JFS_SECURITY is not set
+# CONFIG_JFS_DEBUG is not set
+CONFIG_JFS_STATISTICS=y
+CONFIG_FS_POSIX_ACL=y
+CONFIG_XFS_FS=m
+CONFIG_XFS_QUOTA=y
+CONFIG_XFS_SECURITY=y
+CONFIG_XFS_POSIX_ACL=y
+CONFIG_XFS_RT=y
+# CONFIG_OCFS2_FS is not set
+CONFIG_MINIX_FS=m
+CONFIG_ROMFS_FS=m
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+CONFIG_QUOTA=y
+CONFIG_QFMT_V1=m
+CONFIG_QFMT_V2=m
+CONFIG_QUOTACTL=y
+CONFIG_DNOTIFY=y
+CONFIG_AUTOFS_FS=m
+CONFIG_AUTOFS4_FS=m
+# CONFIG_FUSE_FS is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+CONFIG_ISO9660_FS=m
+CONFIG_JOLIET=y
+CONFIG_ZISOFS=y
+CONFIG_ZISOFS_FS=m
+CONFIG_UDF_FS=m
+CONFIG_UDF_NLS=y
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=m
+CONFIG_MSDOS_FS=m
+CONFIG_VFAT_FS=m
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+CONFIG_NTFS_FS=m
+# CONFIG_NTFS_DEBUG is not set
+# CONFIG_NTFS_RW is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_RAMFS=y
+# CONFIG_CONFIGFS_FS is not set
+
+#
+# Miscellaneous filesystems
+#
+CONFIG_ADFS_FS=m
+# CONFIG_ADFS_FS_RW is not set
+CONFIG_AFFS_FS=m
+CONFIG_HFS_FS=m
+CONFIG_HFSPLUS_FS=m
+CONFIG_BEFS_FS=m
+# CONFIG_BEFS_DEBUG is not set
+CONFIG_BFS_FS=m
+CONFIG_EFS_FS=m
+CONFIG_JFFS_FS=m
+CONFIG_JFFS_FS_VERBOSE=0
+CONFIG_JFFS_PROC_FS=y
+CONFIG_JFFS2_FS=m
+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=m
+CONFIG_HPFS_FS=m
+CONFIG_QNX4FS_FS=m
+CONFIG_SYSV_FS=m
+CONFIG_UFS_FS=m
+# CONFIG_UFS_FS_WRITE is not set
+# CONFIG_UFS_DEBUG is not set
+
+#
+# Network File Systems
+#
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
+CONFIG_NFS_V4=y
+CONFIG_NFS_DIRECTIO=y
+CONFIG_NFSD=m
+CONFIG_NFSD_V3=y
+# CONFIG_NFSD_V3_ACL is not set
+CONFIG_NFSD_V4=y
+CONFIG_NFSD_TCP=y
+CONFIG_ROOT_NFS=y
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_EXPORTFS=m
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+CONFIG_SUNRPC_GSS=y
+CONFIG_RPCSEC_GSS_KRB5=y
+CONFIG_RPCSEC_GSS_SPKM3=m
+CONFIG_SMB_FS=m
+# CONFIG_SMB_NLS_DEFAULT is not set
+CONFIG_CIFS=m
+# CONFIG_CIFS_STATS is not set
+# CONFIG_CIFS_WEAK_PW_HASH is not set
+# CONFIG_CIFS_XATTR is not set
+# CONFIG_CIFS_DEBUG2 is not set
+# CONFIG_CIFS_EXPERIMENTAL is not set
+CONFIG_NCP_FS=m
+CONFIG_NCPFS_PACKET_SIGNING=y
+CONFIG_NCPFS_IOCTL_LOCKING=y
+CONFIG_NCPFS_STRONG=y
+CONFIG_NCPFS_NFS_NS=y
+CONFIG_NCPFS_OS2_NS=y
+# CONFIG_NCPFS_SMALLDOS is not set
+CONFIG_NCPFS_NLS=y
+CONFIG_NCPFS_EXTRAS=y
+CONFIG_CODA_FS=m
+# CONFIG_CODA_FS_OLD_API is not set
+CONFIG_AFS_FS=m
+CONFIG_RXRPC=m
+# CONFIG_9P_FS is not set
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+CONFIG_ACORN_PARTITION=y
+# CONFIG_ACORN_PARTITION_CUMANA is not set
+# CONFIG_ACORN_PARTITION_EESOX is not set
+CONFIG_ACORN_PARTITION_ICS=y
+# CONFIG_ACORN_PARTITION_ADFS is not set
+# CONFIG_ACORN_PARTITION_POWERTEC is not set
+CONFIG_ACORN_PARTITION_RISCIX=y
+CONFIG_OSF_PARTITION=y
+CONFIG_AMIGA_PARTITION=y
+CONFIG_ATARI_PARTITION=y
+CONFIG_MAC_PARTITION=y
+CONFIG_MSDOS_PARTITION=y
+CONFIG_BSD_DISKLABEL=y
+CONFIG_MINIX_SUBPARTITION=y
+CONFIG_SOLARIS_X86_PARTITION=y
+CONFIG_UNIXWARE_DISKLABEL=y
+CONFIG_LDM_PARTITION=y
+# CONFIG_LDM_DEBUG is not set
+CONFIG_SGI_PARTITION=y
+CONFIG_ULTRIX_PARTITION=y
+CONFIG_SUN_PARTITION=y
+# CONFIG_KARMA_PARTITION is not set
+# CONFIG_EFI_PARTITION is not set
+
+#
+# Native Language Support
+#
+CONFIG_NLS=m
+CONFIG_NLS_DEFAULT="cp437"
+CONFIG_NLS_CODEPAGE_437=m
+CONFIG_NLS_CODEPAGE_737=m
+CONFIG_NLS_CODEPAGE_775=m
+CONFIG_NLS_CODEPAGE_850=m
+CONFIG_NLS_CODEPAGE_852=m
+CONFIG_NLS_CODEPAGE_855=m
+CONFIG_NLS_CODEPAGE_857=m
+CONFIG_NLS_CODEPAGE_860=m
+CONFIG_NLS_CODEPAGE_861=m
+CONFIG_NLS_CODEPAGE_862=m
+CONFIG_NLS_CODEPAGE_863=m
+CONFIG_NLS_CODEPAGE_864=m
+CONFIG_NLS_CODEPAGE_865=m
+CONFIG_NLS_CODEPAGE_866=m
+CONFIG_NLS_CODEPAGE_869=m
+CONFIG_NLS_CODEPAGE_936=m
+CONFIG_NLS_CODEPAGE_950=m
+CONFIG_NLS_CODEPAGE_932=m
+CONFIG_NLS_CODEPAGE_949=m
+CONFIG_NLS_CODEPAGE_874=m
+CONFIG_NLS_ISO8859_8=m
+CONFIG_NLS_CODEPAGE_1250=m
+CONFIG_NLS_CODEPAGE_1251=m
+CONFIG_NLS_ASCII=m
+CONFIG_NLS_ISO8859_1=m
+CONFIG_NLS_ISO8859_2=m
+CONFIG_NLS_ISO8859_3=m
+CONFIG_NLS_ISO8859_4=m
+CONFIG_NLS_ISO8859_5=m
+CONFIG_NLS_ISO8859_6=m
+CONFIG_NLS_ISO8859_7=m
+CONFIG_NLS_ISO8859_9=m
+CONFIG_NLS_ISO8859_13=m
+CONFIG_NLS_ISO8859_14=m
+CONFIG_NLS_ISO8859_15=m
+CONFIG_NLS_KOI8_R=m
+CONFIG_NLS_KOI8_U=m
+CONFIG_NLS_UTF8=m
+
+#
+# Profiling support
+#
+# CONFIG_PROFILING is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_UNUSED_SYMBOLS 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=y
+# 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 is not set
+# CONFIG_DEBUG_INFO is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_DEBUG_VM is not set
+CONFIG_FRAME_POINTER=y
+# CONFIG_UNWIND_INFO is not set
+CONFIG_FORCED_INLINING=y
+# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_DEBUG_USER is not set
+# CONFIG_DEBUG_WAITQ is not set
+# CONFIG_DEBUG_ERRORS is not set
+# CONFIG_DEBUG_LL is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+CONFIG_SECURITY=y
+# CONFIG_SECURITY_NETWORK is not set
+CONFIG_SECURITY_CAPABILITIES=m
+CONFIG_SECURITY_ROOTPLUG=m
+CONFIG_SECURITY_SECLVL=m
+
+#
+# Cryptographic options
+#
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_HMAC=y
+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 is not set
+CONFIG_CRYPTO_DES=y
+CONFIG_CRYPTO_BLOWFISH=m
+CONFIG_CRYPTO_TWOFISH=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_TEST=m
+
+#
+# Hardware crypto devices
+#
+
+#
+# Library routines
+#
+CONFIG_CRC_CCITT=m
+CONFIG_CRC16=m
+CONFIG_CRC32=y
+CONFIG_LIBCRC32C=m
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=m
+CONFIG_TEXTSEARCH=y
+CONFIG_TEXTSEARCH_KMP=m
+CONFIG_PLIST=y
diff --git a/arch/arm/configs/trizeps4_defconfig b/arch/arm/configs/trizeps4_defconfig
new file mode 100644
index 000000000..a6698dc4f
--- /dev/null
+++ b/arch/arm/configs/trizeps4_defconfig
@@ -0,0 +1,1579 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.17
+# Sat Jun 24 22:45:14 2006
+#
+CONFIG_ARM=y
+CONFIG_MMU=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_ARCH_MTD_XIP=y
+CONFIG_VECTORS_BASE=0xffff0000
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_BSD_PROCESS_ACCT=y
+CONFIG_BSD_PROCESS_ACCT_V3=y
+CONFIG_SYSCTL=y
+CONFIG_AUDIT=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+# CONFIG_RELAY is not set
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_UID16=y
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_EMBEDDED=y
+CONFIG_KALLSYMS=y
+CONFIG_KALLSYMS_EXTRA_PASS=y
+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_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+# CONFIG_SLOB is not set
+CONFIG_OBSOLETE_INTERMODULE=y
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODULE_FORCE_UNLOAD=y
+# CONFIG_MODVERSIONS is not set
+CONFIG_MODULE_SRCVERSION_ALL=y
+CONFIG_KMOD=y
+
+#
+# Block layer
+#
+# CONFIG_BLK_DEV_IO_TRACE is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+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_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_INTEGRATOR is not set
+# CONFIG_ARCH_IOP3XX 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_PXA=y
+# 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
+# CONFIG_ARCH_VERSATILE is not set
+# CONFIG_ARCH_REALVIEW is not set
+# CONFIG_ARCH_IMX is not set
+# CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_AAEC2000 is not set
+# CONFIG_ARCH_AT91RM9200 is not set
+
+#
+# Intel PXA2xx Implementations
+#
+# CONFIG_ARCH_LUBBOCK is not set
+# CONFIG_MACH_LOGICPD_PXA270 is not set
+# CONFIG_MACH_MAINSTONE is not set
+# CONFIG_ARCH_PXA_IDP is not set
+# CONFIG_PXA_SHARPSL is not set
+CONFIG_MACH_TRIZEPS4=y
+CONFIG_MACH_TRIZEPS4_CONXS=y
+# CONFIG_MACH_TRIZEPS4_ANY is not set
+CONFIG_PXA27x=y
+
+#
+# Processor Type
+#
+CONFIG_CPU_32=y
+CONFIG_CPU_XSCALE=y
+CONFIG_CPU_32v5=y
+CONFIG_CPU_ABRT_EV5T=y
+CONFIG_CPU_CACHE_VIVT=y
+CONFIG_CPU_TLB_V4WBI=y
+
+#
+# Processor Features
+#
+CONFIG_ARM_THUMB=y
+CONFIG_XSCALE_PMU=y
+
+#
+# Bus support
+#
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+CONFIG_PCCARD=m
+# CONFIG_PCMCIA_DEBUG is not set
+CONFIG_PCMCIA=m
+CONFIG_PCMCIA_LOAD_CIS=y
+CONFIG_PCMCIA_IOCTL=y
+
+#
+# PC-card bridges
+#
+CONFIG_PCMCIA_PXA2XX=m
+
+#
+# Kernel Features
+#
+CONFIG_PREEMPT=y
+# 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_LEDS=y
+CONFIG_LEDS_TIMER=y
+CONFIG_LEDS_CPU=y
+CONFIG_ALIGNMENT_TRAP=y
+
+#
+# Boot options
+#
+CONFIG_ZBOOT_ROM_TEXT=0
+CONFIG_ZBOOT_ROM_BSS=0
+CONFIG_CMDLINE="root=/dev/nfs ip=bootp console=ttyS0,115200n8"
+# CONFIG_XIP_KERNEL is not set
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+CONFIG_FPE_NWFPE=y
+CONFIG_FPE_NWFPE_XP=y
+# CONFIG_FPE_FASTFPE is not set
+
+#
+# Userspace binary formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_AOUT is not set
+CONFIG_BINFMT_MISC=m
+# CONFIG_ARTHUR is not set
+
+#
+# Power management options
+#
+CONFIG_PM=y
+CONFIG_PM_LEGACY=y
+# CONFIG_PM_DEBUG is not set
+CONFIG_APM=y
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+# CONFIG_NETDEBUG is not set
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=m
+CONFIG_NET_KEY=y
+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=y
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# 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_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
+
+#
+# IP: Virtual Server Configuration
+#
+# CONFIG_IP_VS is not set
+CONFIG_IPV6=m
+# CONFIG_IPV6_PRIVACY is not set
+# CONFIG_IPV6_ROUTER_PREF is not set
+# CONFIG_INET6_AH is not set
+# CONFIG_INET6_ESP is not set
+# CONFIG_INET6_IPCOMP is not set
+# CONFIG_INET6_XFRM_TUNNEL is not set
+# CONFIG_INET6_TUNNEL is not set
+# CONFIG_IPV6_TUNNEL is not set
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_DEBUG is not set
+
+#
+# Core Netfilter Configuration
+#
+# CONFIG_NETFILTER_NETLINK is not set
+# CONFIG_NETFILTER_XTABLES is not set
+
+#
+# IP: Netfilter Configuration
+#
+CONFIG_IP_NF_CONNTRACK=m
+CONFIG_IP_NF_CT_ACCT=y
+CONFIG_IP_NF_CONNTRACK_MARK=y
+# CONFIG_IP_NF_CONNTRACK_EVENTS is not set
+# 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 is not set
+# CONFIG_IP_NF_H323 is not set
+CONFIG_IP_NF_QUEUE=m
+
+#
+# IPv6: Netfilter Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP6_NF_QUEUE 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=m
+# 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_NET_DIVERT 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=m
+
+#
+# IrDA protocols
+#
+CONFIG_IRLAN=m
+CONFIG_IRNET=m
+CONFIG_IRCOMM=m
+CONFIG_IRDA_ULTRA=y
+
+#
+# IrDA options
+#
+CONFIG_IRDA_CACHE_LAST_LSAP=y
+CONFIG_IRDA_FAST_RR=y
+# CONFIG_IRDA_DEBUG is not set
+
+#
+# Infrared-port device drivers
+#
+
+#
+# SIR device drivers
+#
+CONFIG_IRTTY_SIR=m
+
+#
+# Dongle support
+#
+# CONFIG_DONGLE is not set
+
+#
+# Old SIR device drivers
+#
+# CONFIG_IRPORT_SIR is not set
+
+#
+# Old Serial dongle support
+#
+
+#
+# FIR device drivers
+#
+# CONFIG_USB_IRDA is not set
+# CONFIG_SIGMATEL_FIR is not set
+# CONFIG_PXA_FICP is not set
+CONFIG_BT=m
+CONFIG_BT_L2CAP=m
+CONFIG_BT_SCO=m
+CONFIG_BT_RFCOMM=m
+CONFIG_BT_RFCOMM_TTY=y
+CONFIG_BT_BNEP=m
+CONFIG_BT_BNEP_MC_FILTER=y
+CONFIG_BT_BNEP_PROTO_FILTER=y
+CONFIG_BT_HIDP=m
+
+#
+# Bluetooth device drivers
+#
+# CONFIG_BT_HCIUSB is not set
+# CONFIG_BT_HCIUART is not set
+# CONFIG_BT_HCIBCM203X is not set
+# CONFIG_BT_HCIBPA10X is not set
+# CONFIG_BT_HCIBFUSB is not set
+# CONFIG_BT_HCIDTL1 is not set
+# CONFIG_BT_HCIBT3C is not set
+# CONFIG_BT_HCIBLUECARD is not set
+# CONFIG_BT_HCIBTUART is not set
+# CONFIG_BT_HCIVHCI is not set
+CONFIG_IEEE80211=m
+# CONFIG_IEEE80211_DEBUG is not set
+CONFIG_IEEE80211_CRYPT_WEP=m
+CONFIG_IEEE80211_CRYPT_CCMP=m
+CONFIG_IEEE80211_CRYPT_TKIP=m
+CONFIG_IEEE80211_SOFTMAC=m
+# CONFIG_IEEE80211_SOFTMAC_DEBUG is not set
+CONFIG_WIRELESS_EXT=y
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+CONFIG_CONNECTOR=y
+CONFIG_PROC_EVENTS=y
+
+#
+# Memory Technology Devices (MTD)
+#
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+CONFIG_MTD_CONCAT=y
+CONFIG_MTD_PARTITIONS=y
+CONFIG_MTD_REDBOOT_PARTS=y
+CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1
+CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED=y
+CONFIG_MTD_REDBOOT_PARTS_READONLY=y
+# CONFIG_MTD_CMDLINE_PARTS is not set
+# CONFIG_MTD_AFS_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+CONFIG_NFTL=y
+CONFIG_NFTL_RW=y
+CONFIG_INFTL=y
+# CONFIG_RFD_FTL is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=y
+CONFIG_MTD_JEDECPROBE=y
+CONFIG_MTD_GEN_PROBE=y
+CONFIG_MTD_CFI_ADV_OPTIONS=y
+# CONFIG_MTD_CFI_NOSWAP is not set
+# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set
+CONFIG_MTD_CFI_LE_BYTE_SWAP=y
+CONFIG_MTD_CFI_GEOMETRY=y
+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_OTP is not set
+CONFIG_MTD_CFI_INTELEXT=y
+CONFIG_MTD_CFI_AMDSTD=y
+# CONFIG_MTD_CFI_STAA is not set
+CONFIG_MTD_CFI_UTIL=y
+# 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
+# CONFIG_MTD_XIP is not set
+
+#
+# Mapping drivers for chip access
+#
+CONFIG_MTD_COMPLEX_MAPPINGS=y
+CONFIG_MTD_PHYSMAP=y
+CONFIG_MTD_PHYSMAP_START=0x0
+CONFIG_MTD_PHYSMAP_LEN=0x4000000
+CONFIG_MTD_PHYSMAP_BANKWIDTH=2
+# CONFIG_MTD_TRIZEPS4 is not set
+# CONFIG_MTD_ARM_INTEGRATOR is not set
+# CONFIG_MTD_IMPA7 is not set
+# CONFIG_MTD_SHARP_SL is not set
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_DATAFLASH is not set
+# 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=y
+CONFIG_MTD_DOCPROBE=y
+CONFIG_MTD_DOCECC=y
+# CONFIG_MTD_DOCPROBE_ADVANCED is not set
+CONFIG_MTD_DOCPROBE_ADDRESS=0
+
+#
+# NAND Flash Device Drivers
+#
+CONFIG_MTD_NAND=y
+# CONFIG_MTD_NAND_VERIFY_WRITE is not set
+# CONFIG_MTD_NAND_H1900 is not set
+CONFIG_MTD_NAND_IDS=y
+CONFIG_MTD_NAND_DISKONCHIP=y
+# CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADVANCED is not set
+CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADDRESS=0
+# CONFIG_MTD_NAND_DISKONCHIP_BBTWRITE is not set
+# CONFIG_MTD_NAND_SHARPSL is not set
+# 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=m
+CONFIG_BLK_DEV_NBD=y
+# CONFIG_BLK_DEV_UB is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=4
+CONFIG_BLK_DEV_RAM_SIZE=4096
+CONFIG_BLK_DEV_INITRD=y
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+CONFIG_IDE=y
+CONFIG_BLK_DEV_IDE=y
+
+#
+# Please see Documentation/ide.txt for help/info on IDE drives
+#
+# CONFIG_BLK_DEV_IDE_SATA is not set
+CONFIG_BLK_DEV_IDEDISK=y
+CONFIG_IDEDISK_MULTI_MODE=y
+CONFIG_BLK_DEV_IDECS=m
+# CONFIG_BLK_DEV_IDECD is not set
+# CONFIG_BLK_DEV_IDETAPE is not set
+# CONFIG_BLK_DEV_IDEFLOPPY is not set
+# CONFIG_BLK_DEV_IDESCSI is not set
+# CONFIG_IDE_TASK_IOCTL is not set
+
+#
+# IDE chipset support/bugfixes
+#
+CONFIG_IDE_GENERIC=y
+CONFIG_IDE_PXA_CF=y
+CONFIG_IDE_ARM=y
+# CONFIG_BLK_DEV_IDEDMA is not set
+# CONFIG_IDEDMA_AUTO is not set
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+CONFIG_SCSI=m
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=m
+# CONFIG_CHR_DEV_ST is not set
+# CONFIG_CHR_DEV_OSST is not set
+# CONFIG_BLK_DEV_SR is not set
+CONFIG_CHR_DEV_SG=m
+# CONFIG_CHR_DEV_SCH is not set
+
+#
+# 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
+
+#
+# SCSI Transport Attributes
+#
+# 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
+
+#
+# SCSI low-level drivers
+#
+# CONFIG_ISCSI_TCP is not set
+# CONFIG_SCSI_SATA is not set
+# CONFIG_SCSI_DEBUG is not set
+
+#
+# PCMCIA SCSI adapter support
+#
+# CONFIG_PCMCIA_AHA152X is not set
+# CONFIG_PCMCIA_FDOMAIN is not set
+# CONFIG_PCMCIA_NINJA_SCSI is not set
+# CONFIG_PCMCIA_QLOGIC is not set
+# CONFIG_PCMCIA_SYM53C500 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=y
+
+#
+# MII PHY device drivers
+#
+# CONFIG_MARVELL_PHY is not set
+CONFIG_DAVICOM_PHY=y
+# CONFIG_QSEMI_PHY is not set
+# CONFIG_LXT_PHY is not set
+# CONFIG_CICADA_PHY is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+# CONFIG_SMC91X is not set
+CONFIG_DM9000=y
+
+#
+# Ethernet (1000 Mbit)
+#
+
+#
+# Ethernet (10000 Mbit)
+#
+
+#
+# Token Ring devices
+#
+
+#
+# Wireless LAN (non-hamradio)
+#
+CONFIG_NET_RADIO=y
+# CONFIG_NET_WIRELESS_RTNETLINK is not set
+
+#
+# Obsolete Wireless cards support (pre-802.11)
+#
+# CONFIG_STRIP is not set
+# CONFIG_PCMCIA_WAVELAN is not set
+# CONFIG_PCMCIA_NETWAVE is not set
+
+#
+# Wireless 802.11 Frequency Hopping cards support
+#
+# CONFIG_PCMCIA_RAYCS is not set
+
+#
+# Wireless 802.11b ISA/PCI cards support
+#
+CONFIG_HERMES=m
+# CONFIG_ATMEL is not set
+
+#
+# Wireless 802.11b Pcmcia/Cardbus cards support
+#
+CONFIG_PCMCIA_HERMES=m
+# CONFIG_PCMCIA_SPECTRUM is not set
+CONFIG_AIRO_CS=m
+# CONFIG_PCMCIA_WL3501 is not set
+CONFIG_HOSTAP=m
+CONFIG_HOSTAP_FIRMWARE=y
+CONFIG_HOSTAP_FIRMWARE_NVRAM=y
+CONFIG_HOSTAP_CS=m
+CONFIG_NET_WIRELESS=y
+
+#
+# PCMCIA network device support
+#
+# CONFIG_NET_PCMCIA is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+CONFIG_PPP=m
+CONFIG_PPP_MULTILINK=y
+CONFIG_PPP_FILTER=y
+CONFIG_PPP_ASYNC=m
+CONFIG_PPP_SYNC_TTY=m
+CONFIG_PPP_DEFLATE=m
+CONFIG_PPP_BSDCOMP=m
+CONFIG_PPP_MPPE=m
+# CONFIG_PPPOE 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
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
+CONFIG_INPUT_MOUSEDEV_PSAUX=y
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=640
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=480
+# CONFIG_INPUT_JOYDEV is not set
+CONFIG_INPUT_TSDEV=y
+CONFIG_INPUT_TSDEV_SCREEN_X=640
+CONFIG_INPUT_TSDEV_SCREEN_Y=480
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+CONFIG_KEYBOARD_ATKBD=y
+# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_KEYBOARD_LKKBD is not set
+# CONFIG_KEYBOARD_XTKBD is not set
+# CONFIG_KEYBOARD_NEWTON is not set
+CONFIG_INPUT_MOUSE=y
+# CONFIG_MOUSE_PS2 is not set
+CONFIG_MOUSE_SERIAL=y
+# CONFIG_MOUSE_VSXXXAA is not set
+# CONFIG_INPUT_JOYSTICK is not set
+CONFIG_INPUT_TOUCHSCREEN=y
+# CONFIG_TOUCHSCREEN_ADS7846 is not set
+# 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_INPUT_MISC=y
+CONFIG_INPUT_UINPUT=m
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+CONFIG_SERIO_SERPORT=y
+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_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_PXA=y
+CONFIG_SERIAL_PXA_CONSOLE=y
+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 is not set
+
+#
+# Watchdog Device Drivers
+#
+# CONFIG_SOFT_WATCHDOG is not set
+CONFIG_SA1100_WATCHDOG=y
+
+#
+# USB-based Watchdog Cards
+#
+# CONFIG_USBPCWATCHDOG is not set
+# CONFIG_NVRAM is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+
+#
+# PCMCIA character devices
+#
+# CONFIG_SYNCLINK_CS is not set
+# CONFIG_CARDMAN_4000 is not set
+# CONFIG_CARDMAN_4040 is not set
+# CONFIG_RAW_DRIVER is not set
+
+#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+# CONFIG_TELCLOCK 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_PXA=y
+CONFIG_I2C_PXA_SLAVE=y
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_STUB 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=m
+# 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_MASTER=y
+
+#
+# SPI Master Controller Drivers
+#
+# CONFIG_SPI_BITBANG is not set
+CONFIG_SPI_PXA2XX=m
+
+#
+# SPI Protocol Masters
+#
+
+#
+# Dallas's 1-wire bus
+#
+# CONFIG_W1 is not set
+
+#
+# Hardware Monitoring support
+#
+CONFIG_HWMON=y
+# CONFIG_HWMON_VID is not set
+# CONFIG_SENSORS_ADM1021 is not set
+# CONFIG_SENSORS_ADM1025 is not set
+# CONFIG_SENSORS_ADM1026 is not set
+# CONFIG_SENSORS_ADM1031 is not set
+# CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ASB100 is not set
+# CONFIG_SENSORS_ATXP1 is not set
+# CONFIG_SENSORS_DS1621 is not set
+# CONFIG_SENSORS_F71805F is not set
+# CONFIG_SENSORS_FSCHER is not set
+# CONFIG_SENSORS_FSCPOS is not set
+# CONFIG_SENSORS_GL518SM is not set
+# CONFIG_SENSORS_GL520SM is not set
+# CONFIG_SENSORS_IT87 is not set
+# CONFIG_SENSORS_LM63 is not set
+# CONFIG_SENSORS_LM75 is not set
+# CONFIG_SENSORS_LM77 is not set
+# CONFIG_SENSORS_LM78 is not set
+# CONFIG_SENSORS_LM80 is not set
+# CONFIG_SENSORS_LM83 is not set
+# CONFIG_SENSORS_LM85 is not set
+# CONFIG_SENSORS_LM87 is not set
+# CONFIG_SENSORS_LM90 is not set
+# CONFIG_SENSORS_LM92 is not set
+# CONFIG_SENSORS_MAX1619 is not set
+# CONFIG_SENSORS_PC87360 is not set
+# CONFIG_SENSORS_SMSC47M1 is not set
+# CONFIG_SENSORS_SMSC47B397 is not set
+# CONFIG_SENSORS_W83781D is not set
+# CONFIG_SENSORS_W83792D 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 Capabilities Port drivers
+#
+CONFIG_UCB1400=y
+CONFIG_UCB1400_TS=y
+
+#
+# LED devices
+#
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+
+#
+# LED drivers
+#
+
+#
+# LED Triggers
+#
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_LEDS_TRIGGER_TIMER=y
+CONFIG_LEDS_TRIGGER_IDE_DISK=y
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+CONFIG_VIDEO_V4L2=y
+
+#
+# Digital Video Broadcasting Devices
+#
+# CONFIG_DVB is not set
+# CONFIG_USB_DABUSB is not set
+
+#
+# Graphics support
+#
+CONFIG_FB=y
+CONFIG_FB_CFB_FILLRECT=y
+CONFIG_FB_CFB_COPYAREA=y
+CONFIG_FB_CFB_IMAGEBLIT=y
+# CONFIG_FB_MACMODES is not set
+CONFIG_FB_FIRMWARE_EDID=y
+# CONFIG_FB_MODE_HELPERS is not set
+# CONFIG_FB_TILEBLITTING is not set
+# CONFIG_FB_S1D13XXX is not set
+CONFIG_FB_PXA=y
+# CONFIG_FB_PXA_PARAMETERS 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=y
+CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y
+CONFIG_FONTS=y
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
+# CONFIG_FONT_6x11 is not set
+# CONFIG_FONT_7x14 is not set
+# CONFIG_FONT_PEARL_8x8 is not set
+# CONFIG_FONT_ACORN_8x8 is not set
+# CONFIG_FONT_MINI_4x6 is not set
+# CONFIG_FONT_SUN8x16 is not set
+# CONFIG_FONT_SUN12x22 is not set
+# CONFIG_FONT_10x18 is not set
+
+#
+# Logo configuration
+#
+CONFIG_LOGO=y
+CONFIG_LOGO_LINUX_MONO=y
+CONFIG_LOGO_LINUX_VGA16=y
+CONFIG_LOGO_LINUX_CLUT224=y
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+CONFIG_BACKLIGHT_CLASS_DEVICE=y
+CONFIG_BACKLIGHT_DEVICE=y
+CONFIG_LCD_CLASS_DEVICE=y
+CONFIG_LCD_DEVICE=y
+
+#
+# Sound
+#
+CONFIG_SOUND=y
+
+#
+# Advanced Linux Sound Architecture
+#
+CONFIG_SND=y
+CONFIG_SND_TIMER=y
+CONFIG_SND_PCM=y
+CONFIG_SND_HWDEP=m
+CONFIG_SND_RAWMIDI=m
+CONFIG_SND_SEQUENCER=m
+# CONFIG_SND_SEQ_DUMMY is not set
+CONFIG_SND_OSSEMUL=y
+CONFIG_SND_MIXER_OSS=y
+CONFIG_SND_PCM_OSS=y
+CONFIG_SND_PCM_OSS_PLUGINS=y
+# CONFIG_SND_SEQUENCER_OSS is not set
+# CONFIG_SND_DYNAMIC_MINORS is not set
+CONFIG_SND_SUPPORT_OLD_API=y
+CONFIG_SND_VERBOSE_PROCFS=y
+CONFIG_SND_VERBOSE_PRINTK=y
+# CONFIG_SND_DEBUG is not set
+
+#
+# Generic devices
+#
+CONFIG_SND_AC97_CODEC=y
+CONFIG_SND_AC97_BUS=y
+# CONFIG_SND_DUMMY is not set
+# CONFIG_SND_VIRMIDI is not set
+# CONFIG_SND_MTPAV is not set
+# CONFIG_SND_SERIAL_U16550 is not set
+# CONFIG_SND_MPU401 is not set
+
+#
+# ALSA ARM devices
+#
+CONFIG_SND_PXA2XX_PCM=y
+CONFIG_SND_PXA2XX_AC97=y
+
+#
+# USB devices
+#
+CONFIG_SND_USB_AUDIO=m
+
+#
+# PCMCIA devices
+#
+# CONFIG_SND_VXPOCKET is not set
+# CONFIG_SND_PDAUDIOCF is not set
+
+#
+# Open Sound System
+#
+# CONFIG_SOUND_PRIME is not set
+
+#
+# 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_SUSPEND 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=m
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_ISD200 is not set
+# CONFIG_USB_STORAGE_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_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
+
+#
+# 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=m
+# CONFIG_USB_TOUCHSCREEN_EGALAX is not set
+# CONFIG_USB_TOUCHSCREEN_PANJIT is not set
+# CONFIG_USB_TOUCHSCREEN_3M is not set
+# CONFIG_USB_TOUCHSCREEN_ITM 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 is not set
+# CONFIG_USB_ZD1201 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_AUERSWALD is not set
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_LEGOTOWER is not set
+# CONFIG_USB_LCD is not set
+# CONFIG_USB_LED is not set
+# CONFIG_USB_CYTHERM is not set
+# CONFIG_USB_PHIDGETKIT is not set
+# CONFIG_USB_PHIDGETSERVO is not set
+# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_LD 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 is not set
+CONFIG_USB_GADGET_DUMMY_HCD=y
+CONFIG_USB_DUMMY_HCD=y
+CONFIG_USB_GADGET_DUALSPEED=y
+# CONFIG_USB_ZERO is not set
+CONFIG_USB_ETH=m
+CONFIG_USB_ETH_RNDIS=y
+CONFIG_USB_GADGETFS=m
+CONFIG_USB_FILE_STORAGE=m
+# CONFIG_USB_FILE_STORAGE_TEST is not set
+CONFIG_USB_G_SERIAL=m
+
+#
+# MMC/SD Card support
+#
+CONFIG_MMC=y
+# CONFIG_MMC_DEBUG is not set
+CONFIG_MMC_BLOCK=y
+CONFIG_MMC_PXA=y
+
+#
+# Real Time Clock
+#
+CONFIG_RTC_LIB=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_HCTOSYS=y
+CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
+
+#
+# RTC interfaces
+#
+CONFIG_RTC_INTF_SYSFS=y
+CONFIG_RTC_INTF_PROC=y
+CONFIG_RTC_INTF_DEV=y
+
+#
+# RTC drivers
+#
+# CONFIG_RTC_DRV_X1205 is not set
+# CONFIG_RTC_DRV_DS1672 is not set
+# CONFIG_RTC_DRV_PCF8563 is not set
+# CONFIG_RTC_DRV_RS5C372 is not set
+# CONFIG_RTC_DRV_M48T86 is not set
+CONFIG_RTC_DRV_SA1100=y
+# CONFIG_RTC_DRV_TEST is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+CONFIG_EXT2_FS_POSIX_ACL=y
+CONFIG_EXT2_FS_SECURITY=y
+# CONFIG_EXT2_FS_XIP is not set
+CONFIG_EXT3_FS=y
+CONFIG_EXT3_FS_XATTR=y
+CONFIG_EXT3_FS_POSIX_ACL=y
+CONFIG_EXT3_FS_SECURITY=y
+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=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
+# CONFIG_QUOTA is not set
+CONFIG_DNOTIFY=y
+# CONFIG_AUTOFS_FS is not set
+CONFIG_AUTOFS4_FS=y
+# 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=m
+CONFIG_MSDOS_FS=m
+CONFIG_VFAT_FS=m
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-15"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# 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_JFFS_FS=y
+CONFIG_JFFS_FS_VERBOSE=0
+CONFIG_JFFS_PROC_FS=y
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_FS_DEBUG=0
+CONFIG_JFFS2_FS_WRITEBUFFER=y
+# CONFIG_JFFS2_SUMMARY is not set
+CONFIG_JFFS2_COMPRESSION_OPTIONS=y
+CONFIG_JFFS2_ZLIB=y
+CONFIG_JFFS2_RTIME=y
+# CONFIG_JFFS2_RUBIN is not set
+# CONFIG_JFFS2_CMODE_NONE is not set
+CONFIG_JFFS2_CMODE_PRIORITY=y
+# CONFIG_JFFS2_CMODE_SIZE 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
+
+#
+# Network File Systems
+#
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+CONFIG_NFS_V3_ACL=y
+CONFIG_NFS_V4=y
+# CONFIG_NFS_DIRECTIO is not set
+CONFIG_NFSD=y
+CONFIG_NFSD_V2_ACL=y
+CONFIG_NFSD_V3=y
+CONFIG_NFSD_V3_ACL=y
+CONFIG_NFSD_V4=y
+CONFIG_NFSD_TCP=y
+CONFIG_ROOT_NFS=y
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_EXPORTFS=y
+CONFIG_NFS_ACL_SUPPORT=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+CONFIG_SUNRPC_GSS=y
+CONFIG_RPCSEC_GSS_KRB5=y
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+CONFIG_SMB_FS=m
+# CONFIG_SMB_NLS_DEFAULT is not set
+CONFIG_CIFS=m
+# CONFIG_CIFS_STATS is not set
+# CONFIG_CIFS_XATTR is not set
+# CONFIG_CIFS_EXPERIMENTAL 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=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_BSD_DISKLABEL is not set
+# CONFIG_MINIX_SUBPARTITION is not set
+# CONFIG_SOLARIS_X86_PARTITION is not set
+# CONFIG_UNIXWARE_DISKLABEL is not set
+CONFIG_LDM_PARTITION=y
+# CONFIG_LDM_DEBUG is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_KARMA_PARTITION is not set
+# CONFIG_EFI_PARTITION is not set
+
+#
+# Native Language Support
+#
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="iso8859-15"
+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=y
+CONFIG_NLS_ISO8859_1=m
+# 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=m
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+CONFIG_NLS_UTF8=m
+
+#
+# Profiling support
+#
+CONFIG_PROFILING=y
+CONFIG_OPROFILE=y
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_DEBUG_KERNEL is not set
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_DEBUG_BUGVERBOSE is not set
+# CONFIG_DEBUG_FS is not set
+CONFIG_FRAME_POINTER=y
+# CONFIG_UNWIND_INFO is not set
+CONFIG_DEBUG_USER=y
+
+#
+# Security options
+#
+CONFIG_KEYS=y
+CONFIG_KEYS_DEBUG_PROC_KEYS=y
+CONFIG_SECURITY=y
+# CONFIG_SECURITY_NETWORK is not set
+CONFIG_SECURITY_CAPABILITIES=y
+# CONFIG_SECURITY_ROOTPLUG is not set
+# CONFIG_SECURITY_SECLVL is not set
+
+#
+# Cryptographic options
+#
+CONFIG_CRYPTO=y
+# CONFIG_CRYPTO_HMAC is not set
+# CONFIG_CRYPTO_NULL is not set
+CONFIG_CRYPTO_MD4=y
+CONFIG_CRYPTO_MD5=y
+CONFIG_CRYPTO_SHA1=m
+CONFIG_CRYPTO_SHA256=m
+CONFIG_CRYPTO_SHA512=m
+# CONFIG_CRYPTO_WP512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+CONFIG_CRYPTO_DES=y
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+# CONFIG_CRYPTO_SERPENT is not set
+CONFIG_CRYPTO_AES=m
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+# CONFIG_CRYPTO_TEA is not set
+CONFIG_CRYPTO_ARC4=m
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+CONFIG_CRYPTO_DEFLATE=m
+CONFIG_CRYPTO_MICHAEL_MIC=m
+CONFIG_CRYPTO_CRC32C=y
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Hardware crypto devices
+#
+
+#
+# Library routines
+#
+CONFIG_CRC_CCITT=y
+CONFIG_CRC16=y
+CONFIG_CRC32=y
+CONFIG_LIBCRC32C=y
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_REED_SOLOMON=y
+CONFIG_REED_SOLOMON_DEC16=y
diff --git a/arch/arm/kernel/crunch-bits.S b/arch/arm/kernel/crunch-bits.S
new file mode 100644
index 000000000..a26886758
--- /dev/null
+++ b/arch/arm/kernel/crunch-bits.S
@@ -0,0 +1,305 @@
+/*
+ * arch/arm/kernel/crunch-bits.S
+ * Cirrus MaverickCrunch context switching and handling
+ *
+ * Copyright (C) 2006 Lennert Buytenhek <buytenh@wantstofly.org>
+ *
+ * Shamelessly stolen from the iWMMXt code by Nicolas Pitre, which is
+ * Copyright (c) 2003-2004, 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.
+ */
+
+#include <linux/linkage.h>
+#include <asm/ptrace.h>
+#include <asm/thread_info.h>
+#include <asm/asm-offsets.h>
+#include <asm/arch/ep93xx-regs.h>
+
+/*
+ * We can't use hex constants here due to a bug in gas.
+ */
+#define CRUNCH_MVDX0		0
+#define CRUNCH_MVDX1		8
+#define CRUNCH_MVDX2		16
+#define CRUNCH_MVDX3		24
+#define CRUNCH_MVDX4		32
+#define CRUNCH_MVDX5		40
+#define CRUNCH_MVDX6		48
+#define CRUNCH_MVDX7		56
+#define CRUNCH_MVDX8		64
+#define CRUNCH_MVDX9		72
+#define CRUNCH_MVDX10		80
+#define CRUNCH_MVDX11		88
+#define CRUNCH_MVDX12		96
+#define CRUNCH_MVDX13		104
+#define CRUNCH_MVDX14		112
+#define CRUNCH_MVDX15		120
+#define CRUNCH_MVAX0L		128
+#define CRUNCH_MVAX0M		132
+#define CRUNCH_MVAX0H		136
+#define CRUNCH_MVAX1L		140
+#define CRUNCH_MVAX1M		144
+#define CRUNCH_MVAX1H		148
+#define CRUNCH_MVAX2L		152
+#define CRUNCH_MVAX2M		156
+#define CRUNCH_MVAX2H		160
+#define CRUNCH_MVAX3L		164
+#define CRUNCH_MVAX3M		168
+#define CRUNCH_MVAX3H		172
+#define CRUNCH_DSPSC		176
+
+#define CRUNCH_SIZE		184
+
+	.text
+
+/*
+ * Lazy switching of crunch coprocessor context
+ *
+ * r10 = struct thread_info pointer
+ * r9  = ret_from_exception
+ * lr  = undefined instr exit
+ *
+ * called from prefetch exception handler with interrupts disabled
+ */
+ENTRY(crunch_task_enable)
+	ldr	r8, =(EP93XX_APB_VIRT_BASE + 0x00130000)	@ syscon addr
+
+	ldr	r1, [r8, #0x80]
+	tst	r1, #0x00800000			@ access to crunch enabled?
+	movne	pc, lr				@ if so no business here
+	mov	r3, #0xaa			@ unlock syscon swlock
+	str	r3, [r8, #0xc0]
+	orr	r1, r1, #0x00800000		@ enable access to crunch
+	str	r1, [r8, #0x80]
+
+	ldr	r3, =crunch_owner
+	add	r0, r10, #TI_CRUNCH_STATE	@ get task crunch save area
+	ldr	r2, [sp, #60]			@ current task pc value
+	ldr	r1, [r3]			@ get current crunch owner
+	str	r0, [r3]			@ this task now owns crunch
+	sub	r2, r2, #4			@ adjust pc back
+	str	r2, [sp, #60]
+
+	ldr	r2, [r8, #0x80]
+	mov	r2, r2				@ flush out enable (@@@)
+
+	teq	r1, #0				@ test for last ownership
+	mov	lr, r9				@ normal exit from exception
+	beq	crunch_load			@ no owner, skip save
+
+crunch_save:
+	cfstr64		mvdx0, [r1, #CRUNCH_MVDX0]	@ save 64b registers
+	cfstr64		mvdx1, [r1, #CRUNCH_MVDX1]
+	cfstr64		mvdx2, [r1, #CRUNCH_MVDX2]
+	cfstr64		mvdx3, [r1, #CRUNCH_MVDX3]
+	cfstr64		mvdx4, [r1, #CRUNCH_MVDX4]
+	cfstr64		mvdx5, [r1, #CRUNCH_MVDX5]
+	cfstr64		mvdx6, [r1, #CRUNCH_MVDX6]
+	cfstr64		mvdx7, [r1, #CRUNCH_MVDX7]
+	cfstr64		mvdx8, [r1, #CRUNCH_MVDX8]
+	cfstr64		mvdx9, [r1, #CRUNCH_MVDX9]
+	cfstr64		mvdx10, [r1, #CRUNCH_MVDX10]
+	cfstr64		mvdx11, [r1, #CRUNCH_MVDX11]
+	cfstr64		mvdx12, [r1, #CRUNCH_MVDX12]
+	cfstr64		mvdx13, [r1, #CRUNCH_MVDX13]
+	cfstr64		mvdx14, [r1, #CRUNCH_MVDX14]
+	cfstr64		mvdx15, [r1, #CRUNCH_MVDX15]
+
+#ifdef __ARMEB__
+#error fix me for ARMEB
+#endif
+
+	cfmv32al	mvfx0, mvax0			@ save 72b accumulators
+	cfstr32		mvfx0, [r1, #CRUNCH_MVAX0L]
+	cfmv32am	mvfx0, mvax0
+	cfstr32		mvfx0, [r1, #CRUNCH_MVAX0M]
+	cfmv32ah	mvfx0, mvax0
+	cfstr32		mvfx0, [r1, #CRUNCH_MVAX0H]
+	cfmv32al	mvfx0, mvax1
+	cfstr32		mvfx0, [r1, #CRUNCH_MVAX1L]
+	cfmv32am	mvfx0, mvax1
+	cfstr32		mvfx0, [r1, #CRUNCH_MVAX1M]
+	cfmv32ah	mvfx0, mvax1
+	cfstr32		mvfx0, [r1, #CRUNCH_MVAX1H]
+	cfmv32al	mvfx0, mvax2
+	cfstr32		mvfx0, [r1, #CRUNCH_MVAX2L]
+	cfmv32am	mvfx0, mvax2
+	cfstr32		mvfx0, [r1, #CRUNCH_MVAX2M]
+	cfmv32ah	mvfx0, mvax2
+	cfstr32		mvfx0, [r1, #CRUNCH_MVAX2H]
+	cfmv32al	mvfx0, mvax3
+	cfstr32		mvfx0, [r1, #CRUNCH_MVAX3L]
+	cfmv32am	mvfx0, mvax3
+	cfstr32		mvfx0, [r1, #CRUNCH_MVAX3M]
+	cfmv32ah	mvfx0, mvax3
+	cfstr32		mvfx0, [r1, #CRUNCH_MVAX3H]
+
+	cfmv32sc	mvdx0, dspsc			@ save status word
+	cfstr64		mvdx0, [r1, #CRUNCH_DSPSC]
+
+	teq		r0, #0				@ anything to load?
+	cfldr64eq	mvdx0, [r1, #CRUNCH_MVDX0]	@ mvdx0 was clobbered
+	moveq		pc, lr
+
+crunch_load:
+	cfldr64		mvdx0, [r0, #CRUNCH_DSPSC]	@ load status word
+	cfmvsc32	dspsc, mvdx0
+
+	cfldr32		mvfx0, [r0, #CRUNCH_MVAX0L]	@ load 72b accumulators
+	cfmval32	mvax0, mvfx0
+	cfldr32		mvfx0, [r0, #CRUNCH_MVAX0M]
+	cfmvam32	mvax0, mvfx0
+	cfldr32		mvfx0, [r0, #CRUNCH_MVAX0H]
+	cfmvah32	mvax0, mvfx0
+	cfldr32		mvfx0, [r0, #CRUNCH_MVAX1L]
+	cfmval32	mvax1, mvfx0
+	cfldr32		mvfx0, [r0, #CRUNCH_MVAX1M]
+	cfmvam32	mvax1, mvfx0
+	cfldr32		mvfx0, [r0, #CRUNCH_MVAX1H]
+	cfmvah32	mvax1, mvfx0
+	cfldr32		mvfx0, [r0, #CRUNCH_MVAX2L]
+	cfmval32	mvax2, mvfx0
+	cfldr32		mvfx0, [r0, #CRUNCH_MVAX2M]
+	cfmvam32	mvax2, mvfx0
+	cfldr32		mvfx0, [r0, #CRUNCH_MVAX2H]
+	cfmvah32	mvax2, mvfx0
+	cfldr32		mvfx0, [r0, #CRUNCH_MVAX3L]
+	cfmval32	mvax3, mvfx0
+	cfldr32		mvfx0, [r0, #CRUNCH_MVAX3M]
+	cfmvam32	mvax3, mvfx0
+	cfldr32		mvfx0, [r0, #CRUNCH_MVAX3H]
+	cfmvah32	mvax3, mvfx0
+
+	cfldr64		mvdx0, [r0, #CRUNCH_MVDX0]	@ load 64b registers
+	cfldr64		mvdx1, [r0, #CRUNCH_MVDX1]
+	cfldr64		mvdx2, [r0, #CRUNCH_MVDX2]
+	cfldr64		mvdx3, [r0, #CRUNCH_MVDX3]
+	cfldr64		mvdx4, [r0, #CRUNCH_MVDX4]
+	cfldr64		mvdx5, [r0, #CRUNCH_MVDX5]
+	cfldr64		mvdx6, [r0, #CRUNCH_MVDX6]
+	cfldr64		mvdx7, [r0, #CRUNCH_MVDX7]
+	cfldr64		mvdx8, [r0, #CRUNCH_MVDX8]
+	cfldr64		mvdx9, [r0, #CRUNCH_MVDX9]
+	cfldr64		mvdx10, [r0, #CRUNCH_MVDX10]
+	cfldr64		mvdx11, [r0, #CRUNCH_MVDX11]
+	cfldr64		mvdx12, [r0, #CRUNCH_MVDX12]
+	cfldr64		mvdx13, [r0, #CRUNCH_MVDX13]
+	cfldr64		mvdx14, [r0, #CRUNCH_MVDX14]
+	cfldr64		mvdx15, [r0, #CRUNCH_MVDX15]
+
+	mov	pc, lr
+
+/*
+ * Back up crunch regs to save area and disable access to them
+ * (mainly for gdb or sleep mode usage)
+ *
+ * r0 = struct thread_info pointer of target task or NULL for any
+ */
+ENTRY(crunch_task_disable)
+	stmfd	sp!, {r4, r5, lr}
+
+	mrs	ip, cpsr
+	orr	r2, ip, #PSR_I_BIT		@ disable interrupts
+	msr	cpsr_c, r2
+
+	ldr	r4, =(EP93XX_APB_VIRT_BASE + 0x00130000)	@ syscon addr
+
+	ldr	r3, =crunch_owner
+	add	r2, r0, #TI_CRUNCH_STATE	@ get task crunch save area
+	ldr	r1, [r3]			@ get current crunch owner
+	teq	r1, #0				@ any current owner?
+	beq	1f				@ no: quit
+	teq	r0, #0				@ any owner?
+	teqne	r1, r2				@ or specified one?
+	bne	1f				@ no: quit
+
+	ldr	r5, [r4, #0x80]			@ enable access to crunch
+	mov	r2, #0xaa
+	str	r2, [r4, #0xc0]
+	orr	r5, r5, #0x00800000
+	str	r5, [r4, #0x80]
+
+	mov	r0, #0				@ nothing to load
+	str	r0, [r3]			@ no more current owner
+	ldr	r2, [r4, #0x80]			@ flush out enable (@@@)
+	mov	r2, r2
+	bl	crunch_save
+
+	mov	r2, #0xaa			@ disable access to crunch
+	str	r2, [r4, #0xc0]
+	bic	r5, r5, #0x00800000
+	str	r5, [r4, #0x80]
+	ldr	r5, [r4, #0x80]			@ flush out enable (@@@)
+	mov	r5, r5
+
+1:	msr	cpsr_c, ip			@ restore interrupt mode
+	ldmfd	sp!, {r4, r5, pc}
+
+/*
+ * Copy crunch state to given memory address
+ *
+ * r0 = struct thread_info pointer of target task
+ * r1 = memory address where to store crunch state
+ *
+ * this is called mainly in the creation of signal stack frames
+ */
+ENTRY(crunch_task_copy)
+	mrs	ip, cpsr
+	orr	r2, ip, #PSR_I_BIT		@ disable interrupts
+	msr	cpsr_c, r2
+
+	ldr	r3, =crunch_owner
+	add	r2, r0, #TI_CRUNCH_STATE	@ get task crunch save area
+	ldr	r3, [r3]			@ get current crunch owner
+	teq	r2, r3				@ does this task own it...
+	beq	1f
+
+	@ current crunch values are in the task save area
+	msr	cpsr_c, ip			@ restore interrupt mode
+	mov	r0, r1
+	mov	r1, r2
+	mov	r2, #CRUNCH_SIZE
+	b	memcpy
+
+1:	@ this task owns crunch regs -- grab a copy from there
+	mov	r0, #0				@ nothing to load
+	mov	r3, lr				@ preserve return address
+	bl	crunch_save
+	msr	cpsr_c, ip			@ restore interrupt mode
+	mov	pc, r3
+
+/*
+ * Restore crunch state from given memory address
+ *
+ * r0 = struct thread_info pointer of target task
+ * r1 = memory address where to get crunch state from
+ *
+ * this is used to restore crunch state when unwinding a signal stack frame
+ */
+ENTRY(crunch_task_restore)
+	mrs	ip, cpsr
+	orr	r2, ip, #PSR_I_BIT		@ disable interrupts
+	msr	cpsr_c, r2
+
+	ldr	r3, =crunch_owner
+	add	r2, r0, #TI_CRUNCH_STATE	@ get task crunch save area
+	ldr	r3, [r3]			@ get current crunch owner
+	teq	r2, r3				@ does this task own it...
+	beq	1f
+
+	@ this task doesn't own crunch regs -- use its save area
+	msr	cpsr_c, ip			@ restore interrupt mode
+	mov	r0, r2
+	mov	r2, #CRUNCH_SIZE
+	b	memcpy
+
+1:	@ this task owns crunch regs -- load them directly
+	mov	r0, r1
+	mov	r1, #0				@ nothing to save
+	mov	r3, lr				@ preserve return address
+	bl	crunch_load
+	msr	cpsr_c, ip			@ restore interrupt mode
+	mov	pc, r3
diff --git a/arch/arm/kernel/crunch.c b/arch/arm/kernel/crunch.c
new file mode 100644
index 000000000..cec837832
--- /dev/null
+++ b/arch/arm/kernel/crunch.c
@@ -0,0 +1,82 @@
+/*
+ * arch/arm/kernel/crunch.c
+ * Cirrus MaverickCrunch context switching and handling
+ *
+ * Copyright (C) 2006 Lennert Buytenhek <buytenh@wantstofly.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.
+ */
+
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/init.h>
+#include <asm/arch/ep93xx-regs.h>
+#include <asm/thread_notify.h>
+#include <asm/io.h>
+
+struct crunch_state *crunch_owner;
+
+void crunch_task_release(struct thread_info *thread)
+{
+	local_irq_disable();
+	if (crunch_owner == &thread->crunchstate)
+		crunch_owner = NULL;
+	local_irq_enable();
+}
+
+static int crunch_enabled(u32 devcfg)
+{
+	return !!(devcfg & EP93XX_SYSCON_DEVICE_CONFIG_CRUNCH_ENABLE);
+}
+
+static int crunch_do(struct notifier_block *self, unsigned long cmd, void *t)
+{
+	struct thread_info *thread = (struct thread_info *)t;
+	struct crunch_state *crunch_state;
+	u32 devcfg;
+
+	crunch_state = &thread->crunchstate;
+
+	switch (cmd) {
+	case THREAD_NOTIFY_FLUSH:
+		memset(crunch_state, 0, sizeof(*crunch_state));
+
+		/*
+		 * FALLTHROUGH: Ensure we don't try to overwrite our newly
+		 * initialised state information on the first fault.
+		 */
+
+	case THREAD_NOTIFY_RELEASE:
+		crunch_task_release(thread);
+		break;
+
+	case THREAD_NOTIFY_SWITCH:
+		devcfg = __raw_readl(EP93XX_SYSCON_DEVICE_CONFIG);
+		if (crunch_enabled(devcfg) || crunch_owner == crunch_state) {
+			devcfg ^= EP93XX_SYSCON_DEVICE_CONFIG_CRUNCH_ENABLE;
+			__raw_writel(0xaa, EP93XX_SYSCON_SWLOCK);
+			__raw_writel(devcfg, EP93XX_SYSCON_DEVICE_CONFIG);
+		}
+		break;
+	}
+
+	return NOTIFY_DONE;
+}
+
+static struct notifier_block crunch_notifier_block = {
+	.notifier_call	= crunch_do,
+};
+
+static int __init crunch_init(void)
+{
+	thread_register_notifier(&crunch_notifier_block);
+
+	return 0;
+}
+
+late_initcall(crunch_init);
diff --git a/arch/arm/kernel/iwmmxt-notifier.c b/arch/arm/kernel/iwmmxt-notifier.c
new file mode 100644
index 000000000..0d1a1db40
--- /dev/null
+++ b/arch/arm/kernel/iwmmxt-notifier.c
@@ -0,0 +1,63 @@
+/*
+ *  linux/arch/arm/kernel/iwmmxt-notifier.c
+ *
+ *  XScale iWMMXt (Concan) context switching and handling
+ *
+ *  Initial code:
+ *  Copyright (c) 2003, Intel Corporation
+ *
+ *  Full lazy switching support, optimizations and more, by Nicolas Pitre
+ *  Copyright (c) 2003-2004, 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.
+ */
+
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/init.h>
+#include <asm/thread_notify.h>
+#include <asm/io.h>
+
+static int iwmmxt_do(struct notifier_block *self, unsigned long cmd, void *t)
+{
+	struct thread_info *thread = t;
+
+	switch (cmd) {
+	case THREAD_NOTIFY_FLUSH:
+		/*
+		 * flush_thread() zeroes thread->fpstate, so no need
+		 * to do anything here.
+		 *
+		 * FALLTHROUGH: Ensure we don't try to overwrite our newly
+		 * initialised state information on the first fault.
+		 */
+
+	case THREAD_NOTIFY_RELEASE:
+		iwmmxt_task_release(thread);
+		break;
+
+	case THREAD_NOTIFY_SWITCH:
+		iwmmxt_task_switch(thread);
+		break;
+	}
+
+	return NOTIFY_DONE;
+}
+
+static struct notifier_block iwmmxt_notifier_block = {
+	.notifier_call	= iwmmxt_do,
+};
+
+static int __init iwmmxt_init(void)
+{
+	thread_register_notifier(&iwmmxt_notifier_block);
+
+	return 0;
+}
+
+late_initcall(iwmmxt_init);
diff --git a/arch/arm/mach-at91rm9200/at91rm9200.c b/arch/arm/mach-at91rm9200/at91rm9200.c
new file mode 100644
index 000000000..0985b1c42
--- /dev/null
+++ b/arch/arm/mach-at91rm9200/at91rm9200.c
@@ -0,0 +1,154 @@
+/*
+ * arch/arm/mach-at91rm9200/at91rm9200.c
+ *
+ *  Copyright (C) 2005 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.
+ *
+ */
+
+#include <linux/module.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <asm/hardware.h>
+#include "generic.h"
+
+static struct map_desc at91rm9200_io_desc[] __initdata = {
+	{
+		.virtual	= AT91_VA_BASE_SYS,
+		.pfn		= __phys_to_pfn(AT91_BASE_SYS),
+		.length		= SZ_4K,
+		.type		= MT_DEVICE,
+	}, {
+		.virtual	= AT91_VA_BASE_SPI,
+		.pfn		= __phys_to_pfn(AT91_BASE_SPI),
+		.length		= SZ_16K,
+		.type		= MT_DEVICE,
+	}, {
+		.virtual	= AT91_VA_BASE_SSC2,
+		.pfn		= __phys_to_pfn(AT91_BASE_SSC2),
+		.length		= SZ_16K,
+		.type		= MT_DEVICE,
+	}, {
+		.virtual	= AT91_VA_BASE_SSC1,
+		.pfn		= __phys_to_pfn(AT91_BASE_SSC1),
+		.length		= SZ_16K,
+		.type		= MT_DEVICE,
+	}, {
+		.virtual	= AT91_VA_BASE_SSC0,
+		.pfn		= __phys_to_pfn(AT91_BASE_SSC0),
+		.length		= SZ_16K,
+		.type		= MT_DEVICE,
+	}, {
+		.virtual	= AT91_VA_BASE_US3,
+		.pfn		= __phys_to_pfn(AT91_BASE_US3),
+		.length		= SZ_16K,
+		.type		= MT_DEVICE,
+	}, {
+		.virtual	= AT91_VA_BASE_US2,
+		.pfn		= __phys_to_pfn(AT91_BASE_US2),
+		.length		= SZ_16K,
+		.type		= MT_DEVICE,
+	}, {
+		.virtual	= AT91_VA_BASE_US1,
+		.pfn		= __phys_to_pfn(AT91_BASE_US1),
+		.length		= SZ_16K,
+		.type		= MT_DEVICE,
+	}, {
+		.virtual	= AT91_VA_BASE_US0,
+		.pfn		= __phys_to_pfn(AT91_BASE_US0),
+		.length		= SZ_16K,
+		.type		= MT_DEVICE,
+	}, {
+		.virtual	= AT91_VA_BASE_EMAC,
+		.pfn		= __phys_to_pfn(AT91_BASE_EMAC),
+		.length		= SZ_16K,
+		.type		= MT_DEVICE,
+	}, {
+		.virtual	= AT91_VA_BASE_TWI,
+		.pfn		= __phys_to_pfn(AT91_BASE_TWI),
+		.length		= SZ_16K,
+		.type		= MT_DEVICE,
+	}, {
+		.virtual	= AT91_VA_BASE_MCI,
+		.pfn		= __phys_to_pfn(AT91_BASE_MCI),
+		.length		= SZ_16K,
+		.type		= MT_DEVICE,
+	}, {
+		.virtual	= AT91_VA_BASE_UDP,
+		.pfn		= __phys_to_pfn(AT91_BASE_UDP),
+		.length		= SZ_16K,
+		.type		= MT_DEVICE,
+	}, {
+		.virtual	= AT91_VA_BASE_TCB1,
+		.pfn		= __phys_to_pfn(AT91_BASE_TCB1),
+		.length		= SZ_16K,
+		.type		= MT_DEVICE,
+	}, {
+		.virtual	= AT91_VA_BASE_TCB0,
+		.pfn		= __phys_to_pfn(AT91_BASE_TCB0),
+		.length		= SZ_16K,
+		.type		= MT_DEVICE,
+	}, {
+		.virtual	= AT91_SRAM_VIRT_BASE,
+		.pfn		= __phys_to_pfn(AT91_SRAM_BASE),
+		.length		= AT91_SRAM_SIZE,
+		.type		= MT_DEVICE,
+	},
+};
+
+void __init at91rm9200_map_io(void)
+{
+	iotable_init(at91rm9200_io_desc, ARRAY_SIZE(at91rm9200_io_desc));
+}
+
+/*
+ * The default interrupt priority levels (0 = lowest, 7 = highest).
+ */
+static unsigned int at91rm9200_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 */
+	0,	/* Parallel IO Controller D */
+	6,	/* USART 0 */
+	6,	/* USART 1 */
+	6,	/* USART 2 */
+	6,	/* USART 3 */
+	0,	/* Multimedia Card Interface */
+	4,	/* USB Device Port */
+	0,	/* Two-Wire Interface */
+	6,	/* Serial Peripheral Interface */
+	5,	/* Serial Synchronous Controller 0 */
+	5,	/* Serial Synchronous Controller 1 */
+	5,	/* Serial Synchronous Controller 2 */
+	0,	/* Timer Counter 0 */
+	0,	/* Timer Counter 1 */
+	0,	/* Timer Counter 2 */
+	0,	/* Timer Counter 3 */
+	0,	/* Timer Counter 4 */
+	0,	/* Timer Counter 5 */
+	3,	/* USB Host port */
+	3,	/* Ethernet MAC */
+	0,	/* Advanced Interrupt Controller (IRQ0) */
+	0,	/* Advanced Interrupt Controller (IRQ1) */
+	0,	/* Advanced Interrupt Controller (IRQ2) */
+	0,	/* Advanced Interrupt Controller (IRQ3) */
+	0,	/* Advanced Interrupt Controller (IRQ4) */
+	0,	/* Advanced Interrupt Controller (IRQ5) */
+	0	/* Advanced Interrupt Controller (IRQ6) */
+};
+
+void __init at91rm9200_init_irq(unsigned int priority[NR_AIC_IRQS])
+{
+	if (!priority)
+		priority = at91rm9200_default_irq_priority;
+
+	at91_aic_init(priority);
+}
diff --git a/arch/arm/mach-at91rm9200/at91rm9200_time.c b/arch/arm/mach-at91rm9200/at91rm9200_time.c
new file mode 100644
index 000000000..a92a8622c
--- /dev/null
+++ b/arch/arm/mach-at91rm9200/at91rm9200_time.c
@@ -0,0 +1,141 @@
+/*
+ * linux/arch/arm/mach-at91rm9200/at91rm9200_time.c
+ *
+ *  Copyright (C) 2003 SAN People
+ *  Copyright (C) 2003 ATMEL
+ *
+ * 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/interrupt.h>
+#include <linux/irq.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/time.h>
+
+#include <asm/hardware.h>
+#include <asm/io.h>
+#include <asm/mach/time.h>
+
+static unsigned long last_crtr;
+
+/*
+ * The ST_CRTR is updated asynchronously to the master clock.  It is therefore
+ *  necessary to read it twice (with the same value) to ensure accuracy.
+ */
+static inline unsigned long read_CRTR(void) {
+	unsigned long x1, x2;
+
+	do {
+		x1 = at91_sys_read(AT91_ST_CRTR);
+		x2 = at91_sys_read(AT91_ST_CRTR);
+	} while (x1 != x2);
+
+	return x1;
+}
+
+/*
+ * 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 at91rm9200_gettimeoffset(void)
+{
+	unsigned long elapsed;
+
+	elapsed = (read_CRTR() - last_crtr) & AT91_ST_ALMV;
+
+	return (unsigned long)(elapsed * (tick_nsec / 1000)) / LATCH;
+}
+
+/*
+ * IRQ handler for the timer.
+ */
+static irqreturn_t at91rm9200_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	if (at91_sys_read(AT91_ST_SR) & AT91_ST_PITS) {	/* This is a shared interrupt */
+		write_seqlock(&xtime_lock);
+
+		while (((read_CRTR() - last_crtr) & AT91_ST_ALMV) >= LATCH) {
+			timer_tick(regs);
+			last_crtr = (last_crtr + LATCH) & AT91_ST_ALMV;
+		}
+
+		write_sequnlock(&xtime_lock);
+
+		return IRQ_HANDLED;
+	}
+	else
+		return IRQ_NONE;		/* not handled */
+}
+
+static struct irqaction at91rm9200_timer_irq = {
+	.name		= "at91_tick",
+	.flags		= IRQF_SHARED | IRQF_DISABLED | IRQF_TIMER,
+	.handler	= at91rm9200_timer_interrupt
+};
+
+void at91rm9200_timer_reset(void)
+{
+	last_crtr = 0;
+
+	/* Real time counter incremented every 30.51758 microseconds */
+	at91_sys_write(AT91_ST_RTMR, 1);
+
+	/* Set Period Interval timer */
+	at91_sys_write(AT91_ST_PIMR, LATCH);
+
+	/* Enable Period Interval Timer interrupt */
+	at91_sys_write(AT91_ST_IER, AT91_ST_PITS);
+}
+
+/*
+ * Set up timer interrupt.
+ */
+void __init at91rm9200_timer_init(void)
+{
+	/* Disable all timer interrupts */
+	at91_sys_write(AT91_ST_IDR, AT91_ST_PITS | AT91_ST_WDOVF | AT91_ST_RTTINC | AT91_ST_ALMS);
+	(void) at91_sys_read(AT91_ST_SR);	/* Clear any pending interrupts */
+
+	/* Make IRQs happen for the system timer */
+	setup_irq(AT91_ID_SYS, &at91rm9200_timer_irq);
+
+	/* Change the kernel's 'tick' value to 10009 usec. (the default is 10000) */
+	tick_usec = (LATCH * 1000000) / CLOCK_TICK_RATE;
+
+	/* Initialize and enable the timer interrupt */
+	at91rm9200_timer_reset();
+}
+
+#ifdef CONFIG_PM
+static void at91rm9200_timer_suspend(void)
+{
+	/* disable Period Interval Timer interrupt */
+	at91_sys_write(AT91_ST_IDR, AT91_ST_PITS);
+}
+#else
+#define at91rm9200_timer_suspend	NULL
+#endif
+
+struct sys_timer at91rm9200_timer = {
+	.init		= at91rm9200_timer_init,
+	.offset		= at91rm9200_gettimeoffset,
+	.suspend	= at91rm9200_timer_suspend,
+	.resume		= at91rm9200_timer_reset,
+};
+
diff --git a/arch/arm/mach-at91rm9200/board-1arm.c b/arch/arm/mach-at91rm9200/board-1arm.c
new file mode 100644
index 000000000..051a295e8
--- /dev/null
+++ b/arch/arm/mach-at91rm9200/board-1arm.c
@@ -0,0 +1,108 @@
+/*
+ * linux/arch/arm/mach-at91rm9200/board-1arm.c
+ *
+ *  Copyright (C) 2005 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.
+ *
+ * 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/types.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+
+#include <asm/hardware.h>
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+#include <asm/irq.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <asm/hardware.h>
+#include <asm/arch/board.h>
+#include <asm/arch/gpio.h>
+
+#include "generic.h"
+
+static void __init onearm_init_irq(void)
+{
+	/* Initialize AIC controller */
+	at91rm9200_init_irq(NULL);
+
+	/* Set up the GPIO interrupts */
+	at91_gpio_irq_setup(PQFP_GPIO_BANKS);
+}
+
+/*
+ * Serial port configuration.
+ *    0 .. 3 = USART0 .. USART3
+ *    4      = DBGU
+ */
+static struct at91_uart_config __initdata onearm_uart_config = {
+	.console_tty	= 0,				/* ttyS0 */
+	.nr_tty		= 3,
+	.tty_map	= { 4, 0, 1, -1, -1 },		/* ttyS0, ..., ttyS4 */
+};
+
+static void __init onearm_map_io(void)
+{
+	at91rm9200_map_io();
+
+	/* Initialize clocks: 18.432 MHz crystal */
+	at91_clock_init(18432000);
+
+	/* Setup the serial ports and console */
+	at91_init_serial(&onearm_uart_config);
+}
+
+static struct at91_eth_data __initdata onearm_eth_data = {
+	.phy_irq_pin	= AT91_PIN_PC4,
+	.is_rmii	= 1,
+};
+
+static struct at91_usbh_data __initdata onearm_usbh_data = {
+	.ports		= 1,
+};
+
+static struct at91_udc_data __initdata onearm_udc_data = {
+	.vbus_pin	= AT91_PIN_PC2,
+	.pullup_pin	= AT91_PIN_PC3,
+};
+
+static void __init onearm_board_init(void)
+{
+	/* Serial */
+	at91_add_device_serial();
+	/* Ethernet */
+	at91_add_device_eth(&onearm_eth_data);
+	/* USB Host */
+	at91_add_device_usbh(&onearm_usbh_data);
+	/* USB Device */
+	at91_add_device_udc(&onearm_udc_data);
+}
+
+MACHINE_START(ONEARM, "Ajeco 1ARM single board computer")
+	/* Maintainer: Lennert Buytenhek <buytenh@wantstofly.org> */
+	.phys_io	= AT91_BASE_SYS,
+	.io_pg_offst	= (AT91_VA_BASE_SYS >> 18) & 0xfffc,
+	.boot_params	= AT91_SDRAM_BASE + 0x100,
+	.timer		= &at91rm9200_timer,
+	.map_io		= onearm_map_io,
+	.init_irq	= onearm_init_irq,
+	.init_machine	= onearm_board_init,
+MACHINE_END
diff --git a/arch/arm/mach-at91rm9200/board-carmeva.c b/arch/arm/mach-at91rm9200/board-carmeva.c
new file mode 100644
index 000000000..1efcd04fd
--- /dev/null
+++ b/arch/arm/mach-at91rm9200/board-carmeva.c
@@ -0,0 +1,130 @@
+/*
+ * linux/arch/arm/mach-at91rm9200/board-carmeva.c
+ *
+ *  Copyright (c) 2005 Peer Georgi
+ *  		       Conitec Datasystems
+ *
+ * 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/types.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+
+#include <asm/hardware.h>
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+#include <asm/irq.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <asm/hardware.h>
+#include <asm/arch/board.h>
+#include <asm/arch/gpio.h>
+
+#include "generic.h"
+
+static void __init carmeva_init_irq(void)
+{
+	/* Initialize AIC controller */
+	at91rm9200_init_irq(NULL);
+
+	/* Set up the GPIO interrupts */
+	at91_gpio_irq_setup(BGA_GPIO_BANKS);
+}
+
+/*
+ * Serial port configuration.
+ *    0 .. 3 = USART0 .. USART3
+ *    4      = DBGU
+ */
+static struct at91_uart_config __initdata carmeva_uart_config = {
+	.console_tty	= 0,				/* ttyS0 */
+	.nr_tty		= 2,
+	.tty_map	= { 4, 1, -1, -1, -1 }		/* ttyS0, ..., ttyS4 */
+};
+
+static void __init carmeva_map_io(void)
+{
+	at91rm9200_map_io();
+
+	/* Initialize clocks: 20.000 MHz crystal */
+	at91_clock_init(20000000);
+
+	/* Setup the serial ports and console */
+	at91_init_serial(&carmeva_uart_config);
+}
+
+static struct at91_eth_data __initdata carmeva_eth_data = {
+	.phy_irq_pin	= AT91_PIN_PC4,
+	.is_rmii	= 1,
+};
+
+static struct at91_usbh_data __initdata carmeva_usbh_data = {
+	.ports		= 2,
+};
+
+static struct at91_udc_data __initdata carmeva_udc_data = {
+	.vbus_pin	= AT91_PIN_PD12,
+	.pullup_pin	= AT91_PIN_PD9,
+};
+
+/* FIXME: user dependend */
+// static struct at91_cf_data __initdata carmeva_cf_data = {
+//	.det_pin	= AT91_PIN_PB0,
+//	.rst_pin	= AT91_PIN_PC5,
+	// .irq_pin	= ... not connected
+	// .vcc_pin	= ... always powered
+// };
+
+static struct at91_mmc_data __initdata carmeva_mmc_data = {
+	.is_b		= 0,
+	.wire4		= 1,
+};
+
+static void __init carmeva_board_init(void)
+{
+	/* Serial */
+	at91_add_device_serial();
+	/* Ethernet */
+	at91_add_device_eth(&carmeva_eth_data);
+	/* USB Host */
+	at91_add_device_usbh(&carmeva_usbh_data);
+	/* USB Device */
+	at91_add_device_udc(&carmeva_udc_data);
+	/* I2C */
+	at91_add_device_i2c();
+	/* Compact Flash */
+//	at91_add_device_cf(&carmeva_cf_data);
+	/* SPI */
+//	at91_add_device_spi(NULL, 0);
+	/* MMC */
+	at91_add_device_mmc(&carmeva_mmc_data);
+}
+
+MACHINE_START(CARMEVA, "Carmeva")
+	/* Maintainer: Conitec Datasystems */
+	.phys_io	= AT91_BASE_SYS,
+	.io_pg_offst	= (AT91_VA_BASE_SYS >> 18) & 0xfffc,
+	.boot_params	= AT91_SDRAM_BASE + 0x100,
+	.timer		= &at91rm9200_timer,
+	.map_io		= carmeva_map_io,
+	.init_irq	= carmeva_init_irq,
+	.init_machine	= carmeva_board_init,
+MACHINE_END
diff --git a/arch/arm/mach-at91rm9200/board-eb9200.c b/arch/arm/mach-at91rm9200/board-eb9200.c
new file mode 100644
index 000000000..4531f34c6
--- /dev/null
+++ b/arch/arm/mach-at91rm9200/board-eb9200.c
@@ -0,0 +1,129 @@
+/*
+ * linux/arch/arm/mach-at91rm9200/board-eb9200.c
+ *
+ *  Copyright (C) 2005 SAN People, adapted for ATEB9200 from Embest
+ *  by Andrew Patrikalakis
+ *
+ * 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/types.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/device.h>
+
+#include <asm/hardware.h>
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+#include <asm/irq.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <asm/hardware.h>
+#include <asm/arch/board.h>
+#include <asm/arch/gpio.h>
+
+#include "generic.h"
+
+static void __init eb9200_init_irq(void)
+{
+	/* Initialize AIC controller */
+	at91rm9200_init_irq(NULL);
+
+	/* Set up the GPIO interrupts */
+	at91_gpio_irq_setup(BGA_GPIO_BANKS);
+}
+
+/*
+ * Serial port configuration.
+ *    0 .. 3 = USART0 .. USART3
+ *    4      = DBGU
+ */
+static struct at91_uart_config __initdata eb9200_uart_config = {
+	.console_tty	= 0,				/* ttyS0 */
+	.nr_tty		= 2,
+	.tty_map	= { 4, 1, -1, -1, -1 }		/* ttyS0, ..., ttyS4 */
+};
+
+static void __init eb9200_map_io(void)
+{
+	at91rm9200_map_io();
+
+	/* Initialize clocks: 18.432 MHz crystal */
+	at91_clock_init(18432000);
+
+	/* Setup the serial ports and console */
+	at91_init_serial(&eb9200_uart_config);
+}
+
+static struct at91_eth_data __initdata eb9200_eth_data = {
+	.phy_irq_pin	= AT91_PIN_PC4,
+	.is_rmii	= 1,
+};
+
+static struct at91_usbh_data __initdata eb9200_usbh_data = {
+	.ports		= 2,
+};
+
+static struct at91_udc_data __initdata eb9200_udc_data = {
+	.vbus_pin	= AT91_PIN_PD4,
+	.pullup_pin	= AT91_PIN_PD5,
+};
+
+static struct at91_cf_data __initdata eb9200_cf_data = {
+	.det_pin	= AT91_PIN_PB0,
+	.rst_pin	= AT91_PIN_PC5,
+	// .irq_pin	= ... not connected
+	// .vcc_pin	= ... always powered
+};
+
+static struct at91_mmc_data __initdata eb9200_mmc_data = {
+	.is_b		= 0,
+	.wire4		= 1,
+};
+
+static void __init eb9200_board_init(void)
+{
+	/* Serial */
+	at91_add_device_serial();
+	/* Ethernet */
+	at91_add_device_eth(&eb9200_eth_data);
+	/* USB Host */
+	at91_add_device_usbh(&eb9200_usbh_data);
+	/* USB Device */
+	at91_add_device_udc(&eb9200_udc_data);
+	/* I2C */
+	at91_add_device_i2c();
+	/* Compact Flash */
+	at91_add_device_cf(&eb9200_cf_data);
+	/* SPI */
+	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);
+}
+
+MACHINE_START(ATEB9200, "Embest ATEB9200")
+	.phys_io	= AT91_BASE_SYS,
+	.io_pg_offst	= (AT91_VA_BASE_SYS >> 18) & 0xfffc,
+	.boot_params	= AT91_SDRAM_BASE + 0x100,
+	.timer		= &at91rm9200_timer,
+	.map_io		= eb9200_map_io,
+	.init_irq	= eb9200_init_irq,
+	.init_machine	= eb9200_board_init,
+MACHINE_END
diff --git a/arch/arm/mach-at91rm9200/board-kafa.c b/arch/arm/mach-at91rm9200/board-kafa.c
new file mode 100644
index 000000000..354b91c6b
--- /dev/null
+++ b/arch/arm/mach-at91rm9200/board-kafa.c
@@ -0,0 +1,115 @@
+/*
+ * linux/arch/arm/mach-at91rm9200/board-kafa.c
+ *
+ *  Copyright (C) 2006 Sperry-Sun
+ *
+ * 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/types.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+
+#include <asm/hardware.h>
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+#include <asm/irq.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <asm/hardware.h>
+#include <asm/arch/board.h>
+#include <asm/arch/gpio.h>
+
+#include "generic.h"
+
+static void __init kafa_init_irq(void)
+{
+	/* Initialize AIC controller */
+	at91rm9200_init_irq(NULL);
+
+	/* Set up the GPIO interrupts */
+	at91_gpio_irq_setup(PQFP_GPIO_BANKS);
+}
+
+/*
+ * Serial port configuration.
+ *    0 .. 3 = USART0 .. USART3
+ *    4      = DBGU
+ */
+static struct at91_uart_config __initdata kafa_uart_config = {
+	.console_tty	= 0,				/* ttyS0 */
+	.nr_tty		= 2,
+	.tty_map	= { 4, 0, -1, -1, -1 }		/* ttyS0, ..., ttyS4 */
+};
+
+static void __init kafa_map_io(void)
+{
+	at91rm9200_map_io();
+
+	/* Initialize clocks: 18.432 MHz crystal */
+	at91_clock_init(18432000);
+
+	/* Set up the LEDs */
+	at91_init_leds(AT91_PIN_PB4, AT91_PIN_PB4);
+
+	/* Setup the serial ports and console */
+	at91_init_serial(&kafa_uart_config);
+}
+
+static struct at91_eth_data __initdata kafa_eth_data = {
+	.phy_irq_pin	= AT91_PIN_PC4,
+	.is_rmii	= 0,
+};
+
+static struct at91_usbh_data __initdata kafa_usbh_data = {
+	.ports		= 1,
+};
+
+static struct at91_udc_data __initdata kafa_udc_data = {
+	.vbus_pin	= AT91_PIN_PB6,
+	.pullup_pin	= AT91_PIN_PB7,
+};
+
+static void __init kafa_board_init(void)
+{
+	/* Serial */
+	at91_add_device_serial();
+	/* Ethernet */
+	at91_add_device_eth(&kafa_eth_data);
+	/* USB Host */
+	at91_add_device_usbh(&kafa_usbh_data);
+	/* USB Device */
+	at91_add_device_udc(&kafa_udc_data);
+	/* I2C */
+	at91_add_device_i2c();
+	/* SPI */
+	at91_add_device_spi(NULL, 0);
+}
+
+MACHINE_START(KAFA, "Sperry-Sun KAFA")
+	/* Maintainer: Sergei Sharonov */
+	.phys_io	= AT91_BASE_SYS,
+	.io_pg_offst	= (AT91_VA_BASE_SYS >> 18) & 0xfffc,
+	.boot_params	= AT91_SDRAM_BASE + 0x100,
+	.timer		= &at91rm9200_timer,
+	.map_io		= kafa_map_io,
+	.init_irq	= kafa_init_irq,
+	.init_machine	= kafa_board_init,
+MACHINE_END
diff --git a/arch/arm/mach-at91rm9200/board-kb9202.c b/arch/arm/mach-at91rm9200/board-kb9202.c
new file mode 100644
index 000000000..1827db4c5
--- /dev/null
+++ b/arch/arm/mach-at91rm9200/board-kb9202.c
@@ -0,0 +1,124 @@
+/*
+ * linux/arch/arm/mach-at91rm9200/board-kb9202.c
+ *
+ *  Copyright (c) 2005 kb_admin
+ *  		       KwikByte, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+
+#include <asm/hardware.h>
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+#include <asm/irq.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <asm/hardware.h>
+#include <asm/arch/board.h>
+#include <asm/arch/gpio.h>
+
+#include "generic.h"
+
+static void __init kb9202_init_irq(void)
+{
+	/* Initialize AIC controller */
+	at91rm9200_init_irq(NULL);
+
+	/* Set up the GPIO interrupts */
+	at91_gpio_irq_setup(PQFP_GPIO_BANKS);
+}
+
+/*
+ * Serial port configuration.
+ *    0 .. 3 = USART0 .. USART3
+ *    4      = DBGU
+ */
+static struct at91_uart_config __initdata kb9202_uart_config = {
+	.console_tty	= 0,					/* ttyS0 */
+	.nr_tty		= 3,
+	.tty_map	= { 4, 0, 1, -1, -1 }			/* ttyS0, ..., ttyS4 */
+};
+
+static void __init kb9202_map_io(void)
+{
+	at91rm9200_map_io();
+
+	/* Initialize clocks: 10 MHz crystal */
+	at91_clock_init(10000000);
+
+	/* Set up the LEDs */
+	at91_init_leds(AT91_PIN_PC19, AT91_PIN_PC18);
+
+	/* Setup the serial ports and console */
+	at91_init_serial(&kb9202_uart_config);
+}
+
+static struct at91_eth_data __initdata kb9202_eth_data = {
+	.phy_irq_pin	= AT91_PIN_PB29,
+	.is_rmii	= 0,
+};
+
+static struct at91_usbh_data __initdata kb9202_usbh_data = {
+	.ports		= 1,
+};
+
+static struct at91_udc_data __initdata kb9202_udc_data = {
+	.vbus_pin	= AT91_PIN_PB24,
+	.pullup_pin	= AT91_PIN_PB22,
+};
+
+static struct at91_mmc_data __initdata kb9202_mmc_data = {
+	.det_pin	= AT91_PIN_PB2,
+	.is_b		= 0,
+	.wire4		= 1,
+};
+
+static void __init kb9202_board_init(void)
+{
+	/* Serial */
+	at91_add_device_serial();
+	/* Ethernet */
+	at91_add_device_eth(&kb9202_eth_data);
+	/* USB Host */
+	at91_add_device_usbh(&kb9202_usbh_data);
+	/* USB Device */
+	at91_add_device_udc(&kb9202_udc_data);
+	/* MMC */
+	at91_add_device_mmc(&kb9202_mmc_data);
+	/* I2C */
+	at91_add_device_i2c();
+	/* SPI */
+	at91_add_device_spi(NULL, 0);
+}
+
+MACHINE_START(KB9200, "KB920x")
+	/* Maintainer: KwikByte, Inc. */
+	.phys_io	= AT91_BASE_SYS,
+	.io_pg_offst	= (AT91_VA_BASE_SYS >> 18) & 0xfffc,
+	.boot_params	= AT91_SDRAM_BASE + 0x100,
+	.timer		= &at91rm9200_timer,
+	.map_io		= kb9202_map_io,
+	.init_irq	= kb9202_init_irq,
+	.init_machine	= kb9202_board_init,
+MACHINE_END
diff --git a/arch/arm/mach-at91rm9200/pm.c b/arch/arm/mach-at91rm9200/pm.c
new file mode 100644
index 000000000..47e5480fe
--- /dev/null
+++ b/arch/arm/mach-at91rm9200/pm.c
@@ -0,0 +1,225 @@
+/*
+ * arch/arm/mach-at91rm9200/pm.c
+ * AT91 Power Management
+ *
+ * Copyright (C) 2005 David Brownell
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/pm.h>
+#include <linux/sched.h>
+#include <linux/proc_fs.h>
+#include <linux/pm.h>
+#include <linux/interrupt.h>
+#include <linux/sysfs.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/atomic.h>
+#include <asm/mach/time.h>
+#include <asm/mach/irq.h>
+#include <asm/mach-types.h>
+
+#include <asm/arch/gpio.h>
+
+#include "generic.h"
+
+
+static int at91_pm_valid_state(suspend_state_t state)
+{
+	switch (state) {
+		case PM_SUSPEND_ON:
+		case PM_SUSPEND_STANDBY:
+		case PM_SUSPEND_MEM:
+			return 1;
+
+		default:
+			return 0;
+	}
+}
+
+
+static suspend_state_t target_state;
+
+/*
+ * Called after processes are frozen, but before we shutdown devices.
+ */
+static int at91_pm_prepare(suspend_state_t state)
+{
+	target_state = state;
+	return 0;
+}
+
+/*
+ * Verify that all the clocks are correct before entering
+ * slow-clock mode.
+ */
+static int at91_pm_verify_clocks(void)
+{
+	unsigned long scsr;
+	int i;
+
+	scsr = at91_sys_read(AT91_PMC_SCSR);
+
+	/* USB must not be using PLLB */
+	if ((scsr & (AT91_PMC_UHP | AT91_PMC_UDP)) != 0) {
+		pr_debug("AT91: PM - Suspend-to-RAM with USB still active\n");
+		return 0;
+	}
+
+#ifdef CONFIG_AT91_PROGRAMMABLE_CLOCKS
+	/* PCK0..PCK3 must be disabled, or configured to use clk32k */
+	for (i = 0; i < 4; i++) {
+		u32 css;
+
+		if ((scsr & (AT91_PMC_PCK0 << i)) == 0)
+			continue;
+
+		css = at91_sys_read(AT91_PMC_PCKR(i)) & AT91_PMC_CSS;
+		if (css != AT91_PMC_CSS_SLOW) {
+			pr_debug("AT91: PM - Suspend-to-RAM with PCK%d src %d\n", i, css);
+			return 0;
+		}
+	}
+#endif
+
+	return 1;
+}
+
+/*
+ * Call this from platform driver suspend() to see how deeply to suspend.
+ * For example, some controllers (like OHCI) need one of the PLL clocks
+ * in order to act as a wakeup source, and those are not available when
+ * going into slow clock mode.
+ *
+ * REVISIT: generalize as clk_will_be_available(clk)?  Other platforms have
+ * the very same problem (but not using at91 main_clk), and it'd be better
+ * to add one generic API rather than lots of platform-specific ones.
+ */
+int at91_suspend_entering_slow_clock(void)
+{
+	return (target_state == PM_SUSPEND_MEM);
+}
+EXPORT_SYMBOL(at91_suspend_entering_slow_clock);
+
+
+static void (*slow_clock)(void);
+
+
+
+static int at91_pm_enter(suspend_state_t state)
+{
+	at91_gpio_suspend();
+	at91_irq_suspend();
+
+	pr_debug("AT91: PM - wake mask %08x, pm state %d\n",
+			/* remember all the always-wake irqs */
+			(at91_sys_read(AT91_PMC_PCSR)
+					| (1 << AT91_ID_FIQ)
+					| (1 << AT91_ID_SYS)
+					| (1 << AT91_ID_IRQ0)
+					| (1 << AT91_ID_IRQ1)
+					| (1 << AT91_ID_IRQ2)
+					| (1 << AT91_ID_IRQ3)
+					| (1 << AT91_ID_IRQ4)
+					| (1 << AT91_ID_IRQ5)
+					| (1 << AT91_ID_IRQ6))
+				& at91_sys_read(AT91_AIC_IMR),
+			state);
+
+	switch (state) {
+		/*
+		 * Suspend-to-RAM is like STANDBY plus slow clock mode, so
+		 * drivers must suspend more deeply:  only the master clock
+		 * controller may be using the main oscillator.
+		 */
+		case PM_SUSPEND_MEM:
+			/*
+			 * Ensure that clocks are in a valid state.
+			 */
+			if (!at91_pm_verify_clocks())
+				goto error;
+
+			/*
+			 * Enter slow clock mode by switching over to clk32k and
+			 * turning off the main oscillator; reverse on wakeup.
+			 */
+			if (slow_clock) {
+				slow_clock();
+				break;
+			} else {
+				/* DEVELOPMENT ONLY */
+				pr_info("AT91: PM - no slow clock mode yet ...\n");
+				/* FALLTHROUGH leaving master clock alone */
+			}
+
+		/*
+		 * STANDBY mode has *all* drivers suspended; ignores irqs not
+		 * marked as 'wakeup' event sources; and reduces DRAM power.
+		 * But otherwise it's identical to PM_SUSPEND_ON:  cpu idle, and
+		 * nothing fancy done with main or cpu clocks.
+		 */
+		case PM_SUSPEND_STANDBY:
+			/*
+			 * NOTE: the Wait-for-Interrupt instruction needs to be
+			 * in icache so the SDRAM stays in self-refresh mode until
+			 * the wakeup IRQ occurs.
+			 */
+			asm("b 1f; .align 5; 1:");
+			asm("mcr p15, 0, r0, c7, c10, 4");	/* drain write buffer */
+			at91_sys_write(AT91_SDRAMC_SRR, 1);	/* self-refresh mode */
+			/* fall though to next state */
+
+		case PM_SUSPEND_ON:
+			asm("mcr p15, 0, r0, c7, c0, 4");	/* wait for interrupt */
+			break;
+
+		default:
+			pr_debug("AT91: PM - bogus suspend state %d\n", state);
+			goto error;
+	}
+
+	pr_debug("AT91: PM - wakeup %08x\n",
+			at91_sys_read(AT91_AIC_IPR) & at91_sys_read(AT91_AIC_IMR));
+
+error:
+	target_state = PM_SUSPEND_ON;
+	at91_irq_resume();
+	at91_gpio_resume();
+	return 0;
+}
+
+
+static struct pm_ops at91_pm_ops ={
+	.pm_disk_mode	= 0,
+	.valid		= at91_pm_valid_state,
+	.prepare	= at91_pm_prepare,
+	.enter		= at91_pm_enter,
+};
+
+static int __init at91_pm_init(void)
+{
+	printk("AT91: Power Management\n");
+
+#ifdef CONFIG_AT91_PM_SLOW_CLOCK
+	/* REVISIT allocations of SRAM should be dynamically managed.
+	 * FIQ handlers and other components will want SRAM/TCM too...
+	 */
+	slow_clock = (void *) (AT91_VA_BASE_SRAM + (3 * SZ_4K));
+	memcpy(slow_clock, at91rm9200_slow_clock, at91rm9200_slow_clock_sz);
+#endif
+
+	/* Disable SDRAM low-power mode.  Cannot be used with self-refresh. */
+	at91_sys_write(AT91_SDRAMC_LPR, 0);
+
+	pm_set_ops(&at91_pm_ops);
+
+	return 0;
+}
+arch_initcall(at91_pm_init);
diff --git a/arch/arm/mach-ep93xx/clock.c b/arch/arm/mach-ep93xx/clock.c
new file mode 100644
index 000000000..08ad782c1
--- /dev/null
+++ b/arch/arm/mach-ep93xx/clock.c
@@ -0,0 +1,156 @@
+/*
+ * arch/arm/mach-ep93xx/clock.c
+ * Clock control for Cirrus EP93xx chips.
+ *
+ * Copyright (C) 2006 Lennert Buytenhek <buytenh@wantstofly.org>
+ *
+ * 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/kernel.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/string.h>
+#include <asm/div64.h>
+#include <asm/hardware.h>
+#include <asm/io.h>
+
+struct clk {
+	char		*name;
+	unsigned long	rate;
+	int		users;
+	u32		enable_reg;
+	u32		enable_mask;
+};
+
+static struct clk clk_pll1 = {
+	.name		= "pll1",
+};
+static struct clk clk_f = {
+	.name		= "fclk",
+};
+static struct clk clk_h = {
+	.name		= "hclk",
+};
+static struct clk clk_p = {
+	.name		= "pclk",
+};
+static struct clk clk_pll2 = {
+	.name		= "pll2",
+};
+static struct clk clk_usb_host = {
+	.name		= "usb_host",
+	.enable_reg	= EP93XX_SYSCON_CLOCK_CONTROL,
+	.enable_mask	= EP93XX_SYSCON_CLOCK_USH_EN,
+};
+
+
+static struct clk *clocks[] = {
+	&clk_pll1,
+	&clk_f,
+	&clk_h,
+	&clk_p,
+	&clk_pll2,
+	&clk_usb_host,
+};
+
+struct clk *clk_get(struct device *dev, const char *id)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(clocks); i++) {
+		if (!strcmp(clocks[i]->name, id))
+			return clocks[i];
+	}
+
+	return ERR_PTR(-ENOENT);
+}
+
+int clk_enable(struct clk *clk)
+{
+	if (!clk->users++ && clk->enable_reg) {
+		u32 value;
+
+		value = __raw_readl(clk->enable_reg);
+		__raw_writel(value | clk->enable_mask, clk->enable_reg);
+	}
+
+	return 0;
+}
+
+void clk_disable(struct clk *clk)
+{
+	if (!--clk->users && clk->enable_reg) {
+		u32 value;
+
+		value = __raw_readl(clk->enable_reg);
+		__raw_writel(value & ~clk->enable_mask, clk->enable_reg);
+	}
+}
+
+unsigned long clk_get_rate(struct clk *clk)
+{
+	return clk->rate;
+}
+
+void clk_put(struct clk *clk)
+{
+}
+
+
+
+static char fclk_divisors[] = { 1, 2, 4, 8, 16, 1, 1, 1 };
+static char hclk_divisors[] = { 1, 2, 4, 5, 6, 8, 16, 32 };
+static char pclk_divisors[] = { 1, 2, 4, 8 };
+
+/*
+ * PLL rate = 14.7456 MHz * (X1FBD + 1) * (X2FBD + 1) / (X2IPD + 1) / 2^PS
+ */
+static unsigned long calc_pll_rate(u32 config_word)
+{
+	unsigned long long rate;
+	int i;
+
+	rate = 14745600;
+	rate *= ((config_word >> 11) & 0x1f) + 1;		/* X1FBD */
+	rate *= ((config_word >> 5) & 0x3f) + 1;		/* X2FBD */
+	do_div(rate, (config_word & 0x1f) + 1);			/* X2IPD */
+	for (i = 0; i < ((config_word >> 16) & 3); i++)		/* PS */
+		rate >>= 1;
+
+	return (unsigned long)rate;
+}
+
+void ep93xx_clock_init(void)
+{
+	u32 value;
+
+	value = __raw_readl(EP93XX_SYSCON_CLOCK_SET1);
+	if (!(value & 0x00800000)) {			/* PLL1 bypassed?  */
+		clk_pll1.rate = 14745600;
+	} else {
+		clk_pll1.rate = calc_pll_rate(value);
+	}
+	clk_f.rate = clk_pll1.rate / fclk_divisors[(value >> 25) & 0x7];
+	clk_h.rate = clk_pll1.rate / hclk_divisors[(value >> 20) & 0x7];
+	clk_p.rate = clk_h.rate / pclk_divisors[(value >> 18) & 0x3];
+
+	value = __raw_readl(EP93XX_SYSCON_CLOCK_SET2);
+	if (!(value & 0x00080000)) {			/* PLL2 bypassed?  */
+		clk_pll2.rate = 14745600;
+	} else if (value & 0x00040000) {		/* PLL2 enabled?  */
+		clk_pll2.rate = calc_pll_rate(value);
+	} else {
+		clk_pll2.rate = 0;
+	}
+	clk_usb_host.rate = clk_pll2.rate / (((value >> 28) & 0xf) + 1);
+
+	printk(KERN_INFO "ep93xx: PLL1 running at %ld MHz, PLL2 at %ld MHz\n",
+		clk_pll1.rate / 1000000, clk_pll2.rate / 1000000);
+	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);
+}
diff --git a/arch/arm/mach-ep93xx/edb9302.c b/arch/arm/mach-ep93xx/edb9302.c
new file mode 100644
index 000000000..0315615b7
--- /dev/null
+++ b/arch/arm/mach-ep93xx/edb9302.c
@@ -0,0 +1,61 @@
+/*
+ * arch/arm/mach-ep93xx/edb9302.c
+ * Cirrus Logic EDB9302 support.
+ *
+ * Copyright (C) 2006 George Kashperko <george@chas.com.ua>
+ *
+ * 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/kernel.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/mtd/physmap.h>
+#include <linux/platform_device.h>
+#include <asm/io.h>
+#include <asm/hardware.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+static struct physmap_flash_data edb9302_flash_data = {
+	.width		= 2,
+};
+
+static struct resource edb9302_flash_resource = {
+	.start		= 0x60000000,
+	.end		= 0x60ffffff,
+	.flags		= IORESOURCE_MEM,
+};
+
+static struct platform_device edb9302_flash = {
+	.name		= "physmap-flash",
+	.id		= 0,
+	.dev		= {
+		.platform_data	= &edb9302_flash_data,
+	},
+	.num_resources	= 1,
+	.resource	= &edb9302_flash_resource,
+};
+
+static void __init edb9302_init_machine(void)
+{
+	ep93xx_init_devices();
+	platform_device_register(&edb9302_flash);
+}
+
+MACHINE_START(EDB9302, "Cirrus Logic EDB9302 Evaluation Board")
+	/* Maintainer: George Kashperko <george@chas.com.ua> */
+	.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	= edb9302_init_machine,
+MACHINE_END
diff --git a/arch/arm/mach-ep93xx/edb9315.c b/arch/arm/mach-ep93xx/edb9315.c
new file mode 100644
index 000000000..249ca9e57
--- /dev/null
+++ b/arch/arm/mach-ep93xx/edb9315.c
@@ -0,0 +1,61 @@
+/*
+ * arch/arm/mach-ep93xx/edb9315.c
+ * Cirrus Logic EDB9315 support.
+ *
+ * Copyright (C) 2006 Lennert Buytenhek <buytenh@wantstofly.org>
+ *
+ * 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/kernel.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/mtd/physmap.h>
+#include <linux/platform_device.h>
+#include <asm/io.h>
+#include <asm/hardware.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+static struct physmap_flash_data edb9315_flash_data = {
+	.width		= 4,
+};
+
+static struct resource edb9315_flash_resource = {
+	.start		= 0x60000000,
+	.end		= 0x61ffffff,
+	.flags		= IORESOURCE_MEM,
+};
+
+static struct platform_device edb9315_flash = {
+	.name		= "physmap-flash",
+	.id		= 0,
+	.dev		= {
+		.platform_data	= &edb9315_flash_data,
+	},
+	.num_resources	= 1,
+	.resource	= &edb9315_flash_resource,
+};
+
+static void __init edb9315_init_machine(void)
+{
+	ep93xx_init_devices();
+	platform_device_register(&edb9315_flash);
+}
+
+MACHINE_START(EDB9315, "Cirrus Logic EDB9315 Evaluation Board")
+	/* Maintainer: Lennert Buytenhek <buytenh@wantstofly.org> */
+	.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	= edb9315_init_machine,
+MACHINE_END
diff --git a/arch/arm/mach-ep93xx/edb9315a.c b/arch/arm/mach-ep93xx/edb9315a.c
new file mode 100644
index 000000000..e03407e72
--- /dev/null
+++ b/arch/arm/mach-ep93xx/edb9315a.c
@@ -0,0 +1,61 @@
+/*
+ * arch/arm/mach-ep93xx/edb9315a.c
+ * Cirrus Logic EDB9315A support.
+ *
+ * Copyright (C) 2006 Lennert Buytenhek <buytenh@wantstofly.org>
+ *
+ * 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/kernel.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/mtd/physmap.h>
+#include <linux/platform_device.h>
+#include <asm/io.h>
+#include <asm/hardware.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+static struct physmap_flash_data edb9315a_flash_data = {
+	.width		= 2,
+};
+
+static struct resource edb9315a_flash_resource = {
+	.start		= 0x60000000,
+	.end		= 0x60ffffff,
+	.flags		= IORESOURCE_MEM,
+};
+
+static struct platform_device edb9315a_flash = {
+	.name		= "physmap-flash",
+	.id		= 0,
+	.dev		= {
+		.platform_data	= &edb9315a_flash_data,
+	},
+	.num_resources	= 1,
+	.resource	= &edb9315a_flash_resource,
+};
+
+static void __init edb9315a_init_machine(void)
+{
+	ep93xx_init_devices();
+	platform_device_register(&edb9315a_flash);
+}
+
+MACHINE_START(EDB9315A, "Cirrus Logic EDB9315A Evaluation Board")
+	/* Maintainer: Lennert Buytenhek <buytenh@wantstofly.org> */
+	.phys_io	= EP93XX_APB_PHYS_BASE,
+	.io_pg_offst	= ((EP93XX_APB_VIRT_BASE) >> 18) & 0xfffc,
+	.boot_params	= 0xc0000100,
+	.map_io		= ep93xx_map_io,
+	.init_irq	= ep93xx_init_irq,
+	.timer		= &ep93xx_timer,
+	.init_machine	= edb9315a_init_machine,
+MACHINE_END
diff --git a/arch/arm/mach-lh7a40x/clcd.c b/arch/arm/mach-lh7a40x/clcd.c
new file mode 100644
index 000000000..1992db4c2
--- /dev/null
+++ b/arch/arm/mach-lh7a40x/clcd.c
@@ -0,0 +1,241 @@
+/*
+ *  arch/arm/mach-lh7a40x/clcd.c
+ *
+ *  Copyright (C) 2004 Marc Singer
+ *
+ *  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/device.h>
+#include <linux/dma-mapping.h>
+#include <linux/sysdev.h>
+#include <linux/interrupt.h>
+
+//#include <linux/module.h>
+//#include <linux/time.h>
+//#include <asm/hardware.h>
+
+//#include <asm/mach/time.h>
+#include <asm/irq.h>
+#include <asm/mach/irq.h>
+
+#include <asm/system.h>
+#include <asm/hardware.h>
+#include <linux/amba/bus.h>
+#include <linux/amba/clcd.h>
+
+#define HRTFTC_HRSETUP		__REG(HRTFTC_PHYS + 0x00)
+#define HRTFTC_HRCON		__REG(HRTFTC_PHYS + 0x04)
+#define HRTFTC_HRTIMING1	__REG(HRTFTC_PHYS + 0x08)
+#define HRTFTC_HRTIMING2	__REG(HRTFTC_PHYS + 0x0c)
+
+#define ALI_SETUP		__REG(ALI_PHYS + 0x00)
+#define ALI_CONTROL		__REG(ALI_PHYS + 0x04)
+#define ALI_TIMING1		__REG(ALI_PHYS + 0x08)
+#define ALI_TIMING2		__REG(ALI_PHYS + 0x0c)
+
+#include "lcd-panel.h"
+
+static void lh7a40x_clcd_disable (struct clcd_fb *fb)
+{
+#if defined (CONFIG_MACH_LPD7A400)
+	CPLD_CONTROL &= ~(1<<1);	/* Disable LCD Vee */
+#endif
+
+#if defined (CONFIG_MACH_LPD7A404)
+	GPIO_PCD  &= ~(1<<3);		/* Disable LCD Vee */
+#endif
+
+#if defined (CONFIG_ARCH_LH7A400)
+	HRTFTC_HRSETUP &= ~(1<<13);	/* Disable HRTFT controller */
+#endif
+
+#if defined (CONFIG_ARCH_LH7A404)
+	ALI_SETUP &= ~(1<<13);		/* Disable ALI */
+#endif
+}
+
+static void lh7a40x_clcd_enable (struct clcd_fb *fb)
+{
+	struct clcd_panel_extra* extra
+		= (struct clcd_panel_extra*) fb->board_data;
+
+#if defined (CONFIG_MACH_LPD7A400)
+	CPLD_CONTROL |= (1<<1);		/* Enable LCD Vee */
+#endif
+
+#if defined (CONFIG_MACH_LPD7A404)
+	GPIO_PCDD &= ~(1<<3);		/* Enable LCD Vee */
+	GPIO_PCD  |=  (1<<3);
+#endif
+
+#if defined (CONFIG_ARCH_LH7A400)
+
+	if (extra) {
+		HRTFTC_HRSETUP
+			= (1 << 13)
+			| ((fb->fb.var.xres - 1) << 4)
+			| 0xc
+			| (extra->hrmode ? 1 : 0);
+		HRTFTC_HRCON
+			= ((extra->clsen ? 1 : 0) << 1)
+			| ((extra->spsen ? 1 : 0) << 0);
+		HRTFTC_HRTIMING1
+			= (extra->pcdel << 8)
+			| (extra->revdel << 4)
+			| (extra->lpdel << 0);
+		HRTFTC_HRTIMING2
+			= (extra->spldel << 9)
+			| (extra->pc2del << 0);
+	}
+	else
+		HRTFTC_HRSETUP
+			= (1 << 13)
+			| 0xc;
+#endif
+
+#if defined (CONFIG_ARCH_LH7A404)
+
+	if (extra) {
+		ALI_SETUP
+			= (1 << 13)
+			| ((fb->fb.var.xres - 1) << 4)
+			| 0xc
+			| (extra->hrmode ? 1 : 0);
+		ALI_CONTROL
+			= ((extra->clsen ? 1 : 0) << 1)
+			| ((extra->spsen ? 1 : 0) << 0);
+		ALI_TIMING1
+			= (extra->pcdel << 8)
+			| (extra->revdel << 4)
+			| (extra->lpdel << 0);
+		ALI_TIMING2
+			= (extra->spldel << 9)
+			| (extra->pc2del << 0);
+	}
+	else
+		ALI_SETUP
+			= (1 << 13)
+			| 0xc;
+#endif
+
+}
+
+#define FRAMESIZE(s) (((s) + PAGE_SIZE - 1)&PAGE_MASK)
+
+static int lh7a40x_clcd_setup (struct clcd_fb *fb)
+{
+	dma_addr_t dma;
+	u32 len = FRAMESIZE (lcd_panel.mode.xres*lcd_panel.mode.yres
+			     *(lcd_panel.bpp/8));
+
+	fb->panel = &lcd_panel;
+
+		/* Enforce the sync polarity defaults */
+	if (!(fb->panel->tim2 & TIM2_IHS))
+		fb->fb.var.sync |= FB_SYNC_HOR_HIGH_ACT;
+	if (!(fb->panel->tim2 & TIM2_IVS))
+		fb->fb.var.sync |= FB_SYNC_VERT_HIGH_ACT;
+
+#if defined (HAS_LCD_PANEL_EXTRA)
+	fb->board_data = &lcd_panel_extra;
+#endif
+
+	fb->fb.screen_base
+		= dma_alloc_writecombine (&fb->dev->dev, len,
+					  &dma, GFP_KERNEL);
+	printk ("CLCD: LCD setup fb virt 0x%p phys 0x%p l %x io 0x%p \n",
+		fb->fb.screen_base, (void*) dma, len,
+		(void*) io_p2v (CLCDC_PHYS));
+	printk ("CLCD: pixclock %d\n", lcd_panel.mode.pixclock);
+
+	if (!fb->fb.screen_base) {
+		printk(KERN_ERR "CLCD: unable to map framebuffer\n");
+		return -ENOMEM;
+	}
+
+#if defined (USE_RGB555)
+	fb->fb.var.green.length = 5; /* Panel uses RGB 5:5:5 */
+#endif
+
+	fb->fb.fix.smem_start = dma;
+	fb->fb.fix.smem_len = len;
+
+		/* Drive PE4 high to prevent CPLD crash */
+	GPIO_PEDD |= (1<<4);
+	GPIO_PED  |= (1<<4);
+
+	GPIO_PINMUX |= (1<<1) | (1<<0); /* LCDVD[15:4] */
+
+//	fb->fb.fbops->fb_check_var (&fb->fb.var, &fb->fb);
+//	fb->fb.fbops->fb_set_par (&fb->fb);
+
+	return 0;
+}
+
+static int lh7a40x_clcd_mmap (struct clcd_fb *fb, struct vm_area_struct *vma)
+{
+	return dma_mmap_writecombine(&fb->dev->dev, vma,
+				     fb->fb.screen_base,
+				     fb->fb.fix.smem_start,
+				     fb->fb.fix.smem_len);
+}
+
+static void lh7a40x_clcd_remove (struct clcd_fb *fb)
+{
+	dma_free_writecombine (&fb->dev->dev, fb->fb.fix.smem_len,
+			       fb->fb.screen_base, fb->fb.fix.smem_start);
+}
+
+static struct clcd_board clcd_platform_data = {
+	.name		= "lh7a40x FB",
+	.check		= clcdfb_check,
+	.decode		= clcdfb_decode,
+	.enable		= lh7a40x_clcd_enable,
+	.setup		= lh7a40x_clcd_setup,
+	.mmap		= lh7a40x_clcd_mmap,
+	.remove		= lh7a40x_clcd_remove,
+	.disable	= lh7a40x_clcd_disable,
+};
+
+#define IRQ_CLCDC (IRQ_LCDINTR)
+
+#define AMBA_DEVICE(name,busid,base,plat,pid)			\
+static struct amba_device name##_device = {			\
+	.dev = {						\
+		.coherent_dma_mask = ~0,			\
+		.bus_id	= busid,				\
+		.platform_data = plat,				\
+		},						\
+	.res = {						\
+		.start	= base##_PHYS,				\
+		.end	= (base##_PHYS) + (4*1024) - 1,		\
+		.flags	= IORESOURCE_MEM,			\
+		},						\
+	.dma_mask	= ~0,					\
+	.irq		= { IRQ_##base, },			\
+	/* .dma		= base##_DMA,*/				\
+	.periphid = pid,					\
+}
+
+AMBA_DEVICE(clcd,  "cldc-lh7a40x",  CLCDC,     &clcd_platform_data, 0x41110);
+
+static struct amba_device *amba_devs[] __initdata = {
+	&clcd_device,
+};
+
+void __init lh7a40x_clcd_init (void)
+{
+	int i;
+	int result;
+	printk ("CLCD: registering amba devices\n");
+	for (i = 0; i < ARRAY_SIZE(amba_devs); i++) {
+		struct amba_device *d = amba_devs[i];
+		result = amba_device_register(d, &iomem_resource);
+		printk ("  %d -> %d\n", i ,result);
+	}
+}
diff --git a/arch/arm/mach-lh7a40x/clocks.c b/arch/arm/mach-lh7a40x/clocks.c
new file mode 100644
index 000000000..7530a95c1
--- /dev/null
+++ b/arch/arm/mach-lh7a40x/clocks.c
@@ -0,0 +1,198 @@
+/* arch/arm/mach-lh7a40x/clocks.c
+ *
+ *  Copyright (C) 2004 Marc Singer
+ *
+ *  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/cpufreq.h>
+#include <asm/hardware.h>
+#include <asm/arch/clocks.h>
+#include <linux/err.h>
+
+struct module;
+struct icst525_params;
+
+struct clk {
+	struct list_head node;
+	unsigned long rate;
+	struct module *owner;
+	const char *name;
+//	void *data;
+//	const struct icst525_params *params;
+//	void (*setvco)(struct clk *, struct icst525_vco vco);
+};
+
+int clk_register(struct clk *clk);
+void clk_unregister(struct clk *clk);
+
+/* ----- */
+
+#define MAINDIV1(c)	(((c) >>  7) & 0x0f)
+#define MAINDIV2(c)	(((c) >> 11) & 0x1f)
+#define PS(c)		(((c) >> 18) & 0x03)
+#define PREDIV(c)	(((c) >>  2) & 0x1f)
+#define HCLKDIV(c)	(((c) >>  0) & 0x02)
+#define PCLKDIV(c)	(((c) >> 16) & 0x03)
+
+unsigned int cpufreq_get (unsigned int cpu) /* in kHz */
+{
+	return fclkfreq_get ()/1000;
+}
+EXPORT_SYMBOL(cpufreq_get);
+
+unsigned int fclkfreq_get (void)
+{
+	unsigned int clkset = CSC_CLKSET;
+	unsigned int gclk
+		= XTAL_IN
+		/ (1 << PS(clkset))
+		* (MAINDIV1(clkset) + 2)
+		/ (PREDIV(clkset)   + 2)
+		* (MAINDIV2(clkset) + 2)
+		;
+	return gclk;
+}
+
+unsigned int hclkfreq_get (void)
+{
+	unsigned int clkset = CSC_CLKSET;
+	unsigned int hclk = fclkfreq_get () / (HCLKDIV(clkset) + 1);
+
+	return hclk;
+}
+
+unsigned int pclkfreq_get (void)
+{
+	unsigned int clkset = CSC_CLKSET;
+	int pclkdiv = PCLKDIV(clkset);
+	unsigned int pclk;
+	if (pclkdiv == 0x3)
+		pclkdiv = 0x2;
+	pclk = hclkfreq_get () / (1 << pclkdiv);
+
+	return pclk;
+}
+
+/* ----- */
+
+static LIST_HEAD(clocks);
+static DECLARE_MUTEX(clocks_sem);
+
+struct clk *clk_get (struct device *dev, const char *id)
+{
+	struct clk *p;
+	struct clk *clk = ERR_PTR(-ENOENT);
+
+	down (&clocks_sem);
+	list_for_each_entry (p, &clocks, node) {
+		if (strcmp (id, p->name) == 0
+		    && try_module_get(p->owner)) {
+			clk = p;
+			break;
+		}
+	}
+	up (&clocks_sem);
+
+	return clk;
+}
+EXPORT_SYMBOL(clk_get);
+
+void clk_put (struct clk *clk)
+{
+	module_put(clk->owner);
+}
+EXPORT_SYMBOL(clk_put);
+
+int clk_enable (struct clk *clk)
+{
+	return 0;
+}
+EXPORT_SYMBOL(clk_enable);
+
+void clk_disable (struct clk *clk)
+{
+}
+EXPORT_SYMBOL(clk_disable);
+
+int clk_use (struct clk *clk)
+{
+	return 0;
+}
+EXPORT_SYMBOL(clk_use);
+
+void clk_unuse (struct clk *clk)
+{
+}
+EXPORT_SYMBOL(clk_unuse);
+
+unsigned long clk_get_rate (struct clk *clk)
+{
+	return clk->rate;
+}
+EXPORT_SYMBOL(clk_get_rate);
+
+long clk_round_rate (struct clk *clk, unsigned long rate)
+{
+	return rate;
+}
+EXPORT_SYMBOL(clk_round_rate);
+
+int clk_set_rate (struct clk *clk, unsigned long rate)
+{
+	int ret = -EIO;
+	return ret;
+}
+EXPORT_SYMBOL(clk_set_rate);
+
+#if 0
+/*
+ * These are fixed clocks.
+ */
+static struct clk kmi_clk = {
+	.name	= "KMIREFCLK",
+	.rate	= 24000000,
+};
+
+static struct clk uart_clk = {
+	.name	= "UARTCLK",
+	.rate	= 24000000,
+};
+
+static struct clk mmci_clk = {
+	.name	= "MCLK",
+	.rate	= 33000000,
+};
+#endif
+
+static struct clk clcd_clk = {
+	.name	= "CLCDCLK",
+	.rate	= 0,
+};
+
+int clk_register (struct clk *clk)
+{
+	down (&clocks_sem);
+	list_add (&clk->node, &clocks);
+	up (&clocks_sem);
+	return 0;
+}
+EXPORT_SYMBOL(clk_register);
+
+void clk_unregister (struct clk *clk)
+{
+	down (&clocks_sem);
+	list_del (&clk->node);
+	up (&clocks_sem);
+}
+EXPORT_SYMBOL(clk_unregister);
+
+static int __init clk_init (void)
+{
+	clk_register(&clcd_clk);
+	return 0;
+}
+arch_initcall(clk_init);
diff --git a/arch/arm/mach-lh7a40x/lcd-panel.h b/arch/arm/mach-lh7a40x/lcd-panel.h
new file mode 100644
index 000000000..4fb2efc49
--- /dev/null
+++ b/arch/arm/mach-lh7a40x/lcd-panel.h
@@ -0,0 +1,346 @@
+/* lcd-panel.h
+     $Id$
+
+   written by Marc Singer
+   18 Jul 2005
+
+   Copyright (C) 2005 Marc Singer
+
+   -----------
+   DESCRIPTION
+   -----------
+
+   Only one panel may be defined at a time.
+
+   The pixel clock is calculated to be no greater than the target.
+
+   Each timing value is accompanied by a specification comment.
+
+     UNITS/MIN/TYP/MAX
+
+   Most of the units will be in clocks.
+
+   USE_RGB555
+
+     Define this macro to configure the AMBA LCD controller to use an
+     RGB555 encoding for the pels instead of the normal RGB565.
+
+   LPD9520, LPD79524, LPD7A400, LPD7A404-10, LPD7A404-11
+
+     These boards are best approximated by 555 for all panels.  Some
+     can use an extra low-order bit of blue in bit 16 of the color
+     value, but we don't have a way to communicate this non-linear
+     mapping to the kernel.
+
+*/
+
+#if !defined (__LCD_PANEL_H__)
+#    define   __LCD_PANEL_H__
+
+#if defined (MACH_LPD79520)\
+ || defined (MACH_LPD79524)\
+ || defined (MACH_LPD7A400)\
+ || defined (MACH_LPD7A404)
+# define USE_RGB555
+#endif
+
+struct clcd_panel_extra {
+	unsigned int hrmode;
+	unsigned int clsen;
+	unsigned int spsen;
+	unsigned int pcdel;
+	unsigned int revdel;
+	unsigned int lpdel;
+	unsigned int spldel;
+	unsigned int pc2del;
+};
+
+#define NS_TO_CLOCK(ns,c)	((((ns)*((c)/1000) + (1000000 - 1))/1000000))
+#define CLOCK_TO_DIV(e,c)	(((c) + (e) - 1)/(e))
+
+#if defined CONFIG_FB_ARMCLCD_SHARP_LQ035Q7DB02_HRTFT
+
+	/* Logic Product Development LCD 3.5" QVGA HRTFT -10 */
+	/* Sharp PN LQ035Q7DB02 w/HRTFT controller chip */
+
+#define PIX_CLOCK_TARGET	(6800000)
+#define PIX_CLOCK_DIVIDER	CLOCK_TO_DIV (PIX_CLOCK_TARGET, HCLK)
+#define PIX_CLOCK		(HCLK/PIX_CLOCK_DIVIDER)
+
+static struct clcd_panel lcd_panel = {
+	.mode	= {
+		.name		= "3.5in QVGA (LQ035Q7DB02)",
+		.xres		= 240,
+		.yres		= 320,
+		.pixclock	= PIX_CLOCK,
+		.left_margin	= 16,
+		.right_margin	= 21,
+		.upper_margin	= 8,			// line/8/8/8
+		.lower_margin	= 5,
+		.hsync_len	= 61,
+		.vsync_len	= NS_TO_CLOCK (60, PIX_CLOCK),
+		.vmode		= FB_VMODE_NONINTERLACED,
+	},
+	.width		= -1,
+	.height		= -1,
+	.tim2		= TIM2_IPC | (PIX_CLOCK_DIVIDER - 2),
+	.cntl		= CNTL_LCDTFT | CNTL_WATERMARK,
+	.bpp		= 16,
+};
+
+#define HAS_LCD_PANEL_EXTRA
+
+static struct clcd_panel_extra lcd_panel_extra = {
+	.hrmode = 1,
+	.clsen = 1,
+	.spsen = 1,
+	.pcdel = 8,
+	.revdel = 7,
+	.lpdel = 13,
+	.spldel = 77,
+	.pc2del = 208,
+};
+
+#endif
+
+#if defined CONFIG_FB_ARMCLCD_SHARP_LQ057Q3DC02
+
+	/* Logic Product Development LCD 5.7" QVGA -10 */
+	/* Sharp PN LQ057Q3DC02 */
+	/* QVGA mode, V/Q=LOW */
+
+/* From Sharp on 2006.1.3.  I believe some of the values are incorrect
+ * based on the datasheet.
+
+    Timing0	TIMING1		TIMING2		CONTROL
+    0x140A0C4C	0x080504EF	0x013F380D	0x00000829
+    HBP= 20	VBP=  8		BCD=  0
+    HFP= 10	VFP=  5		CPL=319
+    HSW= 12	VSW=  1		IOE=  0
+    PPL= 19	LPP=239		IPC=  1
+				IHS=  1
+				IVS=  1
+				ACB=  0
+				CSEL= 0
+				PCD= 13
+
+ */
+
+/* The full horozontal cycle (Th) is clock/360/400/450. */
+/* The full vertical   cycle (Tv) is line/251/262/280. */
+
+#define PIX_CLOCK_TARGET	(6300000) /* -/6.3/7 MHz */
+#define PIX_CLOCK_DIVIDER	CLOCK_TO_DIV (PIX_CLOCK_TARGET, HCLK)
+#define PIX_CLOCK		(HCLK/PIX_CLOCK_DIVIDER)
+
+static struct clcd_panel lcd_panel = {
+	.mode	= {
+		.name		= "5.7in QVGA (LQ057Q3DC02)",
+		.xres		= 320,
+		.yres		= 240,
+		.pixclock	= PIX_CLOCK,
+		.left_margin	= 11,
+		.right_margin	= 400-11-320-2,
+		.upper_margin	= 7,			// line/7/7/7
+		.lower_margin	= 262-7-240-2,
+		.hsync_len	= 2,			// clk/2/96/200
+		.vsync_len	= 2,			// line/2/-/34
+		.vmode		= FB_VMODE_NONINTERLACED,
+	},
+	.width		= -1,
+	.height		= -1,
+	.tim2		= TIM2_IHS | TIM2_IVS
+			| (PIX_CLOCK_DIVIDER - 2),
+	.cntl		= CNTL_LCDTFT | CNTL_WATERMARK,
+	.bpp		= 16,
+};
+
+#endif
+
+#if defined CONFIG_FB_ARMCLCD_SHARP_LQ64D343
+
+	/* Logic Product Development LCD 6.4" VGA -10 */
+	/* Sharp PN LQ64D343 */
+
+/* The full horozontal cycle (Th) is clock/750/800/900. */
+/* The full vertical   cycle (Tv) is line/515/525/560. */
+
+#define PIX_CLOCK_TARGET	(28330000)
+#define PIX_CLOCK_DIVIDER	CLOCK_TO_DIV (PIX_CLOCK_TARGET, HCLK)
+#define PIX_CLOCK		(HCLK/PIX_CLOCK_DIVIDER)
+
+static struct clcd_panel lcd_panel = {
+	.mode	= {
+		.name		= "6.4in QVGA (LQ64D343)",
+		.xres		= 640,
+		.yres		= 480,
+		.pixclock	= PIX_CLOCK,
+		.left_margin	= 32,
+		.right_margin	= 800-32-640-96,
+		.upper_margin	= 32,			// line/34/34/34
+		.lower_margin	= 540-32-480-2,
+		.hsync_len	= 96,			// clk/2/96/200
+		.vsync_len	= 2,			// line/2/-/34
+		.vmode		= FB_VMODE_NONINTERLACED,
+	},
+	.width		= -1,
+	.height		= -1,
+	.tim2		= TIM2_IHS | TIM2_IVS
+			| (PIX_CLOCK_DIVIDER - 2),
+	.cntl		= CNTL_LCDTFT | CNTL_WATERMARK,
+	.bpp		= 16,
+};
+
+#endif
+
+#if defined CONFIG_FB_ARMCLCD_SHARP_LQ10D368
+
+	/* Logic Product Development LCD 10.4" VGA -10 */
+	/* Sharp PN LQ10D368 */
+
+#define PIX_CLOCK_TARGET	(28330000)
+#define PIX_CLOCK_DIVIDER	CLOCK_TO_DIV (PIX_CLOCK_TARGET, HCLK)
+#define PIX_CLOCK		(HCLK/PIX_CLOCK_DIVIDER)
+
+static struct clcd_panel lcd_panel = {
+	.mode	= {
+		.name		= "10.4in VGA (LQ10D368)",
+		.xres		= 640,
+		.yres		= 480,
+		.pixclock	= PIX_CLOCK,
+		.left_margin	= 21,
+		.right_margin	= 15,
+		.upper_margin	= 34,
+		.lower_margin	= 5,
+		.hsync_len	= 96,
+		.vsync_len	= 16,
+		.vmode		= FB_VMODE_NONINTERLACED,
+	},
+	.width		= -1,
+	.height		= -1,
+	.tim2		= TIM2_IHS | TIM2_IVS
+			| (PIX_CLOCK_DIVIDER - 2),
+	.cntl		= CNTL_LCDTFT | CNTL_WATERMARK,
+	.bpp		= 16,
+};
+
+#endif
+
+#if defined CONFIG_FB_ARMCLCD_SHARP_LQ121S1DG41
+
+	/* Logic Product Development LCD 12.1" SVGA -10 */
+	/* Sharp PN LQ121S1DG41, was LQ121S1DG31 */
+
+/* Note that with a 99993900 Hz HCLK, it is not possible to hit the
+ * target clock frequency range of 35MHz to 42MHz. */
+
+/* If the target pixel clock is substantially lower than the panel
+ * spec, this is done to prevent the LCD display from glitching when
+ * the CPU is under load.  A pixel clock higher than 25MHz
+ * (empirically determined) will compete with the CPU for bus cycles
+ * for the Ethernet chip.  However, even a pixel clock of 10MHz
+ * competes with Compact Flash interface during some operations
+ * (fdisk, e2fsck).  And, at that speed the display may have a visible
+ * flicker. */
+
+/* The full horozontal cycle (Th) is clock/832/1056/1395. */
+
+#define PIX_CLOCK_TARGET	(20000000)
+#define PIX_CLOCK_DIVIDER	CLOCK_TO_DIV (PIX_CLOCK_TARGET, HCLK)
+#define PIX_CLOCK		(HCLK/PIX_CLOCK_DIVIDER)
+
+static struct clcd_panel lcd_panel = {
+	.mode	= {
+		.name		= "12.1in SVGA (LQ121S1DG41)",
+		.xres		= 800,
+		.yres		= 600,
+		.pixclock	= PIX_CLOCK,
+		.left_margin	= 89,		// ns/5/-/(1/PIX_CLOCK)-10
+		.right_margin	= 1056-800-89-128,
+		.upper_margin	= 23,		// line/23/23/23
+		.lower_margin	= 44,
+		.hsync_len	= 128,		// clk/2/128/200
+		.vsync_len	= 4,		// line/2/4/6
+		.vmode		= FB_VMODE_NONINTERLACED,
+	},
+	.width		= -1,
+	.height		= -1,
+	.tim2		= TIM2_IHS | TIM2_IVS
+			| (PIX_CLOCK_DIVIDER - 2),
+	.cntl		= CNTL_LCDTFT | CNTL_WATERMARK,
+	.bpp		= 16,
+};
+
+#endif
+
+#if defined CONFIG_FB_ARMCLCD_HITACHI
+
+	/* Hitachi*/
+	/* Submitted by Michele Da Rold <michele.darold@ecsproject.com> */
+
+#define PIX_CLOCK_TARGET	(49000000)
+#define PIX_CLOCK_DIVIDER	CLOCK_TO_DIV (PIX_CLOCK_TARGET, HCLK)
+#define PIX_CLOCK		(HCLK/PIX_CLOCK_DIVIDER)
+
+static struct clcd_panel lcd_panel = {
+	.mode	= {
+		.name		= "Hitachi 800x480",
+		.xres		= 800,
+		.yres		= 480,
+		.pixclock	= PIX_CLOCK,
+		.left_margin	= 88,
+		.right_margin	= 40,
+		.upper_margin	= 32,
+		.lower_margin	= 11,
+		.hsync_len	= 128,
+		.vsync_len	= 2,
+		.vmode		= FB_VMODE_NONINTERLACED,
+	},
+	.width		= -1,
+	.height		= -1,
+	.tim2		= TIM2_IPC | TIM2_IHS | TIM2_IVS
+			| (PIX_CLOCK_DIVIDER - 2),
+	.cntl		= CNTL_LCDTFT | CNTL_WATERMARK,
+	.bpp		= 16,
+};
+
+#endif
+
+
+#if defined CONFIG_FB_ARMCLCD_AUO_A070VW01_WIDE
+
+	/* AU Optotronics  A070VW01 7.0 Wide Screen color Display*/
+	/* Submitted by Michele Da Rold <michele.darold@ecsproject.com> */
+
+#define PIX_CLOCK_TARGET	(10000000)
+#define PIX_CLOCK_DIVIDER	CLOCK_TO_DIV (PIX_CLOCK_TARGET, HCLK)
+#define PIX_CLOCK		(HCLK/PIX_CLOCK_DIVIDER)
+
+static struct clcd_panel lcd_panel = {
+	.mode	= {
+		.name		= "7.0in Wide (A070VW01)",
+		.xres		= 480,
+		.yres		= 234,
+		.pixclock	= PIX_CLOCK,
+		.left_margin	= 30,
+		.right_margin	= 25,
+		.upper_margin	= 14,
+		.lower_margin	= 12,
+		.hsync_len	= 100,
+		.vsync_len	= 1,
+		.vmode		= FB_VMODE_NONINTERLACED,
+	},
+	.width		= -1,
+	.height		= -1,
+	.tim2		= TIM2_IPC | TIM2_IHS | TIM2_IVS
+			| (PIX_CLOCK_DIVIDER - 2),
+	.cntl		= CNTL_LCDTFT | CNTL_WATERMARK,
+	.bpp		= 16,
+};
+
+#endif
+
+#undef NS_TO_CLOCK
+#undef CLOCK_TO_DIV
+
+#endif  /* __LCD_PANEL_H__ */
diff --git a/arch/arm/mach-lh7a40x/ssp-cpld.c b/arch/arm/mach-lh7a40x/ssp-cpld.c
new file mode 100644
index 000000000..a10830186
--- /dev/null
+++ b/arch/arm/mach-lh7a40x/ssp-cpld.c
@@ -0,0 +1,343 @@
+/* arch/arm/mach-lh7a40x/ssp-cpld.c
+ *
+ *  Copyright (C) 2004,2005 Marc Singer
+ *
+ *  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.
+ *
+ * SSP/SPI driver for the CardEngine CPLD.
+ *
+ */
+
+/* NOTES
+   -----
+
+   o *** This driver is cribbed from the 7952x implementation.
+	 Some comments may not apply.
+
+   o This driver contains sufficient logic to control either the
+     serial EEPROMs or the audio codec.  It is included in the kernel
+     to support the codec.  The EEPROMs are really the responsibility
+     of the boot loader and should probably be left alone.
+
+   o The code must be augmented to cope with multiple, simultaneous
+     clients.
+     o The audio codec writes to the codec chip whenever playback
+       starts.
+     o The touchscreen driver writes to the ads chip every time it
+       samples.
+     o The audio codec must write 16 bits, but the touch chip writes
+       are 8 bits long.
+     o We need to be able to keep these configurations separate while
+       simultaneously active.
+
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+//#include <linux/sched.h>
+#include <linux/errno.h>
+#include <linux/interrupt.h>
+//#include <linux/ioport.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/spinlock.h>
+
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/hardware.h>
+
+#include <asm/arch/ssp.h>
+
+//#define TALK
+
+#if defined (TALK)
+#define PRINTK(f...)		printk (f)
+#else
+#define PRINTK(f...)		do {} while (0)
+#endif
+
+#if defined (CONFIG_ARCH_LH7A400)
+# define CPLD_SPID		__REGP16(CPLD06_VIRT) /* SPI data */
+# define CPLD_SPIC		__REGP16(CPLD08_VIRT) /* SPI control */
+# define CPLD_SPIC_CS_CODEC	(1<<0)
+# define CPLD_SPIC_CS_TOUCH	(1<<1)
+# define CPLD_SPIC_WRITE	(0<<2)
+# define CPLD_SPIC_READ		(1<<2)
+# define CPLD_SPIC_DONE		(1<<3) /* r/o */
+# define CPLD_SPIC_LOAD		(1<<4)
+# define CPLD_SPIC_START	(1<<4)
+# define CPLD_SPIC_LOADED	(1<<5) /* r/o */
+#endif
+
+#define CPLD_SPI		__REGP16(CPLD0A_VIRT) /* SPI operation */
+#define CPLD_SPI_CS_EEPROM	(1<<3)
+#define CPLD_SPI_SCLK		(1<<2)
+#define CPLD_SPI_TX_SHIFT	(1)
+#define CPLD_SPI_TX		(1<<CPLD_SPI_TX_SHIFT)
+#define CPLD_SPI_RX_SHIFT	(0)
+#define CPLD_SPI_RX		(1<<CPLD_SPI_RX_SHIFT)
+
+/* *** FIXME: these timing values are substantially larger than the
+   *** chip requires. We may implement an nsleep () function. */
+#define T_SKH	1		/* Clock time high (us) */
+#define T_SKL	1		/* Clock time low (us) */
+#define T_CS	1		/* Minimum chip select low time (us)  */
+#define T_CSS	1		/* Minimum chip select setup time (us)  */
+#define T_DIS	1		/* Data setup time (us) */
+
+	 /* EEPROM SPI bits */
+#define P_START		(1<<9)
+#define P_WRITE		(1<<7)
+#define P_READ		(2<<7)
+#define P_ERASE		(3<<7)
+#define P_EWDS		(0<<7)
+#define P_WRAL		(0<<7)
+#define P_ERAL		(0<<7)
+#define P_EWEN		(0<<7)
+#define P_A_EWDS	(0<<5)
+#define P_A_WRAL	(1<<5)
+#define P_A_ERAL	(2<<5)
+#define P_A_EWEN	(3<<5)
+
+struct ssp_configuration {
+	int device;
+	int mode;
+	int speed;
+	int frame_size_write;
+	int frame_size_read;
+};
+
+static struct ssp_configuration ssp_configuration;
+static spinlock_t ssp_lock;
+
+static void enable_cs (void)
+{
+	switch (ssp_configuration.device) {
+	case DEVICE_EEPROM:
+		CPLD_SPI |= CPLD_SPI_CS_EEPROM;
+		break;
+	}
+	udelay (T_CSS);
+}
+
+static void disable_cs (void)
+{
+	switch (ssp_configuration.device) {
+	case DEVICE_EEPROM:
+		CPLD_SPI &= ~CPLD_SPI_CS_EEPROM;
+		break;
+	}
+	udelay (T_CS);
+}
+
+static void pulse_clock (void)
+{
+	CPLD_SPI |=  CPLD_SPI_SCLK;
+	udelay (T_SKH);
+	CPLD_SPI &= ~CPLD_SPI_SCLK;
+	udelay (T_SKL);
+}
+
+
+/* execute_spi_command
+
+   sends an spi command to a device.  It first sends cwrite bits from
+   v.  If cread is greater than zero it will read cread bits
+   (discarding the leading 0 bit) and return them.  If cread is less
+   than zero it will check for completetion status and return 0 on
+   success or -1 on timeout.  If cread is zero it does nothing other
+   than sending the command.
+
+   On the LPD7A400, we can only read or write multiples of 8 bits on
+   the codec and the touch screen device.  Here, we round up.
+
+*/
+
+static int execute_spi_command (int v, int cwrite, int cread)
+{
+	unsigned long l = 0;
+
+#if defined (CONFIG_MACH_LPD7A400)
+	/* The codec and touch devices cannot be bit-banged.  Instead,
+	 * the CPLD provides an eight-bit shift register and a crude
+	 * interface.  */
+	if (   ssp_configuration.device == DEVICE_CODEC
+	    || ssp_configuration.device == DEVICE_TOUCH) {
+		int select = 0;
+
+		PRINTK ("spi(%d %d.%d) 0x%04x",
+			ssp_configuration.device, cwrite, cread,
+			v);
+#if defined (TALK)
+		if (ssp_configuration.device == DEVICE_CODEC)
+			PRINTK (" 0x%03x -> %2d", v & 0x1ff, (v >> 9) & 0x7f);
+#endif
+		PRINTK ("\n");
+
+		if (ssp_configuration.device == DEVICE_CODEC)
+			select = CPLD_SPIC_CS_CODEC;
+		if (ssp_configuration.device == DEVICE_TOUCH)
+			select = CPLD_SPIC_CS_TOUCH;
+		if (cwrite) {
+			for (cwrite = (cwrite + 7)/8; cwrite-- > 0; ) {
+				CPLD_SPID = (v >> (8*cwrite)) & 0xff;
+				CPLD_SPIC = select | CPLD_SPIC_LOAD;
+				while (!(CPLD_SPIC & CPLD_SPIC_LOADED))
+					;
+				CPLD_SPIC = select;
+				while (!(CPLD_SPIC & CPLD_SPIC_DONE))
+					;
+			}
+			v = 0;
+		}
+		if (cread) {
+			mdelay (2);	/* *** FIXME: required by ads7843? */
+			v = 0;
+			for (cread = (cread + 7)/8; cread-- > 0;) {
+				CPLD_SPID = 0;
+				CPLD_SPIC = select | CPLD_SPIC_READ
+					| CPLD_SPIC_START;
+				while (!(CPLD_SPIC & CPLD_SPIC_LOADED))
+					;
+				CPLD_SPIC = select | CPLD_SPIC_READ;
+				while (!(CPLD_SPIC & CPLD_SPIC_DONE))
+					;
+				v = (v << 8) | CPLD_SPID;
+			}
+		}
+		return v;
+	}
+#endif
+
+	PRINTK ("spi(%d) 0x%04x -> 0x%x\r\n", ssp_configuration.device,
+		v & 0x1ff, (v >> 9) & 0x7f);
+
+	enable_cs ();
+
+	v <<= CPLD_SPI_TX_SHIFT; /* Correction for position of SPI_TX bit */
+	while (cwrite--) {
+		CPLD_SPI
+			= (CPLD_SPI & ~CPLD_SPI_TX)
+			| ((v >> cwrite) & CPLD_SPI_TX);
+		udelay (T_DIS);
+		pulse_clock ();
+	}
+
+	if (cread < 0) {
+		int delay = 10;
+		disable_cs ();
+		udelay (1);
+		enable_cs ();
+
+		l = -1;
+		do {
+			if (CPLD_SPI & CPLD_SPI_RX) {
+				l = 0;
+				break;
+			}
+		} while (udelay (1), --delay);
+	}
+	else
+	/* We pulse the clock before the data to skip the leading zero. */
+		while (cread-- > 0) {
+			pulse_clock ();
+			l = (l<<1)
+				| (((CPLD_SPI & CPLD_SPI_RX)
+				    >> CPLD_SPI_RX_SHIFT) & 0x1);
+		}
+
+	disable_cs ();
+	return l;
+}
+
+static int ssp_init (void)
+{
+	spin_lock_init (&ssp_lock);
+	memset (&ssp_configuration, 0, sizeof (ssp_configuration));
+	return 0;
+}
+
+
+/* ssp_chip_select
+
+   drops the chip select line for the CPLD shift-register controlled
+   devices.  It doesn't enable chip
+
+*/
+
+static void ssp_chip_select (int enable)
+{
+#if defined (CONFIG_MACH_LPD7A400)
+	int select;
+
+	if (ssp_configuration.device == DEVICE_CODEC)
+		select = CPLD_SPIC_CS_CODEC;
+	else if (ssp_configuration.device == DEVICE_TOUCH)
+		select = CPLD_SPIC_CS_TOUCH;
+	else
+		return;
+
+	if (enable)
+		CPLD_SPIC = select;
+	else
+		CPLD_SPIC = 0;
+#endif
+}
+
+static void ssp_acquire (void)
+{
+	spin_lock (&ssp_lock);
+}
+
+static void ssp_release (void)
+{
+	ssp_chip_select (0);	/* just in case */
+	spin_unlock (&ssp_lock);
+}
+
+static int ssp_configure (int device, int mode, int speed,
+			   int frame_size_write, int frame_size_read)
+{
+	ssp_configuration.device		= device;
+	ssp_configuration.mode			= mode;
+	ssp_configuration.speed			= speed;
+	ssp_configuration.frame_size_write	= frame_size_write;
+	ssp_configuration.frame_size_read	= frame_size_read;
+
+	return 0;
+}
+
+static int ssp_read (void)
+{
+	return execute_spi_command (0, 0, ssp_configuration.frame_size_read);
+}
+
+static int ssp_write (u16 data)
+{
+	execute_spi_command (data, ssp_configuration.frame_size_write, 0);
+	return 0;
+}
+
+static int ssp_write_read (u16 data)
+{
+	return execute_spi_command (data, ssp_configuration.frame_size_write,
+				    ssp_configuration.frame_size_read);
+}
+
+struct ssp_driver lh7a40x_cpld_ssp_driver = {
+	.init		= ssp_init,
+	.acquire	= ssp_acquire,
+	.release	= ssp_release,
+	.configure	= ssp_configure,
+	.chip_select	= ssp_chip_select,
+	.read		= ssp_read,
+	.write		= ssp_write,
+	.write_read	= ssp_write_read,
+};
+
+
+MODULE_AUTHOR("Marc Singer");
+MODULE_DESCRIPTION("LPD7A40X CPLD SPI driver");
+MODULE_LICENSE("GPL");
diff --git a/arch/arm/mach-netx/Kconfig b/arch/arm/mach-netx/Kconfig
new file mode 100644
index 000000000..3d90ef19b
--- /dev/null
+++ b/arch/arm/mach-netx/Kconfig
@@ -0,0 +1,24 @@
+menu "NetX Implementations"
+	depends on ARCH_NETX
+
+config MACH_NXDKN
+	bool "Enable Hilscher nxdkn Eval Board support"
+	depends on ARCH_NETX
+	help
+	  Board support for the Hilscher NetX Eval Board
+
+config MACH_NXDB500
+	bool "Enable Hilscher nxdb500 Eval Board support"
+	depends on ARCH_NETX
+	select ARM_AMBA
+	help
+	  Board support for the Hilscher nxdb500 Eval Board
+
+config MACH_NXEB500HMI
+	bool "Enable Hilscher nxeb500hmi Eval Board support"
+	depends on ARCH_NETX
+	select ARM_AMBA
+	help
+	  Board support for the Hilscher nxeb500hmi Eval Board
+
+endmenu
diff --git a/arch/arm/mach-netx/Makefile b/arch/arm/mach-netx/Makefile
new file mode 100644
index 000000000..18785ff37
--- /dev/null
+++ b/arch/arm/mach-netx/Makefile
@@ -0,0 +1,15 @@
+#
+# Makefile for the linux kernel.
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+
+# Object file lists.
+
+obj-y			+= time.o generic.o pfifo.o xc.o
+
+# Specific board support
+obj-$(CONFIG_MACH_NXDKN) += nxdkn.o
+obj-$(CONFIG_MACH_NXDB500) += nxdb500.o fb.o
+obj-$(CONFIG_MACH_NXEB500HMI) += nxeb500hmi.o fb.o
diff --git a/arch/arm/mach-netx/Makefile.boot b/arch/arm/mach-netx/Makefile.boot
new file mode 100644
index 000000000..b81cf6aff
--- /dev/null
+++ b/arch/arm/mach-netx/Makefile.boot
@@ -0,0 +1,2 @@
+    zreladdr-y			:= 0x80008000
+
diff --git a/arch/arm/mach-netx/fb.c b/arch/arm/mach-netx/fb.c
new file mode 100644
index 000000000..ef0ab6115
--- /dev/null
+++ b/arch/arm/mach-netx/fb.c
@@ -0,0 +1,114 @@
+/*
+ * arch/arm/mach-netx/fb.c
+ *
+ * Copyright (c) 2005 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix
+ *
+ * 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/device.h>
+#include <linux/init.h>
+#include <linux/dma-mapping.h>
+#include <linux/amba/bus.h>
+#include <linux/amba/clcd.h>
+
+#include <asm/arch/netx-regs.h>
+#include <asm/hardware.h>
+
+struct clk {};
+
+static struct clk fb_clk;
+
+static struct clcd_panel *netx_panel;
+
+void netx_clcd_enable(struct clcd_fb *fb)
+{
+}
+
+int netx_clcd_setup(struct clcd_fb *fb)
+{
+	dma_addr_t dma;
+
+	fb->panel = netx_panel;
+
+	fb->fb.screen_base = dma_alloc_writecombine(&fb->dev->dev, 1024*1024,
+						    &dma, GFP_KERNEL);
+	if (!fb->fb.screen_base) {
+		printk(KERN_ERR "CLCD: unable to map framebuffer\n");
+		return -ENOMEM;
+	}
+
+	fb->fb.fix.smem_start	= dma;
+	fb->fb.fix.smem_len	= 1024*1024;
+
+	return 0;
+}
+
+int netx_clcd_mmap(struct clcd_fb *fb, struct vm_area_struct *vma)
+{
+	return dma_mmap_writecombine(&fb->dev->dev, vma,
+				     fb->fb.screen_base,
+				     fb->fb.fix.smem_start,
+				     fb->fb.fix.smem_len);
+}
+
+void netx_clcd_remove(struct clcd_fb *fb)
+{
+	dma_free_writecombine(&fb->dev->dev, fb->fb.fix.smem_len,
+			      fb->fb.screen_base, fb->fb.fix.smem_start);
+}
+
+void clk_disable(struct clk *clk)
+{
+}
+
+int clk_set_rate(struct clk *clk, unsigned long rate)
+{
+	return 0;
+}
+
+int clk_enable(struct clk *clk)
+{
+	return 0;
+}
+
+struct clk *clk_get(struct device *dev, const char *id)
+{
+	return &fb_clk;
+}
+
+void clk_put(struct clk *clk)
+{
+}
+
+static struct amba_device fb_device = {
+	.dev		= {
+		.bus_id	= "fb",
+		.coherent_dma_mask = ~0,
+	},
+	.res		= {
+		.start	= 0x00104000,
+		.end	= 0x00104fff,
+		.flags	= IORESOURCE_MEM,
+	},
+	.irq		= { NETX_IRQ_LCD, NO_IRQ },
+	.periphid	= 0x10112400,
+};
+
+int netx_fb_init(struct clcd_board *board, struct clcd_panel *panel)
+{
+	netx_panel = panel;
+	fb_device.dev.platform_data = board;
+	return amba_device_register(&fb_device, &iomem_resource);
+}
diff --git a/arch/arm/mach-netx/fb.h b/arch/arm/mach-netx/fb.h
new file mode 100644
index 000000000..4919cf33a
--- /dev/null
+++ b/arch/arm/mach-netx/fb.h
@@ -0,0 +1,24 @@
+/*
+ * arch/arm/mach-netx/fb.h
+ *
+ * Copyright (c) 2005 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix
+ *
+ * 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
+ */
+
+void netx_clcd_enable(struct clcd_fb *fb);
+int netx_clcd_setup(struct clcd_fb *fb);
+int netx_clcd_mmap(struct clcd_fb *fb, struct vm_area_struct *vma);
+void netx_clcd_remove(struct clcd_fb *fb);
+int netx_fb_init(struct clcd_board *board, struct clcd_panel *panel);
diff --git a/arch/arm/mach-netx/generic.c b/arch/arm/mach-netx/generic.c
new file mode 100644
index 000000000..af0b13534
--- /dev/null
+++ b/arch/arm/mach-netx/generic.c
@@ -0,0 +1,193 @@
+/*
+ * arch/arm/mach-netx/generic.c
+ *
+ * Copyright (C) 2005 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix
+ *
+ * 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/device.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <asm/hardware.h>
+#include <asm/mach/map.h>
+#include <asm/hardware/vic.h>
+#include <asm/io.h>
+#include <asm/arch/netx-regs.h>
+#include <asm/mach/irq.h>
+
+static struct map_desc netx_io_desc[] __initdata = {
+	{
+		.virtual        = NETX_IO_VIRT,
+		.pfn            = __phys_to_pfn(NETX_IO_PHYS),
+		.length         = NETX_IO_SIZE,
+		.type           = MT_DEVICE
+	}
+};
+
+void __init netx_map_io(void)
+{
+	iotable_init(netx_io_desc, ARRAY_SIZE(netx_io_desc));
+}
+
+static struct resource netx_rtc_resources[] = {
+	[0] = {
+		.start	= 0x00101200,
+		.end	= 0x00101220,
+		.flags	= IORESOURCE_MEM,
+	},
+};
+
+static struct platform_device netx_rtc_device = {
+	.name		= "netx-rtc",
+	.id		= 0,
+	.num_resources	= ARRAY_SIZE(netx_rtc_resources),
+	.resource	= netx_rtc_resources,
+};
+
+static struct platform_device *devices[] __initdata = {
+	&netx_rtc_device,
+};
+
+#if 0
+#define DEBUG_IRQ(fmt...)	printk(fmt)
+#else
+#define DEBUG_IRQ(fmt...)	while (0) {}
+#endif
+
+static void
+netx_hif_demux_handler(unsigned int irq_unused, struct irqdesc *desc,
+			struct pt_regs *regs)
+{
+	unsigned int irq = NETX_IRQ_HIF_CHAINED(0);
+	unsigned int stat;
+
+	stat = ((readl(NETX_DPMAS_INT_EN) &
+		readl(NETX_DPMAS_INT_STAT)) >> 24) & 0x1f;
+
+	desc = irq_desc + NETX_IRQ_HIF_CHAINED(0);
+
+	while (stat) {
+		if (stat & 1) {
+			DEBUG_IRQ("handling irq %d\n", irq);
+			desc_handle_irq(irq, desc, regs);
+		}
+		irq++;
+		desc++;
+		stat >>= 1;
+	}
+}
+
+static int
+netx_hif_irq_type(unsigned int _irq, unsigned int type)
+{
+	unsigned int val, irq;
+
+	val = readl(NETX_DPMAS_IF_CONF1);
+
+	irq = _irq - NETX_IRQ_HIF_CHAINED(0);
+
+	if (type & __IRQT_RISEDGE) {
+		DEBUG_IRQ("rising edges\n");
+		val |= (1 << 26) << irq;
+	}
+	if (type & __IRQT_FALEDGE) {
+		DEBUG_IRQ("falling edges\n");
+		val &= ~((1 << 26) << irq);
+	}
+	if (type & __IRQT_LOWLVL) {
+		DEBUG_IRQ("low level\n");
+		val &= ~((1 << 26) << irq);
+	}
+	if (type & __IRQT_HIGHLVL) {
+		DEBUG_IRQ("high level\n");
+		val |= (1 << 26) << irq;
+	}
+
+	writel(val, NETX_DPMAS_IF_CONF1);
+
+	return 0;
+}
+
+static void
+netx_hif_ack_irq(unsigned int _irq)
+{
+	unsigned int val, irq;
+
+	irq = _irq - NETX_IRQ_HIF_CHAINED(0);
+	writel((1 << 24) << irq, NETX_DPMAS_INT_STAT);
+
+	val = readl(NETX_DPMAS_INT_EN);
+	val &= ~((1 << 24) << irq);
+	writel(val, NETX_DPMAS_INT_EN);
+
+	DEBUG_IRQ("%s: irq %d\n", __FUNCTION__, _irq);
+}
+
+static void
+netx_hif_mask_irq(unsigned int _irq)
+{
+	unsigned int val, irq;
+
+	irq = _irq - NETX_IRQ_HIF_CHAINED(0);
+	val = readl(NETX_DPMAS_INT_EN);
+	val &= ~((1 << 24) << irq);
+	writel(val, NETX_DPMAS_INT_EN);
+	DEBUG_IRQ("%s: irq %d\n", __FUNCTION__, _irq);
+}
+
+static void
+netx_hif_unmask_irq(unsigned int _irq)
+{
+	unsigned int val, irq;
+
+	irq = _irq - NETX_IRQ_HIF_CHAINED(0);
+	val = readl(NETX_DPMAS_INT_EN);
+	val |= (1 << 24) << irq;
+	writel(val, NETX_DPMAS_INT_EN);
+	DEBUG_IRQ("%s: irq %d\n", __FUNCTION__, _irq);
+}
+
+static struct irqchip netx_hif_chip = {
+	.ack = netx_hif_ack_irq,
+	.mask = netx_hif_mask_irq,
+	.unmask = netx_hif_unmask_irq,
+	.set_type = netx_hif_irq_type,
+};
+
+void __init netx_init_irq(void)
+{
+	int irq;
+
+	vic_init(__io(io_p2v(NETX_PA_VIC)), 0, ~0);
+
+	for (irq = NETX_IRQ_HIF_CHAINED(0); irq <= NETX_IRQ_HIF_LAST; irq++) {
+		set_irq_chip(irq, &netx_hif_chip);
+		set_irq_handler(irq, do_level_IRQ);
+		set_irq_flags(irq, IRQF_VALID);
+	}
+
+	writel(NETX_DPMAS_INT_EN_GLB_EN, NETX_DPMAS_INT_EN);
+	set_irq_chained_handler(NETX_IRQ_HIF, netx_hif_demux_handler);
+}
+
+static int __init netx_init(void)
+{
+	return platform_add_devices(devices, ARRAY_SIZE(devices));
+}
+
+subsys_initcall(netx_init);
+
diff --git a/arch/arm/mach-netx/generic.h b/arch/arm/mach-netx/generic.h
new file mode 100644
index 000000000..ede2d3534
--- /dev/null
+++ b/arch/arm/mach-netx/generic.h
@@ -0,0 +1,24 @@
+/*
+ * arch/arm/mach-netx/generic.h
+ *
+ * Copyright (c) 2005 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix
+ *
+ * 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
+ */
+
+extern void __init netx_map_io(void);
+extern void __init netx_init_irq(void);
+
+struct sys_timer;
+extern struct sys_timer netx_timer;
diff --git a/arch/arm/mach-netx/nxdb500.c b/arch/arm/mach-netx/nxdb500.c
new file mode 100644
index 000000000..e4a133d62
--- /dev/null
+++ b/arch/arm/mach-netx/nxdb500.c
@@ -0,0 +1,210 @@
+/*
+ * arch/arm/mach-netx/nxdb500.c
+ *
+ * Copyright (c) 2005 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix
+ *
+ * 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/dma-mapping.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/mtd/plat-ram.h>
+#include <linux/platform_device.h>
+#include <linux/amba/bus.h>
+#include <linux/amba/clcd.h>
+
+#include <asm/hardware.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/arch/netx-regs.h>
+#include <asm/arch/eth.h>
+
+#include "generic.h"
+#include "fb.h"
+
+static struct clcd_panel qvga = {
+	.mode		= {
+		.name		= "QVGA",
+		.refresh	= 60,
+		.xres		= 240,
+		.yres		= 320,
+		.pixclock	= 187617,
+		.left_margin	= 6,
+		.right_margin	= 26,
+		.upper_margin	= 0,
+		.lower_margin	= 6,
+		.hsync_len	= 6,
+		.vsync_len	= 1,
+		.sync		= 0,
+		.vmode		= FB_VMODE_NONINTERLACED,
+	},
+	.width		= -1,
+	.height		= -1,
+	.tim2		=  16,
+	.cntl		= CNTL_LCDTFT | CNTL_BGR,
+	.bpp		= 16,
+	.grayscale	= 0,
+};
+
+static inline int nxdb500_check(struct clcd_fb *fb, struct fb_var_screeninfo *var)
+{
+	var->green.length = 5;
+	var->green.msb_right = 0;
+
+	return clcdfb_check(fb, var);
+}
+
+static int nxdb500_clcd_setup(struct clcd_fb *fb)
+{
+	unsigned int val;
+
+	fb->fb.var.green.length = 5;
+	fb->fb.var.green.msb_right = 0;
+
+	/* enable asic control */
+	val = readl(NETX_SYSTEM_IOC_ACCESS_KEY);
+	writel(val, NETX_SYSTEM_IOC_ACCESS_KEY);
+
+	writel(3, NETX_SYSTEM_IOC_CR);
+
+	val = readl(NETX_PIO_OUTPIO);
+	writel(val | 1, NETX_PIO_OUTPIO);
+
+	val = readl(NETX_PIO_OEPIO);
+	writel(val | 1, NETX_PIO_OEPIO);
+	return netx_clcd_setup(fb);
+}
+
+static struct clcd_board clcd_data = {
+	.name		= "netX",
+	.check		= nxdb500_check,
+	.decode		= clcdfb_decode,
+	.enable		= netx_clcd_enable,
+	.setup		= nxdb500_clcd_setup,
+	.mmap		= netx_clcd_mmap,
+	.remove		= netx_clcd_remove,
+};
+
+static struct netxeth_platform_data eth0_platform_data = {
+	.xcno = 0,
+};
+
+static struct platform_device netx_eth0_device = {
+	.name		= "netx-eth",
+	.id		= 0,
+	.num_resources	= 0,
+	.resource	= NULL,
+	.dev = {
+		.platform_data = &eth0_platform_data,
+	}
+};
+
+static struct netxeth_platform_data eth1_platform_data = {
+	.xcno = 1,
+};
+
+static struct platform_device netx_eth1_device = {
+	.name		= "netx-eth",
+	.id		= 1,
+	.num_resources	= 0,
+	.resource	= NULL,
+	.dev = {
+		.platform_data = &eth1_platform_data,
+	}
+};
+
+static struct resource netx_uart0_resources[] = {
+	[0] = {
+		.start	= 0x00100A00,
+		.end	= 0x00100A3F,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= (NETX_IRQ_UART0),
+		.end	= (NETX_IRQ_UART0),
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device netx_uart0_device = {
+	.name		= "netx-uart",
+	.id		= 0,
+	.num_resources	= ARRAY_SIZE(netx_uart0_resources),
+	.resource	= netx_uart0_resources,
+};
+
+static struct resource netx_uart1_resources[] = {
+	[0] = {
+		.start	= 0x00100A40,
+		.end	= 0x00100A7F,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= (NETX_IRQ_UART1),
+		.end	= (NETX_IRQ_UART1),
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device netx_uart1_device = {
+	.name		= "netx-uart",
+	.id		= 1,
+	.num_resources	= ARRAY_SIZE(netx_uart1_resources),
+	.resource	= netx_uart1_resources,
+};
+
+static struct resource netx_uart2_resources[] = {
+	[0] = {
+		.start	= 0x00100A80,
+		.end	= 0x00100ABF,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= (NETX_IRQ_UART2),
+		.end	= (NETX_IRQ_UART2),
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device netx_uart2_device = {
+	.name		= "netx-uart",
+	.id		= 2,
+	.num_resources	= ARRAY_SIZE(netx_uart2_resources),
+	.resource	= netx_uart2_resources,
+};
+
+static struct platform_device *devices[] __initdata = {
+	&netx_eth0_device,
+	&netx_eth1_device,
+	&netx_uart0_device,
+	&netx_uart1_device,
+	&netx_uart2_device,
+};
+
+static void __init nxdb500_init(void)
+{
+	netx_fb_init(&clcd_data, &qvga);
+	platform_add_devices(devices, ARRAY_SIZE(devices));
+}
+
+MACHINE_START(NXDB500, "Hilscher nxdb500")
+	.phys_io	= 0x00100000,
+	.io_pg_offst	= (io_p2v(0x00100000) >> 18) & 0xfffc,
+	.boot_params	= 0x80000100,
+	.map_io		= netx_map_io,
+	.init_irq	= netx_init_irq,
+	.timer		= &netx_timer,
+	.init_machine	= nxdb500_init,
+MACHINE_END
diff --git a/arch/arm/mach-netx/nxdkn.c b/arch/arm/mach-netx/nxdkn.c
new file mode 100644
index 000000000..7e26c42d1
--- /dev/null
+++ b/arch/arm/mach-netx/nxdkn.c
@@ -0,0 +1,103 @@
+/*
+ * arch/arm/mach-netx/nxdkn.c
+ *
+ * Copyright (c) 2005 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix
+ *
+ * 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/dma-mapping.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/mtd/plat-ram.h>
+#include <linux/platform_device.h>
+#include <linux/amba/bus.h>
+#include <linux/amba/clcd.h>
+
+#include <asm/hardware.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/arch/netx-regs.h>
+#include <asm/arch/eth.h>
+
+#include "generic.h"
+
+static struct netxeth_platform_data eth0_platform_data = {
+	.xcno = 0,
+};
+
+static struct platform_device nxdkn_eth0_device = {
+	.name		= "netx-eth",
+	.id		= 0,
+	.num_resources	= 0,
+	.resource	= NULL,
+	.dev = {
+		.platform_data = &eth0_platform_data,
+	}
+};
+
+static struct netxeth_platform_data eth1_platform_data = {
+	.xcno = 1,
+};
+
+static struct platform_device nxdkn_eth1_device = {
+	.name		= "netx-eth",
+	.id		= 1,
+	.num_resources	= 0,
+	.resource	= NULL,
+	.dev = {
+		.platform_data = &eth1_platform_data,
+	}
+};
+
+static struct resource netx_uart0_resources[] = {
+	[0] = {
+		.start	= 0x00100A00,
+		.end	= 0x00100A3F,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= (NETX_IRQ_UART0),
+		.end	= (NETX_IRQ_UART0),
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device netx_uart0_device = {
+	.name		= "netx-uart",
+	.id		= 0,
+	.num_resources	= ARRAY_SIZE(netx_uart0_resources),
+	.resource	= netx_uart0_resources,
+};
+
+static struct platform_device *devices[] __initdata = {
+	&nxdkn_eth0_device,
+	&nxdkn_eth1_device,
+	&netx_uart0_device,
+};
+
+static void __init nxdkn_init(void)
+{
+	platform_add_devices(devices, ARRAY_SIZE(devices));
+}
+
+MACHINE_START(NXDKN, "Hilscher nxdkn")
+	.phys_io	= 0x00100000,
+	.io_pg_offst	= (io_p2v(0x00100000) >> 18) & 0xfffc,
+	.boot_params	= 0x80000100,
+	.map_io		= netx_map_io,
+	.init_irq	= netx_init_irq,
+	.timer		= &netx_timer,
+	.init_machine	= nxdkn_init,
+MACHINE_END
diff --git a/arch/arm/mach-netx/nxeb500hmi.c b/arch/arm/mach-netx/nxeb500hmi.c
new file mode 100644
index 000000000..53e10a984
--- /dev/null
+++ b/arch/arm/mach-netx/nxeb500hmi.c
@@ -0,0 +1,187 @@
+/*
+ * arch/arm/mach-netx/nxeb500hmi.c
+ *
+ * Copyright (c) 2005 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix
+ *
+ * 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/dma-mapping.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/mtd/plat-ram.h>
+#include <linux/platform_device.h>
+#include <linux/amba/bus.h>
+#include <linux/amba/clcd.h>
+
+#include <asm/hardware.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/arch/netx-regs.h>
+#include <asm/arch/eth.h>
+
+#include "generic.h"
+#include "fb.h"
+
+static struct clcd_panel qvga = {
+	.mode		= {
+		.name		= "QVGA",
+		.refresh	= 60,
+		.xres		= 240,
+		.yres		= 320,
+		.pixclock	= 187617,
+		.left_margin	= 6,
+		.right_margin	= 26,
+		.upper_margin	= 0,
+		.lower_margin	= 6,
+		.hsync_len	= 6,
+		.vsync_len	= 1,
+		.sync		= 0,
+		.vmode		= FB_VMODE_NONINTERLACED,
+	},
+	.width		= -1,
+	.height		= -1,
+	.tim2		=  16,
+	.cntl		= CNTL_LCDTFT | CNTL_BGR,
+	.bpp		= 16,
+	.grayscale	= 0,
+};
+
+static inline int nxeb500hmi_check(struct clcd_fb *fb, struct fb_var_screeninfo *var)
+{
+	var->green.length = 5;
+	var->green.msb_right = 0;
+
+	return clcdfb_check(fb, var);
+}
+
+static int nxeb500hmi_clcd_setup(struct clcd_fb *fb)
+{
+	unsigned int val;
+
+	fb->fb.var.green.length = 5;
+	fb->fb.var.green.msb_right = 0;
+
+	/* enable asic control */
+	val = readl(NETX_SYSTEM_IOC_ACCESS_KEY);
+	writel(val, NETX_SYSTEM_IOC_ACCESS_KEY);
+
+	writel(3, NETX_SYSTEM_IOC_CR);
+
+	/* GPIO 14 is used for display enable on newer boards */
+	writel(9, NETX_GPIO_CFG(14));
+
+	val = readl(NETX_PIO_OUTPIO);
+	writel(val | 1, NETX_PIO_OUTPIO);
+
+	val = readl(NETX_PIO_OEPIO);
+	writel(val | 1, NETX_PIO_OEPIO);
+	return netx_clcd_setup(fb);
+}
+
+static struct clcd_board clcd_data = {
+	.name		= "netX",
+	.check		= nxeb500hmi_check,
+	.decode		= clcdfb_decode,
+	.enable		= netx_clcd_enable,
+	.setup		= nxeb500hmi_clcd_setup,
+	.mmap		= netx_clcd_mmap,
+	.remove		= netx_clcd_remove,
+};
+
+static struct netxeth_platform_data eth0_platform_data = {
+	.xcno = 0,
+};
+
+static struct platform_device netx_eth0_device = {
+	.name		= "netx-eth",
+	.id		= 0,
+	.num_resources	= 0,
+	.resource	= NULL,
+	.dev = {
+		.platform_data = &eth0_platform_data,
+	}
+};
+
+static struct netxeth_platform_data eth1_platform_data = {
+	.xcno = 1,
+};
+
+static struct platform_device netx_eth1_device = {
+	.name		= "netx-eth",
+	.id		= 1,
+	.num_resources	= 0,
+	.resource	= NULL,
+	.dev = {
+		.platform_data = &eth1_platform_data,
+	}
+};
+
+static struct resource netx_cf_resources[] = {
+	[0] = {
+		.start	= 0x20000000,
+		.end	= 0x25ffffff,
+		.flags	= IORESOURCE_MEM | IORESOURCE_MEM_8AND16BIT,
+	},
+};
+
+static struct platform_device netx_cf_device = {
+	.name		= "netx-cf",
+	.id		= 0,
+	.resource	= netx_cf_resources,
+	.num_resources	= ARRAY_SIZE(netx_cf_resources),
+};
+
+static struct resource netx_uart0_resources[] = {
+	[0] = {
+		.start	= 0x00100A00,
+		.end	= 0x00100A3F,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= (NETX_IRQ_UART0),
+		.end	= (NETX_IRQ_UART0),
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device netx_uart0_device = {
+	.name		= "netx-uart",
+	.id		= 0,
+	.num_resources	= ARRAY_SIZE(netx_uart0_resources),
+	.resource	= netx_uart0_resources,
+};
+
+static struct platform_device *devices[] __initdata = {
+	&netx_eth0_device,
+	&netx_eth1_device,
+	&netx_cf_device,
+	&netx_uart0_device,
+};
+
+static void __init nxeb500hmi_init(void)
+{
+	netx_fb_init(&clcd_data, &qvga);
+	platform_add_devices(devices, ARRAY_SIZE(devices));
+}
+
+MACHINE_START(NXEB500HMI, "Hilscher nxeb500hmi")
+	.phys_io	= 0x00100000,
+	.io_pg_offst	= (io_p2v(0x00100000) >> 18) & 0xfffc,
+	.boot_params	= 0x80000100,
+	.map_io		= netx_map_io,
+	.init_irq	= netx_init_irq,
+	.timer		= &netx_timer,
+	.init_machine	= nxeb500hmi_init,
+MACHINE_END
diff --git a/arch/arm/mach-netx/pfifo.c b/arch/arm/mach-netx/pfifo.c
new file mode 100644
index 000000000..44dea61a9
--- /dev/null
+++ b/arch/arm/mach-netx/pfifo.c
@@ -0,0 +1,68 @@
+/*
+ * arch/arm/mach-netx/pfifo.c
+ *
+ * Copyright (c) 2005 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix
+ *
+ * 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 <linux/module.h>
+#include <linux/mutex.h>
+
+#include <asm/io.h>
+#include <asm/hardware.h>
+#include <asm/arch/netx-regs.h>
+#include <asm/arch/pfifo.h>
+
+static DEFINE_MUTEX(pfifo_lock);
+
+static unsigned int pfifo_used = 0;
+
+int pfifo_request(unsigned int pfifo_mask)
+{
+	int err = 0;
+	unsigned int val;
+
+	mutex_lock(&pfifo_lock);
+
+	if (pfifo_mask & pfifo_used) {
+		err = -EBUSY;
+		goto out;
+	}
+
+	pfifo_used |= pfifo_mask;
+
+	val = readl(NETX_PFIFO_RESET);
+	writel(val | pfifo_mask, NETX_PFIFO_RESET);
+	writel(val, NETX_PFIFO_RESET);
+
+out:
+	mutex_unlock(&pfifo_lock);
+	return err;
+}
+
+void pfifo_free(unsigned int pfifo_mask)
+{
+	mutex_lock(&pfifo_lock);
+	pfifo_used &= ~pfifo_mask;
+	mutex_unlock(&pfifo_lock);
+}
+
+EXPORT_SYMBOL(pfifo_push);
+EXPORT_SYMBOL(pfifo_pop);
+EXPORT_SYMBOL(pfifo_fill_level);
+EXPORT_SYMBOL(pfifo_empty);
+EXPORT_SYMBOL(pfifo_request);
+EXPORT_SYMBOL(pfifo_free);
diff --git a/arch/arm/mach-netx/time.c b/arch/arm/mach-netx/time.c
new file mode 100644
index 000000000..6d72c81b7
--- /dev/null
+++ b/arch/arm/mach-netx/time.c
@@ -0,0 +1,88 @@
+/*
+ * arch/arm/mach-netx/time.c
+ *
+ * Copyright (c) 2005 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix
+ *
+ * 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 <linux/interrupt.h>
+
+#include <asm/hardware.h>
+#include <asm/io.h>
+#include <asm/mach/time.h>
+#include <asm/arch/netx-regs.h>
+
+/*
+ * Returns number of us since last clock interrupt.  Note that interrupts
+ * will have been disabled by do_gettimeoffset()
+ */
+static unsigned long netx_gettimeoffset(void)
+{
+	return readl(NETX_GPIO_COUNTER_CURRENT(0)) / 100;
+}
+
+/*
+ * IRQ handler for the timer
+ */
+static irqreturn_t
+netx_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	write_seqlock(&xtime_lock);
+
+	timer_tick(regs);
+	write_sequnlock(&xtime_lock);
+
+	/* acknowledge interrupt */
+	writel(COUNTER_BIT(0), NETX_GPIO_IRQ);
+
+	return IRQ_HANDLED;
+}
+
+
+static struct irqaction netx_timer_irq = {
+	.name           = "NetX Timer Tick",
+	.flags          = IRQF_DISABLED | IRQF_TIMER,
+	.handler        = netx_timer_interrupt,
+};
+
+/*
+ * Set up timer interrupt
+ */
+static void __init netx_timer_init(void)
+{
+	/* disable timer initially */
+	writel(0, NETX_GPIO_COUNTER_CTRL(0));
+
+	/* Reset the timer value to zero */
+	writel(0, NETX_GPIO_COUNTER_CURRENT(0));
+
+	writel(LATCH, NETX_GPIO_COUNTER_MAX(0));
+
+	/* acknowledge interrupt */
+	writel(COUNTER_BIT(0), NETX_GPIO_IRQ);
+
+	/* Enable the interrupt in the specific timer register and start timer */
+	writel(COUNTER_BIT(0), NETX_GPIO_IRQ_ENABLE);
+	writel(NETX_GPIO_COUNTER_CTRL_IRQ_EN | NETX_GPIO_COUNTER_CTRL_RUN,
+		NETX_GPIO_COUNTER_CTRL(0));
+
+	setup_irq(NETX_IRQ_TIMER0, &netx_timer_irq);
+}
+
+struct sys_timer netx_timer = {
+	.init           = netx_timer_init,
+	.offset         = netx_gettimeoffset,
+};
diff --git a/arch/arm/mach-netx/xc.c b/arch/arm/mach-netx/xc.c
new file mode 100644
index 000000000..172a058dd
--- /dev/null
+++ b/arch/arm/mach-netx/xc.c
@@ -0,0 +1,255 @@
+/*
+ * arch/arm/mach-netx/xc.c
+ *
+ * Copyright (c) 2005 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix
+ *
+ * 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 <linux/device.h>
+#include <linux/firmware.h>
+#include <linux/mutex.h>
+
+#include <asm/io.h>
+#include <asm/hardware.h>
+#include <asm/arch/netx-regs.h>
+
+#include <asm/arch/xc.h>
+
+static DEFINE_MUTEX(xc_lock);
+
+static int xc_in_use = 0;
+
+struct fw_desc {
+	unsigned int ofs;
+	unsigned int size;
+	unsigned int patch_ofs;
+	unsigned int patch_entries;
+};
+
+struct fw_header {
+	unsigned int magic;
+	unsigned int type;
+	unsigned int version;
+	unsigned int reserved[5];
+	struct fw_desc fw_desc[3];
+} __attribute__ ((packed));
+
+int xc_stop(struct xc *x)
+{
+	writel(RPU_HOLD_PC, x->xmac_base + NETX_XMAC_RPU_HOLD_PC_OFS);
+	writel(TPU_HOLD_PC, x->xmac_base + NETX_XMAC_TPU_HOLD_PC_OFS);
+	writel(XPU_HOLD_PC, x->xpec_base + NETX_XPEC_XPU_HOLD_PC_OFS);
+	return 0;
+}
+
+int xc_start(struct xc *x)
+{
+	writel(0, x->xmac_base + NETX_XMAC_RPU_HOLD_PC_OFS);
+	writel(0, x->xmac_base + NETX_XMAC_TPU_HOLD_PC_OFS);
+	writel(0, x->xpec_base + NETX_XPEC_XPU_HOLD_PC_OFS);
+	return 0;
+}
+
+int xc_running(struct xc *x)
+{
+	return (readl(x->xmac_base + NETX_XMAC_RPU_HOLD_PC_OFS) & RPU_HOLD_PC)
+	    || (readl(x->xmac_base + NETX_XMAC_TPU_HOLD_PC_OFS) & TPU_HOLD_PC)
+	    || (readl(x->xpec_base + NETX_XPEC_XPU_HOLD_PC_OFS) & XPU_HOLD_PC) ?
+		0 : 1;
+}
+
+int xc_reset(struct xc *x)
+{
+	writel(0, x->xpec_base + NETX_XPEC_PC_OFS);
+	return 0;
+}
+
+static int xc_check_ptr(struct xc *x, unsigned long adr, unsigned int size)
+{
+	if (adr >= NETX_PA_XMAC(x->no) &&
+	    adr + size < NETX_PA_XMAC(x->no) + XMAC_MEM_SIZE)
+		return 0;
+
+	if (adr >= NETX_PA_XPEC(x->no) &&
+	    adr + size < NETX_PA_XPEC(x->no) + XPEC_MEM_SIZE)
+		return 0;
+
+	dev_err(x->dev, "Illegal pointer in firmware found. aborting\n");
+
+	return -1;
+}
+
+static int xc_patch(struct xc *x, void *patch, int count)
+{
+	unsigned int val, adr;
+	unsigned int *data = patch;
+
+	int i;
+	for (i = 0; i < count; i++) {
+		adr = *data++;
+		val = *data++;
+		if (xc_check_ptr(x, adr, 4) < 0)
+			return -EINVAL;
+
+		writel(val, (void __iomem *)io_p2v(adr));
+	}
+	return 0;
+}
+
+int xc_request_firmware(struct xc *x)
+{
+	int ret;
+	char name[16];
+	const struct firmware *fw;
+	struct fw_header *head;
+	unsigned int size;
+	int i;
+	void *src;
+	unsigned long dst;
+
+	sprintf(name, "xc%d.bin", x->no);
+
+	ret = request_firmware(&fw, name, x->dev);
+
+	if (ret < 0) {
+		dev_err(x->dev, "request_firmware failed\n");
+		return ret;
+	}
+
+	head = (struct fw_header *)fw->data;
+	if (head->magic != 0x4e657458) {
+		if (head->magic == 0x5874654e) {
+			dev_err(x->dev,
+			    "firmware magic is 'XteN'. Endianess problems?\n");
+			ret = -ENODEV;
+			goto exit_release_firmware;
+		}
+		dev_err(x->dev, "unrecognized firmware magic 0x%08x\n",
+			head->magic);
+		ret = -ENODEV;
+		goto exit_release_firmware;
+	}
+
+	x->type = head->type;
+	x->version = head->version;
+
+	ret = -EINVAL;
+
+	for (i = 0; i < 3; i++) {
+		src = fw->data + head->fw_desc[i].ofs;
+		dst = *(unsigned int *)src;
+		src += sizeof (unsigned int);
+		size = head->fw_desc[i].size - sizeof (unsigned int);
+
+		if (xc_check_ptr(x, dst, size))
+			goto exit_release_firmware;
+
+		memcpy((void *)io_p2v(dst), src, size);
+
+		src = fw->data + head->fw_desc[i].patch_ofs;
+		size = head->fw_desc[i].patch_entries;
+		ret = xc_patch(x, src, size);
+		if (ret < 0)
+			goto exit_release_firmware;
+	}
+
+	ret = 0;
+
+      exit_release_firmware:
+	release_firmware(fw);
+
+	return ret;
+}
+
+struct xc *request_xc(int xcno, struct device *dev)
+{
+	struct xc *x = NULL;
+
+	mutex_lock(&xc_lock);
+
+	if (xcno > 3)
+		goto exit;
+	if (xc_in_use & (1 << xcno))
+		goto exit;
+
+	x = kmalloc(sizeof (struct xc), GFP_KERNEL);
+	if (!x)
+		goto exit;
+
+	if (!request_mem_region
+	    (NETX_PA_XPEC(xcno), XPEC_MEM_SIZE, dev->kobj.name))
+		goto exit_free;
+
+	if (!request_mem_region
+	    (NETX_PA_XMAC(xcno), XMAC_MEM_SIZE, dev->kobj.name))
+		goto exit_release_1;
+
+	if (!request_mem_region
+	    (SRAM_INTERNAL_PHYS(xcno), SRAM_MEM_SIZE, dev->kobj.name))
+		goto exit_release_2;
+
+	x->xpec_base = (void * __iomem)io_p2v(NETX_PA_XPEC(xcno));
+	x->xmac_base = (void * __iomem)io_p2v(NETX_PA_XMAC(xcno));
+	x->sram_base = ioremap(SRAM_INTERNAL_PHYS(xcno), SRAM_MEM_SIZE);
+	if (!x->sram_base)
+		goto exit_release_3;
+
+	x->irq = NETX_IRQ_XPEC(xcno);
+
+	x->no = xcno;
+	x->dev = dev;
+
+	xc_in_use |= (1 << xcno);
+
+	goto exit;
+
+      exit_release_3:
+	release_mem_region(SRAM_INTERNAL_PHYS(xcno), SRAM_MEM_SIZE);
+      exit_release_2:
+	release_mem_region(NETX_PA_XMAC(xcno), XMAC_MEM_SIZE);
+      exit_release_1:
+	release_mem_region(NETX_PA_XPEC(xcno), XPEC_MEM_SIZE);
+      exit_free:
+	kfree(x);
+	x = NULL;
+      exit:
+	mutex_unlock(&xc_lock);
+	return x;
+}
+
+void free_xc(struct xc *x)
+{
+	int xcno = x->no;
+
+	mutex_lock(&xc_lock);
+
+	iounmap(x->sram_base);
+	release_mem_region(SRAM_INTERNAL_PHYS(xcno), SRAM_MEM_SIZE);
+	release_mem_region(NETX_PA_XMAC(xcno), XMAC_MEM_SIZE);
+	release_mem_region(NETX_PA_XPEC(xcno), XPEC_MEM_SIZE);
+	xc_in_use &= ~(1 << x->no);
+	kfree(x);
+
+	mutex_unlock(&xc_lock);
+}
+
+EXPORT_SYMBOL(free_xc);
+EXPORT_SYMBOL(request_xc);
+EXPORT_SYMBOL(xc_request_firmware);
+EXPORT_SYMBOL(xc_reset);
+EXPORT_SYMBOL(xc_running);
+EXPORT_SYMBOL(xc_start);
+EXPORT_SYMBOL(xc_stop);
diff --git a/arch/arm/mach-omap1/board-fsample.c b/arch/arm/mach-omap1/board-fsample.c
new file mode 100644
index 000000000..c753a3c5a
--- /dev/null
+++ b/arch/arm/mach-omap1/board-fsample.c
@@ -0,0 +1,319 @@
+/*
+ * linux/arch/arm/mach-omap1/board-fsample.c
+ *
+ * Modified from board-perseus2.c
+ *
+ * Original OMAP730 support by Jean Pihet <j-pihet@ti.com>
+ * Updated for 2.6 by Kevin Hilman <kjh@hilman.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.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/partitions.h>
+#include <linux/input.h>
+
+#include <asm/hardware.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/flash.h>
+#include <asm/mach/map.h>
+
+#include <asm/arch/tc.h>
+#include <asm/arch/gpio.h>
+#include <asm/arch/mux.h>
+#include <asm/arch/fpga.h>
+#include <asm/arch/keypad.h>
+#include <asm/arch/common.h>
+#include <asm/arch/board.h>
+#include <asm/arch/board-fsample.h>
+
+static int fsample_keymap[] = {
+	KEY(0,0,KEY_UP),
+	KEY(0,1,KEY_RIGHT),
+	KEY(0,2,KEY_LEFT),
+	KEY(0,3,KEY_DOWN),
+	KEY(0,4,KEY_CENTER),
+	KEY(0,5,KEY_0_5),
+	KEY(1,0,KEY_SOFT2),
+	KEY(1,1,KEY_SEND),
+	KEY(1,2,KEY_END),
+	KEY(1,3,KEY_VOLUMEDOWN),
+	KEY(1,4,KEY_VOLUMEUP),
+	KEY(1,5,KEY_RECORD),
+	KEY(2,0,KEY_SOFT1),
+	KEY(2,1,KEY_3),
+	KEY(2,2,KEY_6),
+	KEY(2,3,KEY_9),
+	KEY(2,4,KEY_SHARP),
+	KEY(2,5,KEY_2_5),
+	KEY(3,0,KEY_BACK),
+	KEY(3,1,KEY_2),
+	KEY(3,2,KEY_5),
+	KEY(3,3,KEY_8),
+	KEY(3,4,KEY_0),
+	KEY(3,5,KEY_HEADSETHOOK),
+	KEY(4,0,KEY_HOME),
+	KEY(4,1,KEY_1),
+	KEY(4,2,KEY_4),
+	KEY(4,3,KEY_7),
+	KEY(4,4,KEY_STAR),
+	KEY(4,5,KEY_POWER),
+	0
+};
+
+static struct resource smc91x_resources[] = {
+	[0] = {
+		.start	= H2P2_DBG_FPGA_ETHR_START,	/* Physical */
+		.end	= H2P2_DBG_FPGA_ETHR_START + 0xf,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= INT_730_MPU_EXT_NIRQ,
+		.end	= 0,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct mtd_partition nor_partitions[] = {
+	/* bootloader (U-Boot, etc) in first sector */
+	{
+	      .name		= "bootloader",
+	      .offset		= 0,
+	      .size		= SZ_128K,
+	      .mask_flags	= MTD_WRITEABLE, /* force read-only */
+	},
+	/* bootloader params in the next sector */
+	{
+	      .name		= "params",
+	      .offset		= MTDPART_OFS_APPEND,
+	      .size		= SZ_128K,
+	      .mask_flags	= 0,
+	},
+	/* kernel */
+	{
+	      .name		= "kernel",
+	      .offset		= MTDPART_OFS_APPEND,
+	      .size		= SZ_2M,
+	      .mask_flags	= 0
+	},
+	/* rest of flash is a file system */
+	{
+	      .name		= "rootfs",
+	      .offset		= MTDPART_OFS_APPEND,
+	      .size		= MTDPART_SIZ_FULL,
+	      .mask_flags	= 0
+	},
+};
+
+static struct flash_platform_data nor_data = {
+	.map_name	= "cfi_probe",
+	.width		= 2,
+	.parts		= nor_partitions,
+	.nr_parts	= ARRAY_SIZE(nor_partitions),
+};
+
+static struct resource nor_resource = {
+	.start		= OMAP_CS0_PHYS,
+	.end		= OMAP_CS0_PHYS + SZ_32M - 1,
+	.flags		= IORESOURCE_MEM,
+};
+
+static struct platform_device nor_device = {
+	.name		= "omapflash",
+	.id		= 0,
+	.dev		= {
+		.platform_data	= &nor_data,
+	},
+	.num_resources	= 1,
+	.resource	= &nor_resource,
+};
+
+static struct nand_platform_data nand_data = {
+	.options	= NAND_SAMSUNG_LP_OPTIONS,
+};
+
+static struct resource nand_resource = {
+	.start		= OMAP_CS3_PHYS,
+	.end		= OMAP_CS3_PHYS + SZ_4K - 1,
+	.flags		= IORESOURCE_MEM,
+};
+
+static struct platform_device nand_device = {
+	.name		= "omapnand",
+	.id		= 0,
+	.dev		= {
+		.platform_data	= &nand_data,
+	},
+	.num_resources	= 1,
+	.resource	= &nand_resource,
+};
+
+static struct platform_device smc91x_device = {
+	.name		= "smc91x",
+	.id		= 0,
+	.num_resources	= ARRAY_SIZE(smc91x_resources),
+	.resource	= smc91x_resources,
+};
+
+static struct resource kp_resources[] = {
+	[0] = {
+		.start	= INT_730_MPUIO_KEYPAD,
+		.end	= INT_730_MPUIO_KEYPAD,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct omap_kp_platform_data kp_data = {
+	.rows	= 8,
+	.cols	= 8,
+	.keymap = fsample_keymap,
+};
+
+static struct platform_device kp_device = {
+	.name		= "omap-keypad",
+	.id		= -1,
+	.dev		= {
+		.platform_data = &kp_data,
+	},
+	.num_resources	= ARRAY_SIZE(kp_resources),
+	.resource	= kp_resources,
+};
+
+static struct platform_device lcd_device = {
+	.name		= "lcd_p2",
+	.id		= -1,
+};
+
+static struct platform_device *devices[] __initdata = {
+	&nor_device,
+	&nand_device,
+	&smc91x_device,
+	&kp_device,
+	&lcd_device,
+};
+
+#define P2_NAND_RB_GPIO_PIN	62
+
+static int nand_dev_ready(struct nand_platform_data *data)
+{
+	return omap_get_gpio_datain(P2_NAND_RB_GPIO_PIN);
+}
+
+static struct omap_uart_config fsample_uart_config __initdata = {
+	.enabled_uarts = ((1 << 0) | (1 << 1)),
+};
+
+static struct omap_lcd_config fsample_lcd_config __initdata = {
+	.ctrl_name	= "internal",
+};
+
+static struct omap_board_config_kernel fsample_config[] = {
+	{ OMAP_TAG_UART,	&fsample_uart_config },
+	{ OMAP_TAG_LCD,		&fsample_lcd_config },
+};
+
+static void __init omap_fsample_init(void)
+{
+	if (!(omap_request_gpio(P2_NAND_RB_GPIO_PIN)))
+		nand_data.dev_ready = nand_dev_ready;
+
+	omap_cfg_reg(L3_1610_FLASH_CS2B_OE);
+	omap_cfg_reg(M8_1610_FLASH_CS2B_WE);
+
+	platform_add_devices(devices, ARRAY_SIZE(devices));
+
+	omap_board_config = fsample_config;
+	omap_board_config_size = ARRAY_SIZE(fsample_config);
+	omap_serial_init();
+}
+
+static void __init fsample_init_smc91x(void)
+{
+	fpga_write(1, H2P2_DBG_FPGA_LAN_RESET);
+	mdelay(50);
+	fpga_write(fpga_read(H2P2_DBG_FPGA_LAN_RESET) & ~1,
+		   H2P2_DBG_FPGA_LAN_RESET);
+	mdelay(50);
+}
+
+void omap_fsample_init_irq(void)
+{
+	omap1_init_common_hw();
+	omap_init_irq();
+	omap_gpio_init();
+	fsample_init_smc91x();
+}
+
+/* Only FPGA needs to be mapped here. All others are done with ioremap */
+static struct map_desc omap_fsample_io_desc[] __initdata = {
+	{
+		.virtual	= H2P2_DBG_FPGA_BASE,
+		.pfn		= __phys_to_pfn(H2P2_DBG_FPGA_START),
+		.length		= H2P2_DBG_FPGA_SIZE,
+		.type		= MT_DEVICE
+	},
+	{
+		.virtual	= FSAMPLE_CPLD_BASE,
+		.pfn		= __phys_to_pfn(FSAMPLE_CPLD_START),
+		.length		= FSAMPLE_CPLD_SIZE,
+		.type		= MT_DEVICE
+	}
+};
+
+static void __init omap_fsample_map_io(void)
+{
+	omap1_map_common_io();
+	iotable_init(omap_fsample_io_desc,
+		     ARRAY_SIZE(omap_fsample_io_desc));
+
+	/* Early, board-dependent init */
+
+	/*
+	 * Hold GSM Reset until needed
+	 */
+	omap_writew(omap_readw(OMAP730_DSP_M_CTL) & ~1, OMAP730_DSP_M_CTL);
+
+	/*
+	 * UARTs -> done automagically by 8250 driver
+	 */
+
+	/*
+	 * CSx timings, GPIO Mux ... setup
+	 */
+
+	/* Flash: CS0 timings setup */
+	omap_writel(0x0000fff3, OMAP730_FLASH_CFG_0);
+	omap_writel(0x00000088, OMAP730_FLASH_ACFG_0);
+
+	/*
+	 * Ethernet support through the debug board
+	 * CS1 timings setup
+	 */
+	omap_writel(0x0000fff3, OMAP730_FLASH_CFG_1);
+	omap_writel(0x00000000, OMAP730_FLASH_ACFG_1);
+
+	/*
+	 * Configure MPU_EXT_NIRQ IO in IO_CONF9 register,
+	 * It is used as the Ethernet controller interrupt
+	 */
+	omap_writel(omap_readl(OMAP730_IO_CONF_9) & 0x1FFFFFFF, OMAP730_IO_CONF_9);
+}
+
+MACHINE_START(OMAP_FSAMPLE, "OMAP730 F-Sample")
+/* Maintainer: Brian Swetland <swetland@google.com> */
+	.phys_io	= 0xfff00000,
+	.io_pg_offst	= ((0xfef00000) >> 18) & 0xfffc,
+	.boot_params	= 0x10000100,
+	.map_io		= omap_fsample_map_io,
+	.init_irq	= omap_fsample_init_irq,
+	.init_machine	= omap_fsample_init,
+	.timer		= &omap_timer,
+MACHINE_END
diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c
new file mode 100644
index 000000000..c7a48f921
--- /dev/null
+++ b/arch/arm/mach-omap2/gpmc.c
@@ -0,0 +1,209 @@
+/*
+ * GPMC support functions
+ *
+ * Copyright (C) 2005-2006 Nokia Corporation
+ *
+ * Author: Juha Yrjola
+ *
+ * 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/err.h>
+#include <linux/clk.h>
+
+#include <asm/io.h>
+#include <asm/arch/gpmc.h>
+
+#undef DEBUG
+
+#define GPMC_BASE		0x6800a000
+#define GPMC_REVISION		0x00
+#define GPMC_SYSCONFIG		0x10
+#define GPMC_SYSSTATUS		0x14
+#define GPMC_IRQSTATUS		0x18
+#define GPMC_IRQENABLE		0x1c
+#define GPMC_TIMEOUT_CONTROL	0x40
+#define GPMC_ERR_ADDRESS	0x44
+#define GPMC_ERR_TYPE		0x48
+#define GPMC_CONFIG		0x50
+#define GPMC_STATUS		0x54
+#define GPMC_PREFETCH_CONFIG1	0x1e0
+#define GPMC_PREFETCH_CONFIG2	0x1e4
+#define GPMC_PREFETCH_CONTROL	0x1e8
+#define GPMC_PREFETCH_STATUS	0x1f0
+#define GPMC_ECC_CONFIG		0x1f4
+#define GPMC_ECC_CONTROL	0x1f8
+#define GPMC_ECC_SIZE_CONFIG	0x1fc
+
+#define GPMC_CS0		0x60
+#define GPMC_CS_SIZE		0x30
+
+static void __iomem *gpmc_base =
+	(void __iomem *) IO_ADDRESS(GPMC_BASE);
+static void __iomem *gpmc_cs_base =
+	(void __iomem *) IO_ADDRESS(GPMC_BASE) + GPMC_CS0;
+
+static struct clk *gpmc_l3_clk;
+
+static void gpmc_write_reg(int idx, u32 val)
+{
+	__raw_writel(val, gpmc_base + idx);
+}
+
+static u32 gpmc_read_reg(int idx)
+{
+	return __raw_readl(gpmc_base + idx);
+}
+
+void gpmc_cs_write_reg(int cs, int idx, u32 val)
+{
+	void __iomem *reg_addr;
+
+	reg_addr = gpmc_cs_base + (cs * GPMC_CS_SIZE) + idx;
+	__raw_writel(val, reg_addr);
+}
+
+u32 gpmc_cs_read_reg(int cs, int idx)
+{
+	return __raw_readl(gpmc_cs_base + (cs * GPMC_CS_SIZE) + idx);
+}
+
+/* TODO: Add support for gpmc_fck to clock framework and use it */
+static unsigned long gpmc_get_fclk_period(void)
+{
+	/* In picoseconds */
+	return 1000000000 / ((clk_get_rate(gpmc_l3_clk)) / 1000);
+}
+
+unsigned int gpmc_ns_to_ticks(unsigned int time_ns)
+{
+	unsigned long tick_ps;
+
+	/* Calculate in picosecs to yield more exact results */
+	tick_ps = gpmc_get_fclk_period();
+
+	return (time_ns * 1000 + tick_ps - 1) / tick_ps;
+}
+
+#ifdef DEBUG
+static int set_gpmc_timing_reg(int cs, int reg, int st_bit, int end_bit,
+			       int time, const char *name)
+#else
+static int set_gpmc_timing_reg(int cs, int reg, int st_bit, int end_bit,
+			       int time)
+#endif
+{
+	u32 l;
+	int ticks, mask, nr_bits;
+
+	if (time == 0)
+		ticks = 0;
+	else
+		ticks = gpmc_ns_to_ticks(time);
+	nr_bits = end_bit - st_bit + 1;
+	if (ticks >= 1 << nr_bits)
+		return -1;
+
+	mask = (1 << nr_bits) - 1;
+	l = gpmc_cs_read_reg(cs, reg);
+#ifdef DEBUG
+	printk(KERN_INFO "GPMC CS%d: %-10s: %d ticks, %3lu ns (was %i ticks)\n",
+	       cs, name, ticks, gpmc_get_fclk_period() * ticks / 1000,
+	       (l >> st_bit) & mask);
+#endif
+	l &= ~(mask << st_bit);
+	l |= ticks << st_bit;
+	gpmc_cs_write_reg(cs, reg, l);
+
+	return 0;
+}
+
+#ifdef DEBUG
+#define GPMC_SET_ONE(reg, st, end, field) \
+	if (set_gpmc_timing_reg(cs, (reg), (st), (end),		\
+			t->field, #field) < 0)			\
+		return -1
+#else
+#define GPMC_SET_ONE(reg, st, end, field) \
+	if (set_gpmc_timing_reg(cs, (reg), (st), (end), t->field) < 0) \
+		return -1
+#endif
+
+int gpmc_cs_calc_divider(int cs, unsigned int sync_clk)
+{
+	int div;
+	u32 l;
+
+	l = sync_clk * 1000 + (gpmc_get_fclk_period() - 1);
+	div = l / gpmc_get_fclk_period();
+	if (div > 4)
+		return -1;
+	if (div < 0)
+		div = 1;
+
+	return div;
+}
+
+int gpmc_cs_set_timings(int cs, const struct gpmc_timings *t)
+{
+	int div;
+	u32 l;
+
+	div = gpmc_cs_calc_divider(cs, t->sync_clk);
+	if (div < 0)
+		return -1;
+
+	GPMC_SET_ONE(GPMC_CS_CONFIG2,  0,  3, cs_on);
+	GPMC_SET_ONE(GPMC_CS_CONFIG2,  8, 12, cs_rd_off);
+	GPMC_SET_ONE(GPMC_CS_CONFIG2, 16, 20, cs_wr_off);
+
+	GPMC_SET_ONE(GPMC_CS_CONFIG3,  0,  3, adv_on);
+	GPMC_SET_ONE(GPMC_CS_CONFIG3,  8, 12, adv_rd_off);
+	GPMC_SET_ONE(GPMC_CS_CONFIG3, 16, 20, adv_wr_off);
+
+	GPMC_SET_ONE(GPMC_CS_CONFIG4,  0,  3, oe_on);
+	GPMC_SET_ONE(GPMC_CS_CONFIG4,  8, 12, oe_off);
+	GPMC_SET_ONE(GPMC_CS_CONFIG4, 16, 19, we_on);
+	GPMC_SET_ONE(GPMC_CS_CONFIG4, 24, 28, we_off);
+
+	GPMC_SET_ONE(GPMC_CS_CONFIG5,  0,  4, rd_cycle);
+	GPMC_SET_ONE(GPMC_CS_CONFIG5,  8, 12, wr_cycle);
+	GPMC_SET_ONE(GPMC_CS_CONFIG5, 16, 20, access);
+
+	GPMC_SET_ONE(GPMC_CS_CONFIG5, 24, 27, page_burst_access);
+
+#ifdef DEBUG
+	printk(KERN_INFO "GPMC CS%d CLK period is %lu (div %d)\n",
+	       cs, gpmc_get_fclk_period(), div);
+#endif
+
+	l = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG1);
+	l &= ~0x03;
+	l |= (div - 1);
+
+	return 0;
+}
+
+unsigned long gpmc_cs_get_base_addr(int cs)
+{
+	return (gpmc_cs_read_reg(cs, GPMC_CS_CONFIG7) & 0x1f) << 24;
+}
+
+void __init gpmc_init(void)
+{
+	u32 l;
+
+	gpmc_l3_clk = clk_get(NULL, "core_l3_ck");
+	BUG_ON(IS_ERR(gpmc_l3_clk));
+
+	l = gpmc_read_reg(GPMC_REVISION);
+	printk(KERN_INFO "GPMC revision %d.%d\n", (l >> 4) & 0x0f, l & 0x0f);
+	/* Set smart idle mode and automatic L3 clock gating */
+	l = gpmc_read_reg(GPMC_SYSCONFIG);
+	l &= 0x03 << 3;
+	l |= (0x02 << 3) | (1 << 0);
+	gpmc_write_reg(GPMC_SYSCONFIG, l);
+}
diff --git a/arch/arm/mach-omap2/pm-domain.c b/arch/arm/mach-omap2/pm-domain.c
new file mode 100644
index 000000000..2494091a0
--- /dev/null
+++ b/arch/arm/mach-omap2/pm-domain.c
@@ -0,0 +1,299 @@
+/*
+ * linux/arch/arm/mach-omap2/pm-domain.c
+ *
+ * Power domain functions for OMAP2
+ *
+ * Copyright (C) 2006 Nokia Corporation
+ * Tony Lindgren <tony@atomide.com>
+ *
+ * Some code based on earlier OMAP2 sample PM code
+ * Copyright (C) 2005 Texas Instruments, Inc.
+ * Richard Woodruff <r-woodruff2@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/clk.h>
+
+#include <asm/io.h>
+
+#include "prcm-regs.h"
+
+/* Power domain offsets */
+#define PM_MPU_OFFSET			0x100
+#define PM_CORE_OFFSET			0x200
+#define PM_GFX_OFFSET			0x300
+#define PM_WKUP_OFFSET			0x400		/* Autoidle only */
+#define PM_PLL_OFFSET			0x500		/* Autoidle only */
+#define PM_DSP_OFFSET			0x800
+#define PM_MDM_OFFSET			0xc00
+
+/* Power domain wake-up dependency control register */
+#define PM_WKDEP_OFFSET			0xc8
+#define		EN_MDM			(1 << 5)
+#define		EN_WKUP			(1 << 4)
+#define		EN_GFX			(1 << 3)
+#define		EN_DSP			(1 << 2)
+#define		EN_MPU			(1 << 1)
+#define		EN_CORE			(1 << 0)
+
+/* Core power domain state transition control register */
+#define PM_PWSTCTRL_OFFSET		0xe0
+#define		FORCESTATE		(1 << 18)	/* Only for DSP & GFX */
+#define		MEM4RETSTATE		(1 << 6)
+#define		MEM3RETSTATE		(1 << 5)
+#define		MEM2RETSTATE		(1 << 4)
+#define		MEM1RETSTATE		(1 << 3)
+#define		LOGICRETSTATE		(1 << 2)	/* Logic is retained */
+#define		POWERSTATE_OFF		0x3
+#define		POWERSTATE_RETENTION	0x1
+#define		POWERSTATE_ON		0x0
+
+/* Power domain state register */
+#define PM_PWSTST_OFFSET		0xe4
+
+/* Hardware supervised state transition control register */
+#define CM_CLKSTCTRL_OFFSET		0x48
+#define		AUTOSTAT_MPU		(1 << 0)	/* MPU */
+#define		AUTOSTAT_DSS		(1 << 2)	/* Core */
+#define		AUTOSTAT_L4		(1 << 1)	/* Core */
+#define		AUTOSTAT_L3		(1 << 0)	/* Core */
+#define		AUTOSTAT_GFX		(1 << 0)	/* GFX */
+#define		AUTOSTAT_IVA		(1 << 8)	/* 2420 IVA in DSP domain */
+#define		AUTOSTAT_DSP		(1 << 0)	/* DSP */
+#define		AUTOSTAT_MDM		(1 << 0)	/* MDM */
+
+/* Automatic control of interface clock idling */
+#define CM_AUTOIDLE1_OFFSET		0x30
+#define CM_AUTOIDLE2_OFFSET		0x34		/* Core only */
+#define CM_AUTOIDLE3_OFFSET		0x38		/* Core only */
+#define CM_AUTOIDLE4_OFFSET		0x3c		/* Core only */
+#define		AUTO_54M(x)		(((x) & 0x3) << 6)
+#define		AUTO_96M(x)		(((x) & 0x3) << 2)
+#define		AUTO_DPLL(x)		(((x) & 0x3) << 0)
+#define		AUTO_STOPPED		0x3
+#define		AUTO_BYPASS_FAST	0x2		/* DPLL only */
+#define		AUTO_BYPASS_LOW_POWER	0x1		/* DPLL only */
+#define		AUTO_DISABLED		0x0
+
+/* Voltage control PRCM_VOLTCTRL bits */
+#define		AUTO_EXTVOLT		(1 << 15)
+#define		FORCE_EXTVOLT		(1 << 14)
+#define		SETOFF_LEVEL(x)		(((x) & 0x3) << 12)
+#define		MEMRETCTRL		(1 << 8)
+#define		SETRET_LEVEL(x)		(((x) & 0x3) << 6)
+#define		VOLT_LEVEL(x)		(((x) & 0x3) << 0)
+
+#define OMAP24XX_PRCM_VBASE	IO_ADDRESS(OMAP24XX_PRCM_BASE)
+#define prcm_readl(r)		__raw_readl(OMAP24XX_PRCM_VBASE + (r))
+#define prcm_writel(v, r)	__raw_writel((v), OMAP24XX_PRCM_VBASE + (r))
+
+static u32 pmdomain_get_wakeup_dependencies(int domain_offset)
+{
+	return prcm_readl(domain_offset + PM_WKDEP_OFFSET);
+}
+
+static void pmdomain_set_wakeup_dependencies(u32 state, int domain_offset)
+{
+	prcm_writel(state, domain_offset + PM_WKDEP_OFFSET);
+}
+
+static u32 pmdomain_get_powerstate(int domain_offset)
+{
+	return prcm_readl(domain_offset + PM_PWSTCTRL_OFFSET);
+}
+
+static void pmdomain_set_powerstate(u32 state, int domain_offset)
+{
+	prcm_writel(state, domain_offset + PM_PWSTCTRL_OFFSET);
+}
+
+static u32 pmdomain_get_clock_autocontrol(int domain_offset)
+{
+	return prcm_readl(domain_offset + CM_CLKSTCTRL_OFFSET);
+}
+
+static void pmdomain_set_clock_autocontrol(u32 state, int domain_offset)
+{
+	prcm_writel(state, domain_offset + CM_CLKSTCTRL_OFFSET);
+}
+
+static u32 pmdomain_get_clock_autoidle1(int domain_offset)
+{
+	return prcm_readl(domain_offset + CM_AUTOIDLE1_OFFSET);
+}
+
+/* Core domain only */
+static u32 pmdomain_get_clock_autoidle2(int domain_offset)
+{
+	return prcm_readl(domain_offset + CM_AUTOIDLE2_OFFSET);
+}
+
+/* Core domain only */
+static u32 pmdomain_get_clock_autoidle3(int domain_offset)
+{
+	return prcm_readl(domain_offset + CM_AUTOIDLE3_OFFSET);
+}
+
+/* Core domain only */
+static u32 pmdomain_get_clock_autoidle4(int domain_offset)
+{
+	return prcm_readl(domain_offset + CM_AUTOIDLE4_OFFSET);
+}
+
+static void pmdomain_set_clock_autoidle1(u32 state, int domain_offset)
+{
+	prcm_writel(state, CM_AUTOIDLE1_OFFSET + domain_offset);
+}
+
+/* Core domain only */
+static void pmdomain_set_clock_autoidle2(u32 state, int domain_offset)
+{
+	prcm_writel(state, CM_AUTOIDLE2_OFFSET + domain_offset);
+}
+
+/* Core domain only */
+static void pmdomain_set_clock_autoidle3(u32 state, int domain_offset)
+{
+	prcm_writel(state, CM_AUTOIDLE3_OFFSET + domain_offset);
+}
+
+/* Core domain only */
+static void pmdomain_set_clock_autoidle4(u32 state, int domain_offset)
+{
+	prcm_writel(state, CM_AUTOIDLE4_OFFSET + domain_offset);
+}
+
+/*
+ * Configures power management domains to idle clocks automatically.
+ */
+void pmdomain_set_autoidle(void)
+{
+	u32 val;
+
+	/* Set PLL auto stop for 54M, 96M & DPLL */
+	pmdomain_set_clock_autoidle1(AUTO_54M(AUTO_STOPPED) |
+				     AUTO_96M(AUTO_STOPPED) |
+				     AUTO_DPLL(AUTO_STOPPED), PM_PLL_OFFSET);
+
+	/* External clock input control
+	 * REVISIT: Should this be in clock framework?
+	 */
+	PRCM_CLKSRC_CTRL |= (0x3 << 3);
+
+	/* Configure number of 32KHz clock cycles for sys_clk */
+	PRCM_CLKSSETUP = 0x00ff;
+
+	/* Configure automatic voltage transition */
+	PRCM_VOLTSETUP = 0;
+	val = PRCM_VOLTCTRL;
+	val &= ~(SETOFF_LEVEL(0x3) | VOLT_LEVEL(0x3));
+	val |= SETOFF_LEVEL(1) | VOLT_LEVEL(1) | AUTO_EXTVOLT;
+	PRCM_VOLTCTRL = val;
+
+	/* Disable emulation tools functional clock */
+	PRCM_CLKEMUL_CTRL = 0x0;
+
+	/* Set core memory retention state */
+	val = pmdomain_get_powerstate(PM_CORE_OFFSET);
+	if (cpu_is_omap2420()) {
+		val &= ~(0x7 << 3);
+		val |= (MEM3RETSTATE | MEM2RETSTATE | MEM1RETSTATE);
+	} else {
+		val &= ~(0xf << 3);
+		val |= (MEM4RETSTATE | MEM3RETSTATE | MEM2RETSTATE |
+			MEM1RETSTATE);
+	}
+	pmdomain_set_powerstate(val, PM_CORE_OFFSET);
+
+	/* OCP interface smart idle. REVISIT: Enable autoidle bit0 ? */
+	val = SMS_SYSCONFIG;
+	val &= ~(0x3 << 3);
+	val |= (0x2 << 3) | (1 << 0);
+	SMS_SYSCONFIG |= val;
+
+	val = SDRC_SYSCONFIG;
+	val &= ~(0x3 << 3);
+	val |= (0x2 << 3);
+	SDRC_SYSCONFIG = val;
+
+	/* Configure L3 interface for smart idle.
+	 * REVISIT: Enable autoidle bit0 ?
+	 */
+	val = GPMC_SYSCONFIG;
+	val &= ~(0x3 << 3);
+	val |= (0x2 << 3) | (1 << 0);
+	GPMC_SYSCONFIG = val;
+
+	pmdomain_set_powerstate(LOGICRETSTATE | POWERSTATE_RETENTION,
+				PM_MPU_OFFSET);
+	pmdomain_set_powerstate(POWERSTATE_RETENTION, PM_CORE_OFFSET);
+	if (!cpu_is_omap2420())
+		pmdomain_set_powerstate(POWERSTATE_RETENTION, PM_MDM_OFFSET);
+
+	/* Assume suspend function has saved the state for DSP and GFX */
+	pmdomain_set_powerstate(FORCESTATE | POWERSTATE_OFF, PM_DSP_OFFSET);
+	pmdomain_set_powerstate(FORCESTATE | POWERSTATE_OFF, PM_GFX_OFFSET);
+
+#if 0
+	/* REVISIT: Internal USB needs special handling */
+	force_standby_usb();
+	if (cpu_is_omap2430())
+		force_hsmmc();
+	sdram_self_refresh_on_idle_req(1);
+#endif
+
+	/* Enable clock auto control for all domains.
+	 * Note that CORE domain includes also DSS, L4 & L3.
+	 */
+	pmdomain_set_clock_autocontrol(AUTOSTAT_MPU, PM_MPU_OFFSET);
+	pmdomain_set_clock_autocontrol(AUTOSTAT_GFX, PM_GFX_OFFSET);
+	pmdomain_set_clock_autocontrol(AUTOSTAT_DSS | AUTOSTAT_L4 | AUTOSTAT_L3,
+				       PM_CORE_OFFSET);
+	if (cpu_is_omap2420())
+		pmdomain_set_clock_autocontrol(AUTOSTAT_IVA | AUTOSTAT_DSP,
+					       PM_DSP_OFFSET);
+	else {
+		pmdomain_set_clock_autocontrol(AUTOSTAT_DSP, PM_DSP_OFFSET);
+		pmdomain_set_clock_autocontrol(AUTOSTAT_MDM, PM_MDM_OFFSET);
+	}
+
+	/* Enable clock autoidle for all domains */
+	pmdomain_set_clock_autoidle1(0x2, PM_DSP_OFFSET);
+	if (cpu_is_omap2420()) {
+		pmdomain_set_clock_autoidle1(0xfffffff9, PM_CORE_OFFSET);
+		pmdomain_set_clock_autoidle2(0x7, PM_CORE_OFFSET);
+		pmdomain_set_clock_autoidle1(0x3f, PM_WKUP_OFFSET);
+	} else {
+		pmdomain_set_clock_autoidle1(0xeafffff1, PM_CORE_OFFSET);
+		pmdomain_set_clock_autoidle2(0xfff, PM_CORE_OFFSET);
+		pmdomain_set_clock_autoidle1(0x7f, PM_WKUP_OFFSET);
+		pmdomain_set_clock_autoidle1(0x3, PM_MDM_OFFSET);
+	}
+	pmdomain_set_clock_autoidle3(0x7, PM_CORE_OFFSET);
+	pmdomain_set_clock_autoidle4(0x1f, PM_CORE_OFFSET);
+}
+
+/*
+ * Initializes power domains by removing wake-up dependencies and powering
+ * down DSP and GFX. Gets called from PM init. Note that DSP and IVA code
+ * must re-enable DSP and GFX when used.
+ */
+void __init pmdomain_init(void)
+{
+	/* Remove all domain wakeup dependencies */
+	pmdomain_set_wakeup_dependencies(EN_WKUP | EN_CORE, PM_MPU_OFFSET);
+	pmdomain_set_wakeup_dependencies(0, PM_DSP_OFFSET);
+	pmdomain_set_wakeup_dependencies(0, PM_GFX_OFFSET);
+	pmdomain_set_wakeup_dependencies(EN_WKUP | EN_MPU, PM_CORE_OFFSET);
+	if (cpu_is_omap2430())
+		pmdomain_set_wakeup_dependencies(0, PM_MDM_OFFSET);
+
+	/* Power down DSP and GFX */
+	pmdomain_set_powerstate(POWERSTATE_OFF | FORCESTATE, PM_DSP_OFFSET);
+	pmdomain_set_powerstate(POWERSTATE_OFF | FORCESTATE, PM_GFX_OFFSET);
+}
diff --git a/arch/arm/mach-pnx4008/Makefile b/arch/arm/mach-pnx4008/Makefile
new file mode 100644
index 000000000..b457ca0a4
--- /dev/null
+++ b/arch/arm/mach-pnx4008/Makefile
@@ -0,0 +1,12 @@
+#
+# Makefile for the linux kernel.
+#
+
+obj-y			:= core.o irq.o time.o clock.o gpio.o serial.o dma.o
+obj-m			:=
+obj-n			:=
+obj-			:=
+
+# Power Management
+obj-$(CONFIG_PM) += pm.o sleep.o
+
diff --git a/arch/arm/mach-pnx4008/Makefile.boot b/arch/arm/mach-pnx4008/Makefile.boot
new file mode 100644
index 000000000..44c7117e2
--- /dev/null
+++ b/arch/arm/mach-pnx4008/Makefile.boot
@@ -0,0 +1,4 @@
+   zreladdr-y		:= 0x80008000
+params_phys-y		:= 0x80000100
+initrd_phys-y		:= 0x80800000
+
diff --git a/arch/arm/mach-pnx4008/clock.c b/arch/arm/mach-pnx4008/clock.c
new file mode 100644
index 000000000..f582ed2ec
--- /dev/null
+++ b/arch/arm/mach-pnx4008/clock.c
@@ -0,0 +1,983 @@
+/*
+ * arch/arm/mach-pnx4008/clock.c
+ *
+ * Clock control driver for PNX4008
+ *
+ * Authors: Vitaly Wool, Dmitry Chigirev <source@mvista.com>
+ * Generic clock management functions are partially based on:
+ *  linux/arch/arm/mach-omap/clock.c
+ *
+ * 2005-2006 (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.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/errno.h>
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/delay.h>
+
+#include <asm/semaphore.h>
+#include <asm/hardware.h>
+#include <asm/io.h>
+
+#include <asm/arch/clock.h>
+#include "clock.h"
+
+/*forward declaration*/
+static struct clk per_ck;
+static struct clk hclk_ck;
+static struct clk ck_1MHz;
+static struct clk ck_13MHz;
+static struct clk ck_pll1;
+static int local_set_rate(struct clk *clk, u32 rate);
+
+static inline void clock_lock(void)
+{
+	local_irq_disable();
+}
+
+static inline void clock_unlock(void)
+{
+	local_irq_enable();
+}
+
+static void propagate_rate(struct clk *clk)
+{
+	struct clk *tmp_clk;
+
+	tmp_clk = clk;
+	while (tmp_clk->propagate_next) {
+		tmp_clk = tmp_clk->propagate_next;
+		local_set_rate(tmp_clk, tmp_clk->user_rate);
+	}
+}
+
+static inline void clk_reg_disable(struct clk *clk)
+{
+	if (clk->enable_reg)
+		__raw_writel(__raw_readl(clk->enable_reg) &
+			     ~(1 << clk->enable_shift), clk->enable_reg);
+}
+
+static inline void clk_reg_enable(struct clk *clk)
+{
+	if (clk->enable_reg)
+		__raw_writel(__raw_readl(clk->enable_reg) |
+			     (1 << clk->enable_shift), clk->enable_reg);
+}
+
+static inline void clk_reg_disable1(struct clk *clk)
+{
+	if (clk->enable_reg1)
+		__raw_writel(__raw_readl(clk->enable_reg1) &
+			     ~(1 << clk->enable_shift1), clk->enable_reg1);
+}
+
+static inline void clk_reg_enable1(struct clk *clk)
+{
+	if (clk->enable_reg1)
+		__raw_writel(__raw_readl(clk->enable_reg1) |
+			     (1 << clk->enable_shift1), clk->enable_reg1);
+}
+
+static int clk_wait_for_pll_lock(struct clk *clk)
+{
+	int i;
+	i = 0;
+	while (i++ < 0xFFF && !(__raw_readl(clk->scale_reg) & 1)) ;	/*wait for PLL to lock */
+
+	if (!(__raw_readl(clk->scale_reg) & 1)) {
+		printk(KERN_ERR
+		       "%s ERROR: failed to lock, scale reg data: %x\n",
+		       clk->name, __raw_readl(clk->scale_reg));
+		return -1;
+	}
+	return 0;
+}
+
+static int switch_to_dirty_13mhz(struct clk *clk)
+{
+	int i;
+	int ret;
+	u32 tmp_reg;
+
+	ret = 0;
+
+	if (!clk->rate)
+		clk_reg_enable1(clk);
+
+	tmp_reg = __raw_readl(clk->parent_switch_reg);
+	/*if 13Mhz clock selected, select 13'MHz (dirty) source from OSC */
+	if (!(tmp_reg & 1)) {
+		tmp_reg |= (1 << 1);	/* Trigger switch to 13'MHz (dirty) clock */
+		__raw_writel(tmp_reg, clk->parent_switch_reg);
+		i = 0;
+		while (i++ < 0xFFF && !(__raw_readl(clk->parent_switch_reg) & 1)) ;	/*wait for 13'MHz selection status */
+
+		if (!(__raw_readl(clk->parent_switch_reg) & 1)) {
+			printk(KERN_ERR
+			       "%s ERROR: failed to select 13'MHz, parent sw reg data: %x\n",
+			       clk->name, __raw_readl(clk->parent_switch_reg));
+			ret = -1;
+		}
+	}
+
+	if (!clk->rate)
+		clk_reg_disable1(clk);
+
+	return ret;
+}
+
+static int switch_to_clean_13mhz(struct clk *clk)
+{
+	int i;
+	int ret;
+	u32 tmp_reg;
+
+	ret = 0;
+
+	if (!clk->rate)
+		clk_reg_enable1(clk);
+
+	tmp_reg = __raw_readl(clk->parent_switch_reg);
+	/*if 13'Mhz clock selected, select 13MHz (clean) source from OSC */
+	if (tmp_reg & 1) {
+		tmp_reg &= ~(1 << 1);	/* Trigger switch to 13MHz (clean) clock */
+		__raw_writel(tmp_reg, clk->parent_switch_reg);
+		i = 0;
+		while (i++ < 0xFFF && (__raw_readl(clk->parent_switch_reg) & 1)) ;	/*wait for 13MHz selection status */
+
+		if (__raw_readl(clk->parent_switch_reg) & 1) {
+			printk(KERN_ERR
+			       "%s ERROR: failed to select 13MHz, parent sw reg data: %x\n",
+			       clk->name, __raw_readl(clk->parent_switch_reg));
+			ret = -1;
+		}
+	}
+
+	if (!clk->rate)
+		clk_reg_disable1(clk);
+
+	return ret;
+}
+
+static int set_13MHz_parent(struct clk *clk, struct clk *parent)
+{
+	int ret = -EINVAL;
+
+	if (parent == &ck_13MHz)
+		ret = switch_to_clean_13mhz(clk);
+	else if (parent == &ck_pll1)
+		ret = switch_to_dirty_13mhz(clk);
+
+	return ret;
+}
+
+#define PLL160_MIN_FCCO 156000
+#define PLL160_MAX_FCCO 320000
+
+/*
+ * Calculate pll160 settings.
+ * Possible input: up to 320MHz with step of clk->parent->rate.
+ * In PNX4008 parent rate for pll160s may be either 1 or 13MHz.
+ * Ignored paths: "feedback" (bit 13 set), "div-by-N".
+ * Setting ARM PLL4 rate to 0 will put CPU into direct run mode.
+ * Setting PLL5 and PLL3 rate to 0 will disable USB and DSP clock input.
+ * Please refer to PNX4008 IC manual for details.
+ */
+
+static int pll160_set_rate(struct clk *clk, u32 rate)
+{
+	u32 tmp_reg, tmp_m, tmp_2p, i;
+	u32 parent_rate;
+	int ret = -EINVAL;
+
+	parent_rate = clk->parent->rate;
+
+	if (!parent_rate)
+		goto out;
+
+	/* set direct run for ARM or disable output for others  */
+	clk_reg_disable(clk);
+
+	/* disable source input as well (ignored for ARM) */
+	clk_reg_disable1(clk);
+
+	tmp_reg = __raw_readl(clk->scale_reg);
+	tmp_reg &= ~0x1ffff;	/*clear all settings, power down */
+	__raw_writel(tmp_reg, clk->scale_reg);
+
+	rate -= rate % parent_rate;	/*round down the input */
+
+	if (rate > PLL160_MAX_FCCO)
+		rate = PLL160_MAX_FCCO;
+
+	if (!rate) {
+		clk->rate = 0;
+		ret = 0;
+		goto out;
+	}
+
+	clk_reg_enable1(clk);
+	tmp_reg = __raw_readl(clk->scale_reg);
+
+	if (rate == parent_rate) {
+		/*enter direct bypass mode */
+		tmp_reg |= ((1 << 14) | (1 << 15));
+		__raw_writel(tmp_reg, clk->scale_reg);
+		clk->rate = parent_rate;
+		clk_reg_enable(clk);
+		ret = 0;
+		goto out;
+	}
+
+	i = 0;
+	for (tmp_2p = 1; tmp_2p < 16; tmp_2p <<= 1) {
+		if (rate * tmp_2p >= PLL160_MIN_FCCO)
+			break;
+		i++;
+	}
+
+	if (tmp_2p > 1)
+		tmp_reg |= ((i - 1) << 11);
+	else
+		tmp_reg |= (1 << 14);	/*direct mode, no divide */
+
+	tmp_m = rate * tmp_2p;
+	tmp_m /= parent_rate;
+
+	tmp_reg |= (tmp_m - 1) << 1;	/*calculate M */
+	tmp_reg |= (1 << 16);	/*power up PLL */
+	__raw_writel(tmp_reg, clk->scale_reg);
+
+	if (clk_wait_for_pll_lock(clk) < 0) {
+		clk_reg_disable(clk);
+		clk_reg_disable1(clk);
+
+		tmp_reg = __raw_readl(clk->scale_reg);
+		tmp_reg &= ~0x1ffff;	/*clear all settings, power down */
+		__raw_writel(tmp_reg, clk->scale_reg);
+		clk->rate = 0;
+		ret = -EFAULT;
+		goto out;
+	}
+
+	clk->rate = (tmp_m * parent_rate) / tmp_2p;
+
+	if (clk->flags & RATE_PROPAGATES)
+		propagate_rate(clk);
+
+	clk_reg_enable(clk);
+	ret = 0;
+
+out:
+	return ret;
+}
+
+/*configure PER_CLK*/
+static int per_clk_set_rate(struct clk *clk, u32 rate)
+{
+	u32 tmp;
+
+	tmp = __raw_readl(clk->scale_reg);
+	tmp &= ~(0x1f << 2);
+	tmp |= ((clk->parent->rate / clk->rate) - 1) << 2;
+	__raw_writel(tmp, clk->scale_reg);
+	clk->rate = rate;
+	return 0;
+}
+
+/*configure HCLK*/
+static int hclk_set_rate(struct clk *clk, u32 rate)
+{
+	u32 tmp;
+	tmp = __raw_readl(clk->scale_reg);
+	tmp = tmp & ~0x3;
+	switch (rate) {
+	case 1:
+		break;
+	case 2:
+		tmp |= 1;
+		break;
+	case 4:
+		tmp |= 2;
+		break;
+	}
+
+	__raw_writel(tmp, clk->scale_reg);
+	clk->rate = rate;
+	return 0;
+}
+
+static u32 hclk_round_rate(struct clk *clk, u32 rate)
+{
+	switch (rate) {
+	case 1:
+	case 4:
+		return rate;
+	}
+	return 2;
+}
+
+static u32 per_clk_round_rate(struct clk *clk, u32 rate)
+{
+	return CLK_RATE_13MHZ;
+}
+
+static int on_off_set_rate(struct clk *clk, u32 rate)
+{
+	if (rate) {
+		clk_reg_enable(clk);
+		clk->rate = 1;
+	} else {
+		clk_reg_disable(clk);
+		clk->rate = 0;
+	}
+	return 0;
+}
+
+static int on_off_inv_set_rate(struct clk *clk, u32 rate)
+{
+	if (rate) {
+		clk_reg_disable(clk);	/*enable bit is inverted */
+		clk->rate = 1;
+	} else {
+		clk_reg_enable(clk);
+		clk->rate = 0;
+	}
+	return 0;
+}
+
+static u32 on_off_round_rate(struct clk *clk, u32 rate)
+{
+	return (rate ? 1 : 0);
+}
+
+static u32 pll4_round_rate(struct clk *clk, u32 rate)
+{
+	if (rate > CLK_RATE_208MHZ)
+		rate = CLK_RATE_208MHZ;
+	if (rate == CLK_RATE_208MHZ && hclk_ck.user_rate == 1)
+		rate = CLK_RATE_208MHZ - CLK_RATE_13MHZ;
+	return (rate - (rate % (hclk_ck.user_rate * CLK_RATE_13MHZ)));
+}
+
+static u32 pll3_round_rate(struct clk *clk, u32 rate)
+{
+	if (rate > CLK_RATE_208MHZ)
+		rate = CLK_RATE_208MHZ;
+	return (rate - rate % CLK_RATE_13MHZ);
+}
+
+static u32 pll5_round_rate(struct clk *clk, u32 rate)
+{
+	return (rate ? CLK_RATE_48MHZ : 0);
+}
+
+static u32 ck_13MHz_round_rate(struct clk *clk, u32 rate)
+{
+	return (rate ? CLK_RATE_13MHZ : 0);
+}
+
+static int ck_13MHz_set_rate(struct clk *clk, u32 rate)
+{
+	if (rate) {
+		clk_reg_disable(clk);	/*enable bit is inverted */
+		udelay(500);
+		clk->rate = CLK_RATE_13MHZ;
+		ck_1MHz.rate = CLK_RATE_1MHZ;
+	} else {
+		clk_reg_enable(clk);
+		clk->rate = 0;
+		ck_1MHz.rate = 0;
+	}
+	return 0;
+}
+
+static int pll1_set_rate(struct clk *clk, u32 rate)
+{
+#if 0 /* doesn't work on some boards, probably a HW BUG */
+	if (rate) {
+		clk_reg_disable(clk);	/*enable bit is inverted */
+		if (!clk_wait_for_pll_lock(clk)) {
+			clk->rate = CLK_RATE_13MHZ;
+		} else {
+			clk_reg_enable(clk);
+			clk->rate = 0;
+		}
+
+	} else {
+		clk_reg_enable(clk);
+		clk->rate = 0;
+	}
+#endif
+	return 0;
+}
+
+/* Clock sources */
+
+static struct clk osc_13MHz = {
+	.name = "osc_13MHz",
+	.flags = FIXED_RATE,
+	.rate = CLK_RATE_13MHZ,
+};
+
+static struct clk ck_13MHz = {
+	.name = "ck_13MHz",
+	.parent = &osc_13MHz,
+	.flags = NEEDS_INITIALIZATION,
+	.round_rate = &ck_13MHz_round_rate,
+	.set_rate = &ck_13MHz_set_rate,
+	.enable_reg = OSC13CTRL_REG,
+	.enable_shift = 0,
+	.rate = CLK_RATE_13MHZ,
+};
+
+static struct clk osc_32KHz = {
+	.name = "osc_32KHz",
+	.flags = FIXED_RATE,
+	.rate = CLK_RATE_32KHZ,
+};
+
+/*attached to PLL5*/
+static struct clk ck_1MHz = {
+	.name = "ck_1MHz",
+	.flags = FIXED_RATE | PARENT_SET_RATE,
+	.parent = &ck_13MHz,
+};
+
+/* PLL1 (397) - provides 13' MHz clock */
+static struct clk ck_pll1 = {
+	.name = "ck_pll1",
+	.parent = &osc_32KHz,
+	.flags = NEEDS_INITIALIZATION,
+	.round_rate = &ck_13MHz_round_rate,
+	.set_rate = &pll1_set_rate,
+	.enable_reg = PLLCTRL_REG,
+	.enable_shift = 1,
+	.scale_reg = PLLCTRL_REG,
+	.rate = CLK_RATE_13MHZ,
+};
+
+/* CPU/Bus PLL */
+static struct clk ck_pll4 = {
+	.name = "ck_pll4",
+	.parent = &ck_pll1,
+	.flags = RATE_PROPAGATES | NEEDS_INITIALIZATION,
+	.propagate_next = &per_ck,
+	.round_rate = &pll4_round_rate,
+	.set_rate = &pll160_set_rate,
+	.rate = CLK_RATE_208MHZ,
+	.scale_reg = HCLKPLLCTRL_REG,
+	.enable_reg = PWRCTRL_REG,
+	.enable_shift = 2,
+	.parent_switch_reg = SYSCLKCTRL_REG,
+	.set_parent = &set_13MHz_parent,
+};
+
+/* USB PLL */
+static struct clk ck_pll5 = {
+	.name = "ck_pll5",
+	.parent = &ck_1MHz,
+	.flags = NEEDS_INITIALIZATION,
+	.round_rate = &pll5_round_rate,
+	.set_rate = &pll160_set_rate,
+	.scale_reg = USBCTRL_REG,
+	.enable_reg = USBCTRL_REG,
+	.enable_shift = 18,
+	.enable_reg1 = USBCTRL_REG,
+	.enable_shift1 = 17,
+};
+
+/* XPERTTeak DSP PLL */
+static struct clk ck_pll3 = {
+	.name = "ck_pll3",
+	.parent = &ck_pll1,
+	.flags = NEEDS_INITIALIZATION,
+	.round_rate = &pll3_round_rate,
+	.set_rate = &pll160_set_rate,
+	.scale_reg = DSPPLLCTRL_REG,
+	.enable_reg = DSPCLKCTRL_REG,
+	.enable_shift = 3,
+	.enable_reg1 = DSPCLKCTRL_REG,
+	.enable_shift1 = 2,
+	.parent_switch_reg = DSPCLKCTRL_REG,
+	.set_parent = &set_13MHz_parent,
+};
+
+static struct clk hclk_ck = {
+	.name = "hclk_ck",
+	.parent = &ck_pll4,
+	.flags = PARENT_SET_RATE,
+	.set_rate = &hclk_set_rate,
+	.round_rate = &hclk_round_rate,
+	.scale_reg = HCLKDIVCTRL_REG,
+	.rate = 2,
+	.user_rate = 2,
+};
+
+static struct clk per_ck = {
+	.name = "per_ck",
+	.parent = &ck_pll4,
+	.flags = FIXED_RATE,
+	.propagate_next = &hclk_ck,
+	.set_rate = &per_clk_set_rate,
+	.round_rate = &per_clk_round_rate,
+	.scale_reg = HCLKDIVCTRL_REG,
+	.rate = CLK_RATE_13MHZ,
+	.user_rate = CLK_RATE_13MHZ,
+};
+
+static struct clk m2hclk_ck = {
+	.name = "m2hclk_ck",
+	.parent = &hclk_ck,
+	.flags = NEEDS_INITIALIZATION,
+	.round_rate = &on_off_round_rate,
+	.set_rate = &on_off_inv_set_rate,
+	.rate = 1,
+	.enable_shift = 6,
+	.enable_reg = PWRCTRL_REG,
+};
+
+static struct clk vfp9_ck = {
+	.name = "vfp9_ck",
+	.parent = &ck_pll4,
+	.flags = NEEDS_INITIALIZATION,
+	.round_rate = &on_off_round_rate,
+	.set_rate = &on_off_set_rate,
+	.rate = 1,
+	.enable_shift = 4,
+	.enable_reg = VFP9CLKCTRL_REG,
+};
+
+static struct clk keyscan_ck = {
+	.name = "keyscan_ck",
+	.parent = &osc_32KHz,
+	.flags = NEEDS_INITIALIZATION,
+	.round_rate = &on_off_round_rate,
+	.set_rate = &on_off_set_rate,
+	.enable_shift = 0,
+	.enable_reg = KEYCLKCTRL_REG,
+};
+
+static struct clk touch_ck = {
+	.name = "touch_ck",
+	.parent = &osc_32KHz,
+	.flags = NEEDS_INITIALIZATION,
+	.round_rate = &on_off_round_rate,
+	.set_rate = &on_off_set_rate,
+	.enable_shift = 0,
+	.enable_reg = TSCLKCTRL_REG,
+};
+
+static struct clk pwm1_ck = {
+	.name = "pwm1_ck",
+	.parent = &osc_32KHz,
+	.flags = NEEDS_INITIALIZATION,
+	.round_rate = &on_off_round_rate,
+	.set_rate = &on_off_set_rate,
+	.enable_shift = 0,
+	.enable_reg = PWMCLKCTRL_REG,
+};
+
+static struct clk pwm2_ck = {
+	.name = "pwm2_ck",
+	.parent = &osc_32KHz,
+	.flags = NEEDS_INITIALIZATION,
+	.round_rate = &on_off_round_rate,
+	.set_rate = &on_off_set_rate,
+	.enable_shift = 2,
+	.enable_reg = PWMCLKCTRL_REG,
+};
+
+static struct clk jpeg_ck = {
+	.name = "jpeg_ck",
+	.parent = &hclk_ck,
+	.flags = NEEDS_INITIALIZATION,
+	.round_rate = &on_off_round_rate,
+	.set_rate = &on_off_set_rate,
+	.enable_shift = 0,
+	.enable_reg = JPEGCLKCTRL_REG,
+};
+
+static struct clk ms_ck = {
+	.name = "ms_ck",
+	.parent = &ck_pll4,
+	.flags = NEEDS_INITIALIZATION,
+	.round_rate = &on_off_round_rate,
+	.set_rate = &on_off_set_rate,
+	.enable_shift = 5,
+	.enable_reg = MSCTRL_REG,
+};
+
+static struct clk dum_ck = {
+	.name = "dum_ck",
+	.parent = &hclk_ck,
+	.flags = NEEDS_INITIALIZATION,
+	.round_rate = &on_off_round_rate,
+	.set_rate = &on_off_set_rate,
+	.enable_shift = 0,
+	.enable_reg = DUMCLKCTRL_REG,
+};
+
+static struct clk flash_ck = {
+	.name = "flash_ck",
+	.parent = &hclk_ck,
+	.round_rate = &on_off_round_rate,
+	.set_rate = &on_off_set_rate,
+	.enable_shift = 1,	/* Only MLC clock supported */
+	.enable_reg = FLASHCLKCTRL_REG,
+};
+
+static struct clk i2c0_ck = {
+	.name = "i2c0_ck",
+	.parent = &per_ck,
+	.flags = NEEDS_INITIALIZATION,
+	.round_rate = &on_off_round_rate,
+	.set_rate = &on_off_set_rate,
+	.enable_shift = 0,
+	.enable_reg = I2CCLKCTRL_REG,
+};
+
+static struct clk i2c1_ck = {
+	.name = "i2c1_ck",
+	.parent = &per_ck,
+	.flags = NEEDS_INITIALIZATION,
+	.round_rate = &on_off_round_rate,
+	.set_rate = &on_off_set_rate,
+	.enable_shift = 1,
+	.enable_reg = I2CCLKCTRL_REG,
+};
+
+static struct clk i2c2_ck = {
+	.name = "i2c2_ck",
+	.parent = &per_ck,
+	.flags = NEEDS_INITIALIZATION,
+	.round_rate = &on_off_round_rate,
+	.set_rate = &on_off_set_rate,
+	.enable_shift = 2,
+	.enable_reg = USB_OTG_CLKCTRL_REG,
+};
+
+static struct clk spi0_ck = {
+	.name = "spi0_ck",
+	.parent = &hclk_ck,
+	.flags = NEEDS_INITIALIZATION,
+	.round_rate = &on_off_round_rate,
+	.set_rate = &on_off_set_rate,
+	.enable_shift = 0,
+	.enable_reg = SPICTRL_REG,
+};
+
+static struct clk spi1_ck = {
+	.name = "spi1_ck",
+	.parent = &hclk_ck,
+	.flags = NEEDS_INITIALIZATION,
+	.round_rate = &on_off_round_rate,
+	.set_rate = &on_off_set_rate,
+	.enable_shift = 4,
+	.enable_reg = SPICTRL_REG,
+};
+
+static struct clk dma_ck = {
+	.name = "dma_ck",
+	.parent = &hclk_ck,
+	.round_rate = &on_off_round_rate,
+	.set_rate = &on_off_set_rate,
+	.enable_shift = 0,
+	.enable_reg = DMACLKCTRL_REG,
+};
+
+static struct clk uart3_ck = {
+	.name = "uart3_ck",
+	.parent = &per_ck,
+	.flags = NEEDS_INITIALIZATION,
+	.round_rate = &on_off_round_rate,
+	.set_rate = &on_off_set_rate,
+	.rate = 1,
+	.enable_shift = 0,
+	.enable_reg = UARTCLKCTRL_REG,
+};
+
+static struct clk uart4_ck = {
+	.name = "uart4_ck",
+	.parent = &per_ck,
+	.flags = NEEDS_INITIALIZATION,
+	.round_rate = &on_off_round_rate,
+	.set_rate = &on_off_set_rate,
+	.enable_shift = 1,
+	.enable_reg = UARTCLKCTRL_REG,
+};
+
+static struct clk uart5_ck = {
+	.name = "uart5_ck",
+	.parent = &per_ck,
+	.flags = NEEDS_INITIALIZATION,
+	.round_rate = &on_off_round_rate,
+	.set_rate = &on_off_set_rate,
+	.rate = 1,
+	.enable_shift = 2,
+	.enable_reg = UARTCLKCTRL_REG,
+};
+
+static struct clk uart6_ck = {
+	.name = "uart6_ck",
+	.parent = &per_ck,
+	.flags = NEEDS_INITIALIZATION,
+	.round_rate = &on_off_round_rate,
+	.set_rate = &on_off_set_rate,
+	.enable_shift = 3,
+	.enable_reg = UARTCLKCTRL_REG,
+};
+
+/* These clocks are visible outside this module
+ * and can be initialized
+ */
+static struct clk *onchip_clks[] = {
+	&ck_13MHz,
+	&ck_pll1,
+	&ck_pll4,
+	&ck_pll5,
+	&ck_pll3,
+	&vfp9_ck,
+	&m2hclk_ck,
+	&hclk_ck,
+	&dma_ck,
+	&flash_ck,
+	&dum_ck,
+	&keyscan_ck,
+	&pwm1_ck,
+	&pwm2_ck,
+	&jpeg_ck,
+	&ms_ck,
+	&touch_ck,
+	&i2c0_ck,
+	&i2c1_ck,
+	&i2c2_ck,
+	&spi0_ck,
+	&spi1_ck,
+	&uart3_ck,
+	&uart4_ck,
+	&uart5_ck,
+	&uart6_ck,
+};
+
+static int local_clk_enable(struct clk *clk)
+{
+	int ret = 0;
+
+	if (!(clk->flags & FIXED_RATE) && !clk->rate && clk->set_rate
+	    && clk->user_rate)
+		ret = clk->set_rate(clk, clk->user_rate);
+	return ret;
+}
+
+static void local_clk_disable(struct clk *clk)
+{
+	if (!(clk->flags & FIXED_RATE) && clk->rate && clk->set_rate)
+		clk->set_rate(clk, 0);
+}
+
+static void local_clk_unuse(struct clk *clk)
+{
+	if (clk->usecount > 0 && !(--clk->usecount)) {
+		local_clk_disable(clk);
+		if (clk->parent)
+			local_clk_unuse(clk->parent);
+	}
+}
+
+static int local_clk_use(struct clk *clk)
+{
+	int ret = 0;
+	if (clk->usecount++ == 0) {
+		if (clk->parent)
+			ret = local_clk_use(clk->parent);
+
+		if (ret != 0) {
+			clk->usecount--;
+			goto out;
+		}
+
+		ret = local_clk_enable(clk);
+
+		if (ret != 0 && clk->parent) {
+			local_clk_unuse(clk->parent);
+			clk->usecount--;
+		}
+	}
+out:
+	return ret;
+}
+
+static int local_set_rate(struct clk *clk, u32 rate)
+{
+	int ret = -EINVAL;
+	if (clk->set_rate) {
+
+		if (clk->user_rate == clk->rate && clk->parent->rate) {
+			/* if clock enabled or rate not set */
+			clk->user_rate = clk->round_rate(clk, rate);
+			ret = clk->set_rate(clk, clk->user_rate);
+		} else
+			clk->user_rate = clk->round_rate(clk, rate);
+		ret = 0;
+	}
+	return ret;
+}
+
+int clk_set_rate(struct clk *clk, unsigned long rate)
+{
+	int ret = -EINVAL;
+
+	if (clk->flags & FIXED_RATE)
+		goto out;
+
+	clock_lock();
+	if ((clk->flags & PARENT_SET_RATE) && clk->parent) {
+
+		clk->user_rate = clk->round_rate(clk, rate);
+		/* parent clock needs to be refreshed
+		   for the setting to take effect */
+	} else {
+		ret = local_set_rate(clk, rate);
+	}
+	ret = 0;
+	clock_unlock();
+
+out:
+	return ret;
+}
+
+EXPORT_SYMBOL(clk_set_rate);
+
+struct clk *clk_get(struct device *dev, const char *id)
+{
+	struct clk *clk = ERR_PTR(-ENOENT);
+	struct clk **clkp;
+
+	clock_lock();
+	for (clkp = onchip_clks; clkp < onchip_clks + ARRAY_SIZE(onchip_clks);
+	     clkp++) {
+		if (strcmp(id, (*clkp)->name) == 0
+		    && try_module_get((*clkp)->owner)) {
+			clk = (*clkp);
+			break;
+		}
+	}
+	clock_unlock();
+
+	return clk;
+}
+EXPORT_SYMBOL(clk_get);
+
+void clk_put(struct clk *clk)
+{
+	clock_lock();
+	if (clk && !IS_ERR(clk))
+		module_put(clk->owner);
+	clock_unlock();
+}
+EXPORT_SYMBOL(clk_put);
+
+unsigned long clk_get_rate(struct clk *clk)
+{
+	unsigned long ret;
+	clock_lock();
+	ret = clk->rate;
+	clock_unlock();
+	return ret;
+}
+EXPORT_SYMBOL(clk_get_rate);
+
+int clk_enable(struct clk *clk)
+{
+	int ret = 0;
+
+	clock_lock();
+	ret = local_clk_use(clk);
+	clock_unlock();
+	return ret;
+}
+
+EXPORT_SYMBOL(clk_enable);
+
+void clk_disable(struct clk *clk)
+{
+	clock_lock();
+	local_clk_unuse(clk);
+	clock_unlock();
+}
+
+EXPORT_SYMBOL(clk_disable);
+
+long clk_round_rate(struct clk *clk, unsigned long rate)
+{
+	long ret;
+	clock_lock();
+	if (clk->round_rate)
+		ret = clk->round_rate(clk, rate);
+	else
+		ret = clk->rate;
+	clock_unlock();
+	return ret;
+}
+
+EXPORT_SYMBOL(clk_round_rate);
+
+int clk_set_parent(struct clk *clk, struct clk *parent)
+{
+	int ret = -ENODEV;
+	if (!clk->set_parent)
+		goto out;
+
+	clock_lock();
+	ret = clk->set_parent(clk, parent);
+	if (!ret)
+		clk->parent = parent;
+	clock_unlock();
+
+out:
+	return ret;
+}
+
+EXPORT_SYMBOL(clk_set_parent);
+
+static int __init clk_init(void)
+{
+	struct clk **clkp;
+
+	/* Disable autoclocking, as it doesn't seem to work */
+	__raw_writel(0xff, AUTOCLK_CTRL);
+
+	for (clkp = onchip_clks; clkp < onchip_clks + ARRAY_SIZE(onchip_clks);
+	     clkp++) {
+		if (((*clkp)->flags & NEEDS_INITIALIZATION)
+		    && ((*clkp)->set_rate)) {
+			(*clkp)->user_rate = (*clkp)->rate;
+			local_set_rate((*clkp), (*clkp)->user_rate);
+			if ((*clkp)->set_parent)
+				(*clkp)->set_parent((*clkp), (*clkp)->parent);
+		}
+		pr_debug("%s: clock %s, rate %ld\n",
+			__FUNCTION__, (*clkp)->name, (*clkp)->rate);
+	}
+
+	local_clk_use(&ck_pll4);
+
+	/* if ck_13MHz is not used, disable it. */
+	if (ck_13MHz.usecount == 0)
+		local_clk_disable(&ck_13MHz);
+
+	/* Disable autoclocking */
+	__raw_writeb(0xff, AUTOCLK_CTRL);
+
+	return 0;
+}
+
+arch_initcall(clk_init);
diff --git a/arch/arm/mach-pnx4008/clock.h b/arch/arm/mach-pnx4008/clock.h
new file mode 100644
index 000000000..cd58f372c
--- /dev/null
+++ b/arch/arm/mach-pnx4008/clock.h
@@ -0,0 +1,43 @@
+/*
+ * arch/arm/mach-pnx4008/clock.h
+ *
+ * Clock control driver for PNX4008 - internal header file
+ *
+ * Author: Vitaly Wool <source@mvista.com>
+ *
+ * 2006 (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 __ARCH_ARM_PNX4008_CLOCK_H__
+#define __ARCH_ARM_PNX4008_CLOCK_H__
+
+struct clk {
+	struct list_head node;
+	struct module *owner;
+	const char *name;
+	struct clk *parent;
+	struct clk *propagate_next;
+	u32 rate;
+	u32 user_rate;
+	s8 usecount;
+	u32 flags;
+	u32 scale_reg;
+	u8 enable_shift;
+	u32 enable_reg;
+	u8 enable_shift1;
+	u32 enable_reg1;
+	u32 parent_switch_reg;
+	 u32(*round_rate) (struct clk *, u32);
+	int (*set_rate) (struct clk *, u32);
+	int (*set_parent) (struct clk * clk, struct clk * parent);
+};
+
+/* Flags */
+#define RATE_PROPAGATES      (1<<0)
+#define NEEDS_INITIALIZATION (1<<1)
+#define PARENT_SET_RATE      (1<<2)
+#define FIXED_RATE           (1<<3)
+
+#endif
diff --git a/arch/arm/mach-pnx4008/core.c b/arch/arm/mach-pnx4008/core.c
new file mode 100644
index 000000000..3d73c1e93
--- /dev/null
+++ b/arch/arm/mach-pnx4008/core.c
@@ -0,0 +1,205 @@
+/*
+ * arch/arm/mach-pnx4008/core.c
+ *
+ * PNX4008 core startup code
+ *
+ * Authors: Vitaly Wool, Dmitry Chigirev,
+ * Grigory Tolstolytkin, Dmitry Pervushin <source@mvista.com>
+ *
+ * Based on reference code received from Philips:
+ * Copyright (C) 2003 Philips Semiconductors
+ *
+ * 2005 (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.
+ */
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/mm.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <linux/serial_8250.h>
+#include <linux/device.h>
+#include <linux/spi/spi.h>
+
+#include <asm/hardware.h>
+#include <asm/io.h>
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+#include <asm/pgtable.h>
+#include <asm/page.h>
+#include <asm/system.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/time.h>
+
+#include <asm/arch/irq.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/dma.h>
+
+struct resource spipnx_0_resources[] = {
+	{
+		.start = PNX4008_SPI1_BASE,
+		.end = PNX4008_SPI1_BASE + SZ_4K,
+		.flags = IORESOURCE_MEM,
+	}, {
+		.start = PER_SPI1_REC_XMIT,
+		.flags = IORESOURCE_DMA,
+	}, {
+		.start = SPI1_INT,
+		.flags = IORESOURCE_IRQ,
+	}, {
+		.flags = 0,
+	},
+};
+
+struct resource spipnx_1_resources[] = {
+	{
+		.start = PNX4008_SPI2_BASE,
+		.end = PNX4008_SPI2_BASE + SZ_4K,
+		.flags = IORESOURCE_MEM,
+	}, {
+		.start = PER_SPI2_REC_XMIT,
+		.flags = IORESOURCE_DMA,
+	}, {
+		.start = SPI2_INT,
+		.flags = IORESOURCE_IRQ,
+	}, {
+		.flags = 0,
+	}
+};
+
+static struct spi_board_info spi_board_info[] __initdata = {
+	{
+		.modalias	= "m25p80",
+		.max_speed_hz	= 1000000,
+		.bus_num	= 1,
+		.chip_select	= 0,
+	},
+};
+
+static struct platform_device spipnx_1 = {
+	.name = "spipnx",
+	.id = 1,
+	.num_resources = ARRAY_SIZE(spipnx_0_resources),
+	.resource = spipnx_0_resources,
+	.dev = {
+		.coherent_dma_mask = 0xFFFFFFFF,
+		},
+};
+
+static struct platform_device spipnx_2 = {
+	.name = "spipnx",
+	.id = 2,
+	.num_resources = ARRAY_SIZE(spipnx_1_resources),
+	.resource = spipnx_1_resources,
+	.dev = {
+		.coherent_dma_mask = 0xFFFFFFFF,
+		},
+};
+
+static struct plat_serial8250_port platform_serial_ports[] = {
+	{
+		.membase = (void *)__iomem(IO_ADDRESS(PNX4008_UART5_BASE)),
+		.mapbase = (unsigned long)PNX4008_UART5_BASE,
+		.irq = IIR5_INT,
+		.uartclk = PNX4008_UART_CLK,
+		.regshift = 2,
+		.iotype = UPIO_MEM,
+		.flags = UPF_BOOT_AUTOCONF | UPF_BUGGY_UART | UPF_SKIP_TEST,
+	},
+	{
+		.membase = (void *)__iomem(IO_ADDRESS(PNX4008_UART3_BASE)),
+		.mapbase = (unsigned long)PNX4008_UART3_BASE,
+		.irq = IIR3_INT,
+		.uartclk = PNX4008_UART_CLK,
+		.regshift = 2,
+		.iotype = UPIO_MEM,
+		.flags = UPF_BOOT_AUTOCONF | UPF_BUGGY_UART | UPF_SKIP_TEST,
+	 },
+	{}
+};
+
+static struct platform_device serial_device = {
+	.name = "serial8250",
+	.id = PLAT8250_DEV_PLATFORM,
+	.dev = {
+		.platform_data = &platform_serial_ports,
+	},
+};
+
+static struct platform_device *devices[] __initdata = {
+	&spipnx_1,
+	&spipnx_2,
+	&serial_device,
+};
+
+
+extern void pnx4008_uart_init(void);
+
+static void __init pnx4008_init(void)
+{
+	/*disable all START interrupt sources,
+	   and clear all START interrupt flags */
+	__raw_writel(0, START_INT_ER_REG(SE_PIN_BASE_INT));
+	__raw_writel(0, START_INT_ER_REG(SE_INT_BASE_INT));
+	__raw_writel(0xffffffff, START_INT_RSR_REG(SE_PIN_BASE_INT));
+	__raw_writel(0xffffffff, START_INT_RSR_REG(SE_INT_BASE_INT));
+
+	platform_add_devices(devices, ARRAY_SIZE(devices));
+	spi_register_board_info(spi_board_info, ARRAY_SIZE(spi_board_info));
+	/* Switch on the UART clocks */
+	pnx4008_uart_init();
+}
+
+static struct map_desc pnx4008_io_desc[] __initdata = {
+	{
+		.virtual 	= IO_ADDRESS(PNX4008_IRAM_BASE),
+		.pfn 		= __phys_to_pfn(PNX4008_IRAM_BASE),
+		.length		= SZ_64K,
+		.type 		= MT_DEVICE,
+	}, {
+		.virtual 	= IO_ADDRESS(PNX4008_NDF_FLASH_BASE),
+		.pfn 		= __phys_to_pfn(PNX4008_NDF_FLASH_BASE),
+		.length		= SZ_1M - SZ_128K,
+		.type 		= MT_DEVICE,
+	}, {
+		.virtual 	= IO_ADDRESS(PNX4008_JPEG_CONFIG_BASE),
+		.pfn 		= __phys_to_pfn(PNX4008_JPEG_CONFIG_BASE),
+		.length		= SZ_128K * 3,
+		.type 		= MT_DEVICE,
+	}, {
+		.virtual 	= IO_ADDRESS(PNX4008_DMA_CONFIG_BASE),
+		.pfn 		= __phys_to_pfn(PNX4008_DMA_CONFIG_BASE),
+		.length		= SZ_1M,
+		.type 		= MT_DEVICE,
+	}, {
+		.virtual 	= IO_ADDRESS(PNX4008_AHB2FAB_BASE),
+		.pfn 		= __phys_to_pfn(PNX4008_AHB2FAB_BASE),
+		.length		= SZ_1M,
+		.type 		= MT_DEVICE,
+	},
+};
+
+void __init pnx4008_map_io(void)
+{
+	iotable_init(pnx4008_io_desc, ARRAY_SIZE(pnx4008_io_desc));
+}
+
+extern struct sys_timer pnx4008_timer;
+
+MACHINE_START(PNX4008, "Philips PNX4008")
+	/* Maintainer: MontaVista Software Inc. */
+	.phys_io 		= 0x40090000,
+	.io_pg_offst 		= (0xf4090000 >> 18) & 0xfffc,
+	.boot_params		= 0x80000100,
+	.map_io 		= pnx4008_map_io,
+	.init_irq 		= pnx4008_init_irq,
+	.init_machine 		= pnx4008_init,
+	.timer 			= &pnx4008_timer,
+MACHINE_END
diff --git a/arch/arm/mach-pnx4008/dma.c b/arch/arm/mach-pnx4008/dma.c
new file mode 100644
index 000000000..ec01574f8
--- /dev/null
+++ b/arch/arm/mach-pnx4008/dma.c
@@ -0,0 +1,1108 @@
+/*
+ *  linux/arch/arm/mach-pnx4008/dma.c
+ *
+ *  PNX4008 DMA registration and IRQ dispatching
+ *
+ *  Author:	Vitaly Wool
+ *  Copyright:	MontaVista Software Inc. (c) 2005
+ *
+ *  Based on the code from Nicolas Pitre
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 2 as
+ *  published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/interrupt.h>
+#include <linux/errno.h>
+#include <linux/err.h>
+#include <linux/dma-mapping.h>
+#include <linux/clk.h>
+
+#include <asm/system.h>
+#include <asm/hardware.h>
+#include <asm/dma.h>
+#include <asm/dma-mapping.h>
+#include <asm/io.h>
+#include <asm/mach/dma.h>
+#include <asm/arch/clock.h>
+
+static struct dma_channel {
+	char *name;
+	void (*irq_handler) (int, int, void *, struct pt_regs *);
+	void *data;
+	struct pnx4008_dma_ll *ll;
+	u32 ll_dma;
+	void *target_addr;
+	int target_id;
+} dma_channels[MAX_DMA_CHANNELS];
+
+static struct ll_pool {
+	void *vaddr;
+	void *cur;
+	dma_addr_t dma_addr;
+	int count;
+} ll_pool;
+
+static spinlock_t ll_lock = SPIN_LOCK_UNLOCKED;
+
+struct pnx4008_dma_ll *pnx4008_alloc_ll_entry(dma_addr_t * ll_dma)
+{
+	struct pnx4008_dma_ll *ll = NULL;
+	unsigned long flags;
+
+	spin_lock_irqsave(&ll_lock, flags);
+	if (ll_pool.count > 4) { /* can give one more */
+		ll = *(struct pnx4008_dma_ll **) ll_pool.cur;
+		*ll_dma = ll_pool.dma_addr + ((void *)ll - ll_pool.vaddr);
+		*(void **)ll_pool.cur = **(void ***)ll_pool.cur;
+		memset(ll, 0, sizeof(*ll));
+		ll_pool.count--;
+	}
+	spin_unlock_irqrestore(&ll_lock, flags);
+
+	return ll;
+}
+
+EXPORT_SYMBOL_GPL(pnx4008_alloc_ll_entry);
+
+void pnx4008_free_ll_entry(struct pnx4008_dma_ll * ll, dma_addr_t ll_dma)
+{
+	unsigned long flags;
+
+	if (ll) {
+		if ((unsigned long)((long)ll - (long)ll_pool.vaddr) > 0x4000) {
+			printk(KERN_ERR "Trying to free entry not allocated by DMA\n");
+			BUG();
+		}
+
+		if (ll->flags & DMA_BUFFER_ALLOCATED)
+			ll->free(ll->alloc_data);
+
+		spin_lock_irqsave(&ll_lock, flags);
+		*(long *)ll = *(long *)ll_pool.cur;
+		*(long *)ll_pool.cur = (long)ll;
+		ll_pool.count++;
+		spin_unlock_irqrestore(&ll_lock, flags);
+	}
+}
+
+EXPORT_SYMBOL_GPL(pnx4008_free_ll_entry);
+
+void pnx4008_free_ll(u32 ll_dma, struct pnx4008_dma_ll * ll)
+{
+	struct pnx4008_dma_ll *ptr;
+	u32 dma;
+
+	while (ll) {
+		dma = ll->next_dma;
+		ptr = ll->next;
+		pnx4008_free_ll_entry(ll, ll_dma);
+
+		ll_dma = dma;
+		ll = ptr;
+	}
+}
+
+EXPORT_SYMBOL_GPL(pnx4008_free_ll);
+
+static int dma_channels_requested = 0;
+
+static inline void dma_increment_usage(void)
+{
+	if (!dma_channels_requested++) {
+		struct clk *clk = clk_get(0, "dma_ck");
+		if (!IS_ERR(clk)) {
+			clk_set_rate(clk, 1);
+			clk_put(clk);
+		}
+		pnx4008_config_dma(-1, -1, 1);
+	}
+}
+static inline void dma_decrement_usage(void)
+{
+	if (!--dma_channels_requested) {
+		struct clk *clk = clk_get(0, "dma_ck");
+		if (!IS_ERR(clk)) {
+			clk_set_rate(clk, 0);
+			clk_put(clk);
+		}
+		pnx4008_config_dma(-1, -1, 0);
+
+	}
+}
+
+static spinlock_t dma_lock = SPIN_LOCK_UNLOCKED;
+
+static inline void pnx4008_dma_lock(void)
+{
+	spin_lock_irq(&dma_lock);
+}
+
+static inline void pnx4008_dma_unlock(void)
+{
+	spin_unlock_irq(&dma_lock);
+}
+
+#define VALID_CHANNEL(c)	(((c) >= 0) && ((c) < MAX_DMA_CHANNELS))
+
+int pnx4008_request_channel(char *name, int ch,
+			    void (*irq_handler) (int, int, void *,
+						 struct pt_regs *), void *data)
+{
+	int i, found = 0;
+
+	/* basic sanity checks */
+	if (!name || (ch != -1 && !VALID_CHANNEL(ch)))
+		return -EINVAL;
+
+	pnx4008_dma_lock();
+
+	/* try grabbing a DMA channel with the requested priority */
+	for (i = MAX_DMA_CHANNELS - 1; i >= 0; i--) {
+		if (!dma_channels[i].name && (ch == -1 || ch == i)) {
+			found = 1;
+			break;
+		}
+	}
+
+	if (found) {
+		dma_increment_usage();
+		dma_channels[i].name = name;
+		dma_channels[i].irq_handler = irq_handler;
+		dma_channels[i].data = data;
+		dma_channels[i].ll = NULL;
+		dma_channels[i].ll_dma = 0;
+	} else {
+		printk(KERN_WARNING "No more available DMA channels for %s\n",
+		       name);
+		i = -ENODEV;
+	}
+
+	pnx4008_dma_unlock();
+	return i;
+}
+
+EXPORT_SYMBOL_GPL(pnx4008_request_channel);
+
+void pnx4008_free_channel(int ch)
+{
+	if (!dma_channels[ch].name) {
+		printk(KERN_CRIT
+		       "%s: trying to free channel %d which is already freed\n",
+		       __FUNCTION__, ch);
+		return;
+	}
+
+	pnx4008_dma_lock();
+	pnx4008_free_ll(dma_channels[ch].ll_dma, dma_channels[ch].ll);
+	dma_channels[ch].ll = NULL;
+	dma_decrement_usage();
+
+	dma_channels[ch].name = NULL;
+	pnx4008_dma_unlock();
+}
+
+EXPORT_SYMBOL_GPL(pnx4008_free_channel);
+
+int pnx4008_config_dma(int ahb_m1_be, int ahb_m2_be, int enable)
+{
+	unsigned long dma_cfg = __raw_readl(DMAC_CONFIG);
+
+	switch (ahb_m1_be) {
+	case 0:
+		dma_cfg &= ~(1 << 1);
+		break;
+	case 1:
+		dma_cfg |= (1 << 1);
+		break;
+	default:
+		break;
+	}
+
+	switch (ahb_m2_be) {
+	case 0:
+		dma_cfg &= ~(1 << 2);
+		break;
+	case 1:
+		dma_cfg |= (1 << 2);
+		break;
+	default:
+		break;
+	}
+
+	switch (enable) {
+	case 0:
+		dma_cfg &= ~(1 << 0);
+		break;
+	case 1:
+		dma_cfg |= (1 << 0);
+		break;
+	default:
+		break;
+	}
+
+	pnx4008_dma_lock();
+	__raw_writel(dma_cfg, DMAC_CONFIG);
+	pnx4008_dma_unlock();
+
+	return 0;
+}
+
+EXPORT_SYMBOL_GPL(pnx4008_config_dma);
+
+int pnx4008_dma_pack_control(const struct pnx4008_dma_ch_ctrl * ch_ctrl,
+			     unsigned long *ctrl)
+{
+	int i = 0, dbsize, sbsize, err = 0;
+
+	if (!ctrl || !ch_ctrl) {
+		err = -EINVAL;
+		goto out;
+	}
+
+	*ctrl = 0;
+
+	switch (ch_ctrl->tc_mask) {
+	case 0:
+		break;
+	case 1:
+		*ctrl |= (1 << 31);
+		break;
+
+	default:
+		err = -EINVAL;
+		goto out;
+	}
+
+	switch (ch_ctrl->cacheable) {
+	case 0:
+		break;
+	case 1:
+		*ctrl |= (1 << 30);
+		break;
+
+	default:
+		err = -EINVAL;
+		goto out;
+	}
+	switch (ch_ctrl->bufferable) {
+	case 0:
+		break;
+	case 1:
+		*ctrl |= (1 << 29);
+		break;
+
+	default:
+		err = -EINVAL;
+		goto out;
+	}
+	switch (ch_ctrl->priv_mode) {
+	case 0:
+		break;
+	case 1:
+		*ctrl |= (1 << 28);
+		break;
+
+	default:
+		err = -EINVAL;
+		goto out;
+	}
+	switch (ch_ctrl->di) {
+	case 0:
+		break;
+	case 1:
+		*ctrl |= (1 << 27);
+		break;
+
+	default:
+		err = -EINVAL;
+		goto out;
+	}
+	switch (ch_ctrl->si) {
+	case 0:
+		break;
+	case 1:
+		*ctrl |= (1 << 26);
+		break;
+
+	default:
+		err = -EINVAL;
+		goto out;
+	}
+	switch (ch_ctrl->dest_ahb1) {
+	case 0:
+		break;
+	case 1:
+		*ctrl |= (1 << 25);
+		break;
+
+	default:
+		err = -EINVAL;
+		goto out;
+	}
+	switch (ch_ctrl->src_ahb1) {
+	case 0:
+		break;
+	case 1:
+		*ctrl |= (1 << 24);
+		break;
+
+	default:
+		err = -EINVAL;
+		goto out;
+	}
+	switch (ch_ctrl->dwidth) {
+	case WIDTH_BYTE:
+		*ctrl &= ~(7 << 21);
+		break;
+	case WIDTH_HWORD:
+		*ctrl &= ~(7 << 21);
+		*ctrl |= (1 << 21);
+		break;
+	case WIDTH_WORD:
+		*ctrl &= ~(7 << 21);
+		*ctrl |= (2 << 21);
+		break;
+
+	default:
+		err = -EINVAL;
+		goto out;
+	}
+	switch (ch_ctrl->swidth) {
+	case WIDTH_BYTE:
+		*ctrl &= ~(7 << 18);
+		break;
+	case WIDTH_HWORD:
+		*ctrl &= ~(7 << 18);
+		*ctrl |= (1 << 18);
+		break;
+	case WIDTH_WORD:
+		*ctrl &= ~(7 << 18);
+		*ctrl |= (2 << 18);
+		break;
+
+	default:
+		err = -EINVAL;
+		goto out;
+	}
+	dbsize = ch_ctrl->dbsize;
+	while (!(dbsize & 1)) {
+		i++;
+		dbsize >>= 1;
+	}
+	if (ch_ctrl->dbsize != 1 || i > 8 || i == 1) {
+		err = -EINVAL;
+		goto out;
+	} else if (i > 1)
+		i--;
+	*ctrl &= ~(7 << 15);
+	*ctrl |= (i << 15);
+
+	sbsize = ch_ctrl->sbsize;
+	while (!(sbsize & 1)) {
+		i++;
+		sbsize >>= 1;
+	}
+	if (ch_ctrl->sbsize != 1 || i > 8 || i == 1) {
+		err = -EINVAL;
+		goto out;
+	} else if (i > 1)
+		i--;
+	*ctrl &= ~(7 << 12);
+	*ctrl |= (i << 12);
+
+	if (ch_ctrl->tr_size > 0x7ff) {
+		err = -E2BIG;
+		goto out;
+	}
+	*ctrl &= ~0x7ff;
+	*ctrl |= ch_ctrl->tr_size & 0x7ff;
+
+out:
+	return err;
+}
+
+EXPORT_SYMBOL_GPL(pnx4008_dma_pack_control);
+
+int pnx4008_dma_parse_control(unsigned long ctrl,
+			      struct pnx4008_dma_ch_ctrl * ch_ctrl)
+{
+	int err = 0;
+
+	if (!ch_ctrl) {
+		err = -EINVAL;
+		goto out;
+	}
+
+	ch_ctrl->tr_size = ctrl & 0x7ff;
+	ctrl >>= 12;
+
+	ch_ctrl->sbsize = 1 << (ctrl & 7);
+	if (ch_ctrl->sbsize > 1)
+		ch_ctrl->sbsize <<= 1;
+	ctrl >>= 3;
+
+	ch_ctrl->dbsize = 1 << (ctrl & 7);
+	if (ch_ctrl->dbsize > 1)
+		ch_ctrl->dbsize <<= 1;
+	ctrl >>= 3;
+
+	switch (ctrl & 7) {
+	case 0:
+		ch_ctrl->swidth = WIDTH_BYTE;
+		break;
+	case 1:
+		ch_ctrl->swidth = WIDTH_HWORD;
+		break;
+	case 2:
+		ch_ctrl->swidth = WIDTH_WORD;
+		break;
+	default:
+		err = -EINVAL;
+		goto out;
+	}
+	ctrl >>= 3;
+
+	switch (ctrl & 7) {
+	case 0:
+		ch_ctrl->dwidth = WIDTH_BYTE;
+		break;
+	case 1:
+		ch_ctrl->dwidth = WIDTH_HWORD;
+		break;
+	case 2:
+		ch_ctrl->dwidth = WIDTH_WORD;
+		break;
+	default:
+		err = -EINVAL;
+		goto out;
+	}
+	ctrl >>= 3;
+
+	ch_ctrl->src_ahb1 = ctrl & 1;
+	ctrl >>= 1;
+
+	ch_ctrl->dest_ahb1 = ctrl & 1;
+	ctrl >>= 1;
+
+	ch_ctrl->si = ctrl & 1;
+	ctrl >>= 1;
+
+	ch_ctrl->di = ctrl & 1;
+	ctrl >>= 1;
+
+	ch_ctrl->priv_mode = ctrl & 1;
+	ctrl >>= 1;
+
+	ch_ctrl->bufferable = ctrl & 1;
+	ctrl >>= 1;
+
+	ch_ctrl->cacheable = ctrl & 1;
+	ctrl >>= 1;
+
+	ch_ctrl->tc_mask = ctrl & 1;
+
+out:
+	return err;
+}
+
+EXPORT_SYMBOL_GPL(pnx4008_dma_parse_control);
+
+int pnx4008_dma_pack_config(const struct pnx4008_dma_ch_config * ch_cfg,
+			    unsigned long *cfg)
+{
+	int err = 0;
+
+	if (!cfg || !ch_cfg) {
+		err = -EINVAL;
+		goto out;
+	}
+
+	*cfg = 0;
+
+	switch (ch_cfg->halt) {
+	case 0:
+		break;
+	case 1:
+		*cfg |= (1 << 18);
+		break;
+
+	default:
+		err = -EINVAL;
+		goto out;
+	}
+	switch (ch_cfg->active) {
+	case 0:
+		break;
+	case 1:
+		*cfg |= (1 << 17);
+		break;
+
+	default:
+		err = -EINVAL;
+		goto out;
+	}
+	switch (ch_cfg->lock) {
+	case 0:
+		break;
+	case 1:
+		*cfg |= (1 << 16);
+		break;
+
+	default:
+		err = -EINVAL;
+		goto out;
+	}
+	switch (ch_cfg->itc) {
+	case 0:
+		break;
+	case 1:
+		*cfg |= (1 << 15);
+		break;
+
+	default:
+		err = -EINVAL;
+		goto out;
+	}
+	switch (ch_cfg->ie) {
+	case 0:
+		break;
+	case 1:
+		*cfg |= (1 << 14);
+		break;
+
+	default:
+		err = -EINVAL;
+		goto out;
+	}
+	switch (ch_cfg->flow_cntrl) {
+	case FC_MEM2MEM_DMA:
+		*cfg &= ~(7 << 11);
+		break;
+	case FC_MEM2PER_DMA:
+		*cfg &= ~(7 << 11);
+		*cfg |= (1 << 11);
+		break;
+	case FC_PER2MEM_DMA:
+		*cfg &= ~(7 << 11);
+		*cfg |= (2 << 11);
+		break;
+	case FC_PER2PER_DMA:
+		*cfg &= ~(7 << 11);
+		*cfg |= (3 << 11);
+		break;
+	case FC_PER2PER_DPER:
+		*cfg &= ~(7 << 11);
+		*cfg |= (4 << 11);
+		break;
+	case FC_MEM2PER_PER:
+		*cfg &= ~(7 << 11);
+		*cfg |= (5 << 11);
+		break;
+	case FC_PER2MEM_PER:
+		*cfg &= ~(7 << 11);
+		*cfg |= (6 << 11);
+		break;
+	case FC_PER2PER_SPER:
+		*cfg |= (7 << 11);
+		break;
+
+	default:
+		err = -EINVAL;
+		goto out;
+	}
+	*cfg &= ~(0x1f << 6);
+	*cfg |= ((ch_cfg->dest_per & 0x1f) << 6);
+
+	*cfg &= ~(0x1f << 1);
+	*cfg |= ((ch_cfg->src_per & 0x1f) << 1);
+
+out:
+	return err;
+}
+
+EXPORT_SYMBOL_GPL(pnx4008_dma_pack_config);
+
+int pnx4008_dma_parse_config(unsigned long cfg,
+			     struct pnx4008_dma_ch_config * ch_cfg)
+{
+	int err = 0;
+
+	if (!ch_cfg) {
+		err = -EINVAL;
+		goto out;
+	}
+
+	cfg >>= 1;
+
+	ch_cfg->src_per = cfg & 0x1f;
+	cfg >>= 5;
+
+	ch_cfg->dest_per = cfg & 0x1f;
+	cfg >>= 5;
+
+	switch (cfg & 7) {
+	case 0:
+		ch_cfg->flow_cntrl = FC_MEM2MEM_DMA;
+		break;
+	case 1:
+		ch_cfg->flow_cntrl = FC_MEM2PER_DMA;
+		break;
+	case 2:
+		ch_cfg->flow_cntrl = FC_PER2MEM_DMA;
+		break;
+	case 3:
+		ch_cfg->flow_cntrl = FC_PER2PER_DMA;
+		break;
+	case 4:
+		ch_cfg->flow_cntrl = FC_PER2PER_DPER;
+		break;
+	case 5:
+		ch_cfg->flow_cntrl = FC_MEM2PER_PER;
+		break;
+	case 6:
+		ch_cfg->flow_cntrl = FC_PER2MEM_PER;
+		break;
+	case 7:
+		ch_cfg->flow_cntrl = FC_PER2PER_SPER;
+	}
+	cfg >>= 3;
+
+	ch_cfg->ie = cfg & 1;
+	cfg >>= 1;
+
+	ch_cfg->itc = cfg & 1;
+	cfg >>= 1;
+
+	ch_cfg->lock = cfg & 1;
+	cfg >>= 1;
+
+	ch_cfg->active = cfg & 1;
+	cfg >>= 1;
+
+	ch_cfg->halt = cfg & 1;
+
+out:
+	return err;
+}
+
+EXPORT_SYMBOL_GPL(pnx4008_dma_parse_config);
+
+void pnx4008_dma_split_head_entry(struct pnx4008_dma_config * config,
+				  struct pnx4008_dma_ch_ctrl * ctrl)
+{
+	int new_len = ctrl->tr_size, num_entries = 0;
+	int old_len = new_len;
+	int src_width, dest_width, count = 1;
+
+	switch (ctrl->swidth) {
+	case WIDTH_BYTE:
+		src_width = 1;
+		break;
+	case WIDTH_HWORD:
+		src_width = 2;
+		break;
+	case WIDTH_WORD:
+		src_width = 4;
+		break;
+	default:
+		return;
+	}
+
+	switch (ctrl->dwidth) {
+	case WIDTH_BYTE:
+		dest_width = 1;
+		break;
+	case WIDTH_HWORD:
+		dest_width = 2;
+		break;
+	case WIDTH_WORD:
+		dest_width = 4;
+		break;
+	default:
+		return;
+	}
+
+	while (new_len > 0x7FF) {
+		num_entries++;
+		new_len = (ctrl->tr_size + num_entries) / (num_entries + 1);
+	}
+	if (num_entries != 0) {
+		struct pnx4008_dma_ll *ll = NULL;
+		config->ch_ctrl &= ~0x7ff;
+		config->ch_ctrl |= new_len;
+		if (!config->is_ll) {
+			config->is_ll = 1;
+			while (num_entries) {
+				if (!ll) {
+					config->ll =
+					    pnx4008_alloc_ll_entry(&config->
+								   ll_dma);
+					ll = config->ll;
+				} else {
+					ll->next =
+					    pnx4008_alloc_ll_entry(&ll->
+								   next_dma);
+					ll = ll->next;
+				}
+
+				if (ctrl->si)
+					ll->src_addr =
+					    config->src_addr +
+					    src_width * new_len * count;
+				else
+					ll->src_addr = config->src_addr;
+				if (ctrl->di)
+					ll->dest_addr =
+					    config->dest_addr +
+					    dest_width * new_len * count;
+				else
+					ll->dest_addr = config->dest_addr;
+				ll->ch_ctrl = config->ch_ctrl & 0x7fffffff;
+				ll->next_dma = 0;
+				ll->next = NULL;
+				num_entries--;
+				count++;
+			}
+		} else {
+			struct pnx4008_dma_ll *ll_old = config->ll;
+			unsigned long ll_dma_old = config->ll_dma;
+			while (num_entries) {
+				if (!ll) {
+					config->ll =
+					    pnx4008_alloc_ll_entry(&config->
+								   ll_dma);
+					ll = config->ll;
+				} else {
+					ll->next =
+					    pnx4008_alloc_ll_entry(&ll->
+								   next_dma);
+					ll = ll->next;
+				}
+
+				if (ctrl->si)
+					ll->src_addr =
+					    config->src_addr +
+					    src_width * new_len * count;
+				else
+					ll->src_addr = config->src_addr;
+				if (ctrl->di)
+					ll->dest_addr =
+					    config->dest_addr +
+					    dest_width * new_len * count;
+				else
+					ll->dest_addr = config->dest_addr;
+				ll->ch_ctrl = config->ch_ctrl & 0x7fffffff;
+				ll->next_dma = 0;
+				ll->next = NULL;
+				num_entries--;
+				count++;
+			}
+			ll->next_dma = ll_dma_old;
+			ll->next = ll_old;
+		}
+		/* adjust last length/tc */
+		ll->ch_ctrl = config->ch_ctrl & (~0x7ff);
+		ll->ch_ctrl |= old_len - new_len * (count - 1);
+		config->ch_ctrl &= 0x7fffffff;
+	}
+}
+
+EXPORT_SYMBOL_GPL(pnx4008_dma_split_head_entry);
+
+void pnx4008_dma_split_ll_entry(struct pnx4008_dma_ll * cur_ll,
+				struct pnx4008_dma_ch_ctrl * ctrl)
+{
+	int new_len = ctrl->tr_size, num_entries = 0;
+	int old_len = new_len;
+	int src_width, dest_width, count = 1;
+
+	switch (ctrl->swidth) {
+	case WIDTH_BYTE:
+		src_width = 1;
+		break;
+	case WIDTH_HWORD:
+		src_width = 2;
+		break;
+	case WIDTH_WORD:
+		src_width = 4;
+		break;
+	default:
+		return;
+	}
+
+	switch (ctrl->dwidth) {
+	case WIDTH_BYTE:
+		dest_width = 1;
+		break;
+	case WIDTH_HWORD:
+		dest_width = 2;
+		break;
+	case WIDTH_WORD:
+		dest_width = 4;
+		break;
+	default:
+		return;
+	}
+
+	while (new_len > 0x7FF) {
+		num_entries++;
+		new_len = (ctrl->tr_size + num_entries) / (num_entries + 1);
+	}
+	if (num_entries != 0) {
+		struct pnx4008_dma_ll *ll = NULL;
+		cur_ll->ch_ctrl &= ~0x7ff;
+		cur_ll->ch_ctrl |= new_len;
+		if (!cur_ll->next) {
+			while (num_entries) {
+				if (!ll) {
+					cur_ll->next =
+					    pnx4008_alloc_ll_entry(&cur_ll->
+								   next_dma);
+					ll = cur_ll->next;
+				} else {
+					ll->next =
+					    pnx4008_alloc_ll_entry(&ll->
+								   next_dma);
+					ll = ll->next;
+				}
+
+				if (ctrl->si)
+					ll->src_addr =
+					    cur_ll->src_addr +
+					    src_width * new_len * count;
+				else
+					ll->src_addr = cur_ll->src_addr;
+				if (ctrl->di)
+					ll->dest_addr =
+					    cur_ll->dest_addr +
+					    dest_width * new_len * count;
+				else
+					ll->dest_addr = cur_ll->dest_addr;
+				ll->ch_ctrl = cur_ll->ch_ctrl & 0x7fffffff;
+				ll->next_dma = 0;
+				ll->next = NULL;
+				num_entries--;
+				count++;
+			}
+		} else {
+			struct pnx4008_dma_ll *ll_old = cur_ll->next;
+			unsigned long ll_dma_old = cur_ll->next_dma;
+			while (num_entries) {
+				if (!ll) {
+					cur_ll->next =
+					    pnx4008_alloc_ll_entry(&cur_ll->
+								   next_dma);
+					ll = cur_ll->next;
+				} else {
+					ll->next =
+					    pnx4008_alloc_ll_entry(&ll->
+								   next_dma);
+					ll = ll->next;
+				}
+
+				if (ctrl->si)
+					ll->src_addr =
+					    cur_ll->src_addr +
+					    src_width * new_len * count;
+				else
+					ll->src_addr = cur_ll->src_addr;
+				if (ctrl->di)
+					ll->dest_addr =
+					    cur_ll->dest_addr +
+					    dest_width * new_len * count;
+				else
+					ll->dest_addr = cur_ll->dest_addr;
+				ll->ch_ctrl = cur_ll->ch_ctrl & 0x7fffffff;
+				ll->next_dma = 0;
+				ll->next = NULL;
+				num_entries--;
+				count++;
+			}
+
+			ll->next_dma = ll_dma_old;
+			ll->next = ll_old;
+		}
+		/* adjust last length/tc */
+		ll->ch_ctrl = cur_ll->ch_ctrl & (~0x7ff);
+		ll->ch_ctrl |= old_len - new_len * (count - 1);
+		cur_ll->ch_ctrl &= 0x7fffffff;
+	}
+}
+
+EXPORT_SYMBOL_GPL(pnx4008_dma_split_ll_entry);
+
+int pnx4008_config_channel(int ch, struct pnx4008_dma_config * config)
+{
+	if (!VALID_CHANNEL(ch) || !dma_channels[ch].name)
+		return -EINVAL;
+
+	pnx4008_dma_lock();
+	__raw_writel(config->src_addr, DMAC_Cx_SRC_ADDR(ch));
+	__raw_writel(config->dest_addr, DMAC_Cx_DEST_ADDR(ch));
+
+	if (config->is_ll)
+		__raw_writel(config->ll_dma, DMAC_Cx_LLI(ch));
+	else
+		__raw_writel(0, DMAC_Cx_LLI(ch));
+
+	__raw_writel(config->ch_ctrl, DMAC_Cx_CONTROL(ch));
+	__raw_writel(config->ch_cfg, DMAC_Cx_CONFIG(ch));
+	pnx4008_dma_unlock();
+
+	return 0;
+
+}
+
+EXPORT_SYMBOL_GPL(pnx4008_config_channel);
+
+int pnx4008_channel_get_config(int ch, struct pnx4008_dma_config * config)
+{
+	if (!VALID_CHANNEL(ch) || !dma_channels[ch].name || !config)
+		return -EINVAL;
+
+	pnx4008_dma_lock();
+	config->ch_cfg = __raw_readl(DMAC_Cx_CONFIG(ch));
+	config->ch_ctrl = __raw_readl(DMAC_Cx_CONTROL(ch));
+
+	config->ll_dma = __raw_readl(DMAC_Cx_LLI(ch));
+	config->is_ll = config->ll_dma ? 1 : 0;
+
+	config->src_addr = __raw_readl(DMAC_Cx_SRC_ADDR(ch));
+	config->dest_addr = __raw_readl(DMAC_Cx_DEST_ADDR(ch));
+	pnx4008_dma_unlock();
+
+	return 0;
+}
+
+EXPORT_SYMBOL_GPL(pnx4008_channel_get_config);
+
+int pnx4008_dma_ch_enable(int ch)
+{
+	unsigned long ch_cfg;
+
+	if (!VALID_CHANNEL(ch) || !dma_channels[ch].name)
+		return -EINVAL;
+
+	pnx4008_dma_lock();
+	ch_cfg = __raw_readl(DMAC_Cx_CONFIG(ch));
+	ch_cfg |= 1;
+	__raw_writel(ch_cfg, DMAC_Cx_CONFIG(ch));
+	pnx4008_dma_unlock();
+
+	return 0;
+}
+
+EXPORT_SYMBOL_GPL(pnx4008_dma_ch_enable);
+
+int pnx4008_dma_ch_disable(int ch)
+{
+	unsigned long ch_cfg;
+
+	if (!VALID_CHANNEL(ch) || !dma_channels[ch].name)
+		return -EINVAL;
+
+	pnx4008_dma_lock();
+	ch_cfg = __raw_readl(DMAC_Cx_CONFIG(ch));
+	ch_cfg &= ~1;
+	__raw_writel(ch_cfg, DMAC_Cx_CONFIG(ch));
+	pnx4008_dma_unlock();
+
+	return 0;
+}
+
+EXPORT_SYMBOL_GPL(pnx4008_dma_ch_disable);
+
+int pnx4008_dma_ch_enabled(int ch)
+{
+	unsigned long ch_cfg;
+
+	if (!VALID_CHANNEL(ch) || !dma_channels[ch].name)
+		return -EINVAL;
+
+	pnx4008_dma_lock();
+	ch_cfg = __raw_readl(DMAC_Cx_CONFIG(ch));
+	pnx4008_dma_unlock();
+
+	return ch_cfg & 1;
+}
+
+EXPORT_SYMBOL_GPL(pnx4008_dma_ch_enabled);
+
+static irqreturn_t dma_irq_handler(int irq, void *dev_id, struct pt_regs *regs)
+{
+	int i;
+	unsigned long dint = __raw_readl(DMAC_INT_STAT);
+	unsigned long tcint = __raw_readl(DMAC_INT_TC_STAT);
+	unsigned long eint = __raw_readl(DMAC_INT_ERR_STAT);
+	unsigned long i_bit;
+
+	for (i = MAX_DMA_CHANNELS - 1; i >= 0; i--) {
+		i_bit = 1 << i;
+		if (dint & i_bit) {
+			struct dma_channel *channel = &dma_channels[i];
+
+			if (channel->name && channel->irq_handler) {
+				int cause = 0;
+
+				if (eint & i_bit)
+					cause |= DMA_ERR_INT;
+				if (tcint & i_bit)
+					cause |= DMA_TC_INT;
+				channel->irq_handler(i, cause, channel->data,
+						     regs);
+			} else {
+				/*
+				 * IRQ for an unregistered DMA channel
+				 */
+				printk(KERN_WARNING
+				       "spurious IRQ for DMA channel %d\n", i);
+			}
+			if (tcint & i_bit)
+				__raw_writel(i_bit, DMAC_INT_TC_CLEAR);
+			if (eint & i_bit)
+				__raw_writel(i_bit, DMAC_INT_ERR_CLEAR);
+		}
+	}
+	return IRQ_HANDLED;
+}
+
+static int __init pnx4008_dma_init(void)
+{
+	int ret, i;
+
+	ret = request_irq(DMA_INT, dma_irq_handler, 0, "DMA", NULL);
+	if (ret) {
+		printk(KERN_CRIT "Wow!  Can't register IRQ for DMA\n");
+		goto out;
+	}
+
+	ll_pool.count = 0x4000 / sizeof(struct pnx4008_dma_ll);
+	ll_pool.cur = ll_pool.vaddr =
+	    dma_alloc_coherent(NULL, ll_pool.count * sizeof(struct pnx4008_dma_ll),
+			       &ll_pool.dma_addr, GFP_KERNEL);
+
+	if (!ll_pool.vaddr) {
+		ret = -ENOMEM;
+		free_irq(DMA_INT, NULL);
+		goto out;
+	}
+
+	for (i = 0; i < ll_pool.count - 1; i++) {
+		void **addr = ll_pool.vaddr + i * sizeof(struct pnx4008_dma_ll);
+		*addr = (void *)addr + sizeof(struct pnx4008_dma_ll);
+	}
+	*(long *)(ll_pool.vaddr +
+		  (ll_pool.count - 1) * sizeof(struct pnx4008_dma_ll)) =
+	    (long)ll_pool.vaddr;
+
+	__raw_writel(1, DMAC_CONFIG);
+
+out:
+	return ret;
+}
+arch_initcall(pnx4008_dma_init);
diff --git a/arch/arm/mach-pnx4008/gpio.c b/arch/arm/mach-pnx4008/gpio.c
new file mode 100644
index 000000000..1ab84ced7
--- /dev/null
+++ b/arch/arm/mach-pnx4008/gpio.c
@@ -0,0 +1,329 @@
+/*
+ * arch/arm/mach-pnx4008/gpio.c
+ *
+ * PNX4008 GPIO driver
+ *
+ * Author: Dmitry Chigirev <source@mvista.com>
+ *
+ * Based on reference code by Iwo Mergler and Z.Tabaaloute from Philips:
+ * Copyright (c) 2005 Koninklijke Philips Electronics N.V.
+ *
+ * 2005 (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.
+ */
+
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <asm/semaphore.h>
+#include <asm/io.h>
+#include <asm/arch/platform.h>
+#include <asm/arch/gpio.h>
+
+/* register definitions */
+#define PIO_VA_BASE	IO_ADDRESS(PNX4008_PIO_BASE)
+
+#define PIO_INP_STATE	(0x00U)
+#define PIO_OUTP_SET	(0x04U)
+#define PIO_OUTP_CLR	(0x08U)
+#define PIO_OUTP_STATE	(0x0CU)
+#define PIO_DRV_SET	(0x10U)
+#define PIO_DRV_CLR	(0x14U)
+#define PIO_DRV_STATE	(0x18U)
+#define PIO_SDINP_STATE	(0x1CU)
+#define PIO_SDOUTP_SET	(0x20U)
+#define PIO_SDOUTP_CLR	(0x24U)
+#define PIO_MUX_SET	(0x28U)
+#define PIO_MUX_CLR	(0x2CU)
+#define PIO_MUX_STATE	(0x30U)
+
+static inline void gpio_lock(void)
+{
+	local_irq_disable();
+}
+
+static inline void gpio_unlock(void)
+{
+	local_irq_enable();
+}
+
+/* Inline functions */
+static inline int gpio_read_bit(u32 reg, int gpio)
+{
+	u32 bit, val;
+	int ret = -EFAULT;
+
+	if (gpio < 0)
+		goto out;
+
+	bit = GPIO_BIT(gpio);
+	if (bit) {
+		val = __raw_readl(PIO_VA_BASE + reg);
+		ret = (val & bit) ? 1 : 0;
+	}
+out:
+	return ret;
+}
+
+static inline int gpio_set_bit(u32 reg, int gpio)
+{
+	u32 bit, val;
+	int ret = -EFAULT;
+
+	if (gpio < 0)
+		goto out;
+
+	bit = GPIO_BIT(gpio);
+	if (bit) {
+		val = __raw_readl(PIO_VA_BASE + reg);
+		val |= bit;
+		__raw_writel(val, PIO_VA_BASE + reg);
+		ret = 0;
+	}
+out:
+	return ret;
+}
+
+/* Very simple access control, bitmap for allocated/free */
+static unsigned long access_map[4];
+#define INP_INDEX	0
+#define OUTP_INDEX	1
+#define GPIO_INDEX	2
+#define MUX_INDEX	3
+
+/*GPIO to Input Mapping */
+static short gpio_to_inp_map[32] = {
+	-1, -1, -1, -1, -1, -1, -1, -1,
+	-1, -1, -1, -1, -1, -1, -1, -1,
+	-1, -1, -1, -1, -1, -1, -1, -1,
+	-1, 10, 11, 12, 13, 14, 24, -1
+};
+
+/*GPIO to Mux Mapping */
+static short gpio_to_mux_map[32] = {
+	-1, -1, -1, -1, -1, -1, -1, -1,
+	-1, -1, -1, -1, -1, -1, -1, -1,
+	-1, -1, -1, -1, -1, -1, -1, -1,
+	-1, -1, -1, 0, 1, 4, 5, -1
+};
+
+/*Output to Mux Mapping */
+static short outp_to_mux_map[32] = {
+	-1, -1, -1, 6, -1, -1, -1, -1,
+	-1, -1, -1, -1, -1, -1, -1, -1,
+	-1, -1, -1, -1, -1, 2, -1, -1,
+	-1, -1, -1, -1, -1, -1, -1, -1
+};
+
+int pnx4008_gpio_register_pin(unsigned short pin)
+{
+	unsigned long bit = GPIO_BIT(pin);
+	int ret = -EBUSY;	/* Already in use */
+
+	gpio_lock();
+
+	if (GPIO_ISBID(pin)) {
+		if (access_map[GPIO_INDEX] & bit)
+			goto out;
+		access_map[GPIO_INDEX] |= bit;
+
+	} else if (GPIO_ISRAM(pin)) {
+		if (access_map[GPIO_INDEX] & bit)
+			goto out;
+		access_map[GPIO_INDEX] |= bit;
+
+	} else if (GPIO_ISMUX(pin)) {
+		if (access_map[MUX_INDEX] & bit)
+			goto out;
+		access_map[MUX_INDEX] |= bit;
+
+	} else if (GPIO_ISOUT(pin)) {
+		if (access_map[OUTP_INDEX] & bit)
+			goto out;
+		access_map[OUTP_INDEX] |= bit;
+
+	} else if (GPIO_ISIN(pin)) {
+		if (access_map[INP_INDEX] & bit)
+			goto out;
+		access_map[INP_INDEX] |= bit;
+	} else
+		goto out;
+	ret = 0;
+
+out:
+	gpio_unlock();
+	return ret;
+}
+
+EXPORT_SYMBOL(pnx4008_gpio_register_pin);
+
+int pnx4008_gpio_unregister_pin(unsigned short pin)
+{
+	unsigned long bit = GPIO_BIT(pin);
+	int ret = -EFAULT;	/* Not registered */
+
+	gpio_lock();
+
+	if (GPIO_ISBID(pin)) {
+		if (~access_map[GPIO_INDEX] & bit)
+			goto out;
+		access_map[GPIO_INDEX] &= ~bit;
+	} else if (GPIO_ISRAM(pin)) {
+		if (~access_map[GPIO_INDEX] & bit)
+			goto out;
+		access_map[GPIO_INDEX] &= ~bit;
+	} else if (GPIO_ISMUX(pin)) {
+		if (~access_map[MUX_INDEX] & bit)
+			goto out;
+		access_map[MUX_INDEX] &= ~bit;
+	} else if (GPIO_ISOUT(pin)) {
+		if (~access_map[OUTP_INDEX] & bit)
+			goto out;
+		access_map[OUTP_INDEX] &= ~bit;
+	} else if (GPIO_ISIN(pin)) {
+		if (~access_map[INP_INDEX] & bit)
+			goto out;
+		access_map[INP_INDEX] &= ~bit;
+	} else
+		goto out;
+	ret = 0;
+
+out:
+	gpio_unlock();
+	return ret;
+}
+
+EXPORT_SYMBOL(pnx4008_gpio_unregister_pin);
+
+unsigned long pnx4008_gpio_read_pin(unsigned short pin)
+{
+	unsigned long ret = -EFAULT;
+	int gpio = GPIO_BIT_MASK(pin);
+	gpio_lock();
+	if (GPIO_ISOUT(pin)) {
+		ret = gpio_read_bit(PIO_OUTP_STATE, gpio);
+	} else if (GPIO_ISRAM(pin)) {
+		if (gpio_read_bit(PIO_DRV_STATE, gpio) == 0) {
+			ret = gpio_read_bit(PIO_SDINP_STATE, gpio);
+		}
+	} else if (GPIO_ISBID(pin)) {
+		ret = gpio_read_bit(PIO_DRV_STATE, gpio);
+		if (ret > 0)
+			ret = gpio_read_bit(PIO_OUTP_STATE, gpio);
+		else if (ret == 0)
+			ret =
+			    gpio_read_bit(PIO_INP_STATE, gpio_to_inp_map[gpio]);
+	} else if (GPIO_ISIN(pin)) {
+		ret = gpio_read_bit(PIO_INP_STATE, gpio);
+	}
+	gpio_unlock();
+	return ret;
+}
+
+EXPORT_SYMBOL(pnx4008_gpio_read_pin);
+
+/* Write Value to output */
+int pnx4008_gpio_write_pin(unsigned short pin, int output)
+{
+	int gpio = GPIO_BIT_MASK(pin);
+	int ret = -EFAULT;
+
+	gpio_lock();
+	if (GPIO_ISOUT(pin)) {
+		printk( "writing '%x' to '%x'\n",
+				gpio, output ? PIO_OUTP_SET : PIO_OUTP_CLR );
+		ret = gpio_set_bit(output ? PIO_OUTP_SET : PIO_OUTP_CLR, gpio);
+	} else if (GPIO_ISRAM(pin)) {
+		if (gpio_read_bit(PIO_DRV_STATE, gpio) > 0)
+			ret = gpio_set_bit(output ? PIO_SDOUTP_SET :
+					   PIO_SDOUTP_CLR, gpio);
+	} else if (GPIO_ISBID(pin)) {
+		if (gpio_read_bit(PIO_DRV_STATE, gpio) > 0)
+			ret = gpio_set_bit(output ? PIO_OUTP_SET :
+					   PIO_OUTP_CLR, gpio);
+	}
+	gpio_unlock();
+	return ret;
+}
+
+EXPORT_SYMBOL(pnx4008_gpio_write_pin);
+
+/* Value = 1 : Set GPIO pin as output */
+/* Value = 0 : Set GPIO pin as input */
+int pnx4008_gpio_set_pin_direction(unsigned short pin, int output)
+{
+	int gpio = GPIO_BIT_MASK(pin);
+	int ret = -EFAULT;
+
+	gpio_lock();
+	if (GPIO_ISBID(pin) || GPIO_ISRAM(pin)) {
+		ret = gpio_set_bit(output ? PIO_DRV_SET : PIO_DRV_CLR, gpio);
+	}
+	gpio_unlock();
+	return ret;
+}
+
+EXPORT_SYMBOL(pnx4008_gpio_set_pin_direction);
+
+/* Read GPIO pin direction: 0= pin used as input, 1= pin used as output*/
+int pnx4008_gpio_read_pin_direction(unsigned short pin)
+{
+	int gpio = GPIO_BIT_MASK(pin);
+	int ret = -EFAULT;
+
+	gpio_lock();
+	if (GPIO_ISBID(pin) || GPIO_ISRAM(pin)) {
+		ret = gpio_read_bit(PIO_DRV_STATE, gpio);
+	}
+	gpio_unlock();
+	return ret;
+}
+
+EXPORT_SYMBOL(pnx4008_gpio_read_pin_direction);
+
+/* Value = 1 : Set pin to muxed function  */
+/* Value = 0 : Set pin as GPIO */
+int pnx4008_gpio_set_pin_mux(unsigned short pin, int output)
+{
+	int gpio = GPIO_BIT_MASK(pin);
+	int ret = -EFAULT;
+
+	gpio_lock();
+	if (GPIO_ISBID(pin)) {
+		ret =
+		    gpio_set_bit(output ? PIO_MUX_SET : PIO_MUX_CLR,
+				 gpio_to_mux_map[gpio]);
+	} else if (GPIO_ISOUT(pin)) {
+		ret =
+		    gpio_set_bit(output ? PIO_MUX_SET : PIO_MUX_CLR,
+				 outp_to_mux_map[gpio]);
+	} else if (GPIO_ISMUX(pin)) {
+		ret = gpio_set_bit(output ? PIO_MUX_SET : PIO_MUX_CLR, gpio);
+	}
+	gpio_unlock();
+	return ret;
+}
+
+EXPORT_SYMBOL(pnx4008_gpio_set_pin_mux);
+
+/* Read pin mux function: 0= pin used as GPIO, 1= pin used for muxed function*/
+int pnx4008_gpio_read_pin_mux(unsigned short pin)
+{
+	int gpio = GPIO_BIT_MASK(pin);
+	int ret = -EFAULT;
+
+	gpio_lock();
+	if (GPIO_ISBID(pin)) {
+		ret = gpio_read_bit(PIO_MUX_STATE, gpio_to_mux_map[gpio]);
+	} else if (GPIO_ISOUT(pin)) {
+		ret = gpio_read_bit(PIO_MUX_STATE, outp_to_mux_map[gpio]);
+	} else if (GPIO_ISMUX(pin)) {
+		ret = gpio_read_bit(PIO_MUX_STATE, gpio);
+	}
+	gpio_unlock();
+	return ret;
+}
+
+EXPORT_SYMBOL(pnx4008_gpio_read_pin_mux);
diff --git a/arch/arm/mach-pnx4008/irq.c b/arch/arm/mach-pnx4008/irq.c
new file mode 100644
index 000000000..3a4bcf3d9
--- /dev/null
+++ b/arch/arm/mach-pnx4008/irq.c
@@ -0,0 +1,119 @@
+/*
+ * arch/arm/mach-pnx4008/irq.c
+ *
+ * PNX4008 IRQ controller driver
+ *
+ * Author: Dmitry Chigirev <source@mvista.com>
+ *
+ * Based on reference code received from Philips:
+ * Copyright (C) 2003 Philips Semiconductors
+ *
+ * 2005 (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.
+ */
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/mm.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <linux/device.h>
+#include <linux/irq.h>
+#include <asm/hardware.h>
+#include <asm/io.h>
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+#include <asm/pgtable.h>
+#include <asm/page.h>
+#include <asm/system.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/irq.h>
+#include <asm/mach/map.h>
+#include <asm/arch/irq.h>
+
+static u8 pnx4008_irq_type[NR_IRQS] = PNX4008_IRQ_TYPES;
+
+static void pnx4008_mask_irq(unsigned int irq)
+{
+	__raw_writel(__raw_readl(INTC_ER(irq)) & ~INTC_BIT(irq), INTC_ER(irq));	/* mask interrupt */
+}
+
+static void pnx4008_unmask_irq(unsigned int irq)
+{
+	__raw_writel(__raw_readl(INTC_ER(irq)) | INTC_BIT(irq), INTC_ER(irq));	/* unmask interrupt */
+}
+
+static void pnx4008_mask_ack_irq(unsigned int irq)
+{
+	__raw_writel(__raw_readl(INTC_ER(irq)) & ~INTC_BIT(irq), INTC_ER(irq));	/* mask interrupt */
+	__raw_writel(INTC_BIT(irq), INTC_SR(irq));	/* clear interrupt status */
+}
+
+static int pnx4008_set_irq_type(unsigned int irq, unsigned int type)
+{
+	switch (type) {
+	case IRQT_RISING:
+		__raw_writel(__raw_readl(INTC_ATR(irq)) | INTC_BIT(irq), INTC_ATR(irq));	/*edge sensitive */
+		__raw_writel(__raw_readl(INTC_APR(irq)) | INTC_BIT(irq), INTC_APR(irq));	/*rising edge */
+		set_irq_handler(irq, do_edge_IRQ);
+		break;
+	case IRQT_FALLING:
+		__raw_writel(__raw_readl(INTC_ATR(irq)) | INTC_BIT(irq), INTC_ATR(irq));	/*edge sensitive */
+		__raw_writel(__raw_readl(INTC_APR(irq)) & ~INTC_BIT(irq), INTC_APR(irq));	/*falling edge */
+		set_irq_handler(irq, do_edge_IRQ);
+		break;
+	case IRQT_LOW:
+		__raw_writel(__raw_readl(INTC_ATR(irq)) & ~INTC_BIT(irq), INTC_ATR(irq));	/*level sensitive */
+		__raw_writel(__raw_readl(INTC_APR(irq)) & ~INTC_BIT(irq), INTC_APR(irq));	/*low level */
+		set_irq_handler(irq, do_level_IRQ);
+		break;
+	case IRQT_HIGH:
+		__raw_writel(__raw_readl(INTC_ATR(irq)) & ~INTC_BIT(irq), INTC_ATR(irq));	/*level sensitive */
+		__raw_writel(__raw_readl(INTC_APR(irq)) | INTC_BIT(irq), INTC_APR(irq));	/* high level */
+		set_irq_handler(irq, do_level_IRQ);
+		break;
+
+	/* IRQT_BOTHEDGE is not supported */
+	default:
+		printk(KERN_ERR "PNX4008 IRQ: Unsupported irq type %d\n", type);
+		return -1;
+	}
+	return 0;
+}
+
+static struct irqchip pnx4008_irq_chip = {
+	.ack = pnx4008_mask_ack_irq,
+	.mask = pnx4008_mask_irq,
+	.unmask = pnx4008_unmask_irq,
+	.set_type = pnx4008_set_irq_type,
+};
+
+void __init pnx4008_init_irq(void)
+{
+	unsigned int i;
+
+	/* configure IRQ's */
+	for (i = 0; i < NR_IRQS; i++) {
+		set_irq_flags(i, IRQF_VALID);
+		set_irq_chip(i, &pnx4008_irq_chip);
+		pnx4008_set_irq_type(i, pnx4008_irq_type[i]);
+	}
+
+	/* configure and enable IRQ 0,1,30,31 (cascade interrupts) */
+	pnx4008_set_irq_type(SUB1_IRQ_N, pnx4008_irq_type[SUB1_IRQ_N]);
+	pnx4008_set_irq_type(SUB2_IRQ_N, pnx4008_irq_type[SUB2_IRQ_N]);
+	pnx4008_set_irq_type(SUB1_FIQ_N, pnx4008_irq_type[SUB1_FIQ_N]);
+	pnx4008_set_irq_type(SUB2_FIQ_N, pnx4008_irq_type[SUB2_FIQ_N]);
+
+	/* mask all others */
+	__raw_writel((1 << SUB2_FIQ_N) | (1 << SUB1_FIQ_N) |
+			(1 << SUB2_IRQ_N) | (1 << SUB1_IRQ_N),
+		INTC_ER(MAIN_BASE_INT));
+	__raw_writel(0, INTC_ER(SIC1_BASE_INT));
+	__raw_writel(0, INTC_ER(SIC2_BASE_INT));
+}
+
diff --git a/arch/arm/mach-pnx4008/pm.c b/arch/arm/mach-pnx4008/pm.c
new file mode 100644
index 000000000..3649cd3df
--- /dev/null
+++ b/arch/arm/mach-pnx4008/pm.c
@@ -0,0 +1,184 @@
+/*
+ * arch/arm/mach-pnx4008/pm.c
+ *
+ * Power Management driver for PNX4008
+ *
+ * Authors: Vitaly Wool, Dmitry Chigirev <source@mvista.com>
+ *
+ * 2005 (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.
+ */
+
+#include <linux/pm.h>
+#include <linux/rtc.h>
+#include <linux/sched.h>
+#include <linux/proc_fs.h>
+#include <linux/pm.h>
+#include <linux/delay.h>
+#include <linux/clk.h>
+
+#include <asm/io.h>
+#include <asm/mach-types.h>
+#include <asm/cacheflush.h>
+#include <asm/arch/pm.h>
+#include <asm/arch/clock.h>
+
+#define SRAM_VA IO_ADDRESS(PNX4008_IRAM_BASE)
+
+static void *saved_sram;
+
+static struct clk *pll4_clk;
+
+static inline void pnx4008_standby(void)
+{
+	void (*pnx4008_cpu_standby_ptr) (void);
+
+	local_irq_disable();
+	local_fiq_disable();
+
+	clk_disable(pll4_clk);
+
+	/*saving portion of SRAM to be used by suspend function. */
+	memcpy(saved_sram, (void *)SRAM_VA, pnx4008_cpu_standby_sz);
+
+	/*make sure SRAM copy gets physically written into SDRAM.
+	   SDRAM will be placed into self-refresh during power down */
+	flush_cache_all();
+
+	/*copy suspend function into SRAM */
+	memcpy((void *)SRAM_VA, pnx4008_cpu_standby, pnx4008_cpu_standby_sz);
+
+	/*do suspend */
+	pnx4008_cpu_standby_ptr = (void *)SRAM_VA;
+	pnx4008_cpu_standby_ptr();
+
+	/*restoring portion of SRAM that was used by suspend function */
+	memcpy((void *)SRAM_VA, saved_sram, pnx4008_cpu_standby_sz);
+
+	clk_enable(pll4_clk);
+
+	local_fiq_enable();
+	local_irq_enable();
+}
+
+static inline void pnx4008_suspend(void)
+{
+	void (*pnx4008_cpu_suspend_ptr) (void);
+
+	local_irq_disable();
+	local_fiq_disable();
+
+	clk_disable(pll4_clk);
+
+	__raw_writel(0xffffffff, START_INT_RSR_REG(SE_PIN_BASE_INT));
+	__raw_writel(0xffffffff, START_INT_RSR_REG(SE_INT_BASE_INT));
+
+	/*saving portion of SRAM to be used by suspend function. */
+	memcpy(saved_sram, (void *)SRAM_VA, pnx4008_cpu_suspend_sz);
+
+	/*make sure SRAM copy gets physically written into SDRAM.
+	   SDRAM will be placed into self-refresh during power down */
+	flush_cache_all();
+
+	/*copy suspend function into SRAM */
+	memcpy((void *)SRAM_VA, pnx4008_cpu_suspend, pnx4008_cpu_suspend_sz);
+
+	/*do suspend */
+	pnx4008_cpu_suspend_ptr = (void *)SRAM_VA;
+	pnx4008_cpu_suspend_ptr();
+
+	/*restoring portion of SRAM that was used by suspend function */
+	memcpy((void *)SRAM_VA, saved_sram, pnx4008_cpu_suspend_sz);
+
+	clk_enable(pll4_clk);
+
+	local_fiq_enable();
+	local_irq_enable();
+}
+
+static int pnx4008_pm_enter(suspend_state_t state)
+{
+	switch (state) {
+	case PM_SUSPEND_STANDBY:
+		pnx4008_standby();
+		break;
+	case PM_SUSPEND_MEM:
+		pnx4008_suspend();
+		break;
+	case PM_SUSPEND_DISK:
+		return -ENOTSUPP;
+	default:
+		return -EINVAL;
+	}
+	return 0;
+}
+
+/*
+ * Called after processes are frozen, but before we shut down devices.
+ */
+static int pnx4008_pm_prepare(suspend_state_t state)
+{
+	switch (state) {
+	case PM_SUSPEND_STANDBY:
+	case PM_SUSPEND_MEM:
+		break;
+
+	case PM_SUSPEND_DISK:
+		return -ENOTSUPP;
+		break;
+
+	default:
+		return -EINVAL;
+		break;
+	}
+	return 0;
+}
+
+/*
+ * Called after devices are re-setup, but before processes are thawed.
+ */
+static int pnx4008_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 pnx4008_pm_ops = {
+	.prepare = pnx4008_pm_prepare,
+	.enter = pnx4008_pm_enter,
+	.finish = pnx4008_pm_finish,
+};
+
+static int __init pnx4008_pm_init(void)
+{
+	u32 sram_size_to_allocate;
+
+	pll4_clk = clk_get(0, "ck_pll4");
+	if (IS_ERR(pll4_clk)) {
+		printk(KERN_ERR
+		       "PM Suspend cannot acquire ARM(PLL4) clock control\n");
+		return PTR_ERR(pll4_clk);
+	}
+
+	if (pnx4008_cpu_standby_sz > pnx4008_cpu_suspend_sz)
+		sram_size_to_allocate = pnx4008_cpu_standby_sz;
+	else
+		sram_size_to_allocate = pnx4008_cpu_suspend_sz;
+
+	saved_sram = kmalloc(sram_size_to_allocate, GFP_ATOMIC);
+	if (!saved_sram) {
+		printk(KERN_ERR
+		       "PM Suspend: cannot allocate memory to save portion of SRAM\n");
+		clk_put(pll4_clk);
+		return -ENOMEM;
+	}
+
+	pm_set_ops(&pnx4008_pm_ops);
+	return 0;
+}
+
+late_initcall(pnx4008_pm_init);
diff --git a/arch/arm/mach-pnx4008/serial.c b/arch/arm/mach-pnx4008/serial.c
new file mode 100644
index 000000000..95a1b3f96
--- /dev/null
+++ b/arch/arm/mach-pnx4008/serial.c
@@ -0,0 +1,69 @@
+/*
+ *  linux/arch/arm/mach-pnx4008/serial.c
+ *
+ *  PNX4008 UART initialization
+ *
+ *  Copyright:	MontaVista Software Inc. (c) 2005
+ *
+ *  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 <asm/io.h>
+
+#include <asm/arch/platform.h>
+#include <asm/hardware.h>
+
+#include <linux/serial_core.h>
+#include <linux/serial_reg.h>
+#include <asm/arch/gpio.h>
+
+#include <asm/arch/clock.h>
+
+#define UART_3		0
+#define UART_4		1
+#define UART_5		2
+#define UART_6		3
+#define UART_UNKNOWN	(-1)
+
+#define UART3_BASE_VA	IO_ADDRESS(PNX4008_UART3_BASE)
+#define UART4_BASE_VA	IO_ADDRESS(PNX4008_UART4_BASE)
+#define UART5_BASE_VA	IO_ADDRESS(PNX4008_UART5_BASE)
+#define UART6_BASE_VA	IO_ADDRESS(PNX4008_UART6_BASE)
+
+#define UART_FCR_OFFSET		8
+#define UART_FIFO_SIZE		64
+
+void pnx4008_uart_init(void)
+{
+	u32 tmp;
+	int i = UART_FIFO_SIZE;
+
+	__raw_writel(0xC1, UART5_BASE_VA + UART_FCR_OFFSET);
+	__raw_writel(0xC1, UART3_BASE_VA + UART_FCR_OFFSET);
+
+	/* Send a NULL to fix the UART HW bug */
+	__raw_writel(0x00, UART5_BASE_VA);
+	__raw_writel(0x00, UART3_BASE_VA);
+
+	while (i--) {
+		tmp = __raw_readl(UART5_BASE_VA);
+		tmp = __raw_readl(UART3_BASE_VA);
+	}
+	__raw_writel(0, UART5_BASE_VA + UART_FCR_OFFSET);
+	__raw_writel(0, UART3_BASE_VA + UART_FCR_OFFSET);
+
+	/* setup wakeup interrupt */
+	start_int_set_rising_edge(SE_U3_RX_INT);
+	start_int_ack(SE_U3_RX_INT);
+	start_int_umask(SE_U3_RX_INT);
+
+	start_int_set_rising_edge(SE_U5_RX_INT);
+	start_int_ack(SE_U5_RX_INT);
+	start_int_umask(SE_U5_RX_INT);
+}
+
diff --git a/arch/arm/mach-pnx4008/sleep.S b/arch/arm/mach-pnx4008/sleep.S
new file mode 100644
index 000000000..fea1e17a3
--- /dev/null
+++ b/arch/arm/mach-pnx4008/sleep.S
@@ -0,0 +1,195 @@
+/*
+ * linux/arch/arm/mach-pnx4008/sleep.S
+ *
+ * PNX4008 support for STOP mode and SDRAM self-refresh
+ *
+ * Authors: Dmitry Chigirev, Vitaly Wool <source@mvista.com>
+ *
+ * 2005 (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.
+ */
+
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+#include <asm/hardware.h>
+
+#define PWRMAN_VA_BASE IO_ADDRESS(PNX4008_PWRMAN_BASE)
+#define PWR_CTRL_REG_OFFS 0x44
+
+#define SDRAM_CFG_VA_BASE IO_ADDRESS(PNX4008_SDRAM_CFG_BASE)
+#define MPMC_STATUS_REG_OFFS 0x4
+
+		.text
+
+ENTRY(pnx4008_cpu_suspend)
+	@this function should be entered in Direct run mode.
+
+	@ save registers on stack
+	stmfd	sp!, {r0 - r6, lr}
+
+	@ setup Power Manager base address in r4
+	@ and put it's value in r5
+	mov	r4, #(PWRMAN_VA_BASE & 0xff000000)
+	orr	r4, r4, #(PWRMAN_VA_BASE & 0x00ff0000)
+	orr	r4, r4, #(PWRMAN_VA_BASE & 0x0000ff00)
+	orr	r4, r4, #(PWRMAN_VA_BASE & 0x000000ff)
+	ldr	r5, [r4, #PWR_CTRL_REG_OFFS]
+
+	@ setup SDRAM controller base address in r2
+	@ and put it's value in r3
+	mov	r2, #(SDRAM_CFG_VA_BASE & 0xff000000)
+	orr	r2, r2, #(SDRAM_CFG_VA_BASE & 0x00ff0000)
+	orr	r2, r2, #(SDRAM_CFG_VA_BASE & 0x0000ff00)
+	orr	r2, r2, #(SDRAM_CFG_VA_BASE & 0x000000ff)
+	ldr	r3, [r2, #MPMC_STATUS_REG_OFFS] @extra read - HW bug workaround
+
+	@ clear SDRAM self-refresh bit latch
+	and	r5, r5, #(~(1 << 8))
+	@ clear SDRAM self-refresh bit
+	and	r5, r5, #(~(1 << 9))
+	str	r5, [r4, #PWR_CTRL_REG_OFFS]
+
+	@ do save current bit settings in r1
+	mov	r1, r5
+
+	@ set SDRAM self-refresh bit
+	orr	r5, r5, #(1 << 9)
+	str	r5, [r4, #PWR_CTRL_REG_OFFS]
+
+	@ set SDRAM self-refresh bit latch
+	orr	r5, r5, #(1 << 8)
+	str	r5, [r4, #PWR_CTRL_REG_OFFS]
+
+	@ clear SDRAM self-refresh bit latch
+	and	r5, r5, #(~(1 << 8))
+	str	r5, [r4, #PWR_CTRL_REG_OFFS]
+
+	@ clear SDRAM self-refresh bit
+	and	r5, r5, #(~(1 << 9))
+	str	r5, [r4, #PWR_CTRL_REG_OFFS]
+
+	@ wait for SDRAM to get into self-refresh mode
+2:	ldr	r3, [r2, #MPMC_STATUS_REG_OFFS]
+	tst	r3, #(1 << 2)
+	beq	2b
+
+	@ to prepare SDRAM to get out of self-refresh mode after wakeup
+	orr	r5, r5, #(1 << 7)
+	str	r5, [r4, #PWR_CTRL_REG_OFFS]
+
+	@ do enter stop mode
+	orr	r5, r5, #(1 << 0)
+	str	r5, [r4, #PWR_CTRL_REG_OFFS]
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+
+	@ sleeping now...
+
+	@ coming out of STOP mode into Direct Run mode
+	@ clear STOP mode and SDRAM self-refresh bits
+	str	r1, [r4, #PWR_CTRL_REG_OFFS]
+
+	@ wait for SDRAM to get out self-refresh mode
+3:	ldr	r3, [r2, #MPMC_STATUS_REG_OFFS]
+	tst	r3, #5
+	bne	3b
+
+	@ restore regs and return
+	ldmfd   sp!, {r0 - r6, pc}
+
+ENTRY(pnx4008_cpu_suspend_sz)
+	.word	. - pnx4008_cpu_suspend
+
+ENTRY(pnx4008_cpu_standby)
+	@ save registers on stack
+	stmfd	sp!, {r0 - r6, lr}
+
+	@ setup Power Manager base address in r4
+	@ and put it's value in r5
+	mov	r4, #(PWRMAN_VA_BASE & 0xff000000)
+	orr	r4, r4, #(PWRMAN_VA_BASE & 0x00ff0000)
+	orr	r4, r4, #(PWRMAN_VA_BASE & 0x0000ff00)
+	orr	r4, r4, #(PWRMAN_VA_BASE & 0x000000ff)
+	ldr	r5, [r4, #PWR_CTRL_REG_OFFS]
+
+	@ setup SDRAM controller base address in r2
+	@ and put it's value in r3
+	mov	r2, #(SDRAM_CFG_VA_BASE & 0xff000000)
+	orr	r2, r2, #(SDRAM_CFG_VA_BASE & 0x00ff0000)
+	orr	r2, r2, #(SDRAM_CFG_VA_BASE & 0x0000ff00)
+	orr	r2, r2, #(SDRAM_CFG_VA_BASE & 0x000000ff)
+	ldr	r3, [r2, #MPMC_STATUS_REG_OFFS] @extra read - HW bug workaround
+
+	@ clear SDRAM self-refresh bit latch
+	and	r5, r5, #(~(1 << 8))
+	@ clear SDRAM self-refresh bit
+	and	r5, r5, #(~(1 << 9))
+	str	r5, [r4, #PWR_CTRL_REG_OFFS]
+
+	@ do save current bit settings in r1
+	mov	r1, r5
+
+	@ set SDRAM self-refresh bit
+	orr	r5, r5, #(1 << 9)
+	str	r5, [r4, #PWR_CTRL_REG_OFFS]
+
+	@ set SDRAM self-refresh bit latch
+	orr	r5, r5, #(1 << 8)
+	str	r5, [r4, #PWR_CTRL_REG_OFFS]
+
+	@ clear SDRAM self-refresh bit latch
+	and	r5, r5, #(~(1 << 8))
+	str	r5, [r4, #PWR_CTRL_REG_OFFS]
+
+	@ clear SDRAM self-refresh bit
+	and	r5, r5, #(~(1 << 9))
+	str	r5, [r4, #PWR_CTRL_REG_OFFS]
+
+	@ wait for SDRAM to get into self-refresh mode
+2:	ldr	r3, [r2, #MPMC_STATUS_REG_OFFS]
+	tst	r3, #(1 << 2)
+	beq	2b
+
+	@ set 'get out of self-refresh mode after wakeup' bit
+	orr	r5, r5, #(1 << 7)
+	str	r5, [r4, #PWR_CTRL_REG_OFFS]
+
+	mcr     p15, 0, r0, c7, c0, 4	@ kinda sleeping now...
+
+	@ set SDRAM self-refresh bit latch
+	orr	r5, r5, #(1 << 8)
+	str	r5, [r4, #PWR_CTRL_REG_OFFS]
+
+	@ clear SDRAM self-refresh bit latch
+	and	r5, r5, #(~(1 << 8))
+	str	r5, [r4, #PWR_CTRL_REG_OFFS]
+
+	@ wait for SDRAM to get out self-refresh mode
+3:	ldr	r3, [r2, #MPMC_STATUS_REG_OFFS]
+	tst	r3, #5
+	bne	3b
+
+	@ restore regs and return
+	ldmfd   sp!, {r0 - r6, pc}
+
+ENTRY(pnx4008_cpu_standby_sz)
+	.word	. - pnx4008_cpu_standby
+
+ENTRY(pnx4008_cache_clean_invalidate)
+	stmfd	sp!, {r0 - r6, lr}
+#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
+	mcr	p15, 0, ip, c7, c6, 0		@ invalidate D cache
+#else
+1:	mrc	p15, 0, r15, c7, c14, 3		@ test,clean,invalidate
+	bne     1b
+#endif
+	ldmfd   sp!, {r0 - r6, pc}
diff --git a/arch/arm/mach-pnx4008/time.c b/arch/arm/mach-pnx4008/time.c
new file mode 100644
index 000000000..b986065cd
--- /dev/null
+++ b/arch/arm/mach-pnx4008/time.c
@@ -0,0 +1,138 @@
+/*
+ * arch/arm/mach-pnx4008/time.c
+ *
+ * PNX4008 Timers
+ *
+ * Authors: Vitaly Wool, Dmitry Chigirev, Grigory Tolstolytkin <source@mvista.com>
+ *
+ * 2005 (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.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/sched.h>
+#include <linux/spinlock.h>
+#include <linux/module.h>
+#include <linux/kallsyms.h>
+#include <linux/time.h>
+#include <linux/timex.h>
+#include <linux/irq.h>
+
+#include <asm/system.h>
+#include <asm/hardware.h>
+#include <asm/io.h>
+#include <asm/leds.h>
+#include <asm/mach/time.h>
+#include <asm/errno.h>
+
+/*! Note: all timers are UPCOUNTING */
+
+/*!
+ * Returns number of us since last clock interrupt.  Note that interrupts
+ * will have been disabled by do_gettimeoffset()
+ */
+static unsigned long pnx4008_gettimeoffset(void)
+{
+	u32 ticks_to_match =
+	    __raw_readl(HSTIM_MATCH0) - __raw_readl(HSTIM_COUNTER);
+	u32 elapsed = LATCH - ticks_to_match;
+	return (elapsed * (tick_nsec / 1000)) / LATCH;
+}
+
+/*!
+ * IRQ handler for the timer
+ */
+static irqreturn_t pnx4008_timer_interrupt(int irq, void *dev_id,
+					   struct pt_regs *regs)
+{
+	if (__raw_readl(HSTIM_INT) & MATCH0_INT) {
+
+		write_seqlock(&xtime_lock);
+
+		do {
+			timer_tick(regs);
+
+			/*
+			 * this algorithm takes care of possible delay
+			 * for this interrupt handling longer than a normal
+			 * timer period
+			 */
+			__raw_writel(__raw_readl(HSTIM_MATCH0) + LATCH,
+				     HSTIM_MATCH0);
+			__raw_writel(MATCH0_INT, HSTIM_INT);	/* clear interrupt */
+
+			/*
+			 * The goal is to keep incrementing HSTIM_MATCH0
+			 * register until HSTIM_MATCH0 indicates time after
+			 * what HSTIM_COUNTER indicates.
+			 */
+		} while ((signed)
+			 (__raw_readl(HSTIM_MATCH0) -
+			  __raw_readl(HSTIM_COUNTER)) < 0);
+
+		write_sequnlock(&xtime_lock);
+	}
+
+	return IRQ_HANDLED;
+}
+
+static struct irqaction pnx4008_timer_irq = {
+	.name = "PNX4008 Tick Timer",
+	.flags = IRQF_DISABLED | IRQF_TIMER,
+	.handler = pnx4008_timer_interrupt
+};
+
+/*!
+ * Set up timer and timer interrupt.
+ */
+static __init void pnx4008_setup_timer(void)
+{
+	__raw_writel(RESET_COUNT, MSTIM_CTRL);
+	while (__raw_readl(MSTIM_COUNTER)) ;	/* wait for reset to complete. 100% guarantee event */
+	__raw_writel(0, MSTIM_CTRL);	/* stop the timer */
+	__raw_writel(0, MSTIM_MCTRL);
+
+	__raw_writel(RESET_COUNT, HSTIM_CTRL);
+	while (__raw_readl(HSTIM_COUNTER)) ;	/* wait for reset to complete. 100% guarantee event */
+	__raw_writel(0, HSTIM_CTRL);
+	__raw_writel(0, HSTIM_MCTRL);
+	__raw_writel(0, HSTIM_CCR);
+	__raw_writel(12, HSTIM_PMATCH);	/* scale down to 1 MHZ */
+	__raw_writel(LATCH, HSTIM_MATCH0);
+	__raw_writel(MR0_INT, HSTIM_MCTRL);
+
+	setup_irq(HSTIMER_INT, &pnx4008_timer_irq);
+
+	__raw_writel(COUNT_ENAB | DEBUG_EN, HSTIM_CTRL);	/*start timer, stop when JTAG active */
+}
+
+/* Timer Clock Control in PM register */
+#define TIMCLK_CTRL_REG  IO_ADDRESS((PNX4008_PWRMAN_BASE + 0xBC))
+#define WATCHDOG_CLK_EN                   1
+#define TIMER_CLK_EN                      2	/* HS and MS timers? */
+
+static u32 timclk_ctrl_reg_save;
+
+void pnx4008_timer_suspend(void)
+{
+	timclk_ctrl_reg_save = __raw_readl(TIMCLK_CTRL_REG);
+	__raw_writel(0, TIMCLK_CTRL_REG);	/* disable timers */
+}
+
+void pnx4008_timer_resume(void)
+{
+	__raw_writel(timclk_ctrl_reg_save, TIMCLK_CTRL_REG);	/* enable timers */
+}
+
+struct sys_timer pnx4008_timer = {
+	.init = pnx4008_setup_timer,
+	.offset = pnx4008_gettimeoffset,
+	.suspend = pnx4008_timer_suspend,
+	.resume = pnx4008_timer_resume,
+};
+
diff --git a/arch/arm/mach-pxa/leds-trizeps4.c b/arch/arm/mach-pxa/leds-trizeps4.c
new file mode 100644
index 000000000..2271d20ff
--- /dev/null
+++ b/arch/arm/mach-pxa/leds-trizeps4.c
@@ -0,0 +1,133 @@
+/*
+ * linux/arch/arm/mach-pxa/leds-trizeps4.c
+ *
+ *  Author:	Jürgen Schindele
+ *  Created:	20 02, 2006
+ *  Copyright:	Jürgen Schindele
+ *
+ * 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 <asm/hardware.h>
+#include <asm/system.h>
+#include <asm/types.h>
+#include <asm/leds.h>
+
+#include <asm/arch/pxa-regs.h>
+#include <asm/arch/trizeps4.h>
+
+#include "leds.h"
+
+#define LED_STATE_ENABLED	1
+#define LED_STATE_CLAIMED	2
+
+#define SYS_BUSY		0x01
+#define HEARTBEAT		0x02
+#define BLINK			0x04
+
+static unsigned int led_state;
+static unsigned int hw_led_state;
+
+void trizeps4_leds_event(led_event_t evt)
+{
+	unsigned long flags;
+
+	local_irq_save(flags);
+
+	switch (evt) {
+	case led_start:
+		hw_led_state = 0;
+		pxa_gpio_mode( GPIO_SYS_BUSY_LED  | GPIO_OUT);		/* LED1 */
+		pxa_gpio_mode( GPIO_HEARTBEAT_LED | GPIO_OUT);		/* LED2 */
+		led_state = LED_STATE_ENABLED;
+		break;
+
+	case led_stop:
+		led_state &= ~LED_STATE_ENABLED;
+		break;
+
+	case led_claim:
+		led_state |= LED_STATE_CLAIMED;
+		hw_led_state = 0;
+		break;
+
+	case led_release:
+		led_state &= ~LED_STATE_CLAIMED;
+		hw_led_state = 0;
+		break;
+
+#ifdef CONFIG_LEDS_TIMER
+	case led_timer:
+		hw_led_state ^= HEARTBEAT;
+		break;
+#endif
+
+#ifdef CONFIG_LEDS_CPU
+	case led_idle_start:
+		hw_led_state &= ~SYS_BUSY;
+		break;
+
+	case led_idle_end:
+		hw_led_state |= SYS_BUSY;
+		break;
+#endif
+
+	case led_halted:
+		break;
+
+	case led_green_on:
+		hw_led_state |= BLINK;
+		break;
+
+	case led_green_off:
+		hw_led_state &= ~BLINK;
+		break;
+
+	case led_amber_on:
+		break;
+
+	case led_amber_off:
+		break;
+
+	case led_red_on:
+		break;
+
+	case led_red_off:
+		break;
+
+	default:
+		break;
+	}
+
+	if  (led_state & LED_STATE_ENABLED) {
+		switch (hw_led_state) {
+			case 0:
+				GPSR(GPIO_SYS_BUSY_LED)  |= GPIO_bit(GPIO_SYS_BUSY_LED);
+				GPSR(GPIO_HEARTBEAT_LED) |= GPIO_bit(GPIO_HEARTBEAT_LED);
+				break;
+			case 1:
+				GPCR(GPIO_SYS_BUSY_LED)  |= GPIO_bit(GPIO_SYS_BUSY_LED);
+				GPSR(GPIO_HEARTBEAT_LED) |= GPIO_bit(GPIO_HEARTBEAT_LED);
+				break;
+			case 2:
+				GPSR(GPIO_SYS_BUSY_LED)  |= GPIO_bit(GPIO_SYS_BUSY_LED);
+				GPCR(GPIO_HEARTBEAT_LED) |= GPIO_bit(GPIO_HEARTBEAT_LED);
+				break;
+			case 3:
+				GPCR(GPIO_SYS_BUSY_LED)  |= GPIO_bit(GPIO_SYS_BUSY_LED);
+				GPCR(GPIO_HEARTBEAT_LED) |= GPIO_bit(GPIO_HEARTBEAT_LED);
+				break;
+		}
+	}
+	else {
+		/* turn all off */
+		GPSR(GPIO_SYS_BUSY_LED)  |= GPIO_bit(GPIO_SYS_BUSY_LED);
+		GPSR(GPIO_HEARTBEAT_LED) |= GPIO_bit(GPIO_HEARTBEAT_LED);
+	}
+
+	local_irq_restore(flags);
+}
diff --git a/arch/arm/mach-pxa/trizeps4.c b/arch/arm/mach-pxa/trizeps4.c
new file mode 100644
index 000000000..7c3007df1
--- /dev/null
+++ b/arch/arm/mach-pxa/trizeps4.c
@@ -0,0 +1,473 @@
+/*
+ *  linux/arch/arm/mach-pxa/trizeps4.c
+ *
+ *  Support for the Keith und Koep Trizeps4 Module Platform.
+ *
+ *  Author:	Jürgen Schindele
+ *  Created:	20 02, 2006
+ *  Copyright:	Jürgen Schindele
+ *
+ *  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/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/sysdev.h>
+#include <linux/interrupt.h>
+#include <linux/sched.h>
+#include <linux/bitops.h>
+#include <linux/fb.h>
+#include <linux/ioport.h>
+#include <linux/delay.h>
+#include <linux/serial_8250.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+
+#include <asm/types.h>
+#include <asm/setup.h>
+#include <asm/memory.h>
+#include <asm/mach-types.h>
+#include <asm/hardware.h>
+#include <asm/irq.h>
+#include <asm/sizes.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+#include <asm/mach/flash.h>
+
+#include <asm/arch/pxa-regs.h>
+#include <asm/arch/trizeps4.h>
+#include <asm/arch/audio.h>
+#include <asm/arch/pxafb.h>
+#include <asm/arch/mmc.h>
+#include <asm/arch/irda.h>
+#include <asm/arch/ohci.h>
+
+#include "generic.h"
+
+/********************************************************************************************
+ * ONBOARD FLASH
+ ********************************************************************************************/
+static struct mtd_partition trizeps4_partitions[] = {
+	{
+		.name =		"Bootloader",
+		.size =		0x00040000,
+		.offset =	0,
+		.mask_flags =	MTD_WRITEABLE  /* force read-only */
+	},{
+		.name =		"Kernel",
+		.size =		0x00400000,
+		.offset =	0x00040000
+	},{
+		.name =		"Filesystem",
+		.size =		MTDPART_SIZ_FULL,
+		.offset =	0x00440000
+	}
+};
+
+static struct flash_platform_data trizeps4_flash_data[] = {
+	{
+		.map_name	= "cfi_probe",
+		.parts		= trizeps4_partitions,
+		.nr_parts	= ARRAY_SIZE(trizeps4_partitions)
+	}
+};
+
+static struct resource flash_resource = {
+	.start	= PXA_CS0_PHYS,
+	.end	= PXA_CS0_PHYS + SZ_64M - 1,
+	.flags	= IORESOURCE_MEM,
+};
+
+static struct platform_device flash_device = {
+	.name		= "pxa2xx-flash",
+	.id		= 0,
+	.dev = {
+		.platform_data = &trizeps4_flash_data,
+	},
+	.resource = &flash_resource,
+	.num_resources = 1,
+};
+
+/********************************************************************************************
+ * DAVICOM DM9000 Ethernet
+ ********************************************************************************************/
+static struct resource dm9000_resources[] = {
+	[0] = {
+		.start	= TRIZEPS4_ETH_PHYS+0x300,
+		.end	= TRIZEPS4_ETH_PHYS+0x400-1,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= TRIZEPS4_ETH_PHYS+0x8300,
+		.end	= TRIZEPS4_ETH_PHYS+0x8400-1,
+		.flags	= IORESOURCE_MEM,
+	},
+	[2] = {
+		.start	= TRIZEPS4_ETH_IRQ,
+		.end	= TRIZEPS4_ETH_IRQ,
+		.flags	= (IORESOURCE_IRQ | IRQT_RISING),
+	},
+};
+
+static struct platform_device dm9000_device = {
+	.name		= "dm9000",
+	.id		= -1,
+	.num_resources	= ARRAY_SIZE(dm9000_resources),
+	.resource	= dm9000_resources,
+};
+
+/********************************************************************************************
+ * PXA270 serial ports
+ ********************************************************************************************/
+static struct plat_serial8250_port tri_serial_ports[] = {
+#ifdef CONFIG_SERIAL_PXA
+	/* this uses the own PXA driver */
+	{
+		0,
+	},
+#else
+	/* this uses the generic 8520 driver */
+	[0] = {
+		.membase	= (void *)&FFUART,
+		.irq		= IRQ_FFUART,
+		.flags		= UPF_BOOT_AUTOCONF,
+		.iotype		= UPIO_MEM32,
+		.regshift	= 2,
+		.uartclk	= (921600*16),
+	},
+	[1] = {
+		.membase	= (void *)&BTUART,
+		.irq		= IRQ_BTUART,
+		.flags		= UPF_BOOT_AUTOCONF,
+		.iotype		= UPIO_MEM32,
+		.regshift	= 2,
+		.uartclk	= (921600*16),
+	},
+	{
+		0,
+	},
+#endif
+};
+
+static struct platform_device uart_devices = {
+	.name		= "serial8250",
+	.id		= 0,
+	.dev		= {
+		.platform_data	= tri_serial_ports,
+	},
+	.num_resources	= 0,
+	.resource	= NULL,
+};
+
+/********************************************************************************************
+ * PXA270 ac97 sound codec
+ ********************************************************************************************/
+static struct platform_device ac97_audio_device = {
+	.name		= "pxa2xx-ac97",
+	.id		= -1,
+};
+
+static struct platform_device * trizeps4_devices[] __initdata = {
+	&flash_device,
+	&uart_devices,
+	&dm9000_device,
+	&ac97_audio_device,
+};
+
+#ifdef CONFIG_MACH_TRIZEPS4_CONXS
+static short trizeps_conxs_bcr;
+
+/* PCCARD power switching supports only 3,3V */
+void board_pcmcia_power(int power)
+{
+	if (power) {
+		/* switch power on, put in reset and enable buffers */
+		trizeps_conxs_bcr |= power;
+		trizeps_conxs_bcr |= ConXS_BCR_CF_RESET;
+		trizeps_conxs_bcr &= ~(ConXS_BCR_CF_BUF_EN);
+		ConXS_BCR = trizeps_conxs_bcr;
+		/* wait a little */
+		udelay(2000);
+		/* take reset away */
+		trizeps_conxs_bcr &= ~(ConXS_BCR_CF_RESET);
+		ConXS_BCR = trizeps_conxs_bcr;
+		udelay(2000);
+	} else {
+		/* put in reset */
+		trizeps_conxs_bcr |= ConXS_BCR_CF_RESET;
+		ConXS_BCR = trizeps_conxs_bcr;
+		udelay(1000);
+		/* switch power off */
+		trizeps_conxs_bcr &= ~(0xf);
+		ConXS_BCR = trizeps_conxs_bcr;
+
+	}
+	pr_debug("%s: o%s 0x%x\n", __FUNCTION__, power ? "n": "ff", trizeps_conxs_bcr);
+}
+
+/* backlight power switching for LCD panel */
+static void board_backlight_power(int on)
+{
+	if (on) {
+		trizeps_conxs_bcr |= ConXS_BCR_L_DISP;
+	} else {
+		trizeps_conxs_bcr &= ~ConXS_BCR_L_DISP;
+	}
+	pr_debug("%s: o%s 0x%x\n", __FUNCTION__, on ? "n" : "ff", trizeps_conxs_bcr);
+	ConXS_BCR = trizeps_conxs_bcr;
+}
+
+/* Powersupply for MMC/SD cardslot */
+static void board_mci_power(struct device *dev, unsigned int vdd)
+{
+	struct pxamci_platform_data* p_d = dev->platform_data;
+
+	if (( 1 << vdd) & p_d->ocr_mask) {
+		pr_debug("%s: on\n", __FUNCTION__);
+		/* FIXME fill in values here */
+	} else {
+		pr_debug("%s: off\n", __FUNCTION__);
+		/* FIXME fill in values here */
+	}
+}
+
+static short trizeps_conxs_ircr;
+
+/* Switch modes and Power for IRDA receiver */
+static void board_irda_mode(struct device *dev, int mode)
+{
+	unsigned long flags;
+
+	local_irq_save(flags);
+	if (mode & IR_SIRMODE) {
+		/* Slow mode */
+		trizeps_conxs_ircr &= ~ConXS_IRCR_MODE;
+	} else if (mode & IR_FIRMODE) {
+		/* Fast mode */
+		trizeps_conxs_ircr |= ConXS_IRCR_MODE;
+	}
+	if (mode & IR_OFF) {
+		trizeps_conxs_ircr |= ConXS_IRCR_SD;
+	} else {
+		trizeps_conxs_ircr &= ~ConXS_IRCR_SD;
+	}
+	/* FIXME write values to register */
+	local_irq_restore(flags);
+}
+
+#else
+/* for other baseboards define dummies */
+void board_pcmcia_power(int power)	{;}
+#define board_backlight_power		NULL
+#define board_mci_power			NULL
+#define board_irda_mode			NULL
+
+#endif		/* CONFIG_MACH_TRIZEPS4_CONXS */
+EXPORT_SYMBOL(board_pcmcia_power);
+
+static int trizeps4_mci_init(struct device *dev, irqreturn_t (*mci_detect_int)(int, void *, struct pt_regs *), void *data)
+{
+	int err;
+	/* setup GPIO for PXA27x MMC controller */
+	pxa_gpio_mode(GPIO32_MMCCLK_MD);
+	pxa_gpio_mode(GPIO112_MMCCMD_MD);
+	pxa_gpio_mode(GPIO92_MMCDAT0_MD);
+	pxa_gpio_mode(GPIO109_MMCDAT1_MD);
+	pxa_gpio_mode(GPIO110_MMCDAT2_MD);
+	pxa_gpio_mode(GPIO111_MMCDAT3_MD);
+
+	pxa_gpio_mode(GPIO_MMC_DET | GPIO_IN);
+
+	err = request_irq(TRIZEPS4_MMC_IRQ, mci_detect_int,
+			  IRQF_DISABLED | IRQF_TRIGGER_RISING,
+			  "MMC card detect", data);
+	if (err) {
+		printk(KERN_ERR "trizeps4_mci_init: MMC/SD: can't request MMC card detect IRQ\n");
+		return -1;
+	}
+	return 0;
+}
+
+static void trizeps4_mci_exit(struct device *dev, void *data)
+{
+	free_irq(TRIZEPS4_MMC_IRQ, data);
+}
+
+static struct pxamci_platform_data trizeps4_mci_platform_data = {
+	.ocr_mask	= MMC_VDD_32_33|MMC_VDD_33_34,
+	.init 		= trizeps4_mci_init,
+	.exit		= trizeps4_mci_exit,
+	.setpower 	= board_mci_power,
+};
+
+static struct pxaficp_platform_data trizeps4_ficp_platform_data = {
+	.transceiver_cap  = IR_SIRMODE | IR_FIRMODE | IR_OFF,
+	.transceiver_mode = board_irda_mode,
+};
+
+static int trizeps4_ohci_init(struct device *dev)
+{
+	/* setup Port1 GPIO pin. */
+	pxa_gpio_mode( 88 | GPIO_ALT_FN_1_IN);	/* USBHPWR1 */
+	pxa_gpio_mode( 89 | GPIO_ALT_FN_2_OUT);	/* USBHPEN1 */
+
+	/* Set the Power Control Polarity Low and Power Sense
+	   Polarity Low to active low. */
+	UHCHR = (UHCHR | UHCHR_PCPL | UHCHR_PSPL) &
+		~(UHCHR_SSEP1 | UHCHR_SSEP2 | UHCHR_SSEP3 | UHCHR_SSE);
+
+	return 0;
+}
+
+static void trizeps4_ohci_exit(struct device *dev)
+{
+	;
+}
+
+static struct pxaohci_platform_data trizeps4_ohci_platform_data = {
+	.port_mode	= PMM_PERPORT_MODE,
+	.init		= trizeps4_ohci_init,
+	.exit		= trizeps4_ohci_exit,
+};
+
+static struct map_desc trizeps4_io_desc[] __initdata = {
+	{ 	/* ConXS CFSR */
+		.virtual	= TRIZEPS4_CFSR_VIRT,
+		.pfn		= __phys_to_pfn(TRIZEPS4_CFSR_PHYS),
+		.length		= 0x00001000,
+		.type		= MT_DEVICE
+	},
+	{	/* ConXS BCR */
+		.virtual	= TRIZEPS4_BOCR_VIRT,
+		.pfn		= __phys_to_pfn(TRIZEPS4_BOCR_PHYS),
+		.length		= 0x00001000,
+		.type		= MT_DEVICE
+	},
+	{ 	/* ConXS IRCR */
+		.virtual	= TRIZEPS4_IRCR_VIRT,
+		.pfn		= __phys_to_pfn(TRIZEPS4_IRCR_PHYS),
+		.length		= 0x00001000,
+		.type		= MT_DEVICE
+	},
+	{	/* ConXS DCR */
+		.virtual	= TRIZEPS4_DICR_VIRT,
+		.pfn		= __phys_to_pfn(TRIZEPS4_DICR_PHYS),
+		.length		= 0x00001000,
+		.type		= MT_DEVICE
+	},
+	{	/* ConXS UPSR */
+		.virtual	= TRIZEPS4_UPSR_VIRT,
+		.pfn		= __phys_to_pfn(TRIZEPS4_UPSR_PHYS),
+		.length		= 0x00001000,
+		.type		= MT_DEVICE
+	}
+};
+
+static struct pxafb_mach_info sharp_lcd __initdata = {
+    .pixclock		= 78000,
+    .xres		= 640,
+    .yres		= 480,
+    .bpp		= 8,
+    .hsync_len		= 4,
+    .left_margin	= 4,
+    .right_margin	= 4,
+    .vsync_len		= 2,
+    .upper_margin	= 0,
+    .lower_margin	= 0,
+    .sync		= FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+    .cmap_greyscale	= 0,
+    .cmap_inverse	= 0,
+    .cmap_static	= 0,
+    .lccr0		= LCCR0_Color | LCCR0_Pas | LCCR0_Dual,
+    .lccr3		= 0x0340ff02,
+    .pxafb_backlight_power = board_backlight_power,
+};
+
+static void __init trizeps4_fixup(struct machine_desc *desc, struct tag *tags, char **cmdline, struct meminfo *mi)
+{
+}
+
+static void __init trizeps4_init(void)
+{
+	platform_add_devices(trizeps4_devices, ARRAY_SIZE(trizeps4_devices));
+
+	set_pxa_fb_info(&sharp_lcd);
+
+	pxa_set_mci_info(&trizeps4_mci_platform_data);
+	pxa_set_ficp_info(&trizeps4_ficp_platform_data);
+	pxa_set_ohci_info(&trizeps4_ohci_platform_data);
+}
+
+static void __init trizeps4_map_io(void)
+{
+	pxa_map_io();
+	iotable_init(trizeps4_io_desc, ARRAY_SIZE(trizeps4_io_desc));
+
+	/* for DiskOnChip */
+	pxa_gpio_mode(GPIO15_nCS_1_MD);
+
+	/* for off-module PIC on ConXS board */
+	pxa_gpio_mode(GPIO_PIC | GPIO_IN);
+
+	/* UCB1400 irq */
+	pxa_gpio_mode(GPIO_UCB1400 | GPIO_IN);
+
+	/* for DM9000 LAN */
+	pxa_gpio_mode(GPIO78_nCS_2_MD);
+	pxa_gpio_mode(GPIO_DM9000 | GPIO_IN);
+
+	/* for PCMCIA device */
+	pxa_gpio_mode(GPIO_PCD | GPIO_IN);
+	pxa_gpio_mode(GPIO_PRDY | GPIO_IN);
+
+	/* for I2C adapter */
+	pxa_gpio_mode(GPIO117_I2CSCL_MD);
+	pxa_gpio_mode(GPIO118_I2CSDA_MD);
+
+	/* MMC_DET s.o. */
+	pxa_gpio_mode(GPIO_MMC_DET | GPIO_IN);
+
+	/* whats that for ??? */
+	pxa_gpio_mode(GPIO79_nCS_3_MD);
+
+	pxa_gpio_mode( GPIO_SYS_BUSY_LED  | GPIO_OUT);		/* LED1 */
+	pxa_gpio_mode( GPIO_HEARTBEAT_LED | GPIO_OUT);		/* LED2 */
+
+#ifdef CONFIG_MACH_TRIZEPS4_CONXS
+#ifdef CONFIG_IDE_PXA_CF
+	/* if boot direct from compact flash dont disable power */
+	trizeps_conxs_bcr = 0x0009;
+#else
+	/* this is the reset value */
+	trizeps_conxs_bcr = 0x00A0;
+#endif
+	ConXS_BCR = trizeps_conxs_bcr;
+#endif
+
+	PWER  = 0x00000002;
+	PFER  = 0x00000000;
+	PRER  = 0x00000002;
+	PGSR0 = 0x0158C000;
+	PGSR1 = 0x00FF0080;
+	PGSR2 = 0x0001C004;
+	/* Stop 3.6MHz and drive HIGH to PCMCIA and CS */
+	PCFR |= PCFR_OPDE;
+}
+
+MACHINE_START(TRIZEPS4, "Keith und Koep Trizeps IV module")
+	/* MAINTAINER("Jürgen Schindele") */
+	.phys_io	= 0x40000000,
+	.io_pg_offst	= (io_p2v(0x40000000) >> 18) & 0xfffc,
+	.boot_params	= TRIZEPS4_SDRAM_BASE + 0x100,
+	.fixup		= trizeps4_fixup,
+	.init_machine	= trizeps4_init,
+	.map_io		= trizeps4_map_io,
+	.init_irq	= pxa_init_irq,
+	.timer		= &pxa_timer,
+MACHINE_END
+
diff --git a/arch/arm/mach-s3c2410/mach-smdk2413.c b/arch/arm/mach-s3c2410/mach-smdk2413.c
new file mode 100644
index 000000000..3a4ca7f6f
--- /dev/null
+++ b/arch/arm/mach-s3c2410/mach-smdk2413.c
@@ -0,0 +1,139 @@
+/* linux/arch/arm/mach-s3c2410/mach-smdk2413.c
+ *
+ * Copyright (c) 2006 Simtec Electronics
+ *	Ben Dooks <ben@simtec.co.uk>
+ *
+ * Thanks to Dimity Andric (TomTom) and Steven Ryu (Samsung) for the
+ * loans of SMDK2413 to work with.
+ *
+ * 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 <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#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>
+#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>
+
+#include <asm/arch/idle.h>
+#include <asm/arch/fb.h>
+
+#include "s3c2410.h"
+#include "s3c2412.h"
+#include "clock.h"
+#include "devs.h"
+#include "cpu.h"
+
+#include "common-smdk.h"
+
+static struct map_desc smdk2413_iodesc[] __initdata = {
+};
+
+static struct s3c2410_uartcfg smdk2413_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 *smdk2413_devices[] __initdata = {
+	&s3c_device_usb,
+	//&s3c_device_lcd,
+	&s3c_device_wdt,
+	&s3c_device_i2c,
+	&s3c_device_iis,
+};
+
+static struct s3c24xx_board smdk2413_board __initdata = {
+	.devices       = smdk2413_devices,
+	.devices_count = ARRAY_SIZE(smdk2413_devices)
+};
+
+static void __init smdk2413_fixup(struct machine_desc *desc,
+				  struct tag *tags, char **cmdline,
+				  struct meminfo *mi)
+{
+	if (tags != phys_to_virt(S3C2410_SDRAM_PA + 0x100)) {
+		mi->nr_banks=1;
+		mi->bank[0].start = 0x30000000;
+		mi->bank[0].size = SZ_64M;
+		mi->bank[0].node = 0;
+	}
+}
+
+static void __init smdk2413_map_io(void)
+{
+	s3c24xx_init_io(smdk2413_iodesc, ARRAY_SIZE(smdk2413_iodesc));
+	s3c24xx_init_clocks(12000000);
+	s3c24xx_init_uarts(smdk2413_uartcfgs, ARRAY_SIZE(smdk2413_uartcfgs));
+	s3c24xx_set_board(&smdk2413_board);
+}
+
+static void __init smdk2413_machine_init(void)
+{
+	smdk_machine_init();
+}
+
+MACHINE_START(S3C2413, "S3C2413")
+	/* 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,
+	.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
diff --git a/arch/arm/mach-s3c2410/s3c2410-clock.c b/arch/arm/mach-s3c2410/s3c2410-clock.c
new file mode 100644
index 000000000..997186633
--- /dev/null
+++ b/arch/arm/mach-s3c2410/s3c2410-clock.c
@@ -0,0 +1,271 @@
+/* linux/arch/arm/mach-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 <asm/hardware.h>
+#include <asm/io.h>
+
+#include <asm/arch/regs-clock.h>
+#include <asm/arch/regs-gpio.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/s3c2412-clock.c b/arch/arm/mach-s3c2410/s3c2412-clock.c
new file mode 100644
index 000000000..c95ed3e18
--- /dev/null
+++ b/arch/arm/mach-s3c2410/s3c2412-clock.c
@@ -0,0 +1,711 @@
+/* linux/arch/arm/mach-s3c2410/s3c2412-clock.c
+ *
+ * Copyright (c) 2006 Simtec Electronics
+ *	Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C2412,S3C2413 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 <asm/hardware.h>
+#include <asm/io.h>
+
+#include <asm/arch/regs-clock.h>
+#include <asm/arch/regs-gpio.h>
+
+#include "clock.h"
+#include "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
+*/
+
+int s3c2412_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;
+
+	__raw_writel(clkcon, S3C2410_CLKCON);
+
+	return 0;
+}
+
+static int s3c2412_upll_enable(struct clk *clk, int enable)
+{
+	unsigned long upllcon = __raw_readl(S3C2410_UPLLCON);
+	unsigned long orig = upllcon;
+
+	if (!enable)
+		upllcon |= S3C2412_PLLCON_OFF;
+	else
+		upllcon &= ~S3C2412_PLLCON_OFF;
+
+	__raw_writel(upllcon, S3C2410_UPLLCON);
+
+	/* allow ~150uS for the PLL to settle and lock */
+
+	if (enable && (orig & S3C2412_PLLCON_OFF))
+		udelay(150);
+
+	return 0;
+}
+
+/* clock selections */
+
+/* CPU EXTCLK input */
+static struct clk clk_ext = {
+	.name		= "extclk",
+	.id		= -1,
+};
+
+static struct clk clk_erefclk = {
+	.name		= "erefclk",
+	.id		= -1,
+};
+
+static struct clk clk_urefclk = {
+	.name		= "urefclk",
+	.id		= -1,
+};
+
+static int s3c2412_setparent_usysclk(struct clk *clk, struct clk *parent)
+{
+	unsigned long clksrc = __raw_readl(S3C2412_CLKSRC);
+
+	if (parent == &clk_urefclk)
+		clksrc &= ~S3C2412_CLKSRC_USYSCLK_UPLL;
+	else if (parent == &clk_upll)
+		clksrc |= S3C2412_CLKSRC_USYSCLK_UPLL;
+	else
+		return -EINVAL;
+
+	clk->parent = parent;
+
+	__raw_writel(clksrc, S3C2412_CLKSRC);
+	return 0;
+}
+
+static struct clk clk_usysclk = {
+	.name		= "usysclk",
+	.id		= -1,
+	.parent		= &clk_xtal,
+	.set_parent	= s3c2412_setparent_usysclk,
+};
+
+static struct clk clk_mrefclk = {
+	.name		= "mrefclk",
+	.parent		= &clk_xtal,
+	.id		= -1,
+};
+
+static struct clk clk_mdivclk = {
+	.name		= "mdivclk",
+	.parent		= &clk_xtal,
+	.id		= -1,
+};
+
+static int s3c2412_setparent_usbsrc(struct clk *clk, struct clk *parent)
+{
+	unsigned long clksrc = __raw_readl(S3C2412_CLKSRC);
+
+	if (parent == &clk_usysclk)
+		clksrc &= ~S3C2412_CLKSRC_USBCLK_HCLK;
+	else if (parent == &clk_h)
+		clksrc |= S3C2412_CLKSRC_USBCLK_HCLK;
+	else
+		return -EINVAL;
+
+	clk->parent = parent;
+
+	__raw_writel(clksrc, S3C2412_CLKSRC);
+	return 0;
+}
+
+static unsigned long s3c2412_roundrate_usbsrc(struct clk *clk,
+					      unsigned long rate)
+{
+	unsigned long parent_rate = clk_get_rate(clk->parent);
+	int div;
+
+	if (rate > parent_rate)
+		return parent_rate;
+
+	div = parent_rate / rate;
+	if (div > 2)
+		div = 2;
+
+	return parent_rate / div;
+}
+
+static unsigned long s3c2412_getrate_usbsrc(struct clk *clk)
+{
+	unsigned long parent_rate = clk_get_rate(clk->parent);
+	unsigned long div = __raw_readl(S3C2410_CLKDIVN);
+
+	return parent_rate / ((div & S3C2412_CLKDIVN_USB48DIV) ? 2 : 1);
+}
+
+static int s3c2412_setrate_usbsrc(struct clk *clk, unsigned long rate)
+{
+	unsigned long parent_rate = clk_get_rate(clk->parent);
+	unsigned long clkdivn = __raw_readl(S3C2410_CLKDIVN);
+
+	rate = s3c2412_roundrate_usbsrc(clk, rate);
+
+	if ((parent_rate / rate) == 2)
+		clkdivn |= S3C2412_CLKDIVN_USB48DIV;
+	else
+		clkdivn &= ~S3C2412_CLKDIVN_USB48DIV;
+
+	__raw_writel(clkdivn, S3C2410_CLKDIVN);
+	return 0;
+}
+
+static struct clk clk_usbsrc = {
+	.name		= "usbsrc",
+	.id		= -1,
+	.get_rate	= s3c2412_getrate_usbsrc,
+	.set_rate	= s3c2412_setrate_usbsrc,
+	.round_rate	= s3c2412_roundrate_usbsrc,
+	.set_parent	= s3c2412_setparent_usbsrc,
+};
+
+static int s3c2412_setparent_msysclk(struct clk *clk, struct clk *parent)
+{
+	unsigned long clksrc = __raw_readl(S3C2412_CLKSRC);
+
+	if (parent == &clk_mdivclk)
+		clksrc &= ~S3C2412_CLKSRC_MSYSCLK_MPLL;
+	else if (parent == &clk_upll)
+		clksrc |= S3C2412_CLKSRC_MSYSCLK_MPLL;
+	else
+		return -EINVAL;
+
+	clk->parent = parent;
+
+	__raw_writel(clksrc, S3C2412_CLKSRC);
+	return 0;
+}
+
+static struct clk clk_msysclk = {
+	.name		= "msysclk",
+	.id		= -1,
+	.set_parent	= s3c2412_setparent_msysclk,
+};
+
+/* these next clocks have an divider immediately after them,
+ * so we can register them with their divider and leave out the
+ * intermediate clock stage
+*/
+static unsigned long s3c2412_roundrate_clksrc(struct clk *clk,
+					      unsigned long rate)
+{
+	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 > 16)
+		div = 16;
+
+	return parent_rate / div;
+}
+
+static int s3c2412_setparent_uart(struct clk *clk, struct clk *parent)
+{
+	unsigned long clksrc = __raw_readl(S3C2412_CLKSRC);
+
+	if (parent == &clk_erefclk)
+		clksrc &= ~S3C2412_CLKSRC_UARTCLK_MPLL;
+	else if (parent == &clk_mpll)
+		clksrc |= S3C2412_CLKSRC_UARTCLK_MPLL;
+	else
+		return -EINVAL;
+
+	clk->parent = parent;
+
+	__raw_writel(clksrc, S3C2412_CLKSRC);
+	return 0;
+}
+
+static unsigned long s3c2412_getrate_uart(struct clk *clk)
+{
+	unsigned long parent_rate = clk_get_rate(clk->parent);
+	unsigned long div = __raw_readl(S3C2410_CLKDIVN);
+
+	div &= S3C2412_CLKDIVN_UARTDIV_MASK;
+	div >>= S3C2412_CLKDIVN_UARTDIV_SHIFT;
+
+	return parent_rate / (div + 1);
+}
+
+static int s3c2412_setrate_uart(struct clk *clk, unsigned long rate)
+{
+	unsigned long parent_rate = clk_get_rate(clk->parent);
+	unsigned long clkdivn = __raw_readl(S3C2410_CLKDIVN);
+
+	rate = s3c2412_roundrate_clksrc(clk, rate);
+
+	clkdivn &= ~S3C2412_CLKDIVN_UARTDIV_MASK;
+	clkdivn |= ((parent_rate / rate) - 1) << S3C2412_CLKDIVN_UARTDIV_SHIFT;
+
+	__raw_writel(clkdivn, S3C2410_CLKDIVN);
+	return 0;
+}
+
+static struct clk clk_uart = {
+	.name		= "uartclk",
+	.id		= -1,
+	.get_rate	= s3c2412_getrate_uart,
+	.set_rate	= s3c2412_setrate_uart,
+	.set_parent	= s3c2412_setparent_uart,
+	.round_rate	= s3c2412_roundrate_clksrc,
+};
+
+static int s3c2412_setparent_i2s(struct clk *clk, struct clk *parent)
+{
+	unsigned long clksrc = __raw_readl(S3C2412_CLKSRC);
+
+	if (parent == &clk_erefclk)
+		clksrc &= ~S3C2412_CLKSRC_I2SCLK_MPLL;
+	else if (parent == &clk_mpll)
+		clksrc |= S3C2412_CLKSRC_I2SCLK_MPLL;
+	else
+		return -EINVAL;
+
+	clk->parent = parent;
+
+	__raw_writel(clksrc, S3C2412_CLKSRC);
+	return 0;
+}
+
+static unsigned long s3c2412_getrate_i2s(struct clk *clk)
+{
+	unsigned long parent_rate = clk_get_rate(clk->parent);
+	unsigned long div = __raw_readl(S3C2410_CLKDIVN);
+
+	div &= S3C2412_CLKDIVN_I2SDIV_MASK;
+	div >>= S3C2412_CLKDIVN_I2SDIV_SHIFT;
+
+	return parent_rate / (div + 1);
+}
+
+static int s3c2412_setrate_i2s(struct clk *clk, unsigned long rate)
+{
+	unsigned long parent_rate = clk_get_rate(clk->parent);
+	unsigned long clkdivn = __raw_readl(S3C2410_CLKDIVN);
+
+	rate = s3c2412_roundrate_clksrc(clk, rate);
+
+	clkdivn &= ~S3C2412_CLKDIVN_I2SDIV_MASK;
+	clkdivn |= ((parent_rate / rate) - 1) << S3C2412_CLKDIVN_I2SDIV_SHIFT;
+
+	__raw_writel(clkdivn, S3C2410_CLKDIVN);
+	return 0;
+}
+
+static struct clk clk_i2s = {
+	.name		= "i2sclk",
+	.id		= -1,
+	.get_rate	= s3c2412_getrate_i2s,
+	.set_rate	= s3c2412_setrate_i2s,
+	.set_parent	= s3c2412_setparent_i2s,
+	.round_rate	= s3c2412_roundrate_clksrc,
+};
+
+static int s3c2412_setparent_cam(struct clk *clk, struct clk *parent)
+{
+	unsigned long clksrc = __raw_readl(S3C2412_CLKSRC);
+
+	if (parent == &clk_usysclk)
+		clksrc &= ~S3C2412_CLKSRC_CAMCLK_HCLK;
+	else if (parent == &clk_h)
+		clksrc |= S3C2412_CLKSRC_CAMCLK_HCLK;
+	else
+		return -EINVAL;
+
+	clk->parent = parent;
+
+	__raw_writel(clksrc, S3C2412_CLKSRC);
+	return 0;
+}
+static unsigned long s3c2412_getrate_cam(struct clk *clk)
+{
+	unsigned long parent_rate = clk_get_rate(clk->parent);
+	unsigned long div = __raw_readl(S3C2410_CLKDIVN);
+
+	div &= S3C2412_CLKDIVN_CAMDIV_MASK;
+	div >>= S3C2412_CLKDIVN_CAMDIV_SHIFT;
+
+	return parent_rate / (div + 1);
+}
+
+static int s3c2412_setrate_cam(struct clk *clk, unsigned long rate)
+{
+	unsigned long parent_rate = clk_get_rate(clk->parent);
+	unsigned long clkdivn = __raw_readl(S3C2410_CLKDIVN);
+
+	rate = s3c2412_roundrate_clksrc(clk, rate);
+
+	clkdivn &= ~S3C2412_CLKDIVN_CAMDIV_MASK;
+	clkdivn |= ((parent_rate / rate) - 1) << S3C2412_CLKDIVN_CAMDIV_SHIFT;
+
+	__raw_writel(clkdivn, S3C2410_CLKDIVN);
+	return 0;
+}
+
+static struct clk clk_cam = {
+	.name		= "camif-upll",	/* same as 2440 name */
+	.id		= -1,
+	.get_rate	= s3c2412_getrate_cam,
+	.set_rate	= s3c2412_setrate_cam,
+	.set_parent	= s3c2412_setparent_cam,
+	.round_rate	= s3c2412_roundrate_clksrc,
+};
+
+/* standard clock definitions */
+
+static struct clk init_clocks_disable[] = {
+	{
+		.name		= "nand",
+		.id		= -1,
+		.parent		= &clk_h,
+		.enable		= s3c2412_clkcon_enable,
+		.ctrlbit	= S3C2412_CLKCON_NAND,
+	}, {
+		.name		= "sdi",
+		.id		= -1,
+		.parent		= &clk_p,
+		.enable		= s3c2412_clkcon_enable,
+		.ctrlbit	= S3C2412_CLKCON_SDI,
+	}, {
+		.name		= "adc",
+		.id		= -1,
+		.parent		= &clk_p,
+		.enable		= s3c2412_clkcon_enable,
+		.ctrlbit	= S3C2412_CLKCON_ADC,
+	}, {
+		.name		= "i2c",
+		.id		= -1,
+		.parent		= &clk_p,
+		.enable		= s3c2412_clkcon_enable,
+		.ctrlbit	= S3C2412_CLKCON_IIC,
+	}, {
+		.name		= "iis",
+		.id		= -1,
+		.parent		= &clk_p,
+		.enable		= s3c2412_clkcon_enable,
+		.ctrlbit	= S3C2412_CLKCON_IIS,
+	}, {
+		.name		= "spi",
+		.id		= -1,
+		.parent		= &clk_p,
+		.enable		= s3c2412_clkcon_enable,
+		.ctrlbit	= S3C2412_CLKCON_SPI,
+	}
+};
+
+static struct clk init_clocks[] = {
+	{
+		.name		= "dma",
+		.id		= 0,
+		.parent		= &clk_h,
+		.enable		= s3c2412_clkcon_enable,
+		.ctrlbit	= S3C2412_CLKCON_DMA0,
+	}, {
+		.name		= "dma",
+		.id		= 1,
+		.parent		= &clk_h,
+		.enable		= s3c2412_clkcon_enable,
+		.ctrlbit	= S3C2412_CLKCON_DMA1,
+	}, {
+		.name		= "dma",
+		.id		= 2,
+		.parent		= &clk_h,
+		.enable		= s3c2412_clkcon_enable,
+		.ctrlbit	= S3C2412_CLKCON_DMA2,
+	}, {
+		.name		= "dma",
+		.id		= 3,
+		.parent		= &clk_h,
+		.enable		= s3c2412_clkcon_enable,
+		.ctrlbit	= S3C2412_CLKCON_DMA3,
+	}, {
+		.name		= "lcd",
+		.id		= -1,
+		.parent		= &clk_h,
+		.enable		= s3c2412_clkcon_enable,
+		.ctrlbit	= S3C2412_CLKCON_LCDC,
+	}, {
+		.name		= "gpio",
+		.id		= -1,
+		.parent		= &clk_p,
+		.enable		= s3c2412_clkcon_enable,
+		.ctrlbit	= S3C2412_CLKCON_GPIO,
+	}, {
+		.name		= "usb-host",
+		.id		= -1,
+		.parent		= &clk_h,
+		.enable		= s3c2412_clkcon_enable,
+		.ctrlbit	= S3C2412_CLKCON_USBH,
+	}, {
+		.name		= "usb-device",
+		.id		= -1,
+		.parent		= &clk_h,
+		.enable		= s3c2412_clkcon_enable,
+		.ctrlbit	= S3C2412_CLKCON_USBD,
+	}, {
+		.name		= "timers",
+		.id		= -1,
+		.parent		= &clk_p,
+		.enable		= s3c2412_clkcon_enable,
+		.ctrlbit	= S3C2412_CLKCON_PWMT,
+	}, {
+		.name		= "uart",
+		.id		= 0,
+		.parent		= &clk_p,
+		.enable		= s3c2412_clkcon_enable,
+		.ctrlbit	= S3C2412_CLKCON_UART0,
+	}, {
+		.name		= "uart",
+		.id		= 1,
+		.parent		= &clk_p,
+		.enable		= s3c2412_clkcon_enable,
+		.ctrlbit	= S3C2412_CLKCON_UART1,
+	}, {
+		.name		= "uart",
+		.id		= 2,
+		.parent		= &clk_p,
+		.enable		= s3c2412_clkcon_enable,
+		.ctrlbit	= S3C2412_CLKCON_UART2,
+	}, {
+		.name		= "rtc",
+		.id		= -1,
+		.parent		= &clk_p,
+		.enable		= s3c2412_clkcon_enable,
+		.ctrlbit	= S3C2412_CLKCON_RTC,
+	}, {
+		.name		= "watchdog",
+		.id		= -1,
+		.parent		= &clk_p,
+		.ctrlbit	= 0,
+	}, {
+		.name		= "usb-bus-gadget",
+		.id		= -1,
+		.parent		= &clk_usb_bus,
+		.enable		= s3c2412_clkcon_enable,
+		.ctrlbit	= S3C2412_CLKCON_USB_DEV48,
+	}, {
+		.name		= "usb-bus-host",
+		.id		= -1,
+		.parent		= &clk_usb_bus,
+		.enable		= s3c2412_clkcon_enable,
+		.ctrlbit	= S3C2412_CLKCON_USB_HOST48,
+	}
+};
+
+/* clocks to add where we need to check their parentage */
+
+struct clk_init {
+	struct clk	*clk;
+	unsigned int	 bit;
+	struct clk	*src_0;
+	struct clk	*src_1;
+};
+
+struct clk_init clks_src[] __initdata = {
+	{
+		.clk	= &clk_usysclk,
+		.bit	= S3C2412_CLKSRC_USBCLK_HCLK,
+		.src_0	= &clk_urefclk,
+		.src_1	= &clk_upll,
+	}, {
+		.clk	= &clk_i2s,
+		.bit	= S3C2412_CLKSRC_I2SCLK_MPLL,
+		.src_0	= &clk_erefclk,
+		.src_1	= &clk_mpll,
+	}, {
+		.clk	= &clk_cam,
+		.bit	= S3C2412_CLKSRC_CAMCLK_HCLK,
+		.src_0	= &clk_usysclk,
+		.src_1	= &clk_h,
+	}, {
+		.clk	= &clk_msysclk,
+		.bit	= S3C2412_CLKSRC_MSYSCLK_MPLL,
+		.src_0	= &clk_mdivclk,
+		.src_1	= &clk_mpll,
+	}, {
+		.clk	= &clk_uart,
+		.bit	= S3C2412_CLKSRC_UARTCLK_MPLL,
+		.src_0	= &clk_erefclk,
+		.src_1	= &clk_mpll,
+	}, {
+		.clk	= &clk_usbsrc,
+		.bit	= S3C2412_CLKSRC_USBCLK_HCLK,
+		.src_0	= &clk_usysclk,
+		.src_1	= &clk_h,
+	},
+};
+
+/* s3c2412_clk_initparents
+ *
+ * Initialise the parents for the clocks that we get at start-time
+*/
+
+static void __init s3c2412_clk_initparents(void)
+{
+	unsigned long clksrc = __raw_readl(S3C2412_CLKSRC);
+	struct clk_init *cip = clks_src;
+	struct clk *src;
+	int ptr;
+	int ret;
+
+	for (ptr = 0; ptr < ARRAY_SIZE(clks_src); ptr++, cip++) {
+		ret = s3c24xx_register_clock(cip->clk);
+		if (ret < 0) {
+			printk(KERN_ERR "Failed to register clock %s (%d)\n",
+			       cip->clk->name, ret);
+		}
+
+		src = (clksrc & cip->bit) ? cip->src_1 : cip->src_0;
+
+		printk(KERN_INFO "%s: parent %s\n", cip->clk->name, src->name);
+		clk_set_parent(cip->clk, src);
+	}
+}
+
+/* clocks to add straight away */
+
+struct clk *clks[] __initdata = {
+	&clk_ext,
+	&clk_usb_bus,
+	&clk_erefclk,
+	&clk_urefclk,
+	&clk_mrefclk,
+};
+
+int __init s3c2412_baseclk_add(void)
+{
+	unsigned long clkcon  = __raw_readl(S3C2410_CLKCON);
+	struct clk *clkp;
+	int ret;
+	int ptr;
+
+	clk_upll.enable = s3c2412_upll_enable;
+	clk_usb_bus.parent = &clk_usbsrc;
+	clk_usb_bus.rate = 0x0;
+
+	s3c2412_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);
+		}
+	}
+
+	/* ensure usb bus clock is within correct rate of 48MHz */
+
+	if (clk_get_rate(&clk_usb_bus) != (48 * 1000 * 1000)) {
+		printk(KERN_INFO "Warning: USB bus clock not at 48MHz\n");
+
+		/* for the moment, let's use the UPLL, and see if we can
+		 * get 48MHz */
+
+		clk_set_parent(&clk_usysclk, &clk_upll);
+		clk_set_parent(&clk_usbsrc, &clk_usysclk);
+		clk_set_rate(&clk_usbsrc, 48*1000*1000);
+	}
+
+	printk("S3C2412: upll %s, %ld.%03ld MHz, usb-bus %ld.%03ld MHz\n",
+	       (__raw_readl(S3C2410_UPLLCON) & S3C2412_PLLCON_OFF) ? "off":"on",
+	       print_mhz(clk_get_rate(&clk_upll)),
+	       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++) {
+		/* 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);
+		}
+
+		s3c2412_clkcon_enable(clkp, 0);
+	}
+
+	return 0;
+}
diff --git a/arch/arm/mach-s3c2410/s3c2412-irq.c b/arch/arm/mach-s3c2410/s3c2412-irq.c
new file mode 100644
index 000000000..c80ec93df
--- /dev/null
+++ b/arch/arm/mach-s3c2410/s3c2412-irq.c
@@ -0,0 +1,130 @@
+/* linux/arch/arm/mach-s3c2412/s3c2412-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 <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 "cpu.h"
+#include "irq.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
+ * both show the status, they both now need to be acked when the IRQs
+ * go off.
+*/
+
+static void
+s3c2412_irq_mask(unsigned int irqno)
+{
+	unsigned long bitval = 1UL << (irqno - IRQ_EINT0);
+	unsigned long mask;
+
+	mask = __raw_readl(S3C2410_INTMSK);
+	__raw_writel(mask | bitval, S3C2410_INTMSK);
+
+	mask = __raw_readl(S3C2412_EINTMASK);
+	__raw_writel(mask | bitval, S3C2412_EINTMASK);
+}
+
+static inline void
+s3c2412_irq_ack(unsigned int irqno)
+{
+	unsigned long bitval = 1UL << (irqno - IRQ_EINT0);
+
+	__raw_writel(bitval, S3C2412_EINTPEND);
+	__raw_writel(bitval, S3C2410_SRCPND);
+	__raw_writel(bitval, S3C2410_INTPND);
+}
+
+static inline void
+s3c2412_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);
+
+	mask = __raw_readl(S3C2412_EINTMASK);
+	__raw_writel(mask | bitval, S3C2412_EINTMASK);
+
+	__raw_writel(bitval, S3C2412_EINTPEND);
+	__raw_writel(bitval, S3C2410_SRCPND);
+	__raw_writel(bitval, S3C2410_INTPND);
+}
+
+static void
+s3c2412_irq_unmask(unsigned int irqno)
+{
+	unsigned long bitval = 1UL << (irqno - IRQ_EINT0);
+	unsigned long mask;
+
+	mask = __raw_readl(S3C2412_EINTMASK);
+	__raw_writel(mask & ~bitval, S3C2412_EINTMASK);
+
+	mask = __raw_readl(S3C2410_INTMSK);
+	__raw_writel(mask & ~bitval, S3C2410_INTMSK);
+}
+
+static struct irqchip s3c2412_irq_eint0t4 = {
+	.ack	   = s3c2412_irq_ack,
+	.mask	   = s3c2412_irq_mask,
+	.unmask	   = s3c2412_irq_unmask,
+	.set_wake  = s3c_irq_wake,
+	.set_type  = s3c_irqext_type,
+};
+
+static int s3c2412_irq_add(struct sys_device *sysdev)
+{
+	unsigned int irqno;
+
+	for (irqno = IRQ_EINT0; irqno <= IRQ_EINT3; irqno++) {
+		set_irq_chip(irqno, &s3c2412_irq_eint0t4);
+		set_irq_handler(irqno, do_edge_IRQ);
+		set_irq_flags(irqno, IRQF_VALID);
+	}
+
+	return 0;
+}
+
+static struct sysdev_driver s3c2412_irq_driver = {
+	.add		= s3c2412_irq_add,
+};
+
+static int s3c2412_irq_init(void)
+{
+	return sysdev_driver_register(&s3c2412_sysclass, &s3c2412_irq_driver);
+}
+
+arch_initcall(s3c2412_irq_init);
diff --git a/arch/arm/mach-s3c2410/s3c2412.c b/arch/arm/mach-s3c2410/s3c2412.c
new file mode 100644
index 000000000..2d163f760
--- /dev/null
+++ b/arch/arm/mach-s3c2410/s3c2412.c
@@ -0,0 +1,224 @@
+/* linux/arch/arm/mach-s3c2410/s3c2412.c
+ *
+ * Copyright (c) 2006 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.
+ *
+ * Modifications:
+ *     16-May-2003 BJD  Created initial version
+ *     16-Aug-2003 BJD  Fixed header files and copyright, added URL
+ *     05-Sep-2003 BJD  Moved to kernel v2.6
+ *     18-Jan-2004 BJD  Added serial port configuration
+ *     21-Aug-2004 BJD  Added new struct s3c2410_board handler
+ *     28-Sep-2004 BJD  Updates for new serial port bits
+ *     04-Nov-2004 BJD  Updated UART configuration process
+ *     10-Jan-2005 BJD  Removed s3c2410_clock_tick_rate
+ *     13-Aug-2005 DA   Removed UART from initial I/O mappings
+*/
+
+#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/sysdev.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/proc-fns.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+
+#include <asm/arch/idle.h>
+
+#include <asm/arch/regs-clock.h>
+#include <asm/arch/regs-serial.h>
+#include <asm/arch/regs-power.h>
+#include <asm/arch/regs-gpio.h>
+#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"
+
+#ifndef CONFIG_CPU_S3C2412_ONLY
+void __iomem *s3c24xx_va_gpio2 = S3C24XX_VA_GPIO;
+#endif
+
+/* Initial IO mappings */
+
+static struct map_desc s3c2412_iodesc[] __initdata = {
+	IODESC_ENT(CLKPWR),
+	IODESC_ENT(LCD),
+	IODESC_ENT(TIMER),
+	IODESC_ENT(ADC),
+	IODESC_ENT(WATCHDOG),
+};
+
+/* uart registration process */
+
+void __init s3c2412_init_uarts(struct s3c2410_uartcfg *cfg, int no)
+{
+	s3c24xx_init_uartdevs("s3c2412-uart", s3c2410_uart_resources, cfg, no);
+
+	/* rename devices that are s3c2412/s3c2413 specific */
+	s3c_device_sdi.name  = "s3c2412-sdi";
+	s3c_device_nand.name = "s3c2412-nand";
+}
+
+/* s3c2412_idle
+ *
+ * use the standard idle call by ensuring the idle mode
+ * in power config, then issuing the idle co-processor
+ * instruction
+*/
+
+static void s3c2412_idle(void)
+{
+	unsigned long tmp;
+
+	/* ensure our idle mode is to go to idle */
+
+	tmp = __raw_readl(S3C2412_PWRCFG);
+	tmp &= ~S3C2412_PWRCFG_STANDBYWFI_MASK;
+	tmp |= S3C2412_PWRCFG_STANDBYWFI_IDLE;
+	__raw_writel(tmp, S3C2412_PWRCFG);
+
+	cpu_do_idle();
+}
+
+/* s3c2412_map_io
+ *
+ * register the standard cpu IO areas, and any passed in from the
+ * machine specific initialisation.
+*/
+
+void __init s3c2412_map_io(struct map_desc *mach_desc, int mach_size)
+{
+	/* move base of IO */
+
+	s3c24xx_va_gpio2 = S3C24XX_VA_GPIO + 0x10;
+
+	/* set our idle function */
+
+	s3c24xx_idle = s3c2412_idle;
+
+	/* register our io-tables */
+
+	iotable_init(s3c2412_iodesc, ARRAY_SIZE(s3c2412_iodesc));
+	iotable_init(mach_desc, mach_size);
+}
+
+void __init s3c2412_init_clocks(int xtal)
+{
+	unsigned long tmp;
+	unsigned long fclk;
+	unsigned long hclk;
+	unsigned long pclk;
+
+	/* now we've got our machine bits initialised, work out what
+	 * clocks we've got */
+
+	fclk = s3c2410_get_pll(__raw_readl(S3C2410_MPLLCON), xtal*2);
+
+	tmp = __raw_readl(S3C2410_CLKDIVN);
+
+	/* work out clock scalings */
+
+	hclk = fclk / ((tmp & S3C2412_CLKDIVN_HDIVN_MASK) + 1);
+	hclk /= ((tmp & S3C2421_CLKDIVN_ARMDIVN) ? 2 : 1);
+	pclk = hclk / ((tmp & S3C2412_CLKDIVN_PDIVN) ? 2 : 1);
+
+	/* print brieft summary of clocks, etc */
+
+	printk("S3C2412: core %ld.%03ld MHz, memory %ld.%03ld MHz, peripheral %ld.%03ld MHz\n",
+	       print_mhz(fclk), print_mhz(hclk), print_mhz(pclk));
+
+	/* initialise the clocks here, to allow other things like the
+	 * console to use them
+	 */
+
+	s3c24xx_setup_clocks(xtal, fclk, hclk, pclk);
+	s3c2412_baseclk_add();
+}
+
+/* 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 s3c2412 based system)
+ * as a driver which may support both 2410 and 2440 may try and use it.
+*/
+
+#ifdef CONFIG_PM
+static struct sleep_save s3c2412_sleep[] = {
+	SAVE_ITEM(S3C2412_DSC0),
+	SAVE_ITEM(S3C2412_DSC1),
+	SAVE_ITEM(S3C2413_GPJDAT),
+	SAVE_ITEM(S3C2413_GPJCON),
+	SAVE_ITEM(S3C2413_GPJUP),
+
+	/* save the sleep configuration anyway, just in case these
+	 * get damaged during wakeup */
+
+	SAVE_ITEM(S3C2412_GPBSLPCON),
+	SAVE_ITEM(S3C2412_GPCSLPCON),
+	SAVE_ITEM(S3C2412_GPDSLPCON),
+	SAVE_ITEM(S3C2412_GPESLPCON),
+	SAVE_ITEM(S3C2412_GPFSLPCON),
+	SAVE_ITEM(S3C2412_GPGSLPCON),
+	SAVE_ITEM(S3C2412_GPHSLPCON),
+	SAVE_ITEM(S3C2413_GPJSLPCON),
+};
+
+static int s3c2412_suspend(struct sys_device *dev, pm_message_t state)
+{
+	s3c2410_pm_do_save(s3c2412_sleep, ARRAY_SIZE(s3c2412_sleep));
+	return 0;
+}
+
+static int s3c2412_resume(struct sys_device *dev)
+{
+	s3c2410_pm_do_restore(s3c2412_sleep, ARRAY_SIZE(s3c2412_sleep));
+	return 0;
+}
+
+#else
+#define s3c2412_suspend NULL
+#define s3c2412_resume  NULL
+#endif
+
+struct sysdev_class s3c2412_sysclass = {
+	set_kset_name("s3c2412-core"),
+	.suspend	= s3c2412_suspend,
+	.resume		= s3c2412_resume
+};
+
+static int __init s3c2412_core_init(void)
+{
+	return sysdev_class_register(&s3c2412_sysclass);
+}
+
+core_initcall(s3c2412_core_init);
+
+static struct sys_device s3c2412_sysdev = {
+	.cls		= &s3c2412_sysclass,
+};
+
+int __init s3c2412_init(void)
+{
+	printk("S3C2412: Initialising architecture\n");
+
+	return sysdev_register(&s3c2412_sysdev);
+}
diff --git a/arch/arm/mach-s3c2410/s3c2412.h b/arch/arm/mach-s3c2410/s3c2412.h
new file mode 100644
index 000000000..c6e56032a
--- /dev/null
+++ b/arch/arm/mach-s3c2410/s3c2412.h
@@ -0,0 +1,29 @@
+/* arch/arm/mach-s3c2410/s3c2412.h
+ *
+ * Copyright (c) 2006 Simtec Electronics
+ *	Ben Dooks <ben@simtec.co.uk>
+ *
+ * Header file for s3c2412 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_S3C2412
+
+extern  int s3c2412_init(void);
+
+extern void s3c2412_map_io(struct map_desc *mach_desc, int size);
+
+extern void s3c2412_init_uarts(struct s3c2410_uartcfg *cfg, int no);
+
+extern void s3c2412_init_clocks(int xtal);
+
+extern  int s3c2412_baseclk_add(void);
+#else
+#define s3c2412_init_clocks NULL
+#define s3c2412_init_uarts NULL
+#define s3c2412_map_io NULL
+#define s3c2412_init NULL
+#endif
diff --git a/arch/arm/mach-s3c2410/s3c2442-clock.c b/arch/arm/mach-s3c2410/s3c2442-clock.c
new file mode 100644
index 000000000..d9f54b5ca
--- /dev/null
+++ b/arch/arm/mach-s3c2410/s3c2442-clock.c
@@ -0,0 +1,171 @@
+/* linux/arch/arm/mach-s3c2410/s3c2442-clock.c
+ *
+ * Copyright (c) 2004-2005 Simtec Electronics
+ *	http://armlinux.simtec.co.uk/
+ *	Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C2442 Clock 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/device.h>
+#include <linux/sysdev.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/mutex.h>
+#include <linux/clk.h>
+
+#include <asm/hardware.h>
+#include <asm/atomic.h>
+#include <asm/irq.h>
+#include <asm/io.h>
+
+#include <asm/arch/regs-clock.h>
+
+#include "clock.h"
+#include "cpu.h"
+
+/* S3C2442 extended clock support */
+
+static unsigned long s3c2442_camif_upll_round(struct clk *clk,
+					      unsigned long rate)
+{
+	unsigned long parent_rate = clk_get_rate(clk->parent);
+	int div;
+
+	if (rate > parent_rate)
+		return parent_rate;
+
+	div = parent_rate / rate;
+
+	if (div == 3)
+		return parent_rate / 3;
+
+	/* note, we remove the +/- 1 calculations for the divisor */
+
+	div /= 2;
+
+	if (div < 1)
+		div = 1;
+	else if (div > 16)
+		div = 16;
+
+	return parent_rate / (div * 2);
+}
+
+static int s3c2442_camif_upll_setrate(struct clk *clk, unsigned long rate)
+{
+	unsigned long parent_rate = clk_get_rate(clk->parent);
+	unsigned long camdivn =  __raw_readl(S3C2440_CAMDIVN);
+
+	rate = s3c2442_camif_upll_round(clk, rate);
+
+	camdivn &= ~S3C2442_CAMDIVN_CAMCLK_DIV3;
+
+	if (rate == parent_rate) {
+		camdivn &= ~S3C2440_CAMDIVN_CAMCLK_SEL;
+	} else if ((parent_rate / rate) == 3) {
+		camdivn |= S3C2440_CAMDIVN_CAMCLK_SEL;
+		camdivn |= S3C2442_CAMDIVN_CAMCLK_DIV3;
+	} else {
+		camdivn &= ~S3C2440_CAMDIVN_CAMCLK_MASK;
+		camdivn |= S3C2440_CAMDIVN_CAMCLK_SEL;
+		camdivn |= (((parent_rate / rate) / 2) - 1);
+	}
+
+	__raw_writel(camdivn, S3C2440_CAMDIVN);
+
+	return 0;
+}
+
+/* Extra S3C2442 clocks */
+
+static struct clk s3c2442_clk_cam = {
+	.name		= "camif",
+	.id		= -1,
+	.enable		= s3c2410_clkcon_enable,
+	.ctrlbit	= S3C2440_CLKCON_CAMERA,
+};
+
+static struct clk s3c2442_clk_cam_upll = {
+	.name		= "camif-upll",
+	.id		= -1,
+	.set_rate	= s3c2442_camif_upll_setrate,
+	.round_rate	= s3c2442_camif_upll_round,
+};
+
+static int s3c2442_clk_add(struct sys_device *sysdev)
+{
+	unsigned long camdivn = __raw_readl(S3C2440_CAMDIVN);
+	unsigned long clkdivn;
+	struct clk *clk_h;
+	struct clk *clk_p;
+	struct clk *clk_upll;
+
+	printk("S3C2442: Clock Support, DVS %s\n",
+	       (camdivn & S3C2440_CAMDIVN_DVSEN) ? "on" : "off");
+
+	clk_p = clk_get(NULL, "pclk");
+	clk_h = clk_get(NULL, "hclk");
+	clk_upll = clk_get(NULL, "upll");
+
+	if (IS_ERR(clk_p) || IS_ERR(clk_h) || IS_ERR(clk_upll)) {
+		printk(KERN_ERR "S3C2442: Failed to get parent clocks\n");
+		return -EINVAL;
+	}
+
+	/* check rate of UPLL, and if it is near 96MHz, then change
+	 * to using half the UPLL rate for the system */
+
+	if (clk_get_rate(clk_upll) > (94 * MHZ)) {
+		clk_usb_bus.rate = clk_get_rate(clk_upll) / 2;
+
+		mutex_lock(&clocks_mutex);
+
+		clkdivn = __raw_readl(S3C2410_CLKDIVN);
+		clkdivn |= S3C2440_CLKDIVN_UCLK;
+		__raw_writel(clkdivn, S3C2410_CLKDIVN);
+
+		mutex_unlock(&clocks_mutex);
+	}
+
+	s3c2442_clk_cam.parent = clk_h;
+	s3c2442_clk_cam_upll.parent = clk_upll;
+
+	s3c24xx_register_clock(&s3c2442_clk_cam);
+	s3c24xx_register_clock(&s3c2442_clk_cam_upll);
+
+	clk_disable(&s3c2442_clk_cam);
+
+	return 0;
+}
+
+static struct sysdev_driver s3c2442_clk_driver = {
+	.add	= s3c2442_clk_add,
+};
+
+static __init int s3c2442_clk_init(void)
+{
+	return sysdev_driver_register(&s3c2442_sysclass, &s3c2442_clk_driver);
+}
+
+arch_initcall(s3c2442_clk_init);
diff --git a/arch/arm/mach-s3c2410/s3c2442.c b/arch/arm/mach-s3c2410/s3c2442.c
new file mode 100644
index 000000000..debae2430
--- /dev/null
+++ b/arch/arm/mach-s3c2410/s3c2442.c
@@ -0,0 +1,52 @@
+/* linux/arch/arm/mach-s3c2410/s3c2440.c
+ *
+ * Copyright (c) 2006 Simtec Electronics
+ *   Ben Dooks <ben@simtec.co.uk>
+ *
+ * Samsung S3C2442 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/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-clock.h>
+#include <asm/arch/regs-serial.h>
+#include <asm/arch/regs-gpio.h>
+#include <asm/arch/regs-gpioj.h>
+#include <asm/arch/regs-dsc.h>
+
+#include "s3c2442.h"
+#include "clock.h"
+#include "devs.h"
+#include "cpu.h"
+#include "pm.h"
+
+static struct sys_device s3c2442_sysdev = {
+	.cls		= &s3c2442_sysclass,
+};
+
+int __init s3c2442_init(void)
+{
+	printk("S3C2442: Initialising architecture\n");
+
+	return sysdev_register(&s3c2442_sysdev);
+}
diff --git a/arch/arm/mach-s3c2410/s3c2442.h b/arch/arm/mach-s3c2410/s3c2442.h
new file mode 100644
index 000000000..0ae37d248
--- /dev/null
+++ b/arch/arm/mach-s3c2410/s3c2442.h
@@ -0,0 +1,17 @@
+/* arch/arm/mach-s3c2410/s3c2442.h
+ *
+ * Copyright (c) 2006 Simtec Electronics
+ *	Ben Dooks <ben@simtec.co.uk>
+ *
+ * Header file for s3c2442 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_S3C2442
+extern  int s3c2442_init(void);
+#else
+#define s3c2442_init NULL
+#endif
diff --git a/arch/arm/mach-s3c2410/s3c244x-irq.c b/arch/arm/mach-s3c2410/s3c244x-irq.c
new file mode 100644
index 000000000..44c5affa9
--- /dev/null
+++ b/arch/arm/mach-s3c2410/s3c244x-irq.c
@@ -0,0 +1,142 @@
+/* linux/arch/arm/mach-s3c2410/s3c2440-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
+ *
+*/
+
+#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 "cpu.h"
+#include "pm.h"
+#include "irq.h"
+
+/* camera irq */
+
+static void s3c_irq_demux_cam(unsigned int irq,
+			      struct irqdesc *desc,
+			      struct pt_regs *regs)
+{
+	unsigned int subsrc, submsk;
+	struct irqdesc *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 >>= 11;
+	subsrc &= 3;
+
+	if (subsrc != 0) {
+		if (subsrc & 1) {
+			mydesc = irq_desc + IRQ_S3C2440_CAM_C;
+			desc_handle_irq(IRQ_S3C2440_CAM_C, mydesc, regs);
+		}
+		if (subsrc & 2) {
+			mydesc = irq_desc + IRQ_S3C2440_CAM_P;
+			desc_handle_irq(IRQ_S3C2440_CAM_P, mydesc, regs);
+		}
+	}
+}
+
+#define INTMSK_CAM (1UL << (IRQ_CAM - IRQ_EINT0))
+
+static void
+s3c_irq_cam_mask(unsigned int irqno)
+{
+	s3c_irqsub_mask(irqno, INTMSK_CAM, 3<<11);
+}
+
+static void
+s3c_irq_cam_unmask(unsigned int irqno)
+{
+	s3c_irqsub_unmask(irqno, INTMSK_CAM);
+}
+
+static void
+s3c_irq_cam_ack(unsigned int irqno)
+{
+	s3c_irqsub_maskack(irqno, INTMSK_CAM, 3<<11);
+}
+
+static struct irqchip s3c_irq_cam = {
+	.mask	    = s3c_irq_cam_mask,
+	.unmask	    = s3c_irq_cam_unmask,
+	.ack	    = s3c_irq_cam_ack,
+};
+
+static int s3c244x_irq_add(struct sys_device *sysdev)
+{
+	unsigned int irqno;
+
+	set_irq_chip(IRQ_NFCON, &s3c_irq_level_chip);
+	set_irq_handler(IRQ_NFCON, do_level_IRQ);
+	set_irq_flags(IRQ_NFCON, IRQF_VALID);
+
+	/* add chained handler for camera */
+
+	set_irq_chip(IRQ_CAM, &s3c_irq_level_chip);
+	set_irq_handler(IRQ_CAM, do_level_IRQ);
+	set_irq_chained_handler(IRQ_CAM, s3c_irq_demux_cam);
+
+	for (irqno = IRQ_S3C2440_CAM_C; irqno <= IRQ_S3C2440_CAM_P; irqno++) {
+		set_irq_chip(irqno, &s3c_irq_cam);
+		set_irq_handler(irqno, do_level_IRQ);
+		set_irq_flags(irqno, IRQF_VALID);
+	}
+
+	return 0;
+}
+
+static struct sysdev_driver s3c2440_irq_driver = {
+	.add	= s3c244x_irq_add,
+};
+
+static int s3c2440_irq_init(void)
+{
+	return sysdev_driver_register(&s3c2440_sysclass, &s3c2440_irq_driver);
+}
+
+arch_initcall(s3c2440_irq_init);
+
+static struct sysdev_driver s3c2442_irq_driver = {
+	.add	= s3c244x_irq_add,
+};
+
+static int s3c2442_irq_init(void)
+{
+	return sysdev_driver_register(&s3c2442_sysclass, &s3c2442_irq_driver);
+}
+
+arch_initcall(s3c2442_irq_init);
diff --git a/arch/arm/mach-s3c2410/s3c244x.c b/arch/arm/mach-s3c2410/s3c244x.c
new file mode 100644
index 000000000..9a2258270
--- /dev/null
+++ b/arch/arm/mach-s3c2410/s3c244x.c
@@ -0,0 +1,185 @@
+/* linux/arch/arm/mach-s3c2410/s3c244x.c
+ *
+ * Copyright (c) 2004-2006 Simtec Electronics
+ *   Ben Dooks <ben@simtec.co.uk>
+ *
+ * Samsung S3C2440 and S3C2442 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/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-clock.h>
+#include <asm/arch/regs-serial.h>
+#include <asm/arch/regs-gpio.h>
+#include <asm/arch/regs-gpioj.h>
+#include <asm/arch/regs-dsc.h>
+
+#include "s3c2410.h"
+#include "s3c2440.h"
+#include "s3c244x.h"
+#include "clock.h"
+#include "devs.h"
+#include "cpu.h"
+#include "pm.h"
+
+static struct map_desc s3c244x_iodesc[] __initdata = {
+	IODESC_ENT(CLKPWR),
+	IODESC_ENT(TIMER),
+	IODESC_ENT(WATCHDOG),
+	IODESC_ENT(LCD),
+	IODESC_ENT(ADC),
+	IODESC_ENT(USBHOST),
+};
+
+/* uart initialisation */
+
+void __init s3c244x_init_uarts(struct s3c2410_uartcfg *cfg, int no)
+{
+	s3c24xx_init_uartdevs("s3c2440-uart", s3c2410_uart_resources, cfg, no);
+}
+
+void __init s3c244x_map_io(struct map_desc *mach_desc, int size)
+{
+	/* register our io-tables */
+
+	iotable_init(s3c244x_iodesc, ARRAY_SIZE(s3c244x_iodesc));
+	iotable_init(mach_desc, size);
+
+	/* rename any peripherals used differing from the s3c2410 */
+
+	s3c_device_i2c.name  = "s3c2440-i2c";
+	s3c_device_nand.name = "s3c2440-nand";
+	s3c_device_usbgadget.name = "s3c2440-usbgadget";
+}
+
+void __init s3c244x_init_clocks(int xtal)
+{
+	unsigned long clkdiv;
+	unsigned long camdiv;
+	unsigned long hclk, fclk, pclk;
+	int hdiv = 1;
+
+	/* now we've got our machine bits initialised, work out what
+	 * clocks we've got */
+
+	fclk = s3c2410_get_pll(__raw_readl(S3C2410_MPLLCON), xtal) * 2;
+
+	clkdiv = __raw_readl(S3C2410_CLKDIVN);
+	camdiv = __raw_readl(S3C2440_CAMDIVN);
+
+	/* work out clock scalings */
+
+	switch (clkdiv & S3C2440_CLKDIVN_HDIVN_MASK) {
+	case S3C2440_CLKDIVN_HDIVN_1:
+		hdiv = 1;
+		break;
+
+	case S3C2440_CLKDIVN_HDIVN_2:
+		hdiv = 2;
+		break;
+
+	case S3C2440_CLKDIVN_HDIVN_4_8:
+		hdiv = (camdiv & S3C2440_CAMDIVN_HCLK4_HALF) ? 8 : 4;
+		break;
+
+	case S3C2440_CLKDIVN_HDIVN_3_6:
+		hdiv = (camdiv & S3C2440_CAMDIVN_HCLK3_HALF) ? 6 : 3;
+		break;
+	}
+
+	hclk = fclk / hdiv;
+	pclk = hclk / ((clkdiv & S3C2440_CLKDIVN_PDIVN)? 2:1);
+
+	/* print brief summary of clocks, etc */
+
+	printk("S3C244X: core %ld.%03ld MHz, memory %ld.%03ld MHz, peripheral %ld.%03ld MHz\n",
+	       print_mhz(fclk), print_mhz(hclk), print_mhz(pclk));
+
+	/* initialise the clocks here, to allow other things like the
+	 * console to use them, and to add new ones after the initialisation
+	 */
+
+	s3c24xx_setup_clocks(xtal, fclk, hclk, pclk);
+	s3c2410_baseclk_add();
+}
+
+#ifdef CONFIG_PM
+
+static struct sleep_save s3c244x_sleep[] = {
+	SAVE_ITEM(S3C2440_DSC0),
+	SAVE_ITEM(S3C2440_DSC1),
+	SAVE_ITEM(S3C2440_GPJDAT),
+	SAVE_ITEM(S3C2440_GPJCON),
+	SAVE_ITEM(S3C2440_GPJUP)
+};
+
+static int s3c244x_suspend(struct sys_device *dev, pm_message_t state)
+{
+	s3c2410_pm_do_save(s3c244x_sleep, ARRAY_SIZE(s3c244x_sleep));
+	return 0;
+}
+
+static int s3c244x_resume(struct sys_device *dev)
+{
+	s3c2410_pm_do_restore(s3c244x_sleep, ARRAY_SIZE(s3c244x_sleep));
+	return 0;
+}
+
+#else
+#define s3c244x_suspend NULL
+#define s3c244x_resume  NULL
+#endif
+
+/* Since the S3C2442 and S3C2440 share  items, put both sysclasses here */
+
+struct sysdev_class s3c2440_sysclass = {
+	set_kset_name("s3c2440-core"),
+	.suspend	= s3c244x_suspend,
+	.resume		= s3c244x_resume
+};
+
+struct sysdev_class s3c2442_sysclass = {
+	set_kset_name("s3c2442-core"),
+	.suspend	= s3c244x_suspend,
+	.resume		= s3c244x_resume
+};
+
+/* 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)
+ * as a driver which may support both 2410 and 2440 may try and use it.
+*/
+
+static int __init s3c2440_core_init(void)
+{
+	return sysdev_class_register(&s3c2440_sysclass);
+}
+
+core_initcall(s3c2440_core_init);
+
+static int __init s3c2442_core_init(void)
+{
+	return sysdev_class_register(&s3c2442_sysclass);
+}
+
+core_initcall(s3c2442_core_init);
diff --git a/arch/arm/mach-s3c2410/s3c244x.h b/arch/arm/mach-s3c2410/s3c244x.h
new file mode 100644
index 000000000..3e7f5f751
--- /dev/null
+++ b/arch/arm/mach-s3c2410/s3c244x.h
@@ -0,0 +1,25 @@
+/* arch/arm/mach-s3c2410/s3c2440.h
+ *
+ * Copyright (c) 2004-2005 Simtec Electronics
+ *	Ben Dooks <ben@simtec.co.uk>
+ *
+ * Header file for S3C2440 and S3C2442 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.
+*/
+
+#if defined(CONFIG_CPU_S3C2440) || defined(CONFIG_CPU_S3C2442)
+
+extern void s3c244x_map_io(struct map_desc *mach_desc, int size);
+
+extern void s3c244x_init_uarts(struct s3c2410_uartcfg *cfg, int no);
+
+extern void s3c244x_init_clocks(int xtal);
+
+#else
+#define s3c244x_init_clocks NULL
+#define s3c244x_init_uarts NULL
+#define s3c244x_map_io NULL
+#endif
diff --git a/arch/arm/mm/iomap.c b/arch/arm/mm/iomap.c
new file mode 100644
index 000000000..62066f302
--- /dev/null
+++ b/arch/arm/mm/iomap.c
@@ -0,0 +1,55 @@
+/*
+ *  linux/arch/arm/mm/iomap.c
+ *
+ * Map IO port and PCI memory spaces so that {read,write}[bwl] can
+ * be used to access this memory.
+ */
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/ioport.h>
+
+#include <asm/io.h>
+
+#ifdef __io
+void __iomem *ioport_map(unsigned long port, unsigned int nr)
+{
+	return __io(port);
+}
+EXPORT_SYMBOL(ioport_map);
+
+void ioport_unmap(void __iomem *addr)
+{
+}
+EXPORT_SYMBOL(ioport_unmap);
+#endif
+
+#ifdef CONFIG_PCI
+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(start, len);
+	if (flags & IORESOURCE_MEM) {
+		if (flags & IORESOURCE_CACHEABLE)
+			return ioremap(start, len);
+		return ioremap_nocache(start, len);
+	}
+	return NULL;
+}
+EXPORT_SYMBOL(pci_iomap);
+
+void pci_iounmap(struct pci_dev *dev, void __iomem *addr)
+{
+	if ((unsigned long)addr >= VMALLOC_START &&
+	    (unsigned long)addr < VMALLOC_END)
+		iounmap(addr);
+}
+EXPORT_SYMBOL(pci_iounmap);
+#endif
diff --git a/arch/arm/mm/nommu.c b/arch/arm/mm/nommu.c
new file mode 100644
index 000000000..1464ed817
--- /dev/null
+++ b/arch/arm/mm/nommu.c
@@ -0,0 +1,39 @@
+/*
+ *  linux/arch/arm/mm/nommu.c
+ *
+ * ARM uCLinux supporting functions.
+ */
+#include <linux/module.h>
+#include <linux/mm.h>
+#include <linux/pagemap.h>
+
+#include <asm/cacheflush.h>
+#include <asm/io.h>
+#include <asm/page.h>
+
+void flush_dcache_page(struct page *page)
+{
+	__cpuc_flush_dcache_page(page_address(page));
+}
+EXPORT_SYMBOL(flush_dcache_page);
+
+void __iomem *__ioremap_pfn(unsigned long pfn, unsigned long offset,
+			    size_t size, unsigned long flags)
+{
+	if (pfn >= (0x100000000ULL >> PAGE_SHIFT))
+		return NULL;
+	return (void __iomem *) (offset + (pfn << PAGE_SHIFT));
+}
+EXPORT_SYMBOL(__ioremap_pfn);
+
+void __iomem *__ioremap(unsigned long phys_addr, size_t size,
+			unsigned long flags)
+{
+	return (void __iomem *)phys_addr;
+}
+EXPORT_SYMBOL(__ioremap);
+
+void __iounmap(void __iomem *addr)
+{
+}
+EXPORT_SYMBOL(__iounmap);
diff --git a/arch/i386/kernel/hpet.c b/arch/i386/kernel/hpet.c
new file mode 100644
index 000000000..17647a530
--- /dev/null
+++ b/arch/i386/kernel/hpet.c
@@ -0,0 +1,67 @@
+#include <linux/clocksource.h>
+#include <linux/errno.h>
+#include <linux/hpet.h>
+#include <linux/init.h>
+
+#include <asm/hpet.h>
+#include <asm/io.h>
+
+#define HPET_MASK	CLOCKSOURCE_MASK(32)
+#define HPET_SHIFT	22
+
+/* FSEC = 10^-15 NSEC = 10^-9 */
+#define FSEC_PER_NSEC	1000000
+
+static void *hpet_ptr;
+
+static cycle_t read_hpet(void)
+{
+	return (cycle_t)readl(hpet_ptr);
+}
+
+static struct clocksource clocksource_hpet = {
+	.name		= "hpet",
+	.rating		= 250,
+	.read		= read_hpet,
+	.mask		= HPET_MASK,
+	.mult		= 0, /* set below */
+	.shift		= HPET_SHIFT,
+	.is_continuous	= 1,
+};
+
+static int __init init_hpet_clocksource(void)
+{
+	unsigned long hpet_period;
+	void __iomem* hpet_base;
+	u64 tmp;
+
+	if (!is_hpet_enabled())
+		return -ENODEV;
+
+	/* calculate the hpet address: */
+	hpet_base =
+		(void __iomem*)ioremap_nocache(hpet_address, HPET_MMAP_SIZE);
+	hpet_ptr = hpet_base + HPET_COUNTER;
+
+	/* calculate the frequency: */
+	hpet_period = readl(hpet_base + HPET_PERIOD);
+
+	/*
+	 * hpet period is in femto seconds per cycle
+	 * so we need to convert this to ns/cyc units
+	 * aproximated by mult/2^shift
+	 *
+	 *  fsec/cyc * 1nsec/1000000fsec = nsec/cyc = mult/2^shift
+	 *  fsec/cyc * 1ns/1000000fsec * 2^shift = mult
+	 *  fsec/cyc * 2^shift * 1nsec/1000000fsec = mult
+	 *  (fsec/cyc << shift)/1000000 = mult
+	 *  (hpet_period << shift)/FSEC_PER_NSEC = mult
+	 */
+	tmp = (u64)hpet_period << HPET_SHIFT;
+	do_div(tmp, FSEC_PER_NSEC);
+	clocksource_hpet.mult = (u32)tmp;
+
+	return clocksource_register(&clocksource_hpet);
+}
+
+module_init(init_hpet_clocksource);
diff --git a/arch/i386/kernel/i8253.c b/arch/i386/kernel/i8253.c
new file mode 100644
index 000000000..477b24daf
--- /dev/null
+++ b/arch/i386/kernel/i8253.c
@@ -0,0 +1,118 @@
+/*
+ * i8253.c  8253/PIT functions
+ *
+ */
+#include <linux/clocksource.h>
+#include <linux/spinlock.h>
+#include <linux/jiffies.h>
+#include <linux/sysdev.h>
+#include <linux/module.h>
+#include <linux/init.h>
+
+#include <asm/smp.h>
+#include <asm/delay.h>
+#include <asm/i8253.h>
+#include <asm/io.h>
+
+#include "io_ports.h"
+
+DEFINE_SPINLOCK(i8253_lock);
+EXPORT_SYMBOL(i8253_lock);
+
+void setup_pit_timer(void)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&i8253_lock, flags);
+	outb_p(0x34,PIT_MODE);		/* binary, mode 2, LSB/MSB, ch 0 */
+	udelay(10);
+	outb_p(LATCH & 0xff , PIT_CH0);	/* LSB */
+	udelay(10);
+	outb(LATCH >> 8 , PIT_CH0);	/* MSB */
+	spin_unlock_irqrestore(&i8253_lock, flags);
+}
+
+/*
+ * Since the PIT overflows every tick, its not very useful
+ * to just read by itself. So use jiffies to emulate a free
+ * running counter:
+ */
+static cycle_t pit_read(void)
+{
+	unsigned long flags;
+	int count;
+	u32 jifs;
+	static int old_count;
+	static u32 old_jifs;
+
+	spin_lock_irqsave(&i8253_lock, flags);
+        /*
+	 * Although our caller may have the read side of xtime_lock,
+	 * this is now a seqlock, and we are cheating in this routine
+	 * by having side effects on state that we cannot undo if
+	 * there is a collision on the seqlock and our caller has to
+	 * retry.  (Namely, old_jifs and old_count.)  So we must treat
+	 * jiffies as volatile despite the lock.  We read jiffies
+	 * before latching the timer count to guarantee that although
+	 * the jiffies value might be older than the count (that is,
+	 * the counter may underflow between the last point where
+	 * jiffies was incremented and the point where we latch the
+	 * count), it cannot be newer.
+	 */
+	jifs = jiffies;
+	outb_p(0x00, PIT_MODE);	/* latch the count ASAP */
+	count = inb_p(PIT_CH0);	/* read the latched count */
+	count |= inb_p(PIT_CH0) << 8;
+
+	/* VIA686a test code... reset the latch if count > max + 1 */
+	if (count > LATCH) {
+		outb_p(0x34, PIT_MODE);
+		outb_p(LATCH & 0xff, PIT_CH0);
+		outb(LATCH >> 8, PIT_CH0);
+		count = LATCH - 1;
+	}
+
+	/*
+	 * It's possible for count to appear to go the wrong way for a
+	 * couple of reasons:
+	 *
+	 *  1. The timer counter underflows, but we haven't handled the
+	 *     resulting interrupt and incremented jiffies yet.
+	 *  2. Hardware problem with the timer, not giving us continuous time,
+	 *     the counter does small "jumps" upwards on some Pentium systems,
+	 *     (see c't 95/10 page 335 for Neptun bug.)
+	 *
+	 * Previous attempts to handle these cases intelligently were
+	 * buggy, so we just do the simple thing now.
+	 */
+	if (count > old_count && jifs == old_jifs) {
+		count = old_count;
+	}
+	old_count = count;
+	old_jifs = jifs;
+
+	spin_unlock_irqrestore(&i8253_lock, flags);
+
+	count = (LATCH - 1) - count;
+
+	return (cycle_t)(jifs * LATCH) + count;
+}
+
+static struct clocksource clocksource_pit = {
+	.name	= "pit",
+	.rating = 110,
+	.read	= pit_read,
+	.mask	= CLOCKSOURCE_MASK(32),
+	.mult	= 0,
+	.shift	= 20,
+};
+
+static int __init init_pit_clocksource(void)
+{
+	if (num_possible_cpus() > 4) /* PIT does not scale! */
+		return 0;
+
+	clocksource_pit.mult = clocksource_hz2mult(CLOCK_TICK_RATE, 20);
+	return clocksource_register(&clocksource_pit);
+}
+module_init(init_pit_clocksource);
diff --git a/arch/i386/kernel/tsc.c b/arch/i386/kernel/tsc.c
new file mode 100644
index 000000000..650b7462a
--- /dev/null
+++ b/arch/i386/kernel/tsc.c
@@ -0,0 +1,480 @@
+/*
+ * This code largely moved from arch/i386/kernel/timer/timer_tsc.c
+ * which was originally moved from arch/i386/kernel/time.c.
+ * See comments there for proper credits.
+ */
+
+#include <linux/clocksource.h>
+#include <linux/workqueue.h>
+#include <linux/cpufreq.h>
+#include <linux/jiffies.h>
+#include <linux/init.h>
+#include <linux/dmi.h>
+
+#include <asm/delay.h>
+#include <asm/tsc.h>
+#include <asm/delay.h>
+#include <asm/io.h>
+
+#include "mach_timer.h"
+
+/*
+ * On some systems the TSC frequency does not
+ * change with the cpu frequency. So we need
+ * an extra value to store the TSC freq
+ */
+unsigned int tsc_khz;
+
+int tsc_disable __cpuinitdata = 0;
+
+#ifdef CONFIG_X86_TSC
+static int __init tsc_setup(char *str)
+{
+	printk(KERN_WARNING "notsc: Kernel compiled with CONFIG_X86_TSC, "
+				"cannot disable TSC.\n");
+	return 1;
+}
+#else
+/*
+ * disable flag for tsc. Takes effect by clearing the TSC cpu flag
+ * in cpu/common.c
+ */
+static int __init tsc_setup(char *str)
+{
+	tsc_disable = 1;
+
+	return 1;
+}
+#endif
+
+__setup("notsc", tsc_setup);
+
+/*
+ * code to mark and check if the TSC is unstable
+ * due to cpufreq or due to unsynced TSCs
+ */
+static int tsc_unstable;
+
+static inline int check_tsc_unstable(void)
+{
+	return tsc_unstable;
+}
+
+void mark_tsc_unstable(void)
+{
+	tsc_unstable = 1;
+}
+EXPORT_SYMBOL_GPL(mark_tsc_unstable);
+
+/* Accellerators for sched_clock()
+ * convert from cycles(64bits) => nanoseconds (64bits)
+ *  basic equation:
+ *		ns = cycles / (freq / ns_per_sec)
+ *		ns = cycles * (ns_per_sec / freq)
+ *		ns = cycles * (10^9 / (cpu_khz * 10^3))
+ *		ns = cycles * (10^6 / cpu_khz)
+ *
+ *	Then we use scaling math (suggested by george@mvista.com) to get:
+ *		ns = cycles * (10^6 * SC / cpu_khz) / SC
+ *		ns = cycles * cyc2ns_scale / SC
+ *
+ *	And since SC is a constant power of two, we can convert the div
+ *  into a shift.
+ *
+ *  We can use khz divisor instead of mhz to keep a better percision, since
+ *  cyc2ns_scale is limited to 10^6 * 2^10, which fits in 32 bits.
+ *  (mathieu.desnoyers@polymtl.ca)
+ *
+ *			-johnstul@us.ibm.com "math is hard, lets go shopping!"
+ */
+static unsigned long cyc2ns_scale __read_mostly;
+
+#define CYC2NS_SCALE_FACTOR 10 /* 2^10, carefully chosen */
+
+static inline void set_cyc2ns_scale(unsigned long cpu_khz)
+{
+	cyc2ns_scale = (1000000 << CYC2NS_SCALE_FACTOR)/cpu_khz;
+}
+
+static inline unsigned long long cycles_2_ns(unsigned long long cyc)
+{
+	return (cyc * cyc2ns_scale) >> CYC2NS_SCALE_FACTOR;
+}
+
+#ifndef CONFIG_XEN
+/*
+ * Scheduler clock - returns current time in nanosec units.
+ */
+unsigned long long sched_clock(void)
+{
+	unsigned long long this_offset;
+
+	/*
+	 * in the NUMA case we dont use the TSC as they are not
+	 * synchronized across all CPUs.
+	 */
+#ifndef CONFIG_NUMA
+	if (!cpu_khz || check_tsc_unstable())
+#endif
+		/* no locking but a rare wrong value is not a big deal */
+		return (jiffies_64 - INITIAL_JIFFIES) * (1000000000 / HZ);
+
+	/* read the Time Stamp Counter: */
+	rdtscll(this_offset);
+
+	/* return the value in ns */
+	return cycles_2_ns(this_offset);
+}
+#endif
+
+static unsigned long calculate_cpu_khz(void)
+{
+	unsigned long long start, end;
+	unsigned long count;
+	u64 delta64;
+	int i;
+	unsigned long flags;
+
+	local_irq_save(flags);
+
+	/* run 3 times to ensure the cache is warm */
+	for (i = 0; i < 3; i++) {
+		mach_prepare_counter();
+		rdtscll(start);
+		mach_countup(&count);
+		rdtscll(end);
+	}
+	/*
+	 * Error: ECTCNEVERSET
+	 * The CTC wasn't reliable: we got a hit on the very first read,
+	 * or the CPU was so fast/slow that the quotient wouldn't fit in
+	 * 32 bits..
+	 */
+	if (count <= 1)
+		goto err;
+
+	delta64 = end - start;
+
+	/* cpu freq too fast: */
+	if (delta64 > (1ULL<<32))
+		goto err;
+
+	/* cpu freq too slow: */
+	if (delta64 <= CALIBRATE_TIME_MSEC)
+		goto err;
+
+	delta64 += CALIBRATE_TIME_MSEC/2; /* round for do_div */
+	do_div(delta64,CALIBRATE_TIME_MSEC);
+
+	local_irq_restore(flags);
+	return (unsigned long)delta64;
+err:
+	local_irq_restore(flags);
+	return 0;
+}
+
+int recalibrate_cpu_khz(void)
+{
+#ifndef CONFIG_SMP
+	unsigned long cpu_khz_old = cpu_khz;
+
+	if (cpu_has_tsc) {
+		cpu_khz = calculate_cpu_khz();
+		tsc_khz = cpu_khz;
+		cpu_data[0].loops_per_jiffy =
+			cpufreq_scale(cpu_data[0].loops_per_jiffy,
+					cpu_khz_old, cpu_khz);
+		return 0;
+	} else
+		return -ENODEV;
+#else
+	return -ENODEV;
+#endif
+}
+
+EXPORT_SYMBOL(recalibrate_cpu_khz);
+
+void tsc_init(void)
+{
+	if (!cpu_has_tsc || tsc_disable)
+		return;
+
+	cpu_khz = calculate_cpu_khz();
+	tsc_khz = cpu_khz;
+
+	if (!cpu_khz)
+		return;
+
+	printk("Detected %lu.%03lu MHz processor.\n",
+				(unsigned long)cpu_khz / 1000,
+				(unsigned long)cpu_khz % 1000);
+
+	set_cyc2ns_scale(cpu_khz);
+	use_tsc_delay();
+}
+
+#ifdef CONFIG_CPU_FREQ
+
+static unsigned int cpufreq_delayed_issched = 0;
+static unsigned int cpufreq_init = 0;
+static struct work_struct cpufreq_delayed_get_work;
+
+static void handle_cpufreq_delayed_get(void *v)
+{
+	unsigned int cpu;
+
+	for_each_online_cpu(cpu)
+		cpufreq_get(cpu);
+
+	cpufreq_delayed_issched = 0;
+}
+
+/*
+ * if we notice cpufreq oddness, schedule a call to cpufreq_get() as it tries
+ * to verify the CPU frequency the timing core thinks the CPU is running
+ * at is still correct.
+ */
+static inline void cpufreq_delayed_get(void)
+{
+	if (cpufreq_init && !cpufreq_delayed_issched) {
+		cpufreq_delayed_issched = 1;
+		printk(KERN_DEBUG "Checking if CPU frequency changed.\n");
+		schedule_work(&cpufreq_delayed_get_work);
+	}
+}
+
+/*
+ * if the CPU frequency is scaled, TSC-based delays will need a different
+ * loops_per_jiffy value to function properly.
+ */
+static unsigned int ref_freq = 0;
+static unsigned long loops_per_jiffy_ref = 0;
+static unsigned long cpu_khz_ref = 0;
+
+static int
+time_cpufreq_notifier(struct notifier_block *nb, unsigned long val, void *data)
+{
+	struct cpufreq_freqs *freq = data;
+
+	if (val != CPUFREQ_RESUMECHANGE && val != CPUFREQ_SUSPENDCHANGE)
+		write_seqlock_irq(&xtime_lock);
+
+	if (!ref_freq) {
+		if (!freq->old){
+			ref_freq = freq->new;
+			goto end;
+		}
+		ref_freq = freq->old;
+		loops_per_jiffy_ref = cpu_data[freq->cpu].loops_per_jiffy;
+		cpu_khz_ref = cpu_khz;
+	}
+
+	if ((val == CPUFREQ_PRECHANGE  && freq->old < freq->new) ||
+	    (val == CPUFREQ_POSTCHANGE && freq->old > freq->new) ||
+	    (val == CPUFREQ_RESUMECHANGE)) {
+		if (!(freq->flags & CPUFREQ_CONST_LOOPS))
+			cpu_data[freq->cpu].loops_per_jiffy =
+				cpufreq_scale(loops_per_jiffy_ref,
+						ref_freq, freq->new);
+
+		if (cpu_khz) {
+
+			if (num_online_cpus() == 1)
+				cpu_khz = cpufreq_scale(cpu_khz_ref,
+						ref_freq, freq->new);
+			if (!(freq->flags & CPUFREQ_CONST_LOOPS)) {
+				tsc_khz = cpu_khz;
+				set_cyc2ns_scale(cpu_khz);
+				/*
+				 * TSC based sched_clock turns
+				 * to junk w/ cpufreq
+				 */
+				mark_tsc_unstable();
+			}
+		}
+	}
+end:
+	if (val != CPUFREQ_RESUMECHANGE && val != CPUFREQ_SUSPENDCHANGE)
+		write_sequnlock_irq(&xtime_lock);
+
+	return 0;
+}
+
+static struct notifier_block time_cpufreq_notifier_block = {
+	.notifier_call	= time_cpufreq_notifier
+};
+
+static int __init cpufreq_tsc(void)
+{
+	int ret;
+
+	INIT_WORK(&cpufreq_delayed_get_work, handle_cpufreq_delayed_get, NULL);
+	ret = cpufreq_register_notifier(&time_cpufreq_notifier_block,
+					CPUFREQ_TRANSITION_NOTIFIER);
+	if (!ret)
+		cpufreq_init = 1;
+
+	return ret;
+}
+
+core_initcall(cpufreq_tsc);
+
+#endif
+
+/* clock source code */
+
+static unsigned long current_tsc_khz = 0;
+static int tsc_update_callback(void);
+
+static cycle_t read_tsc(void)
+{
+	cycle_t ret;
+
+	rdtscll(ret);
+
+	return ret;
+}
+
+static struct clocksource clocksource_tsc = {
+	.name			= "tsc",
+	.rating			= 300,
+	.read			= read_tsc,
+	.mask			= CLOCKSOURCE_MASK(64),
+	.mult			= 0, /* to be set */
+	.shift			= 22,
+	.update_callback	= tsc_update_callback,
+	.is_continuous		= 1,
+};
+
+static int tsc_update_callback(void)
+{
+	int change = 0;
+
+	/* check to see if we should switch to the safe clocksource: */
+	if (clocksource_tsc.rating != 50 && check_tsc_unstable()) {
+		clocksource_tsc.rating = 50;
+		clocksource_reselect();
+		change = 1;
+	}
+
+	/* only update if tsc_khz has changed: */
+	if (current_tsc_khz != tsc_khz) {
+		current_tsc_khz = tsc_khz;
+		clocksource_tsc.mult = clocksource_khz2mult(current_tsc_khz,
+							clocksource_tsc.shift);
+		change = 1;
+	}
+
+	return change;
+}
+
+static int __init dmi_mark_tsc_unstable(struct dmi_system_id *d)
+{
+	printk(KERN_NOTICE "%s detected: marking TSC unstable.\n",
+		       d->ident);
+	mark_tsc_unstable();
+	return 0;
+}
+
+/* List of systems that have known TSC problems */
+static struct dmi_system_id __initdata bad_tsc_dmi_table[] = {
+	{
+	 .callback = dmi_mark_tsc_unstable,
+	 .ident = "IBM Thinkpad 380XD",
+	 .matches = {
+		     DMI_MATCH(DMI_BOARD_VENDOR, "IBM"),
+		     DMI_MATCH(DMI_BOARD_NAME, "2635FA0"),
+		     },
+	 },
+	 {}
+};
+
+#define TSC_FREQ_CHECK_INTERVAL (10*MSEC_PER_SEC) /* 10sec in MS */
+static struct timer_list verify_tsc_freq_timer;
+
+/* XXX - Probably should add locking */
+static void verify_tsc_freq(unsigned long unused)
+{
+	static u64 last_tsc;
+	static unsigned long last_jiffies;
+
+	u64 now_tsc, interval_tsc;
+	unsigned long now_jiffies, interval_jiffies;
+
+
+	if (check_tsc_unstable())
+		return;
+
+	rdtscll(now_tsc);
+	now_jiffies = jiffies;
+
+	if (!last_jiffies) {
+		goto out;
+	}
+
+	interval_jiffies = now_jiffies - last_jiffies;
+	interval_tsc = now_tsc - last_tsc;
+	interval_tsc *= HZ;
+	do_div(interval_tsc, cpu_khz*1000);
+
+	if (interval_tsc < (interval_jiffies * 3 / 4)) {
+		printk("TSC appears to be running slowly. "
+			"Marking it as unstable\n");
+		mark_tsc_unstable();
+		return;
+	}
+
+out:
+	last_tsc = now_tsc;
+	last_jiffies = now_jiffies;
+	/* set us up to go off on the next interval: */
+	mod_timer(&verify_tsc_freq_timer,
+		jiffies + msecs_to_jiffies(TSC_FREQ_CHECK_INTERVAL));
+}
+
+/*
+ * Make an educated guess if the TSC is trustworthy and synchronized
+ * over all CPUs.
+ */
+static __init int unsynchronized_tsc(void)
+{
+	/*
+	 * Intel systems are normally all synchronized.
+	 * Exceptions must mark TSC as unstable:
+	 */
+	if (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL)
+ 		return 0;
+
+	/* assume multi socket systems are not synchronized: */
+ 	return num_possible_cpus() > 1;
+}
+
+static int __init init_tsc_clocksource(void)
+{
+
+	if (cpu_has_tsc && tsc_khz && !tsc_disable) {
+		/* check blacklist */
+		dmi_check_system(bad_tsc_dmi_table);
+
+		if (unsynchronized_tsc()) /* mark unstable if unsynced */
+			mark_tsc_unstable();
+		current_tsc_khz = tsc_khz;
+		clocksource_tsc.mult = clocksource_khz2mult(current_tsc_khz,
+							clocksource_tsc.shift);
+		/* lower the rating if we already know its unstable: */
+		if (check_tsc_unstable())
+			clocksource_tsc.rating = 50;
+
+		init_timer(&verify_tsc_freq_timer);
+		verify_tsc_freq_timer.function = verify_tsc_freq;
+		verify_tsc_freq_timer.expires =
+			jiffies + msecs_to_jiffies(TSC_FREQ_CHECK_INTERVAL);
+		add_timer(&verify_tsc_freq_timer);
+
+		return clocksource_register(&clocksource_tsc);
+	}
+
+	return 0;
+}
+
+module_init(init_tsc_clocksource);
diff --git a/arch/i386/mach-xen/irqflags.c b/arch/i386/mach-xen/irqflags.c
new file mode 100644
index 000000000..c990ca5d2
--- /dev/null
+++ b/arch/i386/mach-xen/irqflags.c
@@ -0,0 +1,99 @@
+#include <linux/module.h>
+#include <linux/smp.h>
+#include <asm/irqflags.h>
+#include <asm/hypervisor.h>
+
+/* interrupt control.. */
+
+/* 
+ * The use of 'barrier' in the following reflects their use as local-lock
+ * operations. Reentrancy must be prevented (e.g., __cli()) /before/ following
+ * critical operations are executed. All critical operations must complete
+ * /before/ reentrancy is permitted (e.g., __sti()). Alpha architecture also
+ * includes these barriers, for example.
+ */
+
+unsigned long __raw_local_save_flags(void)
+{
+	struct vcpu_info *_vcpu;
+	unsigned long flags;
+
+	preempt_disable();
+	_vcpu = &HYPERVISOR_shared_info->vcpu_info[__vcpu_id];
+	flags = _vcpu->evtchn_upcall_mask;
+	preempt_enable();
+
+	return flags;
+}
+EXPORT_SYMBOL(__raw_local_save_flags);
+
+void raw_local_irq_restore(unsigned long flags)
+{
+	struct vcpu_info *_vcpu;
+
+	preempt_disable();
+	_vcpu = &HYPERVISOR_shared_info->vcpu_info[__vcpu_id];
+	if ((_vcpu->evtchn_upcall_mask = flags) == 0) {
+		barrier(); /* unmask then check (avoid races) */
+		if (unlikely(_vcpu->evtchn_upcall_pending))
+			force_evtchn_callback();
+		preempt_enable();
+	} else
+		preempt_enable_no_resched();
+
+}
+EXPORT_SYMBOL(raw_local_irq_restore);
+
+void raw_local_irq_disable(void)
+{
+	struct vcpu_info *_vcpu;
+
+	preempt_disable();
+	_vcpu = &HYPERVISOR_shared_info->vcpu_info[__vcpu_id];
+	_vcpu->evtchn_upcall_mask = 1;
+	preempt_enable_no_resched();
+}
+EXPORT_SYMBOL(raw_local_irq_disable);
+
+void raw_local_irq_enable(void)
+{
+	struct vcpu_info *_vcpu;
+
+	preempt_disable();
+	_vcpu = &HYPERVISOR_shared_info->vcpu_info[__vcpu_id];
+	_vcpu->evtchn_upcall_mask = 0;
+	barrier(); /* unmask then check (avoid races) */
+	if (unlikely(_vcpu->evtchn_upcall_pending))
+		force_evtchn_callback();
+	preempt_enable();
+}
+EXPORT_SYMBOL(raw_local_irq_enable);
+
+/* Cannot use preempt_enable() here as we would recurse in preempt_sched(). */
+int raw_irqs_disabled(void)
+{
+	struct vcpu_info *_vcpu;
+	int disabled;
+
+	preempt_disable();
+	_vcpu = &HYPERVISOR_shared_info->vcpu_info[__vcpu_id];
+	disabled = (_vcpu->evtchn_upcall_mask != 0);
+	preempt_enable_no_resched();
+	return disabled;
+}
+EXPORT_SYMBOL(raw_irqs_disabled);
+
+unsigned long __raw_local_irq_save(void)
+{
+	struct vcpu_info *_vcpu;
+	unsigned long flags;
+
+	preempt_disable();
+	_vcpu = &HYPERVISOR_shared_info->vcpu_info[__vcpu_id];
+	flags = _vcpu->evtchn_upcall_mask;
+	_vcpu->evtchn_upcall_mask = 1;
+	preempt_enable_no_resched();
+
+	return flags;
+}
+EXPORT_SYMBOL(__raw_local_irq_save);
diff --git a/arch/ia64/ia32/audit.c b/arch/ia64/ia32/audit.c
new file mode 100644
index 000000000..92d7d0c8d
--- /dev/null
+++ b/arch/ia64/ia32/audit.c
@@ -0,0 +1,37 @@
+#include <asm-i386/unistd.h>
+
+unsigned ia32_dir_class[] = {
+#include <asm-generic/audit_dir_write.h>
+~0U
+};
+
+unsigned ia32_chattr_class[] = {
+#include <asm-generic/audit_change_attr.h>
+~0U
+};
+
+unsigned ia32_write_class[] = {
+#include <asm-generic/audit_write.h>
+~0U
+};
+
+unsigned ia32_read_class[] = {
+#include <asm-generic/audit_read.h>
+~0U
+};
+
+int ia32_classify_syscall(unsigned syscall)
+{
+	switch(syscall) {
+	case __NR_open:
+		return 2;
+	case __NR_openat:
+		return 3;
+	case __NR_socketcall:
+		return 4;
+	case __NR_execve:
+		return 5;
+	default:
+		return 1;
+	}
+}
diff --git a/arch/ia64/kernel/audit.c b/arch/ia64/kernel/audit.c
new file mode 100644
index 000000000..04682555a
--- /dev/null
+++ b/arch/ia64/kernel/audit.c
@@ -0,0 +1,64 @@
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/audit.h>
+#include <asm/unistd.h>
+
+static unsigned dir_class[] = {
+#include <asm-generic/audit_dir_write.h>
+~0U
+};
+
+static unsigned read_class[] = {
+#include <asm-generic/audit_read.h>
+~0U
+};
+
+static unsigned write_class[] = {
+#include <asm-generic/audit_write.h>
+~0U
+};
+
+static unsigned chattr_class[] = {
+#include <asm-generic/audit_change_attr.h>
+~0U
+};
+
+int audit_classify_syscall(int abi, unsigned syscall)
+{
+#ifdef CONFIG_IA32_SUPPORT
+	extern int ia32_classify_syscall(unsigned);
+	if (abi == AUDIT_ARCH_I386)
+		return ia32_classify_syscall(syscall);
+#endif
+	switch(syscall) {
+	case __NR_open:
+		return 2;
+	case __NR_openat:
+		return 3;
+	case __NR_execve:
+		return 5;
+	default:
+		return 0;
+	}
+}
+
+static int __init audit_classes_init(void)
+{
+#ifdef CONFIG_IA32_SUPPORT
+	extern __u32 ia32_dir_class[];
+	extern __u32 ia32_write_class[];
+	extern __u32 ia32_read_class[];
+	extern __u32 ia32_chattr_class[];
+	audit_register_class(AUDIT_CLASS_WRITE_32, ia32_write_class);
+	audit_register_class(AUDIT_CLASS_READ_32, ia32_read_class);
+	audit_register_class(AUDIT_CLASS_DIR_WRITE_32, ia32_dir_class);
+	audit_register_class(AUDIT_CLASS_CHATTR_32, ia32_chattr_class);
+#endif
+	audit_register_class(AUDIT_CLASS_WRITE, write_class);
+	audit_register_class(AUDIT_CLASS_READ, read_class);
+	audit_register_class(AUDIT_CLASS_DIR_WRITE, dir_class);
+	audit_register_class(AUDIT_CLASS_CHATTR, chattr_class);
+	return 0;
+}
+
+__initcall(audit_classes_init);
diff --git a/arch/ia64/xen/Makefile b/arch/ia64/xen/Makefile
new file mode 100644
index 000000000..c2b4f94ed
--- /dev/null
+++ b/arch/ia64/xen/Makefile
@@ -0,0 +1,8 @@
+#
+# Makefile for Xen components
+#
+
+obj-y := hypercall.o xenivt.o xenentry.o xensetup.o xenpal.o xenhpski.o \
+	 hypervisor.o pci-dma-xen.o util.o
+
+pci-dma-xen-y := ../../i386/kernel/pci-dma-xen.o
diff --git a/arch/ia64/xen/drivers/README b/arch/ia64/xen/drivers/README
new file mode 100644
index 000000000..33aecaa2a
--- /dev/null
+++ b/arch/ia64/xen/drivers/README
@@ -0,0 +1,2 @@
+This is a temporary location for source/Makefiles that need to be
+patched/reworked in drivers/xen to work with xenlinux/ia64.
diff --git a/arch/ia64/xen/hypercall.S b/arch/ia64/xen/hypercall.S
new file mode 100644
index 000000000..399686576
--- /dev/null
+++ b/arch/ia64/xen/hypercall.S
@@ -0,0 +1,413 @@
+/*
+ * Support routines for Xen hypercalls
+ *
+ * Copyright (C) 2005 Dan Magenheimer <dan.magenheimer@hp.com>
+ */
+
+#include <asm/processor.h>
+#include <asm/asmmacro.h>
+
+/* To clear vpsr.ic, vpsr.i needs to be cleared first */
+#define XEN_CLEAR_PSR_IC				\
+	mov r14=1;					\
+	movl r15=XSI_PSR_I_ADDR;			\
+	movl r2=XSI_PSR_IC;				\
+	;;						\
+	ld8 r15=[r15];					\
+	ld4 r3=[r2];					\
+	;;						\
+	ld1 r16=[r15];					\
+	;;						\
+	st1 [r15]=r14;					\
+	st4 [r2]=r0;					\
+	;;
+
+/* First restore vpsr.ic, and then vpsr.i */
+#define XEN_RESTORE_PSR_IC				\
+	st4 [r2]=r3;					\
+	st1 [r15]=r16;					\
+	;;
+
+GLOBAL_ENTRY(xen_get_ivr)
+	movl r8=running_on_xen;;
+	ld4 r8=[r8];;
+	cmp.eq p7,p0=r8,r0;;
+(p7)	mov r8=cr.ivr;;
+(p7)	br.ret.sptk.many rp
+	;;
+	XEN_CLEAR_PSR_IC
+	;;
+	XEN_HYPER_GET_IVR
+	;;
+	XEN_RESTORE_PSR_IC
+	;;
+	br.ret.sptk.many rp
+	;;
+END(xen_get_ivr)
+
+GLOBAL_ENTRY(xen_get_tpr)
+	movl r8=running_on_xen;;
+	ld4 r8=[r8];;
+	cmp.eq p7,p0=r8,r0;;
+(p7)	mov r8=cr.tpr;;
+(p7)	br.ret.sptk.many rp
+	;;
+	XEN_CLEAR_PSR_IC
+	;;
+	XEN_HYPER_GET_TPR
+	;;
+	XEN_RESTORE_PSR_IC
+	;;
+	br.ret.sptk.many rp
+	;;
+END(xen_get_tpr)
+
+GLOBAL_ENTRY(xen_set_tpr)
+	movl r8=running_on_xen;;
+	ld4 r8=[r8];;
+	cmp.eq p7,p0=r8,r0;;
+(p7)	mov cr.tpr=r32;;
+(p7)	br.ret.sptk.many rp
+	;;
+	mov r8=r32
+	;;
+	XEN_CLEAR_PSR_IC
+	;;
+	XEN_HYPER_SET_TPR
+	;;
+	XEN_RESTORE_PSR_IC
+	;;
+	br.ret.sptk.many rp
+	;;
+END(xen_set_tpr)
+
+GLOBAL_ENTRY(xen_eoi)
+	movl r8=running_on_xen;;
+	ld4 r8=[r8];;
+	cmp.eq p7,p0=r8,r0;;
+(p7)	mov cr.eoi=r0;;
+(p7)	br.ret.sptk.many rp
+	;;
+	mov r8=r32
+	;;
+	XEN_CLEAR_PSR_IC
+	;;
+	XEN_HYPER_EOI
+	;;
+	XEN_RESTORE_PSR_IC
+	;;
+	br.ret.sptk.many rp
+	;;
+END(xen_eoi)
+
+GLOBAL_ENTRY(xen_thash)
+	movl r8=running_on_xen;;
+	ld4 r8=[r8];;
+	cmp.eq p7,p0=r8,r0;;
+(p7)	thash r8=r32;;
+(p7)	br.ret.sptk.many rp
+	;;
+	mov r8=r32
+	;;
+	XEN_CLEAR_PSR_IC
+	;;
+	XEN_HYPER_THASH
+	;;
+	XEN_RESTORE_PSR_IC
+	;;
+	br.ret.sptk.many rp
+	;;
+END(xen_thash)
+
+GLOBAL_ENTRY(xen_set_itm)
+	movl r8=running_on_xen;;
+	ld4 r8=[r8];;
+	cmp.eq p7,p0=r8,r0;;
+(p7)	mov cr.itm=r32;;
+(p7)	br.ret.sptk.many rp
+	;;
+	mov r8=r32
+	;;
+	XEN_CLEAR_PSR_IC
+	;;
+	XEN_HYPER_SET_ITM
+	;;
+	XEN_RESTORE_PSR_IC
+	;;
+	br.ret.sptk.many rp
+	;;
+END(xen_set_itm)
+
+GLOBAL_ENTRY(xen_ptcga)
+	movl r8=running_on_xen;;
+	ld4 r8=[r8];;
+	cmp.eq p7,p0=r8,r0;;
+(p7)	ptc.ga r32,r33;;
+(p7)	br.ret.sptk.many rp
+	;;
+	mov r8=r32
+	mov r9=r33
+	;;
+	XEN_CLEAR_PSR_IC
+	;;
+	XEN_HYPER_PTC_GA
+	;;
+	XEN_RESTORE_PSR_IC
+	;;
+	br.ret.sptk.many rp
+	;;
+END(xen_ptcga)
+
+GLOBAL_ENTRY(xen_get_rr)
+	movl r8=running_on_xen;;
+	ld4 r8=[r8];;
+	cmp.eq p7,p0=r8,r0;;
+(p7)	mov r8=rr[r32];;
+(p7)	br.ret.sptk.many rp
+	;;
+	mov r8=r32
+	;;
+	XEN_CLEAR_PSR_IC
+	;;
+	XEN_HYPER_GET_RR
+	;;
+	XEN_RESTORE_PSR_IC
+	;;
+	br.ret.sptk.many rp
+	;;
+END(xen_get_rr)
+
+GLOBAL_ENTRY(xen_set_rr)
+	movl r8=running_on_xen;;
+	ld4 r8=[r8];;
+	cmp.eq p7,p0=r8,r0;;
+(p7)	mov rr[r32]=r33;;
+(p7)	br.ret.sptk.many rp
+	;;
+	mov r8=r32
+	mov r9=r33
+	;;
+	XEN_CLEAR_PSR_IC
+	;;
+	XEN_HYPER_SET_RR
+	;;
+	XEN_RESTORE_PSR_IC
+	;;
+	br.ret.sptk.many rp
+	;;
+END(xen_set_rr)
+
+GLOBAL_ENTRY(xen_set_kr)
+	movl r8=running_on_xen;;
+	ld4 r8=[r8];;
+	cmp.ne p7,p0=r8,r0;;
+(p7)	br.cond.spnt.few 1f;
+	;;
+	cmp.eq p7,p0=r8,r0
+	adds r8=-1,r8;;
+(p7)	mov ar0=r9
+(p7)	br.ret.sptk.many rp;;
+	cmp.eq p7,p0=r8,r0
+	adds r8=-1,r8;;
+(p7)	mov ar1=r9
+(p7)	br.ret.sptk.many rp;;
+	cmp.eq p7,p0=r8,r0
+	adds r8=-1,r8;;
+(p7)	mov ar2=r9
+(p7)	br.ret.sptk.many rp;;
+	cmp.eq p7,p0=r8,r0
+	adds r8=-1,r8;;
+(p7)	mov ar3=r9
+(p7)	br.ret.sptk.many rp;;
+	cmp.eq p7,p0=r8,r0
+	adds r8=-1,r8;;
+(p7)	mov ar4=r9
+(p7)	br.ret.sptk.many rp;;
+	cmp.eq p7,p0=r8,r0
+	adds r8=-1,r8;;
+(p7)	mov ar5=r9
+(p7)	br.ret.sptk.many rp;;
+	cmp.eq p7,p0=r8,r0
+	adds r8=-1,r8;;
+(p7)	mov ar6=r9
+(p7)	br.ret.sptk.many rp;;
+	cmp.eq p7,p0=r8,r0
+	adds r8=-1,r8;;
+(p7)	mov ar7=r9
+(p7)	br.ret.sptk.many rp;;
+
+1:	mov r8=r32
+	mov r9=r33
+	;;
+	XEN_CLEAR_PSR_IC
+	;;
+	XEN_HYPER_SET_KR
+	;;
+	XEN_RESTORE_PSR_IC
+	;;
+	br.ret.sptk.many rp
+END(xen_set_kr)
+
+GLOBAL_ENTRY(xen_fc)
+	movl r8=running_on_xen;;
+	ld4 r8=[r8];;
+	cmp.eq p7,p0=r8,r0;;
+(p7)	fc r32;;
+(p7)	br.ret.sptk.many rp
+	;;
+	mov r8=r32
+	;;
+	XEN_CLEAR_PSR_IC
+	;;
+	XEN_HYPER_FC
+	;;
+	XEN_RESTORE_PSR_IC
+	;;
+	br.ret.sptk.many rp
+END(xen_fc)
+
+GLOBAL_ENTRY(xen_get_cpuid)
+	movl r8=running_on_xen;;
+	ld4 r8=[r8];;
+	cmp.eq p7,p0=r8,r0;;
+(p7)	mov r8=cpuid[r32];;
+(p7)	br.ret.sptk.many rp
+	;;
+	mov r8=r32
+	;;
+	XEN_CLEAR_PSR_IC
+	;;
+	XEN_HYPER_GET_CPUID
+	;;
+	XEN_RESTORE_PSR_IC
+	;;
+	br.ret.sptk.many rp
+END(xen_get_cpuid)
+
+GLOBAL_ENTRY(xen_get_pmd)
+	movl r8=running_on_xen;;
+	ld4 r8=[r8];;
+	cmp.eq p7,p0=r8,r0;;
+(p7)	mov r8=pmd[r32];;
+(p7)	br.ret.sptk.many rp
+	;;
+	mov r8=r32
+	;;
+	XEN_CLEAR_PSR_IC
+	;;
+	XEN_HYPER_GET_PMD
+	;;
+	XEN_RESTORE_PSR_IC
+	;;
+	br.ret.sptk.many rp
+END(xen_get_pmd)
+
+#ifdef CONFIG_IA32_SUPPORT
+GLOBAL_ENTRY(xen_get_eflag)
+	movl r8=running_on_xen;;
+	ld4 r8=[r8];;
+	cmp.eq p7,p0=r8,r0;;
+(p7)	mov r8=ar24;;
+(p7)	br.ret.sptk.many rp
+	;;
+	mov r8=r32
+	;;
+	XEN_CLEAR_PSR_IC
+	;;
+	XEN_HYPER_GET_EFLAG
+	;;
+	XEN_RESTORE_PSR_IC
+	;;
+	br.ret.sptk.many rp
+END(xen_get_eflag)
+	
+// some bits aren't set if pl!=0, see SDM vol1 3.1.8
+GLOBAL_ENTRY(xen_set_eflag)
+	movl r8=running_on_xen;;
+	ld4 r8=[r8];;
+	cmp.eq p7,p0=r8,r0;;
+(p7)	mov ar24=r32
+(p7)	br.ret.sptk.many rp
+	;;
+	mov r8=r32
+	;;
+	XEN_CLEAR_PSR_IC
+	;;
+	XEN_HYPER_SET_EFLAG
+	;;
+	XEN_RESTORE_PSR_IC
+	;;
+	br.ret.sptk.many rp
+END(xen_set_eflag)
+#endif
+
+GLOBAL_ENTRY(xen_send_ipi)
+        mov r14=r32
+        mov r15=r33
+        mov r2=0x400
+        break 0x1000
+        ;;
+        br.ret.sptk.many rp
+        ;;
+END(xen_send_ipi)
+
+#ifdef CONFIG_XEN_IA64_VDSO_PARAVIRT
+// Those are vdso specialized.
+// In fsys mode, call, ret can't be used.
+GLOBAL_ENTRY(xen_rsm_be_i)
+	ld8 r22=[r22]
+	;; 
+	st1 [r22]=r20
+	st4 [r23]=r0
+	XEN_HYPER_RSM_BE
+	st4 [r23]=r20
+	brl.cond.sptk	.vdso_rsm_be_i_ret
+	;; 
+END(xen_rsm_be_i)
+
+GLOBAL_ENTRY(xen_get_psr)
+	mov r31=r8
+	mov r25=IA64_PSR_IC
+	st4 [r23]=r0
+	XEN_HYPER_GET_PSR
+	;; 
+	st4 [r23]=r20
+	or r29=r8,r25 // vpsr.ic was cleared for hyperprivop
+	mov r8=r31
+	brl.cond.sptk	.vdso_get_psr_ret
+	;; 
+END(xen_get_psr)
+
+	// see xen_ssm_i() in privop.h
+	// r22 = &vcpu->evtchn_mask
+	// r23 = &vpsr.ic
+	// r24 = &vcpu->pending_interruption
+	// r25 = tmp
+	// r31 = tmp
+	// p11 = tmp
+	// p14 = tmp
+#define XEN_SET_PSR_I			\
+	ld4 r31=[r22];			\
+	ld4 r25=[r24];			\
+	;;				\
+	st4 [r22]=r0;			\
+	cmp.ne.unc p14,p0=r0,r31;	\
+	;;				\
+(p14)	cmp.ne.unc p11,p0=r0,r25;	\
+	;;				\
+(p11)	st4 [r22]=r20;			\
+(p11)	st4 [r23]=r0;			\
+(p11)	XEN_HYPER_SSM_I;
+		
+GLOBAL_ENTRY(xen_ssm_i_0)
+	XEN_SET_PSR_I
+	brl.cond.sptk	.vdso_ssm_i_0_ret
+	;; 
+END(xen_ssm_i_0)
+
+GLOBAL_ENTRY(xen_ssm_i_1)
+	XEN_SET_PSR_I
+	brl.cond.sptk	.vdso_ssm_i_1_ret
+	;; 
+END(xen_ssm_i_1)
+#endif
diff --git a/arch/ia64/xen/hypervisor.c b/arch/ia64/xen/hypervisor.c
new file mode 100644
index 000000000..0b286047b
--- /dev/null
+++ b/arch/ia64/xen/hypervisor.c
@@ -0,0 +1,833 @@
+/******************************************************************************
+ * include/asm-ia64/shadow.h
+ *
+ * Copyright (c) 2006 Isaku Yamahata <yamahata at valinux co jp>
+ *                    VA Linux Systems Japan K.K.
+ *
+ * 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/spinlock.h>
+#include <linux/bootmem.h>
+#include <linux/module.h>
+#include <linux/vmalloc.h>
+#include <asm/page.h>
+#include <asm/hypervisor.h>
+#include <asm/hypercall.h>
+#include <xen/interface/memory.h>
+#include <xen/balloon.h>
+
+shared_info_t *HYPERVISOR_shared_info = (shared_info_t *)XSI_BASE;
+EXPORT_SYMBOL(HYPERVISOR_shared_info);
+
+start_info_t *xen_start_info;
+EXPORT_SYMBOL(xen_start_info);
+
+int running_on_xen;
+EXPORT_SYMBOL(running_on_xen);
+
+//XXX xen/ia64 copy_from_guest() is broken.
+//    This is a temporal work around until it is fixed.
+//    used by balloon.c netfront.c
+
+// get_xen_guest_handle is defined only when __XEN_TOOLS__ is defined
+// if the definition in arch-ia64.h is changed, this must be updated.
+#define get_xen_guest_handle(val, hnd)  do { val = (hnd).p; } while (0)
+
+int
+ia64_xenmem_reservation_op(unsigned long op,
+			   struct xen_memory_reservation* reservation__)
+{
+	struct xen_memory_reservation reservation = *reservation__;
+	unsigned long* frame_list;
+	unsigned long nr_extents = reservation__->nr_extents;
+	int ret = 0;
+	get_xen_guest_handle(frame_list, reservation__->extent_start);
+
+	BUG_ON(op != XENMEM_increase_reservation &&
+	       op != XENMEM_decrease_reservation &&
+	       op != XENMEM_populate_physmap);
+
+	while (nr_extents > 0) {
+		int tmp_ret;
+		volatile unsigned long dummy;
+
+		set_xen_guest_handle(reservation.extent_start, frame_list);
+		reservation.nr_extents = nr_extents;
+
+		dummy = frame_list[0];// re-install tlb entry before hypercall
+		tmp_ret = ____HYPERVISOR_memory_op(op, &reservation);
+		if (tmp_ret < 0) {
+			if (ret == 0) {
+				ret = tmp_ret;
+			}
+			break;
+		}
+		if (tmp_ret == 0) {
+			//XXX dirty work around for skbuff_ctor()
+			//    of a non-privileged domain, 
+			if ((op == XENMEM_increase_reservation ||
+			     op == XENMEM_populate_physmap) &&
+			    !is_initial_xendomain() &&
+			    reservation.extent_order > 0)
+				return ret;
+		}
+		frame_list += tmp_ret;
+		nr_extents -= tmp_ret;
+		ret += tmp_ret;
+	}
+	return ret;
+}
+EXPORT_SYMBOL(ia64_xenmem_reservation_op);
+
+//XXX same as i386, x86_64 contiguous_bitmap_set(), contiguous_bitmap_clear()
+// move those to lib/contiguous_bitmap?
+//XXX discontigmem/sparsemem
+
+/*
+ * Bitmap is indexed by page number. If bit is set, the page is part of a
+ * xen_create_contiguous_region() area of memory.
+ */
+unsigned long *contiguous_bitmap;
+
+void
+contiguous_bitmap_init(unsigned long end_pfn)
+{
+	unsigned long size = (end_pfn + 2 * BITS_PER_LONG) >> 3;
+	contiguous_bitmap = alloc_bootmem_low_pages(size);
+	BUG_ON(!contiguous_bitmap);
+	memset(contiguous_bitmap, 0, size);
+}
+
+#if 0
+int
+contiguous_bitmap_test(void* p)
+{
+	return test_bit(__pa(p) >> PAGE_SHIFT, contiguous_bitmap);
+}
+#endif
+
+static void contiguous_bitmap_set(
+	unsigned long first_page, unsigned long nr_pages)
+{
+	unsigned long start_off, end_off, curr_idx, end_idx;
+
+	curr_idx  = first_page / BITS_PER_LONG;
+	start_off = first_page & (BITS_PER_LONG-1);
+	end_idx   = (first_page + nr_pages) / BITS_PER_LONG;
+	end_off   = (first_page + nr_pages) & (BITS_PER_LONG-1);
+
+	if (curr_idx == end_idx) {
+		contiguous_bitmap[curr_idx] |=
+			((1UL<<end_off)-1) & -(1UL<<start_off);
+	} else {
+		contiguous_bitmap[curr_idx] |= -(1UL<<start_off);
+		while ( ++curr_idx < end_idx )
+			contiguous_bitmap[curr_idx] = ~0UL;
+		contiguous_bitmap[curr_idx] |= (1UL<<end_off)-1;
+	}
+}
+
+static void contiguous_bitmap_clear(
+	unsigned long first_page, unsigned long nr_pages)
+{
+	unsigned long start_off, end_off, curr_idx, end_idx;
+
+	curr_idx  = first_page / BITS_PER_LONG;
+	start_off = first_page & (BITS_PER_LONG-1);
+	end_idx   = (first_page + nr_pages) / BITS_PER_LONG;
+	end_off   = (first_page + nr_pages) & (BITS_PER_LONG-1);
+
+	if (curr_idx == end_idx) {
+		contiguous_bitmap[curr_idx] &=
+			-(1UL<<end_off) | ((1UL<<start_off)-1);
+	} else {
+		contiguous_bitmap[curr_idx] &= (1UL<<start_off)-1;
+		while ( ++curr_idx != end_idx )
+			contiguous_bitmap[curr_idx] = 0;
+		contiguous_bitmap[curr_idx] &= -(1UL<<end_off);
+	}
+}
+
+// __xen_create_contiguous_region(), __xen_destroy_contiguous_region()
+// are based on i386 xen_create_contiguous_region(),
+// xen_destroy_contiguous_region()
+
+/* Protected by balloon_lock. */
+#define MAX_CONTIG_ORDER 7
+static unsigned long discontig_frames[1<<MAX_CONTIG_ORDER];
+
+/* Ensure multi-page extents are contiguous in machine memory. */
+int
+__xen_create_contiguous_region(unsigned long vstart,
+			       unsigned int order, unsigned int address_bits)
+{
+	unsigned long error = 0;
+	unsigned long gphys = __pa(vstart);
+	unsigned long start_gpfn = gphys >> PAGE_SHIFT;
+	unsigned long num_gpfn = 1 << order;
+	unsigned long i;
+	unsigned long flags;
+
+	unsigned long *in_frames = discontig_frames, out_frame;
+	int success;
+	struct xen_memory_exchange exchange = {
+		.in = {
+			.nr_extents   = num_gpfn,
+			.extent_order = 0,
+			.domid        = DOMID_SELF
+		},
+		.out = {
+			 .nr_extents   = 1,
+			 .extent_order = order,
+			 .address_bits = address_bits,
+			 .domid        = DOMID_SELF
+		 },
+		.nr_exchanged = 0
+	};
+
+	if (unlikely(order > MAX_CONTIG_ORDER))
+		return -ENOMEM;
+	
+	set_xen_guest_handle(exchange.in.extent_start, in_frames);
+	set_xen_guest_handle(exchange.out.extent_start, &out_frame);
+
+	scrub_pages(vstart, num_gpfn);
+
+	balloon_lock(flags);
+
+	/* Get a new contiguous memory extent. */
+	for (i = 0; i < num_gpfn; i++) {
+		in_frames[i] = start_gpfn + i;
+	}
+	out_frame = start_gpfn;
+	error = HYPERVISOR_memory_op(XENMEM_exchange, &exchange);
+	success = (exchange.nr_exchanged == num_gpfn);
+	BUG_ON(!success && ((exchange.nr_exchanged != 0) || (error == 0)));
+	BUG_ON(success && (error != 0));
+	if (unlikely(error == -ENOSYS)) {
+		/* Compatibility when XENMEM_exchange is unsupported. */
+		error = HYPERVISOR_memory_op(XENMEM_decrease_reservation,
+					     &exchange.in);
+		BUG_ON(error != num_gpfn);
+		error = HYPERVISOR_memory_op(XENMEM_populate_physmap,
+					     &exchange.out);
+		if (error != 1) {
+			/* Couldn't get special memory: fall back to normal. */
+			for (i = 0; i < num_gpfn; i++) {
+				in_frames[i] = start_gpfn + i;
+			}
+			error = HYPERVISOR_memory_op(XENMEM_populate_physmap,
+						     &exchange.in);
+			BUG_ON(error != num_gpfn);
+			success = 0;
+		} else
+			success = 1;
+	}
+	if (success)
+		contiguous_bitmap_set(start_gpfn, num_gpfn);
+#if 0
+	if (success) {
+		unsigned long mfn;
+		unsigned long mfn_prev = ~0UL;
+		for (i = 0; i < num_gpfn; i++) {
+			mfn = pfn_to_mfn_for_dma(start_gpfn + i);
+			if (mfn_prev != ~0UL && mfn != mfn_prev + 1) {
+				xprintk("\n");
+				xprintk("%s:%d order %d "
+					"start 0x%lx bus 0x%lx "
+					"machine 0x%lx\n",
+					__func__, __LINE__, order,
+					vstart, virt_to_bus((void*)vstart),
+					phys_to_machine_for_dma(gphys));
+				xprintk("mfn: ");
+				for (i = 0; i < num_gpfn; i++) {
+					mfn = pfn_to_mfn_for_dma(
+						start_gpfn + i);
+					xprintk("0x%lx ", mfn);
+				}
+				xprintk("\n");
+				break;
+			}
+			mfn_prev = mfn;
+		}
+	}
+#endif
+	balloon_unlock(flags);
+	return success? 0: -ENOMEM;
+}
+
+void
+__xen_destroy_contiguous_region(unsigned long vstart, unsigned int order)
+{
+	unsigned long flags;
+	unsigned long error = 0;
+	unsigned long start_gpfn = __pa(vstart) >> PAGE_SHIFT;
+	unsigned long num_gpfn = 1UL << order;
+	unsigned long i;
+
+	unsigned long *out_frames = discontig_frames, in_frame;
+	int            success;
+	struct xen_memory_exchange exchange = {
+		.in = {
+			.nr_extents   = 1,
+			.extent_order = order,
+			.domid        = DOMID_SELF
+		},
+		.out = {
+			 .nr_extents   = num_gpfn,
+			 .extent_order = 0,
+			 .address_bits = 0,
+			 .domid        = DOMID_SELF
+		 },
+		.nr_exchanged = 0
+        };
+	
+
+	if (!test_bit(start_gpfn, contiguous_bitmap))
+		return;
+
+	if (unlikely(order > MAX_CONTIG_ORDER))
+		return;
+
+	set_xen_guest_handle(exchange.in.extent_start, &in_frame);
+	set_xen_guest_handle(exchange.out.extent_start, out_frames);
+
+	scrub_pages(vstart, num_gpfn);
+
+	balloon_lock(flags);
+
+	contiguous_bitmap_clear(start_gpfn, num_gpfn);
+
+        /* Do the exchange for non-contiguous MFNs. */
+	in_frame = start_gpfn;
+	for (i = 0; i < num_gpfn; i++) {
+		out_frames[i] = start_gpfn + i;
+	}
+	error = HYPERVISOR_memory_op(XENMEM_exchange, &exchange);
+	success = (exchange.nr_exchanged == 1);
+	BUG_ON(!success && ((exchange.nr_exchanged != 0) || (error == 0)));
+	BUG_ON(success && (error != 0));
+	if (unlikely(error == -ENOSYS)) {
+                /* Compatibility when XENMEM_exchange is unsupported. */
+		error = HYPERVISOR_memory_op(XENMEM_decrease_reservation,
+					     &exchange.in);
+		BUG_ON(error != 1);
+
+		error = HYPERVISOR_memory_op(XENMEM_populate_physmap,
+					     &exchange.out);
+		BUG_ON(error != num_gpfn);
+	}
+	balloon_unlock(flags);
+}
+
+
+///////////////////////////////////////////////////////////////////////////
+// grant table hack
+// cmd: GNTTABOP_xxx
+
+#include <linux/mm.h>
+#include <xen/interface/xen.h>
+#include <xen/gnttab.h>
+
+static void
+gnttab_map_grant_ref_pre(struct gnttab_map_grant_ref *uop)
+{
+	uint32_t flags;
+
+	flags = uop->flags;
+
+	if (flags & GNTMAP_host_map) {
+		if (flags & GNTMAP_application_map) {
+			xprintd("GNTMAP_application_map is not supported yet: flags 0x%x\n", flags);
+			BUG();
+		}
+		if (flags & GNTMAP_contains_pte) {
+			xprintd("GNTMAP_contains_pte is not supported yet flags 0x%x\n", flags);
+			BUG();
+		}
+	} else if (flags & GNTMAP_device_map) {
+		xprintd("GNTMAP_device_map is not supported yet 0x%x\n", flags);
+		BUG();//XXX not yet. actually this flag is not used.
+	} else {
+		BUG();
+	}
+}
+
+int
+HYPERVISOR_grant_table_op(unsigned int cmd, void *uop, unsigned int count)
+{
+	__u64 va1, va2, pa1, pa2;
+
+	if (cmd == GNTTABOP_map_grant_ref) {
+		unsigned int i;
+		for (i = 0; i < count; i++) {
+			gnttab_map_grant_ref_pre(
+				(struct gnttab_map_grant_ref*)uop + i);
+		}
+	}
+	va1 = (__u64)uop & PAGE_MASK;
+	pa1 = pa2 = 0;
+	if ((REGION_NUMBER(va1) == 5) &&
+	    ((va1 - KERNEL_START) >= KERNEL_TR_PAGE_SIZE)) {
+		pa1 = ia64_tpa(va1);
+		if (cmd <= GNTTABOP_transfer) {
+			static uint32_t uop_size[GNTTABOP_transfer + 1] = {
+				sizeof(struct gnttab_map_grant_ref),
+				sizeof(struct gnttab_unmap_grant_ref),
+				sizeof(struct gnttab_setup_table),
+				sizeof(struct gnttab_dump_table),
+				sizeof(struct gnttab_transfer),
+			};
+			va2 = (__u64)uop + (uop_size[cmd] * count) - 1;
+			va2 &= PAGE_MASK;
+			if (va1 != va2) {
+				/* maximum size of uop is 2pages */
+				BUG_ON(va2 > va1 + PAGE_SIZE);
+				pa2 = ia64_tpa(va2);
+			}
+		}
+	}
+	return ____HYPERVISOR_grant_table_op(cmd, uop, count, pa1, pa2);
+}
+EXPORT_SYMBOL(HYPERVISOR_grant_table_op);
+
+///////////////////////////////////////////////////////////////////////////
+// PageForeign(), SetPageForeign(), ClearPageForeign()
+
+struct address_space xen_ia64_foreign_dummy_mapping;
+EXPORT_SYMBOL(xen_ia64_foreign_dummy_mapping);
+
+///////////////////////////////////////////////////////////////////////////
+// foreign mapping
+#include <linux/efi.h>
+#include <asm/meminit.h> // for IA64_GRANULE_SIZE, GRANULEROUND{UP,DOWN}()
+
+static unsigned long privcmd_resource_min = 0;
+// Xen/ia64 currently can handle pseudo physical address bits up to
+// (PAGE_SHIFT * 3)
+static unsigned long privcmd_resource_max = GRANULEROUNDDOWN((1UL << (PAGE_SHIFT * 3)) - 1);
+static unsigned long privcmd_resource_align = IA64_GRANULE_SIZE;
+
+static unsigned long
+md_end_addr(const efi_memory_desc_t *md)
+{
+	return md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT);
+}
+
+#define XEN_IA64_PRIVCMD_LEAST_GAP_SIZE	(1024 * 1024 * 1024UL)
+static int
+xen_ia64_privcmd_check_size(unsigned long start, unsigned long end)
+{
+	return (start < end &&
+		(end - start) > XEN_IA64_PRIVCMD_LEAST_GAP_SIZE);
+}
+
+static int __init
+xen_ia64_privcmd_init(void)
+{
+	void *efi_map_start, *efi_map_end, *p;
+	u64 efi_desc_size;
+	efi_memory_desc_t *md;
+	unsigned long tmp_min;
+	unsigned long tmp_max;
+	unsigned long gap_size;
+	unsigned long prev_end;
+
+	if (!is_running_on_xen())
+		return -1;
+
+	efi_map_start = __va(ia64_boot_param->efi_memmap);
+	efi_map_end   = efi_map_start + ia64_boot_param->efi_memmap_size;
+	efi_desc_size = ia64_boot_param->efi_memdesc_size;
+
+	// at first check the used highest address
+	for (p = efi_map_start; p < efi_map_end; p += efi_desc_size) {
+		// nothing
+	}
+	md = p - efi_desc_size;
+	privcmd_resource_min = GRANULEROUNDUP(md_end_addr(md));
+	if (xen_ia64_privcmd_check_size(privcmd_resource_min,
+					privcmd_resource_max)) {
+		goto out;
+	}
+
+	// the used highest address is too large. try to find the largest gap.
+	tmp_min = privcmd_resource_max;
+	tmp_max = 0;
+	gap_size = 0;
+	prev_end = 0;
+	for (p = efi_map_start;
+	     p < efi_map_end - efi_desc_size;
+	     p += efi_desc_size) {
+		unsigned long end;
+		efi_memory_desc_t* next;
+		unsigned long next_start;
+
+		md = p;
+		end = md_end_addr(md);
+		if (end > privcmd_resource_max) {
+			break;
+		}
+		if (end < prev_end) {
+			// work around. 
+			// Xen may pass incompletely sorted memory
+			// descriptors like
+			// [x, x + length]
+			// [x, x]
+			// this order should be reversed.
+			continue;
+		}
+		next = p + efi_desc_size;
+		next_start = next->phys_addr;
+		if (next_start > privcmd_resource_max) {
+			next_start = privcmd_resource_max;
+		}
+		if (end < next_start && gap_size < (next_start - end)) {
+			tmp_min = end;
+			tmp_max = next_start;
+			gap_size = tmp_max - tmp_min;
+		}
+		prev_end = end;
+	}
+
+	privcmd_resource_min = GRANULEROUNDUP(tmp_min);
+	if (xen_ia64_privcmd_check_size(privcmd_resource_min, tmp_max)) {
+		privcmd_resource_max = tmp_max;
+		goto out;
+	}
+
+	privcmd_resource_min = tmp_min;
+	privcmd_resource_max = tmp_max;
+	if (!xen_ia64_privcmd_check_size(privcmd_resource_min,
+					 privcmd_resource_max)) {
+		// Any large enough gap isn't found.
+		// go ahead anyway with the warning hoping that large region
+		// won't be requested.
+		printk(KERN_WARNING "xen privcmd: large enough region for privcmd mmap is not found.\n");
+	}
+
+out:
+	printk(KERN_INFO "xen privcmd uses pseudo physical addr range [0x%lx, 0x%lx] (%ldMB)\n",
+	       privcmd_resource_min, privcmd_resource_max, 
+	       (privcmd_resource_max - privcmd_resource_min) >> 20);
+	BUG_ON(privcmd_resource_min >= privcmd_resource_max);
+	return 0;
+}
+late_initcall(xen_ia64_privcmd_init);
+
+struct xen_ia64_privcmd_entry {
+	atomic_t	map_count;
+#define INVALID_GPFN	(~0UL)
+	unsigned long	gpfn;
+};
+
+struct xen_ia64_privcmd_range {
+	atomic_t			ref_count;
+	unsigned long			pgoff; // in PAGE_SIZE
+	struct resource*		res;
+
+	unsigned long			num_entries;
+	struct xen_ia64_privcmd_entry	entries[0];
+};
+
+struct xen_ia64_privcmd_vma {
+	struct xen_ia64_privcmd_range*	range;
+
+	unsigned long			num_entries;
+	struct xen_ia64_privcmd_entry*	entries;
+};
+
+static void
+xen_ia64_privcmd_init_entry(struct xen_ia64_privcmd_entry* entry)
+{
+	atomic_set(&entry->map_count, 0);
+	entry->gpfn = INVALID_GPFN;
+}
+
+static int
+xen_ia64_privcmd_entry_mmap(struct vm_area_struct* vma,
+			    unsigned long addr,
+			    struct xen_ia64_privcmd_range* privcmd_range,
+			    int i,
+			    unsigned long mfn,
+			    pgprot_t prot,
+			    domid_t domid)
+{
+	int error = 0;
+	struct xen_ia64_privcmd_entry* entry = &privcmd_range->entries[i];
+	unsigned long gpfn;
+	unsigned long flags;
+
+	if ((addr & ~PAGE_MASK) != 0 || mfn == INVALID_MFN) {
+		error = -EINVAL;
+		goto out;
+	}
+
+	if (entry->gpfn != INVALID_GPFN) {
+		error = -EBUSY;
+		goto out;
+	}
+	gpfn = (privcmd_range->res->start >> PAGE_SHIFT) + i;
+
+	flags = ASSIGN_writable;
+	if (pgprot_val(prot) == PROT_READ) {
+		flags = ASSIGN_readonly;
+	}
+	error = HYPERVISOR_add_physmap(gpfn, mfn, flags, domid);
+	if (error != 0) {
+		goto out;
+	}
+
+	prot = vma->vm_page_prot;
+	error = remap_pfn_range(vma, addr, gpfn, 1 << PAGE_SHIFT, prot);
+	if (error != 0) {
+		error = HYPERVISOR_zap_physmap(gpfn, 0);
+		if (error) {
+			BUG();//XXX
+		}
+	} else {
+		atomic_inc(&entry->map_count);
+		entry->gpfn = gpfn;
+	}
+
+out:
+	return error;
+}
+
+static void
+xen_ia64_privcmd_entry_munmap(struct xen_ia64_privcmd_range* privcmd_range,
+			      int i)
+{
+	struct xen_ia64_privcmd_entry* entry = &privcmd_range->entries[i];
+	unsigned long gpfn = entry->gpfn;
+	//gpfn = (privcmd_range->res->start >> PAGE_SHIFT) +
+	//	(vma->vm_pgoff - privcmd_range->pgoff);
+	int error;
+
+	error = HYPERVISOR_zap_physmap(gpfn, 0);
+	if (error) {
+		BUG();//XXX
+	}
+	entry->gpfn = INVALID_GPFN;
+}
+
+static void
+xen_ia64_privcmd_entry_open(struct xen_ia64_privcmd_range* privcmd_range,
+			    int i)
+{
+	struct xen_ia64_privcmd_entry* entry = &privcmd_range->entries[i];
+	if (entry->gpfn != INVALID_GPFN) {
+		atomic_inc(&entry->map_count);
+	} else {
+		BUG_ON(atomic_read(&entry->map_count) != 0);
+	}
+}
+
+static void
+xen_ia64_privcmd_entry_close(struct xen_ia64_privcmd_range* privcmd_range,
+			     int i)
+{
+	struct xen_ia64_privcmd_entry* entry = &privcmd_range->entries[i];
+	if (entry->gpfn != INVALID_GPFN &&
+	    atomic_dec_and_test(&entry->map_count)) {
+		xen_ia64_privcmd_entry_munmap(privcmd_range, i);
+	}
+}
+
+static void xen_ia64_privcmd_vma_open(struct vm_area_struct* vma);
+static void xen_ia64_privcmd_vma_close(struct vm_area_struct* vma);
+
+struct vm_operations_struct xen_ia64_privcmd_vm_ops = {
+	.open = &xen_ia64_privcmd_vma_open,
+	.close = &xen_ia64_privcmd_vma_close,
+};
+
+static void
+__xen_ia64_privcmd_vma_open(struct vm_area_struct* vma,
+			    struct xen_ia64_privcmd_vma* privcmd_vma,
+			    struct xen_ia64_privcmd_range* privcmd_range)
+{
+	unsigned long entry_offset = vma->vm_pgoff - privcmd_range->pgoff;
+	unsigned long num_entries = (vma->vm_end - vma->vm_start) >> PAGE_SHIFT;
+	unsigned long i;
+
+	BUG_ON(entry_offset < 0);
+	BUG_ON(entry_offset + num_entries > privcmd_range->num_entries);
+
+	privcmd_vma->range = privcmd_range;
+	privcmd_vma->num_entries = num_entries;
+	privcmd_vma->entries = &privcmd_range->entries[entry_offset];
+	vma->vm_private_data = privcmd_vma;
+	for (i = 0; i < privcmd_vma->num_entries; i++) {
+		xen_ia64_privcmd_entry_open(privcmd_range, entry_offset + i);
+	}
+
+	vma->vm_private_data = privcmd_vma;
+	vma->vm_ops = &xen_ia64_privcmd_vm_ops;
+}
+
+static void
+xen_ia64_privcmd_vma_open(struct vm_area_struct* vma)
+{
+	struct xen_ia64_privcmd_vma* privcmd_vma = (struct xen_ia64_privcmd_vma*)vma->vm_private_data;
+	struct xen_ia64_privcmd_range* privcmd_range = privcmd_vma->range;
+
+	atomic_inc(&privcmd_range->ref_count);
+	// vm_op->open() can't fail.
+	privcmd_vma = kmalloc(sizeof(*privcmd_vma), GFP_KERNEL | __GFP_NOFAIL);
+
+	__xen_ia64_privcmd_vma_open(vma, privcmd_vma, privcmd_range);
+}
+
+static void
+xen_ia64_privcmd_vma_close(struct vm_area_struct* vma)
+{
+	struct xen_ia64_privcmd_vma* privcmd_vma =
+		(struct xen_ia64_privcmd_vma*)vma->vm_private_data;
+	struct xen_ia64_privcmd_range* privcmd_range = privcmd_vma->range;
+	unsigned long entry_offset = vma->vm_pgoff - privcmd_range->pgoff;
+	unsigned long i;
+
+	for (i = 0; i < privcmd_vma->num_entries; i++) {
+		xen_ia64_privcmd_entry_close(privcmd_range, entry_offset + i);
+	}
+	vma->vm_private_data = NULL;
+	kfree(privcmd_vma);
+
+	if (atomic_dec_and_test(&privcmd_range->ref_count)) {
+#if 1
+		for (i = 0; i < privcmd_range->num_entries; i++) {
+			struct xen_ia64_privcmd_entry* entry =
+				&privcmd_range->entries[i];
+			BUG_ON(atomic_read(&entry->map_count) != 0);
+			BUG_ON(entry->gpfn != INVALID_GPFN);
+		}
+#endif
+		release_resource(privcmd_range->res);
+		kfree(privcmd_range->res);
+		vfree(privcmd_range);
+	}
+}
+
+int
+privcmd_mmap(struct file * file, struct vm_area_struct * vma)
+{
+	int error;
+	unsigned long size = vma->vm_end - vma->vm_start;
+	unsigned long num_entries = size >> PAGE_SHIFT;
+	struct xen_ia64_privcmd_range* privcmd_range = NULL;
+	struct xen_ia64_privcmd_vma* privcmd_vma = NULL;
+	struct resource* res = NULL;
+	unsigned long i;
+	BUG_ON(!is_running_on_xen());
+
+	BUG_ON(file->private_data != NULL);
+
+	error = -ENOMEM;
+	privcmd_range =
+		vmalloc(sizeof(*privcmd_range) +
+			sizeof(privcmd_range->entries[0]) * num_entries);
+	if (privcmd_range == NULL) {
+		goto out_enomem0;
+	}
+	privcmd_vma = kmalloc(sizeof(*privcmd_vma), GFP_KERNEL);
+	if (privcmd_vma == NULL) {
+		goto out_enomem1;
+	}
+	res = kzalloc(sizeof(*res), GFP_KERNEL);
+	if (res == NULL) {
+		goto out_enomem1;
+	}
+	res->name = "Xen privcmd mmap";
+	error = allocate_resource(&iomem_resource, res, size,
+				  privcmd_resource_min, privcmd_resource_max,
+				  privcmd_resource_align, NULL, NULL);
+	if (error) {
+		goto out_enomem1;
+	}
+	privcmd_range->res = res;
+
+	/* DONTCOPY is essential for Xen as copy_page_range is broken. */
+	vma->vm_flags |= VM_RESERVED | VM_IO | VM_DONTCOPY | VM_PFNMAP;
+
+	atomic_set(&privcmd_range->ref_count, 1);
+	privcmd_range->pgoff = vma->vm_pgoff;
+	privcmd_range->num_entries = num_entries;
+	for (i = 0; i < privcmd_range->num_entries; i++) {
+		xen_ia64_privcmd_init_entry(&privcmd_range->entries[i]);
+	}
+
+	__xen_ia64_privcmd_vma_open(vma, privcmd_vma, privcmd_range);
+	return 0;
+
+out_enomem1:
+	kfree(res);
+	kfree(privcmd_vma);
+out_enomem0:
+	vfree(privcmd_range);
+	return error;
+}
+
+int
+direct_remap_pfn_range(struct vm_area_struct *vma,
+		       unsigned long address,	// process virtual address
+		       unsigned long mfn,	// mfn, mfn + 1, ... mfn + size/PAGE_SIZE
+		       unsigned long size,
+		       pgprot_t prot,
+		       domid_t  domid)		// target domain
+{
+	struct xen_ia64_privcmd_vma* privcmd_vma =
+		(struct xen_ia64_privcmd_vma*)vma->vm_private_data;
+	struct xen_ia64_privcmd_range* privcmd_range = privcmd_vma->range;
+	unsigned long entry_offset = vma->vm_pgoff - privcmd_range->pgoff;
+
+	unsigned long i;
+	unsigned long offset;
+	int error = 0;
+	BUG_ON(!is_running_on_xen());
+
+#if 0
+	if (prot != vm->vm_page_prot) {
+		return -EINVAL;
+	}
+#endif
+
+	i = (address - vma->vm_start) >> PAGE_SHIFT;
+	for (offset = 0; offset < size; offset += PAGE_SIZE) {
+		error = xen_ia64_privcmd_entry_mmap(vma, (address + offset) & PAGE_MASK, privcmd_range, entry_offset + i, mfn, prot, domid);
+		if (error != 0) {
+			break;
+		}
+
+		i++;
+		mfn++;
+        }
+
+	return error;
+}
+
+
+/* Called after suspend, to resume time.  */
+void
+time_resume(void)
+{
+	extern void ia64_cpu_local_tick(void);
+
+	/* Just trigger a tick.  */
+	ia64_cpu_local_tick();
+}
diff --git a/arch/ia64/xen/util.c b/arch/ia64/xen/util.c
new file mode 100644
index 000000000..03ac49584
--- /dev/null
+++ b/arch/ia64/xen/util.c
@@ -0,0 +1,115 @@
+/******************************************************************************
+ * arch/ia64/xen/util.c
+ * This file is the ia64 counterpart of drivers/xen/util.c
+ *
+ * Copyright (c) 2006 Isaku Yamahata <yamahata at valinux co jp>
+ *                    VA Linux Systems Japan K.K.
+ *
+ * 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/mm.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/vmalloc.h>
+#include <asm/uaccess.h>
+#include <xen/driver_util.h>
+
+struct vm_struct *alloc_vm_area(unsigned long size)
+{
+	int order;
+	unsigned long virt;
+	unsigned long nr_pages;
+	struct vm_struct* area;
+	
+	order = get_order(size);
+	virt = __get_free_pages(GFP_KERNEL, order);
+	if (virt == 0) {
+		goto err0;
+	}
+	nr_pages = 1 << order;
+	scrub_pages(virt, nr_pages);
+	
+	area = kmalloc(sizeof(*area), GFP_KERNEL);
+	if (area == NULL) {
+		goto err1;
+	}
+	
+        area->flags = VM_IOREMAP;//XXX
+        area->addr = (void*)virt;
+        area->size = size;
+        area->pages = NULL; //XXX
+        area->nr_pages = nr_pages;
+        area->phys_addr = 0; 	/* xenbus_map_ring_valloc uses this field!  */
+
+	return area;
+
+err1:
+	free_pages(virt, order);
+err0:
+	return NULL;
+	
+}
+EXPORT_SYMBOL_GPL(alloc_vm_area);
+
+void free_vm_area(struct vm_struct *area)
+{
+	unsigned int order = get_order(area->size);
+	unsigned long i;
+	unsigned long phys_addr = __pa(area->addr);
+
+	// This area is used for foreign page mappping.
+	// So underlying machine page may not be assigned.
+	for (i = 0; i < (1 << order); i++) {
+		unsigned long ret;
+		unsigned long gpfn = (phys_addr >> PAGE_SHIFT) + i;
+		struct xen_memory_reservation reservation = {
+			.nr_extents   = 1,
+			.address_bits = 0,
+			.extent_order = 0,
+			.domid        = DOMID_SELF
+		};
+		set_xen_guest_handle(reservation.extent_start, &gpfn);
+		ret = HYPERVISOR_memory_op(XENMEM_populate_physmap,
+					   &reservation);
+		BUG_ON(ret != 1);
+	}
+	free_pages((unsigned long)area->addr, order);
+	kfree(area);
+}
+EXPORT_SYMBOL_GPL(free_vm_area);
+
+void lock_vm_area(struct vm_struct *area)
+{
+	// nothing
+}
+EXPORT_SYMBOL_GPL(lock_vm_area);
+
+void unlock_vm_area(struct vm_struct *area)
+{
+	// nothing
+}
+EXPORT_SYMBOL_GPL(unlock_vm_area);
+
+/*
+ * Local variables:
+ *  c-file-style: "linux"
+ *  indent-tabs-mode: t
+ *  c-indent-level: 8
+ *  c-basic-offset: 8
+ *  tab-width: 8
+ * End:
+ */
diff --git a/arch/ia64/xen/xenentry.S b/arch/ia64/xen/xenentry.S
new file mode 100644
index 000000000..ad9e79a91
--- /dev/null
+++ b/arch/ia64/xen/xenentry.S
@@ -0,0 +1,867 @@
+/*
+ * ia64/xen/entry.S
+ *
+ * Alternate kernel routines for Xen.  Heavily leveraged from
+ *   ia64/kernel/entry.S
+ *
+ * Copyright (C) 2005 Hewlett-Packard Co
+ *	Dan Magenheimer <dan.magenheimer@.hp.com>
+ */
+
+#include <asm/asmmacro.h>
+#include <asm/cache.h>
+#include <asm/errno.h>
+#include <asm/kregs.h>
+#include <asm/asm-offsets.h>
+#include <asm/pgtable.h>
+#include <asm/percpu.h>
+#include <asm/processor.h>
+#include <asm/thread_info.h>
+#include <asm/unistd.h>
+
+#ifdef CONFIG_XEN
+#include "xenminstate.h"
+#else
+#include "minstate.h"
+#endif
+
+/*
+ * prev_task <- ia64_switch_to(struct task_struct *next)
+ *	With Ingo's new scheduler, interrupts are disabled when this routine gets
+ *	called.  The code starting at .map relies on this.  The rest of the code
+ *	doesn't care about the interrupt masking status.
+ */
+#ifdef CONFIG_XEN
+GLOBAL_ENTRY(xen_switch_to)
+	.prologue
+	alloc r16=ar.pfs,1,0,0,0
+	movl r22=running_on_xen;;
+	ld4 r22=[r22];;
+	cmp.eq p7,p0=r22,r0
+(p7)	br.cond.sptk.many __ia64_switch_to;;
+#else
+GLOBAL_ENTRY(ia64_switch_to)
+	.prologue
+	alloc r16=ar.pfs,1,0,0,0
+#endif
+	DO_SAVE_SWITCH_STACK
+	.body
+
+	adds r22=IA64_TASK_THREAD_KSP_OFFSET,r13
+	movl r25=init_task
+	mov r27=IA64_KR(CURRENT_STACK)
+	adds r21=IA64_TASK_THREAD_KSP_OFFSET,in0
+	dep r20=0,in0,61,3		// physical address of "next"
+	;;
+	st8 [r22]=sp			// save kernel stack pointer of old task
+	shr.u r26=r20,IA64_GRANULE_SHIFT
+	cmp.eq p7,p6=r25,in0
+	;;
+#ifdef CONFIG_XEN
+	movl r8=XSI_PSR_IC
+	;;
+	st4 [r8]=r0	// force psr.ic off for hyperprivop(s)
+	;;
+#endif
+	/*
+	 * If we've already mapped this task's page, we can skip doing it again.
+	 */
+(p6)	cmp.eq p7,p6=r26,r27
+(p6)	br.cond.dpnt .map
+	;;
+.done:
+#ifdef CONFIG_XEN
+	// psr.ic already off
+	// update "current" application register
+	mov r8=IA64_KR_CURRENT
+	mov r9=in0;;
+	XEN_HYPER_SET_KR
+	ld8 sp=[r21]			// load kernel stack pointer of new task
+	movl r27=XSI_PSR_IC
+	mov r8=1
+	;;
+	st4 [r27]=r8			// psr.ic back on
+#else
+	ld8 sp=[r21]			// load kernel stack pointer of new task
+	mov IA64_KR(CURRENT)=in0	// update "current" application register
+#endif
+	mov r8=r13			// return pointer to previously running task
+	mov r13=in0			// set "current" pointer
+	;;
+	DO_LOAD_SWITCH_STACK
+
+#ifdef CONFIG_SMP
+	sync.i				// ensure "fc"s done by this CPU are visible on other CPUs
+#endif
+	br.ret.sptk.many rp		// boogie on out in new context
+
+.map:
+#ifdef CONFIG_XEN
+	// psr.ic already off
+#else
+	rsm psr.ic			// interrupts (psr.i) are already disabled here
+#endif
+	movl r25=PAGE_KERNEL
+	;;
+	srlz.d
+	or r23=r25,r20			// construct PA | page properties
+	mov r25=IA64_GRANULE_SHIFT<<2
+	;;
+#ifdef CONFIG_XEN
+	movl r8=XSI_ITIR
+	;;
+	st8 [r8]=r25
+	;;
+	movl r8=XSI_IFA
+	;;
+	st8 [r8]=in0			 // VA of next task...
+	;;
+	mov r25=IA64_TR_CURRENT_STACK
+	// remember last page we mapped...
+	mov r8=IA64_KR_CURRENT_STACK
+	mov r9=r26;;
+	XEN_HYPER_SET_KR;;
+#else
+	mov cr.itir=r25
+	mov cr.ifa=in0			// VA of next task...
+	;;
+	mov r25=IA64_TR_CURRENT_STACK
+	mov IA64_KR(CURRENT_STACK)=r26	// remember last page we mapped...
+#endif
+	;;
+	itr.d dtr[r25]=r23		// wire in new mapping...
+#ifndef CONFIG_XEN
+	ssm psr.ic			// reenable the psr.ic bit
+	;;
+	srlz.d
+#endif
+	br.cond.sptk .done
+#ifdef CONFIG_XEN
+END(xen_switch_to)
+#else
+END(ia64_switch_to)
+#endif
+
+	/*
+	 * Invoke a system call, but do some tracing before and after the call.
+	 * We MUST preserve the current register frame throughout this routine
+	 * because some system calls (such as ia64_execve) directly
+	 * manipulate ar.pfs.
+	 */
+#ifdef CONFIG_XEN
+GLOBAL_ENTRY(xen_trace_syscall)
+	PT_REGS_UNWIND_INFO(0)
+	movl r16=running_on_xen;;
+	ld4 r16=[r16];;
+	cmp.eq p7,p0=r16,r0
+(p7)	br.cond.sptk.many __ia64_trace_syscall;;
+#else
+GLOBAL_ENTRY(ia64_trace_syscall)
+	PT_REGS_UNWIND_INFO(0)
+#endif
+	/*
+	 * We need to preserve the scratch registers f6-f11 in case the system
+	 * call is sigreturn.
+	 */
+	adds r16=PT(F6)+16,sp
+	adds r17=PT(F7)+16,sp
+	;;
+ 	stf.spill [r16]=f6,32
+ 	stf.spill [r17]=f7,32
+	;;
+ 	stf.spill [r16]=f8,32
+ 	stf.spill [r17]=f9,32
+	;;
+ 	stf.spill [r16]=f10
+ 	stf.spill [r17]=f11
+	br.call.sptk.many rp=syscall_trace_enter // give parent a chance to catch syscall args
+	adds r16=PT(F6)+16,sp
+	adds r17=PT(F7)+16,sp
+	;;
+	ldf.fill f6=[r16],32
+	ldf.fill f7=[r17],32
+	;;
+	ldf.fill f8=[r16],32
+	ldf.fill f9=[r17],32
+	;;
+	ldf.fill f10=[r16]
+	ldf.fill f11=[r17]
+	// the syscall number may have changed, so re-load it and re-calculate the
+	// syscall entry-point:
+	adds r15=PT(R15)+16,sp			// r15 = &pt_regs.r15 (syscall #)
+	;;
+	ld8 r15=[r15]
+	mov r3=NR_syscalls - 1
+	;;
+	adds r15=-1024,r15
+	movl r16=sys_call_table
+	;;
+	shladd r20=r15,3,r16			// r20 = sys_call_table + 8*(syscall-1024)
+	cmp.leu p6,p7=r15,r3
+	;;
+(p6)	ld8 r20=[r20]				// load address of syscall entry point
+(p7)	movl r20=sys_ni_syscall
+	;;
+	mov b6=r20
+	br.call.sptk.many rp=b6			// do the syscall
+.strace_check_retval:
+	cmp.lt p6,p0=r8,r0			// syscall failed?
+	adds r2=PT(R8)+16,sp			// r2 = &pt_regs.r8
+	adds r3=PT(R10)+16,sp			// r3 = &pt_regs.r10
+	mov r10=0
+(p6)	br.cond.sptk strace_error		// syscall failed ->
+	;;					// avoid RAW on r10
+.strace_save_retval:
+.mem.offset 0,0; st8.spill [r2]=r8		// store return value in slot for r8
+.mem.offset 8,0; st8.spill [r3]=r10		// clear error indication in slot for r10
+	br.call.sptk.many rp=syscall_trace_leave // give parent a chance to catch return value
+.ret3:
+(pUStk)	cmp.eq.unc p6,p0=r0,r0			// p6 <- pUStk
+	br.cond.sptk .work_pending_syscall_end
+
+strace_error:
+	ld8 r3=[r2]				// load pt_regs.r8
+	sub r9=0,r8				// negate return value to get errno value
+	;;
+	cmp.ne p6,p0=r3,r0			// is pt_regs.r8!=0?
+	adds r3=16,r2				// r3=&pt_regs.r10
+	;;
+(p6)	mov r10=-1
+(p6)	mov r8=r9
+	br.cond.sptk .strace_save_retval
+#ifdef CONFIG_XEN
+END(xen_trace_syscall)
+#else
+END(ia64_trace_syscall)
+#endif
+
+/*
+ * ia64_leave_syscall(): Same as ia64_leave_kernel, except that it doesn't
+ *	need to switch to bank 0 and doesn't restore the scratch registers.
+ *	To avoid leaking kernel bits, the scratch registers are set to
+ *	the following known-to-be-safe values:
+ *
+ *		  r1: restored (global pointer)
+ *		  r2: cleared
+ *		  r3: 1 (when returning to user-level)
+ *	      r8-r11: restored (syscall return value(s))
+ *		 r12: restored (user-level stack pointer)
+ *		 r13: restored (user-level thread pointer)
+ *		 r14: set to __kernel_syscall_via_epc
+ *		 r15: restored (syscall #)
+ *	     r16-r17: cleared
+ *		 r18: user-level b6
+ *		 r19: cleared
+ *		 r20: user-level ar.fpsr
+ *		 r21: user-level b0
+ *		 r22: cleared
+ *		 r23: user-level ar.bspstore
+ *		 r24: user-level ar.rnat
+ *		 r25: user-level ar.unat
+ *		 r26: user-level ar.pfs
+ *		 r27: user-level ar.rsc
+ *		 r28: user-level ip
+ *		 r29: user-level psr
+ *		 r30: user-level cfm
+ *		 r31: user-level pr
+ *	      f6-f11: cleared
+ *		  pr: restored (user-level pr)
+ *		  b0: restored (user-level rp)
+ *	          b6: restored
+ *		  b7: set to __kernel_syscall_via_epc
+ *	     ar.unat: restored (user-level ar.unat)
+ *	      ar.pfs: restored (user-level ar.pfs)
+ *	      ar.rsc: restored (user-level ar.rsc)
+ *	     ar.rnat: restored (user-level ar.rnat)
+ *	 ar.bspstore: restored (user-level ar.bspstore)
+ *	     ar.fpsr: restored (user-level ar.fpsr)
+ *	      ar.ccv: cleared
+ *	      ar.csd: cleared
+ *	      ar.ssd: cleared
+ */
+#ifdef CONFIG_XEN
+GLOBAL_ENTRY(xen_leave_syscall)
+	PT_REGS_UNWIND_INFO(0)
+	movl r22=running_on_xen;;
+	ld4 r22=[r22];;
+	cmp.eq p7,p0=r22,r0
+(p7)	br.cond.sptk.many __ia64_leave_syscall;;
+#else
+ENTRY(ia64_leave_syscall)
+	PT_REGS_UNWIND_INFO(0)
+#endif
+	/*
+	 * work.need_resched etc. mustn't get changed by this CPU before it returns to
+	 * user- or fsys-mode, hence we disable interrupts early on.
+	 *
+	 * p6 controls whether current_thread_info()->flags needs to be check for
+	 * extra work.  We always check for extra work when returning to user-level.
+	 * With CONFIG_PREEMPT, we also check for extra work when the preempt_count
+	 * is 0.  After extra work processing has been completed, execution
+	 * resumes at .work_processed_syscall with p6 set to 1 if the extra-work-check
+	 * needs to be redone.
+	 */
+#ifdef CONFIG_PREEMPT
+	rsm psr.i				// disable interrupts
+	cmp.eq pLvSys,p0=r0,r0			// pLvSys=1: leave from syscall
+(pKStk) adds r20=TI_PRE_COUNT+IA64_TASK_SIZE,r13
+	;;
+	.pred.rel.mutex pUStk,pKStk
+(pKStk) ld4 r21=[r20]			// r21 <- preempt_count
+(pUStk)	mov r21=0			// r21 <- 0
+	;;
+	cmp.eq p6,p0=r21,r0		// p6 <- pUStk || (preempt_count == 0)
+#else /* !CONFIG_PREEMPT */
+#ifdef CONFIG_XEN
+	movl r2=XSI_PSR_I_ADDR
+	mov r18=1
+	;;
+	ld8 r2=[r2]
+	;;
+(pUStk)	st1 [r2]=r18
+#else
+(pUStk)	rsm psr.i
+#endif
+	cmp.eq pLvSys,p0=r0,r0		// pLvSys=1: leave from syscall
+(pUStk)	cmp.eq.unc p6,p0=r0,r0		// p6 <- pUStk
+#endif
+.work_processed_syscall:
+	adds r2=PT(LOADRS)+16,r12
+	adds r3=PT(AR_BSPSTORE)+16,r12
+	adds r18=TI_FLAGS+IA64_TASK_SIZE,r13
+	;;
+(p6)	ld4 r31=[r18]				// load current_thread_info()->flags
+	ld8 r19=[r2],PT(B6)-PT(LOADRS)		// load ar.rsc value for "loadrs"
+	nop.i 0
+	;;
+	mov r16=ar.bsp				// M2  get existing backing store pointer
+	ld8 r18=[r2],PT(R9)-PT(B6)		// load b6
+(p6)	and r15=TIF_WORK_MASK,r31		// any work other than TIF_SYSCALL_TRACE?
+	;;
+	ld8 r23=[r3],PT(R11)-PT(AR_BSPSTORE)	// load ar.bspstore (may be garbage)
+(p6)	cmp4.ne.unc p6,p0=r15, r0		// any special work pending?
+(p6)	br.cond.spnt .work_pending_syscall
+	;;
+	// start restoring the state saved on the kernel stack (struct pt_regs):
+	ld8 r9=[r2],PT(CR_IPSR)-PT(R9)
+	ld8 r11=[r3],PT(CR_IIP)-PT(R11)
+(pNonSys) break 0		//      bug check: we shouldn't be here if pNonSys is TRUE!
+	;;
+	invala			// M0|1 invalidate ALAT
+#ifdef CONFIG_XEN
+	movl r28=XSI_PSR_I_ADDR
+	movl r29=XSI_PSR_IC
+	;;
+	ld8 r28=[r28]
+	mov r30=1
+	;;
+	st1	[r28]=r30
+	st4	[r29]=r0	// note: clears both vpsr.i and vpsr.ic!
+	;;
+#else
+	rsm psr.i | psr.ic	// M2   turn off interrupts and interruption collection
+#endif
+	cmp.eq p9,p0=r0,r0	// A    set p9 to indicate that we should restore cr.ifs
+
+	ld8 r29=[r2],16		// M0|1 load cr.ipsr
+	ld8 r28=[r3],16		// M0|1 load cr.iip
+	mov r22=r0		// A    clear r22
+	;;
+	ld8 r30=[r2],16		// M0|1 load cr.ifs
+	ld8 r25=[r3],16		// M0|1 load ar.unat
+(pUStk) add r14=IA64_TASK_THREAD_ON_USTACK_OFFSET,r13
+	;;
+	ld8 r26=[r2],PT(B0)-PT(AR_PFS)	// M0|1 load ar.pfs
+(pKStk)	mov r22=psr			// M2   read PSR now that interrupts are disabled
+	nop 0
+	;;
+	ld8 r21=[r2],PT(AR_RNAT)-PT(B0) // M0|1 load b0
+	ld8 r27=[r3],PT(PR)-PT(AR_RSC)	// M0|1 load ar.rsc
+	mov f6=f0			// F    clear f6
+	;;
+	ld8 r24=[r2],PT(AR_FPSR)-PT(AR_RNAT)	// M0|1 load ar.rnat (may be garbage)
+	ld8 r31=[r3],PT(R1)-PT(PR)		// M0|1 load predicates
+	mov f7=f0				// F    clear f7
+	;;
+	ld8 r20=[r2],PT(R12)-PT(AR_FPSR)	// M0|1 load ar.fpsr
+	ld8.fill r1=[r3],16			// M0|1 load r1
+(pUStk) mov r17=1				// A
+	;;
+(pUStk) st1 [r14]=r17				// M2|3
+	ld8.fill r13=[r3],16			// M0|1
+	mov f8=f0				// F    clear f8
+	;;
+	ld8.fill r12=[r2]			// M0|1 restore r12 (sp)
+	ld8.fill r15=[r3]			// M0|1 restore r15
+	mov b6=r18				// I0   restore b6
+
+	addl r17=THIS_CPU(ia64_phys_stacked_size_p8),r0 // A
+	mov f9=f0					// F    clear f9
+(pKStk) br.cond.dpnt.many skip_rbs_switch		// B
+
+	srlz.d				// M0   ensure interruption collection is off (for cover)
+	shr.u r18=r19,16		// I0|1 get byte size of existing "dirty" partition
+#ifdef CONFIG_XEN
+	XEN_HYPER_COVER;
+#else
+	cover				// B    add current frame into dirty partition & set cr.ifs
+#endif
+	;;
+(pUStk) ld4 r17=[r17]			// M0|1 r17 = cpu_data->phys_stacked_size_p8
+	mov r19=ar.bsp			// M2   get new backing store pointer
+	mov f10=f0			// F    clear f10
+
+	nop.m 0
+	movl r14=__kernel_syscall_via_epc // X
+	;;
+	mov.m ar.csd=r0			// M2   clear ar.csd
+	mov.m ar.ccv=r0			// M2   clear ar.ccv
+	mov b7=r14			// I0   clear b7 (hint with __kernel_syscall_via_epc)
+
+	mov.m ar.ssd=r0			// M2   clear ar.ssd
+	mov f11=f0			// F    clear f11
+	br.cond.sptk.many rbs_switch	// B
+#ifdef CONFIG_XEN
+END(xen_leave_syscall)
+#else
+END(ia64_leave_syscall)
+#endif
+
+#ifdef CONFIG_XEN
+GLOBAL_ENTRY(xen_leave_kernel)
+	PT_REGS_UNWIND_INFO(0)
+	movl r22=running_on_xen;;
+	ld4 r22=[r22];;
+	cmp.eq p7,p0=r22,r0
+(p7)	br.cond.sptk.many __ia64_leave_kernel;;
+#else
+GLOBAL_ENTRY(ia64_leave_kernel)
+	PT_REGS_UNWIND_INFO(0)
+#endif
+	/*
+	 * work.need_resched etc. mustn't get changed by this CPU before it returns to
+	 * user- or fsys-mode, hence we disable interrupts early on.
+	 *
+	 * p6 controls whether current_thread_info()->flags needs to be check for
+	 * extra work.  We always check for extra work when returning to user-level.
+	 * With CONFIG_PREEMPT, we also check for extra work when the preempt_count
+	 * is 0.  After extra work processing has been completed, execution
+	 * resumes at .work_processed_syscall with p6 set to 1 if the extra-work-check
+	 * needs to be redone.
+	 */
+#ifdef CONFIG_PREEMPT
+	rsm psr.i				// disable interrupts
+	cmp.eq p0,pLvSys=r0,r0			// pLvSys=0: leave from kernel
+(pKStk)	adds r20=TI_PRE_COUNT+IA64_TASK_SIZE,r13
+	;;
+	.pred.rel.mutex pUStk,pKStk
+(pKStk)	ld4 r21=[r20]			// r21 <- preempt_count
+(pUStk)	mov r21=0			// r21 <- 0
+	;;
+	cmp.eq p6,p0=r21,r0		// p6 <- pUStk || (preempt_count == 0)
+#else
+#ifdef CONFIG_XEN
+(pUStk)	movl r17=XSI_PSR_I_ADDR
+(pUStk)	mov r31=1
+		;;
+(pUStk) 	ld8 r17=[r17]
+		;;
+(pUStk)	st1 [r17]=r31
+	;;
+#else
+(pUStk)	rsm psr.i
+#endif
+	cmp.eq p0,pLvSys=r0,r0		// pLvSys=0: leave from kernel
+(pUStk)	cmp.eq.unc p6,p0=r0,r0		// p6 <- pUStk
+#endif
+.work_processed_kernel:
+	adds r17=TI_FLAGS+IA64_TASK_SIZE,r13
+	;;
+(p6)	ld4 r31=[r17]				// load current_thread_info()->flags
+	adds r21=PT(PR)+16,r12
+	;;
+
+	lfetch [r21],PT(CR_IPSR)-PT(PR)
+	adds r2=PT(B6)+16,r12
+	adds r3=PT(R16)+16,r12
+	;;
+	lfetch [r21]
+	ld8 r28=[r2],8		// load b6
+	adds r29=PT(R24)+16,r12
+
+	ld8.fill r16=[r3],PT(AR_CSD)-PT(R16)
+	adds r30=PT(AR_CCV)+16,r12
+(p6)	and r19=TIF_WORK_MASK,r31		// any work other than TIF_SYSCALL_TRACE?
+	;;
+	ld8.fill r24=[r29]
+	ld8 r15=[r30]		// load ar.ccv
+(p6)	cmp4.ne.unc p6,p0=r19, r0		// any special work pending?
+	;;
+	ld8 r29=[r2],16		// load b7
+	ld8 r30=[r3],16		// load ar.csd
+(p6)	br.cond.spnt .work_pending
+	;;
+	ld8 r31=[r2],16		// load ar.ssd
+	ld8.fill r8=[r3],16
+	;;
+	ld8.fill r9=[r2],16
+	ld8.fill r10=[r3],PT(R17)-PT(R10)
+	;;
+	ld8.fill r11=[r2],PT(R18)-PT(R11)
+	ld8.fill r17=[r3],16
+	;;
+	ld8.fill r18=[r2],16
+	ld8.fill r19=[r3],16
+	;;
+	ld8.fill r20=[r2],16
+	ld8.fill r21=[r3],16
+	mov ar.csd=r30
+	mov ar.ssd=r31
+	;;
+#ifdef CONFIG_XEN
+	movl r23=XSI_PSR_I_ADDR
+	movl r22=XSI_PSR_IC
+	;;
+	ld8 r23=[r23]
+	mov r25=1
+	;;
+	st1 [r23]=r25
+	st4 [r22]=r0		// note: clears both vpsr.i and vpsr.ic!
+	;;
+#else
+	rsm psr.i | psr.ic	// initiate turning off of interrupt and interruption collection
+#endif
+	invala			// invalidate ALAT
+	;;
+	ld8.fill r22=[r2],24
+	ld8.fill r23=[r3],24
+	mov b6=r28
+	;;
+	ld8.fill r25=[r2],16
+	ld8.fill r26=[r3],16
+	mov b7=r29
+	;;
+	ld8.fill r27=[r2],16
+	ld8.fill r28=[r3],16
+	;;
+	ld8.fill r29=[r2],16
+	ld8.fill r30=[r3],24
+	;;
+	ld8.fill r31=[r2],PT(F9)-PT(R31)
+	adds r3=PT(F10)-PT(F6),r3
+	;;
+	ldf.fill f9=[r2],PT(F6)-PT(F9)
+	ldf.fill f10=[r3],PT(F8)-PT(F10)
+	;;
+	ldf.fill f6=[r2],PT(F7)-PT(F6)
+	;;
+	ldf.fill f7=[r2],PT(F11)-PT(F7)
+	ldf.fill f8=[r3],32
+	;;
+	srlz.d	// ensure that inter. collection is off (VHPT is don't care, since text is pinned)
+	mov ar.ccv=r15
+	;;
+	ldf.fill f11=[r2]
+#ifdef CONFIG_XEN
+	;;
+	// r16-r31 all now hold bank1 values
+	movl r2=XSI_BANK1_R16
+	movl r3=XSI_BANK1_R16+8
+	;;
+.mem.offset 0,0; st8.spill [r2]=r16,16
+.mem.offset 8,0; st8.spill [r3]=r17,16
+	;;
+.mem.offset 0,0; st8.spill [r2]=r18,16
+.mem.offset 8,0; st8.spill [r3]=r19,16
+	;;
+.mem.offset 0,0; st8.spill [r2]=r20,16
+.mem.offset 8,0; st8.spill [r3]=r21,16
+	;;
+.mem.offset 0,0; st8.spill [r2]=r22,16
+.mem.offset 8,0; st8.spill [r3]=r23,16
+	;;
+.mem.offset 0,0; st8.spill [r2]=r24,16
+.mem.offset 8,0; st8.spill [r3]=r25,16
+	;;
+.mem.offset 0,0; st8.spill [r2]=r26,16
+.mem.offset 8,0; st8.spill [r3]=r27,16
+	;;
+.mem.offset 0,0; st8.spill [r2]=r28,16
+.mem.offset 8,0; st8.spill [r3]=r29,16
+	;;
+.mem.offset 0,0; st8.spill [r2]=r30,16
+.mem.offset 8,0; st8.spill [r3]=r31,16
+	;;
+	movl r2=XSI_BANKNUM;;
+	st4 [r2]=r0;
+#else
+	bsw.0			// switch back to bank 0 (no stop bit required beforehand...)
+#endif
+	;;
+(pUStk)	mov r18=IA64_KR(CURRENT)// M2 (12 cycle read latency)
+	adds r16=PT(CR_IPSR)+16,r12
+	adds r17=PT(CR_IIP)+16,r12
+
+(pKStk)	mov r22=psr		// M2 read PSR now that interrupts are disabled
+	nop.i 0
+	nop.i 0
+	;;
+	ld8 r29=[r16],16	// load cr.ipsr
+	ld8 r28=[r17],16	// load cr.iip
+	;;
+	ld8 r30=[r16],16	// load cr.ifs
+	ld8 r25=[r17],16	// load ar.unat
+	;;
+	ld8 r26=[r16],16	// load ar.pfs
+	ld8 r27=[r17],16	// load ar.rsc
+	cmp.eq p9,p0=r0,r0	// set p9 to indicate that we should restore cr.ifs
+	;;
+	ld8 r24=[r16],16	// load ar.rnat (may be garbage)
+	ld8 r23=[r17],16	// load ar.bspstore (may be garbage)
+	;;
+	ld8 r31=[r16],16	// load predicates
+	ld8 r21=[r17],16	// load b0
+	;;
+	ld8 r19=[r16],16	// load ar.rsc value for "loadrs"
+	ld8.fill r1=[r17],16	// load r1
+	;;
+	ld8.fill r12=[r16],16
+	ld8.fill r13=[r17],16
+(pUStk)	adds r18=IA64_TASK_THREAD_ON_USTACK_OFFSET,r18
+	;;
+	ld8 r20=[r16],16	// ar.fpsr
+	ld8.fill r15=[r17],16
+	;;
+	ld8.fill r14=[r16],16
+	ld8.fill r2=[r17]
+(pUStk)	mov r17=1
+	;;
+	ld8.fill r3=[r16]
+(pUStk)	st1 [r18]=r17		// restore current->thread.on_ustack
+	shr.u r18=r19,16	// get byte size of existing "dirty" partition
+	;;
+	mov r16=ar.bsp		// get existing backing store pointer
+	addl r17=THIS_CPU(ia64_phys_stacked_size_p8),r0
+	;;
+	ld4 r17=[r17]		// r17 = cpu_data->phys_stacked_size_p8
+(pKStk)	br.cond.dpnt skip_rbs_switch
+
+	/*
+	 * Restore user backing store.
+	 *
+	 * NOTE: alloc, loadrs, and cover can't be predicated.
+	 */
+(pNonSys) br.cond.dpnt dont_preserve_current_frame
+
+#ifdef CONFIG_XEN
+	XEN_HYPER_COVER;
+#else
+	cover				// add current frame into dirty partition and set cr.ifs
+#endif
+	;;
+	mov r19=ar.bsp			// get new backing store pointer
+rbs_switch:
+	sub r16=r16,r18			// krbs = old bsp - size of dirty partition
+	cmp.ne p9,p0=r0,r0		// clear p9 to skip restore of cr.ifs
+	;;
+	sub r19=r19,r16			// calculate total byte size of dirty partition
+	add r18=64,r18			// don't force in0-in7 into memory...
+	;;
+	shl r19=r19,16			// shift size of dirty partition into loadrs position
+	;;
+dont_preserve_current_frame:
+	/*
+	 * To prevent leaking bits between the kernel and user-space,
+	 * we must clear the stacked registers in the "invalid" partition here.
+	 * Not pretty, but at least it's fast (3.34 registers/cycle on Itanium,
+	 * 5 registers/cycle on McKinley).
+	 */
+#	define pRecurse	p6
+#	define pReturn	p7
+#ifdef CONFIG_ITANIUM
+#	define Nregs	10
+#else
+#	define Nregs	14
+#endif
+	alloc loc0=ar.pfs,2,Nregs-2,2,0
+	shr.u loc1=r18,9		// RNaTslots <= floor(dirtySize / (64*8))
+	sub r17=r17,r18			// r17 = (physStackedSize + 8) - dirtySize
+	;;
+	mov ar.rsc=r19			// load ar.rsc to be used for "loadrs"
+	shladd in0=loc1,3,r17
+	mov in1=0
+	;;
+	TEXT_ALIGN(32)
+rse_clear_invalid:
+#ifdef CONFIG_ITANIUM
+	// cycle 0
+ { .mii
+	alloc loc0=ar.pfs,2,Nregs-2,2,0
+	cmp.lt pRecurse,p0=Nregs*8,in0	// if more than Nregs regs left to clear, (re)curse
+	add out0=-Nregs*8,in0
+}{ .mfb
+	add out1=1,in1			// increment recursion count
+	nop.f 0
+	nop.b 0				// can't do br.call here because of alloc (WAW on CFM)
+	;;
+}{ .mfi	// cycle 1
+	mov loc1=0
+	nop.f 0
+	mov loc2=0
+}{ .mib
+	mov loc3=0
+	mov loc4=0
+(pRecurse) br.call.sptk.many b0=rse_clear_invalid
+
+}{ .mfi	// cycle 2
+	mov loc5=0
+	nop.f 0
+	cmp.ne pReturn,p0=r0,in1	// if recursion count != 0, we need to do a br.ret
+}{ .mib
+	mov loc6=0
+	mov loc7=0
+(pReturn) br.ret.sptk.many b0
+}
+#else /* !CONFIG_ITANIUM */
+	alloc loc0=ar.pfs,2,Nregs-2,2,0
+	cmp.lt pRecurse,p0=Nregs*8,in0	// if more than Nregs regs left to clear, (re)curse
+	add out0=-Nregs*8,in0
+	add out1=1,in1			// increment recursion count
+	mov loc1=0
+	mov loc2=0
+	;;
+	mov loc3=0
+	mov loc4=0
+	mov loc5=0
+	mov loc6=0
+	mov loc7=0
+(pRecurse) br.call.dptk.few b0=rse_clear_invalid
+	;;
+	mov loc8=0
+	mov loc9=0
+	cmp.ne pReturn,p0=r0,in1	// if recursion count != 0, we need to do a br.ret
+	mov loc10=0
+	mov loc11=0
+(pReturn) br.ret.dptk.many b0
+#endif /* !CONFIG_ITANIUM */
+#	undef pRecurse
+#	undef pReturn
+	;;
+	alloc r17=ar.pfs,0,0,0,0	// drop current register frame
+	;;
+	loadrs
+	;;
+skip_rbs_switch:
+	mov ar.unat=r25		// M2
+(pKStk)	extr.u r22=r22,21,1	// I0 extract current value of psr.pp from r22
+(pLvSys)mov r19=r0		// A  clear r19 for leave_syscall, no-op otherwise
+	;;
+(pUStk)	mov ar.bspstore=r23	// M2
+(pKStk)	dep r29=r22,r29,21,1	// I0 update ipsr.pp with psr.pp
+(pLvSys)mov r16=r0		// A  clear r16 for leave_syscall, no-op otherwise
+	;;
+#ifdef CONFIG_XEN
+	movl r25=XSI_IPSR
+	;;
+	st8[r25]=r29,XSI_IFS_OFS-XSI_IPSR_OFS
+	;;
+#else
+	mov cr.ipsr=r29		// M2
+#endif
+	mov ar.pfs=r26		// I0
+(pLvSys)mov r17=r0		// A  clear r17 for leave_syscall, no-op otherwise
+
+#ifdef CONFIG_XEN
+(p9)	st8 [r25]=r30
+	;;
+	adds r25=XSI_IIP_OFS-XSI_IFS_OFS,r25
+	;;
+#else
+(p9)	mov cr.ifs=r30		// M2
+#endif
+	mov b0=r21		// I0
+(pLvSys)mov r18=r0		// A  clear r18 for leave_syscall, no-op otherwise
+
+	mov ar.fpsr=r20		// M2
+#ifdef CONFIG_XEN
+	st8	[r25]=r28
+#else
+	mov cr.iip=r28		// M2
+#endif
+	nop 0
+	;;
+(pUStk)	mov ar.rnat=r24		// M2 must happen with RSE in lazy mode
+	nop 0
+(pLvSys)mov r2=r0
+
+	mov ar.rsc=r27		// M2
+	mov pr=r31,-1		// I0
+#ifdef CONFIG_XEN
+	;;
+	XEN_HYPER_RFI;
+#else
+	rfi			// B
+#endif
+
+	/*
+	 * On entry:
+	 *	r20 = &current->thread_info->pre_count (if CONFIG_PREEMPT)
+	 *	r31 = current->thread_info->flags
+	 * On exit:
+	 *	p6 = TRUE if work-pending-check needs to be redone
+	 */
+.work_pending_syscall:
+	add r2=-8,r2
+	add r3=-8,r3
+	;;
+	st8 [r2]=r8
+	st8 [r3]=r10
+.work_pending:
+	tbit.z p6,p0=r31,TIF_NEED_RESCHED		// current_thread_info()->need_resched==0?
+(p6)	br.cond.sptk.few .notify
+#ifdef CONFIG_PREEMPT
+(pKStk) dep r21=-1,r0,PREEMPT_ACTIVE_BIT,1
+	;;
+(pKStk) st4 [r20]=r21
+	ssm psr.i		// enable interrupts
+#endif
+	br.call.spnt.many rp=schedule
+.ret9:	cmp.eq p6,p0=r0,r0				// p6 <- 1
+#ifdef CONFIG_XEN
+	movl r2=XSI_PSR_I_ADDR
+	mov r20=1
+	;;
+	ld8 r2=[r2]
+	;;
+	st1 [r2]=r20
+#else
+	rsm psr.i		// disable interrupts
+#endif
+	;;
+#ifdef CONFIG_PREEMPT
+(pKStk)	adds r20=TI_PRE_COUNT+IA64_TASK_SIZE,r13
+	;;
+(pKStk)	st4 [r20]=r0		// preempt_count() <- 0
+#endif
+(pLvSys)br.cond.sptk.few  .work_pending_syscall_end
+	br.cond.sptk.many .work_processed_kernel	// re-check
+
+.notify:
+(pUStk)	br.call.spnt.many rp=notify_resume_user
+.ret10:	cmp.ne p6,p0=r0,r0				// p6 <- 0
+(pLvSys)br.cond.sptk.few  .work_pending_syscall_end
+	br.cond.sptk.many .work_processed_kernel	// don't re-check
+
+.work_pending_syscall_end:
+	adds r2=PT(R8)+16,r12
+	adds r3=PT(R10)+16,r12
+	;;
+	ld8 r8=[r2]
+	ld8 r10=[r3]
+	br.cond.sptk.many .work_processed_syscall	// re-check
+
+#ifdef CONFIG_XEN
+END(xen_leave_kernel)
+#else
+END(ia64_leave_kernel)
+#endif
diff --git a/arch/ia64/xen/xenhpski.c b/arch/ia64/xen/xenhpski.c
new file mode 100644
index 000000000..3bc6cdbf7
--- /dev/null
+++ b/arch/ia64/xen/xenhpski.c
@@ -0,0 +1,19 @@
+
+extern unsigned long xen_get_cpuid(int);
+
+int
+running_on_sim(void)
+{
+	int i;
+	long cpuid[6];
+
+	for (i = 0; i < 5; ++i)
+		cpuid[i] = xen_get_cpuid(i);
+	if ((cpuid[0] & 0xff) != 'H') return 0;
+	if ((cpuid[3] & 0xff) != 0x4) return 0;
+	if (((cpuid[3] >> 8) & 0xff) != 0x0) return 0;
+	if (((cpuid[3] >> 16) & 0xff) != 0x0) return 0;
+	if (((cpuid[3] >> 24) & 0x7) != 0x7) return 0;
+	return 1;
+}
+
diff --git a/arch/ia64/xen/xenivt.S b/arch/ia64/xen/xenivt.S
new file mode 100644
index 000000000..9c9e9f267
--- /dev/null
+++ b/arch/ia64/xen/xenivt.S
@@ -0,0 +1,2169 @@
+/*
+ * arch/ia64/xen/ivt.S
+ *
+ * Copyright (C) 2005 Hewlett-Packard Co
+ *	Dan Magenheimer <dan.magenheimer@hp.com>
+ */
+/*
+ * This file defines the interruption vector table used by the CPU.
+ * It does not include one entry per possible cause of interruption.
+ *
+ * The first 20 entries of the table contain 64 bundles each while the
+ * remaining 48 entries contain only 16 bundles each.
+ *
+ * The 64 bundles are used to allow inlining the whole handler for critical
+ * interruptions like TLB misses.
+ *
+ *  For each entry, the comment is as follows:
+ *
+ *		// 0x1c00 Entry 7 (size 64 bundles) Data Key Miss (12,51)
+ *  entry offset ----/     /         /                  /          /
+ *  entry number ---------/         /                  /          /
+ *  size of the entry -------------/                  /          /
+ *  vector name -------------------------------------/          /
+ *  interruptions triggering this vector ----------------------/
+ *
+ * The table is 32KB in size and must be aligned on 32KB boundary.
+ * (The CPU ignores the 15 lower bits of the address)
+ *
+ * Table is based upon EAS2.6 (Oct 1999)
+ */
+
+#include <asm/asmmacro.h>
+#include <asm/break.h>
+#include <asm/ia32.h>
+#include <asm/kregs.h>
+#include <asm/asm-offsets.h>
+#include <asm/pgtable.h>
+#include <asm/processor.h>
+#include <asm/ptrace.h>
+#include <asm/system.h>
+#include <asm/thread_info.h>
+#include <asm/unistd.h>
+#include <asm/errno.h>
+
+#ifdef CONFIG_XEN
+#define ia64_ivt xen_ivt
+#endif
+
+#if 1
+# define PSR_DEFAULT_BITS	psr.ac
+#else
+# define PSR_DEFAULT_BITS	0
+#endif
+
+#if 0
+  /*
+   * This lets you track the last eight faults that occurred on the CPU.  Make sure ar.k2 isn't
+   * needed for something else before enabling this...
+   */
+# define DBG_FAULT(i)	mov r16=ar.k2;;	shl r16=r16,8;;	add r16=(i),r16;;mov ar.k2=r16
+#else
+# define DBG_FAULT(i)
+#endif
+
+#define MINSTATE_VIRT	/* needed by minstate.h */
+#include "xenminstate.h"
+
+#define FAULT(n)									\
+	mov r31=pr;									\
+	mov r19=n;;			/* prepare to save predicates */		\
+	br.sptk.many dispatch_to_fault_handler
+
+	.section .text.ivt,"ax"
+
+	.align 32768	// align on 32KB boundary
+	.global ia64_ivt
+ia64_ivt:
+/////////////////////////////////////////////////////////////////////////////////////////
+// 0x0000 Entry 0 (size 64 bundles) VHPT Translation (8,20,47)
+ENTRY(vhpt_miss)
+	DBG_FAULT(0)
+	/*
+	 * The VHPT vector is invoked when the TLB entry for the virtual page table
+	 * is missing.  This happens only as a result of a previous
+	 * (the "original") TLB miss, which may either be caused by an instruction
+	 * fetch or a data access (or non-access).
+	 *
+	 * What we do here is normal TLB miss handing for the _original_ miss,
+	 * followed by inserting the TLB entry for the virtual page table page
+	 * that the VHPT walker was attempting to access.  The latter gets
+	 * inserted as long as page table entry above pte level have valid
+	 * mappings for the faulting address.  The TLB entry for the original
+	 * miss gets inserted only if the pte entry indicates that the page is
+	 * present.
+	 *
+	 * do_page_fault gets invoked in the following cases:
+	 *	- the faulting virtual address uses unimplemented address bits
+	 *	- the faulting virtual address has no valid page table mapping
+	 */
+#ifdef CONFIG_XEN
+	movl r16=XSI_IFA
+	;;
+	ld8 r16=[r16]
+#ifdef CONFIG_HUGETLB_PAGE
+	movl r18=PAGE_SHIFT
+	movl r25=XSI_ITIR
+	;;
+	ld8 r25=[r25]
+#endif
+	;;
+#else
+	mov r16=cr.ifa				// get address that caused the TLB miss
+#ifdef CONFIG_HUGETLB_PAGE
+	movl r18=PAGE_SHIFT
+	mov r25=cr.itir
+#endif
+#endif
+	;;
+#ifdef CONFIG_XEN
+	XEN_HYPER_RSM_PSR_DT;
+#else
+	rsm psr.dt				// use physical addressing for data
+#endif
+	mov r31=pr				// save the predicate registers
+	mov r19=IA64_KR(PT_BASE)		// get page table base address
+	shl r21=r16,3				// shift bit 60 into sign bit
+	shr.u r17=r16,61			// get the region number into r17
+	;;
+	shr.u r22=r21,3
+#ifdef CONFIG_HUGETLB_PAGE
+	extr.u r26=r25,2,6
+	;;
+	cmp.ne p8,p0=r18,r26
+	sub r27=r26,r18
+	;;
+(p8)	dep r25=r18,r25,2,6
+(p8)	shr r22=r22,r27
+#endif
+	;;
+	cmp.eq p6,p7=5,r17			// is IFA pointing into to region 5?
+	shr.u r18=r22,PGDIR_SHIFT		// get bottom portion of pgd index bit
+	;;
+(p7)	dep r17=r17,r19,(PAGE_SHIFT-3),3	// put region number bits in place
+
+	srlz.d
+	LOAD_PHYSICAL(p6, r19, swapper_pg_dir)	// region 5 is rooted at swapper_pg_dir
+
+	.pred.rel "mutex", p6, p7
+(p6)	shr.u r21=r21,PGDIR_SHIFT+PAGE_SHIFT
+(p7)	shr.u r21=r21,PGDIR_SHIFT+PAGE_SHIFT-3
+	;;
+(p6)	dep r17=r18,r19,3,(PAGE_SHIFT-3)	// r17=pgd_offset for region 5
+(p7)	dep r17=r18,r17,3,(PAGE_SHIFT-6)	// r17=pgd_offset for region[0-4]
+	cmp.eq p7,p6=0,r21			// unused address bits all zeroes?
+#ifdef CONFIG_PGTABLE_4
+	shr.u r28=r22,PUD_SHIFT			// shift pud index into position
+#else
+	shr.u r18=r22,PMD_SHIFT			// shift pmd index into position
+#endif
+	;;
+	ld8 r17=[r17]				// get *pgd (may be 0)
+	;;
+(p7)	cmp.eq p6,p7=r17,r0			// was pgd_present(*pgd) == NULL?
+#ifdef CONFIG_PGTABLE_4
+	dep r28=r28,r17,3,(PAGE_SHIFT-3)	// r28=pud_offset(pgd,addr)
+	;;
+	shr.u r18=r22,PMD_SHIFT			// shift pmd index into position
+(p7)	ld8 r29=[r28]				// get *pud (may be 0)
+	;;
+(p7)	cmp.eq.or.andcm p6,p7=r29,r0		// was pud_present(*pud) == NULL?
+	dep r17=r18,r29,3,(PAGE_SHIFT-3)	// r17=pmd_offset(pud,addr)
+#else
+	dep r17=r18,r17,3,(PAGE_SHIFT-3)	// r17=pmd_offset(pgd,addr)
+#endif
+	;;
+(p7)	ld8 r20=[r17]				// get *pmd (may be 0)
+	shr.u r19=r22,PAGE_SHIFT		// shift pte index into position
+	;;
+(p7)	cmp.eq.or.andcm p6,p7=r20,r0		// was pmd_present(*pmd) == NULL?
+	dep r21=r19,r20,3,(PAGE_SHIFT-3)	// r21=pte_offset(pmd,addr)
+	;;
+(p7)	ld8 r18=[r21]				// read *pte
+#ifdef CONFIG_XEN
+	movl r19=XSI_ISR
+	;;
+	ld8 r19=[r19]
+#else
+	mov r19=cr.isr				// cr.isr bit 32 tells us if this is an insn miss
+#endif
+	;;
+(p7)	tbit.z p6,p7=r18,_PAGE_P_BIT		// page present bit cleared?
+#ifdef CONFIG_XEN
+	movl r22=XSI_IHA
+	;;
+	ld8 r22=[r22]
+#else
+	mov r22=cr.iha				// get the VHPT address that caused the TLB miss
+#endif
+	;;					// avoid RAW on p7
+(p7)	tbit.nz.unc p10,p11=r19,32		// is it an instruction TLB miss?
+	dep r23=0,r20,0,PAGE_SHIFT		// clear low bits to get page address
+	;;
+#ifdef CONFIG_XEN
+	mov r24=r8
+	mov r8=r18
+	;;
+(p10)	XEN_HYPER_ITC_I
+	;;
+(p11)	XEN_HYPER_ITC_D
+	;;
+	mov r8=r24
+	;;
+#else
+(p10)	itc.i r18				// insert the instruction TLB entry
+(p11)	itc.d r18				// insert the data TLB entry
+#endif
+(p6)	br.cond.spnt.many page_fault		// handle bad address/page not present (page fault)
+#ifdef CONFIG_XEN
+	movl r24=XSI_IFA
+	;;
+	st8 [r24]=r22
+	;;
+#else
+	mov cr.ifa=r22
+#endif
+
+#ifdef CONFIG_HUGETLB_PAGE
+(p8)	mov cr.itir=r25				// change to default page-size for VHPT
+#endif
+
+	/*
+	 * Now compute and insert the TLB entry for the virtual page table.  We never
+	 * execute in a page table page so there is no need to set the exception deferral
+	 * bit.
+	 */
+	adds r24=__DIRTY_BITS_NO_ED|_PAGE_PL_0|_PAGE_AR_RW,r23
+	;;
+#ifdef CONFIG_XEN
+(p7)	mov r25=r8
+(p7)	mov r8=r24
+	;;
+(p7)	XEN_HYPER_ITC_D
+	;;
+(p7)	mov r8=r25
+	;;
+#else
+(p7)	itc.d r24
+#endif
+	;;
+#ifdef CONFIG_SMP
+	/*
+	 * Tell the assemblers dependency-violation checker that the above "itc" instructions
+	 * cannot possibly affect the following loads:
+	 */
+	dv_serialize_data
+
+	/*
+	 * Re-check pagetable entry.  If they changed, we may have received a ptc.g
+	 * between reading the pagetable and the "itc".  If so, flush the entry we
+	 * inserted and retry.  At this point, we have:
+	 *
+	 * r28 = equivalent of pud_offset(pgd, ifa)
+	 * r17 = equivalent of pmd_offset(pud, ifa)
+	 * r21 = equivalent of pte_offset(pmd, ifa)
+	 *
+	 * r29 = *pud
+	 * r20 = *pmd
+	 * r18 = *pte
+	 */
+	ld8 r25=[r21]				// read *pte again
+	ld8 r26=[r17]				// read *pmd again
+#ifdef CONFIG_PGTABLE_4
+	ld8 r19=[r28]				// read *pud again
+#endif
+	cmp.ne p6,p7=r0,r0
+	;;
+	cmp.ne.or.andcm p6,p7=r26,r20		// did *pmd change
+#ifdef CONFIG_PGTABLE_4
+	cmp.ne.or.andcm p6,p7=r19,r29		// did *pud change
+#endif
+	mov r27=PAGE_SHIFT<<2
+	;;
+(p6)	ptc.l r22,r27				// purge PTE page translation
+(p7)	cmp.ne.or.andcm p6,p7=r25,r18		// did *pte change
+	;;
+(p6)	ptc.l r16,r27				// purge translation
+#endif
+
+	mov pr=r31,-1				// restore predicate registers
+#ifdef CONFIG_XEN
+	XEN_HYPER_RFI
+	dv_serialize_data
+#else
+	rfi
+#endif
+END(vhpt_miss)
+
+	.org ia64_ivt+0x400
+/////////////////////////////////////////////////////////////////////////////////////////
+// 0x0400 Entry 1 (size 64 bundles) ITLB (21)
+ENTRY(itlb_miss)
+	DBG_FAULT(1)
+	/*
+	 * The ITLB handler accesses the PTE via the virtually mapped linear
+	 * page table.  If a nested TLB miss occurs, we switch into physical
+	 * mode, walk the page table, and then re-execute the PTE read and
+	 * go on normally after that.
+	 */
+#ifdef CONFIG_XEN
+	movl r16=XSI_IFA
+	;;
+	ld8 r16=[r16]
+#else
+	mov r16=cr.ifa				// get virtual address
+#endif
+	mov r29=b0				// save b0
+	mov r31=pr				// save predicates
+.itlb_fault:
+#ifdef CONFIG_XEN
+	movl r17=XSI_IHA
+	;;
+	ld8 r17=[r17]				// get virtual address of L3 PTE
+#else
+	mov r17=cr.iha				// get virtual address of PTE
+#endif
+	movl r30=1f				// load nested fault continuation point
+	;;
+1:	ld8 r18=[r17]				// read *pte
+	;;
+	mov b0=r29
+	tbit.z p6,p0=r18,_PAGE_P_BIT		// page present bit cleared?
+(p6)	br.cond.spnt page_fault
+	;;
+#ifdef CONFIG_XEN
+	mov r19=r8
+	mov r8=r18
+	;;
+	XEN_HYPER_ITC_I
+	;;
+	mov r8=r19
+#else
+	itc.i r18
+#endif
+	;;
+#ifdef CONFIG_SMP
+	/*
+	 * Tell the assemblers dependency-violation checker that the above "itc" instructions
+	 * cannot possibly affect the following loads:
+	 */
+	dv_serialize_data
+
+	ld8 r19=[r17]				// read *pte again and see if same
+	mov r20=PAGE_SHIFT<<2			// setup page size for purge
+	;;
+	cmp.ne p7,p0=r18,r19
+	;;
+(p7)	ptc.l r16,r20
+#endif
+	mov pr=r31,-1
+#ifdef CONFIG_XEN
+	XEN_HYPER_RFI
+	dv_serialize_data
+#else
+	rfi
+#endif
+END(itlb_miss)
+
+	.org ia64_ivt+0x0800
+/////////////////////////////////////////////////////////////////////////////////////////
+// 0x0800 Entry 2 (size 64 bundles) DTLB (9,48)
+ENTRY(dtlb_miss)
+	DBG_FAULT(2)
+	/*
+	 * The DTLB handler accesses the PTE via the virtually mapped linear
+	 * page table.  If a nested TLB miss occurs, we switch into physical
+	 * mode, walk the page table, and then re-execute the PTE read and
+	 * go on normally after that.
+	 */
+#ifdef CONFIG_XEN
+	movl r16=XSI_IFA
+	;;
+	ld8 r16=[r16]
+#else
+	mov r16=cr.ifa				// get virtual address
+#endif
+	mov r29=b0				// save b0
+	mov r31=pr				// save predicates
+dtlb_fault:
+#ifdef CONFIG_XEN
+	movl r17=XSI_IHA
+	;;
+	ld8 r17=[r17]				// get virtual address of L3 PTE
+#else
+	mov r17=cr.iha				// get virtual address of PTE
+#endif
+	movl r30=1f				// load nested fault continuation point
+	;;
+1:	ld8 r18=[r17]				// read *pte
+	;;
+	mov b0=r29
+	tbit.z p6,p0=r18,_PAGE_P_BIT		// page present bit cleared?
+(p6)	br.cond.spnt page_fault
+	;;
+#ifdef CONFIG_XEN
+	mov r19=r8
+	mov r8=r18
+	;;
+	XEN_HYPER_ITC_D
+	;;
+	mov r8=r19
+	;;
+#else
+	itc.d r18
+#endif
+	;;
+#ifdef CONFIG_SMP
+	/*
+	 * Tell the assemblers dependency-violation checker that the above "itc" instructions
+	 * cannot possibly affect the following loads:
+	 */
+	dv_serialize_data
+
+	ld8 r19=[r17]				// read *pte again and see if same
+	mov r20=PAGE_SHIFT<<2			// setup page size for purge
+	;;
+	cmp.ne p7,p0=r18,r19
+	;;
+(p7)	ptc.l r16,r20
+#endif
+	mov pr=r31,-1
+#ifdef CONFIG_XEN
+	XEN_HYPER_RFI
+	dv_serialize_data
+#else
+	rfi
+#endif
+END(dtlb_miss)
+
+	.org ia64_ivt+0x0c00
+/////////////////////////////////////////////////////////////////////////////////////////
+// 0x0c00 Entry 3 (size 64 bundles) Alt ITLB (19)
+ENTRY(alt_itlb_miss)
+	DBG_FAULT(3)
+#ifdef CONFIG_XEN
+	movl r31=XSI_IPSR
+	;;
+	ld8 r21=[r31],XSI_IFA_OFS-XSI_IPSR_OFS	// get ipsr, point to ifa
+	movl r17=PAGE_KERNEL
+	;;
+	ld8 r16=[r31]		// get ifa
+#else
+	mov r16=cr.ifa		// get address that caused the TLB miss
+	movl r17=PAGE_KERNEL
+	mov r21=cr.ipsr
+#endif
+	movl r19=(((1 << IA64_MAX_PHYS_BITS) - 1) & ~0xfff)
+	mov r31=pr
+	;;
+#ifdef CONFIG_DISABLE_VHPT
+	shr.u r22=r16,61			// get the region number into r21
+	;;
+	cmp.gt p8,p0=6,r22			// user mode
+	;;
+#ifndef CONFIG_XEN
+(p8)	thash r17=r16
+	;;
+(p8)	mov cr.iha=r17
+#endif
+(p8)	mov r29=b0				// save b0
+(p8)	br.cond.dptk .itlb_fault
+#endif
+	extr.u r23=r21,IA64_PSR_CPL0_BIT,2	// extract psr.cpl
+	and r19=r19,r16		// clear ed, reserved bits, and PTE control bits
+	shr.u r18=r16,57	// move address bit 61 to bit 4
+	;;
+	andcm r18=0x10,r18	// bit 4=~address-bit(61)
+	cmp.ne p8,p0=r0,r23	// psr.cpl != 0?
+	or r19=r17,r19		// insert PTE control bits into r19
+	;;
+	or r19=r19,r18		// set bit 4 (uncached) if the access was to region 6
+(p8)	br.cond.spnt page_fault
+	;;
+#ifdef CONFIG_XEN
+	mov r18=r8
+	mov r8=r19
+	;;
+	XEN_HYPER_ITC_I
+	;;
+	mov r8=r18
+	;;
+	mov pr=r31,-1
+	;;
+	XEN_HYPER_RFI;
+#else
+	itc.i r19		// insert the TLB entry
+	mov pr=r31,-1
+	rfi
+#endif
+END(alt_itlb_miss)
+
+	.org ia64_ivt+0x1000
+/////////////////////////////////////////////////////////////////////////////////////////
+// 0x1000 Entry 4 (size 64 bundles) Alt DTLB (7,46)
+ENTRY(alt_dtlb_miss)
+	DBG_FAULT(4)
+#ifdef CONFIG_XEN
+	movl r31=XSI_IPSR
+	;;
+	ld8 r21=[r31],XSI_ISR_OFS-XSI_IPSR_OFS	// get ipsr, point to isr
+	movl r17=PAGE_KERNEL
+	;;
+	ld8 r20=[r31],XSI_IFA_OFS-XSI_ISR_OFS	// get isr, point to ifa
+	movl r19=(((1 << IA64_MAX_PHYS_BITS) - 1) & ~0xfff)
+	;;
+	ld8 r16=[r31]		// get ifa
+#else
+	mov r16=cr.ifa		// get address that caused the TLB miss
+	movl r17=PAGE_KERNEL
+	mov r20=cr.isr
+	movl r19=(((1 << IA64_MAX_PHYS_BITS) - 1) & ~0xfff)
+	mov r21=cr.ipsr
+#endif
+	mov r31=pr
+	;;
+#ifdef CONFIG_DISABLE_VHPT
+	shr.u r22=r16,61			// get the region number into r21
+	;;
+	cmp.gt p8,p0=6,r22			// access to region 0-5
+	;;
+#ifndef CONFIG_XEN
+(p8)	thash r17=r16
+	;;
+(p8)	mov cr.iha=r17
+#endif
+(p8)	mov r29=b0				// save b0
+(p8)	br.cond.dptk dtlb_fault
+#endif
+	extr.u r23=r21,IA64_PSR_CPL0_BIT,2	// extract psr.cpl
+	and r22=IA64_ISR_CODE_MASK,r20		// get the isr.code field
+	tbit.nz p6,p7=r20,IA64_ISR_SP_BIT	// is speculation bit on?
+	shr.u r18=r16,57			// move address bit 61 to bit 4
+	and r19=r19,r16				// clear ed, reserved bits, and PTE control bits
+	tbit.nz p9,p0=r20,IA64_ISR_NA_BIT	// is non-access bit on?
+	;;
+	andcm r18=0x10,r18	// bit 4=~address-bit(61)
+	cmp.ne p8,p0=r0,r23
+(p9)	cmp.eq.or.andcm p6,p7=IA64_ISR_CODE_LFETCH,r22	// check isr.code field
+(p8)	br.cond.spnt page_fault
+
+	dep r21=-1,r21,IA64_PSR_ED_BIT,1
+	or r19=r19,r17		// insert PTE control bits into r19
+	;;
+	or r19=r19,r18		// set bit 4 (uncached) if the access was to region 6
+(p6)	mov cr.ipsr=r21
+	;;
+#ifdef CONFIG_XEN
+(p7)	mov r18=r8
+(p7)	mov r8=r19
+	;;
+(p7)	XEN_HYPER_ITC_D
+	;;
+(p7)	mov r8=r18
+	;;
+	mov pr=r31,-1
+	;;
+	XEN_HYPER_RFI;
+#else
+(p7)	itc.d r19		// insert the TLB entry
+	mov pr=r31,-1
+	rfi
+#endif
+END(alt_dtlb_miss)
+
+	.org ia64_ivt+0x1400
+/////////////////////////////////////////////////////////////////////////////////////////
+// 0x1400 Entry 5 (size 64 bundles) Data nested TLB (6,45)
+ENTRY(nested_dtlb_miss)
+	/*
+	 * In the absence of kernel bugs, we get here when the virtually mapped linear
+	 * page table is accessed non-speculatively (e.g., in the Dirty-bit, Instruction
+	 * Access-bit, or Data Access-bit faults).  If the DTLB entry for the virtual page
+	 * table is missing, a nested TLB miss fault is triggered and control is
+	 * transferred to this point.  When this happens, we lookup the pte for the
+	 * faulting address by walking the page table in physical mode and return to the
+	 * continuation point passed in register r30 (or call page_fault if the address is
+	 * not mapped).
+	 *
+	 * Input:	r16:	faulting address
+	 *		r29:	saved b0
+	 *		r30:	continuation address
+	 *		r31:	saved pr
+	 *
+	 * Output:	r17:	physical address of PTE of faulting address
+	 *		r29:	saved b0
+	 *		r30:	continuation address
+	 *		r31:	saved pr
+	 *
+	 * Clobbered:	b0, r18, r19, r21, r22, psr.dt (cleared)
+	 */
+#ifdef CONFIG_XEN
+	XEN_HYPER_RSM_PSR_DT;
+#else
+	rsm psr.dt				// switch to using physical data addressing
+#endif
+	mov r19=IA64_KR(PT_BASE)		// get the page table base address
+	shl r21=r16,3				// shift bit 60 into sign bit
+#ifdef CONFIG_XEN
+	movl r18=XSI_ITIR
+	;;
+	ld8 r18=[r18]
+#else
+	mov r18=cr.itir
+#endif
+	;;
+	shr.u r17=r16,61			// get the region number into r17
+	extr.u r18=r18,2,6			// get the faulting page size
+	;;
+	cmp.eq p6,p7=5,r17			// is faulting address in region 5?
+	add r22=-PAGE_SHIFT,r18			// adjustment for hugetlb address
+	add r18=PGDIR_SHIFT-PAGE_SHIFT,r18
+	;;
+	shr.u r22=r16,r22
+	shr.u r18=r16,r18
+(p7)	dep r17=r17,r19,(PAGE_SHIFT-3),3	// put region number bits in place
+
+	srlz.d
+	LOAD_PHYSICAL(p6, r19, swapper_pg_dir)	// region 5 is rooted at swapper_pg_dir
+
+	.pred.rel "mutex", p6, p7
+(p6)	shr.u r21=r21,PGDIR_SHIFT+PAGE_SHIFT
+(p7)	shr.u r21=r21,PGDIR_SHIFT+PAGE_SHIFT-3
+	;;
+(p6)	dep r17=r18,r19,3,(PAGE_SHIFT-3)	// r17=pgd_offset for region 5
+(p7)	dep r17=r18,r17,3,(PAGE_SHIFT-6)	// r17=pgd_offset for region[0-4]
+	cmp.eq p7,p6=0,r21			// unused address bits all zeroes?
+#ifdef CONFIG_PGTABLE_4
+	shr.u r18=r22,PUD_SHIFT			// shift pud index into position
+#else
+	shr.u r18=r22,PMD_SHIFT			// shift pmd index into position
+#endif
+	;;
+	ld8 r17=[r17]				// get *pgd (may be 0)
+	;;
+(p7)	cmp.eq p6,p7=r17,r0			// was pgd_present(*pgd) == NULL?
+	dep r17=r18,r17,3,(PAGE_SHIFT-3)	// r17=p[u|m]d_offset(pgd,addr)
+	;;
+#ifdef CONFIG_PGTABLE_4
+(p7)	ld8 r17=[r17]				// get *pud (may be 0)
+	shr.u r18=r22,PMD_SHIFT			// shift pmd index into position
+	;;
+(p7)	cmp.eq.or.andcm p6,p7=r17,r0		// was pud_present(*pud) == NULL?
+	dep r17=r18,r17,3,(PAGE_SHIFT-3)	// r17=pmd_offset(pud,addr)
+	;;
+#endif
+(p7)	ld8 r17=[r17]				// get *pmd (may be 0)
+	shr.u r19=r22,PAGE_SHIFT		// shift pte index into position
+	;;
+(p7)	cmp.eq.or.andcm p6,p7=r17,r0		// was pmd_present(*pmd) == NULL?
+	dep r17=r19,r17,3,(PAGE_SHIFT-3)	// r17=pte_offset(pmd,addr);
+(p6)	br.cond.spnt page_fault
+	mov b0=r30
+	br.sptk.many b0				// return to continuation point
+END(nested_dtlb_miss)
+
+	.org ia64_ivt+0x1800
+/////////////////////////////////////////////////////////////////////////////////////////
+// 0x1800 Entry 6 (size 64 bundles) Instruction Key Miss (24)
+ENTRY(ikey_miss)
+	DBG_FAULT(6)
+	FAULT(6)
+END(ikey_miss)
+
+	//-----------------------------------------------------------------------------------
+	// call do_page_fault (predicates are in r31, psr.dt may be off, r16 is faulting address)
+ENTRY(page_fault)
+#ifdef CONFIG_XEN
+	XEN_HYPER_SSM_PSR_DT
+#else
+	ssm psr.dt
+	;;
+	srlz.i
+#endif
+	;;
+	SAVE_MIN_WITH_COVER
+	alloc r15=ar.pfs,0,0,3,0
+#ifdef CONFIG_XEN
+	movl r3=XSI_ISR
+	;;
+	ld8 out1=[r3],XSI_IFA_OFS-XSI_ISR_OFS	// get vcr.isr, point to ifa
+	;;
+	ld8 out0=[r3]				// get vcr.ifa
+	mov r14=1
+	;;
+	add r3=XSI_PSR_IC_OFS-XSI_IFA_OFS, r3	// point to vpsr.ic
+	;;
+	st4 [r3]=r14				// vpsr.ic = 1
+	adds r3=8,r2				// set up second base pointer
+	;;
+#else
+	mov out0=cr.ifa
+	mov out1=cr.isr
+	adds r3=8,r2				// set up second base pointer
+	;;
+	ssm psr.ic | PSR_DEFAULT_BITS
+	;;
+	srlz.i					// guarantee that interruption collectin is on
+	;;
+#endif
+#ifdef CONFIG_XEN
+	br.cond.sptk.many	xen_page_fault
+	;;
+done_xen_page_fault:
+#endif
+(p15)	ssm psr.i				// restore psr.i
+	movl r14=ia64_leave_kernel
+	;;
+	SAVE_REST
+	mov rp=r14
+	;;
+	adds out2=16,r12			// out2 = pointer to pt_regs
+	br.call.sptk.many b6=ia64_do_page_fault	// ignore return address
+END(page_fault)
+
+	.org ia64_ivt+0x1c00
+/////////////////////////////////////////////////////////////////////////////////////////
+// 0x1c00 Entry 7 (size 64 bundles) Data Key Miss (12,51)
+ENTRY(dkey_miss)
+	DBG_FAULT(7)
+	FAULT(7)
+#ifdef CONFIG_XEN
+	// Leaving this code inline above results in an IVT section overflow
+	// There is no particular reason for this code to be here...
+xen_page_fault:
+(p15)	movl r3=XSI_PSR_I_ADDR
+	;;
+(p15)	ld8 r3=[r3]
+	;;
+(p15)	st1 [r3]=r0,XSI_PEND_OFS-XSI_PSR_I_ADDR_OFS	// if (p15) vpsr.i = 1
+	mov r14=r0
+	;;
+(p15)	ld4 r14=[r3]				// if (pending_interrupts)
+	adds r3=8,r2				// re-set up second base pointer
+	;;
+(p15)	cmp.ne	p15,p0=r14,r0
+	;;
+	br.cond.sptk.many done_xen_page_fault
+	;;
+#endif
+END(dkey_miss)
+
+	.org ia64_ivt+0x2000
+/////////////////////////////////////////////////////////////////////////////////////////
+// 0x2000 Entry 8 (size 64 bundles) Dirty-bit (54)
+ENTRY(dirty_bit)
+	DBG_FAULT(8)
+	/*
+	 * What we do here is to simply turn on the dirty bit in the PTE.  We need to
+	 * update both the page-table and the TLB entry.  To efficiently access the PTE,
+	 * we address it through the virtual page table.  Most likely, the TLB entry for
+	 * the relevant virtual page table page is still present in the TLB so we can
+	 * normally do this without additional TLB misses.  In case the necessary virtual
+	 * page table TLB entry isn't present, we take a nested TLB miss hit where we look
+	 * up the physical address of the L3 PTE and then continue at label 1 below.
+	 */
+#ifdef CONFIG_XEN
+	movl r16=XSI_IFA
+	;;
+	ld8 r16=[r16]
+	;;
+#else
+	mov r16=cr.ifa				// get the address that caused the fault
+#endif
+	movl r30=1f				// load continuation point in case of nested fault
+	;;
+#ifdef CONFIG_XEN
+	mov r18=r8;
+	mov r8=r16;
+	XEN_HYPER_THASH;;
+	mov r17=r8;
+	mov r8=r18;;
+#else
+	thash r17=r16				// compute virtual address of L3 PTE
+#endif
+	mov r29=b0				// save b0 in case of nested fault
+	mov r31=pr				// save pr
+#ifdef CONFIG_SMP
+	mov r28=ar.ccv				// save ar.ccv
+	;;
+1:	ld8 r18=[r17]
+	;;					// avoid RAW on r18
+	mov ar.ccv=r18				// set compare value for cmpxchg
+	or r25=_PAGE_D|_PAGE_A,r18		// set the dirty and accessed bits
+	tbit.z p7,p6 = r18,_PAGE_P_BIT		// Check present bit
+	;;
+(p6)	cmpxchg8.acq r26=[r17],r25,ar.ccv	// Only update if page is present
+	mov r24=PAGE_SHIFT<<2
+	;;
+(p6)	cmp.eq p6,p7=r26,r18			// Only compare if page is present
+	;;
+#ifdef CONFIG_XEN
+(p6)	mov r18=r8
+(p6)	mov r8=r25
+	;;
+(p6)	XEN_HYPER_ITC_D
+	;;
+(p6)	mov r8=r18
+#else
+(p6)	itc.d r25				// install updated PTE
+#endif	
+	;;
+	/*
+	 * Tell the assemblers dependency-violation checker that the above "itc" instructions
+	 * cannot possibly affect the following loads:
+	 */
+	dv_serialize_data
+
+	ld8 r18=[r17]				// read PTE again
+	;;
+	cmp.eq p6,p7=r18,r25			// is it same as the newly installed
+	;;
+(p7)	ptc.l r16,r24
+	mov b0=r29				// restore b0
+	mov ar.ccv=r28
+#else
+	;;
+1:	ld8 r18=[r17]
+	;;					// avoid RAW on r18
+	or r18=_PAGE_D|_PAGE_A,r18		// set the dirty and accessed bits
+	mov b0=r29				// restore b0
+	;;
+	st8 [r17]=r18				// store back updated PTE
+	itc.d r18				// install updated PTE
+#endif
+	mov pr=r31,-1				// restore pr
+#ifdef CONFIG_XEN
+	XEN_HYPER_RFI
+	dv_serialize_data
+#else
+	rfi
+#endif
+END(dirty_bit)
+
+	.org ia64_ivt+0x2400
+/////////////////////////////////////////////////////////////////////////////////////////
+// 0x2400 Entry 9 (size 64 bundles) Instruction Access-bit (27)
+ENTRY(iaccess_bit)
+	DBG_FAULT(9)
+	// Like Entry 8, except for instruction access
+#ifdef CONFIG_XEN
+	movl r16=XSI_IFA
+	;;
+	ld8 r16=[r16]
+	;;
+#else
+	mov r16=cr.ifa				// get the address that caused the fault
+#endif
+	movl r30=1f				// load continuation point in case of nested fault
+	mov r31=pr				// save predicates
+#ifdef CONFIG_ITANIUM
+	/*
+	 * Erratum 10 (IFA may contain incorrect address) has "NoFix" status.
+	 */
+	mov r17=cr.ipsr
+	;;
+	mov r18=cr.iip
+	tbit.z p6,p0=r17,IA64_PSR_IS_BIT	// IA64 instruction set?
+	;;
+(p6)	mov r16=r18				// if so, use cr.iip instead of cr.ifa
+#endif /* CONFIG_ITANIUM */
+	;;
+#ifdef CONFIG_XEN
+	mov r18=r8;
+	mov r8=r16;
+	XEN_HYPER_THASH;;
+	mov r17=r8;
+	mov r8=r18;;
+#else
+	thash r17=r16				// compute virtual address of L3 PTE
+#endif
+	mov r29=b0				// save b0 in case of nested fault)
+#ifdef CONFIG_SMP
+	mov r28=ar.ccv				// save ar.ccv
+	;;
+1:	ld8 r18=[r17]
+	;;
+	mov ar.ccv=r18				// set compare value for cmpxchg
+	or r25=_PAGE_A,r18			// set the accessed bit
+	tbit.z p7,p6 = r18,_PAGE_P_BIT	 	// Check present bit
+	;;
+(p6)	cmpxchg8.acq r26=[r17],r25,ar.ccv	// Only if page present
+	mov r24=PAGE_SHIFT<<2
+	;;
+(p6)	cmp.eq p6,p7=r26,r18			// Only if page present
+	;;
+#ifdef CONFIG_XEN
+	mov r26=r8
+	mov r8=r25
+	;;
+(p6)	XEN_HYPER_ITC_I
+	;;
+	mov r8=r26
+	;;
+#else
+(p6)	itc.i r25				// install updated PTE
+#endif
+	;;
+	/*
+	 * Tell the assemblers dependency-violation checker that the above "itc" instructions
+	 * cannot possibly affect the following loads:
+	 */
+	dv_serialize_data
+
+	ld8 r18=[r17]				// read PTE again
+	;;
+	cmp.eq p6,p7=r18,r25			// is it same as the newly installed
+	;;
+(p7)	ptc.l r16,r24
+	mov b0=r29				// restore b0
+	mov ar.ccv=r28
+#else /* !CONFIG_SMP */
+	;;
+1:	ld8 r18=[r17]
+	;;
+	or r18=_PAGE_A,r18			// set the accessed bit
+	mov b0=r29				// restore b0
+	;;
+	st8 [r17]=r18				// store back updated PTE
+	itc.i r18				// install updated PTE
+#endif /* !CONFIG_SMP */
+	mov pr=r31,-1
+#ifdef CONFIG_XEN
+	XEN_HYPER_RFI
+	dv_serialize_data
+#else
+	rfi
+#endif
+END(iaccess_bit)
+
+	.org ia64_ivt+0x2800
+/////////////////////////////////////////////////////////////////////////////////////////
+// 0x2800 Entry 10 (size 64 bundles) Data Access-bit (15,55)
+ENTRY(daccess_bit)
+	DBG_FAULT(10)
+	// Like Entry 8, except for data access
+#ifdef CONFIG_XEN
+	movl r16=XSI_IFA
+	;;
+	ld8 r16=[r16]
+	;;
+#else
+	mov r16=cr.ifa				// get the address that caused the fault
+#endif
+	movl r30=1f				// load continuation point in case of nested fault
+	;;
+#ifdef CONFIG_XEN
+	mov r18=r8
+	mov r8=r16
+	XEN_HYPER_THASH
+	;;
+	mov r17=r8
+	mov r8=r18
+	;;
+#else
+	thash r17=r16				// compute virtual address of L3 PTE
+#endif
+	mov r31=pr
+	mov r29=b0				// save b0 in case of nested fault)
+#ifdef CONFIG_SMP
+	mov r28=ar.ccv				// save ar.ccv
+	;;
+1:	ld8 r18=[r17]
+	;;					// avoid RAW on r18
+	mov ar.ccv=r18				// set compare value for cmpxchg
+	or r25=_PAGE_A,r18			// set the dirty bit
+	tbit.z p7,p6 = r18,_PAGE_P_BIT		// Check present bit
+	;;
+(p6)	cmpxchg8.acq r26=[r17],r25,ar.ccv	// Only if page is present
+	mov r24=PAGE_SHIFT<<2
+	;;
+(p6)	cmp.eq p6,p7=r26,r18			// Only if page is present
+	;;
+#ifdef CONFIG_XEN
+	mov r26=r8
+	mov r8=r25
+	;;
+(p6)	XEN_HYPER_ITC_D
+	;;
+	mov r8=r26
+	;;
+#else
+(p6)	itc.d r25				// install updated PTE
+#endif
+	/*
+	 * Tell the assemblers dependency-violation checker that the above "itc" instructions
+	 * cannot possibly affect the following loads:
+	 */
+	dv_serialize_data
+	;;
+	ld8 r18=[r17]				// read PTE again
+	;;
+	cmp.eq p6,p7=r18,r25			// is it same as the newly installed
+	;;
+(p7)	ptc.l r16,r24
+	mov ar.ccv=r28
+#else
+	;;
+1:	ld8 r18=[r17]
+	;;					// avoid RAW on r18
+	or r18=_PAGE_A,r18			// set the accessed bit
+	;;
+	st8 [r17]=r18				// store back updated PTE
+	itc.d r18				// install updated PTE
+#endif
+	mov b0=r29				// restore b0
+	mov pr=r31,-1
+#ifdef CONFIG_XEN
+	XEN_HYPER_RFI
+	dv_serialize_data
+#else
+	rfi
+#endif
+END(daccess_bit)
+
+	.org ia64_ivt+0x2c00
+/////////////////////////////////////////////////////////////////////////////////////////
+// 0x2c00 Entry 11 (size 64 bundles) Break instruction (33)
+ENTRY(break_fault)
+	/*
+	 * The streamlined system call entry/exit paths only save/restore the initial part
+	 * of pt_regs.  This implies that the callers of system-calls must adhere to the
+	 * normal procedure calling conventions.
+	 *
+	 *   Registers to be saved & restored:
+	 *	CR registers: cr.ipsr, cr.iip, cr.ifs
+	 *	AR registers: ar.unat, ar.pfs, ar.rsc, ar.rnat, ar.bspstore, ar.fpsr
+	 * 	others: pr, b0, b6, loadrs, r1, r11, r12, r13, r15
+	 *   Registers to be restored only:
+	 * 	r8-r11: output value from the system call.
+	 *
+	 * During system call exit, scratch registers (including r15) are modified/cleared
+	 * to prevent leaking bits from kernel to user level.
+	 */
+	DBG_FAULT(11)
+	mov.m r16=IA64_KR(CURRENT)		// M2 r16 <- current task (12 cyc)
+#ifdef CONFIG_XEN
+	movl r22=XSI_IPSR
+	;;
+	ld8 r29=[r22],XSI_IIM_OFS-XSI_IPSR_OFS	// get ipsr, point to iip
+#else
+	mov r29=cr.ipsr				// M2 (12 cyc)
+#endif
+	mov r31=pr				// I0 (2 cyc)
+
+#ifdef CONFIG_XEN
+	;;
+	ld8 r17=[r22],XSI_IIP_OFS-XSI_IIM_OFS
+#else
+	mov r17=cr.iim				// M2 (2 cyc)
+#endif
+	mov.m r27=ar.rsc			// M2 (12 cyc)
+	mov r18=__IA64_BREAK_SYSCALL		// A
+
+	mov.m ar.rsc=0				// M2
+	mov.m r21=ar.fpsr			// M2 (12 cyc)
+	mov r19=b6				// I0 (2 cyc)
+	;;
+	mov.m r23=ar.bspstore			// M2 (12 cyc)
+	mov.m r24=ar.rnat			// M2 (5 cyc)
+	mov.i r26=ar.pfs			// I0 (2 cyc)
+
+	invala					// M0|1
+	nop.m 0					// M
+	mov r20=r1				// A			save r1
+
+	nop.m 0
+	movl r30=sys_call_table			// X
+
+#ifdef CONFIG_XEN
+	ld8 r28=[r22]
+#else
+	mov r28=cr.iip				// M2 (2 cyc)
+#endif
+	cmp.eq p0,p7=r18,r17			// I0 is this a system call?
+(p7)	br.cond.spnt non_syscall		// B  no ->
+	//
+	// From this point on, we are definitely on the syscall-path
+	// and we can use (non-banked) scratch registers.
+	//
+///////////////////////////////////////////////////////////////////////
+	mov r1=r16				// A    move task-pointer to "addl"-addressable reg
+	mov r2=r16				// A    setup r2 for ia64_syscall_setup
+	add r9=TI_FLAGS+IA64_TASK_SIZE,r16	// A	r9 = &current_thread_info()->flags
+
+	adds r16=IA64_TASK_THREAD_ON_USTACK_OFFSET,r16
+	adds r15=-1024,r15			// A    subtract 1024 from syscall number
+	mov r3=NR_syscalls - 1
+	;;
+	ld1.bias r17=[r16]			// M0|1 r17 = current->thread.on_ustack flag
+	ld4 r9=[r9]				// M0|1 r9 = current_thread_info()->flags
+	extr.u r8=r29,41,2			// I0   extract ei field from cr.ipsr
+
+	shladd r30=r15,3,r30			// A    r30 = sys_call_table + 8*(syscall-1024)
+	addl r22=IA64_RBS_OFFSET,r1		// A    compute base of RBS
+	cmp.leu p6,p7=r15,r3			// A    syscall number in range?
+	;;
+
+	lfetch.fault.excl.nt1 [r22]		// M0|1 prefetch RBS
+(p6)	ld8 r30=[r30]				// M0|1 load address of syscall entry point
+	tnat.nz.or p7,p0=r15			// I0	is syscall nr a NaT?
+
+	mov.m ar.bspstore=r22			// M2   switch to kernel RBS
+	cmp.eq p8,p9=2,r8			// A    isr.ei==2?
+	;;
+
+(p8)	mov r8=0				// A    clear ei to 0
+(p7)	movl r30=sys_ni_syscall			// X
+
+(p8)	adds r28=16,r28				// A    switch cr.iip to next bundle
+(p9)	adds r8=1,r8				// A    increment ei to next slot
+	nop.i 0
+	;;
+
+	mov.m r25=ar.unat			// M2 (5 cyc)
+	dep r29=r8,r29,41,2			// I0   insert new ei into cr.ipsr
+	adds r15=1024,r15			// A    restore original syscall number
+	//
+	// If any of the above loads miss in L1D, we'll stall here until
+	// the data arrives.
+	//
+///////////////////////////////////////////////////////////////////////
+	st1 [r16]=r0				// M2|3 clear current->thread.on_ustack flag
+	mov b6=r30				// I0   setup syscall handler branch reg early
+	cmp.eq pKStk,pUStk=r0,r17		// A    were we on kernel stacks already?
+
+	and r9=_TIF_SYSCALL_TRACEAUDIT,r9	// A    mask trace or audit
+	mov r18=ar.bsp				// M2 (12 cyc)
+(pKStk)	br.cond.spnt .break_fixup		// B	we're already in kernel-mode -- fix up RBS
+	;;
+.back_from_break_fixup:
+(pUStk)	addl r1=IA64_STK_OFFSET-IA64_PT_REGS_SIZE,r1 // A    compute base of memory stack
+	cmp.eq p14,p0=r9,r0			// A    are syscalls being traced/audited?
+	br.call.sptk.many b7=ia64_syscall_setup	// B
+1:
+	mov ar.rsc=0x3				// M2   set eager mode, pl 0, LE, loadrs=0
+	nop 0
+#ifdef CONFIG_XEN
+	mov r2=b0; br.call.sptk b0=xen_bsw1;; mov b0=r2;;
+#else
+	bsw.1					// B (6 cyc) regs are saved, switch to bank 1
+#endif
+	;;
+
+#ifdef CONFIG_XEN
+	movl r16=XSI_PSR_IC
+	mov r3=1
+	;;
+	st4 [r16]=r3,XSI_PSR_I_ADDR_OFS-XSI_PSR_IC_OFS	// vpsr.ic = 1
+#else
+	ssm psr.ic | PSR_DEFAULT_BITS		// M2	now it's safe to re-enable intr.-collection
+#endif
+	movl r3=ia64_ret_from_syscall		// X
+	;;
+
+	srlz.i					// M0   ensure interruption collection is on
+	mov rp=r3				// I0   set the real return addr
+(p10)	br.cond.spnt.many ia64_ret_from_syscall	// B    return if bad call-frame or r15 is a NaT
+
+#ifdef CONFIG_XEN
+(p15)	ld8 r16=[r16]				// vpsr.i
+	;;
+(p15)	st1 [r16]=r0,XSI_PEND_OFS-XSI_PSR_I_ADDR_OFS	// if (p15) vpsr.i = 1
+	mov r2=r0
+	;;
+(p15)	ld4 r2=[r16]				// if (pending_interrupts)
+	;;
+	cmp.ne	p6,p0=r2,r0
+	;;
+(p6)	ssm	psr.i				//   do a real ssm psr.i
+#else
+(p15)	ssm psr.i				// M2   restore psr.i
+#endif
+(p14)	br.call.sptk.many b6=b6			// B    invoke syscall-handker (ignore return addr)
+	br.cond.spnt.many ia64_trace_syscall	// B	do syscall-tracing thingamagic
+	// NOT REACHED
+///////////////////////////////////////////////////////////////////////
+	// On entry, we optimistically assumed that we're coming from user-space.
+	// For the rare cases where a system-call is done from within the kernel,
+	// we fix things up at this point:
+.break_fixup:
+	add r1=-IA64_PT_REGS_SIZE,sp		// A    allocate space for pt_regs structure
+	mov ar.rnat=r24				// M2	restore kernel's AR.RNAT
+	;;
+	mov ar.bspstore=r23			// M2	restore kernel's AR.BSPSTORE
+	br.cond.sptk .back_from_break_fixup
+END(break_fault)
+
+	.org ia64_ivt+0x3000
+/////////////////////////////////////////////////////////////////////////////////////////
+// 0x3000 Entry 12 (size 64 bundles) External Interrupt (4)
+ENTRY(interrupt)
+	DBG_FAULT(12)
+	mov r31=pr		// prepare to save predicates
+	;;
+	SAVE_MIN_WITH_COVER	// uses r31; defines r2 and r3
+#ifdef CONFIG_XEN
+	movl r3=XSI_PSR_IC
+	mov r14=1
+	;;
+	st4 [r3]=r14
+#else
+	ssm psr.ic | PSR_DEFAULT_BITS
+#endif
+	;;
+	adds r3=8,r2		// set up second base pointer for SAVE_REST
+	srlz.i			// ensure everybody knows psr.ic is back on
+	;;
+	SAVE_REST
+	;;
+	alloc r14=ar.pfs,0,0,2,0 // must be first in an insn group
+#ifdef CONFIG_XEN
+	;;
+	br.call.sptk.many rp=xen_get_ivr
+	;;
+	mov out0=r8		// pass cr.ivr as first arg
+#else
+	mov out0=cr.ivr		// pass cr.ivr as first arg
+#endif
+	add out1=16,sp		// pass pointer to pt_regs as second arg
+	;;
+	srlz.d			// make sure we see the effect of cr.ivr
+	movl r14=ia64_leave_kernel
+	;;
+	mov rp=r14
+	br.call.sptk.many b6=ia64_handle_irq
+END(interrupt)
+
+	.org ia64_ivt+0x3400
+/////////////////////////////////////////////////////////////////////////////////////////
+// 0x3400 Entry 13 (size 64 bundles) Reserved
+	DBG_FAULT(13)
+	FAULT(13)
+
+	.org ia64_ivt+0x3800
+/////////////////////////////////////////////////////////////////////////////////////////
+// 0x3800 Entry 14 (size 64 bundles) Reserved
+	DBG_FAULT(14)
+	FAULT(14)
+
+	/*
+	 * There is no particular reason for this code to be here, other than that
+	 * there happens to be space here that would go unused otherwise.  If this
+	 * fault ever gets "unreserved", simply moved the following code to a more
+	 * suitable spot...
+	 *
+	 * ia64_syscall_setup() is a separate subroutine so that it can
+	 *	allocate stacked registers so it can safely demine any
+	 *	potential NaT values from the input registers.
+	 *
+	 * On entry:
+	 *	- executing on bank 0 or bank 1 register set (doesn't matter)
+	 *	-  r1: stack pointer
+	 *	-  r2: current task pointer
+	 *	-  r3: preserved
+	 *	- r11: original contents (saved ar.pfs to be saved)
+	 *	- r12: original contents (sp to be saved)
+	 *	- r13: original contents (tp to be saved)
+	 *	- r15: original contents (syscall # to be saved)
+	 *	- r18: saved bsp (after switching to kernel stack)
+	 *	- r19: saved b6
+	 *	- r20: saved r1 (gp)
+	 *	- r21: saved ar.fpsr
+	 *	- r22: kernel's register backing store base (krbs_base)
+	 *	- r23: saved ar.bspstore
+	 *	- r24: saved ar.rnat
+	 *	- r25: saved ar.unat
+	 *	- r26: saved ar.pfs
+	 *	- r27: saved ar.rsc
+	 *	- r28: saved cr.iip
+	 *	- r29: saved cr.ipsr
+	 *	- r31: saved pr
+	 *	-  b0: original contents (to be saved)
+	 * On exit:
+	 *	-  p10: TRUE if syscall is invoked with more than 8 out
+	 *		registers or r15's Nat is true
+	 *	-  r1: kernel's gp
+	 *	-  r3: preserved (same as on entry)
+	 *	-  r8: -EINVAL if p10 is true
+	 *	- r12: points to kernel stack
+	 *	- r13: points to current task
+	 *	- r14: preserved (same as on entry)
+	 *	- p13: preserved
+	 *	- p15: TRUE if interrupts need to be re-enabled
+	 *	- ar.fpsr: set to kernel settings
+	 *	-  b6: preserved (same as on entry)
+	 */
+#ifndef CONFIG_XEN
+GLOBAL_ENTRY(ia64_syscall_setup)
+#if PT(B6) != 0
+# error This code assumes that b6 is the first field in pt_regs.
+#endif
+	st8 [r1]=r19				// save b6
+	add r16=PT(CR_IPSR),r1			// initialize first base pointer
+	add r17=PT(R11),r1			// initialize second base pointer
+	;;
+	alloc r19=ar.pfs,8,0,0,0		// ensure in0-in7 are writable
+	st8 [r16]=r29,PT(AR_PFS)-PT(CR_IPSR)	// save cr.ipsr
+	tnat.nz p8,p0=in0
+
+	st8.spill [r17]=r11,PT(CR_IIP)-PT(R11)	// save r11
+	tnat.nz p9,p0=in1
+(pKStk)	mov r18=r0				// make sure r18 isn't NaT
+	;;
+
+	st8 [r16]=r26,PT(CR_IFS)-PT(AR_PFS)	// save ar.pfs
+	st8 [r17]=r28,PT(AR_UNAT)-PT(CR_IIP)	// save cr.iip
+	mov r28=b0				// save b0 (2 cyc)
+	;;
+
+	st8 [r17]=r25,PT(AR_RSC)-PT(AR_UNAT)	// save ar.unat
+	dep r19=0,r19,38,26			// clear all bits but 0..37 [I0]
+(p8)	mov in0=-1
+	;;
+
+	st8 [r16]=r19,PT(AR_RNAT)-PT(CR_IFS)	// store ar.pfs.pfm in cr.ifs
+	extr.u r11=r19,7,7	// I0		// get sol of ar.pfs
+	and r8=0x7f,r19		// A		// get sof of ar.pfs
+
+	st8 [r17]=r27,PT(AR_BSPSTORE)-PT(AR_RSC)// save ar.rsc
+	tbit.nz p15,p0=r29,IA64_PSR_I_BIT // I0
+(p9)	mov in1=-1
+	;;
+
+(pUStk) sub r18=r18,r22				// r18=RSE.ndirty*8
+	tnat.nz p10,p0=in2
+	add r11=8,r11
+	;;
+(pKStk) adds r16=PT(PR)-PT(AR_RNAT),r16		// skip over ar_rnat field
+(pKStk) adds r17=PT(B0)-PT(AR_BSPSTORE),r17	// skip over ar_bspstore field
+	tnat.nz p11,p0=in3
+	;;
+(p10)	mov in2=-1
+	tnat.nz p12,p0=in4				// [I0]
+(p11)	mov in3=-1
+	;;
+(pUStk) st8 [r16]=r24,PT(PR)-PT(AR_RNAT)	// save ar.rnat
+(pUStk) st8 [r17]=r23,PT(B0)-PT(AR_BSPSTORE)	// save ar.bspstore
+	shl r18=r18,16				// compute ar.rsc to be used for "loadrs"
+	;;
+	st8 [r16]=r31,PT(LOADRS)-PT(PR)		// save predicates
+	st8 [r17]=r28,PT(R1)-PT(B0)		// save b0
+	tnat.nz p13,p0=in5				// [I0]
+	;;
+	st8 [r16]=r18,PT(R12)-PT(LOADRS)	// save ar.rsc value for "loadrs"
+	st8.spill [r17]=r20,PT(R13)-PT(R1)	// save original r1
+(p12)	mov in4=-1
+	;;
+
+.mem.offset 0,0; st8.spill [r16]=r12,PT(AR_FPSR)-PT(R12)	// save r12
+.mem.offset 8,0; st8.spill [r17]=r13,PT(R15)-PT(R13)		// save r13
+(p13)	mov in5=-1
+	;;
+	st8 [r16]=r21,PT(R8)-PT(AR_FPSR)	// save ar.fpsr
+	tnat.nz p13,p0=in6
+	cmp.lt p10,p9=r11,r8	// frame size can't be more than local+8
+	;;
+	mov r8=1
+(p9)	tnat.nz p10,p0=r15
+	adds r12=-16,r1		// switch to kernel memory stack (with 16 bytes of scratch)
+
+	st8.spill [r17]=r15			// save r15
+	tnat.nz p8,p0=in7
+	nop.i 0
+
+	mov r13=r2				// establish `current'
+	movl r1=__gp				// establish kernel global pointer
+	;;
+	st8 [r16]=r8		// ensure pt_regs.r8 != 0 (see handle_syscall_error)
+(p13)	mov in6=-1
+(p8)	mov in7=-1
+
+	cmp.eq pSys,pNonSys=r0,r0		// set pSys=1, pNonSys=0
+	movl r17=FPSR_DEFAULT
+	;;
+	mov.m ar.fpsr=r17			// set ar.fpsr to kernel default value
+(p10)	mov r8=-EINVAL
+	br.ret.sptk.many b7
+END(ia64_syscall_setup)
+#endif
+
+	.org ia64_ivt+0x3c00
+/////////////////////////////////////////////////////////////////////////////////////////
+// 0x3c00 Entry 15 (size 64 bundles) Reserved
+	DBG_FAULT(15)
+	FAULT(15)
+
+	/*
+	 * Squatting in this space ...
+	 *
+	 * This special case dispatcher for illegal operation faults allows preserved
+	 * registers to be modified through a callback function (asm only) that is handed
+	 * back from the fault handler in r8. Up to three arguments can be passed to the
+	 * callback function by returning an aggregate with the callback as its first
+	 * element, followed by the arguments.
+	 */
+ENTRY(dispatch_illegal_op_fault)
+	.prologue
+	.body
+	SAVE_MIN_WITH_COVER
+	ssm psr.ic | PSR_DEFAULT_BITS
+	;;
+	srlz.i		// guarantee that interruption collection is on
+	;;
+(p15)	ssm psr.i	// restore psr.i
+	adds r3=8,r2	// set up second base pointer for SAVE_REST
+	;;
+	alloc r14=ar.pfs,0,0,1,0	// must be first in insn group
+	mov out0=ar.ec
+	;;
+	SAVE_REST
+	PT_REGS_UNWIND_INFO(0)
+	;;
+	br.call.sptk.many rp=ia64_illegal_op_fault
+.ret0:	;;
+	alloc r14=ar.pfs,0,0,3,0	// must be first in insn group
+	mov out0=r9
+	mov out1=r10
+	mov out2=r11
+	movl r15=ia64_leave_kernel
+	;;
+	mov rp=r15
+	mov b6=r8
+	;;
+	cmp.ne p6,p0=0,r8
+(p6)	br.call.dpnt.many b6=b6		// call returns to ia64_leave_kernel
+	br.sptk.many ia64_leave_kernel
+END(dispatch_illegal_op_fault)
+
+	.org ia64_ivt+0x4000
+/////////////////////////////////////////////////////////////////////////////////////////
+// 0x4000 Entry 16 (size 64 bundles) Reserved
+	DBG_FAULT(16)
+	FAULT(16)
+
+	.org ia64_ivt+0x4400
+/////////////////////////////////////////////////////////////////////////////////////////
+// 0x4400 Entry 17 (size 64 bundles) Reserved
+	DBG_FAULT(17)
+	FAULT(17)
+
+ENTRY(non_syscall)
+	mov ar.rsc=r27			// restore ar.rsc before SAVE_MIN_WITH_COVER
+	;;
+	SAVE_MIN_WITH_COVER
+
+	// There is no particular reason for this code to be here, other than that
+	// there happens to be space here that would go unused otherwise.  If this
+	// fault ever gets "unreserved", simply moved the following code to a more
+	// suitable spot...
+
+	alloc r14=ar.pfs,0,0,2,0
+	mov out0=cr.iim
+	add out1=16,sp
+	adds r3=8,r2			// set up second base pointer for SAVE_REST
+
+	ssm psr.ic | PSR_DEFAULT_BITS
+	;;
+	srlz.i				// guarantee that interruption collection is on
+	;;
+(p15)	ssm psr.i			// restore psr.i
+	movl r15=ia64_leave_kernel
+	;;
+	SAVE_REST
+	mov rp=r15
+	;;
+	br.call.sptk.many b6=ia64_bad_break	// avoid WAW on CFM and ignore return addr
+END(non_syscall)
+
+	.org ia64_ivt+0x4800
+/////////////////////////////////////////////////////////////////////////////////////////
+// 0x4800 Entry 18 (size 64 bundles) Reserved
+	DBG_FAULT(18)
+	FAULT(18)
+
+	/*
+	 * There is no particular reason for this code to be here, other than that
+	 * there happens to be space here that would go unused otherwise.  If this
+	 * fault ever gets "unreserved", simply moved the following code to a more
+	 * suitable spot...
+	 */
+
+ENTRY(dispatch_unaligned_handler)
+	SAVE_MIN_WITH_COVER
+	;;
+	alloc r14=ar.pfs,0,0,2,0		// now it's safe (must be first in insn group!)
+	mov out0=cr.ifa
+	adds out1=16,sp
+
+	ssm psr.ic | PSR_DEFAULT_BITS
+	;;
+	srlz.i					// guarantee that interruption collection is on
+	;;
+(p15)	ssm psr.i				// restore psr.i
+	adds r3=8,r2				// set up second base pointer
+	;;
+	SAVE_REST
+	movl r14=ia64_leave_kernel
+	;;
+	mov rp=r14
+	br.sptk.many ia64_prepare_handle_unaligned
+END(dispatch_unaligned_handler)
+
+	.org ia64_ivt+0x4c00
+/////////////////////////////////////////////////////////////////////////////////////////
+// 0x4c00 Entry 19 (size 64 bundles) Reserved
+	DBG_FAULT(19)
+	FAULT(19)
+
+	/*
+	 * There is no particular reason for this code to be here, other than that
+	 * there happens to be space here that would go unused otherwise.  If this
+	 * fault ever gets "unreserved", simply moved the following code to a more
+	 * suitable spot...
+	 */
+
+ENTRY(dispatch_to_fault_handler)
+	/*
+	 * Input:
+	 *	psr.ic:	off
+	 *	r19:	fault vector number (e.g., 24 for General Exception)
+	 *	r31:	contains saved predicates (pr)
+	 */
+	SAVE_MIN_WITH_COVER_R19
+	alloc r14=ar.pfs,0,0,5,0
+	mov out0=r15
+#ifdef CONFIG_XEN
+	movl out1=XSI_ISR
+	;;
+	adds out2=XSI_IFA-XSI_ISR,out1
+	adds out3=XSI_IIM-XSI_ISR,out1
+	adds out4=XSI_ITIR-XSI_ISR,out1
+	;;
+	ld8 out1=[out1]
+	ld8 out2=[out2]
+	ld8 out3=[out4]
+	ld8 out4=[out4]
+	;;
+#else
+	mov out1=cr.isr
+	mov out2=cr.ifa
+	mov out3=cr.iim
+	mov out4=cr.itir
+	;;
+#endif
+	ssm psr.ic | PSR_DEFAULT_BITS
+	;;
+	srlz.i					// guarantee that interruption collection is on
+	;;
+(p15)	ssm psr.i				// restore psr.i
+	adds r3=8,r2				// set up second base pointer for SAVE_REST
+	;;
+	SAVE_REST
+	movl r14=ia64_leave_kernel
+	;;
+	mov rp=r14
+	br.call.sptk.many b6=ia64_fault
+END(dispatch_to_fault_handler)
+
+//
+// --- End of long entries, Beginning of short entries
+//
+
+	.org ia64_ivt+0x5000
+/////////////////////////////////////////////////////////////////////////////////////////
+// 0x5000 Entry 20 (size 16 bundles) Page Not Present (10,22,49)
+ENTRY(page_not_present)
+	DBG_FAULT(20)
+	mov r16=cr.ifa
+	rsm psr.dt
+	/*
+	 * The Linux page fault handler doesn't expect non-present pages to be in
+	 * the TLB.  Flush the existing entry now, so we meet that expectation.
+	 */
+	mov r17=PAGE_SHIFT<<2
+	;;
+	ptc.l r16,r17
+	;;
+	mov r31=pr
+	srlz.d
+	br.sptk.many page_fault
+END(page_not_present)
+
+	.org ia64_ivt+0x5100
+/////////////////////////////////////////////////////////////////////////////////////////
+// 0x5100 Entry 21 (size 16 bundles) Key Permission (13,25,52)
+ENTRY(key_permission)
+	DBG_FAULT(21)
+	mov r16=cr.ifa
+	rsm psr.dt
+	mov r31=pr
+	;;
+	srlz.d
+	br.sptk.many page_fault
+END(key_permission)
+
+	.org ia64_ivt+0x5200
+/////////////////////////////////////////////////////////////////////////////////////////
+// 0x5200 Entry 22 (size 16 bundles) Instruction Access Rights (26)
+ENTRY(iaccess_rights)
+	DBG_FAULT(22)
+	mov r16=cr.ifa
+	rsm psr.dt
+	mov r31=pr
+	;;
+	srlz.d
+	br.sptk.many page_fault
+END(iaccess_rights)
+
+	.org ia64_ivt+0x5300
+/////////////////////////////////////////////////////////////////////////////////////////
+// 0x5300 Entry 23 (size 16 bundles) Data Access Rights (14,53)
+ENTRY(daccess_rights)
+	DBG_FAULT(23)
+#ifdef CONFIG_XEN
+	movl r16=XSI_IFA
+	;;
+	ld8 r16=[r16]
+	;;
+	XEN_HYPER_RSM_PSR_DT
+#else
+	mov r16=cr.ifa
+	rsm psr.dt
+#endif
+	mov r31=pr
+	;;
+	srlz.d
+	br.sptk.many page_fault
+END(daccess_rights)
+
+	.org ia64_ivt+0x5400
+/////////////////////////////////////////////////////////////////////////////////////////
+// 0x5400 Entry 24 (size 16 bundles) General Exception (5,32,34,36,38,39)
+ENTRY(general_exception)
+	DBG_FAULT(24)
+	mov r16=cr.isr
+	mov r31=pr
+	;;
+	cmp4.eq p6,p0=0,r16
+(p6)	br.sptk.many dispatch_illegal_op_fault
+	;;
+	mov r19=24		// fault number
+	br.sptk.many dispatch_to_fault_handler
+END(general_exception)
+
+	.org ia64_ivt+0x5500
+/////////////////////////////////////////////////////////////////////////////////////////
+// 0x5500 Entry 25 (size 16 bundles) Disabled FP-Register (35)
+ENTRY(disabled_fp_reg)
+	DBG_FAULT(25)
+	rsm psr.dfh		// ensure we can access fph
+	;;
+	srlz.d
+	mov r31=pr
+	mov r19=25
+	br.sptk.many dispatch_to_fault_handler
+END(disabled_fp_reg)
+
+	.org ia64_ivt+0x5600
+/////////////////////////////////////////////////////////////////////////////////////////
+// 0x5600 Entry 26 (size 16 bundles) Nat Consumption (11,23,37,50)
+ENTRY(nat_consumption)
+	DBG_FAULT(26)
+
+	mov r16=cr.ipsr
+	mov r17=cr.isr
+	mov r31=pr				// save PR
+	;;
+	and r18=0xf,r17				// r18 = cr.ipsr.code{3:0}
+	tbit.z p6,p0=r17,IA64_ISR_NA_BIT
+	;;
+	cmp.ne.or p6,p0=IA64_ISR_CODE_LFETCH,r18
+	dep r16=-1,r16,IA64_PSR_ED_BIT,1
+(p6)	br.cond.spnt 1f		// branch if (cr.ispr.na == 0 || cr.ipsr.code{3:0} != LFETCH)
+	;;
+	mov cr.ipsr=r16		// set cr.ipsr.na
+	mov pr=r31,-1
+	;;
+	rfi
+
+1:	mov pr=r31,-1
+	;;
+	FAULT(26)
+END(nat_consumption)
+
+	.org ia64_ivt+0x5700
+/////////////////////////////////////////////////////////////////////////////////////////
+// 0x5700 Entry 27 (size 16 bundles) Speculation (40)
+ENTRY(speculation_vector)
+	DBG_FAULT(27)
+	/*
+	 * A [f]chk.[as] instruction needs to take the branch to the recovery code but
+	 * this part of the architecture is not implemented in hardware on some CPUs, such
+	 * as Itanium.  Thus, in general we need to emulate the behavior.  IIM contains
+	 * the relative target (not yet sign extended).  So after sign extending it we
+	 * simply add it to IIP.  We also need to reset the EI field of the IPSR to zero,
+	 * i.e., the slot to restart into.
+	 *
+	 * cr.imm contains zero_ext(imm21)
+	 */
+	mov r18=cr.iim
+	;;
+	mov r17=cr.iip
+	shl r18=r18,43			// put sign bit in position (43=64-21)
+	;;
+
+	mov r16=cr.ipsr
+	shr r18=r18,39			// sign extend (39=43-4)
+	;;
+
+	add r17=r17,r18			// now add the offset
+	;;
+	mov cr.iip=r17
+	dep r16=0,r16,41,2		// clear EI
+	;;
+
+	mov cr.ipsr=r16
+	;;
+
+#ifdef CONFIG_XEN
+	XEN_HYPER_RFI;
+#else
+	rfi				// and go back
+#endif
+END(speculation_vector)
+
+	.org ia64_ivt+0x5800
+/////////////////////////////////////////////////////////////////////////////////////////
+// 0x5800 Entry 28 (size 16 bundles) Reserved
+	DBG_FAULT(28)
+	FAULT(28)
+
+	.org ia64_ivt+0x5900
+/////////////////////////////////////////////////////////////////////////////////////////
+// 0x5900 Entry 29 (size 16 bundles) Debug (16,28,56)
+ENTRY(debug_vector)
+	DBG_FAULT(29)
+	FAULT(29)
+END(debug_vector)
+
+	.org ia64_ivt+0x5a00
+/////////////////////////////////////////////////////////////////////////////////////////
+// 0x5a00 Entry 30 (size 16 bundles) Unaligned Reference (57)
+ENTRY(unaligned_access)
+	DBG_FAULT(30)
+	mov r31=pr		// prepare to save predicates
+	;;
+	br.sptk.many dispatch_unaligned_handler
+END(unaligned_access)
+
+	.org ia64_ivt+0x5b00
+/////////////////////////////////////////////////////////////////////////////////////////
+// 0x5b00 Entry 31 (size 16 bundles) Unsupported Data Reference (57)
+ENTRY(unsupported_data_reference)
+	DBG_FAULT(31)
+	FAULT(31)
+END(unsupported_data_reference)
+
+	.org ia64_ivt+0x5c00
+/////////////////////////////////////////////////////////////////////////////////////////
+// 0x5c00 Entry 32 (size 16 bundles) Floating-Point Fault (64)
+ENTRY(floating_point_fault)
+	DBG_FAULT(32)
+	FAULT(32)
+END(floating_point_fault)
+
+	.org ia64_ivt+0x5d00
+/////////////////////////////////////////////////////////////////////////////////////////
+// 0x5d00 Entry 33 (size 16 bundles) Floating Point Trap (66)
+ENTRY(floating_point_trap)
+	DBG_FAULT(33)
+	FAULT(33)
+END(floating_point_trap)
+
+	.org ia64_ivt+0x5e00
+/////////////////////////////////////////////////////////////////////////////////////////
+// 0x5e00 Entry 34 (size 16 bundles) Lower Privilege Transfer Trap (66)
+ENTRY(lower_privilege_trap)
+	DBG_FAULT(34)
+	FAULT(34)
+END(lower_privilege_trap)
+
+	.org ia64_ivt+0x5f00
+/////////////////////////////////////////////////////////////////////////////////////////
+// 0x5f00 Entry 35 (size 16 bundles) Taken Branch Trap (68)
+ENTRY(taken_branch_trap)
+	DBG_FAULT(35)
+	FAULT(35)
+END(taken_branch_trap)
+
+	.org ia64_ivt+0x6000
+/////////////////////////////////////////////////////////////////////////////////////////
+// 0x6000 Entry 36 (size 16 bundles) Single Step Trap (69)
+ENTRY(single_step_trap)
+	DBG_FAULT(36)
+	FAULT(36)
+END(single_step_trap)
+
+	.org ia64_ivt+0x6100
+/////////////////////////////////////////////////////////////////////////////////////////
+// 0x6100 Entry 37 (size 16 bundles) Reserved
+	DBG_FAULT(37)
+	FAULT(37)
+
+	.org ia64_ivt+0x6200
+/////////////////////////////////////////////////////////////////////////////////////////
+// 0x6200 Entry 38 (size 16 bundles) Reserved
+	DBG_FAULT(38)
+	FAULT(38)
+
+	.org ia64_ivt+0x6300
+/////////////////////////////////////////////////////////////////////////////////////////
+// 0x6300 Entry 39 (size 16 bundles) Reserved
+	DBG_FAULT(39)
+	FAULT(39)
+
+	.org ia64_ivt+0x6400
+/////////////////////////////////////////////////////////////////////////////////////////
+// 0x6400 Entry 40 (size 16 bundles) Reserved
+	DBG_FAULT(40)
+	FAULT(40)
+
+	.org ia64_ivt+0x6500
+/////////////////////////////////////////////////////////////////////////////////////////
+// 0x6500 Entry 41 (size 16 bundles) Reserved
+	DBG_FAULT(41)
+	FAULT(41)
+
+	.org ia64_ivt+0x6600
+/////////////////////////////////////////////////////////////////////////////////////////
+// 0x6600 Entry 42 (size 16 bundles) Reserved
+	DBG_FAULT(42)
+	FAULT(42)
+
+	.org ia64_ivt+0x6700
+/////////////////////////////////////////////////////////////////////////////////////////
+// 0x6700 Entry 43 (size 16 bundles) Reserved
+	DBG_FAULT(43)
+	FAULT(43)
+
+	.org ia64_ivt+0x6800
+/////////////////////////////////////////////////////////////////////////////////////////
+// 0x6800 Entry 44 (size 16 bundles) Reserved
+	DBG_FAULT(44)
+	FAULT(44)
+
+	.org ia64_ivt+0x6900
+/////////////////////////////////////////////////////////////////////////////////////////
+// 0x6900 Entry 45 (size 16 bundles) IA-32 Exeception (17,18,29,41,42,43,44,58,60,61,62,72,73,75,76,77)
+ENTRY(ia32_exception)
+	DBG_FAULT(45)
+	FAULT(45)
+END(ia32_exception)
+
+	.org ia64_ivt+0x6a00
+/////////////////////////////////////////////////////////////////////////////////////////
+// 0x6a00 Entry 46 (size 16 bundles) IA-32 Intercept  (30,31,59,70,71)
+ENTRY(ia32_intercept)
+	DBG_FAULT(46)
+#ifdef	CONFIG_IA32_SUPPORT
+	mov r31=pr
+	mov r16=cr.isr
+	;;
+	extr.u r17=r16,16,8	// get ISR.code
+	mov r18=ar.eflag
+	mov r19=cr.iim		// old eflag value
+	;;
+	cmp.ne p6,p0=2,r17
+(p6)	br.cond.spnt 1f		// not a system flag fault
+	xor r16=r18,r19
+	;;
+	extr.u r17=r16,18,1	// get the eflags.ac bit
+	;;
+	cmp.eq p6,p0=0,r17
+(p6)	br.cond.spnt 1f		// eflags.ac bit didn't change
+	;;
+	mov pr=r31,-1		// restore predicate registers
+#ifdef CONFIG_XEN
+	XEN_HYPER_RFI;
+#else
+	rfi
+#endif
+
+1:
+#endif	// CONFIG_IA32_SUPPORT
+	FAULT(46)
+END(ia32_intercept)
+
+	.org ia64_ivt+0x6b00
+/////////////////////////////////////////////////////////////////////////////////////////
+// 0x6b00 Entry 47 (size 16 bundles) IA-32 Interrupt  (74)
+ENTRY(ia32_interrupt)
+	DBG_FAULT(47)
+#ifdef CONFIG_IA32_SUPPORT
+	mov r31=pr
+	br.sptk.many dispatch_to_ia32_handler
+#else
+	FAULT(47)
+#endif
+END(ia32_interrupt)
+
+	.org ia64_ivt+0x6c00
+/////////////////////////////////////////////////////////////////////////////////////////
+// 0x6c00 Entry 48 (size 16 bundles) Reserved
+	DBG_FAULT(48)
+	FAULT(48)
+
+	.org ia64_ivt+0x6d00
+/////////////////////////////////////////////////////////////////////////////////////////
+// 0x6d00 Entry 49 (size 16 bundles) Reserved
+	DBG_FAULT(49)
+	FAULT(49)
+
+	.org ia64_ivt+0x6e00
+/////////////////////////////////////////////////////////////////////////////////////////
+// 0x6e00 Entry 50 (size 16 bundles) Reserved
+	DBG_FAULT(50)
+	FAULT(50)
+
+	.org ia64_ivt+0x6f00
+/////////////////////////////////////////////////////////////////////////////////////////
+// 0x6f00 Entry 51 (size 16 bundles) Reserved
+	DBG_FAULT(51)
+	FAULT(51)
+
+	.org ia64_ivt+0x7000
+/////////////////////////////////////////////////////////////////////////////////////////
+// 0x7000 Entry 52 (size 16 bundles) Reserved
+	DBG_FAULT(52)
+	FAULT(52)
+
+	.org ia64_ivt+0x7100
+/////////////////////////////////////////////////////////////////////////////////////////
+// 0x7100 Entry 53 (size 16 bundles) Reserved
+	DBG_FAULT(53)
+	FAULT(53)
+
+	.org ia64_ivt+0x7200
+/////////////////////////////////////////////////////////////////////////////////////////
+// 0x7200 Entry 54 (size 16 bundles) Reserved
+	DBG_FAULT(54)
+	FAULT(54)
+
+	.org ia64_ivt+0x7300
+/////////////////////////////////////////////////////////////////////////////////////////
+// 0x7300 Entry 55 (size 16 bundles) Reserved
+	DBG_FAULT(55)
+	FAULT(55)
+
+	.org ia64_ivt+0x7400
+/////////////////////////////////////////////////////////////////////////////////////////
+// 0x7400 Entry 56 (size 16 bundles) Reserved
+	DBG_FAULT(56)
+	FAULT(56)
+
+	.org ia64_ivt+0x7500
+/////////////////////////////////////////////////////////////////////////////////////////
+// 0x7500 Entry 57 (size 16 bundles) Reserved
+	DBG_FAULT(57)
+	FAULT(57)
+
+	.org ia64_ivt+0x7600
+/////////////////////////////////////////////////////////////////////////////////////////
+// 0x7600 Entry 58 (size 16 bundles) Reserved
+	DBG_FAULT(58)
+	FAULT(58)
+
+	.org ia64_ivt+0x7700
+/////////////////////////////////////////////////////////////////////////////////////////
+// 0x7700 Entry 59 (size 16 bundles) Reserved
+	DBG_FAULT(59)
+	FAULT(59)
+
+	.org ia64_ivt+0x7800
+/////////////////////////////////////////////////////////////////////////////////////////
+// 0x7800 Entry 60 (size 16 bundles) Reserved
+	DBG_FAULT(60)
+	FAULT(60)
+
+	.org ia64_ivt+0x7900
+/////////////////////////////////////////////////////////////////////////////////////////
+// 0x7900 Entry 61 (size 16 bundles) Reserved
+	DBG_FAULT(61)
+	FAULT(61)
+
+	.org ia64_ivt+0x7a00
+/////////////////////////////////////////////////////////////////////////////////////////
+// 0x7a00 Entry 62 (size 16 bundles) Reserved
+	DBG_FAULT(62)
+	FAULT(62)
+
+	.org ia64_ivt+0x7b00
+/////////////////////////////////////////////////////////////////////////////////////////
+// 0x7b00 Entry 63 (size 16 bundles) Reserved
+	DBG_FAULT(63)
+	FAULT(63)
+
+	.org ia64_ivt+0x7c00
+/////////////////////////////////////////////////////////////////////////////////////////
+// 0x7c00 Entry 64 (size 16 bundles) Reserved
+	DBG_FAULT(64)
+	FAULT(64)
+
+	.org ia64_ivt+0x7d00
+/////////////////////////////////////////////////////////////////////////////////////////
+// 0x7d00 Entry 65 (size 16 bundles) Reserved
+	DBG_FAULT(65)
+	FAULT(65)
+
+	.org ia64_ivt+0x7e00
+/////////////////////////////////////////////////////////////////////////////////////////
+// 0x7e00 Entry 66 (size 16 bundles) Reserved
+	DBG_FAULT(66)
+	FAULT(66)
+
+#ifdef CONFIG_XEN
+	/*
+	 * There is no particular reason for this code to be here, other than that
+	 * there happens to be space here that would go unused otherwise.  If this
+	 * fault ever gets "unreserved", simply moved the following code to a more
+	 * suitable spot...
+	 */
+
+GLOBAL_ENTRY(xen_bsw1)
+	/* FIXME: THIS CODE IS NOT NaT SAFE! */
+	movl r30=XSI_BANKNUM;
+	mov r31=1;;
+	st4 [r30]=r31;
+	movl r30=XSI_BANK1_R16;
+	movl r31=XSI_BANK1_R16+8;;
+	ld8 r16=[r30],16; ld8 r17=[r31],16;;
+	ld8 r18=[r30],16; ld8 r19=[r31],16;;
+	ld8 r20=[r30],16; ld8 r21=[r31],16;;
+	ld8 r22=[r30],16; ld8 r23=[r31],16;;
+	ld8 r24=[r30],16; ld8 r25=[r31],16;;
+	ld8 r26=[r30],16; ld8 r27=[r31],16;;
+	ld8 r28=[r30],16; ld8 r29=[r31],16;;
+	ld8 r30=[r30]; ld8 r31=[r31];;
+	br.ret.sptk.many b0
+END(xen_bsw1)
+#endif
+
+	.org ia64_ivt+0x7f00
+/////////////////////////////////////////////////////////////////////////////////////////
+// 0x7f00 Entry 67 (size 16 bundles) Reserved
+	DBG_FAULT(67)
+	FAULT(67)
+
+#ifdef CONFIG_IA32_SUPPORT
+
+	/*
+	 * There is no particular reason for this code to be here, other than that
+	 * there happens to be space here that would go unused otherwise.  If this
+	 * fault ever gets "unreserved", simply moved the following code to a more
+	 * suitable spot...
+	 */
+
+	// IA32 interrupt entry point
+
+ENTRY(dispatch_to_ia32_handler)
+	SAVE_MIN
+	;;
+	mov r14=cr.isr
+	ssm psr.ic | PSR_DEFAULT_BITS
+	;;
+	srlz.i					// guarantee that interruption collection is on
+	;;
+(p15)	ssm psr.i
+	adds r3=8,r2		// Base pointer for SAVE_REST
+	;;
+	SAVE_REST
+	;;
+	mov r15=0x80
+	shr r14=r14,16		// Get interrupt number
+	;;
+	cmp.ne p6,p0=r14,r15
+(p6)	br.call.dpnt.many b6=non_ia32_syscall
+
+	adds r14=IA64_PT_REGS_R8_OFFSET + 16,sp	// 16 byte hole per SW conventions
+	adds r15=IA64_PT_REGS_R1_OFFSET + 16,sp
+	;;
+	cmp.eq pSys,pNonSys=r0,r0 // set pSys=1, pNonSys=0
+	ld8 r8=[r14]		// get r8
+	;;
+	st8 [r15]=r8		// save original EAX in r1 (IA32 procs don't use the GP)
+	;;
+	alloc r15=ar.pfs,0,0,6,0	// must first in an insn group
+	;;
+	ld4 r8=[r14],8		// r8 == eax (syscall number)
+	mov r15=IA32_NR_syscalls
+	;;
+	cmp.ltu.unc p6,p7=r8,r15
+	ld4 out1=[r14],8	// r9 == ecx
+	;;
+	ld4 out2=[r14],8	// r10 == edx
+	;;
+	ld4 out0=[r14]		// r11 == ebx
+	adds r14=(IA64_PT_REGS_R13_OFFSET) + 16,sp
+	;;
+	ld4 out5=[r14],PT(R14)-PT(R13)	// r13 == ebp
+	;;
+	ld4 out3=[r14],PT(R15)-PT(R14)	// r14 == esi
+	adds r2=TI_FLAGS+IA64_TASK_SIZE,r13
+	;;
+	ld4 out4=[r14]		// r15 == edi
+	movl r16=ia32_syscall_table
+	;;
+(p6)	shladd r16=r8,3,r16	// force ni_syscall if not valid syscall number
+	ld4 r2=[r2]		// r2 = current_thread_info()->flags
+	;;
+	ld8 r16=[r16]
+	and r2=_TIF_SYSCALL_TRACEAUDIT,r2	// mask trace or audit
+	;;
+	mov b6=r16
+	movl r15=ia32_ret_from_syscall
+	cmp.eq p8,p0=r2,r0
+	;;
+	mov rp=r15
+(p8)	br.call.sptk.many b6=b6
+	br.cond.sptk ia32_trace_syscall
+
+non_ia32_syscall:
+	alloc r15=ar.pfs,0,0,2,0
+	mov out0=r14				// interrupt #
+	add out1=16,sp				// pointer to pt_regs
+	;;			// avoid WAW on CFM
+	br.call.sptk.many rp=ia32_bad_interrupt
+.ret1:	movl r15=ia64_leave_kernel
+	;;
+	mov rp=r15
+	br.ret.sptk.many rp
+END(dispatch_to_ia32_handler)
+#endif /* CONFIG_IA32_SUPPORT */
+
+#ifdef CONFIG_XEN
+	.section .text,"ax"
+GLOBAL_ENTRY(xen_event_callback)
+	mov r31=pr		// prepare to save predicates
+	;;
+	SAVE_MIN_WITH_COVER	// uses r31; defines r2 and r3
+	;;
+	movl r3=XSI_PSR_IC
+	mov r14=1
+	;;
+	st4 [r3]=r14
+	;;
+	adds r3=8,r2		// set up second base pointer for SAVE_REST
+	srlz.i			// ensure everybody knows psr.ic is back on
+	;;
+	SAVE_REST
+	;;
+	alloc r14=ar.pfs,0,0,1,0 // must be first in an insn group
+	add out0=16,sp		// pass pointer to pt_regs as first arg
+	;;
+	srlz.d			// make sure we see the effect of cr.ivr
+	movl r14=ia64_leave_kernel
+	;;
+	mov rp=r14
+	br.call.sptk.many b6=evtchn_do_upcall
+END(xen_event_callback)
+#endif
diff --git a/arch/ia64/xen/xenminstate.h b/arch/ia64/xen/xenminstate.h
new file mode 100644
index 000000000..f92fc6eda
--- /dev/null
+++ b/arch/ia64/xen/xenminstate.h
@@ -0,0 +1,368 @@
+
+#include <asm/cache.h>
+
+#ifdef CONFIG_XEN
+#include "../kernel/entry.h"
+#else
+#include "entry.h"
+#endif
+
+/*
+ * For ivt.s we want to access the stack virtually so we don't have to disable translation
+ * on interrupts.
+ *
+ *  On entry:
+ *	r1:	pointer to current task (ar.k6)
+ */
+#define MINSTATE_START_SAVE_MIN_VIRT								\
+(pUStk)	mov ar.rsc=0;		/* set enforced lazy mode, pl 0, little-endian, loadrs=0 */	\
+	;;											\
+(pUStk)	mov.m r24=ar.rnat;									\
+(pUStk)	addl r22=IA64_RBS_OFFSET,r1;			/* compute base of RBS */		\
+(pKStk) mov r1=sp;					/* get sp  */				\
+	;;											\
+(pUStk) lfetch.fault.excl.nt1 [r22];								\
+(pUStk)	addl r1=IA64_STK_OFFSET-IA64_PT_REGS_SIZE,r1;	/* compute base of memory stack */	\
+(pUStk)	mov r23=ar.bspstore;				/* save ar.bspstore */			\
+	;;											\
+(pUStk)	mov ar.bspstore=r22;				/* switch to kernel RBS */		\
+(pKStk) addl r1=-IA64_PT_REGS_SIZE,r1;			/* if in kernel mode, use sp (r12) */	\
+	;;											\
+(pUStk)	mov r18=ar.bsp;										\
+(pUStk)	mov ar.rsc=0x3;		/* set eager mode, pl 0, little-endian, loadrs=0 */		\
+
+#define MINSTATE_END_SAVE_MIN_VIRT								\
+	bsw.1;			/* switch back to bank 1 (must be last in insn group) */	\
+	;;
+
+/*
+ * For mca_asm.S we want to access the stack physically since the state is saved before we
+ * go virtual and don't want to destroy the iip or ipsr.
+ */
+#define MINSTATE_START_SAVE_MIN_PHYS								\
+(pKStk) mov r3=IA64_KR(PER_CPU_DATA);;								\
+(pKStk) addl r3=THIS_CPU(ia64_mca_data),r3;;							\
+(pKStk) ld8 r3 = [r3];;										\
+(pKStk) addl r3=IA64_MCA_CPU_INIT_STACK_OFFSET,r3;;						\
+(pKStk) addl sp=IA64_STK_OFFSET-IA64_PT_REGS_SIZE,r3;						\
+(pUStk)	mov ar.rsc=0;		/* set enforced lazy mode, pl 0, little-endian, loadrs=0 */	\
+(pUStk)	addl r22=IA64_RBS_OFFSET,r1;		/* compute base of register backing store */	\
+	;;											\
+(pUStk)	mov r24=ar.rnat;									\
+(pUStk)	addl r1=IA64_STK_OFFSET-IA64_PT_REGS_SIZE,r1;	/* compute base of memory stack */	\
+(pUStk)	mov r23=ar.bspstore;				/* save ar.bspstore */			\
+(pUStk)	dep r22=-1,r22,61,3;			/* compute kernel virtual addr of RBS */	\
+	;;											\
+(pKStk) addl r1=-IA64_PT_REGS_SIZE,r1;		/* if in kernel mode, use sp (r12) */		\
+(pUStk)	mov ar.bspstore=r22;			/* switch to kernel RBS */			\
+	;;											\
+(pUStk)	mov r18=ar.bsp;										\
+(pUStk)	mov ar.rsc=0x3;		/* set eager mode, pl 0, little-endian, loadrs=0 */		\
+
+#define MINSTATE_END_SAVE_MIN_PHYS								\
+	dep r12=-1,r12,61,3;		/* make sp a kernel virtual address */			\
+	;;
+
+#ifdef MINSTATE_VIRT
+# define MINSTATE_GET_CURRENT(reg)	mov reg=IA64_KR(CURRENT)
+# define MINSTATE_START_SAVE_MIN	MINSTATE_START_SAVE_MIN_VIRT
+# define MINSTATE_END_SAVE_MIN		MINSTATE_END_SAVE_MIN_VIRT
+#endif
+
+#ifdef MINSTATE_PHYS
+# define MINSTATE_GET_CURRENT(reg)	mov reg=IA64_KR(CURRENT);; tpa reg=reg
+# define MINSTATE_START_SAVE_MIN	MINSTATE_START_SAVE_MIN_PHYS
+# define MINSTATE_END_SAVE_MIN		MINSTATE_END_SAVE_MIN_PHYS
+#endif
+
+/*
+ * DO_SAVE_MIN switches to the kernel stacks (if necessary) and saves
+ * the minimum state necessary that allows us to turn psr.ic back
+ * on.
+ *
+ * Assumed state upon entry:
+ *	psr.ic: off
+ *	r31:	contains saved predicates (pr)
+ *
+ * Upon exit, the state is as follows:
+ *	psr.ic: off
+ *	 r2 = points to &pt_regs.r16
+ *	 r8 = contents of ar.ccv
+ *	 r9 = contents of ar.csd
+ *	r10 = contents of ar.ssd
+ *	r11 = FPSR_DEFAULT
+ *	r12 = kernel sp (kernel virtual address)
+ *	r13 = points to current task_struct (kernel virtual address)
+ *	p15 = TRUE if psr.i is set in cr.ipsr
+ *	predicate registers (other than p2, p3, and p15), b6, r3, r14, r15:
+ *		preserved
+ * CONFIG_XEN note: p6/p7 are not preserved
+ *
+ * Note that psr.ic is NOT turned on by this macro.  This is so that
+ * we can pass interruption state as arguments to a handler.
+ */
+#ifdef CONFIG_XEN
+#define DO_SAVE_MIN(COVER,SAVE_IFS,EXTRA)							\
+	MINSTATE_GET_CURRENT(r16);	/* M (or M;;I) */					\
+	mov r27=ar.rsc;			/* M */							\
+	mov r20=r1;			/* A */							\
+	mov r25=ar.unat;		/* M */							\
+	/* mov r29=cr.ipsr;		/* M */							\
+	movl r29=XSI_IPSR;;									\
+	ld8 r29=[r29];;										\
+	mov r26=ar.pfs;			/* I */							\
+	/* mov r28=cr.iip;		/* M */							\
+	movl r28=XSI_IIP;;									\
+	ld8 r28=[r28];;										\
+	mov r21=ar.fpsr;		/* M */							\
+	COVER;			/* B;; (or nothing) */					\
+	;;											\
+	adds r16=IA64_TASK_THREAD_ON_USTACK_OFFSET,r16;						\
+	;;											\
+	ld1 r17=[r16];				/* load current->thread.on_ustack flag */	\
+	st1 [r16]=r0;				/* clear current->thread.on_ustack flag */	\
+	adds r1=-IA64_TASK_THREAD_ON_USTACK_OFFSET,r16						\
+	/* switch from user to kernel RBS: */							\
+	;;											\
+	invala;				/* M */							\
+	/* SAVE_IFS; /* see xen special handling below */						\
+	cmp.eq pKStk,pUStk=r0,r17;		/* are we in kernel mode already? */		\
+	;;											\
+	MINSTATE_START_SAVE_MIN									\
+	adds r17=2*L1_CACHE_BYTES,r1;		/* really: biggest cache-line size */		\
+	adds r16=PT(CR_IPSR),r1;								\
+	;;											\
+	lfetch.fault.excl.nt1 [r17],L1_CACHE_BYTES;						\
+	st8 [r16]=r29;		/* save cr.ipsr */						\
+	;;											\
+	lfetch.fault.excl.nt1 [r17];								\
+	tbit.nz p15,p0=r29,IA64_PSR_I_BIT;							\
+	mov r29=b0										\
+	;;											\
+	adds r16=PT(R8),r1;	/* initialize first base pointer */				\
+	adds r17=PT(R9),r1;	/* initialize second base pointer */				\
+(pKStk)	mov r18=r0;		/* make sure r18 isn't NaT */					\
+	;;											\
+.mem.offset 0,0; st8.spill [r16]=r8,16;								\
+.mem.offset 8,0; st8.spill [r17]=r9,16;								\
+        ;;											\
+.mem.offset 0,0; st8.spill [r16]=r10,24;							\
+.mem.offset 8,0; st8.spill [r17]=r11,24;							\
+        ;;											\
+	/* xen special handling for possibly lazy cover */					\
+	movl r8=XSI_INCOMPL_REGFR;								\
+	;;											\
+	ld4 r30=[r8];										\
+	;;											\
+	/* set XSI_INCOMPL_REGFR 0 */								\
+	st4 [r8]=r0;										\
+	cmp.eq	p6,p7=r30,r0;									\
+	;; /* not sure if this stop bit is necessary */						\
+(p6)	adds r8=XSI_PRECOVER_IFS-XSI_INCOMPL_REGFR,r8;						\
+(p7)	adds r8=XSI_IFS-XSI_INCOMPL_REGFR,r8;							\
+	;;											\
+	ld8 r30=[r8];										\
+	;;											\
+	st8 [r16]=r28,16;	/* save cr.iip */						\
+	st8 [r17]=r30,16;	/* save cr.ifs */						\
+(pUStk)	sub r18=r18,r22;	/* r18=RSE.ndirty*8 */						\
+	mov r8=ar.ccv;										\
+	mov r9=ar.csd;										\
+	mov r10=ar.ssd;										\
+	movl r11=FPSR_DEFAULT;   /* L-unit */							\
+	;;											\
+	st8 [r16]=r25,16;	/* save ar.unat */						\
+	st8 [r17]=r26,16;	/* save ar.pfs */						\
+	shl r18=r18,16;		/* compute ar.rsc to be used for "loadrs" */			\
+	;;											\
+	st8 [r16]=r27,16;	/* save ar.rsc */						\
+(pUStk)	st8 [r17]=r24,16;	/* save ar.rnat */						\
+(pKStk)	adds r17=16,r17;	/* skip over ar_rnat field */					\
+	;;			/* avoid RAW on r16 & r17 */					\
+(pUStk)	st8 [r16]=r23,16;	/* save ar.bspstore */						\
+	st8 [r17]=r31,16;	/* save predicates */						\
+(pKStk)	adds r16=16,r16;	/* skip over ar_bspstore field */				\
+	;;											\
+	st8 [r16]=r29,16;	/* save b0 */							\
+	st8 [r17]=r18,16;	/* save ar.rsc value for "loadrs" */				\
+	cmp.eq pNonSys,pSys=r0,r0	/* initialize pSys=0, pNonSys=1 */			\
+	;;											\
+.mem.offset 0,0; st8.spill [r16]=r20,16;	/* save original r1 */				\
+.mem.offset 8,0; st8.spill [r17]=r12,16;							\
+	adds r12=-16,r1;	/* switch to kernel memory stack (with 16 bytes of scratch) */	\
+	;;											\
+.mem.offset 0,0; st8.spill [r16]=r13,16;							\
+.mem.offset 8,0; st8.spill [r17]=r21,16;	/* save ar.fpsr */				\
+	mov r13=IA64_KR(CURRENT);	/* establish `current' */				\
+	;;											\
+.mem.offset 0,0; st8.spill [r16]=r15,16;							\
+.mem.offset 8,0; st8.spill [r17]=r14,16;							\
+	;;											\
+.mem.offset 0,0; st8.spill [r16]=r2,16;								\
+.mem.offset 8,0; st8.spill [r17]=r3,16;								\
+	;;											\
+	EXTRA;											\
+	mov r2=b0; br.call.sptk b0=xen_bsw1;; mov b0=r2;					\
+	adds r2=IA64_PT_REGS_R16_OFFSET,r1;							\
+	;;											\
+	movl r1=__gp;		/* establish kernel global pointer */				\
+	;;											\
+	/* MINSTATE_END_SAVE_MIN */
+#else
+#define DO_SAVE_MIN(COVER,SAVE_IFS,EXTRA)							\
+	MINSTATE_GET_CURRENT(r16);	/* M (or M;;I) */					\
+	mov r27=ar.rsc;			/* M */							\
+	mov r20=r1;			/* A */							\
+	mov r25=ar.unat;		/* M */							\
+	mov r29=cr.ipsr;		/* M */							\
+	mov r26=ar.pfs;			/* I */							\
+	mov r28=cr.iip;			/* M */							\
+	mov r21=ar.fpsr;		/* M */							\
+	COVER;				/* B;; (or nothing) */					\
+	;;											\
+	adds r16=IA64_TASK_THREAD_ON_USTACK_OFFSET,r16;						\
+	;;											\
+	ld1 r17=[r16];				/* load current->thread.on_ustack flag */	\
+	st1 [r16]=r0;				/* clear current->thread.on_ustack flag */	\
+	adds r1=-IA64_TASK_THREAD_ON_USTACK_OFFSET,r16						\
+	/* switch from user to kernel RBS: */							\
+	;;											\
+	invala;				/* M */							\
+	SAVE_IFS;										\
+	cmp.eq pKStk,pUStk=r0,r17;		/* are we in kernel mode already? */		\
+	;;											\
+	MINSTATE_START_SAVE_MIN									\
+	adds r17=2*L1_CACHE_BYTES,r1;		/* really: biggest cache-line size */		\
+	adds r16=PT(CR_IPSR),r1;								\
+	;;											\
+	lfetch.fault.excl.nt1 [r17],L1_CACHE_BYTES;						\
+	st8 [r16]=r29;		/* save cr.ipsr */						\
+	;;											\
+	lfetch.fault.excl.nt1 [r17];								\
+	tbit.nz p15,p0=r29,IA64_PSR_I_BIT;							\
+	mov r29=b0										\
+	;;											\
+	adds r16=PT(R8),r1;	/* initialize first base pointer */				\
+	adds r17=PT(R9),r1;	/* initialize second base pointer */				\
+(pKStk)	mov r18=r0;		/* make sure r18 isn't NaT */					\
+	;;											\
+.mem.offset 0,0; st8.spill [r16]=r8,16;								\
+.mem.offset 8,0; st8.spill [r17]=r9,16;								\
+        ;;											\
+.mem.offset 0,0; st8.spill [r16]=r10,24;							\
+.mem.offset 8,0; st8.spill [r17]=r11,24;							\
+        ;;											\
+	st8 [r16]=r28,16;	/* save cr.iip */						\
+	st8 [r17]=r30,16;	/* save cr.ifs */						\
+(pUStk)	sub r18=r18,r22;	/* r18=RSE.ndirty*8 */						\
+	mov r8=ar.ccv;										\
+	mov r9=ar.csd;										\
+	mov r10=ar.ssd;										\
+	movl r11=FPSR_DEFAULT;   /* L-unit */							\
+	;;											\
+	st8 [r16]=r25,16;	/* save ar.unat */						\
+	st8 [r17]=r26,16;	/* save ar.pfs */						\
+	shl r18=r18,16;		/* compute ar.rsc to be used for "loadrs" */			\
+	;;											\
+	st8 [r16]=r27,16;	/* save ar.rsc */						\
+(pUStk)	st8 [r17]=r24,16;	/* save ar.rnat */						\
+(pKStk)	adds r17=16,r17;	/* skip over ar_rnat field */					\
+	;;			/* avoid RAW on r16 & r17 */					\
+(pUStk)	st8 [r16]=r23,16;	/* save ar.bspstore */						\
+	st8 [r17]=r31,16;	/* save predicates */						\
+(pKStk)	adds r16=16,r16;	/* skip over ar_bspstore field */				\
+	;;											\
+	st8 [r16]=r29,16;	/* save b0 */							\
+	st8 [r17]=r18,16;	/* save ar.rsc value for "loadrs" */				\
+	cmp.eq pNonSys,pSys=r0,r0	/* initialize pSys=0, pNonSys=1 */			\
+	;;											\
+.mem.offset 0,0; st8.spill [r16]=r20,16;	/* save original r1 */				\
+.mem.offset 8,0; st8.spill [r17]=r12,16;							\
+	adds r12=-16,r1;	/* switch to kernel memory stack (with 16 bytes of scratch) */	\
+	;;											\
+.mem.offset 0,0; st8.spill [r16]=r13,16;							\
+.mem.offset 8,0; st8.spill [r17]=r21,16;	/* save ar.fpsr */				\
+	mov r13=IA64_KR(CURRENT);	/* establish `current' */				\
+	;;											\
+.mem.offset 0,0; st8.spill [r16]=r15,16;							\
+.mem.offset 8,0; st8.spill [r17]=r14,16;							\
+	;;											\
+.mem.offset 0,0; st8.spill [r16]=r2,16;								\
+.mem.offset 8,0; st8.spill [r17]=r3,16;								\
+	adds r2=IA64_PT_REGS_R16_OFFSET,r1;							\
+	;;											\
+	EXTRA;											\
+	movl r1=__gp;		/* establish kernel global pointer */				\
+	;;											\
+	MINSTATE_END_SAVE_MIN
+#endif
+
+/*
+ * SAVE_REST saves the remainder of pt_regs (with psr.ic on).
+ *
+ * Assumed state upon entry:
+ *	psr.ic: on
+ *	r2:	points to &pt_regs.r16
+ *	r3:	points to &pt_regs.r17
+ *	r8:	contents of ar.ccv
+ *	r9:	contents of ar.csd
+ *	r10:	contents of ar.ssd
+ *	r11:	FPSR_DEFAULT
+ *
+ * Registers r14 and r15 are guaranteed not to be touched by SAVE_REST.
+ */
+#define SAVE_REST				\
+.mem.offset 0,0; st8.spill [r2]=r16,16;		\
+.mem.offset 8,0; st8.spill [r3]=r17,16;		\
+	;;					\
+.mem.offset 0,0; st8.spill [r2]=r18,16;		\
+.mem.offset 8,0; st8.spill [r3]=r19,16;		\
+	;;					\
+.mem.offset 0,0; st8.spill [r2]=r20,16;		\
+.mem.offset 8,0; st8.spill [r3]=r21,16;		\
+	mov r18=b6;				\
+	;;					\
+.mem.offset 0,0; st8.spill [r2]=r22,16;		\
+.mem.offset 8,0; st8.spill [r3]=r23,16;		\
+	mov r19=b7;				\
+	;;					\
+.mem.offset 0,0; st8.spill [r2]=r24,16;		\
+.mem.offset 8,0; st8.spill [r3]=r25,16;		\
+	;;					\
+.mem.offset 0,0; st8.spill [r2]=r26,16;		\
+.mem.offset 8,0; st8.spill [r3]=r27,16;		\
+	;;					\
+.mem.offset 0,0; st8.spill [r2]=r28,16;		\
+.mem.offset 8,0; st8.spill [r3]=r29,16;		\
+	;;					\
+.mem.offset 0,0; st8.spill [r2]=r30,16;		\
+.mem.offset 8,0; st8.spill [r3]=r31,32;		\
+	;;					\
+	mov ar.fpsr=r11;	/* M-unit */	\
+	st8 [r2]=r8,8;		/* ar.ccv */	\
+	adds r24=PT(B6)-PT(F7),r3;		\
+	;;					\
+	stf.spill [r2]=f6,32;			\
+	stf.spill [r3]=f7,32;			\
+	;;					\
+	stf.spill [r2]=f8,32;			\
+	stf.spill [r3]=f9,32;			\
+	;;					\
+	stf.spill [r2]=f10;			\
+	stf.spill [r3]=f11;			\
+	adds r25=PT(B7)-PT(F11),r3;		\
+	;;					\
+	st8 [r24]=r18,16;       /* b6 */	\
+	st8 [r25]=r19,16;       /* b7 */	\
+	;;					\
+	st8 [r24]=r9;        	/* ar.csd */	\
+	st8 [r25]=r10;      	/* ar.ssd */	\
+	;;
+
+#define SAVE_MIN_WITH_COVER	DO_SAVE_MIN(cover, mov r30=cr.ifs,)
+#define SAVE_MIN_WITH_COVER_R19	DO_SAVE_MIN(cover, mov r30=cr.ifs, mov r15=r19)
+#ifdef CONFIG_XEN
+#define SAVE_MIN		break 0;; /* FIXME: non-cover version only for ia32 support? */
+#else
+#define SAVE_MIN		DO_SAVE_MIN(     , mov r30=r0, )
+#endif
diff --git a/arch/ia64/xen/xenpal.S b/arch/ia64/xen/xenpal.S
new file mode 100644
index 000000000..5f9681e49
--- /dev/null
+++ b/arch/ia64/xen/xenpal.S
@@ -0,0 +1,76 @@
+/*
+ * ia64/xen/xenpal.S
+ *
+ * Alternate PAL  routines for Xen.  Heavily leveraged from
+ *   ia64/kernel/pal.S
+ *
+ * Copyright (C) 2005 Hewlett-Packard Co
+ *	Dan Magenheimer <dan.magenheimer@.hp.com>
+ */
+
+#include <asm/asmmacro.h>
+#include <asm/processor.h>
+
+GLOBAL_ENTRY(xen_pal_call_static)
+	.prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(5)
+	alloc loc1 = ar.pfs,5,5,0,0
+#ifdef CONFIG_XEN
+	movl r22=running_on_xen;;
+	ld4 r22=[r22];;
+	cmp.eq p7,p0=r22,r0
+(p7)	br.cond.spnt.many __ia64_pal_call_static;;
+#endif
+	movl loc2 = pal_entry_point
+1:	{
+	  mov r28 = in0
+	  mov r29 = in1
+	  mov r8 = ip
+	}
+	;;
+	ld8 loc2 = [loc2]		// loc2 <- entry point
+	tbit.nz p6,p7 = in4, 0
+	adds r8 = 1f-1b,r8
+	mov loc4=ar.rsc			// save RSE configuration
+	;;
+	mov ar.rsc=0			// put RSE in enforced lazy, LE mode
+	mov loc3 = psr
+	mov loc0 = rp
+	.body
+	mov r30 = in2
+
+#ifdef CONFIG_XEN
+	// this is low priority for paravirtualization, but is called
+	// from the idle loop so confuses privop counting
+	movl r31=XSI_PSR_IC
+	;;
+(p6)	st4 [r31]=r0
+	;;
+(p7)	adds r31=XSI_PSR_I_ADDR_OFS-XSI_PSR_IC_OFS,r31
+(p7)	mov r22=1
+	;;
+(p7)	ld8 r31=[r31]
+	;;
+(p7)	st1 [r31]=r22
+	;;
+	mov r31 = in3
+	mov b7 = loc2
+	;;
+#else
+(p6)	rsm psr.i | psr.ic
+	mov r31 = in3
+	mov b7 = loc2
+
+(p7)	rsm psr.i
+	;;
+(p6)	srlz.i
+#endif
+	mov rp = r8
+	br.cond.sptk.many b7
+1:	mov psr.l = loc3
+	mov ar.rsc = loc4		// restore RSE configuration
+	mov ar.pfs = loc1
+	mov rp = loc0
+	;;
+	srlz.d				// seralize restoration of psr.l
+	br.ret.sptk.many b0
+END(xen_pal_call_static)
diff --git a/arch/ia64/xen/xensetup.S b/arch/ia64/xen/xensetup.S
new file mode 100644
index 000000000..a2beb1cfd
--- /dev/null
+++ b/arch/ia64/xen/xensetup.S
@@ -0,0 +1,54 @@
+/*
+ * Support routines for Xen
+ *
+ * Copyright (C) 2005 Dan Magenheimer <dan.magenheimer@hp.com>
+ */
+
+#include <asm/processor.h>
+#include <asm/asmmacro.h>
+
+#define isBP	p3	// are we the Bootstrap Processor?
+
+	.text
+GLOBAL_ENTRY(early_xen_setup)
+	mov r8=ar.rsc		// Initialized in head.S
+(isBP)	movl r9=running_on_xen;;
+	extr.u r8=r8,2,2;;	// Extract pl fields
+	cmp.eq p7,p0=r8,r0	// p7: !running on xen
+	mov r8=1		// booleanize.
+(p7)	br.ret.sptk.many rp;;
+(isBP)	st4 [r9]=r8
+	movl r10=xen_ivt;;
+	
+	mov cr.iva=r10
+
+#if XSI_BASE != 0xf100000000000000UL
+	/* Backward compatibility.  */
+(isBP)	mov r2=0x600
+(isBP)	movl r28=XSI_BASE;;
+(isBP)	break 0x1000;;
+#endif
+
+	br.ret.sptk.many rp
+	;;
+END(early_xen_setup)
+
+#include <xen/interface/xen.h>
+
+/* Stub for suspend.
+   Just force the stacked registers to be written in memory.  */	
+GLOBAL_ENTRY(HYPERVISOR_suspend)
+	alloc r20=ar.pfs,0,0,0,0
+	mov r14=2
+	mov r15=r12
+	;;
+	/* We don't want to deal with RSE.  */
+	flushrs
+	mov r2=__HYPERVISOR_sched_op
+	st4 [r12]=r14
+	;;
+	break 0x1000
+	;; 
+	mov ar.pfs=r20
+	br.ret.sptk.many b0
+END(HYPERVISOR_suspend)
diff --git a/arch/m68k/kernel/dma.c b/arch/m68k/kernel/dma.c
new file mode 100644
index 000000000..fc449f8b2
--- /dev/null
+++ b/arch/m68k/kernel/dma.c
@@ -0,0 +1,129 @@
+/*
+ * 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.
+ */
+
+#undef DEBUG
+
+#include <linux/dma-mapping.h>
+#include <linux/device.h>
+#include <linux/kernel.h>
+#include <linux/vmalloc.h>
+
+#include <asm/pgalloc.h>
+#include <asm/scatterlist.h>
+
+void *dma_alloc_coherent(struct device *dev, size_t size,
+			 dma_addr_t *handle, int flag)
+{
+	struct page *page, **map;
+	pgprot_t pgprot;
+	void *addr;
+	int i, order;
+
+	pr_debug("dma_alloc_coherent: %d,%x\n", size, flag);
+
+	size = PAGE_ALIGN(size);
+	order = get_order(size);
+
+	page = alloc_pages(flag, order);
+	if (!page)
+		return NULL;
+
+	*handle = page_to_phys(page);
+	map = kmalloc(sizeof(struct page *) << order, flag & ~__GFP_DMA);
+	if (!map) {
+		__free_pages(page, order);
+		return NULL;
+	}
+	split_page(page, order);
+
+	order = 1 << order;
+	size >>= PAGE_SHIFT;
+	map[0] = page;
+	for (i = 1; i < size; i++)
+		map[i] = page + i;
+	for (; i < order; i++)
+		__free_page(page + i);
+	pgprot = __pgprot(_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_DIRTY);
+	if (CPU_IS_040_OR_060)
+		pgprot_val(pgprot) |= _PAGE_GLOBAL040 | _PAGE_NOCACHE_S;
+	else
+		pgprot_val(pgprot) |= _PAGE_NOCACHE030;
+	addr = vmap(map, size, flag, pgprot);
+	kfree(map);
+
+	return addr;
+}
+EXPORT_SYMBOL(dma_alloc_coherent);
+
+void dma_free_coherent(struct device *dev, size_t size,
+		       void *addr, dma_addr_t handle)
+{
+	pr_debug("dma_free_coherent: %p, %x\n", addr, handle);
+	vfree(addr);
+}
+EXPORT_SYMBOL(dma_free_coherent);
+
+inline void dma_sync_single_for_device(struct device *dev, dma_addr_t handle, size_t size,
+				       enum dma_data_direction dir)
+{
+	switch (dir) {
+	case DMA_TO_DEVICE:
+		cache_push(handle, size);
+		break;
+	case DMA_FROM_DEVICE:
+		cache_clear(handle, size);
+		break;
+	default:
+		if (printk_ratelimit())
+			printk("dma_sync_single_for_device: unsupported dir %u\n", dir);
+		break;
+	}
+}
+EXPORT_SYMBOL(dma_sync_single_for_device);
+
+void dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, int nents,
+			    enum dma_data_direction dir)
+{
+	int i;
+
+	for (i = 0; i < nents; sg++, i++)
+		dma_sync_single_for_device(dev, sg->dma_address, sg->length, dir);
+}
+EXPORT_SYMBOL(dma_sync_sg_for_device);
+
+dma_addr_t dma_map_single(struct device *dev, void *addr, size_t size,
+			  enum dma_data_direction dir)
+{
+	dma_addr_t handle = virt_to_bus(addr);
+
+	dma_sync_single_for_device(dev, handle, size, dir);
+	return handle;
+}
+EXPORT_SYMBOL(dma_map_single);
+
+dma_addr_t dma_map_page(struct device *dev, struct page *page,
+			unsigned long offset, size_t size,
+			enum dma_data_direction dir)
+{
+	dma_addr_t handle = page_to_phys(page) + offset;
+
+	dma_sync_single_for_device(dev, handle, size, dir);
+	return handle;
+}
+EXPORT_SYMBOL(dma_map_page);
+
+int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
+	       enum dma_data_direction dir)
+{
+	int i;
+
+	for (i = 0; i < nents; sg++, i++) {
+		sg->dma_address = page_to_phys(sg->page) + sg->offset;
+		dma_sync_single_for_device(dev, sg->dma_address, sg->length, dir);
+	}
+	return nents;
+}
+EXPORT_SYMBOL(dma_map_sg);
diff --git a/arch/m68k/lib/uaccess.c b/arch/m68k/lib/uaccess.c
new file mode 100644
index 000000000..1bc188c0d
--- /dev/null
+++ b/arch/m68k/lib/uaccess.c
@@ -0,0 +1,222 @@
+/*
+ * 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.
+ */
+
+#include <linux/module.h>
+#include <asm/uaccess.h>
+
+unsigned long __generic_copy_from_user(void *to, const void __user *from,
+				       unsigned long n)
+{
+	unsigned long tmp, res;
+
+	asm volatile ("\n"
+		"	tst.l	%0\n"
+		"	jeq	2f\n"
+		"1:	moves.l	(%1)+,%3\n"
+		"	move.l	%3,(%2)+\n"
+		"	subq.l	#1,%0\n"
+		"	jne	1b\n"
+		"2:	btst	#1,%5\n"
+		"	jeq	4f\n"
+		"3:	moves.w	(%1)+,%3\n"
+		"	move.w	%3,(%2)+\n"
+		"4:	btst	#0,%5\n"
+		"	jeq	6f\n"
+		"5:	moves.b	(%1)+,%3\n"
+		"	move.b  %3,(%2)+\n"
+		"6:\n"
+		"	.section .fixup,\"ax\"\n"
+		"	.even\n"
+		"10:	move.l	%0,%3\n"
+		"7:	clr.l	(%2)+\n"
+		"	subq.l	#1,%3\n"
+		"	jne	7b\n"
+		"	lsl.l	#2,%0\n"
+		"	btst	#1,%5\n"
+		"	jeq	8f\n"
+		"30:	clr.w	(%2)+\n"
+		"	addq.l	#2,%0\n"
+		"8:	btst	#0,%5\n"
+		"	jeq	6b\n"
+		"50:	clr.b	(%2)+\n"
+		"	addq.l	#1,%0\n"
+		"	jra	6b\n"
+		"	.previous\n"
+		"\n"
+		"	.section __ex_table,\"a\"\n"
+		"	.align	4\n"
+		"	.long	1b,10b\n"
+		"	.long	3b,30b\n"
+		"	.long	5b,50b\n"
+		"	.previous"
+		: "=d" (res), "+a" (from), "+a" (to), "=&r" (tmp)
+		: "0" (n / 4), "d" (n & 3));
+
+	return res;
+}
+EXPORT_SYMBOL(__generic_copy_from_user);
+
+unsigned long __generic_copy_to_user(void __user *to, const void *from,
+				     unsigned long n)
+{
+	unsigned long tmp, res;
+
+	asm volatile ("\n"
+		"	tst.l	%0\n"
+		"	jeq	4f\n"
+		"1:	move.l	(%1)+,%3\n"
+		"2:	moves.l	%3,(%2)+\n"
+		"3:	subq.l	#1,%0\n"
+		"	jne	1b\n"
+		"4:	btst	#1,%5\n"
+		"	jeq	6f\n"
+		"	move.w	(%1)+,%3\n"
+		"5:	moves.w	%3,(%2)+\n"
+		"6:	btst	#0,%5\n"
+		"	jeq	8f\n"
+		"	move.b	(%1)+,%3\n"
+		"7:	moves.b  %3,(%2)+\n"
+		"8:\n"
+		"	.section .fixup,\"ax\"\n"
+		"	.even\n"
+		"20:	lsl.l	#2,%0\n"
+		"50:	add.l	%5,%0\n"
+		"	jra	7b\n"
+		"	.previous\n"
+		"\n"
+		"	.section __ex_table,\"a\"\n"
+		"	.align	4\n"
+		"	.long	2b,20b\n"
+		"	.long	3b,20b\n"
+		"	.long	5b,50b\n"
+		"	.long	6b,50b\n"
+		"	.long	7b,50b\n"
+		"	.long	8b,50b\n"
+		"	.previous"
+		: "=d" (res), "+a" (from), "+a" (to), "=&r" (tmp)
+		: "0" (n / 4), "d" (n & 3));
+
+	return res;
+}
+EXPORT_SYMBOL(__generic_copy_to_user);
+
+/*
+ * Copy a null terminated string from userspace.
+ */
+long strncpy_from_user(char *dst, const char __user *src, long count)
+{
+	long res;
+	char c;
+
+	if (count <= 0)
+		return count;
+
+	asm volatile ("\n"
+		"1:	moves.b	(%2)+,%4\n"
+		"	move.b	%4,(%1)+\n"
+		"	jeq	2f\n"
+		"	subq.l	#1,%3\n"
+		"	jne	1b\n"
+		"2:	sub.l	%3,%0\n"
+		"3:\n"
+		"	.section .fixup,\"ax\"\n"
+		"	.even\n"
+		"10:	move.l	%5,%0\n"
+		"	jra	3b\n"
+		"	.previous\n"
+		"\n"
+		"	.section __ex_table,\"a\"\n"
+		"	.align	4\n"
+		"	.long	1b,10b\n"
+		"	.previous"
+		: "=d" (res), "+a" (dst), "+a" (src), "+r" (count), "=&d" (c)
+		: "i" (-EFAULT), "0" (count));
+
+	return res;
+}
+EXPORT_SYMBOL(strncpy_from_user);
+
+/*
+ * Return the size of a string (including the ending 0)
+ *
+ * Return 0 on exception, a value greater than N if too long
+ */
+long strnlen_user(const char __user *src, long n)
+{
+	char c;
+	long res;
+
+	asm volatile ("\n"
+		"1:	subq.l	#1,%1\n"
+		"	jmi	3f\n"
+		"2:	moves.b	(%0)+,%2\n"
+		"	tst.b	%2\n"
+		"	jne	1b\n"
+		"	jra	4f\n"
+		"\n"
+		"3:	addq.l	#1,%0\n"
+		"4:	sub.l	%4,%0\n"
+		"5:\n"
+		"	.section .fixup,\"ax\"\n"
+		"	.even\n"
+		"20:	sub.l	%0,%0\n"
+		"	jra	5b\n"
+		"	.previous\n"
+		"\n"
+		"	.section __ex_table,\"a\"\n"
+		"	.align	4\n"
+		"	.long	2b,20b\n"
+		"	.previous\n"
+		: "=&a" (res), "+d" (n), "=&d" (c)
+		: "0" (src), "r" (src));
+
+	return res;
+}
+EXPORT_SYMBOL(strnlen_user);
+
+/*
+ * Zero Userspace
+ */
+
+unsigned long clear_user(void __user *to, unsigned long n)
+{
+	unsigned long res;
+
+	asm volatile ("\n"
+		"	tst.l	%0\n"
+		"	jeq	3f\n"
+		"1:	moves.l	%2,(%1)+\n"
+		"2:	subq.l	#1,%0\n"
+		"	jne	1b\n"
+		"3:	btst	#1,%4\n"
+		"	jeq	5f\n"
+		"4:	moves.w	%2,(%1)+\n"
+		"5:	btst	#0,%4\n"
+		"	jeq	7f\n"
+		"6:	moves.b	%2,(%1)\n"
+		"7:\n"
+		"	.section .fixup,\"ax\"\n"
+		"	.even\n"
+		"10:	lsl.l	#2,%0\n"
+		"40:	add.l	%4,%0\n"
+		"	jra	7b\n"
+		"	.previous\n"
+		"\n"
+		"	.section __ex_table,\"a\"\n"
+		"	.align	4\n"
+		"	.long	1b,10b\n"
+		"	.long	2b,10b\n"
+		"	.long	4b,40b\n"
+		"	.long	5b,40b\n"
+		"	.long	6b,40b\n"
+		"	.long	7b,40b\n"
+		"	.previous"
+		: "=d" (res), "+a" (to)
+		: "r" (0), "0" (n / 4), "d" (n & 3));
+
+    return res;
+}
+EXPORT_SYMBOL(clear_user);
diff --git a/arch/m68knommu/platform/532x/Makefile b/arch/m68knommu/platform/532x/Makefile
new file mode 100644
index 000000000..12301803b
--- /dev/null
+++ b/arch/m68knommu/platform/532x/Makefile
@@ -0,0 +1,20 @@
+#
+# Makefile for the m68knommu linux kernel.
+#
+
+#
+# If you want to play with the HW breakpoints then you will
+# need to add define this,  which will give you a stack backtrace
+# on the console port whenever a DBG interrupt occurs. You have to
+# set up you HW breakpoints to trigger a DBG interrupt:
+#
+# EXTRA_CFLAGS += -DTRAP_DBG_INTERRUPT
+# EXTRA_AFLAGS += -DTRAP_DBG_INTERRUPT
+#
+
+ifdef CONFIG_FULLDEBUG
+AFLAGS += -DDEBUGGER_COMPATIBLE_CACHE=1
+endif
+
+#obj-y := config.o usb-mcf532x.o spi-mcf532x.o
+obj-y := config.o
diff --git a/arch/m68knommu/platform/532x/config.c b/arch/m68knommu/platform/532x/config.c
new file mode 100644
index 000000000..c7d6ad513
--- /dev/null
+++ b/arch/m68knommu/platform/532x/config.c
@@ -0,0 +1,485 @@
+/***************************************************************************/
+
+/*
+ *	linux/arch/m68knommu/platform/532x/config.c
+ *
+ *	Copyright (C) 1999-2002, Greg Ungerer (gerg@snapgear.com)
+ *	Copyright (C) 2000, Lineo (www.lineo.com)
+ *	Yaroslav Vinogradov yaroslav.vinogradov@freescale.com
+ *	Copyright Freescale Semiconductor, Inc 2006
+ *	Copyright (c) 2006, emlix, Sebastian Hess <sh@emlix.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.
+ */
+
+/***************************************************************************/
+
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/param.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <asm/irq.h>
+#include <asm/dma.h>
+#include <asm/traps.h>
+#include <asm/machdep.h>
+#include <asm/coldfire.h>
+#include <asm/mcftimer.h>
+#include <asm/mcfsim.h>
+#include <asm/mcfdma.h>
+#include <asm/mcfwdebug.h>
+
+/***************************************************************************/
+
+void coldfire_tick(void);
+void coldfire_timer_init(irqreturn_t (*handler)(int, void *, struct pt_regs *));
+unsigned long coldfire_timer_offset(void);
+void coldfire_trap_init(void);
+void coldfire_reset(void);
+
+extern unsigned int mcf_timervector;
+extern unsigned int mcf_profilevector;
+extern unsigned int mcf_timerlevel;
+
+/***************************************************************************/
+
+/*
+ *	DMA channel base address table.
+ */
+unsigned int dma_base_addr[MAX_M68K_DMA_CHANNELS] = { };
+unsigned int dma_device_address[MAX_M68K_DMA_CHANNELS];
+
+/***************************************************************************/
+
+void mcf_settimericr(unsigned int timer, unsigned int level)
+{
+	volatile unsigned char *icrp;
+	unsigned int icr;
+	unsigned char irq;
+
+	if (timer <= 2) {
+		switch (timer) {
+		case 2:  irq = 33; icr = MCFSIM_ICR_TIMER2; break;
+		default: irq = 32; icr = MCFSIM_ICR_TIMER1; break;
+		}
+		
+		icrp = (volatile unsigned char *) (MCF_MBAR + icr);
+		*icrp = level;
+		mcf_enable_irq0(irq);
+	}
+}
+
+/***************************************************************************/
+
+int mcf_timerirqpending(int timer)
+{
+	unsigned int imr = 0;
+
+	switch (timer) {
+	case 1:  imr = 0x1; break;
+	case 2:  imr = 0x2; break;
+	default: break;
+	}
+	return (mcf_getiprh() & imr);
+}
+
+/***************************************************************************/
+
+void config_BSP(char *commandp, int size)
+{
+	mcf_setimr(MCFSIM_IMR_MASKALL);
+
+#if defined(CONFIG_BOOTPARAM)
+	strncpy(commandp, CONFIG_BOOTPARAM_STRING, size);
+	commandp[size-1] = 0;
+#else
+	/* Copy command line from FLASH to local buffer... */
+	memcpy(commandp, (char *) 0x4000, 4);
+	if(strncmp(commandp, "kcl ", 4) == 0){
+		memcpy(commandp, (char *) 0x4004, size);
+		commandp[size-1] = 0;
+	} else {
+		memset(commandp, 0, size);
+	}
+#endif
+
+	mcf_timervector = 64+32;
+	mcf_profilevector = 64+33;
+	mach_sched_init = coldfire_timer_init;
+	mach_tick = coldfire_tick;
+	mach_gettimeoffset = coldfire_timer_offset;
+	mach_trap_init = coldfire_trap_init;
+	mach_reset = coldfire_reset;
+
+#ifdef MCF_BDM_DISABLE
+	/*
+	 * Disable the BDM clocking.  This also turns off most of the rest of
+	 * the BDM device.  This is good for EMC reasons. This option is not
+	 * incompatible with the memory protection option.
+	 */
+	wdebug(MCFDEBUG_CSR, MCFDEBUG_CSR_PSTCLK);
+#endif
+}
+
+/***************************************************************************/
+/* Board initialization */
+
+/********************************************************************/
+/* 
+ * PLL min/max specifications
+ */
+#define MAX_FVCO	500000	/* KHz */
+#define MAX_FSYS	80000 	/* KHz */
+#define MIN_FSYS	58333 	/* KHz */
+#define FREF		16000   /* KHz */
+
+
+#define MAX_MFD		135     /* Multiplier */
+#define MIN_MFD		88      /* Multiplier */
+#define BUSDIV		6       /* Divider */
+
+/*
+ * Low Power Divider specifications
+ */
+#define MIN_LPD		(1 << 0)    /* Divider (not encoded) */
+#define MAX_LPD		(1 << 15)   /* Divider (not encoded) */
+#define DEFAULT_LPD	(1 << 1)	/* Divider (not encoded) */
+
+#define SYS_CLK_KHZ	80000
+#define SYSTEM_PERIOD	12.5
+/*
+ *  SDRAM Timing Parameters
+ */  
+#define SDRAM_BL	8	/* # of beats in a burst */
+#define SDRAM_TWR	2	/* in clocks */
+#define SDRAM_CASL	2.5	/* CASL in clocks */
+#define SDRAM_TRCD	2	/* in clocks */
+#define SDRAM_TRP	2	/* in clocks */
+#define SDRAM_TRFC	7	/* in clocks */
+#define SDRAM_TREFI	7800	/* in ns */
+
+#define EXT_SRAM_ADDRESS	(0xC0000000)
+#define FLASH_ADDRESS		(0x00000000)
+#define SDRAM_ADDRESS		(0x40000000)
+
+#define NAND_FLASH_ADDRESS	(0xD0000000)
+
+int sys_clk_khz = 0;
+int sys_clk_mhz = 0;
+
+void wtm_init(void);
+void scm_init(void);
+void gpio_init(void);
+void fbcs_init(void);
+void sdramc_init(void);
+int  clock_pll (int fsys, int flags);
+int  clock_limp (int);
+int  clock_exit_limp (void);
+int  get_sys_clock (void);
+
+asmlinkage void __init sysinit(void)
+{
+	sys_clk_khz = clock_pll(0, 0);
+	sys_clk_mhz = sys_clk_khz/1000;
+	
+	wtm_init();
+	scm_init();
+	gpio_init();
+	fbcs_init();
+	sdramc_init();
+}
+
+void wtm_init(void)
+{
+	/* Disable watchdog timer */
+	MCF_WTM_WCR = 0;
+}
+
+#define MCF_SCM_BCR_GBW		(0x00000100)
+#define MCF_SCM_BCR_GBR		(0x00000200)
+
+void scm_init(void)
+{
+	/* All masters are trusted */
+	MCF_SCM_MPR = 0x77777777;
+    
+	/* Allow supervisor/user, read/write, and trusted/untrusted
+	   access to all slaves */
+	MCF_SCM_PACRA = 0;
+	MCF_SCM_PACRB = 0;
+	MCF_SCM_PACRC = 0;
+	MCF_SCM_PACRD = 0;
+	MCF_SCM_PACRE = 0;
+	MCF_SCM_PACRF = 0;
+
+	/* Enable bursts */
+	MCF_SCM_BCR = (MCF_SCM_BCR_GBR | MCF_SCM_BCR_GBW);
+}
+
+
+void fbcs_init(void)
+{
+	MCF_GPIO_PAR_CS = 0x0000003E;
+
+	/* Latch chip select */
+	MCF_FBCS1_CSAR = 0x10080000;
+
+	MCF_FBCS1_CSCR = 0x002A3780;
+	MCF_FBCS1_CSMR = (MCF_FBCS_CSMR_BAM_2M | MCF_FBCS_CSMR_V);
+
+	/* Initialize latch to drive signals to inactive states */
+	*((u16 *)(0x10080000)) = 0xFFFF;
+
+	/* External SRAM */
+	MCF_FBCS1_CSAR = EXT_SRAM_ADDRESS;
+	MCF_FBCS1_CSCR = (MCF_FBCS_CSCR_PS_16
+			| MCF_FBCS_CSCR_AA
+			| MCF_FBCS_CSCR_SBM
+			| MCF_FBCS_CSCR_WS(1));
+	MCF_FBCS1_CSMR = (MCF_FBCS_CSMR_BAM_512K
+			| MCF_FBCS_CSMR_V);
+
+	/* Boot Flash connected to FBCS0 */
+	MCF_FBCS0_CSAR = FLASH_ADDRESS;
+	MCF_FBCS0_CSCR = (MCF_FBCS_CSCR_PS_16
+			| MCF_FBCS_CSCR_BEM
+			| MCF_FBCS_CSCR_AA
+			| MCF_FBCS_CSCR_SBM
+			| MCF_FBCS_CSCR_WS(7));
+	MCF_FBCS0_CSMR = (MCF_FBCS_CSMR_BAM_32M
+			| MCF_FBCS_CSMR_V);
+}
+
+void sdramc_init(void)
+{
+	/*
+	 * Check to see if the SDRAM has already been initialized
+	 * by a run control tool
+	 */
+	if (!(MCF_SDRAMC_SDCR & MCF_SDRAMC_SDCR_REF)) {
+		/* SDRAM chip select initialization */
+		
+		/* Initialize SDRAM chip select */
+		MCF_SDRAMC_SDCS0 = (0
+			| MCF_SDRAMC_SDCS_BA(SDRAM_ADDRESS)
+			| MCF_SDRAMC_SDCS_CSSZ(MCF_SDRAMC_SDCS_CSSZ_32MBYTE));
+
+	/*
+	 * Basic configuration and initialization
+	 */
+	MCF_SDRAMC_SDCFG1 = (0
+		| MCF_SDRAMC_SDCFG1_SRD2RW((int)((SDRAM_CASL + 2) + 0.5 ))
+		| MCF_SDRAMC_SDCFG1_SWT2RD(SDRAM_TWR + 1)
+		| MCF_SDRAMC_SDCFG1_RDLAT((int)((SDRAM_CASL*2) + 2))
+		| MCF_SDRAMC_SDCFG1_ACT2RW((int)((SDRAM_TRCD ) + 0.5))
+		| MCF_SDRAMC_SDCFG1_PRE2ACT((int)((SDRAM_TRP ) + 0.5))
+		| MCF_SDRAMC_SDCFG1_REF2ACT((int)(((SDRAM_TRFC) ) + 0.5))
+		| MCF_SDRAMC_SDCFG1_WTLAT(3));
+	MCF_SDRAMC_SDCFG2 = (0
+		| MCF_SDRAMC_SDCFG2_BRD2PRE(SDRAM_BL/2 + 1)
+		| MCF_SDRAMC_SDCFG2_BWT2RW(SDRAM_BL/2 + SDRAM_TWR)
+		| MCF_SDRAMC_SDCFG2_BRD2WT((int)((SDRAM_CASL+SDRAM_BL/2-1.0)+0.5))
+		| MCF_SDRAMC_SDCFG2_BL(SDRAM_BL-1));
+
+            
+	/*
+	 * Precharge and enable write to SDMR
+	 */
+        MCF_SDRAMC_SDCR = (0
+		| MCF_SDRAMC_SDCR_MODE_EN
+		| MCF_SDRAMC_SDCR_CKE
+		| MCF_SDRAMC_SDCR_DDR
+		| MCF_SDRAMC_SDCR_MUX(1)
+		| MCF_SDRAMC_SDCR_RCNT((int)(((SDRAM_TREFI/(SYSTEM_PERIOD*64)) - 1) + 0.5))
+		| MCF_SDRAMC_SDCR_PS_16
+		| MCF_SDRAMC_SDCR_IPALL);            
+
+	/*
+	 * Write extended mode register
+	 */
+	MCF_SDRAMC_SDMR = (0
+		| MCF_SDRAMC_SDMR_BNKAD_LEMR
+		| MCF_SDRAMC_SDMR_AD(0x0)
+		| MCF_SDRAMC_SDMR_CMD);
+
+	/*
+	 * Write mode register and reset DLL
+	 */
+	MCF_SDRAMC_SDMR = (0
+		| MCF_SDRAMC_SDMR_BNKAD_LMR
+		| MCF_SDRAMC_SDMR_AD(0x163)
+		| MCF_SDRAMC_SDMR_CMD);
+
+	/*
+	 * Execute a PALL command
+	 */
+	MCF_SDRAMC_SDCR |= MCF_SDRAMC_SDCR_IPALL;
+
+	/*
+	 * Perform two REF cycles
+	 */
+	MCF_SDRAMC_SDCR |= MCF_SDRAMC_SDCR_IREF;
+	MCF_SDRAMC_SDCR |= MCF_SDRAMC_SDCR_IREF;
+
+	/*
+	 * Write mode register and clear reset DLL
+	 */
+	MCF_SDRAMC_SDMR = (0
+		| MCF_SDRAMC_SDMR_BNKAD_LMR
+		| MCF_SDRAMC_SDMR_AD(0x063)
+		| MCF_SDRAMC_SDMR_CMD);
+				
+	/*
+	 * Enable auto refresh and lock SDMR
+	 */
+	MCF_SDRAMC_SDCR &= ~MCF_SDRAMC_SDCR_MODE_EN;
+	MCF_SDRAMC_SDCR |= (0
+		| MCF_SDRAMC_SDCR_REF
+		| MCF_SDRAMC_SDCR_DQS_OE(0xC));
+	}
+}
+
+void gpio_init(void)
+{
+	/* Enable UART0 pins */
+	MCF_GPIO_PAR_UART = ( 0
+		| MCF_GPIO_PAR_UART_PAR_URXD0
+		| MCF_GPIO_PAR_UART_PAR_UTXD0);
+
+	/* Initialize TIN3 as a GPIO output to enable the write
+	   half of the latch */
+	MCF_GPIO_PAR_TIMER = 0x00;
+	MCF_GPIO_PDDR_TIMER = 0x08;
+	MCF_GPIO_PCLRR_TIMER = 0x0;
+
+}
+
+int clock_pll(int fsys, int flags)
+{
+	int fref, temp, fout, mfd;
+	u32 i;
+
+	fref = FREF;
+        
+	if (fsys == 0) {
+		/* Return current PLL output */
+		mfd = MCF_PLL_PFDR;
+
+		return (fref * mfd / (BUSDIV * 4));
+	}
+
+	/* Check bounds of requested system clock */
+	if (fsys > MAX_FSYS)
+		fsys = MAX_FSYS;
+	if (fsys < MIN_FSYS)
+		fsys = MIN_FSYS;
+
+	/* Multiplying by 100 when calculating the temp value,
+	   and then dividing by 100 to calculate the mfd allows
+	   for exact values without needing to include floating
+	   point libraries. */
+	temp = 100 * fsys / fref;
+	mfd = 4 * BUSDIV * temp / 100;
+    	    	    	
+	/* Determine the output frequency for selected values */
+	fout = (fref * mfd / (BUSDIV * 4));
+
+	/*
+	 * Check to see if the SDRAM has already been initialized.
+	 * If it has then the SDRAM needs to be put into self refresh
+	 * mode before reprogramming the PLL.
+	 */
+	if (MCF_SDRAMC_SDCR & MCF_SDRAMC_SDCR_REF)
+		/* Put SDRAM into self refresh mode */
+		MCF_SDRAMC_SDCR &= ~MCF_SDRAMC_SDCR_CKE;
+
+	/*
+	 * Initialize the PLL to generate the new system clock frequency.
+	 * The device must be put into LIMP mode to reprogram the PLL.
+	 */
+
+	/* Enter LIMP mode */
+	clock_limp(DEFAULT_LPD);
+     					
+	/* Reprogram PLL for desired fsys */
+	MCF_PLL_PODR = (0
+		| MCF_PLL_PODR_CPUDIV(BUSDIV/3)
+		| MCF_PLL_PODR_BUSDIV(BUSDIV));
+						
+	MCF_PLL_PFDR = mfd;
+		
+	/* Exit LIMP mode */
+	clock_exit_limp();
+	
+	/*
+	 * Return the SDRAM to normal operation if it is in use.
+	 */
+	if (MCF_SDRAMC_SDCR & MCF_SDRAMC_SDCR_REF)
+		/* Exit self refresh mode */
+		MCF_SDRAMC_SDCR |= MCF_SDRAMC_SDCR_CKE;
+
+	/* Errata - workaround for SDRAM opeartion after exiting LIMP mode */
+	MCF_SDRAMC_LIMP_FIX = MCF_SDRAMC_REFRESH;
+
+	/* wait for DQS logic to relock */
+	for (i = 0; i < 0x200; i++)
+		;
+
+	return fout;
+}
+
+int clock_limp(int div)
+{
+	u32 temp;
+
+	/* Check bounds of divider */
+	if (div < MIN_LPD)
+		div = MIN_LPD;
+	if (div > MAX_LPD)
+		div = MAX_LPD;
+    
+	/* Save of the current value of the SSIDIV so we don't
+	   overwrite the value*/
+	temp = (MCF_CCM_CDR & MCF_CCM_CDR_SSIDIV(0xF));
+      
+	/* Apply the divider to the system clock */
+	MCF_CCM_CDR = ( 0
+		| MCF_CCM_CDR_LPDIV(div)
+		| MCF_CCM_CDR_SSIDIV(temp));
+    
+	MCF_CCM_MISCCR |= MCF_CCM_MISCCR_LIMP;
+    
+	return (FREF/(3*(1 << div)));
+}
+
+int clock_exit_limp(void)
+{
+	int fout;
+	
+	/* Exit LIMP mode */
+	MCF_CCM_MISCCR = (MCF_CCM_MISCCR & ~ MCF_CCM_MISCCR_LIMP);
+
+	/* Wait for PLL to lock */
+	while (!(MCF_CCM_MISCCR & MCF_CCM_MISCCR_PLL_LOCK))
+		;
+	
+	fout = get_sys_clock();
+
+	return fout;
+}
+
+int get_sys_clock(void)
+{
+	int divider;
+	
+	/* Test to see if device is in LIMP mode */
+	if (MCF_CCM_MISCCR & MCF_CCM_MISCCR_LIMP) {
+		divider = MCF_CCM_CDR & MCF_CCM_CDR_LPDIV(0xF);
+		return (FREF/(2 << divider));
+	}
+	else
+		return ((FREF * MCF_PLL_PFDR) / (BUSDIV * 4));
+}
diff --git a/arch/m68knommu/platform/68328/romvec.S b/arch/m68knommu/platform/68328/romvec.S
new file mode 100644
index 000000000..31084466e
--- /dev/null
+++ b/arch/m68knommu/platform/68328/romvec.S
@@ -0,0 +1,35 @@
+/*
+ * linux/arch/m68knommu/platform/68328/romvec.S
+ *
+ * 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 1996 Roman Zippel
+ * Copyright 1999 D. Jeff Dionne <jeff@rt-control.com>
+ * Copyright 2006 Greg Ungerer <gerg@snapgear.com>
+ */
+
+.global _start
+.global _buserr
+.global trap
+.global system_call
+
+.section .romvec
+
+e_vectors:
+.long CONFIG_RAMBASE+CONFIG_RAMSIZE-4, _start, buserr, trap
+.long trap, trap, trap, trap
+.long trap, trap, trap, trap
+.long trap, trap, trap, trap
+.long trap, trap, trap, trap
+.long trap, trap, trap, trap
+.long trap, trap, trap, trap
+.long trap, trap, trap, trap
+/* TRAP #0-15 */
+.long system_call, trap, trap, trap
+.long trap, trap, trap, trap
+.long trap, trap, trap, trap
+.long trap, trap, trap, trap
+.long 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+
diff --git a/arch/mips/basler/excite/Makefile b/arch/mips/basler/excite/Makefile
new file mode 100644
index 000000000..519142c2e
--- /dev/null
+++ b/arch/mips/basler/excite/Makefile
@@ -0,0 +1,9 @@
+#
+# Makefile for Basler eXcite
+#
+
+obj-$(CONFIG_BASLER_EXCITE)	+= excite_irq.o excite_prom.o excite_setup.o \
+				   excite_device.o excite_procfs.o
+
+obj-$(CONFIG_KGDB)		+= excite_dbg_io.o
+obj-m				+= excite_iodev.o
diff --git a/arch/mips/basler/excite/excite_dbg_io.c b/arch/mips/basler/excite/excite_dbg_io.c
new file mode 100644
index 000000000..c04505afa
--- /dev/null
+++ b/arch/mips/basler/excite/excite_dbg_io.c
@@ -0,0 +1,121 @@
+/*
+ *  Copyright (C) 2004 by Basler Vision Technologies AG
+ *  Author: Thomas Koeller <thomas.koeller@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/linkage.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <asm/gdb-stub.h>
+#include <asm/rm9k-ocd.h>
+#include <excite.h>
+
+#if defined(CONFIG_SERIAL_8250) && CONFIG_SERIAL_8250_NR_UARTS > 1
+#error Debug port used by serial driver
+#endif
+
+#define UART_CLK		25000000
+#define BASE_BAUD		(UART_CLK / 16)
+#define REGISTER_BASE_0		0x0208UL
+#define REGISTER_BASE_1		0x0238UL
+
+#define REGISTER_BASE_DBG	REGISTER_BASE_1
+
+#define CPRR	0x0004
+#define UACFG	0x0200
+#define UAINTS	0x0204
+#define UARBR	(REGISTER_BASE_DBG + 0x0000)
+#define UATHR	(REGISTER_BASE_DBG + 0x0004)
+#define UADLL	(REGISTER_BASE_DBG + 0x0008)
+#define UAIER	(REGISTER_BASE_DBG + 0x000c)
+#define UADLH	(REGISTER_BASE_DBG + 0x0010)
+#define UAIIR	(REGISTER_BASE_DBG + 0x0014)
+#define UAFCR	(REGISTER_BASE_DBG + 0x0018)
+#define UALCR	(REGISTER_BASE_DBG + 0x001c)
+#define UAMCR	(REGISTER_BASE_DBG + 0x0020)
+#define UALSR	(REGISTER_BASE_DBG + 0x0024)
+#define UAMSR	(REGISTER_BASE_DBG + 0x0028)
+#define UASCR	(REGISTER_BASE_DBG + 0x002c)
+
+#define	PARITY_NONE	0
+#define	PARITY_ODD	0x08
+#define	PARITY_EVEN	0x18
+#define	PARITY_MARK	0x28
+#define	PARITY_SPACE	0x38
+
+#define	DATA_5BIT	0x0
+#define	DATA_6BIT	0x1
+#define	DATA_7BIT	0x2
+#define	DATA_8BIT	0x3
+
+#define	STOP_1BIT	0x0
+#define	STOP_2BIT	0x4
+
+#define BAUD_DBG	57600
+#define	PARITY_DBG	PARITY_NONE
+#define	DATA_DBG	DATA_8BIT
+#define	STOP_DBG	STOP_1BIT
+
+/* Initialize the serial port for KGDB debugging */
+void __init excite_kgdb_init(void)
+{
+	const u32 divisor = BASE_BAUD / BAUD_DBG;
+
+	/* Take the UART out of reset */
+	titan_writel(0x00ff1cff, CPRR);
+	titan_writel(0x00000000, UACFG);
+	titan_writel(0x00000002, UACFG);
+
+	titan_writel(0x0, UALCR);
+	titan_writel(0x0, UAIER);
+
+	/* Disable FIFOs */
+	titan_writel(0x00, UAFCR);
+
+	titan_writel(0x80, UALCR);
+	titan_writel(divisor & 0xff, UADLL);
+	titan_writel((divisor & 0xff00) >> 8, UADLH);
+	titan_writel(0x0, UALCR);
+
+	titan_writel(DATA_DBG | PARITY_DBG | STOP_DBG, UALCR);
+
+	/* Enable receiver interrupt */
+	titan_readl(UARBR);
+	titan_writel(0x1, UAIER);
+}
+
+int getDebugChar(void)
+{
+	while (!(titan_readl(UALSR) & 0x1));
+	return titan_readl(UARBR);
+}
+
+int putDebugChar(int data)
+{
+	while (!(titan_readl(UALSR) & 0x20));
+	titan_writel(data, UATHR);
+	return 1;
+}
+
+/* KGDB interrupt handler */
+asmlinkage void excite_kgdb_inthdl(struct pt_regs *regs)
+{
+	if (unlikely(
+		((titan_readl(UAIIR) & 0x7) == 4)
+		&& ((titan_readl(UARBR) & 0xff) == 0x3)))
+			set_async_breakpoint(&regs->cp0_epc);
+}
diff --git a/arch/mips/basler/excite/excite_device.c b/arch/mips/basler/excite/excite_device.c
new file mode 100644
index 000000000..bbb4ea43d
--- /dev/null
+++ b/arch/mips/basler/excite/excite_device.c
@@ -0,0 +1,403 @@
+/*
+ *  Copyright (C) 2004 by Basler Vision Technologies AG
+ *  Author: Thomas Koeller <thomas.koeller@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/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/ioport.h>
+#include <linux/err.h>
+#include <linux/jiffies.h>
+#include <linux/sched.h>
+#include <asm/types.h>
+#include <asm/rm9k-ocd.h>
+
+#include <excite.h>
+#include <rm9k_eth.h>
+#include <rm9k_wdt.h>
+#include <rm9k_xicap.h>
+#include <excite_nandflash.h>
+
+#include "excite_iodev.h"
+
+#define RM9K_GE_UNIT	0
+#define XICAP_UNIT	0
+#define NAND_UNIT	0
+
+#define DLL_TIMEOUT	3		/* seconds */
+
+
+#define RINIT(__start__, __end__, __name__, __parent__) {	\
+	.name	= __name__ "_0",				\
+	.start	= (__start__),					\
+	.end	= (__end__),					\
+	.flags	= 0,						\
+	.parent	= (__parent__)					\
+}
+
+#define RINIT_IRQ(__irq__, __name__) {	\
+	.name	= __name__ "_0",	\
+	.start	= (__irq__),		\
+	.end	= (__irq__),		\
+	.flags	= IORESOURCE_IRQ,	\
+	.parent	= NULL			\
+}
+
+
+
+enum {
+	slice_xicap,
+	slice_eth
+};
+
+
+
+static struct resource
+	excite_ctr_resource = {
+		.name		= "GPI counters",
+		.start		= 0,
+		.end		= 5,
+		.flags		= 0,
+		.parent		= NULL,
+		.sibling	= NULL,
+		.child		= NULL
+	},
+	excite_gpislice_resource = {
+		.name		= "GPI slices",
+		.start		= 0,
+		.end		= 1,
+		.flags		= 0,
+		.parent		= NULL,
+		.sibling	= NULL,
+		.child		= NULL
+	},
+	excite_mdio_channel_resource = {
+		.name		= "MDIO channels",
+		.start		= 0,
+		.end		= 1,
+		.flags		= 0,
+		.parent		= NULL,
+		.sibling	= NULL,
+		.child		= NULL
+	},
+	excite_fifomem_resource = {
+		.name		= "FIFO memory",
+		.start		= 0,
+		.end		= 767,
+		.flags		= 0,
+		.parent		= NULL,
+		.sibling	= NULL,
+		.child		= NULL
+	},
+	excite_scram_resource = {
+		.name		= "Scratch RAM",
+		.start		= EXCITE_PHYS_SCRAM,
+		.end		= EXCITE_PHYS_SCRAM + EXCITE_SIZE_SCRAM - 1,
+		.flags		= IORESOURCE_MEM,
+		.parent		= NULL,
+		.sibling	= NULL,
+		.child		= NULL
+	},
+	excite_fpga_resource = {
+		.name		= "System FPGA",
+		.start		= EXCITE_PHYS_FPGA,
+		.end		= EXCITE_PHYS_FPGA + EXCITE_SIZE_FPGA - 1,
+		.flags		= IORESOURCE_MEM,
+		.parent		= NULL,
+		.sibling	= NULL,
+		.child		= NULL
+	},
+	excite_nand_resource = {
+		.name		= "NAND flash control",
+		.start		= EXCITE_PHYS_NAND,
+		.end		= EXCITE_PHYS_NAND + EXCITE_SIZE_NAND - 1,
+		.flags		= IORESOURCE_MEM,
+		.parent		= NULL,
+		.sibling	= NULL,
+		.child		= NULL
+	},
+	excite_titan_resource = {
+		.name		= "TITAN registers",
+		.start		= EXCITE_PHYS_TITAN,
+		.end		= EXCITE_PHYS_TITAN + EXCITE_SIZE_TITAN - 1,
+		.flags		= IORESOURCE_MEM,
+		.parent		= NULL,
+		.sibling	= NULL,
+		.child		= NULL
+	};
+
+
+
+static void adjust_resources(struct resource *res, unsigned int n)
+{
+	struct resource *p;
+	const unsigned long mask = IORESOURCE_IO | IORESOURCE_MEM
+				   | IORESOURCE_IRQ | IORESOURCE_DMA;
+
+	for (p = res; p < res + n; p++) {
+		const struct resource * const parent = p->parent;
+		if (parent) {
+			p->start += parent->start;
+			p->end   += parent->start;
+			p->flags =  parent->flags & mask;
+		}
+	}
+}
+
+
+
+#if defined(CONFIG_EXCITE_FCAP_GPI) || defined(CONFIG_EXCITE_FCAP_GPI_MODULE)
+static struct resource xicap_rsrc[] = {
+	RINIT(0x4840, 0x486f, XICAP_RESOURCE_FIFO_RX, &excite_titan_resource),
+	RINIT(0x4940, 0x494b, XICAP_RESOURCE_FIFO_TX, &excite_titan_resource),
+	RINIT(0x5040, 0x5127, XICAP_RESOURCE_XDMA, &excite_titan_resource),
+	RINIT(0x1000, 0x112f, XICAP_RESOURCE_PKTPROC, &excite_titan_resource),
+	RINIT(0x1100, 0x110f, XICAP_RESOURCE_PKT_STREAM, &excite_fpga_resource),
+	RINIT(0x0800, 0x0bff, XICAP_RESOURCE_DMADESC, &excite_scram_resource),
+	RINIT(slice_xicap, slice_xicap, XICAP_RESOURCE_GPI_SLICE, &excite_gpislice_resource),
+	RINIT(0x0100, 0x02ff, XICAP_RESOURCE_FIFO_BLK, &excite_fifomem_resource),
+	RINIT_IRQ(TITAN_IRQ,  XICAP_RESOURCE_IRQ)
+};
+
+static struct platform_device xicap_pdev = {
+	.name		= XICAP_NAME,
+	.id		= XICAP_UNIT,
+	.num_resources	= ARRAY_SIZE(xicap_rsrc),
+	.resource	= xicap_rsrc
+};
+
+/*
+ * Create a platform device for the GPI port that receives the
+ * image data from the embedded camera.
+ */
+static int __init xicap_devinit(void)
+{
+	unsigned long tend;
+	u32 reg;
+	int retval;
+
+	adjust_resources(xicap_rsrc, ARRAY_SIZE(xicap_rsrc));
+
+	/* Power up the slice and configure it. */
+	reg = titan_readl(CPTC1R);
+	reg &= ~(0x11100 << slice_xicap);
+	titan_writel(reg, CPTC1R);
+
+	/* Enable slice & DLL. */
+	reg= titan_readl(CPRR);
+	reg &= ~(0x00030003 << (slice_xicap * 2));
+	titan_writel(reg, CPRR);
+
+	/* Wait for DLLs to lock */
+	tend = jiffies + DLL_TIMEOUT * HZ;
+	while (time_before(jiffies, tend)) {
+		if (!(~titan_readl(CPDSR) & (0x1 << (slice_xicap * 4))))
+			break;
+		yield();
+	}
+
+	if (~titan_readl(CPDSR) & (0x1 << (slice_xicap * 4))) {
+		printk(KERN_ERR "%s: DLL not locked after %u seconds\n",
+		       xicap_pdev.name, DLL_TIMEOUT);
+		retval = -ETIME;
+	} else {
+		/* Register platform device */
+		retval = platform_device_register(&xicap_pdev);
+	}
+
+	return retval;
+}
+
+device_initcall(xicap_devinit);
+#endif /* defined(CONFIG_EXCITE_FCAP_GPI) || defined(CONFIG_EXCITE_FCAP_GPI_MODULE) */
+
+
+
+#if defined(CONFIG_WDT_RM9K_GPI) || defined(CONFIG_WDT_RM9K_GPI_MODULE)
+static struct resource wdt_rsrc[] = {
+	RINIT(0, 0, WDT_RESOURCE_COUNTER, &excite_ctr_resource),
+	RINIT(0x0084, 0x008f, WDT_RESOURCE_REGS, &excite_titan_resource),
+	RINIT_IRQ(TITAN_IRQ,  WDT_RESOURCE_IRQ)
+};
+
+static struct platform_device wdt_pdev = {
+	.name		= WDT_NAME,
+	.id		= -1,
+	.num_resources	= ARRAY_SIZE(wdt_rsrc),
+	.resource	= wdt_rsrc
+};
+
+/*
+ * Create a platform device for the GPI port that receives the
+ * image data from the embedded camera.
+ */
+static int __init wdt_devinit(void)
+{
+	adjust_resources(wdt_rsrc, ARRAY_SIZE(wdt_rsrc));
+	return platform_device_register(&wdt_pdev);
+}
+
+device_initcall(wdt_devinit);
+#endif /* defined(CONFIG_WDT_RM9K_GPI) || defined(CONFIG_WDT_RM9K_GPI_MODULE) */
+
+
+
+static struct resource excite_nandflash_rsrc[] = {
+ 	RINIT(0x2000, 0x201f, EXCITE_NANDFLASH_RESOURCE_REGS,  &excite_nand_resource)
+};
+
+static struct platform_device excite_nandflash_pdev = {
+	.name		= "excite_nand",
+	.id		= NAND_UNIT,
+	.num_resources	= ARRAY_SIZE(excite_nandflash_rsrc),
+	.resource	= excite_nandflash_rsrc
+};
+
+/*
+ * Create a platform device for the access to the nand-flash
+ * port
+ */
+static int __init excite_nandflash_devinit(void)
+{
+	adjust_resources(excite_nandflash_rsrc, ARRAY_SIZE(excite_nandflash_rsrc));
+
+        /* nothing to be done here */
+
+        /* Register platform device */
+	return platform_device_register(&excite_nandflash_pdev);
+}
+
+device_initcall(excite_nandflash_devinit);
+
+
+
+static struct resource iodev_rsrc[] = {
+	RINIT_IRQ(FPGA1_IRQ,  IODEV_RESOURCE_IRQ)
+};
+
+static struct platform_device io_pdev = {
+	.name		= IODEV_NAME,
+	.id		= -1,
+	.num_resources	= ARRAY_SIZE(iodev_rsrc),
+	.resource	= iodev_rsrc
+};
+
+/*
+ * Create a platform device for the external I/O ports.
+ */
+static int __init io_devinit(void)
+{
+	adjust_resources(iodev_rsrc, ARRAY_SIZE(iodev_rsrc));
+	return platform_device_register(&io_pdev);
+}
+
+device_initcall(io_devinit);
+
+
+
+
+#if defined(CONFIG_RM9K_GE) || defined(CONFIG_RM9K_GE_MODULE)
+static struct resource rm9k_ge_rsrc[] = {
+	RINIT(0x2200, 0x27ff, RM9K_GE_RESOURCE_MAC, &excite_titan_resource),
+	RINIT(0x1800, 0x1fff, RM9K_GE_RESOURCE_MSTAT, &excite_titan_resource),
+	RINIT(0x2000, 0x212f, RM9K_GE_RESOURCE_PKTPROC, &excite_titan_resource),
+	RINIT(0x5140, 0x5227, RM9K_GE_RESOURCE_XDMA, &excite_titan_resource),
+	RINIT(0x4870, 0x489f, RM9K_GE_RESOURCE_FIFO_RX, &excite_titan_resource),
+	RINIT(0x494c, 0x4957, RM9K_GE_RESOURCE_FIFO_TX, &excite_titan_resource),
+	RINIT(0x0000, 0x007f, RM9K_GE_RESOURCE_FIFOMEM_RX, &excite_fifomem_resource),
+	RINIT(0x0080, 0x00ff, RM9K_GE_RESOURCE_FIFOMEM_TX, &excite_fifomem_resource),
+	RINIT(0x0180, 0x019f, RM9K_GE_RESOURCE_PHY, &excite_titan_resource),
+	RINIT(0x0000, 0x03ff, RM9K_GE_RESOURCE_DMADESC_RX, &excite_scram_resource),
+	RINIT(0x0400, 0x07ff, RM9K_GE_RESOURCE_DMADESC_TX, &excite_scram_resource),
+	RINIT(slice_eth, slice_eth, RM9K_GE_RESOURCE_GPI_SLICE, &excite_gpislice_resource),
+	RINIT(0, 0, RM9K_GE_RESOURCE_MDIO_CHANNEL, &excite_mdio_channel_resource),
+	RINIT_IRQ(TITAN_IRQ,  RM9K_GE_RESOURCE_IRQ_MAIN),
+	RINIT_IRQ(PHY_IRQ, RM9K_GE_RESOURCE_IRQ_PHY)
+};
+
+static struct platform_device rm9k_ge_pdev = {
+	.name		= RM9K_GE_NAME,
+	.id		= RM9K_GE_UNIT,
+	.num_resources	= ARRAY_SIZE(rm9k_ge_rsrc),
+	.resource	= rm9k_ge_rsrc
+};
+
+
+
+/*
+ * Create a platform device for the Ethernet port.
+ */
+static int __init rm9k_ge_devinit(void)
+{
+	u32 reg;
+
+	adjust_resources(rm9k_ge_rsrc, ARRAY_SIZE(rm9k_ge_rsrc));
+
+	/* Power up the slice and configure it. */
+	reg = titan_readl(CPTC1R);
+	reg &= ~(0x11000 << slice_eth);
+	reg |= 0x100 << slice_eth;
+	titan_writel(reg, CPTC1R);
+
+	/* Take the MAC out of reset, reset the DLLs. */
+	reg = titan_readl(CPRR);
+	reg &= ~(0x00030000 << (slice_eth * 2));
+	reg |= 0x3 << (slice_eth * 2);
+	titan_writel(reg, CPRR);
+
+	return platform_device_register(&rm9k_ge_pdev);
+}
+
+device_initcall(rm9k_ge_devinit);
+#endif /* defined(CONFIG_RM9K_GE) || defined(CONFIG_RM9K_GE_MODULE) */
+
+
+
+static int __init excite_setup_devs(void)
+{
+	int res;
+	u32 reg;
+
+	/* Enable xdma and fifo interrupts */
+	reg = titan_readl(0x0050);
+	titan_writel(reg | 0x18000000, 0x0050);
+
+	res = request_resource(&iomem_resource, &excite_titan_resource);
+	if (res)
+		return res;
+	res = request_resource(&iomem_resource, &excite_scram_resource);
+	if (res)
+		return res;
+	res = request_resource(&iomem_resource, &excite_fpga_resource);
+	if (res)
+		return res;
+	res = request_resource(&iomem_resource, &excite_nand_resource);
+	if (res)
+		return res;
+	excite_fpga_resource.flags = excite_fpga_resource.parent->flags &
+				   ( IORESOURCE_IO | IORESOURCE_MEM
+				   | IORESOURCE_IRQ | IORESOURCE_DMA);
+	excite_nand_resource.flags = excite_nand_resource.parent->flags &
+				   ( IORESOURCE_IO | IORESOURCE_MEM
+				   | IORESOURCE_IRQ | IORESOURCE_DMA);
+
+	return 0;
+}
+
+arch_initcall(excite_setup_devs);
+
diff --git a/arch/mips/basler/excite/excite_flashtest.c b/arch/mips/basler/excite/excite_flashtest.c
new file mode 100644
index 000000000..f0024a8e3
--- /dev/null
+++ b/arch/mips/basler/excite/excite_flashtest.c
@@ -0,0 +1,294 @@
+/*
+*  Copyright (C) 2005 by Basler Vision Technologies AG
+*  Author: 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/device.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/kernel.h>
+
+#include <excite.h>
+
+#include <asm/io.h>
+
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/nand_ecc.h>
+#include <linux/mtd/partitions.h>
+#include <asm/rm9k-ocd.h> // for ocd_write
+#include <linux/workqueue.h> // for queue
+
+#include "excite_nandflash.h"
+#include "nandflash.h"
+
+#define PFX "excite flashtest: "
+typedef void __iomem *io_reg_t;
+
+#define io_readb(__a__)		__raw_readb((__a__))
+#define io_writeb(__v__, __a__)	__raw_writeb((__v__), (__a__))
+
+
+
+static inline const struct resource *excite_nandflash_get_resource(
+	struct platform_device *d, unsigned long flags, const char *basename)
+{
+	const char fmt[] = "%s_%u";
+	char buf[80];
+
+	if (unlikely(snprintf(buf, sizeof buf, fmt, basename, d->id) >= sizeof buf))
+		return NULL;
+
+	return platform_get_resource_byname(d, flags, buf);
+}
+
+static inline io_reg_t
+excite_nandflash_map_regs(struct platform_device *d, const char *basename)
+{
+	void *result = NULL;
+	const struct resource *const r =
+	    excite_nandflash_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_nandflash_drvdata {
+	struct mtd_info board_mtd;
+	struct nand_chip board_chip;
+	io_reg_t regs;
+};
+
+
+/* command and control functions */
+static void excite_nandflash_hwcontrol(struct mtd_info *mtd, int cmd)
+{
+	struct nand_chip *this = mtd->priv;
+	io_reg_t regs = container_of(mtd,struct excite_nandflash_drvdata,board_mtd)->regs;
+
+	switch (cmd) {
+	/* Select the command latch */
+	case NAND_CTL_SETCLE: this->IO_ADDR_W = regs + EXCITE_NANDFLASH_CMD;
+		break;
+	/* Deselect the command latch */
+	case NAND_CTL_CLRCLE: this->IO_ADDR_W = regs + EXCITE_NANDFLASH_DATA;
+		break;
+	/* Select the address latch */
+	case NAND_CTL_SETALE: this->IO_ADDR_W = regs + EXCITE_NANDFLASH_ADDR;
+		break;
+	/* Deselect the address latch */
+	case NAND_CTL_CLRALE: this->IO_ADDR_W = regs  + EXCITE_NANDFLASH_DATA;
+		break;
+	/* Select the chip  -- not used */
+	case NAND_CTL_SETNCE:
+		break;
+	/* Deselect the chip -- not used */
+	case NAND_CTL_CLRNCE:
+		break;
+	}
+
+	this->IO_ADDR_R = this->IO_ADDR_W;
+}
+
+/* excite_nandflash_devready()
+ *
+ * returns 0 if the nand is busy, 1 if it is ready
+ */
+static int excite_nandflash_devready(struct mtd_info *mtd)
+{
+	struct excite_nandflash_drvdata *drvdata =
+	    container_of(mtd, struct excite_nandflash_drvdata, board_mtd);
+
+	return io_readb(drvdata->regs + EXCITE_NANDFLASH_STATUS);
+}
+
+/* device management functions */
+
+/* excite_nandflash_remove
+ *
+ * called by device layer to remove the driver
+ * the binding to the mtd and all allocated
+ * resources are released
+ */
+static int excite_nandflash_remove(struct device *dev)
+{
+	struct excite_nandflash_drvdata *this = dev_get_drvdata(dev);
+
+	pr_info(PFX "remove");
+
+	dev_set_drvdata(dev, NULL);
+
+	if (this == NULL) {
+		pr_debug(PFX "call remove without private data!!");
+		return 0;
+	}
+
+
+	/* free the common resources */
+	if (this->regs != NULL) {
+		iounmap(this->regs);
+		this->regs = NULL;
+	}
+
+	kfree(this);
+
+	return 0;
+}
+
+static int elapsed;
+
+void my_workqueue_handler(void *arg)
+{
+	elapsed = 1;
+}
+
+DECLARE_WORK(sigElapsed, my_workqueue_handler, 0);
+
+
+/* excite_nandflash_probe
+ *
+ * called by device layer when it finds a device matching
+ * one our driver can handled. This code checks to see if
+ * it can allocate all necessary resources then calls the
+ * nand layer to look for devices
+*/
+static int excite_nandflash_probe(struct device *dev)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+
+	struct excite_nandflash_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 err      = 0;
+	int count    = 0;
+	struct timeval tv,endtv;
+	unsigned int dt;
+
+	pr_info(PFX "probe dev: (%p)\n", dev);
+
+	pr_info(PFX "adjust LB timing\n");
+	ocd_writel(0x00000330, LDP2);
+
+	drvdata = kmalloc(sizeof(*drvdata), GFP_KERNEL);
+	if (unlikely(!drvdata)) {
+		printk(KERN_ERR PFX "no memory for drvdata\n");
+		err = -ENOMEM;
+		goto mem_error;
+	}
+
+	/* Initialize structures */
+	memset(drvdata, 0, sizeof(*drvdata));
+
+	/* bind private data into driver */
+	dev_set_drvdata(dev, drvdata);
+
+	/* allocate and map the resource */
+	drvdata->regs =
+	    excite_nandflash_map_regs(pdev, EXCITE_NANDFLASH_RESOURCE_REGS);
+
+	if (unlikely(!drvdata->regs)) {
+		printk(KERN_ERR PFX "cannot reserve register region\n");
+		err = -ENXIO;
+		goto io_error;
+	}
+
+	/* initialise our chip */
+	board_chip = &drvdata->board_chip;
+
+	board_chip->IO_ADDR_R = drvdata->regs + EXCITE_NANDFLASH_DATA;
+	board_chip->IO_ADDR_W = drvdata->regs + EXCITE_NANDFLASH_DATA;
+
+	board_chip->hwcontrol = excite_nandflash_hwcontrol;
+	board_chip->dev_ready = excite_nandflash_devready;
+
+	board_chip->chip_delay = 25;
+	#if 0
+	/* TODO: speedup the initial scan */
+	board_chip->options = NAND_USE_FLASH_BBT;
+	#endif
+	board_chip->eccmode = NAND_ECC_SOFT;
+
+	/* link chip to mtd */
+	board_mtd = &drvdata->board_mtd;
+	board_mtd->priv = board_chip;
+
+
+	pr_info(PFX "FlashTest\n");
+	elapsed = 0;
+/*	schedule_delayed_work(&sigElapsed, 1*HZ);
+	while (!elapsed) {
+		io_readb(drvdata->regs + EXCITE_NANDFLASH_STATUS);
+		count++;
+	}
+	pr_info(PFX "reads in 1 sec --> %d\n",count);
+*/
+	do_gettimeofday(&tv);
+	for (count = 0 ; count < 1000000; count ++) {
+		io_readb(drvdata->regs + EXCITE_NANDFLASH_STATUS);
+	}
+	do_gettimeofday(&endtv);
+	dt = (endtv.tv_sec - tv.tv_sec) * 1000000 + endtv.tv_usec  - tv.tv_usec;
+	pr_info(PFX "%8d us timeval\n",dt);
+	pr_info(PFX "EndFlashTest\n");
+
+/*      return with error to unload everything
+*/
+io_error:
+	iounmap(drvdata->regs);
+
+mem_error:
+	kfree(drvdata);
+
+	if (err == 0)
+		err = -EINVAL;
+	return err;
+}
+
+static struct device_driver excite_nandflash_driver = {
+	.name = "excite_nand",
+	.bus = &platform_bus_type,
+	.probe = excite_nandflash_probe,
+	.remove = excite_nandflash_remove,
+};
+
+static int __init excite_nandflash_init(void)
+{
+	pr_info(PFX "register Driver (Rev: $Revision:$)\n");
+	return driver_register(&excite_nandflash_driver);
+}
+
+static void __exit excite_nandflash_exit(void)
+{
+	driver_unregister(&excite_nandflash_driver);
+	pr_info(PFX "Driver unregistered");
+}
+
+module_init(excite_nandflash_init);
+module_exit(excite_nandflash_exit);
+
+MODULE_AUTHOR("Thies Moeller <thies.moeller@baslerweb.com>");
+MODULE_DESCRIPTION("Basler eXcite NAND-Flash driver");
+MODULE_LICENSE("GPL");
diff --git a/arch/mips/basler/excite/excite_fpga.h b/arch/mips/basler/excite/excite_fpga.h
new file mode 100644
index 000000000..38fcda703
--- /dev/null
+++ b/arch/mips/basler/excite/excite_fpga.h
@@ -0,0 +1,80 @@
+#ifndef EXCITE_FPGA_H_INCLUDED
+#define EXCITE_FPGA_H_INCLUDED
+
+
+/**
+ * Adress alignment of the individual FPGA bytes.
+ * The address arrangement of the individual bytes of the FPGA is two
+ * byte aligned at the embedded MK2 platform.
+ */
+#ifdef EXCITE_CCI_FPGA_MK2
+typedef unsigned char excite_cci_fpga_align_t __attribute__ ((aligned(2)));
+#else
+typedef unsigned char excite_cci_fpga_align_t;
+#endif
+
+
+/**
+ * Size of Dual Ported RAM.
+ */
+#define EXCITE_DPR_SIZE 263
+
+
+/**
+ * Size of Reserved Status Fields in Dual Ported RAM.
+ */
+#define EXCITE_DPR_STATUS_SIZE 7
+
+
+
+/**
+ * FPGA.
+ * Hardware register layout of the FPGA interface. The FPGA must accessed
+ * byte wise solely.
+ * @see EXCITE_CCI_DPR_MK2
+ */
+typedef struct excite_fpga {
+
+	/**
+	 * Dual Ported RAM.
+	 */
+	excite_cci_fpga_align_t dpr[EXCITE_DPR_SIZE];
+
+	/**
+	 * Status.
+	 */
+	excite_cci_fpga_align_t status[EXCITE_DPR_STATUS_SIZE];
+
+#ifdef EXCITE_CCI_FPGA_MK2
+	/**
+	 * RM9000 Interrupt.
+	 * Write access initiates interrupt at the RM9000 (MIPS) processor of the eXcite.
+	 */
+	excite_cci_fpga_align_t rm9k_int;
+#else
+	/**
+	 * MK2 Interrupt.
+	 * Write access initiates interrupt at the ARM processor of the MK2.
+	 */
+	excite_cci_fpga_align_t mk2_int;
+
+	excite_cci_fpga_align_t gap[0x1000-0x10f];
+
+	/**
+	 * IRQ Source/Acknowledge.
+	 */
+	excite_cci_fpga_align_t rm9k_irq_src;
+
+	/**
+	 * IRQ Mask.
+	 * Set bits enable the related interrupt.
+	 */
+	excite_cci_fpga_align_t rm9k_irq_mask;
+#endif
+
+
+} excite_fpga;
+
+
+
+#endif	/* ndef EXCITE_FPGA_H_INCLUDED */
diff --git a/arch/mips/basler/excite/excite_iodev.c b/arch/mips/basler/excite/excite_iodev.c
new file mode 100644
index 000000000..10bbb8cfb
--- /dev/null
+++ b/arch/mips/basler/excite/excite_iodev.c
@@ -0,0 +1,182 @@
+/*
+ *  Copyright (C) 2005 by Basler Vision Technologies AG
+ *  Author: Thomas Koeller <thomas.koeller@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/compiler.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/wait.h>
+#include <linux/poll.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <linux/miscdevice.h>
+
+#include "excite_iodev.h"
+
+
+
+static const struct resource *iodev_get_resource(struct platform_device *, const char *, unsigned int);
+static int __init iodev_probe(struct device *);
+static int __exit iodev_remove(struct device *);
+static int iodev_open(struct inode *, struct file *);
+static int iodev_release(struct inode *, struct file *);
+static ssize_t iodev_read(struct file *, char __user *, size_t s, loff_t *);
+static unsigned int iodev_poll(struct file *, struct poll_table_struct *);
+static irqreturn_t iodev_irqhdl(int, void *, struct pt_regs *);
+
+
+
+static const char iodev_name[] = "iodev";
+static unsigned int iodev_irq;
+static DECLARE_WAIT_QUEUE_HEAD(wq);
+
+
+
+static struct file_operations fops =
+{
+	.owner		= THIS_MODULE,
+	.open		= iodev_open,
+	.release	= iodev_release,
+	.read		= iodev_read,
+	.poll		= iodev_poll
+};
+
+static struct miscdevice miscdev =
+{
+	.minor		= MISC_DYNAMIC_MINOR,
+	.name		= iodev_name,
+	.fops		= &fops
+};
+
+static struct device_driver iodev_driver =
+{
+	.name		= (char *) iodev_name,
+	.bus		= &platform_bus_type,
+	.owner		= THIS_MODULE,
+	.probe		= iodev_probe,
+	.remove		= __exit_p(iodev_remove)
+};
+
+
+
+static const struct resource *
+iodev_get_resource(struct platform_device *pdv, const char *name,
+		     unsigned int type)
+{
+	char buf[80];
+	if (snprintf(buf, sizeof buf, "%s_0", name) >= sizeof buf)
+		return NULL;
+	return platform_get_resource_byname(pdv, type, buf);
+}
+
+
+
+/* No hotplugging on the platform bus - use __init */
+static int __init iodev_probe(struct device *dev)
+{
+	struct platform_device * const pdv = to_platform_device(dev);
+	const struct resource * const ri =
+		iodev_get_resource(pdv, IODEV_RESOURCE_IRQ, IORESOURCE_IRQ);
+
+	if (unlikely(!ri))
+		return -ENXIO;
+
+	iodev_irq = ri->start;
+	return misc_register(&miscdev);
+}
+
+
+
+static int __exit iodev_remove(struct device *dev)
+{
+	return misc_deregister(&miscdev);
+}
+
+
+
+static int iodev_open(struct inode *i, struct file *f)
+{
+	return request_irq(iodev_irq, iodev_irqhdl, IRQF_DISABLED,
+			   iodev_name, &miscdev);
+}
+
+
+
+static int iodev_release(struct inode *i, struct file *f)
+{
+	free_irq(iodev_irq, &miscdev);
+	return 0;
+}
+
+
+
+
+static ssize_t
+iodev_read(struct file *f, char __user *d, size_t s, loff_t *o)
+{
+	ssize_t ret;
+	DEFINE_WAIT(w);
+
+	prepare_to_wait(&wq, &w, TASK_INTERRUPTIBLE);
+	if (!signal_pending(current))
+		schedule();
+	ret = signal_pending(current) ? -ERESTARTSYS : 0;
+	finish_wait(&wq, &w);
+	return ret;
+}
+
+
+static unsigned int iodev_poll(struct file *f, struct poll_table_struct *p)
+{
+	poll_wait(f, &wq, p);
+	return POLLOUT | POLLWRNORM;
+}
+
+
+
+
+static irqreturn_t iodev_irqhdl(int irq, void *ctxt, struct pt_regs *regs)
+{
+	wake_up(&wq);
+	return IRQ_HANDLED;
+}
+
+
+
+static int __init iodev_init_module(void)
+{
+	return driver_register(&iodev_driver);
+}
+
+
+
+static void __exit iodev_cleanup_module(void)
+{
+	driver_unregister(&iodev_driver);
+}
+
+module_init(iodev_init_module);
+module_exit(iodev_cleanup_module);
+
+
+
+MODULE_AUTHOR("Thomas Koeller <thomas.koeller@baslerweb.com>");
+MODULE_DESCRIPTION("Basler eXcite i/o interrupt handler");
+MODULE_VERSION("0.0");
+MODULE_LICENSE("GPL");
diff --git a/arch/mips/basler/excite/excite_iodev.h b/arch/mips/basler/excite/excite_iodev.h
new file mode 100644
index 000000000..cbfbb5d2e
--- /dev/null
+++ b/arch/mips/basler/excite/excite_iodev.h
@@ -0,0 +1,10 @@
+#ifndef __EXCITE_IODEV_H__
+#define __EXCITE_IODEV_H__
+
+/* Device name */
+#define IODEV_NAME		"iodev"
+
+/* Resource names */
+#define IODEV_RESOURCE_IRQ	"excite_iodev_irq"
+
+#endif /* __EXCITE_IODEV_H__ */
diff --git a/arch/mips/basler/excite/excite_irq.c b/arch/mips/basler/excite/excite_irq.c
new file mode 100644
index 000000000..511ad8730
--- /dev/null
+++ b/arch/mips/basler/excite/excite_irq.c
@@ -0,0 +1,129 @@
+/*
+ *  Copyright (C) by Basler Vision Technologies AG
+ *  Author: Thomas Koeller <thomas.koeller@baslereb.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/errno.h>
+#include <linux/init.h>
+#include <linux/kernel_stat.h>
+#include <linux/module.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/timex.h>
+#include <linux/slab.h>
+#include <linux/random.h>
+#include <asm/bitops.h>
+#include <asm/bootinfo.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/irq_cpu.h>
+#include <asm/mipsregs.h>
+#include <asm/system.h>
+#include <asm/rm9k-ocd.h>
+
+#include <excite.h>
+
+extern asmlinkage void excite_handle_int(void);
+
+/*
+ * Initialize the interrupt handler
+ */
+void __init arch_init_irq(void)
+{
+	mips_cpu_irq_init(0);
+	rm7k_cpu_irq_init(8);
+	rm9k_cpu_irq_init(12);
+
+#ifdef CONFIG_KGDB
+	excite_kgdb_init();
+#endif
+}
+
+asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
+{
+	const u32
+		interrupts = read_c0_cause() >> 8,
+		mask = ((read_c0_status() >> 8) & 0x000000ff) |
+		       (read_c0_intcontrol() & 0x0000ff00),
+		pending = interrupts & mask;
+	u32 msgintflags, msgintmask, msgint;
+
+	/* process timer interrupt */
+	if (pending & (1 << TIMER_IRQ)) {
+		do_IRQ(TIMER_IRQ, regs);
+		return;
+	}
+
+	/* Process PCI interrupts */
+#if USB_IRQ < 10
+	msgintflags = ocd_readl(INTP0Status0 + (USB_MSGINT / 0x20 * 0x10));
+	msgintmask  = ocd_readl(INTP0Mask0 + (USB_MSGINT / 0x20 * 0x10));
+	msgint	    = msgintflags & msgintmask & (0x1 << (USB_MSGINT % 0x20));
+	if ((pending & (1 << USB_IRQ)) && msgint) {
+#else
+	if (pending & (1 << USB_IRQ)) {
+#endif
+		do_IRQ(USB_IRQ, regs);
+		return;
+	}
+
+	/* Process TITAN interrupts */
+	msgintflags = ocd_readl(INTP0Status0 + (TITAN_MSGINT / 0x20 * 0x10));
+	msgintmask  = ocd_readl(INTP0Mask0 + (TITAN_MSGINT / 0x20 * 0x10));
+	msgint	    = msgintflags & msgintmask & (0x1 << (TITAN_MSGINT % 0x20));
+	if ((pending & (1 << TITAN_IRQ)) && msgint) {
+		ocd_writel(msgint, INTP0Clear0 + (TITAN_MSGINT / 0x20 * 0x10));
+#if defined(CONFIG_KGDB)
+		excite_kgdb_inthdl(regs);
+#endif
+		do_IRQ(TITAN_IRQ, regs);
+		return;
+	}
+
+	/* Process FPGA line #0 interrupts */
+	msgintflags = ocd_readl(INTP0Status0 + (FPGA0_MSGINT / 0x20 * 0x10));
+	msgintmask  = ocd_readl(INTP0Mask0 + (FPGA0_MSGINT / 0x20 * 0x10));
+	msgint	    = msgintflags & msgintmask & (0x1 << (FPGA0_MSGINT % 0x20));
+	if ((pending & (1 << FPGA0_IRQ)) && msgint) {
+		do_IRQ(FPGA0_IRQ, regs);
+		return;
+	}
+
+	/* Process FPGA line #1 interrupts */
+	msgintflags = ocd_readl(INTP0Status0 + (FPGA1_MSGINT / 0x20 * 0x10));
+	msgintmask  = ocd_readl(INTP0Mask0 + (FPGA1_MSGINT / 0x20 * 0x10));
+	msgint	    = msgintflags & msgintmask & (0x1 << (FPGA1_MSGINT % 0x20));
+	if ((pending & (1 << FPGA1_IRQ)) && msgint) {
+		do_IRQ(FPGA1_IRQ, regs);
+		return;
+	}
+
+	/* Process PHY interrupts */
+	msgintflags = ocd_readl(INTP0Status0 + (PHY_MSGINT / 0x20 * 0x10));
+	msgintmask  = ocd_readl(INTP0Mask0 + (PHY_MSGINT / 0x20 * 0x10));
+	msgint	    = msgintflags & msgintmask & (0x1 << (PHY_MSGINT % 0x20));
+	if ((pending & (1 << PHY_IRQ)) && msgint) {
+		do_IRQ(PHY_IRQ, regs);
+		return;
+	}
+
+	/* Process spurious interrupts */
+	spurious_interrupt(regs);
+}
diff --git a/arch/mips/basler/excite/excite_procfs.c b/arch/mips/basler/excite/excite_procfs.c
new file mode 100644
index 000000000..9ee67a95f
--- /dev/null
+++ b/arch/mips/basler/excite/excite_procfs.c
@@ -0,0 +1,80 @@
+/*
+ *  Copyright (C) 2004, 2005 by Basler Vision Technologies AG
+ *  Author: Thomas Koeller <thomas.koeller@baslerweb.com>
+ *
+ *  Procfs support for Basler eXcite
+ *
+ *  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/proc_fs.h>
+#include <linux/stat.h>
+#include <asm/page.h>
+#include <asm/io.h>
+#include <asm/system.h>
+#include <asm/rm9k-ocd.h>
+
+#include <excite.h>
+
+static int excite_get_unit_id(char *buf, char **addr, off_t offs, int size)
+{
+	const int len = snprintf(buf, PAGE_SIZE, "%06x", unit_id);
+	const int w = len - offs;
+	*addr = buf + offs;
+	return w < size ? w : size;
+}
+
+static int
+excite_bootrom_read(char *page, char **start, off_t off, int count,
+		  int *eof, void *data)
+{
+	void __iomem * src;
+
+	if (off >= EXCITE_SIZE_BOOTROM) {
+		*eof = 1;
+		return 0;
+	}
+
+	if ((off + count) > EXCITE_SIZE_BOOTROM)
+		count = EXCITE_SIZE_BOOTROM - off;
+
+	src = ioremap(EXCITE_PHYS_BOOTROM + off, count);
+	if (src) {
+		memcpy_fromio(page, src, count);
+		iounmap(src);
+		*start = page;
+	} else {
+		count = -ENOMEM;
+	}
+
+	return count;
+}
+
+void excite_procfs_init(void)
+{
+	/* Create & populate /proc/excite */
+	struct proc_dir_entry * const pdir = proc_mkdir("excite", &proc_root);
+	if (pdir) {
+		struct proc_dir_entry * e;
+
+		e = create_proc_info_entry("unit_id", S_IRUGO, pdir,
+					   excite_get_unit_id);
+		if (e) e->size = 6;
+
+		e = create_proc_read_entry("bootrom", S_IRUGO, pdir,
+					   excite_bootrom_read, NULL);
+		if (e) e->size = EXCITE_SIZE_BOOTROM;
+	}
+}
diff --git a/arch/mips/basler/excite/excite_prom.c b/arch/mips/basler/excite/excite_prom.c
new file mode 100644
index 000000000..6ecd512b9
--- /dev/null
+++ b/arch/mips/basler/excite/excite_prom.c
@@ -0,0 +1,147 @@
+/*
+ *  Copyright (C) 2004, 2005 by Thomas Koeller (thomas.koeller@baslerweb.com)
+ *  Based on the PMC-Sierra Yosemite board support by Ralf Baechle and
+ *  Manish Lachwani.
+ *
+ *  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/sched.h>
+#include <linux/mm.h>
+#include <linux/delay.h>
+#include <linux/smp.h>
+#include <linux/module.h>
+#include <asm/io.h>
+#include <asm/pgtable.h>
+#include <asm/processor.h>
+#include <asm/reboot.h>
+#include <asm/system.h>
+#include <asm/bootinfo.h>
+#include <asm/string.h>
+
+#include <excite.h>
+
+/* This struct is used by Redboot to pass arguments to the kernel */
+typedef struct
+{
+	char *name;
+	char *val;
+} t_env_var;
+
+struct parmblock {
+	t_env_var memsize;
+	t_env_var modetty0;
+	t_env_var ethaddr;
+	t_env_var env_end;
+	char *argv[2];
+	char text[0];
+};
+
+static unsigned int prom_argc;
+static const char ** prom_argv;
+static const t_env_var * prom_env;
+
+static void prom_halt(void) __attribute__((noreturn));
+static void prom_exit(void) __attribute__((noreturn));
+
+
+
+const char *get_system_type(void)
+{
+	return "Basler eXcite";
+}
+
+/*
+ * Halt the system
+ */
+static void prom_halt(void)
+{
+	printk(KERN_NOTICE "\n** System halted.\n");
+	while (1)
+		asm volatile (
+			"\t.set\tmips3\n"
+			"\twait\n"
+			"\t.set\tmips0\n"
+		);
+}
+
+/*
+ * Reset the CPU and re-enter Redboot
+ */
+static void prom_exit(void)
+{
+	unsigned int i;
+	volatile unsigned char * const flg =
+		(volatile unsigned char *) (EXCITE_ADDR_FPGA + EXCITE_FPGA_DPR);
+
+	/* Clear the watchdog reset flag, set the reboot flag */
+	*flg &= ~0x01;
+	*flg |= 0x80;
+
+	for (i = 0; i < 10; i++) {
+		*(volatile unsigned char *)  (EXCITE_ADDR_FPGA + EXCITE_FPGA_SYSCTL) = 0x02;
+		iob();
+		mdelay(1000);
+	}
+
+	printk(KERN_NOTICE "Reset failed\n");
+	prom_halt();
+}
+
+static const char __init *prom_getenv(char *name)
+{
+	const t_env_var * p;
+	for (p = prom_env; p->name != NULL; p++)
+		if(strcmp(name, p->name) == 0)
+			break;
+	return p->val;
+}
+
+/*
+ * Init routine which accepts the variables from Redboot
+ */
+void __init prom_init(void)
+{
+	const struct parmblock * const pb = (struct parmblock *) fw_arg2;
+
+	prom_argc = fw_arg0;
+	prom_argv = (const char **) fw_arg1;
+	prom_env = &pb->memsize;
+
+	/* Callbacks for halt, restart */
+	_machine_restart = (void (*)(char *)) prom_exit;
+	_machine_halt = prom_halt;
+
+#ifdef CONFIG_32BIT
+	/* copy command line */
+	strcpy(arcs_cmdline, prom_argv[1]);
+	memsize = simple_strtol(prom_getenv("memsize"), NULL, 16);
+	strcpy(modetty, prom_getenv("modetty0"));
+#endif /* CONFIG_32BIT */
+
+#ifdef CONFIG_64BIT
+#	error 64 bit support not implemented
+#endif /* CONFIG_64BIT */
+
+	mips_machgroup = MACH_GROUP_TITAN;
+	mips_machtype = MACH_TITAN_EXCITE;
+}
+
+/* This is called from free_initmem(), so we need to provide it */
+void __init prom_free_prom_memory(void)
+{
+	/* Nothing to do */
+}
diff --git a/arch/mips/basler/excite/excite_setup.c b/arch/mips/basler/excite/excite_setup.c
new file mode 100644
index 000000000..a1ce45800
--- /dev/null
+++ b/arch/mips/basler/excite/excite_setup.c
@@ -0,0 +1,305 @@
+/*
+ *  Copyright (C) 2004, 2005 by Basler Vision Technologies AG
+ *  Author: Thomas Koeller <thomas.koeller@baslerweb.com>
+ *  Based on the PMC-Sierra Yosemite board support by Ralf Baechle and
+ *  Manish Lachwani.
+ *
+ *  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/types.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/tty.h>
+#include <linux/serial_core.h>
+#include <linux/serial.h>
+#include <linux/ioport.h>
+#include <linux/spinlock.h>
+#include <asm/bootinfo.h>
+#include <asm/mipsregs.h>
+#include <asm/pgtable-32.h>
+#include <asm/io.h>
+#include <asm/time.h>
+#include <asm/rm9k-ocd.h>
+
+#include <excite.h>
+
+#define TITAN_UART_CLK	25000000
+
+#if 1
+/* normal serial port assignment */
+#define REGBASE_SER0	0x0208
+#define REGBASE_SER1	0x0238
+#define MASK_SER0	0x1
+#define MASK_SER1	0x2
+#else
+/* serial ports swapped */
+#define REGBASE_SER0	0x0238
+#define REGBASE_SER1	0x0208
+#define MASK_SER0	0x2
+#define MASK_SER1	0x1
+#endif
+
+unsigned long memsize;
+char modetty[30];
+unsigned int titan_irq = TITAN_IRQ;
+static void __iomem * ctl_regs;
+u32 unit_id;
+
+volatile void __iomem * const ocd_base = (void *) (EXCITE_ADDR_OCD);
+volatile void __iomem * const titan_base = (void *) (EXCITE_ADDR_TITAN);
+
+/* Protect access to shared GPI registers */
+spinlock_t titan_lock = SPIN_LOCK_UNLOCKED;
+int titan_irqflags;
+
+
+static void excite_timer_init(void)
+{
+	const u32 modebit5 = ocd_readl(0x00e4);
+	unsigned int
+		mult = ((modebit5 >> 11) & 0x1f) + 2,
+		div = ((modebit5 >> 16) & 0x1f) + 2;
+
+	if (div == 33) div = 1;
+	mips_hpt_frequency = EXCITE_CPU_EXT_CLOCK * mult / div / 2;
+}
+
+void __init plat_timer_setup(struct irqaction *irq)
+{
+	/* The eXcite platform uses the alternate timer interrupt */
+	set_c0_intcontrol(0x80);
+	setup_irq(TIMER_IRQ, irq);
+}
+
+static int __init excite_init_console(void)
+{
+#if defined(CONFIG_SERIAL_8250)
+	static __initdata char serr[] =
+		KERN_ERR "Serial port #%u setup failed\n";
+	struct uart_port up;
+
+	/* Take the DUART out of reset */
+	titan_writel(0x00ff1cff, CPRR);
+
+#if defined(CONFIG_KGDB) || (CONFIG_SERIAL_8250_NR_UARTS > 1)
+	/* Enable both ports */
+	titan_writel(MASK_SER0 | MASK_SER1, UACFG);
+#else
+	/* Enable port #0 only */
+	titan_writel(MASK_SER0, UACFG);
+#endif	/* defined(CONFIG_KGDB) */
+
+ 	/*
+	 * Set up serial port #0. Do not use autodetection; the result is
+	 * not what we want.
+ 	 */
+	memset(&up, 0, sizeof(up));
+	up.membase	= (char *) titan_addr(REGBASE_SER0);
+	up.irq		= TITAN_IRQ;
+	up.uartclk	= TITAN_UART_CLK;
+	up.regshift	= 0;
+	up.iotype	= UPIO_MEM32;
+	up.type		= PORT_RM9000;
+	up.flags	= UPF_SHARE_IRQ;
+	up.line		= 0;
+	if (early_serial_setup(&up))
+		printk(serr, up.line);
+
+#if CONFIG_SERIAL_8250_NR_UARTS > 1
+	/* And now for port #1. */
+	up.membase	= (char *) titan_addr(REGBASE_SER1);
+	up.line		= 1;
+ 	if (early_serial_setup(&up))
+		printk(serr, up.line);
+#endif /* CONFIG_SERIAL_8250_NR_UARTS > 1 */
+#else
+	/* Leave the DUART in reset */
+	titan_writel(0x00ff3cff, CPRR);
+#endif  /* defined(CONFIG_SERIAL_8250) */
+
+	return 0;
+}
+
+static int __init excite_platform_init(void)
+{
+	unsigned int i;
+	unsigned char buf[3];
+	u8 reg;
+	void __iomem * dpr;
+
+	/* BIU buffer allocations */
+	ocd_writel(8, CPURSLMT);	/* CPU */
+	titan_writel(4, CPGRWL);	/* GPI / Ethernet */
+
+	/* Map control registers located in FPGA */
+	ctl_regs = ioremap_nocache(EXCITE_PHYS_FPGA + EXCITE_FPGA_SYSCTL, 16);
+	if (!ctl_regs)
+		panic("eXcite: failed to map platform control registers\n");
+	memcpy_fromio(buf, ctl_regs + 2, ARRAY_SIZE(buf));
+	unit_id = buf[0] | (buf[1] << 8) | (buf[2] << 16);
+
+	/* Clear the reboot flag */
+	dpr = ioremap_nocache(EXCITE_PHYS_FPGA + EXCITE_FPGA_DPR, 1);
+	reg = __raw_readb(dpr);
+	__raw_writeb(reg & 0x7f, dpr);
+	iounmap(dpr);
+
+	/* Interrupt controller setup */
+	for (i = INTP0Status0; i < INTP0Status0 + 0x80; i += 0x10) {
+		ocd_writel(0x00000000, i + 0x04);
+		ocd_writel(0xffffffff, i + 0x0c);
+	}
+	ocd_writel(0x2, NMICONFIG);
+
+	ocd_writel(0x1 << (TITAN_MSGINT % 0x20),
+		   INTP0Mask0 + (0x10 * (TITAN_MSGINT / 0x20)));
+	ocd_writel((0x1 << (FPGA0_MSGINT % 0x20))
+		   | ocd_readl(INTP0Mask0 + (0x10 * (FPGA0_MSGINT / 0x20))),
+		   INTP0Mask0 + (0x10 * (FPGA0_MSGINT / 0x20)));
+	ocd_writel((0x1 << (FPGA1_MSGINT % 0x20))
+		   | ocd_readl(INTP0Mask0 + (0x10 * (FPGA1_MSGINT / 0x20))),
+		   INTP0Mask0 + (0x10 * (FPGA1_MSGINT / 0x20)));
+	ocd_writel((0x1 << (PHY_MSGINT % 0x20))
+		   | ocd_readl(INTP0Mask0 + (0x10 * (PHY_MSGINT / 0x20))),
+		   INTP0Mask0 + (0x10 * (PHY_MSGINT / 0x20)));
+#if USB_IRQ < 10
+	ocd_writel((0x1 << (USB_MSGINT % 0x20))
+		   | ocd_readl(INTP0Mask0 + (0x10 * (USB_MSGINT / 0x20))),
+		   INTP0Mask0 + (0x10 * (USB_MSGINT / 0x20)));
+#endif
+	/* Enable the packet FIFO, XDMA and XDMA arbiter */
+	titan_writel(0x00ff18ff, CPRR);
+
+	/*
+	 * Set up the PADMUX. Power down all ethernet slices,
+	 * they will be powered up and configured at device startup.
+	 */
+	titan_writel(0x00878206, CPTC1R);
+	titan_writel(0x00001100, CPTC0R); /* latch PADMUX, enable WCIMODE */
+
+	/* Reset and enable the FIFO block */
+	titan_writel(0x00000001, SDRXFCIE);
+	titan_writel(0x00000001, SDTXFCIE);
+	titan_writel(0x00000100, SDRXFCIE);
+	titan_writel(0x00000000, SDTXFCIE);
+
+	/*
+	 * Initialize the common interrupt shared by all components of
+	 * the GPI/Ethernet subsystem.
+	 */
+	titan_writel((EXCITE_PHYS_OCD >> 12), CPCFG0);
+	titan_writel(TITAN_MSGINT, CPCFG1);
+
+	/*
+	 * XDMA configuration.
+	 * In order for the XDMA to be sharable among multiple drivers,
+	 * the setup must be done here in the platform. The reason is that
+	 * this setup can only be done while the XDMA is in reset. If this
+	 * were done in a driver, it would interrupt all other drivers
+	 * using the XDMA.
+	 */
+	titan_writel(0x80021dff, GXCFG);	/* XDMA reset */
+	titan_writel(0x00000000, CPXCISRA);
+	titan_writel(0x00000000, CPXCISRB);	/* clear pending interrupts */
+#if defined (CONFIG_HIGHMEM)
+#	error change for HIGHMEM support!
+#else
+	titan_writel(0x00000000, GXDMADRPFX);	/* buffer address prefix */
+#endif
+	titan_writel(0, GXDMA_DESCADR);
+
+	for (i = 0x5040; i <= 0x5300; i += 0x0040)
+		titan_writel(0x80080000, i);	/* reset channel */
+
+	titan_writel((0x1 << 29)			/* no sparse tx descr. */
+		     | (0x1 << 28)			/* no sparse rx descr. */
+		     | (0x1 << 23) | (0x1 << 24)	/* descriptor coherency */
+		     | (0x1 << 21) | (0x1 << 22)	/* data coherency */
+		     | (0x1 << 17)
+		     | 0x1dff,
+		     GXCFG);
+
+#if defined(CONFIG_SMP)
+#	error No SMP support
+#else
+	/* All interrupts go to core #0 only. */
+	titan_writel(0x1f007fff, CPDST0A);
+	titan_writel(0x00000000, CPDST0B);
+	titan_writel(0x0000ff3f, CPDST1A);
+	titan_writel(0x00000000, CPDST1B);
+	titan_writel(0x00ffffff, CPXDSTA);
+	titan_writel(0x00000000, CPXDSTB);
+#endif
+
+	/* Enable DUART interrupts, disable everything else. */
+	titan_writel(0x04000000, CPGIG0ER);
+	titan_writel(0x000000c0, CPGIG1ER);
+
+	excite_procfs_init();
+	return 0;
+}
+
+void __init plat_mem_setup(void)
+{
+	volatile u32 * const boot_ocd_base = (u32 *) 0xbf7fc000;
+
+	/* Announce RAM to system */
+	add_memory_region(0x00000000, memsize, BOOT_MEM_RAM);
+
+	/* Set up timer initialization hooks */
+	board_time_init = excite_timer_init;
+
+	/* Set up the peripheral address map */
+	*(boot_ocd_base + (LKB9 / sizeof (u32))) = 0;
+	*(boot_ocd_base + (LKB10 / sizeof (u32))) = 0;
+	*(boot_ocd_base + (LKB11 / sizeof (u32))) = 0;
+	*(boot_ocd_base + (LKB12 / sizeof (u32))) = 0;
+	wmb();
+	*(boot_ocd_base + (LKB0 / sizeof (u32))) = EXCITE_PHYS_OCD >> 4;
+	wmb();
+
+	ocd_writel((EXCITE_PHYS_TITAN >> 4) | 0x1UL, LKB5);
+	ocd_writel(((EXCITE_SIZE_TITAN >> 4) & 0x7fffff00) - 0x100, LKM5);
+	ocd_writel((EXCITE_PHYS_SCRAM >> 4) | 0x1UL, LKB13);
+	ocd_writel(((EXCITE_SIZE_SCRAM >> 4) & 0xffffff00) - 0x100, LKM13);
+
+	/* Local bus slot #0 */
+	ocd_writel(0x00040510, LDP0);
+	ocd_writel((EXCITE_PHYS_BOOTROM >> 4) | 0x1UL, LKB9);
+	ocd_writel(((EXCITE_SIZE_BOOTROM >> 4) & 0x03ffff00) - 0x100, LKM9);
+
+	/* Local bus slot #2 */
+	ocd_writel(0x00000330, LDP2);
+	ocd_writel((EXCITE_PHYS_FPGA >> 4) | 0x1, LKB11);
+	ocd_writel(((EXCITE_SIZE_FPGA >> 4) - 0x100) & 0x03ffff00, LKM11);
+
+	/* Local bus slot #3 */
+	ocd_writel(0x00123413, LDP3);
+	ocd_writel((EXCITE_PHYS_NAND >> 4) | 0x1, LKB12);
+	ocd_writel(((EXCITE_SIZE_NAND >> 4) - 0x100) & 0x03ffff00, LKM12);
+}
+
+
+
+console_initcall(excite_init_console);
+arch_initcall(excite_platform_init);
+
+EXPORT_SYMBOL(titan_lock);
+EXPORT_SYMBOL(titan_irqflags);
+EXPORT_SYMBOL(titan_irq);
+EXPORT_SYMBOL(ocd_base);
+EXPORT_SYMBOL(titan_base);
diff --git a/arch/mips/configs/emma2rh_defconfig b/arch/mips/configs/emma2rh_defconfig
new file mode 100644
index 000000000..375b2ac24
--- /dev/null
+++ b/arch/mips/configs/emma2rh_defconfig
@@ -0,0 +1,1241 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.18-rc1
+# Thu Jul  6 10:04:05 2006
+#
+CONFIG_MIPS=y
+
+#
+# Machine selection
+#
+# CONFIG_MIPS_MTX1 is not set
+# CONFIG_MIPS_BOSPORUS is not set
+# CONFIG_MIPS_PB1000 is not set
+# CONFIG_MIPS_PB1100 is not set
+# CONFIG_MIPS_PB1500 is not set
+# CONFIG_MIPS_PB1550 is not set
+# CONFIG_MIPS_PB1200 is not set
+# CONFIG_MIPS_DB1000 is not set
+# CONFIG_MIPS_DB1100 is not set
+# CONFIG_MIPS_DB1500 is not set
+# CONFIG_MIPS_DB1550 is not set
+# CONFIG_MIPS_DB1200 is not set
+# CONFIG_MIPS_MIRAGE is not set
+# CONFIG_BASLER_EXCITE is not set
+# CONFIG_MIPS_COBALT is not set
+# CONFIG_MACH_DECSTATION is not set
+# CONFIG_MIPS_EV64120 is not set
+# CONFIG_MIPS_EV96100 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
+# CONFIG_MIPS_MALTA is not set
+# CONFIG_MIPS_SEAD is not set
+# CONFIG_WR_PPMC is not set
+# CONFIG_MIPS_SIM is not set
+# CONFIG_MOMENCO_JAGUAR_ATX is not set
+# CONFIG_MOMENCO_OCELOT is not set
+# CONFIG_MOMENCO_OCELOT_3 is not set
+# CONFIG_MOMENCO_OCELOT_C is not set
+# CONFIG_MOMENCO_OCELOT_G is not set
+# CONFIG_MIPS_XXS1500 is not set
+# CONFIG_PNX8550_V2PCI is not set
+# CONFIG_PNX8550_JBS is not set
+# CONFIG_DDB5477 is not set
+# CONFIG_MACH_VR41XX is not set
+# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_QEMU is not set
+CONFIG_MARKEINS=y
+# CONFIG_SGI_IP22 is not set
+# CONFIG_SGI_IP27 is not set
+# CONFIG_SGI_IP32 is not set
+# CONFIG_SIBYTE_BIGSUR is not set
+# CONFIG_SIBYTE_SWARM is not set
+# CONFIG_SIBYTE_SENTOSA is not set
+# CONFIG_SIBYTE_RHONE is not set
+# CONFIG_SIBYTE_CARMEL is not set
+# CONFIG_SIBYTE_PTSWARM is not set
+# 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_TOSHIBA_JMR3927 is not set
+# CONFIG_TOSHIBA_RBTX4927 is not set
+# CONFIG_TOSHIBA_RBTX4938 is not set
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
+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_IRQ_CPU=y
+CONFIG_SWAP_IO_SPACE=y
+CONFIG_EMMA2RH=y
+CONFIG_MIPS_L1_CACHE_SHIFT=5
+
+#
+# CPU selection
+#
+# CONFIG_CPU_MIPS32_R1 is not set
+# CONFIG_CPU_MIPS32_R2 is not set
+# CONFIG_CPU_MIPS64_R1 is not set
+# CONFIG_CPU_MIPS64_R2 is not set
+# CONFIG_CPU_R3000 is not set
+# CONFIG_CPU_TX39XX is not set
+# CONFIG_CPU_VR41XX is not set
+# CONFIG_CPU_R4300 is not set
+# CONFIG_CPU_R4X00 is not set
+# CONFIG_CPU_TX49XX is not set
+CONFIG_CPU_R5000=y
+# CONFIG_CPU_R5432 is not set
+# CONFIG_CPU_R6000 is not set
+# CONFIG_CPU_NEVADA is not set
+# CONFIG_CPU_R8000 is not set
+# CONFIG_CPU_R10000 is not set
+# CONFIG_CPU_RM7000 is not set
+# CONFIG_CPU_RM9000 is not set
+# CONFIG_CPU_SB1 is not set
+CONFIG_SYS_HAS_CPU_R5000=y
+CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
+CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
+CONFIG_CPU_SUPPORTS_64BIT_KERNEL=y
+
+#
+# Kernel type
+#
+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
+# 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_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
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_ARCH_FLATMEM_ENABLE=y
+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=4
+# CONFIG_RESOURCES_64BIT is not set
+# CONFIG_HZ_48 is not set
+# CONFIG_HZ_100 is not set
+# CONFIG_HZ_128 is not set
+# CONFIG_HZ_250 is not set
+# CONFIG_HZ_256 is not set
+CONFIG_HZ_1000=y
+# CONFIG_HZ_1024 is not set
+CONFIG_SYS_SUPPORTS_ARBIT_HZ=y
+CONFIG_HZ=1000
+# CONFIG_PREEMPT_NONE is not set
+# CONFIG_PREEMPT_VOLUNTARY is not set
+CONFIG_PREEMPT=y
+CONFIG_PREEMPT_BKL=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_BSD_PROCESS_ACCT=y
+# CONFIG_BSD_PROCESS_ACCT_V3 is not set
+CONFIG_SYSCTL=y
+# CONFIG_AUDIT is not set
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+# CONFIG_RELAY is not set
+CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_EMBEDDED=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_RT_MUTEXES=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SHMEM=y
+CONFIG_SLAB=y
+CONFIG_VM_EVENT_COUNTERS=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 is not set
+CONFIG_KMOD=y
+
+#
+# Block layer
+#
+CONFIG_LBD=y
+# 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=y
+CONFIG_IOSCHED_CFQ=y
+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"
+
+#
+# Bus options (PCI, PCMCIA, EISA, ISA, TC)
+#
+CONFIG_HW_HAS_PCI=y
+CONFIG_PCI=y
+CONFIG_MMU=y
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# PCI Hotplug Support
+#
+# CONFIG_HOTPLUG_PCI is not set
+
+#
+# Executable file formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+CONFIG_TRAD_SIGNALS=y
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+# CONFIG_NETDEBUG is not set
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+CONFIG_NET_KEY=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_ASK_IP_FIB_HASH=y
+# 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
+CONFIG_IP_PNP=y
+# CONFIG_IP_PNP_DHCP is not set
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+CONFIG_SYN_COOKIES=y
+# 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=m
+CONFIG_INET_XFRM_MODE_TUNNEL=m
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
+
+#
+# IP: Virtual Server Configuration
+#
+# CONFIG_IP_VS is not set
+CONFIG_IPV6=m
+# CONFIG_IPV6_PRIVACY is not set
+# CONFIG_IPV6_ROUTER_PREF is not set
+# CONFIG_INET6_AH is not set
+# CONFIG_INET6_ESP is not set
+# CONFIG_INET6_IPCOMP is not set
+# CONFIG_INET6_XFRM_TUNNEL is not set
+# CONFIG_INET6_TUNNEL is not set
+CONFIG_INET6_XFRM_MODE_TRANSPORT=m
+CONFIG_INET6_XFRM_MODE_TUNNEL=m
+# CONFIG_IPV6_TUNNEL is not set
+CONFIG_NETWORK_SECMARK=y
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_DEBUG is not set
+
+#
+# Core Netfilter Configuration
+#
+# CONFIG_NETFILTER_NETLINK is not set
+# CONFIG_NF_CONNTRACK is not set
+# CONFIG_NETFILTER_XTABLES is not set
+
+#
+# IP: Netfilter Configuration
+#
+# CONFIG_IP_NF_CONNTRACK is not set
+# CONFIG_IP_NF_QUEUE is not set
+
+#
+# IPv6: Netfilter Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP6_NF_QUEUE is not set
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+CONFIG_IP_SCTP=m
+# CONFIG_SCTP_DBG_MSG is not set
+# CONFIG_SCTP_DBG_OBJCNT is not set
+# CONFIG_SCTP_HMAC_NONE is not set
+# CONFIG_SCTP_HMAC_SHA1 is not set
+CONFIG_SCTP_HMAC_MD5=y
+
+#
+# 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_NET_DIVERT 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_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
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=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
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=y
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_GEN_PROBE=y
+# CONFIG_MTD_CFI_ADV_OPTIONS 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_CFI_INTELEXT is not set
+CONFIG_MTD_CFI_AMDSTD=y
+# CONFIG_MTD_CFI_STAA is not set
+CONFIG_MTD_CFI_UTIL=y
+# 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_PHYSMAP=y
+CONFIG_MTD_PHYSMAP_START=0x1e000000
+CONFIG_MTD_PHYSMAP_LEN=0x02000000
+CONFIG_MTD_PHYSMAP_BANKWIDTH=2
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_PMC551 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 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_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=m
+CONFIG_BLK_DEV_CRYPTOLOOP=m
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_SX8 is not set
+# CONFIG_BLK_DEV_RAM is not set
+# CONFIG_BLK_DEV_INITRD is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+CONFIG_SCSI=m
+# CONFIG_SCSI_PROC_FS is not set
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=m
+# CONFIG_CHR_DEV_ST is not set
+# CONFIG_CHR_DEV_OSST is not set
+# CONFIG_BLK_DEV_SR is not set
+CONFIG_CHR_DEV_SG=m
+# CONFIG_CHR_DEV_SCH is not set
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+# CONFIG_SCSI_MULTI_LUN is not set
+# CONFIG_SCSI_CONSTANTS is not set
+# CONFIG_SCSI_LOGGING is not set
+
+#
+# SCSI Transport Attributes
+#
+# 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
+
+#
+# SCSI low-level drivers
+#
+# CONFIG_ISCSI_TCP is not set
+# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
+# CONFIG_SCSI_3W_9XXX is not set
+# CONFIG_SCSI_ACARD is not set
+# CONFIG_SCSI_AACRAID is not set
+# CONFIG_SCSI_AIC7XXX is not set
+# CONFIG_SCSI_AIC7XXX_OLD is not set
+# CONFIG_SCSI_AIC79XX is not set
+# CONFIG_SCSI_DPT_I2O 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_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_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
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+
+#
+# Fusion MPT device support
+#
+# CONFIG_FUSION is not set
+# CONFIG_FUSION_SPI is not set
+# CONFIG_FUSION_FC is not set
+# CONFIG_FUSION_SAS is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+# CONFIG_IEEE1394 is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+CONFIG_TUN=m
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+
+#
+# PHY device support
+#
+# CONFIG_PHYLIB is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+# CONFIG_HAPPYMEAL is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_CASSINI is not set
+# CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_DM9000 is not set
+
+#
+# Tulip family network device support
+#
+# CONFIG_NET_TULIP is not set
+# CONFIG_HP100 is not set
+CONFIG_NET_PCI=y
+# CONFIG_PCNET32 is not set
+# CONFIG_AMD8111_ETH is not set
+# CONFIG_ADAPTEC_STARFIRE is not set
+# CONFIG_B44 is not set
+# CONFIG_FORCEDETH is not set
+# CONFIG_DGRS is not set
+# CONFIG_EEPRO100 is not set
+# CONFIG_E100 is not set
+# CONFIG_FEALNX is not set
+CONFIG_NATSEMI=y
+# CONFIG_NE2K_PCI is not set
+# CONFIG_8139CP is not set
+# CONFIG_8139TOO is not set
+# CONFIG_SIS900 is not set
+# CONFIG_EPIC100 is not set
+# CONFIG_SUNDANCE is not set
+# CONFIG_TLAN is not set
+# CONFIG_VIA_RHINE is not set
+# CONFIG_LAN_SAA9730 is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_E1000 is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_R8169 is not set
+# CONFIG_SIS190 is not set
+# CONFIG_SKGE is not set
+# CONFIG_SKY2 is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_VIA_VELOCITY is not set
+# CONFIG_TIGON3 is not set
+# CONFIG_BNX2 is not set
+
+#
+# Ethernet (10000 Mbit)
+#
+# CONFIG_CHELSIO_T1 is not set
+# CONFIG_IXGB is not set
+# CONFIG_S2IO is not set
+# CONFIG_MYRI10GE is not set
+
+#
+# Token Ring devices
+#
+# CONFIG_TR is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+CONFIG_PPP=m
+# CONFIG_PPP_MULTILINK is not set
+# CONFIG_PPP_FILTER is not set
+CONFIG_PPP_ASYNC=m
+CONFIG_PPP_SYNC_TTY=m
+CONFIG_PPP_DEFLATE=m
+# CONFIG_PPP_BSDCOMP is not set
+# CONFIG_PPP_MPPE is not set
+# CONFIG_PPPOE is not set
+# CONFIG_SLIP is not set
+# CONFIG_NET_FC 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
+
+#
+# Telephony Support
+#
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+
+#
+# Userland interfaces
+#
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_TSDEV is not set
+CONFIG_INPUT_EVDEV=m
+# 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 is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+# CONFIG_VT is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_PCI=y
+CONFIG_SERIAL_8250_NR_UARTS=4
+CONFIG_SERIAL_8250_RUNTIME_UARTS=4
+# CONFIG_SERIAL_8250_EXTENDED is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_JSM is not set
+CONFIG_UNIX98_PTYS=y
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+
+#
+# IPMI
+#
+# CONFIG_IPMI_HANDLER is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_HW_RANDOM is not set
+CONFIG_RTC=m
+CONFIG_GEN_RTC=m
+CONFIG_GEN_RTC_X=y
+# 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
+
+#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+# CONFIG_TELCLOCK 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_ALI1535 is not set
+# CONFIG_I2C_ALI1563 is not set
+# CONFIG_I2C_ALI15X3 is not set
+# CONFIG_I2C_AMD756 is not set
+# CONFIG_I2C_AMD8111 is not set
+# CONFIG_I2C_I801 is not set
+# CONFIG_I2C_I810 is not set
+# CONFIG_I2C_PIIX4 is not set
+# CONFIG_I2C_NFORCE2 is not set
+# CONFIG_I2C_OCORES is not set
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_PROSAVAGE is not set
+# CONFIG_I2C_SAVAGE4 is not set
+# CONFIG_I2C_SIS5595 is not set
+# CONFIG_I2C_SIS630 is not set
+# CONFIG_I2C_SIS96X is not set
+# CONFIG_I2C_STUB is not set
+# CONFIG_I2C_VIA is not set
+# CONFIG_I2C_VIAPRO is not set
+# CONFIG_I2C_VOODOO3 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=y
+# CONFIG_I2C_DEBUG_ALGO is not set
+CONFIG_I2C_DEBUG_BUS=y
+# CONFIG_I2C_DEBUG_CHIP is not set
+
+#
+# SPI support
+#
+# CONFIG_SPI is not set
+# CONFIG_SPI_MASTER is not set
+
+#
+# Dallas's 1-wire bus
+#
+
+#
+# Hardware Monitoring support
+#
+CONFIG_HWMON=y
+# CONFIG_HWMON_VID is not set
+# CONFIG_SENSORS_ABITUGURU is not set
+# CONFIG_SENSORS_ADM1021 is not set
+# CONFIG_SENSORS_ADM1025 is not set
+# CONFIG_SENSORS_ADM1026 is not set
+# CONFIG_SENSORS_ADM1031 is not set
+# CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ASB100 is not set
+# CONFIG_SENSORS_ATXP1 is not set
+# CONFIG_SENSORS_DS1621 is not set
+# CONFIG_SENSORS_F71805F is not set
+# CONFIG_SENSORS_FSCHER is not set
+# CONFIG_SENSORS_FSCPOS is not set
+# CONFIG_SENSORS_GL518SM is not set
+# CONFIG_SENSORS_GL520SM is not set
+# CONFIG_SENSORS_IT87 is not set
+# CONFIG_SENSORS_LM63 is not set
+# CONFIG_SENSORS_LM75 is not set
+# CONFIG_SENSORS_LM77 is not set
+# CONFIG_SENSORS_LM78 is not set
+# CONFIG_SENSORS_LM80 is not set
+# CONFIG_SENSORS_LM83 is not set
+# CONFIG_SENSORS_LM85 is not set
+# CONFIG_SENSORS_LM87 is not set
+# CONFIG_SENSORS_LM90 is not set
+# CONFIG_SENSORS_LM92 is not set
+# CONFIG_SENSORS_MAX1619 is not set
+# CONFIG_SENSORS_PC87360 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_VT8231 is not set
+# CONFIG_SENSORS_W83781D is not set
+# CONFIG_SENSORS_W83791D is not set
+# CONFIG_SENSORS_W83792D 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
+#
+# CONFIG_DVB is not set
+
+#
+# Graphics support
+#
+# CONFIG_FIRMWARE_EDID is not set
+# CONFIG_FB is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
+#
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB_ARCH_HAS_EHCI=y
+# 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
+
+#
+# LED devices
+#
+# CONFIG_NEW_LEDS is not set
+
+#
+# LED drivers
+#
+
+#
+# LED Triggers
+#
+
+#
+# InfiniBand support
+#
+# CONFIG_INFINIBAND is not set
+
+#
+# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
+#
+
+#
+# Real Time Clock
+#
+# CONFIG_RTC_CLASS is not set
+
+#
+# DMA Engine support
+#
+# CONFIG_DMA_ENGINE is not set
+
+#
+# DMA Clients
+#
+
+#
+# DMA Devices
+#
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+CONFIG_EXT2_FS_POSIX_ACL=y
+CONFIG_EXT2_FS_SECURITY=y
+# CONFIG_EXT2_FS_XIP is not set
+CONFIG_EXT3_FS=m
+CONFIG_EXT3_FS_XATTR=y
+# CONFIG_EXT3_FS_POSIX_ACL is not set
+# CONFIG_EXT3_FS_SECURITY is not set
+CONFIG_JBD=m
+# 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=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_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 is not set
+# CONFIG_AUTOFS_FS is not set
+CONFIG_AUTOFS4_FS=m
+# 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=y
+CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+CONFIG_NTFS_FS=m
+# CONFIG_NTFS_DEBUG is not set
+# CONFIG_NTFS_RW is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# 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_JFFS_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=y
+CONFIG_JFFS2_ZLIB=y
+CONFIG_JFFS2_RTIME=y
+# CONFIG_JFFS2_RUBIN is not set
+# CONFIG_JFFS2_CMODE_NONE is not set
+CONFIG_JFFS2_CMODE_PRIORITY=y
+# CONFIG_JFFS2_CMODE_SIZE 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=y
+# CONFIG_NFS_V3_ACL is not set
+CONFIG_NFS_V4=y
+CONFIG_NFS_DIRECTIO=y
+CONFIG_NFSD=m
+CONFIG_NFSD_V3=y
+# CONFIG_NFSD_V3_ACL is not set
+# CONFIG_NFSD_V4 is not set
+CONFIG_NFSD_TCP=y
+CONFIG_ROOT_NFS=y
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_EXPORTFS=m
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+CONFIG_SUNRPC_GSS=y
+CONFIG_RPCSEC_GSS_KRB5=y
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+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
+# 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=""
+CONFIG_NLS_CODEPAGE_437=m
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+CONFIG_NLS_ASCII=m
+CONFIG_NLS_ISO8859_1=m
+# 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=m
+
+#
+# Profiling support
+#
+# CONFIG_PROFILING is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+# 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_CROSSCOMPILE=y
+CONFIG_CMDLINE="console=ttyS0,115200 mem=192m ip=bootp root=/dev/nfs rw"
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+
+#
+# Cryptographic options
+#
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_HMAC=y
+# CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_MD4 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_DES=y
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_AES is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_ARC4 is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Hardware crypto devices
+#
+
+#
+# Library routines
+#
+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_PLIST=y
diff --git a/arch/mips/configs/excite_defconfig b/arch/mips/configs/excite_defconfig
new file mode 100644
index 000000000..045ebd089
--- /dev/null
+++ b/arch/mips/configs/excite_defconfig
@@ -0,0 +1,1245 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.18-rc1
+# Thu Jul  6 10:04:09 2006
+#
+CONFIG_MIPS=y
+
+#
+# Machine selection
+#
+# CONFIG_MIPS_MTX1 is not set
+# CONFIG_MIPS_BOSPORUS is not set
+# CONFIG_MIPS_PB1000 is not set
+# CONFIG_MIPS_PB1100 is not set
+# CONFIG_MIPS_PB1500 is not set
+# CONFIG_MIPS_PB1550 is not set
+# CONFIG_MIPS_PB1200 is not set
+# CONFIG_MIPS_DB1000 is not set
+# CONFIG_MIPS_DB1100 is not set
+# CONFIG_MIPS_DB1500 is not set
+# CONFIG_MIPS_DB1550 is not set
+# CONFIG_MIPS_DB1200 is not set
+# CONFIG_MIPS_MIRAGE is not set
+CONFIG_BASLER_EXCITE=y
+# CONFIG_BASLER_EXCITE_PROTOTYPE is not set
+# CONFIG_MIPS_COBALT is not set
+# CONFIG_MACH_DECSTATION is not set
+# CONFIG_MIPS_EV64120 is not set
+# CONFIG_MIPS_EV96100 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
+# CONFIG_MIPS_MALTA is not set
+# CONFIG_MIPS_SEAD is not set
+# CONFIG_WR_PPMC is not set
+# CONFIG_MIPS_SIM is not set
+# CONFIG_MOMENCO_JAGUAR_ATX is not set
+# CONFIG_MOMENCO_OCELOT is not set
+# CONFIG_MOMENCO_OCELOT_3 is not set
+# CONFIG_MOMENCO_OCELOT_C is not set
+# CONFIG_MOMENCO_OCELOT_G is not set
+# CONFIG_MIPS_XXS1500 is not set
+# CONFIG_PNX8550_V2PCI is not set
+# CONFIG_PNX8550_JBS is not set
+# CONFIG_DDB5477 is not set
+# CONFIG_MACH_VR41XX is not set
+# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_QEMU is not set
+# CONFIG_MARKEINS is not set
+# CONFIG_SGI_IP22 is not set
+# CONFIG_SGI_IP27 is not set
+# CONFIG_SGI_IP32 is not set
+# CONFIG_SIBYTE_BIGSUR is not set
+# CONFIG_SIBYTE_SWARM is not set
+# CONFIG_SIBYTE_SENTOSA is not set
+# CONFIG_SIBYTE_RHONE is not set
+# CONFIG_SIBYTE_CARMEL is not set
+# CONFIG_SIBYTE_PTSWARM is not set
+# 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_TOSHIBA_JMR3927 is not set
+# CONFIG_TOSHIBA_RBTX4927 is not set
+# CONFIG_TOSHIBA_RBTX4938 is not set
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
+CONFIG_DMA_COHERENT=y
+CONFIG_CPU_BIG_ENDIAN=y
+# CONFIG_CPU_LITTLE_ENDIAN is not set
+CONFIG_SYS_SUPPORTS_BIG_ENDIAN=y
+CONFIG_IRQ_CPU=y
+CONFIG_IRQ_CPU_RM7K=y
+CONFIG_IRQ_CPU_RM9K=y
+CONFIG_MIPS_L1_CACHE_SHIFT=5
+
+#
+# CPU selection
+#
+# CONFIG_CPU_MIPS32_R1 is not set
+# CONFIG_CPU_MIPS32_R2 is not set
+# CONFIG_CPU_MIPS64_R1 is not set
+# CONFIG_CPU_MIPS64_R2 is not set
+# CONFIG_CPU_R3000 is not set
+# CONFIG_CPU_TX39XX is not set
+# CONFIG_CPU_VR41XX is not set
+# CONFIG_CPU_R4300 is not set
+# CONFIG_CPU_R4X00 is not set
+# CONFIG_CPU_TX49XX is not set
+# CONFIG_CPU_R5000 is not set
+# CONFIG_CPU_R5432 is not set
+# CONFIG_CPU_R6000 is not set
+# CONFIG_CPU_NEVADA is not set
+# CONFIG_CPU_R8000 is not set
+# CONFIG_CPU_R10000 is not set
+# CONFIG_CPU_RM7000 is not set
+CONFIG_CPU_RM9000=y
+# CONFIG_CPU_SB1 is not set
+CONFIG_SYS_HAS_CPU_RM9000=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=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
+# 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_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
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_CPU_SUPPORTS_HIGHMEM=y
+CONFIG_ARCH_FLATMEM_ENABLE=y
+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=4
+# CONFIG_RESOURCES_64BIT is not set
+# CONFIG_HZ_48 is not set
+# CONFIG_HZ_100 is not set
+# CONFIG_HZ_128 is not set
+# CONFIG_HZ_250 is not set
+# CONFIG_HZ_256 is not set
+CONFIG_HZ_1000=y
+# CONFIG_HZ_1024 is not set
+CONFIG_SYS_SUPPORTS_ARBIT_HZ=y
+CONFIG_HZ=1000
+# CONFIG_PREEMPT_NONE is not set
+# CONFIG_PREEMPT_VOLUNTARY is not set
+CONFIG_PREEMPT=y
+CONFIG_PREEMPT_BKL=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_POSIX_MQUEUE=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+# CONFIG_AUDIT is not set
+# CONFIG_IKCONFIG is not set
+# CONFIG_RELAY is not set
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_EMBEDDED=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_RT_MUTEXES=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SHMEM=y
+CONFIG_SLAB=y
+CONFIG_VM_EVENT_COUNTERS=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_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=y
+CONFIG_IOSCHED_CFQ=y
+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"
+
+#
+# Bus options (PCI, PCMCIA, EISA, ISA, TC)
+#
+CONFIG_HW_HAS_PCI=y
+CONFIG_PCI=y
+CONFIG_MMU=y
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# PCI Hotplug Support
+#
+# CONFIG_HOTPLUG_PCI is not set
+
+#
+# Executable file formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+CONFIG_TRAD_SIGNALS=y
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+# CONFIG_NETDEBUG is not set
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+# 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=y
+# CONFIG_IP_PNP_BOOTP is not set
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_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=m
+CONFIG_INET_XFRM_MODE_TUNNEL=m
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
+# CONFIG_IPV6 is not set
+# CONFIG_INET6_XFRM_TUNNEL is not set
+# CONFIG_INET6_TUNNEL is not set
+CONFIG_NETWORK_SECMARK=y
+# 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_NET_DIVERT 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_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 is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=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
+
+#
+# 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_PMC551 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=y
+# CONFIG_MTD_NAND_ECC_SMC is not set
+CONFIG_MTD_NAND_IDS=y
+# CONFIG_MTD_NAND_DISKONCHIP is not set
+# 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_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=m
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_SX8 is not set
+# CONFIG_BLK_DEV_UB is not set
+# CONFIG_BLK_DEV_RAM is not set
+# CONFIG_BLK_DEV_INITRD is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+CONFIG_SCSI=y
+# CONFIG_SCSI_PROC_FS is not set
+
+#
+# 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 is not set
+# CONFIG_SCSI_CONSTANTS is not set
+# CONFIG_SCSI_LOGGING is not set
+
+#
+# SCSI Transport Attributes
+#
+# 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
+
+#
+# SCSI low-level drivers
+#
+# CONFIG_ISCSI_TCP is not set
+# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
+# CONFIG_SCSI_3W_9XXX is not set
+# CONFIG_SCSI_ACARD is not set
+# CONFIG_SCSI_AACRAID is not set
+# CONFIG_SCSI_AIC7XXX is not set
+# CONFIG_SCSI_AIC7XXX_OLD is not set
+# CONFIG_SCSI_AIC79XX is not set
+# CONFIG_SCSI_DPT_I2O 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_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_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
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+
+#
+# Fusion MPT device support
+#
+# CONFIG_FUSION is not set
+# CONFIG_FUSION_SPI is not set
+# CONFIG_FUSION_FC is not set
+# CONFIG_FUSION_SAS is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+# CONFIG_IEEE1394 is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+
+#
+# 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
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+
+#
+# PHY device support
+#
+
+#
+# Ethernet (10 or 100Mbit)
+#
+# CONFIG_NET_ETHERNET is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_E1000 is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_R8169 is not set
+# CONFIG_SIS190 is not set
+# CONFIG_SKGE is not set
+# CONFIG_SKY2 is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_TIGON3 is not set
+# CONFIG_BNX2 is not set
+
+#
+# Ethernet (10000 Mbit)
+#
+# CONFIG_CHELSIO_T1 is not set
+# CONFIG_IXGB is not set
+# CONFIG_S2IO is not set
+# CONFIG_MYRI10GE is not set
+
+#
+# Token Ring devices
+#
+# CONFIG_TR is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_NET_FC is not set
+# CONFIG_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
+
+#
+# Telephony Support
+#
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=m
+CONFIG_INPUT_MOUSEDEV_PSAUX=y
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_TSDEV is not set
+CONFIG_INPUT_EVDEV=m
+# 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 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=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_PCI=y
+CONFIG_SERIAL_8250_NR_UARTS=2
+CONFIG_SERIAL_8250_RUNTIME_UARTS=2
+CONFIG_SERIAL_8250_EXTENDED=y
+# CONFIG_SERIAL_8250_MANY_PORTS 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
+#
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_JSM is not set
+CONFIG_UNIX98_PTYS=y
+# CONFIG_LEGACY_PTYS is not set
+
+#
+# IPMI
+#
+# CONFIG_IPMI_HANDLER is not set
+
+#
+# Watchdog Cards
+#
+CONFIG_WATCHDOG=y
+# CONFIG_WATCHDOG_NOWAYOUT is not set
+
+#
+# Watchdog Device Drivers
+#
+# CONFIG_SOFT_WATCHDOG is not set
+
+#
+# PCI-based Watchdog Cards
+#
+# CONFIG_PCIPCWATCHDOG is not set
+# CONFIG_WDTPCI is not set
+
+#
+# USB-based Watchdog Cards
+#
+# CONFIG_USBPCWATCHDOG is not set
+# CONFIG_HW_RANDOM is not set
+# CONFIG_RTC is not set
+# CONFIG_GEN_RTC is not set
+# 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
+
+#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+# CONFIG_TELCLOCK 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
+#
+
+#
+# Hardware Monitoring support
+#
+# CONFIG_HWMON is not set
+# CONFIG_HWMON_VID is not set
+
+#
+# Misc devices
+#
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+CONFIG_VIDEO_V4L2=y
+
+#
+# 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_CIRRUS is not set
+# CONFIG_FB_PM2 is not set
+# CONFIG_FB_CYBER2000 is not set
+# CONFIG_FB_ASILIANT is not set
+# CONFIG_FB_IMSTT is not set
+# CONFIG_FB_S1D13XXX is not set
+# CONFIG_FB_NVIDIA is not set
+# CONFIG_FB_RIVA is not set
+# CONFIG_FB_MATROX is not set
+# CONFIG_FB_RADEON is not set
+# CONFIG_FB_ATY128 is not set
+# CONFIG_FB_ATY is not set
+# CONFIG_FB_SAVAGE is not set
+# CONFIG_FB_SIS is not set
+# CONFIG_FB_NEOMAGIC is not set
+# CONFIG_FB_KYRO is not set
+# CONFIG_FB_3DFX is not set
+# CONFIG_FB_VOODOO1 is not set
+# CONFIG_FB_SMIVGX is not set
+# CONFIG_FB_TRIDENT 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=m
+# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
+# CONFIG_FONTS is not set
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
+
+#
+# Logo configuration
+#
+# CONFIG_LOGO is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
+#
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB_ARCH_HAS_EHCI=y
+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_OTG is not set
+
+#
+# USB Host Controller Drivers
+#
+CONFIG_USB_EHCI_HCD=y
+# 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_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_UHCI_HCD is not set
+# 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_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
+
+#
+# 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 is not set
+# CONFIG_USB_MON is not set
+
+#
+# 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_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_CYTHERM is not set
+# CONFIG_USB_PHIDGETKIT is not set
+# CONFIG_USB_PHIDGETSERVO is not set
+# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_APPLEDISPLAY is not set
+# CONFIG_USB_SISUSBVGA is not set
+# CONFIG_USB_LD is not set
+# CONFIG_USB_TEST is not set
+
+#
+# USB DSL modem support
+#
+
+#
+# USB Gadget Support
+#
+# CONFIG_USB_GADGET is not set
+
+#
+# MMC/SD Card support
+#
+# CONFIG_MMC is not set
+
+#
+# LED devices
+#
+# CONFIG_NEW_LEDS is not set
+
+#
+# LED drivers
+#
+
+#
+# LED Triggers
+#
+
+#
+# InfiniBand support
+#
+# CONFIG_INFINIBAND is not set
+
+#
+# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
+#
+
+#
+# Real Time Clock
+#
+# CONFIG_RTC_CLASS is not set
+
+#
+# DMA Engine support
+#
+# CONFIG_DMA_ENGINE is not set
+
+#
+# DMA Clients
+#
+
+#
+# DMA Devices
+#
+
+#
+# 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_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_OCFS2_FS is not set
+# CONFIG_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_FAT_FS=m
+CONFIG_MSDOS_FS=m
+CONFIG_VFAT_FS=m
+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_KCORE=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# 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_JFFS_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 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
+
+#
+# Network File Systems
+#
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL 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_LOCKD_V4=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_CIFS_DEBUG2 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=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_BSD_DISKLABEL is not set
+# CONFIG_MINIX_SUBPARTITION is not set
+# CONFIG_SOLARIS_X86_PARTITION is not set
+# CONFIG_UNIXWARE_DISKLABEL is not set
+# CONFIG_LDM_PARTITION is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_KARMA_PARTITION is not set
+# CONFIG_EFI_PARTITION is not set
+
+#
+# Native Language Support
+#
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="iso8859-1"
+CONFIG_NLS_CODEPAGE_437=m
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+CONFIG_NLS_CODEPAGE_850=m
+# 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=m
+# 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
+
+#
+# Profiling support
+#
+# CONFIG_PROFILING is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+# 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_CROSSCOMPILE=y
+CONFIG_CMDLINE=""
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+
+#
+# Cryptographic options
+#
+CONFIG_CRYPTO=y
+# CONFIG_CRYPTO_HMAC is not set
+# CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_MD4 is not set
+# CONFIG_CRYPTO_MD5 is not set
+# 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_DES is not set
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_AES is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_ARC4 is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Hardware crypto devices
+#
+
+#
+# Library routines
+#
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
+CONFIG_CRC32=y
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_PLIST=y
diff --git a/arch/mips/configs/wrppmc_defconfig b/arch/mips/configs/wrppmc_defconfig
new file mode 100644
index 000000000..3e4b16b39
--- /dev/null
+++ b/arch/mips/configs/wrppmc_defconfig
@@ -0,0 +1,864 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.18-rc1
+# Thu Jul  6 10:04:21 2006
+#
+CONFIG_MIPS=y
+
+#
+# Machine selection
+#
+# CONFIG_MIPS_MTX1 is not set
+# CONFIG_MIPS_BOSPORUS is not set
+# CONFIG_MIPS_PB1000 is not set
+# CONFIG_MIPS_PB1100 is not set
+# CONFIG_MIPS_PB1500 is not set
+# CONFIG_MIPS_PB1550 is not set
+# CONFIG_MIPS_PB1200 is not set
+# CONFIG_MIPS_DB1000 is not set
+# CONFIG_MIPS_DB1100 is not set
+# CONFIG_MIPS_DB1500 is not set
+# CONFIG_MIPS_DB1550 is not set
+# CONFIG_MIPS_DB1200 is not set
+# CONFIG_MIPS_MIRAGE is not set
+# CONFIG_BASLER_EXCITE is not set
+# CONFIG_MIPS_COBALT is not set
+# CONFIG_MACH_DECSTATION is not set
+# CONFIG_MIPS_EV64120 is not set
+# CONFIG_MIPS_EV96100 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
+# CONFIG_MIPS_MALTA is not set
+# CONFIG_MIPS_SEAD is not set
+CONFIG_WR_PPMC=y
+# CONFIG_MIPS_SIM is not set
+# CONFIG_MOMENCO_JAGUAR_ATX is not set
+# CONFIG_MOMENCO_OCELOT is not set
+# CONFIG_MOMENCO_OCELOT_3 is not set
+# CONFIG_MOMENCO_OCELOT_C is not set
+# CONFIG_MOMENCO_OCELOT_G is not set
+# CONFIG_MIPS_XXS1500 is not set
+# CONFIG_PNX8550_V2PCI is not set
+# CONFIG_PNX8550_JBS is not set
+# CONFIG_DDB5477 is not set
+# CONFIG_MACH_VR41XX is not set
+# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_QEMU is not set
+# CONFIG_MARKEINS is not set
+# CONFIG_SGI_IP22 is not set
+# CONFIG_SGI_IP27 is not set
+# CONFIG_SGI_IP32 is not set
+# CONFIG_SIBYTE_BIGSUR is not set
+# CONFIG_SIBYTE_SWARM is not set
+# CONFIG_SIBYTE_SENTOSA is not set
+# CONFIG_SIBYTE_RHONE is not set
+# CONFIG_SIBYTE_CARMEL is not set
+# CONFIG_SIBYTE_PTSWARM is not set
+# 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_TOSHIBA_JMR3927 is not set
+# CONFIG_TOSHIBA_RBTX4927 is not set
+# CONFIG_TOSHIBA_RBTX4938 is not set
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
+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_IRQ_CPU=y
+CONFIG_MIPS_GT64120=y
+CONFIG_SWAP_IO_SPACE=y
+CONFIG_BOOT_ELF32=y
+CONFIG_MIPS_L1_CACHE_SHIFT=5
+
+#
+# CPU selection
+#
+CONFIG_CPU_MIPS32_R1=y
+# CONFIG_CPU_MIPS32_R2 is not set
+# CONFIG_CPU_MIPS64_R1 is not set
+# CONFIG_CPU_MIPS64_R2 is not set
+# CONFIG_CPU_R3000 is not set
+# CONFIG_CPU_TX39XX is not set
+# CONFIG_CPU_VR41XX is not set
+# CONFIG_CPU_R4300 is not set
+# CONFIG_CPU_R4X00 is not set
+# CONFIG_CPU_TX49XX is not set
+# CONFIG_CPU_R5000 is not set
+# CONFIG_CPU_R5432 is not set
+# CONFIG_CPU_R6000 is not set
+# CONFIG_CPU_NEVADA is not set
+# CONFIG_CPU_R8000 is not set
+# CONFIG_CPU_R10000 is not set
+# CONFIG_CPU_RM7000 is not set
+# CONFIG_CPU_RM9000 is not set
+# CONFIG_CPU_SB1 is not set
+CONFIG_SYS_HAS_CPU_MIPS32_R1=y
+CONFIG_SYS_HAS_CPU_MIPS32_R2=y
+CONFIG_SYS_HAS_CPU_MIPS64_R1=y
+CONFIG_SYS_HAS_CPU_NEVADA=y
+CONFIG_SYS_HAS_CPU_RM7000=y
+CONFIG_CPU_MIPS32=y
+CONFIG_CPU_MIPSR1=y
+CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
+CONFIG_SYS_SUPPORTS_64BIT_KERNEL=y
+CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
+
+#
+# Kernel type
+#
+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
+# 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_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
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_CPU_SUPPORTS_HIGHMEM=y
+CONFIG_ARCH_FLATMEM_ENABLE=y
+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=4
+# CONFIG_RESOURCES_64BIT is not set
+# CONFIG_HZ_48 is not set
+# CONFIG_HZ_100 is not set
+# CONFIG_HZ_128 is not set
+# CONFIG_HZ_250 is not set
+# CONFIG_HZ_256 is not set
+CONFIG_HZ_1000=y
+# CONFIG_HZ_1024 is not set
+CONFIG_SYS_SUPPORTS_ARBIT_HZ=y
+CONFIG_HZ=1000
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
+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 is not set
+CONFIG_SYSVIPC=y
+# CONFIG_POSIX_MQUEUE is not set
+CONFIG_BSD_PROCESS_ACCT=y
+# CONFIG_BSD_PROCESS_ACCT_V3 is not set
+CONFIG_SYSCTL=y
+# CONFIG_AUDIT is not set
+# CONFIG_IKCONFIG is not set
+# CONFIG_RELAY is not set
+CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_EMBEDDED=y
+CONFIG_KALLSYMS=y
+CONFIG_KALLSYMS_EXTRA_PASS=y
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+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_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=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+# CONFIG_KMOD is not set
+
+#
+# Block layer
+#
+# 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=y
+CONFIG_IOSCHED_CFQ=y
+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"
+
+#
+# Bus options (PCI, PCMCIA, EISA, ISA, TC)
+#
+CONFIG_HW_HAS_PCI=y
+CONFIG_PCI=y
+CONFIG_MMU=y
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# PCI Hotplug Support
+#
+CONFIG_HOTPLUG_PCI=y
+# CONFIG_HOTPLUG_PCI_FAKE is not set
+# CONFIG_HOTPLUG_PCI_CPCI is not set
+# CONFIG_HOTPLUG_PCI_SHPC is not set
+
+#
+# Executable file formats
+#
+CONFIG_BINFMT_ELF=y
+CONFIG_BINFMT_MISC=y
+CONFIG_TRAD_SIGNALS=y
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+# CONFIG_NETDEBUG is not set
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+CONFIG_IP_PNP_RARP=y
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+CONFIG_IP_MROUTE=y
+# CONFIG_IP_PIMSM_V1 is not set
+# CONFIG_IP_PIMSM_V2 is not set
+CONFIG_ARPD=y
+# 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=m
+CONFIG_INET_XFRM_MODE_TUNNEL=m
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
+# CONFIG_IPV6 is not set
+# CONFIG_INET6_XFRM_TUNNEL is not set
+# CONFIG_INET6_TUNNEL is not set
+CONFIG_NETWORK_SECMARK=y
+# 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_NET_DIVERT 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_SYS_HYPERVISOR is not set
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+# CONFIG_CONNECTOR is not set
+
+#
+# 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_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_COW_COMMON is not set
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_SX8 is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=4096
+CONFIG_BLK_DEV_INITRD=y
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+# CONFIG_SCSI 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
+#
+# CONFIG_IEEE1394 is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+
+#
+# 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
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+
+#
+# PHY device support
+#
+CONFIG_PHYLIB=y
+
+#
+# MII PHY device drivers
+#
+# CONFIG_MARVELL_PHY is not set
+# CONFIG_DAVICOM_PHY is not set
+# CONFIG_QSEMI_PHY is not set
+# CONFIG_LXT_PHY is not set
+# CONFIG_CICADA_PHY is not set
+CONFIG_VITESSE_PHY=m
+CONFIG_SMSC_PHY=m
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+# CONFIG_HAPPYMEAL is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_CASSINI is not set
+# CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_DM9000 is not set
+
+#
+# Tulip family network device support
+#
+# CONFIG_NET_TULIP is not set
+# CONFIG_HP100 is not set
+CONFIG_NET_PCI=y
+# CONFIG_PCNET32 is not set
+# CONFIG_AMD8111_ETH is not set
+# CONFIG_ADAPTEC_STARFIRE is not set
+# CONFIG_B44 is not set
+# CONFIG_FORCEDETH is not set
+# CONFIG_DGRS is not set
+# CONFIG_EEPRO100 is not set
+CONFIG_E100=y
+# CONFIG_FEALNX is not set
+# CONFIG_NATSEMI is not set
+# CONFIG_NE2K_PCI is not set
+# CONFIG_8139CP is not set
+# CONFIG_8139TOO is not set
+# CONFIG_SIS900 is not set
+# CONFIG_EPIC100 is not set
+# CONFIG_SUNDANCE is not set
+# CONFIG_TLAN is not set
+# CONFIG_VIA_RHINE is not set
+# CONFIG_LAN_SAA9730 is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_E1000 is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_R8169 is not set
+# CONFIG_SIS190 is not set
+# CONFIG_SKGE is not set
+# CONFIG_SKY2 is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_VIA_VELOCITY is not set
+# CONFIG_TIGON3 is not set
+# CONFIG_BNX2 is not set
+
+#
+# Ethernet (10000 Mbit)
+#
+# CONFIG_CHELSIO_T1 is not set
+# CONFIG_IXGB is not set
+# CONFIG_S2IO is not set
+# CONFIG_MYRI10GE is not set
+
+#
+# Token Ring devices
+#
+# CONFIG_TR is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI 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
+
+#
+# Telephony Support
+#
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+# CONFIG_INPUT is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+# CONFIG_VT is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_PCI=y
+CONFIG_SERIAL_8250_NR_UARTS=1
+CONFIG_SERIAL_8250_RUNTIME_UARTS=1
+# CONFIG_SERIAL_8250_EXTENDED is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_JSM is not set
+CONFIG_UNIX98_PTYS=y
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+
+#
+# IPMI
+#
+# CONFIG_IPMI_HANDLER is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_HW_RANDOM is not set
+CONFIG_RTC=y
+# 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
+
+#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+# CONFIG_TELCLOCK 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
+#
+
+#
+# Hardware Monitoring support
+#
+CONFIG_HWMON=y
+# CONFIG_HWMON_VID is not set
+# CONFIG_SENSORS_ABITUGURU is not set
+# CONFIG_SENSORS_F71805F 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
+#
+# CONFIG_DVB is not set
+
+#
+# Graphics support
+#
+# CONFIG_FIRMWARE_EDID is not set
+# CONFIG_FB is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
+#
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB_ARCH_HAS_EHCI=y
+# 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
+
+#
+# LED devices
+#
+# CONFIG_NEW_LEDS is not set
+
+#
+# LED drivers
+#
+
+#
+# LED Triggers
+#
+
+#
+# InfiniBand support
+#
+# CONFIG_INFINIBAND is not set
+
+#
+# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
+#
+
+#
+# Real Time Clock
+#
+# CONFIG_RTC_CLASS is not set
+
+#
+# DMA Engine support
+#
+# CONFIG_DMA_ENGINE is not set
+
+#
+# DMA Clients
+#
+
+#
+# DMA Devices
+#
+
+#
+# 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_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
+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_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_KCORE=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# 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
+
+#
+# Network File Systems
+#
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL 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_LOCKD_V4=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_CIFS_DEBUG2 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 is not set
+
+#
+# Profiling support
+#
+# CONFIG_PROFILING is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+# 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_CROSSCOMPILE=y
+CONFIG_CMDLINE="console=ttyS0,115200n8"
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+
+#
+# Cryptographic options
+#
+# CONFIG_CRYPTO is not set
+
+#
+# Hardware crypto devices
+#
+
+#
+# Library routines
+#
+CONFIG_CRC_CCITT=y
+CONFIG_CRC16=y
+CONFIG_CRC32=y
+CONFIG_LIBCRC32C=y
+CONFIG_PLIST=y
diff --git a/arch/mips/emma2rh/common/Makefile b/arch/mips/emma2rh/common/Makefile
new file mode 100644
index 000000000..859121b38
--- /dev/null
+++ b/arch/mips/emma2rh/common/Makefile
@@ -0,0 +1,13 @@
+#
+#  arch/mips/emma2rh/common/Makefile
+#       Makefile for the common code of NEC EMMA2RH based board.
+#
+#  Copyright (C) NEC Electronics Corporation 2005-2006
+#
+#  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.
+#
+
+obj-$(CONFIG_MARKEINS)	+= irq.o irq_emma2rh.o prom.o
diff --git a/arch/mips/emma2rh/common/irq.c b/arch/mips/emma2rh/common/irq.c
new file mode 100644
index 000000000..3af57693c
--- /dev/null
+++ b/arch/mips/emma2rh/common/irq.c
@@ -0,0 +1,107 @@
+/*
+ *  arch/mips/emma2rh/common/irq.c
+ *      This file is common irq dispatcher.
+ *
+ *  Copyright (C) NEC Electronics Corporation 2005-2006
+ *
+ *  This file is based on the arch/mips/ddb5xxx/ddb5477/irq.c
+ *
+ *	Copyright 2001 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 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/interrupt.h>
+#include <linux/irq.h>
+#include <linux/types.h>
+
+#include <asm/i8259.h>
+#include <asm/system.h>
+#include <asm/mipsregs.h>
+#include <asm/debug.h>
+#include <asm/addrspace.h>
+#include <asm/bootinfo.h>
+
+#include <asm/emma2rh/emma2rh.h>
+
+/*
+ * the first level int-handler will jump here if it is a emma2rh irq
+ */
+asmlinkage void emma2rh_irq_dispatch(struct pt_regs *regs)
+{
+	u32 intStatus;
+	u32 bitmask;
+	u32 i;
+
+	intStatus = emma2rh_in32(EMMA2RH_BHIF_INT_ST_0)
+	    & emma2rh_in32(EMMA2RH_BHIF_INT_EN_0);
+
+#ifdef EMMA2RH_SW_CASCADE
+	if (intStatus &
+	    (1 << ((EMMA2RH_SW_CASCADE - EMMA2RH_IRQ_INT0) & (32 - 1)))) {
+		u32 swIntStatus;
+		swIntStatus = emma2rh_in32(EMMA2RH_BHIF_SW_INT)
+		    & emma2rh_in32(EMMA2RH_BHIF_SW_INT_EN);
+		for (i = 0, bitmask = 1; i < 32; i++, bitmask <<= 1) {
+			if (swIntStatus & bitmask) {
+				do_IRQ(EMMA2RH_SW_IRQ_BASE + i, regs);
+				return;
+			}
+		}
+	}
+#endif
+
+	for (i = 0, bitmask = 1; i < 32; i++, bitmask <<= 1) {
+		if (intStatus & bitmask) {
+			do_IRQ(EMMA2RH_IRQ_BASE + i, regs);
+			return;
+		}
+	}
+
+	intStatus = emma2rh_in32(EMMA2RH_BHIF_INT_ST_1)
+	    & emma2rh_in32(EMMA2RH_BHIF_INT_EN_1);
+
+#ifdef EMMA2RH_GPIO_CASCADE
+	if (intStatus &
+	    (1 << ((EMMA2RH_GPIO_CASCADE - EMMA2RH_IRQ_INT0) & (32 - 1)))) {
+		u32 gpioIntStatus;
+		gpioIntStatus = emma2rh_in32(EMMA2RH_GPIO_INT_ST)
+		    & emma2rh_in32(EMMA2RH_GPIO_INT_MASK);
+		for (i = 0, bitmask = 1; i < 32; i++, bitmask <<= 1) {
+			if (gpioIntStatus & bitmask) {
+				do_IRQ(EMMA2RH_GPIO_IRQ_BASE + i, regs);
+				return;
+			}
+		}
+	}
+#endif
+
+	for (i = 32, bitmask = 1; i < 64; i++, bitmask <<= 1) {
+		if (intStatus & bitmask) {
+			do_IRQ(EMMA2RH_IRQ_BASE + i, regs);
+			return;
+		}
+	}
+
+	intStatus = emma2rh_in32(EMMA2RH_BHIF_INT_ST_2)
+	    & emma2rh_in32(EMMA2RH_BHIF_INT_EN_2);
+
+	for (i = 64, bitmask = 1; i < 96; i++, bitmask <<= 1) {
+		if (intStatus & bitmask) {
+			do_IRQ(EMMA2RH_IRQ_BASE + i, regs);
+			return;
+		}
+	}
+}
diff --git a/arch/mips/emma2rh/common/irq_emma2rh.c b/arch/mips/emma2rh/common/irq_emma2rh.c
new file mode 100644
index 000000000..7c930860c
--- /dev/null
+++ b/arch/mips/emma2rh/common/irq_emma2rh.c
@@ -0,0 +1,134 @@
+/*
+ *  arch/mips/emma2rh/common/irq_emma2rh.c
+ *      This file defines the irq handler for EMMA2RH.
+ *
+ *  Copyright (C) NEC Electronics Corporation 2005-2006
+ *
+ *  This file is based on the arch/mips/ddb5xxx/ddb5477/irq_5477.c
+ *
+ *	Copyright 2001 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 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
+ */
+
+/*
+ * EMMA2RH defines 64 IRQs.
+ *
+ * This file exports one function:
+ *	emma2rh_irq_init(u32 irq_base);
+ */
+
+#include <linux/interrupt.h>
+#include <linux/types.h>
+#include <linux/ptrace.h>
+
+#include <asm/debug.h>
+
+#include <asm/emma2rh/emma2rh.h>
+
+/* number of total irqs supported by EMMA2RH */
+#define	NUM_EMMA2RH_IRQ		96
+
+static int emma2rh_irq_base = -1;
+
+void ll_emma2rh_irq_enable(int);
+void ll_emma2rh_irq_disable(int);
+
+static void emma2rh_irq_enable(unsigned int irq)
+{
+	ll_emma2rh_irq_enable(irq - emma2rh_irq_base);
+}
+
+static void emma2rh_irq_disable(unsigned int irq)
+{
+	ll_emma2rh_irq_disable(irq - emma2rh_irq_base);
+}
+
+static unsigned int emma2rh_irq_startup(unsigned int irq)
+{
+	emma2rh_irq_enable(irq);
+	return 0;
+}
+
+#define	emma2rh_irq_shutdown	emma2rh_irq_disable
+
+static void emma2rh_irq_ack(unsigned int irq)
+{
+	/* disable interrupt - some handler will re-enable the irq
+	 * and if the interrupt is leveled, we will have infinite loop
+	 */
+	ll_emma2rh_irq_disable(irq - emma2rh_irq_base);
+}
+
+static void emma2rh_irq_end(unsigned int irq)
+{
+	if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS)))
+		ll_emma2rh_irq_enable(irq - emma2rh_irq_base);
+}
+
+struct irq_chip emma2rh_irq_controller = {
+	.typename = "emma2rh_irq",
+	.startup = emma2rh_irq_startup,
+	.shutdown = emma2rh_irq_shutdown,
+	.enable = emma2rh_irq_enable,
+	.disable = emma2rh_irq_disable,
+	.ack = emma2rh_irq_ack,
+	.end = emma2rh_irq_end,
+	.set_affinity = NULL	/* no affinity stuff for UP */
+};
+
+void emma2rh_irq_init(u32 irq_base)
+{
+	u32 i;
+
+	for (i = irq_base; i < irq_base + NUM_EMMA2RH_IRQ; i++) {
+		irq_desc[i].status = IRQ_DISABLED;
+		irq_desc[i].action = NULL;
+		irq_desc[i].depth = 1;
+		irq_desc[i].handler = &emma2rh_irq_controller;
+	}
+
+	emma2rh_irq_base = irq_base;
+}
+
+void ll_emma2rh_irq_enable(int emma2rh_irq)
+{
+	u32 reg_value;
+	u32 reg_bitmask;
+	u32 reg_index;
+
+	reg_index = EMMA2RH_BHIF_INT_EN_0
+	    + (EMMA2RH_BHIF_INT_EN_1 - EMMA2RH_BHIF_INT_EN_0)
+	    * (emma2rh_irq / 32);
+	reg_value = emma2rh_in32(reg_index);
+	reg_bitmask = 0x1 << (emma2rh_irq % 32);
+	db_assert((reg_value & reg_bitmask) == 0);
+	emma2rh_out32(reg_index, reg_value | reg_bitmask);
+}
+
+void ll_emma2rh_irq_disable(int emma2rh_irq)
+{
+	u32 reg_value;
+	u32 reg_bitmask;
+	u32 reg_index;
+
+	reg_index = EMMA2RH_BHIF_INT_EN_0
+	    + (EMMA2RH_BHIF_INT_EN_1 - EMMA2RH_BHIF_INT_EN_0)
+	    * (emma2rh_irq / 32);
+	reg_value = emma2rh_in32(reg_index);
+	reg_bitmask = 0x1 << (emma2rh_irq % 32);
+	db_assert((reg_value & reg_bitmask) != 0);
+	emma2rh_out32(reg_index, reg_value & ~reg_bitmask);
+}
diff --git a/arch/mips/emma2rh/common/prom.c b/arch/mips/emma2rh/common/prom.c
new file mode 100644
index 000000000..7433bd8e5
--- /dev/null
+++ b/arch/mips/emma2rh/common/prom.c
@@ -0,0 +1,76 @@
+/*
+ *  arch/mips/emma2rh/common/prom.c
+ *      This file is prom file.
+ *
+ *  Copyright (C) NEC Electronics Corporation 2004-2006
+ *
+ *  This file is based on the arch/mips/ddb5xxx/common/prom.c
+ *
+ *	Copyright 2001 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 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/mm.h>
+#include <linux/sched.h>
+#include <linux/bootmem.h>
+
+#include <asm/addrspace.h>
+#include <asm/bootinfo.h>
+#include <asm/emma2rh/emma2rh.h>
+#include <asm/debug.h>
+
+const char *get_system_type(void)
+{
+	switch (mips_machtype) {
+	case MACH_NEC_MARKEINS:
+		return "NEC EMMA2RH Mark-eins";
+	default:
+		return "Unknown NEC board";
+	}
+}
+
+/* [jsun@junsun.net] PMON passes arguments in C main() style */
+void __init prom_init(void)
+{
+	int argc = fw_arg0;
+	char **arg = (char **)fw_arg1;
+	int i;
+
+	/* if user passes kernel args, ignore the default one */
+	if (argc > 1)
+		arcs_cmdline[0] = '\0';
+
+	/* arg[0] is "g", the rest is boot parameters */
+	for (i = 1; i < argc; i++) {
+		if (strlen(arcs_cmdline) + strlen(arg[i] + 1)
+		    >= sizeof(arcs_cmdline))
+			break;
+		strcat(arcs_cmdline, arg[i]);
+		strcat(arcs_cmdline, " ");
+	}
+
+	mips_machgroup = MACH_GROUP_NEC_EMMA2RH;
+
+#if defined(CONFIG_MARKEINS)
+	mips_machtype = MACH_NEC_MARKEINS;
+	add_memory_region(0, EMMA2RH_RAM_SIZE, BOOT_MEM_RAM);
+#endif
+
+}
+
+void __init prom_free_prom_memory(void)
+{
+}
diff --git a/arch/mips/emma2rh/markeins/Makefile b/arch/mips/emma2rh/markeins/Makefile
new file mode 100644
index 000000000..14fc268b1
--- /dev/null
+++ b/arch/mips/emma2rh/markeins/Makefile
@@ -0,0 +1,13 @@
+#
+#  arch/mips/emma2rh/markeins/Makefile
+#       Makefile for the common code of NEC EMMA2RH based board.
+#
+#  Copyright (C) NEC Electronics Corporation 2005-2006
+#
+#  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.
+#
+
+obj-$(CONFIG_MARKEINS) += irq.o irq_markeins.o setup.o led.o platform.o
diff --git a/arch/mips/emma2rh/markeins/irq.c b/arch/mips/emma2rh/markeins/irq.c
new file mode 100644
index 000000000..2a736be42
--- /dev/null
+++ b/arch/mips/emma2rh/markeins/irq.c
@@ -0,0 +1,133 @@
+/*
+ *  arch/mips/emma2rh/markeins/irq.c
+ *      This file defines the irq handler for EMMA2RH.
+ *
+ *  Copyright (C) NEC Electronics Corporation 2004-2006
+ *
+ *  This file is based on the arch/mips/ddb5xxx/ddb5477/irq.c
+ *
+ *	Copyright 2001 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 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/interrupt.h>
+#include <linux/irq.h>
+#include <linux/types.h>
+#include <linux/ptrace.h>
+#include <linux/delay.h>
+
+#include <asm/i8259.h>
+#include <asm/irq_cpu.h>
+#include <asm/system.h>
+#include <asm/mipsregs.h>
+#include <asm/debug.h>
+#include <asm/addrspace.h>
+#include <asm/bootinfo.h>
+
+#include <asm/emma2rh/emma2rh.h>
+
+/*
+ * IRQ mapping
+ *
+ *  0-7: 8 CPU interrupts
+ *	0 -	software interrupt 0
+ *	1 - 	software interrupt 1
+ *	2 - 	most Vrc5477 interrupts are routed to this pin
+ *	3 - 	(optional) some other interrupts routed to this pin for debugg
+ *	4 - 	not used
+ *	5 - 	not used
+ *	6 - 	not used
+ *	7 - 	cpu timer (used by default)
+ *
+ */
+
+extern void emma2rh_sw_irq_init(u32 base);
+extern void emma2rh_gpio_irq_init(u32 base);
+extern void emma2rh_irq_init(u32 base);
+extern asmlinkage void emma2rh_irq_dispatch(struct pt_regs *regs);
+
+static struct irqaction irq_cascade = {
+	   .handler = no_action,
+	   .flags = 0,
+	   .mask = CPU_MASK_NONE,
+	   .name = "cascade",
+	   .dev_id = NULL,
+	   .next = NULL,
+};
+
+void __init arch_init_irq(void)
+{
+	u32 reg;
+
+	db_run(printk("markeins_irq_setup invoked.\n"));
+
+	/* by default, interrupts are disabled. */
+	emma2rh_out32(EMMA2RH_BHIF_INT_EN_0, 0);
+	emma2rh_out32(EMMA2RH_BHIF_INT_EN_1, 0);
+	emma2rh_out32(EMMA2RH_BHIF_INT_EN_2, 0);
+	emma2rh_out32(EMMA2RH_BHIF_INT1_EN_0, 0);
+	emma2rh_out32(EMMA2RH_BHIF_INT1_EN_1, 0);
+	emma2rh_out32(EMMA2RH_BHIF_INT1_EN_2, 0);
+	emma2rh_out32(EMMA2RH_BHIF_SW_INT_EN, 0);
+
+	clear_c0_status(0xff00);
+	set_c0_status(0x0400);
+
+#define GPIO_PCI (0xf<<15)
+	/* setup GPIO interrupt for PCI interface */
+	/* direction input */
+	reg = emma2rh_in32(EMMA2RH_GPIO_DIR);
+	emma2rh_out32(EMMA2RH_GPIO_DIR, reg & ~GPIO_PCI);
+	/* disable interrupt */
+	reg = emma2rh_in32(EMMA2RH_GPIO_INT_MASK);
+	emma2rh_out32(EMMA2RH_GPIO_INT_MASK, reg & ~GPIO_PCI);
+	/* level triggerd */
+	reg = emma2rh_in32(EMMA2RH_GPIO_INT_MODE);
+	emma2rh_out32(EMMA2RH_GPIO_INT_MODE, reg | GPIO_PCI);
+	reg = emma2rh_in32(EMMA2RH_GPIO_INT_CND_A);
+	emma2rh_out32(EMMA2RH_GPIO_INT_CND_A, reg & (~GPIO_PCI));
+	/* interrupt clear */
+	emma2rh_out32(EMMA2RH_GPIO_INT_ST, ~GPIO_PCI);
+
+	/* init all controllers */
+	emma2rh_irq_init(EMMA2RH_IRQ_BASE);
+	emma2rh_sw_irq_init(EMMA2RH_SW_IRQ_BASE);
+	emma2rh_gpio_irq_init(EMMA2RH_GPIO_IRQ_BASE);
+	mips_cpu_irq_init(CPU_IRQ_BASE);
+
+	/* setup cascade interrupts */
+	setup_irq(EMMA2RH_IRQ_BASE + EMMA2RH_SW_CASCADE, &irq_cascade);
+	setup_irq(EMMA2RH_IRQ_BASE + EMMA2RH_GPIO_CASCADE, &irq_cascade);
+	setup_irq(CPU_IRQ_BASE + CPU_EMMA2RH_CASCADE, &irq_cascade);
+}
+
+asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
+{
+        unsigned int pending = read_c0_status() & read_c0_cause();
+
+	if (pending & STATUSF_IP7)
+		do_IRQ(CPU_IRQ_BASE + 7, regs);
+	else if (pending & STATUSF_IP2)
+		emma2rh_irq_dispatch(regs);
+	else if (pending & STATUSF_IP1)
+		do_IRQ(CPU_IRQ_BASE + 1, regs);
+	else if (pending & STATUSF_IP0)
+		do_IRQ(CPU_IRQ_BASE + 0, regs);
+	else
+		spurious_interrupt(regs);
+}
+
+
diff --git a/arch/mips/emma2rh/markeins/irq_markeins.c b/arch/mips/emma2rh/markeins/irq_markeins.c
new file mode 100644
index 000000000..f23ae9fcf
--- /dev/null
+++ b/arch/mips/emma2rh/markeins/irq_markeins.c
@@ -0,0 +1,197 @@
+/*
+ *  arch/mips/emma2rh/markeins/irq_markeins.c
+ *      This file defines the irq handler for Mark-eins.
+ *
+ *  Copyright (C) NEC Electronics Corporation 2004-2006
+ *
+ *  This file is based on the arch/mips/ddb5xxx/ddb5477/irq_5477.c
+ *
+ *	Copyright 2001 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 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/interrupt.h>
+#include <linux/irq.h>
+#include <linux/types.h>
+#include <linux/ptrace.h>
+
+#include <asm/debug.h>
+#include <asm/emma2rh/emma2rh.h>
+
+static int emma2rh_sw_irq_base = -1;
+static int emma2rh_gpio_irq_base = -1;
+
+void ll_emma2rh_sw_irq_enable(int reg);
+void ll_emma2rh_sw_irq_disable(int reg);
+void ll_emma2rh_gpio_irq_enable(int reg);
+void ll_emma2rh_gpio_irq_disable(int reg);
+
+static void emma2rh_sw_irq_enable(unsigned int irq)
+{
+	ll_emma2rh_sw_irq_enable(irq - emma2rh_sw_irq_base);
+}
+
+static void emma2rh_sw_irq_disable(unsigned int irq)
+{
+	ll_emma2rh_sw_irq_disable(irq - emma2rh_sw_irq_base);
+}
+
+static unsigned int emma2rh_sw_irq_startup(unsigned int irq)
+{
+	emma2rh_sw_irq_enable(irq);
+	return 0;
+}
+
+#define emma2rh_sw_irq_shutdown emma2rh_sw_irq_disable
+
+static void emma2rh_sw_irq_ack(unsigned int irq)
+{
+	ll_emma2rh_sw_irq_disable(irq - emma2rh_sw_irq_base);
+}
+
+static void emma2rh_sw_irq_end(unsigned int irq)
+{
+	if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS)))
+		ll_emma2rh_sw_irq_enable(irq - emma2rh_sw_irq_base);
+}
+
+struct irq_chip emma2rh_sw_irq_controller = {
+	.typename = "emma2rh_sw_irq",
+	.startup = emma2rh_sw_irq_startup,
+	.shutdown = emma2rh_sw_irq_shutdown,
+	.enable = emma2rh_sw_irq_enable,
+	.disable = emma2rh_sw_irq_disable,
+	.ack = emma2rh_sw_irq_ack,
+	.end = emma2rh_sw_irq_end,
+	.set_affinity = NULL,
+};
+
+void emma2rh_sw_irq_init(u32 irq_base)
+{
+	u32 i;
+
+	for (i = irq_base; i < irq_base + NUM_EMMA2RH_IRQ_SW; i++) {
+		irq_desc[i].status = IRQ_DISABLED;
+		irq_desc[i].action = NULL;
+		irq_desc[i].depth = 2;
+		irq_desc[i].handler = &emma2rh_sw_irq_controller;
+	}
+
+	emma2rh_sw_irq_base = irq_base;
+}
+
+void ll_emma2rh_sw_irq_enable(int irq)
+{
+	u32 reg;
+
+	db_assert(irq >= 0);
+	db_assert(irq < NUM_EMMA2RH_IRQ_SW);
+
+	reg = emma2rh_in32(EMMA2RH_BHIF_SW_INT_EN);
+	reg |= 1 << irq;
+	emma2rh_out32(EMMA2RH_BHIF_SW_INT_EN, reg);
+}
+
+void ll_emma2rh_sw_irq_disable(int irq)
+{
+	u32 reg;
+
+	db_assert(irq >= 0);
+	db_assert(irq < 32);
+
+	reg = emma2rh_in32(EMMA2RH_BHIF_SW_INT_EN);
+	reg &= ~(1 << irq);
+	emma2rh_out32(EMMA2RH_BHIF_SW_INT_EN, reg);
+}
+
+static void emma2rh_gpio_irq_enable(unsigned int irq)
+{
+	ll_emma2rh_gpio_irq_enable(irq - emma2rh_gpio_irq_base);
+}
+
+static void emma2rh_gpio_irq_disable(unsigned int irq)
+{
+	ll_emma2rh_gpio_irq_disable(irq - emma2rh_gpio_irq_base);
+}
+
+static unsigned int emma2rh_gpio_irq_startup(unsigned int irq)
+{
+	emma2rh_gpio_irq_enable(irq);
+	return 0;
+}
+
+#define emma2rh_gpio_irq_shutdown emma2rh_gpio_irq_disable
+
+static void emma2rh_gpio_irq_ack(unsigned int irq)
+{
+	irq -= emma2rh_gpio_irq_base;
+	emma2rh_out32(EMMA2RH_GPIO_INT_ST, ~(1 << irq));
+	ll_emma2rh_gpio_irq_disable(irq);
+}
+
+static void emma2rh_gpio_irq_end(unsigned int irq)
+{
+	if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS)))
+		ll_emma2rh_gpio_irq_enable(irq - emma2rh_gpio_irq_base);
+}
+
+struct irq_chip emma2rh_gpio_irq_controller = {
+	.typename = "emma2rh_gpio_irq",
+	.startup = emma2rh_gpio_irq_startup,
+	.shutdown = emma2rh_gpio_irq_shutdown,
+	.enable = emma2rh_gpio_irq_enable,
+	.disable = emma2rh_gpio_irq_disable,
+	.ack = emma2rh_gpio_irq_ack,
+	.end = emma2rh_gpio_irq_end,
+	.set_affinity = NULL,
+};
+
+void emma2rh_gpio_irq_init(u32 irq_base)
+{
+	u32 i;
+
+	for (i = irq_base; i < irq_base + NUM_EMMA2RH_IRQ_GPIO; i++) {
+		irq_desc[i].status = IRQ_DISABLED;
+		irq_desc[i].action = NULL;
+		irq_desc[i].depth = 2;
+		irq_desc[i].handler = &emma2rh_gpio_irq_controller;
+	}
+
+	emma2rh_gpio_irq_base = irq_base;
+}
+
+void ll_emma2rh_gpio_irq_enable(int irq)
+{
+	u32 reg;
+
+	db_assert(irq >= 0);
+	db_assert(irq < NUM_EMMA2RH_IRQ_GPIO);
+
+	reg = emma2rh_in32(EMMA2RH_GPIO_INT_MASK);
+	reg |= 1 << irq;
+	emma2rh_out32(EMMA2RH_GPIO_INT_MASK, reg);
+}
+
+void ll_emma2rh_gpio_irq_disable(int irq)
+{
+	u32 reg;
+
+	db_assert(irq >= 0);
+	db_assert(irq < NUM_EMMA2RH_IRQ_GPIO);
+
+	reg = emma2rh_in32(EMMA2RH_GPIO_INT_MASK);
+	reg &= ~(1 << irq);
+	emma2rh_out32(EMMA2RH_GPIO_INT_MASK, reg);
+}
diff --git a/arch/mips/emma2rh/markeins/led.c b/arch/mips/emma2rh/markeins/led.c
new file mode 100644
index 000000000..b65254c1b
--- /dev/null
+++ b/arch/mips/emma2rh/markeins/led.c
@@ -0,0 +1,60 @@
+/*
+ *  arch/mips/emma2rh/markeins/led.c
+ *      This file defines the led display for Mark-eins.
+ *
+ *  Copyright (C) NEC Electronics Corporation 2004-2006
+ *
+ *  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/string.h>
+#include <asm/emma2rh/emma2rh.h>
+
+const unsigned long clear = 0x20202020;
+
+#define LED_BASE 0xb1400038
+
+void markeins_led_clear(void)
+{
+	emma2rh_out32(LED_BASE, clear);
+	emma2rh_out32(LED_BASE + 4, clear);
+}
+
+void markeins_led(const char *str)
+{
+	int i;
+	int len = strlen(str);
+
+	markeins_led_clear();
+	if (len > 8)
+		len = 8;
+
+	if (emma2rh_in32(0xb0000800) & (0x1 << 18))
+		for (i = 0; i < len; i++)
+			emma2rh_out8(LED_BASE + i, str[i]);
+	else
+		for (i = 0; i < len; i++)
+			emma2rh_out8(LED_BASE + (i & 4) + (3 - (i & 3)),
+				     str[i]);
+}
+
+void markeins_led_hex(u32 val)
+{
+	char str[10];
+
+	sprintf(str, "%08x", val);
+	markeins_led(str);
+}
diff --git a/arch/mips/emma2rh/markeins/platform.c b/arch/mips/emma2rh/markeins/platform.c
new file mode 100644
index 000000000..15cc61df3
--- /dev/null
+++ b/arch/mips/emma2rh/markeins/platform.c
@@ -0,0 +1,169 @@
+/*
+ *  arch/mips/emma2rh/markeins/platofrm.c
+ *      This file sets up platform devices for EMMA2RH Mark-eins.
+ *
+ *  Copyright(C) MontaVista Software Inc, 2006
+ *
+ *  Author: dmitry pervushin <dpervushin@ru.mvista.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/init.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/ioport.h>
+#include <linux/serial_8250.h>
+#include <linux/mtd/physmap.h>
+
+#include <asm/cpu.h>
+#include <asm/bootinfo.h>
+#include <asm/addrspace.h>
+#include <asm/time.h>
+#include <asm/bcache.h>
+#include <asm/irq.h>
+#include <asm/reboot.h>
+#include <asm/gdb-stub.h>
+#include <asm/traps.h>
+#include <asm/debug.h>
+
+#include <asm/emma2rh/emma2rh.h>
+
+
+#define I2C_EMMA2RH "emma2rh-iic" /* must be in sync with IIC driver */
+
+static struct resource i2c_emma_resources_0[] = {
+	{ NULL, EMMA2RH_IRQ_PIIC0, EMMA2RH_IRQ_PIIC0, IORESOURCE_IRQ },
+	{ NULL, KSEG1ADDR(EMMA2RH_PIIC0_BASE), KSEG1ADDR(EMMA2RH_PIIC0_BASE + 0x1000), 0 },
+};
+
+struct resource i2c_emma_resources_1[] = {
+	{ NULL, EMMA2RH_IRQ_PIIC1, EMMA2RH_IRQ_PIIC1, IORESOURCE_IRQ },
+	{ NULL, KSEG1ADDR(EMMA2RH_PIIC1_BASE), KSEG1ADDR(EMMA2RH_PIIC1_BASE + 0x1000), 0 },
+};
+
+struct resource i2c_emma_resources_2[] = {
+	{ NULL, EMMA2RH_IRQ_PIIC2, EMMA2RH_IRQ_PIIC2, IORESOURCE_IRQ },
+	{ NULL, KSEG1ADDR(EMMA2RH_PIIC2_BASE), KSEG1ADDR(EMMA2RH_PIIC2_BASE + 0x1000), 0 },
+};
+
+struct platform_device i2c_emma_devices[] = {
+	[0] = {
+		.name = I2C_EMMA2RH,
+		.id = 0,
+		.resource = i2c_emma_resources_0,
+		.num_resources = ARRAY_SIZE(i2c_emma_resources_0),
+	},
+	[1] = {
+		.name = I2C_EMMA2RH,
+		.id = 1,
+		.resource = i2c_emma_resources_1,
+		.num_resources = ARRAY_SIZE(i2c_emma_resources_1),
+	},
+	[2] = {
+		.name = I2C_EMMA2RH,
+		.id = 2,
+		.resource = i2c_emma_resources_2,
+		.num_resources = ARRAY_SIZE(i2c_emma_resources_2),
+	},
+};
+
+#define EMMA2RH_SERIAL_CLOCK 18544000
+#define EMMA2RH_SERIAL_FLAGS UPF_BOOT_AUTOCONF | UPF_SKIP_TEST
+
+static struct  plat_serial8250_port platform_serial_ports[] = {
+       [0] = {
+         .membase = (void __iomem*)KSEG1ADDR(EMMA2RH_PFUR0_BASE + 3),
+         .irq = EMMA2RH_IRQ_PFUR0,
+         .uartclk = EMMA2RH_SERIAL_CLOCK,
+         .regshift = 4,
+         .iotype = UPIO_MEM,
+         .flags = EMMA2RH_SERIAL_FLAGS,
+       },
+       [1] = {
+         .membase = (void __iomem*)KSEG1ADDR(EMMA2RH_PFUR1_BASE + 3),
+         .irq = EMMA2RH_IRQ_PFUR1,
+         .uartclk = EMMA2RH_SERIAL_CLOCK,
+         .regshift = 4,
+         .iotype = UPIO_MEM,
+         .flags = EMMA2RH_SERIAL_FLAGS,
+       },
+       [2] = {
+         .membase = (void __iomem*)KSEG1ADDR(EMMA2RH_PFUR2_BASE + 3),
+         .irq = EMMA2RH_IRQ_PFUR2,
+         .uartclk = EMMA2RH_SERIAL_CLOCK,
+         .regshift = 4,
+         .iotype = UPIO_MEM,
+         .flags = EMMA2RH_SERIAL_FLAGS,
+       },
+       [3] = {
+	 .flags = 0,
+       },
+};
+
+static struct  platform_device serial_emma = {
+	.name = "serial8250",
+	.dev = {
+		.platform_data = &platform_serial_ports,
+	},
+};
+
+static struct platform_device *devices[] = {
+	&i2c_emma_devices[0],
+	&i2c_emma_devices[1],
+	&i2c_emma_devices[2],
+	&serial_emma,
+};
+
+static struct mtd_partition markeins_parts[] = {
+	[0] = {
+		.name = "RootFS",
+		.offset = 0x00000000,
+		.size = 0x00c00000,
+	},
+	[1] = {
+		.name = "boot code area",
+		.offset = MTDPART_OFS_APPEND,
+		.size = 0x00100000,
+	},
+	[2] = {
+		.name = "kernel image",
+		.offset = MTDPART_OFS_APPEND,
+		.size = 0x00300000,
+	},
+	[3] = {
+		.name = "RootFS2",
+		.offset = MTDPART_OFS_APPEND,
+		.size = 0x00c00000,
+	},
+	[4] = {
+		.name = "boot code area2",
+		.offset = MTDPART_OFS_APPEND,
+		.size = 0x00100000,
+	},
+	[5] = {
+		.name = "kernel image2",
+		.offset = MTDPART_OFS_APPEND,
+		.size = MTDPART_SIZ_FULL,
+	},
+};
+
+static int __init platform_devices_setup(void)
+{
+	physmap_set_partitions(markeins_parts, ARRAY_SIZE(markeins_parts));
+	return platform_add_devices(devices, ARRAY_SIZE(devices));
+}
+
+arch_initcall(platform_devices_setup);
+
diff --git a/arch/mips/emma2rh/markeins/setup.c b/arch/mips/emma2rh/markeins/setup.c
new file mode 100644
index 000000000..b29a44739
--- /dev/null
+++ b/arch/mips/emma2rh/markeins/setup.c
@@ -0,0 +1,180 @@
+/*
+ *  arch/mips/emma2rh/markeins/setup.c
+ *      This file is setup for EMMA2RH Mark-eins.
+ *
+ *  Copyright (C) NEC Electronics Corporation 2004-2006
+ *
+ *  This file is based on the arch/mips/ddb5xxx/ddb5477/setup.c.
+ *
+ *	Copyright 2001 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 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/kernel.h>
+#include <linux/types.h>
+#include <linux/initrd.h>
+#include <linux/irq.h>
+#include <linux/ide.h>
+#include <linux/ioport.h>
+#include <linux/param.h>	/* for HZ */
+#include <linux/root_dev.h>
+#include <linux/serial.h>
+#include <linux/serial_core.h>
+
+#include <asm/cpu.h>
+#include <asm/bootinfo.h>
+#include <asm/addrspace.h>
+#include <asm/time.h>
+#include <asm/bcache.h>
+#include <asm/irq.h>
+#include <asm/reboot.h>
+#include <asm/gdb-stub.h>
+#include <asm/traps.h>
+#include <asm/debug.h>
+
+#include <asm/emma2rh/emma2rh.h>
+
+#define	USE_CPU_COUNTER_TIMER	/* whether we use cpu counter */
+
+extern void markeins_led(const char *);
+
+static int bus_frequency = 0;
+
+static void markeins_machine_restart(char *command)
+{
+	static void (*back_to_prom) (void) = (void (*)(void))0xbfc00000;
+
+	printk("cannot EMMA2RH Mark-eins restart.\n");
+	markeins_led("restart.");
+	back_to_prom();
+}
+
+static void markeins_machine_halt(void)
+{
+	printk("EMMA2RH Mark-eins halted.\n");
+	markeins_led("halted.");
+	while (1) ;
+}
+
+static void markeins_machine_power_off(void)
+{
+	printk("EMMA2RH Mark-eins halted. Please turn off the power.\n");
+	markeins_led("poweroff.");
+	while (1) ;
+}
+
+static unsigned long clock[4] = { 166500000, 187312500, 199800000, 210600000 };
+
+static unsigned int __init detect_bus_frequency(unsigned long rtc_base)
+{
+	u32 reg;
+
+	/* detect from boot strap */
+	reg = emma2rh_in32(EMMA2RH_BHIF_STRAP_0);
+	reg = (reg >> 4) & 0x3;
+	return clock[reg];
+}
+
+static void __init emma2rh_time_init(void)
+{
+	u32 reg;
+	if (bus_frequency == 0)
+		bus_frequency = detect_bus_frequency(0);
+
+	reg = emma2rh_in32(EMMA2RH_BHIF_STRAP_0);
+	if ((reg & 0x3) == 0)
+		reg = (reg >> 6) & 0x3;
+	else {
+		reg = emma2rh_in32(EMMA2RH_BHIF_MAIN_CTRL);
+		reg = (reg >> 4) & 0x3;
+	}
+	mips_hpt_frequency = (bus_frequency * (4 + reg)) / 4 / 2;
+}
+
+void __init plat_timer_setup(struct irqaction *irq)
+{
+	/* we are using the cpu counter for timer interrupts */
+	setup_irq(CPU_IRQ_BASE + 7, irq);
+}
+
+static void markeins_board_init(void);
+extern void markeins_irq_setup(void);
+
+static void inline __init markeins_sio_setup(void)
+{
+#ifdef CONFIG_KGDB_8250
+	struct uart_port emma_port;
+
+	memset(&emma_port, 0, sizeof(emma_port));
+
+	emma_port.flags =
+	    UPF_BOOT_AUTOCONF | UPF_SKIP_TEST;
+	emma_port.iotype = UPIO_MEM;
+	emma_port.regshift = 4;	/* I/O addresses are every 8 bytes */
+	emma_port.uartclk = 18544000;	/* Clock rate of the chip */
+
+	emma_port.line = 0;
+	emma_port.mapbase = KSEG1ADDR(EMMA2RH_PFUR0_BASE + 3);
+	emma_port.membase = (u8*)emma_port.mapbase;
+	early_serial_setup(&emma_port);
+
+	emma_port.line = 1;
+	emma_port.mapbase = KSEG1ADDR(EMMA2RH_PFUR1_BASE + 3);
+	emma_port.membase = (u8*)emma_port.mapbase;
+	early_serial_setup(&emma_port);
+
+	emma_port.irq = EMMA2RH_IRQ_PFUR1;
+	kgdb8250_add_port(1, &emma_port);
+#endif
+}
+
+void __init plat_mem_setup(void)
+{
+	/* initialize board - we don't trust the loader */
+	markeins_board_init();
+
+	set_io_port_base(KSEG1ADDR(EMMA2RH_PCI_IO_BASE));
+
+	board_time_init = emma2rh_time_init;
+
+	_machine_restart = markeins_machine_restart;
+	_machine_halt = markeins_machine_halt;
+	pm_power_off = markeins_machine_power_off;
+
+	/* setup resource limits */
+	ioport_resource.start = EMMA2RH_PCI_IO_BASE;
+	ioport_resource.end = EMMA2RH_PCI_IO_BASE + EMMA2RH_PCI_IO_SIZE - 1;
+	iomem_resource.start = EMMA2RH_IO_BASE;
+	iomem_resource.end = EMMA2RH_ROM_BASE - 1;
+
+	/* Reboot on panic */
+	panic_timeout = 180;
+
+	markeins_sio_setup();
+}
+
+static void __init markeins_board_init(void)
+{
+	u32 val;
+
+	val = emma2rh_in32(EMMA2RH_PBRD_INT_EN);	/* open serial interrupts. */
+	emma2rh_out32(EMMA2RH_PBRD_INT_EN, val | 0xaa);
+	val = emma2rh_in32(EMMA2RH_PBRD_CLKSEL);	/* set serial clocks. */
+	emma2rh_out32(EMMA2RH_PBRD_CLKSEL, val | 0x5);	/* 18MHz */
+	emma2rh_out32(EMMA2RH_PCI_CONTROL, 0);
+
+	markeins_led("MVL E2RH");
+}
diff --git a/arch/mips/gt64120/wrppmc/Makefile b/arch/mips/gt64120/wrppmc/Makefile
new file mode 100644
index 000000000..7cf522055
--- /dev/null
+++ b/arch/mips/gt64120/wrppmc/Makefile
@@ -0,0 +1,14 @@
+#
+# 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 2006 Wind River System, Inc.
+# Author: Rongkai.Zhan <rongkai.zhan@windriver.com>
+#
+# Makefile for the Wind River MIPS 4KC PPMC Eval Board
+#
+
+obj-y += irq.o reset.o setup.o time.o pci.o
+
+EXTRA_AFLAGS := $(CFLAGS)
diff --git a/arch/mips/gt64120/wrppmc/irq.c b/arch/mips/gt64120/wrppmc/irq.c
new file mode 100644
index 000000000..8d75a43ce
--- /dev/null
+++ b/arch/mips/gt64120/wrppmc/irq.c
@@ -0,0 +1,69 @@
+/*
+ * irq.c: GT64120 Interrupt Controller
+ *
+ * Copyright (C) 2006, Wind River System Inc.
+ * Author: Rongkai.Zhan, <rongkai.zhan@windriver.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.
+ */
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/kernel_stat.h>
+#include <linux/module.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/timex.h>
+#include <linux/slab.h>
+#include <linux/random.h>
+#include <linux/bitops.h>
+#include <asm/bootinfo.h>
+#include <asm/io.h>
+#include <asm/bitops.h>
+#include <asm/mipsregs.h>
+#include <asm/system.h>
+#include <asm/irq_cpu.h>
+#include <asm/gt64120.h>
+
+asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
+{
+	unsigned int pending = read_c0_status() & read_c0_cause();
+
+	if (pending & STATUSF_IP7)
+		do_IRQ(WRPPMC_MIPS_TIMER_IRQ, regs);	/* CPU Compare/Count internal timer */
+	else if (pending & STATUSF_IP6)
+		do_IRQ(WRPPMC_UART16550_IRQ, regs);	/* UART 16550 port */
+	else if (pending & STATUSF_IP3)
+		do_IRQ(WRPPMC_PCI_INTA_IRQ, regs);	/* PCI INT_A */
+	else
+		spurious_interrupt(regs);
+}
+
+/**
+ * Initialize GT64120 Interrupt Controller
+ */
+void gt64120_init_pic(void)
+{
+	/* clear CPU Interrupt Cause Registers */
+	GT_WRITE(GT_INTRCAUSE_OFS, (0x1F << 21));
+	GT_WRITE(GT_HINTRCAUSE_OFS, 0x00);
+
+	/* Disable all interrupts from GT64120 bridge chip */
+	GT_WRITE(GT_INTRMASK_OFS, 0x00);
+	GT_WRITE(GT_HINTRMASK_OFS, 0x00);
+	GT_WRITE(GT_PCI0_ICMASK_OFS, 0x00);
+	GT_WRITE(GT_PCI0_HICMASK_OFS, 0x00);
+}
+
+void __init arch_init_irq(void)
+{
+	/* IRQ 0 - 7 are for MIPS common irq_cpu controller */
+	mips_cpu_irq_init(0);
+
+	gt64120_init_pic();
+}
diff --git a/arch/mips/gt64120/wrppmc/pci.c b/arch/mips/gt64120/wrppmc/pci.c
new file mode 100644
index 000000000..2fbe93467
--- /dev/null
+++ b/arch/mips/gt64120/wrppmc/pci.c
@@ -0,0 +1,53 @@
+/*
+ * pci.c: GT64120 PCI support.
+ *
+ * Copyright (C) 2006, Wind River System Inc. Rongkai.Zhan <rongkai.zhan@windriver.com>
+ *
+ * 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.
+ */
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <asm/gt64120.h>
+
+extern struct pci_ops gt64120_pci_ops;
+
+static struct resource pci0_io_resource = {
+	.name  = "pci_0 io",
+	.start = GT_PCI_IO_BASE,
+	.end   = GT_PCI_IO_BASE + GT_PCI_IO_SIZE - 1,
+	.flags = IORESOURCE_IO,
+};
+
+static struct resource pci0_mem_resource = {
+	.name  = "pci_0 memory",
+	.start = GT_PCI_MEM_BASE,
+	.end   = GT_PCI_MEM_BASE + GT_PCI_MEM_SIZE - 1,
+	.flags = IORESOURCE_MEM,
+};
+
+static struct pci_controller hose_0 = {
+	.pci_ops	= &gt64120_pci_ops,
+	.io_resource	= &pci0_io_resource,
+	.mem_resource	= &pci0_mem_resource,
+};
+
+static int __init gt64120_pci_init(void)
+{
+	u32 tmp;
+
+	tmp = GT_READ(GT_PCI0_CMD_OFS);		/* Huh??? -- Ralf  */
+	tmp = GT_READ(GT_PCI0_BARE_OFS);
+
+	/* reset the whole PCI I/O space range */
+	ioport_resource.start = GT_PCI_IO_BASE;
+	ioport_resource.end = GT_PCI_IO_BASE + GT_PCI_IO_SIZE - 1;
+
+	register_pci_controller(&hose_0);
+	return 0;
+}
+
+arch_initcall(gt64120_pci_init);
diff --git a/arch/mips/gt64120/wrppmc/reset.c b/arch/mips/gt64120/wrppmc/reset.c
new file mode 100644
index 000000000..b97039c6d
--- /dev/null
+++ b/arch/mips/gt64120/wrppmc/reset.c
@@ -0,0 +1,50 @@
+/*
+ * 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) 1997 Ralf Baechle
+ */
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <asm/io.h>
+#include <asm/pgtable.h>
+#include <asm/processor.h>
+#include <asm/reboot.h>
+#include <asm/system.h>
+#include <asm/cacheflush.h>
+
+void wrppmc_machine_restart(char *command)
+{
+	/*
+	 * Ouch, we're still alive ... This time we take the silver bullet ...
+	 * ... and find that we leave the hardware in a state in which the
+	 * kernel in the flush locks up somewhen during of after the PCI
+	 * detection stuff.
+	 */
+	local_irq_disable();
+	set_c0_status(ST0_BEV | ST0_ERL);
+	change_c0_config(CONF_CM_CMASK, CONF_CM_UNCACHED);
+	flush_cache_all();
+	write_c0_wired(0);
+	__asm__ __volatile__("jr\t%0"::"r"(0xbfc00000));
+}
+
+void wrppmc_machine_halt(void)
+{
+	local_irq_disable();
+
+	printk(KERN_NOTICE "You can safely turn off the power\n");
+	while (1) {
+		__asm__(
+			".set\tmips3\n\t"
+			"wait\n\t"
+			".set\tmips0"
+		);
+	}
+}
+
+void wrppmc_machine_power_off(void)
+{
+	wrppmc_machine_halt();
+}
diff --git a/arch/mips/gt64120/wrppmc/setup.c b/arch/mips/gt64120/wrppmc/setup.c
new file mode 100644
index 000000000..429afc400
--- /dev/null
+++ b/arch/mips/gt64120/wrppmc/setup.c
@@ -0,0 +1,170 @@
+/*
+ * setup.c: Setup pointers to hardware dependent routines.
+ *
+ * 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, 1997, 2004 by Ralf Baechle (ralf@linux-mips.org)
+ * Copyright (C) 2006, Wind River System Inc. Rongkai.zhan <rongkai.zhan@windriver.com>
+ */
+#include <linux/init.h>
+#include <linux/string.h>
+#include <linux/kernel.h>
+#include <linux/tty.h>
+#include <linux/serial.h>
+#include <linux/serial_core.h>
+#include <linux/pm.h>
+
+#include <asm/io.h>
+#include <asm/bootinfo.h>
+#include <asm/reboot.h>
+#include <asm/time.h>
+#include <asm/gt64120.h>
+
+unsigned long gt64120_base = KSEG1ADDR(0x14000000);
+
+#ifdef WRPPMC_EARLY_DEBUG
+
+static volatile unsigned char * wrppmc_led = \
+	(volatile unsigned char *)KSEG1ADDR(WRPPMC_LED_BASE);
+
+/*
+ * PPMC LED control register:
+ * -) bit[0] controls DS1 LED (1 - OFF, 0 - ON)
+ * -) bit[1] controls DS2 LED (1 - OFF, 0 - ON)
+ * -) bit[2] controls DS4 LED (1 - OFF, 0 - ON)
+ */
+void wrppmc_led_on(int mask)
+{
+	unsigned char value = *wrppmc_led;
+
+	value &= (0xF8 | mask);
+	*wrppmc_led = value;
+}
+
+/* If mask = 0, turn off all LEDs */
+void wrppmc_led_off(int mask)
+{
+	unsigned char value = *wrppmc_led;
+
+	value |= (0x7 & mask);
+	*wrppmc_led = value;
+}
+
+/*
+ * We assume that bootloader has initialized UART16550 correctly
+ */
+void __init wrppmc_early_putc(char ch)
+{
+	static volatile unsigned char *wrppmc_uart = \
+		(volatile unsigned char *)KSEG1ADDR(WRPPMC_UART16550_BASE);
+	unsigned char value;
+
+	/* Wait until Transmit-Holding-Register is empty */
+	while (1) {
+		value = *(wrppmc_uart + 5);
+		if (value & 0x20)
+			break;
+	}
+
+	*wrppmc_uart = ch;
+}
+
+void __init wrppmc_early_printk(const char *fmt, ...)
+{
+	static char pbuf[256] = {'\0', };
+	char *ch = pbuf;
+	va_list args;
+	unsigned int i;
+
+	memset(pbuf, 0, 256);
+	va_start(args, fmt);
+	i = vsprintf(pbuf, fmt, args);
+	va_end(args);
+
+	/* Print the string */
+	while (*ch != '\0') {
+		wrppmc_early_putc(*ch);
+		/* if print '\n', also print '\r' */
+		if (*ch++ == '\n')
+			wrppmc_early_putc('\r');
+	}
+}
+#endif /* WRPPMC_EARLY_DEBUG */
+
+unsigned long __init prom_free_prom_memory(void)
+{
+	return 0;
+}
+
+#ifdef CONFIG_SERIAL_8250
+static void wrppmc_setup_serial(void)
+{
+	struct uart_port up;
+
+	memset(&up, 0x00, sizeof(struct uart_port));
+
+	/*
+	 * A note about mapbase/membase
+	 * -) mapbase is the physical address of the IO port.
+	 * -) membase is an 'ioremapped' cookie.
+	 */
+	up.line = 0;
+	up.type = PORT_16550;
+	up.iotype = UPIO_MEM;
+	up.mapbase = WRPPMC_UART16550_BASE;
+	up.membase = ioremap(up.mapbase, 8);
+	up.irq = WRPPMC_UART16550_IRQ;
+	up.uartclk = WRPPMC_UART16550_CLOCK;
+	up.flags = UPF_SKIP_TEST/* | UPF_BOOT_AUTOCONF */;
+	up.regshift = 0;
+
+	early_serial_setup(&up);
+}
+#endif
+
+void __init plat_mem_setup(void)
+{
+	extern void wrppmc_time_init(void);
+	extern void wrppmc_machine_restart(char *command);
+	extern void wrppmc_machine_halt(void);
+	extern void wrppmc_machine_power_off(void);
+
+	_machine_restart = wrppmc_machine_restart;
+	_machine_halt	 = wrppmc_machine_halt;
+	pm_power_off	 = wrppmc_machine_power_off;
+
+	/* Use MIPS Count/Compare Timer */
+	board_time_init   = wrppmc_time_init;
+
+	/* This makes the operations of 'in/out[bwl]' to the
+	 * physical address ( < KSEG0) can work via KSEG1
+	 */
+	set_io_port_base(KSEG1);
+
+#ifdef CONFIG_SERIAL_8250
+	wrppmc_setup_serial();
+#endif
+}
+
+const char *get_system_type(void)
+{
+	return "Wind River PPMC (GT64120)";
+}
+
+/*
+ * Initializes basic routines and structures pointers, memory size (as
+ * given by the bios and saves the command line.
+ */
+void __init prom_init(void)
+{
+	mips_machgroup = MACH_GROUP_GALILEO;
+	mips_machtype = MACH_EV64120A;
+
+	add_memory_region(WRPPMC_SDRAM_SCS0_BASE, WRPPMC_SDRAM_SCS0_SIZE, BOOT_MEM_RAM);
+	add_memory_region(WRPPMC_BOOTROM_BASE, WRPPMC_BOOTROM_SIZE, BOOT_MEM_ROM_DATA);
+
+	wrppmc_early_printk("prom_init: GT64120 SDRAM Bank 0: 0x%x - 0x%08lx\n",
+			WRPPMC_SDRAM_SCS0_BASE, (WRPPMC_SDRAM_SCS0_BASE + WRPPMC_SDRAM_SCS0_SIZE));
+}
diff --git a/arch/mips/gt64120/wrppmc/time.c b/arch/mips/gt64120/wrppmc/time.c
new file mode 100644
index 000000000..5b440859b
--- /dev/null
+++ b/arch/mips/gt64120/wrppmc/time.c
@@ -0,0 +1,52 @@
+/*
+ * time.c: MIPS CPU Count/Compare timer hookup
+ *
+ * Author: Mark.Zhan, <rongkai.zhan@windriver.com>
+ *
+ * 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, 1997, 2004 by Ralf Baechle (ralf@linux-mips.org)
+ * Copyright (C) 2006, Wind River System Inc.
+ */
+#include <linux/init.h>
+#include <linux/string.h>
+#include <linux/kernel.h>
+#include <linux/param.h>	/* for HZ */
+#include <linux/irq.h>
+#include <linux/timex.h>
+#include <linux/interrupt.h>
+
+#include <asm/reboot.h>
+#include <asm/time.h>
+#include <asm/io.h>
+#include <asm/bootinfo.h>
+#include <asm/gt64120.h>
+
+#define WRPPMC_CPU_CLK_FREQ 40000000 /* 40MHZ */
+
+void __init plat_timer_setup(struct irqaction *irq)
+{
+	/* Install ISR for timer interrupt */
+	setup_irq(WRPPMC_MIPS_TIMER_IRQ, irq);
+}
+
+/*
+ * Estimate CPU frequency.  Sets mips_hpt_frequency as a side-effect
+ *
+ * NOTE: We disable all GT64120 timers, and use MIPS processor internal
+ * timer as the source of kernel clock tick.
+ */
+void __init wrppmc_time_init(void)
+{
+	/* Disable GT64120 timers */
+	GT_WRITE(GT_TC_CONTROL_OFS, 0x00);
+	GT_WRITE(GT_TC0_OFS, 0x00);
+	GT_WRITE(GT_TC1_OFS, 0x00);
+	GT_WRITE(GT_TC2_OFS, 0x00);
+	GT_WRITE(GT_TC3_OFS, 0x00);
+
+	/* Use MIPS compare/count internal timer */
+	mips_hpt_frequency = WRPPMC_CPU_CLK_FREQ;
+}
diff --git a/arch/mips/kernel/apm.c b/arch/mips/kernel/apm.c
new file mode 100644
index 000000000..528e73104
--- /dev/null
+++ b/arch/mips/kernel/apm.c
@@ -0,0 +1,604 @@
+/*
+ * bios-less APM driver for MIPS Linux
+ *  Jamey Hicks <jamey@crl.dec.com>
+ *  adapted from the APM BIOS driver for Linux by Stephen Rothwell (sfr@linuxcare.com)
+ *
+ * APM 1.2 Reference:
+ *   Intel Corporation, Microsoft Corporation. Advanced Power Management
+ *   (APM) BIOS Interface Specification, Revision 1.2, February 1996.
+ *
+ * [This document is available from Microsoft at:
+ *    http://www.microsoft.com/hwdev/busbios/amp_12.htm]
+ */
+#include <linux/module.h>
+#include <linux/poll.h>
+#include <linux/timer.h>
+#include <linux/slab.h>
+#include <linux/proc_fs.h>
+#include <linux/miscdevice.h>
+#include <linux/apm_bios.h>
+#include <linux/capability.h>
+#include <linux/sched.h>
+#include <linux/pm.h>
+#include <linux/device.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/init.h>
+#include <linux/completion.h>
+
+#include <asm/apm.h> /* apm_power_info */
+#include <asm/system.h>
+
+/*
+ * The apm_bios device is one of the misc char devices.
+ * This is its minor number.
+ */
+#define APM_MINOR_DEV	134
+
+/*
+ * See Documentation/Config.help for the configuration options.
+ *
+ * Various options can be changed at boot time as follows:
+ * (We allow underscores for compatibility with the modules code)
+ *	apm=on/off			enable/disable APM
+ */
+
+/*
+ * Maximum number of events stored
+ */
+#define APM_MAX_EVENTS		16
+
+struct apm_queue {
+	unsigned int		event_head;
+	unsigned int		event_tail;
+	apm_event_t		events[APM_MAX_EVENTS];
+};
+
+/*
+ * The per-file APM data
+ */
+struct apm_user {
+	struct list_head	list;
+
+	unsigned int		suser: 1;
+	unsigned int		writer: 1;
+	unsigned int		reader: 1;
+
+	int			suspend_result;
+	unsigned int		suspend_state;
+#define SUSPEND_NONE	0		/* no suspend pending */
+#define SUSPEND_PENDING	1		/* suspend pending read */
+#define SUSPEND_READ	2		/* suspend read, pending ack */
+#define SUSPEND_ACKED	3		/* suspend acked */
+#define SUSPEND_DONE	4		/* suspend completed */
+
+	struct apm_queue	queue;
+};
+
+/*
+ * Local variables
+ */
+static int suspends_pending;
+static int apm_disabled;
+static int mips_apm_active;
+
+static DECLARE_WAIT_QUEUE_HEAD(apm_waitqueue);
+static DECLARE_WAIT_QUEUE_HEAD(apm_suspend_waitqueue);
+
+/*
+ * This is a list of everyone who has opened /dev/apm_bios
+ */
+static DECLARE_RWSEM(user_list_lock);
+static LIST_HEAD(apm_user_list);
+
+/*
+ * kapmd info.  kapmd provides us a process context to handle
+ * "APM" events within - specifically necessary if we're going
+ * to be suspending the system.
+ */
+static DECLARE_WAIT_QUEUE_HEAD(kapmd_wait);
+static DECLARE_COMPLETION(kapmd_exit);
+static DEFINE_SPINLOCK(kapmd_queue_lock);
+static struct apm_queue kapmd_queue;
+
+
+static const char driver_version[] = "1.13";	/* no spaces */
+
+
+
+/*
+ * Compatibility cruft until the IPAQ people move over to the new
+ * interface.
+ */
+static void __apm_get_power_status(struct apm_power_info *info)
+{
+}
+
+/*
+ * This allows machines to provide their own "apm get power status" function.
+ */
+void (*apm_get_power_status)(struct apm_power_info *) = __apm_get_power_status;
+EXPORT_SYMBOL(apm_get_power_status);
+
+
+/*
+ * APM event queue management.
+ */
+static inline int queue_empty(struct apm_queue *q)
+{
+	return q->event_head == q->event_tail;
+}
+
+static inline apm_event_t queue_get_event(struct apm_queue *q)
+{
+	q->event_tail = (q->event_tail + 1) % APM_MAX_EVENTS;
+	return q->events[q->event_tail];
+}
+
+static void queue_add_event(struct apm_queue *q, apm_event_t event)
+{
+	q->event_head = (q->event_head + 1) % APM_MAX_EVENTS;
+	if (q->event_head == q->event_tail) {
+		static int notified;
+
+		if (notified++ == 0)
+		    printk(KERN_ERR "apm: an event queue overflowed\n");
+		q->event_tail = (q->event_tail + 1) % APM_MAX_EVENTS;
+	}
+	q->events[q->event_head] = event;
+}
+
+static void queue_event_one_user(struct apm_user *as, apm_event_t event)
+{
+	if (as->suser && as->writer) {
+		switch (event) {
+		case APM_SYS_SUSPEND:
+		case APM_USER_SUSPEND:
+			/*
+			 * If this user already has a suspend pending,
+			 * don't queue another one.
+			 */
+			if (as->suspend_state != SUSPEND_NONE)
+				return;
+
+			as->suspend_state = SUSPEND_PENDING;
+			suspends_pending++;
+			break;
+		}
+	}
+	queue_add_event(&as->queue, event);
+}
+
+static void queue_event(apm_event_t event, struct apm_user *sender)
+{
+	struct apm_user *as;
+
+	down_read(&user_list_lock);
+	list_for_each_entry(as, &apm_user_list, list) {
+		if (as != sender && as->reader)
+			queue_event_one_user(as, event);
+	}
+	up_read(&user_list_lock);
+	wake_up_interruptible(&apm_waitqueue);
+}
+
+static void apm_suspend(void)
+{
+	struct apm_user *as;
+	int err = pm_suspend(PM_SUSPEND_MEM);
+
+	/*
+	 * Anyone on the APM queues will think we're still suspended.
+	 * Send a message so everyone knows we're now awake again.
+	 */
+	queue_event(APM_NORMAL_RESUME, NULL);
+
+	/*
+	 * Finally, wake up anyone who is sleeping on the suspend.
+	 */
+	down_read(&user_list_lock);
+	list_for_each_entry(as, &apm_user_list, list) {
+		as->suspend_result = err;
+		as->suspend_state = SUSPEND_DONE;
+	}
+	up_read(&user_list_lock);
+
+	wake_up(&apm_suspend_waitqueue);
+}
+
+static ssize_t apm_read(struct file *fp, char __user *buf, size_t count, loff_t *ppos)
+{
+	struct apm_user *as = fp->private_data;
+	apm_event_t event;
+	int i = count, ret = 0;
+
+	if (count < sizeof(apm_event_t))
+		return -EINVAL;
+
+	if (queue_empty(&as->queue) && fp->f_flags & O_NONBLOCK)
+		return -EAGAIN;
+
+	wait_event_interruptible(apm_waitqueue, !queue_empty(&as->queue));
+
+	while ((i >= sizeof(event)) && !queue_empty(&as->queue)) {
+		event = queue_get_event(&as->queue);
+
+		ret = -EFAULT;
+		if (copy_to_user(buf, &event, sizeof(event)))
+			break;
+
+		if (event == APM_SYS_SUSPEND || event == APM_USER_SUSPEND)
+			as->suspend_state = SUSPEND_READ;
+
+		buf += sizeof(event);
+		i -= sizeof(event);
+	}
+
+	if (i < count)
+		ret = count - i;
+
+	return ret;
+}
+
+static unsigned int apm_poll(struct file *fp, poll_table * wait)
+{
+	struct apm_user *as = fp->private_data;
+
+	poll_wait(fp, &apm_waitqueue, wait);
+	return queue_empty(&as->queue) ? 0 : POLLIN | POLLRDNORM;
+}
+
+/*
+ * apm_ioctl - handle APM ioctl
+ *
+ * APM_IOC_SUSPEND
+ *   This IOCTL is overloaded, and performs two functions.  It is used to:
+ *     - initiate a suspend
+ *     - acknowledge a suspend read from /dev/apm_bios.
+ *   Only when everyone who has opened /dev/apm_bios with write permission
+ *   has acknowledge does the actual suspend happen.
+ */
+static int
+apm_ioctl(struct inode * inode, struct file *filp, unsigned int cmd, unsigned long arg)
+{
+	struct apm_user *as = filp->private_data;
+	unsigned long flags;
+	int err = -EINVAL;
+
+	if (!as->suser || !as->writer)
+		return -EPERM;
+
+	switch (cmd) {
+	case APM_IOC_SUSPEND:
+		as->suspend_result = -EINTR;
+
+		if (as->suspend_state == SUSPEND_READ) {
+			/*
+			 * If we read a suspend command from /dev/apm_bios,
+			 * then the corresponding APM_IOC_SUSPEND ioctl is
+			 * interpreted as an acknowledge.
+			 */
+			as->suspend_state = SUSPEND_ACKED;
+			suspends_pending--;
+		} else {
+			/*
+			 * Otherwise it is a request to suspend the system.
+			 * Queue an event for all readers, and expect an
+			 * acknowledge from all writers who haven't already
+			 * acknowledged.
+			 */
+			queue_event(APM_USER_SUSPEND, as);
+		}
+
+		/*
+		 * If there are no further acknowledges required, suspend
+		 * the system.
+		 */
+		if (suspends_pending == 0)
+			apm_suspend();
+
+		/*
+		 * Wait for the suspend/resume to complete.  If there are
+		 * pending acknowledges, we wait here for them.
+		 *
+		 * Note that we need to ensure that the PM subsystem does
+		 * not kick us out of the wait when it suspends the threads.
+		 */
+		flags = current->flags;
+		current->flags |= PF_NOFREEZE;
+
+		/*
+		 * Note: do not allow a thread which is acking the suspend
+		 * to escape until the resume is complete.
+		 */
+		if (as->suspend_state == SUSPEND_ACKED)
+			wait_event(apm_suspend_waitqueue,
+					 as->suspend_state == SUSPEND_DONE);
+		else
+			wait_event_interruptible(apm_suspend_waitqueue,
+					 as->suspend_state == SUSPEND_DONE);
+
+		current->flags = flags;
+		err = as->suspend_result;
+		as->suspend_state = SUSPEND_NONE;
+		break;
+	}
+
+	return err;
+}
+
+static int apm_release(struct inode * inode, struct file * filp)
+{
+	struct apm_user *as = filp->private_data;
+	filp->private_data = NULL;
+
+	down_write(&user_list_lock);
+	list_del(&as->list);
+	up_write(&user_list_lock);
+
+	/*
+	 * We are now unhooked from the chain.  As far as new
+	 * events are concerned, we no longer exist.  However, we
+	 * need to balance suspends_pending, which means the
+	 * possibility of sleeping.
+	 */
+	if (as->suspend_state != SUSPEND_NONE) {
+		suspends_pending -= 1;
+		if (suspends_pending == 0)
+			apm_suspend();
+	}
+
+	kfree(as);
+	return 0;
+}
+
+static int apm_open(struct inode * inode, struct file * filp)
+{
+	struct apm_user *as;
+
+	as = (struct apm_user *)kzalloc(sizeof(*as), GFP_KERNEL);
+	if (as) {
+		/*
+		 * XXX - this is a tiny bit broken, when we consider BSD
+		 * process accounting. If the device is opened by root, we
+		 * instantly flag that we used superuser privs. Who knows,
+		 * we might close the device immediately without doing a
+		 * privileged operation -- cevans
+		 */
+		as->suser = capable(CAP_SYS_ADMIN);
+		as->writer = (filp->f_mode & FMODE_WRITE) == FMODE_WRITE;
+		as->reader = (filp->f_mode & FMODE_READ) == FMODE_READ;
+
+		down_write(&user_list_lock);
+		list_add(&as->list, &apm_user_list);
+		up_write(&user_list_lock);
+
+		filp->private_data = as;
+	}
+
+	return as ? 0 : -ENOMEM;
+}
+
+static struct file_operations apm_bios_fops = {
+	.owner		= THIS_MODULE,
+	.read		= apm_read,
+	.poll		= apm_poll,
+	.ioctl		= apm_ioctl,
+	.open		= apm_open,
+	.release	= apm_release,
+};
+
+static struct miscdevice apm_device = {
+	.minor		= APM_MINOR_DEV,
+	.name		= "apm_bios",
+	.fops		= &apm_bios_fops
+};
+
+
+#ifdef CONFIG_PROC_FS
+/*
+ * Arguments, with symbols from linux/apm_bios.h.
+ *
+ *   0) Linux driver version (this will change if format changes)
+ *   1) APM BIOS Version.  Usually 1.0, 1.1 or 1.2.
+ *   2) APM flags from APM Installation Check (0x00):
+ *	bit 0: APM_16_BIT_SUPPORT
+ *	bit 1: APM_32_BIT_SUPPORT
+ *	bit 2: APM_IDLE_SLOWS_CLOCK
+ *	bit 3: APM_BIOS_DISABLED
+ *	bit 4: APM_BIOS_DISENGAGED
+ *   3) AC line status
+ *	0x00: Off-line
+ *	0x01: On-line
+ *	0x02: On backup power (BIOS >= 1.1 only)
+ *	0xff: Unknown
+ *   4) Battery status
+ *	0x00: High
+ *	0x01: Low
+ *	0x02: Critical
+ *	0x03: Charging
+ *	0x04: Selected battery not present (BIOS >= 1.2 only)
+ *	0xff: Unknown
+ *   5) Battery flag
+ *	bit 0: High
+ *	bit 1: Low
+ *	bit 2: Critical
+ *	bit 3: Charging
+ *	bit 7: No system battery
+ *	0xff: Unknown
+ *   6) Remaining battery life (percentage of charge):
+ *	0-100: valid
+ *	-1: Unknown
+ *   7) Remaining battery life (time units):
+ *	Number of remaining minutes or seconds
+ *	-1: Unknown
+ *   8) min = minutes; sec = seconds
+ */
+static int apm_get_info(char *buf, char **start, off_t fpos, int length)
+{
+	struct apm_power_info info;
+	char *units;
+	int ret;
+
+	info.ac_line_status = 0xff;
+	info.battery_status = 0xff;
+	info.battery_flag   = 0xff;
+	info.battery_life   = -1;
+	info.time	    = -1;
+	info.units	    = -1;
+
+	if (apm_get_power_status)
+		apm_get_power_status(&info);
+
+	switch (info.units) {
+	default:	units = "?";	break;
+	case 0: 	units = "min";	break;
+	case 1: 	units = "sec";	break;
+	}
+
+	ret = sprintf(buf, "%s 1.2 0x%02x 0x%02x 0x%02x 0x%02x %d%% %d %s\n",
+		     driver_version, APM_32_BIT_SUPPORT,
+		     info.ac_line_status, info.battery_status,
+		     info.battery_flag, info.battery_life,
+		     info.time, units);
+
+ 	return ret;
+}
+#endif
+
+static int kapmd(void *arg)
+{
+	daemonize("kapmd");
+	current->flags |= PF_NOFREEZE;
+
+	do {
+		apm_event_t event;
+
+		wait_event_interruptible(kapmd_wait,
+				!queue_empty(&kapmd_queue) || !mips_apm_active);
+
+		if (!mips_apm_active)
+			break;
+
+		spin_lock_irq(&kapmd_queue_lock);
+		event = 0;
+		if (!queue_empty(&kapmd_queue))
+			event = queue_get_event(&kapmd_queue);
+		spin_unlock_irq(&kapmd_queue_lock);
+
+		switch (event) {
+		case 0:
+			break;
+
+		case APM_LOW_BATTERY:
+		case APM_POWER_STATUS_CHANGE:
+			queue_event(event, NULL);
+			break;
+
+		case APM_USER_SUSPEND:
+		case APM_SYS_SUSPEND:
+			queue_event(event, NULL);
+			if (suspends_pending == 0)
+				apm_suspend();
+			break;
+
+		case APM_CRITICAL_SUSPEND:
+			apm_suspend();
+			break;
+		}
+	} while (1);
+
+	complete_and_exit(&kapmd_exit, 0);
+}
+
+static int __init apm_init(void)
+{
+	int ret;
+
+	if (apm_disabled) {
+		printk(KERN_NOTICE "apm: disabled on user request.\n");
+		return -ENODEV;
+	}
+
+	mips_apm_active = 1;
+
+	ret = kernel_thread(kapmd, NULL, CLONE_KERNEL);
+	if (ret < 0) {
+		mips_apm_active = 0;
+		return ret;
+	}
+
+#ifdef CONFIG_PROC_FS
+	create_proc_info_entry("apm", 0, NULL, apm_get_info);
+#endif
+
+	ret = misc_register(&apm_device);
+	if (ret != 0) {
+		remove_proc_entry("apm", NULL);
+
+		mips_apm_active = 0;
+		wake_up(&kapmd_wait);
+		wait_for_completion(&kapmd_exit);
+	}
+
+	return ret;
+}
+
+static void __exit apm_exit(void)
+{
+	misc_deregister(&apm_device);
+	remove_proc_entry("apm", NULL);
+
+	mips_apm_active = 0;
+	wake_up(&kapmd_wait);
+	wait_for_completion(&kapmd_exit);
+}
+
+module_init(apm_init);
+module_exit(apm_exit);
+
+MODULE_AUTHOR("Stephen Rothwell");
+MODULE_DESCRIPTION("Advanced Power Management");
+MODULE_LICENSE("GPL");
+
+#ifndef MODULE
+static int __init apm_setup(char *str)
+{
+	while ((str != NULL) && (*str != '\0')) {
+		if (strncmp(str, "off", 3) == 0)
+			apm_disabled = 1;
+		if (strncmp(str, "on", 2) == 0)
+			apm_disabled = 0;
+		str = strchr(str, ',');
+		if (str != NULL)
+			str += strspn(str, ", \t");
+	}
+	return 1;
+}
+
+__setup("apm=", apm_setup);
+#endif
+
+/**
+ * apm_queue_event - queue an APM event for kapmd
+ * @event: APM event
+ *
+ * Queue an APM event for kapmd to process and ultimately take the
+ * appropriate action.  Only a subset of events are handled:
+ *   %APM_LOW_BATTERY
+ *   %APM_POWER_STATUS_CHANGE
+ *   %APM_USER_SUSPEND
+ *   %APM_SYS_SUSPEND
+ *   %APM_CRITICAL_SUSPEND
+ */
+void apm_queue_event(apm_event_t event)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&kapmd_queue_lock, flags);
+	queue_add_event(&kapmd_queue, event);
+	spin_unlock_irqrestore(&kapmd_queue_lock, flags);
+
+	wake_up_interruptible(&kapmd_wait);
+}
+EXPORT_SYMBOL(apm_queue_event);
diff --git a/arch/mips/lib/ashldi3.c b/arch/mips/lib/ashldi3.c
new file mode 100644
index 000000000..beb80f316
--- /dev/null
+++ b/arch/mips/lib/ashldi3.c
@@ -0,0 +1,29 @@
+#include <linux/module.h>
+
+#include "libgcc.h"
+
+long long __ashldi3(long long u, word_type b)
+{
+	DWunion uu, w;
+	word_type bm;
+
+	if (b == 0)
+		return u;
+
+	uu.ll = u;
+	bm = 32 - b;
+
+	if (bm <= 0) {
+		w.s.low = 0;
+		w.s.high = (unsigned int) uu.s.low << -bm;
+	} else {
+		const unsigned int carries = (unsigned int) uu.s.low >> bm;
+
+		w.s.low = (unsigned int) uu.s.low << b;
+		w.s.high = ((unsigned int) uu.s.high << b) | carries;
+	}
+
+	return w.ll;
+}
+
+EXPORT_SYMBOL(__ashldi3);
diff --git a/arch/mips/lib/ashrdi3.c b/arch/mips/lib/ashrdi3.c
new file mode 100644
index 000000000..c884a912b
--- /dev/null
+++ b/arch/mips/lib/ashrdi3.c
@@ -0,0 +1,31 @@
+#include <linux/module.h>
+
+#include "libgcc.h"
+
+long long __ashrdi3(long long u, word_type b)
+{
+	DWunion uu, w;
+	word_type bm;
+
+	if (b == 0)
+		return u;
+
+	uu.ll = u;
+	bm = 32 - b;
+
+	if (bm <= 0) {
+		/* w.s.high = 1..1 or 0..0 */
+		w.s.high =
+		    uu.s.high >> 31;
+		w.s.low = uu.s.high >> -bm;
+	} else {
+		const unsigned int carries = (unsigned int) uu.s.high << bm;
+
+		w.s.high = uu.s.high >> b;
+		w.s.low = ((unsigned int) uu.s.low >> b) | carries;
+	}
+
+	return w.ll;
+}
+
+EXPORT_SYMBOL(__ashrdi3);
diff --git a/arch/mips/lib/libgcc.h b/arch/mips/lib/libgcc.h
new file mode 100644
index 000000000..3f19d1c5d
--- /dev/null
+++ b/arch/mips/lib/libgcc.h
@@ -0,0 +1,26 @@
+#ifndef __ASM_LIBGCC_H
+#define __ASM_LIBGCC_H
+
+#include <asm/byteorder.h>
+
+typedef int word_type __attribute__ ((mode (__word__)));
+
+#ifdef __BIG_ENDIAN
+struct DWstruct {
+	int high, low;
+};
+#elif defined(__LITTLE_ENDIAN)
+struct DWstruct {
+	int low, high;
+};
+#else
+#error I feel sick.
+#endif
+
+typedef union
+{
+	struct DWstruct s;
+	long long ll;
+} DWunion;
+
+#endif /* __ASM_LIBGCC_H */
diff --git a/arch/mips/lib/lshrdi3.c b/arch/mips/lib/lshrdi3.c
new file mode 100644
index 000000000..dcf8d6810
--- /dev/null
+++ b/arch/mips/lib/lshrdi3.c
@@ -0,0 +1,29 @@
+#include <linux/module.h>
+
+#include "libgcc.h"
+
+long long __lshrdi3(long long u, word_type b)
+{
+	DWunion uu, w;
+	word_type bm;
+
+	if (b == 0)
+		return u;
+
+	uu.ll = u;
+	bm = 32 - b;
+
+	if (bm <= 0) {
+		w.s.high = 0;
+		w.s.low = (unsigned int) uu.s.high >> -bm;
+	} else {
+		const unsigned int carries = (unsigned int) uu.s.high << bm;
+
+		w.s.high = (unsigned int) uu.s.high >> b;
+		w.s.low = ((unsigned int) uu.s.low >> b) | carries;
+	}
+
+	return w.ll;
+}
+
+EXPORT_SYMBOL(__lshrdi3);
diff --git a/arch/mips/mm/sc-mips.c b/arch/mips/mm/sc-mips.c
new file mode 100644
index 000000000..42b50964c
--- /dev/null
+++ b/arch/mips/mm/sc-mips.c
@@ -0,0 +1,112 @@
+/*
+ * Copyright (C) 2006 Chris Dearman (chris@mips.com),
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+
+#include <asm/mipsregs.h>
+#include <asm/bcache.h>
+#include <asm/cacheops.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/system.h>
+#include <asm/mmu_context.h>
+#include <asm/r4kcache.h>
+
+/*
+ * MIPS32/MIPS64 L2 cache handling
+ */
+
+/*
+ * Writeback and invalidate the secondary cache before DMA.
+ */
+static void mips_sc_wback_inv(unsigned long addr, unsigned long size)
+{
+	blast_scache_range(addr, addr + size);
+}
+
+/*
+ * Invalidate the secondary cache before DMA.
+ */
+static void mips_sc_inv(unsigned long addr, unsigned long size)
+{
+	blast_inv_scache_range(addr, addr + size);
+}
+
+static void mips_sc_enable(void)
+{
+	/* L2 cache is permanently enabled */
+}
+
+static void mips_sc_disable(void)
+{
+	/* L2 cache is permanently enabled */
+}
+
+static struct bcache_ops mips_sc_ops = {
+	.bc_enable = mips_sc_enable,
+	.bc_disable = mips_sc_disable,
+	.bc_wback_inv = mips_sc_wback_inv,
+	.bc_inv = mips_sc_inv
+};
+
+static inline int __init mips_sc_probe(void)
+{
+	struct cpuinfo_mips *c = &current_cpu_data;
+	unsigned int config1, config2;
+	unsigned int tmp;
+
+	/* Mark as not present until probe completed */
+	c->scache.flags |= MIPS_CACHE_NOT_PRESENT;
+
+	/* Ignore anything but MIPSxx processors */
+	if (c->isa_level != MIPS_CPU_ISA_M32R1 &&
+	    c->isa_level != MIPS_CPU_ISA_M32R2 &&
+	    c->isa_level != MIPS_CPU_ISA_M64R1 &&
+	    c->isa_level != MIPS_CPU_ISA_M64R2)
+		return 0;
+
+	/* Does this MIPS32/MIPS64 CPU have a config2 register? */
+	config1 = read_c0_config1();
+	if (!(config1 & MIPS_CONF_M))
+		return 0;
+
+	config2 = read_c0_config2();
+	tmp = (config2 >> 4) & 0x0f;
+	if (0 < tmp && tmp <= 7)
+		c->scache.linesz = 2 << tmp;
+	else
+		return 0;
+
+	tmp = (config2 >> 8) & 0x0f;
+	if (0 <= tmp && tmp <= 7)
+		c->scache.sets = 64 << tmp;
+	else
+		return 0;
+
+	tmp = (config2 >> 0) & 0x0f;
+	if (0 <= tmp && tmp <= 7)
+		c->scache.ways = tmp + 1;
+	else
+		return 0;
+
+	c->scache.waysize = c->scache.sets * c->scache.linesz;
+	c->scache.waybit = __ffs(c->scache.waysize);
+
+	c->scache.flags &= ~MIPS_CACHE_NOT_PRESENT;
+
+	return 1;
+}
+
+int __init mips_sc_init(void)
+{
+	int found = mips_sc_probe ();
+	if (found) {
+		mips_sc_enable();
+		bcops = &mips_sc_ops;
+	}
+	return found;
+}
+
diff --git a/arch/mips/pci/fixup-emma2rh.c b/arch/mips/pci/fixup-emma2rh.c
new file mode 100644
index 000000000..7abcfd175
--- /dev/null
+++ b/arch/mips/pci/fixup-emma2rh.c
@@ -0,0 +1,101 @@
+/*
+ *  arch/mips/pci/fixup-emma2rh.c
+ *      This file defines the PCI configration.
+ *
+ *  Copyright (C) NEC Electronics Corporation 2004-2006
+ *
+ *  This file is based on the arch/mips/ddb5xxx/ddb5477/pci.c
+ *
+ *	Copyright 2001 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 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/types.h>
+#include <linux/pci.h>
+
+#include <asm/bootinfo.h>
+#include <asm/debug.h>
+
+#include <asm/emma2rh/emma2rh.h>
+
+#define EMMA2RH_PCI_HOST_SLOT 0x09
+#define EMMA2RH_USB_SLOT 0x03
+#define PCI_DEVICE_ID_NEC_EMMA2RH      0x014b /* EMMA2RH PCI Host */
+
+/*
+ * we fix up irqs based on the slot number.
+ * The first entry is at AD:11.
+ * Fortunately this works because, although we have two pci buses,
+ * they all have different slot numbers (except for rockhopper slot 20
+ * which is handled below).
+ *
+ */
+
+#define	MAX_SLOT_NUM 10
+static unsigned char irq_map[][5] __initdata = {
+	[3] = {0, MARKEINS_PCI_IRQ_INTB, MARKEINS_PCI_IRQ_INTC,
+	       MARKEINS_PCI_IRQ_INTD, 0,},
+	[4] = {0, MARKEINS_PCI_IRQ_INTA, 0, 0, 0,},
+	[5] = {0, 0, 0, 0, 0,},
+	[6] = {0, MARKEINS_PCI_IRQ_INTC, MARKEINS_PCI_IRQ_INTD,
+	       MARKEINS_PCI_IRQ_INTA, MARKEINS_PCI_IRQ_INTB,},
+};
+
+static void __devinit nec_usb_controller_fixup(struct pci_dev *dev)
+{
+	if (PCI_SLOT(dev->devfn) == EMMA2RH_USB_SLOT)
+		/* on board USB controller configuration */
+		pci_write_config_dword(dev, 0xe4, 1 << 5);
+}
+
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NEC, PCI_DEVICE_ID_NEC_USB,
+			nec_usb_controller_fixup);
+
+/*
+ * Prevent the PCI layer from seeing the resources allocated to this device
+ * if it is the host bridge by marking it as such.  These resources are of
+ * no consequence to the PCI layer (they are handled elsewhere).
+ */
+static void __devinit emma2rh_pci_host_fixup(struct pci_dev *dev)
+{
+	int i;
+
+	if (PCI_SLOT(dev->devfn) == EMMA2RH_PCI_HOST_SLOT) {
+		dev->class &= 0xff;
+		dev->class |= PCI_CLASS_BRIDGE_HOST << 8;
+		for (i = 0; i < PCI_NUM_RESOURCES; i++) {
+			dev->resource[i].start = 0;
+			dev->resource[i].end = 0;
+			dev->resource[i].flags = 0;
+		}
+	}
+}
+
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_NEC, PCI_DEVICE_ID_NEC_EMMA2RH,
+			 emma2rh_pci_host_fixup);
+
+int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+	return irq_map[slot][pin];
+}
+
+/* Do platform specific device initialization at pci_enable_device() time */
+int pcibios_plat_dev_init(struct pci_dev *dev)
+{
+	return 0;
+}
diff --git a/arch/mips/pci/fixup-excite.c b/arch/mips/pci/fixup-excite.c
new file mode 100644
index 000000000..1da696d43
--- /dev/null
+++ b/arch/mips/pci/fixup-excite.c
@@ -0,0 +1,36 @@
+/*
+ *  Copyright (C) 2004 by Basler Vision Technologies AG
+ *  Author: Thomas Koeller <thomas.koeller@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/kernel.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+#include <excite.h>
+
+int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+	if (pin == 0)
+		return -1;
+
+	return USB_IRQ;		/* USB controller is the only PCI device */
+}
+
+/* Do platform specific device initialization at pci_enable_device() time */
+int pcibios_plat_dev_init(struct pci_dev *dev)
+{
+	return 0;
+}
diff --git a/arch/mips/pci/fixup-wrppmc.c b/arch/mips/pci/fixup-wrppmc.c
new file mode 100644
index 000000000..3357c1300
--- /dev/null
+++ b/arch/mips/pci/fixup-wrppmc.c
@@ -0,0 +1,37 @@
+/*
+ * fixup-wrppmc.c: PPMC board specific PCI fixup
+ *
+ * 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, Wind River Inc. Rongkai.zhan (rongkai.zhan@windriver.com)
+ */
+#include <linux/init.h>
+#include <linux/pci.h>
+#include <asm/gt64120.h>
+
+/* PCI interrupt pins */
+#define PCI_INTA		1
+#define PCI_INTB		2
+#define PCI_INTC		3
+#define PCI_INTD		4
+
+#define PCI_SLOT_MAXNR	32 /* Each PCI bus has 32 physical slots */
+
+static char pci_irq_tab[PCI_SLOT_MAXNR][5] __initdata = {
+	/* 0    INTA   INTB   INTC   INTD */
+	[0] = {0, 0, 0, 0, 0},		/* Slot 0: GT64120 PCI bridge */
+	[6] = {0, WRPPMC_PCI_INTA_IRQ, 0, 0, 0},
+};
+
+int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+	return pci_irq_tab[slot][pin];
+}
+
+/* Do platform specific device initialization at pci_enable_device() time */
+int pcibios_plat_dev_init(struct pci_dev *dev)
+{
+	return 0;
+}
diff --git a/arch/mips/pci/ops-bridge.c b/arch/mips/pci/ops-bridge.c
new file mode 100644
index 000000000..1fa09929c
--- /dev/null
+++ b/arch/mips/pci/ops-bridge.c
@@ -0,0 +1,306 @@
+/*
+ * 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) 1999, 2000, 04, 06 Ralf Baechle (ralf@linux-mips.org)
+ * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
+ */
+#include <linux/pci.h>
+#include <asm/paccess.h>
+#include <asm/pci/bridge.h>
+#include <asm/sn/arch.h>
+#include <asm/sn/intr.h>
+#include <asm/sn/sn0/hub.h>
+
+/*
+ * The Bridge ASIC supports both type 0 and type 1 access.  Type 1 is
+ * not really documented, so right now I can't write code which uses it.
+ * Therefore we use type 0 accesses for now even though they won't work
+ * correcly for PCI-to-PCI bridges.
+ *
+ * The function is complicated by the ultimate brokeness of the IOC3 chip
+ * which is used in SGI systems.  The IOC3 can only handle 32-bit PCI
+ * accesses and does only decode parts of it's address space.
+ */
+
+static int pci_conf0_read_config(struct pci_bus *bus, unsigned int devfn,
+				 int where, int size, u32 * value)
+{
+	struct bridge_controller *bc = BRIDGE_CONTROLLER(bus);
+	bridge_t *bridge = bc->base;
+	int slot = PCI_SLOT(devfn);
+	int fn = PCI_FUNC(devfn);
+	volatile void *addr;
+	u32 cf, shift, mask;
+	int res;
+
+	addr = &bridge->b_type0_cfg_dev[slot].f[fn].c[PCI_VENDOR_ID];
+	if (get_dbe(cf, (u32 *) addr))
+		return PCIBIOS_DEVICE_NOT_FOUND;
+
+	/*
+	 * IOC3 is fucked fucked beyond believe ...  Don't even give the
+	 * generic PCI code a chance to look at it for real ...
+	 */
+	if (cf == (PCI_VENDOR_ID_SGI | (PCI_DEVICE_ID_SGI_IOC3 << 16)))
+		goto oh_my_gawd;
+
+	addr = &bridge->b_type0_cfg_dev[slot].f[fn].c[where ^ (4 - size)];
+
+	if (size == 1)
+		res = get_dbe(*value, (u8 *) addr);
+	else if (size == 2)
+		res = get_dbe(*value, (u16 *) addr);
+	else
+		res = get_dbe(*value, (u32 *) addr);
+
+	return res ? PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL;
+
+oh_my_gawd:
+
+	/*
+	 * IOC3 is fucked fucked beyond believe ...  Don't even give the
+	 * generic PCI code a chance to look at the wrong register.
+	 */
+	if ((where >= 0x14 && where < 0x40) || (where >= 0x48)) {
+		*value = 0;
+		return PCIBIOS_SUCCESSFUL;
+	}
+
+	/*
+	 * IOC3 is fucked fucked beyond believe ...  Don't try to access
+	 * anything but 32-bit words ...
+	 */
+	addr = &bridge->b_type0_cfg_dev[slot].f[fn].l[where >> 2];
+
+	if (get_dbe(cf, (u32 *) addr))
+		return PCIBIOS_DEVICE_NOT_FOUND;
+
+	shift = ((where & 3) << 3);
+	mask = (0xffffffffU >> ((4 - size) << 3));
+	*value = (cf >> shift) & mask;
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int pci_conf1_read_config(struct pci_bus *bus, unsigned int devfn,
+				 int where, int size, u32 * value)
+{
+	struct bridge_controller *bc = BRIDGE_CONTROLLER(bus);
+	bridge_t *bridge = bc->base;
+	int busno = bus->number;
+	int slot = PCI_SLOT(devfn);
+	int fn = PCI_FUNC(devfn);
+	volatile void *addr;
+	u32 cf, shift, mask;
+	int res;
+
+	bridge->b_pci_cfg = (busno << 16) | (slot << 11);
+	addr = &bridge->b_type1_cfg.c[(fn << 8) | PCI_VENDOR_ID];
+	if (get_dbe(cf, (u32 *) addr))
+		return PCIBIOS_DEVICE_NOT_FOUND;
+
+	/*
+	 * IOC3 is fucked fucked beyond believe ...  Don't even give the
+	 * generic PCI code a chance to look at it for real ...
+	 */
+	if (cf == (PCI_VENDOR_ID_SGI | (PCI_DEVICE_ID_SGI_IOC3 << 16)))
+		goto oh_my_gawd;
+
+	bridge->b_pci_cfg = (busno << 16) | (slot << 11);
+	addr = &bridge->b_type1_cfg.c[(fn << 8) | (where ^ (4 - size))];
+
+	if (size == 1)
+		res = get_dbe(*value, (u8 *) addr);
+	else if (size == 2)
+		res = get_dbe(*value, (u16 *) addr);
+	else
+		res = get_dbe(*value, (u32 *) addr);
+
+	return res ? PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL;
+
+oh_my_gawd:
+
+	/*
+	 * IOC3 is fucked fucked beyond believe ...  Don't even give the
+	 * generic PCI code a chance to look at the wrong register.
+	 */
+	if ((where >= 0x14 && where < 0x40) || (where >= 0x48)) {
+		*value = 0;
+		return PCIBIOS_SUCCESSFUL;
+	}
+
+	/*
+	 * IOC3 is fucked fucked beyond believe ...  Don't try to access
+	 * anything but 32-bit words ...
+	 */
+	bridge->b_pci_cfg = (busno << 16) | (slot << 11);
+	addr = &bridge->b_type1_cfg.c[(fn << 8) | where];
+
+	if (get_dbe(cf, (u32 *) addr))
+		return PCIBIOS_DEVICE_NOT_FOUND;
+
+	shift = ((where & 3) << 3);
+	mask = (0xffffffffU >> ((4 - size) << 3));
+	*value = (cf >> shift) & mask;
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int pci_read_config(struct pci_bus *bus, unsigned int devfn,
+			   int where, int size, u32 * value)
+{
+	if (bus->number > 0)
+		return pci_conf1_read_config(bus, devfn, where, size, value);
+
+	return pci_conf0_read_config(bus, devfn, where, size, value);
+}
+
+static int pci_conf0_write_config(struct pci_bus *bus, unsigned int devfn,
+				  int where, int size, u32 value)
+{
+	struct bridge_controller *bc = BRIDGE_CONTROLLER(bus);
+	bridge_t *bridge = bc->base;
+	int slot = PCI_SLOT(devfn);
+	int fn = PCI_FUNC(devfn);
+	volatile void *addr;
+	u32 cf, shift, mask, smask;
+	int res;
+
+	addr = &bridge->b_type0_cfg_dev[slot].f[fn].c[PCI_VENDOR_ID];
+	if (get_dbe(cf, (u32 *) addr))
+		return PCIBIOS_DEVICE_NOT_FOUND;
+
+	/*
+	 * IOC3 is fucked fucked beyond believe ...  Don't even give the
+	 * generic PCI code a chance to look at it for real ...
+	 */
+	if (cf == (PCI_VENDOR_ID_SGI | (PCI_DEVICE_ID_SGI_IOC3 << 16)))
+		goto oh_my_gawd;
+
+	addr = &bridge->b_type0_cfg_dev[slot].f[fn].c[where ^ (4 - size)];
+
+	if (size == 1) {
+		res = put_dbe(value, (u8 *) addr);
+	} else if (size == 2) {
+		res = put_dbe(value, (u16 *) addr);
+	} else {
+		res = put_dbe(value, (u32 *) addr);
+	}
+
+	if (res)
+		return PCIBIOS_DEVICE_NOT_FOUND;
+
+	return PCIBIOS_SUCCESSFUL;
+
+oh_my_gawd:
+
+	/*
+	 * IOC3 is fucked fucked beyond believe ...  Don't even give the
+	 * generic PCI code a chance to touch the wrong register.
+	 */
+	if ((where >= 0x14 && where < 0x40) || (where >= 0x48))
+		return PCIBIOS_SUCCESSFUL;
+
+	/*
+	 * IOC3 is fucked fucked beyond believe ...  Don't try to access
+	 * anything but 32-bit words ...
+	 */
+	addr = &bridge->b_type0_cfg_dev[slot].f[fn].l[where >> 2];
+
+	if (get_dbe(cf, (u32 *) addr))
+		return PCIBIOS_DEVICE_NOT_FOUND;
+
+	shift = ((where & 3) << 3);
+	mask = (0xffffffffU >> ((4 - size) << 3));
+	smask = mask << shift;
+
+	cf = (cf & ~smask) | ((value & mask) << shift);
+	if (put_dbe(cf, (u32 *) addr))
+		return PCIBIOS_DEVICE_NOT_FOUND;
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int pci_conf1_write_config(struct pci_bus *bus, unsigned int devfn,
+				  int where, int size, u32 value)
+{
+	struct bridge_controller *bc = BRIDGE_CONTROLLER(bus);
+	bridge_t *bridge = bc->base;
+	int slot = PCI_SLOT(devfn);
+	int fn = PCI_FUNC(devfn);
+	int busno = bus->number;
+	volatile void *addr;
+	u32 cf, shift, mask, smask;
+	int res;
+
+	bridge->b_pci_cfg = (busno << 16) | (slot << 11);
+	addr = &bridge->b_type1_cfg.c[(fn << 8) | PCI_VENDOR_ID];
+	if (get_dbe(cf, (u32 *) addr))
+		return PCIBIOS_DEVICE_NOT_FOUND;
+
+	/*
+	 * IOC3 is fucked fucked beyond believe ...  Don't even give the
+	 * generic PCI code a chance to look at it for real ...
+	 */
+	if (cf == (PCI_VENDOR_ID_SGI | (PCI_DEVICE_ID_SGI_IOC3 << 16)))
+		goto oh_my_gawd;
+
+	addr = &bridge->b_type1_cfg.c[(fn << 8) | (where ^ (4 - size))];
+
+	if (size == 1) {
+		res = put_dbe(value, (u8 *) addr);
+	} else if (size == 2) {
+		res = put_dbe(value, (u16 *) addr);
+	} else {
+		res = put_dbe(value, (u32 *) addr);
+	}
+
+	if (res)
+		return PCIBIOS_DEVICE_NOT_FOUND;
+
+	return PCIBIOS_SUCCESSFUL;
+
+oh_my_gawd:
+
+	/*
+	 * IOC3 is fucked fucked beyond believe ...  Don't even give the
+	 * generic PCI code a chance to touch the wrong register.
+	 */
+	if ((where >= 0x14 && where < 0x40) || (where >= 0x48))
+		return PCIBIOS_SUCCESSFUL;
+
+	/*
+	 * IOC3 is fucked fucked beyond believe ...  Don't try to access
+	 * anything but 32-bit words ...
+	 */
+	addr = &bridge->b_type0_cfg_dev[slot].f[fn].l[where >> 2];
+
+	if (get_dbe(cf, (u32 *) addr))
+		return PCIBIOS_DEVICE_NOT_FOUND;
+
+	shift = ((where & 3) << 3);
+	mask = (0xffffffffU >> ((4 - size) << 3));
+	smask = mask << shift;
+
+	cf = (cf & ~smask) | ((value & mask) << shift);
+	if (put_dbe(cf, (u32 *) addr))
+		return PCIBIOS_DEVICE_NOT_FOUND;
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int pci_write_config(struct pci_bus *bus, unsigned int devfn,
+	int where, int size, u32 value)
+{
+	if (bus->number > 0)
+		return pci_conf1_write_config(bus, devfn, where, size, value);
+
+	return pci_conf0_write_config(bus, devfn, where, size, value);
+}
+
+struct pci_ops bridge_pci_ops = {
+	.read	= pci_read_config,
+	.write	= pci_write_config,
+};
diff --git a/arch/mips/pci/ops-emma2rh.c b/arch/mips/pci/ops-emma2rh.c
new file mode 100644
index 000000000..38f181625
--- /dev/null
+++ b/arch/mips/pci/ops-emma2rh.c
@@ -0,0 +1,185 @@
+/*
+ *  arch/mips/pci/ops-emma2rh.c
+ *      This file defines the PCI operation for EMMA2RH.
+ *
+ *  Copyright (C) NEC Electronics Corporation 2004-2006
+ *
+ *  This file is based on the arch/mips/pci/ops-vr41xx.c
+ *
+ *	Copyright 2001 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 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/pci.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+
+#include <asm/addrspace.h>
+#include <asm/debug.h>
+
+#include <asm/emma2rh/emma2rh.h>
+
+#define RTABORT (0x1<<9)
+#define RMABORT (0x1<<10)
+#define EMMA2RH_PCI_SLOT_NUM 9	/* 0000:09.0 is final PCI device */
+
+/*
+ * access config space
+ */
+
+static int check_args(struct pci_bus *bus, u32 devfn, u32 * bus_num)
+{
+	/* check if the bus is top-level */
+	if (bus->parent != NULL) {
+		*bus_num = bus->number;
+		db_assert(bus_num != 0);
+	} else
+		*bus_num = 0;
+
+	if (*bus_num == 0) {
+		/* Type 0 */
+		if (PCI_SLOT(devfn) >= 10)
+			return PCIBIOS_DEVICE_NOT_FOUND;
+	} else {
+		/* Type 1 */
+		if ((*bus_num >= 64) || (PCI_SLOT(devfn) >= 16))
+			return PCIBIOS_DEVICE_NOT_FOUND;
+	}
+	return 0;
+}
+
+static inline int set_pci_configuration_address(unsigned char bus_num,
+						unsigned int devfn, int where)
+{
+	u32 config_win0;
+
+	emma2rh_out32(EMMA2RH_PCI_INT, ~RMABORT);
+	if (bus_num == 0)
+		/*
+		 * Type 0 configuration
+		 */
+		config_win0 = (1 << (22 + PCI_SLOT(devfn))) | (5 << 9);
+	else
+		/*
+		 * Type 1 configuration
+		 */
+		config_win0 = (bus_num << 26) | (PCI_SLOT(devfn) << 22) |
+		    (1 << 15) | (5 << 9);
+
+	emma2rh_out32(EMMA2RH_PCI_IWIN0_CTR, config_win0);
+
+	return 0;
+}
+
+static int pci_config_read(struct pci_bus *bus, unsigned int devfn, int where,
+			   int size, uint32_t * val)
+{
+	u32 bus_num;
+	u32 base = KSEG1ADDR(EMMA2RH_PCI_CONFIG_BASE);
+	u32 backup_win0;
+	u32 data;
+
+	*val = 0xffffffffU;
+
+	if (check_args(bus, devfn, &bus_num) == PCIBIOS_DEVICE_NOT_FOUND)
+		return PCIBIOS_DEVICE_NOT_FOUND;
+
+	backup_win0 = emma2rh_in32(EMMA2RH_PCI_IWIN0_CTR);
+
+	if (set_pci_configuration_address(bus_num, devfn, where) < 0)
+		return PCIBIOS_DEVICE_NOT_FOUND;
+
+	data =
+	    *(volatile u32 *)(base + (PCI_FUNC(devfn) << 8) +
+			      (where & 0xfffffffc));
+
+	switch (size) {
+	case 1:
+		*val = (data >> ((where & 3) << 3)) & 0xffU;
+		break;
+	case 2:
+		*val = (data >> ((where & 2) << 3)) & 0xffffU;
+		break;
+	case 4:
+		*val = data;
+		break;
+	default:
+		emma2rh_out32(EMMA2RH_PCI_IWIN0_CTR, backup_win0);
+		return PCIBIOS_FUNC_NOT_SUPPORTED;
+	}
+
+	emma2rh_out32(EMMA2RH_PCI_IWIN0_CTR, backup_win0);
+
+	if (emma2rh_in32(EMMA2RH_PCI_INT) & RMABORT)
+		return PCIBIOS_DEVICE_NOT_FOUND;
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int pci_config_write(struct pci_bus *bus, unsigned int devfn, int where,
+			    int size, u32 val)
+{
+	u32 bus_num;
+	u32 base = KSEG1ADDR(EMMA2RH_PCI_CONFIG_BASE);
+	u32 backup_win0;
+	u32 data;
+	int shift;
+
+	if (check_args(bus, devfn, &bus_num) == PCIBIOS_DEVICE_NOT_FOUND)
+		return PCIBIOS_DEVICE_NOT_FOUND;
+
+	backup_win0 = emma2rh_in32(EMMA2RH_PCI_IWIN0_CTR);
+
+	if (set_pci_configuration_address(bus_num, devfn, where) < 0)
+		return PCIBIOS_DEVICE_NOT_FOUND;
+
+	/* read modify write */
+	data =
+	    *(volatile u32 *)(base + (PCI_FUNC(devfn) << 8) +
+			      (where & 0xfffffffc));
+
+	switch (size) {
+	case 1:
+		shift = (where & 3) << 3;
+		data &= ~(0xffU << shift);
+		data |= ((val & 0xffU) << shift);
+		break;
+	case 2:
+		shift = (where & 2) << 3;
+		data &= ~(0xffffU << shift);
+		data |= ((val & 0xffffU) << shift);
+		break;
+	case 4:
+		data = val;
+		break;
+	default:
+		emma2rh_out32(EMMA2RH_PCI_IWIN0_CTR, backup_win0);
+		return PCIBIOS_FUNC_NOT_SUPPORTED;
+	}
+	*(volatile u32 *)(base + (PCI_FUNC(devfn) << 8) +
+			  (where & 0xfffffffc)) = data;
+
+	emma2rh_out32(EMMA2RH_PCI_IWIN0_CTR, backup_win0);
+	if (emma2rh_in32(EMMA2RH_PCI_INT) & RMABORT)
+		return PCIBIOS_DEVICE_NOT_FOUND;
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+struct pci_ops emma2rh_pci_ops = {
+	.read = pci_config_read,
+	.write = pci_config_write,
+};
diff --git a/arch/mips/pci/pci-emma2rh.c b/arch/mips/pci/pci-emma2rh.c
new file mode 100644
index 000000000..d99591a0c
--- /dev/null
+++ b/arch/mips/pci/pci-emma2rh.c
@@ -0,0 +1,89 @@
+/*
+ *  arch/mips/pci/pci-emma2rh.c
+ *      This file defines the PCI configration.
+ *
+ *  Copyright (C) NEC Electronics Corporation 2004-2006
+ *
+ *  This file is based on the arch/mips/ddb5xxx/ddb5477/pci.c
+ *
+ *	Copyright 2001 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 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/types.h>
+#include <linux/pci.h>
+
+#include <asm/bootinfo.h>
+#include <asm/debug.h>
+
+#include <asm/emma2rh/emma2rh.h>
+
+static struct resource pci_io_resource = {
+	.name = "pci IO space",
+	.start = EMMA2RH_PCI_IO_BASE,
+	.end = EMMA2RH_PCI_IO_BASE + EMMA2RH_PCI_IO_SIZE - 1,
+	.flags = IORESOURCE_IO,
+};
+
+static struct resource pci_mem_resource = {
+	.name = "pci memory space",
+	.start = EMMA2RH_PCI_MEM_BASE,
+	.end = EMMA2RH_PCI_MEM_BASE + EMMA2RH_PCI_MEM_SIZE - 1,
+	.flags = IORESOURCE_MEM,
+};
+
+extern struct pci_ops emma2rh_pci_ops;
+
+static struct pci_controller emma2rh_pci_controller = {
+	.pci_ops = &emma2rh_pci_ops,
+	.mem_resource = &pci_mem_resource,
+	.io_resource = &pci_io_resource,
+	.mem_offset = -0x04000000,
+	.io_offset = 0,
+};
+
+static void __init emma2rh_pci_init(void)
+{
+	/* setup PCI interface */
+	emma2rh_out32(EMMA2RH_PCI_ARBIT_CTR, 0x70f);
+
+	emma2rh_out32(EMMA2RH_PCI_IWIN0_CTR, 0x80000a18);
+	emma2rh_out32(EMMA2RH_PCI_CONFIG_BASE + PCI_COMMAND,
+		      PCI_STATUS_DEVSEL_MEDIUM | PCI_STATUS_CAP_LIST |
+		      PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY);
+	emma2rh_out32(EMMA2RH_PCI_CONFIG_BASE + PCI_BASE_ADDRESS_0, 0x10000000);
+	emma2rh_out32(EMMA2RH_PCI_CONFIG_BASE + PCI_BASE_ADDRESS_1, 0x00000000);
+
+	emma2rh_out32(EMMA2RH_PCI_IWIN0_CTR, 0x12000000 | 0x218);
+	emma2rh_out32(EMMA2RH_PCI_IWIN1_CTR, 0x18000000 | 0x600);
+	emma2rh_out32(EMMA2RH_PCI_INIT_ESWP, 0x00000200);
+
+	emma2rh_out32(EMMA2RH_PCI_TWIN_CTR, 0x00009200);
+	emma2rh_out32(EMMA2RH_PCI_TWIN_BADR, 0x00000000);
+	emma2rh_out32(EMMA2RH_PCI_TWIN0_DADR, 0x00000000);
+	emma2rh_out32(EMMA2RH_PCI_TWIN1_DADR, 0x00000000);
+}
+
+static int __init emma2rh_pci_setup(void)
+{
+	emma2rh_pci_init();
+	register_pci_controller(&emma2rh_pci_controller);
+	return 0;
+}
+
+arch_initcall(emma2rh_pci_setup);
diff --git a/arch/mips/pci/pci-excite.c b/arch/mips/pci/pci-excite.c
new file mode 100644
index 000000000..3c86c77cb
--- /dev/null
+++ b/arch/mips/pci/pci-excite.c
@@ -0,0 +1,149 @@
+/*
+ *  Copyright (C) 2004 by Basler Vision Technologies AG
+ *  Author: Thomas Koeller <thomas.koeller@baslerweb.com>
+ *  Based on the PMC-Sierra Yosemite board support by Ralf Baechle.
+ *
+ *  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/kernel.h>
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/bitops.h>
+#include <asm/rm9k-ocd.h>
+#include <excite.h>
+
+
+extern struct pci_ops titan_pci_ops;
+
+
+static struct resource
+	mem_resource = 	{
+		.name	= "PCI memory",
+		.start	= EXCITE_PHYS_PCI_MEM,
+		.end	= EXCITE_PHYS_PCI_MEM + EXCITE_SIZE_PCI_MEM - 1,
+		.flags	= IORESOURCE_MEM
+	},
+	io_resource = {
+		.name	= "PCI I/O",
+		.start	= EXCITE_PHYS_PCI_IO,
+		.end	= EXCITE_PHYS_PCI_IO + EXCITE_SIZE_PCI_IO - 1,
+		.flags	= IORESOURCE_IO
+	};
+
+
+static struct pci_controller bx_controller = {
+	.pci_ops	= &titan_pci_ops,
+	.mem_resource	= &mem_resource,
+	.mem_offset	= 0x00000000UL,
+	.io_resource	= &io_resource,
+	.io_offset	= 0x00000000UL
+};
+
+
+static char
+	iopage_failed[] __initdata   = "Cannot allocate PCI I/O page",
+	modebits_no_pci[] __initdata = "PCI is not configured in mode bits";
+
+#define RM9000x2_OCD_HTSC	0x0604
+#define RM9000x2_OCD_HTBHL	0x060c
+#define RM9000x2_OCD_PCIHRST	0x078c
+
+#define RM9K_OCD_MODEBIT1	0x00d4 /* (MODEBIT1) Mode Bit 1 */
+#define RM9K_OCD_CPHDCR		0x00f4 /* CPU-PCI/HT Data Control. */
+
+#define PCISC_FB2B 		0x00000200
+#define PCISC_MWICG		0x00000010
+#define PCISC_EMC		0x00000004
+#define PCISC_ERMA		0x00000002
+
+
+
+static int __init basler_excite_pci_setup(void)
+{
+	const unsigned int fullbars = memsize / (256 << 20);
+	unsigned int i;
+
+	/* Check modebits to see if PCI is really enabled. */
+	if (!((ocd_readl(RM9K_OCD_MODEBIT1) >> (47-32)) & 0x1))
+		panic(modebits_no_pci);
+
+	if (NULL == request_mem_region(EXCITE_PHYS_PCI_IO, EXCITE_SIZE_PCI_IO,
+				       "Memory-mapped PCI I/O page"))
+		panic(iopage_failed);
+
+	/* Enable PCI 0 as master for config cycles */
+	ocd_writel(PCISC_EMC | PCISC_ERMA, RM9000x2_OCD_HTSC);
+
+
+	/* Set up latency timer */
+	ocd_writel(0x8008, RM9000x2_OCD_HTBHL);
+
+	/*  Setup host IO and Memory space */
+	ocd_writel((EXCITE_PHYS_PCI_IO >> 4) | 1, LKB7);
+	ocd_writel(((EXCITE_SIZE_PCI_IO >> 4) & 0x7fffff00) - 0x100, LKM7);
+	ocd_writel((EXCITE_PHYS_PCI_MEM >> 4) | 1, LKB8);
+	ocd_writel(((EXCITE_SIZE_PCI_MEM >> 4) & 0x7fffff00) - 0x100, LKM8);
+
+	/* Set up PCI BARs to map all installed memory */
+	for (i = 0; i < 6; i++) {
+		const unsigned int bar = 0x610 + i * 4;
+
+	     	if (i < fullbars) {
+			ocd_writel(0x10000000 * i, bar);
+			ocd_writel(0x01000000 * i, bar + 0x140);
+			ocd_writel(0x0ffff029, bar + 0x100);
+			continue;
+		}
+
+	     	if (i == fullbars) {
+			int o;
+			u32 mask;
+
+			const unsigned long rem = memsize - i * 0x10000000;
+			if (!rem) {
+				ocd_writel(0x00000000, bar + 0x100);
+				continue;
+			}
+
+			o = ffs(rem) - 1;
+			if (rem & ~(0x1 << o))
+				o++;
+			mask = ((0x1 << o) & 0x0ffff000) - 0x1000;
+			ocd_writel(0x10000000 * i, bar);
+			ocd_writel(0x01000000 * i, bar + 0x140);
+			ocd_writel(0x00000029 | mask, bar + 0x100);
+			continue;
+		}
+
+		ocd_writel(0x00000000, bar + 0x100);
+	}
+
+	/* Finally, enable the PCI interupt */
+#if USB_IRQ > 7
+	set_c0_intcontrol(1 << USB_IRQ);
+#else
+	set_c0_status(1 << (USB_IRQ + 8));
+#endif
+
+	ioport_resource.start = EXCITE_PHYS_PCI_IO;
+	ioport_resource.end = EXCITE_PHYS_PCI_IO + EXCITE_SIZE_PCI_IO - 1;
+	set_io_port_base((unsigned long) ioremap_nocache(EXCITE_PHYS_PCI_IO, EXCITE_SIZE_PCI_IO));
+	register_pci_controller(&bx_controller);
+	return 0;
+}
+
+
+arch_initcall(basler_excite_pci_setup);
diff --git a/arch/mips/qemu/q-reset.c b/arch/mips/qemu/q-reset.c
new file mode 100644
index 000000000..dbbe44ad7
--- /dev/null
+++ b/arch/mips/qemu/q-reset.c
@@ -0,0 +1,33 @@
+
+#include <asm/io.h>
+#include <asm/reboot.h>
+#include <asm/cacheflush.h>
+#include <asm/qemu.h>
+
+static void qemu_machine_restart(char *command)
+{
+	volatile unsigned int *reg = (unsigned int *)QEMU_RESTART_REG;
+
+	set_c0_status(ST0_BEV | ST0_ERL);
+	change_c0_config(CONF_CM_CMASK, CONF_CM_UNCACHED);
+	flush_cache_all();
+	write_c0_wired(0);
+	*reg = 42;
+	while (1)
+		cpu_wait();
+}
+
+static void qemu_machine_halt(void)
+{
+	volatile unsigned int *reg = (unsigned int *)QEMU_HALT_REG;
+
+	*reg = 42;
+	while (1)
+		cpu_wait();
+}
+
+void qemu_reboot_setup(void)
+{
+	_machine_restart = qemu_machine_restart;
+	_machine_halt = qemu_machine_halt;
+}
diff --git a/arch/mips/sni/sniprom.c b/arch/mips/sni/sniprom.c
new file mode 100644
index 000000000..d1d0f1f49
--- /dev/null
+++ b/arch/mips/sni/sniprom.c
@@ -0,0 +1,158 @@
+/*
+ * Big Endian PROM code for SNI RM machines
+ *
+ * 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) 2005-2006 Florian Lohoff (flo@rfc822.org)
+ * Copyright (C) 2005-2006 Thomas Bogendoerfer (tsbogend@alpha.franken.de)
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/string.h>
+
+#include <asm/addrspace.h>
+#include <asm/sni.h>
+#include <asm/mipsprom.h>
+#include <asm/bootinfo.h>
+
+/* special SNI prom calls */
+/*
+ * This does not exist in all proms - SINIX compares
+ * the prom env variable "version" against "2.0008"
+ * or greater. If lesser it tries to probe interesting
+ * registers
+ */
+#define PROM_GET_MEMCONF	58
+
+#define PROM_VEC		(u64 *)CKSEG1ADDR(0x1fc00000)
+#define PROM_ENTRY(x)		(PROM_VEC + (x))
+
+
+#undef DEBUG
+#ifdef DEBUG
+#define DBG_PRINTF(x...)     prom_printf(x)
+#else
+#define DBG_PRINTF(x...)
+#endif
+
+static int *(*__prom_putchar)(int)        = (int *(*)(int))PROM_ENTRY(PROM_PUTCHAR);
+static char *(*__prom_getenv)(char *)     = (char *(*)(char *))PROM_ENTRY(PROM_GETENV);
+static void (*__prom_get_memconf)(void *) = (void (*)(void *))PROM_ENTRY(PROM_GET_MEMCONF);
+
+char *prom_getenv (char *s)
+{
+	return __prom_getenv(s);
+}
+
+void prom_printf(char *fmt, ...)
+{
+	va_list args;
+	char ppbuf[1024];
+	char *bptr;
+
+	va_start(args, fmt);
+	vsprintf(ppbuf, fmt, args);
+
+	bptr = ppbuf;
+
+	while (*bptr != 0) {
+		if (*bptr == '\n')
+			__prom_putchar('\r');
+
+		__prom_putchar(*bptr++);
+	}
+	va_end(args);
+}
+
+unsigned long prom_free_prom_memory(void)
+{
+	return 0;
+}
+
+/*
+ * /proc/cpuinfo system type
+ *
+ */
+static const char *systype = "Unknown";
+const char *get_system_type(void)
+{
+	return systype;
+}
+
+#define SNI_IDPROM_BASE                0xbff00000
+#define SNI_IDPROM_MEMSIZE             (SNI_IDPROM_BASE+0x28)  /* Memsize in 16MB quantities */
+#define SNI_IDPROM_BRDTYPE             (SNI_IDPROM_BASE+0x29)  /* Board Type */
+#define SNI_IDPROM_CPUTYPE             (SNI_IDPROM_BASE+0x30)  /* CPU Type */
+
+#define SNI_IDPROM_SIZE	0x1000
+
+#ifdef DEBUG
+static void sni_idprom_dump(void)
+{
+	int	i;
+
+	prom_printf("SNI IDProm dump (first 128byte):\n");
+	for(i=0;i<128;i++) {
+		if (i%16 == 0)
+			prom_printf("%04x ", i);
+
+		prom_printf("%02x ", *(unsigned char *) (SNI_IDPROM_BASE+i));
+
+		if (i%16 == 15)
+			prom_printf("\n");
+	}
+}
+#endif
+
+static void sni_mem_init(void )
+{
+	int i, memsize;
+	struct membank {
+	        u32		size;
+	        u32		base;
+	        u32		size2;
+	        u32		pad1;
+	        u32		pad2;
+	} memconf[8];
+
+	/* MemSIZE from prom in 16MByte chunks */
+	memsize=*((unsigned char *) SNI_IDPROM_MEMSIZE) * 16;
+
+	DBG_PRINTF("IDProm memsize: %lu MByte\n", memsize);
+
+	/* get memory bank layout from prom */
+	__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,
+			memconf[i].size, memconf[i].base);
+		add_memory_region(memconf[i].base, memconf[i].size, BOOT_MEM_RAM);
+	}
+}
+
+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;
+
+	DBG_PRINTF("Found SNI brdtype %02x\n", sni_brd_type);
+
+#ifdef DEBUG
+	sni_idprom_dump();
+#endif
+	sni_mem_init();
+
+	/* copy prom cmdline parameters to kernel cmdline */
+	for (i = 1; i < argc; i++) {
+		strcat(arcs_cmdline, argv[i]);
+		if (i < (argc - 1))
+			strcat(arcs_cmdline, " ");
+	}
+}
+
diff --git a/arch/powerpc/boot/dts/mpc7448hpc2.dts b/arch/powerpc/boot/dts/mpc7448hpc2.dts
new file mode 100644
index 000000000..d7b985e6b
--- /dev/null
+++ b/arch/powerpc/boot/dts/mpc7448hpc2.dts
@@ -0,0 +1,190 @@
+/*
+ * MPC7448HPC2 (Taiga) board Device Tree Source
+ *
+ * Copyright 2006 Freescale Semiconductor Inc.
+ * 2006 Roy Zang <Roy Zang at freescale.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.
+ */
+
+
+/ {
+	model = "mpc7448hpc2";
+	compatible = "mpc74xx";
+	#address-cells = <1>;
+	#size-cells = <1>;
+	linux,phandle = <100>;
+
+	cpus {
+		#cpus = <1>;
+		#address-cells = <1>;
+		#size-cells =<0>;
+		linux,phandle = <200>;
+				
+		PowerPC,7448@0 {
+			device_type = "cpu";
+			reg = <0>;
+			d-cache-line-size = <20>;	// 32 bytes
+			i-cache-line-size = <20>;	// 32 bytes
+			d-cache-size = <8000>;		// L1, 32K bytes
+			i-cache-size = <8000>;		// L1, 32K bytes
+			timebase-frequency = <0>;	// 33 MHz, from uboot
+			clock-frequency = <0>;		// From U-Boot
+			bus-frequency = <0>;		// From U-Boot
+			32-bit;
+			linux,phandle = <201>;
+			linux,boot-cpu;
+		};
+	};
+
+	memory {
+		device_type = "memory";
+		linux,phandle = <300>;
+		reg = <00000000 20000000	// DDR2   512M at 0
+		       >;
+	};
+
+  	tsi108@c0000000 {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		#interrupt-cells = <2>;
+		device_type = "tsi-bridge";
+		ranges = <00000000 c0000000 00010000>;
+		reg = <c0000000 00010000>;
+		bus-frequency = <0>;
+
+		i2c@7000 {
+			interrupt-parent = <7400>;
+			interrupts = <E 0>;
+			reg = <7000 400>;
+			device_type = "i2c";
+			compatible  = "tsi-i2c";
+		};
+
+		mdio@6000 {
+			device_type = "mdio";
+			compatible = "tsi-ethernet";
+
+			ethernet-phy@6000 {
+				linux,phandle = <6000>;
+				interrupt-parent = <7400>;
+				interrupts = <2 1>;
+				reg = <6000 50>;
+				phy-id = <8>;
+				device_type = "ethernet-phy";
+			};
+
+			ethernet-phy@6400 {
+				linux,phandle = <6400>;
+				interrupt-parent = <7400>;
+				interrupts = <2 1>;
+				reg = <6000 50>;
+				phy-id = <9>;
+				device_type = "ethernet-phy";
+			};
+
+		};
+
+		ethernet@6200 {
+			#size-cells = <0>;
+			device_type = "network";
+			model = "TSI-ETH";
+			compatible = "tsi-ethernet";
+			reg = <6000 200>;
+			address = [ 00 06 D2 00 00 01 ];
+			interrupts = <10 2>;
+			interrupt-parent = <7400>;
+			phy-handle = <6000>;
+		};
+
+		ethernet@6600 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			device_type = "network";
+			model = "TSI-ETH";
+			compatible = "tsi-ethernet";
+			reg = <6400 200>;
+			address = [ 00 06 D2 00 00 02 ];
+			interrupts = <11 2>;
+			interrupt-parent = <7400>;
+			phy-handle = <6400>;
+		};
+
+		serial@7808 {
+			device_type = "serial";
+			compatible = "ns16550";
+			reg = <7808 200>;
+			clock-frequency = <3f6b5a00>;
+			interrupts = <c 0>;
+			interrupt-parent = <7400>;
+		};
+
+		serial@7c08 {
+			device_type = "serial";
+			compatible = "ns16550";
+			reg = <7c08 200>;
+			clock-frequency = <3f6b5a00>;
+			interrupts = <d 0>;
+			interrupt-parent = <7400>;
+		};
+
+	  	pic@7400 {
+			linux,phandle = <7400>;
+			clock-frequency = <0>;
+			interrupt-controller;
+			#address-cells = <0>;
+			#interrupt-cells = <2>;
+			reg = <7400 400>;
+			built-in;
+			compatible = "chrp,open-pic";
+			device_type = "open-pic";
+                       	big-endian;
+		};
+		pci@1000 {
+			compatible = "tsi10x";
+			device_type = "pci";
+			linux,phandle = <1000>;
+			#interrupt-cells = <1>;
+			#size-cells = <2>;
+			#address-cells = <3>;
+			reg = <1000 1000>;
+			bus-range = <0 0>;
+			ranges = <02000000 0 e0000000 e0000000 0 1A000000	
+				  01000000 0 00000000 fa000000 0 00010000>;
+			clock-frequency = <7f28154>;
+			interrupt-parent = <7400>;
+			interrupts = <17 2>;
+			interrupt-map-mask = <f800 0 0 7>;
+			interrupt-map = <
+
+				/* IDSEL 0x11 */
+				0800 0 0 1 7400 24 0
+				0800 0 0 2 7400 25 0
+				0800 0 0 3 7400 26 0
+				0800 0 0 4 7400 27 0
+
+				/* IDSEL 0x12 */
+				1000 0 0 1 7400 25 0
+				1000 0 0 2 7400 26 0
+				1000 0 0 3 7400 27 0
+				1000 0 0 4 7400 24 0
+
+				/* IDSEL 0x13 */
+				1800 0 0 1 7400 26 0
+				1800 0 0 2 7400 27 0
+				1800 0 0 3 7400 24 0
+				1800 0 0 4 7400 25 0
+
+				/* IDSEL 0x14 */
+				2000 0 0 1 7400 27 0
+				2000 0 0 2 7400 24 0
+				2000 0 0 3 7400 25 0
+				2000 0 0 4 7400 26 0
+				>;
+		};
+	};
+
+};
diff --git a/arch/powerpc/boot/dts/mpc8349emds.dts b/arch/powerpc/boot/dts/mpc8349emds.dts
new file mode 100644
index 000000000..12f5dbf30
--- /dev/null
+++ b/arch/powerpc/boot/dts/mpc8349emds.dts
@@ -0,0 +1,328 @@
+/*
+ * MPC8349E MDS Device Tree Source
+ *
+ * Copyright 2005, 2006 Freescale Semiconductor Inc.
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+/ {
+	model = "MPC8349EMDS";
+	compatible = "MPC834xMDS";
+	#address-cells = <1>;
+	#size-cells = <1>;
+
+	cpus {
+		#cpus = <1>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		PowerPC,8349@0 {
+			device_type = "cpu";
+			reg = <0>;
+			d-cache-line-size = <20>;	// 32 bytes
+			i-cache-line-size = <20>;	// 32 bytes
+			d-cache-size = <8000>;		// L1, 32K
+			i-cache-size = <8000>;		// L1, 32K
+			timebase-frequency = <0>;	// from bootloader
+			bus-frequency = <0>;		// from bootloader
+			clock-frequency = <0>;		// from bootloader
+			32-bit;
+		};
+	};
+
+	memory {
+		device_type = "memory";
+		reg = <00000000 10000000>;	// 256MB at 0
+	};
+
+	soc8349@e0000000 {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		#interrupt-cells = <2>;
+		device_type = "soc";
+		ranges = <0 e0000000 00100000>;
+		reg = <e0000000 00000200>;
+		bus-frequency = <0>;
+
+		wdt@200 {
+			device_type = "watchdog";
+			compatible = "mpc83xx_wdt";
+			reg = <200 100>;
+		};
+
+		i2c@3000 {
+			device_type = "i2c";
+			compatible = "fsl-i2c";
+			reg = <3000 100>;
+			interrupts = <e 8>;
+			interrupt-parent = <700>;
+			dfsrr;
+		};
+
+		i2c@3100 {
+			device_type = "i2c";
+			compatible = "fsl-i2c";
+			reg = <3100 100>;
+			interrupts = <f 8>;
+			interrupt-parent = <700>;
+			dfsrr;
+		};
+
+		spi@7000 {
+			device_type = "spi";
+			compatible = "mpc83xx_spi";
+			reg = <7000 1000>;
+			interrupts = <10 8>;
+			interrupt-parent = <700>;
+			mode = <0>;
+		};
+
+		/* phy type (ULPI or SERIAL) are only types supportted for MPH */
+		/* port = 0 or 1 */
+		usb@22000 {
+			device_type = "usb";
+			compatible = "fsl-usb2-mph";
+			reg = <22000 1000>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			interrupt-parent = <700>;
+			interrupts = <27 2>;
+			phy_type = "ulpi";
+			port1;
+		};
+		/* phy type (ULPI, UTMI, UTMI_WIDE, SERIAL) */
+		usb@23000 {
+			device_type = "usb";
+			compatible = "fsl-usb2-dr";
+			reg = <23000 1000>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			interrupt-parent = <700>;
+			interrupts = <26 2>;
+			phy_type = "ulpi";
+		};
+
+		mdio@24520 {
+			device_type = "mdio";
+			compatible = "gianfar";
+			reg = <24520 20>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			linux,phandle = <24520>;
+			ethernet-phy@0 {
+				linux,phandle = <2452000>;
+				interrupt-parent = <700>;
+				interrupts = <11 2>;
+				reg = <0>;
+				device_type = "ethernet-phy";
+			};
+			ethernet-phy@1 {
+				linux,phandle = <2452001>;
+				interrupt-parent = <700>;
+				interrupts = <12 2>;
+				reg = <1>;
+				device_type = "ethernet-phy";
+			};
+		};
+
+		ethernet@24000 {
+			device_type = "network";
+			model = "TSEC";
+			compatible = "gianfar";
+			reg = <24000 1000>;
+			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>;
+		};
+
+		ethernet@25000 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			device_type = "network";
+			model = "TSEC";
+			compatible = "gianfar";
+			reg = <25000 1000>;
+			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>;
+		};
+
+		serial@4500 {
+			device_type = "serial";
+			compatible = "ns16550";
+			reg = <4500 100>;
+			clock-frequency = <0>;
+			interrupts = <9 8>;
+			interrupt-parent = <700>;
+		};
+
+		serial@4600 {
+			device_type = "serial";
+			compatible = "ns16550";
+			reg = <4600 100>;
+			clock-frequency = <0>;
+			interrupts = <a 8>;
+			interrupt-parent = <700>;
+		};
+
+		pci@8500 {
+			interrupt-map-mask = <f800 0 0 7>;
+			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
+
+					/* 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
+
+					/* 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
+
+					/* 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
+
+					/* 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
+
+					/* 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
+
+					/* IDSEL 0x18 */
+					 b000 0 0 1 700 15 8
+					 b000 0 0 2 700 16 8
+					 b000 0 0 3 700 17 8
+					 b000 0 0 4 700 14 8>;
+			interrupt-parent = <700>;
+			interrupts = <42 8>;
+			bus-range = <0 0>;
+			ranges = <02000000 0 a0000000 a0000000 0 10000000
+				  42000000 0 80000000 80000000 0 10000000
+				  01000000 0 00000000 e2000000 0 00100000>;
+			clock-frequency = <3f940aa>;
+			#interrupt-cells = <1>;
+			#size-cells = <2>;
+			#address-cells = <3>;
+			reg = <8500 100>;
+			compatible = "83xx";
+			device_type = "pci";
+		};
+
+		pci@8600 {
+			interrupt-map-mask = <f800 0 0 7>;
+			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
+
+					/* 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
+
+					/* 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
+
+					/* 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
+
+					/* 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
+
+					/* 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
+
+					/* IDSEL 0x18 */
+					 b000 0 0 1 700 15 8
+					 b000 0 0 2 700 16 8
+					 b000 0 0 3 700 17 8
+					 b000 0 0 4 700 14 8>;
+			interrupt-parent = <700>;
+			interrupts = <42 8>;
+			bus-range = <0 0>;
+			ranges = <02000000 0 b0000000 b0000000 0 10000000
+				  42000000 0 90000000 90000000 0 10000000
+				  01000000 0 00000000 e2100000 0 00100000>;
+			clock-frequency = <3f940aa>;
+			#interrupt-cells = <1>;
+			#size-cells = <2>;
+			#address-cells = <3>;
+			reg = <8600 100>;
+			compatible = "83xx";
+			device_type = "pci";
+		};
+
+		/* May need to remove if on a part without crypto engine */
+		crypto@30000 {
+			device_type = "crypto";
+			model = "SEC2";
+			compatible = "talitos";
+			reg = <30000 10000>;
+			interrupts = <b 8>;
+			interrupt-parent = <700>;
+			num-channels = <4>;
+			channel-fifo-len = <18>;
+			exec-units-mask = <0000007e>;
+			/* desc mask is for rev2.0,
+			 * we need runtime fixup for >2.0 */
+			descriptor-types-mask = <01010ebf>;
+		};
+
+		/* IPIC
+		 * interrupts cell = <intr #, sense>
+		 * sense values match linux IORESOURCE_IRQ_* defines:
+		 * sense == 8: Level, low assertion
+		 * sense == 2: Edge, high-to-low change
+		 */
+		pic@700 {
+			linux,phandle = <700>;
+			interrupt-controller;
+			#address-cells = <0>;
+			#interrupt-cells = <2>;
+			reg = <700 100>;
+			built-in;
+			device_type = "ipic";
+		};
+	};
+};
diff --git a/arch/powerpc/boot/dts/mpc8540ads.dts b/arch/powerpc/boot/dts/mpc8540ads.dts
new file mode 100644
index 000000000..5f41c1f7a
--- /dev/null
+++ b/arch/powerpc/boot/dts/mpc8540ads.dts
@@ -0,0 +1,257 @@
+/*
+ * MPC8540 ADS Device Tree Source
+ *
+ * Copyright 2006 Freescale Semiconductor Inc.
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+
+/ {
+	model = "MPC8540ADS";
+	compatible = "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";
+			reg = <0>;
+			d-cache-line-size = <20>;	// 32 bytes
+			i-cache-line-size = <20>;	// 32 bytes
+			d-cache-size = <8000>;		// L1, 32K
+			i-cache-size = <8000>;		// L1, 32K
+			timebase-frequency = <0>;	//  33 MHz, from uboot
+			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
+	};
+
+	soc8540@e0000000 {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		#interrupt-cells = <2>;
+		device_type = "soc";
+		ranges = <0 e0000000 00100000>;
+		reg = <e0000000 00100000>;	// CCSRBAR 1M
+		bus-frequency = <0>;
+
+		i2c@3000 {
+			device_type = "i2c";
+			compatible = "fsl-i2c";
+			reg = <3000 100>;
+			interrupts = <1b 2>;
+			interrupt-parent = <40000>;
+			dfsrr;
+		};
+
+		mdio@24520 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			device_type = "mdio";
+			compatible = "gianfar";
+			reg = <24520 20>;
+			linux,phandle = <24520>;
+			ethernet-phy@0 {
+				linux,phandle = <2452000>;
+				interrupt-parent = <40000>;
+				interrupts = <35 1>;
+				reg = <0>;
+				device_type = "ethernet-phy";
+			};
+			ethernet-phy@1 {
+				linux,phandle = <2452001>;
+				interrupt-parent = <40000>;
+				interrupts = <35 1>;
+				reg = <1>;
+				device_type = "ethernet-phy";
+			};
+			ethernet-phy@3 {
+				linux,phandle = <2452003>;
+				interrupt-parent = <40000>;
+				interrupts = <37 1>;
+				reg = <3>;
+				device_type = "ethernet-phy";
+			};
+		};
+
+		ethernet@24000 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			device_type = "network";
+			model = "TSEC";
+			compatible = "gianfar";
+			reg = <24000 1000>;
+			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>;
+		};
+
+		ethernet@25000 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			device_type = "network";
+			model = "TSEC";
+			compatible = "gianfar";
+			reg = <25000 1000>;
+			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>;
+		};
+
+		ethernet@26000 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			device_type = "network";
+			model = "FEC";
+			compatible = "gianfar";
+			reg = <26000 1000>;
+			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>;
+		};
+
+		serial@4500 {
+			device_type = "serial";
+			compatible = "ns16550";
+			reg = <4500 100>; 	// reg base, size
+			clock-frequency = <0>; 	// should we fill in in uboot?
+			interrupts = <1a 2>;
+			interrupt-parent = <40000>;
+		};
+
+		serial@4600 {
+			device_type = "serial";
+			compatible = "ns16550";
+			reg = <4600 100>;	// reg base, size
+			clock-frequency = <0>; 	// should we fill in in uboot?
+			interrupts = <1a 2>;
+			interrupt-parent = <40000>;
+		};
+		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
+
+				/* 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
+
+				/* 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
+
+				/* 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
+
+				/* 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
+
+				/* 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
+
+				/* 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
+
+				/* 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
+
+				/* 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
+
+				/* 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
+
+				/* 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
+
+				/* 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>;
+			interrupts = <08 2>;
+			bus-range = <0 0>;
+			ranges = <02000000 0 80000000 80000000 0 20000000
+				  01000000 0 00000000 e2000000 0 00100000>;
+			clock-frequency = <3f940aa>;
+			#interrupt-cells = <1>;
+			#size-cells = <2>;
+			#address-cells = <3>;
+			reg = <8000 1000>;
+			compatible = "85xx";
+			device_type = "pci";
+		};
+
+		pic@40000 {
+			linux,phandle = <40000>;
+			clock-frequency = <0>;
+			interrupt-controller;
+			#address-cells = <0>;
+			#interrupt-cells = <2>;
+			reg = <40000 40000>;
+			built-in;
+			compatible = "chrp,open-pic";
+			device_type = "open-pic";
+			big-endian;
+		};
+	};
+};
diff --git a/arch/powerpc/boot/dts/mpc8541cds.dts b/arch/powerpc/boot/dts/mpc8541cds.dts
new file mode 100644
index 000000000..7be0bc659
--- /dev/null
+++ b/arch/powerpc/boot/dts/mpc8541cds.dts
@@ -0,0 +1,244 @@
+/*
+ * MPC8541 CDS Device Tree Source
+ *
+ * Copyright 2006 Freescale Semiconductor Inc.
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+
+/ {
+	model = "MPC8541CDS";
+	compatible = "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";
+			reg = <0>;
+			d-cache-line-size = <20>;	// 32 bytes
+			i-cache-line-size = <20>;	// 32 bytes
+			d-cache-size = <8000>;		// L1, 32K
+			i-cache-size = <8000>;		// L1, 32K
+			timebase-frequency = <0>;	//  33 MHz, from uboot
+			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
+	};
+
+	soc8541@e0000000 {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		#interrupt-cells = <2>;
+		device_type = "soc";
+		ranges = <0 e0000000 00100000>;
+		reg = <e0000000 00100000>;	// CCSRBAR 1M
+		bus-frequency = <0>;
+
+		i2c@3000 {
+			device_type = "i2c";
+			compatible = "fsl-i2c";
+			reg = <3000 100>;
+			interrupts = <1b 2>;
+			interrupt-parent = <40000>;
+			dfsrr;
+		};
+
+		mdio@24520 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			device_type = "mdio";
+			compatible = "gianfar";
+			reg = <24520 20>;
+			linux,phandle = <24520>;
+			ethernet-phy@0 {
+				linux,phandle = <2452000>;
+				interrupt-parent = <40000>;
+				interrupts = <35 0>;
+				reg = <0>;
+				device_type = "ethernet-phy";
+			};
+			ethernet-phy@1 {
+				linux,phandle = <2452001>;
+				interrupt-parent = <40000>;
+				interrupts = <35 0>;
+				reg = <1>;
+				device_type = "ethernet-phy";
+			};
+		};
+
+		ethernet@24000 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			device_type = "network";
+			model = "TSEC";
+			compatible = "gianfar";
+			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>;
+		};
+
+		ethernet@25000 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			device_type = "network";
+			model = "TSEC";
+			compatible = "gianfar";
+			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>;
+		};
+
+		serial@4500 {
+			device_type = "serial";
+			compatible = "ns16550";
+			reg = <4500 100>; 	// reg base, size
+			clock-frequency = <0>; 	// should we fill in in uboot?
+			interrupts = <1a 2>;
+			interrupt-parent = <40000>;
+		};
+
+		serial@4600 {
+			device_type = "serial";
+			compatible = "ns16550";
+			reg = <4600 100>;	// reg base, size
+			clock-frequency = <0>; 	// should we fill in in uboot?
+			interrupts = <1a 2>;
+			interrupt-parent = <40000>;
+		};
+
+		pci@8000 {
+			linux,phandle = <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
+
+				/* 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
+
+				/* 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
+
+				/* 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
+
+				/* 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
+
+				/* 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
+
+				/* 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>;
+			interrupts = <08 2>;
+			bus-range = <0 0>;
+			ranges = <02000000 0 80000000 80000000 0 20000000
+				  01000000 0 00000000 e2000000 0 00100000>;
+			clock-frequency = <3f940aa>;
+			#interrupt-cells = <1>;
+			#size-cells = <2>;
+			#address-cells = <3>;
+			reg = <8000 1000>;
+			compatible = "85xx";
+			device_type = "pci";
+
+			i8259@19000 {
+				clock-frequency = <0>;
+				interrupt-controller;
+				device_type = "interrupt-controller";
+				reg = <19000 0 0 0 1>;
+				#address-cells = <0>;
+				#interrupt-cells = <2>;
+				built-in;
+				compatible = "chrp,iic";
+				big-endian;
+				interrupts = <1>;
+				interrupt-parent = <8000>;
+			};
+		};
+
+		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>;
+			interrupts = <09 2>;
+			bus-range = <0 0>;
+			ranges = <02000000 0 a0000000 a0000000 0 20000000
+				  01000000 0 00000000 e3000000 0 00100000>;
+			clock-frequency = <3f940aa>;
+			#interrupt-cells = <1>;
+			#size-cells = <2>;
+			#address-cells = <3>;
+			reg = <9000 1000>;
+			compatible = "85xx";
+			device_type = "pci";
+		};
+
+		pic@40000 {
+			linux,phandle = <40000>;
+			clock-frequency = <0>;
+			interrupt-controller;
+			#address-cells = <0>;
+			#interrupt-cells = <2>;
+			reg = <40000 40000>;
+			built-in;
+			compatible = "chrp,open-pic";
+			device_type = "open-pic";
+                        big-endian;
+		};
+	};
+};
diff --git a/arch/powerpc/boot/dts/mpc8548cds.dts b/arch/powerpc/boot/dts/mpc8548cds.dts
new file mode 100644
index 000000000..893d7957c
--- /dev/null
+++ b/arch/powerpc/boot/dts/mpc8548cds.dts
@@ -0,0 +1,287 @@
+/*
+ * MPC8555 CDS Device Tree Source
+ *
+ * Copyright 2006 Freescale Semiconductor Inc.
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+
+/ {
+	model = "MPC8548CDS";
+	compatible = "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";
+			reg = <0>;
+			d-cache-line-size = <20>;	// 32 bytes
+			i-cache-line-size = <20>;	// 32 bytes
+			d-cache-size = <8000>;		// L1, 32K
+			i-cache-size = <8000>;		// L1, 32K
+			timebase-frequency = <0>;	//  33 MHz, from uboot
+			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
+	};
+
+	soc8548@e0000000 {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		#interrupt-cells = <2>;
+		device_type = "soc";
+		ranges = <0 e0000000 00100000>;
+		reg = <e0000000 00100000>;	// CCSRBAR 1M
+		bus-frequency = <0>;
+
+		i2c@3000 {
+			device_type = "i2c";
+			compatible = "fsl-i2c";
+			reg = <3000 100>;
+			interrupts = <1b 2>;
+			interrupt-parent = <40000>;
+			dfsrr;
+		};
+
+		mdio@24520 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			device_type = "mdio";
+			compatible = "gianfar";
+			reg = <24520 20>;
+			linux,phandle = <24520>;
+			ethernet-phy@0 {
+				linux,phandle = <2452000>;
+				interrupt-parent = <40000>;
+				interrupts = <35 0>;
+				reg = <0>;
+				device_type = "ethernet-phy";
+			};
+			ethernet-phy@1 {
+				linux,phandle = <2452001>;
+				interrupt-parent = <40000>;
+				interrupts = <35 0>;
+				reg = <1>;
+				device_type = "ethernet-phy";
+			};
+
+			ethernet-phy@2 {
+				linux,phandle = <2452002>;
+				interrupt-parent = <40000>;
+				interrupts = <35 0>;
+				reg = <2>;
+				device_type = "ethernet-phy";
+			};
+			ethernet-phy@3 {
+				linux,phandle = <2452003>;
+				interrupt-parent = <40000>;
+				interrupts = <35 0>;
+				reg = <3>;
+				device_type = "ethernet-phy";
+			};
+		};
+
+		ethernet@24000 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			device_type = "network";
+			model = "eTSEC";
+			compatible = "gianfar";
+			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>;
+		};
+
+		ethernet@25000 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			device_type = "network";
+			model = "eTSEC";
+			compatible = "gianfar";
+			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>;
+		};
+
+		ethernet@26000 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			device_type = "network";
+			model = "eTSEC";
+			compatible = "gianfar";
+			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>;
+		};
+
+/* eTSEC 4 is currently broken
+		ethernet@27000 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			device_type = "network";
+			model = "eTSEC";
+			compatible = "gianfar";
+			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>;
+		};
+ */
+
+		serial@4500 {
+			device_type = "serial";
+			compatible = "ns16550";
+			reg = <4500 100>; 	// reg base, size
+			clock-frequency = <0>; 	// should we fill in in uboot?
+			interrupts = <1a 2>;
+			interrupt-parent = <40000>;
+		};
+
+		serial@4600 {
+			device_type = "serial";
+			compatible = "ns16550";
+			reg = <4600 100>;	// reg base, size
+			clock-frequency = <0>; 	// should we fill in in uboot?
+			interrupts = <1a 2>;
+			interrupt-parent = <40000>;
+		};
+
+		pci@8000 {
+			linux,phandle = <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
+
+				/* 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
+
+				/* 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
+
+				/* 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
+
+				/* 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
+
+				/* 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
+
+				/* 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>;
+			interrupts = <08 2>;
+			bus-range = <0 0>;
+			ranges = <02000000 0 80000000 80000000 0 20000000
+				  01000000 0 00000000 e2000000 0 00100000>;
+			clock-frequency = <3f940aa>;
+			#interrupt-cells = <1>;
+			#size-cells = <2>;
+			#address-cells = <3>;
+			reg = <8000 1000>;
+			compatible = "85xx";
+			device_type = "pci";
+
+			i8259@19000 {
+				clock-frequency = <0>;
+				interrupt-controller;
+				device_type = "interrupt-controller";
+				reg = <19000 0 0 0 1>;
+				#address-cells = <0>;
+				#interrupt-cells = <2>;
+				built-in;
+				compatible = "chrp,iic";
+				big-endian;
+				interrupts = <1>;
+				interrupt-parent = <8000>;
+			};
+		};
+
+		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>;
+			interrupts = <09 2>;
+			bus-range = <0 0>;
+			ranges = <02000000 0 a0000000 a0000000 0 20000000
+				  01000000 0 00000000 e3000000 0 00100000>;
+			clock-frequency = <3f940aa>;
+			#interrupt-cells = <1>;
+			#size-cells = <2>;
+			#address-cells = <3>;
+			reg = <9000 1000>;
+			compatible = "85xx";
+			device_type = "pci";
+		};
+
+		pic@40000 {
+			linux,phandle = <40000>;
+			clock-frequency = <0>;
+			interrupt-controller;
+			#address-cells = <0>;
+			#interrupt-cells = <2>;
+			reg = <40000 40000>;
+			built-in;
+			compatible = "chrp,open-pic";
+			device_type = "open-pic";
+                        big-endian;
+		};
+	};
+};
diff --git a/arch/powerpc/boot/dts/mpc8555cds.dts b/arch/powerpc/boot/dts/mpc8555cds.dts
new file mode 100644
index 000000000..118f5a887
--- /dev/null
+++ b/arch/powerpc/boot/dts/mpc8555cds.dts
@@ -0,0 +1,244 @@
+/*
+ * MPC8555 CDS Device Tree Source
+ *
+ * Copyright 2006 Freescale Semiconductor Inc.
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+
+/ {
+	model = "MPC8555CDS";
+	compatible = "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";
+			reg = <0>;
+			d-cache-line-size = <20>;	// 32 bytes
+			i-cache-line-size = <20>;	// 32 bytes
+			d-cache-size = <8000>;		// L1, 32K
+			i-cache-size = <8000>;		// L1, 32K
+			timebase-frequency = <0>;	//  33 MHz, from uboot
+			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
+	};
+
+	soc8555@e0000000 {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		#interrupt-cells = <2>;
+		device_type = "soc";
+		ranges = <0 e0000000 00100000>;
+		reg = <e0000000 00100000>;	// CCSRBAR 1M
+		bus-frequency = <0>;
+
+		i2c@3000 {
+			device_type = "i2c";
+			compatible = "fsl-i2c";
+			reg = <3000 100>;
+			interrupts = <1b 2>;
+			interrupt-parent = <40000>;
+			dfsrr;
+		};
+
+		mdio@24520 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			device_type = "mdio";
+			compatible = "gianfar";
+			reg = <24520 20>;
+			linux,phandle = <24520>;
+			ethernet-phy@0 {
+				linux,phandle = <2452000>;
+				interrupt-parent = <40000>;
+				interrupts = <35 0>;
+				reg = <0>;
+				device_type = "ethernet-phy";
+			};
+			ethernet-phy@1 {
+				linux,phandle = <2452001>;
+				interrupt-parent = <40000>;
+				interrupts = <35 0>;
+				reg = <1>;
+				device_type = "ethernet-phy";
+			};
+		};
+
+		ethernet@24000 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			device_type = "network";
+			model = "TSEC";
+			compatible = "gianfar";
+			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>;
+		};
+
+		ethernet@25000 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			device_type = "network";
+			model = "TSEC";
+			compatible = "gianfar";
+			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>;
+		};
+
+		serial@4500 {
+			device_type = "serial";
+			compatible = "ns16550";
+			reg = <4500 100>; 	// reg base, size
+			clock-frequency = <0>; 	// should we fill in in uboot?
+			interrupts = <1a 2>;
+			interrupt-parent = <40000>;
+		};
+
+		serial@4600 {
+			device_type = "serial";
+			compatible = "ns16550";
+			reg = <4600 100>;	// reg base, size
+			clock-frequency = <0>; 	// should we fill in in uboot?
+			interrupts = <1a 2>;
+			interrupt-parent = <40000>;
+		};
+
+		pci@8000 {
+			linux,phandle = <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
+
+				/* 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
+
+				/* 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
+
+				/* 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
+
+				/* 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
+
+				/* 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
+
+				/* 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>;
+			interrupts = <08 2>;
+			bus-range = <0 0>;
+			ranges = <02000000 0 80000000 80000000 0 20000000
+				  01000000 0 00000000 e2000000 0 00100000>;
+			clock-frequency = <3f940aa>;
+			#interrupt-cells = <1>;
+			#size-cells = <2>;
+			#address-cells = <3>;
+			reg = <8000 1000>;
+			compatible = "85xx";
+			device_type = "pci";
+
+			i8259@19000 {
+				clock-frequency = <0>;
+				interrupt-controller;
+				device_type = "interrupt-controller";
+				reg = <19000 0 0 0 1>;
+				#address-cells = <0>;
+				#interrupt-cells = <2>;
+				built-in;
+				compatible = "chrp,iic";
+				big-endian;
+				interrupts = <1>;
+				interrupt-parent = <8000>;
+			};
+		};
+
+		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>;
+			interrupts = <09 2>;
+			bus-range = <0 0>;
+			ranges = <02000000 0 a0000000 a0000000 0 20000000
+				  01000000 0 00000000 e3000000 0 00100000>;
+			clock-frequency = <3f940aa>;
+			#interrupt-cells = <1>;
+			#size-cells = <2>;
+			#address-cells = <3>;
+			reg = <9000 1000>;
+			compatible = "85xx";
+			device_type = "pci";
+		};
+
+		pic@40000 {
+			linux,phandle = <40000>;
+			clock-frequency = <0>;
+			interrupt-controller;
+			#address-cells = <0>;
+			#interrupt-cells = <2>;
+			reg = <40000 40000>;
+			built-in;
+			compatible = "chrp,open-pic";
+			device_type = "open-pic";
+                        big-endian;
+		};
+	};
+};
diff --git a/arch/powerpc/boot/dts/mpc8641_hpcn.dts b/arch/powerpc/boot/dts/mpc8641_hpcn.dts
new file mode 100644
index 000000000..f0c773174
--- /dev/null
+++ b/arch/powerpc/boot/dts/mpc8641_hpcn.dts
@@ -0,0 +1,339 @@
+/*
+ * MPC8641 HPCN Device Tree Source
+ *
+ * Copyright 2006 Freescale Semiconductor Inc.
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+
+/ {
+	model = "MPC8641HPCN";
+	compatible = "mpc86xx";
+	#address-cells = <1>;
+	#size-cells = <1>;
+
+	cpus {
+		#cpus = <2>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		PowerPC,8641@0 {
+			device_type = "cpu";
+			reg = <0>;
+			d-cache-line-size = <20>;	// 32 bytes
+			i-cache-line-size = <20>;	// 32 bytes
+			d-cache-size = <8000>;		// L1, 32K
+			i-cache-size = <8000>;		// L1, 32K
+			timebase-frequency = <0>;	// 33 MHz, from uboot
+			bus-frequency = <0>;		// From uboot
+			clock-frequency = <0>;		// From uboot
+			32-bit;
+			linux,boot-cpu;
+		};
+		PowerPC,8641@1 {
+			device_type = "cpu";
+			reg = <1>;
+			d-cache-line-size = <20>;	// 32 bytes
+			i-cache-line-size = <20>;	// 32 bytes
+			d-cache-size = <8000>;		// L1, 32K
+			i-cache-size = <8000>;		// L1, 32K
+			timebase-frequency = <0>;	// 33 MHz, from uboot
+			bus-frequency = <0>;		// From uboot
+			clock-frequency = <0>;		// From uboot
+			32-bit;
+		};
+	};
+
+	memory {
+		device_type = "memory";
+		reg = <00000000 40000000>;	// 1G at 0x0
+	};
+
+	soc8641@f8000000 {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		#interrupt-cells = <2>;
+		device_type = "soc";
+		ranges = <0 f8000000 00100000>;
+		reg = <f8000000 00100000>;	// CCSRBAR 1M
+		bus-frequency = <0>;
+
+		i2c@3000 {
+			device_type = "i2c";
+			compatible = "fsl-i2c";
+			reg = <3000 100>;
+			interrupts = <2b 2>;
+			interrupt-parent = <40000>;
+			dfsrr;
+		};
+
+		i2c@3100 {
+			device_type = "i2c";
+			compatible = "fsl-i2c";
+			reg = <3100 100>;
+			interrupts = <2b 2>;
+			interrupt-parent = <40000>;
+			dfsrr;
+		};
+
+		mdio@24520 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			device_type = "mdio";
+			compatible = "gianfar";
+			reg = <24520 20>;
+			linux,phandle = <24520>;
+			ethernet-phy@0 {
+				linux,phandle = <2452000>;
+				interrupt-parent = <40000>;
+				interrupts = <4a 1>;
+				reg = <0>;
+				device_type = "ethernet-phy";
+			};
+			ethernet-phy@1 {
+				linux,phandle = <2452001>;
+				interrupt-parent = <40000>;
+				interrupts = <4a 1>;
+				reg = <1>;
+				device_type = "ethernet-phy";
+			};
+			ethernet-phy@2 {
+				linux,phandle = <2452002>;
+				interrupt-parent = <40000>;
+				interrupts = <4a 1>;
+				reg = <2>;
+				device_type = "ethernet-phy";
+			};
+			ethernet-phy@3 {
+				linux,phandle = <2452003>;
+				interrupt-parent = <40000>;
+				interrupts = <4a 1>;
+				reg = <3>;
+				device_type = "ethernet-phy";
+			};
+		};
+
+		ethernet@24000 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			device_type = "network";
+			model = "TSEC";
+			compatible = "gianfar";
+			reg = <24000 1000>;
+			mac-address = [ 00 E0 0C 00 73 00 ];
+			interrupts = <1d 2 1e 2 22 2>;
+			interrupt-parent = <40000>;
+			phy-handle = <2452000>;
+		};
+
+		ethernet@25000 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			device_type = "network";
+			model = "TSEC";
+			compatible = "gianfar";
+			reg = <25000 1000>;
+			mac-address = [ 00 E0 0C 00 73 01 ];
+			interrupts = <23 2 24 2 28 2>;
+			interrupt-parent = <40000>;
+			phy-handle = <2452001>;
+		};
+		
+		ethernet@26000 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			device_type = "network";
+			model = "TSEC";
+			compatible = "gianfar";
+			reg = <26000 1000>;
+			mac-address = [ 00 E0 0C 00 02 FD ];
+			interrupts = <1F 2 20 2 21 2>;
+			interrupt-parent = <40000>;
+			phy-handle = <2452002>;
+		};
+
+		ethernet@27000 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			device_type = "network";
+			model = "TSEC";
+			compatible = "gianfar";
+			reg = <27000 1000>;
+			mac-address = [ 00 E0 0C 00 03 FD ];
+			interrupts = <25 2 26 2 27 2>;
+			interrupt-parent = <40000>;
+			phy-handle = <2452003>;
+		};
+		serial@4500 {
+			device_type = "serial";
+			compatible = "ns16550";
+			reg = <4500 100>;
+			clock-frequency = <0>;
+			interrupts = <2a 2>;
+			interrupt-parent = <40000>;
+		};
+
+		serial@4600 {
+			device_type = "serial";
+			compatible = "ns16550";
+			reg = <4600 100>;
+			clock-frequency = <0>;
+			interrupts = <1c 2>;
+			interrupt-parent = <40000>;
+		};
+
+		pci@8000 {
+			compatible = "86xx";
+			device_type = "pci";
+			#interrupt-cells = <1>;
+			#size-cells = <2>;
+			#address-cells = <3>;
+			reg = <8000 1000>;
+			bus-range = <0 fe>;
+			ranges = <02000000 0 80000000 80000000 0 20000000
+				  01000000 0 00000000 e2000000 0 00100000>;
+			clock-frequency = <1fca055>;
+			interrupt-parent = <40000>;
+			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
+
+				/* 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
+
+				/* 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
+
+				/* 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
+
+				/* 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
+
+				/* 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
+
+				/* 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
+
+				/* 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
+
+				/* 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
+
+				/* 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
+
+
+				/* 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
+
+				/* 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
+
+				/* 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
+
+				/* 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
+
+				/* 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
+				>;
+			i8259@4d0 {
+				linux,phandle = <4d0>;
+				clock-frequency = <0>;
+				interrupt-controller;
+				device_type = "interrupt-controller";
+				#address-cells = <0>;
+				#interrupt-cells = <2>;
+				built-in;
+				compatible = "chrp,iic";
+                	        big-endian;
+				interrupts = <49 2>;
+				interrupt-parent = <40000>;
+			};
+
+		};
+		pic@40000 {
+			linux,phandle = <40000>;
+			clock-frequency = <0>;
+			interrupt-controller;
+			#address-cells = <0>;
+			#interrupt-cells = <2>;
+			reg = <40000 40000>;
+			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>;
+		};
+	};
+};
diff --git a/arch/powerpc/configs/chrp32_defconfig b/arch/powerpc/configs/chrp32_defconfig
new file mode 100644
index 000000000..bbf2b5f8a
--- /dev/null
+++ b/arch/powerpc/configs/chrp32_defconfig
@@ -0,0 +1,1397 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.18-rc6
+# Sun Sep 10 10:22:54 2006
+#
+# CONFIG_PPC64 is not set
+CONFIG_PPC32=y
+CONFIG_PPC_MERGE=y
+CONFIG_MMU=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_IRQ_PER_CPU=y
+CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_PPC=y
+CONFIG_EARLY_PRINTK=y
+CONFIG_GENERIC_NVRAM=y
+CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
+CONFIG_ARCH_MAY_HAVE_PC_FDC=y
+CONFIG_PPC_OF=y
+CONFIG_PPC_UDBG_16550=y
+CONFIG_GENERIC_TBSYNC=y
+# CONFIG_DEFAULT_UIMAGE is not set
+
+#
+# Processor support
+#
+CONFIG_CLASSIC32=y
+# CONFIG_PPC_52xx is not set
+# CONFIG_PPC_82xx is not set
+# CONFIG_PPC_83xx is not set
+# CONFIG_PPC_85xx is not set
+# CONFIG_PPC_86xx 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_PPC_FPU=y
+# CONFIG_ALTIVEC is not set
+CONFIG_PPC_STD_MMU=y
+CONFIG_PPC_STD_MMU_32=y
+CONFIG_SMP=y
+CONFIG_NR_CPUS=4
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_POSIX_MQUEUE=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_TASKSTATS is not set
+CONFIG_SYSCTL=y
+# CONFIG_AUDIT is not set
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+# CONFIG_CPUSETS is not set
+# CONFIG_RELAY is not set
+CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+# CONFIG_EMBEDDED 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_RT_MUTEXES=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SHMEM=y
+CONFIG_SLAB=y
+CONFIG_VM_EVENT_COUNTERS=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 is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_KMOD=y
+CONFIG_STOP_MACHINE=y
+
+#
+# Block layer
+#
+CONFIG_LBD=y
+# 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=y
+CONFIG_IOSCHED_CFQ=y
+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"
+
+#
+# Platform support
+#
+CONFIG_PPC_MULTIPLATFORM=y
+# CONFIG_PPC_ISERIES is not set
+# CONFIG_EMBEDDED6xx is not set
+# CONFIG_APUS is not set
+CONFIG_PPC_CHRP=y
+# CONFIG_PPC_PMAC is not set
+# CONFIG_PPC_CELL is not set
+# CONFIG_PPC_CELL_NATIVE is not set
+# CONFIG_UDBG_RTAS_CONSOLE is not set
+CONFIG_PPC_RTAS=y
+# CONFIG_RTAS_ERROR_LOGGING is not set
+CONFIG_RTAS_PROC=y
+# CONFIG_MMIO_NVRAM is not set
+CONFIG_PPC_MPC106=y
+# CONFIG_PPC_970_NAP is not set
+# CONFIG_CPU_FREQ is not set
+# CONFIG_TAU is not set
+# CONFIG_WANT_EARLY_SERIAL is not set
+CONFIG_MPIC=y
+
+#
+# Kernel options
+#
+CONFIG_HIGHMEM=y
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
+CONFIG_PREEMPT_BKL=y
+CONFIG_BINFMT_ELF=y
+CONFIG_BINFMT_MISC=y
+CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
+# CONFIG_KEXEC is not set
+CONFIG_IRQ_ALL_CPUS=y
+CONFIG_ARCH_FLATMEM_ENABLE=y
+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=4
+# CONFIG_RESOURCES_64BIT is not set
+CONFIG_PROC_DEVICETREE=y
+# CONFIG_CMDLINE_BOOL is not set
+# CONFIG_PM is not set
+CONFIG_SECCOMP=y
+CONFIG_ISA_DMA_API=y
+
+#
+# Bus options
+#
+CONFIG_ISA=y
+CONFIG_GENERIC_ISA_DMA=y
+# CONFIG_MPIC_WEIRD is not set
+CONFIG_PPC_I8259=y
+CONFIG_PPC_INDIRECT_PCI=y
+CONFIG_PCI=y
+CONFIG_PCI_DOMAINS=y
+# CONFIG_PCIEPORTBUS is not set
+# CONFIG_PCI_DEBUG is not set
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# PCI Hotplug Support
+#
+# CONFIG_HOTPLUG_PCI is not set
+
+#
+# Advanced setup
+#
+# CONFIG_ADVANCED_OPTIONS is not set
+
+#
+# Default settings for advanced configuration options are used
+#
+CONFIG_HIGHMEM_START=0xfe000000
+CONFIG_LOWMEM_SIZE=0x30000000
+CONFIG_KERNEL_START=0xc0000000
+CONFIG_TASK_SIZE=0x80000000
+CONFIG_BOOT_LOAD=0x00800000
+
+#
+# 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=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+# CONFIG_IP_PNP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+CONFIG_SYN_COOKIES=y
+# 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_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
+
+#
+# IP: Virtual Server Configuration
+#
+# CONFIG_IP_VS 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=y
+# CONFIG_NETFILTER_DEBUG is not set
+
+#
+# Core Netfilter Configuration
+#
+# CONFIG_NETFILTER_NETLINK is not set
+# CONFIG_NETFILTER_XTABLES is not set
+
+#
+# IP: Netfilter Configuration
+#
+CONFIG_IP_NF_CONNTRACK=m
+# CONFIG_IP_NF_CT_ACCT is not set
+# CONFIG_IP_NF_CONNTRACK_MARK is not set
+# CONFIG_IP_NF_CONNTRACK_EVENTS is not set
+# 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 is not set
+# CONFIG_IP_NF_H323 is not set
+# CONFIG_IP_NF_SIP is not set
+# CONFIG_IP_NF_QUEUE 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_NET_DIVERT 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 is not set
+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 is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Plug and Play support
+#
+# CONFIG_PNP is not set
+
+#
+# Block devices
+#
+CONFIG_BLK_DEV_FD=y
+# CONFIG_BLK_DEV_XD is not set
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_SX8 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=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
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+CONFIG_IDE=y
+CONFIG_BLK_DEV_IDE=y
+
+#
+# Please see Documentation/ide.txt for help/info on IDE drives
+#
+# CONFIG_BLK_DEV_IDE_SATA is not set
+CONFIG_BLK_DEV_IDEDISK=y
+CONFIG_IDEDISK_MULTI_MODE=y
+CONFIG_BLK_DEV_IDECD=y
+# CONFIG_BLK_DEV_IDETAPE is not set
+# CONFIG_BLK_DEV_IDEFLOPPY is not set
+# CONFIG_BLK_DEV_IDESCSI is not set
+# CONFIG_IDE_TASK_IOCTL is not set
+
+#
+# IDE chipset support/bugfixes
+#
+CONFIG_IDE_GENERIC=y
+CONFIG_BLK_DEV_IDEPCI=y
+CONFIG_IDEPCI_SHARE_IRQ=y
+# CONFIG_BLK_DEV_OFFBOARD is not set
+CONFIG_BLK_DEV_GENERIC=y
+# CONFIG_BLK_DEV_OPTI621 is not set
+CONFIG_BLK_DEV_SL82C105=y
+CONFIG_BLK_DEV_IDEDMA_PCI=y
+# CONFIG_BLK_DEV_IDEDMA_FORCED is not set
+CONFIG_IDEDMA_PCI_AUTO=y
+# CONFIG_IDEDMA_ONLYDISK is not set
+# CONFIG_BLK_DEV_AEC62XX is not set
+# CONFIG_BLK_DEV_ALI15X3 is not set
+# CONFIG_BLK_DEV_AMD74XX is not set
+# CONFIG_BLK_DEV_CMD64X is not set
+# CONFIG_BLK_DEV_TRIFLEX is not set
+# CONFIG_BLK_DEV_CY82C693 is not set
+# CONFIG_BLK_DEV_CS5520 is not set
+# CONFIG_BLK_DEV_CS5530 is not set
+# CONFIG_BLK_DEV_HPT34X is not set
+# CONFIG_BLK_DEV_HPT366 is not set
+# CONFIG_BLK_DEV_SC1200 is not set
+# CONFIG_BLK_DEV_PIIX is not set
+# CONFIG_BLK_DEV_IT821X is not set
+# CONFIG_BLK_DEV_NS87415 is not set
+# CONFIG_BLK_DEV_PDC202XX_OLD is not set
+# 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_SLC90E66 is not set
+# CONFIG_BLK_DEV_TRM290 is not set
+CONFIG_BLK_DEV_VIA82CXXX=y
+# CONFIG_IDE_ARM is not set
+# CONFIG_IDE_CHIPSETS is not set
+CONFIG_BLK_DEV_IDEDMA=y
+# CONFIG_IDEDMA_IVB is not set
+CONFIG_IDEDMA_AUTO=y
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+CONFIG_SCSI=y
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+CONFIG_CHR_DEV_ST=y
+# CONFIG_CHR_DEV_OSST is not set
+CONFIG_BLK_DEV_SR=y
+CONFIG_BLK_DEV_SR_VENDOR=y
+CONFIG_CHR_DEV_SG=y
+# CONFIG_CHR_DEV_SCH is not set
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+# CONFIG_SCSI_MULTI_LUN is not set
+CONFIG_SCSI_CONSTANTS=y
+# CONFIG_SCSI_LOGGING is not set
+
+#
+# SCSI Transport Attributes
+#
+CONFIG_SCSI_SPI_ATTRS=y
+# CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
+# CONFIG_SCSI_SAS_ATTRS is not set
+
+#
+# SCSI low-level drivers
+#
+# CONFIG_ISCSI_TCP is not set
+# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
+# CONFIG_SCSI_3W_9XXX is not set
+# CONFIG_SCSI_7000FASST is not set
+# CONFIG_SCSI_ACARD is not set
+# CONFIG_SCSI_AHA152X is not set
+# CONFIG_SCSI_AHA1542 is not set
+# CONFIG_SCSI_AACRAID is not set
+# CONFIG_SCSI_AIC7XXX is not set
+# CONFIG_SCSI_AIC7XXX_OLD is not set
+# CONFIG_SCSI_AIC79XX is not set
+# CONFIG_SCSI_DPT_I2O is not set
+# CONFIG_SCSI_IN2000 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_BUSLOGIC is not set
+# CONFIG_SCSI_DMX3191D is not set
+# CONFIG_SCSI_DTC3280 is not set
+# CONFIG_SCSI_EATA is not set
+# CONFIG_SCSI_FUTURE_DOMAIN is not set
+# CONFIG_SCSI_GDTH is not set
+# CONFIG_SCSI_GENERIC_NCR5380 is not set
+# CONFIG_SCSI_GENERIC_NCR5380_MMIO is not set
+# CONFIG_SCSI_IPS is not set
+# CONFIG_SCSI_INITIO is not set
+# CONFIG_SCSI_INIA100 is not set
+# CONFIG_SCSI_NCR53C406A 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_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_LPFC is not set
+# CONFIG_SCSI_SYM53C416 is not set
+# CONFIG_SCSI_DC395x is not set
+# CONFIG_SCSI_DC390T is not set
+# CONFIG_SCSI_T128 is not set
+# CONFIG_SCSI_U14_34F is not set
+# CONFIG_SCSI_NSP32 is not set
+# CONFIG_SCSI_DEBUG is not set
+
+#
+# Old CD-ROM drivers (not SCSI, not IDE)
+#
+# CONFIG_CD_NO_IDESCSI is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+
+#
+# Fusion MPT device support
+#
+# CONFIG_FUSION is not set
+# CONFIG_FUSION_SPI is not set
+# CONFIG_FUSION_FC is not set
+# CONFIG_FUSION_SAS is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+# CONFIG_IEEE1394 is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+
+#
+# Macintosh device drivers
+#
+# CONFIG_WINDFARM is not set
+
+#
+# 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
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+
+#
+# PHY device support
+#
+# CONFIG_PHYLIB is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+# CONFIG_HAPPYMEAL is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_CASSINI is not set
+# CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_LANCE is not set
+# CONFIG_NET_VENDOR_SMC is not set
+# CONFIG_NET_VENDOR_RACAL is not set
+
+#
+# Tulip family network device support
+#
+CONFIG_NET_TULIP=y
+# CONFIG_DE2104X is not set
+# CONFIG_TULIP is not set
+CONFIG_DE4X5=y
+# CONFIG_WINBOND_840 is not set
+# CONFIG_DM9102 is not set
+# CONFIG_ULI526X is not set
+# CONFIG_AT1700 is not set
+# CONFIG_DEPCA is not set
+# CONFIG_HP100 is not set
+# CONFIG_NET_ISA is not set
+CONFIG_NET_PCI=y
+CONFIG_PCNET32=y
+# CONFIG_AMD8111_ETH is not set
+# CONFIG_ADAPTEC_STARFIRE is not set
+# CONFIG_AC3200 is not set
+# CONFIG_APRICOT is not set
+# CONFIG_B44 is not set
+# CONFIG_FORCEDETH is not set
+# CONFIG_CS89x0 is not set
+# CONFIG_DGRS is not set
+# CONFIG_EEPRO100 is not set
+# CONFIG_E100 is not set
+# CONFIG_FEALNX is not set
+# CONFIG_NATSEMI is not set
+# CONFIG_NE2K_PCI is not set
+CONFIG_8139CP=y
+CONFIG_8139TOO=y
+# CONFIG_8139TOO_PIO is not set
+# CONFIG_8139TOO_TUNE_TWISTER is not set
+# CONFIG_8139TOO_8129 is not set
+# CONFIG_8139_OLD_RX_RESET is not set
+# CONFIG_SIS900 is not set
+# CONFIG_EPIC100 is not set
+# CONFIG_SUNDANCE is not set
+# CONFIG_TLAN is not set
+CONFIG_VIA_RHINE=y
+# CONFIG_VIA_RHINE_MMIO is not set
+# CONFIG_VIA_RHINE_NAPI is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_E1000 is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_R8169 is not set
+# CONFIG_SIS190 is not set
+# CONFIG_SKGE is not set
+# CONFIG_SKY2 is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_VIA_VELOCITY is not set
+# CONFIG_TIGON3 is not set
+# CONFIG_BNX2 is not set
+CONFIG_MV643XX_ETH=y
+# CONFIG_MV643XX_ETH_0 is not set
+# CONFIG_MV643XX_ETH_1 is not set
+# CONFIG_MV643XX_ETH_2 is not set
+
+#
+# Ethernet (10000 Mbit)
+#
+# CONFIG_CHELSIO_T1 is not set
+# CONFIG_IXGB is not set
+# CONFIG_S2IO is not set
+# CONFIG_MYRI10GE is not set
+
+#
+# Token Ring devices
+#
+# CONFIG_TR is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+CONFIG_PPP=m
+CONFIG_PPP_MULTILINK=y
+CONFIG_PPP_FILTER=y
+CONFIG_PPP_ASYNC=m
+CONFIG_PPP_SYNC_TTY=m
+CONFIG_PPP_DEFLATE=m
+CONFIG_PPP_BSDCOMP=m
+CONFIG_PPP_MPPE=m
+CONFIG_PPPOE=m
+# CONFIG_SLIP is not set
+# CONFIG_NET_FC 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
+
+#
+# Telephony Support
+#
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
+CONFIG_INPUT_MOUSEDEV_PSAUX=y
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_TSDEV is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+CONFIG_KEYBOARD_ATKBD=y
+# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_KEYBOARD_LKKBD is not set
+# CONFIG_KEYBOARD_XTKBD is not set
+# CONFIG_KEYBOARD_NEWTON is not set
+CONFIG_INPUT_MOUSE=y
+CONFIG_MOUSE_PS2=y
+# CONFIG_MOUSE_SERIAL is not set
+# CONFIG_MOUSE_INPORT is not set
+# CONFIG_MOUSE_LOGIBM is not set
+# CONFIG_MOUSE_PC110PAD is not set
+# CONFIG_MOUSE_VSXXXAA is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+CONFIG_INPUT_MISC=y
+# CONFIG_INPUT_PCSPKR is not set
+CONFIG_INPUT_UINPUT=y
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+CONFIG_SERIO_I8042=y
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_PCIPS2 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_PCI=y
+CONFIG_SERIAL_8250_NR_UARTS=4
+CONFIG_SERIAL_8250_RUNTIME_UARTS=4
+# CONFIG_SERIAL_8250_EXTENDED is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_JSM is not set
+CONFIG_UNIX98_PTYS=y
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+# CONFIG_HVC_RTAS 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=y
+CONFIG_GEN_RTC=y
+# CONFIG_GEN_RTC_X is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_AGP is not set
+# CONFIG_DRM is not set
+# CONFIG_RAW_DRIVER is not set
+
+#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+# CONFIG_TELCLOCK is not set
+
+#
+# I2C support
+#
+CONFIG_I2C=y
+# CONFIG_I2C_CHARDEV is not set
+
+#
+# I2C Algorithms
+#
+CONFIG_I2C_ALGOBIT=y
+# CONFIG_I2C_ALGOPCF is not set
+# CONFIG_I2C_ALGOPCA is not set
+
+#
+# I2C Hardware Bus support
+#
+# CONFIG_I2C_ALI1535 is not set
+# CONFIG_I2C_ALI1563 is not set
+# CONFIG_I2C_ALI15X3 is not set
+# CONFIG_I2C_AMD756 is not set
+# CONFIG_I2C_AMD8111 is not set
+# CONFIG_I2C_HYDRA is not set
+# CONFIG_I2C_I801 is not set
+# CONFIG_I2C_I810 is not set
+# CONFIG_I2C_PIIX4 is not set
+# CONFIG_I2C_MPC is not set
+# CONFIG_I2C_NFORCE2 is not set
+# CONFIG_I2C_OCORES is not set
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_PROSAVAGE is not set
+# CONFIG_I2C_SAVAGE4 is not set
+# CONFIG_I2C_SIS5595 is not set
+# CONFIG_I2C_SIS630 is not set
+# CONFIG_I2C_SIS96X is not set
+# CONFIG_I2C_STUB is not set
+# CONFIG_I2C_VIA is not set
+# CONFIG_I2C_VIAPRO is not set
+# CONFIG_I2C_VOODOO3 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_M41T00 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 is not set
+# CONFIG_SPI_MASTER is not set
+
+#
+# Dallas's 1-wire bus
+#
+
+#
+# Hardware Monitoring support
+#
+# CONFIG_HWMON is not set
+# CONFIG_HWMON_VID is not set
+
+#
+# Misc devices
+#
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+CONFIG_VIDEO_V4L2=y
+
+#
+# Digital Video Broadcasting Devices
+#
+# CONFIG_DVB is not set
+# CONFIG_USB_DABUSB is not set
+
+#
+# Graphics support
+#
+CONFIG_FIRMWARE_EDID=y
+CONFIG_FB=y
+CONFIG_FB_CFB_FILLRECT=y
+CONFIG_FB_CFB_COPYAREA=y
+CONFIG_FB_CFB_IMAGEBLIT=y
+CONFIG_FB_MACMODES=y
+# CONFIG_FB_BACKLIGHT is not set
+CONFIG_FB_MODE_HELPERS=y
+CONFIG_FB_TILEBLITTING=y
+# CONFIG_FB_CIRRUS is not set
+# CONFIG_FB_PM2 is not set
+# CONFIG_FB_CYBER2000 is not set
+CONFIG_FB_OF=y
+# CONFIG_FB_CT65550 is not set
+# CONFIG_FB_ASILIANT is not set
+# CONFIG_FB_IMSTT is not set
+# CONFIG_FB_VGA16 is not set
+# CONFIG_FB_S1D13XXX is not set
+# CONFIG_FB_NVIDIA is not set
+# CONFIG_FB_RIVA is not set
+CONFIG_FB_MATROX=y
+CONFIG_FB_MATROX_MILLENIUM=y
+CONFIG_FB_MATROX_MYSTIQUE=y
+CONFIG_FB_MATROX_G=y
+# CONFIG_FB_MATROX_I2C is not set
+# CONFIG_FB_MATROX_MULTIHEAD is not set
+CONFIG_FB_RADEON=y
+CONFIG_FB_RADEON_I2C=y
+# CONFIG_FB_RADEON_DEBUG is not set
+# CONFIG_FB_ATY128 is not set
+CONFIG_FB_ATY=y
+CONFIG_FB_ATY_CT=y
+# CONFIG_FB_ATY_GENERIC_LCD is not set
+CONFIG_FB_ATY_GX=y
+# CONFIG_FB_SAVAGE is not set
+# CONFIG_FB_SIS is not set
+# CONFIG_FB_NEOMAGIC is not set
+# CONFIG_FB_KYRO is not set
+CONFIG_FB_3DFX=y
+# CONFIG_FB_3DFX_ACCEL is not set
+# CONFIG_FB_VOODOO1 is not set
+# CONFIG_FB_TRIDENT is not set
+# CONFIG_FB_VIRTUAL is not set
+
+#
+# Console display driver support
+#
+CONFIG_VGA_CONSOLE=y
+# CONFIG_VGACON_SOFT_SCROLLBACK is not set
+# CONFIG_MDA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
+# CONFIG_FONTS is not set
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
+
+#
+# Logo configuration
+#
+CONFIG_LOGO=y
+CONFIG_LOGO_LINUX_MONO=y
+CONFIG_LOGO_LINUX_VGA16=y
+CONFIG_LOGO_LINUX_CLUT224=y
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
+#
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB_ARCH_HAS_EHCI=y
+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_OTG is not set
+
+#
+# USB Host Controller Drivers
+#
+CONFIG_USB_EHCI_HCD=m
+# 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_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_UHCI_HCD=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=m
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_ISD200 is not set
+# CONFIG_USB_STORAGE_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_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
+# 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 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_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_PHIDGETKIT is not set
+# CONFIG_USB_PHIDGETSERVO is not set
+# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_APPLEDISPLAY is not set
+# CONFIG_USB_SISUSBVGA is not set
+# CONFIG_USB_LD is not set
+# CONFIG_USB_TEST is not set
+
+#
+# USB DSL modem support
+#
+
+#
+# USB Gadget Support
+#
+# CONFIG_USB_GADGET is not set
+
+#
+# MMC/SD Card support
+#
+# CONFIG_MMC is not set
+
+#
+# LED devices
+#
+# CONFIG_NEW_LEDS is not set
+
+#
+# LED drivers
+#
+
+#
+# LED Triggers
+#
+
+#
+# InfiniBand support
+#
+# CONFIG_INFINIBAND is not set
+
+#
+# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
+#
+
+#
+# Real Time Clock
+#
+# CONFIG_RTC_CLASS is not set
+
+#
+# DMA Engine support
+#
+# CONFIG_DMA_ENGINE is not set
+
+#
+# DMA Clients
+#
+
+#
+# DMA Devices
+#
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
+CONFIG_EXT3_FS=y
+CONFIG_EXT3_FS_XATTR=y
+# CONFIG_EXT3_FS_POSIX_ACL is not set
+# CONFIG_EXT3_FS_SECURITY 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_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
+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=y
+# CONFIG_JOLIET is not set
+# CONFIG_ZISOFS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=m
+CONFIG_MSDOS_FS=m
+CONFIG_VFAT_FS=m
+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_KCORE=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# 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
+
+#
+# Network File Systems
+#
+# CONFIG_NFS_FS is not set
+# CONFIG_NFSD 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=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+CONFIG_MAC_PARTITION=y
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_BSD_DISKLABEL is not set
+# CONFIG_MINIX_SUBPARTITION is not set
+# CONFIG_SOLARIS_X86_PARTITION is not set
+# CONFIG_UNIXWARE_DISKLABEL is not set
+# CONFIG_LDM_PARTITION is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_KARMA_PARTITION is not set
+# CONFIG_EFI_PARTITION is not set
+
+#
+# Native Language Support
+#
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="iso8859-1"
+# CONFIG_NLS_CODEPAGE_437 is not set
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+CONFIG_NLS_ASCII=y
+CONFIG_NLS_ISO8859_1=m
+# 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
+
+#
+# Library routines
+#
+CONFIG_CRC_CCITT=m
+# CONFIG_CRC16 is not set
+CONFIG_CRC32=y
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=m
+CONFIG_ZLIB_DEFLATE=m
+CONFIG_TEXTSEARCH=y
+CONFIG_TEXTSEARCH_KMP=m
+CONFIG_PLIST=y
+
+#
+# Instrumentation Support
+#
+# CONFIG_PROFILING is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_UNUSED_SYMBOLS is not set
+CONFIG_DEBUG_KERNEL=y
+CONFIG_LOG_BUF_SHIFT=15
+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=y
+# CONFIG_DEBUG_RWSEMS is not set
+CONFIG_DEBUG_SPINLOCK_SLEEP=y
+# 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_FORCED_INLINING=y
+# CONFIG_RCU_TORTURE_TEST is not set
+CONFIG_DEBUGGER=y
+CONFIG_XMON=y
+CONFIG_XMON_DEFAULT=y
+# CONFIG_BDI_SWITCH is not set
+# CONFIG_BOOTX_TEXT is not set
+# CONFIG_PPC_EARLY_DEBUG is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+
+#
+# Cryptographic options
+#
+CONFIG_CRYPTO=y
+# CONFIG_CRYPTO_HMAC is not set
+# CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_MD4 is not set
+# CONFIG_CRYPTO_MD5 is not set
+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_DES is not set
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_AES is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+# CONFIG_CRYPTO_TEA is not set
+CONFIG_CRYPTO_ARC4=m
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Hardware crypto devices
+#
diff --git a/arch/powerpc/configs/mpc7448_hpc2_defconfig b/arch/powerpc/configs/mpc7448_hpc2_defconfig
new file mode 100644
index 000000000..719fba4eb
--- /dev/null
+++ b/arch/powerpc/configs/mpc7448_hpc2_defconfig
@@ -0,0 +1,963 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.18-rc6
+# Sun Sep 10 10:26:55 2006
+#
+# CONFIG_PPC64 is not set
+CONFIG_PPC32=y
+CONFIG_PPC_MERGE=y
+CONFIG_MMU=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_IRQ_PER_CPU=y
+CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_PPC=y
+CONFIG_EARLY_PRINTK=y
+CONFIG_GENERIC_NVRAM=y
+CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
+CONFIG_ARCH_MAY_HAVE_PC_FDC=y
+CONFIG_PPC_OF=y
+CONFIG_PPC_UDBG_16550=y
+# CONFIG_GENERIC_TBSYNC is not set
+CONFIG_DEFAULT_UIMAGE=y
+
+#
+# Processor support
+#
+CONFIG_CLASSIC32=y
+# CONFIG_PPC_52xx is not set
+# CONFIG_PPC_82xx is not set
+# CONFIG_PPC_83xx is not set
+# CONFIG_PPC_85xx is not set
+# CONFIG_PPC_86xx 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_PPC_FPU=y
+# CONFIG_ALTIVEC is not set
+CONFIG_PPC_STD_MMU=y
+CONFIG_PPC_STD_MMU_32=y
+# CONFIG_SMP is not set
+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_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_TASKSTATS is not set
+CONFIG_SYSCTL=y
+# CONFIG_AUDIT is not set
+# CONFIG_IKCONFIG is not set
+# CONFIG_RELAY is not set
+CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_EMBEDDED=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_RT_MUTEXES=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SHMEM=y
+CONFIG_SLAB=y
+CONFIG_VM_EVENT_COUNTERS=y
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+# CONFIG_SLOB is not set
+
+#
+# Loadable module support
+#
+# CONFIG_MODULES is not set
+
+#
+# Block layer
+#
+CONFIG_LBD=y
+# 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=y
+CONFIG_IOSCHED_CFQ=y
+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"
+
+#
+# Platform support
+#
+# CONFIG_PPC_MULTIPLATFORM is not set
+# CONFIG_PPC_ISERIES is not set
+CONFIG_EMBEDDED6xx=y
+# CONFIG_APUS is not set
+# CONFIG_PPC_CELL is not set
+# CONFIG_PPC_CELL_NATIVE is not set
+# CONFIG_UDBG_RTAS_CONSOLE is not set
+# CONFIG_PPC_RTAS is not set
+# CONFIG_MMIO_NVRAM is not set
+# CONFIG_PPC_MPC106 is not set
+# CONFIG_PPC_970_NAP is not set
+# CONFIG_CPU_FREQ is not set
+# CONFIG_TAU is not set
+# CONFIG_PPC_TODC is not set
+# CONFIG_KATANA is not set
+# CONFIG_WILLOW is not set
+# CONFIG_CPCI690 is not set
+# CONFIG_POWERPMC250 is not set
+# CONFIG_CHESTNUT is not set
+# CONFIG_SPRUCE is not set
+# CONFIG_HDPU is not set
+# CONFIG_EV64260 is not set
+# CONFIG_LOPEC is not set
+# CONFIG_MVME5100 is not set
+# CONFIG_PPLUS is not set
+# CONFIG_PRPMC750 is not set
+# CONFIG_PRPMC800 is not set
+# CONFIG_SANDPOINT is not set
+CONFIG_MPC7448HPC2=y
+# CONFIG_RADSTONE_PPC7D is not set
+# CONFIG_PAL4 is not set
+# CONFIG_GEMINI is not set
+# CONFIG_EST8260 is not set
+# CONFIG_SBC82xx is not set
+# CONFIG_SBS8260 is not set
+# CONFIG_RPX8260 is not set
+# CONFIG_TQM8260 is not set
+# CONFIG_ADS8272 is not set
+# CONFIG_PQ2FADS is not set
+# CONFIG_LITE5200 is not set
+# CONFIG_EV64360 is not set
+CONFIG_TSI108_BRIDGE=y
+# CONFIG_WANT_EARLY_SERIAL is not set
+CONFIG_MPIC=y
+
+#
+# Kernel options
+#
+# CONFIG_HIGHMEM is not set
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
+CONFIG_BINFMT_ELF=y
+CONFIG_BINFMT_MISC=y
+CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
+CONFIG_ARCH_FLATMEM_ENABLE=y
+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=4
+# CONFIG_RESOURCES_64BIT is not set
+CONFIG_PROC_DEVICETREE=y
+# CONFIG_CMDLINE_BOOL is not set
+# CONFIG_PM is not set
+# CONFIG_SECCOMP is not set
+CONFIG_ISA_DMA_API=y
+
+#
+# Bus options
+#
+CONFIG_GENERIC_ISA_DMA=y
+CONFIG_MPIC_WEIRD=y
+# CONFIG_PPC_I8259 is not set
+# CONFIG_PPC_INDIRECT_PCI is not set
+CONFIG_PCI=y
+CONFIG_PCI_DOMAINS=y
+# CONFIG_PCIEPORTBUS is not set
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# PCI Hotplug Support
+#
+# CONFIG_HOTPLUG_PCI is not set
+
+#
+# Advanced setup
+#
+# CONFIG_ADVANCED_OPTIONS is not set
+
+#
+# Default settings for advanced configuration options are used
+#
+CONFIG_HIGHMEM_START=0xfe000000
+CONFIG_LOWMEM_SIZE=0x30000000
+CONFIG_KERNEL_START=0xc0000000
+CONFIG_TASK_SIZE=0x80000000
+CONFIG_BOOT_LOAD=0x00800000
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+# CONFIG_NETDEBUG is not set
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=y
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+CONFIG_SYN_COOKIES=y
+# 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=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
+# 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_NET_DIVERT 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_SYS_HYPERVISOR is not set
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+# CONFIG_CONNECTOR is not set
+
+#
+# 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_FD is not set
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_SX8 is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=131072
+CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
+CONFIG_BLK_DEV_INITRD=y
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+CONFIG_SCSI=y
+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 is not set
+# CONFIG_SCSI_CONSTANTS is not set
+# CONFIG_SCSI_LOGGING is not set
+
+#
+# SCSI Transport Attributes
+#
+# 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
+
+#
+# SCSI low-level drivers
+#
+# CONFIG_ISCSI_TCP is not set
+# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
+# CONFIG_SCSI_3W_9XXX is not set
+# CONFIG_SCSI_ACARD is not set
+# CONFIG_SCSI_AACRAID is not set
+# CONFIG_SCSI_AIC7XXX is not set
+# CONFIG_SCSI_AIC7XXX_OLD is not set
+# CONFIG_SCSI_AIC79XX is not set
+# CONFIG_SCSI_DPT_I2O is not set
+# CONFIG_MEGARAID_NEWGEN is not set
+# CONFIG_MEGARAID_LEGACY is not set
+# CONFIG_MEGARAID_SAS is not set
+CONFIG_SCSI_SATA=y
+# CONFIG_SCSI_SATA_AHCI is not set
+# CONFIG_SCSI_SATA_SVW is not set
+# CONFIG_SCSI_ATA_PIIX is not set
+CONFIG_SCSI_SATA_MV=y
+# CONFIG_SCSI_SATA_NV is not set
+# CONFIG_SCSI_PDC_ADMA is not set
+# CONFIG_SCSI_HPTIOP is not set
+# CONFIG_SCSI_SATA_QSTOR is not set
+# CONFIG_SCSI_SATA_PROMISE is not set
+# CONFIG_SCSI_SATA_SX4 is not set
+# CONFIG_SCSI_SATA_SIL is not set
+# CONFIG_SCSI_SATA_SIL24 is not set
+# CONFIG_SCSI_SATA_SIS is not set
+# CONFIG_SCSI_SATA_ULI is not set
+# CONFIG_SCSI_SATA_VIA is not set
+# CONFIG_SCSI_SATA_VITESSE is not set
+# CONFIG_SCSI_BUSLOGIC is not set
+# CONFIG_SCSI_DMX3191D is not set
+# CONFIG_SCSI_EATA is not set
+# CONFIG_SCSI_FUTURE_DOMAIN is not set
+# CONFIG_SCSI_GDTH is not set
+# CONFIG_SCSI_IPS is not set
+# CONFIG_SCSI_INITIO is not set
+# CONFIG_SCSI_INIA100 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_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
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+
+#
+# Fusion MPT device support
+#
+# CONFIG_FUSION is not set
+# CONFIG_FUSION_SPI is not set
+# CONFIG_FUSION_FC is not set
+# CONFIG_FUSION_SAS is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+# CONFIG_IEEE1394 is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+
+#
+# Macintosh device drivers
+#
+# CONFIG_WINDFARM is not set
+
+#
+# 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
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+
+#
+# PHY device support
+#
+CONFIG_PHYLIB=y
+
+#
+# MII PHY device drivers
+#
+# CONFIG_MARVELL_PHY is not set
+# CONFIG_DAVICOM_PHY is not set
+# CONFIG_QSEMI_PHY is not set
+# CONFIG_LXT_PHY is not set
+# CONFIG_CICADA_PHY is not set
+# CONFIG_VITESSE_PHY is not set
+# CONFIG_SMSC_PHY is not set
+# CONFIG_FIXED_PHY is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+# CONFIG_HAPPYMEAL is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_CASSINI is not set
+# CONFIG_NET_VENDOR_3COM is not set
+
+#
+# Tulip family network device support
+#
+# CONFIG_NET_TULIP is not set
+# CONFIG_HP100 is not set
+CONFIG_NET_PCI=y
+# CONFIG_PCNET32 is not set
+# CONFIG_AMD8111_ETH is not set
+# CONFIG_ADAPTEC_STARFIRE is not set
+# CONFIG_B44 is not set
+# CONFIG_FORCEDETH is not set
+# CONFIG_DGRS is not set
+# CONFIG_EEPRO100 is not set
+CONFIG_E100=y
+# CONFIG_FEALNX is not set
+# CONFIG_NATSEMI is not set
+# CONFIG_NE2K_PCI is not set
+# CONFIG_8139CP is not set
+CONFIG_8139TOO=y
+# CONFIG_8139TOO_PIO is not set
+# CONFIG_8139TOO_TUNE_TWISTER is not set
+# CONFIG_8139TOO_8129 is not set
+# CONFIG_8139_OLD_RX_RESET is not set
+# CONFIG_SIS900 is not set
+# CONFIG_EPIC100 is not set
+# CONFIG_SUNDANCE is not set
+# CONFIG_TLAN is not set
+# CONFIG_VIA_RHINE is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_E1000 is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_R8169 is not set
+# CONFIG_SIS190 is not set
+# CONFIG_SKGE is not set
+# CONFIG_SKY2 is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_VIA_VELOCITY is not set
+# CONFIG_TIGON3 is not set
+# CONFIG_BNX2 is not set
+
+#
+# Ethernet (10000 Mbit)
+#
+# CONFIG_CHELSIO_T1 is not set
+# CONFIG_IXGB is not set
+# CONFIG_S2IO is not set
+# CONFIG_MYRI10GE is not set
+
+#
+# Token Ring devices
+#
+# CONFIG_TR is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_NET_FC is not set
+# CONFIG_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
+
+#
+# Telephony Support
+#
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+
+#
+# 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 is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+# CONFIG_VT is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_PCI=y
+CONFIG_SERIAL_8250_NR_UARTS=4
+CONFIG_SERIAL_8250_RUNTIME_UARTS=4
+# CONFIG_SERIAL_8250_EXTENDED is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_JSM is not set
+CONFIG_UNIX98_PTYS=y
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+
+#
+# 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_GEN_RTC=y
+# CONFIG_GEN_RTC_X is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_AGP is not set
+# CONFIG_DRM is not set
+# CONFIG_RAW_DRIVER is not set
+
+#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+# CONFIG_TELCLOCK 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
+#
+
+#
+# Hardware Monitoring support
+#
+CONFIG_HWMON=y
+# CONFIG_HWMON_VID is not set
+# CONFIG_SENSORS_ABITUGURU is not set
+# CONFIG_SENSORS_F71805F 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
+#
+# CONFIG_DVB is not set
+
+#
+# Graphics support
+#
+CONFIG_FIRMWARE_EDID=y
+# CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
+#
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB_ARCH_HAS_EHCI=y
+# 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
+
+#
+# LED devices
+#
+# CONFIG_NEW_LEDS is not set
+
+#
+# LED drivers
+#
+
+#
+# LED Triggers
+#
+
+#
+# InfiniBand support
+#
+# CONFIG_INFINIBAND is not set
+
+#
+# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
+#
+
+#
+# Real Time Clock
+#
+# CONFIG_RTC_CLASS is not set
+
+#
+# DMA Engine support
+#
+# CONFIG_DMA_ENGINE is not set
+
+#
+# DMA Clients
+#
+
+#
+# DMA Devices
+#
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
+CONFIG_EXT3_FS=y
+CONFIG_EXT3_FS_XATTR=y
+# CONFIG_EXT3_FS_POSIX_ACL is not set
+# CONFIG_EXT3_FS_SECURITY 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_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
+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_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_KCORE=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# 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
+
+#
+# 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=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_BSD_DISKLABEL is not set
+# CONFIG_MINIX_SUBPARTITION is not set
+# CONFIG_SOLARIS_X86_PARTITION is not set
+# CONFIG_UNIXWARE_DISKLABEL is not set
+# CONFIG_LDM_PARTITION is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_KARMA_PARTITION is not set
+# CONFIG_EFI_PARTITION is not set
+
+#
+# Native Language Support
+#
+# CONFIG_NLS is not set
+
+#
+# Library routines
+#
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
+CONFIG_CRC32=y
+# CONFIG_LIBCRC32C is not set
+CONFIG_PLIST=y
+
+#
+# Instrumentation Support
+#
+# CONFIG_PROFILING is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+# 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_UNWIND_INFO is not set
+# CONFIG_BOOTX_TEXT is not set
+# CONFIG_PPC_EARLY_DEBUG is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+
+#
+# Cryptographic options
+#
+# CONFIG_CRYPTO is not set
+
+#
+# Hardware crypto devices
+#
diff --git a/arch/powerpc/configs/mpc834x_itx_defconfig b/arch/powerpc/configs/mpc834x_itx_defconfig
new file mode 100644
index 000000000..8da6a47f0
--- /dev/null
+++ b/arch/powerpc/configs/mpc834x_itx_defconfig
@@ -0,0 +1,1344 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.18-rc6
+# Sun Sep 10 10:28:05 2006
+#
+# CONFIG_PPC64 is not set
+CONFIG_PPC32=y
+CONFIG_PPC_MERGE=y
+CONFIG_MMU=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_IRQ_PER_CPU=y
+CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_PPC=y
+CONFIG_EARLY_PRINTK=y
+CONFIG_GENERIC_NVRAM=y
+CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
+CONFIG_ARCH_MAY_HAVE_PC_FDC=y
+CONFIG_PPC_OF=y
+CONFIG_PPC_UDBG_16550=y
+# CONFIG_GENERIC_TBSYNC is not set
+CONFIG_DEFAULT_UIMAGE=y
+
+#
+# Processor support
+#
+# CONFIG_CLASSIC32 is not set
+# CONFIG_PPC_52xx is not set
+# CONFIG_PPC_82xx is not set
+CONFIG_PPC_83xx=y
+# CONFIG_PPC_85xx is not set
+# CONFIG_PPC_86xx 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
+CONFIG_PPC_FPU=y
+CONFIG_PPC_STD_MMU=y
+CONFIG_PPC_STD_MMU_32=y
+# CONFIG_SMP is not set
+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_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_TASKSTATS is not set
+CONFIG_SYSCTL=y
+# CONFIG_AUDIT is not set
+# CONFIG_IKCONFIG is not set
+# CONFIG_RELAY is not set
+CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_EMBEDDED=y
+# CONFIG_KALLSYMS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+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_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 is not set
+
+#
+# Block layer
+#
+# 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=y
+CONFIG_IOSCHED_CFQ=y
+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"
+CONFIG_PPC_GEN550=y
+# CONFIG_WANT_EARLY_SERIAL is not set
+
+#
+# Platform support
+#
+# CONFIG_MPC834x_SYS is not set
+CONFIG_MPC834x_ITX=y
+CONFIG_MPC834x=y
+# CONFIG_MPIC is not set
+
+#
+# Kernel options
+#
+# CONFIG_HIGHMEM is not set
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
+CONFIG_ARCH_FLATMEM_ENABLE=y
+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=4
+# CONFIG_RESOURCES_64BIT is not set
+CONFIG_PROC_DEVICETREE=y
+# CONFIG_CMDLINE_BOOL is not set
+# CONFIG_PM is not set
+CONFIG_SECCOMP=y
+CONFIG_ISA_DMA_API=y
+
+#
+# Bus options
+#
+CONFIG_GENERIC_ISA_DMA=y
+# CONFIG_MPIC_WEIRD is not set
+# CONFIG_PPC_I8259 is not set
+CONFIG_PPC_INDIRECT_PCI=y
+CONFIG_FSL_SOC=y
+CONFIG_PCI=y
+CONFIG_PCI_DOMAINS=y
+# CONFIG_PCIEPORTBUS is not set
+# CONFIG_PCI_DEBUG is not set
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# PCI Hotplug Support
+#
+# CONFIG_HOTPLUG_PCI is not set
+
+#
+# Advanced setup
+#
+# CONFIG_ADVANCED_OPTIONS is not set
+
+#
+# Default settings for advanced configuration options are used
+#
+CONFIG_HIGHMEM_START=0xfe000000
+CONFIG_LOWMEM_SIZE=0x30000000
+CONFIG_KERNEL_START=0xc0000000
+CONFIG_TASK_SIZE=0x80000000
+CONFIG_BOOT_LOAD=0x00800000
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+# CONFIG_NETDEBUG is not set
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+CONFIG_SYN_COOKIES=y
+# 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=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
+# 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_NET_DIVERT 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 is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+# CONFIG_MTD_BLOCK is not set
+# CONFIG_MTD_BLOCK_RO is not set
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=y
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_GEN_PROBE=y
+# CONFIG_MTD_CFI_ADV_OPTIONS 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_CFI_INTELEXT is not set
+CONFIG_MTD_CFI_AMDSTD=y
+# CONFIG_MTD_CFI_STAA is not set
+CONFIG_MTD_CFI_UTIL=y
+# 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_PHYSMAP=y
+CONFIG_MTD_PHYSMAP_START=0xfe000000
+CONFIG_MTD_PHYSMAP_LEN=0x1000000
+CONFIG_MTD_PHYSMAP_BANKWIDTH=2
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_PMC551 is not set
+# CONFIG_MTD_DATAFLASH is not set
+# 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 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_FD is not set
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_SX8 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=32768
+CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
+CONFIG_BLK_DEV_INITRD=y
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+CONFIG_IDE=y
+# CONFIG_BLK_DEV_IDE is not set
+# CONFIG_BLK_DEV_HD_ONLY is not set
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+CONFIG_SCSI=y
+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=y
+# CONFIG_CHR_DEV_SCH is not set
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+# CONFIG_SCSI_MULTI_LUN is not set
+# CONFIG_SCSI_CONSTANTS is not set
+# CONFIG_SCSI_LOGGING is not set
+
+#
+# SCSI Transport Attributes
+#
+CONFIG_SCSI_SPI_ATTRS=y
+# CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
+# CONFIG_SCSI_SAS_ATTRS is not set
+
+#
+# SCSI low-level drivers
+#
+# CONFIG_ISCSI_TCP is not set
+# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
+# CONFIG_SCSI_3W_9XXX is not set
+# CONFIG_SCSI_ACARD is not set
+# CONFIG_SCSI_AACRAID is not set
+# CONFIG_SCSI_AIC7XXX is not set
+# CONFIG_SCSI_AIC7XXX_OLD is not set
+# CONFIG_SCSI_AIC79XX is not set
+# CONFIG_SCSI_DPT_I2O is not set
+# CONFIG_MEGARAID_NEWGEN is not set
+# CONFIG_MEGARAID_LEGACY is not set
+# CONFIG_MEGARAID_SAS is not set
+CONFIG_SCSI_SATA=y
+# CONFIG_SCSI_SATA_AHCI is not set
+# CONFIG_SCSI_SATA_SVW is not set
+# CONFIG_SCSI_ATA_PIIX is not set
+# CONFIG_SCSI_SATA_MV is not set
+# CONFIG_SCSI_SATA_NV is not set
+# CONFIG_SCSI_PDC_ADMA is not set
+# CONFIG_SCSI_HPTIOP is not set
+# CONFIG_SCSI_SATA_QSTOR is not set
+# CONFIG_SCSI_SATA_PROMISE is not set
+# CONFIG_SCSI_SATA_SX4 is not set
+CONFIG_SCSI_SATA_SIL=y
+# CONFIG_SCSI_SATA_SIL24 is not set
+# CONFIG_SCSI_SATA_SIS is not set
+# CONFIG_SCSI_SATA_ULI is not set
+# CONFIG_SCSI_SATA_VIA is not set
+# CONFIG_SCSI_SATA_VITESSE is not set
+# CONFIG_SCSI_BUSLOGIC is not set
+# CONFIG_SCSI_DMX3191D is not set
+# CONFIG_SCSI_EATA is not set
+# CONFIG_SCSI_FUTURE_DOMAIN is not set
+# CONFIG_SCSI_GDTH is not set
+# CONFIG_SCSI_IPS is not set
+# CONFIG_SCSI_INITIO is not set
+# CONFIG_SCSI_INIA100 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_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
+
+#
+# Multi-device support (RAID and LVM)
+#
+CONFIG_MD=y
+CONFIG_BLK_DEV_MD=y
+CONFIG_MD_LINEAR=y
+CONFIG_MD_RAID0=y
+CONFIG_MD_RAID1=y
+# CONFIG_MD_RAID10 is not set
+# CONFIG_MD_RAID456 is not set
+# CONFIG_MD_MULTIPATH is not set
+# CONFIG_MD_FAULTY is not set
+# CONFIG_BLK_DEV_DM is not set
+
+#
+# Fusion MPT device support
+#
+# CONFIG_FUSION is not set
+# CONFIG_FUSION_SPI is not set
+# CONFIG_FUSION_FC is not set
+# CONFIG_FUSION_SAS is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+# CONFIG_IEEE1394 is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+
+#
+# Macintosh device drivers
+#
+# CONFIG_WINDFARM is not set
+
+#
+# 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
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+
+#
+# PHY device support
+#
+CONFIG_PHYLIB=y
+
+#
+# MII PHY device drivers
+#
+# CONFIG_MARVELL_PHY is not set
+# CONFIG_DAVICOM_PHY is not set
+# CONFIG_QSEMI_PHY is not set
+# CONFIG_LXT_PHY is not set
+CONFIG_CICADA_PHY=y
+# CONFIG_VITESSE_PHY is not set
+# CONFIG_SMSC_PHY is not set
+# CONFIG_FIXED_PHY is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+# CONFIG_HAPPYMEAL is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_CASSINI is not set
+# CONFIG_NET_VENDOR_3COM is not set
+
+#
+# Tulip family network device support
+#
+# CONFIG_NET_TULIP is not set
+# CONFIG_HP100 is not set
+CONFIG_NET_PCI=y
+# CONFIG_PCNET32 is not set
+# CONFIG_AMD8111_ETH is not set
+# CONFIG_ADAPTEC_STARFIRE is not set
+# CONFIG_B44 is not set
+# CONFIG_FORCEDETH is not set
+# CONFIG_DGRS is not set
+# CONFIG_EEPRO100 is not set
+CONFIG_E100=y
+# CONFIG_FEALNX is not set
+# CONFIG_NATSEMI is not set
+# CONFIG_NE2K_PCI is not set
+# CONFIG_8139CP is not set
+# CONFIG_8139TOO is not set
+# CONFIG_SIS900 is not set
+# CONFIG_EPIC100 is not set
+# CONFIG_SUNDANCE is not set
+# CONFIG_TLAN is not set
+# CONFIG_VIA_RHINE is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_E1000 is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_R8169 is not set
+# CONFIG_SIS190 is not set
+# CONFIG_SKGE is not set
+# CONFIG_SKY2 is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_VIA_VELOCITY is not set
+# CONFIG_TIGON3 is not set
+# CONFIG_BNX2 is not set
+CONFIG_GIANFAR=y
+CONFIG_GFAR_NAPI=y
+
+#
+# Ethernet (10000 Mbit)
+#
+# CONFIG_CHELSIO_T1 is not set
+# CONFIG_IXGB is not set
+# CONFIG_S2IO is not set
+# CONFIG_MYRI10GE is not set
+
+#
+# Token Ring devices
+#
+# CONFIG_TR is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_NET_FC is not set
+# CONFIG_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
+
+#
+# Telephony Support
+#
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+
+#
+# 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 is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+# CONFIG_VT is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_PCI=y
+CONFIG_SERIAL_8250_NR_UARTS=4
+CONFIG_SERIAL_8250_RUNTIME_UARTS=4
+# CONFIG_SERIAL_8250_EXTENDED is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_JSM is not set
+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 is not set
+
+#
+# Watchdog Device Drivers
+#
+# CONFIG_SOFT_WATCHDOG is not set
+CONFIG_83xx_WDT=y
+
+#
+# PCI-based Watchdog Cards
+#
+# CONFIG_PCIPCWATCHDOG is not set
+# CONFIG_WDTPCI is not set
+
+#
+# USB-based Watchdog Cards
+#
+# CONFIG_USBPCWATCHDOG is not set
+CONFIG_HW_RANDOM=y
+# CONFIG_NVRAM is not set
+# CONFIG_GEN_RTC is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_AGP is not set
+# CONFIG_DRM is not set
+# CONFIG_RAW_DRIVER is not set
+
+#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+# CONFIG_TELCLOCK 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_ALI1535 is not set
+# CONFIG_I2C_ALI1563 is not set
+# CONFIG_I2C_ALI15X3 is not set
+# CONFIG_I2C_AMD756 is not set
+# CONFIG_I2C_AMD8111 is not set
+# CONFIG_I2C_I801 is not set
+# CONFIG_I2C_I810 is not set
+# CONFIG_I2C_PIIX4 is not set
+CONFIG_I2C_MPC=y
+# CONFIG_I2C_NFORCE2 is not set
+# CONFIG_I2C_OCORES is not set
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_PROSAVAGE is not set
+# CONFIG_I2C_SAVAGE4 is not set
+# CONFIG_I2C_SIS5595 is not set
+# CONFIG_I2C_SIS630 is not set
+# CONFIG_I2C_SIS96X is not set
+# CONFIG_I2C_STUB is not set
+# CONFIG_I2C_VIA is not set
+# CONFIG_I2C_VIAPRO is not set
+# CONFIG_I2C_VOODOO3 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_M41T00 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_BITBANG=y
+CONFIG_SPI_MPC83xx=y
+
+#
+# SPI Protocol Masters
+#
+
+#
+# Dallas's 1-wire bus
+#
+
+#
+# Hardware Monitoring support
+#
+CONFIG_HWMON=y
+# CONFIG_HWMON_VID is not set
+# CONFIG_SENSORS_ABITUGURU is not set
+# CONFIG_SENSORS_ADM1021 is not set
+# CONFIG_SENSORS_ADM1025 is not set
+# CONFIG_SENSORS_ADM1026 is not set
+# CONFIG_SENSORS_ADM1031 is not set
+# CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ASB100 is not set
+# CONFIG_SENSORS_ATXP1 is not set
+# CONFIG_SENSORS_DS1621 is not set
+# CONFIG_SENSORS_F71805F is not set
+# CONFIG_SENSORS_FSCHER is not set
+# CONFIG_SENSORS_FSCPOS is not set
+# CONFIG_SENSORS_GL518SM is not set
+# CONFIG_SENSORS_GL520SM is not set
+# CONFIG_SENSORS_IT87 is not set
+# CONFIG_SENSORS_LM63 is not set
+# CONFIG_SENSORS_LM70 is not set
+# CONFIG_SENSORS_LM75 is not set
+# CONFIG_SENSORS_LM77 is not set
+# CONFIG_SENSORS_LM78 is not set
+# CONFIG_SENSORS_LM80 is not set
+# CONFIG_SENSORS_LM83 is not set
+# CONFIG_SENSORS_LM85 is not set
+# CONFIG_SENSORS_LM87 is not set
+# CONFIG_SENSORS_LM90 is not set
+# CONFIG_SENSORS_LM92 is not set
+# CONFIG_SENSORS_MAX1619 is not set
+# CONFIG_SENSORS_PC87360 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_VT8231 is not set
+# CONFIG_SENSORS_W83781D is not set
+# CONFIG_SENSORS_W83791D is not set
+# CONFIG_SENSORS_W83792D 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
+#
+# CONFIG_DVB is not set
+# CONFIG_USB_DABUSB is not set
+
+#
+# Graphics support
+#
+CONFIG_FIRMWARE_EDID=y
+# CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
+#
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB_ARCH_HAS_EHCI=y
+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_OTG is not set
+
+#
+# USB Host Controller Drivers
+#
+CONFIG_USB_EHCI_HCD=y
+# 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_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_UHCI_HCD=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_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 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_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_PHIDGETKIT is not set
+# CONFIG_USB_PHIDGETSERVO is not set
+# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_APPLEDISPLAY is not set
+# CONFIG_USB_SISUSBVGA is not set
+# CONFIG_USB_LD 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=y
+CONFIG_USB_NET2280=y
+# 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 is not set
+# CONFIG_USB_GADGET_DUMMY_HCD is not set
+CONFIG_USB_GADGET_DUALSPEED=y
+# CONFIG_USB_ZERO is not set
+CONFIG_USB_ETH=y
+CONFIG_USB_ETH_RNDIS=y
+# CONFIG_USB_GADGETFS is not set
+# CONFIG_USB_FILE_STORAGE is not set
+# CONFIG_USB_G_SERIAL is not set
+
+#
+# MMC/SD Card support
+#
+# CONFIG_MMC is not set
+
+#
+# LED devices
+#
+# CONFIG_NEW_LEDS is not set
+
+#
+# LED drivers
+#
+
+#
+# LED Triggers
+#
+
+#
+# InfiniBand support
+#
+# CONFIG_INFINIBAND is not set
+
+#
+# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
+#
+
+#
+# Real Time Clock
+#
+CONFIG_RTC_LIB=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_HCTOSYS=y
+CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
+
+#
+# RTC interfaces
+#
+CONFIG_RTC_INTF_SYSFS=y
+CONFIG_RTC_INTF_PROC=y
+CONFIG_RTC_INTF_DEV=y
+CONFIG_RTC_INTF_DEV_UIE_EMUL=y
+
+#
+# RTC drivers
+#
+# CONFIG_RTC_DRV_X1205 is not set
+CONFIG_RTC_DRV_DS1307=y
+# CONFIG_RTC_DRV_DS1553 is not set
+# CONFIG_RTC_DRV_ISL1208 is not set
+# CONFIG_RTC_DRV_DS1672 is not set
+# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_PCF8563 is not set
+# CONFIG_RTC_DRV_PCF8583 is not set
+# CONFIG_RTC_DRV_RS5C348 is not set
+# CONFIG_RTC_DRV_RS5C372 is not set
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_TEST is not set
+# CONFIG_RTC_DRV_MAX6902 is not set
+# CONFIG_RTC_DRV_V3020 is not set
+
+#
+# DMA Engine support
+#
+CONFIG_DMA_ENGINE=y
+
+#
+# DMA Clients
+#
+CONFIG_NET_DMA=y
+
+#
+# DMA Devices
+#
+CONFIG_INTEL_IOATDMA=y
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
+CONFIG_EXT3_FS=y
+CONFIG_EXT3_FS_XATTR=y
+# CONFIG_EXT3_FS_POSIX_ACL is not set
+# CONFIG_EXT3_FS_SECURITY 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_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
+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_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_KCORE=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# 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_JFFS_FS is not set
+# CONFIG_JFFS2_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
+
+#
+# Network File Systems
+#
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
+CONFIG_NFS_V4=y
+# CONFIG_NFS_DIRECTIO is not set
+# CONFIG_NFSD is not set
+CONFIG_ROOT_NFS=y
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+CONFIG_SUNRPC_GSS=y
+CONFIG_RPCSEC_GSS_KRB5=y
+# 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=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+# CONFIG_MSDOS_PARTITION is not set
+# CONFIG_LDM_PARTITION is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_KARMA_PARTITION is not set
+# CONFIG_EFI_PARTITION is not set
+
+#
+# Native Language Support
+#
+# CONFIG_NLS is not set
+
+#
+# Library routines
+#
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
+CONFIG_CRC32=y
+# CONFIG_LIBCRC32C is not set
+CONFIG_PLIST=y
+
+#
+# Instrumentation Support
+#
+# CONFIG_PROFILING is not set
+
+#
+# Kernel hacking
+#
+CONFIG_PRINTK_TIME=y
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+CONFIG_DEBUG_KERNEL=y
+CONFIG_LOG_BUF_SHIFT=17
+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_INFO=y
+# CONFIG_DEBUG_FS is not set
+# CONFIG_DEBUG_VM is not set
+CONFIG_FORCED_INLINING=y
+# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_DEBUGGER is not set
+# CONFIG_BDI_SWITCH is not set
+CONFIG_BOOTX_TEXT=y
+CONFIG_SERIAL_TEXT_DEBUG=y
+# CONFIG_PPC_EARLY_DEBUG is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+
+#
+# Cryptographic options
+#
+CONFIG_CRYPTO=y
+# CONFIG_CRYPTO_HMAC is not set
+# CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_MD4 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_DES=y
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_AES is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_ARC4 is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Hardware crypto devices
+#
diff --git a/arch/powerpc/configs/mpc834x_mds_defconfig b/arch/powerpc/configs/mpc834x_mds_defconfig
new file mode 100644
index 000000000..9eefab967
--- /dev/null
+++ b/arch/powerpc/configs/mpc834x_mds_defconfig
@@ -0,0 +1,971 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.18-rc6
+# Sun Sep 10 10:28:54 2006
+#
+# CONFIG_PPC64 is not set
+CONFIG_PPC32=y
+CONFIG_PPC_MERGE=y
+CONFIG_MMU=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_IRQ_PER_CPU=y
+CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_PPC=y
+CONFIG_EARLY_PRINTK=y
+CONFIG_GENERIC_NVRAM=y
+CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
+CONFIG_ARCH_MAY_HAVE_PC_FDC=y
+CONFIG_PPC_OF=y
+CONFIG_PPC_UDBG_16550=y
+# CONFIG_GENERIC_TBSYNC is not set
+CONFIG_DEFAULT_UIMAGE=y
+
+#
+# Processor support
+#
+# CONFIG_CLASSIC32 is not set
+# CONFIG_PPC_52xx is not set
+# CONFIG_PPC_82xx is not set
+CONFIG_PPC_83xx=y
+# CONFIG_PPC_85xx is not set
+# CONFIG_PPC_86xx 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
+CONFIG_PPC_FPU=y
+CONFIG_PPC_STD_MMU=y
+CONFIG_PPC_STD_MMU_32=y
+# CONFIG_SMP is not set
+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_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_TASKSTATS is not set
+CONFIG_SYSCTL=y
+# CONFIG_AUDIT is not set
+# CONFIG_IKCONFIG is not set
+# CONFIG_RELAY is not set
+CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_EMBEDDED=y
+# CONFIG_KALLSYMS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+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_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 is not set
+
+#
+# Block layer
+#
+# 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=y
+CONFIG_IOSCHED_CFQ=y
+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"
+CONFIG_PPC_GEN550=y
+# CONFIG_WANT_EARLY_SERIAL is not set
+
+#
+# Platform support
+#
+CONFIG_MPC834x_SYS=y
+# CONFIG_MPC834x_ITX is not set
+CONFIG_MPC834x=y
+# CONFIG_MPIC is not set
+
+#
+# Kernel options
+#
+# CONFIG_HIGHMEM is not set
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
+CONFIG_ARCH_FLATMEM_ENABLE=y
+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=4
+# CONFIG_RESOURCES_64BIT is not set
+CONFIG_PROC_DEVICETREE=y
+# CONFIG_CMDLINE_BOOL is not set
+# CONFIG_PM is not set
+CONFIG_SECCOMP=y
+CONFIG_ISA_DMA_API=y
+
+#
+# Bus options
+#
+CONFIG_GENERIC_ISA_DMA=y
+# CONFIG_MPIC_WEIRD is not set
+# CONFIG_PPC_I8259 is not set
+CONFIG_PPC_INDIRECT_PCI=y
+CONFIG_FSL_SOC=y
+CONFIG_PCI=y
+CONFIG_PCI_DOMAINS=y
+# CONFIG_PCIEPORTBUS is not set
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# PCI Hotplug Support
+#
+# CONFIG_HOTPLUG_PCI is not set
+
+#
+# Advanced setup
+#
+# CONFIG_ADVANCED_OPTIONS is not set
+
+#
+# Default settings for advanced configuration options are used
+#
+CONFIG_HIGHMEM_START=0xfe000000
+CONFIG_LOWMEM_SIZE=0x30000000
+CONFIG_KERNEL_START=0xc0000000
+CONFIG_TASK_SIZE=0x80000000
+CONFIG_BOOT_LOAD=0x00800000
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+# CONFIG_NETDEBUG is not set
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=m
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+CONFIG_SYN_COOKIES=y
+# 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=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
+# 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_NET_DIVERT 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_SYS_HYPERVISOR is not set
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+# CONFIG_CONNECTOR is not set
+
+#
+# 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_FD is not set
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_SX8 is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=32768
+CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
+CONFIG_BLK_DEV_INITRD=y
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+# CONFIG_SCSI 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
+#
+# CONFIG_IEEE1394 is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+
+#
+# Macintosh device drivers
+#
+# CONFIG_WINDFARM is not set
+
+#
+# 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
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+
+#
+# PHY device support
+#
+CONFIG_PHYLIB=y
+
+#
+# MII PHY device drivers
+#
+CONFIG_MARVELL_PHY=y
+# CONFIG_DAVICOM_PHY is not set
+# CONFIG_QSEMI_PHY is not set
+# CONFIG_LXT_PHY is not set
+# CONFIG_CICADA_PHY is not set
+# CONFIG_VITESSE_PHY is not set
+# CONFIG_SMSC_PHY is not set
+# CONFIG_FIXED_PHY is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+# CONFIG_HAPPYMEAL is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_CASSINI is not set
+# CONFIG_NET_VENDOR_3COM is not set
+
+#
+# Tulip family network device support
+#
+# CONFIG_NET_TULIP is not set
+# CONFIG_HP100 is not set
+CONFIG_NET_PCI=y
+# CONFIG_PCNET32 is not set
+# CONFIG_AMD8111_ETH is not set
+# CONFIG_ADAPTEC_STARFIRE is not set
+# CONFIG_B44 is not set
+# CONFIG_FORCEDETH is not set
+# CONFIG_DGRS is not set
+# CONFIG_EEPRO100 is not set
+CONFIG_E100=y
+# CONFIG_FEALNX is not set
+# CONFIG_NATSEMI is not set
+# CONFIG_NE2K_PCI is not set
+# CONFIG_8139CP is not set
+# CONFIG_8139TOO is not set
+# CONFIG_SIS900 is not set
+# CONFIG_EPIC100 is not set
+# CONFIG_SUNDANCE is not set
+# CONFIG_TLAN is not set
+# CONFIG_VIA_RHINE is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_E1000 is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_R8169 is not set
+# CONFIG_SIS190 is not set
+# CONFIG_SKGE is not set
+# CONFIG_SKY2 is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_VIA_VELOCITY is not set
+# CONFIG_TIGON3 is not set
+# CONFIG_BNX2 is not set
+CONFIG_GIANFAR=y
+# CONFIG_GFAR_NAPI is not set
+
+#
+# Ethernet (10000 Mbit)
+#
+# CONFIG_CHELSIO_T1 is not set
+# CONFIG_IXGB is not set
+# CONFIG_S2IO is not set
+# CONFIG_MYRI10GE is not set
+
+#
+# Token Ring devices
+#
+# CONFIG_TR is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI 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
+
+#
+# Telephony Support
+#
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+
+#
+# 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 is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+# CONFIG_VT is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_PCI=y
+CONFIG_SERIAL_8250_NR_UARTS=4
+CONFIG_SERIAL_8250_RUNTIME_UARTS=4
+# CONFIG_SERIAL_8250_EXTENDED is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_JSM is not set
+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 is not set
+
+#
+# Watchdog Device Drivers
+#
+# CONFIG_SOFT_WATCHDOG is not set
+CONFIG_83xx_WDT=y
+
+#
+# PCI-based Watchdog Cards
+#
+# CONFIG_PCIPCWATCHDOG is not set
+# CONFIG_WDTPCI is not set
+# CONFIG_HW_RANDOM is not set
+# CONFIG_NVRAM is not set
+CONFIG_GEN_RTC=y
+# CONFIG_GEN_RTC_X is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_AGP is not set
+# CONFIG_DRM is not set
+# CONFIG_RAW_DRIVER is not set
+
+#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+# CONFIG_TELCLOCK 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_ALI1535 is not set
+# CONFIG_I2C_ALI1563 is not set
+# CONFIG_I2C_ALI15X3 is not set
+# CONFIG_I2C_AMD756 is not set
+# CONFIG_I2C_AMD8111 is not set
+# CONFIG_I2C_I801 is not set
+# CONFIG_I2C_I810 is not set
+# CONFIG_I2C_PIIX4 is not set
+CONFIG_I2C_MPC=y
+# CONFIG_I2C_NFORCE2 is not set
+# CONFIG_I2C_OCORES is not set
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_PROSAVAGE is not set
+# CONFIG_I2C_SAVAGE4 is not set
+# CONFIG_I2C_SIS5595 is not set
+# CONFIG_I2C_SIS630 is not set
+# CONFIG_I2C_SIS96X is not set
+# CONFIG_I2C_STUB is not set
+# CONFIG_I2C_VIA is not set
+# CONFIG_I2C_VIAPRO is not set
+# CONFIG_I2C_VOODOO3 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_M41T00 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 is not set
+# CONFIG_SPI_MASTER is not set
+
+#
+# Dallas's 1-wire bus
+#
+
+#
+# Hardware Monitoring support
+#
+CONFIG_HWMON=y
+# CONFIG_HWMON_VID is not set
+# CONFIG_SENSORS_ABITUGURU is not set
+# CONFIG_SENSORS_ADM1021 is not set
+# CONFIG_SENSORS_ADM1025 is not set
+# CONFIG_SENSORS_ADM1026 is not set
+# CONFIG_SENSORS_ADM1031 is not set
+# CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ASB100 is not set
+# CONFIG_SENSORS_ATXP1 is not set
+# CONFIG_SENSORS_DS1621 is not set
+# CONFIG_SENSORS_F71805F is not set
+# CONFIG_SENSORS_FSCHER is not set
+# CONFIG_SENSORS_FSCPOS is not set
+# CONFIG_SENSORS_GL518SM is not set
+# CONFIG_SENSORS_GL520SM is not set
+# CONFIG_SENSORS_IT87 is not set
+# CONFIG_SENSORS_LM63 is not set
+# CONFIG_SENSORS_LM75 is not set
+# CONFIG_SENSORS_LM77 is not set
+# CONFIG_SENSORS_LM78 is not set
+# CONFIG_SENSORS_LM80 is not set
+# CONFIG_SENSORS_LM83 is not set
+# CONFIG_SENSORS_LM85 is not set
+# CONFIG_SENSORS_LM87 is not set
+# CONFIG_SENSORS_LM90 is not set
+# CONFIG_SENSORS_LM92 is not set
+# CONFIG_SENSORS_MAX1619 is not set
+# CONFIG_SENSORS_PC87360 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_VT8231 is not set
+# CONFIG_SENSORS_W83781D is not set
+# CONFIG_SENSORS_W83791D is not set
+# CONFIG_SENSORS_W83792D 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
+#
+# CONFIG_DVB is not set
+
+#
+# Graphics support
+#
+CONFIG_FIRMWARE_EDID=y
+# CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
+#
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB_ARCH_HAS_EHCI=y
+# 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
+
+#
+# LED devices
+#
+# CONFIG_NEW_LEDS is not set
+
+#
+# LED drivers
+#
+
+#
+# LED Triggers
+#
+
+#
+# InfiniBand support
+#
+# CONFIG_INFINIBAND is not set
+
+#
+# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
+#
+
+#
+# Real Time Clock
+#
+# CONFIG_RTC_CLASS is not set
+
+#
+# DMA Engine support
+#
+# CONFIG_DMA_ENGINE is not set
+
+#
+# DMA Clients
+#
+
+#
+# DMA Devices
+#
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
+CONFIG_EXT3_FS=y
+CONFIG_EXT3_FS_XATTR=y
+# CONFIG_EXT3_FS_POSIX_ACL is not set
+# CONFIG_EXT3_FS_SECURITY 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_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
+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_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_KCORE=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# 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
+
+#
+# Network File Systems
+#
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
+CONFIG_NFS_V4=y
+# CONFIG_NFS_DIRECTIO is not set
+# CONFIG_NFSD is not set
+CONFIG_ROOT_NFS=y
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+CONFIG_SUNRPC_GSS=y
+CONFIG_RPCSEC_GSS_KRB5=y
+# 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=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+# CONFIG_MSDOS_PARTITION is not set
+# CONFIG_LDM_PARTITION is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_KARMA_PARTITION is not set
+# CONFIG_EFI_PARTITION is not set
+
+#
+# Native Language Support
+#
+# CONFIG_NLS is not set
+
+#
+# Library routines
+#
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
+CONFIG_CRC32=y
+# CONFIG_LIBCRC32C is not set
+CONFIG_PLIST=y
+
+#
+# Instrumentation Support
+#
+# CONFIG_PROFILING is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+# 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_BOOTX_TEXT is not set
+# CONFIG_SERIAL_TEXT_DEBUG is not set
+# CONFIG_PPC_EARLY_DEBUG is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+
+#
+# Cryptographic options
+#
+CONFIG_CRYPTO=y
+# CONFIG_CRYPTO_HMAC is not set
+# CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_MD4 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_DES=y
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_AES is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_ARC4 is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Hardware crypto devices
+#
diff --git a/arch/powerpc/configs/mpc85xx_cds_defconfig b/arch/powerpc/configs/mpc85xx_cds_defconfig
new file mode 100644
index 000000000..72edf9f66
--- /dev/null
+++ b/arch/powerpc/configs/mpc85xx_cds_defconfig
@@ -0,0 +1,895 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.18-rc6
+# Sun Sep 10 10:29:49 2006
+#
+# CONFIG_PPC64 is not set
+CONFIG_PPC32=y
+CONFIG_PPC_MERGE=y
+CONFIG_MMU=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_IRQ_PER_CPU=y
+CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_PPC=y
+CONFIG_EARLY_PRINTK=y
+CONFIG_GENERIC_NVRAM=y
+CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
+CONFIG_ARCH_MAY_HAVE_PC_FDC=y
+CONFIG_PPC_OF=y
+CONFIG_PPC_UDBG_16550=y
+# CONFIG_GENERIC_TBSYNC is not set
+CONFIG_DEFAULT_UIMAGE=y
+
+#
+# Processor support
+#
+# CONFIG_CLASSIC32 is not set
+# CONFIG_PPC_52xx is not set
+# CONFIG_PPC_82xx is not set
+# CONFIG_PPC_83xx is not set
+CONFIG_PPC_85xx=y
+# CONFIG_PPC_86xx 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
+CONFIG_BOOKE=y
+CONFIG_FSL_BOOKE=y
+# CONFIG_PHYS_64BIT is not set
+CONFIG_SPE=y
+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_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_TASKSTATS is not set
+CONFIG_SYSCTL=y
+# CONFIG_AUDIT is not set
+# CONFIG_IKCONFIG is not set
+# CONFIG_RELAY is not set
+CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_EMBEDDED=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_RT_MUTEXES=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SHMEM=y
+CONFIG_SLAB=y
+CONFIG_VM_EVENT_COUNTERS=y
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+# CONFIG_SLOB is not set
+
+#
+# Loadable module support
+#
+# CONFIG_MODULES is not set
+
+#
+# Block layer
+#
+# 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=y
+CONFIG_IOSCHED_CFQ=y
+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"
+# CONFIG_WANT_EARLY_SERIAL is not set
+
+#
+# Platform support
+#
+# CONFIG_MPC8540_ADS is not set
+CONFIG_MPC85xx_CDS=y
+CONFIG_MPC8540=y
+CONFIG_PPC_INDIRECT_PCI_BE=y
+CONFIG_MPIC=y
+
+#
+# Kernel options
+#
+# CONFIG_HIGHMEM is not set
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
+CONFIG_BINFMT_ELF=y
+CONFIG_BINFMT_MISC=y
+CONFIG_MATH_EMULATION=y
+CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
+CONFIG_ARCH_FLATMEM_ENABLE=y
+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=4
+# CONFIG_RESOURCES_64BIT is not set
+CONFIG_PROC_DEVICETREE=y
+# CONFIG_CMDLINE_BOOL is not set
+# CONFIG_PM is not set
+# CONFIG_SECCOMP is not set
+CONFIG_ISA_DMA_API=y
+
+#
+# Bus options
+#
+# CONFIG_MPIC_WEIRD is not set
+# CONFIG_PPC_I8259 is not set
+CONFIG_PPC_INDIRECT_PCI=y
+CONFIG_FSL_SOC=y
+CONFIG_PCI=y
+CONFIG_PCI_DOMAINS=y
+# CONFIG_PCIEPORTBUS is not set
+# CONFIG_PCI_DEBUG is not set
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# PCI Hotplug Support
+#
+# CONFIG_HOTPLUG_PCI is not set
+
+#
+# Advanced setup
+#
+# CONFIG_ADVANCED_OPTIONS is not set
+
+#
+# Default settings for advanced configuration options are used
+#
+CONFIG_HIGHMEM_START=0xfe000000
+CONFIG_LOWMEM_SIZE=0x30000000
+CONFIG_KERNEL_START=0xc0000000
+CONFIG_TASK_SIZE=0x80000000
+CONFIG_BOOT_LOAD=0x00800000
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+# CONFIG_NETDEBUG is not set
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=y
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+CONFIG_SYN_COOKIES=y
+# 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=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
+# 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_NET_DIVERT 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 is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Plug and Play support
+#
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_SX8 is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=32768
+CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
+CONFIG_BLK_DEV_INITRD=y
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+CONFIG_IDE=y
+CONFIG_BLK_DEV_IDE=y
+
+#
+# Please see Documentation/ide.txt for help/info on IDE drives
+#
+# CONFIG_BLK_DEV_IDE_SATA is not set
+# CONFIG_BLK_DEV_IDEDISK is not set
+# CONFIG_IDEDISK_MULTI_MODE is not set
+# CONFIG_BLK_DEV_IDECD is not set
+# CONFIG_BLK_DEV_IDETAPE is not set
+# CONFIG_BLK_DEV_IDEFLOPPY is not set
+# CONFIG_IDE_TASK_IOCTL is not set
+
+#
+# IDE chipset support/bugfixes
+#
+CONFIG_IDE_GENERIC=y
+CONFIG_BLK_DEV_IDEPCI=y
+CONFIG_IDEPCI_SHARE_IRQ=y
+# CONFIG_BLK_DEV_OFFBOARD is not set
+CONFIG_BLK_DEV_GENERIC=y
+# CONFIG_BLK_DEV_OPTI621 is not set
+# CONFIG_BLK_DEV_SL82C105 is not set
+CONFIG_BLK_DEV_IDEDMA_PCI=y
+# CONFIG_BLK_DEV_IDEDMA_FORCED is not set
+# CONFIG_IDEDMA_PCI_AUTO is not set
+# CONFIG_BLK_DEV_AEC62XX is not set
+# CONFIG_BLK_DEV_ALI15X3 is not set
+# CONFIG_BLK_DEV_AMD74XX is not set
+# CONFIG_BLK_DEV_CMD64X is not set
+# CONFIG_BLK_DEV_TRIFLEX is not set
+# CONFIG_BLK_DEV_CY82C693 is not set
+# CONFIG_BLK_DEV_CS5520 is not set
+# CONFIG_BLK_DEV_CS5530 is not set
+# CONFIG_BLK_DEV_HPT34X is not set
+# CONFIG_BLK_DEV_HPT366 is not set
+# CONFIG_BLK_DEV_SC1200 is not set
+# CONFIG_BLK_DEV_PIIX is not set
+# CONFIG_BLK_DEV_IT821X is not set
+# CONFIG_BLK_DEV_NS87415 is not set
+# CONFIG_BLK_DEV_PDC202XX_OLD is not set
+# 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_SLC90E66 is not set
+# CONFIG_BLK_DEV_TRM290 is not set
+CONFIG_BLK_DEV_VIA82CXXX=y
+# CONFIG_IDE_ARM is not set
+CONFIG_BLK_DEV_IDEDMA=y
+# CONFIG_IDEDMA_IVB is not set
+# CONFIG_IDEDMA_AUTO is not set
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+# CONFIG_SCSI 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
+#
+# CONFIG_IEEE1394 is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+
+#
+# Macintosh device drivers
+#
+# CONFIG_WINDFARM is not set
+
+#
+# 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
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+
+#
+# PHY device support
+#
+CONFIG_PHYLIB=y
+
+#
+# MII PHY device drivers
+#
+# CONFIG_MARVELL_PHY is not set
+# CONFIG_DAVICOM_PHY is not set
+# CONFIG_QSEMI_PHY is not set
+# CONFIG_LXT_PHY is not set
+# CONFIG_CICADA_PHY is not set
+# CONFIG_VITESSE_PHY is not set
+# CONFIG_SMSC_PHY is not set
+# CONFIG_FIXED_PHY is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+# CONFIG_HAPPYMEAL is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_CASSINI is not set
+# CONFIG_NET_VENDOR_3COM is not set
+
+#
+# Tulip family network device support
+#
+# CONFIG_NET_TULIP is not set
+# CONFIG_HP100 is not set
+# CONFIG_NET_PCI is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+CONFIG_E1000=y
+CONFIG_E1000_NAPI=y
+# CONFIG_E1000_DISABLE_PACKET_SPLIT is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_R8169 is not set
+# CONFIG_SIS190 is not set
+# CONFIG_SKGE is not set
+# CONFIG_SKY2 is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_TIGON3 is not set
+# CONFIG_BNX2 is not set
+CONFIG_GIANFAR=y
+CONFIG_GFAR_NAPI=y
+
+#
+# Ethernet (10000 Mbit)
+#
+# CONFIG_CHELSIO_T1 is not set
+# CONFIG_IXGB is not set
+# CONFIG_S2IO is not set
+# CONFIG_MYRI10GE is not set
+
+#
+# Token Ring devices
+#
+# CONFIG_TR is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI 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
+
+#
+# Telephony Support
+#
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+
+#
+# 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 is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+# CONFIG_VT is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_PCI=y
+CONFIG_SERIAL_8250_NR_UARTS=4
+CONFIG_SERIAL_8250_RUNTIME_UARTS=4
+# CONFIG_SERIAL_8250_EXTENDED is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_JSM is not set
+CONFIG_UNIX98_PTYS=y
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+
+#
+# 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_GEN_RTC=y
+# CONFIG_GEN_RTC_X is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_AGP is not set
+# CONFIG_DRM is not set
+# CONFIG_RAW_DRIVER is not set
+
+#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+# CONFIG_TELCLOCK 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
+#
+
+#
+# Hardware Monitoring support
+#
+CONFIG_HWMON=y
+# CONFIG_HWMON_VID is not set
+# CONFIG_SENSORS_ABITUGURU is not set
+# CONFIG_SENSORS_F71805F 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
+#
+# CONFIG_DVB is not set
+
+#
+# Graphics support
+#
+CONFIG_FIRMWARE_EDID=y
+# CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
+#
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB_ARCH_HAS_EHCI=y
+# 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
+
+#
+# LED devices
+#
+# CONFIG_NEW_LEDS is not set
+
+#
+# LED drivers
+#
+
+#
+# LED Triggers
+#
+
+#
+# InfiniBand support
+#
+# CONFIG_INFINIBAND is not set
+
+#
+# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
+#
+
+#
+# Real Time Clock
+#
+# CONFIG_RTC_CLASS is not set
+
+#
+# DMA Engine support
+#
+# CONFIG_DMA_ENGINE is not set
+
+#
+# DMA Clients
+#
+
+#
+# DMA Devices
+#
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
+CONFIG_EXT3_FS=y
+CONFIG_EXT3_FS_XATTR=y
+# CONFIG_EXT3_FS_POSIX_ACL is not set
+# CONFIG_EXT3_FS_SECURITY 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_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
+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_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_KCORE=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# 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
+
+#
+# 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=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+# CONFIG_MSDOS_PARTITION is not set
+# CONFIG_LDM_PARTITION is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_KARMA_PARTITION is not set
+# CONFIG_EFI_PARTITION is not set
+
+#
+# Native Language Support
+#
+# CONFIG_NLS is not set
+
+#
+# Library routines
+#
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
+CONFIG_CRC32=y
+# CONFIG_LIBCRC32C is not set
+CONFIG_PLIST=y
+
+#
+# Instrumentation Support
+#
+# CONFIG_PROFILING is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_UNUSED_SYMBOLS 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=y
+# 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_INFO is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_DEBUG_VM is not set
+# CONFIG_UNWIND_INFO is not set
+CONFIG_FORCED_INLINING=y
+# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_DEBUGGER is not set
+# CONFIG_BDI_SWITCH is not set
+# CONFIG_BOOTX_TEXT is not set
+# CONFIG_PPC_EARLY_DEBUG is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+
+#
+# Cryptographic options
+#
+# CONFIG_CRYPTO is not set
+
+#
+# Hardware crypto devices
+#
diff --git a/arch/powerpc/configs/mpc8641_hpcn_defconfig b/arch/powerpc/configs/mpc8641_hpcn_defconfig
new file mode 100644
index 000000000..92a527fcc
--- /dev/null
+++ b/arch/powerpc/configs/mpc8641_hpcn_defconfig
@@ -0,0 +1,963 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.18-rc6
+# Sun Sep 10 10:30:15 2006
+#
+# CONFIG_PPC64 is not set
+CONFIG_PPC32=y
+CONFIG_PPC_MERGE=y
+CONFIG_MMU=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_IRQ_PER_CPU=y
+CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_PPC=y
+CONFIG_EARLY_PRINTK=y
+CONFIG_GENERIC_NVRAM=y
+CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
+CONFIG_ARCH_MAY_HAVE_PC_FDC=y
+CONFIG_PPC_OF=y
+CONFIG_PPC_UDBG_16550=y
+CONFIG_GENERIC_TBSYNC=y
+# CONFIG_DEFAULT_UIMAGE is not set
+
+#
+# Processor support
+#
+# CONFIG_CLASSIC32 is not set
+# CONFIG_PPC_52xx is not set
+# CONFIG_PPC_82xx is not set
+# CONFIG_PPC_83xx is not set
+# CONFIG_PPC_85xx is not set
+CONFIG_PPC_86xx=y
+# CONFIG_40x is not set
+# CONFIG_44x is not set
+# CONFIG_8xx is not set
+# CONFIG_E200 is not set
+CONFIG_6xx=y
+CONFIG_PPC_FPU=y
+CONFIG_ALTIVEC=y
+CONFIG_PPC_STD_MMU=y
+CONFIG_PPC_STD_MMU_32=y
+CONFIG_SMP=y
+CONFIG_NR_CPUS=2
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+# CONFIG_LOCALVERSION_AUTO is not set
+# CONFIG_SWAP is not set
+# CONFIG_SYSVIPC is not set
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_TASKSTATS is not set
+CONFIG_SYSCTL=y
+# CONFIG_AUDIT is not set
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+# CONFIG_CPUSETS is not set
+# CONFIG_RELAY is not set
+CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_EMBEDDED=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
+CONFIG_KALLSYMS_EXTRA_PASS=y
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+# CONFIG_ELF_CORE is not set
+CONFIG_BASE_FULL=y
+CONFIG_RT_MUTEXES=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SHMEM=y
+# CONFIG_SLAB is not set
+CONFIG_VM_EVENT_COUNTERS=y
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+CONFIG_SLOB=y
+
+#
+# Loadable module support
+#
+# CONFIG_MODULES is not set
+
+#
+# Block layer
+#
+# 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=y
+# CONFIG_IOSCHED_CFQ is not set
+# CONFIG_DEFAULT_AS is not set
+CONFIG_DEFAULT_DEADLINE=y
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="deadline"
+# CONFIG_WANT_EARLY_SERIAL is not set
+CONFIG_PPC_INDIRECT_PCI_BE=y
+CONFIG_MPIC=y
+
+#
+# Platform Support
+#
+CONFIG_MPC8641_HPCN=y
+CONFIG_MPC8641=y
+
+#
+# Kernel options
+#
+CONFIG_HIGHMEM=y
+# CONFIG_HZ_100 is not set
+# CONFIG_HZ_250 is not set
+CONFIG_HZ_1000=y
+CONFIG_HZ=1000
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
+CONFIG_PREEMPT_BKL=y
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
+# CONFIG_IRQ_ALL_CPUS is not set
+CONFIG_ARCH_FLATMEM_ENABLE=y
+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=4
+# CONFIG_RESOURCES_64BIT is not set
+CONFIG_PROC_DEVICETREE=y
+# CONFIG_CMDLINE_BOOL is not set
+# CONFIG_PM is not set
+# CONFIG_SECCOMP is not set
+CONFIG_ISA_DMA_API=y
+
+#
+# Bus options
+#
+CONFIG_GENERIC_ISA_DMA=y
+# CONFIG_MPIC_WEIRD is not set
+CONFIG_PPC_I8259=y
+CONFIG_PPC_INDIRECT_PCI=y
+CONFIG_FSL_SOC=y
+CONFIG_PCI=y
+CONFIG_PCI_DOMAINS=y
+# CONFIG_PCIEPORTBUS is not set
+# CONFIG_PCI_DEBUG is not set
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# PCI Hotplug Support
+#
+# CONFIG_HOTPLUG_PCI is not set
+
+#
+# Advanced setup
+#
+# CONFIG_ADVANCED_OPTIONS is not set
+
+#
+# Default settings for advanced configuration options are used
+#
+CONFIG_HIGHMEM_START=0xfe000000
+CONFIG_LOWMEM_SIZE=0x30000000
+CONFIG_KERNEL_START=0xc0000000
+CONFIG_TASK_SIZE=0x80000000
+CONFIG_BOOT_LOAD=0x00800000
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+# CONFIG_NETDEBUG is not set
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=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=y
+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=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
+CONFIG_IPV6=y
+# CONFIG_IPV6_PRIVACY is not set
+# CONFIG_IPV6_ROUTER_PREF is not set
+# CONFIG_INET6_AH is not set
+# CONFIG_INET6_ESP is not set
+# CONFIG_INET6_IPCOMP is not set
+# CONFIG_INET6_XFRM_TUNNEL is not set
+# CONFIG_INET6_TUNNEL is not set
+CONFIG_INET6_XFRM_MODE_TRANSPORT=y
+CONFIG_INET6_XFRM_MODE_TUNNEL=y
+# CONFIG_IPV6_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_NET_DIVERT 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=y
+# 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 is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Plug and Play support
+#
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_SX8 is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=131072
+CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
+CONFIG_BLK_DEV_INITRD=y
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+# CONFIG_SCSI 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
+#
+# CONFIG_IEEE1394 is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+
+#
+# Macintosh device drivers
+#
+# CONFIG_WINDFARM is not set
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+CONFIG_DUMMY=y
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+
+#
+# PHY device support
+#
+CONFIG_PHYLIB=y
+
+#
+# MII PHY device drivers
+#
+# CONFIG_MARVELL_PHY is not set
+# CONFIG_DAVICOM_PHY is not set
+# CONFIG_QSEMI_PHY is not set
+# CONFIG_LXT_PHY is not set
+# CONFIG_CICADA_PHY is not set
+CONFIG_VITESSE_PHY=y
+# CONFIG_SMSC_PHY is not set
+# CONFIG_FIXED_PHY is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+# CONFIG_HAPPYMEAL is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_CASSINI is not set
+# CONFIG_NET_VENDOR_3COM is not set
+
+#
+# Tulip family network device support
+#
+# CONFIG_NET_TULIP is not set
+# CONFIG_HP100 is not set
+# CONFIG_NET_PCI is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_E1000 is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_R8169 is not set
+# CONFIG_SIS190 is not set
+# CONFIG_SKGE is not set
+# CONFIG_SKY2 is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_TIGON3 is not set
+# CONFIG_BNX2 is not set
+CONFIG_GIANFAR=y
+# CONFIG_GFAR_NAPI is not set
+
+#
+# Ethernet (10000 Mbit)
+#
+# CONFIG_CHELSIO_T1 is not set
+# CONFIG_IXGB is not set
+# CONFIG_S2IO is not set
+# CONFIG_MYRI10GE is not set
+
+#
+# Token Ring devices
+#
+# CONFIG_TR is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI 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
+
+#
+# Telephony Support
+#
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+
+#
+# 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_I8042=y
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_PCIPS2 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_PCI=y
+CONFIG_SERIAL_8250_NR_UARTS=2
+CONFIG_SERIAL_8250_RUNTIME_UARTS=2
+CONFIG_SERIAL_8250_EXTENDED=y
+CONFIG_SERIAL_8250_MANY_PORTS=y
+CONFIG_SERIAL_8250_SHARE_IRQ=y
+CONFIG_SERIAL_8250_DETECT_IRQ=y
+CONFIG_SERIAL_8250_RSA=y
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_JSM is not set
+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_GEN_RTC is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_AGP is not set
+# CONFIG_DRM is not set
+# CONFIG_RAW_DRIVER is not set
+
+#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+# CONFIG_TELCLOCK is not set
+
+#
+# I2C support
+#
+CONFIG_I2C=y
+# CONFIG_I2C_CHARDEV is not set
+
+#
+# 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_ALI1535 is not set
+# CONFIG_I2C_ALI1563 is not set
+# CONFIG_I2C_ALI15X3 is not set
+# CONFIG_I2C_AMD756 is not set
+# CONFIG_I2C_AMD8111 is not set
+# CONFIG_I2C_I801 is not set
+# CONFIG_I2C_I810 is not set
+# CONFIG_I2C_PIIX4 is not set
+CONFIG_I2C_MPC=y
+# CONFIG_I2C_NFORCE2 is not set
+# CONFIG_I2C_OCORES is not set
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_PROSAVAGE is not set
+# CONFIG_I2C_SAVAGE4 is not set
+# CONFIG_I2C_SIS5595 is not set
+# CONFIG_I2C_SIS630 is not set
+# CONFIG_I2C_SIS96X is not set
+# CONFIG_I2C_VIA is not set
+# CONFIG_I2C_VIAPRO is not set
+# CONFIG_I2C_VOODOO3 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=y
+# CONFIG_SENSORS_PCF8574 is not set
+# CONFIG_SENSORS_PCA9539 is not set
+# CONFIG_SENSORS_PCF8591 is not set
+# CONFIG_SENSORS_M41T00 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 is not set
+# CONFIG_SPI_MASTER is not set
+
+#
+# Dallas's 1-wire bus
+#
+
+#
+# Hardware Monitoring support
+#
+# CONFIG_HWMON is not set
+# CONFIG_HWMON_VID is not set
+
+#
+# Misc devices
+#
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+CONFIG_VIDEO_V4L2=y
+
+#
+# Digital Video Broadcasting Devices
+#
+# CONFIG_DVB is not set
+
+#
+# Graphics support
+#
+CONFIG_FIRMWARE_EDID=y
+# CONFIG_FB is not set
+
+#
+# Console display driver support
+#
+CONFIG_VGA_CONSOLE=y
+# CONFIG_VGACON_SOFT_SCROLLBACK is not set
+CONFIG_DUMMY_CONSOLE=y
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
+#
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB_ARCH_HAS_EHCI=y
+# 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
+
+#
+# LED devices
+#
+# CONFIG_NEW_LEDS is not set
+
+#
+# LED drivers
+#
+
+#
+# LED Triggers
+#
+
+#
+# InfiniBand support
+#
+# CONFIG_INFINIBAND is not set
+
+#
+# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
+#
+
+#
+# Real Time Clock
+#
+# CONFIG_RTC_CLASS is not set
+
+#
+# DMA Engine support
+#
+# CONFIG_DMA_ENGINE is not set
+
+#
+# DMA Clients
+#
+
+#
+# DMA Devices
+#
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
+CONFIG_EXT3_FS=y
+CONFIG_EXT3_FS_XATTR=y
+# CONFIG_EXT3_FS_POSIX_ACL is not set
+# CONFIG_EXT3_FS_SECURITY 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_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 is not set
+# 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_KCORE=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# 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
+
+#
+# Network File Systems
+#
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
+# CONFIG_NFS_V4 is not set
+# CONFIG_NFS_DIRECTIO is not set
+CONFIG_NFSD=y
+# CONFIG_NFSD_V3 is not set
+CONFIG_NFSD_TCP=y
+CONFIG_ROOT_NFS=y
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_EXPORTFS=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=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_BSD_DISKLABEL is not set
+# CONFIG_MINIX_SUBPARTITION is not set
+# CONFIG_SOLARIS_X86_PARTITION is not set
+# CONFIG_UNIXWARE_DISKLABEL is not set
+CONFIG_LDM_PARTITION=y
+# CONFIG_LDM_DEBUG is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_KARMA_PARTITION is not set
+# CONFIG_EFI_PARTITION is not set
+
+#
+# Native Language Support
+#
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="iso8859-1"
+# CONFIG_NLS_CODEPAGE_437 is not set
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ASCII is not set
+# CONFIG_NLS_ISO8859_1 is not set
+# 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
+
+#
+# Library routines
+#
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
+CONFIG_CRC32=y
+# CONFIG_LIBCRC32C is not set
+CONFIG_PLIST=y
+
+#
+# Instrumentation Support
+#
+# CONFIG_PROFILING is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+CONFIG_DEBUG_KERNEL=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_SCHEDSTATS 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_HIGHMEM is not set
+# CONFIG_DEBUG_INFO is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_DEBUG_VM is not set
+# CONFIG_UNWIND_INFO is not set
+CONFIG_FORCED_INLINING=y
+# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_DEBUGGER is not set
+# CONFIG_BDI_SWITCH is not set
+# CONFIG_BOOTX_TEXT is not set
+# CONFIG_PPC_EARLY_DEBUG is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+
+#
+# Cryptographic options
+#
+# CONFIG_CRYPTO is not set
+
+#
+# Hardware crypto devices
+#
diff --git a/arch/powerpc/kernel/audit.c b/arch/powerpc/kernel/audit.c
new file mode 100644
index 000000000..7fe5e6300
--- /dev/null
+++ b/arch/powerpc/kernel/audit.c
@@ -0,0 +1,66 @@
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/audit.h>
+#include <asm/unistd.h>
+
+static unsigned dir_class[] = {
+#include <asm-generic/audit_dir_write.h>
+~0U
+};
+
+static unsigned read_class[] = {
+#include <asm-generic/audit_read.h>
+~0U
+};
+
+static unsigned write_class[] = {
+#include <asm-generic/audit_write.h>
+~0U
+};
+
+static unsigned chattr_class[] = {
+#include <asm-generic/audit_change_attr.h>
+~0U
+};
+
+int audit_classify_syscall(int abi, unsigned syscall)
+{
+#ifdef CONFIG_PPC64
+	extern int ppc32_classify_syscall(unsigned);
+	if (abi == AUDIT_ARCH_PPC)
+		return ppc32_classify_syscall(syscall);
+#endif
+	switch(syscall) {
+	case __NR_open:
+		return 2;
+	case __NR_openat:
+		return 3;
+	case __NR_socketcall:
+		return 4;
+	case __NR_execve:
+		return 5;
+	default:
+		return 0;
+	}
+}
+
+static int __init audit_classes_init(void)
+{
+#ifdef CONFIG_PPC64
+	extern __u32 ppc32_dir_class[];
+	extern __u32 ppc32_write_class[];
+	extern __u32 ppc32_read_class[];
+	extern __u32 ppc32_chattr_class[];
+	audit_register_class(AUDIT_CLASS_WRITE_32, ppc32_write_class);
+	audit_register_class(AUDIT_CLASS_READ_32, ppc32_read_class);
+	audit_register_class(AUDIT_CLASS_DIR_WRITE_32, ppc32_dir_class);
+	audit_register_class(AUDIT_CLASS_CHATTR_32, ppc32_chattr_class);
+#endif
+	audit_register_class(AUDIT_CLASS_WRITE, write_class);
+	audit_register_class(AUDIT_CLASS_READ, read_class);
+	audit_register_class(AUDIT_CLASS_DIR_WRITE, dir_class);
+	audit_register_class(AUDIT_CLASS_CHATTR, chattr_class);
+	return 0;
+}
+
+__initcall(audit_classes_init);
diff --git a/arch/powerpc/kernel/compat_audit.c b/arch/powerpc/kernel/compat_audit.c
new file mode 100644
index 000000000..640d4bb29
--- /dev/null
+++ b/arch/powerpc/kernel/compat_audit.c
@@ -0,0 +1,38 @@
+#undef __powerpc64__
+#include <asm/unistd.h>
+
+unsigned ppc32_dir_class[] = {
+#include <asm-generic/audit_dir_write.h>
+~0U
+};
+
+unsigned ppc32_chattr_class[] = {
+#include <asm-generic/audit_change_attr.h>
+~0U
+};
+
+unsigned ppc32_write_class[] = {
+#include <asm-generic/audit_write.h>
+~0U
+};
+
+unsigned ppc32_read_class[] = {
+#include <asm-generic/audit_read.h>
+~0U
+};
+
+int ppc32_classify_syscall(unsigned syscall)
+{
+	switch(syscall) {
+	case __NR_open:
+		return 2;
+	case __NR_openat:
+		return 3;
+	case __NR_socketcall:
+		return 4;
+	case __NR_execve:
+		return 5;
+	default:
+		return 1;
+	}
+}
diff --git a/arch/powerpc/kernel/misc.S b/arch/powerpc/kernel/misc.S
new file mode 100644
index 000000000..f770805f1
--- /dev/null
+++ b/arch/powerpc/kernel/misc.S
@@ -0,0 +1,204 @@
+/*
+ * This file contains miscellaneous low-level functions.
+ *    Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
+ *
+ * Largely rewritten by Cort Dougan (cort@cs.nmt.edu)
+ * and Paul Mackerras.
+ *
+ * Adapted for iSeries by Mike Corrigan (mikejc@us.ibm.com)
+ * PPC64 updates by Dave Engebretsen (engebret@us.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 of the License, or (at your option) any later version.
+ */
+#include <asm/ppc_asm.h>
+
+	.text
+
+/*
+ * Returns (address we are running at) - (address we were linked at)
+ * for use before the text and data are mapped to KERNELBASE.
+ */
+
+_GLOBAL(reloc_offset)
+	mflr	r0
+	bl	1f
+1:	mflr	r3
+	LOAD_REG_IMMEDIATE(r4,1b)
+	subf	r3,r4,r3
+	mtlr	r0
+	blr
+
+/*
+ * add_reloc_offset(x) returns x + reloc_offset().
+ */
+_GLOBAL(add_reloc_offset)
+	mflr	r0
+	bl	1f
+1:	mflr	r5
+	LOAD_REG_IMMEDIATE(r4,1b)
+	subf	r5,r4,r5
+	add	r3,r3,r5
+	mtlr	r0
+	blr
+
+/*
+ * I/O string operations
+ *
+ * insb(port, buf, len)
+ * outsb(port, buf, len)
+ * insw(port, buf, len)
+ * outsw(port, buf, len)
+ * insl(port, buf, len)
+ * outsl(port, buf, len)
+ * insw_ns(port, buf, len)
+ * outsw_ns(port, buf, len)
+ * insl_ns(port, buf, len)
+ * outsl_ns(port, buf, len)
+ *
+ * The *_ns versions don't do byte-swapping.
+ */
+_GLOBAL(_insb)
+	sync
+	cmpwi	0,r5,0
+	mtctr	r5
+	subi	r4,r4,1
+	blelr-
+00:	lbz	r5,0(r3)
+	eieio
+	stbu	r5,1(r4)
+	bdnz	00b
+	twi	0,r5,0
+	isync
+	blr
+
+_GLOBAL(_outsb)
+	cmpwi	0,r5,0
+	mtctr	r5
+	subi	r4,r4,1
+	blelr-
+	sync
+00:	lbzu	r5,1(r4)
+	stb	r5,0(r3)
+	bdnz	00b
+	sync
+	blr
+
+_GLOBAL(_insw)
+	sync
+	cmpwi	0,r5,0
+	mtctr	r5
+	subi	r4,r4,2
+	blelr-
+00:	lhbrx	r5,0,r3
+	eieio
+	sthu	r5,2(r4)
+	bdnz	00b
+	twi	0,r5,0
+	isync
+	blr
+
+_GLOBAL(_outsw)
+	cmpwi	0,r5,0
+	mtctr	r5
+	subi	r4,r4,2
+	blelr-
+	sync
+00:	lhzu	r5,2(r4)
+	sthbrx	r5,0,r3
+	bdnz	00b
+	sync
+	blr
+
+_GLOBAL(_insl)
+	sync
+	cmpwi	0,r5,0
+	mtctr	r5
+	subi	r4,r4,4
+	blelr-
+00:	lwbrx	r5,0,r3
+	eieio
+	stwu	r5,4(r4)
+	bdnz	00b
+	twi	0,r5,0
+	isync
+	blr
+
+_GLOBAL(_outsl)
+	cmpwi	0,r5,0
+	mtctr	r5
+	subi	r4,r4,4
+	blelr-
+	sync
+00:	lwzu	r5,4(r4)
+	stwbrx	r5,0,r3
+	bdnz	00b
+	sync
+	blr
+
+#ifdef CONFIG_PPC32
+_GLOBAL(__ide_mm_insw)
+#endif
+_GLOBAL(_insw_ns)
+	sync
+	cmpwi	0,r5,0
+	mtctr	r5
+	subi	r4,r4,2
+	blelr-
+00:	lhz	r5,0(r3)
+	eieio
+	sthu	r5,2(r4)
+	bdnz	00b
+	twi	0,r5,0
+	isync
+	blr
+
+#ifdef CONFIG_PPC32
+_GLOBAL(__ide_mm_outsw)
+#endif
+_GLOBAL(_outsw_ns)
+	cmpwi	0,r5,0
+	mtctr	r5
+	subi	r4,r4,2
+	blelr-
+	sync
+00:	lhzu	r5,2(r4)
+	sth	r5,0(r3)
+	bdnz	00b
+	sync
+	blr
+
+#ifdef CONFIG_PPC32
+_GLOBAL(__ide_mm_insl)
+#endif
+_GLOBAL(_insl_ns)
+	sync
+	cmpwi	0,r5,0
+	mtctr	r5
+	subi	r4,r4,4
+	blelr-
+00:	lwz	r5,0(r3)
+	eieio
+	stwu	r5,4(r4)
+	bdnz	00b
+	twi	0,r5,0
+	isync
+	blr
+
+#ifdef CONFIG_PPC32
+_GLOBAL(__ide_mm_outsl)
+#endif
+_GLOBAL(_outsl_ns)
+	cmpwi	0,r5,0
+	mtctr	r5
+	subi	r4,r4,4
+	blelr-
+	sync
+00:	lwzu	r5,4(r4)
+	stw	r5,0(r3)
+	bdnz	00b
+	sync
+	blr
+
diff --git a/arch/powerpc/platforms/83xx/mpc834x_itx.c b/arch/powerpc/platforms/83xx/mpc834x_itx.c
new file mode 100644
index 000000000..8eed8723d
--- /dev/null
+++ b/arch/powerpc/platforms/83xx/mpc834x_itx.c
@@ -0,0 +1,124 @@
+/*
+ * arch/powerpc/platforms/83xx/mpc834x_itx.c
+ *
+ * MPC834x ITX board specific routines
+ *
+ * Maintainer: Kumar Gala <galak@kernel.crashing.org>
+ *
+ * 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/stddef.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/reboot.h>
+#include <linux/pci.h>
+#include <linux/kdev_t.h>
+#include <linux/major.h>
+#include <linux/console.h>
+#include <linux/delay.h>
+#include <linux/seq_file.h>
+#include <linux/root_dev.h>
+
+#include <asm/system.h>
+#include <asm/atomic.h>
+#include <asm/time.h>
+#include <asm/io.h>
+#include <asm/machdep.h>
+#include <asm/ipic.h>
+#include <asm/bootinfo.h>
+#include <asm/irq.h>
+#include <asm/prom.h>
+#include <asm/udbg.h>
+#include <sysdev/fsl_soc.h>
+
+#include "mpc83xx.h"
+
+#include <platforms/83xx/mpc834x_sys.h>
+
+#ifndef CONFIG_PCI
+unsigned long isa_io_base = 0;
+unsigned long isa_mem_base = 0;
+#endif
+
+/* ************************************************************************
+ *
+ * Setup the architecture
+ *
+ */
+static void __init mpc834x_itx_setup_arch(void)
+{
+	struct device_node *np;
+
+	if (ppc_md.progress)
+		ppc_md.progress("mpc834x_itx_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);
+	}
+#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
+}
+
+void __init mpc834x_itx_init_IRQ(void)
+{
+	struct device_node *np;
+
+	np = of_find_node_by_type(NULL, "ipic");
+	if (!np)
+		return;
+
+	ipic_init(np, 0);
+
+	/* Initialize the default interrupt mapping priorities,
+	 * in case the boot rom changed something on us.
+	 */
+	ipic_set_default_priority();
+}
+
+/*
+ * Called very early, MMU is off, device-tree isn't unflattened
+ */
+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;
+}
+
+define_machine(mpc834x_itx) {
+	.name			= "MPC834x ITX",
+	.probe			= mpc834x_itx_probe,
+	.setup_arch		= mpc834x_itx_setup_arch,
+	.init_IRQ		= mpc834x_itx_init_IRQ,
+	.get_irq		= ipic_get_irq,
+	.restart		= mpc83xx_restart,
+	.time_init		= mpc83xx_time_init,
+	.calibrate_decr		= generic_calibrate_decr,
+	.progress		= udbg_progress,
+#ifdef CONFIG_PCI
+	.pcibios_fixup		= mpc83xx_pcibios_fixup,
+#endif
+};
diff --git a/arch/powerpc/platforms/83xx/mpc834x_itx.h b/arch/powerpc/platforms/83xx/mpc834x_itx.h
new file mode 100644
index 000000000..174ca4ef5
--- /dev/null
+++ b/arch/powerpc/platforms/83xx/mpc834x_itx.h
@@ -0,0 +1,23 @@
+/*
+ * arch/powerpc/platforms/83xx/mpc834x_itx.h
+ *
+ * MPC834X ITX common board definitions
+ *
+ * Maintainer: Kumar Gala <galak@kernel.crashing.org>
+ *
+ * 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 __MACH_MPC83XX_ITX_H__
+#define __MACH_MPC83XX_ITX_H__
+
+#define PIRQA	MPC83xx_IRQ_EXT4
+#define PIRQB	MPC83xx_IRQ_EXT5
+#define PIRQC	MPC83xx_IRQ_EXT6
+#define PIRQD	MPC83xx_IRQ_EXT7
+
+#endif				/* __MACH_MPC83XX_ITX_H__ */
diff --git a/arch/powerpc/platforms/85xx/mpc85xx_cds.c b/arch/powerpc/platforms/85xx/mpc85xx_cds.c
new file mode 100644
index 000000000..76b827ca8
--- /dev/null
+++ b/arch/powerpc/platforms/85xx/mpc85xx_cds.c
@@ -0,0 +1,324 @@
+/*
+ * MPC85xx setup and early boot code plus other random bits.
+ *
+ * Maintained by Kumar Gala (see MAINTAINERS for contact information)
+ *
+ * Copyright 2005 Freescale Semiconductor Inc.
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/stddef.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/reboot.h>
+#include <linux/pci.h>
+#include <linux/kdev_t.h>
+#include <linux/major.h>
+#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>
+
+#include <asm/system.h>
+#include <asm/pgtable.h>
+#include <asm/page.h>
+#include <asm/atomic.h>
+#include <asm/time.h>
+#include <asm/io.h>
+#include <asm/machdep.h>
+#include <asm/ipic.h>
+#include <asm/bootinfo.h>
+#include <asm/pci-bridge.h>
+#include <asm/mpc85xx.h>
+#include <asm/irq.h>
+#include <mm/mmu_decl.h>
+#include <asm/prom.h>
+#include <asm/udbg.h>
+#include <asm/mpic.h>
+#include <asm/i8259.h>
+
+#include <sysdev/fsl_soc.h>
+#include "mpc85xx.h"
+
+#ifndef CONFIG_PCI
+unsigned long isa_io_base = 0;
+unsigned long isa_mem_base = 0;
+#endif
+
+static int cds_pci_slot = 2;
+static volatile u8 *cadmus;
+
+
+#ifdef CONFIG_PCI
+
+#define ARCADIA_HOST_BRIDGE_IDSEL	17
+#define ARCADIA_2ND_BRIDGE_IDSEL	3
+
+extern int mpc85xx_pci2_busno;
+
+int
+mpc85xx_exclude_device(u_char bus, u_char devfn)
+{
+	if (bus == 0 && PCI_SLOT(devfn) == 0)
+		return PCIBIOS_DEVICE_NOT_FOUND;
+	if (mpc85xx_pci2_busno)
+		if (bus == (mpc85xx_pci2_busno) && PCI_SLOT(devfn) == 0)
+			return PCIBIOS_DEVICE_NOT_FOUND;
+	/* We explicitly do not go past the Tundra 320 Bridge */
+	if ((bus == 1) && (PCI_SLOT(devfn) == ARCADIA_2ND_BRIDGE_IDSEL))
+		return PCIBIOS_DEVICE_NOT_FOUND;
+	if ((bus == 0) && (PCI_SLOT(devfn) == ARCADIA_2ND_BRIDGE_IDSEL))
+		return PCIBIOS_DEVICE_NOT_FOUND;
+	else
+		return PCIBIOS_SUCCESSFUL;
+}
+
+void __init
+mpc85xx_cds_pcibios_fixup(void)
+{
+	struct pci_dev *dev;
+	u_char		c;
+
+	if ((dev = pci_get_device(PCI_VENDOR_ID_VIA,
+					PCI_DEVICE_ID_VIA_82C586_1, NULL))) {
+		/*
+		 * U-Boot does not set the enable bits
+		 * for the IDE device. Force them on here.
+		 */
+		pci_read_config_byte(dev, 0x40, &c);
+		c |= 0x03; /* IDE: Chip Enable Bits */
+		pci_write_config_byte(dev, 0x40, c);
+
+		/*
+		 * Since only primary interface works, force the
+		 * IDE function to standard primary IDE interrupt
+		 * w/ 8259 offset
+		 */
+		dev->irq = 14;
+		pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq);
+		pci_dev_put(dev);
+	}
+
+	/*
+	 * Force legacy USB interrupt routing
+	 */
+	if ((dev = pci_get_device(PCI_VENDOR_ID_VIA,
+					PCI_DEVICE_ID_VIA_82C586_2, NULL))) {
+		dev->irq = 10;
+		pci_write_config_byte(dev, PCI_INTERRUPT_LINE, 10);
+		pci_dev_put(dev);
+	}
+
+	if ((dev = pci_get_device(PCI_VENDOR_ID_VIA,
+					PCI_DEVICE_ID_VIA_82C586_2, dev))) {
+		dev->irq = 11;
+		pci_write_config_byte(dev, PCI_INTERRUPT_LINE, 11);
+		pci_dev_put(dev);
+	}
+
+	/* Now map all the PCI irqs */
+	dev = NULL;
+	for_each_pci_dev(dev)
+		pci_read_irq_line(dev);
+}
+
+#ifdef CONFIG_PPC_I8259
+#warning The i8259 PIC support is currently broken
+static void mpc85xx_8259_cascade(unsigned int irq, struct
+		irq_desc *desc, struct pt_regs *regs)
+{
+	unsigned int cascade_irq = i8259_irq(regs);
+
+	if (cascade_irq != NO_IRQ)
+		generic_handle_irq(cascade_irq, regs);
+
+	desc->chip->eoi(irq);
+}
+#endif /* PPC_I8259 */
+#endif /* CONFIG_PCI */
+
+void __init mpc85xx_cds_pic_init(void)
+{
+	struct mpic *mpic;
+	struct resource r;
+	struct device_node *np = NULL;
+	struct device_node *cascade_node = NULL;
+	int cascade_irq;
+
+	np = of_find_node_by_type(np, "open-pic");
+
+	if (np == NULL) {
+		printk(KERN_ERR "Could not find open-pic node\n");
+		return;
+	}
+
+	if (of_address_to_resource(np, 0, &r)) {
+		printk(KERN_ERR "Failed to map mpic register space\n");
+		of_node_put(np);
+		return;
+	}
+
+	mpic = mpic_alloc(np, r.start,
+			MPIC_PRIMARY | MPIC_WANTS_RESET | MPIC_BIG_ENDIAN,
+			4, 0, " OpenPIC  ");
+	BUG_ON(mpic == NULL);
+
+	/* Return the mpic node */
+	of_node_put(np);
+
+	mpic_assign_isu(mpic, 0, r.start + 0x10200);
+	mpic_assign_isu(mpic, 1, r.start + 0x10280);
+	mpic_assign_isu(mpic, 2, r.start + 0x10300);
+	mpic_assign_isu(mpic, 3, r.start + 0x10380);
+	mpic_assign_isu(mpic, 4, r.start + 0x10400);
+	mpic_assign_isu(mpic, 5, r.start + 0x10480);
+	mpic_assign_isu(mpic, 6, r.start + 0x10500);
+	mpic_assign_isu(mpic, 7, r.start + 0x10580);
+
+	/* Used only for 8548 so far, but no harm in
+	 * allocating them for everyone */
+	mpic_assign_isu(mpic, 8, r.start + 0x10600);
+	mpic_assign_isu(mpic, 9, r.start + 0x10680);
+	mpic_assign_isu(mpic, 10, r.start + 0x10700);
+	mpic_assign_isu(mpic, 11, r.start + 0x10780);
+
+	/* External Interrupts */
+	mpic_assign_isu(mpic, 12, r.start + 0x10000);
+	mpic_assign_isu(mpic, 13, r.start + 0x10080);
+	mpic_assign_isu(mpic, 14, r.start + 0x10100);
+
+	mpic_init(mpic);
+
+#ifdef CONFIG_PPC_I8259
+	/* Initialize the i8259 controller */
+	for_each_node_by_type(np, "interrupt-controller")
+		if (device_is_compatible(np, "chrp,iic")) {
+			cascade_node = np;
+			break;
+		}
+
+	if (cascade_node == NULL) {
+		printk(KERN_DEBUG "Could not find i8259 PIC\n");
+		return;
+	}
+
+	cascade_irq = irq_of_parse_and_map(cascade_node, 0);
+	if (cascade_irq == NO_IRQ) {
+		printk(KERN_ERR "Failed to map cascade interrupt\n");
+		return;
+	}
+
+	i8259_init(cascade_node, 0);
+	of_node_put(cascade_node);
+
+	set_irq_chained_handler(cascade_irq, mpc85xx_8259_cascade);
+#endif /* CONFIG_PPC_I8259 */
+}
+
+
+/*
+ * Setup the architecture
+ */
+static void __init
+mpc85xx_cds_setup_arch(void)
+{
+	struct device_node *cpu;
+#ifdef CONFIG_PCI
+	struct device_node *np;
+#endif
+
+	if (ppc_md.progress)
+		ppc_md.progress("mpc85xx_cds_setup_arch()", 0);
+
+	cpu = of_find_node_by_type(NULL, "cpu");
+	if (cpu != 0) {
+		unsigned int *fp;
+
+		fp = (int *)get_property(cpu, "clock-frequency", NULL);
+		if (fp != 0)
+			loops_per_jiffy = *fp / HZ;
+		else
+			loops_per_jiffy = 500000000 / HZ;
+		of_node_put(cpu);
+	}
+
+	cadmus = ioremap(CADMUS_BASE, CADMUS_SIZE);
+	cds_pci_slot = ((cadmus[CM_CSR] >> 6) & 0x3) + 1;
+
+	if (ppc_md.progress) {
+		char buf[40];
+		snprintf(buf, 40, "CDS Version = 0x%x in slot %d\n",
+				cadmus[CM_VER], cds_pci_slot);
+		ppc_md.progress(buf, 0);
+	}
+
+#ifdef CONFIG_PCI
+	for (np = NULL; (np = of_find_node_by_type(np, "pci")) != NULL;)
+		add_bridge(np);
+
+	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
+}
+
+
+void
+mpc85xx_cds_show_cpuinfo(struct seq_file *m)
+{
+	uint pvid, svid, phid1;
+	uint memsize = total_memory;
+
+	pvid = mfspr(SPRN_PVR);
+	svid = mfspr(SPRN_SVR);
+
+	seq_printf(m, "Vendor\t\t: Freescale Semiconductor\n");
+	seq_printf(m, "Machine\t\t: MPC85xx CDS (0x%x)\n", cadmus[CM_VER]);
+	seq_printf(m, "PVR\t\t: 0x%x\n", pvid);
+	seq_printf(m, "SVR\t\t: 0x%x\n", svid);
+
+	/* Display cpu Pll setting */
+	phid1 = mfspr(SPRN_HID1);
+	seq_printf(m, "PLL setting\t: 0x%x\n", ((phid1 >> 24) & 0x3f));
+
+	/* Display the amount of memory */
+	seq_printf(m, "Memory\t\t: %d MB\n", memsize / (1024 * 1024));
+}
+
+
+/*
+ * Called very early, device-tree isn't unflattened
+ */
+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;
+}
+
+define_machine(mpc85xx_cds) {
+	.name		= "MPC85xx CDS",
+	.probe		= mpc85xx_cds_probe,
+	.setup_arch	= mpc85xx_cds_setup_arch,
+	.init_IRQ	= mpc85xx_cds_pic_init,
+	.show_cpuinfo	= mpc85xx_cds_show_cpuinfo,
+	.get_irq	= mpic_get_irq,
+	.restart	= mpc85xx_restart,
+	.calibrate_decr = generic_calibrate_decr,
+	.progress	= udbg_progress,
+};
diff --git a/arch/powerpc/platforms/85xx/mpc85xx_cds.h b/arch/powerpc/platforms/85xx/mpc85xx_cds.h
new file mode 100644
index 000000000..671f54ff1
--- /dev/null
+++ b/arch/powerpc/platforms/85xx/mpc85xx_cds.h
@@ -0,0 +1,43 @@
+/*
+ * arch/ppc/platforms/85xx/mpc85xx_cds_common.h
+ *
+ * MPC85xx CDS board definitions
+ *
+ * Maintainer: Kumar Gala <galak@kernel.crashing.org>
+ *
+ * Copyright 2004 Freescale Semiconductor, Inc
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ */
+
+#ifndef __MACH_MPC85XX_CDS_H__
+#define __MACH_MPC85XX_CDS_H__
+
+/* CADMUS info */
+#define CADMUS_BASE (0xf8004000)
+#define CADMUS_SIZE (256)
+#define CM_VER	(0)
+#define CM_CSR	(1)
+#define CM_RST	(2)
+
+/* CDS NVRAM/RTC */
+#define CDS_RTC_ADDR	(0xf8000000)
+#define CDS_RTC_SIZE	(8 * 1024)
+
+/* PCI interrupt controller */
+#define PIRQ0A			MPC85xx_IRQ_EXT0
+#define PIRQ0B			MPC85xx_IRQ_EXT1
+#define PIRQ0C			MPC85xx_IRQ_EXT2
+#define PIRQ0D			MPC85xx_IRQ_EXT3
+#define PIRQ1A			MPC85xx_IRQ_EXT11
+
+#define NR_8259_INTS		16
+#define CPM_IRQ_OFFSET		NR_8259_INTS
+
+#define MPC85xx_OPENPIC_IRQ_OFFSET	80
+
+#endif /* __MACH_MPC85XX_CDS_H__ */
diff --git a/arch/powerpc/platforms/86xx/Kconfig b/arch/powerpc/platforms/86xx/Kconfig
new file mode 100644
index 000000000..d1ecc0f9a
--- /dev/null
+++ b/arch/powerpc/platforms/86xx/Kconfig
@@ -0,0 +1,32 @@
+menu "Platform Support"
+	depends on PPC_86xx
+
+choice
+	prompt "Machine Type"
+	default MPC8641_HPCN
+
+config MPC8641_HPCN
+	bool "Freescale MPC8641 HPCN"
+	select PPC_I8259
+	help
+	  This option enables support for the MPC8641 HPCN board.
+
+endchoice
+
+
+config MPC8641
+	bool
+	select PPC_INDIRECT_PCI
+	select PPC_UDBG_16550
+	default y if MPC8641_HPCN
+
+config MPIC
+	bool
+	default y
+
+config PPC_INDIRECT_PCI_BE
+	bool
+	depends on PPC_86xx
+	default y
+
+endmenu
diff --git a/arch/powerpc/platforms/86xx/Makefile b/arch/powerpc/platforms/86xx/Makefile
new file mode 100644
index 000000000..476a6eeee
--- /dev/null
+++ b/arch/powerpc/platforms/86xx/Makefile
@@ -0,0 +1,7 @@
+#
+# Makefile for the PowerPC 86xx linux kernel.
+#
+
+obj-$(CONFIG_SMP)		+= mpc86xx_smp.o
+obj-$(CONFIG_MPC8641_HPCN)	+= mpc86xx_hpcn.o
+obj-$(CONFIG_PCI)		+= pci.o mpc86xx_pcie.o
diff --git a/arch/powerpc/platforms/86xx/mpc8641_hpcn.h b/arch/powerpc/platforms/86xx/mpc8641_hpcn.h
new file mode 100644
index 000000000..41e554c4a
--- /dev/null
+++ b/arch/powerpc/platforms/86xx/mpc8641_hpcn.h
@@ -0,0 +1,21 @@
+/*
+ * MPC8641 HPCN board definitions
+ *
+ * Copyright 2006 Freescale Semiconductor Inc.
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ * Author: Xianghua Xiao <x.xiao@freescale.com>
+ */
+
+#ifndef __MPC8641_HPCN_H__
+#define __MPC8641_HPCN_H__
+
+#include <linux/init.h>
+
+#define MPC86XX_RSTCR_OFFSET	(0xe00b0)	/* Reset Control Register */
+
+#endif	/* __MPC8641_HPCN_H__ */
diff --git a/arch/powerpc/platforms/86xx/mpc86xx.h b/arch/powerpc/platforms/86xx/mpc86xx.h
new file mode 100644
index 000000000..283446259
--- /dev/null
+++ b/arch/powerpc/platforms/86xx/mpc86xx.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2006 Freescale Semiconductor Inc.
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+#ifndef __MPC86XX_H__
+#define __MPC86XX_H__
+
+/*
+ * Declaration for the various functions exported by the
+ * mpc86xx_* files. Mostly for use by mpc86xx_setup().
+ */
+
+extern int add_bridge(struct device_node *dev);
+
+extern int mpc86xx_exclude_device(u_char bus, u_char devfn);
+
+extern void setup_indirect_pcie(struct pci_controller *hose,
+				       u32 cfg_addr, u32 cfg_data);
+extern void setup_indirect_pcie_nomap(struct pci_controller *hose,
+					     void __iomem *cfg_addr,
+					     void __iomem *cfg_data);
+
+extern void __init mpc86xx_smp_init(void);
+
+#endif	/* __MPC86XX_H__ */
diff --git a/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c b/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c
new file mode 100644
index 000000000..5e583cf38
--- /dev/null
+++ b/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c
@@ -0,0 +1,471 @@
+/*
+ * MPC86xx HPCN board specific routines
+ *
+ * Recode: ZHANG WEI <wei.zhang@freescale.com>
+ * Initial author: Xianghua Xiao <x.xiao@freescale.com>
+ *
+ * Copyright 2006 Freescale Semiconductor Inc.
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/stddef.h>
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#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>
+#include <asm/machdep.h>
+#include <asm/pci-bridge.h>
+#include <asm/mpc86xx.h>
+#include <asm/prom.h>
+#include <mm/mmu_decl.h>
+#include <asm/udbg.h>
+#include <asm/i8259.h>
+
+#include <asm/mpic.h>
+
+#include <sysdev/fsl_soc.h>
+
+#include "mpc86xx.h"
+#include "mpc8641_hpcn.h"
+
+#undef DEBUG
+
+#ifdef DEBUG
+#define DBG(fmt...) do { printk(KERN_ERR fmt); } while(0)
+#else
+#define DBG(fmt...) do { } while(0)
+#endif
+
+#ifndef CONFIG_PCI
+unsigned long isa_io_base = 0;
+unsigned long isa_mem_base = 0;
+unsigned long pci_dram_offset = 0;
+#endif
+
+
+#ifdef CONFIG_PCI
+static void mpc86xx_8259_cascade(unsigned int irq, struct irq_desc *desc,
+				 struct pt_regs *regs)
+{
+	unsigned int cascade_irq = i8259_irq(regs);
+	if (cascade_irq != NO_IRQ)
+		generic_handle_irq(cascade_irq, regs);
+	desc->chip->eoi(irq);
+}
+#endif	/* CONFIG_PCI */
+
+void __init
+mpc86xx_hpcn_init_irq(void)
+{
+	struct mpic *mpic1;
+	struct device_node *np;
+	struct resource res;
+#ifdef CONFIG_PCI
+	struct device_node *cascade_node = NULL;
+	int cascade_irq;
+#endif
+
+	/* Determine PIC address. */
+	np = of_find_node_by_type(NULL, "open-pic");
+	if (np == NULL)
+		return;
+	of_address_to_resource(np, 0, &res);
+
+	/* Alloc mpic structure and per isu has 16 INT entries. */
+	mpic1 = mpic_alloc(np, res.start,
+			MPIC_PRIMARY | MPIC_WANTS_RESET | MPIC_BIG_ENDIAN,
+			16, NR_IRQS - 4,
+			" MPIC     ");
+	BUG_ON(mpic1 == NULL);
+
+	mpic_assign_isu(mpic1, 0, res.start + 0x10000);
+
+	/* 48 Internal Interrupts */
+	mpic_assign_isu(mpic1, 1, res.start + 0x10200);
+	mpic_assign_isu(mpic1, 2, res.start + 0x10400);
+	mpic_assign_isu(mpic1, 3, res.start + 0x10600);
+
+	/* 16 External interrupts
+	 * Moving them from [0 - 15] to [64 - 79]
+	 */
+	mpic_assign_isu(mpic1, 4, res.start + 0x10000);
+
+	mpic_init(mpic1);
+
+#ifdef CONFIG_PCI
+	/* Initialize i8259 controller */
+	for_each_node_by_type(np, "interrupt-controller")
+		if (device_is_compatible(np, "chrp,iic")) {
+			cascade_node = np;
+			break;
+		}
+	if (cascade_node == NULL) {
+		printk(KERN_DEBUG "mpc86xxhpcn: no ISA interrupt controller\n");
+		return;
+	}
+
+	cascade_irq = irq_of_parse_and_map(cascade_node, 0);
+	if (cascade_irq == NO_IRQ) {
+		printk(KERN_ERR "mpc86xxhpcn: failed to map cascade interrupt");
+		return;
+	}
+	DBG("mpc86xxhpcn: cascade mapped to irq %d\n", cascade_irq);
+
+	i8259_init(cascade_node, 0);
+	set_irq_chained_handler(cascade_irq, mpc86xx_8259_cascade);
+#endif
+}
+
+#ifdef CONFIG_PCI
+
+enum pirq{PIRQA = 8, PIRQB, PIRQC, PIRQD, PIRQE, PIRQF, PIRQG, PIRQH};
+const unsigned char uli1575_irq_route_table[16] = {
+	0, 	/* 0: Reserved */
+	0x8, 	/* 1: 0b1000 */
+	0, 	/* 2: Reserved */
+	0x2,	/* 3: 0b0010 */
+	0x4,	/* 4: 0b0100 */
+	0x5, 	/* 5: 0b0101 */
+	0x7,	/* 6: 0b0111 */
+	0x6,	/* 7: 0b0110 */
+	0, 	/* 8: Reserved */
+	0x1,	/* 9: 0b0001 */
+	0x3,	/* 10: 0b0011 */
+	0x9,	/* 11: 0b1001 */
+	0xb,	/* 12: 0b1011 */
+	0, 	/* 13: Reserved */
+	0xd,	/* 14, 0b1101 */
+	0xf,	/* 15, 0b1111 */
+};
+
+static int __devinit
+get_pci_irq_from_of(struct pci_controller *hose, int slot, int pin)
+{
+	struct of_irq oirq;
+	u32 laddr[3];
+	struct device_node *hosenode = hose ? hose->arch_data : NULL;
+
+	if (!hosenode) return -EINVAL;
+
+	laddr[0] = (hose->first_busno << 16) | (PCI_DEVFN(slot, 0) << 8);
+	laddr[1] = laddr[2] = 0;
+	of_irq_map_raw(hosenode, &pin, 1, laddr, &oirq);
+	DBG("mpc86xx_hpcn: pci irq addr %x, slot %d, pin %d, irq %d\n",
+			laddr[0], slot, pin, oirq.specifier[0]);
+	return oirq.specifier[0];
+}
+
+static void __devinit quirk_uli1575(struct pci_dev *dev)
+{
+	unsigned short temp;
+	struct pci_controller *hose = pci_bus_to_host(dev->bus);
+	unsigned char irq2pin[16];
+	unsigned long pirq_map_word = 0;
+	u32 irq;
+	int i;
+
+	/*
+	 * ULI1575 interrupts route setup
+	 */
+	memset(irq2pin, 0, 16); /* Initialize default value 0 */
+
+	/*
+	 * PIRQA -> PIRQD mapping read from OF-tree
+	 *
+	 * interrupts for PCI slot0 -- PIRQA / PIRQB / PIRQC / PIRQD
+	 *                PCI slot1 -- PIRQB / PIRQC / PIRQD / PIRQA
+	 */
+	for (i = 0; i < 4; i++){
+		irq = get_pci_irq_from_of(hose, 17, i + 1);
+		if (irq > 0 && irq < 16)
+			irq2pin[irq] = PIRQA + i;
+		else
+			printk(KERN_WARNING "ULI1575 device"
+			    "(slot %d, pin %d) irq %d is invalid.\n",
+			    17, i, irq);
+	}
+
+	/*
+	 * PIRQE -> PIRQF mapping set manually
+	 *
+	 * IRQ pin   IRQ#
+	 * PIRQE ---- 9
+	 * PIRQF ---- 10
+	 * PIRQG ---- 11
+	 * PIRQH ---- 12
+	 */
+	for (i = 0; i < 4; i++) irq2pin[i + 9] = PIRQE + i;
+
+	/* Set IRQ-PIRQ Mapping to ULI1575 */
+	for (i = 0; i < 16; i++)
+		if (irq2pin[i])
+			pirq_map_word |= (uli1575_irq_route_table[i] & 0xf)
+				<< ((irq2pin[i] - PIRQA) * 4);
+
+	/* ULI1575 IRQ mapping conf register default value is 0xb9317542 */
+	DBG("Setup ULI1575 IRQ mapping configuration register value = 0x%x\n",
+			pirq_map_word);
+	pci_write_config_dword(dev, 0x48, pirq_map_word);
+
+#define ULI1575_SET_DEV_IRQ(slot, pin, reg) 				\
+	do { 								\
+		int irq; 						\
+		irq = get_pci_irq_from_of(hose, slot, pin); 		\
+		if (irq > 0 && irq < 16) 				\
+			pci_write_config_byte(dev, reg, irq2pin[irq]); 	\
+		else							\
+			printk(KERN_WARNING "ULI1575 device"		\
+			    "(slot %d, pin %d) irq %d is invalid.\n",	\
+			    slot, pin, irq);				\
+	} while(0)
+
+	/* USB 1.1 OHCI controller 1, slot 28, pin 1 */
+	ULI1575_SET_DEV_IRQ(28, 1, 0x86);
+
+	/* USB 1.1 OHCI controller 2, slot 28, pin 2 */
+	ULI1575_SET_DEV_IRQ(28, 2, 0x87);
+
+	/* USB 1.1 OHCI controller 3, slot 28, pin 3 */
+	ULI1575_SET_DEV_IRQ(28, 3, 0x88);
+
+	/* USB 2.0 controller, slot 28, pin 4 */
+	irq = get_pci_irq_from_of(hose, 28, 4);
+	if (irq >= 0 && irq <=15)
+		pci_write_config_dword(dev, 0x74, uli1575_irq_route_table[irq]);
+
+	/* Audio controller, slot 29, pin 1 */
+	ULI1575_SET_DEV_IRQ(29, 1, 0x8a);
+
+	/* Modem controller, slot 29, pin 2 */
+	ULI1575_SET_DEV_IRQ(29, 2, 0x8b);
+
+	/* HD audio controller, slot 29, pin 3 */
+	ULI1575_SET_DEV_IRQ(29, 3, 0x8c);
+
+	/* SMB interrupt: slot 30, pin 1 */
+	ULI1575_SET_DEV_IRQ(30, 1, 0x8e);
+
+	/* PMU ACPI SCI interrupt: slot 30, pin 2 */
+	ULI1575_SET_DEV_IRQ(30, 2, 0x8f);
+
+	/* Serial ATA interrupt: slot 31, pin 1 */
+	ULI1575_SET_DEV_IRQ(31, 1, 0x8d);
+
+	/* Primary PATA IDE IRQ: 14
+	 * Secondary PATA IDE IRQ: 15
+	 */
+	pci_write_config_byte(dev, 0x44, 0x30 | uli1575_irq_route_table[14]);
+	pci_write_config_byte(dev, 0x75, uli1575_irq_route_table[15]);
+
+	/* Set IRQ14 and IRQ15 to legacy IRQs */
+	pci_read_config_word(dev, 0x46, &temp);
+	temp |= 0xc000;
+	pci_write_config_word(dev, 0x46, temp);
+
+	/* Set i8259 interrupt trigger
+	 * IRQ 3:  Level
+	 * IRQ 4:  Level
+	 * IRQ 5:  Level
+	 * IRQ 6:  Level
+	 * IRQ 7:  Level
+	 * IRQ 9:  Level
+	 * IRQ 10: Level
+	 * IRQ 11: Level
+	 * IRQ 12: Level
+	 * IRQ 14: Edge
+	 * IRQ 15: Edge
+	 */
+	outb(0xfa, 0x4d0);
+	outb(0x1e, 0x4d1);
+
+#undef ULI1575_SET_DEV_IRQ
+}
+
+static void __devinit quirk_uli5288(struct pci_dev *dev)
+{
+	unsigned char c;
+
+	pci_read_config_byte(dev,0x83,&c);
+	c |= 0x80;
+	pci_write_config_byte(dev, 0x83, c);
+
+	pci_write_config_byte(dev, 0x09, 0x01);
+	pci_write_config_byte(dev, 0x0a, 0x06);
+
+	pci_read_config_byte(dev,0x83,&c);
+	c &= 0x7f;
+	pci_write_config_byte(dev, 0x83, c);
+
+	pci_read_config_byte(dev,0x84,&c);
+	c |= 0x01;
+	pci_write_config_byte(dev, 0x84, c);
+}
+
+static void __devinit quirk_uli5229(struct pci_dev *dev)
+{
+	unsigned short temp;
+	pci_write_config_word(dev, 0x04, 0x0405);
+	pci_read_config_word(dev, 0x4a, &temp);
+	temp |= 0x1000;
+	pci_write_config_word(dev, 0x4a, temp);
+}
+
+static void __devinit early_uli5249(struct pci_dev *dev)
+{
+	unsigned char temp;
+	pci_write_config_word(dev, 0x04, 0x0007);
+	pci_read_config_byte(dev, 0x7c, &temp);
+	pci_write_config_byte(dev, 0x7c, 0x80);
+	pci_write_config_byte(dev, 0x09, 0x01);
+	pci_write_config_byte(dev, 0x7c, temp);
+	dev->class |= 0x1;
+}
+
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AL, 0x1575, quirk_uli1575);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AL, 0x5288, quirk_uli5288);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AL, 0x5229, quirk_uli5229);
+DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_AL, 0x5249, early_uli5249);
+#endif /* CONFIG_PCI */
+
+
+static void __init
+mpc86xx_hpcn_setup_arch(void)
+{
+	struct device_node *np;
+
+	if (ppc_md.progress)
+		ppc_md.progress("mpc86xx_hpcn_setup_arch()", 0);
+
+	np = of_find_node_by_type(NULL, "cpu");
+	if (np != 0) {
+		unsigned int *fp;
+
+		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);
+	}
+
+#ifdef CONFIG_PCI
+	for (np = NULL; (np = of_find_node_by_type(np, "pci")) != NULL;)
+		add_bridge(np);
+
+	ppc_md.pci_exclude_device = mpc86xx_exclude_device;
+#endif
+
+	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
+}
+
+
+void
+mpc86xx_hpcn_show_cpuinfo(struct seq_file *m)
+{
+	struct device_node *root;
+	uint memsize = total_memory;
+	const char *model = "";
+	uint svid = mfspr(SPRN_SVR);
+
+	seq_printf(m, "Vendor\t\t: Freescale Semiconductor\n");
+
+	root = of_find_node_by_path("/");
+	if (root)
+		model = get_property(root, "model", NULL);
+	seq_printf(m, "Machine\t\t: %s\n", model);
+	of_node_put(root);
+
+	seq_printf(m, "SVR\t\t: 0x%x\n", svid);
+	seq_printf(m, "Memory\t\t: %d MB\n", memsize / (1024 * 1024));
+}
+
+
+void __init mpc86xx_hpcn_pcibios_fixup(void)
+{
+	struct pci_dev *dev = NULL;
+
+	for_each_pci_dev(dev)
+		pci_read_irq_line(dev);
+}
+
+
+/*
+ * Called very early, device-tree isn't unflattened
+ */
+static int __init mpc86xx_hpcn_probe(void)
+{
+	unsigned long root = of_get_flat_dt_root();
+
+	if (of_flat_dt_is_compatible(root, "mpc86xx"))
+		return 1;	/* Looks good */
+
+	return 0;
+}
+
+
+void
+mpc86xx_restart(char *cmd)
+{
+	void __iomem *rstcr;
+
+	rstcr = ioremap(get_immrbase() + MPC86XX_RSTCR_OFFSET, 0x100);
+
+	local_irq_disable();
+
+	/* Assert reset request to Reset Control Register */
+	out_be32(rstcr, 0x2);
+
+	/* not reached */
+}
+
+
+long __init
+mpc86xx_time_init(void)
+{
+	unsigned int temp;
+
+	/* Set the time base to zero */
+	mtspr(SPRN_TBWL, 0);
+	mtspr(SPRN_TBWU, 0);
+
+	temp = mfspr(SPRN_HID0);
+	temp |= HID0_TBEN;
+	mtspr(SPRN_HID0, temp);
+	asm volatile("isync");
+
+	return 0;
+}
+
+
+define_machine(mpc86xx_hpcn) {
+	.name			= "MPC86xx HPCN",
+	.probe			= mpc86xx_hpcn_probe,
+	.setup_arch		= mpc86xx_hpcn_setup_arch,
+	.init_IRQ		= mpc86xx_hpcn_init_irq,
+	.show_cpuinfo		= mpc86xx_hpcn_show_cpuinfo,
+	.pcibios_fixup		= mpc86xx_hpcn_pcibios_fixup,
+	.get_irq		= mpic_get_irq,
+	.restart		= mpc86xx_restart,
+	.time_init		= mpc86xx_time_init,
+	.calibrate_decr		= generic_calibrate_decr,
+	.progress		= udbg_progress,
+};
diff --git a/arch/powerpc/platforms/86xx/mpc86xx_pcie.c b/arch/powerpc/platforms/86xx/mpc86xx_pcie.c
new file mode 100644
index 000000000..a2f4f7302
--- /dev/null
+++ b/arch/powerpc/platforms/86xx/mpc86xx_pcie.c
@@ -0,0 +1,173 @@
+/*
+ * Support for indirect PCI bridges.
+ *
+ * Copyright (C) 1998 Gabriel Paubert.
+ *
+ * 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.
+ *
+ * "Temporary" MPC8548 Errata file -
+ * The standard indirect_pci code should work with future silicon versions.
+ */
+
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/delay.h>
+#include <linux/string.h>
+#include <linux/init.h>
+#include <linux/bootmem.h>
+
+#include <asm/io.h>
+#include <asm/prom.h>
+#include <asm/pci-bridge.h>
+#include <asm/machdep.h>
+
+#include "mpc86xx.h"
+
+#define PCI_CFG_OUT out_be32
+
+/* ERRATA PCI-Ex 14 PCIE Controller timeout */
+#define PCIE_FIX		out_be32(hose->cfg_addr+0x4, 0x0400ffff)
+
+
+static int
+indirect_read_config_pcie(struct pci_bus *bus, unsigned int devfn, int offset,
+		     int len, u32 *val)
+{
+	struct pci_controller *hose = bus->sysdata;
+	volatile void __iomem *cfg_data;
+	u32 temp;
+
+	if (ppc_md.pci_exclude_device)
+		if (ppc_md.pci_exclude_device(bus->number, devfn))
+			return PCIBIOS_DEVICE_NOT_FOUND;
+
+	/* Possible artifact of CDCpp50937 needs further investigation */
+	if (devfn != 0x0 && bus->number == 0xff)
+		return PCIBIOS_DEVICE_NOT_FOUND;
+
+	PCIE_FIX;
+	if (bus->number == 0xff) {
+		PCI_CFG_OUT(hose->cfg_addr,
+			    (0x80000000 | ((offset & 0xf00) << 16) |
+			     ((bus->number - hose->bus_offset) << 16)
+			     | (devfn << 8) | ((offset & 0xfc) )));
+	} else {
+		PCI_CFG_OUT(hose->cfg_addr,
+			    (0x80000001 | ((offset & 0xf00) << 16) |
+			     ((bus->number - hose->bus_offset) << 16)
+			     | (devfn << 8) | ((offset & 0xfc) )));
+	}
+
+	/*
+	 * Note: the caller has already checked that offset is
+	 * suitably aligned and that len is 1, 2 or 4.
+	 */
+	/* ERRATA PCI-Ex 12 - Configuration Address/Data Alignment */
+	cfg_data = hose->cfg_data;
+	PCIE_FIX;
+	temp = in_le32(cfg_data);
+	switch (len) {
+	case 1:
+		*val = (temp >> (((offset & 3))*8)) & 0xff;
+		break;
+	case 2:
+		*val = (temp >> (((offset & 3))*8)) & 0xffff;
+		break;
+	default:
+		*val = temp;
+		break;
+	}
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int
+indirect_write_config_pcie(struct pci_bus *bus, unsigned int devfn, int offset,
+		      int len, u32 val)
+{
+	struct pci_controller *hose = bus->sysdata;
+	volatile void __iomem *cfg_data;
+	u32 temp;
+
+	if (ppc_md.pci_exclude_device)
+		if (ppc_md.pci_exclude_device(bus->number, devfn))
+			return PCIBIOS_DEVICE_NOT_FOUND;
+
+	/* Possible artifact of CDCpp50937 needs further investigation */
+	if (devfn != 0x0 && bus->number == 0xff)
+		return PCIBIOS_DEVICE_NOT_FOUND;
+
+	PCIE_FIX;
+	if (bus->number == 0xff) {
+		PCI_CFG_OUT(hose->cfg_addr,
+			    (0x80000000 | ((offset & 0xf00) << 16) |
+			     ((bus->number - hose->bus_offset) << 16)
+			     | (devfn << 8) | ((offset & 0xfc) )));
+	} else {
+		PCI_CFG_OUT(hose->cfg_addr,
+			    (0x80000001 | ((offset & 0xf00) << 16) |
+			     ((bus->number - hose->bus_offset) << 16)
+			     | (devfn << 8) | ((offset & 0xfc) )));
+        }
+
+	/*
+	 * Note: the caller has already checked that offset is
+	 * suitably aligned and that len is 1, 2 or 4.
+	 */
+	/* ERRATA PCI-Ex 12 - Configuration Address/Data Alignment */
+	cfg_data = hose->cfg_data;
+	switch (len) {
+	case 1:
+		PCIE_FIX;
+		temp = in_le32(cfg_data);
+		temp = (temp & ~(0xff << ((offset & 3) * 8))) |
+			(val << ((offset & 3) * 8));
+		PCIE_FIX;
+		out_le32(cfg_data, temp);
+		break;
+	case 2:
+		PCIE_FIX;
+		temp = in_le32(cfg_data);
+		temp = (temp & ~(0xffff << ((offset & 3) * 8)));
+		temp |= (val << ((offset & 3) * 8)) ;
+		PCIE_FIX;
+		out_le32(cfg_data, temp);
+		break;
+	default:
+		PCIE_FIX;
+		out_le32(cfg_data, val);
+		break;
+	}
+	PCIE_FIX;
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static struct pci_ops indirect_pcie_ops = {
+	indirect_read_config_pcie,
+	indirect_write_config_pcie
+};
+
+void __init
+setup_indirect_pcie_nomap(struct pci_controller* hose, void __iomem * cfg_addr,
+	void __iomem * cfg_data)
+{
+	hose->cfg_addr = cfg_addr;
+	hose->cfg_data = cfg_data;
+	hose->ops = &indirect_pcie_ops;
+}
+
+void __init
+setup_indirect_pcie(struct pci_controller* hose, u32 cfg_addr, u32 cfg_data)
+{
+	unsigned long base = cfg_addr & PAGE_MASK;
+	void __iomem *mbase, *addr, *data;
+
+	mbase = ioremap(base, PAGE_SIZE);
+	addr = mbase + (cfg_addr & ~PAGE_MASK);
+	if ((cfg_data & PAGE_MASK) != base)
+		mbase = ioremap(cfg_data & PAGE_MASK, PAGE_SIZE);
+	data = mbase + (cfg_data & ~PAGE_MASK);
+	setup_indirect_pcie_nomap(hose, addr, data);
+}
diff --git a/arch/powerpc/platforms/86xx/mpc86xx_smp.c b/arch/powerpc/platforms/86xx/mpc86xx_smp.c
new file mode 100644
index 000000000..bb7fb4193
--- /dev/null
+++ b/arch/powerpc/platforms/86xx/mpc86xx_smp.c
@@ -0,0 +1,115 @@
+/*
+ * Author: Xianghua Xiao <x.xiao@freescale.com>
+ *         Zhang Wei <wei.zhang@freescale.com>
+ *
+ * Copyright 2006 Freescale Semiconductor Inc.
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/stddef.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+
+#include <asm/pgtable.h>
+#include <asm/page.h>
+#include <asm/pci-bridge.h>
+#include <asm-powerpc/mpic.h>
+#include <asm/mpc86xx.h>
+#include <asm/cacheflush.h>
+
+#include <sysdev/fsl_soc.h>
+
+#include "mpc86xx.h"
+
+extern void __secondary_start_mpc86xx(void);
+extern unsigned long __secondary_hold_acknowledge;
+
+
+static void __init
+smp_86xx_release_core(int nr)
+{
+	__be32 __iomem *mcm_vaddr;
+	unsigned long pcr;
+
+	if (nr < 0 || nr >= NR_CPUS)
+		return;
+
+	/*
+	 * Startup Core #nr.
+	 */
+	mcm_vaddr = ioremap(get_immrbase() + MPC86xx_MCM_OFFSET,
+			    MPC86xx_MCM_SIZE);
+	pcr = in_be32(mcm_vaddr + (MCM_PORT_CONFIG_OFFSET >> 2));
+	pcr |= 1 << (nr + 24);
+	out_be32(mcm_vaddr + (MCM_PORT_CONFIG_OFFSET >> 2), pcr);
+}
+
+
+static void __init
+smp_86xx_kick_cpu(int nr)
+{
+	unsigned int save_vector;
+	unsigned long target, flags;
+	int n = 0;
+	volatile unsigned int *vector
+		 = (volatile unsigned int *)(KERNELBASE + 0x100);
+
+	if (nr < 0 || nr >= NR_CPUS)
+		return;
+
+	pr_debug("smp_86xx_kick_cpu: kick CPU #%d\n", nr);
+
+	local_irq_save(flags);
+	local_irq_disable();
+
+	/* Save reset vector */
+	save_vector = *vector;
+
+	/* Setup fake reset vector to call __secondary_start_mpc86xx. */
+	target = (unsigned long) __secondary_start_mpc86xx;
+	create_branch((unsigned long)vector, target, BRANCH_SET_LINK);
+
+	/* Kick that CPU */
+	smp_86xx_release_core(nr);
+
+	/* Wait a bit for the CPU to take the exception. */
+	while ((__secondary_hold_acknowledge != nr) && (n++, n < 1000))
+		mdelay(1);
+
+	/* Restore the exception vector */
+	*vector = save_vector;
+	flush_icache_range((unsigned long) vector, (unsigned long) vector + 4);
+
+	local_irq_restore(flags);
+
+	pr_debug("wait CPU #%d for %d msecs.\n", nr, n);
+}
+
+
+static void __init
+smp_86xx_setup_cpu(int cpu_nr)
+{
+	mpic_setup_this_cpu();
+}
+
+
+struct smp_ops_t smp_86xx_ops = {
+	.message_pass = smp_mpic_message_pass,
+	.probe = smp_mpic_probe,
+	.kick_cpu = smp_86xx_kick_cpu,
+	.setup_cpu = smp_86xx_setup_cpu,
+	.take_timebase = smp_generic_take_timebase,
+	.give_timebase = smp_generic_give_timebase,
+};
+
+
+void __init
+mpc86xx_smp_init(void)
+{
+	smp_ops = &smp_86xx_ops;
+}
diff --git a/arch/powerpc/platforms/86xx/pci.c b/arch/powerpc/platforms/86xx/pci.c
new file mode 100644
index 000000000..a8c8f0a44
--- /dev/null
+++ b/arch/powerpc/platforms/86xx/pci.c
@@ -0,0 +1,205 @@
+/*
+ * MPC86XX pci setup code
+ *
+ * Recode: ZHANG WEI <wei.zhang@freescale.com>
+ * Initial author: Xianghua Xiao <x.xiao@freescale.com>
+ *
+ * Copyright 2006 Freescale Semiconductor Inc.
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/types.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+#include <linux/serial.h>
+
+#include <asm/system.h>
+#include <asm/atomic.h>
+#include <asm/io.h>
+#include <asm/prom.h>
+#include <asm/immap_86xx.h>
+#include <asm/pci-bridge.h>
+#include <sysdev/fsl_soc.h>
+
+#include "mpc86xx.h"
+
+#undef DEBUG
+
+#ifdef DEBUG
+#define DBG(fmt, args...) printk(KERN_ERR "%s: " fmt, __FUNCTION__, ## args)
+#else
+#define DBG(fmt, args...)
+#endif
+
+struct pcie_outbound_window_regs {
+	uint    pexotar;               /* 0x.0 - PCI Express outbound translation address register */
+	uint    pexotear;              /* 0x.4 - PCI Express outbound translation extended address register */
+	uint    pexowbar;              /* 0x.8 - PCI Express outbound window base address register */
+	char    res1[4];
+	uint    pexowar;               /* 0x.10 - PCI Express outbound window attributes register */
+	char    res2[12];
+};
+
+struct pcie_inbound_window_regs {
+	uint    pexitar;               /* 0x.0 - PCI Express inbound translation address register */
+	char    res1[4];
+	uint    pexiwbar;              /* 0x.8 - PCI Express inbound window base address register */
+	uint    pexiwbear;             /* 0x.c - PCI Express inbound window base extended address register */
+	uint    pexiwar;               /* 0x.10 - PCI Express inbound window attributes register */
+	char    res2[12];
+};
+
+static void __init setup_pcie_atmu(struct pci_controller *hose, struct resource *rsrc)
+{
+	volatile struct ccsr_pex *pcie;
+	volatile struct pcie_outbound_window_regs *pcieow;
+	volatile struct pcie_inbound_window_regs *pcieiw;
+	int i = 0;
+
+	DBG("PCIE memory map start 0x%x, size 0x%x\n", rsrc->start,
+			rsrc->end - rsrc->start + 1);
+	pcie = ioremap(rsrc->start, rsrc->end - rsrc->start + 1);
+
+	/* Disable all windows (except pexowar0 since its ignored) */
+	pcie->pexowar1 = 0;
+	pcie->pexowar2 = 0;
+ 	pcie->pexowar3 = 0;
+ 	pcie->pexowar4 = 0;
+ 	pcie->pexiwar1 = 0;
+ 	pcie->pexiwar2 = 0;
+ 	pcie->pexiwar3 = 0;
+
+ 	pcieow = (struct pcie_outbound_window_regs *)&pcie->pexotar1;
+ 	pcieiw = (struct pcie_inbound_window_regs *)&pcie->pexitar1;
+
+ 	/* Setup outbound MEM window */
+ 	for(i = 0; i < 3; i++)
+ 		if (hose->mem_resources[i].flags & IORESOURCE_MEM){
+ 			DBG("PCIE MEM resource start 0x%08x, size 0x%08x.\n",
+ 				hose->mem_resources[i].start,
+ 				hose->mem_resources[i].end
+ 				  - hose->mem_resources[i].start + 1);
+ 			pcieow->pexotar = (hose->mem_resources[i].start) >> 12
+ 				& 0x000fffff;
+ 			pcieow->pexotear = 0;
+ 			pcieow->pexowbar = (hose->mem_resources[i].start) >> 12
+ 				& 0x000fffff;
+ 			/* Enable, Mem R/W */
+ 			pcieow->pexowar = 0x80044000 |
+ 				(__ilog2(hose->mem_resources[i].end
+ 					 - hose->mem_resources[i].start + 1)
+ 				 - 1);
+ 			pcieow++;
+ 		}
+
+ 	/* Setup outbound IO window */
+ 	if (hose->io_resource.flags & IORESOURCE_IO){
+ 		DBG("PCIE IO resource start 0x%08x, size 0x%08x, phy base 0x%08x.\n",
+ 			hose->io_resource.start,
+ 			hose->io_resource.end - hose->io_resource.start + 1,
+ 			hose->io_base_phys);
+ 		pcieow->pexotar = (hose->io_resource.start) >> 12 & 0x000fffff;
+ 		pcieow->pexotear = 0;
+ 		pcieow->pexowbar = (hose->io_base_phys) >> 12 & 0x000fffff;
+ 		/* Enable, IO R/W */
+ 		pcieow->pexowar = 0x80088000 | (__ilog2(hose->io_resource.end
+ 					- hose->io_resource.start + 1) - 1);
+ 	}
+
+ 	/* Setup 2G inbound Memory Window @ 0 */
+ 	pcieiw->pexitar = 0x00000000;
+ 	pcieiw->pexiwbar = 0x00000000;
+ 	/* Enable, Prefetch, Local Mem, Snoop R/W, 2G */
+ 	pcieiw->pexiwar = 0xa0f5501e;
+}
+
+static void __init
+mpc86xx_setup_pcie(struct pci_controller *hose, u32 pcie_offset, u32 pcie_size)
+{
+	u16 cmd;
+	unsigned int temps;
+
+	DBG("PCIE host controller register offset 0x%08x, size 0x%08x.\n",
+			pcie_offset, pcie_size);
+
+	early_read_config_word(hose, 0, 0, PCI_COMMAND, &cmd);
+	cmd |= PCI_COMMAND_SERR | PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY
+	    | PCI_COMMAND_IO;
+	early_write_config_word(hose, 0, 0, PCI_COMMAND, cmd);
+
+	early_write_config_byte(hose, 0, 0, PCI_LATENCY_TIMER, 0x80);
+
+	/* PCIE Bus, Fix the MPC8641D host bridge's location to bus 0xFF. */
+	early_read_config_dword(hose, 0, 0, PCI_PRIMARY_BUS, &temps);
+	temps = (temps & 0xff000000) | (0xff) | (0x0 << 8) | (0xfe << 16);
+	early_write_config_dword(hose, 0, 0, PCI_PRIMARY_BUS, temps);
+}
+
+int mpc86xx_exclude_device(u_char bus, u_char devfn)
+{
+	if (bus == 0 && PCI_SLOT(devfn) == 0)
+		return PCIBIOS_DEVICE_NOT_FOUND;
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+int __init add_bridge(struct device_node *dev)
+{
+	int len;
+	struct pci_controller *hose;
+	struct resource rsrc;
+	int *bus_range;
+	int has_address = 0;
+	int primary = 0;
+
+	DBG("Adding PCIE host bridge %s\n", dev->full_name);
+
+	/* Fetch host bridge registers address */
+	has_address = (of_address_to_resource(dev, 0, &rsrc) == 0);
+
+	/* Get bus range if any */
+	bus_range = (int *) get_property(dev, "bus-range", &len);
+	if (bus_range == NULL || len < 2 * sizeof(int))
+		printk(KERN_WARNING "Can't get bus-range for %s, assume"
+		       " bus 0\n", dev->full_name);
+
+	hose = pcibios_alloc_controller();
+	if (!hose)
+		return -ENOMEM;
+	hose->arch_data = dev;
+	hose->set_cfg_type = 1;
+
+	/* last_busno = 0xfe cause by MPC8641 PCIE bug */
+	hose->first_busno = bus_range ? bus_range[0] : 0x0;
+	hose->last_busno = bus_range ? bus_range[1] : 0xfe;
+
+	setup_indirect_pcie(hose, rsrc.start, rsrc.start + 0x4);
+
+	/* Setup the PCIE host controller. */
+	mpc86xx_setup_pcie(hose, rsrc.start, rsrc.end - rsrc.start + 1);
+
+	if ((rsrc.start & 0xfffff) == 0x8000)
+		primary = 1;
+
+	printk(KERN_INFO "Found MPC86xx PCIE host bridge at 0x%08lx. "
+	       "Firmware bus number: %d->%d\n",
+	       (unsigned long) rsrc.start,
+	       hose->first_busno, hose->last_busno);
+
+	DBG(" ->Hose at 0x%p, cfg_addr=0x%p,cfg_data=0x%p\n",
+		hose, hose->cfg_addr, hose->cfg_data);
+
+	/* Interpret the "ranges" property */
+	/* This also maps the I/O region and sets isa_io/mem_base */
+	pci_process_bridge_OF_ranges(hose, dev, primary);
+
+	/* Setup PEX window registers */
+	setup_pcie_atmu(hose, &rsrc);
+
+	return 0;
+}
diff --git a/arch/powerpc/platforms/cell/cbe_regs.c b/arch/powerpc/platforms/cell/cbe_regs.c
new file mode 100644
index 000000000..7315f66d1
--- /dev/null
+++ b/arch/powerpc/platforms/cell/cbe_regs.c
@@ -0,0 +1,126 @@
+/*
+ * cbe_regs.c
+ *
+ * Accessor routines for the various MMIO register blocks of the CBE
+ *
+ * (c) 2006 Benjamin Herrenschmidt <benh@kernel.crashing.org>, IBM Corp.
+ */
+
+#include <linux/percpu.h>
+#include <linux/types.h>
+
+#include <asm/io.h>
+#include <asm/pgtable.h>
+#include <asm/prom.h>
+#include <asm/ptrace.h>
+
+#include "cbe_regs.h"
+
+#define MAX_CBE		2
+
+/*
+ * Current implementation uses "cpu" nodes. We build our own mapping
+ * array of cpu numbers to cpu nodes locally for now to allow interrupt
+ * time code to have a fast path rather than call of_get_cpu_node(). If
+ * we implement cpu hotplug, we'll have to install an appropriate norifier
+ * in order to release references to the cpu going away
+ */
+static struct cbe_regs_map
+{
+	struct device_node *cpu_node;
+	struct cbe_pmd_regs __iomem *pmd_regs;
+	struct cbe_iic_regs __iomem *iic_regs;
+} cbe_regs_maps[MAX_CBE];
+static int cbe_regs_map_count;
+
+static struct cbe_thread_map
+{
+	struct device_node *cpu_node;
+	struct cbe_regs_map *regs;
+} cbe_thread_map[NR_CPUS];
+
+static struct cbe_regs_map *cbe_find_map(struct device_node *np)
+{
+	int i;
+
+	for (i = 0; i < cbe_regs_map_count; i++)
+		if (cbe_regs_maps[i].cpu_node == np)
+			return &cbe_regs_maps[i];
+	return NULL;
+}
+
+struct cbe_pmd_regs __iomem *cbe_get_pmd_regs(struct device_node *np)
+{
+	struct cbe_regs_map *map = cbe_find_map(np);
+	if (map == NULL)
+		return NULL;
+	return map->pmd_regs;
+}
+
+struct cbe_pmd_regs __iomem *cbe_get_cpu_pmd_regs(int cpu)
+{
+	struct cbe_regs_map *map = cbe_thread_map[cpu].regs;
+	if (map == NULL)
+		return NULL;
+	return map->pmd_regs;
+}
+
+
+struct cbe_iic_regs __iomem *cbe_get_iic_regs(struct device_node *np)
+{
+	struct cbe_regs_map *map = cbe_find_map(np);
+	if (map == NULL)
+		return NULL;
+	return map->iic_regs;
+}
+struct cbe_iic_regs __iomem *cbe_get_cpu_iic_regs(int cpu)
+{
+	struct cbe_regs_map *map = cbe_thread_map[cpu].regs;
+	if (map == NULL)
+		return NULL;
+	return map->iic_regs;
+}
+
+void __init cbe_regs_init(void)
+{
+	int i;
+	struct device_node *cpu;
+
+	/* Build local fast map of CPUs */
+	for_each_possible_cpu(i)
+		cbe_thread_map[i].cpu_node = of_get_cpu_node(i, NULL);
+
+	/* Find maps for each device tree CPU */
+	for_each_node_by_type(cpu, "cpu") {
+		struct cbe_regs_map *map = &cbe_regs_maps[cbe_regs_map_count++];
+
+		/* That hack must die die die ! */
+		struct address_prop {
+			unsigned long address;
+			unsigned int len;
+		} __attribute__((packed)) *prop;
+
+
+		if (cbe_regs_map_count > MAX_CBE) {
+			printk(KERN_ERR "cbe_regs: More BE chips than supported"
+			       "!\n");
+			cbe_regs_map_count--;
+			return;
+		}
+		map->cpu_node = cpu;
+		for_each_possible_cpu(i)
+			if (cbe_thread_map[i].cpu_node == cpu)
+				cbe_thread_map[i].regs = map;
+
+		prop = (struct address_prop *)get_property(cpu, "pervasive",
+							   NULL);
+		if (prop != NULL)
+			map->pmd_regs = ioremap(prop->address, prop->len);
+
+		prop = (struct address_prop *)get_property(cpu, "iic",
+							   NULL);
+		if (prop != NULL)
+			map->iic_regs = ioremap(prop->address, prop->len);
+	}
+}
+
diff --git a/arch/powerpc/platforms/cell/cbe_regs.h b/arch/powerpc/platforms/cell/cbe_regs.h
new file mode 100644
index 000000000..e76e4a6af
--- /dev/null
+++ b/arch/powerpc/platforms/cell/cbe_regs.h
@@ -0,0 +1,129 @@
+/*
+ * cbe_regs.h
+ *
+ * This file is intended to hold the various register definitions for CBE
+ * on-chip system devices (memory controller, IO controller, etc...)
+ *
+ * (c) 2006 Benjamin Herrenschmidt <benh@kernel.crashing.org>, IBM Corp.
+ */
+
+#ifndef CBE_REGS_H
+#define CBE_REGS_H
+
+/*
+ *
+ * Some HID register definitions
+ *
+ */
+
+/* CBE specific HID0 bits */
+#define HID0_CBE_THERM_WAKEUP	0x0000020000000000ul
+#define HID0_CBE_SYSERR_WAKEUP	0x0000008000000000ul
+#define HID0_CBE_THERM_INT_EN	0x0000000400000000ul
+#define HID0_CBE_SYSERR_INT_EN	0x0000000200000000ul
+
+
+/*
+ *
+ * Pervasive unit register definitions
+ *
+ */
+
+struct cbe_pmd_regs {
+	u8 pad_0x0000_0x0800[0x0800 - 0x0000];			/* 0x0000 */
+
+	/* Thermal Sensor Registers */
+	u64  ts_ctsr1;						/* 0x0800 */
+	u64  ts_ctsr2;						/* 0x0808 */
+	u64  ts_mtsr1;						/* 0x0810 */
+	u64  ts_mtsr2;						/* 0x0818 */
+	u64  ts_itr1;						/* 0x0820 */
+	u64  ts_itr2;						/* 0x0828 */
+	u64  ts_gitr;						/* 0x0830 */
+	u64  ts_isr;						/* 0x0838 */
+	u64  ts_imr;						/* 0x0840 */
+	u64  tm_cr1;						/* 0x0848 */
+	u64  tm_cr2;						/* 0x0850 */
+	u64  tm_simr;						/* 0x0858 */
+	u64  tm_tpr;						/* 0x0860 */
+	u64  tm_str1;						/* 0x0868 */
+	u64  tm_str2;						/* 0x0870 */
+	u64  tm_tsr;						/* 0x0878 */
+
+	/* Power Management */
+	u64  pm_control;					/* 0x0880 */
+#define CBE_PMD_PAUSE_ZERO_CONTROL		0x10000
+	u64  pm_status;						/* 0x0888 */
+
+	/* Time Base Register */
+	u64  tbr;						/* 0x0890 */
+
+	u8   pad_0x0898_0x0c00 [0x0c00 - 0x0898];		/* 0x0898 */
+
+	/* Fault Isolation Registers */
+	u64  checkstop_fir;					/* 0x0c00 */
+	u64  recoverable_fir;
+	u64  spec_att_mchk_fir;
+	u64  fir_mode_reg;
+	u64  fir_enable_mask;
+
+	u8   pad_0x0c28_0x1000 [0x1000 - 0x0c28];		/* 0x0c28 */
+};
+
+extern struct cbe_pmd_regs __iomem *cbe_get_pmd_regs(struct device_node *np);
+extern struct cbe_pmd_regs __iomem *cbe_get_cpu_pmd_regs(int cpu);
+
+/*
+ *
+ * IIC unit register definitions
+ *
+ */
+
+struct cbe_iic_pending_bits {
+	u32 data;
+	u8 flags;
+	u8 class;
+	u8 source;
+	u8 prio;
+};
+
+#define CBE_IIC_IRQ_VALID	0x80
+#define CBE_IIC_IRQ_IPI		0x40
+
+struct cbe_iic_thread_regs {
+	struct cbe_iic_pending_bits pending;
+	struct cbe_iic_pending_bits pending_destr;
+	u64 generate;
+	u64 prio;
+};
+
+struct cbe_iic_regs {
+	u8	pad_0x0000_0x0400[0x0400 - 0x0000];		/* 0x0000 */
+
+	/* IIC interrupt registers */
+	struct	cbe_iic_thread_regs thread[2];			/* 0x0400 */
+	u64     iic_ir;						/* 0x0440 */
+	u64     iic_is;						/* 0x0448 */
+
+	u8	pad_0x0450_0x0500[0x0500 - 0x0450];		/* 0x0450 */
+
+	/* IOC FIR */
+	u64	ioc_fir_reset;					/* 0x0500 */
+	u64	ioc_fir_set;
+	u64	ioc_checkstop_enable;
+	u64	ioc_fir_error_mask;
+	u64	ioc_syserr_enable;
+	u64	ioc_fir;
+
+	u8	pad_0x0530_0x1000[0x1000 - 0x0530];		/* 0x0530 */
+};
+
+extern struct cbe_iic_regs __iomem *cbe_get_iic_regs(struct device_node *np);
+extern struct cbe_iic_regs __iomem *cbe_get_cpu_iic_regs(int cpu);
+
+
+/* Init this module early */
+extern void cbe_regs_init(void);
+
+
+#endif /* CBE_REGS_H */
diff --git a/arch/powerpc/platforms/cell/ras.c b/arch/powerpc/platforms/cell/ras.c
new file mode 100644
index 000000000..0984c7071
--- /dev/null
+++ b/arch/powerpc/platforms/cell/ras.c
@@ -0,0 +1,111 @@
+#define DEBUG
+
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/smp.h>
+
+#include <asm/reg.h>
+#include <asm/io.h>
+#include <asm/prom.h>
+#include <asm/machdep.h>
+
+#include "ras.h"
+#include "cbe_regs.h"
+
+
+static void dump_fir(int cpu)
+{
+	struct cbe_pmd_regs __iomem *pregs = cbe_get_cpu_pmd_regs(cpu);
+	struct cbe_iic_regs __iomem *iregs = cbe_get_cpu_iic_regs(cpu);
+
+	if (pregs == NULL)
+		return;
+
+	/* Todo: do some nicer parsing of bits and based on them go down
+	 * to other sub-units FIRs and not only IIC
+	 */
+	printk(KERN_ERR "Global Checkstop FIR    : 0x%016lx\n",
+	       in_be64(&pregs->checkstop_fir));
+	printk(KERN_ERR "Global Recoverable FIR  : 0x%016lx\n",
+	       in_be64(&pregs->checkstop_fir));
+	printk(KERN_ERR "Global MachineCheck FIR : 0x%016lx\n",
+	       in_be64(&pregs->spec_att_mchk_fir));
+
+	if (iregs == NULL)
+		return;
+	printk(KERN_ERR "IOC FIR                 : 0x%016lx\n",
+	       in_be64(&iregs->ioc_fir));
+
+}
+
+void cbe_system_error_exception(struct pt_regs *regs)
+{
+	int cpu = smp_processor_id();
+
+	printk(KERN_ERR "System Error Interrupt on CPU %d !\n", cpu);
+	dump_fir(cpu);
+	dump_stack();
+}
+
+void cbe_maintenance_exception(struct pt_regs *regs)
+{
+	int cpu = smp_processor_id();
+
+	/*
+	 * Nothing implemented for the maintenance interrupt at this point
+	 */
+
+	printk(KERN_ERR "Unhandled Maintenance interrupt on CPU %d !\n", cpu);
+	dump_stack();
+}
+
+void cbe_thermal_exception(struct pt_regs *regs)
+{
+	int cpu = smp_processor_id();
+
+	/*
+	 * Nothing implemented for the thermal interrupt at this point
+	 */
+
+	printk(KERN_ERR "Unhandled Thermal interrupt on CPU %d !\n", cpu);
+	dump_stack();
+}
+
+static int cbe_machine_check_handler(struct pt_regs *regs)
+{
+	int cpu = smp_processor_id();
+
+	printk(KERN_ERR "Machine Check Interrupt on CPU %d !\n", cpu);
+	dump_fir(cpu);
+
+	/* No recovery from this code now, lets continue */
+	return 0;
+}
+
+void __init cbe_ras_init(void)
+{
+	unsigned long hid0;
+
+	/*
+	 * Enable System Error & thermal interrupts and wakeup conditions
+	 */
+
+	hid0 = mfspr(SPRN_HID0);
+	hid0 |= HID0_CBE_THERM_INT_EN | HID0_CBE_THERM_WAKEUP |
+		HID0_CBE_SYSERR_INT_EN | HID0_CBE_SYSERR_WAKEUP;
+	mtspr(SPRN_HID0, hid0);
+	mb();
+
+	/*
+	 * Install machine check handler. Leave setting of precise mode to
+	 * what the firmware did for now
+	 */
+	ppc_md.machine_check_exception = cbe_machine_check_handler;
+	mb();
+
+	/*
+	 * For now, we assume that IOC_FIR is already set to forward some
+	 * error conditions to the System Error handler. If that is not true
+	 * then it will have to be fixed up here.
+	 */
+}
diff --git a/arch/powerpc/platforms/cell/ras.h b/arch/powerpc/platforms/cell/ras.h
new file mode 100644
index 000000000..eb7ee54c8
--- /dev/null
+++ b/arch/powerpc/platforms/cell/ras.h
@@ -0,0 +1,9 @@
+#ifndef RAS_H
+#define RAS_H
+
+extern void cbe_system_error_exception(struct pt_regs *regs);
+extern void cbe_maintenance_exception(struct pt_regs *regs);
+extern void cbe_thermal_exception(struct pt_regs *regs);
+extern void cbe_ras_init(void);
+
+#endif /* RAS_H */
diff --git a/arch/powerpc/platforms/cell/spu_priv1_mmio.c b/arch/powerpc/platforms/cell/spu_priv1_mmio.c
new file mode 100644
index 000000000..71b69f0a1
--- /dev/null
+++ b/arch/powerpc/platforms/cell/spu_priv1_mmio.c
@@ -0,0 +1,159 @@
+/*
+ * spu hypervisor abstraction for direct hardware access.
+ *
+ *  (C) Copyright IBM Deutschland Entwicklung GmbH 2005
+ *  Copyright 2006 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/module.h>
+
+#include <asm/io.h>
+#include <asm/spu.h>
+#include <asm/spu_priv1.h>
+
+#include "interrupt.h"
+
+static void int_mask_and(struct spu *spu, int class, u64 mask)
+{
+	u64 old_mask;
+
+	old_mask = in_be64(&spu->priv1->int_mask_RW[class]);
+	out_be64(&spu->priv1->int_mask_RW[class], old_mask & mask);
+}
+
+static void int_mask_or(struct spu *spu, int class, u64 mask)
+{
+	u64 old_mask;
+
+	old_mask = in_be64(&spu->priv1->int_mask_RW[class]);
+	out_be64(&spu->priv1->int_mask_RW[class], old_mask | mask);
+}
+
+static void int_mask_set(struct spu *spu, int class, u64 mask)
+{
+	out_be64(&spu->priv1->int_mask_RW[class], mask);
+}
+
+static u64 int_mask_get(struct spu *spu, int class)
+{
+	return in_be64(&spu->priv1->int_mask_RW[class]);
+}
+
+static void int_stat_clear(struct spu *spu, int class, u64 stat)
+{
+	out_be64(&spu->priv1->int_stat_RW[class], stat);
+}
+
+static u64 int_stat_get(struct spu *spu, int class)
+{
+	return in_be64(&spu->priv1->int_stat_RW[class]);
+}
+
+static void cpu_affinity_set(struct spu *spu, int cpu)
+{
+	u64 target = iic_get_target_id(cpu);
+	u64 route = target << 48 | target << 32 | target << 16;
+	out_be64(&spu->priv1->int_route_RW, route);
+}
+
+static u64 mfc_dar_get(struct spu *spu)
+{
+	return in_be64(&spu->priv1->mfc_dar_RW);
+}
+
+static u64 mfc_dsisr_get(struct spu *spu)
+{
+	return in_be64(&spu->priv1->mfc_dsisr_RW);
+}
+
+static void mfc_dsisr_set(struct spu *spu, u64 dsisr)
+{
+	out_be64(&spu->priv1->mfc_dsisr_RW, dsisr);
+}
+
+static void mfc_sdr_set(struct spu *spu, u64 sdr)
+{
+	out_be64(&spu->priv1->mfc_sdr_RW, sdr);
+}
+
+static void mfc_sr1_set(struct spu *spu, u64 sr1)
+{
+	out_be64(&spu->priv1->mfc_sr1_RW, sr1);
+}
+
+static u64 mfc_sr1_get(struct spu *spu)
+{
+	return in_be64(&spu->priv1->mfc_sr1_RW);
+}
+
+static void mfc_tclass_id_set(struct spu *spu, u64 tclass_id)
+{
+	out_be64(&spu->priv1->mfc_tclass_id_RW, tclass_id);
+}
+
+static u64 mfc_tclass_id_get(struct spu *spu)
+{
+	return in_be64(&spu->priv1->mfc_tclass_id_RW);
+}
+
+static void tlb_invalidate(struct spu *spu)
+{
+	out_be64(&spu->priv1->tlb_invalidate_entry_W, 0ul);
+}
+
+static void resource_allocation_groupID_set(struct spu *spu, u64 id)
+{
+	out_be64(&spu->priv1->resource_allocation_groupID_RW, id);
+}
+
+static u64 resource_allocation_groupID_get(struct spu *spu)
+{
+	return in_be64(&spu->priv1->resource_allocation_groupID_RW);
+}
+
+static void resource_allocation_enable_set(struct spu *spu, u64 enable)
+{
+	out_be64(&spu->priv1->resource_allocation_enable_RW, enable);
+}
+
+static u64 resource_allocation_enable_get(struct spu *spu)
+{
+	return in_be64(&spu->priv1->resource_allocation_enable_RW);
+}
+
+const struct spu_priv1_ops spu_priv1_mmio_ops =
+{
+	.int_mask_and = int_mask_and,
+	.int_mask_or = int_mask_or,
+	.int_mask_set = int_mask_set,
+	.int_mask_get = int_mask_get,
+	.int_stat_clear = int_stat_clear,
+	.int_stat_get = int_stat_get,
+	.cpu_affinity_set = cpu_affinity_set,
+	.mfc_dar_get = mfc_dar_get,
+	.mfc_dsisr_get = mfc_dsisr_get,
+	.mfc_dsisr_set = mfc_dsisr_set,
+	.mfc_sdr_set = mfc_sdr_set,
+	.mfc_sr1_set = mfc_sr1_set,
+	.mfc_sr1_get = mfc_sr1_get,
+	.mfc_tclass_id_set = mfc_tclass_id_set,
+	.mfc_tclass_id_get = mfc_tclass_id_get,
+	.tlb_invalidate = tlb_invalidate,
+	.resource_allocation_groupID_set = resource_allocation_groupID_set,
+	.resource_allocation_groupID_get = resource_allocation_groupID_get,
+	.resource_allocation_enable_set = resource_allocation_enable_set,
+	.resource_allocation_enable_get = resource_allocation_enable_get,
+};
diff --git a/arch/powerpc/platforms/embedded6xx/Makefile b/arch/powerpc/platforms/embedded6xx/Makefile
new file mode 100644
index 000000000..fa499fe59
--- /dev/null
+++ b/arch/powerpc/platforms/embedded6xx/Makefile
@@ -0,0 +1,4 @@
+#
+# Makefile for the 6xx/7xx/7xxxx linux kernel.
+#
+obj-$(CONFIG_MPC7448HPC2)	+= mpc7448_hpc2.o
diff --git a/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c b/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c
new file mode 100644
index 000000000..6260bc526
--- /dev/null
+++ b/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c
@@ -0,0 +1,309 @@
+/*
+ * mpc7448_hpc2.c
+ *
+ * Board setup routines for the Freescale mpc7448hpc2(taiga) platform
+ *
+ * Author: Jacob Pan
+ *	 jacob.pan@freescale.com
+ * Author: Xianghua Xiao
+ *       x.xiao@freescale.com
+ * Maintainer: Roy Zang <tie-fei.zang@freescale.com>
+ * 	Add Flat Device Tree support fot mpc7448hpc2 board
+ *
+ * Copyright 2004-2006 Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/stddef.h>
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/kdev_t.h>
+#include <linux/console.h>
+#include <linux/delay.h>
+#include <linux/irq.h>
+#include <linux/ide.h>
+#include <linux/seq_file.h>
+#include <linux/root_dev.h>
+#include <linux/serial.h>
+#include <linux/tty.h>
+#include <linux/serial_core.h>
+
+#include <asm/system.h>
+#include <asm/time.h>
+#include <asm/machdep.h>
+#include <asm/prom.h>
+#include <asm/udbg.h>
+#include <asm/tsi108.h>
+#include <asm/pci-bridge.h>
+#include <asm/reg.h>
+#include <mm/mmu_decl.h>
+#include "mpc7448_hpc2.h"
+#include <asm/tsi108_irq.h>
+#include <asm/mpic.h>
+
+#undef DEBUG
+#ifdef DEBUG
+#define DBG(fmt...) do { printk(fmt); } while(0)
+#else
+#define DBG(fmt...) do { } while(0)
+#endif
+
+#ifndef CONFIG_PCI
+isa_io_base = MPC7448_HPC2_ISA_IO_BASE;
+isa_mem_base = MPC7448_HPC2_ISA_MEM_BASE;
+pci_dram_offset = MPC7448_HPC2_PCI_MEM_OFFSET;
+#endif
+
+extern int tsi108_setup_pci(struct device_node *dev);
+extern void _nmask_and_or_msr(unsigned long nmask, unsigned long or_val);
+extern void tsi108_pci_int_init(void);
+extern void tsi108_irq_cascade(unsigned int irq, struct irq_desc *desc,
+			    struct pt_regs *regs);
+
+int mpc7448_hpc2_exclude_device(u_char bus, u_char devfn)
+{
+	if (bus == 0 && PCI_SLOT(devfn) == 0)
+		return PCIBIOS_DEVICE_NOT_FOUND;
+	else
+		return PCIBIOS_SUCCESSFUL;
+}
+
+/*
+ * find pci slot by devfn in interrupt map of OF tree
+ */
+u8 find_slot_by_devfn(unsigned int *interrupt_map, unsigned int devfn)
+{
+	int i;
+	unsigned int tmp;
+	for (i = 0; i < 4; i++){
+		tmp = interrupt_map[i*4*7];
+		if ((tmp >> 11) == (devfn >> 3))
+			return i;
+	}
+	return i;
+}
+
+/*
+ * Scans the interrupt map for pci device
+ */
+void mpc7448_hpc2_fixup_irq(struct pci_dev *dev)
+{
+	struct pci_controller *hose;
+	struct device_node *node;
+	unsigned int *interrupt;
+	int busnr;
+	int len;
+	u8 slot;
+	u8 pin;
+
+	/* Lookup the hose */
+	busnr = dev->bus->number;
+	hose = pci_bus_to_hose(busnr);
+	if (!hose)
+		printk(KERN_ERR "No pci hose found\n");
+
+	/* Check it has an OF node associated */
+	node = (struct device_node *) hose->arch_data;
+	if (!node)
+		printk(KERN_ERR "No pci node found\n");
+
+	interrupt = (unsigned int *) get_property(node, "interrupt-map", &len);
+	slot = find_slot_by_devfn(interrupt, dev->devfn);
+	pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin);
+	if (pin == 0 || pin > 4)
+		pin = 1;
+	pin--;
+	dev->irq  = interrupt[slot*4*7 + pin*7 + 5];
+	DBG("TSI_PCI: dev->irq = 0x%x\n", dev->irq);
+}
+/* temporary pci irq map fixup*/
+
+void __init mpc7448_hpc2_pcibios_fixup(void)
+{
+	struct pci_dev *dev = NULL;
+	for_each_pci_dev(dev) {
+		mpc7448_hpc2_fixup_irq(dev);
+		pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq);
+	}
+}
+
+static void __init mpc7448_hpc2_setup_arch(void)
+{
+	struct device_node *cpu;
+	struct device_node *np;
+	if (ppc_md.progress)
+		ppc_md.progress("mpc7448_hpc2_setup_arch():set_bridge", 0);
+
+	cpu = of_find_node_by_type(NULL, "cpu");
+	if (cpu != 0) {
+		unsigned int *fp;
+
+		fp = (int *)get_property(cpu, "clock-frequency", NULL);
+		if (fp != 0)
+			loops_per_jiffy = *fp / HZ;
+		else
+			loops_per_jiffy = 50000000 / HZ;
+		of_node_put(cpu);
+	}
+	tsi108_csr_vir_base = get_vir_csrbase();
+
+#ifdef	CONFIG_ROOT_NFS
+	ROOT_DEV = Root_NFS;
+#else
+	ROOT_DEV = Root_HDA1;
+#endif
+
+#ifdef CONFIG_BLK_DEV_INITRD
+	ROOT_DEV = Root_RAM0;
+#endif
+
+	/* setup PCI host bridge */
+#ifdef CONFIG_PCI
+	for (np = NULL; (np = of_find_node_by_type(np, "pci")) != NULL;)
+		tsi108_setup_pci(np);
+
+	ppc_md.pci_exclude_device = mpc7448_hpc2_exclude_device;
+	if (ppc_md.progress)
+		ppc_md.progress("tsi108: resources set", 0x100);
+#endif
+
+	printk(KERN_INFO "MPC7448HPC2 (TAIGA) Platform\n");
+	printk(KERN_INFO
+	       "Jointly ported by Freescale and Tundra Semiconductor\n");
+	printk(KERN_INFO
+	       "Enabling L2 cache then enabling the HID0 prefetch engine.\n");
+}
+
+/*
+ * Interrupt setup and service.  Interrrupts on the mpc7448_hpc2 come
+ * from the four external INT pins, PCI interrupts are routed via
+ * PCI interrupt control registers, it generates internal IRQ23
+ *
+ * Interrupt routing on the Taiga Board:
+ * TSI108:PB_INT[0] -> CPU0:INT#
+ * TSI108:PB_INT[1] -> CPU0:MCP#
+ * TSI108:PB_INT[2] -> N/C
+ * TSI108:PB_INT[3] -> N/C
+ */
+static void __init mpc7448_hpc2_init_IRQ(void)
+{
+	struct mpic *mpic;
+	phys_addr_t mpic_paddr = 0;
+	unsigned int cascade_pci_irq;
+	struct device_node *tsi_pci;
+	struct device_node *tsi_pic;
+
+	tsi_pic = of_find_node_by_type(NULL, "open-pic");
+	if (tsi_pic) {
+		unsigned int size;
+		void *prop = get_property(tsi_pic, "reg", &size);
+		mpic_paddr = of_translate_address(tsi_pic, prop);
+	}
+
+	if (mpic_paddr == 0) {
+		printk("%s: No tsi108 PIC found !\n", __FUNCTION__);
+		return;
+	}
+
+	DBG("%s: tsi108pic phys_addr = 0x%x\n", __FUNCTION__,
+	    (u32) mpic_paddr);
+
+	mpic = mpic_alloc(tsi_pic, mpic_paddr,
+			MPIC_PRIMARY | MPIC_BIG_ENDIAN | MPIC_WANTS_RESET |
+			MPIC_SPV_EOI | MPIC_NO_PTHROU_DIS | MPIC_REGSET_TSI108,
+			0, /* num_sources used */
+			0, /* num_sources used */
+			"Tsi108_PIC");
+
+	BUG_ON(mpic == NULL); /* XXXX */
+	mpic_init(mpic);
+
+	tsi_pci = of_find_node_by_type(NULL, "pci");
+	if (tsi_pci == 0) {
+		printk("%s: No tsi108 pci node found !\n", __FUNCTION__);
+		return;
+	}
+
+	cascade_pci_irq = irq_of_parse_and_map(tsi_pci, 0);
+	set_irq_data(cascade_pci_irq, mpic);
+	set_irq_chained_handler(cascade_pci_irq, tsi108_irq_cascade);
+
+	tsi108_pci_int_init();
+
+	/* Configure MPIC outputs to CPU0 */
+	tsi108_write_reg(TSI108_MPIC_OFFSET + 0x30c, 0);
+	of_node_put(tsi_pic);
+}
+
+void mpc7448_hpc2_show_cpuinfo(struct seq_file *m)
+{
+	seq_printf(m, "vendor\t\t: Freescale Semiconductor\n");
+	seq_printf(m, "machine\t\t: MPC7448hpc2\n");
+}
+
+void mpc7448_hpc2_restart(char *cmd)
+{
+	local_irq_disable();
+
+	/* Set exception prefix high - to the firmware */
+	_nmask_and_or_msr(0, MSR_IP);
+
+	for (;;) ;		/* Spin until reset happens */
+}
+
+void mpc7448_hpc2_power_off(void)
+{
+	local_irq_disable();
+	for (;;) ;		/* No way to shut power off with software */
+}
+
+void mpc7448_hpc2_halt(void)
+{
+	mpc7448_hpc2_power_off();
+}
+
+/*
+ * Called very early, device-tree isn't unflattened
+ */
+static int __init mpc7448_hpc2_probe(void)
+{
+	unsigned long root = of_get_flat_dt_root();
+
+	if (!of_flat_dt_is_compatible(root, "mpc74xx"))
+		return 0;
+	return 1;
+}
+
+static int mpc7448_machine_check_exception(struct pt_regs *regs)
+{
+	extern void tsi108_clear_pci_cfg_error(void);
+	const struct exception_table_entry *entry;
+
+	/* Are we prepared to handle this fault */
+	if ((entry = search_exception_tables(regs->nip)) != NULL) {
+		tsi108_clear_pci_cfg_error();
+		regs->msr |= MSR_RI;
+		regs->nip = entry->fixup;
+		return 1;
+	}
+	return 0;
+
+}
+
+define_machine(mpc7448_hpc2){
+	.name 			= "MPC7448 HPC2",
+	.probe 			= mpc7448_hpc2_probe,
+	.setup_arch 		= mpc7448_hpc2_setup_arch,
+	.init_IRQ 		= mpc7448_hpc2_init_IRQ,
+	.show_cpuinfo 		= mpc7448_hpc2_show_cpuinfo,
+	.get_irq 		= mpic_get_irq,
+	.pcibios_fixup 		= mpc7448_hpc2_pcibios_fixup,
+	.restart 		= mpc7448_hpc2_restart,
+	.calibrate_decr 	= generic_calibrate_decr,
+	.machine_check_exception= mpc7448_machine_check_exception,
+	.progress 		= udbg_progress,
+};
diff --git a/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.h b/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.h
new file mode 100644
index 000000000..a543a5242
--- /dev/null
+++ b/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.h
@@ -0,0 +1,26 @@
+/*
+ * mpc7448_hpc2.h
+ *
+ * Definitions for Freescale MPC7448_HPC2 platform
+ *
+ * Author: Jacob Pan
+ *         jacob.pan@freescale.com
+ * Maintainer: Roy Zang <roy.zang@freescale.com>
+ *
+ * 2006 (c) Freescale Semiconductor, 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 __PPC_PLATFORMS_MPC7448_HPC2_H
+#define __PPC_PLATFORMS_MPC7448_HPC2_H
+
+#include <asm/ppcboot.h>
+
+/* Base Addresses for the PCI bus
+ */
+#define MPC7448_HPC2_PCI_MEM_OFFSET	(0x00000000)
+#define MPC7448_HPC2_ISA_IO_BASE	(0x00000000)
+#define MPC7448_HPC2_ISA_MEM_BASE	(0x00000000)
+#endif				/* __PPC_PLATFORMS_MPC7448_HPC2_H */
diff --git a/arch/powerpc/platforms/iseries/dt.c b/arch/powerpc/platforms/iseries/dt.c
new file mode 100644
index 000000000..d194140c1
--- /dev/null
+++ b/arch/powerpc/platforms/iseries/dt.c
@@ -0,0 +1,617 @@
+/*
+ *    Copyright (c) 2005-2006 Michael Ellerman, IBM Corporation
+ *
+ *    Description:
+ *      This file contains all the routines to build a flattened device
+ *      tree for a legacy iSeries machine.
+ *
+ *      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.
+ */
+
+#undef DEBUG
+
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+#include <linux/pci_regs.h>
+#include <linux/pci_ids.h>
+#include <linux/threads.h>
+#include <linux/bitops.h>
+#include <linux/string.h>
+#include <linux/kernel.h>
+#include <linux/if_ether.h>	/* ETH_ALEN */
+
+#include <asm/machdep.h>
+#include <asm/prom.h>
+#include <asm/lppaca.h>
+#include <asm/cputable.h>
+#include <asm/abs_addr.h>
+#include <asm/system.h>
+#include <asm/iseries/hv_types.h>
+#include <asm/iseries/hv_lp_config.h>
+#include <asm/iseries/hv_call_xm.h>
+#include <asm/iseries/it_exp_vpd_panel.h>
+#include <asm/udbg.h>
+
+#include "processor_vpd.h"
+#include "call_hpt.h"
+#include "call_pci.h"
+#include "pci.h"
+
+#ifdef DEBUG
+#define DBG(fmt...) udbg_printf(fmt)
+#else
+#define DBG(fmt...)
+#endif
+
+/*
+ * These are created by the linker script at the start and end
+ * of the section containing all the strings from this file.
+ */
+extern char __dt_strings_start[];
+extern char __dt_strings_end[];
+
+struct iseries_flat_dt {
+	struct boot_param_header header;
+	u64 reserve_map[2];
+};
+
+static void * __initdata dt_data;
+
+/*
+ * Putting these strings here keeps them out of the section
+ * that we rename to .dt_strings using objcopy and capture
+ * for the strings blob of the flattened device tree.
+ */
+static char __initdata device_type_cpu[] = "cpu";
+static char __initdata device_type_memory[] = "memory";
+static char __initdata device_type_serial[] = "serial";
+static char __initdata device_type_network[] = "network";
+static char __initdata device_type_block[] = "block";
+static char __initdata device_type_byte[] = "byte";
+static char __initdata device_type_pci[] = "pci";
+static char __initdata device_type_vdevice[] = "vdevice";
+static char __initdata device_type_vscsi[] = "vscsi";
+
+static struct iseries_flat_dt * __init dt_init(void)
+{
+	struct iseries_flat_dt *dt;
+	unsigned long str_len;
+
+	str_len = __dt_strings_end - __dt_strings_start;
+	dt = (struct iseries_flat_dt *)ALIGN(klimit, 8);
+	dt->header.off_mem_rsvmap =
+		offsetof(struct iseries_flat_dt, reserve_map);
+	dt->header.off_dt_strings = ALIGN(sizeof(*dt), 8);
+	dt->header.off_dt_struct = dt->header.off_dt_strings
+		+ ALIGN(str_len, 8);
+	dt_data = (void *)((unsigned long)dt + dt->header.off_dt_struct);
+	dt->header.dt_strings_size = str_len;
+
+	/* There is no notion of hardware cpu id on iSeries */
+	dt->header.boot_cpuid_phys = smp_processor_id();
+
+	memcpy((char *)dt + dt->header.off_dt_strings, __dt_strings_start,
+			str_len);
+
+	dt->header.magic = OF_DT_HEADER;
+	dt->header.version = 0x10;
+	dt->header.last_comp_version = 0x10;
+
+	dt->reserve_map[0] = 0;
+	dt->reserve_map[1] = 0;
+
+	return dt;
+}
+
+static void __init dt_push_u32(struct iseries_flat_dt *dt, u32 value)
+{
+	*((u32 *)dt_data) = value;
+	dt_data += sizeof(u32);
+}
+
+#ifdef notyet
+static void __init dt_push_u64(struct iseries_flat_dt *dt, u64 value)
+{
+	*((u64 *)dt_data) = value;
+	dt_data += sizeof(u64);
+}
+#endif
+
+static void __init dt_push_bytes(struct iseries_flat_dt *dt, const char *data,
+		int len)
+{
+	memcpy(dt_data, data, len);
+	dt_data += ALIGN(len, 4);
+}
+
+static void __init dt_start_node(struct iseries_flat_dt *dt, const char *name)
+{
+	dt_push_u32(dt, OF_DT_BEGIN_NODE);
+	dt_push_bytes(dt, name, strlen(name) + 1);
+}
+
+#define dt_end_node(dt) dt_push_u32(dt, OF_DT_END_NODE)
+
+static void __init dt_prop(struct iseries_flat_dt *dt, const char *name,
+		const void *data, int len)
+{
+	unsigned long offset;
+
+	dt_push_u32(dt, OF_DT_PROP);
+
+	/* Length of the data */
+	dt_push_u32(dt, len);
+
+	offset = name - __dt_strings_start;
+
+	/* The offset of the properties name in the string blob. */
+	dt_push_u32(dt, (u32)offset);
+
+	/* The actual data. */
+	dt_push_bytes(dt, data, len);
+}
+
+static void __init dt_prop_str(struct iseries_flat_dt *dt, const char *name,
+		const char *data)
+{
+	dt_prop(dt, name, data, strlen(data) + 1); /* + 1 for NULL */
+}
+
+static void __init dt_prop_u32(struct iseries_flat_dt *dt, const char *name,
+		u32 data)
+{
+	dt_prop(dt, name, &data, sizeof(u32));
+}
+
+#ifdef notyet
+static void __init dt_prop_u64(struct iseries_flat_dt *dt, const char *name,
+		u64 data)
+{
+	dt_prop(dt, name, &data, sizeof(u64));
+}
+#endif
+
+static void __init dt_prop_u64_list(struct iseries_flat_dt *dt,
+		const char *name, u64 *data, int n)
+{
+	dt_prop(dt, name, data, sizeof(u64) * n);
+}
+
+static void __init dt_prop_u32_list(struct iseries_flat_dt *dt,
+		const char *name, u32 *data, int n)
+{
+	dt_prop(dt, name, data, sizeof(u32) * n);
+}
+
+#ifdef notyet
+static void __init dt_prop_empty(struct iseries_flat_dt *dt, const char *name)
+{
+	dt_prop(dt, name, NULL, 0);
+}
+#endif
+
+static void __init dt_cpus(struct iseries_flat_dt *dt)
+{
+	unsigned char buf[32];
+	unsigned char *p;
+	unsigned int i, index;
+	struct IoHriProcessorVpd *d;
+	u32 pft_size[2];
+
+	/* yuck */
+	snprintf(buf, 32, "PowerPC,%s", cur_cpu_spec->cpu_name);
+	p = strchr(buf, ' ');
+	if (!p) p = buf + strlen(buf);
+
+	dt_start_node(dt, "cpus");
+	dt_prop_u32(dt, "#address-cells", 1);
+	dt_prop_u32(dt, "#size-cells", 0);
+
+	pft_size[0] = 0; /* NUMA CEC cookie, 0 for non NUMA  */
+	pft_size[1] = __ilog2(HvCallHpt_getHptPages() * HW_PAGE_SIZE);
+
+	for (i = 0; i < NR_CPUS; i++) {
+		if (lppaca[i].dyn_proc_status >= 2)
+			continue;
+
+		snprintf(p, 32 - (p - buf), "@%d", i);
+		dt_start_node(dt, buf);
+
+		dt_prop_str(dt, "device_type", device_type_cpu);
+
+		index = lppaca[i].dyn_hv_phys_proc_index;
+		d = &xIoHriProcessorVpd[index];
+
+		dt_prop_u32(dt, "i-cache-size", d->xInstCacheSize * 1024);
+		dt_prop_u32(dt, "i-cache-line-size", d->xInstCacheOperandSize);
+
+		dt_prop_u32(dt, "d-cache-size", d->xDataL1CacheSizeKB * 1024);
+		dt_prop_u32(dt, "d-cache-line-size", d->xDataCacheOperandSize);
+
+		/* magic conversions to Hz copied from old code */
+		dt_prop_u32(dt, "clock-frequency",
+			((1UL << 34) * 1000000) / d->xProcFreq);
+		dt_prop_u32(dt, "timebase-frequency",
+			((1UL << 32) * 1000000) / d->xTimeBaseFreq);
+
+		dt_prop_u32(dt, "reg", i);
+
+		dt_prop_u32_list(dt, "ibm,pft-size", pft_size, 2);
+
+		dt_end_node(dt);
+	}
+
+	dt_end_node(dt);
+}
+
+static void __init dt_model(struct iseries_flat_dt *dt)
+{
+	char buf[16] = "IBM,";
+
+	/* N.B. lparcfg.c knows about the "IBM," prefixes ... */
+	/* "IBM," + mfgId[2:3] + systemSerial[1:5] */
+	strne2a(buf + 4, xItExtVpdPanel.mfgID + 2, 2);
+	strne2a(buf + 6, xItExtVpdPanel.systemSerial + 1, 5);
+	buf[11] = '\0';
+	dt_prop_str(dt, "system-id", buf);
+
+	/* "IBM," + machineType[0:4] */
+	strne2a(buf + 4, xItExtVpdPanel.machineType, 4);
+	buf[8] = '\0';
+	dt_prop_str(dt, "model", buf);
+
+	dt_prop_str(dt, "compatible", "IBM,iSeries");
+	dt_prop_u32(dt, "ibm,partition-no", HvLpConfig_getLpIndex());
+}
+
+static void __init dt_do_vdevice(struct iseries_flat_dt *dt,
+		const char *name, u32 reg, int unit,
+		const char *type, const char *compat, int end)
+{
+	char buf[32];
+
+	snprintf(buf, 32, "%s@%08x", name, reg + ((unit >= 0) ? unit : 0));
+	dt_start_node(dt, buf);
+	dt_prop_str(dt, "device_type", type);
+	if (compat)
+		dt_prop_str(dt, "compatible", compat);
+	dt_prop_u32(dt, "reg", reg + ((unit >= 0) ? unit : 0));
+	if (unit >= 0)
+		dt_prop_u32(dt, "linux,unit_address", unit);
+	if (end)
+		dt_end_node(dt);
+}
+
+static void __init dt_vdevices(struct iseries_flat_dt *dt)
+{
+	u32 reg = 0;
+	HvLpIndexMap vlan_map;
+	int i;
+
+	dt_start_node(dt, "vdevice");
+	dt_prop_str(dt, "device_type", device_type_vdevice);
+	dt_prop_str(dt, "compatible", "IBM,iSeries-vdevice");
+	dt_prop_u32(dt, "#address-cells", 1);
+	dt_prop_u32(dt, "#size-cells", 0);
+
+	dt_do_vdevice(dt, "vty", reg, -1, device_type_serial, NULL, 1);
+	reg++;
+
+	dt_do_vdevice(dt, "v-scsi", reg, -1, device_type_vscsi,
+			"IBM,v-scsi", 1);
+	reg++;
+
+	vlan_map = HvLpConfig_getVirtualLanIndexMap();
+	for (i = 0; i < HVMAXARCHITECTEDVIRTUALLANS; i++) {
+		unsigned char mac_addr[ETH_ALEN];
+
+		if ((vlan_map & (0x8000 >> i)) == 0)
+			continue;
+		dt_do_vdevice(dt, "l-lan", reg, i, device_type_network,
+				"IBM,iSeries-l-lan", 0);
+		mac_addr[0] = 0x02;
+		mac_addr[1] = 0x01;
+		mac_addr[2] = 0xff;
+		mac_addr[3] = i;
+		mac_addr[4] = 0xff;
+		mac_addr[5] = HvLpConfig_getLpIndex_outline();
+		dt_prop(dt, "local-mac-address", (char *)mac_addr, ETH_ALEN);
+		dt_prop(dt, "mac-address", (char *)mac_addr, ETH_ALEN);
+		dt_prop_u32(dt, "max-frame-size", 9000);
+		dt_prop_u32(dt, "address-bits", 48);
+
+		dt_end_node(dt);
+	}
+	reg += HVMAXARCHITECTEDVIRTUALLANS;
+
+	for (i = 0; i < HVMAXARCHITECTEDVIRTUALDISKS; i++)
+		dt_do_vdevice(dt, "viodasd", reg, i, device_type_block,
+				"IBM,iSeries-viodasd", 1);
+	reg += HVMAXARCHITECTEDVIRTUALDISKS;
+
+	for (i = 0; i < HVMAXARCHITECTEDVIRTUALCDROMS; i++)
+		dt_do_vdevice(dt, "viocd", reg, i, device_type_block,
+				"IBM,iSeries-viocd", 1);
+	reg += HVMAXARCHITECTEDVIRTUALCDROMS;
+
+	for (i = 0; i < HVMAXARCHITECTEDVIRTUALTAPES; i++)
+		dt_do_vdevice(dt, "viotape", reg, i, device_type_byte,
+				"IBM,iSeries-viotape", 1);
+
+	dt_end_node(dt);
+}
+
+struct pci_class_name {
+	u16 code;
+	const char *name;
+	const char *type;
+};
+
+static struct pci_class_name __initdata pci_class_name[] = {
+	{ PCI_CLASS_NETWORK_ETHERNET, "ethernet", device_type_network },
+};
+
+static struct pci_class_name * __init dt_find_pci_class_name(u16 class_code)
+{
+	struct pci_class_name *cp;
+
+	for (cp = pci_class_name;
+			cp < &pci_class_name[ARRAY_SIZE(pci_class_name)]; cp++)
+		if (cp->code == class_code)
+			return cp;
+	return NULL;
+}
+
+/*
+ * This assumes that the node slot is always on the primary bus!
+ */
+static void __init scan_bridge_slot(struct iseries_flat_dt *dt,
+		HvBusNumber bus, struct HvCallPci_BridgeInfo *bridge_info)
+{
+	HvSubBusNumber sub_bus = bridge_info->subBusNumber;
+	u16 vendor_id;
+	u16 device_id;
+	u32 class_id;
+	int err;
+	char buf[32];
+	u32 reg[5];
+	int id_sel = ISERIES_GET_DEVICE_FROM_SUBBUS(sub_bus);
+	int function = ISERIES_GET_FUNCTION_FROM_SUBBUS(sub_bus);
+	HvAgentId eads_id_sel = ISERIES_PCI_AGENTID(id_sel, function);
+	u8 devfn;
+	struct pci_class_name *cp;
+
+	/*
+	 * Connect all functions of any device found.
+	 */
+	for (id_sel = 1; id_sel <= bridge_info->maxAgents; id_sel++) {
+		for (function = 0; function < 8; function++) {
+			HvAgentId agent_id = ISERIES_PCI_AGENTID(id_sel,
+					function);
+			err = HvCallXm_connectBusUnit(bus, sub_bus,
+					agent_id, 0);
+			if (err) {
+				if (err != 0x302)
+					DBG("connectBusUnit(%x, %x, %x) %x\n",
+						bus, sub_bus, agent_id, err);
+				continue;
+			}
+
+			err = HvCallPci_configLoad16(bus, sub_bus, agent_id,
+					PCI_VENDOR_ID, &vendor_id);
+			if (err) {
+				DBG("ReadVendor(%x, %x, %x) %x\n",
+					bus, sub_bus, agent_id, err);
+				continue;
+			}
+			err = HvCallPci_configLoad16(bus, sub_bus, agent_id,
+					PCI_DEVICE_ID, &device_id);
+			if (err) {
+				DBG("ReadDevice(%x, %x, %x) %x\n",
+					bus, sub_bus, agent_id, err);
+				continue;
+			}
+			err = HvCallPci_configLoad32(bus, sub_bus, agent_id,
+					PCI_CLASS_REVISION , &class_id);
+			if (err) {
+				DBG("ReadClass(%x, %x, %x) %x\n",
+					bus, sub_bus, agent_id, err);
+				continue;
+			}
+
+			devfn = PCI_DEVFN(ISERIES_ENCODE_DEVICE(eads_id_sel),
+					function);
+			cp = dt_find_pci_class_name(class_id >> 16);
+			if (cp && cp->name)
+				strncpy(buf, cp->name, sizeof(buf) - 1);
+			else
+				snprintf(buf, sizeof(buf), "pci%x,%x",
+						vendor_id, device_id);
+			buf[sizeof(buf) - 1] = '\0';
+			snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf),
+					"@%x", PCI_SLOT(devfn));
+			buf[sizeof(buf) - 1] = '\0';
+			if (function != 0)
+				snprintf(buf + strlen(buf),
+					sizeof(buf) - strlen(buf),
+					",%x", function);
+			dt_start_node(dt, buf);
+			reg[0] = (bus << 16) | (devfn << 8);
+			reg[1] = 0;
+			reg[2] = 0;
+			reg[3] = 0;
+			reg[4] = 0;
+			dt_prop_u32_list(dt, "reg", reg, 5);
+			if (cp && (cp->type || cp->name))
+				dt_prop_str(dt, "device_type",
+					cp->type ? cp->type : cp->name);
+			dt_prop_u32(dt, "vendor-id", vendor_id);
+			dt_prop_u32(dt, "device-id", device_id);
+			dt_prop_u32(dt, "class-code", class_id >> 8);
+			dt_prop_u32(dt, "revision-id", class_id & 0xff);
+			dt_prop_u32(dt, "linux,subbus", sub_bus);
+			dt_prop_u32(dt, "linux,agent-id", agent_id);
+			dt_prop_u32(dt, "linux,logical-slot-number",
+					bridge_info->logicalSlotNumber);
+			dt_end_node(dt);
+
+		}
+	}
+}
+
+static void __init scan_bridge(struct iseries_flat_dt *dt, HvBusNumber bus,
+		HvSubBusNumber sub_bus, int id_sel)
+{
+	struct HvCallPci_BridgeInfo bridge_info;
+	HvAgentId agent_id;
+	int function;
+	int ret;
+
+	/* Note: hvSubBus and irq is always be 0 at this level! */
+	for (function = 0; function < 8; ++function) {
+		agent_id = ISERIES_PCI_AGENTID(id_sel, function);
+		ret = HvCallXm_connectBusUnit(bus, sub_bus, agent_id, 0);
+		if (ret != 0) {
+			if (ret != 0xb)
+				DBG("connectBusUnit(%x, %x, %x) %x\n",
+						bus, sub_bus, agent_id, ret);
+			continue;
+		}
+		DBG("found device at bus %d idsel %d func %d (AgentId %x)\n",
+				bus, id_sel, function, agent_id);
+		ret = HvCallPci_getBusUnitInfo(bus, sub_bus, agent_id,
+				iseries_hv_addr(&bridge_info),
+				sizeof(struct HvCallPci_BridgeInfo));
+		if (ret != 0)
+			continue;
+		DBG("bridge info: type %x subbus %x "
+			"maxAgents %x maxsubbus %x logslot %x\n",
+			bridge_info.busUnitInfo.deviceType,
+			bridge_info.subBusNumber,
+			bridge_info.maxAgents,
+			bridge_info.maxSubBusNumber,
+			bridge_info.logicalSlotNumber);
+		if (bridge_info.busUnitInfo.deviceType ==
+				HvCallPci_BridgeDevice)
+			scan_bridge_slot(dt, bus, &bridge_info);
+		else
+			DBG("PCI: Invalid Bridge Configuration(0x%02X)",
+				bridge_info.busUnitInfo.deviceType);
+	}
+}
+
+static void __init scan_phb(struct iseries_flat_dt *dt, HvBusNumber bus)
+{
+	struct HvCallPci_DeviceInfo dev_info;
+	const HvSubBusNumber sub_bus = 0;	/* EADs is always 0. */
+	int err;
+	int id_sel;
+	const int max_agents = 8;
+
+	/*
+	 * Probe for EADs Bridges
+	 */
+	for (id_sel = 1; id_sel < max_agents; ++id_sel) {
+		err = HvCallPci_getDeviceInfo(bus, sub_bus, id_sel,
+				iseries_hv_addr(&dev_info),
+				sizeof(struct HvCallPci_DeviceInfo));
+		if (err) {
+			if (err != 0x302)
+				DBG("getDeviceInfo(%x, %x, %x) %x\n",
+						bus, sub_bus, id_sel, err);
+			continue;
+		}
+		if (dev_info.deviceType != HvCallPci_NodeDevice) {
+			DBG("PCI: Invalid System Configuration"
+					"(0x%02X) for bus 0x%02x id 0x%02x.\n",
+					dev_info.deviceType, bus, id_sel);
+			continue;
+		}
+		scan_bridge(dt, bus, sub_bus, id_sel);
+	}
+}
+
+static void __init dt_pci_devices(struct iseries_flat_dt *dt)
+{
+	HvBusNumber bus;
+	char buf[32];
+	u32 buses[2];
+	int phb_num = 0;
+
+	/* Check all possible buses. */
+	for (bus = 0; bus < 256; bus++) {
+		int err = HvCallXm_testBus(bus);
+
+		if (err) {
+			/*
+			 * Check for Unexpected Return code, a clue that
+			 * something has gone wrong.
+			 */
+			if (err != 0x0301)
+				DBG("Unexpected Return on Probe(0x%02X) "
+						"0x%04X\n", bus, err);
+			continue;
+		}
+		DBG("bus %d appears to exist\n", bus);
+		snprintf(buf, 32, "pci@%d", phb_num);
+		dt_start_node(dt, buf);
+		dt_prop_str(dt, "device_type", device_type_pci);
+		dt_prop_str(dt, "compatible", "IBM,iSeries-Logical-PHB");
+		dt_prop_u32(dt, "#address-cells", 3);
+		dt_prop_u32(dt, "#size-cells", 2);
+		buses[0] = buses[1] = bus;
+		dt_prop_u32_list(dt, "bus-range", buses, 2);
+		scan_phb(dt, bus);
+		dt_end_node(dt);
+		phb_num++;
+	}
+}
+
+static void dt_finish(struct iseries_flat_dt *dt)
+{
+	dt_push_u32(dt, OF_DT_END);
+	dt->header.totalsize = (unsigned long)dt_data - (unsigned long)dt;
+	klimit = ALIGN((unsigned long)dt_data, 8);
+}
+
+void * __init build_flat_dt(unsigned long phys_mem_size)
+{
+	struct iseries_flat_dt *iseries_dt;
+	u64 tmp[2];
+
+	iseries_dt = dt_init();
+
+	dt_start_node(iseries_dt, "");
+
+	dt_prop_u32(iseries_dt, "#address-cells", 2);
+	dt_prop_u32(iseries_dt, "#size-cells", 2);
+	dt_model(iseries_dt);
+
+	/* /memory */
+	dt_start_node(iseries_dt, "memory@0");
+	dt_prop_str(iseries_dt, "device_type", device_type_memory);
+	tmp[0] = 0;
+	tmp[1] = phys_mem_size;
+	dt_prop_u64_list(iseries_dt, "reg", tmp, 2);
+	dt_end_node(iseries_dt);
+
+	/* /chosen */
+	dt_start_node(iseries_dt, "chosen");
+	dt_prop_str(iseries_dt, "bootargs", cmd_line);
+	dt_end_node(iseries_dt);
+
+	dt_cpus(iseries_dt);
+
+	dt_vdevices(iseries_dt);
+	dt_pci_devices(iseries_dt);
+
+	dt_end_node(iseries_dt);
+
+	dt_finish(iseries_dt);
+
+	return iseries_dt;
+}
diff --git a/arch/powerpc/sysdev/todc.c b/arch/powerpc/sysdev/todc.c
new file mode 100644
index 000000000..0a65980ef
--- /dev/null
+++ b/arch/powerpc/sysdev/todc.c
@@ -0,0 +1,392 @@
+/*
+ * Time of Day Clock support for the M48T35, M48T37, M48T59, and MC146818
+ * Real Time Clocks/Timekeepers.
+ *
+ * Author: Mark A. Greer <mgreer@mvista.com>
+ *
+ * 2001-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.
+ */
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/time.h>
+#include <linux/timex.h>
+#include <linux/bcd.h>
+#include <linux/mc146818rtc.h>
+
+#include <asm/machdep.h>
+#include <asm/io.h>
+#include <asm/time.h>
+#include <asm/todc.h>
+
+/*
+ * Depending on the hardware on your board and your board design, the
+ * RTC/NVRAM may be accessed either directly (like normal memory) or via
+ * address/data registers.  If your board uses the direct method, set
+ * 'nvram_data' to the base address of your nvram and leave 'nvram_as0' and
+ * 'nvram_as1' NULL.  If your board uses address/data regs to access nvram,
+ * set 'nvram_as0' to the address of the lower byte, set 'nvram_as1' to the
+ * address of the upper byte (leave NULL if using mc146818), and set
+ * 'nvram_data' to the address of the 8-bit data register.
+ *
+ * Note: Even though the documentation for the various RTC chips say that it
+ * 	 take up to a second before it starts updating once the 'R' bit is
+ * 	 cleared, they always seem to update even though we bang on it many
+ * 	 times a second.  This is true, except for the Dallas Semi 1746/1747
+ * 	 (possibly others).  Those chips seem to have a real problem whenever
+ * 	 we set the 'R' bit before reading them, they basically stop counting.
+ * 	 					--MAG
+ */
+
+/*
+ * 'todc_info' should be initialized in your *_setup.c file to
+ * point to a fully initialized 'todc_info_t' structure.
+ * This structure holds all the register offsets for your particular
+ * TODC/RTC chip.
+ * TODC_ALLOC()/TODC_INIT() will allocate and initialize this table for you.
+ */
+
+#ifdef	RTC_FREQ_SELECT
+#undef	RTC_FREQ_SELECT
+#define	RTC_FREQ_SELECT		control_b	/* Register A */
+#endif
+
+#ifdef	RTC_CONTROL
+#undef	RTC_CONTROL
+#define	RTC_CONTROL		control_a	/* Register B */
+#endif
+
+#ifdef	RTC_INTR_FLAGS
+#undef	RTC_INTR_FLAGS
+#define	RTC_INTR_FLAGS		watchdog	/* Register C */
+#endif
+
+#ifdef	RTC_VALID
+#undef	RTC_VALID
+#define	RTC_VALID		interrupts	/* Register D */
+#endif
+
+/* Access routines when RTC accessed directly (like normal memory) */
+u_char
+todc_direct_read_val(int addr)
+{
+	return readb((void __iomem *)(todc_info->nvram_data + addr));
+}
+
+void
+todc_direct_write_val(int addr, unsigned char val)
+{
+	writeb(val, (void __iomem *)(todc_info->nvram_data + addr));
+	return;
+}
+
+/* Access routines for accessing m48txx type chips via addr/data regs */
+u_char
+todc_m48txx_read_val(int addr)
+{
+	outb(addr, todc_info->nvram_as0);
+	outb(addr>>todc_info->as0_bits, todc_info->nvram_as1);
+	return inb(todc_info->nvram_data);
+}
+
+void
+todc_m48txx_write_val(int addr, unsigned char val)
+{
+	outb(addr, todc_info->nvram_as0);
+	outb(addr>>todc_info->as0_bits, todc_info->nvram_as1);
+	outb(val, todc_info->nvram_data);
+	return;
+}
+
+/* Access routines for accessing mc146818 type chips via addr/data regs */
+u_char
+todc_mc146818_read_val(int addr)
+{
+	outb_p(addr, todc_info->nvram_as0);
+	return inb_p(todc_info->nvram_data);
+}
+
+void
+todc_mc146818_write_val(int addr, unsigned char val)
+{
+	outb_p(addr, todc_info->nvram_as0);
+	outb_p(val, todc_info->nvram_data);
+}
+
+
+/*
+ * Routines to make RTC chips with NVRAM buried behind an addr/data pair
+ * have the NVRAM and clock regs appear at the same level.
+ * The NVRAM will appear to start at addr 0 and the clock regs will appear
+ * to start immediately after the NVRAM (actually, start at offset
+ * todc_info->nvram_size).
+ */
+static inline u_char
+todc_read_val(int addr)
+{
+	u_char	val;
+
+	if (todc_info->sw_flags & TODC_FLAG_2_LEVEL_NVRAM) {
+		if (addr < todc_info->nvram_size) { /* NVRAM */
+			ppc_md.rtc_write_val(todc_info->nvram_addr_reg, addr);
+			val = ppc_md.rtc_read_val(todc_info->nvram_data_reg);
+		} else { /* Clock Reg */
+			addr -= todc_info->nvram_size;
+			val = ppc_md.rtc_read_val(addr);
+		}
+	} else
+		val = ppc_md.rtc_read_val(addr);
+
+	return val;
+}
+
+static inline void
+todc_write_val(int addr, u_char val)
+{
+	if (todc_info->sw_flags & TODC_FLAG_2_LEVEL_NVRAM) {
+		if (addr < todc_info->nvram_size) { /* NVRAM */
+			ppc_md.rtc_write_val(todc_info->nvram_addr_reg, addr);
+			ppc_md.rtc_write_val(todc_info->nvram_data_reg, val);
+		} else { /* Clock Reg */
+			addr -= todc_info->nvram_size;
+			ppc_md.rtc_write_val(addr, val);
+		}
+	} else
+		ppc_md.rtc_write_val(addr, val);
+}
+
+/*
+ * TODC routines
+ *
+ * There is some ugly stuff in that there are assumptions for the mc146818.
+ *
+ * Assumptions:
+ *	- todc_info->control_a has the offset as mc146818 Register B reg
+ *	- todc_info->control_b has the offset as mc146818 Register A reg
+ *	- m48txx control reg's write enable or 'W' bit is same as
+ *	  mc146818 Register B 'SET' bit (i.e., 0x80)
+ *
+ * These assumptions were made to make the code simpler.
+ */
+long __init
+todc_time_init(void)
+{
+	u_char	cntl_b;
+
+	if (!ppc_md.rtc_read_val)
+		ppc_md.rtc_read_val = ppc_md.nvram_read_val;
+	if (!ppc_md.rtc_write_val)
+		ppc_md.rtc_write_val = ppc_md.nvram_write_val;
+
+	cntl_b = todc_read_val(todc_info->control_b);
+
+	if (todc_info->rtc_type == TODC_TYPE_MC146818) {
+		if ((cntl_b & 0x70) != 0x20) {
+			printk(KERN_INFO "TODC real-time-clock was stopped."
+				"  Now starting...");
+			cntl_b &= ~0x70;
+			cntl_b |= 0x20;
+		}
+
+		todc_write_val(todc_info->control_b, cntl_b);
+	} else if (todc_info->rtc_type == TODC_TYPE_DS17285) {
+		u_char mode;
+
+		mode = todc_read_val(TODC_TYPE_DS17285_CNTL_A);
+		/* Make sure countdown clear is not set */
+		mode &= ~0x40;
+		/* Enable oscillator, extended register set */
+		mode |= 0x30;
+		todc_write_val(TODC_TYPE_DS17285_CNTL_A, mode);
+
+	} else if (todc_info->rtc_type == TODC_TYPE_DS1501) {
+		u_char	month;
+
+		todc_info->enable_read = TODC_DS1501_CNTL_B_TE;
+		todc_info->enable_write = TODC_DS1501_CNTL_B_TE;
+
+		month = todc_read_val(todc_info->month);
+
+		if ((month & 0x80) == 0x80) {
+			printk(KERN_INFO "TODC %s %s\n",
+				"real-time-clock was stopped.",
+				"Now starting...");
+			month &= ~0x80;
+			todc_write_val(todc_info->month, month);
+		}
+
+		cntl_b &= ~TODC_DS1501_CNTL_B_TE;
+		todc_write_val(todc_info->control_b, cntl_b);
+	} else { /* must be a m48txx type */
+		u_char	cntl_a;
+
+		todc_info->enable_read = TODC_MK48TXX_CNTL_A_R;
+		todc_info->enable_write = TODC_MK48TXX_CNTL_A_W;
+
+		cntl_a = todc_read_val(todc_info->control_a);
+
+		/* Check & clear STOP bit in control B register */
+		if (cntl_b & TODC_MK48TXX_DAY_CB) {
+			printk(KERN_INFO "TODC %s %s\n",
+				"real-time-clock was stopped.",
+				"Now starting...");
+
+			cntl_a |= todc_info->enable_write;
+			cntl_b &= ~TODC_MK48TXX_DAY_CB;/* Start Oscil */
+
+			todc_write_val(todc_info->control_a, cntl_a);
+			todc_write_val(todc_info->control_b, cntl_b);
+		}
+
+		/* Make sure READ & WRITE bits are cleared. */
+		cntl_a &= ~(todc_info->enable_write | todc_info->enable_read);
+		todc_write_val(todc_info->control_a, cntl_a);
+	}
+
+	return 0;
+}
+
+/*
+ * There is some ugly stuff in that there are assumptions that for a mc146818,
+ * the todc_info->control_a has the offset of the mc146818 Register B reg and
+ * that the register'ss 'SET' bit is the same as the m48txx's write enable
+ * bit in the control register of the m48txx (i.e., 0x80).
+ *
+ * It was done to make the code look simpler.
+ */
+void
+todc_get_rtc_time(struct rtc_time *tm)
+{
+	uint	year = 0, mon = 0, mday = 0, hour = 0, min = 0, sec = 0;
+	uint	limit, i;
+	u_char	save_control, uip = 0;
+	extern void GregorianDay(struct rtc_time *);
+
+	spin_lock(&rtc_lock);
+	save_control = todc_read_val(todc_info->control_a);
+
+	if (todc_info->rtc_type != TODC_TYPE_MC146818) {
+		limit = 1;
+
+		switch (todc_info->rtc_type) {
+		case TODC_TYPE_DS1553:
+		case TODC_TYPE_DS1557:
+		case TODC_TYPE_DS1743:
+		case TODC_TYPE_DS1746:	/* XXXX BAD HACK -> FIX */
+		case TODC_TYPE_DS1747:
+		case TODC_TYPE_DS17285:
+			break;
+		default:
+			todc_write_val(todc_info->control_a,
+				(save_control | todc_info->enable_read));
+		}
+	} else
+		limit = 100000000;
+
+	for (i=0; i<limit; i++) {
+		if (todc_info->rtc_type == TODC_TYPE_MC146818)
+			uip = todc_read_val(todc_info->RTC_FREQ_SELECT);
+
+		sec = todc_read_val(todc_info->seconds) & 0x7f;
+		min = todc_read_val(todc_info->minutes) & 0x7f;
+		hour = todc_read_val(todc_info->hours) & 0x3f;
+		mday = todc_read_val(todc_info->day_of_month) & 0x3f;
+		mon = todc_read_val(todc_info->month) & 0x1f;
+		year = todc_read_val(todc_info->year) & 0xff;
+
+		if (todc_info->rtc_type == TODC_TYPE_MC146818) {
+			uip |= todc_read_val(todc_info->RTC_FREQ_SELECT);
+			if ((uip & RTC_UIP) == 0)
+				break;
+		}
+	}
+
+	if (todc_info->rtc_type != TODC_TYPE_MC146818) {
+		switch (todc_info->rtc_type) {
+		case TODC_TYPE_DS1553:
+		case TODC_TYPE_DS1557:
+		case TODC_TYPE_DS1743:
+		case TODC_TYPE_DS1746:	/* XXXX BAD HACK -> FIX */
+		case TODC_TYPE_DS1747:
+		case TODC_TYPE_DS17285:
+			break;
+		default:
+			save_control &= ~(todc_info->enable_read);
+			todc_write_val(todc_info->control_a, save_control);
+		}
+	}
+	spin_unlock(&rtc_lock);
+
+	if ((todc_info->rtc_type != TODC_TYPE_MC146818)
+			|| ((save_control & RTC_DM_BINARY) == 0)
+			|| RTC_ALWAYS_BCD) {
+		BCD_TO_BIN(sec);
+		BCD_TO_BIN(min);
+		BCD_TO_BIN(hour);
+		BCD_TO_BIN(mday);
+		BCD_TO_BIN(mon);
+		BCD_TO_BIN(year);
+	}
+
+	if ((year + 1900) < 1970) {
+		year += 100;
+	}
+
+	tm->tm_sec = sec;
+	tm->tm_min = min;
+	tm->tm_hour = hour;
+	tm->tm_mday = mday;
+	tm->tm_mon = mon;
+	tm->tm_year = year;
+
+	GregorianDay(tm);
+}
+
+int
+todc_set_rtc_time(struct rtc_time *tm)
+{
+	u_char save_control, save_freq_select = 0;
+
+	spin_lock(&rtc_lock);
+	save_control = todc_read_val(todc_info->control_a);
+
+	/* Assuming MK48T59_RTC_CA_WRITE & RTC_SET are equal */
+	todc_write_val(todc_info->control_a,
+		(save_control | todc_info->enable_write));
+	save_control &= ~(todc_info->enable_write); /* in case it was set */
+
+	if (todc_info->rtc_type == TODC_TYPE_MC146818) {
+		save_freq_select = todc_read_val(todc_info->RTC_FREQ_SELECT);
+		todc_write_val(todc_info->RTC_FREQ_SELECT,
+			save_freq_select | RTC_DIV_RESET2);
+	}
+
+	if ((todc_info->rtc_type != TODC_TYPE_MC146818)
+			|| ((save_control & RTC_DM_BINARY) == 0)
+			|| RTC_ALWAYS_BCD) {
+		BIN_TO_BCD(tm->tm_sec);
+		BIN_TO_BCD(tm->tm_min);
+		BIN_TO_BCD(tm->tm_hour);
+		BIN_TO_BCD(tm->tm_mon);
+		BIN_TO_BCD(tm->tm_mday);
+		BIN_TO_BCD(tm->tm_year);
+	}
+
+	todc_write_val(todc_info->seconds, tm->tm_sec);
+	todc_write_val(todc_info->minutes, tm->tm_min);
+	todc_write_val(todc_info->hours, tm->tm_hour);
+	todc_write_val(todc_info->month, tm->tm_mon);
+	todc_write_val(todc_info->day_of_month, tm->tm_mday);
+	todc_write_val(todc_info->year, tm->tm_year);
+
+	todc_write_val(todc_info->control_a, save_control);
+
+	if (todc_info->rtc_type == TODC_TYPE_MC146818)
+		todc_write_val(todc_info->RTC_FREQ_SELECT, save_freq_select);
+
+	spin_unlock(&rtc_lock);
+	return 0;
+}
diff --git a/arch/powerpc/sysdev/tsi108_dev.c b/arch/powerpc/sysdev/tsi108_dev.c
new file mode 100644
index 000000000..11de090eb
--- /dev/null
+++ b/arch/powerpc/sysdev/tsi108_dev.c
@@ -0,0 +1,146 @@
+/*
+ * tsi108/109 device setup code
+ *
+ * Maintained by Roy Zang < tie-fei.zang@freescale.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.
+ */
+
+#include <linux/stddef.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/major.h>
+#include <linux/delay.h>
+#include <linux/irq.h>
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <asm/tsi108.h>
+
+#include <asm/system.h>
+#include <asm/atomic.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/prom.h>
+#include <mm/mmu_decl.h>
+
+#undef DEBUG
+
+#ifdef DEBUG
+#define DBG(fmt...) do { printk(fmt); } while(0)
+#else
+#define DBG(fmt...) do { } while(0)
+#endif
+
+static phys_addr_t tsi108_csr_base = -1;
+
+phys_addr_t get_csrbase(void)
+{
+	struct device_node *tsi;
+
+	if (tsi108_csr_base != -1)
+		return tsi108_csr_base;
+
+	tsi = of_find_node_by_type(NULL, "tsi-bridge");
+	if (tsi) {
+		unsigned int size;
+		void *prop = get_property(tsi, "reg", &size);
+		tsi108_csr_base = of_translate_address(tsi, prop);
+		of_node_put(tsi);
+	};
+	return tsi108_csr_base;
+}
+
+u32 get_vir_csrbase(void)
+{
+	return (u32) (ioremap(get_csrbase(), 0x10000));
+}
+
+EXPORT_SYMBOL(get_csrbase);
+EXPORT_SYMBOL(get_vir_csrbase);
+
+static int __init tsi108_eth_of_init(void)
+{
+	struct device_node *np;
+	unsigned int i;
+	struct platform_device *tsi_eth_dev;
+	struct resource res;
+	int ret;
+
+	for (np = NULL, i = 0;
+	     (np = of_find_compatible_node(np, "network", "tsi-ethernet")) != NULL;
+	     i++) {
+		struct resource r[2];
+		struct device_node *phy;
+		hw_info tsi_eth_data;
+		unsigned int *id;
+		unsigned int *phy_id;
+		void *mac_addr;
+		phandle *ph;
+
+		memset(r, 0, sizeof(r));
+		memset(&tsi_eth_data, 0, sizeof(tsi_eth_data));
+
+		ret = of_address_to_resource(np, 0, &r[0]);
+		DBG("%s: name:start->end = %s:0x%lx-> 0x%lx\n",
+			__FUNCTION__,r[0].name, r[0].start, r[0].end);
+		if (ret)
+			goto err;
+
+		r[1].name = "tx";
+		r[1].start = irq_of_parse_and_map(np, 0);
+		r[1].end = irq_of_parse_and_map(np, 0);
+		r[1].flags = IORESOURCE_IRQ;
+		DBG("%s: name:start->end = %s:0x%lx-> 0x%lx\n",
+			__FUNCTION__,r[1].name, r[1].start, r[1].end);
+
+		tsi_eth_dev =
+		    platform_device_register_simple("tsi-ethernet", i, &r[0],
+						    1);
+
+		if (IS_ERR(tsi_eth_dev)) {
+			ret = PTR_ERR(tsi_eth_dev);
+			goto err;
+		}
+
+		mac_addr = get_property(np, "address", NULL);
+		memcpy(tsi_eth_data.mac_addr, mac_addr, 6);
+
+		ph = (phandle *) get_property(np, "phy-handle", NULL);
+		phy = of_find_node_by_phandle(*ph);
+
+		if (phy == NULL) {
+			ret = -ENODEV;
+			goto unreg;
+		}
+
+		id = (u32 *) get_property(phy, "reg", NULL);
+		phy_id = (u32 *) get_property(phy, "phy-id", NULL);
+		ret = of_address_to_resource(phy, 0, &res);
+		if (ret) {
+			of_node_put(phy);
+			goto unreg;
+		}
+		tsi_eth_data.regs = r[0].start;
+		tsi_eth_data.phyregs = res.start;
+		tsi_eth_data.phy = *phy_id;
+		tsi_eth_data.irq_num = irq_of_parse_and_map(np, 0);
+		of_node_put(phy);
+		ret =
+		    platform_device_add_data(tsi_eth_dev, &tsi_eth_data,
+					     sizeof(hw_info));
+		if (ret)
+			goto unreg;
+	}
+	return 0;
+unreg:
+	platform_device_unregister(tsi_eth_dev);
+err:
+	return ret;
+}
+
+arch_initcall(tsi108_eth_of_init);
diff --git a/arch/powerpc/sysdev/tsi108_pci.c b/arch/powerpc/sysdev/tsi108_pci.c
new file mode 100644
index 000000000..2ab06ed3a
--- /dev/null
+++ b/arch/powerpc/sysdev/tsi108_pci.c
@@ -0,0 +1,415 @@
+/*
+ * Common routines for Tundra Semiconductor TSI108 host bridge.
+ *
+ * 2004-2005 (c) Tundra Semiconductor Corp.
+ * Author: Alex Bounine (alexandreb@tundra.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/init.h>
+#include <linux/pci.h>
+#include <linux/slab.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+
+#include <asm/byteorder.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/uaccess.h>
+#include <asm/machdep.h>
+#include <asm/pci-bridge.h>
+#include <asm/tsi108.h>
+#include <asm/tsi108_irq.h>
+#include <asm/prom.h>
+
+#undef DEBUG
+#ifdef DEBUG
+#define DBG(x...) printk(x)
+#else
+#define DBG(x...)
+#endif
+
+#define tsi_mk_config_addr(bus, devfunc, offset) \
+	((((bus)<<16) | ((devfunc)<<8) | (offset & 0xfc)) + tsi108_pci_cfg_base)
+
+u32 tsi108_pci_cfg_base;
+u32 tsi108_csr_vir_base;
+
+extern u32 get_vir_csrbase(void);
+extern u32 tsi108_read_reg(u32 reg_offset);
+extern void tsi108_write_reg(u32 reg_offset, u32 val);
+
+int
+tsi108_direct_write_config(struct pci_bus *bus, unsigned int devfunc,
+			   int offset, int len, u32 val)
+{
+	volatile unsigned char *cfg_addr;
+
+	if (ppc_md.pci_exclude_device)
+		if (ppc_md.pci_exclude_device(bus->number, devfunc))
+			return PCIBIOS_DEVICE_NOT_FOUND;
+
+	cfg_addr = (unsigned char *)(tsi_mk_config_addr(bus->number,
+							devfunc, offset) |
+							(offset & 0x03));
+
+#ifdef DEBUG
+	printk("PCI CFG write : ");
+	printk("%d:0x%x:0x%x ", bus->number, devfunc, offset);
+	printk("%d ADDR=0x%08x ", len, (uint) cfg_addr);
+	printk("data = 0x%08x\n", val);
+#endif
+
+	switch (len) {
+	case 1:
+		out_8((u8 *) cfg_addr, val);
+		break;
+	case 2:
+		out_le16((u16 *) cfg_addr, val);
+		break;
+	default:
+		out_le32((u32 *) cfg_addr, val);
+		break;
+	}
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+void tsi108_clear_pci_error(u32 pci_cfg_base)
+{
+	u32 err_stat, err_addr, pci_stat;
+
+	/*
+	 * Quietly clear PB and PCI error flags set as result
+	 * of PCI/X configuration read requests.
+	 */
+
+	/* Read PB Error Log Registers */
+
+	err_stat = tsi108_read_reg(TSI108_PB_OFFSET + TSI108_PB_ERRCS);
+	err_addr = tsi108_read_reg(TSI108_PB_OFFSET + TSI108_PB_AERR);
+
+	if (err_stat & TSI108_PB_ERRCS_ES) {
+		/* Clear error flag */
+		tsi108_write_reg(TSI108_PB_OFFSET + TSI108_PB_ERRCS,
+				 TSI108_PB_ERRCS_ES);
+
+		/* Clear read error reported in PB_ISR */
+		tsi108_write_reg(TSI108_PB_OFFSET + TSI108_PB_ISR,
+				 TSI108_PB_ISR_PBS_RD_ERR);
+
+		/* Clear PCI/X bus cfg errors if applicable */
+		if ((err_addr & 0xFF000000) == pci_cfg_base) {
+			pci_stat =
+			    tsi108_read_reg(TSI108_PCI_OFFSET + TSI108_PCI_CSR);
+			tsi108_write_reg(TSI108_PCI_OFFSET + TSI108_PCI_CSR,
+					 pci_stat);
+		}
+	}
+
+	return;
+}
+
+#define __tsi108_read_pci_config(x, addr, op)		\
+	__asm__ __volatile__(				\
+		"	"op" %0,0,%1\n"		\
+		"1:	eieio\n"			\
+		"2:\n"					\
+		".section .fixup,\"ax\"\n"		\
+		"3:	li %0,-1\n"			\
+		"	b 2b\n"				\
+		".section __ex_table,\"a\"\n"		\
+		"	.align 2\n"			\
+		"	.long 1b,3b\n"			\
+		".text"					\
+		: "=r"(x) : "r"(addr))
+
+int
+tsi108_direct_read_config(struct pci_bus *bus, unsigned int devfn, int offset,
+			  int len, u32 * val)
+{
+	volatile unsigned char *cfg_addr;
+	u32 temp;
+
+	if (ppc_md.pci_exclude_device)
+		if (ppc_md.pci_exclude_device(bus->number, devfn))
+			return PCIBIOS_DEVICE_NOT_FOUND;
+
+	cfg_addr = (unsigned char *)(tsi_mk_config_addr(bus->number,
+							devfn,
+							offset) | (offset &
+								   0x03));
+
+	switch (len) {
+	case 1:
+		__tsi108_read_pci_config(temp, cfg_addr, "lbzx");
+		break;
+	case 2:
+		__tsi108_read_pci_config(temp, cfg_addr, "lhbrx");
+		break;
+	default:
+		__tsi108_read_pci_config(temp, cfg_addr, "lwbrx");
+		break;
+	}
+
+	*val = temp;
+
+#ifdef DEBUG
+	if ((0xFFFFFFFF != temp) && (0xFFFF != temp) && (0xFF != temp)) {
+		printk("PCI CFG read : ");
+		printk("%d:0x%x:0x%x ", bus->number, devfn, offset);
+		printk("%d ADDR=0x%08x ", len, (uint) cfg_addr);
+		printk("data = 0x%x\n", *val);
+	}
+#endif
+	return PCIBIOS_SUCCESSFUL;
+}
+
+void tsi108_clear_pci_cfg_error(void)
+{
+	tsi108_clear_pci_error(TSI108_PCI_CFG_BASE_PHYS);
+}
+
+static struct pci_ops tsi108_direct_pci_ops = {
+	tsi108_direct_read_config,
+	tsi108_direct_write_config
+};
+
+int __init tsi108_setup_pci(struct device_node *dev)
+{
+	int len;
+	struct pci_controller *hose;
+	struct resource rsrc;
+	int *bus_range;
+	int primary = 0, has_address = 0;
+
+	/* PCI Config mapping */
+	tsi108_pci_cfg_base = (u32)ioremap(TSI108_PCI_CFG_BASE_PHYS,
+			TSI108_PCI_CFG_SIZE);
+	DBG("TSI_PCI: %s tsi108_pci_cfg_base=0x%x\n", __FUNCTION__,
+	    tsi108_pci_cfg_base);
+
+	/* Fetch host bridge registers address */
+	has_address = (of_address_to_resource(dev, 0, &rsrc) == 0);
+
+	/* Get bus range if any */
+	bus_range = (int *)get_property(dev, "bus-range", &len);
+	if (bus_range == NULL || len < 2 * sizeof(int)) {
+		printk(KERN_WARNING "Can't get bus-range for %s, assume"
+		       " bus 0\n", dev->full_name);
+	}
+
+	hose = pcibios_alloc_controller();
+
+	if (!hose) {
+		printk("PCI Host bridge init failed\n");
+		return -ENOMEM;
+	}
+	hose->arch_data = dev;
+	hose->set_cfg_type = 1;
+
+	hose->first_busno = bus_range ? bus_range[0] : 0;
+	hose->last_busno = bus_range ? bus_range[1] : 0xff;
+
+	(hose)->ops = &tsi108_direct_pci_ops;
+
+	printk(KERN_INFO "Found tsi108 PCI host bridge at 0x%08x. "
+	       "Firmware bus number: %d->%d\n",
+	       rsrc.start, hose->first_busno, hose->last_busno);
+
+	/* Interpret the "ranges" property */
+	/* This also maps the I/O region and sets isa_io/mem_base */
+	pci_process_bridge_OF_ranges(hose, dev, primary);
+	return 0;
+}
+
+/*
+ * Low level utility functions
+ */
+
+static void tsi108_pci_int_mask(u_int irq)
+{
+	u_int irp_cfg;
+	int int_line = (irq - IRQ_PCI_INTAD_BASE);
+
+	irp_cfg = tsi108_read_reg(TSI108_PCI_OFFSET + TSI108_PCI_IRP_CFG_CTL);
+	mb();
+	irp_cfg |= (1 << int_line);	/* INTx_DIR = output */
+	irp_cfg &= ~(3 << (8 + (int_line * 2)));	/* INTx_TYPE = unused */
+	tsi108_write_reg(TSI108_PCI_OFFSET + TSI108_PCI_IRP_CFG_CTL, irp_cfg);
+	mb();
+	irp_cfg = tsi108_read_reg(TSI108_PCI_OFFSET + TSI108_PCI_IRP_CFG_CTL);
+}
+
+static void tsi108_pci_int_unmask(u_int irq)
+{
+	u_int irp_cfg;
+	int int_line = (irq - IRQ_PCI_INTAD_BASE);
+
+	irp_cfg = tsi108_read_reg(TSI108_PCI_OFFSET + TSI108_PCI_IRP_CFG_CTL);
+	mb();
+	irp_cfg &= ~(1 << int_line);
+	irp_cfg |= (3 << (8 + (int_line * 2)));
+	tsi108_write_reg(TSI108_PCI_OFFSET + TSI108_PCI_IRP_CFG_CTL, irp_cfg);
+	mb();
+}
+
+static void init_pci_source(void)
+{
+	tsi108_write_reg(TSI108_PCI_OFFSET + TSI108_PCI_IRP_CFG_CTL,
+			0x0000ff00);
+	tsi108_write_reg(TSI108_PCI_OFFSET + TSI108_PCI_IRP_ENABLE,
+			TSI108_PCI_IRP_ENABLE_P_INT);
+	mb();
+}
+
+static inline unsigned int get_pci_source(void)
+{
+	u_int temp = 0;
+	int irq = -1;
+	int i;
+	u_int pci_irp_stat;
+	static int mask = 0;
+
+	/* Read PCI/X block interrupt status register */
+	pci_irp_stat = tsi108_read_reg(TSI108_PCI_OFFSET + TSI108_PCI_IRP_STAT);
+	mb();
+
+	if (pci_irp_stat & TSI108_PCI_IRP_STAT_P_INT) {
+		/* Process Interrupt from PCI bus INTA# - INTD# lines */
+		temp =
+		    tsi108_read_reg(TSI108_PCI_OFFSET +
+				    TSI108_PCI_IRP_INTAD) & 0xf;
+		mb();
+		for (i = 0; i < 4; i++, mask++) {
+			if (temp & (1 << mask % 4)) {
+				irq = IRQ_PCI_INTA + mask % 4;
+				mask++;
+				break;
+			}
+		}
+
+		/* Disable interrupts from PCI block */
+		temp = tsi108_read_reg(TSI108_PCI_OFFSET + TSI108_PCI_IRP_ENABLE);
+		tsi108_write_reg(TSI108_PCI_OFFSET + TSI108_PCI_IRP_ENABLE,
+				temp & ~TSI108_PCI_IRP_ENABLE_P_INT);
+		mb();
+		(void)tsi108_read_reg(TSI108_PCI_OFFSET + TSI108_PCI_IRP_ENABLE);
+		mb();
+	}
+#ifdef DEBUG
+	else {
+		printk("TSI108_PIC: error in TSI108_PCI_IRP_STAT\n");
+		pci_irp_stat =
+		    tsi108_read_reg(TSI108_PCI_OFFSET + TSI108_PCI_IRP_STAT);
+		temp =
+		    tsi108_read_reg(TSI108_PCI_OFFSET + TSI108_PCI_IRP_INTAD);
+		mb();
+		printk(">> stat=0x%08x intad=0x%08x ", pci_irp_stat, temp);
+		temp =
+		    tsi108_read_reg(TSI108_PCI_OFFSET + TSI108_PCI_IRP_CFG_CTL);
+		mb();
+		printk("cfg_ctl=0x%08x ", temp);
+		temp =
+		    tsi108_read_reg(TSI108_PCI_OFFSET + TSI108_PCI_IRP_ENABLE);
+		mb();
+		printk("irp_enable=0x%08x\n", temp);
+	}
+#endif	/* end of DEBUG */
+
+	return irq;
+}
+
+
+/*
+ * Linux descriptor level callbacks
+ */
+
+static void tsi108_pci_irq_enable(u_int irq)
+{
+	tsi108_pci_int_unmask(irq);
+}
+
+static void tsi108_pci_irq_disable(u_int irq)
+{
+	tsi108_pci_int_mask(irq);
+}
+
+static void tsi108_pci_irq_ack(u_int irq)
+{
+	tsi108_pci_int_mask(irq);
+}
+
+static void tsi108_pci_irq_end(u_int irq)
+{
+	tsi108_pci_int_unmask(irq);
+
+	/* Enable interrupts from PCI block */
+	tsi108_write_reg(TSI108_PCI_OFFSET + TSI108_PCI_IRP_ENABLE,
+			 tsi108_read_reg(TSI108_PCI_OFFSET +
+					 TSI108_PCI_IRP_ENABLE) |
+			 TSI108_PCI_IRP_ENABLE_P_INT);
+	mb();
+}
+
+/*
+ * Interrupt controller descriptor for cascaded PCI interrupt controller.
+ */
+
+static struct irq_chip tsi108_pci_irq = {
+	.typename = "tsi108_PCI_int",
+	.mask = tsi108_pci_irq_disable,
+	.ack = tsi108_pci_irq_ack,
+	.end = tsi108_pci_irq_end,
+	.unmask = tsi108_pci_irq_enable,
+};
+
+/*
+ * Exported functions
+ */
+
+/*
+ * The Tsi108 PCI interrupts initialization routine.
+ *
+ * The INTA# - INTD# interrupts on the PCI bus are reported by the PCI block
+ * to the MPIC using single interrupt source (IRQ_TSI108_PCI). Therefore the
+ * PCI block has to be treated as a cascaded interrupt controller connected
+ * to the MPIC.
+ */
+
+void __init tsi108_pci_int_init(void)
+{
+	u_int i;
+
+	DBG("Tsi108_pci_int_init: initializing PCI interrupts\n");
+
+	for (i = 0; i < NUM_PCI_IRQS; i++) {
+		irq_desc[i + IRQ_PCI_INTAD_BASE].chip = &tsi108_pci_irq;
+		irq_desc[i + IRQ_PCI_INTAD_BASE].status |= IRQ_LEVEL;
+	}
+
+	init_pci_source();
+}
+
+void tsi108_irq_cascade(unsigned int irq, struct irq_desc *desc,
+			    struct pt_regs *regs)
+{
+	unsigned int cascade_irq = get_pci_source();
+	if (cascade_irq != NO_IRQ)
+		generic_handle_irq(cascade_irq, regs);
+	desc->chip->eoi(irq);
+}
diff --git a/arch/s390/hypfs/Makefile b/arch/s390/hypfs/Makefile
new file mode 100644
index 000000000..f4b00cd81
--- /dev/null
+++ b/arch/s390/hypfs/Makefile
@@ -0,0 +1,7 @@
+#
+# Makefile for the linux hypfs filesystem routines.
+#
+
+obj-$(CONFIG_S390_HYPFS_FS) += s390_hypfs.o
+
+s390_hypfs-objs := inode.o hypfs_diag.o
diff --git a/arch/s390/hypfs/hypfs.h b/arch/s390/hypfs/hypfs.h
new file mode 100644
index 000000000..ea5567be0
--- /dev/null
+++ b/arch/s390/hypfs/hypfs.h
@@ -0,0 +1,30 @@
+/*
+ *  fs/hypfs/hypfs.h
+ *    Hypervisor filesystem for Linux on s390.
+ *
+ *    Copyright (C) IBM Corp. 2006
+ *    Author(s): Michael Holzheu <holzheu@de.ibm.com>
+ */
+
+#ifndef _HYPFS_H_
+#define _HYPFS_H_
+
+#include <linux/fs.h>
+#include <linux/types.h>
+
+#define REG_FILE_MODE    0440
+#define UPDATE_FILE_MODE 0220
+#define DIR_MODE         0550
+
+extern struct dentry *hypfs_mkdir(struct super_block *sb, struct dentry *parent,
+				  const char *name);
+
+extern struct dentry *hypfs_create_u64(struct super_block *sb,
+				       struct dentry *dir, const char *name,
+				       __u64 value);
+
+extern struct dentry *hypfs_create_str(struct super_block *sb,
+				       struct dentry *dir, const char *name,
+				       char *string);
+
+#endif /* _HYPFS_H_ */
diff --git a/arch/s390/hypfs/hypfs_diag.c b/arch/s390/hypfs/hypfs_diag.c
new file mode 100644
index 000000000..1785bce2b
--- /dev/null
+++ b/arch/s390/hypfs/hypfs_diag.c
@@ -0,0 +1,696 @@
+/*
+ *  fs/hypfs/hypfs_diag.c
+ *    Hypervisor filesystem for Linux on s390. Diag 204 and 224
+ *    implementation.
+ *
+ *    Copyright (C) IBM Corp. 2006
+ *    Author(s): Michael Holzheu <holzheu@de.ibm.com>
+ */
+
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/vmalloc.h>
+#include <asm/ebcdic.h>
+#include "hypfs.h"
+
+#define LPAR_NAME_LEN 8		/* lpar name len in diag 204 data */
+#define CPU_NAME_LEN 16		/* type name len of cpus in diag224 name table */
+#define TMP_SIZE 64		/* size of temporary buffers */
+
+/* diag 204 subcodes */
+enum diag204_sc {
+	SUBC_STIB4 = 4,
+	SUBC_RSI = 5,
+	SUBC_STIB6 = 6,
+	SUBC_STIB7 = 7
+};
+
+/* The two available diag 204 data formats */
+enum diag204_format {
+	INFO_SIMPLE = 0,
+	INFO_EXT = 0x00010000
+};
+
+/* bit is set in flags, when physical cpu info is included in diag 204 data */
+#define LPAR_PHYS_FLG  0x80
+
+static char *diag224_cpu_names;			/* diag 224 name table */
+static enum diag204_sc diag204_store_sc;	/* used subcode for store */
+static enum diag204_format diag204_info_type;	/* used diag 204 data format */
+
+static void *diag204_buf;		/* 4K aligned buffer for diag204 data */
+static void *diag204_buf_vmalloc;	/* vmalloc pointer for diag204 data */
+static int diag204_buf_pages;		/* number of pages for diag204 data */
+
+/*
+ * DIAG 204 data structures and member access functions.
+ *
+ * Since we have two different diag 204 data formats for old and new s390
+ * machines, we do not access the structs directly, but use getter functions for
+ * each struct member instead. This should make the code more readable.
+ */
+
+/* Time information block */
+
+struct info_blk_hdr {
+	__u8  npar;
+	__u8  flags;
+	__u16 tslice;
+	__u16 phys_cpus;
+	__u16 this_part;
+	__u64 curtod;
+} __attribute__ ((packed));
+
+struct x_info_blk_hdr {
+	__u8  npar;
+	__u8  flags;
+	__u16 tslice;
+	__u16 phys_cpus;
+	__u16 this_part;
+	__u64 curtod1;
+	__u64 curtod2;
+	char reserved[40];
+} __attribute__ ((packed));
+
+static inline int info_blk_hdr__size(enum diag204_format type)
+{
+	if (type == INFO_SIMPLE)
+		return sizeof(struct info_blk_hdr);
+	else /* INFO_EXT */
+		return sizeof(struct x_info_blk_hdr);
+}
+
+static inline __u8 info_blk_hdr__npar(enum diag204_format type, void *hdr)
+{
+	if (type == INFO_SIMPLE)
+		return ((struct info_blk_hdr *)hdr)->npar;
+	else /* INFO_EXT */
+		return ((struct x_info_blk_hdr *)hdr)->npar;
+}
+
+static inline __u8 info_blk_hdr__flags(enum diag204_format type, void *hdr)
+{
+	if (type == INFO_SIMPLE)
+		return ((struct info_blk_hdr *)hdr)->flags;
+	else /* INFO_EXT */
+		return ((struct x_info_blk_hdr *)hdr)->flags;
+}
+
+static inline __u16 info_blk_hdr__pcpus(enum diag204_format type, void *hdr)
+{
+	if (type == INFO_SIMPLE)
+		return ((struct info_blk_hdr *)hdr)->phys_cpus;
+	else /* INFO_EXT */
+		return ((struct x_info_blk_hdr *)hdr)->phys_cpus;
+}
+
+/* Partition header */
+
+struct part_hdr {
+	__u8 pn;
+	__u8 cpus;
+	char reserved[6];
+	char part_name[LPAR_NAME_LEN];
+} __attribute__ ((packed));
+
+struct x_part_hdr {
+	__u8  pn;
+	__u8  cpus;
+	__u8  rcpus;
+	__u8  pflag;
+	__u32 mlu;
+	char  part_name[LPAR_NAME_LEN];
+	char  lpc_name[8];
+	char  os_name[8];
+	__u64 online_cs;
+	__u64 online_es;
+	__u8  upid;
+	char  reserved1[3];
+	__u32 group_mlu;
+	char  group_name[8];
+	char  reserved2[32];
+} __attribute__ ((packed));
+
+static inline int part_hdr__size(enum diag204_format type)
+{
+	if (type == INFO_SIMPLE)
+		return sizeof(struct part_hdr);
+	else /* INFO_EXT */
+		return sizeof(struct x_part_hdr);
+}
+
+static inline __u8 part_hdr__rcpus(enum diag204_format type, void *hdr)
+{
+	if (type == INFO_SIMPLE)
+		return ((struct part_hdr *)hdr)->cpus;
+	else /* INFO_EXT */
+		return ((struct x_part_hdr *)hdr)->rcpus;
+}
+
+static inline void part_hdr__part_name(enum diag204_format type, void *hdr,
+				       char *name)
+{
+	if (type == INFO_SIMPLE)
+		memcpy(name, ((struct part_hdr *)hdr)->part_name,
+		       LPAR_NAME_LEN);
+	else /* INFO_EXT */
+		memcpy(name, ((struct x_part_hdr *)hdr)->part_name,
+		       LPAR_NAME_LEN);
+	EBCASC(name, LPAR_NAME_LEN);
+	name[LPAR_NAME_LEN] = 0;
+	strstrip(name);
+}
+
+struct cpu_info {
+	__u16 cpu_addr;
+	char  reserved1[2];
+	__u8  ctidx;
+	__u8  cflag;
+	__u16 weight;
+	__u64 acc_time;
+	__u64 lp_time;
+} __attribute__ ((packed));
+
+struct x_cpu_info {
+	__u16 cpu_addr;
+	char  reserved1[2];
+	__u8  ctidx;
+	__u8  cflag;
+	__u16 weight;
+	__u64 acc_time;
+	__u64 lp_time;
+	__u16 min_weight;
+	__u16 cur_weight;
+	__u16 max_weight;
+	char  reseved2[2];
+	__u64 online_time;
+	__u64 wait_time;
+	__u32 pma_weight;
+	__u32 polar_weight;
+	char  reserved3[40];
+} __attribute__ ((packed));
+
+/* CPU info block */
+
+static inline int cpu_info__size(enum diag204_format type)
+{
+	if (type == INFO_SIMPLE)
+		return sizeof(struct cpu_info);
+	else /* INFO_EXT */
+		return sizeof(struct x_cpu_info);
+}
+
+static inline __u8 cpu_info__ctidx(enum diag204_format type, void *hdr)
+{
+	if (type == INFO_SIMPLE)
+		return ((struct cpu_info *)hdr)->ctidx;
+	else /* INFO_EXT */
+		return ((struct x_cpu_info *)hdr)->ctidx;
+}
+
+static inline __u16 cpu_info__cpu_addr(enum diag204_format type, void *hdr)
+{
+	if (type == INFO_SIMPLE)
+		return ((struct cpu_info *)hdr)->cpu_addr;
+	else /* INFO_EXT */
+		return ((struct x_cpu_info *)hdr)->cpu_addr;
+}
+
+static inline __u64 cpu_info__acc_time(enum diag204_format type, void *hdr)
+{
+	if (type == INFO_SIMPLE)
+		return ((struct cpu_info *)hdr)->acc_time;
+	else /* INFO_EXT */
+		return ((struct x_cpu_info *)hdr)->acc_time;
+}
+
+static inline __u64 cpu_info__lp_time(enum diag204_format type, void *hdr)
+{
+	if (type == INFO_SIMPLE)
+		return ((struct cpu_info *)hdr)->lp_time;
+	else /* INFO_EXT */
+		return ((struct x_cpu_info *)hdr)->lp_time;
+}
+
+static inline __u64 cpu_info__online_time(enum diag204_format type, void *hdr)
+{
+	if (type == INFO_SIMPLE)
+		return 0;	/* online_time not available in simple info */
+	else /* INFO_EXT */
+		return ((struct x_cpu_info *)hdr)->online_time;
+}
+
+/* Physical header */
+
+struct phys_hdr {
+	char reserved1[1];
+	__u8 cpus;
+	char reserved2[6];
+	char mgm_name[8];
+} __attribute__ ((packed));
+
+struct x_phys_hdr {
+	char reserved1[1];
+	__u8 cpus;
+	char reserved2[6];
+	char mgm_name[8];
+	char reserved3[80];
+} __attribute__ ((packed));
+
+static inline int phys_hdr__size(enum diag204_format type)
+{
+	if (type == INFO_SIMPLE)
+		return sizeof(struct phys_hdr);
+	else /* INFO_EXT */
+		return sizeof(struct x_phys_hdr);
+}
+
+static inline __u8 phys_hdr__cpus(enum diag204_format type, void *hdr)
+{
+	if (type == INFO_SIMPLE)
+		return ((struct phys_hdr *)hdr)->cpus;
+	else /* INFO_EXT */
+		return ((struct x_phys_hdr *)hdr)->cpus;
+}
+
+/* Physical CPU info block */
+
+struct phys_cpu {
+	__u16 cpu_addr;
+	char  reserved1[2];
+	__u8  ctidx;
+	char  reserved2[3];
+	__u64 mgm_time;
+	char  reserved3[8];
+} __attribute__ ((packed));
+
+struct x_phys_cpu {
+	__u16 cpu_addr;
+	char  reserved1[2];
+	__u8  ctidx;
+	char  reserved2[3];
+	__u64 mgm_time;
+	char  reserved3[80];
+} __attribute__ ((packed));
+
+static inline int phys_cpu__size(enum diag204_format type)
+{
+	if (type == INFO_SIMPLE)
+		return sizeof(struct phys_cpu);
+	else /* INFO_EXT */
+		return sizeof(struct x_phys_cpu);
+}
+
+static inline __u16 phys_cpu__cpu_addr(enum diag204_format type, void *hdr)
+{
+	if (type == INFO_SIMPLE)
+		return ((struct phys_cpu *)hdr)->cpu_addr;
+	else /* INFO_EXT */
+		return ((struct x_phys_cpu *)hdr)->cpu_addr;
+}
+
+static inline __u64 phys_cpu__mgm_time(enum diag204_format type, void *hdr)
+{
+	if (type == INFO_SIMPLE)
+		return ((struct phys_cpu *)hdr)->mgm_time;
+	else /* INFO_EXT */
+		return ((struct x_phys_cpu *)hdr)->mgm_time;
+}
+
+static inline __u64 phys_cpu__ctidx(enum diag204_format type, void *hdr)
+{
+	if (type == INFO_SIMPLE)
+		return ((struct phys_cpu *)hdr)->ctidx;
+	else /* INFO_EXT */
+		return ((struct x_phys_cpu *)hdr)->ctidx;
+}
+
+/* Diagnose 204 functions */
+
+static int diag204(unsigned long subcode, unsigned long size, void *addr)
+{
+	register unsigned long _subcode asm("0") = subcode;
+	register unsigned long _size asm("1") = size;
+
+	asm volatile ("   diag    %2,%0,0x204\n"
+		      "0: \n" ".section __ex_table,\"a\"\n"
+#ifndef __s390x__
+		      "    .align 4\n"
+		      "    .long  0b,0b\n"
+#else
+		      "    .align 8\n"
+		      "    .quad  0b,0b\n"
+#endif
+		      ".previous":"+d" (_subcode), "+d"(_size)
+		      :"d"(addr)
+		      :"memory");
+	if (_subcode)
+		return -1;
+	else
+		return _size;
+}
+
+/*
+ * For the old diag subcode 4 with simple data format we have to use real
+ * memory. If we use subcode 6 or 7 with extended data format, we can (and
+ * should) use vmalloc, since we need a lot of memory in that case. Currently
+ * up to 93 pages!
+ */
+
+static void diag204_free_buffer(void)
+{
+	if (!diag204_buf)
+		return;
+	if (diag204_buf_vmalloc) {
+		vfree(diag204_buf_vmalloc);
+		diag204_buf_vmalloc = NULL;
+	} else {
+		free_pages((unsigned long) diag204_buf, 0);
+	}
+	diag204_buf_pages = 0;
+	diag204_buf = NULL;
+}
+
+static void *diag204_alloc_vbuf(int pages)
+{
+	/* The buffer has to be page aligned! */
+	diag204_buf_vmalloc = vmalloc(PAGE_SIZE * (pages + 1));
+	if (!diag204_buf_vmalloc)
+		return ERR_PTR(-ENOMEM);
+	diag204_buf = (void*)((unsigned long)diag204_buf_vmalloc
+				& ~0xfffUL) + 0x1000;
+	diag204_buf_pages = pages;
+	return diag204_buf;
+}
+
+static void *diag204_alloc_rbuf(void)
+{
+	diag204_buf = (void*)__get_free_pages(GFP_KERNEL,0);
+	if (diag204_buf)
+		return ERR_PTR(-ENOMEM);
+	diag204_buf_pages = 1;
+	return diag204_buf;
+}
+
+static void *diag204_get_buffer(enum diag204_format fmt, int *pages)
+{
+	if (diag204_buf) {
+		*pages = diag204_buf_pages;
+		return diag204_buf;
+	}
+	if (fmt == INFO_SIMPLE) {
+		*pages = 1;
+		return diag204_alloc_rbuf();
+	} else {/* INFO_EXT */
+		*pages = diag204(SUBC_RSI | INFO_EXT, 0, NULL);
+		if (*pages <= 0)
+			return ERR_PTR(-ENOSYS);
+		else
+			return diag204_alloc_vbuf(*pages);
+	}
+}
+
+/*
+ * diag204_probe() has to find out, which type of diagnose 204 implementation
+ * we have on our machine. Currently there are three possible scanarios:
+ *   - subcode 4   + simple data format (only one page)
+ *   - subcode 4-6 + extended data format
+ *   - subcode 4-7 + extended data format
+ *
+ * Subcode 5 is used to retrieve the size of the data, provided by subcodes
+ * 6 and 7. Subcode 7 basically has the same function as subcode 6. In addition
+ * to subcode 6 it provides also information about secondary cpus.
+ * In order to get as much information as possible, we first try
+ * subcode 7, then 6 and if both fail, we use subcode 4.
+ */
+
+static int diag204_probe(void)
+{
+	void *buf;
+	int pages, rc;
+
+	buf = diag204_get_buffer(INFO_EXT, &pages);
+	if (!IS_ERR(buf)) {
+		if (diag204(SUBC_STIB7 | INFO_EXT, pages, buf) >= 0) {
+			diag204_store_sc = SUBC_STIB7;
+			diag204_info_type = INFO_EXT;
+			goto out;
+		}
+		if (diag204(SUBC_STIB6 | INFO_EXT, pages, buf) >= 0) {
+			diag204_store_sc = SUBC_STIB7;
+			diag204_info_type = INFO_EXT;
+			goto out;
+		}
+		diag204_free_buffer();
+	}
+
+	/* subcodes 6 and 7 failed, now try subcode 4 */
+
+	buf = diag204_get_buffer(INFO_SIMPLE, &pages);
+	if (IS_ERR(buf)) {
+		rc = PTR_ERR(buf);
+		goto fail_alloc;
+	}
+	if (diag204(SUBC_STIB4 | INFO_SIMPLE, pages, buf) >= 0) {
+		diag204_store_sc = SUBC_STIB4;
+		diag204_info_type = INFO_SIMPLE;
+		goto out;
+	} else {
+		rc = -ENOSYS;
+		goto fail_store;
+	}
+out:
+	rc = 0;
+fail_store:
+	diag204_free_buffer();
+fail_alloc:
+	return rc;
+}
+
+static void *diag204_store(void)
+{
+	void *buf;
+	int pages;
+
+	buf = diag204_get_buffer(diag204_info_type, &pages);
+	if (IS_ERR(buf))
+		goto out;
+	if (diag204(diag204_store_sc | diag204_info_type, pages, buf) < 0)
+		return ERR_PTR(-ENOSYS);
+out:
+	return buf;
+}
+
+/* Diagnose 224 functions */
+
+static void diag224(void *ptr)
+{
+	asm volatile("   diag    %0,%1,0x224\n"
+		     : :"d" (0), "d"(ptr) : "memory");
+}
+
+static int diag224_get_name_table(void)
+{
+	/* memory must be below 2GB */
+	diag224_cpu_names = kmalloc(PAGE_SIZE, GFP_KERNEL | GFP_DMA);
+	if (!diag224_cpu_names)
+		return -ENOMEM;
+	diag224(diag224_cpu_names);
+	EBCASC(diag224_cpu_names + 16, (*diag224_cpu_names + 1) * 16);
+	return 0;
+}
+
+static void diag224_delete_name_table(void)
+{
+	kfree(diag224_cpu_names);
+}
+
+static int diag224_idx2name(int index, char *name)
+{
+	memcpy(name, diag224_cpu_names + ((index + 1) * CPU_NAME_LEN),
+		CPU_NAME_LEN);
+	name[CPU_NAME_LEN] = 0;
+	strstrip(name);
+	return 0;
+}
+
+__init int hypfs_diag_init(void)
+{
+	int rc;
+
+	if (diag204_probe()) {
+		printk(KERN_ERR "hypfs: diag 204 not working.");
+		return -ENODATA;
+	}
+	rc = diag224_get_name_table();
+	if (rc) {
+		diag224_delete_name_table();
+		printk(KERN_ERR "hypfs: could not get name table.\n");
+	}
+	return rc;
+}
+
+__exit void hypfs_diag_exit(void)
+{
+	diag224_delete_name_table();
+	diag204_free_buffer();
+}
+
+/*
+ * Functions to create the directory structure
+ * *******************************************
+ */
+
+static int hypfs_create_cpu_files(struct super_block *sb,
+				  struct dentry *cpus_dir, void *cpu_info)
+{
+	struct dentry *cpu_dir;
+	char buffer[TMP_SIZE];
+	void *rc;
+
+	snprintf(buffer, TMP_SIZE, "%d", cpu_info__cpu_addr(diag204_info_type,
+							    cpu_info));
+	cpu_dir = hypfs_mkdir(sb, cpus_dir, buffer);
+	rc = hypfs_create_u64(sb, cpu_dir, "mgmtime",
+			      cpu_info__acc_time(diag204_info_type, cpu_info) -
+			      cpu_info__lp_time(diag204_info_type, cpu_info));
+	if (IS_ERR(rc))
+		return PTR_ERR(rc);
+	rc = hypfs_create_u64(sb, cpu_dir, "cputime",
+			      cpu_info__lp_time(diag204_info_type, cpu_info));
+	if (IS_ERR(rc))
+		return PTR_ERR(rc);
+	if (diag204_info_type == INFO_EXT) {
+		rc = hypfs_create_u64(sb, cpu_dir, "onlinetime",
+				      cpu_info__online_time(diag204_info_type,
+							    cpu_info));
+		if (IS_ERR(rc))
+			return PTR_ERR(rc);
+	}
+	diag224_idx2name(cpu_info__ctidx(diag204_info_type, cpu_info), buffer);
+	rc = hypfs_create_str(sb, cpu_dir, "type", buffer);
+	if (IS_ERR(rc))
+		return PTR_ERR(rc);
+	return 0;
+}
+
+static void *hypfs_create_lpar_files(struct super_block *sb,
+				     struct dentry *systems_dir, void *part_hdr)
+{
+	struct dentry *cpus_dir;
+	struct dentry *lpar_dir;
+	char lpar_name[LPAR_NAME_LEN + 1];
+	void *cpu_info;
+	int i;
+
+	part_hdr__part_name(diag204_info_type, part_hdr, lpar_name);
+	lpar_name[LPAR_NAME_LEN] = 0;
+	lpar_dir = hypfs_mkdir(sb, systems_dir, lpar_name);
+	if (IS_ERR(lpar_dir))
+		return lpar_dir;
+	cpus_dir = hypfs_mkdir(sb, lpar_dir, "cpus");
+	if (IS_ERR(cpus_dir))
+		return cpus_dir;
+	cpu_info = part_hdr + part_hdr__size(diag204_info_type);
+	for (i = 0; i < part_hdr__rcpus(diag204_info_type, part_hdr); i++) {
+		int rc;
+		rc = hypfs_create_cpu_files(sb, cpus_dir, cpu_info);
+		if (rc)
+			return ERR_PTR(rc);
+		cpu_info += cpu_info__size(diag204_info_type);
+	}
+	return cpu_info;
+}
+
+static int hypfs_create_phys_cpu_files(struct super_block *sb,
+				       struct dentry *cpus_dir, void *cpu_info)
+{
+	struct dentry *cpu_dir;
+	char buffer[TMP_SIZE];
+	void *rc;
+
+	snprintf(buffer, TMP_SIZE, "%i", phys_cpu__cpu_addr(diag204_info_type,
+							    cpu_info));
+	cpu_dir = hypfs_mkdir(sb, cpus_dir, buffer);
+	if (IS_ERR(cpu_dir))
+		return PTR_ERR(cpu_dir);
+	rc = hypfs_create_u64(sb, cpu_dir, "mgmtime",
+			      phys_cpu__mgm_time(diag204_info_type, cpu_info));
+	if (IS_ERR(rc))
+		return PTR_ERR(rc);
+	diag224_idx2name(phys_cpu__ctidx(diag204_info_type, cpu_info), buffer);
+	rc = hypfs_create_str(sb, cpu_dir, "type", buffer);
+	if (IS_ERR(rc))
+		return PTR_ERR(rc);
+	return 0;
+}
+
+static void *hypfs_create_phys_files(struct super_block *sb,
+				     struct dentry *parent_dir, void *phys_hdr)
+{
+	int i;
+	void *cpu_info;
+	struct dentry *cpus_dir;
+
+	cpus_dir = hypfs_mkdir(sb, parent_dir, "cpus");
+	if (IS_ERR(cpus_dir))
+		return cpus_dir;
+	cpu_info = phys_hdr + phys_hdr__size(diag204_info_type);
+	for (i = 0; i < phys_hdr__cpus(diag204_info_type, phys_hdr); i++) {
+		int rc;
+		rc = hypfs_create_phys_cpu_files(sb, cpus_dir, cpu_info);
+		if (rc)
+			return ERR_PTR(rc);
+		cpu_info += phys_cpu__size(diag204_info_type);
+	}
+	return cpu_info;
+}
+
+int hypfs_diag_create_files(struct super_block *sb, struct dentry *root)
+{
+	struct dentry *systems_dir, *hyp_dir;
+	void *time_hdr, *part_hdr;
+	int i, rc;
+	void *buffer, *ptr;
+
+	buffer = diag204_store();
+	if (IS_ERR(buffer))
+		return PTR_ERR(buffer);
+
+	systems_dir = hypfs_mkdir(sb, root, "systems");
+	if (IS_ERR(systems_dir)) {
+		rc = PTR_ERR(systems_dir);
+		goto err_out;
+	}
+	time_hdr = (struct x_info_blk_hdr *)buffer;
+	part_hdr = time_hdr + info_blk_hdr__size(diag204_info_type);
+	for (i = 0; i < info_blk_hdr__npar(diag204_info_type, time_hdr); i++) {
+		part_hdr = hypfs_create_lpar_files(sb, systems_dir, part_hdr);
+		if (IS_ERR(part_hdr)) {
+			rc = PTR_ERR(part_hdr);
+			goto err_out;
+		}
+	}
+	if (info_blk_hdr__flags(diag204_info_type, time_hdr) & LPAR_PHYS_FLG) {
+		ptr = hypfs_create_phys_files(sb, root, part_hdr);
+		if (IS_ERR(ptr)) {
+			rc = PTR_ERR(ptr);
+			goto err_out;
+		}
+	}
+	hyp_dir = hypfs_mkdir(sb, root, "hyp");
+	if (IS_ERR(hyp_dir)) {
+		rc = PTR_ERR(hyp_dir);
+		goto err_out;
+	}
+	ptr = hypfs_create_str(sb, hyp_dir, "type", "LPAR Hypervisor");
+	if (IS_ERR(ptr)) {
+		rc = PTR_ERR(ptr);
+		goto err_out;
+	}
+	rc = 0;
+
+err_out:
+	return rc;
+}
diff --git a/arch/s390/hypfs/hypfs_diag.h b/arch/s390/hypfs/hypfs_diag.h
new file mode 100644
index 000000000..793dea6b9
--- /dev/null
+++ b/arch/s390/hypfs/hypfs_diag.h
@@ -0,0 +1,16 @@
+/*
+ *  fs/hypfs/hypfs_diag.h
+ *    Hypervisor filesystem for Linux on s390.
+ *
+ *    Copyright (C) IBM Corp. 2006
+ *    Author(s): Michael Holzheu <holzheu@de.ibm.com>
+ */
+
+#ifndef _HYPFS_DIAG_H_
+#define _HYPFS_DIAG_H_
+
+extern int hypfs_diag_init(void);
+extern void hypfs_diag_exit(void);
+extern int hypfs_diag_create_files(struct super_block *sb, struct dentry *root);
+
+#endif /* _HYPFS_DIAG_H_ */
diff --git a/arch/s390/hypfs/inode.c b/arch/s390/hypfs/inode.c
new file mode 100644
index 000000000..666b946f3
--- /dev/null
+++ b/arch/s390/hypfs/inode.c
@@ -0,0 +1,490 @@
+/*
+ *  fs/hypfs/inode.c
+ *    Hypervisor filesystem for Linux on s390.
+ *
+ *    Copyright (C) IBM Corp. 2006
+ *    Author(s): Michael Holzheu <holzheu@de.ibm.com>
+ */
+
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/fs.h>
+#include <linux/namei.h>
+#include <linux/vfs.h>
+#include <linux/pagemap.h>
+#include <linux/gfp.h>
+#include <linux/time.h>
+#include <linux/parser.h>
+#include <linux/sysfs.h>
+#include <linux/module.h>
+#include <asm/ebcdic.h>
+#include "hypfs.h"
+#include "hypfs_diag.h"
+
+#define HYPFS_MAGIC 0x687970	/* ASCII 'hyp' */
+#define TMP_SIZE 64		/* size of temporary buffers */
+
+static struct dentry *hypfs_create_update_file(struct super_block *sb,
+					       struct dentry *dir);
+
+struct hypfs_sb_info {
+	uid_t uid;			/* uid used for files and dirs */
+	gid_t gid;			/* gid used for files and dirs */
+	struct dentry *update_file;	/* file to trigger update */
+	time_t last_update;		/* last update time in secs since 1970 */
+	struct mutex lock;		/* lock to protect update process */
+};
+
+static struct file_operations hypfs_file_ops;
+static struct file_system_type hypfs_type;
+static struct super_operations hypfs_s_ops;
+
+/* start of list of all dentries, which have to be deleted on update */
+static struct dentry *hypfs_last_dentry;
+
+static void hypfs_update_update(struct super_block *sb)
+{
+	struct hypfs_sb_info *sb_info = sb->s_fs_info;
+	struct inode *inode = sb_info->update_file->d_inode;
+
+	sb_info->last_update = get_seconds();
+	inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
+}
+
+/* directory tree removal functions */
+
+static void hypfs_add_dentry(struct dentry *dentry)
+{
+	dentry->d_fsdata = hypfs_last_dentry;
+	hypfs_last_dentry = dentry;
+}
+
+static void hypfs_remove(struct dentry *dentry)
+{
+	struct dentry *parent;
+
+	parent = dentry->d_parent;
+	if (S_ISDIR(dentry->d_inode->i_mode))
+		simple_rmdir(parent->d_inode, dentry);
+	else
+		simple_unlink(parent->d_inode, dentry);
+	d_delete(dentry);
+	dput(dentry);
+}
+
+static void hypfs_delete_tree(struct dentry *root)
+{
+	while (hypfs_last_dentry) {
+		struct dentry *next_dentry;
+		next_dentry = hypfs_last_dentry->d_fsdata;
+		hypfs_remove(hypfs_last_dentry);
+		hypfs_last_dentry = next_dentry;
+	}
+}
+
+static struct inode *hypfs_make_inode(struct super_block *sb, int mode)
+{
+	struct inode *ret = new_inode(sb);
+
+	if (ret) {
+		struct hypfs_sb_info *hypfs_info = sb->s_fs_info;
+		ret->i_mode = mode;
+		ret->i_uid = hypfs_info->uid;
+		ret->i_gid = hypfs_info->gid;
+		ret->i_blocks = 0;
+		ret->i_atime = ret->i_mtime = ret->i_ctime = CURRENT_TIME;
+		if (mode & S_IFDIR)
+			ret->i_nlink = 2;
+		else
+			ret->i_nlink = 1;
+	}
+	return ret;
+}
+
+static void hypfs_drop_inode(struct inode *inode)
+{
+	kfree(inode->i_private);
+	generic_delete_inode(inode);
+}
+
+static int hypfs_open(struct inode *inode, struct file *filp)
+{
+	char *data = filp->f_dentry->d_inode->i_private;
+	struct hypfs_sb_info *fs_info;
+
+	if (filp->f_mode & FMODE_WRITE) {
+		if (!(inode->i_mode & S_IWUGO))
+			return -EACCES;
+	}
+	if (filp->f_mode & FMODE_READ) {
+		if (!(inode->i_mode & S_IRUGO))
+			return -EACCES;
+	}
+
+	fs_info = inode->i_sb->s_fs_info;
+	if(data) {
+		mutex_lock(&fs_info->lock);
+		filp->private_data = kstrdup(data, GFP_KERNEL);
+		if (!filp->private_data) {
+			mutex_unlock(&fs_info->lock);
+			return -ENOMEM;
+		}
+		mutex_unlock(&fs_info->lock);
+	}
+	return 0;
+}
+
+static ssize_t hypfs_aio_read(struct kiocb *iocb, __user char *buf,
+			      size_t count, loff_t offset)
+{
+	char *data;
+	size_t len;
+	struct file *filp = iocb->ki_filp;
+
+	data = filp->private_data;
+	len = strlen(data);
+	if (offset > len) {
+		count = 0;
+		goto out;
+	}
+	if (count > len - offset)
+		count = len - offset;
+	if (copy_to_user(buf, data + offset, count)) {
+		count = -EFAULT;
+		goto out;
+	}
+	iocb->ki_pos += count;
+	file_accessed(filp);
+out:
+	return count;
+}
+static ssize_t hypfs_aio_write(struct kiocb *iocb, const char __user *buf,
+			       size_t count, loff_t pos)
+{
+	int rc;
+	struct super_block *sb;
+	struct hypfs_sb_info *fs_info;
+
+	sb = iocb->ki_filp->f_dentry->d_inode->i_sb;
+	fs_info = sb->s_fs_info;
+	/*
+	 * Currently we only allow one update per second for two reasons:
+	 * 1. diag 204 is VERY expensive
+	 * 2. If several processes do updates in parallel and then read the
+	 *    hypfs data, the likelihood of collisions is reduced, if we restrict
+	 *    the minimum update interval. A collision occurs, if during the
+	 *    data gathering of one process another process triggers an update
+	 *    If the first process wants to ensure consistent data, it has
+	 *    to restart data collection in this case.
+	 */
+	mutex_lock(&fs_info->lock);
+	if (fs_info->last_update == get_seconds()) {
+		rc = -EBUSY;
+		goto out;
+	}
+	hypfs_delete_tree(sb->s_root);
+	rc = hypfs_diag_create_files(sb, sb->s_root);
+	if (rc) {
+		printk(KERN_ERR "hypfs: Update failed\n");
+		hypfs_delete_tree(sb->s_root);
+		goto out;
+	}
+	hypfs_update_update(sb);
+	rc = count;
+out:
+	mutex_unlock(&fs_info->lock);
+	return rc;
+}
+
+static int hypfs_release(struct inode *inode, struct file *filp)
+{
+	kfree(filp->private_data);
+	return 0;
+}
+
+enum { opt_uid, opt_gid, opt_err };
+
+static match_table_t hypfs_tokens = {
+	{opt_uid, "uid=%u"},
+	{opt_gid, "gid=%u"},
+	{opt_err, NULL}
+};
+
+static int hypfs_parse_options(char *options, struct super_block *sb)
+{
+	char *str;
+	substring_t args[MAX_OPT_ARGS];
+
+	if (!options)
+		return 0;
+	while ((str = strsep(&options, ",")) != NULL) {
+		int token, option;
+		struct hypfs_sb_info *hypfs_info = sb->s_fs_info;
+
+		if (!*str)
+			continue;
+		token = match_token(str, hypfs_tokens, args);
+		switch (token) {
+		case opt_uid:
+			if (match_int(&args[0], &option))
+				return -EINVAL;
+			hypfs_info->uid = option;
+			break;
+		case opt_gid:
+			if (match_int(&args[0], &option))
+				return -EINVAL;
+			hypfs_info->gid = option;
+			break;
+		case opt_err:
+		default:
+			printk(KERN_ERR "hypfs: Unrecognized mount option "
+			       "\"%s\" or missing value\n", str);
+			return -EINVAL;
+		}
+	}
+	return 0;
+}
+
+static int hypfs_fill_super(struct super_block *sb, void *data, int silent)
+{
+	struct inode *root_inode;
+	struct dentry *root_dentry;
+	int rc = 0;
+	struct hypfs_sb_info *sbi;
+
+	sbi = kzalloc(sizeof(struct hypfs_sb_info), GFP_KERNEL);
+	if (!sbi)
+		return -ENOMEM;
+	mutex_init(&sbi->lock);
+	sbi->uid = current->uid;
+	sbi->gid = current->gid;
+	sb->s_fs_info = sbi;
+	sb->s_blocksize = PAGE_CACHE_SIZE;
+	sb->s_blocksize_bits = PAGE_CACHE_SHIFT;
+	sb->s_magic = HYPFS_MAGIC;
+	sb->s_op = &hypfs_s_ops;
+	if (hypfs_parse_options(data, sb)) {
+		rc = -EINVAL;
+		goto err_alloc;
+	}
+	root_inode = hypfs_make_inode(sb, S_IFDIR | 0755);
+	if (!root_inode) {
+		rc = -ENOMEM;
+		goto err_alloc;
+	}
+	root_inode->i_op = &simple_dir_inode_operations;
+	root_inode->i_fop = &simple_dir_operations;
+	root_dentry = d_alloc_root(root_inode);
+	if (!root_dentry) {
+		iput(root_inode);
+		rc = -ENOMEM;
+		goto err_alloc;
+	}
+	rc = hypfs_diag_create_files(sb, root_dentry);
+	if (rc)
+		goto err_tree;
+	sbi->update_file = hypfs_create_update_file(sb, root_dentry);
+	if (IS_ERR(sbi->update_file)) {
+		rc = PTR_ERR(sbi->update_file);
+		goto err_tree;
+	}
+	hypfs_update_update(sb);
+	sb->s_root = root_dentry;
+	return 0;
+
+err_tree:
+	hypfs_delete_tree(root_dentry);
+	d_genocide(root_dentry);
+	dput(root_dentry);
+err_alloc:
+	kfree(sbi);
+	return rc;
+}
+
+static int hypfs_get_super(struct file_system_type *fst, int flags,
+			const char *devname, void *data, struct vfsmount *mnt)
+{
+	return get_sb_single(fst, flags, data, hypfs_fill_super, mnt);
+}
+
+static void hypfs_kill_super(struct super_block *sb)
+{
+	struct hypfs_sb_info *sb_info = sb->s_fs_info;
+
+	hypfs_delete_tree(sb->s_root);
+	hypfs_remove(sb_info->update_file);
+	kfree(sb->s_fs_info);
+	sb->s_fs_info = NULL;
+	kill_litter_super(sb);
+}
+
+static struct dentry *hypfs_create_file(struct super_block *sb,
+					struct dentry *parent, const char *name,
+					char *data, mode_t mode)
+{
+	struct dentry *dentry;
+	struct inode *inode;
+	struct qstr qname;
+
+	qname.name = name;
+	qname.len = strlen(name);
+	qname.hash = full_name_hash(name, qname.len);
+	dentry = lookup_one_len(name, parent, strlen(name));
+	if (IS_ERR(dentry))
+		return ERR_PTR(-ENOMEM);
+	inode = hypfs_make_inode(sb, mode);
+	if (!inode) {
+		dput(dentry);
+		return ERR_PTR(-ENOMEM);
+	}
+	if (mode & S_IFREG) {
+		inode->i_fop = &hypfs_file_ops;
+		if (data)
+			inode->i_size = strlen(data);
+		else
+			inode->i_size = 0;
+	} else if (mode & S_IFDIR) {
+		inode->i_op = &simple_dir_inode_operations;
+		inode->i_fop = &simple_dir_operations;
+		parent->d_inode->i_nlink++;
+	} else
+		BUG();
+	inode->i_private = data;
+	d_instantiate(dentry, inode);
+	dget(dentry);
+	return dentry;
+}
+
+struct dentry *hypfs_mkdir(struct super_block *sb, struct dentry *parent,
+			   const char *name)
+{
+	struct dentry *dentry;
+
+	dentry = hypfs_create_file(sb, parent, name, NULL, S_IFDIR | DIR_MODE);
+	if (IS_ERR(dentry))
+		return dentry;
+	hypfs_add_dentry(dentry);
+	parent->d_inode->i_nlink++;
+	return dentry;
+}
+
+static struct dentry *hypfs_create_update_file(struct super_block *sb,
+					       struct dentry *dir)
+{
+	struct dentry *dentry;
+
+	dentry = hypfs_create_file(sb, dir, "update", NULL,
+				   S_IFREG | UPDATE_FILE_MODE);
+	/*
+	 * We do not put the update file on the 'delete' list with
+	 * hypfs_add_dentry(), since it should not be removed when the tree
+	 * is updated.
+	 */
+	return dentry;
+}
+
+struct dentry *hypfs_create_u64(struct super_block *sb, struct dentry *dir,
+				const char *name, __u64 value)
+{
+	char *buffer;
+	char tmp[TMP_SIZE];
+	struct dentry *dentry;
+
+	snprintf(tmp, TMP_SIZE, "%lld\n", (unsigned long long int)value);
+	buffer = kstrdup(tmp, GFP_KERNEL);
+	if (!buffer)
+		return ERR_PTR(-ENOMEM);
+	dentry =
+	    hypfs_create_file(sb, dir, name, buffer, S_IFREG | REG_FILE_MODE);
+	if (IS_ERR(dentry)) {
+		kfree(buffer);
+		return ERR_PTR(-ENOMEM);
+	}
+	hypfs_add_dentry(dentry);
+	return dentry;
+}
+
+struct dentry *hypfs_create_str(struct super_block *sb, struct dentry *dir,
+				const char *name, char *string)
+{
+	char *buffer;
+	struct dentry *dentry;
+
+	buffer = kmalloc(strlen(string) + 2, GFP_KERNEL);
+	if (!buffer)
+		return ERR_PTR(-ENOMEM);
+	sprintf(buffer, "%s\n", string);
+	dentry =
+	    hypfs_create_file(sb, dir, name, buffer, S_IFREG | REG_FILE_MODE);
+	if (IS_ERR(dentry)) {
+		kfree(buffer);
+		return ERR_PTR(-ENOMEM);
+	}
+	hypfs_add_dentry(dentry);
+	return dentry;
+}
+
+static struct file_operations hypfs_file_ops = {
+	.open		= hypfs_open,
+	.release	= hypfs_release,
+	.read		= do_sync_read,
+	.write		= do_sync_write,
+	.aio_read	= hypfs_aio_read,
+	.aio_write	= hypfs_aio_write,
+};
+
+static struct file_system_type hypfs_type = {
+	.owner		= THIS_MODULE,
+	.name		= "s390_hypfs",
+	.get_sb		= hypfs_get_super,
+	.kill_sb	= hypfs_kill_super
+};
+
+static struct super_operations hypfs_s_ops = {
+	.statfs		= simple_statfs,
+	.drop_inode	= hypfs_drop_inode,
+};
+
+static decl_subsys(s390, NULL, NULL);
+
+static int __init hypfs_init(void)
+{
+	int rc;
+
+	if (MACHINE_IS_VM)
+		return -ENODATA;
+	if (hypfs_diag_init()) {
+		rc = -ENODATA;
+		goto fail_diag;
+	}
+	kset_set_kset_s(&s390_subsys, hypervisor_subsys);
+	rc = subsystem_register(&s390_subsys);
+	if (rc)
+		goto fail_sysfs;
+	rc = register_filesystem(&hypfs_type);
+	if (rc)
+		goto fail_filesystem;
+	return 0;
+
+fail_filesystem:
+	subsystem_unregister(&s390_subsys);
+fail_sysfs:
+	hypfs_diag_exit();
+fail_diag:
+	printk(KERN_ERR "hypfs: Initialization failed with rc = %i.\n", rc);
+	return rc;
+}
+
+static void __exit hypfs_exit(void)
+{
+	hypfs_diag_exit();
+	unregister_filesystem(&hypfs_type);
+	subsystem_unregister(&s390_subsys);
+}
+
+module_init(hypfs_init)
+module_exit(hypfs_exit)
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Michael Holzheu <holzheu@de.ibm.com>");
+MODULE_DESCRIPTION("s390 Hypervisor Filesystem");
diff --git a/arch/s390/kernel/audit.c b/arch/s390/kernel/audit.c
new file mode 100644
index 000000000..0741d9193
--- /dev/null
+++ b/arch/s390/kernel/audit.c
@@ -0,0 +1,66 @@
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/audit.h>
+#include <asm/unistd.h>
+
+static unsigned dir_class[] = {
+#include <asm-generic/audit_dir_write.h>
+~0U
+};
+
+static unsigned read_class[] = {
+#include <asm-generic/audit_read.h>
+~0U
+};
+
+static unsigned write_class[] = {
+#include <asm-generic/audit_write.h>
+~0U
+};
+
+static unsigned chattr_class[] = {
+#include <asm-generic/audit_change_attr.h>
+~0U
+};
+
+int audit_classify_syscall(int abi, unsigned syscall)
+{
+#ifdef CONFIG_COMPAT
+	extern int s390_classify_syscall(unsigned);
+	if (abi == AUDIT_ARCH_S390)
+		return s390_classify_syscall(syscall);
+#endif
+	switch(syscall) {
+	case __NR_open:
+		return 2;
+	case __NR_openat:
+		return 3;
+	case __NR_socketcall:
+		return 4;
+	case __NR_execve:
+		return 5;
+	default:
+		return 0;
+	}
+}
+
+static int __init audit_classes_init(void)
+{
+#ifdef CONFIG_COMPAT
+	extern __u32 s390_dir_class[];
+	extern __u32 s390_write_class[];
+	extern __u32 s390_read_class[];
+	extern __u32 s390_chattr_class[];
+	audit_register_class(AUDIT_CLASS_WRITE_32, s390_write_class);
+	audit_register_class(AUDIT_CLASS_READ_32, s390_read_class);
+	audit_register_class(AUDIT_CLASS_DIR_WRITE_32, s390_dir_class);
+	audit_register_class(AUDIT_CLASS_CHATTR_32, s390_chattr_class);
+#endif
+	audit_register_class(AUDIT_CLASS_WRITE, write_class);
+	audit_register_class(AUDIT_CLASS_READ, read_class);
+	audit_register_class(AUDIT_CLASS_DIR_WRITE, dir_class);
+	audit_register_class(AUDIT_CLASS_CHATTR, chattr_class);
+	return 0;
+}
+
+__initcall(audit_classes_init);
diff --git a/arch/s390/kernel/compat_audit.c b/arch/s390/kernel/compat_audit.c
new file mode 100644
index 000000000..16d9436bf
--- /dev/null
+++ b/arch/s390/kernel/compat_audit.c
@@ -0,0 +1,38 @@
+#undef __s390x__
+#include <asm/unistd.h>
+
+unsigned s390_dir_class[] = {
+#include <asm-generic/audit_dir_write.h>
+~0U
+};
+
+unsigned s390_chattr_class[] = {
+#include <asm-generic/audit_change_attr.h>
+~0U
+};
+
+unsigned s390_write_class[] = {
+#include <asm-generic/audit_write.h>
+~0U
+};
+
+unsigned s390_read_class[] = {
+#include <asm-generic/audit_read.h>
+~0U
+};
+
+int s390_classify_syscall(unsigned syscall)
+{
+	switch(syscall) {
+	case __NR_open:
+		return 2;
+	case __NR_openat:
+		return 3;
+	case __NR_socketcall:
+		return 4;
+	case __NR_execve:
+		return 5;
+	default:
+		return 1;
+	}
+}
diff --git a/arch/s390/kernel/stacktrace.c b/arch/s390/kernel/stacktrace.c
new file mode 100644
index 000000000..d9428a0fc
--- /dev/null
+++ b/arch/s390/kernel/stacktrace.c
@@ -0,0 +1,89 @@
+/*
+ * arch/s390/kernel/stacktrace.c
+ *
+ * Stack trace management functions
+ *
+ *  Copyright (C) IBM Corp. 2006
+ *  Author(s): Heiko Carstens <heiko.carstens@de.ibm.com>
+ */
+
+#include <linux/sched.h>
+#include <linux/stacktrace.h>
+#include <linux/kallsyms.h>
+
+static inline unsigned long save_context_stack(struct stack_trace *trace,
+					       unsigned int *skip,
+					       unsigned long sp,
+					       unsigned long low,
+					       unsigned long high)
+{
+	struct stack_frame *sf;
+	struct pt_regs *regs;
+	unsigned long addr;
+
+	while(1) {
+		sp &= PSW_ADDR_INSN;
+		if (sp < low || sp > high)
+			return sp;
+		sf = (struct stack_frame *)sp;
+		while(1) {
+			addr = sf->gprs[8] & PSW_ADDR_INSN;
+			if (!(*skip))
+				trace->entries[trace->nr_entries++] = addr;
+			else
+				(*skip)--;
+			if (trace->nr_entries >= trace->max_entries)
+				return sp;
+			low = sp;
+			sp = sf->back_chain & PSW_ADDR_INSN;
+			if (!sp)
+				break;
+			if (sp <= low || sp > high - sizeof(*sf))
+				return sp;
+			sf = (struct stack_frame *)sp;
+		}
+		/* Zero backchain detected, check for interrupt frame. */
+		sp = (unsigned long)(sf + 1);
+		if (sp <= low || sp > high - sizeof(*regs))
+			return sp;
+		regs = (struct pt_regs *)sp;
+		addr = regs->psw.addr & PSW_ADDR_INSN;
+		if (!(*skip))
+			trace->entries[trace->nr_entries++] = addr;
+		else
+			(*skip)--;
+		if (trace->nr_entries >= trace->max_entries)
+			return sp;
+		low = sp;
+		sp = regs->gprs[15];
+	}
+}
+
+void save_stack_trace(struct stack_trace *trace, struct task_struct *task)
+{
+	register unsigned long sp asm ("15");
+	unsigned long orig_sp;
+
+	sp &= PSW_ADDR_INSN;
+	orig_sp = sp;
+
+	sp = save_context_stack(trace, &trace->skip, sp,
+				S390_lowcore.panic_stack - PAGE_SIZE,
+				S390_lowcore.panic_stack);
+	if ((sp != orig_sp) && !trace->all_contexts)
+		return;
+	sp = save_context_stack(trace, &trace->skip, sp,
+				S390_lowcore.async_stack - ASYNC_SIZE,
+				S390_lowcore.async_stack);
+	if ((sp != orig_sp) && !trace->all_contexts)
+		return;
+	if (task)
+		save_context_stack(trace, &trace->skip, sp,
+				   (unsigned long) task_stack_page(task),
+				   (unsigned long) task_stack_page(task) + THREAD_SIZE);
+	else
+		save_context_stack(trace, &trace->skip, sp,
+				   S390_lowcore.thread_info,
+				   S390_lowcore.thread_info + THREAD_SIZE);
+	return;
+}
diff --git a/arch/s390/lib/div64.c b/arch/s390/lib/div64.c
new file mode 100644
index 000000000..0481f3424
--- /dev/null
+++ b/arch/s390/lib/div64.c
@@ -0,0 +1,151 @@
+/*
+ *  arch/s390/lib/div64.c
+ *
+ *  __div64_32 implementation for 31 bit.
+ *
+ *    Copyright (C) IBM Corp. 2006
+ *    Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com),
+ */
+
+#include <linux/types.h>
+#include <linux/module.h>
+
+#ifdef CONFIG_MARCH_G5
+
+/*
+ * Function to divide an unsigned 64 bit integer by an unsigned
+ * 31 bit integer using signed 64/32 bit division.
+ */
+static uint32_t __div64_31(uint64_t *n, uint32_t base)
+{
+	register uint32_t reg2 asm("2");
+	register uint32_t reg3 asm("3");
+	uint32_t *words = (uint32_t *) n;
+	uint32_t tmp;
+
+	/* Special case base==1, remainder = 0, quotient = n */
+	if (base == 1)
+		return 0;
+	/*
+	 * Special case base==0 will cause a fixed point divide exception
+	 * on the dr instruction and may not happen anyway. For the
+	 * following calculation we can assume base > 1. The first
+	 * signed 64 / 32 bit division with an upper half of 0 will
+	 * give the correct upper half of the 64 bit quotient.
+	 */
+	reg2 = 0UL;
+	reg3 = words[0];
+	asm volatile(
+		"	dr	%0,%2\n"
+		: "+d" (reg2), "+d" (reg3) : "d" (base) : "cc" );
+	words[0] = reg3;
+	reg3 = words[1];
+	/*
+	 * To get the lower half of the 64 bit quotient and the 32 bit
+	 * remainder we have to use a little trick. Since we only have
+	 * a signed division the quotient can get too big. To avoid this
+	 * the 64 bit dividend is halved, then the signed division will
+	 * work. Afterwards the quotient and the remainder are doubled.
+	 * If the last bit of the dividend has been one the remainder
+	 * is increased by one then checked against the base. If the
+	 * remainder has overflown subtract base and increase the
+	 * quotient. Simple, no ?
+	 */
+	asm volatile(
+		"	nr	%2,%1\n"
+		"	srdl	%0,1\n"
+		"	dr	%0,%3\n"
+		"	alr	%0,%0\n"
+		"	alr	%1,%1\n"
+		"	alr	%0,%2\n"
+		"	clr	%0,%3\n"
+		"	jl	0f\n"
+		"	slr	%0,%3\n"
+		"	alr	%1,%2\n"
+		"0:\n"
+		: "+d" (reg2), "+d" (reg3), "=d" (tmp)
+		: "d" (base), "2" (1UL) : "cc" );
+	words[1] = reg3;
+	return reg2;
+}
+
+/*
+ * Function to divide an unsigned 64 bit integer by an unsigned
+ * 32 bit integer using the unsigned 64/31 bit division.
+ */
+uint32_t __div64_32(uint64_t *n, uint32_t base)
+{
+	uint32_t r;
+
+	/*
+	 * If the most significant bit of base is set, divide n by
+	 * (base/2). That allows to use 64/31 bit division and gives a
+	 * good approximation of the result: n = (base/2)*q + r. The
+	 * result needs to be corrected with two simple transformations.
+	 * If base is already < 2^31-1 __div64_31 can be used directly.
+	 */
+	r = __div64_31(n, ((signed) base < 0) ? (base/2) : base);
+	if ((signed) base < 0) {
+		uint64_t q = *n;
+		/*
+		 * First transformation:
+		 * n = (base/2)*q + r
+		 *   = ((base/2)*2)*(q/2) + ((q&1) ? (base/2) : 0) + r
+		 * Since r < (base/2), r + (base/2) < base.
+		 * With q1 = (q/2) and r1 = r + ((q&1) ? (base/2) : 0)
+		 * n = ((base/2)*2)*q1 + r1 with r1 < base.
+		 */
+		if (q & 1)
+			r += base/2;
+		q >>= 1;
+		/*
+		 * Second transformation. ((base/2)*2) could have lost the
+		 * last bit.
+		 * n = ((base/2)*2)*q1 + r1
+		 *   = base*q1 - ((base&1) ? q1 : 0) + r1
+		 */
+		if (base & 1) {
+			int64_t rx = r - q;
+			/*
+			 * base is >= 2^31. The worst case for the while
+			 * loop is n=2^64-1 base=2^31+1. That gives a
+			 * maximum for q=(2^64-1)/2^31 = 0x1ffffffff. Since
+			 * base >= 2^31 the loop is finished after a maximum
+			 * of three iterations.
+			 */
+			while (rx < 0) {
+				rx += base;
+				q--;
+			}
+			r = rx;
+		}
+		*n = q;
+	}
+	return r;
+}
+
+#else /* MARCH_G5 */
+
+uint32_t __div64_32(uint64_t *n, uint32_t base)
+{
+	register uint32_t reg2 asm("2");
+	register uint32_t reg3 asm("3");
+	uint32_t *words = (uint32_t *) n;
+
+	reg2 = 0UL;
+	reg3 = words[0];
+	asm volatile(
+		"	dlr	%0,%2\n"
+		: "+d" (reg2), "+d" (reg3) : "d" (base) : "cc" );
+	words[0] = reg3;
+	reg3 = words[1];
+	asm volatile(
+		"	dlr	%0,%2\n"
+		: "+d" (reg2), "+d" (reg3) : "d" (base) : "cc" );
+	words[1] = reg3;
+	return reg2;
+}
+
+#endif /* MARCH_G5 */
+
+EXPORT_SYMBOL(__div64_32);
diff --git a/arch/sparc/kernel/of_device.c b/arch/sparc/kernel/of_device.c
new file mode 100644
index 000000000..74bef2a2d
--- /dev/null
+++ b/arch/sparc/kernel/of_device.c
@@ -0,0 +1,823 @@
+#include <linux/string.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/mod_devicetable.h>
+#include <linux/slab.h>
+
+#include <asm/errno.h>
+#include <asm/of_device.h>
+
+/**
+ * of_match_device - Tell if an of_device structure has a matching
+ * of_match structure
+ * @ids: array of of device match structures to search in
+ * @dev: the of device structure to match against
+ *
+ * Used by a driver to check whether an of_device present in the
+ * system is in its list of supported devices.
+ */
+const struct of_device_id *of_match_device(const struct of_device_id *matches,
+					const struct of_device *dev)
+{
+	if (!dev->node)
+		return NULL;
+	while (matches->name[0] || matches->type[0] || matches->compatible[0]) {
+		int match = 1;
+		if (matches->name[0])
+			match &= dev->node->name
+				&& !strcmp(matches->name, dev->node->name);
+		if (matches->type[0])
+			match &= dev->node->type
+				&& !strcmp(matches->type, dev->node->type);
+		if (matches->compatible[0])
+			match &= of_device_is_compatible(dev->node,
+							 matches->compatible);
+		if (match)
+			return matches;
+		matches++;
+	}
+	return NULL;
+}
+
+static int of_platform_bus_match(struct device *dev, struct device_driver *drv)
+{
+	struct of_device * of_dev = to_of_device(dev);
+	struct of_platform_driver * of_drv = to_of_platform_driver(drv);
+	const struct of_device_id * matches = of_drv->match_table;
+
+	if (!matches)
+		return 0;
+
+	return of_match_device(matches, of_dev) != NULL;
+}
+
+struct of_device *of_dev_get(struct of_device *dev)
+{
+	struct device *tmp;
+
+	if (!dev)
+		return NULL;
+	tmp = get_device(&dev->dev);
+	if (tmp)
+		return to_of_device(tmp);
+	else
+		return NULL;
+}
+
+void of_dev_put(struct of_device *dev)
+{
+	if (dev)
+		put_device(&dev->dev);
+}
+
+
+static int of_device_probe(struct device *dev)
+{
+	int error = -ENODEV;
+	struct of_platform_driver *drv;
+	struct of_device *of_dev;
+	const struct of_device_id *match;
+
+	drv = to_of_platform_driver(dev->driver);
+	of_dev = to_of_device(dev);
+
+	if (!drv->probe)
+		return error;
+
+	of_dev_get(of_dev);
+
+	match = of_match_device(drv->match_table, of_dev);
+	if (match)
+		error = drv->probe(of_dev, match);
+	if (error)
+		of_dev_put(of_dev);
+
+	return error;
+}
+
+static int of_device_remove(struct device *dev)
+{
+	struct of_device * of_dev = to_of_device(dev);
+	struct of_platform_driver * drv = to_of_platform_driver(dev->driver);
+
+	if (dev->driver && drv->remove)
+		drv->remove(of_dev);
+	return 0;
+}
+
+static int of_device_suspend(struct device *dev, pm_message_t state)
+{
+	struct of_device * of_dev = to_of_device(dev);
+	struct of_platform_driver * drv = to_of_platform_driver(dev->driver);
+	int error = 0;
+
+	if (dev->driver && drv->suspend)
+		error = drv->suspend(of_dev, state);
+	return error;
+}
+
+static int of_device_resume(struct device * dev)
+{
+	struct of_device * of_dev = to_of_device(dev);
+	struct of_platform_driver * drv = to_of_platform_driver(dev->driver);
+	int error = 0;
+
+	if (dev->driver && drv->resume)
+		error = drv->resume(of_dev);
+	return error;
+}
+
+static int node_match(struct device *dev, void *data)
+{
+	struct of_device *op = to_of_device(dev);
+	struct device_node *dp = data;
+
+	return (op->node == dp);
+}
+
+struct of_device *of_find_device_by_node(struct device_node *dp)
+{
+	struct device *dev = bus_find_device(&of_bus_type, NULL,
+					     dp, node_match);
+
+	if (dev)
+		return to_of_device(dev);
+
+	return NULL;
+}
+EXPORT_SYMBOL(of_find_device_by_node);
+
+#ifdef CONFIG_PCI
+struct bus_type ebus_bus_type = {
+       .name	= "ebus",
+       .match	= of_platform_bus_match,
+       .probe	= of_device_probe,
+       .remove	= of_device_remove,
+       .suspend	= of_device_suspend,
+       .resume	= of_device_resume,
+};
+EXPORT_SYMBOL(ebus_bus_type);
+#endif
+
+#ifdef CONFIG_SBUS
+struct bus_type sbus_bus_type = {
+       .name	= "sbus",
+       .match	= of_platform_bus_match,
+       .probe	= of_device_probe,
+       .remove	= of_device_remove,
+       .suspend	= of_device_suspend,
+       .resume	= of_device_resume,
+};
+EXPORT_SYMBOL(sbus_bus_type);
+#endif
+
+struct bus_type of_bus_type = {
+       .name	= "of",
+       .match	= of_platform_bus_match,
+       .probe	= of_device_probe,
+       .remove	= of_device_remove,
+       .suspend	= of_device_suspend,
+       .resume	= of_device_resume,
+};
+EXPORT_SYMBOL(of_bus_type);
+
+static inline u64 of_read_addr(const u32 *cell, int size)
+{
+	u64 r = 0;
+	while (size--)
+		r = (r << 32) | *(cell++);
+	return r;
+}
+
+static void __init get_cells(struct device_node *dp,
+			     int *addrc, int *sizec)
+{
+	if (addrc)
+		*addrc = of_n_addr_cells(dp);
+	if (sizec)
+		*sizec = of_n_size_cells(dp);
+}
+
+/* Max address size we deal with */
+#define OF_MAX_ADDR_CELLS	4
+
+struct of_bus {
+	const char	*name;
+	const char	*addr_prop_name;
+	int		(*match)(struct device_node *parent);
+	void		(*count_cells)(struct device_node *child,
+				       int *addrc, int *sizec);
+	int		(*map)(u32 *addr, const u32 *range,
+			       int na, int ns, int pna);
+	unsigned int	(*get_flags)(u32 *addr);
+};
+
+/*
+ * Default translator (generic bus)
+ */
+
+static void of_bus_default_count_cells(struct device_node *dev,
+				       int *addrc, int *sizec)
+{
+	get_cells(dev, addrc, sizec);
+}
+
+/* Make sure the least significant 64-bits are in-range.  Even
+ * for 3 or 4 cell values it is a good enough approximation.
+ */
+static int of_out_of_range(const u32 *addr, const u32 *base,
+			   const u32 *size, int na, int ns)
+{
+	u64 a = of_read_addr(addr, na);
+	u64 b = of_read_addr(base, na);
+
+	if (a < b)
+		return 1;
+
+	b += of_read_addr(size, ns);
+	if (a >= b)
+		return 1;
+
+	return 0;
+}
+
+static int of_bus_default_map(u32 *addr, const u32 *range,
+			      int na, int ns, int pna)
+{
+	u32 result[OF_MAX_ADDR_CELLS];
+	int i;
+
+	if (ns > 2) {
+		printk("of_device: Cannot handle size cells (%d) > 2.", ns);
+		return -EINVAL;
+	}
+
+	if (of_out_of_range(addr, range, range + na + pna, na, ns))
+		return -EINVAL;
+
+	/* Start with the parent range base.  */
+	memcpy(result, range + na, pna * 4);
+
+	/* Add in the child address offset.  */
+	for (i = 0; i < na; i++)
+		result[pna - 1 - i] +=
+			(addr[na - 1 - i] -
+			 range[na - 1 - i]);
+
+	memcpy(addr, result, pna * 4);
+
+	return 0;
+}
+
+static unsigned int of_bus_default_get_flags(u32 *addr)
+{
+	return IORESOURCE_MEM;
+}
+
+/*
+ * PCI bus specific translator
+ */
+
+static int of_bus_pci_match(struct device_node *np)
+{
+	if (!strcmp(np->type, "pci") || !strcmp(np->type, "pciex")) {
+		/* Do not do PCI specific frobbing if the
+		 * PCI bridge lacks a ranges property.  We
+		 * want to pass it through up to the next
+		 * parent as-is, not with the PCI translate
+		 * method which chops off the top address cell.
+		 */
+		if (!of_find_property(np, "ranges", NULL))
+			return 0;
+
+		return 1;
+	}
+
+	return 0;
+}
+
+static void of_bus_pci_count_cells(struct device_node *np,
+				   int *addrc, int *sizec)
+{
+	if (addrc)
+		*addrc = 3;
+	if (sizec)
+		*sizec = 2;
+}
+
+static int of_bus_pci_map(u32 *addr, const u32 *range,
+			  int na, int ns, int pna)
+{
+	u32 result[OF_MAX_ADDR_CELLS];
+	int i;
+
+	/* Check address type match */
+	if ((addr[0] ^ range[0]) & 0x03000000)
+		return -EINVAL;
+
+	if (of_out_of_range(addr + 1, range + 1, range + na + pna,
+			    na - 1, ns))
+		return -EINVAL;
+
+	/* Start with the parent range base.  */
+	memcpy(result, range + na, pna * 4);
+
+	/* Add in the child address offset, skipping high cell.  */
+	for (i = 0; i < na - 1; i++)
+		result[pna - 1 - i] +=
+			(addr[na - 1 - i] -
+			 range[na - 1 - i]);
+
+	memcpy(addr, result, pna * 4);
+
+	return 0;
+}
+
+static unsigned int of_bus_pci_get_flags(u32 *addr)
+{
+	unsigned int flags = 0;
+	u32 w = addr[0];
+
+	switch((w >> 24) & 0x03) {
+	case 0x01:
+		flags |= IORESOURCE_IO;
+	case 0x02: /* 32 bits */
+	case 0x03: /* 64 bits */
+		flags |= IORESOURCE_MEM;
+	}
+	if (w & 0x40000000)
+		flags |= IORESOURCE_PREFETCH;
+	return flags;
+}
+
+/*
+ * SBUS bus specific translator
+ */
+
+static int of_bus_sbus_match(struct device_node *np)
+{
+	return !strcmp(np->name, "sbus") ||
+		!strcmp(np->name, "sbi");
+}
+
+static void of_bus_sbus_count_cells(struct device_node *child,
+				   int *addrc, int *sizec)
+{
+	if (addrc)
+		*addrc = 2;
+	if (sizec)
+		*sizec = 1;
+}
+
+static int of_bus_sbus_map(u32 *addr, const u32 *range, int na, int ns, int pna)
+{
+	return of_bus_default_map(addr, range, na, ns, pna);
+}
+
+static unsigned int of_bus_sbus_get_flags(u32 *addr)
+{
+	return IORESOURCE_MEM;
+}
+
+
+/*
+ * Array of bus specific translators
+ */
+
+static struct of_bus of_busses[] = {
+	/* PCI */
+	{
+		.name = "pci",
+		.addr_prop_name = "assigned-addresses",
+		.match = of_bus_pci_match,
+		.count_cells = of_bus_pci_count_cells,
+		.map = of_bus_pci_map,
+		.get_flags = of_bus_pci_get_flags,
+	},
+	/* SBUS */
+	{
+		.name = "sbus",
+		.addr_prop_name = "reg",
+		.match = of_bus_sbus_match,
+		.count_cells = of_bus_sbus_count_cells,
+		.map = of_bus_sbus_map,
+		.get_flags = of_bus_sbus_get_flags,
+	},
+	/* Default */
+	{
+		.name = "default",
+		.addr_prop_name = "reg",
+		.match = NULL,
+		.count_cells = of_bus_default_count_cells,
+		.map = of_bus_default_map,
+		.get_flags = of_bus_default_get_flags,
+	},
+};
+
+static struct of_bus *of_match_bus(struct device_node *np)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(of_busses); i ++)
+		if (!of_busses[i].match || of_busses[i].match(np))
+			return &of_busses[i];
+	BUG();
+	return NULL;
+}
+
+static int __init build_one_resource(struct device_node *parent,
+				     struct of_bus *bus,
+				     struct of_bus *pbus,
+				     u32 *addr,
+				     int na, int ns, int pna)
+{
+	u32 *ranges;
+	unsigned int rlen;
+	int rone;
+
+	ranges = of_get_property(parent, "ranges", &rlen);
+	if (ranges == NULL || rlen == 0) {
+		u32 result[OF_MAX_ADDR_CELLS];
+		int i;
+
+		memset(result, 0, pna * 4);
+		for (i = 0; i < na; i++)
+			result[pna - 1 - i] =
+				addr[na - 1 - i];
+
+		memcpy(addr, result, pna * 4);
+		return 0;
+	}
+
+	/* Now walk through the ranges */
+	rlen /= 4;
+	rone = na + pna + ns;
+	for (; rlen >= rone; rlen -= rone, ranges += rone) {
+		if (!bus->map(addr, ranges, na, ns, pna))
+			return 0;
+	}
+
+	return 1;
+}
+
+static int of_resource_verbose;
+
+static void __init build_device_resources(struct of_device *op,
+					  struct device *parent)
+{
+	struct of_device *p_op;
+	struct of_bus *bus;
+	int na, ns;
+	int index, num_reg;
+	void *preg;
+
+	if (!parent)
+		return;
+
+	p_op = to_of_device(parent);
+	bus = of_match_bus(p_op->node);
+	bus->count_cells(op->node, &na, &ns);
+
+	preg = of_get_property(op->node, bus->addr_prop_name, &num_reg);
+	if (!preg || num_reg == 0)
+		return;
+
+	/* Convert to num-cells.  */
+	num_reg /= 4;
+
+	/* Conver to num-entries.  */
+	num_reg /= na + ns;
+
+	for (index = 0; index < num_reg; index++) {
+		struct resource *r = &op->resource[index];
+		u32 addr[OF_MAX_ADDR_CELLS];
+		u32 *reg = (preg + (index * ((na + ns) * 4)));
+		struct device_node *dp = op->node;
+		struct device_node *pp = p_op->node;
+		struct of_bus *pbus;
+		u64 size, result = OF_BAD_ADDR;
+		unsigned long flags;
+		int dna, dns;
+		int pna, pns;
+
+		size = of_read_addr(reg + na, ns);
+		flags = bus->get_flags(reg);
+
+		memcpy(addr, reg, na * 4);
+
+		/* If the immediate parent has no ranges property to apply,
+		 * just use a 1<->1 mapping.
+		 */
+		if (of_find_property(pp, "ranges", NULL) == NULL) {
+			result = of_read_addr(addr, na);
+			goto build_res;
+		}
+
+		dna = na;
+		dns = ns;
+
+		while (1) {
+			dp = pp;
+			pp = dp->parent;
+			if (!pp) {
+				result = of_read_addr(addr, dna);
+				break;
+			}
+
+			pbus = of_match_bus(pp);
+			pbus->count_cells(dp, &pna, &pns);
+
+			if (build_one_resource(dp, bus, pbus, addr,
+					       dna, dns, pna))
+				break;
+
+			dna = pna;
+			dns = pns;
+			bus = pbus;
+		}
+
+	build_res:
+		memset(r, 0, sizeof(*r));
+
+		if (of_resource_verbose)
+			printk("%s reg[%d] -> %llx\n",
+			       op->node->full_name, index,
+			       result);
+
+		if (result != OF_BAD_ADDR) {
+			r->start = result & 0xffffffff;
+			r->end = result + size - 1;
+			r->flags = flags | ((result >> 32ULL) & 0xffUL);
+		} else {
+			r->start = ~0UL;
+			r->end = ~0UL;
+		}
+		r->name = op->node->name;
+	}
+}
+
+static struct of_device * __init scan_one_device(struct device_node *dp,
+						 struct device *parent)
+{
+	struct of_device *op = kzalloc(sizeof(*op), GFP_KERNEL);
+	struct linux_prom_irqs *intr;
+	int len, i;
+
+	if (!op)
+		return NULL;
+
+	op->node = dp;
+
+	op->clock_freq = of_getintprop_default(dp, "clock-frequency",
+					       (25*1000*1000));
+	op->portid = of_getintprop_default(dp, "upa-portid", -1);
+	if (op->portid == -1)
+		op->portid = of_getintprop_default(dp, "portid", -1);
+
+	intr = of_get_property(dp, "intr", &len);
+	if (intr) {
+		op->num_irqs = len / sizeof(struct linux_prom_irqs);
+		for (i = 0; i < op->num_irqs; i++)
+			op->irqs[i] = intr[i].pri;
+	} else {
+		unsigned int *irq = of_get_property(dp, "interrupts", &len);
+
+		if (irq) {
+			op->num_irqs = len / sizeof(unsigned int);
+			for (i = 0; i < op->num_irqs; i++)
+				op->irqs[i] = irq[i];
+		} else {
+			op->num_irqs = 0;
+		}
+	}
+	if (sparc_cpu_model == sun4d) {
+		static int pil_to_sbus[] = {
+			0, 0, 1, 2, 0, 3, 0, 4, 0, 5, 0, 6, 0, 7, 0, 0,
+		};
+		struct device_node *io_unit, *sbi = dp->parent;
+		struct linux_prom_registers *regs;
+		int board, slot;
+
+		while (sbi) {
+			if (!strcmp(sbi->name, "sbi"))
+				break;
+
+			sbi = sbi->parent;
+		}
+		if (!sbi)
+			goto build_resources;
+
+		regs = of_get_property(dp, "reg", NULL);
+		if (!regs)
+			goto build_resources;
+
+		slot = regs->which_io;
+
+		/* If SBI's parent is not io-unit or the io-unit lacks
+		 * a "board#" property, something is very wrong.
+		 */
+		if (!sbi->parent || strcmp(sbi->parent->name, "io-unit")) {
+			printk("%s: Error, parent is not io-unit.\n",
+			       sbi->full_name);
+			goto build_resources;
+		}
+		io_unit = sbi->parent;
+		board = of_getintprop_default(io_unit, "board#", -1);
+		if (board == -1) {
+			printk("%s: Error, lacks board# property.\n",
+			       io_unit->full_name);
+			goto build_resources;
+		}
+
+		for (i = 0; i < op->num_irqs; i++) {
+			int this_irq = op->irqs[i];
+			int sbusl = pil_to_sbus[this_irq];
+
+			if (sbusl)
+				this_irq = (((board + 1) << 5) +
+					    (sbusl << 2) +
+					    slot);
+
+			op->irqs[i] = this_irq;
+		}
+	}
+
+build_resources:
+	build_device_resources(op, parent);
+
+	op->dev.parent = parent;
+	op->dev.bus = &of_bus_type;
+	if (!parent)
+		strcpy(op->dev.bus_id, "root");
+	else
+		strcpy(op->dev.bus_id, dp->path_component_name);
+
+	if (of_device_register(op)) {
+		printk("%s: Could not register of device.\n",
+		       dp->full_name);
+		kfree(op);
+		op = NULL;
+	}
+
+	return op;
+}
+
+static void __init scan_tree(struct device_node *dp, struct device *parent)
+{
+	while (dp) {
+		struct of_device *op = scan_one_device(dp, parent);
+
+		if (op)
+			scan_tree(dp->child, &op->dev);
+
+		dp = dp->sibling;
+	}
+}
+
+static void __init scan_of_devices(void)
+{
+	struct device_node *root = of_find_node_by_path("/");
+	struct of_device *parent;
+
+	parent = scan_one_device(root, NULL);
+	if (!parent)
+		return;
+
+	scan_tree(root->child, &parent->dev);
+}
+
+static int __init of_bus_driver_init(void)
+{
+	int err;
+
+	err = bus_register(&of_bus_type);
+#ifdef CONFIG_PCI
+	if (!err)
+		err = bus_register(&ebus_bus_type);
+#endif
+#ifdef CONFIG_SBUS
+	if (!err)
+		err = bus_register(&sbus_bus_type);
+#endif
+
+	if (!err)
+		scan_of_devices();
+
+	return err;
+}
+
+postcore_initcall(of_bus_driver_init);
+
+static int __init of_debug(char *str)
+{
+	int val = 0;
+
+	get_option(&str, &val);
+	if (val & 1)
+		of_resource_verbose = 1;
+	return 1;
+}
+
+__setup("of_debug=", of_debug);
+
+int of_register_driver(struct of_platform_driver *drv, struct bus_type *bus)
+{
+	/* initialize common driver fields */
+	drv->driver.name = drv->name;
+	drv->driver.bus = bus;
+
+	/* register with core */
+	return driver_register(&drv->driver);
+}
+
+void of_unregister_driver(struct of_platform_driver *drv)
+{
+	driver_unregister(&drv->driver);
+}
+
+
+static ssize_t dev_show_devspec(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	struct of_device *ofdev;
+
+	ofdev = to_of_device(dev);
+	return sprintf(buf, "%s", ofdev->node->full_name);
+}
+
+static DEVICE_ATTR(devspec, S_IRUGO, dev_show_devspec, NULL);
+
+/**
+ * of_release_dev - free an of device structure when all users of it are finished.
+ * @dev: device that's been disconnected
+ *
+ * Will be called only by the device core when all users of this of device are
+ * done.
+ */
+void of_release_dev(struct device *dev)
+{
+	struct of_device *ofdev;
+
+        ofdev = to_of_device(dev);
+
+	kfree(ofdev);
+}
+
+int of_device_register(struct of_device *ofdev)
+{
+	int rc;
+
+	BUG_ON(ofdev->node == NULL);
+
+	rc = device_register(&ofdev->dev);
+	if (rc)
+		return rc;
+
+	rc = device_create_file(&ofdev->dev, &dev_attr_devspec);
+	if (rc)
+		device_unregister(&ofdev->dev);
+
+	return rc;
+}
+
+void of_device_unregister(struct of_device *ofdev)
+{
+	device_remove_file(&ofdev->dev, &dev_attr_devspec);
+	device_unregister(&ofdev->dev);
+}
+
+struct of_device* of_platform_device_create(struct device_node *np,
+					    const char *bus_id,
+					    struct device *parent,
+					    struct bus_type *bus)
+{
+	struct of_device *dev;
+
+	dev = kmalloc(sizeof(*dev), GFP_KERNEL);
+	if (!dev)
+		return NULL;
+	memset(dev, 0, sizeof(*dev));
+
+	dev->dev.parent = parent;
+	dev->dev.bus = bus;
+	dev->dev.release = of_release_dev;
+
+	strlcpy(dev->dev.bus_id, bus_id, BUS_ID_SIZE);
+
+	if (of_device_register(dev) != 0) {
+		kfree(dev);
+		return NULL;
+	}
+
+	return dev;
+}
+
+EXPORT_SYMBOL(of_match_device);
+EXPORT_SYMBOL(of_register_driver);
+EXPORT_SYMBOL(of_unregister_driver);
+EXPORT_SYMBOL(of_device_register);
+EXPORT_SYMBOL(of_device_unregister);
+EXPORT_SYMBOL(of_dev_get);
+EXPORT_SYMBOL(of_dev_put);
+EXPORT_SYMBOL(of_platform_device_create);
+EXPORT_SYMBOL(of_release_dev);
diff --git a/arch/sparc/kernel/prom.c b/arch/sparc/kernel/prom.c
new file mode 100644
index 000000000..4ca9e5fc9
--- /dev/null
+++ b/arch/sparc/kernel/prom.c
@@ -0,0 +1,577 @@
+/*
+ * Procedures for creating, accessing and interpreting the device tree.
+ *
+ * Paul Mackerras	August 1996.
+ * Copyright (C) 1996-2005 Paul Mackerras.
+ * 
+ *  Adapted for 64bit PowerPC by Dave Engebretsen and Peter Bergner.
+ *    {engebret|bergner}@us.ibm.com 
+ *
+ *  Adapted for sparc32 by David S. Miller davem@davemloft.net
+ *
+ *      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/kernel.h>
+#include <linux/types.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/bootmem.h>
+#include <linux/module.h>
+
+#include <asm/prom.h>
+#include <asm/oplib.h>
+
+static struct device_node *allnodes;
+
+/* use when traversing tree through the allnext, child, sibling,
+ * or parent members of struct device_node.
+ */
+static DEFINE_RWLOCK(devtree_lock);
+
+int of_device_is_compatible(struct device_node *device, const char *compat)
+{
+	const char* cp;
+	int cplen, l;
+
+	cp = (char *) of_get_property(device, "compatible", &cplen);
+	if (cp == NULL)
+		return 0;
+	while (cplen > 0) {
+		if (strncmp(cp, compat, strlen(compat)) == 0)
+			return 1;
+		l = strlen(cp) + 1;
+		cp += l;
+		cplen -= l;
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL(of_device_is_compatible);
+
+struct device_node *of_get_parent(const struct device_node *node)
+{
+	struct device_node *np;
+
+	if (!node)
+		return NULL;
+
+	np = node->parent;
+
+	return np;
+}
+EXPORT_SYMBOL(of_get_parent);
+
+struct device_node *of_get_next_child(const struct device_node *node,
+	struct device_node *prev)
+{
+	struct device_node *next;
+
+	next = prev ? prev->sibling : node->child;
+	for (; next != 0; next = next->sibling) {
+		break;
+	}
+
+	return next;
+}
+EXPORT_SYMBOL(of_get_next_child);
+
+struct device_node *of_find_node_by_path(const char *path)
+{
+	struct device_node *np = allnodes;
+
+	for (; np != 0; np = np->allnext) {
+		if (np->full_name != 0 && strcmp(np->full_name, path) == 0)
+			break;
+	}
+
+	return np;
+}
+EXPORT_SYMBOL(of_find_node_by_path);
+
+struct device_node *of_find_node_by_phandle(phandle handle)
+{
+	struct device_node *np;
+
+	for (np = allnodes; np != 0; np = np->allnext)
+		if (np->node == handle)
+			break;
+
+	return np;
+}
+EXPORT_SYMBOL(of_find_node_by_phandle);
+
+struct device_node *of_find_node_by_name(struct device_node *from,
+	const char *name)
+{
+	struct device_node *np;
+
+	np = from ? from->allnext : allnodes;
+	for (; np != NULL; np = np->allnext)
+		if (np->name != NULL && strcmp(np->name, name) == 0)
+			break;
+
+	return np;
+}
+EXPORT_SYMBOL(of_find_node_by_name);
+
+struct device_node *of_find_node_by_type(struct device_node *from,
+	const char *type)
+{
+	struct device_node *np;
+
+	np = from ? from->allnext : allnodes;
+	for (; np != 0; np = np->allnext)
+		if (np->type != 0 && strcmp(np->type, type) == 0)
+			break;
+
+	return np;
+}
+EXPORT_SYMBOL(of_find_node_by_type);
+
+struct device_node *of_find_compatible_node(struct device_node *from,
+	const char *type, const char *compatible)
+{
+	struct device_node *np;
+
+	np = from ? from->allnext : allnodes;
+	for (; np != 0; np = np->allnext) {
+		if (type != NULL
+		    && !(np->type != 0 && strcmp(np->type, type) == 0))
+			continue;
+		if (of_device_is_compatible(np, compatible))
+			break;
+	}
+
+	return np;
+}
+EXPORT_SYMBOL(of_find_compatible_node);
+
+struct property *of_find_property(struct device_node *np, const char *name,
+				  int *lenp)
+{
+	struct property *pp;
+
+	for (pp = np->properties; pp != 0; pp = pp->next) {
+		if (strcmp(pp->name, name) == 0) {
+			if (lenp != 0)
+				*lenp = pp->length;
+			break;
+		}
+	}
+	return pp;
+}
+EXPORT_SYMBOL(of_find_property);
+
+/*
+ * Find a property with a given name for a given node
+ * and return the value.
+ */
+void *of_get_property(struct device_node *np, const char *name, int *lenp)
+{
+	struct property *pp = of_find_property(np,name,lenp);
+	return pp ? pp->value : NULL;
+}
+EXPORT_SYMBOL(of_get_property);
+
+int of_getintprop_default(struct device_node *np, const char *name, int def)
+{
+	struct property *prop;
+	int len;
+
+	prop = of_find_property(np, name, &len);
+	if (!prop || len != 4)
+		return def;
+
+	return *(int *) prop->value;
+}
+EXPORT_SYMBOL(of_getintprop_default);
+
+int of_n_addr_cells(struct device_node *np)
+{
+	int* ip;
+	do {
+		if (np->parent)
+			np = np->parent;
+		ip = of_get_property(np, "#address-cells", NULL);
+		if (ip != NULL)
+			return *ip;
+	} while (np->parent);
+	/* No #address-cells property for the root node, default to 2 */
+	return 2;
+}
+EXPORT_SYMBOL(of_n_addr_cells);
+
+int of_n_size_cells(struct device_node *np)
+{
+	int* ip;
+	do {
+		if (np->parent)
+			np = np->parent;
+		ip = of_get_property(np, "#size-cells", NULL);
+		if (ip != NULL)
+			return *ip;
+	} while (np->parent);
+	/* No #size-cells property for the root node, default to 1 */
+	return 1;
+}
+EXPORT_SYMBOL(of_n_size_cells);
+
+int of_set_property(struct device_node *dp, const char *name, void *val, int len)
+{
+	struct property **prevp;
+	void *new_val;
+	int err;
+
+	new_val = kmalloc(len, GFP_KERNEL);
+	if (!new_val)
+		return -ENOMEM;
+
+	memcpy(new_val, val, len);
+
+	err = -ENODEV;
+
+	write_lock(&devtree_lock);
+	prevp = &dp->properties;
+	while (*prevp) {
+		struct property *prop = *prevp;
+
+		if (!strcmp(prop->name, name)) {
+			void *old_val = prop->value;
+			int ret;
+
+			ret = prom_setprop(dp->node, name, val, len);
+			err = -EINVAL;
+			if (ret >= 0) {
+				prop->value = new_val;
+				prop->length = len;
+
+				if (OF_IS_DYNAMIC(prop))
+					kfree(old_val);
+
+				OF_MARK_DYNAMIC(prop);
+
+				err = 0;
+			}
+			break;
+		}
+		prevp = &(*prevp)->next;
+	}
+	write_unlock(&devtree_lock);
+
+	/* XXX Upate procfs if necessary... */
+
+	return err;
+}
+EXPORT_SYMBOL(of_set_property);
+
+static unsigned int prom_early_allocated;
+
+static void * __init prom_early_alloc(unsigned long size)
+{
+	void *ret;
+
+	ret = __alloc_bootmem(size, SMP_CACHE_BYTES, 0UL);
+	if (ret != NULL)
+		memset(ret, 0, size);
+
+	prom_early_allocated += size;
+
+	return ret;
+}
+
+static int is_root_node(const struct device_node *dp)
+{
+	if (!dp)
+		return 0;
+
+	return (dp->parent == NULL);
+}
+
+/* The following routines deal with the black magic of fully naming a
+ * node.
+ *
+ * Certain well known named nodes are just the simple name string.
+ *
+ * Actual devices have an address specifier appended to the base name
+ * string, like this "foo@addr".  The "addr" can be in any number of
+ * formats, and the platform plus the type of the node determine the
+ * format and how it is constructed.
+ *
+ * For children of the ROOT node, the naming convention is fixed and
+ * determined by whether this is a sun4u or sun4v system.
+ *
+ * For children of other nodes, it is bus type specific.  So
+ * we walk up the tree until we discover a "device_type" property
+ * we recognize and we go from there.
+ */
+static void __init sparc32_path_component(struct device_node *dp, char *tmp_buf)
+{
+	struct linux_prom_registers *regs;
+	struct property *rprop;
+
+	rprop = of_find_property(dp, "reg", NULL);
+	if (!rprop)
+		return;
+
+	regs = rprop->value;
+	sprintf(tmp_buf, "%s@%x,%x",
+		dp->name,
+		regs->which_io, regs->phys_addr);
+}
+
+/* "name@slot,offset"  */
+static void __init sbus_path_component(struct device_node *dp, char *tmp_buf)
+{
+	struct linux_prom_registers *regs;
+	struct property *prop;
+
+	prop = of_find_property(dp, "reg", NULL);
+	if (!prop)
+		return;
+
+	regs = prop->value;
+	sprintf(tmp_buf, "%s@%x,%x",
+		dp->name,
+		regs->which_io,
+		regs->phys_addr);
+}
+
+/* "name@devnum[,func]" */
+static void __init pci_path_component(struct device_node *dp, char *tmp_buf)
+{
+	struct linux_prom_pci_registers *regs;
+	struct property *prop;
+	unsigned int devfn;
+
+	prop = of_find_property(dp, "reg", NULL);
+	if (!prop)
+		return;
+
+	regs = prop->value;
+	devfn = (regs->phys_hi >> 8) & 0xff;
+	if (devfn & 0x07) {
+		sprintf(tmp_buf, "%s@%x,%x",
+			dp->name,
+			devfn >> 3,
+			devfn & 0x07);
+	} else {
+		sprintf(tmp_buf, "%s@%x",
+			dp->name,
+			devfn >> 3);
+	}
+}
+
+/* "name@addrhi,addrlo" */
+static void __init ebus_path_component(struct device_node *dp, char *tmp_buf)
+{
+	struct linux_prom_registers *regs;
+	struct property *prop;
+
+	prop = of_find_property(dp, "reg", NULL);
+	if (!prop)
+		return;
+
+	regs = prop->value;
+
+	sprintf(tmp_buf, "%s@%x,%x",
+		dp->name,
+		regs->which_io, regs->phys_addr);
+}
+
+static void __init __build_path_component(struct device_node *dp, char *tmp_buf)
+{
+	struct device_node *parent = dp->parent;
+
+	if (parent != NULL) {
+		if (!strcmp(parent->type, "pci") ||
+		    !strcmp(parent->type, "pciex"))
+			return pci_path_component(dp, tmp_buf);
+		if (!strcmp(parent->type, "sbus"))
+			return sbus_path_component(dp, tmp_buf);
+		if (!strcmp(parent->type, "ebus"))
+			return ebus_path_component(dp, tmp_buf);
+
+		/* "isa" is handled with platform naming */
+	}
+
+	/* Use platform naming convention.  */
+	return sparc32_path_component(dp, tmp_buf);
+}
+
+static char * __init build_path_component(struct device_node *dp)
+{
+	char tmp_buf[64], *n;
+
+	tmp_buf[0] = '\0';
+	__build_path_component(dp, tmp_buf);
+	if (tmp_buf[0] == '\0')
+		strcpy(tmp_buf, dp->name);
+
+	n = prom_early_alloc(strlen(tmp_buf) + 1);
+	strcpy(n, tmp_buf);
+
+	return n;
+}
+
+static char * __init build_full_name(struct device_node *dp)
+{
+	int len, ourlen, plen;
+	char *n;
+
+	plen = strlen(dp->parent->full_name);
+	ourlen = strlen(dp->path_component_name);
+	len = ourlen + plen + 2;
+
+	n = prom_early_alloc(len);
+	strcpy(n, dp->parent->full_name);
+	if (!is_root_node(dp->parent)) {
+		strcpy(n + plen, "/");
+		plen++;
+	}
+	strcpy(n + plen, dp->path_component_name);
+
+	return n;
+}
+
+static unsigned int unique_id;
+
+static struct property * __init build_one_prop(phandle node, char *prev, char *special_name, void *special_val, int special_len)
+{
+	static struct property *tmp = NULL;
+	struct property *p;
+	int len;
+	const char *name;
+
+	if (tmp) {
+		p = tmp;
+		memset(p, 0, sizeof(*p) + 32);
+		tmp = NULL;
+	} else {
+		p = prom_early_alloc(sizeof(struct property) + 32);
+		p->unique_id = unique_id++;
+	}
+
+	p->name = (char *) (p + 1);
+	if (special_name) {
+		strcpy(p->name, special_name);
+		p->length = special_len;
+		p->value = prom_early_alloc(special_len);
+		memcpy(p->value, special_val, special_len);
+	} else {
+		if (prev == NULL) {
+			name = prom_firstprop(node, NULL);
+		} else {
+			name = prom_nextprop(node, prev, NULL);
+		}
+		if (strlen(name) == 0) {
+			tmp = p;
+			return NULL;
+		}
+		strcpy(p->name, name);
+		p->length = prom_getproplen(node, p->name);
+		if (p->length <= 0) {
+			p->length = 0;
+		} else {
+			p->value = prom_early_alloc(p->length + 1);
+			prom_getproperty(node, p->name, p->value, p->length);
+			((unsigned char *)p->value)[p->length] = '\0';
+		}
+	}
+	return p;
+}
+
+static struct property * __init build_prop_list(phandle node)
+{
+	struct property *head, *tail;
+
+	head = tail = build_one_prop(node, NULL,
+				     ".node", &node, sizeof(node));
+
+	tail->next = build_one_prop(node, NULL, NULL, NULL, 0);
+	tail = tail->next;
+	while(tail) {
+		tail->next = build_one_prop(node, tail->name,
+					    NULL, NULL, 0);
+		tail = tail->next;
+	}
+
+	return head;
+}
+
+static char * __init get_one_property(phandle node, char *name)
+{
+	char *buf = "<NULL>";
+	int len;
+
+	len = prom_getproplen(node, name);
+	if (len > 0) {
+		buf = prom_early_alloc(len);
+		len = prom_getproperty(node, name, buf, len);
+	}
+
+	return buf;
+}
+
+static struct device_node * __init create_node(phandle node)
+{
+	struct device_node *dp;
+
+	if (!node)
+		return NULL;
+
+	dp = prom_early_alloc(sizeof(*dp));
+	dp->unique_id = unique_id++;
+
+	kref_init(&dp->kref);
+
+	dp->name = get_one_property(node, "name");
+	dp->type = get_one_property(node, "device_type");
+	dp->node = node;
+
+	/* Build interrupts later... */
+
+	dp->properties = build_prop_list(node);
+
+	return dp;
+}
+
+static struct device_node * __init build_tree(struct device_node *parent, phandle node, struct device_node ***nextp)
+{
+	struct device_node *dp;
+
+	dp = create_node(node);
+	if (dp) {
+		*(*nextp) = dp;
+		*nextp = &dp->allnext;
+
+		dp->parent = parent;
+		dp->path_component_name = build_path_component(dp);
+		dp->full_name = build_full_name(dp);
+
+		dp->child = build_tree(dp, prom_getchild(node), nextp);
+
+		dp->sibling = build_tree(parent, prom_getsibling(node), nextp);
+	}
+
+	return dp;
+}
+
+void __init prom_build_devicetree(void)
+{
+	struct device_node **nextp;
+
+	allnodes = create_node(prom_root_node);
+	allnodes->path_component_name = "";
+	allnodes->full_name = "/";
+
+	nextp = &allnodes->allnext;
+	allnodes->child = build_tree(allnodes,
+				     prom_getchild(allnodes->node),
+				     &nextp);
+	printk("PROM: Built device tree with %u bytes of memory.\n",
+	       prom_early_allocated);
+}
diff --git a/arch/sparc/lib/iomap.c b/arch/sparc/lib/iomap.c
new file mode 100644
index 000000000..54501c1ca
--- /dev/null
+++ b/arch/sparc/lib/iomap.c
@@ -0,0 +1,48 @@
+/*
+ * Implement the sparc iomap interfaces
+ */
+#include <linux/pci.h>
+#include <linux/module.h>
+#include <asm/io.h>
+
+/* Create a virtual mapping cookie for an IO port range */
+void __iomem *ioport_map(unsigned long port, unsigned int nr)
+{
+	return (void __iomem *) (unsigned long) port;
+}
+
+void ioport_unmap(void __iomem *addr)
+{
+	/* Nothing to do */
+}
+EXPORT_SYMBOL(ioport_map);
+EXPORT_SYMBOL(ioport_unmap);
+
+/* 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(start, len);
+	if (flags & IORESOURCE_MEM) {
+		if (flags & IORESOURCE_CACHEABLE)
+			return ioremap(start, len);
+		return ioremap_nocache(start, len);
+	}
+	/* What? */
+	return NULL;
+}
+
+void pci_iounmap(struct pci_dev *dev, void __iomem * addr)
+{
+	/* nothing to do */
+}
+EXPORT_SYMBOL(pci_iomap);
+EXPORT_SYMBOL(pci_iounmap);
diff --git a/arch/sparc64/kernel/audit.c b/arch/sparc64/kernel/audit.c
new file mode 100644
index 000000000..aef19cc27
--- /dev/null
+++ b/arch/sparc64/kernel/audit.c
@@ -0,0 +1,66 @@
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/audit.h>
+#include <asm/unistd.h>
+
+static unsigned dir_class[] = {
+#include <asm-generic/audit_dir_write.h>
+~0U
+};
+
+static unsigned read_class[] = {
+#include <asm-generic/audit_read.h>
+~0U
+};
+
+static unsigned write_class[] = {
+#include <asm-generic/audit_write.h>
+~0U
+};
+
+static unsigned chattr_class[] = {
+#include <asm-generic/audit_change_attr.h>
+~0U
+};
+
+int audit_classify_syscall(int abi, unsigned syscall)
+{
+#ifdef CONFIG_SPARC32_COMPAT
+	extern int sparc32_classify_syscall(unsigned);
+	if (abi == AUDIT_ARCH_SPARC)
+		return sparc32_classify_syscall(syscall);
+#endif
+	switch(syscall) {
+	case __NR_open:
+		return 2;
+	case __NR_openat:
+		return 3;
+	case __NR_socketcall:
+		return 4;
+	case __NR_execve:
+		return 5;
+	default:
+		return 0;
+	}
+}
+
+static int __init audit_classes_init(void)
+{
+#ifdef CONFIG_SPARC32_COMPAT
+	extern __u32 sparc32_dir_class[];
+	extern __u32 sparc32_write_class[];
+	extern __u32 sparc32_read_class[];
+	extern __u32 sparc32_chattr_class[];
+	audit_register_class(AUDIT_CLASS_WRITE_32, sparc32_write_class);
+	audit_register_class(AUDIT_CLASS_READ_32, sparc32_read_class);
+	audit_register_class(AUDIT_CLASS_DIR_WRITE_32, sparc32_dir_class);
+	audit_register_class(AUDIT_CLASS_CHATTR_32, sparc32_chattr_class);
+#endif
+	audit_register_class(AUDIT_CLASS_WRITE, write_class);
+	audit_register_class(AUDIT_CLASS_READ, read_class);
+	audit_register_class(AUDIT_CLASS_DIR_WRITE, dir_class);
+	audit_register_class(AUDIT_CLASS_CHATTR, chattr_class);
+	return 0;
+}
+
+__initcall(audit_classes_init);
diff --git a/arch/sparc64/kernel/compat_audit.c b/arch/sparc64/kernel/compat_audit.c
new file mode 100644
index 000000000..cca96c91b
--- /dev/null
+++ b/arch/sparc64/kernel/compat_audit.c
@@ -0,0 +1,37 @@
+#include <asm-sparc/unistd.h>
+
+unsigned sparc32_dir_class[] = {
+#include <asm-generic/audit_dir_write.h>
+~0U
+};
+
+unsigned sparc32_chattr_class[] = {
+#include <asm-generic/audit_change_attr.h>
+~0U
+};
+
+unsigned sparc32_write_class[] = {
+#include <asm-generic/audit_write.h>
+~0U
+};
+
+unsigned sparc32_read_class[] = {
+#include <asm-generic/audit_read.h>
+~0U
+};
+
+int sparc32_classify_syscall(unsigned syscall)
+{
+	switch(syscall) {
+	case __NR_open:
+		return 2;
+	case __NR_openat:
+		return 3;
+	case __NR_socketcall:
+		return 4;
+	case __NR_execve:
+		return 5;
+	default:
+		return 1;
+	}
+}
diff --git a/arch/sparc64/kernel/of_device.c b/arch/sparc64/kernel/of_device.c
new file mode 100644
index 000000000..8c7c5004d
--- /dev/null
+++ b/arch/sparc64/kernel/of_device.c
@@ -0,0 +1,1032 @@
+#include <linux/string.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/mod_devicetable.h>
+#include <linux/slab.h>
+
+#include <asm/errno.h>
+#include <asm/of_device.h>
+
+/**
+ * of_match_device - Tell if an of_device structure has a matching
+ * of_match structure
+ * @ids: array of of device match structures to search in
+ * @dev: the of device structure to match against
+ *
+ * Used by a driver to check whether an of_device present in the
+ * system is in its list of supported devices.
+ */
+const struct of_device_id *of_match_device(const struct of_device_id *matches,
+					const struct of_device *dev)
+{
+	if (!dev->node)
+		return NULL;
+	while (matches->name[0] || matches->type[0] || matches->compatible[0]) {
+		int match = 1;
+		if (matches->name[0])
+			match &= dev->node->name
+				&& !strcmp(matches->name, dev->node->name);
+		if (matches->type[0])
+			match &= dev->node->type
+				&& !strcmp(matches->type, dev->node->type);
+		if (matches->compatible[0])
+			match &= of_device_is_compatible(dev->node,
+							 matches->compatible);
+		if (match)
+			return matches;
+		matches++;
+	}
+	return NULL;
+}
+
+static int of_platform_bus_match(struct device *dev, struct device_driver *drv)
+{
+	struct of_device * of_dev = to_of_device(dev);
+	struct of_platform_driver * of_drv = to_of_platform_driver(drv);
+	const struct of_device_id * matches = of_drv->match_table;
+
+	if (!matches)
+		return 0;
+
+	return of_match_device(matches, of_dev) != NULL;
+}
+
+struct of_device *of_dev_get(struct of_device *dev)
+{
+	struct device *tmp;
+
+	if (!dev)
+		return NULL;
+	tmp = get_device(&dev->dev);
+	if (tmp)
+		return to_of_device(tmp);
+	else
+		return NULL;
+}
+
+void of_dev_put(struct of_device *dev)
+{
+	if (dev)
+		put_device(&dev->dev);
+}
+
+
+static int of_device_probe(struct device *dev)
+{
+	int error = -ENODEV;
+	struct of_platform_driver *drv;
+	struct of_device *of_dev;
+	const struct of_device_id *match;
+
+	drv = to_of_platform_driver(dev->driver);
+	of_dev = to_of_device(dev);
+
+	if (!drv->probe)
+		return error;
+
+	of_dev_get(of_dev);
+
+	match = of_match_device(drv->match_table, of_dev);
+	if (match)
+		error = drv->probe(of_dev, match);
+	if (error)
+		of_dev_put(of_dev);
+
+	return error;
+}
+
+static int of_device_remove(struct device *dev)
+{
+	struct of_device * of_dev = to_of_device(dev);
+	struct of_platform_driver * drv = to_of_platform_driver(dev->driver);
+
+	if (dev->driver && drv->remove)
+		drv->remove(of_dev);
+	return 0;
+}
+
+static int of_device_suspend(struct device *dev, pm_message_t state)
+{
+	struct of_device * of_dev = to_of_device(dev);
+	struct of_platform_driver * drv = to_of_platform_driver(dev->driver);
+	int error = 0;
+
+	if (dev->driver && drv->suspend)
+		error = drv->suspend(of_dev, state);
+	return error;
+}
+
+static int of_device_resume(struct device * dev)
+{
+	struct of_device * of_dev = to_of_device(dev);
+	struct of_platform_driver * drv = to_of_platform_driver(dev->driver);
+	int error = 0;
+
+	if (dev->driver && drv->resume)
+		error = drv->resume(of_dev);
+	return error;
+}
+
+void __iomem *of_ioremap(struct resource *res, unsigned long offset, unsigned long size, char *name)
+{
+	unsigned long ret = res->start + offset;
+
+	if (!request_region(ret, size, name))
+		ret = 0;
+
+	return (void __iomem *) ret;
+}
+EXPORT_SYMBOL(of_ioremap);
+
+void of_iounmap(void __iomem *base, unsigned long size)
+{
+	release_region((unsigned long) base, size);
+}
+EXPORT_SYMBOL(of_iounmap);
+
+static int node_match(struct device *dev, void *data)
+{
+	struct of_device *op = to_of_device(dev);
+	struct device_node *dp = data;
+
+	return (op->node == dp);
+}
+
+struct of_device *of_find_device_by_node(struct device_node *dp)
+{
+	struct device *dev = bus_find_device(&of_bus_type, NULL,
+					     dp, node_match);
+
+	if (dev)
+		return to_of_device(dev);
+
+	return NULL;
+}
+EXPORT_SYMBOL(of_find_device_by_node);
+
+#ifdef CONFIG_PCI
+struct bus_type isa_bus_type = {
+       .name	= "isa",
+       .match	= of_platform_bus_match,
+       .probe	= of_device_probe,
+       .remove	= of_device_remove,
+       .suspend	= of_device_suspend,
+       .resume	= of_device_resume,
+};
+EXPORT_SYMBOL(isa_bus_type);
+
+struct bus_type ebus_bus_type = {
+       .name	= "ebus",
+       .match	= of_platform_bus_match,
+       .probe	= of_device_probe,
+       .remove	= of_device_remove,
+       .suspend	= of_device_suspend,
+       .resume	= of_device_resume,
+};
+EXPORT_SYMBOL(ebus_bus_type);
+#endif
+
+#ifdef CONFIG_SBUS
+struct bus_type sbus_bus_type = {
+       .name	= "sbus",
+       .match	= of_platform_bus_match,
+       .probe	= of_device_probe,
+       .remove	= of_device_remove,
+       .suspend	= of_device_suspend,
+       .resume	= of_device_resume,
+};
+EXPORT_SYMBOL(sbus_bus_type);
+#endif
+
+struct bus_type of_bus_type = {
+       .name	= "of",
+       .match	= of_platform_bus_match,
+       .probe	= of_device_probe,
+       .remove	= of_device_remove,
+       .suspend	= of_device_suspend,
+       .resume	= of_device_resume,
+};
+EXPORT_SYMBOL(of_bus_type);
+
+static inline u64 of_read_addr(const u32 *cell, int size)
+{
+	u64 r = 0;
+	while (size--)
+		r = (r << 32) | *(cell++);
+	return r;
+}
+
+static void __init get_cells(struct device_node *dp,
+			     int *addrc, int *sizec)
+{
+	if (addrc)
+		*addrc = of_n_addr_cells(dp);
+	if (sizec)
+		*sizec = of_n_size_cells(dp);
+}
+
+/* Max address size we deal with */
+#define OF_MAX_ADDR_CELLS	4
+
+struct of_bus {
+	const char	*name;
+	const char	*addr_prop_name;
+	int		(*match)(struct device_node *parent);
+	void		(*count_cells)(struct device_node *child,
+				       int *addrc, int *sizec);
+	int		(*map)(u32 *addr, const u32 *range,
+			       int na, int ns, int pna);
+	unsigned int	(*get_flags)(u32 *addr);
+};
+
+/*
+ * Default translator (generic bus)
+ */
+
+static void of_bus_default_count_cells(struct device_node *dev,
+				       int *addrc, int *sizec)
+{
+	get_cells(dev, addrc, sizec);
+}
+
+/* Make sure the least significant 64-bits are in-range.  Even
+ * for 3 or 4 cell values it is a good enough approximation.
+ */
+static int of_out_of_range(const u32 *addr, const u32 *base,
+			   const u32 *size, int na, int ns)
+{
+	u64 a = of_read_addr(addr, na);
+	u64 b = of_read_addr(base, na);
+
+	if (a < b)
+		return 1;
+
+	b += of_read_addr(size, ns);
+	if (a >= b)
+		return 1;
+
+	return 0;
+}
+
+static int of_bus_default_map(u32 *addr, const u32 *range,
+			      int na, int ns, int pna)
+{
+	u32 result[OF_MAX_ADDR_CELLS];
+	int i;
+
+	if (ns > 2) {
+		printk("of_device: Cannot handle size cells (%d) > 2.", ns);
+		return -EINVAL;
+	}
+
+	if (of_out_of_range(addr, range, range + na + pna, na, ns))
+		return -EINVAL;
+
+	/* Start with the parent range base.  */
+	memcpy(result, range + na, pna * 4);
+
+	/* Add in the child address offset.  */
+	for (i = 0; i < na; i++)
+		result[pna - 1 - i] +=
+			(addr[na - 1 - i] -
+			 range[na - 1 - i]);
+
+	memcpy(addr, result, pna * 4);
+
+	return 0;
+}
+
+static unsigned int of_bus_default_get_flags(u32 *addr)
+{
+	return IORESOURCE_MEM;
+}
+
+/*
+ * PCI bus specific translator
+ */
+
+static int of_bus_pci_match(struct device_node *np)
+{
+	if (!strcmp(np->type, "pci") || !strcmp(np->type, "pciex")) {
+		/* Do not do PCI specific frobbing if the
+		 * PCI bridge lacks a ranges property.  We
+		 * want to pass it through up to the next
+		 * parent as-is, not with the PCI translate
+		 * method which chops off the top address cell.
+		 */
+		if (!of_find_property(np, "ranges", NULL))
+			return 0;
+
+		return 1;
+	}
+
+	return 0;
+}
+
+static void of_bus_pci_count_cells(struct device_node *np,
+				   int *addrc, int *sizec)
+{
+	if (addrc)
+		*addrc = 3;
+	if (sizec)
+		*sizec = 2;
+}
+
+static int of_bus_pci_map(u32 *addr, const u32 *range,
+			  int na, int ns, int pna)
+{
+	u32 result[OF_MAX_ADDR_CELLS];
+	int i;
+
+	/* Check address type match */
+	if ((addr[0] ^ range[0]) & 0x03000000)
+		return -EINVAL;
+
+	if (of_out_of_range(addr + 1, range + 1, range + na + pna,
+			    na - 1, ns))
+		return -EINVAL;
+
+	/* Start with the parent range base.  */
+	memcpy(result, range + na, pna * 4);
+
+	/* Add in the child address offset, skipping high cell.  */
+	for (i = 0; i < na - 1; i++)
+		result[pna - 1 - i] +=
+			(addr[na - 1 - i] -
+			 range[na - 1 - i]);
+
+	memcpy(addr, result, pna * 4);
+
+	return 0;
+}
+
+static unsigned int of_bus_pci_get_flags(u32 *addr)
+{
+	unsigned int flags = 0;
+	u32 w = addr[0];
+
+	switch((w >> 24) & 0x03) {
+	case 0x01:
+		flags |= IORESOURCE_IO;
+	case 0x02: /* 32 bits */
+	case 0x03: /* 64 bits */
+		flags |= IORESOURCE_MEM;
+	}
+	if (w & 0x40000000)
+		flags |= IORESOURCE_PREFETCH;
+	return flags;
+}
+
+/*
+ * SBUS bus specific translator
+ */
+
+static int of_bus_sbus_match(struct device_node *np)
+{
+	return !strcmp(np->name, "sbus") ||
+		!strcmp(np->name, "sbi");
+}
+
+static void of_bus_sbus_count_cells(struct device_node *child,
+				   int *addrc, int *sizec)
+{
+	if (addrc)
+		*addrc = 2;
+	if (sizec)
+		*sizec = 1;
+}
+
+/*
+ * FHC/Central bus specific translator.
+ *
+ * This is just needed to hard-code the address and size cell
+ * counts.  'fhc' and 'central' nodes lack the #address-cells and
+ * #size-cells properties, and if you walk to the root on such
+ * Enterprise boxes all you'll get is a #size-cells of 2 which is
+ * not what we want to use.
+ */
+static int of_bus_fhc_match(struct device_node *np)
+{
+	return !strcmp(np->name, "fhc") ||
+		!strcmp(np->name, "central");
+}
+
+#define of_bus_fhc_count_cells of_bus_sbus_count_cells
+
+/*
+ * Array of bus specific translators
+ */
+
+static struct of_bus of_busses[] = {
+	/* PCI */
+	{
+		.name = "pci",
+		.addr_prop_name = "assigned-addresses",
+		.match = of_bus_pci_match,
+		.count_cells = of_bus_pci_count_cells,
+		.map = of_bus_pci_map,
+		.get_flags = of_bus_pci_get_flags,
+	},
+	/* SBUS */
+	{
+		.name = "sbus",
+		.addr_prop_name = "reg",
+		.match = of_bus_sbus_match,
+		.count_cells = of_bus_sbus_count_cells,
+		.map = of_bus_default_map,
+		.get_flags = of_bus_default_get_flags,
+	},
+	/* FHC */
+	{
+		.name = "fhc",
+		.addr_prop_name = "reg",
+		.match = of_bus_fhc_match,
+		.count_cells = of_bus_fhc_count_cells,
+		.map = of_bus_default_map,
+		.get_flags = of_bus_default_get_flags,
+	},
+	/* Default */
+	{
+		.name = "default",
+		.addr_prop_name = "reg",
+		.match = NULL,
+		.count_cells = of_bus_default_count_cells,
+		.map = of_bus_default_map,
+		.get_flags = of_bus_default_get_flags,
+	},
+};
+
+static struct of_bus *of_match_bus(struct device_node *np)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(of_busses); i ++)
+		if (!of_busses[i].match || of_busses[i].match(np))
+			return &of_busses[i];
+	BUG();
+	return NULL;
+}
+
+static int __init build_one_resource(struct device_node *parent,
+				     struct of_bus *bus,
+				     struct of_bus *pbus,
+				     u32 *addr,
+				     int na, int ns, int pna)
+{
+	u32 *ranges;
+	unsigned int rlen;
+	int rone;
+
+	ranges = of_get_property(parent, "ranges", &rlen);
+	if (ranges == NULL || rlen == 0) {
+		u32 result[OF_MAX_ADDR_CELLS];
+		int i;
+
+		memset(result, 0, pna * 4);
+		for (i = 0; i < na; i++)
+			result[pna - 1 - i] =
+				addr[na - 1 - i];
+
+		memcpy(addr, result, pna * 4);
+		return 0;
+	}
+
+	/* Now walk through the ranges */
+	rlen /= 4;
+	rone = na + pna + ns;
+	for (; rlen >= rone; rlen -= rone, ranges += rone) {
+		if (!bus->map(addr, ranges, na, ns, pna))
+			return 0;
+	}
+
+	return 1;
+}
+
+static int __init use_1to1_mapping(struct device_node *pp)
+{
+	char *model;
+
+	/* If this is on the PMU bus, don't try to translate it even
+	 * if a ranges property exists.
+	 */
+	if (!strcmp(pp->name, "pmu"))
+		return 1;
+
+	/* If we have a ranges property in the parent, use it.  */
+	if (of_find_property(pp, "ranges", NULL) != NULL)
+		return 0;
+
+	/* If the parent is the dma node of an ISA bus, pass
+	 * the translation up to the root.
+	 */
+	if (!strcmp(pp->name, "dma"))
+		return 0;
+
+	/* Similarly for Simba PCI bridges.  */
+	model = of_get_property(pp, "model", NULL);
+	if (model && !strcmp(model, "SUNW,simba"))
+		return 0;
+
+	return 1;
+}
+
+static int of_resource_verbose;
+
+static void __init build_device_resources(struct of_device *op,
+					  struct device *parent)
+{
+	struct of_device *p_op;
+	struct of_bus *bus;
+	int na, ns;
+	int index, num_reg;
+	void *preg;
+
+	if (!parent)
+		return;
+
+	p_op = to_of_device(parent);
+	bus = of_match_bus(p_op->node);
+	bus->count_cells(op->node, &na, &ns);
+
+	preg = of_get_property(op->node, bus->addr_prop_name, &num_reg);
+	if (!preg || num_reg == 0)
+		return;
+
+	/* Convert to num-cells.  */
+	num_reg /= 4;
+
+	/* Convert to num-entries.  */
+	num_reg /= na + ns;
+
+	/* Prevent overruning the op->resources[] array.  */
+	if (num_reg > PROMREG_MAX) {
+		printk(KERN_WARNING "%s: Too many regs (%d), "
+		       "limiting to %d.\n",
+		       op->node->full_name, num_reg, PROMREG_MAX);
+		num_reg = PROMREG_MAX;
+	}
+
+	for (index = 0; index < num_reg; index++) {
+		struct resource *r = &op->resource[index];
+		u32 addr[OF_MAX_ADDR_CELLS];
+		u32 *reg = (preg + (index * ((na + ns) * 4)));
+		struct device_node *dp = op->node;
+		struct device_node *pp = p_op->node;
+		struct of_bus *pbus;
+		u64 size, result = OF_BAD_ADDR;
+		unsigned long flags;
+		int dna, dns;
+		int pna, pns;
+
+		size = of_read_addr(reg + na, ns);
+		flags = bus->get_flags(reg);
+
+		memcpy(addr, reg, na * 4);
+
+		if (use_1to1_mapping(pp)) {
+			result = of_read_addr(addr, na);
+			goto build_res;
+		}
+
+		dna = na;
+		dns = ns;
+
+		while (1) {
+			dp = pp;
+			pp = dp->parent;
+			if (!pp) {
+				result = of_read_addr(addr, dna);
+				break;
+			}
+
+			pbus = of_match_bus(pp);
+			pbus->count_cells(dp, &pna, &pns);
+
+			if (build_one_resource(dp, bus, pbus, addr,
+					       dna, dns, pna))
+				break;
+
+			dna = pna;
+			dns = pns;
+			bus = pbus;
+		}
+
+	build_res:
+		memset(r, 0, sizeof(*r));
+
+		if (of_resource_verbose)
+			printk("%s reg[%d] -> %lx\n",
+			       op->node->full_name, index,
+			       result);
+
+		if (result != OF_BAD_ADDR) {
+			if (tlb_type == hypervisor)
+				result &= 0x0fffffffffffffffUL;
+
+			r->start = result;
+			r->end = result + size - 1;
+			r->flags = flags;
+		} else {
+			r->start = ~0UL;
+			r->end = ~0UL;
+		}
+		r->name = op->node->name;
+	}
+}
+
+static struct device_node * __init
+apply_interrupt_map(struct device_node *dp, struct device_node *pp,
+		    u32 *imap, int imlen, u32 *imask,
+		    unsigned int *irq_p)
+{
+	struct device_node *cp;
+	unsigned int irq = *irq_p;
+	struct of_bus *bus;
+	phandle handle;
+	u32 *reg;
+	int na, num_reg, i;
+
+	bus = of_match_bus(pp);
+	bus->count_cells(dp, &na, NULL);
+
+	reg = of_get_property(dp, "reg", &num_reg);
+	if (!reg || !num_reg)
+		return NULL;
+
+	imlen /= ((na + 3) * 4);
+	handle = 0;
+	for (i = 0; i < imlen; i++) {
+		int j;
+
+		for (j = 0; j < na; j++) {
+			if ((reg[j] & imask[j]) != imap[j])
+				goto next;
+		}
+		if (imap[na] == irq) {
+			handle = imap[na + 1];
+			irq = imap[na + 2];
+			break;
+		}
+
+	next:
+		imap += (na + 3);
+	}
+	if (i == imlen) {
+		/* Psycho and Sabre PCI controllers can have 'interrupt-map'
+		 * properties that do not include the on-board device
+		 * interrupts.  Instead, the device's 'interrupts' property
+		 * is already a fully specified INO value.
+		 *
+		 * Handle this by deciding that, if we didn't get a
+		 * match in the parent's 'interrupt-map', and the
+		 * parent is an IRQ translater, then use the parent as
+		 * our IRQ controller.
+		 */
+		if (pp->irq_trans)
+			return pp;
+
+		return NULL;
+	}
+
+	*irq_p = irq;
+	cp = of_find_node_by_phandle(handle);
+
+	return cp;
+}
+
+static unsigned int __init pci_irq_swizzle(struct device_node *dp,
+					   struct device_node *pp,
+					   unsigned int irq)
+{
+	struct linux_prom_pci_registers *regs;
+	unsigned int devfn, slot, ret;
+
+	if (irq < 1 || irq > 4)
+		return irq;
+
+	regs = of_get_property(dp, "reg", NULL);
+	if (!regs)
+		return irq;
+
+	devfn = (regs->phys_hi >> 8) & 0xff;
+	slot = (devfn >> 3) & 0x1f;
+
+	ret = ((irq - 1 + (slot & 3)) & 3) + 1;
+
+	return ret;
+}
+
+static int of_irq_verbose;
+
+static unsigned int __init build_one_device_irq(struct of_device *op,
+						struct device *parent,
+						unsigned int irq)
+{
+	struct device_node *dp = op->node;
+	struct device_node *pp, *ip;
+	unsigned int orig_irq = irq;
+
+	if (irq == 0xffffffff)
+		return irq;
+
+	if (dp->irq_trans) {
+		irq = dp->irq_trans->irq_build(dp, irq,
+					       dp->irq_trans->data);
+
+		if (of_irq_verbose)
+			printk("%s: direct translate %x --> %x\n",
+			       dp->full_name, orig_irq, irq);
+
+		return irq;
+	}
+
+	/* Something more complicated.  Walk up to the root, applying
+	 * interrupt-map or bus specific translations, until we hit
+	 * an IRQ translator.
+	 *
+	 * If we hit a bus type or situation we cannot handle, we
+	 * stop and assume that the original IRQ number was in a
+	 * format which has special meaning to it's immediate parent.
+	 */
+	pp = dp->parent;
+	ip = NULL;
+	while (pp) {
+		void *imap, *imsk;
+		int imlen;
+
+		imap = of_get_property(pp, "interrupt-map", &imlen);
+		imsk = of_get_property(pp, "interrupt-map-mask", NULL);
+		if (imap && imsk) {
+			struct device_node *iret;
+			int this_orig_irq = irq;
+
+			iret = apply_interrupt_map(dp, pp,
+						   imap, imlen, imsk,
+						   &irq);
+
+			if (of_irq_verbose)
+				printk("%s: Apply [%s:%x] imap --> [%s:%x]\n",
+				       op->node->full_name,
+				       pp->full_name, this_orig_irq,
+				       (iret ? iret->full_name : "NULL"), irq);
+
+			if (!iret)
+				break;
+
+			if (iret->irq_trans) {
+				ip = iret;
+				break;
+			}
+		} else {
+			if (!strcmp(pp->type, "pci") ||
+			    !strcmp(pp->type, "pciex")) {
+				unsigned int this_orig_irq = irq;
+
+				irq = pci_irq_swizzle(dp, pp, irq);
+				if (of_irq_verbose)
+					printk("%s: PCI swizzle [%s] "
+					       "%x --> %x\n",
+					       op->node->full_name,
+					       pp->full_name, this_orig_irq,
+					       irq);
+
+			}
+
+			if (pp->irq_trans) {
+				ip = pp;
+				break;
+			}
+		}
+		dp = pp;
+		pp = pp->parent;
+	}
+	if (!ip)
+		return orig_irq;
+
+	irq = ip->irq_trans->irq_build(op->node, irq,
+				       ip->irq_trans->data);
+	if (of_irq_verbose)
+		printk("%s: Apply IRQ trans [%s] %x --> %x\n",
+		       op->node->full_name, ip->full_name, orig_irq, irq);
+
+	return irq;
+}
+
+static struct of_device * __init scan_one_device(struct device_node *dp,
+						 struct device *parent)
+{
+	struct of_device *op = kzalloc(sizeof(*op), GFP_KERNEL);
+	unsigned int *irq;
+	int len, i;
+
+	if (!op)
+		return NULL;
+
+	op->node = dp;
+
+	op->clock_freq = of_getintprop_default(dp, "clock-frequency",
+					       (25*1000*1000));
+	op->portid = of_getintprop_default(dp, "upa-portid", -1);
+	if (op->portid == -1)
+		op->portid = of_getintprop_default(dp, "portid", -1);
+
+	irq = of_get_property(dp, "interrupts", &len);
+	if (irq) {
+		memcpy(op->irqs, irq, len);
+		op->num_irqs = len / 4;
+	} else {
+		op->num_irqs = 0;
+	}
+
+	/* Prevent overruning the op->irqs[] array.  */
+	if (op->num_irqs > PROMINTR_MAX) {
+		printk(KERN_WARNING "%s: Too many irqs (%d), "
+		       "limiting to %d.\n",
+		       dp->full_name, op->num_irqs, PROMINTR_MAX);
+		op->num_irqs = PROMINTR_MAX;
+	}
+
+	build_device_resources(op, parent);
+	for (i = 0; i < op->num_irqs; i++)
+		op->irqs[i] = build_one_device_irq(op, parent, op->irqs[i]);
+
+	op->dev.parent = parent;
+	op->dev.bus = &of_bus_type;
+	if (!parent)
+		strcpy(op->dev.bus_id, "root");
+	else
+		strcpy(op->dev.bus_id, dp->path_component_name);
+
+	if (of_device_register(op)) {
+		printk("%s: Could not register of device.\n",
+		       dp->full_name);
+		kfree(op);
+		op = NULL;
+	}
+
+	return op;
+}
+
+static void __init scan_tree(struct device_node *dp, struct device *parent)
+{
+	while (dp) {
+		struct of_device *op = scan_one_device(dp, parent);
+
+		if (op)
+			scan_tree(dp->child, &op->dev);
+
+		dp = dp->sibling;
+	}
+}
+
+static void __init scan_of_devices(void)
+{
+	struct device_node *root = of_find_node_by_path("/");
+	struct of_device *parent;
+
+	parent = scan_one_device(root, NULL);
+	if (!parent)
+		return;
+
+	scan_tree(root->child, &parent->dev);
+}
+
+static int __init of_bus_driver_init(void)
+{
+	int err;
+
+	err = bus_register(&of_bus_type);
+#ifdef CONFIG_PCI
+	if (!err)
+		err = bus_register(&isa_bus_type);
+	if (!err)
+		err = bus_register(&ebus_bus_type);
+#endif
+#ifdef CONFIG_SBUS
+	if (!err)
+		err = bus_register(&sbus_bus_type);
+#endif
+
+	if (!err)
+		scan_of_devices();
+
+	return err;
+}
+
+postcore_initcall(of_bus_driver_init);
+
+static int __init of_debug(char *str)
+{
+	int val = 0;
+
+	get_option(&str, &val);
+	if (val & 1)
+		of_resource_verbose = 1;
+	if (val & 2)
+		of_irq_verbose = 1;
+	return 1;
+}
+
+__setup("of_debug=", of_debug);
+
+int of_register_driver(struct of_platform_driver *drv, struct bus_type *bus)
+{
+	/* initialize common driver fields */
+	drv->driver.name = drv->name;
+	drv->driver.bus = bus;
+
+	/* register with core */
+	return driver_register(&drv->driver);
+}
+
+void of_unregister_driver(struct of_platform_driver *drv)
+{
+	driver_unregister(&drv->driver);
+}
+
+
+static ssize_t dev_show_devspec(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	struct of_device *ofdev;
+
+	ofdev = to_of_device(dev);
+	return sprintf(buf, "%s", ofdev->node->full_name);
+}
+
+static DEVICE_ATTR(devspec, S_IRUGO, dev_show_devspec, NULL);
+
+/**
+ * of_release_dev - free an of device structure when all users of it are finished.
+ * @dev: device that's been disconnected
+ *
+ * Will be called only by the device core when all users of this of device are
+ * done.
+ */
+void of_release_dev(struct device *dev)
+{
+	struct of_device *ofdev;
+
+        ofdev = to_of_device(dev);
+
+	kfree(ofdev);
+}
+
+int of_device_register(struct of_device *ofdev)
+{
+	int rc;
+
+	BUG_ON(ofdev->node == NULL);
+
+	rc = device_register(&ofdev->dev);
+	if (rc)
+		return rc;
+
+	rc = device_create_file(&ofdev->dev, &dev_attr_devspec);
+	if (rc)
+		device_unregister(&ofdev->dev);
+
+	return rc;
+}
+
+void of_device_unregister(struct of_device *ofdev)
+{
+	device_remove_file(&ofdev->dev, &dev_attr_devspec);
+	device_unregister(&ofdev->dev);
+}
+
+struct of_device* of_platform_device_create(struct device_node *np,
+					    const char *bus_id,
+					    struct device *parent,
+					    struct bus_type *bus)
+{
+	struct of_device *dev;
+
+	dev = kmalloc(sizeof(*dev), GFP_KERNEL);
+	if (!dev)
+		return NULL;
+	memset(dev, 0, sizeof(*dev));
+
+	dev->dev.parent = parent;
+	dev->dev.bus = bus;
+	dev->dev.release = of_release_dev;
+
+	strlcpy(dev->dev.bus_id, bus_id, BUS_ID_SIZE);
+
+	if (of_device_register(dev) != 0) {
+		kfree(dev);
+		return NULL;
+	}
+
+	return dev;
+}
+
+EXPORT_SYMBOL(of_match_device);
+EXPORT_SYMBOL(of_register_driver);
+EXPORT_SYMBOL(of_unregister_driver);
+EXPORT_SYMBOL(of_device_register);
+EXPORT_SYMBOL(of_device_unregister);
+EXPORT_SYMBOL(of_dev_get);
+EXPORT_SYMBOL(of_dev_put);
+EXPORT_SYMBOL(of_platform_device_create);
+EXPORT_SYMBOL(of_release_dev);
diff --git a/arch/sparc64/kernel/prom.c b/arch/sparc64/kernel/prom.c
new file mode 100644
index 000000000..c60efb3cb
--- /dev/null
+++ b/arch/sparc64/kernel/prom.c
@@ -0,0 +1,1577 @@
+/*
+ * Procedures for creating, accessing and interpreting the device tree.
+ *
+ * Paul Mackerras	August 1996.
+ * Copyright (C) 1996-2005 Paul Mackerras.
+ * 
+ *  Adapted for 64bit PowerPC by Dave Engebretsen and Peter Bergner.
+ *    {engebret|bergner}@us.ibm.com 
+ *
+ *  Adapted for sparc64 by David S. Miller davem@davemloft.net
+ *
+ *      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/kernel.h>
+#include <linux/types.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/bootmem.h>
+#include <linux/module.h>
+
+#include <asm/prom.h>
+#include <asm/of_device.h>
+#include <asm/oplib.h>
+#include <asm/irq.h>
+#include <asm/asi.h>
+#include <asm/upa.h>
+
+static struct device_node *allnodes;
+
+/* use when traversing tree through the allnext, child, sibling,
+ * or parent members of struct device_node.
+ */
+static DEFINE_RWLOCK(devtree_lock);
+
+int of_device_is_compatible(struct device_node *device, const char *compat)
+{
+	const char* cp;
+	int cplen, l;
+
+	cp = (char *) of_get_property(device, "compatible", &cplen);
+	if (cp == NULL)
+		return 0;
+	while (cplen > 0) {
+		if (strncmp(cp, compat, strlen(compat)) == 0)
+			return 1;
+		l = strlen(cp) + 1;
+		cp += l;
+		cplen -= l;
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL(of_device_is_compatible);
+
+struct device_node *of_get_parent(const struct device_node *node)
+{
+	struct device_node *np;
+
+	if (!node)
+		return NULL;
+
+	np = node->parent;
+
+	return np;
+}
+EXPORT_SYMBOL(of_get_parent);
+
+struct device_node *of_get_next_child(const struct device_node *node,
+	struct device_node *prev)
+{
+	struct device_node *next;
+
+	next = prev ? prev->sibling : node->child;
+	for (; next != 0; next = next->sibling) {
+		break;
+	}
+
+	return next;
+}
+EXPORT_SYMBOL(of_get_next_child);
+
+struct device_node *of_find_node_by_path(const char *path)
+{
+	struct device_node *np = allnodes;
+
+	for (; np != 0; np = np->allnext) {
+		if (np->full_name != 0 && strcmp(np->full_name, path) == 0)
+			break;
+	}
+
+	return np;
+}
+EXPORT_SYMBOL(of_find_node_by_path);
+
+struct device_node *of_find_node_by_phandle(phandle handle)
+{
+	struct device_node *np;
+
+	for (np = allnodes; np != 0; np = np->allnext)
+		if (np->node == handle)
+			break;
+
+	return np;
+}
+EXPORT_SYMBOL(of_find_node_by_phandle);
+
+struct device_node *of_find_node_by_name(struct device_node *from,
+	const char *name)
+{
+	struct device_node *np;
+
+	np = from ? from->allnext : allnodes;
+	for (; np != NULL; np = np->allnext)
+		if (np->name != NULL && strcmp(np->name, name) == 0)
+			break;
+
+	return np;
+}
+EXPORT_SYMBOL(of_find_node_by_name);
+
+struct device_node *of_find_node_by_type(struct device_node *from,
+	const char *type)
+{
+	struct device_node *np;
+
+	np = from ? from->allnext : allnodes;
+	for (; np != 0; np = np->allnext)
+		if (np->type != 0 && strcmp(np->type, type) == 0)
+			break;
+
+	return np;
+}
+EXPORT_SYMBOL(of_find_node_by_type);
+
+struct device_node *of_find_compatible_node(struct device_node *from,
+	const char *type, const char *compatible)
+{
+	struct device_node *np;
+
+	np = from ? from->allnext : allnodes;
+	for (; np != 0; np = np->allnext) {
+		if (type != NULL
+		    && !(np->type != 0 && strcmp(np->type, type) == 0))
+			continue;
+		if (of_device_is_compatible(np, compatible))
+			break;
+	}
+
+	return np;
+}
+EXPORT_SYMBOL(of_find_compatible_node);
+
+struct property *of_find_property(struct device_node *np, const char *name,
+				  int *lenp)
+{
+	struct property *pp;
+
+	for (pp = np->properties; pp != 0; pp = pp->next) {
+		if (strcmp(pp->name, name) == 0) {
+			if (lenp != 0)
+				*lenp = pp->length;
+			break;
+		}
+	}
+	return pp;
+}
+EXPORT_SYMBOL(of_find_property);
+
+/*
+ * Find a property with a given name for a given node
+ * and return the value.
+ */
+void *of_get_property(struct device_node *np, const char *name, int *lenp)
+{
+	struct property *pp = of_find_property(np,name,lenp);
+	return pp ? pp->value : NULL;
+}
+EXPORT_SYMBOL(of_get_property);
+
+int of_getintprop_default(struct device_node *np, const char *name, int def)
+{
+	struct property *prop;
+	int len;
+
+	prop = of_find_property(np, name, &len);
+	if (!prop || len != 4)
+		return def;
+
+	return *(int *) prop->value;
+}
+EXPORT_SYMBOL(of_getintprop_default);
+
+int of_n_addr_cells(struct device_node *np)
+{
+	int* ip;
+	do {
+		if (np->parent)
+			np = np->parent;
+		ip = of_get_property(np, "#address-cells", NULL);
+		if (ip != NULL)
+			return *ip;
+	} while (np->parent);
+	/* No #address-cells property for the root node, default to 2 */
+	return 2;
+}
+EXPORT_SYMBOL(of_n_addr_cells);
+
+int of_n_size_cells(struct device_node *np)
+{
+	int* ip;
+	do {
+		if (np->parent)
+			np = np->parent;
+		ip = of_get_property(np, "#size-cells", NULL);
+		if (ip != NULL)
+			return *ip;
+	} while (np->parent);
+	/* No #size-cells property for the root node, default to 1 */
+	return 1;
+}
+EXPORT_SYMBOL(of_n_size_cells);
+
+int of_set_property(struct device_node *dp, const char *name, void *val, int len)
+{
+	struct property **prevp;
+	void *new_val;
+	int err;
+
+	new_val = kmalloc(len, GFP_KERNEL);
+	if (!new_val)
+		return -ENOMEM;
+
+	memcpy(new_val, val, len);
+
+	err = -ENODEV;
+
+	write_lock(&devtree_lock);
+	prevp = &dp->properties;
+	while (*prevp) {
+		struct property *prop = *prevp;
+
+		if (!strcmp(prop->name, name)) {
+			void *old_val = prop->value;
+			int ret;
+
+			ret = prom_setprop(dp->node, name, val, len);
+			err = -EINVAL;
+			if (ret >= 0) {
+				prop->value = new_val;
+				prop->length = len;
+
+				if (OF_IS_DYNAMIC(prop))
+					kfree(old_val);
+
+				OF_MARK_DYNAMIC(prop);
+
+				err = 0;
+			}
+			break;
+		}
+		prevp = &(*prevp)->next;
+	}
+	write_unlock(&devtree_lock);
+
+	/* XXX Upate procfs if necessary... */
+
+	return err;
+}
+EXPORT_SYMBOL(of_set_property);
+
+static unsigned int prom_early_allocated;
+
+static void * __init prom_early_alloc(unsigned long size)
+{
+	void *ret;
+
+	ret = __alloc_bootmem(size, SMP_CACHE_BYTES, 0UL);
+	if (ret != NULL)
+		memset(ret, 0, size);
+
+	prom_early_allocated += size;
+
+	return ret;
+}
+
+#ifdef CONFIG_PCI
+/* PSYCHO interrupt mapping support. */
+#define PSYCHO_IMAP_A_SLOT0	0x0c00UL
+#define PSYCHO_IMAP_B_SLOT0	0x0c20UL
+static unsigned long psycho_pcislot_imap_offset(unsigned long ino)
+{
+	unsigned int bus =  (ino & 0x10) >> 4;
+	unsigned int slot = (ino & 0x0c) >> 2;
+
+	if (bus == 0)
+		return PSYCHO_IMAP_A_SLOT0 + (slot * 8);
+	else
+		return PSYCHO_IMAP_B_SLOT0 + (slot * 8);
+}
+
+#define PSYCHO_IMAP_SCSI	0x1000UL
+#define PSYCHO_IMAP_ETH		0x1008UL
+#define PSYCHO_IMAP_BPP		0x1010UL
+#define PSYCHO_IMAP_AU_REC	0x1018UL
+#define PSYCHO_IMAP_AU_PLAY	0x1020UL
+#define PSYCHO_IMAP_PFAIL	0x1028UL
+#define PSYCHO_IMAP_KMS		0x1030UL
+#define PSYCHO_IMAP_FLPY	0x1038UL
+#define PSYCHO_IMAP_SHW		0x1040UL
+#define PSYCHO_IMAP_KBD		0x1048UL
+#define PSYCHO_IMAP_MS		0x1050UL
+#define PSYCHO_IMAP_SER		0x1058UL
+#define PSYCHO_IMAP_TIM0	0x1060UL
+#define PSYCHO_IMAP_TIM1	0x1068UL
+#define PSYCHO_IMAP_UE		0x1070UL
+#define PSYCHO_IMAP_CE		0x1078UL
+#define PSYCHO_IMAP_A_ERR	0x1080UL
+#define PSYCHO_IMAP_B_ERR	0x1088UL
+#define PSYCHO_IMAP_PMGMT	0x1090UL
+#define PSYCHO_IMAP_GFX		0x1098UL
+#define PSYCHO_IMAP_EUPA	0x10a0UL
+
+static unsigned long __psycho_onboard_imap_off[] = {
+/*0x20*/	PSYCHO_IMAP_SCSI,
+/*0x21*/	PSYCHO_IMAP_ETH,
+/*0x22*/	PSYCHO_IMAP_BPP,
+/*0x23*/	PSYCHO_IMAP_AU_REC,
+/*0x24*/	PSYCHO_IMAP_AU_PLAY,
+/*0x25*/	PSYCHO_IMAP_PFAIL,
+/*0x26*/	PSYCHO_IMAP_KMS,
+/*0x27*/	PSYCHO_IMAP_FLPY,
+/*0x28*/	PSYCHO_IMAP_SHW,
+/*0x29*/	PSYCHO_IMAP_KBD,
+/*0x2a*/	PSYCHO_IMAP_MS,
+/*0x2b*/	PSYCHO_IMAP_SER,
+/*0x2c*/	PSYCHO_IMAP_TIM0,
+/*0x2d*/	PSYCHO_IMAP_TIM1,
+/*0x2e*/	PSYCHO_IMAP_UE,
+/*0x2f*/	PSYCHO_IMAP_CE,
+/*0x30*/	PSYCHO_IMAP_A_ERR,
+/*0x31*/	PSYCHO_IMAP_B_ERR,
+/*0x32*/	PSYCHO_IMAP_PMGMT,
+/*0x33*/	PSYCHO_IMAP_GFX,
+/*0x34*/	PSYCHO_IMAP_EUPA,
+};
+#define PSYCHO_ONBOARD_IRQ_BASE		0x20
+#define PSYCHO_ONBOARD_IRQ_LAST		0x34
+#define psycho_onboard_imap_offset(__ino) \
+	__psycho_onboard_imap_off[(__ino) - PSYCHO_ONBOARD_IRQ_BASE]
+
+#define PSYCHO_ICLR_A_SLOT0	0x1400UL
+#define PSYCHO_ICLR_SCSI	0x1800UL
+
+#define psycho_iclr_offset(ino)					      \
+	((ino & 0x20) ? (PSYCHO_ICLR_SCSI + (((ino) & 0x1f) << 3)) :  \
+			(PSYCHO_ICLR_A_SLOT0 + (((ino) & 0x1f)<<3)))
+
+static unsigned int psycho_irq_build(struct device_node *dp,
+				     unsigned int ino,
+				     void *_data)
+{
+	unsigned long controller_regs = (unsigned long) _data;
+	unsigned long imap, iclr;
+	unsigned long imap_off, iclr_off;
+	int inofixup = 0;
+
+	ino &= 0x3f;
+	if (ino < PSYCHO_ONBOARD_IRQ_BASE) {
+		/* PCI slot */
+		imap_off = psycho_pcislot_imap_offset(ino);
+	} else {
+		/* Onboard device */
+		if (ino > PSYCHO_ONBOARD_IRQ_LAST) {
+			prom_printf("psycho_irq_build: Wacky INO [%x]\n", ino);
+			prom_halt();
+		}
+		imap_off = psycho_onboard_imap_offset(ino);
+	}
+
+	/* Now build the IRQ bucket. */
+	imap = controller_regs + imap_off;
+	imap += 4;
+
+	iclr_off = psycho_iclr_offset(ino);
+	iclr = controller_regs + iclr_off;
+	iclr += 4;
+
+	if ((ino & 0x20) == 0)
+		inofixup = ino & 0x03;
+
+	return build_irq(inofixup, iclr, imap);
+}
+
+static void psycho_irq_trans_init(struct device_node *dp)
+{
+	struct linux_prom64_registers *regs;
+
+	dp->irq_trans = prom_early_alloc(sizeof(struct of_irq_controller));
+	dp->irq_trans->irq_build = psycho_irq_build;
+
+	regs = of_get_property(dp, "reg", NULL);
+	dp->irq_trans->data = (void *) regs[2].phys_addr;
+}
+
+#define sabre_read(__reg) \
+({	u64 __ret; \
+	__asm__ __volatile__("ldxa [%1] %2, %0" \
+			     : "=r" (__ret) \
+			     : "r" (__reg), "i" (ASI_PHYS_BYPASS_EC_E) \
+			     : "memory"); \
+	__ret; \
+})
+
+struct sabre_irq_data {
+	unsigned long controller_regs;
+	unsigned int pci_first_busno;
+};
+#define SABRE_CONFIGSPACE	0x001000000UL
+#define SABRE_WRSYNC		0x1c20UL
+
+#define SABRE_CONFIG_BASE(CONFIG_SPACE)	\
+	(CONFIG_SPACE | (1UL << 24))
+#define SABRE_CONFIG_ENCODE(BUS, DEVFN, REG)	\
+	(((unsigned long)(BUS)   << 16) |	\
+	 ((unsigned long)(DEVFN) << 8)  |	\
+	 ((unsigned long)(REG)))
+
+/* When a device lives behind a bridge deeper in the PCI bus topology
+ * than APB, a special sequence must run to make sure all pending DMA
+ * transfers at the time of IRQ delivery are visible in the coherency
+ * domain by the cpu.  This sequence is to perform a read on the far
+ * side of the non-APB bridge, then perform a read of Sabre's DMA
+ * write-sync register.
+ */
+static void sabre_wsync_handler(unsigned int ino, void *_arg1, void *_arg2)
+{
+	unsigned int phys_hi = (unsigned int) (unsigned long) _arg1;
+	struct sabre_irq_data *irq_data = _arg2;
+	unsigned long controller_regs = irq_data->controller_regs;
+	unsigned long sync_reg = controller_regs + SABRE_WRSYNC;
+	unsigned long config_space = controller_regs + SABRE_CONFIGSPACE;
+	unsigned int bus, devfn;
+	u16 _unused;
+
+	config_space = SABRE_CONFIG_BASE(config_space);
+
+	bus = (phys_hi >> 16) & 0xff;
+	devfn = (phys_hi >> 8) & 0xff;
+
+	config_space |= SABRE_CONFIG_ENCODE(bus, devfn, 0x00);
+
+	__asm__ __volatile__("membar #Sync\n\t"
+			     "lduha [%1] %2, %0\n\t"
+			     "membar #Sync"
+			     : "=r" (_unused)
+			     : "r" ((u16 *) config_space),
+			       "i" (ASI_PHYS_BYPASS_EC_E_L)
+			     : "memory");
+
+	sabre_read(sync_reg);
+}
+
+#define SABRE_IMAP_A_SLOT0	0x0c00UL
+#define SABRE_IMAP_B_SLOT0	0x0c20UL
+#define SABRE_IMAP_SCSI		0x1000UL
+#define SABRE_IMAP_ETH		0x1008UL
+#define SABRE_IMAP_BPP		0x1010UL
+#define SABRE_IMAP_AU_REC	0x1018UL
+#define SABRE_IMAP_AU_PLAY	0x1020UL
+#define SABRE_IMAP_PFAIL	0x1028UL
+#define SABRE_IMAP_KMS		0x1030UL
+#define SABRE_IMAP_FLPY		0x1038UL
+#define SABRE_IMAP_SHW		0x1040UL
+#define SABRE_IMAP_KBD		0x1048UL
+#define SABRE_IMAP_MS		0x1050UL
+#define SABRE_IMAP_SER		0x1058UL
+#define SABRE_IMAP_UE		0x1070UL
+#define SABRE_IMAP_CE		0x1078UL
+#define SABRE_IMAP_PCIERR	0x1080UL
+#define SABRE_IMAP_GFX		0x1098UL
+#define SABRE_IMAP_EUPA		0x10a0UL
+#define SABRE_ICLR_A_SLOT0	0x1400UL
+#define SABRE_ICLR_B_SLOT0	0x1480UL
+#define SABRE_ICLR_SCSI		0x1800UL
+#define SABRE_ICLR_ETH		0x1808UL
+#define SABRE_ICLR_BPP		0x1810UL
+#define SABRE_ICLR_AU_REC	0x1818UL
+#define SABRE_ICLR_AU_PLAY	0x1820UL
+#define SABRE_ICLR_PFAIL	0x1828UL
+#define SABRE_ICLR_KMS		0x1830UL
+#define SABRE_ICLR_FLPY		0x1838UL
+#define SABRE_ICLR_SHW		0x1840UL
+#define SABRE_ICLR_KBD		0x1848UL
+#define SABRE_ICLR_MS		0x1850UL
+#define SABRE_ICLR_SER		0x1858UL
+#define SABRE_ICLR_UE		0x1870UL
+#define SABRE_ICLR_CE		0x1878UL
+#define SABRE_ICLR_PCIERR	0x1880UL
+
+static unsigned long sabre_pcislot_imap_offset(unsigned long ino)
+{
+	unsigned int bus =  (ino & 0x10) >> 4;
+	unsigned int slot = (ino & 0x0c) >> 2;
+
+	if (bus == 0)
+		return SABRE_IMAP_A_SLOT0 + (slot * 8);
+	else
+		return SABRE_IMAP_B_SLOT0 + (slot * 8);
+}
+
+static unsigned long __sabre_onboard_imap_off[] = {
+/*0x20*/	SABRE_IMAP_SCSI,
+/*0x21*/	SABRE_IMAP_ETH,
+/*0x22*/	SABRE_IMAP_BPP,
+/*0x23*/	SABRE_IMAP_AU_REC,
+/*0x24*/	SABRE_IMAP_AU_PLAY,
+/*0x25*/	SABRE_IMAP_PFAIL,
+/*0x26*/	SABRE_IMAP_KMS,
+/*0x27*/	SABRE_IMAP_FLPY,
+/*0x28*/	SABRE_IMAP_SHW,
+/*0x29*/	SABRE_IMAP_KBD,
+/*0x2a*/	SABRE_IMAP_MS,
+/*0x2b*/	SABRE_IMAP_SER,
+/*0x2c*/	0 /* reserved */,
+/*0x2d*/	0 /* reserved */,
+/*0x2e*/	SABRE_IMAP_UE,
+/*0x2f*/	SABRE_IMAP_CE,
+/*0x30*/	SABRE_IMAP_PCIERR,
+/*0x31*/	0 /* reserved */,
+/*0x32*/	0 /* reserved */,
+/*0x33*/	SABRE_IMAP_GFX,
+/*0x34*/	SABRE_IMAP_EUPA,
+};
+#define SABRE_ONBOARD_IRQ_BASE		0x20
+#define SABRE_ONBOARD_IRQ_LAST		0x30
+#define sabre_onboard_imap_offset(__ino) \
+	__sabre_onboard_imap_off[(__ino) - SABRE_ONBOARD_IRQ_BASE]
+
+#define sabre_iclr_offset(ino)					      \
+	((ino & 0x20) ? (SABRE_ICLR_SCSI + (((ino) & 0x1f) << 3)) :  \
+			(SABRE_ICLR_A_SLOT0 + (((ino) & 0x1f)<<3)))
+
+static int sabre_device_needs_wsync(struct device_node *dp)
+{
+	struct device_node *parent = dp->parent;
+	char *parent_model, *parent_compat;
+
+	/* This traversal up towards the root is meant to
+	 * handle two cases:
+	 *
+	 * 1) non-PCI bus sitting under PCI, such as 'ebus'
+	 * 2) the PCI controller interrupts themselves, which
+	 *    will use the sabre_irq_build but do not need
+	 *    the DMA synchronization handling
+	 */
+	while (parent) {
+		if (!strcmp(parent->type, "pci"))
+			break;
+		parent = parent->parent;
+	}
+
+	if (!parent)
+		return 0;
+
+	parent_model = of_get_property(parent,
+				       "model", NULL);
+	if (parent_model &&
+	    (!strcmp(parent_model, "SUNW,sabre") ||
+	     !strcmp(parent_model, "SUNW,simba")))
+		return 0;
+
+	parent_compat = of_get_property(parent,
+					"compatible", NULL);
+	if (parent_compat &&
+	    (!strcmp(parent_compat, "pci108e,a000") ||
+	     !strcmp(parent_compat, "pci108e,a001")))
+		return 0;
+
+	return 1;
+}
+
+static unsigned int sabre_irq_build(struct device_node *dp,
+				    unsigned int ino,
+				    void *_data)
+{
+	struct sabre_irq_data *irq_data = _data;
+	unsigned long controller_regs = irq_data->controller_regs;
+	struct linux_prom_pci_registers *regs;
+	unsigned long imap, iclr;
+	unsigned long imap_off, iclr_off;
+	int inofixup = 0;
+	int virt_irq;
+
+	ino &= 0x3f;
+	if (ino < SABRE_ONBOARD_IRQ_BASE) {
+		/* PCI slot */
+		imap_off = sabre_pcislot_imap_offset(ino);
+	} else {
+		/* onboard device */
+		if (ino > SABRE_ONBOARD_IRQ_LAST) {
+			prom_printf("sabre_irq_build: Wacky INO [%x]\n", ino);
+			prom_halt();
+		}
+		imap_off = sabre_onboard_imap_offset(ino);
+	}
+
+	/* Now build the IRQ bucket. */
+	imap = controller_regs + imap_off;
+	imap += 4;
+
+	iclr_off = sabre_iclr_offset(ino);
+	iclr = controller_regs + iclr_off;
+	iclr += 4;
+
+	if ((ino & 0x20) == 0)
+		inofixup = ino & 0x03;
+
+	virt_irq = build_irq(inofixup, iclr, imap);
+
+	/* If the parent device is a PCI<->PCI bridge other than
+	 * APB, we have to install a pre-handler to ensure that
+	 * all pending DMA is drained before the interrupt handler
+	 * is run.
+	 */
+	regs = of_get_property(dp, "reg", NULL);
+	if (regs && sabre_device_needs_wsync(dp)) {
+		irq_install_pre_handler(virt_irq,
+					sabre_wsync_handler,
+					(void *) (long) regs->phys_hi,
+					(void *) irq_data);
+	}
+
+	return virt_irq;
+}
+
+static void sabre_irq_trans_init(struct device_node *dp)
+{
+	struct linux_prom64_registers *regs;
+	struct sabre_irq_data *irq_data;
+	u32 *busrange;
+
+	dp->irq_trans = prom_early_alloc(sizeof(struct of_irq_controller));
+	dp->irq_trans->irq_build = sabre_irq_build;
+
+	irq_data = prom_early_alloc(sizeof(struct sabre_irq_data));
+
+	regs = of_get_property(dp, "reg", NULL);
+	irq_data->controller_regs = regs[0].phys_addr;
+
+	busrange = of_get_property(dp, "bus-range", NULL);
+	irq_data->pci_first_busno = busrange[0];
+
+	dp->irq_trans->data = irq_data;
+}
+
+/* SCHIZO interrupt mapping support.  Unlike Psycho, for this controller the
+ * imap/iclr registers are per-PBM.
+ */
+#define SCHIZO_IMAP_BASE	0x1000UL
+#define SCHIZO_ICLR_BASE	0x1400UL
+
+static unsigned long schizo_imap_offset(unsigned long ino)
+{
+	return SCHIZO_IMAP_BASE + (ino * 8UL);
+}
+
+static unsigned long schizo_iclr_offset(unsigned long ino)
+{
+	return SCHIZO_ICLR_BASE + (ino * 8UL);
+}
+
+static unsigned long schizo_ino_to_iclr(unsigned long pbm_regs,
+					unsigned int ino)
+{
+	return pbm_regs + schizo_iclr_offset(ino) + 4;
+}
+
+static unsigned long schizo_ino_to_imap(unsigned long pbm_regs,
+					unsigned int ino)
+{
+	return pbm_regs + schizo_imap_offset(ino) + 4;
+}
+
+#define schizo_read(__reg) \
+({	u64 __ret; \
+	__asm__ __volatile__("ldxa [%1] %2, %0" \
+			     : "=r" (__ret) \
+			     : "r" (__reg), "i" (ASI_PHYS_BYPASS_EC_E) \
+			     : "memory"); \
+	__ret; \
+})
+#define schizo_write(__reg, __val) \
+	__asm__ __volatile__("stxa %0, [%1] %2" \
+			     : /* no outputs */ \
+			     : "r" (__val), "r" (__reg), \
+			       "i" (ASI_PHYS_BYPASS_EC_E) \
+			     : "memory")
+
+static void tomatillo_wsync_handler(unsigned int ino, void *_arg1, void *_arg2)
+{
+	unsigned long sync_reg = (unsigned long) _arg2;
+	u64 mask = 1UL << (ino & IMAP_INO);
+	u64 val;
+	int limit;
+
+	schizo_write(sync_reg, mask);
+
+	limit = 100000;
+	val = 0;
+	while (--limit) {
+		val = schizo_read(sync_reg);
+		if (!(val & mask))
+			break;
+	}
+	if (limit <= 0) {
+		printk("tomatillo_wsync_handler: DMA won't sync [%lx:%lx]\n",
+		       val, mask);
+	}
+
+	if (_arg1) {
+		static unsigned char cacheline[64]
+			__attribute__ ((aligned (64)));
+
+		__asm__ __volatile__("rd %%fprs, %0\n\t"
+				     "or %0, %4, %1\n\t"
+				     "wr %1, 0x0, %%fprs\n\t"
+				     "stda %%f0, [%5] %6\n\t"
+				     "wr %0, 0x0, %%fprs\n\t"
+				     "membar #Sync"
+				     : "=&r" (mask), "=&r" (val)
+				     : "0" (mask), "1" (val),
+				     "i" (FPRS_FEF), "r" (&cacheline[0]),
+				     "i" (ASI_BLK_COMMIT_P));
+	}
+}
+
+struct schizo_irq_data {
+	unsigned long pbm_regs;
+	unsigned long sync_reg;
+	u32 portid;
+	int chip_version;
+};
+
+static unsigned int schizo_irq_build(struct device_node *dp,
+				     unsigned int ino,
+				     void *_data)
+{
+	struct schizo_irq_data *irq_data = _data;
+	unsigned long pbm_regs = irq_data->pbm_regs;
+	unsigned long imap, iclr;
+	int ign_fixup;
+	int virt_irq;
+	int is_tomatillo;
+
+	ino &= 0x3f;
+
+	/* Now build the IRQ bucket. */
+	imap = schizo_ino_to_imap(pbm_regs, ino);
+	iclr = schizo_ino_to_iclr(pbm_regs, ino);
+
+	/* On Schizo, no inofixup occurs.  This is because each
+	 * INO has it's own IMAP register.  On Psycho and Sabre
+	 * there is only one IMAP register for each PCI slot even
+	 * though four different INOs can be generated by each
+	 * PCI slot.
+	 *
+	 * But, for JBUS variants (essentially, Tomatillo), we have
+	 * to fixup the lowest bit of the interrupt group number.
+	 */
+	ign_fixup = 0;
+
+	is_tomatillo = (irq_data->sync_reg != 0UL);
+
+	if (is_tomatillo) {
+		if (irq_data->portid & 1)
+			ign_fixup = (1 << 6);
+	}
+
+	virt_irq = build_irq(ign_fixup, iclr, imap);
+
+	if (is_tomatillo) {
+		irq_install_pre_handler(virt_irq,
+					tomatillo_wsync_handler,
+					((irq_data->chip_version <= 4) ?
+					 (void *) 1 : (void *) 0),
+					(void *) irq_data->sync_reg);
+	}
+
+	return virt_irq;
+}
+
+static void schizo_irq_trans_init(struct device_node *dp)
+{
+	struct linux_prom64_registers *regs;
+	struct schizo_irq_data *irq_data;
+
+	dp->irq_trans = prom_early_alloc(sizeof(struct of_irq_controller));
+	dp->irq_trans->irq_build = schizo_irq_build;
+
+	irq_data = prom_early_alloc(sizeof(struct schizo_irq_data));
+
+	regs = of_get_property(dp, "reg", NULL);
+	dp->irq_trans->data = irq_data;
+
+	irq_data->pbm_regs = regs[0].phys_addr;
+	irq_data->sync_reg = regs[3].phys_addr + 0x1a18UL;
+	irq_data->portid = of_getintprop_default(dp, "portid", 0);
+	irq_data->chip_version = of_getintprop_default(dp, "version#", 0);
+}
+
+static unsigned int pci_sun4v_irq_build(struct device_node *dp,
+					unsigned int devino,
+					void *_data)
+{
+	u32 devhandle = (u32) (unsigned long) _data;
+
+	return sun4v_build_irq(devhandle, devino);
+}
+
+static void pci_sun4v_irq_trans_init(struct device_node *dp)
+{
+	struct linux_prom64_registers *regs;
+
+	dp->irq_trans = prom_early_alloc(sizeof(struct of_irq_controller));
+	dp->irq_trans->irq_build = pci_sun4v_irq_build;
+
+	regs = of_get_property(dp, "reg", NULL);
+	dp->irq_trans->data = (void *) (unsigned long)
+		((regs->phys_addr >> 32UL) & 0x0fffffff);
+}
+#endif /* CONFIG_PCI */
+
+#ifdef CONFIG_SBUS
+/* INO number to IMAP register offset for SYSIO external IRQ's.
+ * This should conform to both Sunfire/Wildfire server and Fusion
+ * desktop designs.
+ */
+#define SYSIO_IMAP_SLOT0	0x2c04UL
+#define SYSIO_IMAP_SLOT1	0x2c0cUL
+#define SYSIO_IMAP_SLOT2	0x2c14UL
+#define SYSIO_IMAP_SLOT3	0x2c1cUL
+#define SYSIO_IMAP_SCSI		0x3004UL
+#define SYSIO_IMAP_ETH		0x300cUL
+#define SYSIO_IMAP_BPP		0x3014UL
+#define SYSIO_IMAP_AUDIO	0x301cUL
+#define SYSIO_IMAP_PFAIL	0x3024UL
+#define SYSIO_IMAP_KMS		0x302cUL
+#define SYSIO_IMAP_FLPY		0x3034UL
+#define SYSIO_IMAP_SHW		0x303cUL
+#define SYSIO_IMAP_KBD		0x3044UL
+#define SYSIO_IMAP_MS		0x304cUL
+#define SYSIO_IMAP_SER		0x3054UL
+#define SYSIO_IMAP_TIM0		0x3064UL
+#define SYSIO_IMAP_TIM1		0x306cUL
+#define SYSIO_IMAP_UE		0x3074UL
+#define SYSIO_IMAP_CE		0x307cUL
+#define SYSIO_IMAP_SBERR	0x3084UL
+#define SYSIO_IMAP_PMGMT	0x308cUL
+#define SYSIO_IMAP_GFX		0x3094UL
+#define SYSIO_IMAP_EUPA		0x309cUL
+
+#define bogon     ((unsigned long) -1)
+static unsigned long sysio_irq_offsets[] = {
+	/* SBUS Slot 0 --> 3, level 1 --> 7 */
+	SYSIO_IMAP_SLOT0, SYSIO_IMAP_SLOT0, SYSIO_IMAP_SLOT0, SYSIO_IMAP_SLOT0,
+	SYSIO_IMAP_SLOT0, SYSIO_IMAP_SLOT0, SYSIO_IMAP_SLOT0, SYSIO_IMAP_SLOT0,
+	SYSIO_IMAP_SLOT1, SYSIO_IMAP_SLOT1, SYSIO_IMAP_SLOT1, SYSIO_IMAP_SLOT1,
+	SYSIO_IMAP_SLOT1, SYSIO_IMAP_SLOT1, SYSIO_IMAP_SLOT1, SYSIO_IMAP_SLOT1,
+	SYSIO_IMAP_SLOT2, SYSIO_IMAP_SLOT2, SYSIO_IMAP_SLOT2, SYSIO_IMAP_SLOT2,
+	SYSIO_IMAP_SLOT2, SYSIO_IMAP_SLOT2, SYSIO_IMAP_SLOT2, SYSIO_IMAP_SLOT2,
+	SYSIO_IMAP_SLOT3, SYSIO_IMAP_SLOT3, SYSIO_IMAP_SLOT3, SYSIO_IMAP_SLOT3,
+	SYSIO_IMAP_SLOT3, SYSIO_IMAP_SLOT3, SYSIO_IMAP_SLOT3, SYSIO_IMAP_SLOT3,
+
+	/* Onboard devices (not relevant/used on SunFire). */
+	SYSIO_IMAP_SCSI,
+	SYSIO_IMAP_ETH,
+	SYSIO_IMAP_BPP,
+	bogon,
+	SYSIO_IMAP_AUDIO,
+	SYSIO_IMAP_PFAIL,
+	bogon,
+	bogon,
+	SYSIO_IMAP_KMS,
+	SYSIO_IMAP_FLPY,
+	SYSIO_IMAP_SHW,
+	SYSIO_IMAP_KBD,
+	SYSIO_IMAP_MS,
+	SYSIO_IMAP_SER,
+	bogon,
+	bogon,
+	SYSIO_IMAP_TIM0,
+	SYSIO_IMAP_TIM1,
+	bogon,
+	bogon,
+	SYSIO_IMAP_UE,
+	SYSIO_IMAP_CE,
+	SYSIO_IMAP_SBERR,
+	SYSIO_IMAP_PMGMT,
+	SYSIO_IMAP_GFX,
+	SYSIO_IMAP_EUPA,
+};
+
+#undef bogon
+
+#define NUM_SYSIO_OFFSETS ARRAY_SIZE(sysio_irq_offsets)
+
+/* Convert Interrupt Mapping register pointer to associated
+ * Interrupt Clear register pointer, SYSIO specific version.
+ */
+#define SYSIO_ICLR_UNUSED0	0x3400UL
+#define SYSIO_ICLR_SLOT0	0x340cUL
+#define SYSIO_ICLR_SLOT1	0x344cUL
+#define SYSIO_ICLR_SLOT2	0x348cUL
+#define SYSIO_ICLR_SLOT3	0x34ccUL
+static unsigned long sysio_imap_to_iclr(unsigned long imap)
+{
+	unsigned long diff = SYSIO_ICLR_UNUSED0 - SYSIO_IMAP_SLOT0;
+	return imap + diff;
+}
+
+static unsigned int sbus_of_build_irq(struct device_node *dp,
+				      unsigned int ino,
+				      void *_data)
+{
+	unsigned long reg_base = (unsigned long) _data;
+	struct linux_prom_registers *regs;
+	unsigned long imap, iclr;
+	int sbus_slot = 0;
+	int sbus_level = 0;
+
+	ino &= 0x3f;
+
+	regs = of_get_property(dp, "reg", NULL);
+	if (regs)
+		sbus_slot = regs->which_io;
+
+	if (ino < 0x20)
+		ino += (sbus_slot * 8);
+
+	imap = sysio_irq_offsets[ino];
+	if (imap == ((unsigned long)-1)) {
+		prom_printf("get_irq_translations: Bad SYSIO INO[%x]\n",
+			    ino);
+		prom_halt();
+	}
+	imap += reg_base;
+
+	/* SYSIO inconsistency.  For external SLOTS, we have to select
+	 * the right ICLR register based upon the lower SBUS irq level
+	 * bits.
+	 */
+	if (ino >= 0x20) {
+		iclr = sysio_imap_to_iclr(imap);
+	} else {
+		sbus_level = ino & 0x7;
+
+		switch(sbus_slot) {
+		case 0:
+			iclr = reg_base + SYSIO_ICLR_SLOT0;
+			break;
+		case 1:
+			iclr = reg_base + SYSIO_ICLR_SLOT1;
+			break;
+		case 2:
+			iclr = reg_base + SYSIO_ICLR_SLOT2;
+			break;
+		default:
+		case 3:
+			iclr = reg_base + SYSIO_ICLR_SLOT3;
+			break;
+		};
+
+		iclr += ((unsigned long)sbus_level - 1UL) * 8UL;
+	}
+	return build_irq(sbus_level, iclr, imap);
+}
+
+static void sbus_irq_trans_init(struct device_node *dp)
+{
+	struct linux_prom64_registers *regs;
+
+	dp->irq_trans = prom_early_alloc(sizeof(struct of_irq_controller));
+	dp->irq_trans->irq_build = sbus_of_build_irq;
+
+	regs = of_get_property(dp, "reg", NULL);
+	dp->irq_trans->data = (void *) (unsigned long) regs->phys_addr;
+}
+#endif /* CONFIG_SBUS */
+
+
+static unsigned int central_build_irq(struct device_node *dp,
+				      unsigned int ino,
+				      void *_data)
+{
+	struct device_node *central_dp = _data;
+	struct of_device *central_op = of_find_device_by_node(central_dp);
+	struct resource *res;
+	unsigned long imap, iclr;
+	u32 tmp;
+
+	if (!strcmp(dp->name, "eeprom")) {
+		res = &central_op->resource[5];
+	} else if (!strcmp(dp->name, "zs")) {
+		res = &central_op->resource[4];
+	} else if (!strcmp(dp->name, "clock-board")) {
+		res = &central_op->resource[3];
+	} else {
+		return ino;
+	}
+
+	imap = res->start + 0x00UL;
+	iclr = res->start + 0x10UL;
+
+	/* Set the INO state to idle, and disable.  */
+	upa_writel(0, iclr);
+	upa_readl(iclr);
+
+	tmp = upa_readl(imap);
+	tmp &= ~0x80000000;
+	upa_writel(tmp, imap);
+
+	return build_irq(0, iclr, imap);
+}
+
+static void central_irq_trans_init(struct device_node *dp)
+{
+	dp->irq_trans = prom_early_alloc(sizeof(struct of_irq_controller));
+	dp->irq_trans->irq_build = central_build_irq;
+
+	dp->irq_trans->data = dp;
+}
+
+struct irq_trans {
+	const char *name;
+	void (*init)(struct device_node *);
+};
+
+#ifdef CONFIG_PCI
+static struct irq_trans pci_irq_trans_table[] = {
+	{ "SUNW,sabre", sabre_irq_trans_init },
+	{ "pci108e,a000", sabre_irq_trans_init },
+	{ "pci108e,a001", sabre_irq_trans_init },
+	{ "SUNW,psycho", psycho_irq_trans_init },
+	{ "pci108e,8000", psycho_irq_trans_init },
+	{ "SUNW,schizo", schizo_irq_trans_init },
+	{ "pci108e,8001", schizo_irq_trans_init },
+	{ "SUNW,schizo+", schizo_irq_trans_init },
+	{ "pci108e,8002", schizo_irq_trans_init },
+	{ "SUNW,tomatillo", schizo_irq_trans_init },
+	{ "pci108e,a801", schizo_irq_trans_init },
+	{ "SUNW,sun4v-pci", pci_sun4v_irq_trans_init },
+};
+#endif
+
+static unsigned int sun4v_vdev_irq_build(struct device_node *dp,
+					 unsigned int devino,
+					 void *_data)
+{
+	u32 devhandle = (u32) (unsigned long) _data;
+
+	return sun4v_build_irq(devhandle, devino);
+}
+
+static void sun4v_vdev_irq_trans_init(struct device_node *dp)
+{
+	struct linux_prom64_registers *regs;
+
+	dp->irq_trans = prom_early_alloc(sizeof(struct of_irq_controller));
+	dp->irq_trans->irq_build = sun4v_vdev_irq_build;
+
+	regs = of_get_property(dp, "reg", NULL);
+	dp->irq_trans->data = (void *) (unsigned long)
+		((regs->phys_addr >> 32UL) & 0x0fffffff);
+}
+
+static void irq_trans_init(struct device_node *dp)
+{
+#ifdef CONFIG_PCI
+	const char *model;
+	int i;
+#endif
+
+#ifdef CONFIG_PCI
+	model = of_get_property(dp, "model", NULL);
+	if (!model)
+		model = of_get_property(dp, "compatible", NULL);
+	if (model) {
+		for (i = 0; i < ARRAY_SIZE(pci_irq_trans_table); i++) {
+			struct irq_trans *t = &pci_irq_trans_table[i];
+
+			if (!strcmp(model, t->name))
+				return t->init(dp);
+		}
+	}
+#endif
+#ifdef CONFIG_SBUS
+	if (!strcmp(dp->name, "sbus") ||
+	    !strcmp(dp->name, "sbi"))
+		return sbus_irq_trans_init(dp);
+#endif
+	if (!strcmp(dp->name, "fhc") &&
+	    !strcmp(dp->parent->name, "central"))
+		return central_irq_trans_init(dp);
+	if (!strcmp(dp->name, "virtual-devices"))
+		return sun4v_vdev_irq_trans_init(dp);
+}
+
+static int is_root_node(const struct device_node *dp)
+{
+	if (!dp)
+		return 0;
+
+	return (dp->parent == NULL);
+}
+
+/* The following routines deal with the black magic of fully naming a
+ * node.
+ *
+ * Certain well known named nodes are just the simple name string.
+ *
+ * Actual devices have an address specifier appended to the base name
+ * string, like this "foo@addr".  The "addr" can be in any number of
+ * formats, and the platform plus the type of the node determine the
+ * format and how it is constructed.
+ *
+ * For children of the ROOT node, the naming convention is fixed and
+ * determined by whether this is a sun4u or sun4v system.
+ *
+ * For children of other nodes, it is bus type specific.  So
+ * we walk up the tree until we discover a "device_type" property
+ * we recognize and we go from there.
+ *
+ * As an example, the boot device on my workstation has a full path:
+ *
+ *	/pci@1e,600000/ide@d/disk@0,0:c
+ */
+static void __init sun4v_path_component(struct device_node *dp, char *tmp_buf)
+{
+	struct linux_prom64_registers *regs;
+	struct property *rprop;
+	u32 high_bits, low_bits, type;
+
+	rprop = of_find_property(dp, "reg", NULL);
+	if (!rprop)
+		return;
+
+	regs = rprop->value;
+	if (!is_root_node(dp->parent)) {
+		sprintf(tmp_buf, "%s@%x,%x",
+			dp->name,
+			(unsigned int) (regs->phys_addr >> 32UL),
+			(unsigned int) (regs->phys_addr & 0xffffffffUL));
+		return;
+	}
+
+	type = regs->phys_addr >> 60UL;
+	high_bits = (regs->phys_addr >> 32UL) & 0x0fffffffUL;
+	low_bits = (regs->phys_addr & 0xffffffffUL);
+
+	if (type == 0 || type == 8) {
+		const char *prefix = (type == 0) ? "m" : "i";
+
+		if (low_bits)
+			sprintf(tmp_buf, "%s@%s%x,%x",
+				dp->name, prefix,
+				high_bits, low_bits);
+		else
+			sprintf(tmp_buf, "%s@%s%x",
+				dp->name,
+				prefix,
+				high_bits);
+	} else if (type == 12) {
+		sprintf(tmp_buf, "%s@%x",
+			dp->name, high_bits);
+	}
+}
+
+static void __init sun4u_path_component(struct device_node *dp, char *tmp_buf)
+{
+	struct linux_prom64_registers *regs;
+	struct property *prop;
+
+	prop = of_find_property(dp, "reg", NULL);
+	if (!prop)
+		return;
+
+	regs = prop->value;
+	if (!is_root_node(dp->parent)) {
+		sprintf(tmp_buf, "%s@%x,%x",
+			dp->name,
+			(unsigned int) (regs->phys_addr >> 32UL),
+			(unsigned int) (regs->phys_addr & 0xffffffffUL));
+		return;
+	}
+
+	prop = of_find_property(dp, "upa-portid", NULL);
+	if (!prop)
+		prop = of_find_property(dp, "portid", NULL);
+	if (prop) {
+		unsigned long mask = 0xffffffffUL;
+
+		if (tlb_type >= cheetah)
+			mask = 0x7fffff;
+
+		sprintf(tmp_buf, "%s@%x,%x",
+			dp->name,
+			*(u32 *)prop->value,
+			(unsigned int) (regs->phys_addr & mask));
+	}
+}
+
+/* "name@slot,offset"  */
+static void __init sbus_path_component(struct device_node *dp, char *tmp_buf)
+{
+	struct linux_prom_registers *regs;
+	struct property *prop;
+
+	prop = of_find_property(dp, "reg", NULL);
+	if (!prop)
+		return;
+
+	regs = prop->value;
+	sprintf(tmp_buf, "%s@%x,%x",
+		dp->name,
+		regs->which_io,
+		regs->phys_addr);
+}
+
+/* "name@devnum[,func]" */
+static void __init pci_path_component(struct device_node *dp, char *tmp_buf)
+{
+	struct linux_prom_pci_registers *regs;
+	struct property *prop;
+	unsigned int devfn;
+
+	prop = of_find_property(dp, "reg", NULL);
+	if (!prop)
+		return;
+
+	regs = prop->value;
+	devfn = (regs->phys_hi >> 8) & 0xff;
+	if (devfn & 0x07) {
+		sprintf(tmp_buf, "%s@%x,%x",
+			dp->name,
+			devfn >> 3,
+			devfn & 0x07);
+	} else {
+		sprintf(tmp_buf, "%s@%x",
+			dp->name,
+			devfn >> 3);
+	}
+}
+
+/* "name@UPA_PORTID,offset" */
+static void __init upa_path_component(struct device_node *dp, char *tmp_buf)
+{
+	struct linux_prom64_registers *regs;
+	struct property *prop;
+
+	prop = of_find_property(dp, "reg", NULL);
+	if (!prop)
+		return;
+
+	regs = prop->value;
+
+	prop = of_find_property(dp, "upa-portid", NULL);
+	if (!prop)
+		return;
+
+	sprintf(tmp_buf, "%s@%x,%x",
+		dp->name,
+		*(u32 *) prop->value,
+		(unsigned int) (regs->phys_addr & 0xffffffffUL));
+}
+
+/* "name@reg" */
+static void __init vdev_path_component(struct device_node *dp, char *tmp_buf)
+{
+	struct property *prop;
+	u32 *regs;
+
+	prop = of_find_property(dp, "reg", NULL);
+	if (!prop)
+		return;
+
+	regs = prop->value;
+
+	sprintf(tmp_buf, "%s@%x", dp->name, *regs);
+}
+
+/* "name@addrhi,addrlo" */
+static void __init ebus_path_component(struct device_node *dp, char *tmp_buf)
+{
+	struct linux_prom64_registers *regs;
+	struct property *prop;
+
+	prop = of_find_property(dp, "reg", NULL);
+	if (!prop)
+		return;
+
+	regs = prop->value;
+
+	sprintf(tmp_buf, "%s@%x,%x",
+		dp->name,
+		(unsigned int) (regs->phys_addr >> 32UL),
+		(unsigned int) (regs->phys_addr & 0xffffffffUL));
+}
+
+/* "name@bus,addr" */
+static void __init i2c_path_component(struct device_node *dp, char *tmp_buf)
+{
+	struct property *prop;
+	u32 *regs;
+
+	prop = of_find_property(dp, "reg", NULL);
+	if (!prop)
+		return;
+
+	regs = prop->value;
+
+	/* This actually isn't right... should look at the #address-cells
+	 * property of the i2c bus node etc. etc.
+	 */
+	sprintf(tmp_buf, "%s@%x,%x",
+		dp->name, regs[0], regs[1]);
+}
+
+/* "name@reg0[,reg1]" */
+static void __init usb_path_component(struct device_node *dp, char *tmp_buf)
+{
+	struct property *prop;
+	u32 *regs;
+
+	prop = of_find_property(dp, "reg", NULL);
+	if (!prop)
+		return;
+
+	regs = prop->value;
+
+	if (prop->length == sizeof(u32) || regs[1] == 1) {
+		sprintf(tmp_buf, "%s@%x",
+			dp->name, regs[0]);
+	} else {
+		sprintf(tmp_buf, "%s@%x,%x",
+			dp->name, regs[0], regs[1]);
+	}
+}
+
+/* "name@reg0reg1[,reg2reg3]" */
+static void __init ieee1394_path_component(struct device_node *dp, char *tmp_buf)
+{
+	struct property *prop;
+	u32 *regs;
+
+	prop = of_find_property(dp, "reg", NULL);
+	if (!prop)
+		return;
+
+	regs = prop->value;
+
+	if (regs[2] || regs[3]) {
+		sprintf(tmp_buf, "%s@%08x%08x,%04x%08x",
+			dp->name, regs[0], regs[1], regs[2], regs[3]);
+	} else {
+		sprintf(tmp_buf, "%s@%08x%08x",
+			dp->name, regs[0], regs[1]);
+	}
+}
+
+static void __init __build_path_component(struct device_node *dp, char *tmp_buf)
+{
+	struct device_node *parent = dp->parent;
+
+	if (parent != NULL) {
+		if (!strcmp(parent->type, "pci") ||
+		    !strcmp(parent->type, "pciex"))
+			return pci_path_component(dp, tmp_buf);
+		if (!strcmp(parent->type, "sbus"))
+			return sbus_path_component(dp, tmp_buf);
+		if (!strcmp(parent->type, "upa"))
+			return upa_path_component(dp, tmp_buf);
+		if (!strcmp(parent->type, "ebus"))
+			return ebus_path_component(dp, tmp_buf);
+		if (!strcmp(parent->name, "usb") ||
+		    !strcmp(parent->name, "hub"))
+			return usb_path_component(dp, tmp_buf);
+		if (!strcmp(parent->type, "i2c"))
+			return i2c_path_component(dp, tmp_buf);
+		if (!strcmp(parent->type, "firewire"))
+			return ieee1394_path_component(dp, tmp_buf);
+		if (!strcmp(parent->type, "virtual-devices"))
+			return vdev_path_component(dp, tmp_buf);
+
+		/* "isa" is handled with platform naming */
+	}
+
+	/* Use platform naming convention.  */
+	if (tlb_type == hypervisor)
+		return sun4v_path_component(dp, tmp_buf);
+	else
+		return sun4u_path_component(dp, tmp_buf);
+}
+
+static char * __init build_path_component(struct device_node *dp)
+{
+	char tmp_buf[64], *n;
+
+	tmp_buf[0] = '\0';
+	__build_path_component(dp, tmp_buf);
+	if (tmp_buf[0] == '\0')
+		strcpy(tmp_buf, dp->name);
+
+	n = prom_early_alloc(strlen(tmp_buf) + 1);
+	strcpy(n, tmp_buf);
+
+	return n;
+}
+
+static char * __init build_full_name(struct device_node *dp)
+{
+	int len, ourlen, plen;
+	char *n;
+
+	plen = strlen(dp->parent->full_name);
+	ourlen = strlen(dp->path_component_name);
+	len = ourlen + plen + 2;
+
+	n = prom_early_alloc(len);
+	strcpy(n, dp->parent->full_name);
+	if (!is_root_node(dp->parent)) {
+		strcpy(n + plen, "/");
+		plen++;
+	}
+	strcpy(n + plen, dp->path_component_name);
+
+	return n;
+}
+
+static unsigned int unique_id;
+
+static struct property * __init build_one_prop(phandle node, char *prev, char *special_name, void *special_val, int special_len)
+{
+	static struct property *tmp = NULL;
+	struct property *p;
+
+	if (tmp) {
+		p = tmp;
+		memset(p, 0, sizeof(*p) + 32);
+		tmp = NULL;
+	} else {
+		p = prom_early_alloc(sizeof(struct property) + 32);
+		p->unique_id = unique_id++;
+	}
+
+	p->name = (char *) (p + 1);
+	if (special_name) {
+		strcpy(p->name, special_name);
+		p->length = special_len;
+		p->value = prom_early_alloc(special_len);
+		memcpy(p->value, special_val, special_len);
+	} else {
+		if (prev == NULL) {
+			prom_firstprop(node, p->name);
+		} else {
+			prom_nextprop(node, prev, p->name);
+		}
+		if (strlen(p->name) == 0) {
+			tmp = p;
+			return NULL;
+		}
+		p->length = prom_getproplen(node, p->name);
+		if (p->length <= 0) {
+			p->length = 0;
+		} else {
+			p->value = prom_early_alloc(p->length + 1);
+			prom_getproperty(node, p->name, p->value, p->length);
+			((unsigned char *)p->value)[p->length] = '\0';
+		}
+	}
+	return p;
+}
+
+static struct property * __init build_prop_list(phandle node)
+{
+	struct property *head, *tail;
+
+	head = tail = build_one_prop(node, NULL,
+				     ".node", &node, sizeof(node));
+
+	tail->next = build_one_prop(node, NULL, NULL, NULL, 0);
+	tail = tail->next;
+	while(tail) {
+		tail->next = build_one_prop(node, tail->name,
+					    NULL, NULL, 0);
+		tail = tail->next;
+	}
+
+	return head;
+}
+
+static char * __init get_one_property(phandle node, const char *name)
+{
+	char *buf = "<NULL>";
+	int len;
+
+	len = prom_getproplen(node, name);
+	if (len > 0) {
+		buf = prom_early_alloc(len);
+		prom_getproperty(node, name, buf, len);
+	}
+
+	return buf;
+}
+
+static struct device_node * __init create_node(phandle node, struct device_node *parent)
+{
+	struct device_node *dp;
+
+	if (!node)
+		return NULL;
+
+	dp = prom_early_alloc(sizeof(*dp));
+	dp->unique_id = unique_id++;
+	dp->parent = parent;
+
+	kref_init(&dp->kref);
+
+	dp->name = get_one_property(node, "name");
+	dp->type = get_one_property(node, "device_type");
+	dp->node = node;
+
+	dp->properties = build_prop_list(node);
+
+	irq_trans_init(dp);
+
+	return dp;
+}
+
+static struct device_node * __init build_tree(struct device_node *parent, phandle node, struct device_node ***nextp)
+{
+	struct device_node *dp;
+
+	dp = create_node(node, parent);
+	if (dp) {
+		*(*nextp) = dp;
+		*nextp = &dp->allnext;
+
+		dp->path_component_name = build_path_component(dp);
+		dp->full_name = build_full_name(dp);
+
+		dp->child = build_tree(dp, prom_getchild(node), nextp);
+
+		dp->sibling = build_tree(parent, prom_getsibling(node), nextp);
+	}
+
+	return dp;
+}
+
+void __init prom_build_devicetree(void)
+{
+	struct device_node **nextp;
+
+	allnodes = create_node(prom_root_node, NULL);
+	allnodes->path_component_name = "";
+	allnodes->full_name = "/";
+
+	nextp = &allnodes->allnext;
+	allnodes->child = build_tree(allnodes,
+				     prom_getchild(allnodes->node),
+				     &nextp);
+	printk("PROM: Built device tree with %u bytes of memory.\n",
+	       prom_early_allocated);
+}
diff --git a/arch/um/kernel/exec.c b/arch/um/kernel/exec.c
new file mode 100644
index 000000000..fc38a6d59
--- /dev/null
+++ b/arch/um/kernel/exec.c
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2000, 2001 Jeff Dike (jdike@karaya.com)
+ * Licensed under the GPL
+ */
+
+#include "linux/slab.h"
+#include "linux/smp_lock.h"
+#include "linux/ptrace.h"
+#include "asm/ptrace.h"
+#include "asm/pgtable.h"
+#include "asm/tlbflush.h"
+#include "asm/uaccess.h"
+#include "user_util.h"
+#include "kern_util.h"
+#include "mem_user.h"
+#include "kern.h"
+#include "irq_user.h"
+#include "tlb.h"
+#include "os.h"
+#include "choose-mode.h"
+#include "mode_kern.h"
+
+void flush_thread(void)
+{
+	arch_flush_thread(&current->thread.arch);
+	CHOOSE_MODE(flush_thread_tt(), flush_thread_skas());
+}
+
+void start_thread(struct pt_regs *regs, unsigned long eip, unsigned long esp)
+{
+	CHOOSE_MODE_PROC(start_thread_tt, start_thread_skas, regs, eip, esp);
+}
+
+#ifdef CONFIG_TTY_LOG
+extern void log_exec(char **argv, void *tty);
+#endif
+
+static long execve1(char *file, char __user * __user *argv,
+		    char __user *__user *env)
+{
+        long error;
+
+#ifdef CONFIG_TTY_LOG
+	task_lock(current);
+	log_exec(argv, current->signal->tty);
+	task_unlock(current);
+#endif
+        error = do_execve(file, argv, env, &current->thread.regs);
+        if (error == 0){
+		task_lock(current);
+                current->ptrace &= ~PT_DTRACE;
+#ifdef SUBARCH_EXECVE1
+		SUBARCH_EXECVE1(&current->thread.regs.regs);
+#endif
+		task_unlock(current);
+                set_cmdline(current_cmd());
+        }
+        return(error);
+}
+
+long um_execve(char *file, char __user *__user *argv, char __user *__user *env)
+{
+	long err;
+
+	err = execve1(file, argv, env);
+	if(!err)
+		do_longjmp(current->thread.exec_buf, 1);
+	return(err);
+}
+
+long sys_execve(char __user *file, char __user *__user *argv,
+		char __user *__user *env)
+{
+	long error;
+	char *filename;
+
+	lock_kernel();
+	filename = getname(file);
+	error = PTR_ERR(filename);
+	if (IS_ERR(filename)) goto out;
+	error = execve1(filename, argv, env);
+	putname(filename);
+ out:
+	unlock_kernel();
+	return(error);
+}
diff --git a/arch/um/kernel/irq.c.orig b/arch/um/kernel/irq.c.orig
new file mode 100644
index 000000000..f386d21d2
--- /dev/null
+++ b/arch/um/kernel/irq.c.orig
@@ -0,0 +1,474 @@
+/* 
+ * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
+ * Licensed under the GPL
+ * Derived (i.e. mostly copied) from arch/i386/kernel/irq.c:
+ *	Copyright (C) 1992, 1998 Linus Torvalds, Ingo Molnar
+ */
+
+#include "linux/kernel.h"
+#include "linux/module.h"
+#include "linux/smp.h"
+#include "linux/kernel_stat.h"
+#include "linux/interrupt.h"
+#include "linux/random.h"
+#include "linux/slab.h"
+#include "linux/file.h"
+#include "linux/proc_fs.h"
+#include "linux/init.h"
+#include "linux/seq_file.h"
+#include "linux/profile.h"
+#include "linux/hardirq.h"
+#include "linux/vs_context.h"
+#include "asm/irq.h"
+#include "asm/hw_irq.h"
+#include "asm/atomic.h"
+#include "asm/signal.h"
+#include "asm/system.h"
+#include "asm/errno.h"
+#include "asm/uaccess.h"
+#include "user_util.h"
+#include "kern_util.h"
+#include "irq_user.h"
+#include "irq_kern.h"
+#include "os.h"
+#include "sigio.h"
+#include "misc_constants.h"
+
+/*
+ * Generic, controller-independent functions:
+ */
+
+int show_interrupts(struct seq_file *p, void *v)
+{
+	int i = *(loff_t *) v, j;
+	struct irqaction * action;
+	unsigned long flags;
+
+	if (i == 0) {
+		seq_printf(p, "           ");
+		for_each_online_cpu(j)
+			seq_printf(p, "CPU%d       ",j);
+		seq_putc(p, '\n');
+	}
+
+	if (i < NR_IRQS) {
+		spin_lock_irqsave(&irq_desc[i].lock, flags);
+		action = irq_desc[i].action;
+		if (!action) 
+			goto skip;
+		seq_printf(p, "%3d: ",i);
+#ifndef CONFIG_SMP
+		seq_printf(p, "%10u ", kstat_irqs(i));
+#else
+		for_each_online_cpu(j)
+			seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]);
+#endif
+		seq_printf(p, " %14s", irq_desc[i].chip->typename);
+		seq_printf(p, "  %s", action->name);
+
+		for (action=action->next; action; action = action->next)
+			seq_printf(p, ", %s", action->name);
+
+		seq_putc(p, '\n');
+skip:
+		spin_unlock_irqrestore(&irq_desc[i].lock, flags);
+	} else if (i == NR_IRQS) {
+		seq_putc(p, '\n');
+	}
+
+	return 0;
+}
+
+struct irq_fd *active_fds = NULL;
+static struct irq_fd **last_irq_ptr = &active_fds;
+
+extern void free_irqs(void);
+
+void sigio_handler(int sig, union uml_pt_regs *regs)
+{
+	struct irq_fd *irq_fd;
+	int n;
+
+	if (smp_sigio_handler())
+		return;
+
+	while (1) {
+		n = os_waiting_for_events(active_fds);
+		if (n <= 0) {
+			if(n == -EINTR) continue;
+			else break;
+		}
+
+		for (irq_fd = active_fds; irq_fd != NULL; irq_fd = irq_fd->next) {
+			if (irq_fd->current_events != 0) {
+				irq_fd->current_events = 0;
+				do_IRQ(irq_fd->irq, regs);
+			}
+		}
+	}
+
+	free_irqs();
+}
+
+static DEFINE_SPINLOCK(irq_lock);
+
+int activate_fd(int irq, int fd, int type, void *dev_id)
+{
+	struct pollfd *tmp_pfd;
+	struct irq_fd *new_fd, *irq_fd;
+	unsigned long flags;
+	int pid, events, err, n;
+
+	pid = os_getpid();
+	err = os_set_fd_async(fd, pid);
+	if (err < 0)
+		goto out;
+
+	new_fd = um_kmalloc(sizeof(*new_fd));
+	err = -ENOMEM;
+	if (new_fd == NULL)
+		goto out;
+
+	if (type == IRQ_READ)
+		events = UM_POLLIN | UM_POLLPRI;
+	else
+		events = UM_POLLOUT;
+	*new_fd = ((struct irq_fd) { .next  		= NULL,
+				     .id 		= dev_id,
+				     .fd 		= fd,
+				     .type 		= type,
+				     .irq 		= irq,
+				     .pid  		= pid,
+				     .events 		= events,
+				     .current_events 	= 0 } );
+
+	/* Critical section - locked by a spinlock because this stuff can
+	 * be changed from interrupt handlers.  The stuff above is done
+	 * outside the lock because it allocates memory.
+	 */
+
+	/* Actually, it only looks like it can be called from interrupt
+	 * context.  The culprit is reactivate_fd, which calls
+	 * maybe_sigio_broken, which calls write_sigio_workaround,
+	 * which calls activate_fd.  However, write_sigio_workaround should
+	 * only be called once, at boot time.  That would make it clear that
+	 * this is called only from process context, and can be locked with
+	 * a semaphore.
+	 */
+	spin_lock_irqsave(&irq_lock, flags);
+	for (irq_fd = active_fds; irq_fd != NULL; irq_fd = irq_fd->next) {
+		if ((irq_fd->fd == fd) && (irq_fd->type == type)) {
+			printk("Registering fd %d twice\n", fd);
+			printk("Irqs : %d, %d\n", irq_fd->irq, irq);
+			printk("Ids : 0x%p, 0x%p\n", irq_fd->id, dev_id);
+			goto out_unlock;
+		}
+	}
+
+	/*-------------*/
+	if (type == IRQ_WRITE)
+		fd = -1;
+
+	tmp_pfd = NULL;
+	n = 0;
+
+	while (1) {
+		n = os_create_pollfd(fd, events, tmp_pfd, n);
+		if (n == 0)
+			break;
+
+		/* n > 0
+		 * It means we couldn't put new pollfd to current pollfds
+		 * and tmp_fds is NULL or too small for new pollfds array.
+		 * Needed size is equal to n as minimum.
+		 *
+		 * Here we have to drop the lock in order to call
+		 * kmalloc, which might sleep.
+		 * If something else came in and changed the pollfds array
+		 * so we will not be able to put new pollfd struct to pollfds
+		 * then we free the buffer tmp_fds and try again.
+		 */
+		spin_unlock_irqrestore(&irq_lock, flags);
+		kfree(tmp_pfd);
+		tmp_pfd = NULL;
+
+		tmp_pfd = um_kmalloc(n);
+		if (tmp_pfd == NULL)
+			goto out_kfree;
+
+		spin_lock_irqsave(&irq_lock, flags);
+	}
+	/*-------------*/
+
+	*last_irq_ptr = new_fd;
+	last_irq_ptr = &new_fd->next;
+
+	spin_unlock_irqrestore(&irq_lock, flags);
+
+	/* This calls activate_fd, so it has to be outside the critical
+	 * section.
+	 */
+	maybe_sigio_broken(fd, (type == IRQ_READ));
+
+	return(0);
+
+ out_unlock:
+	spin_unlock_irqrestore(&irq_lock, flags);
+ out_kfree:
+	kfree(new_fd);
+ out:
+	return(err);
+}
+
+static void free_irq_by_cb(int (*test)(struct irq_fd *, void *), void *arg)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&irq_lock, flags);
+	os_free_irq_by_cb(test, arg, active_fds, &last_irq_ptr);
+	spin_unlock_irqrestore(&irq_lock, flags);
+}
+
+struct irq_and_dev {
+	int irq;
+	void *dev;
+};
+
+static int same_irq_and_dev(struct irq_fd *irq, void *d)
+{
+	struct irq_and_dev *data = d;
+
+	return ((irq->irq == data->irq) && (irq->id == data->dev));
+}
+
+void free_irq_by_irq_and_dev(unsigned int irq, void *dev)
+{
+	struct irq_and_dev data = ((struct irq_and_dev) { .irq  = irq,
+							  .dev  = dev });
+
+	free_irq_by_cb(same_irq_and_dev, &data);
+}
+
+static int same_fd(struct irq_fd *irq, void *fd)
+{
+	return (irq->fd == *((int *)fd));
+}
+
+void free_irq_by_fd(int fd)
+{
+	free_irq_by_cb(same_fd, &fd);
+}
+
+static struct irq_fd *find_irq_by_fd(int fd, int irqnum, int *index_out)
+{
+	struct irq_fd *irq;
+	int i = 0;
+	int fdi;
+
+	for (irq = active_fds; irq != NULL; irq = irq->next) {
+		if ((irq->fd == fd) && (irq->irq == irqnum))
+			break;
+		i++;
+	}
+	if (irq == NULL) {
+		printk("find_irq_by_fd doesn't have descriptor %d\n", fd);
+		goto out;
+	}
+	fdi = os_get_pollfd(i);
+	if ((fdi != -1) && (fdi != fd)) {
+		printk("find_irq_by_fd - mismatch between active_fds and "
+		       "pollfds, fd %d vs %d, need %d\n", irq->fd,
+		       fdi, fd);
+		irq = NULL;
+		goto out;
+	}
+	*index_out = i;
+ out:
+	return irq;
+}
+
+void reactivate_fd(int fd, int irqnum)
+{
+	struct irq_fd *irq;
+	unsigned long flags;
+	int i;
+
+	spin_lock_irqsave(&irq_lock, flags);
+	irq = find_irq_by_fd(fd, irqnum, &i);
+	if (irq == NULL) {
+		spin_unlock_irqrestore(&irq_lock, flags);
+		return;
+	}
+	os_set_pollfd(i, irq->fd);
+	spin_unlock_irqrestore(&irq_lock, flags);
+
+	/* This calls activate_fd, so it has to be outside the critical
+	 * section.
+	 */
+	maybe_sigio_broken(fd, (irq->type == IRQ_READ));
+}
+
+void deactivate_fd(int fd, int irqnum)
+{
+	struct irq_fd *irq;
+	unsigned long flags;
+	int i;
+
+	spin_lock_irqsave(&irq_lock, flags);
+	irq = find_irq_by_fd(fd, irqnum, &i);
+	if (irq == NULL)
+		goto out;
+	os_set_pollfd(i, -1);
+ out:
+	spin_unlock_irqrestore(&irq_lock, flags);
+}
+
+int deactivate_all_fds(void)
+{
+	struct irq_fd *irq;
+	int err;
+
+	for (irq = active_fds; irq != NULL; irq = irq->next) {
+		err = os_clear_fd_async(irq->fd);
+		if (err)
+			return err;
+	}
+	/* If there is a signal already queued, after unblocking ignore it */
+	os_set_ioignore();
+
+	return 0;
+}
+
+#ifdef CONFIG_MODE_TT
+void forward_interrupts(int pid)
+{
+	struct irq_fd *irq;
+	unsigned long flags;
+	int err;
+
+	spin_lock_irqsave(&irq_lock, flags);
+	for (irq = active_fds; irq != NULL; irq = irq->next) {
+		err = os_set_owner(irq->fd, pid);
+		if (err < 0) {
+			/* XXX Just remove the irq rather than
+			 * print out an infinite stream of these
+			 */
+			printk("Failed to forward %d to pid %d, err = %d\n",
+			       irq->fd, pid, -err);
+		}
+
+		irq->pid = pid;
+	}
+	spin_unlock_irqrestore(&irq_lock, flags);
+}
+#endif
+
+/*
+ * do_IRQ handles all normal device IRQ's (the special
+ * SMP cross-CPU interrupts have their own specific
+ * handlers).
+ */
+unsigned int do_IRQ(int irq, union uml_pt_regs *regs)
+{
+	struct vx_info_save vxis;
+
+	irq_enter();
+
+	__enter_vx_admin(&vxis);
+	__do_IRQ(irq, (struct pt_regs *)regs);
+	__leave_vx_admin(&vxis);
+	irq_exit();
+	return 1;
+}
+
+int um_request_irq(unsigned int irq, int fd, int type,
+		   irqreturn_t (*handler)(int, void *, struct pt_regs *),
+		   unsigned long irqflags, const char * devname,
+		   void *dev_id)
+{
+	int err;
+
+	err = request_irq(irq, handler, irqflags, devname, dev_id);
+	if (err)
+		return err;
+
+	if (fd != -1)
+		err = activate_fd(irq, fd, type, dev_id);
+	return err;
+}
+EXPORT_SYMBOL(um_request_irq);
+EXPORT_SYMBOL(reactivate_fd);
+
+/* hw_interrupt_type must define (startup || enable) &&
+ * (shutdown || disable) && end */
+static void dummy(unsigned int irq)
+{
+}
+
+/* This is used for everything else than the timer. */
+static struct hw_interrupt_type normal_irq_type = {
+	.typename = "SIGIO",
+	.release = free_irq_by_irq_and_dev,
+	.disable = dummy,
+	.enable = dummy,
+	.ack = dummy,
+	.end = dummy
+};
+
+static struct hw_interrupt_type SIGVTALRM_irq_type = {
+	.typename = "SIGVTALRM",
+	.release = free_irq_by_irq_and_dev,
+	.shutdown = dummy, /* never called */
+	.disable = dummy,
+	.enable = dummy,
+	.ack = dummy,
+	.end = dummy
+};
+
+void __init init_IRQ(void)
+{
+	int i;
+
+	irq_desc[TIMER_IRQ].status = IRQ_DISABLED;
+	irq_desc[TIMER_IRQ].action = NULL;
+	irq_desc[TIMER_IRQ].depth = 1;
+	irq_desc[TIMER_IRQ].chip = &SIGVTALRM_irq_type;
+	enable_irq(TIMER_IRQ);
+	for (i = 1; i < NR_IRQS; i++) {
+		irq_desc[i].status = IRQ_DISABLED;
+		irq_desc[i].action = NULL;
+		irq_desc[i].depth = 1;
+		irq_desc[i].chip = &normal_irq_type;
+		enable_irq(i);
+	}
+}
+
+int init_aio_irq(int irq, char *name, irqreturn_t (*handler)(int, void *,
+							     struct pt_regs *))
+{
+	int fds[2], err;
+
+	err = os_pipe(fds, 1, 1);
+	if (err) {
+		printk("init_aio_irq - os_pipe failed, err = %d\n", -err);
+		goto out;
+	}
+
+	err = um_request_irq(irq, fds[0], IRQ_READ, handler,
+			     IRQF_DISABLED | IRQF_SAMPLE_RANDOM, name,
+			     (void *) (long) fds[0]);
+	if (err) {
+		printk("init_aio_irq - : um_request_irq failed, err = %d\n",
+		       err);
+		goto out_close;
+	}
+
+	err = fds[1];
+	goto out;
+
+ out_close:
+	os_close_file(fds[0]);
+	os_close_file(fds[1]);
+ out:
+	return err;
+}
diff --git a/arch/um/kernel/sigio.c b/arch/um/kernel/sigio.c
new file mode 100644
index 000000000..0ad755ceb
--- /dev/null
+++ b/arch/um/kernel/sigio.c
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2002 - 2003 Jeff Dike (jdike@addtoit.com)
+ * Licensed under the GPL
+ */
+
+#include "linux/kernel.h"
+#include "linux/list.h"
+#include "linux/slab.h"
+#include "linux/signal.h"
+#include "linux/interrupt.h"
+#include "init.h"
+#include "sigio.h"
+#include "irq_user.h"
+#include "irq_kern.h"
+#include "os.h"
+
+/* Protected by sigio_lock() called from write_sigio_workaround */
+static int sigio_irq_fd = -1;
+
+static irqreturn_t sigio_interrupt(int irq, void *data, struct pt_regs *unused)
+{
+	char c;
+
+	os_read_file(sigio_irq_fd, &c, sizeof(c));
+	reactivate_fd(sigio_irq_fd, SIGIO_WRITE_IRQ);
+	return(IRQ_HANDLED);
+}
+
+int write_sigio_irq(int fd)
+{
+	int err;
+
+	err = um_request_irq(SIGIO_WRITE_IRQ, fd, IRQ_READ, sigio_interrupt,
+			     IRQF_DISABLED|IRQF_SAMPLE_RANDOM, "write sigio",
+			     NULL);
+	if(err){
+		printk("write_sigio_irq : um_request_irq failed, err = %d\n",
+		       err);
+		return(-1);
+	}
+	sigio_irq_fd = fd;
+	return(0);
+}
+
+static DEFINE_SPINLOCK(sigio_spinlock);
+
+void sigio_lock(void)
+{
+	spin_lock(&sigio_spinlock);
+}
+
+void sigio_unlock(void)
+{
+	spin_unlock(&sigio_spinlock);
+}
diff --git a/arch/um/kernel/signal.c b/arch/um/kernel/signal.c
new file mode 100644
index 000000000..2a32e5e8e
--- /dev/null
+++ b/arch/um/kernel/signal.c
@@ -0,0 +1,190 @@
+/*
+ * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
+ * Licensed under the GPL
+ */
+
+#include "linux/stddef.h"
+#include "linux/sys.h"
+#include "linux/sched.h"
+#include "linux/wait.h"
+#include "linux/kernel.h"
+#include "linux/smp_lock.h"
+#include "linux/module.h"
+#include "linux/slab.h"
+#include "linux/tty.h"
+#include "linux/binfmts.h"
+#include "linux/ptrace.h"
+#include "asm/signal.h"
+#include "asm/uaccess.h"
+#include "asm/unistd.h"
+#include "user_util.h"
+#include "asm/ucontext.h"
+#include "kern_util.h"
+#include "signal_kern.h"
+#include "kern.h"
+#include "frame_kern.h"
+#include "sigcontext.h"
+#include "mode.h"
+
+EXPORT_SYMBOL(block_signals);
+EXPORT_SYMBOL(unblock_signals);
+
+#define _S(nr) (1<<((nr)-1))
+
+#define _BLOCKABLE (~(_S(SIGKILL) | _S(SIGSTOP)))
+
+/*
+ * OK, we're invoking a handler
+ */
+static int handle_signal(struct pt_regs *regs, unsigned long signr,
+			 struct k_sigaction *ka, siginfo_t *info,
+			 sigset_t *oldset)
+{
+	unsigned long sp;
+	int err;
+
+	/* Always make any pending restarted system calls return -EINTR */
+	current_thread_info()->restart_block.fn = do_no_restart_syscall;
+
+	/* Did we come from a system call? */
+	if(PT_REGS_SYSCALL_NR(regs) >= 0){
+		/* If so, check system call restarting.. */
+		switch(PT_REGS_SYSCALL_RET(regs)){
+		case -ERESTART_RESTARTBLOCK:
+		case -ERESTARTNOHAND:
+			PT_REGS_SYSCALL_RET(regs) = -EINTR;
+			break;
+
+		case -ERESTARTSYS:
+			if (!(ka->sa.sa_flags & SA_RESTART)) {
+				PT_REGS_SYSCALL_RET(regs) = -EINTR;
+				break;
+			}
+		/* fallthrough */
+		case -ERESTARTNOINTR:
+			PT_REGS_RESTART_SYSCALL(regs);
+			PT_REGS_ORIG_SYSCALL(regs) = PT_REGS_SYSCALL_NR(regs);
+			break;
+		}
+	}
+
+	sp = PT_REGS_SP(regs);
+	if((ka->sa.sa_flags & SA_ONSTACK) && (sas_ss_flags(sp) == 0))
+		sp = current->sas_ss_sp + current->sas_ss_size;
+
+#ifdef CONFIG_ARCH_HAS_SC_SIGNALS
+	if(!(ka->sa.sa_flags & SA_SIGINFO))
+		err = setup_signal_stack_sc(sp, signr, ka, regs, oldset);
+	else
+#endif
+		err = setup_signal_stack_si(sp, signr, ka, regs, info, oldset);
+
+	if(err){
+		spin_lock_irq(&current->sighand->siglock);
+		current->blocked = *oldset;
+		recalc_sigpending();
+		spin_unlock_irq(&current->sighand->siglock);
+		force_sigsegv(signr, current);
+	} else {
+		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, signr);
+		recalc_sigpending();
+		spin_unlock_irq(&current->sighand->siglock);
+	}
+
+	return err;
+}
+
+static int kern_do_signal(struct pt_regs *regs)
+{
+	struct k_sigaction ka_copy;
+	siginfo_t info;
+	sigset_t *oldset;
+	int sig, handled_sig = 0;
+
+	if (test_thread_flag(TIF_RESTORE_SIGMASK))
+		oldset = &current->saved_sigmask;
+	else
+		oldset = &current->blocked;
+
+	while((sig = get_signal_to_deliver(&info, &ka_copy, regs, NULL)) > 0){
+		handled_sig = 1;
+		/* Whee!  Actually deliver the signal.  */
+		if(!handle_signal(regs, sig, &ka_copy, &info, oldset)){
+			/* 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);
+			break;
+		}
+	}
+
+	/* Did we come from a system call? */
+	if(!handled_sig && (PT_REGS_SYSCALL_NR(regs) >= 0)){
+		/* Restart the system call - no handlers present */
+		switch(PT_REGS_SYSCALL_RET(regs)){
+		case -ERESTARTNOHAND:
+		case -ERESTARTSYS:
+		case -ERESTARTNOINTR:
+			PT_REGS_ORIG_SYSCALL(regs) = PT_REGS_SYSCALL_NR(regs);
+			PT_REGS_RESTART_SYSCALL(regs);
+			break;
+		case -ERESTART_RESTARTBLOCK:
+			PT_REGS_ORIG_SYSCALL(regs) = __NR_restart_syscall;
+			PT_REGS_RESTART_SYSCALL(regs);
+			break;
+ 		}
+	}
+
+	/* This closes a way to execute a system call on the host.  If
+	 * you set a breakpoint on a system call instruction and singlestep
+	 * from it, the tracing thread used to PTRACE_SINGLESTEP the process
+	 * rather than PTRACE_SYSCALL it, allowing the system call to execute
+	 * on the host.  The tracing thread will check this flag and
+	 * PTRACE_SYSCALL if necessary.
+	 */
+	if(current->ptrace & PT_DTRACE)
+		current->thread.singlestep_syscall =
+			is_syscall(PT_REGS_IP(&current->thread.regs));
+
+	/* if there's no signal to deliver, we just put the saved sigmask
+	 * back */
+	if (!handled_sig && test_thread_flag(TIF_RESTORE_SIGMASK)) {
+		clear_thread_flag(TIF_RESTORE_SIGMASK);
+		sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
+	}
+	return(handled_sig);
+}
+
+int do_signal(void)
+{
+	return(kern_do_signal(&current->thread.regs));
+}
+
+/*
+ * Atomically swap in the new signal mask, and wait for a signal.
+ */
+long sys_sigsuspend(int history0, int history1, old_sigset_t mask)
+{
+	mask &= _BLOCKABLE;
+	spin_lock_irq(&current->sighand->siglock);
+	current->saved_sigmask = current->blocked;
+	siginitset(&current->blocked, mask);
+	recalc_sigpending();
+	spin_unlock_irq(&current->sighand->siglock);
+
+	current->state = TASK_INTERRUPTIBLE;
+	schedule();
+	set_thread_flag(TIF_RESTORE_SIGMASK);
+	return -ERESTARTNOHAND;
+}
+
+long sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss)
+{
+	return(do_sigaltstack(uss, uoss, PT_REGS_SP(&current->thread.regs)));
+}
diff --git a/arch/um/kernel/trap.c b/arch/um/kernel/trap.c
new file mode 100644
index 000000000..8c90a63d9
--- /dev/null
+++ b/arch/um/kernel/trap.c
@@ -0,0 +1,250 @@
+/*
+ * Copyright (C) 2000, 2001 Jeff Dike (jdike@karaya.com)
+ * Licensed under the GPL
+ */
+
+#include "linux/kernel.h"
+#include "asm/errno.h"
+#include "linux/sched.h"
+#include "linux/mm.h"
+#include "linux/spinlock.h"
+#include "linux/init.h"
+#include "linux/ptrace.h"
+#include "asm/semaphore.h"
+#include "asm/pgtable.h"
+#include "asm/pgalloc.h"
+#include "asm/tlbflush.h"
+#include "asm/a.out.h"
+#include "asm/current.h"
+#include "asm/irq.h"
+#include "sysdep/sigcontext.h"
+#include "user_util.h"
+#include "kern_util.h"
+#include "kern.h"
+#include "chan_kern.h"
+#include "mconsole_kern.h"
+#include "mem.h"
+#include "mem_kern.h"
+#include "sysdep/sigcontext.h"
+#include "sysdep/ptrace.h"
+#include "os.h"
+#ifdef CONFIG_MODE_SKAS
+#include "skas.h"
+#endif
+#include "os.h"
+
+/* Note this is constrained to return 0, -EFAULT, -EACCESS, -ENOMEM by segv(). */
+int handle_page_fault(unsigned long address, unsigned long ip,
+		      int is_write, int is_user, int *code_out)
+{
+	struct mm_struct *mm = current->mm;
+	struct vm_area_struct *vma;
+	pgd_t *pgd;
+	pud_t *pud;
+	pmd_t *pmd;
+	pte_t *pte;
+	int err = -EFAULT;
+
+	*code_out = SEGV_MAPERR;
+
+	/* If the fault was during atomic operation, don't take the fault, just
+	 * fail. */
+	if (in_atomic())
+		goto out_nosemaphore;
+
+	down_read(&mm->mmap_sem);
+	vma = find_vma(mm, address);
+	if(!vma)
+		goto out;
+	else if(vma->vm_start <= address)
+		goto good_area;
+	else if(!(vma->vm_flags & VM_GROWSDOWN))
+		goto out;
+	else if(is_user && !ARCH_IS_STACKGROW(address))
+		goto out;
+	else if(expand_stack(vma, address))
+		goto out;
+
+good_area:
+	*code_out = SEGV_ACCERR;
+	if(is_write && !(vma->vm_flags & VM_WRITE))
+		goto out;
+
+	/* Don't require VM_READ|VM_EXEC for write faults! */
+        if(!is_write && !(vma->vm_flags & (VM_READ | VM_EXEC)))
+                goto out;
+
+	do {
+survive:
+		switch (handle_mm_fault(mm, vma, address, is_write)){
+		case VM_FAULT_MINOR:
+			current->min_flt++;
+			break;
+		case VM_FAULT_MAJOR:
+			current->maj_flt++;
+			break;
+		case VM_FAULT_SIGBUS:
+			err = -EACCES;
+			goto out;
+		case VM_FAULT_OOM:
+			err = -ENOMEM;
+			goto out_of_memory;
+		default:
+			BUG();
+		}
+		pgd = pgd_offset(mm, address);
+		pud = pud_offset(pgd, address);
+		pmd = pmd_offset(pud, address);
+		pte = pte_offset_kernel(pmd, address);
+	} while(!pte_present(*pte));
+	err = 0;
+	/* The below warning was added in place of
+	 *	pte_mkyoung(); if (is_write) pte_mkdirty();
+	 * If it's triggered, we'd see normally a hang here (a clean pte is
+	 * marked read-only to emulate the dirty bit).
+	 * However, the generic code can mark a PTE writable but clean on a
+	 * concurrent read fault, triggering this harmlessly. So comment it out.
+	 */
+#if 0
+	WARN_ON(!pte_young(*pte) || (is_write && !pte_dirty(*pte)));
+#endif
+	flush_tlb_page(vma, address);
+out:
+	up_read(&mm->mmap_sem);
+out_nosemaphore:
+	return(err);
+
+/*
+ * We ran out of memory, or some other thing happened to us that made
+ * us unable to handle the page fault gracefully.
+ */
+out_of_memory:
+	if (current->pid == 1) {
+		up_read(&mm->mmap_sem);
+		yield();
+		down_read(&mm->mmap_sem);
+		goto survive;
+	}
+	goto out;
+}
+
+void segv_handler(int sig, union uml_pt_regs *regs)
+{
+	struct faultinfo * fi = UPT_FAULTINFO(regs);
+
+	if(UPT_IS_USER(regs) && !SEGV_IS_FIXABLE(fi)){
+		bad_segv(*fi, UPT_IP(regs));
+		return;
+	}
+	segv(*fi, UPT_IP(regs), UPT_IS_USER(regs), regs);
+}
+
+struct kern_handlers handlinfo_kern = {
+	.relay_signal = relay_signal,
+	.winch = winch,
+	.bus_handler = relay_signal,
+	.page_fault = segv_handler,
+	.sigio_handler = sigio_handler,
+	.timer_handler = timer_handler
+};
+/*
+ * We give a *copy* of the faultinfo in the regs to segv.
+ * This must be done, since nesting SEGVs could overwrite
+ * the info in the regs. A pointer to the info then would
+ * give us bad data!
+ */
+unsigned long segv(struct faultinfo fi, unsigned long ip, int is_user, void *sc)
+{
+	struct siginfo si;
+	void *catcher;
+	int err;
+        int is_write = FAULT_WRITE(fi);
+        unsigned long address = FAULT_ADDRESS(fi);
+
+        if(!is_user && (address >= start_vm) && (address < end_vm)){
+                flush_tlb_kernel_vm();
+                return(0);
+        }
+	else if(current->mm == NULL)
+		panic("Segfault with no mm");
+
+	if (SEGV_IS_FIXABLE(&fi) || SEGV_MAYBE_FIXABLE(&fi))
+		err = handle_page_fault(address, ip, is_write, is_user, &si.si_code);
+	else {
+		err = -EFAULT;
+		/* A thread accessed NULL, we get a fault, but CR2 is invalid.
+		 * This code is used in __do_copy_from_user() of TT mode. */
+		address = 0;
+	}
+
+	catcher = current->thread.fault_catcher;
+	if(!err)
+		return(0);
+	else if(catcher != NULL){
+		current->thread.fault_addr = (void *) address;
+		do_longjmp(catcher, 1);
+	}
+	else if(current->thread.fault_addr != NULL)
+		panic("fault_addr set but no fault catcher");
+        else if(!is_user && arch_fixup(ip, sc))
+		return(0);
+
+ 	if(!is_user)
+		panic("Kernel mode fault at addr 0x%lx, ip 0x%lx",
+		      address, ip);
+
+	if (err == -EACCES) {
+		si.si_signo = SIGBUS;
+		si.si_errno = 0;
+		si.si_code = BUS_ADRERR;
+		si.si_addr = (void __user *)address;
+                current->thread.arch.faultinfo = fi;
+		force_sig_info(SIGBUS, &si, current);
+	} else if (err == -ENOMEM) {
+		printk("VM: killing process %s\n", current->comm);
+		do_exit(SIGKILL);
+	} else {
+		BUG_ON(err != -EFAULT);
+		si.si_signo = SIGSEGV;
+		si.si_addr = (void __user *) address;
+                current->thread.arch.faultinfo = fi;
+		force_sig_info(SIGSEGV, &si, current);
+	}
+	return(0);
+}
+
+void bad_segv(struct faultinfo fi, unsigned long ip)
+{
+	struct siginfo si;
+
+	si.si_signo = SIGSEGV;
+	si.si_code = SEGV_ACCERR;
+	si.si_addr = (void __user *) FAULT_ADDRESS(fi);
+	current->thread.arch.faultinfo = fi;
+	force_sig_info(SIGSEGV, &si, current);
+}
+
+void relay_signal(int sig, union uml_pt_regs *regs)
+{
+	if(arch_handle_signal(sig, regs)) return;
+	if(!UPT_IS_USER(regs))
+		panic("Kernel mode signal %d", sig);
+        current->thread.arch.faultinfo = *UPT_FAULTINFO(regs);
+	force_sig(sig, current);
+}
+
+void bus_handler(int sig, union uml_pt_regs *regs)
+{
+	if(current->thread.fault_catcher != NULL)
+		do_longjmp(current->thread.fault_catcher, 1);
+	else relay_signal(sig, regs);
+}
+
+void winch(int sig, union uml_pt_regs *regs)
+{
+	do_IRQ(WINCH_IRQ, regs);
+}
+
+void trap_init(void)
+{
+}
diff --git a/arch/x86_64/ia32/audit.c b/arch/x86_64/ia32/audit.c
new file mode 100644
index 000000000..92d7d0c8d
--- /dev/null
+++ b/arch/x86_64/ia32/audit.c
@@ -0,0 +1,37 @@
+#include <asm-i386/unistd.h>
+
+unsigned ia32_dir_class[] = {
+#include <asm-generic/audit_dir_write.h>
+~0U
+};
+
+unsigned ia32_chattr_class[] = {
+#include <asm-generic/audit_change_attr.h>
+~0U
+};
+
+unsigned ia32_write_class[] = {
+#include <asm-generic/audit_write.h>
+~0U
+};
+
+unsigned ia32_read_class[] = {
+#include <asm-generic/audit_read.h>
+~0U
+};
+
+int ia32_classify_syscall(unsigned syscall)
+{
+	switch(syscall) {
+	case __NR_open:
+		return 2;
+	case __NR_openat:
+		return 3;
+	case __NR_socketcall:
+		return 4;
+	case __NR_execve:
+		return 5;
+	default:
+		return 1;
+	}
+}
diff --git a/arch/x86_64/kernel/audit.c b/arch/x86_64/kernel/audit.c
new file mode 100644
index 000000000..21f33387b
--- /dev/null
+++ b/arch/x86_64/kernel/audit.c
@@ -0,0 +1,64 @@
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/audit.h>
+#include <asm/unistd.h>
+
+static unsigned dir_class[] = {
+#include <asm-generic/audit_dir_write.h>
+~0U
+};
+
+static unsigned read_class[] = {
+#include <asm-generic/audit_read.h>
+~0U
+};
+
+static unsigned write_class[] = {
+#include <asm-generic/audit_write.h>
+~0U
+};
+
+static unsigned chattr_class[] = {
+#include <asm-generic/audit_change_attr.h>
+~0U
+};
+
+int audit_classify_syscall(int abi, unsigned syscall)
+{
+#ifdef CONFIG_IA32_EMULATION
+	extern int ia32_classify_syscall(unsigned);
+	if (abi == AUDIT_ARCH_I386)
+		return ia32_classify_syscall(syscall);
+#endif
+	switch(syscall) {
+	case __NR_open:
+		return 2;
+	case __NR_openat:
+		return 3;
+	case __NR_execve:
+		return 5;
+	default:
+		return 0;
+	}
+}
+
+static int __init audit_classes_init(void)
+{
+#ifdef CONFIG_IA32_EMULATION
+	extern __u32 ia32_dir_class[];
+	extern __u32 ia32_write_class[];
+	extern __u32 ia32_read_class[];
+	extern __u32 ia32_chattr_class[];
+	audit_register_class(AUDIT_CLASS_WRITE_32, ia32_write_class);
+	audit_register_class(AUDIT_CLASS_READ_32, ia32_read_class);
+	audit_register_class(AUDIT_CLASS_DIR_WRITE_32, ia32_dir_class);
+	audit_register_class(AUDIT_CLASS_CHATTR_32, ia32_chattr_class);
+#endif
+	audit_register_class(AUDIT_CLASS_WRITE, write_class);
+	audit_register_class(AUDIT_CLASS_READ, read_class);
+	audit_register_class(AUDIT_CLASS_DIR_WRITE, dir_class);
+	audit_register_class(AUDIT_CLASS_CHATTR, chattr_class);
+	return 0;
+}
+
+__initcall(audit_classes_init);
diff --git a/arch/x86_64/kernel/irqflags-xen.c b/arch/x86_64/kernel/irqflags-xen.c
new file mode 100644
index 000000000..e3b7ab5e6
--- /dev/null
+++ b/arch/x86_64/kernel/irqflags-xen.c
@@ -0,0 +1,100 @@
+#include <linux/module.h>
+#include <linux/smp.h>
+#include <asm/irqflags.h>
+#include <asm/hypervisor.h>
+
+/* 
+ * The use of 'barrier' in the following reflects their use as local-lock
+ * operations. Reentrancy must be prevented (e.g., __cli()) /before/ following
+ * critical operations are executed. All critical operations must complete
+ * /before/ reentrancy is permitted (e.g., __sti()). Alpha architecture also
+ * includes these barriers, for example.
+ */
+
+unsigned long __raw_local_save_flags(void)
+{
+	struct vcpu_info *_vcpu;
+	unsigned long flags;
+
+	preempt_disable();
+	_vcpu = &HYPERVISOR_shared_info->vcpu_info[__vcpu_id];
+	flags = _vcpu->evtchn_upcall_mask;
+	preempt_enable();
+
+	return flags;
+}
+EXPORT_SYMBOL(__raw_local_save_flags);
+
+void raw_local_irq_restore(unsigned long flags)
+{
+	struct vcpu_info *_vcpu;
+	preempt_disable();
+	_vcpu = &HYPERVISOR_shared_info->vcpu_info[__vcpu_id];
+	if ((_vcpu->evtchn_upcall_mask = flags) == 0) {
+		barrier(); /* unmask then check (avoid races) */
+		if ( unlikely(_vcpu->evtchn_upcall_pending) )
+			force_evtchn_callback();
+		preempt_enable();
+	} else
+		preempt_enable_no_resched();
+}
+EXPORT_SYMBOL(raw_local_irq_restore);
+
+void raw_local_irq_disable(void)
+{
+	struct vcpu_info *_vcpu;
+
+	preempt_disable();
+	_vcpu = &HYPERVISOR_shared_info->vcpu_info[__vcpu_id];
+	_vcpu->evtchn_upcall_mask = 1;
+	preempt_enable_no_resched();
+}
+EXPORT_SYMBOL(raw_local_irq_disable);
+
+void raw_local_irq_enable(void)
+{
+	struct vcpu_info *_vcpu;
+
+	preempt_disable();
+	_vcpu = &HYPERVISOR_shared_info->vcpu_info[__vcpu_id];
+	_vcpu->evtchn_upcall_mask = 0;
+	barrier(); /* unmask then check (avoid races) */
+	if ( unlikely(_vcpu->evtchn_upcall_pending) )
+		force_evtchn_callback();
+	preempt_enable();
+}
+EXPORT_SYMBOL(raw_local_irq_enable);
+
+/*
+ * For spinlocks, etc.:
+ */
+
+unsigned long __raw_local_irq_save(void)
+{
+	struct vcpu_info *_vcpu;
+	unsigned long flags;
+
+	preempt_disable();
+	_vcpu = &HYPERVISOR_shared_info->vcpu_info[__vcpu_id];
+	flags = _vcpu->evtchn_upcall_mask;
+	_vcpu->evtchn_upcall_mask = 1;
+	preempt_enable_no_resched();
+
+	return flags;
+}
+EXPORT_SYMBOL(__raw_local_irq_save);
+
+/* Cannot use preempt_enable() here as we would recurse in preempt_sched(). */
+int raw_irqs_disabled(void)
+{
+	struct vcpu_info *_vcpu;
+	int disabled;
+
+	preempt_disable();
+	_vcpu = &HYPERVISOR_shared_info->vcpu_info[__vcpu_id];
+	disabled = (_vcpu->evtchn_upcall_mask != 0);
+	preempt_enable_no_resched();
+
+	return disabled;
+}
+EXPORT_SYMBOL(raw_irqs_disabled);
diff --git a/arch/x86_64/kernel/k8.c b/arch/x86_64/kernel/k8.c
new file mode 100644
index 000000000..6416682d3
--- /dev/null
+++ b/arch/x86_64/kernel/k8.c
@@ -0,0 +1,118 @@
+/*
+ * Shared support code for AMD K8 northbridges and derivates.
+ * Copyright 2006 Andi Kleen, SUSE Labs. Subject to GPLv2.
+ */
+#include <linux/gfp.h>
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/module.h>
+#include <linux/spinlock.h>
+#include <asm/k8.h>
+
+int num_k8_northbridges;
+EXPORT_SYMBOL(num_k8_northbridges);
+
+static u32 *flush_words;
+
+struct pci_device_id k8_nb_ids[] = {
+	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, 0x1103) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, 0x1203) },
+	{}
+};
+EXPORT_SYMBOL(k8_nb_ids);
+
+struct pci_dev **k8_northbridges;
+EXPORT_SYMBOL(k8_northbridges);
+
+static struct pci_dev *next_k8_northbridge(struct pci_dev *dev)
+{
+	do {
+		dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev);
+		if (!dev)
+			break;
+	} while (!pci_match_id(&k8_nb_ids[0], dev));
+	return dev;
+}
+
+int cache_k8_northbridges(void)
+{
+	int i;
+	struct pci_dev *dev;
+	if (num_k8_northbridges)
+		return 0;
+
+	num_k8_northbridges = 0;
+	dev = NULL;
+	while ((dev = next_k8_northbridge(dev)) != NULL)
+		num_k8_northbridges++;
+
+	k8_northbridges = kmalloc((num_k8_northbridges + 1) * sizeof(void *),
+				  GFP_KERNEL);
+	if (!k8_northbridges)
+		return -ENOMEM;
+
+	flush_words = kmalloc(num_k8_northbridges * sizeof(u32), GFP_KERNEL);
+	if (!flush_words) {
+		kfree(k8_northbridges);
+		return -ENOMEM;
+	}
+
+	dev = NULL;
+	i = 0;
+	while ((dev = next_k8_northbridge(dev)) != NULL) {
+		k8_northbridges[i++] = dev;
+		pci_read_config_dword(dev, 0x9c, &flush_words[i]);
+	}
+	k8_northbridges[i] = NULL;
+	return 0;
+}
+EXPORT_SYMBOL_GPL(cache_k8_northbridges);
+
+/* Ignores subdevice/subvendor but as far as I can figure out
+   they're useless anyways */
+int __init early_is_k8_nb(u32 device)
+{
+	struct pci_device_id *id;
+	u32 vendor = device & 0xffff;
+	device >>= 16;
+	for (id = k8_nb_ids; id->vendor; id++)
+		if (vendor == id->vendor && device == id->device)
+			return 1;
+	return 0;
+}
+
+void k8_flush_garts(void)
+{
+	int flushed, i;
+	unsigned long flags;
+	static DEFINE_SPINLOCK(gart_lock);
+
+	/* Avoid races between AGP and IOMMU. In theory it's not needed
+	   but I'm not sure if the hardware won't lose flush requests
+	   when another is pending. This whole thing is so expensive anyways
+	   that it doesn't matter to serialize more. -AK */
+	spin_lock_irqsave(&gart_lock, flags);
+	flushed = 0;
+	for (i = 0; i < num_k8_northbridges; i++) {
+		pci_write_config_dword(k8_northbridges[i], 0x9c,
+				       flush_words[i]|1);
+		flushed++;
+	}
+	for (i = 0; i < num_k8_northbridges; i++) {
+		u32 w;
+		/* Make sure the hardware actually executed the flush*/
+		for (;;) {
+			pci_read_config_dword(k8_northbridges[i],
+					      0x9c, &w);
+			if (!(w & 1))
+				break;
+			cpu_relax();
+		}
+	}
+	spin_unlock_irqrestore(&gart_lock, flags);
+	if (!flushed)
+		printk("nothing to flush?\n");
+}
+EXPORT_SYMBOL_GPL(k8_flush_garts);
+
diff --git a/arch/x86_64/kernel/pci-calgary.c b/arch/x86_64/kernel/pci-calgary.c
new file mode 100644
index 000000000..61ffebb79
--- /dev/null
+++ b/arch/x86_64/kernel/pci-calgary.c
@@ -0,0 +1,1039 @@
+/*
+ * Derived from arch/powerpc/kernel/iommu.c
+ *
+ * Copyright (C) IBM Corporation, 2006
+ *
+ * Author: Jon Mason <jdmason@us.ibm.com>
+ * Author: Muli Ben-Yehuda <muli@il.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 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/types.h>
+#include <linux/slab.h>
+#include <linux/mm.h>
+#include <linux/spinlock.h>
+#include <linux/string.h>
+#include <linux/dma-mapping.h>
+#include <linux/init.h>
+#include <linux/bitops.h>
+#include <linux/pci_ids.h>
+#include <linux/pci.h>
+#include <linux/delay.h>
+#include <asm/proto.h>
+#include <asm/calgary.h>
+#include <asm/tce.h>
+#include <asm/pci-direct.h>
+#include <asm/system.h>
+#include <asm/dma.h>
+
+#define PCI_DEVICE_ID_IBM_CALGARY 0x02a1
+#define PCI_VENDOR_DEVICE_ID_CALGARY \
+	(PCI_VENDOR_ID_IBM | PCI_DEVICE_ID_IBM_CALGARY << 16)
+
+/* we need these for register space address calculation */
+#define START_ADDRESS           0xfe000000
+#define CHASSIS_BASE            0
+#define ONE_BASED_CHASSIS_NUM   1
+
+/* register offsets inside the host bridge space */
+#define PHB_CSR_OFFSET		0x0110
+#define PHB_PLSSR_OFFSET	0x0120
+#define PHB_CONFIG_RW_OFFSET	0x0160
+#define PHB_IOBASE_BAR_LOW	0x0170
+#define PHB_IOBASE_BAR_HIGH	0x0180
+#define PHB_MEM_1_LOW		0x0190
+#define PHB_MEM_1_HIGH		0x01A0
+#define PHB_IO_ADDR_SIZE	0x01B0
+#define PHB_MEM_1_SIZE		0x01C0
+#define PHB_MEM_ST_OFFSET	0x01D0
+#define PHB_AER_OFFSET		0x0200
+#define PHB_CONFIG_0_HIGH	0x0220
+#define PHB_CONFIG_0_LOW	0x0230
+#define PHB_CONFIG_0_END	0x0240
+#define PHB_MEM_2_LOW		0x02B0
+#define PHB_MEM_2_HIGH		0x02C0
+#define PHB_MEM_2_SIZE_HIGH	0x02D0
+#define PHB_MEM_2_SIZE_LOW	0x02E0
+#define PHB_DOSHOLE_OFFSET	0x08E0
+
+/* PHB_CONFIG_RW */
+#define PHB_TCE_ENABLE		0x20000000
+#define PHB_SLOT_DISABLE	0x1C000000
+#define PHB_DAC_DISABLE		0x01000000
+#define PHB_MEM2_ENABLE		0x00400000
+#define PHB_MCSR_ENABLE		0x00100000
+/* TAR (Table Address Register) */
+#define TAR_SW_BITS		0x0000ffffffff800fUL
+#define TAR_VALID		0x0000000000000008UL
+/* CSR (Channel/DMA Status Register) */
+#define CSR_AGENT_MASK		0xffe0ffff
+
+#define MAX_NUM_OF_PHBS		8 /* how many PHBs in total? */
+#define MAX_NUM_CHASSIS		8 /* max number of chassis */
+#define MAX_PHB_BUS_NUM		(MAX_NUM_OF_PHBS * MAX_NUM_CHASSIS * 2) /* max dev->bus->number */
+#define PHBS_PER_CALGARY	4
+
+/* register offsets in Calgary's internal register space */
+static const unsigned long tar_offsets[] = {
+	0x0580 /* TAR0 */,
+	0x0588 /* TAR1 */,
+	0x0590 /* TAR2 */,
+	0x0598 /* TAR3 */
+};
+
+static const unsigned long split_queue_offsets[] = {
+	0x4870 /* SPLIT QUEUE 0 */,
+	0x5870 /* SPLIT QUEUE 1 */,
+	0x6870 /* SPLIT QUEUE 2 */,
+	0x7870 /* SPLIT QUEUE 3 */
+};
+
+static const unsigned long phb_offsets[] = {
+	0x8000 /* PHB0 */,
+	0x9000 /* PHB1 */,
+	0xA000 /* PHB2 */,
+	0xB000 /* PHB3 */
+};
+
+static char bus_to_phb[MAX_PHB_BUS_NUM];
+void* tce_table_kva[MAX_PHB_BUS_NUM];
+unsigned int specified_table_size = TCE_TABLE_SIZE_UNSPECIFIED;
+static int translate_empty_slots __read_mostly = 0;
+static int calgary_detected __read_mostly = 0;
+
+/*
+ * the bitmap of PHBs the user requested that we disable
+ * translation on.
+ */
+static DECLARE_BITMAP(translation_disabled, MAX_PHB_BUS_NUM);
+
+static void tce_cache_blast(struct iommu_table *tbl);
+
+/* enable this to stress test the chip's TCE cache */
+#ifdef CONFIG_IOMMU_DEBUG
+static inline void tce_cache_blast_stress(struct iommu_table *tbl)
+{
+	tce_cache_blast(tbl);
+}
+#else
+static inline void tce_cache_blast_stress(struct iommu_table *tbl)
+{
+}
+#endif /* BLAST_TCE_CACHE_ON_UNMAP */
+
+static inline unsigned int num_dma_pages(unsigned long dma, unsigned int dmalen)
+{
+	unsigned int npages;
+
+	npages = PAGE_ALIGN(dma + dmalen) - (dma & PAGE_MASK);
+	npages >>= PAGE_SHIFT;
+
+	return npages;
+}
+
+static inline int translate_phb(struct pci_dev* dev)
+{
+	int disabled = test_bit(dev->bus->number, translation_disabled);
+	return !disabled;
+}
+
+static void iommu_range_reserve(struct iommu_table *tbl,
+        unsigned long start_addr, unsigned int npages)
+{
+	unsigned long index;
+	unsigned long end;
+
+	index = start_addr >> PAGE_SHIFT;
+
+	/* bail out if we're asked to reserve a region we don't cover */
+	if (index >= tbl->it_size)
+		return;
+
+	end = index + npages;
+	if (end > tbl->it_size) /* don't go off the table */
+		end = tbl->it_size;
+
+	while (index < end) {
+		if (test_bit(index, tbl->it_map))
+			printk(KERN_ERR "Calgary: entry already allocated at "
+			       "0x%lx tbl %p dma 0x%lx npages %u\n",
+			       index, tbl, start_addr, npages);
+		++index;
+	}
+	set_bit_string(tbl->it_map, start_addr >> PAGE_SHIFT, npages);
+}
+
+static unsigned long iommu_range_alloc(struct iommu_table *tbl,
+	unsigned int npages)
+{
+	unsigned long offset;
+
+	BUG_ON(npages == 0);
+
+	offset = find_next_zero_string(tbl->it_map, tbl->it_hint,
+				       tbl->it_size, npages);
+	if (offset == ~0UL) {
+		tce_cache_blast(tbl);
+		offset = find_next_zero_string(tbl->it_map, 0,
+					       tbl->it_size, npages);
+		if (offset == ~0UL) {
+			printk(KERN_WARNING "Calgary: IOMMU full.\n");
+			if (panic_on_overflow)
+				panic("Calgary: fix the allocator.\n");
+			else
+				return bad_dma_address;
+		}
+	}
+
+	set_bit_string(tbl->it_map, offset, npages);
+	tbl->it_hint = offset + npages;
+	BUG_ON(tbl->it_hint > tbl->it_size);
+
+	return offset;
+}
+
+static dma_addr_t iommu_alloc(struct iommu_table *tbl, void *vaddr,
+	unsigned int npages, int direction)
+{
+	unsigned long entry, flags;
+	dma_addr_t ret = bad_dma_address;
+
+	spin_lock_irqsave(&tbl->it_lock, flags);
+
+	entry = iommu_range_alloc(tbl, npages);
+
+	if (unlikely(entry == bad_dma_address))
+		goto error;
+
+	/* set the return dma address */
+	ret = (entry << PAGE_SHIFT) | ((unsigned long)vaddr & ~PAGE_MASK);
+
+	/* put the TCEs in the HW table */
+	tce_build(tbl, entry, npages, (unsigned long)vaddr & PAGE_MASK,
+		  direction);
+
+	spin_unlock_irqrestore(&tbl->it_lock, flags);
+
+	return ret;
+
+error:
+	spin_unlock_irqrestore(&tbl->it_lock, flags);
+	printk(KERN_WARNING "Calgary: failed to allocate %u pages in "
+	       "iommu %p\n", npages, tbl);
+	return bad_dma_address;
+}
+
+static void __iommu_free(struct iommu_table *tbl, dma_addr_t dma_addr,
+	unsigned int npages)
+{
+	unsigned long entry;
+	unsigned long i;
+
+	entry = dma_addr >> PAGE_SHIFT;
+
+	BUG_ON(entry + npages > tbl->it_size);
+
+	tce_free(tbl, entry, npages);
+
+	for (i = 0; i < npages; ++i) {
+		if (!test_bit(entry + i, tbl->it_map))
+			printk(KERN_ERR "Calgary: bit is off at 0x%lx "
+			       "tbl %p dma 0x%Lx entry 0x%lx npages %u\n",
+			       entry + i, tbl, dma_addr, entry, npages);
+	}
+
+	__clear_bit_string(tbl->it_map, entry, npages);
+
+	tce_cache_blast_stress(tbl);
+}
+
+static void iommu_free(struct iommu_table *tbl, dma_addr_t dma_addr,
+	unsigned int npages)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&tbl->it_lock, flags);
+
+	__iommu_free(tbl, dma_addr, npages);
+
+	spin_unlock_irqrestore(&tbl->it_lock, flags);
+}
+
+static void __calgary_unmap_sg(struct iommu_table *tbl,
+	struct scatterlist *sglist, int nelems, int direction)
+{
+	while (nelems--) {
+		unsigned int npages;
+		dma_addr_t dma = sglist->dma_address;
+		unsigned int dmalen = sglist->dma_length;
+
+		if (dmalen == 0)
+			break;
+
+		npages = num_dma_pages(dma, dmalen);
+		__iommu_free(tbl, dma, npages);
+		sglist++;
+	}
+}
+
+void calgary_unmap_sg(struct device *dev, struct scatterlist *sglist,
+		      int nelems, int direction)
+{
+	unsigned long flags;
+	struct iommu_table *tbl = to_pci_dev(dev)->bus->self->sysdata;
+
+	if (!translate_phb(to_pci_dev(dev)))
+		return;
+
+	spin_lock_irqsave(&tbl->it_lock, flags);
+
+	__calgary_unmap_sg(tbl, sglist, nelems, direction);
+
+	spin_unlock_irqrestore(&tbl->it_lock, flags);
+}
+
+static int calgary_nontranslate_map_sg(struct device* dev,
+	struct scatterlist *sg, int nelems, int direction)
+{
+	int i;
+
+ 	for (i = 0; i < nelems; i++ ) {
+		struct scatterlist *s = &sg[i];
+		BUG_ON(!s->page);
+		s->dma_address = virt_to_bus(page_address(s->page) +s->offset);
+		s->dma_length = s->length;
+	}
+	return nelems;
+}
+
+int calgary_map_sg(struct device *dev, struct scatterlist *sg,
+	int nelems, int direction)
+{
+	struct iommu_table *tbl = to_pci_dev(dev)->bus->self->sysdata;
+	unsigned long flags;
+	unsigned long vaddr;
+	unsigned int npages;
+	unsigned long entry;
+	int i;
+
+	if (!translate_phb(to_pci_dev(dev)))
+		return calgary_nontranslate_map_sg(dev, sg, nelems, direction);
+
+	spin_lock_irqsave(&tbl->it_lock, flags);
+
+	for (i = 0; i < nelems; i++ ) {
+		struct scatterlist *s = &sg[i];
+		BUG_ON(!s->page);
+
+		vaddr = (unsigned long)page_address(s->page) + s->offset;
+		npages = num_dma_pages(vaddr, s->length);
+
+		entry = iommu_range_alloc(tbl, npages);
+		if (entry == bad_dma_address) {
+			/* makes sure unmap knows to stop */
+			s->dma_length = 0;
+			goto error;
+		}
+
+		s->dma_address = (entry << PAGE_SHIFT) | s->offset;
+
+		/* insert into HW table */
+		tce_build(tbl, entry, npages, vaddr & PAGE_MASK,
+			  direction);
+
+		s->dma_length = s->length;
+	}
+
+	spin_unlock_irqrestore(&tbl->it_lock, flags);
+
+	return nelems;
+error:
+	__calgary_unmap_sg(tbl, sg, nelems, direction);
+	for (i = 0; i < nelems; i++) {
+		sg[i].dma_address = bad_dma_address;
+		sg[i].dma_length = 0;
+	}
+	spin_unlock_irqrestore(&tbl->it_lock, flags);
+	return 0;
+}
+
+dma_addr_t calgary_map_single(struct device *dev, void *vaddr,
+	size_t size, int direction)
+{
+	dma_addr_t dma_handle = bad_dma_address;
+	unsigned long uaddr;
+	unsigned int npages;
+	struct iommu_table *tbl = to_pci_dev(dev)->bus->self->sysdata;
+
+	uaddr = (unsigned long)vaddr;
+	npages = num_dma_pages(uaddr, size);
+
+	if (translate_phb(to_pci_dev(dev)))
+		dma_handle = iommu_alloc(tbl, vaddr, npages, direction);
+	else
+		dma_handle = virt_to_bus(vaddr);
+
+	return dma_handle;
+}
+
+void calgary_unmap_single(struct device *dev, dma_addr_t dma_handle,
+	size_t size, int direction)
+{
+	struct iommu_table *tbl = to_pci_dev(dev)->bus->self->sysdata;
+	unsigned int npages;
+
+	if (!translate_phb(to_pci_dev(dev)))
+		return;
+
+	npages = num_dma_pages(dma_handle, size);
+	iommu_free(tbl, dma_handle, npages);
+}
+
+void* calgary_alloc_coherent(struct device *dev, size_t size,
+	dma_addr_t *dma_handle, gfp_t flag)
+{
+	void *ret = NULL;
+	dma_addr_t mapping;
+	unsigned int npages, order;
+	struct iommu_table *tbl;
+
+	tbl = to_pci_dev(dev)->bus->self->sysdata;
+
+	size = PAGE_ALIGN(size); /* size rounded up to full pages */
+	npages = size >> PAGE_SHIFT;
+	order = get_order(size);
+
+	/* alloc enough pages (and possibly more) */
+	ret = (void *)__get_free_pages(flag, order);
+	if (!ret)
+		goto error;
+	memset(ret, 0, size);
+
+	if (translate_phb(to_pci_dev(dev))) {
+		/* set up tces to cover the allocated range */
+		mapping = iommu_alloc(tbl, ret, npages, DMA_BIDIRECTIONAL);
+		if (mapping == bad_dma_address)
+			goto free;
+
+		*dma_handle = mapping;
+	} else /* non translated slot */
+		*dma_handle = virt_to_bus(ret);
+
+	return ret;
+
+free:
+	free_pages((unsigned long)ret, get_order(size));
+	ret = NULL;
+error:
+	return ret;
+}
+
+static struct dma_mapping_ops calgary_dma_ops = {
+	.alloc_coherent = calgary_alloc_coherent,
+	.map_single = calgary_map_single,
+	.unmap_single = calgary_unmap_single,
+	.map_sg = calgary_map_sg,
+	.unmap_sg = calgary_unmap_sg,
+};
+
+static inline int busno_to_phbid(unsigned char num)
+{
+	return bus_to_phb[num];
+}
+
+static inline unsigned long split_queue_offset(unsigned char num)
+{
+	size_t idx = busno_to_phbid(num);
+
+	return split_queue_offsets[idx];
+}
+
+static inline unsigned long tar_offset(unsigned char num)
+{
+	size_t idx = busno_to_phbid(num);
+
+	return tar_offsets[idx];
+}
+
+static inline unsigned long phb_offset(unsigned char num)
+{
+	size_t idx = busno_to_phbid(num);
+
+	return phb_offsets[idx];
+}
+
+static inline void __iomem* calgary_reg(void __iomem *bar, unsigned long offset)
+{
+	unsigned long target = ((unsigned long)bar) | offset;
+	return (void __iomem*)target;
+}
+
+static void tce_cache_blast(struct iommu_table *tbl)
+{
+	u64 val;
+	u32 aer;
+	int i = 0;
+	void __iomem *bbar = tbl->bbar;
+	void __iomem *target;
+
+	/* disable arbitration on the bus */
+	target = calgary_reg(bbar, phb_offset(tbl->it_busno) | PHB_AER_OFFSET);
+	aer = readl(target);
+	writel(0, target);
+
+	/* read plssr to ensure it got there */
+	target = calgary_reg(bbar, phb_offset(tbl->it_busno) | PHB_PLSSR_OFFSET);
+	val = readl(target);
+
+	/* poll split queues until all DMA activity is done */
+	target = calgary_reg(bbar, split_queue_offset(tbl->it_busno));
+	do {
+		val = readq(target);
+		i++;
+	} while ((val & 0xff) != 0xff && i < 100);
+	if (i == 100)
+		printk(KERN_WARNING "Calgary: PCI bus not quiesced, "
+		       "continuing anyway\n");
+
+	/* invalidate TCE cache */
+	target = calgary_reg(bbar, tar_offset(tbl->it_busno));
+	writeq(tbl->tar_val, target);
+
+	/* enable arbitration */
+	target = calgary_reg(bbar, phb_offset(tbl->it_busno) | PHB_AER_OFFSET);
+	writel(aer, target);
+	(void)readl(target); /* flush */
+}
+
+static void __init calgary_reserve_mem_region(struct pci_dev *dev, u64 start,
+	u64 limit)
+{
+	unsigned int numpages;
+
+	limit = limit | 0xfffff;
+	limit++;
+
+	numpages = ((limit - start) >> PAGE_SHIFT);
+	iommu_range_reserve(dev->sysdata, start, numpages);
+}
+
+static void __init calgary_reserve_peripheral_mem_1(struct pci_dev *dev)
+{
+	void __iomem *target;
+	u64 low, high, sizelow;
+	u64 start, limit;
+	struct iommu_table *tbl = dev->sysdata;
+	unsigned char busnum = dev->bus->number;
+	void __iomem *bbar = tbl->bbar;
+
+	/* peripheral MEM_1 region */
+	target = calgary_reg(bbar, phb_offset(busnum) | PHB_MEM_1_LOW);
+	low = be32_to_cpu(readl(target));
+	target = calgary_reg(bbar, phb_offset(busnum) | PHB_MEM_1_HIGH);
+	high = be32_to_cpu(readl(target));
+	target = calgary_reg(bbar, phb_offset(busnum) | PHB_MEM_1_SIZE);
+	sizelow = be32_to_cpu(readl(target));
+
+	start = (high << 32) | low;
+	limit = sizelow;
+
+	calgary_reserve_mem_region(dev, start, limit);
+}
+
+static void __init calgary_reserve_peripheral_mem_2(struct pci_dev *dev)
+{
+	void __iomem *target;
+	u32 val32;
+	u64 low, high, sizelow, sizehigh;
+	u64 start, limit;
+	struct iommu_table *tbl = dev->sysdata;
+	unsigned char busnum = dev->bus->number;
+	void __iomem *bbar = tbl->bbar;
+
+	/* is it enabled? */
+	target = calgary_reg(bbar, phb_offset(busnum) | PHB_CONFIG_RW_OFFSET);
+	val32 = be32_to_cpu(readl(target));
+	if (!(val32 & PHB_MEM2_ENABLE))
+		return;
+
+	target = calgary_reg(bbar, phb_offset(busnum) | PHB_MEM_2_LOW);
+	low = be32_to_cpu(readl(target));
+	target = calgary_reg(bbar, phb_offset(busnum) | PHB_MEM_2_HIGH);
+	high = be32_to_cpu(readl(target));
+	target = calgary_reg(bbar, phb_offset(busnum) | PHB_MEM_2_SIZE_LOW);
+	sizelow = be32_to_cpu(readl(target));
+	target = calgary_reg(bbar, phb_offset(busnum) | PHB_MEM_2_SIZE_HIGH);
+	sizehigh = be32_to_cpu(readl(target));
+
+	start = (high << 32) | low;
+	limit = (sizehigh << 32) | sizelow;
+
+	calgary_reserve_mem_region(dev, start, limit);
+}
+
+/*
+ * some regions of the IO address space do not get translated, so we
+ * must not give devices IO addresses in those regions. The regions
+ * are the 640KB-1MB region and the two PCI peripheral memory holes.
+ * Reserve all of them in the IOMMU bitmap to avoid giving them out
+ * later.
+ */
+static void __init calgary_reserve_regions(struct pci_dev *dev)
+{
+	unsigned int npages;
+	void __iomem *bbar;
+	unsigned char busnum;
+	u64 start;
+	struct iommu_table *tbl = dev->sysdata;
+
+	bbar = tbl->bbar;
+	busnum = dev->bus->number;
+
+	/* reserve bad_dma_address in case it's a legal address */
+	iommu_range_reserve(tbl, bad_dma_address, 1);
+
+	/* avoid the BIOS/VGA first 640KB-1MB region */
+	start = (640 * 1024);
+	npages = ((1024 - 640) * 1024) >> PAGE_SHIFT;
+	iommu_range_reserve(tbl, start, npages);
+
+	/* reserve the two PCI peripheral memory regions in IO space */
+	calgary_reserve_peripheral_mem_1(dev);
+	calgary_reserve_peripheral_mem_2(dev);
+}
+
+static int __init calgary_setup_tar(struct pci_dev *dev, void __iomem *bbar)
+{
+	u64 val64;
+	u64 table_phys;
+	void __iomem *target;
+	int ret;
+	struct iommu_table *tbl;
+
+	/* build TCE tables for each PHB */
+	ret = build_tce_table(dev, bbar);
+	if (ret)
+		return ret;
+
+	calgary_reserve_regions(dev);
+
+	/* set TARs for each PHB */
+	target = calgary_reg(bbar, tar_offset(dev->bus->number));
+	val64 = be64_to_cpu(readq(target));
+
+	/* zero out all TAR bits under sw control */
+	val64 &= ~TAR_SW_BITS;
+
+	tbl = dev->sysdata;
+	table_phys = (u64)__pa(tbl->it_base);
+	val64 |= table_phys;
+
+	BUG_ON(specified_table_size > TCE_TABLE_SIZE_8M);
+	val64 |= (u64) specified_table_size;
+
+	tbl->tar_val = cpu_to_be64(val64);
+	writeq(tbl->tar_val, target);
+	readq(target); /* flush */
+
+	return 0;
+}
+
+static void __init calgary_free_tar(struct pci_dev *dev)
+{
+	u64 val64;
+	struct iommu_table *tbl = dev->sysdata;
+	void __iomem *target;
+
+	target = calgary_reg(tbl->bbar, tar_offset(dev->bus->number));
+	val64 = be64_to_cpu(readq(target));
+	val64 &= ~TAR_SW_BITS;
+	writeq(cpu_to_be64(val64), target);
+	readq(target); /* flush */
+
+	kfree(tbl);
+	dev->sysdata = NULL;
+}
+
+static void calgary_watchdog(unsigned long data)
+{
+	struct pci_dev *dev = (struct pci_dev *)data;
+	struct iommu_table *tbl = dev->sysdata;
+	void __iomem *bbar = tbl->bbar;
+	u32 val32;
+	void __iomem *target;
+
+	target = calgary_reg(bbar, phb_offset(tbl->it_busno) | PHB_CSR_OFFSET);
+	val32 = be32_to_cpu(readl(target));
+
+	/* If no error, the agent ID in the CSR is not valid */
+	if (val32 & CSR_AGENT_MASK) {
+		printk(KERN_EMERG "calgary_watchdog: DMA error on bus %d, "
+				  "CSR = %#x\n", dev->bus->number, val32);
+		writel(0, target);
+
+		/* Disable bus that caused the error */
+		target = calgary_reg(bbar, phb_offset(tbl->it_busno) |
+					   PHB_CONFIG_RW_OFFSET);
+		val32 = be32_to_cpu(readl(target));
+		val32 |= PHB_SLOT_DISABLE;
+		writel(cpu_to_be32(val32), target);
+		readl(target); /* flush */
+	} else {
+		/* Reset the timer */
+		mod_timer(&tbl->watchdog_timer, jiffies + 2 * HZ);
+	}
+}
+
+static void __init calgary_enable_translation(struct pci_dev *dev)
+{
+	u32 val32;
+	unsigned char busnum;
+	void __iomem *target;
+	void __iomem *bbar;
+	struct iommu_table *tbl;
+
+	busnum = dev->bus->number;
+	tbl = dev->sysdata;
+	bbar = tbl->bbar;
+
+	/* enable TCE in PHB Config Register */
+	target = calgary_reg(bbar, phb_offset(busnum) | PHB_CONFIG_RW_OFFSET);
+	val32 = be32_to_cpu(readl(target));
+	val32 |= PHB_TCE_ENABLE | PHB_DAC_DISABLE | PHB_MCSR_ENABLE;
+
+	printk(KERN_INFO "Calgary: enabling translation on PHB %d\n", busnum);
+	printk(KERN_INFO "Calgary: errant DMAs will now be prevented on this "
+	       "bus.\n");
+
+	writel(cpu_to_be32(val32), target);
+	readl(target); /* flush */
+
+	init_timer(&tbl->watchdog_timer);
+	tbl->watchdog_timer.function = &calgary_watchdog;
+	tbl->watchdog_timer.data = (unsigned long)dev;
+	mod_timer(&tbl->watchdog_timer, jiffies);
+}
+
+static void __init calgary_disable_translation(struct pci_dev *dev)
+{
+	u32 val32;
+	unsigned char busnum;
+	void __iomem *target;
+	void __iomem *bbar;
+	struct iommu_table *tbl;
+
+	busnum = dev->bus->number;
+	tbl = dev->sysdata;
+	bbar = tbl->bbar;
+
+	/* disable TCE in PHB Config Register */
+	target = calgary_reg(bbar, phb_offset(busnum) | PHB_CONFIG_RW_OFFSET);
+	val32 = be32_to_cpu(readl(target));
+	val32 &= ~(PHB_TCE_ENABLE | PHB_DAC_DISABLE | PHB_MCSR_ENABLE);
+
+	printk(KERN_INFO "Calgary: disabling translation on PHB %d!\n", busnum);
+	writel(cpu_to_be32(val32), target);
+	readl(target); /* flush */
+
+	del_timer_sync(&tbl->watchdog_timer);
+}
+
+static inline unsigned int __init locate_register_space(struct pci_dev *dev)
+{
+	int rionodeid;
+	u32 address;
+
+	/*
+	 * Each Calgary has four busses. The first four busses (first Calgary)
+	 * have RIO node ID 2, then the next four (second Calgary) have RIO
+	 * node ID 3, the next four (third Calgary) have node ID 2 again, etc.
+	 * We use a gross hack - relying on the dev->bus->number ordering,
+	 * modulo 14 - to decide which Calgary a given bus is on. Busses 0, 1,
+	 * 2 and 4 are on the first Calgary (id 2), 6, 8, a and c are on the
+	 * second (id 3), and then it repeats modulo 14.
+ 	 */
+	rionodeid = (dev->bus->number % 14 > 4) ? 3 : 2;
+	/*
+	 * register space address calculation as follows:
+	 * FE0MB-8MB*OneBasedChassisNumber+1MB*(RioNodeId-ChassisBase)
+	 * ChassisBase is always zero for x366/x260/x460
+	 * RioNodeId is 2 for first Calgary, 3 for second Calgary
+	 */
+	address = START_ADDRESS	-
+		(0x800000 * (ONE_BASED_CHASSIS_NUM + dev->bus->number / 14)) +
+		(0x100000) * (rionodeid - CHASSIS_BASE);
+	return address;
+}
+
+static int __init calgary_init_one_nontraslated(struct pci_dev *dev)
+{
+	dev->sysdata = NULL;
+	dev->bus->self = dev;
+
+	return 0;
+}
+
+static int __init calgary_init_one(struct pci_dev *dev)
+{
+	u32 address;
+	void __iomem *bbar;
+	int ret;
+
+	address = locate_register_space(dev);
+	/* map entire 1MB of Calgary config space */
+	bbar = ioremap_nocache(address, 1024 * 1024);
+	if (!bbar) {
+		ret = -ENODATA;
+		goto done;
+	}
+
+	ret = calgary_setup_tar(dev, bbar);
+	if (ret)
+		goto iounmap;
+
+	dev->bus->self = dev;
+	calgary_enable_translation(dev);
+
+	return 0;
+
+iounmap:
+	iounmap(bbar);
+done:
+	return ret;
+}
+
+static int __init calgary_init(void)
+{
+	int i, ret = -ENODEV;
+	struct pci_dev *dev = NULL;
+
+	for (i = 0; i < MAX_PHB_BUS_NUM; i++) {
+		dev = pci_get_device(PCI_VENDOR_ID_IBM,
+				     PCI_DEVICE_ID_IBM_CALGARY,
+				     dev);
+		if (!dev)
+			break;
+		if (!translate_phb(dev)) {
+			calgary_init_one_nontraslated(dev);
+			continue;
+		}
+		if (!tce_table_kva[dev->bus->number] && !translate_empty_slots) {
+			pci_dev_put(dev);
+			continue;
+		}
+		ret = calgary_init_one(dev);
+		if (ret)
+			goto error;
+	}
+
+	return ret;
+
+error:
+	for (i--; i >= 0; i--) {
+		dev = pci_find_device_reverse(PCI_VENDOR_ID_IBM,
+					      PCI_DEVICE_ID_IBM_CALGARY,
+					      dev);
+		if (!translate_phb(dev)) {
+			pci_dev_put(dev);
+			continue;
+		}
+		if (!tce_table_kva[dev->bus->number] && !translate_empty_slots)
+			continue;
+		calgary_disable_translation(dev);
+		calgary_free_tar(dev);
+		pci_dev_put(dev);
+	}
+
+	return ret;
+}
+
+static inline int __init determine_tce_table_size(u64 ram)
+{
+	int ret;
+
+	if (specified_table_size != TCE_TABLE_SIZE_UNSPECIFIED)
+		return specified_table_size;
+
+	/*
+	 * Table sizes are from 0 to 7 (TCE_TABLE_SIZE_64K to
+	 * TCE_TABLE_SIZE_8M). Table size 0 has 8K entries and each
+	 * larger table size has twice as many entries, so shift the
+	 * max ram address by 13 to divide by 8K and then look at the
+	 * order of the result to choose between 0-7.
+	 */
+	ret = get_order(ram >> 13);
+	if (ret > TCE_TABLE_SIZE_8M)
+		ret = TCE_TABLE_SIZE_8M;
+
+	return ret;
+}
+
+void __init detect_calgary(void)
+{
+	u32 val;
+	int bus;
+	void *tbl;
+	int calgary_found = 0;
+	int phb = -1;
+
+	/*
+	 * if the user specified iommu=off or iommu=soft or we found
+	 * another HW IOMMU already, bail out.
+	 */
+	if (swiotlb || no_iommu || iommu_detected)
+		return;
+
+	specified_table_size = determine_tce_table_size(end_pfn * PAGE_SIZE);
+
+	for (bus = 0; bus < MAX_PHB_BUS_NUM; bus++) {
+		int dev;
+
+		tce_table_kva[bus] = NULL;
+		bus_to_phb[bus] = -1;
+
+		if (read_pci_config(bus, 0, 0, 0) != PCI_VENDOR_DEVICE_ID_CALGARY)
+			continue;
+
+		/*
+		 * There are 4 PHBs per Calgary chip.  Set phb to which phb (0-3)
+		 * it is connected to releative to the clagary chip.
+		 */
+		phb = (phb + 1) % PHBS_PER_CALGARY;
+
+		if (test_bit(bus, translation_disabled)) {
+			printk(KERN_INFO "Calgary: translation is disabled for "
+			       "PHB 0x%x\n", bus);
+			/* skip this phb, don't allocate a tbl for it */
+			continue;
+		}
+		/*
+		 * Scan the slots of the PCI bus to see if there is a device present.
+		 * The parent bus will be the zero-ith device, so start at 1.
+		 */
+		for (dev = 1; dev < 8; dev++) {
+			val = read_pci_config(bus, dev, 0, 0);
+			if (val != 0xffffffff || translate_empty_slots) {
+				tbl = alloc_tce_table();
+				if (!tbl)
+					goto cleanup;
+				tce_table_kva[bus] = tbl;
+				bus_to_phb[bus] = phb;
+				calgary_found = 1;
+				break;
+			}
+		}
+	}
+
+	if (calgary_found) {
+		iommu_detected = 1;
+		calgary_detected = 1;
+		printk(KERN_INFO "PCI-DMA: Calgary IOMMU detected. "
+		       "TCE table spec is %d.\n", specified_table_size);
+	}
+	return;
+
+cleanup:
+	for (--bus; bus >= 0; --bus)
+		if (tce_table_kva[bus])
+			free_tce_table(tce_table_kva[bus]);
+}
+
+int __init calgary_iommu_init(void)
+{
+	int ret;
+
+	if (no_iommu || swiotlb)
+		return -ENODEV;
+
+	if (!calgary_detected)
+		return -ENODEV;
+
+	/* ok, we're trying to use Calgary - let's roll */
+	printk(KERN_INFO "PCI-DMA: Using Calgary IOMMU\n");
+
+	ret = calgary_init();
+	if (ret) {
+		printk(KERN_ERR "PCI-DMA: Calgary init failed %d, "
+		       "falling back to no_iommu\n", ret);
+		if (end_pfn > MAX_DMA32_PFN)
+			printk(KERN_ERR "WARNING more than 4GB of memory, "
+					"32bit PCI may malfunction.\n");
+		return ret;
+	}
+
+	force_iommu = 1;
+	dma_ops = &calgary_dma_ops;
+
+	return 0;
+}
+
+static int __init calgary_parse_options(char *p)
+{
+	unsigned int bridge;
+	size_t len;
+	char* endp;
+
+	while (*p) {
+		if (!strncmp(p, "64k", 3))
+			specified_table_size = TCE_TABLE_SIZE_64K;
+		else if (!strncmp(p, "128k", 4))
+			specified_table_size = TCE_TABLE_SIZE_128K;
+		else if (!strncmp(p, "256k", 4))
+			specified_table_size = TCE_TABLE_SIZE_256K;
+		else if (!strncmp(p, "512k", 4))
+			specified_table_size = TCE_TABLE_SIZE_512K;
+		else if (!strncmp(p, "1M", 2))
+			specified_table_size = TCE_TABLE_SIZE_1M;
+		else if (!strncmp(p, "2M", 2))
+			specified_table_size = TCE_TABLE_SIZE_2M;
+		else if (!strncmp(p, "4M", 2))
+			specified_table_size = TCE_TABLE_SIZE_4M;
+		else if (!strncmp(p, "8M", 2))
+			specified_table_size = TCE_TABLE_SIZE_8M;
+
+		len = strlen("translate_empty_slots");
+		if (!strncmp(p, "translate_empty_slots", len))
+			translate_empty_slots = 1;
+
+		len = strlen("disable");
+		if (!strncmp(p, "disable", len)) {
+			p += len;
+			if (*p == '=')
+				++p;
+			if (*p == '\0')
+				break;
+			bridge = simple_strtol(p, &endp, 0);
+			if (p == endp)
+				break;
+
+			if (bridge < MAX_PHB_BUS_NUM) {
+				printk(KERN_INFO "Calgary: disabling "
+				       "translation for PHB 0x%x\n", bridge);
+				set_bit(bridge, translation_disabled);
+			}
+		}
+
+		p = strpbrk(p, ",");
+		if (!p)
+			break;
+
+		p++; /* skip ',' */
+	}
+	return 1;
+}
+__setup("calgary=", calgary_parse_options);
diff --git a/arch/x86_64/kernel/stacktrace.c b/arch/x86_64/kernel/stacktrace.c
new file mode 100644
index 000000000..6026b31d0
--- /dev/null
+++ b/arch/x86_64/kernel/stacktrace.c
@@ -0,0 +1,55 @@
+/*
+ * arch/x86_64/kernel/stacktrace.c
+ *
+ * Stack trace management functions
+ *
+ *  Copyright (C) 2006 Red Hat, Inc., Ingo Molnar <mingo@redhat.com>
+ */
+#include <linux/sched.h>
+#include <linux/stacktrace.h>
+#include <linux/module.h>
+#include <asm/stacktrace.h>
+
+static void save_stack_warning(void *data, char *msg)
+{
+}
+
+static void
+save_stack_warning_symbol(void *data, char *msg, unsigned long symbol)
+{
+}
+
+static int save_stack_stack(void *data, char *name)
+{
+	struct stack_trace *trace = (struct stack_trace *)data;
+	return trace->all_contexts ? 0 : -1;
+}
+
+static void save_stack_address(void *data, unsigned long addr)
+{
+	struct stack_trace *trace = (struct stack_trace *)data;
+	if (trace->skip > 0) {
+		trace->skip--;
+		return;
+	}
+	if (trace->nr_entries < trace->max_entries - 1)
+		trace->entries[trace->nr_entries++] = addr;
+}
+
+static struct stacktrace_ops save_stack_ops = {
+	.warning = save_stack_warning,
+	.warning_symbol = save_stack_warning_symbol,
+	.stack = save_stack_stack,
+	.address = save_stack_address,
+};
+
+/*
+ * Save stack-backtrace addresses into a stack_trace buffer.
+ */
+void save_stack_trace(struct stack_trace *trace, struct task_struct *task)
+{
+	dump_trace(task, NULL, NULL, &save_stack_ops, trace);
+	trace->entries[trace->nr_entries++] = ULONG_MAX;
+}
+EXPORT_SYMBOL(save_stack_trace);
+
diff --git a/arch/x86_64/kernel/tce.c b/arch/x86_64/kernel/tce.c
new file mode 100644
index 000000000..1affe8cab
--- /dev/null
+++ b/arch/x86_64/kernel/tce.c
@@ -0,0 +1,201 @@
+/*
+ * Derived from arch/powerpc/platforms/pseries/iommu.c
+ *
+ * Copyright (C) IBM Corporation, 2006
+ *
+ * Author: Jon Mason <jdmason@us.ibm.com>
+ * Author: Muli Ben-Yehuda <muli@il.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 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/types.h>
+#include <linux/slab.h>
+#include <linux/mm.h>
+#include <linux/spinlock.h>
+#include <linux/string.h>
+#include <linux/pci.h>
+#include <linux/dma-mapping.h>
+#include <linux/bootmem.h>
+#include <asm/tce.h>
+#include <asm/calgary.h>
+#include <asm/proto.h>
+
+/* flush a tce at 'tceaddr' to main memory */
+static inline void flush_tce(void* tceaddr)
+{
+	/* a single tce can't cross a cache line */
+	if (cpu_has_clflush)
+		asm volatile("clflush (%0)" :: "r" (tceaddr));
+	else
+		asm volatile("wbinvd":::"memory");
+}
+
+void tce_build(struct iommu_table *tbl, unsigned long index,
+	unsigned int npages, unsigned long uaddr, int direction)
+{
+	u64* tp;
+	u64 t;
+	u64 rpn;
+
+	t = (1 << TCE_READ_SHIFT);
+	if (direction != DMA_TO_DEVICE)
+		t |= (1 << TCE_WRITE_SHIFT);
+
+	tp = ((u64*)tbl->it_base) + index;
+
+	while (npages--) {
+		rpn = (virt_to_bus((void*)uaddr)) >> PAGE_SHIFT;
+		t &= ~TCE_RPN_MASK;
+		t |= (rpn << TCE_RPN_SHIFT);
+
+		*tp = cpu_to_be64(t);
+		flush_tce(tp);
+
+		uaddr += PAGE_SIZE;
+		tp++;
+	}
+}
+
+void tce_free(struct iommu_table *tbl, long index, unsigned int npages)
+{
+	u64* tp;
+
+	tp  = ((u64*)tbl->it_base) + index;
+
+	while (npages--) {
+		*tp = cpu_to_be64(0);
+		flush_tce(tp);
+		tp++;
+	}
+}
+
+static inline unsigned int table_size_to_number_of_entries(unsigned char size)
+{
+	/*
+	 * size is the order of the table, 0-7
+	 * smallest table is 8K entries, so shift result by 13 to
+	 * multiply by 8K
+	 */
+	return (1 << size) << 13;
+}
+
+static int tce_table_setparms(struct pci_dev *dev, struct iommu_table *tbl)
+{
+	unsigned int bitmapsz;
+	unsigned long bmppages;
+	int ret;
+
+	tbl->it_busno = dev->bus->number;
+
+	/* set the tce table size - measured in entries */
+	tbl->it_size = table_size_to_number_of_entries(specified_table_size);
+
+	tbl->it_base = (unsigned long)tce_table_kva[dev->bus->number];
+	if (!tbl->it_base) {
+		printk(KERN_ERR "Calgary: iommu_table_setparms: "
+		       "no table allocated?!\n");
+		ret = -ENOMEM;
+		goto done;
+	}
+
+	/*
+	 * number of bytes needed for the bitmap size in number of
+	 * entries; we need one bit per entry
+	 */
+	bitmapsz = tbl->it_size / BITS_PER_BYTE;
+	bmppages = __get_free_pages(GFP_KERNEL, get_order(bitmapsz));
+	if (!bmppages) {
+		printk(KERN_ERR "Calgary: cannot allocate bitmap\n");
+		ret = -ENOMEM;
+		goto done;
+	}
+
+	tbl->it_map = (unsigned long*)bmppages;
+
+	memset(tbl->it_map, 0, bitmapsz);
+
+	tbl->it_hint = 0;
+
+	spin_lock_init(&tbl->it_lock);
+
+	return 0;
+
+done:
+	return ret;
+}
+
+int build_tce_table(struct pci_dev *dev, void __iomem *bbar)
+{
+	struct iommu_table *tbl;
+	int ret;
+
+	if (dev->sysdata) {
+		printk(KERN_ERR "Calgary: dev %p has sysdata %p\n",
+		       dev, dev->sysdata);
+		BUG();
+	}
+
+	tbl = kzalloc(sizeof(struct iommu_table), GFP_KERNEL);
+	if (!tbl) {
+		printk(KERN_ERR "Calgary: error allocating iommu_table\n");
+		ret = -ENOMEM;
+		goto done;
+	}
+
+	ret = tce_table_setparms(dev, tbl);
+	if (ret)
+		goto free_tbl;
+
+	tce_free(tbl, 0, tbl->it_size);
+
+	tbl->bbar = bbar;
+
+	/*
+	 * NUMA is already using the bus's sysdata pointer, so we use
+	 * the bus's pci_dev's sysdata instead.
+	 */
+	dev->sysdata = tbl;
+
+	return 0;
+
+free_tbl:
+	kfree(tbl);
+done:
+	return ret;
+}
+
+void* alloc_tce_table(void)
+{
+	unsigned int size;
+
+	size = table_size_to_number_of_entries(specified_table_size);
+	size *= TCE_ENTRY_SIZE;
+
+	return __alloc_bootmem_low(size, size, 0);
+}
+
+void free_tce_table(void *tbl)
+{
+	unsigned int size;
+
+	if (!tbl)
+		return;
+
+	size = table_size_to_number_of_entries(specified_table_size);
+	size *= TCE_ENTRY_SIZE;
+
+	free_bootmem(__pa(tbl), size);
+}
diff --git a/arch/x86_64/lib/rwlock.S b/arch/x86_64/lib/rwlock.S
new file mode 100644
index 000000000..0cde1f807
--- /dev/null
+++ b/arch/x86_64/lib/rwlock.S
@@ -0,0 +1,38 @@
+/* Slow paths of read/write spinlocks. */
+
+#include <linux/linkage.h>
+#include <asm/rwlock.h>
+#include <asm/alternative-asm.i>
+#include <asm/dwarf2.h>
+
+/* rdi:	pointer to rwlock_t */
+ENTRY(__write_lock_failed)
+	CFI_STARTPROC
+	LOCK_PREFIX
+	addl $RW_LOCK_BIAS,(%rdi)
+1:	rep
+	nop
+	cmpl $RW_LOCK_BIAS,(%rdi)
+	jne 1b
+	LOCK_PREFIX
+	subl $RW_LOCK_BIAS,(%rdi)
+	jnz  __write_lock_failed
+	ret
+	CFI_ENDPROC
+END(__write_lock_failed)
+
+/* rdi:	pointer to rwlock_t */
+ENTRY(__read_lock_failed)
+	CFI_STARTPROC
+	LOCK_PREFIX
+	incl (%rdi)
+1:	rep
+	nop
+	cmpl $1,(%rdi)
+	js 1b
+	LOCK_PREFIX
+	decl (%rdi)
+	js __read_lock_failed
+	ret
+	CFI_ENDPROC
+END(__read_lock_failed)
diff --git a/configs/kernel-2.6.18-i586-smp.config b/configs/kernel-2.6.18-i586-smp.config
new file mode 100644
index 000000000..224fc97d5
--- /dev/null
+++ b/configs/kernel-2.6.18-i586-smp.config
@@ -0,0 +1,3368 @@
+# i386
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.18.2-rc1
+# Mon Nov 13 09:44:39 2006
+#
+CONFIG_X86_32=y
+CONFIG_GENERIC_TIME=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_SEMAPHORE_SLEEPERS=y
+CONFIG_X86=y
+CONFIG_MMU=y
+CONFIG_GENERIC_ISA_DMA=y
+CONFIG_GENERIC_IOMAP=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_ARCH_MAY_HAVE_PC_FDC=y
+CONFIG_DMI=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_BSD_PROCESS_ACCT=y
+# CONFIG_BSD_PROCESS_ACCT_V3 is not set
+CONFIG_TASKSTATS=y
+CONFIG_TASK_DELAY_ACCT=y
+CONFIG_AUDIT=y
+CONFIG_AUDITSYSCALL=y
+# CONFIG_IKCONFIG is not set
+CONFIG_CPUSETS=y
+CONFIG_RELAY=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+# CONFIG_EMBEDDED is not set
+CONFIG_UID16=y
+CONFIG_SYSCTL=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
+CONFIG_KALLSYMS_EXTRA_PASS=y
+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=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+CONFIG_MODULE_SIG=y
+# CONFIG_MODULE_SIG_FORCE is not set
+CONFIG_KMOD=y
+CONFIG_STOP_MACHINE=y
+
+#
+# Process debugging support
+#
+CONFIG_UTRACE=y
+CONFIG_PTRACE=y
+
+#
+# Block layer
+#
+CONFIG_LBD=y
+CONFIG_BLK_DEV_IO_TRACE=y
+CONFIG_LSF=y
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_DEFAULT_AS is not set
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+
+#
+# Processor type and features
+#
+CONFIG_SMP=y
+CONFIG_X86_PC=y
+# CONFIG_X86_XEN is not set
+# CONFIG_X86_ELAN is not set
+# CONFIG_X86_VOYAGER is not set
+# CONFIG_X86_NUMAQ is not set
+# CONFIG_X86_SUMMIT is not set
+# CONFIG_X86_BIGSMP is not set
+# CONFIG_X86_VISWS is not set
+# CONFIG_X86_GENERICARCH is not set
+# CONFIG_X86_ES7000 is not set
+# CONFIG_M386 is not set
+# CONFIG_M486 is not set
+CONFIG_M586=y
+# CONFIG_M586TSC is not set
+# CONFIG_M586MMX is not set
+# CONFIG_M686 is not set
+# CONFIG_MPENTIUMII is not set
+# CONFIG_MPENTIUMIII is not set
+# CONFIG_MPENTIUMM is not set
+# CONFIG_MPENTIUM4 is not set
+# CONFIG_MK6 is not set
+# CONFIG_MK7 is not set
+# CONFIG_MK8 is not set
+# CONFIG_MCRUSOE is not set
+# CONFIG_MEFFICEON is not set
+# CONFIG_MWINCHIPC6 is not set
+# CONFIG_MWINCHIP2 is not set
+# CONFIG_MWINCHIP3D is not set
+# CONFIG_MGEODEGX1 is not set
+# CONFIG_MGEODE_LX is not set
+# CONFIG_MCYRIXIII is not set
+# CONFIG_MVIAC3_2 is not set
+CONFIG_X86_GENERIC=y
+CONFIG_X86_CMPXCHG=y
+CONFIG_X86_XADD=y
+CONFIG_X86_L1_CACHE_SHIFT=7
+CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_X86_PPRO_FENCE=y
+CONFIG_X86_F00F_BUG=y
+CONFIG_X86_WP_WORKS_OK=y
+CONFIG_X86_INVLPG=y
+CONFIG_X86_BSWAP=y
+CONFIG_X86_POPAD_OK=y
+CONFIG_X86_CMPXCHG64=y
+CONFIG_X86_ALIGNMENT_16=y
+CONFIG_X86_INTEL_USERCOPY=y
+CONFIG_HPET_TIMER=y
+CONFIG_HPET_EMULATE_RTC=y
+CONFIG_NR_CPUS=2
+CONFIG_SCHED_SMT=y
+CONFIG_SCHED_MC=y
+# CONFIG_PREEMPT_NONE is not set
+CONFIG_PREEMPT_VOLUNTARY=y
+# CONFIG_PREEMPT is not set
+CONFIG_PREEMPT_BKL=y
+CONFIG_X86_LOCAL_APIC=y
+CONFIG_X86_APIC_AUTO=y
+CONFIG_X86_IO_APIC=y
+CONFIG_X86_MCE=y
+# CONFIG_X86_MCE_NONFATAL is not set
+# CONFIG_X86_MCE_P4THERMAL is not set
+CONFIG_VM86=y
+# CONFIG_TOSHIBA is not set
+# CONFIG_I8K is not set
+# CONFIG_X86_REBOOTFIXUPS is not set
+# CONFIG_MICROCODE is not set
+CONFIG_X86_MSR=m
+CONFIG_X86_CPUID=m
+# CONFIG_SWIOTLB is not set
+
+#
+# Firmware Drivers
+#
+CONFIG_EDD=m
+CONFIG_EFI_VARS=y
+# CONFIG_DELL_RBU is not set
+# CONFIG_DCDBAS is not set
+# CONFIG_NOHIGHMEM is not set
+CONFIG_HIGHMEM4G=y
+# CONFIG_HIGHMEM64G is not set
+CONFIG_PAGE_OFFSET=0xC0000000
+CONFIG_HIGHMEM=y
+CONFIG_ARCH_FLATMEM_ENABLE=y
+CONFIG_ARCH_SPARSEMEM_ENABLE=y
+CONFIG_ARCH_SELECT_MEMORY_MODEL=y
+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=y
+CONFIG_SPLIT_PTLOCK_CPUS=4096
+CONFIG_RESOURCES_64BIT=y
+CONFIG_HIGHPTE=y
+# CONFIG_MATH_EMULATION is not set
+CONFIG_MTRR=y
+CONFIG_EFI=y
+# CONFIG_IRQBALANCE is not set
+CONFIG_BOOT_IOREMAP=y
+CONFIG_REGPARM=y
+# CONFIG_SECCOMP is not set
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
+CONFIG_KEXEC=y
+# CONFIG_CRASH_DUMP is not set
+CONFIG_PHYSICAL_START=0x400000
+CONFIG_HOTPLUG_CPU=y
+# CONFIG_COMPAT_VDSO is not set
+CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
+
+#
+# Power management options (ACPI, APM)
+#
+CONFIG_PM=y
+CONFIG_PM_LEGACY=y
+# CONFIG_PM_DEBUG is not set
+CONFIG_SOFTWARE_SUSPEND=y
+CONFIG_PM_STD_PARTITION=""
+CONFIG_SUSPEND_SMP=y
+
+#
+# ACPI (Advanced Configuration and Power Interface) Support
+#
+CONFIG_ACPI=y
+CONFIG_ACPI_SLEEP=y
+CONFIG_ACPI_SLEEP_PROC_FS=y
+# CONFIG_ACPI_SLEEP_PROC_SLEEP is not set
+CONFIG_ACPI_AC=m
+CONFIG_ACPI_BATTERY=m
+CONFIG_ACPI_BUTTON=m
+CONFIG_ACPI_VIDEO=m
+# CONFIG_ACPI_HOTKEY is not set
+CONFIG_ACPI_FAN=y
+CONFIG_ACPI_DOCK=m
+CONFIG_ACPI_PROCESSOR=y
+CONFIG_ACPI_HOTPLUG_CPU=y
+CONFIG_ACPI_THERMAL=y
+# CONFIG_ACPI_ASUS is not set
+# CONFIG_ACPI_IBM is not set
+# CONFIG_ACPI_TOSHIBA is not set
+CONFIG_ACPI_BLACKLIST_YEAR=1999
+# CONFIG_ACPI_DEBUG is not set
+CONFIG_ACPI_EC=y
+CONFIG_ACPI_POWER=y
+CONFIG_ACPI_SYSTEM=y
+CONFIG_X86_PM_TIMER=y
+CONFIG_ACPI_CONTAINER=y
+CONFIG_ACPI_SBS=m
+
+#
+# APM (Advanced Power Management) BIOS Support
+#
+CONFIG_APM=y
+# CONFIG_APM_IGNORE_USER_SUSPEND is not set
+# CONFIG_APM_DO_ENABLE is not set
+CONFIG_APM_CPU_IDLE=y
+# CONFIG_APM_DISPLAY_BLANK is not set
+CONFIG_APM_RTC_IS_GMT=y
+# CONFIG_APM_ALLOW_INTS is not set
+# CONFIG_APM_REAL_MODE_POWER_OFF is not set
+
+#
+# CPU Frequency scaling
+#
+CONFIG_CPU_FREQ=y
+CONFIG_CPU_FREQ_TABLE=m
+CONFIG_CPU_FREQ_DEBUG=y
+CONFIG_CPU_FREQ_STAT=m
+CONFIG_CPU_FREQ_STAT_DETAILS=y
+# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set
+CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE=y
+CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
+CONFIG_CPU_FREQ_GOV_POWERSAVE=m
+CONFIG_CPU_FREQ_GOV_USERSPACE=y
+CONFIG_CPU_FREQ_GOV_ONDEMAND=m
+CONFIG_CPU_FREQ_GOV_CONSERVATIVE=m
+
+#
+# CPUFreq processor drivers
+#
+CONFIG_X86_ACPI_CPUFREQ=m
+# CONFIG_X86_POWERNOW_K6 is not set
+# CONFIG_X86_POWERNOW_K7 is not set
+# CONFIG_X86_POWERNOW_K8 is not set
+# CONFIG_X86_GX_SUSPMOD is not set
+# CONFIG_X86_SPEEDSTEP_CENTRINO is not set
+# CONFIG_X86_SPEEDSTEP_ICH is not set
+# CONFIG_X86_SPEEDSTEP_SMI is not set
+# CONFIG_X86_P4_CLOCKMOD is not set
+# CONFIG_X86_CPUFREQ_NFORCE2 is not set
+CONFIG_X86_LONGRUN=y
+# CONFIG_X86_LONGHAUL is not set
+
+#
+# shared options
+#
+# CONFIG_X86_ACPI_CPUFREQ_PROC_INTF is not set
+# CONFIG_X86_SPEEDSTEP_LIB is not set
+
+#
+# Bus options (PCI, PCMCIA, EISA, MCA, ISA)
+#
+CONFIG_PCI=y
+# CONFIG_PCI_GOBIOS is not set
+# CONFIG_PCI_GOMMCONFIG is not set
+# CONFIG_PCI_GODIRECT is not set
+# CONFIG_PCI_GOXEN_FE is not set
+CONFIG_PCI_GOANY=y
+CONFIG_PCI_BIOS=y
+CONFIG_PCI_DIRECT=y
+CONFIG_PCI_MMCONFIG=y
+CONFIG_PCIEPORTBUS=y
+CONFIG_PCI_MSI=y
+# CONFIG_PCI_DEBUG is not set
+CONFIG_ISA_DMA_API=y
+CONFIG_ISA=y
+# CONFIG_EISA is not set
+# CONFIG_MCA is not set
+# CONFIG_SCx200 is not set
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+CONFIG_PCCARD=y
+# CONFIG_PCMCIA_DEBUG is not set
+CONFIG_PCMCIA=y
+CONFIG_PCMCIA_LOAD_CIS=y
+CONFIG_PCMCIA_IOCTL=y
+CONFIG_CARDBUS=y
+
+#
+# PC-card bridges
+#
+CONFIG_YENTA=y
+CONFIG_YENTA_O2=y
+CONFIG_YENTA_RICOH=y
+CONFIG_YENTA_TI=y
+CONFIG_YENTA_ENE_TUNE=y
+CONFIG_YENTA_TOSHIBA=y
+CONFIG_PD6729=m
+CONFIG_I82092=m
+# CONFIG_I82365 is not set
+# CONFIG_TCIC is not set
+CONFIG_PCMCIA_PROBE=y
+CONFIG_PCCARD_NONSTATIC=y
+
+#
+# PCI Hotplug Support
+#
+# CONFIG_HOTPLUG_PCI is not set
+
+#
+# Executable file formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_AOUT is not set
+CONFIG_BINFMT_MISC=y
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+# CONFIG_NETDEBUG is not set
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=y
+CONFIG_NET_KEY=m
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_ASK_IP_FIB_HASH=y
+# 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
+# CONFIG_IP_PNP is not set
+CONFIG_NET_IPIP=m
+CONFIG_NET_IPGRE=m
+CONFIG_NET_IPGRE_BROADCAST=y
+CONFIG_IP_MROUTE=y
+CONFIG_IP_PIMSM_V1=y
+CONFIG_IP_PIMSM_V2=y
+# CONFIG_ARPD is not set
+CONFIG_SYN_COOKIES=y
+CONFIG_INET_AH=m
+CONFIG_INET_ESP=m
+CONFIG_INET_IPCOMP=m
+CONFIG_INET_XFRM_TUNNEL=m
+CONFIG_INET_TUNNEL=m
+CONFIG_INET_XFRM_MODE_TRANSPORT=m
+CONFIG_INET_XFRM_MODE_TUNNEL=m
+CONFIG_INET_DIAG=m
+CONFIG_INET_TCP_DIAG=m
+CONFIG_TCP_CONG_ADVANCED=y
+
+#
+# TCP congestion control
+#
+CONFIG_TCP_CONG_BIC=y
+CONFIG_TCP_CONG_CUBIC=m
+CONFIG_TCP_CONG_WESTWOOD=m
+CONFIG_TCP_CONG_HTCP=m
+CONFIG_TCP_CONG_HSTCP=m
+CONFIG_TCP_CONG_HYBLA=m
+CONFIG_TCP_CONG_VEGAS=m
+CONFIG_TCP_CONG_SCALABLE=m
+CONFIG_TCP_CONG_LP=m
+CONFIG_TCP_CONG_VENO=m
+
+#
+# IP: Virtual Server Configuration
+#
+CONFIG_IP_VS=m
+# CONFIG_IP_VS_DEBUG is not set
+CONFIG_IP_VS_TAB_BITS=12
+
+#
+# IPVS transport protocol load balancing support
+#
+CONFIG_IP_VS_PROTO_TCP=y
+CONFIG_IP_VS_PROTO_UDP=y
+CONFIG_IP_VS_PROTO_ESP=y
+CONFIG_IP_VS_PROTO_AH=y
+
+#
+# IPVS scheduler
+#
+CONFIG_IP_VS_RR=m
+CONFIG_IP_VS_WRR=m
+CONFIG_IP_VS_LC=m
+CONFIG_IP_VS_WLC=m
+CONFIG_IP_VS_LBLC=m
+CONFIG_IP_VS_LBLCR=m
+CONFIG_IP_VS_DH=m
+CONFIG_IP_VS_SH=m
+CONFIG_IP_VS_SED=m
+CONFIG_IP_VS_NQ=m
+
+#
+# IPVS application helper
+#
+CONFIG_IP_VS_FTP=m
+CONFIG_IPV6=m
+CONFIG_IPV6_PRIVACY=y
+CONFIG_IPV6_ROUTER_PREF=y
+CONFIG_IPV6_ROUTE_INFO=y
+CONFIG_INET6_AH=m
+CONFIG_INET6_ESP=m
+CONFIG_INET6_IPCOMP=m
+CONFIG_INET6_XFRM_TUNNEL=m
+CONFIG_INET6_TUNNEL=m
+CONFIG_INET6_XFRM_MODE_TRANSPORT=m
+CONFIG_INET6_XFRM_MODE_TUNNEL=m
+CONFIG_IPV6_TUNNEL=m
+CONFIG_NETWORK_SECMARK=y
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_DEBUG is not set
+CONFIG_BRIDGE_NETFILTER=y
+
+#
+# Core Netfilter Configuration
+#
+CONFIG_NETFILTER_NETLINK=m
+CONFIG_NETFILTER_NETLINK_QUEUE=m
+CONFIG_NETFILTER_NETLINK_LOG=m
+CONFIG_NETFILTER_XTABLES=m
+CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
+CONFIG_NETFILTER_XT_TARGET_CONNMARK=m
+CONFIG_NETFILTER_XT_TARGET_MARK=m
+CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
+CONFIG_NETFILTER_XT_TARGET_NOTRACK=m
+CONFIG_NETFILTER_XT_TARGET_SECMARK=m
+CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=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_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_PHYSDEV=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
+
+#
+# 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=m
+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_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_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_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
+CONFIG_IP_NF_ARPTABLES=m
+CONFIG_IP_NF_ARPFILTER=m
+CONFIG_IP_NF_ARP_MANGLE=m
+
+#
+# IPv6: Netfilter Configuration (EXPERIMENTAL)
+#
+CONFIG_IP6_NF_QUEUE=m
+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_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
+
+#
+# DECnet: Netfilter Configuration
+#
+# CONFIG_DECNET_NF_GRABULATOR is not set
+
+#
+# Bridge: Netfilter Configuration
+#
+CONFIG_BRIDGE_NF_EBTABLES=m
+CONFIG_BRIDGE_EBT_BROUTE=m
+CONFIG_BRIDGE_EBT_T_FILTER=m
+CONFIG_BRIDGE_EBT_T_NAT=m
+CONFIG_BRIDGE_EBT_802_3=m
+CONFIG_BRIDGE_EBT_AMONG=m
+CONFIG_BRIDGE_EBT_ARP=m
+CONFIG_BRIDGE_EBT_IP=m
+CONFIG_BRIDGE_EBT_LIMIT=m
+CONFIG_BRIDGE_EBT_MARK=m
+CONFIG_BRIDGE_EBT_PKTTYPE=m
+CONFIG_BRIDGE_EBT_STP=m
+CONFIG_BRIDGE_EBT_VLAN=m
+CONFIG_BRIDGE_EBT_ARPREPLY=m
+CONFIG_BRIDGE_EBT_DNAT=m
+CONFIG_BRIDGE_EBT_MARK_T=m
+CONFIG_BRIDGE_EBT_REDIRECT=m
+CONFIG_BRIDGE_EBT_SNAT=m
+CONFIG_BRIDGE_EBT_LOG=m
+CONFIG_BRIDGE_EBT_ULOG=m
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+CONFIG_IP_DCCP=m
+CONFIG_INET_DCCP_DIAG=m
+CONFIG_IP_DCCP_ACKVEC=y
+
+#
+# DCCP CCIDs Configuration (EXPERIMENTAL)
+#
+CONFIG_IP_DCCP_CCID2=m
+CONFIG_IP_DCCP_CCID3=m
+CONFIG_IP_DCCP_TFRC_LIB=m
+
+#
+# DCCP Kernel Hacking
+#
+# CONFIG_IP_DCCP_DEBUG is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+CONFIG_IP_SCTP=m
+# CONFIG_SCTP_DBG_MSG is not set
+# CONFIG_SCTP_DBG_OBJCNT is not set
+# CONFIG_SCTP_HMAC_NONE is not set
+# CONFIG_SCTP_HMAC_SHA1 is not set
+CONFIG_SCTP_HMAC_MD5=y
+
+#
+# TIPC Configuration (EXPERIMENTAL)
+#
+CONFIG_TIPC=m
+# CONFIG_TIPC_ADVANCED is not set
+# CONFIG_TIPC_DEBUG is not set
+CONFIG_ATM=m
+CONFIG_ATM_CLIP=m
+# CONFIG_ATM_CLIP_NO_ICMP is not set
+CONFIG_ATM_LANE=m
+# CONFIG_ATM_MPOA is not set
+CONFIG_ATM_BR2684=m
+# CONFIG_ATM_BR2684_IPFILTER is not set
+CONFIG_BRIDGE=m
+CONFIG_VLAN_8021Q=m
+CONFIG_DECNET=m
+CONFIG_DECNET_ROUTER=y
+CONFIG_DECNET_ROUTE_FWMARK=y
+CONFIG_LLC=y
+# CONFIG_LLC2 is not set
+CONFIG_IPX=m
+# CONFIG_IPX_INTERN is not set
+CONFIG_ATALK=m
+CONFIG_DEV_APPLETALK=m
+# CONFIG_LTPC is not set
+# CONFIG_COPS is not set
+CONFIG_IPDDP=m
+CONFIG_IPDDP_ENCAP=y
+CONFIG_IPDDP_DECAP=y
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+CONFIG_WAN_ROUTER=m
+
+#
+# QoS and/or fair queueing
+#
+CONFIG_NET_SCHED=y
+# CONFIG_NET_SCH_CLK_JIFFIES is not set
+CONFIG_NET_SCH_CLK_GETTIMEOFDAY=y
+# CONFIG_NET_SCH_CLK_CPU is not set
+
+#
+# Queueing/Scheduling
+#
+CONFIG_NET_SCH_CBQ=m
+CONFIG_NET_SCH_HTB=m
+CONFIG_NET_SCH_HFSC=m
+CONFIG_NET_SCH_ATM=m
+CONFIG_NET_SCH_PRIO=m
+CONFIG_NET_SCH_RED=m
+CONFIG_NET_SCH_SFQ=m
+CONFIG_NET_SCH_TEQL=m
+CONFIG_NET_SCH_TBF=m
+CONFIG_NET_SCH_GRED=m
+CONFIG_NET_SCH_DSMARK=m
+CONFIG_NET_SCH_NETEM=m
+CONFIG_NET_SCH_INGRESS=m
+
+#
+# Classification
+#
+CONFIG_NET_CLS=y
+CONFIG_NET_CLS_BASIC=m
+CONFIG_NET_CLS_TCINDEX=m
+CONFIG_NET_CLS_ROUTE4=m
+CONFIG_NET_CLS_ROUTE=y
+CONFIG_NET_CLS_FW=m
+CONFIG_NET_CLS_U32=m
+CONFIG_CLS_U32_PERF=y
+CONFIG_CLS_U32_MARK=y
+CONFIG_NET_CLS_RSVP=m
+CONFIG_NET_CLS_RSVP6=m
+CONFIG_NET_EMATCH=y
+CONFIG_NET_EMATCH_STACK=32
+CONFIG_NET_EMATCH_CMP=m
+CONFIG_NET_EMATCH_NBYTE=m
+CONFIG_NET_EMATCH_U32=m
+CONFIG_NET_EMATCH_META=m
+CONFIG_NET_EMATCH_TEXT=m
+CONFIG_NET_CLS_ACT=y
+CONFIG_NET_ACT_POLICE=m
+CONFIG_NET_ACT_GACT=m
+CONFIG_GACT_PROB=y
+CONFIG_NET_ACT_MIRRED=m
+CONFIG_NET_ACT_IPT=m
+CONFIG_NET_ACT_PEDIT=m
+CONFIG_NET_ACT_SIMP=m
+CONFIG_NET_CLS_IND=y
+CONFIG_NET_ESTIMATOR=y
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_NET_TCPPROBE is not set
+# CONFIG_HAMRADIO is not set
+CONFIG_IRDA=m
+
+#
+# IrDA protocols
+#
+CONFIG_IRLAN=m
+CONFIG_IRNET=m
+CONFIG_IRCOMM=m
+# CONFIG_IRDA_ULTRA is not set
+
+#
+# IrDA options
+#
+CONFIG_IRDA_CACHE_LAST_LSAP=y
+CONFIG_IRDA_FAST_RR=y
+# CONFIG_IRDA_DEBUG is not set
+
+#
+# Infrared-port device drivers
+#
+
+#
+# SIR device drivers
+#
+CONFIG_IRTTY_SIR=m
+
+#
+# Dongle support
+#
+CONFIG_DONGLE=y
+CONFIG_ESI_DONGLE=m
+CONFIG_ACTISYS_DONGLE=m
+CONFIG_TEKRAM_DONGLE=m
+CONFIG_TOIM3232_DONGLE=m
+CONFIG_LITELINK_DONGLE=m
+CONFIG_MA600_DONGLE=m
+CONFIG_GIRBIL_DONGLE=m
+CONFIG_MCP2120_DONGLE=m
+CONFIG_OLD_BELKIN_DONGLE=m
+CONFIG_ACT200L_DONGLE=m
+
+#
+# Old SIR device drivers
+#
+
+#
+# Old Serial dongle support
+#
+
+#
+# FIR device drivers
+#
+CONFIG_USB_IRDA=m
+CONFIG_SIGMATEL_FIR=m
+CONFIG_NSC_FIR=m
+CONFIG_WINBOND_FIR=m
+CONFIG_TOSHIBA_FIR=m
+CONFIG_SMC_IRCC_FIR=m
+CONFIG_ALI_FIR=m
+CONFIG_VLSI_FIR=m
+CONFIG_VIA_FIR=m
+CONFIG_MCS_FIR=m
+CONFIG_BT=m
+CONFIG_BT_L2CAP=m
+CONFIG_BT_SCO=m
+CONFIG_BT_RFCOMM=m
+CONFIG_BT_RFCOMM_TTY=y
+CONFIG_BT_BNEP=m
+CONFIG_BT_BNEP_MC_FILTER=y
+CONFIG_BT_BNEP_PROTO_FILTER=y
+CONFIG_BT_CMTP=m
+CONFIG_BT_HIDP=m
+
+#
+# Bluetooth device drivers
+#
+CONFIG_BT_HCIUSB=m
+CONFIG_BT_HCIUSB_SCO=y
+CONFIG_BT_HCIUART=m
+CONFIG_BT_HCIUART_H4=y
+CONFIG_BT_HCIUART_BCSP=y
+CONFIG_BT_HCIBCM203X=m
+CONFIG_BT_HCIBPA10X=m
+CONFIG_BT_HCIBFUSB=m
+CONFIG_BT_HCIDTL1=m
+CONFIG_BT_HCIBT3C=m
+CONFIG_BT_HCIBLUECARD=m
+CONFIG_BT_HCIBTUART=m
+CONFIG_BT_HCIVHCI=m
+CONFIG_IEEE80211=m
+# CONFIG_IEEE80211_DEBUG is not set
+CONFIG_IEEE80211_CRYPT_WEP=m
+CONFIG_IEEE80211_CRYPT_CCMP=m
+CONFIG_IEEE80211_CRYPT_TKIP=m
+CONFIG_IEEE80211_SOFTMAC=m
+CONFIG_IEEE80211_SOFTMAC_DEBUG=y
+CONFIG_TUX=m
+
+#
+# TUX options
+#
+CONFIG_TUX_EXTCGI=y
+CONFIG_TUX_EXTENDED_LOG=y
+# CONFIG_TUX_DEBUG is not set
+CONFIG_WIRELESS_EXT=y
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_SYS_HYPERVISOR is not set
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+CONFIG_CONNECTOR=y
+CONFIG_PROC_EVENTS=y
+
+#
+# Memory Technology Devices (MTD)
+#
+CONFIG_MTD=m
+# CONFIG_MTD_DEBUG is not set
+CONFIG_MTD_CONCAT=m
+CONFIG_MTD_PARTITIONS=y
+CONFIG_MTD_REDBOOT_PARTS=m
+CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1
+# CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED is not set
+# CONFIG_MTD_REDBOOT_PARTS_READONLY is not set
+CONFIG_MTD_CMDLINE_PARTS=y
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=m
+CONFIG_MTD_BLOCK=m
+CONFIG_MTD_BLOCK_RO=m
+CONFIG_FTL=m
+CONFIG_NFTL=m
+CONFIG_NFTL_RW=y
+CONFIG_INFTL=m
+CONFIG_RFD_FTL=m
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=m
+CONFIG_MTD_JEDECPROBE=m
+CONFIG_MTD_GEN_PROBE=m
+# CONFIG_MTD_CFI_ADV_OPTIONS 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_CFI_INTELEXT=m
+CONFIG_MTD_CFI_AMDSTD=m
+CONFIG_MTD_CFI_STAA=m
+CONFIG_MTD_CFI_UTIL=m
+CONFIG_MTD_RAM=m
+CONFIG_MTD_ROM=m
+CONFIG_MTD_ABSENT=m
+# CONFIG_MTD_OBSOLETE_CHIPS is not set
+
+#
+# Mapping drivers for chip access
+#
+CONFIG_MTD_COMPLEX_MAPPINGS=y
+# CONFIG_MTD_PHYSMAP is not set
+# CONFIG_MTD_PNC2000 is not set
+CONFIG_MTD_SC520CDP=m
+CONFIG_MTD_NETSC520=m
+CONFIG_MTD_TS5500=m
+# CONFIG_MTD_SBC_GXX is not set
+# CONFIG_MTD_AMD76XROM is not set
+# CONFIG_MTD_ICHXROM is not set
+CONFIG_MTD_SCB2_FLASH=m
+# CONFIG_MTD_NETtel is not set
+# CONFIG_MTD_DILNETPC is not set
+# CONFIG_MTD_L440GX is not set
+CONFIG_MTD_PCI=m
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+CONFIG_MTD_PMC551=m
+# CONFIG_MTD_PMC551_BUGFIX is not set
+# CONFIG_MTD_PMC551_DEBUG is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+CONFIG_MTD_MTDRAM=m
+CONFIG_MTDRAM_TOTAL_SIZE=4096
+CONFIG_MTDRAM_ERASE_SIZE=128
+CONFIG_MTD_BLOCK2MTD=m
+
+#
+# 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=m
+# CONFIG_MTD_NAND_VERIFY_WRITE is not set
+CONFIG_MTD_NAND_ECC_SMC=y
+CONFIG_MTD_NAND_IDS=m
+CONFIG_MTD_NAND_DISKONCHIP=m
+# CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADVANCED is not set
+CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADDRESS=0
+# CONFIG_MTD_NAND_DISKONCHIP_BBTWRITE is not set
+CONFIG_MTD_NAND_CS553X=m
+CONFIG_MTD_NAND_NANDSIM=m
+
+#
+# OneNAND Flash Device Drivers
+#
+# CONFIG_MTD_ONENAND is not set
+
+#
+# Parallel port support
+#
+CONFIG_PARPORT=m
+CONFIG_PARPORT_PC=m
+CONFIG_PARPORT_SERIAL=m
+# CONFIG_PARPORT_PC_FIFO is not set
+# CONFIG_PARPORT_PC_SUPERIO is not set
+CONFIG_PARPORT_PC_PCMCIA=m
+CONFIG_PARPORT_NOT_PC=y
+# CONFIG_PARPORT_GSC is not set
+# CONFIG_PARPORT_AX88796 is not set
+CONFIG_PARPORT_1284=y
+
+#
+# Plug and Play support
+#
+CONFIG_PNP=y
+# CONFIG_PNP_DEBUG is not set
+
+#
+# Protocols
+#
+CONFIG_ISAPNP=y
+# CONFIG_PNPBIOS is not set
+CONFIG_PNPACPI=y
+
+#
+# Block devices
+#
+CONFIG_BLK_DEV_FD=m
+# CONFIG_BLK_DEV_XD is not set
+CONFIG_PARIDE=m
+CONFIG_PARIDE_PARPORT=m
+
+#
+# Parallel IDE high-level drivers
+#
+CONFIG_PARIDE_PD=m
+CONFIG_PARIDE_PCD=m
+CONFIG_PARIDE_PF=m
+CONFIG_PARIDE_PT=m
+CONFIG_PARIDE_PG=m
+
+#
+# Parallel IDE protocol modules
+#
+CONFIG_PARIDE_ATEN=m
+CONFIG_PARIDE_BPCK=m
+CONFIG_PARIDE_BPCK6=m
+CONFIG_PARIDE_COMM=m
+CONFIG_PARIDE_DSTR=m
+CONFIG_PARIDE_FIT2=m
+CONFIG_PARIDE_FIT3=m
+CONFIG_PARIDE_EPAT=m
+CONFIG_PARIDE_EPATC8=y
+CONFIG_PARIDE_EPIA=m
+CONFIG_PARIDE_FRIQ=m
+CONFIG_PARIDE_FRPW=m
+CONFIG_PARIDE_KBIC=m
+CONFIG_PARIDE_KTTI=m
+CONFIG_PARIDE_ON20=m
+CONFIG_PARIDE_ON26=m
+CONFIG_BLK_CPQ_DA=m
+CONFIG_BLK_CPQ_CISS_DA=m
+CONFIG_CISS_SCSI_TAPE=y
+CONFIG_BLK_DEV_DAC960=m
+CONFIG_BLK_DEV_UMEM=m
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=m
+CONFIG_BLK_DEV_CRYPTOLOOP=m
+CONFIG_BLK_DEV_NBD=m
+CONFIG_BLK_DEV_SX8=m
+CONFIG_BLK_DEV_UB=m
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=16384
+CONFIG_BLK_DEV_RAM_BLOCKSIZE=4096
+CONFIG_BLK_DEV_INITRD=y
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+CONFIG_IDE=y
+CONFIG_BLK_DEV_IDE=y
+
+#
+# Please see Documentation/ide.txt for help/info on IDE drives
+#
+# CONFIG_BLK_DEV_IDE_SATA is not set
+# CONFIG_BLK_DEV_HD_IDE is not set
+CONFIG_BLK_DEV_IDEDISK=y
+CONFIG_IDEDISK_MULTI_MODE=y
+CONFIG_BLK_DEV_IDECS=m
+CONFIG_BLK_DEV_IDECD=m
+# CONFIG_BLK_DEV_IDETAPE is not set
+CONFIG_BLK_DEV_IDEFLOPPY=y
+CONFIG_BLK_DEV_IDESCSI=m
+CONFIG_IDE_TASK_IOCTL=y
+
+#
+# IDE chipset support/bugfixes
+#
+CONFIG_IDE_GENERIC=y
+CONFIG_BLK_DEV_CMD640=y
+CONFIG_BLK_DEV_CMD640_ENHANCED=y
+CONFIG_BLK_DEV_IDEPNP=y
+CONFIG_BLK_DEV_IDEPCI=y
+CONFIG_IDEPCI_SHARE_IRQ=y
+# CONFIG_BLK_DEV_OFFBOARD is not set
+CONFIG_BLK_DEV_GENERIC=y
+# CONFIG_BLK_DEV_OPTI621 is not set
+CONFIG_BLK_DEV_RZ1000=y
+CONFIG_BLK_DEV_IDEDMA_PCI=y
+# CONFIG_BLK_DEV_IDEDMA_FORCED is not set
+CONFIG_IDEDMA_PCI_AUTO=y
+# CONFIG_IDEDMA_ONLYDISK is not set
+CONFIG_BLK_DEV_AEC62XX=y
+CONFIG_BLK_DEV_ALI15X3=y
+# CONFIG_WDC_ALI15X3 is not set
+CONFIG_BLK_DEV_AMD74XX=y
+CONFIG_BLK_DEV_ATIIXP=y
+CONFIG_BLK_DEV_CMD64X=y
+CONFIG_BLK_DEV_TRIFLEX=y
+# CONFIG_BLK_DEV_CY82C693 is not set
+CONFIG_BLK_DEV_CS5520=y
+CONFIG_BLK_DEV_CS5530=y
+CONFIG_BLK_DEV_CS5535=y
+CONFIG_BLK_DEV_HPT34X=y
+# CONFIG_HPT34X_AUTODMA is not set
+CONFIG_BLK_DEV_HPT366=y
+# CONFIG_BLK_DEV_SC1200 is not set
+CONFIG_BLK_DEV_PIIX=y
+CONFIG_BLK_DEV_IT821X=y
+# CONFIG_BLK_DEV_NS87415 is not set
+CONFIG_BLK_DEV_PDC202XX_OLD=y
+# CONFIG_PDC202XX_BURST is not set
+CONFIG_BLK_DEV_PDC202XX_NEW=y
+CONFIG_BLK_DEV_SVWKS=y
+CONFIG_BLK_DEV_SIIMAGE=y
+CONFIG_BLK_DEV_SIS5513=y
+# CONFIG_BLK_DEV_SLC90E66 is not set
+# CONFIG_BLK_DEV_TRM290 is not set
+CONFIG_BLK_DEV_VIA82CXXX=y
+# CONFIG_IDE_ARM is not set
+# CONFIG_IDE_CHIPSETS is not set
+CONFIG_BLK_DEV_IDEDMA=y
+# CONFIG_IDEDMA_IVB is not set
+CONFIG_IDEDMA_AUTO=y
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# SCSI device support
+#
+CONFIG_RAID_ATTRS=m
+CONFIG_SCSI=m
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=m
+CONFIG_CHR_DEV_ST=m
+CONFIG_CHR_DEV_OSST=m
+CONFIG_BLK_DEV_SR=m
+CONFIG_BLK_DEV_SR_VENDOR=y
+CONFIG_CHR_DEV_SG=m
+CONFIG_CHR_DEV_SCH=m
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+CONFIG_SCSI_MULTI_LUN=y
+CONFIG_SCSI_CONSTANTS=y
+CONFIG_SCSI_LOGGING=y
+
+#
+# SCSI Transport Attributes
+#
+CONFIG_SCSI_SPI_ATTRS=m
+CONFIG_SCSI_FC_ATTRS=m
+CONFIG_SCSI_ISCSI_ATTRS=m
+CONFIG_SCSI_SAS_ATTRS=m
+
+#
+# SCSI low-level drivers
+#
+CONFIG_ISCSI_TCP=m
+CONFIG_BLK_DEV_3W_XXXX_RAID=m
+CONFIG_SCSI_3W_9XXX=m
+# CONFIG_SCSI_7000FASST is not set
+CONFIG_SCSI_ACARD=m
+CONFIG_SCSI_AHA152X=m
+CONFIG_SCSI_AHA1542=m
+CONFIG_SCSI_AACRAID=m
+CONFIG_SCSI_AIC7XXX=m
+CONFIG_AIC7XXX_CMDS_PER_DEVICE=4
+CONFIG_AIC7XXX_RESET_DELAY_MS=15000
+# CONFIG_AIC7XXX_DEBUG_ENABLE is not set
+CONFIG_AIC7XXX_DEBUG_MASK=0
+# CONFIG_AIC7XXX_REG_PRETTY_PRINT is not set
+CONFIG_SCSI_AIC7XXX_OLD=m
+CONFIG_SCSI_AIC79XX=m
+CONFIG_AIC79XX_CMDS_PER_DEVICE=4
+CONFIG_AIC79XX_RESET_DELAY_MS=15000
+# CONFIG_AIC79XX_ENABLE_RD_STRM is not set
+# CONFIG_AIC79XX_DEBUG_ENABLE is not set
+CONFIG_AIC79XX_DEBUG_MASK=0
+# CONFIG_AIC79XX_REG_PRETTY_PRINT is not set
+# CONFIG_SCSI_DPT_I2O is not set
+CONFIG_SCSI_ADVANSYS=m
+# CONFIG_SCSI_IN2000 is not set
+CONFIG_MEGARAID_NEWGEN=y
+CONFIG_MEGARAID_MM=m
+CONFIG_MEGARAID_MAILBOX=m
+CONFIG_MEGARAID_LEGACY=m
+CONFIG_MEGARAID_SAS=m
+CONFIG_SCSI_SATA=m
+CONFIG_SCSI_SATA_AHCI=m
+CONFIG_SCSI_SATA_SVW=m
+CONFIG_SCSI_ATA_PIIX=m
+CONFIG_SCSI_SATA_MV=m
+CONFIG_SCSI_SATA_NV=m
+CONFIG_SCSI_PDC_ADMA=m
+CONFIG_SCSI_HPTIOP=m
+CONFIG_SCSI_SATA_QSTOR=m
+CONFIG_SCSI_SATA_PROMISE=m
+CONFIG_SCSI_SATA_SX4=m
+CONFIG_SCSI_SATA_SIL=m
+CONFIG_SCSI_SATA_SIL24=m
+CONFIG_SCSI_SATA_SIS=m
+CONFIG_SCSI_SATA_ULI=m
+CONFIG_SCSI_SATA_VIA=m
+CONFIG_SCSI_SATA_VITESSE=m
+CONFIG_SCSI_SATA_INTEL_COMBINED=y
+CONFIG_SCSI_BUSLOGIC=m
+# CONFIG_SCSI_OMIT_FLASHPOINT is not set
+# CONFIG_SCSI_DMX3191D is not set
+# CONFIG_SCSI_DTC3280 is not set
+# CONFIG_SCSI_EATA is not set
+CONFIG_SCSI_FUTURE_DOMAIN=m
+CONFIG_SCSI_GDTH=m
+# CONFIG_SCSI_GENERIC_NCR5380 is not set
+# CONFIG_SCSI_GENERIC_NCR5380_MMIO is not set
+CONFIG_SCSI_IPS=m
+CONFIG_SCSI_INITIO=m
+CONFIG_SCSI_INIA100=m
+CONFIG_SCSI_PPA=m
+CONFIG_SCSI_IMM=m
+# CONFIG_SCSI_IZIP_EPP16 is not set
+# CONFIG_SCSI_IZIP_SLOW_CTR is not set
+# CONFIG_SCSI_NCR53C406A is not set
+CONFIG_SCSI_SYM53C8XX_2=m
+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=m
+CONFIG_SCSI_QLA_FC=m
+CONFIG_SCSI_LPFC=m
+# CONFIG_SCSI_SYM53C416 is not set
+CONFIG_SCSI_DC395x=m
+CONFIG_SCSI_DC390T=m
+# CONFIG_SCSI_T128 is not set
+# CONFIG_SCSI_U14_34F is not set
+# CONFIG_SCSI_ULTRASTOR is not set
+# CONFIG_SCSI_NSP32 is not set
+# CONFIG_SCSI_DEBUG is not set
+
+#
+# PCMCIA SCSI adapter support
+#
+CONFIG_PCMCIA_AHA152X=m
+CONFIG_PCMCIA_FDOMAIN=m
+CONFIG_PCMCIA_NINJA_SCSI=m
+CONFIG_PCMCIA_QLOGIC=m
+CONFIG_PCMCIA_SYM53C500=m
+
+#
+# Old CD-ROM drivers (not SCSI, not IDE)
+#
+# CONFIG_CD_NO_IDESCSI is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+CONFIG_MD=y
+CONFIG_BLK_DEV_MD=y
+CONFIG_MD_LINEAR=m
+CONFIG_MD_RAID0=m
+CONFIG_MD_RAID1=m
+CONFIG_MD_RAID10=m
+CONFIG_MD_RAID456=m
+CONFIG_MD_RAID5_RESHAPE=y
+CONFIG_MD_MULTIPATH=m
+CONFIG_MD_FAULTY=m
+CONFIG_BLK_DEV_DM=m
+CONFIG_DM_CRYPT=m
+CONFIG_DM_SNAPSHOT=m
+CONFIG_DM_MIRROR=m
+CONFIG_DM_ZERO=m
+CONFIG_DM_MULTIPATH=m
+CONFIG_DM_MULTIPATH_EMC=m
+
+#
+# Fusion MPT device support
+#
+CONFIG_FUSION=y
+CONFIG_FUSION_SPI=m
+CONFIG_FUSION_FC=m
+CONFIG_FUSION_SAS=m
+CONFIG_FUSION_MAX_SGE=40
+CONFIG_FUSION_CTL=m
+CONFIG_FUSION_LAN=m
+
+#
+# IEEE 1394 (FireWire) support
+#
+CONFIG_IEEE1394=m
+
+#
+# Subsystem Options
+#
+# CONFIG_IEEE1394_VERBOSEDEBUG is not set
+CONFIG_IEEE1394_OUI_DB=y
+CONFIG_IEEE1394_EXTRA_CONFIG_ROMS=y
+CONFIG_IEEE1394_CONFIG_ROM_IP1394=y
+# CONFIG_IEEE1394_EXPORT_FULL_API is not set
+
+#
+# Device Drivers
+#
+CONFIG_IEEE1394_PCILYNX=m
+CONFIG_IEEE1394_OHCI1394=m
+
+#
+# Protocol Drivers
+#
+CONFIG_IEEE1394_VIDEO1394=m
+CONFIG_IEEE1394_SBP2=m
+# CONFIG_IEEE1394_SBP2_PHYS_DMA is not set
+CONFIG_IEEE1394_ETH1394=m
+CONFIG_IEEE1394_DV1394=m
+CONFIG_IEEE1394_RAWIO=m
+
+#
+# I2O device support
+#
+CONFIG_I2O=m
+# CONFIG_I2O_LCT_NOTIFY_ON_CHANGES is not set
+CONFIG_I2O_EXT_ADAPTEC=y
+CONFIG_I2O_CONFIG=m
+CONFIG_I2O_CONFIG_OLD_IOCTL=y
+CONFIG_I2O_BUS=m
+CONFIG_I2O_BLOCK=m
+CONFIG_I2O_SCSI=m
+CONFIG_I2O_PROC=m
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+CONFIG_IFB=m
+CONFIG_DUMMY=m
+CONFIG_BONDING=m
+CONFIG_EQUALIZER=m
+CONFIG_TUN=m
+CONFIG_NET_SB1000=m
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+
+#
+# PHY device support
+#
+CONFIG_PHYLIB=m
+
+#
+# MII PHY device drivers
+#
+CONFIG_MARVELL_PHY=m
+CONFIG_DAVICOM_PHY=m
+CONFIG_QSEMI_PHY=m
+CONFIG_LXT_PHY=m
+CONFIG_CICADA_PHY=m
+CONFIG_VITESSE_PHY=m
+CONFIG_SMSC_PHY=m
+CONFIG_FIXED_PHY=m
+CONFIG_FIXED_MII_10_FDX=y
+CONFIG_FIXED_MII_100_FDX=y
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=m
+CONFIG_HAPPYMEAL=m
+CONFIG_SUNGEM=m
+CONFIG_CASSINI=m
+CONFIG_NET_VENDOR_3COM=y
+# CONFIG_EL1 is not set
+# CONFIG_EL2 is not set
+# CONFIG_ELPLUS is not set
+# CONFIG_EL16 is not set
+CONFIG_EL3=m
+# CONFIG_3C515 is not set
+CONFIG_VORTEX=m
+CONFIG_TYPHOON=m
+# CONFIG_LANCE is not set
+CONFIG_NET_VENDOR_SMC=y
+# CONFIG_WD80x3 is not set
+CONFIG_ULTRA=m
+# CONFIG_SMC9194 is not set
+# CONFIG_NET_VENDOR_RACAL is not set
+
+#
+# Tulip family network device support
+#
+CONFIG_NET_TULIP=y
+CONFIG_DE2104X=m
+CONFIG_TULIP=m
+# CONFIG_TULIP_MWI is not set
+CONFIG_TULIP_MMIO=y
+# CONFIG_TULIP_NAPI is not set
+CONFIG_DE4X5=m
+CONFIG_WINBOND_840=m
+CONFIG_DM9102=m
+CONFIG_ULI526X=m
+CONFIG_PCMCIA_XIRCOM=m
+# CONFIG_AT1700 is not set
+# CONFIG_DEPCA is not set
+# CONFIG_HP100 is not set
+CONFIG_NET_ISA=y
+# CONFIG_E2100 is not set
+CONFIG_EWRK3=m
+# CONFIG_EEXPRESS is not set
+# CONFIG_EEXPRESS_PRO is not set
+# CONFIG_HPLAN_PLUS is not set
+# CONFIG_HPLAN is not set
+# CONFIG_LP486E is not set
+# CONFIG_ETH16I is not set
+CONFIG_NE2000=m
+# CONFIG_ZNET is not set
+# CONFIG_SEEQ8005 is not set
+CONFIG_NET_PCI=y
+CONFIG_PCNET32=m
+CONFIG_AMD8111_ETH=m
+CONFIG_AMD8111E_NAPI=y
+CONFIG_ADAPTEC_STARFIRE=m
+CONFIG_ADAPTEC_STARFIRE_NAPI=y
+# CONFIG_AC3200 is not set
+# CONFIG_APRICOT is not set
+CONFIG_B44=m
+CONFIG_FORCEDETH=m
+# CONFIG_CS89x0 is not set
+# CONFIG_DGRS is not set
+# CONFIG_EEPRO100 is not set
+CONFIG_E100=m
+CONFIG_FEALNX=m
+CONFIG_NATSEMI=m
+CONFIG_NE2K_PCI=m
+CONFIG_8139CP=m
+CONFIG_8139TOO=m
+# CONFIG_8139TOO_PIO is not set
+# CONFIG_8139TOO_TUNE_TWISTER is not set
+CONFIG_8139TOO_8129=y
+# CONFIG_8139_OLD_RX_RESET is not set
+CONFIG_SIS900=m
+CONFIG_EPIC100=m
+CONFIG_SUNDANCE=m
+# CONFIG_SUNDANCE_MMIO is not set
+CONFIG_TLAN=m
+CONFIG_VIA_RHINE=m
+CONFIG_VIA_RHINE_MMIO=y
+CONFIG_VIA_RHINE_NAPI=y
+CONFIG_NET_POCKET=y
+CONFIG_ATP=m
+CONFIG_DE600=m
+CONFIG_DE620=m
+
+#
+# Ethernet (1000 Mbit)
+#
+CONFIG_ACENIC=m
+# CONFIG_ACENIC_OMIT_TIGON_I is not set
+CONFIG_DL2K=m
+CONFIG_E1000=m
+CONFIG_E1000_NAPI=y
+# CONFIG_E1000_DISABLE_PACKET_SPLIT is not set
+CONFIG_NS83820=m
+CONFIG_HAMACHI=m
+CONFIG_YELLOWFIN=m
+CONFIG_R8169=m
+CONFIG_R8169_NAPI=y
+CONFIG_R8169_VLAN=y
+CONFIG_SIS190=m
+CONFIG_SKGE=m
+CONFIG_SKY2=m
+# CONFIG_SK98LIN is not set
+CONFIG_VIA_VELOCITY=m
+CONFIG_TIGON3=m
+CONFIG_BNX2=m
+
+#
+# Ethernet (10000 Mbit)
+#
+CONFIG_CHELSIO_T1=m
+CONFIG_IXGB=m
+CONFIG_IXGB_NAPI=y
+CONFIG_S2IO=m
+CONFIG_S2IO_NAPI=y
+CONFIG_MYRI10GE=m
+
+#
+# Token Ring devices
+#
+CONFIG_TR=y
+# CONFIG_IBMTR is not set
+CONFIG_IBMOL=m
+CONFIG_IBMLS=m
+CONFIG_3C359=m
+# CONFIG_TMS380TR is not set
+# CONFIG_SMCTR is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+CONFIG_NET_RADIO=y
+CONFIG_NET_WIRELESS_RTNETLINK=y
+
+#
+# Obsolete Wireless cards support (pre-802.11)
+#
+# CONFIG_STRIP is not set
+# CONFIG_ARLAN is not set
+# CONFIG_WAVELAN is not set
+CONFIG_PCMCIA_WAVELAN=m
+CONFIG_PCMCIA_NETWAVE=m
+
+#
+# Wireless 802.11 Frequency Hopping cards support
+#
+# CONFIG_PCMCIA_RAYCS is not set
+
+#
+# Wireless 802.11b ISA/PCI cards support
+#
+CONFIG_IPW2100=m
+CONFIG_IPW2100_MONITOR=y
+# CONFIG_IPW2100_DEBUG is not set
+CONFIG_IPW2200=m
+CONFIG_IPW2200_MONITOR=y
+CONFIG_IPW2200_RADIOTAP=y
+CONFIG_IPW2200_PROMISCUOUS=y
+CONFIG_IPW2200_QOS=y
+# CONFIG_IPW2200_DEBUG is not set
+CONFIG_AIRO=m
+CONFIG_HERMES=m
+CONFIG_PLX_HERMES=m
+CONFIG_TMD_HERMES=m
+CONFIG_NORTEL_HERMES=m
+CONFIG_PCI_HERMES=m
+CONFIG_ATMEL=m
+CONFIG_PCI_ATMEL=m
+
+#
+# Wireless 802.11b Pcmcia/Cardbus cards support
+#
+CONFIG_PCMCIA_HERMES=m
+CONFIG_PCMCIA_SPECTRUM=m
+CONFIG_AIRO_CS=m
+CONFIG_PCMCIA_ATMEL=m
+CONFIG_PCMCIA_WL3501=m
+
+#
+# Prism GT/Duette 802.11(a/b/g) PCI/Cardbus support
+#
+CONFIG_PRISM54=m
+CONFIG_USB_ZD1201=m
+CONFIG_HOSTAP=m
+CONFIG_HOSTAP_FIRMWARE=y
+CONFIG_HOSTAP_FIRMWARE_NVRAM=y
+CONFIG_HOSTAP_PLX=m
+CONFIG_HOSTAP_PCI=m
+CONFIG_HOSTAP_CS=m
+CONFIG_BCM43XX=m
+CONFIG_BCM43XX_DEBUG=y
+CONFIG_BCM43XX_DMA=y
+CONFIG_BCM43XX_PIO=y
+CONFIG_BCM43XX_DMA_AND_PIO_MODE=y
+# CONFIG_BCM43XX_DMA_MODE is not set
+# CONFIG_BCM43XX_PIO_MODE is not set
+CONFIG_ZD1211RW=m
+# CONFIG_ZD1211RW_DEBUG is not set
+CONFIG_NET_WIRELESS=y
+
+#
+# PCMCIA network device support
+#
+CONFIG_NET_PCMCIA=y
+CONFIG_PCMCIA_3C589=m
+CONFIG_PCMCIA_3C574=m
+CONFIG_PCMCIA_FMVJ18X=m
+CONFIG_PCMCIA_PCNET=m
+CONFIG_PCMCIA_NMCLAN=m
+CONFIG_PCMCIA_SMC91C92=m
+CONFIG_PCMCIA_XIRC2PS=m
+CONFIG_PCMCIA_AXNET=m
+CONFIG_PCMCIA_IBMTR=m
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+
+#
+# ATM drivers
+#
+# CONFIG_ATM_DUMMY is not set
+CONFIG_ATM_TCP=m
+CONFIG_ATM_LANAI=m
+CONFIG_ATM_ENI=m
+# CONFIG_ATM_ENI_DEBUG is not set
+# CONFIG_ATM_ENI_TUNE_BURST is not set
+CONFIG_ATM_FIRESTREAM=m
+# CONFIG_ATM_ZATM is not set
+CONFIG_ATM_NICSTAR=m
+# CONFIG_ATM_NICSTAR_USE_SUNI is not set
+# CONFIG_ATM_NICSTAR_USE_IDT77105 is not set
+CONFIG_ATM_IDT77252=m
+# CONFIG_ATM_IDT77252_DEBUG is not set
+# CONFIG_ATM_IDT77252_RCV_ALL is not set
+CONFIG_ATM_IDT77252_USE_SUNI=y
+CONFIG_ATM_AMBASSADOR=m
+# CONFIG_ATM_AMBASSADOR_DEBUG is not set
+CONFIG_ATM_HORIZON=m
+# CONFIG_ATM_HORIZON_DEBUG is not set
+# CONFIG_ATM_IA is not set
+CONFIG_ATM_FORE200E_MAYBE=m
+# CONFIG_ATM_FORE200E_PCA is not set
+CONFIG_ATM_HE=m
+# CONFIG_ATM_HE_USE_SUNI is not set
+CONFIG_FDDI=y
+# CONFIG_DEFXX is not set
+CONFIG_SKFP=m
+# CONFIG_HIPPI is not set
+CONFIG_PLIP=m
+CONFIG_PPP=m
+CONFIG_PPP_MULTILINK=y
+CONFIG_PPP_FILTER=y
+CONFIG_PPP_ASYNC=m
+CONFIG_PPP_SYNC_TTY=m
+CONFIG_PPP_DEFLATE=m
+# CONFIG_PPP_BSDCOMP is not set
+CONFIG_PPP_MPPE=m
+CONFIG_PPPOE=m
+CONFIG_PPPOATM=m
+CONFIG_SLIP=m
+CONFIG_SLIP_COMPRESSED=y
+CONFIG_SLIP_SMART=y
+# CONFIG_SLIP_MODE_SLIP6 is not set
+CONFIG_NET_FC=y
+# CONFIG_SHAPER is not set
+CONFIG_NETCONSOLE=m
+CONFIG_NETPOLL=y
+# CONFIG_NETPOLL_RX is not set
+CONFIG_NETPOLL_TRAP=y
+CONFIG_NET_POLL_CONTROLLER=y
+
+#
+# ISDN subsystem
+#
+CONFIG_ISDN=m
+
+#
+# Old ISDN4Linux
+#
+CONFIG_ISDN_I4L=m
+CONFIG_ISDN_PPP=y
+CONFIG_ISDN_PPP_VJ=y
+CONFIG_ISDN_MPP=y
+CONFIG_IPPP_FILTER=y
+# CONFIG_ISDN_PPP_BSDCOMP is not set
+CONFIG_ISDN_AUDIO=y
+CONFIG_ISDN_TTY_FAX=y
+
+#
+# ISDN feature submodules
+#
+CONFIG_ISDN_DIVERSION=m
+
+#
+# ISDN4Linux hardware drivers
+#
+
+#
+# Passive cards
+#
+CONFIG_ISDN_DRV_HISAX=m
+
+#
+# D-channel protocol features
+#
+CONFIG_HISAX_EURO=y
+CONFIG_DE_AOC=y
+CONFIG_HISAX_NO_SENDCOMPLETE=y
+CONFIG_HISAX_NO_LLC=y
+CONFIG_HISAX_NO_KEYPAD=y
+CONFIG_HISAX_1TR6=y
+CONFIG_HISAX_NI1=y
+CONFIG_HISAX_MAX_CARDS=8
+
+#
+# HiSax supported cards
+#
+# CONFIG_HISAX_16_0 is not set
+CONFIG_HISAX_16_3=y
+CONFIG_HISAX_TELESPCI=y
+CONFIG_HISAX_S0BOX=y
+# CONFIG_HISAX_AVM_A1 is not set
+CONFIG_HISAX_FRITZPCI=y
+CONFIG_HISAX_AVM_A1_PCMCIA=y
+CONFIG_HISAX_ELSA=y
+# CONFIG_HISAX_IX1MICROR2 is not set
+CONFIG_HISAX_DIEHLDIVA=y
+# CONFIG_HISAX_ASUSCOM is not set
+# CONFIG_HISAX_TELEINT is not set
+# CONFIG_HISAX_HFCS is not set
+CONFIG_HISAX_SEDLBAUER=y
+# CONFIG_HISAX_SPORTSTER is not set
+# CONFIG_HISAX_MIC is not set
+CONFIG_HISAX_NETJET=y
+CONFIG_HISAX_NETJET_U=y
+CONFIG_HISAX_NICCY=y
+# CONFIG_HISAX_ISURF is not set
+# CONFIG_HISAX_HSTSAPHIR is not set
+CONFIG_HISAX_BKM_A4T=y
+CONFIG_HISAX_SCT_QUADRO=y
+CONFIG_HISAX_GAZEL=y
+CONFIG_HISAX_HFC_PCI=y
+CONFIG_HISAX_W6692=y
+CONFIG_HISAX_HFC_SX=y
+CONFIG_HISAX_ENTERNOW_PCI=y
+# CONFIG_HISAX_DEBUG is not set
+
+#
+# HiSax PCMCIA card service modules
+#
+CONFIG_HISAX_SEDLBAUER_CS=m
+CONFIG_HISAX_ELSA_CS=m
+CONFIG_HISAX_AVM_A1_CS=m
+CONFIG_HISAX_TELES_CS=m
+
+#
+# HiSax sub driver modules
+#
+CONFIG_HISAX_ST5481=m
+# CONFIG_HISAX_HFCUSB is not set
+CONFIG_HISAX_HFC4S8S=m
+CONFIG_HISAX_FRITZ_PCIPNP=m
+CONFIG_HISAX_HDLC=y
+
+#
+# Active cards
+#
+# CONFIG_ISDN_DRV_ICN is not set
+# CONFIG_ISDN_DRV_PCBIT is not set
+# CONFIG_ISDN_DRV_SC is not set
+# CONFIG_ISDN_DRV_ACT2000 is not set
+
+#
+# Siemens Gigaset
+#
+CONFIG_ISDN_DRV_GIGASET=m
+CONFIG_GIGASET_BASE=m
+CONFIG_GIGASET_M105=m
+# CONFIG_GIGASET_DEBUG is not set
+# CONFIG_GIGASET_UNDOCREQ is not set
+
+#
+# CAPI subsystem
+#
+CONFIG_ISDN_CAPI=m
+CONFIG_ISDN_DRV_AVMB1_VERBOSE_REASON=y
+CONFIG_ISDN_CAPI_MIDDLEWARE=y
+CONFIG_ISDN_CAPI_CAPI20=m
+CONFIG_ISDN_CAPI_CAPIFS_BOOL=y
+CONFIG_ISDN_CAPI_CAPIFS=m
+CONFIG_ISDN_CAPI_CAPIDRV=m
+
+#
+# CAPI hardware drivers
+#
+
+#
+# Active AVM cards
+#
+CONFIG_CAPI_AVM=y
+# CONFIG_ISDN_DRV_AVMB1_B1ISA is not set
+CONFIG_ISDN_DRV_AVMB1_B1PCI=m
+CONFIG_ISDN_DRV_AVMB1_B1PCIV4=y
+# CONFIG_ISDN_DRV_AVMB1_T1ISA is not set
+CONFIG_ISDN_DRV_AVMB1_B1PCMCIA=m
+CONFIG_ISDN_DRV_AVMB1_AVM_CS=m
+CONFIG_ISDN_DRV_AVMB1_T1PCI=m
+CONFIG_ISDN_DRV_AVMB1_C4=m
+
+#
+# Active Eicon DIVA Server cards
+#
+CONFIG_CAPI_EICON=y
+CONFIG_ISDN_DIVAS=m
+CONFIG_ISDN_DIVAS_BRIPCI=y
+CONFIG_ISDN_DIVAS_PRIPCI=y
+CONFIG_ISDN_DIVAS_DIVACAPI=m
+CONFIG_ISDN_DIVAS_USERIDI=m
+CONFIG_ISDN_DIVAS_MAINT=m
+
+#
+# Telephony Support
+#
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+
+#
+# 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=m
+# CONFIG_INPUT_TSDEV is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+CONFIG_KEYBOARD_ATKBD=y
+# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_KEYBOARD_LKKBD is not set
+# CONFIG_KEYBOARD_XTKBD is not set
+# CONFIG_KEYBOARD_NEWTON is not set
+CONFIG_INPUT_MOUSE=y
+CONFIG_MOUSE_PS2=y
+CONFIG_MOUSE_SERIAL=m
+# CONFIG_MOUSE_INPORT is not set
+# CONFIG_MOUSE_LOGIBM is not set
+# CONFIG_MOUSE_PC110PAD is not set
+CONFIG_MOUSE_VSXXXAA=m
+CONFIG_INPUT_JOYSTICK=y
+CONFIG_JOYSTICK_ANALOG=m
+CONFIG_JOYSTICK_A3D=m
+CONFIG_JOYSTICK_ADI=m
+CONFIG_JOYSTICK_COBRA=m
+CONFIG_JOYSTICK_GF2K=m
+CONFIG_JOYSTICK_GRIP=m
+CONFIG_JOYSTICK_GRIP_MP=m
+CONFIG_JOYSTICK_GUILLEMOT=m
+CONFIG_JOYSTICK_INTERACT=m
+CONFIG_JOYSTICK_SIDEWINDER=m
+CONFIG_JOYSTICK_TMDC=m
+CONFIG_JOYSTICK_IFORCE=m
+CONFIG_JOYSTICK_IFORCE_USB=y
+CONFIG_JOYSTICK_IFORCE_232=y
+CONFIG_JOYSTICK_WARRIOR=m
+CONFIG_JOYSTICK_MAGELLAN=m
+CONFIG_JOYSTICK_SPACEORB=m
+CONFIG_JOYSTICK_SPACEBALL=m
+CONFIG_JOYSTICK_STINGER=m
+CONFIG_JOYSTICK_TWIDJOY=m
+CONFIG_JOYSTICK_DB9=m
+CONFIG_JOYSTICK_GAMECON=m
+CONFIG_JOYSTICK_TURBOGRAFX=m
+CONFIG_JOYSTICK_JOYDUMP=m
+CONFIG_INPUT_TOUCHSCREEN=y
+CONFIG_TOUCHSCREEN_GUNZE=m
+CONFIG_TOUCHSCREEN_ELO=m
+CONFIG_TOUCHSCREEN_MTOUCH=m
+CONFIG_TOUCHSCREEN_MK712=m
+CONFIG_INPUT_MISC=y
+CONFIG_INPUT_PCSPKR=m
+CONFIG_INPUT_WISTRON_BTNS=m
+CONFIG_INPUT_UINPUT=m
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+CONFIG_SERIO_I8042=y
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_CT82C710 is not set
+# CONFIG_SERIO_PARKBD is not set
+# CONFIG_SERIO_PCIPS2 is not set
+CONFIG_SERIO_LIBPS2=y
+CONFIG_SERIO_RAW=m
+CONFIG_GAMEPORT=m
+CONFIG_GAMEPORT_NS558=m
+CONFIG_GAMEPORT_L4=m
+CONFIG_GAMEPORT_EMU10K1=m
+CONFIG_GAMEPORT_FM801=m
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+CONFIG_VT_HW_CONSOLE_BINDING=y
+CONFIG_SERIAL_NONSTANDARD=y
+# CONFIG_COMPUTONE is not set
+# CONFIG_ROCKETPORT is not set
+CONFIG_CYCLADES=m
+# CONFIG_CYZ_INTR is not set
+# CONFIG_DIGIEPCA is not set
+# CONFIG_ESPSERIAL is not set
+# CONFIG_MOXA_INTELLIO is not set
+# CONFIG_MOXA_SMARTIO is not set
+# CONFIG_ISI is not set
+CONFIG_SYNCLINK=m
+CONFIG_SYNCLINKMP=m
+CONFIG_SYNCLINK_GT=m
+CONFIG_N_HDLC=m
+# CONFIG_SPECIALIX is not set
+# CONFIG_SX is not set
+# CONFIG_RIO is not set
+# CONFIG_STALDRV is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_PCI=y
+CONFIG_SERIAL_8250_PNP=y
+CONFIG_SERIAL_8250_CS=m
+CONFIG_SERIAL_8250_NR_UARTS=32
+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=y
+CONFIG_SERIAL_8250_RSA=y
+# CONFIG_SERIAL_8250_FOURPORT is not set
+# CONFIG_SERIAL_8250_ACCENT is not set
+# CONFIG_SERIAL_8250_BOCA is not set
+# CONFIG_SERIAL_8250_HUB6 is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_SERIAL_JSM=m
+CONFIG_UNIX98_PTYS=y
+# CONFIG_LEGACY_PTYS is not set
+CONFIG_CRASH=m
+CONFIG_PRINTER=m
+CONFIG_LP_CONSOLE=y
+CONFIG_PPDEV=m
+CONFIG_TIPAR=m
+
+#
+# IPMI
+#
+# CONFIG_IPMI_HANDLER is not set
+
+#
+# Watchdog Cards
+#
+CONFIG_WATCHDOG=y
+# CONFIG_WATCHDOG_NOWAYOUT is not set
+
+#
+# Watchdog Device Drivers
+#
+CONFIG_SOFT_WATCHDOG=m
+# CONFIG_ACQUIRE_WDT is not set
+# CONFIG_ADVANTECH_WDT is not set
+CONFIG_ALIM1535_WDT=m
+CONFIG_ALIM7101_WDT=m
+# CONFIG_SC520_WDT is not set
+# CONFIG_EUROTECH_WDT is not set
+# CONFIG_IB700_WDT is not set
+CONFIG_IBMASR=m
+# CONFIG_WAFER_WDT is not set
+CONFIG_I6300ESB_WDT=m
+CONFIG_I8XX_TCO=m
+# CONFIG_SC1200_WDT is not set
+# CONFIG_60XX_WDT is not set
+# CONFIG_SBC8360_WDT is not set
+# CONFIG_CPU5_WDT is not set
+CONFIG_W83627HF_WDT=m
+CONFIG_W83877F_WDT=m
+CONFIG_W83977F_WDT=m
+CONFIG_MACHZ_WDT=m
+# CONFIG_SBC_EPX_C3_WATCHDOG is not set
+
+#
+# ISA-based Watchdog Cards
+#
+# CONFIG_PCWATCHDOG is not set
+# CONFIG_MIXCOMWD is not set
+# CONFIG_WDT is not set
+
+#
+# PCI-based Watchdog Cards
+#
+CONFIG_PCIPCWATCHDOG=m
+CONFIG_WDTPCI=m
+CONFIG_WDT_501_PCI=y
+
+#
+# USB-based Watchdog Cards
+#
+CONFIG_USBPCWATCHDOG=m
+CONFIG_HW_RANDOM=y
+CONFIG_HW_RANDOM_INTEL=m
+CONFIG_HW_RANDOM_AMD=m
+CONFIG_HW_RANDOM_GEODE=m
+CONFIG_HW_RANDOM_VIA=m
+CONFIG_NVRAM=y
+CONFIG_RTC=y
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+# CONFIG_SONYPI is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+CONFIG_AGP=y
+CONFIG_AGP_ALI=y
+# CONFIG_AGP_ATI is not set
+# CONFIG_AGP_AMD is not set
+# CONFIG_AGP_AMD64 is not set
+CONFIG_AGP_INTEL=y
+# CONFIG_AGP_NVIDIA is not set
+CONFIG_AGP_SIS=y
+# CONFIG_AGP_SWORKS is not set
+CONFIG_AGP_VIA=y
+CONFIG_AGP_EFFICEON=y
+CONFIG_DRM=m
+CONFIG_DRM_TDFX=m
+CONFIG_DRM_R128=m
+CONFIG_DRM_RADEON=m
+CONFIG_DRM_I810=m
+CONFIG_DRM_I830=m
+CONFIG_DRM_I915=m
+CONFIG_DRM_MGA=m
+CONFIG_DRM_SIS=m
+CONFIG_DRM_VIA=m
+CONFIG_DRM_SAVAGE=m
+
+#
+# PCMCIA character devices
+#
+# CONFIG_SYNCLINK_CS is not set
+CONFIG_CARDMAN_4000=m
+CONFIG_CARDMAN_4040=m
+CONFIG_MWAVE=m
+CONFIG_PC8736x_GPIO=m
+CONFIG_NSC_GPIO=m
+CONFIG_CS5535_GPIO=m
+# CONFIG_RAW_DRIVER is not set
+CONFIG_HPET=y
+# CONFIG_HPET_RTC_IRQ is not set
+# CONFIG_HPET_MMAP is not set
+CONFIG_HANGCHECK_TIMER=m
+
+#
+# TPM devices
+#
+CONFIG_TCG_TPM=m
+CONFIG_TCG_TIS=m
+CONFIG_TCG_NSC=m
+CONFIG_TCG_ATMEL=m
+CONFIG_TCG_INFINEON=m
+# CONFIG_TELCLOCK is not set
+
+#
+# I2C support
+#
+CONFIG_I2C=m
+CONFIG_I2C_CHARDEV=m
+
+#
+# I2C Algorithms
+#
+CONFIG_I2C_ALGOBIT=m
+CONFIG_I2C_ALGOPCF=m
+CONFIG_I2C_ALGOPCA=m
+
+#
+# I2C Hardware Bus support
+#
+CONFIG_I2C_ALI1535=m
+CONFIG_I2C_ALI1563=m
+CONFIG_I2C_ALI15X3=m
+CONFIG_I2C_AMD756=m
+CONFIG_I2C_AMD756_S4882=m
+CONFIG_I2C_AMD8111=m
+CONFIG_I2C_I801=m
+CONFIG_I2C_I810=m
+CONFIG_I2C_PIIX4=m
+CONFIG_I2C_ISA=m
+CONFIG_I2C_NFORCE2=m
+# CONFIG_I2C_OCORES is not set
+CONFIG_I2C_PARPORT=m
+CONFIG_I2C_PARPORT_LIGHT=m
+CONFIG_I2C_PROSAVAGE=m
+CONFIG_I2C_SAVAGE4=m
+# CONFIG_SCx200_ACB is not set
+CONFIG_I2C_SIS5595=m
+CONFIG_I2C_SIS630=m
+CONFIG_I2C_SIS96X=m
+CONFIG_I2C_STUB=m
+CONFIG_I2C_VIA=m
+CONFIG_I2C_VIAPRO=m
+CONFIG_I2C_VOODOO3=m
+CONFIG_I2C_PCA_ISA=m
+
+#
+# Miscellaneous I2C Chip support
+#
+CONFIG_SENSORS_DS1337=m
+CONFIG_SENSORS_DS1374=m
+CONFIG_SENSORS_EEPROM=m
+CONFIG_SENSORS_PCF8574=m
+CONFIG_SENSORS_PCA9539=m
+CONFIG_SENSORS_PCF8591=m
+CONFIG_SENSORS_MAX6875=m
+# 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 is not set
+# CONFIG_SPI_MASTER is not set
+
+#
+# Dallas's 1-wire bus
+#
+# CONFIG_W1 is not set
+
+#
+# Hardware Monitoring support
+#
+CONFIG_HWMON=m
+CONFIG_HWMON_VID=m
+CONFIG_SENSORS_ABITUGURU=m
+CONFIG_SENSORS_ADM1021=m
+CONFIG_SENSORS_ADM1025=m
+CONFIG_SENSORS_ADM1026=m
+CONFIG_SENSORS_ADM1031=m
+CONFIG_SENSORS_ADM9240=m
+CONFIG_SENSORS_ASB100=m
+CONFIG_SENSORS_ATXP1=m
+CONFIG_SENSORS_DS1621=m
+CONFIG_SENSORS_F71805F=m
+CONFIG_SENSORS_FSCHER=m
+CONFIG_SENSORS_FSCPOS=m
+CONFIG_SENSORS_GL518SM=m
+CONFIG_SENSORS_GL520SM=m
+CONFIG_SENSORS_IT87=m
+CONFIG_SENSORS_LM63=m
+CONFIG_SENSORS_LM75=m
+CONFIG_SENSORS_LM77=m
+CONFIG_SENSORS_LM78=m
+CONFIG_SENSORS_LM80=m
+CONFIG_SENSORS_LM83=m
+CONFIG_SENSORS_LM85=m
+CONFIG_SENSORS_LM87=m
+CONFIG_SENSORS_LM90=m
+CONFIG_SENSORS_LM92=m
+CONFIG_SENSORS_MAX1619=m
+CONFIG_SENSORS_PC87360=m
+CONFIG_SENSORS_SIS5595=m
+CONFIG_SENSORS_SMSC47M1=m
+CONFIG_SENSORS_SMSC47M192=m
+CONFIG_SENSORS_SMSC47B397=m
+CONFIG_SENSORS_VIA686A=m
+CONFIG_SENSORS_VT8231=m
+CONFIG_SENSORS_W83781D=m
+CONFIG_SENSORS_W83791D=m
+CONFIG_SENSORS_W83792D=m
+CONFIG_SENSORS_W83L785TS=m
+CONFIG_SENSORS_W83627HF=m
+CONFIG_SENSORS_W83627EHF=m
+# CONFIG_SENSORS_HDAPS is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
+
+#
+# Misc devices
+#
+# CONFIG_IBM_ASM is not set
+
+#
+# Multimedia devices
+#
+CONFIG_VIDEO_DEV=m
+CONFIG_VIDEO_V4L1=y
+CONFIG_VIDEO_V4L1_COMPAT=y
+CONFIG_VIDEO_V4L2=y
+
+#
+# Video Capture Adapters
+#
+
+#
+# Video Capture Adapters
+#
+# CONFIG_VIDEO_ADV_DEBUG is not set
+# CONFIG_VIDEO_VIVI is not set
+CONFIG_VIDEO_BT848=m
+CONFIG_VIDEO_BT848_DVB=y
+CONFIG_VIDEO_SAA6588=m
+# CONFIG_VIDEO_PMS is not set
+CONFIG_VIDEO_BWQCAM=m
+CONFIG_VIDEO_CQCAM=m
+CONFIG_VIDEO_W9966=m
+CONFIG_VIDEO_CPIA=m
+CONFIG_VIDEO_CPIA_PP=m
+CONFIG_VIDEO_CPIA_USB=m
+CONFIG_VIDEO_CPIA2=m
+CONFIG_VIDEO_SAA5246A=m
+CONFIG_VIDEO_SAA5249=m
+CONFIG_TUNER_3036=m
+CONFIG_VIDEO_STRADIS=m
+CONFIG_VIDEO_ZORAN=m
+CONFIG_VIDEO_ZORAN_BUZ=m
+CONFIG_VIDEO_ZORAN_DC10=m
+CONFIG_VIDEO_ZORAN_DC30=m
+CONFIG_VIDEO_ZORAN_LML33=m
+CONFIG_VIDEO_ZORAN_LML33R10=m
+CONFIG_VIDEO_ZORAN_AVS6EYES=m
+CONFIG_VIDEO_SAA7134=m
+CONFIG_VIDEO_SAA7134_ALSA=m
+CONFIG_VIDEO_SAA7134_DVB=m
+CONFIG_VIDEO_SAA7134_DVB_ALL_FRONTENDS=y
+CONFIG_VIDEO_MXB=m
+CONFIG_VIDEO_DPC=m
+CONFIG_VIDEO_HEXIUM_ORION=m
+CONFIG_VIDEO_HEXIUM_GEMINI=m
+CONFIG_VIDEO_CX88_VP3054=m
+CONFIG_VIDEO_CX88=m
+CONFIG_VIDEO_CX88_ALSA=m
+CONFIG_VIDEO_CX88_BLACKBIRD=m
+CONFIG_VIDEO_CX88_DVB=m
+CONFIG_VIDEO_CX88_DVB_ALL_FRONTENDS=y
+
+#
+# Encoders and Decoders
+#
+CONFIG_VIDEO_MSP3400=m
+CONFIG_VIDEO_CS53L32A=m
+CONFIG_VIDEO_TLV320AIC23B=m
+CONFIG_VIDEO_WM8775=m
+CONFIG_VIDEO_WM8739=m
+CONFIG_VIDEO_CX2341X=m
+CONFIG_VIDEO_CX25840=m
+CONFIG_VIDEO_SAA711X=m
+CONFIG_VIDEO_SAA7127=m
+CONFIG_VIDEO_UPD64031A=m
+CONFIG_VIDEO_UPD64083=m
+
+#
+# V4L USB devices
+#
+CONFIG_VIDEO_PVRUSB2=m
+CONFIG_VIDEO_PVRUSB2_24XXX=y
+CONFIG_VIDEO_PVRUSB2_SYSFS=y
+# CONFIG_VIDEO_PVRUSB2_DEBUGIFC is not set
+CONFIG_VIDEO_EM28XX=m
+CONFIG_VIDEO_USBVIDEO=m
+CONFIG_USB_VICAM=m
+CONFIG_USB_IBMCAM=m
+CONFIG_USB_KONICAWC=m
+CONFIG_USB_QUICKCAM_MESSENGER=m
+CONFIG_USB_ET61X251=m
+CONFIG_VIDEO_OVCAMCHIP=m
+CONFIG_USB_W9968CF=m
+CONFIG_USB_OV511=m
+CONFIG_USB_SE401=m
+CONFIG_USB_SN9C102=m
+CONFIG_USB_STV680=m
+CONFIG_USB_ZC0301=m
+CONFIG_USB_PWC=m
+# CONFIG_USB_PWC_DEBUG is not set
+
+#
+# Radio Adapters
+#
+# CONFIG_RADIO_CADET is not set
+# CONFIG_RADIO_RTRACK is not set
+# CONFIG_RADIO_RTRACK2 is not set
+# CONFIG_RADIO_AZTECH is not set
+# CONFIG_RADIO_GEMTEK is not set
+CONFIG_RADIO_GEMTEK_PCI=m
+CONFIG_RADIO_MAXIRADIO=m
+CONFIG_RADIO_MAESTRO=m
+# CONFIG_RADIO_SF16FMI is not set
+# CONFIG_RADIO_SF16FMR2 is not set
+# CONFIG_RADIO_TERRATEC is not set
+# CONFIG_RADIO_TRUST is not set
+# CONFIG_RADIO_TYPHOON is not set
+# CONFIG_RADIO_ZOLTRIX is not set
+CONFIG_USB_DSBR=m
+
+#
+# Digital Video Broadcasting Devices
+#
+CONFIG_DVB=y
+CONFIG_DVB_CORE=m
+
+#
+# Supported SAA7146 based PCI Adapters
+#
+CONFIG_DVB_AV7110=m
+CONFIG_DVB_AV7110_OSD=y
+CONFIG_DVB_BUDGET=m
+CONFIG_DVB_BUDGET_CI=m
+CONFIG_DVB_BUDGET_AV=m
+CONFIG_DVB_BUDGET_PATCH=m
+
+#
+# Supported USB Adapters
+#
+CONFIG_DVB_USB=m
+# CONFIG_DVB_USB_DEBUG is not set
+CONFIG_DVB_USB_A800=m
+CONFIG_DVB_USB_DIBUSB_MB=m
+# CONFIG_DVB_USB_DIBUSB_MB_FAULTY is not set
+CONFIG_DVB_USB_DIBUSB_MC=m
+CONFIG_DVB_USB_UMT_010=m
+CONFIG_DVB_USB_CXUSB=m
+CONFIG_DVB_USB_DIGITV=m
+CONFIG_DVB_USB_VP7045=m
+CONFIG_DVB_USB_VP702X=m
+CONFIG_DVB_USB_GP8PSK=m
+CONFIG_DVB_USB_NOVA_T_USB2=m
+CONFIG_DVB_USB_DTT200U=m
+CONFIG_DVB_TTUSB_BUDGET=m
+CONFIG_DVB_TTUSB_DEC=m
+CONFIG_DVB_CINERGYT2=m
+CONFIG_DVB_CINERGYT2_TUNING=y
+CONFIG_DVB_CINERGYT2_STREAM_URB_COUNT=32
+CONFIG_DVB_CINERGYT2_STREAM_BUF_SIZE=512
+CONFIG_DVB_CINERGYT2_QUERY_INTERVAL=250
+CONFIG_DVB_CINERGYT2_ENABLE_RC_INPUT_DEVICE=y
+CONFIG_DVB_CINERGYT2_RC_QUERY_INTERVAL=100
+
+#
+# Supported FlexCopII (B2C2) Adapters
+#
+CONFIG_DVB_B2C2_FLEXCOP=m
+CONFIG_DVB_B2C2_FLEXCOP_PCI=m
+CONFIG_DVB_B2C2_FLEXCOP_USB=m
+# CONFIG_DVB_B2C2_FLEXCOP_DEBUG is not set
+
+#
+# Supported BT878 Adapters
+#
+CONFIG_DVB_BT8XX=m
+
+#
+# Supported Pluto2 Adapters
+#
+CONFIG_DVB_PLUTO2=m
+
+#
+# Supported DVB Frontends
+#
+
+#
+# Customise DVB Frontends
+#
+
+#
+# DVB-S (satellite) frontends
+#
+CONFIG_DVB_STV0299=m
+CONFIG_DVB_CX24110=m
+CONFIG_DVB_CX24123=m
+CONFIG_DVB_TDA8083=m
+CONFIG_DVB_MT312=m
+CONFIG_DVB_VES1X93=m
+CONFIG_DVB_S5H1420=m
+
+#
+# DVB-T (terrestrial) frontends
+#
+CONFIG_DVB_SP8870=m
+CONFIG_DVB_SP887X=m
+CONFIG_DVB_CX22700=m
+CONFIG_DVB_CX22702=m
+CONFIG_DVB_L64781=m
+CONFIG_DVB_TDA1004X=m
+CONFIG_DVB_NXT6000=m
+CONFIG_DVB_MT352=m
+CONFIG_DVB_ZL10353=m
+CONFIG_DVB_DIB3000MB=m
+CONFIG_DVB_DIB3000MC=m
+
+#
+# DVB-C (cable) frontends
+#
+CONFIG_DVB_VES1820=m
+CONFIG_DVB_TDA10021=m
+CONFIG_DVB_STV0297=m
+
+#
+# ATSC (North American/Korean Terrestrial/Cable DTV) frontends
+#
+CONFIG_DVB_NXT200X=m
+CONFIG_DVB_OR51211=m
+CONFIG_DVB_OR51132=m
+CONFIG_DVB_BCM3510=m
+CONFIG_DVB_LGDT330X=m
+
+#
+# Miscellaneous devices
+#
+CONFIG_DVB_PLL=m
+CONFIG_DVB_LNBP21=m
+CONFIG_DVB_ISL6421=m
+CONFIG_VIDEO_SAA7146=m
+CONFIG_VIDEO_SAA7146_VV=m
+CONFIG_VIDEO_VIDEOBUF=m
+CONFIG_VIDEO_TUNER=m
+CONFIG_VIDEO_BUF=m
+CONFIG_VIDEO_BUF_DVB=m
+CONFIG_VIDEO_BTCX=m
+CONFIG_VIDEO_IR=m
+CONFIG_VIDEO_TVEEPROM=m
+CONFIG_USB_DABUSB=m
+
+#
+# Graphics support
+#
+# CONFIG_FIRMWARE_EDID is not set
+CONFIG_FB=y
+CONFIG_FB_CFB_FILLRECT=y
+CONFIG_FB_CFB_COPYAREA=y
+CONFIG_FB_CFB_IMAGEBLIT=y
+# CONFIG_FB_MACMODES is not set
+# CONFIG_FB_BACKLIGHT is not set
+CONFIG_FB_MODE_HELPERS=y
+CONFIG_FB_TILEBLITTING=y
+CONFIG_FB_CIRRUS=m
+# CONFIG_FB_PM2 is not set
+# CONFIG_FB_CYBER2000 is not set
+# CONFIG_FB_ARC is not set
+# CONFIG_FB_ASILIANT is not set
+# CONFIG_FB_IMSTT is not set
+CONFIG_FB_VGA16=m
+CONFIG_FB_VESA=y
+# CONFIG_FB_IMAC is not set
+# CONFIG_FB_HGA is not set
+# CONFIG_FB_S1D13XXX is not set
+CONFIG_FB_NVIDIA=m
+CONFIG_FB_NVIDIA_I2C=y
+CONFIG_FB_RIVA=m
+# CONFIG_FB_RIVA_I2C is not set
+# CONFIG_FB_RIVA_DEBUG is not set
+CONFIG_FB_I810=m
+CONFIG_FB_I810_GTF=y
+CONFIG_FB_I810_I2C=y
+CONFIG_FB_INTEL=m
+# CONFIG_FB_INTEL_DEBUG is not set
+CONFIG_FB_MATROX=m
+CONFIG_FB_MATROX_MILLENIUM=y
+CONFIG_FB_MATROX_MYSTIQUE=y
+CONFIG_FB_MATROX_G=y
+CONFIG_FB_MATROX_I2C=m
+CONFIG_FB_MATROX_MAVEN=m
+CONFIG_FB_MATROX_MULTIHEAD=y
+CONFIG_FB_RADEON=m
+CONFIG_FB_RADEON_I2C=y
+# CONFIG_FB_RADEON_DEBUG is not set
+CONFIG_FB_ATY128=m
+CONFIG_FB_ATY=m
+CONFIG_FB_ATY_CT=y
+CONFIG_FB_ATY_GENERIC_LCD=y
+CONFIG_FB_ATY_GX=y
+CONFIG_FB_SAVAGE=m
+CONFIG_FB_SAVAGE_I2C=y
+CONFIG_FB_SAVAGE_ACCEL=y
+# CONFIG_FB_SIS is not set
+CONFIG_FB_NEOMAGIC=m
+CONFIG_FB_KYRO=m
+CONFIG_FB_3DFX=m
+CONFIG_FB_3DFX_ACCEL=y
+CONFIG_FB_VOODOO1=m
+CONFIG_FB_CYBLA=m
+CONFIG_FB_TRIDENT=m
+CONFIG_FB_TRIDENT_ACCEL=y
+# CONFIG_FB_GEODE is not set
+# CONFIG_FB_VIRTUAL is not set
+
+#
+# Console display driver support
+#
+CONFIG_VGA_CONSOLE=y
+CONFIG_VGACON_SOFT_SCROLLBACK=y
+CONFIG_VGACON_SOFT_SCROLLBACK_SIZE=64
+CONFIG_VIDEO_SELECT=y
+# CONFIG_MDA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y
+# CONFIG_FONTS is not set
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
+
+#
+# Logo configuration
+#
+CONFIG_LOGO=y
+# CONFIG_LOGO_LINUX_MONO is not set
+# CONFIG_LOGO_LINUX_VGA16 is not set
+CONFIG_LOGO_LINUX_CLUT224=y
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+CONFIG_BACKLIGHT_CLASS_DEVICE=m
+CONFIG_BACKLIGHT_DEVICE=y
+CONFIG_LCD_CLASS_DEVICE=m
+CONFIG_LCD_DEVICE=y
+
+#
+# Sound
+#
+CONFIG_SOUND=m
+
+#
+# Advanced Linux Sound Architecture
+#
+CONFIG_SND=m
+CONFIG_SND_TIMER=m
+CONFIG_SND_PCM=m
+CONFIG_SND_HWDEP=m
+CONFIG_SND_RAWMIDI=m
+CONFIG_SND_SEQUENCER=m
+CONFIG_SND_SEQ_DUMMY=m
+CONFIG_SND_OSSEMUL=y
+CONFIG_SND_MIXER_OSS=m
+CONFIG_SND_PCM_OSS=m
+CONFIG_SND_PCM_OSS_PLUGINS=y
+CONFIG_SND_SEQUENCER_OSS=y
+CONFIG_SND_RTCTIMER=m
+CONFIG_SND_SEQ_RTCTIMER_DEFAULT=y
+CONFIG_SND_DYNAMIC_MINORS=y
+# CONFIG_SND_SUPPORT_OLD_API is not set
+CONFIG_SND_VERBOSE_PROCFS=y
+# CONFIG_SND_VERBOSE_PRINTK is not set
+# CONFIG_SND_DEBUG is not set
+
+#
+# Generic devices
+#
+CONFIG_SND_MPU401_UART=m
+CONFIG_SND_OPL3_LIB=m
+CONFIG_SND_OPL4_LIB=m
+CONFIG_SND_VX_LIB=m
+CONFIG_SND_AC97_CODEC=m
+CONFIG_SND_AC97_BUS=m
+CONFIG_SND_DUMMY=m
+CONFIG_SND_VIRMIDI=m
+CONFIG_SND_MTPAV=m
+# CONFIG_SND_SERIAL_U16550 is not set
+CONFIG_SND_MPU401=m
+
+#
+# ISA devices
+#
+CONFIG_SND_CS4231_LIB=m
+CONFIG_SND_ADLIB=m
+# CONFIG_SND_AD1816A is not set
+# CONFIG_SND_AD1848 is not set
+# CONFIG_SND_ALS100 is not set
+# CONFIG_SND_AZT2320 is not set
+# CONFIG_SND_CMI8330 is not set
+# CONFIG_SND_CS4231 is not set
+# CONFIG_SND_CS4232 is not set
+CONFIG_SND_CS4236=m
+# CONFIG_SND_DT019X is not set
+# CONFIG_SND_ES968 is not set
+# CONFIG_SND_ES1688 is not set
+CONFIG_SND_ES18XX=m
+# CONFIG_SND_GUSCLASSIC is not set
+# CONFIG_SND_GUSEXTREME is not set
+# CONFIG_SND_GUSMAX is not set
+# CONFIG_SND_INTERWAVE is not set
+# CONFIG_SND_INTERWAVE_STB is not set
+CONFIG_SND_OPL3SA2=m
+# CONFIG_SND_OPTI92X_AD1848 is not set
+# CONFIG_SND_OPTI92X_CS4231 is not set
+# CONFIG_SND_OPTI93X is not set
+CONFIG_SND_MIRO=m
+# CONFIG_SND_SB8 is not set
+CONFIG_SND_SB16=m
+CONFIG_SND_SBAWE=m
+# CONFIG_SND_SB16_CSP is not set
+# CONFIG_SND_SGALAXY is not set
+# CONFIG_SND_SSCAPE is not set
+# CONFIG_SND_WAVEFRONT is not set
+
+#
+# PCI devices
+#
+CONFIG_SND_AD1889=m
+CONFIG_SND_ALS300=m
+CONFIG_SND_ALS4000=m
+CONFIG_SND_ALI5451=m
+CONFIG_SND_ATIIXP=m
+CONFIG_SND_ATIIXP_MODEM=m
+CONFIG_SND_AU8810=m
+CONFIG_SND_AU8820=m
+CONFIG_SND_AU8830=m
+CONFIG_SND_AZT3328=m
+CONFIG_SND_BT87X=m
+# CONFIG_SND_BT87X_OVERCLOCK is not set
+CONFIG_SND_CA0106=m
+CONFIG_SND_CMIPCI=m
+CONFIG_SND_CS4281=m
+CONFIG_SND_CS46XX=m
+CONFIG_SND_CS46XX_NEW_DSP=y
+CONFIG_SND_CS5535AUDIO=m
+CONFIG_SND_DARLA20=m
+CONFIG_SND_GINA20=m
+CONFIG_SND_LAYLA20=m
+CONFIG_SND_DARLA24=m
+CONFIG_SND_GINA24=m
+CONFIG_SND_LAYLA24=m
+CONFIG_SND_MONA=m
+CONFIG_SND_MIA=m
+CONFIG_SND_ECHO3G=m
+CONFIG_SND_INDIGO=m
+CONFIG_SND_INDIGOIO=m
+CONFIG_SND_INDIGODJ=m
+CONFIG_SND_EMU10K1=m
+CONFIG_SND_EMU10K1X=m
+CONFIG_SND_ENS1370=m
+CONFIG_SND_ENS1371=m
+CONFIG_SND_ES1938=m
+CONFIG_SND_ES1968=m
+CONFIG_SND_FM801=m
+CONFIG_SND_FM801_TEA575X_BOOL=y
+CONFIG_SND_FM801_TEA575X=m
+CONFIG_SND_HDA_INTEL=m
+CONFIG_SND_HDSP=m
+CONFIG_SND_HDSPM=m
+CONFIG_SND_ICE1712=m
+CONFIG_SND_ICE1724=m
+CONFIG_SND_INTEL8X0=m
+CONFIG_SND_INTEL8X0M=m
+CONFIG_SND_KORG1212=m
+CONFIG_SND_MAESTRO3=m
+CONFIG_SND_MIXART=m
+CONFIG_SND_NM256=m
+CONFIG_SND_PCXHR=m
+CONFIG_SND_RIPTIDE=m
+CONFIG_SND_RME32=m
+CONFIG_SND_RME96=m
+CONFIG_SND_RME9652=m
+CONFIG_SND_SONICVIBES=m
+CONFIG_SND_TRIDENT=m
+CONFIG_SND_VIA82XX=m
+CONFIG_SND_VIA82XX_MODEM=m
+CONFIG_SND_VX222=m
+CONFIG_SND_YMFPCI=m
+
+#
+# USB devices
+#
+CONFIG_SND_USB_AUDIO=m
+CONFIG_SND_USB_USX2Y=m
+
+#
+# PCMCIA devices
+#
+# CONFIG_SND_VXPOCKET is not set
+# CONFIG_SND_PDAUDIOCF is not set
+
+#
+# Open Sound System
+#
+# CONFIG_SOUND_PRIME is not set
+
+#
+# USB support
+#
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB_ARCH_HAS_EHCI=y
+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_SUSPEND is not set
+# CONFIG_USB_OTG is not set
+
+#
+# USB Host Controller Drivers
+#
+CONFIG_USB_EHCI_HCD=m
+CONFIG_USB_EHCI_SPLIT_ISO=y
+CONFIG_USB_EHCI_ROOT_HUB_TT=y
+CONFIG_USB_EHCI_TT_NEWSCHED=y
+CONFIG_USB_ISP116X_HCD=m
+CONFIG_USB_OHCI_HCD=m
+# CONFIG_USB_OHCI_BIG_ENDIAN is not set
+CONFIG_USB_OHCI_LITTLE_ENDIAN=y
+CONFIG_USB_UHCI_HCD=m
+CONFIG_USB_SL811_HCD=m
+CONFIG_USB_SL811_CS=m
+
+#
+# USB Device Class drivers
+#
+CONFIG_USB_ACM=m
+CONFIG_USB_PRINTER=m
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+#
+
+#
+# may also be needed; see USB_STORAGE Help for more information
+#
+CONFIG_USB_STORAGE=m
+# CONFIG_USB_STORAGE_DEBUG is not set
+CONFIG_USB_STORAGE_DATAFAB=y
+CONFIG_USB_STORAGE_FREECOM=y
+CONFIG_USB_STORAGE_ISD200=y
+CONFIG_USB_STORAGE_DPCM=y
+CONFIG_USB_STORAGE_USBAT=y
+CONFIG_USB_STORAGE_SDDR09=y
+CONFIG_USB_STORAGE_SDDR55=y
+CONFIG_USB_STORAGE_JUMPSHOT=y
+CONFIG_USB_STORAGE_ALAUDA=y
+CONFIG_USB_LIBUSUAL=y
+
+#
+# USB Input Devices
+#
+CONFIG_USB_HID=y
+CONFIG_USB_HIDINPUT=y
+CONFIG_USB_HIDINPUT_POWERBOOK=y
+CONFIG_HID_FF=y
+CONFIG_HID_PID=y
+CONFIG_LOGITECH_FF=y
+CONFIG_THRUSTMASTER_FF=y
+CONFIG_USB_HIDDEV=y
+CONFIG_USB_AIPTEK=m
+CONFIG_USB_WACOM=m
+CONFIG_USB_ACECAD=m
+CONFIG_USB_KBTAB=m
+CONFIG_USB_POWERMATE=m
+CONFIG_USB_TOUCHSCREEN=m
+CONFIG_USB_TOUCHSCREEN_EGALAX=y
+CONFIG_USB_TOUCHSCREEN_PANJIT=y
+CONFIG_USB_TOUCHSCREEN_3M=y
+CONFIG_USB_TOUCHSCREEN_ITM=y
+# CONFIG_USB_YEALINK is not set
+CONFIG_USB_XPAD=m
+CONFIG_USB_ATI_REMOTE=m
+CONFIG_USB_ATI_REMOTE2=m
+CONFIG_USB_KEYSPAN_REMOTE=m
+CONFIG_USB_APPLETOUCH=m
+
+#
+# USB Imaging devices
+#
+CONFIG_USB_MDC800=m
+CONFIG_USB_MICROTEK=m
+
+#
+# USB Network Adapters
+#
+CONFIG_USB_CATC=m
+CONFIG_USB_KAWETH=m
+CONFIG_USB_PEGASUS=m
+CONFIG_USB_RTL8150=m
+CONFIG_USB_USBNET=m
+CONFIG_USB_NET_AX8817X=m
+CONFIG_USB_NET_CDCETHER=m
+CONFIG_USB_NET_GL620A=m
+CONFIG_USB_NET_NET1080=m
+CONFIG_USB_NET_PLUSB=m
+CONFIG_USB_NET_RNDIS_HOST=m
+CONFIG_USB_NET_CDC_SUBSET=m
+CONFIG_USB_ALI_M5632=y
+CONFIG_USB_AN2720=y
+CONFIG_USB_BELKIN=y
+CONFIG_USB_ARMLINUX=y
+CONFIG_USB_EPSON2888=y
+CONFIG_USB_NET_ZAURUS=m
+CONFIG_USB_MON=y
+
+#
+# USB port drivers
+#
+CONFIG_USB_USS720=m
+
+#
+# USB Serial Converter support
+#
+CONFIG_USB_SERIAL=m
+CONFIG_USB_SERIAL_GENERIC=y
+CONFIG_USB_SERIAL_AIRPRIME=m
+CONFIG_USB_SERIAL_ARK3116=m
+CONFIG_USB_SERIAL_BELKIN=m
+CONFIG_USB_SERIAL_WHITEHEAT=m
+CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m
+CONFIG_USB_SERIAL_CP2101=m
+CONFIG_USB_SERIAL_CYPRESS_M8=m
+CONFIG_USB_SERIAL_EMPEG=m
+CONFIG_USB_SERIAL_FTDI_SIO=m
+CONFIG_USB_SERIAL_FUNSOFT=m
+CONFIG_USB_SERIAL_VISOR=m
+CONFIG_USB_SERIAL_IPAQ=m
+CONFIG_USB_SERIAL_IR=m
+CONFIG_USB_SERIAL_EDGEPORT=m
+CONFIG_USB_SERIAL_EDGEPORT_TI=m
+CONFIG_USB_SERIAL_GARMIN=m
+CONFIG_USB_SERIAL_IPW=m
+CONFIG_USB_SERIAL_KEYSPAN_PDA=m
+CONFIG_USB_SERIAL_KEYSPAN=m
+CONFIG_USB_SERIAL_KEYSPAN_MPR=y
+CONFIG_USB_SERIAL_KEYSPAN_USA28=y
+CONFIG_USB_SERIAL_KEYSPAN_USA28X=y
+CONFIG_USB_SERIAL_KEYSPAN_USA28XA=y
+CONFIG_USB_SERIAL_KEYSPAN_USA28XB=y
+CONFIG_USB_SERIAL_KEYSPAN_USA19=y
+CONFIG_USB_SERIAL_KEYSPAN_USA18X=y
+CONFIG_USB_SERIAL_KEYSPAN_USA19W=y
+CONFIG_USB_SERIAL_KEYSPAN_USA19QW=y
+CONFIG_USB_SERIAL_KEYSPAN_USA19QI=y
+CONFIG_USB_SERIAL_KEYSPAN_USA49W=y
+CONFIG_USB_SERIAL_KEYSPAN_USA49WLC=y
+CONFIG_USB_SERIAL_KLSI=m
+CONFIG_USB_SERIAL_KOBIL_SCT=m
+CONFIG_USB_SERIAL_MCT_U232=m
+CONFIG_USB_SERIAL_NAVMAN=m
+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=m
+CONFIG_USB_SERIAL_TI=m
+CONFIG_USB_SERIAL_CYBERJACK=m
+CONFIG_USB_SERIAL_XIRCOM=m
+CONFIG_USB_SERIAL_OPTION=m
+CONFIG_USB_SERIAL_OMNINET=m
+CONFIG_USB_EZUSB=y
+
+#
+# USB Miscellaneous drivers
+#
+CONFIG_USB_EMI62=m
+CONFIG_USB_EMI26=m
+CONFIG_USB_AUERSWALD=m
+CONFIG_USB_RIO500=m
+CONFIG_USB_LEGOTOWER=m
+CONFIG_USB_LCD=m
+CONFIG_USB_LED=m
+# CONFIG_USB_CYPRESS_CY7C63 is not set
+# CONFIG_USB_CYTHERM is not set
+CONFIG_USB_PHIDGETKIT=m
+CONFIG_USB_PHIDGETSERVO=m
+CONFIG_USB_IDMOUSE=m
+CONFIG_USB_APPLEDISPLAY=m
+CONFIG_USB_SISUSBVGA=m
+CONFIG_USB_SISUSBVGA_CON=y
+CONFIG_USB_LD=m
+CONFIG_USB_TEST=m
+
+#
+# USB DSL modem support
+#
+CONFIG_USB_ATM=m
+CONFIG_USB_SPEEDTOUCH=m
+CONFIG_USB_CXACRU=m
+CONFIG_USB_UEAGLEATM=m
+CONFIG_USB_XUSBATM=m
+
+#
+# USB Gadget Support
+#
+# CONFIG_USB_GADGET is not set
+
+#
+# MMC/SD Card support
+#
+CONFIG_MMC=m
+# CONFIG_MMC_DEBUG is not set
+CONFIG_MMC_BLOCK=m
+CONFIG_MMC_SDHCI=m
+CONFIG_MMC_WBSD=m
+
+#
+# LED devices
+#
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+
+#
+# LED drivers
+#
+
+#
+# LED Triggers
+#
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_LEDS_TRIGGER_TIMER=m
+CONFIG_LEDS_TRIGGER_IDE_DISK=y
+CONFIG_LEDS_TRIGGER_HEARTBEAT=m
+
+#
+# InfiniBand support
+#
+# CONFIG_INFINIBAND is not set
+
+#
+# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
+#
+CONFIG_EDAC=y
+
+#
+# Reporting subsystems
+#
+# CONFIG_EDAC_DEBUG is not set
+CONFIG_EDAC_MM_EDAC=m
+CONFIG_EDAC_AMD76X=m
+CONFIG_EDAC_E7XXX=m
+CONFIG_EDAC_E752X=m
+CONFIG_EDAC_I82875P=m
+CONFIG_EDAC_I82860=m
+CONFIG_EDAC_K8=m
+CONFIG_EDAC_R82600=m
+CONFIG_EDAC_POLL=y
+
+#
+# Real Time Clock
+#
+CONFIG_RTC_LIB=m
+CONFIG_RTC_CLASS=m
+
+#
+# RTC interfaces
+#
+CONFIG_RTC_INTF_SYSFS=m
+CONFIG_RTC_INTF_PROC=m
+CONFIG_RTC_INTF_DEV=m
+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
+
+#
+# RTC drivers
+#
+CONFIG_RTC_DRV_X1205=m
+CONFIG_RTC_DRV_DS1307=m
+CONFIG_RTC_DRV_DS1553=m
+CONFIG_RTC_DRV_ISL1208=m
+CONFIG_RTC_DRV_DS1672=m
+CONFIG_RTC_DRV_DS1742=m
+CONFIG_RTC_DRV_PCF8563=m
+CONFIG_RTC_DRV_PCF8583=m
+CONFIG_RTC_DRV_RS5C372=m
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_TEST is not set
+CONFIG_RTC_DRV_V3020=m
+
+#
+# DMA Engine support
+#
+CONFIG_DMA_ENGINE=y
+
+#
+# DMA Clients
+#
+CONFIG_NET_DMA=y
+
+#
+# DMA Devices
+#
+CONFIG_INTEL_IOATDMA=m
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+CONFIG_EXT2_FS_POSIX_ACL=y
+CONFIG_EXT2_FS_SECURITY=y
+CONFIG_EXT2_FS_XIP=y
+CONFIG_FS_XIP=y
+CONFIG_EXT3_FS=m
+CONFIG_EXT3_FS_XATTR=y
+CONFIG_EXT3_FS_POSIX_ACL=y
+CONFIG_EXT3_FS_SECURITY=y
+CONFIG_JBD=m
+# CONFIG_JBD_DEBUG is not set
+CONFIG_FS_MBCACHE=y
+CONFIG_REISERFS_FS=m
+# CONFIG_REISERFS_CHECK is not set
+CONFIG_REISERFS_PROC_INFO=y
+CONFIG_REISERFS_FS_XATTR=y
+CONFIG_REISERFS_FS_POSIX_ACL=y
+CONFIG_REISERFS_FS_SECURITY=y
+CONFIG_JFS_FS=m
+CONFIG_JFS_POSIX_ACL=y
+CONFIG_JFS_SECURITY=y
+# CONFIG_JFS_DEBUG is not set
+# CONFIG_JFS_STATISTICS is not set
+CONFIG_FS_POSIX_ACL=y
+CONFIG_XFS_FS=m
+CONFIG_XFS_QUOTA=y
+CONFIG_XFS_SECURITY=y
+CONFIG_XFS_POSIX_ACL=y
+# CONFIG_XFS_RT is not set
+CONFIG_OCFS2_FS=m
+# CONFIG_OCFS2_DEBUG_MASKLOG is not set
+CONFIG_MINIX_FS=m
+CONFIG_ROMFS_FS=m
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+CONFIG_QUOTA=y
+# CONFIG_QFMT_V1 is not set
+CONFIG_QFMT_V2=y
+CONFIG_QUOTACTL=y
+CONFIG_DNOTIFY=y
+CONFIG_AUTOFS_FS=m
+CONFIG_AUTOFS4_FS=m
+CONFIG_FUSE_FS=m
+
+#
+# Caches
+#
+CONFIG_FSCACHE=m
+
+#
+# CD-ROM/DVD Filesystems
+#
+CONFIG_ISO9660_FS=y
+CONFIG_JOLIET=y
+CONFIG_ZISOFS=y
+CONFIG_ZISOFS_FS=y
+CONFIG_UDF_FS=m
+CONFIG_UDF_NLS=y
+CONFIG_CACHEFILES=m
+CONFIG_CACHEFILES_DEBUG=y
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=m
+CONFIG_MSDOS_FS=m
+CONFIG_VFAT_FS=m
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="ascii"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+CONFIG_HUGETLBFS=y
+CONFIG_HUGETLB_PAGE=y
+CONFIG_RAMFS=y
+CONFIG_CONFIGFS_FS=m
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+CONFIG_AFFS_FS=m
+CONFIG_HFS_FS=m
+CONFIG_HFSPLUS_FS=m
+CONFIG_BEFS_FS=m
+# CONFIG_BEFS_DEBUG is not set
+CONFIG_BFS_FS=m
+CONFIG_EFS_FS=m
+# CONFIG_JFFS_FS is not set
+CONFIG_JFFS2_FS=m
+CONFIG_JFFS2_FS_DEBUG=0
+CONFIG_JFFS2_FS_WRITEBUFFER=y
+CONFIG_JFFS2_SUMMARY=y
+# 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=m
+CONFIG_SQUASHFS=m
+# CONFIG_SQUASHFS_EMBEDDED is not set
+CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3
+# CONFIG_SQUASHFS_VMALLOC is not set
+CONFIG_VXFS_FS=m
+# CONFIG_HPFS_FS is not set
+CONFIG_QNX4FS_FS=m
+CONFIG_SYSV_FS=m
+CONFIG_UFS_FS=m
+# CONFIG_UFS_FS_WRITE is not set
+# CONFIG_UFS_DEBUG is not set
+
+#
+# Network File Systems
+#
+CONFIG_NFS_FS=m
+CONFIG_NFS_V3=y
+CONFIG_NFS_V3_ACL=y
+CONFIG_NFS_V4=y
+CONFIG_NFS_FSCACHE=y
+CONFIG_NFS_DIRECTIO=y
+CONFIG_NFSD=m
+CONFIG_NFSD_V2_ACL=y
+CONFIG_NFSD_V3=y
+CONFIG_NFSD_V3_ACL=y
+CONFIG_NFSD_V4=y
+CONFIG_NFSD_TCP=y
+CONFIG_LOCKD=m
+CONFIG_LOCKD_V4=y
+CONFIG_EXPORTFS=m
+CONFIG_NFS_ACL_SUPPORT=m
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=m
+CONFIG_SUNRPC_GSS=m
+CONFIG_RPCSEC_GSS_KRB5=m
+CONFIG_RPCSEC_GSS_SPKM3=m
+# CONFIG_SMB_FS is not set
+CONFIG_CIFS=m
+# CONFIG_CIFS_STATS is not set
+CONFIG_CIFS_WEAK_PW_HASH=y
+CONFIG_CIFS_XATTR=y
+CONFIG_CIFS_POSIX=y
+# CONFIG_CIFS_DEBUG2 is not set
+# CONFIG_CIFS_EXPERIMENTAL is not set
+CONFIG_NCP_FS=m
+CONFIG_NCPFS_PACKET_SIGNING=y
+CONFIG_NCPFS_IOCTL_LOCKING=y
+CONFIG_NCPFS_STRONG=y
+CONFIG_NCPFS_NFS_NS=y
+CONFIG_NCPFS_OS2_NS=y
+CONFIG_NCPFS_SMALLDOS=y
+CONFIG_NCPFS_NLS=y
+CONFIG_NCPFS_EXTRAS=y
+CONFIG_CODA_FS=m
+# CONFIG_CODA_FS_OLD_API is not set
+# CONFIG_AFS_FS is not set
+CONFIG_9P_FS=m
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+CONFIG_OSF_PARTITION=y
+CONFIG_AMIGA_PARTITION=y
+# CONFIG_ATARI_PARTITION is not set
+CONFIG_MAC_PARTITION=y
+CONFIG_MSDOS_PARTITION=y
+CONFIG_BSD_DISKLABEL=y
+CONFIG_MINIX_SUBPARTITION=y
+CONFIG_SOLARIS_X86_PARTITION=y
+CONFIG_UNIXWARE_DISKLABEL=y
+# CONFIG_LDM_PARTITION is not set
+CONFIG_SGI_PARTITION=y
+# CONFIG_ULTRIX_PARTITION is not set
+CONFIG_SUN_PARTITION=y
+CONFIG_KARMA_PARTITION=y
+CONFIG_EFI_PARTITION=y
+
+#
+# Native Language Support
+#
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="utf8"
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_CODEPAGE_737=m
+CONFIG_NLS_CODEPAGE_775=m
+CONFIG_NLS_CODEPAGE_850=m
+CONFIG_NLS_CODEPAGE_852=m
+CONFIG_NLS_CODEPAGE_855=m
+CONFIG_NLS_CODEPAGE_857=m
+CONFIG_NLS_CODEPAGE_860=m
+CONFIG_NLS_CODEPAGE_861=m
+CONFIG_NLS_CODEPAGE_862=m
+CONFIG_NLS_CODEPAGE_863=m
+CONFIG_NLS_CODEPAGE_864=m
+CONFIG_NLS_CODEPAGE_865=m
+CONFIG_NLS_CODEPAGE_866=m
+CONFIG_NLS_CODEPAGE_869=m
+CONFIG_NLS_CODEPAGE_936=m
+CONFIG_NLS_CODEPAGE_950=m
+CONFIG_NLS_CODEPAGE_932=m
+CONFIG_NLS_CODEPAGE_949=m
+CONFIG_NLS_CODEPAGE_874=m
+CONFIG_NLS_ISO8859_8=m
+CONFIG_NLS_CODEPAGE_1250=m
+CONFIG_NLS_CODEPAGE_1251=m
+CONFIG_NLS_ASCII=y
+CONFIG_NLS_ISO8859_1=m
+CONFIG_NLS_ISO8859_2=m
+CONFIG_NLS_ISO8859_3=m
+CONFIG_NLS_ISO8859_4=m
+CONFIG_NLS_ISO8859_5=m
+CONFIG_NLS_ISO8859_6=m
+CONFIG_NLS_ISO8859_7=m
+CONFIG_NLS_ISO8859_9=m
+CONFIG_NLS_ISO8859_13=m
+CONFIG_NLS_ISO8859_14=m
+CONFIG_NLS_ISO8859_15=m
+CONFIG_NLS_KOI8_R=m
+CONFIG_NLS_KOI8_U=m
+CONFIG_NLS_UTF8=m
+
+#
+# Instrumentation Support
+#
+CONFIG_PROFILING=y
+CONFIG_OPROFILE=m
+CONFIG_KPROBES=y
+
+#
+# Kernel hacking
+#
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+# CONFIG_PRINTK_TIME is not set
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_UNUSED_SYMBOLS is not set
+CONFIG_DEBUG_KERNEL=y
+CONFIG_LOG_BUF_SHIFT=17
+CONFIG_DETECT_SOFTLOCKUP=y
+CONFIG_SCHEDSTATS=y
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
+CONFIG_DEBUG_SPINLOCK=y
+# 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=y
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+# CONFIG_DEBUG_KOBJECT is not set
+CONFIG_DEBUG_HIGHMEM=y
+CONFIG_DEBUG_BUGVERBOSE=y
+CONFIG_DEBUG_INFO=y
+CONFIG_DEBUG_FS=y
+# CONFIG_DEBUG_VM is not set
+CONFIG_DEBUG_LIST=y
+# CONFIG_FRAME_POINTER is not set
+CONFIG_UNWIND_INFO=y
+CONFIG_STACK_UNWIND=y
+# CONFIG_FORCED_INLINING is not set
+CONFIG_BOOT_DELAY=y
+# CONFIG_RCU_TORTURE_TEST is not set
+CONFIG_EARLY_PRINTK=y
+CONFIG_DEBUG_STACKOVERFLOW=y
+CONFIG_DEBUG_STACK_USAGE=y
+
+#
+# Page alloc debug is incompatible with Software Suspend on i386
+#
+CONFIG_DEBUG_RODATA=y
+CONFIG_4KSTACKS=y
+CONFIG_X86_FIND_SMP_CONFIG=y
+CONFIG_X86_MPPARSE=y
+CONFIG_DOUBLEFAULT=y
+
+#
+# Security options
+#
+CONFIG_KEYS=y
+CONFIG_KEYS_DEBUG_PROC_KEYS=y
+CONFIG_SECURITY=y
+CONFIG_SECURITY_NETWORK=y
+# CONFIG_SECURITY_NETWORK_XFRM is not set
+CONFIG_SECURITY_CAPABILITIES=y
+# CONFIG_SECURITY_ROOTPLUG is not set
+# CONFIG_SECURITY_SECLVL is not set
+CONFIG_SECURITY_SELINUX=y
+CONFIG_SECURITY_SELINUX_BOOTPARAM=y
+CONFIG_SECURITY_SELINUX_BOOTPARAM_VALUE=1
+CONFIG_SECURITY_SELINUX_DISABLE=y
+CONFIG_SECURITY_SELINUX_DEVELOP=y
+CONFIG_SECURITY_SELINUX_AVC_STATS=y
+CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE=1
+# CONFIG_SECURITY_SELINUX_ENABLE_SECMARK_DEFAULT is not set
+# CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX is not set
+
+#
+# Cryptographic options
+#
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_NULL=m
+CONFIG_CRYPTO_MD4=m
+CONFIG_CRYPTO_MD5=m
+CONFIG_CRYPTO_SHA1=y
+CONFIG_CRYPTO_SHA256=m
+CONFIG_CRYPTO_SHA512=m
+CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_TGR192=m
+CONFIG_CRYPTO_DES=m
+CONFIG_CRYPTO_BLOWFISH=m
+CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_SERPENT=m
+CONFIG_CRYPTO_AES=m
+CONFIG_CRYPTO_AES_586=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_TEST is not set
+CONFIG_CRYPTO_SIGNATURE=y
+CONFIG_CRYPTO_SIGNATURE_DSA=y
+CONFIG_CRYPTO_MPILIB=y
+
+#
+# Hardware crypto devices
+#
+CONFIG_CRYPTO_DEV_PADLOCK=m
+CONFIG_CRYPTO_DEV_PADLOCK_AES=y
+
+#
+# Library routines
+#
+CONFIG_CRC_CCITT=m
+CONFIG_CRC16=m
+CONFIG_CRC32=y
+CONFIG_LIBCRC32C=m
+CONFIG_AUDIT_GENERIC=y
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=m
+CONFIG_REED_SOLOMON=m
+CONFIG_REED_SOLOMON_DEC16=y
+CONFIG_TEXTSEARCH=y
+CONFIG_TEXTSEARCH_KMP=m
+CONFIG_TEXTSEARCH_BM=m
+CONFIG_TEXTSEARCH_FSM=m
+CONFIG_PLIST=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_GENERIC_PENDING_IRQ=y
+CONFIG_X86_SMP=y
+CONFIG_X86_HT=y
+CONFIG_X86_BIOS_REBOOT=y
+CONFIG_X86_TRAMPOLINE=y
+CONFIG_KTIME_SCALAR=y
diff --git a/configs/kernel-2.6.18-i586.config b/configs/kernel-2.6.18-i586.config
new file mode 100644
index 000000000..906c52ba2
--- /dev/null
+++ b/configs/kernel-2.6.18-i586.config
@@ -0,0 +1,3357 @@
+# i386
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.18.2-rc1
+# Mon Nov 13 09:44:39 2006
+#
+CONFIG_X86_32=y
+CONFIG_GENERIC_TIME=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_SEMAPHORE_SLEEPERS=y
+CONFIG_X86=y
+CONFIG_MMU=y
+CONFIG_GENERIC_ISA_DMA=y
+CONFIG_GENERIC_IOMAP=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_ARCH_MAY_HAVE_PC_FDC=y
+CONFIG_DMI=y
+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=y
+CONFIG_SYSVIPC=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_BSD_PROCESS_ACCT=y
+# CONFIG_BSD_PROCESS_ACCT_V3 is not set
+CONFIG_TASKSTATS=y
+CONFIG_TASK_DELAY_ACCT=y
+CONFIG_AUDIT=y
+CONFIG_AUDITSYSCALL=y
+# CONFIG_IKCONFIG is not set
+CONFIG_RELAY=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+# CONFIG_EMBEDDED is not set
+CONFIG_UID16=y
+CONFIG_SYSCTL=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
+CONFIG_KALLSYMS_EXTRA_PASS=y
+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=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+CONFIG_MODULE_SIG=y
+# CONFIG_MODULE_SIG_FORCE is not set
+CONFIG_KMOD=y
+
+#
+# Process debugging support
+#
+CONFIG_UTRACE=y
+CONFIG_PTRACE=y
+
+#
+# Block layer
+#
+CONFIG_LBD=y
+CONFIG_BLK_DEV_IO_TRACE=y
+CONFIG_LSF=y
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_DEFAULT_AS is not set
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+
+#
+# Processor type and features
+#
+# CONFIG_SMP is not set
+CONFIG_X86_PC=y
+# CONFIG_X86_XEN is not set
+# CONFIG_X86_ELAN is not set
+# CONFIG_X86_VOYAGER is not set
+# CONFIG_X86_NUMAQ is not set
+# CONFIG_X86_SUMMIT is not set
+# CONFIG_X86_BIGSMP is not set
+# CONFIG_X86_VISWS is not set
+# CONFIG_X86_GENERICARCH is not set
+# CONFIG_X86_ES7000 is not set
+# CONFIG_M386 is not set
+# CONFIG_M486 is not set
+CONFIG_M586=y
+# CONFIG_M586TSC is not set
+# CONFIG_M586MMX is not set
+# CONFIG_M686 is not set
+# CONFIG_MPENTIUMII is not set
+# CONFIG_MPENTIUMIII is not set
+# CONFIG_MPENTIUMM is not set
+# CONFIG_MPENTIUM4 is not set
+# CONFIG_MK6 is not set
+# CONFIG_MK7 is not set
+# CONFIG_MK8 is not set
+# CONFIG_MCRUSOE is not set
+# CONFIG_MEFFICEON is not set
+# CONFIG_MWINCHIPC6 is not set
+# CONFIG_MWINCHIP2 is not set
+# CONFIG_MWINCHIP3D is not set
+# CONFIG_MGEODEGX1 is not set
+# CONFIG_MGEODE_LX is not set
+# CONFIG_MCYRIXIII is not set
+# CONFIG_MVIAC3_2 is not set
+CONFIG_X86_GENERIC=y
+CONFIG_X86_CMPXCHG=y
+CONFIG_X86_XADD=y
+CONFIG_X86_L1_CACHE_SHIFT=7
+CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_X86_PPRO_FENCE=y
+CONFIG_X86_F00F_BUG=y
+CONFIG_X86_WP_WORKS_OK=y
+CONFIG_X86_INVLPG=y
+CONFIG_X86_BSWAP=y
+CONFIG_X86_POPAD_OK=y
+CONFIG_X86_CMPXCHG64=y
+CONFIG_X86_ALIGNMENT_16=y
+CONFIG_X86_INTEL_USERCOPY=y
+CONFIG_HPET_TIMER=y
+CONFIG_HPET_EMULATE_RTC=y
+# CONFIG_PREEMPT_NONE is not set
+CONFIG_PREEMPT_VOLUNTARY=y
+# CONFIG_PREEMPT is not set
+# CONFIG_X86_UP_APIC is not set
+CONFIG_X86_MCE=y
+# CONFIG_X86_MCE_NONFATAL is not set
+CONFIG_VM86=y
+# CONFIG_TOSHIBA is not set
+# CONFIG_I8K is not set
+# CONFIG_X86_REBOOTFIXUPS is not set
+# CONFIG_MICROCODE is not set
+CONFIG_X86_MSR=m
+CONFIG_X86_CPUID=m
+# CONFIG_SWIOTLB is not set
+
+#
+# Firmware Drivers
+#
+CONFIG_EDD=m
+CONFIG_EFI_VARS=y
+# CONFIG_DELL_RBU is not set
+# CONFIG_DCDBAS is not set
+# CONFIG_NOHIGHMEM is not set
+CONFIG_HIGHMEM4G=y
+# CONFIG_HIGHMEM64G is not set
+CONFIG_PAGE_OFFSET=0xC0000000
+CONFIG_HIGHMEM=y
+CONFIG_ARCH_FLATMEM_ENABLE=y
+CONFIG_ARCH_SPARSEMEM_ENABLE=y
+CONFIG_ARCH_SELECT_MEMORY_MODEL=y
+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=y
+CONFIG_SPLIT_PTLOCK_CPUS=4096
+CONFIG_RESOURCES_64BIT=y
+CONFIG_HIGHPTE=y
+# CONFIG_MATH_EMULATION is not set
+CONFIG_MTRR=y
+CONFIG_EFI=y
+CONFIG_BOOT_IOREMAP=y
+CONFIG_REGPARM=y
+# CONFIG_SECCOMP is not set
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
+CONFIG_KEXEC=y
+# CONFIG_CRASH_DUMP is not set
+CONFIG_PHYSICAL_START=0x400000
+# CONFIG_COMPAT_VDSO is not set
+CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
+
+#
+# Power management options (ACPI, APM)
+#
+CONFIG_PM=y
+CONFIG_PM_LEGACY=y
+# CONFIG_PM_DEBUG is not set
+CONFIG_SOFTWARE_SUSPEND=y
+CONFIG_PM_STD_PARTITION=""
+
+#
+# ACPI (Advanced Configuration and Power Interface) Support
+#
+CONFIG_ACPI=y
+CONFIG_ACPI_SLEEP=y
+CONFIG_ACPI_SLEEP_PROC_FS=y
+# CONFIG_ACPI_SLEEP_PROC_SLEEP is not set
+CONFIG_ACPI_AC=m
+CONFIG_ACPI_BATTERY=m
+CONFIG_ACPI_BUTTON=m
+CONFIG_ACPI_VIDEO=m
+# CONFIG_ACPI_HOTKEY is not set
+CONFIG_ACPI_FAN=y
+CONFIG_ACPI_DOCK=m
+CONFIG_ACPI_PROCESSOR=y
+CONFIG_ACPI_THERMAL=y
+# CONFIG_ACPI_ASUS is not set
+# CONFIG_ACPI_IBM is not set
+# CONFIG_ACPI_TOSHIBA is not set
+CONFIG_ACPI_BLACKLIST_YEAR=1999
+# CONFIG_ACPI_DEBUG is not set
+CONFIG_ACPI_EC=y
+CONFIG_ACPI_POWER=y
+CONFIG_ACPI_SYSTEM=y
+CONFIG_X86_PM_TIMER=y
+CONFIG_ACPI_CONTAINER=m
+CONFIG_ACPI_SBS=m
+
+#
+# APM (Advanced Power Management) BIOS Support
+#
+CONFIG_APM=y
+# CONFIG_APM_IGNORE_USER_SUSPEND is not set
+# CONFIG_APM_DO_ENABLE is not set
+CONFIG_APM_CPU_IDLE=y
+# CONFIG_APM_DISPLAY_BLANK is not set
+CONFIG_APM_RTC_IS_GMT=y
+# CONFIG_APM_ALLOW_INTS is not set
+# CONFIG_APM_REAL_MODE_POWER_OFF is not set
+
+#
+# CPU Frequency scaling
+#
+CONFIG_CPU_FREQ=y
+CONFIG_CPU_FREQ_TABLE=m
+CONFIG_CPU_FREQ_DEBUG=y
+CONFIG_CPU_FREQ_STAT=m
+CONFIG_CPU_FREQ_STAT_DETAILS=y
+# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set
+CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE=y
+CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
+CONFIG_CPU_FREQ_GOV_POWERSAVE=m
+CONFIG_CPU_FREQ_GOV_USERSPACE=y
+CONFIG_CPU_FREQ_GOV_ONDEMAND=m
+CONFIG_CPU_FREQ_GOV_CONSERVATIVE=m
+
+#
+# CPUFreq processor drivers
+#
+CONFIG_X86_ACPI_CPUFREQ=m
+CONFIG_X86_POWERNOW_K6=m
+# CONFIG_X86_POWERNOW_K7 is not set
+# CONFIG_X86_POWERNOW_K8 is not set
+# CONFIG_X86_GX_SUSPMOD is not set
+# CONFIG_X86_SPEEDSTEP_CENTRINO is not set
+# CONFIG_X86_SPEEDSTEP_ICH is not set
+# CONFIG_X86_SPEEDSTEP_SMI is not set
+# CONFIG_X86_P4_CLOCKMOD is not set
+# CONFIG_X86_CPUFREQ_NFORCE2 is not set
+CONFIG_X86_LONGRUN=y
+# CONFIG_X86_LONGHAUL is not set
+
+#
+# shared options
+#
+# CONFIG_X86_ACPI_CPUFREQ_PROC_INTF is not set
+# CONFIG_X86_SPEEDSTEP_LIB is not set
+
+#
+# Bus options (PCI, PCMCIA, EISA, MCA, ISA)
+#
+CONFIG_PCI=y
+# CONFIG_PCI_GOBIOS is not set
+# CONFIG_PCI_GOMMCONFIG is not set
+# CONFIG_PCI_GODIRECT is not set
+# CONFIG_PCI_GOXEN_FE is not set
+CONFIG_PCI_GOANY=y
+CONFIG_PCI_BIOS=y
+CONFIG_PCI_DIRECT=y
+CONFIG_PCI_MMCONFIG=y
+CONFIG_PCIEPORTBUS=y
+# CONFIG_PCI_DEBUG is not set
+CONFIG_ISA_DMA_API=y
+CONFIG_ISA=y
+# CONFIG_EISA is not set
+# CONFIG_MCA is not set
+# CONFIG_SCx200 is not set
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+CONFIG_PCCARD=y
+# CONFIG_PCMCIA_DEBUG is not set
+CONFIG_PCMCIA=y
+CONFIG_PCMCIA_LOAD_CIS=y
+CONFIG_PCMCIA_IOCTL=y
+CONFIG_CARDBUS=y
+
+#
+# PC-card bridges
+#
+CONFIG_YENTA=y
+CONFIG_YENTA_O2=y
+CONFIG_YENTA_RICOH=y
+CONFIG_YENTA_TI=y
+CONFIG_YENTA_ENE_TUNE=y
+CONFIG_YENTA_TOSHIBA=y
+CONFIG_PD6729=m
+CONFIG_I82092=m
+# CONFIG_I82365 is not set
+# CONFIG_TCIC is not set
+CONFIG_PCMCIA_PROBE=y
+CONFIG_PCCARD_NONSTATIC=y
+
+#
+# PCI Hotplug Support
+#
+# CONFIG_HOTPLUG_PCI is not set
+
+#
+# Executable file formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_AOUT is not set
+CONFIG_BINFMT_MISC=y
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+# CONFIG_NETDEBUG is not set
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=y
+CONFIG_NET_KEY=m
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_ASK_IP_FIB_HASH=y
+# 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
+# CONFIG_IP_PNP is not set
+CONFIG_NET_IPIP=m
+CONFIG_NET_IPGRE=m
+CONFIG_NET_IPGRE_BROADCAST=y
+CONFIG_IP_MROUTE=y
+CONFIG_IP_PIMSM_V1=y
+CONFIG_IP_PIMSM_V2=y
+# CONFIG_ARPD is not set
+CONFIG_SYN_COOKIES=y
+CONFIG_INET_AH=m
+CONFIG_INET_ESP=m
+CONFIG_INET_IPCOMP=m
+CONFIG_INET_XFRM_TUNNEL=m
+CONFIG_INET_TUNNEL=m
+CONFIG_INET_XFRM_MODE_TRANSPORT=m
+CONFIG_INET_XFRM_MODE_TUNNEL=m
+CONFIG_INET_DIAG=m
+CONFIG_INET_TCP_DIAG=m
+CONFIG_TCP_CONG_ADVANCED=y
+
+#
+# TCP congestion control
+#
+CONFIG_TCP_CONG_BIC=y
+CONFIG_TCP_CONG_CUBIC=m
+CONFIG_TCP_CONG_WESTWOOD=m
+CONFIG_TCP_CONG_HTCP=m
+CONFIG_TCP_CONG_HSTCP=m
+CONFIG_TCP_CONG_HYBLA=m
+CONFIG_TCP_CONG_VEGAS=m
+CONFIG_TCP_CONG_SCALABLE=m
+CONFIG_TCP_CONG_LP=m
+CONFIG_TCP_CONG_VENO=m
+
+#
+# IP: Virtual Server Configuration
+#
+CONFIG_IP_VS=m
+# CONFIG_IP_VS_DEBUG is not set
+CONFIG_IP_VS_TAB_BITS=12
+
+#
+# IPVS transport protocol load balancing support
+#
+CONFIG_IP_VS_PROTO_TCP=y
+CONFIG_IP_VS_PROTO_UDP=y
+CONFIG_IP_VS_PROTO_ESP=y
+CONFIG_IP_VS_PROTO_AH=y
+
+#
+# IPVS scheduler
+#
+CONFIG_IP_VS_RR=m
+CONFIG_IP_VS_WRR=m
+CONFIG_IP_VS_LC=m
+CONFIG_IP_VS_WLC=m
+CONFIG_IP_VS_LBLC=m
+CONFIG_IP_VS_LBLCR=m
+CONFIG_IP_VS_DH=m
+CONFIG_IP_VS_SH=m
+CONFIG_IP_VS_SED=m
+CONFIG_IP_VS_NQ=m
+
+#
+# IPVS application helper
+#
+CONFIG_IP_VS_FTP=m
+CONFIG_IPV6=m
+CONFIG_IPV6_PRIVACY=y
+CONFIG_IPV6_ROUTER_PREF=y
+CONFIG_IPV6_ROUTE_INFO=y
+CONFIG_INET6_AH=m
+CONFIG_INET6_ESP=m
+CONFIG_INET6_IPCOMP=m
+CONFIG_INET6_XFRM_TUNNEL=m
+CONFIG_INET6_TUNNEL=m
+CONFIG_INET6_XFRM_MODE_TRANSPORT=m
+CONFIG_INET6_XFRM_MODE_TUNNEL=m
+CONFIG_IPV6_TUNNEL=m
+CONFIG_NETWORK_SECMARK=y
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_DEBUG is not set
+CONFIG_BRIDGE_NETFILTER=y
+
+#
+# Core Netfilter Configuration
+#
+CONFIG_NETFILTER_NETLINK=m
+CONFIG_NETFILTER_NETLINK_QUEUE=m
+CONFIG_NETFILTER_NETLINK_LOG=m
+CONFIG_NETFILTER_XTABLES=m
+CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
+CONFIG_NETFILTER_XT_TARGET_CONNMARK=m
+CONFIG_NETFILTER_XT_TARGET_MARK=m
+CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
+CONFIG_NETFILTER_XT_TARGET_NOTRACK=m
+CONFIG_NETFILTER_XT_TARGET_SECMARK=m
+CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=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_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_PHYSDEV=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
+
+#
+# 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=m
+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_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_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_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
+CONFIG_IP_NF_ARPTABLES=m
+CONFIG_IP_NF_ARPFILTER=m
+CONFIG_IP_NF_ARP_MANGLE=m
+
+#
+# IPv6: Netfilter Configuration (EXPERIMENTAL)
+#
+CONFIG_IP6_NF_QUEUE=m
+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_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
+
+#
+# DECnet: Netfilter Configuration
+#
+# CONFIG_DECNET_NF_GRABULATOR is not set
+
+#
+# Bridge: Netfilter Configuration
+#
+CONFIG_BRIDGE_NF_EBTABLES=m
+CONFIG_BRIDGE_EBT_BROUTE=m
+CONFIG_BRIDGE_EBT_T_FILTER=m
+CONFIG_BRIDGE_EBT_T_NAT=m
+CONFIG_BRIDGE_EBT_802_3=m
+CONFIG_BRIDGE_EBT_AMONG=m
+CONFIG_BRIDGE_EBT_ARP=m
+CONFIG_BRIDGE_EBT_IP=m
+CONFIG_BRIDGE_EBT_LIMIT=m
+CONFIG_BRIDGE_EBT_MARK=m
+CONFIG_BRIDGE_EBT_PKTTYPE=m
+CONFIG_BRIDGE_EBT_STP=m
+CONFIG_BRIDGE_EBT_VLAN=m
+CONFIG_BRIDGE_EBT_ARPREPLY=m
+CONFIG_BRIDGE_EBT_DNAT=m
+CONFIG_BRIDGE_EBT_MARK_T=m
+CONFIG_BRIDGE_EBT_REDIRECT=m
+CONFIG_BRIDGE_EBT_SNAT=m
+CONFIG_BRIDGE_EBT_LOG=m
+CONFIG_BRIDGE_EBT_ULOG=m
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+CONFIG_IP_DCCP=m
+CONFIG_INET_DCCP_DIAG=m
+CONFIG_IP_DCCP_ACKVEC=y
+
+#
+# DCCP CCIDs Configuration (EXPERIMENTAL)
+#
+CONFIG_IP_DCCP_CCID2=m
+CONFIG_IP_DCCP_CCID3=m
+CONFIG_IP_DCCP_TFRC_LIB=m
+
+#
+# DCCP Kernel Hacking
+#
+# CONFIG_IP_DCCP_DEBUG is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+CONFIG_IP_SCTP=m
+# CONFIG_SCTP_DBG_MSG is not set
+# CONFIG_SCTP_DBG_OBJCNT is not set
+# CONFIG_SCTP_HMAC_NONE is not set
+# CONFIG_SCTP_HMAC_SHA1 is not set
+CONFIG_SCTP_HMAC_MD5=y
+
+#
+# TIPC Configuration (EXPERIMENTAL)
+#
+CONFIG_TIPC=m
+# CONFIG_TIPC_ADVANCED is not set
+# CONFIG_TIPC_DEBUG is not set
+CONFIG_ATM=m
+CONFIG_ATM_CLIP=m
+# CONFIG_ATM_CLIP_NO_ICMP is not set
+CONFIG_ATM_LANE=m
+# CONFIG_ATM_MPOA is not set
+CONFIG_ATM_BR2684=m
+# CONFIG_ATM_BR2684_IPFILTER is not set
+CONFIG_BRIDGE=m
+CONFIG_VLAN_8021Q=m
+CONFIG_DECNET=m
+CONFIG_DECNET_ROUTER=y
+CONFIG_DECNET_ROUTE_FWMARK=y
+CONFIG_LLC=y
+# CONFIG_LLC2 is not set
+CONFIG_IPX=m
+# CONFIG_IPX_INTERN is not set
+CONFIG_ATALK=m
+CONFIG_DEV_APPLETALK=m
+# CONFIG_LTPC is not set
+# CONFIG_COPS is not set
+CONFIG_IPDDP=m
+CONFIG_IPDDP_ENCAP=y
+CONFIG_IPDDP_DECAP=y
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+CONFIG_WAN_ROUTER=m
+
+#
+# QoS and/or fair queueing
+#
+CONFIG_NET_SCHED=y
+# CONFIG_NET_SCH_CLK_JIFFIES is not set
+CONFIG_NET_SCH_CLK_GETTIMEOFDAY=y
+# CONFIG_NET_SCH_CLK_CPU is not set
+
+#
+# Queueing/Scheduling
+#
+CONFIG_NET_SCH_CBQ=m
+CONFIG_NET_SCH_HTB=m
+CONFIG_NET_SCH_HFSC=m
+CONFIG_NET_SCH_ATM=m
+CONFIG_NET_SCH_PRIO=m
+CONFIG_NET_SCH_RED=m
+CONFIG_NET_SCH_SFQ=m
+CONFIG_NET_SCH_TEQL=m
+CONFIG_NET_SCH_TBF=m
+CONFIG_NET_SCH_GRED=m
+CONFIG_NET_SCH_DSMARK=m
+CONFIG_NET_SCH_NETEM=m
+CONFIG_NET_SCH_INGRESS=m
+
+#
+# Classification
+#
+CONFIG_NET_CLS=y
+CONFIG_NET_CLS_BASIC=m
+CONFIG_NET_CLS_TCINDEX=m
+CONFIG_NET_CLS_ROUTE4=m
+CONFIG_NET_CLS_ROUTE=y
+CONFIG_NET_CLS_FW=m
+CONFIG_NET_CLS_U32=m
+CONFIG_CLS_U32_PERF=y
+CONFIG_CLS_U32_MARK=y
+CONFIG_NET_CLS_RSVP=m
+CONFIG_NET_CLS_RSVP6=m
+CONFIG_NET_EMATCH=y
+CONFIG_NET_EMATCH_STACK=32
+CONFIG_NET_EMATCH_CMP=m
+CONFIG_NET_EMATCH_NBYTE=m
+CONFIG_NET_EMATCH_U32=m
+CONFIG_NET_EMATCH_META=m
+CONFIG_NET_EMATCH_TEXT=m
+CONFIG_NET_CLS_ACT=y
+CONFIG_NET_ACT_POLICE=m
+CONFIG_NET_ACT_GACT=m
+CONFIG_GACT_PROB=y
+CONFIG_NET_ACT_MIRRED=m
+CONFIG_NET_ACT_IPT=m
+CONFIG_NET_ACT_PEDIT=m
+CONFIG_NET_ACT_SIMP=m
+CONFIG_NET_CLS_IND=y
+CONFIG_NET_ESTIMATOR=y
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_NET_TCPPROBE is not set
+# CONFIG_HAMRADIO is not set
+CONFIG_IRDA=m
+
+#
+# IrDA protocols
+#
+CONFIG_IRLAN=m
+CONFIG_IRNET=m
+CONFIG_IRCOMM=m
+# CONFIG_IRDA_ULTRA is not set
+
+#
+# IrDA options
+#
+CONFIG_IRDA_CACHE_LAST_LSAP=y
+CONFIG_IRDA_FAST_RR=y
+# CONFIG_IRDA_DEBUG is not set
+
+#
+# Infrared-port device drivers
+#
+
+#
+# SIR device drivers
+#
+CONFIG_IRTTY_SIR=m
+
+#
+# Dongle support
+#
+CONFIG_DONGLE=y
+CONFIG_ESI_DONGLE=m
+CONFIG_ACTISYS_DONGLE=m
+CONFIG_TEKRAM_DONGLE=m
+CONFIG_TOIM3232_DONGLE=m
+CONFIG_LITELINK_DONGLE=m
+CONFIG_MA600_DONGLE=m
+CONFIG_GIRBIL_DONGLE=m
+CONFIG_MCP2120_DONGLE=m
+CONFIG_OLD_BELKIN_DONGLE=m
+CONFIG_ACT200L_DONGLE=m
+
+#
+# Old SIR device drivers
+#
+CONFIG_IRPORT_SIR=m
+
+#
+# Old Serial dongle support
+#
+# CONFIG_DONGLE_OLD is not set
+
+#
+# FIR device drivers
+#
+CONFIG_USB_IRDA=m
+CONFIG_SIGMATEL_FIR=m
+CONFIG_NSC_FIR=m
+CONFIG_WINBOND_FIR=m
+CONFIG_TOSHIBA_FIR=m
+CONFIG_SMC_IRCC_FIR=m
+CONFIG_ALI_FIR=m
+CONFIG_VLSI_FIR=m
+CONFIG_VIA_FIR=m
+CONFIG_MCS_FIR=m
+CONFIG_BT=m
+CONFIG_BT_L2CAP=m
+CONFIG_BT_SCO=m
+CONFIG_BT_RFCOMM=m
+CONFIG_BT_RFCOMM_TTY=y
+CONFIG_BT_BNEP=m
+CONFIG_BT_BNEP_MC_FILTER=y
+CONFIG_BT_BNEP_PROTO_FILTER=y
+CONFIG_BT_CMTP=m
+CONFIG_BT_HIDP=m
+
+#
+# Bluetooth device drivers
+#
+CONFIG_BT_HCIUSB=m
+CONFIG_BT_HCIUSB_SCO=y
+CONFIG_BT_HCIUART=m
+CONFIG_BT_HCIUART_H4=y
+CONFIG_BT_HCIUART_BCSP=y
+CONFIG_BT_HCIBCM203X=m
+CONFIG_BT_HCIBPA10X=m
+CONFIG_BT_HCIBFUSB=m
+CONFIG_BT_HCIDTL1=m
+CONFIG_BT_HCIBT3C=m
+CONFIG_BT_HCIBLUECARD=m
+CONFIG_BT_HCIBTUART=m
+CONFIG_BT_HCIVHCI=m
+CONFIG_IEEE80211=m
+# CONFIG_IEEE80211_DEBUG is not set
+CONFIG_IEEE80211_CRYPT_WEP=m
+CONFIG_IEEE80211_CRYPT_CCMP=m
+CONFIG_IEEE80211_CRYPT_TKIP=m
+CONFIG_IEEE80211_SOFTMAC=m
+CONFIG_IEEE80211_SOFTMAC_DEBUG=y
+CONFIG_TUX=m
+
+#
+# TUX options
+#
+CONFIG_TUX_EXTCGI=y
+CONFIG_TUX_EXTENDED_LOG=y
+# CONFIG_TUX_DEBUG is not set
+CONFIG_WIRELESS_EXT=y
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_SYS_HYPERVISOR is not set
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+CONFIG_CONNECTOR=y
+CONFIG_PROC_EVENTS=y
+
+#
+# Memory Technology Devices (MTD)
+#
+CONFIG_MTD=m
+# CONFIG_MTD_DEBUG is not set
+CONFIG_MTD_CONCAT=m
+CONFIG_MTD_PARTITIONS=y
+CONFIG_MTD_REDBOOT_PARTS=m
+CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1
+# CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED is not set
+# CONFIG_MTD_REDBOOT_PARTS_READONLY is not set
+CONFIG_MTD_CMDLINE_PARTS=y
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=m
+CONFIG_MTD_BLOCK=m
+CONFIG_MTD_BLOCK_RO=m
+CONFIG_FTL=m
+CONFIG_NFTL=m
+CONFIG_NFTL_RW=y
+CONFIG_INFTL=m
+CONFIG_RFD_FTL=m
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=m
+CONFIG_MTD_JEDECPROBE=m
+CONFIG_MTD_GEN_PROBE=m
+# CONFIG_MTD_CFI_ADV_OPTIONS 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_CFI_INTELEXT=m
+CONFIG_MTD_CFI_AMDSTD=m
+CONFIG_MTD_CFI_STAA=m
+CONFIG_MTD_CFI_UTIL=m
+CONFIG_MTD_RAM=m
+CONFIG_MTD_ROM=m
+CONFIG_MTD_ABSENT=m
+# CONFIG_MTD_OBSOLETE_CHIPS is not set
+
+#
+# Mapping drivers for chip access
+#
+CONFIG_MTD_COMPLEX_MAPPINGS=y
+# CONFIG_MTD_PHYSMAP is not set
+# CONFIG_MTD_PNC2000 is not set
+CONFIG_MTD_SC520CDP=m
+CONFIG_MTD_NETSC520=m
+CONFIG_MTD_TS5500=m
+# CONFIG_MTD_SBC_GXX is not set
+# CONFIG_MTD_AMD76XROM is not set
+# CONFIG_MTD_ICHXROM is not set
+CONFIG_MTD_SCB2_FLASH=m
+# CONFIG_MTD_NETtel is not set
+# CONFIG_MTD_DILNETPC is not set
+# CONFIG_MTD_L440GX is not set
+CONFIG_MTD_PCI=m
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+CONFIG_MTD_PMC551=m
+# CONFIG_MTD_PMC551_BUGFIX is not set
+# CONFIG_MTD_PMC551_DEBUG is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+CONFIG_MTD_MTDRAM=m
+CONFIG_MTDRAM_TOTAL_SIZE=4096
+CONFIG_MTDRAM_ERASE_SIZE=128
+CONFIG_MTD_BLOCK2MTD=m
+
+#
+# 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=m
+# CONFIG_MTD_NAND_VERIFY_WRITE is not set
+CONFIG_MTD_NAND_ECC_SMC=y
+CONFIG_MTD_NAND_IDS=m
+CONFIG_MTD_NAND_DISKONCHIP=m
+# CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADVANCED is not set
+CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADDRESS=0
+# CONFIG_MTD_NAND_DISKONCHIP_BBTWRITE is not set
+CONFIG_MTD_NAND_CS553X=m
+CONFIG_MTD_NAND_NANDSIM=m
+
+#
+# OneNAND Flash Device Drivers
+#
+# CONFIG_MTD_ONENAND is not set
+
+#
+# Parallel port support
+#
+CONFIG_PARPORT=m
+CONFIG_PARPORT_PC=m
+CONFIG_PARPORT_SERIAL=m
+# CONFIG_PARPORT_PC_FIFO is not set
+# CONFIG_PARPORT_PC_SUPERIO is not set
+CONFIG_PARPORT_PC_PCMCIA=m
+CONFIG_PARPORT_NOT_PC=y
+# CONFIG_PARPORT_GSC is not set
+# CONFIG_PARPORT_AX88796 is not set
+CONFIG_PARPORT_1284=y
+
+#
+# Plug and Play support
+#
+CONFIG_PNP=y
+# CONFIG_PNP_DEBUG is not set
+
+#
+# Protocols
+#
+CONFIG_ISAPNP=y
+# CONFIG_PNPBIOS is not set
+CONFIG_PNPACPI=y
+
+#
+# Block devices
+#
+CONFIG_BLK_DEV_FD=m
+# CONFIG_BLK_DEV_XD is not set
+CONFIG_PARIDE=m
+CONFIG_PARIDE_PARPORT=m
+
+#
+# Parallel IDE high-level drivers
+#
+CONFIG_PARIDE_PD=m
+CONFIG_PARIDE_PCD=m
+CONFIG_PARIDE_PF=m
+CONFIG_PARIDE_PT=m
+CONFIG_PARIDE_PG=m
+
+#
+# Parallel IDE protocol modules
+#
+CONFIG_PARIDE_ATEN=m
+CONFIG_PARIDE_BPCK=m
+CONFIG_PARIDE_BPCK6=m
+CONFIG_PARIDE_COMM=m
+CONFIG_PARIDE_DSTR=m
+CONFIG_PARIDE_FIT2=m
+CONFIG_PARIDE_FIT3=m
+CONFIG_PARIDE_EPAT=m
+CONFIG_PARIDE_EPATC8=y
+CONFIG_PARIDE_EPIA=m
+CONFIG_PARIDE_FRIQ=m
+CONFIG_PARIDE_FRPW=m
+CONFIG_PARIDE_KBIC=m
+CONFIG_PARIDE_KTTI=m
+CONFIG_PARIDE_ON20=m
+CONFIG_PARIDE_ON26=m
+CONFIG_BLK_CPQ_DA=m
+CONFIG_BLK_CPQ_CISS_DA=m
+CONFIG_CISS_SCSI_TAPE=y
+CONFIG_BLK_DEV_DAC960=m
+CONFIG_BLK_DEV_UMEM=m
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=m
+CONFIG_BLK_DEV_CRYPTOLOOP=m
+CONFIG_BLK_DEV_NBD=m
+CONFIG_BLK_DEV_SX8=m
+CONFIG_BLK_DEV_UB=m
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=16384
+CONFIG_BLK_DEV_RAM_BLOCKSIZE=4096
+CONFIG_BLK_DEV_INITRD=y
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+CONFIG_IDE=y
+CONFIG_BLK_DEV_IDE=y
+
+#
+# Please see Documentation/ide.txt for help/info on IDE drives
+#
+# CONFIG_BLK_DEV_IDE_SATA is not set
+# CONFIG_BLK_DEV_HD_IDE is not set
+CONFIG_BLK_DEV_IDEDISK=y
+CONFIG_IDEDISK_MULTI_MODE=y
+CONFIG_BLK_DEV_IDECS=m
+CONFIG_BLK_DEV_IDECD=m
+# CONFIG_BLK_DEV_IDETAPE is not set
+CONFIG_BLK_DEV_IDEFLOPPY=y
+CONFIG_BLK_DEV_IDESCSI=m
+CONFIG_IDE_TASK_IOCTL=y
+
+#
+# IDE chipset support/bugfixes
+#
+CONFIG_IDE_GENERIC=y
+CONFIG_BLK_DEV_CMD640=y
+CONFIG_BLK_DEV_CMD640_ENHANCED=y
+CONFIG_BLK_DEV_IDEPNP=y
+CONFIG_BLK_DEV_IDEPCI=y
+CONFIG_IDEPCI_SHARE_IRQ=y
+# CONFIG_BLK_DEV_OFFBOARD is not set
+CONFIG_BLK_DEV_GENERIC=y
+# CONFIG_BLK_DEV_OPTI621 is not set
+CONFIG_BLK_DEV_RZ1000=y
+CONFIG_BLK_DEV_IDEDMA_PCI=y
+# CONFIG_BLK_DEV_IDEDMA_FORCED is not set
+CONFIG_IDEDMA_PCI_AUTO=y
+# CONFIG_IDEDMA_ONLYDISK is not set
+CONFIG_BLK_DEV_AEC62XX=y
+CONFIG_BLK_DEV_ALI15X3=y
+# CONFIG_WDC_ALI15X3 is not set
+CONFIG_BLK_DEV_AMD74XX=y
+CONFIG_BLK_DEV_ATIIXP=y
+CONFIG_BLK_DEV_CMD64X=y
+CONFIG_BLK_DEV_TRIFLEX=y
+# CONFIG_BLK_DEV_CY82C693 is not set
+CONFIG_BLK_DEV_CS5520=y
+CONFIG_BLK_DEV_CS5530=y
+CONFIG_BLK_DEV_CS5535=y
+CONFIG_BLK_DEV_HPT34X=y
+# CONFIG_HPT34X_AUTODMA is not set
+CONFIG_BLK_DEV_HPT366=y
+# CONFIG_BLK_DEV_SC1200 is not set
+CONFIG_BLK_DEV_PIIX=y
+CONFIG_BLK_DEV_IT821X=y
+# CONFIG_BLK_DEV_NS87415 is not set
+CONFIG_BLK_DEV_PDC202XX_OLD=y
+# CONFIG_PDC202XX_BURST is not set
+CONFIG_BLK_DEV_PDC202XX_NEW=y
+CONFIG_BLK_DEV_SVWKS=y
+CONFIG_BLK_DEV_SIIMAGE=y
+CONFIG_BLK_DEV_SIS5513=y
+# CONFIG_BLK_DEV_SLC90E66 is not set
+# CONFIG_BLK_DEV_TRM290 is not set
+CONFIG_BLK_DEV_VIA82CXXX=y
+# CONFIG_IDE_ARM is not set
+# CONFIG_IDE_CHIPSETS is not set
+CONFIG_BLK_DEV_IDEDMA=y
+# CONFIG_IDEDMA_IVB is not set
+CONFIG_IDEDMA_AUTO=y
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# SCSI device support
+#
+CONFIG_RAID_ATTRS=m
+CONFIG_SCSI=m
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=m
+CONFIG_CHR_DEV_ST=m
+CONFIG_CHR_DEV_OSST=m
+CONFIG_BLK_DEV_SR=m
+CONFIG_BLK_DEV_SR_VENDOR=y
+CONFIG_CHR_DEV_SG=m
+CONFIG_CHR_DEV_SCH=m
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+CONFIG_SCSI_MULTI_LUN=y
+CONFIG_SCSI_CONSTANTS=y
+CONFIG_SCSI_LOGGING=y
+
+#
+# SCSI Transport Attributes
+#
+CONFIG_SCSI_SPI_ATTRS=m
+CONFIG_SCSI_FC_ATTRS=m
+CONFIG_SCSI_ISCSI_ATTRS=m
+CONFIG_SCSI_SAS_ATTRS=m
+
+#
+# SCSI low-level drivers
+#
+CONFIG_ISCSI_TCP=m
+CONFIG_BLK_DEV_3W_XXXX_RAID=m
+CONFIG_SCSI_3W_9XXX=m
+# CONFIG_SCSI_7000FASST is not set
+CONFIG_SCSI_ACARD=m
+CONFIG_SCSI_AHA152X=m
+CONFIG_SCSI_AHA1542=m
+CONFIG_SCSI_AACRAID=m
+CONFIG_SCSI_AIC7XXX=m
+CONFIG_AIC7XXX_CMDS_PER_DEVICE=4
+CONFIG_AIC7XXX_RESET_DELAY_MS=15000
+# CONFIG_AIC7XXX_DEBUG_ENABLE is not set
+CONFIG_AIC7XXX_DEBUG_MASK=0
+# CONFIG_AIC7XXX_REG_PRETTY_PRINT is not set
+CONFIG_SCSI_AIC7XXX_OLD=m
+CONFIG_SCSI_AIC79XX=m
+CONFIG_AIC79XX_CMDS_PER_DEVICE=4
+CONFIG_AIC79XX_RESET_DELAY_MS=15000
+# CONFIG_AIC79XX_ENABLE_RD_STRM is not set
+# CONFIG_AIC79XX_DEBUG_ENABLE is not set
+CONFIG_AIC79XX_DEBUG_MASK=0
+# CONFIG_AIC79XX_REG_PRETTY_PRINT is not set
+# CONFIG_SCSI_DPT_I2O is not set
+CONFIG_SCSI_ADVANSYS=m
+# CONFIG_SCSI_IN2000 is not set
+CONFIG_MEGARAID_NEWGEN=y
+CONFIG_MEGARAID_MM=m
+CONFIG_MEGARAID_MAILBOX=m
+CONFIG_MEGARAID_LEGACY=m
+CONFIG_MEGARAID_SAS=m
+CONFIG_SCSI_SATA=m
+CONFIG_SCSI_SATA_AHCI=m
+CONFIG_SCSI_SATA_SVW=m
+CONFIG_SCSI_ATA_PIIX=m
+CONFIG_SCSI_SATA_MV=m
+CONFIG_SCSI_SATA_NV=m
+CONFIG_SCSI_PDC_ADMA=m
+CONFIG_SCSI_HPTIOP=m
+CONFIG_SCSI_SATA_QSTOR=m
+CONFIG_SCSI_SATA_PROMISE=m
+CONFIG_SCSI_SATA_SX4=m
+CONFIG_SCSI_SATA_SIL=m
+CONFIG_SCSI_SATA_SIL24=m
+CONFIG_SCSI_SATA_SIS=m
+CONFIG_SCSI_SATA_ULI=m
+CONFIG_SCSI_SATA_VIA=m
+CONFIG_SCSI_SATA_VITESSE=m
+CONFIG_SCSI_SATA_INTEL_COMBINED=y
+CONFIG_SCSI_BUSLOGIC=m
+# CONFIG_SCSI_OMIT_FLASHPOINT is not set
+# CONFIG_SCSI_DMX3191D is not set
+# CONFIG_SCSI_DTC3280 is not set
+# CONFIG_SCSI_EATA is not set
+CONFIG_SCSI_FUTURE_DOMAIN=m
+CONFIG_SCSI_GDTH=m
+# CONFIG_SCSI_GENERIC_NCR5380 is not set
+# CONFIG_SCSI_GENERIC_NCR5380_MMIO is not set
+CONFIG_SCSI_IPS=m
+CONFIG_SCSI_INITIO=m
+CONFIG_SCSI_INIA100=m
+CONFIG_SCSI_PPA=m
+CONFIG_SCSI_IMM=m
+# CONFIG_SCSI_IZIP_EPP16 is not set
+# CONFIG_SCSI_IZIP_SLOW_CTR is not set
+# CONFIG_SCSI_NCR53C406A is not set
+CONFIG_SCSI_SYM53C8XX_2=m
+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=m
+CONFIG_SCSI_QLA_FC=m
+CONFIG_SCSI_LPFC=m
+# CONFIG_SCSI_SYM53C416 is not set
+CONFIG_SCSI_DC395x=m
+CONFIG_SCSI_DC390T=m
+# CONFIG_SCSI_T128 is not set
+# CONFIG_SCSI_U14_34F is not set
+# CONFIG_SCSI_ULTRASTOR is not set
+# CONFIG_SCSI_NSP32 is not set
+# CONFIG_SCSI_DEBUG is not set
+
+#
+# PCMCIA SCSI adapter support
+#
+CONFIG_PCMCIA_AHA152X=m
+CONFIG_PCMCIA_FDOMAIN=m
+CONFIG_PCMCIA_NINJA_SCSI=m
+CONFIG_PCMCIA_QLOGIC=m
+CONFIG_PCMCIA_SYM53C500=m
+
+#
+# Old CD-ROM drivers (not SCSI, not IDE)
+#
+# CONFIG_CD_NO_IDESCSI is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+CONFIG_MD=y
+CONFIG_BLK_DEV_MD=y
+CONFIG_MD_LINEAR=m
+CONFIG_MD_RAID0=m
+CONFIG_MD_RAID1=m
+CONFIG_MD_RAID10=m
+CONFIG_MD_RAID456=m
+CONFIG_MD_RAID5_RESHAPE=y
+CONFIG_MD_MULTIPATH=m
+CONFIG_MD_FAULTY=m
+CONFIG_BLK_DEV_DM=m
+CONFIG_DM_CRYPT=m
+CONFIG_DM_SNAPSHOT=m
+CONFIG_DM_MIRROR=m
+CONFIG_DM_ZERO=m
+CONFIG_DM_MULTIPATH=m
+CONFIG_DM_MULTIPATH_EMC=m
+
+#
+# Fusion MPT device support
+#
+CONFIG_FUSION=y
+CONFIG_FUSION_SPI=m
+CONFIG_FUSION_FC=m
+CONFIG_FUSION_SAS=m
+CONFIG_FUSION_MAX_SGE=40
+CONFIG_FUSION_CTL=m
+CONFIG_FUSION_LAN=m
+
+#
+# IEEE 1394 (FireWire) support
+#
+CONFIG_IEEE1394=m
+
+#
+# Subsystem Options
+#
+# CONFIG_IEEE1394_VERBOSEDEBUG is not set
+CONFIG_IEEE1394_OUI_DB=y
+CONFIG_IEEE1394_EXTRA_CONFIG_ROMS=y
+CONFIG_IEEE1394_CONFIG_ROM_IP1394=y
+# CONFIG_IEEE1394_EXPORT_FULL_API is not set
+
+#
+# Device Drivers
+#
+CONFIG_IEEE1394_PCILYNX=m
+CONFIG_IEEE1394_OHCI1394=m
+
+#
+# Protocol Drivers
+#
+CONFIG_IEEE1394_VIDEO1394=m
+CONFIG_IEEE1394_SBP2=m
+# CONFIG_IEEE1394_SBP2_PHYS_DMA is not set
+CONFIG_IEEE1394_ETH1394=m
+CONFIG_IEEE1394_DV1394=m
+CONFIG_IEEE1394_RAWIO=m
+
+#
+# I2O device support
+#
+CONFIG_I2O=m
+# CONFIG_I2O_LCT_NOTIFY_ON_CHANGES is not set
+CONFIG_I2O_EXT_ADAPTEC=y
+CONFIG_I2O_CONFIG=m
+CONFIG_I2O_CONFIG_OLD_IOCTL=y
+CONFIG_I2O_BUS=m
+CONFIG_I2O_BLOCK=m
+CONFIG_I2O_SCSI=m
+CONFIG_I2O_PROC=m
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+CONFIG_IFB=m
+CONFIG_DUMMY=m
+CONFIG_BONDING=m
+CONFIG_EQUALIZER=m
+CONFIG_TUN=m
+CONFIG_NET_SB1000=m
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+
+#
+# PHY device support
+#
+CONFIG_PHYLIB=m
+
+#
+# MII PHY device drivers
+#
+CONFIG_MARVELL_PHY=m
+CONFIG_DAVICOM_PHY=m
+CONFIG_QSEMI_PHY=m
+CONFIG_LXT_PHY=m
+CONFIG_CICADA_PHY=m
+CONFIG_VITESSE_PHY=m
+CONFIG_SMSC_PHY=m
+CONFIG_FIXED_PHY=m
+CONFIG_FIXED_MII_10_FDX=y
+CONFIG_FIXED_MII_100_FDX=y
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=m
+CONFIG_HAPPYMEAL=m
+CONFIG_SUNGEM=m
+CONFIG_CASSINI=m
+CONFIG_NET_VENDOR_3COM=y
+# CONFIG_EL1 is not set
+# CONFIG_EL2 is not set
+# CONFIG_ELPLUS is not set
+# CONFIG_EL16 is not set
+CONFIG_EL3=m
+# CONFIG_3C515 is not set
+CONFIG_VORTEX=m
+CONFIG_TYPHOON=m
+# CONFIG_LANCE is not set
+CONFIG_NET_VENDOR_SMC=y
+# CONFIG_WD80x3 is not set
+CONFIG_ULTRA=m
+# CONFIG_SMC9194 is not set
+# CONFIG_NET_VENDOR_RACAL is not set
+
+#
+# Tulip family network device support
+#
+CONFIG_NET_TULIP=y
+CONFIG_DE2104X=m
+CONFIG_TULIP=m
+# CONFIG_TULIP_MWI is not set
+CONFIG_TULIP_MMIO=y
+# CONFIG_TULIP_NAPI is not set
+CONFIG_DE4X5=m
+CONFIG_WINBOND_840=m
+CONFIG_DM9102=m
+CONFIG_ULI526X=m
+CONFIG_PCMCIA_XIRCOM=m
+# CONFIG_PCMCIA_XIRTULIP is not set
+# CONFIG_AT1700 is not set
+# CONFIG_DEPCA is not set
+# CONFIG_HP100 is not set
+CONFIG_NET_ISA=y
+# CONFIG_E2100 is not set
+CONFIG_EWRK3=m
+# CONFIG_EEXPRESS is not set
+# CONFIG_EEXPRESS_PRO is not set
+# CONFIG_HPLAN_PLUS is not set
+# CONFIG_HPLAN is not set
+# CONFIG_LP486E is not set
+# CONFIG_ETH16I is not set
+CONFIG_NE2000=m
+# CONFIG_ZNET is not set
+# CONFIG_SEEQ8005 is not set
+CONFIG_NET_PCI=y
+CONFIG_PCNET32=m
+CONFIG_AMD8111_ETH=m
+CONFIG_AMD8111E_NAPI=y
+CONFIG_ADAPTEC_STARFIRE=m
+CONFIG_ADAPTEC_STARFIRE_NAPI=y
+# CONFIG_AC3200 is not set
+# CONFIG_APRICOT is not set
+CONFIG_B44=m
+CONFIG_FORCEDETH=m
+# CONFIG_CS89x0 is not set
+# CONFIG_DGRS is not set
+# CONFIG_EEPRO100 is not set
+CONFIG_E100=m
+CONFIG_FEALNX=m
+CONFIG_NATSEMI=m
+CONFIG_NE2K_PCI=m
+CONFIG_8139CP=m
+CONFIG_8139TOO=m
+# CONFIG_8139TOO_PIO is not set
+# CONFIG_8139TOO_TUNE_TWISTER is not set
+CONFIG_8139TOO_8129=y
+# CONFIG_8139_OLD_RX_RESET is not set
+CONFIG_SIS900=m
+CONFIG_EPIC100=m
+CONFIG_SUNDANCE=m
+# CONFIG_SUNDANCE_MMIO is not set
+CONFIG_TLAN=m
+CONFIG_VIA_RHINE=m
+CONFIG_VIA_RHINE_MMIO=y
+CONFIG_VIA_RHINE_NAPI=y
+CONFIG_NET_POCKET=y
+CONFIG_ATP=m
+CONFIG_DE600=m
+CONFIG_DE620=m
+
+#
+# Ethernet (1000 Mbit)
+#
+CONFIG_ACENIC=m
+# CONFIG_ACENIC_OMIT_TIGON_I is not set
+CONFIG_DL2K=m
+CONFIG_E1000=m
+CONFIG_E1000_NAPI=y
+# CONFIG_E1000_DISABLE_PACKET_SPLIT is not set
+CONFIG_NS83820=m
+CONFIG_HAMACHI=m
+CONFIG_YELLOWFIN=m
+CONFIG_R8169=m
+CONFIG_R8169_NAPI=y
+CONFIG_R8169_VLAN=y
+CONFIG_SIS190=m
+CONFIG_SKGE=m
+CONFIG_SKY2=m
+# CONFIG_SK98LIN is not set
+CONFIG_VIA_VELOCITY=m
+CONFIG_TIGON3=m
+CONFIG_BNX2=m
+
+#
+# Ethernet (10000 Mbit)
+#
+CONFIG_CHELSIO_T1=m
+CONFIG_IXGB=m
+CONFIG_IXGB_NAPI=y
+CONFIG_S2IO=m
+CONFIG_S2IO_NAPI=y
+CONFIG_MYRI10GE=m
+
+#
+# Token Ring devices
+#
+CONFIG_TR=y
+# CONFIG_IBMTR is not set
+CONFIG_IBMOL=m
+CONFIG_IBMLS=m
+CONFIG_3C359=m
+# CONFIG_TMS380TR is not set
+# CONFIG_SMCTR is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+CONFIG_NET_RADIO=y
+CONFIG_NET_WIRELESS_RTNETLINK=y
+
+#
+# Obsolete Wireless cards support (pre-802.11)
+#
+# CONFIG_STRIP is not set
+# CONFIG_ARLAN is not set
+# CONFIG_WAVELAN is not set
+CONFIG_PCMCIA_WAVELAN=m
+CONFIG_PCMCIA_NETWAVE=m
+
+#
+# Wireless 802.11 Frequency Hopping cards support
+#
+# CONFIG_PCMCIA_RAYCS is not set
+
+#
+# Wireless 802.11b ISA/PCI cards support
+#
+CONFIG_IPW2100=m
+CONFIG_IPW2100_MONITOR=y
+# CONFIG_IPW2100_DEBUG is not set
+CONFIG_IPW2200=m
+CONFIG_IPW2200_MONITOR=y
+CONFIG_IPW2200_RADIOTAP=y
+CONFIG_IPW2200_PROMISCUOUS=y
+CONFIG_IPW2200_QOS=y
+# CONFIG_IPW2200_DEBUG is not set
+CONFIG_AIRO=m
+CONFIG_HERMES=m
+CONFIG_PLX_HERMES=m
+CONFIG_TMD_HERMES=m
+CONFIG_NORTEL_HERMES=m
+CONFIG_PCI_HERMES=m
+CONFIG_ATMEL=m
+CONFIG_PCI_ATMEL=m
+
+#
+# Wireless 802.11b Pcmcia/Cardbus cards support
+#
+CONFIG_PCMCIA_HERMES=m
+CONFIG_PCMCIA_SPECTRUM=m
+CONFIG_AIRO_CS=m
+CONFIG_PCMCIA_ATMEL=m
+CONFIG_PCMCIA_WL3501=m
+
+#
+# Prism GT/Duette 802.11(a/b/g) PCI/Cardbus support
+#
+CONFIG_PRISM54=m
+CONFIG_USB_ZD1201=m
+CONFIG_HOSTAP=m
+CONFIG_HOSTAP_FIRMWARE=y
+CONFIG_HOSTAP_FIRMWARE_NVRAM=y
+CONFIG_HOSTAP_PLX=m
+CONFIG_HOSTAP_PCI=m
+CONFIG_HOSTAP_CS=m
+CONFIG_BCM43XX=m
+CONFIG_BCM43XX_DEBUG=y
+CONFIG_BCM43XX_DMA=y
+CONFIG_BCM43XX_PIO=y
+CONFIG_BCM43XX_DMA_AND_PIO_MODE=y
+# CONFIG_BCM43XX_DMA_MODE is not set
+# CONFIG_BCM43XX_PIO_MODE is not set
+CONFIG_ZD1211RW=m
+# CONFIG_ZD1211RW_DEBUG is not set
+CONFIG_NET_WIRELESS=y
+
+#
+# PCMCIA network device support
+#
+CONFIG_NET_PCMCIA=y
+CONFIG_PCMCIA_3C589=m
+CONFIG_PCMCIA_3C574=m
+CONFIG_PCMCIA_FMVJ18X=m
+CONFIG_PCMCIA_PCNET=m
+CONFIG_PCMCIA_NMCLAN=m
+CONFIG_PCMCIA_SMC91C92=m
+CONFIG_PCMCIA_XIRC2PS=m
+CONFIG_PCMCIA_AXNET=m
+CONFIG_PCMCIA_IBMTR=m
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+
+#
+# ATM drivers
+#
+# CONFIG_ATM_DUMMY is not set
+CONFIG_ATM_TCP=m
+CONFIG_ATM_LANAI=m
+CONFIG_ATM_ENI=m
+# CONFIG_ATM_ENI_DEBUG is not set
+# CONFIG_ATM_ENI_TUNE_BURST is not set
+CONFIG_ATM_FIRESTREAM=m
+# CONFIG_ATM_ZATM is not set
+CONFIG_ATM_NICSTAR=m
+# CONFIG_ATM_NICSTAR_USE_SUNI is not set
+# CONFIG_ATM_NICSTAR_USE_IDT77105 is not set
+CONFIG_ATM_IDT77252=m
+# CONFIG_ATM_IDT77252_DEBUG is not set
+# CONFIG_ATM_IDT77252_RCV_ALL is not set
+CONFIG_ATM_IDT77252_USE_SUNI=y
+CONFIG_ATM_AMBASSADOR=m
+# CONFIG_ATM_AMBASSADOR_DEBUG is not set
+CONFIG_ATM_HORIZON=m
+# CONFIG_ATM_HORIZON_DEBUG is not set
+# CONFIG_ATM_IA is not set
+CONFIG_ATM_FORE200E_MAYBE=m
+# CONFIG_ATM_FORE200E_PCA is not set
+CONFIG_ATM_HE=m
+# CONFIG_ATM_HE_USE_SUNI is not set
+CONFIG_FDDI=y
+# CONFIG_DEFXX is not set
+CONFIG_SKFP=m
+# CONFIG_HIPPI is not set
+CONFIG_PLIP=m
+CONFIG_PPP=m
+CONFIG_PPP_MULTILINK=y
+CONFIG_PPP_FILTER=y
+CONFIG_PPP_ASYNC=m
+CONFIG_PPP_SYNC_TTY=m
+CONFIG_PPP_DEFLATE=m
+# CONFIG_PPP_BSDCOMP is not set
+CONFIG_PPP_MPPE=m
+CONFIG_PPPOE=m
+CONFIG_PPPOATM=m
+CONFIG_SLIP=m
+CONFIG_SLIP_COMPRESSED=y
+CONFIG_SLIP_SMART=y
+# CONFIG_SLIP_MODE_SLIP6 is not set
+CONFIG_NET_FC=y
+# CONFIG_SHAPER is not set
+CONFIG_NETCONSOLE=m
+CONFIG_NETPOLL=y
+# CONFIG_NETPOLL_RX is not set
+CONFIG_NETPOLL_TRAP=y
+CONFIG_NET_POLL_CONTROLLER=y
+
+#
+# ISDN subsystem
+#
+CONFIG_ISDN=m
+
+#
+# Old ISDN4Linux
+#
+CONFIG_ISDN_I4L=m
+CONFIG_ISDN_PPP=y
+CONFIG_ISDN_PPP_VJ=y
+CONFIG_ISDN_MPP=y
+CONFIG_IPPP_FILTER=y
+# CONFIG_ISDN_PPP_BSDCOMP is not set
+CONFIG_ISDN_AUDIO=y
+CONFIG_ISDN_TTY_FAX=y
+
+#
+# ISDN feature submodules
+#
+CONFIG_ISDN_DRV_LOOP=m
+CONFIG_ISDN_DIVERSION=m
+
+#
+# ISDN4Linux hardware drivers
+#
+
+#
+# Passive cards
+#
+CONFIG_ISDN_DRV_HISAX=m
+
+#
+# D-channel protocol features
+#
+CONFIG_HISAX_EURO=y
+CONFIG_DE_AOC=y
+CONFIG_HISAX_NO_SENDCOMPLETE=y
+CONFIG_HISAX_NO_LLC=y
+CONFIG_HISAX_NO_KEYPAD=y
+CONFIG_HISAX_1TR6=y
+CONFIG_HISAX_NI1=y
+CONFIG_HISAX_MAX_CARDS=8
+
+#
+# HiSax supported cards
+#
+# CONFIG_HISAX_16_0 is not set
+CONFIG_HISAX_16_3=y
+CONFIG_HISAX_TELESPCI=y
+CONFIG_HISAX_S0BOX=y
+# CONFIG_HISAX_AVM_A1 is not set
+CONFIG_HISAX_FRITZPCI=y
+CONFIG_HISAX_AVM_A1_PCMCIA=y
+CONFIG_HISAX_ELSA=y
+# CONFIG_HISAX_IX1MICROR2 is not set
+CONFIG_HISAX_DIEHLDIVA=y
+# CONFIG_HISAX_ASUSCOM is not set
+# CONFIG_HISAX_TELEINT is not set
+# CONFIG_HISAX_HFCS is not set
+CONFIG_HISAX_SEDLBAUER=y
+# CONFIG_HISAX_SPORTSTER is not set
+# CONFIG_HISAX_MIC is not set
+CONFIG_HISAX_NETJET=y
+CONFIG_HISAX_NETJET_U=y
+CONFIG_HISAX_NICCY=y
+# CONFIG_HISAX_ISURF is not set
+# CONFIG_HISAX_HSTSAPHIR is not set
+CONFIG_HISAX_BKM_A4T=y
+CONFIG_HISAX_SCT_QUADRO=y
+CONFIG_HISAX_GAZEL=y
+CONFIG_HISAX_HFC_PCI=y
+CONFIG_HISAX_W6692=y
+CONFIG_HISAX_HFC_SX=y
+CONFIG_HISAX_ENTERNOW_PCI=y
+# CONFIG_HISAX_DEBUG is not set
+
+#
+# HiSax PCMCIA card service modules
+#
+CONFIG_HISAX_SEDLBAUER_CS=m
+CONFIG_HISAX_ELSA_CS=m
+CONFIG_HISAX_AVM_A1_CS=m
+CONFIG_HISAX_TELES_CS=m
+
+#
+# HiSax sub driver modules
+#
+CONFIG_HISAX_ST5481=m
+# CONFIG_HISAX_HFCUSB is not set
+CONFIG_HISAX_HFC4S8S=m
+CONFIG_HISAX_FRITZ_PCIPNP=m
+CONFIG_HISAX_HDLC=y
+
+#
+# Active cards
+#
+# CONFIG_ISDN_DRV_ICN is not set
+# CONFIG_ISDN_DRV_PCBIT is not set
+# CONFIG_ISDN_DRV_SC is not set
+# CONFIG_ISDN_DRV_ACT2000 is not set
+CONFIG_HYSDN=m
+CONFIG_HYSDN_CAPI=y
+
+#
+# Siemens Gigaset
+#
+CONFIG_ISDN_DRV_GIGASET=m
+CONFIG_GIGASET_BASE=m
+CONFIG_GIGASET_M105=m
+# CONFIG_GIGASET_DEBUG is not set
+# CONFIG_GIGASET_UNDOCREQ is not set
+
+#
+# CAPI subsystem
+#
+CONFIG_ISDN_CAPI=m
+CONFIG_ISDN_DRV_AVMB1_VERBOSE_REASON=y
+CONFIG_ISDN_CAPI_MIDDLEWARE=y
+CONFIG_ISDN_CAPI_CAPI20=m
+CONFIG_ISDN_CAPI_CAPIFS_BOOL=y
+CONFIG_ISDN_CAPI_CAPIFS=m
+CONFIG_ISDN_CAPI_CAPIDRV=m
+
+#
+# CAPI hardware drivers
+#
+
+#
+# Active AVM cards
+#
+CONFIG_CAPI_AVM=y
+# CONFIG_ISDN_DRV_AVMB1_B1ISA is not set
+CONFIG_ISDN_DRV_AVMB1_B1PCI=m
+CONFIG_ISDN_DRV_AVMB1_B1PCIV4=y
+# CONFIG_ISDN_DRV_AVMB1_T1ISA is not set
+CONFIG_ISDN_DRV_AVMB1_B1PCMCIA=m
+CONFIG_ISDN_DRV_AVMB1_AVM_CS=m
+CONFIG_ISDN_DRV_AVMB1_T1PCI=m
+CONFIG_ISDN_DRV_AVMB1_C4=m
+
+#
+# Active Eicon DIVA Server cards
+#
+CONFIG_CAPI_EICON=y
+CONFIG_ISDN_DIVAS=m
+CONFIG_ISDN_DIVAS_BRIPCI=y
+CONFIG_ISDN_DIVAS_PRIPCI=y
+CONFIG_ISDN_DIVAS_DIVACAPI=m
+CONFIG_ISDN_DIVAS_USERIDI=m
+CONFIG_ISDN_DIVAS_MAINT=m
+
+#
+# Telephony Support
+#
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+
+#
+# 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=m
+# CONFIG_INPUT_TSDEV is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+CONFIG_KEYBOARD_ATKBD=y
+# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_KEYBOARD_LKKBD is not set
+# CONFIG_KEYBOARD_XTKBD is not set
+# CONFIG_KEYBOARD_NEWTON is not set
+CONFIG_INPUT_MOUSE=y
+CONFIG_MOUSE_PS2=y
+CONFIG_MOUSE_SERIAL=m
+# CONFIG_MOUSE_INPORT is not set
+# CONFIG_MOUSE_LOGIBM is not set
+# CONFIG_MOUSE_PC110PAD is not set
+CONFIG_MOUSE_VSXXXAA=m
+CONFIG_INPUT_JOYSTICK=y
+CONFIG_JOYSTICK_ANALOG=m
+CONFIG_JOYSTICK_A3D=m
+CONFIG_JOYSTICK_ADI=m
+CONFIG_JOYSTICK_COBRA=m
+CONFIG_JOYSTICK_GF2K=m
+CONFIG_JOYSTICK_GRIP=m
+CONFIG_JOYSTICK_GRIP_MP=m
+CONFIG_JOYSTICK_GUILLEMOT=m
+CONFIG_JOYSTICK_INTERACT=m
+CONFIG_JOYSTICK_SIDEWINDER=m
+CONFIG_JOYSTICK_TMDC=m
+CONFIG_JOYSTICK_IFORCE=m
+CONFIG_JOYSTICK_IFORCE_USB=y
+CONFIG_JOYSTICK_IFORCE_232=y
+CONFIG_JOYSTICK_WARRIOR=m
+CONFIG_JOYSTICK_MAGELLAN=m
+CONFIG_JOYSTICK_SPACEORB=m
+CONFIG_JOYSTICK_SPACEBALL=m
+CONFIG_JOYSTICK_STINGER=m
+CONFIG_JOYSTICK_TWIDJOY=m
+CONFIG_JOYSTICK_DB9=m
+CONFIG_JOYSTICK_GAMECON=m
+CONFIG_JOYSTICK_TURBOGRAFX=m
+CONFIG_JOYSTICK_JOYDUMP=m
+CONFIG_INPUT_TOUCHSCREEN=y
+CONFIG_TOUCHSCREEN_GUNZE=m
+CONFIG_TOUCHSCREEN_ELO=m
+CONFIG_TOUCHSCREEN_MTOUCH=m
+CONFIG_TOUCHSCREEN_MK712=m
+CONFIG_INPUT_MISC=y
+CONFIG_INPUT_PCSPKR=m
+CONFIG_INPUT_WISTRON_BTNS=m
+CONFIG_INPUT_UINPUT=m
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+CONFIG_SERIO_I8042=y
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_CT82C710 is not set
+# CONFIG_SERIO_PARKBD is not set
+# CONFIG_SERIO_PCIPS2 is not set
+CONFIG_SERIO_LIBPS2=y
+CONFIG_SERIO_RAW=m
+CONFIG_GAMEPORT=m
+CONFIG_GAMEPORT_NS558=m
+CONFIG_GAMEPORT_L4=m
+CONFIG_GAMEPORT_EMU10K1=m
+CONFIG_GAMEPORT_FM801=m
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+CONFIG_VT_HW_CONSOLE_BINDING=y
+CONFIG_SERIAL_NONSTANDARD=y
+# CONFIG_COMPUTONE is not set
+# CONFIG_ROCKETPORT is not set
+CONFIG_CYCLADES=m
+# CONFIG_CYZ_INTR is not set
+# CONFIG_DIGIEPCA is not set
+# CONFIG_ESPSERIAL is not set
+# CONFIG_MOXA_INTELLIO is not set
+# CONFIG_MOXA_SMARTIO is not set
+# CONFIG_ISI is not set
+CONFIG_SYNCLINK=m
+CONFIG_SYNCLINKMP=m
+CONFIG_SYNCLINK_GT=m
+CONFIG_N_HDLC=m
+# CONFIG_RISCOM8 is not set
+# CONFIG_SPECIALIX is not set
+# CONFIG_SX is not set
+# CONFIG_RIO is not set
+# CONFIG_STALDRV is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_PCI=y
+CONFIG_SERIAL_8250_PNP=y
+CONFIG_SERIAL_8250_CS=m
+CONFIG_SERIAL_8250_NR_UARTS=32
+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=y
+CONFIG_SERIAL_8250_RSA=y
+# CONFIG_SERIAL_8250_FOURPORT is not set
+# CONFIG_SERIAL_8250_ACCENT is not set
+# CONFIG_SERIAL_8250_BOCA is not set
+# CONFIG_SERIAL_8250_HUB6 is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_SERIAL_JSM=m
+CONFIG_UNIX98_PTYS=y
+# CONFIG_LEGACY_PTYS is not set
+CONFIG_CRASH=m
+CONFIG_PRINTER=m
+CONFIG_LP_CONSOLE=y
+CONFIG_PPDEV=m
+CONFIG_TIPAR=m
+
+#
+# IPMI
+#
+# CONFIG_IPMI_HANDLER is not set
+
+#
+# Watchdog Cards
+#
+CONFIG_WATCHDOG=y
+# CONFIG_WATCHDOG_NOWAYOUT is not set
+
+#
+# Watchdog Device Drivers
+#
+CONFIG_SOFT_WATCHDOG=m
+# CONFIG_ACQUIRE_WDT is not set
+# CONFIG_ADVANTECH_WDT is not set
+CONFIG_ALIM1535_WDT=m
+CONFIG_ALIM7101_WDT=m
+# CONFIG_SC520_WDT is not set
+# CONFIG_EUROTECH_WDT is not set
+# CONFIG_IB700_WDT is not set
+CONFIG_IBMASR=m
+# CONFIG_WAFER_WDT is not set
+CONFIG_I6300ESB_WDT=m
+CONFIG_I8XX_TCO=m
+# CONFIG_SC1200_WDT is not set
+# CONFIG_60XX_WDT is not set
+# CONFIG_SBC8360_WDT is not set
+# CONFIG_CPU5_WDT is not set
+CONFIG_W83627HF_WDT=m
+CONFIG_W83877F_WDT=m
+CONFIG_W83977F_WDT=m
+CONFIG_MACHZ_WDT=m
+# CONFIG_SBC_EPX_C3_WATCHDOG is not set
+
+#
+# ISA-based Watchdog Cards
+#
+# CONFIG_PCWATCHDOG is not set
+# CONFIG_MIXCOMWD is not set
+# CONFIG_WDT is not set
+
+#
+# PCI-based Watchdog Cards
+#
+CONFIG_PCIPCWATCHDOG=m
+CONFIG_WDTPCI=m
+CONFIG_WDT_501_PCI=y
+
+#
+# USB-based Watchdog Cards
+#
+CONFIG_USBPCWATCHDOG=m
+CONFIG_HW_RANDOM=y
+CONFIG_HW_RANDOM_INTEL=m
+CONFIG_HW_RANDOM_AMD=m
+CONFIG_HW_RANDOM_GEODE=m
+CONFIG_HW_RANDOM_VIA=m
+CONFIG_NVRAM=y
+CONFIG_RTC=y
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+# CONFIG_SONYPI is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_FTAPE is not set
+CONFIG_AGP=y
+CONFIG_AGP_ALI=y
+# CONFIG_AGP_ATI is not set
+# CONFIG_AGP_AMD is not set
+# CONFIG_AGP_AMD64 is not set
+CONFIG_AGP_INTEL=y
+# CONFIG_AGP_NVIDIA is not set
+CONFIG_AGP_SIS=y
+# CONFIG_AGP_SWORKS is not set
+CONFIG_AGP_VIA=y
+CONFIG_AGP_EFFICEON=y
+CONFIG_DRM=m
+CONFIG_DRM_TDFX=m
+CONFIG_DRM_R128=m
+CONFIG_DRM_RADEON=m
+CONFIG_DRM_I810=m
+CONFIG_DRM_I830=m
+CONFIG_DRM_I915=m
+CONFIG_DRM_MGA=m
+CONFIG_DRM_SIS=m
+CONFIG_DRM_VIA=m
+CONFIG_DRM_SAVAGE=m
+
+#
+# PCMCIA character devices
+#
+# CONFIG_SYNCLINK_CS is not set
+CONFIG_CARDMAN_4000=m
+CONFIG_CARDMAN_4040=m
+CONFIG_MWAVE=m
+CONFIG_PC8736x_GPIO=m
+CONFIG_NSC_GPIO=m
+CONFIG_CS5535_GPIO=m
+# CONFIG_RAW_DRIVER is not set
+CONFIG_HPET=y
+# CONFIG_HPET_RTC_IRQ is not set
+# CONFIG_HPET_MMAP is not set
+CONFIG_HANGCHECK_TIMER=m
+
+#
+# TPM devices
+#
+CONFIG_TCG_TPM=m
+CONFIG_TCG_TIS=m
+CONFIG_TCG_NSC=m
+CONFIG_TCG_ATMEL=m
+CONFIG_TCG_INFINEON=m
+# CONFIG_TELCLOCK is not set
+
+#
+# I2C support
+#
+CONFIG_I2C=m
+CONFIG_I2C_CHARDEV=m
+
+#
+# I2C Algorithms
+#
+CONFIG_I2C_ALGOBIT=m
+CONFIG_I2C_ALGOPCF=m
+CONFIG_I2C_ALGOPCA=m
+
+#
+# I2C Hardware Bus support
+#
+CONFIG_I2C_ALI1535=m
+CONFIG_I2C_ALI1563=m
+CONFIG_I2C_ALI15X3=m
+CONFIG_I2C_AMD756=m
+CONFIG_I2C_AMD756_S4882=m
+CONFIG_I2C_AMD8111=m
+# CONFIG_I2C_ELEKTOR is not set
+CONFIG_I2C_I801=m
+CONFIG_I2C_I810=m
+CONFIG_I2C_PIIX4=m
+CONFIG_I2C_ISA=m
+CONFIG_I2C_NFORCE2=m
+# CONFIG_I2C_OCORES is not set
+CONFIG_I2C_PARPORT=m
+CONFIG_I2C_PARPORT_LIGHT=m
+CONFIG_I2C_PROSAVAGE=m
+CONFIG_I2C_SAVAGE4=m
+# CONFIG_SCx200_ACB is not set
+CONFIG_I2C_SIS5595=m
+CONFIG_I2C_SIS630=m
+CONFIG_I2C_SIS96X=m
+CONFIG_I2C_STUB=m
+CONFIG_I2C_VIA=m
+CONFIG_I2C_VIAPRO=m
+CONFIG_I2C_VOODOO3=m
+CONFIG_I2C_PCA_ISA=m
+
+#
+# Miscellaneous I2C Chip support
+#
+CONFIG_SENSORS_DS1337=m
+CONFIG_SENSORS_DS1374=m
+CONFIG_SENSORS_EEPROM=m
+CONFIG_SENSORS_PCF8574=m
+CONFIG_SENSORS_PCA9539=m
+CONFIG_SENSORS_PCF8591=m
+CONFIG_SENSORS_MAX6875=m
+# 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 is not set
+# CONFIG_SPI_MASTER is not set
+
+#
+# Dallas's 1-wire bus
+#
+# CONFIG_W1 is not set
+
+#
+# Hardware Monitoring support
+#
+CONFIG_HWMON=m
+CONFIG_HWMON_VID=m
+CONFIG_SENSORS_ABITUGURU=m
+CONFIG_SENSORS_ADM1021=m
+CONFIG_SENSORS_ADM1025=m
+CONFIG_SENSORS_ADM1026=m
+CONFIG_SENSORS_ADM1031=m
+CONFIG_SENSORS_ADM9240=m
+CONFIG_SENSORS_ASB100=m
+CONFIG_SENSORS_ATXP1=m
+CONFIG_SENSORS_DS1621=m
+CONFIG_SENSORS_F71805F=m
+CONFIG_SENSORS_FSCHER=m
+CONFIG_SENSORS_FSCPOS=m
+CONFIG_SENSORS_GL518SM=m
+CONFIG_SENSORS_GL520SM=m
+CONFIG_SENSORS_IT87=m
+CONFIG_SENSORS_LM63=m
+CONFIG_SENSORS_LM75=m
+CONFIG_SENSORS_LM77=m
+CONFIG_SENSORS_LM78=m
+CONFIG_SENSORS_LM80=m
+CONFIG_SENSORS_LM83=m
+CONFIG_SENSORS_LM85=m
+CONFIG_SENSORS_LM87=m
+CONFIG_SENSORS_LM90=m
+CONFIG_SENSORS_LM92=m
+CONFIG_SENSORS_MAX1619=m
+CONFIG_SENSORS_PC87360=m
+CONFIG_SENSORS_SIS5595=m
+CONFIG_SENSORS_SMSC47M1=m
+CONFIG_SENSORS_SMSC47M192=m
+CONFIG_SENSORS_SMSC47B397=m
+CONFIG_SENSORS_VIA686A=m
+CONFIG_SENSORS_VT8231=m
+CONFIG_SENSORS_W83781D=m
+CONFIG_SENSORS_W83791D=m
+CONFIG_SENSORS_W83792D=m
+CONFIG_SENSORS_W83L785TS=m
+CONFIG_SENSORS_W83627HF=m
+CONFIG_SENSORS_W83627EHF=m
+# CONFIG_SENSORS_HDAPS is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
+
+#
+# Misc devices
+#
+# CONFIG_IBM_ASM is not set
+
+#
+# Multimedia devices
+#
+CONFIG_VIDEO_DEV=m
+CONFIG_VIDEO_V4L1=y
+CONFIG_VIDEO_V4L1_COMPAT=y
+CONFIG_VIDEO_V4L2=y
+
+#
+# Video Capture Adapters
+#
+
+#
+# Video Capture Adapters
+#
+# CONFIG_VIDEO_ADV_DEBUG is not set
+# CONFIG_VIDEO_VIVI is not set
+CONFIG_VIDEO_BT848=m
+CONFIG_VIDEO_BT848_DVB=y
+CONFIG_VIDEO_SAA6588=m
+# CONFIG_VIDEO_PMS is not set
+CONFIG_VIDEO_BWQCAM=m
+CONFIG_VIDEO_CQCAM=m
+CONFIG_VIDEO_W9966=m
+CONFIG_VIDEO_CPIA=m
+CONFIG_VIDEO_CPIA_PP=m
+CONFIG_VIDEO_CPIA_USB=m
+CONFIG_VIDEO_CPIA2=m
+CONFIG_VIDEO_SAA5246A=m
+CONFIG_VIDEO_SAA5249=m
+CONFIG_TUNER_3036=m
+CONFIG_VIDEO_STRADIS=m
+CONFIG_VIDEO_ZORAN=m
+CONFIG_VIDEO_ZORAN_BUZ=m
+CONFIG_VIDEO_ZORAN_DC10=m
+CONFIG_VIDEO_ZORAN_DC30=m
+CONFIG_VIDEO_ZORAN_LML33=m
+CONFIG_VIDEO_ZORAN_LML33R10=m
+CONFIG_VIDEO_ZORAN_AVS6EYES=m
+CONFIG_VIDEO_SAA7134=m
+CONFIG_VIDEO_SAA7134_ALSA=m
+CONFIG_VIDEO_SAA7134_DVB=m
+CONFIG_VIDEO_SAA7134_DVB_ALL_FRONTENDS=y
+CONFIG_VIDEO_MXB=m
+CONFIG_VIDEO_DPC=m
+CONFIG_VIDEO_HEXIUM_ORION=m
+CONFIG_VIDEO_HEXIUM_GEMINI=m
+CONFIG_VIDEO_CX88_VP3054=m
+CONFIG_VIDEO_CX88=m
+CONFIG_VIDEO_CX88_ALSA=m
+CONFIG_VIDEO_CX88_BLACKBIRD=m
+CONFIG_VIDEO_CX88_DVB=m
+CONFIG_VIDEO_CX88_DVB_ALL_FRONTENDS=y
+
+#
+# Encoders and Decoders
+#
+CONFIG_VIDEO_MSP3400=m
+CONFIG_VIDEO_CS53L32A=m
+CONFIG_VIDEO_TLV320AIC23B=m
+CONFIG_VIDEO_WM8775=m
+CONFIG_VIDEO_WM8739=m
+CONFIG_VIDEO_CX2341X=m
+CONFIG_VIDEO_CX25840=m
+CONFIG_VIDEO_SAA711X=m
+CONFIG_VIDEO_SAA7127=m
+CONFIG_VIDEO_UPD64031A=m
+CONFIG_VIDEO_UPD64083=m
+
+#
+# V4L USB devices
+#
+CONFIG_VIDEO_PVRUSB2=m
+CONFIG_VIDEO_PVRUSB2_24XXX=y
+CONFIG_VIDEO_PVRUSB2_SYSFS=y
+# CONFIG_VIDEO_PVRUSB2_DEBUGIFC is not set
+CONFIG_VIDEO_EM28XX=m
+CONFIG_VIDEO_USBVIDEO=m
+CONFIG_USB_VICAM=m
+CONFIG_USB_IBMCAM=m
+CONFIG_USB_KONICAWC=m
+CONFIG_USB_QUICKCAM_MESSENGER=m
+CONFIG_USB_ET61X251=m
+CONFIG_VIDEO_OVCAMCHIP=m
+CONFIG_USB_W9968CF=m
+CONFIG_USB_OV511=m
+CONFIG_USB_SE401=m
+CONFIG_USB_SN9C102=m
+CONFIG_USB_STV680=m
+CONFIG_USB_ZC0301=m
+CONFIG_USB_PWC=m
+# CONFIG_USB_PWC_DEBUG is not set
+
+#
+# Radio Adapters
+#
+# CONFIG_RADIO_CADET is not set
+# CONFIG_RADIO_RTRACK is not set
+# CONFIG_RADIO_RTRACK2 is not set
+# CONFIG_RADIO_AZTECH is not set
+# CONFIG_RADIO_GEMTEK is not set
+CONFIG_RADIO_GEMTEK_PCI=m
+CONFIG_RADIO_MAXIRADIO=m
+CONFIG_RADIO_MAESTRO=m
+# CONFIG_RADIO_SF16FMI is not set
+# CONFIG_RADIO_SF16FMR2 is not set
+# CONFIG_RADIO_TERRATEC is not set
+# CONFIG_RADIO_TRUST is not set
+# CONFIG_RADIO_TYPHOON is not set
+# CONFIG_RADIO_ZOLTRIX is not set
+CONFIG_USB_DSBR=m
+
+#
+# Digital Video Broadcasting Devices
+#
+CONFIG_DVB=y
+CONFIG_DVB_CORE=m
+
+#
+# Supported SAA7146 based PCI Adapters
+#
+CONFIG_DVB_AV7110=m
+CONFIG_DVB_AV7110_OSD=y
+CONFIG_DVB_BUDGET=m
+CONFIG_DVB_BUDGET_CI=m
+CONFIG_DVB_BUDGET_AV=m
+CONFIG_DVB_BUDGET_PATCH=m
+
+#
+# Supported USB Adapters
+#
+CONFIG_DVB_USB=m
+# CONFIG_DVB_USB_DEBUG is not set
+CONFIG_DVB_USB_A800=m
+CONFIG_DVB_USB_DIBUSB_MB=m
+# CONFIG_DVB_USB_DIBUSB_MB_FAULTY is not set
+CONFIG_DVB_USB_DIBUSB_MC=m
+CONFIG_DVB_USB_UMT_010=m
+CONFIG_DVB_USB_CXUSB=m
+CONFIG_DVB_USB_DIGITV=m
+CONFIG_DVB_USB_VP7045=m
+CONFIG_DVB_USB_VP702X=m
+CONFIG_DVB_USB_GP8PSK=m
+CONFIG_DVB_USB_NOVA_T_USB2=m
+CONFIG_DVB_USB_DTT200U=m
+CONFIG_DVB_TTUSB_BUDGET=m
+CONFIG_DVB_TTUSB_DEC=m
+CONFIG_DVB_CINERGYT2=m
+CONFIG_DVB_CINERGYT2_TUNING=y
+CONFIG_DVB_CINERGYT2_STREAM_URB_COUNT=32
+CONFIG_DVB_CINERGYT2_STREAM_BUF_SIZE=512
+CONFIG_DVB_CINERGYT2_QUERY_INTERVAL=250
+CONFIG_DVB_CINERGYT2_ENABLE_RC_INPUT_DEVICE=y
+CONFIG_DVB_CINERGYT2_RC_QUERY_INTERVAL=100
+
+#
+# Supported FlexCopII (B2C2) Adapters
+#
+CONFIG_DVB_B2C2_FLEXCOP=m
+CONFIG_DVB_B2C2_FLEXCOP_PCI=m
+CONFIG_DVB_B2C2_FLEXCOP_USB=m
+# CONFIG_DVB_B2C2_FLEXCOP_DEBUG is not set
+
+#
+# Supported BT878 Adapters
+#
+CONFIG_DVB_BT8XX=m
+
+#
+# Supported Pluto2 Adapters
+#
+CONFIG_DVB_PLUTO2=m
+
+#
+# Supported DVB Frontends
+#
+
+#
+# Customise DVB Frontends
+#
+
+#
+# DVB-S (satellite) frontends
+#
+CONFIG_DVB_STV0299=m
+CONFIG_DVB_CX24110=m
+CONFIG_DVB_CX24123=m
+CONFIG_DVB_TDA8083=m
+CONFIG_DVB_MT312=m
+CONFIG_DVB_VES1X93=m
+CONFIG_DVB_S5H1420=m
+
+#
+# DVB-T (terrestrial) frontends
+#
+CONFIG_DVB_SP8870=m
+CONFIG_DVB_SP887X=m
+CONFIG_DVB_CX22700=m
+CONFIG_DVB_CX22702=m
+CONFIG_DVB_L64781=m
+CONFIG_DVB_TDA1004X=m
+CONFIG_DVB_NXT6000=m
+CONFIG_DVB_MT352=m
+CONFIG_DVB_ZL10353=m
+CONFIG_DVB_DIB3000MB=m
+CONFIG_DVB_DIB3000MC=m
+
+#
+# DVB-C (cable) frontends
+#
+CONFIG_DVB_VES1820=m
+CONFIG_DVB_TDA10021=m
+CONFIG_DVB_STV0297=m
+
+#
+# ATSC (North American/Korean Terrestrial/Cable DTV) frontends
+#
+CONFIG_DVB_NXT200X=m
+CONFIG_DVB_OR51211=m
+CONFIG_DVB_OR51132=m
+CONFIG_DVB_BCM3510=m
+CONFIG_DVB_LGDT330X=m
+
+#
+# Miscellaneous devices
+#
+CONFIG_DVB_PLL=m
+CONFIG_DVB_LNBP21=m
+CONFIG_DVB_ISL6421=m
+CONFIG_VIDEO_SAA7146=m
+CONFIG_VIDEO_SAA7146_VV=m
+CONFIG_VIDEO_VIDEOBUF=m
+CONFIG_VIDEO_TUNER=m
+CONFIG_VIDEO_BUF=m
+CONFIG_VIDEO_BUF_DVB=m
+CONFIG_VIDEO_BTCX=m
+CONFIG_VIDEO_IR=m
+CONFIG_VIDEO_TVEEPROM=m
+CONFIG_USB_DABUSB=m
+
+#
+# Graphics support
+#
+# CONFIG_FIRMWARE_EDID is not set
+CONFIG_FB=y
+CONFIG_FB_CFB_FILLRECT=y
+CONFIG_FB_CFB_COPYAREA=y
+CONFIG_FB_CFB_IMAGEBLIT=y
+# CONFIG_FB_MACMODES is not set
+# CONFIG_FB_BACKLIGHT is not set
+CONFIG_FB_MODE_HELPERS=y
+CONFIG_FB_TILEBLITTING=y
+CONFIG_FB_CIRRUS=m
+# CONFIG_FB_PM2 is not set
+# CONFIG_FB_CYBER2000 is not set
+# CONFIG_FB_ARC is not set
+# CONFIG_FB_ASILIANT is not set
+# CONFIG_FB_IMSTT is not set
+CONFIG_FB_VGA16=m
+CONFIG_FB_VESA=y
+# CONFIG_FB_IMAC is not set
+# CONFIG_FB_HGA is not set
+# CONFIG_FB_S1D13XXX is not set
+CONFIG_FB_NVIDIA=m
+CONFIG_FB_NVIDIA_I2C=y
+CONFIG_FB_RIVA=m
+# CONFIG_FB_RIVA_I2C is not set
+# CONFIG_FB_RIVA_DEBUG is not set
+CONFIG_FB_I810=m
+CONFIG_FB_I810_GTF=y
+CONFIG_FB_I810_I2C=y
+CONFIG_FB_INTEL=m
+# CONFIG_FB_INTEL_DEBUG is not set
+CONFIG_FB_MATROX=m
+CONFIG_FB_MATROX_MILLENIUM=y
+CONFIG_FB_MATROX_MYSTIQUE=y
+CONFIG_FB_MATROX_G=y
+CONFIG_FB_MATROX_I2C=m
+CONFIG_FB_MATROX_MAVEN=m
+CONFIG_FB_MATROX_MULTIHEAD=y
+CONFIG_FB_RADEON=m
+CONFIG_FB_RADEON_I2C=y
+# CONFIG_FB_RADEON_DEBUG is not set
+CONFIG_FB_ATY128=m
+CONFIG_FB_ATY=m
+CONFIG_FB_ATY_CT=y
+CONFIG_FB_ATY_GENERIC_LCD=y
+CONFIG_FB_ATY_GX=y
+CONFIG_FB_SAVAGE=m
+CONFIG_FB_SAVAGE_I2C=y
+CONFIG_FB_SAVAGE_ACCEL=y
+# CONFIG_FB_SIS is not set
+CONFIG_FB_NEOMAGIC=m
+CONFIG_FB_KYRO=m
+CONFIG_FB_3DFX=m
+CONFIG_FB_3DFX_ACCEL=y
+CONFIG_FB_VOODOO1=m
+CONFIG_FB_CYBLA=m
+CONFIG_FB_TRIDENT=m
+CONFIG_FB_TRIDENT_ACCEL=y
+# CONFIG_FB_GEODE is not set
+# CONFIG_FB_VIRTUAL is not set
+
+#
+# Console display driver support
+#
+CONFIG_VGA_CONSOLE=y
+CONFIG_VGACON_SOFT_SCROLLBACK=y
+CONFIG_VGACON_SOFT_SCROLLBACK_SIZE=64
+CONFIG_VIDEO_SELECT=y
+# CONFIG_MDA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y
+# CONFIG_FONTS is not set
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
+
+#
+# Logo configuration
+#
+CONFIG_LOGO=y
+# CONFIG_LOGO_LINUX_MONO is not set
+# CONFIG_LOGO_LINUX_VGA16 is not set
+CONFIG_LOGO_LINUX_CLUT224=y
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+CONFIG_BACKLIGHT_CLASS_DEVICE=m
+CONFIG_BACKLIGHT_DEVICE=y
+CONFIG_LCD_CLASS_DEVICE=m
+CONFIG_LCD_DEVICE=y
+
+#
+# Sound
+#
+CONFIG_SOUND=m
+
+#
+# Advanced Linux Sound Architecture
+#
+CONFIG_SND=m
+CONFIG_SND_TIMER=m
+CONFIG_SND_PCM=m
+CONFIG_SND_HWDEP=m
+CONFIG_SND_RAWMIDI=m
+CONFIG_SND_SEQUENCER=m
+CONFIG_SND_SEQ_DUMMY=m
+CONFIG_SND_OSSEMUL=y
+CONFIG_SND_MIXER_OSS=m
+CONFIG_SND_PCM_OSS=m
+CONFIG_SND_PCM_OSS_PLUGINS=y
+CONFIG_SND_SEQUENCER_OSS=y
+CONFIG_SND_RTCTIMER=m
+CONFIG_SND_SEQ_RTCTIMER_DEFAULT=y
+CONFIG_SND_DYNAMIC_MINORS=y
+# CONFIG_SND_SUPPORT_OLD_API is not set
+CONFIG_SND_VERBOSE_PROCFS=y
+# CONFIG_SND_VERBOSE_PRINTK is not set
+# CONFIG_SND_DEBUG is not set
+
+#
+# Generic devices
+#
+CONFIG_SND_MPU401_UART=m
+CONFIG_SND_OPL3_LIB=m
+CONFIG_SND_OPL4_LIB=m
+CONFIG_SND_VX_LIB=m
+CONFIG_SND_AC97_CODEC=m
+CONFIG_SND_AC97_BUS=m
+CONFIG_SND_DUMMY=m
+CONFIG_SND_VIRMIDI=m
+CONFIG_SND_MTPAV=m
+# CONFIG_SND_SERIAL_U16550 is not set
+CONFIG_SND_MPU401=m
+
+#
+# ISA devices
+#
+CONFIG_SND_CS4231_LIB=m
+CONFIG_SND_ADLIB=m
+# CONFIG_SND_AD1816A is not set
+# CONFIG_SND_AD1848 is not set
+# CONFIG_SND_ALS100 is not set
+# CONFIG_SND_AZT2320 is not set
+# CONFIG_SND_CMI8330 is not set
+# CONFIG_SND_CS4231 is not set
+# CONFIG_SND_CS4232 is not set
+CONFIG_SND_CS4236=m
+# CONFIG_SND_DT019X is not set
+# CONFIG_SND_ES968 is not set
+# CONFIG_SND_ES1688 is not set
+CONFIG_SND_ES18XX=m
+# CONFIG_SND_GUSCLASSIC is not set
+# CONFIG_SND_GUSEXTREME is not set
+# CONFIG_SND_GUSMAX is not set
+# CONFIG_SND_INTERWAVE is not set
+# CONFIG_SND_INTERWAVE_STB is not set
+CONFIG_SND_OPL3SA2=m
+# CONFIG_SND_OPTI92X_AD1848 is not set
+# CONFIG_SND_OPTI92X_CS4231 is not set
+# CONFIG_SND_OPTI93X is not set
+CONFIG_SND_MIRO=m
+# CONFIG_SND_SB8 is not set
+CONFIG_SND_SB16=m
+CONFIG_SND_SBAWE=m
+# CONFIG_SND_SB16_CSP is not set
+# CONFIG_SND_SGALAXY is not set
+# CONFIG_SND_SSCAPE is not set
+# CONFIG_SND_WAVEFRONT is not set
+
+#
+# PCI devices
+#
+CONFIG_SND_AD1889=m
+CONFIG_SND_ALS300=m
+CONFIG_SND_ALS4000=m
+CONFIG_SND_ALI5451=m
+CONFIG_SND_ATIIXP=m
+CONFIG_SND_ATIIXP_MODEM=m
+CONFIG_SND_AU8810=m
+CONFIG_SND_AU8820=m
+CONFIG_SND_AU8830=m
+CONFIG_SND_AZT3328=m
+CONFIG_SND_BT87X=m
+# CONFIG_SND_BT87X_OVERCLOCK is not set
+CONFIG_SND_CA0106=m
+CONFIG_SND_CMIPCI=m
+CONFIG_SND_CS4281=m
+CONFIG_SND_CS46XX=m
+CONFIG_SND_CS46XX_NEW_DSP=y
+CONFIG_SND_CS5535AUDIO=m
+CONFIG_SND_DARLA20=m
+CONFIG_SND_GINA20=m
+CONFIG_SND_LAYLA20=m
+CONFIG_SND_DARLA24=m
+CONFIG_SND_GINA24=m
+CONFIG_SND_LAYLA24=m
+CONFIG_SND_MONA=m
+CONFIG_SND_MIA=m
+CONFIG_SND_ECHO3G=m
+CONFIG_SND_INDIGO=m
+CONFIG_SND_INDIGOIO=m
+CONFIG_SND_INDIGODJ=m
+CONFIG_SND_EMU10K1=m
+CONFIG_SND_EMU10K1X=m
+CONFIG_SND_ENS1370=m
+CONFIG_SND_ENS1371=m
+CONFIG_SND_ES1938=m
+CONFIG_SND_ES1968=m
+CONFIG_SND_FM801=m
+CONFIG_SND_FM801_TEA575X_BOOL=y
+CONFIG_SND_FM801_TEA575X=m
+CONFIG_SND_HDA_INTEL=m
+CONFIG_SND_HDSP=m
+CONFIG_SND_HDSPM=m
+CONFIG_SND_ICE1712=m
+CONFIG_SND_ICE1724=m
+CONFIG_SND_INTEL8X0=m
+CONFIG_SND_INTEL8X0M=m
+CONFIG_SND_KORG1212=m
+CONFIG_SND_MAESTRO3=m
+CONFIG_SND_MIXART=m
+CONFIG_SND_NM256=m
+CONFIG_SND_PCXHR=m
+CONFIG_SND_RIPTIDE=m
+CONFIG_SND_RME32=m
+CONFIG_SND_RME96=m
+CONFIG_SND_RME9652=m
+CONFIG_SND_SONICVIBES=m
+CONFIG_SND_TRIDENT=m
+CONFIG_SND_VIA82XX=m
+CONFIG_SND_VIA82XX_MODEM=m
+CONFIG_SND_VX222=m
+CONFIG_SND_YMFPCI=m
+
+#
+# USB devices
+#
+CONFIG_SND_USB_AUDIO=m
+CONFIG_SND_USB_USX2Y=m
+
+#
+# PCMCIA devices
+#
+# CONFIG_SND_VXPOCKET is not set
+# CONFIG_SND_PDAUDIOCF is not set
+
+#
+# Open Sound System
+#
+# CONFIG_SOUND_PRIME is not set
+
+#
+# USB support
+#
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB_ARCH_HAS_EHCI=y
+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_SUSPEND is not set
+# CONFIG_USB_OTG is not set
+
+#
+# USB Host Controller Drivers
+#
+CONFIG_USB_EHCI_HCD=m
+CONFIG_USB_EHCI_SPLIT_ISO=y
+CONFIG_USB_EHCI_ROOT_HUB_TT=y
+CONFIG_USB_EHCI_TT_NEWSCHED=y
+CONFIG_USB_ISP116X_HCD=m
+CONFIG_USB_OHCI_HCD=m
+# CONFIG_USB_OHCI_BIG_ENDIAN is not set
+CONFIG_USB_OHCI_LITTLE_ENDIAN=y
+CONFIG_USB_UHCI_HCD=m
+CONFIG_USB_SL811_HCD=m
+CONFIG_USB_SL811_CS=m
+
+#
+# USB Device Class drivers
+#
+CONFIG_USB_ACM=m
+CONFIG_USB_PRINTER=m
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+#
+
+#
+# may also be needed; see USB_STORAGE Help for more information
+#
+CONFIG_USB_STORAGE=m
+# CONFIG_USB_STORAGE_DEBUG is not set
+CONFIG_USB_STORAGE_DATAFAB=y
+CONFIG_USB_STORAGE_FREECOM=y
+CONFIG_USB_STORAGE_ISD200=y
+CONFIG_USB_STORAGE_DPCM=y
+CONFIG_USB_STORAGE_USBAT=y
+CONFIG_USB_STORAGE_SDDR09=y
+CONFIG_USB_STORAGE_SDDR55=y
+CONFIG_USB_STORAGE_JUMPSHOT=y
+CONFIG_USB_STORAGE_ALAUDA=y
+CONFIG_USB_LIBUSUAL=y
+
+#
+# USB Input Devices
+#
+CONFIG_USB_HID=y
+CONFIG_USB_HIDINPUT=y
+CONFIG_USB_HIDINPUT_POWERBOOK=y
+CONFIG_HID_FF=y
+CONFIG_HID_PID=y
+CONFIG_LOGITECH_FF=y
+CONFIG_THRUSTMASTER_FF=y
+CONFIG_USB_HIDDEV=y
+CONFIG_USB_AIPTEK=m
+CONFIG_USB_WACOM=m
+CONFIG_USB_ACECAD=m
+CONFIG_USB_KBTAB=m
+CONFIG_USB_POWERMATE=m
+CONFIG_USB_TOUCHSCREEN=m
+CONFIG_USB_TOUCHSCREEN_EGALAX=y
+CONFIG_USB_TOUCHSCREEN_PANJIT=y
+CONFIG_USB_TOUCHSCREEN_3M=y
+CONFIG_USB_TOUCHSCREEN_ITM=y
+# CONFIG_USB_YEALINK is not set
+CONFIG_USB_XPAD=m
+CONFIG_USB_ATI_REMOTE=m
+CONFIG_USB_ATI_REMOTE2=m
+CONFIG_USB_KEYSPAN_REMOTE=m
+CONFIG_USB_APPLETOUCH=m
+
+#
+# USB Imaging devices
+#
+CONFIG_USB_MDC800=m
+CONFIG_USB_MICROTEK=m
+
+#
+# USB Network Adapters
+#
+CONFIG_USB_CATC=m
+CONFIG_USB_KAWETH=m
+CONFIG_USB_PEGASUS=m
+CONFIG_USB_RTL8150=m
+CONFIG_USB_USBNET=m
+CONFIG_USB_NET_AX8817X=m
+CONFIG_USB_NET_CDCETHER=m
+CONFIG_USB_NET_GL620A=m
+CONFIG_USB_NET_NET1080=m
+CONFIG_USB_NET_PLUSB=m
+CONFIG_USB_NET_RNDIS_HOST=m
+CONFIG_USB_NET_CDC_SUBSET=m
+CONFIG_USB_ALI_M5632=y
+CONFIG_USB_AN2720=y
+CONFIG_USB_BELKIN=y
+CONFIG_USB_ARMLINUX=y
+CONFIG_USB_EPSON2888=y
+CONFIG_USB_NET_ZAURUS=m
+CONFIG_USB_MON=y
+
+#
+# USB port drivers
+#
+CONFIG_USB_USS720=m
+
+#
+# USB Serial Converter support
+#
+CONFIG_USB_SERIAL=m
+CONFIG_USB_SERIAL_GENERIC=y
+CONFIG_USB_SERIAL_AIRPRIME=m
+CONFIG_USB_SERIAL_ARK3116=m
+CONFIG_USB_SERIAL_BELKIN=m
+CONFIG_USB_SERIAL_WHITEHEAT=m
+CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m
+CONFIG_USB_SERIAL_CP2101=m
+CONFIG_USB_SERIAL_CYPRESS_M8=m
+CONFIG_USB_SERIAL_EMPEG=m
+CONFIG_USB_SERIAL_FTDI_SIO=m
+CONFIG_USB_SERIAL_FUNSOFT=m
+CONFIG_USB_SERIAL_VISOR=m
+CONFIG_USB_SERIAL_IPAQ=m
+CONFIG_USB_SERIAL_IR=m
+CONFIG_USB_SERIAL_EDGEPORT=m
+CONFIG_USB_SERIAL_EDGEPORT_TI=m
+CONFIG_USB_SERIAL_GARMIN=m
+CONFIG_USB_SERIAL_IPW=m
+CONFIG_USB_SERIAL_KEYSPAN_PDA=m
+CONFIG_USB_SERIAL_KEYSPAN=m
+CONFIG_USB_SERIAL_KEYSPAN_MPR=y
+CONFIG_USB_SERIAL_KEYSPAN_USA28=y
+CONFIG_USB_SERIAL_KEYSPAN_USA28X=y
+CONFIG_USB_SERIAL_KEYSPAN_USA28XA=y
+CONFIG_USB_SERIAL_KEYSPAN_USA28XB=y
+CONFIG_USB_SERIAL_KEYSPAN_USA19=y
+CONFIG_USB_SERIAL_KEYSPAN_USA18X=y
+CONFIG_USB_SERIAL_KEYSPAN_USA19W=y
+CONFIG_USB_SERIAL_KEYSPAN_USA19QW=y
+CONFIG_USB_SERIAL_KEYSPAN_USA19QI=y
+CONFIG_USB_SERIAL_KEYSPAN_USA49W=y
+CONFIG_USB_SERIAL_KEYSPAN_USA49WLC=y
+CONFIG_USB_SERIAL_KLSI=m
+CONFIG_USB_SERIAL_KOBIL_SCT=m
+CONFIG_USB_SERIAL_MCT_U232=m
+CONFIG_USB_SERIAL_NAVMAN=m
+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=m
+CONFIG_USB_SERIAL_TI=m
+CONFIG_USB_SERIAL_CYBERJACK=m
+CONFIG_USB_SERIAL_XIRCOM=m
+CONFIG_USB_SERIAL_OPTION=m
+CONFIG_USB_SERIAL_OMNINET=m
+CONFIG_USB_EZUSB=y
+
+#
+# USB Miscellaneous drivers
+#
+CONFIG_USB_EMI62=m
+CONFIG_USB_EMI26=m
+CONFIG_USB_AUERSWALD=m
+CONFIG_USB_RIO500=m
+CONFIG_USB_LEGOTOWER=m
+CONFIG_USB_LCD=m
+CONFIG_USB_LED=m
+# CONFIG_USB_CYPRESS_CY7C63 is not set
+# CONFIG_USB_CYTHERM is not set
+CONFIG_USB_PHIDGETKIT=m
+CONFIG_USB_PHIDGETSERVO=m
+CONFIG_USB_IDMOUSE=m
+CONFIG_USB_APPLEDISPLAY=m
+CONFIG_USB_SISUSBVGA=m
+CONFIG_USB_SISUSBVGA_CON=y
+CONFIG_USB_LD=m
+CONFIG_USB_TEST=m
+
+#
+# USB DSL modem support
+#
+CONFIG_USB_ATM=m
+CONFIG_USB_SPEEDTOUCH=m
+CONFIG_USB_CXACRU=m
+CONFIG_USB_UEAGLEATM=m
+CONFIG_USB_XUSBATM=m
+
+#
+# USB Gadget Support
+#
+# CONFIG_USB_GADGET is not set
+
+#
+# MMC/SD Card support
+#
+CONFIG_MMC=m
+# CONFIG_MMC_DEBUG is not set
+CONFIG_MMC_BLOCK=m
+CONFIG_MMC_SDHCI=m
+CONFIG_MMC_WBSD=m
+
+#
+# LED devices
+#
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+
+#
+# LED drivers
+#
+
+#
+# LED Triggers
+#
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_LEDS_TRIGGER_TIMER=m
+CONFIG_LEDS_TRIGGER_IDE_DISK=y
+CONFIG_LEDS_TRIGGER_HEARTBEAT=m
+
+#
+# InfiniBand support
+#
+# CONFIG_INFINIBAND is not set
+
+#
+# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
+#
+CONFIG_EDAC=y
+
+#
+# Reporting subsystems
+#
+# CONFIG_EDAC_DEBUG is not set
+CONFIG_EDAC_MM_EDAC=m
+CONFIG_EDAC_AMD76X=m
+CONFIG_EDAC_E7XXX=m
+CONFIG_EDAC_E752X=m
+CONFIG_EDAC_I82875P=m
+CONFIG_EDAC_I82860=m
+CONFIG_EDAC_K8=m
+CONFIG_EDAC_R82600=m
+CONFIG_EDAC_POLL=y
+
+#
+# Real Time Clock
+#
+CONFIG_RTC_LIB=m
+CONFIG_RTC_CLASS=m
+
+#
+# RTC interfaces
+#
+CONFIG_RTC_INTF_SYSFS=m
+CONFIG_RTC_INTF_PROC=m
+CONFIG_RTC_INTF_DEV=m
+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
+
+#
+# RTC drivers
+#
+CONFIG_RTC_DRV_X1205=m
+CONFIG_RTC_DRV_DS1307=m
+CONFIG_RTC_DRV_DS1553=m
+CONFIG_RTC_DRV_ISL1208=m
+CONFIG_RTC_DRV_DS1672=m
+CONFIG_RTC_DRV_DS1742=m
+CONFIG_RTC_DRV_PCF8563=m
+CONFIG_RTC_DRV_PCF8583=m
+CONFIG_RTC_DRV_RS5C372=m
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_TEST is not set
+CONFIG_RTC_DRV_V3020=m
+
+#
+# DMA Engine support
+#
+CONFIG_DMA_ENGINE=y
+
+#
+# DMA Clients
+#
+CONFIG_NET_DMA=y
+
+#
+# DMA Devices
+#
+CONFIG_INTEL_IOATDMA=m
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+CONFIG_EXT2_FS_POSIX_ACL=y
+CONFIG_EXT2_FS_SECURITY=y
+CONFIG_EXT2_FS_XIP=y
+CONFIG_FS_XIP=y
+CONFIG_EXT3_FS=m
+CONFIG_EXT3_FS_XATTR=y
+CONFIG_EXT3_FS_POSIX_ACL=y
+CONFIG_EXT3_FS_SECURITY=y
+CONFIG_JBD=m
+# CONFIG_JBD_DEBUG is not set
+CONFIG_FS_MBCACHE=y
+CONFIG_REISERFS_FS=m
+# CONFIG_REISERFS_CHECK is not set
+CONFIG_REISERFS_PROC_INFO=y
+CONFIG_REISERFS_FS_XATTR=y
+CONFIG_REISERFS_FS_POSIX_ACL=y
+CONFIG_REISERFS_FS_SECURITY=y
+CONFIG_JFS_FS=m
+CONFIG_JFS_POSIX_ACL=y
+CONFIG_JFS_SECURITY=y
+# CONFIG_JFS_DEBUG is not set
+# CONFIG_JFS_STATISTICS is not set
+CONFIG_FS_POSIX_ACL=y
+CONFIG_XFS_FS=m
+CONFIG_XFS_QUOTA=y
+CONFIG_XFS_SECURITY=y
+CONFIG_XFS_POSIX_ACL=y
+# CONFIG_XFS_RT is not set
+CONFIG_OCFS2_FS=m
+# CONFIG_OCFS2_DEBUG_MASKLOG is not set
+CONFIG_MINIX_FS=m
+CONFIG_ROMFS_FS=m
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+CONFIG_QUOTA=y
+# CONFIG_QFMT_V1 is not set
+CONFIG_QFMT_V2=y
+CONFIG_QUOTACTL=y
+CONFIG_DNOTIFY=y
+CONFIG_AUTOFS_FS=m
+CONFIG_AUTOFS4_FS=m
+CONFIG_FUSE_FS=m
+
+#
+# Caches
+#
+CONFIG_FSCACHE=m
+
+#
+# CD-ROM/DVD Filesystems
+#
+CONFIG_ISO9660_FS=y
+CONFIG_JOLIET=y
+CONFIG_ZISOFS=y
+CONFIG_ZISOFS_FS=y
+CONFIG_UDF_FS=m
+CONFIG_UDF_NLS=y
+CONFIG_CACHEFILES=m
+CONFIG_CACHEFILES_DEBUG=y
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=m
+CONFIG_MSDOS_FS=m
+CONFIG_VFAT_FS=m
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="ascii"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+CONFIG_HUGETLBFS=y
+CONFIG_HUGETLB_PAGE=y
+CONFIG_RAMFS=y
+CONFIG_CONFIGFS_FS=m
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+CONFIG_AFFS_FS=m
+CONFIG_HFS_FS=m
+CONFIG_HFSPLUS_FS=m
+CONFIG_BEFS_FS=m
+# CONFIG_BEFS_DEBUG is not set
+CONFIG_BFS_FS=m
+CONFIG_EFS_FS=m
+# CONFIG_JFFS_FS is not set
+CONFIG_JFFS2_FS=m
+CONFIG_JFFS2_FS_DEBUG=0
+CONFIG_JFFS2_FS_WRITEBUFFER=y
+CONFIG_JFFS2_SUMMARY=y
+# 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=m
+CONFIG_SQUASHFS=m
+# CONFIG_SQUASHFS_EMBEDDED is not set
+CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3
+# CONFIG_SQUASHFS_VMALLOC is not set
+CONFIG_VXFS_FS=m
+# CONFIG_HPFS_FS is not set
+CONFIG_QNX4FS_FS=m
+CONFIG_SYSV_FS=m
+CONFIG_UFS_FS=m
+# CONFIG_UFS_FS_WRITE is not set
+# CONFIG_UFS_DEBUG is not set
+
+#
+# Network File Systems
+#
+CONFIG_NFS_FS=m
+CONFIG_NFS_V3=y
+CONFIG_NFS_V3_ACL=y
+CONFIG_NFS_V4=y
+CONFIG_NFS_FSCACHE=y
+CONFIG_NFS_DIRECTIO=y
+CONFIG_NFSD=m
+CONFIG_NFSD_V2_ACL=y
+CONFIG_NFSD_V3=y
+CONFIG_NFSD_V3_ACL=y
+CONFIG_NFSD_V4=y
+CONFIG_NFSD_TCP=y
+CONFIG_LOCKD=m
+CONFIG_LOCKD_V4=y
+CONFIG_EXPORTFS=m
+CONFIG_NFS_ACL_SUPPORT=m
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=m
+CONFIG_SUNRPC_GSS=m
+CONFIG_RPCSEC_GSS_KRB5=m
+CONFIG_RPCSEC_GSS_SPKM3=m
+# CONFIG_SMB_FS is not set
+CONFIG_CIFS=m
+# CONFIG_CIFS_STATS is not set
+CONFIG_CIFS_WEAK_PW_HASH=y
+CONFIG_CIFS_XATTR=y
+CONFIG_CIFS_POSIX=y
+# CONFIG_CIFS_DEBUG2 is not set
+# CONFIG_CIFS_EXPERIMENTAL is not set
+CONFIG_NCP_FS=m
+CONFIG_NCPFS_PACKET_SIGNING=y
+CONFIG_NCPFS_IOCTL_LOCKING=y
+CONFIG_NCPFS_STRONG=y
+CONFIG_NCPFS_NFS_NS=y
+CONFIG_NCPFS_OS2_NS=y
+CONFIG_NCPFS_SMALLDOS=y
+CONFIG_NCPFS_NLS=y
+CONFIG_NCPFS_EXTRAS=y
+CONFIG_CODA_FS=m
+# CONFIG_CODA_FS_OLD_API is not set
+# CONFIG_AFS_FS is not set
+CONFIG_9P_FS=m
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+CONFIG_OSF_PARTITION=y
+CONFIG_AMIGA_PARTITION=y
+# CONFIG_ATARI_PARTITION is not set
+CONFIG_MAC_PARTITION=y
+CONFIG_MSDOS_PARTITION=y
+CONFIG_BSD_DISKLABEL=y
+CONFIG_MINIX_SUBPARTITION=y
+CONFIG_SOLARIS_X86_PARTITION=y
+CONFIG_UNIXWARE_DISKLABEL=y
+# CONFIG_LDM_PARTITION is not set
+CONFIG_SGI_PARTITION=y
+# CONFIG_ULTRIX_PARTITION is not set
+CONFIG_SUN_PARTITION=y
+CONFIG_KARMA_PARTITION=y
+CONFIG_EFI_PARTITION=y
+
+#
+# Native Language Support
+#
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="utf8"
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_CODEPAGE_737=m
+CONFIG_NLS_CODEPAGE_775=m
+CONFIG_NLS_CODEPAGE_850=m
+CONFIG_NLS_CODEPAGE_852=m
+CONFIG_NLS_CODEPAGE_855=m
+CONFIG_NLS_CODEPAGE_857=m
+CONFIG_NLS_CODEPAGE_860=m
+CONFIG_NLS_CODEPAGE_861=m
+CONFIG_NLS_CODEPAGE_862=m
+CONFIG_NLS_CODEPAGE_863=m
+CONFIG_NLS_CODEPAGE_864=m
+CONFIG_NLS_CODEPAGE_865=m
+CONFIG_NLS_CODEPAGE_866=m
+CONFIG_NLS_CODEPAGE_869=m
+CONFIG_NLS_CODEPAGE_936=m
+CONFIG_NLS_CODEPAGE_950=m
+CONFIG_NLS_CODEPAGE_932=m
+CONFIG_NLS_CODEPAGE_949=m
+CONFIG_NLS_CODEPAGE_874=m
+CONFIG_NLS_ISO8859_8=m
+CONFIG_NLS_CODEPAGE_1250=m
+CONFIG_NLS_CODEPAGE_1251=m
+CONFIG_NLS_ASCII=y
+CONFIG_NLS_ISO8859_1=m
+CONFIG_NLS_ISO8859_2=m
+CONFIG_NLS_ISO8859_3=m
+CONFIG_NLS_ISO8859_4=m
+CONFIG_NLS_ISO8859_5=m
+CONFIG_NLS_ISO8859_6=m
+CONFIG_NLS_ISO8859_7=m
+CONFIG_NLS_ISO8859_9=m
+CONFIG_NLS_ISO8859_13=m
+CONFIG_NLS_ISO8859_14=m
+CONFIG_NLS_ISO8859_15=m
+CONFIG_NLS_KOI8_R=m
+CONFIG_NLS_KOI8_U=m
+CONFIG_NLS_UTF8=m
+
+#
+# Instrumentation Support
+#
+CONFIG_PROFILING=y
+CONFIG_OPROFILE=m
+CONFIG_KPROBES=y
+
+#
+# Kernel hacking
+#
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+# CONFIG_PRINTK_TIME is not set
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_UNUSED_SYMBOLS is not set
+CONFIG_DEBUG_KERNEL=y
+CONFIG_LOG_BUF_SHIFT=17
+CONFIG_DETECT_SOFTLOCKUP=y
+CONFIG_SCHEDSTATS=y
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
+CONFIG_DEBUG_SPINLOCK=y
+# 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=y
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+# CONFIG_DEBUG_KOBJECT is not set
+CONFIG_DEBUG_HIGHMEM=y
+CONFIG_DEBUG_BUGVERBOSE=y
+CONFIG_DEBUG_INFO=y
+CONFIG_DEBUG_FS=y
+# CONFIG_DEBUG_VM is not set
+CONFIG_DEBUG_LIST=y
+# CONFIG_FRAME_POINTER is not set
+CONFIG_UNWIND_INFO=y
+CONFIG_STACK_UNWIND=y
+# CONFIG_FORCED_INLINING is not set
+CONFIG_BOOT_DELAY=y
+# CONFIG_RCU_TORTURE_TEST is not set
+CONFIG_EARLY_PRINTK=y
+CONFIG_DEBUG_STACKOVERFLOW=y
+CONFIG_DEBUG_STACK_USAGE=y
+
+#
+# Page alloc debug is incompatible with Software Suspend on i386
+#
+CONFIG_DEBUG_RODATA=y
+CONFIG_4KSTACKS=y
+CONFIG_DOUBLEFAULT=y
+
+#
+# Security options
+#
+CONFIG_KEYS=y
+CONFIG_KEYS_DEBUG_PROC_KEYS=y
+CONFIG_SECURITY=y
+CONFIG_SECURITY_NETWORK=y
+# CONFIG_SECURITY_NETWORK_XFRM is not set
+CONFIG_SECURITY_CAPABILITIES=y
+# CONFIG_SECURITY_ROOTPLUG is not set
+# CONFIG_SECURITY_SECLVL is not set
+CONFIG_SECURITY_SELINUX=y
+CONFIG_SECURITY_SELINUX_BOOTPARAM=y
+CONFIG_SECURITY_SELINUX_BOOTPARAM_VALUE=1
+CONFIG_SECURITY_SELINUX_DISABLE=y
+CONFIG_SECURITY_SELINUX_DEVELOP=y
+CONFIG_SECURITY_SELINUX_AVC_STATS=y
+CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE=1
+# CONFIG_SECURITY_SELINUX_ENABLE_SECMARK_DEFAULT is not set
+# CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX is not set
+
+#
+# Cryptographic options
+#
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_NULL=m
+CONFIG_CRYPTO_MD4=m
+CONFIG_CRYPTO_MD5=m
+CONFIG_CRYPTO_SHA1=y
+CONFIG_CRYPTO_SHA256=m
+CONFIG_CRYPTO_SHA512=m
+CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_TGR192=m
+CONFIG_CRYPTO_DES=m
+CONFIG_CRYPTO_BLOWFISH=m
+CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_SERPENT=m
+CONFIG_CRYPTO_AES=m
+CONFIG_CRYPTO_AES_586=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_TEST is not set
+CONFIG_CRYPTO_SIGNATURE=y
+CONFIG_CRYPTO_SIGNATURE_DSA=y
+CONFIG_CRYPTO_MPILIB=y
+
+#
+# Hardware crypto devices
+#
+CONFIG_CRYPTO_DEV_PADLOCK=m
+CONFIG_CRYPTO_DEV_PADLOCK_AES=y
+
+#
+# Library routines
+#
+CONFIG_CRC_CCITT=m
+CONFIG_CRC16=m
+CONFIG_CRC32=y
+CONFIG_LIBCRC32C=m
+CONFIG_AUDIT_GENERIC=y
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=m
+CONFIG_REED_SOLOMON=m
+CONFIG_REED_SOLOMON_DEC16=y
+CONFIG_TEXTSEARCH=y
+CONFIG_TEXTSEARCH_KMP=m
+CONFIG_TEXTSEARCH_BM=m
+CONFIG_TEXTSEARCH_FSM=m
+CONFIG_PLIST=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_X86_BIOS_REBOOT=y
+CONFIG_KTIME_SCALAR=y
diff --git a/configs/kernel-2.6.18-i686-kdump.config b/configs/kernel-2.6.18-i686-kdump.config
new file mode 100644
index 000000000..8e2ca42b6
--- /dev/null
+++ b/configs/kernel-2.6.18-i686-kdump.config
@@ -0,0 +1,3413 @@
+# i386
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.18.2-rc1
+# Mon Nov 13 09:44:39 2006
+#
+CONFIG_X86_32=y
+CONFIG_GENERIC_TIME=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_SEMAPHORE_SLEEPERS=y
+CONFIG_X86=y
+CONFIG_MMU=y
+CONFIG_GENERIC_ISA_DMA=y
+CONFIG_GENERIC_IOMAP=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_ARCH_MAY_HAVE_PC_FDC=y
+CONFIG_DMI=y
+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=y
+CONFIG_SYSVIPC=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_BSD_PROCESS_ACCT=y
+# CONFIG_BSD_PROCESS_ACCT_V3 is not set
+CONFIG_TASKSTATS=y
+CONFIG_TASK_DELAY_ACCT=y
+CONFIG_AUDIT=y
+CONFIG_AUDITSYSCALL=y
+# CONFIG_IKCONFIG is not set
+CONFIG_RELAY=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+# CONFIG_EMBEDDED is not set
+CONFIG_UID16=y
+CONFIG_SYSCTL=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
+CONFIG_KALLSYMS_EXTRA_PASS=y
+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=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+CONFIG_MODULE_SIG=y
+# CONFIG_MODULE_SIG_FORCE is not set
+CONFIG_KMOD=y
+
+#
+# Process debugging support
+#
+CONFIG_UTRACE=y
+CONFIG_PTRACE=y
+
+#
+# Block layer
+#
+CONFIG_LBD=y
+CONFIG_BLK_DEV_IO_TRACE=y
+CONFIG_LSF=y
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_DEFAULT_AS is not set
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+
+#
+# Processor type and features
+#
+# CONFIG_SMP is not set
+CONFIG_X86_PC=y
+# CONFIG_X86_XEN is not set
+# CONFIG_X86_ELAN is not set
+# CONFIG_X86_VOYAGER is not set
+# CONFIG_X86_NUMAQ is not set
+# CONFIG_X86_SUMMIT is not set
+# CONFIG_X86_BIGSMP is not set
+# CONFIG_X86_VISWS is not set
+# CONFIG_X86_GENERICARCH is not set
+# CONFIG_X86_ES7000 is not set
+# CONFIG_M386 is not set
+# CONFIG_M486 is not set
+# CONFIG_M586 is not set
+# CONFIG_M586TSC is not set
+# CONFIG_M586MMX is not set
+CONFIG_M686=y
+# CONFIG_MPENTIUMII is not set
+# CONFIG_MPENTIUMIII is not set
+# CONFIG_MPENTIUMM is not set
+# CONFIG_MPENTIUM4 is not set
+# CONFIG_MK6 is not set
+# CONFIG_MK7 is not set
+# CONFIG_MK8 is not set
+# CONFIG_MCRUSOE is not set
+# CONFIG_MEFFICEON is not set
+# CONFIG_MWINCHIPC6 is not set
+# CONFIG_MWINCHIP2 is not set
+# CONFIG_MWINCHIP3D is not set
+# CONFIG_MGEODEGX1 is not set
+# CONFIG_MGEODE_LX is not set
+# CONFIG_MCYRIXIII is not set
+# CONFIG_MVIAC3_2 is not set
+CONFIG_X86_GENERIC=y
+CONFIG_X86_CMPXCHG=y
+CONFIG_X86_XADD=y
+CONFIG_X86_L1_CACHE_SHIFT=7
+CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_X86_PPRO_FENCE=y
+CONFIG_X86_WP_WORKS_OK=y
+CONFIG_X86_INVLPG=y
+CONFIG_X86_BSWAP=y
+CONFIG_X86_POPAD_OK=y
+CONFIG_X86_CMPXCHG64=y
+CONFIG_X86_GOOD_APIC=y
+CONFIG_X86_INTEL_USERCOPY=y
+CONFIG_X86_USE_PPRO_CHECKSUM=y
+CONFIG_X86_TSC=y
+CONFIG_HPET_TIMER=y
+CONFIG_HPET_EMULATE_RTC=y
+# CONFIG_PREEMPT_NONE is not set
+CONFIG_PREEMPT_VOLUNTARY=y
+# CONFIG_PREEMPT is not set
+CONFIG_X86_UP_APIC=y
+CONFIG_X86_UP_IOAPIC=y
+CONFIG_X86_LOCAL_APIC=y
+CONFIG_X86_APIC_AUTO=y
+CONFIG_X86_IO_APIC=y
+CONFIG_X86_MCE=y
+# CONFIG_X86_MCE_NONFATAL is not set
+CONFIG_X86_MCE_P4THERMAL=y
+CONFIG_VM86=y
+CONFIG_TOSHIBA=m
+CONFIG_I8K=m
+# CONFIG_X86_REBOOTFIXUPS is not set
+CONFIG_MICROCODE=m
+CONFIG_X86_MSR=m
+CONFIG_X86_CPUID=m
+# CONFIG_SWIOTLB is not set
+
+#
+# Firmware Drivers
+#
+CONFIG_EDD=m
+CONFIG_EFI_VARS=y
+CONFIG_DELL_RBU=m
+CONFIG_DCDBAS=m
+# CONFIG_NOHIGHMEM is not set
+# CONFIG_HIGHMEM4G is not set
+CONFIG_HIGHMEM64G=y
+CONFIG_PAGE_OFFSET=0xC0000000
+CONFIG_HIGHMEM=y
+CONFIG_X86_PAE=y
+CONFIG_ARCH_FLATMEM_ENABLE=y
+CONFIG_ARCH_SPARSEMEM_ENABLE=y
+CONFIG_ARCH_SELECT_MEMORY_MODEL=y
+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=y
+CONFIG_SPLIT_PTLOCK_CPUS=4096
+CONFIG_RESOURCES_64BIT=y
+CONFIG_HIGHPTE=y
+# CONFIG_MATH_EMULATION is not set
+CONFIG_MTRR=y
+CONFIG_EFI=y
+CONFIG_BOOT_IOREMAP=y
+CONFIG_REGPARM=y
+# CONFIG_SECCOMP is not set
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
+CONFIG_KEXEC=y
+CONFIG_CRASH_DUMP=y
+CONFIG_PHYSICAL_START=0x1000000
+# CONFIG_COMPAT_VDSO is not set
+CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
+
+#
+# Power management options (ACPI, APM)
+#
+CONFIG_PM=y
+CONFIG_PM_LEGACY=y
+# CONFIG_PM_DEBUG is not set
+
+#
+# ACPI (Advanced Configuration and Power Interface) Support
+#
+CONFIG_ACPI=y
+CONFIG_ACPI_SLEEP=y
+CONFIG_ACPI_SLEEP_PROC_FS=y
+# CONFIG_ACPI_SLEEP_PROC_SLEEP is not set
+CONFIG_ACPI_AC=m
+CONFIG_ACPI_BATTERY=m
+CONFIG_ACPI_BUTTON=m
+CONFIG_ACPI_VIDEO=m
+# CONFIG_ACPI_HOTKEY is not set
+CONFIG_ACPI_FAN=y
+CONFIG_ACPI_DOCK=m
+CONFIG_ACPI_PROCESSOR=y
+CONFIG_ACPI_THERMAL=y
+CONFIG_ACPI_ASUS=m
+CONFIG_ACPI_IBM=m
+CONFIG_ACPI_TOSHIBA=m
+CONFIG_ACPI_BLACKLIST_YEAR=1999
+# CONFIG_ACPI_DEBUG is not set
+CONFIG_ACPI_EC=y
+CONFIG_ACPI_POWER=y
+CONFIG_ACPI_SYSTEM=y
+CONFIG_X86_PM_TIMER=y
+CONFIG_ACPI_CONTAINER=m
+CONFIG_ACPI_SBS=m
+
+#
+# APM (Advanced Power Management) BIOS Support
+#
+CONFIG_APM=y
+# CONFIG_APM_IGNORE_USER_SUSPEND is not set
+# CONFIG_APM_DO_ENABLE is not set
+CONFIG_APM_CPU_IDLE=y
+# CONFIG_APM_DISPLAY_BLANK is not set
+CONFIG_APM_RTC_IS_GMT=y
+# CONFIG_APM_ALLOW_INTS is not set
+# CONFIG_APM_REAL_MODE_POWER_OFF is not set
+
+#
+# CPU Frequency scaling
+#
+CONFIG_CPU_FREQ=y
+CONFIG_CPU_FREQ_TABLE=y
+CONFIG_CPU_FREQ_DEBUG=y
+CONFIG_CPU_FREQ_STAT=m
+CONFIG_CPU_FREQ_STAT_DETAILS=y
+# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set
+CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE=y
+CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
+CONFIG_CPU_FREQ_GOV_POWERSAVE=m
+CONFIG_CPU_FREQ_GOV_USERSPACE=y
+CONFIG_CPU_FREQ_GOV_ONDEMAND=m
+CONFIG_CPU_FREQ_GOV_CONSERVATIVE=m
+
+#
+# CPUFreq processor drivers
+#
+CONFIG_X86_ACPI_CPUFREQ=m
+# CONFIG_X86_POWERNOW_K6 is not set
+CONFIG_X86_POWERNOW_K7=y
+CONFIG_X86_POWERNOW_K7_ACPI=y
+CONFIG_X86_POWERNOW_K8=y
+CONFIG_X86_POWERNOW_K8_ACPI=y
+# CONFIG_X86_GX_SUSPMOD is not set
+CONFIG_X86_SPEEDSTEP_CENTRINO=y
+CONFIG_X86_SPEEDSTEP_CENTRINO_ACPI=y
+CONFIG_X86_SPEEDSTEP_CENTRINO_TABLE=y
+CONFIG_X86_SPEEDSTEP_ICH=y
+CONFIG_X86_SPEEDSTEP_SMI=y
+CONFIG_X86_P4_CLOCKMOD=m
+# CONFIG_X86_CPUFREQ_NFORCE2 is not set
+CONFIG_X86_LONGRUN=y
+# CONFIG_X86_LONGHAUL is not set
+
+#
+# shared options
+#
+# CONFIG_X86_ACPI_CPUFREQ_PROC_INTF is not set
+CONFIG_X86_SPEEDSTEP_LIB=y
+# CONFIG_X86_SPEEDSTEP_RELAXED_CAP_CHECK is not set
+
+#
+# Bus options (PCI, PCMCIA, EISA, MCA, ISA)
+#
+CONFIG_PCI=y
+# CONFIG_PCI_GOBIOS is not set
+# CONFIG_PCI_GOMMCONFIG is not set
+# CONFIG_PCI_GODIRECT is not set
+# CONFIG_PCI_GOXEN_FE is not set
+CONFIG_PCI_GOANY=y
+CONFIG_PCI_BIOS=y
+CONFIG_PCI_DIRECT=y
+CONFIG_PCI_MMCONFIG=y
+CONFIG_PCIEPORTBUS=y
+CONFIG_HOTPLUG_PCI_PCIE=m
+# CONFIG_HOTPLUG_PCI_PCIE_POLL_EVENT_MODE is not set
+CONFIG_PCI_MSI=y
+# CONFIG_PCI_DEBUG is not set
+CONFIG_ISA_DMA_API=y
+CONFIG_ISA=y
+# CONFIG_EISA is not set
+# CONFIG_MCA is not set
+# CONFIG_SCx200 is not set
+CONFIG_K8_NB=y
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+CONFIG_PCCARD=y
+# CONFIG_PCMCIA_DEBUG is not set
+CONFIG_PCMCIA=y
+CONFIG_PCMCIA_LOAD_CIS=y
+CONFIG_PCMCIA_IOCTL=y
+CONFIG_CARDBUS=y
+
+#
+# PC-card bridges
+#
+CONFIG_YENTA=y
+CONFIG_YENTA_O2=y
+CONFIG_YENTA_RICOH=y
+CONFIG_YENTA_TI=y
+CONFIG_YENTA_ENE_TUNE=y
+CONFIG_YENTA_TOSHIBA=y
+CONFIG_PD6729=m
+CONFIG_I82092=m
+# CONFIG_I82365 is not set
+# CONFIG_TCIC is not set
+CONFIG_PCMCIA_PROBE=y
+CONFIG_PCCARD_NONSTATIC=y
+
+#
+# PCI Hotplug Support
+#
+CONFIG_HOTPLUG_PCI=y
+CONFIG_HOTPLUG_PCI_FAKE=m
+CONFIG_HOTPLUG_PCI_COMPAQ=m
+# CONFIG_HOTPLUG_PCI_COMPAQ_NVRAM is not set
+CONFIG_HOTPLUG_PCI_IBM=m
+CONFIG_HOTPLUG_PCI_ACPI=m
+CONFIG_HOTPLUG_PCI_ACPI_IBM=m
+# CONFIG_HOTPLUG_PCI_CPCI is not set
+# CONFIG_HOTPLUG_PCI_SHPC is not set
+
+#
+# Executable file formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_AOUT is not set
+CONFIG_BINFMT_MISC=y
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+# CONFIG_NETDEBUG is not set
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=y
+CONFIG_NET_KEY=m
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_ASK_IP_FIB_HASH=y
+# 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
+# CONFIG_IP_PNP is not set
+CONFIG_NET_IPIP=m
+CONFIG_NET_IPGRE=m
+CONFIG_NET_IPGRE_BROADCAST=y
+CONFIG_IP_MROUTE=y
+CONFIG_IP_PIMSM_V1=y
+CONFIG_IP_PIMSM_V2=y
+# CONFIG_ARPD is not set
+CONFIG_SYN_COOKIES=y
+CONFIG_INET_AH=m
+CONFIG_INET_ESP=m
+CONFIG_INET_IPCOMP=m
+CONFIG_INET_XFRM_TUNNEL=m
+CONFIG_INET_TUNNEL=m
+CONFIG_INET_XFRM_MODE_TRANSPORT=m
+CONFIG_INET_XFRM_MODE_TUNNEL=m
+CONFIG_INET_DIAG=m
+CONFIG_INET_TCP_DIAG=m
+CONFIG_TCP_CONG_ADVANCED=y
+
+#
+# TCP congestion control
+#
+CONFIG_TCP_CONG_BIC=y
+CONFIG_TCP_CONG_CUBIC=m
+CONFIG_TCP_CONG_WESTWOOD=m
+CONFIG_TCP_CONG_HTCP=m
+CONFIG_TCP_CONG_HSTCP=m
+CONFIG_TCP_CONG_HYBLA=m
+CONFIG_TCP_CONG_VEGAS=m
+CONFIG_TCP_CONG_SCALABLE=m
+CONFIG_TCP_CONG_LP=m
+CONFIG_TCP_CONG_VENO=m
+
+#
+# IP: Virtual Server Configuration
+#
+CONFIG_IP_VS=m
+# CONFIG_IP_VS_DEBUG is not set
+CONFIG_IP_VS_TAB_BITS=12
+
+#
+# IPVS transport protocol load balancing support
+#
+CONFIG_IP_VS_PROTO_TCP=y
+CONFIG_IP_VS_PROTO_UDP=y
+CONFIG_IP_VS_PROTO_ESP=y
+CONFIG_IP_VS_PROTO_AH=y
+
+#
+# IPVS scheduler
+#
+CONFIG_IP_VS_RR=m
+CONFIG_IP_VS_WRR=m
+CONFIG_IP_VS_LC=m
+CONFIG_IP_VS_WLC=m
+CONFIG_IP_VS_LBLC=m
+CONFIG_IP_VS_LBLCR=m
+CONFIG_IP_VS_DH=m
+CONFIG_IP_VS_SH=m
+CONFIG_IP_VS_SED=m
+CONFIG_IP_VS_NQ=m
+
+#
+# IPVS application helper
+#
+CONFIG_IP_VS_FTP=m
+CONFIG_IPV6=m
+CONFIG_IPV6_PRIVACY=y
+CONFIG_IPV6_ROUTER_PREF=y
+CONFIG_IPV6_ROUTE_INFO=y
+CONFIG_INET6_AH=m
+CONFIG_INET6_ESP=m
+CONFIG_INET6_IPCOMP=m
+CONFIG_INET6_XFRM_TUNNEL=m
+CONFIG_INET6_TUNNEL=m
+CONFIG_INET6_XFRM_MODE_TRANSPORT=m
+CONFIG_INET6_XFRM_MODE_TUNNEL=m
+CONFIG_IPV6_TUNNEL=m
+CONFIG_NETWORK_SECMARK=y
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_DEBUG is not set
+CONFIG_BRIDGE_NETFILTER=y
+
+#
+# Core Netfilter Configuration
+#
+CONFIG_NETFILTER_NETLINK=m
+CONFIG_NETFILTER_NETLINK_QUEUE=m
+CONFIG_NETFILTER_NETLINK_LOG=m
+CONFIG_NETFILTER_XTABLES=m
+CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
+CONFIG_NETFILTER_XT_TARGET_CONNMARK=m
+CONFIG_NETFILTER_XT_TARGET_MARK=m
+CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
+CONFIG_NETFILTER_XT_TARGET_NOTRACK=m
+CONFIG_NETFILTER_XT_TARGET_SECMARK=m
+CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=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_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_PHYSDEV=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
+
+#
+# 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=m
+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_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_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_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
+CONFIG_IP_NF_ARPTABLES=m
+CONFIG_IP_NF_ARPFILTER=m
+CONFIG_IP_NF_ARP_MANGLE=m
+
+#
+# IPv6: Netfilter Configuration (EXPERIMENTAL)
+#
+CONFIG_IP6_NF_QUEUE=m
+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_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
+
+#
+# DECnet: Netfilter Configuration
+#
+# CONFIG_DECNET_NF_GRABULATOR is not set
+
+#
+# Bridge: Netfilter Configuration
+#
+CONFIG_BRIDGE_NF_EBTABLES=m
+CONFIG_BRIDGE_EBT_BROUTE=m
+CONFIG_BRIDGE_EBT_T_FILTER=m
+CONFIG_BRIDGE_EBT_T_NAT=m
+CONFIG_BRIDGE_EBT_802_3=m
+CONFIG_BRIDGE_EBT_AMONG=m
+CONFIG_BRIDGE_EBT_ARP=m
+CONFIG_BRIDGE_EBT_IP=m
+CONFIG_BRIDGE_EBT_LIMIT=m
+CONFIG_BRIDGE_EBT_MARK=m
+CONFIG_BRIDGE_EBT_PKTTYPE=m
+CONFIG_BRIDGE_EBT_STP=m
+CONFIG_BRIDGE_EBT_VLAN=m
+CONFIG_BRIDGE_EBT_ARPREPLY=m
+CONFIG_BRIDGE_EBT_DNAT=m
+CONFIG_BRIDGE_EBT_MARK_T=m
+CONFIG_BRIDGE_EBT_REDIRECT=m
+CONFIG_BRIDGE_EBT_SNAT=m
+CONFIG_BRIDGE_EBT_LOG=m
+CONFIG_BRIDGE_EBT_ULOG=m
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+CONFIG_IP_DCCP=m
+CONFIG_INET_DCCP_DIAG=m
+CONFIG_IP_DCCP_ACKVEC=y
+
+#
+# DCCP CCIDs Configuration (EXPERIMENTAL)
+#
+CONFIG_IP_DCCP_CCID2=m
+CONFIG_IP_DCCP_CCID3=m
+CONFIG_IP_DCCP_TFRC_LIB=m
+
+#
+# DCCP Kernel Hacking
+#
+# CONFIG_IP_DCCP_DEBUG is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+CONFIG_IP_SCTP=m
+# CONFIG_SCTP_DBG_MSG is not set
+# CONFIG_SCTP_DBG_OBJCNT is not set
+# CONFIG_SCTP_HMAC_NONE is not set
+# CONFIG_SCTP_HMAC_SHA1 is not set
+CONFIG_SCTP_HMAC_MD5=y
+
+#
+# TIPC Configuration (EXPERIMENTAL)
+#
+CONFIG_TIPC=m
+# CONFIG_TIPC_ADVANCED is not set
+# CONFIG_TIPC_DEBUG is not set
+CONFIG_ATM=m
+CONFIG_ATM_CLIP=m
+# CONFIG_ATM_CLIP_NO_ICMP is not set
+CONFIG_ATM_LANE=m
+# CONFIG_ATM_MPOA is not set
+CONFIG_ATM_BR2684=m
+# CONFIG_ATM_BR2684_IPFILTER is not set
+CONFIG_BRIDGE=m
+CONFIG_VLAN_8021Q=m
+CONFIG_DECNET=m
+CONFIG_DECNET_ROUTER=y
+CONFIG_DECNET_ROUTE_FWMARK=y
+CONFIG_LLC=y
+# CONFIG_LLC2 is not set
+CONFIG_IPX=m
+# CONFIG_IPX_INTERN is not set
+CONFIG_ATALK=m
+CONFIG_DEV_APPLETALK=m
+# CONFIG_LTPC is not set
+# CONFIG_COPS is not set
+CONFIG_IPDDP=m
+CONFIG_IPDDP_ENCAP=y
+CONFIG_IPDDP_DECAP=y
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+CONFIG_WAN_ROUTER=m
+
+#
+# QoS and/or fair queueing
+#
+CONFIG_NET_SCHED=y
+# CONFIG_NET_SCH_CLK_JIFFIES is not set
+CONFIG_NET_SCH_CLK_GETTIMEOFDAY=y
+# CONFIG_NET_SCH_CLK_CPU is not set
+
+#
+# Queueing/Scheduling
+#
+CONFIG_NET_SCH_CBQ=m
+CONFIG_NET_SCH_HTB=m
+CONFIG_NET_SCH_HFSC=m
+CONFIG_NET_SCH_ATM=m
+CONFIG_NET_SCH_PRIO=m
+CONFIG_NET_SCH_RED=m
+CONFIG_NET_SCH_SFQ=m
+CONFIG_NET_SCH_TEQL=m
+CONFIG_NET_SCH_TBF=m
+CONFIG_NET_SCH_GRED=m
+CONFIG_NET_SCH_DSMARK=m
+CONFIG_NET_SCH_NETEM=m
+CONFIG_NET_SCH_INGRESS=m
+
+#
+# Classification
+#
+CONFIG_NET_CLS=y
+CONFIG_NET_CLS_BASIC=m
+CONFIG_NET_CLS_TCINDEX=m
+CONFIG_NET_CLS_ROUTE4=m
+CONFIG_NET_CLS_ROUTE=y
+CONFIG_NET_CLS_FW=m
+CONFIG_NET_CLS_U32=m
+CONFIG_CLS_U32_PERF=y
+CONFIG_CLS_U32_MARK=y
+CONFIG_NET_CLS_RSVP=m
+CONFIG_NET_CLS_RSVP6=m
+CONFIG_NET_EMATCH=y
+CONFIG_NET_EMATCH_STACK=32
+CONFIG_NET_EMATCH_CMP=m
+CONFIG_NET_EMATCH_NBYTE=m
+CONFIG_NET_EMATCH_U32=m
+CONFIG_NET_EMATCH_META=m
+CONFIG_NET_EMATCH_TEXT=m
+CONFIG_NET_CLS_ACT=y
+CONFIG_NET_ACT_POLICE=m
+CONFIG_NET_ACT_GACT=m
+CONFIG_GACT_PROB=y
+CONFIG_NET_ACT_MIRRED=m
+CONFIG_NET_ACT_IPT=m
+CONFIG_NET_ACT_PEDIT=m
+CONFIG_NET_ACT_SIMP=m
+CONFIG_NET_CLS_IND=y
+CONFIG_NET_ESTIMATOR=y
+
+#
+# Network testing
+#
+CONFIG_NET_PKTGEN=m
+# CONFIG_NET_TCPPROBE is not set
+# CONFIG_HAMRADIO is not set
+CONFIG_IRDA=m
+
+#
+# IrDA protocols
+#
+CONFIG_IRLAN=m
+CONFIG_IRNET=m
+CONFIG_IRCOMM=m
+# CONFIG_IRDA_ULTRA is not set
+
+#
+# IrDA options
+#
+CONFIG_IRDA_CACHE_LAST_LSAP=y
+CONFIG_IRDA_FAST_RR=y
+# CONFIG_IRDA_DEBUG is not set
+
+#
+# Infrared-port device drivers
+#
+
+#
+# SIR device drivers
+#
+CONFIG_IRTTY_SIR=m
+
+#
+# Dongle support
+#
+CONFIG_DONGLE=y
+CONFIG_ESI_DONGLE=m
+CONFIG_ACTISYS_DONGLE=m
+CONFIG_TEKRAM_DONGLE=m
+CONFIG_TOIM3232_DONGLE=m
+CONFIG_LITELINK_DONGLE=m
+CONFIG_MA600_DONGLE=m
+CONFIG_GIRBIL_DONGLE=m
+CONFIG_MCP2120_DONGLE=m
+CONFIG_OLD_BELKIN_DONGLE=m
+CONFIG_ACT200L_DONGLE=m
+
+#
+# Old SIR device drivers
+#
+CONFIG_IRPORT_SIR=m
+
+#
+# Old Serial dongle support
+#
+# CONFIG_DONGLE_OLD is not set
+
+#
+# FIR device drivers
+#
+CONFIG_USB_IRDA=m
+CONFIG_SIGMATEL_FIR=m
+CONFIG_NSC_FIR=m
+CONFIG_WINBOND_FIR=m
+CONFIG_TOSHIBA_FIR=m
+CONFIG_SMC_IRCC_FIR=m
+CONFIG_ALI_FIR=m
+CONFIG_VLSI_FIR=m
+CONFIG_VIA_FIR=m
+CONFIG_MCS_FIR=m
+CONFIG_BT=m
+CONFIG_BT_L2CAP=m
+CONFIG_BT_SCO=m
+CONFIG_BT_RFCOMM=m
+CONFIG_BT_RFCOMM_TTY=y
+CONFIG_BT_BNEP=m
+CONFIG_BT_BNEP_MC_FILTER=y
+CONFIG_BT_BNEP_PROTO_FILTER=y
+CONFIG_BT_CMTP=m
+CONFIG_BT_HIDP=m
+
+#
+# Bluetooth device drivers
+#
+CONFIG_BT_HCIUSB=m
+CONFIG_BT_HCIUSB_SCO=y
+CONFIG_BT_HCIUART=m
+CONFIG_BT_HCIUART_H4=y
+CONFIG_BT_HCIUART_BCSP=y
+CONFIG_BT_HCIBCM203X=m
+CONFIG_BT_HCIBPA10X=m
+CONFIG_BT_HCIBFUSB=m
+CONFIG_BT_HCIDTL1=m
+CONFIG_BT_HCIBT3C=m
+CONFIG_BT_HCIBLUECARD=m
+CONFIG_BT_HCIBTUART=m
+CONFIG_BT_HCIVHCI=m
+CONFIG_IEEE80211=m
+# CONFIG_IEEE80211_DEBUG is not set
+CONFIG_IEEE80211_CRYPT_WEP=m
+CONFIG_IEEE80211_CRYPT_CCMP=m
+CONFIG_IEEE80211_CRYPT_TKIP=m
+CONFIG_IEEE80211_SOFTMAC=m
+CONFIG_IEEE80211_SOFTMAC_DEBUG=y
+CONFIG_TUX=m
+
+#
+# TUX options
+#
+CONFIG_TUX_EXTCGI=y
+CONFIG_TUX_EXTENDED_LOG=y
+# CONFIG_TUX_DEBUG is not set
+CONFIG_WIRELESS_EXT=y
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_SYS_HYPERVISOR is not set
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+CONFIG_CONNECTOR=y
+CONFIG_PROC_EVENTS=y
+
+#
+# Memory Technology Devices (MTD)
+#
+CONFIG_MTD=m
+# CONFIG_MTD_DEBUG is not set
+CONFIG_MTD_CONCAT=m
+CONFIG_MTD_PARTITIONS=y
+CONFIG_MTD_REDBOOT_PARTS=m
+CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1
+# CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED is not set
+# CONFIG_MTD_REDBOOT_PARTS_READONLY is not set
+CONFIG_MTD_CMDLINE_PARTS=y
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=m
+CONFIG_MTD_BLOCK=m
+CONFIG_MTD_BLOCK_RO=m
+CONFIG_FTL=m
+CONFIG_NFTL=m
+CONFIG_NFTL_RW=y
+CONFIG_INFTL=m
+CONFIG_RFD_FTL=m
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=m
+CONFIG_MTD_JEDECPROBE=m
+CONFIG_MTD_GEN_PROBE=m
+# CONFIG_MTD_CFI_ADV_OPTIONS 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_CFI_INTELEXT=m
+CONFIG_MTD_CFI_AMDSTD=m
+CONFIG_MTD_CFI_STAA=m
+CONFIG_MTD_CFI_UTIL=m
+CONFIG_MTD_RAM=m
+CONFIG_MTD_ROM=m
+CONFIG_MTD_ABSENT=m
+# CONFIG_MTD_OBSOLETE_CHIPS is not set
+
+#
+# Mapping drivers for chip access
+#
+CONFIG_MTD_COMPLEX_MAPPINGS=y
+# CONFIG_MTD_PHYSMAP is not set
+# CONFIG_MTD_PNC2000 is not set
+CONFIG_MTD_SC520CDP=m
+CONFIG_MTD_NETSC520=m
+CONFIG_MTD_TS5500=m
+# CONFIG_MTD_SBC_GXX is not set
+# CONFIG_MTD_AMD76XROM is not set
+# CONFIG_MTD_ICHXROM is not set
+CONFIG_MTD_SCB2_FLASH=m
+# CONFIG_MTD_NETtel is not set
+# CONFIG_MTD_DILNETPC is not set
+# CONFIG_MTD_L440GX is not set
+CONFIG_MTD_PCI=m
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+CONFIG_MTD_PMC551=m
+# CONFIG_MTD_PMC551_BUGFIX is not set
+# CONFIG_MTD_PMC551_DEBUG is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+CONFIG_MTD_MTDRAM=m
+CONFIG_MTDRAM_TOTAL_SIZE=4096
+CONFIG_MTDRAM_ERASE_SIZE=128
+CONFIG_MTD_BLOCK2MTD=m
+
+#
+# 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=m
+# CONFIG_MTD_NAND_VERIFY_WRITE is not set
+CONFIG_MTD_NAND_ECC_SMC=y
+CONFIG_MTD_NAND_IDS=m
+CONFIG_MTD_NAND_DISKONCHIP=m
+# CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADVANCED is not set
+CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADDRESS=0
+# CONFIG_MTD_NAND_DISKONCHIP_BBTWRITE is not set
+CONFIG_MTD_NAND_CS553X=m
+CONFIG_MTD_NAND_NANDSIM=m
+
+#
+# OneNAND Flash Device Drivers
+#
+# CONFIG_MTD_ONENAND is not set
+
+#
+# Parallel port support
+#
+CONFIG_PARPORT=m
+CONFIG_PARPORT_PC=m
+CONFIG_PARPORT_SERIAL=m
+# CONFIG_PARPORT_PC_FIFO is not set
+# CONFIG_PARPORT_PC_SUPERIO is not set
+CONFIG_PARPORT_PC_PCMCIA=m
+CONFIG_PARPORT_NOT_PC=y
+# CONFIG_PARPORT_GSC is not set
+# CONFIG_PARPORT_AX88796 is not set
+CONFIG_PARPORT_1284=y
+
+#
+# Plug and Play support
+#
+CONFIG_PNP=y
+# CONFIG_PNP_DEBUG is not set
+
+#
+# Protocols
+#
+CONFIG_ISAPNP=y
+# CONFIG_PNPBIOS is not set
+CONFIG_PNPACPI=y
+
+#
+# Block devices
+#
+CONFIG_BLK_DEV_FD=m
+# CONFIG_BLK_DEV_XD is not set
+CONFIG_PARIDE=m
+CONFIG_PARIDE_PARPORT=m
+
+#
+# Parallel IDE high-level drivers
+#
+CONFIG_PARIDE_PD=m
+CONFIG_PARIDE_PCD=m
+CONFIG_PARIDE_PF=m
+CONFIG_PARIDE_PT=m
+CONFIG_PARIDE_PG=m
+
+#
+# Parallel IDE protocol modules
+#
+CONFIG_PARIDE_ATEN=m
+CONFIG_PARIDE_BPCK=m
+CONFIG_PARIDE_BPCK6=m
+CONFIG_PARIDE_COMM=m
+CONFIG_PARIDE_DSTR=m
+CONFIG_PARIDE_FIT2=m
+CONFIG_PARIDE_FIT3=m
+CONFIG_PARIDE_EPAT=m
+CONFIG_PARIDE_EPATC8=y
+CONFIG_PARIDE_EPIA=m
+CONFIG_PARIDE_FRIQ=m
+CONFIG_PARIDE_FRPW=m
+CONFIG_PARIDE_KBIC=m
+CONFIG_PARIDE_KTTI=m
+CONFIG_PARIDE_ON20=m
+CONFIG_PARIDE_ON26=m
+CONFIG_BLK_CPQ_DA=m
+CONFIG_BLK_CPQ_CISS_DA=m
+CONFIG_CISS_SCSI_TAPE=y
+CONFIG_BLK_DEV_DAC960=m
+CONFIG_BLK_DEV_UMEM=m
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=m
+CONFIG_BLK_DEV_CRYPTOLOOP=m
+CONFIG_BLK_DEV_NBD=m
+CONFIG_BLK_DEV_SX8=m
+CONFIG_BLK_DEV_UB=m
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=16384
+CONFIG_BLK_DEV_RAM_BLOCKSIZE=4096
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_CDROM_PKTCDVD=m
+CONFIG_CDROM_PKTCDVD_BUFFERS=8
+# CONFIG_CDROM_PKTCDVD_WCACHE is not set
+CONFIG_ATA_OVER_ETH=m
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+CONFIG_IDE=y
+CONFIG_BLK_DEV_IDE=y
+
+#
+# Please see Documentation/ide.txt for help/info on IDE drives
+#
+# CONFIG_BLK_DEV_IDE_SATA is not set
+# CONFIG_BLK_DEV_HD_IDE is not set
+CONFIG_BLK_DEV_IDEDISK=y
+CONFIG_IDEDISK_MULTI_MODE=y
+CONFIG_BLK_DEV_IDECS=m
+CONFIG_BLK_DEV_IDECD=m
+# CONFIG_BLK_DEV_IDETAPE is not set
+CONFIG_BLK_DEV_IDEFLOPPY=y
+CONFIG_BLK_DEV_IDESCSI=m
+CONFIG_IDE_TASK_IOCTL=y
+
+#
+# IDE chipset support/bugfixes
+#
+CONFIG_IDE_GENERIC=y
+CONFIG_BLK_DEV_CMD640=y
+CONFIG_BLK_DEV_CMD640_ENHANCED=y
+CONFIG_BLK_DEV_IDEPNP=y
+CONFIG_BLK_DEV_IDEPCI=y
+CONFIG_IDEPCI_SHARE_IRQ=y
+# CONFIG_BLK_DEV_OFFBOARD is not set
+CONFIG_BLK_DEV_GENERIC=y
+# CONFIG_BLK_DEV_OPTI621 is not set
+CONFIG_BLK_DEV_RZ1000=y
+CONFIG_BLK_DEV_IDEDMA_PCI=y
+# CONFIG_BLK_DEV_IDEDMA_FORCED is not set
+CONFIG_IDEDMA_PCI_AUTO=y
+# CONFIG_IDEDMA_ONLYDISK is not set
+CONFIG_BLK_DEV_AEC62XX=y
+CONFIG_BLK_DEV_ALI15X3=y
+# CONFIG_WDC_ALI15X3 is not set
+CONFIG_BLK_DEV_AMD74XX=y
+CONFIG_BLK_DEV_ATIIXP=y
+CONFIG_BLK_DEV_CMD64X=y
+CONFIG_BLK_DEV_TRIFLEX=y
+# CONFIG_BLK_DEV_CY82C693 is not set
+CONFIG_BLK_DEV_CS5520=y
+CONFIG_BLK_DEV_CS5530=y
+CONFIG_BLK_DEV_CS5535=y
+CONFIG_BLK_DEV_HPT34X=y
+# CONFIG_HPT34X_AUTODMA is not set
+CONFIG_BLK_DEV_HPT366=y
+# CONFIG_BLK_DEV_SC1200 is not set
+CONFIG_BLK_DEV_PIIX=y
+CONFIG_BLK_DEV_IT821X=y
+# CONFIG_BLK_DEV_NS87415 is not set
+CONFIG_BLK_DEV_PDC202XX_OLD=y
+# CONFIG_PDC202XX_BURST is not set
+CONFIG_BLK_DEV_PDC202XX_NEW=y
+CONFIG_BLK_DEV_SVWKS=y
+CONFIG_BLK_DEV_SIIMAGE=y
+CONFIG_BLK_DEV_SIS5513=y
+# CONFIG_BLK_DEV_SLC90E66 is not set
+# CONFIG_BLK_DEV_TRM290 is not set
+CONFIG_BLK_DEV_VIA82CXXX=y
+# CONFIG_IDE_ARM is not set
+# CONFIG_IDE_CHIPSETS is not set
+CONFIG_BLK_DEV_IDEDMA=y
+# CONFIG_IDEDMA_IVB is not set
+CONFIG_IDEDMA_AUTO=y
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# SCSI device support
+#
+CONFIG_RAID_ATTRS=m
+CONFIG_SCSI=m
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=m
+CONFIG_CHR_DEV_ST=m
+CONFIG_CHR_DEV_OSST=m
+CONFIG_BLK_DEV_SR=m
+CONFIG_BLK_DEV_SR_VENDOR=y
+CONFIG_CHR_DEV_SG=m
+CONFIG_CHR_DEV_SCH=m
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+CONFIG_SCSI_MULTI_LUN=y
+CONFIG_SCSI_CONSTANTS=y
+CONFIG_SCSI_LOGGING=y
+
+#
+# SCSI Transport Attributes
+#
+CONFIG_SCSI_SPI_ATTRS=m
+CONFIG_SCSI_FC_ATTRS=m
+CONFIG_SCSI_ISCSI_ATTRS=m
+CONFIG_SCSI_SAS_ATTRS=m
+
+#
+# SCSI low-level drivers
+#
+CONFIG_ISCSI_TCP=m
+CONFIG_BLK_DEV_3W_XXXX_RAID=m
+CONFIG_SCSI_3W_9XXX=m
+# CONFIG_SCSI_7000FASST is not set
+CONFIG_SCSI_ACARD=m
+CONFIG_SCSI_AHA152X=m
+CONFIG_SCSI_AHA1542=m
+CONFIG_SCSI_AACRAID=m
+CONFIG_SCSI_AIC7XXX=m
+CONFIG_AIC7XXX_CMDS_PER_DEVICE=4
+CONFIG_AIC7XXX_RESET_DELAY_MS=15000
+# CONFIG_AIC7XXX_DEBUG_ENABLE is not set
+CONFIG_AIC7XXX_DEBUG_MASK=0
+# CONFIG_AIC7XXX_REG_PRETTY_PRINT is not set
+CONFIG_SCSI_AIC7XXX_OLD=m
+CONFIG_SCSI_AIC79XX=m
+CONFIG_AIC79XX_CMDS_PER_DEVICE=4
+CONFIG_AIC79XX_RESET_DELAY_MS=15000
+# CONFIG_AIC79XX_ENABLE_RD_STRM is not set
+# CONFIG_AIC79XX_DEBUG_ENABLE is not set
+CONFIG_AIC79XX_DEBUG_MASK=0
+# CONFIG_AIC79XX_REG_PRETTY_PRINT is not set
+# CONFIG_SCSI_DPT_I2O is not set
+CONFIG_SCSI_ADVANSYS=m
+# CONFIG_SCSI_IN2000 is not set
+CONFIG_MEGARAID_NEWGEN=y
+CONFIG_MEGARAID_MM=m
+CONFIG_MEGARAID_MAILBOX=m
+CONFIG_MEGARAID_LEGACY=m
+CONFIG_MEGARAID_SAS=m
+CONFIG_SCSI_SATA=m
+CONFIG_SCSI_SATA_AHCI=m
+CONFIG_SCSI_SATA_SVW=m
+CONFIG_SCSI_ATA_PIIX=m
+CONFIG_SCSI_SATA_MV=m
+CONFIG_SCSI_SATA_NV=m
+CONFIG_SCSI_PDC_ADMA=m
+CONFIG_SCSI_HPTIOP=m
+CONFIG_SCSI_SATA_QSTOR=m
+CONFIG_SCSI_SATA_PROMISE=m
+CONFIG_SCSI_SATA_SX4=m
+CONFIG_SCSI_SATA_SIL=m
+CONFIG_SCSI_SATA_SIL24=m
+CONFIG_SCSI_SATA_SIS=m
+CONFIG_SCSI_SATA_ULI=m
+CONFIG_SCSI_SATA_VIA=m
+CONFIG_SCSI_SATA_VITESSE=m
+CONFIG_SCSI_SATA_INTEL_COMBINED=y
+CONFIG_SCSI_BUSLOGIC=m
+# CONFIG_SCSI_OMIT_FLASHPOINT is not set
+# CONFIG_SCSI_DMX3191D is not set
+# CONFIG_SCSI_DTC3280 is not set
+# CONFIG_SCSI_EATA is not set
+CONFIG_SCSI_FUTURE_DOMAIN=m
+CONFIG_SCSI_GDTH=m
+# CONFIG_SCSI_GENERIC_NCR5380 is not set
+# CONFIG_SCSI_GENERIC_NCR5380_MMIO is not set
+CONFIG_SCSI_IPS=m
+CONFIG_SCSI_INITIO=m
+CONFIG_SCSI_INIA100=m
+CONFIG_SCSI_PPA=m
+CONFIG_SCSI_IMM=m
+# CONFIG_SCSI_IZIP_EPP16 is not set
+# CONFIG_SCSI_IZIP_SLOW_CTR is not set
+# CONFIG_SCSI_NCR53C406A is not set
+CONFIG_SCSI_SYM53C8XX_2=m
+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=m
+CONFIG_SCSI_QLA_FC=m
+CONFIG_SCSI_LPFC=m
+# CONFIG_SCSI_SYM53C416 is not set
+CONFIG_SCSI_DC395x=m
+CONFIG_SCSI_DC390T=m
+# CONFIG_SCSI_T128 is not set
+# CONFIG_SCSI_U14_34F is not set
+# CONFIG_SCSI_ULTRASTOR is not set
+# CONFIG_SCSI_NSP32 is not set
+# CONFIG_SCSI_DEBUG is not set
+
+#
+# PCMCIA SCSI adapter support
+#
+CONFIG_PCMCIA_AHA152X=m
+CONFIG_PCMCIA_FDOMAIN=m
+CONFIG_PCMCIA_NINJA_SCSI=m
+CONFIG_PCMCIA_QLOGIC=m
+CONFIG_PCMCIA_SYM53C500=m
+
+#
+# Old CD-ROM drivers (not SCSI, not IDE)
+#
+# CONFIG_CD_NO_IDESCSI is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+CONFIG_MD=y
+CONFIG_BLK_DEV_MD=y
+CONFIG_MD_LINEAR=m
+CONFIG_MD_RAID0=m
+CONFIG_MD_RAID1=m
+CONFIG_MD_RAID10=m
+CONFIG_MD_RAID456=m
+CONFIG_MD_RAID5_RESHAPE=y
+CONFIG_MD_MULTIPATH=m
+CONFIG_MD_FAULTY=m
+CONFIG_BLK_DEV_DM=m
+CONFIG_DM_CRYPT=m
+CONFIG_DM_SNAPSHOT=m
+CONFIG_DM_MIRROR=m
+CONFIG_DM_ZERO=m
+CONFIG_DM_MULTIPATH=m
+CONFIG_DM_MULTIPATH_EMC=m
+
+#
+# Fusion MPT device support
+#
+CONFIG_FUSION=y
+CONFIG_FUSION_SPI=m
+CONFIG_FUSION_FC=m
+CONFIG_FUSION_SAS=m
+CONFIG_FUSION_MAX_SGE=40
+CONFIG_FUSION_CTL=m
+CONFIG_FUSION_LAN=m
+
+#
+# IEEE 1394 (FireWire) support
+#
+CONFIG_IEEE1394=m
+
+#
+# Subsystem Options
+#
+# CONFIG_IEEE1394_VERBOSEDEBUG is not set
+CONFIG_IEEE1394_OUI_DB=y
+CONFIG_IEEE1394_EXTRA_CONFIG_ROMS=y
+CONFIG_IEEE1394_CONFIG_ROM_IP1394=y
+# CONFIG_IEEE1394_EXPORT_FULL_API is not set
+
+#
+# Device Drivers
+#
+CONFIG_IEEE1394_PCILYNX=m
+CONFIG_IEEE1394_OHCI1394=m
+
+#
+# Protocol Drivers
+#
+CONFIG_IEEE1394_VIDEO1394=m
+CONFIG_IEEE1394_SBP2=m
+# CONFIG_IEEE1394_SBP2_PHYS_DMA is not set
+CONFIG_IEEE1394_ETH1394=m
+CONFIG_IEEE1394_DV1394=m
+CONFIG_IEEE1394_RAWIO=m
+
+#
+# I2O device support
+#
+CONFIG_I2O=m
+# CONFIG_I2O_LCT_NOTIFY_ON_CHANGES is not set
+CONFIG_I2O_EXT_ADAPTEC=y
+CONFIG_I2O_EXT_ADAPTEC_DMA64=y
+CONFIG_I2O_CONFIG=m
+CONFIG_I2O_CONFIG_OLD_IOCTL=y
+CONFIG_I2O_BUS=m
+CONFIG_I2O_BLOCK=m
+CONFIG_I2O_SCSI=m
+CONFIG_I2O_PROC=m
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+CONFIG_IFB=m
+CONFIG_DUMMY=m
+CONFIG_BONDING=m
+CONFIG_EQUALIZER=m
+CONFIG_TUN=m
+CONFIG_NET_SB1000=m
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+
+#
+# PHY device support
+#
+CONFIG_PHYLIB=m
+
+#
+# MII PHY device drivers
+#
+CONFIG_MARVELL_PHY=m
+CONFIG_DAVICOM_PHY=m
+CONFIG_QSEMI_PHY=m
+CONFIG_LXT_PHY=m
+CONFIG_CICADA_PHY=m
+CONFIG_VITESSE_PHY=m
+CONFIG_SMSC_PHY=m
+CONFIG_FIXED_PHY=m
+CONFIG_FIXED_MII_10_FDX=y
+CONFIG_FIXED_MII_100_FDX=y
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=m
+CONFIG_HAPPYMEAL=m
+CONFIG_SUNGEM=m
+CONFIG_CASSINI=m
+CONFIG_NET_VENDOR_3COM=y
+# CONFIG_EL1 is not set
+# CONFIG_EL2 is not set
+# CONFIG_ELPLUS is not set
+# CONFIG_EL16 is not set
+CONFIG_EL3=m
+# CONFIG_3C515 is not set
+CONFIG_VORTEX=m
+CONFIG_TYPHOON=m
+# CONFIG_LANCE is not set
+CONFIG_NET_VENDOR_SMC=y
+# CONFIG_WD80x3 is not set
+CONFIG_ULTRA=m
+# CONFIG_SMC9194 is not set
+# CONFIG_NET_VENDOR_RACAL is not set
+
+#
+# Tulip family network device support
+#
+CONFIG_NET_TULIP=y
+CONFIG_DE2104X=m
+CONFIG_TULIP=m
+# CONFIG_TULIP_MWI is not set
+CONFIG_TULIP_MMIO=y
+# CONFIG_TULIP_NAPI is not set
+CONFIG_DE4X5=m
+CONFIG_WINBOND_840=m
+CONFIG_DM9102=m
+CONFIG_ULI526X=m
+CONFIG_PCMCIA_XIRCOM=m
+# CONFIG_PCMCIA_XIRTULIP is not set
+# CONFIG_AT1700 is not set
+# CONFIG_DEPCA is not set
+# CONFIG_HP100 is not set
+CONFIG_NET_ISA=y
+# CONFIG_E2100 is not set
+CONFIG_EWRK3=m
+# CONFIG_EEXPRESS is not set
+# CONFIG_EEXPRESS_PRO is not set
+# CONFIG_HPLAN_PLUS is not set
+# CONFIG_HPLAN is not set
+# CONFIG_LP486E is not set
+# CONFIG_ETH16I is not set
+CONFIG_NE2000=m
+# CONFIG_ZNET is not set
+# CONFIG_SEEQ8005 is not set
+CONFIG_NET_PCI=y
+CONFIG_PCNET32=m
+CONFIG_AMD8111_ETH=m
+CONFIG_AMD8111E_NAPI=y
+CONFIG_ADAPTEC_STARFIRE=m
+CONFIG_ADAPTEC_STARFIRE_NAPI=y
+# CONFIG_AC3200 is not set
+# CONFIG_APRICOT is not set
+CONFIG_B44=m
+CONFIG_FORCEDETH=m
+# CONFIG_CS89x0 is not set
+# CONFIG_DGRS is not set
+# CONFIG_EEPRO100 is not set
+CONFIG_E100=m
+CONFIG_FEALNX=m
+CONFIG_NATSEMI=m
+CONFIG_NE2K_PCI=m
+CONFIG_8139CP=m
+CONFIG_8139TOO=m
+# CONFIG_8139TOO_PIO is not set
+# CONFIG_8139TOO_TUNE_TWISTER is not set
+CONFIG_8139TOO_8129=y
+# CONFIG_8139_OLD_RX_RESET is not set
+CONFIG_SIS900=m
+CONFIG_EPIC100=m
+CONFIG_SUNDANCE=m
+# CONFIG_SUNDANCE_MMIO is not set
+CONFIG_TLAN=m
+CONFIG_VIA_RHINE=m
+CONFIG_VIA_RHINE_MMIO=y
+CONFIG_VIA_RHINE_NAPI=y
+CONFIG_NET_POCKET=y
+CONFIG_ATP=m
+CONFIG_DE600=m
+CONFIG_DE620=m
+
+#
+# Ethernet (1000 Mbit)
+#
+CONFIG_ACENIC=m
+# CONFIG_ACENIC_OMIT_TIGON_I is not set
+CONFIG_DL2K=m
+CONFIG_E1000=m
+CONFIG_E1000_NAPI=y
+# CONFIG_E1000_DISABLE_PACKET_SPLIT is not set
+CONFIG_NS83820=m
+CONFIG_HAMACHI=m
+CONFIG_YELLOWFIN=m
+CONFIG_R8169=m
+CONFIG_R8169_NAPI=y
+CONFIG_R8169_VLAN=y
+CONFIG_SIS190=m
+CONFIG_SKGE=m
+CONFIG_SKY2=m
+# CONFIG_SK98LIN is not set
+CONFIG_VIA_VELOCITY=m
+CONFIG_TIGON3=m
+CONFIG_BNX2=m
+
+#
+# Ethernet (10000 Mbit)
+#
+CONFIG_CHELSIO_T1=m
+CONFIG_IXGB=m
+CONFIG_IXGB_NAPI=y
+CONFIG_S2IO=m
+CONFIG_S2IO_NAPI=y
+CONFIG_MYRI10GE=m
+
+#
+# Token Ring devices
+#
+CONFIG_TR=y
+# CONFIG_IBMTR is not set
+CONFIG_IBMOL=m
+CONFIG_IBMLS=m
+CONFIG_3C359=m
+# CONFIG_TMS380TR is not set
+# CONFIG_SMCTR is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+CONFIG_NET_RADIO=y
+CONFIG_NET_WIRELESS_RTNETLINK=y
+
+#
+# Obsolete Wireless cards support (pre-802.11)
+#
+# CONFIG_STRIP is not set
+# CONFIG_ARLAN is not set
+# CONFIG_WAVELAN is not set
+CONFIG_PCMCIA_WAVELAN=m
+CONFIG_PCMCIA_NETWAVE=m
+
+#
+# Wireless 802.11 Frequency Hopping cards support
+#
+# CONFIG_PCMCIA_RAYCS is not set
+
+#
+# Wireless 802.11b ISA/PCI cards support
+#
+CONFIG_IPW2100=m
+CONFIG_IPW2100_MONITOR=y
+# CONFIG_IPW2100_DEBUG is not set
+CONFIG_IPW2200=m
+CONFIG_IPW2200_MONITOR=y
+CONFIG_IPW2200_RADIOTAP=y
+CONFIG_IPW2200_PROMISCUOUS=y
+CONFIG_IPW2200_QOS=y
+# CONFIG_IPW2200_DEBUG is not set
+CONFIG_AIRO=m
+CONFIG_HERMES=m
+CONFIG_PLX_HERMES=m
+CONFIG_TMD_HERMES=m
+CONFIG_NORTEL_HERMES=m
+CONFIG_PCI_HERMES=m
+CONFIG_ATMEL=m
+CONFIG_PCI_ATMEL=m
+
+#
+# Wireless 802.11b Pcmcia/Cardbus cards support
+#
+CONFIG_PCMCIA_HERMES=m
+CONFIG_PCMCIA_SPECTRUM=m
+CONFIG_AIRO_CS=m
+CONFIG_PCMCIA_ATMEL=m
+CONFIG_PCMCIA_WL3501=m
+
+#
+# Prism GT/Duette 802.11(a/b/g) PCI/Cardbus support
+#
+CONFIG_PRISM54=m
+CONFIG_USB_ZD1201=m
+CONFIG_HOSTAP=m
+CONFIG_HOSTAP_FIRMWARE=y
+CONFIG_HOSTAP_FIRMWARE_NVRAM=y
+CONFIG_HOSTAP_PLX=m
+CONFIG_HOSTAP_PCI=m
+CONFIG_HOSTAP_CS=m
+CONFIG_BCM43XX=m
+CONFIG_BCM43XX_DEBUG=y
+CONFIG_BCM43XX_DMA=y
+CONFIG_BCM43XX_PIO=y
+CONFIG_BCM43XX_DMA_AND_PIO_MODE=y
+# CONFIG_BCM43XX_DMA_MODE is not set
+# CONFIG_BCM43XX_PIO_MODE is not set
+CONFIG_ZD1211RW=m
+# CONFIG_ZD1211RW_DEBUG is not set
+CONFIG_NET_WIRELESS=y
+
+#
+# PCMCIA network device support
+#
+CONFIG_NET_PCMCIA=y
+CONFIG_PCMCIA_3C589=m
+CONFIG_PCMCIA_3C574=m
+CONFIG_PCMCIA_FMVJ18X=m
+CONFIG_PCMCIA_PCNET=m
+CONFIG_PCMCIA_NMCLAN=m
+CONFIG_PCMCIA_SMC91C92=m
+CONFIG_PCMCIA_XIRC2PS=m
+CONFIG_PCMCIA_AXNET=m
+CONFIG_PCMCIA_IBMTR=m
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+
+#
+# ATM drivers
+#
+# CONFIG_ATM_DUMMY is not set
+CONFIG_ATM_TCP=m
+CONFIG_ATM_LANAI=m
+CONFIG_ATM_ENI=m
+# CONFIG_ATM_ENI_DEBUG is not set
+# CONFIG_ATM_ENI_TUNE_BURST is not set
+CONFIG_ATM_FIRESTREAM=m
+# CONFIG_ATM_ZATM is not set
+CONFIG_ATM_NICSTAR=m
+# CONFIG_ATM_NICSTAR_USE_SUNI is not set
+# CONFIG_ATM_NICSTAR_USE_IDT77105 is not set
+CONFIG_ATM_IDT77252=m
+# CONFIG_ATM_IDT77252_DEBUG is not set
+# CONFIG_ATM_IDT77252_RCV_ALL is not set
+CONFIG_ATM_IDT77252_USE_SUNI=y
+CONFIG_ATM_AMBASSADOR=m
+# CONFIG_ATM_AMBASSADOR_DEBUG is not set
+CONFIG_ATM_HORIZON=m
+# CONFIG_ATM_HORIZON_DEBUG is not set
+# CONFIG_ATM_IA is not set
+CONFIG_ATM_FORE200E_MAYBE=m
+# CONFIG_ATM_FORE200E_PCA is not set
+CONFIG_ATM_HE=m
+# CONFIG_ATM_HE_USE_SUNI is not set
+CONFIG_FDDI=y
+# CONFIG_DEFXX is not set
+CONFIG_SKFP=m
+# CONFIG_HIPPI is not set
+CONFIG_PLIP=m
+CONFIG_PPP=m
+CONFIG_PPP_MULTILINK=y
+CONFIG_PPP_FILTER=y
+CONFIG_PPP_ASYNC=m
+CONFIG_PPP_SYNC_TTY=m
+CONFIG_PPP_DEFLATE=m
+# CONFIG_PPP_BSDCOMP is not set
+CONFIG_PPP_MPPE=m
+CONFIG_PPPOE=m
+CONFIG_PPPOATM=m
+CONFIG_SLIP=m
+CONFIG_SLIP_COMPRESSED=y
+CONFIG_SLIP_SMART=y
+# CONFIG_SLIP_MODE_SLIP6 is not set
+CONFIG_NET_FC=y
+# CONFIG_SHAPER is not set
+CONFIG_NETCONSOLE=m
+CONFIG_NETPOLL=y
+# CONFIG_NETPOLL_RX is not set
+CONFIG_NETPOLL_TRAP=y
+CONFIG_NET_POLL_CONTROLLER=y
+
+#
+# ISDN subsystem
+#
+CONFIG_ISDN=m
+
+#
+# Old ISDN4Linux
+#
+CONFIG_ISDN_I4L=m
+CONFIG_ISDN_PPP=y
+CONFIG_ISDN_PPP_VJ=y
+CONFIG_ISDN_MPP=y
+CONFIG_IPPP_FILTER=y
+# CONFIG_ISDN_PPP_BSDCOMP is not set
+CONFIG_ISDN_AUDIO=y
+CONFIG_ISDN_TTY_FAX=y
+
+#
+# ISDN feature submodules
+#
+CONFIG_ISDN_DRV_LOOP=m
+CONFIG_ISDN_DIVERSION=m
+
+#
+# ISDN4Linux hardware drivers
+#
+
+#
+# Passive cards
+#
+CONFIG_ISDN_DRV_HISAX=m
+
+#
+# D-channel protocol features
+#
+CONFIG_HISAX_EURO=y
+CONFIG_DE_AOC=y
+CONFIG_HISAX_NO_SENDCOMPLETE=y
+CONFIG_HISAX_NO_LLC=y
+CONFIG_HISAX_NO_KEYPAD=y
+CONFIG_HISAX_1TR6=y
+CONFIG_HISAX_NI1=y
+CONFIG_HISAX_MAX_CARDS=8
+
+#
+# HiSax supported cards
+#
+# CONFIG_HISAX_16_0 is not set
+CONFIG_HISAX_16_3=y
+CONFIG_HISAX_TELESPCI=y
+CONFIG_HISAX_S0BOX=y
+# CONFIG_HISAX_AVM_A1 is not set
+CONFIG_HISAX_FRITZPCI=y
+CONFIG_HISAX_AVM_A1_PCMCIA=y
+CONFIG_HISAX_ELSA=y
+# CONFIG_HISAX_IX1MICROR2 is not set
+CONFIG_HISAX_DIEHLDIVA=y
+# CONFIG_HISAX_ASUSCOM is not set
+# CONFIG_HISAX_TELEINT is not set
+# CONFIG_HISAX_HFCS is not set
+CONFIG_HISAX_SEDLBAUER=y
+# CONFIG_HISAX_SPORTSTER is not set
+# CONFIG_HISAX_MIC is not set
+CONFIG_HISAX_NETJET=y
+CONFIG_HISAX_NETJET_U=y
+CONFIG_HISAX_NICCY=y
+# CONFIG_HISAX_ISURF is not set
+# CONFIG_HISAX_HSTSAPHIR is not set
+CONFIG_HISAX_BKM_A4T=y
+CONFIG_HISAX_SCT_QUADRO=y
+CONFIG_HISAX_GAZEL=y
+CONFIG_HISAX_HFC_PCI=y
+CONFIG_HISAX_W6692=y
+CONFIG_HISAX_HFC_SX=y
+CONFIG_HISAX_ENTERNOW_PCI=y
+# CONFIG_HISAX_DEBUG is not set
+
+#
+# HiSax PCMCIA card service modules
+#
+CONFIG_HISAX_SEDLBAUER_CS=m
+CONFIG_HISAX_ELSA_CS=m
+CONFIG_HISAX_AVM_A1_CS=m
+CONFIG_HISAX_TELES_CS=m
+
+#
+# HiSax sub driver modules
+#
+CONFIG_HISAX_ST5481=m
+# CONFIG_HISAX_HFCUSB is not set
+CONFIG_HISAX_HFC4S8S=m
+CONFIG_HISAX_FRITZ_PCIPNP=m
+CONFIG_HISAX_HDLC=y
+
+#
+# Active cards
+#
+# CONFIG_ISDN_DRV_ICN is not set
+# CONFIG_ISDN_DRV_PCBIT is not set
+# CONFIG_ISDN_DRV_SC is not set
+# CONFIG_ISDN_DRV_ACT2000 is not set
+CONFIG_HYSDN=m
+CONFIG_HYSDN_CAPI=y
+
+#
+# Siemens Gigaset
+#
+CONFIG_ISDN_DRV_GIGASET=m
+CONFIG_GIGASET_BASE=m
+CONFIG_GIGASET_M105=m
+# CONFIG_GIGASET_DEBUG is not set
+# CONFIG_GIGASET_UNDOCREQ is not set
+
+#
+# CAPI subsystem
+#
+CONFIG_ISDN_CAPI=m
+CONFIG_ISDN_DRV_AVMB1_VERBOSE_REASON=y
+CONFIG_ISDN_CAPI_MIDDLEWARE=y
+CONFIG_ISDN_CAPI_CAPI20=m
+CONFIG_ISDN_CAPI_CAPIFS_BOOL=y
+CONFIG_ISDN_CAPI_CAPIFS=m
+CONFIG_ISDN_CAPI_CAPIDRV=m
+
+#
+# CAPI hardware drivers
+#
+
+#
+# Active AVM cards
+#
+CONFIG_CAPI_AVM=y
+# CONFIG_ISDN_DRV_AVMB1_B1ISA is not set
+CONFIG_ISDN_DRV_AVMB1_B1PCI=m
+CONFIG_ISDN_DRV_AVMB1_B1PCIV4=y
+# CONFIG_ISDN_DRV_AVMB1_T1ISA is not set
+CONFIG_ISDN_DRV_AVMB1_B1PCMCIA=m
+CONFIG_ISDN_DRV_AVMB1_AVM_CS=m
+CONFIG_ISDN_DRV_AVMB1_T1PCI=m
+CONFIG_ISDN_DRV_AVMB1_C4=m
+
+#
+# Active Eicon DIVA Server cards
+#
+CONFIG_CAPI_EICON=y
+CONFIG_ISDN_DIVAS=m
+CONFIG_ISDN_DIVAS_BRIPCI=y
+CONFIG_ISDN_DIVAS_PRIPCI=y
+CONFIG_ISDN_DIVAS_DIVACAPI=m
+CONFIG_ISDN_DIVAS_USERIDI=m
+CONFIG_ISDN_DIVAS_MAINT=m
+
+#
+# Telephony Support
+#
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+
+#
+# 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=m
+# CONFIG_INPUT_TSDEV is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+CONFIG_KEYBOARD_ATKBD=y
+# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_KEYBOARD_LKKBD is not set
+# CONFIG_KEYBOARD_XTKBD is not set
+# CONFIG_KEYBOARD_NEWTON is not set
+CONFIG_INPUT_MOUSE=y
+CONFIG_MOUSE_PS2=y
+CONFIG_MOUSE_SERIAL=m
+# CONFIG_MOUSE_INPORT is not set
+# CONFIG_MOUSE_LOGIBM is not set
+# CONFIG_MOUSE_PC110PAD is not set
+CONFIG_MOUSE_VSXXXAA=m
+CONFIG_INPUT_JOYSTICK=y
+CONFIG_JOYSTICK_ANALOG=m
+CONFIG_JOYSTICK_A3D=m
+CONFIG_JOYSTICK_ADI=m
+CONFIG_JOYSTICK_COBRA=m
+CONFIG_JOYSTICK_GF2K=m
+CONFIG_JOYSTICK_GRIP=m
+CONFIG_JOYSTICK_GRIP_MP=m
+CONFIG_JOYSTICK_GUILLEMOT=m
+CONFIG_JOYSTICK_INTERACT=m
+CONFIG_JOYSTICK_SIDEWINDER=m
+CONFIG_JOYSTICK_TMDC=m
+CONFIG_JOYSTICK_IFORCE=m
+CONFIG_JOYSTICK_IFORCE_USB=y
+CONFIG_JOYSTICK_IFORCE_232=y
+CONFIG_JOYSTICK_WARRIOR=m
+CONFIG_JOYSTICK_MAGELLAN=m
+CONFIG_JOYSTICK_SPACEORB=m
+CONFIG_JOYSTICK_SPACEBALL=m
+CONFIG_JOYSTICK_STINGER=m
+CONFIG_JOYSTICK_TWIDJOY=m
+CONFIG_JOYSTICK_DB9=m
+CONFIG_JOYSTICK_GAMECON=m
+CONFIG_JOYSTICK_TURBOGRAFX=m
+CONFIG_JOYSTICK_JOYDUMP=m
+CONFIG_INPUT_TOUCHSCREEN=y
+CONFIG_TOUCHSCREEN_GUNZE=m
+CONFIG_TOUCHSCREEN_ELO=m
+CONFIG_TOUCHSCREEN_MTOUCH=m
+CONFIG_TOUCHSCREEN_MK712=m
+CONFIG_INPUT_MISC=y
+CONFIG_INPUT_PCSPKR=m
+CONFIG_INPUT_WISTRON_BTNS=m
+CONFIG_INPUT_UINPUT=m
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+CONFIG_SERIO_I8042=y
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_CT82C710 is not set
+# CONFIG_SERIO_PARKBD is not set
+# CONFIG_SERIO_PCIPS2 is not set
+CONFIG_SERIO_LIBPS2=y
+CONFIG_SERIO_RAW=m
+CONFIG_GAMEPORT=m
+CONFIG_GAMEPORT_NS558=m
+CONFIG_GAMEPORT_L4=m
+CONFIG_GAMEPORT_EMU10K1=m
+CONFIG_GAMEPORT_FM801=m
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+CONFIG_VT_HW_CONSOLE_BINDING=y
+CONFIG_SERIAL_NONSTANDARD=y
+# CONFIG_COMPUTONE is not set
+# CONFIG_ROCKETPORT is not set
+CONFIG_CYCLADES=m
+# CONFIG_CYZ_INTR is not set
+# CONFIG_DIGIEPCA is not set
+# CONFIG_ESPSERIAL is not set
+# CONFIG_MOXA_INTELLIO is not set
+# CONFIG_MOXA_SMARTIO is not set
+# CONFIG_ISI is not set
+CONFIG_SYNCLINK=m
+CONFIG_SYNCLINKMP=m
+CONFIG_SYNCLINK_GT=m
+CONFIG_N_HDLC=m
+# CONFIG_RISCOM8 is not set
+# CONFIG_SPECIALIX is not set
+# CONFIG_SX is not set
+# CONFIG_RIO is not set
+# CONFIG_STALDRV is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_PCI=y
+CONFIG_SERIAL_8250_PNP=y
+CONFIG_SERIAL_8250_CS=m
+CONFIG_SERIAL_8250_NR_UARTS=32
+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=y
+CONFIG_SERIAL_8250_RSA=y
+# CONFIG_SERIAL_8250_FOURPORT is not set
+# CONFIG_SERIAL_8250_ACCENT is not set
+# CONFIG_SERIAL_8250_BOCA is not set
+# CONFIG_SERIAL_8250_HUB6 is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_SERIAL_JSM=m
+CONFIG_UNIX98_PTYS=y
+# CONFIG_LEGACY_PTYS is not set
+CONFIG_CRASH=m
+CONFIG_PRINTER=m
+CONFIG_LP_CONSOLE=y
+CONFIG_PPDEV=m
+CONFIG_TIPAR=m
+
+#
+# IPMI
+#
+CONFIG_IPMI_HANDLER=m
+# CONFIG_IPMI_PANIC_EVENT is not set
+CONFIG_IPMI_DEVICE_INTERFACE=m
+CONFIG_IPMI_SI=m
+CONFIG_IPMI_WATCHDOG=m
+CONFIG_IPMI_POWEROFF=m
+
+#
+# Watchdog Cards
+#
+CONFIG_WATCHDOG=y
+# CONFIG_WATCHDOG_NOWAYOUT is not set
+
+#
+# Watchdog Device Drivers
+#
+CONFIG_SOFT_WATCHDOG=m
+# CONFIG_ACQUIRE_WDT is not set
+# CONFIG_ADVANTECH_WDT is not set
+CONFIG_ALIM1535_WDT=m
+CONFIG_ALIM7101_WDT=m
+# CONFIG_SC520_WDT is not set
+# CONFIG_EUROTECH_WDT is not set
+# CONFIG_IB700_WDT is not set
+CONFIG_IBMASR=m
+# CONFIG_WAFER_WDT is not set
+CONFIG_I6300ESB_WDT=m
+CONFIG_I8XX_TCO=m
+# CONFIG_SC1200_WDT is not set
+# CONFIG_60XX_WDT is not set
+# CONFIG_SBC8360_WDT is not set
+# CONFIG_CPU5_WDT is not set
+CONFIG_W83627HF_WDT=m
+CONFIG_W83877F_WDT=m
+CONFIG_W83977F_WDT=m
+CONFIG_MACHZ_WDT=m
+# CONFIG_SBC_EPX_C3_WATCHDOG is not set
+
+#
+# ISA-based Watchdog Cards
+#
+# CONFIG_PCWATCHDOG is not set
+# CONFIG_MIXCOMWD is not set
+# CONFIG_WDT is not set
+
+#
+# PCI-based Watchdog Cards
+#
+CONFIG_PCIPCWATCHDOG=m
+CONFIG_WDTPCI=m
+CONFIG_WDT_501_PCI=y
+
+#
+# USB-based Watchdog Cards
+#
+CONFIG_USBPCWATCHDOG=m
+CONFIG_HW_RANDOM=y
+CONFIG_HW_RANDOM_INTEL=m
+CONFIG_HW_RANDOM_AMD=m
+CONFIG_HW_RANDOM_GEODE=m
+CONFIG_HW_RANDOM_VIA=m
+CONFIG_NVRAM=y
+CONFIG_RTC=y
+CONFIG_DTLK=m
+CONFIG_R3964=m
+# CONFIG_APPLICOM is not set
+CONFIG_SONYPI=m
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_FTAPE is not set
+CONFIG_AGP=y
+CONFIG_AGP_ALI=y
+CONFIG_AGP_ATI=y
+CONFIG_AGP_AMD=y
+CONFIG_AGP_AMD64=y
+CONFIG_AGP_INTEL=y
+CONFIG_AGP_NVIDIA=y
+CONFIG_AGP_SIS=y
+CONFIG_AGP_SWORKS=y
+CONFIG_AGP_VIA=y
+CONFIG_AGP_EFFICEON=y
+CONFIG_DRM=m
+CONFIG_DRM_TDFX=m
+CONFIG_DRM_R128=m
+CONFIG_DRM_RADEON=m
+CONFIG_DRM_I810=m
+CONFIG_DRM_I830=m
+CONFIG_DRM_I915=m
+CONFIG_DRM_MGA=m
+CONFIG_DRM_SIS=m
+CONFIG_DRM_VIA=m
+CONFIG_DRM_SAVAGE=m
+
+#
+# PCMCIA character devices
+#
+# CONFIG_SYNCLINK_CS is not set
+CONFIG_CARDMAN_4000=m
+CONFIG_CARDMAN_4040=m
+CONFIG_MWAVE=m
+CONFIG_PC8736x_GPIO=m
+CONFIG_NSC_GPIO=m
+CONFIG_CS5535_GPIO=m
+# CONFIG_RAW_DRIVER is not set
+CONFIG_HPET=y
+# CONFIG_HPET_RTC_IRQ is not set
+# CONFIG_HPET_MMAP is not set
+CONFIG_HANGCHECK_TIMER=m
+
+#
+# TPM devices
+#
+CONFIG_TCG_TPM=m
+CONFIG_TCG_TIS=m
+CONFIG_TCG_NSC=m
+CONFIG_TCG_ATMEL=m
+CONFIG_TCG_INFINEON=m
+# CONFIG_TELCLOCK is not set
+
+#
+# I2C support
+#
+CONFIG_I2C=m
+CONFIG_I2C_CHARDEV=m
+
+#
+# I2C Algorithms
+#
+CONFIG_I2C_ALGOBIT=m
+CONFIG_I2C_ALGOPCF=m
+CONFIG_I2C_ALGOPCA=m
+
+#
+# I2C Hardware Bus support
+#
+CONFIG_I2C_ALI1535=m
+CONFIG_I2C_ALI1563=m
+CONFIG_I2C_ALI15X3=m
+CONFIG_I2C_AMD756=m
+CONFIG_I2C_AMD756_S4882=m
+CONFIG_I2C_AMD8111=m
+# CONFIG_I2C_ELEKTOR is not set
+CONFIG_I2C_I801=m
+CONFIG_I2C_I810=m
+CONFIG_I2C_PIIX4=m
+CONFIG_I2C_ISA=m
+CONFIG_I2C_NFORCE2=m
+# CONFIG_I2C_OCORES is not set
+CONFIG_I2C_PARPORT=m
+CONFIG_I2C_PARPORT_LIGHT=m
+CONFIG_I2C_PROSAVAGE=m
+CONFIG_I2C_SAVAGE4=m
+# CONFIG_SCx200_ACB is not set
+CONFIG_I2C_SIS5595=m
+CONFIG_I2C_SIS630=m
+CONFIG_I2C_SIS96X=m
+CONFIG_I2C_STUB=m
+CONFIG_I2C_VIA=m
+CONFIG_I2C_VIAPRO=m
+CONFIG_I2C_VOODOO3=m
+CONFIG_I2C_PCA_ISA=m
+
+#
+# Miscellaneous I2C Chip support
+#
+CONFIG_SENSORS_DS1337=m
+CONFIG_SENSORS_DS1374=m
+CONFIG_SENSORS_EEPROM=m
+CONFIG_SENSORS_PCF8574=m
+CONFIG_SENSORS_PCA9539=m
+CONFIG_SENSORS_PCF8591=m
+CONFIG_SENSORS_MAX6875=m
+# 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 is not set
+# CONFIG_SPI_MASTER is not set
+
+#
+# Dallas's 1-wire bus
+#
+CONFIG_W1=m
+CONFIG_W1_CON=y
+
+#
+# 1-wire Bus Masters
+#
+CONFIG_W1_MASTER_MATROX=m
+CONFIG_W1_MASTER_DS2490=m
+CONFIG_W1_MASTER_DS2482=m
+
+#
+# 1-wire Slaves
+#
+CONFIG_W1_SLAVE_THERM=m
+CONFIG_W1_SLAVE_SMEM=m
+CONFIG_W1_SLAVE_DS2433=m
+CONFIG_W1_SLAVE_DS2433_CRC=y
+
+#
+# Hardware Monitoring support
+#
+CONFIG_HWMON=m
+CONFIG_HWMON_VID=m
+CONFIG_SENSORS_ABITUGURU=m
+CONFIG_SENSORS_ADM1021=m
+CONFIG_SENSORS_ADM1025=m
+CONFIG_SENSORS_ADM1026=m
+CONFIG_SENSORS_ADM1031=m
+CONFIG_SENSORS_ADM9240=m
+CONFIG_SENSORS_ASB100=m
+CONFIG_SENSORS_ATXP1=m
+CONFIG_SENSORS_DS1621=m
+CONFIG_SENSORS_F71805F=m
+CONFIG_SENSORS_FSCHER=m
+CONFIG_SENSORS_FSCPOS=m
+CONFIG_SENSORS_GL518SM=m
+CONFIG_SENSORS_GL520SM=m
+CONFIG_SENSORS_IT87=m
+CONFIG_SENSORS_LM63=m
+CONFIG_SENSORS_LM75=m
+CONFIG_SENSORS_LM77=m
+CONFIG_SENSORS_LM78=m
+CONFIG_SENSORS_LM80=m
+CONFIG_SENSORS_LM83=m
+CONFIG_SENSORS_LM85=m
+CONFIG_SENSORS_LM87=m
+CONFIG_SENSORS_LM90=m
+CONFIG_SENSORS_LM92=m
+CONFIG_SENSORS_MAX1619=m
+CONFIG_SENSORS_PC87360=m
+CONFIG_SENSORS_SIS5595=m
+CONFIG_SENSORS_SMSC47M1=m
+CONFIG_SENSORS_SMSC47M192=m
+CONFIG_SENSORS_SMSC47B397=m
+CONFIG_SENSORS_VIA686A=m
+CONFIG_SENSORS_VT8231=m
+CONFIG_SENSORS_W83781D=m
+CONFIG_SENSORS_W83791D=m
+CONFIG_SENSORS_W83792D=m
+CONFIG_SENSORS_W83L785TS=m
+CONFIG_SENSORS_W83627HF=m
+CONFIG_SENSORS_W83627EHF=m
+CONFIG_SENSORS_HDAPS=m
+# CONFIG_HWMON_DEBUG_CHIP is not set
+
+#
+# Misc devices
+#
+CONFIG_IBM_ASM=m
+
+#
+# Multimedia devices
+#
+CONFIG_VIDEO_DEV=m
+CONFIG_VIDEO_V4L1=y
+CONFIG_VIDEO_V4L1_COMPAT=y
+CONFIG_VIDEO_V4L2=y
+
+#
+# Video Capture Adapters
+#
+
+#
+# Video Capture Adapters
+#
+# CONFIG_VIDEO_ADV_DEBUG is not set
+# CONFIG_VIDEO_VIVI is not set
+CONFIG_VIDEO_BT848=m
+CONFIG_VIDEO_BT848_DVB=y
+CONFIG_VIDEO_SAA6588=m
+# CONFIG_VIDEO_PMS is not set
+CONFIG_VIDEO_BWQCAM=m
+CONFIG_VIDEO_CQCAM=m
+CONFIG_VIDEO_W9966=m
+CONFIG_VIDEO_CPIA=m
+CONFIG_VIDEO_CPIA_PP=m
+CONFIG_VIDEO_CPIA_USB=m
+CONFIG_VIDEO_CPIA2=m
+CONFIG_VIDEO_SAA5246A=m
+CONFIG_VIDEO_SAA5249=m
+CONFIG_TUNER_3036=m
+CONFIG_VIDEO_STRADIS=m
+CONFIG_VIDEO_ZORAN=m
+CONFIG_VIDEO_ZORAN_BUZ=m
+CONFIG_VIDEO_ZORAN_DC10=m
+CONFIG_VIDEO_ZORAN_DC30=m
+CONFIG_VIDEO_ZORAN_LML33=m
+CONFIG_VIDEO_ZORAN_LML33R10=m
+CONFIG_VIDEO_ZORAN_AVS6EYES=m
+CONFIG_VIDEO_MEYE=m
+CONFIG_VIDEO_SAA7134=m
+CONFIG_VIDEO_SAA7134_ALSA=m
+CONFIG_VIDEO_SAA7134_DVB=m
+CONFIG_VIDEO_SAA7134_DVB_ALL_FRONTENDS=y
+CONFIG_VIDEO_MXB=m
+CONFIG_VIDEO_DPC=m
+CONFIG_VIDEO_HEXIUM_ORION=m
+CONFIG_VIDEO_HEXIUM_GEMINI=m
+CONFIG_VIDEO_CX88_VP3054=m
+CONFIG_VIDEO_CX88=m
+CONFIG_VIDEO_CX88_ALSA=m
+CONFIG_VIDEO_CX88_BLACKBIRD=m
+CONFIG_VIDEO_CX88_DVB=m
+CONFIG_VIDEO_CX88_DVB_ALL_FRONTENDS=y
+
+#
+# Encoders and Decoders
+#
+CONFIG_VIDEO_MSP3400=m
+CONFIG_VIDEO_CS53L32A=m
+CONFIG_VIDEO_TLV320AIC23B=m
+CONFIG_VIDEO_WM8775=m
+CONFIG_VIDEO_WM8739=m
+CONFIG_VIDEO_CX2341X=m
+CONFIG_VIDEO_CX25840=m
+CONFIG_VIDEO_SAA711X=m
+CONFIG_VIDEO_SAA7127=m
+CONFIG_VIDEO_UPD64031A=m
+CONFIG_VIDEO_UPD64083=m
+
+#
+# V4L USB devices
+#
+CONFIG_VIDEO_PVRUSB2=m
+CONFIG_VIDEO_PVRUSB2_24XXX=y
+CONFIG_VIDEO_PVRUSB2_SYSFS=y
+# CONFIG_VIDEO_PVRUSB2_DEBUGIFC is not set
+CONFIG_VIDEO_EM28XX=m
+CONFIG_VIDEO_USBVIDEO=m
+CONFIG_USB_VICAM=m
+CONFIG_USB_IBMCAM=m
+CONFIG_USB_KONICAWC=m
+CONFIG_USB_QUICKCAM_MESSENGER=m
+CONFIG_USB_ET61X251=m
+CONFIG_VIDEO_OVCAMCHIP=m
+CONFIG_USB_W9968CF=m
+CONFIG_USB_OV511=m
+CONFIG_USB_SE401=m
+CONFIG_USB_SN9C102=m
+CONFIG_USB_STV680=m
+CONFIG_USB_ZC0301=m
+CONFIG_USB_PWC=m
+# CONFIG_USB_PWC_DEBUG is not set
+
+#
+# Radio Adapters
+#
+# CONFIG_RADIO_CADET is not set
+# CONFIG_RADIO_RTRACK is not set
+# CONFIG_RADIO_RTRACK2 is not set
+# CONFIG_RADIO_AZTECH is not set
+# CONFIG_RADIO_GEMTEK is not set
+CONFIG_RADIO_GEMTEK_PCI=m
+CONFIG_RADIO_MAXIRADIO=m
+CONFIG_RADIO_MAESTRO=m
+# CONFIG_RADIO_SF16FMI is not set
+# CONFIG_RADIO_SF16FMR2 is not set
+# CONFIG_RADIO_TERRATEC is not set
+# CONFIG_RADIO_TRUST is not set
+# CONFIG_RADIO_TYPHOON is not set
+# CONFIG_RADIO_ZOLTRIX is not set
+CONFIG_USB_DSBR=m
+
+#
+# Digital Video Broadcasting Devices
+#
+CONFIG_DVB=y
+CONFIG_DVB_CORE=m
+
+#
+# Supported SAA7146 based PCI Adapters
+#
+CONFIG_DVB_AV7110=m
+CONFIG_DVB_AV7110_OSD=y
+CONFIG_DVB_BUDGET=m
+CONFIG_DVB_BUDGET_CI=m
+CONFIG_DVB_BUDGET_AV=m
+CONFIG_DVB_BUDGET_PATCH=m
+
+#
+# Supported USB Adapters
+#
+CONFIG_DVB_USB=m
+# CONFIG_DVB_USB_DEBUG is not set
+CONFIG_DVB_USB_A800=m
+CONFIG_DVB_USB_DIBUSB_MB=m
+# CONFIG_DVB_USB_DIBUSB_MB_FAULTY is not set
+CONFIG_DVB_USB_DIBUSB_MC=m
+CONFIG_DVB_USB_UMT_010=m
+CONFIG_DVB_USB_CXUSB=m
+CONFIG_DVB_USB_DIGITV=m
+CONFIG_DVB_USB_VP7045=m
+CONFIG_DVB_USB_VP702X=m
+CONFIG_DVB_USB_GP8PSK=m
+CONFIG_DVB_USB_NOVA_T_USB2=m
+CONFIG_DVB_USB_DTT200U=m
+CONFIG_DVB_TTUSB_BUDGET=m
+CONFIG_DVB_TTUSB_DEC=m
+CONFIG_DVB_CINERGYT2=m
+CONFIG_DVB_CINERGYT2_TUNING=y
+CONFIG_DVB_CINERGYT2_STREAM_URB_COUNT=32
+CONFIG_DVB_CINERGYT2_STREAM_BUF_SIZE=512
+CONFIG_DVB_CINERGYT2_QUERY_INTERVAL=250
+CONFIG_DVB_CINERGYT2_ENABLE_RC_INPUT_DEVICE=y
+CONFIG_DVB_CINERGYT2_RC_QUERY_INTERVAL=100
+
+#
+# Supported FlexCopII (B2C2) Adapters
+#
+CONFIG_DVB_B2C2_FLEXCOP=m
+CONFIG_DVB_B2C2_FLEXCOP_PCI=m
+CONFIG_DVB_B2C2_FLEXCOP_USB=m
+# CONFIG_DVB_B2C2_FLEXCOP_DEBUG is not set
+
+#
+# Supported BT878 Adapters
+#
+CONFIG_DVB_BT8XX=m
+
+#
+# Supported Pluto2 Adapters
+#
+CONFIG_DVB_PLUTO2=m
+
+#
+# Supported DVB Frontends
+#
+
+#
+# Customise DVB Frontends
+#
+
+#
+# DVB-S (satellite) frontends
+#
+CONFIG_DVB_STV0299=m
+CONFIG_DVB_CX24110=m
+CONFIG_DVB_CX24123=m
+CONFIG_DVB_TDA8083=m
+CONFIG_DVB_MT312=m
+CONFIG_DVB_VES1X93=m
+CONFIG_DVB_S5H1420=m
+
+#
+# DVB-T (terrestrial) frontends
+#
+CONFIG_DVB_SP8870=m
+CONFIG_DVB_SP887X=m
+CONFIG_DVB_CX22700=m
+CONFIG_DVB_CX22702=m
+CONFIG_DVB_L64781=m
+CONFIG_DVB_TDA1004X=m
+CONFIG_DVB_NXT6000=m
+CONFIG_DVB_MT352=m
+CONFIG_DVB_ZL10353=m
+CONFIG_DVB_DIB3000MB=m
+CONFIG_DVB_DIB3000MC=m
+
+#
+# DVB-C (cable) frontends
+#
+CONFIG_DVB_VES1820=m
+CONFIG_DVB_TDA10021=m
+CONFIG_DVB_STV0297=m
+
+#
+# ATSC (North American/Korean Terrestrial/Cable DTV) frontends
+#
+CONFIG_DVB_NXT200X=m
+CONFIG_DVB_OR51211=m
+CONFIG_DVB_OR51132=m
+CONFIG_DVB_BCM3510=m
+CONFIG_DVB_LGDT330X=m
+
+#
+# Miscellaneous devices
+#
+CONFIG_DVB_PLL=m
+CONFIG_DVB_LNBP21=m
+CONFIG_DVB_ISL6421=m
+CONFIG_VIDEO_SAA7146=m
+CONFIG_VIDEO_SAA7146_VV=m
+CONFIG_VIDEO_VIDEOBUF=m
+CONFIG_VIDEO_TUNER=m
+CONFIG_VIDEO_BUF=m
+CONFIG_VIDEO_BUF_DVB=m
+CONFIG_VIDEO_BTCX=m
+CONFIG_VIDEO_IR=m
+CONFIG_VIDEO_TVEEPROM=m
+CONFIG_USB_DABUSB=m
+
+#
+# Graphics support
+#
+# CONFIG_FIRMWARE_EDID is not set
+CONFIG_FB=y
+CONFIG_FB_CFB_FILLRECT=y
+CONFIG_FB_CFB_COPYAREA=y
+CONFIG_FB_CFB_IMAGEBLIT=y
+# CONFIG_FB_MACMODES is not set
+# CONFIG_FB_BACKLIGHT is not set
+CONFIG_FB_MODE_HELPERS=y
+CONFIG_FB_TILEBLITTING=y
+CONFIG_FB_CIRRUS=m
+# CONFIG_FB_PM2 is not set
+# CONFIG_FB_CYBER2000 is not set
+# CONFIG_FB_ARC is not set
+# CONFIG_FB_ASILIANT is not set
+# CONFIG_FB_IMSTT is not set
+CONFIG_FB_VGA16=m
+CONFIG_FB_VESA=y
+# CONFIG_FB_IMAC is not set
+# CONFIG_FB_HGA is not set
+# CONFIG_FB_S1D13XXX is not set
+CONFIG_FB_NVIDIA=m
+CONFIG_FB_NVIDIA_I2C=y
+CONFIG_FB_RIVA=m
+# CONFIG_FB_RIVA_I2C is not set
+# CONFIG_FB_RIVA_DEBUG is not set
+CONFIG_FB_I810=m
+CONFIG_FB_I810_GTF=y
+CONFIG_FB_I810_I2C=y
+CONFIG_FB_INTEL=m
+# CONFIG_FB_INTEL_DEBUG is not set
+CONFIG_FB_MATROX=m
+CONFIG_FB_MATROX_MILLENIUM=y
+CONFIG_FB_MATROX_MYSTIQUE=y
+CONFIG_FB_MATROX_G=y
+CONFIG_FB_MATROX_I2C=m
+CONFIG_FB_MATROX_MAVEN=m
+CONFIG_FB_MATROX_MULTIHEAD=y
+CONFIG_FB_RADEON=m
+CONFIG_FB_RADEON_I2C=y
+# CONFIG_FB_RADEON_DEBUG is not set
+CONFIG_FB_ATY128=m
+CONFIG_FB_ATY=m
+CONFIG_FB_ATY_CT=y
+CONFIG_FB_ATY_GENERIC_LCD=y
+CONFIG_FB_ATY_GX=y
+CONFIG_FB_SAVAGE=m
+CONFIG_FB_SAVAGE_I2C=y
+CONFIG_FB_SAVAGE_ACCEL=y
+# CONFIG_FB_SIS is not set
+CONFIG_FB_NEOMAGIC=m
+CONFIG_FB_KYRO=m
+CONFIG_FB_3DFX=m
+CONFIG_FB_3DFX_ACCEL=y
+CONFIG_FB_VOODOO1=m
+CONFIG_FB_CYBLA=m
+CONFIG_FB_TRIDENT=m
+CONFIG_FB_TRIDENT_ACCEL=y
+# CONFIG_FB_GEODE is not set
+# CONFIG_FB_VIRTUAL is not set
+
+#
+# Console display driver support
+#
+CONFIG_VGA_CONSOLE=y
+CONFIG_VGACON_SOFT_SCROLLBACK=y
+CONFIG_VGACON_SOFT_SCROLLBACK_SIZE=64
+CONFIG_VIDEO_SELECT=y
+# CONFIG_MDA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y
+# CONFIG_FONTS is not set
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
+
+#
+# Logo configuration
+#
+CONFIG_LOGO=y
+# CONFIG_LOGO_LINUX_MONO is not set
+# CONFIG_LOGO_LINUX_VGA16 is not set
+CONFIG_LOGO_LINUX_CLUT224=y
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+CONFIG_BACKLIGHT_CLASS_DEVICE=m
+CONFIG_BACKLIGHT_DEVICE=y
+CONFIG_LCD_CLASS_DEVICE=m
+CONFIG_LCD_DEVICE=y
+
+#
+# Sound
+#
+CONFIG_SOUND=m
+
+#
+# Advanced Linux Sound Architecture
+#
+CONFIG_SND=m
+CONFIG_SND_TIMER=m
+CONFIG_SND_PCM=m
+CONFIG_SND_HWDEP=m
+CONFIG_SND_RAWMIDI=m
+CONFIG_SND_SEQUENCER=m
+CONFIG_SND_SEQ_DUMMY=m
+CONFIG_SND_OSSEMUL=y
+CONFIG_SND_MIXER_OSS=m
+CONFIG_SND_PCM_OSS=m
+CONFIG_SND_PCM_OSS_PLUGINS=y
+CONFIG_SND_SEQUENCER_OSS=y
+CONFIG_SND_RTCTIMER=m
+CONFIG_SND_SEQ_RTCTIMER_DEFAULT=y
+CONFIG_SND_DYNAMIC_MINORS=y
+# CONFIG_SND_SUPPORT_OLD_API is not set
+CONFIG_SND_VERBOSE_PROCFS=y
+# CONFIG_SND_VERBOSE_PRINTK is not set
+# CONFIG_SND_DEBUG is not set
+
+#
+# Generic devices
+#
+CONFIG_SND_MPU401_UART=m
+CONFIG_SND_OPL3_LIB=m
+CONFIG_SND_OPL4_LIB=m
+CONFIG_SND_VX_LIB=m
+CONFIG_SND_AC97_CODEC=m
+CONFIG_SND_AC97_BUS=m
+CONFIG_SND_DUMMY=m
+CONFIG_SND_VIRMIDI=m
+CONFIG_SND_MTPAV=m
+# CONFIG_SND_SERIAL_U16550 is not set
+CONFIG_SND_MPU401=m
+
+#
+# ISA devices
+#
+CONFIG_SND_CS4231_LIB=m
+CONFIG_SND_ADLIB=m
+# CONFIG_SND_AD1816A is not set
+# CONFIG_SND_AD1848 is not set
+# CONFIG_SND_ALS100 is not set
+# CONFIG_SND_AZT2320 is not set
+# CONFIG_SND_CMI8330 is not set
+# CONFIG_SND_CS4231 is not set
+# CONFIG_SND_CS4232 is not set
+CONFIG_SND_CS4236=m
+# CONFIG_SND_DT019X is not set
+# CONFIG_SND_ES968 is not set
+# CONFIG_SND_ES1688 is not set
+CONFIG_SND_ES18XX=m
+# CONFIG_SND_GUSCLASSIC is not set
+# CONFIG_SND_GUSEXTREME is not set
+# CONFIG_SND_GUSMAX is not set
+# CONFIG_SND_INTERWAVE is not set
+# CONFIG_SND_INTERWAVE_STB is not set
+CONFIG_SND_OPL3SA2=m
+# CONFIG_SND_OPTI92X_AD1848 is not set
+# CONFIG_SND_OPTI92X_CS4231 is not set
+# CONFIG_SND_OPTI93X is not set
+CONFIG_SND_MIRO=m
+# CONFIG_SND_SB8 is not set
+CONFIG_SND_SB16=m
+CONFIG_SND_SBAWE=m
+# CONFIG_SND_SB16_CSP is not set
+# CONFIG_SND_SGALAXY is not set
+# CONFIG_SND_SSCAPE is not set
+# CONFIG_SND_WAVEFRONT is not set
+
+#
+# PCI devices
+#
+CONFIG_SND_AD1889=m
+CONFIG_SND_ALS300=m
+CONFIG_SND_ALS4000=m
+CONFIG_SND_ALI5451=m
+CONFIG_SND_ATIIXP=m
+CONFIG_SND_ATIIXP_MODEM=m
+CONFIG_SND_AU8810=m
+CONFIG_SND_AU8820=m
+CONFIG_SND_AU8830=m
+CONFIG_SND_AZT3328=m
+CONFIG_SND_BT87X=m
+# CONFIG_SND_BT87X_OVERCLOCK is not set
+CONFIG_SND_CA0106=m
+CONFIG_SND_CMIPCI=m
+CONFIG_SND_CS4281=m
+CONFIG_SND_CS46XX=m
+CONFIG_SND_CS46XX_NEW_DSP=y
+CONFIG_SND_CS5535AUDIO=m
+CONFIG_SND_DARLA20=m
+CONFIG_SND_GINA20=m
+CONFIG_SND_LAYLA20=m
+CONFIG_SND_DARLA24=m
+CONFIG_SND_GINA24=m
+CONFIG_SND_LAYLA24=m
+CONFIG_SND_MONA=m
+CONFIG_SND_MIA=m
+CONFIG_SND_ECHO3G=m
+CONFIG_SND_INDIGO=m
+CONFIG_SND_INDIGOIO=m
+CONFIG_SND_INDIGODJ=m
+CONFIG_SND_EMU10K1=m
+CONFIG_SND_EMU10K1X=m
+CONFIG_SND_ENS1370=m
+CONFIG_SND_ENS1371=m
+CONFIG_SND_ES1938=m
+CONFIG_SND_ES1968=m
+CONFIG_SND_FM801=m
+CONFIG_SND_FM801_TEA575X_BOOL=y
+CONFIG_SND_FM801_TEA575X=m
+CONFIG_SND_HDA_INTEL=m
+CONFIG_SND_HDSP=m
+CONFIG_SND_HDSPM=m
+CONFIG_SND_ICE1712=m
+CONFIG_SND_ICE1724=m
+CONFIG_SND_INTEL8X0=m
+CONFIG_SND_INTEL8X0M=m
+CONFIG_SND_KORG1212=m
+CONFIG_SND_MAESTRO3=m
+CONFIG_SND_MIXART=m
+CONFIG_SND_NM256=m
+CONFIG_SND_PCXHR=m
+CONFIG_SND_RIPTIDE=m
+CONFIG_SND_RME32=m
+CONFIG_SND_RME96=m
+CONFIG_SND_RME9652=m
+CONFIG_SND_SONICVIBES=m
+CONFIG_SND_TRIDENT=m
+CONFIG_SND_VIA82XX=m
+CONFIG_SND_VIA82XX_MODEM=m
+CONFIG_SND_VX222=m
+CONFIG_SND_YMFPCI=m
+
+#
+# USB devices
+#
+CONFIG_SND_USB_AUDIO=m
+CONFIG_SND_USB_USX2Y=m
+
+#
+# PCMCIA devices
+#
+# CONFIG_SND_VXPOCKET is not set
+# CONFIG_SND_PDAUDIOCF is not set
+
+#
+# Open Sound System
+#
+# CONFIG_SOUND_PRIME is not set
+
+#
+# USB support
+#
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB_ARCH_HAS_EHCI=y
+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_SUSPEND is not set
+# CONFIG_USB_OTG is not set
+
+#
+# USB Host Controller Drivers
+#
+CONFIG_USB_EHCI_HCD=m
+CONFIG_USB_EHCI_SPLIT_ISO=y
+CONFIG_USB_EHCI_ROOT_HUB_TT=y
+CONFIG_USB_EHCI_TT_NEWSCHED=y
+CONFIG_USB_ISP116X_HCD=m
+CONFIG_USB_OHCI_HCD=m
+# CONFIG_USB_OHCI_BIG_ENDIAN is not set
+CONFIG_USB_OHCI_LITTLE_ENDIAN=y
+CONFIG_USB_UHCI_HCD=m
+CONFIG_USB_SL811_HCD=m
+CONFIG_USB_SL811_CS=m
+
+#
+# USB Device Class drivers
+#
+CONFIG_USB_ACM=m
+CONFIG_USB_PRINTER=m
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+#
+
+#
+# may also be needed; see USB_STORAGE Help for more information
+#
+CONFIG_USB_STORAGE=m
+# CONFIG_USB_STORAGE_DEBUG is not set
+CONFIG_USB_STORAGE_DATAFAB=y
+CONFIG_USB_STORAGE_FREECOM=y
+CONFIG_USB_STORAGE_ISD200=y
+CONFIG_USB_STORAGE_DPCM=y
+CONFIG_USB_STORAGE_USBAT=y
+CONFIG_USB_STORAGE_SDDR09=y
+CONFIG_USB_STORAGE_SDDR55=y
+CONFIG_USB_STORAGE_JUMPSHOT=y
+CONFIG_USB_STORAGE_ALAUDA=y
+CONFIG_USB_LIBUSUAL=y
+
+#
+# USB Input Devices
+#
+CONFIG_USB_HID=y
+CONFIG_USB_HIDINPUT=y
+CONFIG_USB_HIDINPUT_POWERBOOK=y
+CONFIG_HID_FF=y
+CONFIG_HID_PID=y
+CONFIG_LOGITECH_FF=y
+CONFIG_THRUSTMASTER_FF=y
+CONFIG_USB_HIDDEV=y
+CONFIG_USB_AIPTEK=m
+CONFIG_USB_WACOM=m
+CONFIG_USB_ACECAD=m
+CONFIG_USB_KBTAB=m
+CONFIG_USB_POWERMATE=m
+CONFIG_USB_TOUCHSCREEN=m
+CONFIG_USB_TOUCHSCREEN_EGALAX=y
+CONFIG_USB_TOUCHSCREEN_PANJIT=y
+CONFIG_USB_TOUCHSCREEN_3M=y
+CONFIG_USB_TOUCHSCREEN_ITM=y
+# CONFIG_USB_YEALINK is not set
+CONFIG_USB_XPAD=m
+CONFIG_USB_ATI_REMOTE=m
+CONFIG_USB_ATI_REMOTE2=m
+CONFIG_USB_KEYSPAN_REMOTE=m
+CONFIG_USB_APPLETOUCH=m
+
+#
+# USB Imaging devices
+#
+CONFIG_USB_MDC800=m
+CONFIG_USB_MICROTEK=m
+
+#
+# USB Network Adapters
+#
+CONFIG_USB_CATC=m
+CONFIG_USB_KAWETH=m
+CONFIG_USB_PEGASUS=m
+CONFIG_USB_RTL8150=m
+CONFIG_USB_USBNET=m
+CONFIG_USB_NET_AX8817X=m
+CONFIG_USB_NET_CDCETHER=m
+CONFIG_USB_NET_GL620A=m
+CONFIG_USB_NET_NET1080=m
+CONFIG_USB_NET_PLUSB=m
+CONFIG_USB_NET_RNDIS_HOST=m
+CONFIG_USB_NET_CDC_SUBSET=m
+CONFIG_USB_ALI_M5632=y
+CONFIG_USB_AN2720=y
+CONFIG_USB_BELKIN=y
+CONFIG_USB_ARMLINUX=y
+CONFIG_USB_EPSON2888=y
+CONFIG_USB_NET_ZAURUS=m
+CONFIG_USB_MON=y
+
+#
+# USB port drivers
+#
+CONFIG_USB_USS720=m
+
+#
+# USB Serial Converter support
+#
+CONFIG_USB_SERIAL=m
+CONFIG_USB_SERIAL_GENERIC=y
+CONFIG_USB_SERIAL_AIRPRIME=m
+CONFIG_USB_SERIAL_ARK3116=m
+CONFIG_USB_SERIAL_BELKIN=m
+CONFIG_USB_SERIAL_WHITEHEAT=m
+CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m
+CONFIG_USB_SERIAL_CP2101=m
+CONFIG_USB_SERIAL_CYPRESS_M8=m
+CONFIG_USB_SERIAL_EMPEG=m
+CONFIG_USB_SERIAL_FTDI_SIO=m
+CONFIG_USB_SERIAL_FUNSOFT=m
+CONFIG_USB_SERIAL_VISOR=m
+CONFIG_USB_SERIAL_IPAQ=m
+CONFIG_USB_SERIAL_IR=m
+CONFIG_USB_SERIAL_EDGEPORT=m
+CONFIG_USB_SERIAL_EDGEPORT_TI=m
+CONFIG_USB_SERIAL_GARMIN=m
+CONFIG_USB_SERIAL_IPW=m
+CONFIG_USB_SERIAL_KEYSPAN_PDA=m
+CONFIG_USB_SERIAL_KEYSPAN=m
+CONFIG_USB_SERIAL_KEYSPAN_MPR=y
+CONFIG_USB_SERIAL_KEYSPAN_USA28=y
+CONFIG_USB_SERIAL_KEYSPAN_USA28X=y
+CONFIG_USB_SERIAL_KEYSPAN_USA28XA=y
+CONFIG_USB_SERIAL_KEYSPAN_USA28XB=y
+CONFIG_USB_SERIAL_KEYSPAN_USA19=y
+CONFIG_USB_SERIAL_KEYSPAN_USA18X=y
+CONFIG_USB_SERIAL_KEYSPAN_USA19W=y
+CONFIG_USB_SERIAL_KEYSPAN_USA19QW=y
+CONFIG_USB_SERIAL_KEYSPAN_USA19QI=y
+CONFIG_USB_SERIAL_KEYSPAN_USA49W=y
+CONFIG_USB_SERIAL_KEYSPAN_USA49WLC=y
+CONFIG_USB_SERIAL_KLSI=m
+CONFIG_USB_SERIAL_KOBIL_SCT=m
+CONFIG_USB_SERIAL_MCT_U232=m
+CONFIG_USB_SERIAL_NAVMAN=m
+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=m
+CONFIG_USB_SERIAL_TI=m
+CONFIG_USB_SERIAL_CYBERJACK=m
+CONFIG_USB_SERIAL_XIRCOM=m
+CONFIG_USB_SERIAL_OPTION=m
+CONFIG_USB_SERIAL_OMNINET=m
+CONFIG_USB_EZUSB=y
+
+#
+# USB Miscellaneous drivers
+#
+CONFIG_USB_EMI62=m
+CONFIG_USB_EMI26=m
+CONFIG_USB_AUERSWALD=m
+CONFIG_USB_RIO500=m
+CONFIG_USB_LEGOTOWER=m
+CONFIG_USB_LCD=m
+CONFIG_USB_LED=m
+# CONFIG_USB_CYPRESS_CY7C63 is not set
+# CONFIG_USB_CYTHERM is not set
+CONFIG_USB_PHIDGETKIT=m
+CONFIG_USB_PHIDGETSERVO=m
+CONFIG_USB_IDMOUSE=m
+CONFIG_USB_APPLEDISPLAY=m
+CONFIG_USB_SISUSBVGA=m
+CONFIG_USB_SISUSBVGA_CON=y
+CONFIG_USB_LD=m
+CONFIG_USB_TEST=m
+
+#
+# USB DSL modem support
+#
+CONFIG_USB_ATM=m
+CONFIG_USB_SPEEDTOUCH=m
+CONFIG_USB_CXACRU=m
+CONFIG_USB_UEAGLEATM=m
+CONFIG_USB_XUSBATM=m
+
+#
+# USB Gadget Support
+#
+# CONFIG_USB_GADGET is not set
+
+#
+# MMC/SD Card support
+#
+CONFIG_MMC=m
+# CONFIG_MMC_DEBUG is not set
+CONFIG_MMC_BLOCK=m
+CONFIG_MMC_SDHCI=m
+CONFIG_MMC_WBSD=m
+
+#
+# LED devices
+#
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+
+#
+# LED drivers
+#
+
+#
+# LED Triggers
+#
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_LEDS_TRIGGER_TIMER=m
+CONFIG_LEDS_TRIGGER_IDE_DISK=y
+CONFIG_LEDS_TRIGGER_HEARTBEAT=m
+
+#
+# InfiniBand support
+#
+CONFIG_INFINIBAND=m
+CONFIG_INFINIBAND_USER_MAD=m
+CONFIG_INFINIBAND_USER_ACCESS=m
+CONFIG_INFINIBAND_ADDR_TRANS=y
+CONFIG_INFINIBAND_MTHCA=m
+CONFIG_INFINIBAND_MTHCA_DEBUG=y
+CONFIG_INFINIBAND_IPOIB=m
+CONFIG_INFINIBAND_IPOIB_DEBUG=y
+CONFIG_INFINIBAND_IPOIB_DEBUG_DATA=y
+CONFIG_INFINIBAND_SRP=m
+CONFIG_INFINIBAND_ISER=m
+
+#
+# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
+#
+CONFIG_EDAC=y
+
+#
+# Reporting subsystems
+#
+# CONFIG_EDAC_DEBUG is not set
+CONFIG_EDAC_MM_EDAC=m
+CONFIG_EDAC_AMD76X=m
+CONFIG_EDAC_E7XXX=m
+CONFIG_EDAC_E752X=m
+CONFIG_EDAC_I82875P=m
+CONFIG_EDAC_I82860=m
+CONFIG_EDAC_K8=m
+CONFIG_EDAC_R82600=m
+CONFIG_EDAC_POLL=y
+
+#
+# Real Time Clock
+#
+CONFIG_RTC_LIB=m
+CONFIG_RTC_CLASS=m
+
+#
+# RTC interfaces
+#
+CONFIG_RTC_INTF_SYSFS=m
+CONFIG_RTC_INTF_PROC=m
+CONFIG_RTC_INTF_DEV=m
+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
+
+#
+# RTC drivers
+#
+CONFIG_RTC_DRV_X1205=m
+CONFIG_RTC_DRV_DS1307=m
+CONFIG_RTC_DRV_DS1553=m
+CONFIG_RTC_DRV_ISL1208=m
+CONFIG_RTC_DRV_DS1672=m
+CONFIG_RTC_DRV_DS1742=m
+CONFIG_RTC_DRV_PCF8563=m
+CONFIG_RTC_DRV_PCF8583=m
+CONFIG_RTC_DRV_RS5C372=m
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_TEST is not set
+CONFIG_RTC_DRV_V3020=m
+
+#
+# DMA Engine support
+#
+CONFIG_DMA_ENGINE=y
+
+#
+# DMA Clients
+#
+CONFIG_NET_DMA=y
+
+#
+# DMA Devices
+#
+CONFIG_INTEL_IOATDMA=m
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+CONFIG_EXT2_FS_POSIX_ACL=y
+CONFIG_EXT2_FS_SECURITY=y
+CONFIG_EXT2_FS_XIP=y
+CONFIG_FS_XIP=y
+CONFIG_EXT3_FS=m
+CONFIG_EXT3_FS_XATTR=y
+CONFIG_EXT3_FS_POSIX_ACL=y
+CONFIG_EXT3_FS_SECURITY=y
+CONFIG_JBD=m
+# CONFIG_JBD_DEBUG is not set
+CONFIG_FS_MBCACHE=y
+CONFIG_REISERFS_FS=m
+# CONFIG_REISERFS_CHECK is not set
+CONFIG_REISERFS_PROC_INFO=y
+CONFIG_REISERFS_FS_XATTR=y
+CONFIG_REISERFS_FS_POSIX_ACL=y
+CONFIG_REISERFS_FS_SECURITY=y
+CONFIG_JFS_FS=m
+CONFIG_JFS_POSIX_ACL=y
+CONFIG_JFS_SECURITY=y
+# CONFIG_JFS_DEBUG is not set
+# CONFIG_JFS_STATISTICS is not set
+CONFIG_FS_POSIX_ACL=y
+CONFIG_XFS_FS=m
+CONFIG_XFS_QUOTA=y
+CONFIG_XFS_SECURITY=y
+CONFIG_XFS_POSIX_ACL=y
+# CONFIG_XFS_RT is not set
+CONFIG_OCFS2_FS=m
+# CONFIG_OCFS2_DEBUG_MASKLOG is not set
+CONFIG_MINIX_FS=m
+CONFIG_ROMFS_FS=m
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+CONFIG_QUOTA=y
+# CONFIG_QFMT_V1 is not set
+CONFIG_QFMT_V2=y
+CONFIG_QUOTACTL=y
+CONFIG_DNOTIFY=y
+CONFIG_AUTOFS_FS=m
+CONFIG_AUTOFS4_FS=m
+CONFIG_FUSE_FS=m
+
+#
+# Caches
+#
+CONFIG_FSCACHE=m
+
+#
+# CD-ROM/DVD Filesystems
+#
+CONFIG_ISO9660_FS=y
+CONFIG_JOLIET=y
+CONFIG_ZISOFS=y
+CONFIG_ZISOFS_FS=y
+CONFIG_UDF_FS=m
+CONFIG_UDF_NLS=y
+CONFIG_CACHEFILES=m
+CONFIG_CACHEFILES_DEBUG=y
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=m
+CONFIG_MSDOS_FS=m
+CONFIG_VFAT_FS=m
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="ascii"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_PROC_VMCORE=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+CONFIG_HUGETLBFS=y
+CONFIG_HUGETLB_PAGE=y
+CONFIG_RAMFS=y
+CONFIG_CONFIGFS_FS=m
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+CONFIG_AFFS_FS=m
+CONFIG_HFS_FS=m
+CONFIG_HFSPLUS_FS=m
+CONFIG_BEFS_FS=m
+# CONFIG_BEFS_DEBUG is not set
+CONFIG_BFS_FS=m
+CONFIG_EFS_FS=m
+# CONFIG_JFFS_FS is not set
+CONFIG_JFFS2_FS=m
+CONFIG_JFFS2_FS_DEBUG=0
+CONFIG_JFFS2_FS_WRITEBUFFER=y
+CONFIG_JFFS2_SUMMARY=y
+# 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=m
+CONFIG_SQUASHFS=m
+# CONFIG_SQUASHFS_EMBEDDED is not set
+CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3
+# CONFIG_SQUASHFS_VMALLOC is not set
+CONFIG_VXFS_FS=m
+# CONFIG_HPFS_FS is not set
+CONFIG_QNX4FS_FS=m
+CONFIG_SYSV_FS=m
+CONFIG_UFS_FS=m
+# CONFIG_UFS_FS_WRITE is not set
+# CONFIG_UFS_DEBUG is not set
+
+#
+# Network File Systems
+#
+CONFIG_NFS_FS=m
+CONFIG_NFS_V3=y
+CONFIG_NFS_V3_ACL=y
+CONFIG_NFS_V4=y
+CONFIG_NFS_FSCACHE=y
+CONFIG_NFS_DIRECTIO=y
+CONFIG_NFSD=m
+CONFIG_NFSD_V2_ACL=y
+CONFIG_NFSD_V3=y
+CONFIG_NFSD_V3_ACL=y
+CONFIG_NFSD_V4=y
+CONFIG_NFSD_TCP=y
+CONFIG_LOCKD=m
+CONFIG_LOCKD_V4=y
+CONFIG_EXPORTFS=m
+CONFIG_NFS_ACL_SUPPORT=m
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=m
+CONFIG_SUNRPC_GSS=m
+CONFIG_RPCSEC_GSS_KRB5=m
+CONFIG_RPCSEC_GSS_SPKM3=m
+# CONFIG_SMB_FS is not set
+CONFIG_CIFS=m
+# CONFIG_CIFS_STATS is not set
+CONFIG_CIFS_WEAK_PW_HASH=y
+CONFIG_CIFS_XATTR=y
+CONFIG_CIFS_POSIX=y
+# CONFIG_CIFS_DEBUG2 is not set
+# CONFIG_CIFS_EXPERIMENTAL is not set
+CONFIG_NCP_FS=m
+CONFIG_NCPFS_PACKET_SIGNING=y
+CONFIG_NCPFS_IOCTL_LOCKING=y
+CONFIG_NCPFS_STRONG=y
+CONFIG_NCPFS_NFS_NS=y
+CONFIG_NCPFS_OS2_NS=y
+CONFIG_NCPFS_SMALLDOS=y
+CONFIG_NCPFS_NLS=y
+CONFIG_NCPFS_EXTRAS=y
+CONFIG_CODA_FS=m
+# CONFIG_CODA_FS_OLD_API is not set
+# CONFIG_AFS_FS is not set
+CONFIG_9P_FS=m
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+CONFIG_OSF_PARTITION=y
+CONFIG_AMIGA_PARTITION=y
+# CONFIG_ATARI_PARTITION is not set
+CONFIG_MAC_PARTITION=y
+CONFIG_MSDOS_PARTITION=y
+CONFIG_BSD_DISKLABEL=y
+CONFIG_MINIX_SUBPARTITION=y
+CONFIG_SOLARIS_X86_PARTITION=y
+CONFIG_UNIXWARE_DISKLABEL=y
+# CONFIG_LDM_PARTITION is not set
+CONFIG_SGI_PARTITION=y
+# CONFIG_ULTRIX_PARTITION is not set
+CONFIG_SUN_PARTITION=y
+CONFIG_KARMA_PARTITION=y
+CONFIG_EFI_PARTITION=y
+
+#
+# Native Language Support
+#
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="utf8"
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_CODEPAGE_737=m
+CONFIG_NLS_CODEPAGE_775=m
+CONFIG_NLS_CODEPAGE_850=m
+CONFIG_NLS_CODEPAGE_852=m
+CONFIG_NLS_CODEPAGE_855=m
+CONFIG_NLS_CODEPAGE_857=m
+CONFIG_NLS_CODEPAGE_860=m
+CONFIG_NLS_CODEPAGE_861=m
+CONFIG_NLS_CODEPAGE_862=m
+CONFIG_NLS_CODEPAGE_863=m
+CONFIG_NLS_CODEPAGE_864=m
+CONFIG_NLS_CODEPAGE_865=m
+CONFIG_NLS_CODEPAGE_866=m
+CONFIG_NLS_CODEPAGE_869=m
+CONFIG_NLS_CODEPAGE_936=m
+CONFIG_NLS_CODEPAGE_950=m
+CONFIG_NLS_CODEPAGE_932=m
+CONFIG_NLS_CODEPAGE_949=m
+CONFIG_NLS_CODEPAGE_874=m
+CONFIG_NLS_ISO8859_8=m
+CONFIG_NLS_CODEPAGE_1250=m
+CONFIG_NLS_CODEPAGE_1251=m
+CONFIG_NLS_ASCII=y
+CONFIG_NLS_ISO8859_1=m
+CONFIG_NLS_ISO8859_2=m
+CONFIG_NLS_ISO8859_3=m
+CONFIG_NLS_ISO8859_4=m
+CONFIG_NLS_ISO8859_5=m
+CONFIG_NLS_ISO8859_6=m
+CONFIG_NLS_ISO8859_7=m
+CONFIG_NLS_ISO8859_9=m
+CONFIG_NLS_ISO8859_13=m
+CONFIG_NLS_ISO8859_14=m
+CONFIG_NLS_ISO8859_15=m
+CONFIG_NLS_KOI8_R=m
+CONFIG_NLS_KOI8_U=m
+CONFIG_NLS_UTF8=m
+
+#
+# Instrumentation Support
+#
+CONFIG_PROFILING=y
+CONFIG_OPROFILE=m
+CONFIG_KPROBES=y
+
+#
+# Kernel hacking
+#
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+# CONFIG_PRINTK_TIME is not set
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_UNUSED_SYMBOLS is not set
+CONFIG_DEBUG_KERNEL=y
+CONFIG_LOG_BUF_SHIFT=17
+CONFIG_DETECT_SOFTLOCKUP=y
+CONFIG_SCHEDSTATS=y
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
+CONFIG_DEBUG_SPINLOCK=y
+# 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=y
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+# CONFIG_DEBUG_KOBJECT is not set
+CONFIG_DEBUG_HIGHMEM=y
+CONFIG_DEBUG_BUGVERBOSE=y
+CONFIG_DEBUG_INFO=y
+CONFIG_DEBUG_FS=y
+# CONFIG_DEBUG_VM is not set
+CONFIG_DEBUG_LIST=y
+# CONFIG_FRAME_POINTER is not set
+CONFIG_UNWIND_INFO=y
+CONFIG_STACK_UNWIND=y
+# CONFIG_FORCED_INLINING is not set
+CONFIG_BOOT_DELAY=y
+# CONFIG_RCU_TORTURE_TEST is not set
+CONFIG_EARLY_PRINTK=y
+CONFIG_DEBUG_STACKOVERFLOW=y
+CONFIG_DEBUG_STACK_USAGE=y
+CONFIG_DEBUG_RODATA=y
+CONFIG_4KSTACKS=y
+CONFIG_X86_FIND_SMP_CONFIG=y
+CONFIG_X86_MPPARSE=y
+CONFIG_DOUBLEFAULT=y
+
+#
+# Security options
+#
+CONFIG_KEYS=y
+CONFIG_KEYS_DEBUG_PROC_KEYS=y
+CONFIG_SECURITY=y
+CONFIG_SECURITY_NETWORK=y
+# CONFIG_SECURITY_NETWORK_XFRM is not set
+CONFIG_SECURITY_CAPABILITIES=y
+# CONFIG_SECURITY_ROOTPLUG is not set
+# CONFIG_SECURITY_SECLVL is not set
+CONFIG_SECURITY_SELINUX=y
+CONFIG_SECURITY_SELINUX_BOOTPARAM=y
+CONFIG_SECURITY_SELINUX_BOOTPARAM_VALUE=1
+CONFIG_SECURITY_SELINUX_DISABLE=y
+CONFIG_SECURITY_SELINUX_DEVELOP=y
+CONFIG_SECURITY_SELINUX_AVC_STATS=y
+CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE=1
+# CONFIG_SECURITY_SELINUX_ENABLE_SECMARK_DEFAULT is not set
+# CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX is not set
+
+#
+# Cryptographic options
+#
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_NULL=m
+CONFIG_CRYPTO_MD4=m
+CONFIG_CRYPTO_MD5=m
+CONFIG_CRYPTO_SHA1=y
+CONFIG_CRYPTO_SHA256=m
+CONFIG_CRYPTO_SHA512=m
+CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_TGR192=m
+CONFIG_CRYPTO_DES=m
+CONFIG_CRYPTO_BLOWFISH=m
+CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_SERPENT=m
+CONFIG_CRYPTO_AES=m
+CONFIG_CRYPTO_AES_586=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_TEST is not set
+CONFIG_CRYPTO_SIGNATURE=y
+CONFIG_CRYPTO_SIGNATURE_DSA=y
+CONFIG_CRYPTO_MPILIB=y
+
+#
+# Hardware crypto devices
+#
+CONFIG_CRYPTO_DEV_PADLOCK=m
+CONFIG_CRYPTO_DEV_PADLOCK_AES=y
+
+#
+# Library routines
+#
+CONFIG_CRC_CCITT=m
+CONFIG_CRC16=m
+CONFIG_CRC32=y
+CONFIG_LIBCRC32C=m
+CONFIG_AUDIT_GENERIC=y
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=m
+CONFIG_REED_SOLOMON=m
+CONFIG_REED_SOLOMON_DEC16=y
+CONFIG_TEXTSEARCH=y
+CONFIG_TEXTSEARCH_KMP=m
+CONFIG_TEXTSEARCH_BM=m
+CONFIG_TEXTSEARCH_FSM=m
+CONFIG_PLIST=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_X86_BIOS_REBOOT=y
+CONFIG_KTIME_SCALAR=y
diff --git a/configs/kernel-2.6.18-i686-smp.config b/configs/kernel-2.6.18-i686-smp.config
new file mode 100644
index 000000000..00cc6b483
--- /dev/null
+++ b/configs/kernel-2.6.18-i686-smp.config
@@ -0,0 +1,3414 @@
+# i386
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.18.2-rc1
+# Mon Nov 13 09:44:40 2006
+#
+CONFIG_X86_32=y
+CONFIG_GENERIC_TIME=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_SEMAPHORE_SLEEPERS=y
+CONFIG_X86=y
+CONFIG_MMU=y
+CONFIG_GENERIC_ISA_DMA=y
+CONFIG_GENERIC_IOMAP=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_ARCH_MAY_HAVE_PC_FDC=y
+CONFIG_DMI=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_BSD_PROCESS_ACCT=y
+# CONFIG_BSD_PROCESS_ACCT_V3 is not set
+CONFIG_TASKSTATS=y
+CONFIG_TASK_DELAY_ACCT=y
+CONFIG_AUDIT=y
+CONFIG_AUDITSYSCALL=y
+# CONFIG_IKCONFIG is not set
+CONFIG_CPUSETS=y
+CONFIG_RELAY=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+# CONFIG_EMBEDDED is not set
+CONFIG_UID16=y
+CONFIG_SYSCTL=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
+CONFIG_KALLSYMS_EXTRA_PASS=y
+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=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+CONFIG_MODULE_SIG=y
+# CONFIG_MODULE_SIG_FORCE is not set
+CONFIG_KMOD=y
+CONFIG_STOP_MACHINE=y
+
+#
+# Process debugging support
+#
+CONFIG_UTRACE=y
+CONFIG_PTRACE=y
+
+#
+# Block layer
+#
+CONFIG_LBD=y
+CONFIG_BLK_DEV_IO_TRACE=y
+CONFIG_LSF=y
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_DEFAULT_AS is not set
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+
+#
+# Processor type and features
+#
+CONFIG_SMP=y
+# CONFIG_X86_PC is not set
+# CONFIG_X86_XEN is not set
+# CONFIG_X86_ELAN is not set
+# CONFIG_X86_VOYAGER is not set
+# CONFIG_X86_NUMAQ is not set
+# CONFIG_X86_SUMMIT is not set
+# CONFIG_X86_BIGSMP is not set
+# CONFIG_X86_VISWS is not set
+CONFIG_X86_GENERICARCH=y
+# CONFIG_X86_ES7000 is not set
+CONFIG_X86_CYCLONE_TIMER=y
+# CONFIG_M386 is not set
+# CONFIG_M486 is not set
+# CONFIG_M586 is not set
+# CONFIG_M586TSC is not set
+# CONFIG_M586MMX is not set
+CONFIG_M686=y
+# CONFIG_MPENTIUMII is not set
+# CONFIG_MPENTIUMIII is not set
+# CONFIG_MPENTIUMM is not set
+# CONFIG_MPENTIUM4 is not set
+# CONFIG_MK6 is not set
+# CONFIG_MK7 is not set
+# CONFIG_MK8 is not set
+# CONFIG_MCRUSOE is not set
+# CONFIG_MEFFICEON is not set
+# CONFIG_MWINCHIPC6 is not set
+# CONFIG_MWINCHIP2 is not set
+# CONFIG_MWINCHIP3D is not set
+# CONFIG_MGEODEGX1 is not set
+# CONFIG_MGEODE_LX is not set
+# CONFIG_MCYRIXIII is not set
+# CONFIG_MVIAC3_2 is not set
+CONFIG_X86_GENERIC=y
+CONFIG_X86_CMPXCHG=y
+CONFIG_X86_XADD=y
+CONFIG_X86_L1_CACHE_SHIFT=7
+CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_X86_PPRO_FENCE=y
+CONFIG_X86_WP_WORKS_OK=y
+CONFIG_X86_INVLPG=y
+CONFIG_X86_BSWAP=y
+CONFIG_X86_POPAD_OK=y
+CONFIG_X86_CMPXCHG64=y
+CONFIG_X86_GOOD_APIC=y
+CONFIG_X86_INTEL_USERCOPY=y
+CONFIG_X86_USE_PPRO_CHECKSUM=y
+CONFIG_X86_TSC=y
+CONFIG_HPET_TIMER=y
+CONFIG_HPET_EMULATE_RTC=y
+CONFIG_NR_CPUS=32
+CONFIG_SCHED_SMT=y
+CONFIG_SCHED_MC=y
+# CONFIG_PREEMPT_NONE is not set
+CONFIG_PREEMPT_VOLUNTARY=y
+# CONFIG_PREEMPT is not set
+CONFIG_PREEMPT_BKL=y
+CONFIG_X86_LOCAL_APIC=y
+CONFIG_X86_APIC_AUTO=y
+CONFIG_X86_IO_APIC=y
+CONFIG_X86_MCE=y
+# CONFIG_X86_MCE_NONFATAL is not set
+CONFIG_X86_MCE_P4THERMAL=y
+CONFIG_VM86=y
+CONFIG_TOSHIBA=m
+CONFIG_I8K=m
+# CONFIG_X86_REBOOTFIXUPS is not set
+CONFIG_MICROCODE=m
+CONFIG_X86_MSR=m
+CONFIG_X86_CPUID=m
+# CONFIG_SWIOTLB is not set
+
+#
+# Firmware Drivers
+#
+CONFIG_EDD=m
+CONFIG_EFI_VARS=y
+CONFIG_DELL_RBU=m
+CONFIG_DCDBAS=m
+# CONFIG_NOHIGHMEM is not set
+# CONFIG_HIGHMEM4G is not set
+CONFIG_HIGHMEM64G=y
+CONFIG_PAGE_OFFSET=0xC0000000
+CONFIG_HIGHMEM=y
+CONFIG_X86_PAE=y
+# CONFIG_NUMA 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=y
+CONFIG_HIGHPTE=y
+# CONFIG_MATH_EMULATION is not set
+CONFIG_MTRR=y
+CONFIG_EFI=y
+# CONFIG_IRQBALANCE is not set
+CONFIG_BOOT_IOREMAP=y
+CONFIG_REGPARM=y
+# CONFIG_SECCOMP is not set
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
+CONFIG_KEXEC=y
+# CONFIG_CRASH_DUMP is not set
+CONFIG_PHYSICAL_START=0x400000
+CONFIG_HOTPLUG_CPU=y
+# CONFIG_COMPAT_VDSO is not set
+CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
+
+#
+# Power management options (ACPI, APM)
+#
+CONFIG_PM=y
+CONFIG_PM_LEGACY=y
+# CONFIG_PM_DEBUG is not set
+CONFIG_SUSPEND_SMP=y
+
+#
+# ACPI (Advanced Configuration and Power Interface) Support
+#
+CONFIG_ACPI=y
+CONFIG_ACPI_SLEEP=y
+CONFIG_ACPI_SLEEP_PROC_FS=y
+# CONFIG_ACPI_SLEEP_PROC_SLEEP is not set
+CONFIG_ACPI_AC=m
+CONFIG_ACPI_BATTERY=m
+CONFIG_ACPI_BUTTON=m
+CONFIG_ACPI_VIDEO=m
+# CONFIG_ACPI_HOTKEY is not set
+CONFIG_ACPI_FAN=y
+CONFIG_ACPI_DOCK=m
+CONFIG_ACPI_PROCESSOR=y
+CONFIG_ACPI_HOTPLUG_CPU=y
+CONFIG_ACPI_THERMAL=y
+CONFIG_ACPI_ASUS=m
+CONFIG_ACPI_IBM=m
+CONFIG_ACPI_TOSHIBA=m
+CONFIG_ACPI_BLACKLIST_YEAR=1999
+# CONFIG_ACPI_DEBUG is not set
+CONFIG_ACPI_EC=y
+CONFIG_ACPI_POWER=y
+CONFIG_ACPI_SYSTEM=y
+CONFIG_X86_PM_TIMER=y
+CONFIG_ACPI_CONTAINER=y
+CONFIG_ACPI_SBS=m
+
+#
+# APM (Advanced Power Management) BIOS Support
+#
+CONFIG_APM=y
+# CONFIG_APM_IGNORE_USER_SUSPEND is not set
+# CONFIG_APM_DO_ENABLE is not set
+CONFIG_APM_CPU_IDLE=y
+# CONFIG_APM_DISPLAY_BLANK is not set
+CONFIG_APM_RTC_IS_GMT=y
+# CONFIG_APM_ALLOW_INTS is not set
+# CONFIG_APM_REAL_MODE_POWER_OFF is not set
+
+#
+# CPU Frequency scaling
+#
+CONFIG_CPU_FREQ=y
+CONFIG_CPU_FREQ_TABLE=y
+CONFIG_CPU_FREQ_DEBUG=y
+CONFIG_CPU_FREQ_STAT=m
+CONFIG_CPU_FREQ_STAT_DETAILS=y
+# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set
+CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE=y
+CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
+CONFIG_CPU_FREQ_GOV_POWERSAVE=m
+CONFIG_CPU_FREQ_GOV_USERSPACE=y
+CONFIG_CPU_FREQ_GOV_ONDEMAND=m
+CONFIG_CPU_FREQ_GOV_CONSERVATIVE=m
+
+#
+# CPUFreq processor drivers
+#
+CONFIG_X86_ACPI_CPUFREQ=m
+# CONFIG_X86_POWERNOW_K6 is not set
+CONFIG_X86_POWERNOW_K7=y
+CONFIG_X86_POWERNOW_K7_ACPI=y
+CONFIG_X86_POWERNOW_K8=y
+CONFIG_X86_POWERNOW_K8_ACPI=y
+# CONFIG_X86_GX_SUSPMOD is not set
+CONFIG_X86_SPEEDSTEP_CENTRINO=y
+CONFIG_X86_SPEEDSTEP_CENTRINO_ACPI=y
+CONFIG_X86_SPEEDSTEP_CENTRINO_TABLE=y
+CONFIG_X86_SPEEDSTEP_ICH=y
+CONFIG_X86_SPEEDSTEP_SMI=y
+CONFIG_X86_P4_CLOCKMOD=m
+# CONFIG_X86_CPUFREQ_NFORCE2 is not set
+CONFIG_X86_LONGRUN=y
+# CONFIG_X86_LONGHAUL is not set
+
+#
+# shared options
+#
+# CONFIG_X86_ACPI_CPUFREQ_PROC_INTF is not set
+CONFIG_X86_SPEEDSTEP_LIB=y
+# CONFIG_X86_SPEEDSTEP_RELAXED_CAP_CHECK is not set
+
+#
+# Bus options (PCI, PCMCIA, EISA, MCA, ISA)
+#
+CONFIG_PCI=y
+# CONFIG_PCI_GOBIOS is not set
+# CONFIG_PCI_GOMMCONFIG is not set
+# CONFIG_PCI_GODIRECT is not set
+# CONFIG_PCI_GOXEN_FE is not set
+CONFIG_PCI_GOANY=y
+CONFIG_PCI_BIOS=y
+CONFIG_PCI_DIRECT=y
+CONFIG_PCI_MMCONFIG=y
+CONFIG_PCIEPORTBUS=y
+CONFIG_HOTPLUG_PCI_PCIE=m
+# CONFIG_HOTPLUG_PCI_PCIE_POLL_EVENT_MODE is not set
+CONFIG_PCI_MSI=y
+# CONFIG_PCI_DEBUG is not set
+CONFIG_ISA_DMA_API=y
+CONFIG_ISA=y
+# CONFIG_EISA is not set
+# CONFIG_MCA is not set
+# CONFIG_SCx200 is not set
+CONFIG_K8_NB=y
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+CONFIG_PCCARD=y
+# CONFIG_PCMCIA_DEBUG is not set
+CONFIG_PCMCIA=y
+CONFIG_PCMCIA_LOAD_CIS=y
+CONFIG_PCMCIA_IOCTL=y
+CONFIG_CARDBUS=y
+
+#
+# PC-card bridges
+#
+CONFIG_YENTA=y
+CONFIG_YENTA_O2=y
+CONFIG_YENTA_RICOH=y
+CONFIG_YENTA_TI=y
+CONFIG_YENTA_ENE_TUNE=y
+CONFIG_YENTA_TOSHIBA=y
+CONFIG_PD6729=m
+CONFIG_I82092=m
+# CONFIG_I82365 is not set
+# CONFIG_TCIC is not set
+CONFIG_PCMCIA_PROBE=y
+CONFIG_PCCARD_NONSTATIC=y
+
+#
+# PCI Hotplug Support
+#
+CONFIG_HOTPLUG_PCI=y
+CONFIG_HOTPLUG_PCI_FAKE=m
+CONFIG_HOTPLUG_PCI_COMPAQ=m
+# CONFIG_HOTPLUG_PCI_COMPAQ_NVRAM is not set
+CONFIG_HOTPLUG_PCI_IBM=m
+CONFIG_HOTPLUG_PCI_ACPI=m
+CONFIG_HOTPLUG_PCI_ACPI_IBM=m
+# CONFIG_HOTPLUG_PCI_CPCI is not set
+# CONFIG_HOTPLUG_PCI_SHPC is not set
+
+#
+# Executable file formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_AOUT is not set
+CONFIG_BINFMT_MISC=y
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+# CONFIG_NETDEBUG is not set
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=y
+CONFIG_NET_KEY=m
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_ASK_IP_FIB_HASH=y
+# 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
+# CONFIG_IP_PNP is not set
+CONFIG_NET_IPIP=m
+CONFIG_NET_IPGRE=m
+CONFIG_NET_IPGRE_BROADCAST=y
+CONFIG_IP_MROUTE=y
+CONFIG_IP_PIMSM_V1=y
+CONFIG_IP_PIMSM_V2=y
+# CONFIG_ARPD is not set
+CONFIG_SYN_COOKIES=y
+CONFIG_INET_AH=m
+CONFIG_INET_ESP=m
+CONFIG_INET_IPCOMP=m
+CONFIG_INET_XFRM_TUNNEL=m
+CONFIG_INET_TUNNEL=m
+CONFIG_INET_XFRM_MODE_TRANSPORT=m
+CONFIG_INET_XFRM_MODE_TUNNEL=m
+CONFIG_INET_DIAG=m
+CONFIG_INET_TCP_DIAG=m
+CONFIG_TCP_CONG_ADVANCED=y
+
+#
+# TCP congestion control
+#
+CONFIG_TCP_CONG_BIC=y
+CONFIG_TCP_CONG_CUBIC=m
+CONFIG_TCP_CONG_WESTWOOD=m
+CONFIG_TCP_CONG_HTCP=m
+CONFIG_TCP_CONG_HSTCP=m
+CONFIG_TCP_CONG_HYBLA=m
+CONFIG_TCP_CONG_VEGAS=m
+CONFIG_TCP_CONG_SCALABLE=m
+CONFIG_TCP_CONG_LP=m
+CONFIG_TCP_CONG_VENO=m
+
+#
+# IP: Virtual Server Configuration
+#
+CONFIG_IP_VS=m
+# CONFIG_IP_VS_DEBUG is not set
+CONFIG_IP_VS_TAB_BITS=12
+
+#
+# IPVS transport protocol load balancing support
+#
+CONFIG_IP_VS_PROTO_TCP=y
+CONFIG_IP_VS_PROTO_UDP=y
+CONFIG_IP_VS_PROTO_ESP=y
+CONFIG_IP_VS_PROTO_AH=y
+
+#
+# IPVS scheduler
+#
+CONFIG_IP_VS_RR=m
+CONFIG_IP_VS_WRR=m
+CONFIG_IP_VS_LC=m
+CONFIG_IP_VS_WLC=m
+CONFIG_IP_VS_LBLC=m
+CONFIG_IP_VS_LBLCR=m
+CONFIG_IP_VS_DH=m
+CONFIG_IP_VS_SH=m
+CONFIG_IP_VS_SED=m
+CONFIG_IP_VS_NQ=m
+
+#
+# IPVS application helper
+#
+CONFIG_IP_VS_FTP=m
+CONFIG_IPV6=m
+CONFIG_IPV6_PRIVACY=y
+CONFIG_IPV6_ROUTER_PREF=y
+CONFIG_IPV6_ROUTE_INFO=y
+CONFIG_INET6_AH=m
+CONFIG_INET6_ESP=m
+CONFIG_INET6_IPCOMP=m
+CONFIG_INET6_XFRM_TUNNEL=m
+CONFIG_INET6_TUNNEL=m
+CONFIG_INET6_XFRM_MODE_TRANSPORT=m
+CONFIG_INET6_XFRM_MODE_TUNNEL=m
+CONFIG_IPV6_TUNNEL=m
+CONFIG_NETWORK_SECMARK=y
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_DEBUG is not set
+CONFIG_BRIDGE_NETFILTER=y
+
+#
+# Core Netfilter Configuration
+#
+CONFIG_NETFILTER_NETLINK=m
+CONFIG_NETFILTER_NETLINK_QUEUE=m
+CONFIG_NETFILTER_NETLINK_LOG=m
+CONFIG_NETFILTER_XTABLES=m
+CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
+CONFIG_NETFILTER_XT_TARGET_CONNMARK=m
+CONFIG_NETFILTER_XT_TARGET_MARK=m
+CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
+CONFIG_NETFILTER_XT_TARGET_NOTRACK=m
+CONFIG_NETFILTER_XT_TARGET_SECMARK=m
+CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=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_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_PHYSDEV=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
+
+#
+# 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=m
+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_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_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_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
+CONFIG_IP_NF_ARPTABLES=m
+CONFIG_IP_NF_ARPFILTER=m
+CONFIG_IP_NF_ARP_MANGLE=m
+
+#
+# IPv6: Netfilter Configuration (EXPERIMENTAL)
+#
+CONFIG_IP6_NF_QUEUE=m
+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_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
+
+#
+# DECnet: Netfilter Configuration
+#
+# CONFIG_DECNET_NF_GRABULATOR is not set
+
+#
+# Bridge: Netfilter Configuration
+#
+CONFIG_BRIDGE_NF_EBTABLES=m
+CONFIG_BRIDGE_EBT_BROUTE=m
+CONFIG_BRIDGE_EBT_T_FILTER=m
+CONFIG_BRIDGE_EBT_T_NAT=m
+CONFIG_BRIDGE_EBT_802_3=m
+CONFIG_BRIDGE_EBT_AMONG=m
+CONFIG_BRIDGE_EBT_ARP=m
+CONFIG_BRIDGE_EBT_IP=m
+CONFIG_BRIDGE_EBT_LIMIT=m
+CONFIG_BRIDGE_EBT_MARK=m
+CONFIG_BRIDGE_EBT_PKTTYPE=m
+CONFIG_BRIDGE_EBT_STP=m
+CONFIG_BRIDGE_EBT_VLAN=m
+CONFIG_BRIDGE_EBT_ARPREPLY=m
+CONFIG_BRIDGE_EBT_DNAT=m
+CONFIG_BRIDGE_EBT_MARK_T=m
+CONFIG_BRIDGE_EBT_REDIRECT=m
+CONFIG_BRIDGE_EBT_SNAT=m
+CONFIG_BRIDGE_EBT_LOG=m
+CONFIG_BRIDGE_EBT_ULOG=m
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+CONFIG_IP_DCCP=m
+CONFIG_INET_DCCP_DIAG=m
+CONFIG_IP_DCCP_ACKVEC=y
+
+#
+# DCCP CCIDs Configuration (EXPERIMENTAL)
+#
+CONFIG_IP_DCCP_CCID2=m
+CONFIG_IP_DCCP_CCID3=m
+CONFIG_IP_DCCP_TFRC_LIB=m
+
+#
+# DCCP Kernel Hacking
+#
+# CONFIG_IP_DCCP_DEBUG is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+CONFIG_IP_SCTP=m
+# CONFIG_SCTP_DBG_MSG is not set
+# CONFIG_SCTP_DBG_OBJCNT is not set
+# CONFIG_SCTP_HMAC_NONE is not set
+# CONFIG_SCTP_HMAC_SHA1 is not set
+CONFIG_SCTP_HMAC_MD5=y
+
+#
+# TIPC Configuration (EXPERIMENTAL)
+#
+CONFIG_TIPC=m
+# CONFIG_TIPC_ADVANCED is not set
+# CONFIG_TIPC_DEBUG is not set
+CONFIG_ATM=m
+CONFIG_ATM_CLIP=m
+# CONFIG_ATM_CLIP_NO_ICMP is not set
+CONFIG_ATM_LANE=m
+# CONFIG_ATM_MPOA is not set
+CONFIG_ATM_BR2684=m
+# CONFIG_ATM_BR2684_IPFILTER is not set
+CONFIG_BRIDGE=m
+CONFIG_VLAN_8021Q=m
+CONFIG_DECNET=m
+CONFIG_DECNET_ROUTER=y
+CONFIG_DECNET_ROUTE_FWMARK=y
+CONFIG_LLC=y
+# CONFIG_LLC2 is not set
+CONFIG_IPX=m
+# CONFIG_IPX_INTERN is not set
+CONFIG_ATALK=m
+CONFIG_DEV_APPLETALK=m
+# CONFIG_LTPC is not set
+# CONFIG_COPS is not set
+CONFIG_IPDDP=m
+CONFIG_IPDDP_ENCAP=y
+CONFIG_IPDDP_DECAP=y
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+CONFIG_WAN_ROUTER=m
+
+#
+# QoS and/or fair queueing
+#
+CONFIG_NET_SCHED=y
+# CONFIG_NET_SCH_CLK_JIFFIES is not set
+CONFIG_NET_SCH_CLK_GETTIMEOFDAY=y
+# CONFIG_NET_SCH_CLK_CPU is not set
+
+#
+# Queueing/Scheduling
+#
+CONFIG_NET_SCH_CBQ=m
+CONFIG_NET_SCH_HTB=m
+CONFIG_NET_SCH_HFSC=m
+CONFIG_NET_SCH_ATM=m
+CONFIG_NET_SCH_PRIO=m
+CONFIG_NET_SCH_RED=m
+CONFIG_NET_SCH_SFQ=m
+CONFIG_NET_SCH_TEQL=m
+CONFIG_NET_SCH_TBF=m
+CONFIG_NET_SCH_GRED=m
+CONFIG_NET_SCH_DSMARK=m
+CONFIG_NET_SCH_NETEM=m
+CONFIG_NET_SCH_INGRESS=m
+
+#
+# Classification
+#
+CONFIG_NET_CLS=y
+CONFIG_NET_CLS_BASIC=m
+CONFIG_NET_CLS_TCINDEX=m
+CONFIG_NET_CLS_ROUTE4=m
+CONFIG_NET_CLS_ROUTE=y
+CONFIG_NET_CLS_FW=m
+CONFIG_NET_CLS_U32=m
+CONFIG_CLS_U32_PERF=y
+CONFIG_CLS_U32_MARK=y
+CONFIG_NET_CLS_RSVP=m
+CONFIG_NET_CLS_RSVP6=m
+CONFIG_NET_EMATCH=y
+CONFIG_NET_EMATCH_STACK=32
+CONFIG_NET_EMATCH_CMP=m
+CONFIG_NET_EMATCH_NBYTE=m
+CONFIG_NET_EMATCH_U32=m
+CONFIG_NET_EMATCH_META=m
+CONFIG_NET_EMATCH_TEXT=m
+CONFIG_NET_CLS_ACT=y
+CONFIG_NET_ACT_POLICE=m
+CONFIG_NET_ACT_GACT=m
+CONFIG_GACT_PROB=y
+CONFIG_NET_ACT_MIRRED=m
+CONFIG_NET_ACT_IPT=m
+CONFIG_NET_ACT_PEDIT=m
+CONFIG_NET_ACT_SIMP=m
+CONFIG_NET_CLS_IND=y
+CONFIG_NET_ESTIMATOR=y
+
+#
+# Network testing
+#
+CONFIG_NET_PKTGEN=m
+# CONFIG_NET_TCPPROBE is not set
+# CONFIG_HAMRADIO is not set
+CONFIG_IRDA=m
+
+#
+# IrDA protocols
+#
+CONFIG_IRLAN=m
+CONFIG_IRNET=m
+CONFIG_IRCOMM=m
+# CONFIG_IRDA_ULTRA is not set
+
+#
+# IrDA options
+#
+CONFIG_IRDA_CACHE_LAST_LSAP=y
+CONFIG_IRDA_FAST_RR=y
+# CONFIG_IRDA_DEBUG is not set
+
+#
+# Infrared-port device drivers
+#
+
+#
+# SIR device drivers
+#
+CONFIG_IRTTY_SIR=m
+
+#
+# Dongle support
+#
+CONFIG_DONGLE=y
+CONFIG_ESI_DONGLE=m
+CONFIG_ACTISYS_DONGLE=m
+CONFIG_TEKRAM_DONGLE=m
+CONFIG_TOIM3232_DONGLE=m
+CONFIG_LITELINK_DONGLE=m
+CONFIG_MA600_DONGLE=m
+CONFIG_GIRBIL_DONGLE=m
+CONFIG_MCP2120_DONGLE=m
+CONFIG_OLD_BELKIN_DONGLE=m
+CONFIG_ACT200L_DONGLE=m
+
+#
+# Old SIR device drivers
+#
+
+#
+# Old Serial dongle support
+#
+
+#
+# FIR device drivers
+#
+CONFIG_USB_IRDA=m
+CONFIG_SIGMATEL_FIR=m
+CONFIG_NSC_FIR=m
+CONFIG_WINBOND_FIR=m
+CONFIG_TOSHIBA_FIR=m
+CONFIG_SMC_IRCC_FIR=m
+CONFIG_ALI_FIR=m
+CONFIG_VLSI_FIR=m
+CONFIG_VIA_FIR=m
+CONFIG_MCS_FIR=m
+CONFIG_BT=m
+CONFIG_BT_L2CAP=m
+CONFIG_BT_SCO=m
+CONFIG_BT_RFCOMM=m
+CONFIG_BT_RFCOMM_TTY=y
+CONFIG_BT_BNEP=m
+CONFIG_BT_BNEP_MC_FILTER=y
+CONFIG_BT_BNEP_PROTO_FILTER=y
+CONFIG_BT_CMTP=m
+CONFIG_BT_HIDP=m
+
+#
+# Bluetooth device drivers
+#
+CONFIG_BT_HCIUSB=m
+CONFIG_BT_HCIUSB_SCO=y
+CONFIG_BT_HCIUART=m
+CONFIG_BT_HCIUART_H4=y
+CONFIG_BT_HCIUART_BCSP=y
+CONFIG_BT_HCIBCM203X=m
+CONFIG_BT_HCIBPA10X=m
+CONFIG_BT_HCIBFUSB=m
+CONFIG_BT_HCIDTL1=m
+CONFIG_BT_HCIBT3C=m
+CONFIG_BT_HCIBLUECARD=m
+CONFIG_BT_HCIBTUART=m
+CONFIG_BT_HCIVHCI=m
+CONFIG_IEEE80211=m
+# CONFIG_IEEE80211_DEBUG is not set
+CONFIG_IEEE80211_CRYPT_WEP=m
+CONFIG_IEEE80211_CRYPT_CCMP=m
+CONFIG_IEEE80211_CRYPT_TKIP=m
+CONFIG_IEEE80211_SOFTMAC=m
+CONFIG_IEEE80211_SOFTMAC_DEBUG=y
+CONFIG_TUX=m
+
+#
+# TUX options
+#
+CONFIG_TUX_EXTCGI=y
+CONFIG_TUX_EXTENDED_LOG=y
+# CONFIG_TUX_DEBUG is not set
+CONFIG_WIRELESS_EXT=y
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_SYS_HYPERVISOR is not set
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+CONFIG_CONNECTOR=y
+CONFIG_PROC_EVENTS=y
+
+#
+# Memory Technology Devices (MTD)
+#
+CONFIG_MTD=m
+# CONFIG_MTD_DEBUG is not set
+CONFIG_MTD_CONCAT=m
+CONFIG_MTD_PARTITIONS=y
+CONFIG_MTD_REDBOOT_PARTS=m
+CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1
+# CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED is not set
+# CONFIG_MTD_REDBOOT_PARTS_READONLY is not set
+CONFIG_MTD_CMDLINE_PARTS=y
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=m
+CONFIG_MTD_BLOCK=m
+CONFIG_MTD_BLOCK_RO=m
+CONFIG_FTL=m
+CONFIG_NFTL=m
+CONFIG_NFTL_RW=y
+CONFIG_INFTL=m
+CONFIG_RFD_FTL=m
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=m
+CONFIG_MTD_JEDECPROBE=m
+CONFIG_MTD_GEN_PROBE=m
+# CONFIG_MTD_CFI_ADV_OPTIONS 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_CFI_INTELEXT=m
+CONFIG_MTD_CFI_AMDSTD=m
+CONFIG_MTD_CFI_STAA=m
+CONFIG_MTD_CFI_UTIL=m
+CONFIG_MTD_RAM=m
+CONFIG_MTD_ROM=m
+CONFIG_MTD_ABSENT=m
+# CONFIG_MTD_OBSOLETE_CHIPS is not set
+
+#
+# Mapping drivers for chip access
+#
+CONFIG_MTD_COMPLEX_MAPPINGS=y
+# CONFIG_MTD_PHYSMAP is not set
+# CONFIG_MTD_PNC2000 is not set
+CONFIG_MTD_SC520CDP=m
+CONFIG_MTD_NETSC520=m
+CONFIG_MTD_TS5500=m
+# CONFIG_MTD_SBC_GXX is not set
+# CONFIG_MTD_AMD76XROM is not set
+# CONFIG_MTD_ICHXROM is not set
+CONFIG_MTD_SCB2_FLASH=m
+# CONFIG_MTD_NETtel is not set
+# CONFIG_MTD_DILNETPC is not set
+# CONFIG_MTD_L440GX is not set
+CONFIG_MTD_PCI=m
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+CONFIG_MTD_PMC551=m
+# CONFIG_MTD_PMC551_BUGFIX is not set
+# CONFIG_MTD_PMC551_DEBUG is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+CONFIG_MTD_MTDRAM=m
+CONFIG_MTDRAM_TOTAL_SIZE=4096
+CONFIG_MTDRAM_ERASE_SIZE=128
+CONFIG_MTD_BLOCK2MTD=m
+
+#
+# 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=m
+# CONFIG_MTD_NAND_VERIFY_WRITE is not set
+CONFIG_MTD_NAND_ECC_SMC=y
+CONFIG_MTD_NAND_IDS=m
+CONFIG_MTD_NAND_DISKONCHIP=m
+# CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADVANCED is not set
+CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADDRESS=0
+# CONFIG_MTD_NAND_DISKONCHIP_BBTWRITE is not set
+CONFIG_MTD_NAND_CS553X=m
+CONFIG_MTD_NAND_NANDSIM=m
+
+#
+# OneNAND Flash Device Drivers
+#
+# CONFIG_MTD_ONENAND is not set
+
+#
+# Parallel port support
+#
+CONFIG_PARPORT=m
+CONFIG_PARPORT_PC=m
+CONFIG_PARPORT_SERIAL=m
+# CONFIG_PARPORT_PC_FIFO is not set
+# CONFIG_PARPORT_PC_SUPERIO is not set
+CONFIG_PARPORT_PC_PCMCIA=m
+CONFIG_PARPORT_NOT_PC=y
+# CONFIG_PARPORT_GSC is not set
+# CONFIG_PARPORT_AX88796 is not set
+CONFIG_PARPORT_1284=y
+
+#
+# Plug and Play support
+#
+CONFIG_PNP=y
+# CONFIG_PNP_DEBUG is not set
+
+#
+# Protocols
+#
+CONFIG_ISAPNP=y
+# CONFIG_PNPBIOS is not set
+CONFIG_PNPACPI=y
+
+#
+# Block devices
+#
+CONFIG_BLK_DEV_FD=m
+# CONFIG_BLK_DEV_XD is not set
+CONFIG_PARIDE=m
+CONFIG_PARIDE_PARPORT=m
+
+#
+# Parallel IDE high-level drivers
+#
+CONFIG_PARIDE_PD=m
+CONFIG_PARIDE_PCD=m
+CONFIG_PARIDE_PF=m
+CONFIG_PARIDE_PT=m
+CONFIG_PARIDE_PG=m
+
+#
+# Parallel IDE protocol modules
+#
+CONFIG_PARIDE_ATEN=m
+CONFIG_PARIDE_BPCK=m
+CONFIG_PARIDE_BPCK6=m
+CONFIG_PARIDE_COMM=m
+CONFIG_PARIDE_DSTR=m
+CONFIG_PARIDE_FIT2=m
+CONFIG_PARIDE_FIT3=m
+CONFIG_PARIDE_EPAT=m
+CONFIG_PARIDE_EPATC8=y
+CONFIG_PARIDE_EPIA=m
+CONFIG_PARIDE_FRIQ=m
+CONFIG_PARIDE_FRPW=m
+CONFIG_PARIDE_KBIC=m
+CONFIG_PARIDE_KTTI=m
+CONFIG_PARIDE_ON20=m
+CONFIG_PARIDE_ON26=m
+CONFIG_BLK_CPQ_DA=m
+CONFIG_BLK_CPQ_CISS_DA=m
+CONFIG_CISS_SCSI_TAPE=y
+CONFIG_BLK_DEV_DAC960=m
+CONFIG_BLK_DEV_UMEM=m
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=m
+CONFIG_BLK_DEV_CRYPTOLOOP=m
+CONFIG_BLK_DEV_NBD=m
+CONFIG_BLK_DEV_SX8=m
+CONFIG_BLK_DEV_UB=m
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=16384
+CONFIG_BLK_DEV_RAM_BLOCKSIZE=4096
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_CDROM_PKTCDVD=m
+CONFIG_CDROM_PKTCDVD_BUFFERS=8
+# CONFIG_CDROM_PKTCDVD_WCACHE is not set
+CONFIG_ATA_OVER_ETH=m
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+CONFIG_IDE=y
+CONFIG_BLK_DEV_IDE=y
+
+#
+# Please see Documentation/ide.txt for help/info on IDE drives
+#
+# CONFIG_BLK_DEV_IDE_SATA is not set
+# CONFIG_BLK_DEV_HD_IDE is not set
+CONFIG_BLK_DEV_IDEDISK=y
+CONFIG_IDEDISK_MULTI_MODE=y
+CONFIG_BLK_DEV_IDECS=m
+CONFIG_BLK_DEV_IDECD=m
+# CONFIG_BLK_DEV_IDETAPE is not set
+CONFIG_BLK_DEV_IDEFLOPPY=y
+CONFIG_BLK_DEV_IDESCSI=m
+CONFIG_IDE_TASK_IOCTL=y
+
+#
+# IDE chipset support/bugfixes
+#
+CONFIG_IDE_GENERIC=y
+CONFIG_BLK_DEV_CMD640=y
+CONFIG_BLK_DEV_CMD640_ENHANCED=y
+CONFIG_BLK_DEV_IDEPNP=y
+CONFIG_BLK_DEV_IDEPCI=y
+CONFIG_IDEPCI_SHARE_IRQ=y
+# CONFIG_BLK_DEV_OFFBOARD is not set
+CONFIG_BLK_DEV_GENERIC=y
+# CONFIG_BLK_DEV_OPTI621 is not set
+CONFIG_BLK_DEV_RZ1000=y
+CONFIG_BLK_DEV_IDEDMA_PCI=y
+# CONFIG_BLK_DEV_IDEDMA_FORCED is not set
+CONFIG_IDEDMA_PCI_AUTO=y
+# CONFIG_IDEDMA_ONLYDISK is not set
+CONFIG_BLK_DEV_AEC62XX=y
+CONFIG_BLK_DEV_ALI15X3=y
+# CONFIG_WDC_ALI15X3 is not set
+CONFIG_BLK_DEV_AMD74XX=y
+CONFIG_BLK_DEV_ATIIXP=y
+CONFIG_BLK_DEV_CMD64X=y
+CONFIG_BLK_DEV_TRIFLEX=y
+# CONFIG_BLK_DEV_CY82C693 is not set
+CONFIG_BLK_DEV_CS5520=y
+CONFIG_BLK_DEV_CS5530=y
+CONFIG_BLK_DEV_CS5535=y
+CONFIG_BLK_DEV_HPT34X=y
+# CONFIG_HPT34X_AUTODMA is not set
+CONFIG_BLK_DEV_HPT366=y
+# CONFIG_BLK_DEV_SC1200 is not set
+CONFIG_BLK_DEV_PIIX=y
+CONFIG_BLK_DEV_IT821X=y
+# CONFIG_BLK_DEV_NS87415 is not set
+CONFIG_BLK_DEV_PDC202XX_OLD=y
+# CONFIG_PDC202XX_BURST is not set
+CONFIG_BLK_DEV_PDC202XX_NEW=y
+CONFIG_BLK_DEV_SVWKS=y
+CONFIG_BLK_DEV_SIIMAGE=y
+CONFIG_BLK_DEV_SIS5513=y
+# CONFIG_BLK_DEV_SLC90E66 is not set
+# CONFIG_BLK_DEV_TRM290 is not set
+CONFIG_BLK_DEV_VIA82CXXX=y
+# CONFIG_IDE_ARM is not set
+# CONFIG_IDE_CHIPSETS is not set
+CONFIG_BLK_DEV_IDEDMA=y
+# CONFIG_IDEDMA_IVB is not set
+CONFIG_IDEDMA_AUTO=y
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# SCSI device support
+#
+CONFIG_RAID_ATTRS=m
+CONFIG_SCSI=m
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=m
+CONFIG_CHR_DEV_ST=m
+CONFIG_CHR_DEV_OSST=m
+CONFIG_BLK_DEV_SR=m
+CONFIG_BLK_DEV_SR_VENDOR=y
+CONFIG_CHR_DEV_SG=m
+CONFIG_CHR_DEV_SCH=m
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+CONFIG_SCSI_MULTI_LUN=y
+CONFIG_SCSI_CONSTANTS=y
+CONFIG_SCSI_LOGGING=y
+
+#
+# SCSI Transport Attributes
+#
+CONFIG_SCSI_SPI_ATTRS=m
+CONFIG_SCSI_FC_ATTRS=m
+CONFIG_SCSI_ISCSI_ATTRS=m
+CONFIG_SCSI_SAS_ATTRS=m
+
+#
+# SCSI low-level drivers
+#
+CONFIG_ISCSI_TCP=m
+CONFIG_BLK_DEV_3W_XXXX_RAID=m
+CONFIG_SCSI_3W_9XXX=m
+# CONFIG_SCSI_7000FASST is not set
+CONFIG_SCSI_ACARD=m
+CONFIG_SCSI_AHA152X=m
+CONFIG_SCSI_AHA1542=m
+CONFIG_SCSI_AACRAID=m
+CONFIG_SCSI_AIC7XXX=m
+CONFIG_AIC7XXX_CMDS_PER_DEVICE=4
+CONFIG_AIC7XXX_RESET_DELAY_MS=15000
+# CONFIG_AIC7XXX_DEBUG_ENABLE is not set
+CONFIG_AIC7XXX_DEBUG_MASK=0
+# CONFIG_AIC7XXX_REG_PRETTY_PRINT is not set
+CONFIG_SCSI_AIC7XXX_OLD=m
+CONFIG_SCSI_AIC79XX=m
+CONFIG_AIC79XX_CMDS_PER_DEVICE=4
+CONFIG_AIC79XX_RESET_DELAY_MS=15000
+# CONFIG_AIC79XX_ENABLE_RD_STRM is not set
+# CONFIG_AIC79XX_DEBUG_ENABLE is not set
+CONFIG_AIC79XX_DEBUG_MASK=0
+# CONFIG_AIC79XX_REG_PRETTY_PRINT is not set
+# CONFIG_SCSI_DPT_I2O is not set
+CONFIG_SCSI_ADVANSYS=m
+# CONFIG_SCSI_IN2000 is not set
+CONFIG_MEGARAID_NEWGEN=y
+CONFIG_MEGARAID_MM=m
+CONFIG_MEGARAID_MAILBOX=m
+CONFIG_MEGARAID_LEGACY=m
+CONFIG_MEGARAID_SAS=m
+CONFIG_SCSI_SATA=m
+CONFIG_SCSI_SATA_AHCI=m
+CONFIG_SCSI_SATA_SVW=m
+CONFIG_SCSI_ATA_PIIX=m
+CONFIG_SCSI_SATA_MV=m
+CONFIG_SCSI_SATA_NV=m
+CONFIG_SCSI_PDC_ADMA=m
+CONFIG_SCSI_HPTIOP=m
+CONFIG_SCSI_SATA_QSTOR=m
+CONFIG_SCSI_SATA_PROMISE=m
+CONFIG_SCSI_SATA_SX4=m
+CONFIG_SCSI_SATA_SIL=m
+CONFIG_SCSI_SATA_SIL24=m
+CONFIG_SCSI_SATA_SIS=m
+CONFIG_SCSI_SATA_ULI=m
+CONFIG_SCSI_SATA_VIA=m
+CONFIG_SCSI_SATA_VITESSE=m
+CONFIG_SCSI_SATA_INTEL_COMBINED=y
+CONFIG_SCSI_BUSLOGIC=m
+# CONFIG_SCSI_OMIT_FLASHPOINT is not set
+# CONFIG_SCSI_DMX3191D is not set
+# CONFIG_SCSI_DTC3280 is not set
+# CONFIG_SCSI_EATA is not set
+CONFIG_SCSI_FUTURE_DOMAIN=m
+CONFIG_SCSI_GDTH=m
+# CONFIG_SCSI_GENERIC_NCR5380 is not set
+# CONFIG_SCSI_GENERIC_NCR5380_MMIO is not set
+CONFIG_SCSI_IPS=m
+CONFIG_SCSI_INITIO=m
+CONFIG_SCSI_INIA100=m
+CONFIG_SCSI_PPA=m
+CONFIG_SCSI_IMM=m
+# CONFIG_SCSI_IZIP_EPP16 is not set
+# CONFIG_SCSI_IZIP_SLOW_CTR is not set
+# CONFIG_SCSI_NCR53C406A is not set
+CONFIG_SCSI_SYM53C8XX_2=m
+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=m
+CONFIG_SCSI_QLA_FC=m
+CONFIG_SCSI_LPFC=m
+# CONFIG_SCSI_SYM53C416 is not set
+CONFIG_SCSI_DC395x=m
+CONFIG_SCSI_DC390T=m
+# CONFIG_SCSI_T128 is not set
+# CONFIG_SCSI_U14_34F is not set
+# CONFIG_SCSI_ULTRASTOR is not set
+# CONFIG_SCSI_NSP32 is not set
+# CONFIG_SCSI_DEBUG is not set
+
+#
+# PCMCIA SCSI adapter support
+#
+CONFIG_PCMCIA_AHA152X=m
+CONFIG_PCMCIA_FDOMAIN=m
+CONFIG_PCMCIA_NINJA_SCSI=m
+CONFIG_PCMCIA_QLOGIC=m
+CONFIG_PCMCIA_SYM53C500=m
+
+#
+# Old CD-ROM drivers (not SCSI, not IDE)
+#
+# CONFIG_CD_NO_IDESCSI is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+CONFIG_MD=y
+CONFIG_BLK_DEV_MD=y
+CONFIG_MD_LINEAR=m
+CONFIG_MD_RAID0=m
+CONFIG_MD_RAID1=m
+CONFIG_MD_RAID10=m
+CONFIG_MD_RAID456=m
+CONFIG_MD_RAID5_RESHAPE=y
+CONFIG_MD_MULTIPATH=m
+CONFIG_MD_FAULTY=m
+CONFIG_BLK_DEV_DM=m
+CONFIG_DM_CRYPT=m
+CONFIG_DM_SNAPSHOT=m
+CONFIG_DM_MIRROR=m
+CONFIG_DM_ZERO=m
+CONFIG_DM_MULTIPATH=m
+CONFIG_DM_MULTIPATH_EMC=m
+
+#
+# Fusion MPT device support
+#
+CONFIG_FUSION=y
+CONFIG_FUSION_SPI=m
+CONFIG_FUSION_FC=m
+CONFIG_FUSION_SAS=m
+CONFIG_FUSION_MAX_SGE=40
+CONFIG_FUSION_CTL=m
+CONFIG_FUSION_LAN=m
+
+#
+# IEEE 1394 (FireWire) support
+#
+CONFIG_IEEE1394=m
+
+#
+# Subsystem Options
+#
+# CONFIG_IEEE1394_VERBOSEDEBUG is not set
+CONFIG_IEEE1394_OUI_DB=y
+CONFIG_IEEE1394_EXTRA_CONFIG_ROMS=y
+CONFIG_IEEE1394_CONFIG_ROM_IP1394=y
+# CONFIG_IEEE1394_EXPORT_FULL_API is not set
+
+#
+# Device Drivers
+#
+CONFIG_IEEE1394_PCILYNX=m
+CONFIG_IEEE1394_OHCI1394=m
+
+#
+# Protocol Drivers
+#
+CONFIG_IEEE1394_VIDEO1394=m
+CONFIG_IEEE1394_SBP2=m
+# CONFIG_IEEE1394_SBP2_PHYS_DMA is not set
+CONFIG_IEEE1394_ETH1394=m
+CONFIG_IEEE1394_DV1394=m
+CONFIG_IEEE1394_RAWIO=m
+
+#
+# I2O device support
+#
+CONFIG_I2O=m
+# CONFIG_I2O_LCT_NOTIFY_ON_CHANGES is not set
+CONFIG_I2O_EXT_ADAPTEC=y
+CONFIG_I2O_EXT_ADAPTEC_DMA64=y
+CONFIG_I2O_CONFIG=m
+CONFIG_I2O_CONFIG_OLD_IOCTL=y
+CONFIG_I2O_BUS=m
+CONFIG_I2O_BLOCK=m
+CONFIG_I2O_SCSI=m
+CONFIG_I2O_PROC=m
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+CONFIG_IFB=m
+CONFIG_DUMMY=m
+CONFIG_BONDING=m
+CONFIG_EQUALIZER=m
+CONFIG_TUN=m
+CONFIG_NET_SB1000=m
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+
+#
+# PHY device support
+#
+CONFIG_PHYLIB=m
+
+#
+# MII PHY device drivers
+#
+CONFIG_MARVELL_PHY=m
+CONFIG_DAVICOM_PHY=m
+CONFIG_QSEMI_PHY=m
+CONFIG_LXT_PHY=m
+CONFIG_CICADA_PHY=m
+CONFIG_VITESSE_PHY=m
+CONFIG_SMSC_PHY=m
+CONFIG_FIXED_PHY=m
+CONFIG_FIXED_MII_10_FDX=y
+CONFIG_FIXED_MII_100_FDX=y
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=m
+CONFIG_HAPPYMEAL=m
+CONFIG_SUNGEM=m
+CONFIG_CASSINI=m
+CONFIG_NET_VENDOR_3COM=y
+# CONFIG_EL1 is not set
+# CONFIG_EL2 is not set
+# CONFIG_ELPLUS is not set
+# CONFIG_EL16 is not set
+CONFIG_EL3=m
+# CONFIG_3C515 is not set
+CONFIG_VORTEX=m
+CONFIG_TYPHOON=m
+# CONFIG_LANCE is not set
+CONFIG_NET_VENDOR_SMC=y
+# CONFIG_WD80x3 is not set
+CONFIG_ULTRA=m
+# CONFIG_SMC9194 is not set
+# CONFIG_NET_VENDOR_RACAL is not set
+
+#
+# Tulip family network device support
+#
+CONFIG_NET_TULIP=y
+CONFIG_DE2104X=m
+CONFIG_TULIP=m
+# CONFIG_TULIP_MWI is not set
+CONFIG_TULIP_MMIO=y
+# CONFIG_TULIP_NAPI is not set
+CONFIG_DE4X5=m
+CONFIG_WINBOND_840=m
+CONFIG_DM9102=m
+CONFIG_ULI526X=m
+CONFIG_PCMCIA_XIRCOM=m
+# CONFIG_AT1700 is not set
+# CONFIG_DEPCA is not set
+# CONFIG_HP100 is not set
+CONFIG_NET_ISA=y
+# CONFIG_E2100 is not set
+CONFIG_EWRK3=m
+# CONFIG_EEXPRESS is not set
+# CONFIG_EEXPRESS_PRO is not set
+# CONFIG_HPLAN_PLUS is not set
+# CONFIG_HPLAN is not set
+# CONFIG_LP486E is not set
+# CONFIG_ETH16I is not set
+CONFIG_NE2000=m
+# CONFIG_ZNET is not set
+# CONFIG_SEEQ8005 is not set
+CONFIG_NET_PCI=y
+CONFIG_PCNET32=m
+CONFIG_AMD8111_ETH=m
+CONFIG_AMD8111E_NAPI=y
+CONFIG_ADAPTEC_STARFIRE=m
+CONFIG_ADAPTEC_STARFIRE_NAPI=y
+# CONFIG_AC3200 is not set
+# CONFIG_APRICOT is not set
+CONFIG_B44=m
+CONFIG_FORCEDETH=m
+# CONFIG_CS89x0 is not set
+# CONFIG_DGRS is not set
+# CONFIG_EEPRO100 is not set
+CONFIG_E100=m
+CONFIG_FEALNX=m
+CONFIG_NATSEMI=m
+CONFIG_NE2K_PCI=m
+CONFIG_8139CP=m
+CONFIG_8139TOO=m
+# CONFIG_8139TOO_PIO is not set
+# CONFIG_8139TOO_TUNE_TWISTER is not set
+CONFIG_8139TOO_8129=y
+# CONFIG_8139_OLD_RX_RESET is not set
+CONFIG_SIS900=m
+CONFIG_EPIC100=m
+CONFIG_SUNDANCE=m
+# CONFIG_SUNDANCE_MMIO is not set
+CONFIG_TLAN=m
+CONFIG_VIA_RHINE=m
+CONFIG_VIA_RHINE_MMIO=y
+CONFIG_VIA_RHINE_NAPI=y
+CONFIG_NET_POCKET=y
+CONFIG_ATP=m
+CONFIG_DE600=m
+CONFIG_DE620=m
+
+#
+# Ethernet (1000 Mbit)
+#
+CONFIG_ACENIC=m
+# CONFIG_ACENIC_OMIT_TIGON_I is not set
+CONFIG_DL2K=m
+CONFIG_E1000=m
+CONFIG_E1000_NAPI=y
+# CONFIG_E1000_DISABLE_PACKET_SPLIT is not set
+CONFIG_NS83820=m
+CONFIG_HAMACHI=m
+CONFIG_YELLOWFIN=m
+CONFIG_R8169=m
+CONFIG_R8169_NAPI=y
+CONFIG_R8169_VLAN=y
+CONFIG_SIS190=m
+CONFIG_SKGE=m
+CONFIG_SKY2=m
+# CONFIG_SK98LIN is not set
+CONFIG_VIA_VELOCITY=m
+CONFIG_TIGON3=m
+CONFIG_BNX2=m
+
+#
+# Ethernet (10000 Mbit)
+#
+CONFIG_CHELSIO_T1=m
+CONFIG_IXGB=m
+CONFIG_IXGB_NAPI=y
+CONFIG_S2IO=m
+CONFIG_S2IO_NAPI=y
+CONFIG_MYRI10GE=m
+
+#
+# Token Ring devices
+#
+CONFIG_TR=y
+# CONFIG_IBMTR is not set
+CONFIG_IBMOL=m
+CONFIG_IBMLS=m
+CONFIG_3C359=m
+# CONFIG_TMS380TR is not set
+# CONFIG_SMCTR is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+CONFIG_NET_RADIO=y
+CONFIG_NET_WIRELESS_RTNETLINK=y
+
+#
+# Obsolete Wireless cards support (pre-802.11)
+#
+# CONFIG_STRIP is not set
+# CONFIG_ARLAN is not set
+# CONFIG_WAVELAN is not set
+CONFIG_PCMCIA_WAVELAN=m
+CONFIG_PCMCIA_NETWAVE=m
+
+#
+# Wireless 802.11 Frequency Hopping cards support
+#
+# CONFIG_PCMCIA_RAYCS is not set
+
+#
+# Wireless 802.11b ISA/PCI cards support
+#
+CONFIG_IPW2100=m
+CONFIG_IPW2100_MONITOR=y
+# CONFIG_IPW2100_DEBUG is not set
+CONFIG_IPW2200=m
+CONFIG_IPW2200_MONITOR=y
+CONFIG_IPW2200_RADIOTAP=y
+CONFIG_IPW2200_PROMISCUOUS=y
+CONFIG_IPW2200_QOS=y
+# CONFIG_IPW2200_DEBUG is not set
+CONFIG_AIRO=m
+CONFIG_HERMES=m
+CONFIG_PLX_HERMES=m
+CONFIG_TMD_HERMES=m
+CONFIG_NORTEL_HERMES=m
+CONFIG_PCI_HERMES=m
+CONFIG_ATMEL=m
+CONFIG_PCI_ATMEL=m
+
+#
+# Wireless 802.11b Pcmcia/Cardbus cards support
+#
+CONFIG_PCMCIA_HERMES=m
+CONFIG_PCMCIA_SPECTRUM=m
+CONFIG_AIRO_CS=m
+CONFIG_PCMCIA_ATMEL=m
+CONFIG_PCMCIA_WL3501=m
+
+#
+# Prism GT/Duette 802.11(a/b/g) PCI/Cardbus support
+#
+CONFIG_PRISM54=m
+CONFIG_USB_ZD1201=m
+CONFIG_HOSTAP=m
+CONFIG_HOSTAP_FIRMWARE=y
+CONFIG_HOSTAP_FIRMWARE_NVRAM=y
+CONFIG_HOSTAP_PLX=m
+CONFIG_HOSTAP_PCI=m
+CONFIG_HOSTAP_CS=m
+CONFIG_BCM43XX=m
+CONFIG_BCM43XX_DEBUG=y
+CONFIG_BCM43XX_DMA=y
+CONFIG_BCM43XX_PIO=y
+CONFIG_BCM43XX_DMA_AND_PIO_MODE=y
+# CONFIG_BCM43XX_DMA_MODE is not set
+# CONFIG_BCM43XX_PIO_MODE is not set
+CONFIG_ZD1211RW=m
+# CONFIG_ZD1211RW_DEBUG is not set
+CONFIG_NET_WIRELESS=y
+
+#
+# PCMCIA network device support
+#
+CONFIG_NET_PCMCIA=y
+CONFIG_PCMCIA_3C589=m
+CONFIG_PCMCIA_3C574=m
+CONFIG_PCMCIA_FMVJ18X=m
+CONFIG_PCMCIA_PCNET=m
+CONFIG_PCMCIA_NMCLAN=m
+CONFIG_PCMCIA_SMC91C92=m
+CONFIG_PCMCIA_XIRC2PS=m
+CONFIG_PCMCIA_AXNET=m
+CONFIG_PCMCIA_IBMTR=m
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+
+#
+# ATM drivers
+#
+# CONFIG_ATM_DUMMY is not set
+CONFIG_ATM_TCP=m
+CONFIG_ATM_LANAI=m
+CONFIG_ATM_ENI=m
+# CONFIG_ATM_ENI_DEBUG is not set
+# CONFIG_ATM_ENI_TUNE_BURST is not set
+CONFIG_ATM_FIRESTREAM=m
+# CONFIG_ATM_ZATM is not set
+CONFIG_ATM_NICSTAR=m
+# CONFIG_ATM_NICSTAR_USE_SUNI is not set
+# CONFIG_ATM_NICSTAR_USE_IDT77105 is not set
+CONFIG_ATM_IDT77252=m
+# CONFIG_ATM_IDT77252_DEBUG is not set
+# CONFIG_ATM_IDT77252_RCV_ALL is not set
+CONFIG_ATM_IDT77252_USE_SUNI=y
+CONFIG_ATM_AMBASSADOR=m
+# CONFIG_ATM_AMBASSADOR_DEBUG is not set
+CONFIG_ATM_HORIZON=m
+# CONFIG_ATM_HORIZON_DEBUG is not set
+# CONFIG_ATM_IA is not set
+CONFIG_ATM_FORE200E_MAYBE=m
+# CONFIG_ATM_FORE200E_PCA is not set
+CONFIG_ATM_HE=m
+# CONFIG_ATM_HE_USE_SUNI is not set
+CONFIG_FDDI=y
+# CONFIG_DEFXX is not set
+CONFIG_SKFP=m
+# CONFIG_HIPPI is not set
+CONFIG_PLIP=m
+CONFIG_PPP=m
+CONFIG_PPP_MULTILINK=y
+CONFIG_PPP_FILTER=y
+CONFIG_PPP_ASYNC=m
+CONFIG_PPP_SYNC_TTY=m
+CONFIG_PPP_DEFLATE=m
+# CONFIG_PPP_BSDCOMP is not set
+CONFIG_PPP_MPPE=m
+CONFIG_PPPOE=m
+CONFIG_PPPOATM=m
+CONFIG_SLIP=m
+CONFIG_SLIP_COMPRESSED=y
+CONFIG_SLIP_SMART=y
+# CONFIG_SLIP_MODE_SLIP6 is not set
+CONFIG_NET_FC=y
+# CONFIG_SHAPER is not set
+CONFIG_NETCONSOLE=m
+CONFIG_NETPOLL=y
+# CONFIG_NETPOLL_RX is not set
+CONFIG_NETPOLL_TRAP=y
+CONFIG_NET_POLL_CONTROLLER=y
+
+#
+# ISDN subsystem
+#
+CONFIG_ISDN=m
+
+#
+# Old ISDN4Linux
+#
+CONFIG_ISDN_I4L=m
+CONFIG_ISDN_PPP=y
+CONFIG_ISDN_PPP_VJ=y
+CONFIG_ISDN_MPP=y
+CONFIG_IPPP_FILTER=y
+# CONFIG_ISDN_PPP_BSDCOMP is not set
+CONFIG_ISDN_AUDIO=y
+CONFIG_ISDN_TTY_FAX=y
+
+#
+# ISDN feature submodules
+#
+CONFIG_ISDN_DIVERSION=m
+
+#
+# ISDN4Linux hardware drivers
+#
+
+#
+# Passive cards
+#
+CONFIG_ISDN_DRV_HISAX=m
+
+#
+# D-channel protocol features
+#
+CONFIG_HISAX_EURO=y
+CONFIG_DE_AOC=y
+CONFIG_HISAX_NO_SENDCOMPLETE=y
+CONFIG_HISAX_NO_LLC=y
+CONFIG_HISAX_NO_KEYPAD=y
+CONFIG_HISAX_1TR6=y
+CONFIG_HISAX_NI1=y
+CONFIG_HISAX_MAX_CARDS=8
+
+#
+# HiSax supported cards
+#
+# CONFIG_HISAX_16_0 is not set
+CONFIG_HISAX_16_3=y
+CONFIG_HISAX_TELESPCI=y
+CONFIG_HISAX_S0BOX=y
+# CONFIG_HISAX_AVM_A1 is not set
+CONFIG_HISAX_FRITZPCI=y
+CONFIG_HISAX_AVM_A1_PCMCIA=y
+CONFIG_HISAX_ELSA=y
+# CONFIG_HISAX_IX1MICROR2 is not set
+CONFIG_HISAX_DIEHLDIVA=y
+# CONFIG_HISAX_ASUSCOM is not set
+# CONFIG_HISAX_TELEINT is not set
+# CONFIG_HISAX_HFCS is not set
+CONFIG_HISAX_SEDLBAUER=y
+# CONFIG_HISAX_SPORTSTER is not set
+# CONFIG_HISAX_MIC is not set
+CONFIG_HISAX_NETJET=y
+CONFIG_HISAX_NETJET_U=y
+CONFIG_HISAX_NICCY=y
+# CONFIG_HISAX_ISURF is not set
+# CONFIG_HISAX_HSTSAPHIR is not set
+CONFIG_HISAX_BKM_A4T=y
+CONFIG_HISAX_SCT_QUADRO=y
+CONFIG_HISAX_GAZEL=y
+CONFIG_HISAX_HFC_PCI=y
+CONFIG_HISAX_W6692=y
+CONFIG_HISAX_HFC_SX=y
+CONFIG_HISAX_ENTERNOW_PCI=y
+# CONFIG_HISAX_DEBUG is not set
+
+#
+# HiSax PCMCIA card service modules
+#
+CONFIG_HISAX_SEDLBAUER_CS=m
+CONFIG_HISAX_ELSA_CS=m
+CONFIG_HISAX_AVM_A1_CS=m
+CONFIG_HISAX_TELES_CS=m
+
+#
+# HiSax sub driver modules
+#
+CONFIG_HISAX_ST5481=m
+# CONFIG_HISAX_HFCUSB is not set
+CONFIG_HISAX_HFC4S8S=m
+CONFIG_HISAX_FRITZ_PCIPNP=m
+CONFIG_HISAX_HDLC=y
+
+#
+# Active cards
+#
+# CONFIG_ISDN_DRV_ICN is not set
+# CONFIG_ISDN_DRV_PCBIT is not set
+# CONFIG_ISDN_DRV_SC is not set
+# CONFIG_ISDN_DRV_ACT2000 is not set
+
+#
+# Siemens Gigaset
+#
+CONFIG_ISDN_DRV_GIGASET=m
+CONFIG_GIGASET_BASE=m
+CONFIG_GIGASET_M105=m
+# CONFIG_GIGASET_DEBUG is not set
+# CONFIG_GIGASET_UNDOCREQ is not set
+
+#
+# CAPI subsystem
+#
+CONFIG_ISDN_CAPI=m
+CONFIG_ISDN_DRV_AVMB1_VERBOSE_REASON=y
+CONFIG_ISDN_CAPI_MIDDLEWARE=y
+CONFIG_ISDN_CAPI_CAPI20=m
+CONFIG_ISDN_CAPI_CAPIFS_BOOL=y
+CONFIG_ISDN_CAPI_CAPIFS=m
+CONFIG_ISDN_CAPI_CAPIDRV=m
+
+#
+# CAPI hardware drivers
+#
+
+#
+# Active AVM cards
+#
+CONFIG_CAPI_AVM=y
+# CONFIG_ISDN_DRV_AVMB1_B1ISA is not set
+CONFIG_ISDN_DRV_AVMB1_B1PCI=m
+CONFIG_ISDN_DRV_AVMB1_B1PCIV4=y
+# CONFIG_ISDN_DRV_AVMB1_T1ISA is not set
+CONFIG_ISDN_DRV_AVMB1_B1PCMCIA=m
+CONFIG_ISDN_DRV_AVMB1_AVM_CS=m
+CONFIG_ISDN_DRV_AVMB1_T1PCI=m
+CONFIG_ISDN_DRV_AVMB1_C4=m
+
+#
+# Active Eicon DIVA Server cards
+#
+CONFIG_CAPI_EICON=y
+CONFIG_ISDN_DIVAS=m
+CONFIG_ISDN_DIVAS_BRIPCI=y
+CONFIG_ISDN_DIVAS_PRIPCI=y
+CONFIG_ISDN_DIVAS_DIVACAPI=m
+CONFIG_ISDN_DIVAS_USERIDI=m
+CONFIG_ISDN_DIVAS_MAINT=m
+
+#
+# Telephony Support
+#
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+
+#
+# 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=m
+# CONFIG_INPUT_TSDEV is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+CONFIG_KEYBOARD_ATKBD=y
+# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_KEYBOARD_LKKBD is not set
+# CONFIG_KEYBOARD_XTKBD is not set
+# CONFIG_KEYBOARD_NEWTON is not set
+CONFIG_INPUT_MOUSE=y
+CONFIG_MOUSE_PS2=y
+CONFIG_MOUSE_SERIAL=m
+# CONFIG_MOUSE_INPORT is not set
+# CONFIG_MOUSE_LOGIBM is not set
+# CONFIG_MOUSE_PC110PAD is not set
+CONFIG_MOUSE_VSXXXAA=m
+CONFIG_INPUT_JOYSTICK=y
+CONFIG_JOYSTICK_ANALOG=m
+CONFIG_JOYSTICK_A3D=m
+CONFIG_JOYSTICK_ADI=m
+CONFIG_JOYSTICK_COBRA=m
+CONFIG_JOYSTICK_GF2K=m
+CONFIG_JOYSTICK_GRIP=m
+CONFIG_JOYSTICK_GRIP_MP=m
+CONFIG_JOYSTICK_GUILLEMOT=m
+CONFIG_JOYSTICK_INTERACT=m
+CONFIG_JOYSTICK_SIDEWINDER=m
+CONFIG_JOYSTICK_TMDC=m
+CONFIG_JOYSTICK_IFORCE=m
+CONFIG_JOYSTICK_IFORCE_USB=y
+CONFIG_JOYSTICK_IFORCE_232=y
+CONFIG_JOYSTICK_WARRIOR=m
+CONFIG_JOYSTICK_MAGELLAN=m
+CONFIG_JOYSTICK_SPACEORB=m
+CONFIG_JOYSTICK_SPACEBALL=m
+CONFIG_JOYSTICK_STINGER=m
+CONFIG_JOYSTICK_TWIDJOY=m
+CONFIG_JOYSTICK_DB9=m
+CONFIG_JOYSTICK_GAMECON=m
+CONFIG_JOYSTICK_TURBOGRAFX=m
+CONFIG_JOYSTICK_JOYDUMP=m
+CONFIG_INPUT_TOUCHSCREEN=y
+CONFIG_TOUCHSCREEN_GUNZE=m
+CONFIG_TOUCHSCREEN_ELO=m
+CONFIG_TOUCHSCREEN_MTOUCH=m
+CONFIG_TOUCHSCREEN_MK712=m
+CONFIG_INPUT_MISC=y
+CONFIG_INPUT_PCSPKR=m
+CONFIG_INPUT_WISTRON_BTNS=m
+CONFIG_INPUT_UINPUT=m
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+CONFIG_SERIO_I8042=y
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_CT82C710 is not set
+# CONFIG_SERIO_PARKBD is not set
+# CONFIG_SERIO_PCIPS2 is not set
+CONFIG_SERIO_LIBPS2=y
+CONFIG_SERIO_RAW=m
+CONFIG_GAMEPORT=m
+CONFIG_GAMEPORT_NS558=m
+CONFIG_GAMEPORT_L4=m
+CONFIG_GAMEPORT_EMU10K1=m
+CONFIG_GAMEPORT_FM801=m
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+CONFIG_VT_HW_CONSOLE_BINDING=y
+CONFIG_SERIAL_NONSTANDARD=y
+# CONFIG_COMPUTONE is not set
+# CONFIG_ROCKETPORT is not set
+CONFIG_CYCLADES=m
+# CONFIG_CYZ_INTR is not set
+# CONFIG_DIGIEPCA is not set
+# CONFIG_ESPSERIAL is not set
+# CONFIG_MOXA_INTELLIO is not set
+# CONFIG_MOXA_SMARTIO is not set
+# CONFIG_ISI is not set
+CONFIG_SYNCLINK=m
+CONFIG_SYNCLINKMP=m
+CONFIG_SYNCLINK_GT=m
+CONFIG_N_HDLC=m
+# CONFIG_SPECIALIX is not set
+# CONFIG_SX is not set
+# CONFIG_RIO is not set
+# CONFIG_STALDRV is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_PCI=y
+CONFIG_SERIAL_8250_PNP=y
+CONFIG_SERIAL_8250_CS=m
+CONFIG_SERIAL_8250_NR_UARTS=32
+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=y
+CONFIG_SERIAL_8250_RSA=y
+# CONFIG_SERIAL_8250_FOURPORT is not set
+# CONFIG_SERIAL_8250_ACCENT is not set
+# CONFIG_SERIAL_8250_BOCA is not set
+# CONFIG_SERIAL_8250_HUB6 is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_SERIAL_JSM=m
+CONFIG_UNIX98_PTYS=y
+# CONFIG_LEGACY_PTYS is not set
+CONFIG_CRASH=m
+CONFIG_PRINTER=m
+CONFIG_LP_CONSOLE=y
+CONFIG_PPDEV=m
+CONFIG_TIPAR=m
+
+#
+# IPMI
+#
+CONFIG_IPMI_HANDLER=m
+# CONFIG_IPMI_PANIC_EVENT is not set
+CONFIG_IPMI_DEVICE_INTERFACE=m
+CONFIG_IPMI_SI=m
+CONFIG_IPMI_WATCHDOG=m
+CONFIG_IPMI_POWEROFF=m
+
+#
+# Watchdog Cards
+#
+CONFIG_WATCHDOG=y
+# CONFIG_WATCHDOG_NOWAYOUT is not set
+
+#
+# Watchdog Device Drivers
+#
+CONFIG_SOFT_WATCHDOG=m
+# CONFIG_ACQUIRE_WDT is not set
+# CONFIG_ADVANTECH_WDT is not set
+CONFIG_ALIM1535_WDT=m
+CONFIG_ALIM7101_WDT=m
+# CONFIG_SC520_WDT is not set
+# CONFIG_EUROTECH_WDT is not set
+# CONFIG_IB700_WDT is not set
+CONFIG_IBMASR=m
+# CONFIG_WAFER_WDT is not set
+CONFIG_I6300ESB_WDT=m
+CONFIG_I8XX_TCO=m
+# CONFIG_SC1200_WDT is not set
+# CONFIG_60XX_WDT is not set
+# CONFIG_SBC8360_WDT is not set
+# CONFIG_CPU5_WDT is not set
+CONFIG_W83627HF_WDT=m
+CONFIG_W83877F_WDT=m
+CONFIG_W83977F_WDT=m
+CONFIG_MACHZ_WDT=m
+# CONFIG_SBC_EPX_C3_WATCHDOG is not set
+
+#
+# ISA-based Watchdog Cards
+#
+# CONFIG_PCWATCHDOG is not set
+# CONFIG_MIXCOMWD is not set
+# CONFIG_WDT is not set
+
+#
+# PCI-based Watchdog Cards
+#
+CONFIG_PCIPCWATCHDOG=m
+CONFIG_WDTPCI=m
+CONFIG_WDT_501_PCI=y
+
+#
+# USB-based Watchdog Cards
+#
+CONFIG_USBPCWATCHDOG=m
+CONFIG_HW_RANDOM=y
+CONFIG_HW_RANDOM_INTEL=m
+CONFIG_HW_RANDOM_AMD=m
+CONFIG_HW_RANDOM_GEODE=m
+CONFIG_HW_RANDOM_VIA=m
+CONFIG_NVRAM=y
+CONFIG_RTC=y
+CONFIG_DTLK=m
+CONFIG_R3964=m
+# CONFIG_APPLICOM is not set
+CONFIG_SONYPI=m
+
+#
+# Ftape, the floppy tape device driver
+#
+CONFIG_AGP=y
+CONFIG_AGP_ALI=y
+CONFIG_AGP_ATI=y
+CONFIG_AGP_AMD=y
+CONFIG_AGP_AMD64=y
+CONFIG_AGP_INTEL=y
+CONFIG_AGP_NVIDIA=y
+CONFIG_AGP_SIS=y
+CONFIG_AGP_SWORKS=y
+CONFIG_AGP_VIA=y
+CONFIG_AGP_EFFICEON=y
+CONFIG_DRM=m
+CONFIG_DRM_TDFX=m
+CONFIG_DRM_R128=m
+CONFIG_DRM_RADEON=m
+CONFIG_DRM_I810=m
+CONFIG_DRM_I830=m
+CONFIG_DRM_I915=m
+CONFIG_DRM_MGA=m
+CONFIG_DRM_SIS=m
+CONFIG_DRM_VIA=m
+CONFIG_DRM_SAVAGE=m
+
+#
+# PCMCIA character devices
+#
+# CONFIG_SYNCLINK_CS is not set
+CONFIG_CARDMAN_4000=m
+CONFIG_CARDMAN_4040=m
+CONFIG_MWAVE=m
+CONFIG_PC8736x_GPIO=m
+CONFIG_NSC_GPIO=m
+CONFIG_CS5535_GPIO=m
+# CONFIG_RAW_DRIVER is not set
+CONFIG_HPET=y
+# CONFIG_HPET_RTC_IRQ is not set
+# CONFIG_HPET_MMAP is not set
+CONFIG_HANGCHECK_TIMER=m
+
+#
+# TPM devices
+#
+CONFIG_TCG_TPM=m
+CONFIG_TCG_TIS=m
+CONFIG_TCG_NSC=m
+CONFIG_TCG_ATMEL=m
+CONFIG_TCG_INFINEON=m
+# CONFIG_TELCLOCK is not set
+
+#
+# I2C support
+#
+CONFIG_I2C=m
+CONFIG_I2C_CHARDEV=m
+
+#
+# I2C Algorithms
+#
+CONFIG_I2C_ALGOBIT=m
+CONFIG_I2C_ALGOPCF=m
+CONFIG_I2C_ALGOPCA=m
+
+#
+# I2C Hardware Bus support
+#
+CONFIG_I2C_ALI1535=m
+CONFIG_I2C_ALI1563=m
+CONFIG_I2C_ALI15X3=m
+CONFIG_I2C_AMD756=m
+CONFIG_I2C_AMD756_S4882=m
+CONFIG_I2C_AMD8111=m
+CONFIG_I2C_I801=m
+CONFIG_I2C_I810=m
+CONFIG_I2C_PIIX4=m
+CONFIG_I2C_ISA=m
+CONFIG_I2C_NFORCE2=m
+# CONFIG_I2C_OCORES is not set
+CONFIG_I2C_PARPORT=m
+CONFIG_I2C_PARPORT_LIGHT=m
+CONFIG_I2C_PROSAVAGE=m
+CONFIG_I2C_SAVAGE4=m
+# CONFIG_SCx200_ACB is not set
+CONFIG_I2C_SIS5595=m
+CONFIG_I2C_SIS630=m
+CONFIG_I2C_SIS96X=m
+CONFIG_I2C_STUB=m
+CONFIG_I2C_VIA=m
+CONFIG_I2C_VIAPRO=m
+CONFIG_I2C_VOODOO3=m
+CONFIG_I2C_PCA_ISA=m
+
+#
+# Miscellaneous I2C Chip support
+#
+CONFIG_SENSORS_DS1337=m
+CONFIG_SENSORS_DS1374=m
+CONFIG_SENSORS_EEPROM=m
+CONFIG_SENSORS_PCF8574=m
+CONFIG_SENSORS_PCA9539=m
+CONFIG_SENSORS_PCF8591=m
+CONFIG_SENSORS_MAX6875=m
+# 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 is not set
+# CONFIG_SPI_MASTER is not set
+
+#
+# Dallas's 1-wire bus
+#
+CONFIG_W1=m
+CONFIG_W1_CON=y
+
+#
+# 1-wire Bus Masters
+#
+CONFIG_W1_MASTER_MATROX=m
+CONFIG_W1_MASTER_DS2490=m
+CONFIG_W1_MASTER_DS2482=m
+
+#
+# 1-wire Slaves
+#
+CONFIG_W1_SLAVE_THERM=m
+CONFIG_W1_SLAVE_SMEM=m
+CONFIG_W1_SLAVE_DS2433=m
+CONFIG_W1_SLAVE_DS2433_CRC=y
+
+#
+# Hardware Monitoring support
+#
+CONFIG_HWMON=m
+CONFIG_HWMON_VID=m
+CONFIG_SENSORS_ABITUGURU=m
+CONFIG_SENSORS_ADM1021=m
+CONFIG_SENSORS_ADM1025=m
+CONFIG_SENSORS_ADM1026=m
+CONFIG_SENSORS_ADM1031=m
+CONFIG_SENSORS_ADM9240=m
+CONFIG_SENSORS_ASB100=m
+CONFIG_SENSORS_ATXP1=m
+CONFIG_SENSORS_DS1621=m
+CONFIG_SENSORS_F71805F=m
+CONFIG_SENSORS_FSCHER=m
+CONFIG_SENSORS_FSCPOS=m
+CONFIG_SENSORS_GL518SM=m
+CONFIG_SENSORS_GL520SM=m
+CONFIG_SENSORS_IT87=m
+CONFIG_SENSORS_LM63=m
+CONFIG_SENSORS_LM75=m
+CONFIG_SENSORS_LM77=m
+CONFIG_SENSORS_LM78=m
+CONFIG_SENSORS_LM80=m
+CONFIG_SENSORS_LM83=m
+CONFIG_SENSORS_LM85=m
+CONFIG_SENSORS_LM87=m
+CONFIG_SENSORS_LM90=m
+CONFIG_SENSORS_LM92=m
+CONFIG_SENSORS_MAX1619=m
+CONFIG_SENSORS_PC87360=m
+CONFIG_SENSORS_SIS5595=m
+CONFIG_SENSORS_SMSC47M1=m
+CONFIG_SENSORS_SMSC47M192=m
+CONFIG_SENSORS_SMSC47B397=m
+CONFIG_SENSORS_VIA686A=m
+CONFIG_SENSORS_VT8231=m
+CONFIG_SENSORS_W83781D=m
+CONFIG_SENSORS_W83791D=m
+CONFIG_SENSORS_W83792D=m
+CONFIG_SENSORS_W83L785TS=m
+CONFIG_SENSORS_W83627HF=m
+CONFIG_SENSORS_W83627EHF=m
+CONFIG_SENSORS_HDAPS=m
+# CONFIG_HWMON_DEBUG_CHIP is not set
+
+#
+# Misc devices
+#
+CONFIG_IBM_ASM=m
+
+#
+# Multimedia devices
+#
+CONFIG_VIDEO_DEV=m
+CONFIG_VIDEO_V4L1=y
+CONFIG_VIDEO_V4L1_COMPAT=y
+CONFIG_VIDEO_V4L2=y
+
+#
+# Video Capture Adapters
+#
+
+#
+# Video Capture Adapters
+#
+# CONFIG_VIDEO_ADV_DEBUG is not set
+# CONFIG_VIDEO_VIVI is not set
+CONFIG_VIDEO_BT848=m
+CONFIG_VIDEO_BT848_DVB=y
+CONFIG_VIDEO_SAA6588=m
+# CONFIG_VIDEO_PMS is not set
+CONFIG_VIDEO_BWQCAM=m
+CONFIG_VIDEO_CQCAM=m
+CONFIG_VIDEO_W9966=m
+CONFIG_VIDEO_CPIA=m
+CONFIG_VIDEO_CPIA_PP=m
+CONFIG_VIDEO_CPIA_USB=m
+CONFIG_VIDEO_CPIA2=m
+CONFIG_VIDEO_SAA5246A=m
+CONFIG_VIDEO_SAA5249=m
+CONFIG_TUNER_3036=m
+CONFIG_VIDEO_STRADIS=m
+CONFIG_VIDEO_ZORAN=m
+CONFIG_VIDEO_ZORAN_BUZ=m
+CONFIG_VIDEO_ZORAN_DC10=m
+CONFIG_VIDEO_ZORAN_DC30=m
+CONFIG_VIDEO_ZORAN_LML33=m
+CONFIG_VIDEO_ZORAN_LML33R10=m
+CONFIG_VIDEO_ZORAN_AVS6EYES=m
+CONFIG_VIDEO_MEYE=m
+CONFIG_VIDEO_SAA7134=m
+CONFIG_VIDEO_SAA7134_ALSA=m
+CONFIG_VIDEO_SAA7134_DVB=m
+CONFIG_VIDEO_SAA7134_DVB_ALL_FRONTENDS=y
+CONFIG_VIDEO_MXB=m
+CONFIG_VIDEO_DPC=m
+CONFIG_VIDEO_HEXIUM_ORION=m
+CONFIG_VIDEO_HEXIUM_GEMINI=m
+CONFIG_VIDEO_CX88_VP3054=m
+CONFIG_VIDEO_CX88=m
+CONFIG_VIDEO_CX88_ALSA=m
+CONFIG_VIDEO_CX88_BLACKBIRD=m
+CONFIG_VIDEO_CX88_DVB=m
+CONFIG_VIDEO_CX88_DVB_ALL_FRONTENDS=y
+
+#
+# Encoders and Decoders
+#
+CONFIG_VIDEO_MSP3400=m
+CONFIG_VIDEO_CS53L32A=m
+CONFIG_VIDEO_TLV320AIC23B=m
+CONFIG_VIDEO_WM8775=m
+CONFIG_VIDEO_WM8739=m
+CONFIG_VIDEO_CX2341X=m
+CONFIG_VIDEO_CX25840=m
+CONFIG_VIDEO_SAA711X=m
+CONFIG_VIDEO_SAA7127=m
+CONFIG_VIDEO_UPD64031A=m
+CONFIG_VIDEO_UPD64083=m
+
+#
+# V4L USB devices
+#
+CONFIG_VIDEO_PVRUSB2=m
+CONFIG_VIDEO_PVRUSB2_24XXX=y
+CONFIG_VIDEO_PVRUSB2_SYSFS=y
+# CONFIG_VIDEO_PVRUSB2_DEBUGIFC is not set
+CONFIG_VIDEO_EM28XX=m
+CONFIG_VIDEO_USBVIDEO=m
+CONFIG_USB_VICAM=m
+CONFIG_USB_IBMCAM=m
+CONFIG_USB_KONICAWC=m
+CONFIG_USB_QUICKCAM_MESSENGER=m
+CONFIG_USB_ET61X251=m
+CONFIG_VIDEO_OVCAMCHIP=m
+CONFIG_USB_W9968CF=m
+CONFIG_USB_OV511=m
+CONFIG_USB_SE401=m
+CONFIG_USB_SN9C102=m
+CONFIG_USB_STV680=m
+CONFIG_USB_ZC0301=m
+CONFIG_USB_PWC=m
+# CONFIG_USB_PWC_DEBUG is not set
+
+#
+# Radio Adapters
+#
+# CONFIG_RADIO_CADET is not set
+# CONFIG_RADIO_RTRACK is not set
+# CONFIG_RADIO_RTRACK2 is not set
+# CONFIG_RADIO_AZTECH is not set
+# CONFIG_RADIO_GEMTEK is not set
+CONFIG_RADIO_GEMTEK_PCI=m
+CONFIG_RADIO_MAXIRADIO=m
+CONFIG_RADIO_MAESTRO=m
+# CONFIG_RADIO_SF16FMI is not set
+# CONFIG_RADIO_SF16FMR2 is not set
+# CONFIG_RADIO_TERRATEC is not set
+# CONFIG_RADIO_TRUST is not set
+# CONFIG_RADIO_TYPHOON is not set
+# CONFIG_RADIO_ZOLTRIX is not set
+CONFIG_USB_DSBR=m
+
+#
+# Digital Video Broadcasting Devices
+#
+CONFIG_DVB=y
+CONFIG_DVB_CORE=m
+
+#
+# Supported SAA7146 based PCI Adapters
+#
+CONFIG_DVB_AV7110=m
+CONFIG_DVB_AV7110_OSD=y
+CONFIG_DVB_BUDGET=m
+CONFIG_DVB_BUDGET_CI=m
+CONFIG_DVB_BUDGET_AV=m
+CONFIG_DVB_BUDGET_PATCH=m
+
+#
+# Supported USB Adapters
+#
+CONFIG_DVB_USB=m
+# CONFIG_DVB_USB_DEBUG is not set
+CONFIG_DVB_USB_A800=m
+CONFIG_DVB_USB_DIBUSB_MB=m
+# CONFIG_DVB_USB_DIBUSB_MB_FAULTY is not set
+CONFIG_DVB_USB_DIBUSB_MC=m
+CONFIG_DVB_USB_UMT_010=m
+CONFIG_DVB_USB_CXUSB=m
+CONFIG_DVB_USB_DIGITV=m
+CONFIG_DVB_USB_VP7045=m
+CONFIG_DVB_USB_VP702X=m
+CONFIG_DVB_USB_GP8PSK=m
+CONFIG_DVB_USB_NOVA_T_USB2=m
+CONFIG_DVB_USB_DTT200U=m
+CONFIG_DVB_TTUSB_BUDGET=m
+CONFIG_DVB_TTUSB_DEC=m
+CONFIG_DVB_CINERGYT2=m
+CONFIG_DVB_CINERGYT2_TUNING=y
+CONFIG_DVB_CINERGYT2_STREAM_URB_COUNT=32
+CONFIG_DVB_CINERGYT2_STREAM_BUF_SIZE=512
+CONFIG_DVB_CINERGYT2_QUERY_INTERVAL=250
+CONFIG_DVB_CINERGYT2_ENABLE_RC_INPUT_DEVICE=y
+CONFIG_DVB_CINERGYT2_RC_QUERY_INTERVAL=100
+
+#
+# Supported FlexCopII (B2C2) Adapters
+#
+CONFIG_DVB_B2C2_FLEXCOP=m
+CONFIG_DVB_B2C2_FLEXCOP_PCI=m
+CONFIG_DVB_B2C2_FLEXCOP_USB=m
+# CONFIG_DVB_B2C2_FLEXCOP_DEBUG is not set
+
+#
+# Supported BT878 Adapters
+#
+CONFIG_DVB_BT8XX=m
+
+#
+# Supported Pluto2 Adapters
+#
+CONFIG_DVB_PLUTO2=m
+
+#
+# Supported DVB Frontends
+#
+
+#
+# Customise DVB Frontends
+#
+
+#
+# DVB-S (satellite) frontends
+#
+CONFIG_DVB_STV0299=m
+CONFIG_DVB_CX24110=m
+CONFIG_DVB_CX24123=m
+CONFIG_DVB_TDA8083=m
+CONFIG_DVB_MT312=m
+CONFIG_DVB_VES1X93=m
+CONFIG_DVB_S5H1420=m
+
+#
+# DVB-T (terrestrial) frontends
+#
+CONFIG_DVB_SP8870=m
+CONFIG_DVB_SP887X=m
+CONFIG_DVB_CX22700=m
+CONFIG_DVB_CX22702=m
+CONFIG_DVB_L64781=m
+CONFIG_DVB_TDA1004X=m
+CONFIG_DVB_NXT6000=m
+CONFIG_DVB_MT352=m
+CONFIG_DVB_ZL10353=m
+CONFIG_DVB_DIB3000MB=m
+CONFIG_DVB_DIB3000MC=m
+
+#
+# DVB-C (cable) frontends
+#
+CONFIG_DVB_VES1820=m
+CONFIG_DVB_TDA10021=m
+CONFIG_DVB_STV0297=m
+
+#
+# ATSC (North American/Korean Terrestrial/Cable DTV) frontends
+#
+CONFIG_DVB_NXT200X=m
+CONFIG_DVB_OR51211=m
+CONFIG_DVB_OR51132=m
+CONFIG_DVB_BCM3510=m
+CONFIG_DVB_LGDT330X=m
+
+#
+# Miscellaneous devices
+#
+CONFIG_DVB_PLL=m
+CONFIG_DVB_LNBP21=m
+CONFIG_DVB_ISL6421=m
+CONFIG_VIDEO_SAA7146=m
+CONFIG_VIDEO_SAA7146_VV=m
+CONFIG_VIDEO_VIDEOBUF=m
+CONFIG_VIDEO_TUNER=m
+CONFIG_VIDEO_BUF=m
+CONFIG_VIDEO_BUF_DVB=m
+CONFIG_VIDEO_BTCX=m
+CONFIG_VIDEO_IR=m
+CONFIG_VIDEO_TVEEPROM=m
+CONFIG_USB_DABUSB=m
+
+#
+# Graphics support
+#
+# CONFIG_FIRMWARE_EDID is not set
+CONFIG_FB=y
+CONFIG_FB_CFB_FILLRECT=y
+CONFIG_FB_CFB_COPYAREA=y
+CONFIG_FB_CFB_IMAGEBLIT=y
+# CONFIG_FB_MACMODES is not set
+# CONFIG_FB_BACKLIGHT is not set
+CONFIG_FB_MODE_HELPERS=y
+CONFIG_FB_TILEBLITTING=y
+CONFIG_FB_CIRRUS=m
+# CONFIG_FB_PM2 is not set
+# CONFIG_FB_CYBER2000 is not set
+# CONFIG_FB_ARC is not set
+# CONFIG_FB_ASILIANT is not set
+# CONFIG_FB_IMSTT is not set
+CONFIG_FB_VGA16=m
+CONFIG_FB_VESA=y
+# CONFIG_FB_IMAC is not set
+# CONFIG_FB_HGA is not set
+# CONFIG_FB_S1D13XXX is not set
+CONFIG_FB_NVIDIA=m
+CONFIG_FB_NVIDIA_I2C=y
+CONFIG_FB_RIVA=m
+# CONFIG_FB_RIVA_I2C is not set
+# CONFIG_FB_RIVA_DEBUG is not set
+CONFIG_FB_I810=m
+CONFIG_FB_I810_GTF=y
+CONFIG_FB_I810_I2C=y
+CONFIG_FB_INTEL=m
+# CONFIG_FB_INTEL_DEBUG is not set
+CONFIG_FB_MATROX=m
+CONFIG_FB_MATROX_MILLENIUM=y
+CONFIG_FB_MATROX_MYSTIQUE=y
+CONFIG_FB_MATROX_G=y
+CONFIG_FB_MATROX_I2C=m
+CONFIG_FB_MATROX_MAVEN=m
+CONFIG_FB_MATROX_MULTIHEAD=y
+CONFIG_FB_RADEON=m
+CONFIG_FB_RADEON_I2C=y
+# CONFIG_FB_RADEON_DEBUG is not set
+CONFIG_FB_ATY128=m
+CONFIG_FB_ATY=m
+CONFIG_FB_ATY_CT=y
+CONFIG_FB_ATY_GENERIC_LCD=y
+CONFIG_FB_ATY_GX=y
+CONFIG_FB_SAVAGE=m
+CONFIG_FB_SAVAGE_I2C=y
+CONFIG_FB_SAVAGE_ACCEL=y
+# CONFIG_FB_SIS is not set
+CONFIG_FB_NEOMAGIC=m
+CONFIG_FB_KYRO=m
+CONFIG_FB_3DFX=m
+CONFIG_FB_3DFX_ACCEL=y
+CONFIG_FB_VOODOO1=m
+CONFIG_FB_CYBLA=m
+CONFIG_FB_TRIDENT=m
+CONFIG_FB_TRIDENT_ACCEL=y
+# CONFIG_FB_GEODE is not set
+# CONFIG_FB_VIRTUAL is not set
+
+#
+# Console display driver support
+#
+CONFIG_VGA_CONSOLE=y
+CONFIG_VGACON_SOFT_SCROLLBACK=y
+CONFIG_VGACON_SOFT_SCROLLBACK_SIZE=64
+CONFIG_VIDEO_SELECT=y
+# CONFIG_MDA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y
+# CONFIG_FONTS is not set
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
+
+#
+# Logo configuration
+#
+CONFIG_LOGO=y
+# CONFIG_LOGO_LINUX_MONO is not set
+# CONFIG_LOGO_LINUX_VGA16 is not set
+CONFIG_LOGO_LINUX_CLUT224=y
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+CONFIG_BACKLIGHT_CLASS_DEVICE=m
+CONFIG_BACKLIGHT_DEVICE=y
+CONFIG_LCD_CLASS_DEVICE=m
+CONFIG_LCD_DEVICE=y
+
+#
+# Sound
+#
+CONFIG_SOUND=m
+
+#
+# Advanced Linux Sound Architecture
+#
+CONFIG_SND=m
+CONFIG_SND_TIMER=m
+CONFIG_SND_PCM=m
+CONFIG_SND_HWDEP=m
+CONFIG_SND_RAWMIDI=m
+CONFIG_SND_SEQUENCER=m
+CONFIG_SND_SEQ_DUMMY=m
+CONFIG_SND_OSSEMUL=y
+CONFIG_SND_MIXER_OSS=m
+CONFIG_SND_PCM_OSS=m
+CONFIG_SND_PCM_OSS_PLUGINS=y
+CONFIG_SND_SEQUENCER_OSS=y
+CONFIG_SND_RTCTIMER=m
+CONFIG_SND_SEQ_RTCTIMER_DEFAULT=y
+CONFIG_SND_DYNAMIC_MINORS=y
+# CONFIG_SND_SUPPORT_OLD_API is not set
+CONFIG_SND_VERBOSE_PROCFS=y
+# CONFIG_SND_VERBOSE_PRINTK is not set
+# CONFIG_SND_DEBUG is not set
+
+#
+# Generic devices
+#
+CONFIG_SND_MPU401_UART=m
+CONFIG_SND_OPL3_LIB=m
+CONFIG_SND_OPL4_LIB=m
+CONFIG_SND_VX_LIB=m
+CONFIG_SND_AC97_CODEC=m
+CONFIG_SND_AC97_BUS=m
+CONFIG_SND_DUMMY=m
+CONFIG_SND_VIRMIDI=m
+CONFIG_SND_MTPAV=m
+# CONFIG_SND_SERIAL_U16550 is not set
+CONFIG_SND_MPU401=m
+
+#
+# ISA devices
+#
+CONFIG_SND_CS4231_LIB=m
+CONFIG_SND_ADLIB=m
+# CONFIG_SND_AD1816A is not set
+# CONFIG_SND_AD1848 is not set
+# CONFIG_SND_ALS100 is not set
+# CONFIG_SND_AZT2320 is not set
+# CONFIG_SND_CMI8330 is not set
+# CONFIG_SND_CS4231 is not set
+# CONFIG_SND_CS4232 is not set
+CONFIG_SND_CS4236=m
+# CONFIG_SND_DT019X is not set
+# CONFIG_SND_ES968 is not set
+# CONFIG_SND_ES1688 is not set
+CONFIG_SND_ES18XX=m
+# CONFIG_SND_GUSCLASSIC is not set
+# CONFIG_SND_GUSEXTREME is not set
+# CONFIG_SND_GUSMAX is not set
+# CONFIG_SND_INTERWAVE is not set
+# CONFIG_SND_INTERWAVE_STB is not set
+CONFIG_SND_OPL3SA2=m
+# CONFIG_SND_OPTI92X_AD1848 is not set
+# CONFIG_SND_OPTI92X_CS4231 is not set
+# CONFIG_SND_OPTI93X is not set
+CONFIG_SND_MIRO=m
+# CONFIG_SND_SB8 is not set
+CONFIG_SND_SB16=m
+CONFIG_SND_SBAWE=m
+# CONFIG_SND_SB16_CSP is not set
+# CONFIG_SND_SGALAXY is not set
+# CONFIG_SND_SSCAPE is not set
+# CONFIG_SND_WAVEFRONT is not set
+
+#
+# PCI devices
+#
+CONFIG_SND_AD1889=m
+CONFIG_SND_ALS300=m
+CONFIG_SND_ALS4000=m
+CONFIG_SND_ALI5451=m
+CONFIG_SND_ATIIXP=m
+CONFIG_SND_ATIIXP_MODEM=m
+CONFIG_SND_AU8810=m
+CONFIG_SND_AU8820=m
+CONFIG_SND_AU8830=m
+CONFIG_SND_AZT3328=m
+CONFIG_SND_BT87X=m
+# CONFIG_SND_BT87X_OVERCLOCK is not set
+CONFIG_SND_CA0106=m
+CONFIG_SND_CMIPCI=m
+CONFIG_SND_CS4281=m
+CONFIG_SND_CS46XX=m
+CONFIG_SND_CS46XX_NEW_DSP=y
+CONFIG_SND_CS5535AUDIO=m
+CONFIG_SND_DARLA20=m
+CONFIG_SND_GINA20=m
+CONFIG_SND_LAYLA20=m
+CONFIG_SND_DARLA24=m
+CONFIG_SND_GINA24=m
+CONFIG_SND_LAYLA24=m
+CONFIG_SND_MONA=m
+CONFIG_SND_MIA=m
+CONFIG_SND_ECHO3G=m
+CONFIG_SND_INDIGO=m
+CONFIG_SND_INDIGOIO=m
+CONFIG_SND_INDIGODJ=m
+CONFIG_SND_EMU10K1=m
+CONFIG_SND_EMU10K1X=m
+CONFIG_SND_ENS1370=m
+CONFIG_SND_ENS1371=m
+CONFIG_SND_ES1938=m
+CONFIG_SND_ES1968=m
+CONFIG_SND_FM801=m
+CONFIG_SND_FM801_TEA575X_BOOL=y
+CONFIG_SND_FM801_TEA575X=m
+CONFIG_SND_HDA_INTEL=m
+CONFIG_SND_HDSP=m
+CONFIG_SND_HDSPM=m
+CONFIG_SND_ICE1712=m
+CONFIG_SND_ICE1724=m
+CONFIG_SND_INTEL8X0=m
+CONFIG_SND_INTEL8X0M=m
+CONFIG_SND_KORG1212=m
+CONFIG_SND_MAESTRO3=m
+CONFIG_SND_MIXART=m
+CONFIG_SND_NM256=m
+CONFIG_SND_PCXHR=m
+CONFIG_SND_RIPTIDE=m
+CONFIG_SND_RME32=m
+CONFIG_SND_RME96=m
+CONFIG_SND_RME9652=m
+CONFIG_SND_SONICVIBES=m
+CONFIG_SND_TRIDENT=m
+CONFIG_SND_VIA82XX=m
+CONFIG_SND_VIA82XX_MODEM=m
+CONFIG_SND_VX222=m
+CONFIG_SND_YMFPCI=m
+
+#
+# USB devices
+#
+CONFIG_SND_USB_AUDIO=m
+CONFIG_SND_USB_USX2Y=m
+
+#
+# PCMCIA devices
+#
+# CONFIG_SND_VXPOCKET is not set
+# CONFIG_SND_PDAUDIOCF is not set
+
+#
+# Open Sound System
+#
+# CONFIG_SOUND_PRIME is not set
+
+#
+# USB support
+#
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB_ARCH_HAS_EHCI=y
+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_SUSPEND is not set
+# CONFIG_USB_OTG is not set
+
+#
+# USB Host Controller Drivers
+#
+CONFIG_USB_EHCI_HCD=m
+CONFIG_USB_EHCI_SPLIT_ISO=y
+CONFIG_USB_EHCI_ROOT_HUB_TT=y
+CONFIG_USB_EHCI_TT_NEWSCHED=y
+CONFIG_USB_ISP116X_HCD=m
+CONFIG_USB_OHCI_HCD=m
+# CONFIG_USB_OHCI_BIG_ENDIAN is not set
+CONFIG_USB_OHCI_LITTLE_ENDIAN=y
+CONFIG_USB_UHCI_HCD=m
+CONFIG_USB_SL811_HCD=m
+CONFIG_USB_SL811_CS=m
+
+#
+# USB Device Class drivers
+#
+CONFIG_USB_ACM=m
+CONFIG_USB_PRINTER=m
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+#
+
+#
+# may also be needed; see USB_STORAGE Help for more information
+#
+CONFIG_USB_STORAGE=m
+# CONFIG_USB_STORAGE_DEBUG is not set
+CONFIG_USB_STORAGE_DATAFAB=y
+CONFIG_USB_STORAGE_FREECOM=y
+CONFIG_USB_STORAGE_ISD200=y
+CONFIG_USB_STORAGE_DPCM=y
+CONFIG_USB_STORAGE_USBAT=y
+CONFIG_USB_STORAGE_SDDR09=y
+CONFIG_USB_STORAGE_SDDR55=y
+CONFIG_USB_STORAGE_JUMPSHOT=y
+CONFIG_USB_STORAGE_ALAUDA=y
+CONFIG_USB_LIBUSUAL=y
+
+#
+# USB Input Devices
+#
+CONFIG_USB_HID=y
+CONFIG_USB_HIDINPUT=y
+CONFIG_USB_HIDINPUT_POWERBOOK=y
+CONFIG_HID_FF=y
+CONFIG_HID_PID=y
+CONFIG_LOGITECH_FF=y
+CONFIG_THRUSTMASTER_FF=y
+CONFIG_USB_HIDDEV=y
+CONFIG_USB_AIPTEK=m
+CONFIG_USB_WACOM=m
+CONFIG_USB_ACECAD=m
+CONFIG_USB_KBTAB=m
+CONFIG_USB_POWERMATE=m
+CONFIG_USB_TOUCHSCREEN=m
+CONFIG_USB_TOUCHSCREEN_EGALAX=y
+CONFIG_USB_TOUCHSCREEN_PANJIT=y
+CONFIG_USB_TOUCHSCREEN_3M=y
+CONFIG_USB_TOUCHSCREEN_ITM=y
+# CONFIG_USB_YEALINK is not set
+CONFIG_USB_XPAD=m
+CONFIG_USB_ATI_REMOTE=m
+CONFIG_USB_ATI_REMOTE2=m
+CONFIG_USB_KEYSPAN_REMOTE=m
+CONFIG_USB_APPLETOUCH=m
+
+#
+# USB Imaging devices
+#
+CONFIG_USB_MDC800=m
+CONFIG_USB_MICROTEK=m
+
+#
+# USB Network Adapters
+#
+CONFIG_USB_CATC=m
+CONFIG_USB_KAWETH=m
+CONFIG_USB_PEGASUS=m
+CONFIG_USB_RTL8150=m
+CONFIG_USB_USBNET=m
+CONFIG_USB_NET_AX8817X=m
+CONFIG_USB_NET_CDCETHER=m
+CONFIG_USB_NET_GL620A=m
+CONFIG_USB_NET_NET1080=m
+CONFIG_USB_NET_PLUSB=m
+CONFIG_USB_NET_RNDIS_HOST=m
+CONFIG_USB_NET_CDC_SUBSET=m
+CONFIG_USB_ALI_M5632=y
+CONFIG_USB_AN2720=y
+CONFIG_USB_BELKIN=y
+CONFIG_USB_ARMLINUX=y
+CONFIG_USB_EPSON2888=y
+CONFIG_USB_NET_ZAURUS=m
+CONFIG_USB_MON=y
+
+#
+# USB port drivers
+#
+CONFIG_USB_USS720=m
+
+#
+# USB Serial Converter support
+#
+CONFIG_USB_SERIAL=m
+CONFIG_USB_SERIAL_GENERIC=y
+CONFIG_USB_SERIAL_AIRPRIME=m
+CONFIG_USB_SERIAL_ARK3116=m
+CONFIG_USB_SERIAL_BELKIN=m
+CONFIG_USB_SERIAL_WHITEHEAT=m
+CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m
+CONFIG_USB_SERIAL_CP2101=m
+CONFIG_USB_SERIAL_CYPRESS_M8=m
+CONFIG_USB_SERIAL_EMPEG=m
+CONFIG_USB_SERIAL_FTDI_SIO=m
+CONFIG_USB_SERIAL_FUNSOFT=m
+CONFIG_USB_SERIAL_VISOR=m
+CONFIG_USB_SERIAL_IPAQ=m
+CONFIG_USB_SERIAL_IR=m
+CONFIG_USB_SERIAL_EDGEPORT=m
+CONFIG_USB_SERIAL_EDGEPORT_TI=m
+CONFIG_USB_SERIAL_GARMIN=m
+CONFIG_USB_SERIAL_IPW=m
+CONFIG_USB_SERIAL_KEYSPAN_PDA=m
+CONFIG_USB_SERIAL_KEYSPAN=m
+CONFIG_USB_SERIAL_KEYSPAN_MPR=y
+CONFIG_USB_SERIAL_KEYSPAN_USA28=y
+CONFIG_USB_SERIAL_KEYSPAN_USA28X=y
+CONFIG_USB_SERIAL_KEYSPAN_USA28XA=y
+CONFIG_USB_SERIAL_KEYSPAN_USA28XB=y
+CONFIG_USB_SERIAL_KEYSPAN_USA19=y
+CONFIG_USB_SERIAL_KEYSPAN_USA18X=y
+CONFIG_USB_SERIAL_KEYSPAN_USA19W=y
+CONFIG_USB_SERIAL_KEYSPAN_USA19QW=y
+CONFIG_USB_SERIAL_KEYSPAN_USA19QI=y
+CONFIG_USB_SERIAL_KEYSPAN_USA49W=y
+CONFIG_USB_SERIAL_KEYSPAN_USA49WLC=y
+CONFIG_USB_SERIAL_KLSI=m
+CONFIG_USB_SERIAL_KOBIL_SCT=m
+CONFIG_USB_SERIAL_MCT_U232=m
+CONFIG_USB_SERIAL_NAVMAN=m
+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=m
+CONFIG_USB_SERIAL_TI=m
+CONFIG_USB_SERIAL_CYBERJACK=m
+CONFIG_USB_SERIAL_XIRCOM=m
+CONFIG_USB_SERIAL_OPTION=m
+CONFIG_USB_SERIAL_OMNINET=m
+CONFIG_USB_EZUSB=y
+
+#
+# USB Miscellaneous drivers
+#
+CONFIG_USB_EMI62=m
+CONFIG_USB_EMI26=m
+CONFIG_USB_AUERSWALD=m
+CONFIG_USB_RIO500=m
+CONFIG_USB_LEGOTOWER=m
+CONFIG_USB_LCD=m
+CONFIG_USB_LED=m
+# CONFIG_USB_CYPRESS_CY7C63 is not set
+# CONFIG_USB_CYTHERM is not set
+CONFIG_USB_PHIDGETKIT=m
+CONFIG_USB_PHIDGETSERVO=m
+CONFIG_USB_IDMOUSE=m
+CONFIG_USB_APPLEDISPLAY=m
+CONFIG_USB_SISUSBVGA=m
+CONFIG_USB_SISUSBVGA_CON=y
+CONFIG_USB_LD=m
+CONFIG_USB_TEST=m
+
+#
+# USB DSL modem support
+#
+CONFIG_USB_ATM=m
+CONFIG_USB_SPEEDTOUCH=m
+CONFIG_USB_CXACRU=m
+CONFIG_USB_UEAGLEATM=m
+CONFIG_USB_XUSBATM=m
+
+#
+# USB Gadget Support
+#
+# CONFIG_USB_GADGET is not set
+
+#
+# MMC/SD Card support
+#
+CONFIG_MMC=m
+# CONFIG_MMC_DEBUG is not set
+CONFIG_MMC_BLOCK=m
+CONFIG_MMC_SDHCI=m
+CONFIG_MMC_WBSD=m
+
+#
+# LED devices
+#
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+
+#
+# LED drivers
+#
+
+#
+# LED Triggers
+#
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_LEDS_TRIGGER_TIMER=m
+CONFIG_LEDS_TRIGGER_IDE_DISK=y
+CONFIG_LEDS_TRIGGER_HEARTBEAT=m
+
+#
+# InfiniBand support
+#
+CONFIG_INFINIBAND=m
+CONFIG_INFINIBAND_USER_MAD=m
+CONFIG_INFINIBAND_USER_ACCESS=m
+CONFIG_INFINIBAND_ADDR_TRANS=y
+CONFIG_INFINIBAND_MTHCA=m
+CONFIG_INFINIBAND_MTHCA_DEBUG=y
+CONFIG_INFINIBAND_IPOIB=m
+CONFIG_INFINIBAND_IPOIB_DEBUG=y
+CONFIG_INFINIBAND_IPOIB_DEBUG_DATA=y
+CONFIG_INFINIBAND_SRP=m
+CONFIG_INFINIBAND_ISER=m
+
+#
+# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
+#
+CONFIG_EDAC=y
+
+#
+# Reporting subsystems
+#
+# CONFIG_EDAC_DEBUG is not set
+CONFIG_EDAC_MM_EDAC=m
+CONFIG_EDAC_AMD76X=m
+CONFIG_EDAC_E7XXX=m
+CONFIG_EDAC_E752X=m
+CONFIG_EDAC_I82875P=m
+CONFIG_EDAC_I82860=m
+CONFIG_EDAC_K8=m
+CONFIG_EDAC_R82600=m
+CONFIG_EDAC_POLL=y
+
+#
+# Real Time Clock
+#
+CONFIG_RTC_LIB=m
+CONFIG_RTC_CLASS=m
+
+#
+# RTC interfaces
+#
+CONFIG_RTC_INTF_SYSFS=m
+CONFIG_RTC_INTF_PROC=m
+CONFIG_RTC_INTF_DEV=m
+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
+
+#
+# RTC drivers
+#
+CONFIG_RTC_DRV_X1205=m
+CONFIG_RTC_DRV_DS1307=m
+CONFIG_RTC_DRV_DS1553=m
+CONFIG_RTC_DRV_ISL1208=m
+CONFIG_RTC_DRV_DS1672=m
+CONFIG_RTC_DRV_DS1742=m
+CONFIG_RTC_DRV_PCF8563=m
+CONFIG_RTC_DRV_PCF8583=m
+CONFIG_RTC_DRV_RS5C372=m
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_TEST is not set
+CONFIG_RTC_DRV_V3020=m
+
+#
+# DMA Engine support
+#
+CONFIG_DMA_ENGINE=y
+
+#
+# DMA Clients
+#
+CONFIG_NET_DMA=y
+
+#
+# DMA Devices
+#
+CONFIG_INTEL_IOATDMA=m
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+CONFIG_EXT2_FS_POSIX_ACL=y
+CONFIG_EXT2_FS_SECURITY=y
+CONFIG_EXT2_FS_XIP=y
+CONFIG_FS_XIP=y
+CONFIG_EXT3_FS=m
+CONFIG_EXT3_FS_XATTR=y
+CONFIG_EXT3_FS_POSIX_ACL=y
+CONFIG_EXT3_FS_SECURITY=y
+CONFIG_JBD=m
+# CONFIG_JBD_DEBUG is not set
+CONFIG_FS_MBCACHE=y
+CONFIG_REISERFS_FS=m
+# CONFIG_REISERFS_CHECK is not set
+CONFIG_REISERFS_PROC_INFO=y
+CONFIG_REISERFS_FS_XATTR=y
+CONFIG_REISERFS_FS_POSIX_ACL=y
+CONFIG_REISERFS_FS_SECURITY=y
+CONFIG_JFS_FS=m
+CONFIG_JFS_POSIX_ACL=y
+CONFIG_JFS_SECURITY=y
+# CONFIG_JFS_DEBUG is not set
+# CONFIG_JFS_STATISTICS is not set
+CONFIG_FS_POSIX_ACL=y
+CONFIG_XFS_FS=m
+CONFIG_XFS_QUOTA=y
+CONFIG_XFS_SECURITY=y
+CONFIG_XFS_POSIX_ACL=y
+# CONFIG_XFS_RT is not set
+CONFIG_OCFS2_FS=m
+# CONFIG_OCFS2_DEBUG_MASKLOG is not set
+CONFIG_MINIX_FS=m
+CONFIG_ROMFS_FS=m
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+CONFIG_QUOTA=y
+# CONFIG_QFMT_V1 is not set
+CONFIG_QFMT_V2=y
+CONFIG_QUOTACTL=y
+CONFIG_DNOTIFY=y
+CONFIG_AUTOFS_FS=m
+CONFIG_AUTOFS4_FS=m
+CONFIG_FUSE_FS=m
+
+#
+# Caches
+#
+CONFIG_FSCACHE=m
+
+#
+# CD-ROM/DVD Filesystems
+#
+CONFIG_ISO9660_FS=y
+CONFIG_JOLIET=y
+CONFIG_ZISOFS=y
+CONFIG_ZISOFS_FS=y
+CONFIG_UDF_FS=m
+CONFIG_UDF_NLS=y
+CONFIG_CACHEFILES=m
+CONFIG_CACHEFILES_DEBUG=y
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=m
+CONFIG_MSDOS_FS=m
+CONFIG_VFAT_FS=m
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="ascii"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+CONFIG_HUGETLBFS=y
+CONFIG_HUGETLB_PAGE=y
+CONFIG_RAMFS=y
+CONFIG_CONFIGFS_FS=m
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+CONFIG_AFFS_FS=m
+CONFIG_HFS_FS=m
+CONFIG_HFSPLUS_FS=m
+CONFIG_BEFS_FS=m
+# CONFIG_BEFS_DEBUG is not set
+CONFIG_BFS_FS=m
+CONFIG_EFS_FS=m
+# CONFIG_JFFS_FS is not set
+CONFIG_JFFS2_FS=m
+CONFIG_JFFS2_FS_DEBUG=0
+CONFIG_JFFS2_FS_WRITEBUFFER=y
+CONFIG_JFFS2_SUMMARY=y
+# 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=m
+CONFIG_SQUASHFS=m
+# CONFIG_SQUASHFS_EMBEDDED is not set
+CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3
+# CONFIG_SQUASHFS_VMALLOC is not set
+CONFIG_VXFS_FS=m
+# CONFIG_HPFS_FS is not set
+CONFIG_QNX4FS_FS=m
+CONFIG_SYSV_FS=m
+CONFIG_UFS_FS=m
+# CONFIG_UFS_FS_WRITE is not set
+# CONFIG_UFS_DEBUG is not set
+
+#
+# Network File Systems
+#
+CONFIG_NFS_FS=m
+CONFIG_NFS_V3=y
+CONFIG_NFS_V3_ACL=y
+CONFIG_NFS_V4=y
+CONFIG_NFS_FSCACHE=y
+CONFIG_NFS_DIRECTIO=y
+CONFIG_NFSD=m
+CONFIG_NFSD_V2_ACL=y
+CONFIG_NFSD_V3=y
+CONFIG_NFSD_V3_ACL=y
+CONFIG_NFSD_V4=y
+CONFIG_NFSD_TCP=y
+CONFIG_LOCKD=m
+CONFIG_LOCKD_V4=y
+CONFIG_EXPORTFS=m
+CONFIG_NFS_ACL_SUPPORT=m
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=m
+CONFIG_SUNRPC_GSS=m
+CONFIG_RPCSEC_GSS_KRB5=m
+CONFIG_RPCSEC_GSS_SPKM3=m
+# CONFIG_SMB_FS is not set
+CONFIG_CIFS=m
+# CONFIG_CIFS_STATS is not set
+CONFIG_CIFS_WEAK_PW_HASH=y
+CONFIG_CIFS_XATTR=y
+CONFIG_CIFS_POSIX=y
+# CONFIG_CIFS_DEBUG2 is not set
+# CONFIG_CIFS_EXPERIMENTAL is not set
+CONFIG_NCP_FS=m
+CONFIG_NCPFS_PACKET_SIGNING=y
+CONFIG_NCPFS_IOCTL_LOCKING=y
+CONFIG_NCPFS_STRONG=y
+CONFIG_NCPFS_NFS_NS=y
+CONFIG_NCPFS_OS2_NS=y
+CONFIG_NCPFS_SMALLDOS=y
+CONFIG_NCPFS_NLS=y
+CONFIG_NCPFS_EXTRAS=y
+CONFIG_CODA_FS=m
+# CONFIG_CODA_FS_OLD_API is not set
+# CONFIG_AFS_FS is not set
+CONFIG_9P_FS=m
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+CONFIG_OSF_PARTITION=y
+CONFIG_AMIGA_PARTITION=y
+# CONFIG_ATARI_PARTITION is not set
+CONFIG_MAC_PARTITION=y
+CONFIG_MSDOS_PARTITION=y
+CONFIG_BSD_DISKLABEL=y
+CONFIG_MINIX_SUBPARTITION=y
+CONFIG_SOLARIS_X86_PARTITION=y
+CONFIG_UNIXWARE_DISKLABEL=y
+# CONFIG_LDM_PARTITION is not set
+CONFIG_SGI_PARTITION=y
+# CONFIG_ULTRIX_PARTITION is not set
+CONFIG_SUN_PARTITION=y
+CONFIG_KARMA_PARTITION=y
+CONFIG_EFI_PARTITION=y
+
+#
+# Native Language Support
+#
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="utf8"
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_CODEPAGE_737=m
+CONFIG_NLS_CODEPAGE_775=m
+CONFIG_NLS_CODEPAGE_850=m
+CONFIG_NLS_CODEPAGE_852=m
+CONFIG_NLS_CODEPAGE_855=m
+CONFIG_NLS_CODEPAGE_857=m
+CONFIG_NLS_CODEPAGE_860=m
+CONFIG_NLS_CODEPAGE_861=m
+CONFIG_NLS_CODEPAGE_862=m
+CONFIG_NLS_CODEPAGE_863=m
+CONFIG_NLS_CODEPAGE_864=m
+CONFIG_NLS_CODEPAGE_865=m
+CONFIG_NLS_CODEPAGE_866=m
+CONFIG_NLS_CODEPAGE_869=m
+CONFIG_NLS_CODEPAGE_936=m
+CONFIG_NLS_CODEPAGE_950=m
+CONFIG_NLS_CODEPAGE_932=m
+CONFIG_NLS_CODEPAGE_949=m
+CONFIG_NLS_CODEPAGE_874=m
+CONFIG_NLS_ISO8859_8=m
+CONFIG_NLS_CODEPAGE_1250=m
+CONFIG_NLS_CODEPAGE_1251=m
+CONFIG_NLS_ASCII=y
+CONFIG_NLS_ISO8859_1=m
+CONFIG_NLS_ISO8859_2=m
+CONFIG_NLS_ISO8859_3=m
+CONFIG_NLS_ISO8859_4=m
+CONFIG_NLS_ISO8859_5=m
+CONFIG_NLS_ISO8859_6=m
+CONFIG_NLS_ISO8859_7=m
+CONFIG_NLS_ISO8859_9=m
+CONFIG_NLS_ISO8859_13=m
+CONFIG_NLS_ISO8859_14=m
+CONFIG_NLS_ISO8859_15=m
+CONFIG_NLS_KOI8_R=m
+CONFIG_NLS_KOI8_U=m
+CONFIG_NLS_UTF8=m
+
+#
+# Instrumentation Support
+#
+CONFIG_PROFILING=y
+CONFIG_OPROFILE=m
+CONFIG_KPROBES=y
+
+#
+# Kernel hacking
+#
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+# CONFIG_PRINTK_TIME is not set
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_UNUSED_SYMBOLS is not set
+CONFIG_DEBUG_KERNEL=y
+CONFIG_LOG_BUF_SHIFT=17
+CONFIG_DETECT_SOFTLOCKUP=y
+CONFIG_SCHEDSTATS=y
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
+CONFIG_DEBUG_SPINLOCK=y
+# 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=y
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+# CONFIG_DEBUG_KOBJECT is not set
+CONFIG_DEBUG_HIGHMEM=y
+CONFIG_DEBUG_BUGVERBOSE=y
+CONFIG_DEBUG_INFO=y
+CONFIG_DEBUG_FS=y
+# CONFIG_DEBUG_VM is not set
+CONFIG_DEBUG_LIST=y
+# CONFIG_FRAME_POINTER is not set
+CONFIG_UNWIND_INFO=y
+CONFIG_STACK_UNWIND=y
+# CONFIG_FORCED_INLINING is not set
+CONFIG_BOOT_DELAY=y
+# CONFIG_RCU_TORTURE_TEST is not set
+CONFIG_EARLY_PRINTK=y
+CONFIG_DEBUG_STACKOVERFLOW=y
+CONFIG_DEBUG_STACK_USAGE=y
+CONFIG_DEBUG_RODATA=y
+CONFIG_4KSTACKS=y
+CONFIG_X86_FIND_SMP_CONFIG=y
+CONFIG_X86_MPPARSE=y
+CONFIG_DOUBLEFAULT=y
+
+#
+# Security options
+#
+CONFIG_KEYS=y
+CONFIG_KEYS_DEBUG_PROC_KEYS=y
+CONFIG_SECURITY=y
+CONFIG_SECURITY_NETWORK=y
+# CONFIG_SECURITY_NETWORK_XFRM is not set
+CONFIG_SECURITY_CAPABILITIES=y
+# CONFIG_SECURITY_ROOTPLUG is not set
+# CONFIG_SECURITY_SECLVL is not set
+CONFIG_SECURITY_SELINUX=y
+CONFIG_SECURITY_SELINUX_BOOTPARAM=y
+CONFIG_SECURITY_SELINUX_BOOTPARAM_VALUE=1
+CONFIG_SECURITY_SELINUX_DISABLE=y
+CONFIG_SECURITY_SELINUX_DEVELOP=y
+CONFIG_SECURITY_SELINUX_AVC_STATS=y
+CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE=1
+# CONFIG_SECURITY_SELINUX_ENABLE_SECMARK_DEFAULT is not set
+# CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX is not set
+
+#
+# Cryptographic options
+#
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_NULL=m
+CONFIG_CRYPTO_MD4=m
+CONFIG_CRYPTO_MD5=m
+CONFIG_CRYPTO_SHA1=y
+CONFIG_CRYPTO_SHA256=m
+CONFIG_CRYPTO_SHA512=m
+CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_TGR192=m
+CONFIG_CRYPTO_DES=m
+CONFIG_CRYPTO_BLOWFISH=m
+CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_SERPENT=m
+CONFIG_CRYPTO_AES=m
+CONFIG_CRYPTO_AES_586=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_TEST is not set
+CONFIG_CRYPTO_SIGNATURE=y
+CONFIG_CRYPTO_SIGNATURE_DSA=y
+CONFIG_CRYPTO_MPILIB=y
+
+#
+# Hardware crypto devices
+#
+CONFIG_CRYPTO_DEV_PADLOCK=m
+CONFIG_CRYPTO_DEV_PADLOCK_AES=y
+
+#
+# Library routines
+#
+CONFIG_CRC_CCITT=m
+CONFIG_CRC16=m
+CONFIG_CRC32=y
+CONFIG_LIBCRC32C=m
+CONFIG_AUDIT_GENERIC=y
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=m
+CONFIG_REED_SOLOMON=m
+CONFIG_REED_SOLOMON_DEC16=y
+CONFIG_TEXTSEARCH=y
+CONFIG_TEXTSEARCH_KMP=m
+CONFIG_TEXTSEARCH_BM=m
+CONFIG_TEXTSEARCH_FSM=m
+CONFIG_PLIST=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_GENERIC_PENDING_IRQ=y
+CONFIG_X86_SMP=y
+CONFIG_X86_HT=y
+CONFIG_X86_BIOS_REBOOT=y
+CONFIG_X86_TRAMPOLINE=y
+CONFIG_KTIME_SCALAR=y
diff --git a/configs/kernel-2.6.18-i686-xen.config b/configs/kernel-2.6.18-i686-xen.config
new file mode 100644
index 000000000..b6af8017a
--- /dev/null
+++ b/configs/kernel-2.6.18-i686-xen.config
@@ -0,0 +1,3260 @@
+# i386
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.18.2-rc1
+# Mon Nov 13 09:44:40 2006
+#
+CONFIG_X86_32=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_SEMAPHORE_SLEEPERS=y
+CONFIG_X86=y
+CONFIG_MMU=y
+CONFIG_GENERIC_ISA_DMA=y
+CONFIG_GENERIC_IOMAP=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_ARCH_MAY_HAVE_PC_FDC=y
+CONFIG_DMI=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_BSD_PROCESS_ACCT=y
+# CONFIG_BSD_PROCESS_ACCT_V3 is not set
+CONFIG_TASKSTATS=y
+CONFIG_TASK_DELAY_ACCT=y
+CONFIG_AUDIT=y
+CONFIG_AUDITSYSCALL=y
+# CONFIG_IKCONFIG is not set
+CONFIG_CPUSETS=y
+CONFIG_RELAY=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+# CONFIG_EMBEDDED is not set
+CONFIG_UID16=y
+CONFIG_SYSCTL=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
+CONFIG_KALLSYMS_EXTRA_PASS=y
+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=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+CONFIG_MODULE_SIG=y
+# CONFIG_MODULE_SIG_FORCE is not set
+CONFIG_KMOD=y
+CONFIG_STOP_MACHINE=y
+
+#
+# Process debugging support
+#
+CONFIG_UTRACE=y
+CONFIG_PTRACE=y
+
+#
+# Block layer
+#
+CONFIG_LBD=y
+CONFIG_BLK_DEV_IO_TRACE=y
+CONFIG_LSF=y
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_DEFAULT_AS is not set
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+
+#
+# Processor type and features
+#
+CONFIG_SMP=y
+# CONFIG_X86_PC is not set
+CONFIG_X86_XEN=y
+# CONFIG_X86_ELAN is not set
+# CONFIG_X86_VOYAGER is not set
+# CONFIG_X86_NUMAQ is not set
+# CONFIG_X86_SUMMIT is not set
+# CONFIG_X86_BIGSMP is not set
+# CONFIG_X86_VISWS is not set
+# CONFIG_X86_GENERICARCH is not set
+# CONFIG_X86_ES7000 is not set
+# CONFIG_M386 is not set
+# CONFIG_M486 is not set
+# CONFIG_M586 is not set
+# CONFIG_M586TSC is not set
+# CONFIG_M586MMX is not set
+CONFIG_M686=y
+# CONFIG_MPENTIUMII is not set
+# CONFIG_MPENTIUMIII is not set
+# CONFIG_MPENTIUMM is not set
+# CONFIG_MPENTIUM4 is not set
+# CONFIG_MK6 is not set
+# CONFIG_MK7 is not set
+# CONFIG_MK8 is not set
+# CONFIG_MCRUSOE is not set
+# CONFIG_MEFFICEON is not set
+# CONFIG_MWINCHIPC6 is not set
+# CONFIG_MWINCHIP2 is not set
+# CONFIG_MWINCHIP3D is not set
+# CONFIG_MGEODEGX1 is not set
+# CONFIG_MGEODE_LX is not set
+# CONFIG_MCYRIXIII is not set
+# CONFIG_MVIAC3_2 is not set
+CONFIG_X86_GENERIC=y
+CONFIG_X86_CMPXCHG=y
+CONFIG_X86_XADD=y
+CONFIG_X86_L1_CACHE_SHIFT=7
+CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_X86_PPRO_FENCE=y
+CONFIG_X86_WP_WORKS_OK=y
+CONFIG_X86_INVLPG=y
+CONFIG_X86_BSWAP=y
+CONFIG_X86_POPAD_OK=y
+CONFIG_X86_CMPXCHG64=y
+CONFIG_X86_GOOD_APIC=y
+CONFIG_X86_INTEL_USERCOPY=y
+CONFIG_X86_USE_PPRO_CHECKSUM=y
+CONFIG_NR_CPUS=32
+# CONFIG_PREEMPT_NONE is not set
+CONFIG_PREEMPT_VOLUNTARY=y
+# CONFIG_PREEMPT is not set
+CONFIG_PREEMPT_BKL=y
+CONFIG_X86_LOCAL_APIC=y
+CONFIG_X86_APIC_AUTO=y
+CONFIG_X86_IO_APIC=y
+CONFIG_VM86=y
+CONFIG_TOSHIBA=m
+CONFIG_I8K=m
+# CONFIG_X86_REBOOTFIXUPS is not set
+CONFIG_MICROCODE=y
+CONFIG_X86_CPUID=m
+CONFIG_SWIOTLB=y
+
+#
+# Firmware Drivers
+#
+CONFIG_DELL_RBU=m
+CONFIG_DCDBAS=m
+# CONFIG_NOHIGHMEM is not set
+# CONFIG_HIGHMEM4G is not set
+CONFIG_HIGHMEM64G=y
+CONFIG_PAGE_OFFSET=0xC0000000
+CONFIG_HIGHMEM=y
+CONFIG_X86_PAE=y
+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=y
+CONFIG_MTRR=y
+CONFIG_REGPARM=y
+# CONFIG_SECCOMP is not set
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
+# CONFIG_CRASH_DUMP is not set
+CONFIG_PHYSICAL_START=0x400000
+CONFIG_HOTPLUG_CPU=y
+CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
+
+#
+# Power management options (ACPI, APM)
+#
+CONFIG_PM=y
+
+#
+# ACPI (Advanced Configuration and Power Interface) Support
+#
+CONFIG_ACPI=y
+CONFIG_ACPI_AC=m
+CONFIG_ACPI_BATTERY=m
+CONFIG_ACPI_BUTTON=m
+CONFIG_ACPI_VIDEO=m
+# CONFIG_ACPI_HOTKEY is not set
+CONFIG_ACPI_FAN=y
+CONFIG_ACPI_DOCK=m
+CONFIG_ACPI_PROCESSOR=y
+CONFIG_ACPI_HOTPLUG_CPU=y
+CONFIG_ACPI_THERMAL=y
+CONFIG_ACPI_ASUS=m
+CONFIG_ACPI_IBM=m
+CONFIG_ACPI_TOSHIBA=m
+CONFIG_ACPI_BLACKLIST_YEAR=1999
+# CONFIG_ACPI_DEBUG is not set
+CONFIG_ACPI_EC=y
+CONFIG_ACPI_POWER=y
+CONFIG_ACPI_SYSTEM=y
+CONFIG_ACPI_CONTAINER=y
+CONFIG_ACPI_SBS=m
+
+#
+# CPU Frequency scaling
+#
+CONFIG_CPU_FREQ=y
+CONFIG_CPU_FREQ_TABLE=y
+CONFIG_CPU_FREQ_DEBUG=y
+CONFIG_CPU_FREQ_STAT=m
+CONFIG_CPU_FREQ_STAT_DETAILS=y
+# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set
+CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE=y
+CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
+CONFIG_CPU_FREQ_GOV_POWERSAVE=m
+CONFIG_CPU_FREQ_GOV_USERSPACE=y
+CONFIG_CPU_FREQ_GOV_ONDEMAND=m
+CONFIG_CPU_FREQ_GOV_CONSERVATIVE=m
+
+#
+# CPUFreq processor drivers
+#
+CONFIG_X86_ACPI_CPUFREQ=m
+# CONFIG_X86_POWERNOW_K6 is not set
+CONFIG_X86_POWERNOW_K7=y
+CONFIG_X86_POWERNOW_K7_ACPI=y
+CONFIG_X86_POWERNOW_K8=y
+CONFIG_X86_POWERNOW_K8_ACPI=y
+# CONFIG_X86_GX_SUSPMOD is not set
+CONFIG_X86_SPEEDSTEP_CENTRINO=y
+CONFIG_X86_SPEEDSTEP_CENTRINO_ACPI=y
+CONFIG_X86_SPEEDSTEP_CENTRINO_TABLE=y
+CONFIG_X86_SPEEDSTEP_ICH=y
+CONFIG_X86_SPEEDSTEP_SMI=y
+CONFIG_X86_P4_CLOCKMOD=m
+# CONFIG_X86_CPUFREQ_NFORCE2 is not set
+CONFIG_X86_LONGRUN=y
+# CONFIG_X86_LONGHAUL is not set
+
+#
+# shared options
+#
+# CONFIG_X86_ACPI_CPUFREQ_PROC_INTF is not set
+CONFIG_X86_SPEEDSTEP_LIB=y
+# CONFIG_X86_SPEEDSTEP_RELAXED_CAP_CHECK is not set
+
+#
+# Bus options (PCI, PCMCIA, EISA, MCA, ISA)
+#
+CONFIG_PCI=y
+# CONFIG_PCI_GOBIOS is not set
+# CONFIG_PCI_GOMMCONFIG is not set
+# CONFIG_PCI_GODIRECT is not set
+# CONFIG_PCI_GOXEN_FE is not set
+CONFIG_PCI_GOANY=y
+CONFIG_PCI_DIRECT=y
+CONFIG_PCI_MMCONFIG=y
+CONFIG_XEN_PCIDEV_FRONTEND=y
+# CONFIG_XEN_PCIDEV_FE_DEBUG is not set
+CONFIG_PCIEPORTBUS=y
+CONFIG_HOTPLUG_PCI_PCIE=m
+# CONFIG_HOTPLUG_PCI_PCIE_POLL_EVENT_MODE is not set
+# CONFIG_PCI_DEBUG is not set
+CONFIG_ISA_DMA_API=y
+# CONFIG_SCx200 is not set
+CONFIG_K8_NB=y
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+CONFIG_PCCARD=y
+# CONFIG_PCMCIA_DEBUG is not set
+CONFIG_PCMCIA=y
+CONFIG_PCMCIA_LOAD_CIS=y
+CONFIG_PCMCIA_IOCTL=y
+CONFIG_CARDBUS=y
+
+#
+# PC-card bridges
+#
+CONFIG_YENTA=y
+CONFIG_YENTA_O2=y
+CONFIG_YENTA_RICOH=y
+CONFIG_YENTA_TI=y
+CONFIG_YENTA_ENE_TUNE=y
+CONFIG_YENTA_TOSHIBA=y
+CONFIG_PD6729=m
+CONFIG_I82092=m
+CONFIG_PCCARD_NONSTATIC=y
+
+#
+# PCI Hotplug Support
+#
+CONFIG_HOTPLUG_PCI=y
+CONFIG_HOTPLUG_PCI_FAKE=m
+CONFIG_HOTPLUG_PCI_ACPI=m
+CONFIG_HOTPLUG_PCI_ACPI_IBM=m
+# CONFIG_HOTPLUG_PCI_CPCI is not set
+# CONFIG_HOTPLUG_PCI_SHPC is not set
+
+#
+# Executable file formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_AOUT is not set
+CONFIG_BINFMT_MISC=y
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+# CONFIG_NETDEBUG is not set
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=y
+CONFIG_NET_KEY=m
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_ASK_IP_FIB_HASH=y
+# 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
+# CONFIG_IP_PNP is not set
+CONFIG_NET_IPIP=m
+CONFIG_NET_IPGRE=m
+CONFIG_NET_IPGRE_BROADCAST=y
+CONFIG_IP_MROUTE=y
+CONFIG_IP_PIMSM_V1=y
+CONFIG_IP_PIMSM_V2=y
+# CONFIG_ARPD is not set
+CONFIG_SYN_COOKIES=y
+CONFIG_INET_AH=m
+CONFIG_INET_ESP=m
+CONFIG_INET_IPCOMP=m
+CONFIG_INET_XFRM_TUNNEL=m
+CONFIG_INET_TUNNEL=m
+CONFIG_INET_XFRM_MODE_TRANSPORT=m
+CONFIG_INET_XFRM_MODE_TUNNEL=m
+CONFIG_INET_DIAG=m
+CONFIG_INET_TCP_DIAG=m
+CONFIG_TCP_CONG_ADVANCED=y
+
+#
+# TCP congestion control
+#
+CONFIG_TCP_CONG_BIC=y
+CONFIG_TCP_CONG_CUBIC=m
+CONFIG_TCP_CONG_WESTWOOD=m
+CONFIG_TCP_CONG_HTCP=m
+CONFIG_TCP_CONG_HSTCP=m
+CONFIG_TCP_CONG_HYBLA=m
+CONFIG_TCP_CONG_VEGAS=m
+CONFIG_TCP_CONG_SCALABLE=m
+CONFIG_TCP_CONG_LP=m
+CONFIG_TCP_CONG_VENO=m
+
+#
+# IP: Virtual Server Configuration
+#
+CONFIG_IP_VS=m
+# CONFIG_IP_VS_DEBUG is not set
+CONFIG_IP_VS_TAB_BITS=12
+
+#
+# IPVS transport protocol load balancing support
+#
+CONFIG_IP_VS_PROTO_TCP=y
+CONFIG_IP_VS_PROTO_UDP=y
+CONFIG_IP_VS_PROTO_ESP=y
+CONFIG_IP_VS_PROTO_AH=y
+
+#
+# IPVS scheduler
+#
+CONFIG_IP_VS_RR=m
+CONFIG_IP_VS_WRR=m
+CONFIG_IP_VS_LC=m
+CONFIG_IP_VS_WLC=m
+CONFIG_IP_VS_LBLC=m
+CONFIG_IP_VS_LBLCR=m
+CONFIG_IP_VS_DH=m
+CONFIG_IP_VS_SH=m
+CONFIG_IP_VS_SED=m
+CONFIG_IP_VS_NQ=m
+
+#
+# IPVS application helper
+#
+CONFIG_IP_VS_FTP=m
+CONFIG_IPV6=m
+CONFIG_IPV6_PRIVACY=y
+CONFIG_IPV6_ROUTER_PREF=y
+CONFIG_IPV6_ROUTE_INFO=y
+CONFIG_INET6_AH=m
+CONFIG_INET6_ESP=m
+CONFIG_INET6_IPCOMP=m
+CONFIG_INET6_XFRM_TUNNEL=m
+CONFIG_INET6_TUNNEL=m
+CONFIG_INET6_XFRM_MODE_TRANSPORT=m
+CONFIG_INET6_XFRM_MODE_TUNNEL=m
+CONFIG_IPV6_TUNNEL=m
+CONFIG_NETWORK_SECMARK=y
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_DEBUG is not set
+CONFIG_BRIDGE_NETFILTER=y
+
+#
+# Core Netfilter Configuration
+#
+CONFIG_NETFILTER_NETLINK=m
+CONFIG_NETFILTER_NETLINK_QUEUE=m
+CONFIG_NETFILTER_NETLINK_LOG=m
+CONFIG_NETFILTER_XTABLES=m
+CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
+CONFIG_NETFILTER_XT_TARGET_CONNMARK=m
+CONFIG_NETFILTER_XT_TARGET_MARK=m
+CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
+CONFIG_NETFILTER_XT_TARGET_NOTRACK=m
+CONFIG_NETFILTER_XT_TARGET_SECMARK=m
+CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=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_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_PHYSDEV=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
+
+#
+# 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=m
+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_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_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_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
+CONFIG_IP_NF_ARPTABLES=m
+CONFIG_IP_NF_ARPFILTER=m
+CONFIG_IP_NF_ARP_MANGLE=m
+
+#
+# IPv6: Netfilter Configuration (EXPERIMENTAL)
+#
+CONFIG_IP6_NF_QUEUE=m
+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_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
+
+#
+# DECnet: Netfilter Configuration
+#
+# CONFIG_DECNET_NF_GRABULATOR is not set
+
+#
+# Bridge: Netfilter Configuration
+#
+CONFIG_BRIDGE_NF_EBTABLES=m
+CONFIG_BRIDGE_EBT_BROUTE=m
+CONFIG_BRIDGE_EBT_T_FILTER=m
+CONFIG_BRIDGE_EBT_T_NAT=m
+CONFIG_BRIDGE_EBT_802_3=m
+CONFIG_BRIDGE_EBT_AMONG=m
+CONFIG_BRIDGE_EBT_ARP=m
+CONFIG_BRIDGE_EBT_IP=m
+CONFIG_BRIDGE_EBT_LIMIT=m
+CONFIG_BRIDGE_EBT_MARK=m
+CONFIG_BRIDGE_EBT_PKTTYPE=m
+CONFIG_BRIDGE_EBT_STP=m
+CONFIG_BRIDGE_EBT_VLAN=m
+CONFIG_BRIDGE_EBT_ARPREPLY=m
+CONFIG_BRIDGE_EBT_DNAT=m
+CONFIG_BRIDGE_EBT_MARK_T=m
+CONFIG_BRIDGE_EBT_REDIRECT=m
+CONFIG_BRIDGE_EBT_SNAT=m
+CONFIG_BRIDGE_EBT_LOG=m
+CONFIG_BRIDGE_EBT_ULOG=m
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+CONFIG_IP_DCCP=m
+CONFIG_INET_DCCP_DIAG=m
+CONFIG_IP_DCCP_ACKVEC=y
+
+#
+# DCCP CCIDs Configuration (EXPERIMENTAL)
+#
+CONFIG_IP_DCCP_CCID2=m
+CONFIG_IP_DCCP_CCID3=m
+CONFIG_IP_DCCP_TFRC_LIB=m
+
+#
+# DCCP Kernel Hacking
+#
+# CONFIG_IP_DCCP_DEBUG is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+CONFIG_IP_SCTP=m
+# CONFIG_SCTP_DBG_MSG is not set
+# CONFIG_SCTP_DBG_OBJCNT is not set
+# CONFIG_SCTP_HMAC_NONE is not set
+# CONFIG_SCTP_HMAC_SHA1 is not set
+CONFIG_SCTP_HMAC_MD5=y
+
+#
+# TIPC Configuration (EXPERIMENTAL)
+#
+CONFIG_TIPC=m
+# CONFIG_TIPC_ADVANCED is not set
+# CONFIG_TIPC_DEBUG is not set
+CONFIG_ATM=m
+CONFIG_ATM_CLIP=m
+# CONFIG_ATM_CLIP_NO_ICMP is not set
+CONFIG_ATM_LANE=m
+# CONFIG_ATM_MPOA is not set
+CONFIG_ATM_BR2684=m
+# CONFIG_ATM_BR2684_IPFILTER is not set
+CONFIG_BRIDGE=m
+CONFIG_VLAN_8021Q=m
+CONFIG_DECNET=m
+CONFIG_DECNET_ROUTER=y
+CONFIG_DECNET_ROUTE_FWMARK=y
+CONFIG_LLC=y
+# CONFIG_LLC2 is not set
+CONFIG_IPX=m
+# CONFIG_IPX_INTERN is not set
+CONFIG_ATALK=m
+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_ECONET is not set
+CONFIG_WAN_ROUTER=m
+
+#
+# QoS and/or fair queueing
+#
+CONFIG_NET_SCHED=y
+# CONFIG_NET_SCH_CLK_JIFFIES is not set
+CONFIG_NET_SCH_CLK_GETTIMEOFDAY=y
+# CONFIG_NET_SCH_CLK_CPU is not set
+
+#
+# Queueing/Scheduling
+#
+CONFIG_NET_SCH_CBQ=m
+CONFIG_NET_SCH_HTB=m
+CONFIG_NET_SCH_HFSC=m
+CONFIG_NET_SCH_ATM=m
+CONFIG_NET_SCH_PRIO=m
+CONFIG_NET_SCH_RED=m
+CONFIG_NET_SCH_SFQ=m
+CONFIG_NET_SCH_TEQL=m
+CONFIG_NET_SCH_TBF=m
+CONFIG_NET_SCH_GRED=m
+CONFIG_NET_SCH_DSMARK=m
+CONFIG_NET_SCH_NETEM=m
+CONFIG_NET_SCH_INGRESS=m
+
+#
+# Classification
+#
+CONFIG_NET_CLS=y
+CONFIG_NET_CLS_BASIC=m
+CONFIG_NET_CLS_TCINDEX=m
+CONFIG_NET_CLS_ROUTE4=m
+CONFIG_NET_CLS_ROUTE=y
+CONFIG_NET_CLS_FW=m
+CONFIG_NET_CLS_U32=m
+CONFIG_CLS_U32_PERF=y
+CONFIG_CLS_U32_MARK=y
+CONFIG_NET_CLS_RSVP=m
+CONFIG_NET_CLS_RSVP6=m
+CONFIG_NET_EMATCH=y
+CONFIG_NET_EMATCH_STACK=32
+CONFIG_NET_EMATCH_CMP=m
+CONFIG_NET_EMATCH_NBYTE=m
+CONFIG_NET_EMATCH_U32=m
+CONFIG_NET_EMATCH_META=m
+CONFIG_NET_EMATCH_TEXT=m
+CONFIG_NET_CLS_ACT=y
+CONFIG_NET_ACT_POLICE=m
+CONFIG_NET_ACT_GACT=m
+CONFIG_GACT_PROB=y
+CONFIG_NET_ACT_MIRRED=m
+CONFIG_NET_ACT_IPT=m
+CONFIG_NET_ACT_PEDIT=m
+CONFIG_NET_ACT_SIMP=m
+CONFIG_NET_CLS_IND=y
+CONFIG_NET_ESTIMATOR=y
+
+#
+# Network testing
+#
+CONFIG_NET_PKTGEN=m
+# CONFIG_NET_TCPPROBE is not set
+# CONFIG_HAMRADIO is not set
+CONFIG_IRDA=m
+
+#
+# IrDA protocols
+#
+CONFIG_IRLAN=m
+CONFIG_IRNET=m
+CONFIG_IRCOMM=m
+# CONFIG_IRDA_ULTRA is not set
+
+#
+# IrDA options
+#
+CONFIG_IRDA_CACHE_LAST_LSAP=y
+CONFIG_IRDA_FAST_RR=y
+# CONFIG_IRDA_DEBUG is not set
+
+#
+# Infrared-port device drivers
+#
+
+#
+# SIR device drivers
+#
+CONFIG_IRTTY_SIR=m
+
+#
+# Dongle support
+#
+CONFIG_DONGLE=y
+CONFIG_ESI_DONGLE=m
+CONFIG_ACTISYS_DONGLE=m
+CONFIG_TEKRAM_DONGLE=m
+CONFIG_TOIM3232_DONGLE=m
+CONFIG_LITELINK_DONGLE=m
+CONFIG_MA600_DONGLE=m
+CONFIG_GIRBIL_DONGLE=m
+CONFIG_MCP2120_DONGLE=m
+CONFIG_OLD_BELKIN_DONGLE=m
+CONFIG_ACT200L_DONGLE=m
+
+#
+# Old SIR device drivers
+#
+
+#
+# Old Serial dongle support
+#
+
+#
+# FIR device drivers
+#
+CONFIG_USB_IRDA=m
+CONFIG_SIGMATEL_FIR=m
+CONFIG_NSC_FIR=m
+CONFIG_WINBOND_FIR=m
+CONFIG_TOSHIBA_FIR=m
+CONFIG_SMC_IRCC_FIR=m
+CONFIG_ALI_FIR=m
+CONFIG_VLSI_FIR=m
+CONFIG_VIA_FIR=m
+CONFIG_MCS_FIR=m
+CONFIG_BT=m
+CONFIG_BT_L2CAP=m
+CONFIG_BT_SCO=m
+CONFIG_BT_RFCOMM=m
+CONFIG_BT_RFCOMM_TTY=y
+CONFIG_BT_BNEP=m
+CONFIG_BT_BNEP_MC_FILTER=y
+CONFIG_BT_BNEP_PROTO_FILTER=y
+CONFIG_BT_CMTP=m
+CONFIG_BT_HIDP=m
+
+#
+# Bluetooth device drivers
+#
+CONFIG_BT_HCIUSB=m
+CONFIG_BT_HCIUSB_SCO=y
+CONFIG_BT_HCIUART=m
+CONFIG_BT_HCIUART_H4=y
+CONFIG_BT_HCIUART_BCSP=y
+CONFIG_BT_HCIBCM203X=m
+CONFIG_BT_HCIBPA10X=m
+CONFIG_BT_HCIBFUSB=m
+CONFIG_BT_HCIDTL1=m
+CONFIG_BT_HCIBT3C=m
+CONFIG_BT_HCIBLUECARD=m
+CONFIG_BT_HCIBTUART=m
+CONFIG_BT_HCIVHCI=m
+CONFIG_IEEE80211=m
+# CONFIG_IEEE80211_DEBUG is not set
+CONFIG_IEEE80211_CRYPT_WEP=m
+CONFIG_IEEE80211_CRYPT_CCMP=m
+CONFIG_IEEE80211_CRYPT_TKIP=m
+CONFIG_IEEE80211_SOFTMAC=m
+CONFIG_IEEE80211_SOFTMAC_DEBUG=y
+CONFIG_TUX=m
+
+#
+# TUX options
+#
+CONFIG_TUX_EXTCGI=y
+CONFIG_TUX_EXTENDED_LOG=y
+# CONFIG_TUX_DEBUG is not set
+CONFIG_WIRELESS_EXT=y
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_SYS_HYPERVISOR is not set
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+CONFIG_CONNECTOR=y
+CONFIG_PROC_EVENTS=y
+
+#
+# Memory Technology Devices (MTD)
+#
+CONFIG_MTD=m
+# CONFIG_MTD_DEBUG is not set
+CONFIG_MTD_CONCAT=m
+CONFIG_MTD_PARTITIONS=y
+CONFIG_MTD_REDBOOT_PARTS=m
+CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1
+# CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED is not set
+# CONFIG_MTD_REDBOOT_PARTS_READONLY is not set
+CONFIG_MTD_CMDLINE_PARTS=y
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=m
+CONFIG_MTD_BLOCK=m
+CONFIG_MTD_BLOCK_RO=m
+CONFIG_FTL=m
+CONFIG_NFTL=m
+CONFIG_NFTL_RW=y
+CONFIG_INFTL=m
+CONFIG_RFD_FTL=m
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=m
+CONFIG_MTD_JEDECPROBE=m
+CONFIG_MTD_GEN_PROBE=m
+# CONFIG_MTD_CFI_ADV_OPTIONS 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_CFI_INTELEXT=m
+CONFIG_MTD_CFI_AMDSTD=m
+CONFIG_MTD_CFI_STAA=m
+CONFIG_MTD_CFI_UTIL=m
+CONFIG_MTD_RAM=m
+CONFIG_MTD_ROM=m
+CONFIG_MTD_ABSENT=m
+# CONFIG_MTD_OBSOLETE_CHIPS is not set
+
+#
+# Mapping drivers for chip access
+#
+CONFIG_MTD_COMPLEX_MAPPINGS=y
+# CONFIG_MTD_PHYSMAP is not set
+# CONFIG_MTD_PNC2000 is not set
+CONFIG_MTD_SC520CDP=m
+CONFIG_MTD_NETSC520=m
+CONFIG_MTD_TS5500=m
+# CONFIG_MTD_SBC_GXX is not set
+# CONFIG_MTD_AMD76XROM is not set
+# CONFIG_MTD_ICHXROM is not set
+CONFIG_MTD_SCB2_FLASH=m
+# CONFIG_MTD_NETtel is not set
+# CONFIG_MTD_DILNETPC is not set
+# CONFIG_MTD_L440GX is not set
+CONFIG_MTD_PCI=m
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+CONFIG_MTD_PMC551=m
+# CONFIG_MTD_PMC551_BUGFIX is not set
+# CONFIG_MTD_PMC551_DEBUG is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+CONFIG_MTD_MTDRAM=m
+CONFIG_MTDRAM_TOTAL_SIZE=4096
+CONFIG_MTDRAM_ERASE_SIZE=128
+CONFIG_MTD_BLOCK2MTD=m
+
+#
+# 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=m
+# CONFIG_MTD_NAND_VERIFY_WRITE is not set
+CONFIG_MTD_NAND_ECC_SMC=y
+CONFIG_MTD_NAND_IDS=m
+CONFIG_MTD_NAND_DISKONCHIP=m
+# CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADVANCED is not set
+CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADDRESS=0
+# CONFIG_MTD_NAND_DISKONCHIP_BBTWRITE is not set
+CONFIG_MTD_NAND_NANDSIM=m
+
+#
+# OneNAND Flash Device Drivers
+#
+# CONFIG_MTD_ONENAND is not set
+
+#
+# Parallel port support
+#
+CONFIG_PARPORT=m
+CONFIG_PARPORT_PC=m
+CONFIG_PARPORT_SERIAL=m
+# CONFIG_PARPORT_PC_FIFO is not set
+# CONFIG_PARPORT_PC_SUPERIO is not set
+CONFIG_PARPORT_PC_PCMCIA=m
+CONFIG_PARPORT_NOT_PC=y
+# CONFIG_PARPORT_GSC is not set
+# CONFIG_PARPORT_AX88796 is not set
+CONFIG_PARPORT_1284=y
+
+#
+# Plug and Play support
+#
+CONFIG_PNP=y
+# CONFIG_PNP_DEBUG is not set
+
+#
+# Protocols
+#
+CONFIG_PNPACPI=y
+
+#
+# Block devices
+#
+CONFIG_BLK_DEV_FD=m
+CONFIG_PARIDE=m
+CONFIG_PARIDE_PARPORT=m
+
+#
+# Parallel IDE high-level drivers
+#
+CONFIG_PARIDE_PD=m
+CONFIG_PARIDE_PCD=m
+CONFIG_PARIDE_PF=m
+CONFIG_PARIDE_PT=m
+CONFIG_PARIDE_PG=m
+
+#
+# Parallel IDE protocol modules
+#
+CONFIG_PARIDE_ATEN=m
+CONFIG_PARIDE_BPCK=m
+CONFIG_PARIDE_BPCK6=m
+CONFIG_PARIDE_COMM=m
+CONFIG_PARIDE_DSTR=m
+CONFIG_PARIDE_FIT2=m
+CONFIG_PARIDE_FIT3=m
+CONFIG_PARIDE_EPAT=m
+CONFIG_PARIDE_EPATC8=y
+CONFIG_PARIDE_EPIA=m
+CONFIG_PARIDE_FRIQ=m
+CONFIG_PARIDE_FRPW=m
+CONFIG_PARIDE_KBIC=m
+CONFIG_PARIDE_KTTI=m
+CONFIG_PARIDE_ON20=m
+CONFIG_PARIDE_ON26=m
+CONFIG_BLK_CPQ_DA=m
+CONFIG_BLK_CPQ_CISS_DA=m
+CONFIG_CISS_SCSI_TAPE=y
+CONFIG_BLK_DEV_DAC960=m
+CONFIG_BLK_DEV_UMEM=m
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=m
+CONFIG_BLK_DEV_CRYPTOLOOP=m
+CONFIG_BLK_DEV_NBD=m
+CONFIG_BLK_DEV_SX8=m
+CONFIG_BLK_DEV_UB=m
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=16384
+CONFIG_BLK_DEV_RAM_BLOCKSIZE=4096
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_CDROM_PKTCDVD=m
+CONFIG_CDROM_PKTCDVD_BUFFERS=8
+# CONFIG_CDROM_PKTCDVD_WCACHE is not set
+CONFIG_ATA_OVER_ETH=m
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+CONFIG_IDE=y
+CONFIG_BLK_DEV_IDE=y
+
+#
+# Please see Documentation/ide.txt for help/info on IDE drives
+#
+# CONFIG_BLK_DEV_IDE_SATA is not set
+# CONFIG_BLK_DEV_HD_IDE is not set
+CONFIG_BLK_DEV_IDEDISK=y
+CONFIG_IDEDISK_MULTI_MODE=y
+CONFIG_BLK_DEV_IDECS=m
+CONFIG_BLK_DEV_IDECD=m
+# CONFIG_BLK_DEV_IDETAPE is not set
+CONFIG_BLK_DEV_IDEFLOPPY=y
+CONFIG_BLK_DEV_IDESCSI=m
+CONFIG_IDE_TASK_IOCTL=y
+
+#
+# IDE chipset support/bugfixes
+#
+CONFIG_IDE_GENERIC=y
+CONFIG_BLK_DEV_CMD640=y
+CONFIG_BLK_DEV_CMD640_ENHANCED=y
+CONFIG_BLK_DEV_IDEPNP=y
+CONFIG_BLK_DEV_IDEPCI=y
+CONFIG_IDEPCI_SHARE_IRQ=y
+# CONFIG_BLK_DEV_OFFBOARD is not set
+CONFIG_BLK_DEV_GENERIC=y
+# CONFIG_BLK_DEV_OPTI621 is not set
+CONFIG_BLK_DEV_RZ1000=y
+CONFIG_BLK_DEV_IDEDMA_PCI=y
+# CONFIG_BLK_DEV_IDEDMA_FORCED is not set
+CONFIG_IDEDMA_PCI_AUTO=y
+# CONFIG_IDEDMA_ONLYDISK is not set
+CONFIG_BLK_DEV_AEC62XX=y
+CONFIG_BLK_DEV_ALI15X3=y
+# CONFIG_WDC_ALI15X3 is not set
+CONFIG_BLK_DEV_AMD74XX=y
+CONFIG_BLK_DEV_ATIIXP=y
+CONFIG_BLK_DEV_CMD64X=y
+CONFIG_BLK_DEV_TRIFLEX=y
+# CONFIG_BLK_DEV_CY82C693 is not set
+CONFIG_BLK_DEV_CS5520=y
+CONFIG_BLK_DEV_CS5530=y
+CONFIG_BLK_DEV_CS5535=y
+CONFIG_BLK_DEV_HPT34X=y
+# CONFIG_HPT34X_AUTODMA is not set
+CONFIG_BLK_DEV_HPT366=y
+# CONFIG_BLK_DEV_SC1200 is not set
+CONFIG_BLK_DEV_PIIX=y
+CONFIG_BLK_DEV_IT821X=y
+# CONFIG_BLK_DEV_NS87415 is not set
+CONFIG_BLK_DEV_PDC202XX_OLD=y
+# CONFIG_PDC202XX_BURST is not set
+CONFIG_BLK_DEV_PDC202XX_NEW=y
+CONFIG_BLK_DEV_SVWKS=y
+CONFIG_BLK_DEV_SIIMAGE=y
+CONFIG_BLK_DEV_SIS5513=y
+# CONFIG_BLK_DEV_SLC90E66 is not set
+# CONFIG_BLK_DEV_TRM290 is not set
+CONFIG_BLK_DEV_VIA82CXXX=y
+# CONFIG_IDE_ARM is not set
+CONFIG_BLK_DEV_IDEDMA=y
+# CONFIG_IDEDMA_IVB is not set
+CONFIG_IDEDMA_AUTO=y
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# SCSI device support
+#
+CONFIG_RAID_ATTRS=m
+CONFIG_SCSI=m
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=m
+CONFIG_CHR_DEV_ST=m
+CONFIG_CHR_DEV_OSST=m
+CONFIG_BLK_DEV_SR=m
+CONFIG_BLK_DEV_SR_VENDOR=y
+CONFIG_CHR_DEV_SG=m
+CONFIG_CHR_DEV_SCH=m
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+CONFIG_SCSI_MULTI_LUN=y
+CONFIG_SCSI_CONSTANTS=y
+CONFIG_SCSI_LOGGING=y
+
+#
+# SCSI Transport Attributes
+#
+CONFIG_SCSI_SPI_ATTRS=m
+CONFIG_SCSI_FC_ATTRS=m
+CONFIG_SCSI_ISCSI_ATTRS=m
+CONFIG_SCSI_SAS_ATTRS=m
+
+#
+# SCSI low-level drivers
+#
+CONFIG_ISCSI_TCP=m
+CONFIG_BLK_DEV_3W_XXXX_RAID=m
+CONFIG_SCSI_3W_9XXX=m
+CONFIG_SCSI_ACARD=m
+CONFIG_SCSI_AACRAID=m
+CONFIG_SCSI_AIC7XXX=m
+CONFIG_AIC7XXX_CMDS_PER_DEVICE=4
+CONFIG_AIC7XXX_RESET_DELAY_MS=15000
+# CONFIG_AIC7XXX_DEBUG_ENABLE is not set
+CONFIG_AIC7XXX_DEBUG_MASK=0
+# CONFIG_AIC7XXX_REG_PRETTY_PRINT is not set
+CONFIG_SCSI_AIC7XXX_OLD=m
+CONFIG_SCSI_AIC79XX=m
+CONFIG_AIC79XX_CMDS_PER_DEVICE=4
+CONFIG_AIC79XX_RESET_DELAY_MS=15000
+# CONFIG_AIC79XX_ENABLE_RD_STRM is not set
+# CONFIG_AIC79XX_DEBUG_ENABLE is not set
+CONFIG_AIC79XX_DEBUG_MASK=0
+# CONFIG_AIC79XX_REG_PRETTY_PRINT is not set
+# CONFIG_SCSI_DPT_I2O is not set
+CONFIG_SCSI_ADVANSYS=m
+CONFIG_MEGARAID_NEWGEN=y
+CONFIG_MEGARAID_MM=m
+CONFIG_MEGARAID_MAILBOX=m
+CONFIG_MEGARAID_LEGACY=m
+CONFIG_MEGARAID_SAS=m
+CONFIG_SCSI_SATA=m
+CONFIG_SCSI_SATA_AHCI=m
+CONFIG_SCSI_SATA_SVW=m
+CONFIG_SCSI_ATA_PIIX=m
+CONFIG_SCSI_SATA_MV=m
+CONFIG_SCSI_SATA_NV=m
+CONFIG_SCSI_PDC_ADMA=m
+CONFIG_SCSI_HPTIOP=m
+CONFIG_SCSI_SATA_QSTOR=m
+CONFIG_SCSI_SATA_PROMISE=m
+CONFIG_SCSI_SATA_SX4=m
+CONFIG_SCSI_SATA_SIL=m
+CONFIG_SCSI_SATA_SIL24=m
+CONFIG_SCSI_SATA_SIS=m
+CONFIG_SCSI_SATA_ULI=m
+CONFIG_SCSI_SATA_VIA=m
+CONFIG_SCSI_SATA_VITESSE=m
+CONFIG_SCSI_SATA_INTEL_COMBINED=y
+CONFIG_SCSI_BUSLOGIC=m
+# CONFIG_SCSI_OMIT_FLASHPOINT is not set
+# CONFIG_SCSI_DMX3191D is not set
+# CONFIG_SCSI_EATA is not set
+CONFIG_SCSI_FUTURE_DOMAIN=m
+CONFIG_SCSI_GDTH=m
+CONFIG_SCSI_IPS=m
+CONFIG_SCSI_INITIO=m
+CONFIG_SCSI_INIA100=m
+CONFIG_SCSI_PPA=m
+CONFIG_SCSI_IMM=m
+# CONFIG_SCSI_IZIP_EPP16 is not set
+# CONFIG_SCSI_IZIP_SLOW_CTR is not set
+CONFIG_SCSI_SYM53C8XX_2=m
+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_QLOGIC_1280=m
+CONFIG_SCSI_QLA_FC=m
+CONFIG_SCSI_LPFC=m
+CONFIG_SCSI_DC395x=m
+CONFIG_SCSI_DC390T=m
+# CONFIG_SCSI_NSP32 is not set
+# CONFIG_SCSI_DEBUG is not set
+
+#
+# PCMCIA SCSI adapter support
+#
+CONFIG_PCMCIA_AHA152X=m
+CONFIG_PCMCIA_FDOMAIN=m
+CONFIG_PCMCIA_NINJA_SCSI=m
+CONFIG_PCMCIA_QLOGIC=m
+CONFIG_PCMCIA_SYM53C500=m
+
+#
+# Multi-device support (RAID and LVM)
+#
+CONFIG_MD=y
+CONFIG_BLK_DEV_MD=y
+CONFIG_MD_LINEAR=m
+CONFIG_MD_RAID0=m
+CONFIG_MD_RAID1=m
+CONFIG_MD_RAID10=m
+CONFIG_MD_RAID456=m
+CONFIG_MD_RAID5_RESHAPE=y
+CONFIG_MD_MULTIPATH=m
+CONFIG_MD_FAULTY=m
+CONFIG_BLK_DEV_DM=m
+CONFIG_DM_CRYPT=m
+CONFIG_DM_SNAPSHOT=m
+CONFIG_DM_MIRROR=m
+CONFIG_DM_ZERO=m
+CONFIG_DM_MULTIPATH=m
+CONFIG_DM_MULTIPATH_EMC=m
+
+#
+# Fusion MPT device support
+#
+CONFIG_FUSION=y
+CONFIG_FUSION_SPI=m
+CONFIG_FUSION_FC=m
+CONFIG_FUSION_SAS=m
+CONFIG_FUSION_MAX_SGE=40
+CONFIG_FUSION_CTL=m
+CONFIG_FUSION_LAN=m
+
+#
+# IEEE 1394 (FireWire) support
+#
+CONFIG_IEEE1394=m
+
+#
+# Subsystem Options
+#
+# CONFIG_IEEE1394_VERBOSEDEBUG is not set
+CONFIG_IEEE1394_OUI_DB=y
+CONFIG_IEEE1394_EXTRA_CONFIG_ROMS=y
+CONFIG_IEEE1394_CONFIG_ROM_IP1394=y
+# CONFIG_IEEE1394_EXPORT_FULL_API is not set
+
+#
+# Device Drivers
+#
+CONFIG_IEEE1394_PCILYNX=m
+CONFIG_IEEE1394_OHCI1394=m
+
+#
+# Protocol Drivers
+#
+CONFIG_IEEE1394_VIDEO1394=m
+CONFIG_IEEE1394_SBP2=m
+# CONFIG_IEEE1394_SBP2_PHYS_DMA is not set
+CONFIG_IEEE1394_ETH1394=m
+CONFIG_IEEE1394_DV1394=m
+CONFIG_IEEE1394_RAWIO=m
+
+#
+# I2O device support
+#
+CONFIG_I2O=m
+# CONFIG_I2O_LCT_NOTIFY_ON_CHANGES is not set
+CONFIG_I2O_EXT_ADAPTEC=y
+CONFIG_I2O_EXT_ADAPTEC_DMA64=y
+CONFIG_I2O_CONFIG=m
+CONFIG_I2O_CONFIG_OLD_IOCTL=y
+CONFIG_I2O_BUS=m
+CONFIG_I2O_BLOCK=m
+CONFIG_I2O_SCSI=m
+CONFIG_I2O_PROC=m
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+CONFIG_IFB=m
+CONFIG_DUMMY=m
+CONFIG_BONDING=m
+CONFIG_EQUALIZER=m
+CONFIG_TUN=m
+CONFIG_NET_SB1000=m
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+
+#
+# PHY device support
+#
+CONFIG_PHYLIB=m
+
+#
+# MII PHY device drivers
+#
+CONFIG_MARVELL_PHY=m
+CONFIG_DAVICOM_PHY=m
+CONFIG_QSEMI_PHY=m
+CONFIG_LXT_PHY=m
+CONFIG_CICADA_PHY=m
+CONFIG_VITESSE_PHY=m
+CONFIG_SMSC_PHY=m
+CONFIG_FIXED_PHY=m
+CONFIG_FIXED_MII_10_FDX=y
+CONFIG_FIXED_MII_100_FDX=y
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=m
+CONFIG_HAPPYMEAL=m
+CONFIG_SUNGEM=m
+CONFIG_CASSINI=m
+CONFIG_NET_VENDOR_3COM=y
+CONFIG_VORTEX=m
+CONFIG_TYPHOON=m
+
+#
+# Tulip family network device support
+#
+CONFIG_NET_TULIP=y
+CONFIG_DE2104X=m
+CONFIG_TULIP=m
+# CONFIG_TULIP_MWI is not set
+CONFIG_TULIP_MMIO=y
+# CONFIG_TULIP_NAPI is not set
+CONFIG_DE4X5=m
+CONFIG_WINBOND_840=m
+CONFIG_DM9102=m
+CONFIG_ULI526X=m
+CONFIG_PCMCIA_XIRCOM=m
+# CONFIG_HP100 is not set
+CONFIG_NET_PCI=y
+CONFIG_PCNET32=m
+CONFIG_AMD8111_ETH=m
+CONFIG_AMD8111E_NAPI=y
+CONFIG_ADAPTEC_STARFIRE=m
+CONFIG_ADAPTEC_STARFIRE_NAPI=y
+CONFIG_B44=m
+CONFIG_FORCEDETH=m
+# CONFIG_DGRS is not set
+# CONFIG_EEPRO100 is not set
+CONFIG_E100=m
+CONFIG_FEALNX=m
+CONFIG_NATSEMI=m
+CONFIG_NE2K_PCI=m
+CONFIG_8139CP=m
+CONFIG_8139TOO=m
+# CONFIG_8139TOO_PIO is not set
+# CONFIG_8139TOO_TUNE_TWISTER is not set
+CONFIG_8139TOO_8129=y
+# CONFIG_8139_OLD_RX_RESET is not set
+CONFIG_SIS900=m
+CONFIG_EPIC100=m
+CONFIG_SUNDANCE=m
+# CONFIG_SUNDANCE_MMIO is not set
+CONFIG_TLAN=m
+CONFIG_VIA_RHINE=m
+CONFIG_VIA_RHINE_MMIO=y
+CONFIG_VIA_RHINE_NAPI=y
+CONFIG_NET_POCKET=y
+CONFIG_ATP=m
+CONFIG_DE600=m
+CONFIG_DE620=m
+
+#
+# Ethernet (1000 Mbit)
+#
+CONFIG_ACENIC=m
+# CONFIG_ACENIC_OMIT_TIGON_I is not set
+CONFIG_DL2K=m
+CONFIG_E1000=m
+CONFIG_E1000_NAPI=y
+# CONFIG_E1000_DISABLE_PACKET_SPLIT is not set
+CONFIG_NS83820=m
+CONFIG_HAMACHI=m
+CONFIG_YELLOWFIN=m
+CONFIG_R8169=m
+CONFIG_R8169_NAPI=y
+CONFIG_R8169_VLAN=y
+CONFIG_SIS190=m
+CONFIG_SKGE=m
+CONFIG_SKY2=m
+# CONFIG_SK98LIN is not set
+CONFIG_VIA_VELOCITY=m
+CONFIG_TIGON3=m
+CONFIG_BNX2=m
+
+#
+# Ethernet (10000 Mbit)
+#
+CONFIG_CHELSIO_T1=m
+CONFIG_IXGB=m
+CONFIG_IXGB_NAPI=y
+CONFIG_S2IO=m
+CONFIG_S2IO_NAPI=y
+CONFIG_MYRI10GE=m
+
+#
+# Token Ring devices
+#
+CONFIG_TR=y
+CONFIG_IBMOL=m
+CONFIG_IBMLS=m
+CONFIG_3C359=m
+# CONFIG_TMS380TR is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+CONFIG_NET_RADIO=y
+CONFIG_NET_WIRELESS_RTNETLINK=y
+
+#
+# Obsolete Wireless cards support (pre-802.11)
+#
+# CONFIG_STRIP is not set
+CONFIG_PCMCIA_WAVELAN=m
+CONFIG_PCMCIA_NETWAVE=m
+
+#
+# Wireless 802.11 Frequency Hopping cards support
+#
+# CONFIG_PCMCIA_RAYCS is not set
+
+#
+# Wireless 802.11b ISA/PCI cards support
+#
+CONFIG_IPW2100=m
+CONFIG_IPW2100_MONITOR=y
+# CONFIG_IPW2100_DEBUG is not set
+CONFIG_IPW2200=m
+CONFIG_IPW2200_MONITOR=y
+CONFIG_IPW2200_RADIOTAP=y
+CONFIG_IPW2200_PROMISCUOUS=y
+CONFIG_IPW2200_QOS=y
+# CONFIG_IPW2200_DEBUG is not set
+CONFIG_AIRO=m
+CONFIG_HERMES=m
+CONFIG_PLX_HERMES=m
+CONFIG_TMD_HERMES=m
+CONFIG_NORTEL_HERMES=m
+CONFIG_PCI_HERMES=m
+CONFIG_ATMEL=m
+CONFIG_PCI_ATMEL=m
+
+#
+# Wireless 802.11b Pcmcia/Cardbus cards support
+#
+CONFIG_PCMCIA_HERMES=m
+CONFIG_PCMCIA_SPECTRUM=m
+CONFIG_AIRO_CS=m
+CONFIG_PCMCIA_ATMEL=m
+CONFIG_PCMCIA_WL3501=m
+
+#
+# Prism GT/Duette 802.11(a/b/g) PCI/Cardbus support
+#
+CONFIG_PRISM54=m
+CONFIG_USB_ZD1201=m
+CONFIG_HOSTAP=m
+CONFIG_HOSTAP_FIRMWARE=y
+CONFIG_HOSTAP_FIRMWARE_NVRAM=y
+CONFIG_HOSTAP_PLX=m
+CONFIG_HOSTAP_PCI=m
+CONFIG_HOSTAP_CS=m
+CONFIG_BCM43XX=m
+CONFIG_BCM43XX_DEBUG=y
+CONFIG_BCM43XX_DMA=y
+CONFIG_BCM43XX_PIO=y
+CONFIG_BCM43XX_DMA_AND_PIO_MODE=y
+# CONFIG_BCM43XX_DMA_MODE is not set
+# CONFIG_BCM43XX_PIO_MODE is not set
+CONFIG_ZD1211RW=m
+# CONFIG_ZD1211RW_DEBUG is not set
+CONFIG_NET_WIRELESS=y
+
+#
+# PCMCIA network device support
+#
+CONFIG_NET_PCMCIA=y
+CONFIG_PCMCIA_3C589=m
+CONFIG_PCMCIA_3C574=m
+CONFIG_PCMCIA_FMVJ18X=m
+CONFIG_PCMCIA_PCNET=m
+CONFIG_PCMCIA_NMCLAN=m
+CONFIG_PCMCIA_SMC91C92=m
+CONFIG_PCMCIA_XIRC2PS=m
+CONFIG_PCMCIA_AXNET=m
+CONFIG_PCMCIA_IBMTR=m
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+
+#
+# ATM drivers
+#
+# CONFIG_ATM_DUMMY is not set
+CONFIG_ATM_TCP=m
+CONFIG_ATM_LANAI=m
+CONFIG_ATM_ENI=m
+# CONFIG_ATM_ENI_DEBUG is not set
+# CONFIG_ATM_ENI_TUNE_BURST is not set
+CONFIG_ATM_FIRESTREAM=m
+# CONFIG_ATM_ZATM is not set
+CONFIG_ATM_NICSTAR=m
+# CONFIG_ATM_NICSTAR_USE_SUNI is not set
+# CONFIG_ATM_NICSTAR_USE_IDT77105 is not set
+CONFIG_ATM_IDT77252=m
+# CONFIG_ATM_IDT77252_DEBUG is not set
+# CONFIG_ATM_IDT77252_RCV_ALL is not set
+CONFIG_ATM_IDT77252_USE_SUNI=y
+CONFIG_ATM_AMBASSADOR=m
+# CONFIG_ATM_AMBASSADOR_DEBUG is not set
+CONFIG_ATM_HORIZON=m
+# CONFIG_ATM_HORIZON_DEBUG is not set
+# CONFIG_ATM_IA is not set
+CONFIG_ATM_FORE200E_MAYBE=m
+# CONFIG_ATM_FORE200E_PCA is not set
+CONFIG_ATM_HE=m
+# CONFIG_ATM_HE_USE_SUNI is not set
+CONFIG_FDDI=y
+# CONFIG_DEFXX is not set
+CONFIG_SKFP=m
+# CONFIG_HIPPI is not set
+CONFIG_PLIP=m
+CONFIG_PPP=m
+CONFIG_PPP_MULTILINK=y
+CONFIG_PPP_FILTER=y
+CONFIG_PPP_ASYNC=m
+CONFIG_PPP_SYNC_TTY=m
+CONFIG_PPP_DEFLATE=m
+# CONFIG_PPP_BSDCOMP is not set
+CONFIG_PPP_MPPE=m
+CONFIG_PPPOE=m
+CONFIG_PPPOATM=m
+CONFIG_SLIP=m
+CONFIG_SLIP_COMPRESSED=y
+CONFIG_SLIP_SMART=y
+# CONFIG_SLIP_MODE_SLIP6 is not set
+CONFIG_NET_FC=y
+# CONFIG_SHAPER is not set
+CONFIG_NETCONSOLE=m
+CONFIG_NETPOLL=y
+# CONFIG_NETPOLL_RX is not set
+CONFIG_NETPOLL_TRAP=y
+CONFIG_NET_POLL_CONTROLLER=y
+
+#
+# ISDN subsystem
+#
+CONFIG_ISDN=m
+
+#
+# Old ISDN4Linux
+#
+CONFIG_ISDN_I4L=m
+CONFIG_ISDN_PPP=y
+CONFIG_ISDN_PPP_VJ=y
+CONFIG_ISDN_MPP=y
+CONFIG_IPPP_FILTER=y
+# CONFIG_ISDN_PPP_BSDCOMP is not set
+CONFIG_ISDN_AUDIO=y
+CONFIG_ISDN_TTY_FAX=y
+
+#
+# ISDN feature submodules
+#
+CONFIG_ISDN_DIVERSION=m
+
+#
+# ISDN4Linux hardware drivers
+#
+
+#
+# Passive cards
+#
+CONFIG_ISDN_DRV_HISAX=m
+
+#
+# D-channel protocol features
+#
+CONFIG_HISAX_EURO=y
+CONFIG_DE_AOC=y
+CONFIG_HISAX_NO_SENDCOMPLETE=y
+CONFIG_HISAX_NO_LLC=y
+CONFIG_HISAX_NO_KEYPAD=y
+CONFIG_HISAX_1TR6=y
+CONFIG_HISAX_NI1=y
+CONFIG_HISAX_MAX_CARDS=8
+
+#
+# HiSax supported cards
+#
+CONFIG_HISAX_16_3=y
+CONFIG_HISAX_TELESPCI=y
+CONFIG_HISAX_S0BOX=y
+CONFIG_HISAX_FRITZPCI=y
+CONFIG_HISAX_AVM_A1_PCMCIA=y
+CONFIG_HISAX_ELSA=y
+CONFIG_HISAX_DIEHLDIVA=y
+CONFIG_HISAX_SEDLBAUER=y
+CONFIG_HISAX_NETJET=y
+CONFIG_HISAX_NETJET_U=y
+CONFIG_HISAX_NICCY=y
+CONFIG_HISAX_BKM_A4T=y
+CONFIG_HISAX_SCT_QUADRO=y
+CONFIG_HISAX_GAZEL=y
+CONFIG_HISAX_HFC_PCI=y
+CONFIG_HISAX_W6692=y
+CONFIG_HISAX_HFC_SX=y
+CONFIG_HISAX_ENTERNOW_PCI=y
+# CONFIG_HISAX_DEBUG is not set
+
+#
+# HiSax PCMCIA card service modules
+#
+CONFIG_HISAX_SEDLBAUER_CS=m
+CONFIG_HISAX_ELSA_CS=m
+CONFIG_HISAX_AVM_A1_CS=m
+CONFIG_HISAX_TELES_CS=m
+
+#
+# HiSax sub driver modules
+#
+CONFIG_HISAX_ST5481=m
+# CONFIG_HISAX_HFCUSB is not set
+CONFIG_HISAX_HFC4S8S=m
+CONFIG_HISAX_FRITZ_PCIPNP=m
+CONFIG_HISAX_HDLC=y
+
+#
+# Active cards
+#
+
+#
+# Siemens Gigaset
+#
+CONFIG_ISDN_DRV_GIGASET=m
+CONFIG_GIGASET_BASE=m
+CONFIG_GIGASET_M105=m
+# CONFIG_GIGASET_DEBUG is not set
+# CONFIG_GIGASET_UNDOCREQ is not set
+
+#
+# CAPI subsystem
+#
+CONFIG_ISDN_CAPI=m
+CONFIG_ISDN_DRV_AVMB1_VERBOSE_REASON=y
+CONFIG_ISDN_CAPI_MIDDLEWARE=y
+CONFIG_ISDN_CAPI_CAPI20=m
+CONFIG_ISDN_CAPI_CAPIFS_BOOL=y
+CONFIG_ISDN_CAPI_CAPIFS=m
+CONFIG_ISDN_CAPI_CAPIDRV=m
+
+#
+# CAPI hardware drivers
+#
+
+#
+# Active AVM cards
+#
+CONFIG_CAPI_AVM=y
+CONFIG_ISDN_DRV_AVMB1_B1PCI=m
+CONFIG_ISDN_DRV_AVMB1_B1PCIV4=y
+CONFIG_ISDN_DRV_AVMB1_B1PCMCIA=m
+CONFIG_ISDN_DRV_AVMB1_AVM_CS=m
+CONFIG_ISDN_DRV_AVMB1_T1PCI=m
+CONFIG_ISDN_DRV_AVMB1_C4=m
+
+#
+# Active Eicon DIVA Server cards
+#
+CONFIG_CAPI_EICON=y
+CONFIG_ISDN_DIVAS=m
+CONFIG_ISDN_DIVAS_BRIPCI=y
+CONFIG_ISDN_DIVAS_PRIPCI=y
+CONFIG_ISDN_DIVAS_DIVACAPI=m
+CONFIG_ISDN_DIVAS_USERIDI=m
+CONFIG_ISDN_DIVAS_MAINT=m
+
+#
+# Telephony Support
+#
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+
+#
+# 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=m
+# CONFIG_INPUT_TSDEV is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+CONFIG_KEYBOARD_ATKBD=y
+# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_KEYBOARD_LKKBD is not set
+# CONFIG_KEYBOARD_XTKBD is not set
+# CONFIG_KEYBOARD_NEWTON is not set
+CONFIG_INPUT_MOUSE=y
+CONFIG_MOUSE_PS2=y
+CONFIG_MOUSE_SERIAL=m
+CONFIG_MOUSE_VSXXXAA=m
+CONFIG_INPUT_JOYSTICK=y
+CONFIG_JOYSTICK_ANALOG=m
+CONFIG_JOYSTICK_A3D=m
+CONFIG_JOYSTICK_ADI=m
+CONFIG_JOYSTICK_COBRA=m
+CONFIG_JOYSTICK_GF2K=m
+CONFIG_JOYSTICK_GRIP=m
+CONFIG_JOYSTICK_GRIP_MP=m
+CONFIG_JOYSTICK_GUILLEMOT=m
+CONFIG_JOYSTICK_INTERACT=m
+CONFIG_JOYSTICK_SIDEWINDER=m
+CONFIG_JOYSTICK_TMDC=m
+CONFIG_JOYSTICK_IFORCE=m
+CONFIG_JOYSTICK_IFORCE_USB=y
+CONFIG_JOYSTICK_IFORCE_232=y
+CONFIG_JOYSTICK_WARRIOR=m
+CONFIG_JOYSTICK_MAGELLAN=m
+CONFIG_JOYSTICK_SPACEORB=m
+CONFIG_JOYSTICK_SPACEBALL=m
+CONFIG_JOYSTICK_STINGER=m
+CONFIG_JOYSTICK_TWIDJOY=m
+CONFIG_JOYSTICK_DB9=m
+CONFIG_JOYSTICK_GAMECON=m
+CONFIG_JOYSTICK_TURBOGRAFX=m
+CONFIG_JOYSTICK_JOYDUMP=m
+CONFIG_INPUT_TOUCHSCREEN=y
+CONFIG_TOUCHSCREEN_GUNZE=m
+CONFIG_TOUCHSCREEN_ELO=m
+CONFIG_TOUCHSCREEN_MTOUCH=m
+CONFIG_TOUCHSCREEN_MK712=m
+CONFIG_INPUT_MISC=y
+CONFIG_INPUT_PCSPKR=m
+CONFIG_INPUT_WISTRON_BTNS=m
+CONFIG_INPUT_UINPUT=m
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+CONFIG_SERIO_I8042=y
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_CT82C710 is not set
+# CONFIG_SERIO_PARKBD is not set
+# CONFIG_SERIO_PCIPS2 is not set
+CONFIG_SERIO_LIBPS2=y
+CONFIG_SERIO_RAW=m
+CONFIG_GAMEPORT=m
+CONFIG_GAMEPORT_NS558=m
+CONFIG_GAMEPORT_L4=m
+CONFIG_GAMEPORT_EMU10K1=m
+CONFIG_GAMEPORT_FM801=m
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+CONFIG_VT_HW_CONSOLE_BINDING=y
+CONFIG_SERIAL_NONSTANDARD=y
+# CONFIG_COMPUTONE is not set
+# CONFIG_ROCKETPORT is not set
+CONFIG_CYCLADES=m
+# CONFIG_CYZ_INTR is not set
+# CONFIG_DIGIEPCA is not set
+# CONFIG_MOXA_INTELLIO is not set
+# CONFIG_MOXA_SMARTIO is not set
+# CONFIG_ISI is not set
+CONFIG_SYNCLINK=m
+CONFIG_SYNCLINKMP=m
+CONFIG_SYNCLINK_GT=m
+CONFIG_N_HDLC=m
+# CONFIG_SPECIALIX is not set
+# CONFIG_SX is not set
+# CONFIG_RIO is not set
+# CONFIG_STALDRV is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=m
+CONFIG_SERIAL_8250_PCI=m
+CONFIG_SERIAL_8250_PNP=m
+CONFIG_SERIAL_8250_CS=m
+CONFIG_SERIAL_8250_NR_UARTS=32
+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=y
+CONFIG_SERIAL_8250_RSA=y
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_CORE=m
+CONFIG_SERIAL_JSM=m
+CONFIG_UNIX98_PTYS=y
+# CONFIG_LEGACY_PTYS is not set
+CONFIG_CRASH=m
+CONFIG_PRINTER=m
+CONFIG_LP_CONSOLE=y
+CONFIG_PPDEV=m
+CONFIG_TIPAR=m
+
+#
+# IPMI
+#
+CONFIG_IPMI_HANDLER=m
+# CONFIG_IPMI_PANIC_EVENT is not set
+CONFIG_IPMI_DEVICE_INTERFACE=m
+CONFIG_IPMI_SI=m
+CONFIG_IPMI_WATCHDOG=m
+CONFIG_IPMI_POWEROFF=m
+
+#
+# Watchdog Cards
+#
+CONFIG_WATCHDOG=y
+# CONFIG_WATCHDOG_NOWAYOUT is not set
+
+#
+# Watchdog Device Drivers
+#
+CONFIG_SOFT_WATCHDOG=m
+# CONFIG_ACQUIRE_WDT is not set
+# CONFIG_ADVANTECH_WDT is not set
+CONFIG_ALIM1535_WDT=m
+CONFIG_ALIM7101_WDT=m
+# CONFIG_SC520_WDT is not set
+# CONFIG_EUROTECH_WDT is not set
+# CONFIG_IB700_WDT is not set
+CONFIG_IBMASR=m
+# CONFIG_WAFER_WDT is not set
+CONFIG_I6300ESB_WDT=m
+CONFIG_I8XX_TCO=m
+# CONFIG_SC1200_WDT is not set
+# CONFIG_60XX_WDT is not set
+# CONFIG_SBC8360_WDT is not set
+# CONFIG_CPU5_WDT is not set
+CONFIG_W83627HF_WDT=m
+CONFIG_W83877F_WDT=m
+CONFIG_W83977F_WDT=m
+CONFIG_MACHZ_WDT=m
+# CONFIG_SBC_EPX_C3_WATCHDOG is not set
+
+#
+# PCI-based Watchdog Cards
+#
+CONFIG_PCIPCWATCHDOG=m
+CONFIG_WDTPCI=m
+CONFIG_WDT_501_PCI=y
+
+#
+# USB-based Watchdog Cards
+#
+CONFIG_USBPCWATCHDOG=m
+CONFIG_HW_RANDOM=y
+CONFIG_HW_RANDOM_INTEL=m
+CONFIG_HW_RANDOM_AMD=m
+CONFIG_HW_RANDOM_GEODE=m
+CONFIG_HW_RANDOM_VIA=m
+CONFIG_NVRAM=y
+CONFIG_RTC=y
+CONFIG_DTLK=m
+CONFIG_R3964=m
+# CONFIG_APPLICOM is not set
+CONFIG_SONYPI=m
+
+#
+# Ftape, the floppy tape device driver
+#
+CONFIG_AGP=y
+CONFIG_AGP_ALI=y
+CONFIG_AGP_ATI=y
+CONFIG_AGP_AMD=y
+CONFIG_AGP_AMD64=y
+CONFIG_AGP_INTEL=y
+CONFIG_AGP_NVIDIA=y
+CONFIG_AGP_SIS=y
+CONFIG_AGP_SWORKS=y
+CONFIG_AGP_VIA=y
+CONFIG_AGP_EFFICEON=y
+CONFIG_DRM=m
+CONFIG_DRM_TDFX=m
+CONFIG_DRM_R128=m
+CONFIG_DRM_RADEON=m
+CONFIG_DRM_I810=m
+CONFIG_DRM_I830=m
+CONFIG_DRM_I915=m
+CONFIG_DRM_MGA=m
+CONFIG_DRM_SIS=m
+CONFIG_DRM_VIA=m
+CONFIG_DRM_SAVAGE=m
+
+#
+# PCMCIA character devices
+#
+# CONFIG_SYNCLINK_CS is not set
+CONFIG_CARDMAN_4000=m
+CONFIG_CARDMAN_4040=m
+CONFIG_MWAVE=m
+CONFIG_PC8736x_GPIO=m
+CONFIG_NSC_GPIO=m
+CONFIG_CS5535_GPIO=m
+# CONFIG_RAW_DRIVER is not set
+CONFIG_HPET=y
+# CONFIG_HPET_RTC_IRQ is not set
+# CONFIG_HPET_MMAP is not set
+CONFIG_HANGCHECK_TIMER=m
+
+#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+# CONFIG_TELCLOCK is not set
+
+#
+# I2C support
+#
+CONFIG_I2C=m
+CONFIG_I2C_CHARDEV=m
+
+#
+# I2C Algorithms
+#
+CONFIG_I2C_ALGOBIT=m
+CONFIG_I2C_ALGOPCF=m
+CONFIG_I2C_ALGOPCA=m
+
+#
+# I2C Hardware Bus support
+#
+CONFIG_I2C_ALI1535=m
+CONFIG_I2C_ALI1563=m
+CONFIG_I2C_ALI15X3=m
+CONFIG_I2C_AMD756=m
+CONFIG_I2C_AMD756_S4882=m
+CONFIG_I2C_AMD8111=m
+CONFIG_I2C_I801=m
+CONFIG_I2C_I810=m
+CONFIG_I2C_PIIX4=m
+CONFIG_I2C_ISA=m
+CONFIG_I2C_NFORCE2=m
+# CONFIG_I2C_OCORES is not set
+CONFIG_I2C_PARPORT=m
+CONFIG_I2C_PARPORT_LIGHT=m
+CONFIG_I2C_PROSAVAGE=m
+CONFIG_I2C_SAVAGE4=m
+# CONFIG_SCx200_ACB is not set
+CONFIG_I2C_SIS5595=m
+CONFIG_I2C_SIS630=m
+CONFIG_I2C_SIS96X=m
+CONFIG_I2C_STUB=m
+CONFIG_I2C_VIA=m
+CONFIG_I2C_VIAPRO=m
+CONFIG_I2C_VOODOO3=m
+CONFIG_I2C_PCA_ISA=m
+
+#
+# Miscellaneous I2C Chip support
+#
+CONFIG_SENSORS_DS1337=m
+CONFIG_SENSORS_DS1374=m
+CONFIG_SENSORS_EEPROM=m
+CONFIG_SENSORS_PCF8574=m
+CONFIG_SENSORS_PCA9539=m
+CONFIG_SENSORS_PCF8591=m
+CONFIG_SENSORS_MAX6875=m
+# 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 is not set
+# CONFIG_SPI_MASTER is not set
+
+#
+# Dallas's 1-wire bus
+#
+CONFIG_W1=m
+CONFIG_W1_CON=y
+
+#
+# 1-wire Bus Masters
+#
+CONFIG_W1_MASTER_MATROX=m
+CONFIG_W1_MASTER_DS2490=m
+CONFIG_W1_MASTER_DS2482=m
+
+#
+# 1-wire Slaves
+#
+CONFIG_W1_SLAVE_THERM=m
+CONFIG_W1_SLAVE_SMEM=m
+CONFIG_W1_SLAVE_DS2433=m
+CONFIG_W1_SLAVE_DS2433_CRC=y
+
+#
+# Hardware Monitoring support
+#
+CONFIG_HWMON=m
+CONFIG_HWMON_VID=m
+CONFIG_SENSORS_ABITUGURU=m
+CONFIG_SENSORS_ADM1021=m
+CONFIG_SENSORS_ADM1025=m
+CONFIG_SENSORS_ADM1026=m
+CONFIG_SENSORS_ADM1031=m
+CONFIG_SENSORS_ADM9240=m
+CONFIG_SENSORS_ASB100=m
+CONFIG_SENSORS_ATXP1=m
+CONFIG_SENSORS_DS1621=m
+CONFIG_SENSORS_F71805F=m
+CONFIG_SENSORS_FSCHER=m
+CONFIG_SENSORS_FSCPOS=m
+CONFIG_SENSORS_GL518SM=m
+CONFIG_SENSORS_GL520SM=m
+CONFIG_SENSORS_IT87=m
+CONFIG_SENSORS_LM63=m
+CONFIG_SENSORS_LM75=m
+CONFIG_SENSORS_LM77=m
+CONFIG_SENSORS_LM78=m
+CONFIG_SENSORS_LM80=m
+CONFIG_SENSORS_LM83=m
+CONFIG_SENSORS_LM85=m
+CONFIG_SENSORS_LM87=m
+CONFIG_SENSORS_LM90=m
+CONFIG_SENSORS_LM92=m
+CONFIG_SENSORS_MAX1619=m
+CONFIG_SENSORS_PC87360=m
+CONFIG_SENSORS_SIS5595=m
+CONFIG_SENSORS_SMSC47M1=m
+CONFIG_SENSORS_SMSC47M192=m
+CONFIG_SENSORS_SMSC47B397=m
+CONFIG_SENSORS_VIA686A=m
+CONFIG_SENSORS_VT8231=m
+CONFIG_SENSORS_W83781D=m
+CONFIG_SENSORS_W83791D=m
+CONFIG_SENSORS_W83792D=m
+CONFIG_SENSORS_W83L785TS=m
+CONFIG_SENSORS_W83627HF=m
+CONFIG_SENSORS_W83627EHF=m
+CONFIG_SENSORS_HDAPS=m
+# CONFIG_HWMON_DEBUG_CHIP is not set
+
+#
+# Misc devices
+#
+CONFIG_IBM_ASM=m
+
+#
+# Multimedia devices
+#
+CONFIG_VIDEO_DEV=m
+CONFIG_VIDEO_V4L1=y
+CONFIG_VIDEO_V4L1_COMPAT=y
+CONFIG_VIDEO_V4L2=y
+
+#
+# Video Capture Adapters
+#
+
+#
+# Video Capture Adapters
+#
+# CONFIG_VIDEO_ADV_DEBUG is not set
+# CONFIG_VIDEO_VIVI is not set
+CONFIG_VIDEO_BT848=m
+CONFIG_VIDEO_BT848_DVB=y
+CONFIG_VIDEO_SAA6588=m
+CONFIG_VIDEO_BWQCAM=m
+CONFIG_VIDEO_CQCAM=m
+CONFIG_VIDEO_W9966=m
+CONFIG_VIDEO_CPIA=m
+CONFIG_VIDEO_CPIA_PP=m
+CONFIG_VIDEO_CPIA_USB=m
+CONFIG_VIDEO_CPIA2=m
+CONFIG_VIDEO_SAA5246A=m
+CONFIG_VIDEO_SAA5249=m
+CONFIG_TUNER_3036=m
+CONFIG_VIDEO_STRADIS=m
+CONFIG_VIDEO_ZORAN=m
+CONFIG_VIDEO_ZORAN_BUZ=m
+CONFIG_VIDEO_ZORAN_DC10=m
+CONFIG_VIDEO_ZORAN_DC30=m
+CONFIG_VIDEO_ZORAN_LML33=m
+CONFIG_VIDEO_ZORAN_LML33R10=m
+CONFIG_VIDEO_ZORAN_AVS6EYES=m
+CONFIG_VIDEO_MEYE=m
+CONFIG_VIDEO_SAA7134=m
+CONFIG_VIDEO_SAA7134_ALSA=m
+CONFIG_VIDEO_SAA7134_DVB=m
+CONFIG_VIDEO_SAA7134_DVB_ALL_FRONTENDS=y
+CONFIG_VIDEO_MXB=m
+CONFIG_VIDEO_DPC=m
+CONFIG_VIDEO_HEXIUM_ORION=m
+CONFIG_VIDEO_HEXIUM_GEMINI=m
+CONFIG_VIDEO_CX88_VP3054=m
+CONFIG_VIDEO_CX88=m
+CONFIG_VIDEO_CX88_ALSA=m
+CONFIG_VIDEO_CX88_BLACKBIRD=m
+CONFIG_VIDEO_CX88_DVB=m
+CONFIG_VIDEO_CX88_DVB_ALL_FRONTENDS=y
+
+#
+# Encoders and Decoders
+#
+CONFIG_VIDEO_MSP3400=m
+CONFIG_VIDEO_CS53L32A=m
+CONFIG_VIDEO_TLV320AIC23B=m
+CONFIG_VIDEO_WM8775=m
+CONFIG_VIDEO_WM8739=m
+CONFIG_VIDEO_CX2341X=m
+CONFIG_VIDEO_CX25840=m
+CONFIG_VIDEO_SAA711X=m
+CONFIG_VIDEO_SAA7127=m
+CONFIG_VIDEO_UPD64031A=m
+CONFIG_VIDEO_UPD64083=m
+
+#
+# V4L USB devices
+#
+CONFIG_VIDEO_PVRUSB2=m
+CONFIG_VIDEO_PVRUSB2_24XXX=y
+CONFIG_VIDEO_PVRUSB2_SYSFS=y
+# CONFIG_VIDEO_PVRUSB2_DEBUGIFC is not set
+CONFIG_VIDEO_EM28XX=m
+CONFIG_VIDEO_USBVIDEO=m
+CONFIG_USB_VICAM=m
+CONFIG_USB_IBMCAM=m
+CONFIG_USB_KONICAWC=m
+CONFIG_USB_QUICKCAM_MESSENGER=m
+CONFIG_USB_ET61X251=m
+CONFIG_VIDEO_OVCAMCHIP=m
+CONFIG_USB_W9968CF=m
+CONFIG_USB_OV511=m
+CONFIG_USB_SE401=m
+CONFIG_USB_SN9C102=m
+CONFIG_USB_STV680=m
+CONFIG_USB_ZC0301=m
+CONFIG_USB_PWC=m
+# CONFIG_USB_PWC_DEBUG is not set
+
+#
+# Radio Adapters
+#
+CONFIG_RADIO_GEMTEK_PCI=m
+CONFIG_RADIO_MAXIRADIO=m
+CONFIG_RADIO_MAESTRO=m
+CONFIG_USB_DSBR=m
+
+#
+# Digital Video Broadcasting Devices
+#
+CONFIG_DVB=y
+CONFIG_DVB_CORE=m
+
+#
+# Supported SAA7146 based PCI Adapters
+#
+CONFIG_DVB_AV7110=m
+CONFIG_DVB_AV7110_OSD=y
+CONFIG_DVB_BUDGET=m
+CONFIG_DVB_BUDGET_CI=m
+CONFIG_DVB_BUDGET_AV=m
+CONFIG_DVB_BUDGET_PATCH=m
+
+#
+# Supported USB Adapters
+#
+CONFIG_DVB_USB=m
+# CONFIG_DVB_USB_DEBUG is not set
+CONFIG_DVB_USB_A800=m
+CONFIG_DVB_USB_DIBUSB_MB=m
+# CONFIG_DVB_USB_DIBUSB_MB_FAULTY is not set
+CONFIG_DVB_USB_DIBUSB_MC=m
+CONFIG_DVB_USB_UMT_010=m
+CONFIG_DVB_USB_CXUSB=m
+CONFIG_DVB_USB_DIGITV=m
+CONFIG_DVB_USB_VP7045=m
+CONFIG_DVB_USB_VP702X=m
+CONFIG_DVB_USB_GP8PSK=m
+CONFIG_DVB_USB_NOVA_T_USB2=m
+CONFIG_DVB_USB_DTT200U=m
+CONFIG_DVB_TTUSB_BUDGET=m
+CONFIG_DVB_TTUSB_DEC=m
+CONFIG_DVB_CINERGYT2=m
+CONFIG_DVB_CINERGYT2_TUNING=y
+CONFIG_DVB_CINERGYT2_STREAM_URB_COUNT=32
+CONFIG_DVB_CINERGYT2_STREAM_BUF_SIZE=512
+CONFIG_DVB_CINERGYT2_QUERY_INTERVAL=250
+CONFIG_DVB_CINERGYT2_ENABLE_RC_INPUT_DEVICE=y
+CONFIG_DVB_CINERGYT2_RC_QUERY_INTERVAL=100
+
+#
+# Supported FlexCopII (B2C2) Adapters
+#
+CONFIG_DVB_B2C2_FLEXCOP=m
+CONFIG_DVB_B2C2_FLEXCOP_PCI=m
+CONFIG_DVB_B2C2_FLEXCOP_USB=m
+# CONFIG_DVB_B2C2_FLEXCOP_DEBUG is not set
+
+#
+# Supported BT878 Adapters
+#
+CONFIG_DVB_BT8XX=m
+
+#
+# Supported Pluto2 Adapters
+#
+CONFIG_DVB_PLUTO2=m
+
+#
+# Supported DVB Frontends
+#
+
+#
+# Customise DVB Frontends
+#
+
+#
+# DVB-S (satellite) frontends
+#
+CONFIG_DVB_STV0299=m
+CONFIG_DVB_CX24110=m
+CONFIG_DVB_CX24123=m
+CONFIG_DVB_TDA8083=m
+CONFIG_DVB_MT312=m
+CONFIG_DVB_VES1X93=m
+CONFIG_DVB_S5H1420=m
+
+#
+# DVB-T (terrestrial) frontends
+#
+CONFIG_DVB_SP8870=m
+CONFIG_DVB_SP887X=m
+CONFIG_DVB_CX22700=m
+CONFIG_DVB_CX22702=m
+CONFIG_DVB_L64781=m
+CONFIG_DVB_TDA1004X=m
+CONFIG_DVB_NXT6000=m
+CONFIG_DVB_MT352=m
+CONFIG_DVB_ZL10353=m
+CONFIG_DVB_DIB3000MB=m
+CONFIG_DVB_DIB3000MC=m
+
+#
+# DVB-C (cable) frontends
+#
+CONFIG_DVB_VES1820=m
+CONFIG_DVB_TDA10021=m
+CONFIG_DVB_STV0297=m
+
+#
+# ATSC (North American/Korean Terrestrial/Cable DTV) frontends
+#
+CONFIG_DVB_NXT200X=m
+CONFIG_DVB_OR51211=m
+CONFIG_DVB_OR51132=m
+CONFIG_DVB_BCM3510=m
+CONFIG_DVB_LGDT330X=m
+
+#
+# Miscellaneous devices
+#
+CONFIG_DVB_PLL=m
+CONFIG_DVB_LNBP21=m
+CONFIG_DVB_ISL6421=m
+CONFIG_VIDEO_SAA7146=m
+CONFIG_VIDEO_SAA7146_VV=m
+CONFIG_VIDEO_VIDEOBUF=m
+CONFIG_VIDEO_TUNER=m
+CONFIG_VIDEO_BUF=m
+CONFIG_VIDEO_BUF_DVB=m
+CONFIG_VIDEO_BTCX=m
+CONFIG_VIDEO_IR=m
+CONFIG_VIDEO_TVEEPROM=m
+CONFIG_USB_DABUSB=m
+
+#
+# Graphics support
+#
+# CONFIG_FIRMWARE_EDID is not set
+CONFIG_FB=y
+CONFIG_FB_CFB_FILLRECT=y
+CONFIG_FB_CFB_COPYAREA=y
+CONFIG_FB_CFB_IMAGEBLIT=y
+# CONFIG_FB_MACMODES is not set
+# CONFIG_FB_BACKLIGHT is not set
+CONFIG_FB_MODE_HELPERS=y
+CONFIG_FB_TILEBLITTING=y
+CONFIG_FB_CIRRUS=m
+# CONFIG_FB_PM2 is not set
+# CONFIG_FB_CYBER2000 is not set
+# CONFIG_FB_ARC is not set
+# CONFIG_FB_ASILIANT is not set
+# CONFIG_FB_IMSTT is not set
+CONFIG_FB_VGA16=m
+CONFIG_FB_VESA=y
+# CONFIG_FB_HGA is not set
+# CONFIG_FB_S1D13XXX is not set
+CONFIG_FB_NVIDIA=m
+CONFIG_FB_NVIDIA_I2C=y
+CONFIG_FB_RIVA=m
+# CONFIG_FB_RIVA_I2C is not set
+# CONFIG_FB_RIVA_DEBUG is not set
+CONFIG_FB_I810=m
+CONFIG_FB_I810_GTF=y
+CONFIG_FB_I810_I2C=y
+CONFIG_FB_INTEL=m
+# CONFIG_FB_INTEL_DEBUG is not set
+CONFIG_FB_MATROX=m
+CONFIG_FB_MATROX_MILLENIUM=y
+CONFIG_FB_MATROX_MYSTIQUE=y
+CONFIG_FB_MATROX_G=y
+CONFIG_FB_MATROX_I2C=m
+CONFIG_FB_MATROX_MAVEN=m
+CONFIG_FB_MATROX_MULTIHEAD=y
+CONFIG_FB_RADEON=m
+CONFIG_FB_RADEON_I2C=y
+# CONFIG_FB_RADEON_DEBUG is not set
+CONFIG_FB_ATY128=m
+CONFIG_FB_ATY=m
+CONFIG_FB_ATY_CT=y
+CONFIG_FB_ATY_GENERIC_LCD=y
+CONFIG_FB_ATY_GX=y
+CONFIG_FB_SAVAGE=m
+CONFIG_FB_SAVAGE_I2C=y
+CONFIG_FB_SAVAGE_ACCEL=y
+# CONFIG_FB_SIS is not set
+CONFIG_FB_NEOMAGIC=m
+CONFIG_FB_KYRO=m
+CONFIG_FB_3DFX=m
+CONFIG_FB_3DFX_ACCEL=y
+CONFIG_FB_VOODOO1=m
+CONFIG_FB_CYBLA=m
+CONFIG_FB_TRIDENT=m
+CONFIG_FB_TRIDENT_ACCEL=y
+# CONFIG_FB_GEODE is not set
+# CONFIG_FB_VIRTUAL is not set
+
+#
+# Console display driver support
+#
+CONFIG_VGA_CONSOLE=y
+CONFIG_VGACON_SOFT_SCROLLBACK=y
+CONFIG_VGACON_SOFT_SCROLLBACK_SIZE=64
+CONFIG_VIDEO_SELECT=y
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y
+# CONFIG_FONTS is not set
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
+
+#
+# Logo configuration
+#
+CONFIG_LOGO=y
+# CONFIG_LOGO_LINUX_MONO is not set
+# CONFIG_LOGO_LINUX_VGA16 is not set
+CONFIG_LOGO_LINUX_CLUT224=y
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+CONFIG_BACKLIGHT_CLASS_DEVICE=m
+CONFIG_BACKLIGHT_DEVICE=y
+CONFIG_LCD_CLASS_DEVICE=m
+CONFIG_LCD_DEVICE=y
+
+#
+# Sound
+#
+CONFIG_SOUND=m
+
+#
+# Advanced Linux Sound Architecture
+#
+CONFIG_SND=m
+CONFIG_SND_TIMER=m
+CONFIG_SND_PCM=m
+CONFIG_SND_HWDEP=m
+CONFIG_SND_RAWMIDI=m
+CONFIG_SND_SEQUENCER=m
+CONFIG_SND_SEQ_DUMMY=m
+CONFIG_SND_OSSEMUL=y
+CONFIG_SND_MIXER_OSS=m
+CONFIG_SND_PCM_OSS=m
+CONFIG_SND_PCM_OSS_PLUGINS=y
+CONFIG_SND_SEQUENCER_OSS=y
+CONFIG_SND_RTCTIMER=m
+CONFIG_SND_SEQ_RTCTIMER_DEFAULT=y
+CONFIG_SND_DYNAMIC_MINORS=y
+# CONFIG_SND_SUPPORT_OLD_API is not set
+CONFIG_SND_VERBOSE_PROCFS=y
+# CONFIG_SND_VERBOSE_PRINTK is not set
+# CONFIG_SND_DEBUG is not set
+
+#
+# Generic devices
+#
+CONFIG_SND_MPU401_UART=m
+CONFIG_SND_OPL3_LIB=m
+CONFIG_SND_VX_LIB=m
+CONFIG_SND_AC97_CODEC=m
+CONFIG_SND_AC97_BUS=m
+CONFIG_SND_DUMMY=m
+CONFIG_SND_VIRMIDI=m
+CONFIG_SND_MTPAV=m
+# CONFIG_SND_SERIAL_U16550 is not set
+CONFIG_SND_MPU401=m
+
+#
+# PCI devices
+#
+CONFIG_SND_AD1889=m
+CONFIG_SND_ALS300=m
+CONFIG_SND_ALS4000=m
+CONFIG_SND_ALI5451=m
+CONFIG_SND_ATIIXP=m
+CONFIG_SND_ATIIXP_MODEM=m
+CONFIG_SND_AU8810=m
+CONFIG_SND_AU8820=m
+CONFIG_SND_AU8830=m
+CONFIG_SND_AZT3328=m
+CONFIG_SND_BT87X=m
+# CONFIG_SND_BT87X_OVERCLOCK is not set
+CONFIG_SND_CA0106=m
+CONFIG_SND_CMIPCI=m
+CONFIG_SND_CS4281=m
+CONFIG_SND_CS46XX=m
+CONFIG_SND_CS46XX_NEW_DSP=y
+CONFIG_SND_CS5535AUDIO=m
+CONFIG_SND_DARLA20=m
+CONFIG_SND_GINA20=m
+CONFIG_SND_LAYLA20=m
+CONFIG_SND_DARLA24=m
+CONFIG_SND_GINA24=m
+CONFIG_SND_LAYLA24=m
+CONFIG_SND_MONA=m
+CONFIG_SND_MIA=m
+CONFIG_SND_ECHO3G=m
+CONFIG_SND_INDIGO=m
+CONFIG_SND_INDIGOIO=m
+CONFIG_SND_INDIGODJ=m
+CONFIG_SND_EMU10K1=m
+CONFIG_SND_EMU10K1X=m
+CONFIG_SND_ENS1370=m
+CONFIG_SND_ENS1371=m
+CONFIG_SND_ES1938=m
+CONFIG_SND_ES1968=m
+CONFIG_SND_FM801=m
+CONFIG_SND_FM801_TEA575X_BOOL=y
+CONFIG_SND_FM801_TEA575X=m
+CONFIG_SND_HDA_INTEL=m
+CONFIG_SND_HDSP=m
+CONFIG_SND_HDSPM=m
+CONFIG_SND_ICE1712=m
+CONFIG_SND_ICE1724=m
+CONFIG_SND_INTEL8X0=m
+CONFIG_SND_INTEL8X0M=m
+CONFIG_SND_KORG1212=m
+CONFIG_SND_MAESTRO3=m
+CONFIG_SND_MIXART=m
+CONFIG_SND_NM256=m
+CONFIG_SND_PCXHR=m
+CONFIG_SND_RIPTIDE=m
+CONFIG_SND_RME32=m
+CONFIG_SND_RME96=m
+CONFIG_SND_RME9652=m
+CONFIG_SND_SONICVIBES=m
+CONFIG_SND_TRIDENT=m
+CONFIG_SND_VIA82XX=m
+CONFIG_SND_VIA82XX_MODEM=m
+CONFIG_SND_VX222=m
+CONFIG_SND_YMFPCI=m
+
+#
+# USB devices
+#
+CONFIG_SND_USB_AUDIO=m
+CONFIG_SND_USB_USX2Y=m
+
+#
+# PCMCIA devices
+#
+# CONFIG_SND_VXPOCKET is not set
+# CONFIG_SND_PDAUDIOCF is not set
+
+#
+# Open Sound System
+#
+# CONFIG_SOUND_PRIME is not set
+
+#
+# USB support
+#
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB_ARCH_HAS_EHCI=y
+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_SUSPEND is not set
+# CONFIG_USB_OTG is not set
+
+#
+# USB Host Controller Drivers
+#
+CONFIG_USB_EHCI_HCD=m
+CONFIG_USB_EHCI_SPLIT_ISO=y
+CONFIG_USB_EHCI_ROOT_HUB_TT=y
+CONFIG_USB_EHCI_TT_NEWSCHED=y
+CONFIG_USB_ISP116X_HCD=m
+CONFIG_USB_OHCI_HCD=m
+# CONFIG_USB_OHCI_BIG_ENDIAN is not set
+CONFIG_USB_OHCI_LITTLE_ENDIAN=y
+CONFIG_USB_UHCI_HCD=m
+CONFIG_USB_SL811_HCD=m
+CONFIG_USB_SL811_CS=m
+
+#
+# USB Device Class drivers
+#
+CONFIG_USB_ACM=m
+CONFIG_USB_PRINTER=m
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+#
+
+#
+# may also be needed; see USB_STORAGE Help for more information
+#
+CONFIG_USB_STORAGE=m
+# CONFIG_USB_STORAGE_DEBUG is not set
+CONFIG_USB_STORAGE_DATAFAB=y
+CONFIG_USB_STORAGE_FREECOM=y
+CONFIG_USB_STORAGE_ISD200=y
+CONFIG_USB_STORAGE_DPCM=y
+CONFIG_USB_STORAGE_USBAT=y
+CONFIG_USB_STORAGE_SDDR09=y
+CONFIG_USB_STORAGE_SDDR55=y
+CONFIG_USB_STORAGE_JUMPSHOT=y
+CONFIG_USB_STORAGE_ALAUDA=y
+CONFIG_USB_LIBUSUAL=y
+
+#
+# USB Input Devices
+#
+CONFIG_USB_HID=y
+CONFIG_USB_HIDINPUT=y
+CONFIG_USB_HIDINPUT_POWERBOOK=y
+CONFIG_HID_FF=y
+CONFIG_HID_PID=y
+CONFIG_LOGITECH_FF=y
+CONFIG_THRUSTMASTER_FF=y
+CONFIG_USB_HIDDEV=y
+CONFIG_USB_AIPTEK=m
+CONFIG_USB_WACOM=m
+CONFIG_USB_ACECAD=m
+CONFIG_USB_KBTAB=m
+CONFIG_USB_POWERMATE=m
+CONFIG_USB_TOUCHSCREEN=m
+CONFIG_USB_TOUCHSCREEN_EGALAX=y
+CONFIG_USB_TOUCHSCREEN_PANJIT=y
+CONFIG_USB_TOUCHSCREEN_3M=y
+CONFIG_USB_TOUCHSCREEN_ITM=y
+# CONFIG_USB_YEALINK is not set
+CONFIG_USB_XPAD=m
+CONFIG_USB_ATI_REMOTE=m
+CONFIG_USB_ATI_REMOTE2=m
+CONFIG_USB_KEYSPAN_REMOTE=m
+CONFIG_USB_APPLETOUCH=m
+
+#
+# USB Imaging devices
+#
+CONFIG_USB_MDC800=m
+CONFIG_USB_MICROTEK=m
+
+#
+# USB Network Adapters
+#
+CONFIG_USB_CATC=m
+CONFIG_USB_KAWETH=m
+CONFIG_USB_PEGASUS=m
+CONFIG_USB_RTL8150=m
+CONFIG_USB_USBNET=m
+CONFIG_USB_NET_AX8817X=m
+CONFIG_USB_NET_CDCETHER=m
+CONFIG_USB_NET_GL620A=m
+CONFIG_USB_NET_NET1080=m
+CONFIG_USB_NET_PLUSB=m
+CONFIG_USB_NET_RNDIS_HOST=m
+CONFIG_USB_NET_CDC_SUBSET=m
+CONFIG_USB_ALI_M5632=y
+CONFIG_USB_AN2720=y
+CONFIG_USB_BELKIN=y
+CONFIG_USB_ARMLINUX=y
+CONFIG_USB_EPSON2888=y
+CONFIG_USB_NET_ZAURUS=m
+CONFIG_USB_MON=y
+
+#
+# USB port drivers
+#
+CONFIG_USB_USS720=m
+
+#
+# USB Serial Converter support
+#
+CONFIG_USB_SERIAL=m
+CONFIG_USB_SERIAL_GENERIC=y
+CONFIG_USB_SERIAL_AIRPRIME=m
+CONFIG_USB_SERIAL_ARK3116=m
+CONFIG_USB_SERIAL_BELKIN=m
+CONFIG_USB_SERIAL_WHITEHEAT=m
+CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m
+CONFIG_USB_SERIAL_CP2101=m
+CONFIG_USB_SERIAL_CYPRESS_M8=m
+CONFIG_USB_SERIAL_EMPEG=m
+CONFIG_USB_SERIAL_FTDI_SIO=m
+CONFIG_USB_SERIAL_FUNSOFT=m
+CONFIG_USB_SERIAL_VISOR=m
+CONFIG_USB_SERIAL_IPAQ=m
+CONFIG_USB_SERIAL_IR=m
+CONFIG_USB_SERIAL_EDGEPORT=m
+CONFIG_USB_SERIAL_EDGEPORT_TI=m
+CONFIG_USB_SERIAL_GARMIN=m
+CONFIG_USB_SERIAL_IPW=m
+CONFIG_USB_SERIAL_KEYSPAN_PDA=m
+CONFIG_USB_SERIAL_KEYSPAN=m
+CONFIG_USB_SERIAL_KEYSPAN_MPR=y
+CONFIG_USB_SERIAL_KEYSPAN_USA28=y
+CONFIG_USB_SERIAL_KEYSPAN_USA28X=y
+CONFIG_USB_SERIAL_KEYSPAN_USA28XA=y
+CONFIG_USB_SERIAL_KEYSPAN_USA28XB=y
+CONFIG_USB_SERIAL_KEYSPAN_USA19=y
+CONFIG_USB_SERIAL_KEYSPAN_USA18X=y
+CONFIG_USB_SERIAL_KEYSPAN_USA19W=y
+CONFIG_USB_SERIAL_KEYSPAN_USA19QW=y
+CONFIG_USB_SERIAL_KEYSPAN_USA19QI=y
+CONFIG_USB_SERIAL_KEYSPAN_USA49W=y
+CONFIG_USB_SERIAL_KEYSPAN_USA49WLC=y
+CONFIG_USB_SERIAL_KLSI=m
+CONFIG_USB_SERIAL_KOBIL_SCT=m
+CONFIG_USB_SERIAL_MCT_U232=m
+CONFIG_USB_SERIAL_NAVMAN=m
+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=m
+CONFIG_USB_SERIAL_TI=m
+CONFIG_USB_SERIAL_CYBERJACK=m
+CONFIG_USB_SERIAL_XIRCOM=m
+CONFIG_USB_SERIAL_OPTION=m
+CONFIG_USB_SERIAL_OMNINET=m
+CONFIG_USB_EZUSB=y
+
+#
+# USB Miscellaneous drivers
+#
+CONFIG_USB_EMI62=m
+CONFIG_USB_EMI26=m
+CONFIG_USB_AUERSWALD=m
+CONFIG_USB_RIO500=m
+CONFIG_USB_LEGOTOWER=m
+CONFIG_USB_LCD=m
+CONFIG_USB_LED=m
+# CONFIG_USB_CYPRESS_CY7C63 is not set
+# CONFIG_USB_CYTHERM is not set
+CONFIG_USB_PHIDGETKIT=m
+CONFIG_USB_PHIDGETSERVO=m
+CONFIG_USB_IDMOUSE=m
+CONFIG_USB_APPLEDISPLAY=m
+CONFIG_USB_SISUSBVGA=m
+CONFIG_USB_SISUSBVGA_CON=y
+CONFIG_USB_LD=m
+CONFIG_USB_TEST=m
+
+#
+# USB DSL modem support
+#
+CONFIG_USB_ATM=m
+CONFIG_USB_SPEEDTOUCH=m
+CONFIG_USB_CXACRU=m
+CONFIG_USB_UEAGLEATM=m
+CONFIG_USB_XUSBATM=m
+
+#
+# USB Gadget Support
+#
+# CONFIG_USB_GADGET is not set
+
+#
+# MMC/SD Card support
+#
+CONFIG_MMC=m
+# CONFIG_MMC_DEBUG is not set
+CONFIG_MMC_BLOCK=m
+CONFIG_MMC_SDHCI=m
+CONFIG_MMC_WBSD=m
+
+#
+# LED devices
+#
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+
+#
+# LED drivers
+#
+
+#
+# LED Triggers
+#
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_LEDS_TRIGGER_TIMER=m
+CONFIG_LEDS_TRIGGER_IDE_DISK=y
+CONFIG_LEDS_TRIGGER_HEARTBEAT=m
+
+#
+# InfiniBand support
+#
+CONFIG_INFINIBAND=m
+CONFIG_INFINIBAND_USER_MAD=m
+CONFIG_INFINIBAND_USER_ACCESS=m
+CONFIG_INFINIBAND_ADDR_TRANS=y
+CONFIG_INFINIBAND_MTHCA=m
+CONFIG_INFINIBAND_MTHCA_DEBUG=y
+CONFIG_INFINIBAND_IPOIB=m
+CONFIG_INFINIBAND_IPOIB_DEBUG=y
+CONFIG_INFINIBAND_IPOIB_DEBUG_DATA=y
+CONFIG_INFINIBAND_SRP=m
+CONFIG_INFINIBAND_ISER=m
+
+#
+# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
+#
+CONFIG_EDAC=y
+
+#
+# Reporting subsystems
+#
+# CONFIG_EDAC_DEBUG is not set
+CONFIG_EDAC_MM_EDAC=m
+CONFIG_EDAC_AMD76X=m
+CONFIG_EDAC_E7XXX=m
+CONFIG_EDAC_E752X=m
+CONFIG_EDAC_I82875P=m
+CONFIG_EDAC_I82860=m
+CONFIG_EDAC_K8=m
+CONFIG_EDAC_R82600=m
+CONFIG_EDAC_POLL=y
+
+#
+# Real Time Clock
+#
+CONFIG_RTC_LIB=m
+CONFIG_RTC_CLASS=m
+
+#
+# RTC interfaces
+#
+CONFIG_RTC_INTF_SYSFS=m
+CONFIG_RTC_INTF_PROC=m
+CONFIG_RTC_INTF_DEV=m
+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
+
+#
+# RTC drivers
+#
+CONFIG_RTC_DRV_X1205=m
+CONFIG_RTC_DRV_DS1307=m
+CONFIG_RTC_DRV_DS1553=m
+CONFIG_RTC_DRV_ISL1208=m
+CONFIG_RTC_DRV_DS1672=m
+CONFIG_RTC_DRV_DS1742=m
+CONFIG_RTC_DRV_PCF8563=m
+CONFIG_RTC_DRV_PCF8583=m
+CONFIG_RTC_DRV_RS5C372=m
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_TEST is not set
+CONFIG_RTC_DRV_V3020=m
+
+#
+# DMA Engine support
+#
+CONFIG_DMA_ENGINE=y
+
+#
+# DMA Clients
+#
+CONFIG_NET_DMA=y
+
+#
+# DMA Devices
+#
+CONFIG_INTEL_IOATDMA=m
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+CONFIG_EXT2_FS_POSIX_ACL=y
+CONFIG_EXT2_FS_SECURITY=y
+CONFIG_EXT2_FS_XIP=y
+CONFIG_FS_XIP=y
+CONFIG_EXT3_FS=m
+CONFIG_EXT3_FS_XATTR=y
+CONFIG_EXT3_FS_POSIX_ACL=y
+CONFIG_EXT3_FS_SECURITY=y
+CONFIG_JBD=m
+# CONFIG_JBD_DEBUG is not set
+CONFIG_FS_MBCACHE=y
+CONFIG_REISERFS_FS=m
+# CONFIG_REISERFS_CHECK is not set
+CONFIG_REISERFS_PROC_INFO=y
+CONFIG_REISERFS_FS_XATTR=y
+CONFIG_REISERFS_FS_POSIX_ACL=y
+CONFIG_REISERFS_FS_SECURITY=y
+CONFIG_JFS_FS=m
+CONFIG_JFS_POSIX_ACL=y
+CONFIG_JFS_SECURITY=y
+# CONFIG_JFS_DEBUG is not set
+# CONFIG_JFS_STATISTICS is not set
+CONFIG_FS_POSIX_ACL=y
+CONFIG_XFS_FS=m
+CONFIG_XFS_QUOTA=y
+CONFIG_XFS_SECURITY=y
+CONFIG_XFS_POSIX_ACL=y
+# CONFIG_XFS_RT is not set
+CONFIG_OCFS2_FS=m
+# CONFIG_OCFS2_DEBUG_MASKLOG is not set
+CONFIG_MINIX_FS=m
+CONFIG_ROMFS_FS=m
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+CONFIG_QUOTA=y
+# CONFIG_QFMT_V1 is not set
+CONFIG_QFMT_V2=y
+CONFIG_QUOTACTL=y
+CONFIG_DNOTIFY=y
+CONFIG_AUTOFS_FS=m
+CONFIG_AUTOFS4_FS=m
+CONFIG_FUSE_FS=m
+
+#
+# Caches
+#
+CONFIG_FSCACHE=m
+
+#
+# CD-ROM/DVD Filesystems
+#
+CONFIG_ISO9660_FS=y
+CONFIG_JOLIET=y
+CONFIG_ZISOFS=y
+CONFIG_ZISOFS_FS=y
+CONFIG_UDF_FS=m
+CONFIG_UDF_NLS=y
+CONFIG_CACHEFILES=m
+CONFIG_CACHEFILES_DEBUG=y
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=m
+CONFIG_MSDOS_FS=m
+CONFIG_VFAT_FS=m
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="ascii"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_RAMFS=y
+CONFIG_CONFIGFS_FS=m
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+CONFIG_AFFS_FS=m
+CONFIG_HFS_FS=m
+CONFIG_HFSPLUS_FS=m
+CONFIG_BEFS_FS=m
+# CONFIG_BEFS_DEBUG is not set
+CONFIG_BFS_FS=m
+CONFIG_EFS_FS=m
+# CONFIG_JFFS_FS is not set
+CONFIG_JFFS2_FS=m
+CONFIG_JFFS2_FS_DEBUG=0
+CONFIG_JFFS2_FS_WRITEBUFFER=y
+CONFIG_JFFS2_SUMMARY=y
+# 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=m
+CONFIG_SQUASHFS=m
+# CONFIG_SQUASHFS_EMBEDDED is not set
+CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3
+# CONFIG_SQUASHFS_VMALLOC is not set
+CONFIG_VXFS_FS=m
+# CONFIG_HPFS_FS is not set
+CONFIG_QNX4FS_FS=m
+CONFIG_SYSV_FS=m
+CONFIG_UFS_FS=m
+# CONFIG_UFS_FS_WRITE is not set
+# CONFIG_UFS_DEBUG is not set
+
+#
+# Network File Systems
+#
+CONFIG_NFS_FS=m
+CONFIG_NFS_V3=y
+CONFIG_NFS_V3_ACL=y
+CONFIG_NFS_V4=y
+CONFIG_NFS_FSCACHE=y
+CONFIG_NFS_DIRECTIO=y
+CONFIG_NFSD=m
+CONFIG_NFSD_V2_ACL=y
+CONFIG_NFSD_V3=y
+CONFIG_NFSD_V3_ACL=y
+CONFIG_NFSD_V4=y
+CONFIG_NFSD_TCP=y
+CONFIG_LOCKD=m
+CONFIG_LOCKD_V4=y
+CONFIG_EXPORTFS=m
+CONFIG_NFS_ACL_SUPPORT=m
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=m
+CONFIG_SUNRPC_GSS=m
+CONFIG_RPCSEC_GSS_KRB5=m
+CONFIG_RPCSEC_GSS_SPKM3=m
+# CONFIG_SMB_FS is not set
+CONFIG_CIFS=m
+# CONFIG_CIFS_STATS is not set
+CONFIG_CIFS_WEAK_PW_HASH=y
+CONFIG_CIFS_XATTR=y
+CONFIG_CIFS_POSIX=y
+# CONFIG_CIFS_DEBUG2 is not set
+# CONFIG_CIFS_EXPERIMENTAL is not set
+CONFIG_NCP_FS=m
+CONFIG_NCPFS_PACKET_SIGNING=y
+CONFIG_NCPFS_IOCTL_LOCKING=y
+CONFIG_NCPFS_STRONG=y
+CONFIG_NCPFS_NFS_NS=y
+CONFIG_NCPFS_OS2_NS=y
+CONFIG_NCPFS_SMALLDOS=y
+CONFIG_NCPFS_NLS=y
+CONFIG_NCPFS_EXTRAS=y
+CONFIG_CODA_FS=m
+# CONFIG_CODA_FS_OLD_API is not set
+# CONFIG_AFS_FS is not set
+CONFIG_9P_FS=m
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+CONFIG_OSF_PARTITION=y
+CONFIG_AMIGA_PARTITION=y
+# CONFIG_ATARI_PARTITION is not set
+CONFIG_MAC_PARTITION=y
+CONFIG_MSDOS_PARTITION=y
+CONFIG_BSD_DISKLABEL=y
+CONFIG_MINIX_SUBPARTITION=y
+CONFIG_SOLARIS_X86_PARTITION=y
+CONFIG_UNIXWARE_DISKLABEL=y
+# CONFIG_LDM_PARTITION is not set
+CONFIG_SGI_PARTITION=y
+# CONFIG_ULTRIX_PARTITION is not set
+CONFIG_SUN_PARTITION=y
+CONFIG_KARMA_PARTITION=y
+CONFIG_EFI_PARTITION=y
+
+#
+# Native Language Support
+#
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="utf8"
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_CODEPAGE_737=m
+CONFIG_NLS_CODEPAGE_775=m
+CONFIG_NLS_CODEPAGE_850=m
+CONFIG_NLS_CODEPAGE_852=m
+CONFIG_NLS_CODEPAGE_855=m
+CONFIG_NLS_CODEPAGE_857=m
+CONFIG_NLS_CODEPAGE_860=m
+CONFIG_NLS_CODEPAGE_861=m
+CONFIG_NLS_CODEPAGE_862=m
+CONFIG_NLS_CODEPAGE_863=m
+CONFIG_NLS_CODEPAGE_864=m
+CONFIG_NLS_CODEPAGE_865=m
+CONFIG_NLS_CODEPAGE_866=m
+CONFIG_NLS_CODEPAGE_869=m
+CONFIG_NLS_CODEPAGE_936=m
+CONFIG_NLS_CODEPAGE_950=m
+CONFIG_NLS_CODEPAGE_932=m
+CONFIG_NLS_CODEPAGE_949=m
+CONFIG_NLS_CODEPAGE_874=m
+CONFIG_NLS_ISO8859_8=m
+CONFIG_NLS_CODEPAGE_1250=m
+CONFIG_NLS_CODEPAGE_1251=m
+CONFIG_NLS_ASCII=y
+CONFIG_NLS_ISO8859_1=m
+CONFIG_NLS_ISO8859_2=m
+CONFIG_NLS_ISO8859_3=m
+CONFIG_NLS_ISO8859_4=m
+CONFIG_NLS_ISO8859_5=m
+CONFIG_NLS_ISO8859_6=m
+CONFIG_NLS_ISO8859_7=m
+CONFIG_NLS_ISO8859_9=m
+CONFIG_NLS_ISO8859_13=m
+CONFIG_NLS_ISO8859_14=m
+CONFIG_NLS_ISO8859_15=m
+CONFIG_NLS_KOI8_R=m
+CONFIG_NLS_KOI8_U=m
+CONFIG_NLS_UTF8=m
+
+#
+# Instrumentation Support
+#
+CONFIG_PROFILING=y
+CONFIG_OPROFILE=m
+CONFIG_KPROBES=y
+
+#
+# Kernel hacking
+#
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+# CONFIG_PRINTK_TIME is not set
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_UNUSED_SYMBOLS is not set
+CONFIG_DEBUG_KERNEL=y
+CONFIG_LOG_BUF_SHIFT=17
+CONFIG_DETECT_SOFTLOCKUP=y
+CONFIG_SCHEDSTATS=y
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
+CONFIG_DEBUG_SPINLOCK=y
+# 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=y
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+# CONFIG_DEBUG_KOBJECT is not set
+CONFIG_DEBUG_HIGHMEM=y
+CONFIG_DEBUG_BUGVERBOSE=y
+CONFIG_DEBUG_INFO=y
+CONFIG_DEBUG_FS=y
+# CONFIG_DEBUG_VM is not set
+CONFIG_DEBUG_LIST=y
+# CONFIG_FRAME_POINTER is not set
+CONFIG_UNWIND_INFO=y
+CONFIG_STACK_UNWIND=y
+# CONFIG_FORCED_INLINING is not set
+CONFIG_BOOT_DELAY=y
+# CONFIG_RCU_TORTURE_TEST is not set
+CONFIG_EARLY_PRINTK=y
+CONFIG_DEBUG_STACKOVERFLOW=y
+CONFIG_DEBUG_STACK_USAGE=y
+# CONFIG_DEBUG_PAGEALLOC is not set
+CONFIG_DEBUG_RODATA=y
+CONFIG_4KSTACKS=y
+CONFIG_X86_FIND_SMP_CONFIG=y
+CONFIG_X86_MPPARSE=y
+
+#
+# Security options
+#
+CONFIG_KEYS=y
+CONFIG_KEYS_DEBUG_PROC_KEYS=y
+CONFIG_SECURITY=y
+CONFIG_SECURITY_NETWORK=y
+# CONFIG_SECURITY_NETWORK_XFRM is not set
+CONFIG_SECURITY_CAPABILITIES=y
+# CONFIG_SECURITY_ROOTPLUG is not set
+# CONFIG_SECURITY_SECLVL is not set
+CONFIG_SECURITY_SELINUX=y
+CONFIG_SECURITY_SELINUX_BOOTPARAM=y
+CONFIG_SECURITY_SELINUX_BOOTPARAM_VALUE=1
+CONFIG_SECURITY_SELINUX_DISABLE=y
+CONFIG_SECURITY_SELINUX_DEVELOP=y
+CONFIG_SECURITY_SELINUX_AVC_STATS=y
+CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE=1
+# CONFIG_SECURITY_SELINUX_ENABLE_SECMARK_DEFAULT is not set
+# CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX is not set
+
+#
+# Cryptographic options
+#
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_NULL=m
+CONFIG_CRYPTO_MD4=m
+CONFIG_CRYPTO_MD5=m
+CONFIG_CRYPTO_SHA1=y
+CONFIG_CRYPTO_SHA256=m
+CONFIG_CRYPTO_SHA512=m
+CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_TGR192=m
+CONFIG_CRYPTO_DES=m
+CONFIG_CRYPTO_BLOWFISH=m
+CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_SERPENT=m
+CONFIG_CRYPTO_AES=m
+CONFIG_CRYPTO_AES_586=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_TEST is not set
+CONFIG_CRYPTO_SIGNATURE=y
+CONFIG_CRYPTO_SIGNATURE_DSA=y
+CONFIG_CRYPTO_MPILIB=y
+
+#
+# Hardware crypto devices
+#
+CONFIG_CRYPTO_DEV_PADLOCK=m
+CONFIG_CRYPTO_DEV_PADLOCK_AES=y
+CONFIG_XEN=y
+CONFIG_XEN_INTERFACE_VERSION=0x00030203
+
+#
+# XEN
+#
+CONFIG_XEN_PRIVILEGED_GUEST=y
+# CONFIG_XEN_UNPRIVILEGED_GUEST is not set
+CONFIG_XEN_PRIVCMD=y
+CONFIG_XEN_XENBUS_DEV=y
+CONFIG_XEN_BACKEND=y
+CONFIG_XEN_BLKDEV_BACKEND=m
+CONFIG_XEN_BLKDEV_TAP=m
+CONFIG_XEN_NETDEV_BACKEND=m
+# CONFIG_XEN_NETDEV_PIPELINED_TRANSMITTER is not set
+CONFIG_XEN_NETDEV_LOOPBACK=m
+CONFIG_XEN_PCIDEV_BACKEND=m
+CONFIG_XEN_PCIDEV_BACKEND_VPCI=y
+# CONFIG_XEN_PCIDEV_BACKEND_PASS is not set
+# CONFIG_XEN_PCIDEV_BACKEND_SLOT is not set
+# CONFIG_XEN_PCIDEV_BE_DEBUG is not set
+# CONFIG_XEN_TPMDEV_BACKEND is not set
+CONFIG_XEN_BLKDEV_FRONTEND=m
+CONFIG_XEN_NETDEV_FRONTEND=m
+CONFIG_XEN_FRAMEBUFFER=y
+CONFIG_XEN_KEYBOARD=y
+CONFIG_XEN_SCRUB_PAGES=y
+# CONFIG_XEN_DISABLE_SERIAL is not set
+CONFIG_XEN_SYSFS=y
+CONFIG_XEN_COMPAT_030002_AND_LATER=y
+# CONFIG_XEN_COMPAT_LATEST_ONLY is not set
+CONFIG_XEN_COMPAT_030002=y
+CONFIG_HAVE_ARCH_ALLOC_SKB=y
+CONFIG_HAVE_ARCH_DEV_ALLOC_SKB=y
+CONFIG_HAVE_IRQ_IGNORE_UNHANDLED=y
+CONFIG_NO_IDLE_HZ=y
+CONFIG_XEN_UTIL=y
+CONFIG_XEN_BALLOON=y
+CONFIG_XEN_DEVMEM=y
+CONFIG_XEN_SKBUFF=y
+CONFIG_XEN_REBOOT=y
+CONFIG_XEN_SMPBOOT=y
+
+#
+# Library routines
+#
+CONFIG_CRC_CCITT=m
+CONFIG_CRC16=m
+CONFIG_CRC32=y
+CONFIG_LIBCRC32C=m
+CONFIG_AUDIT_GENERIC=y
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=m
+CONFIG_REED_SOLOMON=m
+CONFIG_REED_SOLOMON_DEC16=y
+CONFIG_TEXTSEARCH=y
+CONFIG_TEXTSEARCH_KMP=m
+CONFIG_TEXTSEARCH_BM=m
+CONFIG_TEXTSEARCH_FSM=m
+CONFIG_PLIST=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_GENERIC_PENDING_IRQ=y
+CONFIG_X86_SMP=y
+CONFIG_X86_BIOS_REBOOT=y
+CONFIG_X86_TRAMPOLINE=y
+CONFIG_X86_NO_TSS=y
+CONFIG_X86_NO_IDT=y
+CONFIG_KTIME_SCALAR=y
diff --git a/configs/kernel-2.6.18-i686-xen0.config b/configs/kernel-2.6.18-i686-xen0.config
new file mode 100644
index 000000000..c6fe1ef9d
--- /dev/null
+++ b/configs/kernel-2.6.18-i686-xen0.config
@@ -0,0 +1,3258 @@
+# i386
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.18.2-rc1
+# Mon Nov 13 09:44:40 2006
+#
+CONFIG_X86_32=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_SEMAPHORE_SLEEPERS=y
+CONFIG_X86=y
+CONFIG_MMU=y
+CONFIG_GENERIC_ISA_DMA=y
+CONFIG_GENERIC_IOMAP=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_ARCH_MAY_HAVE_PC_FDC=y
+CONFIG_DMI=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_BSD_PROCESS_ACCT=y
+# CONFIG_BSD_PROCESS_ACCT_V3 is not set
+CONFIG_TASKSTATS=y
+CONFIG_TASK_DELAY_ACCT=y
+CONFIG_AUDIT=y
+CONFIG_AUDITSYSCALL=y
+# CONFIG_IKCONFIG is not set
+CONFIG_CPUSETS=y
+CONFIG_RELAY=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+# CONFIG_EMBEDDED is not set
+CONFIG_UID16=y
+CONFIG_SYSCTL=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
+CONFIG_KALLSYMS_EXTRA_PASS=y
+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=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+CONFIG_MODULE_SIG=y
+# CONFIG_MODULE_SIG_FORCE is not set
+CONFIG_KMOD=y
+CONFIG_STOP_MACHINE=y
+
+#
+# Process debugging support
+#
+CONFIG_UTRACE=y
+CONFIG_PTRACE=y
+
+#
+# Block layer
+#
+CONFIG_LBD=y
+CONFIG_BLK_DEV_IO_TRACE=y
+CONFIG_LSF=y
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_DEFAULT_AS is not set
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+
+#
+# Processor type and features
+#
+CONFIG_SMP=y
+# CONFIG_X86_PC is not set
+CONFIG_X86_XEN=y
+# CONFIG_X86_ELAN is not set
+# CONFIG_X86_VOYAGER is not set
+# CONFIG_X86_NUMAQ is not set
+# CONFIG_X86_SUMMIT is not set
+# CONFIG_X86_BIGSMP is not set
+# CONFIG_X86_VISWS is not set
+# CONFIG_X86_GENERICARCH is not set
+# CONFIG_X86_ES7000 is not set
+# CONFIG_M386 is not set
+# CONFIG_M486 is not set
+# CONFIG_M586 is not set
+# CONFIG_M586TSC is not set
+# CONFIG_M586MMX is not set
+CONFIG_M686=y
+# CONFIG_MPENTIUMII is not set
+# CONFIG_MPENTIUMIII is not set
+# CONFIG_MPENTIUMM is not set
+# CONFIG_MPENTIUM4 is not set
+# CONFIG_MK6 is not set
+# CONFIG_MK7 is not set
+# CONFIG_MK8 is not set
+# CONFIG_MCRUSOE is not set
+# CONFIG_MEFFICEON is not set
+# CONFIG_MWINCHIPC6 is not set
+# CONFIG_MWINCHIP2 is not set
+# CONFIG_MWINCHIP3D is not set
+# CONFIG_MGEODEGX1 is not set
+# CONFIG_MGEODE_LX is not set
+# CONFIG_MCYRIXIII is not set
+# CONFIG_MVIAC3_2 is not set
+CONFIG_X86_GENERIC=y
+CONFIG_X86_CMPXCHG=y
+CONFIG_X86_XADD=y
+CONFIG_X86_L1_CACHE_SHIFT=7
+CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_X86_PPRO_FENCE=y
+CONFIG_X86_WP_WORKS_OK=y
+CONFIG_X86_INVLPG=y
+CONFIG_X86_BSWAP=y
+CONFIG_X86_POPAD_OK=y
+CONFIG_X86_CMPXCHG64=y
+CONFIG_X86_GOOD_APIC=y
+CONFIG_X86_INTEL_USERCOPY=y
+CONFIG_X86_USE_PPRO_CHECKSUM=y
+CONFIG_NR_CPUS=32
+# CONFIG_PREEMPT_NONE is not set
+CONFIG_PREEMPT_VOLUNTARY=y
+# CONFIG_PREEMPT is not set
+CONFIG_PREEMPT_BKL=y
+CONFIG_X86_LOCAL_APIC=y
+CONFIG_X86_APIC_AUTO=y
+CONFIG_X86_IO_APIC=y
+CONFIG_VM86=y
+CONFIG_TOSHIBA=m
+CONFIG_I8K=m
+# CONFIG_X86_REBOOTFIXUPS is not set
+CONFIG_MICROCODE=y
+CONFIG_X86_CPUID=m
+CONFIG_SWIOTLB=y
+
+#
+# Firmware Drivers
+#
+CONFIG_DELL_RBU=m
+CONFIG_DCDBAS=m
+# CONFIG_NOHIGHMEM is not set
+CONFIG_HIGHMEM4G=y
+# CONFIG_HIGHMEM64G is not set
+CONFIG_PAGE_OFFSET=0xC0000000
+CONFIG_HIGHMEM=y
+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=y
+CONFIG_MTRR=y
+CONFIG_REGPARM=y
+# CONFIG_SECCOMP is not set
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
+# CONFIG_CRASH_DUMP is not set
+CONFIG_PHYSICAL_START=0x400000
+CONFIG_HOTPLUG_CPU=y
+CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
+
+#
+# Power management options (ACPI, APM)
+#
+CONFIG_PM=y
+
+#
+# ACPI (Advanced Configuration and Power Interface) Support
+#
+CONFIG_ACPI=y
+CONFIG_ACPI_AC=m
+CONFIG_ACPI_BATTERY=m
+CONFIG_ACPI_BUTTON=m
+CONFIG_ACPI_VIDEO=m
+# CONFIG_ACPI_HOTKEY is not set
+CONFIG_ACPI_FAN=y
+CONFIG_ACPI_DOCK=m
+CONFIG_ACPI_PROCESSOR=y
+CONFIG_ACPI_HOTPLUG_CPU=y
+CONFIG_ACPI_THERMAL=y
+CONFIG_ACPI_ASUS=m
+CONFIG_ACPI_IBM=m
+CONFIG_ACPI_TOSHIBA=m
+CONFIG_ACPI_BLACKLIST_YEAR=1999
+# CONFIG_ACPI_DEBUG is not set
+CONFIG_ACPI_EC=y
+CONFIG_ACPI_POWER=y
+CONFIG_ACPI_SYSTEM=y
+CONFIG_ACPI_CONTAINER=y
+CONFIG_ACPI_SBS=m
+
+#
+# CPU Frequency scaling
+#
+CONFIG_CPU_FREQ=y
+CONFIG_CPU_FREQ_TABLE=y
+CONFIG_CPU_FREQ_DEBUG=y
+CONFIG_CPU_FREQ_STAT=m
+CONFIG_CPU_FREQ_STAT_DETAILS=y
+# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set
+CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE=y
+CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
+CONFIG_CPU_FREQ_GOV_POWERSAVE=m
+CONFIG_CPU_FREQ_GOV_USERSPACE=y
+CONFIG_CPU_FREQ_GOV_ONDEMAND=m
+CONFIG_CPU_FREQ_GOV_CONSERVATIVE=m
+
+#
+# CPUFreq processor drivers
+#
+CONFIG_X86_ACPI_CPUFREQ=m
+# CONFIG_X86_POWERNOW_K6 is not set
+CONFIG_X86_POWERNOW_K7=y
+CONFIG_X86_POWERNOW_K7_ACPI=y
+CONFIG_X86_POWERNOW_K8=y
+CONFIG_X86_POWERNOW_K8_ACPI=y
+# CONFIG_X86_GX_SUSPMOD is not set
+CONFIG_X86_SPEEDSTEP_CENTRINO=y
+CONFIG_X86_SPEEDSTEP_CENTRINO_ACPI=y
+CONFIG_X86_SPEEDSTEP_CENTRINO_TABLE=y
+CONFIG_X86_SPEEDSTEP_ICH=y
+CONFIG_X86_SPEEDSTEP_SMI=y
+CONFIG_X86_P4_CLOCKMOD=m
+# CONFIG_X86_CPUFREQ_NFORCE2 is not set
+CONFIG_X86_LONGRUN=y
+# CONFIG_X86_LONGHAUL is not set
+
+#
+# shared options
+#
+# CONFIG_X86_ACPI_CPUFREQ_PROC_INTF is not set
+CONFIG_X86_SPEEDSTEP_LIB=y
+# CONFIG_X86_SPEEDSTEP_RELAXED_CAP_CHECK is not set
+
+#
+# Bus options (PCI, PCMCIA, EISA, MCA, ISA)
+#
+CONFIG_PCI=y
+# CONFIG_PCI_GOBIOS is not set
+# CONFIG_PCI_GOMMCONFIG is not set
+# CONFIG_PCI_GODIRECT is not set
+# CONFIG_PCI_GOXEN_FE is not set
+CONFIG_PCI_GOANY=y
+CONFIG_PCI_DIRECT=y
+CONFIG_PCI_MMCONFIG=y
+CONFIG_XEN_PCIDEV_FRONTEND=y
+# CONFIG_XEN_PCIDEV_FE_DEBUG is not set
+CONFIG_PCIEPORTBUS=y
+CONFIG_HOTPLUG_PCI_PCIE=m
+# CONFIG_HOTPLUG_PCI_PCIE_POLL_EVENT_MODE is not set
+# CONFIG_PCI_DEBUG is not set
+CONFIG_ISA_DMA_API=y
+# CONFIG_SCx200 is not set
+CONFIG_K8_NB=y
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+CONFIG_PCCARD=y
+# CONFIG_PCMCIA_DEBUG is not set
+CONFIG_PCMCIA=y
+CONFIG_PCMCIA_LOAD_CIS=y
+CONFIG_PCMCIA_IOCTL=y
+CONFIG_CARDBUS=y
+
+#
+# PC-card bridges
+#
+CONFIG_YENTA=y
+CONFIG_YENTA_O2=y
+CONFIG_YENTA_RICOH=y
+CONFIG_YENTA_TI=y
+CONFIG_YENTA_ENE_TUNE=y
+CONFIG_YENTA_TOSHIBA=y
+CONFIG_PD6729=m
+CONFIG_I82092=m
+CONFIG_PCCARD_NONSTATIC=y
+
+#
+# PCI Hotplug Support
+#
+CONFIG_HOTPLUG_PCI=y
+CONFIG_HOTPLUG_PCI_FAKE=m
+CONFIG_HOTPLUG_PCI_ACPI=m
+CONFIG_HOTPLUG_PCI_ACPI_IBM=m
+# CONFIG_HOTPLUG_PCI_CPCI is not set
+# CONFIG_HOTPLUG_PCI_SHPC is not set
+
+#
+# Executable file formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_AOUT is not set
+CONFIG_BINFMT_MISC=y
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+# CONFIG_NETDEBUG is not set
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=y
+CONFIG_NET_KEY=m
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_ASK_IP_FIB_HASH=y
+# 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
+# CONFIG_IP_PNP is not set
+CONFIG_NET_IPIP=m
+CONFIG_NET_IPGRE=m
+CONFIG_NET_IPGRE_BROADCAST=y
+CONFIG_IP_MROUTE=y
+CONFIG_IP_PIMSM_V1=y
+CONFIG_IP_PIMSM_V2=y
+# CONFIG_ARPD is not set
+CONFIG_SYN_COOKIES=y
+CONFIG_INET_AH=m
+CONFIG_INET_ESP=m
+CONFIG_INET_IPCOMP=m
+CONFIG_INET_XFRM_TUNNEL=m
+CONFIG_INET_TUNNEL=m
+CONFIG_INET_XFRM_MODE_TRANSPORT=m
+CONFIG_INET_XFRM_MODE_TUNNEL=m
+CONFIG_INET_DIAG=m
+CONFIG_INET_TCP_DIAG=m
+CONFIG_TCP_CONG_ADVANCED=y
+
+#
+# TCP congestion control
+#
+CONFIG_TCP_CONG_BIC=y
+CONFIG_TCP_CONG_CUBIC=m
+CONFIG_TCP_CONG_WESTWOOD=m
+CONFIG_TCP_CONG_HTCP=m
+CONFIG_TCP_CONG_HSTCP=m
+CONFIG_TCP_CONG_HYBLA=m
+CONFIG_TCP_CONG_VEGAS=m
+CONFIG_TCP_CONG_SCALABLE=m
+CONFIG_TCP_CONG_LP=m
+CONFIG_TCP_CONG_VENO=m
+
+#
+# IP: Virtual Server Configuration
+#
+CONFIG_IP_VS=m
+# CONFIG_IP_VS_DEBUG is not set
+CONFIG_IP_VS_TAB_BITS=12
+
+#
+# IPVS transport protocol load balancing support
+#
+CONFIG_IP_VS_PROTO_TCP=y
+CONFIG_IP_VS_PROTO_UDP=y
+CONFIG_IP_VS_PROTO_ESP=y
+CONFIG_IP_VS_PROTO_AH=y
+
+#
+# IPVS scheduler
+#
+CONFIG_IP_VS_RR=m
+CONFIG_IP_VS_WRR=m
+CONFIG_IP_VS_LC=m
+CONFIG_IP_VS_WLC=m
+CONFIG_IP_VS_LBLC=m
+CONFIG_IP_VS_LBLCR=m
+CONFIG_IP_VS_DH=m
+CONFIG_IP_VS_SH=m
+CONFIG_IP_VS_SED=m
+CONFIG_IP_VS_NQ=m
+
+#
+# IPVS application helper
+#
+CONFIG_IP_VS_FTP=m
+CONFIG_IPV6=m
+CONFIG_IPV6_PRIVACY=y
+CONFIG_IPV6_ROUTER_PREF=y
+CONFIG_IPV6_ROUTE_INFO=y
+CONFIG_INET6_AH=m
+CONFIG_INET6_ESP=m
+CONFIG_INET6_IPCOMP=m
+CONFIG_INET6_XFRM_TUNNEL=m
+CONFIG_INET6_TUNNEL=m
+CONFIG_INET6_XFRM_MODE_TRANSPORT=m
+CONFIG_INET6_XFRM_MODE_TUNNEL=m
+CONFIG_IPV6_TUNNEL=m
+CONFIG_NETWORK_SECMARK=y
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_DEBUG is not set
+CONFIG_BRIDGE_NETFILTER=y
+
+#
+# Core Netfilter Configuration
+#
+CONFIG_NETFILTER_NETLINK=m
+CONFIG_NETFILTER_NETLINK_QUEUE=m
+CONFIG_NETFILTER_NETLINK_LOG=m
+CONFIG_NETFILTER_XTABLES=m
+CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
+CONFIG_NETFILTER_XT_TARGET_CONNMARK=m
+CONFIG_NETFILTER_XT_TARGET_MARK=m
+CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
+CONFIG_NETFILTER_XT_TARGET_NOTRACK=m
+CONFIG_NETFILTER_XT_TARGET_SECMARK=m
+CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=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_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_PHYSDEV=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
+
+#
+# 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=m
+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_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_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_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
+CONFIG_IP_NF_ARPTABLES=m
+CONFIG_IP_NF_ARPFILTER=m
+CONFIG_IP_NF_ARP_MANGLE=m
+
+#
+# IPv6: Netfilter Configuration (EXPERIMENTAL)
+#
+CONFIG_IP6_NF_QUEUE=m
+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_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
+
+#
+# DECnet: Netfilter Configuration
+#
+# CONFIG_DECNET_NF_GRABULATOR is not set
+
+#
+# Bridge: Netfilter Configuration
+#
+CONFIG_BRIDGE_NF_EBTABLES=m
+CONFIG_BRIDGE_EBT_BROUTE=m
+CONFIG_BRIDGE_EBT_T_FILTER=m
+CONFIG_BRIDGE_EBT_T_NAT=m
+CONFIG_BRIDGE_EBT_802_3=m
+CONFIG_BRIDGE_EBT_AMONG=m
+CONFIG_BRIDGE_EBT_ARP=m
+CONFIG_BRIDGE_EBT_IP=m
+CONFIG_BRIDGE_EBT_LIMIT=m
+CONFIG_BRIDGE_EBT_MARK=m
+CONFIG_BRIDGE_EBT_PKTTYPE=m
+CONFIG_BRIDGE_EBT_STP=m
+CONFIG_BRIDGE_EBT_VLAN=m
+CONFIG_BRIDGE_EBT_ARPREPLY=m
+CONFIG_BRIDGE_EBT_DNAT=m
+CONFIG_BRIDGE_EBT_MARK_T=m
+CONFIG_BRIDGE_EBT_REDIRECT=m
+CONFIG_BRIDGE_EBT_SNAT=m
+CONFIG_BRIDGE_EBT_LOG=m
+CONFIG_BRIDGE_EBT_ULOG=m
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+CONFIG_IP_DCCP=m
+CONFIG_INET_DCCP_DIAG=m
+CONFIG_IP_DCCP_ACKVEC=y
+
+#
+# DCCP CCIDs Configuration (EXPERIMENTAL)
+#
+CONFIG_IP_DCCP_CCID2=m
+CONFIG_IP_DCCP_CCID3=m
+CONFIG_IP_DCCP_TFRC_LIB=m
+
+#
+# DCCP Kernel Hacking
+#
+# CONFIG_IP_DCCP_DEBUG is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+CONFIG_IP_SCTP=m
+# CONFIG_SCTP_DBG_MSG is not set
+# CONFIG_SCTP_DBG_OBJCNT is not set
+# CONFIG_SCTP_HMAC_NONE is not set
+# CONFIG_SCTP_HMAC_SHA1 is not set
+CONFIG_SCTP_HMAC_MD5=y
+
+#
+# TIPC Configuration (EXPERIMENTAL)
+#
+CONFIG_TIPC=m
+# CONFIG_TIPC_ADVANCED is not set
+# CONFIG_TIPC_DEBUG is not set
+CONFIG_ATM=m
+CONFIG_ATM_CLIP=m
+# CONFIG_ATM_CLIP_NO_ICMP is not set
+CONFIG_ATM_LANE=m
+# CONFIG_ATM_MPOA is not set
+CONFIG_ATM_BR2684=m
+# CONFIG_ATM_BR2684_IPFILTER is not set
+CONFIG_BRIDGE=m
+CONFIG_VLAN_8021Q=m
+CONFIG_DECNET=m
+CONFIG_DECNET_ROUTER=y
+CONFIG_DECNET_ROUTE_FWMARK=y
+CONFIG_LLC=y
+# CONFIG_LLC2 is not set
+CONFIG_IPX=m
+# CONFIG_IPX_INTERN is not set
+CONFIG_ATALK=m
+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_ECONET is not set
+CONFIG_WAN_ROUTER=m
+
+#
+# QoS and/or fair queueing
+#
+CONFIG_NET_SCHED=y
+# CONFIG_NET_SCH_CLK_JIFFIES is not set
+CONFIG_NET_SCH_CLK_GETTIMEOFDAY=y
+# CONFIG_NET_SCH_CLK_CPU is not set
+
+#
+# Queueing/Scheduling
+#
+CONFIG_NET_SCH_CBQ=m
+CONFIG_NET_SCH_HTB=m
+CONFIG_NET_SCH_HFSC=m
+CONFIG_NET_SCH_ATM=m
+CONFIG_NET_SCH_PRIO=m
+CONFIG_NET_SCH_RED=m
+CONFIG_NET_SCH_SFQ=m
+CONFIG_NET_SCH_TEQL=m
+CONFIG_NET_SCH_TBF=m
+CONFIG_NET_SCH_GRED=m
+CONFIG_NET_SCH_DSMARK=m
+CONFIG_NET_SCH_NETEM=m
+CONFIG_NET_SCH_INGRESS=m
+
+#
+# Classification
+#
+CONFIG_NET_CLS=y
+CONFIG_NET_CLS_BASIC=m
+CONFIG_NET_CLS_TCINDEX=m
+CONFIG_NET_CLS_ROUTE4=m
+CONFIG_NET_CLS_ROUTE=y
+CONFIG_NET_CLS_FW=m
+CONFIG_NET_CLS_U32=m
+CONFIG_CLS_U32_PERF=y
+CONFIG_CLS_U32_MARK=y
+CONFIG_NET_CLS_RSVP=m
+CONFIG_NET_CLS_RSVP6=m
+CONFIG_NET_EMATCH=y
+CONFIG_NET_EMATCH_STACK=32
+CONFIG_NET_EMATCH_CMP=m
+CONFIG_NET_EMATCH_NBYTE=m
+CONFIG_NET_EMATCH_U32=m
+CONFIG_NET_EMATCH_META=m
+CONFIG_NET_EMATCH_TEXT=m
+CONFIG_NET_CLS_ACT=y
+CONFIG_NET_ACT_POLICE=m
+CONFIG_NET_ACT_GACT=m
+CONFIG_GACT_PROB=y
+CONFIG_NET_ACT_MIRRED=m
+CONFIG_NET_ACT_IPT=m
+CONFIG_NET_ACT_PEDIT=m
+CONFIG_NET_ACT_SIMP=m
+CONFIG_NET_CLS_IND=y
+CONFIG_NET_ESTIMATOR=y
+
+#
+# Network testing
+#
+CONFIG_NET_PKTGEN=m
+# CONFIG_NET_TCPPROBE is not set
+# CONFIG_HAMRADIO is not set
+CONFIG_IRDA=m
+
+#
+# IrDA protocols
+#
+CONFIG_IRLAN=m
+CONFIG_IRNET=m
+CONFIG_IRCOMM=m
+# CONFIG_IRDA_ULTRA is not set
+
+#
+# IrDA options
+#
+CONFIG_IRDA_CACHE_LAST_LSAP=y
+CONFIG_IRDA_FAST_RR=y
+# CONFIG_IRDA_DEBUG is not set
+
+#
+# Infrared-port device drivers
+#
+
+#
+# SIR device drivers
+#
+CONFIG_IRTTY_SIR=m
+
+#
+# Dongle support
+#
+CONFIG_DONGLE=y
+CONFIG_ESI_DONGLE=m
+CONFIG_ACTISYS_DONGLE=m
+CONFIG_TEKRAM_DONGLE=m
+CONFIG_TOIM3232_DONGLE=m
+CONFIG_LITELINK_DONGLE=m
+CONFIG_MA600_DONGLE=m
+CONFIG_GIRBIL_DONGLE=m
+CONFIG_MCP2120_DONGLE=m
+CONFIG_OLD_BELKIN_DONGLE=m
+CONFIG_ACT200L_DONGLE=m
+
+#
+# Old SIR device drivers
+#
+
+#
+# Old Serial dongle support
+#
+
+#
+# FIR device drivers
+#
+CONFIG_USB_IRDA=m
+CONFIG_SIGMATEL_FIR=m
+CONFIG_NSC_FIR=m
+CONFIG_WINBOND_FIR=m
+CONFIG_TOSHIBA_FIR=m
+CONFIG_SMC_IRCC_FIR=m
+CONFIG_ALI_FIR=m
+CONFIG_VLSI_FIR=m
+CONFIG_VIA_FIR=m
+CONFIG_MCS_FIR=m
+CONFIG_BT=m
+CONFIG_BT_L2CAP=m
+CONFIG_BT_SCO=m
+CONFIG_BT_RFCOMM=m
+CONFIG_BT_RFCOMM_TTY=y
+CONFIG_BT_BNEP=m
+CONFIG_BT_BNEP_MC_FILTER=y
+CONFIG_BT_BNEP_PROTO_FILTER=y
+CONFIG_BT_CMTP=m
+CONFIG_BT_HIDP=m
+
+#
+# Bluetooth device drivers
+#
+CONFIG_BT_HCIUSB=m
+CONFIG_BT_HCIUSB_SCO=y
+CONFIG_BT_HCIUART=m
+CONFIG_BT_HCIUART_H4=y
+CONFIG_BT_HCIUART_BCSP=y
+CONFIG_BT_HCIBCM203X=m
+CONFIG_BT_HCIBPA10X=m
+CONFIG_BT_HCIBFUSB=m
+CONFIG_BT_HCIDTL1=m
+CONFIG_BT_HCIBT3C=m
+CONFIG_BT_HCIBLUECARD=m
+CONFIG_BT_HCIBTUART=m
+CONFIG_BT_HCIVHCI=m
+CONFIG_IEEE80211=m
+# CONFIG_IEEE80211_DEBUG is not set
+CONFIG_IEEE80211_CRYPT_WEP=m
+CONFIG_IEEE80211_CRYPT_CCMP=m
+CONFIG_IEEE80211_CRYPT_TKIP=m
+CONFIG_IEEE80211_SOFTMAC=m
+CONFIG_IEEE80211_SOFTMAC_DEBUG=y
+CONFIG_TUX=m
+
+#
+# TUX options
+#
+CONFIG_TUX_EXTCGI=y
+CONFIG_TUX_EXTENDED_LOG=y
+# CONFIG_TUX_DEBUG is not set
+CONFIG_WIRELESS_EXT=y
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_SYS_HYPERVISOR is not set
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+CONFIG_CONNECTOR=y
+CONFIG_PROC_EVENTS=y
+
+#
+# Memory Technology Devices (MTD)
+#
+CONFIG_MTD=m
+# CONFIG_MTD_DEBUG is not set
+CONFIG_MTD_CONCAT=m
+CONFIG_MTD_PARTITIONS=y
+CONFIG_MTD_REDBOOT_PARTS=m
+CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1
+# CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED is not set
+# CONFIG_MTD_REDBOOT_PARTS_READONLY is not set
+CONFIG_MTD_CMDLINE_PARTS=y
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=m
+CONFIG_MTD_BLOCK=m
+CONFIG_MTD_BLOCK_RO=m
+CONFIG_FTL=m
+CONFIG_NFTL=m
+CONFIG_NFTL_RW=y
+CONFIG_INFTL=m
+CONFIG_RFD_FTL=m
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=m
+CONFIG_MTD_JEDECPROBE=m
+CONFIG_MTD_GEN_PROBE=m
+# CONFIG_MTD_CFI_ADV_OPTIONS 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_CFI_INTELEXT=m
+CONFIG_MTD_CFI_AMDSTD=m
+CONFIG_MTD_CFI_STAA=m
+CONFIG_MTD_CFI_UTIL=m
+CONFIG_MTD_RAM=m
+CONFIG_MTD_ROM=m
+CONFIG_MTD_ABSENT=m
+# CONFIG_MTD_OBSOLETE_CHIPS is not set
+
+#
+# Mapping drivers for chip access
+#
+CONFIG_MTD_COMPLEX_MAPPINGS=y
+# CONFIG_MTD_PHYSMAP is not set
+# CONFIG_MTD_PNC2000 is not set
+CONFIG_MTD_SC520CDP=m
+CONFIG_MTD_NETSC520=m
+CONFIG_MTD_TS5500=m
+# CONFIG_MTD_SBC_GXX is not set
+# CONFIG_MTD_AMD76XROM is not set
+# CONFIG_MTD_ICHXROM is not set
+CONFIG_MTD_SCB2_FLASH=m
+# CONFIG_MTD_NETtel is not set
+# CONFIG_MTD_DILNETPC is not set
+# CONFIG_MTD_L440GX is not set
+CONFIG_MTD_PCI=m
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+CONFIG_MTD_PMC551=m
+# CONFIG_MTD_PMC551_BUGFIX is not set
+# CONFIG_MTD_PMC551_DEBUG is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+CONFIG_MTD_MTDRAM=m
+CONFIG_MTDRAM_TOTAL_SIZE=4096
+CONFIG_MTDRAM_ERASE_SIZE=128
+CONFIG_MTD_BLOCK2MTD=m
+
+#
+# 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=m
+# CONFIG_MTD_NAND_VERIFY_WRITE is not set
+CONFIG_MTD_NAND_ECC_SMC=y
+CONFIG_MTD_NAND_IDS=m
+CONFIG_MTD_NAND_DISKONCHIP=m
+# CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADVANCED is not set
+CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADDRESS=0
+# CONFIG_MTD_NAND_DISKONCHIP_BBTWRITE is not set
+CONFIG_MTD_NAND_NANDSIM=m
+
+#
+# OneNAND Flash Device Drivers
+#
+# CONFIG_MTD_ONENAND is not set
+
+#
+# Parallel port support
+#
+CONFIG_PARPORT=m
+CONFIG_PARPORT_PC=m
+CONFIG_PARPORT_SERIAL=m
+# CONFIG_PARPORT_PC_FIFO is not set
+# CONFIG_PARPORT_PC_SUPERIO is not set
+CONFIG_PARPORT_PC_PCMCIA=m
+CONFIG_PARPORT_NOT_PC=y
+# CONFIG_PARPORT_GSC is not set
+# CONFIG_PARPORT_AX88796 is not set
+CONFIG_PARPORT_1284=y
+
+#
+# Plug and Play support
+#
+CONFIG_PNP=y
+# CONFIG_PNP_DEBUG is not set
+
+#
+# Protocols
+#
+CONFIG_PNPACPI=y
+
+#
+# Block devices
+#
+CONFIG_BLK_DEV_FD=m
+CONFIG_PARIDE=m
+CONFIG_PARIDE_PARPORT=m
+
+#
+# Parallel IDE high-level drivers
+#
+CONFIG_PARIDE_PD=m
+CONFIG_PARIDE_PCD=m
+CONFIG_PARIDE_PF=m
+CONFIG_PARIDE_PT=m
+CONFIG_PARIDE_PG=m
+
+#
+# Parallel IDE protocol modules
+#
+CONFIG_PARIDE_ATEN=m
+CONFIG_PARIDE_BPCK=m
+CONFIG_PARIDE_BPCK6=m
+CONFIG_PARIDE_COMM=m
+CONFIG_PARIDE_DSTR=m
+CONFIG_PARIDE_FIT2=m
+CONFIG_PARIDE_FIT3=m
+CONFIG_PARIDE_EPAT=m
+CONFIG_PARIDE_EPATC8=y
+CONFIG_PARIDE_EPIA=m
+CONFIG_PARIDE_FRIQ=m
+CONFIG_PARIDE_FRPW=m
+CONFIG_PARIDE_KBIC=m
+CONFIG_PARIDE_KTTI=m
+CONFIG_PARIDE_ON20=m
+CONFIG_PARIDE_ON26=m
+CONFIG_BLK_CPQ_DA=m
+CONFIG_BLK_CPQ_CISS_DA=m
+CONFIG_CISS_SCSI_TAPE=y
+CONFIG_BLK_DEV_DAC960=m
+CONFIG_BLK_DEV_UMEM=m
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=m
+CONFIG_BLK_DEV_CRYPTOLOOP=m
+CONFIG_BLK_DEV_NBD=m
+CONFIG_BLK_DEV_SX8=m
+CONFIG_BLK_DEV_UB=m
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=16384
+CONFIG_BLK_DEV_RAM_BLOCKSIZE=4096
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_CDROM_PKTCDVD=m
+CONFIG_CDROM_PKTCDVD_BUFFERS=8
+# CONFIG_CDROM_PKTCDVD_WCACHE is not set
+CONFIG_ATA_OVER_ETH=m
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+CONFIG_IDE=y
+CONFIG_BLK_DEV_IDE=y
+
+#
+# Please see Documentation/ide.txt for help/info on IDE drives
+#
+# CONFIG_BLK_DEV_IDE_SATA is not set
+# CONFIG_BLK_DEV_HD_IDE is not set
+CONFIG_BLK_DEV_IDEDISK=y
+CONFIG_IDEDISK_MULTI_MODE=y
+CONFIG_BLK_DEV_IDECS=m
+CONFIG_BLK_DEV_IDECD=m
+# CONFIG_BLK_DEV_IDETAPE is not set
+CONFIG_BLK_DEV_IDEFLOPPY=y
+CONFIG_BLK_DEV_IDESCSI=m
+CONFIG_IDE_TASK_IOCTL=y
+
+#
+# IDE chipset support/bugfixes
+#
+CONFIG_IDE_GENERIC=y
+CONFIG_BLK_DEV_CMD640=y
+CONFIG_BLK_DEV_CMD640_ENHANCED=y
+CONFIG_BLK_DEV_IDEPNP=y
+CONFIG_BLK_DEV_IDEPCI=y
+CONFIG_IDEPCI_SHARE_IRQ=y
+# CONFIG_BLK_DEV_OFFBOARD is not set
+CONFIG_BLK_DEV_GENERIC=y
+# CONFIG_BLK_DEV_OPTI621 is not set
+CONFIG_BLK_DEV_RZ1000=y
+CONFIG_BLK_DEV_IDEDMA_PCI=y
+# CONFIG_BLK_DEV_IDEDMA_FORCED is not set
+CONFIG_IDEDMA_PCI_AUTO=y
+# CONFIG_IDEDMA_ONLYDISK is not set
+CONFIG_BLK_DEV_AEC62XX=y
+CONFIG_BLK_DEV_ALI15X3=y
+# CONFIG_WDC_ALI15X3 is not set
+CONFIG_BLK_DEV_AMD74XX=y
+CONFIG_BLK_DEV_ATIIXP=y
+CONFIG_BLK_DEV_CMD64X=y
+CONFIG_BLK_DEV_TRIFLEX=y
+# CONFIG_BLK_DEV_CY82C693 is not set
+CONFIG_BLK_DEV_CS5520=y
+CONFIG_BLK_DEV_CS5530=y
+CONFIG_BLK_DEV_CS5535=y
+CONFIG_BLK_DEV_HPT34X=y
+# CONFIG_HPT34X_AUTODMA is not set
+CONFIG_BLK_DEV_HPT366=y
+# CONFIG_BLK_DEV_SC1200 is not set
+CONFIG_BLK_DEV_PIIX=y
+CONFIG_BLK_DEV_IT821X=y
+# CONFIG_BLK_DEV_NS87415 is not set
+CONFIG_BLK_DEV_PDC202XX_OLD=y
+# CONFIG_PDC202XX_BURST is not set
+CONFIG_BLK_DEV_PDC202XX_NEW=y
+CONFIG_BLK_DEV_SVWKS=y
+CONFIG_BLK_DEV_SIIMAGE=y
+CONFIG_BLK_DEV_SIS5513=y
+# CONFIG_BLK_DEV_SLC90E66 is not set
+# CONFIG_BLK_DEV_TRM290 is not set
+CONFIG_BLK_DEV_VIA82CXXX=y
+# CONFIG_IDE_ARM is not set
+CONFIG_BLK_DEV_IDEDMA=y
+# CONFIG_IDEDMA_IVB is not set
+CONFIG_IDEDMA_AUTO=y
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# SCSI device support
+#
+CONFIG_RAID_ATTRS=m
+CONFIG_SCSI=m
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=m
+CONFIG_CHR_DEV_ST=m
+CONFIG_CHR_DEV_OSST=m
+CONFIG_BLK_DEV_SR=m
+CONFIG_BLK_DEV_SR_VENDOR=y
+CONFIG_CHR_DEV_SG=m
+CONFIG_CHR_DEV_SCH=m
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+CONFIG_SCSI_MULTI_LUN=y
+CONFIG_SCSI_CONSTANTS=y
+CONFIG_SCSI_LOGGING=y
+
+#
+# SCSI Transport Attributes
+#
+CONFIG_SCSI_SPI_ATTRS=m
+CONFIG_SCSI_FC_ATTRS=m
+CONFIG_SCSI_ISCSI_ATTRS=m
+CONFIG_SCSI_SAS_ATTRS=m
+
+#
+# SCSI low-level drivers
+#
+CONFIG_ISCSI_TCP=m
+CONFIG_BLK_DEV_3W_XXXX_RAID=m
+CONFIG_SCSI_3W_9XXX=m
+CONFIG_SCSI_ACARD=m
+CONFIG_SCSI_AACRAID=m
+CONFIG_SCSI_AIC7XXX=m
+CONFIG_AIC7XXX_CMDS_PER_DEVICE=4
+CONFIG_AIC7XXX_RESET_DELAY_MS=15000
+# CONFIG_AIC7XXX_DEBUG_ENABLE is not set
+CONFIG_AIC7XXX_DEBUG_MASK=0
+# CONFIG_AIC7XXX_REG_PRETTY_PRINT is not set
+CONFIG_SCSI_AIC7XXX_OLD=m
+CONFIG_SCSI_AIC79XX=m
+CONFIG_AIC79XX_CMDS_PER_DEVICE=4
+CONFIG_AIC79XX_RESET_DELAY_MS=15000
+# CONFIG_AIC79XX_ENABLE_RD_STRM is not set
+# CONFIG_AIC79XX_DEBUG_ENABLE is not set
+CONFIG_AIC79XX_DEBUG_MASK=0
+# CONFIG_AIC79XX_REG_PRETTY_PRINT is not set
+# CONFIG_SCSI_DPT_I2O is not set
+CONFIG_SCSI_ADVANSYS=m
+CONFIG_MEGARAID_NEWGEN=y
+CONFIG_MEGARAID_MM=m
+CONFIG_MEGARAID_MAILBOX=m
+CONFIG_MEGARAID_LEGACY=m
+CONFIG_MEGARAID_SAS=m
+CONFIG_SCSI_SATA=m
+CONFIG_SCSI_SATA_AHCI=m
+CONFIG_SCSI_SATA_SVW=m
+CONFIG_SCSI_ATA_PIIX=m
+CONFIG_SCSI_SATA_MV=m
+CONFIG_SCSI_SATA_NV=m
+CONFIG_SCSI_PDC_ADMA=m
+CONFIG_SCSI_HPTIOP=m
+CONFIG_SCSI_SATA_QSTOR=m
+CONFIG_SCSI_SATA_PROMISE=m
+CONFIG_SCSI_SATA_SX4=m
+CONFIG_SCSI_SATA_SIL=m
+CONFIG_SCSI_SATA_SIL24=m
+CONFIG_SCSI_SATA_SIS=m
+CONFIG_SCSI_SATA_ULI=m
+CONFIG_SCSI_SATA_VIA=m
+CONFIG_SCSI_SATA_VITESSE=m
+CONFIG_SCSI_SATA_INTEL_COMBINED=y
+CONFIG_SCSI_BUSLOGIC=m
+# CONFIG_SCSI_OMIT_FLASHPOINT is not set
+# CONFIG_SCSI_DMX3191D is not set
+# CONFIG_SCSI_EATA is not set
+CONFIG_SCSI_FUTURE_DOMAIN=m
+CONFIG_SCSI_GDTH=m
+CONFIG_SCSI_IPS=m
+CONFIG_SCSI_INITIO=m
+CONFIG_SCSI_INIA100=m
+CONFIG_SCSI_PPA=m
+CONFIG_SCSI_IMM=m
+# CONFIG_SCSI_IZIP_EPP16 is not set
+# CONFIG_SCSI_IZIP_SLOW_CTR is not set
+CONFIG_SCSI_SYM53C8XX_2=m
+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_QLOGIC_1280=m
+CONFIG_SCSI_QLA_FC=m
+CONFIG_SCSI_LPFC=m
+CONFIG_SCSI_DC395x=m
+CONFIG_SCSI_DC390T=m
+# CONFIG_SCSI_NSP32 is not set
+# CONFIG_SCSI_DEBUG is not set
+
+#
+# PCMCIA SCSI adapter support
+#
+CONFIG_PCMCIA_AHA152X=m
+CONFIG_PCMCIA_FDOMAIN=m
+CONFIG_PCMCIA_NINJA_SCSI=m
+CONFIG_PCMCIA_QLOGIC=m
+CONFIG_PCMCIA_SYM53C500=m
+
+#
+# Multi-device support (RAID and LVM)
+#
+CONFIG_MD=y
+CONFIG_BLK_DEV_MD=y
+CONFIG_MD_LINEAR=m
+CONFIG_MD_RAID0=m
+CONFIG_MD_RAID1=m
+CONFIG_MD_RAID10=m
+CONFIG_MD_RAID456=m
+CONFIG_MD_RAID5_RESHAPE=y
+CONFIG_MD_MULTIPATH=m
+CONFIG_MD_FAULTY=m
+CONFIG_BLK_DEV_DM=m
+CONFIG_DM_CRYPT=m
+CONFIG_DM_SNAPSHOT=m
+CONFIG_DM_MIRROR=m
+CONFIG_DM_ZERO=m
+CONFIG_DM_MULTIPATH=m
+CONFIG_DM_MULTIPATH_EMC=m
+
+#
+# Fusion MPT device support
+#
+CONFIG_FUSION=y
+CONFIG_FUSION_SPI=m
+CONFIG_FUSION_FC=m
+CONFIG_FUSION_SAS=m
+CONFIG_FUSION_MAX_SGE=40
+CONFIG_FUSION_CTL=m
+CONFIG_FUSION_LAN=m
+
+#
+# IEEE 1394 (FireWire) support
+#
+CONFIG_IEEE1394=m
+
+#
+# Subsystem Options
+#
+# CONFIG_IEEE1394_VERBOSEDEBUG is not set
+CONFIG_IEEE1394_OUI_DB=y
+CONFIG_IEEE1394_EXTRA_CONFIG_ROMS=y
+CONFIG_IEEE1394_CONFIG_ROM_IP1394=y
+# CONFIG_IEEE1394_EXPORT_FULL_API is not set
+
+#
+# Device Drivers
+#
+CONFIG_IEEE1394_PCILYNX=m
+CONFIG_IEEE1394_OHCI1394=m
+
+#
+# Protocol Drivers
+#
+CONFIG_IEEE1394_VIDEO1394=m
+CONFIG_IEEE1394_SBP2=m
+# CONFIG_IEEE1394_SBP2_PHYS_DMA is not set
+CONFIG_IEEE1394_ETH1394=m
+CONFIG_IEEE1394_DV1394=m
+CONFIG_IEEE1394_RAWIO=m
+
+#
+# I2O device support
+#
+CONFIG_I2O=m
+# CONFIG_I2O_LCT_NOTIFY_ON_CHANGES is not set
+CONFIG_I2O_EXT_ADAPTEC=y
+CONFIG_I2O_CONFIG=m
+CONFIG_I2O_CONFIG_OLD_IOCTL=y
+CONFIG_I2O_BUS=m
+CONFIG_I2O_BLOCK=m
+CONFIG_I2O_SCSI=m
+CONFIG_I2O_PROC=m
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+CONFIG_IFB=m
+CONFIG_DUMMY=m
+CONFIG_BONDING=m
+CONFIG_EQUALIZER=m
+CONFIG_TUN=m
+CONFIG_NET_SB1000=m
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+
+#
+# PHY device support
+#
+CONFIG_PHYLIB=m
+
+#
+# MII PHY device drivers
+#
+CONFIG_MARVELL_PHY=m
+CONFIG_DAVICOM_PHY=m
+CONFIG_QSEMI_PHY=m
+CONFIG_LXT_PHY=m
+CONFIG_CICADA_PHY=m
+CONFIG_VITESSE_PHY=m
+CONFIG_SMSC_PHY=m
+CONFIG_FIXED_PHY=m
+CONFIG_FIXED_MII_10_FDX=y
+CONFIG_FIXED_MII_100_FDX=y
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=m
+CONFIG_HAPPYMEAL=m
+CONFIG_SUNGEM=m
+CONFIG_CASSINI=m
+CONFIG_NET_VENDOR_3COM=y
+CONFIG_VORTEX=m
+CONFIG_TYPHOON=m
+
+#
+# Tulip family network device support
+#
+CONFIG_NET_TULIP=y
+CONFIG_DE2104X=m
+CONFIG_TULIP=m
+# CONFIG_TULIP_MWI is not set
+CONFIG_TULIP_MMIO=y
+# CONFIG_TULIP_NAPI is not set
+CONFIG_DE4X5=m
+CONFIG_WINBOND_840=m
+CONFIG_DM9102=m
+CONFIG_ULI526X=m
+CONFIG_PCMCIA_XIRCOM=m
+# CONFIG_HP100 is not set
+CONFIG_NET_PCI=y
+CONFIG_PCNET32=m
+CONFIG_AMD8111_ETH=m
+CONFIG_AMD8111E_NAPI=y
+CONFIG_ADAPTEC_STARFIRE=m
+CONFIG_ADAPTEC_STARFIRE_NAPI=y
+CONFIG_B44=m
+CONFIG_FORCEDETH=m
+# CONFIG_DGRS is not set
+# CONFIG_EEPRO100 is not set
+CONFIG_E100=m
+CONFIG_FEALNX=m
+CONFIG_NATSEMI=m
+CONFIG_NE2K_PCI=m
+CONFIG_8139CP=m
+CONFIG_8139TOO=m
+# CONFIG_8139TOO_PIO is not set
+# CONFIG_8139TOO_TUNE_TWISTER is not set
+CONFIG_8139TOO_8129=y
+# CONFIG_8139_OLD_RX_RESET is not set
+CONFIG_SIS900=m
+CONFIG_EPIC100=m
+CONFIG_SUNDANCE=m
+# CONFIG_SUNDANCE_MMIO is not set
+CONFIG_TLAN=m
+CONFIG_VIA_RHINE=m
+CONFIG_VIA_RHINE_MMIO=y
+CONFIG_VIA_RHINE_NAPI=y
+CONFIG_NET_POCKET=y
+CONFIG_ATP=m
+CONFIG_DE600=m
+CONFIG_DE620=m
+
+#
+# Ethernet (1000 Mbit)
+#
+CONFIG_ACENIC=m
+# CONFIG_ACENIC_OMIT_TIGON_I is not set
+CONFIG_DL2K=m
+CONFIG_E1000=m
+CONFIG_E1000_NAPI=y
+# CONFIG_E1000_DISABLE_PACKET_SPLIT is not set
+CONFIG_NS83820=m
+CONFIG_HAMACHI=m
+CONFIG_YELLOWFIN=m
+CONFIG_R8169=m
+CONFIG_R8169_NAPI=y
+CONFIG_R8169_VLAN=y
+CONFIG_SIS190=m
+CONFIG_SKGE=m
+CONFIG_SKY2=m
+# CONFIG_SK98LIN is not set
+CONFIG_VIA_VELOCITY=m
+CONFIG_TIGON3=m
+CONFIG_BNX2=m
+
+#
+# Ethernet (10000 Mbit)
+#
+CONFIG_CHELSIO_T1=m
+CONFIG_IXGB=m
+CONFIG_IXGB_NAPI=y
+CONFIG_S2IO=m
+CONFIG_S2IO_NAPI=y
+CONFIG_MYRI10GE=m
+
+#
+# Token Ring devices
+#
+CONFIG_TR=y
+CONFIG_IBMOL=m
+CONFIG_IBMLS=m
+CONFIG_3C359=m
+# CONFIG_TMS380TR is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+CONFIG_NET_RADIO=y
+CONFIG_NET_WIRELESS_RTNETLINK=y
+
+#
+# Obsolete Wireless cards support (pre-802.11)
+#
+# CONFIG_STRIP is not set
+CONFIG_PCMCIA_WAVELAN=m
+CONFIG_PCMCIA_NETWAVE=m
+
+#
+# Wireless 802.11 Frequency Hopping cards support
+#
+# CONFIG_PCMCIA_RAYCS is not set
+
+#
+# Wireless 802.11b ISA/PCI cards support
+#
+CONFIG_IPW2100=m
+CONFIG_IPW2100_MONITOR=y
+# CONFIG_IPW2100_DEBUG is not set
+CONFIG_IPW2200=m
+CONFIG_IPW2200_MONITOR=y
+CONFIG_IPW2200_RADIOTAP=y
+CONFIG_IPW2200_PROMISCUOUS=y
+CONFIG_IPW2200_QOS=y
+# CONFIG_IPW2200_DEBUG is not set
+CONFIG_AIRO=m
+CONFIG_HERMES=m
+CONFIG_PLX_HERMES=m
+CONFIG_TMD_HERMES=m
+CONFIG_NORTEL_HERMES=m
+CONFIG_PCI_HERMES=m
+CONFIG_ATMEL=m
+CONFIG_PCI_ATMEL=m
+
+#
+# Wireless 802.11b Pcmcia/Cardbus cards support
+#
+CONFIG_PCMCIA_HERMES=m
+CONFIG_PCMCIA_SPECTRUM=m
+CONFIG_AIRO_CS=m
+CONFIG_PCMCIA_ATMEL=m
+CONFIG_PCMCIA_WL3501=m
+
+#
+# Prism GT/Duette 802.11(a/b/g) PCI/Cardbus support
+#
+CONFIG_PRISM54=m
+CONFIG_USB_ZD1201=m
+CONFIG_HOSTAP=m
+CONFIG_HOSTAP_FIRMWARE=y
+CONFIG_HOSTAP_FIRMWARE_NVRAM=y
+CONFIG_HOSTAP_PLX=m
+CONFIG_HOSTAP_PCI=m
+CONFIG_HOSTAP_CS=m
+CONFIG_BCM43XX=m
+CONFIG_BCM43XX_DEBUG=y
+CONFIG_BCM43XX_DMA=y
+CONFIG_BCM43XX_PIO=y
+CONFIG_BCM43XX_DMA_AND_PIO_MODE=y
+# CONFIG_BCM43XX_DMA_MODE is not set
+# CONFIG_BCM43XX_PIO_MODE is not set
+CONFIG_ZD1211RW=m
+# CONFIG_ZD1211RW_DEBUG is not set
+CONFIG_NET_WIRELESS=y
+
+#
+# PCMCIA network device support
+#
+CONFIG_NET_PCMCIA=y
+CONFIG_PCMCIA_3C589=m
+CONFIG_PCMCIA_3C574=m
+CONFIG_PCMCIA_FMVJ18X=m
+CONFIG_PCMCIA_PCNET=m
+CONFIG_PCMCIA_NMCLAN=m
+CONFIG_PCMCIA_SMC91C92=m
+CONFIG_PCMCIA_XIRC2PS=m
+CONFIG_PCMCIA_AXNET=m
+CONFIG_PCMCIA_IBMTR=m
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+
+#
+# ATM drivers
+#
+# CONFIG_ATM_DUMMY is not set
+CONFIG_ATM_TCP=m
+CONFIG_ATM_LANAI=m
+CONFIG_ATM_ENI=m
+# CONFIG_ATM_ENI_DEBUG is not set
+# CONFIG_ATM_ENI_TUNE_BURST is not set
+CONFIG_ATM_FIRESTREAM=m
+# CONFIG_ATM_ZATM is not set
+CONFIG_ATM_NICSTAR=m
+# CONFIG_ATM_NICSTAR_USE_SUNI is not set
+# CONFIG_ATM_NICSTAR_USE_IDT77105 is not set
+CONFIG_ATM_IDT77252=m
+# CONFIG_ATM_IDT77252_DEBUG is not set
+# CONFIG_ATM_IDT77252_RCV_ALL is not set
+CONFIG_ATM_IDT77252_USE_SUNI=y
+CONFIG_ATM_AMBASSADOR=m
+# CONFIG_ATM_AMBASSADOR_DEBUG is not set
+CONFIG_ATM_HORIZON=m
+# CONFIG_ATM_HORIZON_DEBUG is not set
+# CONFIG_ATM_IA is not set
+CONFIG_ATM_FORE200E_MAYBE=m
+# CONFIG_ATM_FORE200E_PCA is not set
+CONFIG_ATM_HE=m
+# CONFIG_ATM_HE_USE_SUNI is not set
+CONFIG_FDDI=y
+# CONFIG_DEFXX is not set
+CONFIG_SKFP=m
+# CONFIG_HIPPI is not set
+CONFIG_PLIP=m
+CONFIG_PPP=m
+CONFIG_PPP_MULTILINK=y
+CONFIG_PPP_FILTER=y
+CONFIG_PPP_ASYNC=m
+CONFIG_PPP_SYNC_TTY=m
+CONFIG_PPP_DEFLATE=m
+# CONFIG_PPP_BSDCOMP is not set
+CONFIG_PPP_MPPE=m
+CONFIG_PPPOE=m
+CONFIG_PPPOATM=m
+CONFIG_SLIP=m
+CONFIG_SLIP_COMPRESSED=y
+CONFIG_SLIP_SMART=y
+# CONFIG_SLIP_MODE_SLIP6 is not set
+CONFIG_NET_FC=y
+# CONFIG_SHAPER is not set
+CONFIG_NETCONSOLE=m
+CONFIG_NETPOLL=y
+# CONFIG_NETPOLL_RX is not set
+CONFIG_NETPOLL_TRAP=y
+CONFIG_NET_POLL_CONTROLLER=y
+
+#
+# ISDN subsystem
+#
+CONFIG_ISDN=m
+
+#
+# Old ISDN4Linux
+#
+CONFIG_ISDN_I4L=m
+CONFIG_ISDN_PPP=y
+CONFIG_ISDN_PPP_VJ=y
+CONFIG_ISDN_MPP=y
+CONFIG_IPPP_FILTER=y
+# CONFIG_ISDN_PPP_BSDCOMP is not set
+CONFIG_ISDN_AUDIO=y
+CONFIG_ISDN_TTY_FAX=y
+
+#
+# ISDN feature submodules
+#
+CONFIG_ISDN_DIVERSION=m
+
+#
+# ISDN4Linux hardware drivers
+#
+
+#
+# Passive cards
+#
+CONFIG_ISDN_DRV_HISAX=m
+
+#
+# D-channel protocol features
+#
+CONFIG_HISAX_EURO=y
+CONFIG_DE_AOC=y
+CONFIG_HISAX_NO_SENDCOMPLETE=y
+CONFIG_HISAX_NO_LLC=y
+CONFIG_HISAX_NO_KEYPAD=y
+CONFIG_HISAX_1TR6=y
+CONFIG_HISAX_NI1=y
+CONFIG_HISAX_MAX_CARDS=8
+
+#
+# HiSax supported cards
+#
+CONFIG_HISAX_16_3=y
+CONFIG_HISAX_TELESPCI=y
+CONFIG_HISAX_S0BOX=y
+CONFIG_HISAX_FRITZPCI=y
+CONFIG_HISAX_AVM_A1_PCMCIA=y
+CONFIG_HISAX_ELSA=y
+CONFIG_HISAX_DIEHLDIVA=y
+CONFIG_HISAX_SEDLBAUER=y
+CONFIG_HISAX_NETJET=y
+CONFIG_HISAX_NETJET_U=y
+CONFIG_HISAX_NICCY=y
+CONFIG_HISAX_BKM_A4T=y
+CONFIG_HISAX_SCT_QUADRO=y
+CONFIG_HISAX_GAZEL=y
+CONFIG_HISAX_HFC_PCI=y
+CONFIG_HISAX_W6692=y
+CONFIG_HISAX_HFC_SX=y
+CONFIG_HISAX_ENTERNOW_PCI=y
+# CONFIG_HISAX_DEBUG is not set
+
+#
+# HiSax PCMCIA card service modules
+#
+CONFIG_HISAX_SEDLBAUER_CS=m
+CONFIG_HISAX_ELSA_CS=m
+CONFIG_HISAX_AVM_A1_CS=m
+CONFIG_HISAX_TELES_CS=m
+
+#
+# HiSax sub driver modules
+#
+CONFIG_HISAX_ST5481=m
+# CONFIG_HISAX_HFCUSB is not set
+CONFIG_HISAX_HFC4S8S=m
+CONFIG_HISAX_FRITZ_PCIPNP=m
+CONFIG_HISAX_HDLC=y
+
+#
+# Active cards
+#
+
+#
+# Siemens Gigaset
+#
+CONFIG_ISDN_DRV_GIGASET=m
+CONFIG_GIGASET_BASE=m
+CONFIG_GIGASET_M105=m
+# CONFIG_GIGASET_DEBUG is not set
+# CONFIG_GIGASET_UNDOCREQ is not set
+
+#
+# CAPI subsystem
+#
+CONFIG_ISDN_CAPI=m
+CONFIG_ISDN_DRV_AVMB1_VERBOSE_REASON=y
+CONFIG_ISDN_CAPI_MIDDLEWARE=y
+CONFIG_ISDN_CAPI_CAPI20=m
+CONFIG_ISDN_CAPI_CAPIFS_BOOL=y
+CONFIG_ISDN_CAPI_CAPIFS=m
+CONFIG_ISDN_CAPI_CAPIDRV=m
+
+#
+# CAPI hardware drivers
+#
+
+#
+# Active AVM cards
+#
+CONFIG_CAPI_AVM=y
+CONFIG_ISDN_DRV_AVMB1_B1PCI=m
+CONFIG_ISDN_DRV_AVMB1_B1PCIV4=y
+CONFIG_ISDN_DRV_AVMB1_B1PCMCIA=m
+CONFIG_ISDN_DRV_AVMB1_AVM_CS=m
+CONFIG_ISDN_DRV_AVMB1_T1PCI=m
+CONFIG_ISDN_DRV_AVMB1_C4=m
+
+#
+# Active Eicon DIVA Server cards
+#
+CONFIG_CAPI_EICON=y
+CONFIG_ISDN_DIVAS=m
+CONFIG_ISDN_DIVAS_BRIPCI=y
+CONFIG_ISDN_DIVAS_PRIPCI=y
+CONFIG_ISDN_DIVAS_DIVACAPI=m
+CONFIG_ISDN_DIVAS_USERIDI=m
+CONFIG_ISDN_DIVAS_MAINT=m
+
+#
+# Telephony Support
+#
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+
+#
+# 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=m
+# CONFIG_INPUT_TSDEV is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+CONFIG_KEYBOARD_ATKBD=y
+# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_KEYBOARD_LKKBD is not set
+# CONFIG_KEYBOARD_XTKBD is not set
+# CONFIG_KEYBOARD_NEWTON is not set
+CONFIG_INPUT_MOUSE=y
+CONFIG_MOUSE_PS2=y
+CONFIG_MOUSE_SERIAL=m
+CONFIG_MOUSE_VSXXXAA=m
+CONFIG_INPUT_JOYSTICK=y
+CONFIG_JOYSTICK_ANALOG=m
+CONFIG_JOYSTICK_A3D=m
+CONFIG_JOYSTICK_ADI=m
+CONFIG_JOYSTICK_COBRA=m
+CONFIG_JOYSTICK_GF2K=m
+CONFIG_JOYSTICK_GRIP=m
+CONFIG_JOYSTICK_GRIP_MP=m
+CONFIG_JOYSTICK_GUILLEMOT=m
+CONFIG_JOYSTICK_INTERACT=m
+CONFIG_JOYSTICK_SIDEWINDER=m
+CONFIG_JOYSTICK_TMDC=m
+CONFIG_JOYSTICK_IFORCE=m
+CONFIG_JOYSTICK_IFORCE_USB=y
+CONFIG_JOYSTICK_IFORCE_232=y
+CONFIG_JOYSTICK_WARRIOR=m
+CONFIG_JOYSTICK_MAGELLAN=m
+CONFIG_JOYSTICK_SPACEORB=m
+CONFIG_JOYSTICK_SPACEBALL=m
+CONFIG_JOYSTICK_STINGER=m
+CONFIG_JOYSTICK_TWIDJOY=m
+CONFIG_JOYSTICK_DB9=m
+CONFIG_JOYSTICK_GAMECON=m
+CONFIG_JOYSTICK_TURBOGRAFX=m
+CONFIG_JOYSTICK_JOYDUMP=m
+CONFIG_INPUT_TOUCHSCREEN=y
+CONFIG_TOUCHSCREEN_GUNZE=m
+CONFIG_TOUCHSCREEN_ELO=m
+CONFIG_TOUCHSCREEN_MTOUCH=m
+CONFIG_TOUCHSCREEN_MK712=m
+CONFIG_INPUT_MISC=y
+CONFIG_INPUT_PCSPKR=m
+CONFIG_INPUT_WISTRON_BTNS=m
+CONFIG_INPUT_UINPUT=m
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+CONFIG_SERIO_I8042=y
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_CT82C710 is not set
+# CONFIG_SERIO_PARKBD is not set
+# CONFIG_SERIO_PCIPS2 is not set
+CONFIG_SERIO_LIBPS2=y
+CONFIG_SERIO_RAW=m
+CONFIG_GAMEPORT=m
+CONFIG_GAMEPORT_NS558=m
+CONFIG_GAMEPORT_L4=m
+CONFIG_GAMEPORT_EMU10K1=m
+CONFIG_GAMEPORT_FM801=m
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+CONFIG_VT_HW_CONSOLE_BINDING=y
+CONFIG_SERIAL_NONSTANDARD=y
+# CONFIG_COMPUTONE is not set
+# CONFIG_ROCKETPORT is not set
+CONFIG_CYCLADES=m
+# CONFIG_CYZ_INTR is not set
+# CONFIG_DIGIEPCA is not set
+# CONFIG_MOXA_INTELLIO is not set
+# CONFIG_MOXA_SMARTIO is not set
+# CONFIG_ISI is not set
+CONFIG_SYNCLINK=m
+CONFIG_SYNCLINKMP=m
+CONFIG_SYNCLINK_GT=m
+CONFIG_N_HDLC=m
+# CONFIG_SPECIALIX is not set
+# CONFIG_SX is not set
+# CONFIG_RIO is not set
+# CONFIG_STALDRV is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=m
+CONFIG_SERIAL_8250_PCI=m
+CONFIG_SERIAL_8250_PNP=m
+CONFIG_SERIAL_8250_CS=m
+CONFIG_SERIAL_8250_NR_UARTS=32
+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=y
+CONFIG_SERIAL_8250_RSA=y
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_CORE=m
+CONFIG_SERIAL_JSM=m
+CONFIG_UNIX98_PTYS=y
+# CONFIG_LEGACY_PTYS is not set
+CONFIG_CRASH=m
+CONFIG_PRINTER=m
+CONFIG_LP_CONSOLE=y
+CONFIG_PPDEV=m
+CONFIG_TIPAR=m
+
+#
+# IPMI
+#
+CONFIG_IPMI_HANDLER=m
+# CONFIG_IPMI_PANIC_EVENT is not set
+CONFIG_IPMI_DEVICE_INTERFACE=m
+CONFIG_IPMI_SI=m
+CONFIG_IPMI_WATCHDOG=m
+CONFIG_IPMI_POWEROFF=m
+
+#
+# Watchdog Cards
+#
+CONFIG_WATCHDOG=y
+# CONFIG_WATCHDOG_NOWAYOUT is not set
+
+#
+# Watchdog Device Drivers
+#
+CONFIG_SOFT_WATCHDOG=m
+# CONFIG_ACQUIRE_WDT is not set
+# CONFIG_ADVANTECH_WDT is not set
+CONFIG_ALIM1535_WDT=m
+CONFIG_ALIM7101_WDT=m
+# CONFIG_SC520_WDT is not set
+# CONFIG_EUROTECH_WDT is not set
+# CONFIG_IB700_WDT is not set
+CONFIG_IBMASR=m
+# CONFIG_WAFER_WDT is not set
+CONFIG_I6300ESB_WDT=m
+CONFIG_I8XX_TCO=m
+# CONFIG_SC1200_WDT is not set
+# CONFIG_60XX_WDT is not set
+# CONFIG_SBC8360_WDT is not set
+# CONFIG_CPU5_WDT is not set
+CONFIG_W83627HF_WDT=m
+CONFIG_W83877F_WDT=m
+CONFIG_W83977F_WDT=m
+CONFIG_MACHZ_WDT=m
+# CONFIG_SBC_EPX_C3_WATCHDOG is not set
+
+#
+# PCI-based Watchdog Cards
+#
+CONFIG_PCIPCWATCHDOG=m
+CONFIG_WDTPCI=m
+CONFIG_WDT_501_PCI=y
+
+#
+# USB-based Watchdog Cards
+#
+CONFIG_USBPCWATCHDOG=m
+CONFIG_HW_RANDOM=y
+CONFIG_HW_RANDOM_INTEL=m
+CONFIG_HW_RANDOM_AMD=m
+CONFIG_HW_RANDOM_GEODE=m
+CONFIG_HW_RANDOM_VIA=m
+CONFIG_NVRAM=y
+CONFIG_RTC=y
+CONFIG_DTLK=m
+CONFIG_R3964=m
+# CONFIG_APPLICOM is not set
+CONFIG_SONYPI=m
+
+#
+# Ftape, the floppy tape device driver
+#
+CONFIG_AGP=y
+CONFIG_AGP_ALI=y
+CONFIG_AGP_ATI=y
+CONFIG_AGP_AMD=y
+CONFIG_AGP_AMD64=y
+CONFIG_AGP_INTEL=y
+CONFIG_AGP_NVIDIA=y
+CONFIG_AGP_SIS=y
+CONFIG_AGP_SWORKS=y
+CONFIG_AGP_VIA=y
+CONFIG_AGP_EFFICEON=y
+CONFIG_DRM=m
+CONFIG_DRM_TDFX=m
+CONFIG_DRM_R128=m
+CONFIG_DRM_RADEON=m
+CONFIG_DRM_I810=m
+CONFIG_DRM_I830=m
+CONFIG_DRM_I915=m
+CONFIG_DRM_MGA=m
+CONFIG_DRM_SIS=m
+CONFIG_DRM_VIA=m
+CONFIG_DRM_SAVAGE=m
+
+#
+# PCMCIA character devices
+#
+# CONFIG_SYNCLINK_CS is not set
+CONFIG_CARDMAN_4000=m
+CONFIG_CARDMAN_4040=m
+CONFIG_MWAVE=m
+CONFIG_PC8736x_GPIO=m
+CONFIG_NSC_GPIO=m
+CONFIG_CS5535_GPIO=m
+# CONFIG_RAW_DRIVER is not set
+CONFIG_HPET=y
+# CONFIG_HPET_RTC_IRQ is not set
+# CONFIG_HPET_MMAP is not set
+CONFIG_HANGCHECK_TIMER=m
+
+#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+# CONFIG_TELCLOCK is not set
+
+#
+# I2C support
+#
+CONFIG_I2C=m
+CONFIG_I2C_CHARDEV=m
+
+#
+# I2C Algorithms
+#
+CONFIG_I2C_ALGOBIT=m
+CONFIG_I2C_ALGOPCF=m
+CONFIG_I2C_ALGOPCA=m
+
+#
+# I2C Hardware Bus support
+#
+CONFIG_I2C_ALI1535=m
+CONFIG_I2C_ALI1563=m
+CONFIG_I2C_ALI15X3=m
+CONFIG_I2C_AMD756=m
+CONFIG_I2C_AMD756_S4882=m
+CONFIG_I2C_AMD8111=m
+CONFIG_I2C_I801=m
+CONFIG_I2C_I810=m
+CONFIG_I2C_PIIX4=m
+CONFIG_I2C_ISA=m
+CONFIG_I2C_NFORCE2=m
+# CONFIG_I2C_OCORES is not set
+CONFIG_I2C_PARPORT=m
+CONFIG_I2C_PARPORT_LIGHT=m
+CONFIG_I2C_PROSAVAGE=m
+CONFIG_I2C_SAVAGE4=m
+# CONFIG_SCx200_ACB is not set
+CONFIG_I2C_SIS5595=m
+CONFIG_I2C_SIS630=m
+CONFIG_I2C_SIS96X=m
+CONFIG_I2C_STUB=m
+CONFIG_I2C_VIA=m
+CONFIG_I2C_VIAPRO=m
+CONFIG_I2C_VOODOO3=m
+CONFIG_I2C_PCA_ISA=m
+
+#
+# Miscellaneous I2C Chip support
+#
+CONFIG_SENSORS_DS1337=m
+CONFIG_SENSORS_DS1374=m
+CONFIG_SENSORS_EEPROM=m
+CONFIG_SENSORS_PCF8574=m
+CONFIG_SENSORS_PCA9539=m
+CONFIG_SENSORS_PCF8591=m
+CONFIG_SENSORS_MAX6875=m
+# 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 is not set
+# CONFIG_SPI_MASTER is not set
+
+#
+# Dallas's 1-wire bus
+#
+CONFIG_W1=m
+CONFIG_W1_CON=y
+
+#
+# 1-wire Bus Masters
+#
+CONFIG_W1_MASTER_MATROX=m
+CONFIG_W1_MASTER_DS2490=m
+CONFIG_W1_MASTER_DS2482=m
+
+#
+# 1-wire Slaves
+#
+CONFIG_W1_SLAVE_THERM=m
+CONFIG_W1_SLAVE_SMEM=m
+CONFIG_W1_SLAVE_DS2433=m
+CONFIG_W1_SLAVE_DS2433_CRC=y
+
+#
+# Hardware Monitoring support
+#
+CONFIG_HWMON=m
+CONFIG_HWMON_VID=m
+CONFIG_SENSORS_ABITUGURU=m
+CONFIG_SENSORS_ADM1021=m
+CONFIG_SENSORS_ADM1025=m
+CONFIG_SENSORS_ADM1026=m
+CONFIG_SENSORS_ADM1031=m
+CONFIG_SENSORS_ADM9240=m
+CONFIG_SENSORS_ASB100=m
+CONFIG_SENSORS_ATXP1=m
+CONFIG_SENSORS_DS1621=m
+CONFIG_SENSORS_F71805F=m
+CONFIG_SENSORS_FSCHER=m
+CONFIG_SENSORS_FSCPOS=m
+CONFIG_SENSORS_GL518SM=m
+CONFIG_SENSORS_GL520SM=m
+CONFIG_SENSORS_IT87=m
+CONFIG_SENSORS_LM63=m
+CONFIG_SENSORS_LM75=m
+CONFIG_SENSORS_LM77=m
+CONFIG_SENSORS_LM78=m
+CONFIG_SENSORS_LM80=m
+CONFIG_SENSORS_LM83=m
+CONFIG_SENSORS_LM85=m
+CONFIG_SENSORS_LM87=m
+CONFIG_SENSORS_LM90=m
+CONFIG_SENSORS_LM92=m
+CONFIG_SENSORS_MAX1619=m
+CONFIG_SENSORS_PC87360=m
+CONFIG_SENSORS_SIS5595=m
+CONFIG_SENSORS_SMSC47M1=m
+CONFIG_SENSORS_SMSC47M192=m
+CONFIG_SENSORS_SMSC47B397=m
+CONFIG_SENSORS_VIA686A=m
+CONFIG_SENSORS_VT8231=m
+CONFIG_SENSORS_W83781D=m
+CONFIG_SENSORS_W83791D=m
+CONFIG_SENSORS_W83792D=m
+CONFIG_SENSORS_W83L785TS=m
+CONFIG_SENSORS_W83627HF=m
+CONFIG_SENSORS_W83627EHF=m
+CONFIG_SENSORS_HDAPS=m
+# CONFIG_HWMON_DEBUG_CHIP is not set
+
+#
+# Misc devices
+#
+CONFIG_IBM_ASM=m
+
+#
+# Multimedia devices
+#
+CONFIG_VIDEO_DEV=m
+CONFIG_VIDEO_V4L1=y
+CONFIG_VIDEO_V4L1_COMPAT=y
+CONFIG_VIDEO_V4L2=y
+
+#
+# Video Capture Adapters
+#
+
+#
+# Video Capture Adapters
+#
+# CONFIG_VIDEO_ADV_DEBUG is not set
+# CONFIG_VIDEO_VIVI is not set
+CONFIG_VIDEO_BT848=m
+CONFIG_VIDEO_BT848_DVB=y
+CONFIG_VIDEO_SAA6588=m
+CONFIG_VIDEO_BWQCAM=m
+CONFIG_VIDEO_CQCAM=m
+CONFIG_VIDEO_W9966=m
+CONFIG_VIDEO_CPIA=m
+CONFIG_VIDEO_CPIA_PP=m
+CONFIG_VIDEO_CPIA_USB=m
+CONFIG_VIDEO_CPIA2=m
+CONFIG_VIDEO_SAA5246A=m
+CONFIG_VIDEO_SAA5249=m
+CONFIG_TUNER_3036=m
+CONFIG_VIDEO_STRADIS=m
+CONFIG_VIDEO_ZORAN=m
+CONFIG_VIDEO_ZORAN_BUZ=m
+CONFIG_VIDEO_ZORAN_DC10=m
+CONFIG_VIDEO_ZORAN_DC30=m
+CONFIG_VIDEO_ZORAN_LML33=m
+CONFIG_VIDEO_ZORAN_LML33R10=m
+CONFIG_VIDEO_ZORAN_AVS6EYES=m
+CONFIG_VIDEO_MEYE=m
+CONFIG_VIDEO_SAA7134=m
+CONFIG_VIDEO_SAA7134_ALSA=m
+CONFIG_VIDEO_SAA7134_DVB=m
+CONFIG_VIDEO_SAA7134_DVB_ALL_FRONTENDS=y
+CONFIG_VIDEO_MXB=m
+CONFIG_VIDEO_DPC=m
+CONFIG_VIDEO_HEXIUM_ORION=m
+CONFIG_VIDEO_HEXIUM_GEMINI=m
+CONFIG_VIDEO_CX88_VP3054=m
+CONFIG_VIDEO_CX88=m
+CONFIG_VIDEO_CX88_ALSA=m
+CONFIG_VIDEO_CX88_BLACKBIRD=m
+CONFIG_VIDEO_CX88_DVB=m
+CONFIG_VIDEO_CX88_DVB_ALL_FRONTENDS=y
+
+#
+# Encoders and Decoders
+#
+CONFIG_VIDEO_MSP3400=m
+CONFIG_VIDEO_CS53L32A=m
+CONFIG_VIDEO_TLV320AIC23B=m
+CONFIG_VIDEO_WM8775=m
+CONFIG_VIDEO_WM8739=m
+CONFIG_VIDEO_CX2341X=m
+CONFIG_VIDEO_CX25840=m
+CONFIG_VIDEO_SAA711X=m
+CONFIG_VIDEO_SAA7127=m
+CONFIG_VIDEO_UPD64031A=m
+CONFIG_VIDEO_UPD64083=m
+
+#
+# V4L USB devices
+#
+CONFIG_VIDEO_PVRUSB2=m
+CONFIG_VIDEO_PVRUSB2_24XXX=y
+CONFIG_VIDEO_PVRUSB2_SYSFS=y
+# CONFIG_VIDEO_PVRUSB2_DEBUGIFC is not set
+CONFIG_VIDEO_EM28XX=m
+CONFIG_VIDEO_USBVIDEO=m
+CONFIG_USB_VICAM=m
+CONFIG_USB_IBMCAM=m
+CONFIG_USB_KONICAWC=m
+CONFIG_USB_QUICKCAM_MESSENGER=m
+CONFIG_USB_ET61X251=m
+CONFIG_VIDEO_OVCAMCHIP=m
+CONFIG_USB_W9968CF=m
+CONFIG_USB_OV511=m
+CONFIG_USB_SE401=m
+CONFIG_USB_SN9C102=m
+CONFIG_USB_STV680=m
+CONFIG_USB_ZC0301=m
+CONFIG_USB_PWC=m
+# CONFIG_USB_PWC_DEBUG is not set
+
+#
+# Radio Adapters
+#
+CONFIG_RADIO_GEMTEK_PCI=m
+CONFIG_RADIO_MAXIRADIO=m
+CONFIG_RADIO_MAESTRO=m
+CONFIG_USB_DSBR=m
+
+#
+# Digital Video Broadcasting Devices
+#
+CONFIG_DVB=y
+CONFIG_DVB_CORE=m
+
+#
+# Supported SAA7146 based PCI Adapters
+#
+CONFIG_DVB_AV7110=m
+CONFIG_DVB_AV7110_OSD=y
+CONFIG_DVB_BUDGET=m
+CONFIG_DVB_BUDGET_CI=m
+CONFIG_DVB_BUDGET_AV=m
+CONFIG_DVB_BUDGET_PATCH=m
+
+#
+# Supported USB Adapters
+#
+CONFIG_DVB_USB=m
+# CONFIG_DVB_USB_DEBUG is not set
+CONFIG_DVB_USB_A800=m
+CONFIG_DVB_USB_DIBUSB_MB=m
+# CONFIG_DVB_USB_DIBUSB_MB_FAULTY is not set
+CONFIG_DVB_USB_DIBUSB_MC=m
+CONFIG_DVB_USB_UMT_010=m
+CONFIG_DVB_USB_CXUSB=m
+CONFIG_DVB_USB_DIGITV=m
+CONFIG_DVB_USB_VP7045=m
+CONFIG_DVB_USB_VP702X=m
+CONFIG_DVB_USB_GP8PSK=m
+CONFIG_DVB_USB_NOVA_T_USB2=m
+CONFIG_DVB_USB_DTT200U=m
+CONFIG_DVB_TTUSB_BUDGET=m
+CONFIG_DVB_TTUSB_DEC=m
+CONFIG_DVB_CINERGYT2=m
+CONFIG_DVB_CINERGYT2_TUNING=y
+CONFIG_DVB_CINERGYT2_STREAM_URB_COUNT=32
+CONFIG_DVB_CINERGYT2_STREAM_BUF_SIZE=512
+CONFIG_DVB_CINERGYT2_QUERY_INTERVAL=250
+CONFIG_DVB_CINERGYT2_ENABLE_RC_INPUT_DEVICE=y
+CONFIG_DVB_CINERGYT2_RC_QUERY_INTERVAL=100
+
+#
+# Supported FlexCopII (B2C2) Adapters
+#
+CONFIG_DVB_B2C2_FLEXCOP=m
+CONFIG_DVB_B2C2_FLEXCOP_PCI=m
+CONFIG_DVB_B2C2_FLEXCOP_USB=m
+# CONFIG_DVB_B2C2_FLEXCOP_DEBUG is not set
+
+#
+# Supported BT878 Adapters
+#
+CONFIG_DVB_BT8XX=m
+
+#
+# Supported Pluto2 Adapters
+#
+CONFIG_DVB_PLUTO2=m
+
+#
+# Supported DVB Frontends
+#
+
+#
+# Customise DVB Frontends
+#
+
+#
+# DVB-S (satellite) frontends
+#
+CONFIG_DVB_STV0299=m
+CONFIG_DVB_CX24110=m
+CONFIG_DVB_CX24123=m
+CONFIG_DVB_TDA8083=m
+CONFIG_DVB_MT312=m
+CONFIG_DVB_VES1X93=m
+CONFIG_DVB_S5H1420=m
+
+#
+# DVB-T (terrestrial) frontends
+#
+CONFIG_DVB_SP8870=m
+CONFIG_DVB_SP887X=m
+CONFIG_DVB_CX22700=m
+CONFIG_DVB_CX22702=m
+CONFIG_DVB_L64781=m
+CONFIG_DVB_TDA1004X=m
+CONFIG_DVB_NXT6000=m
+CONFIG_DVB_MT352=m
+CONFIG_DVB_ZL10353=m
+CONFIG_DVB_DIB3000MB=m
+CONFIG_DVB_DIB3000MC=m
+
+#
+# DVB-C (cable) frontends
+#
+CONFIG_DVB_VES1820=m
+CONFIG_DVB_TDA10021=m
+CONFIG_DVB_STV0297=m
+
+#
+# ATSC (North American/Korean Terrestrial/Cable DTV) frontends
+#
+CONFIG_DVB_NXT200X=m
+CONFIG_DVB_OR51211=m
+CONFIG_DVB_OR51132=m
+CONFIG_DVB_BCM3510=m
+CONFIG_DVB_LGDT330X=m
+
+#
+# Miscellaneous devices
+#
+CONFIG_DVB_PLL=m
+CONFIG_DVB_LNBP21=m
+CONFIG_DVB_ISL6421=m
+CONFIG_VIDEO_SAA7146=m
+CONFIG_VIDEO_SAA7146_VV=m
+CONFIG_VIDEO_VIDEOBUF=m
+CONFIG_VIDEO_TUNER=m
+CONFIG_VIDEO_BUF=m
+CONFIG_VIDEO_BUF_DVB=m
+CONFIG_VIDEO_BTCX=m
+CONFIG_VIDEO_IR=m
+CONFIG_VIDEO_TVEEPROM=m
+CONFIG_USB_DABUSB=m
+
+#
+# Graphics support
+#
+# CONFIG_FIRMWARE_EDID is not set
+CONFIG_FB=y
+CONFIG_FB_CFB_FILLRECT=y
+CONFIG_FB_CFB_COPYAREA=y
+CONFIG_FB_CFB_IMAGEBLIT=y
+# CONFIG_FB_MACMODES is not set
+# CONFIG_FB_BACKLIGHT is not set
+CONFIG_FB_MODE_HELPERS=y
+CONFIG_FB_TILEBLITTING=y
+CONFIG_FB_CIRRUS=m
+# CONFIG_FB_PM2 is not set
+# CONFIG_FB_CYBER2000 is not set
+# CONFIG_FB_ARC is not set
+# CONFIG_FB_ASILIANT is not set
+# CONFIG_FB_IMSTT is not set
+CONFIG_FB_VGA16=m
+CONFIG_FB_VESA=y
+# CONFIG_FB_HGA is not set
+# CONFIG_FB_S1D13XXX is not set
+CONFIG_FB_NVIDIA=m
+CONFIG_FB_NVIDIA_I2C=y
+CONFIG_FB_RIVA=m
+# CONFIG_FB_RIVA_I2C is not set
+# CONFIG_FB_RIVA_DEBUG is not set
+CONFIG_FB_I810=m
+CONFIG_FB_I810_GTF=y
+CONFIG_FB_I810_I2C=y
+CONFIG_FB_INTEL=m
+# CONFIG_FB_INTEL_DEBUG is not set
+CONFIG_FB_MATROX=m
+CONFIG_FB_MATROX_MILLENIUM=y
+CONFIG_FB_MATROX_MYSTIQUE=y
+CONFIG_FB_MATROX_G=y
+CONFIG_FB_MATROX_I2C=m
+CONFIG_FB_MATROX_MAVEN=m
+CONFIG_FB_MATROX_MULTIHEAD=y
+CONFIG_FB_RADEON=m
+CONFIG_FB_RADEON_I2C=y
+# CONFIG_FB_RADEON_DEBUG is not set
+CONFIG_FB_ATY128=m
+CONFIG_FB_ATY=m
+CONFIG_FB_ATY_CT=y
+CONFIG_FB_ATY_GENERIC_LCD=y
+CONFIG_FB_ATY_GX=y
+CONFIG_FB_SAVAGE=m
+CONFIG_FB_SAVAGE_I2C=y
+CONFIG_FB_SAVAGE_ACCEL=y
+# CONFIG_FB_SIS is not set
+CONFIG_FB_NEOMAGIC=m
+CONFIG_FB_KYRO=m
+CONFIG_FB_3DFX=m
+CONFIG_FB_3DFX_ACCEL=y
+CONFIG_FB_VOODOO1=m
+CONFIG_FB_CYBLA=m
+CONFIG_FB_TRIDENT=m
+CONFIG_FB_TRIDENT_ACCEL=y
+# CONFIG_FB_GEODE is not set
+# CONFIG_FB_VIRTUAL is not set
+
+#
+# Console display driver support
+#
+CONFIG_VGA_CONSOLE=y
+CONFIG_VGACON_SOFT_SCROLLBACK=y
+CONFIG_VGACON_SOFT_SCROLLBACK_SIZE=64
+CONFIG_VIDEO_SELECT=y
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y
+# CONFIG_FONTS is not set
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
+
+#
+# Logo configuration
+#
+CONFIG_LOGO=y
+# CONFIG_LOGO_LINUX_MONO is not set
+# CONFIG_LOGO_LINUX_VGA16 is not set
+CONFIG_LOGO_LINUX_CLUT224=y
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+CONFIG_BACKLIGHT_CLASS_DEVICE=m
+CONFIG_BACKLIGHT_DEVICE=y
+CONFIG_LCD_CLASS_DEVICE=m
+CONFIG_LCD_DEVICE=y
+
+#
+# Sound
+#
+CONFIG_SOUND=m
+
+#
+# Advanced Linux Sound Architecture
+#
+CONFIG_SND=m
+CONFIG_SND_TIMER=m
+CONFIG_SND_PCM=m
+CONFIG_SND_HWDEP=m
+CONFIG_SND_RAWMIDI=m
+CONFIG_SND_SEQUENCER=m
+CONFIG_SND_SEQ_DUMMY=m
+CONFIG_SND_OSSEMUL=y
+CONFIG_SND_MIXER_OSS=m
+CONFIG_SND_PCM_OSS=m
+CONFIG_SND_PCM_OSS_PLUGINS=y
+CONFIG_SND_SEQUENCER_OSS=y
+CONFIG_SND_RTCTIMER=m
+CONFIG_SND_SEQ_RTCTIMER_DEFAULT=y
+CONFIG_SND_DYNAMIC_MINORS=y
+# CONFIG_SND_SUPPORT_OLD_API is not set
+CONFIG_SND_VERBOSE_PROCFS=y
+# CONFIG_SND_VERBOSE_PRINTK is not set
+# CONFIG_SND_DEBUG is not set
+
+#
+# Generic devices
+#
+CONFIG_SND_MPU401_UART=m
+CONFIG_SND_OPL3_LIB=m
+CONFIG_SND_VX_LIB=m
+CONFIG_SND_AC97_CODEC=m
+CONFIG_SND_AC97_BUS=m
+CONFIG_SND_DUMMY=m
+CONFIG_SND_VIRMIDI=m
+CONFIG_SND_MTPAV=m
+# CONFIG_SND_SERIAL_U16550 is not set
+CONFIG_SND_MPU401=m
+
+#
+# PCI devices
+#
+CONFIG_SND_AD1889=m
+CONFIG_SND_ALS300=m
+CONFIG_SND_ALS4000=m
+CONFIG_SND_ALI5451=m
+CONFIG_SND_ATIIXP=m
+CONFIG_SND_ATIIXP_MODEM=m
+CONFIG_SND_AU8810=m
+CONFIG_SND_AU8820=m
+CONFIG_SND_AU8830=m
+CONFIG_SND_AZT3328=m
+CONFIG_SND_BT87X=m
+# CONFIG_SND_BT87X_OVERCLOCK is not set
+CONFIG_SND_CA0106=m
+CONFIG_SND_CMIPCI=m
+CONFIG_SND_CS4281=m
+CONFIG_SND_CS46XX=m
+CONFIG_SND_CS46XX_NEW_DSP=y
+CONFIG_SND_CS5535AUDIO=m
+CONFIG_SND_DARLA20=m
+CONFIG_SND_GINA20=m
+CONFIG_SND_LAYLA20=m
+CONFIG_SND_DARLA24=m
+CONFIG_SND_GINA24=m
+CONFIG_SND_LAYLA24=m
+CONFIG_SND_MONA=m
+CONFIG_SND_MIA=m
+CONFIG_SND_ECHO3G=m
+CONFIG_SND_INDIGO=m
+CONFIG_SND_INDIGOIO=m
+CONFIG_SND_INDIGODJ=m
+CONFIG_SND_EMU10K1=m
+CONFIG_SND_EMU10K1X=m
+CONFIG_SND_ENS1370=m
+CONFIG_SND_ENS1371=m
+CONFIG_SND_ES1938=m
+CONFIG_SND_ES1968=m
+CONFIG_SND_FM801=m
+CONFIG_SND_FM801_TEA575X_BOOL=y
+CONFIG_SND_FM801_TEA575X=m
+CONFIG_SND_HDA_INTEL=m
+CONFIG_SND_HDSP=m
+CONFIG_SND_HDSPM=m
+CONFIG_SND_ICE1712=m
+CONFIG_SND_ICE1724=m
+CONFIG_SND_INTEL8X0=m
+CONFIG_SND_INTEL8X0M=m
+CONFIG_SND_KORG1212=m
+CONFIG_SND_MAESTRO3=m
+CONFIG_SND_MIXART=m
+CONFIG_SND_NM256=m
+CONFIG_SND_PCXHR=m
+CONFIG_SND_RIPTIDE=m
+CONFIG_SND_RME32=m
+CONFIG_SND_RME96=m
+CONFIG_SND_RME9652=m
+CONFIG_SND_SONICVIBES=m
+CONFIG_SND_TRIDENT=m
+CONFIG_SND_VIA82XX=m
+CONFIG_SND_VIA82XX_MODEM=m
+CONFIG_SND_VX222=m
+CONFIG_SND_YMFPCI=m
+
+#
+# USB devices
+#
+CONFIG_SND_USB_AUDIO=m
+CONFIG_SND_USB_USX2Y=m
+
+#
+# PCMCIA devices
+#
+# CONFIG_SND_VXPOCKET is not set
+# CONFIG_SND_PDAUDIOCF is not set
+
+#
+# Open Sound System
+#
+# CONFIG_SOUND_PRIME is not set
+
+#
+# USB support
+#
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB_ARCH_HAS_EHCI=y
+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_SUSPEND is not set
+# CONFIG_USB_OTG is not set
+
+#
+# USB Host Controller Drivers
+#
+CONFIG_USB_EHCI_HCD=m
+CONFIG_USB_EHCI_SPLIT_ISO=y
+CONFIG_USB_EHCI_ROOT_HUB_TT=y
+CONFIG_USB_EHCI_TT_NEWSCHED=y
+CONFIG_USB_ISP116X_HCD=m
+CONFIG_USB_OHCI_HCD=m
+# CONFIG_USB_OHCI_BIG_ENDIAN is not set
+CONFIG_USB_OHCI_LITTLE_ENDIAN=y
+CONFIG_USB_UHCI_HCD=m
+CONFIG_USB_SL811_HCD=m
+CONFIG_USB_SL811_CS=m
+
+#
+# USB Device Class drivers
+#
+CONFIG_USB_ACM=m
+CONFIG_USB_PRINTER=m
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+#
+
+#
+# may also be needed; see USB_STORAGE Help for more information
+#
+CONFIG_USB_STORAGE=m
+# CONFIG_USB_STORAGE_DEBUG is not set
+CONFIG_USB_STORAGE_DATAFAB=y
+CONFIG_USB_STORAGE_FREECOM=y
+CONFIG_USB_STORAGE_ISD200=y
+CONFIG_USB_STORAGE_DPCM=y
+CONFIG_USB_STORAGE_USBAT=y
+CONFIG_USB_STORAGE_SDDR09=y
+CONFIG_USB_STORAGE_SDDR55=y
+CONFIG_USB_STORAGE_JUMPSHOT=y
+CONFIG_USB_STORAGE_ALAUDA=y
+CONFIG_USB_LIBUSUAL=y
+
+#
+# USB Input Devices
+#
+CONFIG_USB_HID=y
+CONFIG_USB_HIDINPUT=y
+CONFIG_USB_HIDINPUT_POWERBOOK=y
+CONFIG_HID_FF=y
+CONFIG_HID_PID=y
+CONFIG_LOGITECH_FF=y
+CONFIG_THRUSTMASTER_FF=y
+CONFIG_USB_HIDDEV=y
+CONFIG_USB_AIPTEK=m
+CONFIG_USB_WACOM=m
+CONFIG_USB_ACECAD=m
+CONFIG_USB_KBTAB=m
+CONFIG_USB_POWERMATE=m
+CONFIG_USB_TOUCHSCREEN=m
+CONFIG_USB_TOUCHSCREEN_EGALAX=y
+CONFIG_USB_TOUCHSCREEN_PANJIT=y
+CONFIG_USB_TOUCHSCREEN_3M=y
+CONFIG_USB_TOUCHSCREEN_ITM=y
+# CONFIG_USB_YEALINK is not set
+CONFIG_USB_XPAD=m
+CONFIG_USB_ATI_REMOTE=m
+CONFIG_USB_ATI_REMOTE2=m
+CONFIG_USB_KEYSPAN_REMOTE=m
+CONFIG_USB_APPLETOUCH=m
+
+#
+# USB Imaging devices
+#
+CONFIG_USB_MDC800=m
+CONFIG_USB_MICROTEK=m
+
+#
+# USB Network Adapters
+#
+CONFIG_USB_CATC=m
+CONFIG_USB_KAWETH=m
+CONFIG_USB_PEGASUS=m
+CONFIG_USB_RTL8150=m
+CONFIG_USB_USBNET=m
+CONFIG_USB_NET_AX8817X=m
+CONFIG_USB_NET_CDCETHER=m
+CONFIG_USB_NET_GL620A=m
+CONFIG_USB_NET_NET1080=m
+CONFIG_USB_NET_PLUSB=m
+CONFIG_USB_NET_RNDIS_HOST=m
+CONFIG_USB_NET_CDC_SUBSET=m
+CONFIG_USB_ALI_M5632=y
+CONFIG_USB_AN2720=y
+CONFIG_USB_BELKIN=y
+CONFIG_USB_ARMLINUX=y
+CONFIG_USB_EPSON2888=y
+CONFIG_USB_NET_ZAURUS=m
+CONFIG_USB_MON=y
+
+#
+# USB port drivers
+#
+CONFIG_USB_USS720=m
+
+#
+# USB Serial Converter support
+#
+CONFIG_USB_SERIAL=m
+CONFIG_USB_SERIAL_GENERIC=y
+CONFIG_USB_SERIAL_AIRPRIME=m
+CONFIG_USB_SERIAL_ARK3116=m
+CONFIG_USB_SERIAL_BELKIN=m
+CONFIG_USB_SERIAL_WHITEHEAT=m
+CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m
+CONFIG_USB_SERIAL_CP2101=m
+CONFIG_USB_SERIAL_CYPRESS_M8=m
+CONFIG_USB_SERIAL_EMPEG=m
+CONFIG_USB_SERIAL_FTDI_SIO=m
+CONFIG_USB_SERIAL_FUNSOFT=m
+CONFIG_USB_SERIAL_VISOR=m
+CONFIG_USB_SERIAL_IPAQ=m
+CONFIG_USB_SERIAL_IR=m
+CONFIG_USB_SERIAL_EDGEPORT=m
+CONFIG_USB_SERIAL_EDGEPORT_TI=m
+CONFIG_USB_SERIAL_GARMIN=m
+CONFIG_USB_SERIAL_IPW=m
+CONFIG_USB_SERIAL_KEYSPAN_PDA=m
+CONFIG_USB_SERIAL_KEYSPAN=m
+CONFIG_USB_SERIAL_KEYSPAN_MPR=y
+CONFIG_USB_SERIAL_KEYSPAN_USA28=y
+CONFIG_USB_SERIAL_KEYSPAN_USA28X=y
+CONFIG_USB_SERIAL_KEYSPAN_USA28XA=y
+CONFIG_USB_SERIAL_KEYSPAN_USA28XB=y
+CONFIG_USB_SERIAL_KEYSPAN_USA19=y
+CONFIG_USB_SERIAL_KEYSPAN_USA18X=y
+CONFIG_USB_SERIAL_KEYSPAN_USA19W=y
+CONFIG_USB_SERIAL_KEYSPAN_USA19QW=y
+CONFIG_USB_SERIAL_KEYSPAN_USA19QI=y
+CONFIG_USB_SERIAL_KEYSPAN_USA49W=y
+CONFIG_USB_SERIAL_KEYSPAN_USA49WLC=y
+CONFIG_USB_SERIAL_KLSI=m
+CONFIG_USB_SERIAL_KOBIL_SCT=m
+CONFIG_USB_SERIAL_MCT_U232=m
+CONFIG_USB_SERIAL_NAVMAN=m
+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=m
+CONFIG_USB_SERIAL_TI=m
+CONFIG_USB_SERIAL_CYBERJACK=m
+CONFIG_USB_SERIAL_XIRCOM=m
+CONFIG_USB_SERIAL_OPTION=m
+CONFIG_USB_SERIAL_OMNINET=m
+CONFIG_USB_EZUSB=y
+
+#
+# USB Miscellaneous drivers
+#
+CONFIG_USB_EMI62=m
+CONFIG_USB_EMI26=m
+CONFIG_USB_AUERSWALD=m
+CONFIG_USB_RIO500=m
+CONFIG_USB_LEGOTOWER=m
+CONFIG_USB_LCD=m
+CONFIG_USB_LED=m
+# CONFIG_USB_CYPRESS_CY7C63 is not set
+# CONFIG_USB_CYTHERM is not set
+CONFIG_USB_PHIDGETKIT=m
+CONFIG_USB_PHIDGETSERVO=m
+CONFIG_USB_IDMOUSE=m
+CONFIG_USB_APPLEDISPLAY=m
+CONFIG_USB_SISUSBVGA=m
+CONFIG_USB_SISUSBVGA_CON=y
+CONFIG_USB_LD=m
+CONFIG_USB_TEST=m
+
+#
+# USB DSL modem support
+#
+CONFIG_USB_ATM=m
+CONFIG_USB_SPEEDTOUCH=m
+CONFIG_USB_CXACRU=m
+CONFIG_USB_UEAGLEATM=m
+CONFIG_USB_XUSBATM=m
+
+#
+# USB Gadget Support
+#
+# CONFIG_USB_GADGET is not set
+
+#
+# MMC/SD Card support
+#
+CONFIG_MMC=m
+# CONFIG_MMC_DEBUG is not set
+CONFIG_MMC_BLOCK=m
+CONFIG_MMC_SDHCI=m
+CONFIG_MMC_WBSD=m
+
+#
+# LED devices
+#
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+
+#
+# LED drivers
+#
+
+#
+# LED Triggers
+#
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_LEDS_TRIGGER_TIMER=m
+CONFIG_LEDS_TRIGGER_IDE_DISK=y
+CONFIG_LEDS_TRIGGER_HEARTBEAT=m
+
+#
+# InfiniBand support
+#
+CONFIG_INFINIBAND=m
+CONFIG_INFINIBAND_USER_MAD=m
+CONFIG_INFINIBAND_USER_ACCESS=m
+CONFIG_INFINIBAND_ADDR_TRANS=y
+CONFIG_INFINIBAND_MTHCA=m
+CONFIG_INFINIBAND_MTHCA_DEBUG=y
+CONFIG_INFINIBAND_IPOIB=m
+CONFIG_INFINIBAND_IPOIB_DEBUG=y
+CONFIG_INFINIBAND_IPOIB_DEBUG_DATA=y
+CONFIG_INFINIBAND_SRP=m
+CONFIG_INFINIBAND_ISER=m
+
+#
+# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
+#
+CONFIG_EDAC=y
+
+#
+# Reporting subsystems
+#
+# CONFIG_EDAC_DEBUG is not set
+CONFIG_EDAC_MM_EDAC=m
+CONFIG_EDAC_AMD76X=m
+CONFIG_EDAC_E7XXX=m
+CONFIG_EDAC_E752X=m
+CONFIG_EDAC_I82875P=m
+CONFIG_EDAC_I82860=m
+CONFIG_EDAC_K8=m
+CONFIG_EDAC_R82600=m
+CONFIG_EDAC_POLL=y
+
+#
+# Real Time Clock
+#
+CONFIG_RTC_LIB=m
+CONFIG_RTC_CLASS=m
+
+#
+# RTC interfaces
+#
+CONFIG_RTC_INTF_SYSFS=m
+CONFIG_RTC_INTF_PROC=m
+CONFIG_RTC_INTF_DEV=m
+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
+
+#
+# RTC drivers
+#
+CONFIG_RTC_DRV_X1205=m
+CONFIG_RTC_DRV_DS1307=m
+CONFIG_RTC_DRV_DS1553=m
+CONFIG_RTC_DRV_ISL1208=m
+CONFIG_RTC_DRV_DS1672=m
+CONFIG_RTC_DRV_DS1742=m
+CONFIG_RTC_DRV_PCF8563=m
+CONFIG_RTC_DRV_PCF8583=m
+CONFIG_RTC_DRV_RS5C372=m
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_TEST is not set
+CONFIG_RTC_DRV_V3020=m
+
+#
+# DMA Engine support
+#
+CONFIG_DMA_ENGINE=y
+
+#
+# DMA Clients
+#
+CONFIG_NET_DMA=y
+
+#
+# DMA Devices
+#
+CONFIG_INTEL_IOATDMA=m
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+CONFIG_EXT2_FS_POSIX_ACL=y
+CONFIG_EXT2_FS_SECURITY=y
+CONFIG_EXT2_FS_XIP=y
+CONFIG_FS_XIP=y
+CONFIG_EXT3_FS=m
+CONFIG_EXT3_FS_XATTR=y
+CONFIG_EXT3_FS_POSIX_ACL=y
+CONFIG_EXT3_FS_SECURITY=y
+CONFIG_JBD=m
+# CONFIG_JBD_DEBUG is not set
+CONFIG_FS_MBCACHE=y
+CONFIG_REISERFS_FS=m
+# CONFIG_REISERFS_CHECK is not set
+CONFIG_REISERFS_PROC_INFO=y
+CONFIG_REISERFS_FS_XATTR=y
+CONFIG_REISERFS_FS_POSIX_ACL=y
+CONFIG_REISERFS_FS_SECURITY=y
+CONFIG_JFS_FS=m
+CONFIG_JFS_POSIX_ACL=y
+CONFIG_JFS_SECURITY=y
+# CONFIG_JFS_DEBUG is not set
+# CONFIG_JFS_STATISTICS is not set
+CONFIG_FS_POSIX_ACL=y
+CONFIG_XFS_FS=m
+CONFIG_XFS_QUOTA=y
+CONFIG_XFS_SECURITY=y
+CONFIG_XFS_POSIX_ACL=y
+# CONFIG_XFS_RT is not set
+CONFIG_OCFS2_FS=m
+# CONFIG_OCFS2_DEBUG_MASKLOG is not set
+CONFIG_MINIX_FS=m
+CONFIG_ROMFS_FS=m
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+CONFIG_QUOTA=y
+# CONFIG_QFMT_V1 is not set
+CONFIG_QFMT_V2=y
+CONFIG_QUOTACTL=y
+CONFIG_DNOTIFY=y
+CONFIG_AUTOFS_FS=m
+CONFIG_AUTOFS4_FS=m
+CONFIG_FUSE_FS=m
+
+#
+# Caches
+#
+CONFIG_FSCACHE=m
+
+#
+# CD-ROM/DVD Filesystems
+#
+CONFIG_ISO9660_FS=y
+CONFIG_JOLIET=y
+CONFIG_ZISOFS=y
+CONFIG_ZISOFS_FS=y
+CONFIG_UDF_FS=m
+CONFIG_UDF_NLS=y
+CONFIG_CACHEFILES=m
+CONFIG_CACHEFILES_DEBUG=y
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=m
+CONFIG_MSDOS_FS=m
+CONFIG_VFAT_FS=m
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="ascii"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_RAMFS=y
+CONFIG_CONFIGFS_FS=m
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+CONFIG_AFFS_FS=m
+CONFIG_HFS_FS=m
+CONFIG_HFSPLUS_FS=m
+CONFIG_BEFS_FS=m
+# CONFIG_BEFS_DEBUG is not set
+CONFIG_BFS_FS=m
+CONFIG_EFS_FS=m
+# CONFIG_JFFS_FS is not set
+CONFIG_JFFS2_FS=m
+CONFIG_JFFS2_FS_DEBUG=0
+CONFIG_JFFS2_FS_WRITEBUFFER=y
+CONFIG_JFFS2_SUMMARY=y
+# 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=m
+CONFIG_SQUASHFS=m
+# CONFIG_SQUASHFS_EMBEDDED is not set
+CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3
+# CONFIG_SQUASHFS_VMALLOC is not set
+CONFIG_VXFS_FS=m
+# CONFIG_HPFS_FS is not set
+CONFIG_QNX4FS_FS=m
+CONFIG_SYSV_FS=m
+CONFIG_UFS_FS=m
+# CONFIG_UFS_FS_WRITE is not set
+# CONFIG_UFS_DEBUG is not set
+
+#
+# Network File Systems
+#
+CONFIG_NFS_FS=m
+CONFIG_NFS_V3=y
+CONFIG_NFS_V3_ACL=y
+CONFIG_NFS_V4=y
+CONFIG_NFS_FSCACHE=y
+CONFIG_NFS_DIRECTIO=y
+CONFIG_NFSD=m
+CONFIG_NFSD_V2_ACL=y
+CONFIG_NFSD_V3=y
+CONFIG_NFSD_V3_ACL=y
+CONFIG_NFSD_V4=y
+CONFIG_NFSD_TCP=y
+CONFIG_LOCKD=m
+CONFIG_LOCKD_V4=y
+CONFIG_EXPORTFS=m
+CONFIG_NFS_ACL_SUPPORT=m
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=m
+CONFIG_SUNRPC_GSS=m
+CONFIG_RPCSEC_GSS_KRB5=m
+CONFIG_RPCSEC_GSS_SPKM3=m
+# CONFIG_SMB_FS is not set
+CONFIG_CIFS=m
+# CONFIG_CIFS_STATS is not set
+CONFIG_CIFS_WEAK_PW_HASH=y
+CONFIG_CIFS_XATTR=y
+CONFIG_CIFS_POSIX=y
+# CONFIG_CIFS_DEBUG2 is not set
+# CONFIG_CIFS_EXPERIMENTAL is not set
+CONFIG_NCP_FS=m
+CONFIG_NCPFS_PACKET_SIGNING=y
+CONFIG_NCPFS_IOCTL_LOCKING=y
+CONFIG_NCPFS_STRONG=y
+CONFIG_NCPFS_NFS_NS=y
+CONFIG_NCPFS_OS2_NS=y
+CONFIG_NCPFS_SMALLDOS=y
+CONFIG_NCPFS_NLS=y
+CONFIG_NCPFS_EXTRAS=y
+CONFIG_CODA_FS=m
+# CONFIG_CODA_FS_OLD_API is not set
+# CONFIG_AFS_FS is not set
+CONFIG_9P_FS=m
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+CONFIG_OSF_PARTITION=y
+CONFIG_AMIGA_PARTITION=y
+# CONFIG_ATARI_PARTITION is not set
+CONFIG_MAC_PARTITION=y
+CONFIG_MSDOS_PARTITION=y
+CONFIG_BSD_DISKLABEL=y
+CONFIG_MINIX_SUBPARTITION=y
+CONFIG_SOLARIS_X86_PARTITION=y
+CONFIG_UNIXWARE_DISKLABEL=y
+# CONFIG_LDM_PARTITION is not set
+CONFIG_SGI_PARTITION=y
+# CONFIG_ULTRIX_PARTITION is not set
+CONFIG_SUN_PARTITION=y
+CONFIG_KARMA_PARTITION=y
+CONFIG_EFI_PARTITION=y
+
+#
+# Native Language Support
+#
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="utf8"
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_CODEPAGE_737=m
+CONFIG_NLS_CODEPAGE_775=m
+CONFIG_NLS_CODEPAGE_850=m
+CONFIG_NLS_CODEPAGE_852=m
+CONFIG_NLS_CODEPAGE_855=m
+CONFIG_NLS_CODEPAGE_857=m
+CONFIG_NLS_CODEPAGE_860=m
+CONFIG_NLS_CODEPAGE_861=m
+CONFIG_NLS_CODEPAGE_862=m
+CONFIG_NLS_CODEPAGE_863=m
+CONFIG_NLS_CODEPAGE_864=m
+CONFIG_NLS_CODEPAGE_865=m
+CONFIG_NLS_CODEPAGE_866=m
+CONFIG_NLS_CODEPAGE_869=m
+CONFIG_NLS_CODEPAGE_936=m
+CONFIG_NLS_CODEPAGE_950=m
+CONFIG_NLS_CODEPAGE_932=m
+CONFIG_NLS_CODEPAGE_949=m
+CONFIG_NLS_CODEPAGE_874=m
+CONFIG_NLS_ISO8859_8=m
+CONFIG_NLS_CODEPAGE_1250=m
+CONFIG_NLS_CODEPAGE_1251=m
+CONFIG_NLS_ASCII=y
+CONFIG_NLS_ISO8859_1=m
+CONFIG_NLS_ISO8859_2=m
+CONFIG_NLS_ISO8859_3=m
+CONFIG_NLS_ISO8859_4=m
+CONFIG_NLS_ISO8859_5=m
+CONFIG_NLS_ISO8859_6=m
+CONFIG_NLS_ISO8859_7=m
+CONFIG_NLS_ISO8859_9=m
+CONFIG_NLS_ISO8859_13=m
+CONFIG_NLS_ISO8859_14=m
+CONFIG_NLS_ISO8859_15=m
+CONFIG_NLS_KOI8_R=m
+CONFIG_NLS_KOI8_U=m
+CONFIG_NLS_UTF8=m
+
+#
+# Instrumentation Support
+#
+CONFIG_PROFILING=y
+CONFIG_OPROFILE=m
+CONFIG_KPROBES=y
+
+#
+# Kernel hacking
+#
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+# CONFIG_PRINTK_TIME is not set
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_UNUSED_SYMBOLS is not set
+CONFIG_DEBUG_KERNEL=y
+CONFIG_LOG_BUF_SHIFT=17
+CONFIG_DETECT_SOFTLOCKUP=y
+CONFIG_SCHEDSTATS=y
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
+CONFIG_DEBUG_SPINLOCK=y
+# 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=y
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+# CONFIG_DEBUG_KOBJECT is not set
+CONFIG_DEBUG_HIGHMEM=y
+CONFIG_DEBUG_BUGVERBOSE=y
+CONFIG_DEBUG_INFO=y
+CONFIG_DEBUG_FS=y
+# CONFIG_DEBUG_VM is not set
+CONFIG_DEBUG_LIST=y
+# CONFIG_FRAME_POINTER is not set
+CONFIG_UNWIND_INFO=y
+CONFIG_STACK_UNWIND=y
+# CONFIG_FORCED_INLINING is not set
+CONFIG_BOOT_DELAY=y
+# CONFIG_RCU_TORTURE_TEST is not set
+CONFIG_EARLY_PRINTK=y
+CONFIG_DEBUG_STACKOVERFLOW=y
+CONFIG_DEBUG_STACK_USAGE=y
+# CONFIG_DEBUG_PAGEALLOC is not set
+CONFIG_DEBUG_RODATA=y
+CONFIG_4KSTACKS=y
+CONFIG_X86_FIND_SMP_CONFIG=y
+CONFIG_X86_MPPARSE=y
+
+#
+# Security options
+#
+CONFIG_KEYS=y
+CONFIG_KEYS_DEBUG_PROC_KEYS=y
+CONFIG_SECURITY=y
+CONFIG_SECURITY_NETWORK=y
+# CONFIG_SECURITY_NETWORK_XFRM is not set
+CONFIG_SECURITY_CAPABILITIES=y
+# CONFIG_SECURITY_ROOTPLUG is not set
+# CONFIG_SECURITY_SECLVL is not set
+CONFIG_SECURITY_SELINUX=y
+CONFIG_SECURITY_SELINUX_BOOTPARAM=y
+CONFIG_SECURITY_SELINUX_BOOTPARAM_VALUE=1
+CONFIG_SECURITY_SELINUX_DISABLE=y
+CONFIG_SECURITY_SELINUX_DEVELOP=y
+CONFIG_SECURITY_SELINUX_AVC_STATS=y
+CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE=1
+# CONFIG_SECURITY_SELINUX_ENABLE_SECMARK_DEFAULT is not set
+# CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX is not set
+
+#
+# Cryptographic options
+#
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_NULL=m
+CONFIG_CRYPTO_MD4=m
+CONFIG_CRYPTO_MD5=m
+CONFIG_CRYPTO_SHA1=y
+CONFIG_CRYPTO_SHA256=m
+CONFIG_CRYPTO_SHA512=m
+CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_TGR192=m
+CONFIG_CRYPTO_DES=m
+CONFIG_CRYPTO_BLOWFISH=m
+CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_SERPENT=m
+CONFIG_CRYPTO_AES=m
+CONFIG_CRYPTO_AES_586=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_TEST is not set
+CONFIG_CRYPTO_SIGNATURE=y
+CONFIG_CRYPTO_SIGNATURE_DSA=y
+CONFIG_CRYPTO_MPILIB=y
+
+#
+# Hardware crypto devices
+#
+CONFIG_CRYPTO_DEV_PADLOCK=m
+CONFIG_CRYPTO_DEV_PADLOCK_AES=y
+CONFIG_XEN=y
+CONFIG_XEN_INTERFACE_VERSION=0x00030203
+
+#
+# XEN
+#
+CONFIG_XEN_PRIVILEGED_GUEST=y
+# CONFIG_XEN_UNPRIVILEGED_GUEST is not set
+CONFIG_XEN_PRIVCMD=y
+CONFIG_XEN_XENBUS_DEV=y
+CONFIG_XEN_BACKEND=y
+CONFIG_XEN_BLKDEV_BACKEND=y
+CONFIG_XEN_BLKDEV_TAP=m
+CONFIG_XEN_NETDEV_BACKEND=y
+# CONFIG_XEN_NETDEV_PIPELINED_TRANSMITTER is not set
+CONFIG_XEN_NETDEV_LOOPBACK=y
+CONFIG_XEN_PCIDEV_BACKEND=m
+CONFIG_XEN_PCIDEV_BACKEND_VPCI=y
+# CONFIG_XEN_PCIDEV_BACKEND_PASS is not set
+# CONFIG_XEN_PCIDEV_BACKEND_SLOT is not set
+# CONFIG_XEN_PCIDEV_BE_DEBUG is not set
+# CONFIG_XEN_TPMDEV_BACKEND is not set
+CONFIG_XEN_BLKDEV_FRONTEND=m
+CONFIG_XEN_NETDEV_FRONTEND=m
+CONFIG_XEN_FRAMEBUFFER=y
+CONFIG_XEN_KEYBOARD=y
+CONFIG_XEN_SCRUB_PAGES=y
+# CONFIG_XEN_DISABLE_SERIAL is not set
+CONFIG_XEN_SYSFS=y
+CONFIG_XEN_COMPAT_030002_AND_LATER=y
+# CONFIG_XEN_COMPAT_LATEST_ONLY is not set
+CONFIG_XEN_COMPAT_030002=y
+CONFIG_HAVE_ARCH_ALLOC_SKB=y
+CONFIG_HAVE_ARCH_DEV_ALLOC_SKB=y
+CONFIG_HAVE_IRQ_IGNORE_UNHANDLED=y
+CONFIG_NO_IDLE_HZ=y
+CONFIG_XEN_UTIL=y
+CONFIG_XEN_BALLOON=y
+CONFIG_XEN_DEVMEM=y
+CONFIG_XEN_SKBUFF=y
+CONFIG_XEN_REBOOT=y
+CONFIG_XEN_SMPBOOT=y
+
+#
+# Library routines
+#
+CONFIG_CRC_CCITT=m
+CONFIG_CRC16=m
+CONFIG_CRC32=y
+CONFIG_LIBCRC32C=m
+CONFIG_AUDIT_GENERIC=y
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=m
+CONFIG_REED_SOLOMON=m
+CONFIG_REED_SOLOMON_DEC16=y
+CONFIG_TEXTSEARCH=y
+CONFIG_TEXTSEARCH_KMP=m
+CONFIG_TEXTSEARCH_BM=m
+CONFIG_TEXTSEARCH_FSM=m
+CONFIG_PLIST=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_GENERIC_PENDING_IRQ=y
+CONFIG_X86_SMP=y
+CONFIG_X86_BIOS_REBOOT=y
+CONFIG_X86_TRAMPOLINE=y
+CONFIG_X86_NO_TSS=y
+CONFIG_X86_NO_IDT=y
+CONFIG_KTIME_SCALAR=y
diff --git a/configs/kernel-2.6.18-i686-xenU.config b/configs/kernel-2.6.18-i686-xenU.config
new file mode 100644
index 000000000..309644b0c
--- /dev/null
+++ b/configs/kernel-2.6.18-i686-xenU.config
@@ -0,0 +1,1635 @@
+# i386
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.18.2-rc1
+# Mon Nov 13 09:44:40 2006
+#
+CONFIG_X86_32=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_SEMAPHORE_SLEEPERS=y
+CONFIG_X86=y
+CONFIG_MMU=y
+CONFIG_GENERIC_ISA_DMA=y
+CONFIG_GENERIC_IOMAP=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_ARCH_MAY_HAVE_PC_FDC=y
+CONFIG_DMI=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_BSD_PROCESS_ACCT=y
+# CONFIG_BSD_PROCESS_ACCT_V3 is not set
+CONFIG_TASKSTATS=y
+CONFIG_TASK_DELAY_ACCT=y
+CONFIG_AUDIT=y
+CONFIG_AUDITSYSCALL=y
+# CONFIG_IKCONFIG is not set
+CONFIG_CPUSETS=y
+CONFIG_RELAY=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+# CONFIG_EMBEDDED is not set
+CONFIG_UID16=y
+CONFIG_SYSCTL=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
+CONFIG_KALLSYMS_EXTRA_PASS=y
+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=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+CONFIG_MODULE_SIG=y
+# CONFIG_MODULE_SIG_FORCE is not set
+CONFIG_KMOD=y
+CONFIG_STOP_MACHINE=y
+
+#
+# Process debugging support
+#
+CONFIG_UTRACE=y
+CONFIG_PTRACE=y
+
+#
+# Block layer
+#
+CONFIG_LBD=y
+CONFIG_BLK_DEV_IO_TRACE=y
+CONFIG_LSF=y
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_DEFAULT_AS is not set
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+
+#
+# Processor type and features
+#
+CONFIG_SMP=y
+# CONFIG_X86_PC is not set
+CONFIG_X86_XEN=y
+# CONFIG_X86_ELAN is not set
+# CONFIG_X86_VOYAGER is not set
+# CONFIG_X86_NUMAQ is not set
+# CONFIG_X86_SUMMIT is not set
+# CONFIG_X86_BIGSMP is not set
+# CONFIG_X86_VISWS is not set
+# CONFIG_X86_GENERICARCH is not set
+# CONFIG_X86_ES7000 is not set
+# CONFIG_M386 is not set
+# CONFIG_M486 is not set
+# CONFIG_M586 is not set
+# CONFIG_M586TSC is not set
+# CONFIG_M586MMX is not set
+CONFIG_M686=y
+# CONFIG_MPENTIUMII is not set
+# CONFIG_MPENTIUMIII is not set
+# CONFIG_MPENTIUMM is not set
+# CONFIG_MPENTIUM4 is not set
+# CONFIG_MK6 is not set
+# CONFIG_MK7 is not set
+# CONFIG_MK8 is not set
+# CONFIG_MCRUSOE is not set
+# CONFIG_MEFFICEON is not set
+# CONFIG_MWINCHIPC6 is not set
+# CONFIG_MWINCHIP2 is not set
+# CONFIG_MWINCHIP3D is not set
+# CONFIG_MGEODEGX1 is not set
+# CONFIG_MGEODE_LX is not set
+# CONFIG_MCYRIXIII is not set
+# CONFIG_MVIAC3_2 is not set
+CONFIG_X86_GENERIC=y
+CONFIG_X86_CMPXCHG=y
+CONFIG_X86_XADD=y
+CONFIG_X86_L1_CACHE_SHIFT=7
+CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_X86_PPRO_FENCE=y
+CONFIG_X86_WP_WORKS_OK=y
+CONFIG_X86_INVLPG=y
+CONFIG_X86_BSWAP=y
+CONFIG_X86_POPAD_OK=y
+CONFIG_X86_CMPXCHG64=y
+CONFIG_X86_GOOD_APIC=y
+CONFIG_X86_INTEL_USERCOPY=y
+CONFIG_X86_USE_PPRO_CHECKSUM=y
+CONFIG_NR_CPUS=32
+# CONFIG_PREEMPT_NONE is not set
+CONFIG_PREEMPT_VOLUNTARY=y
+# CONFIG_PREEMPT is not set
+CONFIG_PREEMPT_BKL=y
+CONFIG_VM86=y
+# CONFIG_TOSHIBA is not set
+CONFIG_I8K=m
+# CONFIG_X86_REBOOTFIXUPS is not set
+CONFIG_X86_CPUID=m
+CONFIG_SWIOTLB=y
+
+#
+# Firmware Drivers
+#
+CONFIG_DELL_RBU=m
+CONFIG_DCDBAS=m
+# CONFIG_NOHIGHMEM is not set
+CONFIG_HIGHMEM4G=y
+# CONFIG_HIGHMEM64G is not set
+CONFIG_PAGE_OFFSET=0xC0000000
+CONFIG_HIGHMEM=y
+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=y
+CONFIG_REGPARM=y
+# CONFIG_SECCOMP is not set
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
+# CONFIG_CRASH_DUMP is not set
+CONFIG_PHYSICAL_START=0x400000
+CONFIG_HOTPLUG_CPU=y
+CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
+
+#
+# Bus options (PCI, PCMCIA, EISA, MCA, ISA)
+#
+# CONFIG_PCI is not set
+CONFIG_ISA_DMA_API=y
+# CONFIG_SCx200 is not set
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+CONFIG_PCCARD=y
+# CONFIG_PCMCIA_DEBUG is not set
+# CONFIG_PCMCIA is not set
+
+#
+# PC-card bridges
+#
+
+#
+# PCI Hotplug Support
+#
+
+#
+# Executable file formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_AOUT is not set
+CONFIG_BINFMT_MISC=y
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+# CONFIG_NETDEBUG is not set
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=y
+CONFIG_NET_KEY=m
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_ASK_IP_FIB_HASH=y
+# 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
+# CONFIG_IP_PNP is not set
+CONFIG_NET_IPIP=m
+CONFIG_NET_IPGRE=m
+CONFIG_NET_IPGRE_BROADCAST=y
+CONFIG_IP_MROUTE=y
+CONFIG_IP_PIMSM_V1=y
+CONFIG_IP_PIMSM_V2=y
+# CONFIG_ARPD is not set
+CONFIG_SYN_COOKIES=y
+CONFIG_INET_AH=m
+CONFIG_INET_ESP=m
+CONFIG_INET_IPCOMP=m
+CONFIG_INET_XFRM_TUNNEL=m
+CONFIG_INET_TUNNEL=m
+CONFIG_INET_XFRM_MODE_TRANSPORT=m
+CONFIG_INET_XFRM_MODE_TUNNEL=m
+CONFIG_INET_DIAG=m
+CONFIG_INET_TCP_DIAG=m
+CONFIG_TCP_CONG_ADVANCED=y
+
+#
+# TCP congestion control
+#
+CONFIG_TCP_CONG_BIC=y
+CONFIG_TCP_CONG_CUBIC=m
+CONFIG_TCP_CONG_WESTWOOD=m
+CONFIG_TCP_CONG_HTCP=m
+CONFIG_TCP_CONG_HSTCP=m
+CONFIG_TCP_CONG_HYBLA=m
+CONFIG_TCP_CONG_VEGAS=m
+CONFIG_TCP_CONG_SCALABLE=m
+CONFIG_TCP_CONG_LP=m
+CONFIG_TCP_CONG_VENO=m
+
+#
+# IP: Virtual Server Configuration
+#
+CONFIG_IP_VS=m
+# CONFIG_IP_VS_DEBUG is not set
+CONFIG_IP_VS_TAB_BITS=12
+
+#
+# IPVS transport protocol load balancing support
+#
+CONFIG_IP_VS_PROTO_TCP=y
+CONFIG_IP_VS_PROTO_UDP=y
+CONFIG_IP_VS_PROTO_ESP=y
+CONFIG_IP_VS_PROTO_AH=y
+
+#
+# IPVS scheduler
+#
+CONFIG_IP_VS_RR=m
+CONFIG_IP_VS_WRR=m
+CONFIG_IP_VS_LC=m
+CONFIG_IP_VS_WLC=m
+CONFIG_IP_VS_LBLC=m
+CONFIG_IP_VS_LBLCR=m
+CONFIG_IP_VS_DH=m
+CONFIG_IP_VS_SH=m
+CONFIG_IP_VS_SED=m
+CONFIG_IP_VS_NQ=m
+
+#
+# IPVS application helper
+#
+CONFIG_IP_VS_FTP=m
+CONFIG_IPV6=m
+CONFIG_IPV6_PRIVACY=y
+CONFIG_IPV6_ROUTER_PREF=y
+CONFIG_IPV6_ROUTE_INFO=y
+CONFIG_INET6_AH=m
+CONFIG_INET6_ESP=m
+CONFIG_INET6_IPCOMP=m
+CONFIG_INET6_XFRM_TUNNEL=m
+CONFIG_INET6_TUNNEL=m
+CONFIG_INET6_XFRM_MODE_TRANSPORT=m
+CONFIG_INET6_XFRM_MODE_TUNNEL=m
+CONFIG_IPV6_TUNNEL=m
+CONFIG_NETWORK_SECMARK=y
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_DEBUG is not set
+CONFIG_BRIDGE_NETFILTER=y
+
+#
+# Core Netfilter Configuration
+#
+CONFIG_NETFILTER_NETLINK=m
+CONFIG_NETFILTER_NETLINK_QUEUE=m
+CONFIG_NETFILTER_NETLINK_LOG=m
+CONFIG_NETFILTER_XTABLES=m
+CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
+CONFIG_NETFILTER_XT_TARGET_CONNMARK=m
+CONFIG_NETFILTER_XT_TARGET_MARK=m
+CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
+CONFIG_NETFILTER_XT_TARGET_NOTRACK=m
+CONFIG_NETFILTER_XT_TARGET_SECMARK=m
+CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=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_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_PHYSDEV=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
+
+#
+# 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=m
+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_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_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_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
+CONFIG_IP_NF_ARPTABLES=m
+CONFIG_IP_NF_ARPFILTER=m
+CONFIG_IP_NF_ARP_MANGLE=m
+
+#
+# IPv6: Netfilter Configuration (EXPERIMENTAL)
+#
+CONFIG_IP6_NF_QUEUE=m
+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_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
+
+#
+# DECnet: Netfilter Configuration
+#
+# CONFIG_DECNET_NF_GRABULATOR is not set
+
+#
+# Bridge: Netfilter Configuration
+#
+CONFIG_BRIDGE_NF_EBTABLES=m
+CONFIG_BRIDGE_EBT_BROUTE=m
+CONFIG_BRIDGE_EBT_T_FILTER=m
+CONFIG_BRIDGE_EBT_T_NAT=m
+CONFIG_BRIDGE_EBT_802_3=m
+CONFIG_BRIDGE_EBT_AMONG=m
+CONFIG_BRIDGE_EBT_ARP=m
+CONFIG_BRIDGE_EBT_IP=m
+CONFIG_BRIDGE_EBT_LIMIT=m
+CONFIG_BRIDGE_EBT_MARK=m
+CONFIG_BRIDGE_EBT_PKTTYPE=m
+CONFIG_BRIDGE_EBT_STP=m
+CONFIG_BRIDGE_EBT_VLAN=m
+CONFIG_BRIDGE_EBT_ARPREPLY=m
+CONFIG_BRIDGE_EBT_DNAT=m
+CONFIG_BRIDGE_EBT_MARK_T=m
+CONFIG_BRIDGE_EBT_REDIRECT=m
+CONFIG_BRIDGE_EBT_SNAT=m
+CONFIG_BRIDGE_EBT_LOG=m
+CONFIG_BRIDGE_EBT_ULOG=m
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+CONFIG_IP_DCCP=m
+CONFIG_INET_DCCP_DIAG=m
+CONFIG_IP_DCCP_ACKVEC=y
+
+#
+# DCCP CCIDs Configuration (EXPERIMENTAL)
+#
+CONFIG_IP_DCCP_CCID2=m
+CONFIG_IP_DCCP_CCID3=m
+CONFIG_IP_DCCP_TFRC_LIB=m
+
+#
+# DCCP Kernel Hacking
+#
+# CONFIG_IP_DCCP_DEBUG is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+CONFIG_IP_SCTP=m
+# CONFIG_SCTP_DBG_MSG is not set
+# CONFIG_SCTP_DBG_OBJCNT is not set
+# CONFIG_SCTP_HMAC_NONE is not set
+# CONFIG_SCTP_HMAC_SHA1 is not set
+CONFIG_SCTP_HMAC_MD5=y
+
+#
+# TIPC Configuration (EXPERIMENTAL)
+#
+CONFIG_TIPC=m
+# CONFIG_TIPC_ADVANCED is not set
+# CONFIG_TIPC_DEBUG is not set
+CONFIG_ATM=m
+CONFIG_ATM_CLIP=m
+# CONFIG_ATM_CLIP_NO_ICMP is not set
+CONFIG_ATM_LANE=m
+# CONFIG_ATM_MPOA is not set
+CONFIG_ATM_BR2684=m
+# CONFIG_ATM_BR2684_IPFILTER is not set
+CONFIG_BRIDGE=m
+CONFIG_VLAN_8021Q=m
+CONFIG_DECNET=m
+CONFIG_DECNET_ROUTER=y
+CONFIG_DECNET_ROUTE_FWMARK=y
+CONFIG_LLC=m
+# CONFIG_LLC2 is not set
+CONFIG_IPX=m
+# CONFIG_IPX_INTERN is not set
+CONFIG_ATALK=m
+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_ECONET is not set
+CONFIG_WAN_ROUTER=m
+
+#
+# QoS and/or fair queueing
+#
+CONFIG_NET_SCHED=y
+# CONFIG_NET_SCH_CLK_JIFFIES is not set
+CONFIG_NET_SCH_CLK_GETTIMEOFDAY=y
+# CONFIG_NET_SCH_CLK_CPU is not set
+
+#
+# Queueing/Scheduling
+#
+CONFIG_NET_SCH_CBQ=m
+CONFIG_NET_SCH_HTB=m
+CONFIG_NET_SCH_HFSC=m
+CONFIG_NET_SCH_ATM=m
+CONFIG_NET_SCH_PRIO=m
+CONFIG_NET_SCH_RED=m
+CONFIG_NET_SCH_SFQ=m
+CONFIG_NET_SCH_TEQL=m
+CONFIG_NET_SCH_TBF=m
+CONFIG_NET_SCH_GRED=m
+CONFIG_NET_SCH_DSMARK=m
+CONFIG_NET_SCH_NETEM=m
+CONFIG_NET_SCH_INGRESS=m
+
+#
+# Classification
+#
+CONFIG_NET_CLS=y
+CONFIG_NET_CLS_BASIC=m
+CONFIG_NET_CLS_TCINDEX=m
+CONFIG_NET_CLS_ROUTE4=m
+CONFIG_NET_CLS_ROUTE=y
+CONFIG_NET_CLS_FW=m
+CONFIG_NET_CLS_U32=m
+CONFIG_CLS_U32_PERF=y
+CONFIG_CLS_U32_MARK=y
+CONFIG_NET_CLS_RSVP=m
+CONFIG_NET_CLS_RSVP6=m
+CONFIG_NET_EMATCH=y
+CONFIG_NET_EMATCH_STACK=32
+CONFIG_NET_EMATCH_CMP=m
+CONFIG_NET_EMATCH_NBYTE=m
+CONFIG_NET_EMATCH_U32=m
+CONFIG_NET_EMATCH_META=m
+CONFIG_NET_EMATCH_TEXT=m
+CONFIG_NET_CLS_ACT=y
+CONFIG_NET_ACT_POLICE=m
+CONFIG_NET_ACT_GACT=m
+CONFIG_GACT_PROB=y
+CONFIG_NET_ACT_MIRRED=m
+CONFIG_NET_ACT_IPT=m
+CONFIG_NET_ACT_PEDIT=m
+CONFIG_NET_ACT_SIMP=m
+CONFIG_NET_CLS_IND=y
+CONFIG_NET_ESTIMATOR=y
+
+#
+# Network testing
+#
+CONFIG_NET_PKTGEN=m
+# CONFIG_NET_TCPPROBE is not set
+# CONFIG_HAMRADIO is not set
+CONFIG_IRDA=m
+
+#
+# IrDA protocols
+#
+CONFIG_IRLAN=m
+CONFIG_IRNET=m
+CONFIG_IRCOMM=m
+# CONFIG_IRDA_ULTRA is not set
+
+#
+# IrDA options
+#
+CONFIG_IRDA_CACHE_LAST_LSAP=y
+CONFIG_IRDA_FAST_RR=y
+# CONFIG_IRDA_DEBUG is not set
+
+#
+# Infrared-port device drivers
+#
+
+#
+# SIR device drivers
+#
+CONFIG_IRTTY_SIR=m
+
+#
+# Dongle support
+#
+# CONFIG_DONGLE is not set
+
+#
+# Old SIR device drivers
+#
+
+#
+# Old Serial dongle support
+#
+
+#
+# FIR device drivers
+#
+CONFIG_NSC_FIR=m
+CONFIG_WINBOND_FIR=m
+CONFIG_SMC_IRCC_FIR=m
+CONFIG_ALI_FIR=m
+CONFIG_VIA_FIR=m
+# CONFIG_BT is not set
+# CONFIG_IEEE80211 is not set
+CONFIG_TUX=m
+
+#
+# TUX options
+#
+CONFIG_TUX_EXTCGI=y
+CONFIG_TUX_EXTENDED_LOG=y
+# CONFIG_TUX_DEBUG is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=m
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_SYS_HYPERVISOR is not set
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+CONFIG_CONNECTOR=y
+CONFIG_PROC_EVENTS=y
+
+#
+# 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_FD=m
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=m
+CONFIG_BLK_DEV_CRYPTOLOOP=m
+CONFIG_BLK_DEV_NBD=m
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=16384
+CONFIG_BLK_DEV_RAM_BLOCKSIZE=4096
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_CDROM_PKTCDVD=m
+CONFIG_CDROM_PKTCDVD_BUFFERS=8
+# CONFIG_CDROM_PKTCDVD_WCACHE is not set
+CONFIG_ATA_OVER_ETH=m
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+CONFIG_IDE=y
+CONFIG_BLK_DEV_IDE=y
+
+#
+# Please see Documentation/ide.txt for help/info on IDE drives
+#
+# CONFIG_BLK_DEV_IDE_SATA is not set
+# CONFIG_BLK_DEV_HD_IDE is not set
+CONFIG_BLK_DEV_IDEDISK=y
+CONFIG_IDEDISK_MULTI_MODE=y
+CONFIG_BLK_DEV_IDECD=m
+# CONFIG_BLK_DEV_IDETAPE is not set
+CONFIG_BLK_DEV_IDEFLOPPY=y
+CONFIG_BLK_DEV_IDESCSI=m
+CONFIG_IDE_TASK_IOCTL=y
+
+#
+# IDE chipset support/bugfixes
+#
+CONFIG_IDE_GENERIC=y
+CONFIG_BLK_DEV_CMD640=y
+CONFIG_BLK_DEV_CMD640_ENHANCED=y
+# CONFIG_IDE_ARM is not set
+# CONFIG_BLK_DEV_IDEDMA is not set
+# CONFIG_IDEDMA_AUTO is not set
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# SCSI device support
+#
+CONFIG_RAID_ATTRS=m
+CONFIG_SCSI=m
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=m
+CONFIG_CHR_DEV_ST=m
+CONFIG_CHR_DEV_OSST=m
+CONFIG_BLK_DEV_SR=m
+CONFIG_BLK_DEV_SR_VENDOR=y
+CONFIG_CHR_DEV_SG=m
+CONFIG_CHR_DEV_SCH=m
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+CONFIG_SCSI_MULTI_LUN=y
+CONFIG_SCSI_CONSTANTS=y
+CONFIG_SCSI_LOGGING=y
+
+#
+# SCSI Transport Attributes
+#
+CONFIG_SCSI_SPI_ATTRS=m
+CONFIG_SCSI_FC_ATTRS=m
+CONFIG_SCSI_ISCSI_ATTRS=m
+CONFIG_SCSI_SAS_ATTRS=m
+
+#
+# SCSI low-level drivers
+#
+CONFIG_ISCSI_TCP=m
+CONFIG_SCSI_SATA=m
+# CONFIG_SCSI_DEBUG is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+CONFIG_MD=y
+CONFIG_BLK_DEV_MD=y
+CONFIG_MD_LINEAR=m
+CONFIG_MD_RAID0=m
+CONFIG_MD_RAID1=m
+CONFIG_MD_RAID10=m
+CONFIG_MD_RAID456=m
+CONFIG_MD_RAID5_RESHAPE=y
+CONFIG_MD_MULTIPATH=m
+CONFIG_MD_FAULTY=m
+CONFIG_BLK_DEV_DM=m
+CONFIG_DM_CRYPT=m
+CONFIG_DM_SNAPSHOT=m
+CONFIG_DM_MIRROR=m
+CONFIG_DM_ZERO=m
+CONFIG_DM_MULTIPATH=m
+CONFIG_DM_MULTIPATH_EMC=m
+
+#
+# Fusion MPT device support
+#
+# CONFIG_FUSION is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+
+#
+# I2O device support
+#
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+CONFIG_IFB=m
+CONFIG_DUMMY=m
+CONFIG_BONDING=m
+CONFIG_EQUALIZER=m
+CONFIG_TUN=m
+
+#
+# PHY device support
+#
+# CONFIG_PHYLIB is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=m
+
+#
+# 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
+
+#
+# ATM drivers
+#
+# CONFIG_ATM_DUMMY is not set
+CONFIG_ATM_TCP=m
+CONFIG_PPP=m
+CONFIG_PPP_MULTILINK=y
+CONFIG_PPP_FILTER=y
+CONFIG_PPP_ASYNC=m
+CONFIG_PPP_SYNC_TTY=m
+CONFIG_PPP_DEFLATE=m
+# CONFIG_PPP_BSDCOMP is not set
+CONFIG_PPP_MPPE=m
+CONFIG_PPPOE=m
+CONFIG_PPPOATM=m
+CONFIG_SLIP=m
+CONFIG_SLIP_COMPRESSED=y
+CONFIG_SLIP_SMART=y
+# CONFIG_SLIP_MODE_SLIP6 is not set
+# CONFIG_SHAPER is not set
+CONFIG_NETCONSOLE=m
+CONFIG_NETPOLL=y
+# CONFIG_NETPOLL_RX is not set
+CONFIG_NETPOLL_TRAP=y
+CONFIG_NET_POLL_CONTROLLER=y
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Telephony Support
+#
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+
+#
+# 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=m
+# CONFIG_INPUT_TSDEV is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+CONFIG_KEYBOARD_ATKBD=y
+# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_KEYBOARD_LKKBD is not set
+# CONFIG_KEYBOARD_XTKBD is not set
+# CONFIG_KEYBOARD_NEWTON is not set
+CONFIG_INPUT_MOUSE=y
+CONFIG_MOUSE_PS2=y
+CONFIG_MOUSE_SERIAL=m
+CONFIG_MOUSE_VSXXXAA=m
+CONFIG_INPUT_JOYSTICK=y
+CONFIG_JOYSTICK_ANALOG=m
+CONFIG_JOYSTICK_A3D=m
+CONFIG_JOYSTICK_ADI=m
+CONFIG_JOYSTICK_COBRA=m
+CONFIG_JOYSTICK_GF2K=m
+CONFIG_JOYSTICK_GRIP=m
+CONFIG_JOYSTICK_GRIP_MP=m
+CONFIG_JOYSTICK_GUILLEMOT=m
+CONFIG_JOYSTICK_INTERACT=m
+CONFIG_JOYSTICK_SIDEWINDER=m
+CONFIG_JOYSTICK_TMDC=m
+CONFIG_JOYSTICK_IFORCE=m
+CONFIG_JOYSTICK_IFORCE_232=y
+CONFIG_JOYSTICK_WARRIOR=m
+CONFIG_JOYSTICK_MAGELLAN=m
+CONFIG_JOYSTICK_SPACEORB=m
+CONFIG_JOYSTICK_SPACEBALL=m
+CONFIG_JOYSTICK_STINGER=m
+CONFIG_JOYSTICK_TWIDJOY=m
+CONFIG_JOYSTICK_JOYDUMP=m
+CONFIG_INPUT_TOUCHSCREEN=y
+CONFIG_TOUCHSCREEN_GUNZE=m
+CONFIG_TOUCHSCREEN_ELO=m
+CONFIG_TOUCHSCREEN_MTOUCH=m
+CONFIG_TOUCHSCREEN_MK712=m
+CONFIG_INPUT_MISC=y
+CONFIG_INPUT_PCSPKR=m
+CONFIG_INPUT_WISTRON_BTNS=m
+CONFIG_INPUT_UINPUT=m
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+CONFIG_SERIO_I8042=y
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_CT82C710 is not set
+CONFIG_SERIO_LIBPS2=y
+CONFIG_SERIO_RAW=m
+CONFIG_GAMEPORT=m
+CONFIG_GAMEPORT_NS558=m
+CONFIG_GAMEPORT_L4=m
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+CONFIG_VT_HW_CONSOLE_BINDING=y
+CONFIG_SERIAL_NONSTANDARD=y
+# CONFIG_COMPUTONE is not set
+# CONFIG_ROCKETPORT is not set
+CONFIG_CYCLADES=m
+# CONFIG_CYZ_INTR is not set
+# CONFIG_DIGIEPCA is not set
+# CONFIG_MOXA_INTELLIO is not set
+# CONFIG_MOXA_SMARTIO is not set
+# CONFIG_ISI is not set
+CONFIG_SYNCLINKMP=m
+CONFIG_N_HDLC=m
+# CONFIG_SPECIALIX is not set
+# CONFIG_SX is not set
+# CONFIG_RIO is not set
+# CONFIG_STALDRV is not set
+
+#
+# Serial drivers
+#
+
+#
+# Non-8250 serial port support
+#
+CONFIG_UNIX98_PTYS=y
+# CONFIG_LEGACY_PTYS is not set
+CONFIG_CRASH=m
+
+#
+# IPMI
+#
+CONFIG_IPMI_HANDLER=m
+# CONFIG_IPMI_PANIC_EVENT is not set
+CONFIG_IPMI_DEVICE_INTERFACE=m
+CONFIG_IPMI_SI=m
+CONFIG_IPMI_WATCHDOG=m
+CONFIG_IPMI_POWEROFF=m
+
+#
+# Watchdog Cards
+#
+CONFIG_WATCHDOG=y
+# CONFIG_WATCHDOG_NOWAYOUT is not set
+
+#
+# Watchdog Device Drivers
+#
+CONFIG_SOFT_WATCHDOG=m
+# CONFIG_ACQUIRE_WDT is not set
+# CONFIG_ADVANTECH_WDT is not set
+# CONFIG_SC520_WDT is not set
+# CONFIG_EUROTECH_WDT is not set
+# CONFIG_IB700_WDT is not set
+CONFIG_IBMASR=m
+# CONFIG_WAFER_WDT is not set
+# CONFIG_SC1200_WDT is not set
+# CONFIG_60XX_WDT is not set
+# CONFIG_SBC8360_WDT is not set
+# CONFIG_CPU5_WDT is not set
+CONFIG_W83627HF_WDT=m
+CONFIG_W83877F_WDT=m
+CONFIG_W83977F_WDT=m
+CONFIG_MACHZ_WDT=m
+# CONFIG_SBC_EPX_C3_WATCHDOG is not set
+CONFIG_HW_RANDOM=y
+CONFIG_HW_RANDOM_VIA=m
+CONFIG_NVRAM=y
+CONFIG_RTC=y
+CONFIG_DTLK=m
+CONFIG_R3964=m
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_MWAVE is not set
+CONFIG_PC8736x_GPIO=m
+CONFIG_NSC_GPIO=m
+# CONFIG_CS5535_GPIO is not set
+# CONFIG_RAW_DRIVER is not set
+CONFIG_HANGCHECK_TIMER=m
+
+#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+# CONFIG_TELCLOCK 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
+#
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+CONFIG_VIDEO_V4L2=y
+
+#
+# Digital Video Broadcasting Devices
+#
+# CONFIG_DVB is not set
+
+#
+# Graphics support
+#
+# CONFIG_FIRMWARE_EDID is not set
+CONFIG_FB=y
+CONFIG_FB_CFB_FILLRECT=y
+CONFIG_FB_CFB_COPYAREA=y
+CONFIG_FB_CFB_IMAGEBLIT=y
+# CONFIG_FB_MACMODES is not set
+# CONFIG_FB_BACKLIGHT is not set
+# CONFIG_FB_MODE_HELPERS is not set
+CONFIG_FB_TILEBLITTING=y
+# CONFIG_FB_ARC is not set
+CONFIG_FB_VGA16=m
+CONFIG_FB_VESA=y
+# CONFIG_FB_HGA is not set
+# CONFIG_FB_S1D13XXX is not set
+# CONFIG_FB_VIRTUAL is not set
+
+#
+# Console display driver support
+#
+CONFIG_VGA_CONSOLE=y
+CONFIG_VGACON_SOFT_SCROLLBACK=y
+CONFIG_VGACON_SOFT_SCROLLBACK_SIZE=64
+CONFIG_VIDEO_SELECT=y
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y
+# CONFIG_FONTS is not set
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
+
+#
+# Logo configuration
+#
+CONFIG_LOGO=y
+# CONFIG_LOGO_LINUX_MONO is not set
+# CONFIG_LOGO_LINUX_VGA16 is not set
+CONFIG_LOGO_LINUX_CLUT224=y
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+CONFIG_BACKLIGHT_CLASS_DEVICE=m
+CONFIG_BACKLIGHT_DEVICE=y
+CONFIG_LCD_CLASS_DEVICE=m
+CONFIG_LCD_DEVICE=y
+
+#
+# Sound
+#
+CONFIG_SOUND=m
+
+#
+# Advanced Linux Sound Architecture
+#
+# CONFIG_SND is not set
+
+#
+# Open Sound System
+#
+# CONFIG_SOUND_PRIME is not set
+
+#
+# USB support
+#
+# CONFIG_USB_ARCH_HAS_HCD is not set
+# CONFIG_USB_ARCH_HAS_OHCI is not set
+# CONFIG_USB_ARCH_HAS_EHCI 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
+
+#
+# LED devices
+#
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+
+#
+# LED drivers
+#
+
+#
+# LED Triggers
+#
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_LEDS_TRIGGER_TIMER=m
+CONFIG_LEDS_TRIGGER_IDE_DISK=y
+CONFIG_LEDS_TRIGGER_HEARTBEAT=m
+
+#
+# InfiniBand support
+#
+
+#
+# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
+#
+# CONFIG_EDAC is not set
+
+#
+# Real Time Clock
+#
+CONFIG_RTC_LIB=m
+CONFIG_RTC_CLASS=m
+
+#
+# RTC interfaces
+#
+CONFIG_RTC_INTF_SYSFS=m
+CONFIG_RTC_INTF_PROC=m
+CONFIG_RTC_INTF_DEV=m
+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
+
+#
+# RTC drivers
+#
+CONFIG_RTC_DRV_DS1553=m
+CONFIG_RTC_DRV_DS1742=m
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_TEST is not set
+CONFIG_RTC_DRV_V3020=m
+
+#
+# DMA Engine support
+#
+CONFIG_DMA_ENGINE=y
+
+#
+# DMA Clients
+#
+CONFIG_NET_DMA=y
+
+#
+# DMA Devices
+#
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+CONFIG_EXT2_FS_POSIX_ACL=y
+CONFIG_EXT2_FS_SECURITY=y
+CONFIG_EXT2_FS_XIP=y
+CONFIG_FS_XIP=y
+CONFIG_EXT3_FS=y
+CONFIG_EXT3_FS_XATTR=y
+CONFIG_EXT3_FS_POSIX_ACL=y
+CONFIG_EXT3_FS_SECURITY=y
+CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
+CONFIG_FS_MBCACHE=y
+CONFIG_REISERFS_FS=m
+# CONFIG_REISERFS_CHECK is not set
+CONFIG_REISERFS_PROC_INFO=y
+CONFIG_REISERFS_FS_XATTR=y
+CONFIG_REISERFS_FS_POSIX_ACL=y
+CONFIG_REISERFS_FS_SECURITY=y
+CONFIG_JFS_FS=m
+CONFIG_JFS_POSIX_ACL=y
+CONFIG_JFS_SECURITY=y
+# CONFIG_JFS_DEBUG is not set
+# CONFIG_JFS_STATISTICS is not set
+CONFIG_FS_POSIX_ACL=y
+CONFIG_XFS_FS=m
+CONFIG_XFS_QUOTA=y
+CONFIG_XFS_SECURITY=y
+CONFIG_XFS_POSIX_ACL=y
+# CONFIG_XFS_RT is not set
+CONFIG_OCFS2_FS=m
+# CONFIG_OCFS2_DEBUG_MASKLOG is not set
+CONFIG_MINIX_FS=m
+CONFIG_ROMFS_FS=m
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+CONFIG_QUOTA=y
+# CONFIG_QFMT_V1 is not set
+CONFIG_QFMT_V2=y
+CONFIG_QUOTACTL=y
+CONFIG_DNOTIFY=y
+CONFIG_AUTOFS_FS=m
+CONFIG_AUTOFS4_FS=m
+CONFIG_FUSE_FS=m
+
+#
+# Caches
+#
+CONFIG_FSCACHE=m
+
+#
+# CD-ROM/DVD Filesystems
+#
+CONFIG_ISO9660_FS=y
+CONFIG_JOLIET=y
+CONFIG_ZISOFS=y
+CONFIG_ZISOFS_FS=y
+CONFIG_UDF_FS=m
+CONFIG_UDF_NLS=y
+CONFIG_CACHEFILES=m
+CONFIG_CACHEFILES_DEBUG=y
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=m
+CONFIG_MSDOS_FS=m
+CONFIG_VFAT_FS=m
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="ascii"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_RAMFS=y
+CONFIG_CONFIGFS_FS=m
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+CONFIG_AFFS_FS=m
+CONFIG_HFS_FS=m
+CONFIG_HFSPLUS_FS=m
+CONFIG_BEFS_FS=m
+# CONFIG_BEFS_DEBUG is not set
+CONFIG_BFS_FS=m
+CONFIG_EFS_FS=m
+CONFIG_CRAMFS=m
+CONFIG_SQUASHFS=m
+# CONFIG_SQUASHFS_EMBEDDED is not set
+CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3
+# CONFIG_SQUASHFS_VMALLOC is not set
+CONFIG_VXFS_FS=m
+# CONFIG_HPFS_FS is not set
+CONFIG_QNX4FS_FS=m
+CONFIG_SYSV_FS=m
+CONFIG_UFS_FS=m
+# CONFIG_UFS_FS_WRITE is not set
+# CONFIG_UFS_DEBUG is not set
+
+#
+# Network File Systems
+#
+CONFIG_NFS_FS=m
+CONFIG_NFS_V3=y
+CONFIG_NFS_V3_ACL=y
+CONFIG_NFS_V4=y
+CONFIG_NFS_FSCACHE=y
+CONFIG_NFS_DIRECTIO=y
+CONFIG_NFSD=m
+CONFIG_NFSD_V2_ACL=y
+CONFIG_NFSD_V3=y
+CONFIG_NFSD_V3_ACL=y
+CONFIG_NFSD_V4=y
+CONFIG_NFSD_TCP=y
+CONFIG_LOCKD=m
+CONFIG_LOCKD_V4=y
+CONFIG_EXPORTFS=m
+CONFIG_NFS_ACL_SUPPORT=m
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=m
+CONFIG_SUNRPC_GSS=m
+CONFIG_RPCSEC_GSS_KRB5=m
+CONFIG_RPCSEC_GSS_SPKM3=m
+# CONFIG_SMB_FS is not set
+CONFIG_CIFS=m
+# CONFIG_CIFS_STATS is not set
+CONFIG_CIFS_WEAK_PW_HASH=y
+CONFIG_CIFS_XATTR=y
+CONFIG_CIFS_POSIX=y
+# CONFIG_CIFS_DEBUG2 is not set
+# CONFIG_CIFS_EXPERIMENTAL is not set
+CONFIG_NCP_FS=m
+CONFIG_NCPFS_PACKET_SIGNING=y
+CONFIG_NCPFS_IOCTL_LOCKING=y
+CONFIG_NCPFS_STRONG=y
+CONFIG_NCPFS_NFS_NS=y
+CONFIG_NCPFS_OS2_NS=y
+CONFIG_NCPFS_SMALLDOS=y
+CONFIG_NCPFS_NLS=y
+CONFIG_NCPFS_EXTRAS=y
+CONFIG_CODA_FS=m
+# CONFIG_CODA_FS_OLD_API is not set
+# CONFIG_AFS_FS is not set
+CONFIG_9P_FS=m
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+CONFIG_OSF_PARTITION=y
+CONFIG_AMIGA_PARTITION=y
+# CONFIG_ATARI_PARTITION is not set
+CONFIG_MAC_PARTITION=y
+CONFIG_MSDOS_PARTITION=y
+CONFIG_BSD_DISKLABEL=y
+CONFIG_MINIX_SUBPARTITION=y
+CONFIG_SOLARIS_X86_PARTITION=y
+CONFIG_UNIXWARE_DISKLABEL=y
+# CONFIG_LDM_PARTITION is not set
+CONFIG_SGI_PARTITION=y
+# CONFIG_ULTRIX_PARTITION is not set
+CONFIG_SUN_PARTITION=y
+CONFIG_KARMA_PARTITION=y
+CONFIG_EFI_PARTITION=y
+
+#
+# Native Language Support
+#
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="utf8"
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_CODEPAGE_737=m
+CONFIG_NLS_CODEPAGE_775=m
+CONFIG_NLS_CODEPAGE_850=m
+CONFIG_NLS_CODEPAGE_852=m
+CONFIG_NLS_CODEPAGE_855=m
+CONFIG_NLS_CODEPAGE_857=m
+CONFIG_NLS_CODEPAGE_860=m
+CONFIG_NLS_CODEPAGE_861=m
+CONFIG_NLS_CODEPAGE_862=m
+CONFIG_NLS_CODEPAGE_863=m
+CONFIG_NLS_CODEPAGE_864=m
+CONFIG_NLS_CODEPAGE_865=m
+CONFIG_NLS_CODEPAGE_866=m
+CONFIG_NLS_CODEPAGE_869=m
+CONFIG_NLS_CODEPAGE_936=m
+CONFIG_NLS_CODEPAGE_950=m
+CONFIG_NLS_CODEPAGE_932=m
+CONFIG_NLS_CODEPAGE_949=m
+CONFIG_NLS_CODEPAGE_874=m
+CONFIG_NLS_ISO8859_8=m
+CONFIG_NLS_CODEPAGE_1250=m
+CONFIG_NLS_CODEPAGE_1251=m
+CONFIG_NLS_ASCII=y
+CONFIG_NLS_ISO8859_1=m
+CONFIG_NLS_ISO8859_2=m
+CONFIG_NLS_ISO8859_3=m
+CONFIG_NLS_ISO8859_4=m
+CONFIG_NLS_ISO8859_5=m
+CONFIG_NLS_ISO8859_6=m
+CONFIG_NLS_ISO8859_7=m
+CONFIG_NLS_ISO8859_9=m
+CONFIG_NLS_ISO8859_13=m
+CONFIG_NLS_ISO8859_14=m
+CONFIG_NLS_ISO8859_15=m
+CONFIG_NLS_KOI8_R=m
+CONFIG_NLS_KOI8_U=m
+CONFIG_NLS_UTF8=m
+
+#
+# Instrumentation Support
+#
+CONFIG_PROFILING=y
+CONFIG_OPROFILE=m
+CONFIG_KPROBES=y
+
+#
+# Kernel hacking
+#
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+# CONFIG_PRINTK_TIME is not set
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_UNUSED_SYMBOLS is not set
+CONFIG_DEBUG_KERNEL=y
+CONFIG_LOG_BUF_SHIFT=17
+CONFIG_DETECT_SOFTLOCKUP=y
+CONFIG_SCHEDSTATS=y
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
+CONFIG_DEBUG_SPINLOCK=y
+# 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=y
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+# CONFIG_DEBUG_KOBJECT is not set
+CONFIG_DEBUG_HIGHMEM=y
+CONFIG_DEBUG_BUGVERBOSE=y
+CONFIG_DEBUG_INFO=y
+CONFIG_DEBUG_FS=y
+# CONFIG_DEBUG_VM is not set
+CONFIG_DEBUG_LIST=y
+# CONFIG_FRAME_POINTER is not set
+CONFIG_UNWIND_INFO=y
+CONFIG_STACK_UNWIND=y
+# CONFIG_FORCED_INLINING is not set
+CONFIG_BOOT_DELAY=y
+# CONFIG_RCU_TORTURE_TEST is not set
+CONFIG_EARLY_PRINTK=y
+CONFIG_DEBUG_STACKOVERFLOW=y
+CONFIG_DEBUG_STACK_USAGE=y
+# CONFIG_DEBUG_PAGEALLOC is not set
+CONFIG_DEBUG_RODATA=y
+CONFIG_4KSTACKS=y
+
+#
+# Security options
+#
+CONFIG_KEYS=y
+CONFIG_KEYS_DEBUG_PROC_KEYS=y
+CONFIG_SECURITY=y
+CONFIG_SECURITY_NETWORK=y
+# CONFIG_SECURITY_NETWORK_XFRM is not set
+CONFIG_SECURITY_CAPABILITIES=y
+# CONFIG_SECURITY_SECLVL is not set
+CONFIG_SECURITY_SELINUX=y
+CONFIG_SECURITY_SELINUX_BOOTPARAM=y
+CONFIG_SECURITY_SELINUX_BOOTPARAM_VALUE=1
+CONFIG_SECURITY_SELINUX_DISABLE=y
+CONFIG_SECURITY_SELINUX_DEVELOP=y
+CONFIG_SECURITY_SELINUX_AVC_STATS=y
+CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE=1
+# CONFIG_SECURITY_SELINUX_ENABLE_SECMARK_DEFAULT is not set
+# CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX is not set
+
+#
+# Cryptographic options
+#
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_NULL=m
+CONFIG_CRYPTO_MD4=m
+CONFIG_CRYPTO_MD5=m
+CONFIG_CRYPTO_SHA1=y
+CONFIG_CRYPTO_SHA256=m
+CONFIG_CRYPTO_SHA512=m
+CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_TGR192=m
+CONFIG_CRYPTO_DES=m
+CONFIG_CRYPTO_BLOWFISH=m
+CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_SERPENT=m
+CONFIG_CRYPTO_AES=m
+CONFIG_CRYPTO_AES_586=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_TEST is not set
+CONFIG_CRYPTO_SIGNATURE=y
+CONFIG_CRYPTO_SIGNATURE_DSA=y
+CONFIG_CRYPTO_MPILIB=y
+
+#
+# Hardware crypto devices
+#
+# CONFIG_CRYPTO_DEV_PADLOCK is not set
+CONFIG_XEN=y
+CONFIG_XEN_INTERFACE_VERSION=0x00030203
+
+#
+# XEN
+#
+# CONFIG_XEN_PRIVILEGED_GUEST is not set
+CONFIG_XEN_UNPRIVILEGED_GUEST=y
+CONFIG_XEN_PRIVCMD=y
+CONFIG_XEN_XENBUS_DEV=y
+CONFIG_XEN_BACKEND=y
+# CONFIG_XEN_BLKDEV_BACKEND is not set
+CONFIG_XEN_BLKDEV_TAP=m
+# CONFIG_XEN_NETDEV_BACKEND is not set
+# CONFIG_XEN_TPMDEV_BACKEND is not set
+CONFIG_XEN_BLKDEV_FRONTEND=y
+CONFIG_XEN_NETDEV_FRONTEND=m
+CONFIG_XEN_FRAMEBUFFER=y
+CONFIG_XEN_KEYBOARD=y
+CONFIG_XEN_SCRUB_PAGES=y
+CONFIG_XEN_DISABLE_SERIAL=y
+CONFIG_XEN_SYSFS=y
+CONFIG_XEN_COMPAT_030002_AND_LATER=y
+# CONFIG_XEN_COMPAT_LATEST_ONLY is not set
+CONFIG_XEN_COMPAT_030002=y
+CONFIG_HAVE_ARCH_ALLOC_SKB=y
+CONFIG_HAVE_ARCH_DEV_ALLOC_SKB=y
+CONFIG_HAVE_IRQ_IGNORE_UNHANDLED=y
+CONFIG_NO_IDLE_HZ=y
+CONFIG_XEN_UTIL=y
+CONFIG_XEN_BALLOON=y
+CONFIG_XEN_DEVMEM=y
+CONFIG_XEN_SKBUFF=y
+CONFIG_XEN_REBOOT=y
+CONFIG_XEN_SMPBOOT=y
+
+#
+# Library routines
+#
+CONFIG_CRC_CCITT=m
+CONFIG_CRC16=m
+CONFIG_CRC32=y
+CONFIG_LIBCRC32C=m
+CONFIG_AUDIT_GENERIC=y
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=m
+CONFIG_TEXTSEARCH=y
+CONFIG_TEXTSEARCH_KMP=m
+CONFIG_TEXTSEARCH_BM=m
+CONFIG_TEXTSEARCH_FSM=m
+CONFIG_PLIST=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_GENERIC_PENDING_IRQ=y
+CONFIG_X86_SMP=y
+CONFIG_X86_BIOS_REBOOT=y
+CONFIG_X86_TRAMPOLINE=y
+CONFIG_X86_NO_TSS=y
+CONFIG_X86_NO_IDT=y
+CONFIG_KTIME_SCALAR=y
diff --git a/configs/kernel-2.6.18-i686.config b/configs/kernel-2.6.18-i686.config
new file mode 100644
index 000000000..96690dc15
--- /dev/null
+++ b/configs/kernel-2.6.18-i686.config
@@ -0,0 +1,3416 @@
+# i386
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.18.2-rc1
+# Mon Nov 13 09:44:41 2006
+#
+CONFIG_X86_32=y
+CONFIG_GENERIC_TIME=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_SEMAPHORE_SLEEPERS=y
+CONFIG_X86=y
+CONFIG_MMU=y
+CONFIG_GENERIC_ISA_DMA=y
+CONFIG_GENERIC_IOMAP=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_ARCH_MAY_HAVE_PC_FDC=y
+CONFIG_DMI=y
+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=y
+CONFIG_SYSVIPC=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_BSD_PROCESS_ACCT=y
+# CONFIG_BSD_PROCESS_ACCT_V3 is not set
+CONFIG_TASKSTATS=y
+CONFIG_TASK_DELAY_ACCT=y
+CONFIG_AUDIT=y
+CONFIG_AUDITSYSCALL=y
+# CONFIG_IKCONFIG is not set
+CONFIG_RELAY=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+# CONFIG_EMBEDDED is not set
+CONFIG_UID16=y
+CONFIG_SYSCTL=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
+CONFIG_KALLSYMS_EXTRA_PASS=y
+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=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+CONFIG_MODULE_SIG=y
+# CONFIG_MODULE_SIG_FORCE is not set
+CONFIG_KMOD=y
+
+#
+# Process debugging support
+#
+CONFIG_UTRACE=y
+CONFIG_PTRACE=y
+
+#
+# Block layer
+#
+CONFIG_LBD=y
+CONFIG_BLK_DEV_IO_TRACE=y
+CONFIG_LSF=y
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_DEFAULT_AS is not set
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+
+#
+# Processor type and features
+#
+# CONFIG_SMP is not set
+CONFIG_X86_PC=y
+# CONFIG_X86_XEN is not set
+# CONFIG_X86_ELAN is not set
+# CONFIG_X86_VOYAGER is not set
+# CONFIG_X86_NUMAQ is not set
+# CONFIG_X86_SUMMIT is not set
+# CONFIG_X86_BIGSMP is not set
+# CONFIG_X86_VISWS is not set
+# CONFIG_X86_GENERICARCH is not set
+# CONFIG_X86_ES7000 is not set
+# CONFIG_M386 is not set
+# CONFIG_M486 is not set
+# CONFIG_M586 is not set
+# CONFIG_M586TSC is not set
+# CONFIG_M586MMX is not set
+CONFIG_M686=y
+# CONFIG_MPENTIUMII is not set
+# CONFIG_MPENTIUMIII is not set
+# CONFIG_MPENTIUMM is not set
+# CONFIG_MPENTIUM4 is not set
+# CONFIG_MK6 is not set
+# CONFIG_MK7 is not set
+# CONFIG_MK8 is not set
+# CONFIG_MCRUSOE is not set
+# CONFIG_MEFFICEON is not set
+# CONFIG_MWINCHIPC6 is not set
+# CONFIG_MWINCHIP2 is not set
+# CONFIG_MWINCHIP3D is not set
+# CONFIG_MGEODEGX1 is not set
+# CONFIG_MGEODE_LX is not set
+# CONFIG_MCYRIXIII is not set
+# CONFIG_MVIAC3_2 is not set
+CONFIG_X86_GENERIC=y
+CONFIG_X86_CMPXCHG=y
+CONFIG_X86_XADD=y
+CONFIG_X86_L1_CACHE_SHIFT=7
+CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_X86_PPRO_FENCE=y
+CONFIG_X86_WP_WORKS_OK=y
+CONFIG_X86_INVLPG=y
+CONFIG_X86_BSWAP=y
+CONFIG_X86_POPAD_OK=y
+CONFIG_X86_CMPXCHG64=y
+CONFIG_X86_GOOD_APIC=y
+CONFIG_X86_INTEL_USERCOPY=y
+CONFIG_X86_USE_PPRO_CHECKSUM=y
+CONFIG_X86_TSC=y
+CONFIG_HPET_TIMER=y
+CONFIG_HPET_EMULATE_RTC=y
+# CONFIG_PREEMPT_NONE is not set
+CONFIG_PREEMPT_VOLUNTARY=y
+# CONFIG_PREEMPT is not set
+CONFIG_X86_UP_APIC=y
+CONFIG_X86_UP_IOAPIC=y
+CONFIG_X86_LOCAL_APIC=y
+CONFIG_X86_APIC_AUTO=y
+CONFIG_X86_IO_APIC=y
+CONFIG_X86_MCE=y
+# CONFIG_X86_MCE_NONFATAL is not set
+CONFIG_X86_MCE_P4THERMAL=y
+CONFIG_VM86=y
+CONFIG_TOSHIBA=m
+CONFIG_I8K=m
+# CONFIG_X86_REBOOTFIXUPS is not set
+CONFIG_MICROCODE=m
+CONFIG_X86_MSR=m
+CONFIG_X86_CPUID=m
+# CONFIG_SWIOTLB is not set
+
+#
+# Firmware Drivers
+#
+CONFIG_EDD=m
+CONFIG_EFI_VARS=y
+CONFIG_DELL_RBU=m
+CONFIG_DCDBAS=m
+# CONFIG_NOHIGHMEM is not set
+CONFIG_HIGHMEM4G=y
+# CONFIG_HIGHMEM64G is not set
+CONFIG_PAGE_OFFSET=0xC0000000
+CONFIG_HIGHMEM=y
+CONFIG_ARCH_FLATMEM_ENABLE=y
+CONFIG_ARCH_SPARSEMEM_ENABLE=y
+CONFIG_ARCH_SELECT_MEMORY_MODEL=y
+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=y
+CONFIG_SPLIT_PTLOCK_CPUS=4096
+CONFIG_RESOURCES_64BIT=y
+CONFIG_HIGHPTE=y
+# CONFIG_MATH_EMULATION is not set
+CONFIG_MTRR=y
+CONFIG_EFI=y
+CONFIG_BOOT_IOREMAP=y
+CONFIG_REGPARM=y
+# CONFIG_SECCOMP is not set
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
+CONFIG_KEXEC=y
+# CONFIG_CRASH_DUMP is not set
+CONFIG_PHYSICAL_START=0x400000
+# CONFIG_COMPAT_VDSO is not set
+CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
+
+#
+# Power management options (ACPI, APM)
+#
+CONFIG_PM=y
+CONFIG_PM_LEGACY=y
+# CONFIG_PM_DEBUG is not set
+CONFIG_SOFTWARE_SUSPEND=y
+CONFIG_PM_STD_PARTITION=""
+
+#
+# ACPI (Advanced Configuration and Power Interface) Support
+#
+CONFIG_ACPI=y
+CONFIG_ACPI_SLEEP=y
+CONFIG_ACPI_SLEEP_PROC_FS=y
+# CONFIG_ACPI_SLEEP_PROC_SLEEP is not set
+CONFIG_ACPI_AC=m
+CONFIG_ACPI_BATTERY=m
+CONFIG_ACPI_BUTTON=m
+CONFIG_ACPI_VIDEO=m
+# CONFIG_ACPI_HOTKEY is not set
+CONFIG_ACPI_FAN=y
+CONFIG_ACPI_DOCK=m
+CONFIG_ACPI_PROCESSOR=y
+CONFIG_ACPI_THERMAL=y
+CONFIG_ACPI_ASUS=m
+CONFIG_ACPI_IBM=m
+CONFIG_ACPI_TOSHIBA=m
+CONFIG_ACPI_BLACKLIST_YEAR=1999
+# CONFIG_ACPI_DEBUG is not set
+CONFIG_ACPI_EC=y
+CONFIG_ACPI_POWER=y
+CONFIG_ACPI_SYSTEM=y
+CONFIG_X86_PM_TIMER=y
+CONFIG_ACPI_CONTAINER=m
+CONFIG_ACPI_SBS=m
+
+#
+# APM (Advanced Power Management) BIOS Support
+#
+CONFIG_APM=y
+# CONFIG_APM_IGNORE_USER_SUSPEND is not set
+# CONFIG_APM_DO_ENABLE is not set
+CONFIG_APM_CPU_IDLE=y
+# CONFIG_APM_DISPLAY_BLANK is not set
+CONFIG_APM_RTC_IS_GMT=y
+# CONFIG_APM_ALLOW_INTS is not set
+# CONFIG_APM_REAL_MODE_POWER_OFF is not set
+
+#
+# CPU Frequency scaling
+#
+CONFIG_CPU_FREQ=y
+CONFIG_CPU_FREQ_TABLE=y
+CONFIG_CPU_FREQ_DEBUG=y
+CONFIG_CPU_FREQ_STAT=m
+CONFIG_CPU_FREQ_STAT_DETAILS=y
+# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set
+CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE=y
+CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
+CONFIG_CPU_FREQ_GOV_POWERSAVE=m
+CONFIG_CPU_FREQ_GOV_USERSPACE=y
+CONFIG_CPU_FREQ_GOV_ONDEMAND=m
+CONFIG_CPU_FREQ_GOV_CONSERVATIVE=m
+
+#
+# CPUFreq processor drivers
+#
+CONFIG_X86_ACPI_CPUFREQ=m
+# CONFIG_X86_POWERNOW_K6 is not set
+CONFIG_X86_POWERNOW_K7=y
+CONFIG_X86_POWERNOW_K7_ACPI=y
+CONFIG_X86_POWERNOW_K8=y
+CONFIG_X86_POWERNOW_K8_ACPI=y
+# CONFIG_X86_GX_SUSPMOD is not set
+CONFIG_X86_SPEEDSTEP_CENTRINO=y
+CONFIG_X86_SPEEDSTEP_CENTRINO_ACPI=y
+CONFIG_X86_SPEEDSTEP_CENTRINO_TABLE=y
+CONFIG_X86_SPEEDSTEP_ICH=y
+CONFIG_X86_SPEEDSTEP_SMI=y
+CONFIG_X86_P4_CLOCKMOD=m
+# CONFIG_X86_CPUFREQ_NFORCE2 is not set
+CONFIG_X86_LONGRUN=y
+# CONFIG_X86_LONGHAUL is not set
+
+#
+# shared options
+#
+# CONFIG_X86_ACPI_CPUFREQ_PROC_INTF is not set
+CONFIG_X86_SPEEDSTEP_LIB=y
+# CONFIG_X86_SPEEDSTEP_RELAXED_CAP_CHECK is not set
+
+#
+# Bus options (PCI, PCMCIA, EISA, MCA, ISA)
+#
+CONFIG_PCI=y
+# CONFIG_PCI_GOBIOS is not set
+# CONFIG_PCI_GOMMCONFIG is not set
+# CONFIG_PCI_GODIRECT is not set
+# CONFIG_PCI_GOXEN_FE is not set
+CONFIG_PCI_GOANY=y
+CONFIG_PCI_BIOS=y
+CONFIG_PCI_DIRECT=y
+CONFIG_PCI_MMCONFIG=y
+CONFIG_PCIEPORTBUS=y
+CONFIG_HOTPLUG_PCI_PCIE=m
+# CONFIG_HOTPLUG_PCI_PCIE_POLL_EVENT_MODE is not set
+CONFIG_PCI_MSI=y
+# CONFIG_PCI_DEBUG is not set
+CONFIG_ISA_DMA_API=y
+CONFIG_ISA=y
+# CONFIG_EISA is not set
+# CONFIG_MCA is not set
+# CONFIG_SCx200 is not set
+CONFIG_K8_NB=y
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+CONFIG_PCCARD=y
+# CONFIG_PCMCIA_DEBUG is not set
+CONFIG_PCMCIA=y
+CONFIG_PCMCIA_LOAD_CIS=y
+CONFIG_PCMCIA_IOCTL=y
+CONFIG_CARDBUS=y
+
+#
+# PC-card bridges
+#
+CONFIG_YENTA=y
+CONFIG_YENTA_O2=y
+CONFIG_YENTA_RICOH=y
+CONFIG_YENTA_TI=y
+CONFIG_YENTA_ENE_TUNE=y
+CONFIG_YENTA_TOSHIBA=y
+CONFIG_PD6729=m
+CONFIG_I82092=m
+# CONFIG_I82365 is not set
+# CONFIG_TCIC is not set
+CONFIG_PCMCIA_PROBE=y
+CONFIG_PCCARD_NONSTATIC=y
+
+#
+# PCI Hotplug Support
+#
+CONFIG_HOTPLUG_PCI=y
+CONFIG_HOTPLUG_PCI_FAKE=m
+CONFIG_HOTPLUG_PCI_COMPAQ=m
+# CONFIG_HOTPLUG_PCI_COMPAQ_NVRAM is not set
+CONFIG_HOTPLUG_PCI_IBM=m
+CONFIG_HOTPLUG_PCI_ACPI=m
+CONFIG_HOTPLUG_PCI_ACPI_IBM=m
+# CONFIG_HOTPLUG_PCI_CPCI is not set
+# CONFIG_HOTPLUG_PCI_SHPC is not set
+
+#
+# Executable file formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_AOUT is not set
+CONFIG_BINFMT_MISC=y
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+# CONFIG_NETDEBUG is not set
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=y
+CONFIG_NET_KEY=m
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_ASK_IP_FIB_HASH=y
+# 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
+# CONFIG_IP_PNP is not set
+CONFIG_NET_IPIP=m
+CONFIG_NET_IPGRE=m
+CONFIG_NET_IPGRE_BROADCAST=y
+CONFIG_IP_MROUTE=y
+CONFIG_IP_PIMSM_V1=y
+CONFIG_IP_PIMSM_V2=y
+# CONFIG_ARPD is not set
+CONFIG_SYN_COOKIES=y
+CONFIG_INET_AH=m
+CONFIG_INET_ESP=m
+CONFIG_INET_IPCOMP=m
+CONFIG_INET_XFRM_TUNNEL=m
+CONFIG_INET_TUNNEL=m
+CONFIG_INET_XFRM_MODE_TRANSPORT=m
+CONFIG_INET_XFRM_MODE_TUNNEL=m
+CONFIG_INET_DIAG=m
+CONFIG_INET_TCP_DIAG=m
+CONFIG_TCP_CONG_ADVANCED=y
+
+#
+# TCP congestion control
+#
+CONFIG_TCP_CONG_BIC=y
+CONFIG_TCP_CONG_CUBIC=m
+CONFIG_TCP_CONG_WESTWOOD=m
+CONFIG_TCP_CONG_HTCP=m
+CONFIG_TCP_CONG_HSTCP=m
+CONFIG_TCP_CONG_HYBLA=m
+CONFIG_TCP_CONG_VEGAS=m
+CONFIG_TCP_CONG_SCALABLE=m
+CONFIG_TCP_CONG_LP=m
+CONFIG_TCP_CONG_VENO=m
+
+#
+# IP: Virtual Server Configuration
+#
+CONFIG_IP_VS=m
+# CONFIG_IP_VS_DEBUG is not set
+CONFIG_IP_VS_TAB_BITS=12
+
+#
+# IPVS transport protocol load balancing support
+#
+CONFIG_IP_VS_PROTO_TCP=y
+CONFIG_IP_VS_PROTO_UDP=y
+CONFIG_IP_VS_PROTO_ESP=y
+CONFIG_IP_VS_PROTO_AH=y
+
+#
+# IPVS scheduler
+#
+CONFIG_IP_VS_RR=m
+CONFIG_IP_VS_WRR=m
+CONFIG_IP_VS_LC=m
+CONFIG_IP_VS_WLC=m
+CONFIG_IP_VS_LBLC=m
+CONFIG_IP_VS_LBLCR=m
+CONFIG_IP_VS_DH=m
+CONFIG_IP_VS_SH=m
+CONFIG_IP_VS_SED=m
+CONFIG_IP_VS_NQ=m
+
+#
+# IPVS application helper
+#
+CONFIG_IP_VS_FTP=m
+CONFIG_IPV6=m
+CONFIG_IPV6_PRIVACY=y
+CONFIG_IPV6_ROUTER_PREF=y
+CONFIG_IPV6_ROUTE_INFO=y
+CONFIG_INET6_AH=m
+CONFIG_INET6_ESP=m
+CONFIG_INET6_IPCOMP=m
+CONFIG_INET6_XFRM_TUNNEL=m
+CONFIG_INET6_TUNNEL=m
+CONFIG_INET6_XFRM_MODE_TRANSPORT=m
+CONFIG_INET6_XFRM_MODE_TUNNEL=m
+CONFIG_IPV6_TUNNEL=m
+CONFIG_NETWORK_SECMARK=y
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_DEBUG is not set
+CONFIG_BRIDGE_NETFILTER=y
+
+#
+# Core Netfilter Configuration
+#
+CONFIG_NETFILTER_NETLINK=m
+CONFIG_NETFILTER_NETLINK_QUEUE=m
+CONFIG_NETFILTER_NETLINK_LOG=m
+CONFIG_NETFILTER_XTABLES=m
+CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
+CONFIG_NETFILTER_XT_TARGET_CONNMARK=m
+CONFIG_NETFILTER_XT_TARGET_MARK=m
+CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
+CONFIG_NETFILTER_XT_TARGET_NOTRACK=m
+CONFIG_NETFILTER_XT_TARGET_SECMARK=m
+CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=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_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_PHYSDEV=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
+
+#
+# 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=m
+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_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_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_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
+CONFIG_IP_NF_ARPTABLES=m
+CONFIG_IP_NF_ARPFILTER=m
+CONFIG_IP_NF_ARP_MANGLE=m
+
+#
+# IPv6: Netfilter Configuration (EXPERIMENTAL)
+#
+CONFIG_IP6_NF_QUEUE=m
+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_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
+
+#
+# DECnet: Netfilter Configuration
+#
+# CONFIG_DECNET_NF_GRABULATOR is not set
+
+#
+# Bridge: Netfilter Configuration
+#
+CONFIG_BRIDGE_NF_EBTABLES=m
+CONFIG_BRIDGE_EBT_BROUTE=m
+CONFIG_BRIDGE_EBT_T_FILTER=m
+CONFIG_BRIDGE_EBT_T_NAT=m
+CONFIG_BRIDGE_EBT_802_3=m
+CONFIG_BRIDGE_EBT_AMONG=m
+CONFIG_BRIDGE_EBT_ARP=m
+CONFIG_BRIDGE_EBT_IP=m
+CONFIG_BRIDGE_EBT_LIMIT=m
+CONFIG_BRIDGE_EBT_MARK=m
+CONFIG_BRIDGE_EBT_PKTTYPE=m
+CONFIG_BRIDGE_EBT_STP=m
+CONFIG_BRIDGE_EBT_VLAN=m
+CONFIG_BRIDGE_EBT_ARPREPLY=m
+CONFIG_BRIDGE_EBT_DNAT=m
+CONFIG_BRIDGE_EBT_MARK_T=m
+CONFIG_BRIDGE_EBT_REDIRECT=m
+CONFIG_BRIDGE_EBT_SNAT=m
+CONFIG_BRIDGE_EBT_LOG=m
+CONFIG_BRIDGE_EBT_ULOG=m
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+CONFIG_IP_DCCP=m
+CONFIG_INET_DCCP_DIAG=m
+CONFIG_IP_DCCP_ACKVEC=y
+
+#
+# DCCP CCIDs Configuration (EXPERIMENTAL)
+#
+CONFIG_IP_DCCP_CCID2=m
+CONFIG_IP_DCCP_CCID3=m
+CONFIG_IP_DCCP_TFRC_LIB=m
+
+#
+# DCCP Kernel Hacking
+#
+# CONFIG_IP_DCCP_DEBUG is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+CONFIG_IP_SCTP=m
+# CONFIG_SCTP_DBG_MSG is not set
+# CONFIG_SCTP_DBG_OBJCNT is not set
+# CONFIG_SCTP_HMAC_NONE is not set
+# CONFIG_SCTP_HMAC_SHA1 is not set
+CONFIG_SCTP_HMAC_MD5=y
+
+#
+# TIPC Configuration (EXPERIMENTAL)
+#
+CONFIG_TIPC=m
+# CONFIG_TIPC_ADVANCED is not set
+# CONFIG_TIPC_DEBUG is not set
+CONFIG_ATM=m
+CONFIG_ATM_CLIP=m
+# CONFIG_ATM_CLIP_NO_ICMP is not set
+CONFIG_ATM_LANE=m
+# CONFIG_ATM_MPOA is not set
+CONFIG_ATM_BR2684=m
+# CONFIG_ATM_BR2684_IPFILTER is not set
+CONFIG_BRIDGE=m
+CONFIG_VLAN_8021Q=m
+CONFIG_DECNET=m
+CONFIG_DECNET_ROUTER=y
+CONFIG_DECNET_ROUTE_FWMARK=y
+CONFIG_LLC=y
+# CONFIG_LLC2 is not set
+CONFIG_IPX=m
+# CONFIG_IPX_INTERN is not set
+CONFIG_ATALK=m
+CONFIG_DEV_APPLETALK=m
+# CONFIG_LTPC is not set
+# CONFIG_COPS is not set
+CONFIG_IPDDP=m
+CONFIG_IPDDP_ENCAP=y
+CONFIG_IPDDP_DECAP=y
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+CONFIG_WAN_ROUTER=m
+
+#
+# QoS and/or fair queueing
+#
+CONFIG_NET_SCHED=y
+# CONFIG_NET_SCH_CLK_JIFFIES is not set
+CONFIG_NET_SCH_CLK_GETTIMEOFDAY=y
+# CONFIG_NET_SCH_CLK_CPU is not set
+
+#
+# Queueing/Scheduling
+#
+CONFIG_NET_SCH_CBQ=m
+CONFIG_NET_SCH_HTB=m
+CONFIG_NET_SCH_HFSC=m
+CONFIG_NET_SCH_ATM=m
+CONFIG_NET_SCH_PRIO=m
+CONFIG_NET_SCH_RED=m
+CONFIG_NET_SCH_SFQ=m
+CONFIG_NET_SCH_TEQL=m
+CONFIG_NET_SCH_TBF=m
+CONFIG_NET_SCH_GRED=m
+CONFIG_NET_SCH_DSMARK=m
+CONFIG_NET_SCH_NETEM=m
+CONFIG_NET_SCH_INGRESS=m
+
+#
+# Classification
+#
+CONFIG_NET_CLS=y
+CONFIG_NET_CLS_BASIC=m
+CONFIG_NET_CLS_TCINDEX=m
+CONFIG_NET_CLS_ROUTE4=m
+CONFIG_NET_CLS_ROUTE=y
+CONFIG_NET_CLS_FW=m
+CONFIG_NET_CLS_U32=m
+CONFIG_CLS_U32_PERF=y
+CONFIG_CLS_U32_MARK=y
+CONFIG_NET_CLS_RSVP=m
+CONFIG_NET_CLS_RSVP6=m
+CONFIG_NET_EMATCH=y
+CONFIG_NET_EMATCH_STACK=32
+CONFIG_NET_EMATCH_CMP=m
+CONFIG_NET_EMATCH_NBYTE=m
+CONFIG_NET_EMATCH_U32=m
+CONFIG_NET_EMATCH_META=m
+CONFIG_NET_EMATCH_TEXT=m
+CONFIG_NET_CLS_ACT=y
+CONFIG_NET_ACT_POLICE=m
+CONFIG_NET_ACT_GACT=m
+CONFIG_GACT_PROB=y
+CONFIG_NET_ACT_MIRRED=m
+CONFIG_NET_ACT_IPT=m
+CONFIG_NET_ACT_PEDIT=m
+CONFIG_NET_ACT_SIMP=m
+CONFIG_NET_CLS_IND=y
+CONFIG_NET_ESTIMATOR=y
+
+#
+# Network testing
+#
+CONFIG_NET_PKTGEN=m
+# CONFIG_NET_TCPPROBE is not set
+# CONFIG_HAMRADIO is not set
+CONFIG_IRDA=m
+
+#
+# IrDA protocols
+#
+CONFIG_IRLAN=m
+CONFIG_IRNET=m
+CONFIG_IRCOMM=m
+# CONFIG_IRDA_ULTRA is not set
+
+#
+# IrDA options
+#
+CONFIG_IRDA_CACHE_LAST_LSAP=y
+CONFIG_IRDA_FAST_RR=y
+# CONFIG_IRDA_DEBUG is not set
+
+#
+# Infrared-port device drivers
+#
+
+#
+# SIR device drivers
+#
+CONFIG_IRTTY_SIR=m
+
+#
+# Dongle support
+#
+CONFIG_DONGLE=y
+CONFIG_ESI_DONGLE=m
+CONFIG_ACTISYS_DONGLE=m
+CONFIG_TEKRAM_DONGLE=m
+CONFIG_TOIM3232_DONGLE=m
+CONFIG_LITELINK_DONGLE=m
+CONFIG_MA600_DONGLE=m
+CONFIG_GIRBIL_DONGLE=m
+CONFIG_MCP2120_DONGLE=m
+CONFIG_OLD_BELKIN_DONGLE=m
+CONFIG_ACT200L_DONGLE=m
+
+#
+# Old SIR device drivers
+#
+CONFIG_IRPORT_SIR=m
+
+#
+# Old Serial dongle support
+#
+# CONFIG_DONGLE_OLD is not set
+
+#
+# FIR device drivers
+#
+CONFIG_USB_IRDA=m
+CONFIG_SIGMATEL_FIR=m
+CONFIG_NSC_FIR=m
+CONFIG_WINBOND_FIR=m
+CONFIG_TOSHIBA_FIR=m
+CONFIG_SMC_IRCC_FIR=m
+CONFIG_ALI_FIR=m
+CONFIG_VLSI_FIR=m
+CONFIG_VIA_FIR=m
+CONFIG_MCS_FIR=m
+CONFIG_BT=m
+CONFIG_BT_L2CAP=m
+CONFIG_BT_SCO=m
+CONFIG_BT_RFCOMM=m
+CONFIG_BT_RFCOMM_TTY=y
+CONFIG_BT_BNEP=m
+CONFIG_BT_BNEP_MC_FILTER=y
+CONFIG_BT_BNEP_PROTO_FILTER=y
+CONFIG_BT_CMTP=m
+CONFIG_BT_HIDP=m
+
+#
+# Bluetooth device drivers
+#
+CONFIG_BT_HCIUSB=m
+CONFIG_BT_HCIUSB_SCO=y
+CONFIG_BT_HCIUART=m
+CONFIG_BT_HCIUART_H4=y
+CONFIG_BT_HCIUART_BCSP=y
+CONFIG_BT_HCIBCM203X=m
+CONFIG_BT_HCIBPA10X=m
+CONFIG_BT_HCIBFUSB=m
+CONFIG_BT_HCIDTL1=m
+CONFIG_BT_HCIBT3C=m
+CONFIG_BT_HCIBLUECARD=m
+CONFIG_BT_HCIBTUART=m
+CONFIG_BT_HCIVHCI=m
+CONFIG_IEEE80211=m
+# CONFIG_IEEE80211_DEBUG is not set
+CONFIG_IEEE80211_CRYPT_WEP=m
+CONFIG_IEEE80211_CRYPT_CCMP=m
+CONFIG_IEEE80211_CRYPT_TKIP=m
+CONFIG_IEEE80211_SOFTMAC=m
+CONFIG_IEEE80211_SOFTMAC_DEBUG=y
+CONFIG_TUX=m
+
+#
+# TUX options
+#
+CONFIG_TUX_EXTCGI=y
+CONFIG_TUX_EXTENDED_LOG=y
+# CONFIG_TUX_DEBUG is not set
+CONFIG_WIRELESS_EXT=y
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_SYS_HYPERVISOR is not set
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+CONFIG_CONNECTOR=y
+CONFIG_PROC_EVENTS=y
+
+#
+# Memory Technology Devices (MTD)
+#
+CONFIG_MTD=m
+# CONFIG_MTD_DEBUG is not set
+CONFIG_MTD_CONCAT=m
+CONFIG_MTD_PARTITIONS=y
+CONFIG_MTD_REDBOOT_PARTS=m
+CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1
+# CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED is not set
+# CONFIG_MTD_REDBOOT_PARTS_READONLY is not set
+CONFIG_MTD_CMDLINE_PARTS=y
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=m
+CONFIG_MTD_BLOCK=m
+CONFIG_MTD_BLOCK_RO=m
+CONFIG_FTL=m
+CONFIG_NFTL=m
+CONFIG_NFTL_RW=y
+CONFIG_INFTL=m
+CONFIG_RFD_FTL=m
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=m
+CONFIG_MTD_JEDECPROBE=m
+CONFIG_MTD_GEN_PROBE=m
+# CONFIG_MTD_CFI_ADV_OPTIONS 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_CFI_INTELEXT=m
+CONFIG_MTD_CFI_AMDSTD=m
+CONFIG_MTD_CFI_STAA=m
+CONFIG_MTD_CFI_UTIL=m
+CONFIG_MTD_RAM=m
+CONFIG_MTD_ROM=m
+CONFIG_MTD_ABSENT=m
+# CONFIG_MTD_OBSOLETE_CHIPS is not set
+
+#
+# Mapping drivers for chip access
+#
+CONFIG_MTD_COMPLEX_MAPPINGS=y
+# CONFIG_MTD_PHYSMAP is not set
+# CONFIG_MTD_PNC2000 is not set
+CONFIG_MTD_SC520CDP=m
+CONFIG_MTD_NETSC520=m
+CONFIG_MTD_TS5500=m
+# CONFIG_MTD_SBC_GXX is not set
+# CONFIG_MTD_AMD76XROM is not set
+# CONFIG_MTD_ICHXROM is not set
+CONFIG_MTD_SCB2_FLASH=m
+# CONFIG_MTD_NETtel is not set
+# CONFIG_MTD_DILNETPC is not set
+# CONFIG_MTD_L440GX is not set
+CONFIG_MTD_PCI=m
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+CONFIG_MTD_PMC551=m
+# CONFIG_MTD_PMC551_BUGFIX is not set
+# CONFIG_MTD_PMC551_DEBUG is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+CONFIG_MTD_MTDRAM=m
+CONFIG_MTDRAM_TOTAL_SIZE=4096
+CONFIG_MTDRAM_ERASE_SIZE=128
+CONFIG_MTD_BLOCK2MTD=m
+
+#
+# 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=m
+# CONFIG_MTD_NAND_VERIFY_WRITE is not set
+CONFIG_MTD_NAND_ECC_SMC=y
+CONFIG_MTD_NAND_IDS=m
+CONFIG_MTD_NAND_DISKONCHIP=m
+# CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADVANCED is not set
+CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADDRESS=0
+# CONFIG_MTD_NAND_DISKONCHIP_BBTWRITE is not set
+CONFIG_MTD_NAND_CS553X=m
+CONFIG_MTD_NAND_NANDSIM=m
+
+#
+# OneNAND Flash Device Drivers
+#
+# CONFIG_MTD_ONENAND is not set
+
+#
+# Parallel port support
+#
+CONFIG_PARPORT=m
+CONFIG_PARPORT_PC=m
+CONFIG_PARPORT_SERIAL=m
+# CONFIG_PARPORT_PC_FIFO is not set
+# CONFIG_PARPORT_PC_SUPERIO is not set
+CONFIG_PARPORT_PC_PCMCIA=m
+CONFIG_PARPORT_NOT_PC=y
+# CONFIG_PARPORT_GSC is not set
+# CONFIG_PARPORT_AX88796 is not set
+CONFIG_PARPORT_1284=y
+
+#
+# Plug and Play support
+#
+CONFIG_PNP=y
+# CONFIG_PNP_DEBUG is not set
+
+#
+# Protocols
+#
+CONFIG_ISAPNP=y
+# CONFIG_PNPBIOS is not set
+CONFIG_PNPACPI=y
+
+#
+# Block devices
+#
+CONFIG_BLK_DEV_FD=m
+# CONFIG_BLK_DEV_XD is not set
+CONFIG_PARIDE=m
+CONFIG_PARIDE_PARPORT=m
+
+#
+# Parallel IDE high-level drivers
+#
+CONFIG_PARIDE_PD=m
+CONFIG_PARIDE_PCD=m
+CONFIG_PARIDE_PF=m
+CONFIG_PARIDE_PT=m
+CONFIG_PARIDE_PG=m
+
+#
+# Parallel IDE protocol modules
+#
+CONFIG_PARIDE_ATEN=m
+CONFIG_PARIDE_BPCK=m
+CONFIG_PARIDE_BPCK6=m
+CONFIG_PARIDE_COMM=m
+CONFIG_PARIDE_DSTR=m
+CONFIG_PARIDE_FIT2=m
+CONFIG_PARIDE_FIT3=m
+CONFIG_PARIDE_EPAT=m
+CONFIG_PARIDE_EPATC8=y
+CONFIG_PARIDE_EPIA=m
+CONFIG_PARIDE_FRIQ=m
+CONFIG_PARIDE_FRPW=m
+CONFIG_PARIDE_KBIC=m
+CONFIG_PARIDE_KTTI=m
+CONFIG_PARIDE_ON20=m
+CONFIG_PARIDE_ON26=m
+CONFIG_BLK_CPQ_DA=m
+CONFIG_BLK_CPQ_CISS_DA=m
+CONFIG_CISS_SCSI_TAPE=y
+CONFIG_BLK_DEV_DAC960=m
+CONFIG_BLK_DEV_UMEM=m
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=m
+CONFIG_BLK_DEV_CRYPTOLOOP=m
+CONFIG_BLK_DEV_NBD=m
+CONFIG_BLK_DEV_SX8=m
+CONFIG_BLK_DEV_UB=m
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=16384
+CONFIG_BLK_DEV_RAM_BLOCKSIZE=4096
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_CDROM_PKTCDVD=m
+CONFIG_CDROM_PKTCDVD_BUFFERS=8
+# CONFIG_CDROM_PKTCDVD_WCACHE is not set
+CONFIG_ATA_OVER_ETH=m
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+CONFIG_IDE=y
+CONFIG_BLK_DEV_IDE=y
+
+#
+# Please see Documentation/ide.txt for help/info on IDE drives
+#
+# CONFIG_BLK_DEV_IDE_SATA is not set
+# CONFIG_BLK_DEV_HD_IDE is not set
+CONFIG_BLK_DEV_IDEDISK=y
+CONFIG_IDEDISK_MULTI_MODE=y
+CONFIG_BLK_DEV_IDECS=m
+CONFIG_BLK_DEV_IDECD=m
+# CONFIG_BLK_DEV_IDETAPE is not set
+CONFIG_BLK_DEV_IDEFLOPPY=y
+CONFIG_BLK_DEV_IDESCSI=m
+CONFIG_IDE_TASK_IOCTL=y
+
+#
+# IDE chipset support/bugfixes
+#
+CONFIG_IDE_GENERIC=y
+CONFIG_BLK_DEV_CMD640=y
+CONFIG_BLK_DEV_CMD640_ENHANCED=y
+CONFIG_BLK_DEV_IDEPNP=y
+CONFIG_BLK_DEV_IDEPCI=y
+CONFIG_IDEPCI_SHARE_IRQ=y
+# CONFIG_BLK_DEV_OFFBOARD is not set
+CONFIG_BLK_DEV_GENERIC=y
+# CONFIG_BLK_DEV_OPTI621 is not set
+CONFIG_BLK_DEV_RZ1000=y
+CONFIG_BLK_DEV_IDEDMA_PCI=y
+# CONFIG_BLK_DEV_IDEDMA_FORCED is not set
+CONFIG_IDEDMA_PCI_AUTO=y
+# CONFIG_IDEDMA_ONLYDISK is not set
+CONFIG_BLK_DEV_AEC62XX=y
+CONFIG_BLK_DEV_ALI15X3=y
+# CONFIG_WDC_ALI15X3 is not set
+CONFIG_BLK_DEV_AMD74XX=y
+CONFIG_BLK_DEV_ATIIXP=y
+CONFIG_BLK_DEV_CMD64X=y
+CONFIG_BLK_DEV_TRIFLEX=y
+# CONFIG_BLK_DEV_CY82C693 is not set
+CONFIG_BLK_DEV_CS5520=y
+CONFIG_BLK_DEV_CS5530=y
+CONFIG_BLK_DEV_CS5535=y
+CONFIG_BLK_DEV_HPT34X=y
+# CONFIG_HPT34X_AUTODMA is not set
+CONFIG_BLK_DEV_HPT366=y
+# CONFIG_BLK_DEV_SC1200 is not set
+CONFIG_BLK_DEV_PIIX=y
+CONFIG_BLK_DEV_IT821X=y
+# CONFIG_BLK_DEV_NS87415 is not set
+CONFIG_BLK_DEV_PDC202XX_OLD=y
+# CONFIG_PDC202XX_BURST is not set
+CONFIG_BLK_DEV_PDC202XX_NEW=y
+CONFIG_BLK_DEV_SVWKS=y
+CONFIG_BLK_DEV_SIIMAGE=y
+CONFIG_BLK_DEV_SIS5513=y
+# CONFIG_BLK_DEV_SLC90E66 is not set
+# CONFIG_BLK_DEV_TRM290 is not set
+CONFIG_BLK_DEV_VIA82CXXX=y
+# CONFIG_IDE_ARM is not set
+# CONFIG_IDE_CHIPSETS is not set
+CONFIG_BLK_DEV_IDEDMA=y
+# CONFIG_IDEDMA_IVB is not set
+CONFIG_IDEDMA_AUTO=y
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# SCSI device support
+#
+CONFIG_RAID_ATTRS=m
+CONFIG_SCSI=m
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=m
+CONFIG_CHR_DEV_ST=m
+CONFIG_CHR_DEV_OSST=m
+CONFIG_BLK_DEV_SR=m
+CONFIG_BLK_DEV_SR_VENDOR=y
+CONFIG_CHR_DEV_SG=m
+CONFIG_CHR_DEV_SCH=m
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+CONFIG_SCSI_MULTI_LUN=y
+CONFIG_SCSI_CONSTANTS=y
+CONFIG_SCSI_LOGGING=y
+
+#
+# SCSI Transport Attributes
+#
+CONFIG_SCSI_SPI_ATTRS=m
+CONFIG_SCSI_FC_ATTRS=m
+CONFIG_SCSI_ISCSI_ATTRS=m
+CONFIG_SCSI_SAS_ATTRS=m
+
+#
+# SCSI low-level drivers
+#
+CONFIG_ISCSI_TCP=m
+CONFIG_BLK_DEV_3W_XXXX_RAID=m
+CONFIG_SCSI_3W_9XXX=m
+# CONFIG_SCSI_7000FASST is not set
+CONFIG_SCSI_ACARD=m
+CONFIG_SCSI_AHA152X=m
+CONFIG_SCSI_AHA1542=m
+CONFIG_SCSI_AACRAID=m
+CONFIG_SCSI_AIC7XXX=m
+CONFIG_AIC7XXX_CMDS_PER_DEVICE=4
+CONFIG_AIC7XXX_RESET_DELAY_MS=15000
+# CONFIG_AIC7XXX_DEBUG_ENABLE is not set
+CONFIG_AIC7XXX_DEBUG_MASK=0
+# CONFIG_AIC7XXX_REG_PRETTY_PRINT is not set
+CONFIG_SCSI_AIC7XXX_OLD=m
+CONFIG_SCSI_AIC79XX=m
+CONFIG_AIC79XX_CMDS_PER_DEVICE=4
+CONFIG_AIC79XX_RESET_DELAY_MS=15000
+# CONFIG_AIC79XX_ENABLE_RD_STRM is not set
+# CONFIG_AIC79XX_DEBUG_ENABLE is not set
+CONFIG_AIC79XX_DEBUG_MASK=0
+# CONFIG_AIC79XX_REG_PRETTY_PRINT is not set
+# CONFIG_SCSI_DPT_I2O is not set
+CONFIG_SCSI_ADVANSYS=m
+# CONFIG_SCSI_IN2000 is not set
+CONFIG_MEGARAID_NEWGEN=y
+CONFIG_MEGARAID_MM=m
+CONFIG_MEGARAID_MAILBOX=m
+CONFIG_MEGARAID_LEGACY=m
+CONFIG_MEGARAID_SAS=m
+CONFIG_SCSI_SATA=m
+CONFIG_SCSI_SATA_AHCI=m
+CONFIG_SCSI_SATA_SVW=m
+CONFIG_SCSI_ATA_PIIX=m
+CONFIG_SCSI_SATA_MV=m
+CONFIG_SCSI_SATA_NV=m
+CONFIG_SCSI_PDC_ADMA=m
+CONFIG_SCSI_HPTIOP=m
+CONFIG_SCSI_SATA_QSTOR=m
+CONFIG_SCSI_SATA_PROMISE=m
+CONFIG_SCSI_SATA_SX4=m
+CONFIG_SCSI_SATA_SIL=m
+CONFIG_SCSI_SATA_SIL24=m
+CONFIG_SCSI_SATA_SIS=m
+CONFIG_SCSI_SATA_ULI=m
+CONFIG_SCSI_SATA_VIA=m
+CONFIG_SCSI_SATA_VITESSE=m
+CONFIG_SCSI_SATA_INTEL_COMBINED=y
+CONFIG_SCSI_BUSLOGIC=m
+# CONFIG_SCSI_OMIT_FLASHPOINT is not set
+# CONFIG_SCSI_DMX3191D is not set
+# CONFIG_SCSI_DTC3280 is not set
+# CONFIG_SCSI_EATA is not set
+CONFIG_SCSI_FUTURE_DOMAIN=m
+CONFIG_SCSI_GDTH=m
+# CONFIG_SCSI_GENERIC_NCR5380 is not set
+# CONFIG_SCSI_GENERIC_NCR5380_MMIO is not set
+CONFIG_SCSI_IPS=m
+CONFIG_SCSI_INITIO=m
+CONFIG_SCSI_INIA100=m
+CONFIG_SCSI_PPA=m
+CONFIG_SCSI_IMM=m
+# CONFIG_SCSI_IZIP_EPP16 is not set
+# CONFIG_SCSI_IZIP_SLOW_CTR is not set
+# CONFIG_SCSI_NCR53C406A is not set
+CONFIG_SCSI_SYM53C8XX_2=m
+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=m
+CONFIG_SCSI_QLA_FC=m
+CONFIG_SCSI_LPFC=m
+# CONFIG_SCSI_SYM53C416 is not set
+CONFIG_SCSI_DC395x=m
+CONFIG_SCSI_DC390T=m
+# CONFIG_SCSI_T128 is not set
+# CONFIG_SCSI_U14_34F is not set
+# CONFIG_SCSI_ULTRASTOR is not set
+# CONFIG_SCSI_NSP32 is not set
+# CONFIG_SCSI_DEBUG is not set
+
+#
+# PCMCIA SCSI adapter support
+#
+CONFIG_PCMCIA_AHA152X=m
+CONFIG_PCMCIA_FDOMAIN=m
+CONFIG_PCMCIA_NINJA_SCSI=m
+CONFIG_PCMCIA_QLOGIC=m
+CONFIG_PCMCIA_SYM53C500=m
+
+#
+# Old CD-ROM drivers (not SCSI, not IDE)
+#
+# CONFIG_CD_NO_IDESCSI is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+CONFIG_MD=y
+CONFIG_BLK_DEV_MD=y
+CONFIG_MD_LINEAR=m
+CONFIG_MD_RAID0=m
+CONFIG_MD_RAID1=m
+CONFIG_MD_RAID10=m
+CONFIG_MD_RAID456=m
+CONFIG_MD_RAID5_RESHAPE=y
+CONFIG_MD_MULTIPATH=m
+CONFIG_MD_FAULTY=m
+CONFIG_BLK_DEV_DM=m
+CONFIG_DM_CRYPT=m
+CONFIG_DM_SNAPSHOT=m
+CONFIG_DM_MIRROR=m
+CONFIG_DM_ZERO=m
+CONFIG_DM_MULTIPATH=m
+CONFIG_DM_MULTIPATH_EMC=m
+
+#
+# Fusion MPT device support
+#
+CONFIG_FUSION=y
+CONFIG_FUSION_SPI=m
+CONFIG_FUSION_FC=m
+CONFIG_FUSION_SAS=m
+CONFIG_FUSION_MAX_SGE=40
+CONFIG_FUSION_CTL=m
+CONFIG_FUSION_LAN=m
+
+#
+# IEEE 1394 (FireWire) support
+#
+CONFIG_IEEE1394=m
+
+#
+# Subsystem Options
+#
+# CONFIG_IEEE1394_VERBOSEDEBUG is not set
+CONFIG_IEEE1394_OUI_DB=y
+CONFIG_IEEE1394_EXTRA_CONFIG_ROMS=y
+CONFIG_IEEE1394_CONFIG_ROM_IP1394=y
+# CONFIG_IEEE1394_EXPORT_FULL_API is not set
+
+#
+# Device Drivers
+#
+CONFIG_IEEE1394_PCILYNX=m
+CONFIG_IEEE1394_OHCI1394=m
+
+#
+# Protocol Drivers
+#
+CONFIG_IEEE1394_VIDEO1394=m
+CONFIG_IEEE1394_SBP2=m
+# CONFIG_IEEE1394_SBP2_PHYS_DMA is not set
+CONFIG_IEEE1394_ETH1394=m
+CONFIG_IEEE1394_DV1394=m
+CONFIG_IEEE1394_RAWIO=m
+
+#
+# I2O device support
+#
+CONFIG_I2O=m
+# CONFIG_I2O_LCT_NOTIFY_ON_CHANGES is not set
+CONFIG_I2O_EXT_ADAPTEC=y
+CONFIG_I2O_CONFIG=m
+CONFIG_I2O_CONFIG_OLD_IOCTL=y
+CONFIG_I2O_BUS=m
+CONFIG_I2O_BLOCK=m
+CONFIG_I2O_SCSI=m
+CONFIG_I2O_PROC=m
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+CONFIG_IFB=m
+CONFIG_DUMMY=m
+CONFIG_BONDING=m
+CONFIG_EQUALIZER=m
+CONFIG_TUN=m
+CONFIG_NET_SB1000=m
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+
+#
+# PHY device support
+#
+CONFIG_PHYLIB=m
+
+#
+# MII PHY device drivers
+#
+CONFIG_MARVELL_PHY=m
+CONFIG_DAVICOM_PHY=m
+CONFIG_QSEMI_PHY=m
+CONFIG_LXT_PHY=m
+CONFIG_CICADA_PHY=m
+CONFIG_VITESSE_PHY=m
+CONFIG_SMSC_PHY=m
+CONFIG_FIXED_PHY=m
+CONFIG_FIXED_MII_10_FDX=y
+CONFIG_FIXED_MII_100_FDX=y
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=m
+CONFIG_HAPPYMEAL=m
+CONFIG_SUNGEM=m
+CONFIG_CASSINI=m
+CONFIG_NET_VENDOR_3COM=y
+# CONFIG_EL1 is not set
+# CONFIG_EL2 is not set
+# CONFIG_ELPLUS is not set
+# CONFIG_EL16 is not set
+CONFIG_EL3=m
+# CONFIG_3C515 is not set
+CONFIG_VORTEX=m
+CONFIG_TYPHOON=m
+# CONFIG_LANCE is not set
+CONFIG_NET_VENDOR_SMC=y
+# CONFIG_WD80x3 is not set
+CONFIG_ULTRA=m
+# CONFIG_SMC9194 is not set
+# CONFIG_NET_VENDOR_RACAL is not set
+
+#
+# Tulip family network device support
+#
+CONFIG_NET_TULIP=y
+CONFIG_DE2104X=m
+CONFIG_TULIP=m
+# CONFIG_TULIP_MWI is not set
+CONFIG_TULIP_MMIO=y
+# CONFIG_TULIP_NAPI is not set
+CONFIG_DE4X5=m
+CONFIG_WINBOND_840=m
+CONFIG_DM9102=m
+CONFIG_ULI526X=m
+CONFIG_PCMCIA_XIRCOM=m
+# CONFIG_PCMCIA_XIRTULIP is not set
+# CONFIG_AT1700 is not set
+# CONFIG_DEPCA is not set
+# CONFIG_HP100 is not set
+CONFIG_NET_ISA=y
+# CONFIG_E2100 is not set
+CONFIG_EWRK3=m
+# CONFIG_EEXPRESS is not set
+# CONFIG_EEXPRESS_PRO is not set
+# CONFIG_HPLAN_PLUS is not set
+# CONFIG_HPLAN is not set
+# CONFIG_LP486E is not set
+# CONFIG_ETH16I is not set
+CONFIG_NE2000=m
+# CONFIG_ZNET is not set
+# CONFIG_SEEQ8005 is not set
+CONFIG_NET_PCI=y
+CONFIG_PCNET32=m
+CONFIG_AMD8111_ETH=m
+CONFIG_AMD8111E_NAPI=y
+CONFIG_ADAPTEC_STARFIRE=m
+CONFIG_ADAPTEC_STARFIRE_NAPI=y
+# CONFIG_AC3200 is not set
+# CONFIG_APRICOT is not set
+CONFIG_B44=m
+CONFIG_FORCEDETH=m
+# CONFIG_CS89x0 is not set
+# CONFIG_DGRS is not set
+# CONFIG_EEPRO100 is not set
+CONFIG_E100=m
+CONFIG_FEALNX=m
+CONFIG_NATSEMI=m
+CONFIG_NE2K_PCI=m
+CONFIG_8139CP=m
+CONFIG_8139TOO=m
+# CONFIG_8139TOO_PIO is not set
+# CONFIG_8139TOO_TUNE_TWISTER is not set
+CONFIG_8139TOO_8129=y
+# CONFIG_8139_OLD_RX_RESET is not set
+CONFIG_SIS900=m
+CONFIG_EPIC100=m
+CONFIG_SUNDANCE=m
+# CONFIG_SUNDANCE_MMIO is not set
+CONFIG_TLAN=m
+CONFIG_VIA_RHINE=m
+CONFIG_VIA_RHINE_MMIO=y
+CONFIG_VIA_RHINE_NAPI=y
+CONFIG_NET_POCKET=y
+CONFIG_ATP=m
+CONFIG_DE600=m
+CONFIG_DE620=m
+
+#
+# Ethernet (1000 Mbit)
+#
+CONFIG_ACENIC=m
+# CONFIG_ACENIC_OMIT_TIGON_I is not set
+CONFIG_DL2K=m
+CONFIG_E1000=m
+CONFIG_E1000_NAPI=y
+# CONFIG_E1000_DISABLE_PACKET_SPLIT is not set
+CONFIG_NS83820=m
+CONFIG_HAMACHI=m
+CONFIG_YELLOWFIN=m
+CONFIG_R8169=m
+CONFIG_R8169_NAPI=y
+CONFIG_R8169_VLAN=y
+CONFIG_SIS190=m
+CONFIG_SKGE=m
+CONFIG_SKY2=m
+# CONFIG_SK98LIN is not set
+CONFIG_VIA_VELOCITY=m
+CONFIG_TIGON3=m
+CONFIG_BNX2=m
+
+#
+# Ethernet (10000 Mbit)
+#
+CONFIG_CHELSIO_T1=m
+CONFIG_IXGB=m
+CONFIG_IXGB_NAPI=y
+CONFIG_S2IO=m
+CONFIG_S2IO_NAPI=y
+CONFIG_MYRI10GE=m
+
+#
+# Token Ring devices
+#
+CONFIG_TR=y
+# CONFIG_IBMTR is not set
+CONFIG_IBMOL=m
+CONFIG_IBMLS=m
+CONFIG_3C359=m
+# CONFIG_TMS380TR is not set
+# CONFIG_SMCTR is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+CONFIG_NET_RADIO=y
+CONFIG_NET_WIRELESS_RTNETLINK=y
+
+#
+# Obsolete Wireless cards support (pre-802.11)
+#
+# CONFIG_STRIP is not set
+# CONFIG_ARLAN is not set
+# CONFIG_WAVELAN is not set
+CONFIG_PCMCIA_WAVELAN=m
+CONFIG_PCMCIA_NETWAVE=m
+
+#
+# Wireless 802.11 Frequency Hopping cards support
+#
+# CONFIG_PCMCIA_RAYCS is not set
+
+#
+# Wireless 802.11b ISA/PCI cards support
+#
+CONFIG_IPW2100=m
+CONFIG_IPW2100_MONITOR=y
+# CONFIG_IPW2100_DEBUG is not set
+CONFIG_IPW2200=m
+CONFIG_IPW2200_MONITOR=y
+CONFIG_IPW2200_RADIOTAP=y
+CONFIG_IPW2200_PROMISCUOUS=y
+CONFIG_IPW2200_QOS=y
+# CONFIG_IPW2200_DEBUG is not set
+CONFIG_AIRO=m
+CONFIG_HERMES=m
+CONFIG_PLX_HERMES=m
+CONFIG_TMD_HERMES=m
+CONFIG_NORTEL_HERMES=m
+CONFIG_PCI_HERMES=m
+CONFIG_ATMEL=m
+CONFIG_PCI_ATMEL=m
+
+#
+# Wireless 802.11b Pcmcia/Cardbus cards support
+#
+CONFIG_PCMCIA_HERMES=m
+CONFIG_PCMCIA_SPECTRUM=m
+CONFIG_AIRO_CS=m
+CONFIG_PCMCIA_ATMEL=m
+CONFIG_PCMCIA_WL3501=m
+
+#
+# Prism GT/Duette 802.11(a/b/g) PCI/Cardbus support
+#
+CONFIG_PRISM54=m
+CONFIG_USB_ZD1201=m
+CONFIG_HOSTAP=m
+CONFIG_HOSTAP_FIRMWARE=y
+CONFIG_HOSTAP_FIRMWARE_NVRAM=y
+CONFIG_HOSTAP_PLX=m
+CONFIG_HOSTAP_PCI=m
+CONFIG_HOSTAP_CS=m
+CONFIG_BCM43XX=m
+CONFIG_BCM43XX_DEBUG=y
+CONFIG_BCM43XX_DMA=y
+CONFIG_BCM43XX_PIO=y
+CONFIG_BCM43XX_DMA_AND_PIO_MODE=y
+# CONFIG_BCM43XX_DMA_MODE is not set
+# CONFIG_BCM43XX_PIO_MODE is not set
+CONFIG_ZD1211RW=m
+# CONFIG_ZD1211RW_DEBUG is not set
+CONFIG_NET_WIRELESS=y
+
+#
+# PCMCIA network device support
+#
+CONFIG_NET_PCMCIA=y
+CONFIG_PCMCIA_3C589=m
+CONFIG_PCMCIA_3C574=m
+CONFIG_PCMCIA_FMVJ18X=m
+CONFIG_PCMCIA_PCNET=m
+CONFIG_PCMCIA_NMCLAN=m
+CONFIG_PCMCIA_SMC91C92=m
+CONFIG_PCMCIA_XIRC2PS=m
+CONFIG_PCMCIA_AXNET=m
+CONFIG_PCMCIA_IBMTR=m
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+
+#
+# ATM drivers
+#
+# CONFIG_ATM_DUMMY is not set
+CONFIG_ATM_TCP=m
+CONFIG_ATM_LANAI=m
+CONFIG_ATM_ENI=m
+# CONFIG_ATM_ENI_DEBUG is not set
+# CONFIG_ATM_ENI_TUNE_BURST is not set
+CONFIG_ATM_FIRESTREAM=m
+# CONFIG_ATM_ZATM is not set
+CONFIG_ATM_NICSTAR=m
+# CONFIG_ATM_NICSTAR_USE_SUNI is not set
+# CONFIG_ATM_NICSTAR_USE_IDT77105 is not set
+CONFIG_ATM_IDT77252=m
+# CONFIG_ATM_IDT77252_DEBUG is not set
+# CONFIG_ATM_IDT77252_RCV_ALL is not set
+CONFIG_ATM_IDT77252_USE_SUNI=y
+CONFIG_ATM_AMBASSADOR=m
+# CONFIG_ATM_AMBASSADOR_DEBUG is not set
+CONFIG_ATM_HORIZON=m
+# CONFIG_ATM_HORIZON_DEBUG is not set
+# CONFIG_ATM_IA is not set
+CONFIG_ATM_FORE200E_MAYBE=m
+# CONFIG_ATM_FORE200E_PCA is not set
+CONFIG_ATM_HE=m
+# CONFIG_ATM_HE_USE_SUNI is not set
+CONFIG_FDDI=y
+# CONFIG_DEFXX is not set
+CONFIG_SKFP=m
+# CONFIG_HIPPI is not set
+CONFIG_PLIP=m
+CONFIG_PPP=m
+CONFIG_PPP_MULTILINK=y
+CONFIG_PPP_FILTER=y
+CONFIG_PPP_ASYNC=m
+CONFIG_PPP_SYNC_TTY=m
+CONFIG_PPP_DEFLATE=m
+# CONFIG_PPP_BSDCOMP is not set
+CONFIG_PPP_MPPE=m
+CONFIG_PPPOE=m
+CONFIG_PPPOATM=m
+CONFIG_SLIP=m
+CONFIG_SLIP_COMPRESSED=y
+CONFIG_SLIP_SMART=y
+# CONFIG_SLIP_MODE_SLIP6 is not set
+CONFIG_NET_FC=y
+# CONFIG_SHAPER is not set
+CONFIG_NETCONSOLE=m
+CONFIG_NETPOLL=y
+# CONFIG_NETPOLL_RX is not set
+CONFIG_NETPOLL_TRAP=y
+CONFIG_NET_POLL_CONTROLLER=y
+
+#
+# ISDN subsystem
+#
+CONFIG_ISDN=m
+
+#
+# Old ISDN4Linux
+#
+CONFIG_ISDN_I4L=m
+CONFIG_ISDN_PPP=y
+CONFIG_ISDN_PPP_VJ=y
+CONFIG_ISDN_MPP=y
+CONFIG_IPPP_FILTER=y
+# CONFIG_ISDN_PPP_BSDCOMP is not set
+CONFIG_ISDN_AUDIO=y
+CONFIG_ISDN_TTY_FAX=y
+
+#
+# ISDN feature submodules
+#
+CONFIG_ISDN_DRV_LOOP=m
+CONFIG_ISDN_DIVERSION=m
+
+#
+# ISDN4Linux hardware drivers
+#
+
+#
+# Passive cards
+#
+CONFIG_ISDN_DRV_HISAX=m
+
+#
+# D-channel protocol features
+#
+CONFIG_HISAX_EURO=y
+CONFIG_DE_AOC=y
+CONFIG_HISAX_NO_SENDCOMPLETE=y
+CONFIG_HISAX_NO_LLC=y
+CONFIG_HISAX_NO_KEYPAD=y
+CONFIG_HISAX_1TR6=y
+CONFIG_HISAX_NI1=y
+CONFIG_HISAX_MAX_CARDS=8
+
+#
+# HiSax supported cards
+#
+# CONFIG_HISAX_16_0 is not set
+CONFIG_HISAX_16_3=y
+CONFIG_HISAX_TELESPCI=y
+CONFIG_HISAX_S0BOX=y
+# CONFIG_HISAX_AVM_A1 is not set
+CONFIG_HISAX_FRITZPCI=y
+CONFIG_HISAX_AVM_A1_PCMCIA=y
+CONFIG_HISAX_ELSA=y
+# CONFIG_HISAX_IX1MICROR2 is not set
+CONFIG_HISAX_DIEHLDIVA=y
+# CONFIG_HISAX_ASUSCOM is not set
+# CONFIG_HISAX_TELEINT is not set
+# CONFIG_HISAX_HFCS is not set
+CONFIG_HISAX_SEDLBAUER=y
+# CONFIG_HISAX_SPORTSTER is not set
+# CONFIG_HISAX_MIC is not set
+CONFIG_HISAX_NETJET=y
+CONFIG_HISAX_NETJET_U=y
+CONFIG_HISAX_NICCY=y
+# CONFIG_HISAX_ISURF is not set
+# CONFIG_HISAX_HSTSAPHIR is not set
+CONFIG_HISAX_BKM_A4T=y
+CONFIG_HISAX_SCT_QUADRO=y
+CONFIG_HISAX_GAZEL=y
+CONFIG_HISAX_HFC_PCI=y
+CONFIG_HISAX_W6692=y
+CONFIG_HISAX_HFC_SX=y
+CONFIG_HISAX_ENTERNOW_PCI=y
+# CONFIG_HISAX_DEBUG is not set
+
+#
+# HiSax PCMCIA card service modules
+#
+CONFIG_HISAX_SEDLBAUER_CS=m
+CONFIG_HISAX_ELSA_CS=m
+CONFIG_HISAX_AVM_A1_CS=m
+CONFIG_HISAX_TELES_CS=m
+
+#
+# HiSax sub driver modules
+#
+CONFIG_HISAX_ST5481=m
+# CONFIG_HISAX_HFCUSB is not set
+CONFIG_HISAX_HFC4S8S=m
+CONFIG_HISAX_FRITZ_PCIPNP=m
+CONFIG_HISAX_HDLC=y
+
+#
+# Active cards
+#
+# CONFIG_ISDN_DRV_ICN is not set
+# CONFIG_ISDN_DRV_PCBIT is not set
+# CONFIG_ISDN_DRV_SC is not set
+# CONFIG_ISDN_DRV_ACT2000 is not set
+CONFIG_HYSDN=m
+CONFIG_HYSDN_CAPI=y
+
+#
+# Siemens Gigaset
+#
+CONFIG_ISDN_DRV_GIGASET=m
+CONFIG_GIGASET_BASE=m
+CONFIG_GIGASET_M105=m
+# CONFIG_GIGASET_DEBUG is not set
+# CONFIG_GIGASET_UNDOCREQ is not set
+
+#
+# CAPI subsystem
+#
+CONFIG_ISDN_CAPI=m
+CONFIG_ISDN_DRV_AVMB1_VERBOSE_REASON=y
+CONFIG_ISDN_CAPI_MIDDLEWARE=y
+CONFIG_ISDN_CAPI_CAPI20=m
+CONFIG_ISDN_CAPI_CAPIFS_BOOL=y
+CONFIG_ISDN_CAPI_CAPIFS=m
+CONFIG_ISDN_CAPI_CAPIDRV=m
+
+#
+# CAPI hardware drivers
+#
+
+#
+# Active AVM cards
+#
+CONFIG_CAPI_AVM=y
+# CONFIG_ISDN_DRV_AVMB1_B1ISA is not set
+CONFIG_ISDN_DRV_AVMB1_B1PCI=m
+CONFIG_ISDN_DRV_AVMB1_B1PCIV4=y
+# CONFIG_ISDN_DRV_AVMB1_T1ISA is not set
+CONFIG_ISDN_DRV_AVMB1_B1PCMCIA=m
+CONFIG_ISDN_DRV_AVMB1_AVM_CS=m
+CONFIG_ISDN_DRV_AVMB1_T1PCI=m
+CONFIG_ISDN_DRV_AVMB1_C4=m
+
+#
+# Active Eicon DIVA Server cards
+#
+CONFIG_CAPI_EICON=y
+CONFIG_ISDN_DIVAS=m
+CONFIG_ISDN_DIVAS_BRIPCI=y
+CONFIG_ISDN_DIVAS_PRIPCI=y
+CONFIG_ISDN_DIVAS_DIVACAPI=m
+CONFIG_ISDN_DIVAS_USERIDI=m
+CONFIG_ISDN_DIVAS_MAINT=m
+
+#
+# Telephony Support
+#
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+
+#
+# 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=m
+# CONFIG_INPUT_TSDEV is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+CONFIG_KEYBOARD_ATKBD=y
+# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_KEYBOARD_LKKBD is not set
+# CONFIG_KEYBOARD_XTKBD is not set
+# CONFIG_KEYBOARD_NEWTON is not set
+CONFIG_INPUT_MOUSE=y
+CONFIG_MOUSE_PS2=y
+CONFIG_MOUSE_SERIAL=m
+# CONFIG_MOUSE_INPORT is not set
+# CONFIG_MOUSE_LOGIBM is not set
+# CONFIG_MOUSE_PC110PAD is not set
+CONFIG_MOUSE_VSXXXAA=m
+CONFIG_INPUT_JOYSTICK=y
+CONFIG_JOYSTICK_ANALOG=m
+CONFIG_JOYSTICK_A3D=m
+CONFIG_JOYSTICK_ADI=m
+CONFIG_JOYSTICK_COBRA=m
+CONFIG_JOYSTICK_GF2K=m
+CONFIG_JOYSTICK_GRIP=m
+CONFIG_JOYSTICK_GRIP_MP=m
+CONFIG_JOYSTICK_GUILLEMOT=m
+CONFIG_JOYSTICK_INTERACT=m
+CONFIG_JOYSTICK_SIDEWINDER=m
+CONFIG_JOYSTICK_TMDC=m
+CONFIG_JOYSTICK_IFORCE=m
+CONFIG_JOYSTICK_IFORCE_USB=y
+CONFIG_JOYSTICK_IFORCE_232=y
+CONFIG_JOYSTICK_WARRIOR=m
+CONFIG_JOYSTICK_MAGELLAN=m
+CONFIG_JOYSTICK_SPACEORB=m
+CONFIG_JOYSTICK_SPACEBALL=m
+CONFIG_JOYSTICK_STINGER=m
+CONFIG_JOYSTICK_TWIDJOY=m
+CONFIG_JOYSTICK_DB9=m
+CONFIG_JOYSTICK_GAMECON=m
+CONFIG_JOYSTICK_TURBOGRAFX=m
+CONFIG_JOYSTICK_JOYDUMP=m
+CONFIG_INPUT_TOUCHSCREEN=y
+CONFIG_TOUCHSCREEN_GUNZE=m
+CONFIG_TOUCHSCREEN_ELO=m
+CONFIG_TOUCHSCREEN_MTOUCH=m
+CONFIG_TOUCHSCREEN_MK712=m
+CONFIG_INPUT_MISC=y
+CONFIG_INPUT_PCSPKR=m
+CONFIG_INPUT_WISTRON_BTNS=m
+CONFIG_INPUT_UINPUT=m
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+CONFIG_SERIO_I8042=y
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_CT82C710 is not set
+# CONFIG_SERIO_PARKBD is not set
+# CONFIG_SERIO_PCIPS2 is not set
+CONFIG_SERIO_LIBPS2=y
+CONFIG_SERIO_RAW=m
+CONFIG_GAMEPORT=m
+CONFIG_GAMEPORT_NS558=m
+CONFIG_GAMEPORT_L4=m
+CONFIG_GAMEPORT_EMU10K1=m
+CONFIG_GAMEPORT_FM801=m
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+CONFIG_VT_HW_CONSOLE_BINDING=y
+CONFIG_SERIAL_NONSTANDARD=y
+# CONFIG_COMPUTONE is not set
+# CONFIG_ROCKETPORT is not set
+CONFIG_CYCLADES=m
+# CONFIG_CYZ_INTR is not set
+# CONFIG_DIGIEPCA is not set
+# CONFIG_ESPSERIAL is not set
+# CONFIG_MOXA_INTELLIO is not set
+# CONFIG_MOXA_SMARTIO is not set
+# CONFIG_ISI is not set
+CONFIG_SYNCLINK=m
+CONFIG_SYNCLINKMP=m
+CONFIG_SYNCLINK_GT=m
+CONFIG_N_HDLC=m
+# CONFIG_RISCOM8 is not set
+# CONFIG_SPECIALIX is not set
+# CONFIG_SX is not set
+# CONFIG_RIO is not set
+# CONFIG_STALDRV is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_PCI=y
+CONFIG_SERIAL_8250_PNP=y
+CONFIG_SERIAL_8250_CS=m
+CONFIG_SERIAL_8250_NR_UARTS=32
+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=y
+CONFIG_SERIAL_8250_RSA=y
+# CONFIG_SERIAL_8250_FOURPORT is not set
+# CONFIG_SERIAL_8250_ACCENT is not set
+# CONFIG_SERIAL_8250_BOCA is not set
+# CONFIG_SERIAL_8250_HUB6 is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_SERIAL_JSM=m
+CONFIG_UNIX98_PTYS=y
+# CONFIG_LEGACY_PTYS is not set
+CONFIG_CRASH=m
+CONFIG_PRINTER=m
+CONFIG_LP_CONSOLE=y
+CONFIG_PPDEV=m
+CONFIG_TIPAR=m
+
+#
+# IPMI
+#
+CONFIG_IPMI_HANDLER=m
+# CONFIG_IPMI_PANIC_EVENT is not set
+CONFIG_IPMI_DEVICE_INTERFACE=m
+CONFIG_IPMI_SI=m
+CONFIG_IPMI_WATCHDOG=m
+CONFIG_IPMI_POWEROFF=m
+
+#
+# Watchdog Cards
+#
+CONFIG_WATCHDOG=y
+# CONFIG_WATCHDOG_NOWAYOUT is not set
+
+#
+# Watchdog Device Drivers
+#
+CONFIG_SOFT_WATCHDOG=m
+# CONFIG_ACQUIRE_WDT is not set
+# CONFIG_ADVANTECH_WDT is not set
+CONFIG_ALIM1535_WDT=m
+CONFIG_ALIM7101_WDT=m
+# CONFIG_SC520_WDT is not set
+# CONFIG_EUROTECH_WDT is not set
+# CONFIG_IB700_WDT is not set
+CONFIG_IBMASR=m
+# CONFIG_WAFER_WDT is not set
+CONFIG_I6300ESB_WDT=m
+CONFIG_I8XX_TCO=m
+# CONFIG_SC1200_WDT is not set
+# CONFIG_60XX_WDT is not set
+# CONFIG_SBC8360_WDT is not set
+# CONFIG_CPU5_WDT is not set
+CONFIG_W83627HF_WDT=m
+CONFIG_W83877F_WDT=m
+CONFIG_W83977F_WDT=m
+CONFIG_MACHZ_WDT=m
+# CONFIG_SBC_EPX_C3_WATCHDOG is not set
+
+#
+# ISA-based Watchdog Cards
+#
+# CONFIG_PCWATCHDOG is not set
+# CONFIG_MIXCOMWD is not set
+# CONFIG_WDT is not set
+
+#
+# PCI-based Watchdog Cards
+#
+CONFIG_PCIPCWATCHDOG=m
+CONFIG_WDTPCI=m
+CONFIG_WDT_501_PCI=y
+
+#
+# USB-based Watchdog Cards
+#
+CONFIG_USBPCWATCHDOG=m
+CONFIG_HW_RANDOM=y
+CONFIG_HW_RANDOM_INTEL=m
+CONFIG_HW_RANDOM_AMD=m
+CONFIG_HW_RANDOM_GEODE=m
+CONFIG_HW_RANDOM_VIA=m
+CONFIG_NVRAM=y
+CONFIG_RTC=y
+CONFIG_DTLK=m
+CONFIG_R3964=m
+# CONFIG_APPLICOM is not set
+CONFIG_SONYPI=m
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_FTAPE is not set
+CONFIG_AGP=y
+CONFIG_AGP_ALI=y
+CONFIG_AGP_ATI=y
+CONFIG_AGP_AMD=y
+CONFIG_AGP_AMD64=y
+CONFIG_AGP_INTEL=y
+CONFIG_AGP_NVIDIA=y
+CONFIG_AGP_SIS=y
+CONFIG_AGP_SWORKS=y
+CONFIG_AGP_VIA=y
+CONFIG_AGP_EFFICEON=y
+CONFIG_DRM=m
+CONFIG_DRM_TDFX=m
+CONFIG_DRM_R128=m
+CONFIG_DRM_RADEON=m
+CONFIG_DRM_I810=m
+CONFIG_DRM_I830=m
+CONFIG_DRM_I915=m
+CONFIG_DRM_MGA=m
+CONFIG_DRM_SIS=m
+CONFIG_DRM_VIA=m
+CONFIG_DRM_SAVAGE=m
+
+#
+# PCMCIA character devices
+#
+# CONFIG_SYNCLINK_CS is not set
+CONFIG_CARDMAN_4000=m
+CONFIG_CARDMAN_4040=m
+CONFIG_MWAVE=m
+CONFIG_PC8736x_GPIO=m
+CONFIG_NSC_GPIO=m
+CONFIG_CS5535_GPIO=m
+# CONFIG_RAW_DRIVER is not set
+CONFIG_HPET=y
+# CONFIG_HPET_RTC_IRQ is not set
+# CONFIG_HPET_MMAP is not set
+CONFIG_HANGCHECK_TIMER=m
+
+#
+# TPM devices
+#
+CONFIG_TCG_TPM=m
+CONFIG_TCG_TIS=m
+CONFIG_TCG_NSC=m
+CONFIG_TCG_ATMEL=m
+CONFIG_TCG_INFINEON=m
+# CONFIG_TELCLOCK is not set
+
+#
+# I2C support
+#
+CONFIG_I2C=m
+CONFIG_I2C_CHARDEV=m
+
+#
+# I2C Algorithms
+#
+CONFIG_I2C_ALGOBIT=m
+CONFIG_I2C_ALGOPCF=m
+CONFIG_I2C_ALGOPCA=m
+
+#
+# I2C Hardware Bus support
+#
+CONFIG_I2C_ALI1535=m
+CONFIG_I2C_ALI1563=m
+CONFIG_I2C_ALI15X3=m
+CONFIG_I2C_AMD756=m
+CONFIG_I2C_AMD756_S4882=m
+CONFIG_I2C_AMD8111=m
+# CONFIG_I2C_ELEKTOR is not set
+CONFIG_I2C_I801=m
+CONFIG_I2C_I810=m
+CONFIG_I2C_PIIX4=m
+CONFIG_I2C_ISA=m
+CONFIG_I2C_NFORCE2=m
+# CONFIG_I2C_OCORES is not set
+CONFIG_I2C_PARPORT=m
+CONFIG_I2C_PARPORT_LIGHT=m
+CONFIG_I2C_PROSAVAGE=m
+CONFIG_I2C_SAVAGE4=m
+# CONFIG_SCx200_ACB is not set
+CONFIG_I2C_SIS5595=m
+CONFIG_I2C_SIS630=m
+CONFIG_I2C_SIS96X=m
+CONFIG_I2C_STUB=m
+CONFIG_I2C_VIA=m
+CONFIG_I2C_VIAPRO=m
+CONFIG_I2C_VOODOO3=m
+CONFIG_I2C_PCA_ISA=m
+
+#
+# Miscellaneous I2C Chip support
+#
+CONFIG_SENSORS_DS1337=m
+CONFIG_SENSORS_DS1374=m
+CONFIG_SENSORS_EEPROM=m
+CONFIG_SENSORS_PCF8574=m
+CONFIG_SENSORS_PCA9539=m
+CONFIG_SENSORS_PCF8591=m
+CONFIG_SENSORS_MAX6875=m
+# 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 is not set
+# CONFIG_SPI_MASTER is not set
+
+#
+# Dallas's 1-wire bus
+#
+CONFIG_W1=m
+CONFIG_W1_CON=y
+
+#
+# 1-wire Bus Masters
+#
+CONFIG_W1_MASTER_MATROX=m
+CONFIG_W1_MASTER_DS2490=m
+CONFIG_W1_MASTER_DS2482=m
+
+#
+# 1-wire Slaves
+#
+CONFIG_W1_SLAVE_THERM=m
+CONFIG_W1_SLAVE_SMEM=m
+CONFIG_W1_SLAVE_DS2433=m
+CONFIG_W1_SLAVE_DS2433_CRC=y
+
+#
+# Hardware Monitoring support
+#
+CONFIG_HWMON=m
+CONFIG_HWMON_VID=m
+CONFIG_SENSORS_ABITUGURU=m
+CONFIG_SENSORS_ADM1021=m
+CONFIG_SENSORS_ADM1025=m
+CONFIG_SENSORS_ADM1026=m
+CONFIG_SENSORS_ADM1031=m
+CONFIG_SENSORS_ADM9240=m
+CONFIG_SENSORS_ASB100=m
+CONFIG_SENSORS_ATXP1=m
+CONFIG_SENSORS_DS1621=m
+CONFIG_SENSORS_F71805F=m
+CONFIG_SENSORS_FSCHER=m
+CONFIG_SENSORS_FSCPOS=m
+CONFIG_SENSORS_GL518SM=m
+CONFIG_SENSORS_GL520SM=m
+CONFIG_SENSORS_IT87=m
+CONFIG_SENSORS_LM63=m
+CONFIG_SENSORS_LM75=m
+CONFIG_SENSORS_LM77=m
+CONFIG_SENSORS_LM78=m
+CONFIG_SENSORS_LM80=m
+CONFIG_SENSORS_LM83=m
+CONFIG_SENSORS_LM85=m
+CONFIG_SENSORS_LM87=m
+CONFIG_SENSORS_LM90=m
+CONFIG_SENSORS_LM92=m
+CONFIG_SENSORS_MAX1619=m
+CONFIG_SENSORS_PC87360=m
+CONFIG_SENSORS_SIS5595=m
+CONFIG_SENSORS_SMSC47M1=m
+CONFIG_SENSORS_SMSC47M192=m
+CONFIG_SENSORS_SMSC47B397=m
+CONFIG_SENSORS_VIA686A=m
+CONFIG_SENSORS_VT8231=m
+CONFIG_SENSORS_W83781D=m
+CONFIG_SENSORS_W83791D=m
+CONFIG_SENSORS_W83792D=m
+CONFIG_SENSORS_W83L785TS=m
+CONFIG_SENSORS_W83627HF=m
+CONFIG_SENSORS_W83627EHF=m
+CONFIG_SENSORS_HDAPS=m
+# CONFIG_HWMON_DEBUG_CHIP is not set
+
+#
+# Misc devices
+#
+CONFIG_IBM_ASM=m
+
+#
+# Multimedia devices
+#
+CONFIG_VIDEO_DEV=m
+CONFIG_VIDEO_V4L1=y
+CONFIG_VIDEO_V4L1_COMPAT=y
+CONFIG_VIDEO_V4L2=y
+
+#
+# Video Capture Adapters
+#
+
+#
+# Video Capture Adapters
+#
+# CONFIG_VIDEO_ADV_DEBUG is not set
+# CONFIG_VIDEO_VIVI is not set
+CONFIG_VIDEO_BT848=m
+CONFIG_VIDEO_BT848_DVB=y
+CONFIG_VIDEO_SAA6588=m
+# CONFIG_VIDEO_PMS is not set
+CONFIG_VIDEO_BWQCAM=m
+CONFIG_VIDEO_CQCAM=m
+CONFIG_VIDEO_W9966=m
+CONFIG_VIDEO_CPIA=m
+CONFIG_VIDEO_CPIA_PP=m
+CONFIG_VIDEO_CPIA_USB=m
+CONFIG_VIDEO_CPIA2=m
+CONFIG_VIDEO_SAA5246A=m
+CONFIG_VIDEO_SAA5249=m
+CONFIG_TUNER_3036=m
+CONFIG_VIDEO_STRADIS=m
+CONFIG_VIDEO_ZORAN=m
+CONFIG_VIDEO_ZORAN_BUZ=m
+CONFIG_VIDEO_ZORAN_DC10=m
+CONFIG_VIDEO_ZORAN_DC30=m
+CONFIG_VIDEO_ZORAN_LML33=m
+CONFIG_VIDEO_ZORAN_LML33R10=m
+CONFIG_VIDEO_ZORAN_AVS6EYES=m
+CONFIG_VIDEO_MEYE=m
+CONFIG_VIDEO_SAA7134=m
+CONFIG_VIDEO_SAA7134_ALSA=m
+CONFIG_VIDEO_SAA7134_DVB=m
+CONFIG_VIDEO_SAA7134_DVB_ALL_FRONTENDS=y
+CONFIG_VIDEO_MXB=m
+CONFIG_VIDEO_DPC=m
+CONFIG_VIDEO_HEXIUM_ORION=m
+CONFIG_VIDEO_HEXIUM_GEMINI=m
+CONFIG_VIDEO_CX88_VP3054=m
+CONFIG_VIDEO_CX88=m
+CONFIG_VIDEO_CX88_ALSA=m
+CONFIG_VIDEO_CX88_BLACKBIRD=m
+CONFIG_VIDEO_CX88_DVB=m
+CONFIG_VIDEO_CX88_DVB_ALL_FRONTENDS=y
+
+#
+# Encoders and Decoders
+#
+CONFIG_VIDEO_MSP3400=m
+CONFIG_VIDEO_CS53L32A=m
+CONFIG_VIDEO_TLV320AIC23B=m
+CONFIG_VIDEO_WM8775=m
+CONFIG_VIDEO_WM8739=m
+CONFIG_VIDEO_CX2341X=m
+CONFIG_VIDEO_CX25840=m
+CONFIG_VIDEO_SAA711X=m
+CONFIG_VIDEO_SAA7127=m
+CONFIG_VIDEO_UPD64031A=m
+CONFIG_VIDEO_UPD64083=m
+
+#
+# V4L USB devices
+#
+CONFIG_VIDEO_PVRUSB2=m
+CONFIG_VIDEO_PVRUSB2_24XXX=y
+CONFIG_VIDEO_PVRUSB2_SYSFS=y
+# CONFIG_VIDEO_PVRUSB2_DEBUGIFC is not set
+CONFIG_VIDEO_EM28XX=m
+CONFIG_VIDEO_USBVIDEO=m
+CONFIG_USB_VICAM=m
+CONFIG_USB_IBMCAM=m
+CONFIG_USB_KONICAWC=m
+CONFIG_USB_QUICKCAM_MESSENGER=m
+CONFIG_USB_ET61X251=m
+CONFIG_VIDEO_OVCAMCHIP=m
+CONFIG_USB_W9968CF=m
+CONFIG_USB_OV511=m
+CONFIG_USB_SE401=m
+CONFIG_USB_SN9C102=m
+CONFIG_USB_STV680=m
+CONFIG_USB_ZC0301=m
+CONFIG_USB_PWC=m
+# CONFIG_USB_PWC_DEBUG is not set
+
+#
+# Radio Adapters
+#
+# CONFIG_RADIO_CADET is not set
+# CONFIG_RADIO_RTRACK is not set
+# CONFIG_RADIO_RTRACK2 is not set
+# CONFIG_RADIO_AZTECH is not set
+# CONFIG_RADIO_GEMTEK is not set
+CONFIG_RADIO_GEMTEK_PCI=m
+CONFIG_RADIO_MAXIRADIO=m
+CONFIG_RADIO_MAESTRO=m
+# CONFIG_RADIO_SF16FMI is not set
+# CONFIG_RADIO_SF16FMR2 is not set
+# CONFIG_RADIO_TERRATEC is not set
+# CONFIG_RADIO_TRUST is not set
+# CONFIG_RADIO_TYPHOON is not set
+# CONFIG_RADIO_ZOLTRIX is not set
+CONFIG_USB_DSBR=m
+
+#
+# Digital Video Broadcasting Devices
+#
+CONFIG_DVB=y
+CONFIG_DVB_CORE=m
+
+#
+# Supported SAA7146 based PCI Adapters
+#
+CONFIG_DVB_AV7110=m
+CONFIG_DVB_AV7110_OSD=y
+CONFIG_DVB_BUDGET=m
+CONFIG_DVB_BUDGET_CI=m
+CONFIG_DVB_BUDGET_AV=m
+CONFIG_DVB_BUDGET_PATCH=m
+
+#
+# Supported USB Adapters
+#
+CONFIG_DVB_USB=m
+# CONFIG_DVB_USB_DEBUG is not set
+CONFIG_DVB_USB_A800=m
+CONFIG_DVB_USB_DIBUSB_MB=m
+# CONFIG_DVB_USB_DIBUSB_MB_FAULTY is not set
+CONFIG_DVB_USB_DIBUSB_MC=m
+CONFIG_DVB_USB_UMT_010=m
+CONFIG_DVB_USB_CXUSB=m
+CONFIG_DVB_USB_DIGITV=m
+CONFIG_DVB_USB_VP7045=m
+CONFIG_DVB_USB_VP702X=m
+CONFIG_DVB_USB_GP8PSK=m
+CONFIG_DVB_USB_NOVA_T_USB2=m
+CONFIG_DVB_USB_DTT200U=m
+CONFIG_DVB_TTUSB_BUDGET=m
+CONFIG_DVB_TTUSB_DEC=m
+CONFIG_DVB_CINERGYT2=m
+CONFIG_DVB_CINERGYT2_TUNING=y
+CONFIG_DVB_CINERGYT2_STREAM_URB_COUNT=32
+CONFIG_DVB_CINERGYT2_STREAM_BUF_SIZE=512
+CONFIG_DVB_CINERGYT2_QUERY_INTERVAL=250
+CONFIG_DVB_CINERGYT2_ENABLE_RC_INPUT_DEVICE=y
+CONFIG_DVB_CINERGYT2_RC_QUERY_INTERVAL=100
+
+#
+# Supported FlexCopII (B2C2) Adapters
+#
+CONFIG_DVB_B2C2_FLEXCOP=m
+CONFIG_DVB_B2C2_FLEXCOP_PCI=m
+CONFIG_DVB_B2C2_FLEXCOP_USB=m
+# CONFIG_DVB_B2C2_FLEXCOP_DEBUG is not set
+
+#
+# Supported BT878 Adapters
+#
+CONFIG_DVB_BT8XX=m
+
+#
+# Supported Pluto2 Adapters
+#
+CONFIG_DVB_PLUTO2=m
+
+#
+# Supported DVB Frontends
+#
+
+#
+# Customise DVB Frontends
+#
+
+#
+# DVB-S (satellite) frontends
+#
+CONFIG_DVB_STV0299=m
+CONFIG_DVB_CX24110=m
+CONFIG_DVB_CX24123=m
+CONFIG_DVB_TDA8083=m
+CONFIG_DVB_MT312=m
+CONFIG_DVB_VES1X93=m
+CONFIG_DVB_S5H1420=m
+
+#
+# DVB-T (terrestrial) frontends
+#
+CONFIG_DVB_SP8870=m
+CONFIG_DVB_SP887X=m
+CONFIG_DVB_CX22700=m
+CONFIG_DVB_CX22702=m
+CONFIG_DVB_L64781=m
+CONFIG_DVB_TDA1004X=m
+CONFIG_DVB_NXT6000=m
+CONFIG_DVB_MT352=m
+CONFIG_DVB_ZL10353=m
+CONFIG_DVB_DIB3000MB=m
+CONFIG_DVB_DIB3000MC=m
+
+#
+# DVB-C (cable) frontends
+#
+CONFIG_DVB_VES1820=m
+CONFIG_DVB_TDA10021=m
+CONFIG_DVB_STV0297=m
+
+#
+# ATSC (North American/Korean Terrestrial/Cable DTV) frontends
+#
+CONFIG_DVB_NXT200X=m
+CONFIG_DVB_OR51211=m
+CONFIG_DVB_OR51132=m
+CONFIG_DVB_BCM3510=m
+CONFIG_DVB_LGDT330X=m
+
+#
+# Miscellaneous devices
+#
+CONFIG_DVB_PLL=m
+CONFIG_DVB_LNBP21=m
+CONFIG_DVB_ISL6421=m
+CONFIG_VIDEO_SAA7146=m
+CONFIG_VIDEO_SAA7146_VV=m
+CONFIG_VIDEO_VIDEOBUF=m
+CONFIG_VIDEO_TUNER=m
+CONFIG_VIDEO_BUF=m
+CONFIG_VIDEO_BUF_DVB=m
+CONFIG_VIDEO_BTCX=m
+CONFIG_VIDEO_IR=m
+CONFIG_VIDEO_TVEEPROM=m
+CONFIG_USB_DABUSB=m
+
+#
+# Graphics support
+#
+# CONFIG_FIRMWARE_EDID is not set
+CONFIG_FB=y
+CONFIG_FB_CFB_FILLRECT=y
+CONFIG_FB_CFB_COPYAREA=y
+CONFIG_FB_CFB_IMAGEBLIT=y
+# CONFIG_FB_MACMODES is not set
+# CONFIG_FB_BACKLIGHT is not set
+CONFIG_FB_MODE_HELPERS=y
+CONFIG_FB_TILEBLITTING=y
+CONFIG_FB_CIRRUS=m
+# CONFIG_FB_PM2 is not set
+# CONFIG_FB_CYBER2000 is not set
+# CONFIG_FB_ARC is not set
+# CONFIG_FB_ASILIANT is not set
+# CONFIG_FB_IMSTT is not set
+CONFIG_FB_VGA16=m
+CONFIG_FB_VESA=y
+# CONFIG_FB_IMAC is not set
+# CONFIG_FB_HGA is not set
+# CONFIG_FB_S1D13XXX is not set
+CONFIG_FB_NVIDIA=m
+CONFIG_FB_NVIDIA_I2C=y
+CONFIG_FB_RIVA=m
+# CONFIG_FB_RIVA_I2C is not set
+# CONFIG_FB_RIVA_DEBUG is not set
+CONFIG_FB_I810=m
+CONFIG_FB_I810_GTF=y
+CONFIG_FB_I810_I2C=y
+CONFIG_FB_INTEL=m
+# CONFIG_FB_INTEL_DEBUG is not set
+CONFIG_FB_MATROX=m
+CONFIG_FB_MATROX_MILLENIUM=y
+CONFIG_FB_MATROX_MYSTIQUE=y
+CONFIG_FB_MATROX_G=y
+CONFIG_FB_MATROX_I2C=m
+CONFIG_FB_MATROX_MAVEN=m
+CONFIG_FB_MATROX_MULTIHEAD=y
+CONFIG_FB_RADEON=m
+CONFIG_FB_RADEON_I2C=y
+# CONFIG_FB_RADEON_DEBUG is not set
+CONFIG_FB_ATY128=m
+CONFIG_FB_ATY=m
+CONFIG_FB_ATY_CT=y
+CONFIG_FB_ATY_GENERIC_LCD=y
+CONFIG_FB_ATY_GX=y
+CONFIG_FB_SAVAGE=m
+CONFIG_FB_SAVAGE_I2C=y
+CONFIG_FB_SAVAGE_ACCEL=y
+# CONFIG_FB_SIS is not set
+CONFIG_FB_NEOMAGIC=m
+CONFIG_FB_KYRO=m
+CONFIG_FB_3DFX=m
+CONFIG_FB_3DFX_ACCEL=y
+CONFIG_FB_VOODOO1=m
+CONFIG_FB_CYBLA=m
+CONFIG_FB_TRIDENT=m
+CONFIG_FB_TRIDENT_ACCEL=y
+# CONFIG_FB_GEODE is not set
+# CONFIG_FB_VIRTUAL is not set
+
+#
+# Console display driver support
+#
+CONFIG_VGA_CONSOLE=y
+CONFIG_VGACON_SOFT_SCROLLBACK=y
+CONFIG_VGACON_SOFT_SCROLLBACK_SIZE=64
+CONFIG_VIDEO_SELECT=y
+# CONFIG_MDA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y
+# CONFIG_FONTS is not set
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
+
+#
+# Logo configuration
+#
+CONFIG_LOGO=y
+# CONFIG_LOGO_LINUX_MONO is not set
+# CONFIG_LOGO_LINUX_VGA16 is not set
+CONFIG_LOGO_LINUX_CLUT224=y
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+CONFIG_BACKLIGHT_CLASS_DEVICE=m
+CONFIG_BACKLIGHT_DEVICE=y
+CONFIG_LCD_CLASS_DEVICE=m
+CONFIG_LCD_DEVICE=y
+
+#
+# Sound
+#
+CONFIG_SOUND=m
+
+#
+# Advanced Linux Sound Architecture
+#
+CONFIG_SND=m
+CONFIG_SND_TIMER=m
+CONFIG_SND_PCM=m
+CONFIG_SND_HWDEP=m
+CONFIG_SND_RAWMIDI=m
+CONFIG_SND_SEQUENCER=m
+CONFIG_SND_SEQ_DUMMY=m
+CONFIG_SND_OSSEMUL=y
+CONFIG_SND_MIXER_OSS=m
+CONFIG_SND_PCM_OSS=m
+CONFIG_SND_PCM_OSS_PLUGINS=y
+CONFIG_SND_SEQUENCER_OSS=y
+CONFIG_SND_RTCTIMER=m
+CONFIG_SND_SEQ_RTCTIMER_DEFAULT=y
+CONFIG_SND_DYNAMIC_MINORS=y
+# CONFIG_SND_SUPPORT_OLD_API is not set
+CONFIG_SND_VERBOSE_PROCFS=y
+# CONFIG_SND_VERBOSE_PRINTK is not set
+# CONFIG_SND_DEBUG is not set
+
+#
+# Generic devices
+#
+CONFIG_SND_MPU401_UART=m
+CONFIG_SND_OPL3_LIB=m
+CONFIG_SND_OPL4_LIB=m
+CONFIG_SND_VX_LIB=m
+CONFIG_SND_AC97_CODEC=m
+CONFIG_SND_AC97_BUS=m
+CONFIG_SND_DUMMY=m
+CONFIG_SND_VIRMIDI=m
+CONFIG_SND_MTPAV=m
+# CONFIG_SND_SERIAL_U16550 is not set
+CONFIG_SND_MPU401=m
+
+#
+# ISA devices
+#
+CONFIG_SND_CS4231_LIB=m
+CONFIG_SND_ADLIB=m
+# CONFIG_SND_AD1816A is not set
+# CONFIG_SND_AD1848 is not set
+# CONFIG_SND_ALS100 is not set
+# CONFIG_SND_AZT2320 is not set
+# CONFIG_SND_CMI8330 is not set
+# CONFIG_SND_CS4231 is not set
+# CONFIG_SND_CS4232 is not set
+CONFIG_SND_CS4236=m
+# CONFIG_SND_DT019X is not set
+# CONFIG_SND_ES968 is not set
+# CONFIG_SND_ES1688 is not set
+CONFIG_SND_ES18XX=m
+# CONFIG_SND_GUSCLASSIC is not set
+# CONFIG_SND_GUSEXTREME is not set
+# CONFIG_SND_GUSMAX is not set
+# CONFIG_SND_INTERWAVE is not set
+# CONFIG_SND_INTERWAVE_STB is not set
+CONFIG_SND_OPL3SA2=m
+# CONFIG_SND_OPTI92X_AD1848 is not set
+# CONFIG_SND_OPTI92X_CS4231 is not set
+# CONFIG_SND_OPTI93X is not set
+CONFIG_SND_MIRO=m
+# CONFIG_SND_SB8 is not set
+CONFIG_SND_SB16=m
+CONFIG_SND_SBAWE=m
+# CONFIG_SND_SB16_CSP is not set
+# CONFIG_SND_SGALAXY is not set
+# CONFIG_SND_SSCAPE is not set
+# CONFIG_SND_WAVEFRONT is not set
+
+#
+# PCI devices
+#
+CONFIG_SND_AD1889=m
+CONFIG_SND_ALS300=m
+CONFIG_SND_ALS4000=m
+CONFIG_SND_ALI5451=m
+CONFIG_SND_ATIIXP=m
+CONFIG_SND_ATIIXP_MODEM=m
+CONFIG_SND_AU8810=m
+CONFIG_SND_AU8820=m
+CONFIG_SND_AU8830=m
+CONFIG_SND_AZT3328=m
+CONFIG_SND_BT87X=m
+# CONFIG_SND_BT87X_OVERCLOCK is not set
+CONFIG_SND_CA0106=m
+CONFIG_SND_CMIPCI=m
+CONFIG_SND_CS4281=m
+CONFIG_SND_CS46XX=m
+CONFIG_SND_CS46XX_NEW_DSP=y
+CONFIG_SND_CS5535AUDIO=m
+CONFIG_SND_DARLA20=m
+CONFIG_SND_GINA20=m
+CONFIG_SND_LAYLA20=m
+CONFIG_SND_DARLA24=m
+CONFIG_SND_GINA24=m
+CONFIG_SND_LAYLA24=m
+CONFIG_SND_MONA=m
+CONFIG_SND_MIA=m
+CONFIG_SND_ECHO3G=m
+CONFIG_SND_INDIGO=m
+CONFIG_SND_INDIGOIO=m
+CONFIG_SND_INDIGODJ=m
+CONFIG_SND_EMU10K1=m
+CONFIG_SND_EMU10K1X=m
+CONFIG_SND_ENS1370=m
+CONFIG_SND_ENS1371=m
+CONFIG_SND_ES1938=m
+CONFIG_SND_ES1968=m
+CONFIG_SND_FM801=m
+CONFIG_SND_FM801_TEA575X_BOOL=y
+CONFIG_SND_FM801_TEA575X=m
+CONFIG_SND_HDA_INTEL=m
+CONFIG_SND_HDSP=m
+CONFIG_SND_HDSPM=m
+CONFIG_SND_ICE1712=m
+CONFIG_SND_ICE1724=m
+CONFIG_SND_INTEL8X0=m
+CONFIG_SND_INTEL8X0M=m
+CONFIG_SND_KORG1212=m
+CONFIG_SND_MAESTRO3=m
+CONFIG_SND_MIXART=m
+CONFIG_SND_NM256=m
+CONFIG_SND_PCXHR=m
+CONFIG_SND_RIPTIDE=m
+CONFIG_SND_RME32=m
+CONFIG_SND_RME96=m
+CONFIG_SND_RME9652=m
+CONFIG_SND_SONICVIBES=m
+CONFIG_SND_TRIDENT=m
+CONFIG_SND_VIA82XX=m
+CONFIG_SND_VIA82XX_MODEM=m
+CONFIG_SND_VX222=m
+CONFIG_SND_YMFPCI=m
+
+#
+# USB devices
+#
+CONFIG_SND_USB_AUDIO=m
+CONFIG_SND_USB_USX2Y=m
+
+#
+# PCMCIA devices
+#
+# CONFIG_SND_VXPOCKET is not set
+# CONFIG_SND_PDAUDIOCF is not set
+
+#
+# Open Sound System
+#
+# CONFIG_SOUND_PRIME is not set
+
+#
+# USB support
+#
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB_ARCH_HAS_EHCI=y
+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_SUSPEND is not set
+# CONFIG_USB_OTG is not set
+
+#
+# USB Host Controller Drivers
+#
+CONFIG_USB_EHCI_HCD=m
+CONFIG_USB_EHCI_SPLIT_ISO=y
+CONFIG_USB_EHCI_ROOT_HUB_TT=y
+CONFIG_USB_EHCI_TT_NEWSCHED=y
+CONFIG_USB_ISP116X_HCD=m
+CONFIG_USB_OHCI_HCD=m
+# CONFIG_USB_OHCI_BIG_ENDIAN is not set
+CONFIG_USB_OHCI_LITTLE_ENDIAN=y
+CONFIG_USB_UHCI_HCD=m
+CONFIG_USB_SL811_HCD=m
+CONFIG_USB_SL811_CS=m
+
+#
+# USB Device Class drivers
+#
+CONFIG_USB_ACM=m
+CONFIG_USB_PRINTER=m
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+#
+
+#
+# may also be needed; see USB_STORAGE Help for more information
+#
+CONFIG_USB_STORAGE=m
+# CONFIG_USB_STORAGE_DEBUG is not set
+CONFIG_USB_STORAGE_DATAFAB=y
+CONFIG_USB_STORAGE_FREECOM=y
+CONFIG_USB_STORAGE_ISD200=y
+CONFIG_USB_STORAGE_DPCM=y
+CONFIG_USB_STORAGE_USBAT=y
+CONFIG_USB_STORAGE_SDDR09=y
+CONFIG_USB_STORAGE_SDDR55=y
+CONFIG_USB_STORAGE_JUMPSHOT=y
+CONFIG_USB_STORAGE_ALAUDA=y
+CONFIG_USB_LIBUSUAL=y
+
+#
+# USB Input Devices
+#
+CONFIG_USB_HID=y
+CONFIG_USB_HIDINPUT=y
+CONFIG_USB_HIDINPUT_POWERBOOK=y
+CONFIG_HID_FF=y
+CONFIG_HID_PID=y
+CONFIG_LOGITECH_FF=y
+CONFIG_THRUSTMASTER_FF=y
+CONFIG_USB_HIDDEV=y
+CONFIG_USB_AIPTEK=m
+CONFIG_USB_WACOM=m
+CONFIG_USB_ACECAD=m
+CONFIG_USB_KBTAB=m
+CONFIG_USB_POWERMATE=m
+CONFIG_USB_TOUCHSCREEN=m
+CONFIG_USB_TOUCHSCREEN_EGALAX=y
+CONFIG_USB_TOUCHSCREEN_PANJIT=y
+CONFIG_USB_TOUCHSCREEN_3M=y
+CONFIG_USB_TOUCHSCREEN_ITM=y
+# CONFIG_USB_YEALINK is not set
+CONFIG_USB_XPAD=m
+CONFIG_USB_ATI_REMOTE=m
+CONFIG_USB_ATI_REMOTE2=m
+CONFIG_USB_KEYSPAN_REMOTE=m
+CONFIG_USB_APPLETOUCH=m
+
+#
+# USB Imaging devices
+#
+CONFIG_USB_MDC800=m
+CONFIG_USB_MICROTEK=m
+
+#
+# USB Network Adapters
+#
+CONFIG_USB_CATC=m
+CONFIG_USB_KAWETH=m
+CONFIG_USB_PEGASUS=m
+CONFIG_USB_RTL8150=m
+CONFIG_USB_USBNET=m
+CONFIG_USB_NET_AX8817X=m
+CONFIG_USB_NET_CDCETHER=m
+CONFIG_USB_NET_GL620A=m
+CONFIG_USB_NET_NET1080=m
+CONFIG_USB_NET_PLUSB=m
+CONFIG_USB_NET_RNDIS_HOST=m
+CONFIG_USB_NET_CDC_SUBSET=m
+CONFIG_USB_ALI_M5632=y
+CONFIG_USB_AN2720=y
+CONFIG_USB_BELKIN=y
+CONFIG_USB_ARMLINUX=y
+CONFIG_USB_EPSON2888=y
+CONFIG_USB_NET_ZAURUS=m
+CONFIG_USB_MON=y
+
+#
+# USB port drivers
+#
+CONFIG_USB_USS720=m
+
+#
+# USB Serial Converter support
+#
+CONFIG_USB_SERIAL=m
+CONFIG_USB_SERIAL_GENERIC=y
+CONFIG_USB_SERIAL_AIRPRIME=m
+CONFIG_USB_SERIAL_ARK3116=m
+CONFIG_USB_SERIAL_BELKIN=m
+CONFIG_USB_SERIAL_WHITEHEAT=m
+CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m
+CONFIG_USB_SERIAL_CP2101=m
+CONFIG_USB_SERIAL_CYPRESS_M8=m
+CONFIG_USB_SERIAL_EMPEG=m
+CONFIG_USB_SERIAL_FTDI_SIO=m
+CONFIG_USB_SERIAL_FUNSOFT=m
+CONFIG_USB_SERIAL_VISOR=m
+CONFIG_USB_SERIAL_IPAQ=m
+CONFIG_USB_SERIAL_IR=m
+CONFIG_USB_SERIAL_EDGEPORT=m
+CONFIG_USB_SERIAL_EDGEPORT_TI=m
+CONFIG_USB_SERIAL_GARMIN=m
+CONFIG_USB_SERIAL_IPW=m
+CONFIG_USB_SERIAL_KEYSPAN_PDA=m
+CONFIG_USB_SERIAL_KEYSPAN=m
+CONFIG_USB_SERIAL_KEYSPAN_MPR=y
+CONFIG_USB_SERIAL_KEYSPAN_USA28=y
+CONFIG_USB_SERIAL_KEYSPAN_USA28X=y
+CONFIG_USB_SERIAL_KEYSPAN_USA28XA=y
+CONFIG_USB_SERIAL_KEYSPAN_USA28XB=y
+CONFIG_USB_SERIAL_KEYSPAN_USA19=y
+CONFIG_USB_SERIAL_KEYSPAN_USA18X=y
+CONFIG_USB_SERIAL_KEYSPAN_USA19W=y
+CONFIG_USB_SERIAL_KEYSPAN_USA19QW=y
+CONFIG_USB_SERIAL_KEYSPAN_USA19QI=y
+CONFIG_USB_SERIAL_KEYSPAN_USA49W=y
+CONFIG_USB_SERIAL_KEYSPAN_USA49WLC=y
+CONFIG_USB_SERIAL_KLSI=m
+CONFIG_USB_SERIAL_KOBIL_SCT=m
+CONFIG_USB_SERIAL_MCT_U232=m
+CONFIG_USB_SERIAL_NAVMAN=m
+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=m
+CONFIG_USB_SERIAL_TI=m
+CONFIG_USB_SERIAL_CYBERJACK=m
+CONFIG_USB_SERIAL_XIRCOM=m
+CONFIG_USB_SERIAL_OPTION=m
+CONFIG_USB_SERIAL_OMNINET=m
+CONFIG_USB_EZUSB=y
+
+#
+# USB Miscellaneous drivers
+#
+CONFIG_USB_EMI62=m
+CONFIG_USB_EMI26=m
+CONFIG_USB_AUERSWALD=m
+CONFIG_USB_RIO500=m
+CONFIG_USB_LEGOTOWER=m
+CONFIG_USB_LCD=m
+CONFIG_USB_LED=m
+# CONFIG_USB_CYPRESS_CY7C63 is not set
+# CONFIG_USB_CYTHERM is not set
+CONFIG_USB_PHIDGETKIT=m
+CONFIG_USB_PHIDGETSERVO=m
+CONFIG_USB_IDMOUSE=m
+CONFIG_USB_APPLEDISPLAY=m
+CONFIG_USB_SISUSBVGA=m
+CONFIG_USB_SISUSBVGA_CON=y
+CONFIG_USB_LD=m
+CONFIG_USB_TEST=m
+
+#
+# USB DSL modem support
+#
+CONFIG_USB_ATM=m
+CONFIG_USB_SPEEDTOUCH=m
+CONFIG_USB_CXACRU=m
+CONFIG_USB_UEAGLEATM=m
+CONFIG_USB_XUSBATM=m
+
+#
+# USB Gadget Support
+#
+# CONFIG_USB_GADGET is not set
+
+#
+# MMC/SD Card support
+#
+CONFIG_MMC=m
+# CONFIG_MMC_DEBUG is not set
+CONFIG_MMC_BLOCK=m
+CONFIG_MMC_SDHCI=m
+CONFIG_MMC_WBSD=m
+
+#
+# LED devices
+#
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+
+#
+# LED drivers
+#
+
+#
+# LED Triggers
+#
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_LEDS_TRIGGER_TIMER=m
+CONFIG_LEDS_TRIGGER_IDE_DISK=y
+CONFIG_LEDS_TRIGGER_HEARTBEAT=m
+
+#
+# InfiniBand support
+#
+CONFIG_INFINIBAND=m
+CONFIG_INFINIBAND_USER_MAD=m
+CONFIG_INFINIBAND_USER_ACCESS=m
+CONFIG_INFINIBAND_ADDR_TRANS=y
+CONFIG_INFINIBAND_MTHCA=m
+CONFIG_INFINIBAND_MTHCA_DEBUG=y
+CONFIG_INFINIBAND_IPOIB=m
+CONFIG_INFINIBAND_IPOIB_DEBUG=y
+CONFIG_INFINIBAND_IPOIB_DEBUG_DATA=y
+CONFIG_INFINIBAND_SRP=m
+CONFIG_INFINIBAND_ISER=m
+
+#
+# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
+#
+CONFIG_EDAC=y
+
+#
+# Reporting subsystems
+#
+# CONFIG_EDAC_DEBUG is not set
+CONFIG_EDAC_MM_EDAC=m
+CONFIG_EDAC_AMD76X=m
+CONFIG_EDAC_E7XXX=m
+CONFIG_EDAC_E752X=m
+CONFIG_EDAC_I82875P=m
+CONFIG_EDAC_I82860=m
+CONFIG_EDAC_K8=m
+CONFIG_EDAC_R82600=m
+CONFIG_EDAC_POLL=y
+
+#
+# Real Time Clock
+#
+CONFIG_RTC_LIB=m
+CONFIG_RTC_CLASS=m
+
+#
+# RTC interfaces
+#
+CONFIG_RTC_INTF_SYSFS=m
+CONFIG_RTC_INTF_PROC=m
+CONFIG_RTC_INTF_DEV=m
+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
+
+#
+# RTC drivers
+#
+CONFIG_RTC_DRV_X1205=m
+CONFIG_RTC_DRV_DS1307=m
+CONFIG_RTC_DRV_DS1553=m
+CONFIG_RTC_DRV_ISL1208=m
+CONFIG_RTC_DRV_DS1672=m
+CONFIG_RTC_DRV_DS1742=m
+CONFIG_RTC_DRV_PCF8563=m
+CONFIG_RTC_DRV_PCF8583=m
+CONFIG_RTC_DRV_RS5C372=m
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_TEST is not set
+CONFIG_RTC_DRV_V3020=m
+
+#
+# DMA Engine support
+#
+CONFIG_DMA_ENGINE=y
+
+#
+# DMA Clients
+#
+CONFIG_NET_DMA=y
+
+#
+# DMA Devices
+#
+CONFIG_INTEL_IOATDMA=m
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+CONFIG_EXT2_FS_POSIX_ACL=y
+CONFIG_EXT2_FS_SECURITY=y
+CONFIG_EXT2_FS_XIP=y
+CONFIG_FS_XIP=y
+CONFIG_EXT3_FS=m
+CONFIG_EXT3_FS_XATTR=y
+CONFIG_EXT3_FS_POSIX_ACL=y
+CONFIG_EXT3_FS_SECURITY=y
+CONFIG_JBD=m
+# CONFIG_JBD_DEBUG is not set
+CONFIG_FS_MBCACHE=y
+CONFIG_REISERFS_FS=m
+# CONFIG_REISERFS_CHECK is not set
+CONFIG_REISERFS_PROC_INFO=y
+CONFIG_REISERFS_FS_XATTR=y
+CONFIG_REISERFS_FS_POSIX_ACL=y
+CONFIG_REISERFS_FS_SECURITY=y
+CONFIG_JFS_FS=m
+CONFIG_JFS_POSIX_ACL=y
+CONFIG_JFS_SECURITY=y
+# CONFIG_JFS_DEBUG is not set
+# CONFIG_JFS_STATISTICS is not set
+CONFIG_FS_POSIX_ACL=y
+CONFIG_XFS_FS=m
+CONFIG_XFS_QUOTA=y
+CONFIG_XFS_SECURITY=y
+CONFIG_XFS_POSIX_ACL=y
+# CONFIG_XFS_RT is not set
+CONFIG_OCFS2_FS=m
+# CONFIG_OCFS2_DEBUG_MASKLOG is not set
+CONFIG_MINIX_FS=m
+CONFIG_ROMFS_FS=m
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+CONFIG_QUOTA=y
+# CONFIG_QFMT_V1 is not set
+CONFIG_QFMT_V2=y
+CONFIG_QUOTACTL=y
+CONFIG_DNOTIFY=y
+CONFIG_AUTOFS_FS=m
+CONFIG_AUTOFS4_FS=m
+CONFIG_FUSE_FS=m
+
+#
+# Caches
+#
+CONFIG_FSCACHE=m
+
+#
+# CD-ROM/DVD Filesystems
+#
+CONFIG_ISO9660_FS=y
+CONFIG_JOLIET=y
+CONFIG_ZISOFS=y
+CONFIG_ZISOFS_FS=y
+CONFIG_UDF_FS=m
+CONFIG_UDF_NLS=y
+CONFIG_CACHEFILES=m
+CONFIG_CACHEFILES_DEBUG=y
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=m
+CONFIG_MSDOS_FS=m
+CONFIG_VFAT_FS=m
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="ascii"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+CONFIG_HUGETLBFS=y
+CONFIG_HUGETLB_PAGE=y
+CONFIG_RAMFS=y
+CONFIG_CONFIGFS_FS=m
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+CONFIG_AFFS_FS=m
+CONFIG_HFS_FS=m
+CONFIG_HFSPLUS_FS=m
+CONFIG_BEFS_FS=m
+# CONFIG_BEFS_DEBUG is not set
+CONFIG_BFS_FS=m
+CONFIG_EFS_FS=m
+# CONFIG_JFFS_FS is not set
+CONFIG_JFFS2_FS=m
+CONFIG_JFFS2_FS_DEBUG=0
+CONFIG_JFFS2_FS_WRITEBUFFER=y
+CONFIG_JFFS2_SUMMARY=y
+# 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=m
+CONFIG_SQUASHFS=m
+# CONFIG_SQUASHFS_EMBEDDED is not set
+CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3
+# CONFIG_SQUASHFS_VMALLOC is not set
+CONFIG_VXFS_FS=m
+# CONFIG_HPFS_FS is not set
+CONFIG_QNX4FS_FS=m
+CONFIG_SYSV_FS=m
+CONFIG_UFS_FS=m
+# CONFIG_UFS_FS_WRITE is not set
+# CONFIG_UFS_DEBUG is not set
+
+#
+# Network File Systems
+#
+CONFIG_NFS_FS=m
+CONFIG_NFS_V3=y
+CONFIG_NFS_V3_ACL=y
+CONFIG_NFS_V4=y
+CONFIG_NFS_FSCACHE=y
+CONFIG_NFS_DIRECTIO=y
+CONFIG_NFSD=m
+CONFIG_NFSD_V2_ACL=y
+CONFIG_NFSD_V3=y
+CONFIG_NFSD_V3_ACL=y
+CONFIG_NFSD_V4=y
+CONFIG_NFSD_TCP=y
+CONFIG_LOCKD=m
+CONFIG_LOCKD_V4=y
+CONFIG_EXPORTFS=m
+CONFIG_NFS_ACL_SUPPORT=m
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=m
+CONFIG_SUNRPC_GSS=m
+CONFIG_RPCSEC_GSS_KRB5=m
+CONFIG_RPCSEC_GSS_SPKM3=m
+# CONFIG_SMB_FS is not set
+CONFIG_CIFS=m
+# CONFIG_CIFS_STATS is not set
+CONFIG_CIFS_WEAK_PW_HASH=y
+CONFIG_CIFS_XATTR=y
+CONFIG_CIFS_POSIX=y
+# CONFIG_CIFS_DEBUG2 is not set
+# CONFIG_CIFS_EXPERIMENTAL is not set
+CONFIG_NCP_FS=m
+CONFIG_NCPFS_PACKET_SIGNING=y
+CONFIG_NCPFS_IOCTL_LOCKING=y
+CONFIG_NCPFS_STRONG=y
+CONFIG_NCPFS_NFS_NS=y
+CONFIG_NCPFS_OS2_NS=y
+CONFIG_NCPFS_SMALLDOS=y
+CONFIG_NCPFS_NLS=y
+CONFIG_NCPFS_EXTRAS=y
+CONFIG_CODA_FS=m
+# CONFIG_CODA_FS_OLD_API is not set
+# CONFIG_AFS_FS is not set
+CONFIG_9P_FS=m
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+CONFIG_OSF_PARTITION=y
+CONFIG_AMIGA_PARTITION=y
+# CONFIG_ATARI_PARTITION is not set
+CONFIG_MAC_PARTITION=y
+CONFIG_MSDOS_PARTITION=y
+CONFIG_BSD_DISKLABEL=y
+CONFIG_MINIX_SUBPARTITION=y
+CONFIG_SOLARIS_X86_PARTITION=y
+CONFIG_UNIXWARE_DISKLABEL=y
+# CONFIG_LDM_PARTITION is not set
+CONFIG_SGI_PARTITION=y
+# CONFIG_ULTRIX_PARTITION is not set
+CONFIG_SUN_PARTITION=y
+CONFIG_KARMA_PARTITION=y
+CONFIG_EFI_PARTITION=y
+
+#
+# Native Language Support
+#
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="utf8"
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_CODEPAGE_737=m
+CONFIG_NLS_CODEPAGE_775=m
+CONFIG_NLS_CODEPAGE_850=m
+CONFIG_NLS_CODEPAGE_852=m
+CONFIG_NLS_CODEPAGE_855=m
+CONFIG_NLS_CODEPAGE_857=m
+CONFIG_NLS_CODEPAGE_860=m
+CONFIG_NLS_CODEPAGE_861=m
+CONFIG_NLS_CODEPAGE_862=m
+CONFIG_NLS_CODEPAGE_863=m
+CONFIG_NLS_CODEPAGE_864=m
+CONFIG_NLS_CODEPAGE_865=m
+CONFIG_NLS_CODEPAGE_866=m
+CONFIG_NLS_CODEPAGE_869=m
+CONFIG_NLS_CODEPAGE_936=m
+CONFIG_NLS_CODEPAGE_950=m
+CONFIG_NLS_CODEPAGE_932=m
+CONFIG_NLS_CODEPAGE_949=m
+CONFIG_NLS_CODEPAGE_874=m
+CONFIG_NLS_ISO8859_8=m
+CONFIG_NLS_CODEPAGE_1250=m
+CONFIG_NLS_CODEPAGE_1251=m
+CONFIG_NLS_ASCII=y
+CONFIG_NLS_ISO8859_1=m
+CONFIG_NLS_ISO8859_2=m
+CONFIG_NLS_ISO8859_3=m
+CONFIG_NLS_ISO8859_4=m
+CONFIG_NLS_ISO8859_5=m
+CONFIG_NLS_ISO8859_6=m
+CONFIG_NLS_ISO8859_7=m
+CONFIG_NLS_ISO8859_9=m
+CONFIG_NLS_ISO8859_13=m
+CONFIG_NLS_ISO8859_14=m
+CONFIG_NLS_ISO8859_15=m
+CONFIG_NLS_KOI8_R=m
+CONFIG_NLS_KOI8_U=m
+CONFIG_NLS_UTF8=m
+
+#
+# Instrumentation Support
+#
+CONFIG_PROFILING=y
+CONFIG_OPROFILE=m
+CONFIG_KPROBES=y
+
+#
+# Kernel hacking
+#
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+# CONFIG_PRINTK_TIME is not set
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_UNUSED_SYMBOLS is not set
+CONFIG_DEBUG_KERNEL=y
+CONFIG_LOG_BUF_SHIFT=17
+CONFIG_DETECT_SOFTLOCKUP=y
+CONFIG_SCHEDSTATS=y
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
+CONFIG_DEBUG_SPINLOCK=y
+# 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=y
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+# CONFIG_DEBUG_KOBJECT is not set
+CONFIG_DEBUG_HIGHMEM=y
+CONFIG_DEBUG_BUGVERBOSE=y
+CONFIG_DEBUG_INFO=y
+CONFIG_DEBUG_FS=y
+# CONFIG_DEBUG_VM is not set
+CONFIG_DEBUG_LIST=y
+# CONFIG_FRAME_POINTER is not set
+CONFIG_UNWIND_INFO=y
+CONFIG_STACK_UNWIND=y
+# CONFIG_FORCED_INLINING is not set
+CONFIG_BOOT_DELAY=y
+# CONFIG_RCU_TORTURE_TEST is not set
+CONFIG_EARLY_PRINTK=y
+CONFIG_DEBUG_STACKOVERFLOW=y
+CONFIG_DEBUG_STACK_USAGE=y
+
+#
+# Page alloc debug is incompatible with Software Suspend on i386
+#
+CONFIG_DEBUG_RODATA=y
+CONFIG_4KSTACKS=y
+CONFIG_X86_FIND_SMP_CONFIG=y
+CONFIG_X86_MPPARSE=y
+CONFIG_DOUBLEFAULT=y
+
+#
+# Security options
+#
+CONFIG_KEYS=y
+CONFIG_KEYS_DEBUG_PROC_KEYS=y
+CONFIG_SECURITY=y
+CONFIG_SECURITY_NETWORK=y
+# CONFIG_SECURITY_NETWORK_XFRM is not set
+CONFIG_SECURITY_CAPABILITIES=y
+# CONFIG_SECURITY_ROOTPLUG is not set
+# CONFIG_SECURITY_SECLVL is not set
+CONFIG_SECURITY_SELINUX=y
+CONFIG_SECURITY_SELINUX_BOOTPARAM=y
+CONFIG_SECURITY_SELINUX_BOOTPARAM_VALUE=1
+CONFIG_SECURITY_SELINUX_DISABLE=y
+CONFIG_SECURITY_SELINUX_DEVELOP=y
+CONFIG_SECURITY_SELINUX_AVC_STATS=y
+CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE=1
+# CONFIG_SECURITY_SELINUX_ENABLE_SECMARK_DEFAULT is not set
+# CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX is not set
+
+#
+# Cryptographic options
+#
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_NULL=m
+CONFIG_CRYPTO_MD4=m
+CONFIG_CRYPTO_MD5=m
+CONFIG_CRYPTO_SHA1=y
+CONFIG_CRYPTO_SHA256=m
+CONFIG_CRYPTO_SHA512=m
+CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_TGR192=m
+CONFIG_CRYPTO_DES=m
+CONFIG_CRYPTO_BLOWFISH=m
+CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_SERPENT=m
+CONFIG_CRYPTO_AES=m
+CONFIG_CRYPTO_AES_586=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_TEST is not set
+CONFIG_CRYPTO_SIGNATURE=y
+CONFIG_CRYPTO_SIGNATURE_DSA=y
+CONFIG_CRYPTO_MPILIB=y
+
+#
+# Hardware crypto devices
+#
+CONFIG_CRYPTO_DEV_PADLOCK=m
+CONFIG_CRYPTO_DEV_PADLOCK_AES=y
+
+#
+# Library routines
+#
+CONFIG_CRC_CCITT=m
+CONFIG_CRC16=m
+CONFIG_CRC32=y
+CONFIG_LIBCRC32C=m
+CONFIG_AUDIT_GENERIC=y
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=m
+CONFIG_REED_SOLOMON=m
+CONFIG_REED_SOLOMON_DEC16=y
+CONFIG_TEXTSEARCH=y
+CONFIG_TEXTSEARCH_KMP=m
+CONFIG_TEXTSEARCH_BM=m
+CONFIG_TEXTSEARCH_FSM=m
+CONFIG_PLIST=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_X86_BIOS_REBOOT=y
+CONFIG_KTIME_SCALAR=y
diff --git a/configs/kernel-2.6.18-ia64-xen.config b/configs/kernel-2.6.18-ia64-xen.config
new file mode 100644
index 000000000..7fea409eb
--- /dev/null
+++ b/configs/kernel-2.6.18-ia64-xen.config
@@ -0,0 +1,2883 @@
+# ia64
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.18.2-rc1
+# Mon Nov 13 09:44:41 2006
+#
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_BSD_PROCESS_ACCT=y
+# CONFIG_BSD_PROCESS_ACCT_V3 is not set
+CONFIG_TASKSTATS=y
+CONFIG_TASK_DELAY_ACCT=y
+CONFIG_AUDIT=y
+CONFIG_AUDITSYSCALL=y
+# CONFIG_IKCONFIG is not set
+CONFIG_CPUSETS=y
+CONFIG_RELAY=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+# CONFIG_EMBEDDED is not set
+CONFIG_SYSCTL=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
+CONFIG_KALLSYMS_EXTRA_PASS=y
+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=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+CONFIG_MODULE_SIG=y
+# CONFIG_MODULE_SIG_FORCE is not set
+CONFIG_KMOD=y
+CONFIG_STOP_MACHINE=y
+
+#
+# Process debugging support
+#
+CONFIG_UTRACE=y
+CONFIG_PTRACE=y
+
+#
+# Block layer
+#
+CONFIG_BLK_DEV_IO_TRACE=y
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_DEFAULT_AS is not set
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+
+#
+# Processor type and features
+#
+CONFIG_IA64=y
+CONFIG_64BIT=y
+CONFIG_MMU=y
+CONFIG_SWIOTLB=y
+CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_TIME_INTERPOLATION=y
+CONFIG_DMI=y
+CONFIG_EFI=y
+CONFIG_GENERIC_IOMAP=y
+CONFIG_XEN=y
+CONFIG_XEN_IA64_VDSO_PARAVIRT=y
+CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
+CONFIG_DMA_IS_DMA32=y
+CONFIG_AUDIT_ARCH=y
+# CONFIG_IA64_GENERIC is not set
+CONFIG_IA64_DIG=y
+# CONFIG_IA64_HP_ZX1 is not set
+# CONFIG_IA64_HP_ZX1_SWIOTLB is not set
+# CONFIG_IA64_SGI_SN2 is not set
+# CONFIG_IA64_HP_SIM is not set
+# CONFIG_ITANIUM is not set
+CONFIG_MCKINLEY=y
+# CONFIG_IA64_PAGE_SIZE_4KB is not set
+# CONFIG_IA64_PAGE_SIZE_8KB is not set
+CONFIG_IA64_PAGE_SIZE_16KB=y
+# CONFIG_IA64_PAGE_SIZE_64KB is not set
+CONFIG_PGTABLE_3=y
+# CONFIG_PGTABLE_4 is not set
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
+CONFIG_IA64_L1_CACHE_SHIFT=7
+CONFIG_IA64_CYCLONE=y
+CONFIG_IOSAPIC=y
+CONFIG_FORCE_MAX_ZONEORDER=11
+CONFIG_SMP=y
+CONFIG_NR_CPUS=1024
+CONFIG_HOTPLUG_CPU=y
+CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
+CONFIG_SCHED_SMT=y
+# CONFIG_PERMIT_BSP_REMOVE is not set
+# CONFIG_PREEMPT 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=4
+CONFIG_RESOURCES_64BIT=y
+CONFIG_ARCH_SELECT_MEMORY_MODEL=y
+CONFIG_ARCH_DISCONTIGMEM_ENABLE=y
+CONFIG_ARCH_FLATMEM_ENABLE=y
+CONFIG_ARCH_SPARSEMEM_ENABLE=y
+# CONFIG_VIRTUAL_MEM_MAP is not set
+# CONFIG_IA32_SUPPORT is not set
+CONFIG_IA64_MCA_RECOVERY=m
+CONFIG_PERFMON=y
+CONFIG_IA64_PALINFO=y
+
+#
+# Firmware Drivers
+#
+CONFIG_EFI_VARS=y
+CONFIG_EFI_PCDP=y
+CONFIG_BINFMT_ELF=y
+CONFIG_BINFMT_MISC=y
+
+#
+# Power management and ACPI
+#
+CONFIG_PM=y
+CONFIG_PM_LEGACY=y
+# CONFIG_PM_DEBUG is not set
+
+#
+# ACPI (Advanced Configuration and Power Interface) Support
+#
+CONFIG_ACPI=y
+CONFIG_ACPI_BUTTON=m
+CONFIG_ACPI_FAN=y
+# CONFIG_ACPI_DOCK is not set
+CONFIG_ACPI_PROCESSOR=y
+CONFIG_ACPI_HOTPLUG_CPU=y
+CONFIG_ACPI_THERMAL=y
+CONFIG_ACPI_BLACKLIST_YEAR=0
+# CONFIG_ACPI_DEBUG is not set
+CONFIG_ACPI_EC=y
+CONFIG_ACPI_POWER=y
+CONFIG_ACPI_SYSTEM=y
+CONFIG_ACPI_CONTAINER=y
+
+#
+# CPU Frequency scaling
+#
+CONFIG_CPU_FREQ=y
+CONFIG_CPU_FREQ_TABLE=m
+CONFIG_CPU_FREQ_DEBUG=y
+CONFIG_CPU_FREQ_STAT=m
+CONFIG_CPU_FREQ_STAT_DETAILS=y
+# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set
+CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE=y
+CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
+CONFIG_CPU_FREQ_GOV_POWERSAVE=m
+CONFIG_CPU_FREQ_GOV_USERSPACE=y
+CONFIG_CPU_FREQ_GOV_ONDEMAND=m
+CONFIG_CPU_FREQ_GOV_CONSERVATIVE=m
+
+#
+# CPUFreq processor drivers
+#
+CONFIG_IA64_ACPI_CPUFREQ=m
+
+#
+# Bus options (PCI, PCMCIA)
+#
+CONFIG_PCI=y
+CONFIG_PCI_DOMAINS=y
+CONFIG_XEN_PCIDEV_FRONTEND=y
+# CONFIG_XEN_PCIDEV_FE_DEBUG is not set
+CONFIG_PCIEPORTBUS=y
+# CONFIG_HOTPLUG_PCI_PCIE is not set
+# CONFIG_PCI_DEBUG is not set
+
+#
+# PCI Hotplug Support
+#
+CONFIG_HOTPLUG_PCI=y
+CONFIG_HOTPLUG_PCI_FAKE=m
+CONFIG_HOTPLUG_PCI_ACPI=m
+CONFIG_HOTPLUG_PCI_ACPI_IBM=m
+# CONFIG_HOTPLUG_PCI_CPCI is not set
+CONFIG_HOTPLUG_PCI_SHPC=m
+CONFIG_HOTPLUG_PCI_SHPC_POLL_EVENT_MODE=y
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+CONFIG_PCCARD=y
+# CONFIG_PCMCIA_DEBUG is not set
+CONFIG_PCMCIA=y
+CONFIG_PCMCIA_LOAD_CIS=y
+CONFIG_PCMCIA_IOCTL=y
+CONFIG_CARDBUS=y
+
+#
+# PC-card bridges
+#
+CONFIG_YENTA=y
+CONFIG_YENTA_O2=y
+CONFIG_YENTA_RICOH=y
+CONFIG_YENTA_TI=y
+CONFIG_YENTA_ENE_TUNE=y
+CONFIG_YENTA_TOSHIBA=y
+CONFIG_PD6729=m
+CONFIG_I82092=m
+CONFIG_PCCARD_NONSTATIC=y
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+# CONFIG_NETDEBUG is not set
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=y
+CONFIG_NET_KEY=m
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_ASK_IP_FIB_HASH=y
+# 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
+# CONFIG_IP_PNP is not set
+CONFIG_NET_IPIP=m
+CONFIG_NET_IPGRE=m
+CONFIG_NET_IPGRE_BROADCAST=y
+CONFIG_IP_MROUTE=y
+CONFIG_IP_PIMSM_V1=y
+CONFIG_IP_PIMSM_V2=y
+# CONFIG_ARPD is not set
+CONFIG_SYN_COOKIES=y
+CONFIG_INET_AH=m
+CONFIG_INET_ESP=m
+CONFIG_INET_IPCOMP=m
+CONFIG_INET_XFRM_TUNNEL=m
+CONFIG_INET_TUNNEL=m
+CONFIG_INET_XFRM_MODE_TRANSPORT=m
+CONFIG_INET_XFRM_MODE_TUNNEL=m
+CONFIG_INET_DIAG=m
+CONFIG_INET_TCP_DIAG=m
+CONFIG_TCP_CONG_ADVANCED=y
+
+#
+# TCP congestion control
+#
+CONFIG_TCP_CONG_BIC=y
+CONFIG_TCP_CONG_CUBIC=m
+CONFIG_TCP_CONG_WESTWOOD=m
+CONFIG_TCP_CONG_HTCP=m
+CONFIG_TCP_CONG_HSTCP=m
+CONFIG_TCP_CONG_HYBLA=m
+CONFIG_TCP_CONG_VEGAS=m
+CONFIG_TCP_CONG_SCALABLE=m
+CONFIG_TCP_CONG_LP=m
+CONFIG_TCP_CONG_VENO=m
+
+#
+# IP: Virtual Server Configuration
+#
+CONFIG_IP_VS=m
+# CONFIG_IP_VS_DEBUG is not set
+CONFIG_IP_VS_TAB_BITS=12
+
+#
+# IPVS transport protocol load balancing support
+#
+CONFIG_IP_VS_PROTO_TCP=y
+CONFIG_IP_VS_PROTO_UDP=y
+CONFIG_IP_VS_PROTO_ESP=y
+CONFIG_IP_VS_PROTO_AH=y
+
+#
+# IPVS scheduler
+#
+CONFIG_IP_VS_RR=m
+CONFIG_IP_VS_WRR=m
+CONFIG_IP_VS_LC=m
+CONFIG_IP_VS_WLC=m
+CONFIG_IP_VS_LBLC=m
+CONFIG_IP_VS_LBLCR=m
+CONFIG_IP_VS_DH=m
+CONFIG_IP_VS_SH=m
+CONFIG_IP_VS_SED=m
+CONFIG_IP_VS_NQ=m
+
+#
+# IPVS application helper
+#
+CONFIG_IP_VS_FTP=m
+CONFIG_IPV6=m
+CONFIG_IPV6_PRIVACY=y
+CONFIG_IPV6_ROUTER_PREF=y
+CONFIG_IPV6_ROUTE_INFO=y
+CONFIG_INET6_AH=m
+CONFIG_INET6_ESP=m
+CONFIG_INET6_IPCOMP=m
+CONFIG_INET6_XFRM_TUNNEL=m
+CONFIG_INET6_TUNNEL=m
+CONFIG_INET6_XFRM_MODE_TRANSPORT=m
+CONFIG_INET6_XFRM_MODE_TUNNEL=m
+CONFIG_IPV6_TUNNEL=m
+CONFIG_NETWORK_SECMARK=y
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_DEBUG is not set
+CONFIG_BRIDGE_NETFILTER=y
+
+#
+# Core Netfilter Configuration
+#
+CONFIG_NETFILTER_NETLINK=m
+CONFIG_NETFILTER_NETLINK_QUEUE=m
+CONFIG_NETFILTER_NETLINK_LOG=m
+CONFIG_NETFILTER_XTABLES=m
+CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
+CONFIG_NETFILTER_XT_TARGET_CONNMARK=m
+CONFIG_NETFILTER_XT_TARGET_MARK=m
+CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
+CONFIG_NETFILTER_XT_TARGET_NOTRACK=m
+CONFIG_NETFILTER_XT_TARGET_SECMARK=m
+CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=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_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_PHYSDEV=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
+
+#
+# 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=m
+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_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_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_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
+CONFIG_IP_NF_ARPTABLES=m
+CONFIG_IP_NF_ARPFILTER=m
+CONFIG_IP_NF_ARP_MANGLE=m
+
+#
+# IPv6: Netfilter Configuration (EXPERIMENTAL)
+#
+CONFIG_IP6_NF_QUEUE=m
+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_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
+
+#
+# DECnet: Netfilter Configuration
+#
+# CONFIG_DECNET_NF_GRABULATOR is not set
+
+#
+# Bridge: Netfilter Configuration
+#
+CONFIG_BRIDGE_NF_EBTABLES=m
+CONFIG_BRIDGE_EBT_BROUTE=m
+CONFIG_BRIDGE_EBT_T_FILTER=m
+CONFIG_BRIDGE_EBT_T_NAT=m
+CONFIG_BRIDGE_EBT_802_3=m
+CONFIG_BRIDGE_EBT_AMONG=m
+CONFIG_BRIDGE_EBT_ARP=m
+CONFIG_BRIDGE_EBT_IP=m
+CONFIG_BRIDGE_EBT_LIMIT=m
+CONFIG_BRIDGE_EBT_MARK=m
+CONFIG_BRIDGE_EBT_PKTTYPE=m
+CONFIG_BRIDGE_EBT_STP=m
+CONFIG_BRIDGE_EBT_VLAN=m
+CONFIG_BRIDGE_EBT_ARPREPLY=m
+CONFIG_BRIDGE_EBT_DNAT=m
+CONFIG_BRIDGE_EBT_MARK_T=m
+CONFIG_BRIDGE_EBT_REDIRECT=m
+CONFIG_BRIDGE_EBT_SNAT=m
+CONFIG_BRIDGE_EBT_LOG=m
+CONFIG_BRIDGE_EBT_ULOG=m
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+CONFIG_IP_DCCP=m
+CONFIG_INET_DCCP_DIAG=m
+CONFIG_IP_DCCP_ACKVEC=y
+
+#
+# DCCP CCIDs Configuration (EXPERIMENTAL)
+#
+CONFIG_IP_DCCP_CCID2=m
+CONFIG_IP_DCCP_CCID3=m
+CONFIG_IP_DCCP_TFRC_LIB=m
+
+#
+# DCCP Kernel Hacking
+#
+# CONFIG_IP_DCCP_DEBUG is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+CONFIG_IP_SCTP=m
+# CONFIG_SCTP_DBG_MSG is not set
+# CONFIG_SCTP_DBG_OBJCNT is not set
+# CONFIG_SCTP_HMAC_NONE is not set
+# CONFIG_SCTP_HMAC_SHA1 is not set
+CONFIG_SCTP_HMAC_MD5=y
+
+#
+# TIPC Configuration (EXPERIMENTAL)
+#
+CONFIG_TIPC=m
+# CONFIG_TIPC_ADVANCED is not set
+# CONFIG_TIPC_DEBUG is not set
+CONFIG_ATM=m
+CONFIG_ATM_CLIP=m
+# CONFIG_ATM_CLIP_NO_ICMP is not set
+CONFIG_ATM_LANE=m
+# CONFIG_ATM_MPOA is not set
+CONFIG_ATM_BR2684=m
+# CONFIG_ATM_BR2684_IPFILTER is not set
+CONFIG_BRIDGE=m
+CONFIG_VLAN_8021Q=m
+CONFIG_DECNET=m
+CONFIG_DECNET_ROUTER=y
+CONFIG_DECNET_ROUTE_FWMARK=y
+CONFIG_LLC=y
+# CONFIG_LLC2 is not set
+CONFIG_IPX=m
+# CONFIG_IPX_INTERN is not set
+CONFIG_ATALK=m
+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_ECONET is not set
+CONFIG_WAN_ROUTER=m
+
+#
+# QoS and/or fair queueing
+#
+CONFIG_NET_SCHED=y
+# CONFIG_NET_SCH_CLK_JIFFIES is not set
+CONFIG_NET_SCH_CLK_GETTIMEOFDAY=y
+# CONFIG_NET_SCH_CLK_CPU is not set
+
+#
+# Queueing/Scheduling
+#
+CONFIG_NET_SCH_CBQ=m
+CONFIG_NET_SCH_HTB=m
+CONFIG_NET_SCH_HFSC=m
+CONFIG_NET_SCH_ATM=m
+CONFIG_NET_SCH_PRIO=m
+CONFIG_NET_SCH_RED=m
+CONFIG_NET_SCH_SFQ=m
+CONFIG_NET_SCH_TEQL=m
+CONFIG_NET_SCH_TBF=m
+CONFIG_NET_SCH_GRED=m
+CONFIG_NET_SCH_DSMARK=m
+CONFIG_NET_SCH_NETEM=m
+CONFIG_NET_SCH_INGRESS=m
+
+#
+# Classification
+#
+CONFIG_NET_CLS=y
+CONFIG_NET_CLS_BASIC=m
+CONFIG_NET_CLS_TCINDEX=m
+CONFIG_NET_CLS_ROUTE4=m
+CONFIG_NET_CLS_ROUTE=y
+CONFIG_NET_CLS_FW=m
+CONFIG_NET_CLS_U32=m
+CONFIG_CLS_U32_PERF=y
+CONFIG_CLS_U32_MARK=y
+CONFIG_NET_CLS_RSVP=m
+CONFIG_NET_CLS_RSVP6=m
+CONFIG_NET_EMATCH=y
+CONFIG_NET_EMATCH_STACK=32
+CONFIG_NET_EMATCH_CMP=m
+CONFIG_NET_EMATCH_NBYTE=m
+CONFIG_NET_EMATCH_U32=m
+CONFIG_NET_EMATCH_META=m
+CONFIG_NET_EMATCH_TEXT=m
+CONFIG_NET_CLS_ACT=y
+CONFIG_NET_ACT_POLICE=m
+CONFIG_NET_ACT_GACT=m
+CONFIG_GACT_PROB=y
+CONFIG_NET_ACT_MIRRED=m
+CONFIG_NET_ACT_IPT=m
+CONFIG_NET_ACT_PEDIT=m
+CONFIG_NET_ACT_SIMP=m
+CONFIG_NET_CLS_IND=y
+CONFIG_NET_ESTIMATOR=y
+
+#
+# Network testing
+#
+CONFIG_NET_PKTGEN=m
+# CONFIG_NET_TCPPROBE is not set
+# CONFIG_HAMRADIO is not set
+CONFIG_IRDA=m
+
+#
+# IrDA protocols
+#
+CONFIG_IRLAN=m
+CONFIG_IRNET=m
+CONFIG_IRCOMM=m
+# CONFIG_IRDA_ULTRA is not set
+
+#
+# IrDA options
+#
+CONFIG_IRDA_CACHE_LAST_LSAP=y
+CONFIG_IRDA_FAST_RR=y
+# CONFIG_IRDA_DEBUG is not set
+
+#
+# Infrared-port device drivers
+#
+
+#
+# SIR device drivers
+#
+CONFIG_IRTTY_SIR=m
+
+#
+# Dongle support
+#
+CONFIG_DONGLE=y
+CONFIG_ESI_DONGLE=m
+CONFIG_ACTISYS_DONGLE=m
+CONFIG_TEKRAM_DONGLE=m
+CONFIG_TOIM3232_DONGLE=m
+CONFIG_LITELINK_DONGLE=m
+CONFIG_MA600_DONGLE=m
+CONFIG_GIRBIL_DONGLE=m
+CONFIG_MCP2120_DONGLE=m
+CONFIG_OLD_BELKIN_DONGLE=m
+CONFIG_ACT200L_DONGLE=m
+
+#
+# Old SIR device drivers
+#
+
+#
+# Old Serial dongle support
+#
+
+#
+# FIR device drivers
+#
+CONFIG_USB_IRDA=m
+CONFIG_SIGMATEL_FIR=m
+CONFIG_VLSI_FIR=m
+CONFIG_MCS_FIR=m
+CONFIG_BT=m
+CONFIG_BT_L2CAP=m
+CONFIG_BT_SCO=m
+CONFIG_BT_RFCOMM=m
+CONFIG_BT_RFCOMM_TTY=y
+CONFIG_BT_BNEP=m
+CONFIG_BT_BNEP_MC_FILTER=y
+CONFIG_BT_BNEP_PROTO_FILTER=y
+CONFIG_BT_CMTP=m
+CONFIG_BT_HIDP=m
+
+#
+# Bluetooth device drivers
+#
+CONFIG_BT_HCIUSB=m
+CONFIG_BT_HCIUSB_SCO=y
+CONFIG_BT_HCIUART=m
+CONFIG_BT_HCIUART_H4=y
+CONFIG_BT_HCIUART_BCSP=y
+CONFIG_BT_HCIBCM203X=m
+CONFIG_BT_HCIBPA10X=m
+CONFIG_BT_HCIBFUSB=m
+CONFIG_BT_HCIDTL1=m
+CONFIG_BT_HCIBT3C=m
+CONFIG_BT_HCIBLUECARD=m
+CONFIG_BT_HCIBTUART=m
+CONFIG_BT_HCIVHCI=m
+CONFIG_IEEE80211=m
+CONFIG_IEEE80211_DEBUG=y
+CONFIG_IEEE80211_CRYPT_WEP=m
+CONFIG_IEEE80211_CRYPT_CCMP=m
+CONFIG_IEEE80211_CRYPT_TKIP=m
+CONFIG_IEEE80211_SOFTMAC=m
+CONFIG_IEEE80211_SOFTMAC_DEBUG=y
+CONFIG_TUX=m
+
+#
+# TUX options
+#
+CONFIG_TUX_EXTCGI=y
+CONFIG_TUX_EXTENDED_LOG=y
+# CONFIG_TUX_DEBUG is not set
+CONFIG_WIRELESS_EXT=y
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_SYS_HYPERVISOR is not set
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+CONFIG_CONNECTOR=y
+CONFIG_PROC_EVENTS=y
+
+#
+# Memory Technology Devices (MTD)
+#
+# CONFIG_MTD is not set
+
+#
+# Parallel port support
+#
+CONFIG_PARPORT=m
+CONFIG_PARPORT_PC=m
+# CONFIG_PARPORT_PC_FIFO is not set
+# CONFIG_PARPORT_PC_SUPERIO is not set
+CONFIG_PARPORT_PC_PCMCIA=m
+CONFIG_PARPORT_NOT_PC=y
+# CONFIG_PARPORT_GSC is not set
+# CONFIG_PARPORT_AX88796 is not set
+CONFIG_PARPORT_1284=y
+
+#
+# Plug and Play support
+#
+CONFIG_PNP=y
+# CONFIG_PNP_DEBUG is not set
+
+#
+# Protocols
+#
+CONFIG_PNPACPI=y
+
+#
+# Block devices
+#
+CONFIG_PARIDE=m
+CONFIG_PARIDE_PARPORT=m
+
+#
+# Parallel IDE high-level drivers
+#
+CONFIG_PARIDE_PD=m
+CONFIG_PARIDE_PCD=m
+CONFIG_PARIDE_PF=m
+CONFIG_PARIDE_PT=m
+CONFIG_PARIDE_PG=m
+
+#
+# Parallel IDE protocol modules
+#
+CONFIG_PARIDE_ATEN=m
+CONFIG_PARIDE_BPCK=m
+CONFIG_PARIDE_COMM=m
+CONFIG_PARIDE_DSTR=m
+CONFIG_PARIDE_FIT2=m
+CONFIG_PARIDE_FIT3=m
+CONFIG_PARIDE_EPAT=m
+CONFIG_PARIDE_EPATC8=y
+CONFIG_PARIDE_EPIA=m
+CONFIG_PARIDE_FRIQ=m
+CONFIG_PARIDE_FRPW=m
+CONFIG_PARIDE_KBIC=m
+CONFIG_PARIDE_KTTI=m
+CONFIG_PARIDE_ON20=m
+CONFIG_PARIDE_ON26=m
+CONFIG_BLK_CPQ_DA=m
+CONFIG_BLK_CPQ_CISS_DA=m
+CONFIG_CISS_SCSI_TAPE=y
+CONFIG_BLK_DEV_DAC960=m
+CONFIG_BLK_DEV_UMEM=m
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=m
+CONFIG_BLK_DEV_CRYPTOLOOP=m
+CONFIG_BLK_DEV_NBD=m
+CONFIG_BLK_DEV_SX8=m
+CONFIG_BLK_DEV_UB=m
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=16384
+CONFIG_BLK_DEV_RAM_BLOCKSIZE=4096
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_CDROM_PKTCDVD=m
+CONFIG_CDROM_PKTCDVD_BUFFERS=8
+# CONFIG_CDROM_PKTCDVD_WCACHE is not set
+CONFIG_ATA_OVER_ETH=m
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+CONFIG_IDE=y
+CONFIG_IDE_MAX_HWIFS=4
+CONFIG_BLK_DEV_IDE=y
+
+#
+# Please see Documentation/ide.txt for help/info on IDE drives
+#
+# CONFIG_BLK_DEV_IDE_SATA is not set
+CONFIG_BLK_DEV_IDEDISK=y
+CONFIG_IDEDISK_MULTI_MODE=y
+CONFIG_BLK_DEV_IDECS=m
+CONFIG_BLK_DEV_IDECD=m
+# CONFIG_BLK_DEV_IDETAPE is not set
+CONFIG_BLK_DEV_IDEFLOPPY=y
+CONFIG_BLK_DEV_IDESCSI=m
+CONFIG_IDE_TASK_IOCTL=y
+
+#
+# IDE chipset support/bugfixes
+#
+CONFIG_IDE_GENERIC=y
+CONFIG_BLK_DEV_IDEPNP=y
+CONFIG_BLK_DEV_IDEPCI=y
+CONFIG_IDEPCI_SHARE_IRQ=y
+# CONFIG_BLK_DEV_OFFBOARD is not set
+CONFIG_BLK_DEV_GENERIC=y
+# CONFIG_BLK_DEV_OPTI621 is not set
+CONFIG_BLK_DEV_IDEDMA_PCI=y
+# CONFIG_BLK_DEV_IDEDMA_FORCED is not set
+CONFIG_IDEDMA_PCI_AUTO=y
+# CONFIG_IDEDMA_ONLYDISK is not set
+CONFIG_BLK_DEV_AEC62XX=y
+CONFIG_BLK_DEV_ALI15X3=y
+# CONFIG_WDC_ALI15X3 is not set
+# CONFIG_BLK_DEV_AMD74XX is not set
+CONFIG_BLK_DEV_CMD64X=y
+CONFIG_BLK_DEV_TRIFLEX=y
+# CONFIG_BLK_DEV_CY82C693 is not set
+CONFIG_BLK_DEV_CS5520=y
+CONFIG_BLK_DEV_CS5530=y
+CONFIG_BLK_DEV_HPT34X=y
+# CONFIG_HPT34X_AUTODMA is not set
+CONFIG_BLK_DEV_HPT366=y
+# CONFIG_BLK_DEV_SC1200 is not set
+CONFIG_BLK_DEV_PIIX=y
+CONFIG_BLK_DEV_IT821X=y
+# CONFIG_BLK_DEV_NS87415 is not set
+CONFIG_BLK_DEV_PDC202XX_OLD=y
+# CONFIG_PDC202XX_BURST is not set
+CONFIG_BLK_DEV_PDC202XX_NEW=y
+CONFIG_BLK_DEV_SVWKS=y
+CONFIG_BLK_DEV_SIIMAGE=y
+# CONFIG_BLK_DEV_SLC90E66 is not set
+# CONFIG_BLK_DEV_TRM290 is not set
+CONFIG_BLK_DEV_VIA82CXXX=y
+# CONFIG_IDE_ARM is not set
+CONFIG_BLK_DEV_IDEDMA=y
+# CONFIG_IDEDMA_IVB is not set
+CONFIG_IDEDMA_AUTO=y
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# SCSI device support
+#
+CONFIG_RAID_ATTRS=m
+CONFIG_SCSI=m
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=m
+CONFIG_CHR_DEV_ST=m
+CONFIG_CHR_DEV_OSST=m
+CONFIG_BLK_DEV_SR=m
+CONFIG_BLK_DEV_SR_VENDOR=y
+CONFIG_CHR_DEV_SG=m
+CONFIG_CHR_DEV_SCH=m
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+CONFIG_SCSI_MULTI_LUN=y
+CONFIG_SCSI_CONSTANTS=y
+CONFIG_SCSI_LOGGING=y
+
+#
+# SCSI Transport Attributes
+#
+CONFIG_SCSI_SPI_ATTRS=m
+CONFIG_SCSI_FC_ATTRS=m
+CONFIG_SCSI_ISCSI_ATTRS=m
+CONFIG_SCSI_SAS_ATTRS=m
+
+#
+# SCSI low-level drivers
+#
+CONFIG_ISCSI_TCP=m
+CONFIG_BLK_DEV_3W_XXXX_RAID=m
+CONFIG_SCSI_3W_9XXX=m
+CONFIG_SCSI_ACARD=m
+CONFIG_SCSI_AACRAID=m
+CONFIG_SCSI_AIC7XXX=m
+CONFIG_AIC7XXX_CMDS_PER_DEVICE=4
+CONFIG_AIC7XXX_RESET_DELAY_MS=15000
+# CONFIG_AIC7XXX_DEBUG_ENABLE is not set
+CONFIG_AIC7XXX_DEBUG_MASK=0
+# CONFIG_AIC7XXX_REG_PRETTY_PRINT is not set
+CONFIG_SCSI_AIC7XXX_OLD=m
+CONFIG_SCSI_AIC79XX=m
+CONFIG_AIC79XX_CMDS_PER_DEVICE=4
+CONFIG_AIC79XX_RESET_DELAY_MS=15000
+# CONFIG_AIC79XX_ENABLE_RD_STRM is not set
+# CONFIG_AIC79XX_DEBUG_ENABLE is not set
+CONFIG_AIC79XX_DEBUG_MASK=0
+# CONFIG_AIC79XX_REG_PRETTY_PRINT is not set
+CONFIG_MEGARAID_NEWGEN=y
+CONFIG_MEGARAID_MM=m
+CONFIG_MEGARAID_MAILBOX=m
+CONFIG_MEGARAID_LEGACY=m
+CONFIG_MEGARAID_SAS=m
+CONFIG_SCSI_SATA=m
+CONFIG_SCSI_SATA_AHCI=m
+CONFIG_SCSI_SATA_SVW=m
+CONFIG_SCSI_ATA_PIIX=m
+CONFIG_SCSI_SATA_MV=m
+CONFIG_SCSI_SATA_NV=m
+CONFIG_SCSI_PDC_ADMA=m
+CONFIG_SCSI_HPTIOP=m
+CONFIG_SCSI_SATA_QSTOR=m
+CONFIG_SCSI_SATA_PROMISE=m
+CONFIG_SCSI_SATA_SX4=m
+CONFIG_SCSI_SATA_SIL=m
+CONFIG_SCSI_SATA_SIL24=m
+CONFIG_SCSI_SATA_SIS=m
+CONFIG_SCSI_SATA_ULI=m
+CONFIG_SCSI_SATA_VIA=m
+CONFIG_SCSI_SATA_VITESSE=m
+CONFIG_SCSI_SATA_INTEL_COMBINED=y
+# CONFIG_SCSI_DMX3191D is not set
+# CONFIG_SCSI_FUTURE_DOMAIN is not set
+CONFIG_SCSI_IPS=m
+CONFIG_SCSI_INITIO=m
+CONFIG_SCSI_INIA100=m
+CONFIG_SCSI_PPA=m
+CONFIG_SCSI_IMM=m
+# CONFIG_SCSI_IZIP_EPP16 is not set
+# CONFIG_SCSI_IZIP_SLOW_CTR is not set
+CONFIG_SCSI_SYM53C8XX_2=m
+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_QLOGIC_1280=m
+CONFIG_SCSI_QLA_FC=m
+CONFIG_SCSI_LPFC=m
+CONFIG_SCSI_DC395x=m
+CONFIG_SCSI_DC390T=m
+# CONFIG_SCSI_DEBUG is not set
+
+#
+# PCMCIA SCSI adapter support
+#
+# CONFIG_PCMCIA_FDOMAIN is not set
+CONFIG_PCMCIA_QLOGIC=m
+CONFIG_PCMCIA_SYM53C500=m
+
+#
+# Multi-device support (RAID and LVM)
+#
+CONFIG_MD=y
+CONFIG_BLK_DEV_MD=y
+CONFIG_MD_LINEAR=m
+CONFIG_MD_RAID0=m
+CONFIG_MD_RAID1=m
+CONFIG_MD_RAID10=m
+CONFIG_MD_RAID456=m
+CONFIG_MD_RAID5_RESHAPE=y
+CONFIG_MD_MULTIPATH=m
+CONFIG_MD_FAULTY=m
+CONFIG_BLK_DEV_DM=m
+CONFIG_DM_CRYPT=m
+CONFIG_DM_SNAPSHOT=m
+CONFIG_DM_MIRROR=m
+CONFIG_DM_ZERO=m
+CONFIG_DM_MULTIPATH=m
+CONFIG_DM_MULTIPATH_EMC=m
+
+#
+# Fusion MPT device support
+#
+CONFIG_FUSION=y
+CONFIG_FUSION_SPI=m
+CONFIG_FUSION_FC=m
+CONFIG_FUSION_SAS=m
+CONFIG_FUSION_MAX_SGE=40
+CONFIG_FUSION_CTL=m
+CONFIG_FUSION_LAN=m
+
+#
+# IEEE 1394 (FireWire) support
+#
+CONFIG_IEEE1394=m
+
+#
+# Subsystem Options
+#
+# CONFIG_IEEE1394_VERBOSEDEBUG is not set
+CONFIG_IEEE1394_OUI_DB=y
+CONFIG_IEEE1394_EXTRA_CONFIG_ROMS=y
+CONFIG_IEEE1394_CONFIG_ROM_IP1394=y
+# CONFIG_IEEE1394_EXPORT_FULL_API is not set
+
+#
+# Device Drivers
+#
+CONFIG_IEEE1394_PCILYNX=m
+CONFIG_IEEE1394_OHCI1394=m
+
+#
+# Protocol Drivers
+#
+CONFIG_IEEE1394_VIDEO1394=m
+CONFIG_IEEE1394_SBP2=m
+CONFIG_IEEE1394_ETH1394=m
+CONFIG_IEEE1394_DV1394=m
+CONFIG_IEEE1394_RAWIO=m
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+CONFIG_IFB=m
+CONFIG_DUMMY=m
+CONFIG_BONDING=m
+CONFIG_EQUALIZER=m
+CONFIG_TUN=m
+CONFIG_NET_SB1000=m
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+
+#
+# PHY device support
+#
+CONFIG_PHYLIB=m
+
+#
+# MII PHY device drivers
+#
+CONFIG_MARVELL_PHY=m
+CONFIG_DAVICOM_PHY=m
+CONFIG_QSEMI_PHY=m
+CONFIG_LXT_PHY=m
+CONFIG_CICADA_PHY=m
+CONFIG_VITESSE_PHY=m
+CONFIG_SMSC_PHY=m
+CONFIG_FIXED_PHY=m
+CONFIG_FIXED_MII_10_FDX=y
+CONFIG_FIXED_MII_100_FDX=y
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=m
+CONFIG_HAPPYMEAL=m
+CONFIG_SUNGEM=m
+CONFIG_CASSINI=m
+CONFIG_NET_VENDOR_3COM=y
+CONFIG_VORTEX=m
+CONFIG_TYPHOON=m
+
+#
+# Tulip family network device support
+#
+CONFIG_NET_TULIP=y
+CONFIG_DE2104X=m
+CONFIG_TULIP=m
+# CONFIG_TULIP_MWI is not set
+CONFIG_TULIP_MMIO=y
+# CONFIG_TULIP_NAPI is not set
+CONFIG_DE4X5=m
+CONFIG_WINBOND_840=m
+CONFIG_DM9102=m
+CONFIG_ULI526X=m
+CONFIG_PCMCIA_XIRCOM=m
+# CONFIG_HP100 is not set
+CONFIG_NET_PCI=y
+CONFIG_PCNET32=m
+CONFIG_AMD8111_ETH=m
+CONFIG_AMD8111E_NAPI=y
+CONFIG_ADAPTEC_STARFIRE=m
+CONFIG_ADAPTEC_STARFIRE_NAPI=y
+CONFIG_B44=m
+CONFIG_FORCEDETH=m
+# CONFIG_DGRS is not set
+# CONFIG_EEPRO100 is not set
+CONFIG_E100=m
+CONFIG_FEALNX=m
+CONFIG_NATSEMI=m
+CONFIG_NE2K_PCI=m
+CONFIG_8139CP=m
+CONFIG_8139TOO=m
+# CONFIG_8139TOO_PIO is not set
+# CONFIG_8139TOO_TUNE_TWISTER is not set
+CONFIG_8139TOO_8129=y
+# CONFIG_8139_OLD_RX_RESET is not set
+CONFIG_SIS900=m
+CONFIG_EPIC100=m
+CONFIG_SUNDANCE=m
+# CONFIG_SUNDANCE_MMIO is not set
+CONFIG_VIA_RHINE=m
+CONFIG_VIA_RHINE_MMIO=y
+CONFIG_VIA_RHINE_NAPI=y
+CONFIG_NET_POCKET=y
+CONFIG_DE600=m
+CONFIG_DE620=m
+
+#
+# Ethernet (1000 Mbit)
+#
+CONFIG_ACENIC=m
+# CONFIG_ACENIC_OMIT_TIGON_I is not set
+CONFIG_DL2K=m
+CONFIG_E1000=m
+CONFIG_E1000_NAPI=y
+# CONFIG_E1000_DISABLE_PACKET_SPLIT is not set
+CONFIG_NS83820=m
+CONFIG_HAMACHI=m
+CONFIG_YELLOWFIN=m
+CONFIG_R8169=m
+CONFIG_R8169_NAPI=y
+CONFIG_R8169_VLAN=y
+CONFIG_SIS190=m
+CONFIG_SKGE=m
+CONFIG_SKY2=m
+# CONFIG_SK98LIN is not set
+CONFIG_VIA_VELOCITY=m
+CONFIG_TIGON3=m
+CONFIG_BNX2=m
+
+#
+# Ethernet (10000 Mbit)
+#
+CONFIG_CHELSIO_T1=m
+CONFIG_IXGB=m
+CONFIG_IXGB_NAPI=y
+CONFIG_S2IO=m
+CONFIG_S2IO_NAPI=y
+CONFIG_MYRI10GE=m
+
+#
+# Token Ring devices
+#
+CONFIG_TR=y
+CONFIG_IBMOL=m
+CONFIG_3C359=m
+# CONFIG_TMS380TR is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+CONFIG_NET_RADIO=y
+CONFIG_NET_WIRELESS_RTNETLINK=y
+
+#
+# Obsolete Wireless cards support (pre-802.11)
+#
+# CONFIG_STRIP is not set
+CONFIG_PCMCIA_WAVELAN=m
+CONFIG_PCMCIA_NETWAVE=m
+
+#
+# Wireless 802.11 Frequency Hopping cards support
+#
+# CONFIG_PCMCIA_RAYCS is not set
+
+#
+# Wireless 802.11b ISA/PCI cards support
+#
+# CONFIG_IPW2100 is not set
+# CONFIG_IPW2200 is not set
+CONFIG_HERMES=m
+CONFIG_PLX_HERMES=m
+CONFIG_TMD_HERMES=m
+CONFIG_NORTEL_HERMES=m
+CONFIG_PCI_HERMES=m
+CONFIG_ATMEL=m
+CONFIG_PCI_ATMEL=m
+
+#
+# Wireless 802.11b Pcmcia/Cardbus cards support
+#
+CONFIG_PCMCIA_HERMES=m
+CONFIG_PCMCIA_SPECTRUM=m
+CONFIG_AIRO_CS=m
+CONFIG_PCMCIA_ATMEL=m
+CONFIG_PCMCIA_WL3501=m
+
+#
+# Prism GT/Duette 802.11(a/b/g) PCI/Cardbus support
+#
+CONFIG_PRISM54=m
+CONFIG_USB_ZD1201=m
+CONFIG_HOSTAP=m
+CONFIG_HOSTAP_FIRMWARE=y
+CONFIG_HOSTAP_FIRMWARE_NVRAM=y
+CONFIG_HOSTAP_PLX=m
+CONFIG_HOSTAP_PCI=m
+CONFIG_HOSTAP_CS=m
+# CONFIG_BCM43XX is not set
+CONFIG_ZD1211RW=m
+# CONFIG_ZD1211RW_DEBUG is not set
+CONFIG_NET_WIRELESS=y
+
+#
+# PCMCIA network device support
+#
+CONFIG_NET_PCMCIA=y
+CONFIG_PCMCIA_3C589=m
+CONFIG_PCMCIA_3C574=m
+CONFIG_PCMCIA_FMVJ18X=m
+CONFIG_PCMCIA_PCNET=m
+CONFIG_PCMCIA_NMCLAN=m
+CONFIG_PCMCIA_SMC91C92=m
+CONFIG_PCMCIA_XIRC2PS=m
+CONFIG_PCMCIA_AXNET=m
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+
+#
+# ATM drivers
+#
+# CONFIG_ATM_DUMMY is not set
+CONFIG_ATM_TCP=m
+CONFIG_ATM_LANAI=m
+CONFIG_ATM_ENI=m
+# CONFIG_ATM_ENI_DEBUG is not set
+# CONFIG_ATM_ENI_TUNE_BURST is not set
+CONFIG_ATM_FIRESTREAM=m
+# CONFIG_ATM_ZATM is not set
+CONFIG_ATM_IDT77252=m
+# CONFIG_ATM_IDT77252_DEBUG is not set
+# CONFIG_ATM_IDT77252_RCV_ALL is not set
+CONFIG_ATM_IDT77252_USE_SUNI=y
+CONFIG_ATM_AMBASSADOR=m
+# CONFIG_ATM_AMBASSADOR_DEBUG is not set
+CONFIG_ATM_HORIZON=m
+# CONFIG_ATM_HORIZON_DEBUG is not set
+CONFIG_ATM_FORE200E_MAYBE=m
+# CONFIG_ATM_FORE200E_PCA is not set
+CONFIG_ATM_HE=m
+# CONFIG_ATM_HE_USE_SUNI is not set
+CONFIG_FDDI=y
+# CONFIG_DEFXX is not set
+CONFIG_SKFP=m
+# CONFIG_HIPPI is not set
+CONFIG_PLIP=m
+CONFIG_PPP=m
+CONFIG_PPP_MULTILINK=y
+CONFIG_PPP_FILTER=y
+CONFIG_PPP_ASYNC=m
+CONFIG_PPP_SYNC_TTY=m
+CONFIG_PPP_DEFLATE=m
+# CONFIG_PPP_BSDCOMP is not set
+CONFIG_PPP_MPPE=m
+CONFIG_PPPOE=m
+CONFIG_PPPOATM=m
+CONFIG_SLIP=m
+CONFIG_SLIP_COMPRESSED=y
+CONFIG_SLIP_SMART=y
+# CONFIG_SLIP_MODE_SLIP6 is not set
+CONFIG_NET_FC=y
+# CONFIG_SHAPER is not set
+CONFIG_NETCONSOLE=m
+CONFIG_NETPOLL=y
+# CONFIG_NETPOLL_RX is not set
+CONFIG_NETPOLL_TRAP=y
+CONFIG_NET_POLL_CONTROLLER=y
+
+#
+# ISDN subsystem
+#
+CONFIG_ISDN=m
+
+#
+# Old ISDN4Linux
+#
+CONFIG_ISDN_I4L=m
+CONFIG_ISDN_PPP=y
+CONFIG_ISDN_PPP_VJ=y
+CONFIG_ISDN_MPP=y
+CONFIG_IPPP_FILTER=y
+# CONFIG_ISDN_PPP_BSDCOMP is not set
+CONFIG_ISDN_AUDIO=y
+CONFIG_ISDN_TTY_FAX=y
+
+#
+# ISDN feature submodules
+#
+CONFIG_ISDN_DIVERSION=m
+
+#
+# ISDN4Linux hardware drivers
+#
+
+#
+# Passive cards
+#
+CONFIG_ISDN_DRV_HISAX=m
+
+#
+# D-channel protocol features
+#
+CONFIG_HISAX_EURO=y
+CONFIG_DE_AOC=y
+CONFIG_HISAX_NO_SENDCOMPLETE=y
+CONFIG_HISAX_NO_LLC=y
+CONFIG_HISAX_NO_KEYPAD=y
+CONFIG_HISAX_1TR6=y
+CONFIG_HISAX_NI1=y
+CONFIG_HISAX_MAX_CARDS=8
+
+#
+# HiSax supported cards
+#
+CONFIG_HISAX_16_3=y
+CONFIG_HISAX_TELESPCI=y
+CONFIG_HISAX_S0BOX=y
+CONFIG_HISAX_FRITZPCI=y
+CONFIG_HISAX_AVM_A1_PCMCIA=y
+CONFIG_HISAX_ELSA=y
+CONFIG_HISAX_DIEHLDIVA=y
+CONFIG_HISAX_SEDLBAUER=y
+CONFIG_HISAX_NETJET=y
+CONFIG_HISAX_NETJET_U=y
+CONFIG_HISAX_NICCY=y
+CONFIG_HISAX_BKM_A4T=y
+CONFIG_HISAX_SCT_QUADRO=y
+CONFIG_HISAX_GAZEL=y
+CONFIG_HISAX_HFC_PCI=y
+CONFIG_HISAX_W6692=y
+CONFIG_HISAX_HFC_SX=y
+CONFIG_HISAX_ENTERNOW_PCI=y
+# CONFIG_HISAX_DEBUG is not set
+
+#
+# HiSax PCMCIA card service modules
+#
+CONFIG_HISAX_SEDLBAUER_CS=m
+CONFIG_HISAX_ELSA_CS=m
+CONFIG_HISAX_AVM_A1_CS=m
+CONFIG_HISAX_TELES_CS=m
+
+#
+# HiSax sub driver modules
+#
+CONFIG_HISAX_ST5481=m
+# CONFIG_HISAX_HFCUSB is not set
+CONFIG_HISAX_HFC4S8S=m
+CONFIG_HISAX_FRITZ_PCIPNP=m
+CONFIG_HISAX_HDLC=y
+
+#
+# Active cards
+#
+
+#
+# Siemens Gigaset
+#
+CONFIG_ISDN_DRV_GIGASET=m
+CONFIG_GIGASET_BASE=m
+CONFIG_GIGASET_M105=m
+# CONFIG_GIGASET_DEBUG is not set
+# CONFIG_GIGASET_UNDOCREQ is not set
+
+#
+# CAPI subsystem
+#
+CONFIG_ISDN_CAPI=m
+CONFIG_ISDN_DRV_AVMB1_VERBOSE_REASON=y
+CONFIG_ISDN_CAPI_MIDDLEWARE=y
+CONFIG_ISDN_CAPI_CAPI20=m
+CONFIG_ISDN_CAPI_CAPIFS_BOOL=y
+CONFIG_ISDN_CAPI_CAPIFS=m
+CONFIG_ISDN_CAPI_CAPIDRV=m
+
+#
+# CAPI hardware drivers
+#
+
+#
+# Active AVM cards
+#
+CONFIG_CAPI_AVM=y
+CONFIG_ISDN_DRV_AVMB1_B1PCI=m
+CONFIG_ISDN_DRV_AVMB1_B1PCIV4=y
+CONFIG_ISDN_DRV_AVMB1_B1PCMCIA=m
+CONFIG_ISDN_DRV_AVMB1_AVM_CS=m
+CONFIG_ISDN_DRV_AVMB1_T1PCI=m
+CONFIG_ISDN_DRV_AVMB1_C4=m
+
+#
+# Active Eicon DIVA Server cards
+#
+# CONFIG_CAPI_EICON is not set
+
+#
+# Telephony Support
+#
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+
+#
+# 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=m
+# CONFIG_INPUT_TSDEV is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+CONFIG_KEYBOARD_ATKBD=y
+# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_KEYBOARD_LKKBD is not set
+# CONFIG_KEYBOARD_XTKBD is not set
+# CONFIG_KEYBOARD_NEWTON is not set
+CONFIG_INPUT_MOUSE=y
+CONFIG_MOUSE_PS2=y
+CONFIG_MOUSE_SERIAL=m
+CONFIG_MOUSE_VSXXXAA=m
+CONFIG_INPUT_JOYSTICK=y
+CONFIG_JOYSTICK_ANALOG=m
+CONFIG_JOYSTICK_A3D=m
+CONFIG_JOYSTICK_ADI=m
+CONFIG_JOYSTICK_COBRA=m
+CONFIG_JOYSTICK_GF2K=m
+CONFIG_JOYSTICK_GRIP=m
+CONFIG_JOYSTICK_GRIP_MP=m
+CONFIG_JOYSTICK_GUILLEMOT=m
+CONFIG_JOYSTICK_INTERACT=m
+CONFIG_JOYSTICK_SIDEWINDER=m
+CONFIG_JOYSTICK_TMDC=m
+CONFIG_JOYSTICK_IFORCE=m
+CONFIG_JOYSTICK_IFORCE_USB=y
+CONFIG_JOYSTICK_IFORCE_232=y
+CONFIG_JOYSTICK_WARRIOR=m
+CONFIG_JOYSTICK_MAGELLAN=m
+CONFIG_JOYSTICK_SPACEORB=m
+CONFIG_JOYSTICK_SPACEBALL=m
+CONFIG_JOYSTICK_STINGER=m
+CONFIG_JOYSTICK_TWIDJOY=m
+CONFIG_JOYSTICK_DB9=m
+CONFIG_JOYSTICK_GAMECON=m
+CONFIG_JOYSTICK_TURBOGRAFX=m
+CONFIG_JOYSTICK_JOYDUMP=m
+CONFIG_INPUT_TOUCHSCREEN=y
+CONFIG_TOUCHSCREEN_GUNZE=m
+CONFIG_TOUCHSCREEN_ELO=m
+CONFIG_TOUCHSCREEN_MTOUCH=m
+CONFIG_TOUCHSCREEN_MK712=m
+CONFIG_INPUT_MISC=y
+CONFIG_INPUT_UINPUT=m
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+CONFIG_SERIO_I8042=y
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_PARKBD is not set
+# CONFIG_SERIO_PCIPS2 is not set
+CONFIG_SERIO_LIBPS2=y
+CONFIG_SERIO_RAW=m
+CONFIG_GAMEPORT=m
+CONFIG_GAMEPORT_NS558=m
+CONFIG_GAMEPORT_L4=m
+CONFIG_GAMEPORT_EMU10K1=m
+CONFIG_GAMEPORT_FM801=m
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+CONFIG_VT_HW_CONSOLE_BINDING=y
+CONFIG_SERIAL_NONSTANDARD=y
+# CONFIG_COMPUTONE is not set
+# CONFIG_ROCKETPORT is not set
+CONFIG_CYCLADES=m
+# CONFIG_CYZ_INTR is not set
+# CONFIG_DIGIEPCA is not set
+# CONFIG_MOXA_INTELLIO is not set
+# CONFIG_MOXA_SMARTIO is not set
+# CONFIG_ISI is not set
+CONFIG_SYNCLINKMP=m
+CONFIG_SYNCLINK_GT=m
+CONFIG_N_HDLC=m
+# CONFIG_SPECIALIX is not set
+# CONFIG_SX is not set
+# CONFIG_RIO is not set
+# CONFIG_STALDRV is not set
+
+#
+# Serial drivers
+#
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_CORE=m
+CONFIG_SERIAL_JSM=m
+CONFIG_UNIX98_PTYS=y
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_CRASH is not set
+CONFIG_PRINTER=m
+CONFIG_LP_CONSOLE=y
+CONFIG_PPDEV=m
+CONFIG_TIPAR=m
+
+#
+# IPMI
+#
+CONFIG_IPMI_HANDLER=m
+# CONFIG_IPMI_PANIC_EVENT is not set
+CONFIG_IPMI_DEVICE_INTERFACE=m
+CONFIG_IPMI_SI=m
+CONFIG_IPMI_WATCHDOG=m
+CONFIG_IPMI_POWEROFF=m
+
+#
+# Watchdog Cards
+#
+CONFIG_WATCHDOG=y
+# CONFIG_WATCHDOG_NOWAYOUT is not set
+
+#
+# Watchdog Device Drivers
+#
+CONFIG_SOFT_WATCHDOG=m
+CONFIG_I8XX_TCO=m
+
+#
+# PCI-based Watchdog Cards
+#
+CONFIG_PCIPCWATCHDOG=m
+CONFIG_WDTPCI=m
+CONFIG_WDT_501_PCI=y
+
+#
+# USB-based Watchdog Cards
+#
+CONFIG_USBPCWATCHDOG=m
+# CONFIG_HW_RANDOM is not set
+CONFIG_EFI_RTC=y
+CONFIG_DTLK=m
+CONFIG_R3964=m
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+CONFIG_AGP=y
+CONFIG_AGP_SIS=y
+CONFIG_AGP_VIA=y
+CONFIG_AGP_I460=y
+CONFIG_DRM=m
+CONFIG_DRM_TDFX=m
+CONFIG_DRM_R128=m
+CONFIG_DRM_RADEON=m
+CONFIG_DRM_MGA=m
+CONFIG_DRM_SIS=m
+CONFIG_DRM_VIA=m
+CONFIG_DRM_SAVAGE=m
+
+#
+# PCMCIA character devices
+#
+# CONFIG_SYNCLINK_CS is not set
+CONFIG_CARDMAN_4000=m
+CONFIG_CARDMAN_4040=m
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_HPET is not set
+CONFIG_HANGCHECK_TIMER=m
+
+#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+# CONFIG_TELCLOCK is not set
+
+#
+# I2C support
+#
+CONFIG_I2C=m
+CONFIG_I2C_CHARDEV=m
+
+#
+# I2C Algorithms
+#
+CONFIG_I2C_ALGOBIT=m
+CONFIG_I2C_ALGOPCF=m
+CONFIG_I2C_ALGOPCA=m
+
+#
+# I2C Hardware Bus support
+#
+# CONFIG_I2C_ALI1535 is not set
+# CONFIG_I2C_ALI1563 is not set
+# CONFIG_I2C_ALI15X3 is not set
+# CONFIG_I2C_AMD756 is not set
+# CONFIG_I2C_AMD8111 is not set
+# CONFIG_I2C_I801 is not set
+# CONFIG_I2C_I810 is not set
+# CONFIG_I2C_PIIX4 is not set
+CONFIG_I2C_ISA=m
+CONFIG_I2C_NFORCE2=m
+# CONFIG_I2C_OCORES is not set
+CONFIG_I2C_PARPORT=m
+CONFIG_I2C_PARPORT_LIGHT=m
+CONFIG_I2C_PROSAVAGE=m
+CONFIG_I2C_SAVAGE4=m
+# CONFIG_I2C_SIS5595 is not set
+# CONFIG_I2C_SIS630 is not set
+# CONFIG_I2C_SIS96X is not set
+CONFIG_I2C_STUB=m
+# CONFIG_I2C_VIA is not set
+# CONFIG_I2C_VIAPRO is not set
+CONFIG_I2C_VOODOO3=m
+CONFIG_I2C_PCA_ISA=m
+
+#
+# Miscellaneous I2C Chip support
+#
+CONFIG_SENSORS_DS1337=m
+CONFIG_SENSORS_DS1374=m
+CONFIG_SENSORS_EEPROM=m
+CONFIG_SENSORS_PCF8574=m
+CONFIG_SENSORS_PCA9539=m
+CONFIG_SENSORS_PCF8591=m
+CONFIG_SENSORS_MAX6875=m
+# 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 is not set
+# CONFIG_SPI_MASTER is not set
+
+#
+# Dallas's 1-wire bus
+#
+CONFIG_W1=m
+CONFIG_W1_CON=y
+
+#
+# 1-wire Bus Masters
+#
+CONFIG_W1_MASTER_MATROX=m
+CONFIG_W1_MASTER_DS2490=m
+CONFIG_W1_MASTER_DS2482=m
+
+#
+# 1-wire Slaves
+#
+CONFIG_W1_SLAVE_THERM=m
+CONFIG_W1_SLAVE_SMEM=m
+CONFIG_W1_SLAVE_DS2433=m
+CONFIG_W1_SLAVE_DS2433_CRC=y
+
+#
+# Hardware Monitoring support
+#
+CONFIG_HWMON=m
+CONFIG_HWMON_VID=m
+CONFIG_SENSORS_ABITUGURU=m
+CONFIG_SENSORS_ADM1021=m
+CONFIG_SENSORS_ADM1025=m
+CONFIG_SENSORS_ADM1026=m
+CONFIG_SENSORS_ADM1031=m
+CONFIG_SENSORS_ADM9240=m
+CONFIG_SENSORS_ASB100=m
+CONFIG_SENSORS_ATXP1=m
+CONFIG_SENSORS_DS1621=m
+CONFIG_SENSORS_F71805F=m
+CONFIG_SENSORS_FSCHER=m
+CONFIG_SENSORS_FSCPOS=m
+CONFIG_SENSORS_GL518SM=m
+CONFIG_SENSORS_GL520SM=m
+CONFIG_SENSORS_IT87=m
+CONFIG_SENSORS_LM63=m
+CONFIG_SENSORS_LM75=m
+CONFIG_SENSORS_LM77=m
+CONFIG_SENSORS_LM78=m
+CONFIG_SENSORS_LM80=m
+CONFIG_SENSORS_LM83=m
+CONFIG_SENSORS_LM85=m
+CONFIG_SENSORS_LM87=m
+CONFIG_SENSORS_LM90=m
+CONFIG_SENSORS_LM92=m
+CONFIG_SENSORS_MAX1619=m
+CONFIG_SENSORS_PC87360=m
+CONFIG_SENSORS_SIS5595=m
+CONFIG_SENSORS_SMSC47M1=m
+CONFIG_SENSORS_SMSC47M192=m
+CONFIG_SENSORS_SMSC47B397=m
+CONFIG_SENSORS_VIA686A=m
+CONFIG_SENSORS_VT8231=m
+CONFIG_SENSORS_W83781D=m
+CONFIG_SENSORS_W83791D=m
+CONFIG_SENSORS_W83792D=m
+CONFIG_SENSORS_W83L785TS=m
+CONFIG_SENSORS_W83627HF=m
+CONFIG_SENSORS_W83627EHF=m
+# CONFIG_HWMON_DEBUG_CHIP is not set
+
+#
+# Misc devices
+#
+
+#
+# Multimedia devices
+#
+CONFIG_VIDEO_DEV=m
+CONFIG_VIDEO_V4L1=y
+CONFIG_VIDEO_V4L1_COMPAT=y
+CONFIG_VIDEO_V4L2=y
+
+#
+# Video Capture Adapters
+#
+
+#
+# Video Capture Adapters
+#
+# CONFIG_VIDEO_ADV_DEBUG is not set
+# CONFIG_VIDEO_VIVI is not set
+CONFIG_VIDEO_BT848=m
+CONFIG_VIDEO_BT848_DVB=y
+CONFIG_VIDEO_SAA6588=m
+CONFIG_VIDEO_BWQCAM=m
+CONFIG_VIDEO_CQCAM=m
+CONFIG_VIDEO_W9966=m
+CONFIG_VIDEO_CPIA=m
+CONFIG_VIDEO_CPIA_PP=m
+CONFIG_VIDEO_CPIA_USB=m
+CONFIG_VIDEO_CPIA2=m
+CONFIG_VIDEO_SAA5246A=m
+CONFIG_VIDEO_SAA5249=m
+CONFIG_TUNER_3036=m
+CONFIG_VIDEO_STRADIS=m
+CONFIG_VIDEO_ZORAN=m
+CONFIG_VIDEO_ZORAN_BUZ=m
+CONFIG_VIDEO_ZORAN_DC10=m
+CONFIG_VIDEO_ZORAN_DC30=m
+CONFIG_VIDEO_ZORAN_LML33=m
+CONFIG_VIDEO_ZORAN_LML33R10=m
+CONFIG_VIDEO_ZORAN_AVS6EYES=m
+CONFIG_VIDEO_SAA7134=m
+CONFIG_VIDEO_SAA7134_ALSA=m
+CONFIG_VIDEO_SAA7134_DVB=m
+CONFIG_VIDEO_SAA7134_DVB_ALL_FRONTENDS=y
+CONFIG_VIDEO_MXB=m
+CONFIG_VIDEO_DPC=m
+CONFIG_VIDEO_HEXIUM_ORION=m
+CONFIG_VIDEO_HEXIUM_GEMINI=m
+CONFIG_VIDEO_CX88_VP3054=m
+CONFIG_VIDEO_CX88=m
+CONFIG_VIDEO_CX88_ALSA=m
+CONFIG_VIDEO_CX88_BLACKBIRD=m
+CONFIG_VIDEO_CX88_DVB=m
+CONFIG_VIDEO_CX88_DVB_ALL_FRONTENDS=y
+
+#
+# Encoders and Decoders
+#
+CONFIG_VIDEO_MSP3400=m
+CONFIG_VIDEO_CS53L32A=m
+CONFIG_VIDEO_TLV320AIC23B=m
+CONFIG_VIDEO_WM8775=m
+CONFIG_VIDEO_WM8739=m
+CONFIG_VIDEO_CX2341X=m
+CONFIG_VIDEO_CX25840=m
+CONFIG_VIDEO_SAA711X=m
+CONFIG_VIDEO_SAA7127=m
+CONFIG_VIDEO_UPD64031A=m
+CONFIG_VIDEO_UPD64083=m
+
+#
+# V4L USB devices
+#
+CONFIG_VIDEO_PVRUSB2=m
+CONFIG_VIDEO_PVRUSB2_24XXX=y
+CONFIG_VIDEO_PVRUSB2_SYSFS=y
+# CONFIG_VIDEO_PVRUSB2_DEBUGIFC is not set
+CONFIG_VIDEO_EM28XX=m
+CONFIG_VIDEO_USBVIDEO=m
+CONFIG_USB_VICAM=m
+CONFIG_USB_IBMCAM=m
+CONFIG_USB_KONICAWC=m
+CONFIG_USB_QUICKCAM_MESSENGER=m
+CONFIG_USB_ET61X251=m
+CONFIG_VIDEO_OVCAMCHIP=m
+CONFIG_USB_W9968CF=m
+CONFIG_USB_OV511=m
+CONFIG_USB_SE401=m
+CONFIG_USB_SN9C102=m
+CONFIG_USB_STV680=m
+CONFIG_USB_ZC0301=m
+CONFIG_USB_PWC=m
+# CONFIG_USB_PWC_DEBUG is not set
+
+#
+# Radio Adapters
+#
+CONFIG_RADIO_GEMTEK_PCI=m
+CONFIG_RADIO_MAXIRADIO=m
+CONFIG_RADIO_MAESTRO=m
+CONFIG_USB_DSBR=m
+
+#
+# Digital Video Broadcasting Devices
+#
+CONFIG_DVB=y
+CONFIG_DVB_CORE=m
+
+#
+# Supported SAA7146 based PCI Adapters
+#
+CONFIG_DVB_AV7110=m
+CONFIG_DVB_AV7110_OSD=y
+CONFIG_DVB_BUDGET=m
+CONFIG_DVB_BUDGET_CI=m
+CONFIG_DVB_BUDGET_AV=m
+CONFIG_DVB_BUDGET_PATCH=m
+
+#
+# Supported USB Adapters
+#
+CONFIG_DVB_USB=m
+# CONFIG_DVB_USB_DEBUG is not set
+CONFIG_DVB_USB_A800=m
+CONFIG_DVB_USB_DIBUSB_MB=m
+# CONFIG_DVB_USB_DIBUSB_MB_FAULTY is not set
+CONFIG_DVB_USB_DIBUSB_MC=m
+CONFIG_DVB_USB_UMT_010=m
+CONFIG_DVB_USB_CXUSB=m
+CONFIG_DVB_USB_DIGITV=m
+CONFIG_DVB_USB_VP7045=m
+CONFIG_DVB_USB_VP702X=m
+CONFIG_DVB_USB_GP8PSK=m
+CONFIG_DVB_USB_NOVA_T_USB2=m
+CONFIG_DVB_USB_DTT200U=m
+CONFIG_DVB_TTUSB_BUDGET=m
+CONFIG_DVB_TTUSB_DEC=m
+CONFIG_DVB_CINERGYT2=m
+CONFIG_DVB_CINERGYT2_TUNING=y
+CONFIG_DVB_CINERGYT2_STREAM_URB_COUNT=32
+CONFIG_DVB_CINERGYT2_STREAM_BUF_SIZE=512
+CONFIG_DVB_CINERGYT2_QUERY_INTERVAL=250
+CONFIG_DVB_CINERGYT2_ENABLE_RC_INPUT_DEVICE=y
+CONFIG_DVB_CINERGYT2_RC_QUERY_INTERVAL=100
+
+#
+# Supported FlexCopII (B2C2) Adapters
+#
+CONFIG_DVB_B2C2_FLEXCOP=m
+CONFIG_DVB_B2C2_FLEXCOP_PCI=m
+CONFIG_DVB_B2C2_FLEXCOP_USB=m
+# CONFIG_DVB_B2C2_FLEXCOP_DEBUG is not set
+
+#
+# Supported BT878 Adapters
+#
+CONFIG_DVB_BT8XX=m
+
+#
+# Supported Pluto2 Adapters
+#
+CONFIG_DVB_PLUTO2=m
+
+#
+# Supported DVB Frontends
+#
+
+#
+# Customise DVB Frontends
+#
+
+#
+# DVB-S (satellite) frontends
+#
+CONFIG_DVB_STV0299=m
+CONFIG_DVB_CX24110=m
+CONFIG_DVB_CX24123=m
+CONFIG_DVB_TDA8083=m
+CONFIG_DVB_MT312=m
+CONFIG_DVB_VES1X93=m
+CONFIG_DVB_S5H1420=m
+
+#
+# DVB-T (terrestrial) frontends
+#
+CONFIG_DVB_SP8870=m
+CONFIG_DVB_SP887X=m
+CONFIG_DVB_CX22700=m
+CONFIG_DVB_CX22702=m
+CONFIG_DVB_L64781=m
+CONFIG_DVB_TDA1004X=m
+CONFIG_DVB_NXT6000=m
+CONFIG_DVB_MT352=m
+CONFIG_DVB_ZL10353=m
+CONFIG_DVB_DIB3000MB=m
+CONFIG_DVB_DIB3000MC=m
+
+#
+# DVB-C (cable) frontends
+#
+CONFIG_DVB_VES1820=m
+CONFIG_DVB_TDA10021=m
+CONFIG_DVB_STV0297=m
+
+#
+# ATSC (North American/Korean Terrestrial/Cable DTV) frontends
+#
+CONFIG_DVB_NXT200X=m
+CONFIG_DVB_OR51211=m
+CONFIG_DVB_OR51132=m
+CONFIG_DVB_BCM3510=m
+CONFIG_DVB_LGDT330X=m
+
+#
+# Miscellaneous devices
+#
+CONFIG_DVB_PLL=m
+CONFIG_DVB_LNBP21=m
+CONFIG_DVB_ISL6421=m
+CONFIG_VIDEO_SAA7146=m
+CONFIG_VIDEO_SAA7146_VV=m
+CONFIG_VIDEO_VIDEOBUF=m
+CONFIG_VIDEO_TUNER=m
+CONFIG_VIDEO_BUF=m
+CONFIG_VIDEO_BUF_DVB=m
+CONFIG_VIDEO_BTCX=m
+CONFIG_VIDEO_IR=m
+CONFIG_VIDEO_TVEEPROM=m
+CONFIG_USB_DABUSB=m
+
+#
+# Graphics support
+#
+# CONFIG_FIRMWARE_EDID is not set
+CONFIG_FB=y
+CONFIG_FB_CFB_FILLRECT=y
+CONFIG_FB_CFB_COPYAREA=y
+CONFIG_FB_CFB_IMAGEBLIT=y
+# CONFIG_FB_MACMODES is not set
+# CONFIG_FB_BACKLIGHT is not set
+CONFIG_FB_MODE_HELPERS=y
+CONFIG_FB_TILEBLITTING=y
+CONFIG_FB_CIRRUS=m
+# CONFIG_FB_PM2 is not set
+# CONFIG_FB_CYBER2000 is not set
+# CONFIG_FB_ASILIANT is not set
+# CONFIG_FB_IMSTT is not set
+# CONFIG_FB_S1D13XXX is not set
+CONFIG_FB_NVIDIA=m
+CONFIG_FB_NVIDIA_I2C=y
+CONFIG_FB_RIVA=m
+# CONFIG_FB_RIVA_I2C is not set
+# CONFIG_FB_RIVA_DEBUG is not set
+CONFIG_FB_MATROX=m
+CONFIG_FB_MATROX_MILLENIUM=y
+CONFIG_FB_MATROX_MYSTIQUE=y
+CONFIG_FB_MATROX_G=y
+CONFIG_FB_MATROX_I2C=m
+CONFIG_FB_MATROX_MAVEN=m
+CONFIG_FB_MATROX_MULTIHEAD=y
+CONFIG_FB_RADEON=m
+CONFIG_FB_RADEON_I2C=y
+# CONFIG_FB_RADEON_DEBUG is not set
+CONFIG_FB_ATY128=m
+CONFIG_FB_ATY=m
+CONFIG_FB_ATY_CT=y
+CONFIG_FB_ATY_GENERIC_LCD=y
+CONFIG_FB_ATY_GX=y
+CONFIG_FB_SAVAGE=m
+CONFIG_FB_SAVAGE_I2C=y
+CONFIG_FB_SAVAGE_ACCEL=y
+# CONFIG_FB_SIS is not set
+# CONFIG_FB_NEOMAGIC is not set
+CONFIG_FB_KYRO=m
+CONFIG_FB_3DFX=m
+CONFIG_FB_3DFX_ACCEL=y
+CONFIG_FB_VOODOO1=m
+CONFIG_FB_TRIDENT=m
+CONFIG_FB_TRIDENT_ACCEL=y
+# CONFIG_FB_VIRTUAL is not set
+
+#
+# Console display driver support
+#
+CONFIG_VGA_CONSOLE=y
+CONFIG_VGACON_SOFT_SCROLLBACK=y
+CONFIG_VGACON_SOFT_SCROLLBACK_SIZE=64
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y
+# CONFIG_FONTS is not set
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
+
+#
+# Logo configuration
+#
+CONFIG_LOGO=y
+# CONFIG_LOGO_LINUX_MONO is not set
+# CONFIG_LOGO_LINUX_VGA16 is not set
+CONFIG_LOGO_LINUX_CLUT224=y
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+CONFIG_BACKLIGHT_CLASS_DEVICE=m
+CONFIG_BACKLIGHT_DEVICE=y
+CONFIG_LCD_CLASS_DEVICE=m
+CONFIG_LCD_DEVICE=y
+
+#
+# Sound
+#
+CONFIG_SOUND=m
+
+#
+# Advanced Linux Sound Architecture
+#
+CONFIG_SND=m
+CONFIG_SND_TIMER=m
+CONFIG_SND_PCM=m
+CONFIG_SND_HWDEP=m
+CONFIG_SND_RAWMIDI=m
+CONFIG_SND_SEQUENCER=m
+CONFIG_SND_SEQ_DUMMY=m
+CONFIG_SND_OSSEMUL=y
+CONFIG_SND_MIXER_OSS=m
+CONFIG_SND_PCM_OSS=m
+CONFIG_SND_PCM_OSS_PLUGINS=y
+CONFIG_SND_SEQUENCER_OSS=y
+CONFIG_SND_DYNAMIC_MINORS=y
+# CONFIG_SND_SUPPORT_OLD_API is not set
+CONFIG_SND_VERBOSE_PROCFS=y
+# CONFIG_SND_VERBOSE_PRINTK is not set
+# CONFIG_SND_DEBUG is not set
+
+#
+# Generic devices
+#
+CONFIG_SND_MPU401_UART=m
+CONFIG_SND_OPL3_LIB=m
+CONFIG_SND_VX_LIB=m
+CONFIG_SND_AC97_CODEC=m
+CONFIG_SND_AC97_BUS=m
+CONFIG_SND_DUMMY=m
+CONFIG_SND_VIRMIDI=m
+CONFIG_SND_MTPAV=m
+# CONFIG_SND_SERIAL_U16550 is not set
+CONFIG_SND_MPU401=m
+
+#
+# PCI devices
+#
+CONFIG_SND_AD1889=m
+CONFIG_SND_ALS300=m
+CONFIG_SND_ALI5451=m
+CONFIG_SND_ATIIXP=m
+CONFIG_SND_ATIIXP_MODEM=m
+CONFIG_SND_AU8810=m
+CONFIG_SND_AU8820=m
+CONFIG_SND_AU8830=m
+CONFIG_SND_AZT3328=m
+CONFIG_SND_BT87X=m
+# CONFIG_SND_BT87X_OVERCLOCK is not set
+CONFIG_SND_CA0106=m
+CONFIG_SND_CMIPCI=m
+CONFIG_SND_CS4281=m
+CONFIG_SND_CS46XX=m
+CONFIG_SND_CS46XX_NEW_DSP=y
+CONFIG_SND_DARLA20=m
+CONFIG_SND_GINA20=m
+CONFIG_SND_LAYLA20=m
+CONFIG_SND_DARLA24=m
+CONFIG_SND_GINA24=m
+CONFIG_SND_LAYLA24=m
+CONFIG_SND_MONA=m
+CONFIG_SND_MIA=m
+CONFIG_SND_ECHO3G=m
+CONFIG_SND_INDIGO=m
+CONFIG_SND_INDIGOIO=m
+CONFIG_SND_INDIGODJ=m
+CONFIG_SND_EMU10K1=m
+CONFIG_SND_EMU10K1X=m
+CONFIG_SND_ENS1370=m
+CONFIG_SND_ENS1371=m
+CONFIG_SND_ES1938=m
+CONFIG_SND_ES1968=m
+CONFIG_SND_FM801=m
+CONFIG_SND_FM801_TEA575X_BOOL=y
+CONFIG_SND_FM801_TEA575X=m
+CONFIG_SND_HDA_INTEL=m
+CONFIG_SND_HDSP=m
+CONFIG_SND_HDSPM=m
+CONFIG_SND_ICE1712=m
+CONFIG_SND_ICE1724=m
+CONFIG_SND_INTEL8X0=m
+CONFIG_SND_INTEL8X0M=m
+CONFIG_SND_KORG1212=m
+CONFIG_SND_MAESTRO3=m
+CONFIG_SND_MIXART=m
+CONFIG_SND_NM256=m
+CONFIG_SND_PCXHR=m
+CONFIG_SND_RIPTIDE=m
+CONFIG_SND_RME32=m
+CONFIG_SND_RME96=m
+CONFIG_SND_RME9652=m
+CONFIG_SND_SONICVIBES=m
+CONFIG_SND_TRIDENT=m
+CONFIG_SND_VIA82XX=m
+CONFIG_SND_VIA82XX_MODEM=m
+CONFIG_SND_VX222=m
+CONFIG_SND_YMFPCI=m
+
+#
+# USB devices
+#
+CONFIG_SND_USB_AUDIO=m
+
+#
+# PCMCIA devices
+#
+# CONFIG_SND_VXPOCKET is not set
+# CONFIG_SND_PDAUDIOCF is not set
+
+#
+# Open Sound System
+#
+# CONFIG_SOUND_PRIME is not set
+
+#
+# USB support
+#
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB_ARCH_HAS_EHCI=y
+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_SUSPEND is not set
+# CONFIG_USB_OTG is not set
+
+#
+# USB Host Controller Drivers
+#
+CONFIG_USB_EHCI_HCD=m
+CONFIG_USB_EHCI_SPLIT_ISO=y
+CONFIG_USB_EHCI_ROOT_HUB_TT=y
+CONFIG_USB_EHCI_TT_NEWSCHED=y
+CONFIG_USB_ISP116X_HCD=m
+CONFIG_USB_OHCI_HCD=m
+# CONFIG_USB_OHCI_BIG_ENDIAN is not set
+CONFIG_USB_OHCI_LITTLE_ENDIAN=y
+CONFIG_USB_UHCI_HCD=m
+CONFIG_USB_SL811_HCD=m
+CONFIG_USB_SL811_CS=m
+
+#
+# USB Device Class drivers
+#
+CONFIG_USB_ACM=m
+CONFIG_USB_PRINTER=m
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+#
+
+#
+# may also be needed; see USB_STORAGE Help for more information
+#
+CONFIG_USB_STORAGE=m
+# CONFIG_USB_STORAGE_DEBUG is not set
+CONFIG_USB_STORAGE_DATAFAB=y
+CONFIG_USB_STORAGE_FREECOM=y
+CONFIG_USB_STORAGE_ISD200=y
+CONFIG_USB_STORAGE_DPCM=y
+CONFIG_USB_STORAGE_USBAT=y
+CONFIG_USB_STORAGE_SDDR09=y
+CONFIG_USB_STORAGE_SDDR55=y
+CONFIG_USB_STORAGE_JUMPSHOT=y
+CONFIG_USB_STORAGE_ALAUDA=y
+CONFIG_USB_LIBUSUAL=y
+
+#
+# USB Input Devices
+#
+CONFIG_USB_HID=y
+CONFIG_USB_HIDINPUT=y
+# CONFIG_USB_HIDINPUT_POWERBOOK is not set
+CONFIG_HID_FF=y
+CONFIG_HID_PID=y
+CONFIG_LOGITECH_FF=y
+CONFIG_THRUSTMASTER_FF=y
+CONFIG_USB_HIDDEV=y
+CONFIG_USB_AIPTEK=m
+CONFIG_USB_WACOM=m
+CONFIG_USB_ACECAD=m
+CONFIG_USB_KBTAB=m
+CONFIG_USB_POWERMATE=m
+CONFIG_USB_TOUCHSCREEN=m
+CONFIG_USB_TOUCHSCREEN_EGALAX=y
+CONFIG_USB_TOUCHSCREEN_PANJIT=y
+CONFIG_USB_TOUCHSCREEN_3M=y
+CONFIG_USB_TOUCHSCREEN_ITM=y
+# CONFIG_USB_YEALINK is not set
+CONFIG_USB_XPAD=m
+CONFIG_USB_ATI_REMOTE=m
+CONFIG_USB_ATI_REMOTE2=m
+CONFIG_USB_KEYSPAN_REMOTE=m
+CONFIG_USB_APPLETOUCH=m
+
+#
+# USB Imaging devices
+#
+CONFIG_USB_MDC800=m
+CONFIG_USB_MICROTEK=m
+
+#
+# USB Network Adapters
+#
+CONFIG_USB_CATC=m
+CONFIG_USB_KAWETH=m
+CONFIG_USB_PEGASUS=m
+CONFIG_USB_RTL8150=m
+CONFIG_USB_USBNET=m
+CONFIG_USB_NET_AX8817X=m
+CONFIG_USB_NET_CDCETHER=m
+CONFIG_USB_NET_GL620A=m
+CONFIG_USB_NET_NET1080=m
+CONFIG_USB_NET_PLUSB=m
+CONFIG_USB_NET_RNDIS_HOST=m
+CONFIG_USB_NET_CDC_SUBSET=m
+CONFIG_USB_ALI_M5632=y
+CONFIG_USB_AN2720=y
+CONFIG_USB_BELKIN=y
+CONFIG_USB_ARMLINUX=y
+CONFIG_USB_EPSON2888=y
+CONFIG_USB_NET_ZAURUS=m
+CONFIG_USB_MON=y
+
+#
+# USB port drivers
+#
+CONFIG_USB_USS720=m
+
+#
+# USB Serial Converter support
+#
+CONFIG_USB_SERIAL=m
+CONFIG_USB_SERIAL_GENERIC=y
+CONFIG_USB_SERIAL_AIRPRIME=m
+CONFIG_USB_SERIAL_ARK3116=m
+CONFIG_USB_SERIAL_BELKIN=m
+CONFIG_USB_SERIAL_WHITEHEAT=m
+CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m
+CONFIG_USB_SERIAL_CP2101=m
+CONFIG_USB_SERIAL_CYPRESS_M8=m
+CONFIG_USB_SERIAL_EMPEG=m
+CONFIG_USB_SERIAL_FTDI_SIO=m
+CONFIG_USB_SERIAL_FUNSOFT=m
+CONFIG_USB_SERIAL_VISOR=m
+CONFIG_USB_SERIAL_IPAQ=m
+CONFIG_USB_SERIAL_IR=m
+CONFIG_USB_SERIAL_EDGEPORT=m
+CONFIG_USB_SERIAL_EDGEPORT_TI=m
+CONFIG_USB_SERIAL_GARMIN=m
+CONFIG_USB_SERIAL_IPW=m
+CONFIG_USB_SERIAL_KEYSPAN_PDA=m
+CONFIG_USB_SERIAL_KEYSPAN=m
+CONFIG_USB_SERIAL_KEYSPAN_MPR=y
+CONFIG_USB_SERIAL_KEYSPAN_USA28=y
+CONFIG_USB_SERIAL_KEYSPAN_USA28X=y
+CONFIG_USB_SERIAL_KEYSPAN_USA28XA=y
+CONFIG_USB_SERIAL_KEYSPAN_USA28XB=y
+CONFIG_USB_SERIAL_KEYSPAN_USA19=y
+CONFIG_USB_SERIAL_KEYSPAN_USA18X=y
+CONFIG_USB_SERIAL_KEYSPAN_USA19W=y
+CONFIG_USB_SERIAL_KEYSPAN_USA19QW=y
+CONFIG_USB_SERIAL_KEYSPAN_USA19QI=y
+CONFIG_USB_SERIAL_KEYSPAN_USA49W=y
+CONFIG_USB_SERIAL_KEYSPAN_USA49WLC=y
+CONFIG_USB_SERIAL_KLSI=m
+CONFIG_USB_SERIAL_KOBIL_SCT=m
+CONFIG_USB_SERIAL_MCT_U232=m
+CONFIG_USB_SERIAL_NAVMAN=m
+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=m
+CONFIG_USB_SERIAL_TI=m
+CONFIG_USB_SERIAL_CYBERJACK=m
+CONFIG_USB_SERIAL_XIRCOM=m
+CONFIG_USB_SERIAL_OPTION=m
+CONFIG_USB_SERIAL_OMNINET=m
+CONFIG_USB_EZUSB=y
+
+#
+# USB Miscellaneous drivers
+#
+CONFIG_USB_EMI62=m
+CONFIG_USB_EMI26=m
+CONFIG_USB_AUERSWALD=m
+CONFIG_USB_RIO500=m
+CONFIG_USB_LEGOTOWER=m
+CONFIG_USB_LCD=m
+CONFIG_USB_LED=m
+# CONFIG_USB_CYPRESS_CY7C63 is not set
+# CONFIG_USB_CYTHERM is not set
+CONFIG_USB_PHIDGETKIT=m
+CONFIG_USB_PHIDGETSERVO=m
+CONFIG_USB_IDMOUSE=m
+CONFIG_USB_APPLEDISPLAY=m
+CONFIG_USB_SISUSBVGA=m
+CONFIG_USB_SISUSBVGA_CON=y
+CONFIG_USB_LD=m
+CONFIG_USB_TEST=m
+
+#
+# USB DSL modem support
+#
+CONFIG_USB_ATM=m
+CONFIG_USB_SPEEDTOUCH=m
+CONFIG_USB_CXACRU=m
+CONFIG_USB_UEAGLEATM=m
+CONFIG_USB_XUSBATM=m
+
+#
+# USB Gadget Support
+#
+# CONFIG_USB_GADGET is not set
+
+#
+# MMC/SD Card support
+#
+CONFIG_MMC=m
+# CONFIG_MMC_DEBUG is not set
+CONFIG_MMC_BLOCK=m
+CONFIG_MMC_SDHCI=m
+
+#
+# LED devices
+#
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+
+#
+# LED drivers
+#
+
+#
+# LED Triggers
+#
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_LEDS_TRIGGER_TIMER=m
+CONFIG_LEDS_TRIGGER_IDE_DISK=y
+CONFIG_LEDS_TRIGGER_HEARTBEAT=m
+
+#
+# InfiniBand support
+#
+CONFIG_INFINIBAND=m
+CONFIG_INFINIBAND_USER_MAD=m
+CONFIG_INFINIBAND_USER_ACCESS=m
+CONFIG_INFINIBAND_ADDR_TRANS=y
+CONFIG_INFINIBAND_MTHCA=m
+CONFIG_INFINIBAND_MTHCA_DEBUG=y
+CONFIG_INFINIBAND_IPOIB=m
+CONFIG_INFINIBAND_IPOIB_DEBUG=y
+CONFIG_INFINIBAND_IPOIB_DEBUG_DATA=y
+CONFIG_INFINIBAND_SRP=m
+CONFIG_INFINIBAND_ISER=m
+
+#
+# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
+#
+
+#
+# Real Time Clock
+#
+CONFIG_RTC_LIB=m
+CONFIG_RTC_CLASS=m
+
+#
+# RTC interfaces
+#
+CONFIG_RTC_INTF_SYSFS=m
+CONFIG_RTC_INTF_PROC=m
+CONFIG_RTC_INTF_DEV=m
+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
+
+#
+# RTC drivers
+#
+CONFIG_RTC_DRV_X1205=m
+CONFIG_RTC_DRV_DS1307=m
+CONFIG_RTC_DRV_DS1553=m
+CONFIG_RTC_DRV_ISL1208=m
+CONFIG_RTC_DRV_DS1672=m
+CONFIG_RTC_DRV_DS1742=m
+CONFIG_RTC_DRV_PCF8563=m
+CONFIG_RTC_DRV_PCF8583=m
+CONFIG_RTC_DRV_RS5C372=m
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_TEST is not set
+CONFIG_RTC_DRV_V3020=m
+
+#
+# DMA Engine support
+#
+CONFIG_DMA_ENGINE=y
+
+#
+# DMA Clients
+#
+CONFIG_NET_DMA=y
+
+#
+# DMA Devices
+#
+CONFIG_INTEL_IOATDMA=m
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+CONFIG_EXT2_FS_POSIX_ACL=y
+CONFIG_EXT2_FS_SECURITY=y
+CONFIG_EXT2_FS_XIP=y
+CONFIG_FS_XIP=y
+CONFIG_EXT3_FS=m
+CONFIG_EXT3_FS_XATTR=y
+CONFIG_EXT3_FS_POSIX_ACL=y
+CONFIG_EXT3_FS_SECURITY=y
+CONFIG_JBD=m
+# CONFIG_JBD_DEBUG is not set
+CONFIG_FS_MBCACHE=y
+CONFIG_REISERFS_FS=m
+# CONFIG_REISERFS_CHECK is not set
+CONFIG_REISERFS_PROC_INFO=y
+CONFIG_REISERFS_FS_XATTR=y
+CONFIG_REISERFS_FS_POSIX_ACL=y
+CONFIG_REISERFS_FS_SECURITY=y
+CONFIG_JFS_FS=m
+CONFIG_JFS_POSIX_ACL=y
+CONFIG_JFS_SECURITY=y
+# CONFIG_JFS_DEBUG is not set
+# CONFIG_JFS_STATISTICS is not set
+CONFIG_FS_POSIX_ACL=y
+CONFIG_XFS_FS=m
+CONFIG_XFS_QUOTA=y
+CONFIG_XFS_SECURITY=y
+CONFIG_XFS_POSIX_ACL=y
+# CONFIG_XFS_RT is not set
+CONFIG_OCFS2_FS=m
+# CONFIG_OCFS2_DEBUG_MASKLOG is not set
+CONFIG_MINIX_FS=m
+CONFIG_ROMFS_FS=m
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+CONFIG_QUOTA=y
+# CONFIG_QFMT_V1 is not set
+CONFIG_QFMT_V2=y
+CONFIG_QUOTACTL=y
+CONFIG_DNOTIFY=y
+CONFIG_AUTOFS_FS=m
+CONFIG_AUTOFS4_FS=m
+CONFIG_FUSE_FS=m
+
+#
+# Caches
+#
+CONFIG_FSCACHE=m
+
+#
+# CD-ROM/DVD Filesystems
+#
+CONFIG_ISO9660_FS=y
+CONFIG_JOLIET=y
+CONFIG_ZISOFS=y
+CONFIG_ZISOFS_FS=y
+CONFIG_UDF_FS=m
+CONFIG_UDF_NLS=y
+CONFIG_CACHEFILES=m
+CONFIG_CACHEFILES_DEBUG=y
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=m
+CONFIG_MSDOS_FS=m
+CONFIG_VFAT_FS=m
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="ascii"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_RAMFS=y
+CONFIG_CONFIGFS_FS=m
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+CONFIG_AFFS_FS=m
+CONFIG_HFS_FS=m
+CONFIG_HFSPLUS_FS=m
+CONFIG_BEFS_FS=m
+# CONFIG_BEFS_DEBUG is not set
+CONFIG_BFS_FS=m
+CONFIG_EFS_FS=m
+CONFIG_CRAMFS=m
+CONFIG_SQUASHFS=m
+# CONFIG_SQUASHFS_EMBEDDED is not set
+CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3
+# CONFIG_SQUASHFS_VMALLOC is not set
+CONFIG_VXFS_FS=m
+# CONFIG_HPFS_FS is not set
+CONFIG_QNX4FS_FS=m
+CONFIG_SYSV_FS=m
+CONFIG_UFS_FS=m
+# CONFIG_UFS_FS_WRITE is not set
+# CONFIG_UFS_DEBUG is not set
+
+#
+# Network File Systems
+#
+CONFIG_NFS_FS=m
+CONFIG_NFS_V3=y
+CONFIG_NFS_V3_ACL=y
+CONFIG_NFS_V4=y
+CONFIG_NFS_FSCACHE=y
+CONFIG_NFS_DIRECTIO=y
+CONFIG_NFSD=m
+CONFIG_NFSD_V2_ACL=y
+CONFIG_NFSD_V3=y
+CONFIG_NFSD_V3_ACL=y
+CONFIG_NFSD_V4=y
+CONFIG_NFSD_TCP=y
+CONFIG_LOCKD=m
+CONFIG_LOCKD_V4=y
+CONFIG_EXPORTFS=m
+CONFIG_NFS_ACL_SUPPORT=m
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=m
+CONFIG_SUNRPC_GSS=m
+CONFIG_RPCSEC_GSS_KRB5=m
+CONFIG_RPCSEC_GSS_SPKM3=m
+# CONFIG_SMB_FS is not set
+CONFIG_CIFS=m
+# CONFIG_CIFS_STATS is not set
+CONFIG_CIFS_WEAK_PW_HASH=y
+CONFIG_CIFS_XATTR=y
+CONFIG_CIFS_POSIX=y
+# CONFIG_CIFS_DEBUG2 is not set
+# CONFIG_CIFS_EXPERIMENTAL is not set
+CONFIG_NCP_FS=m
+CONFIG_NCPFS_PACKET_SIGNING=y
+CONFIG_NCPFS_IOCTL_LOCKING=y
+CONFIG_NCPFS_STRONG=y
+CONFIG_NCPFS_NFS_NS=y
+CONFIG_NCPFS_OS2_NS=y
+CONFIG_NCPFS_SMALLDOS=y
+CONFIG_NCPFS_NLS=y
+CONFIG_NCPFS_EXTRAS=y
+CONFIG_CODA_FS=m
+# CONFIG_CODA_FS_OLD_API is not set
+# CONFIG_AFS_FS is not set
+CONFIG_9P_FS=m
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+CONFIG_OSF_PARTITION=y
+CONFIG_AMIGA_PARTITION=y
+# CONFIG_ATARI_PARTITION is not set
+CONFIG_MAC_PARTITION=y
+CONFIG_MSDOS_PARTITION=y
+CONFIG_BSD_DISKLABEL=y
+CONFIG_MINIX_SUBPARTITION=y
+CONFIG_SOLARIS_X86_PARTITION=y
+CONFIG_UNIXWARE_DISKLABEL=y
+# CONFIG_LDM_PARTITION is not set
+CONFIG_SGI_PARTITION=y
+# CONFIG_ULTRIX_PARTITION is not set
+CONFIG_SUN_PARTITION=y
+CONFIG_KARMA_PARTITION=y
+CONFIG_EFI_PARTITION=y
+
+#
+# Native Language Support
+#
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="utf8"
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_CODEPAGE_737=m
+CONFIG_NLS_CODEPAGE_775=m
+CONFIG_NLS_CODEPAGE_850=m
+CONFIG_NLS_CODEPAGE_852=m
+CONFIG_NLS_CODEPAGE_855=m
+CONFIG_NLS_CODEPAGE_857=m
+CONFIG_NLS_CODEPAGE_860=m
+CONFIG_NLS_CODEPAGE_861=m
+CONFIG_NLS_CODEPAGE_862=m
+CONFIG_NLS_CODEPAGE_863=m
+CONFIG_NLS_CODEPAGE_864=m
+CONFIG_NLS_CODEPAGE_865=m
+CONFIG_NLS_CODEPAGE_866=m
+CONFIG_NLS_CODEPAGE_869=m
+CONFIG_NLS_CODEPAGE_936=m
+CONFIG_NLS_CODEPAGE_950=m
+CONFIG_NLS_CODEPAGE_932=m
+CONFIG_NLS_CODEPAGE_949=m
+CONFIG_NLS_CODEPAGE_874=m
+CONFIG_NLS_ISO8859_8=m
+CONFIG_NLS_CODEPAGE_1250=m
+CONFIG_NLS_CODEPAGE_1251=m
+CONFIG_NLS_ASCII=y
+CONFIG_NLS_ISO8859_1=m
+CONFIG_NLS_ISO8859_2=m
+CONFIG_NLS_ISO8859_3=m
+CONFIG_NLS_ISO8859_4=m
+CONFIG_NLS_ISO8859_5=m
+CONFIG_NLS_ISO8859_6=m
+CONFIG_NLS_ISO8859_7=m
+CONFIG_NLS_ISO8859_9=m
+CONFIG_NLS_ISO8859_13=m
+CONFIG_NLS_ISO8859_14=m
+CONFIG_NLS_ISO8859_15=m
+CONFIG_NLS_KOI8_R=m
+CONFIG_NLS_KOI8_U=m
+CONFIG_NLS_UTF8=m
+
+#
+# Library routines
+#
+CONFIG_CRC_CCITT=m
+CONFIG_CRC16=m
+CONFIG_CRC32=y
+CONFIG_LIBCRC32C=m
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=m
+CONFIG_TEXTSEARCH=y
+CONFIG_TEXTSEARCH_KMP=m
+CONFIG_TEXTSEARCH_BM=m
+CONFIG_TEXTSEARCH_FSM=m
+CONFIG_PLIST=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_GENERIC_PENDING_IRQ=y
+CONFIG_IRQ_PER_CPU=y
+
+#
+# Instrumentation Support
+#
+CONFIG_PROFILING=y
+CONFIG_OPROFILE=m
+CONFIG_KPROBES=y
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_UNUSED_SYMBOLS is not set
+CONFIG_DEBUG_KERNEL=y
+CONFIG_LOG_BUF_SHIFT=17
+CONFIG_DETECT_SOFTLOCKUP=y
+CONFIG_SCHEDSTATS=y
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
+CONFIG_DEBUG_SPINLOCK=y
+# CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_RWSEMS is not set
+CONFIG_DEBUG_SPINLOCK_SLEEP=y
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+# CONFIG_DEBUG_KOBJECT is not set
+CONFIG_DEBUG_INFO=y
+CONFIG_DEBUG_FS=y
+# CONFIG_DEBUG_VM is not set
+CONFIG_DEBUG_LIST=y
+# CONFIG_FORCED_INLINING is not set
+CONFIG_BOOT_DELAY=y
+# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_IA64_GRANULE_16MB is not set
+CONFIG_IA64_GRANULE_64MB=y
+# CONFIG_IA64_PRINT_HAZARDS is not set
+# CONFIG_DISABLE_VHPT is not set
+# CONFIG_IA64_DEBUG_CMPXCHG is not set
+# CONFIG_IA64_DEBUG_IRQ is not set
+
+#
+# Security options
+#
+CONFIG_KEYS=y
+CONFIG_KEYS_DEBUG_PROC_KEYS=y
+CONFIG_SECURITY=y
+CONFIG_SECURITY_NETWORK=y
+# CONFIG_SECURITY_NETWORK_XFRM is not set
+CONFIG_SECURITY_CAPABILITIES=y
+# CONFIG_SECURITY_ROOTPLUG is not set
+# CONFIG_SECURITY_SECLVL is not set
+CONFIG_SECURITY_SELINUX=y
+CONFIG_SECURITY_SELINUX_BOOTPARAM=y
+CONFIG_SECURITY_SELINUX_BOOTPARAM_VALUE=1
+CONFIG_SECURITY_SELINUX_DISABLE=y
+CONFIG_SECURITY_SELINUX_DEVELOP=y
+CONFIG_SECURITY_SELINUX_AVC_STATS=y
+CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE=1
+# CONFIG_SECURITY_SELINUX_ENABLE_SECMARK_DEFAULT is not set
+# CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX is not set
+
+#
+# Cryptographic options
+#
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_NULL=m
+CONFIG_CRYPTO_MD4=m
+CONFIG_CRYPTO_MD5=m
+CONFIG_CRYPTO_SHA1=y
+CONFIG_CRYPTO_SHA256=m
+CONFIG_CRYPTO_SHA512=m
+CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_TGR192=m
+CONFIG_CRYPTO_DES=m
+CONFIG_CRYPTO_BLOWFISH=m
+CONFIG_CRYPTO_TWOFISH=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_TEST is not set
+CONFIG_CRYPTO_SIGNATURE=y
+CONFIG_CRYPTO_SIGNATURE_DSA=y
+CONFIG_CRYPTO_MPILIB=y
+
+#
+# Hardware crypto devices
+#
+# CONFIG_XEN_UTIL is not set
+CONFIG_HAVE_ARCH_ALLOC_SKB=y
+CONFIG_HAVE_ARCH_DEV_ALLOC_SKB=y
+CONFIG_XEN_BALLOON=y
+CONFIG_XEN_SKBUFF=y
+# CONFIG_XEN_DEVMEM is not set
+CONFIG_XEN_REBOOT=y
+# CONFIG_XEN_SMPBOOT is not set
+CONFIG_XEN_INTERFACE_VERSION=0x00030203
+
+#
+# XEN
+#
+CONFIG_XEN_PRIVILEGED_GUEST=y
+# CONFIG_XEN_UNPRIVILEGED_GUEST is not set
+CONFIG_XEN_PRIVCMD=y
+CONFIG_XEN_XENBUS_DEV=y
+CONFIG_XEN_BACKEND=y
+CONFIG_XEN_BLKDEV_BACKEND=m
+# CONFIG_XEN_BLKDEV_TAP is not set
+CONFIG_XEN_NETDEV_BACKEND=m
+# CONFIG_XEN_NETDEV_PIPELINED_TRANSMITTER is not set
+CONFIG_XEN_NETDEV_LOOPBACK=m
+# CONFIG_XEN_PCIDEV_BACKEND is not set
+# CONFIG_XEN_TPMDEV_BACKEND is not set
+CONFIG_XEN_BLKDEV_FRONTEND=m
+CONFIG_XEN_NETDEV_FRONTEND=m
+CONFIG_XEN_FRAMEBUFFER=y
+CONFIG_XEN_KEYBOARD=y
+CONFIG_XEN_SCRUB_PAGES=y
+CONFIG_XEN_DISABLE_SERIAL=y
+CONFIG_XEN_SYSFS=y
+CONFIG_XEN_COMPAT_030002_AND_LATER=y
+# CONFIG_XEN_COMPAT_LATEST_ONLY is not set
+CONFIG_XEN_COMPAT_030002=y
+CONFIG_HAVE_IRQ_IGNORE_UNHANDLED=y
+CONFIG_NO_IDLE_HZ=y
diff --git a/configs/kernel-2.6.18-ia64.config b/configs/kernel-2.6.18-ia64.config
new file mode 100644
index 000000000..e6c8653c4
--- /dev/null
+++ b/configs/kernel-2.6.18-ia64.config
@@ -0,0 +1,2902 @@
+# ia64
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.18.2-rc1
+# Mon Nov 13 09:44:41 2006
+#
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_BSD_PROCESS_ACCT=y
+# CONFIG_BSD_PROCESS_ACCT_V3 is not set
+CONFIG_TASKSTATS=y
+CONFIG_TASK_DELAY_ACCT=y
+CONFIG_AUDIT=y
+CONFIG_AUDITSYSCALL=y
+# CONFIG_IKCONFIG is not set
+CONFIG_CPUSETS=y
+CONFIG_RELAY=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+# CONFIG_EMBEDDED is not set
+CONFIG_SYSCTL=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
+CONFIG_KALLSYMS_EXTRA_PASS=y
+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=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+CONFIG_MODULE_SIG=y
+# CONFIG_MODULE_SIG_FORCE is not set
+CONFIG_KMOD=y
+CONFIG_STOP_MACHINE=y
+
+#
+# Process debugging support
+#
+CONFIG_UTRACE=y
+CONFIG_PTRACE=y
+
+#
+# Block layer
+#
+CONFIG_BLK_DEV_IO_TRACE=y
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_DEFAULT_AS is not set
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+
+#
+# Processor type and features
+#
+CONFIG_IA64=y
+CONFIG_64BIT=y
+CONFIG_MMU=y
+CONFIG_SWIOTLB=y
+CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_TIME_INTERPOLATION=y
+CONFIG_DMI=y
+CONFIG_EFI=y
+CONFIG_GENERIC_IOMAP=y
+# CONFIG_XEN is not set
+CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
+CONFIG_IA64_UNCACHED_ALLOCATOR=y
+CONFIG_DMA_IS_DMA32=y
+CONFIG_AUDIT_ARCH=y
+CONFIG_IA64_GENERIC=y
+# CONFIG_IA64_DIG is not set
+# CONFIG_IA64_HP_ZX1 is not set
+# CONFIG_IA64_HP_ZX1_SWIOTLB is not set
+# CONFIG_IA64_SGI_SN2 is not set
+# CONFIG_IA64_HP_SIM is not set
+# CONFIG_ITANIUM is not set
+CONFIG_MCKINLEY=y
+# CONFIG_IA64_PAGE_SIZE_4KB is not set
+# CONFIG_IA64_PAGE_SIZE_8KB is not set
+CONFIG_IA64_PAGE_SIZE_16KB=y
+# CONFIG_IA64_PAGE_SIZE_64KB is not set
+CONFIG_PGTABLE_3=y
+# CONFIG_PGTABLE_4 is not set
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
+CONFIG_IA64_L1_CACHE_SHIFT=7
+CONFIG_IA64_CYCLONE=y
+CONFIG_IOSAPIC=y
+CONFIG_IA64_SGI_SN_XP=y
+CONFIG_FORCE_MAX_ZONEORDER=17
+CONFIG_SMP=y
+CONFIG_NR_CPUS=1024
+CONFIG_HOTPLUG_CPU=y
+CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
+CONFIG_SCHED_SMT=y
+# CONFIG_PERMIT_BSP_REMOVE is not set
+# CONFIG_PREEMPT is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+# CONFIG_FLATMEM_MANUAL is not set
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+CONFIG_SPARSEMEM_MANUAL=y
+CONFIG_SPARSEMEM=y
+CONFIG_NEED_MULTIPLE_NODES=y
+CONFIG_HAVE_MEMORY_PRESENT=y
+# CONFIG_SPARSEMEM_STATIC is not set
+CONFIG_SPARSEMEM_EXTREME=y
+CONFIG_MEMORY_HOTPLUG=y
+CONFIG_SPLIT_PTLOCK_CPUS=4
+CONFIG_MIGRATION=y
+CONFIG_RESOURCES_64BIT=y
+CONFIG_ARCH_SELECT_MEMORY_MODEL=y
+CONFIG_ARCH_DISCONTIGMEM_ENABLE=y
+CONFIG_ARCH_FLATMEM_ENABLE=y
+CONFIG_ARCH_SPARSEMEM_ENABLE=y
+CONFIG_ARCH_DISCONTIGMEM_DEFAULT=y
+CONFIG_NUMA=y
+CONFIG_NODES_SHIFT=8
+CONFIG_HAVE_ARCH_EARLY_PFN_TO_NID=y
+CONFIG_HAVE_ARCH_NODEDATA_EXTENSION=y
+# CONFIG_IA32_SUPPORT is not set
+CONFIG_IA64_MCA_RECOVERY=m
+CONFIG_PERFMON=y
+CONFIG_IA64_PALINFO=y
+CONFIG_SGI_SN=y
+
+#
+# SN Devices
+#
+CONFIG_SGI_IOC4=y
+CONFIG_SGI_IOC3=m
+
+#
+# Firmware Drivers
+#
+CONFIG_EFI_VARS=y
+CONFIG_EFI_PCDP=y
+CONFIG_BINFMT_ELF=y
+CONFIG_BINFMT_MISC=y
+
+#
+# Power management and ACPI
+#
+CONFIG_PM=y
+CONFIG_PM_LEGACY=y
+# CONFIG_PM_DEBUG is not set
+
+#
+# ACPI (Advanced Configuration and Power Interface) Support
+#
+CONFIG_ACPI=y
+CONFIG_ACPI_BUTTON=m
+CONFIG_ACPI_FAN=y
+# CONFIG_ACPI_DOCK is not set
+CONFIG_ACPI_PROCESSOR=y
+CONFIG_ACPI_HOTPLUG_CPU=y
+CONFIG_ACPI_THERMAL=y
+CONFIG_ACPI_NUMA=y
+CONFIG_ACPI_BLACKLIST_YEAR=0
+# CONFIG_ACPI_DEBUG is not set
+CONFIG_ACPI_EC=y
+CONFIG_ACPI_POWER=y
+CONFIG_ACPI_SYSTEM=y
+CONFIG_ACPI_CONTAINER=y
+CONFIG_ACPI_HOTPLUG_MEMORY=y
+
+#
+# CPU Frequency scaling
+#
+CONFIG_CPU_FREQ=y
+CONFIG_CPU_FREQ_TABLE=m
+CONFIG_CPU_FREQ_DEBUG=y
+CONFIG_CPU_FREQ_STAT=m
+CONFIG_CPU_FREQ_STAT_DETAILS=y
+# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set
+CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE=y
+CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
+CONFIG_CPU_FREQ_GOV_POWERSAVE=m
+CONFIG_CPU_FREQ_GOV_USERSPACE=y
+CONFIG_CPU_FREQ_GOV_ONDEMAND=m
+CONFIG_CPU_FREQ_GOV_CONSERVATIVE=m
+
+#
+# CPUFreq processor drivers
+#
+CONFIG_IA64_ACPI_CPUFREQ=m
+
+#
+# Bus options (PCI, PCMCIA)
+#
+CONFIG_PCI=y
+CONFIG_PCI_DOMAINS=y
+CONFIG_PCIEPORTBUS=y
+# CONFIG_HOTPLUG_PCI_PCIE is not set
+CONFIG_PCI_MSI=y
+# CONFIG_PCI_DEBUG is not set
+
+#
+# PCI Hotplug Support
+#
+CONFIG_HOTPLUG_PCI=y
+CONFIG_HOTPLUG_PCI_FAKE=m
+CONFIG_HOTPLUG_PCI_ACPI=m
+CONFIG_HOTPLUG_PCI_ACPI_IBM=m
+# CONFIG_HOTPLUG_PCI_CPCI is not set
+CONFIG_HOTPLUG_PCI_SHPC=m
+CONFIG_HOTPLUG_PCI_SHPC_POLL_EVENT_MODE=y
+CONFIG_HOTPLUG_PCI_SGI=m
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+CONFIG_PCCARD=y
+# CONFIG_PCMCIA_DEBUG is not set
+CONFIG_PCMCIA=y
+CONFIG_PCMCIA_LOAD_CIS=y
+CONFIG_PCMCIA_IOCTL=y
+CONFIG_CARDBUS=y
+
+#
+# PC-card bridges
+#
+CONFIG_YENTA=y
+CONFIG_YENTA_O2=y
+CONFIG_YENTA_RICOH=y
+CONFIG_YENTA_TI=y
+CONFIG_YENTA_ENE_TUNE=y
+CONFIG_YENTA_TOSHIBA=y
+CONFIG_PD6729=m
+CONFIG_I82092=m
+CONFIG_PCCARD_NONSTATIC=y
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+# CONFIG_NETDEBUG is not set
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=y
+CONFIG_NET_KEY=m
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_ASK_IP_FIB_HASH=y
+# 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
+# CONFIG_IP_PNP is not set
+CONFIG_NET_IPIP=m
+CONFIG_NET_IPGRE=m
+CONFIG_NET_IPGRE_BROADCAST=y
+CONFIG_IP_MROUTE=y
+CONFIG_IP_PIMSM_V1=y
+CONFIG_IP_PIMSM_V2=y
+# CONFIG_ARPD is not set
+CONFIG_SYN_COOKIES=y
+CONFIG_INET_AH=m
+CONFIG_INET_ESP=m
+CONFIG_INET_IPCOMP=m
+CONFIG_INET_XFRM_TUNNEL=m
+CONFIG_INET_TUNNEL=m
+CONFIG_INET_XFRM_MODE_TRANSPORT=m
+CONFIG_INET_XFRM_MODE_TUNNEL=m
+CONFIG_INET_DIAG=m
+CONFIG_INET_TCP_DIAG=m
+CONFIG_TCP_CONG_ADVANCED=y
+
+#
+# TCP congestion control
+#
+CONFIG_TCP_CONG_BIC=y
+CONFIG_TCP_CONG_CUBIC=m
+CONFIG_TCP_CONG_WESTWOOD=m
+CONFIG_TCP_CONG_HTCP=m
+CONFIG_TCP_CONG_HSTCP=m
+CONFIG_TCP_CONG_HYBLA=m
+CONFIG_TCP_CONG_VEGAS=m
+CONFIG_TCP_CONG_SCALABLE=m
+CONFIG_TCP_CONG_LP=m
+CONFIG_TCP_CONG_VENO=m
+
+#
+# IP: Virtual Server Configuration
+#
+CONFIG_IP_VS=m
+# CONFIG_IP_VS_DEBUG is not set
+CONFIG_IP_VS_TAB_BITS=12
+
+#
+# IPVS transport protocol load balancing support
+#
+CONFIG_IP_VS_PROTO_TCP=y
+CONFIG_IP_VS_PROTO_UDP=y
+CONFIG_IP_VS_PROTO_ESP=y
+CONFIG_IP_VS_PROTO_AH=y
+
+#
+# IPVS scheduler
+#
+CONFIG_IP_VS_RR=m
+CONFIG_IP_VS_WRR=m
+CONFIG_IP_VS_LC=m
+CONFIG_IP_VS_WLC=m
+CONFIG_IP_VS_LBLC=m
+CONFIG_IP_VS_LBLCR=m
+CONFIG_IP_VS_DH=m
+CONFIG_IP_VS_SH=m
+CONFIG_IP_VS_SED=m
+CONFIG_IP_VS_NQ=m
+
+#
+# IPVS application helper
+#
+CONFIG_IP_VS_FTP=m
+CONFIG_IPV6=m
+CONFIG_IPV6_PRIVACY=y
+CONFIG_IPV6_ROUTER_PREF=y
+CONFIG_IPV6_ROUTE_INFO=y
+CONFIG_INET6_AH=m
+CONFIG_INET6_ESP=m
+CONFIG_INET6_IPCOMP=m
+CONFIG_INET6_XFRM_TUNNEL=m
+CONFIG_INET6_TUNNEL=m
+CONFIG_INET6_XFRM_MODE_TRANSPORT=m
+CONFIG_INET6_XFRM_MODE_TUNNEL=m
+CONFIG_IPV6_TUNNEL=m
+CONFIG_NETWORK_SECMARK=y
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_DEBUG is not set
+CONFIG_BRIDGE_NETFILTER=y
+
+#
+# Core Netfilter Configuration
+#
+CONFIG_NETFILTER_NETLINK=m
+CONFIG_NETFILTER_NETLINK_QUEUE=m
+CONFIG_NETFILTER_NETLINK_LOG=m
+CONFIG_NETFILTER_XTABLES=m
+CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
+CONFIG_NETFILTER_XT_TARGET_CONNMARK=m
+CONFIG_NETFILTER_XT_TARGET_MARK=m
+CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
+CONFIG_NETFILTER_XT_TARGET_NOTRACK=m
+CONFIG_NETFILTER_XT_TARGET_SECMARK=m
+CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=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_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_PHYSDEV=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
+
+#
+# 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=m
+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_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_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_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
+CONFIG_IP_NF_ARPTABLES=m
+CONFIG_IP_NF_ARPFILTER=m
+CONFIG_IP_NF_ARP_MANGLE=m
+
+#
+# IPv6: Netfilter Configuration (EXPERIMENTAL)
+#
+CONFIG_IP6_NF_QUEUE=m
+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_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
+
+#
+# DECnet: Netfilter Configuration
+#
+# CONFIG_DECNET_NF_GRABULATOR is not set
+
+#
+# Bridge: Netfilter Configuration
+#
+CONFIG_BRIDGE_NF_EBTABLES=m
+CONFIG_BRIDGE_EBT_BROUTE=m
+CONFIG_BRIDGE_EBT_T_FILTER=m
+CONFIG_BRIDGE_EBT_T_NAT=m
+CONFIG_BRIDGE_EBT_802_3=m
+CONFIG_BRIDGE_EBT_AMONG=m
+CONFIG_BRIDGE_EBT_ARP=m
+CONFIG_BRIDGE_EBT_IP=m
+CONFIG_BRIDGE_EBT_LIMIT=m
+CONFIG_BRIDGE_EBT_MARK=m
+CONFIG_BRIDGE_EBT_PKTTYPE=m
+CONFIG_BRIDGE_EBT_STP=m
+CONFIG_BRIDGE_EBT_VLAN=m
+CONFIG_BRIDGE_EBT_ARPREPLY=m
+CONFIG_BRIDGE_EBT_DNAT=m
+CONFIG_BRIDGE_EBT_MARK_T=m
+CONFIG_BRIDGE_EBT_REDIRECT=m
+CONFIG_BRIDGE_EBT_SNAT=m
+CONFIG_BRIDGE_EBT_LOG=m
+CONFIG_BRIDGE_EBT_ULOG=m
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+CONFIG_IP_DCCP=m
+CONFIG_INET_DCCP_DIAG=m
+CONFIG_IP_DCCP_ACKVEC=y
+
+#
+# DCCP CCIDs Configuration (EXPERIMENTAL)
+#
+CONFIG_IP_DCCP_CCID2=m
+CONFIG_IP_DCCP_CCID3=m
+CONFIG_IP_DCCP_TFRC_LIB=m
+
+#
+# DCCP Kernel Hacking
+#
+# CONFIG_IP_DCCP_DEBUG is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+CONFIG_IP_SCTP=m
+# CONFIG_SCTP_DBG_MSG is not set
+# CONFIG_SCTP_DBG_OBJCNT is not set
+# CONFIG_SCTP_HMAC_NONE is not set
+# CONFIG_SCTP_HMAC_SHA1 is not set
+CONFIG_SCTP_HMAC_MD5=y
+
+#
+# TIPC Configuration (EXPERIMENTAL)
+#
+CONFIG_TIPC=m
+# CONFIG_TIPC_ADVANCED is not set
+# CONFIG_TIPC_DEBUG is not set
+CONFIG_ATM=m
+CONFIG_ATM_CLIP=m
+# CONFIG_ATM_CLIP_NO_ICMP is not set
+CONFIG_ATM_LANE=m
+# CONFIG_ATM_MPOA is not set
+CONFIG_ATM_BR2684=m
+# CONFIG_ATM_BR2684_IPFILTER is not set
+CONFIG_BRIDGE=m
+CONFIG_VLAN_8021Q=m
+CONFIG_DECNET=m
+CONFIG_DECNET_ROUTER=y
+CONFIG_DECNET_ROUTE_FWMARK=y
+CONFIG_LLC=y
+# CONFIG_LLC2 is not set
+CONFIG_IPX=m
+# CONFIG_IPX_INTERN is not set
+CONFIG_ATALK=m
+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_ECONET is not set
+CONFIG_WAN_ROUTER=m
+
+#
+# QoS and/or fair queueing
+#
+CONFIG_NET_SCHED=y
+# CONFIG_NET_SCH_CLK_JIFFIES is not set
+CONFIG_NET_SCH_CLK_GETTIMEOFDAY=y
+# CONFIG_NET_SCH_CLK_CPU is not set
+
+#
+# Queueing/Scheduling
+#
+CONFIG_NET_SCH_CBQ=m
+CONFIG_NET_SCH_HTB=m
+CONFIG_NET_SCH_HFSC=m
+CONFIG_NET_SCH_ATM=m
+CONFIG_NET_SCH_PRIO=m
+CONFIG_NET_SCH_RED=m
+CONFIG_NET_SCH_SFQ=m
+CONFIG_NET_SCH_TEQL=m
+CONFIG_NET_SCH_TBF=m
+CONFIG_NET_SCH_GRED=m
+CONFIG_NET_SCH_DSMARK=m
+CONFIG_NET_SCH_NETEM=m
+CONFIG_NET_SCH_INGRESS=m
+
+#
+# Classification
+#
+CONFIG_NET_CLS=y
+CONFIG_NET_CLS_BASIC=m
+CONFIG_NET_CLS_TCINDEX=m
+CONFIG_NET_CLS_ROUTE4=m
+CONFIG_NET_CLS_ROUTE=y
+CONFIG_NET_CLS_FW=m
+CONFIG_NET_CLS_U32=m
+CONFIG_CLS_U32_PERF=y
+CONFIG_CLS_U32_MARK=y
+CONFIG_NET_CLS_RSVP=m
+CONFIG_NET_CLS_RSVP6=m
+CONFIG_NET_EMATCH=y
+CONFIG_NET_EMATCH_STACK=32
+CONFIG_NET_EMATCH_CMP=m
+CONFIG_NET_EMATCH_NBYTE=m
+CONFIG_NET_EMATCH_U32=m
+CONFIG_NET_EMATCH_META=m
+CONFIG_NET_EMATCH_TEXT=m
+CONFIG_NET_CLS_ACT=y
+CONFIG_NET_ACT_POLICE=m
+CONFIG_NET_ACT_GACT=m
+CONFIG_GACT_PROB=y
+CONFIG_NET_ACT_MIRRED=m
+CONFIG_NET_ACT_IPT=m
+CONFIG_NET_ACT_PEDIT=m
+CONFIG_NET_ACT_SIMP=m
+CONFIG_NET_CLS_IND=y
+CONFIG_NET_ESTIMATOR=y
+
+#
+# Network testing
+#
+CONFIG_NET_PKTGEN=m
+# CONFIG_NET_TCPPROBE is not set
+# CONFIG_HAMRADIO is not set
+CONFIG_IRDA=m
+
+#
+# IrDA protocols
+#
+CONFIG_IRLAN=m
+CONFIG_IRNET=m
+CONFIG_IRCOMM=m
+# CONFIG_IRDA_ULTRA is not set
+
+#
+# IrDA options
+#
+CONFIG_IRDA_CACHE_LAST_LSAP=y
+CONFIG_IRDA_FAST_RR=y
+# CONFIG_IRDA_DEBUG is not set
+
+#
+# Infrared-port device drivers
+#
+
+#
+# SIR device drivers
+#
+CONFIG_IRTTY_SIR=m
+
+#
+# Dongle support
+#
+CONFIG_DONGLE=y
+CONFIG_ESI_DONGLE=m
+CONFIG_ACTISYS_DONGLE=m
+CONFIG_TEKRAM_DONGLE=m
+CONFIG_TOIM3232_DONGLE=m
+CONFIG_LITELINK_DONGLE=m
+CONFIG_MA600_DONGLE=m
+CONFIG_GIRBIL_DONGLE=m
+CONFIG_MCP2120_DONGLE=m
+CONFIG_OLD_BELKIN_DONGLE=m
+CONFIG_ACT200L_DONGLE=m
+
+#
+# Old SIR device drivers
+#
+
+#
+# Old Serial dongle support
+#
+
+#
+# FIR device drivers
+#
+CONFIG_USB_IRDA=m
+CONFIG_SIGMATEL_FIR=m
+CONFIG_VLSI_FIR=m
+CONFIG_MCS_FIR=m
+CONFIG_BT=m
+CONFIG_BT_L2CAP=m
+CONFIG_BT_SCO=m
+CONFIG_BT_RFCOMM=m
+CONFIG_BT_RFCOMM_TTY=y
+CONFIG_BT_BNEP=m
+CONFIG_BT_BNEP_MC_FILTER=y
+CONFIG_BT_BNEP_PROTO_FILTER=y
+CONFIG_BT_CMTP=m
+CONFIG_BT_HIDP=m
+
+#
+# Bluetooth device drivers
+#
+CONFIG_BT_HCIUSB=m
+CONFIG_BT_HCIUSB_SCO=y
+CONFIG_BT_HCIUART=m
+CONFIG_BT_HCIUART_H4=y
+CONFIG_BT_HCIUART_BCSP=y
+CONFIG_BT_HCIBCM203X=m
+CONFIG_BT_HCIBPA10X=m
+CONFIG_BT_HCIBFUSB=m
+CONFIG_BT_HCIDTL1=m
+CONFIG_BT_HCIBT3C=m
+CONFIG_BT_HCIBLUECARD=m
+CONFIG_BT_HCIBTUART=m
+CONFIG_BT_HCIVHCI=m
+CONFIG_IEEE80211=m
+CONFIG_IEEE80211_DEBUG=y
+CONFIG_IEEE80211_CRYPT_WEP=m
+CONFIG_IEEE80211_CRYPT_CCMP=m
+CONFIG_IEEE80211_CRYPT_TKIP=m
+CONFIG_IEEE80211_SOFTMAC=m
+CONFIG_IEEE80211_SOFTMAC_DEBUG=y
+CONFIG_TUX=m
+
+#
+# TUX options
+#
+CONFIG_TUX_EXTCGI=y
+CONFIG_TUX_EXTENDED_LOG=y
+# CONFIG_TUX_DEBUG is not set
+CONFIG_WIRELESS_EXT=y
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_SYS_HYPERVISOR is not set
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+CONFIG_CONNECTOR=y
+CONFIG_PROC_EVENTS=y
+
+#
+# Memory Technology Devices (MTD)
+#
+# CONFIG_MTD is not set
+
+#
+# Parallel port support
+#
+CONFIG_PARPORT=m
+CONFIG_PARPORT_PC=m
+CONFIG_PARPORT_SERIAL=m
+# CONFIG_PARPORT_PC_FIFO is not set
+# CONFIG_PARPORT_PC_SUPERIO is not set
+CONFIG_PARPORT_PC_PCMCIA=m
+CONFIG_PARPORT_NOT_PC=y
+# CONFIG_PARPORT_GSC is not set
+# CONFIG_PARPORT_AX88796 is not set
+CONFIG_PARPORT_1284=y
+
+#
+# Plug and Play support
+#
+CONFIG_PNP=y
+# CONFIG_PNP_DEBUG is not set
+
+#
+# Protocols
+#
+CONFIG_PNPACPI=y
+
+#
+# Block devices
+#
+CONFIG_PARIDE=m
+CONFIG_PARIDE_PARPORT=m
+
+#
+# Parallel IDE high-level drivers
+#
+CONFIG_PARIDE_PD=m
+CONFIG_PARIDE_PCD=m
+CONFIG_PARIDE_PF=m
+CONFIG_PARIDE_PT=m
+CONFIG_PARIDE_PG=m
+
+#
+# Parallel IDE protocol modules
+#
+CONFIG_PARIDE_ATEN=m
+CONFIG_PARIDE_BPCK=m
+CONFIG_PARIDE_COMM=m
+CONFIG_PARIDE_DSTR=m
+CONFIG_PARIDE_FIT2=m
+CONFIG_PARIDE_FIT3=m
+CONFIG_PARIDE_EPAT=m
+CONFIG_PARIDE_EPATC8=y
+CONFIG_PARIDE_EPIA=m
+CONFIG_PARIDE_FRIQ=m
+CONFIG_PARIDE_FRPW=m
+CONFIG_PARIDE_KBIC=m
+CONFIG_PARIDE_KTTI=m
+CONFIG_PARIDE_ON20=m
+CONFIG_PARIDE_ON26=m
+CONFIG_BLK_CPQ_DA=m
+CONFIG_BLK_CPQ_CISS_DA=m
+CONFIG_CISS_SCSI_TAPE=y
+CONFIG_BLK_DEV_DAC960=m
+CONFIG_BLK_DEV_UMEM=m
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=m
+CONFIG_BLK_DEV_CRYPTOLOOP=m
+CONFIG_BLK_DEV_NBD=m
+CONFIG_BLK_DEV_SX8=m
+CONFIG_BLK_DEV_UB=m
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=16384
+CONFIG_BLK_DEV_RAM_BLOCKSIZE=4096
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_CDROM_PKTCDVD=m
+CONFIG_CDROM_PKTCDVD_BUFFERS=8
+# CONFIG_CDROM_PKTCDVD_WCACHE is not set
+CONFIG_ATA_OVER_ETH=m
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+CONFIG_IDE=y
+CONFIG_IDE_MAX_HWIFS=4
+CONFIG_BLK_DEV_IDE=y
+
+#
+# Please see Documentation/ide.txt for help/info on IDE drives
+#
+# CONFIG_BLK_DEV_IDE_SATA is not set
+CONFIG_BLK_DEV_IDEDISK=y
+CONFIG_IDEDISK_MULTI_MODE=y
+CONFIG_BLK_DEV_IDECS=m
+CONFIG_BLK_DEV_IDECD=m
+# CONFIG_BLK_DEV_IDETAPE is not set
+CONFIG_BLK_DEV_IDEFLOPPY=y
+CONFIG_BLK_DEV_IDESCSI=m
+CONFIG_IDE_TASK_IOCTL=y
+
+#
+# IDE chipset support/bugfixes
+#
+CONFIG_IDE_GENERIC=y
+CONFIG_BLK_DEV_IDEPNP=y
+CONFIG_BLK_DEV_IDEPCI=y
+CONFIG_IDEPCI_SHARE_IRQ=y
+# CONFIG_BLK_DEV_OFFBOARD is not set
+CONFIG_BLK_DEV_GENERIC=y
+# CONFIG_BLK_DEV_OPTI621 is not set
+CONFIG_BLK_DEV_IDEDMA_PCI=y
+# CONFIG_BLK_DEV_IDEDMA_FORCED is not set
+CONFIG_IDEDMA_PCI_AUTO=y
+# CONFIG_IDEDMA_ONLYDISK is not set
+CONFIG_BLK_DEV_AEC62XX=y
+CONFIG_BLK_DEV_ALI15X3=y
+# CONFIG_WDC_ALI15X3 is not set
+# CONFIG_BLK_DEV_AMD74XX is not set
+CONFIG_BLK_DEV_CMD64X=y
+CONFIG_BLK_DEV_TRIFLEX=y
+# CONFIG_BLK_DEV_CY82C693 is not set
+CONFIG_BLK_DEV_CS5520=y
+CONFIG_BLK_DEV_CS5530=y
+CONFIG_BLK_DEV_HPT34X=y
+# CONFIG_HPT34X_AUTODMA is not set
+CONFIG_BLK_DEV_HPT366=y
+# CONFIG_BLK_DEV_SC1200 is not set
+CONFIG_BLK_DEV_PIIX=y
+CONFIG_BLK_DEV_IT821X=y
+# CONFIG_BLK_DEV_NS87415 is not set
+CONFIG_BLK_DEV_PDC202XX_OLD=y
+# CONFIG_PDC202XX_BURST is not set
+CONFIG_BLK_DEV_PDC202XX_NEW=y
+CONFIG_BLK_DEV_SVWKS=y
+CONFIG_BLK_DEV_SGIIOC4=y
+CONFIG_BLK_DEV_SIIMAGE=y
+# CONFIG_BLK_DEV_SLC90E66 is not set
+# CONFIG_BLK_DEV_TRM290 is not set
+CONFIG_BLK_DEV_VIA82CXXX=y
+# CONFIG_IDE_ARM is not set
+CONFIG_BLK_DEV_IDEDMA=y
+# CONFIG_IDEDMA_IVB is not set
+CONFIG_IDEDMA_AUTO=y
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# SCSI device support
+#
+CONFIG_RAID_ATTRS=m
+CONFIG_SCSI=m
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=m
+CONFIG_CHR_DEV_ST=m
+CONFIG_CHR_DEV_OSST=m
+CONFIG_BLK_DEV_SR=m
+CONFIG_BLK_DEV_SR_VENDOR=y
+CONFIG_CHR_DEV_SG=m
+CONFIG_CHR_DEV_SCH=m
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+CONFIG_SCSI_MULTI_LUN=y
+CONFIG_SCSI_CONSTANTS=y
+CONFIG_SCSI_LOGGING=y
+
+#
+# SCSI Transport Attributes
+#
+CONFIG_SCSI_SPI_ATTRS=m
+CONFIG_SCSI_FC_ATTRS=m
+CONFIG_SCSI_ISCSI_ATTRS=m
+CONFIG_SCSI_SAS_ATTRS=m
+
+#
+# SCSI low-level drivers
+#
+CONFIG_ISCSI_TCP=m
+CONFIG_BLK_DEV_3W_XXXX_RAID=m
+CONFIG_SCSI_3W_9XXX=m
+CONFIG_SCSI_ACARD=m
+CONFIG_SCSI_AACRAID=m
+CONFIG_SCSI_AIC7XXX=m
+CONFIG_AIC7XXX_CMDS_PER_DEVICE=4
+CONFIG_AIC7XXX_RESET_DELAY_MS=15000
+# CONFIG_AIC7XXX_DEBUG_ENABLE is not set
+CONFIG_AIC7XXX_DEBUG_MASK=0
+# CONFIG_AIC7XXX_REG_PRETTY_PRINT is not set
+CONFIG_SCSI_AIC7XXX_OLD=m
+CONFIG_SCSI_AIC79XX=m
+CONFIG_AIC79XX_CMDS_PER_DEVICE=4
+CONFIG_AIC79XX_RESET_DELAY_MS=15000
+# CONFIG_AIC79XX_ENABLE_RD_STRM is not set
+# CONFIG_AIC79XX_DEBUG_ENABLE is not set
+CONFIG_AIC79XX_DEBUG_MASK=0
+# CONFIG_AIC79XX_REG_PRETTY_PRINT is not set
+CONFIG_MEGARAID_NEWGEN=y
+CONFIG_MEGARAID_MM=m
+CONFIG_MEGARAID_MAILBOX=m
+CONFIG_MEGARAID_LEGACY=m
+CONFIG_MEGARAID_SAS=m
+CONFIG_SCSI_SATA=m
+CONFIG_SCSI_SATA_AHCI=m
+CONFIG_SCSI_SATA_SVW=m
+CONFIG_SCSI_ATA_PIIX=m
+CONFIG_SCSI_SATA_MV=m
+CONFIG_SCSI_SATA_NV=m
+CONFIG_SCSI_PDC_ADMA=m
+CONFIG_SCSI_HPTIOP=m
+CONFIG_SCSI_SATA_QSTOR=m
+CONFIG_SCSI_SATA_PROMISE=m
+CONFIG_SCSI_SATA_SX4=m
+CONFIG_SCSI_SATA_SIL=m
+CONFIG_SCSI_SATA_SIL24=m
+CONFIG_SCSI_SATA_SIS=m
+CONFIG_SCSI_SATA_ULI=m
+CONFIG_SCSI_SATA_VIA=m
+CONFIG_SCSI_SATA_VITESSE=m
+CONFIG_SCSI_SATA_INTEL_COMBINED=y
+# CONFIG_SCSI_DMX3191D is not set
+# CONFIG_SCSI_FUTURE_DOMAIN is not set
+CONFIG_SCSI_IPS=m
+CONFIG_SCSI_INITIO=m
+CONFIG_SCSI_INIA100=m
+CONFIG_SCSI_PPA=m
+CONFIG_SCSI_IMM=m
+# CONFIG_SCSI_IZIP_EPP16 is not set
+# CONFIG_SCSI_IZIP_SLOW_CTR is not set
+CONFIG_SCSI_SYM53C8XX_2=m
+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_QLOGIC_1280=m
+CONFIG_SCSI_QLA_FC=m
+CONFIG_SCSI_LPFC=m
+CONFIG_SCSI_DC395x=m
+CONFIG_SCSI_DC390T=m
+# CONFIG_SCSI_DEBUG is not set
+
+#
+# PCMCIA SCSI adapter support
+#
+# CONFIG_PCMCIA_FDOMAIN is not set
+CONFIG_PCMCIA_QLOGIC=m
+CONFIG_PCMCIA_SYM53C500=m
+
+#
+# Multi-device support (RAID and LVM)
+#
+CONFIG_MD=y
+CONFIG_BLK_DEV_MD=y
+CONFIG_MD_LINEAR=m
+CONFIG_MD_RAID0=m
+CONFIG_MD_RAID1=m
+CONFIG_MD_RAID10=m
+CONFIG_MD_RAID456=m
+CONFIG_MD_RAID5_RESHAPE=y
+CONFIG_MD_MULTIPATH=m
+CONFIG_MD_FAULTY=m
+CONFIG_BLK_DEV_DM=m
+CONFIG_DM_CRYPT=m
+CONFIG_DM_SNAPSHOT=m
+CONFIG_DM_MIRROR=m
+CONFIG_DM_ZERO=m
+CONFIG_DM_MULTIPATH=m
+CONFIG_DM_MULTIPATH_EMC=m
+
+#
+# Fusion MPT device support
+#
+CONFIG_FUSION=y
+CONFIG_FUSION_SPI=m
+CONFIG_FUSION_FC=m
+CONFIG_FUSION_SAS=m
+CONFIG_FUSION_MAX_SGE=40
+CONFIG_FUSION_CTL=m
+CONFIG_FUSION_LAN=m
+
+#
+# IEEE 1394 (FireWire) support
+#
+CONFIG_IEEE1394=m
+
+#
+# Subsystem Options
+#
+# CONFIG_IEEE1394_VERBOSEDEBUG is not set
+CONFIG_IEEE1394_OUI_DB=y
+CONFIG_IEEE1394_EXTRA_CONFIG_ROMS=y
+CONFIG_IEEE1394_CONFIG_ROM_IP1394=y
+# CONFIG_IEEE1394_EXPORT_FULL_API is not set
+
+#
+# Device Drivers
+#
+CONFIG_IEEE1394_PCILYNX=m
+CONFIG_IEEE1394_OHCI1394=m
+
+#
+# Protocol Drivers
+#
+CONFIG_IEEE1394_VIDEO1394=m
+CONFIG_IEEE1394_SBP2=m
+CONFIG_IEEE1394_ETH1394=m
+CONFIG_IEEE1394_DV1394=m
+CONFIG_IEEE1394_RAWIO=m
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+CONFIG_IFB=m
+CONFIG_DUMMY=m
+CONFIG_BONDING=m
+CONFIG_EQUALIZER=m
+CONFIG_TUN=m
+CONFIG_NET_SB1000=m
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+
+#
+# PHY device support
+#
+CONFIG_PHYLIB=m
+
+#
+# MII PHY device drivers
+#
+CONFIG_MARVELL_PHY=m
+CONFIG_DAVICOM_PHY=m
+CONFIG_QSEMI_PHY=m
+CONFIG_LXT_PHY=m
+CONFIG_CICADA_PHY=m
+CONFIG_VITESSE_PHY=m
+CONFIG_SMSC_PHY=m
+CONFIG_FIXED_PHY=m
+CONFIG_FIXED_MII_10_FDX=y
+CONFIG_FIXED_MII_100_FDX=y
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=m
+CONFIG_HAPPYMEAL=m
+CONFIG_SUNGEM=m
+CONFIG_CASSINI=m
+CONFIG_NET_VENDOR_3COM=y
+CONFIG_VORTEX=m
+CONFIG_TYPHOON=m
+
+#
+# Tulip family network device support
+#
+CONFIG_NET_TULIP=y
+CONFIG_DE2104X=m
+CONFIG_TULIP=m
+# CONFIG_TULIP_MWI is not set
+CONFIG_TULIP_MMIO=y
+# CONFIG_TULIP_NAPI is not set
+CONFIG_DE4X5=m
+CONFIG_WINBOND_840=m
+CONFIG_DM9102=m
+CONFIG_ULI526X=m
+CONFIG_PCMCIA_XIRCOM=m
+# CONFIG_HP100 is not set
+CONFIG_NET_PCI=y
+CONFIG_PCNET32=m
+CONFIG_AMD8111_ETH=m
+CONFIG_AMD8111E_NAPI=y
+CONFIG_ADAPTEC_STARFIRE=m
+CONFIG_ADAPTEC_STARFIRE_NAPI=y
+CONFIG_B44=m
+CONFIG_FORCEDETH=m
+# CONFIG_DGRS is not set
+# CONFIG_EEPRO100 is not set
+CONFIG_E100=m
+CONFIG_FEALNX=m
+CONFIG_NATSEMI=m
+CONFIG_NE2K_PCI=m
+CONFIG_8139CP=m
+CONFIG_8139TOO=m
+# CONFIG_8139TOO_PIO is not set
+# CONFIG_8139TOO_TUNE_TWISTER is not set
+CONFIG_8139TOO_8129=y
+# CONFIG_8139_OLD_RX_RESET is not set
+CONFIG_SIS900=m
+CONFIG_EPIC100=m
+CONFIG_SUNDANCE=m
+# CONFIG_SUNDANCE_MMIO is not set
+CONFIG_VIA_RHINE=m
+CONFIG_VIA_RHINE_MMIO=y
+CONFIG_VIA_RHINE_NAPI=y
+CONFIG_NET_POCKET=y
+CONFIG_DE600=m
+CONFIG_DE620=m
+
+#
+# Ethernet (1000 Mbit)
+#
+CONFIG_ACENIC=m
+# CONFIG_ACENIC_OMIT_TIGON_I is not set
+CONFIG_DL2K=m
+CONFIG_E1000=m
+CONFIG_E1000_NAPI=y
+# CONFIG_E1000_DISABLE_PACKET_SPLIT is not set
+CONFIG_NS83820=m
+CONFIG_HAMACHI=m
+CONFIG_YELLOWFIN=m
+CONFIG_R8169=m
+CONFIG_R8169_NAPI=y
+CONFIG_R8169_VLAN=y
+CONFIG_SIS190=m
+CONFIG_SKGE=m
+CONFIG_SKY2=m
+# CONFIG_SK98LIN is not set
+CONFIG_VIA_VELOCITY=m
+CONFIG_TIGON3=m
+CONFIG_BNX2=m
+
+#
+# Ethernet (10000 Mbit)
+#
+CONFIG_CHELSIO_T1=m
+CONFIG_IXGB=m
+CONFIG_IXGB_NAPI=y
+CONFIG_S2IO=m
+CONFIG_S2IO_NAPI=y
+CONFIG_MYRI10GE=m
+
+#
+# Token Ring devices
+#
+CONFIG_TR=y
+CONFIG_IBMOL=m
+CONFIG_3C359=m
+# CONFIG_TMS380TR is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+CONFIG_NET_RADIO=y
+CONFIG_NET_WIRELESS_RTNETLINK=y
+
+#
+# Obsolete Wireless cards support (pre-802.11)
+#
+# CONFIG_STRIP is not set
+CONFIG_PCMCIA_WAVELAN=m
+CONFIG_PCMCIA_NETWAVE=m
+
+#
+# Wireless 802.11 Frequency Hopping cards support
+#
+# CONFIG_PCMCIA_RAYCS is not set
+
+#
+# Wireless 802.11b ISA/PCI cards support
+#
+# CONFIG_IPW2100 is not set
+# CONFIG_IPW2200 is not set
+CONFIG_HERMES=m
+CONFIG_PLX_HERMES=m
+CONFIG_TMD_HERMES=m
+CONFIG_NORTEL_HERMES=m
+CONFIG_PCI_HERMES=m
+CONFIG_ATMEL=m
+CONFIG_PCI_ATMEL=m
+
+#
+# Wireless 802.11b Pcmcia/Cardbus cards support
+#
+CONFIG_PCMCIA_HERMES=m
+CONFIG_PCMCIA_SPECTRUM=m
+CONFIG_AIRO_CS=m
+CONFIG_PCMCIA_ATMEL=m
+CONFIG_PCMCIA_WL3501=m
+
+#
+# Prism GT/Duette 802.11(a/b/g) PCI/Cardbus support
+#
+CONFIG_PRISM54=m
+CONFIG_USB_ZD1201=m
+CONFIG_HOSTAP=m
+CONFIG_HOSTAP_FIRMWARE=y
+CONFIG_HOSTAP_FIRMWARE_NVRAM=y
+CONFIG_HOSTAP_PLX=m
+CONFIG_HOSTAP_PCI=m
+CONFIG_HOSTAP_CS=m
+# CONFIG_BCM43XX is not set
+CONFIG_ZD1211RW=m
+# CONFIG_ZD1211RW_DEBUG is not set
+CONFIG_NET_WIRELESS=y
+
+#
+# PCMCIA network device support
+#
+CONFIG_NET_PCMCIA=y
+CONFIG_PCMCIA_3C589=m
+CONFIG_PCMCIA_3C574=m
+CONFIG_PCMCIA_FMVJ18X=m
+CONFIG_PCMCIA_PCNET=m
+CONFIG_PCMCIA_NMCLAN=m
+CONFIG_PCMCIA_SMC91C92=m
+CONFIG_PCMCIA_XIRC2PS=m
+CONFIG_PCMCIA_AXNET=m
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+
+#
+# ATM drivers
+#
+# CONFIG_ATM_DUMMY is not set
+CONFIG_ATM_TCP=m
+CONFIG_ATM_LANAI=m
+CONFIG_ATM_ENI=m
+# CONFIG_ATM_ENI_DEBUG is not set
+# CONFIG_ATM_ENI_TUNE_BURST is not set
+CONFIG_ATM_FIRESTREAM=m
+# CONFIG_ATM_ZATM is not set
+CONFIG_ATM_IDT77252=m
+# CONFIG_ATM_IDT77252_DEBUG is not set
+# CONFIG_ATM_IDT77252_RCV_ALL is not set
+CONFIG_ATM_IDT77252_USE_SUNI=y
+CONFIG_ATM_AMBASSADOR=m
+# CONFIG_ATM_AMBASSADOR_DEBUG is not set
+CONFIG_ATM_HORIZON=m
+# CONFIG_ATM_HORIZON_DEBUG is not set
+CONFIG_ATM_FORE200E_MAYBE=m
+# CONFIG_ATM_FORE200E_PCA is not set
+CONFIG_ATM_HE=m
+# CONFIG_ATM_HE_USE_SUNI is not set
+CONFIG_FDDI=y
+# CONFIG_DEFXX is not set
+CONFIG_SKFP=m
+# CONFIG_HIPPI is not set
+CONFIG_PLIP=m
+CONFIG_PPP=m
+CONFIG_PPP_MULTILINK=y
+CONFIG_PPP_FILTER=y
+CONFIG_PPP_ASYNC=m
+CONFIG_PPP_SYNC_TTY=m
+CONFIG_PPP_DEFLATE=m
+# CONFIG_PPP_BSDCOMP is not set
+CONFIG_PPP_MPPE=m
+CONFIG_PPPOE=m
+CONFIG_PPPOATM=m
+CONFIG_SLIP=m
+CONFIG_SLIP_COMPRESSED=y
+CONFIG_SLIP_SMART=y
+# CONFIG_SLIP_MODE_SLIP6 is not set
+CONFIG_NET_FC=y
+# CONFIG_SHAPER is not set
+CONFIG_NETCONSOLE=m
+CONFIG_NETPOLL=y
+# CONFIG_NETPOLL_RX is not set
+CONFIG_NETPOLL_TRAP=y
+CONFIG_NET_POLL_CONTROLLER=y
+
+#
+# ISDN subsystem
+#
+CONFIG_ISDN=m
+
+#
+# Old ISDN4Linux
+#
+CONFIG_ISDN_I4L=m
+CONFIG_ISDN_PPP=y
+CONFIG_ISDN_PPP_VJ=y
+CONFIG_ISDN_MPP=y
+CONFIG_IPPP_FILTER=y
+# CONFIG_ISDN_PPP_BSDCOMP is not set
+CONFIG_ISDN_AUDIO=y
+CONFIG_ISDN_TTY_FAX=y
+
+#
+# ISDN feature submodules
+#
+CONFIG_ISDN_DIVERSION=m
+
+#
+# ISDN4Linux hardware drivers
+#
+
+#
+# Passive cards
+#
+CONFIG_ISDN_DRV_HISAX=m
+
+#
+# D-channel protocol features
+#
+CONFIG_HISAX_EURO=y
+CONFIG_DE_AOC=y
+CONFIG_HISAX_NO_SENDCOMPLETE=y
+CONFIG_HISAX_NO_LLC=y
+CONFIG_HISAX_NO_KEYPAD=y
+CONFIG_HISAX_1TR6=y
+CONFIG_HISAX_NI1=y
+CONFIG_HISAX_MAX_CARDS=8
+
+#
+# HiSax supported cards
+#
+CONFIG_HISAX_16_3=y
+CONFIG_HISAX_TELESPCI=y
+CONFIG_HISAX_S0BOX=y
+CONFIG_HISAX_FRITZPCI=y
+CONFIG_HISAX_AVM_A1_PCMCIA=y
+CONFIG_HISAX_ELSA=y
+CONFIG_HISAX_DIEHLDIVA=y
+CONFIG_HISAX_SEDLBAUER=y
+CONFIG_HISAX_NETJET=y
+CONFIG_HISAX_NETJET_U=y
+CONFIG_HISAX_NICCY=y
+CONFIG_HISAX_BKM_A4T=y
+CONFIG_HISAX_SCT_QUADRO=y
+CONFIG_HISAX_GAZEL=y
+CONFIG_HISAX_HFC_PCI=y
+CONFIG_HISAX_W6692=y
+CONFIG_HISAX_HFC_SX=y
+CONFIG_HISAX_ENTERNOW_PCI=y
+# CONFIG_HISAX_DEBUG is not set
+
+#
+# HiSax PCMCIA card service modules
+#
+CONFIG_HISAX_SEDLBAUER_CS=m
+CONFIG_HISAX_ELSA_CS=m
+CONFIG_HISAX_AVM_A1_CS=m
+CONFIG_HISAX_TELES_CS=m
+
+#
+# HiSax sub driver modules
+#
+CONFIG_HISAX_ST5481=m
+# CONFIG_HISAX_HFCUSB is not set
+CONFIG_HISAX_HFC4S8S=m
+CONFIG_HISAX_FRITZ_PCIPNP=m
+CONFIG_HISAX_HDLC=y
+
+#
+# Active cards
+#
+
+#
+# Siemens Gigaset
+#
+CONFIG_ISDN_DRV_GIGASET=m
+CONFIG_GIGASET_BASE=m
+CONFIG_GIGASET_M105=m
+# CONFIG_GIGASET_DEBUG is not set
+# CONFIG_GIGASET_UNDOCREQ is not set
+
+#
+# CAPI subsystem
+#
+CONFIG_ISDN_CAPI=m
+CONFIG_ISDN_DRV_AVMB1_VERBOSE_REASON=y
+CONFIG_ISDN_CAPI_MIDDLEWARE=y
+CONFIG_ISDN_CAPI_CAPI20=m
+CONFIG_ISDN_CAPI_CAPIFS_BOOL=y
+CONFIG_ISDN_CAPI_CAPIFS=m
+CONFIG_ISDN_CAPI_CAPIDRV=m
+
+#
+# CAPI hardware drivers
+#
+
+#
+# Active AVM cards
+#
+CONFIG_CAPI_AVM=y
+CONFIG_ISDN_DRV_AVMB1_B1PCI=m
+CONFIG_ISDN_DRV_AVMB1_B1PCIV4=y
+CONFIG_ISDN_DRV_AVMB1_B1PCMCIA=m
+CONFIG_ISDN_DRV_AVMB1_AVM_CS=m
+CONFIG_ISDN_DRV_AVMB1_T1PCI=m
+CONFIG_ISDN_DRV_AVMB1_C4=m
+
+#
+# Active Eicon DIVA Server cards
+#
+# CONFIG_CAPI_EICON is not set
+
+#
+# Telephony Support
+#
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+
+#
+# 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=m
+# CONFIG_INPUT_TSDEV is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+CONFIG_KEYBOARD_ATKBD=y
+# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_KEYBOARD_LKKBD is not set
+# CONFIG_KEYBOARD_XTKBD is not set
+# CONFIG_KEYBOARD_NEWTON is not set
+CONFIG_INPUT_MOUSE=y
+CONFIG_MOUSE_PS2=y
+CONFIG_MOUSE_SERIAL=m
+CONFIG_MOUSE_VSXXXAA=m
+CONFIG_INPUT_JOYSTICK=y
+CONFIG_JOYSTICK_ANALOG=m
+CONFIG_JOYSTICK_A3D=m
+CONFIG_JOYSTICK_ADI=m
+CONFIG_JOYSTICK_COBRA=m
+CONFIG_JOYSTICK_GF2K=m
+CONFIG_JOYSTICK_GRIP=m
+CONFIG_JOYSTICK_GRIP_MP=m
+CONFIG_JOYSTICK_GUILLEMOT=m
+CONFIG_JOYSTICK_INTERACT=m
+CONFIG_JOYSTICK_SIDEWINDER=m
+CONFIG_JOYSTICK_TMDC=m
+CONFIG_JOYSTICK_IFORCE=m
+CONFIG_JOYSTICK_IFORCE_USB=y
+CONFIG_JOYSTICK_IFORCE_232=y
+CONFIG_JOYSTICK_WARRIOR=m
+CONFIG_JOYSTICK_MAGELLAN=m
+CONFIG_JOYSTICK_SPACEORB=m
+CONFIG_JOYSTICK_SPACEBALL=m
+CONFIG_JOYSTICK_STINGER=m
+CONFIG_JOYSTICK_TWIDJOY=m
+CONFIG_JOYSTICK_DB9=m
+CONFIG_JOYSTICK_GAMECON=m
+CONFIG_JOYSTICK_TURBOGRAFX=m
+CONFIG_JOYSTICK_JOYDUMP=m
+CONFIG_INPUT_TOUCHSCREEN=y
+CONFIG_TOUCHSCREEN_GUNZE=m
+CONFIG_TOUCHSCREEN_ELO=m
+CONFIG_TOUCHSCREEN_MTOUCH=m
+CONFIG_TOUCHSCREEN_MK712=m
+CONFIG_INPUT_MISC=y
+CONFIG_INPUT_UINPUT=m
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+CONFIG_SERIO_I8042=y
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_PARKBD is not set
+# CONFIG_SERIO_PCIPS2 is not set
+CONFIG_SERIO_LIBPS2=y
+CONFIG_SERIO_RAW=m
+CONFIG_GAMEPORT=m
+CONFIG_GAMEPORT_NS558=m
+CONFIG_GAMEPORT_L4=m
+CONFIG_GAMEPORT_EMU10K1=m
+CONFIG_GAMEPORT_FM801=m
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+CONFIG_VT_HW_CONSOLE_BINDING=y
+CONFIG_SERIAL_NONSTANDARD=y
+# CONFIG_COMPUTONE is not set
+# CONFIG_ROCKETPORT is not set
+CONFIG_CYCLADES=m
+# CONFIG_CYZ_INTR is not set
+# CONFIG_DIGIEPCA is not set
+# CONFIG_MOXA_INTELLIO is not set
+# CONFIG_MOXA_SMARTIO is not set
+# CONFIG_ISI is not set
+CONFIG_SYNCLINKMP=m
+CONFIG_SYNCLINK_GT=m
+CONFIG_N_HDLC=m
+# CONFIG_SPECIALIX is not set
+# CONFIG_SX is not set
+# CONFIG_RIO is not set
+# CONFIG_STALDRV is not set
+CONFIG_SGI_SNSC=y
+CONFIG_SGI_TIOCX=y
+CONFIG_SGI_MBCS=m
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_PCI=y
+CONFIG_SERIAL_8250_PNP=y
+CONFIG_SERIAL_8250_CS=m
+CONFIG_SERIAL_8250_NR_UARTS=32
+CONFIG_SERIAL_8250_RUNTIME_UARTS=16
+CONFIG_SERIAL_8250_EXTENDED=y
+CONFIG_SERIAL_8250_SHARE_IRQ=y
+CONFIG_SERIAL_8250_DETECT_IRQ=y
+CONFIG_SERIAL_8250_RSA=y
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_SERIAL_SGI_L1_CONSOLE=y
+CONFIG_SERIAL_JSM=m
+CONFIG_SERIAL_SGI_IOC4=m
+CONFIG_SERIAL_SGI_IOC3=m
+CONFIG_UNIX98_PTYS=y
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_CRASH is not set
+CONFIG_PRINTER=m
+CONFIG_LP_CONSOLE=y
+CONFIG_PPDEV=m
+CONFIG_TIPAR=m
+
+#
+# IPMI
+#
+CONFIG_IPMI_HANDLER=m
+# CONFIG_IPMI_PANIC_EVENT is not set
+CONFIG_IPMI_DEVICE_INTERFACE=m
+CONFIG_IPMI_SI=m
+CONFIG_IPMI_WATCHDOG=m
+CONFIG_IPMI_POWEROFF=m
+
+#
+# Watchdog Cards
+#
+CONFIG_WATCHDOG=y
+# CONFIG_WATCHDOG_NOWAYOUT is not set
+
+#
+# Watchdog Device Drivers
+#
+CONFIG_SOFT_WATCHDOG=m
+CONFIG_I8XX_TCO=m
+
+#
+# PCI-based Watchdog Cards
+#
+CONFIG_PCIPCWATCHDOG=m
+CONFIG_WDTPCI=m
+CONFIG_WDT_501_PCI=y
+
+#
+# USB-based Watchdog Cards
+#
+CONFIG_USBPCWATCHDOG=m
+# CONFIG_HW_RANDOM is not set
+CONFIG_EFI_RTC=y
+CONFIG_DTLK=m
+CONFIG_R3964=m
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+CONFIG_AGP=y
+CONFIG_AGP_SIS=y
+CONFIG_AGP_VIA=y
+CONFIG_AGP_I460=y
+CONFIG_AGP_HP_ZX1=y
+CONFIG_AGP_SGI_TIOCA=y
+CONFIG_DRM=m
+CONFIG_DRM_TDFX=m
+CONFIG_DRM_R128=m
+CONFIG_DRM_RADEON=m
+CONFIG_DRM_MGA=m
+CONFIG_DRM_SIS=m
+CONFIG_DRM_VIA=m
+CONFIG_DRM_SAVAGE=m
+
+#
+# PCMCIA character devices
+#
+# CONFIG_SYNCLINK_CS is not set
+CONFIG_CARDMAN_4000=m
+CONFIG_CARDMAN_4040=m
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_HPET is not set
+CONFIG_HANGCHECK_TIMER=m
+CONFIG_MMTIMER=y
+
+#
+# TPM devices
+#
+CONFIG_TCG_TPM=m
+CONFIG_TCG_TIS=m
+CONFIG_TCG_NSC=m
+CONFIG_TCG_ATMEL=m
+# CONFIG_TCG_INFINEON is not set
+# CONFIG_TELCLOCK is not set
+
+#
+# I2C support
+#
+CONFIG_I2C=m
+CONFIG_I2C_CHARDEV=m
+
+#
+# I2C Algorithms
+#
+CONFIG_I2C_ALGOBIT=m
+CONFIG_I2C_ALGOPCF=m
+CONFIG_I2C_ALGOPCA=m
+
+#
+# I2C Hardware Bus support
+#
+# CONFIG_I2C_ALI1535 is not set
+# CONFIG_I2C_ALI1563 is not set
+# CONFIG_I2C_ALI15X3 is not set
+# CONFIG_I2C_AMD756 is not set
+# CONFIG_I2C_AMD8111 is not set
+# CONFIG_I2C_I801 is not set
+# CONFIG_I2C_I810 is not set
+# CONFIG_I2C_PIIX4 is not set
+CONFIG_I2C_ISA=m
+CONFIG_I2C_NFORCE2=m
+# CONFIG_I2C_OCORES is not set
+CONFIG_I2C_PARPORT=m
+CONFIG_I2C_PARPORT_LIGHT=m
+CONFIG_I2C_PROSAVAGE=m
+CONFIG_I2C_SAVAGE4=m
+# CONFIG_I2C_SIS5595 is not set
+# CONFIG_I2C_SIS630 is not set
+# CONFIG_I2C_SIS96X is not set
+CONFIG_I2C_STUB=m
+# CONFIG_I2C_VIA is not set
+# CONFIG_I2C_VIAPRO is not set
+CONFIG_I2C_VOODOO3=m
+CONFIG_I2C_PCA_ISA=m
+
+#
+# Miscellaneous I2C Chip support
+#
+CONFIG_SENSORS_DS1337=m
+CONFIG_SENSORS_DS1374=m
+CONFIG_SENSORS_EEPROM=m
+CONFIG_SENSORS_PCF8574=m
+CONFIG_SENSORS_PCA9539=m
+CONFIG_SENSORS_PCF8591=m
+CONFIG_SENSORS_MAX6875=m
+# 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 is not set
+# CONFIG_SPI_MASTER is not set
+
+#
+# Dallas's 1-wire bus
+#
+CONFIG_W1=m
+CONFIG_W1_CON=y
+
+#
+# 1-wire Bus Masters
+#
+CONFIG_W1_MASTER_MATROX=m
+CONFIG_W1_MASTER_DS2490=m
+CONFIG_W1_MASTER_DS2482=m
+
+#
+# 1-wire Slaves
+#
+CONFIG_W1_SLAVE_THERM=m
+CONFIG_W1_SLAVE_SMEM=m
+CONFIG_W1_SLAVE_DS2433=m
+CONFIG_W1_SLAVE_DS2433_CRC=y
+
+#
+# Hardware Monitoring support
+#
+CONFIG_HWMON=m
+CONFIG_HWMON_VID=m
+CONFIG_SENSORS_ABITUGURU=m
+CONFIG_SENSORS_ADM1021=m
+CONFIG_SENSORS_ADM1025=m
+CONFIG_SENSORS_ADM1026=m
+CONFIG_SENSORS_ADM1031=m
+CONFIG_SENSORS_ADM9240=m
+CONFIG_SENSORS_ASB100=m
+CONFIG_SENSORS_ATXP1=m
+CONFIG_SENSORS_DS1621=m
+CONFIG_SENSORS_F71805F=m
+CONFIG_SENSORS_FSCHER=m
+CONFIG_SENSORS_FSCPOS=m
+CONFIG_SENSORS_GL518SM=m
+CONFIG_SENSORS_GL520SM=m
+CONFIG_SENSORS_IT87=m
+CONFIG_SENSORS_LM63=m
+CONFIG_SENSORS_LM75=m
+CONFIG_SENSORS_LM77=m
+CONFIG_SENSORS_LM78=m
+CONFIG_SENSORS_LM80=m
+CONFIG_SENSORS_LM83=m
+CONFIG_SENSORS_LM85=m
+CONFIG_SENSORS_LM87=m
+CONFIG_SENSORS_LM90=m
+CONFIG_SENSORS_LM92=m
+CONFIG_SENSORS_MAX1619=m
+CONFIG_SENSORS_PC87360=m
+CONFIG_SENSORS_SIS5595=m
+CONFIG_SENSORS_SMSC47M1=m
+CONFIG_SENSORS_SMSC47M192=m
+CONFIG_SENSORS_SMSC47B397=m
+CONFIG_SENSORS_VIA686A=m
+CONFIG_SENSORS_VT8231=m
+CONFIG_SENSORS_W83781D=m
+CONFIG_SENSORS_W83791D=m
+CONFIG_SENSORS_W83792D=m
+CONFIG_SENSORS_W83L785TS=m
+CONFIG_SENSORS_W83627HF=m
+CONFIG_SENSORS_W83627EHF=m
+# CONFIG_HWMON_DEBUG_CHIP is not set
+
+#
+# Misc devices
+#
+
+#
+# Multimedia devices
+#
+CONFIG_VIDEO_DEV=m
+CONFIG_VIDEO_V4L1=y
+CONFIG_VIDEO_V4L1_COMPAT=y
+CONFIG_VIDEO_V4L2=y
+
+#
+# Video Capture Adapters
+#
+
+#
+# Video Capture Adapters
+#
+# CONFIG_VIDEO_ADV_DEBUG is not set
+# CONFIG_VIDEO_VIVI is not set
+CONFIG_VIDEO_BT848=m
+CONFIG_VIDEO_BT848_DVB=y
+CONFIG_VIDEO_SAA6588=m
+CONFIG_VIDEO_BWQCAM=m
+CONFIG_VIDEO_CQCAM=m
+CONFIG_VIDEO_W9966=m
+CONFIG_VIDEO_CPIA=m
+CONFIG_VIDEO_CPIA_PP=m
+CONFIG_VIDEO_CPIA_USB=m
+CONFIG_VIDEO_CPIA2=m
+CONFIG_VIDEO_SAA5246A=m
+CONFIG_VIDEO_SAA5249=m
+CONFIG_TUNER_3036=m
+CONFIG_VIDEO_STRADIS=m
+CONFIG_VIDEO_ZORAN=m
+CONFIG_VIDEO_ZORAN_BUZ=m
+CONFIG_VIDEO_ZORAN_DC10=m
+CONFIG_VIDEO_ZORAN_DC30=m
+CONFIG_VIDEO_ZORAN_LML33=m
+CONFIG_VIDEO_ZORAN_LML33R10=m
+CONFIG_VIDEO_ZORAN_AVS6EYES=m
+CONFIG_VIDEO_SAA7134=m
+CONFIG_VIDEO_SAA7134_ALSA=m
+CONFIG_VIDEO_SAA7134_DVB=m
+CONFIG_VIDEO_SAA7134_DVB_ALL_FRONTENDS=y
+CONFIG_VIDEO_MXB=m
+CONFIG_VIDEO_DPC=m
+CONFIG_VIDEO_HEXIUM_ORION=m
+CONFIG_VIDEO_HEXIUM_GEMINI=m
+CONFIG_VIDEO_CX88_VP3054=m
+CONFIG_VIDEO_CX88=m
+CONFIG_VIDEO_CX88_ALSA=m
+CONFIG_VIDEO_CX88_BLACKBIRD=m
+CONFIG_VIDEO_CX88_DVB=m
+CONFIG_VIDEO_CX88_DVB_ALL_FRONTENDS=y
+
+#
+# Encoders and Decoders
+#
+CONFIG_VIDEO_MSP3400=m
+CONFIG_VIDEO_CS53L32A=m
+CONFIG_VIDEO_TLV320AIC23B=m
+CONFIG_VIDEO_WM8775=m
+CONFIG_VIDEO_WM8739=m
+CONFIG_VIDEO_CX2341X=m
+CONFIG_VIDEO_CX25840=m
+CONFIG_VIDEO_SAA711X=m
+CONFIG_VIDEO_SAA7127=m
+CONFIG_VIDEO_UPD64031A=m
+CONFIG_VIDEO_UPD64083=m
+
+#
+# V4L USB devices
+#
+CONFIG_VIDEO_PVRUSB2=m
+CONFIG_VIDEO_PVRUSB2_24XXX=y
+CONFIG_VIDEO_PVRUSB2_SYSFS=y
+# CONFIG_VIDEO_PVRUSB2_DEBUGIFC is not set
+CONFIG_VIDEO_EM28XX=m
+CONFIG_VIDEO_USBVIDEO=m
+CONFIG_USB_VICAM=m
+CONFIG_USB_IBMCAM=m
+CONFIG_USB_KONICAWC=m
+CONFIG_USB_QUICKCAM_MESSENGER=m
+CONFIG_USB_ET61X251=m
+CONFIG_VIDEO_OVCAMCHIP=m
+CONFIG_USB_W9968CF=m
+CONFIG_USB_OV511=m
+CONFIG_USB_SE401=m
+CONFIG_USB_SN9C102=m
+CONFIG_USB_STV680=m
+CONFIG_USB_ZC0301=m
+CONFIG_USB_PWC=m
+# CONFIG_USB_PWC_DEBUG is not set
+
+#
+# Radio Adapters
+#
+CONFIG_RADIO_GEMTEK_PCI=m
+CONFIG_RADIO_MAXIRADIO=m
+CONFIG_RADIO_MAESTRO=m
+CONFIG_USB_DSBR=m
+
+#
+# Digital Video Broadcasting Devices
+#
+CONFIG_DVB=y
+CONFIG_DVB_CORE=m
+
+#
+# Supported SAA7146 based PCI Adapters
+#
+CONFIG_DVB_AV7110=m
+CONFIG_DVB_AV7110_OSD=y
+CONFIG_DVB_BUDGET=m
+CONFIG_DVB_BUDGET_CI=m
+CONFIG_DVB_BUDGET_AV=m
+CONFIG_DVB_BUDGET_PATCH=m
+
+#
+# Supported USB Adapters
+#
+CONFIG_DVB_USB=m
+# CONFIG_DVB_USB_DEBUG is not set
+CONFIG_DVB_USB_A800=m
+CONFIG_DVB_USB_DIBUSB_MB=m
+# CONFIG_DVB_USB_DIBUSB_MB_FAULTY is not set
+CONFIG_DVB_USB_DIBUSB_MC=m
+CONFIG_DVB_USB_UMT_010=m
+CONFIG_DVB_USB_CXUSB=m
+CONFIG_DVB_USB_DIGITV=m
+CONFIG_DVB_USB_VP7045=m
+CONFIG_DVB_USB_VP702X=m
+CONFIG_DVB_USB_GP8PSK=m
+CONFIG_DVB_USB_NOVA_T_USB2=m
+CONFIG_DVB_USB_DTT200U=m
+CONFIG_DVB_TTUSB_BUDGET=m
+CONFIG_DVB_TTUSB_DEC=m
+CONFIG_DVB_CINERGYT2=m
+CONFIG_DVB_CINERGYT2_TUNING=y
+CONFIG_DVB_CINERGYT2_STREAM_URB_COUNT=32
+CONFIG_DVB_CINERGYT2_STREAM_BUF_SIZE=512
+CONFIG_DVB_CINERGYT2_QUERY_INTERVAL=250
+CONFIG_DVB_CINERGYT2_ENABLE_RC_INPUT_DEVICE=y
+CONFIG_DVB_CINERGYT2_RC_QUERY_INTERVAL=100
+
+#
+# Supported FlexCopII (B2C2) Adapters
+#
+CONFIG_DVB_B2C2_FLEXCOP=m
+CONFIG_DVB_B2C2_FLEXCOP_PCI=m
+CONFIG_DVB_B2C2_FLEXCOP_USB=m
+# CONFIG_DVB_B2C2_FLEXCOP_DEBUG is not set
+
+#
+# Supported BT878 Adapters
+#
+CONFIG_DVB_BT8XX=m
+
+#
+# Supported Pluto2 Adapters
+#
+CONFIG_DVB_PLUTO2=m
+
+#
+# Supported DVB Frontends
+#
+
+#
+# Customise DVB Frontends
+#
+
+#
+# DVB-S (satellite) frontends
+#
+CONFIG_DVB_STV0299=m
+CONFIG_DVB_CX24110=m
+CONFIG_DVB_CX24123=m
+CONFIG_DVB_TDA8083=m
+CONFIG_DVB_MT312=m
+CONFIG_DVB_VES1X93=m
+CONFIG_DVB_S5H1420=m
+
+#
+# DVB-T (terrestrial) frontends
+#
+CONFIG_DVB_SP8870=m
+CONFIG_DVB_SP887X=m
+CONFIG_DVB_CX22700=m
+CONFIG_DVB_CX22702=m
+CONFIG_DVB_L64781=m
+CONFIG_DVB_TDA1004X=m
+CONFIG_DVB_NXT6000=m
+CONFIG_DVB_MT352=m
+CONFIG_DVB_ZL10353=m
+CONFIG_DVB_DIB3000MB=m
+CONFIG_DVB_DIB3000MC=m
+
+#
+# DVB-C (cable) frontends
+#
+CONFIG_DVB_VES1820=m
+CONFIG_DVB_TDA10021=m
+CONFIG_DVB_STV0297=m
+
+#
+# ATSC (North American/Korean Terrestrial/Cable DTV) frontends
+#
+CONFIG_DVB_NXT200X=m
+CONFIG_DVB_OR51211=m
+CONFIG_DVB_OR51132=m
+CONFIG_DVB_BCM3510=m
+CONFIG_DVB_LGDT330X=m
+
+#
+# Miscellaneous devices
+#
+CONFIG_DVB_PLL=m
+CONFIG_DVB_LNBP21=m
+CONFIG_DVB_ISL6421=m
+CONFIG_VIDEO_SAA7146=m
+CONFIG_VIDEO_SAA7146_VV=m
+CONFIG_VIDEO_VIDEOBUF=m
+CONFIG_VIDEO_TUNER=m
+CONFIG_VIDEO_BUF=m
+CONFIG_VIDEO_BUF_DVB=m
+CONFIG_VIDEO_BTCX=m
+CONFIG_VIDEO_IR=m
+CONFIG_VIDEO_TVEEPROM=m
+CONFIG_USB_DABUSB=m
+
+#
+# Graphics support
+#
+# CONFIG_FIRMWARE_EDID is not set
+CONFIG_FB=y
+CONFIG_FB_CFB_FILLRECT=m
+CONFIG_FB_CFB_COPYAREA=m
+CONFIG_FB_CFB_IMAGEBLIT=m
+# CONFIG_FB_MACMODES is not set
+# CONFIG_FB_BACKLIGHT is not set
+CONFIG_FB_MODE_HELPERS=y
+CONFIG_FB_TILEBLITTING=y
+CONFIG_FB_CIRRUS=m
+# CONFIG_FB_PM2 is not set
+# CONFIG_FB_CYBER2000 is not set
+# CONFIG_FB_ASILIANT is not set
+# CONFIG_FB_IMSTT is not set
+# CONFIG_FB_S1D13XXX is not set
+CONFIG_FB_NVIDIA=m
+CONFIG_FB_NVIDIA_I2C=y
+CONFIG_FB_RIVA=m
+# CONFIG_FB_RIVA_I2C is not set
+# CONFIG_FB_RIVA_DEBUG is not set
+CONFIG_FB_MATROX=m
+CONFIG_FB_MATROX_MILLENIUM=y
+CONFIG_FB_MATROX_MYSTIQUE=y
+CONFIG_FB_MATROX_G=y
+CONFIG_FB_MATROX_I2C=m
+CONFIG_FB_MATROX_MAVEN=m
+CONFIG_FB_MATROX_MULTIHEAD=y
+CONFIG_FB_RADEON=m
+CONFIG_FB_RADEON_I2C=y
+# CONFIG_FB_RADEON_DEBUG is not set
+CONFIG_FB_ATY128=m
+CONFIG_FB_ATY=m
+CONFIG_FB_ATY_CT=y
+CONFIG_FB_ATY_GENERIC_LCD=y
+CONFIG_FB_ATY_GX=y
+CONFIG_FB_SAVAGE=m
+CONFIG_FB_SAVAGE_I2C=y
+CONFIG_FB_SAVAGE_ACCEL=y
+# CONFIG_FB_SIS is not set
+CONFIG_FB_NEOMAGIC=m
+CONFIG_FB_KYRO=m
+CONFIG_FB_3DFX=m
+CONFIG_FB_3DFX_ACCEL=y
+CONFIG_FB_VOODOO1=m
+CONFIG_FB_TRIDENT=m
+CONFIG_FB_TRIDENT_ACCEL=y
+# CONFIG_FB_VIRTUAL is not set
+
+#
+# Console display driver support
+#
+CONFIG_VGA_CONSOLE=y
+CONFIG_VGACON_SOFT_SCROLLBACK=y
+CONFIG_VGACON_SOFT_SCROLLBACK_SIZE=64
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y
+# CONFIG_FONTS is not set
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
+
+#
+# Logo configuration
+#
+CONFIG_LOGO=y
+# CONFIG_LOGO_LINUX_MONO is not set
+# CONFIG_LOGO_LINUX_VGA16 is not set
+CONFIG_LOGO_LINUX_CLUT224=y
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+CONFIG_BACKLIGHT_CLASS_DEVICE=m
+CONFIG_BACKLIGHT_DEVICE=y
+CONFIG_LCD_CLASS_DEVICE=m
+CONFIG_LCD_DEVICE=y
+
+#
+# Sound
+#
+CONFIG_SOUND=m
+
+#
+# Advanced Linux Sound Architecture
+#
+CONFIG_SND=m
+CONFIG_SND_TIMER=m
+CONFIG_SND_PCM=m
+CONFIG_SND_HWDEP=m
+CONFIG_SND_RAWMIDI=m
+CONFIG_SND_SEQUENCER=m
+CONFIG_SND_SEQ_DUMMY=m
+CONFIG_SND_OSSEMUL=y
+CONFIG_SND_MIXER_OSS=m
+CONFIG_SND_PCM_OSS=m
+CONFIG_SND_PCM_OSS_PLUGINS=y
+CONFIG_SND_SEQUENCER_OSS=y
+CONFIG_SND_DYNAMIC_MINORS=y
+# CONFIG_SND_SUPPORT_OLD_API is not set
+CONFIG_SND_VERBOSE_PROCFS=y
+# CONFIG_SND_VERBOSE_PRINTK is not set
+# CONFIG_SND_DEBUG is not set
+
+#
+# Generic devices
+#
+CONFIG_SND_MPU401_UART=m
+CONFIG_SND_OPL3_LIB=m
+CONFIG_SND_VX_LIB=m
+CONFIG_SND_AC97_CODEC=m
+CONFIG_SND_AC97_BUS=m
+CONFIG_SND_DUMMY=m
+CONFIG_SND_VIRMIDI=m
+CONFIG_SND_MTPAV=m
+# CONFIG_SND_SERIAL_U16550 is not set
+CONFIG_SND_MPU401=m
+
+#
+# PCI devices
+#
+CONFIG_SND_AD1889=m
+CONFIG_SND_ALS300=m
+CONFIG_SND_ALI5451=m
+CONFIG_SND_ATIIXP=m
+CONFIG_SND_ATIIXP_MODEM=m
+CONFIG_SND_AU8810=m
+CONFIG_SND_AU8820=m
+CONFIG_SND_AU8830=m
+CONFIG_SND_AZT3328=m
+CONFIG_SND_BT87X=m
+# CONFIG_SND_BT87X_OVERCLOCK is not set
+CONFIG_SND_CA0106=m
+CONFIG_SND_CMIPCI=m
+CONFIG_SND_CS4281=m
+CONFIG_SND_CS46XX=m
+CONFIG_SND_CS46XX_NEW_DSP=y
+CONFIG_SND_DARLA20=m
+CONFIG_SND_GINA20=m
+CONFIG_SND_LAYLA20=m
+CONFIG_SND_DARLA24=m
+CONFIG_SND_GINA24=m
+CONFIG_SND_LAYLA24=m
+CONFIG_SND_MONA=m
+CONFIG_SND_MIA=m
+CONFIG_SND_ECHO3G=m
+CONFIG_SND_INDIGO=m
+CONFIG_SND_INDIGOIO=m
+CONFIG_SND_INDIGODJ=m
+CONFIG_SND_EMU10K1=m
+CONFIG_SND_EMU10K1X=m
+CONFIG_SND_ENS1370=m
+CONFIG_SND_ENS1371=m
+CONFIG_SND_ES1938=m
+CONFIG_SND_ES1968=m
+CONFIG_SND_FM801=m
+CONFIG_SND_FM801_TEA575X_BOOL=y
+CONFIG_SND_FM801_TEA575X=m
+CONFIG_SND_HDA_INTEL=m
+CONFIG_SND_HDSP=m
+CONFIG_SND_HDSPM=m
+CONFIG_SND_ICE1712=m
+CONFIG_SND_ICE1724=m
+CONFIG_SND_INTEL8X0=m
+CONFIG_SND_INTEL8X0M=m
+CONFIG_SND_KORG1212=m
+CONFIG_SND_MAESTRO3=m
+CONFIG_SND_MIXART=m
+CONFIG_SND_NM256=m
+CONFIG_SND_PCXHR=m
+CONFIG_SND_RIPTIDE=m
+CONFIG_SND_RME32=m
+CONFIG_SND_RME96=m
+CONFIG_SND_RME9652=m
+CONFIG_SND_SONICVIBES=m
+CONFIG_SND_TRIDENT=m
+CONFIG_SND_VIA82XX=m
+CONFIG_SND_VIA82XX_MODEM=m
+CONFIG_SND_VX222=m
+CONFIG_SND_YMFPCI=m
+
+#
+# USB devices
+#
+CONFIG_SND_USB_AUDIO=m
+
+#
+# PCMCIA devices
+#
+# CONFIG_SND_VXPOCKET is not set
+# CONFIG_SND_PDAUDIOCF is not set
+
+#
+# Open Sound System
+#
+# CONFIG_SOUND_PRIME is not set
+
+#
+# USB support
+#
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB_ARCH_HAS_EHCI=y
+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_SUSPEND is not set
+# CONFIG_USB_OTG is not set
+
+#
+# USB Host Controller Drivers
+#
+CONFIG_USB_EHCI_HCD=m
+CONFIG_USB_EHCI_SPLIT_ISO=y
+CONFIG_USB_EHCI_ROOT_HUB_TT=y
+CONFIG_USB_EHCI_TT_NEWSCHED=y
+CONFIG_USB_ISP116X_HCD=m
+CONFIG_USB_OHCI_HCD=m
+# CONFIG_USB_OHCI_BIG_ENDIAN is not set
+CONFIG_USB_OHCI_LITTLE_ENDIAN=y
+CONFIG_USB_UHCI_HCD=m
+CONFIG_USB_SL811_HCD=m
+CONFIG_USB_SL811_CS=m
+
+#
+# USB Device Class drivers
+#
+CONFIG_USB_ACM=m
+CONFIG_USB_PRINTER=m
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+#
+
+#
+# may also be needed; see USB_STORAGE Help for more information
+#
+CONFIG_USB_STORAGE=m
+# CONFIG_USB_STORAGE_DEBUG is not set
+CONFIG_USB_STORAGE_DATAFAB=y
+CONFIG_USB_STORAGE_FREECOM=y
+CONFIG_USB_STORAGE_ISD200=y
+CONFIG_USB_STORAGE_DPCM=y
+CONFIG_USB_STORAGE_USBAT=y
+CONFIG_USB_STORAGE_SDDR09=y
+CONFIG_USB_STORAGE_SDDR55=y
+CONFIG_USB_STORAGE_JUMPSHOT=y
+CONFIG_USB_STORAGE_ALAUDA=y
+CONFIG_USB_LIBUSUAL=y
+
+#
+# USB Input Devices
+#
+CONFIG_USB_HID=y
+CONFIG_USB_HIDINPUT=y
+# CONFIG_USB_HIDINPUT_POWERBOOK is not set
+CONFIG_HID_FF=y
+CONFIG_HID_PID=y
+CONFIG_LOGITECH_FF=y
+CONFIG_THRUSTMASTER_FF=y
+CONFIG_USB_HIDDEV=y
+CONFIG_USB_AIPTEK=m
+CONFIG_USB_WACOM=m
+CONFIG_USB_ACECAD=m
+CONFIG_USB_KBTAB=m
+CONFIG_USB_POWERMATE=m
+CONFIG_USB_TOUCHSCREEN=m
+CONFIG_USB_TOUCHSCREEN_EGALAX=y
+CONFIG_USB_TOUCHSCREEN_PANJIT=y
+CONFIG_USB_TOUCHSCREEN_3M=y
+CONFIG_USB_TOUCHSCREEN_ITM=y
+# CONFIG_USB_YEALINK is not set
+CONFIG_USB_XPAD=m
+CONFIG_USB_ATI_REMOTE=m
+CONFIG_USB_ATI_REMOTE2=m
+CONFIG_USB_KEYSPAN_REMOTE=m
+CONFIG_USB_APPLETOUCH=m
+
+#
+# USB Imaging devices
+#
+CONFIG_USB_MDC800=m
+CONFIG_USB_MICROTEK=m
+
+#
+# USB Network Adapters
+#
+CONFIG_USB_CATC=m
+CONFIG_USB_KAWETH=m
+CONFIG_USB_PEGASUS=m
+CONFIG_USB_RTL8150=m
+CONFIG_USB_USBNET=m
+CONFIG_USB_NET_AX8817X=m
+CONFIG_USB_NET_CDCETHER=m
+CONFIG_USB_NET_GL620A=m
+CONFIG_USB_NET_NET1080=m
+CONFIG_USB_NET_PLUSB=m
+CONFIG_USB_NET_RNDIS_HOST=m
+CONFIG_USB_NET_CDC_SUBSET=m
+CONFIG_USB_ALI_M5632=y
+CONFIG_USB_AN2720=y
+CONFIG_USB_BELKIN=y
+CONFIG_USB_ARMLINUX=y
+CONFIG_USB_EPSON2888=y
+CONFIG_USB_NET_ZAURUS=m
+CONFIG_USB_MON=y
+
+#
+# USB port drivers
+#
+CONFIG_USB_USS720=m
+
+#
+# USB Serial Converter support
+#
+CONFIG_USB_SERIAL=m
+CONFIG_USB_SERIAL_GENERIC=y
+CONFIG_USB_SERIAL_AIRPRIME=m
+CONFIG_USB_SERIAL_ARK3116=m
+CONFIG_USB_SERIAL_BELKIN=m
+CONFIG_USB_SERIAL_WHITEHEAT=m
+CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m
+CONFIG_USB_SERIAL_CP2101=m
+CONFIG_USB_SERIAL_CYPRESS_M8=m
+CONFIG_USB_SERIAL_EMPEG=m
+CONFIG_USB_SERIAL_FTDI_SIO=m
+CONFIG_USB_SERIAL_FUNSOFT=m
+CONFIG_USB_SERIAL_VISOR=m
+CONFIG_USB_SERIAL_IPAQ=m
+CONFIG_USB_SERIAL_IR=m
+CONFIG_USB_SERIAL_EDGEPORT=m
+CONFIG_USB_SERIAL_EDGEPORT_TI=m
+CONFIG_USB_SERIAL_GARMIN=m
+CONFIG_USB_SERIAL_IPW=m
+CONFIG_USB_SERIAL_KEYSPAN_PDA=m
+CONFIG_USB_SERIAL_KEYSPAN=m
+CONFIG_USB_SERIAL_KEYSPAN_MPR=y
+CONFIG_USB_SERIAL_KEYSPAN_USA28=y
+CONFIG_USB_SERIAL_KEYSPAN_USA28X=y
+CONFIG_USB_SERIAL_KEYSPAN_USA28XA=y
+CONFIG_USB_SERIAL_KEYSPAN_USA28XB=y
+CONFIG_USB_SERIAL_KEYSPAN_USA19=y
+CONFIG_USB_SERIAL_KEYSPAN_USA18X=y
+CONFIG_USB_SERIAL_KEYSPAN_USA19W=y
+CONFIG_USB_SERIAL_KEYSPAN_USA19QW=y
+CONFIG_USB_SERIAL_KEYSPAN_USA19QI=y
+CONFIG_USB_SERIAL_KEYSPAN_USA49W=y
+CONFIG_USB_SERIAL_KEYSPAN_USA49WLC=y
+CONFIG_USB_SERIAL_KLSI=m
+CONFIG_USB_SERIAL_KOBIL_SCT=m
+CONFIG_USB_SERIAL_MCT_U232=m
+CONFIG_USB_SERIAL_NAVMAN=m
+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=m
+CONFIG_USB_SERIAL_TI=m
+CONFIG_USB_SERIAL_CYBERJACK=m
+CONFIG_USB_SERIAL_XIRCOM=m
+CONFIG_USB_SERIAL_OPTION=m
+CONFIG_USB_SERIAL_OMNINET=m
+CONFIG_USB_EZUSB=y
+
+#
+# USB Miscellaneous drivers
+#
+CONFIG_USB_EMI62=m
+CONFIG_USB_EMI26=m
+CONFIG_USB_AUERSWALD=m
+CONFIG_USB_RIO500=m
+CONFIG_USB_LEGOTOWER=m
+CONFIG_USB_LCD=m
+CONFIG_USB_LED=m
+# CONFIG_USB_CYPRESS_CY7C63 is not set
+# CONFIG_USB_CYTHERM is not set
+CONFIG_USB_PHIDGETKIT=m
+CONFIG_USB_PHIDGETSERVO=m
+CONFIG_USB_IDMOUSE=m
+CONFIG_USB_APPLEDISPLAY=m
+CONFIG_USB_SISUSBVGA=m
+CONFIG_USB_SISUSBVGA_CON=y
+CONFIG_USB_LD=m
+CONFIG_USB_TEST=m
+
+#
+# USB DSL modem support
+#
+CONFIG_USB_ATM=m
+CONFIG_USB_SPEEDTOUCH=m
+CONFIG_USB_CXACRU=m
+CONFIG_USB_UEAGLEATM=m
+CONFIG_USB_XUSBATM=m
+
+#
+# USB Gadget Support
+#
+# CONFIG_USB_GADGET is not set
+
+#
+# MMC/SD Card support
+#
+CONFIG_MMC=m
+# CONFIG_MMC_DEBUG is not set
+CONFIG_MMC_BLOCK=m
+CONFIG_MMC_SDHCI=m
+
+#
+# LED devices
+#
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+
+#
+# LED drivers
+#
+
+#
+# LED Triggers
+#
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_LEDS_TRIGGER_TIMER=m
+CONFIG_LEDS_TRIGGER_IDE_DISK=y
+CONFIG_LEDS_TRIGGER_HEARTBEAT=m
+
+#
+# InfiniBand support
+#
+CONFIG_INFINIBAND=m
+CONFIG_INFINIBAND_USER_MAD=m
+CONFIG_INFINIBAND_USER_ACCESS=m
+CONFIG_INFINIBAND_ADDR_TRANS=y
+CONFIG_INFINIBAND_MTHCA=m
+CONFIG_INFINIBAND_MTHCA_DEBUG=y
+CONFIG_IPATH_CORE=m
+CONFIG_INFINIBAND_IPATH=m
+CONFIG_INFINIBAND_IPOIB=m
+CONFIG_INFINIBAND_IPOIB_DEBUG=y
+CONFIG_INFINIBAND_IPOIB_DEBUG_DATA=y
+CONFIG_INFINIBAND_SRP=m
+CONFIG_INFINIBAND_ISER=m
+
+#
+# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
+#
+
+#
+# Real Time Clock
+#
+CONFIG_RTC_LIB=m
+CONFIG_RTC_CLASS=m
+
+#
+# RTC interfaces
+#
+CONFIG_RTC_INTF_SYSFS=m
+CONFIG_RTC_INTF_PROC=m
+CONFIG_RTC_INTF_DEV=m
+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
+
+#
+# RTC drivers
+#
+CONFIG_RTC_DRV_X1205=m
+CONFIG_RTC_DRV_DS1307=m
+CONFIG_RTC_DRV_DS1553=m
+CONFIG_RTC_DRV_ISL1208=m
+CONFIG_RTC_DRV_DS1672=m
+CONFIG_RTC_DRV_DS1742=m
+CONFIG_RTC_DRV_PCF8563=m
+CONFIG_RTC_DRV_PCF8583=m
+CONFIG_RTC_DRV_RS5C372=m
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_TEST is not set
+CONFIG_RTC_DRV_V3020=m
+
+#
+# DMA Engine support
+#
+CONFIG_DMA_ENGINE=y
+
+#
+# DMA Clients
+#
+CONFIG_NET_DMA=y
+
+#
+# DMA Devices
+#
+CONFIG_INTEL_IOATDMA=m
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+CONFIG_EXT2_FS_POSIX_ACL=y
+CONFIG_EXT2_FS_SECURITY=y
+CONFIG_EXT2_FS_XIP=y
+CONFIG_FS_XIP=y
+CONFIG_EXT3_FS=m
+CONFIG_EXT3_FS_XATTR=y
+CONFIG_EXT3_FS_POSIX_ACL=y
+CONFIG_EXT3_FS_SECURITY=y
+CONFIG_JBD=m
+# CONFIG_JBD_DEBUG is not set
+CONFIG_FS_MBCACHE=y
+CONFIG_REISERFS_FS=m
+# CONFIG_REISERFS_CHECK is not set
+CONFIG_REISERFS_PROC_INFO=y
+CONFIG_REISERFS_FS_XATTR=y
+CONFIG_REISERFS_FS_POSIX_ACL=y
+CONFIG_REISERFS_FS_SECURITY=y
+CONFIG_JFS_FS=m
+CONFIG_JFS_POSIX_ACL=y
+CONFIG_JFS_SECURITY=y
+# CONFIG_JFS_DEBUG is not set
+# CONFIG_JFS_STATISTICS is not set
+CONFIG_FS_POSIX_ACL=y
+CONFIG_XFS_FS=m
+CONFIG_XFS_QUOTA=y
+CONFIG_XFS_SECURITY=y
+CONFIG_XFS_POSIX_ACL=y
+# CONFIG_XFS_RT is not set
+CONFIG_OCFS2_FS=m
+# CONFIG_OCFS2_DEBUG_MASKLOG is not set
+CONFIG_MINIX_FS=m
+CONFIG_ROMFS_FS=m
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+CONFIG_QUOTA=y
+# CONFIG_QFMT_V1 is not set
+CONFIG_QFMT_V2=y
+CONFIG_QUOTACTL=y
+CONFIG_DNOTIFY=y
+CONFIG_AUTOFS_FS=m
+CONFIG_AUTOFS4_FS=m
+CONFIG_FUSE_FS=m
+
+#
+# Caches
+#
+CONFIG_FSCACHE=m
+
+#
+# CD-ROM/DVD Filesystems
+#
+CONFIG_ISO9660_FS=y
+CONFIG_JOLIET=y
+CONFIG_ZISOFS=y
+CONFIG_ZISOFS_FS=y
+CONFIG_UDF_FS=m
+CONFIG_UDF_NLS=y
+CONFIG_CACHEFILES=m
+CONFIG_CACHEFILES_DEBUG=y
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=m
+CONFIG_MSDOS_FS=m
+CONFIG_VFAT_FS=m
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="ascii"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+CONFIG_HUGETLBFS=y
+CONFIG_HUGETLB_PAGE=y
+CONFIG_RAMFS=y
+CONFIG_CONFIGFS_FS=m
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+CONFIG_AFFS_FS=m
+CONFIG_HFS_FS=m
+CONFIG_HFSPLUS_FS=m
+CONFIG_BEFS_FS=m
+# CONFIG_BEFS_DEBUG is not set
+CONFIG_BFS_FS=m
+CONFIG_EFS_FS=m
+CONFIG_CRAMFS=m
+CONFIG_SQUASHFS=m
+# CONFIG_SQUASHFS_EMBEDDED is not set
+CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3
+# CONFIG_SQUASHFS_VMALLOC is not set
+CONFIG_VXFS_FS=m
+# CONFIG_HPFS_FS is not set
+CONFIG_QNX4FS_FS=m
+CONFIG_SYSV_FS=m
+CONFIG_UFS_FS=m
+# CONFIG_UFS_FS_WRITE is not set
+# CONFIG_UFS_DEBUG is not set
+
+#
+# Network File Systems
+#
+CONFIG_NFS_FS=m
+CONFIG_NFS_V3=y
+CONFIG_NFS_V3_ACL=y
+CONFIG_NFS_V4=y
+CONFIG_NFS_FSCACHE=y
+CONFIG_NFS_DIRECTIO=y
+CONFIG_NFSD=m
+CONFIG_NFSD_V2_ACL=y
+CONFIG_NFSD_V3=y
+CONFIG_NFSD_V3_ACL=y
+CONFIG_NFSD_V4=y
+CONFIG_NFSD_TCP=y
+CONFIG_LOCKD=m
+CONFIG_LOCKD_V4=y
+CONFIG_EXPORTFS=m
+CONFIG_NFS_ACL_SUPPORT=m
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=m
+CONFIG_SUNRPC_GSS=m
+CONFIG_RPCSEC_GSS_KRB5=m
+CONFIG_RPCSEC_GSS_SPKM3=m
+# CONFIG_SMB_FS is not set
+CONFIG_CIFS=m
+# CONFIG_CIFS_STATS is not set
+CONFIG_CIFS_WEAK_PW_HASH=y
+CONFIG_CIFS_XATTR=y
+CONFIG_CIFS_POSIX=y
+# CONFIG_CIFS_DEBUG2 is not set
+# CONFIG_CIFS_EXPERIMENTAL is not set
+CONFIG_NCP_FS=m
+CONFIG_NCPFS_PACKET_SIGNING=y
+CONFIG_NCPFS_IOCTL_LOCKING=y
+CONFIG_NCPFS_STRONG=y
+CONFIG_NCPFS_NFS_NS=y
+CONFIG_NCPFS_OS2_NS=y
+CONFIG_NCPFS_SMALLDOS=y
+CONFIG_NCPFS_NLS=y
+CONFIG_NCPFS_EXTRAS=y
+CONFIG_CODA_FS=m
+# CONFIG_CODA_FS_OLD_API is not set
+# CONFIG_AFS_FS is not set
+CONFIG_9P_FS=m
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+CONFIG_OSF_PARTITION=y
+CONFIG_AMIGA_PARTITION=y
+# CONFIG_ATARI_PARTITION is not set
+CONFIG_MAC_PARTITION=y
+CONFIG_MSDOS_PARTITION=y
+CONFIG_BSD_DISKLABEL=y
+CONFIG_MINIX_SUBPARTITION=y
+CONFIG_SOLARIS_X86_PARTITION=y
+CONFIG_UNIXWARE_DISKLABEL=y
+# CONFIG_LDM_PARTITION is not set
+CONFIG_SGI_PARTITION=y
+# CONFIG_ULTRIX_PARTITION is not set
+CONFIG_SUN_PARTITION=y
+CONFIG_KARMA_PARTITION=y
+CONFIG_EFI_PARTITION=y
+
+#
+# Native Language Support
+#
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="utf8"
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_CODEPAGE_737=m
+CONFIG_NLS_CODEPAGE_775=m
+CONFIG_NLS_CODEPAGE_850=m
+CONFIG_NLS_CODEPAGE_852=m
+CONFIG_NLS_CODEPAGE_855=m
+CONFIG_NLS_CODEPAGE_857=m
+CONFIG_NLS_CODEPAGE_860=m
+CONFIG_NLS_CODEPAGE_861=m
+CONFIG_NLS_CODEPAGE_862=m
+CONFIG_NLS_CODEPAGE_863=m
+CONFIG_NLS_CODEPAGE_864=m
+CONFIG_NLS_CODEPAGE_865=m
+CONFIG_NLS_CODEPAGE_866=m
+CONFIG_NLS_CODEPAGE_869=m
+CONFIG_NLS_CODEPAGE_936=m
+CONFIG_NLS_CODEPAGE_950=m
+CONFIG_NLS_CODEPAGE_932=m
+CONFIG_NLS_CODEPAGE_949=m
+CONFIG_NLS_CODEPAGE_874=m
+CONFIG_NLS_ISO8859_8=m
+CONFIG_NLS_CODEPAGE_1250=m
+CONFIG_NLS_CODEPAGE_1251=m
+CONFIG_NLS_ASCII=y
+CONFIG_NLS_ISO8859_1=m
+CONFIG_NLS_ISO8859_2=m
+CONFIG_NLS_ISO8859_3=m
+CONFIG_NLS_ISO8859_4=m
+CONFIG_NLS_ISO8859_5=m
+CONFIG_NLS_ISO8859_6=m
+CONFIG_NLS_ISO8859_7=m
+CONFIG_NLS_ISO8859_9=m
+CONFIG_NLS_ISO8859_13=m
+CONFIG_NLS_ISO8859_14=m
+CONFIG_NLS_ISO8859_15=m
+CONFIG_NLS_KOI8_R=m
+CONFIG_NLS_KOI8_U=m
+CONFIG_NLS_UTF8=m
+
+#
+# Library routines
+#
+CONFIG_CRC_CCITT=m
+CONFIG_CRC16=m
+CONFIG_CRC32=y
+CONFIG_LIBCRC32C=m
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=m
+CONFIG_GENERIC_ALLOCATOR=y
+CONFIG_TEXTSEARCH=y
+CONFIG_TEXTSEARCH_KMP=m
+CONFIG_TEXTSEARCH_BM=m
+CONFIG_TEXTSEARCH_FSM=m
+CONFIG_PLIST=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_GENERIC_PENDING_IRQ=y
+CONFIG_IRQ_PER_CPU=y
+
+#
+# HP Simulator drivers
+#
+# CONFIG_HP_SIMETH is not set
+# CONFIG_HP_SIMSERIAL is not set
+# CONFIG_HP_SIMSCSI is not set
+
+#
+# Instrumentation Support
+#
+CONFIG_PROFILING=y
+CONFIG_OPROFILE=m
+CONFIG_KPROBES=y
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_UNUSED_SYMBOLS is not set
+CONFIG_DEBUG_KERNEL=y
+CONFIG_LOG_BUF_SHIFT=17
+CONFIG_DETECT_SOFTLOCKUP=y
+CONFIG_SCHEDSTATS=y
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
+CONFIG_DEBUG_SPINLOCK=y
+# CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_RWSEMS is not set
+CONFIG_DEBUG_SPINLOCK_SLEEP=y
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+# CONFIG_DEBUG_KOBJECT is not set
+CONFIG_DEBUG_INFO=y
+CONFIG_DEBUG_FS=y
+# CONFIG_DEBUG_VM is not set
+CONFIG_DEBUG_LIST=y
+# CONFIG_FORCED_INLINING is not set
+CONFIG_BOOT_DELAY=y
+# CONFIG_RCU_TORTURE_TEST is not set
+CONFIG_IA64_GRANULE_16MB=y
+# CONFIG_IA64_GRANULE_64MB is not set
+# CONFIG_IA64_PRINT_HAZARDS is not set
+# CONFIG_DISABLE_VHPT is not set
+# CONFIG_IA64_DEBUG_CMPXCHG is not set
+# CONFIG_IA64_DEBUG_IRQ is not set
+
+#
+# Security options
+#
+CONFIG_KEYS=y
+CONFIG_KEYS_DEBUG_PROC_KEYS=y
+CONFIG_SECURITY=y
+CONFIG_SECURITY_NETWORK=y
+# CONFIG_SECURITY_NETWORK_XFRM is not set
+CONFIG_SECURITY_CAPABILITIES=y
+# CONFIG_SECURITY_ROOTPLUG is not set
+# CONFIG_SECURITY_SECLVL is not set
+CONFIG_SECURITY_SELINUX=y
+CONFIG_SECURITY_SELINUX_BOOTPARAM=y
+CONFIG_SECURITY_SELINUX_BOOTPARAM_VALUE=1
+CONFIG_SECURITY_SELINUX_DISABLE=y
+CONFIG_SECURITY_SELINUX_DEVELOP=y
+CONFIG_SECURITY_SELINUX_AVC_STATS=y
+CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE=1
+# CONFIG_SECURITY_SELINUX_ENABLE_SECMARK_DEFAULT is not set
+# CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX is not set
+
+#
+# Cryptographic options
+#
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_NULL=m
+CONFIG_CRYPTO_MD4=m
+CONFIG_CRYPTO_MD5=m
+CONFIG_CRYPTO_SHA1=y
+CONFIG_CRYPTO_SHA256=m
+CONFIG_CRYPTO_SHA512=m
+CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_TGR192=m
+CONFIG_CRYPTO_DES=m
+CONFIG_CRYPTO_BLOWFISH=m
+CONFIG_CRYPTO_TWOFISH=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_TEST is not set
+CONFIG_CRYPTO_SIGNATURE=y
+CONFIG_CRYPTO_SIGNATURE_DSA=y
+CONFIG_CRYPTO_MPILIB=y
+
+#
+# Hardware crypto devices
+#
diff --git a/configs/kernel-2.6.18-ppc-smp.config b/configs/kernel-2.6.18-ppc-smp.config
new file mode 100644
index 000000000..66147ea3d
--- /dev/null
+++ b/configs/kernel-2.6.18-ppc-smp.config
@@ -0,0 +1,3204 @@
+# powerpc
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.18.2-rc1
+# Mon Nov 13 09:44:41 2006
+#
+# CONFIG_PPC64 is not set
+CONFIG_PPC32=y
+CONFIG_PPC_MERGE=y
+CONFIG_MMU=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_IRQ_PER_CPU=y
+CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_PPC=y
+CONFIG_EARLY_PRINTK=y
+CONFIG_GENERIC_NVRAM=y
+CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
+CONFIG_ARCH_MAY_HAVE_PC_FDC=y
+CONFIG_PPC_OF=y
+CONFIG_PPC_UDBG_16550=y
+CONFIG_GENERIC_TBSYNC=y
+CONFIG_AUDIT_ARCH=y
+# CONFIG_DEFAULT_UIMAGE is not set
+
+#
+# Processor support
+#
+CONFIG_CLASSIC32=y
+# CONFIG_PPC_52xx is not set
+# CONFIG_PPC_82xx is not set
+# CONFIG_PPC_83xx is not set
+# CONFIG_PPC_85xx is not set
+# CONFIG_PPC_86xx 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_PPC_FPU=y
+CONFIG_ALTIVEC=y
+CONFIG_PPC_STD_MMU=y
+CONFIG_PPC_STD_MMU_32=y
+CONFIG_SMP=y
+CONFIG_NR_CPUS=4
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_BSD_PROCESS_ACCT=y
+# CONFIG_BSD_PROCESS_ACCT_V3 is not set
+CONFIG_TASKSTATS=y
+CONFIG_TASK_DELAY_ACCT=y
+CONFIG_AUDIT=y
+CONFIG_AUDITSYSCALL=y
+# CONFIG_IKCONFIG is not set
+CONFIG_CPUSETS=y
+CONFIG_RELAY=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+# CONFIG_EMBEDDED is not set
+CONFIG_SYSCTL=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
+CONFIG_KALLSYMS_EXTRA_PASS=y
+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=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+CONFIG_MODULE_SIG=y
+# CONFIG_MODULE_SIG_FORCE is not set
+CONFIG_KMOD=y
+CONFIG_STOP_MACHINE=y
+
+#
+# Process debugging support
+#
+CONFIG_UTRACE=y
+CONFIG_PTRACE=y
+
+#
+# Block layer
+#
+CONFIG_LBD=y
+CONFIG_BLK_DEV_IO_TRACE=y
+CONFIG_LSF=y
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_DEFAULT_AS is not set
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+
+#
+# Platform support
+#
+CONFIG_PPC_MULTIPLATFORM=y
+# CONFIG_PPC_ISERIES is not set
+# CONFIG_EMBEDDED6xx is not set
+# CONFIG_APUS is not set
+CONFIG_PPC_CHRP=y
+CONFIG_PPC_PMAC=y
+# CONFIG_PPC_CELL is not set
+# CONFIG_PPC_CELL_NATIVE is not set
+# CONFIG_UDBG_RTAS_CONSOLE is not set
+# CONFIG_MAMBO is not set
+CONFIG_PPC_RTAS=y
+# CONFIG_RTAS_ERROR_LOGGING is not set
+# CONFIG_RTAS_PROC is not set
+# CONFIG_MMIO_NVRAM is not set
+CONFIG_PPC_MPC106=y
+# CONFIG_PPC_970_NAP is not set
+CONFIG_CPU_FREQ=y
+CONFIG_CPU_FREQ_TABLE=y
+CONFIG_CPU_FREQ_DEBUG=y
+CONFIG_CPU_FREQ_STAT=m
+CONFIG_CPU_FREQ_STAT_DETAILS=y
+# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set
+CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE=y
+CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
+CONFIG_CPU_FREQ_GOV_POWERSAVE=m
+CONFIG_CPU_FREQ_GOV_USERSPACE=y
+CONFIG_CPU_FREQ_GOV_ONDEMAND=m
+CONFIG_CPU_FREQ_GOV_CONSERVATIVE=m
+CONFIG_CPU_FREQ_PMAC=y
+# CONFIG_PPC601_SYNC_FIX is not set
+CONFIG_TAU=y
+# CONFIG_TAU_INT is not set
+CONFIG_TAU_AVERAGE=y
+# CONFIG_WANT_EARLY_SERIAL is not set
+CONFIG_MPIC=y
+
+#
+# Kernel options
+#
+CONFIG_HIGHMEM=y
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
+# CONFIG_PREEMPT_NONE is not set
+CONFIG_PREEMPT_VOLUNTARY=y
+# CONFIG_PREEMPT is not set
+CONFIG_PREEMPT_BKL=y
+CONFIG_BINFMT_ELF=y
+CONFIG_BINFMT_MISC=y
+# CONFIG_HOTPLUG_CPU is not set
+CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
+# CONFIG_KEXEC is not set
+CONFIG_IRQ_ALL_CPUS=y
+CONFIG_ARCH_FLATMEM_ENABLE=y
+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=y
+CONFIG_PROC_DEVICETREE=y
+# CONFIG_CMDLINE_BOOL is not set
+CONFIG_PM=y
+CONFIG_PM_LEGACY=y
+# CONFIG_PM_DEBUG is not set
+# CONFIG_SECCOMP is not set
+CONFIG_ISA_DMA_API=y
+
+#
+# Bus options
+#
+CONFIG_ISA=y
+CONFIG_GENERIC_ISA_DMA=y
+# CONFIG_MPIC_WEIRD is not set
+CONFIG_PPC_I8259=y
+CONFIG_PPC_INDIRECT_PCI=y
+CONFIG_PCI=y
+CONFIG_PCI_DOMAINS=y
+CONFIG_PCIEPORTBUS=y
+# CONFIG_PCI_DEBUG is not set
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+CONFIG_PCCARD=y
+# CONFIG_PCMCIA_DEBUG is not set
+CONFIG_PCMCIA=y
+CONFIG_PCMCIA_LOAD_CIS=y
+CONFIG_PCMCIA_IOCTL=y
+CONFIG_CARDBUS=y
+
+#
+# PC-card bridges
+#
+CONFIG_YENTA=y
+CONFIG_YENTA_O2=y
+CONFIG_YENTA_RICOH=y
+CONFIG_YENTA_TI=y
+CONFIG_YENTA_ENE_TUNE=y
+CONFIG_YENTA_TOSHIBA=y
+CONFIG_PD6729=m
+CONFIG_I82092=m
+# CONFIG_I82365 is not set
+# CONFIG_TCIC is not set
+CONFIG_PCMCIA_PROBE=y
+CONFIG_PCCARD_NONSTATIC=y
+
+#
+# PCI Hotplug Support
+#
+# CONFIG_HOTPLUG_PCI is not set
+
+#
+# Advanced setup
+#
+CONFIG_ADVANCED_OPTIONS=y
+# CONFIG_HIGHMEM_START_BOOL is not set
+CONFIG_HIGHMEM_START=0xfe000000
+# CONFIG_LOWMEM_SIZE_BOOL is not set
+CONFIG_LOWMEM_SIZE=0x30000000
+# CONFIG_KERNEL_START_BOOL is not set
+CONFIG_KERNEL_START=0xc0000000
+# CONFIG_TASK_SIZE_BOOL is not set
+CONFIG_TASK_SIZE=0x80000000
+CONFIG_BOOT_LOAD=0x00800000
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+# CONFIG_NETDEBUG is not set
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=y
+CONFIG_NET_KEY=m
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_ASK_IP_FIB_HASH=y
+# 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
+# CONFIG_IP_PNP is not set
+CONFIG_NET_IPIP=m
+CONFIG_NET_IPGRE=m
+CONFIG_NET_IPGRE_BROADCAST=y
+CONFIG_IP_MROUTE=y
+CONFIG_IP_PIMSM_V1=y
+CONFIG_IP_PIMSM_V2=y
+# CONFIG_ARPD is not set
+CONFIG_SYN_COOKIES=y
+CONFIG_INET_AH=m
+CONFIG_INET_ESP=m
+CONFIG_INET_IPCOMP=m
+CONFIG_INET_XFRM_TUNNEL=m
+CONFIG_INET_TUNNEL=m
+CONFIG_INET_XFRM_MODE_TRANSPORT=m
+CONFIG_INET_XFRM_MODE_TUNNEL=m
+CONFIG_INET_DIAG=m
+CONFIG_INET_TCP_DIAG=m
+CONFIG_TCP_CONG_ADVANCED=y
+
+#
+# TCP congestion control
+#
+CONFIG_TCP_CONG_BIC=y
+CONFIG_TCP_CONG_CUBIC=m
+CONFIG_TCP_CONG_WESTWOOD=m
+CONFIG_TCP_CONG_HTCP=m
+CONFIG_TCP_CONG_HSTCP=m
+CONFIG_TCP_CONG_HYBLA=m
+CONFIG_TCP_CONG_VEGAS=m
+CONFIG_TCP_CONG_SCALABLE=m
+CONFIG_TCP_CONG_LP=m
+CONFIG_TCP_CONG_VENO=m
+
+#
+# IP: Virtual Server Configuration
+#
+CONFIG_IP_VS=m
+# CONFIG_IP_VS_DEBUG is not set
+CONFIG_IP_VS_TAB_BITS=12
+
+#
+# IPVS transport protocol load balancing support
+#
+CONFIG_IP_VS_PROTO_TCP=y
+CONFIG_IP_VS_PROTO_UDP=y
+CONFIG_IP_VS_PROTO_ESP=y
+CONFIG_IP_VS_PROTO_AH=y
+
+#
+# IPVS scheduler
+#
+CONFIG_IP_VS_RR=m
+CONFIG_IP_VS_WRR=m
+CONFIG_IP_VS_LC=m
+CONFIG_IP_VS_WLC=m
+CONFIG_IP_VS_LBLC=m
+CONFIG_IP_VS_LBLCR=m
+CONFIG_IP_VS_DH=m
+CONFIG_IP_VS_SH=m
+CONFIG_IP_VS_SED=m
+CONFIG_IP_VS_NQ=m
+
+#
+# IPVS application helper
+#
+CONFIG_IP_VS_FTP=m
+CONFIG_IPV6=m
+CONFIG_IPV6_PRIVACY=y
+CONFIG_IPV6_ROUTER_PREF=y
+CONFIG_IPV6_ROUTE_INFO=y
+CONFIG_INET6_AH=m
+CONFIG_INET6_ESP=m
+CONFIG_INET6_IPCOMP=m
+CONFIG_INET6_XFRM_TUNNEL=m
+CONFIG_INET6_TUNNEL=m
+CONFIG_INET6_XFRM_MODE_TRANSPORT=m
+CONFIG_INET6_XFRM_MODE_TUNNEL=m
+CONFIG_IPV6_TUNNEL=m
+CONFIG_NETWORK_SECMARK=y
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_DEBUG is not set
+CONFIG_BRIDGE_NETFILTER=y
+
+#
+# Core Netfilter Configuration
+#
+CONFIG_NETFILTER_NETLINK=m
+CONFIG_NETFILTER_NETLINK_QUEUE=m
+CONFIG_NETFILTER_NETLINK_LOG=m
+CONFIG_NETFILTER_XTABLES=m
+CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
+CONFIG_NETFILTER_XT_TARGET_CONNMARK=m
+CONFIG_NETFILTER_XT_TARGET_MARK=m
+CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
+CONFIG_NETFILTER_XT_TARGET_NOTRACK=m
+CONFIG_NETFILTER_XT_TARGET_SECMARK=m
+CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=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_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_PHYSDEV=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
+
+#
+# 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=m
+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_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_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_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
+CONFIG_IP_NF_ARPTABLES=m
+CONFIG_IP_NF_ARPFILTER=m
+CONFIG_IP_NF_ARP_MANGLE=m
+
+#
+# IPv6: Netfilter Configuration (EXPERIMENTAL)
+#
+CONFIG_IP6_NF_QUEUE=m
+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_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
+
+#
+# DECnet: Netfilter Configuration
+#
+# CONFIG_DECNET_NF_GRABULATOR is not set
+
+#
+# Bridge: Netfilter Configuration
+#
+CONFIG_BRIDGE_NF_EBTABLES=m
+CONFIG_BRIDGE_EBT_BROUTE=m
+CONFIG_BRIDGE_EBT_T_FILTER=m
+CONFIG_BRIDGE_EBT_T_NAT=m
+CONFIG_BRIDGE_EBT_802_3=m
+CONFIG_BRIDGE_EBT_AMONG=m
+CONFIG_BRIDGE_EBT_ARP=m
+CONFIG_BRIDGE_EBT_IP=m
+CONFIG_BRIDGE_EBT_LIMIT=m
+CONFIG_BRIDGE_EBT_MARK=m
+CONFIG_BRIDGE_EBT_PKTTYPE=m
+CONFIG_BRIDGE_EBT_STP=m
+CONFIG_BRIDGE_EBT_VLAN=m
+CONFIG_BRIDGE_EBT_ARPREPLY=m
+CONFIG_BRIDGE_EBT_DNAT=m
+CONFIG_BRIDGE_EBT_MARK_T=m
+CONFIG_BRIDGE_EBT_REDIRECT=m
+CONFIG_BRIDGE_EBT_SNAT=m
+CONFIG_BRIDGE_EBT_LOG=m
+CONFIG_BRIDGE_EBT_ULOG=m
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+CONFIG_IP_DCCP=m
+CONFIG_INET_DCCP_DIAG=m
+CONFIG_IP_DCCP_ACKVEC=y
+
+#
+# DCCP CCIDs Configuration (EXPERIMENTAL)
+#
+CONFIG_IP_DCCP_CCID2=m
+CONFIG_IP_DCCP_CCID3=m
+CONFIG_IP_DCCP_TFRC_LIB=m
+
+#
+# DCCP Kernel Hacking
+#
+# CONFIG_IP_DCCP_DEBUG is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+CONFIG_IP_SCTP=m
+# CONFIG_SCTP_DBG_MSG is not set
+# CONFIG_SCTP_DBG_OBJCNT is not set
+# CONFIG_SCTP_HMAC_NONE is not set
+# CONFIG_SCTP_HMAC_SHA1 is not set
+CONFIG_SCTP_HMAC_MD5=y
+
+#
+# TIPC Configuration (EXPERIMENTAL)
+#
+CONFIG_TIPC=m
+# CONFIG_TIPC_ADVANCED is not set
+# CONFIG_TIPC_DEBUG is not set
+CONFIG_ATM=m
+CONFIG_ATM_CLIP=m
+# CONFIG_ATM_CLIP_NO_ICMP is not set
+CONFIG_ATM_LANE=m
+# CONFIG_ATM_MPOA is not set
+CONFIG_ATM_BR2684=m
+# CONFIG_ATM_BR2684_IPFILTER is not set
+CONFIG_BRIDGE=m
+CONFIG_VLAN_8021Q=m
+CONFIG_DECNET=m
+CONFIG_DECNET_ROUTER=y
+CONFIG_DECNET_ROUTE_FWMARK=y
+CONFIG_LLC=y
+# CONFIG_LLC2 is not set
+CONFIG_IPX=m
+# CONFIG_IPX_INTERN is not set
+CONFIG_ATALK=m
+CONFIG_DEV_APPLETALK=m
+# CONFIG_LTPC is not set
+# CONFIG_COPS is not set
+CONFIG_IPDDP=m
+CONFIG_IPDDP_ENCAP=y
+CONFIG_IPDDP_DECAP=y
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+CONFIG_WAN_ROUTER=m
+
+#
+# QoS and/or fair queueing
+#
+CONFIG_NET_SCHED=y
+# CONFIG_NET_SCH_CLK_JIFFIES is not set
+CONFIG_NET_SCH_CLK_GETTIMEOFDAY=y
+# CONFIG_NET_SCH_CLK_CPU is not set
+
+#
+# Queueing/Scheduling
+#
+CONFIG_NET_SCH_CBQ=m
+CONFIG_NET_SCH_HTB=m
+CONFIG_NET_SCH_HFSC=m
+CONFIG_NET_SCH_ATM=m
+CONFIG_NET_SCH_PRIO=m
+CONFIG_NET_SCH_RED=m
+CONFIG_NET_SCH_SFQ=m
+CONFIG_NET_SCH_TEQL=m
+CONFIG_NET_SCH_TBF=m
+CONFIG_NET_SCH_GRED=m
+CONFIG_NET_SCH_DSMARK=m
+CONFIG_NET_SCH_NETEM=m
+CONFIG_NET_SCH_INGRESS=m
+
+#
+# Classification
+#
+CONFIG_NET_CLS=y
+CONFIG_NET_CLS_BASIC=m
+CONFIG_NET_CLS_TCINDEX=m
+CONFIG_NET_CLS_ROUTE4=m
+CONFIG_NET_CLS_ROUTE=y
+CONFIG_NET_CLS_FW=m
+CONFIG_NET_CLS_U32=m
+CONFIG_CLS_U32_PERF=y
+CONFIG_CLS_U32_MARK=y
+CONFIG_NET_CLS_RSVP=m
+CONFIG_NET_CLS_RSVP6=m
+CONFIG_NET_EMATCH=y
+CONFIG_NET_EMATCH_STACK=32
+CONFIG_NET_EMATCH_CMP=m
+CONFIG_NET_EMATCH_NBYTE=m
+CONFIG_NET_EMATCH_U32=m
+CONFIG_NET_EMATCH_META=m
+CONFIG_NET_EMATCH_TEXT=m
+CONFIG_NET_CLS_ACT=y
+CONFIG_NET_ACT_POLICE=m
+CONFIG_NET_ACT_GACT=m
+CONFIG_GACT_PROB=y
+CONFIG_NET_ACT_MIRRED=m
+CONFIG_NET_ACT_IPT=m
+CONFIG_NET_ACT_PEDIT=m
+CONFIG_NET_ACT_SIMP=m
+CONFIG_NET_CLS_IND=y
+CONFIG_NET_ESTIMATOR=y
+
+#
+# Network testing
+#
+CONFIG_NET_PKTGEN=m
+# CONFIG_HAMRADIO is not set
+CONFIG_IRDA=m
+
+#
+# IrDA protocols
+#
+CONFIG_IRLAN=m
+CONFIG_IRNET=m
+CONFIG_IRCOMM=m
+# CONFIG_IRDA_ULTRA is not set
+
+#
+# IrDA options
+#
+CONFIG_IRDA_CACHE_LAST_LSAP=y
+CONFIG_IRDA_FAST_RR=y
+# CONFIG_IRDA_DEBUG is not set
+
+#
+# Infrared-port device drivers
+#
+
+#
+# SIR device drivers
+#
+CONFIG_IRTTY_SIR=m
+
+#
+# Dongle support
+#
+CONFIG_DONGLE=y
+CONFIG_ESI_DONGLE=m
+CONFIG_ACTISYS_DONGLE=m
+CONFIG_TEKRAM_DONGLE=m
+CONFIG_TOIM3232_DONGLE=m
+CONFIG_LITELINK_DONGLE=m
+CONFIG_MA600_DONGLE=m
+CONFIG_GIRBIL_DONGLE=m
+CONFIG_MCP2120_DONGLE=m
+CONFIG_OLD_BELKIN_DONGLE=m
+CONFIG_ACT200L_DONGLE=m
+
+#
+# Old SIR device drivers
+#
+
+#
+# Old Serial dongle support
+#
+
+#
+# FIR device drivers
+#
+CONFIG_USB_IRDA=m
+CONFIG_SIGMATEL_FIR=m
+CONFIG_NSC_FIR=m
+CONFIG_WINBOND_FIR=m
+CONFIG_TOSHIBA_FIR=m
+CONFIG_SMC_IRCC_FIR=m
+CONFIG_ALI_FIR=m
+CONFIG_VLSI_FIR=m
+CONFIG_VIA_FIR=m
+CONFIG_MCS_FIR=m
+CONFIG_BT=m
+CONFIG_BT_L2CAP=m
+CONFIG_BT_SCO=m
+CONFIG_BT_RFCOMM=m
+CONFIG_BT_RFCOMM_TTY=y
+CONFIG_BT_BNEP=m
+CONFIG_BT_BNEP_MC_FILTER=y
+CONFIG_BT_BNEP_PROTO_FILTER=y
+CONFIG_BT_CMTP=m
+CONFIG_BT_HIDP=m
+
+#
+# Bluetooth device drivers
+#
+CONFIG_BT_HCIUSB=m
+CONFIG_BT_HCIUSB_SCO=y
+CONFIG_BT_HCIUART=m
+CONFIG_BT_HCIUART_H4=y
+CONFIG_BT_HCIUART_BCSP=y
+CONFIG_BT_HCIBCM203X=m
+CONFIG_BT_HCIBPA10X=m
+CONFIG_BT_HCIBFUSB=m
+CONFIG_BT_HCIDTL1=m
+CONFIG_BT_HCIBT3C=m
+CONFIG_BT_HCIBLUECARD=m
+CONFIG_BT_HCIBTUART=m
+CONFIG_BT_HCIVHCI=m
+CONFIG_IEEE80211=m
+CONFIG_IEEE80211_DEBUG=y
+CONFIG_IEEE80211_CRYPT_WEP=m
+CONFIG_IEEE80211_CRYPT_CCMP=m
+CONFIG_IEEE80211_CRYPT_TKIP=m
+CONFIG_IEEE80211_SOFTMAC=m
+CONFIG_IEEE80211_SOFTMAC_DEBUG=y
+CONFIG_TUX=m
+
+#
+# TUX options
+#
+CONFIG_TUX_EXTCGI=y
+CONFIG_TUX_EXTENDED_LOG=y
+# CONFIG_TUX_DEBUG is not set
+CONFIG_WIRELESS_EXT=y
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_SYS_HYPERVISOR is not set
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+CONFIG_CONNECTOR=y
+CONFIG_PROC_EVENTS=y
+
+#
+# Memory Technology Devices (MTD)
+#
+CONFIG_MTD=m
+# CONFIG_MTD_DEBUG is not set
+CONFIG_MTD_CONCAT=m
+CONFIG_MTD_PARTITIONS=y
+CONFIG_MTD_REDBOOT_PARTS=m
+CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1
+# CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED is not set
+# CONFIG_MTD_REDBOOT_PARTS_READONLY is not set
+CONFIG_MTD_CMDLINE_PARTS=y
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=m
+CONFIG_MTD_BLOCK=m
+CONFIG_MTD_BLOCK_RO=m
+CONFIG_FTL=m
+CONFIG_NFTL=m
+CONFIG_NFTL_RW=y
+CONFIG_INFTL=m
+CONFIG_RFD_FTL=m
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=m
+CONFIG_MTD_JEDECPROBE=m
+CONFIG_MTD_GEN_PROBE=m
+# CONFIG_MTD_CFI_ADV_OPTIONS 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_CFI_INTELEXT=m
+CONFIG_MTD_CFI_AMDSTD=m
+CONFIG_MTD_CFI_STAA=m
+CONFIG_MTD_CFI_UTIL=m
+CONFIG_MTD_RAM=m
+CONFIG_MTD_ROM=m
+CONFIG_MTD_ABSENT=m
+# CONFIG_MTD_OBSOLETE_CHIPS is not set
+
+#
+# Mapping drivers for chip access
+#
+CONFIG_MTD_COMPLEX_MAPPINGS=y
+# CONFIG_MTD_PHYSMAP is not set
+CONFIG_MTD_PCI=m
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+CONFIG_MTD_PMC551=m
+# CONFIG_MTD_PMC551_BUGFIX is not set
+# CONFIG_MTD_PMC551_DEBUG is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+CONFIG_MTD_MTDRAM=m
+CONFIG_MTDRAM_TOTAL_SIZE=4096
+CONFIG_MTDRAM_ERASE_SIZE=128
+CONFIG_MTD_BLOCK2MTD=m
+
+#
+# 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=m
+# CONFIG_MTD_NAND_VERIFY_WRITE is not set
+CONFIG_MTD_NAND_ECC_SMC=y
+CONFIG_MTD_NAND_IDS=m
+CONFIG_MTD_NAND_DISKONCHIP=m
+# CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADVANCED is not set
+CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADDRESS=0
+# CONFIG_MTD_NAND_DISKONCHIP_BBTWRITE is not set
+CONFIG_MTD_NAND_NANDSIM=m
+
+#
+# OneNAND Flash Device Drivers
+#
+# CONFIG_MTD_ONENAND is not set
+
+#
+# Parallel port support
+#
+CONFIG_PARPORT=m
+CONFIG_PARPORT_PC=m
+CONFIG_PARPORT_SERIAL=m
+# CONFIG_PARPORT_PC_FIFO is not set
+# CONFIG_PARPORT_PC_SUPERIO is not set
+CONFIG_PARPORT_PC_PCMCIA=m
+CONFIG_PARPORT_NOT_PC=y
+# CONFIG_PARPORT_GSC is not set
+# CONFIG_PARPORT_AX88796 is not set
+CONFIG_PARPORT_1284=y
+
+#
+# Plug and Play support
+#
+CONFIG_PNP=y
+# CONFIG_PNP_DEBUG is not set
+
+#
+# Protocols
+#
+CONFIG_ISAPNP=y
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+CONFIG_MAC_FLOPPY=m
+# CONFIG_BLK_DEV_XD is not set
+CONFIG_PARIDE=m
+CONFIG_PARIDE_PARPORT=m
+
+#
+# Parallel IDE high-level drivers
+#
+CONFIG_PARIDE_PD=m
+CONFIG_PARIDE_PCD=m
+CONFIG_PARIDE_PF=m
+CONFIG_PARIDE_PT=m
+CONFIG_PARIDE_PG=m
+
+#
+# Parallel IDE protocol modules
+#
+CONFIG_PARIDE_ATEN=m
+CONFIG_PARIDE_BPCK=m
+CONFIG_PARIDE_BPCK6=m
+CONFIG_PARIDE_COMM=m
+CONFIG_PARIDE_DSTR=m
+CONFIG_PARIDE_FIT2=m
+CONFIG_PARIDE_FIT3=m
+CONFIG_PARIDE_EPAT=m
+CONFIG_PARIDE_EPATC8=y
+CONFIG_PARIDE_EPIA=m
+CONFIG_PARIDE_FRIQ=m
+CONFIG_PARIDE_FRPW=m
+CONFIG_PARIDE_KBIC=m
+CONFIG_PARIDE_KTTI=m
+CONFIG_PARIDE_ON20=m
+CONFIG_PARIDE_ON26=m
+# CONFIG_BLK_CPQ_DA is not set
+CONFIG_BLK_CPQ_CISS_DA=m
+CONFIG_CISS_SCSI_TAPE=y
+CONFIG_BLK_DEV_DAC960=m
+CONFIG_BLK_DEV_UMEM=m
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=m
+CONFIG_BLK_DEV_CRYPTOLOOP=m
+CONFIG_BLK_DEV_NBD=m
+CONFIG_BLK_DEV_SX8=m
+CONFIG_BLK_DEV_UB=m
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=16384
+CONFIG_BLK_DEV_RAM_BLOCKSIZE=4096
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_CDROM_PKTCDVD=m
+CONFIG_CDROM_PKTCDVD_BUFFERS=8
+# CONFIG_CDROM_PKTCDVD_WCACHE is not set
+CONFIG_ATA_OVER_ETH=m
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+CONFIG_IDE=y
+CONFIG_BLK_DEV_IDE=y
+
+#
+# Please see Documentation/ide.txt for help/info on IDE drives
+#
+# CONFIG_BLK_DEV_IDE_SATA is not set
+CONFIG_BLK_DEV_IDEDISK=y
+CONFIG_IDEDISK_MULTI_MODE=y
+CONFIG_BLK_DEV_IDECS=m
+CONFIG_BLK_DEV_IDECD=m
+# CONFIG_BLK_DEV_IDETAPE is not set
+CONFIG_BLK_DEV_IDEFLOPPY=y
+CONFIG_BLK_DEV_IDESCSI=m
+CONFIG_IDE_TASK_IOCTL=y
+
+#
+# IDE chipset support/bugfixes
+#
+CONFIG_IDE_GENERIC=y
+CONFIG_BLK_DEV_IDEPNP=y
+CONFIG_BLK_DEV_IDEPCI=y
+CONFIG_IDEPCI_SHARE_IRQ=y
+# CONFIG_BLK_DEV_OFFBOARD is not set
+CONFIG_BLK_DEV_GENERIC=y
+# CONFIG_BLK_DEV_OPTI621 is not set
+CONFIG_BLK_DEV_SL82C105=m
+CONFIG_BLK_DEV_IDEDMA_PCI=y
+# CONFIG_BLK_DEV_IDEDMA_FORCED is not set
+CONFIG_IDEDMA_PCI_AUTO=y
+# CONFIG_IDEDMA_ONLYDISK is not set
+CONFIG_BLK_DEV_AEC62XX=y
+CONFIG_BLK_DEV_ALI15X3=y
+# CONFIG_WDC_ALI15X3 is not set
+# CONFIG_BLK_DEV_AMD74XX is not set
+CONFIG_BLK_DEV_CMD64X=y
+CONFIG_BLK_DEV_TRIFLEX=y
+# CONFIG_BLK_DEV_CY82C693 is not set
+CONFIG_BLK_DEV_CS5520=y
+CONFIG_BLK_DEV_CS5530=y
+CONFIG_BLK_DEV_HPT34X=y
+# CONFIG_HPT34X_AUTODMA is not set
+CONFIG_BLK_DEV_HPT366=y
+# CONFIG_BLK_DEV_SC1200 is not set
+CONFIG_BLK_DEV_PIIX=y
+CONFIG_BLK_DEV_IT821X=y
+# CONFIG_BLK_DEV_NS87415 is not set
+CONFIG_BLK_DEV_PDC202XX_OLD=y
+# CONFIG_PDC202XX_BURST is not set
+CONFIG_BLK_DEV_PDC202XX_NEW=y
+CONFIG_BLK_DEV_SVWKS=y
+CONFIG_BLK_DEV_SIIMAGE=y
+# CONFIG_BLK_DEV_SLC90E66 is not set
+# CONFIG_BLK_DEV_TRM290 is not set
+CONFIG_BLK_DEV_VIA82CXXX=y
+CONFIG_BLK_DEV_IDE_PMAC=y
+CONFIG_BLK_DEV_IDE_PMAC_ATA100FIRST=y
+CONFIG_BLK_DEV_IDEDMA_PMAC=y
+# CONFIG_IDE_ARM is not set
+# CONFIG_IDE_CHIPSETS is not set
+CONFIG_BLK_DEV_IDEDMA=y
+# CONFIG_IDEDMA_IVB is not set
+CONFIG_IDEDMA_AUTO=y
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# SCSI device support
+#
+CONFIG_RAID_ATTRS=m
+CONFIG_SCSI=m
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=m
+CONFIG_CHR_DEV_ST=m
+CONFIG_CHR_DEV_OSST=m
+CONFIG_BLK_DEV_SR=m
+CONFIG_BLK_DEV_SR_VENDOR=y
+CONFIG_CHR_DEV_SG=m
+CONFIG_CHR_DEV_SCH=m
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+CONFIG_SCSI_MULTI_LUN=y
+CONFIG_SCSI_CONSTANTS=y
+CONFIG_SCSI_LOGGING=y
+
+#
+# SCSI Transport Attributes
+#
+CONFIG_SCSI_SPI_ATTRS=m
+CONFIG_SCSI_FC_ATTRS=m
+CONFIG_SCSI_ISCSI_ATTRS=m
+CONFIG_SCSI_SAS_ATTRS=m
+
+#
+# SCSI low-level drivers
+#
+CONFIG_ISCSI_TCP=m
+CONFIG_BLK_DEV_3W_XXXX_RAID=m
+CONFIG_SCSI_3W_9XXX=m
+# CONFIG_SCSI_7000FASST is not set
+CONFIG_SCSI_ACARD=m
+CONFIG_SCSI_AHA152X=m
+# CONFIG_SCSI_AHA1542 is not set
+CONFIG_SCSI_AACRAID=m
+CONFIG_SCSI_AIC7XXX=m
+CONFIG_AIC7XXX_CMDS_PER_DEVICE=4
+CONFIG_AIC7XXX_RESET_DELAY_MS=15000
+# CONFIG_AIC7XXX_DEBUG_ENABLE is not set
+CONFIG_AIC7XXX_DEBUG_MASK=0
+# CONFIG_AIC7XXX_REG_PRETTY_PRINT is not set
+CONFIG_SCSI_AIC7XXX_OLD=m
+CONFIG_SCSI_AIC79XX=m
+CONFIG_AIC79XX_CMDS_PER_DEVICE=4
+CONFIG_AIC79XX_RESET_DELAY_MS=15000
+# CONFIG_AIC79XX_ENABLE_RD_STRM is not set
+# CONFIG_AIC79XX_DEBUG_ENABLE is not set
+CONFIG_AIC79XX_DEBUG_MASK=0
+# CONFIG_AIC79XX_REG_PRETTY_PRINT is not set
+# CONFIG_SCSI_DPT_I2O is not set
+# CONFIG_SCSI_IN2000 is not set
+CONFIG_MEGARAID_NEWGEN=y
+CONFIG_MEGARAID_MM=m
+CONFIG_MEGARAID_MAILBOX=m
+CONFIG_MEGARAID_LEGACY=m
+CONFIG_MEGARAID_SAS=m
+CONFIG_SCSI_SATA=m
+CONFIG_SCSI_SATA_AHCI=m
+CONFIG_SCSI_SATA_SVW=m
+CONFIG_SCSI_ATA_PIIX=m
+CONFIG_SCSI_SATA_MV=m
+CONFIG_SCSI_SATA_NV=m
+CONFIG_SCSI_PDC_ADMA=m
+CONFIG_SCSI_HPTIOP=m
+CONFIG_SCSI_SATA_QSTOR=m
+CONFIG_SCSI_SATA_PROMISE=m
+CONFIG_SCSI_SATA_SX4=m
+CONFIG_SCSI_SATA_SIL=m
+CONFIG_SCSI_SATA_SIL24=m
+CONFIG_SCSI_SATA_SIS=m
+CONFIG_SCSI_SATA_ULI=m
+CONFIG_SCSI_SATA_VIA=m
+CONFIG_SCSI_SATA_VITESSE=m
+CONFIG_SCSI_SATA_INTEL_COMBINED=y
+# CONFIG_SCSI_BUSLOGIC is not set
+# CONFIG_SCSI_DMX3191D is not set
+# CONFIG_SCSI_DTC3280 is not set
+# CONFIG_SCSI_EATA is not set
+# CONFIG_SCSI_FUTURE_DOMAIN is not set
+CONFIG_SCSI_GDTH=m
+# CONFIG_SCSI_GENERIC_NCR5380 is not set
+# CONFIG_SCSI_GENERIC_NCR5380_MMIO is not set
+CONFIG_SCSI_IPS=m
+CONFIG_SCSI_INITIO=m
+CONFIG_SCSI_INIA100=m
+CONFIG_SCSI_PPA=m
+CONFIG_SCSI_IMM=m
+# CONFIG_SCSI_IZIP_EPP16 is not set
+# CONFIG_SCSI_IZIP_SLOW_CTR is not set
+# CONFIG_SCSI_NCR53C406A is not set
+CONFIG_SCSI_SYM53C8XX_2=m
+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=m
+CONFIG_SCSI_QLA_FC=m
+CONFIG_SCSI_LPFC=m
+# CONFIG_SCSI_SYM53C416 is not set
+CONFIG_SCSI_DC395x=m
+# CONFIG_SCSI_DC390T is not set
+# CONFIG_SCSI_T128 is not set
+# CONFIG_SCSI_U14_34F is not set
+# CONFIG_SCSI_NSP32 is not set
+# CONFIG_SCSI_DEBUG is not set
+CONFIG_SCSI_MESH=m
+CONFIG_SCSI_MESH_SYNC_RATE=5
+CONFIG_SCSI_MESH_RESET_DELAY_MS=4000
+CONFIG_SCSI_MAC53C94=m
+
+#
+# PCMCIA SCSI adapter support
+#
+CONFIG_PCMCIA_AHA152X=m
+# CONFIG_PCMCIA_FDOMAIN is not set
+CONFIG_PCMCIA_NINJA_SCSI=m
+CONFIG_PCMCIA_QLOGIC=m
+CONFIG_PCMCIA_SYM53C500=m
+
+#
+# Old CD-ROM drivers (not SCSI, not IDE)
+#
+# CONFIG_CD_NO_IDESCSI is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+CONFIG_MD=y
+CONFIG_BLK_DEV_MD=y
+CONFIG_MD_LINEAR=m
+CONFIG_MD_RAID0=m
+CONFIG_MD_RAID1=m
+CONFIG_MD_RAID10=m
+CONFIG_MD_RAID456=m
+CONFIG_MD_RAID5_RESHAPE=y
+CONFIG_MD_MULTIPATH=m
+CONFIG_MD_FAULTY=m
+CONFIG_BLK_DEV_DM=m
+CONFIG_DM_CRYPT=m
+CONFIG_DM_SNAPSHOT=m
+CONFIG_DM_MIRROR=m
+CONFIG_DM_ZERO=m
+CONFIG_DM_MULTIPATH=m
+CONFIG_DM_MULTIPATH_EMC=m
+
+#
+# Fusion MPT device support
+#
+CONFIG_FUSION=y
+CONFIG_FUSION_SPI=m
+CONFIG_FUSION_FC=m
+CONFIG_FUSION_SAS=m
+CONFIG_FUSION_MAX_SGE=40
+CONFIG_FUSION_CTL=m
+CONFIG_FUSION_LAN=m
+
+#
+# IEEE 1394 (FireWire) support
+#
+CONFIG_IEEE1394=m
+
+#
+# Subsystem Options
+#
+# CONFIG_IEEE1394_VERBOSEDEBUG is not set
+CONFIG_IEEE1394_OUI_DB=y
+CONFIG_IEEE1394_EXTRA_CONFIG_ROMS=y
+CONFIG_IEEE1394_CONFIG_ROM_IP1394=y
+# CONFIG_IEEE1394_EXPORT_FULL_API is not set
+
+#
+# Device Drivers
+#
+CONFIG_IEEE1394_PCILYNX=m
+CONFIG_IEEE1394_OHCI1394=m
+
+#
+# Protocol Drivers
+#
+CONFIG_IEEE1394_VIDEO1394=m
+CONFIG_IEEE1394_SBP2=m
+CONFIG_IEEE1394_ETH1394=m
+CONFIG_IEEE1394_DV1394=m
+CONFIG_IEEE1394_RAWIO=m
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+
+#
+# Macintosh device drivers
+#
+CONFIG_ADB=y
+CONFIG_ADB_CUDA=y
+CONFIG_ADB_PMU=y
+CONFIG_ADB_PMU_LED=y
+CONFIG_ADB_PMU_LED_IDE=y
+CONFIG_PMAC_APM_EMU=y
+CONFIG_PMAC_MEDIABAY=y
+CONFIG_PMAC_BACKLIGHT=y
+# CONFIG_PMAC_BACKLIGHT_LEGACY is not set
+CONFIG_ADB_MACIO=y
+CONFIG_INPUT_ADBHID=y
+CONFIG_MAC_EMUMOUSEBTN=y
+CONFIG_THERM_WINDTUNNEL=m
+CONFIG_THERM_ADT746X=m
+CONFIG_WINDFARM=y
+# CONFIG_ANSLCD is not set
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+CONFIG_IFB=m
+CONFIG_DUMMY=m
+CONFIG_BONDING=m
+CONFIG_EQUALIZER=m
+CONFIG_TUN=m
+CONFIG_NET_SB1000=m
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+
+#
+# PHY device support
+#
+CONFIG_PHYLIB=m
+
+#
+# MII PHY device drivers
+#
+CONFIG_MARVELL_PHY=m
+CONFIG_DAVICOM_PHY=m
+CONFIG_QSEMI_PHY=m
+CONFIG_LXT_PHY=m
+CONFIG_CICADA_PHY=m
+CONFIG_VITESSE_PHY=m
+CONFIG_SMSC_PHY=m
+CONFIG_FIXED_PHY=m
+CONFIG_FIXED_MII_10_FDX=y
+CONFIG_FIXED_MII_100_FDX=y
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=m
+CONFIG_MACE=m
+# CONFIG_MACE_AAUI_PORT is not set
+CONFIG_BMAC=m
+CONFIG_HAPPYMEAL=m
+CONFIG_SUNGEM=m
+CONFIG_CASSINI=m
+CONFIG_NET_VENDOR_3COM=y
+# CONFIG_EL1 is not set
+# CONFIG_EL2 is not set
+# CONFIG_ELPLUS is not set
+# CONFIG_EL16 is not set
+CONFIG_EL3=m
+# CONFIG_3C515 is not set
+CONFIG_VORTEX=m
+CONFIG_TYPHOON=m
+# CONFIG_LANCE is not set
+CONFIG_NET_VENDOR_SMC=y
+# CONFIG_WD80x3 is not set
+CONFIG_ULTRA=m
+# CONFIG_SMC9194 is not set
+# CONFIG_NET_VENDOR_RACAL is not set
+
+#
+# Tulip family network device support
+#
+CONFIG_NET_TULIP=y
+CONFIG_DE2104X=m
+CONFIG_TULIP=m
+# CONFIG_TULIP_MWI is not set
+CONFIG_TULIP_MMIO=y
+# CONFIG_TULIP_NAPI is not set
+CONFIG_DE4X5=m
+CONFIG_WINBOND_840=m
+CONFIG_DM9102=m
+CONFIG_ULI526X=m
+CONFIG_PCMCIA_XIRCOM=m
+# CONFIG_AT1700 is not set
+# CONFIG_DEPCA is not set
+# CONFIG_HP100 is not set
+CONFIG_NET_ISA=y
+# CONFIG_E2100 is not set
+CONFIG_EWRK3=m
+# CONFIG_EEXPRESS is not set
+# CONFIG_EEXPRESS_PRO is not set
+# CONFIG_HPLAN_PLUS is not set
+# CONFIG_HPLAN is not set
+# CONFIG_LP486E is not set
+# CONFIG_ETH16I is not set
+CONFIG_NE2000=m
+# CONFIG_ZNET is not set
+# CONFIG_SEEQ8005 is not set
+CONFIG_NET_PCI=y
+CONFIG_PCNET32=m
+CONFIG_AMD8111_ETH=m
+CONFIG_AMD8111E_NAPI=y
+CONFIG_ADAPTEC_STARFIRE=m
+CONFIG_ADAPTEC_STARFIRE_NAPI=y
+# CONFIG_AC3200 is not set
+# CONFIG_APRICOT is not set
+CONFIG_B44=m
+CONFIG_FORCEDETH=m
+# CONFIG_CS89x0 is not set
+# CONFIG_DGRS is not set
+# CONFIG_EEPRO100 is not set
+CONFIG_E100=m
+CONFIG_FEALNX=m
+CONFIG_NATSEMI=m
+CONFIG_NE2K_PCI=m
+CONFIG_8139CP=m
+CONFIG_8139TOO=m
+# CONFIG_8139TOO_PIO is not set
+# CONFIG_8139TOO_TUNE_TWISTER is not set
+CONFIG_8139TOO_8129=y
+# CONFIG_8139_OLD_RX_RESET is not set
+CONFIG_SIS900=m
+CONFIG_EPIC100=m
+CONFIG_SUNDANCE=m
+# CONFIG_SUNDANCE_MMIO is not set
+CONFIG_TLAN=m
+CONFIG_VIA_RHINE=m
+CONFIG_VIA_RHINE_MMIO=y
+CONFIG_VIA_RHINE_NAPI=y
+CONFIG_NET_POCKET=y
+CONFIG_DE600=m
+CONFIG_DE620=m
+
+#
+# Ethernet (1000 Mbit)
+#
+CONFIG_ACENIC=m
+# CONFIG_ACENIC_OMIT_TIGON_I is not set
+CONFIG_DL2K=m
+CONFIG_E1000=m
+CONFIG_E1000_NAPI=y
+# CONFIG_E1000_DISABLE_PACKET_SPLIT is not set
+CONFIG_NS83820=m
+CONFIG_HAMACHI=m
+CONFIG_YELLOWFIN=m
+CONFIG_R8169=m
+CONFIG_R8169_NAPI=y
+CONFIG_R8169_VLAN=y
+CONFIG_SIS190=m
+CONFIG_SKGE=m
+CONFIG_SKY2=m
+# CONFIG_SK98LIN is not set
+CONFIG_VIA_VELOCITY=m
+CONFIG_TIGON3=m
+CONFIG_BNX2=m
+CONFIG_MV643XX_ETH=m
+CONFIG_MV643XX_ETH_0=y
+CONFIG_MV643XX_ETH_1=y
+CONFIG_MV643XX_ETH_2=y
+
+#
+# Ethernet (10000 Mbit)
+#
+CONFIG_CHELSIO_T1=m
+CONFIG_IXGB=m
+CONFIG_IXGB_NAPI=y
+CONFIG_S2IO=m
+CONFIG_S2IO_NAPI=y
+CONFIG_MYRI10GE=m
+
+#
+# Token Ring devices
+#
+CONFIG_TR=y
+# CONFIG_IBMTR is not set
+CONFIG_IBMOL=m
+CONFIG_IBMLS=m
+CONFIG_3C359=m
+# CONFIG_TMS380TR is not set
+# CONFIG_SMCTR is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+CONFIG_NET_RADIO=y
+CONFIG_NET_WIRELESS_RTNETLINK=y
+
+#
+# Obsolete Wireless cards support (pre-802.11)
+#
+# CONFIG_STRIP is not set
+# CONFIG_ARLAN is not set
+# CONFIG_WAVELAN is not set
+CONFIG_PCMCIA_WAVELAN=m
+CONFIG_PCMCIA_NETWAVE=m
+
+#
+# Wireless 802.11 Frequency Hopping cards support
+#
+# CONFIG_PCMCIA_RAYCS is not set
+
+#
+# Wireless 802.11b ISA/PCI cards support
+#
+# CONFIG_IPW2100 is not set
+# CONFIG_IPW2200 is not set
+CONFIG_AIRO=m
+CONFIG_HERMES=m
+CONFIG_APPLE_AIRPORT=m
+CONFIG_PLX_HERMES=m
+CONFIG_TMD_HERMES=m
+CONFIG_NORTEL_HERMES=m
+CONFIG_PCI_HERMES=m
+CONFIG_ATMEL=m
+CONFIG_PCI_ATMEL=m
+
+#
+# Wireless 802.11b Pcmcia/Cardbus cards support
+#
+CONFIG_PCMCIA_HERMES=m
+CONFIG_PCMCIA_SPECTRUM=m
+CONFIG_AIRO_CS=m
+CONFIG_PCMCIA_ATMEL=m
+CONFIG_PCMCIA_WL3501=m
+
+#
+# Prism GT/Duette 802.11(a/b/g) PCI/Cardbus support
+#
+CONFIG_PRISM54=m
+CONFIG_USB_ZD1201=m
+CONFIG_HOSTAP=m
+CONFIG_HOSTAP_FIRMWARE=y
+CONFIG_HOSTAP_FIRMWARE_NVRAM=y
+CONFIG_HOSTAP_PLX=m
+CONFIG_HOSTAP_PCI=m
+CONFIG_HOSTAP_CS=m
+CONFIG_BCM43XX=m
+CONFIG_BCM43XX_DEBUG=y
+CONFIG_BCM43XX_DMA=y
+CONFIG_BCM43XX_PIO=y
+CONFIG_BCM43XX_DMA_AND_PIO_MODE=y
+# CONFIG_BCM43XX_DMA_MODE is not set
+# CONFIG_BCM43XX_PIO_MODE is not set
+CONFIG_ZD1211RW=m
+# CONFIG_ZD1211RW_DEBUG is not set
+CONFIG_NET_WIRELESS=y
+
+#
+# PCMCIA network device support
+#
+CONFIG_NET_PCMCIA=y
+CONFIG_PCMCIA_3C589=m
+CONFIG_PCMCIA_3C574=m
+CONFIG_PCMCIA_FMVJ18X=m
+CONFIG_PCMCIA_PCNET=m
+CONFIG_PCMCIA_NMCLAN=m
+CONFIG_PCMCIA_SMC91C92=m
+CONFIG_PCMCIA_XIRC2PS=m
+CONFIG_PCMCIA_AXNET=m
+CONFIG_PCMCIA_IBMTR=m
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+
+#
+# ATM drivers
+#
+# CONFIG_ATM_DUMMY is not set
+CONFIG_ATM_TCP=m
+CONFIG_ATM_LANAI=m
+CONFIG_ATM_ENI=m
+# CONFIG_ATM_ENI_DEBUG is not set
+# CONFIG_ATM_ENI_TUNE_BURST is not set
+# CONFIG_ATM_FIRESTREAM is not set
+# CONFIG_ATM_ZATM is not set
+CONFIG_ATM_NICSTAR=m
+# CONFIG_ATM_NICSTAR_USE_SUNI is not set
+# CONFIG_ATM_NICSTAR_USE_IDT77105 is not set
+CONFIG_ATM_IDT77252=m
+# CONFIG_ATM_IDT77252_DEBUG is not set
+# CONFIG_ATM_IDT77252_RCV_ALL is not set
+CONFIG_ATM_IDT77252_USE_SUNI=y
+# CONFIG_ATM_AMBASSADOR is not set
+# CONFIG_ATM_HORIZON is not set
+# CONFIG_ATM_IA is not set
+CONFIG_ATM_FORE200E_MAYBE=m
+# CONFIG_ATM_FORE200E_PCA is not set
+CONFIG_ATM_HE=m
+# CONFIG_ATM_HE_USE_SUNI is not set
+CONFIG_FDDI=y
+# CONFIG_DEFXX is not set
+CONFIG_SKFP=m
+# CONFIG_HIPPI is not set
+CONFIG_PLIP=m
+CONFIG_PPP=m
+CONFIG_PPP_MULTILINK=y
+CONFIG_PPP_FILTER=y
+CONFIG_PPP_ASYNC=m
+CONFIG_PPP_SYNC_TTY=m
+CONFIG_PPP_DEFLATE=m
+# CONFIG_PPP_BSDCOMP is not set
+CONFIG_PPP_MPPE=m
+CONFIG_PPPOE=m
+CONFIG_PPPOATM=m
+CONFIG_SLIP=m
+CONFIG_SLIP_COMPRESSED=y
+CONFIG_SLIP_SMART=y
+# CONFIG_SLIP_MODE_SLIP6 is not set
+CONFIG_NET_FC=y
+# CONFIG_SHAPER is not set
+CONFIG_NETCONSOLE=m
+CONFIG_NETPOLL=y
+# CONFIG_NETPOLL_RX is not set
+CONFIG_NETPOLL_TRAP=y
+CONFIG_NET_POLL_CONTROLLER=y
+
+#
+# ISDN subsystem
+#
+CONFIG_ISDN=m
+
+#
+# Old ISDN4Linux
+#
+CONFIG_ISDN_I4L=m
+CONFIG_ISDN_PPP=y
+CONFIG_ISDN_PPP_VJ=y
+CONFIG_ISDN_MPP=y
+CONFIG_IPPP_FILTER=y
+# CONFIG_ISDN_PPP_BSDCOMP is not set
+CONFIG_ISDN_AUDIO=y
+CONFIG_ISDN_TTY_FAX=y
+
+#
+# ISDN feature submodules
+#
+CONFIG_ISDN_DIVERSION=m
+
+#
+# ISDN4Linux hardware drivers
+#
+
+#
+# Passive cards
+#
+CONFIG_ISDN_DRV_HISAX=m
+
+#
+# D-channel protocol features
+#
+CONFIG_HISAX_EURO=y
+CONFIG_DE_AOC=y
+CONFIG_HISAX_NO_SENDCOMPLETE=y
+CONFIG_HISAX_NO_LLC=y
+CONFIG_HISAX_NO_KEYPAD=y
+CONFIG_HISAX_1TR6=y
+CONFIG_HISAX_NI1=y
+CONFIG_HISAX_MAX_CARDS=8
+
+#
+# HiSax supported cards
+#
+# CONFIG_HISAX_16_0 is not set
+CONFIG_HISAX_16_3=y
+CONFIG_HISAX_S0BOX=y
+# CONFIG_HISAX_AVM_A1 is not set
+CONFIG_HISAX_FRITZPCI=y
+CONFIG_HISAX_AVM_A1_PCMCIA=y
+CONFIG_HISAX_ELSA=y
+# CONFIG_HISAX_IX1MICROR2 is not set
+CONFIG_HISAX_DIEHLDIVA=y
+# CONFIG_HISAX_ASUSCOM is not set
+# CONFIG_HISAX_TELEINT is not set
+# CONFIG_HISAX_HFCS is not set
+CONFIG_HISAX_SEDLBAUER=y
+# CONFIG_HISAX_SPORTSTER is not set
+# CONFIG_HISAX_MIC is not set
+CONFIG_HISAX_NICCY=y
+# CONFIG_HISAX_ISURF is not set
+# CONFIG_HISAX_HSTSAPHIR is not set
+CONFIG_HISAX_BKM_A4T=y
+CONFIG_HISAX_SCT_QUADRO=y
+CONFIG_HISAX_GAZEL=y
+CONFIG_HISAX_W6692=y
+CONFIG_HISAX_HFC_SX=y
+# CONFIG_HISAX_DEBUG is not set
+
+#
+# HiSax PCMCIA card service modules
+#
+CONFIG_HISAX_SEDLBAUER_CS=m
+CONFIG_HISAX_ELSA_CS=m
+CONFIG_HISAX_AVM_A1_CS=m
+CONFIG_HISAX_TELES_CS=m
+
+#
+# HiSax sub driver modules
+#
+CONFIG_HISAX_ST5481=m
+# CONFIG_HISAX_HFCUSB is not set
+CONFIG_HISAX_HFC4S8S=m
+CONFIG_HISAX_FRITZ_PCIPNP=m
+CONFIG_HISAX_HDLC=y
+
+#
+# Active cards
+#
+# CONFIG_ISDN_DRV_ICN is not set
+# CONFIG_ISDN_DRV_SC is not set
+# CONFIG_ISDN_DRV_ACT2000 is not set
+
+#
+# Siemens Gigaset
+#
+CONFIG_ISDN_DRV_GIGASET=m
+CONFIG_GIGASET_BASE=m
+CONFIG_GIGASET_M105=m
+# CONFIG_GIGASET_DEBUG is not set
+# CONFIG_GIGASET_UNDOCREQ is not set
+
+#
+# CAPI subsystem
+#
+CONFIG_ISDN_CAPI=m
+CONFIG_ISDN_DRV_AVMB1_VERBOSE_REASON=y
+CONFIG_ISDN_CAPI_MIDDLEWARE=y
+CONFIG_ISDN_CAPI_CAPI20=m
+CONFIG_ISDN_CAPI_CAPIFS_BOOL=y
+CONFIG_ISDN_CAPI_CAPIFS=m
+CONFIG_ISDN_CAPI_CAPIDRV=m
+
+#
+# CAPI hardware drivers
+#
+
+#
+# Active AVM cards
+#
+CONFIG_CAPI_AVM=y
+# CONFIG_ISDN_DRV_AVMB1_B1ISA is not set
+CONFIG_ISDN_DRV_AVMB1_B1PCI=m
+CONFIG_ISDN_DRV_AVMB1_B1PCIV4=y
+# CONFIG_ISDN_DRV_AVMB1_T1ISA is not set
+CONFIG_ISDN_DRV_AVMB1_B1PCMCIA=m
+CONFIG_ISDN_DRV_AVMB1_AVM_CS=m
+CONFIG_ISDN_DRV_AVMB1_T1PCI=m
+CONFIG_ISDN_DRV_AVMB1_C4=m
+
+#
+# Active Eicon DIVA Server cards
+#
+CONFIG_CAPI_EICON=y
+CONFIG_ISDN_DIVAS=m
+CONFIG_ISDN_DIVAS_BRIPCI=y
+CONFIG_ISDN_DIVAS_PRIPCI=y
+CONFIG_ISDN_DIVAS_DIVACAPI=m
+CONFIG_ISDN_DIVAS_USERIDI=m
+CONFIG_ISDN_DIVAS_MAINT=m
+
+#
+# Telephony Support
+#
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+
+#
+# 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=m
+# CONFIG_INPUT_TSDEV is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+CONFIG_KEYBOARD_ATKBD=y
+# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_KEYBOARD_LKKBD is not set
+# CONFIG_KEYBOARD_XTKBD is not set
+# CONFIG_KEYBOARD_NEWTON is not set
+CONFIG_INPUT_MOUSE=y
+CONFIG_MOUSE_PS2=y
+CONFIG_MOUSE_SERIAL=m
+# CONFIG_MOUSE_INPORT is not set
+# CONFIG_MOUSE_LOGIBM is not set
+# CONFIG_MOUSE_PC110PAD is not set
+CONFIG_MOUSE_VSXXXAA=m
+CONFIG_INPUT_JOYSTICK=y
+CONFIG_JOYSTICK_ANALOG=m
+CONFIG_JOYSTICK_A3D=m
+CONFIG_JOYSTICK_ADI=m
+CONFIG_JOYSTICK_COBRA=m
+CONFIG_JOYSTICK_GF2K=m
+CONFIG_JOYSTICK_GRIP=m
+CONFIG_JOYSTICK_GRIP_MP=m
+CONFIG_JOYSTICK_GUILLEMOT=m
+CONFIG_JOYSTICK_INTERACT=m
+CONFIG_JOYSTICK_SIDEWINDER=m
+CONFIG_JOYSTICK_TMDC=m
+CONFIG_JOYSTICK_IFORCE=m
+CONFIG_JOYSTICK_IFORCE_USB=y
+CONFIG_JOYSTICK_IFORCE_232=y
+CONFIG_JOYSTICK_WARRIOR=m
+CONFIG_JOYSTICK_MAGELLAN=m
+CONFIG_JOYSTICK_SPACEORB=m
+CONFIG_JOYSTICK_SPACEBALL=m
+CONFIG_JOYSTICK_STINGER=m
+CONFIG_JOYSTICK_TWIDJOY=m
+CONFIG_JOYSTICK_DB9=m
+CONFIG_JOYSTICK_GAMECON=m
+CONFIG_JOYSTICK_TURBOGRAFX=m
+CONFIG_JOYSTICK_JOYDUMP=m
+CONFIG_INPUT_TOUCHSCREEN=y
+CONFIG_TOUCHSCREEN_GUNZE=m
+CONFIG_TOUCHSCREEN_ELO=m
+CONFIG_TOUCHSCREEN_MTOUCH=m
+CONFIG_TOUCHSCREEN_MK712=m
+CONFIG_INPUT_MISC=y
+CONFIG_INPUT_PCSPKR=m
+CONFIG_INPUT_UINPUT=m
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+CONFIG_SERIO_I8042=y
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_PARKBD is not set
+# CONFIG_SERIO_PCIPS2 is not set
+CONFIG_SERIO_LIBPS2=y
+CONFIG_SERIO_RAW=m
+CONFIG_GAMEPORT=m
+CONFIG_GAMEPORT_NS558=m
+CONFIG_GAMEPORT_L4=m
+CONFIG_GAMEPORT_EMU10K1=m
+CONFIG_GAMEPORT_FM801=m
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+CONFIG_VT_HW_CONSOLE_BINDING=y
+CONFIG_SERIAL_NONSTANDARD=y
+# CONFIG_COMPUTONE is not set
+# CONFIG_ROCKETPORT is not set
+CONFIG_CYCLADES=m
+# CONFIG_CYZ_INTR is not set
+# CONFIG_DIGIEPCA is not set
+# CONFIG_ESPSERIAL is not set
+# CONFIG_MOXA_INTELLIO is not set
+# CONFIG_MOXA_SMARTIO is not set
+# CONFIG_ISI is not set
+CONFIG_SYNCLINK=m
+CONFIG_SYNCLINKMP=m
+CONFIG_SYNCLINK_GT=m
+CONFIG_N_HDLC=m
+# CONFIG_SPECIALIX is not set
+# CONFIG_SX is not set
+# CONFIG_RIO is not set
+# CONFIG_STALDRV is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_PCI=y
+CONFIG_SERIAL_8250_PNP=y
+CONFIG_SERIAL_8250_CS=m
+CONFIG_SERIAL_8250_NR_UARTS=32
+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=y
+CONFIG_SERIAL_8250_RSA=y
+# CONFIG_SERIAL_8250_FOURPORT is not set
+# CONFIG_SERIAL_8250_ACCENT is not set
+# CONFIG_SERIAL_8250_BOCA is not set
+# CONFIG_SERIAL_8250_HUB6 is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_SERIAL_PMACZILOG=m
+CONFIG_SERIAL_JSM=m
+CONFIG_UNIX98_PTYS=y
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_CRASH is not set
+CONFIG_PRINTER=m
+CONFIG_LP_CONSOLE=y
+CONFIG_PPDEV=m
+CONFIG_TIPAR=m
+# CONFIG_HVC_RTAS is not set
+
+#
+# IPMI
+#
+CONFIG_IPMI_HANDLER=m
+# CONFIG_IPMI_PANIC_EVENT is not set
+CONFIG_IPMI_DEVICE_INTERFACE=m
+CONFIG_IPMI_SI=m
+CONFIG_IPMI_WATCHDOG=m
+CONFIG_IPMI_POWEROFF=m
+
+#
+# Watchdog Cards
+#
+CONFIG_WATCHDOG=y
+# CONFIG_WATCHDOG_NOWAYOUT is not set
+
+#
+# Watchdog Device Drivers
+#
+CONFIG_SOFT_WATCHDOG=m
+CONFIG_WATCHDOG_RTAS=m
+
+#
+# ISA-based Watchdog Cards
+#
+# CONFIG_PCWATCHDOG is not set
+# CONFIG_MIXCOMWD is not set
+# CONFIG_WDT is not set
+
+#
+# PCI-based Watchdog Cards
+#
+CONFIG_PCIPCWATCHDOG=m
+CONFIG_WDTPCI=m
+CONFIG_WDT_501_PCI=y
+
+#
+# USB-based Watchdog Cards
+#
+CONFIG_USBPCWATCHDOG=m
+CONFIG_HW_RANDOM=y
+CONFIG_NVRAM=y
+CONFIG_GEN_RTC=y
+# CONFIG_GEN_RTC_X is not set
+CONFIG_DTLK=m
+CONFIG_R3964=m
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+CONFIG_AGP=y
+CONFIG_AGP_SIS=y
+CONFIG_AGP_VIA=y
+CONFIG_AGP_UNINORTH=y
+CONFIG_DRM=m
+CONFIG_DRM_TDFX=m
+CONFIG_DRM_R128=m
+CONFIG_DRM_RADEON=m
+CONFIG_DRM_MGA=m
+CONFIG_DRM_SIS=m
+CONFIG_DRM_VIA=m
+CONFIG_DRM_SAVAGE=m
+
+#
+# PCMCIA character devices
+#
+# CONFIG_SYNCLINK_CS is not set
+CONFIG_CARDMAN_4000=m
+CONFIG_CARDMAN_4040=m
+# CONFIG_RAW_DRIVER is not set
+
+#
+# TPM devices
+#
+CONFIG_TCG_TPM=m
+CONFIG_TCG_ATMEL=m
+# CONFIG_TELCLOCK is not set
+
+#
+# I2C support
+#
+CONFIG_I2C=y
+CONFIG_I2C_CHARDEV=m
+
+#
+# I2C Algorithms
+#
+CONFIG_I2C_ALGOBIT=y
+CONFIG_I2C_ALGOPCF=m
+CONFIG_I2C_ALGOPCA=m
+
+#
+# I2C Hardware Bus support
+#
+# CONFIG_I2C_ALI1535 is not set
+# CONFIG_I2C_ALI1563 is not set
+# CONFIG_I2C_ALI15X3 is not set
+# CONFIG_I2C_AMD756 is not set
+# CONFIG_I2C_AMD8111 is not set
+CONFIG_I2C_HYDRA=m
+# CONFIG_I2C_I801 is not set
+# CONFIG_I2C_I810 is not set
+# CONFIG_I2C_PIIX4 is not set
+CONFIG_I2C_ISA=m
+CONFIG_I2C_POWERMAC=y
+CONFIG_I2C_MPC=m
+CONFIG_I2C_NFORCE2=m
+# CONFIG_I2C_OCORES is not set
+CONFIG_I2C_PARPORT=m
+CONFIG_I2C_PARPORT_LIGHT=m
+CONFIG_I2C_PROSAVAGE=m
+CONFIG_I2C_SAVAGE4=m
+# CONFIG_I2C_SIS5595 is not set
+# CONFIG_I2C_SIS630 is not set
+# CONFIG_I2C_SIS96X is not set
+CONFIG_I2C_STUB=m
+# CONFIG_I2C_VIA is not set
+# CONFIG_I2C_VIAPRO is not set
+CONFIG_I2C_VOODOO3=m
+CONFIG_I2C_PCA_ISA=m
+
+#
+# Miscellaneous I2C Chip support
+#
+CONFIG_SENSORS_DS1337=m
+CONFIG_SENSORS_DS1374=m
+CONFIG_SENSORS_EEPROM=m
+CONFIG_SENSORS_PCF8574=m
+CONFIG_SENSORS_PCA9539=m
+CONFIG_SENSORS_PCF8591=m
+CONFIG_SENSORS_M41T00=m
+CONFIG_SENSORS_MAX6875=m
+# 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 is not set
+# CONFIG_SPI_MASTER is not set
+
+#
+# Dallas's 1-wire bus
+#
+CONFIG_W1=m
+CONFIG_W1_CON=y
+
+#
+# 1-wire Bus Masters
+#
+CONFIG_W1_MASTER_MATROX=m
+CONFIG_W1_MASTER_DS2490=m
+CONFIG_W1_MASTER_DS2482=m
+
+#
+# 1-wire Slaves
+#
+CONFIG_W1_SLAVE_THERM=m
+CONFIG_W1_SLAVE_SMEM=m
+CONFIG_W1_SLAVE_DS2433=m
+CONFIG_W1_SLAVE_DS2433_CRC=y
+
+#
+# Hardware Monitoring support
+#
+CONFIG_HWMON=m
+CONFIG_HWMON_VID=m
+CONFIG_SENSORS_ABITUGURU=m
+CONFIG_SENSORS_ADM1021=m
+CONFIG_SENSORS_ADM1025=m
+CONFIG_SENSORS_ADM1026=m
+CONFIG_SENSORS_ADM1031=m
+CONFIG_SENSORS_ADM9240=m
+CONFIG_SENSORS_ASB100=m
+CONFIG_SENSORS_ATXP1=m
+CONFIG_SENSORS_DS1621=m
+CONFIG_SENSORS_F71805F=m
+CONFIG_SENSORS_FSCHER=m
+CONFIG_SENSORS_FSCPOS=m
+CONFIG_SENSORS_GL518SM=m
+CONFIG_SENSORS_GL520SM=m
+CONFIG_SENSORS_IT87=m
+CONFIG_SENSORS_LM63=m
+CONFIG_SENSORS_LM75=m
+CONFIG_SENSORS_LM77=m
+CONFIG_SENSORS_LM78=m
+CONFIG_SENSORS_LM80=m
+CONFIG_SENSORS_LM83=m
+CONFIG_SENSORS_LM85=m
+CONFIG_SENSORS_LM87=m
+CONFIG_SENSORS_LM90=m
+CONFIG_SENSORS_LM92=m
+CONFIG_SENSORS_MAX1619=m
+CONFIG_SENSORS_PC87360=m
+CONFIG_SENSORS_SIS5595=m
+CONFIG_SENSORS_SMSC47M1=m
+CONFIG_SENSORS_SMSC47M192=m
+CONFIG_SENSORS_SMSC47B397=m
+CONFIG_SENSORS_VIA686A=m
+CONFIG_SENSORS_VT8231=m
+CONFIG_SENSORS_W83781D=m
+CONFIG_SENSORS_W83791D=m
+CONFIG_SENSORS_W83792D=m
+CONFIG_SENSORS_W83L785TS=m
+CONFIG_SENSORS_W83627HF=m
+CONFIG_SENSORS_W83627EHF=m
+# CONFIG_HWMON_DEBUG_CHIP is not set
+
+#
+# Misc devices
+#
+
+#
+# Multimedia devices
+#
+CONFIG_VIDEO_DEV=m
+CONFIG_VIDEO_V4L1=y
+CONFIG_VIDEO_V4L1_COMPAT=y
+CONFIG_VIDEO_V4L2=y
+
+#
+# Video Capture Adapters
+#
+
+#
+# Video Capture Adapters
+#
+# CONFIG_VIDEO_ADV_DEBUG is not set
+# CONFIG_VIDEO_VIVI is not set
+CONFIG_VIDEO_BT848=m
+CONFIG_VIDEO_BT848_DVB=y
+CONFIG_VIDEO_SAA6588=m
+# CONFIG_VIDEO_PMS is not set
+CONFIG_VIDEO_BWQCAM=m
+CONFIG_VIDEO_CQCAM=m
+CONFIG_VIDEO_W9966=m
+CONFIG_VIDEO_CPIA=m
+CONFIG_VIDEO_CPIA_PP=m
+CONFIG_VIDEO_CPIA_USB=m
+CONFIG_VIDEO_CPIA2=m
+CONFIG_VIDEO_SAA5246A=m
+CONFIG_VIDEO_SAA5249=m
+CONFIG_TUNER_3036=m
+# CONFIG_VIDEO_STRADIS is not set
+# CONFIG_VIDEO_ZORAN is not set
+CONFIG_VIDEO_SAA7134=m
+CONFIG_VIDEO_SAA7134_ALSA=m
+CONFIG_VIDEO_SAA7134_DVB=m
+CONFIG_VIDEO_SAA7134_DVB_ALL_FRONTENDS=y
+CONFIG_VIDEO_MXB=m
+CONFIG_VIDEO_DPC=m
+CONFIG_VIDEO_HEXIUM_ORION=m
+CONFIG_VIDEO_HEXIUM_GEMINI=m
+CONFIG_VIDEO_CX88_VP3054=m
+CONFIG_VIDEO_CX88=m
+CONFIG_VIDEO_CX88_ALSA=m
+CONFIG_VIDEO_CX88_BLACKBIRD=m
+CONFIG_VIDEO_CX88_DVB=m
+CONFIG_VIDEO_CX88_DVB_ALL_FRONTENDS=y
+
+#
+# Encoders and Decoders
+#
+CONFIG_VIDEO_MSP3400=m
+CONFIG_VIDEO_CS53L32A=m
+CONFIG_VIDEO_TLV320AIC23B=m
+CONFIG_VIDEO_WM8775=m
+CONFIG_VIDEO_WM8739=m
+CONFIG_VIDEO_CX2341X=m
+CONFIG_VIDEO_CX25840=m
+CONFIG_VIDEO_SAA711X=m
+CONFIG_VIDEO_SAA7127=m
+CONFIG_VIDEO_UPD64031A=m
+CONFIG_VIDEO_UPD64083=m
+
+#
+# V4L USB devices
+#
+CONFIG_VIDEO_PVRUSB2=m
+CONFIG_VIDEO_PVRUSB2_24XXX=y
+CONFIG_VIDEO_PVRUSB2_SYSFS=y
+# CONFIG_VIDEO_PVRUSB2_DEBUGIFC is not set
+CONFIG_VIDEO_EM28XX=m
+CONFIG_VIDEO_USBVIDEO=m
+CONFIG_USB_VICAM=m
+CONFIG_USB_IBMCAM=m
+CONFIG_USB_KONICAWC=m
+CONFIG_USB_QUICKCAM_MESSENGER=m
+CONFIG_USB_ET61X251=m
+CONFIG_VIDEO_OVCAMCHIP=m
+CONFIG_USB_W9968CF=m
+CONFIG_USB_OV511=m
+CONFIG_USB_SE401=m
+CONFIG_USB_SN9C102=m
+CONFIG_USB_STV680=m
+CONFIG_USB_ZC0301=m
+CONFIG_USB_PWC=m
+# CONFIG_USB_PWC_DEBUG is not set
+
+#
+# Radio Adapters
+#
+# CONFIG_RADIO_CADET is not set
+# CONFIG_RADIO_RTRACK is not set
+# CONFIG_RADIO_RTRACK2 is not set
+# CONFIG_RADIO_AZTECH is not set
+# CONFIG_RADIO_GEMTEK is not set
+CONFIG_RADIO_GEMTEK_PCI=m
+CONFIG_RADIO_MAXIRADIO=m
+CONFIG_RADIO_MAESTRO=m
+# CONFIG_RADIO_SF16FMI is not set
+# CONFIG_RADIO_SF16FMR2 is not set
+# CONFIG_RADIO_TERRATEC is not set
+# CONFIG_RADIO_TRUST is not set
+# CONFIG_RADIO_TYPHOON is not set
+# CONFIG_RADIO_ZOLTRIX is not set
+CONFIG_USB_DSBR=m
+
+#
+# Digital Video Broadcasting Devices
+#
+CONFIG_DVB=y
+CONFIG_DVB_CORE=m
+
+#
+# Supported SAA7146 based PCI Adapters
+#
+CONFIG_DVB_AV7110=m
+CONFIG_DVB_AV7110_OSD=y
+CONFIG_DVB_BUDGET=m
+CONFIG_DVB_BUDGET_CI=m
+CONFIG_DVB_BUDGET_AV=m
+CONFIG_DVB_BUDGET_PATCH=m
+
+#
+# Supported USB Adapters
+#
+CONFIG_DVB_USB=m
+# CONFIG_DVB_USB_DEBUG is not set
+CONFIG_DVB_USB_A800=m
+CONFIG_DVB_USB_DIBUSB_MB=m
+# CONFIG_DVB_USB_DIBUSB_MB_FAULTY is not set
+CONFIG_DVB_USB_DIBUSB_MC=m
+CONFIG_DVB_USB_UMT_010=m
+CONFIG_DVB_USB_CXUSB=m
+CONFIG_DVB_USB_DIGITV=m
+CONFIG_DVB_USB_VP7045=m
+CONFIG_DVB_USB_VP702X=m
+CONFIG_DVB_USB_GP8PSK=m
+CONFIG_DVB_USB_NOVA_T_USB2=m
+CONFIG_DVB_USB_DTT200U=m
+CONFIG_DVB_TTUSB_BUDGET=m
+CONFIG_DVB_TTUSB_DEC=m
+CONFIG_DVB_CINERGYT2=m
+CONFIG_DVB_CINERGYT2_TUNING=y
+CONFIG_DVB_CINERGYT2_STREAM_URB_COUNT=32
+CONFIG_DVB_CINERGYT2_STREAM_BUF_SIZE=512
+CONFIG_DVB_CINERGYT2_QUERY_INTERVAL=250
+CONFIG_DVB_CINERGYT2_ENABLE_RC_INPUT_DEVICE=y
+CONFIG_DVB_CINERGYT2_RC_QUERY_INTERVAL=100
+
+#
+# Supported FlexCopII (B2C2) Adapters
+#
+CONFIG_DVB_B2C2_FLEXCOP=m
+CONFIG_DVB_B2C2_FLEXCOP_PCI=m
+CONFIG_DVB_B2C2_FLEXCOP_USB=m
+# CONFIG_DVB_B2C2_FLEXCOP_DEBUG is not set
+
+#
+# Supported BT878 Adapters
+#
+CONFIG_DVB_BT8XX=m
+
+#
+# Supported Pluto2 Adapters
+#
+CONFIG_DVB_PLUTO2=m
+
+#
+# Supported DVB Frontends
+#
+
+#
+# Customise DVB Frontends
+#
+
+#
+# DVB-S (satellite) frontends
+#
+CONFIG_DVB_STV0299=m
+CONFIG_DVB_CX24110=m
+CONFIG_DVB_CX24123=m
+CONFIG_DVB_TDA8083=m
+CONFIG_DVB_MT312=m
+CONFIG_DVB_VES1X93=m
+CONFIG_DVB_S5H1420=m
+
+#
+# DVB-T (terrestrial) frontends
+#
+CONFIG_DVB_SP8870=m
+CONFIG_DVB_SP887X=m
+CONFIG_DVB_CX22700=m
+CONFIG_DVB_CX22702=m
+CONFIG_DVB_L64781=m
+CONFIG_DVB_TDA1004X=m
+CONFIG_DVB_NXT6000=m
+CONFIG_DVB_MT352=m
+CONFIG_DVB_ZL10353=m
+CONFIG_DVB_DIB3000MB=m
+CONFIG_DVB_DIB3000MC=m
+
+#
+# DVB-C (cable) frontends
+#
+CONFIG_DVB_VES1820=m
+CONFIG_DVB_TDA10021=m
+CONFIG_DVB_STV0297=m
+
+#
+# ATSC (North American/Korean Terrestrial/Cable DTV) frontends
+#
+CONFIG_DVB_NXT200X=m
+CONFIG_DVB_OR51211=m
+CONFIG_DVB_OR51132=m
+CONFIG_DVB_BCM3510=m
+CONFIG_DVB_LGDT330X=m
+
+#
+# Miscellaneous devices
+#
+CONFIG_DVB_PLL=m
+CONFIG_DVB_LNBP21=m
+CONFIG_DVB_ISL6421=m
+CONFIG_VIDEO_SAA7146=m
+CONFIG_VIDEO_SAA7146_VV=m
+CONFIG_VIDEO_VIDEOBUF=m
+CONFIG_VIDEO_TUNER=m
+CONFIG_VIDEO_BUF=m
+CONFIG_VIDEO_BUF_DVB=m
+CONFIG_VIDEO_BTCX=m
+CONFIG_VIDEO_IR=m
+CONFIG_VIDEO_TVEEPROM=m
+CONFIG_USB_DABUSB=m
+
+#
+# Graphics support
+#
+# CONFIG_FIRMWARE_EDID is not set
+CONFIG_FB=y
+CONFIG_FB_CFB_FILLRECT=y
+CONFIG_FB_CFB_COPYAREA=y
+CONFIG_FB_CFB_IMAGEBLIT=y
+CONFIG_FB_MACMODES=y
+CONFIG_FB_BACKLIGHT=y
+CONFIG_FB_MODE_HELPERS=y
+CONFIG_FB_TILEBLITTING=y
+CONFIG_FB_CIRRUS=m
+# CONFIG_FB_PM2 is not set
+# CONFIG_FB_CYBER2000 is not set
+CONFIG_FB_OF=y
+# CONFIG_FB_CONTROL is not set
+CONFIG_FB_PLATINUM=y
+CONFIG_FB_VALKYRIE=y
+CONFIG_FB_CT65550=y
+# CONFIG_FB_ASILIANT is not set
+# CONFIG_FB_IMSTT is not set
+# CONFIG_FB_VGA16 is not set
+# CONFIG_FB_S1D13XXX is not set
+CONFIG_FB_NVIDIA=m
+CONFIG_FB_NVIDIA_I2C=y
+CONFIG_FB_NVIDIA_BACKLIGHT=y
+CONFIG_FB_RIVA=m
+# CONFIG_FB_RIVA_I2C is not set
+# CONFIG_FB_RIVA_DEBUG is not set
+CONFIG_FB_RIVA_BACKLIGHT=y
+CONFIG_FB_MATROX=y
+CONFIG_FB_MATROX_MILLENIUM=y
+CONFIG_FB_MATROX_MYSTIQUE=y
+CONFIG_FB_MATROX_G=y
+CONFIG_FB_MATROX_I2C=m
+CONFIG_FB_MATROX_MAVEN=m
+CONFIG_FB_MATROX_MULTIHEAD=y
+CONFIG_FB_RADEON=y
+CONFIG_FB_RADEON_I2C=y
+CONFIG_FB_RADEON_BACKLIGHT=y
+# CONFIG_FB_RADEON_DEBUG is not set
+CONFIG_FB_ATY128=y
+CONFIG_FB_ATY128_BACKLIGHT=y
+CONFIG_FB_ATY=y
+CONFIG_FB_ATY_CT=y
+CONFIG_FB_ATY_GENERIC_LCD=y
+CONFIG_FB_ATY_GX=y
+CONFIG_FB_ATY_BACKLIGHT=y
+CONFIG_FB_SAVAGE=m
+CONFIG_FB_SAVAGE_I2C=y
+CONFIG_FB_SAVAGE_ACCEL=y
+# CONFIG_FB_SIS is not set
+CONFIG_FB_NEOMAGIC=m
+CONFIG_FB_KYRO=m
+CONFIG_FB_3DFX=m
+CONFIG_FB_3DFX_ACCEL=y
+CONFIG_FB_VOODOO1=m
+CONFIG_FB_TRIDENT=m
+CONFIG_FB_TRIDENT_ACCEL=y
+# CONFIG_FB_VIRTUAL is not set
+
+#
+# Console display driver support
+#
+CONFIG_VGA_CONSOLE=y
+CONFIG_VGACON_SOFT_SCROLLBACK=y
+CONFIG_VGACON_SOFT_SCROLLBACK_SIZE=64
+# CONFIG_MDA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y
+# CONFIG_FONTS is not set
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
+
+#
+# Logo configuration
+#
+CONFIG_LOGO=y
+# CONFIG_LOGO_LINUX_MONO is not set
+# CONFIG_LOGO_LINUX_VGA16 is not set
+CONFIG_LOGO_LINUX_CLUT224=y
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+CONFIG_BACKLIGHT_CLASS_DEVICE=y
+CONFIG_BACKLIGHT_DEVICE=y
+CONFIG_LCD_CLASS_DEVICE=m
+CONFIG_LCD_DEVICE=y
+
+#
+# Sound
+#
+CONFIG_SOUND=m
+CONFIG_DMASOUND_PMAC=m
+CONFIG_DMASOUND=m
+
+#
+# Advanced Linux Sound Architecture
+#
+CONFIG_SND=m
+CONFIG_SND_TIMER=m
+CONFIG_SND_PCM=m
+CONFIG_SND_HWDEP=m
+CONFIG_SND_RAWMIDI=m
+CONFIG_SND_SEQUENCER=m
+CONFIG_SND_SEQ_DUMMY=m
+CONFIG_SND_OSSEMUL=y
+CONFIG_SND_MIXER_OSS=m
+CONFIG_SND_PCM_OSS=m
+CONFIG_SND_PCM_OSS_PLUGINS=y
+CONFIG_SND_SEQUENCER_OSS=y
+CONFIG_SND_DYNAMIC_MINORS=y
+# CONFIG_SND_SUPPORT_OLD_API is not set
+CONFIG_SND_VERBOSE_PROCFS=y
+# CONFIG_SND_VERBOSE_PRINTK is not set
+# CONFIG_SND_DEBUG is not set
+
+#
+# Generic devices
+#
+CONFIG_SND_MPU401_UART=m
+CONFIG_SND_OPL3_LIB=m
+CONFIG_SND_OPL4_LIB=m
+CONFIG_SND_VX_LIB=m
+CONFIG_SND_AC97_CODEC=m
+CONFIG_SND_AC97_BUS=m
+CONFIG_SND_DUMMY=m
+CONFIG_SND_VIRMIDI=m
+CONFIG_SND_MTPAV=m
+# CONFIG_SND_SERIAL_U16550 is not set
+CONFIG_SND_MPU401=m
+
+#
+# ISA devices
+#
+CONFIG_SND_CS4231_LIB=m
+CONFIG_SND_ADLIB=m
+# CONFIG_SND_AD1816A is not set
+# CONFIG_SND_AD1848 is not set
+# CONFIG_SND_ALS100 is not set
+# CONFIG_SND_AZT2320 is not set
+# CONFIG_SND_CMI8330 is not set
+# CONFIG_SND_CS4231 is not set
+# CONFIG_SND_CS4232 is not set
+CONFIG_SND_CS4236=m
+# CONFIG_SND_DT019X is not set
+# CONFIG_SND_ES968 is not set
+# CONFIG_SND_ES1688 is not set
+# CONFIG_SND_ES18XX is not set
+# CONFIG_SND_GUSCLASSIC is not set
+# CONFIG_SND_GUSEXTREME is not set
+# CONFIG_SND_GUSMAX is not set
+# CONFIG_SND_INTERWAVE is not set
+# CONFIG_SND_INTERWAVE_STB is not set
+CONFIG_SND_OPL3SA2=m
+# CONFIG_SND_OPTI92X_AD1848 is not set
+# CONFIG_SND_OPTI92X_CS4231 is not set
+# CONFIG_SND_OPTI93X is not set
+CONFIG_SND_MIRO=m
+# CONFIG_SND_SB8 is not set
+CONFIG_SND_SB16=m
+CONFIG_SND_SBAWE=m
+# CONFIG_SND_SGALAXY is not set
+# CONFIG_SND_SSCAPE is not set
+# CONFIG_SND_WAVEFRONT is not set
+
+#
+# PCI devices
+#
+CONFIG_SND_AD1889=m
+CONFIG_SND_ALS300=m
+CONFIG_SND_ALS4000=m
+CONFIG_SND_ALI5451=m
+CONFIG_SND_ATIIXP=m
+CONFIG_SND_ATIIXP_MODEM=m
+CONFIG_SND_AU8810=m
+CONFIG_SND_AU8820=m
+CONFIG_SND_AU8830=m
+CONFIG_SND_AZT3328=m
+CONFIG_SND_BT87X=m
+# CONFIG_SND_BT87X_OVERCLOCK is not set
+CONFIG_SND_CA0106=m
+CONFIG_SND_CMIPCI=m
+CONFIG_SND_CS4281=m
+CONFIG_SND_CS46XX=m
+CONFIG_SND_CS46XX_NEW_DSP=y
+CONFIG_SND_DARLA20=m
+CONFIG_SND_GINA20=m
+CONFIG_SND_LAYLA20=m
+CONFIG_SND_DARLA24=m
+CONFIG_SND_GINA24=m
+CONFIG_SND_LAYLA24=m
+CONFIG_SND_MONA=m
+CONFIG_SND_MIA=m
+CONFIG_SND_ECHO3G=m
+CONFIG_SND_INDIGO=m
+CONFIG_SND_INDIGOIO=m
+CONFIG_SND_INDIGODJ=m
+CONFIG_SND_EMU10K1=m
+CONFIG_SND_EMU10K1X=m
+CONFIG_SND_ENS1370=m
+CONFIG_SND_ENS1371=m
+CONFIG_SND_ES1938=m
+CONFIG_SND_ES1968=m
+CONFIG_SND_FM801=m
+CONFIG_SND_FM801_TEA575X_BOOL=y
+CONFIG_SND_FM801_TEA575X=m
+CONFIG_SND_HDA_INTEL=m
+CONFIG_SND_HDSP=m
+CONFIG_SND_HDSPM=m
+CONFIG_SND_ICE1712=m
+CONFIG_SND_ICE1724=m
+CONFIG_SND_INTEL8X0=m
+CONFIG_SND_INTEL8X0M=m
+CONFIG_SND_KORG1212=m
+CONFIG_SND_MAESTRO3=m
+CONFIG_SND_MIXART=m
+CONFIG_SND_NM256=m
+CONFIG_SND_PCXHR=m
+CONFIG_SND_RIPTIDE=m
+CONFIG_SND_RME32=m
+CONFIG_SND_RME96=m
+CONFIG_SND_RME9652=m
+CONFIG_SND_SONICVIBES=m
+CONFIG_SND_TRIDENT=m
+CONFIG_SND_VIA82XX=m
+CONFIG_SND_VIA82XX_MODEM=m
+CONFIG_SND_VX222=m
+CONFIG_SND_YMFPCI=m
+
+#
+# ALSA PowerMac devices
+#
+CONFIG_SND_POWERMAC=m
+CONFIG_SND_POWERMAC_AUTO_DRC=y
+
+#
+# Apple Onboard Audio driver
+#
+CONFIG_SND_AOA=m
+CONFIG_SND_AOA_FABRIC_LAYOUT=m
+CONFIG_SND_AOA_ONYX=m
+CONFIG_SND_AOA_TAS=m
+CONFIG_SND_AOA_TOONIE=m
+CONFIG_SND_AOA_SOUNDBUS=m
+CONFIG_SND_AOA_SOUNDBUS_I2S=m
+
+#
+# USB devices
+#
+CONFIG_SND_USB_AUDIO=m
+CONFIG_SND_USB_USX2Y=m
+
+#
+# PCMCIA devices
+#
+# CONFIG_SND_VXPOCKET is not set
+# CONFIG_SND_PDAUDIOCF is not set
+
+#
+# Open Sound System
+#
+# CONFIG_SOUND_PRIME is not set
+
+#
+# USB support
+#
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB_ARCH_HAS_EHCI=y
+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_SUSPEND is not set
+# CONFIG_USB_OTG is not set
+
+#
+# USB Host Controller Drivers
+#
+CONFIG_USB_EHCI_HCD=m
+CONFIG_USB_EHCI_SPLIT_ISO=y
+CONFIG_USB_EHCI_ROOT_HUB_TT=y
+CONFIG_USB_EHCI_TT_NEWSCHED=y
+CONFIG_USB_ISP116X_HCD=m
+CONFIG_USB_OHCI_HCD=m
+# CONFIG_USB_OHCI_BIG_ENDIAN is not set
+CONFIG_USB_OHCI_LITTLE_ENDIAN=y
+CONFIG_USB_UHCI_HCD=m
+CONFIG_USB_SL811_HCD=m
+CONFIG_USB_SL811_CS=m
+
+#
+# USB Device Class drivers
+#
+CONFIG_USB_ACM=m
+CONFIG_USB_PRINTER=m
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+#
+
+#
+# may also be needed; see USB_STORAGE Help for more information
+#
+CONFIG_USB_STORAGE=m
+# CONFIG_USB_STORAGE_DEBUG is not set
+CONFIG_USB_STORAGE_DATAFAB=y
+CONFIG_USB_STORAGE_FREECOM=y
+CONFIG_USB_STORAGE_ISD200=y
+CONFIG_USB_STORAGE_DPCM=y
+CONFIG_USB_STORAGE_USBAT=y
+CONFIG_USB_STORAGE_SDDR09=y
+CONFIG_USB_STORAGE_SDDR55=y
+CONFIG_USB_STORAGE_JUMPSHOT=y
+CONFIG_USB_STORAGE_ALAUDA=y
+CONFIG_USB_LIBUSUAL=y
+
+#
+# USB Input Devices
+#
+CONFIG_USB_HID=y
+CONFIG_USB_HIDINPUT=y
+CONFIG_USB_HIDINPUT_POWERBOOK=y
+CONFIG_HID_FF=y
+CONFIG_HID_PID=y
+CONFIG_LOGITECH_FF=y
+CONFIG_THRUSTMASTER_FF=y
+CONFIG_USB_HIDDEV=y
+CONFIG_USB_AIPTEK=m
+CONFIG_USB_WACOM=m
+CONFIG_USB_ACECAD=m
+CONFIG_USB_KBTAB=m
+CONFIG_USB_POWERMATE=m
+CONFIG_USB_TOUCHSCREEN=m
+CONFIG_USB_TOUCHSCREEN_EGALAX=y
+CONFIG_USB_TOUCHSCREEN_PANJIT=y
+CONFIG_USB_TOUCHSCREEN_3M=y
+CONFIG_USB_TOUCHSCREEN_ITM=y
+# CONFIG_USB_YEALINK is not set
+CONFIG_USB_XPAD=m
+CONFIG_USB_ATI_REMOTE=m
+CONFIG_USB_ATI_REMOTE2=m
+CONFIG_USB_KEYSPAN_REMOTE=m
+CONFIG_USB_APPLETOUCH=m
+
+#
+# USB Imaging devices
+#
+CONFIG_USB_MDC800=m
+CONFIG_USB_MICROTEK=m
+
+#
+# USB Network Adapters
+#
+CONFIG_USB_CATC=m
+CONFIG_USB_KAWETH=m
+CONFIG_USB_PEGASUS=m
+CONFIG_USB_RTL8150=m
+CONFIG_USB_USBNET=m
+CONFIG_USB_NET_AX8817X=m
+CONFIG_USB_NET_CDCETHER=m
+CONFIG_USB_NET_GL620A=m
+CONFIG_USB_NET_NET1080=m
+CONFIG_USB_NET_PLUSB=m
+CONFIG_USB_NET_RNDIS_HOST=m
+CONFIG_USB_NET_CDC_SUBSET=m
+CONFIG_USB_ALI_M5632=y
+CONFIG_USB_AN2720=y
+CONFIG_USB_BELKIN=y
+CONFIG_USB_ARMLINUX=y
+CONFIG_USB_EPSON2888=y
+CONFIG_USB_NET_ZAURUS=m
+CONFIG_USB_MON=y
+
+#
+# USB port drivers
+#
+CONFIG_USB_USS720=m
+
+#
+# USB Serial Converter support
+#
+CONFIG_USB_SERIAL=m
+CONFIG_USB_SERIAL_GENERIC=y
+CONFIG_USB_SERIAL_AIRPRIME=m
+CONFIG_USB_SERIAL_ARK3116=m
+CONFIG_USB_SERIAL_BELKIN=m
+CONFIG_USB_SERIAL_WHITEHEAT=m
+CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m
+CONFIG_USB_SERIAL_CP2101=m
+CONFIG_USB_SERIAL_CYPRESS_M8=m
+CONFIG_USB_SERIAL_EMPEG=m
+CONFIG_USB_SERIAL_FTDI_SIO=m
+CONFIG_USB_SERIAL_FUNSOFT=m
+CONFIG_USB_SERIAL_VISOR=m
+CONFIG_USB_SERIAL_IPAQ=m
+CONFIG_USB_SERIAL_IR=m
+CONFIG_USB_SERIAL_EDGEPORT=m
+CONFIG_USB_SERIAL_EDGEPORT_TI=m
+CONFIG_USB_SERIAL_GARMIN=m
+CONFIG_USB_SERIAL_IPW=m
+CONFIG_USB_SERIAL_KEYSPAN_PDA=m
+CONFIG_USB_SERIAL_KEYSPAN=m
+CONFIG_USB_SERIAL_KEYSPAN_MPR=y
+CONFIG_USB_SERIAL_KEYSPAN_USA28=y
+CONFIG_USB_SERIAL_KEYSPAN_USA28X=y
+CONFIG_USB_SERIAL_KEYSPAN_USA28XA=y
+CONFIG_USB_SERIAL_KEYSPAN_USA28XB=y
+CONFIG_USB_SERIAL_KEYSPAN_USA19=y
+CONFIG_USB_SERIAL_KEYSPAN_USA18X=y
+CONFIG_USB_SERIAL_KEYSPAN_USA19W=y
+CONFIG_USB_SERIAL_KEYSPAN_USA19QW=y
+CONFIG_USB_SERIAL_KEYSPAN_USA19QI=y
+CONFIG_USB_SERIAL_KEYSPAN_USA49W=y
+CONFIG_USB_SERIAL_KEYSPAN_USA49WLC=y
+CONFIG_USB_SERIAL_KLSI=m
+CONFIG_USB_SERIAL_KOBIL_SCT=m
+CONFIG_USB_SERIAL_MCT_U232=m
+CONFIG_USB_SERIAL_NAVMAN=m
+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=m
+CONFIG_USB_SERIAL_TI=m
+CONFIG_USB_SERIAL_CYBERJACK=m
+CONFIG_USB_SERIAL_XIRCOM=m
+CONFIG_USB_SERIAL_OPTION=m
+CONFIG_USB_SERIAL_OMNINET=m
+CONFIG_USB_EZUSB=y
+
+#
+# USB Miscellaneous drivers
+#
+CONFIG_USB_EMI62=m
+CONFIG_USB_EMI26=m
+CONFIG_USB_AUERSWALD=m
+CONFIG_USB_RIO500=m
+CONFIG_USB_LEGOTOWER=m
+CONFIG_USB_LCD=m
+CONFIG_USB_LED=m
+# CONFIG_USB_CYPRESS_CY7C63 is not set
+# CONFIG_USB_CYTHERM is not set
+CONFIG_USB_PHIDGETKIT=m
+CONFIG_USB_PHIDGETSERVO=m
+CONFIG_USB_IDMOUSE=m
+CONFIG_USB_APPLEDISPLAY=m
+CONFIG_USB_SISUSBVGA=m
+CONFIG_USB_SISUSBVGA_CON=y
+CONFIG_USB_LD=m
+CONFIG_USB_TEST=m
+
+#
+# USB DSL modem support
+#
+CONFIG_USB_ATM=m
+CONFIG_USB_SPEEDTOUCH=m
+CONFIG_USB_CXACRU=m
+CONFIG_USB_UEAGLEATM=m
+CONFIG_USB_XUSBATM=m
+
+#
+# USB Gadget Support
+#
+# CONFIG_USB_GADGET is not set
+
+#
+# MMC/SD Card support
+#
+CONFIG_MMC=m
+# CONFIG_MMC_DEBUG is not set
+CONFIG_MMC_BLOCK=m
+CONFIG_MMC_SDHCI=m
+CONFIG_MMC_WBSD=m
+
+#
+# LED devices
+#
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+
+#
+# LED drivers
+#
+
+#
+# LED Triggers
+#
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_LEDS_TRIGGER_TIMER=m
+CONFIG_LEDS_TRIGGER_IDE_DISK=y
+CONFIG_LEDS_TRIGGER_HEARTBEAT=m
+
+#
+# InfiniBand support
+#
+CONFIG_INFINIBAND=m
+CONFIG_INFINIBAND_USER_MAD=m
+CONFIG_INFINIBAND_USER_ACCESS=m
+CONFIG_INFINIBAND_ADDR_TRANS=y
+CONFIG_INFINIBAND_MTHCA=m
+CONFIG_INFINIBAND_MTHCA_DEBUG=y
+CONFIG_INFINIBAND_IPOIB=m
+CONFIG_INFINIBAND_IPOIB_DEBUG=y
+CONFIG_INFINIBAND_IPOIB_DEBUG_DATA=y
+CONFIG_INFINIBAND_SRP=m
+CONFIG_INFINIBAND_ISER=m
+
+#
+# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
+#
+
+#
+# Real Time Clock
+#
+CONFIG_RTC_LIB=m
+CONFIG_RTC_CLASS=m
+
+#
+# RTC interfaces
+#
+CONFIG_RTC_INTF_SYSFS=m
+CONFIG_RTC_INTF_PROC=m
+CONFIG_RTC_INTF_DEV=m
+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
+
+#
+# RTC drivers
+#
+CONFIG_RTC_DRV_X1205=m
+CONFIG_RTC_DRV_DS1307=m
+CONFIG_RTC_DRV_DS1553=m
+CONFIG_RTC_DRV_ISL1208=m
+CONFIG_RTC_DRV_DS1672=m
+CONFIG_RTC_DRV_DS1742=m
+CONFIG_RTC_DRV_PCF8563=m
+CONFIG_RTC_DRV_PCF8583=m
+CONFIG_RTC_DRV_RS5C372=m
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_TEST is not set
+CONFIG_RTC_DRV_V3020=m
+
+#
+# DMA Engine support
+#
+CONFIG_DMA_ENGINE=y
+
+#
+# DMA Clients
+#
+CONFIG_NET_DMA=y
+
+#
+# DMA Devices
+#
+CONFIG_INTEL_IOATDMA=m
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+CONFIG_EXT2_FS_POSIX_ACL=y
+CONFIG_EXT2_FS_SECURITY=y
+CONFIG_EXT2_FS_XIP=y
+CONFIG_FS_XIP=y
+CONFIG_EXT3_FS=m
+CONFIG_EXT3_FS_XATTR=y
+CONFIG_EXT3_FS_POSIX_ACL=y
+CONFIG_EXT3_FS_SECURITY=y
+CONFIG_JBD=m
+# CONFIG_JBD_DEBUG is not set
+CONFIG_FS_MBCACHE=y
+CONFIG_REISERFS_FS=m
+# CONFIG_REISERFS_CHECK is not set
+CONFIG_REISERFS_PROC_INFO=y
+CONFIG_REISERFS_FS_XATTR=y
+CONFIG_REISERFS_FS_POSIX_ACL=y
+CONFIG_REISERFS_FS_SECURITY=y
+CONFIG_JFS_FS=m
+CONFIG_JFS_POSIX_ACL=y
+CONFIG_JFS_SECURITY=y
+# CONFIG_JFS_DEBUG is not set
+# CONFIG_JFS_STATISTICS is not set
+CONFIG_FS_POSIX_ACL=y
+CONFIG_XFS_FS=m
+CONFIG_XFS_QUOTA=y
+CONFIG_XFS_SECURITY=y
+CONFIG_XFS_POSIX_ACL=y
+# CONFIG_XFS_RT is not set
+CONFIG_OCFS2_FS=m
+# CONFIG_OCFS2_DEBUG_MASKLOG is not set
+CONFIG_MINIX_FS=m
+CONFIG_ROMFS_FS=m
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+CONFIG_QUOTA=y
+# CONFIG_QFMT_V1 is not set
+CONFIG_QFMT_V2=y
+CONFIG_QUOTACTL=y
+CONFIG_DNOTIFY=y
+CONFIG_AUTOFS_FS=m
+CONFIG_AUTOFS4_FS=m
+CONFIG_FUSE_FS=m
+
+#
+# Caches
+#
+CONFIG_FSCACHE=m
+
+#
+# CD-ROM/DVD Filesystems
+#
+CONFIG_ISO9660_FS=y
+CONFIG_JOLIET=y
+CONFIG_ZISOFS=y
+CONFIG_ZISOFS_FS=y
+CONFIG_UDF_FS=m
+CONFIG_UDF_NLS=y
+CONFIG_CACHEFILES=m
+CONFIG_CACHEFILES_DEBUG=y
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=m
+CONFIG_MSDOS_FS=m
+CONFIG_VFAT_FS=m
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="ascii"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_RAMFS=y
+CONFIG_CONFIGFS_FS=m
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+CONFIG_AFFS_FS=m
+CONFIG_HFS_FS=m
+CONFIG_HFSPLUS_FS=m
+CONFIG_BEFS_FS=m
+# CONFIG_BEFS_DEBUG is not set
+CONFIG_BFS_FS=m
+CONFIG_EFS_FS=m
+# CONFIG_JFFS_FS is not set
+CONFIG_JFFS2_FS=m
+CONFIG_JFFS2_FS_DEBUG=0
+CONFIG_JFFS2_FS_WRITEBUFFER=y
+CONFIG_JFFS2_SUMMARY=y
+# 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=m
+CONFIG_SQUASHFS=m
+# CONFIG_SQUASHFS_EMBEDDED is not set
+CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3
+# CONFIG_SQUASHFS_VMALLOC is not set
+CONFIG_VXFS_FS=m
+# CONFIG_HPFS_FS is not set
+CONFIG_QNX4FS_FS=m
+CONFIG_SYSV_FS=m
+CONFIG_UFS_FS=m
+# CONFIG_UFS_FS_WRITE is not set
+# CONFIG_UFS_DEBUG is not set
+
+#
+# Network File Systems
+#
+CONFIG_NFS_FS=m
+CONFIG_NFS_V3=y
+CONFIG_NFS_V3_ACL=y
+CONFIG_NFS_V4=y
+CONFIG_NFS_FSCACHE=y
+CONFIG_NFS_DIRECTIO=y
+CONFIG_NFSD=m
+CONFIG_NFSD_V2_ACL=y
+CONFIG_NFSD_V3=y
+CONFIG_NFSD_V3_ACL=y
+CONFIG_NFSD_V4=y
+CONFIG_NFSD_TCP=y
+CONFIG_LOCKD=m
+CONFIG_LOCKD_V4=y
+CONFIG_EXPORTFS=m
+CONFIG_NFS_ACL_SUPPORT=m
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=m
+CONFIG_SUNRPC_GSS=m
+CONFIG_RPCSEC_GSS_KRB5=m
+CONFIG_RPCSEC_GSS_SPKM3=m
+# CONFIG_SMB_FS is not set
+CONFIG_CIFS=m
+# CONFIG_CIFS_STATS is not set
+CONFIG_CIFS_WEAK_PW_HASH=y
+CONFIG_CIFS_XATTR=y
+CONFIG_CIFS_POSIX=y
+# CONFIG_CIFS_DEBUG2 is not set
+# CONFIG_CIFS_EXPERIMENTAL is not set
+CONFIG_NCP_FS=m
+CONFIG_NCPFS_PACKET_SIGNING=y
+CONFIG_NCPFS_IOCTL_LOCKING=y
+CONFIG_NCPFS_STRONG=y
+CONFIG_NCPFS_NFS_NS=y
+CONFIG_NCPFS_OS2_NS=y
+CONFIG_NCPFS_SMALLDOS=y
+CONFIG_NCPFS_NLS=y
+CONFIG_NCPFS_EXTRAS=y
+CONFIG_CODA_FS=m
+# CONFIG_CODA_FS_OLD_API is not set
+# CONFIG_AFS_FS is not set
+CONFIG_9P_FS=m
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+CONFIG_OSF_PARTITION=y
+CONFIG_AMIGA_PARTITION=y
+# CONFIG_ATARI_PARTITION is not set
+CONFIG_MAC_PARTITION=y
+CONFIG_MSDOS_PARTITION=y
+CONFIG_BSD_DISKLABEL=y
+CONFIG_MINIX_SUBPARTITION=y
+CONFIG_SOLARIS_X86_PARTITION=y
+CONFIG_UNIXWARE_DISKLABEL=y
+# CONFIG_LDM_PARTITION is not set
+CONFIG_SGI_PARTITION=y
+# CONFIG_ULTRIX_PARTITION is not set
+CONFIG_SUN_PARTITION=y
+CONFIG_KARMA_PARTITION=y
+CONFIG_EFI_PARTITION=y
+
+#
+# Native Language Support
+#
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="utf8"
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_CODEPAGE_737=m
+CONFIG_NLS_CODEPAGE_775=m
+CONFIG_NLS_CODEPAGE_850=m
+CONFIG_NLS_CODEPAGE_852=m
+CONFIG_NLS_CODEPAGE_855=m
+CONFIG_NLS_CODEPAGE_857=m
+CONFIG_NLS_CODEPAGE_860=m
+CONFIG_NLS_CODEPAGE_861=m
+CONFIG_NLS_CODEPAGE_862=m
+CONFIG_NLS_CODEPAGE_863=m
+CONFIG_NLS_CODEPAGE_864=m
+CONFIG_NLS_CODEPAGE_865=m
+CONFIG_NLS_CODEPAGE_866=m
+CONFIG_NLS_CODEPAGE_869=m
+CONFIG_NLS_CODEPAGE_936=m
+CONFIG_NLS_CODEPAGE_950=m
+CONFIG_NLS_CODEPAGE_932=m
+CONFIG_NLS_CODEPAGE_949=m
+CONFIG_NLS_CODEPAGE_874=m
+CONFIG_NLS_ISO8859_8=m
+CONFIG_NLS_CODEPAGE_1250=m
+CONFIG_NLS_CODEPAGE_1251=m
+CONFIG_NLS_ASCII=y
+CONFIG_NLS_ISO8859_1=m
+CONFIG_NLS_ISO8859_2=m
+CONFIG_NLS_ISO8859_3=m
+CONFIG_NLS_ISO8859_4=m
+CONFIG_NLS_ISO8859_5=m
+CONFIG_NLS_ISO8859_6=m
+CONFIG_NLS_ISO8859_7=m
+CONFIG_NLS_ISO8859_9=m
+CONFIG_NLS_ISO8859_13=m
+CONFIG_NLS_ISO8859_14=m
+CONFIG_NLS_ISO8859_15=m
+CONFIG_NLS_KOI8_R=m
+CONFIG_NLS_KOI8_U=m
+CONFIG_NLS_UTF8=m
+
+#
+# Library routines
+#
+CONFIG_CRC_CCITT=m
+CONFIG_CRC16=m
+CONFIG_CRC32=y
+CONFIG_LIBCRC32C=m
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=m
+CONFIG_REED_SOLOMON=m
+CONFIG_REED_SOLOMON_DEC16=y
+CONFIG_TEXTSEARCH=y
+CONFIG_TEXTSEARCH_KMP=m
+CONFIG_TEXTSEARCH_BM=m
+CONFIG_TEXTSEARCH_FSM=m
+CONFIG_PLIST=y
+
+#
+# Instrumentation Support
+#
+CONFIG_PROFILING=y
+CONFIG_OPROFILE=m
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_UNUSED_SYMBOLS is not set
+CONFIG_DEBUG_KERNEL=y
+CONFIG_LOG_BUF_SHIFT=17
+CONFIG_DETECT_SOFTLOCKUP=y
+CONFIG_SCHEDSTATS=y
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
+CONFIG_DEBUG_SPINLOCK=y
+# CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_RWSEMS is not set
+CONFIG_DEBUG_SPINLOCK_SLEEP=y
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+# CONFIG_DEBUG_KOBJECT is not set
+CONFIG_DEBUG_HIGHMEM=y
+CONFIG_DEBUG_INFO=y
+CONFIG_DEBUG_FS=y
+# CONFIG_DEBUG_VM is not set
+CONFIG_DEBUG_LIST=y
+# CONFIG_FORCED_INLINING is not set
+CONFIG_BOOT_DELAY=y
+# CONFIG_RCU_TORTURE_TEST is not set
+CONFIG_DEBUGGER=y
+CONFIG_XMON=y
+CONFIG_XMON_DEFAULT=y
+# CONFIG_BDI_SWITCH is not set
+CONFIG_BOOTX_TEXT=y
+# CONFIG_PPC_EARLY_DEBUG is not set
+
+#
+# Security options
+#
+CONFIG_KEYS=y
+CONFIG_KEYS_DEBUG_PROC_KEYS=y
+CONFIG_SECURITY=y
+CONFIG_SECURITY_NETWORK=y
+# CONFIG_SECURITY_NETWORK_XFRM is not set
+CONFIG_SECURITY_CAPABILITIES=y
+# CONFIG_SECURITY_ROOTPLUG is not set
+# CONFIG_SECURITY_SECLVL is not set
+CONFIG_SECURITY_SELINUX=y
+CONFIG_SECURITY_SELINUX_BOOTPARAM=y
+CONFIG_SECURITY_SELINUX_BOOTPARAM_VALUE=1
+CONFIG_SECURITY_SELINUX_DISABLE=y
+CONFIG_SECURITY_SELINUX_DEVELOP=y
+CONFIG_SECURITY_SELINUX_AVC_STATS=y
+CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE=1
+# CONFIG_SECURITY_SELINUX_ENABLE_SECMARK_DEFAULT is not set
+# CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX is not set
+
+#
+# Cryptographic options
+#
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_NULL=m
+CONFIG_CRYPTO_MD4=m
+CONFIG_CRYPTO_MD5=m
+CONFIG_CRYPTO_SHA1=y
+CONFIG_CRYPTO_SHA256=m
+CONFIG_CRYPTO_SHA512=m
+CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_TGR192=m
+CONFIG_CRYPTO_DES=m
+CONFIG_CRYPTO_BLOWFISH=m
+CONFIG_CRYPTO_TWOFISH=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_TEST is not set
+CONFIG_CRYPTO_SIGNATURE=y
+CONFIG_CRYPTO_SIGNATURE_DSA=y
+CONFIG_CRYPTO_MPILIB=y
+
+#
+# Hardware crypto devices
+#
diff --git a/configs/kernel-2.6.18-ppc.config b/configs/kernel-2.6.18-ppc.config
new file mode 100644
index 000000000..1db169fcf
--- /dev/null
+++ b/configs/kernel-2.6.18-ppc.config
@@ -0,0 +1,3208 @@
+# powerpc
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.18.2-rc1
+# Mon Nov 13 09:44:41 2006
+#
+# CONFIG_PPC64 is not set
+CONFIG_PPC32=y
+CONFIG_PPC_MERGE=y
+CONFIG_MMU=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_IRQ_PER_CPU=y
+CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_PPC=y
+CONFIG_EARLY_PRINTK=y
+CONFIG_GENERIC_NVRAM=y
+CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
+CONFIG_ARCH_MAY_HAVE_PC_FDC=y
+CONFIG_PPC_OF=y
+CONFIG_PPC_UDBG_16550=y
+# CONFIG_GENERIC_TBSYNC is not set
+CONFIG_AUDIT_ARCH=y
+# CONFIG_DEFAULT_UIMAGE is not set
+
+#
+# Processor support
+#
+CONFIG_CLASSIC32=y
+# CONFIG_PPC_52xx is not set
+# CONFIG_PPC_82xx is not set
+# CONFIG_PPC_83xx is not set
+# CONFIG_PPC_85xx is not set
+# CONFIG_PPC_86xx 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_PPC_FPU=y
+CONFIG_ALTIVEC=y
+CONFIG_PPC_STD_MMU=y
+CONFIG_PPC_STD_MMU_32=y
+# CONFIG_SMP is not set
+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=y
+CONFIG_SYSVIPC=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_BSD_PROCESS_ACCT=y
+# CONFIG_BSD_PROCESS_ACCT_V3 is not set
+CONFIG_TASKSTATS=y
+CONFIG_TASK_DELAY_ACCT=y
+CONFIG_AUDIT=y
+CONFIG_AUDITSYSCALL=y
+# CONFIG_IKCONFIG is not set
+CONFIG_RELAY=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+# CONFIG_EMBEDDED is not set
+CONFIG_SYSCTL=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
+CONFIG_KALLSYMS_EXTRA_PASS=y
+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=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+CONFIG_MODULE_SIG=y
+# CONFIG_MODULE_SIG_FORCE is not set
+CONFIG_KMOD=y
+
+#
+# Process debugging support
+#
+CONFIG_UTRACE=y
+CONFIG_PTRACE=y
+
+#
+# Block layer
+#
+CONFIG_LBD=y
+CONFIG_BLK_DEV_IO_TRACE=y
+CONFIG_LSF=y
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_DEFAULT_AS is not set
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+
+#
+# Platform support
+#
+CONFIG_PPC_MULTIPLATFORM=y
+# CONFIG_PPC_ISERIES is not set
+# CONFIG_EMBEDDED6xx is not set
+# CONFIG_APUS is not set
+CONFIG_PPC_CHRP=y
+CONFIG_PPC_PMAC=y
+# CONFIG_PPC_CELL is not set
+# CONFIG_PPC_CELL_NATIVE is not set
+# CONFIG_UDBG_RTAS_CONSOLE is not set
+# CONFIG_MAMBO is not set
+CONFIG_PPC_RTAS=y
+# CONFIG_RTAS_ERROR_LOGGING is not set
+# CONFIG_RTAS_PROC is not set
+# CONFIG_MMIO_NVRAM is not set
+CONFIG_PPC_MPC106=y
+# CONFIG_PPC_970_NAP is not set
+CONFIG_CPU_FREQ=y
+CONFIG_CPU_FREQ_TABLE=y
+CONFIG_CPU_FREQ_DEBUG=y
+CONFIG_CPU_FREQ_STAT=m
+CONFIG_CPU_FREQ_STAT_DETAILS=y
+# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set
+CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE=y
+CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
+CONFIG_CPU_FREQ_GOV_POWERSAVE=m
+CONFIG_CPU_FREQ_GOV_USERSPACE=y
+CONFIG_CPU_FREQ_GOV_ONDEMAND=m
+CONFIG_CPU_FREQ_GOV_CONSERVATIVE=m
+CONFIG_CPU_FREQ_PMAC=y
+# CONFIG_PPC601_SYNC_FIX is not set
+CONFIG_TAU=y
+# CONFIG_TAU_INT is not set
+CONFIG_TAU_AVERAGE=y
+# CONFIG_WANT_EARLY_SERIAL is not set
+CONFIG_MPIC=y
+
+#
+# Kernel options
+#
+CONFIG_HIGHMEM=y
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
+# CONFIG_PREEMPT_NONE is not set
+CONFIG_PREEMPT_VOLUNTARY=y
+# CONFIG_PREEMPT is not set
+CONFIG_BINFMT_ELF=y
+CONFIG_BINFMT_MISC=y
+CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
+# CONFIG_KEXEC is not set
+CONFIG_ARCH_FLATMEM_ENABLE=y
+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=y
+CONFIG_PROC_DEVICETREE=y
+# CONFIG_CMDLINE_BOOL is not set
+CONFIG_PM=y
+CONFIG_PM_LEGACY=y
+# CONFIG_PM_DEBUG is not set
+CONFIG_SOFTWARE_SUSPEND=y
+CONFIG_PM_STD_PARTITION=""
+# CONFIG_SECCOMP is not set
+CONFIG_ISA_DMA_API=y
+
+#
+# Bus options
+#
+CONFIG_ISA=y
+CONFIG_GENERIC_ISA_DMA=y
+# CONFIG_MPIC_WEIRD is not set
+CONFIG_PPC_I8259=y
+CONFIG_PPC_INDIRECT_PCI=y
+CONFIG_PCI=y
+CONFIG_PCI_DOMAINS=y
+CONFIG_PCIEPORTBUS=y
+# CONFIG_PCI_DEBUG is not set
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+CONFIG_PCCARD=y
+# CONFIG_PCMCIA_DEBUG is not set
+CONFIG_PCMCIA=y
+CONFIG_PCMCIA_LOAD_CIS=y
+CONFIG_PCMCIA_IOCTL=y
+CONFIG_CARDBUS=y
+
+#
+# PC-card bridges
+#
+CONFIG_YENTA=y
+CONFIG_YENTA_O2=y
+CONFIG_YENTA_RICOH=y
+CONFIG_YENTA_TI=y
+CONFIG_YENTA_ENE_TUNE=y
+CONFIG_YENTA_TOSHIBA=y
+CONFIG_PD6729=m
+CONFIG_I82092=m
+# CONFIG_I82365 is not set
+# CONFIG_TCIC is not set
+CONFIG_PCMCIA_PROBE=y
+CONFIG_PCCARD_NONSTATIC=y
+
+#
+# PCI Hotplug Support
+#
+# CONFIG_HOTPLUG_PCI is not set
+
+#
+# Advanced setup
+#
+CONFIG_ADVANCED_OPTIONS=y
+# CONFIG_HIGHMEM_START_BOOL is not set
+CONFIG_HIGHMEM_START=0xfe000000
+# CONFIG_LOWMEM_SIZE_BOOL is not set
+CONFIG_LOWMEM_SIZE=0x30000000
+# CONFIG_KERNEL_START_BOOL is not set
+CONFIG_KERNEL_START=0xc0000000
+# CONFIG_TASK_SIZE_BOOL is not set
+CONFIG_TASK_SIZE=0x80000000
+CONFIG_BOOT_LOAD=0x00800000
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+# CONFIG_NETDEBUG is not set
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=y
+CONFIG_NET_KEY=m
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_ASK_IP_FIB_HASH=y
+# 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
+# CONFIG_IP_PNP is not set
+CONFIG_NET_IPIP=m
+CONFIG_NET_IPGRE=m
+CONFIG_NET_IPGRE_BROADCAST=y
+CONFIG_IP_MROUTE=y
+CONFIG_IP_PIMSM_V1=y
+CONFIG_IP_PIMSM_V2=y
+# CONFIG_ARPD is not set
+CONFIG_SYN_COOKIES=y
+CONFIG_INET_AH=m
+CONFIG_INET_ESP=m
+CONFIG_INET_IPCOMP=m
+CONFIG_INET_XFRM_TUNNEL=m
+CONFIG_INET_TUNNEL=m
+CONFIG_INET_XFRM_MODE_TRANSPORT=m
+CONFIG_INET_XFRM_MODE_TUNNEL=m
+CONFIG_INET_DIAG=m
+CONFIG_INET_TCP_DIAG=m
+CONFIG_TCP_CONG_ADVANCED=y
+
+#
+# TCP congestion control
+#
+CONFIG_TCP_CONG_BIC=y
+CONFIG_TCP_CONG_CUBIC=m
+CONFIG_TCP_CONG_WESTWOOD=m
+CONFIG_TCP_CONG_HTCP=m
+CONFIG_TCP_CONG_HSTCP=m
+CONFIG_TCP_CONG_HYBLA=m
+CONFIG_TCP_CONG_VEGAS=m
+CONFIG_TCP_CONG_SCALABLE=m
+CONFIG_TCP_CONG_LP=m
+CONFIG_TCP_CONG_VENO=m
+
+#
+# IP: Virtual Server Configuration
+#
+CONFIG_IP_VS=m
+# CONFIG_IP_VS_DEBUG is not set
+CONFIG_IP_VS_TAB_BITS=12
+
+#
+# IPVS transport protocol load balancing support
+#
+CONFIG_IP_VS_PROTO_TCP=y
+CONFIG_IP_VS_PROTO_UDP=y
+CONFIG_IP_VS_PROTO_ESP=y
+CONFIG_IP_VS_PROTO_AH=y
+
+#
+# IPVS scheduler
+#
+CONFIG_IP_VS_RR=m
+CONFIG_IP_VS_WRR=m
+CONFIG_IP_VS_LC=m
+CONFIG_IP_VS_WLC=m
+CONFIG_IP_VS_LBLC=m
+CONFIG_IP_VS_LBLCR=m
+CONFIG_IP_VS_DH=m
+CONFIG_IP_VS_SH=m
+CONFIG_IP_VS_SED=m
+CONFIG_IP_VS_NQ=m
+
+#
+# IPVS application helper
+#
+CONFIG_IP_VS_FTP=m
+CONFIG_IPV6=m
+CONFIG_IPV6_PRIVACY=y
+CONFIG_IPV6_ROUTER_PREF=y
+CONFIG_IPV6_ROUTE_INFO=y
+CONFIG_INET6_AH=m
+CONFIG_INET6_ESP=m
+CONFIG_INET6_IPCOMP=m
+CONFIG_INET6_XFRM_TUNNEL=m
+CONFIG_INET6_TUNNEL=m
+CONFIG_INET6_XFRM_MODE_TRANSPORT=m
+CONFIG_INET6_XFRM_MODE_TUNNEL=m
+CONFIG_IPV6_TUNNEL=m
+CONFIG_NETWORK_SECMARK=y
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_DEBUG is not set
+CONFIG_BRIDGE_NETFILTER=y
+
+#
+# Core Netfilter Configuration
+#
+CONFIG_NETFILTER_NETLINK=m
+CONFIG_NETFILTER_NETLINK_QUEUE=m
+CONFIG_NETFILTER_NETLINK_LOG=m
+CONFIG_NETFILTER_XTABLES=m
+CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
+CONFIG_NETFILTER_XT_TARGET_CONNMARK=m
+CONFIG_NETFILTER_XT_TARGET_MARK=m
+CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
+CONFIG_NETFILTER_XT_TARGET_NOTRACK=m
+CONFIG_NETFILTER_XT_TARGET_SECMARK=m
+CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=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_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_PHYSDEV=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
+
+#
+# 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=m
+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_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_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_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
+CONFIG_IP_NF_ARPTABLES=m
+CONFIG_IP_NF_ARPFILTER=m
+CONFIG_IP_NF_ARP_MANGLE=m
+
+#
+# IPv6: Netfilter Configuration (EXPERIMENTAL)
+#
+CONFIG_IP6_NF_QUEUE=m
+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_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
+
+#
+# DECnet: Netfilter Configuration
+#
+# CONFIG_DECNET_NF_GRABULATOR is not set
+
+#
+# Bridge: Netfilter Configuration
+#
+CONFIG_BRIDGE_NF_EBTABLES=m
+CONFIG_BRIDGE_EBT_BROUTE=m
+CONFIG_BRIDGE_EBT_T_FILTER=m
+CONFIG_BRIDGE_EBT_T_NAT=m
+CONFIG_BRIDGE_EBT_802_3=m
+CONFIG_BRIDGE_EBT_AMONG=m
+CONFIG_BRIDGE_EBT_ARP=m
+CONFIG_BRIDGE_EBT_IP=m
+CONFIG_BRIDGE_EBT_LIMIT=m
+CONFIG_BRIDGE_EBT_MARK=m
+CONFIG_BRIDGE_EBT_PKTTYPE=m
+CONFIG_BRIDGE_EBT_STP=m
+CONFIG_BRIDGE_EBT_VLAN=m
+CONFIG_BRIDGE_EBT_ARPREPLY=m
+CONFIG_BRIDGE_EBT_DNAT=m
+CONFIG_BRIDGE_EBT_MARK_T=m
+CONFIG_BRIDGE_EBT_REDIRECT=m
+CONFIG_BRIDGE_EBT_SNAT=m
+CONFIG_BRIDGE_EBT_LOG=m
+CONFIG_BRIDGE_EBT_ULOG=m
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+CONFIG_IP_DCCP=m
+CONFIG_INET_DCCP_DIAG=m
+CONFIG_IP_DCCP_ACKVEC=y
+
+#
+# DCCP CCIDs Configuration (EXPERIMENTAL)
+#
+CONFIG_IP_DCCP_CCID2=m
+CONFIG_IP_DCCP_CCID3=m
+CONFIG_IP_DCCP_TFRC_LIB=m
+
+#
+# DCCP Kernel Hacking
+#
+# CONFIG_IP_DCCP_DEBUG is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+CONFIG_IP_SCTP=m
+# CONFIG_SCTP_DBG_MSG is not set
+# CONFIG_SCTP_DBG_OBJCNT is not set
+# CONFIG_SCTP_HMAC_NONE is not set
+# CONFIG_SCTP_HMAC_SHA1 is not set
+CONFIG_SCTP_HMAC_MD5=y
+
+#
+# TIPC Configuration (EXPERIMENTAL)
+#
+CONFIG_TIPC=m
+# CONFIG_TIPC_ADVANCED is not set
+# CONFIG_TIPC_DEBUG is not set
+CONFIG_ATM=m
+CONFIG_ATM_CLIP=m
+# CONFIG_ATM_CLIP_NO_ICMP is not set
+CONFIG_ATM_LANE=m
+# CONFIG_ATM_MPOA is not set
+CONFIG_ATM_BR2684=m
+# CONFIG_ATM_BR2684_IPFILTER is not set
+CONFIG_BRIDGE=m
+CONFIG_VLAN_8021Q=m
+CONFIG_DECNET=m
+CONFIG_DECNET_ROUTER=y
+CONFIG_DECNET_ROUTE_FWMARK=y
+CONFIG_LLC=y
+# CONFIG_LLC2 is not set
+CONFIG_IPX=m
+# CONFIG_IPX_INTERN is not set
+CONFIG_ATALK=m
+CONFIG_DEV_APPLETALK=m
+# CONFIG_LTPC is not set
+# CONFIG_COPS is not set
+CONFIG_IPDDP=m
+CONFIG_IPDDP_ENCAP=y
+CONFIG_IPDDP_DECAP=y
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+CONFIG_WAN_ROUTER=m
+
+#
+# QoS and/or fair queueing
+#
+CONFIG_NET_SCHED=y
+# CONFIG_NET_SCH_CLK_JIFFIES is not set
+CONFIG_NET_SCH_CLK_GETTIMEOFDAY=y
+# CONFIG_NET_SCH_CLK_CPU is not set
+
+#
+# Queueing/Scheduling
+#
+CONFIG_NET_SCH_CBQ=m
+CONFIG_NET_SCH_HTB=m
+CONFIG_NET_SCH_HFSC=m
+CONFIG_NET_SCH_ATM=m
+CONFIG_NET_SCH_PRIO=m
+CONFIG_NET_SCH_RED=m
+CONFIG_NET_SCH_SFQ=m
+CONFIG_NET_SCH_TEQL=m
+CONFIG_NET_SCH_TBF=m
+CONFIG_NET_SCH_GRED=m
+CONFIG_NET_SCH_DSMARK=m
+CONFIG_NET_SCH_NETEM=m
+CONFIG_NET_SCH_INGRESS=m
+
+#
+# Classification
+#
+CONFIG_NET_CLS=y
+CONFIG_NET_CLS_BASIC=m
+CONFIG_NET_CLS_TCINDEX=m
+CONFIG_NET_CLS_ROUTE4=m
+CONFIG_NET_CLS_ROUTE=y
+CONFIG_NET_CLS_FW=m
+CONFIG_NET_CLS_U32=m
+CONFIG_CLS_U32_PERF=y
+CONFIG_CLS_U32_MARK=y
+CONFIG_NET_CLS_RSVP=m
+CONFIG_NET_CLS_RSVP6=m
+CONFIG_NET_EMATCH=y
+CONFIG_NET_EMATCH_STACK=32
+CONFIG_NET_EMATCH_CMP=m
+CONFIG_NET_EMATCH_NBYTE=m
+CONFIG_NET_EMATCH_U32=m
+CONFIG_NET_EMATCH_META=m
+CONFIG_NET_EMATCH_TEXT=m
+CONFIG_NET_CLS_ACT=y
+CONFIG_NET_ACT_POLICE=m
+CONFIG_NET_ACT_GACT=m
+CONFIG_GACT_PROB=y
+CONFIG_NET_ACT_MIRRED=m
+CONFIG_NET_ACT_IPT=m
+CONFIG_NET_ACT_PEDIT=m
+CONFIG_NET_ACT_SIMP=m
+CONFIG_NET_CLS_IND=y
+CONFIG_NET_ESTIMATOR=y
+
+#
+# Network testing
+#
+CONFIG_NET_PKTGEN=m
+# CONFIG_HAMRADIO is not set
+CONFIG_IRDA=m
+
+#
+# IrDA protocols
+#
+CONFIG_IRLAN=m
+CONFIG_IRNET=m
+CONFIG_IRCOMM=m
+# CONFIG_IRDA_ULTRA is not set
+
+#
+# IrDA options
+#
+CONFIG_IRDA_CACHE_LAST_LSAP=y
+CONFIG_IRDA_FAST_RR=y
+# CONFIG_IRDA_DEBUG is not set
+
+#
+# Infrared-port device drivers
+#
+
+#
+# SIR device drivers
+#
+CONFIG_IRTTY_SIR=m
+
+#
+# Dongle support
+#
+CONFIG_DONGLE=y
+CONFIG_ESI_DONGLE=m
+CONFIG_ACTISYS_DONGLE=m
+CONFIG_TEKRAM_DONGLE=m
+CONFIG_TOIM3232_DONGLE=m
+CONFIG_LITELINK_DONGLE=m
+CONFIG_MA600_DONGLE=m
+CONFIG_GIRBIL_DONGLE=m
+CONFIG_MCP2120_DONGLE=m
+CONFIG_OLD_BELKIN_DONGLE=m
+CONFIG_ACT200L_DONGLE=m
+
+#
+# Old SIR device drivers
+#
+CONFIG_IRPORT_SIR=m
+
+#
+# Old Serial dongle support
+#
+# CONFIG_DONGLE_OLD is not set
+
+#
+# FIR device drivers
+#
+CONFIG_USB_IRDA=m
+CONFIG_SIGMATEL_FIR=m
+CONFIG_NSC_FIR=m
+CONFIG_WINBOND_FIR=m
+CONFIG_TOSHIBA_FIR=m
+CONFIG_SMC_IRCC_FIR=m
+CONFIG_ALI_FIR=m
+CONFIG_VLSI_FIR=m
+CONFIG_VIA_FIR=m
+CONFIG_MCS_FIR=m
+CONFIG_BT=m
+CONFIG_BT_L2CAP=m
+CONFIG_BT_SCO=m
+CONFIG_BT_RFCOMM=m
+CONFIG_BT_RFCOMM_TTY=y
+CONFIG_BT_BNEP=m
+CONFIG_BT_BNEP_MC_FILTER=y
+CONFIG_BT_BNEP_PROTO_FILTER=y
+CONFIG_BT_CMTP=m
+CONFIG_BT_HIDP=m
+
+#
+# Bluetooth device drivers
+#
+CONFIG_BT_HCIUSB=m
+CONFIG_BT_HCIUSB_SCO=y
+CONFIG_BT_HCIUART=m
+CONFIG_BT_HCIUART_H4=y
+CONFIG_BT_HCIUART_BCSP=y
+CONFIG_BT_HCIBCM203X=m
+CONFIG_BT_HCIBPA10X=m
+CONFIG_BT_HCIBFUSB=m
+CONFIG_BT_HCIDTL1=m
+CONFIG_BT_HCIBT3C=m
+CONFIG_BT_HCIBLUECARD=m
+CONFIG_BT_HCIBTUART=m
+CONFIG_BT_HCIVHCI=m
+CONFIG_IEEE80211=m
+CONFIG_IEEE80211_DEBUG=y
+CONFIG_IEEE80211_CRYPT_WEP=m
+CONFIG_IEEE80211_CRYPT_CCMP=m
+CONFIG_IEEE80211_CRYPT_TKIP=m
+CONFIG_IEEE80211_SOFTMAC=m
+CONFIG_IEEE80211_SOFTMAC_DEBUG=y
+CONFIG_TUX=m
+
+#
+# TUX options
+#
+CONFIG_TUX_EXTCGI=y
+CONFIG_TUX_EXTENDED_LOG=y
+# CONFIG_TUX_DEBUG is not set
+CONFIG_WIRELESS_EXT=y
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_SYS_HYPERVISOR is not set
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+CONFIG_CONNECTOR=y
+CONFIG_PROC_EVENTS=y
+
+#
+# Memory Technology Devices (MTD)
+#
+CONFIG_MTD=m
+# CONFIG_MTD_DEBUG is not set
+CONFIG_MTD_CONCAT=m
+CONFIG_MTD_PARTITIONS=y
+CONFIG_MTD_REDBOOT_PARTS=m
+CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1
+# CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED is not set
+# CONFIG_MTD_REDBOOT_PARTS_READONLY is not set
+CONFIG_MTD_CMDLINE_PARTS=y
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=m
+CONFIG_MTD_BLOCK=m
+CONFIG_MTD_BLOCK_RO=m
+CONFIG_FTL=m
+CONFIG_NFTL=m
+CONFIG_NFTL_RW=y
+CONFIG_INFTL=m
+CONFIG_RFD_FTL=m
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=m
+CONFIG_MTD_JEDECPROBE=m
+CONFIG_MTD_GEN_PROBE=m
+# CONFIG_MTD_CFI_ADV_OPTIONS 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_CFI_INTELEXT=m
+CONFIG_MTD_CFI_AMDSTD=m
+CONFIG_MTD_CFI_STAA=m
+CONFIG_MTD_CFI_UTIL=m
+CONFIG_MTD_RAM=m
+CONFIG_MTD_ROM=m
+CONFIG_MTD_ABSENT=m
+# CONFIG_MTD_OBSOLETE_CHIPS is not set
+
+#
+# Mapping drivers for chip access
+#
+CONFIG_MTD_COMPLEX_MAPPINGS=y
+# CONFIG_MTD_PHYSMAP is not set
+CONFIG_MTD_PCI=m
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+CONFIG_MTD_PMC551=m
+# CONFIG_MTD_PMC551_BUGFIX is not set
+# CONFIG_MTD_PMC551_DEBUG is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+CONFIG_MTD_MTDRAM=m
+CONFIG_MTDRAM_TOTAL_SIZE=4096
+CONFIG_MTDRAM_ERASE_SIZE=128
+CONFIG_MTD_BLOCK2MTD=m
+
+#
+# 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=m
+# CONFIG_MTD_NAND_VERIFY_WRITE is not set
+CONFIG_MTD_NAND_ECC_SMC=y
+CONFIG_MTD_NAND_IDS=m
+CONFIG_MTD_NAND_DISKONCHIP=m
+# CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADVANCED is not set
+CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADDRESS=0
+# CONFIG_MTD_NAND_DISKONCHIP_BBTWRITE is not set
+CONFIG_MTD_NAND_NANDSIM=m
+
+#
+# OneNAND Flash Device Drivers
+#
+# CONFIG_MTD_ONENAND is not set
+
+#
+# Parallel port support
+#
+CONFIG_PARPORT=m
+CONFIG_PARPORT_PC=m
+CONFIG_PARPORT_SERIAL=m
+# CONFIG_PARPORT_PC_FIFO is not set
+# CONFIG_PARPORT_PC_SUPERIO is not set
+CONFIG_PARPORT_PC_PCMCIA=m
+CONFIG_PARPORT_NOT_PC=y
+# CONFIG_PARPORT_GSC is not set
+# CONFIG_PARPORT_AX88796 is not set
+CONFIG_PARPORT_1284=y
+
+#
+# Plug and Play support
+#
+CONFIG_PNP=y
+# CONFIG_PNP_DEBUG is not set
+
+#
+# Protocols
+#
+CONFIG_ISAPNP=y
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+CONFIG_MAC_FLOPPY=m
+# CONFIG_BLK_DEV_XD is not set
+CONFIG_PARIDE=m
+CONFIG_PARIDE_PARPORT=m
+
+#
+# Parallel IDE high-level drivers
+#
+CONFIG_PARIDE_PD=m
+CONFIG_PARIDE_PCD=m
+CONFIG_PARIDE_PF=m
+CONFIG_PARIDE_PT=m
+CONFIG_PARIDE_PG=m
+
+#
+# Parallel IDE protocol modules
+#
+CONFIG_PARIDE_ATEN=m
+CONFIG_PARIDE_BPCK=m
+CONFIG_PARIDE_BPCK6=m
+CONFIG_PARIDE_COMM=m
+CONFIG_PARIDE_DSTR=m
+CONFIG_PARIDE_FIT2=m
+CONFIG_PARIDE_FIT3=m
+CONFIG_PARIDE_EPAT=m
+CONFIG_PARIDE_EPATC8=y
+CONFIG_PARIDE_EPIA=m
+CONFIG_PARIDE_FRIQ=m
+CONFIG_PARIDE_FRPW=m
+CONFIG_PARIDE_KBIC=m
+CONFIG_PARIDE_KTTI=m
+CONFIG_PARIDE_ON20=m
+CONFIG_PARIDE_ON26=m
+# CONFIG_BLK_CPQ_DA is not set
+CONFIG_BLK_CPQ_CISS_DA=m
+CONFIG_CISS_SCSI_TAPE=y
+CONFIG_BLK_DEV_DAC960=m
+CONFIG_BLK_DEV_UMEM=m
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=m
+CONFIG_BLK_DEV_CRYPTOLOOP=m
+CONFIG_BLK_DEV_NBD=m
+CONFIG_BLK_DEV_SX8=m
+CONFIG_BLK_DEV_UB=m
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=16384
+CONFIG_BLK_DEV_RAM_BLOCKSIZE=4096
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_CDROM_PKTCDVD=m
+CONFIG_CDROM_PKTCDVD_BUFFERS=8
+# CONFIG_CDROM_PKTCDVD_WCACHE is not set
+CONFIG_ATA_OVER_ETH=m
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+CONFIG_IDE=y
+CONFIG_BLK_DEV_IDE=y
+
+#
+# Please see Documentation/ide.txt for help/info on IDE drives
+#
+# CONFIG_BLK_DEV_IDE_SATA is not set
+CONFIG_BLK_DEV_IDEDISK=y
+CONFIG_IDEDISK_MULTI_MODE=y
+CONFIG_BLK_DEV_IDECS=m
+CONFIG_BLK_DEV_IDECD=m
+# CONFIG_BLK_DEV_IDETAPE is not set
+CONFIG_BLK_DEV_IDEFLOPPY=y
+CONFIG_BLK_DEV_IDESCSI=m
+CONFIG_IDE_TASK_IOCTL=y
+
+#
+# IDE chipset support/bugfixes
+#
+CONFIG_IDE_GENERIC=y
+CONFIG_BLK_DEV_IDEPNP=y
+CONFIG_BLK_DEV_IDEPCI=y
+CONFIG_IDEPCI_SHARE_IRQ=y
+# CONFIG_BLK_DEV_OFFBOARD is not set
+CONFIG_BLK_DEV_GENERIC=y
+# CONFIG_BLK_DEV_OPTI621 is not set
+CONFIG_BLK_DEV_SL82C105=m
+CONFIG_BLK_DEV_IDEDMA_PCI=y
+# CONFIG_BLK_DEV_IDEDMA_FORCED is not set
+CONFIG_IDEDMA_PCI_AUTO=y
+# CONFIG_IDEDMA_ONLYDISK is not set
+CONFIG_BLK_DEV_AEC62XX=y
+CONFIG_BLK_DEV_ALI15X3=y
+# CONFIG_WDC_ALI15X3 is not set
+# CONFIG_BLK_DEV_AMD74XX is not set
+CONFIG_BLK_DEV_CMD64X=y
+CONFIG_BLK_DEV_TRIFLEX=y
+# CONFIG_BLK_DEV_CY82C693 is not set
+CONFIG_BLK_DEV_CS5520=y
+CONFIG_BLK_DEV_CS5530=y
+CONFIG_BLK_DEV_HPT34X=y
+# CONFIG_HPT34X_AUTODMA is not set
+CONFIG_BLK_DEV_HPT366=y
+# CONFIG_BLK_DEV_SC1200 is not set
+CONFIG_BLK_DEV_PIIX=y
+CONFIG_BLK_DEV_IT821X=y
+# CONFIG_BLK_DEV_NS87415 is not set
+CONFIG_BLK_DEV_PDC202XX_OLD=y
+# CONFIG_PDC202XX_BURST is not set
+CONFIG_BLK_DEV_PDC202XX_NEW=y
+CONFIG_BLK_DEV_SVWKS=y
+CONFIG_BLK_DEV_SIIMAGE=y
+# CONFIG_BLK_DEV_SLC90E66 is not set
+# CONFIG_BLK_DEV_TRM290 is not set
+CONFIG_BLK_DEV_VIA82CXXX=y
+CONFIG_BLK_DEV_IDE_PMAC=y
+CONFIG_BLK_DEV_IDE_PMAC_ATA100FIRST=y
+CONFIG_BLK_DEV_IDEDMA_PMAC=y
+# CONFIG_IDE_ARM is not set
+# CONFIG_IDE_CHIPSETS is not set
+CONFIG_BLK_DEV_IDEDMA=y
+# CONFIG_IDEDMA_IVB is not set
+CONFIG_IDEDMA_AUTO=y
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# SCSI device support
+#
+CONFIG_RAID_ATTRS=m
+CONFIG_SCSI=m
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=m
+CONFIG_CHR_DEV_ST=m
+CONFIG_CHR_DEV_OSST=m
+CONFIG_BLK_DEV_SR=m
+CONFIG_BLK_DEV_SR_VENDOR=y
+CONFIG_CHR_DEV_SG=m
+CONFIG_CHR_DEV_SCH=m
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+CONFIG_SCSI_MULTI_LUN=y
+CONFIG_SCSI_CONSTANTS=y
+CONFIG_SCSI_LOGGING=y
+
+#
+# SCSI Transport Attributes
+#
+CONFIG_SCSI_SPI_ATTRS=m
+CONFIG_SCSI_FC_ATTRS=m
+CONFIG_SCSI_ISCSI_ATTRS=m
+CONFIG_SCSI_SAS_ATTRS=m
+
+#
+# SCSI low-level drivers
+#
+CONFIG_ISCSI_TCP=m
+CONFIG_BLK_DEV_3W_XXXX_RAID=m
+CONFIG_SCSI_3W_9XXX=m
+# CONFIG_SCSI_7000FASST is not set
+CONFIG_SCSI_ACARD=m
+CONFIG_SCSI_AHA152X=m
+# CONFIG_SCSI_AHA1542 is not set
+CONFIG_SCSI_AACRAID=m
+CONFIG_SCSI_AIC7XXX=m
+CONFIG_AIC7XXX_CMDS_PER_DEVICE=4
+CONFIG_AIC7XXX_RESET_DELAY_MS=15000
+# CONFIG_AIC7XXX_DEBUG_ENABLE is not set
+CONFIG_AIC7XXX_DEBUG_MASK=0
+# CONFIG_AIC7XXX_REG_PRETTY_PRINT is not set
+CONFIG_SCSI_AIC7XXX_OLD=m
+CONFIG_SCSI_AIC79XX=m
+CONFIG_AIC79XX_CMDS_PER_DEVICE=4
+CONFIG_AIC79XX_RESET_DELAY_MS=15000
+# CONFIG_AIC79XX_ENABLE_RD_STRM is not set
+# CONFIG_AIC79XX_DEBUG_ENABLE is not set
+CONFIG_AIC79XX_DEBUG_MASK=0
+# CONFIG_AIC79XX_REG_PRETTY_PRINT is not set
+# CONFIG_SCSI_DPT_I2O is not set
+# CONFIG_SCSI_IN2000 is not set
+CONFIG_MEGARAID_NEWGEN=y
+CONFIG_MEGARAID_MM=m
+CONFIG_MEGARAID_MAILBOX=m
+CONFIG_MEGARAID_LEGACY=m
+CONFIG_MEGARAID_SAS=m
+CONFIG_SCSI_SATA=m
+CONFIG_SCSI_SATA_AHCI=m
+CONFIG_SCSI_SATA_SVW=m
+CONFIG_SCSI_ATA_PIIX=m
+CONFIG_SCSI_SATA_MV=m
+CONFIG_SCSI_SATA_NV=m
+CONFIG_SCSI_PDC_ADMA=m
+CONFIG_SCSI_HPTIOP=m
+CONFIG_SCSI_SATA_QSTOR=m
+CONFIG_SCSI_SATA_PROMISE=m
+CONFIG_SCSI_SATA_SX4=m
+CONFIG_SCSI_SATA_SIL=m
+CONFIG_SCSI_SATA_SIL24=m
+CONFIG_SCSI_SATA_SIS=m
+CONFIG_SCSI_SATA_ULI=m
+CONFIG_SCSI_SATA_VIA=m
+CONFIG_SCSI_SATA_VITESSE=m
+CONFIG_SCSI_SATA_INTEL_COMBINED=y
+# CONFIG_SCSI_BUSLOGIC is not set
+# CONFIG_SCSI_DMX3191D is not set
+# CONFIG_SCSI_DTC3280 is not set
+# CONFIG_SCSI_EATA is not set
+# CONFIG_SCSI_FUTURE_DOMAIN is not set
+CONFIG_SCSI_GDTH=m
+# CONFIG_SCSI_GENERIC_NCR5380 is not set
+# CONFIG_SCSI_GENERIC_NCR5380_MMIO is not set
+CONFIG_SCSI_IPS=m
+CONFIG_SCSI_INITIO=m
+CONFIG_SCSI_INIA100=m
+CONFIG_SCSI_PPA=m
+CONFIG_SCSI_IMM=m
+# CONFIG_SCSI_IZIP_EPP16 is not set
+# CONFIG_SCSI_IZIP_SLOW_CTR is not set
+# CONFIG_SCSI_NCR53C406A is not set
+CONFIG_SCSI_SYM53C8XX_2=m
+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=m
+CONFIG_SCSI_QLA_FC=m
+CONFIG_SCSI_LPFC=m
+# CONFIG_SCSI_SYM53C416 is not set
+CONFIG_SCSI_DC395x=m
+# CONFIG_SCSI_DC390T is not set
+# CONFIG_SCSI_T128 is not set
+# CONFIG_SCSI_U14_34F is not set
+# CONFIG_SCSI_NSP32 is not set
+# CONFIG_SCSI_DEBUG is not set
+CONFIG_SCSI_MESH=m
+CONFIG_SCSI_MESH_SYNC_RATE=5
+CONFIG_SCSI_MESH_RESET_DELAY_MS=4000
+CONFIG_SCSI_MAC53C94=m
+
+#
+# PCMCIA SCSI adapter support
+#
+CONFIG_PCMCIA_AHA152X=m
+# CONFIG_PCMCIA_FDOMAIN is not set
+CONFIG_PCMCIA_NINJA_SCSI=m
+CONFIG_PCMCIA_QLOGIC=m
+CONFIG_PCMCIA_SYM53C500=m
+
+#
+# Old CD-ROM drivers (not SCSI, not IDE)
+#
+# CONFIG_CD_NO_IDESCSI is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+CONFIG_MD=y
+CONFIG_BLK_DEV_MD=y
+CONFIG_MD_LINEAR=m
+CONFIG_MD_RAID0=m
+CONFIG_MD_RAID1=m
+CONFIG_MD_RAID10=m
+CONFIG_MD_RAID456=m
+CONFIG_MD_RAID5_RESHAPE=y
+CONFIG_MD_MULTIPATH=m
+CONFIG_MD_FAULTY=m
+CONFIG_BLK_DEV_DM=m
+CONFIG_DM_CRYPT=m
+CONFIG_DM_SNAPSHOT=m
+CONFIG_DM_MIRROR=m
+CONFIG_DM_ZERO=m
+CONFIG_DM_MULTIPATH=m
+CONFIG_DM_MULTIPATH_EMC=m
+
+#
+# Fusion MPT device support
+#
+CONFIG_FUSION=y
+CONFIG_FUSION_SPI=m
+CONFIG_FUSION_FC=m
+CONFIG_FUSION_SAS=m
+CONFIG_FUSION_MAX_SGE=40
+CONFIG_FUSION_CTL=m
+CONFIG_FUSION_LAN=m
+
+#
+# IEEE 1394 (FireWire) support
+#
+CONFIG_IEEE1394=m
+
+#
+# Subsystem Options
+#
+# CONFIG_IEEE1394_VERBOSEDEBUG is not set
+CONFIG_IEEE1394_OUI_DB=y
+CONFIG_IEEE1394_EXTRA_CONFIG_ROMS=y
+CONFIG_IEEE1394_CONFIG_ROM_IP1394=y
+# CONFIG_IEEE1394_EXPORT_FULL_API is not set
+
+#
+# Device Drivers
+#
+CONFIG_IEEE1394_PCILYNX=m
+CONFIG_IEEE1394_OHCI1394=m
+
+#
+# Protocol Drivers
+#
+CONFIG_IEEE1394_VIDEO1394=m
+CONFIG_IEEE1394_SBP2=m
+CONFIG_IEEE1394_ETH1394=m
+CONFIG_IEEE1394_DV1394=m
+CONFIG_IEEE1394_RAWIO=m
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+
+#
+# Macintosh device drivers
+#
+CONFIG_ADB=y
+CONFIG_ADB_CUDA=y
+CONFIG_ADB_PMU=y
+CONFIG_ADB_PMU_LED=y
+CONFIG_ADB_PMU_LED_IDE=y
+CONFIG_PMAC_APM_EMU=y
+CONFIG_PMAC_MEDIABAY=y
+CONFIG_PMAC_BACKLIGHT=y
+# CONFIG_PMAC_BACKLIGHT_LEGACY is not set
+CONFIG_ADB_MACIO=y
+CONFIG_INPUT_ADBHID=y
+CONFIG_MAC_EMUMOUSEBTN=y
+CONFIG_THERM_WINDTUNNEL=m
+CONFIG_THERM_ADT746X=m
+CONFIG_WINDFARM=y
+# CONFIG_ANSLCD is not set
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+CONFIG_IFB=m
+CONFIG_DUMMY=m
+CONFIG_BONDING=m
+CONFIG_EQUALIZER=m
+CONFIG_TUN=m
+CONFIG_NET_SB1000=m
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+
+#
+# PHY device support
+#
+CONFIG_PHYLIB=m
+
+#
+# MII PHY device drivers
+#
+CONFIG_MARVELL_PHY=m
+CONFIG_DAVICOM_PHY=m
+CONFIG_QSEMI_PHY=m
+CONFIG_LXT_PHY=m
+CONFIG_CICADA_PHY=m
+CONFIG_VITESSE_PHY=m
+CONFIG_SMSC_PHY=m
+CONFIG_FIXED_PHY=m
+CONFIG_FIXED_MII_10_FDX=y
+CONFIG_FIXED_MII_100_FDX=y
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=m
+CONFIG_MACE=m
+# CONFIG_MACE_AAUI_PORT is not set
+CONFIG_BMAC=m
+CONFIG_HAPPYMEAL=m
+CONFIG_SUNGEM=m
+CONFIG_CASSINI=m
+CONFIG_NET_VENDOR_3COM=y
+# CONFIG_EL1 is not set
+# CONFIG_EL2 is not set
+# CONFIG_ELPLUS is not set
+# CONFIG_EL16 is not set
+CONFIG_EL3=m
+# CONFIG_3C515 is not set
+CONFIG_VORTEX=m
+CONFIG_TYPHOON=m
+# CONFIG_LANCE is not set
+CONFIG_NET_VENDOR_SMC=y
+# CONFIG_WD80x3 is not set
+CONFIG_ULTRA=m
+# CONFIG_SMC9194 is not set
+# CONFIG_NET_VENDOR_RACAL is not set
+
+#
+# Tulip family network device support
+#
+CONFIG_NET_TULIP=y
+CONFIG_DE2104X=m
+CONFIG_TULIP=m
+# CONFIG_TULIP_MWI is not set
+CONFIG_TULIP_MMIO=y
+# CONFIG_TULIP_NAPI is not set
+CONFIG_DE4X5=m
+CONFIG_WINBOND_840=m
+CONFIG_DM9102=m
+CONFIG_ULI526X=m
+CONFIG_PCMCIA_XIRCOM=m
+# CONFIG_PCMCIA_XIRTULIP is not set
+# CONFIG_AT1700 is not set
+# CONFIG_DEPCA is not set
+# CONFIG_HP100 is not set
+CONFIG_NET_ISA=y
+# CONFIG_E2100 is not set
+CONFIG_EWRK3=m
+# CONFIG_EEXPRESS is not set
+# CONFIG_EEXPRESS_PRO is not set
+# CONFIG_HPLAN_PLUS is not set
+# CONFIG_HPLAN is not set
+# CONFIG_LP486E is not set
+# CONFIG_ETH16I is not set
+CONFIG_NE2000=m
+# CONFIG_ZNET is not set
+# CONFIG_SEEQ8005 is not set
+CONFIG_NET_PCI=y
+CONFIG_PCNET32=m
+CONFIG_AMD8111_ETH=m
+CONFIG_AMD8111E_NAPI=y
+CONFIG_ADAPTEC_STARFIRE=m
+CONFIG_ADAPTEC_STARFIRE_NAPI=y
+# CONFIG_AC3200 is not set
+# CONFIG_APRICOT is not set
+CONFIG_B44=m
+CONFIG_FORCEDETH=m
+# CONFIG_CS89x0 is not set
+# CONFIG_DGRS is not set
+# CONFIG_EEPRO100 is not set
+CONFIG_E100=m
+CONFIG_FEALNX=m
+CONFIG_NATSEMI=m
+CONFIG_NE2K_PCI=m
+CONFIG_8139CP=m
+CONFIG_8139TOO=m
+# CONFIG_8139TOO_PIO is not set
+# CONFIG_8139TOO_TUNE_TWISTER is not set
+CONFIG_8139TOO_8129=y
+# CONFIG_8139_OLD_RX_RESET is not set
+CONFIG_SIS900=m
+CONFIG_EPIC100=m
+CONFIG_SUNDANCE=m
+# CONFIG_SUNDANCE_MMIO is not set
+CONFIG_TLAN=m
+CONFIG_VIA_RHINE=m
+CONFIG_VIA_RHINE_MMIO=y
+CONFIG_VIA_RHINE_NAPI=y
+CONFIG_NET_POCKET=y
+CONFIG_DE600=m
+CONFIG_DE620=m
+
+#
+# Ethernet (1000 Mbit)
+#
+CONFIG_ACENIC=m
+# CONFIG_ACENIC_OMIT_TIGON_I is not set
+CONFIG_DL2K=m
+CONFIG_E1000=m
+CONFIG_E1000_NAPI=y
+# CONFIG_E1000_DISABLE_PACKET_SPLIT is not set
+CONFIG_NS83820=m
+CONFIG_HAMACHI=m
+CONFIG_YELLOWFIN=m
+CONFIG_R8169=m
+CONFIG_R8169_NAPI=y
+CONFIG_R8169_VLAN=y
+CONFIG_SIS190=m
+CONFIG_SKGE=m
+CONFIG_SKY2=m
+# CONFIG_SK98LIN is not set
+CONFIG_VIA_VELOCITY=m
+CONFIG_TIGON3=m
+CONFIG_BNX2=m
+CONFIG_MV643XX_ETH=m
+CONFIG_MV643XX_ETH_0=y
+CONFIG_MV643XX_ETH_1=y
+CONFIG_MV643XX_ETH_2=y
+
+#
+# Ethernet (10000 Mbit)
+#
+CONFIG_CHELSIO_T1=m
+CONFIG_IXGB=m
+CONFIG_IXGB_NAPI=y
+CONFIG_S2IO=m
+CONFIG_S2IO_NAPI=y
+CONFIG_MYRI10GE=m
+
+#
+# Token Ring devices
+#
+CONFIG_TR=y
+# CONFIG_IBMTR is not set
+CONFIG_IBMOL=m
+CONFIG_IBMLS=m
+CONFIG_3C359=m
+# CONFIG_TMS380TR is not set
+# CONFIG_SMCTR is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+CONFIG_NET_RADIO=y
+CONFIG_NET_WIRELESS_RTNETLINK=y
+
+#
+# Obsolete Wireless cards support (pre-802.11)
+#
+# CONFIG_STRIP is not set
+# CONFIG_ARLAN is not set
+# CONFIG_WAVELAN is not set
+CONFIG_PCMCIA_WAVELAN=m
+CONFIG_PCMCIA_NETWAVE=m
+
+#
+# Wireless 802.11 Frequency Hopping cards support
+#
+# CONFIG_PCMCIA_RAYCS is not set
+
+#
+# Wireless 802.11b ISA/PCI cards support
+#
+# CONFIG_IPW2100 is not set
+# CONFIG_IPW2200 is not set
+CONFIG_AIRO=m
+CONFIG_HERMES=m
+CONFIG_APPLE_AIRPORT=m
+CONFIG_PLX_HERMES=m
+CONFIG_TMD_HERMES=m
+CONFIG_NORTEL_HERMES=m
+CONFIG_PCI_HERMES=m
+CONFIG_ATMEL=m
+CONFIG_PCI_ATMEL=m
+
+#
+# Wireless 802.11b Pcmcia/Cardbus cards support
+#
+CONFIG_PCMCIA_HERMES=m
+CONFIG_PCMCIA_SPECTRUM=m
+CONFIG_AIRO_CS=m
+CONFIG_PCMCIA_ATMEL=m
+CONFIG_PCMCIA_WL3501=m
+
+#
+# Prism GT/Duette 802.11(a/b/g) PCI/Cardbus support
+#
+CONFIG_PRISM54=m
+CONFIG_USB_ZD1201=m
+CONFIG_HOSTAP=m
+CONFIG_HOSTAP_FIRMWARE=y
+CONFIG_HOSTAP_FIRMWARE_NVRAM=y
+CONFIG_HOSTAP_PLX=m
+CONFIG_HOSTAP_PCI=m
+CONFIG_HOSTAP_CS=m
+CONFIG_BCM43XX=m
+CONFIG_BCM43XX_DEBUG=y
+CONFIG_BCM43XX_DMA=y
+CONFIG_BCM43XX_PIO=y
+CONFIG_BCM43XX_DMA_AND_PIO_MODE=y
+# CONFIG_BCM43XX_DMA_MODE is not set
+# CONFIG_BCM43XX_PIO_MODE is not set
+CONFIG_ZD1211RW=m
+# CONFIG_ZD1211RW_DEBUG is not set
+CONFIG_NET_WIRELESS=y
+
+#
+# PCMCIA network device support
+#
+CONFIG_NET_PCMCIA=y
+CONFIG_PCMCIA_3C589=m
+CONFIG_PCMCIA_3C574=m
+CONFIG_PCMCIA_FMVJ18X=m
+CONFIG_PCMCIA_PCNET=m
+CONFIG_PCMCIA_NMCLAN=m
+CONFIG_PCMCIA_SMC91C92=m
+CONFIG_PCMCIA_XIRC2PS=m
+CONFIG_PCMCIA_AXNET=m
+CONFIG_PCMCIA_IBMTR=m
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+
+#
+# ATM drivers
+#
+# CONFIG_ATM_DUMMY is not set
+CONFIG_ATM_TCP=m
+CONFIG_ATM_LANAI=m
+CONFIG_ATM_ENI=m
+# CONFIG_ATM_ENI_DEBUG is not set
+# CONFIG_ATM_ENI_TUNE_BURST is not set
+# CONFIG_ATM_FIRESTREAM is not set
+# CONFIG_ATM_ZATM is not set
+CONFIG_ATM_NICSTAR=m
+# CONFIG_ATM_NICSTAR_USE_SUNI is not set
+# CONFIG_ATM_NICSTAR_USE_IDT77105 is not set
+CONFIG_ATM_IDT77252=m
+# CONFIG_ATM_IDT77252_DEBUG is not set
+# CONFIG_ATM_IDT77252_RCV_ALL is not set
+CONFIG_ATM_IDT77252_USE_SUNI=y
+# CONFIG_ATM_AMBASSADOR is not set
+# CONFIG_ATM_HORIZON is not set
+# CONFIG_ATM_IA is not set
+CONFIG_ATM_FORE200E_MAYBE=m
+# CONFIG_ATM_FORE200E_PCA is not set
+CONFIG_ATM_HE=m
+# CONFIG_ATM_HE_USE_SUNI is not set
+CONFIG_FDDI=y
+# CONFIG_DEFXX is not set
+CONFIG_SKFP=m
+# CONFIG_HIPPI is not set
+CONFIG_PLIP=m
+CONFIG_PPP=m
+CONFIG_PPP_MULTILINK=y
+CONFIG_PPP_FILTER=y
+CONFIG_PPP_ASYNC=m
+CONFIG_PPP_SYNC_TTY=m
+CONFIG_PPP_DEFLATE=m
+# CONFIG_PPP_BSDCOMP is not set
+CONFIG_PPP_MPPE=m
+CONFIG_PPPOE=m
+CONFIG_PPPOATM=m
+CONFIG_SLIP=m
+CONFIG_SLIP_COMPRESSED=y
+CONFIG_SLIP_SMART=y
+# CONFIG_SLIP_MODE_SLIP6 is not set
+CONFIG_NET_FC=y
+# CONFIG_SHAPER is not set
+CONFIG_NETCONSOLE=m
+CONFIG_NETPOLL=y
+# CONFIG_NETPOLL_RX is not set
+CONFIG_NETPOLL_TRAP=y
+CONFIG_NET_POLL_CONTROLLER=y
+
+#
+# ISDN subsystem
+#
+CONFIG_ISDN=m
+
+#
+# Old ISDN4Linux
+#
+CONFIG_ISDN_I4L=m
+CONFIG_ISDN_PPP=y
+CONFIG_ISDN_PPP_VJ=y
+CONFIG_ISDN_MPP=y
+CONFIG_IPPP_FILTER=y
+# CONFIG_ISDN_PPP_BSDCOMP is not set
+CONFIG_ISDN_AUDIO=y
+CONFIG_ISDN_TTY_FAX=y
+
+#
+# ISDN feature submodules
+#
+CONFIG_ISDN_DRV_LOOP=m
+CONFIG_ISDN_DIVERSION=m
+
+#
+# ISDN4Linux hardware drivers
+#
+
+#
+# Passive cards
+#
+CONFIG_ISDN_DRV_HISAX=m
+
+#
+# D-channel protocol features
+#
+CONFIG_HISAX_EURO=y
+CONFIG_DE_AOC=y
+CONFIG_HISAX_NO_SENDCOMPLETE=y
+CONFIG_HISAX_NO_LLC=y
+CONFIG_HISAX_NO_KEYPAD=y
+CONFIG_HISAX_1TR6=y
+CONFIG_HISAX_NI1=y
+CONFIG_HISAX_MAX_CARDS=8
+
+#
+# HiSax supported cards
+#
+# CONFIG_HISAX_16_0 is not set
+CONFIG_HISAX_16_3=y
+CONFIG_HISAX_S0BOX=y
+# CONFIG_HISAX_AVM_A1 is not set
+CONFIG_HISAX_FRITZPCI=y
+CONFIG_HISAX_AVM_A1_PCMCIA=y
+CONFIG_HISAX_ELSA=y
+# CONFIG_HISAX_IX1MICROR2 is not set
+CONFIG_HISAX_DIEHLDIVA=y
+# CONFIG_HISAX_ASUSCOM is not set
+# CONFIG_HISAX_TELEINT is not set
+# CONFIG_HISAX_HFCS is not set
+CONFIG_HISAX_SEDLBAUER=y
+# CONFIG_HISAX_SPORTSTER is not set
+# CONFIG_HISAX_MIC is not set
+CONFIG_HISAX_NICCY=y
+# CONFIG_HISAX_ISURF is not set
+# CONFIG_HISAX_HSTSAPHIR is not set
+CONFIG_HISAX_BKM_A4T=y
+CONFIG_HISAX_SCT_QUADRO=y
+CONFIG_HISAX_GAZEL=y
+CONFIG_HISAX_W6692=y
+CONFIG_HISAX_HFC_SX=y
+# CONFIG_HISAX_DEBUG is not set
+
+#
+# HiSax PCMCIA card service modules
+#
+CONFIG_HISAX_SEDLBAUER_CS=m
+CONFIG_HISAX_ELSA_CS=m
+CONFIG_HISAX_AVM_A1_CS=m
+CONFIG_HISAX_TELES_CS=m
+
+#
+# HiSax sub driver modules
+#
+CONFIG_HISAX_ST5481=m
+# CONFIG_HISAX_HFCUSB is not set
+CONFIG_HISAX_HFC4S8S=m
+CONFIG_HISAX_FRITZ_PCIPNP=m
+CONFIG_HISAX_HDLC=y
+
+#
+# Active cards
+#
+# CONFIG_ISDN_DRV_ICN is not set
+# CONFIG_ISDN_DRV_SC is not set
+# CONFIG_ISDN_DRV_ACT2000 is not set
+CONFIG_HYSDN=m
+CONFIG_HYSDN_CAPI=y
+
+#
+# Siemens Gigaset
+#
+CONFIG_ISDN_DRV_GIGASET=m
+CONFIG_GIGASET_BASE=m
+CONFIG_GIGASET_M105=m
+# CONFIG_GIGASET_DEBUG is not set
+# CONFIG_GIGASET_UNDOCREQ is not set
+
+#
+# CAPI subsystem
+#
+CONFIG_ISDN_CAPI=m
+CONFIG_ISDN_DRV_AVMB1_VERBOSE_REASON=y
+CONFIG_ISDN_CAPI_MIDDLEWARE=y
+CONFIG_ISDN_CAPI_CAPI20=m
+CONFIG_ISDN_CAPI_CAPIFS_BOOL=y
+CONFIG_ISDN_CAPI_CAPIFS=m
+CONFIG_ISDN_CAPI_CAPIDRV=m
+
+#
+# CAPI hardware drivers
+#
+
+#
+# Active AVM cards
+#
+CONFIG_CAPI_AVM=y
+# CONFIG_ISDN_DRV_AVMB1_B1ISA is not set
+CONFIG_ISDN_DRV_AVMB1_B1PCI=m
+CONFIG_ISDN_DRV_AVMB1_B1PCIV4=y
+# CONFIG_ISDN_DRV_AVMB1_T1ISA is not set
+CONFIG_ISDN_DRV_AVMB1_B1PCMCIA=m
+CONFIG_ISDN_DRV_AVMB1_AVM_CS=m
+CONFIG_ISDN_DRV_AVMB1_T1PCI=m
+CONFIG_ISDN_DRV_AVMB1_C4=m
+
+#
+# Active Eicon DIVA Server cards
+#
+CONFIG_CAPI_EICON=y
+CONFIG_ISDN_DIVAS=m
+CONFIG_ISDN_DIVAS_BRIPCI=y
+CONFIG_ISDN_DIVAS_PRIPCI=y
+CONFIG_ISDN_DIVAS_DIVACAPI=m
+CONFIG_ISDN_DIVAS_USERIDI=m
+CONFIG_ISDN_DIVAS_MAINT=m
+
+#
+# Telephony Support
+#
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+
+#
+# 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=m
+# CONFIG_INPUT_TSDEV is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+CONFIG_KEYBOARD_ATKBD=y
+# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_KEYBOARD_LKKBD is not set
+# CONFIG_KEYBOARD_XTKBD is not set
+# CONFIG_KEYBOARD_NEWTON is not set
+CONFIG_INPUT_MOUSE=y
+CONFIG_MOUSE_PS2=y
+CONFIG_MOUSE_SERIAL=m
+# CONFIG_MOUSE_INPORT is not set
+# CONFIG_MOUSE_LOGIBM is not set
+# CONFIG_MOUSE_PC110PAD is not set
+CONFIG_MOUSE_VSXXXAA=m
+CONFIG_INPUT_JOYSTICK=y
+CONFIG_JOYSTICK_ANALOG=m
+CONFIG_JOYSTICK_A3D=m
+CONFIG_JOYSTICK_ADI=m
+CONFIG_JOYSTICK_COBRA=m
+CONFIG_JOYSTICK_GF2K=m
+CONFIG_JOYSTICK_GRIP=m
+CONFIG_JOYSTICK_GRIP_MP=m
+CONFIG_JOYSTICK_GUILLEMOT=m
+CONFIG_JOYSTICK_INTERACT=m
+CONFIG_JOYSTICK_SIDEWINDER=m
+CONFIG_JOYSTICK_TMDC=m
+CONFIG_JOYSTICK_IFORCE=m
+CONFIG_JOYSTICK_IFORCE_USB=y
+CONFIG_JOYSTICK_IFORCE_232=y
+CONFIG_JOYSTICK_WARRIOR=m
+CONFIG_JOYSTICK_MAGELLAN=m
+CONFIG_JOYSTICK_SPACEORB=m
+CONFIG_JOYSTICK_SPACEBALL=m
+CONFIG_JOYSTICK_STINGER=m
+CONFIG_JOYSTICK_TWIDJOY=m
+CONFIG_JOYSTICK_DB9=m
+CONFIG_JOYSTICK_GAMECON=m
+CONFIG_JOYSTICK_TURBOGRAFX=m
+CONFIG_JOYSTICK_JOYDUMP=m
+CONFIG_INPUT_TOUCHSCREEN=y
+CONFIG_TOUCHSCREEN_GUNZE=m
+CONFIG_TOUCHSCREEN_ELO=m
+CONFIG_TOUCHSCREEN_MTOUCH=m
+CONFIG_TOUCHSCREEN_MK712=m
+CONFIG_INPUT_MISC=y
+CONFIG_INPUT_PCSPKR=m
+CONFIG_INPUT_UINPUT=m
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+CONFIG_SERIO_I8042=y
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_PARKBD is not set
+# CONFIG_SERIO_PCIPS2 is not set
+CONFIG_SERIO_LIBPS2=y
+CONFIG_SERIO_RAW=m
+CONFIG_GAMEPORT=m
+CONFIG_GAMEPORT_NS558=m
+CONFIG_GAMEPORT_L4=m
+CONFIG_GAMEPORT_EMU10K1=m
+CONFIG_GAMEPORT_FM801=m
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+CONFIG_VT_HW_CONSOLE_BINDING=y
+CONFIG_SERIAL_NONSTANDARD=y
+# CONFIG_COMPUTONE is not set
+# CONFIG_ROCKETPORT is not set
+CONFIG_CYCLADES=m
+# CONFIG_CYZ_INTR is not set
+# CONFIG_DIGIEPCA is not set
+# CONFIG_ESPSERIAL is not set
+# CONFIG_MOXA_INTELLIO is not set
+# CONFIG_MOXA_SMARTIO is not set
+# CONFIG_ISI is not set
+CONFIG_SYNCLINK=m
+CONFIG_SYNCLINKMP=m
+CONFIG_SYNCLINK_GT=m
+CONFIG_N_HDLC=m
+# CONFIG_RISCOM8 is not set
+# CONFIG_SPECIALIX is not set
+# CONFIG_SX is not set
+# CONFIG_RIO is not set
+# CONFIG_STALDRV is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_PCI=y
+CONFIG_SERIAL_8250_PNP=y
+CONFIG_SERIAL_8250_CS=m
+CONFIG_SERIAL_8250_NR_UARTS=32
+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=y
+CONFIG_SERIAL_8250_RSA=y
+# CONFIG_SERIAL_8250_FOURPORT is not set
+# CONFIG_SERIAL_8250_ACCENT is not set
+# CONFIG_SERIAL_8250_BOCA is not set
+# CONFIG_SERIAL_8250_HUB6 is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_SERIAL_PMACZILOG=m
+CONFIG_SERIAL_JSM=m
+CONFIG_UNIX98_PTYS=y
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_CRASH is not set
+CONFIG_PRINTER=m
+CONFIG_LP_CONSOLE=y
+CONFIG_PPDEV=m
+CONFIG_TIPAR=m
+# CONFIG_HVC_RTAS is not set
+
+#
+# IPMI
+#
+CONFIG_IPMI_HANDLER=m
+# CONFIG_IPMI_PANIC_EVENT is not set
+CONFIG_IPMI_DEVICE_INTERFACE=m
+CONFIG_IPMI_SI=m
+CONFIG_IPMI_WATCHDOG=m
+CONFIG_IPMI_POWEROFF=m
+
+#
+# Watchdog Cards
+#
+CONFIG_WATCHDOG=y
+# CONFIG_WATCHDOG_NOWAYOUT is not set
+
+#
+# Watchdog Device Drivers
+#
+CONFIG_SOFT_WATCHDOG=m
+CONFIG_WATCHDOG_RTAS=m
+
+#
+# ISA-based Watchdog Cards
+#
+# CONFIG_PCWATCHDOG is not set
+# CONFIG_MIXCOMWD is not set
+# CONFIG_WDT is not set
+
+#
+# PCI-based Watchdog Cards
+#
+CONFIG_PCIPCWATCHDOG=m
+CONFIG_WDTPCI=m
+CONFIG_WDT_501_PCI=y
+
+#
+# USB-based Watchdog Cards
+#
+CONFIG_USBPCWATCHDOG=m
+CONFIG_HW_RANDOM=y
+CONFIG_NVRAM=y
+CONFIG_GEN_RTC=y
+# CONFIG_GEN_RTC_X is not set
+CONFIG_DTLK=m
+CONFIG_R3964=m
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+CONFIG_AGP=y
+CONFIG_AGP_SIS=y
+CONFIG_AGP_VIA=y
+CONFIG_AGP_UNINORTH=y
+CONFIG_DRM=m
+CONFIG_DRM_TDFX=m
+CONFIG_DRM_R128=m
+CONFIG_DRM_RADEON=m
+CONFIG_DRM_MGA=m
+CONFIG_DRM_SIS=m
+CONFIG_DRM_VIA=m
+CONFIG_DRM_SAVAGE=m
+
+#
+# PCMCIA character devices
+#
+# CONFIG_SYNCLINK_CS is not set
+CONFIG_CARDMAN_4000=m
+CONFIG_CARDMAN_4040=m
+# CONFIG_RAW_DRIVER is not set
+
+#
+# TPM devices
+#
+CONFIG_TCG_TPM=m
+CONFIG_TCG_ATMEL=m
+# CONFIG_TELCLOCK is not set
+
+#
+# I2C support
+#
+CONFIG_I2C=y
+CONFIG_I2C_CHARDEV=m
+
+#
+# I2C Algorithms
+#
+CONFIG_I2C_ALGOBIT=y
+CONFIG_I2C_ALGOPCF=m
+CONFIG_I2C_ALGOPCA=m
+
+#
+# I2C Hardware Bus support
+#
+# CONFIG_I2C_ALI1535 is not set
+# CONFIG_I2C_ALI1563 is not set
+# CONFIG_I2C_ALI15X3 is not set
+# CONFIG_I2C_AMD756 is not set
+# CONFIG_I2C_AMD8111 is not set
+# CONFIG_I2C_ELEKTOR is not set
+CONFIG_I2C_HYDRA=m
+# CONFIG_I2C_I801 is not set
+# CONFIG_I2C_I810 is not set
+# CONFIG_I2C_PIIX4 is not set
+CONFIG_I2C_ISA=m
+CONFIG_I2C_POWERMAC=y
+CONFIG_I2C_MPC=m
+CONFIG_I2C_NFORCE2=m
+# CONFIG_I2C_OCORES is not set
+CONFIG_I2C_PARPORT=m
+CONFIG_I2C_PARPORT_LIGHT=m
+CONFIG_I2C_PROSAVAGE=m
+CONFIG_I2C_SAVAGE4=m
+# CONFIG_I2C_SIS5595 is not set
+# CONFIG_I2C_SIS630 is not set
+# CONFIG_I2C_SIS96X is not set
+CONFIG_I2C_STUB=m
+# CONFIG_I2C_VIA is not set
+# CONFIG_I2C_VIAPRO is not set
+CONFIG_I2C_VOODOO3=m
+CONFIG_I2C_PCA_ISA=m
+
+#
+# Miscellaneous I2C Chip support
+#
+CONFIG_SENSORS_DS1337=m
+CONFIG_SENSORS_DS1374=m
+CONFIG_SENSORS_EEPROM=m
+CONFIG_SENSORS_PCF8574=m
+CONFIG_SENSORS_PCA9539=m
+CONFIG_SENSORS_PCF8591=m
+CONFIG_SENSORS_M41T00=m
+CONFIG_SENSORS_MAX6875=m
+# 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 is not set
+# CONFIG_SPI_MASTER is not set
+
+#
+# Dallas's 1-wire bus
+#
+CONFIG_W1=m
+CONFIG_W1_CON=y
+
+#
+# 1-wire Bus Masters
+#
+CONFIG_W1_MASTER_MATROX=m
+CONFIG_W1_MASTER_DS2490=m
+CONFIG_W1_MASTER_DS2482=m
+
+#
+# 1-wire Slaves
+#
+CONFIG_W1_SLAVE_THERM=m
+CONFIG_W1_SLAVE_SMEM=m
+CONFIG_W1_SLAVE_DS2433=m
+CONFIG_W1_SLAVE_DS2433_CRC=y
+
+#
+# Hardware Monitoring support
+#
+CONFIG_HWMON=m
+CONFIG_HWMON_VID=m
+CONFIG_SENSORS_ABITUGURU=m
+CONFIG_SENSORS_ADM1021=m
+CONFIG_SENSORS_ADM1025=m
+CONFIG_SENSORS_ADM1026=m
+CONFIG_SENSORS_ADM1031=m
+CONFIG_SENSORS_ADM9240=m
+CONFIG_SENSORS_ASB100=m
+CONFIG_SENSORS_ATXP1=m
+CONFIG_SENSORS_DS1621=m
+CONFIG_SENSORS_F71805F=m
+CONFIG_SENSORS_FSCHER=m
+CONFIG_SENSORS_FSCPOS=m
+CONFIG_SENSORS_GL518SM=m
+CONFIG_SENSORS_GL520SM=m
+CONFIG_SENSORS_IT87=m
+CONFIG_SENSORS_LM63=m
+CONFIG_SENSORS_LM75=m
+CONFIG_SENSORS_LM77=m
+CONFIG_SENSORS_LM78=m
+CONFIG_SENSORS_LM80=m
+CONFIG_SENSORS_LM83=m
+CONFIG_SENSORS_LM85=m
+CONFIG_SENSORS_LM87=m
+CONFIG_SENSORS_LM90=m
+CONFIG_SENSORS_LM92=m
+CONFIG_SENSORS_MAX1619=m
+CONFIG_SENSORS_PC87360=m
+CONFIG_SENSORS_SIS5595=m
+CONFIG_SENSORS_SMSC47M1=m
+CONFIG_SENSORS_SMSC47M192=m
+CONFIG_SENSORS_SMSC47B397=m
+CONFIG_SENSORS_VIA686A=m
+CONFIG_SENSORS_VT8231=m
+CONFIG_SENSORS_W83781D=m
+CONFIG_SENSORS_W83791D=m
+CONFIG_SENSORS_W83792D=m
+CONFIG_SENSORS_W83L785TS=m
+CONFIG_SENSORS_W83627HF=m
+CONFIG_SENSORS_W83627EHF=m
+# CONFIG_HWMON_DEBUG_CHIP is not set
+
+#
+# Misc devices
+#
+
+#
+# Multimedia devices
+#
+CONFIG_VIDEO_DEV=m
+CONFIG_VIDEO_V4L1=y
+CONFIG_VIDEO_V4L1_COMPAT=y
+CONFIG_VIDEO_V4L2=y
+
+#
+# Video Capture Adapters
+#
+
+#
+# Video Capture Adapters
+#
+# CONFIG_VIDEO_ADV_DEBUG is not set
+# CONFIG_VIDEO_VIVI is not set
+CONFIG_VIDEO_BT848=m
+CONFIG_VIDEO_BT848_DVB=y
+CONFIG_VIDEO_SAA6588=m
+# CONFIG_VIDEO_PMS is not set
+CONFIG_VIDEO_BWQCAM=m
+CONFIG_VIDEO_CQCAM=m
+CONFIG_VIDEO_W9966=m
+CONFIG_VIDEO_CPIA=m
+CONFIG_VIDEO_CPIA_PP=m
+CONFIG_VIDEO_CPIA_USB=m
+CONFIG_VIDEO_CPIA2=m
+CONFIG_VIDEO_SAA5246A=m
+CONFIG_VIDEO_SAA5249=m
+CONFIG_TUNER_3036=m
+# CONFIG_VIDEO_STRADIS is not set
+# CONFIG_VIDEO_ZORAN is not set
+CONFIG_VIDEO_SAA7134=m
+CONFIG_VIDEO_SAA7134_ALSA=m
+CONFIG_VIDEO_SAA7134_DVB=m
+CONFIG_VIDEO_SAA7134_DVB_ALL_FRONTENDS=y
+CONFIG_VIDEO_MXB=m
+CONFIG_VIDEO_DPC=m
+CONFIG_VIDEO_HEXIUM_ORION=m
+CONFIG_VIDEO_HEXIUM_GEMINI=m
+CONFIG_VIDEO_CX88_VP3054=m
+CONFIG_VIDEO_CX88=m
+CONFIG_VIDEO_CX88_ALSA=m
+CONFIG_VIDEO_CX88_BLACKBIRD=m
+CONFIG_VIDEO_CX88_DVB=m
+CONFIG_VIDEO_CX88_DVB_ALL_FRONTENDS=y
+
+#
+# Encoders and Decoders
+#
+CONFIG_VIDEO_MSP3400=m
+CONFIG_VIDEO_CS53L32A=m
+CONFIG_VIDEO_TLV320AIC23B=m
+CONFIG_VIDEO_WM8775=m
+CONFIG_VIDEO_WM8739=m
+CONFIG_VIDEO_CX2341X=m
+CONFIG_VIDEO_CX25840=m
+CONFIG_VIDEO_SAA711X=m
+CONFIG_VIDEO_SAA7127=m
+CONFIG_VIDEO_UPD64031A=m
+CONFIG_VIDEO_UPD64083=m
+
+#
+# V4L USB devices
+#
+CONFIG_VIDEO_PVRUSB2=m
+CONFIG_VIDEO_PVRUSB2_24XXX=y
+CONFIG_VIDEO_PVRUSB2_SYSFS=y
+# CONFIG_VIDEO_PVRUSB2_DEBUGIFC is not set
+CONFIG_VIDEO_EM28XX=m
+CONFIG_VIDEO_USBVIDEO=m
+CONFIG_USB_VICAM=m
+CONFIG_USB_IBMCAM=m
+CONFIG_USB_KONICAWC=m
+CONFIG_USB_QUICKCAM_MESSENGER=m
+CONFIG_USB_ET61X251=m
+CONFIG_VIDEO_OVCAMCHIP=m
+CONFIG_USB_W9968CF=m
+CONFIG_USB_OV511=m
+CONFIG_USB_SE401=m
+CONFIG_USB_SN9C102=m
+CONFIG_USB_STV680=m
+CONFIG_USB_ZC0301=m
+CONFIG_USB_PWC=m
+# CONFIG_USB_PWC_DEBUG is not set
+
+#
+# Radio Adapters
+#
+# CONFIG_RADIO_CADET is not set
+# CONFIG_RADIO_RTRACK is not set
+# CONFIG_RADIO_RTRACK2 is not set
+# CONFIG_RADIO_AZTECH is not set
+# CONFIG_RADIO_GEMTEK is not set
+CONFIG_RADIO_GEMTEK_PCI=m
+CONFIG_RADIO_MAXIRADIO=m
+CONFIG_RADIO_MAESTRO=m
+# CONFIG_RADIO_SF16FMI is not set
+# CONFIG_RADIO_SF16FMR2 is not set
+# CONFIG_RADIO_TERRATEC is not set
+# CONFIG_RADIO_TRUST is not set
+# CONFIG_RADIO_TYPHOON is not set
+# CONFIG_RADIO_ZOLTRIX is not set
+CONFIG_USB_DSBR=m
+
+#
+# Digital Video Broadcasting Devices
+#
+CONFIG_DVB=y
+CONFIG_DVB_CORE=m
+
+#
+# Supported SAA7146 based PCI Adapters
+#
+CONFIG_DVB_AV7110=m
+CONFIG_DVB_AV7110_OSD=y
+CONFIG_DVB_BUDGET=m
+CONFIG_DVB_BUDGET_CI=m
+CONFIG_DVB_BUDGET_AV=m
+CONFIG_DVB_BUDGET_PATCH=m
+
+#
+# Supported USB Adapters
+#
+CONFIG_DVB_USB=m
+# CONFIG_DVB_USB_DEBUG is not set
+CONFIG_DVB_USB_A800=m
+CONFIG_DVB_USB_DIBUSB_MB=m
+# CONFIG_DVB_USB_DIBUSB_MB_FAULTY is not set
+CONFIG_DVB_USB_DIBUSB_MC=m
+CONFIG_DVB_USB_UMT_010=m
+CONFIG_DVB_USB_CXUSB=m
+CONFIG_DVB_USB_DIGITV=m
+CONFIG_DVB_USB_VP7045=m
+CONFIG_DVB_USB_VP702X=m
+CONFIG_DVB_USB_GP8PSK=m
+CONFIG_DVB_USB_NOVA_T_USB2=m
+CONFIG_DVB_USB_DTT200U=m
+CONFIG_DVB_TTUSB_BUDGET=m
+CONFIG_DVB_TTUSB_DEC=m
+CONFIG_DVB_CINERGYT2=m
+CONFIG_DVB_CINERGYT2_TUNING=y
+CONFIG_DVB_CINERGYT2_STREAM_URB_COUNT=32
+CONFIG_DVB_CINERGYT2_STREAM_BUF_SIZE=512
+CONFIG_DVB_CINERGYT2_QUERY_INTERVAL=250
+CONFIG_DVB_CINERGYT2_ENABLE_RC_INPUT_DEVICE=y
+CONFIG_DVB_CINERGYT2_RC_QUERY_INTERVAL=100
+
+#
+# Supported FlexCopII (B2C2) Adapters
+#
+CONFIG_DVB_B2C2_FLEXCOP=m
+CONFIG_DVB_B2C2_FLEXCOP_PCI=m
+CONFIG_DVB_B2C2_FLEXCOP_USB=m
+# CONFIG_DVB_B2C2_FLEXCOP_DEBUG is not set
+
+#
+# Supported BT878 Adapters
+#
+CONFIG_DVB_BT8XX=m
+
+#
+# Supported Pluto2 Adapters
+#
+CONFIG_DVB_PLUTO2=m
+
+#
+# Supported DVB Frontends
+#
+
+#
+# Customise DVB Frontends
+#
+
+#
+# DVB-S (satellite) frontends
+#
+CONFIG_DVB_STV0299=m
+CONFIG_DVB_CX24110=m
+CONFIG_DVB_CX24123=m
+CONFIG_DVB_TDA8083=m
+CONFIG_DVB_MT312=m
+CONFIG_DVB_VES1X93=m
+CONFIG_DVB_S5H1420=m
+
+#
+# DVB-T (terrestrial) frontends
+#
+CONFIG_DVB_SP8870=m
+CONFIG_DVB_SP887X=m
+CONFIG_DVB_CX22700=m
+CONFIG_DVB_CX22702=m
+CONFIG_DVB_L64781=m
+CONFIG_DVB_TDA1004X=m
+CONFIG_DVB_NXT6000=m
+CONFIG_DVB_MT352=m
+CONFIG_DVB_ZL10353=m
+CONFIG_DVB_DIB3000MB=m
+CONFIG_DVB_DIB3000MC=m
+
+#
+# DVB-C (cable) frontends
+#
+CONFIG_DVB_VES1820=m
+CONFIG_DVB_TDA10021=m
+CONFIG_DVB_STV0297=m
+
+#
+# ATSC (North American/Korean Terrestrial/Cable DTV) frontends
+#
+CONFIG_DVB_NXT200X=m
+CONFIG_DVB_OR51211=m
+CONFIG_DVB_OR51132=m
+CONFIG_DVB_BCM3510=m
+CONFIG_DVB_LGDT330X=m
+
+#
+# Miscellaneous devices
+#
+CONFIG_DVB_PLL=m
+CONFIG_DVB_LNBP21=m
+CONFIG_DVB_ISL6421=m
+CONFIG_VIDEO_SAA7146=m
+CONFIG_VIDEO_SAA7146_VV=m
+CONFIG_VIDEO_VIDEOBUF=m
+CONFIG_VIDEO_TUNER=m
+CONFIG_VIDEO_BUF=m
+CONFIG_VIDEO_BUF_DVB=m
+CONFIG_VIDEO_BTCX=m
+CONFIG_VIDEO_IR=m
+CONFIG_VIDEO_TVEEPROM=m
+CONFIG_USB_DABUSB=m
+
+#
+# Graphics support
+#
+# CONFIG_FIRMWARE_EDID is not set
+CONFIG_FB=y
+CONFIG_FB_CFB_FILLRECT=y
+CONFIG_FB_CFB_COPYAREA=y
+CONFIG_FB_CFB_IMAGEBLIT=y
+CONFIG_FB_MACMODES=y
+CONFIG_FB_BACKLIGHT=y
+CONFIG_FB_MODE_HELPERS=y
+CONFIG_FB_TILEBLITTING=y
+CONFIG_FB_CIRRUS=m
+# CONFIG_FB_PM2 is not set
+# CONFIG_FB_CYBER2000 is not set
+CONFIG_FB_OF=y
+# CONFIG_FB_CONTROL is not set
+CONFIG_FB_PLATINUM=y
+CONFIG_FB_VALKYRIE=y
+CONFIG_FB_CT65550=y
+# CONFIG_FB_ASILIANT is not set
+# CONFIG_FB_IMSTT is not set
+# CONFIG_FB_VGA16 is not set
+# CONFIG_FB_S1D13XXX is not set
+CONFIG_FB_NVIDIA=m
+CONFIG_FB_NVIDIA_I2C=y
+CONFIG_FB_NVIDIA_BACKLIGHT=y
+CONFIG_FB_RIVA=m
+# CONFIG_FB_RIVA_I2C is not set
+# CONFIG_FB_RIVA_DEBUG is not set
+CONFIG_FB_RIVA_BACKLIGHT=y
+CONFIG_FB_MATROX=y
+CONFIG_FB_MATROX_MILLENIUM=y
+CONFIG_FB_MATROX_MYSTIQUE=y
+CONFIG_FB_MATROX_G=y
+CONFIG_FB_MATROX_I2C=m
+CONFIG_FB_MATROX_MAVEN=m
+CONFIG_FB_MATROX_MULTIHEAD=y
+CONFIG_FB_RADEON=y
+CONFIG_FB_RADEON_I2C=y
+CONFIG_FB_RADEON_BACKLIGHT=y
+# CONFIG_FB_RADEON_DEBUG is not set
+CONFIG_FB_ATY128=y
+CONFIG_FB_ATY128_BACKLIGHT=y
+CONFIG_FB_ATY=y
+CONFIG_FB_ATY_CT=y
+CONFIG_FB_ATY_GENERIC_LCD=y
+CONFIG_FB_ATY_GX=y
+CONFIG_FB_ATY_BACKLIGHT=y
+CONFIG_FB_SAVAGE=m
+CONFIG_FB_SAVAGE_I2C=y
+CONFIG_FB_SAVAGE_ACCEL=y
+# CONFIG_FB_SIS is not set
+CONFIG_FB_NEOMAGIC=m
+CONFIG_FB_KYRO=m
+CONFIG_FB_3DFX=m
+CONFIG_FB_3DFX_ACCEL=y
+CONFIG_FB_VOODOO1=m
+CONFIG_FB_TRIDENT=m
+CONFIG_FB_TRIDENT_ACCEL=y
+# CONFIG_FB_VIRTUAL is not set
+
+#
+# Console display driver support
+#
+CONFIG_VGA_CONSOLE=y
+CONFIG_VGACON_SOFT_SCROLLBACK=y
+CONFIG_VGACON_SOFT_SCROLLBACK_SIZE=64
+# CONFIG_MDA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y
+# CONFIG_FONTS is not set
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
+
+#
+# Logo configuration
+#
+CONFIG_LOGO=y
+# CONFIG_LOGO_LINUX_MONO is not set
+# CONFIG_LOGO_LINUX_VGA16 is not set
+CONFIG_LOGO_LINUX_CLUT224=y
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+CONFIG_BACKLIGHT_CLASS_DEVICE=y
+CONFIG_BACKLIGHT_DEVICE=y
+CONFIG_LCD_CLASS_DEVICE=m
+CONFIG_LCD_DEVICE=y
+
+#
+# Sound
+#
+CONFIG_SOUND=m
+CONFIG_DMASOUND_PMAC=m
+CONFIG_DMASOUND=m
+
+#
+# Advanced Linux Sound Architecture
+#
+CONFIG_SND=m
+CONFIG_SND_TIMER=m
+CONFIG_SND_PCM=m
+CONFIG_SND_HWDEP=m
+CONFIG_SND_RAWMIDI=m
+CONFIG_SND_SEQUENCER=m
+CONFIG_SND_SEQ_DUMMY=m
+CONFIG_SND_OSSEMUL=y
+CONFIG_SND_MIXER_OSS=m
+CONFIG_SND_PCM_OSS=m
+CONFIG_SND_PCM_OSS_PLUGINS=y
+CONFIG_SND_SEQUENCER_OSS=y
+CONFIG_SND_DYNAMIC_MINORS=y
+# CONFIG_SND_SUPPORT_OLD_API is not set
+CONFIG_SND_VERBOSE_PROCFS=y
+# CONFIG_SND_VERBOSE_PRINTK is not set
+# CONFIG_SND_DEBUG is not set
+
+#
+# Generic devices
+#
+CONFIG_SND_MPU401_UART=m
+CONFIG_SND_OPL3_LIB=m
+CONFIG_SND_OPL4_LIB=m
+CONFIG_SND_VX_LIB=m
+CONFIG_SND_AC97_CODEC=m
+CONFIG_SND_AC97_BUS=m
+CONFIG_SND_DUMMY=m
+CONFIG_SND_VIRMIDI=m
+CONFIG_SND_MTPAV=m
+# CONFIG_SND_SERIAL_U16550 is not set
+CONFIG_SND_MPU401=m
+
+#
+# ISA devices
+#
+CONFIG_SND_CS4231_LIB=m
+CONFIG_SND_ADLIB=m
+# CONFIG_SND_AD1816A is not set
+# CONFIG_SND_AD1848 is not set
+# CONFIG_SND_ALS100 is not set
+# CONFIG_SND_AZT2320 is not set
+# CONFIG_SND_CMI8330 is not set
+# CONFIG_SND_CS4231 is not set
+# CONFIG_SND_CS4232 is not set
+CONFIG_SND_CS4236=m
+# CONFIG_SND_DT019X is not set
+# CONFIG_SND_ES968 is not set
+# CONFIG_SND_ES1688 is not set
+# CONFIG_SND_ES18XX is not set
+# CONFIG_SND_GUSCLASSIC is not set
+# CONFIG_SND_GUSEXTREME is not set
+# CONFIG_SND_GUSMAX is not set
+# CONFIG_SND_INTERWAVE is not set
+# CONFIG_SND_INTERWAVE_STB is not set
+CONFIG_SND_OPL3SA2=m
+# CONFIG_SND_OPTI92X_AD1848 is not set
+# CONFIG_SND_OPTI92X_CS4231 is not set
+# CONFIG_SND_OPTI93X is not set
+CONFIG_SND_MIRO=m
+# CONFIG_SND_SB8 is not set
+CONFIG_SND_SB16=m
+CONFIG_SND_SBAWE=m
+# CONFIG_SND_SGALAXY is not set
+# CONFIG_SND_SSCAPE is not set
+# CONFIG_SND_WAVEFRONT is not set
+
+#
+# PCI devices
+#
+CONFIG_SND_AD1889=m
+CONFIG_SND_ALS300=m
+CONFIG_SND_ALS4000=m
+CONFIG_SND_ALI5451=m
+CONFIG_SND_ATIIXP=m
+CONFIG_SND_ATIIXP_MODEM=m
+CONFIG_SND_AU8810=m
+CONFIG_SND_AU8820=m
+CONFIG_SND_AU8830=m
+CONFIG_SND_AZT3328=m
+CONFIG_SND_BT87X=m
+# CONFIG_SND_BT87X_OVERCLOCK is not set
+CONFIG_SND_CA0106=m
+CONFIG_SND_CMIPCI=m
+CONFIG_SND_CS4281=m
+CONFIG_SND_CS46XX=m
+CONFIG_SND_CS46XX_NEW_DSP=y
+CONFIG_SND_DARLA20=m
+CONFIG_SND_GINA20=m
+CONFIG_SND_LAYLA20=m
+CONFIG_SND_DARLA24=m
+CONFIG_SND_GINA24=m
+CONFIG_SND_LAYLA24=m
+CONFIG_SND_MONA=m
+CONFIG_SND_MIA=m
+CONFIG_SND_ECHO3G=m
+CONFIG_SND_INDIGO=m
+CONFIG_SND_INDIGOIO=m
+CONFIG_SND_INDIGODJ=m
+CONFIG_SND_EMU10K1=m
+CONFIG_SND_EMU10K1X=m
+CONFIG_SND_ENS1370=m
+CONFIG_SND_ENS1371=m
+CONFIG_SND_ES1938=m
+CONFIG_SND_ES1968=m
+CONFIG_SND_FM801=m
+CONFIG_SND_FM801_TEA575X_BOOL=y
+CONFIG_SND_FM801_TEA575X=m
+CONFIG_SND_HDA_INTEL=m
+CONFIG_SND_HDSP=m
+CONFIG_SND_HDSPM=m
+CONFIG_SND_ICE1712=m
+CONFIG_SND_ICE1724=m
+CONFIG_SND_INTEL8X0=m
+CONFIG_SND_INTEL8X0M=m
+CONFIG_SND_KORG1212=m
+CONFIG_SND_MAESTRO3=m
+CONFIG_SND_MIXART=m
+CONFIG_SND_NM256=m
+CONFIG_SND_PCXHR=m
+CONFIG_SND_RIPTIDE=m
+CONFIG_SND_RME32=m
+CONFIG_SND_RME96=m
+CONFIG_SND_RME9652=m
+CONFIG_SND_SONICVIBES=m
+CONFIG_SND_TRIDENT=m
+CONFIG_SND_VIA82XX=m
+CONFIG_SND_VIA82XX_MODEM=m
+CONFIG_SND_VX222=m
+CONFIG_SND_YMFPCI=m
+
+#
+# ALSA PowerMac devices
+#
+CONFIG_SND_POWERMAC=m
+CONFIG_SND_POWERMAC_AUTO_DRC=y
+
+#
+# Apple Onboard Audio driver
+#
+CONFIG_SND_AOA=m
+CONFIG_SND_AOA_FABRIC_LAYOUT=m
+CONFIG_SND_AOA_ONYX=m
+CONFIG_SND_AOA_TAS=m
+CONFIG_SND_AOA_TOONIE=m
+CONFIG_SND_AOA_SOUNDBUS=m
+CONFIG_SND_AOA_SOUNDBUS_I2S=m
+
+#
+# USB devices
+#
+CONFIG_SND_USB_AUDIO=m
+CONFIG_SND_USB_USX2Y=m
+
+#
+# PCMCIA devices
+#
+# CONFIG_SND_VXPOCKET is not set
+# CONFIG_SND_PDAUDIOCF is not set
+
+#
+# Open Sound System
+#
+# CONFIG_SOUND_PRIME is not set
+
+#
+# USB support
+#
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB_ARCH_HAS_EHCI=y
+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_SUSPEND is not set
+# CONFIG_USB_OTG is not set
+
+#
+# USB Host Controller Drivers
+#
+CONFIG_USB_EHCI_HCD=m
+CONFIG_USB_EHCI_SPLIT_ISO=y
+CONFIG_USB_EHCI_ROOT_HUB_TT=y
+CONFIG_USB_EHCI_TT_NEWSCHED=y
+CONFIG_USB_ISP116X_HCD=m
+CONFIG_USB_OHCI_HCD=m
+# CONFIG_USB_OHCI_BIG_ENDIAN is not set
+CONFIG_USB_OHCI_LITTLE_ENDIAN=y
+CONFIG_USB_UHCI_HCD=m
+CONFIG_USB_SL811_HCD=m
+CONFIG_USB_SL811_CS=m
+
+#
+# USB Device Class drivers
+#
+CONFIG_USB_ACM=m
+CONFIG_USB_PRINTER=m
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+#
+
+#
+# may also be needed; see USB_STORAGE Help for more information
+#
+CONFIG_USB_STORAGE=m
+# CONFIG_USB_STORAGE_DEBUG is not set
+CONFIG_USB_STORAGE_DATAFAB=y
+CONFIG_USB_STORAGE_FREECOM=y
+CONFIG_USB_STORAGE_ISD200=y
+CONFIG_USB_STORAGE_DPCM=y
+CONFIG_USB_STORAGE_USBAT=y
+CONFIG_USB_STORAGE_SDDR09=y
+CONFIG_USB_STORAGE_SDDR55=y
+CONFIG_USB_STORAGE_JUMPSHOT=y
+CONFIG_USB_STORAGE_ALAUDA=y
+CONFIG_USB_LIBUSUAL=y
+
+#
+# USB Input Devices
+#
+CONFIG_USB_HID=y
+CONFIG_USB_HIDINPUT=y
+CONFIG_USB_HIDINPUT_POWERBOOK=y
+CONFIG_HID_FF=y
+CONFIG_HID_PID=y
+CONFIG_LOGITECH_FF=y
+CONFIG_THRUSTMASTER_FF=y
+CONFIG_USB_HIDDEV=y
+CONFIG_USB_AIPTEK=m
+CONFIG_USB_WACOM=m
+CONFIG_USB_ACECAD=m
+CONFIG_USB_KBTAB=m
+CONFIG_USB_POWERMATE=m
+CONFIG_USB_TOUCHSCREEN=m
+CONFIG_USB_TOUCHSCREEN_EGALAX=y
+CONFIG_USB_TOUCHSCREEN_PANJIT=y
+CONFIG_USB_TOUCHSCREEN_3M=y
+CONFIG_USB_TOUCHSCREEN_ITM=y
+# CONFIG_USB_YEALINK is not set
+CONFIG_USB_XPAD=m
+CONFIG_USB_ATI_REMOTE=m
+CONFIG_USB_ATI_REMOTE2=m
+CONFIG_USB_KEYSPAN_REMOTE=m
+CONFIG_USB_APPLETOUCH=m
+
+#
+# USB Imaging devices
+#
+CONFIG_USB_MDC800=m
+CONFIG_USB_MICROTEK=m
+
+#
+# USB Network Adapters
+#
+CONFIG_USB_CATC=m
+CONFIG_USB_KAWETH=m
+CONFIG_USB_PEGASUS=m
+CONFIG_USB_RTL8150=m
+CONFIG_USB_USBNET=m
+CONFIG_USB_NET_AX8817X=m
+CONFIG_USB_NET_CDCETHER=m
+CONFIG_USB_NET_GL620A=m
+CONFIG_USB_NET_NET1080=m
+CONFIG_USB_NET_PLUSB=m
+CONFIG_USB_NET_RNDIS_HOST=m
+CONFIG_USB_NET_CDC_SUBSET=m
+CONFIG_USB_ALI_M5632=y
+CONFIG_USB_AN2720=y
+CONFIG_USB_BELKIN=y
+CONFIG_USB_ARMLINUX=y
+CONFIG_USB_EPSON2888=y
+CONFIG_USB_NET_ZAURUS=m
+CONFIG_USB_MON=y
+
+#
+# USB port drivers
+#
+CONFIG_USB_USS720=m
+
+#
+# USB Serial Converter support
+#
+CONFIG_USB_SERIAL=m
+CONFIG_USB_SERIAL_GENERIC=y
+CONFIG_USB_SERIAL_AIRPRIME=m
+CONFIG_USB_SERIAL_ARK3116=m
+CONFIG_USB_SERIAL_BELKIN=m
+CONFIG_USB_SERIAL_WHITEHEAT=m
+CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m
+CONFIG_USB_SERIAL_CP2101=m
+CONFIG_USB_SERIAL_CYPRESS_M8=m
+CONFIG_USB_SERIAL_EMPEG=m
+CONFIG_USB_SERIAL_FTDI_SIO=m
+CONFIG_USB_SERIAL_FUNSOFT=m
+CONFIG_USB_SERIAL_VISOR=m
+CONFIG_USB_SERIAL_IPAQ=m
+CONFIG_USB_SERIAL_IR=m
+CONFIG_USB_SERIAL_EDGEPORT=m
+CONFIG_USB_SERIAL_EDGEPORT_TI=m
+CONFIG_USB_SERIAL_GARMIN=m
+CONFIG_USB_SERIAL_IPW=m
+CONFIG_USB_SERIAL_KEYSPAN_PDA=m
+CONFIG_USB_SERIAL_KEYSPAN=m
+CONFIG_USB_SERIAL_KEYSPAN_MPR=y
+CONFIG_USB_SERIAL_KEYSPAN_USA28=y
+CONFIG_USB_SERIAL_KEYSPAN_USA28X=y
+CONFIG_USB_SERIAL_KEYSPAN_USA28XA=y
+CONFIG_USB_SERIAL_KEYSPAN_USA28XB=y
+CONFIG_USB_SERIAL_KEYSPAN_USA19=y
+CONFIG_USB_SERIAL_KEYSPAN_USA18X=y
+CONFIG_USB_SERIAL_KEYSPAN_USA19W=y
+CONFIG_USB_SERIAL_KEYSPAN_USA19QW=y
+CONFIG_USB_SERIAL_KEYSPAN_USA19QI=y
+CONFIG_USB_SERIAL_KEYSPAN_USA49W=y
+CONFIG_USB_SERIAL_KEYSPAN_USA49WLC=y
+CONFIG_USB_SERIAL_KLSI=m
+CONFIG_USB_SERIAL_KOBIL_SCT=m
+CONFIG_USB_SERIAL_MCT_U232=m
+CONFIG_USB_SERIAL_NAVMAN=m
+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=m
+CONFIG_USB_SERIAL_TI=m
+CONFIG_USB_SERIAL_CYBERJACK=m
+CONFIG_USB_SERIAL_XIRCOM=m
+CONFIG_USB_SERIAL_OPTION=m
+CONFIG_USB_SERIAL_OMNINET=m
+CONFIG_USB_EZUSB=y
+
+#
+# USB Miscellaneous drivers
+#
+CONFIG_USB_EMI62=m
+CONFIG_USB_EMI26=m
+CONFIG_USB_AUERSWALD=m
+CONFIG_USB_RIO500=m
+CONFIG_USB_LEGOTOWER=m
+CONFIG_USB_LCD=m
+CONFIG_USB_LED=m
+# CONFIG_USB_CYPRESS_CY7C63 is not set
+# CONFIG_USB_CYTHERM is not set
+CONFIG_USB_PHIDGETKIT=m
+CONFIG_USB_PHIDGETSERVO=m
+CONFIG_USB_IDMOUSE=m
+CONFIG_USB_APPLEDISPLAY=m
+CONFIG_USB_SISUSBVGA=m
+CONFIG_USB_SISUSBVGA_CON=y
+CONFIG_USB_LD=m
+CONFIG_USB_TEST=m
+
+#
+# USB DSL modem support
+#
+CONFIG_USB_ATM=m
+CONFIG_USB_SPEEDTOUCH=m
+CONFIG_USB_CXACRU=m
+CONFIG_USB_UEAGLEATM=m
+CONFIG_USB_XUSBATM=m
+
+#
+# USB Gadget Support
+#
+# CONFIG_USB_GADGET is not set
+
+#
+# MMC/SD Card support
+#
+CONFIG_MMC=m
+# CONFIG_MMC_DEBUG is not set
+CONFIG_MMC_BLOCK=m
+CONFIG_MMC_SDHCI=m
+CONFIG_MMC_WBSD=m
+
+#
+# LED devices
+#
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+
+#
+# LED drivers
+#
+
+#
+# LED Triggers
+#
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_LEDS_TRIGGER_TIMER=m
+CONFIG_LEDS_TRIGGER_IDE_DISK=y
+CONFIG_LEDS_TRIGGER_HEARTBEAT=m
+
+#
+# InfiniBand support
+#
+CONFIG_INFINIBAND=m
+CONFIG_INFINIBAND_USER_MAD=m
+CONFIG_INFINIBAND_USER_ACCESS=m
+CONFIG_INFINIBAND_ADDR_TRANS=y
+CONFIG_INFINIBAND_MTHCA=m
+CONFIG_INFINIBAND_MTHCA_DEBUG=y
+CONFIG_INFINIBAND_IPOIB=m
+CONFIG_INFINIBAND_IPOIB_DEBUG=y
+CONFIG_INFINIBAND_IPOIB_DEBUG_DATA=y
+CONFIG_INFINIBAND_SRP=m
+CONFIG_INFINIBAND_ISER=m
+
+#
+# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
+#
+
+#
+# Real Time Clock
+#
+CONFIG_RTC_LIB=m
+CONFIG_RTC_CLASS=m
+
+#
+# RTC interfaces
+#
+CONFIG_RTC_INTF_SYSFS=m
+CONFIG_RTC_INTF_PROC=m
+CONFIG_RTC_INTF_DEV=m
+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
+
+#
+# RTC drivers
+#
+CONFIG_RTC_DRV_X1205=m
+CONFIG_RTC_DRV_DS1307=m
+CONFIG_RTC_DRV_DS1553=m
+CONFIG_RTC_DRV_ISL1208=m
+CONFIG_RTC_DRV_DS1672=m
+CONFIG_RTC_DRV_DS1742=m
+CONFIG_RTC_DRV_PCF8563=m
+CONFIG_RTC_DRV_PCF8583=m
+CONFIG_RTC_DRV_RS5C372=m
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_TEST is not set
+CONFIG_RTC_DRV_V3020=m
+
+#
+# DMA Engine support
+#
+CONFIG_DMA_ENGINE=y
+
+#
+# DMA Clients
+#
+CONFIG_NET_DMA=y
+
+#
+# DMA Devices
+#
+CONFIG_INTEL_IOATDMA=m
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+CONFIG_EXT2_FS_POSIX_ACL=y
+CONFIG_EXT2_FS_SECURITY=y
+CONFIG_EXT2_FS_XIP=y
+CONFIG_FS_XIP=y
+CONFIG_EXT3_FS=m
+CONFIG_EXT3_FS_XATTR=y
+CONFIG_EXT3_FS_POSIX_ACL=y
+CONFIG_EXT3_FS_SECURITY=y
+CONFIG_JBD=m
+# CONFIG_JBD_DEBUG is not set
+CONFIG_FS_MBCACHE=y
+CONFIG_REISERFS_FS=m
+# CONFIG_REISERFS_CHECK is not set
+CONFIG_REISERFS_PROC_INFO=y
+CONFIG_REISERFS_FS_XATTR=y
+CONFIG_REISERFS_FS_POSIX_ACL=y
+CONFIG_REISERFS_FS_SECURITY=y
+CONFIG_JFS_FS=m
+CONFIG_JFS_POSIX_ACL=y
+CONFIG_JFS_SECURITY=y
+# CONFIG_JFS_DEBUG is not set
+# CONFIG_JFS_STATISTICS is not set
+CONFIG_FS_POSIX_ACL=y
+CONFIG_XFS_FS=m
+CONFIG_XFS_QUOTA=y
+CONFIG_XFS_SECURITY=y
+CONFIG_XFS_POSIX_ACL=y
+# CONFIG_XFS_RT is not set
+CONFIG_OCFS2_FS=m
+# CONFIG_OCFS2_DEBUG_MASKLOG is not set
+CONFIG_MINIX_FS=m
+CONFIG_ROMFS_FS=m
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+CONFIG_QUOTA=y
+# CONFIG_QFMT_V1 is not set
+CONFIG_QFMT_V2=y
+CONFIG_QUOTACTL=y
+CONFIG_DNOTIFY=y
+CONFIG_AUTOFS_FS=m
+CONFIG_AUTOFS4_FS=m
+CONFIG_FUSE_FS=m
+
+#
+# Caches
+#
+CONFIG_FSCACHE=m
+
+#
+# CD-ROM/DVD Filesystems
+#
+CONFIG_ISO9660_FS=y
+CONFIG_JOLIET=y
+CONFIG_ZISOFS=y
+CONFIG_ZISOFS_FS=y
+CONFIG_UDF_FS=m
+CONFIG_UDF_NLS=y
+CONFIG_CACHEFILES=m
+CONFIG_CACHEFILES_DEBUG=y
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=m
+CONFIG_MSDOS_FS=m
+CONFIG_VFAT_FS=m
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="ascii"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_RAMFS=y
+CONFIG_CONFIGFS_FS=m
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+CONFIG_AFFS_FS=m
+CONFIG_HFS_FS=m
+CONFIG_HFSPLUS_FS=m
+CONFIG_BEFS_FS=m
+# CONFIG_BEFS_DEBUG is not set
+CONFIG_BFS_FS=m
+CONFIG_EFS_FS=m
+# CONFIG_JFFS_FS is not set
+CONFIG_JFFS2_FS=m
+CONFIG_JFFS2_FS_DEBUG=0
+CONFIG_JFFS2_FS_WRITEBUFFER=y
+CONFIG_JFFS2_SUMMARY=y
+# 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=m
+CONFIG_SQUASHFS=m
+# CONFIG_SQUASHFS_EMBEDDED is not set
+CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3
+# CONFIG_SQUASHFS_VMALLOC is not set
+CONFIG_VXFS_FS=m
+# CONFIG_HPFS_FS is not set
+CONFIG_QNX4FS_FS=m
+CONFIG_SYSV_FS=m
+CONFIG_UFS_FS=m
+# CONFIG_UFS_FS_WRITE is not set
+# CONFIG_UFS_DEBUG is not set
+
+#
+# Network File Systems
+#
+CONFIG_NFS_FS=m
+CONFIG_NFS_V3=y
+CONFIG_NFS_V3_ACL=y
+CONFIG_NFS_V4=y
+CONFIG_NFS_FSCACHE=y
+CONFIG_NFS_DIRECTIO=y
+CONFIG_NFSD=m
+CONFIG_NFSD_V2_ACL=y
+CONFIG_NFSD_V3=y
+CONFIG_NFSD_V3_ACL=y
+CONFIG_NFSD_V4=y
+CONFIG_NFSD_TCP=y
+CONFIG_LOCKD=m
+CONFIG_LOCKD_V4=y
+CONFIG_EXPORTFS=m
+CONFIG_NFS_ACL_SUPPORT=m
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=m
+CONFIG_SUNRPC_GSS=m
+CONFIG_RPCSEC_GSS_KRB5=m
+CONFIG_RPCSEC_GSS_SPKM3=m
+# CONFIG_SMB_FS is not set
+CONFIG_CIFS=m
+# CONFIG_CIFS_STATS is not set
+CONFIG_CIFS_WEAK_PW_HASH=y
+CONFIG_CIFS_XATTR=y
+CONFIG_CIFS_POSIX=y
+# CONFIG_CIFS_DEBUG2 is not set
+# CONFIG_CIFS_EXPERIMENTAL is not set
+CONFIG_NCP_FS=m
+CONFIG_NCPFS_PACKET_SIGNING=y
+CONFIG_NCPFS_IOCTL_LOCKING=y
+CONFIG_NCPFS_STRONG=y
+CONFIG_NCPFS_NFS_NS=y
+CONFIG_NCPFS_OS2_NS=y
+CONFIG_NCPFS_SMALLDOS=y
+CONFIG_NCPFS_NLS=y
+CONFIG_NCPFS_EXTRAS=y
+CONFIG_CODA_FS=m
+# CONFIG_CODA_FS_OLD_API is not set
+# CONFIG_AFS_FS is not set
+CONFIG_9P_FS=m
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+CONFIG_OSF_PARTITION=y
+CONFIG_AMIGA_PARTITION=y
+# CONFIG_ATARI_PARTITION is not set
+CONFIG_MAC_PARTITION=y
+CONFIG_MSDOS_PARTITION=y
+CONFIG_BSD_DISKLABEL=y
+CONFIG_MINIX_SUBPARTITION=y
+CONFIG_SOLARIS_X86_PARTITION=y
+CONFIG_UNIXWARE_DISKLABEL=y
+# CONFIG_LDM_PARTITION is not set
+CONFIG_SGI_PARTITION=y
+# CONFIG_ULTRIX_PARTITION is not set
+CONFIG_SUN_PARTITION=y
+CONFIG_KARMA_PARTITION=y
+CONFIG_EFI_PARTITION=y
+
+#
+# Native Language Support
+#
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="utf8"
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_CODEPAGE_737=m
+CONFIG_NLS_CODEPAGE_775=m
+CONFIG_NLS_CODEPAGE_850=m
+CONFIG_NLS_CODEPAGE_852=m
+CONFIG_NLS_CODEPAGE_855=m
+CONFIG_NLS_CODEPAGE_857=m
+CONFIG_NLS_CODEPAGE_860=m
+CONFIG_NLS_CODEPAGE_861=m
+CONFIG_NLS_CODEPAGE_862=m
+CONFIG_NLS_CODEPAGE_863=m
+CONFIG_NLS_CODEPAGE_864=m
+CONFIG_NLS_CODEPAGE_865=m
+CONFIG_NLS_CODEPAGE_866=m
+CONFIG_NLS_CODEPAGE_869=m
+CONFIG_NLS_CODEPAGE_936=m
+CONFIG_NLS_CODEPAGE_950=m
+CONFIG_NLS_CODEPAGE_932=m
+CONFIG_NLS_CODEPAGE_949=m
+CONFIG_NLS_CODEPAGE_874=m
+CONFIG_NLS_ISO8859_8=m
+CONFIG_NLS_CODEPAGE_1250=m
+CONFIG_NLS_CODEPAGE_1251=m
+CONFIG_NLS_ASCII=y
+CONFIG_NLS_ISO8859_1=m
+CONFIG_NLS_ISO8859_2=m
+CONFIG_NLS_ISO8859_3=m
+CONFIG_NLS_ISO8859_4=m
+CONFIG_NLS_ISO8859_5=m
+CONFIG_NLS_ISO8859_6=m
+CONFIG_NLS_ISO8859_7=m
+CONFIG_NLS_ISO8859_9=m
+CONFIG_NLS_ISO8859_13=m
+CONFIG_NLS_ISO8859_14=m
+CONFIG_NLS_ISO8859_15=m
+CONFIG_NLS_KOI8_R=m
+CONFIG_NLS_KOI8_U=m
+CONFIG_NLS_UTF8=m
+
+#
+# Library routines
+#
+CONFIG_CRC_CCITT=m
+CONFIG_CRC16=m
+CONFIG_CRC32=y
+CONFIG_LIBCRC32C=m
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=m
+CONFIG_REED_SOLOMON=m
+CONFIG_REED_SOLOMON_DEC16=y
+CONFIG_TEXTSEARCH=y
+CONFIG_TEXTSEARCH_KMP=m
+CONFIG_TEXTSEARCH_BM=m
+CONFIG_TEXTSEARCH_FSM=m
+CONFIG_PLIST=y
+
+#
+# Instrumentation Support
+#
+CONFIG_PROFILING=y
+CONFIG_OPROFILE=m
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_UNUSED_SYMBOLS is not set
+CONFIG_DEBUG_KERNEL=y
+CONFIG_LOG_BUF_SHIFT=17
+CONFIG_DETECT_SOFTLOCKUP=y
+CONFIG_SCHEDSTATS=y
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
+CONFIG_DEBUG_SPINLOCK=y
+# CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_RWSEMS is not set
+CONFIG_DEBUG_SPINLOCK_SLEEP=y
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+# CONFIG_DEBUG_KOBJECT is not set
+CONFIG_DEBUG_HIGHMEM=y
+CONFIG_DEBUG_INFO=y
+CONFIG_DEBUG_FS=y
+# CONFIG_DEBUG_VM is not set
+CONFIG_DEBUG_LIST=y
+# CONFIG_FORCED_INLINING is not set
+CONFIG_BOOT_DELAY=y
+# CONFIG_RCU_TORTURE_TEST is not set
+CONFIG_DEBUGGER=y
+CONFIG_XMON=y
+CONFIG_XMON_DEFAULT=y
+# CONFIG_BDI_SWITCH is not set
+CONFIG_BOOTX_TEXT=y
+# CONFIG_PPC_EARLY_DEBUG is not set
+
+#
+# Security options
+#
+CONFIG_KEYS=y
+CONFIG_KEYS_DEBUG_PROC_KEYS=y
+CONFIG_SECURITY=y
+CONFIG_SECURITY_NETWORK=y
+# CONFIG_SECURITY_NETWORK_XFRM is not set
+CONFIG_SECURITY_CAPABILITIES=y
+# CONFIG_SECURITY_ROOTPLUG is not set
+# CONFIG_SECURITY_SECLVL is not set
+CONFIG_SECURITY_SELINUX=y
+CONFIG_SECURITY_SELINUX_BOOTPARAM=y
+CONFIG_SECURITY_SELINUX_BOOTPARAM_VALUE=1
+CONFIG_SECURITY_SELINUX_DISABLE=y
+CONFIG_SECURITY_SELINUX_DEVELOP=y
+CONFIG_SECURITY_SELINUX_AVC_STATS=y
+CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE=1
+# CONFIG_SECURITY_SELINUX_ENABLE_SECMARK_DEFAULT is not set
+# CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX is not set
+
+#
+# Cryptographic options
+#
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_NULL=m
+CONFIG_CRYPTO_MD4=m
+CONFIG_CRYPTO_MD5=m
+CONFIG_CRYPTO_SHA1=y
+CONFIG_CRYPTO_SHA256=m
+CONFIG_CRYPTO_SHA512=m
+CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_TGR192=m
+CONFIG_CRYPTO_DES=m
+CONFIG_CRYPTO_BLOWFISH=m
+CONFIG_CRYPTO_TWOFISH=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_TEST is not set
+CONFIG_CRYPTO_SIGNATURE=y
+CONFIG_CRYPTO_SIGNATURE_DSA=y
+CONFIG_CRYPTO_MPILIB=y
+
+#
+# Hardware crypto devices
+#
diff --git a/configs/kernel-2.6.18-ppc64-kdump.config b/configs/kernel-2.6.18-ppc64-kdump.config
new file mode 100644
index 000000000..aba782700
--- /dev/null
+++ b/configs/kernel-2.6.18-ppc64-kdump.config
@@ -0,0 +1,3039 @@
+# powerpc
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.18.2-rc1
+# Mon Nov 13 09:44:42 2006
+#
+CONFIG_PPC64=y
+CONFIG_64BIT=y
+CONFIG_PPC_MERGE=y
+CONFIG_MMU=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_IRQ_PER_CPU=y
+CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_PPC=y
+CONFIG_EARLY_PRINTK=y
+CONFIG_COMPAT=y
+CONFIG_SYSVIPC_COMPAT=y
+CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
+CONFIG_ARCH_MAY_HAVE_PC_FDC=y
+CONFIG_PPC_OF=y
+CONFIG_PPC_UDBG_16550=y
+CONFIG_GENERIC_TBSYNC=y
+CONFIG_AUDIT_ARCH=y
+# CONFIG_DEFAULT_UIMAGE is not set
+
+#
+# Processor support
+#
+# CONFIG_POWER4_ONLY is not set
+CONFIG_POWER3=y
+CONFIG_POWER4=y
+CONFIG_PPC_FPU=y
+CONFIG_ALTIVEC=y
+CONFIG_PPC_STD_MMU=y
+CONFIG_VIRT_CPU_ACCOUNTING=y
+CONFIG_SMP=y
+CONFIG_NR_CPUS=128
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_BSD_PROCESS_ACCT=y
+# CONFIG_BSD_PROCESS_ACCT_V3 is not set
+CONFIG_TASKSTATS=y
+CONFIG_TASK_DELAY_ACCT=y
+CONFIG_AUDIT=y
+CONFIG_AUDITSYSCALL=y
+# CONFIG_IKCONFIG is not set
+CONFIG_CPUSETS=y
+CONFIG_RELAY=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+# CONFIG_EMBEDDED is not set
+CONFIG_SYSCTL=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
+CONFIG_KALLSYMS_EXTRA_PASS=y
+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=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+CONFIG_MODULE_SIG=y
+# CONFIG_MODULE_SIG_FORCE is not set
+CONFIG_KMOD=y
+CONFIG_STOP_MACHINE=y
+
+#
+# Process debugging support
+#
+CONFIG_UTRACE=y
+CONFIG_PTRACE=y
+
+#
+# Block layer
+#
+CONFIG_BLK_DEV_IO_TRACE=y
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_DEFAULT_AS is not set
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+
+#
+# Platform support
+#
+CONFIG_PPC_MULTIPLATFORM=y
+# CONFIG_PPC_ISERIES is not set
+# CONFIG_EMBEDDED6xx is not set
+# CONFIG_APUS is not set
+CONFIG_PPC_PSERIES=y
+CONFIG_PPC_PMAC=y
+CONFIG_PPC_PMAC64=y
+# CONFIG_PPC_MAPLE is not set
+CONFIG_PPC_CELL=y
+CONFIG_PPC_CELL_NATIVE=y
+CONFIG_PPC_IBM_CELL_BLADE=y
+CONFIG_UDBG_RTAS_CONSOLE=y
+CONFIG_MAMBO=y
+CONFIG_MAMBO_DISK=m
+CONFIG_MAMBO_NET=m
+CONFIG_XICS=y
+CONFIG_U3_DART=y
+CONFIG_PPC_RTAS=y
+CONFIG_RTAS_ERROR_LOGGING=y
+CONFIG_RTAS_PROC=y
+CONFIG_RTAS_FLASH=y
+CONFIG_MMIO_NVRAM=y
+CONFIG_MPIC_BROKEN_U3=y
+CONFIG_IBMVIO=y
+CONFIG_IBMEBUS=y
+# CONFIG_PPC_MPC106 is not set
+CONFIG_PPC_970_NAP=y
+CONFIG_CPU_FREQ=y
+CONFIG_CPU_FREQ_TABLE=y
+CONFIG_CPU_FREQ_DEBUG=y
+CONFIG_CPU_FREQ_STAT=m
+CONFIG_CPU_FREQ_STAT_DETAILS=y
+# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set
+CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE=y
+CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
+CONFIG_CPU_FREQ_GOV_POWERSAVE=m
+CONFIG_CPU_FREQ_GOV_USERSPACE=y
+CONFIG_CPU_FREQ_GOV_ONDEMAND=m
+CONFIG_CPU_FREQ_GOV_CONSERVATIVE=m
+CONFIG_CPU_FREQ_PMAC64=y
+# CONFIG_WANT_EARLY_SERIAL is not set
+CONFIG_MPIC=y
+
+#
+# Cell Broadband Engine options
+#
+CONFIG_SPU_FS=m
+CONFIG_SPU_BASE=y
+CONFIG_SPUFS_MMAP=y
+CONFIG_CBE_RAS=y
+
+#
+# Kernel options
+#
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
+# CONFIG_PREEMPT_NONE is not set
+CONFIG_PREEMPT_VOLUNTARY=y
+# CONFIG_PREEMPT is not set
+CONFIG_PREEMPT_BKL=y
+CONFIG_BINFMT_ELF=y
+CONFIG_BINFMT_MISC=y
+CONFIG_FORCE_MAX_ZONEORDER=9
+CONFIG_IOMMU_VMERGE=y
+CONFIG_HOTPLUG_CPU=y
+CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
+CONFIG_KEXEC=y
+CONFIG_CRASH_DUMP=y
+CONFIG_IRQ_ALL_CPUS=y
+CONFIG_PPC_SPLPAR=y
+CONFIG_EEH=y
+CONFIG_SCANLOG=y
+CONFIG_LPARCFG=y
+CONFIG_NUMA=y
+CONFIG_NODES_SHIFT=4
+CONFIG_ARCH_SELECT_MEMORY_MODEL=y
+CONFIG_ARCH_SPARSEMEM_ENABLE=y
+CONFIG_ARCH_SPARSEMEM_DEFAULT=y
+CONFIG_SELECT_MEMORY_MODEL=y
+# CONFIG_FLATMEM_MANUAL is not set
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+CONFIG_SPARSEMEM_MANUAL=y
+CONFIG_SPARSEMEM=y
+CONFIG_NEED_MULTIPLE_NODES=y
+CONFIG_HAVE_MEMORY_PRESENT=y
+# CONFIG_SPARSEMEM_STATIC is not set
+CONFIG_SPARSEMEM_EXTREME=y
+CONFIG_MEMORY_HOTPLUG=y
+CONFIG_SPLIT_PTLOCK_CPUS=4
+CONFIG_MIGRATION=y
+CONFIG_RESOURCES_64BIT=y
+CONFIG_HAVE_ARCH_EARLY_PFN_TO_NID=y
+CONFIG_ARCH_MEMORY_PROBE=y
+CONFIG_NODES_SPAN_OTHER_NODES=y
+CONFIG_PPC_64K_PAGES=y
+CONFIG_SCHED_SMT=y
+CONFIG_PROC_DEVICETREE=y
+# CONFIG_CMDLINE_BOOL is not set
+CONFIG_PM=y
+CONFIG_PM_LEGACY=y
+# CONFIG_PM_DEBUG is not set
+# CONFIG_SECCOMP is not set
+CONFIG_ISA_DMA_API=y
+
+#
+# Bus options
+#
+CONFIG_GENERIC_ISA_DMA=y
+# CONFIG_MPIC_WEIRD is not set
+CONFIG_PPC_I8259=y
+# CONFIG_PPC_INDIRECT_PCI is not set
+CONFIG_PCI=y
+CONFIG_PCI_DOMAINS=y
+CONFIG_PCIEPORTBUS=y
+# CONFIG_HOTPLUG_PCI_PCIE is not set
+# CONFIG_PCI_DEBUG is not set
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+CONFIG_PCCARD=y
+# CONFIG_PCMCIA_DEBUG is not set
+CONFIG_PCMCIA=y
+CONFIG_PCMCIA_LOAD_CIS=y
+CONFIG_PCMCIA_IOCTL=y
+CONFIG_CARDBUS=y
+
+#
+# PC-card bridges
+#
+CONFIG_YENTA=y
+CONFIG_YENTA_O2=y
+CONFIG_YENTA_RICOH=y
+CONFIG_YENTA_TI=y
+CONFIG_YENTA_ENE_TUNE=y
+CONFIG_YENTA_TOSHIBA=y
+CONFIG_PD6729=m
+CONFIG_I82092=m
+CONFIG_PCCARD_NONSTATIC=y
+
+#
+# PCI Hotplug Support
+#
+CONFIG_HOTPLUG_PCI=y
+CONFIG_HOTPLUG_PCI_FAKE=m
+# CONFIG_HOTPLUG_PCI_CPCI is not set
+CONFIG_HOTPLUG_PCI_SHPC=m
+CONFIG_HOTPLUG_PCI_SHPC_POLL_EVENT_MODE=y
+CONFIG_HOTPLUG_PCI_RPA=m
+CONFIG_HOTPLUG_PCI_RPA_DLPAR=m
+CONFIG_KERNEL_START=0xc000000000000000
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+# CONFIG_NETDEBUG is not set
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=y
+CONFIG_NET_KEY=m
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_ASK_IP_FIB_HASH=y
+# 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
+# CONFIG_IP_PNP is not set
+CONFIG_NET_IPIP=m
+CONFIG_NET_IPGRE=m
+CONFIG_NET_IPGRE_BROADCAST=y
+CONFIG_IP_MROUTE=y
+CONFIG_IP_PIMSM_V1=y
+CONFIG_IP_PIMSM_V2=y
+# CONFIG_ARPD is not set
+CONFIG_SYN_COOKIES=y
+CONFIG_INET_AH=m
+CONFIG_INET_ESP=m
+CONFIG_INET_IPCOMP=m
+CONFIG_INET_XFRM_TUNNEL=m
+CONFIG_INET_TUNNEL=m
+CONFIG_INET_XFRM_MODE_TRANSPORT=m
+CONFIG_INET_XFRM_MODE_TUNNEL=m
+CONFIG_INET_DIAG=m
+CONFIG_INET_TCP_DIAG=m
+CONFIG_TCP_CONG_ADVANCED=y
+
+#
+# TCP congestion control
+#
+CONFIG_TCP_CONG_BIC=y
+CONFIG_TCP_CONG_CUBIC=m
+CONFIG_TCP_CONG_WESTWOOD=m
+CONFIG_TCP_CONG_HTCP=m
+CONFIG_TCP_CONG_HSTCP=m
+CONFIG_TCP_CONG_HYBLA=m
+CONFIG_TCP_CONG_VEGAS=m
+CONFIG_TCP_CONG_SCALABLE=m
+CONFIG_TCP_CONG_LP=m
+CONFIG_TCP_CONG_VENO=m
+
+#
+# IP: Virtual Server Configuration
+#
+CONFIG_IP_VS=m
+# CONFIG_IP_VS_DEBUG is not set
+CONFIG_IP_VS_TAB_BITS=12
+
+#
+# IPVS transport protocol load balancing support
+#
+CONFIG_IP_VS_PROTO_TCP=y
+CONFIG_IP_VS_PROTO_UDP=y
+CONFIG_IP_VS_PROTO_ESP=y
+CONFIG_IP_VS_PROTO_AH=y
+
+#
+# IPVS scheduler
+#
+CONFIG_IP_VS_RR=m
+CONFIG_IP_VS_WRR=m
+CONFIG_IP_VS_LC=m
+CONFIG_IP_VS_WLC=m
+CONFIG_IP_VS_LBLC=m
+CONFIG_IP_VS_LBLCR=m
+CONFIG_IP_VS_DH=m
+CONFIG_IP_VS_SH=m
+CONFIG_IP_VS_SED=m
+CONFIG_IP_VS_NQ=m
+
+#
+# IPVS application helper
+#
+CONFIG_IP_VS_FTP=m
+CONFIG_IPV6=m
+CONFIG_IPV6_PRIVACY=y
+CONFIG_IPV6_ROUTER_PREF=y
+CONFIG_IPV6_ROUTE_INFO=y
+CONFIG_INET6_AH=m
+CONFIG_INET6_ESP=m
+CONFIG_INET6_IPCOMP=m
+CONFIG_INET6_XFRM_TUNNEL=m
+CONFIG_INET6_TUNNEL=m
+CONFIG_INET6_XFRM_MODE_TRANSPORT=m
+CONFIG_INET6_XFRM_MODE_TUNNEL=m
+CONFIG_IPV6_TUNNEL=m
+CONFIG_NETWORK_SECMARK=y
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_DEBUG is not set
+CONFIG_BRIDGE_NETFILTER=y
+
+#
+# Core Netfilter Configuration
+#
+CONFIG_NETFILTER_NETLINK=m
+CONFIG_NETFILTER_NETLINK_QUEUE=m
+CONFIG_NETFILTER_NETLINK_LOG=m
+CONFIG_NETFILTER_XTABLES=m
+CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
+CONFIG_NETFILTER_XT_TARGET_CONNMARK=m
+CONFIG_NETFILTER_XT_TARGET_MARK=m
+CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
+CONFIG_NETFILTER_XT_TARGET_NOTRACK=m
+CONFIG_NETFILTER_XT_TARGET_SECMARK=m
+CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=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_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_PHYSDEV=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
+
+#
+# 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=m
+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_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_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_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
+CONFIG_IP_NF_ARPTABLES=m
+CONFIG_IP_NF_ARPFILTER=m
+CONFIG_IP_NF_ARP_MANGLE=m
+
+#
+# IPv6: Netfilter Configuration (EXPERIMENTAL)
+#
+CONFIG_IP6_NF_QUEUE=m
+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_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
+
+#
+# DECnet: Netfilter Configuration
+#
+# CONFIG_DECNET_NF_GRABULATOR is not set
+
+#
+# Bridge: Netfilter Configuration
+#
+CONFIG_BRIDGE_NF_EBTABLES=m
+CONFIG_BRIDGE_EBT_BROUTE=m
+CONFIG_BRIDGE_EBT_T_FILTER=m
+CONFIG_BRIDGE_EBT_T_NAT=m
+CONFIG_BRIDGE_EBT_802_3=m
+CONFIG_BRIDGE_EBT_AMONG=m
+CONFIG_BRIDGE_EBT_ARP=m
+CONFIG_BRIDGE_EBT_IP=m
+CONFIG_BRIDGE_EBT_LIMIT=m
+CONFIG_BRIDGE_EBT_MARK=m
+CONFIG_BRIDGE_EBT_PKTTYPE=m
+CONFIG_BRIDGE_EBT_STP=m
+CONFIG_BRIDGE_EBT_VLAN=m
+CONFIG_BRIDGE_EBT_ARPREPLY=m
+CONFIG_BRIDGE_EBT_DNAT=m
+CONFIG_BRIDGE_EBT_MARK_T=m
+CONFIG_BRIDGE_EBT_REDIRECT=m
+CONFIG_BRIDGE_EBT_SNAT=m
+CONFIG_BRIDGE_EBT_LOG=m
+CONFIG_BRIDGE_EBT_ULOG=m
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+CONFIG_IP_DCCP=m
+CONFIG_INET_DCCP_DIAG=m
+CONFIG_IP_DCCP_ACKVEC=y
+
+#
+# DCCP CCIDs Configuration (EXPERIMENTAL)
+#
+CONFIG_IP_DCCP_CCID2=m
+CONFIG_IP_DCCP_CCID3=m
+CONFIG_IP_DCCP_TFRC_LIB=m
+
+#
+# DCCP Kernel Hacking
+#
+# CONFIG_IP_DCCP_DEBUG is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+CONFIG_IP_SCTP=m
+# CONFIG_SCTP_DBG_MSG is not set
+# CONFIG_SCTP_DBG_OBJCNT is not set
+# CONFIG_SCTP_HMAC_NONE is not set
+# CONFIG_SCTP_HMAC_SHA1 is not set
+CONFIG_SCTP_HMAC_MD5=y
+
+#
+# TIPC Configuration (EXPERIMENTAL)
+#
+CONFIG_TIPC=m
+# CONFIG_TIPC_ADVANCED is not set
+# CONFIG_TIPC_DEBUG is not set
+CONFIG_ATM=m
+CONFIG_ATM_CLIP=m
+# CONFIG_ATM_CLIP_NO_ICMP is not set
+CONFIG_ATM_LANE=m
+# CONFIG_ATM_MPOA is not set
+CONFIG_ATM_BR2684=m
+# CONFIG_ATM_BR2684_IPFILTER is not set
+CONFIG_BRIDGE=m
+CONFIG_VLAN_8021Q=m
+CONFIG_DECNET=m
+CONFIG_DECNET_ROUTER=y
+CONFIG_DECNET_ROUTE_FWMARK=y
+CONFIG_LLC=y
+# CONFIG_LLC2 is not set
+CONFIG_IPX=m
+# CONFIG_IPX_INTERN is not set
+CONFIG_ATALK=m
+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_ECONET is not set
+CONFIG_WAN_ROUTER=m
+
+#
+# QoS and/or fair queueing
+#
+CONFIG_NET_SCHED=y
+# CONFIG_NET_SCH_CLK_JIFFIES is not set
+CONFIG_NET_SCH_CLK_GETTIMEOFDAY=y
+# CONFIG_NET_SCH_CLK_CPU is not set
+
+#
+# Queueing/Scheduling
+#
+CONFIG_NET_SCH_CBQ=m
+CONFIG_NET_SCH_HTB=m
+CONFIG_NET_SCH_HFSC=m
+CONFIG_NET_SCH_ATM=m
+CONFIG_NET_SCH_PRIO=m
+CONFIG_NET_SCH_RED=m
+CONFIG_NET_SCH_SFQ=m
+CONFIG_NET_SCH_TEQL=m
+CONFIG_NET_SCH_TBF=m
+CONFIG_NET_SCH_GRED=m
+CONFIG_NET_SCH_DSMARK=m
+CONFIG_NET_SCH_NETEM=m
+CONFIG_NET_SCH_INGRESS=m
+
+#
+# Classification
+#
+CONFIG_NET_CLS=y
+CONFIG_NET_CLS_BASIC=m
+CONFIG_NET_CLS_TCINDEX=m
+CONFIG_NET_CLS_ROUTE4=m
+CONFIG_NET_CLS_ROUTE=y
+CONFIG_NET_CLS_FW=m
+CONFIG_NET_CLS_U32=m
+CONFIG_CLS_U32_PERF=y
+CONFIG_CLS_U32_MARK=y
+CONFIG_NET_CLS_RSVP=m
+CONFIG_NET_CLS_RSVP6=m
+CONFIG_NET_EMATCH=y
+CONFIG_NET_EMATCH_STACK=32
+CONFIG_NET_EMATCH_CMP=m
+CONFIG_NET_EMATCH_NBYTE=m
+CONFIG_NET_EMATCH_U32=m
+CONFIG_NET_EMATCH_META=m
+CONFIG_NET_EMATCH_TEXT=m
+CONFIG_NET_CLS_ACT=y
+CONFIG_NET_ACT_POLICE=m
+CONFIG_NET_ACT_GACT=m
+CONFIG_GACT_PROB=y
+CONFIG_NET_ACT_MIRRED=m
+CONFIG_NET_ACT_IPT=m
+CONFIG_NET_ACT_PEDIT=m
+CONFIG_NET_ACT_SIMP=m
+CONFIG_NET_CLS_IND=y
+CONFIG_NET_ESTIMATOR=y
+
+#
+# Network testing
+#
+CONFIG_NET_PKTGEN=m
+# CONFIG_NET_TCPPROBE is not set
+# CONFIG_HAMRADIO is not set
+CONFIG_IRDA=m
+
+#
+# IrDA protocols
+#
+CONFIG_IRLAN=m
+CONFIG_IRNET=m
+CONFIG_IRCOMM=m
+# CONFIG_IRDA_ULTRA is not set
+
+#
+# IrDA options
+#
+CONFIG_IRDA_CACHE_LAST_LSAP=y
+CONFIG_IRDA_FAST_RR=y
+# CONFIG_IRDA_DEBUG is not set
+
+#
+# Infrared-port device drivers
+#
+
+#
+# SIR device drivers
+#
+CONFIG_IRTTY_SIR=m
+
+#
+# Dongle support
+#
+CONFIG_DONGLE=y
+CONFIG_ESI_DONGLE=m
+CONFIG_ACTISYS_DONGLE=m
+CONFIG_TEKRAM_DONGLE=m
+CONFIG_TOIM3232_DONGLE=m
+CONFIG_LITELINK_DONGLE=m
+CONFIG_MA600_DONGLE=m
+CONFIG_GIRBIL_DONGLE=m
+CONFIG_MCP2120_DONGLE=m
+CONFIG_OLD_BELKIN_DONGLE=m
+CONFIG_ACT200L_DONGLE=m
+
+#
+# Old SIR device drivers
+#
+
+#
+# Old Serial dongle support
+#
+
+#
+# FIR device drivers
+#
+CONFIG_USB_IRDA=m
+CONFIG_SIGMATEL_FIR=m
+CONFIG_NSC_FIR=m
+CONFIG_WINBOND_FIR=m
+CONFIG_SMC_IRCC_FIR=m
+CONFIG_ALI_FIR=m
+CONFIG_VLSI_FIR=m
+CONFIG_VIA_FIR=m
+CONFIG_MCS_FIR=m
+CONFIG_BT=m
+CONFIG_BT_L2CAP=m
+CONFIG_BT_SCO=m
+CONFIG_BT_RFCOMM=m
+CONFIG_BT_RFCOMM_TTY=y
+CONFIG_BT_BNEP=m
+CONFIG_BT_BNEP_MC_FILTER=y
+CONFIG_BT_BNEP_PROTO_FILTER=y
+CONFIG_BT_CMTP=m
+CONFIG_BT_HIDP=m
+
+#
+# Bluetooth device drivers
+#
+CONFIG_BT_HCIUSB=m
+CONFIG_BT_HCIUSB_SCO=y
+CONFIG_BT_HCIUART=m
+CONFIG_BT_HCIUART_H4=y
+CONFIG_BT_HCIUART_BCSP=y
+CONFIG_BT_HCIBCM203X=m
+CONFIG_BT_HCIBPA10X=m
+CONFIG_BT_HCIBFUSB=m
+CONFIG_BT_HCIDTL1=m
+CONFIG_BT_HCIBT3C=m
+CONFIG_BT_HCIBLUECARD=m
+CONFIG_BT_HCIBTUART=m
+CONFIG_BT_HCIVHCI=m
+CONFIG_IEEE80211=m
+CONFIG_IEEE80211_DEBUG=y
+CONFIG_IEEE80211_CRYPT_WEP=m
+CONFIG_IEEE80211_CRYPT_CCMP=m
+CONFIG_IEEE80211_CRYPT_TKIP=m
+CONFIG_IEEE80211_SOFTMAC=m
+CONFIG_IEEE80211_SOFTMAC_DEBUG=y
+CONFIG_TUX=m
+
+#
+# TUX options
+#
+CONFIG_TUX_EXTCGI=y
+CONFIG_TUX_EXTENDED_LOG=y
+# CONFIG_TUX_DEBUG is not set
+CONFIG_WIRELESS_EXT=y
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_SYS_HYPERVISOR is not set
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+CONFIG_CONNECTOR=y
+CONFIG_PROC_EVENTS=y
+
+#
+# Memory Technology Devices (MTD)
+#
+CONFIG_MTD=m
+# CONFIG_MTD_DEBUG is not set
+CONFIG_MTD_CONCAT=m
+CONFIG_MTD_PARTITIONS=y
+CONFIG_MTD_REDBOOT_PARTS=m
+CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1
+# CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED is not set
+# CONFIG_MTD_REDBOOT_PARTS_READONLY is not set
+CONFIG_MTD_CMDLINE_PARTS=y
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=m
+CONFIG_MTD_BLOCK=m
+CONFIG_MTD_BLOCK_RO=m
+CONFIG_FTL=m
+CONFIG_NFTL=m
+CONFIG_NFTL_RW=y
+CONFIG_INFTL=m
+CONFIG_RFD_FTL=m
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=m
+CONFIG_MTD_JEDECPROBE=m
+CONFIG_MTD_GEN_PROBE=m
+# CONFIG_MTD_CFI_ADV_OPTIONS 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_CFI_INTELEXT=m
+CONFIG_MTD_CFI_AMDSTD=m
+CONFIG_MTD_CFI_STAA=m
+CONFIG_MTD_CFI_UTIL=m
+CONFIG_MTD_RAM=m
+CONFIG_MTD_ROM=m
+CONFIG_MTD_ABSENT=m
+# CONFIG_MTD_OBSOLETE_CHIPS is not set
+
+#
+# Mapping drivers for chip access
+#
+CONFIG_MTD_COMPLEX_MAPPINGS=y
+# CONFIG_MTD_PHYSMAP is not set
+CONFIG_MTD_PCI=m
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+CONFIG_MTD_PMC551=m
+# CONFIG_MTD_PMC551_BUGFIX is not set
+# CONFIG_MTD_PMC551_DEBUG is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+CONFIG_MTD_MTDRAM=m
+CONFIG_MTDRAM_TOTAL_SIZE=4096
+CONFIG_MTDRAM_ERASE_SIZE=128
+CONFIG_MTD_BLOCK2MTD=m
+
+#
+# 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=m
+# CONFIG_MTD_NAND_VERIFY_WRITE is not set
+CONFIG_MTD_NAND_ECC_SMC=y
+CONFIG_MTD_NAND_IDS=m
+CONFIG_MTD_NAND_DISKONCHIP=m
+# CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADVANCED is not set
+CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADDRESS=0
+# CONFIG_MTD_NAND_DISKONCHIP_BBTWRITE is not set
+CONFIG_MTD_NAND_NANDSIM=m
+
+#
+# OneNAND Flash Device Drivers
+#
+# CONFIG_MTD_ONENAND is not set
+
+#
+# Parallel port support
+#
+CONFIG_PARPORT=m
+CONFIG_PARPORT_PC=m
+CONFIG_PARPORT_SERIAL=m
+# CONFIG_PARPORT_PC_FIFO is not set
+# CONFIG_PARPORT_PC_SUPERIO is not set
+CONFIG_PARPORT_PC_PCMCIA=m
+CONFIG_PARPORT_NOT_PC=y
+# CONFIG_PARPORT_GSC is not set
+# CONFIG_PARPORT_AX88796 is not set
+CONFIG_PARPORT_1284=y
+
+#
+# Plug and Play support
+#
+
+#
+# Block devices
+#
+CONFIG_BLK_DEV_FD=m
+CONFIG_PARIDE=m
+CONFIG_PARIDE_PARPORT=m
+
+#
+# Parallel IDE high-level drivers
+#
+CONFIG_PARIDE_PD=m
+CONFIG_PARIDE_PCD=m
+CONFIG_PARIDE_PF=m
+CONFIG_PARIDE_PT=m
+CONFIG_PARIDE_PG=m
+
+#
+# Parallel IDE protocol modules
+#
+CONFIG_PARIDE_ATEN=m
+CONFIG_PARIDE_BPCK=m
+CONFIG_PARIDE_COMM=m
+CONFIG_PARIDE_DSTR=m
+CONFIG_PARIDE_FIT2=m
+CONFIG_PARIDE_FIT3=m
+CONFIG_PARIDE_EPAT=m
+CONFIG_PARIDE_EPATC8=y
+CONFIG_PARIDE_EPIA=m
+CONFIG_PARIDE_FRIQ=m
+CONFIG_PARIDE_FRPW=m
+CONFIG_PARIDE_KBIC=m
+CONFIG_PARIDE_KTTI=m
+CONFIG_PARIDE_ON20=m
+CONFIG_PARIDE_ON26=m
+# CONFIG_BLK_CPQ_DA is not set
+CONFIG_BLK_CPQ_CISS_DA=m
+CONFIG_CISS_SCSI_TAPE=y
+CONFIG_BLK_DEV_DAC960=m
+CONFIG_BLK_DEV_UMEM=m
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=m
+CONFIG_BLK_DEV_CRYPTOLOOP=m
+CONFIG_BLK_DEV_NBD=m
+CONFIG_BLK_DEV_SX8=m
+CONFIG_BLK_DEV_UB=m
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=16384
+CONFIG_BLK_DEV_RAM_BLOCKSIZE=4096
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_CDROM_PKTCDVD=m
+CONFIG_CDROM_PKTCDVD_BUFFERS=8
+# CONFIG_CDROM_PKTCDVD_WCACHE is not set
+CONFIG_ATA_OVER_ETH=m
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+CONFIG_IDE=y
+CONFIG_BLK_DEV_IDE=y
+
+#
+# Please see Documentation/ide.txt for help/info on IDE drives
+#
+# CONFIG_BLK_DEV_IDE_SATA is not set
+CONFIG_BLK_DEV_IDEDISK=y
+CONFIG_IDEDISK_MULTI_MODE=y
+CONFIG_BLK_DEV_IDECS=m
+CONFIG_BLK_DEV_IDECD=m
+# CONFIG_BLK_DEV_IDETAPE is not set
+CONFIG_BLK_DEV_IDEFLOPPY=y
+CONFIG_BLK_DEV_IDESCSI=m
+CONFIG_IDE_TASK_IOCTL=y
+
+#
+# IDE chipset support/bugfixes
+#
+CONFIG_IDE_GENERIC=y
+CONFIG_BLK_DEV_IDEPCI=y
+CONFIG_IDEPCI_SHARE_IRQ=y
+# CONFIG_BLK_DEV_OFFBOARD is not set
+CONFIG_BLK_DEV_GENERIC=y
+# CONFIG_BLK_DEV_OPTI621 is not set
+CONFIG_BLK_DEV_SL82C105=y
+CONFIG_BLK_DEV_IDEDMA_PCI=y
+# CONFIG_BLK_DEV_IDEDMA_FORCED is not set
+CONFIG_IDEDMA_PCI_AUTO=y
+# CONFIG_IDEDMA_ONLYDISK is not set
+CONFIG_BLK_DEV_AEC62XX=y
+CONFIG_BLK_DEV_ALI15X3=y
+# CONFIG_WDC_ALI15X3 is not set
+CONFIG_BLK_DEV_AMD74XX=y
+CONFIG_BLK_DEV_CMD64X=y
+CONFIG_BLK_DEV_TRIFLEX=y
+# CONFIG_BLK_DEV_CY82C693 is not set
+CONFIG_BLK_DEV_CS5520=y
+CONFIG_BLK_DEV_CS5530=y
+CONFIG_BLK_DEV_HPT34X=y
+# CONFIG_HPT34X_AUTODMA is not set
+CONFIG_BLK_DEV_HPT366=y
+# CONFIG_BLK_DEV_SC1200 is not set
+CONFIG_BLK_DEV_PIIX=y
+CONFIG_BLK_DEV_IT821X=y
+# CONFIG_BLK_DEV_NS87415 is not set
+CONFIG_BLK_DEV_PDC202XX_OLD=y
+# CONFIG_PDC202XX_BURST is not set
+CONFIG_BLK_DEV_PDC202XX_NEW=y
+CONFIG_BLK_DEV_SVWKS=y
+CONFIG_BLK_DEV_SIIMAGE=y
+# CONFIG_BLK_DEV_SLC90E66 is not set
+# CONFIG_BLK_DEV_TRM290 is not set
+CONFIG_BLK_DEV_VIA82CXXX=y
+CONFIG_BLK_DEV_IDE_PMAC=y
+CONFIG_BLK_DEV_IDE_PMAC_ATA100FIRST=y
+CONFIG_BLK_DEV_IDEDMA_PMAC=y
+# CONFIG_IDE_ARM is not set
+CONFIG_BLK_DEV_IDEDMA=y
+# CONFIG_IDEDMA_IVB is not set
+CONFIG_IDEDMA_AUTO=y
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# SCSI device support
+#
+CONFIG_RAID_ATTRS=m
+CONFIG_SCSI=m
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=m
+CONFIG_CHR_DEV_ST=m
+CONFIG_CHR_DEV_OSST=m
+CONFIG_BLK_DEV_SR=m
+CONFIG_BLK_DEV_SR_VENDOR=y
+CONFIG_CHR_DEV_SG=m
+CONFIG_CHR_DEV_SCH=m
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+CONFIG_SCSI_MULTI_LUN=y
+CONFIG_SCSI_CONSTANTS=y
+CONFIG_SCSI_LOGGING=y
+
+#
+# SCSI Transport Attributes
+#
+CONFIG_SCSI_SPI_ATTRS=m
+CONFIG_SCSI_FC_ATTRS=m
+CONFIG_SCSI_ISCSI_ATTRS=m
+CONFIG_SCSI_SAS_ATTRS=m
+
+#
+# SCSI low-level drivers
+#
+CONFIG_ISCSI_TCP=m
+CONFIG_BLK_DEV_3W_XXXX_RAID=m
+CONFIG_SCSI_3W_9XXX=m
+CONFIG_SCSI_ACARD=m
+CONFIG_SCSI_AACRAID=m
+CONFIG_SCSI_AIC7XXX=m
+CONFIG_AIC7XXX_CMDS_PER_DEVICE=4
+CONFIG_AIC7XXX_RESET_DELAY_MS=15000
+# CONFIG_AIC7XXX_DEBUG_ENABLE is not set
+CONFIG_AIC7XXX_DEBUG_MASK=0
+# CONFIG_AIC7XXX_REG_PRETTY_PRINT is not set
+CONFIG_SCSI_AIC7XXX_OLD=m
+CONFIG_SCSI_AIC79XX=m
+CONFIG_AIC79XX_CMDS_PER_DEVICE=4
+CONFIG_AIC79XX_RESET_DELAY_MS=15000
+# CONFIG_AIC79XX_ENABLE_RD_STRM is not set
+# CONFIG_AIC79XX_DEBUG_ENABLE is not set
+CONFIG_AIC79XX_DEBUG_MASK=0
+# CONFIG_AIC79XX_REG_PRETTY_PRINT is not set
+CONFIG_MEGARAID_NEWGEN=y
+CONFIG_MEGARAID_MM=m
+CONFIG_MEGARAID_MAILBOX=m
+CONFIG_MEGARAID_LEGACY=m
+CONFIG_MEGARAID_SAS=m
+CONFIG_SCSI_SATA=m
+CONFIG_SCSI_SATA_AHCI=m
+CONFIG_SCSI_SATA_SVW=m
+CONFIG_SCSI_ATA_PIIX=m
+CONFIG_SCSI_SATA_MV=m
+CONFIG_SCSI_SATA_NV=m
+CONFIG_SCSI_PDC_ADMA=m
+CONFIG_SCSI_HPTIOP=m
+CONFIG_SCSI_SATA_QSTOR=m
+CONFIG_SCSI_SATA_PROMISE=m
+CONFIG_SCSI_SATA_SX4=m
+CONFIG_SCSI_SATA_SIL=m
+CONFIG_SCSI_SATA_SIL24=m
+CONFIG_SCSI_SATA_SIS=m
+CONFIG_SCSI_SATA_ULI=m
+CONFIG_SCSI_SATA_VIA=m
+CONFIG_SCSI_SATA_VITESSE=m
+CONFIG_SCSI_SATA_INTEL_COMBINED=y
+# CONFIG_SCSI_BUSLOGIC is not set
+# CONFIG_SCSI_DMX3191D is not set
+# CONFIG_SCSI_EATA is not set
+# CONFIG_SCSI_FUTURE_DOMAIN is not set
+CONFIG_SCSI_GDTH=m
+CONFIG_SCSI_IPS=m
+CONFIG_SCSI_IBMVSCSI=m
+CONFIG_SCSI_INITIO=m
+CONFIG_SCSI_INIA100=m
+CONFIG_SCSI_PPA=m
+CONFIG_SCSI_IMM=m
+# CONFIG_SCSI_IZIP_EPP16 is not set
+# CONFIG_SCSI_IZIP_SLOW_CTR is not set
+CONFIG_SCSI_SYM53C8XX_2=m
+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=m
+CONFIG_SCSI_IPR_TRACE=y
+CONFIG_SCSI_IPR_DUMP=y
+CONFIG_SCSI_QLOGIC_1280=m
+CONFIG_SCSI_QLA_FC=m
+CONFIG_SCSI_LPFC=m
+CONFIG_SCSI_DC395x=m
+# CONFIG_SCSI_DC390T is not set
+# CONFIG_SCSI_DEBUG is not set
+
+#
+# PCMCIA SCSI adapter support
+#
+# CONFIG_PCMCIA_FDOMAIN is not set
+CONFIG_PCMCIA_QLOGIC=m
+CONFIG_PCMCIA_SYM53C500=m
+
+#
+# Multi-device support (RAID and LVM)
+#
+CONFIG_MD=y
+CONFIG_BLK_DEV_MD=y
+CONFIG_MD_LINEAR=m
+CONFIG_MD_RAID0=m
+CONFIG_MD_RAID1=m
+CONFIG_MD_RAID10=m
+CONFIG_MD_RAID456=m
+CONFIG_MD_RAID5_RESHAPE=y
+CONFIG_MD_MULTIPATH=m
+CONFIG_MD_FAULTY=m
+CONFIG_BLK_DEV_DM=m
+CONFIG_DM_CRYPT=m
+CONFIG_DM_SNAPSHOT=m
+CONFIG_DM_MIRROR=m
+CONFIG_DM_ZERO=m
+CONFIG_DM_MULTIPATH=m
+CONFIG_DM_MULTIPATH_EMC=m
+
+#
+# Fusion MPT device support
+#
+CONFIG_FUSION=y
+CONFIG_FUSION_SPI=m
+CONFIG_FUSION_FC=m
+CONFIG_FUSION_SAS=m
+CONFIG_FUSION_MAX_SGE=40
+CONFIG_FUSION_CTL=m
+CONFIG_FUSION_LAN=m
+
+#
+# IEEE 1394 (FireWire) support
+#
+CONFIG_IEEE1394=m
+
+#
+# Subsystem Options
+#
+# CONFIG_IEEE1394_VERBOSEDEBUG is not set
+CONFIG_IEEE1394_OUI_DB=y
+CONFIG_IEEE1394_EXTRA_CONFIG_ROMS=y
+CONFIG_IEEE1394_CONFIG_ROM_IP1394=y
+# CONFIG_IEEE1394_EXPORT_FULL_API is not set
+
+#
+# Device Drivers
+#
+CONFIG_IEEE1394_PCILYNX=m
+CONFIG_IEEE1394_OHCI1394=m
+
+#
+# Protocol Drivers
+#
+CONFIG_IEEE1394_VIDEO1394=m
+CONFIG_IEEE1394_SBP2=m
+CONFIG_IEEE1394_ETH1394=m
+CONFIG_IEEE1394_DV1394=m
+CONFIG_IEEE1394_RAWIO=m
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+
+#
+# Macintosh device drivers
+#
+CONFIG_ADB_PMU=y
+CONFIG_ADB_PMU_LED=y
+CONFIG_ADB_PMU_LED_IDE=y
+CONFIG_PMAC_SMU=y
+CONFIG_THERM_PM72=y
+CONFIG_WINDFARM=y
+CONFIG_WINDFARM_PM81=y
+CONFIG_WINDFARM_PM91=y
+CONFIG_WINDFARM_PM112=y
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+CONFIG_IFB=m
+CONFIG_DUMMY=m
+CONFIG_BONDING=m
+CONFIG_EQUALIZER=m
+CONFIG_TUN=m
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+
+#
+# PHY device support
+#
+CONFIG_PHYLIB=m
+
+#
+# MII PHY device drivers
+#
+CONFIG_MARVELL_PHY=m
+CONFIG_DAVICOM_PHY=m
+CONFIG_QSEMI_PHY=m
+CONFIG_LXT_PHY=m
+CONFIG_CICADA_PHY=m
+CONFIG_VITESSE_PHY=m
+CONFIG_SMSC_PHY=m
+CONFIG_FIXED_PHY=m
+CONFIG_FIXED_MII_10_FDX=y
+CONFIG_FIXED_MII_100_FDX=y
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=m
+CONFIG_HAPPYMEAL=m
+CONFIG_SUNGEM=m
+CONFIG_CASSINI=m
+CONFIG_NET_VENDOR_3COM=y
+CONFIG_VORTEX=m
+CONFIG_TYPHOON=m
+
+#
+# Tulip family network device support
+#
+CONFIG_NET_TULIP=y
+CONFIG_DE2104X=m
+CONFIG_TULIP=m
+# CONFIG_TULIP_MWI is not set
+CONFIG_TULIP_MMIO=y
+# CONFIG_TULIP_NAPI is not set
+CONFIG_DE4X5=m
+CONFIG_WINBOND_840=m
+CONFIG_DM9102=m
+CONFIG_ULI526X=m
+CONFIG_PCMCIA_XIRCOM=m
+# CONFIG_HP100 is not set
+CONFIG_IBMVETH=m
+CONFIG_NET_PCI=y
+CONFIG_PCNET32=m
+CONFIG_AMD8111_ETH=m
+CONFIG_AMD8111E_NAPI=y
+CONFIG_ADAPTEC_STARFIRE=m
+CONFIG_ADAPTEC_STARFIRE_NAPI=y
+CONFIG_B44=m
+CONFIG_FORCEDETH=m
+# CONFIG_DGRS is not set
+# CONFIG_EEPRO100 is not set
+CONFIG_E100=m
+CONFIG_FEALNX=m
+CONFIG_NATSEMI=m
+CONFIG_NE2K_PCI=m
+CONFIG_8139CP=m
+CONFIG_8139TOO=m
+# CONFIG_8139TOO_PIO is not set
+# CONFIG_8139TOO_TUNE_TWISTER is not set
+CONFIG_8139TOO_8129=y
+# CONFIG_8139_OLD_RX_RESET is not set
+CONFIG_SIS900=m
+CONFIG_EPIC100=m
+CONFIG_SUNDANCE=m
+# CONFIG_SUNDANCE_MMIO is not set
+CONFIG_VIA_RHINE=m
+CONFIG_VIA_RHINE_MMIO=y
+CONFIG_VIA_RHINE_NAPI=y
+CONFIG_NET_POCKET=y
+CONFIG_DE600=m
+CONFIG_DE620=m
+
+#
+# Ethernet (1000 Mbit)
+#
+CONFIG_ACENIC=m
+# CONFIG_ACENIC_OMIT_TIGON_I is not set
+CONFIG_DL2K=m
+CONFIG_E1000=m
+CONFIG_E1000_NAPI=y
+# CONFIG_E1000_DISABLE_PACKET_SPLIT is not set
+CONFIG_NS83820=m
+CONFIG_HAMACHI=m
+CONFIG_YELLOWFIN=m
+CONFIG_R8169=m
+CONFIG_R8169_NAPI=y
+CONFIG_R8169_VLAN=y
+CONFIG_SIS190=m
+CONFIG_SKGE=m
+CONFIG_SKY2=m
+# CONFIG_SK98LIN is not set
+CONFIG_VIA_VELOCITY=m
+CONFIG_TIGON3=m
+CONFIG_BNX2=m
+CONFIG_SPIDER_NET=m
+# CONFIG_MV643XX_ETH is not set
+
+#
+# Ethernet (10000 Mbit)
+#
+CONFIG_CHELSIO_T1=m
+CONFIG_IXGB=m
+CONFIG_IXGB_NAPI=y
+CONFIG_S2IO=m
+CONFIG_S2IO_NAPI=y
+CONFIG_MYRI10GE=m
+
+#
+# Token Ring devices
+#
+CONFIG_TR=y
+CONFIG_IBMOL=m
+CONFIG_3C359=m
+# CONFIG_TMS380TR is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+CONFIG_NET_RADIO=y
+CONFIG_NET_WIRELESS_RTNETLINK=y
+
+#
+# Obsolete Wireless cards support (pre-802.11)
+#
+# CONFIG_STRIP is not set
+CONFIG_PCMCIA_WAVELAN=m
+CONFIG_PCMCIA_NETWAVE=m
+
+#
+# Wireless 802.11 Frequency Hopping cards support
+#
+# CONFIG_PCMCIA_RAYCS is not set
+
+#
+# Wireless 802.11b ISA/PCI cards support
+#
+# CONFIG_IPW2100 is not set
+# CONFIG_IPW2200 is not set
+CONFIG_AIRO=m
+CONFIG_HERMES=m
+CONFIG_APPLE_AIRPORT=m
+CONFIG_PLX_HERMES=m
+CONFIG_TMD_HERMES=m
+CONFIG_NORTEL_HERMES=m
+CONFIG_PCI_HERMES=m
+CONFIG_ATMEL=m
+CONFIG_PCI_ATMEL=m
+
+#
+# Wireless 802.11b Pcmcia/Cardbus cards support
+#
+CONFIG_PCMCIA_HERMES=m
+CONFIG_PCMCIA_SPECTRUM=m
+CONFIG_AIRO_CS=m
+CONFIG_PCMCIA_ATMEL=m
+CONFIG_PCMCIA_WL3501=m
+
+#
+# Prism GT/Duette 802.11(a/b/g) PCI/Cardbus support
+#
+CONFIG_PRISM54=m
+CONFIG_USB_ZD1201=m
+CONFIG_HOSTAP=m
+CONFIG_HOSTAP_FIRMWARE=y
+CONFIG_HOSTAP_FIRMWARE_NVRAM=y
+CONFIG_HOSTAP_PLX=m
+CONFIG_HOSTAP_PCI=m
+CONFIG_HOSTAP_CS=m
+CONFIG_BCM43XX=m
+CONFIG_BCM43XX_DEBUG=y
+CONFIG_BCM43XX_DMA=y
+CONFIG_BCM43XX_PIO=y
+CONFIG_BCM43XX_DMA_AND_PIO_MODE=y
+# CONFIG_BCM43XX_DMA_MODE is not set
+# CONFIG_BCM43XX_PIO_MODE is not set
+CONFIG_ZD1211RW=m
+# CONFIG_ZD1211RW_DEBUG is not set
+CONFIG_NET_WIRELESS=y
+
+#
+# PCMCIA network device support
+#
+CONFIG_NET_PCMCIA=y
+CONFIG_PCMCIA_3C589=m
+CONFIG_PCMCIA_3C574=m
+CONFIG_PCMCIA_FMVJ18X=m
+CONFIG_PCMCIA_PCNET=m
+CONFIG_PCMCIA_NMCLAN=m
+CONFIG_PCMCIA_SMC91C92=m
+CONFIG_PCMCIA_XIRC2PS=m
+CONFIG_PCMCIA_AXNET=m
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+
+#
+# ATM drivers
+#
+# CONFIG_ATM_DUMMY is not set
+CONFIG_ATM_TCP=m
+CONFIG_ATM_LANAI=m
+CONFIG_ATM_ENI=m
+# CONFIG_ATM_ENI_DEBUG is not set
+# CONFIG_ATM_ENI_TUNE_BURST is not set
+# CONFIG_ATM_FIRESTREAM is not set
+# CONFIG_ATM_ZATM is not set
+CONFIG_ATM_IDT77252=m
+# CONFIG_ATM_IDT77252_DEBUG is not set
+# CONFIG_ATM_IDT77252_RCV_ALL is not set
+CONFIG_ATM_IDT77252_USE_SUNI=y
+# CONFIG_ATM_AMBASSADOR is not set
+# CONFIG_ATM_HORIZON is not set
+CONFIG_ATM_FORE200E_MAYBE=m
+# CONFIG_ATM_FORE200E_PCA is not set
+CONFIG_ATM_HE=m
+# CONFIG_ATM_HE_USE_SUNI is not set
+CONFIG_FDDI=y
+# CONFIG_DEFXX is not set
+CONFIG_SKFP=m
+# CONFIG_HIPPI is not set
+CONFIG_PLIP=m
+CONFIG_PPP=m
+CONFIG_PPP_MULTILINK=y
+CONFIG_PPP_FILTER=y
+CONFIG_PPP_ASYNC=m
+CONFIG_PPP_SYNC_TTY=m
+CONFIG_PPP_DEFLATE=m
+# CONFIG_PPP_BSDCOMP is not set
+CONFIG_PPP_MPPE=m
+CONFIG_PPPOE=m
+CONFIG_PPPOATM=m
+CONFIG_SLIP=m
+CONFIG_SLIP_COMPRESSED=y
+CONFIG_SLIP_SMART=y
+# CONFIG_SLIP_MODE_SLIP6 is not set
+CONFIG_NET_FC=y
+# CONFIG_SHAPER is not set
+CONFIG_NETCONSOLE=m
+CONFIG_NETPOLL=y
+# CONFIG_NETPOLL_RX is not set
+CONFIG_NETPOLL_TRAP=y
+CONFIG_NET_POLL_CONTROLLER=y
+
+#
+# ISDN subsystem
+#
+CONFIG_ISDN=m
+
+#
+# Old ISDN4Linux
+#
+CONFIG_ISDN_I4L=m
+CONFIG_ISDN_PPP=y
+CONFIG_ISDN_PPP_VJ=y
+CONFIG_ISDN_MPP=y
+CONFIG_IPPP_FILTER=y
+# CONFIG_ISDN_PPP_BSDCOMP is not set
+CONFIG_ISDN_AUDIO=y
+CONFIG_ISDN_TTY_FAX=y
+
+#
+# ISDN feature submodules
+#
+CONFIG_ISDN_DIVERSION=m
+
+#
+# ISDN4Linux hardware drivers
+#
+
+#
+# Passive cards
+#
+CONFIG_ISDN_DRV_HISAX=m
+
+#
+# D-channel protocol features
+#
+CONFIG_HISAX_EURO=y
+CONFIG_DE_AOC=y
+CONFIG_HISAX_NO_SENDCOMPLETE=y
+CONFIG_HISAX_NO_LLC=y
+CONFIG_HISAX_NO_KEYPAD=y
+CONFIG_HISAX_1TR6=y
+CONFIG_HISAX_NI1=y
+CONFIG_HISAX_MAX_CARDS=8
+
+#
+# HiSax supported cards
+#
+CONFIG_HISAX_16_3=y
+CONFIG_HISAX_S0BOX=y
+CONFIG_HISAX_AVM_A1_PCMCIA=y
+CONFIG_HISAX_ELSA=y
+CONFIG_HISAX_DIEHLDIVA=y
+CONFIG_HISAX_SEDLBAUER=y
+CONFIG_HISAX_NICCY=y
+CONFIG_HISAX_BKM_A4T=y
+CONFIG_HISAX_SCT_QUADRO=y
+CONFIG_HISAX_GAZEL=y
+CONFIG_HISAX_W6692=y
+CONFIG_HISAX_HFC_SX=y
+# CONFIG_HISAX_DEBUG is not set
+
+#
+# HiSax PCMCIA card service modules
+#
+CONFIG_HISAX_SEDLBAUER_CS=m
+CONFIG_HISAX_ELSA_CS=m
+CONFIG_HISAX_AVM_A1_CS=m
+CONFIG_HISAX_TELES_CS=m
+
+#
+# HiSax sub driver modules
+#
+CONFIG_HISAX_ST5481=m
+# CONFIG_HISAX_HFCUSB is not set
+CONFIG_HISAX_HFC4S8S=m
+CONFIG_HISAX_FRITZ_PCIPNP=m
+CONFIG_HISAX_HDLC=y
+
+#
+# Active cards
+#
+
+#
+# Siemens Gigaset
+#
+CONFIG_ISDN_DRV_GIGASET=m
+CONFIG_GIGASET_BASE=m
+CONFIG_GIGASET_M105=m
+# CONFIG_GIGASET_DEBUG is not set
+# CONFIG_GIGASET_UNDOCREQ is not set
+
+#
+# CAPI subsystem
+#
+CONFIG_ISDN_CAPI=m
+CONFIG_ISDN_DRV_AVMB1_VERBOSE_REASON=y
+CONFIG_ISDN_CAPI_MIDDLEWARE=y
+CONFIG_ISDN_CAPI_CAPI20=m
+CONFIG_ISDN_CAPI_CAPIFS_BOOL=y
+CONFIG_ISDN_CAPI_CAPIFS=m
+CONFIG_ISDN_CAPI_CAPIDRV=m
+
+#
+# CAPI hardware drivers
+#
+
+#
+# Active AVM cards
+#
+CONFIG_CAPI_AVM=y
+CONFIG_ISDN_DRV_AVMB1_B1PCI=m
+CONFIG_ISDN_DRV_AVMB1_B1PCIV4=y
+CONFIG_ISDN_DRV_AVMB1_B1PCMCIA=m
+CONFIG_ISDN_DRV_AVMB1_AVM_CS=m
+CONFIG_ISDN_DRV_AVMB1_T1PCI=m
+CONFIG_ISDN_DRV_AVMB1_C4=m
+
+#
+# Active Eicon DIVA Server cards
+#
+CONFIG_CAPI_EICON=y
+CONFIG_ISDN_DIVAS=m
+CONFIG_ISDN_DIVAS_BRIPCI=y
+CONFIG_ISDN_DIVAS_PRIPCI=y
+CONFIG_ISDN_DIVAS_DIVACAPI=m
+CONFIG_ISDN_DIVAS_USERIDI=m
+CONFIG_ISDN_DIVAS_MAINT=m
+
+#
+# Telephony Support
+#
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+
+#
+# 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=m
+# CONFIG_INPUT_TSDEV is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+CONFIG_KEYBOARD_ATKBD=y
+# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_KEYBOARD_LKKBD is not set
+# CONFIG_KEYBOARD_XTKBD is not set
+# CONFIG_KEYBOARD_NEWTON is not set
+CONFIG_INPUT_MOUSE=y
+CONFIG_MOUSE_PS2=y
+CONFIG_MOUSE_SERIAL=m
+CONFIG_MOUSE_VSXXXAA=m
+CONFIG_INPUT_JOYSTICK=y
+CONFIG_JOYSTICK_ANALOG=m
+CONFIG_JOYSTICK_A3D=m
+CONFIG_JOYSTICK_ADI=m
+CONFIG_JOYSTICK_COBRA=m
+CONFIG_JOYSTICK_GF2K=m
+CONFIG_JOYSTICK_GRIP=m
+CONFIG_JOYSTICK_GRIP_MP=m
+CONFIG_JOYSTICK_GUILLEMOT=m
+CONFIG_JOYSTICK_INTERACT=m
+CONFIG_JOYSTICK_SIDEWINDER=m
+CONFIG_JOYSTICK_TMDC=m
+CONFIG_JOYSTICK_IFORCE=m
+CONFIG_JOYSTICK_IFORCE_USB=y
+CONFIG_JOYSTICK_IFORCE_232=y
+CONFIG_JOYSTICK_WARRIOR=m
+CONFIG_JOYSTICK_MAGELLAN=m
+CONFIG_JOYSTICK_SPACEORB=m
+CONFIG_JOYSTICK_SPACEBALL=m
+CONFIG_JOYSTICK_STINGER=m
+CONFIG_JOYSTICK_TWIDJOY=m
+CONFIG_JOYSTICK_DB9=m
+CONFIG_JOYSTICK_GAMECON=m
+CONFIG_JOYSTICK_TURBOGRAFX=m
+CONFIG_JOYSTICK_JOYDUMP=m
+CONFIG_INPUT_TOUCHSCREEN=y
+CONFIG_TOUCHSCREEN_GUNZE=m
+CONFIG_TOUCHSCREEN_ELO=m
+CONFIG_TOUCHSCREEN_MTOUCH=m
+CONFIG_TOUCHSCREEN_MK712=m
+CONFIG_INPUT_MISC=y
+# CONFIG_INPUT_PCSPKR is not set
+CONFIG_INPUT_UINPUT=m
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+CONFIG_SERIO_I8042=y
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_PARKBD is not set
+# CONFIG_SERIO_PCIPS2 is not set
+CONFIG_SERIO_LIBPS2=y
+CONFIG_SERIO_RAW=m
+CONFIG_GAMEPORT=m
+CONFIG_GAMEPORT_NS558=m
+CONFIG_GAMEPORT_L4=m
+CONFIG_GAMEPORT_EMU10K1=m
+CONFIG_GAMEPORT_FM801=m
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+CONFIG_VT_HW_CONSOLE_BINDING=y
+CONFIG_SERIAL_NONSTANDARD=y
+# CONFIG_COMPUTONE is not set
+# CONFIG_ROCKETPORT is not set
+CONFIG_CYCLADES=m
+# CONFIG_CYZ_INTR is not set
+# CONFIG_DIGIEPCA is not set
+# CONFIG_MOXA_INTELLIO is not set
+# CONFIG_MOXA_SMARTIO is not set
+# CONFIG_ISI is not set
+CONFIG_SYNCLINK=m
+CONFIG_SYNCLINKMP=m
+CONFIG_SYNCLINK_GT=m
+CONFIG_N_HDLC=m
+# CONFIG_SPECIALIX is not set
+# CONFIG_SX is not set
+# CONFIG_RIO is not set
+# CONFIG_STALDRV is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_PCI=y
+CONFIG_SERIAL_8250_CS=m
+CONFIG_SERIAL_8250_NR_UARTS=32
+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=y
+CONFIG_SERIAL_8250_RSA=y
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_SERIAL_PMACZILOG=m
+CONFIG_SERIAL_ICOM=m
+CONFIG_SERIAL_JSM=m
+CONFIG_UNIX98_PTYS=y
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_CRASH is not set
+CONFIG_PRINTER=m
+CONFIG_LP_CONSOLE=y
+CONFIG_PPDEV=m
+CONFIG_TIPAR=m
+CONFIG_HVC_DRIVER=y
+CONFIG_HVC_CONSOLE=y
+CONFIG_HVC_RTAS=y
+CONFIG_HVCS=m
+
+#
+# IPMI
+#
+CONFIG_IPMI_HANDLER=m
+# CONFIG_IPMI_PANIC_EVENT is not set
+CONFIG_IPMI_DEVICE_INTERFACE=m
+CONFIG_IPMI_SI=m
+CONFIG_IPMI_WATCHDOG=m
+CONFIG_IPMI_POWEROFF=m
+
+#
+# Watchdog Cards
+#
+CONFIG_WATCHDOG=y
+# CONFIG_WATCHDOG_NOWAYOUT is not set
+
+#
+# Watchdog Device Drivers
+#
+CONFIG_SOFT_WATCHDOG=m
+CONFIG_WATCHDOG_RTAS=m
+
+#
+# PCI-based Watchdog Cards
+#
+CONFIG_PCIPCWATCHDOG=m
+CONFIG_WDTPCI=m
+CONFIG_WDT_501_PCI=y
+
+#
+# USB-based Watchdog Cards
+#
+CONFIG_USBPCWATCHDOG=m
+CONFIG_HW_RANDOM=y
+CONFIG_GEN_RTC=y
+# CONFIG_GEN_RTC_X is not set
+CONFIG_DTLK=m
+CONFIG_R3964=m
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+CONFIG_AGP=y
+CONFIG_AGP_SIS=y
+CONFIG_AGP_VIA=y
+CONFIG_AGP_UNINORTH=y
+CONFIG_DRM=m
+CONFIG_DRM_TDFX=m
+CONFIG_DRM_R128=m
+CONFIG_DRM_RADEON=m
+CONFIG_DRM_MGA=m
+CONFIG_DRM_SIS=m
+CONFIG_DRM_VIA=m
+CONFIG_DRM_SAVAGE=m
+
+#
+# PCMCIA character devices
+#
+# CONFIG_SYNCLINK_CS is not set
+CONFIG_CARDMAN_4000=m
+CONFIG_CARDMAN_4040=m
+# CONFIG_RAW_DRIVER is not set
+CONFIG_HANGCHECK_TIMER=m
+
+#
+# TPM devices
+#
+CONFIG_TCG_TPM=m
+CONFIG_TCG_ATMEL=m
+# CONFIG_TELCLOCK is not set
+
+#
+# I2C support
+#
+CONFIG_I2C=y
+CONFIG_I2C_CHARDEV=m
+
+#
+# I2C Algorithms
+#
+CONFIG_I2C_ALGOBIT=y
+CONFIG_I2C_ALGOPCF=m
+CONFIG_I2C_ALGOPCA=m
+
+#
+# I2C Hardware Bus support
+#
+# CONFIG_I2C_ALI1535 is not set
+# CONFIG_I2C_ALI1563 is not set
+# CONFIG_I2C_ALI15X3 is not set
+# CONFIG_I2C_AMD756 is not set
+# CONFIG_I2C_AMD8111 is not set
+# CONFIG_I2C_I801 is not set
+# CONFIG_I2C_I810 is not set
+# CONFIG_I2C_PIIX4 is not set
+CONFIG_I2C_ISA=m
+CONFIG_I2C_POWERMAC=y
+CONFIG_I2C_NFORCE2=m
+# CONFIG_I2C_OCORES is not set
+CONFIG_I2C_PARPORT=m
+CONFIG_I2C_PARPORT_LIGHT=m
+CONFIG_I2C_PROSAVAGE=m
+CONFIG_I2C_SAVAGE4=m
+# CONFIG_I2C_SIS5595 is not set
+# CONFIG_I2C_SIS630 is not set
+# CONFIG_I2C_SIS96X is not set
+CONFIG_I2C_STUB=m
+# CONFIG_I2C_VIA is not set
+# CONFIG_I2C_VIAPRO is not set
+CONFIG_I2C_VOODOO3=m
+CONFIG_I2C_PCA_ISA=m
+
+#
+# Miscellaneous I2C Chip support
+#
+CONFIG_SENSORS_DS1337=m
+CONFIG_SENSORS_DS1374=m
+CONFIG_SENSORS_EEPROM=m
+CONFIG_SENSORS_PCF8574=m
+CONFIG_SENSORS_PCA9539=m
+CONFIG_SENSORS_PCF8591=m
+CONFIG_SENSORS_MAX6875=m
+# 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 is not set
+# CONFIG_SPI_MASTER is not set
+
+#
+# Dallas's 1-wire bus
+#
+CONFIG_W1=m
+CONFIG_W1_CON=y
+
+#
+# 1-wire Bus Masters
+#
+CONFIG_W1_MASTER_MATROX=m
+CONFIG_W1_MASTER_DS2490=m
+CONFIG_W1_MASTER_DS2482=m
+
+#
+# 1-wire Slaves
+#
+CONFIG_W1_SLAVE_THERM=m
+CONFIG_W1_SLAVE_SMEM=m
+CONFIG_W1_SLAVE_DS2433=m
+CONFIG_W1_SLAVE_DS2433_CRC=y
+
+#
+# Hardware Monitoring support
+#
+CONFIG_HWMON=m
+CONFIG_HWMON_VID=m
+CONFIG_SENSORS_ABITUGURU=m
+CONFIG_SENSORS_ADM1021=m
+CONFIG_SENSORS_ADM1025=m
+CONFIG_SENSORS_ADM1026=m
+CONFIG_SENSORS_ADM1031=m
+CONFIG_SENSORS_ADM9240=m
+CONFIG_SENSORS_ASB100=m
+CONFIG_SENSORS_ATXP1=m
+CONFIG_SENSORS_DS1621=m
+CONFIG_SENSORS_F71805F=m
+CONFIG_SENSORS_FSCHER=m
+CONFIG_SENSORS_FSCPOS=m
+CONFIG_SENSORS_GL518SM=m
+CONFIG_SENSORS_GL520SM=m
+CONFIG_SENSORS_IT87=m
+CONFIG_SENSORS_LM63=m
+CONFIG_SENSORS_LM75=m
+CONFIG_SENSORS_LM77=m
+CONFIG_SENSORS_LM78=m
+CONFIG_SENSORS_LM80=m
+CONFIG_SENSORS_LM83=m
+CONFIG_SENSORS_LM85=m
+CONFIG_SENSORS_LM87=m
+CONFIG_SENSORS_LM90=m
+CONFIG_SENSORS_LM92=m
+CONFIG_SENSORS_MAX1619=m
+CONFIG_SENSORS_PC87360=m
+CONFIG_SENSORS_SIS5595=m
+CONFIG_SENSORS_SMSC47M1=m
+CONFIG_SENSORS_SMSC47M192=m
+CONFIG_SENSORS_SMSC47B397=m
+CONFIG_SENSORS_VIA686A=m
+CONFIG_SENSORS_VT8231=m
+CONFIG_SENSORS_W83781D=m
+CONFIG_SENSORS_W83791D=m
+CONFIG_SENSORS_W83792D=m
+CONFIG_SENSORS_W83L785TS=m
+CONFIG_SENSORS_W83627HF=m
+CONFIG_SENSORS_W83627EHF=m
+# CONFIG_HWMON_DEBUG_CHIP is not set
+
+#
+# Misc devices
+#
+
+#
+# Multimedia devices
+#
+CONFIG_VIDEO_DEV=m
+CONFIG_VIDEO_V4L1=y
+CONFIG_VIDEO_V4L1_COMPAT=y
+CONFIG_VIDEO_V4L2=y
+
+#
+# Video Capture Adapters
+#
+
+#
+# Video Capture Adapters
+#
+# CONFIG_VIDEO_ADV_DEBUG is not set
+# CONFIG_VIDEO_VIVI is not set
+CONFIG_VIDEO_BT848=m
+CONFIG_VIDEO_BT848_DVB=y
+CONFIG_VIDEO_SAA6588=m
+CONFIG_VIDEO_BWQCAM=m
+CONFIG_VIDEO_CQCAM=m
+CONFIG_VIDEO_W9966=m
+CONFIG_VIDEO_CPIA=m
+CONFIG_VIDEO_CPIA_PP=m
+CONFIG_VIDEO_CPIA_USB=m
+CONFIG_VIDEO_CPIA2=m
+CONFIG_VIDEO_SAA5246A=m
+CONFIG_VIDEO_SAA5249=m
+CONFIG_TUNER_3036=m
+CONFIG_VIDEO_SAA7134=m
+CONFIG_VIDEO_SAA7134_ALSA=m
+CONFIG_VIDEO_SAA7134_DVB=m
+CONFIG_VIDEO_SAA7134_DVB_ALL_FRONTENDS=y
+CONFIG_VIDEO_MXB=m
+CONFIG_VIDEO_DPC=m
+CONFIG_VIDEO_HEXIUM_ORION=m
+CONFIG_VIDEO_HEXIUM_GEMINI=m
+CONFIG_VIDEO_CX88_VP3054=m
+CONFIG_VIDEO_CX88=m
+CONFIG_VIDEO_CX88_ALSA=m
+CONFIG_VIDEO_CX88_BLACKBIRD=m
+CONFIG_VIDEO_CX88_DVB=m
+CONFIG_VIDEO_CX88_DVB_ALL_FRONTENDS=y
+
+#
+# Encoders and Decoders
+#
+CONFIG_VIDEO_MSP3400=m
+CONFIG_VIDEO_CS53L32A=m
+CONFIG_VIDEO_TLV320AIC23B=m
+CONFIG_VIDEO_WM8775=m
+CONFIG_VIDEO_WM8739=m
+CONFIG_VIDEO_CX2341X=m
+CONFIG_VIDEO_CX25840=m
+CONFIG_VIDEO_SAA711X=m
+CONFIG_VIDEO_SAA7127=m
+CONFIG_VIDEO_UPD64031A=m
+CONFIG_VIDEO_UPD64083=m
+
+#
+# V4L USB devices
+#
+CONFIG_VIDEO_PVRUSB2=m
+CONFIG_VIDEO_PVRUSB2_24XXX=y
+CONFIG_VIDEO_PVRUSB2_SYSFS=y
+# CONFIG_VIDEO_PVRUSB2_DEBUGIFC is not set
+CONFIG_VIDEO_EM28XX=m
+CONFIG_VIDEO_USBVIDEO=m
+CONFIG_USB_VICAM=m
+CONFIG_USB_IBMCAM=m
+CONFIG_USB_KONICAWC=m
+CONFIG_USB_QUICKCAM_MESSENGER=m
+CONFIG_USB_ET61X251=m
+CONFIG_VIDEO_OVCAMCHIP=m
+CONFIG_USB_W9968CF=m
+CONFIG_USB_OV511=m
+CONFIG_USB_SE401=m
+CONFIG_USB_SN9C102=m
+CONFIG_USB_STV680=m
+CONFIG_USB_ZC0301=m
+CONFIG_USB_PWC=m
+# CONFIG_USB_PWC_DEBUG is not set
+
+#
+# Radio Adapters
+#
+CONFIG_RADIO_GEMTEK_PCI=m
+CONFIG_RADIO_MAXIRADIO=m
+CONFIG_RADIO_MAESTRO=m
+CONFIG_USB_DSBR=m
+
+#
+# Digital Video Broadcasting Devices
+#
+CONFIG_DVB=y
+CONFIG_DVB_CORE=m
+
+#
+# Supported SAA7146 based PCI Adapters
+#
+CONFIG_DVB_AV7110=m
+CONFIG_DVB_AV7110_OSD=y
+CONFIG_DVB_BUDGET=m
+CONFIG_DVB_BUDGET_CI=m
+CONFIG_DVB_BUDGET_AV=m
+CONFIG_DVB_BUDGET_PATCH=m
+
+#
+# Supported USB Adapters
+#
+CONFIG_DVB_USB=m
+# CONFIG_DVB_USB_DEBUG is not set
+CONFIG_DVB_USB_A800=m
+CONFIG_DVB_USB_DIBUSB_MB=m
+# CONFIG_DVB_USB_DIBUSB_MB_FAULTY is not set
+CONFIG_DVB_USB_DIBUSB_MC=m
+CONFIG_DVB_USB_UMT_010=m
+CONFIG_DVB_USB_CXUSB=m
+CONFIG_DVB_USB_DIGITV=m
+CONFIG_DVB_USB_VP7045=m
+CONFIG_DVB_USB_VP702X=m
+CONFIG_DVB_USB_GP8PSK=m
+CONFIG_DVB_USB_NOVA_T_USB2=m
+CONFIG_DVB_USB_DTT200U=m
+CONFIG_DVB_TTUSB_BUDGET=m
+CONFIG_DVB_TTUSB_DEC=m
+CONFIG_DVB_CINERGYT2=m
+CONFIG_DVB_CINERGYT2_TUNING=y
+CONFIG_DVB_CINERGYT2_STREAM_URB_COUNT=32
+CONFIG_DVB_CINERGYT2_STREAM_BUF_SIZE=512
+CONFIG_DVB_CINERGYT2_QUERY_INTERVAL=250
+CONFIG_DVB_CINERGYT2_ENABLE_RC_INPUT_DEVICE=y
+CONFIG_DVB_CINERGYT2_RC_QUERY_INTERVAL=100
+
+#
+# Supported FlexCopII (B2C2) Adapters
+#
+CONFIG_DVB_B2C2_FLEXCOP=m
+CONFIG_DVB_B2C2_FLEXCOP_PCI=m
+CONFIG_DVB_B2C2_FLEXCOP_USB=m
+# CONFIG_DVB_B2C2_FLEXCOP_DEBUG is not set
+
+#
+# Supported BT878 Adapters
+#
+CONFIG_DVB_BT8XX=m
+
+#
+# Supported Pluto2 Adapters
+#
+CONFIG_DVB_PLUTO2=m
+
+#
+# Supported DVB Frontends
+#
+
+#
+# Customise DVB Frontends
+#
+
+#
+# DVB-S (satellite) frontends
+#
+CONFIG_DVB_STV0299=m
+CONFIG_DVB_CX24110=m
+CONFIG_DVB_CX24123=m
+CONFIG_DVB_TDA8083=m
+CONFIG_DVB_MT312=m
+CONFIG_DVB_VES1X93=m
+CONFIG_DVB_S5H1420=m
+
+#
+# DVB-T (terrestrial) frontends
+#
+CONFIG_DVB_SP8870=m
+CONFIG_DVB_SP887X=m
+CONFIG_DVB_CX22700=m
+CONFIG_DVB_CX22702=m
+CONFIG_DVB_L64781=m
+CONFIG_DVB_TDA1004X=m
+CONFIG_DVB_NXT6000=m
+CONFIG_DVB_MT352=m
+CONFIG_DVB_ZL10353=m
+CONFIG_DVB_DIB3000MB=m
+CONFIG_DVB_DIB3000MC=m
+
+#
+# DVB-C (cable) frontends
+#
+CONFIG_DVB_VES1820=m
+CONFIG_DVB_TDA10021=m
+CONFIG_DVB_STV0297=m
+
+#
+# ATSC (North American/Korean Terrestrial/Cable DTV) frontends
+#
+CONFIG_DVB_NXT200X=m
+CONFIG_DVB_OR51211=m
+CONFIG_DVB_OR51132=m
+CONFIG_DVB_BCM3510=m
+CONFIG_DVB_LGDT330X=m
+
+#
+# Miscellaneous devices
+#
+CONFIG_DVB_PLL=m
+CONFIG_DVB_LNBP21=m
+CONFIG_DVB_ISL6421=m
+CONFIG_VIDEO_SAA7146=m
+CONFIG_VIDEO_SAA7146_VV=m
+CONFIG_VIDEO_VIDEOBUF=m
+CONFIG_VIDEO_TUNER=m
+CONFIG_VIDEO_BUF=m
+CONFIG_VIDEO_BUF_DVB=m
+CONFIG_VIDEO_BTCX=m
+CONFIG_VIDEO_IR=m
+CONFIG_VIDEO_TVEEPROM=m
+CONFIG_USB_DABUSB=m
+
+#
+# Graphics support
+#
+# CONFIG_FIRMWARE_EDID is not set
+CONFIG_FB=y
+CONFIG_FB_CFB_FILLRECT=y
+CONFIG_FB_CFB_COPYAREA=y
+CONFIG_FB_CFB_IMAGEBLIT=y
+CONFIG_FB_MACMODES=y
+# CONFIG_FB_BACKLIGHT is not set
+CONFIG_FB_MODE_HELPERS=y
+CONFIG_FB_TILEBLITTING=y
+CONFIG_FB_CIRRUS=m
+# CONFIG_FB_PM2 is not set
+# CONFIG_FB_CYBER2000 is not set
+CONFIG_FB_OF=y
+# CONFIG_FB_ASILIANT is not set
+# CONFIG_FB_IMSTT is not set
+# CONFIG_FB_VGA16 is not set
+# CONFIG_FB_S1D13XXX is not set
+CONFIG_FB_NVIDIA=m
+CONFIG_FB_NVIDIA_I2C=y
+CONFIG_FB_RIVA=m
+# CONFIG_FB_RIVA_I2C is not set
+# CONFIG_FB_RIVA_DEBUG is not set
+CONFIG_FB_MATROX=m
+CONFIG_FB_MATROX_MILLENIUM=y
+CONFIG_FB_MATROX_MYSTIQUE=y
+CONFIG_FB_MATROX_G=y
+CONFIG_FB_MATROX_I2C=m
+CONFIG_FB_MATROX_MAVEN=m
+CONFIG_FB_MATROX_MULTIHEAD=y
+CONFIG_FB_RADEON=y
+CONFIG_FB_RADEON_I2C=y
+# CONFIG_FB_RADEON_DEBUG is not set
+# CONFIG_FB_ATY128 is not set
+# CONFIG_FB_ATY is not set
+CONFIG_FB_SAVAGE=m
+CONFIG_FB_SAVAGE_I2C=y
+CONFIG_FB_SAVAGE_ACCEL=y
+# CONFIG_FB_SIS is not set
+CONFIG_FB_NEOMAGIC=m
+CONFIG_FB_KYRO=m
+CONFIG_FB_3DFX=m
+CONFIG_FB_3DFX_ACCEL=y
+CONFIG_FB_VOODOO1=m
+CONFIG_FB_TRIDENT=m
+CONFIG_FB_TRIDENT_ACCEL=y
+# CONFIG_FB_VIRTUAL is not set
+
+#
+# Console display driver support
+#
+CONFIG_VGA_CONSOLE=y
+CONFIG_VGACON_SOFT_SCROLLBACK=y
+CONFIG_VGACON_SOFT_SCROLLBACK_SIZE=64
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y
+# CONFIG_FONTS is not set
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
+
+#
+# Logo configuration
+#
+CONFIG_LOGO=y
+# CONFIG_LOGO_LINUX_MONO is not set
+# CONFIG_LOGO_LINUX_VGA16 is not set
+CONFIG_LOGO_LINUX_CLUT224=y
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+CONFIG_BACKLIGHT_CLASS_DEVICE=m
+CONFIG_BACKLIGHT_DEVICE=y
+CONFIG_LCD_CLASS_DEVICE=m
+CONFIG_LCD_DEVICE=y
+
+#
+# Sound
+#
+CONFIG_SOUND=m
+
+#
+# Advanced Linux Sound Architecture
+#
+CONFIG_SND=m
+CONFIG_SND_TIMER=m
+CONFIG_SND_PCM=m
+CONFIG_SND_HWDEP=m
+CONFIG_SND_RAWMIDI=m
+CONFIG_SND_SEQUENCER=m
+CONFIG_SND_SEQ_DUMMY=m
+CONFIG_SND_OSSEMUL=y
+CONFIG_SND_MIXER_OSS=m
+CONFIG_SND_PCM_OSS=m
+CONFIG_SND_PCM_OSS_PLUGINS=y
+CONFIG_SND_SEQUENCER_OSS=y
+CONFIG_SND_DYNAMIC_MINORS=y
+# CONFIG_SND_SUPPORT_OLD_API is not set
+CONFIG_SND_VERBOSE_PROCFS=y
+# CONFIG_SND_VERBOSE_PRINTK is not set
+# CONFIG_SND_DEBUG is not set
+
+#
+# Generic devices
+#
+CONFIG_SND_MPU401_UART=m
+CONFIG_SND_OPL3_LIB=m
+CONFIG_SND_VX_LIB=m
+CONFIG_SND_AC97_CODEC=m
+CONFIG_SND_AC97_BUS=m
+CONFIG_SND_DUMMY=m
+CONFIG_SND_VIRMIDI=m
+CONFIG_SND_MTPAV=m
+# CONFIG_SND_SERIAL_U16550 is not set
+CONFIG_SND_MPU401=m
+
+#
+# PCI devices
+#
+CONFIG_SND_AD1889=m
+CONFIG_SND_ALS300=m
+CONFIG_SND_ALS4000=m
+CONFIG_SND_ALI5451=m
+CONFIG_SND_ATIIXP=m
+CONFIG_SND_ATIIXP_MODEM=m
+CONFIG_SND_AU8810=m
+CONFIG_SND_AU8820=m
+CONFIG_SND_AU8830=m
+CONFIG_SND_AZT3328=m
+CONFIG_SND_BT87X=m
+# CONFIG_SND_BT87X_OVERCLOCK is not set
+CONFIG_SND_CA0106=m
+CONFIG_SND_CMIPCI=m
+CONFIG_SND_CS4281=m
+CONFIG_SND_CS46XX=m
+CONFIG_SND_CS46XX_NEW_DSP=y
+CONFIG_SND_DARLA20=m
+CONFIG_SND_GINA20=m
+CONFIG_SND_LAYLA20=m
+CONFIG_SND_DARLA24=m
+CONFIG_SND_GINA24=m
+CONFIG_SND_LAYLA24=m
+CONFIG_SND_MONA=m
+CONFIG_SND_MIA=m
+CONFIG_SND_ECHO3G=m
+CONFIG_SND_INDIGO=m
+CONFIG_SND_INDIGOIO=m
+CONFIG_SND_INDIGODJ=m
+CONFIG_SND_EMU10K1=m
+CONFIG_SND_EMU10K1X=m
+CONFIG_SND_ENS1370=m
+CONFIG_SND_ENS1371=m
+CONFIG_SND_ES1938=m
+CONFIG_SND_ES1968=m
+CONFIG_SND_FM801=m
+CONFIG_SND_FM801_TEA575X_BOOL=y
+CONFIG_SND_FM801_TEA575X=m
+CONFIG_SND_HDA_INTEL=m
+CONFIG_SND_HDSP=m
+CONFIG_SND_HDSPM=m
+CONFIG_SND_ICE1712=m
+CONFIG_SND_ICE1724=m
+CONFIG_SND_INTEL8X0=m
+CONFIG_SND_INTEL8X0M=m
+CONFIG_SND_KORG1212=m
+CONFIG_SND_MAESTRO3=m
+CONFIG_SND_MIXART=m
+CONFIG_SND_NM256=m
+CONFIG_SND_PCXHR=m
+CONFIG_SND_RIPTIDE=m
+CONFIG_SND_RME32=m
+CONFIG_SND_RME96=m
+CONFIG_SND_RME9652=m
+CONFIG_SND_SONICVIBES=m
+CONFIG_SND_TRIDENT=m
+CONFIG_SND_VIA82XX=m
+CONFIG_SND_VIA82XX_MODEM=m
+CONFIG_SND_VX222=m
+CONFIG_SND_YMFPCI=m
+
+#
+# ALSA PowerMac devices
+#
+CONFIG_SND_POWERMAC=m
+CONFIG_SND_POWERMAC_AUTO_DRC=y
+
+#
+# Apple Onboard Audio driver
+#
+CONFIG_SND_AOA=m
+CONFIG_SND_AOA_FABRIC_LAYOUT=m
+CONFIG_SND_AOA_ONYX=m
+CONFIG_SND_AOA_TAS=m
+CONFIG_SND_AOA_TOONIE=m
+CONFIG_SND_AOA_SOUNDBUS=m
+CONFIG_SND_AOA_SOUNDBUS_I2S=m
+
+#
+# USB devices
+#
+CONFIG_SND_USB_AUDIO=m
+CONFIG_SND_USB_USX2Y=m
+
+#
+# PCMCIA devices
+#
+# CONFIG_SND_VXPOCKET is not set
+# CONFIG_SND_PDAUDIOCF is not set
+
+#
+# Open Sound System
+#
+# CONFIG_SOUND_PRIME is not set
+
+#
+# USB support
+#
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB_ARCH_HAS_EHCI=y
+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_SUSPEND is not set
+# CONFIG_USB_OTG is not set
+
+#
+# USB Host Controller Drivers
+#
+CONFIG_USB_EHCI_HCD=m
+CONFIG_USB_EHCI_SPLIT_ISO=y
+CONFIG_USB_EHCI_ROOT_HUB_TT=y
+CONFIG_USB_EHCI_TT_NEWSCHED=y
+CONFIG_USB_ISP116X_HCD=m
+CONFIG_USB_OHCI_HCD=m
+# CONFIG_USB_OHCI_BIG_ENDIAN is not set
+CONFIG_USB_OHCI_LITTLE_ENDIAN=y
+CONFIG_USB_UHCI_HCD=m
+CONFIG_USB_SL811_HCD=m
+CONFIG_USB_SL811_CS=m
+
+#
+# USB Device Class drivers
+#
+CONFIG_USB_ACM=m
+CONFIG_USB_PRINTER=m
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+#
+
+#
+# may also be needed; see USB_STORAGE Help for more information
+#
+CONFIG_USB_STORAGE=m
+# CONFIG_USB_STORAGE_DEBUG is not set
+CONFIG_USB_STORAGE_DATAFAB=y
+CONFIG_USB_STORAGE_FREECOM=y
+CONFIG_USB_STORAGE_ISD200=y
+CONFIG_USB_STORAGE_DPCM=y
+CONFIG_USB_STORAGE_USBAT=y
+CONFIG_USB_STORAGE_SDDR09=y
+CONFIG_USB_STORAGE_SDDR55=y
+CONFIG_USB_STORAGE_JUMPSHOT=y
+CONFIG_USB_STORAGE_ALAUDA=y
+CONFIG_USB_LIBUSUAL=y
+
+#
+# USB Input Devices
+#
+CONFIG_USB_HID=y
+CONFIG_USB_HIDINPUT=y
+CONFIG_USB_HIDINPUT_POWERBOOK=y
+CONFIG_HID_FF=y
+CONFIG_HID_PID=y
+CONFIG_LOGITECH_FF=y
+CONFIG_THRUSTMASTER_FF=y
+CONFIG_USB_HIDDEV=y
+CONFIG_USB_AIPTEK=m
+CONFIG_USB_WACOM=m
+CONFIG_USB_ACECAD=m
+CONFIG_USB_KBTAB=m
+CONFIG_USB_POWERMATE=m
+CONFIG_USB_TOUCHSCREEN=m
+CONFIG_USB_TOUCHSCREEN_EGALAX=y
+CONFIG_USB_TOUCHSCREEN_PANJIT=y
+CONFIG_USB_TOUCHSCREEN_3M=y
+CONFIG_USB_TOUCHSCREEN_ITM=y
+# CONFIG_USB_YEALINK is not set
+CONFIG_USB_XPAD=m
+CONFIG_USB_ATI_REMOTE=m
+CONFIG_USB_ATI_REMOTE2=m
+CONFIG_USB_KEYSPAN_REMOTE=m
+CONFIG_USB_APPLETOUCH=m
+
+#
+# USB Imaging devices
+#
+CONFIG_USB_MDC800=m
+CONFIG_USB_MICROTEK=m
+
+#
+# USB Network Adapters
+#
+CONFIG_USB_CATC=m
+CONFIG_USB_KAWETH=m
+CONFIG_USB_PEGASUS=m
+CONFIG_USB_RTL8150=m
+CONFIG_USB_USBNET=m
+CONFIG_USB_NET_AX8817X=m
+CONFIG_USB_NET_CDCETHER=m
+CONFIG_USB_NET_GL620A=m
+CONFIG_USB_NET_NET1080=m
+CONFIG_USB_NET_PLUSB=m
+CONFIG_USB_NET_RNDIS_HOST=m
+CONFIG_USB_NET_CDC_SUBSET=m
+CONFIG_USB_ALI_M5632=y
+CONFIG_USB_AN2720=y
+CONFIG_USB_BELKIN=y
+CONFIG_USB_ARMLINUX=y
+CONFIG_USB_EPSON2888=y
+CONFIG_USB_NET_ZAURUS=m
+CONFIG_USB_MON=y
+
+#
+# USB port drivers
+#
+CONFIG_USB_USS720=m
+
+#
+# USB Serial Converter support
+#
+CONFIG_USB_SERIAL=m
+CONFIG_USB_SERIAL_GENERIC=y
+CONFIG_USB_SERIAL_AIRPRIME=m
+CONFIG_USB_SERIAL_ARK3116=m
+CONFIG_USB_SERIAL_BELKIN=m
+CONFIG_USB_SERIAL_WHITEHEAT=m
+CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m
+CONFIG_USB_SERIAL_CP2101=m
+CONFIG_USB_SERIAL_CYPRESS_M8=m
+CONFIG_USB_SERIAL_EMPEG=m
+CONFIG_USB_SERIAL_FTDI_SIO=m
+CONFIG_USB_SERIAL_FUNSOFT=m
+CONFIG_USB_SERIAL_VISOR=m
+CONFIG_USB_SERIAL_IPAQ=m
+CONFIG_USB_SERIAL_IR=m
+CONFIG_USB_SERIAL_EDGEPORT=m
+CONFIG_USB_SERIAL_EDGEPORT_TI=m
+CONFIG_USB_SERIAL_GARMIN=m
+CONFIG_USB_SERIAL_IPW=m
+CONFIG_USB_SERIAL_KEYSPAN_PDA=m
+CONFIG_USB_SERIAL_KEYSPAN=m
+CONFIG_USB_SERIAL_KEYSPAN_MPR=y
+CONFIG_USB_SERIAL_KEYSPAN_USA28=y
+CONFIG_USB_SERIAL_KEYSPAN_USA28X=y
+CONFIG_USB_SERIAL_KEYSPAN_USA28XA=y
+CONFIG_USB_SERIAL_KEYSPAN_USA28XB=y
+CONFIG_USB_SERIAL_KEYSPAN_USA19=y
+CONFIG_USB_SERIAL_KEYSPAN_USA18X=y
+CONFIG_USB_SERIAL_KEYSPAN_USA19W=y
+CONFIG_USB_SERIAL_KEYSPAN_USA19QW=y
+CONFIG_USB_SERIAL_KEYSPAN_USA19QI=y
+CONFIG_USB_SERIAL_KEYSPAN_USA49W=y
+CONFIG_USB_SERIAL_KEYSPAN_USA49WLC=y
+CONFIG_USB_SERIAL_KLSI=m
+CONFIG_USB_SERIAL_KOBIL_SCT=m
+CONFIG_USB_SERIAL_MCT_U232=m
+CONFIG_USB_SERIAL_NAVMAN=m
+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=m
+CONFIG_USB_SERIAL_TI=m
+CONFIG_USB_SERIAL_CYBERJACK=m
+CONFIG_USB_SERIAL_XIRCOM=m
+CONFIG_USB_SERIAL_OPTION=m
+CONFIG_USB_SERIAL_OMNINET=m
+CONFIG_USB_EZUSB=y
+
+#
+# USB Miscellaneous drivers
+#
+CONFIG_USB_EMI62=m
+CONFIG_USB_EMI26=m
+CONFIG_USB_AUERSWALD=m
+CONFIG_USB_RIO500=m
+CONFIG_USB_LEGOTOWER=m
+CONFIG_USB_LCD=m
+CONFIG_USB_LED=m
+# CONFIG_USB_CYPRESS_CY7C63 is not set
+# CONFIG_USB_CYTHERM is not set
+CONFIG_USB_PHIDGETKIT=m
+CONFIG_USB_PHIDGETSERVO=m
+CONFIG_USB_IDMOUSE=m
+CONFIG_USB_APPLEDISPLAY=m
+CONFIG_USB_SISUSBVGA=m
+CONFIG_USB_SISUSBVGA_CON=y
+CONFIG_USB_LD=m
+CONFIG_USB_TEST=m
+
+#
+# USB DSL modem support
+#
+CONFIG_USB_ATM=m
+CONFIG_USB_SPEEDTOUCH=m
+CONFIG_USB_CXACRU=m
+CONFIG_USB_UEAGLEATM=m
+CONFIG_USB_XUSBATM=m
+
+#
+# USB Gadget Support
+#
+# CONFIG_USB_GADGET is not set
+
+#
+# MMC/SD Card support
+#
+CONFIG_MMC=m
+# CONFIG_MMC_DEBUG is not set
+CONFIG_MMC_BLOCK=m
+CONFIG_MMC_SDHCI=m
+CONFIG_MMC_WBSD=m
+
+#
+# LED devices
+#
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+
+#
+# LED drivers
+#
+
+#
+# LED Triggers
+#
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_LEDS_TRIGGER_TIMER=m
+CONFIG_LEDS_TRIGGER_IDE_DISK=y
+CONFIG_LEDS_TRIGGER_HEARTBEAT=m
+
+#
+# InfiniBand support
+#
+CONFIG_INFINIBAND=m
+CONFIG_INFINIBAND_USER_MAD=m
+CONFIG_INFINIBAND_USER_ACCESS=m
+CONFIG_INFINIBAND_ADDR_TRANS=y
+CONFIG_INFINIBAND_MTHCA=m
+CONFIG_INFINIBAND_MTHCA_DEBUG=y
+CONFIG_INFINIBAND_IPOIB=m
+CONFIG_INFINIBAND_IPOIB_DEBUG=y
+CONFIG_INFINIBAND_IPOIB_DEBUG_DATA=y
+CONFIG_INFINIBAND_SRP=m
+CONFIG_INFINIBAND_ISER=m
+
+#
+# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
+#
+
+#
+# Real Time Clock
+#
+CONFIG_RTC_LIB=m
+CONFIG_RTC_CLASS=m
+
+#
+# RTC interfaces
+#
+CONFIG_RTC_INTF_SYSFS=m
+CONFIG_RTC_INTF_PROC=m
+CONFIG_RTC_INTF_DEV=m
+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
+
+#
+# RTC drivers
+#
+CONFIG_RTC_DRV_X1205=m
+CONFIG_RTC_DRV_DS1307=m
+CONFIG_RTC_DRV_DS1553=m
+CONFIG_RTC_DRV_ISL1208=m
+CONFIG_RTC_DRV_DS1672=m
+CONFIG_RTC_DRV_DS1742=m
+CONFIG_RTC_DRV_PCF8563=m
+CONFIG_RTC_DRV_PCF8583=m
+CONFIG_RTC_DRV_RS5C372=m
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_TEST is not set
+CONFIG_RTC_DRV_V3020=m
+
+#
+# DMA Engine support
+#
+CONFIG_DMA_ENGINE=y
+
+#
+# DMA Clients
+#
+CONFIG_NET_DMA=y
+
+#
+# DMA Devices
+#
+CONFIG_INTEL_IOATDMA=m
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+CONFIG_EXT2_FS_POSIX_ACL=y
+CONFIG_EXT2_FS_SECURITY=y
+CONFIG_EXT2_FS_XIP=y
+CONFIG_FS_XIP=y
+CONFIG_EXT3_FS=m
+CONFIG_EXT3_FS_XATTR=y
+CONFIG_EXT3_FS_POSIX_ACL=y
+CONFIG_EXT3_FS_SECURITY=y
+CONFIG_JBD=m
+# CONFIG_JBD_DEBUG is not set
+CONFIG_FS_MBCACHE=y
+CONFIG_REISERFS_FS=m
+# CONFIG_REISERFS_CHECK is not set
+CONFIG_REISERFS_PROC_INFO=y
+CONFIG_REISERFS_FS_XATTR=y
+CONFIG_REISERFS_FS_POSIX_ACL=y
+CONFIG_REISERFS_FS_SECURITY=y
+CONFIG_JFS_FS=m
+CONFIG_JFS_POSIX_ACL=y
+CONFIG_JFS_SECURITY=y
+# CONFIG_JFS_DEBUG is not set
+# CONFIG_JFS_STATISTICS is not set
+CONFIG_FS_POSIX_ACL=y
+CONFIG_XFS_FS=m
+CONFIG_XFS_QUOTA=y
+CONFIG_XFS_SECURITY=y
+CONFIG_XFS_POSIX_ACL=y
+# CONFIG_XFS_RT is not set
+CONFIG_OCFS2_FS=m
+# CONFIG_OCFS2_DEBUG_MASKLOG is not set
+CONFIG_MINIX_FS=m
+CONFIG_ROMFS_FS=m
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+CONFIG_QUOTA=y
+# CONFIG_QFMT_V1 is not set
+CONFIG_QFMT_V2=y
+CONFIG_QUOTACTL=y
+CONFIG_DNOTIFY=y
+CONFIG_AUTOFS_FS=m
+CONFIG_AUTOFS4_FS=m
+CONFIG_FUSE_FS=m
+
+#
+# Caches
+#
+CONFIG_FSCACHE=m
+
+#
+# CD-ROM/DVD Filesystems
+#
+CONFIG_ISO9660_FS=y
+CONFIG_JOLIET=y
+CONFIG_ZISOFS=y
+CONFIG_ZISOFS_FS=y
+CONFIG_UDF_FS=m
+CONFIG_UDF_NLS=y
+CONFIG_CACHEFILES=m
+CONFIG_CACHEFILES_DEBUG=y
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=m
+CONFIG_MSDOS_FS=m
+CONFIG_VFAT_FS=m
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="ascii"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_PROC_VMCORE=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+CONFIG_HUGETLBFS=y
+CONFIG_HUGETLB_PAGE=y
+CONFIG_RAMFS=y
+CONFIG_CONFIGFS_FS=m
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+CONFIG_AFFS_FS=m
+CONFIG_HFS_FS=m
+CONFIG_HFSPLUS_FS=m
+CONFIG_BEFS_FS=m
+# CONFIG_BEFS_DEBUG is not set
+CONFIG_BFS_FS=m
+CONFIG_EFS_FS=m
+# CONFIG_JFFS_FS is not set
+CONFIG_JFFS2_FS=m
+CONFIG_JFFS2_FS_DEBUG=0
+CONFIG_JFFS2_FS_WRITEBUFFER=y
+CONFIG_JFFS2_SUMMARY=y
+# 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=m
+CONFIG_SQUASHFS=m
+# CONFIG_SQUASHFS_EMBEDDED is not set
+CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3
+# CONFIG_SQUASHFS_VMALLOC is not set
+CONFIG_VXFS_FS=m
+# CONFIG_HPFS_FS is not set
+CONFIG_QNX4FS_FS=m
+CONFIG_SYSV_FS=m
+CONFIG_UFS_FS=m
+# CONFIG_UFS_FS_WRITE is not set
+# CONFIG_UFS_DEBUG is not set
+
+#
+# Network File Systems
+#
+CONFIG_NFS_FS=m
+CONFIG_NFS_V3=y
+CONFIG_NFS_V3_ACL=y
+CONFIG_NFS_V4=y
+CONFIG_NFS_FSCACHE=y
+CONFIG_NFS_DIRECTIO=y
+CONFIG_NFSD=m
+CONFIG_NFSD_V2_ACL=y
+CONFIG_NFSD_V3=y
+CONFIG_NFSD_V3_ACL=y
+CONFIG_NFSD_V4=y
+CONFIG_NFSD_TCP=y
+CONFIG_LOCKD=m
+CONFIG_LOCKD_V4=y
+CONFIG_EXPORTFS=m
+CONFIG_NFS_ACL_SUPPORT=m
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=m
+CONFIG_SUNRPC_GSS=m
+CONFIG_RPCSEC_GSS_KRB5=m
+CONFIG_RPCSEC_GSS_SPKM3=m
+# CONFIG_SMB_FS is not set
+CONFIG_CIFS=m
+# CONFIG_CIFS_STATS is not set
+CONFIG_CIFS_WEAK_PW_HASH=y
+CONFIG_CIFS_XATTR=y
+CONFIG_CIFS_POSIX=y
+# CONFIG_CIFS_DEBUG2 is not set
+# CONFIG_CIFS_EXPERIMENTAL is not set
+CONFIG_NCP_FS=m
+CONFIG_NCPFS_PACKET_SIGNING=y
+CONFIG_NCPFS_IOCTL_LOCKING=y
+CONFIG_NCPFS_STRONG=y
+CONFIG_NCPFS_NFS_NS=y
+CONFIG_NCPFS_OS2_NS=y
+CONFIG_NCPFS_SMALLDOS=y
+CONFIG_NCPFS_NLS=y
+CONFIG_NCPFS_EXTRAS=y
+CONFIG_CODA_FS=m
+# CONFIG_CODA_FS_OLD_API is not set
+# CONFIG_AFS_FS is not set
+CONFIG_9P_FS=m
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+CONFIG_OSF_PARTITION=y
+CONFIG_AMIGA_PARTITION=y
+# CONFIG_ATARI_PARTITION is not set
+CONFIG_MAC_PARTITION=y
+CONFIG_MSDOS_PARTITION=y
+CONFIG_BSD_DISKLABEL=y
+CONFIG_MINIX_SUBPARTITION=y
+CONFIG_SOLARIS_X86_PARTITION=y
+CONFIG_UNIXWARE_DISKLABEL=y
+# CONFIG_LDM_PARTITION is not set
+CONFIG_SGI_PARTITION=y
+# CONFIG_ULTRIX_PARTITION is not set
+CONFIG_SUN_PARTITION=y
+CONFIG_KARMA_PARTITION=y
+CONFIG_EFI_PARTITION=y
+
+#
+# Native Language Support
+#
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="utf8"
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_CODEPAGE_737=m
+CONFIG_NLS_CODEPAGE_775=m
+CONFIG_NLS_CODEPAGE_850=m
+CONFIG_NLS_CODEPAGE_852=m
+CONFIG_NLS_CODEPAGE_855=m
+CONFIG_NLS_CODEPAGE_857=m
+CONFIG_NLS_CODEPAGE_860=m
+CONFIG_NLS_CODEPAGE_861=m
+CONFIG_NLS_CODEPAGE_862=m
+CONFIG_NLS_CODEPAGE_863=m
+CONFIG_NLS_CODEPAGE_864=m
+CONFIG_NLS_CODEPAGE_865=m
+CONFIG_NLS_CODEPAGE_866=m
+CONFIG_NLS_CODEPAGE_869=m
+CONFIG_NLS_CODEPAGE_936=m
+CONFIG_NLS_CODEPAGE_950=m
+CONFIG_NLS_CODEPAGE_932=m
+CONFIG_NLS_CODEPAGE_949=m
+CONFIG_NLS_CODEPAGE_874=m
+CONFIG_NLS_ISO8859_8=m
+CONFIG_NLS_CODEPAGE_1250=m
+CONFIG_NLS_CODEPAGE_1251=m
+CONFIG_NLS_ASCII=y
+CONFIG_NLS_ISO8859_1=m
+CONFIG_NLS_ISO8859_2=m
+CONFIG_NLS_ISO8859_3=m
+CONFIG_NLS_ISO8859_4=m
+CONFIG_NLS_ISO8859_5=m
+CONFIG_NLS_ISO8859_6=m
+CONFIG_NLS_ISO8859_7=m
+CONFIG_NLS_ISO8859_9=m
+CONFIG_NLS_ISO8859_13=m
+CONFIG_NLS_ISO8859_14=m
+CONFIG_NLS_ISO8859_15=m
+CONFIG_NLS_KOI8_R=m
+CONFIG_NLS_KOI8_U=m
+CONFIG_NLS_UTF8=m
+
+#
+# Library routines
+#
+CONFIG_CRC_CCITT=m
+CONFIG_CRC16=m
+CONFIG_CRC32=y
+CONFIG_LIBCRC32C=m
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=m
+CONFIG_REED_SOLOMON=m
+CONFIG_REED_SOLOMON_DEC16=y
+CONFIG_TEXTSEARCH=y
+CONFIG_TEXTSEARCH_KMP=m
+CONFIG_TEXTSEARCH_BM=m
+CONFIG_TEXTSEARCH_FSM=m
+CONFIG_PLIST=y
+
+#
+# Instrumentation Support
+#
+CONFIG_PROFILING=y
+CONFIG_OPROFILE=m
+CONFIG_KPROBES=y
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_UNUSED_SYMBOLS is not set
+CONFIG_DEBUG_KERNEL=y
+CONFIG_LOG_BUF_SHIFT=17
+CONFIG_DETECT_SOFTLOCKUP=y
+CONFIG_SCHEDSTATS=y
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
+CONFIG_DEBUG_SPINLOCK=y
+# CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_RWSEMS is not set
+CONFIG_DEBUG_SPINLOCK_SLEEP=y
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+# CONFIG_DEBUG_KOBJECT is not set
+CONFIG_DEBUG_INFO=y
+CONFIG_DEBUG_FS=y
+# CONFIG_DEBUG_VM is not set
+CONFIG_DEBUG_LIST=y
+# CONFIG_FORCED_INLINING is not set
+CONFIG_BOOT_DELAY=y
+# CONFIG_RCU_TORTURE_TEST is not set
+CONFIG_DEBUG_STACKOVERFLOW=y
+CONFIG_DEBUG_STACK_USAGE=y
+CONFIG_DEBUGGER=y
+CONFIG_XMON=y
+CONFIG_XMON_DEFAULT=y
+CONFIG_IRQSTACKS=y
+CONFIG_BOOTX_TEXT=y
+# CONFIG_PPC_EARLY_DEBUG is not set
+
+#
+# Security options
+#
+CONFIG_KEYS=y
+CONFIG_KEYS_DEBUG_PROC_KEYS=y
+CONFIG_SECURITY=y
+CONFIG_SECURITY_NETWORK=y
+# CONFIG_SECURITY_NETWORK_XFRM is not set
+CONFIG_SECURITY_CAPABILITIES=y
+# CONFIG_SECURITY_ROOTPLUG is not set
+# CONFIG_SECURITY_SECLVL is not set
+CONFIG_SECURITY_SELINUX=y
+CONFIG_SECURITY_SELINUX_BOOTPARAM=y
+CONFIG_SECURITY_SELINUX_BOOTPARAM_VALUE=1
+CONFIG_SECURITY_SELINUX_DISABLE=y
+CONFIG_SECURITY_SELINUX_DEVELOP=y
+CONFIG_SECURITY_SELINUX_AVC_STATS=y
+CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE=1
+# CONFIG_SECURITY_SELINUX_ENABLE_SECMARK_DEFAULT is not set
+# CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX is not set
+CONFIG_KEYS_COMPAT=y
+
+#
+# Cryptographic options
+#
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_NULL=m
+CONFIG_CRYPTO_MD4=m
+CONFIG_CRYPTO_MD5=m
+CONFIG_CRYPTO_SHA1=y
+CONFIG_CRYPTO_SHA256=m
+CONFIG_CRYPTO_SHA512=m
+CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_TGR192=m
+CONFIG_CRYPTO_DES=m
+CONFIG_CRYPTO_BLOWFISH=m
+CONFIG_CRYPTO_TWOFISH=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_TEST is not set
+CONFIG_CRYPTO_SIGNATURE=y
+CONFIG_CRYPTO_SIGNATURE_DSA=y
+CONFIG_CRYPTO_MPILIB=y
+
+#
+# Hardware crypto devices
+#
diff --git a/configs/kernel-2.6.18-ppc64.config b/configs/kernel-2.6.18-ppc64.config
new file mode 100644
index 000000000..7b31ef807
--- /dev/null
+++ b/configs/kernel-2.6.18-ppc64.config
@@ -0,0 +1,3038 @@
+# powerpc
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.18.2-rc1
+# Mon Nov 13 09:44:42 2006
+#
+CONFIG_PPC64=y
+CONFIG_64BIT=y
+CONFIG_PPC_MERGE=y
+CONFIG_MMU=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_IRQ_PER_CPU=y
+CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_PPC=y
+CONFIG_EARLY_PRINTK=y
+CONFIG_COMPAT=y
+CONFIG_SYSVIPC_COMPAT=y
+CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
+CONFIG_ARCH_MAY_HAVE_PC_FDC=y
+CONFIG_PPC_OF=y
+CONFIG_PPC_UDBG_16550=y
+CONFIG_GENERIC_TBSYNC=y
+CONFIG_AUDIT_ARCH=y
+# CONFIG_DEFAULT_UIMAGE is not set
+
+#
+# Processor support
+#
+# CONFIG_POWER4_ONLY is not set
+CONFIG_POWER3=y
+CONFIG_POWER4=y
+CONFIG_PPC_FPU=y
+CONFIG_ALTIVEC=y
+CONFIG_PPC_STD_MMU=y
+CONFIG_VIRT_CPU_ACCOUNTING=y
+CONFIG_SMP=y
+CONFIG_NR_CPUS=128
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_BSD_PROCESS_ACCT=y
+# CONFIG_BSD_PROCESS_ACCT_V3 is not set
+CONFIG_TASKSTATS=y
+CONFIG_TASK_DELAY_ACCT=y
+CONFIG_AUDIT=y
+CONFIG_AUDITSYSCALL=y
+# CONFIG_IKCONFIG is not set
+CONFIG_CPUSETS=y
+CONFIG_RELAY=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+# CONFIG_EMBEDDED is not set
+CONFIG_SYSCTL=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
+CONFIG_KALLSYMS_EXTRA_PASS=y
+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=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+CONFIG_MODULE_SIG=y
+# CONFIG_MODULE_SIG_FORCE is not set
+CONFIG_KMOD=y
+CONFIG_STOP_MACHINE=y
+
+#
+# Process debugging support
+#
+CONFIG_UTRACE=y
+CONFIG_PTRACE=y
+
+#
+# Block layer
+#
+CONFIG_BLK_DEV_IO_TRACE=y
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_DEFAULT_AS is not set
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+
+#
+# Platform support
+#
+CONFIG_PPC_MULTIPLATFORM=y
+# CONFIG_PPC_ISERIES is not set
+# CONFIG_EMBEDDED6xx is not set
+# CONFIG_APUS is not set
+CONFIG_PPC_PSERIES=y
+CONFIG_PPC_PMAC=y
+CONFIG_PPC_PMAC64=y
+# CONFIG_PPC_MAPLE is not set
+CONFIG_PPC_CELL=y
+CONFIG_PPC_CELL_NATIVE=y
+CONFIG_PPC_IBM_CELL_BLADE=y
+CONFIG_UDBG_RTAS_CONSOLE=y
+CONFIG_MAMBO=y
+CONFIG_MAMBO_DISK=m
+CONFIG_MAMBO_NET=m
+CONFIG_XICS=y
+CONFIG_U3_DART=y
+CONFIG_PPC_RTAS=y
+CONFIG_RTAS_ERROR_LOGGING=y
+CONFIG_RTAS_PROC=y
+CONFIG_RTAS_FLASH=y
+CONFIG_MMIO_NVRAM=y
+CONFIG_MPIC_BROKEN_U3=y
+CONFIG_IBMVIO=y
+CONFIG_IBMEBUS=y
+# CONFIG_PPC_MPC106 is not set
+CONFIG_PPC_970_NAP=y
+CONFIG_CPU_FREQ=y
+CONFIG_CPU_FREQ_TABLE=y
+CONFIG_CPU_FREQ_DEBUG=y
+CONFIG_CPU_FREQ_STAT=m
+CONFIG_CPU_FREQ_STAT_DETAILS=y
+# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set
+CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE=y
+CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
+CONFIG_CPU_FREQ_GOV_POWERSAVE=m
+CONFIG_CPU_FREQ_GOV_USERSPACE=y
+CONFIG_CPU_FREQ_GOV_ONDEMAND=m
+CONFIG_CPU_FREQ_GOV_CONSERVATIVE=m
+CONFIG_CPU_FREQ_PMAC64=y
+# CONFIG_WANT_EARLY_SERIAL is not set
+CONFIG_MPIC=y
+
+#
+# Cell Broadband Engine options
+#
+CONFIG_SPU_FS=m
+CONFIG_SPU_BASE=y
+CONFIG_SPUFS_MMAP=y
+CONFIG_CBE_RAS=y
+
+#
+# Kernel options
+#
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
+# CONFIG_PREEMPT_NONE is not set
+CONFIG_PREEMPT_VOLUNTARY=y
+# CONFIG_PREEMPT is not set
+CONFIG_PREEMPT_BKL=y
+CONFIG_BINFMT_ELF=y
+CONFIG_BINFMT_MISC=y
+CONFIG_FORCE_MAX_ZONEORDER=9
+CONFIG_IOMMU_VMERGE=y
+CONFIG_HOTPLUG_CPU=y
+CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
+CONFIG_KEXEC=y
+# CONFIG_CRASH_DUMP is not set
+CONFIG_IRQ_ALL_CPUS=y
+CONFIG_PPC_SPLPAR=y
+CONFIG_EEH=y
+CONFIG_SCANLOG=y
+CONFIG_LPARCFG=y
+CONFIG_NUMA=y
+CONFIG_NODES_SHIFT=4
+CONFIG_ARCH_SELECT_MEMORY_MODEL=y
+CONFIG_ARCH_SPARSEMEM_ENABLE=y
+CONFIG_ARCH_SPARSEMEM_DEFAULT=y
+CONFIG_SELECT_MEMORY_MODEL=y
+# CONFIG_FLATMEM_MANUAL is not set
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+CONFIG_SPARSEMEM_MANUAL=y
+CONFIG_SPARSEMEM=y
+CONFIG_NEED_MULTIPLE_NODES=y
+CONFIG_HAVE_MEMORY_PRESENT=y
+# CONFIG_SPARSEMEM_STATIC is not set
+CONFIG_SPARSEMEM_EXTREME=y
+CONFIG_MEMORY_HOTPLUG=y
+CONFIG_SPLIT_PTLOCK_CPUS=4
+CONFIG_MIGRATION=y
+CONFIG_RESOURCES_64BIT=y
+CONFIG_HAVE_ARCH_EARLY_PFN_TO_NID=y
+CONFIG_ARCH_MEMORY_PROBE=y
+CONFIG_NODES_SPAN_OTHER_NODES=y
+CONFIG_PPC_64K_PAGES=y
+CONFIG_SCHED_SMT=y
+CONFIG_PROC_DEVICETREE=y
+# CONFIG_CMDLINE_BOOL is not set
+CONFIG_PM=y
+CONFIG_PM_LEGACY=y
+# CONFIG_PM_DEBUG is not set
+# CONFIG_SECCOMP is not set
+CONFIG_ISA_DMA_API=y
+
+#
+# Bus options
+#
+CONFIG_GENERIC_ISA_DMA=y
+# CONFIG_MPIC_WEIRD is not set
+CONFIG_PPC_I8259=y
+# CONFIG_PPC_INDIRECT_PCI is not set
+CONFIG_PCI=y
+CONFIG_PCI_DOMAINS=y
+CONFIG_PCIEPORTBUS=y
+# CONFIG_HOTPLUG_PCI_PCIE is not set
+# CONFIG_PCI_DEBUG is not set
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+CONFIG_PCCARD=y
+# CONFIG_PCMCIA_DEBUG is not set
+CONFIG_PCMCIA=y
+CONFIG_PCMCIA_LOAD_CIS=y
+CONFIG_PCMCIA_IOCTL=y
+CONFIG_CARDBUS=y
+
+#
+# PC-card bridges
+#
+CONFIG_YENTA=y
+CONFIG_YENTA_O2=y
+CONFIG_YENTA_RICOH=y
+CONFIG_YENTA_TI=y
+CONFIG_YENTA_ENE_TUNE=y
+CONFIG_YENTA_TOSHIBA=y
+CONFIG_PD6729=m
+CONFIG_I82092=m
+CONFIG_PCCARD_NONSTATIC=y
+
+#
+# PCI Hotplug Support
+#
+CONFIG_HOTPLUG_PCI=y
+CONFIG_HOTPLUG_PCI_FAKE=m
+# CONFIG_HOTPLUG_PCI_CPCI is not set
+CONFIG_HOTPLUG_PCI_SHPC=m
+CONFIG_HOTPLUG_PCI_SHPC_POLL_EVENT_MODE=y
+CONFIG_HOTPLUG_PCI_RPA=m
+CONFIG_HOTPLUG_PCI_RPA_DLPAR=m
+CONFIG_KERNEL_START=0xc000000000000000
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+# CONFIG_NETDEBUG is not set
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=y
+CONFIG_NET_KEY=m
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_ASK_IP_FIB_HASH=y
+# 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
+# CONFIG_IP_PNP is not set
+CONFIG_NET_IPIP=m
+CONFIG_NET_IPGRE=m
+CONFIG_NET_IPGRE_BROADCAST=y
+CONFIG_IP_MROUTE=y
+CONFIG_IP_PIMSM_V1=y
+CONFIG_IP_PIMSM_V2=y
+# CONFIG_ARPD is not set
+CONFIG_SYN_COOKIES=y
+CONFIG_INET_AH=m
+CONFIG_INET_ESP=m
+CONFIG_INET_IPCOMP=m
+CONFIG_INET_XFRM_TUNNEL=m
+CONFIG_INET_TUNNEL=m
+CONFIG_INET_XFRM_MODE_TRANSPORT=m
+CONFIG_INET_XFRM_MODE_TUNNEL=m
+CONFIG_INET_DIAG=m
+CONFIG_INET_TCP_DIAG=m
+CONFIG_TCP_CONG_ADVANCED=y
+
+#
+# TCP congestion control
+#
+CONFIG_TCP_CONG_BIC=y
+CONFIG_TCP_CONG_CUBIC=m
+CONFIG_TCP_CONG_WESTWOOD=m
+CONFIG_TCP_CONG_HTCP=m
+CONFIG_TCP_CONG_HSTCP=m
+CONFIG_TCP_CONG_HYBLA=m
+CONFIG_TCP_CONG_VEGAS=m
+CONFIG_TCP_CONG_SCALABLE=m
+CONFIG_TCP_CONG_LP=m
+CONFIG_TCP_CONG_VENO=m
+
+#
+# IP: Virtual Server Configuration
+#
+CONFIG_IP_VS=m
+# CONFIG_IP_VS_DEBUG is not set
+CONFIG_IP_VS_TAB_BITS=12
+
+#
+# IPVS transport protocol load balancing support
+#
+CONFIG_IP_VS_PROTO_TCP=y
+CONFIG_IP_VS_PROTO_UDP=y
+CONFIG_IP_VS_PROTO_ESP=y
+CONFIG_IP_VS_PROTO_AH=y
+
+#
+# IPVS scheduler
+#
+CONFIG_IP_VS_RR=m
+CONFIG_IP_VS_WRR=m
+CONFIG_IP_VS_LC=m
+CONFIG_IP_VS_WLC=m
+CONFIG_IP_VS_LBLC=m
+CONFIG_IP_VS_LBLCR=m
+CONFIG_IP_VS_DH=m
+CONFIG_IP_VS_SH=m
+CONFIG_IP_VS_SED=m
+CONFIG_IP_VS_NQ=m
+
+#
+# IPVS application helper
+#
+CONFIG_IP_VS_FTP=m
+CONFIG_IPV6=m
+CONFIG_IPV6_PRIVACY=y
+CONFIG_IPV6_ROUTER_PREF=y
+CONFIG_IPV6_ROUTE_INFO=y
+CONFIG_INET6_AH=m
+CONFIG_INET6_ESP=m
+CONFIG_INET6_IPCOMP=m
+CONFIG_INET6_XFRM_TUNNEL=m
+CONFIG_INET6_TUNNEL=m
+CONFIG_INET6_XFRM_MODE_TRANSPORT=m
+CONFIG_INET6_XFRM_MODE_TUNNEL=m
+CONFIG_IPV6_TUNNEL=m
+CONFIG_NETWORK_SECMARK=y
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_DEBUG is not set
+CONFIG_BRIDGE_NETFILTER=y
+
+#
+# Core Netfilter Configuration
+#
+CONFIG_NETFILTER_NETLINK=m
+CONFIG_NETFILTER_NETLINK_QUEUE=m
+CONFIG_NETFILTER_NETLINK_LOG=m
+CONFIG_NETFILTER_XTABLES=m
+CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
+CONFIG_NETFILTER_XT_TARGET_CONNMARK=m
+CONFIG_NETFILTER_XT_TARGET_MARK=m
+CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
+CONFIG_NETFILTER_XT_TARGET_NOTRACK=m
+CONFIG_NETFILTER_XT_TARGET_SECMARK=m
+CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=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_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_PHYSDEV=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
+
+#
+# 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=m
+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_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_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_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
+CONFIG_IP_NF_ARPTABLES=m
+CONFIG_IP_NF_ARPFILTER=m
+CONFIG_IP_NF_ARP_MANGLE=m
+
+#
+# IPv6: Netfilter Configuration (EXPERIMENTAL)
+#
+CONFIG_IP6_NF_QUEUE=m
+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_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
+
+#
+# DECnet: Netfilter Configuration
+#
+# CONFIG_DECNET_NF_GRABULATOR is not set
+
+#
+# Bridge: Netfilter Configuration
+#
+CONFIG_BRIDGE_NF_EBTABLES=m
+CONFIG_BRIDGE_EBT_BROUTE=m
+CONFIG_BRIDGE_EBT_T_FILTER=m
+CONFIG_BRIDGE_EBT_T_NAT=m
+CONFIG_BRIDGE_EBT_802_3=m
+CONFIG_BRIDGE_EBT_AMONG=m
+CONFIG_BRIDGE_EBT_ARP=m
+CONFIG_BRIDGE_EBT_IP=m
+CONFIG_BRIDGE_EBT_LIMIT=m
+CONFIG_BRIDGE_EBT_MARK=m
+CONFIG_BRIDGE_EBT_PKTTYPE=m
+CONFIG_BRIDGE_EBT_STP=m
+CONFIG_BRIDGE_EBT_VLAN=m
+CONFIG_BRIDGE_EBT_ARPREPLY=m
+CONFIG_BRIDGE_EBT_DNAT=m
+CONFIG_BRIDGE_EBT_MARK_T=m
+CONFIG_BRIDGE_EBT_REDIRECT=m
+CONFIG_BRIDGE_EBT_SNAT=m
+CONFIG_BRIDGE_EBT_LOG=m
+CONFIG_BRIDGE_EBT_ULOG=m
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+CONFIG_IP_DCCP=m
+CONFIG_INET_DCCP_DIAG=m
+CONFIG_IP_DCCP_ACKVEC=y
+
+#
+# DCCP CCIDs Configuration (EXPERIMENTAL)
+#
+CONFIG_IP_DCCP_CCID2=m
+CONFIG_IP_DCCP_CCID3=m
+CONFIG_IP_DCCP_TFRC_LIB=m
+
+#
+# DCCP Kernel Hacking
+#
+# CONFIG_IP_DCCP_DEBUG is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+CONFIG_IP_SCTP=m
+# CONFIG_SCTP_DBG_MSG is not set
+# CONFIG_SCTP_DBG_OBJCNT is not set
+# CONFIG_SCTP_HMAC_NONE is not set
+# CONFIG_SCTP_HMAC_SHA1 is not set
+CONFIG_SCTP_HMAC_MD5=y
+
+#
+# TIPC Configuration (EXPERIMENTAL)
+#
+CONFIG_TIPC=m
+# CONFIG_TIPC_ADVANCED is not set
+# CONFIG_TIPC_DEBUG is not set
+CONFIG_ATM=m
+CONFIG_ATM_CLIP=m
+# CONFIG_ATM_CLIP_NO_ICMP is not set
+CONFIG_ATM_LANE=m
+# CONFIG_ATM_MPOA is not set
+CONFIG_ATM_BR2684=m
+# CONFIG_ATM_BR2684_IPFILTER is not set
+CONFIG_BRIDGE=m
+CONFIG_VLAN_8021Q=m
+CONFIG_DECNET=m
+CONFIG_DECNET_ROUTER=y
+CONFIG_DECNET_ROUTE_FWMARK=y
+CONFIG_LLC=y
+# CONFIG_LLC2 is not set
+CONFIG_IPX=m
+# CONFIG_IPX_INTERN is not set
+CONFIG_ATALK=m
+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_ECONET is not set
+CONFIG_WAN_ROUTER=m
+
+#
+# QoS and/or fair queueing
+#
+CONFIG_NET_SCHED=y
+# CONFIG_NET_SCH_CLK_JIFFIES is not set
+CONFIG_NET_SCH_CLK_GETTIMEOFDAY=y
+# CONFIG_NET_SCH_CLK_CPU is not set
+
+#
+# Queueing/Scheduling
+#
+CONFIG_NET_SCH_CBQ=m
+CONFIG_NET_SCH_HTB=m
+CONFIG_NET_SCH_HFSC=m
+CONFIG_NET_SCH_ATM=m
+CONFIG_NET_SCH_PRIO=m
+CONFIG_NET_SCH_RED=m
+CONFIG_NET_SCH_SFQ=m
+CONFIG_NET_SCH_TEQL=m
+CONFIG_NET_SCH_TBF=m
+CONFIG_NET_SCH_GRED=m
+CONFIG_NET_SCH_DSMARK=m
+CONFIG_NET_SCH_NETEM=m
+CONFIG_NET_SCH_INGRESS=m
+
+#
+# Classification
+#
+CONFIG_NET_CLS=y
+CONFIG_NET_CLS_BASIC=m
+CONFIG_NET_CLS_TCINDEX=m
+CONFIG_NET_CLS_ROUTE4=m
+CONFIG_NET_CLS_ROUTE=y
+CONFIG_NET_CLS_FW=m
+CONFIG_NET_CLS_U32=m
+CONFIG_CLS_U32_PERF=y
+CONFIG_CLS_U32_MARK=y
+CONFIG_NET_CLS_RSVP=m
+CONFIG_NET_CLS_RSVP6=m
+CONFIG_NET_EMATCH=y
+CONFIG_NET_EMATCH_STACK=32
+CONFIG_NET_EMATCH_CMP=m
+CONFIG_NET_EMATCH_NBYTE=m
+CONFIG_NET_EMATCH_U32=m
+CONFIG_NET_EMATCH_META=m
+CONFIG_NET_EMATCH_TEXT=m
+CONFIG_NET_CLS_ACT=y
+CONFIG_NET_ACT_POLICE=m
+CONFIG_NET_ACT_GACT=m
+CONFIG_GACT_PROB=y
+CONFIG_NET_ACT_MIRRED=m
+CONFIG_NET_ACT_IPT=m
+CONFIG_NET_ACT_PEDIT=m
+CONFIG_NET_ACT_SIMP=m
+CONFIG_NET_CLS_IND=y
+CONFIG_NET_ESTIMATOR=y
+
+#
+# Network testing
+#
+CONFIG_NET_PKTGEN=m
+# CONFIG_NET_TCPPROBE is not set
+# CONFIG_HAMRADIO is not set
+CONFIG_IRDA=m
+
+#
+# IrDA protocols
+#
+CONFIG_IRLAN=m
+CONFIG_IRNET=m
+CONFIG_IRCOMM=m
+# CONFIG_IRDA_ULTRA is not set
+
+#
+# IrDA options
+#
+CONFIG_IRDA_CACHE_LAST_LSAP=y
+CONFIG_IRDA_FAST_RR=y
+# CONFIG_IRDA_DEBUG is not set
+
+#
+# Infrared-port device drivers
+#
+
+#
+# SIR device drivers
+#
+CONFIG_IRTTY_SIR=m
+
+#
+# Dongle support
+#
+CONFIG_DONGLE=y
+CONFIG_ESI_DONGLE=m
+CONFIG_ACTISYS_DONGLE=m
+CONFIG_TEKRAM_DONGLE=m
+CONFIG_TOIM3232_DONGLE=m
+CONFIG_LITELINK_DONGLE=m
+CONFIG_MA600_DONGLE=m
+CONFIG_GIRBIL_DONGLE=m
+CONFIG_MCP2120_DONGLE=m
+CONFIG_OLD_BELKIN_DONGLE=m
+CONFIG_ACT200L_DONGLE=m
+
+#
+# Old SIR device drivers
+#
+
+#
+# Old Serial dongle support
+#
+
+#
+# FIR device drivers
+#
+CONFIG_USB_IRDA=m
+CONFIG_SIGMATEL_FIR=m
+CONFIG_NSC_FIR=m
+CONFIG_WINBOND_FIR=m
+CONFIG_SMC_IRCC_FIR=m
+CONFIG_ALI_FIR=m
+CONFIG_VLSI_FIR=m
+CONFIG_VIA_FIR=m
+CONFIG_MCS_FIR=m
+CONFIG_BT=m
+CONFIG_BT_L2CAP=m
+CONFIG_BT_SCO=m
+CONFIG_BT_RFCOMM=m
+CONFIG_BT_RFCOMM_TTY=y
+CONFIG_BT_BNEP=m
+CONFIG_BT_BNEP_MC_FILTER=y
+CONFIG_BT_BNEP_PROTO_FILTER=y
+CONFIG_BT_CMTP=m
+CONFIG_BT_HIDP=m
+
+#
+# Bluetooth device drivers
+#
+CONFIG_BT_HCIUSB=m
+CONFIG_BT_HCIUSB_SCO=y
+CONFIG_BT_HCIUART=m
+CONFIG_BT_HCIUART_H4=y
+CONFIG_BT_HCIUART_BCSP=y
+CONFIG_BT_HCIBCM203X=m
+CONFIG_BT_HCIBPA10X=m
+CONFIG_BT_HCIBFUSB=m
+CONFIG_BT_HCIDTL1=m
+CONFIG_BT_HCIBT3C=m
+CONFIG_BT_HCIBLUECARD=m
+CONFIG_BT_HCIBTUART=m
+CONFIG_BT_HCIVHCI=m
+CONFIG_IEEE80211=m
+CONFIG_IEEE80211_DEBUG=y
+CONFIG_IEEE80211_CRYPT_WEP=m
+CONFIG_IEEE80211_CRYPT_CCMP=m
+CONFIG_IEEE80211_CRYPT_TKIP=m
+CONFIG_IEEE80211_SOFTMAC=m
+CONFIG_IEEE80211_SOFTMAC_DEBUG=y
+CONFIG_TUX=m
+
+#
+# TUX options
+#
+CONFIG_TUX_EXTCGI=y
+CONFIG_TUX_EXTENDED_LOG=y
+# CONFIG_TUX_DEBUG is not set
+CONFIG_WIRELESS_EXT=y
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_SYS_HYPERVISOR is not set
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+CONFIG_CONNECTOR=y
+CONFIG_PROC_EVENTS=y
+
+#
+# Memory Technology Devices (MTD)
+#
+CONFIG_MTD=m
+# CONFIG_MTD_DEBUG is not set
+CONFIG_MTD_CONCAT=m
+CONFIG_MTD_PARTITIONS=y
+CONFIG_MTD_REDBOOT_PARTS=m
+CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1
+# CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED is not set
+# CONFIG_MTD_REDBOOT_PARTS_READONLY is not set
+CONFIG_MTD_CMDLINE_PARTS=y
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=m
+CONFIG_MTD_BLOCK=m
+CONFIG_MTD_BLOCK_RO=m
+CONFIG_FTL=m
+CONFIG_NFTL=m
+CONFIG_NFTL_RW=y
+CONFIG_INFTL=m
+CONFIG_RFD_FTL=m
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=m
+CONFIG_MTD_JEDECPROBE=m
+CONFIG_MTD_GEN_PROBE=m
+# CONFIG_MTD_CFI_ADV_OPTIONS 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_CFI_INTELEXT=m
+CONFIG_MTD_CFI_AMDSTD=m
+CONFIG_MTD_CFI_STAA=m
+CONFIG_MTD_CFI_UTIL=m
+CONFIG_MTD_RAM=m
+CONFIG_MTD_ROM=m
+CONFIG_MTD_ABSENT=m
+# CONFIG_MTD_OBSOLETE_CHIPS is not set
+
+#
+# Mapping drivers for chip access
+#
+CONFIG_MTD_COMPLEX_MAPPINGS=y
+# CONFIG_MTD_PHYSMAP is not set
+CONFIG_MTD_PCI=m
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+CONFIG_MTD_PMC551=m
+# CONFIG_MTD_PMC551_BUGFIX is not set
+# CONFIG_MTD_PMC551_DEBUG is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+CONFIG_MTD_MTDRAM=m
+CONFIG_MTDRAM_TOTAL_SIZE=4096
+CONFIG_MTDRAM_ERASE_SIZE=128
+CONFIG_MTD_BLOCK2MTD=m
+
+#
+# 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=m
+# CONFIG_MTD_NAND_VERIFY_WRITE is not set
+CONFIG_MTD_NAND_ECC_SMC=y
+CONFIG_MTD_NAND_IDS=m
+CONFIG_MTD_NAND_DISKONCHIP=m
+# CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADVANCED is not set
+CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADDRESS=0
+# CONFIG_MTD_NAND_DISKONCHIP_BBTWRITE is not set
+CONFIG_MTD_NAND_NANDSIM=m
+
+#
+# OneNAND Flash Device Drivers
+#
+# CONFIG_MTD_ONENAND is not set
+
+#
+# Parallel port support
+#
+CONFIG_PARPORT=m
+CONFIG_PARPORT_PC=m
+CONFIG_PARPORT_SERIAL=m
+# CONFIG_PARPORT_PC_FIFO is not set
+# CONFIG_PARPORT_PC_SUPERIO is not set
+CONFIG_PARPORT_PC_PCMCIA=m
+CONFIG_PARPORT_NOT_PC=y
+# CONFIG_PARPORT_GSC is not set
+# CONFIG_PARPORT_AX88796 is not set
+CONFIG_PARPORT_1284=y
+
+#
+# Plug and Play support
+#
+
+#
+# Block devices
+#
+CONFIG_BLK_DEV_FD=m
+CONFIG_PARIDE=m
+CONFIG_PARIDE_PARPORT=m
+
+#
+# Parallel IDE high-level drivers
+#
+CONFIG_PARIDE_PD=m
+CONFIG_PARIDE_PCD=m
+CONFIG_PARIDE_PF=m
+CONFIG_PARIDE_PT=m
+CONFIG_PARIDE_PG=m
+
+#
+# Parallel IDE protocol modules
+#
+CONFIG_PARIDE_ATEN=m
+CONFIG_PARIDE_BPCK=m
+CONFIG_PARIDE_COMM=m
+CONFIG_PARIDE_DSTR=m
+CONFIG_PARIDE_FIT2=m
+CONFIG_PARIDE_FIT3=m
+CONFIG_PARIDE_EPAT=m
+CONFIG_PARIDE_EPATC8=y
+CONFIG_PARIDE_EPIA=m
+CONFIG_PARIDE_FRIQ=m
+CONFIG_PARIDE_FRPW=m
+CONFIG_PARIDE_KBIC=m
+CONFIG_PARIDE_KTTI=m
+CONFIG_PARIDE_ON20=m
+CONFIG_PARIDE_ON26=m
+# CONFIG_BLK_CPQ_DA is not set
+CONFIG_BLK_CPQ_CISS_DA=m
+CONFIG_CISS_SCSI_TAPE=y
+CONFIG_BLK_DEV_DAC960=m
+CONFIG_BLK_DEV_UMEM=m
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=m
+CONFIG_BLK_DEV_CRYPTOLOOP=m
+CONFIG_BLK_DEV_NBD=m
+CONFIG_BLK_DEV_SX8=m
+CONFIG_BLK_DEV_UB=m
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=16384
+CONFIG_BLK_DEV_RAM_BLOCKSIZE=4096
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_CDROM_PKTCDVD=m
+CONFIG_CDROM_PKTCDVD_BUFFERS=8
+# CONFIG_CDROM_PKTCDVD_WCACHE is not set
+CONFIG_ATA_OVER_ETH=m
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+CONFIG_IDE=y
+CONFIG_BLK_DEV_IDE=y
+
+#
+# Please see Documentation/ide.txt for help/info on IDE drives
+#
+# CONFIG_BLK_DEV_IDE_SATA is not set
+CONFIG_BLK_DEV_IDEDISK=y
+CONFIG_IDEDISK_MULTI_MODE=y
+CONFIG_BLK_DEV_IDECS=m
+CONFIG_BLK_DEV_IDECD=m
+# CONFIG_BLK_DEV_IDETAPE is not set
+CONFIG_BLK_DEV_IDEFLOPPY=y
+CONFIG_BLK_DEV_IDESCSI=m
+CONFIG_IDE_TASK_IOCTL=y
+
+#
+# IDE chipset support/bugfixes
+#
+CONFIG_IDE_GENERIC=y
+CONFIG_BLK_DEV_IDEPCI=y
+CONFIG_IDEPCI_SHARE_IRQ=y
+# CONFIG_BLK_DEV_OFFBOARD is not set
+CONFIG_BLK_DEV_GENERIC=y
+# CONFIG_BLK_DEV_OPTI621 is not set
+CONFIG_BLK_DEV_SL82C105=y
+CONFIG_BLK_DEV_IDEDMA_PCI=y
+# CONFIG_BLK_DEV_IDEDMA_FORCED is not set
+CONFIG_IDEDMA_PCI_AUTO=y
+# CONFIG_IDEDMA_ONLYDISK is not set
+CONFIG_BLK_DEV_AEC62XX=y
+CONFIG_BLK_DEV_ALI15X3=y
+# CONFIG_WDC_ALI15X3 is not set
+CONFIG_BLK_DEV_AMD74XX=y
+CONFIG_BLK_DEV_CMD64X=y
+CONFIG_BLK_DEV_TRIFLEX=y
+# CONFIG_BLK_DEV_CY82C693 is not set
+CONFIG_BLK_DEV_CS5520=y
+CONFIG_BLK_DEV_CS5530=y
+CONFIG_BLK_DEV_HPT34X=y
+# CONFIG_HPT34X_AUTODMA is not set
+CONFIG_BLK_DEV_HPT366=y
+# CONFIG_BLK_DEV_SC1200 is not set
+CONFIG_BLK_DEV_PIIX=y
+CONFIG_BLK_DEV_IT821X=y
+# CONFIG_BLK_DEV_NS87415 is not set
+CONFIG_BLK_DEV_PDC202XX_OLD=y
+# CONFIG_PDC202XX_BURST is not set
+CONFIG_BLK_DEV_PDC202XX_NEW=y
+CONFIG_BLK_DEV_SVWKS=y
+CONFIG_BLK_DEV_SIIMAGE=y
+# CONFIG_BLK_DEV_SLC90E66 is not set
+# CONFIG_BLK_DEV_TRM290 is not set
+CONFIG_BLK_DEV_VIA82CXXX=y
+CONFIG_BLK_DEV_IDE_PMAC=y
+CONFIG_BLK_DEV_IDE_PMAC_ATA100FIRST=y
+CONFIG_BLK_DEV_IDEDMA_PMAC=y
+# CONFIG_IDE_ARM is not set
+CONFIG_BLK_DEV_IDEDMA=y
+# CONFIG_IDEDMA_IVB is not set
+CONFIG_IDEDMA_AUTO=y
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# SCSI device support
+#
+CONFIG_RAID_ATTRS=m
+CONFIG_SCSI=m
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=m
+CONFIG_CHR_DEV_ST=m
+CONFIG_CHR_DEV_OSST=m
+CONFIG_BLK_DEV_SR=m
+CONFIG_BLK_DEV_SR_VENDOR=y
+CONFIG_CHR_DEV_SG=m
+CONFIG_CHR_DEV_SCH=m
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+CONFIG_SCSI_MULTI_LUN=y
+CONFIG_SCSI_CONSTANTS=y
+CONFIG_SCSI_LOGGING=y
+
+#
+# SCSI Transport Attributes
+#
+CONFIG_SCSI_SPI_ATTRS=m
+CONFIG_SCSI_FC_ATTRS=m
+CONFIG_SCSI_ISCSI_ATTRS=m
+CONFIG_SCSI_SAS_ATTRS=m
+
+#
+# SCSI low-level drivers
+#
+CONFIG_ISCSI_TCP=m
+CONFIG_BLK_DEV_3W_XXXX_RAID=m
+CONFIG_SCSI_3W_9XXX=m
+CONFIG_SCSI_ACARD=m
+CONFIG_SCSI_AACRAID=m
+CONFIG_SCSI_AIC7XXX=m
+CONFIG_AIC7XXX_CMDS_PER_DEVICE=4
+CONFIG_AIC7XXX_RESET_DELAY_MS=15000
+# CONFIG_AIC7XXX_DEBUG_ENABLE is not set
+CONFIG_AIC7XXX_DEBUG_MASK=0
+# CONFIG_AIC7XXX_REG_PRETTY_PRINT is not set
+CONFIG_SCSI_AIC7XXX_OLD=m
+CONFIG_SCSI_AIC79XX=m
+CONFIG_AIC79XX_CMDS_PER_DEVICE=4
+CONFIG_AIC79XX_RESET_DELAY_MS=15000
+# CONFIG_AIC79XX_ENABLE_RD_STRM is not set
+# CONFIG_AIC79XX_DEBUG_ENABLE is not set
+CONFIG_AIC79XX_DEBUG_MASK=0
+# CONFIG_AIC79XX_REG_PRETTY_PRINT is not set
+CONFIG_MEGARAID_NEWGEN=y
+CONFIG_MEGARAID_MM=m
+CONFIG_MEGARAID_MAILBOX=m
+CONFIG_MEGARAID_LEGACY=m
+CONFIG_MEGARAID_SAS=m
+CONFIG_SCSI_SATA=m
+CONFIG_SCSI_SATA_AHCI=m
+CONFIG_SCSI_SATA_SVW=m
+CONFIG_SCSI_ATA_PIIX=m
+CONFIG_SCSI_SATA_MV=m
+CONFIG_SCSI_SATA_NV=m
+CONFIG_SCSI_PDC_ADMA=m
+CONFIG_SCSI_HPTIOP=m
+CONFIG_SCSI_SATA_QSTOR=m
+CONFIG_SCSI_SATA_PROMISE=m
+CONFIG_SCSI_SATA_SX4=m
+CONFIG_SCSI_SATA_SIL=m
+CONFIG_SCSI_SATA_SIL24=m
+CONFIG_SCSI_SATA_SIS=m
+CONFIG_SCSI_SATA_ULI=m
+CONFIG_SCSI_SATA_VIA=m
+CONFIG_SCSI_SATA_VITESSE=m
+CONFIG_SCSI_SATA_INTEL_COMBINED=y
+# CONFIG_SCSI_BUSLOGIC is not set
+# CONFIG_SCSI_DMX3191D is not set
+# CONFIG_SCSI_EATA is not set
+# CONFIG_SCSI_FUTURE_DOMAIN is not set
+CONFIG_SCSI_GDTH=m
+CONFIG_SCSI_IPS=m
+CONFIG_SCSI_IBMVSCSI=m
+CONFIG_SCSI_INITIO=m
+CONFIG_SCSI_INIA100=m
+CONFIG_SCSI_PPA=m
+CONFIG_SCSI_IMM=m
+# CONFIG_SCSI_IZIP_EPP16 is not set
+# CONFIG_SCSI_IZIP_SLOW_CTR is not set
+CONFIG_SCSI_SYM53C8XX_2=m
+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=m
+CONFIG_SCSI_IPR_TRACE=y
+CONFIG_SCSI_IPR_DUMP=y
+CONFIG_SCSI_QLOGIC_1280=m
+CONFIG_SCSI_QLA_FC=m
+CONFIG_SCSI_LPFC=m
+CONFIG_SCSI_DC395x=m
+# CONFIG_SCSI_DC390T is not set
+# CONFIG_SCSI_DEBUG is not set
+
+#
+# PCMCIA SCSI adapter support
+#
+# CONFIG_PCMCIA_FDOMAIN is not set
+CONFIG_PCMCIA_QLOGIC=m
+CONFIG_PCMCIA_SYM53C500=m
+
+#
+# Multi-device support (RAID and LVM)
+#
+CONFIG_MD=y
+CONFIG_BLK_DEV_MD=y
+CONFIG_MD_LINEAR=m
+CONFIG_MD_RAID0=m
+CONFIG_MD_RAID1=m
+CONFIG_MD_RAID10=m
+CONFIG_MD_RAID456=m
+CONFIG_MD_RAID5_RESHAPE=y
+CONFIG_MD_MULTIPATH=m
+CONFIG_MD_FAULTY=m
+CONFIG_BLK_DEV_DM=m
+CONFIG_DM_CRYPT=m
+CONFIG_DM_SNAPSHOT=m
+CONFIG_DM_MIRROR=m
+CONFIG_DM_ZERO=m
+CONFIG_DM_MULTIPATH=m
+CONFIG_DM_MULTIPATH_EMC=m
+
+#
+# Fusion MPT device support
+#
+CONFIG_FUSION=y
+CONFIG_FUSION_SPI=m
+CONFIG_FUSION_FC=m
+CONFIG_FUSION_SAS=m
+CONFIG_FUSION_MAX_SGE=40
+CONFIG_FUSION_CTL=m
+CONFIG_FUSION_LAN=m
+
+#
+# IEEE 1394 (FireWire) support
+#
+CONFIG_IEEE1394=m
+
+#
+# Subsystem Options
+#
+# CONFIG_IEEE1394_VERBOSEDEBUG is not set
+CONFIG_IEEE1394_OUI_DB=y
+CONFIG_IEEE1394_EXTRA_CONFIG_ROMS=y
+CONFIG_IEEE1394_CONFIG_ROM_IP1394=y
+# CONFIG_IEEE1394_EXPORT_FULL_API is not set
+
+#
+# Device Drivers
+#
+CONFIG_IEEE1394_PCILYNX=m
+CONFIG_IEEE1394_OHCI1394=m
+
+#
+# Protocol Drivers
+#
+CONFIG_IEEE1394_VIDEO1394=m
+CONFIG_IEEE1394_SBP2=m
+CONFIG_IEEE1394_ETH1394=m
+CONFIG_IEEE1394_DV1394=m
+CONFIG_IEEE1394_RAWIO=m
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+
+#
+# Macintosh device drivers
+#
+CONFIG_ADB_PMU=y
+CONFIG_ADB_PMU_LED=y
+CONFIG_ADB_PMU_LED_IDE=y
+CONFIG_PMAC_SMU=y
+CONFIG_THERM_PM72=y
+CONFIG_WINDFARM=y
+CONFIG_WINDFARM_PM81=y
+CONFIG_WINDFARM_PM91=y
+CONFIG_WINDFARM_PM112=y
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+CONFIG_IFB=m
+CONFIG_DUMMY=m
+CONFIG_BONDING=m
+CONFIG_EQUALIZER=m
+CONFIG_TUN=m
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+
+#
+# PHY device support
+#
+CONFIG_PHYLIB=m
+
+#
+# MII PHY device drivers
+#
+CONFIG_MARVELL_PHY=m
+CONFIG_DAVICOM_PHY=m
+CONFIG_QSEMI_PHY=m
+CONFIG_LXT_PHY=m
+CONFIG_CICADA_PHY=m
+CONFIG_VITESSE_PHY=m
+CONFIG_SMSC_PHY=m
+CONFIG_FIXED_PHY=m
+CONFIG_FIXED_MII_10_FDX=y
+CONFIG_FIXED_MII_100_FDX=y
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=m
+CONFIG_HAPPYMEAL=m
+CONFIG_SUNGEM=m
+CONFIG_CASSINI=m
+CONFIG_NET_VENDOR_3COM=y
+CONFIG_VORTEX=m
+CONFIG_TYPHOON=m
+
+#
+# Tulip family network device support
+#
+CONFIG_NET_TULIP=y
+CONFIG_DE2104X=m
+CONFIG_TULIP=m
+# CONFIG_TULIP_MWI is not set
+CONFIG_TULIP_MMIO=y
+# CONFIG_TULIP_NAPI is not set
+CONFIG_DE4X5=m
+CONFIG_WINBOND_840=m
+CONFIG_DM9102=m
+CONFIG_ULI526X=m
+CONFIG_PCMCIA_XIRCOM=m
+# CONFIG_HP100 is not set
+CONFIG_IBMVETH=m
+CONFIG_NET_PCI=y
+CONFIG_PCNET32=m
+CONFIG_AMD8111_ETH=m
+CONFIG_AMD8111E_NAPI=y
+CONFIG_ADAPTEC_STARFIRE=m
+CONFIG_ADAPTEC_STARFIRE_NAPI=y
+CONFIG_B44=m
+CONFIG_FORCEDETH=m
+# CONFIG_DGRS is not set
+# CONFIG_EEPRO100 is not set
+CONFIG_E100=m
+CONFIG_FEALNX=m
+CONFIG_NATSEMI=m
+CONFIG_NE2K_PCI=m
+CONFIG_8139CP=m
+CONFIG_8139TOO=m
+# CONFIG_8139TOO_PIO is not set
+# CONFIG_8139TOO_TUNE_TWISTER is not set
+CONFIG_8139TOO_8129=y
+# CONFIG_8139_OLD_RX_RESET is not set
+CONFIG_SIS900=m
+CONFIG_EPIC100=m
+CONFIG_SUNDANCE=m
+# CONFIG_SUNDANCE_MMIO is not set
+CONFIG_VIA_RHINE=m
+CONFIG_VIA_RHINE_MMIO=y
+CONFIG_VIA_RHINE_NAPI=y
+CONFIG_NET_POCKET=y
+CONFIG_DE600=m
+CONFIG_DE620=m
+
+#
+# Ethernet (1000 Mbit)
+#
+CONFIG_ACENIC=m
+# CONFIG_ACENIC_OMIT_TIGON_I is not set
+CONFIG_DL2K=m
+CONFIG_E1000=m
+CONFIG_E1000_NAPI=y
+# CONFIG_E1000_DISABLE_PACKET_SPLIT is not set
+CONFIG_NS83820=m
+CONFIG_HAMACHI=m
+CONFIG_YELLOWFIN=m
+CONFIG_R8169=m
+CONFIG_R8169_NAPI=y
+CONFIG_R8169_VLAN=y
+CONFIG_SIS190=m
+CONFIG_SKGE=m
+CONFIG_SKY2=m
+# CONFIG_SK98LIN is not set
+CONFIG_VIA_VELOCITY=m
+CONFIG_TIGON3=m
+CONFIG_BNX2=m
+CONFIG_SPIDER_NET=m
+# CONFIG_MV643XX_ETH is not set
+
+#
+# Ethernet (10000 Mbit)
+#
+CONFIG_CHELSIO_T1=m
+CONFIG_IXGB=m
+CONFIG_IXGB_NAPI=y
+CONFIG_S2IO=m
+CONFIG_S2IO_NAPI=y
+CONFIG_MYRI10GE=m
+
+#
+# Token Ring devices
+#
+CONFIG_TR=y
+CONFIG_IBMOL=m
+CONFIG_3C359=m
+# CONFIG_TMS380TR is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+CONFIG_NET_RADIO=y
+CONFIG_NET_WIRELESS_RTNETLINK=y
+
+#
+# Obsolete Wireless cards support (pre-802.11)
+#
+# CONFIG_STRIP is not set
+CONFIG_PCMCIA_WAVELAN=m
+CONFIG_PCMCIA_NETWAVE=m
+
+#
+# Wireless 802.11 Frequency Hopping cards support
+#
+# CONFIG_PCMCIA_RAYCS is not set
+
+#
+# Wireless 802.11b ISA/PCI cards support
+#
+# CONFIG_IPW2100 is not set
+# CONFIG_IPW2200 is not set
+CONFIG_AIRO=m
+CONFIG_HERMES=m
+CONFIG_APPLE_AIRPORT=m
+CONFIG_PLX_HERMES=m
+CONFIG_TMD_HERMES=m
+CONFIG_NORTEL_HERMES=m
+CONFIG_PCI_HERMES=m
+CONFIG_ATMEL=m
+CONFIG_PCI_ATMEL=m
+
+#
+# Wireless 802.11b Pcmcia/Cardbus cards support
+#
+CONFIG_PCMCIA_HERMES=m
+CONFIG_PCMCIA_SPECTRUM=m
+CONFIG_AIRO_CS=m
+CONFIG_PCMCIA_ATMEL=m
+CONFIG_PCMCIA_WL3501=m
+
+#
+# Prism GT/Duette 802.11(a/b/g) PCI/Cardbus support
+#
+CONFIG_PRISM54=m
+CONFIG_USB_ZD1201=m
+CONFIG_HOSTAP=m
+CONFIG_HOSTAP_FIRMWARE=y
+CONFIG_HOSTAP_FIRMWARE_NVRAM=y
+CONFIG_HOSTAP_PLX=m
+CONFIG_HOSTAP_PCI=m
+CONFIG_HOSTAP_CS=m
+CONFIG_BCM43XX=m
+CONFIG_BCM43XX_DEBUG=y
+CONFIG_BCM43XX_DMA=y
+CONFIG_BCM43XX_PIO=y
+CONFIG_BCM43XX_DMA_AND_PIO_MODE=y
+# CONFIG_BCM43XX_DMA_MODE is not set
+# CONFIG_BCM43XX_PIO_MODE is not set
+CONFIG_ZD1211RW=m
+# CONFIG_ZD1211RW_DEBUG is not set
+CONFIG_NET_WIRELESS=y
+
+#
+# PCMCIA network device support
+#
+CONFIG_NET_PCMCIA=y
+CONFIG_PCMCIA_3C589=m
+CONFIG_PCMCIA_3C574=m
+CONFIG_PCMCIA_FMVJ18X=m
+CONFIG_PCMCIA_PCNET=m
+CONFIG_PCMCIA_NMCLAN=m
+CONFIG_PCMCIA_SMC91C92=m
+CONFIG_PCMCIA_XIRC2PS=m
+CONFIG_PCMCIA_AXNET=m
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+
+#
+# ATM drivers
+#
+# CONFIG_ATM_DUMMY is not set
+CONFIG_ATM_TCP=m
+CONFIG_ATM_LANAI=m
+CONFIG_ATM_ENI=m
+# CONFIG_ATM_ENI_DEBUG is not set
+# CONFIG_ATM_ENI_TUNE_BURST is not set
+# CONFIG_ATM_FIRESTREAM is not set
+# CONFIG_ATM_ZATM is not set
+CONFIG_ATM_IDT77252=m
+# CONFIG_ATM_IDT77252_DEBUG is not set
+# CONFIG_ATM_IDT77252_RCV_ALL is not set
+CONFIG_ATM_IDT77252_USE_SUNI=y
+# CONFIG_ATM_AMBASSADOR is not set
+# CONFIG_ATM_HORIZON is not set
+CONFIG_ATM_FORE200E_MAYBE=m
+# CONFIG_ATM_FORE200E_PCA is not set
+CONFIG_ATM_HE=m
+# CONFIG_ATM_HE_USE_SUNI is not set
+CONFIG_FDDI=y
+# CONFIG_DEFXX is not set
+CONFIG_SKFP=m
+# CONFIG_HIPPI is not set
+CONFIG_PLIP=m
+CONFIG_PPP=m
+CONFIG_PPP_MULTILINK=y
+CONFIG_PPP_FILTER=y
+CONFIG_PPP_ASYNC=m
+CONFIG_PPP_SYNC_TTY=m
+CONFIG_PPP_DEFLATE=m
+# CONFIG_PPP_BSDCOMP is not set
+CONFIG_PPP_MPPE=m
+CONFIG_PPPOE=m
+CONFIG_PPPOATM=m
+CONFIG_SLIP=m
+CONFIG_SLIP_COMPRESSED=y
+CONFIG_SLIP_SMART=y
+# CONFIG_SLIP_MODE_SLIP6 is not set
+CONFIG_NET_FC=y
+# CONFIG_SHAPER is not set
+CONFIG_NETCONSOLE=m
+CONFIG_NETPOLL=y
+# CONFIG_NETPOLL_RX is not set
+CONFIG_NETPOLL_TRAP=y
+CONFIG_NET_POLL_CONTROLLER=y
+
+#
+# ISDN subsystem
+#
+CONFIG_ISDN=m
+
+#
+# Old ISDN4Linux
+#
+CONFIG_ISDN_I4L=m
+CONFIG_ISDN_PPP=y
+CONFIG_ISDN_PPP_VJ=y
+CONFIG_ISDN_MPP=y
+CONFIG_IPPP_FILTER=y
+# CONFIG_ISDN_PPP_BSDCOMP is not set
+CONFIG_ISDN_AUDIO=y
+CONFIG_ISDN_TTY_FAX=y
+
+#
+# ISDN feature submodules
+#
+CONFIG_ISDN_DIVERSION=m
+
+#
+# ISDN4Linux hardware drivers
+#
+
+#
+# Passive cards
+#
+CONFIG_ISDN_DRV_HISAX=m
+
+#
+# D-channel protocol features
+#
+CONFIG_HISAX_EURO=y
+CONFIG_DE_AOC=y
+CONFIG_HISAX_NO_SENDCOMPLETE=y
+CONFIG_HISAX_NO_LLC=y
+CONFIG_HISAX_NO_KEYPAD=y
+CONFIG_HISAX_1TR6=y
+CONFIG_HISAX_NI1=y
+CONFIG_HISAX_MAX_CARDS=8
+
+#
+# HiSax supported cards
+#
+CONFIG_HISAX_16_3=y
+CONFIG_HISAX_S0BOX=y
+CONFIG_HISAX_AVM_A1_PCMCIA=y
+CONFIG_HISAX_ELSA=y
+CONFIG_HISAX_DIEHLDIVA=y
+CONFIG_HISAX_SEDLBAUER=y
+CONFIG_HISAX_NICCY=y
+CONFIG_HISAX_BKM_A4T=y
+CONFIG_HISAX_SCT_QUADRO=y
+CONFIG_HISAX_GAZEL=y
+CONFIG_HISAX_W6692=y
+CONFIG_HISAX_HFC_SX=y
+# CONFIG_HISAX_DEBUG is not set
+
+#
+# HiSax PCMCIA card service modules
+#
+CONFIG_HISAX_SEDLBAUER_CS=m
+CONFIG_HISAX_ELSA_CS=m
+CONFIG_HISAX_AVM_A1_CS=m
+CONFIG_HISAX_TELES_CS=m
+
+#
+# HiSax sub driver modules
+#
+CONFIG_HISAX_ST5481=m
+# CONFIG_HISAX_HFCUSB is not set
+CONFIG_HISAX_HFC4S8S=m
+CONFIG_HISAX_FRITZ_PCIPNP=m
+CONFIG_HISAX_HDLC=y
+
+#
+# Active cards
+#
+
+#
+# Siemens Gigaset
+#
+CONFIG_ISDN_DRV_GIGASET=m
+CONFIG_GIGASET_BASE=m
+CONFIG_GIGASET_M105=m
+# CONFIG_GIGASET_DEBUG is not set
+# CONFIG_GIGASET_UNDOCREQ is not set
+
+#
+# CAPI subsystem
+#
+CONFIG_ISDN_CAPI=m
+CONFIG_ISDN_DRV_AVMB1_VERBOSE_REASON=y
+CONFIG_ISDN_CAPI_MIDDLEWARE=y
+CONFIG_ISDN_CAPI_CAPI20=m
+CONFIG_ISDN_CAPI_CAPIFS_BOOL=y
+CONFIG_ISDN_CAPI_CAPIFS=m
+CONFIG_ISDN_CAPI_CAPIDRV=m
+
+#
+# CAPI hardware drivers
+#
+
+#
+# Active AVM cards
+#
+CONFIG_CAPI_AVM=y
+CONFIG_ISDN_DRV_AVMB1_B1PCI=m
+CONFIG_ISDN_DRV_AVMB1_B1PCIV4=y
+CONFIG_ISDN_DRV_AVMB1_B1PCMCIA=m
+CONFIG_ISDN_DRV_AVMB1_AVM_CS=m
+CONFIG_ISDN_DRV_AVMB1_T1PCI=m
+CONFIG_ISDN_DRV_AVMB1_C4=m
+
+#
+# Active Eicon DIVA Server cards
+#
+CONFIG_CAPI_EICON=y
+CONFIG_ISDN_DIVAS=m
+CONFIG_ISDN_DIVAS_BRIPCI=y
+CONFIG_ISDN_DIVAS_PRIPCI=y
+CONFIG_ISDN_DIVAS_DIVACAPI=m
+CONFIG_ISDN_DIVAS_USERIDI=m
+CONFIG_ISDN_DIVAS_MAINT=m
+
+#
+# Telephony Support
+#
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+
+#
+# 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=m
+# CONFIG_INPUT_TSDEV is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+CONFIG_KEYBOARD_ATKBD=y
+# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_KEYBOARD_LKKBD is not set
+# CONFIG_KEYBOARD_XTKBD is not set
+# CONFIG_KEYBOARD_NEWTON is not set
+CONFIG_INPUT_MOUSE=y
+CONFIG_MOUSE_PS2=y
+CONFIG_MOUSE_SERIAL=m
+CONFIG_MOUSE_VSXXXAA=m
+CONFIG_INPUT_JOYSTICK=y
+CONFIG_JOYSTICK_ANALOG=m
+CONFIG_JOYSTICK_A3D=m
+CONFIG_JOYSTICK_ADI=m
+CONFIG_JOYSTICK_COBRA=m
+CONFIG_JOYSTICK_GF2K=m
+CONFIG_JOYSTICK_GRIP=m
+CONFIG_JOYSTICK_GRIP_MP=m
+CONFIG_JOYSTICK_GUILLEMOT=m
+CONFIG_JOYSTICK_INTERACT=m
+CONFIG_JOYSTICK_SIDEWINDER=m
+CONFIG_JOYSTICK_TMDC=m
+CONFIG_JOYSTICK_IFORCE=m
+CONFIG_JOYSTICK_IFORCE_USB=y
+CONFIG_JOYSTICK_IFORCE_232=y
+CONFIG_JOYSTICK_WARRIOR=m
+CONFIG_JOYSTICK_MAGELLAN=m
+CONFIG_JOYSTICK_SPACEORB=m
+CONFIG_JOYSTICK_SPACEBALL=m
+CONFIG_JOYSTICK_STINGER=m
+CONFIG_JOYSTICK_TWIDJOY=m
+CONFIG_JOYSTICK_DB9=m
+CONFIG_JOYSTICK_GAMECON=m
+CONFIG_JOYSTICK_TURBOGRAFX=m
+CONFIG_JOYSTICK_JOYDUMP=m
+CONFIG_INPUT_TOUCHSCREEN=y
+CONFIG_TOUCHSCREEN_GUNZE=m
+CONFIG_TOUCHSCREEN_ELO=m
+CONFIG_TOUCHSCREEN_MTOUCH=m
+CONFIG_TOUCHSCREEN_MK712=m
+CONFIG_INPUT_MISC=y
+# CONFIG_INPUT_PCSPKR is not set
+CONFIG_INPUT_UINPUT=m
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+CONFIG_SERIO_I8042=y
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_PARKBD is not set
+# CONFIG_SERIO_PCIPS2 is not set
+CONFIG_SERIO_LIBPS2=y
+CONFIG_SERIO_RAW=m
+CONFIG_GAMEPORT=m
+CONFIG_GAMEPORT_NS558=m
+CONFIG_GAMEPORT_L4=m
+CONFIG_GAMEPORT_EMU10K1=m
+CONFIG_GAMEPORT_FM801=m
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+CONFIG_VT_HW_CONSOLE_BINDING=y
+CONFIG_SERIAL_NONSTANDARD=y
+# CONFIG_COMPUTONE is not set
+# CONFIG_ROCKETPORT is not set
+CONFIG_CYCLADES=m
+# CONFIG_CYZ_INTR is not set
+# CONFIG_DIGIEPCA is not set
+# CONFIG_MOXA_INTELLIO is not set
+# CONFIG_MOXA_SMARTIO is not set
+# CONFIG_ISI is not set
+CONFIG_SYNCLINK=m
+CONFIG_SYNCLINKMP=m
+CONFIG_SYNCLINK_GT=m
+CONFIG_N_HDLC=m
+# CONFIG_SPECIALIX is not set
+# CONFIG_SX is not set
+# CONFIG_RIO is not set
+# CONFIG_STALDRV is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_PCI=y
+CONFIG_SERIAL_8250_CS=m
+CONFIG_SERIAL_8250_NR_UARTS=32
+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=y
+CONFIG_SERIAL_8250_RSA=y
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_SERIAL_PMACZILOG=m
+CONFIG_SERIAL_ICOM=m
+CONFIG_SERIAL_JSM=m
+CONFIG_UNIX98_PTYS=y
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_CRASH is not set
+CONFIG_PRINTER=m
+CONFIG_LP_CONSOLE=y
+CONFIG_PPDEV=m
+CONFIG_TIPAR=m
+CONFIG_HVC_DRIVER=y
+CONFIG_HVC_CONSOLE=y
+CONFIG_HVC_RTAS=y
+CONFIG_HVCS=m
+
+#
+# IPMI
+#
+CONFIG_IPMI_HANDLER=m
+# CONFIG_IPMI_PANIC_EVENT is not set
+CONFIG_IPMI_DEVICE_INTERFACE=m
+CONFIG_IPMI_SI=m
+CONFIG_IPMI_WATCHDOG=m
+CONFIG_IPMI_POWEROFF=m
+
+#
+# Watchdog Cards
+#
+CONFIG_WATCHDOG=y
+# CONFIG_WATCHDOG_NOWAYOUT is not set
+
+#
+# Watchdog Device Drivers
+#
+CONFIG_SOFT_WATCHDOG=m
+CONFIG_WATCHDOG_RTAS=m
+
+#
+# PCI-based Watchdog Cards
+#
+CONFIG_PCIPCWATCHDOG=m
+CONFIG_WDTPCI=m
+CONFIG_WDT_501_PCI=y
+
+#
+# USB-based Watchdog Cards
+#
+CONFIG_USBPCWATCHDOG=m
+CONFIG_HW_RANDOM=y
+CONFIG_GEN_RTC=y
+# CONFIG_GEN_RTC_X is not set
+CONFIG_DTLK=m
+CONFIG_R3964=m
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+CONFIG_AGP=y
+CONFIG_AGP_SIS=y
+CONFIG_AGP_VIA=y
+CONFIG_AGP_UNINORTH=y
+CONFIG_DRM=m
+CONFIG_DRM_TDFX=m
+CONFIG_DRM_R128=m
+CONFIG_DRM_RADEON=m
+CONFIG_DRM_MGA=m
+CONFIG_DRM_SIS=m
+CONFIG_DRM_VIA=m
+CONFIG_DRM_SAVAGE=m
+
+#
+# PCMCIA character devices
+#
+# CONFIG_SYNCLINK_CS is not set
+CONFIG_CARDMAN_4000=m
+CONFIG_CARDMAN_4040=m
+# CONFIG_RAW_DRIVER is not set
+CONFIG_HANGCHECK_TIMER=m
+
+#
+# TPM devices
+#
+CONFIG_TCG_TPM=m
+CONFIG_TCG_ATMEL=m
+# CONFIG_TELCLOCK is not set
+
+#
+# I2C support
+#
+CONFIG_I2C=y
+CONFIG_I2C_CHARDEV=m
+
+#
+# I2C Algorithms
+#
+CONFIG_I2C_ALGOBIT=y
+CONFIG_I2C_ALGOPCF=m
+CONFIG_I2C_ALGOPCA=m
+
+#
+# I2C Hardware Bus support
+#
+# CONFIG_I2C_ALI1535 is not set
+# CONFIG_I2C_ALI1563 is not set
+# CONFIG_I2C_ALI15X3 is not set
+# CONFIG_I2C_AMD756 is not set
+# CONFIG_I2C_AMD8111 is not set
+# CONFIG_I2C_I801 is not set
+# CONFIG_I2C_I810 is not set
+# CONFIG_I2C_PIIX4 is not set
+CONFIG_I2C_ISA=m
+CONFIG_I2C_POWERMAC=y
+CONFIG_I2C_NFORCE2=m
+# CONFIG_I2C_OCORES is not set
+CONFIG_I2C_PARPORT=m
+CONFIG_I2C_PARPORT_LIGHT=m
+CONFIG_I2C_PROSAVAGE=m
+CONFIG_I2C_SAVAGE4=m
+# CONFIG_I2C_SIS5595 is not set
+# CONFIG_I2C_SIS630 is not set
+# CONFIG_I2C_SIS96X is not set
+CONFIG_I2C_STUB=m
+# CONFIG_I2C_VIA is not set
+# CONFIG_I2C_VIAPRO is not set
+CONFIG_I2C_VOODOO3=m
+CONFIG_I2C_PCA_ISA=m
+
+#
+# Miscellaneous I2C Chip support
+#
+CONFIG_SENSORS_DS1337=m
+CONFIG_SENSORS_DS1374=m
+CONFIG_SENSORS_EEPROM=m
+CONFIG_SENSORS_PCF8574=m
+CONFIG_SENSORS_PCA9539=m
+CONFIG_SENSORS_PCF8591=m
+CONFIG_SENSORS_MAX6875=m
+# 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 is not set
+# CONFIG_SPI_MASTER is not set
+
+#
+# Dallas's 1-wire bus
+#
+CONFIG_W1=m
+CONFIG_W1_CON=y
+
+#
+# 1-wire Bus Masters
+#
+CONFIG_W1_MASTER_MATROX=m
+CONFIG_W1_MASTER_DS2490=m
+CONFIG_W1_MASTER_DS2482=m
+
+#
+# 1-wire Slaves
+#
+CONFIG_W1_SLAVE_THERM=m
+CONFIG_W1_SLAVE_SMEM=m
+CONFIG_W1_SLAVE_DS2433=m
+CONFIG_W1_SLAVE_DS2433_CRC=y
+
+#
+# Hardware Monitoring support
+#
+CONFIG_HWMON=m
+CONFIG_HWMON_VID=m
+CONFIG_SENSORS_ABITUGURU=m
+CONFIG_SENSORS_ADM1021=m
+CONFIG_SENSORS_ADM1025=m
+CONFIG_SENSORS_ADM1026=m
+CONFIG_SENSORS_ADM1031=m
+CONFIG_SENSORS_ADM9240=m
+CONFIG_SENSORS_ASB100=m
+CONFIG_SENSORS_ATXP1=m
+CONFIG_SENSORS_DS1621=m
+CONFIG_SENSORS_F71805F=m
+CONFIG_SENSORS_FSCHER=m
+CONFIG_SENSORS_FSCPOS=m
+CONFIG_SENSORS_GL518SM=m
+CONFIG_SENSORS_GL520SM=m
+CONFIG_SENSORS_IT87=m
+CONFIG_SENSORS_LM63=m
+CONFIG_SENSORS_LM75=m
+CONFIG_SENSORS_LM77=m
+CONFIG_SENSORS_LM78=m
+CONFIG_SENSORS_LM80=m
+CONFIG_SENSORS_LM83=m
+CONFIG_SENSORS_LM85=m
+CONFIG_SENSORS_LM87=m
+CONFIG_SENSORS_LM90=m
+CONFIG_SENSORS_LM92=m
+CONFIG_SENSORS_MAX1619=m
+CONFIG_SENSORS_PC87360=m
+CONFIG_SENSORS_SIS5595=m
+CONFIG_SENSORS_SMSC47M1=m
+CONFIG_SENSORS_SMSC47M192=m
+CONFIG_SENSORS_SMSC47B397=m
+CONFIG_SENSORS_VIA686A=m
+CONFIG_SENSORS_VT8231=m
+CONFIG_SENSORS_W83781D=m
+CONFIG_SENSORS_W83791D=m
+CONFIG_SENSORS_W83792D=m
+CONFIG_SENSORS_W83L785TS=m
+CONFIG_SENSORS_W83627HF=m
+CONFIG_SENSORS_W83627EHF=m
+# CONFIG_HWMON_DEBUG_CHIP is not set
+
+#
+# Misc devices
+#
+
+#
+# Multimedia devices
+#
+CONFIG_VIDEO_DEV=m
+CONFIG_VIDEO_V4L1=y
+CONFIG_VIDEO_V4L1_COMPAT=y
+CONFIG_VIDEO_V4L2=y
+
+#
+# Video Capture Adapters
+#
+
+#
+# Video Capture Adapters
+#
+# CONFIG_VIDEO_ADV_DEBUG is not set
+# CONFIG_VIDEO_VIVI is not set
+CONFIG_VIDEO_BT848=m
+CONFIG_VIDEO_BT848_DVB=y
+CONFIG_VIDEO_SAA6588=m
+CONFIG_VIDEO_BWQCAM=m
+CONFIG_VIDEO_CQCAM=m
+CONFIG_VIDEO_W9966=m
+CONFIG_VIDEO_CPIA=m
+CONFIG_VIDEO_CPIA_PP=m
+CONFIG_VIDEO_CPIA_USB=m
+CONFIG_VIDEO_CPIA2=m
+CONFIG_VIDEO_SAA5246A=m
+CONFIG_VIDEO_SAA5249=m
+CONFIG_TUNER_3036=m
+CONFIG_VIDEO_SAA7134=m
+CONFIG_VIDEO_SAA7134_ALSA=m
+CONFIG_VIDEO_SAA7134_DVB=m
+CONFIG_VIDEO_SAA7134_DVB_ALL_FRONTENDS=y
+CONFIG_VIDEO_MXB=m
+CONFIG_VIDEO_DPC=m
+CONFIG_VIDEO_HEXIUM_ORION=m
+CONFIG_VIDEO_HEXIUM_GEMINI=m
+CONFIG_VIDEO_CX88_VP3054=m
+CONFIG_VIDEO_CX88=m
+CONFIG_VIDEO_CX88_ALSA=m
+CONFIG_VIDEO_CX88_BLACKBIRD=m
+CONFIG_VIDEO_CX88_DVB=m
+CONFIG_VIDEO_CX88_DVB_ALL_FRONTENDS=y
+
+#
+# Encoders and Decoders
+#
+CONFIG_VIDEO_MSP3400=m
+CONFIG_VIDEO_CS53L32A=m
+CONFIG_VIDEO_TLV320AIC23B=m
+CONFIG_VIDEO_WM8775=m
+CONFIG_VIDEO_WM8739=m
+CONFIG_VIDEO_CX2341X=m
+CONFIG_VIDEO_CX25840=m
+CONFIG_VIDEO_SAA711X=m
+CONFIG_VIDEO_SAA7127=m
+CONFIG_VIDEO_UPD64031A=m
+CONFIG_VIDEO_UPD64083=m
+
+#
+# V4L USB devices
+#
+CONFIG_VIDEO_PVRUSB2=m
+CONFIG_VIDEO_PVRUSB2_24XXX=y
+CONFIG_VIDEO_PVRUSB2_SYSFS=y
+# CONFIG_VIDEO_PVRUSB2_DEBUGIFC is not set
+CONFIG_VIDEO_EM28XX=m
+CONFIG_VIDEO_USBVIDEO=m
+CONFIG_USB_VICAM=m
+CONFIG_USB_IBMCAM=m
+CONFIG_USB_KONICAWC=m
+CONFIG_USB_QUICKCAM_MESSENGER=m
+CONFIG_USB_ET61X251=m
+CONFIG_VIDEO_OVCAMCHIP=m
+CONFIG_USB_W9968CF=m
+CONFIG_USB_OV511=m
+CONFIG_USB_SE401=m
+CONFIG_USB_SN9C102=m
+CONFIG_USB_STV680=m
+CONFIG_USB_ZC0301=m
+CONFIG_USB_PWC=m
+# CONFIG_USB_PWC_DEBUG is not set
+
+#
+# Radio Adapters
+#
+CONFIG_RADIO_GEMTEK_PCI=m
+CONFIG_RADIO_MAXIRADIO=m
+CONFIG_RADIO_MAESTRO=m
+CONFIG_USB_DSBR=m
+
+#
+# Digital Video Broadcasting Devices
+#
+CONFIG_DVB=y
+CONFIG_DVB_CORE=m
+
+#
+# Supported SAA7146 based PCI Adapters
+#
+CONFIG_DVB_AV7110=m
+CONFIG_DVB_AV7110_OSD=y
+CONFIG_DVB_BUDGET=m
+CONFIG_DVB_BUDGET_CI=m
+CONFIG_DVB_BUDGET_AV=m
+CONFIG_DVB_BUDGET_PATCH=m
+
+#
+# Supported USB Adapters
+#
+CONFIG_DVB_USB=m
+# CONFIG_DVB_USB_DEBUG is not set
+CONFIG_DVB_USB_A800=m
+CONFIG_DVB_USB_DIBUSB_MB=m
+# CONFIG_DVB_USB_DIBUSB_MB_FAULTY is not set
+CONFIG_DVB_USB_DIBUSB_MC=m
+CONFIG_DVB_USB_UMT_010=m
+CONFIG_DVB_USB_CXUSB=m
+CONFIG_DVB_USB_DIGITV=m
+CONFIG_DVB_USB_VP7045=m
+CONFIG_DVB_USB_VP702X=m
+CONFIG_DVB_USB_GP8PSK=m
+CONFIG_DVB_USB_NOVA_T_USB2=m
+CONFIG_DVB_USB_DTT200U=m
+CONFIG_DVB_TTUSB_BUDGET=m
+CONFIG_DVB_TTUSB_DEC=m
+CONFIG_DVB_CINERGYT2=m
+CONFIG_DVB_CINERGYT2_TUNING=y
+CONFIG_DVB_CINERGYT2_STREAM_URB_COUNT=32
+CONFIG_DVB_CINERGYT2_STREAM_BUF_SIZE=512
+CONFIG_DVB_CINERGYT2_QUERY_INTERVAL=250
+CONFIG_DVB_CINERGYT2_ENABLE_RC_INPUT_DEVICE=y
+CONFIG_DVB_CINERGYT2_RC_QUERY_INTERVAL=100
+
+#
+# Supported FlexCopII (B2C2) Adapters
+#
+CONFIG_DVB_B2C2_FLEXCOP=m
+CONFIG_DVB_B2C2_FLEXCOP_PCI=m
+CONFIG_DVB_B2C2_FLEXCOP_USB=m
+# CONFIG_DVB_B2C2_FLEXCOP_DEBUG is not set
+
+#
+# Supported BT878 Adapters
+#
+CONFIG_DVB_BT8XX=m
+
+#
+# Supported Pluto2 Adapters
+#
+CONFIG_DVB_PLUTO2=m
+
+#
+# Supported DVB Frontends
+#
+
+#
+# Customise DVB Frontends
+#
+
+#
+# DVB-S (satellite) frontends
+#
+CONFIG_DVB_STV0299=m
+CONFIG_DVB_CX24110=m
+CONFIG_DVB_CX24123=m
+CONFIG_DVB_TDA8083=m
+CONFIG_DVB_MT312=m
+CONFIG_DVB_VES1X93=m
+CONFIG_DVB_S5H1420=m
+
+#
+# DVB-T (terrestrial) frontends
+#
+CONFIG_DVB_SP8870=m
+CONFIG_DVB_SP887X=m
+CONFIG_DVB_CX22700=m
+CONFIG_DVB_CX22702=m
+CONFIG_DVB_L64781=m
+CONFIG_DVB_TDA1004X=m
+CONFIG_DVB_NXT6000=m
+CONFIG_DVB_MT352=m
+CONFIG_DVB_ZL10353=m
+CONFIG_DVB_DIB3000MB=m
+CONFIG_DVB_DIB3000MC=m
+
+#
+# DVB-C (cable) frontends
+#
+CONFIG_DVB_VES1820=m
+CONFIG_DVB_TDA10021=m
+CONFIG_DVB_STV0297=m
+
+#
+# ATSC (North American/Korean Terrestrial/Cable DTV) frontends
+#
+CONFIG_DVB_NXT200X=m
+CONFIG_DVB_OR51211=m
+CONFIG_DVB_OR51132=m
+CONFIG_DVB_BCM3510=m
+CONFIG_DVB_LGDT330X=m
+
+#
+# Miscellaneous devices
+#
+CONFIG_DVB_PLL=m
+CONFIG_DVB_LNBP21=m
+CONFIG_DVB_ISL6421=m
+CONFIG_VIDEO_SAA7146=m
+CONFIG_VIDEO_SAA7146_VV=m
+CONFIG_VIDEO_VIDEOBUF=m
+CONFIG_VIDEO_TUNER=m
+CONFIG_VIDEO_BUF=m
+CONFIG_VIDEO_BUF_DVB=m
+CONFIG_VIDEO_BTCX=m
+CONFIG_VIDEO_IR=m
+CONFIG_VIDEO_TVEEPROM=m
+CONFIG_USB_DABUSB=m
+
+#
+# Graphics support
+#
+# CONFIG_FIRMWARE_EDID is not set
+CONFIG_FB=y
+CONFIG_FB_CFB_FILLRECT=y
+CONFIG_FB_CFB_COPYAREA=y
+CONFIG_FB_CFB_IMAGEBLIT=y
+CONFIG_FB_MACMODES=y
+# CONFIG_FB_BACKLIGHT is not set
+CONFIG_FB_MODE_HELPERS=y
+CONFIG_FB_TILEBLITTING=y
+CONFIG_FB_CIRRUS=m
+# CONFIG_FB_PM2 is not set
+# CONFIG_FB_CYBER2000 is not set
+CONFIG_FB_OF=y
+# CONFIG_FB_ASILIANT is not set
+# CONFIG_FB_IMSTT is not set
+# CONFIG_FB_VGA16 is not set
+# CONFIG_FB_S1D13XXX is not set
+CONFIG_FB_NVIDIA=m
+CONFIG_FB_NVIDIA_I2C=y
+CONFIG_FB_RIVA=m
+# CONFIG_FB_RIVA_I2C is not set
+# CONFIG_FB_RIVA_DEBUG is not set
+CONFIG_FB_MATROX=m
+CONFIG_FB_MATROX_MILLENIUM=y
+CONFIG_FB_MATROX_MYSTIQUE=y
+CONFIG_FB_MATROX_G=y
+CONFIG_FB_MATROX_I2C=m
+CONFIG_FB_MATROX_MAVEN=m
+CONFIG_FB_MATROX_MULTIHEAD=y
+CONFIG_FB_RADEON=y
+CONFIG_FB_RADEON_I2C=y
+# CONFIG_FB_RADEON_DEBUG is not set
+# CONFIG_FB_ATY128 is not set
+# CONFIG_FB_ATY is not set
+CONFIG_FB_SAVAGE=m
+CONFIG_FB_SAVAGE_I2C=y
+CONFIG_FB_SAVAGE_ACCEL=y
+# CONFIG_FB_SIS is not set
+CONFIG_FB_NEOMAGIC=m
+CONFIG_FB_KYRO=m
+CONFIG_FB_3DFX=m
+CONFIG_FB_3DFX_ACCEL=y
+CONFIG_FB_VOODOO1=m
+CONFIG_FB_TRIDENT=m
+CONFIG_FB_TRIDENT_ACCEL=y
+# CONFIG_FB_VIRTUAL is not set
+
+#
+# Console display driver support
+#
+CONFIG_VGA_CONSOLE=y
+CONFIG_VGACON_SOFT_SCROLLBACK=y
+CONFIG_VGACON_SOFT_SCROLLBACK_SIZE=64
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y
+# CONFIG_FONTS is not set
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
+
+#
+# Logo configuration
+#
+CONFIG_LOGO=y
+# CONFIG_LOGO_LINUX_MONO is not set
+# CONFIG_LOGO_LINUX_VGA16 is not set
+CONFIG_LOGO_LINUX_CLUT224=y
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+CONFIG_BACKLIGHT_CLASS_DEVICE=m
+CONFIG_BACKLIGHT_DEVICE=y
+CONFIG_LCD_CLASS_DEVICE=m
+CONFIG_LCD_DEVICE=y
+
+#
+# Sound
+#
+CONFIG_SOUND=m
+
+#
+# Advanced Linux Sound Architecture
+#
+CONFIG_SND=m
+CONFIG_SND_TIMER=m
+CONFIG_SND_PCM=m
+CONFIG_SND_HWDEP=m
+CONFIG_SND_RAWMIDI=m
+CONFIG_SND_SEQUENCER=m
+CONFIG_SND_SEQ_DUMMY=m
+CONFIG_SND_OSSEMUL=y
+CONFIG_SND_MIXER_OSS=m
+CONFIG_SND_PCM_OSS=m
+CONFIG_SND_PCM_OSS_PLUGINS=y
+CONFIG_SND_SEQUENCER_OSS=y
+CONFIG_SND_DYNAMIC_MINORS=y
+# CONFIG_SND_SUPPORT_OLD_API is not set
+CONFIG_SND_VERBOSE_PROCFS=y
+# CONFIG_SND_VERBOSE_PRINTK is not set
+# CONFIG_SND_DEBUG is not set
+
+#
+# Generic devices
+#
+CONFIG_SND_MPU401_UART=m
+CONFIG_SND_OPL3_LIB=m
+CONFIG_SND_VX_LIB=m
+CONFIG_SND_AC97_CODEC=m
+CONFIG_SND_AC97_BUS=m
+CONFIG_SND_DUMMY=m
+CONFIG_SND_VIRMIDI=m
+CONFIG_SND_MTPAV=m
+# CONFIG_SND_SERIAL_U16550 is not set
+CONFIG_SND_MPU401=m
+
+#
+# PCI devices
+#
+CONFIG_SND_AD1889=m
+CONFIG_SND_ALS300=m
+CONFIG_SND_ALS4000=m
+CONFIG_SND_ALI5451=m
+CONFIG_SND_ATIIXP=m
+CONFIG_SND_ATIIXP_MODEM=m
+CONFIG_SND_AU8810=m
+CONFIG_SND_AU8820=m
+CONFIG_SND_AU8830=m
+CONFIG_SND_AZT3328=m
+CONFIG_SND_BT87X=m
+# CONFIG_SND_BT87X_OVERCLOCK is not set
+CONFIG_SND_CA0106=m
+CONFIG_SND_CMIPCI=m
+CONFIG_SND_CS4281=m
+CONFIG_SND_CS46XX=m
+CONFIG_SND_CS46XX_NEW_DSP=y
+CONFIG_SND_DARLA20=m
+CONFIG_SND_GINA20=m
+CONFIG_SND_LAYLA20=m
+CONFIG_SND_DARLA24=m
+CONFIG_SND_GINA24=m
+CONFIG_SND_LAYLA24=m
+CONFIG_SND_MONA=m
+CONFIG_SND_MIA=m
+CONFIG_SND_ECHO3G=m
+CONFIG_SND_INDIGO=m
+CONFIG_SND_INDIGOIO=m
+CONFIG_SND_INDIGODJ=m
+CONFIG_SND_EMU10K1=m
+CONFIG_SND_EMU10K1X=m
+CONFIG_SND_ENS1370=m
+CONFIG_SND_ENS1371=m
+CONFIG_SND_ES1938=m
+CONFIG_SND_ES1968=m
+CONFIG_SND_FM801=m
+CONFIG_SND_FM801_TEA575X_BOOL=y
+CONFIG_SND_FM801_TEA575X=m
+CONFIG_SND_HDA_INTEL=m
+CONFIG_SND_HDSP=m
+CONFIG_SND_HDSPM=m
+CONFIG_SND_ICE1712=m
+CONFIG_SND_ICE1724=m
+CONFIG_SND_INTEL8X0=m
+CONFIG_SND_INTEL8X0M=m
+CONFIG_SND_KORG1212=m
+CONFIG_SND_MAESTRO3=m
+CONFIG_SND_MIXART=m
+CONFIG_SND_NM256=m
+CONFIG_SND_PCXHR=m
+CONFIG_SND_RIPTIDE=m
+CONFIG_SND_RME32=m
+CONFIG_SND_RME96=m
+CONFIG_SND_RME9652=m
+CONFIG_SND_SONICVIBES=m
+CONFIG_SND_TRIDENT=m
+CONFIG_SND_VIA82XX=m
+CONFIG_SND_VIA82XX_MODEM=m
+CONFIG_SND_VX222=m
+CONFIG_SND_YMFPCI=m
+
+#
+# ALSA PowerMac devices
+#
+CONFIG_SND_POWERMAC=m
+CONFIG_SND_POWERMAC_AUTO_DRC=y
+
+#
+# Apple Onboard Audio driver
+#
+CONFIG_SND_AOA=m
+CONFIG_SND_AOA_FABRIC_LAYOUT=m
+CONFIG_SND_AOA_ONYX=m
+CONFIG_SND_AOA_TAS=m
+CONFIG_SND_AOA_TOONIE=m
+CONFIG_SND_AOA_SOUNDBUS=m
+CONFIG_SND_AOA_SOUNDBUS_I2S=m
+
+#
+# USB devices
+#
+CONFIG_SND_USB_AUDIO=m
+CONFIG_SND_USB_USX2Y=m
+
+#
+# PCMCIA devices
+#
+# CONFIG_SND_VXPOCKET is not set
+# CONFIG_SND_PDAUDIOCF is not set
+
+#
+# Open Sound System
+#
+# CONFIG_SOUND_PRIME is not set
+
+#
+# USB support
+#
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB_ARCH_HAS_EHCI=y
+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_SUSPEND is not set
+# CONFIG_USB_OTG is not set
+
+#
+# USB Host Controller Drivers
+#
+CONFIG_USB_EHCI_HCD=m
+CONFIG_USB_EHCI_SPLIT_ISO=y
+CONFIG_USB_EHCI_ROOT_HUB_TT=y
+CONFIG_USB_EHCI_TT_NEWSCHED=y
+CONFIG_USB_ISP116X_HCD=m
+CONFIG_USB_OHCI_HCD=m
+# CONFIG_USB_OHCI_BIG_ENDIAN is not set
+CONFIG_USB_OHCI_LITTLE_ENDIAN=y
+CONFIG_USB_UHCI_HCD=m
+CONFIG_USB_SL811_HCD=m
+CONFIG_USB_SL811_CS=m
+
+#
+# USB Device Class drivers
+#
+CONFIG_USB_ACM=m
+CONFIG_USB_PRINTER=m
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+#
+
+#
+# may also be needed; see USB_STORAGE Help for more information
+#
+CONFIG_USB_STORAGE=m
+# CONFIG_USB_STORAGE_DEBUG is not set
+CONFIG_USB_STORAGE_DATAFAB=y
+CONFIG_USB_STORAGE_FREECOM=y
+CONFIG_USB_STORAGE_ISD200=y
+CONFIG_USB_STORAGE_DPCM=y
+CONFIG_USB_STORAGE_USBAT=y
+CONFIG_USB_STORAGE_SDDR09=y
+CONFIG_USB_STORAGE_SDDR55=y
+CONFIG_USB_STORAGE_JUMPSHOT=y
+CONFIG_USB_STORAGE_ALAUDA=y
+CONFIG_USB_LIBUSUAL=y
+
+#
+# USB Input Devices
+#
+CONFIG_USB_HID=y
+CONFIG_USB_HIDINPUT=y
+CONFIG_USB_HIDINPUT_POWERBOOK=y
+CONFIG_HID_FF=y
+CONFIG_HID_PID=y
+CONFIG_LOGITECH_FF=y
+CONFIG_THRUSTMASTER_FF=y
+CONFIG_USB_HIDDEV=y
+CONFIG_USB_AIPTEK=m
+CONFIG_USB_WACOM=m
+CONFIG_USB_ACECAD=m
+CONFIG_USB_KBTAB=m
+CONFIG_USB_POWERMATE=m
+CONFIG_USB_TOUCHSCREEN=m
+CONFIG_USB_TOUCHSCREEN_EGALAX=y
+CONFIG_USB_TOUCHSCREEN_PANJIT=y
+CONFIG_USB_TOUCHSCREEN_3M=y
+CONFIG_USB_TOUCHSCREEN_ITM=y
+# CONFIG_USB_YEALINK is not set
+CONFIG_USB_XPAD=m
+CONFIG_USB_ATI_REMOTE=m
+CONFIG_USB_ATI_REMOTE2=m
+CONFIG_USB_KEYSPAN_REMOTE=m
+CONFIG_USB_APPLETOUCH=m
+
+#
+# USB Imaging devices
+#
+CONFIG_USB_MDC800=m
+CONFIG_USB_MICROTEK=m
+
+#
+# USB Network Adapters
+#
+CONFIG_USB_CATC=m
+CONFIG_USB_KAWETH=m
+CONFIG_USB_PEGASUS=m
+CONFIG_USB_RTL8150=m
+CONFIG_USB_USBNET=m
+CONFIG_USB_NET_AX8817X=m
+CONFIG_USB_NET_CDCETHER=m
+CONFIG_USB_NET_GL620A=m
+CONFIG_USB_NET_NET1080=m
+CONFIG_USB_NET_PLUSB=m
+CONFIG_USB_NET_RNDIS_HOST=m
+CONFIG_USB_NET_CDC_SUBSET=m
+CONFIG_USB_ALI_M5632=y
+CONFIG_USB_AN2720=y
+CONFIG_USB_BELKIN=y
+CONFIG_USB_ARMLINUX=y
+CONFIG_USB_EPSON2888=y
+CONFIG_USB_NET_ZAURUS=m
+CONFIG_USB_MON=y
+
+#
+# USB port drivers
+#
+CONFIG_USB_USS720=m
+
+#
+# USB Serial Converter support
+#
+CONFIG_USB_SERIAL=m
+CONFIG_USB_SERIAL_GENERIC=y
+CONFIG_USB_SERIAL_AIRPRIME=m
+CONFIG_USB_SERIAL_ARK3116=m
+CONFIG_USB_SERIAL_BELKIN=m
+CONFIG_USB_SERIAL_WHITEHEAT=m
+CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m
+CONFIG_USB_SERIAL_CP2101=m
+CONFIG_USB_SERIAL_CYPRESS_M8=m
+CONFIG_USB_SERIAL_EMPEG=m
+CONFIG_USB_SERIAL_FTDI_SIO=m
+CONFIG_USB_SERIAL_FUNSOFT=m
+CONFIG_USB_SERIAL_VISOR=m
+CONFIG_USB_SERIAL_IPAQ=m
+CONFIG_USB_SERIAL_IR=m
+CONFIG_USB_SERIAL_EDGEPORT=m
+CONFIG_USB_SERIAL_EDGEPORT_TI=m
+CONFIG_USB_SERIAL_GARMIN=m
+CONFIG_USB_SERIAL_IPW=m
+CONFIG_USB_SERIAL_KEYSPAN_PDA=m
+CONFIG_USB_SERIAL_KEYSPAN=m
+CONFIG_USB_SERIAL_KEYSPAN_MPR=y
+CONFIG_USB_SERIAL_KEYSPAN_USA28=y
+CONFIG_USB_SERIAL_KEYSPAN_USA28X=y
+CONFIG_USB_SERIAL_KEYSPAN_USA28XA=y
+CONFIG_USB_SERIAL_KEYSPAN_USA28XB=y
+CONFIG_USB_SERIAL_KEYSPAN_USA19=y
+CONFIG_USB_SERIAL_KEYSPAN_USA18X=y
+CONFIG_USB_SERIAL_KEYSPAN_USA19W=y
+CONFIG_USB_SERIAL_KEYSPAN_USA19QW=y
+CONFIG_USB_SERIAL_KEYSPAN_USA19QI=y
+CONFIG_USB_SERIAL_KEYSPAN_USA49W=y
+CONFIG_USB_SERIAL_KEYSPAN_USA49WLC=y
+CONFIG_USB_SERIAL_KLSI=m
+CONFIG_USB_SERIAL_KOBIL_SCT=m
+CONFIG_USB_SERIAL_MCT_U232=m
+CONFIG_USB_SERIAL_NAVMAN=m
+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=m
+CONFIG_USB_SERIAL_TI=m
+CONFIG_USB_SERIAL_CYBERJACK=m
+CONFIG_USB_SERIAL_XIRCOM=m
+CONFIG_USB_SERIAL_OPTION=m
+CONFIG_USB_SERIAL_OMNINET=m
+CONFIG_USB_EZUSB=y
+
+#
+# USB Miscellaneous drivers
+#
+CONFIG_USB_EMI62=m
+CONFIG_USB_EMI26=m
+CONFIG_USB_AUERSWALD=m
+CONFIG_USB_RIO500=m
+CONFIG_USB_LEGOTOWER=m
+CONFIG_USB_LCD=m
+CONFIG_USB_LED=m
+# CONFIG_USB_CYPRESS_CY7C63 is not set
+# CONFIG_USB_CYTHERM is not set
+CONFIG_USB_PHIDGETKIT=m
+CONFIG_USB_PHIDGETSERVO=m
+CONFIG_USB_IDMOUSE=m
+CONFIG_USB_APPLEDISPLAY=m
+CONFIG_USB_SISUSBVGA=m
+CONFIG_USB_SISUSBVGA_CON=y
+CONFIG_USB_LD=m
+CONFIG_USB_TEST=m
+
+#
+# USB DSL modem support
+#
+CONFIG_USB_ATM=m
+CONFIG_USB_SPEEDTOUCH=m
+CONFIG_USB_CXACRU=m
+CONFIG_USB_UEAGLEATM=m
+CONFIG_USB_XUSBATM=m
+
+#
+# USB Gadget Support
+#
+# CONFIG_USB_GADGET is not set
+
+#
+# MMC/SD Card support
+#
+CONFIG_MMC=m
+# CONFIG_MMC_DEBUG is not set
+CONFIG_MMC_BLOCK=m
+CONFIG_MMC_SDHCI=m
+CONFIG_MMC_WBSD=m
+
+#
+# LED devices
+#
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+
+#
+# LED drivers
+#
+
+#
+# LED Triggers
+#
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_LEDS_TRIGGER_TIMER=m
+CONFIG_LEDS_TRIGGER_IDE_DISK=y
+CONFIG_LEDS_TRIGGER_HEARTBEAT=m
+
+#
+# InfiniBand support
+#
+CONFIG_INFINIBAND=m
+CONFIG_INFINIBAND_USER_MAD=m
+CONFIG_INFINIBAND_USER_ACCESS=m
+CONFIG_INFINIBAND_ADDR_TRANS=y
+CONFIG_INFINIBAND_MTHCA=m
+CONFIG_INFINIBAND_MTHCA_DEBUG=y
+CONFIG_INFINIBAND_IPOIB=m
+CONFIG_INFINIBAND_IPOIB_DEBUG=y
+CONFIG_INFINIBAND_IPOIB_DEBUG_DATA=y
+CONFIG_INFINIBAND_SRP=m
+CONFIG_INFINIBAND_ISER=m
+
+#
+# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
+#
+
+#
+# Real Time Clock
+#
+CONFIG_RTC_LIB=m
+CONFIG_RTC_CLASS=m
+
+#
+# RTC interfaces
+#
+CONFIG_RTC_INTF_SYSFS=m
+CONFIG_RTC_INTF_PROC=m
+CONFIG_RTC_INTF_DEV=m
+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
+
+#
+# RTC drivers
+#
+CONFIG_RTC_DRV_X1205=m
+CONFIG_RTC_DRV_DS1307=m
+CONFIG_RTC_DRV_DS1553=m
+CONFIG_RTC_DRV_ISL1208=m
+CONFIG_RTC_DRV_DS1672=m
+CONFIG_RTC_DRV_DS1742=m
+CONFIG_RTC_DRV_PCF8563=m
+CONFIG_RTC_DRV_PCF8583=m
+CONFIG_RTC_DRV_RS5C372=m
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_TEST is not set
+CONFIG_RTC_DRV_V3020=m
+
+#
+# DMA Engine support
+#
+CONFIG_DMA_ENGINE=y
+
+#
+# DMA Clients
+#
+CONFIG_NET_DMA=y
+
+#
+# DMA Devices
+#
+CONFIG_INTEL_IOATDMA=m
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+CONFIG_EXT2_FS_POSIX_ACL=y
+CONFIG_EXT2_FS_SECURITY=y
+CONFIG_EXT2_FS_XIP=y
+CONFIG_FS_XIP=y
+CONFIG_EXT3_FS=m
+CONFIG_EXT3_FS_XATTR=y
+CONFIG_EXT3_FS_POSIX_ACL=y
+CONFIG_EXT3_FS_SECURITY=y
+CONFIG_JBD=m
+# CONFIG_JBD_DEBUG is not set
+CONFIG_FS_MBCACHE=y
+CONFIG_REISERFS_FS=m
+# CONFIG_REISERFS_CHECK is not set
+CONFIG_REISERFS_PROC_INFO=y
+CONFIG_REISERFS_FS_XATTR=y
+CONFIG_REISERFS_FS_POSIX_ACL=y
+CONFIG_REISERFS_FS_SECURITY=y
+CONFIG_JFS_FS=m
+CONFIG_JFS_POSIX_ACL=y
+CONFIG_JFS_SECURITY=y
+# CONFIG_JFS_DEBUG is not set
+# CONFIG_JFS_STATISTICS is not set
+CONFIG_FS_POSIX_ACL=y
+CONFIG_XFS_FS=m
+CONFIG_XFS_QUOTA=y
+CONFIG_XFS_SECURITY=y
+CONFIG_XFS_POSIX_ACL=y
+# CONFIG_XFS_RT is not set
+CONFIG_OCFS2_FS=m
+# CONFIG_OCFS2_DEBUG_MASKLOG is not set
+CONFIG_MINIX_FS=m
+CONFIG_ROMFS_FS=m
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+CONFIG_QUOTA=y
+# CONFIG_QFMT_V1 is not set
+CONFIG_QFMT_V2=y
+CONFIG_QUOTACTL=y
+CONFIG_DNOTIFY=y
+CONFIG_AUTOFS_FS=m
+CONFIG_AUTOFS4_FS=m
+CONFIG_FUSE_FS=m
+
+#
+# Caches
+#
+CONFIG_FSCACHE=m
+
+#
+# CD-ROM/DVD Filesystems
+#
+CONFIG_ISO9660_FS=y
+CONFIG_JOLIET=y
+CONFIG_ZISOFS=y
+CONFIG_ZISOFS_FS=y
+CONFIG_UDF_FS=m
+CONFIG_UDF_NLS=y
+CONFIG_CACHEFILES=m
+CONFIG_CACHEFILES_DEBUG=y
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=m
+CONFIG_MSDOS_FS=m
+CONFIG_VFAT_FS=m
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="ascii"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+CONFIG_HUGETLBFS=y
+CONFIG_HUGETLB_PAGE=y
+CONFIG_RAMFS=y
+CONFIG_CONFIGFS_FS=m
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+CONFIG_AFFS_FS=m
+CONFIG_HFS_FS=m
+CONFIG_HFSPLUS_FS=m
+CONFIG_BEFS_FS=m
+# CONFIG_BEFS_DEBUG is not set
+CONFIG_BFS_FS=m
+CONFIG_EFS_FS=m
+# CONFIG_JFFS_FS is not set
+CONFIG_JFFS2_FS=m
+CONFIG_JFFS2_FS_DEBUG=0
+CONFIG_JFFS2_FS_WRITEBUFFER=y
+CONFIG_JFFS2_SUMMARY=y
+# 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=m
+CONFIG_SQUASHFS=m
+# CONFIG_SQUASHFS_EMBEDDED is not set
+CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3
+# CONFIG_SQUASHFS_VMALLOC is not set
+CONFIG_VXFS_FS=m
+# CONFIG_HPFS_FS is not set
+CONFIG_QNX4FS_FS=m
+CONFIG_SYSV_FS=m
+CONFIG_UFS_FS=m
+# CONFIG_UFS_FS_WRITE is not set
+# CONFIG_UFS_DEBUG is not set
+
+#
+# Network File Systems
+#
+CONFIG_NFS_FS=m
+CONFIG_NFS_V3=y
+CONFIG_NFS_V3_ACL=y
+CONFIG_NFS_V4=y
+CONFIG_NFS_FSCACHE=y
+CONFIG_NFS_DIRECTIO=y
+CONFIG_NFSD=m
+CONFIG_NFSD_V2_ACL=y
+CONFIG_NFSD_V3=y
+CONFIG_NFSD_V3_ACL=y
+CONFIG_NFSD_V4=y
+CONFIG_NFSD_TCP=y
+CONFIG_LOCKD=m
+CONFIG_LOCKD_V4=y
+CONFIG_EXPORTFS=m
+CONFIG_NFS_ACL_SUPPORT=m
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=m
+CONFIG_SUNRPC_GSS=m
+CONFIG_RPCSEC_GSS_KRB5=m
+CONFIG_RPCSEC_GSS_SPKM3=m
+# CONFIG_SMB_FS is not set
+CONFIG_CIFS=m
+# CONFIG_CIFS_STATS is not set
+CONFIG_CIFS_WEAK_PW_HASH=y
+CONFIG_CIFS_XATTR=y
+CONFIG_CIFS_POSIX=y
+# CONFIG_CIFS_DEBUG2 is not set
+# CONFIG_CIFS_EXPERIMENTAL is not set
+CONFIG_NCP_FS=m
+CONFIG_NCPFS_PACKET_SIGNING=y
+CONFIG_NCPFS_IOCTL_LOCKING=y
+CONFIG_NCPFS_STRONG=y
+CONFIG_NCPFS_NFS_NS=y
+CONFIG_NCPFS_OS2_NS=y
+CONFIG_NCPFS_SMALLDOS=y
+CONFIG_NCPFS_NLS=y
+CONFIG_NCPFS_EXTRAS=y
+CONFIG_CODA_FS=m
+# CONFIG_CODA_FS_OLD_API is not set
+# CONFIG_AFS_FS is not set
+CONFIG_9P_FS=m
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+CONFIG_OSF_PARTITION=y
+CONFIG_AMIGA_PARTITION=y
+# CONFIG_ATARI_PARTITION is not set
+CONFIG_MAC_PARTITION=y
+CONFIG_MSDOS_PARTITION=y
+CONFIG_BSD_DISKLABEL=y
+CONFIG_MINIX_SUBPARTITION=y
+CONFIG_SOLARIS_X86_PARTITION=y
+CONFIG_UNIXWARE_DISKLABEL=y
+# CONFIG_LDM_PARTITION is not set
+CONFIG_SGI_PARTITION=y
+# CONFIG_ULTRIX_PARTITION is not set
+CONFIG_SUN_PARTITION=y
+CONFIG_KARMA_PARTITION=y
+CONFIG_EFI_PARTITION=y
+
+#
+# Native Language Support
+#
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="utf8"
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_CODEPAGE_737=m
+CONFIG_NLS_CODEPAGE_775=m
+CONFIG_NLS_CODEPAGE_850=m
+CONFIG_NLS_CODEPAGE_852=m
+CONFIG_NLS_CODEPAGE_855=m
+CONFIG_NLS_CODEPAGE_857=m
+CONFIG_NLS_CODEPAGE_860=m
+CONFIG_NLS_CODEPAGE_861=m
+CONFIG_NLS_CODEPAGE_862=m
+CONFIG_NLS_CODEPAGE_863=m
+CONFIG_NLS_CODEPAGE_864=m
+CONFIG_NLS_CODEPAGE_865=m
+CONFIG_NLS_CODEPAGE_866=m
+CONFIG_NLS_CODEPAGE_869=m
+CONFIG_NLS_CODEPAGE_936=m
+CONFIG_NLS_CODEPAGE_950=m
+CONFIG_NLS_CODEPAGE_932=m
+CONFIG_NLS_CODEPAGE_949=m
+CONFIG_NLS_CODEPAGE_874=m
+CONFIG_NLS_ISO8859_8=m
+CONFIG_NLS_CODEPAGE_1250=m
+CONFIG_NLS_CODEPAGE_1251=m
+CONFIG_NLS_ASCII=y
+CONFIG_NLS_ISO8859_1=m
+CONFIG_NLS_ISO8859_2=m
+CONFIG_NLS_ISO8859_3=m
+CONFIG_NLS_ISO8859_4=m
+CONFIG_NLS_ISO8859_5=m
+CONFIG_NLS_ISO8859_6=m
+CONFIG_NLS_ISO8859_7=m
+CONFIG_NLS_ISO8859_9=m
+CONFIG_NLS_ISO8859_13=m
+CONFIG_NLS_ISO8859_14=m
+CONFIG_NLS_ISO8859_15=m
+CONFIG_NLS_KOI8_R=m
+CONFIG_NLS_KOI8_U=m
+CONFIG_NLS_UTF8=m
+
+#
+# Library routines
+#
+CONFIG_CRC_CCITT=m
+CONFIG_CRC16=m
+CONFIG_CRC32=y
+CONFIG_LIBCRC32C=m
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=m
+CONFIG_REED_SOLOMON=m
+CONFIG_REED_SOLOMON_DEC16=y
+CONFIG_TEXTSEARCH=y
+CONFIG_TEXTSEARCH_KMP=m
+CONFIG_TEXTSEARCH_BM=m
+CONFIG_TEXTSEARCH_FSM=m
+CONFIG_PLIST=y
+
+#
+# Instrumentation Support
+#
+CONFIG_PROFILING=y
+CONFIG_OPROFILE=m
+CONFIG_KPROBES=y
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_UNUSED_SYMBOLS is not set
+CONFIG_DEBUG_KERNEL=y
+CONFIG_LOG_BUF_SHIFT=17
+CONFIG_DETECT_SOFTLOCKUP=y
+CONFIG_SCHEDSTATS=y
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
+CONFIG_DEBUG_SPINLOCK=y
+# CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_RWSEMS is not set
+CONFIG_DEBUG_SPINLOCK_SLEEP=y
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+# CONFIG_DEBUG_KOBJECT is not set
+CONFIG_DEBUG_INFO=y
+CONFIG_DEBUG_FS=y
+# CONFIG_DEBUG_VM is not set
+CONFIG_DEBUG_LIST=y
+# CONFIG_FORCED_INLINING is not set
+CONFIG_BOOT_DELAY=y
+# CONFIG_RCU_TORTURE_TEST is not set
+CONFIG_DEBUG_STACKOVERFLOW=y
+CONFIG_DEBUG_STACK_USAGE=y
+CONFIG_DEBUGGER=y
+CONFIG_XMON=y
+CONFIG_XMON_DEFAULT=y
+CONFIG_IRQSTACKS=y
+CONFIG_BOOTX_TEXT=y
+# CONFIG_PPC_EARLY_DEBUG is not set
+
+#
+# Security options
+#
+CONFIG_KEYS=y
+CONFIG_KEYS_DEBUG_PROC_KEYS=y
+CONFIG_SECURITY=y
+CONFIG_SECURITY_NETWORK=y
+# CONFIG_SECURITY_NETWORK_XFRM is not set
+CONFIG_SECURITY_CAPABILITIES=y
+# CONFIG_SECURITY_ROOTPLUG is not set
+# CONFIG_SECURITY_SECLVL is not set
+CONFIG_SECURITY_SELINUX=y
+CONFIG_SECURITY_SELINUX_BOOTPARAM=y
+CONFIG_SECURITY_SELINUX_BOOTPARAM_VALUE=1
+CONFIG_SECURITY_SELINUX_DISABLE=y
+CONFIG_SECURITY_SELINUX_DEVELOP=y
+CONFIG_SECURITY_SELINUX_AVC_STATS=y
+CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE=1
+# CONFIG_SECURITY_SELINUX_ENABLE_SECMARK_DEFAULT is not set
+# CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX is not set
+CONFIG_KEYS_COMPAT=y
+
+#
+# Cryptographic options
+#
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_NULL=m
+CONFIG_CRYPTO_MD4=m
+CONFIG_CRYPTO_MD5=m
+CONFIG_CRYPTO_SHA1=y
+CONFIG_CRYPTO_SHA256=m
+CONFIG_CRYPTO_SHA512=m
+CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_TGR192=m
+CONFIG_CRYPTO_DES=m
+CONFIG_CRYPTO_BLOWFISH=m
+CONFIG_CRYPTO_TWOFISH=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_TEST is not set
+CONFIG_CRYPTO_SIGNATURE=y
+CONFIG_CRYPTO_SIGNATURE_DSA=y
+CONFIG_CRYPTO_MPILIB=y
+
+#
+# Hardware crypto devices
+#
diff --git a/configs/kernel-2.6.18-ppc64iseries.config b/configs/kernel-2.6.18-ppc64iseries.config
new file mode 100644
index 000000000..ffeabee01
--- /dev/null
+++ b/configs/kernel-2.6.18-ppc64iseries.config
@@ -0,0 +1,1586 @@
+# powerpc
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.18.2-rc1
+# Mon Nov 13 09:44:42 2006
+#
+CONFIG_PPC64=y
+CONFIG_64BIT=y
+CONFIG_PPC_MERGE=y
+CONFIG_MMU=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_IRQ_PER_CPU=y
+CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_PPC=y
+CONFIG_EARLY_PRINTK=y
+CONFIG_COMPAT=y
+CONFIG_SYSVIPC_COMPAT=y
+CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
+CONFIG_ARCH_MAY_HAVE_PC_FDC=y
+CONFIG_PPC_OF=y
+# CONFIG_PPC_UDBG_16550 is not set
+# CONFIG_GENERIC_TBSYNC is not set
+CONFIG_AUDIT_ARCH=y
+# CONFIG_DEFAULT_UIMAGE is not set
+
+#
+# Processor support
+#
+# CONFIG_POWER4_ONLY is not set
+CONFIG_POWER3=y
+CONFIG_POWER4=y
+CONFIG_PPC_FPU=y
+CONFIG_ALTIVEC=y
+CONFIG_PPC_STD_MMU=y
+CONFIG_VIRT_CPU_ACCOUNTING=y
+CONFIG_SMP=y
+CONFIG_NR_CPUS=128
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_BSD_PROCESS_ACCT=y
+# CONFIG_BSD_PROCESS_ACCT_V3 is not set
+CONFIG_TASKSTATS=y
+CONFIG_TASK_DELAY_ACCT=y
+CONFIG_AUDIT=y
+CONFIG_AUDITSYSCALL=y
+# CONFIG_IKCONFIG is not set
+CONFIG_CPUSETS=y
+CONFIG_RELAY=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+# CONFIG_EMBEDDED is not set
+CONFIG_SYSCTL=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
+CONFIG_KALLSYMS_EXTRA_PASS=y
+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=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+CONFIG_MODULE_SIG=y
+# CONFIG_MODULE_SIG_FORCE is not set
+CONFIG_KMOD=y
+CONFIG_STOP_MACHINE=y
+
+#
+# Process debugging support
+#
+CONFIG_UTRACE=y
+CONFIG_PTRACE=y
+
+#
+# Block layer
+#
+CONFIG_BLK_DEV_IO_TRACE=y
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_DEFAULT_AS is not set
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+
+#
+# Platform support
+#
+# CONFIG_PPC_MULTIPLATFORM is not set
+CONFIG_PPC_ISERIES=y
+# CONFIG_EMBEDDED6xx is not set
+# CONFIG_APUS is not set
+# CONFIG_PPC_CELL is not set
+# CONFIG_PPC_CELL_NATIVE is not set
+# CONFIG_UDBG_RTAS_CONSOLE is not set
+# CONFIG_MAMBO is not set
+# CONFIG_PPC_RTAS is not set
+# CONFIG_MMIO_NVRAM is not set
+CONFIG_IBMVIO=y
+# CONFIG_PPC_MPC106 is not set
+# CONFIG_PPC_970_NAP is not set
+# CONFIG_CPU_FREQ is not set
+# CONFIG_WANT_EARLY_SERIAL is not set
+# CONFIG_MPIC is not set
+
+#
+# Kernel options
+#
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
+# CONFIG_PREEMPT_NONE is not set
+CONFIG_PREEMPT_VOLUNTARY=y
+# CONFIG_PREEMPT is not set
+CONFIG_PREEMPT_BKL=y
+CONFIG_BINFMT_ELF=y
+CONFIG_BINFMT_MISC=y
+CONFIG_FORCE_MAX_ZONEORDER=9
+CONFIG_IOMMU_VMERGE=y
+CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
+CONFIG_IRQ_ALL_CPUS=y
+CONFIG_LPARCFG=y
+# CONFIG_NUMA is not set
+CONFIG_ARCH_SELECT_MEMORY_MODEL=y
+CONFIG_ARCH_FLATMEM_ENABLE=y
+CONFIG_ARCH_SPARSEMEM_ENABLE=y
+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=4
+CONFIG_RESOURCES_64BIT=y
+CONFIG_PPC_64K_PAGES=y
+# CONFIG_SCHED_SMT is not set
+CONFIG_PROC_DEVICETREE=y
+CONFIG_PM=y
+CONFIG_PM_LEGACY=y
+# CONFIG_PM_DEBUG is not set
+# CONFIG_SECCOMP is not set
+CONFIG_ISA_DMA_API=y
+
+#
+# Bus options
+#
+CONFIG_GENERIC_ISA_DMA=y
+# CONFIG_MPIC_WEIRD is not set
+# CONFIG_PPC_I8259 is not set
+# CONFIG_PPC_INDIRECT_PCI is not set
+CONFIG_PCI=y
+CONFIG_PCI_DOMAINS=y
+CONFIG_PCIEPORTBUS=y
+# CONFIG_HOTPLUG_PCI_PCIE is not set
+# CONFIG_PCI_DEBUG is not set
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# PCI Hotplug Support
+#
+CONFIG_HOTPLUG_PCI=y
+# CONFIG_HOTPLUG_PCI_FAKE is not set
+# CONFIG_HOTPLUG_PCI_CPCI is not set
+CONFIG_HOTPLUG_PCI_SHPC=m
+CONFIG_HOTPLUG_PCI_SHPC_POLL_EVENT_MODE=y
+CONFIG_KERNEL_START=0xc000000000000000
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+# CONFIG_NETDEBUG is not set
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=y
+CONFIG_NET_KEY=m
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_ASK_IP_FIB_HASH=y
+# 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
+# CONFIG_IP_PNP is not set
+CONFIG_NET_IPIP=m
+CONFIG_NET_IPGRE=m
+CONFIG_NET_IPGRE_BROADCAST=y
+CONFIG_IP_MROUTE=y
+CONFIG_IP_PIMSM_V1=y
+CONFIG_IP_PIMSM_V2=y
+# CONFIG_ARPD is not set
+CONFIG_SYN_COOKIES=y
+CONFIG_INET_AH=m
+CONFIG_INET_ESP=m
+CONFIG_INET_IPCOMP=m
+CONFIG_INET_XFRM_TUNNEL=m
+CONFIG_INET_TUNNEL=m
+CONFIG_INET_XFRM_MODE_TRANSPORT=m
+CONFIG_INET_XFRM_MODE_TUNNEL=m
+CONFIG_INET_DIAG=m
+CONFIG_INET_TCP_DIAG=m
+CONFIG_TCP_CONG_ADVANCED=y
+
+#
+# TCP congestion control
+#
+CONFIG_TCP_CONG_BIC=y
+CONFIG_TCP_CONG_CUBIC=m
+CONFIG_TCP_CONG_WESTWOOD=m
+CONFIG_TCP_CONG_HTCP=m
+CONFIG_TCP_CONG_HSTCP=m
+CONFIG_TCP_CONG_HYBLA=m
+CONFIG_TCP_CONG_VEGAS=m
+CONFIG_TCP_CONG_SCALABLE=m
+CONFIG_TCP_CONG_LP=m
+CONFIG_TCP_CONG_VENO=m
+
+#
+# IP: Virtual Server Configuration
+#
+CONFIG_IP_VS=m
+# CONFIG_IP_VS_DEBUG is not set
+CONFIG_IP_VS_TAB_BITS=12
+
+#
+# IPVS transport protocol load balancing support
+#
+CONFIG_IP_VS_PROTO_TCP=y
+CONFIG_IP_VS_PROTO_UDP=y
+CONFIG_IP_VS_PROTO_ESP=y
+CONFIG_IP_VS_PROTO_AH=y
+
+#
+# IPVS scheduler
+#
+CONFIG_IP_VS_RR=m
+CONFIG_IP_VS_WRR=m
+CONFIG_IP_VS_LC=m
+CONFIG_IP_VS_WLC=m
+CONFIG_IP_VS_LBLC=m
+CONFIG_IP_VS_LBLCR=m
+CONFIG_IP_VS_DH=m
+CONFIG_IP_VS_SH=m
+CONFIG_IP_VS_SED=m
+CONFIG_IP_VS_NQ=m
+
+#
+# IPVS application helper
+#
+CONFIG_IP_VS_FTP=m
+CONFIG_IPV6=m
+CONFIG_IPV6_PRIVACY=y
+CONFIG_IPV6_ROUTER_PREF=y
+CONFIG_IPV6_ROUTE_INFO=y
+CONFIG_INET6_AH=m
+CONFIG_INET6_ESP=m
+CONFIG_INET6_IPCOMP=m
+CONFIG_INET6_XFRM_TUNNEL=m
+CONFIG_INET6_TUNNEL=m
+CONFIG_INET6_XFRM_MODE_TRANSPORT=m
+CONFIG_INET6_XFRM_MODE_TUNNEL=m
+CONFIG_IPV6_TUNNEL=m
+CONFIG_NETWORK_SECMARK=y
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_DEBUG is not set
+CONFIG_BRIDGE_NETFILTER=y
+
+#
+# Core Netfilter Configuration
+#
+CONFIG_NETFILTER_NETLINK=m
+CONFIG_NETFILTER_NETLINK_QUEUE=m
+CONFIG_NETFILTER_NETLINK_LOG=m
+CONFIG_NETFILTER_XTABLES=m
+CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
+CONFIG_NETFILTER_XT_TARGET_CONNMARK=m
+CONFIG_NETFILTER_XT_TARGET_MARK=m
+CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
+CONFIG_NETFILTER_XT_TARGET_NOTRACK=m
+CONFIG_NETFILTER_XT_TARGET_SECMARK=m
+CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=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_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_PHYSDEV=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
+
+#
+# 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=m
+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_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_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_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
+CONFIG_IP_NF_ARPTABLES=m
+CONFIG_IP_NF_ARPFILTER=m
+CONFIG_IP_NF_ARP_MANGLE=m
+
+#
+# IPv6: Netfilter Configuration (EXPERIMENTAL)
+#
+CONFIG_IP6_NF_QUEUE=m
+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_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
+
+#
+# DECnet: Netfilter Configuration
+#
+# CONFIG_DECNET_NF_GRABULATOR is not set
+
+#
+# Bridge: Netfilter Configuration
+#
+CONFIG_BRIDGE_NF_EBTABLES=m
+CONFIG_BRIDGE_EBT_BROUTE=m
+CONFIG_BRIDGE_EBT_T_FILTER=m
+CONFIG_BRIDGE_EBT_T_NAT=m
+CONFIG_BRIDGE_EBT_802_3=m
+CONFIG_BRIDGE_EBT_AMONG=m
+CONFIG_BRIDGE_EBT_ARP=m
+CONFIG_BRIDGE_EBT_IP=m
+CONFIG_BRIDGE_EBT_LIMIT=m
+CONFIG_BRIDGE_EBT_MARK=m
+CONFIG_BRIDGE_EBT_PKTTYPE=m
+CONFIG_BRIDGE_EBT_STP=m
+CONFIG_BRIDGE_EBT_VLAN=m
+CONFIG_BRIDGE_EBT_ARPREPLY=m
+CONFIG_BRIDGE_EBT_DNAT=m
+CONFIG_BRIDGE_EBT_MARK_T=m
+CONFIG_BRIDGE_EBT_REDIRECT=m
+CONFIG_BRIDGE_EBT_SNAT=m
+CONFIG_BRIDGE_EBT_LOG=m
+CONFIG_BRIDGE_EBT_ULOG=m
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+CONFIG_IP_DCCP=m
+CONFIG_INET_DCCP_DIAG=m
+CONFIG_IP_DCCP_ACKVEC=y
+
+#
+# DCCP CCIDs Configuration (EXPERIMENTAL)
+#
+CONFIG_IP_DCCP_CCID2=m
+CONFIG_IP_DCCP_CCID3=m
+CONFIG_IP_DCCP_TFRC_LIB=m
+
+#
+# DCCP Kernel Hacking
+#
+# CONFIG_IP_DCCP_DEBUG is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+CONFIG_IP_SCTP=m
+# CONFIG_SCTP_DBG_MSG is not set
+# CONFIG_SCTP_DBG_OBJCNT is not set
+# CONFIG_SCTP_HMAC_NONE is not set
+# CONFIG_SCTP_HMAC_SHA1 is not set
+CONFIG_SCTP_HMAC_MD5=y
+
+#
+# TIPC Configuration (EXPERIMENTAL)
+#
+CONFIG_TIPC=m
+# CONFIG_TIPC_ADVANCED is not set
+# CONFIG_TIPC_DEBUG is not set
+# CONFIG_ATM is not set
+CONFIG_BRIDGE=m
+CONFIG_VLAN_8021Q=m
+CONFIG_DECNET=m
+CONFIG_DECNET_ROUTER=y
+CONFIG_DECNET_ROUTE_FWMARK=y
+CONFIG_LLC=y
+# 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=y
+# CONFIG_NET_SCH_CLK_JIFFIES is not set
+CONFIG_NET_SCH_CLK_GETTIMEOFDAY=y
+# CONFIG_NET_SCH_CLK_CPU is not set
+
+#
+# Queueing/Scheduling
+#
+CONFIG_NET_SCH_CBQ=m
+CONFIG_NET_SCH_HTB=m
+CONFIG_NET_SCH_HFSC=m
+CONFIG_NET_SCH_PRIO=m
+CONFIG_NET_SCH_RED=m
+CONFIG_NET_SCH_SFQ=m
+CONFIG_NET_SCH_TEQL=m
+CONFIG_NET_SCH_TBF=m
+CONFIG_NET_SCH_GRED=m
+CONFIG_NET_SCH_DSMARK=m
+CONFIG_NET_SCH_NETEM=m
+CONFIG_NET_SCH_INGRESS=m
+
+#
+# Classification
+#
+CONFIG_NET_CLS=y
+CONFIG_NET_CLS_BASIC=m
+CONFIG_NET_CLS_TCINDEX=m
+CONFIG_NET_CLS_ROUTE4=m
+CONFIG_NET_CLS_ROUTE=y
+CONFIG_NET_CLS_FW=m
+CONFIG_NET_CLS_U32=m
+CONFIG_CLS_U32_PERF=y
+CONFIG_CLS_U32_MARK=y
+CONFIG_NET_CLS_RSVP=m
+CONFIG_NET_CLS_RSVP6=m
+CONFIG_NET_EMATCH=y
+CONFIG_NET_EMATCH_STACK=32
+CONFIG_NET_EMATCH_CMP=m
+CONFIG_NET_EMATCH_NBYTE=m
+CONFIG_NET_EMATCH_U32=m
+CONFIG_NET_EMATCH_META=m
+CONFIG_NET_EMATCH_TEXT=m
+CONFIG_NET_CLS_ACT=y
+CONFIG_NET_ACT_POLICE=m
+CONFIG_NET_ACT_GACT=m
+CONFIG_GACT_PROB=y
+CONFIG_NET_ACT_MIRRED=m
+CONFIG_NET_ACT_IPT=m
+CONFIG_NET_ACT_PEDIT=m
+CONFIG_NET_ACT_SIMP=m
+CONFIG_NET_CLS_IND=y
+CONFIG_NET_ESTIMATOR=y
+
+#
+# Network testing
+#
+CONFIG_NET_PKTGEN=m
+# CONFIG_NET_TCPPROBE is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_IEEE80211 is not set
+CONFIG_TUX=m
+
+#
+# TUX options
+#
+CONFIG_TUX_EXTCGI=y
+CONFIG_TUX_EXTENDED_LOG=y
+# CONFIG_TUX_DEBUG is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_SYS_HYPERVISOR is not set
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+CONFIG_CONNECTOR=y
+CONFIG_PROC_EVENTS=y
+
+#
+# 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_FD is not set
+# CONFIG_BLK_CPQ_DA is not set
+CONFIG_BLK_CPQ_CISS_DA=m
+CONFIG_CISS_SCSI_TAPE=y
+CONFIG_BLK_DEV_DAC960=m
+CONFIG_BLK_DEV_UMEM=m
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=m
+CONFIG_BLK_DEV_CRYPTOLOOP=m
+CONFIG_BLK_DEV_NBD=m
+# CONFIG_BLK_DEV_SX8 is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=16384
+CONFIG_BLK_DEV_RAM_BLOCKSIZE=4096
+CONFIG_BLK_DEV_INITRD=y
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+CONFIG_RAID_ATTRS=m
+CONFIG_SCSI=m
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=m
+CONFIG_CHR_DEV_ST=m
+CONFIG_CHR_DEV_OSST=m
+CONFIG_BLK_DEV_SR=m
+CONFIG_BLK_DEV_SR_VENDOR=y
+CONFIG_CHR_DEV_SG=m
+CONFIG_CHR_DEV_SCH=m
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+CONFIG_SCSI_MULTI_LUN=y
+CONFIG_SCSI_CONSTANTS=y
+CONFIG_SCSI_LOGGING=y
+
+#
+# SCSI Transport Attributes
+#
+CONFIG_SCSI_SPI_ATTRS=m
+CONFIG_SCSI_FC_ATTRS=m
+CONFIG_SCSI_ISCSI_ATTRS=m
+CONFIG_SCSI_SAS_ATTRS=m
+
+#
+# SCSI low-level drivers
+#
+CONFIG_ISCSI_TCP=m
+CONFIG_BLK_DEV_3W_XXXX_RAID=m
+# CONFIG_SCSI_3W_9XXX is not set
+CONFIG_SCSI_ACARD=m
+CONFIG_SCSI_AACRAID=m
+CONFIG_SCSI_AIC7XXX=m
+CONFIG_AIC7XXX_CMDS_PER_DEVICE=4
+CONFIG_AIC7XXX_RESET_DELAY_MS=15000
+# CONFIG_AIC7XXX_DEBUG_ENABLE is not set
+CONFIG_AIC7XXX_DEBUG_MASK=0
+# CONFIG_AIC7XXX_REG_PRETTY_PRINT is not set
+CONFIG_SCSI_AIC7XXX_OLD=m
+CONFIG_SCSI_AIC79XX=m
+CONFIG_AIC79XX_CMDS_PER_DEVICE=4
+CONFIG_AIC79XX_RESET_DELAY_MS=15000
+# CONFIG_AIC79XX_ENABLE_RD_STRM is not set
+# CONFIG_AIC79XX_DEBUG_ENABLE is not set
+CONFIG_AIC79XX_DEBUG_MASK=0
+# CONFIG_AIC79XX_REG_PRETTY_PRINT is not set
+CONFIG_MEGARAID_NEWGEN=y
+CONFIG_MEGARAID_MM=m
+CONFIG_MEGARAID_MAILBOX=m
+CONFIG_MEGARAID_LEGACY=m
+CONFIG_MEGARAID_SAS=m
+# CONFIG_SCSI_SATA is not set
+CONFIG_SCSI_HPTIOP=m
+# CONFIG_SCSI_BUSLOGIC is not set
+# CONFIG_SCSI_DMX3191D is not set
+# CONFIG_SCSI_EATA is not set
+# CONFIG_SCSI_FUTURE_DOMAIN is not set
+CONFIG_SCSI_GDTH=m
+# CONFIG_SCSI_IPS is not set
+CONFIG_SCSI_IBMVSCSI=m
+CONFIG_SCSI_INITIO=m
+CONFIG_SCSI_INIA100=m
+CONFIG_SCSI_SYM53C8XX_2=m
+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_QLOGIC_1280=m
+CONFIG_SCSI_QLA_FC=m
+CONFIG_SCSI_LPFC=m
+CONFIG_SCSI_DC395x=m
+# CONFIG_SCSI_DC390T is not set
+# CONFIG_SCSI_DEBUG is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+CONFIG_MD=y
+CONFIG_BLK_DEV_MD=y
+CONFIG_MD_LINEAR=m
+CONFIG_MD_RAID0=m
+CONFIG_MD_RAID1=m
+CONFIG_MD_RAID10=m
+CONFIG_MD_RAID456=m
+CONFIG_MD_RAID5_RESHAPE=y
+CONFIG_MD_MULTIPATH=m
+CONFIG_MD_FAULTY=m
+CONFIG_BLK_DEV_DM=m
+CONFIG_DM_CRYPT=m
+CONFIG_DM_SNAPSHOT=m
+CONFIG_DM_MIRROR=m
+CONFIG_DM_ZERO=m
+CONFIG_DM_MULTIPATH=m
+CONFIG_DM_MULTIPATH_EMC=m
+
+#
+# Fusion MPT device support
+#
+CONFIG_FUSION=y
+CONFIG_FUSION_SPI=m
+CONFIG_FUSION_FC=m
+CONFIG_FUSION_SAS=m
+CONFIG_FUSION_MAX_SGE=40
+CONFIG_FUSION_CTL=m
+CONFIG_FUSION_LAN=m
+
+#
+# IEEE 1394 (FireWire) support
+#
+# CONFIG_IEEE1394 is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+
+#
+# Macintosh device drivers
+#
+# CONFIG_WINDFARM is not set
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+CONFIG_IFB=m
+CONFIG_DUMMY=m
+CONFIG_BONDING=m
+CONFIG_EQUALIZER=m
+CONFIG_TUN=m
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+
+#
+# PHY device support
+#
+CONFIG_PHYLIB=m
+
+#
+# MII PHY device drivers
+#
+CONFIG_MARVELL_PHY=m
+CONFIG_DAVICOM_PHY=m
+CONFIG_QSEMI_PHY=m
+CONFIG_LXT_PHY=m
+CONFIG_CICADA_PHY=m
+CONFIG_VITESSE_PHY=m
+CONFIG_SMSC_PHY=m
+CONFIG_FIXED_PHY=m
+CONFIG_FIXED_MII_10_FDX=y
+CONFIG_FIXED_MII_100_FDX=y
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=m
+CONFIG_HAPPYMEAL=m
+# CONFIG_SUNGEM is not set
+CONFIG_CASSINI=m
+CONFIG_NET_VENDOR_3COM=y
+# CONFIG_VORTEX is not set
+CONFIG_TYPHOON=m
+
+#
+# Tulip family network device support
+#
+CONFIG_NET_TULIP=y
+CONFIG_DE2104X=m
+CONFIG_TULIP=m
+# CONFIG_TULIP_MWI is not set
+CONFIG_TULIP_MMIO=y
+# CONFIG_TULIP_NAPI is not set
+CONFIG_DE4X5=m
+CONFIG_WINBOND_840=m
+CONFIG_DM9102=m
+CONFIG_ULI526X=m
+# CONFIG_HP100 is not set
+CONFIG_NET_PCI=y
+CONFIG_PCNET32=m
+CONFIG_AMD8111_ETH=m
+CONFIG_AMD8111E_NAPI=y
+CONFIG_ADAPTEC_STARFIRE=m
+CONFIG_ADAPTEC_STARFIRE_NAPI=y
+CONFIG_B44=m
+CONFIG_FORCEDETH=m
+# CONFIG_DGRS is not set
+# CONFIG_EEPRO100 is not set
+CONFIG_E100=m
+# CONFIG_FEALNX is not set
+CONFIG_NATSEMI=m
+# CONFIG_NE2K_PCI is not set
+CONFIG_8139CP=m
+# CONFIG_8139TOO is not set
+CONFIG_SIS900=m
+CONFIG_EPIC100=m
+CONFIG_SUNDANCE=m
+# CONFIG_SUNDANCE_MMIO is not set
+CONFIG_VIA_RHINE=m
+CONFIG_VIA_RHINE_MMIO=y
+CONFIG_VIA_RHINE_NAPI=y
+
+#
+# Ethernet (1000 Mbit)
+#
+CONFIG_ACENIC=m
+# CONFIG_ACENIC_OMIT_TIGON_I is not set
+# CONFIG_DL2K is not set
+CONFIG_E1000=m
+CONFIG_E1000_NAPI=y
+# CONFIG_E1000_DISABLE_PACKET_SPLIT is not set
+CONFIG_NS83820=m
+CONFIG_HAMACHI=m
+CONFIG_YELLOWFIN=m
+# CONFIG_R8169 is not set
+CONFIG_SIS190=m
+CONFIG_SKGE=m
+CONFIG_SKY2=m
+# CONFIG_SK98LIN is not set
+CONFIG_VIA_VELOCITY=m
+CONFIG_TIGON3=m
+CONFIG_BNX2=m
+
+#
+# Ethernet (10000 Mbit)
+#
+CONFIG_CHELSIO_T1=m
+CONFIG_IXGB=m
+CONFIG_IXGB_NAPI=y
+CONFIG_S2IO=m
+CONFIG_S2IO_NAPI=y
+CONFIG_MYRI10GE=m
+
+#
+# Token Ring devices
+#
+CONFIG_TR=y
+CONFIG_IBMOL=m
+CONFIG_3C359=m
+# CONFIG_TMS380TR is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+CONFIG_ISERIES_VETH=m
+CONFIG_FDDI=y
+# CONFIG_DEFXX is not set
+CONFIG_SKFP=m
+# CONFIG_HIPPI is not set
+CONFIG_PPP=m
+CONFIG_PPP_MULTILINK=y
+CONFIG_PPP_FILTER=y
+CONFIG_PPP_ASYNC=m
+CONFIG_PPP_SYNC_TTY=m
+CONFIG_PPP_DEFLATE=m
+# CONFIG_PPP_BSDCOMP is not set
+CONFIG_PPP_MPPE=m
+CONFIG_PPPOE=m
+CONFIG_SLIP=m
+CONFIG_SLIP_COMPRESSED=y
+CONFIG_SLIP_SMART=y
+# CONFIG_SLIP_MODE_SLIP6 is not set
+CONFIG_NET_FC=y
+# CONFIG_SHAPER is not set
+CONFIG_NETCONSOLE=m
+CONFIG_NETPOLL=y
+# CONFIG_NETPOLL_RX is not set
+CONFIG_NETPOLL_TRAP=y
+CONFIG_NET_POLL_CONTROLLER=y
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Telephony Support
+#
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+
+#
+# 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=m
+# CONFIG_INPUT_TSDEV is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+CONFIG_KEYBOARD_ATKBD=y
+# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_KEYBOARD_LKKBD is not set
+# CONFIG_KEYBOARD_XTKBD is not set
+# CONFIG_KEYBOARD_NEWTON is not set
+CONFIG_INPUT_MOUSE=y
+CONFIG_MOUSE_PS2=y
+CONFIG_MOUSE_SERIAL=m
+CONFIG_MOUSE_VSXXXAA=m
+CONFIG_INPUT_JOYSTICK=y
+CONFIG_JOYSTICK_ANALOG=m
+CONFIG_JOYSTICK_A3D=m
+CONFIG_JOYSTICK_ADI=m
+CONFIG_JOYSTICK_COBRA=m
+CONFIG_JOYSTICK_GF2K=m
+CONFIG_JOYSTICK_GRIP=m
+CONFIG_JOYSTICK_GRIP_MP=m
+CONFIG_JOYSTICK_GUILLEMOT=m
+CONFIG_JOYSTICK_INTERACT=m
+CONFIG_JOYSTICK_SIDEWINDER=m
+CONFIG_JOYSTICK_TMDC=m
+CONFIG_JOYSTICK_IFORCE=m
+CONFIG_JOYSTICK_IFORCE_232=y
+CONFIG_JOYSTICK_WARRIOR=m
+CONFIG_JOYSTICK_MAGELLAN=m
+CONFIG_JOYSTICK_SPACEORB=m
+CONFIG_JOYSTICK_SPACEBALL=m
+CONFIG_JOYSTICK_STINGER=m
+CONFIG_JOYSTICK_TWIDJOY=m
+CONFIG_JOYSTICK_JOYDUMP=m
+CONFIG_INPUT_TOUCHSCREEN=y
+CONFIG_TOUCHSCREEN_GUNZE=m
+CONFIG_TOUCHSCREEN_ELO=m
+CONFIG_TOUCHSCREEN_MTOUCH=m
+CONFIG_TOUCHSCREEN_MK712=m
+CONFIG_INPUT_MISC=y
+CONFIG_INPUT_UINPUT=m
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+# CONFIG_SERIO_I8042 is not set
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_PCIPS2 is not set
+CONFIG_SERIO_LIBPS2=y
+CONFIG_SERIO_RAW=m
+CONFIG_GAMEPORT=m
+CONFIG_GAMEPORT_NS558=m
+CONFIG_GAMEPORT_L4=m
+CONFIG_GAMEPORT_EMU10K1=m
+CONFIG_GAMEPORT_FM801=m
+
+#
+# Character devices
+#
+CONFIG_SERIAL_NONSTANDARD=y
+# CONFIG_COMPUTONE is not set
+# CONFIG_ROCKETPORT is not set
+CONFIG_CYCLADES=m
+# CONFIG_CYZ_INTR is not set
+# CONFIG_DIGIEPCA is not set
+# CONFIG_MOXA_INTELLIO is not set
+# CONFIG_MOXA_SMARTIO is not set
+# CONFIG_ISI is not set
+CONFIG_SYNCLINK=m
+CONFIG_SYNCLINKMP=m
+CONFIG_SYNCLINK_GT=m
+CONFIG_N_HDLC=m
+# CONFIG_SPECIALIX is not set
+# CONFIG_SX is not set
+# CONFIG_RIO is not set
+# CONFIG_STALDRV is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_CORE=m
+CONFIG_SERIAL_ICOM=m
+CONFIG_SERIAL_JSM=m
+CONFIG_UNIX98_PTYS=y
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_CRASH is not set
+
+#
+# IPMI
+#
+# CONFIG_IPMI_HANDLER is not set
+
+#
+# Watchdog Cards
+#
+CONFIG_WATCHDOG=y
+# CONFIG_WATCHDOG_NOWAYOUT is not set
+
+#
+# Watchdog Device Drivers
+#
+CONFIG_SOFT_WATCHDOG=m
+
+#
+# PCI-based Watchdog Cards
+#
+CONFIG_PCIPCWATCHDOG=m
+CONFIG_WDTPCI=m
+CONFIG_WDT_501_PCI=y
+CONFIG_HW_RANDOM=y
+CONFIG_GEN_RTC=y
+# CONFIG_GEN_RTC_X is not set
+CONFIG_DTLK=m
+CONFIG_R3964=m
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_AGP is not set
+# CONFIG_DRM is not set
+# CONFIG_RAW_DRIVER is not set
+CONFIG_HANGCHECK_TIMER=m
+
+#
+# TPM devices
+#
+CONFIG_TCG_TPM=m
+CONFIG_TCG_ATMEL=m
+# CONFIG_TELCLOCK 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
+#
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+CONFIG_VIDEO_V4L2=y
+
+#
+# Digital Video Broadcasting Devices
+#
+# CONFIG_DVB is not set
+
+#
+# Graphics support
+#
+# CONFIG_FIRMWARE_EDID is not set
+# CONFIG_FB is not set
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+CONFIG_BACKLIGHT_CLASS_DEVICE=m
+CONFIG_BACKLIGHT_DEVICE=y
+CONFIG_LCD_CLASS_DEVICE=m
+CONFIG_LCD_DEVICE=y
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
+#
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB_ARCH_HAS_EHCI=y
+# 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
+
+#
+# LED devices
+#
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+
+#
+# LED drivers
+#
+
+#
+# LED Triggers
+#
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_LEDS_TRIGGER_TIMER=m
+CONFIG_LEDS_TRIGGER_HEARTBEAT=m
+
+#
+# InfiniBand support
+#
+# CONFIG_INFINIBAND is not set
+
+#
+# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
+#
+
+#
+# Real Time Clock
+#
+CONFIG_RTC_LIB=m
+CONFIG_RTC_CLASS=m
+
+#
+# RTC interfaces
+#
+CONFIG_RTC_INTF_SYSFS=m
+CONFIG_RTC_INTF_PROC=m
+CONFIG_RTC_INTF_DEV=m
+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
+
+#
+# RTC drivers
+#
+CONFIG_RTC_DRV_DS1553=m
+CONFIG_RTC_DRV_DS1742=m
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_TEST is not set
+CONFIG_RTC_DRV_V3020=m
+
+#
+# DMA Engine support
+#
+CONFIG_DMA_ENGINE=y
+
+#
+# DMA Clients
+#
+CONFIG_NET_DMA=y
+
+#
+# DMA Devices
+#
+# CONFIG_INTEL_IOATDMA is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+CONFIG_EXT2_FS_POSIX_ACL=y
+CONFIG_EXT2_FS_SECURITY=y
+CONFIG_EXT2_FS_XIP=y
+CONFIG_FS_XIP=y
+CONFIG_EXT3_FS=m
+CONFIG_EXT3_FS_XATTR=y
+CONFIG_EXT3_FS_POSIX_ACL=y
+CONFIG_EXT3_FS_SECURITY=y
+CONFIG_JBD=m
+# CONFIG_JBD_DEBUG is not set
+CONFIG_FS_MBCACHE=y
+CONFIG_REISERFS_FS=m
+# CONFIG_REISERFS_CHECK is not set
+CONFIG_REISERFS_PROC_INFO=y
+CONFIG_REISERFS_FS_XATTR=y
+CONFIG_REISERFS_FS_POSIX_ACL=y
+CONFIG_REISERFS_FS_SECURITY=y
+CONFIG_JFS_FS=m
+CONFIG_JFS_POSIX_ACL=y
+CONFIG_JFS_SECURITY=y
+# CONFIG_JFS_DEBUG is not set
+# CONFIG_JFS_STATISTICS is not set
+CONFIG_FS_POSIX_ACL=y
+CONFIG_XFS_FS=m
+CONFIG_XFS_QUOTA=y
+CONFIG_XFS_SECURITY=y
+CONFIG_XFS_POSIX_ACL=y
+# CONFIG_XFS_RT is not set
+CONFIG_OCFS2_FS=m
+# CONFIG_OCFS2_DEBUG_MASKLOG is not set
+CONFIG_MINIX_FS=m
+CONFIG_ROMFS_FS=m
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+CONFIG_QUOTA=y
+# CONFIG_QFMT_V1 is not set
+CONFIG_QFMT_V2=y
+CONFIG_QUOTACTL=y
+CONFIG_DNOTIFY=y
+CONFIG_AUTOFS_FS=m
+CONFIG_AUTOFS4_FS=m
+CONFIG_FUSE_FS=m
+
+#
+# Caches
+#
+CONFIG_FSCACHE=m
+
+#
+# CD-ROM/DVD Filesystems
+#
+CONFIG_ISO9660_FS=y
+CONFIG_JOLIET=y
+CONFIG_ZISOFS=y
+CONFIG_ZISOFS_FS=y
+CONFIG_UDF_FS=m
+CONFIG_UDF_NLS=y
+CONFIG_CACHEFILES=m
+CONFIG_CACHEFILES_DEBUG=y
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=m
+CONFIG_MSDOS_FS=m
+CONFIG_VFAT_FS=m
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="ascii"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+CONFIG_HUGETLBFS=y
+CONFIG_HUGETLB_PAGE=y
+CONFIG_RAMFS=y
+CONFIG_CONFIGFS_FS=m
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+CONFIG_AFFS_FS=m
+CONFIG_HFS_FS=m
+CONFIG_HFSPLUS_FS=m
+CONFIG_BEFS_FS=m
+# CONFIG_BEFS_DEBUG is not set
+CONFIG_BFS_FS=m
+CONFIG_EFS_FS=m
+CONFIG_CRAMFS=m
+CONFIG_SQUASHFS=m
+# CONFIG_SQUASHFS_EMBEDDED is not set
+CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3
+# CONFIG_SQUASHFS_VMALLOC is not set
+CONFIG_VXFS_FS=m
+# CONFIG_HPFS_FS is not set
+CONFIG_QNX4FS_FS=m
+CONFIG_SYSV_FS=m
+CONFIG_UFS_FS=m
+# CONFIG_UFS_FS_WRITE is not set
+# CONFIG_UFS_DEBUG is not set
+
+#
+# Network File Systems
+#
+CONFIG_NFS_FS=m
+CONFIG_NFS_V3=y
+CONFIG_NFS_V3_ACL=y
+CONFIG_NFS_V4=y
+CONFIG_NFS_FSCACHE=y
+CONFIG_NFS_DIRECTIO=y
+CONFIG_NFSD=m
+CONFIG_NFSD_V2_ACL=y
+CONFIG_NFSD_V3=y
+CONFIG_NFSD_V3_ACL=y
+CONFIG_NFSD_V4=y
+CONFIG_NFSD_TCP=y
+CONFIG_LOCKD=m
+CONFIG_LOCKD_V4=y
+CONFIG_EXPORTFS=m
+CONFIG_NFS_ACL_SUPPORT=m
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=m
+CONFIG_SUNRPC_GSS=m
+CONFIG_RPCSEC_GSS_KRB5=m
+CONFIG_RPCSEC_GSS_SPKM3=m
+# CONFIG_SMB_FS is not set
+CONFIG_CIFS=m
+# CONFIG_CIFS_STATS is not set
+CONFIG_CIFS_WEAK_PW_HASH=y
+CONFIG_CIFS_XATTR=y
+CONFIG_CIFS_POSIX=y
+# CONFIG_CIFS_DEBUG2 is not set
+# CONFIG_CIFS_EXPERIMENTAL is not set
+CONFIG_NCP_FS=m
+CONFIG_NCPFS_PACKET_SIGNING=y
+CONFIG_NCPFS_IOCTL_LOCKING=y
+CONFIG_NCPFS_STRONG=y
+CONFIG_NCPFS_NFS_NS=y
+CONFIG_NCPFS_OS2_NS=y
+CONFIG_NCPFS_SMALLDOS=y
+CONFIG_NCPFS_NLS=y
+CONFIG_NCPFS_EXTRAS=y
+CONFIG_CODA_FS=m
+# CONFIG_CODA_FS_OLD_API is not set
+# CONFIG_AFS_FS is not set
+CONFIG_9P_FS=m
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+CONFIG_OSF_PARTITION=y
+CONFIG_AMIGA_PARTITION=y
+# CONFIG_ATARI_PARTITION is not set
+CONFIG_MAC_PARTITION=y
+CONFIG_MSDOS_PARTITION=y
+CONFIG_BSD_DISKLABEL=y
+CONFIG_MINIX_SUBPARTITION=y
+CONFIG_SOLARIS_X86_PARTITION=y
+CONFIG_UNIXWARE_DISKLABEL=y
+# CONFIG_LDM_PARTITION is not set
+CONFIG_SGI_PARTITION=y
+# CONFIG_ULTRIX_PARTITION is not set
+CONFIG_SUN_PARTITION=y
+CONFIG_KARMA_PARTITION=y
+CONFIG_EFI_PARTITION=y
+
+#
+# Native Language Support
+#
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="utf8"
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_CODEPAGE_737=m
+CONFIG_NLS_CODEPAGE_775=m
+CONFIG_NLS_CODEPAGE_850=m
+CONFIG_NLS_CODEPAGE_852=m
+CONFIG_NLS_CODEPAGE_855=m
+CONFIG_NLS_CODEPAGE_857=m
+CONFIG_NLS_CODEPAGE_860=m
+CONFIG_NLS_CODEPAGE_861=m
+CONFIG_NLS_CODEPAGE_862=m
+CONFIG_NLS_CODEPAGE_863=m
+CONFIG_NLS_CODEPAGE_864=m
+CONFIG_NLS_CODEPAGE_865=m
+CONFIG_NLS_CODEPAGE_866=m
+CONFIG_NLS_CODEPAGE_869=m
+CONFIG_NLS_CODEPAGE_936=m
+CONFIG_NLS_CODEPAGE_950=m
+CONFIG_NLS_CODEPAGE_932=m
+CONFIG_NLS_CODEPAGE_949=m
+CONFIG_NLS_CODEPAGE_874=m
+CONFIG_NLS_ISO8859_8=m
+CONFIG_NLS_CODEPAGE_1250=m
+CONFIG_NLS_CODEPAGE_1251=m
+CONFIG_NLS_ASCII=y
+CONFIG_NLS_ISO8859_1=m
+CONFIG_NLS_ISO8859_2=m
+CONFIG_NLS_ISO8859_3=m
+CONFIG_NLS_ISO8859_4=m
+CONFIG_NLS_ISO8859_5=m
+CONFIG_NLS_ISO8859_6=m
+CONFIG_NLS_ISO8859_7=m
+CONFIG_NLS_ISO8859_9=m
+CONFIG_NLS_ISO8859_13=m
+CONFIG_NLS_ISO8859_14=m
+CONFIG_NLS_ISO8859_15=m
+CONFIG_NLS_KOI8_R=m
+CONFIG_NLS_KOI8_U=m
+CONFIG_NLS_UTF8=m
+
+#
+# iSeries device drivers
+#
+CONFIG_VIOCONS=y
+CONFIG_VIODASD=m
+CONFIG_VIOCD=m
+CONFIG_VIOTAPE=m
+CONFIG_VIOPATH=y
+
+#
+# Library routines
+#
+CONFIG_CRC_CCITT=m
+CONFIG_CRC16=m
+CONFIG_CRC32=y
+CONFIG_LIBCRC32C=m
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=m
+CONFIG_TEXTSEARCH=y
+CONFIG_TEXTSEARCH_KMP=m
+CONFIG_TEXTSEARCH_BM=m
+CONFIG_TEXTSEARCH_FSM=m
+CONFIG_PLIST=y
+
+#
+# Instrumentation Support
+#
+CONFIG_PROFILING=y
+CONFIG_OPROFILE=m
+CONFIG_KPROBES=y
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_UNUSED_SYMBOLS is not set
+CONFIG_DEBUG_KERNEL=y
+CONFIG_LOG_BUF_SHIFT=17
+CONFIG_DETECT_SOFTLOCKUP=y
+CONFIG_SCHEDSTATS=y
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
+CONFIG_DEBUG_SPINLOCK=y
+# CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_RWSEMS is not set
+CONFIG_DEBUG_SPINLOCK_SLEEP=y
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+# CONFIG_DEBUG_KOBJECT is not set
+CONFIG_DEBUG_INFO=y
+CONFIG_DEBUG_FS=y
+# CONFIG_DEBUG_VM is not set
+CONFIG_DEBUG_LIST=y
+# CONFIG_FORCED_INLINING is not set
+CONFIG_BOOT_DELAY=y
+# CONFIG_RCU_TORTURE_TEST is not set
+CONFIG_DEBUG_STACKOVERFLOW=y
+CONFIG_DEBUG_STACK_USAGE=y
+CONFIG_DEBUGGER=y
+CONFIG_IRQSTACKS=y
+# CONFIG_PPC_EARLY_DEBUG is not set
+
+#
+# Security options
+#
+CONFIG_KEYS=y
+CONFIG_KEYS_DEBUG_PROC_KEYS=y
+CONFIG_SECURITY=y
+CONFIG_SECURITY_NETWORK=y
+# CONFIG_SECURITY_NETWORK_XFRM is not set
+CONFIG_SECURITY_CAPABILITIES=y
+# CONFIG_SECURITY_SECLVL is not set
+CONFIG_SECURITY_SELINUX=y
+CONFIG_SECURITY_SELINUX_BOOTPARAM=y
+CONFIG_SECURITY_SELINUX_BOOTPARAM_VALUE=1
+CONFIG_SECURITY_SELINUX_DISABLE=y
+CONFIG_SECURITY_SELINUX_DEVELOP=y
+CONFIG_SECURITY_SELINUX_AVC_STATS=y
+CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE=1
+# CONFIG_SECURITY_SELINUX_ENABLE_SECMARK_DEFAULT is not set
+# CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX is not set
+CONFIG_KEYS_COMPAT=y
+
+#
+# Cryptographic options
+#
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_NULL=m
+CONFIG_CRYPTO_MD4=m
+CONFIG_CRYPTO_MD5=m
+CONFIG_CRYPTO_SHA1=y
+CONFIG_CRYPTO_SHA256=m
+CONFIG_CRYPTO_SHA512=m
+CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_TGR192=m
+CONFIG_CRYPTO_DES=m
+CONFIG_CRYPTO_BLOWFISH=m
+CONFIG_CRYPTO_TWOFISH=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_TEST is not set
+CONFIG_CRYPTO_SIGNATURE=y
+CONFIG_CRYPTO_SIGNATURE_DSA=y
+CONFIG_CRYPTO_MPILIB=y
+
+#
+# Hardware crypto devices
+#
diff --git a/configs/kernel-2.6.18-s390.config b/configs/kernel-2.6.18-s390.config
new file mode 100644
index 000000000..971ecd194
--- /dev/null
+++ b/configs/kernel-2.6.18-s390.config
@@ -0,0 +1,1133 @@
+# s390
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.18.2-rc1
+# Mon Nov 13 09:44:42 2006
+#
+CONFIG_MMU=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_S390=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_BSD_PROCESS_ACCT=y
+# CONFIG_BSD_PROCESS_ACCT_V3 is not set
+CONFIG_TASKSTATS=y
+CONFIG_TASK_DELAY_ACCT=y
+CONFIG_AUDIT=y
+CONFIG_AUDITSYSCALL=y
+# CONFIG_IKCONFIG is not set
+CONFIG_CPUSETS=y
+CONFIG_RELAY=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+# CONFIG_EMBEDDED is not set
+CONFIG_UID16=y
+CONFIG_SYSCTL=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
+CONFIG_KALLSYMS_EXTRA_PASS=y
+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=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+CONFIG_MODULE_SIG=y
+# CONFIG_MODULE_SIG_FORCE is not set
+CONFIG_KMOD=y
+CONFIG_STOP_MACHINE=y
+
+#
+# Process debugging support
+#
+CONFIG_UTRACE=y
+CONFIG_PTRACE=y
+
+#
+# Block layer
+#
+CONFIG_LBD=y
+CONFIG_BLK_DEV_IO_TRACE=y
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_DEFAULT_AS is not set
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+
+#
+# Base setup
+#
+
+#
+# Processor type and features
+#
+# CONFIG_64BIT is not set
+CONFIG_32BIT=y
+CONFIG_SMP=y
+CONFIG_NR_CPUS=32
+CONFIG_HOTPLUG_CPU=y
+CONFIG_DEFAULT_MIGRATION_COST=1000000
+CONFIG_MATHEMU=y
+CONFIG_AUDIT_ARCH=y
+
+#
+# Code generation options
+#
+CONFIG_MARCH_G5=y
+# CONFIG_MARCH_Z900 is not set
+# CONFIG_MARCH_Z990 is not set
+CONFIG_PACK_STACK=y
+# CONFIG_SMALL_STACK is not set
+CONFIG_CHECK_STACK=y
+CONFIG_STACK_GUARD=256
+# CONFIG_WARN_STACK 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=y
+
+#
+# I/O subsystem configuration
+#
+CONFIG_MACHCHK_WARNING=y
+CONFIG_QDIO=m
+# CONFIG_QDIO_PERF_STATS is not set
+# CONFIG_QDIO_DEBUG is not set
+
+#
+# Misc
+#
+# CONFIG_PREEMPT is not set
+CONFIG_IPL=y
+# CONFIG_IPL_TAPE is not set
+CONFIG_IPL_VM=y
+CONFIG_BINFMT_ELF=y
+CONFIG_BINFMT_MISC=y
+# CONFIG_PROCESS_DEBUG is not set
+CONFIG_PFAULT=y
+# CONFIG_SHARED_KERNEL is not set
+CONFIG_CMM=m
+CONFIG_CMM_PROC=y
+CONFIG_CMM_IUCV=y
+CONFIG_VIRT_TIMER=y
+CONFIG_VIRT_CPU_ACCOUNTING=y
+CONFIG_APPLDATA_BASE=y
+CONFIG_APPLDATA_MEM=m
+CONFIG_APPLDATA_OS=m
+CONFIG_APPLDATA_NET_SUM=m
+CONFIG_NO_IDLE_HZ=y
+CONFIG_NO_IDLE_HZ_INIT=y
+CONFIG_S390_HYPFS_FS=y
+CONFIG_KEXEC=y
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+# CONFIG_NETDEBUG is not set
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=y
+CONFIG_NET_KEY=m
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_ASK_IP_FIB_HASH=y
+# 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
+# CONFIG_IP_PNP is not set
+CONFIG_NET_IPIP=m
+CONFIG_NET_IPGRE=m
+CONFIG_NET_IPGRE_BROADCAST=y
+CONFIG_IP_MROUTE=y
+CONFIG_IP_PIMSM_V1=y
+CONFIG_IP_PIMSM_V2=y
+# CONFIG_ARPD is not set
+CONFIG_SYN_COOKIES=y
+CONFIG_INET_AH=m
+CONFIG_INET_ESP=m
+CONFIG_INET_IPCOMP=m
+CONFIG_INET_XFRM_TUNNEL=m
+CONFIG_INET_TUNNEL=m
+CONFIG_INET_XFRM_MODE_TRANSPORT=m
+CONFIG_INET_XFRM_MODE_TUNNEL=m
+CONFIG_INET_DIAG=m
+CONFIG_INET_TCP_DIAG=m
+CONFIG_TCP_CONG_ADVANCED=y
+
+#
+# TCP congestion control
+#
+CONFIG_TCP_CONG_BIC=y
+CONFIG_TCP_CONG_CUBIC=m
+CONFIG_TCP_CONG_WESTWOOD=m
+CONFIG_TCP_CONG_HTCP=m
+CONFIG_TCP_CONG_HSTCP=m
+CONFIG_TCP_CONG_HYBLA=m
+CONFIG_TCP_CONG_VEGAS=m
+CONFIG_TCP_CONG_SCALABLE=m
+CONFIG_TCP_CONG_LP=m
+CONFIG_TCP_CONG_VENO=m
+
+#
+# IP: Virtual Server Configuration
+#
+CONFIG_IP_VS=m
+# CONFIG_IP_VS_DEBUG is not set
+CONFIG_IP_VS_TAB_BITS=12
+
+#
+# IPVS transport protocol load balancing support
+#
+CONFIG_IP_VS_PROTO_TCP=y
+CONFIG_IP_VS_PROTO_UDP=y
+CONFIG_IP_VS_PROTO_ESP=y
+CONFIG_IP_VS_PROTO_AH=y
+
+#
+# IPVS scheduler
+#
+CONFIG_IP_VS_RR=m
+CONFIG_IP_VS_WRR=m
+CONFIG_IP_VS_LC=m
+CONFIG_IP_VS_WLC=m
+CONFIG_IP_VS_LBLC=m
+CONFIG_IP_VS_LBLCR=m
+CONFIG_IP_VS_DH=m
+CONFIG_IP_VS_SH=m
+CONFIG_IP_VS_SED=m
+CONFIG_IP_VS_NQ=m
+
+#
+# IPVS application helper
+#
+CONFIG_IP_VS_FTP=m
+CONFIG_IPV6=m
+CONFIG_IPV6_PRIVACY=y
+CONFIG_IPV6_ROUTER_PREF=y
+CONFIG_IPV6_ROUTE_INFO=y
+CONFIG_INET6_AH=m
+CONFIG_INET6_ESP=m
+CONFIG_INET6_IPCOMP=m
+CONFIG_INET6_XFRM_TUNNEL=m
+CONFIG_INET6_TUNNEL=m
+CONFIG_INET6_XFRM_MODE_TRANSPORT=m
+CONFIG_INET6_XFRM_MODE_TUNNEL=m
+CONFIG_IPV6_TUNNEL=m
+CONFIG_NETWORK_SECMARK=y
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_DEBUG is not set
+CONFIG_BRIDGE_NETFILTER=y
+
+#
+# Core Netfilter Configuration
+#
+CONFIG_NETFILTER_NETLINK=m
+CONFIG_NETFILTER_NETLINK_QUEUE=m
+CONFIG_NETFILTER_NETLINK_LOG=m
+CONFIG_NETFILTER_XTABLES=m
+CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
+CONFIG_NETFILTER_XT_TARGET_CONNMARK=m
+CONFIG_NETFILTER_XT_TARGET_MARK=m
+CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
+CONFIG_NETFILTER_XT_TARGET_NOTRACK=m
+CONFIG_NETFILTER_XT_TARGET_SECMARK=m
+CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=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_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_PHYSDEV=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
+
+#
+# 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=m
+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_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_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_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
+CONFIG_IP_NF_ARPTABLES=m
+CONFIG_IP_NF_ARPFILTER=m
+CONFIG_IP_NF_ARP_MANGLE=m
+
+#
+# IPv6: Netfilter Configuration (EXPERIMENTAL)
+#
+CONFIG_IP6_NF_QUEUE=m
+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_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
+
+#
+# DECnet: Netfilter Configuration
+#
+# CONFIG_DECNET_NF_GRABULATOR is not set
+
+#
+# Bridge: Netfilter Configuration
+#
+CONFIG_BRIDGE_NF_EBTABLES=m
+CONFIG_BRIDGE_EBT_BROUTE=m
+CONFIG_BRIDGE_EBT_T_FILTER=m
+CONFIG_BRIDGE_EBT_T_NAT=m
+CONFIG_BRIDGE_EBT_802_3=m
+CONFIG_BRIDGE_EBT_AMONG=m
+CONFIG_BRIDGE_EBT_ARP=m
+CONFIG_BRIDGE_EBT_IP=m
+CONFIG_BRIDGE_EBT_LIMIT=m
+CONFIG_BRIDGE_EBT_MARK=m
+CONFIG_BRIDGE_EBT_PKTTYPE=m
+CONFIG_BRIDGE_EBT_STP=m
+CONFIG_BRIDGE_EBT_VLAN=m
+CONFIG_BRIDGE_EBT_ARPREPLY=m
+CONFIG_BRIDGE_EBT_DNAT=m
+CONFIG_BRIDGE_EBT_MARK_T=m
+CONFIG_BRIDGE_EBT_REDIRECT=m
+CONFIG_BRIDGE_EBT_SNAT=m
+CONFIG_BRIDGE_EBT_LOG=m
+CONFIG_BRIDGE_EBT_ULOG=m
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+CONFIG_IP_DCCP=m
+CONFIG_INET_DCCP_DIAG=m
+CONFIG_IP_DCCP_ACKVEC=y
+
+#
+# DCCP CCIDs Configuration (EXPERIMENTAL)
+#
+CONFIG_IP_DCCP_CCID2=m
+CONFIG_IP_DCCP_CCID3=m
+CONFIG_IP_DCCP_TFRC_LIB=m
+
+#
+# DCCP Kernel Hacking
+#
+# CONFIG_IP_DCCP_DEBUG is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+CONFIG_IP_SCTP=m
+# CONFIG_SCTP_DBG_MSG is not set
+# CONFIG_SCTP_DBG_OBJCNT is not set
+# CONFIG_SCTP_HMAC_NONE is not set
+# CONFIG_SCTP_HMAC_SHA1 is not set
+CONFIG_SCTP_HMAC_MD5=y
+
+#
+# TIPC Configuration (EXPERIMENTAL)
+#
+CONFIG_TIPC=m
+# CONFIG_TIPC_ADVANCED is not set
+# CONFIG_TIPC_DEBUG is not set
+CONFIG_ATM=m
+CONFIG_ATM_CLIP=m
+# CONFIG_ATM_CLIP_NO_ICMP is not set
+CONFIG_ATM_LANE=m
+# CONFIG_ATM_MPOA is not set
+CONFIG_ATM_BR2684=m
+# CONFIG_ATM_BR2684_IPFILTER is not set
+CONFIG_BRIDGE=m
+CONFIG_VLAN_8021Q=m
+CONFIG_DECNET=m
+CONFIG_DECNET_ROUTER=y
+CONFIG_DECNET_ROUTE_FWMARK=y
+CONFIG_LLC=y
+# CONFIG_LLC2 is not set
+CONFIG_IPX=m
+# CONFIG_IPX_INTERN is not set
+CONFIG_ATALK=m
+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_ECONET is not set
+CONFIG_WAN_ROUTER=m
+
+#
+# QoS and/or fair queueing
+#
+CONFIG_NET_SCHED=y
+# CONFIG_NET_SCH_CLK_JIFFIES is not set
+CONFIG_NET_SCH_CLK_GETTIMEOFDAY=y
+# CONFIG_NET_SCH_CLK_CPU is not set
+
+#
+# Queueing/Scheduling
+#
+CONFIG_NET_SCH_CBQ=m
+CONFIG_NET_SCH_HTB=m
+CONFIG_NET_SCH_HFSC=m
+CONFIG_NET_SCH_ATM=m
+CONFIG_NET_SCH_PRIO=m
+CONFIG_NET_SCH_RED=m
+CONFIG_NET_SCH_SFQ=m
+CONFIG_NET_SCH_TEQL=m
+CONFIG_NET_SCH_TBF=m
+CONFIG_NET_SCH_GRED=m
+CONFIG_NET_SCH_DSMARK=m
+CONFIG_NET_SCH_NETEM=m
+CONFIG_NET_SCH_INGRESS=m
+
+#
+# Classification
+#
+CONFIG_NET_CLS=y
+CONFIG_NET_CLS_BASIC=m
+CONFIG_NET_CLS_TCINDEX=m
+CONFIG_NET_CLS_ROUTE4=m
+CONFIG_NET_CLS_ROUTE=y
+CONFIG_NET_CLS_FW=m
+CONFIG_NET_CLS_U32=m
+CONFIG_CLS_U32_PERF=y
+CONFIG_CLS_U32_MARK=y
+CONFIG_NET_CLS_RSVP=m
+CONFIG_NET_CLS_RSVP6=m
+CONFIG_NET_EMATCH=y
+CONFIG_NET_EMATCH_STACK=32
+CONFIG_NET_EMATCH_CMP=m
+CONFIG_NET_EMATCH_NBYTE=m
+CONFIG_NET_EMATCH_U32=m
+CONFIG_NET_EMATCH_META=m
+CONFIG_NET_EMATCH_TEXT=m
+CONFIG_NET_CLS_ACT=y
+CONFIG_NET_ACT_POLICE=m
+CONFIG_NET_ACT_GACT=m
+CONFIG_GACT_PROB=y
+CONFIG_NET_ACT_MIRRED=m
+CONFIG_NET_ACT_IPT=m
+CONFIG_NET_ACT_PEDIT=m
+CONFIG_NET_ACT_SIMP=m
+CONFIG_NET_CLS_IND=y
+CONFIG_NET_ESTIMATOR=y
+
+#
+# Network testing
+#
+CONFIG_NET_PKTGEN=m
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_IEEE80211 is not set
+CONFIG_TUX=m
+
+#
+# TUX options
+#
+CONFIG_TUX_EXTCGI=y
+CONFIG_TUX_EXTENDED_LOG=y
+# CONFIG_TUX_DEBUG is not set
+# CONFIG_PCMCIA is not set
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+# CONFIG_DEBUG_DRIVER is not set
+CONFIG_SYS_HYPERVISOR=y
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+CONFIG_CONNECTOR=y
+CONFIG_PROC_EVENTS=y
+
+#
+# SCSI device support
+#
+CONFIG_RAID_ATTRS=m
+CONFIG_SCSI=m
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=m
+CONFIG_CHR_DEV_ST=m
+CONFIG_CHR_DEV_OSST=m
+CONFIG_BLK_DEV_SR=m
+CONFIG_BLK_DEV_SR_VENDOR=y
+CONFIG_CHR_DEV_SG=m
+CONFIG_CHR_DEV_SCH=m
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+CONFIG_SCSI_MULTI_LUN=y
+CONFIG_SCSI_CONSTANTS=y
+CONFIG_SCSI_LOGGING=y
+
+#
+# SCSI Transport Attributes
+#
+CONFIG_SCSI_SPI_ATTRS=m
+CONFIG_SCSI_FC_ATTRS=m
+CONFIG_SCSI_ISCSI_ATTRS=m
+CONFIG_SCSI_SAS_ATTRS=m
+
+#
+# SCSI low-level drivers
+#
+CONFIG_ISCSI_TCP=m
+# CONFIG_SCSI_SATA is not set
+# CONFIG_SCSI_DEBUG is not set
+CONFIG_ZFCP=m
+CONFIG_CCW=y
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=m
+CONFIG_BLK_DEV_CRYPTOLOOP=m
+CONFIG_BLK_DEV_NBD=m
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=16384
+CONFIG_BLK_DEV_RAM_BLOCKSIZE=4096
+CONFIG_BLK_DEV_INITRD=y
+# CONFIG_CDROM_PKTCDVD is not set
+
+#
+# S/390 block device drivers
+#
+CONFIG_BLK_DEV_XPRAM=m
+CONFIG_DCSSBLK=m
+CONFIG_DASD=m
+CONFIG_DASD_PROFILE=y
+CONFIG_DASD_ECKD=m
+CONFIG_DASD_FBA=m
+CONFIG_DASD_DIAG=m
+CONFIG_DASD_EER=y
+# CONFIG_ATA_OVER_ETH is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+CONFIG_MD=y
+CONFIG_BLK_DEV_MD=y
+CONFIG_MD_LINEAR=m
+CONFIG_MD_RAID0=m
+CONFIG_MD_RAID1=m
+CONFIG_MD_RAID10=m
+CONFIG_MD_RAID456=m
+CONFIG_MD_RAID5_RESHAPE=y
+CONFIG_MD_MULTIPATH=m
+CONFIG_MD_FAULTY=m
+CONFIG_BLK_DEV_DM=m
+CONFIG_DM_CRYPT=m
+CONFIG_DM_SNAPSHOT=m
+CONFIG_DM_MIRROR=m
+CONFIG_DM_ZERO=m
+CONFIG_DM_MULTIPATH=m
+CONFIG_DM_MULTIPATH_EMC=m
+
+#
+# Character device drivers
+#
+CONFIG_UNIX98_PTYS=y
+CONFIG_UNIX98_PTY_COUNT=2048
+CONFIG_HANGCHECK_TIMER=m
+
+#
+# Watchdog Cards
+#
+CONFIG_WATCHDOG=y
+# CONFIG_WATCHDOG_NOWAYOUT is not set
+
+#
+# Watchdog Device Drivers
+#
+CONFIG_SOFT_WATCHDOG=m
+CONFIG_ZVM_WATCHDOG=m
+
+#
+# S/390 character device drivers
+#
+CONFIG_TN3270=y
+CONFIG_TN3270_TTY=y
+CONFIG_TN3270_FS=m
+CONFIG_TN3270_CONSOLE=y
+CONFIG_TN3215=y
+CONFIG_TN3215_CONSOLE=y
+CONFIG_CCW_CONSOLE=y
+CONFIG_SCLP=y
+CONFIG_SCLP_TTY=y
+CONFIG_SCLP_CONSOLE=y
+CONFIG_SCLP_VT220_TTY=y
+CONFIG_SCLP_VT220_CONSOLE=y
+CONFIG_SCLP_CPI=m
+CONFIG_S390_TAPE=m
+
+#
+# S/390 tape interface support
+#
+CONFIG_S390_TAPE_BLOCK=y
+
+#
+# S/390 tape hardware support
+#
+CONFIG_S390_TAPE_34XX=m
+CONFIG_S390_TAPE_3590=m
+CONFIG_VMLOGRDR=m
+CONFIG_VMCP=m
+CONFIG_MONREADER=m
+
+#
+# Cryptographic devices
+#
+CONFIG_Z90CRYPT=m
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+CONFIG_IFB=m
+CONFIG_DUMMY=m
+CONFIG_BONDING=m
+CONFIG_EQUALIZER=m
+CONFIG_TUN=m
+
+#
+# PHY device support
+#
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+# CONFIG_MII is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+
+#
+# Ethernet (10000 Mbit)
+#
+
+#
+# Token Ring devices
+#
+CONFIG_TR=y
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+
+#
+# ATM drivers
+#
+# CONFIG_ATM_DUMMY is not set
+CONFIG_ATM_TCP=m
+
+#
+# S/390 network device drivers
+#
+CONFIG_LCS=m
+CONFIG_CTC=m
+CONFIG_IUCV=m
+CONFIG_NETIUCV=m
+CONFIG_SMSGIUCV=m
+# CONFIG_CLAW is not set
+CONFIG_QETH=m
+
+#
+# Gigabit Ethernet default settings
+#
+CONFIG_QETH_IPV6=y
+CONFIG_QETH_VLAN=y
+CONFIG_CCWGROUP=m
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_SHAPER is not set
+CONFIG_NETCONSOLE=m
+CONFIG_NETPOLL=y
+# CONFIG_NETPOLL_RX is not set
+CONFIG_NETPOLL_TRAP=y
+CONFIG_NET_POLL_CONTROLLER=y
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+CONFIG_EXT2_FS_POSIX_ACL=y
+CONFIG_EXT2_FS_SECURITY=y
+CONFIG_EXT2_FS_XIP=y
+CONFIG_FS_XIP=y
+CONFIG_EXT3_FS=m
+CONFIG_EXT3_FS_XATTR=y
+CONFIG_EXT3_FS_POSIX_ACL=y
+CONFIG_EXT3_FS_SECURITY=y
+CONFIG_JBD=m
+# CONFIG_JBD_DEBUG is not set
+CONFIG_FS_MBCACHE=y
+CONFIG_REISERFS_FS=m
+# CONFIG_REISERFS_CHECK is not set
+CONFIG_REISERFS_PROC_INFO=y
+CONFIG_REISERFS_FS_XATTR=y
+CONFIG_REISERFS_FS_POSIX_ACL=y
+CONFIG_REISERFS_FS_SECURITY=y
+CONFIG_JFS_FS=m
+CONFIG_JFS_POSIX_ACL=y
+CONFIG_JFS_SECURITY=y
+# CONFIG_JFS_DEBUG is not set
+# CONFIG_JFS_STATISTICS is not set
+CONFIG_FS_POSIX_ACL=y
+CONFIG_XFS_FS=m
+CONFIG_XFS_QUOTA=y
+CONFIG_XFS_SECURITY=y
+CONFIG_XFS_POSIX_ACL=y
+# CONFIG_XFS_RT is not set
+CONFIG_OCFS2_FS=m
+# CONFIG_OCFS2_DEBUG_MASKLOG is not set
+CONFIG_MINIX_FS=m
+CONFIG_ROMFS_FS=m
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+CONFIG_QUOTA=y
+# CONFIG_QFMT_V1 is not set
+CONFIG_QFMT_V2=y
+CONFIG_QUOTACTL=y
+CONFIG_DNOTIFY=y
+CONFIG_AUTOFS_FS=m
+CONFIG_AUTOFS4_FS=m
+CONFIG_FUSE_FS=m
+
+#
+# Caches
+#
+CONFIG_FSCACHE=m
+
+#
+# CD-ROM/DVD Filesystems
+#
+CONFIG_ISO9660_FS=y
+CONFIG_JOLIET=y
+CONFIG_ZISOFS=y
+CONFIG_ZISOFS_FS=y
+CONFIG_UDF_FS=m
+CONFIG_UDF_NLS=y
+CONFIG_CACHEFILES=m
+CONFIG_CACHEFILES_DEBUG=y
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=m
+CONFIG_MSDOS_FS=m
+CONFIG_VFAT_FS=m
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="ascii"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_RAMFS=y
+CONFIG_CONFIGFS_FS=m
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+CONFIG_AFFS_FS=m
+CONFIG_HFS_FS=m
+CONFIG_HFSPLUS_FS=m
+CONFIG_BEFS_FS=m
+# CONFIG_BEFS_DEBUG is not set
+CONFIG_BFS_FS=m
+CONFIG_EFS_FS=m
+CONFIG_CRAMFS=m
+CONFIG_SQUASHFS=m
+# CONFIG_SQUASHFS_EMBEDDED is not set
+CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3
+# CONFIG_SQUASHFS_VMALLOC is not set
+CONFIG_VXFS_FS=m
+# CONFIG_HPFS_FS is not set
+CONFIG_QNX4FS_FS=m
+CONFIG_SYSV_FS=m
+CONFIG_UFS_FS=m
+# CONFIG_UFS_FS_WRITE is not set
+# CONFIG_UFS_DEBUG is not set
+
+#
+# Network File Systems
+#
+CONFIG_NFS_FS=m
+CONFIG_NFS_V3=y
+CONFIG_NFS_V3_ACL=y
+CONFIG_NFS_V4=y
+CONFIG_NFS_FSCACHE=y
+CONFIG_NFS_DIRECTIO=y
+CONFIG_NFSD=m
+CONFIG_NFSD_V2_ACL=y
+CONFIG_NFSD_V3=y
+CONFIG_NFSD_V3_ACL=y
+CONFIG_NFSD_V4=y
+CONFIG_NFSD_TCP=y
+CONFIG_LOCKD=m
+CONFIG_LOCKD_V4=y
+CONFIG_EXPORTFS=m
+CONFIG_NFS_ACL_SUPPORT=m
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=m
+CONFIG_SUNRPC_GSS=m
+CONFIG_RPCSEC_GSS_KRB5=m
+CONFIG_RPCSEC_GSS_SPKM3=m
+# CONFIG_SMB_FS is not set
+CONFIG_CIFS=m
+# CONFIG_CIFS_STATS is not set
+CONFIG_CIFS_WEAK_PW_HASH=y
+CONFIG_CIFS_XATTR=y
+CONFIG_CIFS_POSIX=y
+# CONFIG_CIFS_DEBUG2 is not set
+# CONFIG_CIFS_EXPERIMENTAL is not set
+CONFIG_NCP_FS=m
+CONFIG_NCPFS_PACKET_SIGNING=y
+CONFIG_NCPFS_IOCTL_LOCKING=y
+CONFIG_NCPFS_STRONG=y
+CONFIG_NCPFS_NFS_NS=y
+CONFIG_NCPFS_OS2_NS=y
+CONFIG_NCPFS_SMALLDOS=y
+CONFIG_NCPFS_NLS=y
+CONFIG_NCPFS_EXTRAS=y
+CONFIG_CODA_FS=m
+# CONFIG_CODA_FS_OLD_API is not set
+# CONFIG_AFS_FS is not set
+CONFIG_9P_FS=m
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+CONFIG_AMIGA_PARTITION=y
+# CONFIG_ATARI_PARTITION is not set
+CONFIG_IBM_PARTITION=y
+# CONFIG_MAC_PARTITION is not set
+CONFIG_MSDOS_PARTITION=y
+CONFIG_BSD_DISKLABEL=y
+CONFIG_MINIX_SUBPARTITION=y
+CONFIG_SOLARIS_X86_PARTITION=y
+CONFIG_UNIXWARE_DISKLABEL=y
+# CONFIG_LDM_PARTITION is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+CONFIG_KARMA_PARTITION=y
+CONFIG_EFI_PARTITION=y
+
+#
+# Native Language Support
+#
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="utf8"
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_CODEPAGE_737=m
+CONFIG_NLS_CODEPAGE_775=m
+CONFIG_NLS_CODEPAGE_850=m
+CONFIG_NLS_CODEPAGE_852=m
+CONFIG_NLS_CODEPAGE_855=m
+CONFIG_NLS_CODEPAGE_857=m
+CONFIG_NLS_CODEPAGE_860=m
+CONFIG_NLS_CODEPAGE_861=m
+CONFIG_NLS_CODEPAGE_862=m
+CONFIG_NLS_CODEPAGE_863=m
+CONFIG_NLS_CODEPAGE_864=m
+CONFIG_NLS_CODEPAGE_865=m
+CONFIG_NLS_CODEPAGE_866=m
+CONFIG_NLS_CODEPAGE_869=m
+CONFIG_NLS_CODEPAGE_936=m
+CONFIG_NLS_CODEPAGE_950=m
+CONFIG_NLS_CODEPAGE_932=m
+CONFIG_NLS_CODEPAGE_949=m
+CONFIG_NLS_CODEPAGE_874=m
+CONFIG_NLS_ISO8859_8=m
+CONFIG_NLS_CODEPAGE_1250=m
+CONFIG_NLS_CODEPAGE_1251=m
+CONFIG_NLS_ASCII=y
+CONFIG_NLS_ISO8859_1=m
+CONFIG_NLS_ISO8859_2=m
+CONFIG_NLS_ISO8859_3=m
+CONFIG_NLS_ISO8859_4=m
+CONFIG_NLS_ISO8859_5=m
+CONFIG_NLS_ISO8859_6=m
+CONFIG_NLS_ISO8859_7=m
+CONFIG_NLS_ISO8859_9=m
+CONFIG_NLS_ISO8859_13=m
+CONFIG_NLS_ISO8859_14=m
+CONFIG_NLS_ISO8859_15=m
+CONFIG_NLS_KOI8_R=m
+CONFIG_NLS_KOI8_U=m
+CONFIG_NLS_UTF8=m
+
+#
+# Profiling support
+#
+CONFIG_PROFILING=y
+CONFIG_OPROFILE=m
+
+#
+# Kernel hacking
+#
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+# CONFIG_PRINTK_TIME is not set
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_UNUSED_SYMBOLS is not set
+CONFIG_DEBUG_KERNEL=y
+CONFIG_LOG_BUF_SHIFT=16
+# CONFIG_DETECT_SOFTLOCKUP is not set
+CONFIG_SCHEDSTATS=y
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
+CONFIG_DEBUG_SPINLOCK=y
+# 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=y
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+# CONFIG_DEBUG_KOBJECT is not set
+CONFIG_DEBUG_INFO=y
+CONFIG_DEBUG_FS=y
+# CONFIG_DEBUG_VM is not set
+CONFIG_DEBUG_LIST=y
+# CONFIG_FRAME_POINTER is not set
+CONFIG_UNWIND_INFO=y
+# CONFIG_FORCED_INLINING is not set
+# CONFIG_BOOT_DELAY is not set
+# CONFIG_RCU_TORTURE_TEST is not set
+
+#
+# Security options
+#
+CONFIG_KEYS=y
+CONFIG_KEYS_DEBUG_PROC_KEYS=y
+CONFIG_SECURITY=y
+CONFIG_SECURITY_NETWORK=y
+# CONFIG_SECURITY_NETWORK_XFRM is not set
+CONFIG_SECURITY_CAPABILITIES=y
+# CONFIG_SECURITY_SECLVL is not set
+CONFIG_SECURITY_SELINUX=y
+CONFIG_SECURITY_SELINUX_BOOTPARAM=y
+CONFIG_SECURITY_SELINUX_BOOTPARAM_VALUE=1
+CONFIG_SECURITY_SELINUX_DISABLE=y
+CONFIG_SECURITY_SELINUX_DEVELOP=y
+CONFIG_SECURITY_SELINUX_AVC_STATS=y
+CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE=1
+# CONFIG_SECURITY_SELINUX_ENABLE_SECMARK_DEFAULT is not set
+# CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX is not set
+
+#
+# Cryptographic options
+#
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_NULL=m
+CONFIG_CRYPTO_MD4=m
+CONFIG_CRYPTO_MD5=m
+CONFIG_CRYPTO_SHA1=y
+CONFIG_CRYPTO_SHA1_S390=m
+CONFIG_CRYPTO_SHA256=m
+CONFIG_CRYPTO_SHA256_S390=m
+CONFIG_CRYPTO_SHA512=m
+CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_TGR192=m
+CONFIG_CRYPTO_DES=m
+CONFIG_CRYPTO_DES_S390=m
+CONFIG_CRYPTO_BLOWFISH=m
+CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_SERPENT=m
+CONFIG_CRYPTO_AES=m
+CONFIG_CRYPTO_AES_S390=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_TEST is not set
+CONFIG_CRYPTO_SIGNATURE=y
+CONFIG_CRYPTO_SIGNATURE_DSA=y
+CONFIG_CRYPTO_MPILIB=y
+
+#
+# Hardware crypto devices
+#
+
+#
+# Library routines
+#
+CONFIG_CRC_CCITT=m
+CONFIG_CRC16=m
+CONFIG_CRC32=y
+CONFIG_LIBCRC32C=m
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=m
+CONFIG_TEXTSEARCH=y
+CONFIG_TEXTSEARCH_KMP=m
+CONFIG_TEXTSEARCH_BM=m
+CONFIG_TEXTSEARCH_FSM=m
+CONFIG_PLIST=y
diff --git a/configs/kernel-2.6.18-s390x.config b/configs/kernel-2.6.18-s390x.config
new file mode 100644
index 000000000..6340b1bce
--- /dev/null
+++ b/configs/kernel-2.6.18-s390x.config
@@ -0,0 +1,1131 @@
+# s390
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.18.2-rc1
+# Mon Nov 13 09:44:42 2006
+#
+CONFIG_MMU=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_S390=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_BSD_PROCESS_ACCT=y
+# CONFIG_BSD_PROCESS_ACCT_V3 is not set
+CONFIG_TASKSTATS=y
+CONFIG_TASK_DELAY_ACCT=y
+CONFIG_AUDIT=y
+CONFIG_AUDITSYSCALL=y
+# CONFIG_IKCONFIG is not set
+CONFIG_CPUSETS=y
+CONFIG_RELAY=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+# CONFIG_EMBEDDED is not set
+CONFIG_SYSCTL=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
+CONFIG_KALLSYMS_EXTRA_PASS=y
+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=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+CONFIG_MODULE_SIG=y
+# CONFIG_MODULE_SIG_FORCE is not set
+CONFIG_KMOD=y
+CONFIG_STOP_MACHINE=y
+
+#
+# Process debugging support
+#
+CONFIG_UTRACE=y
+CONFIG_PTRACE=y
+
+#
+# Block layer
+#
+CONFIG_BLK_DEV_IO_TRACE=y
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_DEFAULT_AS is not set
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+
+#
+# Base setup
+#
+
+#
+# Processor type and features
+#
+CONFIG_64BIT=y
+CONFIG_SMP=y
+CONFIG_NR_CPUS=64
+CONFIG_HOTPLUG_CPU=y
+CONFIG_DEFAULT_MIGRATION_COST=1000000
+CONFIG_COMPAT=y
+CONFIG_SYSVIPC_COMPAT=y
+CONFIG_AUDIT_ARCH=y
+
+#
+# Code generation options
+#
+# CONFIG_MARCH_G5 is not set
+CONFIG_MARCH_Z900=y
+# CONFIG_MARCH_Z990 is not set
+CONFIG_PACK_STACK=y
+# CONFIG_SMALL_STACK is not set
+CONFIG_CHECK_STACK=y
+CONFIG_STACK_GUARD=256
+# CONFIG_WARN_STACK 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=4
+CONFIG_RESOURCES_64BIT=y
+
+#
+# I/O subsystem configuration
+#
+CONFIG_MACHCHK_WARNING=y
+CONFIG_QDIO=m
+# CONFIG_QDIO_PERF_STATS is not set
+# CONFIG_QDIO_DEBUG is not set
+
+#
+# Misc
+#
+# CONFIG_PREEMPT is not set
+CONFIG_IPL=y
+# CONFIG_IPL_TAPE is not set
+CONFIG_IPL_VM=y
+CONFIG_BINFMT_ELF=y
+CONFIG_BINFMT_MISC=y
+# CONFIG_PROCESS_DEBUG is not set
+CONFIG_PFAULT=y
+# CONFIG_SHARED_KERNEL is not set
+CONFIG_CMM=m
+CONFIG_CMM_PROC=y
+CONFIG_CMM_IUCV=y
+CONFIG_VIRT_TIMER=y
+CONFIG_VIRT_CPU_ACCOUNTING=y
+CONFIG_APPLDATA_BASE=y
+CONFIG_APPLDATA_MEM=m
+CONFIG_APPLDATA_OS=m
+CONFIG_APPLDATA_NET_SUM=m
+CONFIG_NO_IDLE_HZ=y
+CONFIG_NO_IDLE_HZ_INIT=y
+CONFIG_S390_HYPFS_FS=y
+CONFIG_KEXEC=y
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+# CONFIG_NETDEBUG is not set
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=y
+CONFIG_NET_KEY=m
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_ASK_IP_FIB_HASH=y
+# 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
+# CONFIG_IP_PNP is not set
+CONFIG_NET_IPIP=m
+CONFIG_NET_IPGRE=m
+CONFIG_NET_IPGRE_BROADCAST=y
+CONFIG_IP_MROUTE=y
+CONFIG_IP_PIMSM_V1=y
+CONFIG_IP_PIMSM_V2=y
+# CONFIG_ARPD is not set
+CONFIG_SYN_COOKIES=y
+CONFIG_INET_AH=m
+CONFIG_INET_ESP=m
+CONFIG_INET_IPCOMP=m
+CONFIG_INET_XFRM_TUNNEL=m
+CONFIG_INET_TUNNEL=m
+CONFIG_INET_XFRM_MODE_TRANSPORT=m
+CONFIG_INET_XFRM_MODE_TUNNEL=m
+CONFIG_INET_DIAG=m
+CONFIG_INET_TCP_DIAG=m
+CONFIG_TCP_CONG_ADVANCED=y
+
+#
+# TCP congestion control
+#
+CONFIG_TCP_CONG_BIC=y
+CONFIG_TCP_CONG_CUBIC=m
+CONFIG_TCP_CONG_WESTWOOD=m
+CONFIG_TCP_CONG_HTCP=m
+CONFIG_TCP_CONG_HSTCP=m
+CONFIG_TCP_CONG_HYBLA=m
+CONFIG_TCP_CONG_VEGAS=m
+CONFIG_TCP_CONG_SCALABLE=m
+CONFIG_TCP_CONG_LP=m
+CONFIG_TCP_CONG_VENO=m
+
+#
+# IP: Virtual Server Configuration
+#
+CONFIG_IP_VS=m
+# CONFIG_IP_VS_DEBUG is not set
+CONFIG_IP_VS_TAB_BITS=12
+
+#
+# IPVS transport protocol load balancing support
+#
+CONFIG_IP_VS_PROTO_TCP=y
+CONFIG_IP_VS_PROTO_UDP=y
+CONFIG_IP_VS_PROTO_ESP=y
+CONFIG_IP_VS_PROTO_AH=y
+
+#
+# IPVS scheduler
+#
+CONFIG_IP_VS_RR=m
+CONFIG_IP_VS_WRR=m
+CONFIG_IP_VS_LC=m
+CONFIG_IP_VS_WLC=m
+CONFIG_IP_VS_LBLC=m
+CONFIG_IP_VS_LBLCR=m
+CONFIG_IP_VS_DH=m
+CONFIG_IP_VS_SH=m
+CONFIG_IP_VS_SED=m
+CONFIG_IP_VS_NQ=m
+
+#
+# IPVS application helper
+#
+CONFIG_IP_VS_FTP=m
+CONFIG_IPV6=m
+CONFIG_IPV6_PRIVACY=y
+CONFIG_IPV6_ROUTER_PREF=y
+CONFIG_IPV6_ROUTE_INFO=y
+CONFIG_INET6_AH=m
+CONFIG_INET6_ESP=m
+CONFIG_INET6_IPCOMP=m
+CONFIG_INET6_XFRM_TUNNEL=m
+CONFIG_INET6_TUNNEL=m
+CONFIG_INET6_XFRM_MODE_TRANSPORT=m
+CONFIG_INET6_XFRM_MODE_TUNNEL=m
+CONFIG_IPV6_TUNNEL=m
+CONFIG_NETWORK_SECMARK=y
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_DEBUG is not set
+CONFIG_BRIDGE_NETFILTER=y
+
+#
+# Core Netfilter Configuration
+#
+CONFIG_NETFILTER_NETLINK=m
+CONFIG_NETFILTER_NETLINK_QUEUE=m
+CONFIG_NETFILTER_NETLINK_LOG=m
+CONFIG_NETFILTER_XTABLES=m
+CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
+CONFIG_NETFILTER_XT_TARGET_CONNMARK=m
+CONFIG_NETFILTER_XT_TARGET_MARK=m
+CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
+CONFIG_NETFILTER_XT_TARGET_NOTRACK=m
+CONFIG_NETFILTER_XT_TARGET_SECMARK=m
+CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=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_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_PHYSDEV=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
+
+#
+# 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=m
+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_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_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_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
+CONFIG_IP_NF_ARPTABLES=m
+CONFIG_IP_NF_ARPFILTER=m
+CONFIG_IP_NF_ARP_MANGLE=m
+
+#
+# IPv6: Netfilter Configuration (EXPERIMENTAL)
+#
+CONFIG_IP6_NF_QUEUE=m
+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_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
+
+#
+# DECnet: Netfilter Configuration
+#
+# CONFIG_DECNET_NF_GRABULATOR is not set
+
+#
+# Bridge: Netfilter Configuration
+#
+CONFIG_BRIDGE_NF_EBTABLES=m
+CONFIG_BRIDGE_EBT_BROUTE=m
+CONFIG_BRIDGE_EBT_T_FILTER=m
+CONFIG_BRIDGE_EBT_T_NAT=m
+CONFIG_BRIDGE_EBT_802_3=m
+CONFIG_BRIDGE_EBT_AMONG=m
+CONFIG_BRIDGE_EBT_ARP=m
+CONFIG_BRIDGE_EBT_IP=m
+CONFIG_BRIDGE_EBT_LIMIT=m
+CONFIG_BRIDGE_EBT_MARK=m
+CONFIG_BRIDGE_EBT_PKTTYPE=m
+CONFIG_BRIDGE_EBT_STP=m
+CONFIG_BRIDGE_EBT_VLAN=m
+CONFIG_BRIDGE_EBT_ARPREPLY=m
+CONFIG_BRIDGE_EBT_DNAT=m
+CONFIG_BRIDGE_EBT_MARK_T=m
+CONFIG_BRIDGE_EBT_REDIRECT=m
+CONFIG_BRIDGE_EBT_SNAT=m
+CONFIG_BRIDGE_EBT_LOG=m
+CONFIG_BRIDGE_EBT_ULOG=m
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+CONFIG_IP_DCCP=m
+CONFIG_INET_DCCP_DIAG=m
+CONFIG_IP_DCCP_ACKVEC=y
+
+#
+# DCCP CCIDs Configuration (EXPERIMENTAL)
+#
+CONFIG_IP_DCCP_CCID2=m
+CONFIG_IP_DCCP_CCID3=m
+CONFIG_IP_DCCP_TFRC_LIB=m
+
+#
+# DCCP Kernel Hacking
+#
+# CONFIG_IP_DCCP_DEBUG is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+CONFIG_IP_SCTP=m
+# CONFIG_SCTP_DBG_MSG is not set
+# CONFIG_SCTP_DBG_OBJCNT is not set
+# CONFIG_SCTP_HMAC_NONE is not set
+# CONFIG_SCTP_HMAC_SHA1 is not set
+CONFIG_SCTP_HMAC_MD5=y
+
+#
+# TIPC Configuration (EXPERIMENTAL)
+#
+CONFIG_TIPC=m
+# CONFIG_TIPC_ADVANCED is not set
+# CONFIG_TIPC_DEBUG is not set
+CONFIG_ATM=m
+CONFIG_ATM_CLIP=m
+# CONFIG_ATM_CLIP_NO_ICMP is not set
+CONFIG_ATM_LANE=m
+# CONFIG_ATM_MPOA is not set
+CONFIG_ATM_BR2684=m
+# CONFIG_ATM_BR2684_IPFILTER is not set
+CONFIG_BRIDGE=m
+CONFIG_VLAN_8021Q=m
+CONFIG_DECNET=m
+CONFIG_DECNET_ROUTER=y
+CONFIG_DECNET_ROUTE_FWMARK=y
+CONFIG_LLC=y
+# CONFIG_LLC2 is not set
+CONFIG_IPX=m
+# CONFIG_IPX_INTERN is not set
+CONFIG_ATALK=m
+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_ECONET is not set
+CONFIG_WAN_ROUTER=m
+
+#
+# QoS and/or fair queueing
+#
+CONFIG_NET_SCHED=y
+# CONFIG_NET_SCH_CLK_JIFFIES is not set
+CONFIG_NET_SCH_CLK_GETTIMEOFDAY=y
+# CONFIG_NET_SCH_CLK_CPU is not set
+
+#
+# Queueing/Scheduling
+#
+CONFIG_NET_SCH_CBQ=m
+CONFIG_NET_SCH_HTB=m
+CONFIG_NET_SCH_HFSC=m
+CONFIG_NET_SCH_ATM=m
+CONFIG_NET_SCH_PRIO=m
+CONFIG_NET_SCH_RED=m
+CONFIG_NET_SCH_SFQ=m
+CONFIG_NET_SCH_TEQL=m
+CONFIG_NET_SCH_TBF=m
+CONFIG_NET_SCH_GRED=m
+CONFIG_NET_SCH_DSMARK=m
+CONFIG_NET_SCH_NETEM=m
+CONFIG_NET_SCH_INGRESS=m
+
+#
+# Classification
+#
+CONFIG_NET_CLS=y
+CONFIG_NET_CLS_BASIC=m
+CONFIG_NET_CLS_TCINDEX=m
+CONFIG_NET_CLS_ROUTE4=m
+CONFIG_NET_CLS_ROUTE=y
+CONFIG_NET_CLS_FW=m
+CONFIG_NET_CLS_U32=m
+CONFIG_CLS_U32_PERF=y
+CONFIG_CLS_U32_MARK=y
+CONFIG_NET_CLS_RSVP=m
+CONFIG_NET_CLS_RSVP6=m
+CONFIG_NET_EMATCH=y
+CONFIG_NET_EMATCH_STACK=32
+CONFIG_NET_EMATCH_CMP=m
+CONFIG_NET_EMATCH_NBYTE=m
+CONFIG_NET_EMATCH_U32=m
+CONFIG_NET_EMATCH_META=m
+CONFIG_NET_EMATCH_TEXT=m
+CONFIG_NET_CLS_ACT=y
+CONFIG_NET_ACT_POLICE=m
+CONFIG_NET_ACT_GACT=m
+CONFIG_GACT_PROB=y
+CONFIG_NET_ACT_MIRRED=m
+CONFIG_NET_ACT_IPT=m
+CONFIG_NET_ACT_PEDIT=m
+CONFIG_NET_ACT_SIMP=m
+CONFIG_NET_CLS_IND=y
+CONFIG_NET_ESTIMATOR=y
+
+#
+# Network testing
+#
+CONFIG_NET_PKTGEN=m
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_IEEE80211 is not set
+CONFIG_TUX=m
+
+#
+# TUX options
+#
+CONFIG_TUX_EXTCGI=y
+CONFIG_TUX_EXTENDED_LOG=y
+# CONFIG_TUX_DEBUG is not set
+# CONFIG_PCMCIA is not set
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+# CONFIG_DEBUG_DRIVER is not set
+CONFIG_SYS_HYPERVISOR=y
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+CONFIG_CONNECTOR=y
+CONFIG_PROC_EVENTS=y
+
+#
+# SCSI device support
+#
+CONFIG_RAID_ATTRS=m
+CONFIG_SCSI=m
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=m
+CONFIG_CHR_DEV_ST=m
+CONFIG_CHR_DEV_OSST=m
+CONFIG_BLK_DEV_SR=m
+CONFIG_BLK_DEV_SR_VENDOR=y
+CONFIG_CHR_DEV_SG=m
+CONFIG_CHR_DEV_SCH=m
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+CONFIG_SCSI_MULTI_LUN=y
+CONFIG_SCSI_CONSTANTS=y
+CONFIG_SCSI_LOGGING=y
+
+#
+# SCSI Transport Attributes
+#
+CONFIG_SCSI_SPI_ATTRS=m
+CONFIG_SCSI_FC_ATTRS=m
+CONFIG_SCSI_ISCSI_ATTRS=m
+CONFIG_SCSI_SAS_ATTRS=m
+
+#
+# SCSI low-level drivers
+#
+CONFIG_ISCSI_TCP=m
+# CONFIG_SCSI_SATA is not set
+# CONFIG_SCSI_DEBUG is not set
+CONFIG_ZFCP=m
+CONFIG_CCW=y
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=m
+CONFIG_BLK_DEV_CRYPTOLOOP=m
+CONFIG_BLK_DEV_NBD=m
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=16384
+CONFIG_BLK_DEV_RAM_BLOCKSIZE=4096
+CONFIG_BLK_DEV_INITRD=y
+# CONFIG_CDROM_PKTCDVD is not set
+
+#
+# S/390 block device drivers
+#
+CONFIG_BLK_DEV_XPRAM=m
+CONFIG_DCSSBLK=m
+CONFIG_DASD=m
+CONFIG_DASD_PROFILE=y
+CONFIG_DASD_ECKD=m
+CONFIG_DASD_FBA=m
+CONFIG_DASD_DIAG=m
+CONFIG_DASD_EER=y
+# CONFIG_ATA_OVER_ETH is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+CONFIG_MD=y
+CONFIG_BLK_DEV_MD=y
+CONFIG_MD_LINEAR=m
+CONFIG_MD_RAID0=m
+CONFIG_MD_RAID1=m
+CONFIG_MD_RAID10=m
+CONFIG_MD_RAID456=m
+CONFIG_MD_RAID5_RESHAPE=y
+CONFIG_MD_MULTIPATH=m
+CONFIG_MD_FAULTY=m
+CONFIG_BLK_DEV_DM=m
+CONFIG_DM_CRYPT=m
+CONFIG_DM_SNAPSHOT=m
+CONFIG_DM_MIRROR=m
+CONFIG_DM_ZERO=m
+CONFIG_DM_MULTIPATH=m
+CONFIG_DM_MULTIPATH_EMC=m
+
+#
+# Character device drivers
+#
+CONFIG_UNIX98_PTYS=y
+CONFIG_UNIX98_PTY_COUNT=2048
+CONFIG_HANGCHECK_TIMER=m
+
+#
+# Watchdog Cards
+#
+CONFIG_WATCHDOG=y
+# CONFIG_WATCHDOG_NOWAYOUT is not set
+
+#
+# Watchdog Device Drivers
+#
+CONFIG_SOFT_WATCHDOG=m
+CONFIG_ZVM_WATCHDOG=m
+
+#
+# S/390 character device drivers
+#
+CONFIG_TN3270=y
+CONFIG_TN3270_TTY=y
+CONFIG_TN3270_FS=m
+CONFIG_TN3270_CONSOLE=y
+CONFIG_TN3215=y
+CONFIG_TN3215_CONSOLE=y
+CONFIG_CCW_CONSOLE=y
+CONFIG_SCLP=y
+CONFIG_SCLP_TTY=y
+CONFIG_SCLP_CONSOLE=y
+CONFIG_SCLP_VT220_TTY=y
+CONFIG_SCLP_VT220_CONSOLE=y
+CONFIG_SCLP_CPI=m
+CONFIG_S390_TAPE=m
+
+#
+# S/390 tape interface support
+#
+CONFIG_S390_TAPE_BLOCK=y
+
+#
+# S/390 tape hardware support
+#
+CONFIG_S390_TAPE_34XX=m
+CONFIG_S390_TAPE_3590=m
+CONFIG_VMLOGRDR=m
+CONFIG_VMCP=m
+CONFIG_MONREADER=m
+
+#
+# Cryptographic devices
+#
+CONFIG_Z90CRYPT=m
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+CONFIG_IFB=m
+CONFIG_DUMMY=m
+CONFIG_BONDING=m
+CONFIG_EQUALIZER=m
+CONFIG_TUN=m
+
+#
+# PHY device support
+#
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+# CONFIG_MII is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+
+#
+# Ethernet (10000 Mbit)
+#
+
+#
+# Token Ring devices
+#
+CONFIG_TR=y
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+
+#
+# ATM drivers
+#
+# CONFIG_ATM_DUMMY is not set
+CONFIG_ATM_TCP=m
+
+#
+# S/390 network device drivers
+#
+CONFIG_LCS=m
+CONFIG_CTC=m
+CONFIG_IUCV=m
+CONFIG_NETIUCV=m
+CONFIG_SMSGIUCV=m
+# CONFIG_CLAW is not set
+CONFIG_QETH=m
+
+#
+# Gigabit Ethernet default settings
+#
+CONFIG_QETH_IPV6=y
+CONFIG_QETH_VLAN=y
+CONFIG_CCWGROUP=m
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_SHAPER is not set
+CONFIG_NETCONSOLE=m
+CONFIG_NETPOLL=y
+# CONFIG_NETPOLL_RX is not set
+CONFIG_NETPOLL_TRAP=y
+CONFIG_NET_POLL_CONTROLLER=y
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+CONFIG_EXT2_FS_POSIX_ACL=y
+CONFIG_EXT2_FS_SECURITY=y
+CONFIG_EXT2_FS_XIP=y
+CONFIG_FS_XIP=y
+CONFIG_EXT3_FS=m
+CONFIG_EXT3_FS_XATTR=y
+CONFIG_EXT3_FS_POSIX_ACL=y
+CONFIG_EXT3_FS_SECURITY=y
+CONFIG_JBD=m
+# CONFIG_JBD_DEBUG is not set
+CONFIG_FS_MBCACHE=y
+CONFIG_REISERFS_FS=m
+# CONFIG_REISERFS_CHECK is not set
+CONFIG_REISERFS_PROC_INFO=y
+CONFIG_REISERFS_FS_XATTR=y
+CONFIG_REISERFS_FS_POSIX_ACL=y
+CONFIG_REISERFS_FS_SECURITY=y
+CONFIG_JFS_FS=m
+CONFIG_JFS_POSIX_ACL=y
+CONFIG_JFS_SECURITY=y
+# CONFIG_JFS_DEBUG is not set
+# CONFIG_JFS_STATISTICS is not set
+CONFIG_FS_POSIX_ACL=y
+CONFIG_XFS_FS=m
+CONFIG_XFS_QUOTA=y
+CONFIG_XFS_SECURITY=y
+CONFIG_XFS_POSIX_ACL=y
+# CONFIG_XFS_RT is not set
+CONFIG_OCFS2_FS=m
+# CONFIG_OCFS2_DEBUG_MASKLOG is not set
+CONFIG_MINIX_FS=m
+CONFIG_ROMFS_FS=m
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+CONFIG_QUOTA=y
+# CONFIG_QFMT_V1 is not set
+CONFIG_QFMT_V2=y
+CONFIG_QUOTACTL=y
+CONFIG_DNOTIFY=y
+CONFIG_AUTOFS_FS=m
+CONFIG_AUTOFS4_FS=m
+CONFIG_FUSE_FS=m
+
+#
+# Caches
+#
+CONFIG_FSCACHE=m
+
+#
+# CD-ROM/DVD Filesystems
+#
+CONFIG_ISO9660_FS=y
+CONFIG_JOLIET=y
+CONFIG_ZISOFS=y
+CONFIG_ZISOFS_FS=y
+CONFIG_UDF_FS=m
+CONFIG_UDF_NLS=y
+CONFIG_CACHEFILES=m
+CONFIG_CACHEFILES_DEBUG=y
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=m
+CONFIG_MSDOS_FS=m
+CONFIG_VFAT_FS=m
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="ascii"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_RAMFS=y
+CONFIG_CONFIGFS_FS=m
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+CONFIG_AFFS_FS=m
+CONFIG_HFS_FS=m
+CONFIG_HFSPLUS_FS=m
+CONFIG_BEFS_FS=m
+# CONFIG_BEFS_DEBUG is not set
+CONFIG_BFS_FS=m
+CONFIG_EFS_FS=m
+CONFIG_CRAMFS=m
+CONFIG_SQUASHFS=m
+# CONFIG_SQUASHFS_EMBEDDED is not set
+CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3
+# CONFIG_SQUASHFS_VMALLOC is not set
+CONFIG_VXFS_FS=m
+# CONFIG_HPFS_FS is not set
+CONFIG_QNX4FS_FS=m
+CONFIG_SYSV_FS=m
+CONFIG_UFS_FS=m
+# CONFIG_UFS_FS_WRITE is not set
+# CONFIG_UFS_DEBUG is not set
+
+#
+# Network File Systems
+#
+CONFIG_NFS_FS=m
+CONFIG_NFS_V3=y
+CONFIG_NFS_V3_ACL=y
+CONFIG_NFS_V4=y
+CONFIG_NFS_FSCACHE=y
+CONFIG_NFS_DIRECTIO=y
+CONFIG_NFSD=m
+CONFIG_NFSD_V2_ACL=y
+CONFIG_NFSD_V3=y
+CONFIG_NFSD_V3_ACL=y
+CONFIG_NFSD_V4=y
+CONFIG_NFSD_TCP=y
+CONFIG_LOCKD=m
+CONFIG_LOCKD_V4=y
+CONFIG_EXPORTFS=m
+CONFIG_NFS_ACL_SUPPORT=m
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=m
+CONFIG_SUNRPC_GSS=m
+CONFIG_RPCSEC_GSS_KRB5=m
+CONFIG_RPCSEC_GSS_SPKM3=m
+# CONFIG_SMB_FS is not set
+CONFIG_CIFS=m
+# CONFIG_CIFS_STATS is not set
+CONFIG_CIFS_WEAK_PW_HASH=y
+CONFIG_CIFS_XATTR=y
+CONFIG_CIFS_POSIX=y
+# CONFIG_CIFS_DEBUG2 is not set
+# CONFIG_CIFS_EXPERIMENTAL is not set
+CONFIG_NCP_FS=m
+CONFIG_NCPFS_PACKET_SIGNING=y
+CONFIG_NCPFS_IOCTL_LOCKING=y
+CONFIG_NCPFS_STRONG=y
+CONFIG_NCPFS_NFS_NS=y
+CONFIG_NCPFS_OS2_NS=y
+CONFIG_NCPFS_SMALLDOS=y
+CONFIG_NCPFS_NLS=y
+CONFIG_NCPFS_EXTRAS=y
+CONFIG_CODA_FS=m
+# CONFIG_CODA_FS_OLD_API is not set
+# CONFIG_AFS_FS is not set
+CONFIG_9P_FS=m
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+CONFIG_AMIGA_PARTITION=y
+# CONFIG_ATARI_PARTITION is not set
+CONFIG_IBM_PARTITION=y
+# CONFIG_MAC_PARTITION is not set
+CONFIG_MSDOS_PARTITION=y
+CONFIG_BSD_DISKLABEL=y
+CONFIG_MINIX_SUBPARTITION=y
+CONFIG_SOLARIS_X86_PARTITION=y
+CONFIG_UNIXWARE_DISKLABEL=y
+# CONFIG_LDM_PARTITION is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+CONFIG_KARMA_PARTITION=y
+CONFIG_EFI_PARTITION=y
+
+#
+# Native Language Support
+#
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="utf8"
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_CODEPAGE_737=m
+CONFIG_NLS_CODEPAGE_775=m
+CONFIG_NLS_CODEPAGE_850=m
+CONFIG_NLS_CODEPAGE_852=m
+CONFIG_NLS_CODEPAGE_855=m
+CONFIG_NLS_CODEPAGE_857=m
+CONFIG_NLS_CODEPAGE_860=m
+CONFIG_NLS_CODEPAGE_861=m
+CONFIG_NLS_CODEPAGE_862=m
+CONFIG_NLS_CODEPAGE_863=m
+CONFIG_NLS_CODEPAGE_864=m
+CONFIG_NLS_CODEPAGE_865=m
+CONFIG_NLS_CODEPAGE_866=m
+CONFIG_NLS_CODEPAGE_869=m
+CONFIG_NLS_CODEPAGE_936=m
+CONFIG_NLS_CODEPAGE_950=m
+CONFIG_NLS_CODEPAGE_932=m
+CONFIG_NLS_CODEPAGE_949=m
+CONFIG_NLS_CODEPAGE_874=m
+CONFIG_NLS_ISO8859_8=m
+CONFIG_NLS_CODEPAGE_1250=m
+CONFIG_NLS_CODEPAGE_1251=m
+CONFIG_NLS_ASCII=y
+CONFIG_NLS_ISO8859_1=m
+CONFIG_NLS_ISO8859_2=m
+CONFIG_NLS_ISO8859_3=m
+CONFIG_NLS_ISO8859_4=m
+CONFIG_NLS_ISO8859_5=m
+CONFIG_NLS_ISO8859_6=m
+CONFIG_NLS_ISO8859_7=m
+CONFIG_NLS_ISO8859_9=m
+CONFIG_NLS_ISO8859_13=m
+CONFIG_NLS_ISO8859_14=m
+CONFIG_NLS_ISO8859_15=m
+CONFIG_NLS_KOI8_R=m
+CONFIG_NLS_KOI8_U=m
+CONFIG_NLS_UTF8=m
+
+#
+# Profiling support
+#
+CONFIG_PROFILING=y
+CONFIG_OPROFILE=m
+
+#
+# Kernel hacking
+#
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+# CONFIG_PRINTK_TIME is not set
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_UNUSED_SYMBOLS is not set
+CONFIG_DEBUG_KERNEL=y
+CONFIG_LOG_BUF_SHIFT=16
+# CONFIG_DETECT_SOFTLOCKUP is not set
+CONFIG_SCHEDSTATS=y
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
+CONFIG_DEBUG_SPINLOCK=y
+# 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=y
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+# CONFIG_DEBUG_KOBJECT is not set
+CONFIG_DEBUG_INFO=y
+CONFIG_DEBUG_FS=y
+# CONFIG_DEBUG_VM is not set
+CONFIG_DEBUG_LIST=y
+# CONFIG_FRAME_POINTER is not set
+CONFIG_UNWIND_INFO=y
+# CONFIG_FORCED_INLINING is not set
+# CONFIG_BOOT_DELAY is not set
+# CONFIG_RCU_TORTURE_TEST is not set
+
+#
+# Security options
+#
+CONFIG_KEYS=y
+CONFIG_KEYS_DEBUG_PROC_KEYS=y
+CONFIG_SECURITY=y
+CONFIG_SECURITY_NETWORK=y
+# CONFIG_SECURITY_NETWORK_XFRM is not set
+CONFIG_SECURITY_CAPABILITIES=y
+# CONFIG_SECURITY_SECLVL is not set
+CONFIG_SECURITY_SELINUX=y
+CONFIG_SECURITY_SELINUX_BOOTPARAM=y
+CONFIG_SECURITY_SELINUX_BOOTPARAM_VALUE=1
+CONFIG_SECURITY_SELINUX_DISABLE=y
+CONFIG_SECURITY_SELINUX_DEVELOP=y
+CONFIG_SECURITY_SELINUX_AVC_STATS=y
+CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE=1
+# CONFIG_SECURITY_SELINUX_ENABLE_SECMARK_DEFAULT is not set
+# CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX is not set
+
+#
+# Cryptographic options
+#
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_NULL=m
+CONFIG_CRYPTO_MD4=m
+CONFIG_CRYPTO_MD5=m
+CONFIG_CRYPTO_SHA1=y
+CONFIG_CRYPTO_SHA1_S390=m
+CONFIG_CRYPTO_SHA256=m
+CONFIG_CRYPTO_SHA256_S390=m
+CONFIG_CRYPTO_SHA512=m
+CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_TGR192=m
+CONFIG_CRYPTO_DES=m
+CONFIG_CRYPTO_DES_S390=m
+CONFIG_CRYPTO_BLOWFISH=m
+CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_SERPENT=m
+CONFIG_CRYPTO_AES=m
+CONFIG_CRYPTO_AES_S390=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_TEST is not set
+CONFIG_CRYPTO_SIGNATURE=y
+CONFIG_CRYPTO_SIGNATURE_DSA=y
+CONFIG_CRYPTO_MPILIB=y
+
+#
+# Hardware crypto devices
+#
+
+#
+# Library routines
+#
+CONFIG_CRC_CCITT=m
+CONFIG_CRC16=m
+CONFIG_CRC32=y
+CONFIG_LIBCRC32C=m
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=m
+CONFIG_TEXTSEARCH=y
+CONFIG_TEXTSEARCH_KMP=m
+CONFIG_TEXTSEARCH_BM=m
+CONFIG_TEXTSEARCH_FSM=m
+CONFIG_PLIST=y
diff --git a/configs/kernel-2.6.18-x86_64-kdump.config b/configs/kernel-2.6.18-x86_64-kdump.config
new file mode 100644
index 000000000..e62073eff
--- /dev/null
+++ b/configs/kernel-2.6.18-x86_64-kdump.config
@@ -0,0 +1,3136 @@
+# x86_64
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.18.2-rc1
+# Mon Nov 13 09:44:42 2006
+#
+CONFIG_X86_64=y
+CONFIG_64BIT=y
+CONFIG_X86=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_SEMAPHORE_SLEEPERS=y
+CONFIG_MMU=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_X86_CMPXCHG=y
+CONFIG_EARLY_PRINTK=y
+CONFIG_GENERIC_ISA_DMA=y
+CONFIG_GENERIC_IOMAP=y
+CONFIG_ARCH_MAY_HAVE_PC_FDC=y
+CONFIG_DMI=y
+CONFIG_AUDIT_ARCH=y
+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=y
+CONFIG_SYSVIPC=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_BSD_PROCESS_ACCT=y
+# CONFIG_BSD_PROCESS_ACCT_V3 is not set
+CONFIG_TASKSTATS=y
+CONFIG_TASK_DELAY_ACCT=y
+CONFIG_AUDIT=y
+CONFIG_AUDITSYSCALL=y
+# CONFIG_IKCONFIG is not set
+CONFIG_RELAY=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+# CONFIG_EMBEDDED is not set
+CONFIG_UID16=y
+CONFIG_SYSCTL=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
+CONFIG_KALLSYMS_EXTRA_PASS=y
+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=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+CONFIG_MODULE_SIG=y
+# CONFIG_MODULE_SIG_FORCE is not set
+CONFIG_KMOD=y
+
+#
+# Process debugging support
+#
+CONFIG_UTRACE=y
+CONFIG_PTRACE=y
+
+#
+# Block layer
+#
+CONFIG_LBD=y
+CONFIG_BLK_DEV_IO_TRACE=y
+CONFIG_LSF=y
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_DEFAULT_AS is not set
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+
+#
+# Processor type and features
+#
+CONFIG_X86_PC=y
+# CONFIG_X86_VSMP is not set
+# CONFIG_MK8 is not set
+# CONFIG_MPSC is not set
+CONFIG_GENERIC_CPU=y
+# CONFIG_X86_64_XEN is not set
+CONFIG_X86_L1_CACHE_BYTES=128
+CONFIG_X86_L1_CACHE_SHIFT=7
+CONFIG_X86_INTERNODE_CACHE_BYTES=128
+CONFIG_X86_TSC=y
+CONFIG_X86_GOOD_APIC=y
+CONFIG_MICROCODE=m
+CONFIG_X86_MSR=y
+CONFIG_X86_CPUID=y
+CONFIG_X86_IO_APIC=y
+CONFIG_X86_LOCAL_APIC=y
+CONFIG_MTRR=y
+# CONFIG_SMP is not set
+# CONFIG_PREEMPT_NONE is not set
+CONFIG_PREEMPT_VOLUNTARY=y
+# CONFIG_PREEMPT is not set
+CONFIG_ARCH_SPARSEMEM_ENABLE=y
+CONFIG_ARCH_FLATMEM_ENABLE=y
+CONFIG_SELECT_MEMORY_MODEL=y
+# CONFIG_FLATMEM_MANUAL is not set
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+CONFIG_SPARSEMEM_MANUAL=y
+CONFIG_SPARSEMEM=y
+CONFIG_HAVE_MEMORY_PRESENT=y
+# CONFIG_SPARSEMEM_STATIC is not set
+CONFIG_SPARSEMEM_EXTREME=y
+
+#
+# Memory hotplug is currently incompatible with Software Suspend
+#
+CONFIG_SPLIT_PTLOCK_CPUS=4
+CONFIG_RESOURCES_64BIT=y
+CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
+CONFIG_HPET_TIMER=y
+CONFIG_HPET_EMULATE_RTC=y
+CONFIG_IOMMU=y
+CONFIG_CALGARY_IOMMU=y
+CONFIG_SWIOTLB=y
+CONFIG_X86_MCE=y
+CONFIG_X86_MCE_INTEL=y
+CONFIG_X86_MCE_AMD=y
+CONFIG_KEXEC=y
+CONFIG_CRASH_DUMP=y
+CONFIG_PHYSICAL_START=0x1000000
+# CONFIG_SECCOMP is not set
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
+CONFIG_REORDER=y
+CONFIG_K8_NB=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_ISA_DMA_API=y
+
+#
+# Power management options
+#
+CONFIG_PM=y
+CONFIG_PM_LEGACY=y
+# CONFIG_PM_DEBUG is not set
+CONFIG_SOFTWARE_SUSPEND=y
+CONFIG_PM_STD_PARTITION=""
+
+#
+# ACPI (Advanced Configuration and Power Interface) Support
+#
+CONFIG_ACPI=y
+CONFIG_ACPI_SLEEP=y
+CONFIG_ACPI_SLEEP_PROC_FS=y
+# CONFIG_ACPI_SLEEP_PROC_SLEEP is not set
+CONFIG_ACPI_AC=m
+CONFIG_ACPI_BATTERY=m
+CONFIG_ACPI_BUTTON=m
+CONFIG_ACPI_VIDEO=m
+# CONFIG_ACPI_HOTKEY is not set
+CONFIG_ACPI_FAN=y
+CONFIG_ACPI_DOCK=m
+CONFIG_ACPI_PROCESSOR=y
+CONFIG_ACPI_THERMAL=y
+CONFIG_ACPI_ASUS=m
+CONFIG_ACPI_IBM=m
+CONFIG_ACPI_TOSHIBA=m
+CONFIG_ACPI_BLACKLIST_YEAR=0
+# CONFIG_ACPI_DEBUG is not set
+CONFIG_ACPI_EC=y
+CONFIG_ACPI_POWER=y
+CONFIG_ACPI_SYSTEM=y
+CONFIG_X86_PM_TIMER=y
+CONFIG_ACPI_CONTAINER=m
+CONFIG_ACPI_SBS=m
+
+#
+# CPU Frequency scaling
+#
+CONFIG_CPU_FREQ=y
+CONFIG_CPU_FREQ_TABLE=y
+CONFIG_CPU_FREQ_DEBUG=y
+CONFIG_CPU_FREQ_STAT=m
+CONFIG_CPU_FREQ_STAT_DETAILS=y
+# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set
+CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE=y
+CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
+CONFIG_CPU_FREQ_GOV_POWERSAVE=m
+CONFIG_CPU_FREQ_GOV_USERSPACE=y
+CONFIG_CPU_FREQ_GOV_ONDEMAND=m
+CONFIG_CPU_FREQ_GOV_CONSERVATIVE=m
+
+#
+# CPUFreq processor drivers
+#
+CONFIG_X86_POWERNOW_K8=y
+CONFIG_X86_POWERNOW_K8_ACPI=y
+CONFIG_X86_SPEEDSTEP_CENTRINO=y
+CONFIG_X86_SPEEDSTEP_CENTRINO_ACPI=y
+CONFIG_X86_ACPI_CPUFREQ=m
+
+#
+# shared options
+#
+# CONFIG_X86_ACPI_CPUFREQ_PROC_INTF is not set
+# CONFIG_X86_SPEEDSTEP_LIB is not set
+
+#
+# Bus options (PCI etc.)
+#
+CONFIG_PCI=y
+CONFIG_PCI_DIRECT=y
+CONFIG_PCI_MMCONFIG=y
+CONFIG_PCIEPORTBUS=y
+CONFIG_HOTPLUG_PCI_PCIE=m
+# CONFIG_HOTPLUG_PCI_PCIE_POLL_EVENT_MODE is not set
+# CONFIG_PCI_MSI is not set
+# CONFIG_PCI_DEBUG is not set
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+CONFIG_PCCARD=y
+# CONFIG_PCMCIA_DEBUG is not set
+CONFIG_PCMCIA=y
+CONFIG_PCMCIA_LOAD_CIS=y
+CONFIG_PCMCIA_IOCTL=y
+CONFIG_CARDBUS=y
+
+#
+# PC-card bridges
+#
+CONFIG_YENTA=y
+CONFIG_YENTA_O2=y
+CONFIG_YENTA_RICOH=y
+CONFIG_YENTA_TI=y
+CONFIG_YENTA_ENE_TUNE=y
+CONFIG_YENTA_TOSHIBA=y
+CONFIG_PD6729=m
+CONFIG_I82092=m
+CONFIG_PCCARD_NONSTATIC=y
+
+#
+# PCI Hotplug Support
+#
+CONFIG_HOTPLUG_PCI=y
+CONFIG_HOTPLUG_PCI_FAKE=m
+CONFIG_HOTPLUG_PCI_ACPI=m
+CONFIG_HOTPLUG_PCI_ACPI_IBM=m
+# CONFIG_HOTPLUG_PCI_CPCI is not set
+CONFIG_HOTPLUG_PCI_SHPC=m
+# CONFIG_HOTPLUG_PCI_SHPC_POLL_EVENT_MODE is not set
+
+#
+# Executable file formats / Emulations
+#
+CONFIG_BINFMT_ELF=y
+CONFIG_BINFMT_MISC=y
+CONFIG_IA32_EMULATION=y
+# CONFIG_IA32_AOUT is not set
+CONFIG_COMPAT=y
+CONFIG_SYSVIPC_COMPAT=y
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+# CONFIG_NETDEBUG is not set
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=y
+CONFIG_NET_KEY=m
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_ASK_IP_FIB_HASH=y
+# 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
+# CONFIG_IP_PNP is not set
+CONFIG_NET_IPIP=m
+CONFIG_NET_IPGRE=m
+CONFIG_NET_IPGRE_BROADCAST=y
+CONFIG_IP_MROUTE=y
+CONFIG_IP_PIMSM_V1=y
+CONFIG_IP_PIMSM_V2=y
+# CONFIG_ARPD is not set
+CONFIG_SYN_COOKIES=y
+CONFIG_INET_AH=m
+CONFIG_INET_ESP=m
+CONFIG_INET_IPCOMP=m
+CONFIG_INET_XFRM_TUNNEL=m
+CONFIG_INET_TUNNEL=m
+CONFIG_INET_XFRM_MODE_TRANSPORT=m
+CONFIG_INET_XFRM_MODE_TUNNEL=m
+CONFIG_INET_DIAG=m
+CONFIG_INET_TCP_DIAG=m
+CONFIG_TCP_CONG_ADVANCED=y
+
+#
+# TCP congestion control
+#
+CONFIG_TCP_CONG_BIC=y
+CONFIG_TCP_CONG_CUBIC=m
+CONFIG_TCP_CONG_WESTWOOD=m
+CONFIG_TCP_CONG_HTCP=m
+CONFIG_TCP_CONG_HSTCP=m
+CONFIG_TCP_CONG_HYBLA=m
+CONFIG_TCP_CONG_VEGAS=m
+CONFIG_TCP_CONG_SCALABLE=m
+CONFIG_TCP_CONG_LP=m
+CONFIG_TCP_CONG_VENO=m
+
+#
+# IP: Virtual Server Configuration
+#
+CONFIG_IP_VS=m
+# CONFIG_IP_VS_DEBUG is not set
+CONFIG_IP_VS_TAB_BITS=12
+
+#
+# IPVS transport protocol load balancing support
+#
+CONFIG_IP_VS_PROTO_TCP=y
+CONFIG_IP_VS_PROTO_UDP=y
+CONFIG_IP_VS_PROTO_ESP=y
+CONFIG_IP_VS_PROTO_AH=y
+
+#
+# IPVS scheduler
+#
+CONFIG_IP_VS_RR=m
+CONFIG_IP_VS_WRR=m
+CONFIG_IP_VS_LC=m
+CONFIG_IP_VS_WLC=m
+CONFIG_IP_VS_LBLC=m
+CONFIG_IP_VS_LBLCR=m
+CONFIG_IP_VS_DH=m
+CONFIG_IP_VS_SH=m
+CONFIG_IP_VS_SED=m
+CONFIG_IP_VS_NQ=m
+
+#
+# IPVS application helper
+#
+CONFIG_IP_VS_FTP=m
+CONFIG_IPV6=m
+CONFIG_IPV6_PRIVACY=y
+CONFIG_IPV6_ROUTER_PREF=y
+CONFIG_IPV6_ROUTE_INFO=y
+CONFIG_INET6_AH=m
+CONFIG_INET6_ESP=m
+CONFIG_INET6_IPCOMP=m
+CONFIG_INET6_XFRM_TUNNEL=m
+CONFIG_INET6_TUNNEL=m
+CONFIG_INET6_XFRM_MODE_TRANSPORT=m
+CONFIG_INET6_XFRM_MODE_TUNNEL=m
+CONFIG_IPV6_TUNNEL=m
+CONFIG_NETWORK_SECMARK=y
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_DEBUG is not set
+CONFIG_BRIDGE_NETFILTER=y
+
+#
+# Core Netfilter Configuration
+#
+CONFIG_NETFILTER_NETLINK=m
+CONFIG_NETFILTER_NETLINK_QUEUE=m
+CONFIG_NETFILTER_NETLINK_LOG=m
+CONFIG_NETFILTER_XTABLES=m
+CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
+CONFIG_NETFILTER_XT_TARGET_CONNMARK=m
+CONFIG_NETFILTER_XT_TARGET_MARK=m
+CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
+CONFIG_NETFILTER_XT_TARGET_NOTRACK=m
+CONFIG_NETFILTER_XT_TARGET_SECMARK=m
+CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=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_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_PHYSDEV=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
+
+#
+# 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=m
+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_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_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_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
+CONFIG_IP_NF_ARPTABLES=m
+CONFIG_IP_NF_ARPFILTER=m
+CONFIG_IP_NF_ARP_MANGLE=m
+
+#
+# IPv6: Netfilter Configuration (EXPERIMENTAL)
+#
+CONFIG_IP6_NF_QUEUE=m
+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_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
+
+#
+# DECnet: Netfilter Configuration
+#
+# CONFIG_DECNET_NF_GRABULATOR is not set
+
+#
+# Bridge: Netfilter Configuration
+#
+CONFIG_BRIDGE_NF_EBTABLES=m
+CONFIG_BRIDGE_EBT_BROUTE=m
+CONFIG_BRIDGE_EBT_T_FILTER=m
+CONFIG_BRIDGE_EBT_T_NAT=m
+CONFIG_BRIDGE_EBT_802_3=m
+CONFIG_BRIDGE_EBT_AMONG=m
+CONFIG_BRIDGE_EBT_ARP=m
+CONFIG_BRIDGE_EBT_IP=m
+CONFIG_BRIDGE_EBT_LIMIT=m
+CONFIG_BRIDGE_EBT_MARK=m
+CONFIG_BRIDGE_EBT_PKTTYPE=m
+CONFIG_BRIDGE_EBT_STP=m
+CONFIG_BRIDGE_EBT_VLAN=m
+CONFIG_BRIDGE_EBT_ARPREPLY=m
+CONFIG_BRIDGE_EBT_DNAT=m
+CONFIG_BRIDGE_EBT_MARK_T=m
+CONFIG_BRIDGE_EBT_REDIRECT=m
+CONFIG_BRIDGE_EBT_SNAT=m
+CONFIG_BRIDGE_EBT_LOG=m
+CONFIG_BRIDGE_EBT_ULOG=m
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+CONFIG_IP_DCCP=m
+CONFIG_INET_DCCP_DIAG=m
+CONFIG_IP_DCCP_ACKVEC=y
+
+#
+# DCCP CCIDs Configuration (EXPERIMENTAL)
+#
+CONFIG_IP_DCCP_CCID2=m
+CONFIG_IP_DCCP_CCID3=m
+CONFIG_IP_DCCP_TFRC_LIB=m
+
+#
+# DCCP Kernel Hacking
+#
+# CONFIG_IP_DCCP_DEBUG is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+CONFIG_IP_SCTP=m
+# CONFIG_SCTP_DBG_MSG is not set
+# CONFIG_SCTP_DBG_OBJCNT is not set
+# CONFIG_SCTP_HMAC_NONE is not set
+# CONFIG_SCTP_HMAC_SHA1 is not set
+CONFIG_SCTP_HMAC_MD5=y
+
+#
+# TIPC Configuration (EXPERIMENTAL)
+#
+CONFIG_TIPC=m
+# CONFIG_TIPC_ADVANCED is not set
+# CONFIG_TIPC_DEBUG is not set
+CONFIG_ATM=m
+CONFIG_ATM_CLIP=m
+# CONFIG_ATM_CLIP_NO_ICMP is not set
+CONFIG_ATM_LANE=m
+# CONFIG_ATM_MPOA is not set
+CONFIG_ATM_BR2684=m
+# CONFIG_ATM_BR2684_IPFILTER is not set
+CONFIG_BRIDGE=m
+CONFIG_VLAN_8021Q=m
+CONFIG_DECNET=m
+CONFIG_DECNET_ROUTER=y
+CONFIG_DECNET_ROUTE_FWMARK=y
+CONFIG_LLC=y
+# CONFIG_LLC2 is not set
+CONFIG_IPX=m
+# CONFIG_IPX_INTERN is not set
+CONFIG_ATALK=m
+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_ECONET is not set
+CONFIG_WAN_ROUTER=m
+
+#
+# QoS and/or fair queueing
+#
+CONFIG_NET_SCHED=y
+# CONFIG_NET_SCH_CLK_JIFFIES is not set
+CONFIG_NET_SCH_CLK_GETTIMEOFDAY=y
+# CONFIG_NET_SCH_CLK_CPU is not set
+
+#
+# Queueing/Scheduling
+#
+CONFIG_NET_SCH_CBQ=m
+CONFIG_NET_SCH_HTB=m
+CONFIG_NET_SCH_HFSC=m
+CONFIG_NET_SCH_ATM=m
+CONFIG_NET_SCH_PRIO=m
+CONFIG_NET_SCH_RED=m
+CONFIG_NET_SCH_SFQ=m
+CONFIG_NET_SCH_TEQL=m
+CONFIG_NET_SCH_TBF=m
+CONFIG_NET_SCH_GRED=m
+CONFIG_NET_SCH_DSMARK=m
+CONFIG_NET_SCH_NETEM=m
+CONFIG_NET_SCH_INGRESS=m
+
+#
+# Classification
+#
+CONFIG_NET_CLS=y
+CONFIG_NET_CLS_BASIC=m
+CONFIG_NET_CLS_TCINDEX=m
+CONFIG_NET_CLS_ROUTE4=m
+CONFIG_NET_CLS_ROUTE=y
+CONFIG_NET_CLS_FW=m
+CONFIG_NET_CLS_U32=m
+CONFIG_CLS_U32_PERF=y
+CONFIG_CLS_U32_MARK=y
+CONFIG_NET_CLS_RSVP=m
+CONFIG_NET_CLS_RSVP6=m
+CONFIG_NET_EMATCH=y
+CONFIG_NET_EMATCH_STACK=32
+CONFIG_NET_EMATCH_CMP=m
+CONFIG_NET_EMATCH_NBYTE=m
+CONFIG_NET_EMATCH_U32=m
+CONFIG_NET_EMATCH_META=m
+CONFIG_NET_EMATCH_TEXT=m
+CONFIG_NET_CLS_ACT=y
+CONFIG_NET_ACT_POLICE=m
+CONFIG_NET_ACT_GACT=m
+CONFIG_GACT_PROB=y
+CONFIG_NET_ACT_MIRRED=m
+CONFIG_NET_ACT_IPT=m
+CONFIG_NET_ACT_PEDIT=m
+CONFIG_NET_ACT_SIMP=m
+CONFIG_NET_CLS_IND=y
+CONFIG_NET_ESTIMATOR=y
+
+#
+# Network testing
+#
+CONFIG_NET_PKTGEN=m
+# CONFIG_NET_TCPPROBE is not set
+# CONFIG_HAMRADIO is not set
+CONFIG_IRDA=m
+
+#
+# IrDA protocols
+#
+CONFIG_IRLAN=m
+CONFIG_IRNET=m
+CONFIG_IRCOMM=m
+# CONFIG_IRDA_ULTRA is not set
+
+#
+# IrDA options
+#
+CONFIG_IRDA_CACHE_LAST_LSAP=y
+CONFIG_IRDA_FAST_RR=y
+# CONFIG_IRDA_DEBUG is not set
+
+#
+# Infrared-port device drivers
+#
+
+#
+# SIR device drivers
+#
+CONFIG_IRTTY_SIR=m
+
+#
+# Dongle support
+#
+CONFIG_DONGLE=y
+CONFIG_ESI_DONGLE=m
+CONFIG_ACTISYS_DONGLE=m
+CONFIG_TEKRAM_DONGLE=m
+CONFIG_TOIM3232_DONGLE=m
+CONFIG_LITELINK_DONGLE=m
+CONFIG_MA600_DONGLE=m
+CONFIG_GIRBIL_DONGLE=m
+CONFIG_MCP2120_DONGLE=m
+CONFIG_OLD_BELKIN_DONGLE=m
+CONFIG_ACT200L_DONGLE=m
+
+#
+# Old SIR device drivers
+#
+CONFIG_IRPORT_SIR=m
+
+#
+# Old Serial dongle support
+#
+# CONFIG_DONGLE_OLD is not set
+
+#
+# FIR device drivers
+#
+CONFIG_USB_IRDA=m
+CONFIG_SIGMATEL_FIR=m
+CONFIG_NSC_FIR=m
+CONFIG_WINBOND_FIR=m
+CONFIG_SMC_IRCC_FIR=m
+CONFIG_ALI_FIR=m
+CONFIG_VLSI_FIR=m
+CONFIG_VIA_FIR=m
+CONFIG_MCS_FIR=m
+CONFIG_BT=m
+CONFIG_BT_L2CAP=m
+CONFIG_BT_SCO=m
+CONFIG_BT_RFCOMM=m
+CONFIG_BT_RFCOMM_TTY=y
+CONFIG_BT_BNEP=m
+CONFIG_BT_BNEP_MC_FILTER=y
+CONFIG_BT_BNEP_PROTO_FILTER=y
+CONFIG_BT_CMTP=m
+CONFIG_BT_HIDP=m
+
+#
+# Bluetooth device drivers
+#
+CONFIG_BT_HCIUSB=m
+CONFIG_BT_HCIUSB_SCO=y
+CONFIG_BT_HCIUART=m
+CONFIG_BT_HCIUART_H4=y
+CONFIG_BT_HCIUART_BCSP=y
+CONFIG_BT_HCIBCM203X=m
+CONFIG_BT_HCIBPA10X=m
+CONFIG_BT_HCIBFUSB=m
+CONFIG_BT_HCIDTL1=m
+CONFIG_BT_HCIBT3C=m
+CONFIG_BT_HCIBLUECARD=m
+CONFIG_BT_HCIBTUART=m
+CONFIG_BT_HCIVHCI=m
+CONFIG_IEEE80211=m
+# CONFIG_IEEE80211_DEBUG is not set
+CONFIG_IEEE80211_CRYPT_WEP=m
+CONFIG_IEEE80211_CRYPT_CCMP=m
+CONFIG_IEEE80211_CRYPT_TKIP=m
+CONFIG_IEEE80211_SOFTMAC=m
+CONFIG_IEEE80211_SOFTMAC_DEBUG=y
+CONFIG_TUX=m
+
+#
+# TUX options
+#
+CONFIG_TUX_EXTCGI=y
+CONFIG_TUX_EXTENDED_LOG=y
+# CONFIG_TUX_DEBUG is not set
+CONFIG_WIRELESS_EXT=y
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_SYS_HYPERVISOR is not set
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+CONFIG_CONNECTOR=y
+CONFIG_PROC_EVENTS=y
+
+#
+# Memory Technology Devices (MTD)
+#
+CONFIG_MTD=m
+# CONFIG_MTD_DEBUG is not set
+CONFIG_MTD_CONCAT=m
+CONFIG_MTD_PARTITIONS=y
+CONFIG_MTD_REDBOOT_PARTS=m
+CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1
+# CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED is not set
+# CONFIG_MTD_REDBOOT_PARTS_READONLY is not set
+CONFIG_MTD_CMDLINE_PARTS=y
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=m
+CONFIG_MTD_BLOCK=m
+CONFIG_MTD_BLOCK_RO=m
+CONFIG_FTL=m
+CONFIG_NFTL=m
+CONFIG_NFTL_RW=y
+CONFIG_INFTL=m
+CONFIG_RFD_FTL=m
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=m
+CONFIG_MTD_JEDECPROBE=m
+CONFIG_MTD_GEN_PROBE=m
+# CONFIG_MTD_CFI_ADV_OPTIONS 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_CFI_INTELEXT=m
+CONFIG_MTD_CFI_AMDSTD=m
+CONFIG_MTD_CFI_STAA=m
+CONFIG_MTD_CFI_UTIL=m
+CONFIG_MTD_RAM=m
+CONFIG_MTD_ROM=m
+CONFIG_MTD_ABSENT=m
+# CONFIG_MTD_OBSOLETE_CHIPS is not set
+
+#
+# Mapping drivers for chip access
+#
+CONFIG_MTD_COMPLEX_MAPPINGS=y
+# CONFIG_MTD_PHYSMAP is not set
+# CONFIG_MTD_PNC2000 is not set
+CONFIG_MTD_SC520CDP=m
+CONFIG_MTD_NETSC520=m
+CONFIG_MTD_TS5500=m
+# CONFIG_MTD_SBC_GXX is not set
+# CONFIG_MTD_AMD76XROM is not set
+# CONFIG_MTD_ICHXROM is not set
+CONFIG_MTD_SCB2_FLASH=m
+# CONFIG_MTD_NETtel is not set
+# CONFIG_MTD_DILNETPC is not set
+# CONFIG_MTD_L440GX is not set
+CONFIG_MTD_PCI=m
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+CONFIG_MTD_PMC551=m
+# CONFIG_MTD_PMC551_BUGFIX is not set
+# CONFIG_MTD_PMC551_DEBUG is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+CONFIG_MTD_MTDRAM=m
+CONFIG_MTDRAM_TOTAL_SIZE=4096
+CONFIG_MTDRAM_ERASE_SIZE=128
+CONFIG_MTD_BLOCK2MTD=m
+
+#
+# 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=m
+# CONFIG_MTD_NAND_VERIFY_WRITE is not set
+CONFIG_MTD_NAND_ECC_SMC=y
+CONFIG_MTD_NAND_IDS=m
+CONFIG_MTD_NAND_DISKONCHIP=m
+# CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADVANCED is not set
+CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADDRESS=0
+# CONFIG_MTD_NAND_DISKONCHIP_BBTWRITE is not set
+CONFIG_MTD_NAND_NANDSIM=m
+
+#
+# OneNAND Flash Device Drivers
+#
+# CONFIG_MTD_ONENAND is not set
+
+#
+# Parallel port support
+#
+CONFIG_PARPORT=m
+CONFIG_PARPORT_PC=m
+CONFIG_PARPORT_SERIAL=m
+# CONFIG_PARPORT_PC_FIFO is not set
+# CONFIG_PARPORT_PC_SUPERIO is not set
+CONFIG_PARPORT_PC_PCMCIA=m
+CONFIG_PARPORT_NOT_PC=y
+# CONFIG_PARPORT_GSC is not set
+# CONFIG_PARPORT_AX88796 is not set
+CONFIG_PARPORT_1284=y
+
+#
+# Plug and Play support
+#
+CONFIG_PNP=y
+# CONFIG_PNP_DEBUG is not set
+
+#
+# Protocols
+#
+CONFIG_PNPACPI=y
+
+#
+# Block devices
+#
+CONFIG_BLK_DEV_FD=m
+CONFIG_PARIDE=m
+CONFIG_PARIDE_PARPORT=m
+
+#
+# Parallel IDE high-level drivers
+#
+CONFIG_PARIDE_PD=m
+CONFIG_PARIDE_PCD=m
+CONFIG_PARIDE_PF=m
+CONFIG_PARIDE_PT=m
+CONFIG_PARIDE_PG=m
+
+#
+# Parallel IDE protocol modules
+#
+CONFIG_PARIDE_ATEN=m
+CONFIG_PARIDE_BPCK=m
+CONFIG_PARIDE_COMM=m
+CONFIG_PARIDE_DSTR=m
+CONFIG_PARIDE_FIT2=m
+CONFIG_PARIDE_FIT3=m
+CONFIG_PARIDE_EPAT=m
+CONFIG_PARIDE_EPATC8=y
+CONFIG_PARIDE_EPIA=m
+CONFIG_PARIDE_FRIQ=m
+CONFIG_PARIDE_FRPW=m
+CONFIG_PARIDE_KBIC=m
+CONFIG_PARIDE_KTTI=m
+CONFIG_PARIDE_ON20=m
+CONFIG_PARIDE_ON26=m
+CONFIG_BLK_CPQ_DA=m
+CONFIG_BLK_CPQ_CISS_DA=m
+CONFIG_CISS_SCSI_TAPE=y
+CONFIG_BLK_DEV_DAC960=m
+CONFIG_BLK_DEV_UMEM=m
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=m
+CONFIG_BLK_DEV_CRYPTOLOOP=m
+CONFIG_BLK_DEV_NBD=m
+CONFIG_BLK_DEV_SX8=m
+CONFIG_BLK_DEV_UB=m
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=16384
+CONFIG_BLK_DEV_RAM_BLOCKSIZE=4096
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_CDROM_PKTCDVD=m
+CONFIG_CDROM_PKTCDVD_BUFFERS=8
+# CONFIG_CDROM_PKTCDVD_WCACHE is not set
+CONFIG_ATA_OVER_ETH=m
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+CONFIG_IDE=y
+CONFIG_BLK_DEV_IDE=y
+
+#
+# Please see Documentation/ide.txt for help/info on IDE drives
+#
+# CONFIG_BLK_DEV_IDE_SATA is not set
+# CONFIG_BLK_DEV_HD_IDE is not set
+CONFIG_BLK_DEV_IDEDISK=y
+CONFIG_IDEDISK_MULTI_MODE=y
+CONFIG_BLK_DEV_IDECS=m
+CONFIG_BLK_DEV_IDECD=m
+# CONFIG_BLK_DEV_IDETAPE is not set
+CONFIG_BLK_DEV_IDEFLOPPY=y
+CONFIG_BLK_DEV_IDESCSI=m
+CONFIG_IDE_TASK_IOCTL=y
+
+#
+# IDE chipset support/bugfixes
+#
+CONFIG_IDE_GENERIC=y
+# CONFIG_BLK_DEV_CMD640 is not set
+CONFIG_BLK_DEV_IDEPNP=y
+CONFIG_BLK_DEV_IDEPCI=y
+CONFIG_IDEPCI_SHARE_IRQ=y
+# CONFIG_BLK_DEV_OFFBOARD is not set
+CONFIG_BLK_DEV_GENERIC=y
+# CONFIG_BLK_DEV_OPTI621 is not set
+# CONFIG_BLK_DEV_RZ1000 is not set
+CONFIG_BLK_DEV_IDEDMA_PCI=y
+# CONFIG_BLK_DEV_IDEDMA_FORCED is not set
+CONFIG_IDEDMA_PCI_AUTO=y
+# CONFIG_IDEDMA_ONLYDISK is not set
+CONFIG_BLK_DEV_AEC62XX=y
+CONFIG_BLK_DEV_ALI15X3=y
+# CONFIG_WDC_ALI15X3 is not set
+CONFIG_BLK_DEV_AMD74XX=y
+CONFIG_BLK_DEV_ATIIXP=y
+CONFIG_BLK_DEV_CMD64X=y
+# CONFIG_BLK_DEV_TRIFLEX is not set
+# CONFIG_BLK_DEV_CY82C693 is not set
+# CONFIG_BLK_DEV_CS5520 is not set
+# CONFIG_BLK_DEV_CS5530 is not set
+CONFIG_BLK_DEV_HPT34X=y
+# CONFIG_HPT34X_AUTODMA is not set
+CONFIG_BLK_DEV_HPT366=y
+# CONFIG_BLK_DEV_SC1200 is not set
+CONFIG_BLK_DEV_PIIX=y
+CONFIG_BLK_DEV_IT821X=y
+# CONFIG_BLK_DEV_NS87415 is not set
+CONFIG_BLK_DEV_PDC202XX_OLD=y
+# CONFIG_PDC202XX_BURST is not set
+CONFIG_BLK_DEV_PDC202XX_NEW=y
+CONFIG_BLK_DEV_SVWKS=y
+CONFIG_BLK_DEV_SIIMAGE=y
+CONFIG_BLK_DEV_SIS5513=y
+# CONFIG_BLK_DEV_SLC90E66 is not set
+# CONFIG_BLK_DEV_TRM290 is not set
+CONFIG_BLK_DEV_VIA82CXXX=y
+# CONFIG_IDE_ARM is not set
+CONFIG_BLK_DEV_IDEDMA=y
+# CONFIG_IDEDMA_IVB is not set
+CONFIG_IDEDMA_AUTO=y
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# SCSI device support
+#
+CONFIG_RAID_ATTRS=m
+CONFIG_SCSI=m
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=m
+CONFIG_CHR_DEV_ST=m
+CONFIG_CHR_DEV_OSST=m
+CONFIG_BLK_DEV_SR=m
+CONFIG_BLK_DEV_SR_VENDOR=y
+CONFIG_CHR_DEV_SG=m
+CONFIG_CHR_DEV_SCH=m
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+CONFIG_SCSI_MULTI_LUN=y
+CONFIG_SCSI_CONSTANTS=y
+CONFIG_SCSI_LOGGING=y
+
+#
+# SCSI Transport Attributes
+#
+CONFIG_SCSI_SPI_ATTRS=m
+CONFIG_SCSI_FC_ATTRS=m
+CONFIG_SCSI_ISCSI_ATTRS=m
+CONFIG_SCSI_SAS_ATTRS=m
+
+#
+# SCSI low-level drivers
+#
+CONFIG_ISCSI_TCP=m
+CONFIG_BLK_DEV_3W_XXXX_RAID=m
+CONFIG_SCSI_3W_9XXX=m
+CONFIG_SCSI_ACARD=m
+CONFIG_SCSI_AACRAID=m
+CONFIG_SCSI_AIC7XXX=m
+CONFIG_AIC7XXX_CMDS_PER_DEVICE=4
+CONFIG_AIC7XXX_RESET_DELAY_MS=15000
+# CONFIG_AIC7XXX_DEBUG_ENABLE is not set
+CONFIG_AIC7XXX_DEBUG_MASK=0
+# CONFIG_AIC7XXX_REG_PRETTY_PRINT is not set
+CONFIG_SCSI_AIC7XXX_OLD=m
+CONFIG_SCSI_AIC79XX=m
+CONFIG_AIC79XX_CMDS_PER_DEVICE=4
+CONFIG_AIC79XX_RESET_DELAY_MS=15000
+# CONFIG_AIC79XX_ENABLE_RD_STRM is not set
+# CONFIG_AIC79XX_DEBUG_ENABLE is not set
+CONFIG_AIC79XX_DEBUG_MASK=0
+# CONFIG_AIC79XX_REG_PRETTY_PRINT is not set
+CONFIG_MEGARAID_NEWGEN=y
+CONFIG_MEGARAID_MM=m
+CONFIG_MEGARAID_MAILBOX=m
+CONFIG_MEGARAID_LEGACY=m
+CONFIG_MEGARAID_SAS=m
+CONFIG_SCSI_SATA=m
+CONFIG_SCSI_SATA_AHCI=m
+CONFIG_SCSI_SATA_SVW=m
+CONFIG_SCSI_ATA_PIIX=m
+CONFIG_SCSI_SATA_MV=m
+CONFIG_SCSI_SATA_NV=m
+CONFIG_SCSI_PDC_ADMA=m
+CONFIG_SCSI_HPTIOP=m
+CONFIG_SCSI_SATA_QSTOR=m
+CONFIG_SCSI_SATA_PROMISE=m
+CONFIG_SCSI_SATA_SX4=m
+CONFIG_SCSI_SATA_SIL=m
+CONFIG_SCSI_SATA_SIL24=m
+CONFIG_SCSI_SATA_SIS=m
+CONFIG_SCSI_SATA_ULI=m
+CONFIG_SCSI_SATA_VIA=m
+CONFIG_SCSI_SATA_VITESSE=m
+CONFIG_SCSI_SATA_INTEL_COMBINED=y
+CONFIG_SCSI_BUSLOGIC=m
+# CONFIG_SCSI_OMIT_FLASHPOINT is not set
+# CONFIG_SCSI_DMX3191D is not set
+# CONFIG_SCSI_EATA is not set
+# CONFIG_SCSI_FUTURE_DOMAIN is not set
+CONFIG_SCSI_GDTH=m
+CONFIG_SCSI_IPS=m
+CONFIG_SCSI_INITIO=m
+CONFIG_SCSI_INIA100=m
+CONFIG_SCSI_PPA=m
+CONFIG_SCSI_IMM=m
+# CONFIG_SCSI_IZIP_EPP16 is not set
+# CONFIG_SCSI_IZIP_SLOW_CTR is not set
+CONFIG_SCSI_SYM53C8XX_2=m
+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_QLOGIC_1280=m
+CONFIG_SCSI_QLA_FC=m
+CONFIG_SCSI_LPFC=m
+CONFIG_SCSI_DC395x=m
+CONFIG_SCSI_DC390T=m
+# CONFIG_SCSI_DEBUG is not set
+
+#
+# PCMCIA SCSI adapter support
+#
+# CONFIG_PCMCIA_FDOMAIN is not set
+CONFIG_PCMCIA_QLOGIC=m
+CONFIG_PCMCIA_SYM53C500=m
+
+#
+# Multi-device support (RAID and LVM)
+#
+CONFIG_MD=y
+CONFIG_BLK_DEV_MD=y
+CONFIG_MD_LINEAR=m
+CONFIG_MD_RAID0=m
+CONFIG_MD_RAID1=m
+CONFIG_MD_RAID10=m
+CONFIG_MD_RAID456=m
+CONFIG_MD_RAID5_RESHAPE=y
+CONFIG_MD_MULTIPATH=m
+CONFIG_MD_FAULTY=m
+CONFIG_BLK_DEV_DM=m
+CONFIG_DM_CRYPT=m
+CONFIG_DM_SNAPSHOT=m
+CONFIG_DM_MIRROR=m
+CONFIG_DM_ZERO=m
+CONFIG_DM_MULTIPATH=m
+CONFIG_DM_MULTIPATH_EMC=m
+
+#
+# Fusion MPT device support
+#
+CONFIG_FUSION=y
+CONFIG_FUSION_SPI=m
+CONFIG_FUSION_FC=m
+CONFIG_FUSION_SAS=m
+CONFIG_FUSION_MAX_SGE=40
+CONFIG_FUSION_CTL=m
+CONFIG_FUSION_LAN=m
+
+#
+# IEEE 1394 (FireWire) support
+#
+CONFIG_IEEE1394=m
+
+#
+# Subsystem Options
+#
+# CONFIG_IEEE1394_VERBOSEDEBUG is not set
+CONFIG_IEEE1394_OUI_DB=y
+CONFIG_IEEE1394_EXTRA_CONFIG_ROMS=y
+CONFIG_IEEE1394_CONFIG_ROM_IP1394=y
+# CONFIG_IEEE1394_EXPORT_FULL_API is not set
+
+#
+# Device Drivers
+#
+CONFIG_IEEE1394_PCILYNX=m
+CONFIG_IEEE1394_OHCI1394=m
+
+#
+# Protocol Drivers
+#
+CONFIG_IEEE1394_VIDEO1394=m
+CONFIG_IEEE1394_SBP2=m
+CONFIG_IEEE1394_ETH1394=m
+CONFIG_IEEE1394_DV1394=m
+CONFIG_IEEE1394_RAWIO=m
+
+#
+# I2O device support
+#
+CONFIG_I2O=m
+# CONFIG_I2O_LCT_NOTIFY_ON_CHANGES is not set
+CONFIG_I2O_EXT_ADAPTEC=y
+CONFIG_I2O_EXT_ADAPTEC_DMA64=y
+CONFIG_I2O_CONFIG=m
+CONFIG_I2O_CONFIG_OLD_IOCTL=y
+CONFIG_I2O_BUS=m
+CONFIG_I2O_BLOCK=m
+CONFIG_I2O_SCSI=m
+CONFIG_I2O_PROC=m
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+CONFIG_IFB=m
+CONFIG_DUMMY=m
+CONFIG_BONDING=m
+CONFIG_EQUALIZER=m
+CONFIG_TUN=m
+CONFIG_NET_SB1000=m
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+
+#
+# PHY device support
+#
+CONFIG_PHYLIB=m
+
+#
+# MII PHY device drivers
+#
+CONFIG_MARVELL_PHY=m
+CONFIG_DAVICOM_PHY=m
+CONFIG_QSEMI_PHY=m
+CONFIG_LXT_PHY=m
+CONFIG_CICADA_PHY=m
+CONFIG_VITESSE_PHY=m
+CONFIG_SMSC_PHY=m
+CONFIG_FIXED_PHY=m
+CONFIG_FIXED_MII_10_FDX=y
+CONFIG_FIXED_MII_100_FDX=y
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=m
+CONFIG_HAPPYMEAL=m
+CONFIG_SUNGEM=m
+CONFIG_CASSINI=m
+CONFIG_NET_VENDOR_3COM=y
+CONFIG_VORTEX=m
+CONFIG_TYPHOON=m
+
+#
+# Tulip family network device support
+#
+CONFIG_NET_TULIP=y
+CONFIG_DE2104X=m
+CONFIG_TULIP=m
+# CONFIG_TULIP_MWI is not set
+CONFIG_TULIP_MMIO=y
+# CONFIG_TULIP_NAPI is not set
+CONFIG_DE4X5=m
+CONFIG_WINBOND_840=m
+CONFIG_DM9102=m
+CONFIG_ULI526X=m
+CONFIG_PCMCIA_XIRCOM=m
+# CONFIG_PCMCIA_XIRTULIP is not set
+# CONFIG_HP100 is not set
+CONFIG_NET_PCI=y
+CONFIG_PCNET32=m
+CONFIG_AMD8111_ETH=m
+CONFIG_AMD8111E_NAPI=y
+CONFIG_ADAPTEC_STARFIRE=m
+CONFIG_ADAPTEC_STARFIRE_NAPI=y
+CONFIG_B44=m
+CONFIG_FORCEDETH=m
+# CONFIG_DGRS is not set
+# CONFIG_EEPRO100 is not set
+CONFIG_E100=m
+CONFIG_FEALNX=m
+CONFIG_NATSEMI=m
+CONFIG_NE2K_PCI=m
+CONFIG_8139CP=m
+CONFIG_8139TOO=m
+# CONFIG_8139TOO_PIO is not set
+# CONFIG_8139TOO_TUNE_TWISTER is not set
+CONFIG_8139TOO_8129=y
+# CONFIG_8139_OLD_RX_RESET is not set
+CONFIG_SIS900=m
+CONFIG_EPIC100=m
+CONFIG_SUNDANCE=m
+# CONFIG_SUNDANCE_MMIO is not set
+CONFIG_VIA_RHINE=m
+CONFIG_VIA_RHINE_MMIO=y
+CONFIG_VIA_RHINE_NAPI=y
+CONFIG_NET_POCKET=y
+CONFIG_ATP=m
+CONFIG_DE600=m
+CONFIG_DE620=m
+
+#
+# Ethernet (1000 Mbit)
+#
+CONFIG_ACENIC=m
+# CONFIG_ACENIC_OMIT_TIGON_I is not set
+CONFIG_DL2K=m
+CONFIG_E1000=m
+CONFIG_E1000_NAPI=y
+# CONFIG_E1000_DISABLE_PACKET_SPLIT is not set
+CONFIG_NS83820=m
+CONFIG_HAMACHI=m
+CONFIG_YELLOWFIN=m
+CONFIG_R8169=m
+CONFIG_R8169_NAPI=y
+CONFIG_R8169_VLAN=y
+CONFIG_SIS190=m
+CONFIG_SKGE=m
+CONFIG_SKY2=m
+# CONFIG_SK98LIN is not set
+CONFIG_VIA_VELOCITY=m
+CONFIG_TIGON3=m
+CONFIG_BNX2=m
+
+#
+# Ethernet (10000 Mbit)
+#
+CONFIG_CHELSIO_T1=m
+CONFIG_IXGB=m
+CONFIG_IXGB_NAPI=y
+CONFIG_S2IO=m
+CONFIG_S2IO_NAPI=y
+CONFIG_MYRI10GE=m
+
+#
+# Token Ring devices
+#
+CONFIG_TR=y
+CONFIG_IBMOL=m
+CONFIG_3C359=m
+# CONFIG_TMS380TR is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+CONFIG_NET_RADIO=y
+CONFIG_NET_WIRELESS_RTNETLINK=y
+
+#
+# Obsolete Wireless cards support (pre-802.11)
+#
+# CONFIG_STRIP is not set
+CONFIG_PCMCIA_WAVELAN=m
+CONFIG_PCMCIA_NETWAVE=m
+
+#
+# Wireless 802.11 Frequency Hopping cards support
+#
+# CONFIG_PCMCIA_RAYCS is not set
+
+#
+# Wireless 802.11b ISA/PCI cards support
+#
+CONFIG_IPW2100=m
+CONFIG_IPW2100_MONITOR=y
+# CONFIG_IPW2100_DEBUG is not set
+CONFIG_IPW2200=m
+CONFIG_IPW2200_MONITOR=y
+CONFIG_IPW2200_RADIOTAP=y
+CONFIG_IPW2200_PROMISCUOUS=y
+CONFIG_IPW2200_QOS=y
+# CONFIG_IPW2200_DEBUG is not set
+CONFIG_AIRO=m
+CONFIG_HERMES=m
+CONFIG_PLX_HERMES=m
+CONFIG_TMD_HERMES=m
+CONFIG_NORTEL_HERMES=m
+CONFIG_PCI_HERMES=m
+CONFIG_ATMEL=m
+CONFIG_PCI_ATMEL=m
+
+#
+# Wireless 802.11b Pcmcia/Cardbus cards support
+#
+CONFIG_PCMCIA_HERMES=m
+CONFIG_PCMCIA_SPECTRUM=m
+CONFIG_AIRO_CS=m
+CONFIG_PCMCIA_ATMEL=m
+CONFIG_PCMCIA_WL3501=m
+
+#
+# Prism GT/Duette 802.11(a/b/g) PCI/Cardbus support
+#
+CONFIG_PRISM54=m
+CONFIG_USB_ZD1201=m
+CONFIG_HOSTAP=m
+CONFIG_HOSTAP_FIRMWARE=y
+CONFIG_HOSTAP_FIRMWARE_NVRAM=y
+CONFIG_HOSTAP_PLX=m
+CONFIG_HOSTAP_PCI=m
+CONFIG_HOSTAP_CS=m
+CONFIG_BCM43XX=m
+CONFIG_BCM43XX_DEBUG=y
+CONFIG_BCM43XX_DMA=y
+CONFIG_BCM43XX_PIO=y
+CONFIG_BCM43XX_DMA_AND_PIO_MODE=y
+# CONFIG_BCM43XX_DMA_MODE is not set
+# CONFIG_BCM43XX_PIO_MODE is not set
+CONFIG_ZD1211RW=m
+# CONFIG_ZD1211RW_DEBUG is not set
+CONFIG_NET_WIRELESS=y
+
+#
+# PCMCIA network device support
+#
+CONFIG_NET_PCMCIA=y
+CONFIG_PCMCIA_3C589=m
+CONFIG_PCMCIA_3C574=m
+CONFIG_PCMCIA_FMVJ18X=m
+CONFIG_PCMCIA_PCNET=m
+CONFIG_PCMCIA_NMCLAN=m
+CONFIG_PCMCIA_SMC91C92=m
+CONFIG_PCMCIA_XIRC2PS=m
+CONFIG_PCMCIA_AXNET=m
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+
+#
+# ATM drivers
+#
+# CONFIG_ATM_DUMMY is not set
+CONFIG_ATM_TCP=m
+CONFIG_ATM_LANAI=m
+CONFIG_ATM_ENI=m
+# CONFIG_ATM_ENI_DEBUG is not set
+# CONFIG_ATM_ENI_TUNE_BURST is not set
+CONFIG_ATM_FIRESTREAM=m
+# CONFIG_ATM_ZATM is not set
+CONFIG_ATM_IDT77252=m
+# CONFIG_ATM_IDT77252_DEBUG is not set
+# CONFIG_ATM_IDT77252_RCV_ALL is not set
+CONFIG_ATM_IDT77252_USE_SUNI=y
+CONFIG_ATM_AMBASSADOR=m
+# CONFIG_ATM_AMBASSADOR_DEBUG is not set
+CONFIG_ATM_HORIZON=m
+# CONFIG_ATM_HORIZON_DEBUG is not set
+CONFIG_ATM_FORE200E_MAYBE=m
+# CONFIG_ATM_FORE200E_PCA is not set
+CONFIG_ATM_HE=m
+# CONFIG_ATM_HE_USE_SUNI is not set
+CONFIG_FDDI=y
+# CONFIG_DEFXX is not set
+CONFIG_SKFP=m
+# CONFIG_HIPPI is not set
+CONFIG_PLIP=m
+CONFIG_PPP=m
+CONFIG_PPP_MULTILINK=y
+CONFIG_PPP_FILTER=y
+CONFIG_PPP_ASYNC=m
+CONFIG_PPP_SYNC_TTY=m
+CONFIG_PPP_DEFLATE=m
+# CONFIG_PPP_BSDCOMP is not set
+CONFIG_PPP_MPPE=m
+CONFIG_PPPOE=m
+CONFIG_PPPOATM=m
+CONFIG_SLIP=m
+CONFIG_SLIP_COMPRESSED=y
+CONFIG_SLIP_SMART=y
+# CONFIG_SLIP_MODE_SLIP6 is not set
+CONFIG_NET_FC=y
+# CONFIG_SHAPER is not set
+CONFIG_NETCONSOLE=m
+CONFIG_NETPOLL=y
+# CONFIG_NETPOLL_RX is not set
+CONFIG_NETPOLL_TRAP=y
+CONFIG_NET_POLL_CONTROLLER=y
+
+#
+# ISDN subsystem
+#
+CONFIG_ISDN=m
+
+#
+# Old ISDN4Linux
+#
+CONFIG_ISDN_I4L=m
+CONFIG_ISDN_PPP=y
+CONFIG_ISDN_PPP_VJ=y
+CONFIG_ISDN_MPP=y
+CONFIG_IPPP_FILTER=y
+# CONFIG_ISDN_PPP_BSDCOMP is not set
+CONFIG_ISDN_AUDIO=y
+CONFIG_ISDN_TTY_FAX=y
+
+#
+# ISDN feature submodules
+#
+CONFIG_ISDN_DRV_LOOP=m
+CONFIG_ISDN_DIVERSION=m
+
+#
+# ISDN4Linux hardware drivers
+#
+
+#
+# Passive cards
+#
+CONFIG_ISDN_DRV_HISAX=m
+
+#
+# D-channel protocol features
+#
+CONFIG_HISAX_EURO=y
+CONFIG_DE_AOC=y
+CONFIG_HISAX_NO_SENDCOMPLETE=y
+CONFIG_HISAX_NO_LLC=y
+CONFIG_HISAX_NO_KEYPAD=y
+CONFIG_HISAX_1TR6=y
+CONFIG_HISAX_NI1=y
+CONFIG_HISAX_MAX_CARDS=8
+
+#
+# HiSax supported cards
+#
+CONFIG_HISAX_16_3=y
+CONFIG_HISAX_TELESPCI=y
+CONFIG_HISAX_S0BOX=y
+CONFIG_HISAX_FRITZPCI=y
+CONFIG_HISAX_AVM_A1_PCMCIA=y
+CONFIG_HISAX_ELSA=y
+CONFIG_HISAX_DIEHLDIVA=y
+CONFIG_HISAX_SEDLBAUER=y
+CONFIG_HISAX_NETJET=y
+CONFIG_HISAX_NETJET_U=y
+CONFIG_HISAX_NICCY=y
+CONFIG_HISAX_BKM_A4T=y
+CONFIG_HISAX_SCT_QUADRO=y
+CONFIG_HISAX_GAZEL=y
+CONFIG_HISAX_HFC_PCI=y
+CONFIG_HISAX_W6692=y
+CONFIG_HISAX_HFC_SX=y
+CONFIG_HISAX_ENTERNOW_PCI=y
+# CONFIG_HISAX_DEBUG is not set
+
+#
+# HiSax PCMCIA card service modules
+#
+CONFIG_HISAX_SEDLBAUER_CS=m
+CONFIG_HISAX_ELSA_CS=m
+CONFIG_HISAX_AVM_A1_CS=m
+CONFIG_HISAX_TELES_CS=m
+
+#
+# HiSax sub driver modules
+#
+CONFIG_HISAX_ST5481=m
+# CONFIG_HISAX_HFCUSB is not set
+CONFIG_HISAX_HFC4S8S=m
+CONFIG_HISAX_FRITZ_PCIPNP=m
+CONFIG_HISAX_HDLC=y
+
+#
+# Active cards
+#
+CONFIG_HYSDN=m
+CONFIG_HYSDN_CAPI=y
+
+#
+# Siemens Gigaset
+#
+CONFIG_ISDN_DRV_GIGASET=m
+CONFIG_GIGASET_BASE=m
+CONFIG_GIGASET_M105=m
+# CONFIG_GIGASET_DEBUG is not set
+# CONFIG_GIGASET_UNDOCREQ is not set
+
+#
+# CAPI subsystem
+#
+CONFIG_ISDN_CAPI=m
+CONFIG_ISDN_DRV_AVMB1_VERBOSE_REASON=y
+CONFIG_ISDN_CAPI_MIDDLEWARE=y
+CONFIG_ISDN_CAPI_CAPI20=m
+CONFIG_ISDN_CAPI_CAPIFS_BOOL=y
+CONFIG_ISDN_CAPI_CAPIFS=m
+CONFIG_ISDN_CAPI_CAPIDRV=m
+
+#
+# CAPI hardware drivers
+#
+
+#
+# Active AVM cards
+#
+CONFIG_CAPI_AVM=y
+CONFIG_ISDN_DRV_AVMB1_B1PCI=m
+CONFIG_ISDN_DRV_AVMB1_B1PCIV4=y
+CONFIG_ISDN_DRV_AVMB1_B1PCMCIA=m
+CONFIG_ISDN_DRV_AVMB1_AVM_CS=m
+CONFIG_ISDN_DRV_AVMB1_T1PCI=m
+CONFIG_ISDN_DRV_AVMB1_C4=m
+
+#
+# Active Eicon DIVA Server cards
+#
+# CONFIG_CAPI_EICON is not set
+
+#
+# Telephony Support
+#
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+
+#
+# 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=m
+# CONFIG_INPUT_TSDEV is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+CONFIG_KEYBOARD_ATKBD=y
+# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_KEYBOARD_LKKBD is not set
+# CONFIG_KEYBOARD_XTKBD is not set
+# CONFIG_KEYBOARD_NEWTON is not set
+CONFIG_INPUT_MOUSE=y
+CONFIG_MOUSE_PS2=y
+CONFIG_MOUSE_SERIAL=m
+CONFIG_MOUSE_VSXXXAA=m
+CONFIG_INPUT_JOYSTICK=y
+CONFIG_JOYSTICK_ANALOG=m
+CONFIG_JOYSTICK_A3D=m
+CONFIG_JOYSTICK_ADI=m
+CONFIG_JOYSTICK_COBRA=m
+CONFIG_JOYSTICK_GF2K=m
+CONFIG_JOYSTICK_GRIP=m
+CONFIG_JOYSTICK_GRIP_MP=m
+CONFIG_JOYSTICK_GUILLEMOT=m
+CONFIG_JOYSTICK_INTERACT=m
+CONFIG_JOYSTICK_SIDEWINDER=m
+CONFIG_JOYSTICK_TMDC=m
+CONFIG_JOYSTICK_IFORCE=m
+CONFIG_JOYSTICK_IFORCE_USB=y
+CONFIG_JOYSTICK_IFORCE_232=y
+CONFIG_JOYSTICK_WARRIOR=m
+CONFIG_JOYSTICK_MAGELLAN=m
+CONFIG_JOYSTICK_SPACEORB=m
+CONFIG_JOYSTICK_SPACEBALL=m
+CONFIG_JOYSTICK_STINGER=m
+CONFIG_JOYSTICK_TWIDJOY=m
+CONFIG_JOYSTICK_DB9=m
+CONFIG_JOYSTICK_GAMECON=m
+CONFIG_JOYSTICK_TURBOGRAFX=m
+CONFIG_JOYSTICK_JOYDUMP=m
+CONFIG_INPUT_TOUCHSCREEN=y
+CONFIG_TOUCHSCREEN_GUNZE=m
+CONFIG_TOUCHSCREEN_ELO=m
+CONFIG_TOUCHSCREEN_MTOUCH=m
+CONFIG_TOUCHSCREEN_MK712=m
+CONFIG_INPUT_MISC=y
+CONFIG_INPUT_PCSPKR=m
+CONFIG_INPUT_UINPUT=m
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+CONFIG_SERIO_I8042=y
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_CT82C710 is not set
+# CONFIG_SERIO_PARKBD is not set
+# CONFIG_SERIO_PCIPS2 is not set
+CONFIG_SERIO_LIBPS2=y
+CONFIG_SERIO_RAW=m
+CONFIG_GAMEPORT=m
+CONFIG_GAMEPORT_NS558=m
+CONFIG_GAMEPORT_L4=m
+CONFIG_GAMEPORT_EMU10K1=m
+CONFIG_GAMEPORT_FM801=m
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+CONFIG_VT_HW_CONSOLE_BINDING=y
+CONFIG_SERIAL_NONSTANDARD=y
+# CONFIG_COMPUTONE is not set
+# CONFIG_ROCKETPORT is not set
+CONFIG_CYCLADES=m
+# CONFIG_CYZ_INTR is not set
+# CONFIG_DIGIEPCA is not set
+# CONFIG_MOXA_INTELLIO is not set
+# CONFIG_MOXA_SMARTIO is not set
+# CONFIG_ISI is not set
+CONFIG_SYNCLINK=m
+CONFIG_SYNCLINKMP=m
+CONFIG_SYNCLINK_GT=m
+CONFIG_N_HDLC=m
+# CONFIG_RISCOM8 is not set
+# CONFIG_SPECIALIX is not set
+# CONFIG_SX is not set
+# CONFIG_RIO is not set
+# CONFIG_STALDRV is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_PCI=y
+CONFIG_SERIAL_8250_PNP=y
+CONFIG_SERIAL_8250_CS=m
+CONFIG_SERIAL_8250_NR_UARTS=32
+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=y
+CONFIG_SERIAL_8250_RSA=y
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_SERIAL_JSM=m
+CONFIG_UNIX98_PTYS=y
+# CONFIG_LEGACY_PTYS is not set
+CONFIG_CRASH=m
+CONFIG_PRINTER=m
+CONFIG_LP_CONSOLE=y
+CONFIG_PPDEV=m
+CONFIG_TIPAR=m
+
+#
+# IPMI
+#
+CONFIG_IPMI_HANDLER=m
+# CONFIG_IPMI_PANIC_EVENT is not set
+CONFIG_IPMI_DEVICE_INTERFACE=m
+CONFIG_IPMI_SI=m
+CONFIG_IPMI_WATCHDOG=m
+CONFIG_IPMI_POWEROFF=m
+
+#
+# Watchdog Cards
+#
+CONFIG_WATCHDOG=y
+# CONFIG_WATCHDOG_NOWAYOUT is not set
+
+#
+# Watchdog Device Drivers
+#
+CONFIG_SOFT_WATCHDOG=m
+# CONFIG_ACQUIRE_WDT is not set
+# CONFIG_ADVANTECH_WDT is not set
+CONFIG_ALIM1535_WDT=m
+CONFIG_ALIM7101_WDT=m
+# CONFIG_SC520_WDT is not set
+# CONFIG_EUROTECH_WDT is not set
+# CONFIG_IB700_WDT is not set
+CONFIG_IBMASR=m
+# CONFIG_WAFER_WDT is not set
+CONFIG_I6300ESB_WDT=m
+CONFIG_I8XX_TCO=m
+# CONFIG_SC1200_WDT is not set
+# CONFIG_60XX_WDT is not set
+# CONFIG_SBC8360_WDT is not set
+# CONFIG_CPU5_WDT is not set
+CONFIG_W83627HF_WDT=m
+CONFIG_W83877F_WDT=m
+CONFIG_W83977F_WDT=m
+CONFIG_MACHZ_WDT=m
+# CONFIG_SBC_EPX_C3_WATCHDOG is not set
+
+#
+# PCI-based Watchdog Cards
+#
+CONFIG_PCIPCWATCHDOG=m
+CONFIG_WDTPCI=m
+CONFIG_WDT_501_PCI=y
+
+#
+# USB-based Watchdog Cards
+#
+CONFIG_USBPCWATCHDOG=m
+CONFIG_HW_RANDOM=y
+CONFIG_HW_RANDOM_INTEL=m
+CONFIG_HW_RANDOM_AMD=m
+# CONFIG_HW_RANDOM_GEODE is not set
+CONFIG_NVRAM=y
+CONFIG_RTC=y
+CONFIG_DTLK=m
+CONFIG_R3964=m
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_FTAPE is not set
+CONFIG_AGP=y
+CONFIG_AGP_AMD64=y
+CONFIG_AGP_INTEL=y
+CONFIG_AGP_SIS=y
+CONFIG_AGP_VIA=y
+CONFIG_DRM=m
+CONFIG_DRM_TDFX=m
+CONFIG_DRM_R128=m
+CONFIG_DRM_RADEON=m
+CONFIG_DRM_I810=m
+CONFIG_DRM_I830=m
+CONFIG_DRM_I915=m
+CONFIG_DRM_MGA=m
+CONFIG_DRM_SIS=m
+CONFIG_DRM_VIA=m
+CONFIG_DRM_SAVAGE=m
+
+#
+# PCMCIA character devices
+#
+# CONFIG_SYNCLINK_CS is not set
+CONFIG_CARDMAN_4000=m
+CONFIG_CARDMAN_4040=m
+CONFIG_MWAVE=m
+CONFIG_PC8736x_GPIO=m
+CONFIG_NSC_GPIO=m
+# CONFIG_RAW_DRIVER is not set
+CONFIG_HPET=y
+# CONFIG_HPET_RTC_IRQ is not set
+# CONFIG_HPET_MMAP is not set
+CONFIG_HANGCHECK_TIMER=m
+
+#
+# TPM devices
+#
+CONFIG_TCG_TPM=m
+CONFIG_TCG_TIS=m
+CONFIG_TCG_NSC=m
+CONFIG_TCG_ATMEL=m
+CONFIG_TCG_INFINEON=m
+# CONFIG_TELCLOCK is not set
+
+#
+# I2C support
+#
+CONFIG_I2C=m
+CONFIG_I2C_CHARDEV=m
+
+#
+# I2C Algorithms
+#
+CONFIG_I2C_ALGOBIT=m
+CONFIG_I2C_ALGOPCF=m
+CONFIG_I2C_ALGOPCA=m
+
+#
+# I2C Hardware Bus support
+#
+# CONFIG_I2C_ALI1535 is not set
+# CONFIG_I2C_ALI1563 is not set
+# CONFIG_I2C_ALI15X3 is not set
+CONFIG_I2C_AMD756=m
+CONFIG_I2C_AMD756_S4882=m
+CONFIG_I2C_AMD8111=m
+CONFIG_I2C_I801=m
+# CONFIG_I2C_I810 is not set
+# CONFIG_I2C_PIIX4 is not set
+CONFIG_I2C_ISA=m
+CONFIG_I2C_NFORCE2=m
+# CONFIG_I2C_OCORES is not set
+CONFIG_I2C_PARPORT=m
+CONFIG_I2C_PARPORT_LIGHT=m
+CONFIG_I2C_PROSAVAGE=m
+CONFIG_I2C_SAVAGE4=m
+# CONFIG_I2C_SIS5595 is not set
+# CONFIG_I2C_SIS630 is not set
+CONFIG_I2C_SIS96X=m
+CONFIG_I2C_STUB=m
+CONFIG_I2C_VIA=m
+CONFIG_I2C_VIAPRO=m
+CONFIG_I2C_VOODOO3=m
+CONFIG_I2C_PCA_ISA=m
+
+#
+# Miscellaneous I2C Chip support
+#
+CONFIG_SENSORS_DS1337=m
+CONFIG_SENSORS_DS1374=m
+CONFIG_SENSORS_EEPROM=m
+CONFIG_SENSORS_PCF8574=m
+CONFIG_SENSORS_PCA9539=m
+CONFIG_SENSORS_PCF8591=m
+CONFIG_SENSORS_MAX6875=m
+# 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 is not set
+# CONFIG_SPI_MASTER is not set
+
+#
+# Dallas's 1-wire bus
+#
+CONFIG_W1=m
+CONFIG_W1_CON=y
+
+#
+# 1-wire Bus Masters
+#
+CONFIG_W1_MASTER_MATROX=m
+CONFIG_W1_MASTER_DS2490=m
+CONFIG_W1_MASTER_DS2482=m
+
+#
+# 1-wire Slaves
+#
+CONFIG_W1_SLAVE_THERM=m
+CONFIG_W1_SLAVE_SMEM=m
+CONFIG_W1_SLAVE_DS2433=m
+CONFIG_W1_SLAVE_DS2433_CRC=y
+
+#
+# Hardware Monitoring support
+#
+CONFIG_HWMON=m
+CONFIG_HWMON_VID=m
+CONFIG_SENSORS_ABITUGURU=m
+CONFIG_SENSORS_ADM1021=m
+CONFIG_SENSORS_ADM1025=m
+CONFIG_SENSORS_ADM1026=m
+CONFIG_SENSORS_ADM1031=m
+CONFIG_SENSORS_ADM9240=m
+CONFIG_SENSORS_ASB100=m
+CONFIG_SENSORS_ATXP1=m
+CONFIG_SENSORS_DS1621=m
+CONFIG_SENSORS_F71805F=m
+CONFIG_SENSORS_FSCHER=m
+CONFIG_SENSORS_FSCPOS=m
+CONFIG_SENSORS_GL518SM=m
+CONFIG_SENSORS_GL520SM=m
+CONFIG_SENSORS_IT87=m
+CONFIG_SENSORS_LM63=m
+CONFIG_SENSORS_LM75=m
+CONFIG_SENSORS_LM77=m
+CONFIG_SENSORS_LM78=m
+CONFIG_SENSORS_LM80=m
+CONFIG_SENSORS_LM83=m
+CONFIG_SENSORS_LM85=m
+CONFIG_SENSORS_LM87=m
+CONFIG_SENSORS_LM90=m
+CONFIG_SENSORS_LM92=m
+CONFIG_SENSORS_MAX1619=m
+CONFIG_SENSORS_PC87360=m
+CONFIG_SENSORS_SIS5595=m
+CONFIG_SENSORS_SMSC47M1=m
+CONFIG_SENSORS_SMSC47M192=m
+CONFIG_SENSORS_SMSC47B397=m
+CONFIG_SENSORS_VIA686A=m
+CONFIG_SENSORS_VT8231=m
+CONFIG_SENSORS_W83781D=m
+CONFIG_SENSORS_W83791D=m
+CONFIG_SENSORS_W83792D=m
+CONFIG_SENSORS_W83L785TS=m
+CONFIG_SENSORS_W83627HF=m
+CONFIG_SENSORS_W83627EHF=m
+CONFIG_SENSORS_HDAPS=m
+# CONFIG_HWMON_DEBUG_CHIP is not set
+
+#
+# Misc devices
+#
+# CONFIG_IBM_ASM is not set
+
+#
+# Multimedia devices
+#
+CONFIG_VIDEO_DEV=m
+CONFIG_VIDEO_V4L1=y
+CONFIG_VIDEO_V4L1_COMPAT=y
+CONFIG_VIDEO_V4L2=y
+
+#
+# Video Capture Adapters
+#
+
+#
+# Video Capture Adapters
+#
+# CONFIG_VIDEO_ADV_DEBUG is not set
+# CONFIG_VIDEO_VIVI is not set
+CONFIG_VIDEO_BT848=m
+CONFIG_VIDEO_BT848_DVB=y
+CONFIG_VIDEO_SAA6588=m
+CONFIG_VIDEO_BWQCAM=m
+CONFIG_VIDEO_CQCAM=m
+CONFIG_VIDEO_W9966=m
+CONFIG_VIDEO_CPIA=m
+CONFIG_VIDEO_CPIA_PP=m
+CONFIG_VIDEO_CPIA_USB=m
+CONFIG_VIDEO_CPIA2=m
+CONFIG_VIDEO_SAA5246A=m
+CONFIG_VIDEO_SAA5249=m
+CONFIG_TUNER_3036=m
+CONFIG_VIDEO_STRADIS=m
+CONFIG_VIDEO_ZORAN=m
+CONFIG_VIDEO_ZORAN_BUZ=m
+CONFIG_VIDEO_ZORAN_DC10=m
+CONFIG_VIDEO_ZORAN_DC30=m
+CONFIG_VIDEO_ZORAN_LML33=m
+CONFIG_VIDEO_ZORAN_LML33R10=m
+CONFIG_VIDEO_ZORAN_AVS6EYES=m
+CONFIG_VIDEO_SAA7134=m
+CONFIG_VIDEO_SAA7134_ALSA=m
+CONFIG_VIDEO_SAA7134_DVB=m
+CONFIG_VIDEO_SAA7134_DVB_ALL_FRONTENDS=y
+CONFIG_VIDEO_MXB=m
+CONFIG_VIDEO_DPC=m
+CONFIG_VIDEO_HEXIUM_ORION=m
+CONFIG_VIDEO_HEXIUM_GEMINI=m
+CONFIG_VIDEO_CX88_VP3054=m
+CONFIG_VIDEO_CX88=m
+CONFIG_VIDEO_CX88_ALSA=m
+CONFIG_VIDEO_CX88_BLACKBIRD=m
+CONFIG_VIDEO_CX88_DVB=m
+CONFIG_VIDEO_CX88_DVB_ALL_FRONTENDS=y
+
+#
+# Encoders and Decoders
+#
+CONFIG_VIDEO_MSP3400=m
+CONFIG_VIDEO_CS53L32A=m
+CONFIG_VIDEO_TLV320AIC23B=m
+CONFIG_VIDEO_WM8775=m
+CONFIG_VIDEO_WM8739=m
+CONFIG_VIDEO_CX2341X=m
+CONFIG_VIDEO_CX25840=m
+CONFIG_VIDEO_SAA711X=m
+CONFIG_VIDEO_SAA7127=m
+CONFIG_VIDEO_UPD64031A=m
+CONFIG_VIDEO_UPD64083=m
+
+#
+# V4L USB devices
+#
+CONFIG_VIDEO_PVRUSB2=m
+CONFIG_VIDEO_PVRUSB2_24XXX=y
+CONFIG_VIDEO_PVRUSB2_SYSFS=y
+# CONFIG_VIDEO_PVRUSB2_DEBUGIFC is not set
+CONFIG_VIDEO_EM28XX=m
+CONFIG_VIDEO_USBVIDEO=m
+CONFIG_USB_VICAM=m
+CONFIG_USB_IBMCAM=m
+CONFIG_USB_KONICAWC=m
+CONFIG_USB_QUICKCAM_MESSENGER=m
+CONFIG_USB_ET61X251=m
+CONFIG_VIDEO_OVCAMCHIP=m
+CONFIG_USB_W9968CF=m
+CONFIG_USB_OV511=m
+CONFIG_USB_SE401=m
+CONFIG_USB_SN9C102=m
+CONFIG_USB_STV680=m
+CONFIG_USB_ZC0301=m
+CONFIG_USB_PWC=m
+# CONFIG_USB_PWC_DEBUG is not set
+
+#
+# Radio Adapters
+#
+CONFIG_RADIO_GEMTEK_PCI=m
+CONFIG_RADIO_MAXIRADIO=m
+CONFIG_RADIO_MAESTRO=m
+CONFIG_USB_DSBR=m
+
+#
+# Digital Video Broadcasting Devices
+#
+CONFIG_DVB=y
+CONFIG_DVB_CORE=m
+
+#
+# Supported SAA7146 based PCI Adapters
+#
+CONFIG_DVB_AV7110=m
+CONFIG_DVB_AV7110_OSD=y
+CONFIG_DVB_BUDGET=m
+CONFIG_DVB_BUDGET_CI=m
+CONFIG_DVB_BUDGET_AV=m
+CONFIG_DVB_BUDGET_PATCH=m
+
+#
+# Supported USB Adapters
+#
+CONFIG_DVB_USB=m
+# CONFIG_DVB_USB_DEBUG is not set
+CONFIG_DVB_USB_A800=m
+CONFIG_DVB_USB_DIBUSB_MB=m
+# CONFIG_DVB_USB_DIBUSB_MB_FAULTY is not set
+CONFIG_DVB_USB_DIBUSB_MC=m
+CONFIG_DVB_USB_UMT_010=m
+CONFIG_DVB_USB_CXUSB=m
+CONFIG_DVB_USB_DIGITV=m
+CONFIG_DVB_USB_VP7045=m
+CONFIG_DVB_USB_VP702X=m
+CONFIG_DVB_USB_GP8PSK=m
+CONFIG_DVB_USB_NOVA_T_USB2=m
+CONFIG_DVB_USB_DTT200U=m
+CONFIG_DVB_TTUSB_BUDGET=m
+CONFIG_DVB_TTUSB_DEC=m
+CONFIG_DVB_CINERGYT2=m
+CONFIG_DVB_CINERGYT2_TUNING=y
+CONFIG_DVB_CINERGYT2_STREAM_URB_COUNT=32
+CONFIG_DVB_CINERGYT2_STREAM_BUF_SIZE=512
+CONFIG_DVB_CINERGYT2_QUERY_INTERVAL=250
+CONFIG_DVB_CINERGYT2_ENABLE_RC_INPUT_DEVICE=y
+CONFIG_DVB_CINERGYT2_RC_QUERY_INTERVAL=100
+
+#
+# Supported FlexCopII (B2C2) Adapters
+#
+CONFIG_DVB_B2C2_FLEXCOP=m
+CONFIG_DVB_B2C2_FLEXCOP_PCI=m
+CONFIG_DVB_B2C2_FLEXCOP_USB=m
+# CONFIG_DVB_B2C2_FLEXCOP_DEBUG is not set
+
+#
+# Supported BT878 Adapters
+#
+CONFIG_DVB_BT8XX=m
+
+#
+# Supported Pluto2 Adapters
+#
+CONFIG_DVB_PLUTO2=m
+
+#
+# Supported DVB Frontends
+#
+
+#
+# Customise DVB Frontends
+#
+
+#
+# DVB-S (satellite) frontends
+#
+CONFIG_DVB_STV0299=m
+CONFIG_DVB_CX24110=m
+CONFIG_DVB_CX24123=m
+CONFIG_DVB_TDA8083=m
+CONFIG_DVB_MT312=m
+CONFIG_DVB_VES1X93=m
+CONFIG_DVB_S5H1420=m
+
+#
+# DVB-T (terrestrial) frontends
+#
+CONFIG_DVB_SP8870=m
+CONFIG_DVB_SP887X=m
+CONFIG_DVB_CX22700=m
+CONFIG_DVB_CX22702=m
+CONFIG_DVB_L64781=m
+CONFIG_DVB_TDA1004X=m
+CONFIG_DVB_NXT6000=m
+CONFIG_DVB_MT352=m
+CONFIG_DVB_ZL10353=m
+CONFIG_DVB_DIB3000MB=m
+CONFIG_DVB_DIB3000MC=m
+
+#
+# DVB-C (cable) frontends
+#
+CONFIG_DVB_VES1820=m
+CONFIG_DVB_TDA10021=m
+CONFIG_DVB_STV0297=m
+
+#
+# ATSC (North American/Korean Terrestrial/Cable DTV) frontends
+#
+CONFIG_DVB_NXT200X=m
+CONFIG_DVB_OR51211=m
+CONFIG_DVB_OR51132=m
+CONFIG_DVB_BCM3510=m
+CONFIG_DVB_LGDT330X=m
+
+#
+# Miscellaneous devices
+#
+CONFIG_DVB_PLL=m
+CONFIG_DVB_LNBP21=m
+CONFIG_DVB_ISL6421=m
+CONFIG_VIDEO_SAA7146=m
+CONFIG_VIDEO_SAA7146_VV=m
+CONFIG_VIDEO_VIDEOBUF=m
+CONFIG_VIDEO_TUNER=m
+CONFIG_VIDEO_BUF=m
+CONFIG_VIDEO_BUF_DVB=m
+CONFIG_VIDEO_BTCX=m
+CONFIG_VIDEO_IR=m
+CONFIG_VIDEO_TVEEPROM=m
+CONFIG_USB_DABUSB=m
+
+#
+# Graphics support
+#
+# CONFIG_FIRMWARE_EDID is not set
+CONFIG_FB=y
+CONFIG_FB_CFB_FILLRECT=y
+CONFIG_FB_CFB_COPYAREA=y
+CONFIG_FB_CFB_IMAGEBLIT=y
+# CONFIG_FB_MACMODES is not set
+# CONFIG_FB_BACKLIGHT is not set
+CONFIG_FB_MODE_HELPERS=y
+CONFIG_FB_TILEBLITTING=y
+CONFIG_FB_CIRRUS=m
+# CONFIG_FB_PM2 is not set
+# CONFIG_FB_CYBER2000 is not set
+# CONFIG_FB_ARC is not set
+# CONFIG_FB_ASILIANT is not set
+# CONFIG_FB_IMSTT is not set
+CONFIG_FB_VGA16=m
+CONFIG_FB_VESA=y
+# CONFIG_FB_HGA is not set
+# CONFIG_FB_S1D13XXX is not set
+CONFIG_FB_NVIDIA=m
+CONFIG_FB_NVIDIA_I2C=y
+CONFIG_FB_RIVA=m
+# CONFIG_FB_RIVA_I2C is not set
+# CONFIG_FB_RIVA_DEBUG is not set
+CONFIG_FB_INTEL=m
+# CONFIG_FB_INTEL_DEBUG is not set
+CONFIG_FB_MATROX=m
+CONFIG_FB_MATROX_MILLENIUM=y
+CONFIG_FB_MATROX_MYSTIQUE=y
+CONFIG_FB_MATROX_G=y
+CONFIG_FB_MATROX_I2C=m
+CONFIG_FB_MATROX_MAVEN=m
+CONFIG_FB_MATROX_MULTIHEAD=y
+CONFIG_FB_RADEON=m
+CONFIG_FB_RADEON_I2C=y
+# CONFIG_FB_RADEON_DEBUG is not set
+CONFIG_FB_ATY128=m
+CONFIG_FB_ATY=m
+CONFIG_FB_ATY_CT=y
+CONFIG_FB_ATY_GENERIC_LCD=y
+CONFIG_FB_ATY_GX=y
+CONFIG_FB_SAVAGE=m
+CONFIG_FB_SAVAGE_I2C=y
+CONFIG_FB_SAVAGE_ACCEL=y
+# CONFIG_FB_SIS is not set
+CONFIG_FB_NEOMAGIC=m
+CONFIG_FB_KYRO=m
+CONFIG_FB_3DFX=m
+CONFIG_FB_3DFX_ACCEL=y
+CONFIG_FB_VOODOO1=m
+CONFIG_FB_TRIDENT=m
+CONFIG_FB_TRIDENT_ACCEL=y
+# CONFIG_FB_GEODE is not set
+# CONFIG_FB_VIRTUAL is not set
+
+#
+# Console display driver support
+#
+CONFIG_VGA_CONSOLE=y
+CONFIG_VGACON_SOFT_SCROLLBACK=y
+CONFIG_VGACON_SOFT_SCROLLBACK_SIZE=64
+CONFIG_VIDEO_SELECT=y
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y
+# CONFIG_FONTS is not set
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
+
+#
+# Logo configuration
+#
+CONFIG_LOGO=y
+# CONFIG_LOGO_LINUX_MONO is not set
+# CONFIG_LOGO_LINUX_VGA16 is not set
+CONFIG_LOGO_LINUX_CLUT224=y
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+CONFIG_BACKLIGHT_CLASS_DEVICE=m
+CONFIG_BACKLIGHT_DEVICE=y
+CONFIG_LCD_CLASS_DEVICE=m
+CONFIG_LCD_DEVICE=y
+
+#
+# Sound
+#
+CONFIG_SOUND=m
+
+#
+# Advanced Linux Sound Architecture
+#
+CONFIG_SND=m
+CONFIG_SND_TIMER=m
+CONFIG_SND_PCM=m
+CONFIG_SND_HWDEP=m
+CONFIG_SND_RAWMIDI=m
+CONFIG_SND_SEQUENCER=m
+CONFIG_SND_SEQ_DUMMY=m
+CONFIG_SND_OSSEMUL=y
+CONFIG_SND_MIXER_OSS=m
+CONFIG_SND_PCM_OSS=m
+CONFIG_SND_PCM_OSS_PLUGINS=y
+CONFIG_SND_SEQUENCER_OSS=y
+CONFIG_SND_RTCTIMER=m
+CONFIG_SND_SEQ_RTCTIMER_DEFAULT=y
+CONFIG_SND_DYNAMIC_MINORS=y
+# CONFIG_SND_SUPPORT_OLD_API is not set
+CONFIG_SND_VERBOSE_PROCFS=y
+# CONFIG_SND_VERBOSE_PRINTK is not set
+# CONFIG_SND_DEBUG is not set
+
+#
+# Generic devices
+#
+CONFIG_SND_MPU401_UART=m
+CONFIG_SND_OPL3_LIB=m
+CONFIG_SND_VX_LIB=m
+CONFIG_SND_AC97_CODEC=m
+CONFIG_SND_AC97_BUS=m
+CONFIG_SND_DUMMY=m
+CONFIG_SND_VIRMIDI=m
+CONFIG_SND_MTPAV=m
+# CONFIG_SND_SERIAL_U16550 is not set
+CONFIG_SND_MPU401=m
+
+#
+# PCI devices
+#
+CONFIG_SND_AD1889=m
+CONFIG_SND_ALS300=m
+CONFIG_SND_ALS4000=m
+CONFIG_SND_ALI5451=m
+CONFIG_SND_ATIIXP=m
+CONFIG_SND_ATIIXP_MODEM=m
+CONFIG_SND_AU8810=m
+CONFIG_SND_AU8820=m
+CONFIG_SND_AU8830=m
+CONFIG_SND_AZT3328=m
+CONFIG_SND_BT87X=m
+# CONFIG_SND_BT87X_OVERCLOCK is not set
+CONFIG_SND_CA0106=m
+CONFIG_SND_CMIPCI=m
+CONFIG_SND_CS4281=m
+CONFIG_SND_CS46XX=m
+CONFIG_SND_CS46XX_NEW_DSP=y
+CONFIG_SND_DARLA20=m
+CONFIG_SND_GINA20=m
+CONFIG_SND_LAYLA20=m
+CONFIG_SND_DARLA24=m
+CONFIG_SND_GINA24=m
+CONFIG_SND_LAYLA24=m
+CONFIG_SND_MONA=m
+CONFIG_SND_MIA=m
+CONFIG_SND_ECHO3G=m
+CONFIG_SND_INDIGO=m
+CONFIG_SND_INDIGOIO=m
+CONFIG_SND_INDIGODJ=m
+CONFIG_SND_EMU10K1=m
+CONFIG_SND_EMU10K1X=m
+CONFIG_SND_ENS1370=m
+CONFIG_SND_ENS1371=m
+CONFIG_SND_ES1938=m
+CONFIG_SND_ES1968=m
+CONFIG_SND_FM801=m
+CONFIG_SND_FM801_TEA575X_BOOL=y
+CONFIG_SND_FM801_TEA575X=m
+CONFIG_SND_HDA_INTEL=m
+CONFIG_SND_HDSP=m
+CONFIG_SND_HDSPM=m
+CONFIG_SND_ICE1712=m
+CONFIG_SND_ICE1724=m
+CONFIG_SND_INTEL8X0=m
+CONFIG_SND_INTEL8X0M=m
+CONFIG_SND_KORG1212=m
+CONFIG_SND_MAESTRO3=m
+CONFIG_SND_MIXART=m
+CONFIG_SND_NM256=m
+CONFIG_SND_PCXHR=m
+CONFIG_SND_RIPTIDE=m
+CONFIG_SND_RME32=m
+CONFIG_SND_RME96=m
+CONFIG_SND_RME9652=m
+CONFIG_SND_SONICVIBES=m
+CONFIG_SND_TRIDENT=m
+CONFIG_SND_VIA82XX=m
+CONFIG_SND_VIA82XX_MODEM=m
+CONFIG_SND_VX222=m
+CONFIG_SND_YMFPCI=m
+
+#
+# USB devices
+#
+CONFIG_SND_USB_AUDIO=m
+CONFIG_SND_USB_USX2Y=m
+
+#
+# PCMCIA devices
+#
+# CONFIG_SND_VXPOCKET is not set
+# CONFIG_SND_PDAUDIOCF is not set
+
+#
+# Open Sound System
+#
+# CONFIG_SOUND_PRIME is not set
+
+#
+# USB support
+#
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB_ARCH_HAS_EHCI=y
+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_SUSPEND is not set
+# CONFIG_USB_OTG is not set
+
+#
+# USB Host Controller Drivers
+#
+CONFIG_USB_EHCI_HCD=m
+CONFIG_USB_EHCI_SPLIT_ISO=y
+CONFIG_USB_EHCI_ROOT_HUB_TT=y
+CONFIG_USB_EHCI_TT_NEWSCHED=y
+CONFIG_USB_ISP116X_HCD=m
+CONFIG_USB_OHCI_HCD=m
+# CONFIG_USB_OHCI_BIG_ENDIAN is not set
+CONFIG_USB_OHCI_LITTLE_ENDIAN=y
+CONFIG_USB_UHCI_HCD=m
+CONFIG_USB_SL811_HCD=m
+CONFIG_USB_SL811_CS=m
+
+#
+# USB Device Class drivers
+#
+CONFIG_USB_ACM=m
+CONFIG_USB_PRINTER=m
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+#
+
+#
+# may also be needed; see USB_STORAGE Help for more information
+#
+CONFIG_USB_STORAGE=m
+# CONFIG_USB_STORAGE_DEBUG is not set
+CONFIG_USB_STORAGE_DATAFAB=y
+CONFIG_USB_STORAGE_FREECOM=y
+CONFIG_USB_STORAGE_ISD200=y
+CONFIG_USB_STORAGE_DPCM=y
+CONFIG_USB_STORAGE_USBAT=y
+CONFIG_USB_STORAGE_SDDR09=y
+CONFIG_USB_STORAGE_SDDR55=y
+CONFIG_USB_STORAGE_JUMPSHOT=y
+CONFIG_USB_STORAGE_ALAUDA=y
+CONFIG_USB_LIBUSUAL=y
+
+#
+# USB Input Devices
+#
+CONFIG_USB_HID=y
+CONFIG_USB_HIDINPUT=y
+# CONFIG_USB_HIDINPUT_POWERBOOK is not set
+CONFIG_HID_FF=y
+CONFIG_HID_PID=y
+CONFIG_LOGITECH_FF=y
+CONFIG_THRUSTMASTER_FF=y
+CONFIG_USB_HIDDEV=y
+CONFIG_USB_AIPTEK=m
+CONFIG_USB_WACOM=m
+CONFIG_USB_ACECAD=m
+CONFIG_USB_KBTAB=m
+CONFIG_USB_POWERMATE=m
+CONFIG_USB_TOUCHSCREEN=m
+CONFIG_USB_TOUCHSCREEN_EGALAX=y
+CONFIG_USB_TOUCHSCREEN_PANJIT=y
+CONFIG_USB_TOUCHSCREEN_3M=y
+CONFIG_USB_TOUCHSCREEN_ITM=y
+# CONFIG_USB_YEALINK is not set
+CONFIG_USB_XPAD=m
+CONFIG_USB_ATI_REMOTE=m
+CONFIG_USB_ATI_REMOTE2=m
+CONFIG_USB_KEYSPAN_REMOTE=m
+CONFIG_USB_APPLETOUCH=m
+
+#
+# USB Imaging devices
+#
+CONFIG_USB_MDC800=m
+CONFIG_USB_MICROTEK=m
+
+#
+# USB Network Adapters
+#
+CONFIG_USB_CATC=m
+CONFIG_USB_KAWETH=m
+CONFIG_USB_PEGASUS=m
+CONFIG_USB_RTL8150=m
+CONFIG_USB_USBNET=m
+CONFIG_USB_NET_AX8817X=m
+CONFIG_USB_NET_CDCETHER=m
+CONFIG_USB_NET_GL620A=m
+CONFIG_USB_NET_NET1080=m
+CONFIG_USB_NET_PLUSB=m
+CONFIG_USB_NET_RNDIS_HOST=m
+CONFIG_USB_NET_CDC_SUBSET=m
+CONFIG_USB_ALI_M5632=y
+CONFIG_USB_AN2720=y
+CONFIG_USB_BELKIN=y
+CONFIG_USB_ARMLINUX=y
+CONFIG_USB_EPSON2888=y
+CONFIG_USB_NET_ZAURUS=m
+CONFIG_USB_MON=y
+
+#
+# USB port drivers
+#
+CONFIG_USB_USS720=m
+
+#
+# USB Serial Converter support
+#
+CONFIG_USB_SERIAL=m
+CONFIG_USB_SERIAL_GENERIC=y
+CONFIG_USB_SERIAL_AIRPRIME=m
+CONFIG_USB_SERIAL_ARK3116=m
+CONFIG_USB_SERIAL_BELKIN=m
+CONFIG_USB_SERIAL_WHITEHEAT=m
+CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m
+CONFIG_USB_SERIAL_CP2101=m
+CONFIG_USB_SERIAL_CYPRESS_M8=m
+CONFIG_USB_SERIAL_EMPEG=m
+CONFIG_USB_SERIAL_FTDI_SIO=m
+CONFIG_USB_SERIAL_FUNSOFT=m
+CONFIG_USB_SERIAL_VISOR=m
+CONFIG_USB_SERIAL_IPAQ=m
+CONFIG_USB_SERIAL_IR=m
+CONFIG_USB_SERIAL_EDGEPORT=m
+CONFIG_USB_SERIAL_EDGEPORT_TI=m
+CONFIG_USB_SERIAL_GARMIN=m
+CONFIG_USB_SERIAL_IPW=m
+CONFIG_USB_SERIAL_KEYSPAN_PDA=m
+CONFIG_USB_SERIAL_KEYSPAN=m
+CONFIG_USB_SERIAL_KEYSPAN_MPR=y
+CONFIG_USB_SERIAL_KEYSPAN_USA28=y
+CONFIG_USB_SERIAL_KEYSPAN_USA28X=y
+CONFIG_USB_SERIAL_KEYSPAN_USA28XA=y
+CONFIG_USB_SERIAL_KEYSPAN_USA28XB=y
+CONFIG_USB_SERIAL_KEYSPAN_USA19=y
+CONFIG_USB_SERIAL_KEYSPAN_USA18X=y
+CONFIG_USB_SERIAL_KEYSPAN_USA19W=y
+CONFIG_USB_SERIAL_KEYSPAN_USA19QW=y
+CONFIG_USB_SERIAL_KEYSPAN_USA19QI=y
+CONFIG_USB_SERIAL_KEYSPAN_USA49W=y
+CONFIG_USB_SERIAL_KEYSPAN_USA49WLC=y
+CONFIG_USB_SERIAL_KLSI=m
+CONFIG_USB_SERIAL_KOBIL_SCT=m
+CONFIG_USB_SERIAL_MCT_U232=m
+CONFIG_USB_SERIAL_NAVMAN=m
+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=m
+CONFIG_USB_SERIAL_TI=m
+CONFIG_USB_SERIAL_CYBERJACK=m
+CONFIG_USB_SERIAL_XIRCOM=m
+CONFIG_USB_SERIAL_OPTION=m
+CONFIG_USB_SERIAL_OMNINET=m
+CONFIG_USB_EZUSB=y
+
+#
+# USB Miscellaneous drivers
+#
+CONFIG_USB_EMI62=m
+CONFIG_USB_EMI26=m
+CONFIG_USB_AUERSWALD=m
+CONFIG_USB_RIO500=m
+CONFIG_USB_LEGOTOWER=m
+CONFIG_USB_LCD=m
+CONFIG_USB_LED=m
+# CONFIG_USB_CYPRESS_CY7C63 is not set
+# CONFIG_USB_CYTHERM is not set
+CONFIG_USB_PHIDGETKIT=m
+CONFIG_USB_PHIDGETSERVO=m
+CONFIG_USB_IDMOUSE=m
+CONFIG_USB_APPLEDISPLAY=m
+CONFIG_USB_SISUSBVGA=m
+CONFIG_USB_SISUSBVGA_CON=y
+CONFIG_USB_LD=m
+CONFIG_USB_TEST=m
+
+#
+# USB DSL modem support
+#
+CONFIG_USB_ATM=m
+CONFIG_USB_SPEEDTOUCH=m
+CONFIG_USB_CXACRU=m
+CONFIG_USB_UEAGLEATM=m
+CONFIG_USB_XUSBATM=m
+
+#
+# USB Gadget Support
+#
+# CONFIG_USB_GADGET is not set
+
+#
+# MMC/SD Card support
+#
+CONFIG_MMC=m
+# CONFIG_MMC_DEBUG is not set
+CONFIG_MMC_BLOCK=m
+CONFIG_MMC_SDHCI=m
+CONFIG_MMC_WBSD=m
+
+#
+# LED devices
+#
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+
+#
+# LED drivers
+#
+
+#
+# LED Triggers
+#
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_LEDS_TRIGGER_TIMER=m
+CONFIG_LEDS_TRIGGER_IDE_DISK=y
+CONFIG_LEDS_TRIGGER_HEARTBEAT=m
+
+#
+# InfiniBand support
+#
+CONFIG_INFINIBAND=m
+CONFIG_INFINIBAND_USER_MAD=m
+CONFIG_INFINIBAND_USER_ACCESS=m
+CONFIG_INFINIBAND_ADDR_TRANS=y
+CONFIG_INFINIBAND_MTHCA=m
+CONFIG_INFINIBAND_MTHCA_DEBUG=y
+CONFIG_INFINIBAND_IPOIB=m
+CONFIG_INFINIBAND_IPOIB_DEBUG=y
+CONFIG_INFINIBAND_IPOIB_DEBUG_DATA=y
+CONFIG_INFINIBAND_SRP=m
+CONFIG_INFINIBAND_ISER=m
+
+#
+# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
+#
+CONFIG_EDAC=y
+
+#
+# Reporting subsystems
+#
+# CONFIG_EDAC_DEBUG is not set
+CONFIG_EDAC_MM_EDAC=m
+CONFIG_EDAC_E752X=m
+CONFIG_EDAC_K8=m
+CONFIG_EDAC_POLL=y
+
+#
+# Real Time Clock
+#
+CONFIG_RTC_LIB=m
+CONFIG_RTC_CLASS=m
+
+#
+# RTC interfaces
+#
+CONFIG_RTC_INTF_SYSFS=m
+CONFIG_RTC_INTF_PROC=m
+CONFIG_RTC_INTF_DEV=m
+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
+
+#
+# RTC drivers
+#
+CONFIG_RTC_DRV_X1205=m
+CONFIG_RTC_DRV_DS1307=m
+CONFIG_RTC_DRV_DS1553=m
+CONFIG_RTC_DRV_ISL1208=m
+CONFIG_RTC_DRV_DS1672=m
+CONFIG_RTC_DRV_DS1742=m
+CONFIG_RTC_DRV_PCF8563=m
+CONFIG_RTC_DRV_PCF8583=m
+CONFIG_RTC_DRV_RS5C372=m
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_TEST is not set
+CONFIG_RTC_DRV_V3020=m
+
+#
+# DMA Engine support
+#
+CONFIG_DMA_ENGINE=y
+
+#
+# DMA Clients
+#
+CONFIG_NET_DMA=y
+
+#
+# DMA Devices
+#
+CONFIG_INTEL_IOATDMA=m
+
+#
+# Firmware Drivers
+#
+CONFIG_EDD=m
+CONFIG_DELL_RBU=m
+CONFIG_DCDBAS=m
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+CONFIG_EXT2_FS_POSIX_ACL=y
+CONFIG_EXT2_FS_SECURITY=y
+CONFIG_EXT2_FS_XIP=y
+CONFIG_FS_XIP=y
+CONFIG_EXT3_FS=m
+CONFIG_EXT3_FS_XATTR=y
+CONFIG_EXT3_FS_POSIX_ACL=y
+CONFIG_EXT3_FS_SECURITY=y
+CONFIG_JBD=m
+# CONFIG_JBD_DEBUG is not set
+CONFIG_FS_MBCACHE=y
+CONFIG_REISERFS_FS=m
+# CONFIG_REISERFS_CHECK is not set
+CONFIG_REISERFS_PROC_INFO=y
+CONFIG_REISERFS_FS_XATTR=y
+CONFIG_REISERFS_FS_POSIX_ACL=y
+CONFIG_REISERFS_FS_SECURITY=y
+CONFIG_JFS_FS=m
+CONFIG_JFS_POSIX_ACL=y
+CONFIG_JFS_SECURITY=y
+# CONFIG_JFS_DEBUG is not set
+# CONFIG_JFS_STATISTICS is not set
+CONFIG_FS_POSIX_ACL=y
+CONFIG_XFS_FS=m
+CONFIG_XFS_QUOTA=y
+CONFIG_XFS_SECURITY=y
+CONFIG_XFS_POSIX_ACL=y
+# CONFIG_XFS_RT is not set
+CONFIG_OCFS2_FS=m
+# CONFIG_OCFS2_DEBUG_MASKLOG is not set
+CONFIG_MINIX_FS=m
+CONFIG_ROMFS_FS=m
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+CONFIG_QUOTA=y
+# CONFIG_QFMT_V1 is not set
+CONFIG_QFMT_V2=y
+CONFIG_QUOTACTL=y
+CONFIG_DNOTIFY=y
+CONFIG_AUTOFS_FS=m
+CONFIG_AUTOFS4_FS=m
+CONFIG_FUSE_FS=m
+
+#
+# Caches
+#
+CONFIG_FSCACHE=m
+
+#
+# CD-ROM/DVD Filesystems
+#
+CONFIG_ISO9660_FS=y
+CONFIG_JOLIET=y
+CONFIG_ZISOFS=y
+CONFIG_ZISOFS_FS=y
+CONFIG_UDF_FS=m
+CONFIG_UDF_NLS=y
+CONFIG_CACHEFILES=m
+CONFIG_CACHEFILES_DEBUG=y
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=m
+CONFIG_MSDOS_FS=m
+CONFIG_VFAT_FS=m
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="ascii"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_PROC_VMCORE=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+CONFIG_HUGETLBFS=y
+CONFIG_HUGETLB_PAGE=y
+CONFIG_RAMFS=y
+CONFIG_CONFIGFS_FS=m
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+CONFIG_AFFS_FS=m
+CONFIG_HFS_FS=m
+CONFIG_HFSPLUS_FS=m
+CONFIG_BEFS_FS=m
+# CONFIG_BEFS_DEBUG is not set
+CONFIG_BFS_FS=m
+CONFIG_EFS_FS=m
+# CONFIG_JFFS_FS is not set
+CONFIG_JFFS2_FS=m
+CONFIG_JFFS2_FS_DEBUG=0
+CONFIG_JFFS2_FS_WRITEBUFFER=y
+CONFIG_JFFS2_SUMMARY=y
+# 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=m
+CONFIG_SQUASHFS=m
+# CONFIG_SQUASHFS_EMBEDDED is not set
+CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3
+# CONFIG_SQUASHFS_VMALLOC is not set
+CONFIG_VXFS_FS=m
+# CONFIG_HPFS_FS is not set
+CONFIG_QNX4FS_FS=m
+CONFIG_SYSV_FS=m
+CONFIG_UFS_FS=m
+# CONFIG_UFS_FS_WRITE is not set
+# CONFIG_UFS_DEBUG is not set
+
+#
+# Network File Systems
+#
+CONFIG_NFS_FS=m
+CONFIG_NFS_V3=y
+CONFIG_NFS_V3_ACL=y
+CONFIG_NFS_V4=y
+CONFIG_NFS_FSCACHE=y
+CONFIG_NFS_DIRECTIO=y
+CONFIG_NFSD=m
+CONFIG_NFSD_V2_ACL=y
+CONFIG_NFSD_V3=y
+CONFIG_NFSD_V3_ACL=y
+CONFIG_NFSD_V4=y
+CONFIG_NFSD_TCP=y
+CONFIG_LOCKD=m
+CONFIG_LOCKD_V4=y
+CONFIG_EXPORTFS=m
+CONFIG_NFS_ACL_SUPPORT=m
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=m
+CONFIG_SUNRPC_GSS=m
+CONFIG_RPCSEC_GSS_KRB5=m
+CONFIG_RPCSEC_GSS_SPKM3=m
+# CONFIG_SMB_FS is not set
+CONFIG_CIFS=m
+# CONFIG_CIFS_STATS is not set
+CONFIG_CIFS_WEAK_PW_HASH=y
+CONFIG_CIFS_XATTR=y
+CONFIG_CIFS_POSIX=y
+# CONFIG_CIFS_DEBUG2 is not set
+# CONFIG_CIFS_EXPERIMENTAL is not set
+CONFIG_NCP_FS=m
+CONFIG_NCPFS_PACKET_SIGNING=y
+CONFIG_NCPFS_IOCTL_LOCKING=y
+CONFIG_NCPFS_STRONG=y
+CONFIG_NCPFS_NFS_NS=y
+CONFIG_NCPFS_OS2_NS=y
+CONFIG_NCPFS_SMALLDOS=y
+CONFIG_NCPFS_NLS=y
+CONFIG_NCPFS_EXTRAS=y
+CONFIG_CODA_FS=m
+# CONFIG_CODA_FS_OLD_API is not set
+# CONFIG_AFS_FS is not set
+CONFIG_9P_FS=m
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+CONFIG_OSF_PARTITION=y
+CONFIG_AMIGA_PARTITION=y
+# CONFIG_ATARI_PARTITION is not set
+CONFIG_MAC_PARTITION=y
+CONFIG_MSDOS_PARTITION=y
+CONFIG_BSD_DISKLABEL=y
+CONFIG_MINIX_SUBPARTITION=y
+CONFIG_SOLARIS_X86_PARTITION=y
+CONFIG_UNIXWARE_DISKLABEL=y
+# CONFIG_LDM_PARTITION is not set
+CONFIG_SGI_PARTITION=y
+# CONFIG_ULTRIX_PARTITION is not set
+CONFIG_SUN_PARTITION=y
+CONFIG_KARMA_PARTITION=y
+CONFIG_EFI_PARTITION=y
+
+#
+# Native Language Support
+#
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="utf8"
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_CODEPAGE_737=m
+CONFIG_NLS_CODEPAGE_775=m
+CONFIG_NLS_CODEPAGE_850=m
+CONFIG_NLS_CODEPAGE_852=m
+CONFIG_NLS_CODEPAGE_855=m
+CONFIG_NLS_CODEPAGE_857=m
+CONFIG_NLS_CODEPAGE_860=m
+CONFIG_NLS_CODEPAGE_861=m
+CONFIG_NLS_CODEPAGE_862=m
+CONFIG_NLS_CODEPAGE_863=m
+CONFIG_NLS_CODEPAGE_864=m
+CONFIG_NLS_CODEPAGE_865=m
+CONFIG_NLS_CODEPAGE_866=m
+CONFIG_NLS_CODEPAGE_869=m
+CONFIG_NLS_CODEPAGE_936=m
+CONFIG_NLS_CODEPAGE_950=m
+CONFIG_NLS_CODEPAGE_932=m
+CONFIG_NLS_CODEPAGE_949=m
+CONFIG_NLS_CODEPAGE_874=m
+CONFIG_NLS_ISO8859_8=m
+CONFIG_NLS_CODEPAGE_1250=m
+CONFIG_NLS_CODEPAGE_1251=m
+CONFIG_NLS_ASCII=y
+CONFIG_NLS_ISO8859_1=m
+CONFIG_NLS_ISO8859_2=m
+CONFIG_NLS_ISO8859_3=m
+CONFIG_NLS_ISO8859_4=m
+CONFIG_NLS_ISO8859_5=m
+CONFIG_NLS_ISO8859_6=m
+CONFIG_NLS_ISO8859_7=m
+CONFIG_NLS_ISO8859_9=m
+CONFIG_NLS_ISO8859_13=m
+CONFIG_NLS_ISO8859_14=m
+CONFIG_NLS_ISO8859_15=m
+CONFIG_NLS_KOI8_R=m
+CONFIG_NLS_KOI8_U=m
+CONFIG_NLS_UTF8=m
+
+#
+# Instrumentation Support
+#
+CONFIG_PROFILING=y
+CONFIG_OPROFILE=m
+CONFIG_KPROBES=y
+
+#
+# Kernel hacking
+#
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+# CONFIG_PRINTK_TIME is not set
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_UNUSED_SYMBOLS is not set
+CONFIG_DEBUG_KERNEL=y
+CONFIG_LOG_BUF_SHIFT=17
+CONFIG_DETECT_SOFTLOCKUP=y
+CONFIG_SCHEDSTATS=y
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
+CONFIG_DEBUG_SPINLOCK=y
+# 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=y
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+# CONFIG_DEBUG_KOBJECT is not set
+CONFIG_DEBUG_INFO=y
+CONFIG_DEBUG_FS=y
+# CONFIG_DEBUG_VM is not set
+CONFIG_DEBUG_LIST=y
+# CONFIG_FRAME_POINTER is not set
+CONFIG_UNWIND_INFO=y
+CONFIG_STACK_UNWIND=y
+# CONFIG_FORCED_INLINING is not set
+CONFIG_BOOT_DELAY=y
+# CONFIG_RCU_TORTURE_TEST is not set
+CONFIG_DEBUG_RODATA=y
+# CONFIG_IOMMU_DEBUG is not set
+CONFIG_DEBUG_STACKOVERFLOW=y
+# CONFIG_DEBUG_STACK_USAGE is not set
+
+#
+# Security options
+#
+CONFIG_KEYS=y
+CONFIG_KEYS_DEBUG_PROC_KEYS=y
+CONFIG_SECURITY=y
+CONFIG_SECURITY_NETWORK=y
+# CONFIG_SECURITY_NETWORK_XFRM is not set
+CONFIG_SECURITY_CAPABILITIES=y
+# CONFIG_SECURITY_ROOTPLUG is not set
+# CONFIG_SECURITY_SECLVL is not set
+CONFIG_SECURITY_SELINUX=y
+CONFIG_SECURITY_SELINUX_BOOTPARAM=y
+CONFIG_SECURITY_SELINUX_BOOTPARAM_VALUE=1
+CONFIG_SECURITY_SELINUX_DISABLE=y
+CONFIG_SECURITY_SELINUX_DEVELOP=y
+CONFIG_SECURITY_SELINUX_AVC_STATS=y
+CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE=1
+# CONFIG_SECURITY_SELINUX_ENABLE_SECMARK_DEFAULT is not set
+# CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX is not set
+
+#
+# Cryptographic options
+#
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_NULL=m
+CONFIG_CRYPTO_MD4=m
+CONFIG_CRYPTO_MD5=m
+CONFIG_CRYPTO_SHA1=y
+CONFIG_CRYPTO_SHA256=m
+CONFIG_CRYPTO_SHA512=m
+CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_TGR192=m
+CONFIG_CRYPTO_DES=m
+CONFIG_CRYPTO_BLOWFISH=m
+CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_SERPENT=m
+CONFIG_CRYPTO_AES=m
+CONFIG_CRYPTO_AES_X86_64=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_TEST is not set
+CONFIG_CRYPTO_SIGNATURE=y
+CONFIG_CRYPTO_SIGNATURE_DSA=y
+CONFIG_CRYPTO_MPILIB=y
+
+#
+# Hardware crypto devices
+#
+
+#
+# Library routines
+#
+CONFIG_CRC_CCITT=m
+CONFIG_CRC16=m
+CONFIG_CRC32=y
+CONFIG_LIBCRC32C=m
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=m
+CONFIG_REED_SOLOMON=m
+CONFIG_REED_SOLOMON_DEC16=y
+CONFIG_TEXTSEARCH=y
+CONFIG_TEXTSEARCH_KMP=m
+CONFIG_TEXTSEARCH_BM=m
+CONFIG_TEXTSEARCH_FSM=m
+CONFIG_PLIST=y
diff --git a/configs/kernel-2.6.18-x86_64-xen.config b/configs/kernel-2.6.18-x86_64-xen.config
new file mode 100644
index 000000000..b4a0c30c0
--- /dev/null
+++ b/configs/kernel-2.6.18-x86_64-xen.config
@@ -0,0 +1,3144 @@
+# x86_64
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.18.2-rc1
+# Mon Nov 13 09:44:43 2006
+#
+CONFIG_X86_64=y
+CONFIG_64BIT=y
+CONFIG_X86=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_SEMAPHORE_SLEEPERS=y
+CONFIG_MMU=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_X86_CMPXCHG=y
+CONFIG_EARLY_PRINTK=y
+CONFIG_GENERIC_ISA_DMA=y
+CONFIG_GENERIC_IOMAP=y
+CONFIG_ARCH_MAY_HAVE_PC_FDC=y
+CONFIG_DMI=y
+CONFIG_AUDIT_ARCH=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_BSD_PROCESS_ACCT=y
+# CONFIG_BSD_PROCESS_ACCT_V3 is not set
+CONFIG_TASKSTATS=y
+CONFIG_TASK_DELAY_ACCT=y
+CONFIG_AUDIT=y
+CONFIG_AUDITSYSCALL=y
+# CONFIG_IKCONFIG is not set
+CONFIG_CPUSETS=y
+CONFIG_RELAY=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+# CONFIG_EMBEDDED is not set
+CONFIG_UID16=y
+CONFIG_SYSCTL=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
+CONFIG_KALLSYMS_EXTRA_PASS=y
+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=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+CONFIG_MODULE_SIG=y
+# CONFIG_MODULE_SIG_FORCE is not set
+CONFIG_KMOD=y
+CONFIG_STOP_MACHINE=y
+
+#
+# Process debugging support
+#
+CONFIG_UTRACE=y
+CONFIG_PTRACE=y
+
+#
+# Block layer
+#
+CONFIG_LBD=y
+CONFIG_BLK_DEV_IO_TRACE=y
+CONFIG_LSF=y
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_DEFAULT_AS is not set
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+
+#
+# Processor type and features
+#
+CONFIG_X86_PC=y
+# CONFIG_X86_VSMP is not set
+# CONFIG_MK8 is not set
+# CONFIG_MPSC is not set
+CONFIG_GENERIC_CPU=y
+CONFIG_X86_64_XEN=y
+CONFIG_X86_NO_TSS=y
+CONFIG_X86_NO_IDT=y
+CONFIG_X86_L1_CACHE_BYTES=128
+CONFIG_X86_L1_CACHE_SHIFT=7
+CONFIG_X86_INTERNODE_CACHE_BYTES=128
+CONFIG_X86_GOOD_APIC=y
+CONFIG_MICROCODE=y
+CONFIG_X86_MSR=y
+CONFIG_X86_CPUID=y
+CONFIG_X86_IO_APIC=y
+CONFIG_X86_XEN_GENAPIC=y
+CONFIG_X86_LOCAL_APIC=y
+CONFIG_MTRR=y
+CONFIG_SMP=y
+# CONFIG_PREEMPT_NONE is not set
+CONFIG_PREEMPT_VOLUNTARY=y
+# CONFIG_PREEMPT is not set
+CONFIG_PREEMPT_BKL=y
+CONFIG_ARCH_FLATMEM_ENABLE=y
+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=y
+CONFIG_NR_CPUS=8
+CONFIG_HOTPLUG_CPU=y
+CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
+CONFIG_CALGARY_IOMMU=y
+CONFIG_SWIOTLB=y
+# CONFIG_CRASH_DUMP is not set
+CONFIG_PHYSICAL_START=0x200000
+# CONFIG_SECCOMP is not set
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
+CONFIG_REORDER=y
+CONFIG_K8_NB=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_ISA_DMA_API=y
+CONFIG_GENERIC_PENDING_IRQ=y
+
+#
+# Power management options
+#
+CONFIG_PM=y
+
+#
+# ACPI (Advanced Configuration and Power Interface) Support
+#
+CONFIG_ACPI=y
+CONFIG_ACPI_AC=m
+CONFIG_ACPI_BATTERY=m
+CONFIG_ACPI_BUTTON=m
+CONFIG_ACPI_VIDEO=m
+# CONFIG_ACPI_HOTKEY is not set
+CONFIG_ACPI_FAN=y
+CONFIG_ACPI_DOCK=m
+CONFIG_ACPI_PROCESSOR=y
+CONFIG_ACPI_HOTPLUG_CPU=y
+CONFIG_ACPI_THERMAL=y
+CONFIG_ACPI_ASUS=m
+CONFIG_ACPI_IBM=m
+CONFIG_ACPI_TOSHIBA=m
+CONFIG_ACPI_BLACKLIST_YEAR=0
+# CONFIG_ACPI_DEBUG is not set
+CONFIG_ACPI_EC=y
+CONFIG_ACPI_POWER=y
+CONFIG_ACPI_SYSTEM=y
+CONFIG_ACPI_CONTAINER=y
+CONFIG_ACPI_SBS=m
+
+#
+# CPU Frequency scaling
+#
+CONFIG_CPU_FREQ=y
+CONFIG_CPU_FREQ_TABLE=y
+CONFIG_CPU_FREQ_DEBUG=y
+CONFIG_CPU_FREQ_STAT=m
+CONFIG_CPU_FREQ_STAT_DETAILS=y
+# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set
+CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE=y
+CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
+CONFIG_CPU_FREQ_GOV_POWERSAVE=m
+CONFIG_CPU_FREQ_GOV_USERSPACE=y
+CONFIG_CPU_FREQ_GOV_ONDEMAND=m
+CONFIG_CPU_FREQ_GOV_CONSERVATIVE=m
+
+#
+# CPUFreq processor drivers
+#
+CONFIG_X86_POWERNOW_K8=y
+CONFIG_X86_POWERNOW_K8_ACPI=y
+CONFIG_X86_SPEEDSTEP_CENTRINO=y
+CONFIG_X86_SPEEDSTEP_CENTRINO_ACPI=y
+CONFIG_X86_ACPI_CPUFREQ=m
+
+#
+# shared options
+#
+# CONFIG_X86_ACPI_CPUFREQ_PROC_INTF is not set
+# CONFIG_X86_SPEEDSTEP_LIB is not set
+
+#
+# Bus options (PCI etc.)
+#
+CONFIG_PCI=y
+CONFIG_PCI_DIRECT=y
+# CONFIG_PCI_MMCONFIG is not set
+CONFIG_XEN_PCIDEV_FRONTEND=y
+# CONFIG_XEN_PCIDEV_FE_DEBUG is not set
+CONFIG_PCIEPORTBUS=y
+CONFIG_HOTPLUG_PCI_PCIE=m
+# CONFIG_HOTPLUG_PCI_PCIE_POLL_EVENT_MODE is not set
+# CONFIG_PCI_DEBUG is not set
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+CONFIG_PCCARD=y
+# CONFIG_PCMCIA_DEBUG is not set
+CONFIG_PCMCIA=y
+CONFIG_PCMCIA_LOAD_CIS=y
+CONFIG_PCMCIA_IOCTL=y
+CONFIG_CARDBUS=y
+
+#
+# PC-card bridges
+#
+CONFIG_YENTA=y
+CONFIG_YENTA_O2=y
+CONFIG_YENTA_RICOH=y
+CONFIG_YENTA_TI=y
+CONFIG_YENTA_ENE_TUNE=y
+CONFIG_YENTA_TOSHIBA=y
+CONFIG_PD6729=m
+CONFIG_I82092=m
+CONFIG_PCCARD_NONSTATIC=y
+
+#
+# PCI Hotplug Support
+#
+CONFIG_HOTPLUG_PCI=y
+CONFIG_HOTPLUG_PCI_FAKE=m
+CONFIG_HOTPLUG_PCI_ACPI=m
+CONFIG_HOTPLUG_PCI_ACPI_IBM=m
+# CONFIG_HOTPLUG_PCI_CPCI is not set
+CONFIG_HOTPLUG_PCI_SHPC=m
+# CONFIG_HOTPLUG_PCI_SHPC_POLL_EVENT_MODE is not set
+
+#
+# Executable file formats / Emulations
+#
+CONFIG_BINFMT_ELF=y
+CONFIG_BINFMT_MISC=y
+CONFIG_IA32_EMULATION=y
+# CONFIG_IA32_AOUT is not set
+CONFIG_COMPAT=y
+CONFIG_SYSVIPC_COMPAT=y
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+# CONFIG_NETDEBUG is not set
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=y
+CONFIG_NET_KEY=m
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_ASK_IP_FIB_HASH=y
+# 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
+# CONFIG_IP_PNP is not set
+CONFIG_NET_IPIP=m
+CONFIG_NET_IPGRE=m
+CONFIG_NET_IPGRE_BROADCAST=y
+CONFIG_IP_MROUTE=y
+CONFIG_IP_PIMSM_V1=y
+CONFIG_IP_PIMSM_V2=y
+# CONFIG_ARPD is not set
+CONFIG_SYN_COOKIES=y
+CONFIG_INET_AH=m
+CONFIG_INET_ESP=m
+CONFIG_INET_IPCOMP=m
+CONFIG_INET_XFRM_TUNNEL=m
+CONFIG_INET_TUNNEL=m
+CONFIG_INET_XFRM_MODE_TRANSPORT=m
+CONFIG_INET_XFRM_MODE_TUNNEL=m
+CONFIG_INET_DIAG=m
+CONFIG_INET_TCP_DIAG=m
+CONFIG_TCP_CONG_ADVANCED=y
+
+#
+# TCP congestion control
+#
+CONFIG_TCP_CONG_BIC=y
+CONFIG_TCP_CONG_CUBIC=m
+CONFIG_TCP_CONG_WESTWOOD=m
+CONFIG_TCP_CONG_HTCP=m
+CONFIG_TCP_CONG_HSTCP=m
+CONFIG_TCP_CONG_HYBLA=m
+CONFIG_TCP_CONG_VEGAS=m
+CONFIG_TCP_CONG_SCALABLE=m
+CONFIG_TCP_CONG_LP=m
+CONFIG_TCP_CONG_VENO=m
+
+#
+# IP: Virtual Server Configuration
+#
+CONFIG_IP_VS=m
+# CONFIG_IP_VS_DEBUG is not set
+CONFIG_IP_VS_TAB_BITS=12
+
+#
+# IPVS transport protocol load balancing support
+#
+CONFIG_IP_VS_PROTO_TCP=y
+CONFIG_IP_VS_PROTO_UDP=y
+CONFIG_IP_VS_PROTO_ESP=y
+CONFIG_IP_VS_PROTO_AH=y
+
+#
+# IPVS scheduler
+#
+CONFIG_IP_VS_RR=m
+CONFIG_IP_VS_WRR=m
+CONFIG_IP_VS_LC=m
+CONFIG_IP_VS_WLC=m
+CONFIG_IP_VS_LBLC=m
+CONFIG_IP_VS_LBLCR=m
+CONFIG_IP_VS_DH=m
+CONFIG_IP_VS_SH=m
+CONFIG_IP_VS_SED=m
+CONFIG_IP_VS_NQ=m
+
+#
+# IPVS application helper
+#
+CONFIG_IP_VS_FTP=m
+CONFIG_IPV6=m
+CONFIG_IPV6_PRIVACY=y
+CONFIG_IPV6_ROUTER_PREF=y
+CONFIG_IPV6_ROUTE_INFO=y
+CONFIG_INET6_AH=m
+CONFIG_INET6_ESP=m
+CONFIG_INET6_IPCOMP=m
+CONFIG_INET6_XFRM_TUNNEL=m
+CONFIG_INET6_TUNNEL=m
+CONFIG_INET6_XFRM_MODE_TRANSPORT=m
+CONFIG_INET6_XFRM_MODE_TUNNEL=m
+CONFIG_IPV6_TUNNEL=m
+CONFIG_NETWORK_SECMARK=y
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_DEBUG is not set
+CONFIG_BRIDGE_NETFILTER=y
+
+#
+# Core Netfilter Configuration
+#
+CONFIG_NETFILTER_NETLINK=m
+CONFIG_NETFILTER_NETLINK_QUEUE=m
+CONFIG_NETFILTER_NETLINK_LOG=m
+CONFIG_NETFILTER_XTABLES=m
+CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
+CONFIG_NETFILTER_XT_TARGET_CONNMARK=m
+CONFIG_NETFILTER_XT_TARGET_MARK=m
+CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
+CONFIG_NETFILTER_XT_TARGET_NOTRACK=m
+CONFIG_NETFILTER_XT_TARGET_SECMARK=m
+CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=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_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_PHYSDEV=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
+
+#
+# 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=m
+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_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_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_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
+CONFIG_IP_NF_ARPTABLES=m
+CONFIG_IP_NF_ARPFILTER=m
+CONFIG_IP_NF_ARP_MANGLE=m
+
+#
+# IPv6: Netfilter Configuration (EXPERIMENTAL)
+#
+CONFIG_IP6_NF_QUEUE=m
+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_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
+
+#
+# DECnet: Netfilter Configuration
+#
+# CONFIG_DECNET_NF_GRABULATOR is not set
+
+#
+# Bridge: Netfilter Configuration
+#
+CONFIG_BRIDGE_NF_EBTABLES=m
+CONFIG_BRIDGE_EBT_BROUTE=m
+CONFIG_BRIDGE_EBT_T_FILTER=m
+CONFIG_BRIDGE_EBT_T_NAT=m
+CONFIG_BRIDGE_EBT_802_3=m
+CONFIG_BRIDGE_EBT_AMONG=m
+CONFIG_BRIDGE_EBT_ARP=m
+CONFIG_BRIDGE_EBT_IP=m
+CONFIG_BRIDGE_EBT_LIMIT=m
+CONFIG_BRIDGE_EBT_MARK=m
+CONFIG_BRIDGE_EBT_PKTTYPE=m
+CONFIG_BRIDGE_EBT_STP=m
+CONFIG_BRIDGE_EBT_VLAN=m
+CONFIG_BRIDGE_EBT_ARPREPLY=m
+CONFIG_BRIDGE_EBT_DNAT=m
+CONFIG_BRIDGE_EBT_MARK_T=m
+CONFIG_BRIDGE_EBT_REDIRECT=m
+CONFIG_BRIDGE_EBT_SNAT=m
+CONFIG_BRIDGE_EBT_LOG=m
+CONFIG_BRIDGE_EBT_ULOG=m
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+CONFIG_IP_DCCP=m
+CONFIG_INET_DCCP_DIAG=m
+CONFIG_IP_DCCP_ACKVEC=y
+
+#
+# DCCP CCIDs Configuration (EXPERIMENTAL)
+#
+CONFIG_IP_DCCP_CCID2=m
+CONFIG_IP_DCCP_CCID3=m
+CONFIG_IP_DCCP_TFRC_LIB=m
+
+#
+# DCCP Kernel Hacking
+#
+# CONFIG_IP_DCCP_DEBUG is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+CONFIG_IP_SCTP=m
+# CONFIG_SCTP_DBG_MSG is not set
+# CONFIG_SCTP_DBG_OBJCNT is not set
+# CONFIG_SCTP_HMAC_NONE is not set
+# CONFIG_SCTP_HMAC_SHA1 is not set
+CONFIG_SCTP_HMAC_MD5=y
+
+#
+# TIPC Configuration (EXPERIMENTAL)
+#
+CONFIG_TIPC=m
+# CONFIG_TIPC_ADVANCED is not set
+# CONFIG_TIPC_DEBUG is not set
+CONFIG_ATM=m
+CONFIG_ATM_CLIP=m
+# CONFIG_ATM_CLIP_NO_ICMP is not set
+CONFIG_ATM_LANE=m
+# CONFIG_ATM_MPOA is not set
+CONFIG_ATM_BR2684=m
+# CONFIG_ATM_BR2684_IPFILTER is not set
+CONFIG_BRIDGE=m
+CONFIG_VLAN_8021Q=m
+CONFIG_DECNET=m
+CONFIG_DECNET_ROUTER=y
+CONFIG_DECNET_ROUTE_FWMARK=y
+CONFIG_LLC=y
+# CONFIG_LLC2 is not set
+CONFIG_IPX=m
+# CONFIG_IPX_INTERN is not set
+CONFIG_ATALK=m
+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_ECONET is not set
+CONFIG_WAN_ROUTER=m
+
+#
+# QoS and/or fair queueing
+#
+CONFIG_NET_SCHED=y
+# CONFIG_NET_SCH_CLK_JIFFIES is not set
+CONFIG_NET_SCH_CLK_GETTIMEOFDAY=y
+# CONFIG_NET_SCH_CLK_CPU is not set
+
+#
+# Queueing/Scheduling
+#
+CONFIG_NET_SCH_CBQ=m
+CONFIG_NET_SCH_HTB=m
+CONFIG_NET_SCH_HFSC=m
+CONFIG_NET_SCH_ATM=m
+CONFIG_NET_SCH_PRIO=m
+CONFIG_NET_SCH_RED=m
+CONFIG_NET_SCH_SFQ=m
+CONFIG_NET_SCH_TEQL=m
+CONFIG_NET_SCH_TBF=m
+CONFIG_NET_SCH_GRED=m
+CONFIG_NET_SCH_DSMARK=m
+CONFIG_NET_SCH_NETEM=m
+CONFIG_NET_SCH_INGRESS=m
+
+#
+# Classification
+#
+CONFIG_NET_CLS=y
+CONFIG_NET_CLS_BASIC=m
+CONFIG_NET_CLS_TCINDEX=m
+CONFIG_NET_CLS_ROUTE4=m
+CONFIG_NET_CLS_ROUTE=y
+CONFIG_NET_CLS_FW=m
+CONFIG_NET_CLS_U32=m
+CONFIG_CLS_U32_PERF=y
+CONFIG_CLS_U32_MARK=y
+CONFIG_NET_CLS_RSVP=m
+CONFIG_NET_CLS_RSVP6=m
+CONFIG_NET_EMATCH=y
+CONFIG_NET_EMATCH_STACK=32
+CONFIG_NET_EMATCH_CMP=m
+CONFIG_NET_EMATCH_NBYTE=m
+CONFIG_NET_EMATCH_U32=m
+CONFIG_NET_EMATCH_META=m
+CONFIG_NET_EMATCH_TEXT=m
+CONFIG_NET_CLS_ACT=y
+CONFIG_NET_ACT_POLICE=m
+CONFIG_NET_ACT_GACT=m
+CONFIG_GACT_PROB=y
+CONFIG_NET_ACT_MIRRED=m
+CONFIG_NET_ACT_IPT=m
+CONFIG_NET_ACT_PEDIT=m
+CONFIG_NET_ACT_SIMP=m
+CONFIG_NET_CLS_IND=y
+CONFIG_NET_ESTIMATOR=y
+
+#
+# Network testing
+#
+CONFIG_NET_PKTGEN=m
+# CONFIG_NET_TCPPROBE is not set
+# CONFIG_HAMRADIO is not set
+CONFIG_IRDA=m
+
+#
+# IrDA protocols
+#
+CONFIG_IRLAN=m
+CONFIG_IRNET=m
+CONFIG_IRCOMM=m
+# CONFIG_IRDA_ULTRA is not set
+
+#
+# IrDA options
+#
+CONFIG_IRDA_CACHE_LAST_LSAP=y
+CONFIG_IRDA_FAST_RR=y
+# CONFIG_IRDA_DEBUG is not set
+
+#
+# Infrared-port device drivers
+#
+
+#
+# SIR device drivers
+#
+CONFIG_IRTTY_SIR=m
+
+#
+# Dongle support
+#
+CONFIG_DONGLE=y
+CONFIG_ESI_DONGLE=m
+CONFIG_ACTISYS_DONGLE=m
+CONFIG_TEKRAM_DONGLE=m
+CONFIG_TOIM3232_DONGLE=m
+CONFIG_LITELINK_DONGLE=m
+CONFIG_MA600_DONGLE=m
+CONFIG_GIRBIL_DONGLE=m
+CONFIG_MCP2120_DONGLE=m
+CONFIG_OLD_BELKIN_DONGLE=m
+CONFIG_ACT200L_DONGLE=m
+
+#
+# Old SIR device drivers
+#
+
+#
+# Old Serial dongle support
+#
+
+#
+# FIR device drivers
+#
+CONFIG_USB_IRDA=m
+CONFIG_SIGMATEL_FIR=m
+CONFIG_NSC_FIR=m
+CONFIG_WINBOND_FIR=m
+CONFIG_SMC_IRCC_FIR=m
+CONFIG_ALI_FIR=m
+CONFIG_VLSI_FIR=m
+CONFIG_VIA_FIR=m
+CONFIG_MCS_FIR=m
+CONFIG_BT=m
+CONFIG_BT_L2CAP=m
+CONFIG_BT_SCO=m
+CONFIG_BT_RFCOMM=m
+CONFIG_BT_RFCOMM_TTY=y
+CONFIG_BT_BNEP=m
+CONFIG_BT_BNEP_MC_FILTER=y
+CONFIG_BT_BNEP_PROTO_FILTER=y
+CONFIG_BT_CMTP=m
+CONFIG_BT_HIDP=m
+
+#
+# Bluetooth device drivers
+#
+CONFIG_BT_HCIUSB=m
+CONFIG_BT_HCIUSB_SCO=y
+CONFIG_BT_HCIUART=m
+CONFIG_BT_HCIUART_H4=y
+CONFIG_BT_HCIUART_BCSP=y
+CONFIG_BT_HCIBCM203X=m
+CONFIG_BT_HCIBPA10X=m
+CONFIG_BT_HCIBFUSB=m
+CONFIG_BT_HCIDTL1=m
+CONFIG_BT_HCIBT3C=m
+CONFIG_BT_HCIBLUECARD=m
+CONFIG_BT_HCIBTUART=m
+CONFIG_BT_HCIVHCI=m
+CONFIG_IEEE80211=m
+# CONFIG_IEEE80211_DEBUG is not set
+CONFIG_IEEE80211_CRYPT_WEP=m
+CONFIG_IEEE80211_CRYPT_CCMP=m
+CONFIG_IEEE80211_CRYPT_TKIP=m
+CONFIG_IEEE80211_SOFTMAC=m
+CONFIG_IEEE80211_SOFTMAC_DEBUG=y
+CONFIG_TUX=m
+
+#
+# TUX options
+#
+CONFIG_TUX_EXTCGI=y
+CONFIG_TUX_EXTENDED_LOG=y
+# CONFIG_TUX_DEBUG is not set
+CONFIG_WIRELESS_EXT=y
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_SYS_HYPERVISOR is not set
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+CONFIG_CONNECTOR=y
+CONFIG_PROC_EVENTS=y
+
+#
+# Memory Technology Devices (MTD)
+#
+CONFIG_MTD=m
+# CONFIG_MTD_DEBUG is not set
+CONFIG_MTD_CONCAT=m
+CONFIG_MTD_PARTITIONS=y
+CONFIG_MTD_REDBOOT_PARTS=m
+CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1
+# CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED is not set
+# CONFIG_MTD_REDBOOT_PARTS_READONLY is not set
+CONFIG_MTD_CMDLINE_PARTS=y
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=m
+CONFIG_MTD_BLOCK=m
+CONFIG_MTD_BLOCK_RO=m
+CONFIG_FTL=m
+CONFIG_NFTL=m
+CONFIG_NFTL_RW=y
+CONFIG_INFTL=m
+CONFIG_RFD_FTL=m
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=m
+CONFIG_MTD_JEDECPROBE=m
+CONFIG_MTD_GEN_PROBE=m
+# CONFIG_MTD_CFI_ADV_OPTIONS 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_CFI_INTELEXT=m
+CONFIG_MTD_CFI_AMDSTD=m
+CONFIG_MTD_CFI_STAA=m
+CONFIG_MTD_CFI_UTIL=m
+CONFIG_MTD_RAM=m
+CONFIG_MTD_ROM=m
+CONFIG_MTD_ABSENT=m
+# CONFIG_MTD_OBSOLETE_CHIPS is not set
+
+#
+# Mapping drivers for chip access
+#
+CONFIG_MTD_COMPLEX_MAPPINGS=y
+# CONFIG_MTD_PHYSMAP is not set
+# CONFIG_MTD_PNC2000 is not set
+CONFIG_MTD_SC520CDP=m
+CONFIG_MTD_NETSC520=m
+CONFIG_MTD_TS5500=m
+# CONFIG_MTD_SBC_GXX is not set
+# CONFIG_MTD_AMD76XROM is not set
+# CONFIG_MTD_ICHXROM is not set
+CONFIG_MTD_SCB2_FLASH=m
+# CONFIG_MTD_NETtel is not set
+# CONFIG_MTD_DILNETPC is not set
+# CONFIG_MTD_L440GX is not set
+CONFIG_MTD_PCI=m
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+CONFIG_MTD_PMC551=m
+# CONFIG_MTD_PMC551_BUGFIX is not set
+# CONFIG_MTD_PMC551_DEBUG is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+CONFIG_MTD_MTDRAM=m
+CONFIG_MTDRAM_TOTAL_SIZE=4096
+CONFIG_MTDRAM_ERASE_SIZE=128
+CONFIG_MTD_BLOCK2MTD=m
+
+#
+# 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=m
+# CONFIG_MTD_NAND_VERIFY_WRITE is not set
+CONFIG_MTD_NAND_ECC_SMC=y
+CONFIG_MTD_NAND_IDS=m
+CONFIG_MTD_NAND_DISKONCHIP=m
+# CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADVANCED is not set
+CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADDRESS=0
+# CONFIG_MTD_NAND_DISKONCHIP_BBTWRITE is not set
+CONFIG_MTD_NAND_NANDSIM=m
+
+#
+# OneNAND Flash Device Drivers
+#
+# CONFIG_MTD_ONENAND is not set
+
+#
+# Parallel port support
+#
+CONFIG_PARPORT=m
+CONFIG_PARPORT_PC=m
+CONFIG_PARPORT_SERIAL=m
+# CONFIG_PARPORT_PC_FIFO is not set
+# CONFIG_PARPORT_PC_SUPERIO is not set
+CONFIG_PARPORT_PC_PCMCIA=m
+CONFIG_PARPORT_NOT_PC=y
+# CONFIG_PARPORT_GSC is not set
+# CONFIG_PARPORT_AX88796 is not set
+CONFIG_PARPORT_1284=y
+
+#
+# Plug and Play support
+#
+CONFIG_PNP=y
+# CONFIG_PNP_DEBUG is not set
+
+#
+# Protocols
+#
+CONFIG_PNPACPI=y
+
+#
+# Block devices
+#
+CONFIG_BLK_DEV_FD=m
+CONFIG_PARIDE=m
+CONFIG_PARIDE_PARPORT=m
+
+#
+# Parallel IDE high-level drivers
+#
+CONFIG_PARIDE_PD=m
+CONFIG_PARIDE_PCD=m
+CONFIG_PARIDE_PF=m
+CONFIG_PARIDE_PT=m
+CONFIG_PARIDE_PG=m
+
+#
+# Parallel IDE protocol modules
+#
+CONFIG_PARIDE_ATEN=m
+CONFIG_PARIDE_BPCK=m
+CONFIG_PARIDE_COMM=m
+CONFIG_PARIDE_DSTR=m
+CONFIG_PARIDE_FIT2=m
+CONFIG_PARIDE_FIT3=m
+CONFIG_PARIDE_EPAT=m
+CONFIG_PARIDE_EPATC8=y
+CONFIG_PARIDE_EPIA=m
+CONFIG_PARIDE_FRIQ=m
+CONFIG_PARIDE_FRPW=m
+CONFIG_PARIDE_KBIC=m
+CONFIG_PARIDE_KTTI=m
+CONFIG_PARIDE_ON20=m
+CONFIG_PARIDE_ON26=m
+CONFIG_BLK_CPQ_DA=m
+CONFIG_BLK_CPQ_CISS_DA=m
+CONFIG_CISS_SCSI_TAPE=y
+CONFIG_BLK_DEV_DAC960=m
+CONFIG_BLK_DEV_UMEM=m
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=m
+CONFIG_BLK_DEV_CRYPTOLOOP=m
+CONFIG_BLK_DEV_NBD=m
+CONFIG_BLK_DEV_SX8=m
+CONFIG_BLK_DEV_UB=m
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=16384
+CONFIG_BLK_DEV_RAM_BLOCKSIZE=4096
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_CDROM_PKTCDVD=m
+CONFIG_CDROM_PKTCDVD_BUFFERS=8
+# CONFIG_CDROM_PKTCDVD_WCACHE is not set
+CONFIG_ATA_OVER_ETH=m
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+CONFIG_IDE=y
+CONFIG_BLK_DEV_IDE=y
+
+#
+# Please see Documentation/ide.txt for help/info on IDE drives
+#
+# CONFIG_BLK_DEV_IDE_SATA is not set
+# CONFIG_BLK_DEV_HD_IDE is not set
+CONFIG_BLK_DEV_IDEDISK=y
+CONFIG_IDEDISK_MULTI_MODE=y
+CONFIG_BLK_DEV_IDECS=m
+CONFIG_BLK_DEV_IDECD=m
+# CONFIG_BLK_DEV_IDETAPE is not set
+CONFIG_BLK_DEV_IDEFLOPPY=y
+CONFIG_BLK_DEV_IDESCSI=m
+CONFIG_IDE_TASK_IOCTL=y
+
+#
+# IDE chipset support/bugfixes
+#
+CONFIG_IDE_GENERIC=y
+# CONFIG_BLK_DEV_CMD640 is not set
+CONFIG_BLK_DEV_IDEPNP=y
+CONFIG_BLK_DEV_IDEPCI=y
+CONFIG_IDEPCI_SHARE_IRQ=y
+# CONFIG_BLK_DEV_OFFBOARD is not set
+CONFIG_BLK_DEV_GENERIC=y
+# CONFIG_BLK_DEV_OPTI621 is not set
+# CONFIG_BLK_DEV_RZ1000 is not set
+CONFIG_BLK_DEV_IDEDMA_PCI=y
+# CONFIG_BLK_DEV_IDEDMA_FORCED is not set
+CONFIG_IDEDMA_PCI_AUTO=y
+# CONFIG_IDEDMA_ONLYDISK is not set
+CONFIG_BLK_DEV_AEC62XX=y
+CONFIG_BLK_DEV_ALI15X3=y
+# CONFIG_WDC_ALI15X3 is not set
+CONFIG_BLK_DEV_AMD74XX=y
+CONFIG_BLK_DEV_ATIIXP=y
+CONFIG_BLK_DEV_CMD64X=y
+# CONFIG_BLK_DEV_TRIFLEX is not set
+# CONFIG_BLK_DEV_CY82C693 is not set
+# CONFIG_BLK_DEV_CS5520 is not set
+# CONFIG_BLK_DEV_CS5530 is not set
+CONFIG_BLK_DEV_HPT34X=y
+# CONFIG_HPT34X_AUTODMA is not set
+CONFIG_BLK_DEV_HPT366=y
+# CONFIG_BLK_DEV_SC1200 is not set
+CONFIG_BLK_DEV_PIIX=y
+CONFIG_BLK_DEV_IT821X=y
+# CONFIG_BLK_DEV_NS87415 is not set
+CONFIG_BLK_DEV_PDC202XX_OLD=y
+# CONFIG_PDC202XX_BURST is not set
+CONFIG_BLK_DEV_PDC202XX_NEW=y
+CONFIG_BLK_DEV_SVWKS=y
+CONFIG_BLK_DEV_SIIMAGE=y
+CONFIG_BLK_DEV_SIS5513=y
+# CONFIG_BLK_DEV_SLC90E66 is not set
+# CONFIG_BLK_DEV_TRM290 is not set
+CONFIG_BLK_DEV_VIA82CXXX=y
+# CONFIG_IDE_ARM is not set
+CONFIG_BLK_DEV_IDEDMA=y
+# CONFIG_IDEDMA_IVB is not set
+CONFIG_IDEDMA_AUTO=y
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# SCSI device support
+#
+CONFIG_RAID_ATTRS=m
+CONFIG_SCSI=m
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=m
+CONFIG_CHR_DEV_ST=m
+CONFIG_CHR_DEV_OSST=m
+CONFIG_BLK_DEV_SR=m
+CONFIG_BLK_DEV_SR_VENDOR=y
+CONFIG_CHR_DEV_SG=m
+CONFIG_CHR_DEV_SCH=m
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+CONFIG_SCSI_MULTI_LUN=y
+CONFIG_SCSI_CONSTANTS=y
+CONFIG_SCSI_LOGGING=y
+
+#
+# SCSI Transport Attributes
+#
+CONFIG_SCSI_SPI_ATTRS=m
+CONFIG_SCSI_FC_ATTRS=m
+CONFIG_SCSI_ISCSI_ATTRS=m
+CONFIG_SCSI_SAS_ATTRS=m
+
+#
+# SCSI low-level drivers
+#
+CONFIG_ISCSI_TCP=m
+CONFIG_BLK_DEV_3W_XXXX_RAID=m
+CONFIG_SCSI_3W_9XXX=m
+CONFIG_SCSI_ACARD=m
+CONFIG_SCSI_AACRAID=m
+CONFIG_SCSI_AIC7XXX=m
+CONFIG_AIC7XXX_CMDS_PER_DEVICE=4
+CONFIG_AIC7XXX_RESET_DELAY_MS=15000
+# CONFIG_AIC7XXX_DEBUG_ENABLE is not set
+CONFIG_AIC7XXX_DEBUG_MASK=0
+# CONFIG_AIC7XXX_REG_PRETTY_PRINT is not set
+CONFIG_SCSI_AIC7XXX_OLD=m
+CONFIG_SCSI_AIC79XX=m
+CONFIG_AIC79XX_CMDS_PER_DEVICE=4
+CONFIG_AIC79XX_RESET_DELAY_MS=15000
+# CONFIG_AIC79XX_ENABLE_RD_STRM is not set
+# CONFIG_AIC79XX_DEBUG_ENABLE is not set
+CONFIG_AIC79XX_DEBUG_MASK=0
+# CONFIG_AIC79XX_REG_PRETTY_PRINT is not set
+CONFIG_MEGARAID_NEWGEN=y
+CONFIG_MEGARAID_MM=m
+CONFIG_MEGARAID_MAILBOX=m
+CONFIG_MEGARAID_LEGACY=m
+CONFIG_MEGARAID_SAS=m
+CONFIG_SCSI_SATA=m
+CONFIG_SCSI_SATA_AHCI=m
+CONFIG_SCSI_SATA_SVW=m
+CONFIG_SCSI_ATA_PIIX=m
+CONFIG_SCSI_SATA_MV=m
+CONFIG_SCSI_SATA_NV=m
+CONFIG_SCSI_PDC_ADMA=m
+CONFIG_SCSI_HPTIOP=m
+CONFIG_SCSI_SATA_QSTOR=m
+CONFIG_SCSI_SATA_PROMISE=m
+CONFIG_SCSI_SATA_SX4=m
+CONFIG_SCSI_SATA_SIL=m
+CONFIG_SCSI_SATA_SIL24=m
+CONFIG_SCSI_SATA_SIS=m
+CONFIG_SCSI_SATA_ULI=m
+CONFIG_SCSI_SATA_VIA=m
+CONFIG_SCSI_SATA_VITESSE=m
+CONFIG_SCSI_SATA_INTEL_COMBINED=y
+CONFIG_SCSI_BUSLOGIC=m
+# CONFIG_SCSI_OMIT_FLASHPOINT is not set
+# CONFIG_SCSI_DMX3191D is not set
+# CONFIG_SCSI_EATA is not set
+# CONFIG_SCSI_FUTURE_DOMAIN is not set
+CONFIG_SCSI_GDTH=m
+CONFIG_SCSI_IPS=m
+CONFIG_SCSI_INITIO=m
+CONFIG_SCSI_INIA100=m
+CONFIG_SCSI_PPA=m
+CONFIG_SCSI_IMM=m
+# CONFIG_SCSI_IZIP_EPP16 is not set
+# CONFIG_SCSI_IZIP_SLOW_CTR is not set
+CONFIG_SCSI_SYM53C8XX_2=m
+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_QLOGIC_1280=m
+CONFIG_SCSI_QLA_FC=m
+CONFIG_SCSI_LPFC=m
+CONFIG_SCSI_DC395x=m
+CONFIG_SCSI_DC390T=m
+# CONFIG_SCSI_DEBUG is not set
+
+#
+# PCMCIA SCSI adapter support
+#
+# CONFIG_PCMCIA_FDOMAIN is not set
+CONFIG_PCMCIA_QLOGIC=m
+CONFIG_PCMCIA_SYM53C500=m
+
+#
+# Multi-device support (RAID and LVM)
+#
+CONFIG_MD=y
+CONFIG_BLK_DEV_MD=y
+CONFIG_MD_LINEAR=m
+CONFIG_MD_RAID0=m
+CONFIG_MD_RAID1=m
+CONFIG_MD_RAID10=m
+CONFIG_MD_RAID456=m
+CONFIG_MD_RAID5_RESHAPE=y
+CONFIG_MD_MULTIPATH=m
+CONFIG_MD_FAULTY=m
+CONFIG_BLK_DEV_DM=m
+CONFIG_DM_CRYPT=m
+CONFIG_DM_SNAPSHOT=m
+CONFIG_DM_MIRROR=m
+CONFIG_DM_ZERO=m
+CONFIG_DM_MULTIPATH=m
+CONFIG_DM_MULTIPATH_EMC=m
+
+#
+# Fusion MPT device support
+#
+CONFIG_FUSION=y
+CONFIG_FUSION_SPI=m
+CONFIG_FUSION_FC=m
+CONFIG_FUSION_SAS=m
+CONFIG_FUSION_MAX_SGE=40
+CONFIG_FUSION_CTL=m
+CONFIG_FUSION_LAN=m
+
+#
+# IEEE 1394 (FireWire) support
+#
+CONFIG_IEEE1394=m
+
+#
+# Subsystem Options
+#
+# CONFIG_IEEE1394_VERBOSEDEBUG is not set
+CONFIG_IEEE1394_OUI_DB=y
+CONFIG_IEEE1394_EXTRA_CONFIG_ROMS=y
+CONFIG_IEEE1394_CONFIG_ROM_IP1394=y
+# CONFIG_IEEE1394_EXPORT_FULL_API is not set
+
+#
+# Device Drivers
+#
+CONFIG_IEEE1394_PCILYNX=m
+CONFIG_IEEE1394_OHCI1394=m
+
+#
+# Protocol Drivers
+#
+CONFIG_IEEE1394_VIDEO1394=m
+CONFIG_IEEE1394_SBP2=m
+CONFIG_IEEE1394_ETH1394=m
+CONFIG_IEEE1394_DV1394=m
+CONFIG_IEEE1394_RAWIO=m
+
+#
+# I2O device support
+#
+CONFIG_I2O=m
+# CONFIG_I2O_LCT_NOTIFY_ON_CHANGES is not set
+CONFIG_I2O_EXT_ADAPTEC=y
+CONFIG_I2O_EXT_ADAPTEC_DMA64=y
+CONFIG_I2O_CONFIG=m
+CONFIG_I2O_CONFIG_OLD_IOCTL=y
+CONFIG_I2O_BUS=m
+CONFIG_I2O_BLOCK=m
+CONFIG_I2O_SCSI=m
+CONFIG_I2O_PROC=m
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+CONFIG_IFB=m
+CONFIG_DUMMY=m
+CONFIG_BONDING=m
+CONFIG_EQUALIZER=m
+CONFIG_TUN=m
+CONFIG_NET_SB1000=m
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+
+#
+# PHY device support
+#
+CONFIG_PHYLIB=m
+
+#
+# MII PHY device drivers
+#
+CONFIG_MARVELL_PHY=m
+CONFIG_DAVICOM_PHY=m
+CONFIG_QSEMI_PHY=m
+CONFIG_LXT_PHY=m
+CONFIG_CICADA_PHY=m
+CONFIG_VITESSE_PHY=m
+CONFIG_SMSC_PHY=m
+CONFIG_FIXED_PHY=m
+CONFIG_FIXED_MII_10_FDX=y
+CONFIG_FIXED_MII_100_FDX=y
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=m
+CONFIG_HAPPYMEAL=m
+CONFIG_SUNGEM=m
+CONFIG_CASSINI=m
+CONFIG_NET_VENDOR_3COM=y
+CONFIG_VORTEX=m
+CONFIG_TYPHOON=m
+
+#
+# Tulip family network device support
+#
+CONFIG_NET_TULIP=y
+CONFIG_DE2104X=m
+CONFIG_TULIP=m
+# CONFIG_TULIP_MWI is not set
+CONFIG_TULIP_MMIO=y
+# CONFIG_TULIP_NAPI is not set
+CONFIG_DE4X5=m
+CONFIG_WINBOND_840=m
+CONFIG_DM9102=m
+CONFIG_ULI526X=m
+CONFIG_PCMCIA_XIRCOM=m
+# CONFIG_HP100 is not set
+CONFIG_NET_PCI=y
+CONFIG_PCNET32=m
+CONFIG_AMD8111_ETH=m
+CONFIG_AMD8111E_NAPI=y
+CONFIG_ADAPTEC_STARFIRE=m
+CONFIG_ADAPTEC_STARFIRE_NAPI=y
+CONFIG_B44=m
+CONFIG_FORCEDETH=m
+# CONFIG_DGRS is not set
+# CONFIG_EEPRO100 is not set
+CONFIG_E100=m
+CONFIG_FEALNX=m
+CONFIG_NATSEMI=m
+CONFIG_NE2K_PCI=m
+CONFIG_8139CP=m
+CONFIG_8139TOO=m
+# CONFIG_8139TOO_PIO is not set
+# CONFIG_8139TOO_TUNE_TWISTER is not set
+CONFIG_8139TOO_8129=y
+# CONFIG_8139_OLD_RX_RESET is not set
+CONFIG_SIS900=m
+CONFIG_EPIC100=m
+CONFIG_SUNDANCE=m
+# CONFIG_SUNDANCE_MMIO is not set
+CONFIG_VIA_RHINE=m
+CONFIG_VIA_RHINE_MMIO=y
+CONFIG_VIA_RHINE_NAPI=y
+CONFIG_NET_POCKET=y
+CONFIG_ATP=m
+CONFIG_DE600=m
+CONFIG_DE620=m
+
+#
+# Ethernet (1000 Mbit)
+#
+CONFIG_ACENIC=m
+# CONFIG_ACENIC_OMIT_TIGON_I is not set
+CONFIG_DL2K=m
+CONFIG_E1000=m
+CONFIG_E1000_NAPI=y
+# CONFIG_E1000_DISABLE_PACKET_SPLIT is not set
+CONFIG_NS83820=m
+CONFIG_HAMACHI=m
+CONFIG_YELLOWFIN=m
+CONFIG_R8169=m
+CONFIG_R8169_NAPI=y
+CONFIG_R8169_VLAN=y
+CONFIG_SIS190=m
+CONFIG_SKGE=m
+CONFIG_SKY2=m
+# CONFIG_SK98LIN is not set
+CONFIG_VIA_VELOCITY=m
+CONFIG_TIGON3=m
+CONFIG_BNX2=m
+
+#
+# Ethernet (10000 Mbit)
+#
+CONFIG_CHELSIO_T1=m
+CONFIG_IXGB=m
+CONFIG_IXGB_NAPI=y
+CONFIG_S2IO=m
+CONFIG_S2IO_NAPI=y
+CONFIG_MYRI10GE=m
+
+#
+# Token Ring devices
+#
+CONFIG_TR=y
+CONFIG_IBMOL=m
+CONFIG_3C359=m
+# CONFIG_TMS380TR is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+CONFIG_NET_RADIO=y
+CONFIG_NET_WIRELESS_RTNETLINK=y
+
+#
+# Obsolete Wireless cards support (pre-802.11)
+#
+# CONFIG_STRIP is not set
+CONFIG_PCMCIA_WAVELAN=m
+CONFIG_PCMCIA_NETWAVE=m
+
+#
+# Wireless 802.11 Frequency Hopping cards support
+#
+# CONFIG_PCMCIA_RAYCS is not set
+
+#
+# Wireless 802.11b ISA/PCI cards support
+#
+CONFIG_IPW2100=m
+CONFIG_IPW2100_MONITOR=y
+# CONFIG_IPW2100_DEBUG is not set
+CONFIG_IPW2200=m
+CONFIG_IPW2200_MONITOR=y
+CONFIG_IPW2200_RADIOTAP=y
+CONFIG_IPW2200_PROMISCUOUS=y
+CONFIG_IPW2200_QOS=y
+# CONFIG_IPW2200_DEBUG is not set
+CONFIG_AIRO=m
+CONFIG_HERMES=m
+CONFIG_PLX_HERMES=m
+CONFIG_TMD_HERMES=m
+CONFIG_NORTEL_HERMES=m
+CONFIG_PCI_HERMES=m
+CONFIG_ATMEL=m
+CONFIG_PCI_ATMEL=m
+
+#
+# Wireless 802.11b Pcmcia/Cardbus cards support
+#
+CONFIG_PCMCIA_HERMES=m
+CONFIG_PCMCIA_SPECTRUM=m
+CONFIG_AIRO_CS=m
+CONFIG_PCMCIA_ATMEL=m
+CONFIG_PCMCIA_WL3501=m
+
+#
+# Prism GT/Duette 802.11(a/b/g) PCI/Cardbus support
+#
+CONFIG_PRISM54=m
+CONFIG_USB_ZD1201=m
+CONFIG_HOSTAP=m
+CONFIG_HOSTAP_FIRMWARE=y
+CONFIG_HOSTAP_FIRMWARE_NVRAM=y
+CONFIG_HOSTAP_PLX=m
+CONFIG_HOSTAP_PCI=m
+CONFIG_HOSTAP_CS=m
+CONFIG_BCM43XX=m
+CONFIG_BCM43XX_DEBUG=y
+CONFIG_BCM43XX_DMA=y
+CONFIG_BCM43XX_PIO=y
+CONFIG_BCM43XX_DMA_AND_PIO_MODE=y
+# CONFIG_BCM43XX_DMA_MODE is not set
+# CONFIG_BCM43XX_PIO_MODE is not set
+CONFIG_ZD1211RW=m
+# CONFIG_ZD1211RW_DEBUG is not set
+CONFIG_NET_WIRELESS=y
+
+#
+# PCMCIA network device support
+#
+CONFIG_NET_PCMCIA=y
+CONFIG_PCMCIA_3C589=m
+CONFIG_PCMCIA_3C574=m
+CONFIG_PCMCIA_FMVJ18X=m
+CONFIG_PCMCIA_PCNET=m
+CONFIG_PCMCIA_NMCLAN=m
+CONFIG_PCMCIA_SMC91C92=m
+CONFIG_PCMCIA_XIRC2PS=m
+CONFIG_PCMCIA_AXNET=m
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+
+#
+# ATM drivers
+#
+# CONFIG_ATM_DUMMY is not set
+CONFIG_ATM_TCP=m
+CONFIG_ATM_LANAI=m
+CONFIG_ATM_ENI=m
+# CONFIG_ATM_ENI_DEBUG is not set
+# CONFIG_ATM_ENI_TUNE_BURST is not set
+CONFIG_ATM_FIRESTREAM=m
+# CONFIG_ATM_ZATM is not set
+CONFIG_ATM_IDT77252=m
+# CONFIG_ATM_IDT77252_DEBUG is not set
+# CONFIG_ATM_IDT77252_RCV_ALL is not set
+CONFIG_ATM_IDT77252_USE_SUNI=y
+CONFIG_ATM_AMBASSADOR=m
+# CONFIG_ATM_AMBASSADOR_DEBUG is not set
+CONFIG_ATM_HORIZON=m
+# CONFIG_ATM_HORIZON_DEBUG is not set
+CONFIG_ATM_FORE200E_MAYBE=m
+# CONFIG_ATM_FORE200E_PCA is not set
+CONFIG_ATM_HE=m
+# CONFIG_ATM_HE_USE_SUNI is not set
+CONFIG_FDDI=y
+# CONFIG_DEFXX is not set
+CONFIG_SKFP=m
+# CONFIG_HIPPI is not set
+CONFIG_PLIP=m
+CONFIG_PPP=m
+CONFIG_PPP_MULTILINK=y
+CONFIG_PPP_FILTER=y
+CONFIG_PPP_ASYNC=m
+CONFIG_PPP_SYNC_TTY=m
+CONFIG_PPP_DEFLATE=m
+# CONFIG_PPP_BSDCOMP is not set
+CONFIG_PPP_MPPE=m
+CONFIG_PPPOE=m
+CONFIG_PPPOATM=m
+CONFIG_SLIP=m
+CONFIG_SLIP_COMPRESSED=y
+CONFIG_SLIP_SMART=y
+# CONFIG_SLIP_MODE_SLIP6 is not set
+CONFIG_NET_FC=y
+# CONFIG_SHAPER is not set
+CONFIG_NETCONSOLE=m
+CONFIG_NETPOLL=y
+# CONFIG_NETPOLL_RX is not set
+CONFIG_NETPOLL_TRAP=y
+CONFIG_NET_POLL_CONTROLLER=y
+
+#
+# ISDN subsystem
+#
+CONFIG_ISDN=m
+
+#
+# Old ISDN4Linux
+#
+CONFIG_ISDN_I4L=m
+CONFIG_ISDN_PPP=y
+CONFIG_ISDN_PPP_VJ=y
+CONFIG_ISDN_MPP=y
+CONFIG_IPPP_FILTER=y
+# CONFIG_ISDN_PPP_BSDCOMP is not set
+CONFIG_ISDN_AUDIO=y
+CONFIG_ISDN_TTY_FAX=y
+
+#
+# ISDN feature submodules
+#
+CONFIG_ISDN_DIVERSION=m
+
+#
+# ISDN4Linux hardware drivers
+#
+
+#
+# Passive cards
+#
+CONFIG_ISDN_DRV_HISAX=m
+
+#
+# D-channel protocol features
+#
+CONFIG_HISAX_EURO=y
+CONFIG_DE_AOC=y
+CONFIG_HISAX_NO_SENDCOMPLETE=y
+CONFIG_HISAX_NO_LLC=y
+CONFIG_HISAX_NO_KEYPAD=y
+CONFIG_HISAX_1TR6=y
+CONFIG_HISAX_NI1=y
+CONFIG_HISAX_MAX_CARDS=8
+
+#
+# HiSax supported cards
+#
+CONFIG_HISAX_16_3=y
+CONFIG_HISAX_TELESPCI=y
+CONFIG_HISAX_S0BOX=y
+CONFIG_HISAX_FRITZPCI=y
+CONFIG_HISAX_AVM_A1_PCMCIA=y
+CONFIG_HISAX_ELSA=y
+CONFIG_HISAX_DIEHLDIVA=y
+CONFIG_HISAX_SEDLBAUER=y
+CONFIG_HISAX_NETJET=y
+CONFIG_HISAX_NETJET_U=y
+CONFIG_HISAX_NICCY=y
+CONFIG_HISAX_BKM_A4T=y
+CONFIG_HISAX_SCT_QUADRO=y
+CONFIG_HISAX_GAZEL=y
+CONFIG_HISAX_HFC_PCI=y
+CONFIG_HISAX_W6692=y
+CONFIG_HISAX_HFC_SX=y
+CONFIG_HISAX_ENTERNOW_PCI=y
+# CONFIG_HISAX_DEBUG is not set
+
+#
+# HiSax PCMCIA card service modules
+#
+CONFIG_HISAX_SEDLBAUER_CS=m
+CONFIG_HISAX_ELSA_CS=m
+CONFIG_HISAX_AVM_A1_CS=m
+CONFIG_HISAX_TELES_CS=m
+
+#
+# HiSax sub driver modules
+#
+CONFIG_HISAX_ST5481=m
+# CONFIG_HISAX_HFCUSB is not set
+CONFIG_HISAX_HFC4S8S=m
+CONFIG_HISAX_FRITZ_PCIPNP=m
+CONFIG_HISAX_HDLC=y
+
+#
+# Active cards
+#
+
+#
+# Siemens Gigaset
+#
+CONFIG_ISDN_DRV_GIGASET=m
+CONFIG_GIGASET_BASE=m
+CONFIG_GIGASET_M105=m
+# CONFIG_GIGASET_DEBUG is not set
+# CONFIG_GIGASET_UNDOCREQ is not set
+
+#
+# CAPI subsystem
+#
+CONFIG_ISDN_CAPI=m
+CONFIG_ISDN_DRV_AVMB1_VERBOSE_REASON=y
+CONFIG_ISDN_CAPI_MIDDLEWARE=y
+CONFIG_ISDN_CAPI_CAPI20=m
+CONFIG_ISDN_CAPI_CAPIFS_BOOL=y
+CONFIG_ISDN_CAPI_CAPIFS=m
+CONFIG_ISDN_CAPI_CAPIDRV=m
+
+#
+# CAPI hardware drivers
+#
+
+#
+# Active AVM cards
+#
+CONFIG_CAPI_AVM=y
+CONFIG_ISDN_DRV_AVMB1_B1PCI=m
+CONFIG_ISDN_DRV_AVMB1_B1PCIV4=y
+CONFIG_ISDN_DRV_AVMB1_B1PCMCIA=m
+CONFIG_ISDN_DRV_AVMB1_AVM_CS=m
+CONFIG_ISDN_DRV_AVMB1_T1PCI=m
+CONFIG_ISDN_DRV_AVMB1_C4=m
+
+#
+# Active Eicon DIVA Server cards
+#
+# CONFIG_CAPI_EICON is not set
+
+#
+# Telephony Support
+#
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+
+#
+# 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=m
+# CONFIG_INPUT_TSDEV is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+CONFIG_KEYBOARD_ATKBD=y
+# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_KEYBOARD_LKKBD is not set
+# CONFIG_KEYBOARD_XTKBD is not set
+# CONFIG_KEYBOARD_NEWTON is not set
+CONFIG_INPUT_MOUSE=y
+CONFIG_MOUSE_PS2=y
+CONFIG_MOUSE_SERIAL=m
+CONFIG_MOUSE_VSXXXAA=m
+CONFIG_INPUT_JOYSTICK=y
+CONFIG_JOYSTICK_ANALOG=m
+CONFIG_JOYSTICK_A3D=m
+CONFIG_JOYSTICK_ADI=m
+CONFIG_JOYSTICK_COBRA=m
+CONFIG_JOYSTICK_GF2K=m
+CONFIG_JOYSTICK_GRIP=m
+CONFIG_JOYSTICK_GRIP_MP=m
+CONFIG_JOYSTICK_GUILLEMOT=m
+CONFIG_JOYSTICK_INTERACT=m
+CONFIG_JOYSTICK_SIDEWINDER=m
+CONFIG_JOYSTICK_TMDC=m
+CONFIG_JOYSTICK_IFORCE=m
+CONFIG_JOYSTICK_IFORCE_USB=y
+CONFIG_JOYSTICK_IFORCE_232=y
+CONFIG_JOYSTICK_WARRIOR=m
+CONFIG_JOYSTICK_MAGELLAN=m
+CONFIG_JOYSTICK_SPACEORB=m
+CONFIG_JOYSTICK_SPACEBALL=m
+CONFIG_JOYSTICK_STINGER=m
+CONFIG_JOYSTICK_TWIDJOY=m
+CONFIG_JOYSTICK_DB9=m
+CONFIG_JOYSTICK_GAMECON=m
+CONFIG_JOYSTICK_TURBOGRAFX=m
+CONFIG_JOYSTICK_JOYDUMP=m
+CONFIG_INPUT_TOUCHSCREEN=y
+CONFIG_TOUCHSCREEN_GUNZE=m
+CONFIG_TOUCHSCREEN_ELO=m
+CONFIG_TOUCHSCREEN_MTOUCH=m
+CONFIG_TOUCHSCREEN_MK712=m
+CONFIG_INPUT_MISC=y
+CONFIG_INPUT_PCSPKR=m
+CONFIG_INPUT_UINPUT=m
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+CONFIG_SERIO_I8042=y
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_CT82C710 is not set
+# CONFIG_SERIO_PARKBD is not set
+# CONFIG_SERIO_PCIPS2 is not set
+CONFIG_SERIO_LIBPS2=y
+CONFIG_SERIO_RAW=m
+CONFIG_GAMEPORT=m
+CONFIG_GAMEPORT_NS558=m
+CONFIG_GAMEPORT_L4=m
+CONFIG_GAMEPORT_EMU10K1=m
+CONFIG_GAMEPORT_FM801=m
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+CONFIG_VT_HW_CONSOLE_BINDING=y
+CONFIG_SERIAL_NONSTANDARD=y
+# CONFIG_COMPUTONE is not set
+# CONFIG_ROCKETPORT is not set
+CONFIG_CYCLADES=m
+# CONFIG_CYZ_INTR is not set
+# CONFIG_DIGIEPCA is not set
+# CONFIG_MOXA_INTELLIO is not set
+# CONFIG_MOXA_SMARTIO is not set
+# CONFIG_ISI is not set
+CONFIG_SYNCLINK=m
+CONFIG_SYNCLINKMP=m
+CONFIG_SYNCLINK_GT=m
+CONFIG_N_HDLC=m
+# CONFIG_SPECIALIX is not set
+# CONFIG_SX is not set
+# CONFIG_RIO is not set
+# CONFIG_STALDRV is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=m
+CONFIG_SERIAL_8250_PCI=m
+CONFIG_SERIAL_8250_PNP=m
+CONFIG_SERIAL_8250_CS=m
+CONFIG_SERIAL_8250_NR_UARTS=32
+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=y
+CONFIG_SERIAL_8250_RSA=y
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_CORE=m
+CONFIG_SERIAL_JSM=m
+CONFIG_UNIX98_PTYS=y
+# CONFIG_LEGACY_PTYS is not set
+CONFIG_CRASH=m
+CONFIG_PRINTER=m
+CONFIG_LP_CONSOLE=y
+CONFIG_PPDEV=m
+CONFIG_TIPAR=m
+
+#
+# IPMI
+#
+CONFIG_IPMI_HANDLER=m
+# CONFIG_IPMI_PANIC_EVENT is not set
+CONFIG_IPMI_DEVICE_INTERFACE=m
+CONFIG_IPMI_SI=m
+CONFIG_IPMI_WATCHDOG=m
+CONFIG_IPMI_POWEROFF=m
+
+#
+# Watchdog Cards
+#
+CONFIG_WATCHDOG=y
+# CONFIG_WATCHDOG_NOWAYOUT is not set
+
+#
+# Watchdog Device Drivers
+#
+CONFIG_SOFT_WATCHDOG=m
+# CONFIG_ACQUIRE_WDT is not set
+# CONFIG_ADVANTECH_WDT is not set
+CONFIG_ALIM1535_WDT=m
+CONFIG_ALIM7101_WDT=m
+# CONFIG_SC520_WDT is not set
+# CONFIG_EUROTECH_WDT is not set
+# CONFIG_IB700_WDT is not set
+CONFIG_IBMASR=m
+# CONFIG_WAFER_WDT is not set
+CONFIG_I6300ESB_WDT=m
+CONFIG_I8XX_TCO=m
+# CONFIG_SC1200_WDT is not set
+# CONFIG_60XX_WDT is not set
+# CONFIG_SBC8360_WDT is not set
+# CONFIG_CPU5_WDT is not set
+CONFIG_W83627HF_WDT=m
+CONFIG_W83877F_WDT=m
+CONFIG_W83977F_WDT=m
+CONFIG_MACHZ_WDT=m
+# CONFIG_SBC_EPX_C3_WATCHDOG is not set
+
+#
+# PCI-based Watchdog Cards
+#
+CONFIG_PCIPCWATCHDOG=m
+CONFIG_WDTPCI=m
+CONFIG_WDT_501_PCI=y
+
+#
+# USB-based Watchdog Cards
+#
+CONFIG_USBPCWATCHDOG=m
+CONFIG_HW_RANDOM=y
+CONFIG_HW_RANDOM_INTEL=m
+CONFIG_HW_RANDOM_AMD=m
+# CONFIG_HW_RANDOM_GEODE is not set
+CONFIG_NVRAM=y
+CONFIG_RTC=y
+CONFIG_DTLK=m
+CONFIG_R3964=m
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+CONFIG_AGP=y
+CONFIG_AGP_AMD64=y
+CONFIG_AGP_INTEL=y
+CONFIG_AGP_SIS=y
+CONFIG_AGP_VIA=y
+CONFIG_DRM=m
+CONFIG_DRM_TDFX=m
+CONFIG_DRM_R128=m
+CONFIG_DRM_RADEON=m
+CONFIG_DRM_I810=m
+CONFIG_DRM_I830=m
+CONFIG_DRM_I915=m
+CONFIG_DRM_MGA=m
+CONFIG_DRM_SIS=m
+CONFIG_DRM_VIA=m
+CONFIG_DRM_SAVAGE=m
+
+#
+# PCMCIA character devices
+#
+# CONFIG_SYNCLINK_CS is not set
+CONFIG_CARDMAN_4000=m
+CONFIG_CARDMAN_4040=m
+CONFIG_MWAVE=m
+CONFIG_PC8736x_GPIO=m
+CONFIG_NSC_GPIO=m
+# CONFIG_RAW_DRIVER is not set
+CONFIG_HPET=y
+# CONFIG_HPET_RTC_IRQ is not set
+# CONFIG_HPET_MMAP is not set
+CONFIG_HANGCHECK_TIMER=m
+
+#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+# CONFIG_TELCLOCK is not set
+
+#
+# I2C support
+#
+CONFIG_I2C=m
+CONFIG_I2C_CHARDEV=m
+
+#
+# I2C Algorithms
+#
+CONFIG_I2C_ALGOBIT=m
+CONFIG_I2C_ALGOPCF=m
+CONFIG_I2C_ALGOPCA=m
+
+#
+# I2C Hardware Bus support
+#
+# CONFIG_I2C_ALI1535 is not set
+# CONFIG_I2C_ALI1563 is not set
+# CONFIG_I2C_ALI15X3 is not set
+CONFIG_I2C_AMD756=m
+CONFIG_I2C_AMD756_S4882=m
+CONFIG_I2C_AMD8111=m
+CONFIG_I2C_I801=m
+# CONFIG_I2C_I810 is not set
+# CONFIG_I2C_PIIX4 is not set
+CONFIG_I2C_ISA=m
+CONFIG_I2C_NFORCE2=m
+# CONFIG_I2C_OCORES is not set
+CONFIG_I2C_PARPORT=m
+CONFIG_I2C_PARPORT_LIGHT=m
+CONFIG_I2C_PROSAVAGE=m
+CONFIG_I2C_SAVAGE4=m
+# CONFIG_I2C_SIS5595 is not set
+# CONFIG_I2C_SIS630 is not set
+CONFIG_I2C_SIS96X=m
+CONFIG_I2C_STUB=m
+CONFIG_I2C_VIA=m
+CONFIG_I2C_VIAPRO=m
+CONFIG_I2C_VOODOO3=m
+CONFIG_I2C_PCA_ISA=m
+
+#
+# Miscellaneous I2C Chip support
+#
+CONFIG_SENSORS_DS1337=m
+CONFIG_SENSORS_DS1374=m
+CONFIG_SENSORS_EEPROM=m
+CONFIG_SENSORS_PCF8574=m
+CONFIG_SENSORS_PCA9539=m
+CONFIG_SENSORS_PCF8591=m
+CONFIG_SENSORS_MAX6875=m
+# 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 is not set
+# CONFIG_SPI_MASTER is not set
+
+#
+# Dallas's 1-wire bus
+#
+CONFIG_W1=m
+CONFIG_W1_CON=y
+
+#
+# 1-wire Bus Masters
+#
+CONFIG_W1_MASTER_MATROX=m
+CONFIG_W1_MASTER_DS2490=m
+CONFIG_W1_MASTER_DS2482=m
+
+#
+# 1-wire Slaves
+#
+CONFIG_W1_SLAVE_THERM=m
+CONFIG_W1_SLAVE_SMEM=m
+CONFIG_W1_SLAVE_DS2433=m
+CONFIG_W1_SLAVE_DS2433_CRC=y
+
+#
+# Hardware Monitoring support
+#
+CONFIG_HWMON=m
+CONFIG_HWMON_VID=m
+CONFIG_SENSORS_ABITUGURU=m
+CONFIG_SENSORS_ADM1021=m
+CONFIG_SENSORS_ADM1025=m
+CONFIG_SENSORS_ADM1026=m
+CONFIG_SENSORS_ADM1031=m
+CONFIG_SENSORS_ADM9240=m
+CONFIG_SENSORS_ASB100=m
+CONFIG_SENSORS_ATXP1=m
+CONFIG_SENSORS_DS1621=m
+CONFIG_SENSORS_F71805F=m
+CONFIG_SENSORS_FSCHER=m
+CONFIG_SENSORS_FSCPOS=m
+CONFIG_SENSORS_GL518SM=m
+CONFIG_SENSORS_GL520SM=m
+CONFIG_SENSORS_IT87=m
+CONFIG_SENSORS_LM63=m
+CONFIG_SENSORS_LM75=m
+CONFIG_SENSORS_LM77=m
+CONFIG_SENSORS_LM78=m
+CONFIG_SENSORS_LM80=m
+CONFIG_SENSORS_LM83=m
+CONFIG_SENSORS_LM85=m
+CONFIG_SENSORS_LM87=m
+CONFIG_SENSORS_LM90=m
+CONFIG_SENSORS_LM92=m
+CONFIG_SENSORS_MAX1619=m
+CONFIG_SENSORS_PC87360=m
+CONFIG_SENSORS_SIS5595=m
+CONFIG_SENSORS_SMSC47M1=m
+CONFIG_SENSORS_SMSC47M192=m
+CONFIG_SENSORS_SMSC47B397=m
+CONFIG_SENSORS_VIA686A=m
+CONFIG_SENSORS_VT8231=m
+CONFIG_SENSORS_W83781D=m
+CONFIG_SENSORS_W83791D=m
+CONFIG_SENSORS_W83792D=m
+CONFIG_SENSORS_W83L785TS=m
+CONFIG_SENSORS_W83627HF=m
+CONFIG_SENSORS_W83627EHF=m
+CONFIG_SENSORS_HDAPS=m
+# CONFIG_HWMON_DEBUG_CHIP is not set
+
+#
+# Misc devices
+#
+# CONFIG_IBM_ASM is not set
+
+#
+# Multimedia devices
+#
+CONFIG_VIDEO_DEV=m
+CONFIG_VIDEO_V4L1=y
+CONFIG_VIDEO_V4L1_COMPAT=y
+CONFIG_VIDEO_V4L2=y
+
+#
+# Video Capture Adapters
+#
+
+#
+# Video Capture Adapters
+#
+# CONFIG_VIDEO_ADV_DEBUG is not set
+# CONFIG_VIDEO_VIVI is not set
+CONFIG_VIDEO_BT848=m
+CONFIG_VIDEO_BT848_DVB=y
+CONFIG_VIDEO_SAA6588=m
+CONFIG_VIDEO_BWQCAM=m
+CONFIG_VIDEO_CQCAM=m
+CONFIG_VIDEO_W9966=m
+CONFIG_VIDEO_CPIA=m
+CONFIG_VIDEO_CPIA_PP=m
+CONFIG_VIDEO_CPIA_USB=m
+CONFIG_VIDEO_CPIA2=m
+CONFIG_VIDEO_SAA5246A=m
+CONFIG_VIDEO_SAA5249=m
+CONFIG_TUNER_3036=m
+CONFIG_VIDEO_STRADIS=m
+CONFIG_VIDEO_ZORAN=m
+CONFIG_VIDEO_ZORAN_BUZ=m
+CONFIG_VIDEO_ZORAN_DC10=m
+CONFIG_VIDEO_ZORAN_DC30=m
+CONFIG_VIDEO_ZORAN_LML33=m
+CONFIG_VIDEO_ZORAN_LML33R10=m
+CONFIG_VIDEO_ZORAN_AVS6EYES=m
+CONFIG_VIDEO_SAA7134=m
+CONFIG_VIDEO_SAA7134_ALSA=m
+CONFIG_VIDEO_SAA7134_DVB=m
+CONFIG_VIDEO_SAA7134_DVB_ALL_FRONTENDS=y
+CONFIG_VIDEO_MXB=m
+CONFIG_VIDEO_DPC=m
+CONFIG_VIDEO_HEXIUM_ORION=m
+CONFIG_VIDEO_HEXIUM_GEMINI=m
+CONFIG_VIDEO_CX88_VP3054=m
+CONFIG_VIDEO_CX88=m
+CONFIG_VIDEO_CX88_ALSA=m
+CONFIG_VIDEO_CX88_BLACKBIRD=m
+CONFIG_VIDEO_CX88_DVB=m
+CONFIG_VIDEO_CX88_DVB_ALL_FRONTENDS=y
+
+#
+# Encoders and Decoders
+#
+CONFIG_VIDEO_MSP3400=m
+CONFIG_VIDEO_CS53L32A=m
+CONFIG_VIDEO_TLV320AIC23B=m
+CONFIG_VIDEO_WM8775=m
+CONFIG_VIDEO_WM8739=m
+CONFIG_VIDEO_CX2341X=m
+CONFIG_VIDEO_CX25840=m
+CONFIG_VIDEO_SAA711X=m
+CONFIG_VIDEO_SAA7127=m
+CONFIG_VIDEO_UPD64031A=m
+CONFIG_VIDEO_UPD64083=m
+
+#
+# V4L USB devices
+#
+CONFIG_VIDEO_PVRUSB2=m
+CONFIG_VIDEO_PVRUSB2_24XXX=y
+CONFIG_VIDEO_PVRUSB2_SYSFS=y
+# CONFIG_VIDEO_PVRUSB2_DEBUGIFC is not set
+CONFIG_VIDEO_EM28XX=m
+CONFIG_VIDEO_USBVIDEO=m
+CONFIG_USB_VICAM=m
+CONFIG_USB_IBMCAM=m
+CONFIG_USB_KONICAWC=m
+CONFIG_USB_QUICKCAM_MESSENGER=m
+CONFIG_USB_ET61X251=m
+CONFIG_VIDEO_OVCAMCHIP=m
+CONFIG_USB_W9968CF=m
+CONFIG_USB_OV511=m
+CONFIG_USB_SE401=m
+CONFIG_USB_SN9C102=m
+CONFIG_USB_STV680=m
+CONFIG_USB_ZC0301=m
+CONFIG_USB_PWC=m
+# CONFIG_USB_PWC_DEBUG is not set
+
+#
+# Radio Adapters
+#
+CONFIG_RADIO_GEMTEK_PCI=m
+CONFIG_RADIO_MAXIRADIO=m
+CONFIG_RADIO_MAESTRO=m
+CONFIG_USB_DSBR=m
+
+#
+# Digital Video Broadcasting Devices
+#
+CONFIG_DVB=y
+CONFIG_DVB_CORE=m
+
+#
+# Supported SAA7146 based PCI Adapters
+#
+CONFIG_DVB_AV7110=m
+CONFIG_DVB_AV7110_OSD=y
+CONFIG_DVB_BUDGET=m
+CONFIG_DVB_BUDGET_CI=m
+CONFIG_DVB_BUDGET_AV=m
+CONFIG_DVB_BUDGET_PATCH=m
+
+#
+# Supported USB Adapters
+#
+CONFIG_DVB_USB=m
+# CONFIG_DVB_USB_DEBUG is not set
+CONFIG_DVB_USB_A800=m
+CONFIG_DVB_USB_DIBUSB_MB=m
+# CONFIG_DVB_USB_DIBUSB_MB_FAULTY is not set
+CONFIG_DVB_USB_DIBUSB_MC=m
+CONFIG_DVB_USB_UMT_010=m
+CONFIG_DVB_USB_CXUSB=m
+CONFIG_DVB_USB_DIGITV=m
+CONFIG_DVB_USB_VP7045=m
+CONFIG_DVB_USB_VP702X=m
+CONFIG_DVB_USB_GP8PSK=m
+CONFIG_DVB_USB_NOVA_T_USB2=m
+CONFIG_DVB_USB_DTT200U=m
+CONFIG_DVB_TTUSB_BUDGET=m
+CONFIG_DVB_TTUSB_DEC=m
+CONFIG_DVB_CINERGYT2=m
+CONFIG_DVB_CINERGYT2_TUNING=y
+CONFIG_DVB_CINERGYT2_STREAM_URB_COUNT=32
+CONFIG_DVB_CINERGYT2_STREAM_BUF_SIZE=512
+CONFIG_DVB_CINERGYT2_QUERY_INTERVAL=250
+CONFIG_DVB_CINERGYT2_ENABLE_RC_INPUT_DEVICE=y
+CONFIG_DVB_CINERGYT2_RC_QUERY_INTERVAL=100
+
+#
+# Supported FlexCopII (B2C2) Adapters
+#
+CONFIG_DVB_B2C2_FLEXCOP=m
+CONFIG_DVB_B2C2_FLEXCOP_PCI=m
+CONFIG_DVB_B2C2_FLEXCOP_USB=m
+# CONFIG_DVB_B2C2_FLEXCOP_DEBUG is not set
+
+#
+# Supported BT878 Adapters
+#
+CONFIG_DVB_BT8XX=m
+
+#
+# Supported Pluto2 Adapters
+#
+CONFIG_DVB_PLUTO2=m
+
+#
+# Supported DVB Frontends
+#
+
+#
+# Customise DVB Frontends
+#
+
+#
+# DVB-S (satellite) frontends
+#
+CONFIG_DVB_STV0299=m
+CONFIG_DVB_CX24110=m
+CONFIG_DVB_CX24123=m
+CONFIG_DVB_TDA8083=m
+CONFIG_DVB_MT312=m
+CONFIG_DVB_VES1X93=m
+CONFIG_DVB_S5H1420=m
+
+#
+# DVB-T (terrestrial) frontends
+#
+CONFIG_DVB_SP8870=m
+CONFIG_DVB_SP887X=m
+CONFIG_DVB_CX22700=m
+CONFIG_DVB_CX22702=m
+CONFIG_DVB_L64781=m
+CONFIG_DVB_TDA1004X=m
+CONFIG_DVB_NXT6000=m
+CONFIG_DVB_MT352=m
+CONFIG_DVB_ZL10353=m
+CONFIG_DVB_DIB3000MB=m
+CONFIG_DVB_DIB3000MC=m
+
+#
+# DVB-C (cable) frontends
+#
+CONFIG_DVB_VES1820=m
+CONFIG_DVB_TDA10021=m
+CONFIG_DVB_STV0297=m
+
+#
+# ATSC (North American/Korean Terrestrial/Cable DTV) frontends
+#
+CONFIG_DVB_NXT200X=m
+CONFIG_DVB_OR51211=m
+CONFIG_DVB_OR51132=m
+CONFIG_DVB_BCM3510=m
+CONFIG_DVB_LGDT330X=m
+
+#
+# Miscellaneous devices
+#
+CONFIG_DVB_PLL=m
+CONFIG_DVB_LNBP21=m
+CONFIG_DVB_ISL6421=m
+CONFIG_VIDEO_SAA7146=m
+CONFIG_VIDEO_SAA7146_VV=m
+CONFIG_VIDEO_VIDEOBUF=m
+CONFIG_VIDEO_TUNER=m
+CONFIG_VIDEO_BUF=m
+CONFIG_VIDEO_BUF_DVB=m
+CONFIG_VIDEO_BTCX=m
+CONFIG_VIDEO_IR=m
+CONFIG_VIDEO_TVEEPROM=m
+CONFIG_USB_DABUSB=m
+
+#
+# Graphics support
+#
+# CONFIG_FIRMWARE_EDID is not set
+CONFIG_FB=y
+CONFIG_FB_CFB_FILLRECT=y
+CONFIG_FB_CFB_COPYAREA=y
+CONFIG_FB_CFB_IMAGEBLIT=y
+# CONFIG_FB_MACMODES is not set
+# CONFIG_FB_BACKLIGHT is not set
+CONFIG_FB_MODE_HELPERS=y
+CONFIG_FB_TILEBLITTING=y
+CONFIG_FB_CIRRUS=m
+# CONFIG_FB_PM2 is not set
+# CONFIG_FB_CYBER2000 is not set
+# CONFIG_FB_ARC is not set
+# CONFIG_FB_ASILIANT is not set
+# CONFIG_FB_IMSTT is not set
+CONFIG_FB_VGA16=m
+CONFIG_FB_VESA=y
+# CONFIG_FB_HGA is not set
+# CONFIG_FB_S1D13XXX is not set
+CONFIG_FB_NVIDIA=m
+CONFIG_FB_NVIDIA_I2C=y
+CONFIG_FB_RIVA=m
+# CONFIG_FB_RIVA_I2C is not set
+# CONFIG_FB_RIVA_DEBUG is not set
+CONFIG_FB_INTEL=m
+# CONFIG_FB_INTEL_DEBUG is not set
+CONFIG_FB_MATROX=m
+CONFIG_FB_MATROX_MILLENIUM=y
+CONFIG_FB_MATROX_MYSTIQUE=y
+CONFIG_FB_MATROX_G=y
+CONFIG_FB_MATROX_I2C=m
+CONFIG_FB_MATROX_MAVEN=m
+CONFIG_FB_MATROX_MULTIHEAD=y
+CONFIG_FB_RADEON=m
+CONFIG_FB_RADEON_I2C=y
+# CONFIG_FB_RADEON_DEBUG is not set
+CONFIG_FB_ATY128=m
+CONFIG_FB_ATY=m
+CONFIG_FB_ATY_CT=y
+CONFIG_FB_ATY_GENERIC_LCD=y
+CONFIG_FB_ATY_GX=y
+CONFIG_FB_SAVAGE=m
+CONFIG_FB_SAVAGE_I2C=y
+CONFIG_FB_SAVAGE_ACCEL=y
+# CONFIG_FB_SIS is not set
+CONFIG_FB_NEOMAGIC=m
+CONFIG_FB_KYRO=m
+CONFIG_FB_3DFX=m
+CONFIG_FB_3DFX_ACCEL=y
+CONFIG_FB_VOODOO1=m
+CONFIG_FB_TRIDENT=m
+CONFIG_FB_TRIDENT_ACCEL=y
+# CONFIG_FB_GEODE is not set
+# CONFIG_FB_VIRTUAL is not set
+
+#
+# Console display driver support
+#
+CONFIG_VGA_CONSOLE=y
+CONFIG_VGACON_SOFT_SCROLLBACK=y
+CONFIG_VGACON_SOFT_SCROLLBACK_SIZE=64
+CONFIG_VIDEO_SELECT=y
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y
+# CONFIG_FONTS is not set
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
+
+#
+# Logo configuration
+#
+CONFIG_LOGO=y
+# CONFIG_LOGO_LINUX_MONO is not set
+# CONFIG_LOGO_LINUX_VGA16 is not set
+CONFIG_LOGO_LINUX_CLUT224=y
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+CONFIG_BACKLIGHT_CLASS_DEVICE=m
+CONFIG_BACKLIGHT_DEVICE=y
+CONFIG_LCD_CLASS_DEVICE=m
+CONFIG_LCD_DEVICE=y
+
+#
+# Sound
+#
+CONFIG_SOUND=m
+
+#
+# Advanced Linux Sound Architecture
+#
+CONFIG_SND=m
+CONFIG_SND_TIMER=m
+CONFIG_SND_PCM=m
+CONFIG_SND_HWDEP=m
+CONFIG_SND_RAWMIDI=m
+CONFIG_SND_SEQUENCER=m
+CONFIG_SND_SEQ_DUMMY=m
+CONFIG_SND_OSSEMUL=y
+CONFIG_SND_MIXER_OSS=m
+CONFIG_SND_PCM_OSS=m
+CONFIG_SND_PCM_OSS_PLUGINS=y
+CONFIG_SND_SEQUENCER_OSS=y
+CONFIG_SND_RTCTIMER=m
+CONFIG_SND_SEQ_RTCTIMER_DEFAULT=y
+CONFIG_SND_DYNAMIC_MINORS=y
+# CONFIG_SND_SUPPORT_OLD_API is not set
+CONFIG_SND_VERBOSE_PROCFS=y
+# CONFIG_SND_VERBOSE_PRINTK is not set
+# CONFIG_SND_DEBUG is not set
+
+#
+# Generic devices
+#
+CONFIG_SND_MPU401_UART=m
+CONFIG_SND_OPL3_LIB=m
+CONFIG_SND_VX_LIB=m
+CONFIG_SND_AC97_CODEC=m
+CONFIG_SND_AC97_BUS=m
+CONFIG_SND_DUMMY=m
+CONFIG_SND_VIRMIDI=m
+CONFIG_SND_MTPAV=m
+# CONFIG_SND_SERIAL_U16550 is not set
+CONFIG_SND_MPU401=m
+
+#
+# PCI devices
+#
+CONFIG_SND_AD1889=m
+CONFIG_SND_ALS300=m
+CONFIG_SND_ALS4000=m
+CONFIG_SND_ALI5451=m
+CONFIG_SND_ATIIXP=m
+CONFIG_SND_ATIIXP_MODEM=m
+CONFIG_SND_AU8810=m
+CONFIG_SND_AU8820=m
+CONFIG_SND_AU8830=m
+CONFIG_SND_AZT3328=m
+CONFIG_SND_BT87X=m
+# CONFIG_SND_BT87X_OVERCLOCK is not set
+CONFIG_SND_CA0106=m
+CONFIG_SND_CMIPCI=m
+CONFIG_SND_CS4281=m
+CONFIG_SND_CS46XX=m
+CONFIG_SND_CS46XX_NEW_DSP=y
+CONFIG_SND_DARLA20=m
+CONFIG_SND_GINA20=m
+CONFIG_SND_LAYLA20=m
+CONFIG_SND_DARLA24=m
+CONFIG_SND_GINA24=m
+CONFIG_SND_LAYLA24=m
+CONFIG_SND_MONA=m
+CONFIG_SND_MIA=m
+CONFIG_SND_ECHO3G=m
+CONFIG_SND_INDIGO=m
+CONFIG_SND_INDIGOIO=m
+CONFIG_SND_INDIGODJ=m
+CONFIG_SND_EMU10K1=m
+CONFIG_SND_EMU10K1X=m
+CONFIG_SND_ENS1370=m
+CONFIG_SND_ENS1371=m
+CONFIG_SND_ES1938=m
+CONFIG_SND_ES1968=m
+CONFIG_SND_FM801=m
+CONFIG_SND_FM801_TEA575X_BOOL=y
+CONFIG_SND_FM801_TEA575X=m
+CONFIG_SND_HDA_INTEL=m
+CONFIG_SND_HDSP=m
+CONFIG_SND_HDSPM=m
+CONFIG_SND_ICE1712=m
+CONFIG_SND_ICE1724=m
+CONFIG_SND_INTEL8X0=m
+CONFIG_SND_INTEL8X0M=m
+CONFIG_SND_KORG1212=m
+CONFIG_SND_MAESTRO3=m
+CONFIG_SND_MIXART=m
+CONFIG_SND_NM256=m
+CONFIG_SND_PCXHR=m
+CONFIG_SND_RIPTIDE=m
+CONFIG_SND_RME32=m
+CONFIG_SND_RME96=m
+CONFIG_SND_RME9652=m
+CONFIG_SND_SONICVIBES=m
+CONFIG_SND_TRIDENT=m
+CONFIG_SND_VIA82XX=m
+CONFIG_SND_VIA82XX_MODEM=m
+CONFIG_SND_VX222=m
+CONFIG_SND_YMFPCI=m
+
+#
+# USB devices
+#
+CONFIG_SND_USB_AUDIO=m
+CONFIG_SND_USB_USX2Y=m
+
+#
+# PCMCIA devices
+#
+# CONFIG_SND_VXPOCKET is not set
+# CONFIG_SND_PDAUDIOCF is not set
+
+#
+# Open Sound System
+#
+# CONFIG_SOUND_PRIME is not set
+
+#
+# USB support
+#
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB_ARCH_HAS_EHCI=y
+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_SUSPEND is not set
+# CONFIG_USB_OTG is not set
+
+#
+# USB Host Controller Drivers
+#
+CONFIG_USB_EHCI_HCD=m
+CONFIG_USB_EHCI_SPLIT_ISO=y
+CONFIG_USB_EHCI_ROOT_HUB_TT=y
+CONFIG_USB_EHCI_TT_NEWSCHED=y
+CONFIG_USB_ISP116X_HCD=m
+CONFIG_USB_OHCI_HCD=m
+# CONFIG_USB_OHCI_BIG_ENDIAN is not set
+CONFIG_USB_OHCI_LITTLE_ENDIAN=y
+CONFIG_USB_UHCI_HCD=m
+CONFIG_USB_SL811_HCD=m
+CONFIG_USB_SL811_CS=m
+
+#
+# USB Device Class drivers
+#
+CONFIG_USB_ACM=m
+CONFIG_USB_PRINTER=m
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+#
+
+#
+# may also be needed; see USB_STORAGE Help for more information
+#
+CONFIG_USB_STORAGE=m
+# CONFIG_USB_STORAGE_DEBUG is not set
+CONFIG_USB_STORAGE_DATAFAB=y
+CONFIG_USB_STORAGE_FREECOM=y
+CONFIG_USB_STORAGE_ISD200=y
+CONFIG_USB_STORAGE_DPCM=y
+CONFIG_USB_STORAGE_USBAT=y
+CONFIG_USB_STORAGE_SDDR09=y
+CONFIG_USB_STORAGE_SDDR55=y
+CONFIG_USB_STORAGE_JUMPSHOT=y
+CONFIG_USB_STORAGE_ALAUDA=y
+CONFIG_USB_LIBUSUAL=y
+
+#
+# USB Input Devices
+#
+CONFIG_USB_HID=y
+CONFIG_USB_HIDINPUT=y
+# CONFIG_USB_HIDINPUT_POWERBOOK is not set
+CONFIG_HID_FF=y
+CONFIG_HID_PID=y
+CONFIG_LOGITECH_FF=y
+CONFIG_THRUSTMASTER_FF=y
+CONFIG_USB_HIDDEV=y
+CONFIG_USB_AIPTEK=m
+CONFIG_USB_WACOM=m
+CONFIG_USB_ACECAD=m
+CONFIG_USB_KBTAB=m
+CONFIG_USB_POWERMATE=m
+CONFIG_USB_TOUCHSCREEN=m
+CONFIG_USB_TOUCHSCREEN_EGALAX=y
+CONFIG_USB_TOUCHSCREEN_PANJIT=y
+CONFIG_USB_TOUCHSCREEN_3M=y
+CONFIG_USB_TOUCHSCREEN_ITM=y
+# CONFIG_USB_YEALINK is not set
+CONFIG_USB_XPAD=m
+CONFIG_USB_ATI_REMOTE=m
+CONFIG_USB_ATI_REMOTE2=m
+CONFIG_USB_KEYSPAN_REMOTE=m
+CONFIG_USB_APPLETOUCH=m
+
+#
+# USB Imaging devices
+#
+CONFIG_USB_MDC800=m
+CONFIG_USB_MICROTEK=m
+
+#
+# USB Network Adapters
+#
+CONFIG_USB_CATC=m
+CONFIG_USB_KAWETH=m
+CONFIG_USB_PEGASUS=m
+CONFIG_USB_RTL8150=m
+CONFIG_USB_USBNET=m
+CONFIG_USB_NET_AX8817X=m
+CONFIG_USB_NET_CDCETHER=m
+CONFIG_USB_NET_GL620A=m
+CONFIG_USB_NET_NET1080=m
+CONFIG_USB_NET_PLUSB=m
+CONFIG_USB_NET_RNDIS_HOST=m
+CONFIG_USB_NET_CDC_SUBSET=m
+CONFIG_USB_ALI_M5632=y
+CONFIG_USB_AN2720=y
+CONFIG_USB_BELKIN=y
+CONFIG_USB_ARMLINUX=y
+CONFIG_USB_EPSON2888=y
+CONFIG_USB_NET_ZAURUS=m
+CONFIG_USB_MON=y
+
+#
+# USB port drivers
+#
+CONFIG_USB_USS720=m
+
+#
+# USB Serial Converter support
+#
+CONFIG_USB_SERIAL=m
+CONFIG_USB_SERIAL_GENERIC=y
+CONFIG_USB_SERIAL_AIRPRIME=m
+CONFIG_USB_SERIAL_ARK3116=m
+CONFIG_USB_SERIAL_BELKIN=m
+CONFIG_USB_SERIAL_WHITEHEAT=m
+CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m
+CONFIG_USB_SERIAL_CP2101=m
+CONFIG_USB_SERIAL_CYPRESS_M8=m
+CONFIG_USB_SERIAL_EMPEG=m
+CONFIG_USB_SERIAL_FTDI_SIO=m
+CONFIG_USB_SERIAL_FUNSOFT=m
+CONFIG_USB_SERIAL_VISOR=m
+CONFIG_USB_SERIAL_IPAQ=m
+CONFIG_USB_SERIAL_IR=m
+CONFIG_USB_SERIAL_EDGEPORT=m
+CONFIG_USB_SERIAL_EDGEPORT_TI=m
+CONFIG_USB_SERIAL_GARMIN=m
+CONFIG_USB_SERIAL_IPW=m
+CONFIG_USB_SERIAL_KEYSPAN_PDA=m
+CONFIG_USB_SERIAL_KEYSPAN=m
+CONFIG_USB_SERIAL_KEYSPAN_MPR=y
+CONFIG_USB_SERIAL_KEYSPAN_USA28=y
+CONFIG_USB_SERIAL_KEYSPAN_USA28X=y
+CONFIG_USB_SERIAL_KEYSPAN_USA28XA=y
+CONFIG_USB_SERIAL_KEYSPAN_USA28XB=y
+CONFIG_USB_SERIAL_KEYSPAN_USA19=y
+CONFIG_USB_SERIAL_KEYSPAN_USA18X=y
+CONFIG_USB_SERIAL_KEYSPAN_USA19W=y
+CONFIG_USB_SERIAL_KEYSPAN_USA19QW=y
+CONFIG_USB_SERIAL_KEYSPAN_USA19QI=y
+CONFIG_USB_SERIAL_KEYSPAN_USA49W=y
+CONFIG_USB_SERIAL_KEYSPAN_USA49WLC=y
+CONFIG_USB_SERIAL_KLSI=m
+CONFIG_USB_SERIAL_KOBIL_SCT=m
+CONFIG_USB_SERIAL_MCT_U232=m
+CONFIG_USB_SERIAL_NAVMAN=m
+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=m
+CONFIG_USB_SERIAL_TI=m
+CONFIG_USB_SERIAL_CYBERJACK=m
+CONFIG_USB_SERIAL_XIRCOM=m
+CONFIG_USB_SERIAL_OPTION=m
+CONFIG_USB_SERIAL_OMNINET=m
+CONFIG_USB_EZUSB=y
+
+#
+# USB Miscellaneous drivers
+#
+CONFIG_USB_EMI62=m
+CONFIG_USB_EMI26=m
+CONFIG_USB_AUERSWALD=m
+CONFIG_USB_RIO500=m
+CONFIG_USB_LEGOTOWER=m
+CONFIG_USB_LCD=m
+CONFIG_USB_LED=m
+# CONFIG_USB_CYPRESS_CY7C63 is not set
+# CONFIG_USB_CYTHERM is not set
+CONFIG_USB_PHIDGETKIT=m
+CONFIG_USB_PHIDGETSERVO=m
+CONFIG_USB_IDMOUSE=m
+CONFIG_USB_APPLEDISPLAY=m
+CONFIG_USB_SISUSBVGA=m
+CONFIG_USB_SISUSBVGA_CON=y
+CONFIG_USB_LD=m
+CONFIG_USB_TEST=m
+
+#
+# USB DSL modem support
+#
+CONFIG_USB_ATM=m
+CONFIG_USB_SPEEDTOUCH=m
+CONFIG_USB_CXACRU=m
+CONFIG_USB_UEAGLEATM=m
+CONFIG_USB_XUSBATM=m
+
+#
+# USB Gadget Support
+#
+# CONFIG_USB_GADGET is not set
+
+#
+# MMC/SD Card support
+#
+CONFIG_MMC=m
+# CONFIG_MMC_DEBUG is not set
+CONFIG_MMC_BLOCK=m
+CONFIG_MMC_SDHCI=m
+CONFIG_MMC_WBSD=m
+
+#
+# LED devices
+#
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+
+#
+# LED drivers
+#
+
+#
+# LED Triggers
+#
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_LEDS_TRIGGER_TIMER=m
+CONFIG_LEDS_TRIGGER_IDE_DISK=y
+CONFIG_LEDS_TRIGGER_HEARTBEAT=m
+
+#
+# InfiniBand support
+#
+CONFIG_INFINIBAND=m
+CONFIG_INFINIBAND_USER_MAD=m
+CONFIG_INFINIBAND_USER_ACCESS=m
+CONFIG_INFINIBAND_ADDR_TRANS=y
+CONFIG_INFINIBAND_MTHCA=m
+CONFIG_INFINIBAND_MTHCA_DEBUG=y
+CONFIG_INFINIBAND_IPOIB=m
+CONFIG_INFINIBAND_IPOIB_DEBUG=y
+CONFIG_INFINIBAND_IPOIB_DEBUG_DATA=y
+CONFIG_INFINIBAND_SRP=m
+CONFIG_INFINIBAND_ISER=m
+
+#
+# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
+#
+CONFIG_EDAC=y
+
+#
+# Reporting subsystems
+#
+# CONFIG_EDAC_DEBUG is not set
+CONFIG_EDAC_MM_EDAC=m
+CONFIG_EDAC_E752X=m
+CONFIG_EDAC_K8=m
+CONFIG_EDAC_POLL=y
+
+#
+# Real Time Clock
+#
+CONFIG_RTC_LIB=m
+CONFIG_RTC_CLASS=m
+
+#
+# RTC interfaces
+#
+CONFIG_RTC_INTF_SYSFS=m
+CONFIG_RTC_INTF_PROC=m
+CONFIG_RTC_INTF_DEV=m
+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
+
+#
+# RTC drivers
+#
+CONFIG_RTC_DRV_X1205=m
+CONFIG_RTC_DRV_DS1307=m
+CONFIG_RTC_DRV_DS1553=m
+CONFIG_RTC_DRV_ISL1208=m
+CONFIG_RTC_DRV_DS1672=m
+CONFIG_RTC_DRV_DS1742=m
+CONFIG_RTC_DRV_PCF8563=m
+CONFIG_RTC_DRV_PCF8583=m
+CONFIG_RTC_DRV_RS5C372=m
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_TEST is not set
+CONFIG_RTC_DRV_V3020=m
+
+#
+# DMA Engine support
+#
+CONFIG_DMA_ENGINE=y
+
+#
+# DMA Clients
+#
+CONFIG_NET_DMA=y
+
+#
+# DMA Devices
+#
+CONFIG_INTEL_IOATDMA=m
+
+#
+# Firmware Drivers
+#
+CONFIG_DELL_RBU=m
+CONFIG_DCDBAS=m
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+CONFIG_EXT2_FS_POSIX_ACL=y
+CONFIG_EXT2_FS_SECURITY=y
+CONFIG_EXT2_FS_XIP=y
+CONFIG_FS_XIP=y
+CONFIG_EXT3_FS=m
+CONFIG_EXT3_FS_XATTR=y
+CONFIG_EXT3_FS_POSIX_ACL=y
+CONFIG_EXT3_FS_SECURITY=y
+CONFIG_JBD=m
+# CONFIG_JBD_DEBUG is not set
+CONFIG_FS_MBCACHE=y
+CONFIG_REISERFS_FS=m
+# CONFIG_REISERFS_CHECK is not set
+CONFIG_REISERFS_PROC_INFO=y
+CONFIG_REISERFS_FS_XATTR=y
+CONFIG_REISERFS_FS_POSIX_ACL=y
+CONFIG_REISERFS_FS_SECURITY=y
+CONFIG_JFS_FS=m
+CONFIG_JFS_POSIX_ACL=y
+CONFIG_JFS_SECURITY=y
+# CONFIG_JFS_DEBUG is not set
+# CONFIG_JFS_STATISTICS is not set
+CONFIG_FS_POSIX_ACL=y
+CONFIG_XFS_FS=m
+CONFIG_XFS_QUOTA=y
+CONFIG_XFS_SECURITY=y
+CONFIG_XFS_POSIX_ACL=y
+# CONFIG_XFS_RT is not set
+CONFIG_OCFS2_FS=m
+# CONFIG_OCFS2_DEBUG_MASKLOG is not set
+CONFIG_MINIX_FS=m
+CONFIG_ROMFS_FS=m
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+CONFIG_QUOTA=y
+# CONFIG_QFMT_V1 is not set
+CONFIG_QFMT_V2=y
+CONFIG_QUOTACTL=y
+CONFIG_DNOTIFY=y
+CONFIG_AUTOFS_FS=m
+CONFIG_AUTOFS4_FS=m
+CONFIG_FUSE_FS=m
+
+#
+# Caches
+#
+CONFIG_FSCACHE=m
+
+#
+# CD-ROM/DVD Filesystems
+#
+CONFIG_ISO9660_FS=y
+CONFIG_JOLIET=y
+CONFIG_ZISOFS=y
+CONFIG_ZISOFS_FS=y
+CONFIG_UDF_FS=m
+CONFIG_UDF_NLS=y
+CONFIG_CACHEFILES=m
+CONFIG_CACHEFILES_DEBUG=y
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=m
+CONFIG_MSDOS_FS=m
+CONFIG_VFAT_FS=m
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="ascii"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_RAMFS=y
+CONFIG_CONFIGFS_FS=m
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+CONFIG_AFFS_FS=m
+CONFIG_HFS_FS=m
+CONFIG_HFSPLUS_FS=m
+CONFIG_BEFS_FS=m
+# CONFIG_BEFS_DEBUG is not set
+CONFIG_BFS_FS=m
+CONFIG_EFS_FS=m
+# CONFIG_JFFS_FS is not set
+CONFIG_JFFS2_FS=m
+CONFIG_JFFS2_FS_DEBUG=0
+CONFIG_JFFS2_FS_WRITEBUFFER=y
+CONFIG_JFFS2_SUMMARY=y
+# 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=m
+CONFIG_SQUASHFS=m
+# CONFIG_SQUASHFS_EMBEDDED is not set
+CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3
+# CONFIG_SQUASHFS_VMALLOC is not set
+CONFIG_VXFS_FS=m
+# CONFIG_HPFS_FS is not set
+CONFIG_QNX4FS_FS=m
+CONFIG_SYSV_FS=m
+CONFIG_UFS_FS=m
+# CONFIG_UFS_FS_WRITE is not set
+# CONFIG_UFS_DEBUG is not set
+
+#
+# Network File Systems
+#
+CONFIG_NFS_FS=m
+CONFIG_NFS_V3=y
+CONFIG_NFS_V3_ACL=y
+CONFIG_NFS_V4=y
+CONFIG_NFS_FSCACHE=y
+CONFIG_NFS_DIRECTIO=y
+CONFIG_NFSD=m
+CONFIG_NFSD_V2_ACL=y
+CONFIG_NFSD_V3=y
+CONFIG_NFSD_V3_ACL=y
+CONFIG_NFSD_V4=y
+CONFIG_NFSD_TCP=y
+CONFIG_LOCKD=m
+CONFIG_LOCKD_V4=y
+CONFIG_EXPORTFS=m
+CONFIG_NFS_ACL_SUPPORT=m
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=m
+CONFIG_SUNRPC_GSS=m
+CONFIG_RPCSEC_GSS_KRB5=m
+CONFIG_RPCSEC_GSS_SPKM3=m
+# CONFIG_SMB_FS is not set
+CONFIG_CIFS=m
+# CONFIG_CIFS_STATS is not set
+CONFIG_CIFS_WEAK_PW_HASH=y
+CONFIG_CIFS_XATTR=y
+CONFIG_CIFS_POSIX=y
+# CONFIG_CIFS_DEBUG2 is not set
+# CONFIG_CIFS_EXPERIMENTAL is not set
+CONFIG_NCP_FS=m
+CONFIG_NCPFS_PACKET_SIGNING=y
+CONFIG_NCPFS_IOCTL_LOCKING=y
+CONFIG_NCPFS_STRONG=y
+CONFIG_NCPFS_NFS_NS=y
+CONFIG_NCPFS_OS2_NS=y
+CONFIG_NCPFS_SMALLDOS=y
+CONFIG_NCPFS_NLS=y
+CONFIG_NCPFS_EXTRAS=y
+CONFIG_CODA_FS=m
+# CONFIG_CODA_FS_OLD_API is not set
+# CONFIG_AFS_FS is not set
+CONFIG_9P_FS=m
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+CONFIG_OSF_PARTITION=y
+CONFIG_AMIGA_PARTITION=y
+# CONFIG_ATARI_PARTITION is not set
+CONFIG_MAC_PARTITION=y
+CONFIG_MSDOS_PARTITION=y
+CONFIG_BSD_DISKLABEL=y
+CONFIG_MINIX_SUBPARTITION=y
+CONFIG_SOLARIS_X86_PARTITION=y
+CONFIG_UNIXWARE_DISKLABEL=y
+# CONFIG_LDM_PARTITION is not set
+CONFIG_SGI_PARTITION=y
+# CONFIG_ULTRIX_PARTITION is not set
+CONFIG_SUN_PARTITION=y
+CONFIG_KARMA_PARTITION=y
+CONFIG_EFI_PARTITION=y
+
+#
+# Native Language Support
+#
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="utf8"
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_CODEPAGE_737=m
+CONFIG_NLS_CODEPAGE_775=m
+CONFIG_NLS_CODEPAGE_850=m
+CONFIG_NLS_CODEPAGE_852=m
+CONFIG_NLS_CODEPAGE_855=m
+CONFIG_NLS_CODEPAGE_857=m
+CONFIG_NLS_CODEPAGE_860=m
+CONFIG_NLS_CODEPAGE_861=m
+CONFIG_NLS_CODEPAGE_862=m
+CONFIG_NLS_CODEPAGE_863=m
+CONFIG_NLS_CODEPAGE_864=m
+CONFIG_NLS_CODEPAGE_865=m
+CONFIG_NLS_CODEPAGE_866=m
+CONFIG_NLS_CODEPAGE_869=m
+CONFIG_NLS_CODEPAGE_936=m
+CONFIG_NLS_CODEPAGE_950=m
+CONFIG_NLS_CODEPAGE_932=m
+CONFIG_NLS_CODEPAGE_949=m
+CONFIG_NLS_CODEPAGE_874=m
+CONFIG_NLS_ISO8859_8=m
+CONFIG_NLS_CODEPAGE_1250=m
+CONFIG_NLS_CODEPAGE_1251=m
+CONFIG_NLS_ASCII=y
+CONFIG_NLS_ISO8859_1=m
+CONFIG_NLS_ISO8859_2=m
+CONFIG_NLS_ISO8859_3=m
+CONFIG_NLS_ISO8859_4=m
+CONFIG_NLS_ISO8859_5=m
+CONFIG_NLS_ISO8859_6=m
+CONFIG_NLS_ISO8859_7=m
+CONFIG_NLS_ISO8859_9=m
+CONFIG_NLS_ISO8859_13=m
+CONFIG_NLS_ISO8859_14=m
+CONFIG_NLS_ISO8859_15=m
+CONFIG_NLS_KOI8_R=m
+CONFIG_NLS_KOI8_U=m
+CONFIG_NLS_UTF8=m
+
+#
+# Instrumentation Support
+#
+CONFIG_PROFILING=y
+CONFIG_OPROFILE=m
+CONFIG_KPROBES=y
+
+#
+# Kernel hacking
+#
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+# CONFIG_PRINTK_TIME is not set
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_UNUSED_SYMBOLS is not set
+CONFIG_DEBUG_KERNEL=y
+CONFIG_LOG_BUF_SHIFT=17
+CONFIG_DETECT_SOFTLOCKUP=y
+CONFIG_SCHEDSTATS=y
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
+CONFIG_DEBUG_SPINLOCK=y
+# CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_RWSEMS is not set
+CONFIG_DEBUG_SPINLOCK_SLEEP=y
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+# CONFIG_DEBUG_KOBJECT is not set
+CONFIG_DEBUG_INFO=y
+CONFIG_DEBUG_FS=y
+# CONFIG_DEBUG_VM is not set
+CONFIG_DEBUG_LIST=y
+# CONFIG_FRAME_POINTER is not set
+# CONFIG_FORCED_INLINING is not set
+CONFIG_BOOT_DELAY=y
+# CONFIG_RCU_TORTURE_TEST is not set
+CONFIG_DEBUG_RODATA=y
+CONFIG_DEBUG_STACKOVERFLOW=y
+# CONFIG_DEBUG_STACK_USAGE is not set
+
+#
+# Security options
+#
+CONFIG_KEYS=y
+CONFIG_KEYS_DEBUG_PROC_KEYS=y
+CONFIG_SECURITY=y
+CONFIG_SECURITY_NETWORK=y
+# CONFIG_SECURITY_NETWORK_XFRM is not set
+CONFIG_SECURITY_CAPABILITIES=y
+# CONFIG_SECURITY_ROOTPLUG is not set
+# CONFIG_SECURITY_SECLVL is not set
+CONFIG_SECURITY_SELINUX=y
+CONFIG_SECURITY_SELINUX_BOOTPARAM=y
+CONFIG_SECURITY_SELINUX_BOOTPARAM_VALUE=1
+CONFIG_SECURITY_SELINUX_DISABLE=y
+CONFIG_SECURITY_SELINUX_DEVELOP=y
+CONFIG_SECURITY_SELINUX_AVC_STATS=y
+CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE=1
+# CONFIG_SECURITY_SELINUX_ENABLE_SECMARK_DEFAULT is not set
+# CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX is not set
+
+#
+# Cryptographic options
+#
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_NULL=m
+CONFIG_CRYPTO_MD4=m
+CONFIG_CRYPTO_MD5=m
+CONFIG_CRYPTO_SHA1=y
+CONFIG_CRYPTO_SHA256=m
+CONFIG_CRYPTO_SHA512=m
+CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_TGR192=m
+CONFIG_CRYPTO_DES=m
+CONFIG_CRYPTO_BLOWFISH=m
+CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_SERPENT=m
+CONFIG_CRYPTO_AES=m
+CONFIG_CRYPTO_AES_X86_64=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_TEST is not set
+CONFIG_CRYPTO_SIGNATURE=y
+CONFIG_CRYPTO_SIGNATURE_DSA=y
+CONFIG_CRYPTO_MPILIB=y
+
+#
+# Hardware crypto devices
+#
+CONFIG_XEN=y
+CONFIG_XEN_INTERFACE_VERSION=0x00030203
+
+#
+# XEN
+#
+CONFIG_XEN_PRIVILEGED_GUEST=y
+# CONFIG_XEN_UNPRIVILEGED_GUEST is not set
+CONFIG_XEN_PRIVCMD=y
+CONFIG_XEN_XENBUS_DEV=y
+CONFIG_XEN_BACKEND=y
+CONFIG_XEN_BLKDEV_BACKEND=m
+CONFIG_XEN_BLKDEV_TAP=m
+CONFIG_XEN_NETDEV_BACKEND=m
+# CONFIG_XEN_NETDEV_PIPELINED_TRANSMITTER is not set
+CONFIG_XEN_NETDEV_LOOPBACK=m
+CONFIG_XEN_PCIDEV_BACKEND=m
+CONFIG_XEN_PCIDEV_BACKEND_VPCI=y
+# CONFIG_XEN_PCIDEV_BACKEND_PASS is not set
+# CONFIG_XEN_PCIDEV_BACKEND_SLOT is not set
+# CONFIG_XEN_PCIDEV_BE_DEBUG is not set
+# CONFIG_XEN_TPMDEV_BACKEND is not set
+CONFIG_XEN_BLKDEV_FRONTEND=m
+CONFIG_XEN_NETDEV_FRONTEND=m
+CONFIG_XEN_FRAMEBUFFER=y
+CONFIG_XEN_KEYBOARD=y
+CONFIG_XEN_SCRUB_PAGES=y
+# CONFIG_XEN_DISABLE_SERIAL is not set
+CONFIG_XEN_SYSFS=y
+CONFIG_XEN_COMPAT_030002_AND_LATER=y
+# CONFIG_XEN_COMPAT_LATEST_ONLY is not set
+CONFIG_XEN_COMPAT_030002=y
+CONFIG_HAVE_ARCH_ALLOC_SKB=y
+CONFIG_HAVE_ARCH_DEV_ALLOC_SKB=y
+CONFIG_HAVE_IRQ_IGNORE_UNHANDLED=y
+CONFIG_NO_IDLE_HZ=y
+CONFIG_XEN_UTIL=y
+CONFIG_XEN_BALLOON=y
+CONFIG_XEN_DEVMEM=y
+CONFIG_XEN_SKBUFF=y
+CONFIG_XEN_REBOOT=y
+CONFIG_XEN_SMPBOOT=y
+
+#
+# Library routines
+#
+CONFIG_CRC_CCITT=m
+CONFIG_CRC16=m
+CONFIG_CRC32=y
+CONFIG_LIBCRC32C=m
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=m
+CONFIG_REED_SOLOMON=m
+CONFIG_REED_SOLOMON_DEC16=y
+CONFIG_TEXTSEARCH=y
+CONFIG_TEXTSEARCH_KMP=m
+CONFIG_TEXTSEARCH_BM=m
+CONFIG_TEXTSEARCH_FSM=m
+CONFIG_PLIST=y
diff --git a/configs/kernel-2.6.18-x86_64-xen0.config b/configs/kernel-2.6.18-x86_64-xen0.config
new file mode 100644
index 000000000..25d6f9044
--- /dev/null
+++ b/configs/kernel-2.6.18-x86_64-xen0.config
@@ -0,0 +1,3144 @@
+# x86_64
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.18.2-rc1
+# Mon Nov 13 09:44:43 2006
+#
+CONFIG_X86_64=y
+CONFIG_64BIT=y
+CONFIG_X86=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_SEMAPHORE_SLEEPERS=y
+CONFIG_MMU=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_X86_CMPXCHG=y
+CONFIG_EARLY_PRINTK=y
+CONFIG_GENERIC_ISA_DMA=y
+CONFIG_GENERIC_IOMAP=y
+CONFIG_ARCH_MAY_HAVE_PC_FDC=y
+CONFIG_DMI=y
+CONFIG_AUDIT_ARCH=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_BSD_PROCESS_ACCT=y
+# CONFIG_BSD_PROCESS_ACCT_V3 is not set
+CONFIG_TASKSTATS=y
+CONFIG_TASK_DELAY_ACCT=y
+CONFIG_AUDIT=y
+CONFIG_AUDITSYSCALL=y
+# CONFIG_IKCONFIG is not set
+CONFIG_CPUSETS=y
+CONFIG_RELAY=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+# CONFIG_EMBEDDED is not set
+CONFIG_UID16=y
+CONFIG_SYSCTL=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
+CONFIG_KALLSYMS_EXTRA_PASS=y
+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=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+CONFIG_MODULE_SIG=y
+# CONFIG_MODULE_SIG_FORCE is not set
+CONFIG_KMOD=y
+CONFIG_STOP_MACHINE=y
+
+#
+# Process debugging support
+#
+CONFIG_UTRACE=y
+CONFIG_PTRACE=y
+
+#
+# Block layer
+#
+CONFIG_LBD=y
+CONFIG_BLK_DEV_IO_TRACE=y
+CONFIG_LSF=y
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_DEFAULT_AS is not set
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+
+#
+# Processor type and features
+#
+CONFIG_X86_PC=y
+# CONFIG_X86_VSMP is not set
+# CONFIG_MK8 is not set
+# CONFIG_MPSC is not set
+CONFIG_GENERIC_CPU=y
+CONFIG_X86_64_XEN=y
+CONFIG_X86_NO_TSS=y
+CONFIG_X86_NO_IDT=y
+CONFIG_X86_L1_CACHE_BYTES=128
+CONFIG_X86_L1_CACHE_SHIFT=7
+CONFIG_X86_INTERNODE_CACHE_BYTES=128
+CONFIG_X86_GOOD_APIC=y
+CONFIG_MICROCODE=y
+CONFIG_X86_MSR=y
+CONFIG_X86_CPUID=y
+CONFIG_X86_IO_APIC=y
+CONFIG_X86_XEN_GENAPIC=y
+CONFIG_X86_LOCAL_APIC=y
+CONFIG_MTRR=y
+CONFIG_SMP=y
+# CONFIG_PREEMPT_NONE is not set
+CONFIG_PREEMPT_VOLUNTARY=y
+# CONFIG_PREEMPT is not set
+CONFIG_PREEMPT_BKL=y
+CONFIG_ARCH_FLATMEM_ENABLE=y
+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=y
+CONFIG_NR_CPUS=8
+CONFIG_HOTPLUG_CPU=y
+CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
+CONFIG_CALGARY_IOMMU=y
+CONFIG_SWIOTLB=y
+# CONFIG_CRASH_DUMP is not set
+CONFIG_PHYSICAL_START=0x200000
+# CONFIG_SECCOMP is not set
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
+CONFIG_REORDER=y
+CONFIG_K8_NB=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_ISA_DMA_API=y
+CONFIG_GENERIC_PENDING_IRQ=y
+
+#
+# Power management options
+#
+CONFIG_PM=y
+
+#
+# ACPI (Advanced Configuration and Power Interface) Support
+#
+CONFIG_ACPI=y
+CONFIG_ACPI_AC=m
+CONFIG_ACPI_BATTERY=m
+CONFIG_ACPI_BUTTON=m
+CONFIG_ACPI_VIDEO=m
+# CONFIG_ACPI_HOTKEY is not set
+CONFIG_ACPI_FAN=y
+CONFIG_ACPI_DOCK=m
+CONFIG_ACPI_PROCESSOR=y
+CONFIG_ACPI_HOTPLUG_CPU=y
+CONFIG_ACPI_THERMAL=y
+CONFIG_ACPI_ASUS=m
+CONFIG_ACPI_IBM=m
+CONFIG_ACPI_TOSHIBA=m
+CONFIG_ACPI_BLACKLIST_YEAR=0
+# CONFIG_ACPI_DEBUG is not set
+CONFIG_ACPI_EC=y
+CONFIG_ACPI_POWER=y
+CONFIG_ACPI_SYSTEM=y
+CONFIG_ACPI_CONTAINER=y
+CONFIG_ACPI_SBS=m
+
+#
+# CPU Frequency scaling
+#
+CONFIG_CPU_FREQ=y
+CONFIG_CPU_FREQ_TABLE=y
+CONFIG_CPU_FREQ_DEBUG=y
+CONFIG_CPU_FREQ_STAT=m
+CONFIG_CPU_FREQ_STAT_DETAILS=y
+# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set
+CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE=y
+CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
+CONFIG_CPU_FREQ_GOV_POWERSAVE=m
+CONFIG_CPU_FREQ_GOV_USERSPACE=y
+CONFIG_CPU_FREQ_GOV_ONDEMAND=m
+CONFIG_CPU_FREQ_GOV_CONSERVATIVE=m
+
+#
+# CPUFreq processor drivers
+#
+CONFIG_X86_POWERNOW_K8=y
+CONFIG_X86_POWERNOW_K8_ACPI=y
+CONFIG_X86_SPEEDSTEP_CENTRINO=y
+CONFIG_X86_SPEEDSTEP_CENTRINO_ACPI=y
+CONFIG_X86_ACPI_CPUFREQ=m
+
+#
+# shared options
+#
+# CONFIG_X86_ACPI_CPUFREQ_PROC_INTF is not set
+# CONFIG_X86_SPEEDSTEP_LIB is not set
+
+#
+# Bus options (PCI etc.)
+#
+CONFIG_PCI=y
+CONFIG_PCI_DIRECT=y
+# CONFIG_PCI_MMCONFIG is not set
+CONFIG_XEN_PCIDEV_FRONTEND=y
+# CONFIG_XEN_PCIDEV_FE_DEBUG is not set
+CONFIG_PCIEPORTBUS=y
+CONFIG_HOTPLUG_PCI_PCIE=m
+# CONFIG_HOTPLUG_PCI_PCIE_POLL_EVENT_MODE is not set
+# CONFIG_PCI_DEBUG is not set
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+CONFIG_PCCARD=y
+# CONFIG_PCMCIA_DEBUG is not set
+CONFIG_PCMCIA=y
+CONFIG_PCMCIA_LOAD_CIS=y
+CONFIG_PCMCIA_IOCTL=y
+CONFIG_CARDBUS=y
+
+#
+# PC-card bridges
+#
+CONFIG_YENTA=y
+CONFIG_YENTA_O2=y
+CONFIG_YENTA_RICOH=y
+CONFIG_YENTA_TI=y
+CONFIG_YENTA_ENE_TUNE=y
+CONFIG_YENTA_TOSHIBA=y
+CONFIG_PD6729=m
+CONFIG_I82092=m
+CONFIG_PCCARD_NONSTATIC=y
+
+#
+# PCI Hotplug Support
+#
+CONFIG_HOTPLUG_PCI=y
+CONFIG_HOTPLUG_PCI_FAKE=m
+CONFIG_HOTPLUG_PCI_ACPI=m
+CONFIG_HOTPLUG_PCI_ACPI_IBM=m
+# CONFIG_HOTPLUG_PCI_CPCI is not set
+CONFIG_HOTPLUG_PCI_SHPC=m
+# CONFIG_HOTPLUG_PCI_SHPC_POLL_EVENT_MODE is not set
+
+#
+# Executable file formats / Emulations
+#
+CONFIG_BINFMT_ELF=y
+CONFIG_BINFMT_MISC=y
+CONFIG_IA32_EMULATION=y
+# CONFIG_IA32_AOUT is not set
+CONFIG_COMPAT=y
+CONFIG_SYSVIPC_COMPAT=y
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+# CONFIG_NETDEBUG is not set
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=y
+CONFIG_NET_KEY=m
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_ASK_IP_FIB_HASH=y
+# 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
+# CONFIG_IP_PNP is not set
+CONFIG_NET_IPIP=m
+CONFIG_NET_IPGRE=m
+CONFIG_NET_IPGRE_BROADCAST=y
+CONFIG_IP_MROUTE=y
+CONFIG_IP_PIMSM_V1=y
+CONFIG_IP_PIMSM_V2=y
+# CONFIG_ARPD is not set
+CONFIG_SYN_COOKIES=y
+CONFIG_INET_AH=m
+CONFIG_INET_ESP=m
+CONFIG_INET_IPCOMP=m
+CONFIG_INET_XFRM_TUNNEL=m
+CONFIG_INET_TUNNEL=m
+CONFIG_INET_XFRM_MODE_TRANSPORT=m
+CONFIG_INET_XFRM_MODE_TUNNEL=m
+CONFIG_INET_DIAG=m
+CONFIG_INET_TCP_DIAG=m
+CONFIG_TCP_CONG_ADVANCED=y
+
+#
+# TCP congestion control
+#
+CONFIG_TCP_CONG_BIC=y
+CONFIG_TCP_CONG_CUBIC=m
+CONFIG_TCP_CONG_WESTWOOD=m
+CONFIG_TCP_CONG_HTCP=m
+CONFIG_TCP_CONG_HSTCP=m
+CONFIG_TCP_CONG_HYBLA=m
+CONFIG_TCP_CONG_VEGAS=m
+CONFIG_TCP_CONG_SCALABLE=m
+CONFIG_TCP_CONG_LP=m
+CONFIG_TCP_CONG_VENO=m
+
+#
+# IP: Virtual Server Configuration
+#
+CONFIG_IP_VS=m
+# CONFIG_IP_VS_DEBUG is not set
+CONFIG_IP_VS_TAB_BITS=12
+
+#
+# IPVS transport protocol load balancing support
+#
+CONFIG_IP_VS_PROTO_TCP=y
+CONFIG_IP_VS_PROTO_UDP=y
+CONFIG_IP_VS_PROTO_ESP=y
+CONFIG_IP_VS_PROTO_AH=y
+
+#
+# IPVS scheduler
+#
+CONFIG_IP_VS_RR=m
+CONFIG_IP_VS_WRR=m
+CONFIG_IP_VS_LC=m
+CONFIG_IP_VS_WLC=m
+CONFIG_IP_VS_LBLC=m
+CONFIG_IP_VS_LBLCR=m
+CONFIG_IP_VS_DH=m
+CONFIG_IP_VS_SH=m
+CONFIG_IP_VS_SED=m
+CONFIG_IP_VS_NQ=m
+
+#
+# IPVS application helper
+#
+CONFIG_IP_VS_FTP=m
+CONFIG_IPV6=m
+CONFIG_IPV6_PRIVACY=y
+CONFIG_IPV6_ROUTER_PREF=y
+CONFIG_IPV6_ROUTE_INFO=y
+CONFIG_INET6_AH=m
+CONFIG_INET6_ESP=m
+CONFIG_INET6_IPCOMP=m
+CONFIG_INET6_XFRM_TUNNEL=m
+CONFIG_INET6_TUNNEL=m
+CONFIG_INET6_XFRM_MODE_TRANSPORT=m
+CONFIG_INET6_XFRM_MODE_TUNNEL=m
+CONFIG_IPV6_TUNNEL=m
+CONFIG_NETWORK_SECMARK=y
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_DEBUG is not set
+CONFIG_BRIDGE_NETFILTER=y
+
+#
+# Core Netfilter Configuration
+#
+CONFIG_NETFILTER_NETLINK=m
+CONFIG_NETFILTER_NETLINK_QUEUE=m
+CONFIG_NETFILTER_NETLINK_LOG=m
+CONFIG_NETFILTER_XTABLES=m
+CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
+CONFIG_NETFILTER_XT_TARGET_CONNMARK=m
+CONFIG_NETFILTER_XT_TARGET_MARK=m
+CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
+CONFIG_NETFILTER_XT_TARGET_NOTRACK=m
+CONFIG_NETFILTER_XT_TARGET_SECMARK=m
+CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=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_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_PHYSDEV=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
+
+#
+# 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=m
+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_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_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_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
+CONFIG_IP_NF_ARPTABLES=m
+CONFIG_IP_NF_ARPFILTER=m
+CONFIG_IP_NF_ARP_MANGLE=m
+
+#
+# IPv6: Netfilter Configuration (EXPERIMENTAL)
+#
+CONFIG_IP6_NF_QUEUE=m
+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_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
+
+#
+# DECnet: Netfilter Configuration
+#
+# CONFIG_DECNET_NF_GRABULATOR is not set
+
+#
+# Bridge: Netfilter Configuration
+#
+CONFIG_BRIDGE_NF_EBTABLES=m
+CONFIG_BRIDGE_EBT_BROUTE=m
+CONFIG_BRIDGE_EBT_T_FILTER=m
+CONFIG_BRIDGE_EBT_T_NAT=m
+CONFIG_BRIDGE_EBT_802_3=m
+CONFIG_BRIDGE_EBT_AMONG=m
+CONFIG_BRIDGE_EBT_ARP=m
+CONFIG_BRIDGE_EBT_IP=m
+CONFIG_BRIDGE_EBT_LIMIT=m
+CONFIG_BRIDGE_EBT_MARK=m
+CONFIG_BRIDGE_EBT_PKTTYPE=m
+CONFIG_BRIDGE_EBT_STP=m
+CONFIG_BRIDGE_EBT_VLAN=m
+CONFIG_BRIDGE_EBT_ARPREPLY=m
+CONFIG_BRIDGE_EBT_DNAT=m
+CONFIG_BRIDGE_EBT_MARK_T=m
+CONFIG_BRIDGE_EBT_REDIRECT=m
+CONFIG_BRIDGE_EBT_SNAT=m
+CONFIG_BRIDGE_EBT_LOG=m
+CONFIG_BRIDGE_EBT_ULOG=m
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+CONFIG_IP_DCCP=m
+CONFIG_INET_DCCP_DIAG=m
+CONFIG_IP_DCCP_ACKVEC=y
+
+#
+# DCCP CCIDs Configuration (EXPERIMENTAL)
+#
+CONFIG_IP_DCCP_CCID2=m
+CONFIG_IP_DCCP_CCID3=m
+CONFIG_IP_DCCP_TFRC_LIB=m
+
+#
+# DCCP Kernel Hacking
+#
+# CONFIG_IP_DCCP_DEBUG is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+CONFIG_IP_SCTP=m
+# CONFIG_SCTP_DBG_MSG is not set
+# CONFIG_SCTP_DBG_OBJCNT is not set
+# CONFIG_SCTP_HMAC_NONE is not set
+# CONFIG_SCTP_HMAC_SHA1 is not set
+CONFIG_SCTP_HMAC_MD5=y
+
+#
+# TIPC Configuration (EXPERIMENTAL)
+#
+CONFIG_TIPC=m
+# CONFIG_TIPC_ADVANCED is not set
+# CONFIG_TIPC_DEBUG is not set
+CONFIG_ATM=m
+CONFIG_ATM_CLIP=m
+# CONFIG_ATM_CLIP_NO_ICMP is not set
+CONFIG_ATM_LANE=m
+# CONFIG_ATM_MPOA is not set
+CONFIG_ATM_BR2684=m
+# CONFIG_ATM_BR2684_IPFILTER is not set
+CONFIG_BRIDGE=m
+CONFIG_VLAN_8021Q=m
+CONFIG_DECNET=m
+CONFIG_DECNET_ROUTER=y
+CONFIG_DECNET_ROUTE_FWMARK=y
+CONFIG_LLC=y
+# CONFIG_LLC2 is not set
+CONFIG_IPX=m
+# CONFIG_IPX_INTERN is not set
+CONFIG_ATALK=m
+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_ECONET is not set
+CONFIG_WAN_ROUTER=m
+
+#
+# QoS and/or fair queueing
+#
+CONFIG_NET_SCHED=y
+# CONFIG_NET_SCH_CLK_JIFFIES is not set
+CONFIG_NET_SCH_CLK_GETTIMEOFDAY=y
+# CONFIG_NET_SCH_CLK_CPU is not set
+
+#
+# Queueing/Scheduling
+#
+CONFIG_NET_SCH_CBQ=m
+CONFIG_NET_SCH_HTB=m
+CONFIG_NET_SCH_HFSC=m
+CONFIG_NET_SCH_ATM=m
+CONFIG_NET_SCH_PRIO=m
+CONFIG_NET_SCH_RED=m
+CONFIG_NET_SCH_SFQ=m
+CONFIG_NET_SCH_TEQL=m
+CONFIG_NET_SCH_TBF=m
+CONFIG_NET_SCH_GRED=m
+CONFIG_NET_SCH_DSMARK=m
+CONFIG_NET_SCH_NETEM=m
+CONFIG_NET_SCH_INGRESS=m
+
+#
+# Classification
+#
+CONFIG_NET_CLS=y
+CONFIG_NET_CLS_BASIC=m
+CONFIG_NET_CLS_TCINDEX=m
+CONFIG_NET_CLS_ROUTE4=m
+CONFIG_NET_CLS_ROUTE=y
+CONFIG_NET_CLS_FW=m
+CONFIG_NET_CLS_U32=m
+CONFIG_CLS_U32_PERF=y
+CONFIG_CLS_U32_MARK=y
+CONFIG_NET_CLS_RSVP=m
+CONFIG_NET_CLS_RSVP6=m
+CONFIG_NET_EMATCH=y
+CONFIG_NET_EMATCH_STACK=32
+CONFIG_NET_EMATCH_CMP=m
+CONFIG_NET_EMATCH_NBYTE=m
+CONFIG_NET_EMATCH_U32=m
+CONFIG_NET_EMATCH_META=m
+CONFIG_NET_EMATCH_TEXT=m
+CONFIG_NET_CLS_ACT=y
+CONFIG_NET_ACT_POLICE=m
+CONFIG_NET_ACT_GACT=m
+CONFIG_GACT_PROB=y
+CONFIG_NET_ACT_MIRRED=m
+CONFIG_NET_ACT_IPT=m
+CONFIG_NET_ACT_PEDIT=m
+CONFIG_NET_ACT_SIMP=m
+CONFIG_NET_CLS_IND=y
+CONFIG_NET_ESTIMATOR=y
+
+#
+# Network testing
+#
+CONFIG_NET_PKTGEN=m
+# CONFIG_NET_TCPPROBE is not set
+# CONFIG_HAMRADIO is not set
+CONFIG_IRDA=m
+
+#
+# IrDA protocols
+#
+CONFIG_IRLAN=m
+CONFIG_IRNET=m
+CONFIG_IRCOMM=m
+# CONFIG_IRDA_ULTRA is not set
+
+#
+# IrDA options
+#
+CONFIG_IRDA_CACHE_LAST_LSAP=y
+CONFIG_IRDA_FAST_RR=y
+# CONFIG_IRDA_DEBUG is not set
+
+#
+# Infrared-port device drivers
+#
+
+#
+# SIR device drivers
+#
+CONFIG_IRTTY_SIR=m
+
+#
+# Dongle support
+#
+CONFIG_DONGLE=y
+CONFIG_ESI_DONGLE=m
+CONFIG_ACTISYS_DONGLE=m
+CONFIG_TEKRAM_DONGLE=m
+CONFIG_TOIM3232_DONGLE=m
+CONFIG_LITELINK_DONGLE=m
+CONFIG_MA600_DONGLE=m
+CONFIG_GIRBIL_DONGLE=m
+CONFIG_MCP2120_DONGLE=m
+CONFIG_OLD_BELKIN_DONGLE=m
+CONFIG_ACT200L_DONGLE=m
+
+#
+# Old SIR device drivers
+#
+
+#
+# Old Serial dongle support
+#
+
+#
+# FIR device drivers
+#
+CONFIG_USB_IRDA=m
+CONFIG_SIGMATEL_FIR=m
+CONFIG_NSC_FIR=m
+CONFIG_WINBOND_FIR=m
+CONFIG_SMC_IRCC_FIR=m
+CONFIG_ALI_FIR=m
+CONFIG_VLSI_FIR=m
+CONFIG_VIA_FIR=m
+CONFIG_MCS_FIR=m
+CONFIG_BT=m
+CONFIG_BT_L2CAP=m
+CONFIG_BT_SCO=m
+CONFIG_BT_RFCOMM=m
+CONFIG_BT_RFCOMM_TTY=y
+CONFIG_BT_BNEP=m
+CONFIG_BT_BNEP_MC_FILTER=y
+CONFIG_BT_BNEP_PROTO_FILTER=y
+CONFIG_BT_CMTP=m
+CONFIG_BT_HIDP=m
+
+#
+# Bluetooth device drivers
+#
+CONFIG_BT_HCIUSB=m
+CONFIG_BT_HCIUSB_SCO=y
+CONFIG_BT_HCIUART=m
+CONFIG_BT_HCIUART_H4=y
+CONFIG_BT_HCIUART_BCSP=y
+CONFIG_BT_HCIBCM203X=m
+CONFIG_BT_HCIBPA10X=m
+CONFIG_BT_HCIBFUSB=m
+CONFIG_BT_HCIDTL1=m
+CONFIG_BT_HCIBT3C=m
+CONFIG_BT_HCIBLUECARD=m
+CONFIG_BT_HCIBTUART=m
+CONFIG_BT_HCIVHCI=m
+CONFIG_IEEE80211=m
+# CONFIG_IEEE80211_DEBUG is not set
+CONFIG_IEEE80211_CRYPT_WEP=m
+CONFIG_IEEE80211_CRYPT_CCMP=m
+CONFIG_IEEE80211_CRYPT_TKIP=m
+CONFIG_IEEE80211_SOFTMAC=m
+CONFIG_IEEE80211_SOFTMAC_DEBUG=y
+CONFIG_TUX=m
+
+#
+# TUX options
+#
+CONFIG_TUX_EXTCGI=y
+CONFIG_TUX_EXTENDED_LOG=y
+# CONFIG_TUX_DEBUG is not set
+CONFIG_WIRELESS_EXT=y
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_SYS_HYPERVISOR is not set
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+CONFIG_CONNECTOR=y
+CONFIG_PROC_EVENTS=y
+
+#
+# Memory Technology Devices (MTD)
+#
+CONFIG_MTD=m
+# CONFIG_MTD_DEBUG is not set
+CONFIG_MTD_CONCAT=m
+CONFIG_MTD_PARTITIONS=y
+CONFIG_MTD_REDBOOT_PARTS=m
+CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1
+# CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED is not set
+# CONFIG_MTD_REDBOOT_PARTS_READONLY is not set
+CONFIG_MTD_CMDLINE_PARTS=y
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=m
+CONFIG_MTD_BLOCK=m
+CONFIG_MTD_BLOCK_RO=m
+CONFIG_FTL=m
+CONFIG_NFTL=m
+CONFIG_NFTL_RW=y
+CONFIG_INFTL=m
+CONFIG_RFD_FTL=m
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=m
+CONFIG_MTD_JEDECPROBE=m
+CONFIG_MTD_GEN_PROBE=m
+# CONFIG_MTD_CFI_ADV_OPTIONS 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_CFI_INTELEXT=m
+CONFIG_MTD_CFI_AMDSTD=m
+CONFIG_MTD_CFI_STAA=m
+CONFIG_MTD_CFI_UTIL=m
+CONFIG_MTD_RAM=m
+CONFIG_MTD_ROM=m
+CONFIG_MTD_ABSENT=m
+# CONFIG_MTD_OBSOLETE_CHIPS is not set
+
+#
+# Mapping drivers for chip access
+#
+CONFIG_MTD_COMPLEX_MAPPINGS=y
+# CONFIG_MTD_PHYSMAP is not set
+# CONFIG_MTD_PNC2000 is not set
+CONFIG_MTD_SC520CDP=m
+CONFIG_MTD_NETSC520=m
+CONFIG_MTD_TS5500=m
+# CONFIG_MTD_SBC_GXX is not set
+# CONFIG_MTD_AMD76XROM is not set
+# CONFIG_MTD_ICHXROM is not set
+CONFIG_MTD_SCB2_FLASH=m
+# CONFIG_MTD_NETtel is not set
+# CONFIG_MTD_DILNETPC is not set
+# CONFIG_MTD_L440GX is not set
+CONFIG_MTD_PCI=m
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+CONFIG_MTD_PMC551=m
+# CONFIG_MTD_PMC551_BUGFIX is not set
+# CONFIG_MTD_PMC551_DEBUG is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+CONFIG_MTD_MTDRAM=m
+CONFIG_MTDRAM_TOTAL_SIZE=4096
+CONFIG_MTDRAM_ERASE_SIZE=128
+CONFIG_MTD_BLOCK2MTD=m
+
+#
+# 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=m
+# CONFIG_MTD_NAND_VERIFY_WRITE is not set
+CONFIG_MTD_NAND_ECC_SMC=y
+CONFIG_MTD_NAND_IDS=m
+CONFIG_MTD_NAND_DISKONCHIP=m
+# CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADVANCED is not set
+CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADDRESS=0
+# CONFIG_MTD_NAND_DISKONCHIP_BBTWRITE is not set
+CONFIG_MTD_NAND_NANDSIM=m
+
+#
+# OneNAND Flash Device Drivers
+#
+# CONFIG_MTD_ONENAND is not set
+
+#
+# Parallel port support
+#
+CONFIG_PARPORT=m
+CONFIG_PARPORT_PC=m
+CONFIG_PARPORT_SERIAL=m
+# CONFIG_PARPORT_PC_FIFO is not set
+# CONFIG_PARPORT_PC_SUPERIO is not set
+CONFIG_PARPORT_PC_PCMCIA=m
+CONFIG_PARPORT_NOT_PC=y
+# CONFIG_PARPORT_GSC is not set
+# CONFIG_PARPORT_AX88796 is not set
+CONFIG_PARPORT_1284=y
+
+#
+# Plug and Play support
+#
+CONFIG_PNP=y
+# CONFIG_PNP_DEBUG is not set
+
+#
+# Protocols
+#
+CONFIG_PNPACPI=y
+
+#
+# Block devices
+#
+CONFIG_BLK_DEV_FD=m
+CONFIG_PARIDE=m
+CONFIG_PARIDE_PARPORT=m
+
+#
+# Parallel IDE high-level drivers
+#
+CONFIG_PARIDE_PD=m
+CONFIG_PARIDE_PCD=m
+CONFIG_PARIDE_PF=m
+CONFIG_PARIDE_PT=m
+CONFIG_PARIDE_PG=m
+
+#
+# Parallel IDE protocol modules
+#
+CONFIG_PARIDE_ATEN=m
+CONFIG_PARIDE_BPCK=m
+CONFIG_PARIDE_COMM=m
+CONFIG_PARIDE_DSTR=m
+CONFIG_PARIDE_FIT2=m
+CONFIG_PARIDE_FIT3=m
+CONFIG_PARIDE_EPAT=m
+CONFIG_PARIDE_EPATC8=y
+CONFIG_PARIDE_EPIA=m
+CONFIG_PARIDE_FRIQ=m
+CONFIG_PARIDE_FRPW=m
+CONFIG_PARIDE_KBIC=m
+CONFIG_PARIDE_KTTI=m
+CONFIG_PARIDE_ON20=m
+CONFIG_PARIDE_ON26=m
+CONFIG_BLK_CPQ_DA=m
+CONFIG_BLK_CPQ_CISS_DA=m
+CONFIG_CISS_SCSI_TAPE=y
+CONFIG_BLK_DEV_DAC960=m
+CONFIG_BLK_DEV_UMEM=m
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=m
+CONFIG_BLK_DEV_CRYPTOLOOP=m
+CONFIG_BLK_DEV_NBD=m
+CONFIG_BLK_DEV_SX8=m
+CONFIG_BLK_DEV_UB=m
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=16384
+CONFIG_BLK_DEV_RAM_BLOCKSIZE=4096
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_CDROM_PKTCDVD=m
+CONFIG_CDROM_PKTCDVD_BUFFERS=8
+# CONFIG_CDROM_PKTCDVD_WCACHE is not set
+CONFIG_ATA_OVER_ETH=m
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+CONFIG_IDE=y
+CONFIG_BLK_DEV_IDE=y
+
+#
+# Please see Documentation/ide.txt for help/info on IDE drives
+#
+# CONFIG_BLK_DEV_IDE_SATA is not set
+# CONFIG_BLK_DEV_HD_IDE is not set
+CONFIG_BLK_DEV_IDEDISK=y
+CONFIG_IDEDISK_MULTI_MODE=y
+CONFIG_BLK_DEV_IDECS=m
+CONFIG_BLK_DEV_IDECD=m
+# CONFIG_BLK_DEV_IDETAPE is not set
+CONFIG_BLK_DEV_IDEFLOPPY=y
+CONFIG_BLK_DEV_IDESCSI=m
+CONFIG_IDE_TASK_IOCTL=y
+
+#
+# IDE chipset support/bugfixes
+#
+CONFIG_IDE_GENERIC=y
+# CONFIG_BLK_DEV_CMD640 is not set
+CONFIG_BLK_DEV_IDEPNP=y
+CONFIG_BLK_DEV_IDEPCI=y
+CONFIG_IDEPCI_SHARE_IRQ=y
+# CONFIG_BLK_DEV_OFFBOARD is not set
+CONFIG_BLK_DEV_GENERIC=y
+# CONFIG_BLK_DEV_OPTI621 is not set
+# CONFIG_BLK_DEV_RZ1000 is not set
+CONFIG_BLK_DEV_IDEDMA_PCI=y
+# CONFIG_BLK_DEV_IDEDMA_FORCED is not set
+CONFIG_IDEDMA_PCI_AUTO=y
+# CONFIG_IDEDMA_ONLYDISK is not set
+CONFIG_BLK_DEV_AEC62XX=y
+CONFIG_BLK_DEV_ALI15X3=y
+# CONFIG_WDC_ALI15X3 is not set
+CONFIG_BLK_DEV_AMD74XX=y
+CONFIG_BLK_DEV_ATIIXP=y
+CONFIG_BLK_DEV_CMD64X=y
+# CONFIG_BLK_DEV_TRIFLEX is not set
+# CONFIG_BLK_DEV_CY82C693 is not set
+# CONFIG_BLK_DEV_CS5520 is not set
+# CONFIG_BLK_DEV_CS5530 is not set
+CONFIG_BLK_DEV_HPT34X=y
+# CONFIG_HPT34X_AUTODMA is not set
+CONFIG_BLK_DEV_HPT366=y
+# CONFIG_BLK_DEV_SC1200 is not set
+CONFIG_BLK_DEV_PIIX=y
+CONFIG_BLK_DEV_IT821X=y
+# CONFIG_BLK_DEV_NS87415 is not set
+CONFIG_BLK_DEV_PDC202XX_OLD=y
+# CONFIG_PDC202XX_BURST is not set
+CONFIG_BLK_DEV_PDC202XX_NEW=y
+CONFIG_BLK_DEV_SVWKS=y
+CONFIG_BLK_DEV_SIIMAGE=y
+CONFIG_BLK_DEV_SIS5513=y
+# CONFIG_BLK_DEV_SLC90E66 is not set
+# CONFIG_BLK_DEV_TRM290 is not set
+CONFIG_BLK_DEV_VIA82CXXX=y
+# CONFIG_IDE_ARM is not set
+CONFIG_BLK_DEV_IDEDMA=y
+# CONFIG_IDEDMA_IVB is not set
+CONFIG_IDEDMA_AUTO=y
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# SCSI device support
+#
+CONFIG_RAID_ATTRS=m
+CONFIG_SCSI=m
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=m
+CONFIG_CHR_DEV_ST=m
+CONFIG_CHR_DEV_OSST=m
+CONFIG_BLK_DEV_SR=m
+CONFIG_BLK_DEV_SR_VENDOR=y
+CONFIG_CHR_DEV_SG=m
+CONFIG_CHR_DEV_SCH=m
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+CONFIG_SCSI_MULTI_LUN=y
+CONFIG_SCSI_CONSTANTS=y
+CONFIG_SCSI_LOGGING=y
+
+#
+# SCSI Transport Attributes
+#
+CONFIG_SCSI_SPI_ATTRS=m
+CONFIG_SCSI_FC_ATTRS=m
+CONFIG_SCSI_ISCSI_ATTRS=m
+CONFIG_SCSI_SAS_ATTRS=m
+
+#
+# SCSI low-level drivers
+#
+CONFIG_ISCSI_TCP=m
+CONFIG_BLK_DEV_3W_XXXX_RAID=m
+CONFIG_SCSI_3W_9XXX=m
+CONFIG_SCSI_ACARD=m
+CONFIG_SCSI_AACRAID=m
+CONFIG_SCSI_AIC7XXX=m
+CONFIG_AIC7XXX_CMDS_PER_DEVICE=4
+CONFIG_AIC7XXX_RESET_DELAY_MS=15000
+# CONFIG_AIC7XXX_DEBUG_ENABLE is not set
+CONFIG_AIC7XXX_DEBUG_MASK=0
+# CONFIG_AIC7XXX_REG_PRETTY_PRINT is not set
+CONFIG_SCSI_AIC7XXX_OLD=m
+CONFIG_SCSI_AIC79XX=m
+CONFIG_AIC79XX_CMDS_PER_DEVICE=4
+CONFIG_AIC79XX_RESET_DELAY_MS=15000
+# CONFIG_AIC79XX_ENABLE_RD_STRM is not set
+# CONFIG_AIC79XX_DEBUG_ENABLE is not set
+CONFIG_AIC79XX_DEBUG_MASK=0
+# CONFIG_AIC79XX_REG_PRETTY_PRINT is not set
+CONFIG_MEGARAID_NEWGEN=y
+CONFIG_MEGARAID_MM=m
+CONFIG_MEGARAID_MAILBOX=m
+CONFIG_MEGARAID_LEGACY=m
+CONFIG_MEGARAID_SAS=m
+CONFIG_SCSI_SATA=m
+CONFIG_SCSI_SATA_AHCI=m
+CONFIG_SCSI_SATA_SVW=m
+CONFIG_SCSI_ATA_PIIX=m
+CONFIG_SCSI_SATA_MV=m
+CONFIG_SCSI_SATA_NV=m
+CONFIG_SCSI_PDC_ADMA=m
+CONFIG_SCSI_HPTIOP=m
+CONFIG_SCSI_SATA_QSTOR=m
+CONFIG_SCSI_SATA_PROMISE=m
+CONFIG_SCSI_SATA_SX4=m
+CONFIG_SCSI_SATA_SIL=m
+CONFIG_SCSI_SATA_SIL24=m
+CONFIG_SCSI_SATA_SIS=m
+CONFIG_SCSI_SATA_ULI=m
+CONFIG_SCSI_SATA_VIA=m
+CONFIG_SCSI_SATA_VITESSE=m
+CONFIG_SCSI_SATA_INTEL_COMBINED=y
+CONFIG_SCSI_BUSLOGIC=m
+# CONFIG_SCSI_OMIT_FLASHPOINT is not set
+# CONFIG_SCSI_DMX3191D is not set
+# CONFIG_SCSI_EATA is not set
+# CONFIG_SCSI_FUTURE_DOMAIN is not set
+CONFIG_SCSI_GDTH=m
+CONFIG_SCSI_IPS=m
+CONFIG_SCSI_INITIO=m
+CONFIG_SCSI_INIA100=m
+CONFIG_SCSI_PPA=m
+CONFIG_SCSI_IMM=m
+# CONFIG_SCSI_IZIP_EPP16 is not set
+# CONFIG_SCSI_IZIP_SLOW_CTR is not set
+CONFIG_SCSI_SYM53C8XX_2=m
+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_QLOGIC_1280=m
+CONFIG_SCSI_QLA_FC=m
+CONFIG_SCSI_LPFC=m
+CONFIG_SCSI_DC395x=m
+CONFIG_SCSI_DC390T=m
+# CONFIG_SCSI_DEBUG is not set
+
+#
+# PCMCIA SCSI adapter support
+#
+# CONFIG_PCMCIA_FDOMAIN is not set
+CONFIG_PCMCIA_QLOGIC=m
+CONFIG_PCMCIA_SYM53C500=m
+
+#
+# Multi-device support (RAID and LVM)
+#
+CONFIG_MD=y
+CONFIG_BLK_DEV_MD=y
+CONFIG_MD_LINEAR=m
+CONFIG_MD_RAID0=m
+CONFIG_MD_RAID1=m
+CONFIG_MD_RAID10=m
+CONFIG_MD_RAID456=m
+CONFIG_MD_RAID5_RESHAPE=y
+CONFIG_MD_MULTIPATH=m
+CONFIG_MD_FAULTY=m
+CONFIG_BLK_DEV_DM=m
+CONFIG_DM_CRYPT=m
+CONFIG_DM_SNAPSHOT=m
+CONFIG_DM_MIRROR=m
+CONFIG_DM_ZERO=m
+CONFIG_DM_MULTIPATH=m
+CONFIG_DM_MULTIPATH_EMC=m
+
+#
+# Fusion MPT device support
+#
+CONFIG_FUSION=y
+CONFIG_FUSION_SPI=m
+CONFIG_FUSION_FC=m
+CONFIG_FUSION_SAS=m
+CONFIG_FUSION_MAX_SGE=40
+CONFIG_FUSION_CTL=m
+CONFIG_FUSION_LAN=m
+
+#
+# IEEE 1394 (FireWire) support
+#
+CONFIG_IEEE1394=m
+
+#
+# Subsystem Options
+#
+# CONFIG_IEEE1394_VERBOSEDEBUG is not set
+CONFIG_IEEE1394_OUI_DB=y
+CONFIG_IEEE1394_EXTRA_CONFIG_ROMS=y
+CONFIG_IEEE1394_CONFIG_ROM_IP1394=y
+# CONFIG_IEEE1394_EXPORT_FULL_API is not set
+
+#
+# Device Drivers
+#
+CONFIG_IEEE1394_PCILYNX=m
+CONFIG_IEEE1394_OHCI1394=m
+
+#
+# Protocol Drivers
+#
+CONFIG_IEEE1394_VIDEO1394=m
+CONFIG_IEEE1394_SBP2=m
+CONFIG_IEEE1394_ETH1394=m
+CONFIG_IEEE1394_DV1394=m
+CONFIG_IEEE1394_RAWIO=m
+
+#
+# I2O device support
+#
+CONFIG_I2O=m
+# CONFIG_I2O_LCT_NOTIFY_ON_CHANGES is not set
+CONFIG_I2O_EXT_ADAPTEC=y
+CONFIG_I2O_EXT_ADAPTEC_DMA64=y
+CONFIG_I2O_CONFIG=m
+CONFIG_I2O_CONFIG_OLD_IOCTL=y
+CONFIG_I2O_BUS=m
+CONFIG_I2O_BLOCK=m
+CONFIG_I2O_SCSI=m
+CONFIG_I2O_PROC=m
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+CONFIG_IFB=m
+CONFIG_DUMMY=m
+CONFIG_BONDING=m
+CONFIG_EQUALIZER=m
+CONFIG_TUN=m
+CONFIG_NET_SB1000=m
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+
+#
+# PHY device support
+#
+CONFIG_PHYLIB=m
+
+#
+# MII PHY device drivers
+#
+CONFIG_MARVELL_PHY=m
+CONFIG_DAVICOM_PHY=m
+CONFIG_QSEMI_PHY=m
+CONFIG_LXT_PHY=m
+CONFIG_CICADA_PHY=m
+CONFIG_VITESSE_PHY=m
+CONFIG_SMSC_PHY=m
+CONFIG_FIXED_PHY=m
+CONFIG_FIXED_MII_10_FDX=y
+CONFIG_FIXED_MII_100_FDX=y
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=m
+CONFIG_HAPPYMEAL=m
+CONFIG_SUNGEM=m
+CONFIG_CASSINI=m
+CONFIG_NET_VENDOR_3COM=y
+CONFIG_VORTEX=m
+CONFIG_TYPHOON=m
+
+#
+# Tulip family network device support
+#
+CONFIG_NET_TULIP=y
+CONFIG_DE2104X=m
+CONFIG_TULIP=m
+# CONFIG_TULIP_MWI is not set
+CONFIG_TULIP_MMIO=y
+# CONFIG_TULIP_NAPI is not set
+CONFIG_DE4X5=m
+CONFIG_WINBOND_840=m
+CONFIG_DM9102=m
+CONFIG_ULI526X=m
+CONFIG_PCMCIA_XIRCOM=m
+# CONFIG_HP100 is not set
+CONFIG_NET_PCI=y
+CONFIG_PCNET32=m
+CONFIG_AMD8111_ETH=m
+CONFIG_AMD8111E_NAPI=y
+CONFIG_ADAPTEC_STARFIRE=m
+CONFIG_ADAPTEC_STARFIRE_NAPI=y
+CONFIG_B44=m
+CONFIG_FORCEDETH=m
+# CONFIG_DGRS is not set
+# CONFIG_EEPRO100 is not set
+CONFIG_E100=m
+CONFIG_FEALNX=m
+CONFIG_NATSEMI=m
+CONFIG_NE2K_PCI=m
+CONFIG_8139CP=m
+CONFIG_8139TOO=m
+# CONFIG_8139TOO_PIO is not set
+# CONFIG_8139TOO_TUNE_TWISTER is not set
+CONFIG_8139TOO_8129=y
+# CONFIG_8139_OLD_RX_RESET is not set
+CONFIG_SIS900=m
+CONFIG_EPIC100=m
+CONFIG_SUNDANCE=m
+# CONFIG_SUNDANCE_MMIO is not set
+CONFIG_VIA_RHINE=m
+CONFIG_VIA_RHINE_MMIO=y
+CONFIG_VIA_RHINE_NAPI=y
+CONFIG_NET_POCKET=y
+CONFIG_ATP=m
+CONFIG_DE600=m
+CONFIG_DE620=m
+
+#
+# Ethernet (1000 Mbit)
+#
+CONFIG_ACENIC=m
+# CONFIG_ACENIC_OMIT_TIGON_I is not set
+CONFIG_DL2K=m
+CONFIG_E1000=m
+CONFIG_E1000_NAPI=y
+# CONFIG_E1000_DISABLE_PACKET_SPLIT is not set
+CONFIG_NS83820=m
+CONFIG_HAMACHI=m
+CONFIG_YELLOWFIN=m
+CONFIG_R8169=m
+CONFIG_R8169_NAPI=y
+CONFIG_R8169_VLAN=y
+CONFIG_SIS190=m
+CONFIG_SKGE=m
+CONFIG_SKY2=m
+# CONFIG_SK98LIN is not set
+CONFIG_VIA_VELOCITY=m
+CONFIG_TIGON3=m
+CONFIG_BNX2=m
+
+#
+# Ethernet (10000 Mbit)
+#
+CONFIG_CHELSIO_T1=m
+CONFIG_IXGB=m
+CONFIG_IXGB_NAPI=y
+CONFIG_S2IO=m
+CONFIG_S2IO_NAPI=y
+CONFIG_MYRI10GE=m
+
+#
+# Token Ring devices
+#
+CONFIG_TR=y
+CONFIG_IBMOL=m
+CONFIG_3C359=m
+# CONFIG_TMS380TR is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+CONFIG_NET_RADIO=y
+CONFIG_NET_WIRELESS_RTNETLINK=y
+
+#
+# Obsolete Wireless cards support (pre-802.11)
+#
+# CONFIG_STRIP is not set
+CONFIG_PCMCIA_WAVELAN=m
+CONFIG_PCMCIA_NETWAVE=m
+
+#
+# Wireless 802.11 Frequency Hopping cards support
+#
+# CONFIG_PCMCIA_RAYCS is not set
+
+#
+# Wireless 802.11b ISA/PCI cards support
+#
+CONFIG_IPW2100=m
+CONFIG_IPW2100_MONITOR=y
+# CONFIG_IPW2100_DEBUG is not set
+CONFIG_IPW2200=m
+CONFIG_IPW2200_MONITOR=y
+CONFIG_IPW2200_RADIOTAP=y
+CONFIG_IPW2200_PROMISCUOUS=y
+CONFIG_IPW2200_QOS=y
+# CONFIG_IPW2200_DEBUG is not set
+CONFIG_AIRO=m
+CONFIG_HERMES=m
+CONFIG_PLX_HERMES=m
+CONFIG_TMD_HERMES=m
+CONFIG_NORTEL_HERMES=m
+CONFIG_PCI_HERMES=m
+CONFIG_ATMEL=m
+CONFIG_PCI_ATMEL=m
+
+#
+# Wireless 802.11b Pcmcia/Cardbus cards support
+#
+CONFIG_PCMCIA_HERMES=m
+CONFIG_PCMCIA_SPECTRUM=m
+CONFIG_AIRO_CS=m
+CONFIG_PCMCIA_ATMEL=m
+CONFIG_PCMCIA_WL3501=m
+
+#
+# Prism GT/Duette 802.11(a/b/g) PCI/Cardbus support
+#
+CONFIG_PRISM54=m
+CONFIG_USB_ZD1201=m
+CONFIG_HOSTAP=m
+CONFIG_HOSTAP_FIRMWARE=y
+CONFIG_HOSTAP_FIRMWARE_NVRAM=y
+CONFIG_HOSTAP_PLX=m
+CONFIG_HOSTAP_PCI=m
+CONFIG_HOSTAP_CS=m
+CONFIG_BCM43XX=m
+CONFIG_BCM43XX_DEBUG=y
+CONFIG_BCM43XX_DMA=y
+CONFIG_BCM43XX_PIO=y
+CONFIG_BCM43XX_DMA_AND_PIO_MODE=y
+# CONFIG_BCM43XX_DMA_MODE is not set
+# CONFIG_BCM43XX_PIO_MODE is not set
+CONFIG_ZD1211RW=m
+# CONFIG_ZD1211RW_DEBUG is not set
+CONFIG_NET_WIRELESS=y
+
+#
+# PCMCIA network device support
+#
+CONFIG_NET_PCMCIA=y
+CONFIG_PCMCIA_3C589=m
+CONFIG_PCMCIA_3C574=m
+CONFIG_PCMCIA_FMVJ18X=m
+CONFIG_PCMCIA_PCNET=m
+CONFIG_PCMCIA_NMCLAN=m
+CONFIG_PCMCIA_SMC91C92=m
+CONFIG_PCMCIA_XIRC2PS=m
+CONFIG_PCMCIA_AXNET=m
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+
+#
+# ATM drivers
+#
+# CONFIG_ATM_DUMMY is not set
+CONFIG_ATM_TCP=m
+CONFIG_ATM_LANAI=m
+CONFIG_ATM_ENI=m
+# CONFIG_ATM_ENI_DEBUG is not set
+# CONFIG_ATM_ENI_TUNE_BURST is not set
+CONFIG_ATM_FIRESTREAM=m
+# CONFIG_ATM_ZATM is not set
+CONFIG_ATM_IDT77252=m
+# CONFIG_ATM_IDT77252_DEBUG is not set
+# CONFIG_ATM_IDT77252_RCV_ALL is not set
+CONFIG_ATM_IDT77252_USE_SUNI=y
+CONFIG_ATM_AMBASSADOR=m
+# CONFIG_ATM_AMBASSADOR_DEBUG is not set
+CONFIG_ATM_HORIZON=m
+# CONFIG_ATM_HORIZON_DEBUG is not set
+CONFIG_ATM_FORE200E_MAYBE=m
+# CONFIG_ATM_FORE200E_PCA is not set
+CONFIG_ATM_HE=m
+# CONFIG_ATM_HE_USE_SUNI is not set
+CONFIG_FDDI=y
+# CONFIG_DEFXX is not set
+CONFIG_SKFP=m
+# CONFIG_HIPPI is not set
+CONFIG_PLIP=m
+CONFIG_PPP=m
+CONFIG_PPP_MULTILINK=y
+CONFIG_PPP_FILTER=y
+CONFIG_PPP_ASYNC=m
+CONFIG_PPP_SYNC_TTY=m
+CONFIG_PPP_DEFLATE=m
+# CONFIG_PPP_BSDCOMP is not set
+CONFIG_PPP_MPPE=m
+CONFIG_PPPOE=m
+CONFIG_PPPOATM=m
+CONFIG_SLIP=m
+CONFIG_SLIP_COMPRESSED=y
+CONFIG_SLIP_SMART=y
+# CONFIG_SLIP_MODE_SLIP6 is not set
+CONFIG_NET_FC=y
+# CONFIG_SHAPER is not set
+CONFIG_NETCONSOLE=m
+CONFIG_NETPOLL=y
+# CONFIG_NETPOLL_RX is not set
+CONFIG_NETPOLL_TRAP=y
+CONFIG_NET_POLL_CONTROLLER=y
+
+#
+# ISDN subsystem
+#
+CONFIG_ISDN=m
+
+#
+# Old ISDN4Linux
+#
+CONFIG_ISDN_I4L=m
+CONFIG_ISDN_PPP=y
+CONFIG_ISDN_PPP_VJ=y
+CONFIG_ISDN_MPP=y
+CONFIG_IPPP_FILTER=y
+# CONFIG_ISDN_PPP_BSDCOMP is not set
+CONFIG_ISDN_AUDIO=y
+CONFIG_ISDN_TTY_FAX=y
+
+#
+# ISDN feature submodules
+#
+CONFIG_ISDN_DIVERSION=m
+
+#
+# ISDN4Linux hardware drivers
+#
+
+#
+# Passive cards
+#
+CONFIG_ISDN_DRV_HISAX=m
+
+#
+# D-channel protocol features
+#
+CONFIG_HISAX_EURO=y
+CONFIG_DE_AOC=y
+CONFIG_HISAX_NO_SENDCOMPLETE=y
+CONFIG_HISAX_NO_LLC=y
+CONFIG_HISAX_NO_KEYPAD=y
+CONFIG_HISAX_1TR6=y
+CONFIG_HISAX_NI1=y
+CONFIG_HISAX_MAX_CARDS=8
+
+#
+# HiSax supported cards
+#
+CONFIG_HISAX_16_3=y
+CONFIG_HISAX_TELESPCI=y
+CONFIG_HISAX_S0BOX=y
+CONFIG_HISAX_FRITZPCI=y
+CONFIG_HISAX_AVM_A1_PCMCIA=y
+CONFIG_HISAX_ELSA=y
+CONFIG_HISAX_DIEHLDIVA=y
+CONFIG_HISAX_SEDLBAUER=y
+CONFIG_HISAX_NETJET=y
+CONFIG_HISAX_NETJET_U=y
+CONFIG_HISAX_NICCY=y
+CONFIG_HISAX_BKM_A4T=y
+CONFIG_HISAX_SCT_QUADRO=y
+CONFIG_HISAX_GAZEL=y
+CONFIG_HISAX_HFC_PCI=y
+CONFIG_HISAX_W6692=y
+CONFIG_HISAX_HFC_SX=y
+CONFIG_HISAX_ENTERNOW_PCI=y
+# CONFIG_HISAX_DEBUG is not set
+
+#
+# HiSax PCMCIA card service modules
+#
+CONFIG_HISAX_SEDLBAUER_CS=m
+CONFIG_HISAX_ELSA_CS=m
+CONFIG_HISAX_AVM_A1_CS=m
+CONFIG_HISAX_TELES_CS=m
+
+#
+# HiSax sub driver modules
+#
+CONFIG_HISAX_ST5481=m
+# CONFIG_HISAX_HFCUSB is not set
+CONFIG_HISAX_HFC4S8S=m
+CONFIG_HISAX_FRITZ_PCIPNP=m
+CONFIG_HISAX_HDLC=y
+
+#
+# Active cards
+#
+
+#
+# Siemens Gigaset
+#
+CONFIG_ISDN_DRV_GIGASET=m
+CONFIG_GIGASET_BASE=m
+CONFIG_GIGASET_M105=m
+# CONFIG_GIGASET_DEBUG is not set
+# CONFIG_GIGASET_UNDOCREQ is not set
+
+#
+# CAPI subsystem
+#
+CONFIG_ISDN_CAPI=m
+CONFIG_ISDN_DRV_AVMB1_VERBOSE_REASON=y
+CONFIG_ISDN_CAPI_MIDDLEWARE=y
+CONFIG_ISDN_CAPI_CAPI20=m
+CONFIG_ISDN_CAPI_CAPIFS_BOOL=y
+CONFIG_ISDN_CAPI_CAPIFS=m
+CONFIG_ISDN_CAPI_CAPIDRV=m
+
+#
+# CAPI hardware drivers
+#
+
+#
+# Active AVM cards
+#
+CONFIG_CAPI_AVM=y
+CONFIG_ISDN_DRV_AVMB1_B1PCI=m
+CONFIG_ISDN_DRV_AVMB1_B1PCIV4=y
+CONFIG_ISDN_DRV_AVMB1_B1PCMCIA=m
+CONFIG_ISDN_DRV_AVMB1_AVM_CS=m
+CONFIG_ISDN_DRV_AVMB1_T1PCI=m
+CONFIG_ISDN_DRV_AVMB1_C4=m
+
+#
+# Active Eicon DIVA Server cards
+#
+# CONFIG_CAPI_EICON is not set
+
+#
+# Telephony Support
+#
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+
+#
+# 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=m
+# CONFIG_INPUT_TSDEV is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+CONFIG_KEYBOARD_ATKBD=y
+# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_KEYBOARD_LKKBD is not set
+# CONFIG_KEYBOARD_XTKBD is not set
+# CONFIG_KEYBOARD_NEWTON is not set
+CONFIG_INPUT_MOUSE=y
+CONFIG_MOUSE_PS2=y
+CONFIG_MOUSE_SERIAL=m
+CONFIG_MOUSE_VSXXXAA=m
+CONFIG_INPUT_JOYSTICK=y
+CONFIG_JOYSTICK_ANALOG=m
+CONFIG_JOYSTICK_A3D=m
+CONFIG_JOYSTICK_ADI=m
+CONFIG_JOYSTICK_COBRA=m
+CONFIG_JOYSTICK_GF2K=m
+CONFIG_JOYSTICK_GRIP=m
+CONFIG_JOYSTICK_GRIP_MP=m
+CONFIG_JOYSTICK_GUILLEMOT=m
+CONFIG_JOYSTICK_INTERACT=m
+CONFIG_JOYSTICK_SIDEWINDER=m
+CONFIG_JOYSTICK_TMDC=m
+CONFIG_JOYSTICK_IFORCE=m
+CONFIG_JOYSTICK_IFORCE_USB=y
+CONFIG_JOYSTICK_IFORCE_232=y
+CONFIG_JOYSTICK_WARRIOR=m
+CONFIG_JOYSTICK_MAGELLAN=m
+CONFIG_JOYSTICK_SPACEORB=m
+CONFIG_JOYSTICK_SPACEBALL=m
+CONFIG_JOYSTICK_STINGER=m
+CONFIG_JOYSTICK_TWIDJOY=m
+CONFIG_JOYSTICK_DB9=m
+CONFIG_JOYSTICK_GAMECON=m
+CONFIG_JOYSTICK_TURBOGRAFX=m
+CONFIG_JOYSTICK_JOYDUMP=m
+CONFIG_INPUT_TOUCHSCREEN=y
+CONFIG_TOUCHSCREEN_GUNZE=m
+CONFIG_TOUCHSCREEN_ELO=m
+CONFIG_TOUCHSCREEN_MTOUCH=m
+CONFIG_TOUCHSCREEN_MK712=m
+CONFIG_INPUT_MISC=y
+CONFIG_INPUT_PCSPKR=m
+CONFIG_INPUT_UINPUT=m
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+CONFIG_SERIO_I8042=y
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_CT82C710 is not set
+# CONFIG_SERIO_PARKBD is not set
+# CONFIG_SERIO_PCIPS2 is not set
+CONFIG_SERIO_LIBPS2=y
+CONFIG_SERIO_RAW=m
+CONFIG_GAMEPORT=m
+CONFIG_GAMEPORT_NS558=m
+CONFIG_GAMEPORT_L4=m
+CONFIG_GAMEPORT_EMU10K1=m
+CONFIG_GAMEPORT_FM801=m
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+CONFIG_VT_HW_CONSOLE_BINDING=y
+CONFIG_SERIAL_NONSTANDARD=y
+# CONFIG_COMPUTONE is not set
+# CONFIG_ROCKETPORT is not set
+CONFIG_CYCLADES=m
+# CONFIG_CYZ_INTR is not set
+# CONFIG_DIGIEPCA is not set
+# CONFIG_MOXA_INTELLIO is not set
+# CONFIG_MOXA_SMARTIO is not set
+# CONFIG_ISI is not set
+CONFIG_SYNCLINK=m
+CONFIG_SYNCLINKMP=m
+CONFIG_SYNCLINK_GT=m
+CONFIG_N_HDLC=m
+# CONFIG_SPECIALIX is not set
+# CONFIG_SX is not set
+# CONFIG_RIO is not set
+# CONFIG_STALDRV is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=m
+CONFIG_SERIAL_8250_PCI=m
+CONFIG_SERIAL_8250_PNP=m
+CONFIG_SERIAL_8250_CS=m
+CONFIG_SERIAL_8250_NR_UARTS=32
+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=y
+CONFIG_SERIAL_8250_RSA=y
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_CORE=m
+CONFIG_SERIAL_JSM=m
+CONFIG_UNIX98_PTYS=y
+# CONFIG_LEGACY_PTYS is not set
+CONFIG_CRASH=m
+CONFIG_PRINTER=m
+CONFIG_LP_CONSOLE=y
+CONFIG_PPDEV=m
+CONFIG_TIPAR=m
+
+#
+# IPMI
+#
+CONFIG_IPMI_HANDLER=m
+# CONFIG_IPMI_PANIC_EVENT is not set
+CONFIG_IPMI_DEVICE_INTERFACE=m
+CONFIG_IPMI_SI=m
+CONFIG_IPMI_WATCHDOG=m
+CONFIG_IPMI_POWEROFF=m
+
+#
+# Watchdog Cards
+#
+CONFIG_WATCHDOG=y
+# CONFIG_WATCHDOG_NOWAYOUT is not set
+
+#
+# Watchdog Device Drivers
+#
+CONFIG_SOFT_WATCHDOG=m
+# CONFIG_ACQUIRE_WDT is not set
+# CONFIG_ADVANTECH_WDT is not set
+CONFIG_ALIM1535_WDT=m
+CONFIG_ALIM7101_WDT=m
+# CONFIG_SC520_WDT is not set
+# CONFIG_EUROTECH_WDT is not set
+# CONFIG_IB700_WDT is not set
+CONFIG_IBMASR=m
+# CONFIG_WAFER_WDT is not set
+CONFIG_I6300ESB_WDT=m
+CONFIG_I8XX_TCO=m
+# CONFIG_SC1200_WDT is not set
+# CONFIG_60XX_WDT is not set
+# CONFIG_SBC8360_WDT is not set
+# CONFIG_CPU5_WDT is not set
+CONFIG_W83627HF_WDT=m
+CONFIG_W83877F_WDT=m
+CONFIG_W83977F_WDT=m
+CONFIG_MACHZ_WDT=m
+# CONFIG_SBC_EPX_C3_WATCHDOG is not set
+
+#
+# PCI-based Watchdog Cards
+#
+CONFIG_PCIPCWATCHDOG=m
+CONFIG_WDTPCI=m
+CONFIG_WDT_501_PCI=y
+
+#
+# USB-based Watchdog Cards
+#
+CONFIG_USBPCWATCHDOG=m
+CONFIG_HW_RANDOM=y
+CONFIG_HW_RANDOM_INTEL=m
+CONFIG_HW_RANDOM_AMD=m
+# CONFIG_HW_RANDOM_GEODE is not set
+CONFIG_NVRAM=y
+CONFIG_RTC=y
+CONFIG_DTLK=m
+CONFIG_R3964=m
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+CONFIG_AGP=y
+CONFIG_AGP_AMD64=y
+CONFIG_AGP_INTEL=y
+CONFIG_AGP_SIS=y
+CONFIG_AGP_VIA=y
+CONFIG_DRM=m
+CONFIG_DRM_TDFX=m
+CONFIG_DRM_R128=m
+CONFIG_DRM_RADEON=m
+CONFIG_DRM_I810=m
+CONFIG_DRM_I830=m
+CONFIG_DRM_I915=m
+CONFIG_DRM_MGA=m
+CONFIG_DRM_SIS=m
+CONFIG_DRM_VIA=m
+CONFIG_DRM_SAVAGE=m
+
+#
+# PCMCIA character devices
+#
+# CONFIG_SYNCLINK_CS is not set
+CONFIG_CARDMAN_4000=m
+CONFIG_CARDMAN_4040=m
+CONFIG_MWAVE=m
+CONFIG_PC8736x_GPIO=m
+CONFIG_NSC_GPIO=m
+# CONFIG_RAW_DRIVER is not set
+CONFIG_HPET=y
+# CONFIG_HPET_RTC_IRQ is not set
+# CONFIG_HPET_MMAP is not set
+CONFIG_HANGCHECK_TIMER=m
+
+#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+# CONFIG_TELCLOCK is not set
+
+#
+# I2C support
+#
+CONFIG_I2C=m
+CONFIG_I2C_CHARDEV=m
+
+#
+# I2C Algorithms
+#
+CONFIG_I2C_ALGOBIT=m
+CONFIG_I2C_ALGOPCF=m
+CONFIG_I2C_ALGOPCA=m
+
+#
+# I2C Hardware Bus support
+#
+# CONFIG_I2C_ALI1535 is not set
+# CONFIG_I2C_ALI1563 is not set
+# CONFIG_I2C_ALI15X3 is not set
+CONFIG_I2C_AMD756=m
+CONFIG_I2C_AMD756_S4882=m
+CONFIG_I2C_AMD8111=m
+CONFIG_I2C_I801=m
+# CONFIG_I2C_I810 is not set
+# CONFIG_I2C_PIIX4 is not set
+CONFIG_I2C_ISA=m
+CONFIG_I2C_NFORCE2=m
+# CONFIG_I2C_OCORES is not set
+CONFIG_I2C_PARPORT=m
+CONFIG_I2C_PARPORT_LIGHT=m
+CONFIG_I2C_PROSAVAGE=m
+CONFIG_I2C_SAVAGE4=m
+# CONFIG_I2C_SIS5595 is not set
+# CONFIG_I2C_SIS630 is not set
+CONFIG_I2C_SIS96X=m
+CONFIG_I2C_STUB=m
+CONFIG_I2C_VIA=m
+CONFIG_I2C_VIAPRO=m
+CONFIG_I2C_VOODOO3=m
+CONFIG_I2C_PCA_ISA=m
+
+#
+# Miscellaneous I2C Chip support
+#
+CONFIG_SENSORS_DS1337=m
+CONFIG_SENSORS_DS1374=m
+CONFIG_SENSORS_EEPROM=m
+CONFIG_SENSORS_PCF8574=m
+CONFIG_SENSORS_PCA9539=m
+CONFIG_SENSORS_PCF8591=m
+CONFIG_SENSORS_MAX6875=m
+# 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 is not set
+# CONFIG_SPI_MASTER is not set
+
+#
+# Dallas's 1-wire bus
+#
+CONFIG_W1=m
+CONFIG_W1_CON=y
+
+#
+# 1-wire Bus Masters
+#
+CONFIG_W1_MASTER_MATROX=m
+CONFIG_W1_MASTER_DS2490=m
+CONFIG_W1_MASTER_DS2482=m
+
+#
+# 1-wire Slaves
+#
+CONFIG_W1_SLAVE_THERM=m
+CONFIG_W1_SLAVE_SMEM=m
+CONFIG_W1_SLAVE_DS2433=m
+CONFIG_W1_SLAVE_DS2433_CRC=y
+
+#
+# Hardware Monitoring support
+#
+CONFIG_HWMON=m
+CONFIG_HWMON_VID=m
+CONFIG_SENSORS_ABITUGURU=m
+CONFIG_SENSORS_ADM1021=m
+CONFIG_SENSORS_ADM1025=m
+CONFIG_SENSORS_ADM1026=m
+CONFIG_SENSORS_ADM1031=m
+CONFIG_SENSORS_ADM9240=m
+CONFIG_SENSORS_ASB100=m
+CONFIG_SENSORS_ATXP1=m
+CONFIG_SENSORS_DS1621=m
+CONFIG_SENSORS_F71805F=m
+CONFIG_SENSORS_FSCHER=m
+CONFIG_SENSORS_FSCPOS=m
+CONFIG_SENSORS_GL518SM=m
+CONFIG_SENSORS_GL520SM=m
+CONFIG_SENSORS_IT87=m
+CONFIG_SENSORS_LM63=m
+CONFIG_SENSORS_LM75=m
+CONFIG_SENSORS_LM77=m
+CONFIG_SENSORS_LM78=m
+CONFIG_SENSORS_LM80=m
+CONFIG_SENSORS_LM83=m
+CONFIG_SENSORS_LM85=m
+CONFIG_SENSORS_LM87=m
+CONFIG_SENSORS_LM90=m
+CONFIG_SENSORS_LM92=m
+CONFIG_SENSORS_MAX1619=m
+CONFIG_SENSORS_PC87360=m
+CONFIG_SENSORS_SIS5595=m
+CONFIG_SENSORS_SMSC47M1=m
+CONFIG_SENSORS_SMSC47M192=m
+CONFIG_SENSORS_SMSC47B397=m
+CONFIG_SENSORS_VIA686A=m
+CONFIG_SENSORS_VT8231=m
+CONFIG_SENSORS_W83781D=m
+CONFIG_SENSORS_W83791D=m
+CONFIG_SENSORS_W83792D=m
+CONFIG_SENSORS_W83L785TS=m
+CONFIG_SENSORS_W83627HF=m
+CONFIG_SENSORS_W83627EHF=m
+CONFIG_SENSORS_HDAPS=m
+# CONFIG_HWMON_DEBUG_CHIP is not set
+
+#
+# Misc devices
+#
+# CONFIG_IBM_ASM is not set
+
+#
+# Multimedia devices
+#
+CONFIG_VIDEO_DEV=m
+CONFIG_VIDEO_V4L1=y
+CONFIG_VIDEO_V4L1_COMPAT=y
+CONFIG_VIDEO_V4L2=y
+
+#
+# Video Capture Adapters
+#
+
+#
+# Video Capture Adapters
+#
+# CONFIG_VIDEO_ADV_DEBUG is not set
+# CONFIG_VIDEO_VIVI is not set
+CONFIG_VIDEO_BT848=m
+CONFIG_VIDEO_BT848_DVB=y
+CONFIG_VIDEO_SAA6588=m
+CONFIG_VIDEO_BWQCAM=m
+CONFIG_VIDEO_CQCAM=m
+CONFIG_VIDEO_W9966=m
+CONFIG_VIDEO_CPIA=m
+CONFIG_VIDEO_CPIA_PP=m
+CONFIG_VIDEO_CPIA_USB=m
+CONFIG_VIDEO_CPIA2=m
+CONFIG_VIDEO_SAA5246A=m
+CONFIG_VIDEO_SAA5249=m
+CONFIG_TUNER_3036=m
+CONFIG_VIDEO_STRADIS=m
+CONFIG_VIDEO_ZORAN=m
+CONFIG_VIDEO_ZORAN_BUZ=m
+CONFIG_VIDEO_ZORAN_DC10=m
+CONFIG_VIDEO_ZORAN_DC30=m
+CONFIG_VIDEO_ZORAN_LML33=m
+CONFIG_VIDEO_ZORAN_LML33R10=m
+CONFIG_VIDEO_ZORAN_AVS6EYES=m
+CONFIG_VIDEO_SAA7134=m
+CONFIG_VIDEO_SAA7134_ALSA=m
+CONFIG_VIDEO_SAA7134_DVB=m
+CONFIG_VIDEO_SAA7134_DVB_ALL_FRONTENDS=y
+CONFIG_VIDEO_MXB=m
+CONFIG_VIDEO_DPC=m
+CONFIG_VIDEO_HEXIUM_ORION=m
+CONFIG_VIDEO_HEXIUM_GEMINI=m
+CONFIG_VIDEO_CX88_VP3054=m
+CONFIG_VIDEO_CX88=m
+CONFIG_VIDEO_CX88_ALSA=m
+CONFIG_VIDEO_CX88_BLACKBIRD=m
+CONFIG_VIDEO_CX88_DVB=m
+CONFIG_VIDEO_CX88_DVB_ALL_FRONTENDS=y
+
+#
+# Encoders and Decoders
+#
+CONFIG_VIDEO_MSP3400=m
+CONFIG_VIDEO_CS53L32A=m
+CONFIG_VIDEO_TLV320AIC23B=m
+CONFIG_VIDEO_WM8775=m
+CONFIG_VIDEO_WM8739=m
+CONFIG_VIDEO_CX2341X=m
+CONFIG_VIDEO_CX25840=m
+CONFIG_VIDEO_SAA711X=m
+CONFIG_VIDEO_SAA7127=m
+CONFIG_VIDEO_UPD64031A=m
+CONFIG_VIDEO_UPD64083=m
+
+#
+# V4L USB devices
+#
+CONFIG_VIDEO_PVRUSB2=m
+CONFIG_VIDEO_PVRUSB2_24XXX=y
+CONFIG_VIDEO_PVRUSB2_SYSFS=y
+# CONFIG_VIDEO_PVRUSB2_DEBUGIFC is not set
+CONFIG_VIDEO_EM28XX=m
+CONFIG_VIDEO_USBVIDEO=m
+CONFIG_USB_VICAM=m
+CONFIG_USB_IBMCAM=m
+CONFIG_USB_KONICAWC=m
+CONFIG_USB_QUICKCAM_MESSENGER=m
+CONFIG_USB_ET61X251=m
+CONFIG_VIDEO_OVCAMCHIP=m
+CONFIG_USB_W9968CF=m
+CONFIG_USB_OV511=m
+CONFIG_USB_SE401=m
+CONFIG_USB_SN9C102=m
+CONFIG_USB_STV680=m
+CONFIG_USB_ZC0301=m
+CONFIG_USB_PWC=m
+# CONFIG_USB_PWC_DEBUG is not set
+
+#
+# Radio Adapters
+#
+CONFIG_RADIO_GEMTEK_PCI=m
+CONFIG_RADIO_MAXIRADIO=m
+CONFIG_RADIO_MAESTRO=m
+CONFIG_USB_DSBR=m
+
+#
+# Digital Video Broadcasting Devices
+#
+CONFIG_DVB=y
+CONFIG_DVB_CORE=m
+
+#
+# Supported SAA7146 based PCI Adapters
+#
+CONFIG_DVB_AV7110=m
+CONFIG_DVB_AV7110_OSD=y
+CONFIG_DVB_BUDGET=m
+CONFIG_DVB_BUDGET_CI=m
+CONFIG_DVB_BUDGET_AV=m
+CONFIG_DVB_BUDGET_PATCH=m
+
+#
+# Supported USB Adapters
+#
+CONFIG_DVB_USB=m
+# CONFIG_DVB_USB_DEBUG is not set
+CONFIG_DVB_USB_A800=m
+CONFIG_DVB_USB_DIBUSB_MB=m
+# CONFIG_DVB_USB_DIBUSB_MB_FAULTY is not set
+CONFIG_DVB_USB_DIBUSB_MC=m
+CONFIG_DVB_USB_UMT_010=m
+CONFIG_DVB_USB_CXUSB=m
+CONFIG_DVB_USB_DIGITV=m
+CONFIG_DVB_USB_VP7045=m
+CONFIG_DVB_USB_VP702X=m
+CONFIG_DVB_USB_GP8PSK=m
+CONFIG_DVB_USB_NOVA_T_USB2=m
+CONFIG_DVB_USB_DTT200U=m
+CONFIG_DVB_TTUSB_BUDGET=m
+CONFIG_DVB_TTUSB_DEC=m
+CONFIG_DVB_CINERGYT2=m
+CONFIG_DVB_CINERGYT2_TUNING=y
+CONFIG_DVB_CINERGYT2_STREAM_URB_COUNT=32
+CONFIG_DVB_CINERGYT2_STREAM_BUF_SIZE=512
+CONFIG_DVB_CINERGYT2_QUERY_INTERVAL=250
+CONFIG_DVB_CINERGYT2_ENABLE_RC_INPUT_DEVICE=y
+CONFIG_DVB_CINERGYT2_RC_QUERY_INTERVAL=100
+
+#
+# Supported FlexCopII (B2C2) Adapters
+#
+CONFIG_DVB_B2C2_FLEXCOP=m
+CONFIG_DVB_B2C2_FLEXCOP_PCI=m
+CONFIG_DVB_B2C2_FLEXCOP_USB=m
+# CONFIG_DVB_B2C2_FLEXCOP_DEBUG is not set
+
+#
+# Supported BT878 Adapters
+#
+CONFIG_DVB_BT8XX=m
+
+#
+# Supported Pluto2 Adapters
+#
+CONFIG_DVB_PLUTO2=m
+
+#
+# Supported DVB Frontends
+#
+
+#
+# Customise DVB Frontends
+#
+
+#
+# DVB-S (satellite) frontends
+#
+CONFIG_DVB_STV0299=m
+CONFIG_DVB_CX24110=m
+CONFIG_DVB_CX24123=m
+CONFIG_DVB_TDA8083=m
+CONFIG_DVB_MT312=m
+CONFIG_DVB_VES1X93=m
+CONFIG_DVB_S5H1420=m
+
+#
+# DVB-T (terrestrial) frontends
+#
+CONFIG_DVB_SP8870=m
+CONFIG_DVB_SP887X=m
+CONFIG_DVB_CX22700=m
+CONFIG_DVB_CX22702=m
+CONFIG_DVB_L64781=m
+CONFIG_DVB_TDA1004X=m
+CONFIG_DVB_NXT6000=m
+CONFIG_DVB_MT352=m
+CONFIG_DVB_ZL10353=m
+CONFIG_DVB_DIB3000MB=m
+CONFIG_DVB_DIB3000MC=m
+
+#
+# DVB-C (cable) frontends
+#
+CONFIG_DVB_VES1820=m
+CONFIG_DVB_TDA10021=m
+CONFIG_DVB_STV0297=m
+
+#
+# ATSC (North American/Korean Terrestrial/Cable DTV) frontends
+#
+CONFIG_DVB_NXT200X=m
+CONFIG_DVB_OR51211=m
+CONFIG_DVB_OR51132=m
+CONFIG_DVB_BCM3510=m
+CONFIG_DVB_LGDT330X=m
+
+#
+# Miscellaneous devices
+#
+CONFIG_DVB_PLL=m
+CONFIG_DVB_LNBP21=m
+CONFIG_DVB_ISL6421=m
+CONFIG_VIDEO_SAA7146=m
+CONFIG_VIDEO_SAA7146_VV=m
+CONFIG_VIDEO_VIDEOBUF=m
+CONFIG_VIDEO_TUNER=m
+CONFIG_VIDEO_BUF=m
+CONFIG_VIDEO_BUF_DVB=m
+CONFIG_VIDEO_BTCX=m
+CONFIG_VIDEO_IR=m
+CONFIG_VIDEO_TVEEPROM=m
+CONFIG_USB_DABUSB=m
+
+#
+# Graphics support
+#
+# CONFIG_FIRMWARE_EDID is not set
+CONFIG_FB=y
+CONFIG_FB_CFB_FILLRECT=y
+CONFIG_FB_CFB_COPYAREA=y
+CONFIG_FB_CFB_IMAGEBLIT=y
+# CONFIG_FB_MACMODES is not set
+# CONFIG_FB_BACKLIGHT is not set
+CONFIG_FB_MODE_HELPERS=y
+CONFIG_FB_TILEBLITTING=y
+CONFIG_FB_CIRRUS=m
+# CONFIG_FB_PM2 is not set
+# CONFIG_FB_CYBER2000 is not set
+# CONFIG_FB_ARC is not set
+# CONFIG_FB_ASILIANT is not set
+# CONFIG_FB_IMSTT is not set
+CONFIG_FB_VGA16=m
+CONFIG_FB_VESA=y
+# CONFIG_FB_HGA is not set
+# CONFIG_FB_S1D13XXX is not set
+CONFIG_FB_NVIDIA=m
+CONFIG_FB_NVIDIA_I2C=y
+CONFIG_FB_RIVA=m
+# CONFIG_FB_RIVA_I2C is not set
+# CONFIG_FB_RIVA_DEBUG is not set
+CONFIG_FB_INTEL=m
+# CONFIG_FB_INTEL_DEBUG is not set
+CONFIG_FB_MATROX=m
+CONFIG_FB_MATROX_MILLENIUM=y
+CONFIG_FB_MATROX_MYSTIQUE=y
+CONFIG_FB_MATROX_G=y
+CONFIG_FB_MATROX_I2C=m
+CONFIG_FB_MATROX_MAVEN=m
+CONFIG_FB_MATROX_MULTIHEAD=y
+CONFIG_FB_RADEON=m
+CONFIG_FB_RADEON_I2C=y
+# CONFIG_FB_RADEON_DEBUG is not set
+CONFIG_FB_ATY128=m
+CONFIG_FB_ATY=m
+CONFIG_FB_ATY_CT=y
+CONFIG_FB_ATY_GENERIC_LCD=y
+CONFIG_FB_ATY_GX=y
+CONFIG_FB_SAVAGE=m
+CONFIG_FB_SAVAGE_I2C=y
+CONFIG_FB_SAVAGE_ACCEL=y
+# CONFIG_FB_SIS is not set
+CONFIG_FB_NEOMAGIC=m
+CONFIG_FB_KYRO=m
+CONFIG_FB_3DFX=m
+CONFIG_FB_3DFX_ACCEL=y
+CONFIG_FB_VOODOO1=m
+CONFIG_FB_TRIDENT=m
+CONFIG_FB_TRIDENT_ACCEL=y
+# CONFIG_FB_GEODE is not set
+# CONFIG_FB_VIRTUAL is not set
+
+#
+# Console display driver support
+#
+CONFIG_VGA_CONSOLE=y
+CONFIG_VGACON_SOFT_SCROLLBACK=y
+CONFIG_VGACON_SOFT_SCROLLBACK_SIZE=64
+CONFIG_VIDEO_SELECT=y
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y
+# CONFIG_FONTS is not set
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
+
+#
+# Logo configuration
+#
+CONFIG_LOGO=y
+# CONFIG_LOGO_LINUX_MONO is not set
+# CONFIG_LOGO_LINUX_VGA16 is not set
+CONFIG_LOGO_LINUX_CLUT224=y
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+CONFIG_BACKLIGHT_CLASS_DEVICE=m
+CONFIG_BACKLIGHT_DEVICE=y
+CONFIG_LCD_CLASS_DEVICE=m
+CONFIG_LCD_DEVICE=y
+
+#
+# Sound
+#
+CONFIG_SOUND=m
+
+#
+# Advanced Linux Sound Architecture
+#
+CONFIG_SND=m
+CONFIG_SND_TIMER=m
+CONFIG_SND_PCM=m
+CONFIG_SND_HWDEP=m
+CONFIG_SND_RAWMIDI=m
+CONFIG_SND_SEQUENCER=m
+CONFIG_SND_SEQ_DUMMY=m
+CONFIG_SND_OSSEMUL=y
+CONFIG_SND_MIXER_OSS=m
+CONFIG_SND_PCM_OSS=m
+CONFIG_SND_PCM_OSS_PLUGINS=y
+CONFIG_SND_SEQUENCER_OSS=y
+CONFIG_SND_RTCTIMER=m
+CONFIG_SND_SEQ_RTCTIMER_DEFAULT=y
+CONFIG_SND_DYNAMIC_MINORS=y
+# CONFIG_SND_SUPPORT_OLD_API is not set
+CONFIG_SND_VERBOSE_PROCFS=y
+# CONFIG_SND_VERBOSE_PRINTK is not set
+# CONFIG_SND_DEBUG is not set
+
+#
+# Generic devices
+#
+CONFIG_SND_MPU401_UART=m
+CONFIG_SND_OPL3_LIB=m
+CONFIG_SND_VX_LIB=m
+CONFIG_SND_AC97_CODEC=m
+CONFIG_SND_AC97_BUS=m
+CONFIG_SND_DUMMY=m
+CONFIG_SND_VIRMIDI=m
+CONFIG_SND_MTPAV=m
+# CONFIG_SND_SERIAL_U16550 is not set
+CONFIG_SND_MPU401=m
+
+#
+# PCI devices
+#
+CONFIG_SND_AD1889=m
+CONFIG_SND_ALS300=m
+CONFIG_SND_ALS4000=m
+CONFIG_SND_ALI5451=m
+CONFIG_SND_ATIIXP=m
+CONFIG_SND_ATIIXP_MODEM=m
+CONFIG_SND_AU8810=m
+CONFIG_SND_AU8820=m
+CONFIG_SND_AU8830=m
+CONFIG_SND_AZT3328=m
+CONFIG_SND_BT87X=m
+# CONFIG_SND_BT87X_OVERCLOCK is not set
+CONFIG_SND_CA0106=m
+CONFIG_SND_CMIPCI=m
+CONFIG_SND_CS4281=m
+CONFIG_SND_CS46XX=m
+CONFIG_SND_CS46XX_NEW_DSP=y
+CONFIG_SND_DARLA20=m
+CONFIG_SND_GINA20=m
+CONFIG_SND_LAYLA20=m
+CONFIG_SND_DARLA24=m
+CONFIG_SND_GINA24=m
+CONFIG_SND_LAYLA24=m
+CONFIG_SND_MONA=m
+CONFIG_SND_MIA=m
+CONFIG_SND_ECHO3G=m
+CONFIG_SND_INDIGO=m
+CONFIG_SND_INDIGOIO=m
+CONFIG_SND_INDIGODJ=m
+CONFIG_SND_EMU10K1=m
+CONFIG_SND_EMU10K1X=m
+CONFIG_SND_ENS1370=m
+CONFIG_SND_ENS1371=m
+CONFIG_SND_ES1938=m
+CONFIG_SND_ES1968=m
+CONFIG_SND_FM801=m
+CONFIG_SND_FM801_TEA575X_BOOL=y
+CONFIG_SND_FM801_TEA575X=m
+CONFIG_SND_HDA_INTEL=m
+CONFIG_SND_HDSP=m
+CONFIG_SND_HDSPM=m
+CONFIG_SND_ICE1712=m
+CONFIG_SND_ICE1724=m
+CONFIG_SND_INTEL8X0=m
+CONFIG_SND_INTEL8X0M=m
+CONFIG_SND_KORG1212=m
+CONFIG_SND_MAESTRO3=m
+CONFIG_SND_MIXART=m
+CONFIG_SND_NM256=m
+CONFIG_SND_PCXHR=m
+CONFIG_SND_RIPTIDE=m
+CONFIG_SND_RME32=m
+CONFIG_SND_RME96=m
+CONFIG_SND_RME9652=m
+CONFIG_SND_SONICVIBES=m
+CONFIG_SND_TRIDENT=m
+CONFIG_SND_VIA82XX=m
+CONFIG_SND_VIA82XX_MODEM=m
+CONFIG_SND_VX222=m
+CONFIG_SND_YMFPCI=m
+
+#
+# USB devices
+#
+CONFIG_SND_USB_AUDIO=m
+CONFIG_SND_USB_USX2Y=m
+
+#
+# PCMCIA devices
+#
+# CONFIG_SND_VXPOCKET is not set
+# CONFIG_SND_PDAUDIOCF is not set
+
+#
+# Open Sound System
+#
+# CONFIG_SOUND_PRIME is not set
+
+#
+# USB support
+#
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB_ARCH_HAS_EHCI=y
+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_SUSPEND is not set
+# CONFIG_USB_OTG is not set
+
+#
+# USB Host Controller Drivers
+#
+CONFIG_USB_EHCI_HCD=m
+CONFIG_USB_EHCI_SPLIT_ISO=y
+CONFIG_USB_EHCI_ROOT_HUB_TT=y
+CONFIG_USB_EHCI_TT_NEWSCHED=y
+CONFIG_USB_ISP116X_HCD=m
+CONFIG_USB_OHCI_HCD=m
+# CONFIG_USB_OHCI_BIG_ENDIAN is not set
+CONFIG_USB_OHCI_LITTLE_ENDIAN=y
+CONFIG_USB_UHCI_HCD=m
+CONFIG_USB_SL811_HCD=m
+CONFIG_USB_SL811_CS=m
+
+#
+# USB Device Class drivers
+#
+CONFIG_USB_ACM=m
+CONFIG_USB_PRINTER=m
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+#
+
+#
+# may also be needed; see USB_STORAGE Help for more information
+#
+CONFIG_USB_STORAGE=m
+# CONFIG_USB_STORAGE_DEBUG is not set
+CONFIG_USB_STORAGE_DATAFAB=y
+CONFIG_USB_STORAGE_FREECOM=y
+CONFIG_USB_STORAGE_ISD200=y
+CONFIG_USB_STORAGE_DPCM=y
+CONFIG_USB_STORAGE_USBAT=y
+CONFIG_USB_STORAGE_SDDR09=y
+CONFIG_USB_STORAGE_SDDR55=y
+CONFIG_USB_STORAGE_JUMPSHOT=y
+CONFIG_USB_STORAGE_ALAUDA=y
+CONFIG_USB_LIBUSUAL=y
+
+#
+# USB Input Devices
+#
+CONFIG_USB_HID=y
+CONFIG_USB_HIDINPUT=y
+# CONFIG_USB_HIDINPUT_POWERBOOK is not set
+CONFIG_HID_FF=y
+CONFIG_HID_PID=y
+CONFIG_LOGITECH_FF=y
+CONFIG_THRUSTMASTER_FF=y
+CONFIG_USB_HIDDEV=y
+CONFIG_USB_AIPTEK=m
+CONFIG_USB_WACOM=m
+CONFIG_USB_ACECAD=m
+CONFIG_USB_KBTAB=m
+CONFIG_USB_POWERMATE=m
+CONFIG_USB_TOUCHSCREEN=m
+CONFIG_USB_TOUCHSCREEN_EGALAX=y
+CONFIG_USB_TOUCHSCREEN_PANJIT=y
+CONFIG_USB_TOUCHSCREEN_3M=y
+CONFIG_USB_TOUCHSCREEN_ITM=y
+# CONFIG_USB_YEALINK is not set
+CONFIG_USB_XPAD=m
+CONFIG_USB_ATI_REMOTE=m
+CONFIG_USB_ATI_REMOTE2=m
+CONFIG_USB_KEYSPAN_REMOTE=m
+CONFIG_USB_APPLETOUCH=m
+
+#
+# USB Imaging devices
+#
+CONFIG_USB_MDC800=m
+CONFIG_USB_MICROTEK=m
+
+#
+# USB Network Adapters
+#
+CONFIG_USB_CATC=m
+CONFIG_USB_KAWETH=m
+CONFIG_USB_PEGASUS=m
+CONFIG_USB_RTL8150=m
+CONFIG_USB_USBNET=m
+CONFIG_USB_NET_AX8817X=m
+CONFIG_USB_NET_CDCETHER=m
+CONFIG_USB_NET_GL620A=m
+CONFIG_USB_NET_NET1080=m
+CONFIG_USB_NET_PLUSB=m
+CONFIG_USB_NET_RNDIS_HOST=m
+CONFIG_USB_NET_CDC_SUBSET=m
+CONFIG_USB_ALI_M5632=y
+CONFIG_USB_AN2720=y
+CONFIG_USB_BELKIN=y
+CONFIG_USB_ARMLINUX=y
+CONFIG_USB_EPSON2888=y
+CONFIG_USB_NET_ZAURUS=m
+CONFIG_USB_MON=y
+
+#
+# USB port drivers
+#
+CONFIG_USB_USS720=m
+
+#
+# USB Serial Converter support
+#
+CONFIG_USB_SERIAL=m
+CONFIG_USB_SERIAL_GENERIC=y
+CONFIG_USB_SERIAL_AIRPRIME=m
+CONFIG_USB_SERIAL_ARK3116=m
+CONFIG_USB_SERIAL_BELKIN=m
+CONFIG_USB_SERIAL_WHITEHEAT=m
+CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m
+CONFIG_USB_SERIAL_CP2101=m
+CONFIG_USB_SERIAL_CYPRESS_M8=m
+CONFIG_USB_SERIAL_EMPEG=m
+CONFIG_USB_SERIAL_FTDI_SIO=m
+CONFIG_USB_SERIAL_FUNSOFT=m
+CONFIG_USB_SERIAL_VISOR=m
+CONFIG_USB_SERIAL_IPAQ=m
+CONFIG_USB_SERIAL_IR=m
+CONFIG_USB_SERIAL_EDGEPORT=m
+CONFIG_USB_SERIAL_EDGEPORT_TI=m
+CONFIG_USB_SERIAL_GARMIN=m
+CONFIG_USB_SERIAL_IPW=m
+CONFIG_USB_SERIAL_KEYSPAN_PDA=m
+CONFIG_USB_SERIAL_KEYSPAN=m
+CONFIG_USB_SERIAL_KEYSPAN_MPR=y
+CONFIG_USB_SERIAL_KEYSPAN_USA28=y
+CONFIG_USB_SERIAL_KEYSPAN_USA28X=y
+CONFIG_USB_SERIAL_KEYSPAN_USA28XA=y
+CONFIG_USB_SERIAL_KEYSPAN_USA28XB=y
+CONFIG_USB_SERIAL_KEYSPAN_USA19=y
+CONFIG_USB_SERIAL_KEYSPAN_USA18X=y
+CONFIG_USB_SERIAL_KEYSPAN_USA19W=y
+CONFIG_USB_SERIAL_KEYSPAN_USA19QW=y
+CONFIG_USB_SERIAL_KEYSPAN_USA19QI=y
+CONFIG_USB_SERIAL_KEYSPAN_USA49W=y
+CONFIG_USB_SERIAL_KEYSPAN_USA49WLC=y
+CONFIG_USB_SERIAL_KLSI=m
+CONFIG_USB_SERIAL_KOBIL_SCT=m
+CONFIG_USB_SERIAL_MCT_U232=m
+CONFIG_USB_SERIAL_NAVMAN=m
+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=m
+CONFIG_USB_SERIAL_TI=m
+CONFIG_USB_SERIAL_CYBERJACK=m
+CONFIG_USB_SERIAL_XIRCOM=m
+CONFIG_USB_SERIAL_OPTION=m
+CONFIG_USB_SERIAL_OMNINET=m
+CONFIG_USB_EZUSB=y
+
+#
+# USB Miscellaneous drivers
+#
+CONFIG_USB_EMI62=m
+CONFIG_USB_EMI26=m
+CONFIG_USB_AUERSWALD=m
+CONFIG_USB_RIO500=m
+CONFIG_USB_LEGOTOWER=m
+CONFIG_USB_LCD=m
+CONFIG_USB_LED=m
+# CONFIG_USB_CYPRESS_CY7C63 is not set
+# CONFIG_USB_CYTHERM is not set
+CONFIG_USB_PHIDGETKIT=m
+CONFIG_USB_PHIDGETSERVO=m
+CONFIG_USB_IDMOUSE=m
+CONFIG_USB_APPLEDISPLAY=m
+CONFIG_USB_SISUSBVGA=m
+CONFIG_USB_SISUSBVGA_CON=y
+CONFIG_USB_LD=m
+CONFIG_USB_TEST=m
+
+#
+# USB DSL modem support
+#
+CONFIG_USB_ATM=m
+CONFIG_USB_SPEEDTOUCH=m
+CONFIG_USB_CXACRU=m
+CONFIG_USB_UEAGLEATM=m
+CONFIG_USB_XUSBATM=m
+
+#
+# USB Gadget Support
+#
+# CONFIG_USB_GADGET is not set
+
+#
+# MMC/SD Card support
+#
+CONFIG_MMC=m
+# CONFIG_MMC_DEBUG is not set
+CONFIG_MMC_BLOCK=m
+CONFIG_MMC_SDHCI=m
+CONFIG_MMC_WBSD=m
+
+#
+# LED devices
+#
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+
+#
+# LED drivers
+#
+
+#
+# LED Triggers
+#
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_LEDS_TRIGGER_TIMER=m
+CONFIG_LEDS_TRIGGER_IDE_DISK=y
+CONFIG_LEDS_TRIGGER_HEARTBEAT=m
+
+#
+# InfiniBand support
+#
+CONFIG_INFINIBAND=m
+CONFIG_INFINIBAND_USER_MAD=m
+CONFIG_INFINIBAND_USER_ACCESS=m
+CONFIG_INFINIBAND_ADDR_TRANS=y
+CONFIG_INFINIBAND_MTHCA=m
+CONFIG_INFINIBAND_MTHCA_DEBUG=y
+CONFIG_INFINIBAND_IPOIB=m
+CONFIG_INFINIBAND_IPOIB_DEBUG=y
+CONFIG_INFINIBAND_IPOIB_DEBUG_DATA=y
+CONFIG_INFINIBAND_SRP=m
+CONFIG_INFINIBAND_ISER=m
+
+#
+# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
+#
+CONFIG_EDAC=y
+
+#
+# Reporting subsystems
+#
+# CONFIG_EDAC_DEBUG is not set
+CONFIG_EDAC_MM_EDAC=m
+CONFIG_EDAC_E752X=m
+CONFIG_EDAC_K8=m
+CONFIG_EDAC_POLL=y
+
+#
+# Real Time Clock
+#
+CONFIG_RTC_LIB=m
+CONFIG_RTC_CLASS=m
+
+#
+# RTC interfaces
+#
+CONFIG_RTC_INTF_SYSFS=m
+CONFIG_RTC_INTF_PROC=m
+CONFIG_RTC_INTF_DEV=m
+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
+
+#
+# RTC drivers
+#
+CONFIG_RTC_DRV_X1205=m
+CONFIG_RTC_DRV_DS1307=m
+CONFIG_RTC_DRV_DS1553=m
+CONFIG_RTC_DRV_ISL1208=m
+CONFIG_RTC_DRV_DS1672=m
+CONFIG_RTC_DRV_DS1742=m
+CONFIG_RTC_DRV_PCF8563=m
+CONFIG_RTC_DRV_PCF8583=m
+CONFIG_RTC_DRV_RS5C372=m
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_TEST is not set
+CONFIG_RTC_DRV_V3020=m
+
+#
+# DMA Engine support
+#
+CONFIG_DMA_ENGINE=y
+
+#
+# DMA Clients
+#
+CONFIG_NET_DMA=y
+
+#
+# DMA Devices
+#
+CONFIG_INTEL_IOATDMA=m
+
+#
+# Firmware Drivers
+#
+CONFIG_DELL_RBU=m
+CONFIG_DCDBAS=m
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+CONFIG_EXT2_FS_POSIX_ACL=y
+CONFIG_EXT2_FS_SECURITY=y
+CONFIG_EXT2_FS_XIP=y
+CONFIG_FS_XIP=y
+CONFIG_EXT3_FS=m
+CONFIG_EXT3_FS_XATTR=y
+CONFIG_EXT3_FS_POSIX_ACL=y
+CONFIG_EXT3_FS_SECURITY=y
+CONFIG_JBD=m
+# CONFIG_JBD_DEBUG is not set
+CONFIG_FS_MBCACHE=y
+CONFIG_REISERFS_FS=m
+# CONFIG_REISERFS_CHECK is not set
+CONFIG_REISERFS_PROC_INFO=y
+CONFIG_REISERFS_FS_XATTR=y
+CONFIG_REISERFS_FS_POSIX_ACL=y
+CONFIG_REISERFS_FS_SECURITY=y
+CONFIG_JFS_FS=m
+CONFIG_JFS_POSIX_ACL=y
+CONFIG_JFS_SECURITY=y
+# CONFIG_JFS_DEBUG is not set
+# CONFIG_JFS_STATISTICS is not set
+CONFIG_FS_POSIX_ACL=y
+CONFIG_XFS_FS=m
+CONFIG_XFS_QUOTA=y
+CONFIG_XFS_SECURITY=y
+CONFIG_XFS_POSIX_ACL=y
+# CONFIG_XFS_RT is not set
+CONFIG_OCFS2_FS=m
+# CONFIG_OCFS2_DEBUG_MASKLOG is not set
+CONFIG_MINIX_FS=m
+CONFIG_ROMFS_FS=m
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+CONFIG_QUOTA=y
+# CONFIG_QFMT_V1 is not set
+CONFIG_QFMT_V2=y
+CONFIG_QUOTACTL=y
+CONFIG_DNOTIFY=y
+CONFIG_AUTOFS_FS=m
+CONFIG_AUTOFS4_FS=m
+CONFIG_FUSE_FS=m
+
+#
+# Caches
+#
+CONFIG_FSCACHE=m
+
+#
+# CD-ROM/DVD Filesystems
+#
+CONFIG_ISO9660_FS=y
+CONFIG_JOLIET=y
+CONFIG_ZISOFS=y
+CONFIG_ZISOFS_FS=y
+CONFIG_UDF_FS=m
+CONFIG_UDF_NLS=y
+CONFIG_CACHEFILES=m
+CONFIG_CACHEFILES_DEBUG=y
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=m
+CONFIG_MSDOS_FS=m
+CONFIG_VFAT_FS=m
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="ascii"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_RAMFS=y
+CONFIG_CONFIGFS_FS=m
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+CONFIG_AFFS_FS=m
+CONFIG_HFS_FS=m
+CONFIG_HFSPLUS_FS=m
+CONFIG_BEFS_FS=m
+# CONFIG_BEFS_DEBUG is not set
+CONFIG_BFS_FS=m
+CONFIG_EFS_FS=m
+# CONFIG_JFFS_FS is not set
+CONFIG_JFFS2_FS=m
+CONFIG_JFFS2_FS_DEBUG=0
+CONFIG_JFFS2_FS_WRITEBUFFER=y
+CONFIG_JFFS2_SUMMARY=y
+# 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=m
+CONFIG_SQUASHFS=m
+# CONFIG_SQUASHFS_EMBEDDED is not set
+CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3
+# CONFIG_SQUASHFS_VMALLOC is not set
+CONFIG_VXFS_FS=m
+# CONFIG_HPFS_FS is not set
+CONFIG_QNX4FS_FS=m
+CONFIG_SYSV_FS=m
+CONFIG_UFS_FS=m
+# CONFIG_UFS_FS_WRITE is not set
+# CONFIG_UFS_DEBUG is not set
+
+#
+# Network File Systems
+#
+CONFIG_NFS_FS=m
+CONFIG_NFS_V3=y
+CONFIG_NFS_V3_ACL=y
+CONFIG_NFS_V4=y
+CONFIG_NFS_FSCACHE=y
+CONFIG_NFS_DIRECTIO=y
+CONFIG_NFSD=m
+CONFIG_NFSD_V2_ACL=y
+CONFIG_NFSD_V3=y
+CONFIG_NFSD_V3_ACL=y
+CONFIG_NFSD_V4=y
+CONFIG_NFSD_TCP=y
+CONFIG_LOCKD=m
+CONFIG_LOCKD_V4=y
+CONFIG_EXPORTFS=m
+CONFIG_NFS_ACL_SUPPORT=m
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=m
+CONFIG_SUNRPC_GSS=m
+CONFIG_RPCSEC_GSS_KRB5=m
+CONFIG_RPCSEC_GSS_SPKM3=m
+# CONFIG_SMB_FS is not set
+CONFIG_CIFS=m
+# CONFIG_CIFS_STATS is not set
+CONFIG_CIFS_WEAK_PW_HASH=y
+CONFIG_CIFS_XATTR=y
+CONFIG_CIFS_POSIX=y
+# CONFIG_CIFS_DEBUG2 is not set
+# CONFIG_CIFS_EXPERIMENTAL is not set
+CONFIG_NCP_FS=m
+CONFIG_NCPFS_PACKET_SIGNING=y
+CONFIG_NCPFS_IOCTL_LOCKING=y
+CONFIG_NCPFS_STRONG=y
+CONFIG_NCPFS_NFS_NS=y
+CONFIG_NCPFS_OS2_NS=y
+CONFIG_NCPFS_SMALLDOS=y
+CONFIG_NCPFS_NLS=y
+CONFIG_NCPFS_EXTRAS=y
+CONFIG_CODA_FS=m
+# CONFIG_CODA_FS_OLD_API is not set
+# CONFIG_AFS_FS is not set
+CONFIG_9P_FS=m
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+CONFIG_OSF_PARTITION=y
+CONFIG_AMIGA_PARTITION=y
+# CONFIG_ATARI_PARTITION is not set
+CONFIG_MAC_PARTITION=y
+CONFIG_MSDOS_PARTITION=y
+CONFIG_BSD_DISKLABEL=y
+CONFIG_MINIX_SUBPARTITION=y
+CONFIG_SOLARIS_X86_PARTITION=y
+CONFIG_UNIXWARE_DISKLABEL=y
+# CONFIG_LDM_PARTITION is not set
+CONFIG_SGI_PARTITION=y
+# CONFIG_ULTRIX_PARTITION is not set
+CONFIG_SUN_PARTITION=y
+CONFIG_KARMA_PARTITION=y
+CONFIG_EFI_PARTITION=y
+
+#
+# Native Language Support
+#
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="utf8"
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_CODEPAGE_737=m
+CONFIG_NLS_CODEPAGE_775=m
+CONFIG_NLS_CODEPAGE_850=m
+CONFIG_NLS_CODEPAGE_852=m
+CONFIG_NLS_CODEPAGE_855=m
+CONFIG_NLS_CODEPAGE_857=m
+CONFIG_NLS_CODEPAGE_860=m
+CONFIG_NLS_CODEPAGE_861=m
+CONFIG_NLS_CODEPAGE_862=m
+CONFIG_NLS_CODEPAGE_863=m
+CONFIG_NLS_CODEPAGE_864=m
+CONFIG_NLS_CODEPAGE_865=m
+CONFIG_NLS_CODEPAGE_866=m
+CONFIG_NLS_CODEPAGE_869=m
+CONFIG_NLS_CODEPAGE_936=m
+CONFIG_NLS_CODEPAGE_950=m
+CONFIG_NLS_CODEPAGE_932=m
+CONFIG_NLS_CODEPAGE_949=m
+CONFIG_NLS_CODEPAGE_874=m
+CONFIG_NLS_ISO8859_8=m
+CONFIG_NLS_CODEPAGE_1250=m
+CONFIG_NLS_CODEPAGE_1251=m
+CONFIG_NLS_ASCII=y
+CONFIG_NLS_ISO8859_1=m
+CONFIG_NLS_ISO8859_2=m
+CONFIG_NLS_ISO8859_3=m
+CONFIG_NLS_ISO8859_4=m
+CONFIG_NLS_ISO8859_5=m
+CONFIG_NLS_ISO8859_6=m
+CONFIG_NLS_ISO8859_7=m
+CONFIG_NLS_ISO8859_9=m
+CONFIG_NLS_ISO8859_13=m
+CONFIG_NLS_ISO8859_14=m
+CONFIG_NLS_ISO8859_15=m
+CONFIG_NLS_KOI8_R=m
+CONFIG_NLS_KOI8_U=m
+CONFIG_NLS_UTF8=m
+
+#
+# Instrumentation Support
+#
+CONFIG_PROFILING=y
+CONFIG_OPROFILE=m
+CONFIG_KPROBES=y
+
+#
+# Kernel hacking
+#
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+# CONFIG_PRINTK_TIME is not set
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_UNUSED_SYMBOLS is not set
+CONFIG_DEBUG_KERNEL=y
+CONFIG_LOG_BUF_SHIFT=17
+CONFIG_DETECT_SOFTLOCKUP=y
+CONFIG_SCHEDSTATS=y
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
+CONFIG_DEBUG_SPINLOCK=y
+# CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_RWSEMS is not set
+CONFIG_DEBUG_SPINLOCK_SLEEP=y
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+# CONFIG_DEBUG_KOBJECT is not set
+CONFIG_DEBUG_INFO=y
+CONFIG_DEBUG_FS=y
+# CONFIG_DEBUG_VM is not set
+CONFIG_DEBUG_LIST=y
+# CONFIG_FRAME_POINTER is not set
+# CONFIG_FORCED_INLINING is not set
+CONFIG_BOOT_DELAY=y
+# CONFIG_RCU_TORTURE_TEST is not set
+CONFIG_DEBUG_RODATA=y
+CONFIG_DEBUG_STACKOVERFLOW=y
+# CONFIG_DEBUG_STACK_USAGE is not set
+
+#
+# Security options
+#
+CONFIG_KEYS=y
+CONFIG_KEYS_DEBUG_PROC_KEYS=y
+CONFIG_SECURITY=y
+CONFIG_SECURITY_NETWORK=y
+# CONFIG_SECURITY_NETWORK_XFRM is not set
+CONFIG_SECURITY_CAPABILITIES=y
+# CONFIG_SECURITY_ROOTPLUG is not set
+# CONFIG_SECURITY_SECLVL is not set
+CONFIG_SECURITY_SELINUX=y
+CONFIG_SECURITY_SELINUX_BOOTPARAM=y
+CONFIG_SECURITY_SELINUX_BOOTPARAM_VALUE=1
+CONFIG_SECURITY_SELINUX_DISABLE=y
+CONFIG_SECURITY_SELINUX_DEVELOP=y
+CONFIG_SECURITY_SELINUX_AVC_STATS=y
+CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE=1
+# CONFIG_SECURITY_SELINUX_ENABLE_SECMARK_DEFAULT is not set
+# CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX is not set
+
+#
+# Cryptographic options
+#
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_NULL=m
+CONFIG_CRYPTO_MD4=m
+CONFIG_CRYPTO_MD5=m
+CONFIG_CRYPTO_SHA1=y
+CONFIG_CRYPTO_SHA256=m
+CONFIG_CRYPTO_SHA512=m
+CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_TGR192=m
+CONFIG_CRYPTO_DES=m
+CONFIG_CRYPTO_BLOWFISH=m
+CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_SERPENT=m
+CONFIG_CRYPTO_AES=m
+CONFIG_CRYPTO_AES_X86_64=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_TEST is not set
+CONFIG_CRYPTO_SIGNATURE=y
+CONFIG_CRYPTO_SIGNATURE_DSA=y
+CONFIG_CRYPTO_MPILIB=y
+
+#
+# Hardware crypto devices
+#
+CONFIG_XEN=y
+CONFIG_XEN_INTERFACE_VERSION=0x00030203
+
+#
+# XEN
+#
+CONFIG_XEN_PRIVILEGED_GUEST=y
+# CONFIG_XEN_UNPRIVILEGED_GUEST is not set
+CONFIG_XEN_PRIVCMD=y
+CONFIG_XEN_XENBUS_DEV=y
+CONFIG_XEN_BACKEND=y
+CONFIG_XEN_BLKDEV_BACKEND=y
+CONFIG_XEN_BLKDEV_TAP=m
+CONFIG_XEN_NETDEV_BACKEND=y
+# CONFIG_XEN_NETDEV_PIPELINED_TRANSMITTER is not set
+CONFIG_XEN_NETDEV_LOOPBACK=y
+CONFIG_XEN_PCIDEV_BACKEND=m
+CONFIG_XEN_PCIDEV_BACKEND_VPCI=y
+# CONFIG_XEN_PCIDEV_BACKEND_PASS is not set
+# CONFIG_XEN_PCIDEV_BACKEND_SLOT is not set
+# CONFIG_XEN_PCIDEV_BE_DEBUG is not set
+# CONFIG_XEN_TPMDEV_BACKEND is not set
+CONFIG_XEN_BLKDEV_FRONTEND=m
+CONFIG_XEN_NETDEV_FRONTEND=m
+CONFIG_XEN_FRAMEBUFFER=y
+CONFIG_XEN_KEYBOARD=y
+CONFIG_XEN_SCRUB_PAGES=y
+# CONFIG_XEN_DISABLE_SERIAL is not set
+CONFIG_XEN_SYSFS=y
+CONFIG_XEN_COMPAT_030002_AND_LATER=y
+# CONFIG_XEN_COMPAT_LATEST_ONLY is not set
+CONFIG_XEN_COMPAT_030002=y
+CONFIG_HAVE_ARCH_ALLOC_SKB=y
+CONFIG_HAVE_ARCH_DEV_ALLOC_SKB=y
+CONFIG_HAVE_IRQ_IGNORE_UNHANDLED=y
+CONFIG_NO_IDLE_HZ=y
+CONFIG_XEN_UTIL=y
+CONFIG_XEN_BALLOON=y
+CONFIG_XEN_DEVMEM=y
+CONFIG_XEN_SKBUFF=y
+CONFIG_XEN_REBOOT=y
+CONFIG_XEN_SMPBOOT=y
+
+#
+# Library routines
+#
+CONFIG_CRC_CCITT=m
+CONFIG_CRC16=m
+CONFIG_CRC32=y
+CONFIG_LIBCRC32C=m
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=m
+CONFIG_REED_SOLOMON=m
+CONFIG_REED_SOLOMON_DEC16=y
+CONFIG_TEXTSEARCH=y
+CONFIG_TEXTSEARCH_KMP=m
+CONFIG_TEXTSEARCH_BM=m
+CONFIG_TEXTSEARCH_FSM=m
+CONFIG_PLIST=y
diff --git a/configs/kernel-2.6.18-x86_64-xenU.config b/configs/kernel-2.6.18-x86_64-xenU.config
new file mode 100644
index 000000000..78ffb6490
--- /dev/null
+++ b/configs/kernel-2.6.18-x86_64-xenU.config
@@ -0,0 +1,1581 @@
+# x86_64
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.18.2-rc1
+# Mon Nov 13 09:44:43 2006
+#
+CONFIG_X86_64=y
+CONFIG_64BIT=y
+CONFIG_X86=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_SEMAPHORE_SLEEPERS=y
+CONFIG_MMU=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_X86_CMPXCHG=y
+CONFIG_EARLY_PRINTK=y
+CONFIG_GENERIC_ISA_DMA=y
+CONFIG_GENERIC_IOMAP=y
+CONFIG_ARCH_MAY_HAVE_PC_FDC=y
+CONFIG_DMI=y
+CONFIG_AUDIT_ARCH=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_BSD_PROCESS_ACCT=y
+# CONFIG_BSD_PROCESS_ACCT_V3 is not set
+CONFIG_TASKSTATS=y
+CONFIG_TASK_DELAY_ACCT=y
+CONFIG_AUDIT=y
+CONFIG_AUDITSYSCALL=y
+# CONFIG_IKCONFIG is not set
+CONFIG_CPUSETS=y
+CONFIG_RELAY=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+# CONFIG_EMBEDDED is not set
+CONFIG_UID16=y
+CONFIG_SYSCTL=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
+CONFIG_KALLSYMS_EXTRA_PASS=y
+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=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+CONFIG_MODULE_SIG=y
+# CONFIG_MODULE_SIG_FORCE is not set
+CONFIG_KMOD=y
+CONFIG_STOP_MACHINE=y
+
+#
+# Process debugging support
+#
+CONFIG_UTRACE=y
+CONFIG_PTRACE=y
+
+#
+# Block layer
+#
+CONFIG_LBD=y
+CONFIG_BLK_DEV_IO_TRACE=y
+CONFIG_LSF=y
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_DEFAULT_AS is not set
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+
+#
+# Processor type and features
+#
+CONFIG_X86_PC=y
+# CONFIG_X86_VSMP is not set
+# CONFIG_MK8 is not set
+# CONFIG_MPSC is not set
+CONFIG_GENERIC_CPU=y
+CONFIG_X86_64_XEN=y
+CONFIG_X86_NO_TSS=y
+CONFIG_X86_NO_IDT=y
+CONFIG_X86_L1_CACHE_BYTES=128
+CONFIG_X86_L1_CACHE_SHIFT=7
+CONFIG_X86_INTERNODE_CACHE_BYTES=128
+CONFIG_X86_GOOD_APIC=y
+# CONFIG_MICROCODE is not set
+CONFIG_X86_MSR=y
+CONFIG_X86_CPUID=y
+CONFIG_X86_XEN_GENAPIC=y
+CONFIG_SMP=y
+# CONFIG_PREEMPT_NONE is not set
+CONFIG_PREEMPT_VOLUNTARY=y
+# CONFIG_PREEMPT is not set
+CONFIG_PREEMPT_BKL=y
+CONFIG_ARCH_FLATMEM_ENABLE=y
+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=y
+CONFIG_NR_CPUS=8
+CONFIG_HOTPLUG_CPU=y
+CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
+CONFIG_SWIOTLB=y
+# CONFIG_CRASH_DUMP is not set
+CONFIG_PHYSICAL_START=0x200000
+# CONFIG_SECCOMP is not set
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
+CONFIG_REORDER=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_ISA_DMA_API=y
+CONFIG_GENERIC_PENDING_IRQ=y
+
+#
+# Bus options (PCI etc.)
+#
+# CONFIG_PCI is not set
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+CONFIG_PCCARD=y
+# CONFIG_PCMCIA_DEBUG is not set
+# CONFIG_PCMCIA is not set
+
+#
+# PC-card bridges
+#
+
+#
+# PCI Hotplug Support
+#
+
+#
+# Executable file formats / Emulations
+#
+CONFIG_BINFMT_ELF=y
+CONFIG_BINFMT_MISC=y
+CONFIG_IA32_EMULATION=y
+# CONFIG_IA32_AOUT is not set
+CONFIG_COMPAT=y
+CONFIG_SYSVIPC_COMPAT=y
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+# CONFIG_NETDEBUG is not set
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=y
+CONFIG_NET_KEY=m
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_ASK_IP_FIB_HASH=y
+# 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
+# CONFIG_IP_PNP is not set
+CONFIG_NET_IPIP=m
+CONFIG_NET_IPGRE=m
+CONFIG_NET_IPGRE_BROADCAST=y
+CONFIG_IP_MROUTE=y
+CONFIG_IP_PIMSM_V1=y
+CONFIG_IP_PIMSM_V2=y
+# CONFIG_ARPD is not set
+CONFIG_SYN_COOKIES=y
+CONFIG_INET_AH=m
+CONFIG_INET_ESP=m
+CONFIG_INET_IPCOMP=m
+CONFIG_INET_XFRM_TUNNEL=m
+CONFIG_INET_TUNNEL=m
+CONFIG_INET_XFRM_MODE_TRANSPORT=m
+CONFIG_INET_XFRM_MODE_TUNNEL=m
+CONFIG_INET_DIAG=m
+CONFIG_INET_TCP_DIAG=m
+CONFIG_TCP_CONG_ADVANCED=y
+
+#
+# TCP congestion control
+#
+CONFIG_TCP_CONG_BIC=y
+CONFIG_TCP_CONG_CUBIC=m
+CONFIG_TCP_CONG_WESTWOOD=m
+CONFIG_TCP_CONG_HTCP=m
+CONFIG_TCP_CONG_HSTCP=m
+CONFIG_TCP_CONG_HYBLA=m
+CONFIG_TCP_CONG_VEGAS=m
+CONFIG_TCP_CONG_SCALABLE=m
+CONFIG_TCP_CONG_LP=m
+CONFIG_TCP_CONG_VENO=m
+
+#
+# IP: Virtual Server Configuration
+#
+CONFIG_IP_VS=m
+# CONFIG_IP_VS_DEBUG is not set
+CONFIG_IP_VS_TAB_BITS=12
+
+#
+# IPVS transport protocol load balancing support
+#
+CONFIG_IP_VS_PROTO_TCP=y
+CONFIG_IP_VS_PROTO_UDP=y
+CONFIG_IP_VS_PROTO_ESP=y
+CONFIG_IP_VS_PROTO_AH=y
+
+#
+# IPVS scheduler
+#
+CONFIG_IP_VS_RR=m
+CONFIG_IP_VS_WRR=m
+CONFIG_IP_VS_LC=m
+CONFIG_IP_VS_WLC=m
+CONFIG_IP_VS_LBLC=m
+CONFIG_IP_VS_LBLCR=m
+CONFIG_IP_VS_DH=m
+CONFIG_IP_VS_SH=m
+CONFIG_IP_VS_SED=m
+CONFIG_IP_VS_NQ=m
+
+#
+# IPVS application helper
+#
+CONFIG_IP_VS_FTP=m
+CONFIG_IPV6=m
+CONFIG_IPV6_PRIVACY=y
+CONFIG_IPV6_ROUTER_PREF=y
+CONFIG_IPV6_ROUTE_INFO=y
+CONFIG_INET6_AH=m
+CONFIG_INET6_ESP=m
+CONFIG_INET6_IPCOMP=m
+CONFIG_INET6_XFRM_TUNNEL=m
+CONFIG_INET6_TUNNEL=m
+CONFIG_INET6_XFRM_MODE_TRANSPORT=m
+CONFIG_INET6_XFRM_MODE_TUNNEL=m
+CONFIG_IPV6_TUNNEL=m
+CONFIG_NETWORK_SECMARK=y
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_DEBUG is not set
+CONFIG_BRIDGE_NETFILTER=y
+
+#
+# Core Netfilter Configuration
+#
+CONFIG_NETFILTER_NETLINK=m
+CONFIG_NETFILTER_NETLINK_QUEUE=m
+CONFIG_NETFILTER_NETLINK_LOG=m
+CONFIG_NETFILTER_XTABLES=m
+CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
+CONFIG_NETFILTER_XT_TARGET_CONNMARK=m
+CONFIG_NETFILTER_XT_TARGET_MARK=m
+CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
+CONFIG_NETFILTER_XT_TARGET_NOTRACK=m
+CONFIG_NETFILTER_XT_TARGET_SECMARK=m
+CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=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_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_PHYSDEV=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
+
+#
+# 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=m
+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_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_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_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
+CONFIG_IP_NF_ARPTABLES=m
+CONFIG_IP_NF_ARPFILTER=m
+CONFIG_IP_NF_ARP_MANGLE=m
+
+#
+# IPv6: Netfilter Configuration (EXPERIMENTAL)
+#
+CONFIG_IP6_NF_QUEUE=m
+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_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
+
+#
+# DECnet: Netfilter Configuration
+#
+# CONFIG_DECNET_NF_GRABULATOR is not set
+
+#
+# Bridge: Netfilter Configuration
+#
+CONFIG_BRIDGE_NF_EBTABLES=m
+CONFIG_BRIDGE_EBT_BROUTE=m
+CONFIG_BRIDGE_EBT_T_FILTER=m
+CONFIG_BRIDGE_EBT_T_NAT=m
+CONFIG_BRIDGE_EBT_802_3=m
+CONFIG_BRIDGE_EBT_AMONG=m
+CONFIG_BRIDGE_EBT_ARP=m
+CONFIG_BRIDGE_EBT_IP=m
+CONFIG_BRIDGE_EBT_LIMIT=m
+CONFIG_BRIDGE_EBT_MARK=m
+CONFIG_BRIDGE_EBT_PKTTYPE=m
+CONFIG_BRIDGE_EBT_STP=m
+CONFIG_BRIDGE_EBT_VLAN=m
+CONFIG_BRIDGE_EBT_ARPREPLY=m
+CONFIG_BRIDGE_EBT_DNAT=m
+CONFIG_BRIDGE_EBT_MARK_T=m
+CONFIG_BRIDGE_EBT_REDIRECT=m
+CONFIG_BRIDGE_EBT_SNAT=m
+CONFIG_BRIDGE_EBT_LOG=m
+CONFIG_BRIDGE_EBT_ULOG=m
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+CONFIG_IP_DCCP=m
+CONFIG_INET_DCCP_DIAG=m
+CONFIG_IP_DCCP_ACKVEC=y
+
+#
+# DCCP CCIDs Configuration (EXPERIMENTAL)
+#
+CONFIG_IP_DCCP_CCID2=m
+CONFIG_IP_DCCP_CCID3=m
+CONFIG_IP_DCCP_TFRC_LIB=m
+
+#
+# DCCP Kernel Hacking
+#
+# CONFIG_IP_DCCP_DEBUG is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+CONFIG_IP_SCTP=m
+# CONFIG_SCTP_DBG_MSG is not set
+# CONFIG_SCTP_DBG_OBJCNT is not set
+# CONFIG_SCTP_HMAC_NONE is not set
+# CONFIG_SCTP_HMAC_SHA1 is not set
+CONFIG_SCTP_HMAC_MD5=y
+
+#
+# TIPC Configuration (EXPERIMENTAL)
+#
+CONFIG_TIPC=m
+# CONFIG_TIPC_ADVANCED is not set
+# CONFIG_TIPC_DEBUG is not set
+CONFIG_ATM=m
+CONFIG_ATM_CLIP=m
+# CONFIG_ATM_CLIP_NO_ICMP is not set
+CONFIG_ATM_LANE=m
+# CONFIG_ATM_MPOA is not set
+CONFIG_ATM_BR2684=m
+# CONFIG_ATM_BR2684_IPFILTER is not set
+CONFIG_BRIDGE=m
+CONFIG_VLAN_8021Q=m
+CONFIG_DECNET=m
+CONFIG_DECNET_ROUTER=y
+CONFIG_DECNET_ROUTE_FWMARK=y
+CONFIG_LLC=m
+# CONFIG_LLC2 is not set
+CONFIG_IPX=m
+# CONFIG_IPX_INTERN is not set
+CONFIG_ATALK=m
+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_ECONET is not set
+CONFIG_WAN_ROUTER=m
+
+#
+# QoS and/or fair queueing
+#
+CONFIG_NET_SCHED=y
+# CONFIG_NET_SCH_CLK_JIFFIES is not set
+CONFIG_NET_SCH_CLK_GETTIMEOFDAY=y
+# CONFIG_NET_SCH_CLK_CPU is not set
+
+#
+# Queueing/Scheduling
+#
+CONFIG_NET_SCH_CBQ=m
+CONFIG_NET_SCH_HTB=m
+CONFIG_NET_SCH_HFSC=m
+CONFIG_NET_SCH_ATM=m
+CONFIG_NET_SCH_PRIO=m
+CONFIG_NET_SCH_RED=m
+CONFIG_NET_SCH_SFQ=m
+CONFIG_NET_SCH_TEQL=m
+CONFIG_NET_SCH_TBF=m
+CONFIG_NET_SCH_GRED=m
+CONFIG_NET_SCH_DSMARK=m
+CONFIG_NET_SCH_NETEM=m
+CONFIG_NET_SCH_INGRESS=m
+
+#
+# Classification
+#
+CONFIG_NET_CLS=y
+CONFIG_NET_CLS_BASIC=m
+CONFIG_NET_CLS_TCINDEX=m
+CONFIG_NET_CLS_ROUTE4=m
+CONFIG_NET_CLS_ROUTE=y
+CONFIG_NET_CLS_FW=m
+CONFIG_NET_CLS_U32=m
+CONFIG_CLS_U32_PERF=y
+CONFIG_CLS_U32_MARK=y
+CONFIG_NET_CLS_RSVP=m
+CONFIG_NET_CLS_RSVP6=m
+CONFIG_NET_EMATCH=y
+CONFIG_NET_EMATCH_STACK=32
+CONFIG_NET_EMATCH_CMP=m
+CONFIG_NET_EMATCH_NBYTE=m
+CONFIG_NET_EMATCH_U32=m
+CONFIG_NET_EMATCH_META=m
+CONFIG_NET_EMATCH_TEXT=m
+CONFIG_NET_CLS_ACT=y
+CONFIG_NET_ACT_POLICE=m
+CONFIG_NET_ACT_GACT=m
+CONFIG_GACT_PROB=y
+CONFIG_NET_ACT_MIRRED=m
+CONFIG_NET_ACT_IPT=m
+CONFIG_NET_ACT_PEDIT=m
+CONFIG_NET_ACT_SIMP=m
+CONFIG_NET_CLS_IND=y
+CONFIG_NET_ESTIMATOR=y
+
+#
+# Network testing
+#
+CONFIG_NET_PKTGEN=m
+# CONFIG_NET_TCPPROBE is not set
+# CONFIG_HAMRADIO is not set
+CONFIG_IRDA=m
+
+#
+# IrDA protocols
+#
+CONFIG_IRLAN=m
+CONFIG_IRNET=m
+CONFIG_IRCOMM=m
+# CONFIG_IRDA_ULTRA is not set
+
+#
+# IrDA options
+#
+CONFIG_IRDA_CACHE_LAST_LSAP=y
+CONFIG_IRDA_FAST_RR=y
+# CONFIG_IRDA_DEBUG is not set
+
+#
+# Infrared-port device drivers
+#
+
+#
+# SIR device drivers
+#
+CONFIG_IRTTY_SIR=m
+
+#
+# Dongle support
+#
+# CONFIG_DONGLE is not set
+
+#
+# Old SIR device drivers
+#
+
+#
+# Old Serial dongle support
+#
+
+#
+# FIR device drivers
+#
+CONFIG_NSC_FIR=m
+CONFIG_WINBOND_FIR=m
+CONFIG_SMC_IRCC_FIR=m
+CONFIG_ALI_FIR=m
+CONFIG_VIA_FIR=m
+# CONFIG_BT is not set
+# CONFIG_IEEE80211 is not set
+CONFIG_TUX=m
+
+#
+# TUX options
+#
+CONFIG_TUX_EXTCGI=y
+CONFIG_TUX_EXTENDED_LOG=y
+# CONFIG_TUX_DEBUG is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=m
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_SYS_HYPERVISOR is not set
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+CONFIG_CONNECTOR=y
+CONFIG_PROC_EVENTS=y
+
+#
+# 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_FD=m
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=m
+CONFIG_BLK_DEV_CRYPTOLOOP=m
+CONFIG_BLK_DEV_NBD=m
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=16384
+CONFIG_BLK_DEV_RAM_BLOCKSIZE=4096
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_CDROM_PKTCDVD=m
+CONFIG_CDROM_PKTCDVD_BUFFERS=8
+# CONFIG_CDROM_PKTCDVD_WCACHE is not set
+CONFIG_ATA_OVER_ETH=m
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+CONFIG_IDE=y
+CONFIG_BLK_DEV_IDE=y
+
+#
+# Please see Documentation/ide.txt for help/info on IDE drives
+#
+# CONFIG_BLK_DEV_IDE_SATA is not set
+# CONFIG_BLK_DEV_HD_IDE is not set
+CONFIG_BLK_DEV_IDEDISK=y
+CONFIG_IDEDISK_MULTI_MODE=y
+CONFIG_BLK_DEV_IDECD=m
+# CONFIG_BLK_DEV_IDETAPE is not set
+CONFIG_BLK_DEV_IDEFLOPPY=y
+CONFIG_BLK_DEV_IDESCSI=m
+CONFIG_IDE_TASK_IOCTL=y
+
+#
+# IDE chipset support/bugfixes
+#
+CONFIG_IDE_GENERIC=y
+# CONFIG_BLK_DEV_CMD640 is not set
+# CONFIG_IDE_ARM is not set
+# CONFIG_BLK_DEV_IDEDMA is not set
+# CONFIG_IDEDMA_AUTO is not set
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# SCSI device support
+#
+CONFIG_RAID_ATTRS=m
+CONFIG_SCSI=m
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=m
+CONFIG_CHR_DEV_ST=m
+CONFIG_CHR_DEV_OSST=m
+CONFIG_BLK_DEV_SR=m
+CONFIG_BLK_DEV_SR_VENDOR=y
+CONFIG_CHR_DEV_SG=m
+CONFIG_CHR_DEV_SCH=m
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+CONFIG_SCSI_MULTI_LUN=y
+CONFIG_SCSI_CONSTANTS=y
+CONFIG_SCSI_LOGGING=y
+
+#
+# SCSI Transport Attributes
+#
+CONFIG_SCSI_SPI_ATTRS=m
+CONFIG_SCSI_FC_ATTRS=m
+CONFIG_SCSI_ISCSI_ATTRS=m
+CONFIG_SCSI_SAS_ATTRS=m
+
+#
+# SCSI low-level drivers
+#
+CONFIG_ISCSI_TCP=m
+CONFIG_SCSI_SATA=m
+# CONFIG_SCSI_DEBUG is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+CONFIG_MD=y
+CONFIG_BLK_DEV_MD=y
+CONFIG_MD_LINEAR=m
+CONFIG_MD_RAID0=m
+CONFIG_MD_RAID1=m
+CONFIG_MD_RAID10=m
+CONFIG_MD_RAID456=m
+CONFIG_MD_RAID5_RESHAPE=y
+CONFIG_MD_MULTIPATH=m
+CONFIG_MD_FAULTY=m
+CONFIG_BLK_DEV_DM=m
+CONFIG_DM_CRYPT=m
+CONFIG_DM_SNAPSHOT=m
+CONFIG_DM_MIRROR=m
+CONFIG_DM_ZERO=m
+CONFIG_DM_MULTIPATH=m
+CONFIG_DM_MULTIPATH_EMC=m
+
+#
+# Fusion MPT device support
+#
+# CONFIG_FUSION is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+
+#
+# I2O device support
+#
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+CONFIG_IFB=m
+CONFIG_DUMMY=m
+CONFIG_BONDING=m
+CONFIG_EQUALIZER=m
+CONFIG_TUN=m
+
+#
+# PHY device support
+#
+# CONFIG_PHYLIB is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=m
+
+#
+# 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
+
+#
+# ATM drivers
+#
+# CONFIG_ATM_DUMMY is not set
+CONFIG_ATM_TCP=m
+CONFIG_PPP=m
+CONFIG_PPP_MULTILINK=y
+CONFIG_PPP_FILTER=y
+CONFIG_PPP_ASYNC=m
+CONFIG_PPP_SYNC_TTY=m
+CONFIG_PPP_DEFLATE=m
+# CONFIG_PPP_BSDCOMP is not set
+CONFIG_PPP_MPPE=m
+CONFIG_PPPOE=m
+CONFIG_PPPOATM=m
+CONFIG_SLIP=m
+CONFIG_SLIP_COMPRESSED=y
+CONFIG_SLIP_SMART=y
+# CONFIG_SLIP_MODE_SLIP6 is not set
+# CONFIG_SHAPER is not set
+CONFIG_NETCONSOLE=m
+CONFIG_NETPOLL=y
+# CONFIG_NETPOLL_RX is not set
+CONFIG_NETPOLL_TRAP=y
+CONFIG_NET_POLL_CONTROLLER=y
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Telephony Support
+#
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+
+#
+# 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=m
+# CONFIG_INPUT_TSDEV is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+CONFIG_KEYBOARD_ATKBD=y
+# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_KEYBOARD_LKKBD is not set
+# CONFIG_KEYBOARD_XTKBD is not set
+# CONFIG_KEYBOARD_NEWTON is not set
+CONFIG_INPUT_MOUSE=y
+CONFIG_MOUSE_PS2=y
+CONFIG_MOUSE_SERIAL=m
+CONFIG_MOUSE_VSXXXAA=m
+CONFIG_INPUT_JOYSTICK=y
+CONFIG_JOYSTICK_ANALOG=m
+CONFIG_JOYSTICK_A3D=m
+CONFIG_JOYSTICK_ADI=m
+CONFIG_JOYSTICK_COBRA=m
+CONFIG_JOYSTICK_GF2K=m
+CONFIG_JOYSTICK_GRIP=m
+CONFIG_JOYSTICK_GRIP_MP=m
+CONFIG_JOYSTICK_GUILLEMOT=m
+CONFIG_JOYSTICK_INTERACT=m
+CONFIG_JOYSTICK_SIDEWINDER=m
+CONFIG_JOYSTICK_TMDC=m
+CONFIG_JOYSTICK_IFORCE=m
+CONFIG_JOYSTICK_IFORCE_232=y
+CONFIG_JOYSTICK_WARRIOR=m
+CONFIG_JOYSTICK_MAGELLAN=m
+CONFIG_JOYSTICK_SPACEORB=m
+CONFIG_JOYSTICK_SPACEBALL=m
+CONFIG_JOYSTICK_STINGER=m
+CONFIG_JOYSTICK_TWIDJOY=m
+CONFIG_JOYSTICK_JOYDUMP=m
+CONFIG_INPUT_TOUCHSCREEN=y
+CONFIG_TOUCHSCREEN_GUNZE=m
+CONFIG_TOUCHSCREEN_ELO=m
+CONFIG_TOUCHSCREEN_MTOUCH=m
+CONFIG_TOUCHSCREEN_MK712=m
+CONFIG_INPUT_MISC=y
+CONFIG_INPUT_PCSPKR=m
+CONFIG_INPUT_UINPUT=m
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+CONFIG_SERIO_I8042=y
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_CT82C710 is not set
+CONFIG_SERIO_LIBPS2=y
+CONFIG_SERIO_RAW=m
+CONFIG_GAMEPORT=m
+CONFIG_GAMEPORT_NS558=m
+CONFIG_GAMEPORT_L4=m
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+CONFIG_VT_HW_CONSOLE_BINDING=y
+CONFIG_SERIAL_NONSTANDARD=y
+# CONFIG_COMPUTONE is not set
+# CONFIG_ROCKETPORT is not set
+CONFIG_CYCLADES=m
+# CONFIG_CYZ_INTR is not set
+# CONFIG_DIGIEPCA is not set
+# CONFIG_MOXA_INTELLIO is not set
+# CONFIG_MOXA_SMARTIO is not set
+# CONFIG_ISI is not set
+CONFIG_SYNCLINKMP=m
+CONFIG_N_HDLC=m
+# CONFIG_SPECIALIX is not set
+# CONFIG_SX is not set
+# CONFIG_RIO is not set
+# CONFIG_STALDRV is not set
+
+#
+# Serial drivers
+#
+
+#
+# Non-8250 serial port support
+#
+CONFIG_UNIX98_PTYS=y
+# CONFIG_LEGACY_PTYS is not set
+CONFIG_CRASH=m
+
+#
+# IPMI
+#
+CONFIG_IPMI_HANDLER=m
+# CONFIG_IPMI_PANIC_EVENT is not set
+CONFIG_IPMI_DEVICE_INTERFACE=m
+CONFIG_IPMI_SI=m
+CONFIG_IPMI_WATCHDOG=m
+CONFIG_IPMI_POWEROFF=m
+
+#
+# Watchdog Cards
+#
+CONFIG_WATCHDOG=y
+# CONFIG_WATCHDOG_NOWAYOUT is not set
+
+#
+# Watchdog Device Drivers
+#
+CONFIG_SOFT_WATCHDOG=m
+# CONFIG_ACQUIRE_WDT is not set
+# CONFIG_ADVANTECH_WDT is not set
+# CONFIG_SC520_WDT is not set
+# CONFIG_EUROTECH_WDT is not set
+# CONFIG_IB700_WDT is not set
+CONFIG_IBMASR=m
+# CONFIG_WAFER_WDT is not set
+# CONFIG_SC1200_WDT is not set
+# CONFIG_60XX_WDT is not set
+# CONFIG_SBC8360_WDT is not set
+# CONFIG_CPU5_WDT is not set
+CONFIG_W83627HF_WDT=m
+CONFIG_W83877F_WDT=m
+CONFIG_W83977F_WDT=m
+CONFIG_MACHZ_WDT=m
+# CONFIG_SBC_EPX_C3_WATCHDOG is not set
+CONFIG_HW_RANDOM=y
+CONFIG_NVRAM=y
+CONFIG_RTC=y
+CONFIG_DTLK=m
+CONFIG_R3964=m
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_MWAVE is not set
+CONFIG_PC8736x_GPIO=m
+CONFIG_NSC_GPIO=m
+# CONFIG_RAW_DRIVER is not set
+CONFIG_HANGCHECK_TIMER=m
+
+#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+# CONFIG_TELCLOCK 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
+#
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+CONFIG_VIDEO_V4L2=y
+
+#
+# Digital Video Broadcasting Devices
+#
+# CONFIG_DVB is not set
+
+#
+# Graphics support
+#
+# CONFIG_FIRMWARE_EDID is not set
+CONFIG_FB=y
+CONFIG_FB_CFB_FILLRECT=y
+CONFIG_FB_CFB_COPYAREA=y
+CONFIG_FB_CFB_IMAGEBLIT=y
+# CONFIG_FB_MACMODES is not set
+# CONFIG_FB_BACKLIGHT is not set
+# CONFIG_FB_MODE_HELPERS is not set
+CONFIG_FB_TILEBLITTING=y
+# CONFIG_FB_ARC is not set
+CONFIG_FB_VGA16=m
+CONFIG_FB_VESA=y
+# CONFIG_FB_HGA is not set
+# CONFIG_FB_S1D13XXX is not set
+# CONFIG_FB_VIRTUAL is not set
+
+#
+# Console display driver support
+#
+CONFIG_VGA_CONSOLE=y
+CONFIG_VGACON_SOFT_SCROLLBACK=y
+CONFIG_VGACON_SOFT_SCROLLBACK_SIZE=64
+CONFIG_VIDEO_SELECT=y
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y
+# CONFIG_FONTS is not set
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
+
+#
+# Logo configuration
+#
+CONFIG_LOGO=y
+# CONFIG_LOGO_LINUX_MONO is not set
+# CONFIG_LOGO_LINUX_VGA16 is not set
+CONFIG_LOGO_LINUX_CLUT224=y
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+CONFIG_BACKLIGHT_CLASS_DEVICE=m
+CONFIG_BACKLIGHT_DEVICE=y
+CONFIG_LCD_CLASS_DEVICE=m
+CONFIG_LCD_DEVICE=y
+
+#
+# Sound
+#
+CONFIG_SOUND=m
+
+#
+# Advanced Linux Sound Architecture
+#
+# CONFIG_SND is not set
+
+#
+# Open Sound System
+#
+# CONFIG_SOUND_PRIME is not set
+
+#
+# USB support
+#
+# CONFIG_USB_ARCH_HAS_HCD is not set
+# CONFIG_USB_ARCH_HAS_OHCI is not set
+# CONFIG_USB_ARCH_HAS_EHCI 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
+
+#
+# LED devices
+#
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+
+#
+# LED drivers
+#
+
+#
+# LED Triggers
+#
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_LEDS_TRIGGER_TIMER=m
+CONFIG_LEDS_TRIGGER_IDE_DISK=y
+CONFIG_LEDS_TRIGGER_HEARTBEAT=m
+
+#
+# InfiniBand support
+#
+
+#
+# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
+#
+# CONFIG_EDAC is not set
+
+#
+# Real Time Clock
+#
+CONFIG_RTC_LIB=m
+CONFIG_RTC_CLASS=m
+
+#
+# RTC interfaces
+#
+CONFIG_RTC_INTF_SYSFS=m
+CONFIG_RTC_INTF_PROC=m
+CONFIG_RTC_INTF_DEV=m
+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
+
+#
+# RTC drivers
+#
+CONFIG_RTC_DRV_DS1553=m
+CONFIG_RTC_DRV_DS1742=m
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_TEST is not set
+CONFIG_RTC_DRV_V3020=m
+
+#
+# DMA Engine support
+#
+CONFIG_DMA_ENGINE=y
+
+#
+# DMA Clients
+#
+CONFIG_NET_DMA=y
+
+#
+# DMA Devices
+#
+
+#
+# Firmware Drivers
+#
+CONFIG_DELL_RBU=m
+CONFIG_DCDBAS=m
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+CONFIG_EXT2_FS_POSIX_ACL=y
+CONFIG_EXT2_FS_SECURITY=y
+CONFIG_EXT2_FS_XIP=y
+CONFIG_FS_XIP=y
+CONFIG_EXT3_FS=y
+CONFIG_EXT3_FS_XATTR=y
+CONFIG_EXT3_FS_POSIX_ACL=y
+CONFIG_EXT3_FS_SECURITY=y
+CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
+CONFIG_FS_MBCACHE=y
+CONFIG_REISERFS_FS=m
+# CONFIG_REISERFS_CHECK is not set
+CONFIG_REISERFS_PROC_INFO=y
+CONFIG_REISERFS_FS_XATTR=y
+CONFIG_REISERFS_FS_POSIX_ACL=y
+CONFIG_REISERFS_FS_SECURITY=y
+CONFIG_JFS_FS=m
+CONFIG_JFS_POSIX_ACL=y
+CONFIG_JFS_SECURITY=y
+# CONFIG_JFS_DEBUG is not set
+# CONFIG_JFS_STATISTICS is not set
+CONFIG_FS_POSIX_ACL=y
+CONFIG_XFS_FS=m
+CONFIG_XFS_QUOTA=y
+CONFIG_XFS_SECURITY=y
+CONFIG_XFS_POSIX_ACL=y
+# CONFIG_XFS_RT is not set
+CONFIG_OCFS2_FS=m
+# CONFIG_OCFS2_DEBUG_MASKLOG is not set
+CONFIG_MINIX_FS=m
+CONFIG_ROMFS_FS=m
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+CONFIG_QUOTA=y
+# CONFIG_QFMT_V1 is not set
+CONFIG_QFMT_V2=y
+CONFIG_QUOTACTL=y
+CONFIG_DNOTIFY=y
+CONFIG_AUTOFS_FS=m
+CONFIG_AUTOFS4_FS=m
+CONFIG_FUSE_FS=m
+
+#
+# Caches
+#
+CONFIG_FSCACHE=m
+
+#
+# CD-ROM/DVD Filesystems
+#
+CONFIG_ISO9660_FS=y
+CONFIG_JOLIET=y
+CONFIG_ZISOFS=y
+CONFIG_ZISOFS_FS=y
+CONFIG_UDF_FS=m
+CONFIG_UDF_NLS=y
+CONFIG_CACHEFILES=m
+CONFIG_CACHEFILES_DEBUG=y
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=m
+CONFIG_MSDOS_FS=m
+CONFIG_VFAT_FS=m
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="ascii"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_RAMFS=y
+CONFIG_CONFIGFS_FS=m
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+CONFIG_AFFS_FS=m
+CONFIG_HFS_FS=m
+CONFIG_HFSPLUS_FS=m
+CONFIG_BEFS_FS=m
+# CONFIG_BEFS_DEBUG is not set
+CONFIG_BFS_FS=m
+CONFIG_EFS_FS=m
+CONFIG_CRAMFS=m
+CONFIG_SQUASHFS=m
+# CONFIG_SQUASHFS_EMBEDDED is not set
+CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3
+# CONFIG_SQUASHFS_VMALLOC is not set
+CONFIG_VXFS_FS=m
+# CONFIG_HPFS_FS is not set
+CONFIG_QNX4FS_FS=m
+CONFIG_SYSV_FS=m
+CONFIG_UFS_FS=m
+# CONFIG_UFS_FS_WRITE is not set
+# CONFIG_UFS_DEBUG is not set
+
+#
+# Network File Systems
+#
+CONFIG_NFS_FS=m
+CONFIG_NFS_V3=y
+CONFIG_NFS_V3_ACL=y
+CONFIG_NFS_V4=y
+CONFIG_NFS_FSCACHE=y
+CONFIG_NFS_DIRECTIO=y
+CONFIG_NFSD=m
+CONFIG_NFSD_V2_ACL=y
+CONFIG_NFSD_V3=y
+CONFIG_NFSD_V3_ACL=y
+CONFIG_NFSD_V4=y
+CONFIG_NFSD_TCP=y
+CONFIG_LOCKD=m
+CONFIG_LOCKD_V4=y
+CONFIG_EXPORTFS=m
+CONFIG_NFS_ACL_SUPPORT=m
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=m
+CONFIG_SUNRPC_GSS=m
+CONFIG_RPCSEC_GSS_KRB5=m
+CONFIG_RPCSEC_GSS_SPKM3=m
+# CONFIG_SMB_FS is not set
+CONFIG_CIFS=m
+# CONFIG_CIFS_STATS is not set
+CONFIG_CIFS_WEAK_PW_HASH=y
+CONFIG_CIFS_XATTR=y
+CONFIG_CIFS_POSIX=y
+# CONFIG_CIFS_DEBUG2 is not set
+# CONFIG_CIFS_EXPERIMENTAL is not set
+CONFIG_NCP_FS=m
+CONFIG_NCPFS_PACKET_SIGNING=y
+CONFIG_NCPFS_IOCTL_LOCKING=y
+CONFIG_NCPFS_STRONG=y
+CONFIG_NCPFS_NFS_NS=y
+CONFIG_NCPFS_OS2_NS=y
+CONFIG_NCPFS_SMALLDOS=y
+CONFIG_NCPFS_NLS=y
+CONFIG_NCPFS_EXTRAS=y
+CONFIG_CODA_FS=m
+# CONFIG_CODA_FS_OLD_API is not set
+# CONFIG_AFS_FS is not set
+CONFIG_9P_FS=m
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+CONFIG_OSF_PARTITION=y
+CONFIG_AMIGA_PARTITION=y
+# CONFIG_ATARI_PARTITION is not set
+CONFIG_MAC_PARTITION=y
+CONFIG_MSDOS_PARTITION=y
+CONFIG_BSD_DISKLABEL=y
+CONFIG_MINIX_SUBPARTITION=y
+CONFIG_SOLARIS_X86_PARTITION=y
+CONFIG_UNIXWARE_DISKLABEL=y
+# CONFIG_LDM_PARTITION is not set
+CONFIG_SGI_PARTITION=y
+# CONFIG_ULTRIX_PARTITION is not set
+CONFIG_SUN_PARTITION=y
+CONFIG_KARMA_PARTITION=y
+CONFIG_EFI_PARTITION=y
+
+#
+# Native Language Support
+#
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="utf8"
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_CODEPAGE_737=m
+CONFIG_NLS_CODEPAGE_775=m
+CONFIG_NLS_CODEPAGE_850=m
+CONFIG_NLS_CODEPAGE_852=m
+CONFIG_NLS_CODEPAGE_855=m
+CONFIG_NLS_CODEPAGE_857=m
+CONFIG_NLS_CODEPAGE_860=m
+CONFIG_NLS_CODEPAGE_861=m
+CONFIG_NLS_CODEPAGE_862=m
+CONFIG_NLS_CODEPAGE_863=m
+CONFIG_NLS_CODEPAGE_864=m
+CONFIG_NLS_CODEPAGE_865=m
+CONFIG_NLS_CODEPAGE_866=m
+CONFIG_NLS_CODEPAGE_869=m
+CONFIG_NLS_CODEPAGE_936=m
+CONFIG_NLS_CODEPAGE_950=m
+CONFIG_NLS_CODEPAGE_932=m
+CONFIG_NLS_CODEPAGE_949=m
+CONFIG_NLS_CODEPAGE_874=m
+CONFIG_NLS_ISO8859_8=m
+CONFIG_NLS_CODEPAGE_1250=m
+CONFIG_NLS_CODEPAGE_1251=m
+CONFIG_NLS_ASCII=y
+CONFIG_NLS_ISO8859_1=m
+CONFIG_NLS_ISO8859_2=m
+CONFIG_NLS_ISO8859_3=m
+CONFIG_NLS_ISO8859_4=m
+CONFIG_NLS_ISO8859_5=m
+CONFIG_NLS_ISO8859_6=m
+CONFIG_NLS_ISO8859_7=m
+CONFIG_NLS_ISO8859_9=m
+CONFIG_NLS_ISO8859_13=m
+CONFIG_NLS_ISO8859_14=m
+CONFIG_NLS_ISO8859_15=m
+CONFIG_NLS_KOI8_R=m
+CONFIG_NLS_KOI8_U=m
+CONFIG_NLS_UTF8=m
+
+#
+# Instrumentation Support
+#
+CONFIG_PROFILING=y
+CONFIG_OPROFILE=m
+CONFIG_KPROBES=y
+
+#
+# Kernel hacking
+#
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+# CONFIG_PRINTK_TIME is not set
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_UNUSED_SYMBOLS is not set
+CONFIG_DEBUG_KERNEL=y
+CONFIG_LOG_BUF_SHIFT=17
+CONFIG_DETECT_SOFTLOCKUP=y
+CONFIG_SCHEDSTATS=y
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
+CONFIG_DEBUG_SPINLOCK=y
+# CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_RWSEMS is not set
+CONFIG_DEBUG_SPINLOCK_SLEEP=y
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+# CONFIG_DEBUG_KOBJECT is not set
+CONFIG_DEBUG_INFO=y
+CONFIG_DEBUG_FS=y
+# CONFIG_DEBUG_VM is not set
+CONFIG_DEBUG_LIST=y
+# CONFIG_FRAME_POINTER is not set
+# CONFIG_FORCED_INLINING is not set
+CONFIG_BOOT_DELAY=y
+# CONFIG_RCU_TORTURE_TEST is not set
+CONFIG_DEBUG_RODATA=y
+CONFIG_DEBUG_STACKOVERFLOW=y
+# CONFIG_DEBUG_STACK_USAGE is not set
+
+#
+# Security options
+#
+CONFIG_KEYS=y
+CONFIG_KEYS_DEBUG_PROC_KEYS=y
+CONFIG_SECURITY=y
+CONFIG_SECURITY_NETWORK=y
+# CONFIG_SECURITY_NETWORK_XFRM is not set
+CONFIG_SECURITY_CAPABILITIES=y
+# CONFIG_SECURITY_SECLVL is not set
+CONFIG_SECURITY_SELINUX=y
+CONFIG_SECURITY_SELINUX_BOOTPARAM=y
+CONFIG_SECURITY_SELINUX_BOOTPARAM_VALUE=1
+CONFIG_SECURITY_SELINUX_DISABLE=y
+CONFIG_SECURITY_SELINUX_DEVELOP=y
+CONFIG_SECURITY_SELINUX_AVC_STATS=y
+CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE=1
+# CONFIG_SECURITY_SELINUX_ENABLE_SECMARK_DEFAULT is not set
+# CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX is not set
+
+#
+# Cryptographic options
+#
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_NULL=m
+CONFIG_CRYPTO_MD4=m
+CONFIG_CRYPTO_MD5=m
+CONFIG_CRYPTO_SHA1=y
+CONFIG_CRYPTO_SHA256=m
+CONFIG_CRYPTO_SHA512=m
+CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_TGR192=m
+CONFIG_CRYPTO_DES=m
+CONFIG_CRYPTO_BLOWFISH=m
+CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_SERPENT=m
+CONFIG_CRYPTO_AES=m
+CONFIG_CRYPTO_AES_X86_64=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_TEST is not set
+CONFIG_CRYPTO_SIGNATURE=y
+CONFIG_CRYPTO_SIGNATURE_DSA=y
+CONFIG_CRYPTO_MPILIB=y
+
+#
+# Hardware crypto devices
+#
+CONFIG_XEN=y
+CONFIG_XEN_INTERFACE_VERSION=0x00030203
+
+#
+# XEN
+#
+# CONFIG_XEN_PRIVILEGED_GUEST is not set
+CONFIG_XEN_UNPRIVILEGED_GUEST=y
+CONFIG_XEN_PRIVCMD=y
+CONFIG_XEN_XENBUS_DEV=y
+CONFIG_XEN_BACKEND=y
+# CONFIG_XEN_BLKDEV_BACKEND is not set
+CONFIG_XEN_BLKDEV_TAP=m
+# CONFIG_XEN_NETDEV_BACKEND is not set
+# CONFIG_XEN_TPMDEV_BACKEND is not set
+CONFIG_XEN_BLKDEV_FRONTEND=y
+CONFIG_XEN_NETDEV_FRONTEND=m
+CONFIG_XEN_FRAMEBUFFER=y
+CONFIG_XEN_KEYBOARD=y
+CONFIG_XEN_SCRUB_PAGES=y
+CONFIG_XEN_DISABLE_SERIAL=y
+CONFIG_XEN_SYSFS=y
+CONFIG_XEN_COMPAT_030002_AND_LATER=y
+# CONFIG_XEN_COMPAT_LATEST_ONLY is not set
+CONFIG_XEN_COMPAT_030002=y
+CONFIG_HAVE_ARCH_ALLOC_SKB=y
+CONFIG_HAVE_ARCH_DEV_ALLOC_SKB=y
+CONFIG_HAVE_IRQ_IGNORE_UNHANDLED=y
+CONFIG_NO_IDLE_HZ=y
+CONFIG_XEN_UTIL=y
+CONFIG_XEN_BALLOON=y
+CONFIG_XEN_DEVMEM=y
+CONFIG_XEN_SKBUFF=y
+CONFIG_XEN_REBOOT=y
+CONFIG_XEN_SMPBOOT=y
+
+#
+# Library routines
+#
+CONFIG_CRC_CCITT=m
+CONFIG_CRC16=m
+CONFIG_CRC32=y
+CONFIG_LIBCRC32C=m
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=m
+CONFIG_TEXTSEARCH=y
+CONFIG_TEXTSEARCH_KMP=m
+CONFIG_TEXTSEARCH_BM=m
+CONFIG_TEXTSEARCH_FSM=m
+CONFIG_PLIST=y
diff --git a/configs/kernel-2.6.18-x86_64.config b/configs/kernel-2.6.18-x86_64.config
new file mode 100644
index 000000000..16135f6c2
--- /dev/null
+++ b/configs/kernel-2.6.18-x86_64.config
@@ -0,0 +1,3150 @@
+# x86_64
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.18.2-rc1
+# Mon Nov 13 09:44:43 2006
+#
+CONFIG_X86_64=y
+CONFIG_64BIT=y
+CONFIG_X86=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_SEMAPHORE_SLEEPERS=y
+CONFIG_MMU=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_X86_CMPXCHG=y
+CONFIG_EARLY_PRINTK=y
+CONFIG_GENERIC_ISA_DMA=y
+CONFIG_GENERIC_IOMAP=y
+CONFIG_ARCH_MAY_HAVE_PC_FDC=y
+CONFIG_DMI=y
+CONFIG_AUDIT_ARCH=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_BSD_PROCESS_ACCT=y
+# CONFIG_BSD_PROCESS_ACCT_V3 is not set
+CONFIG_TASKSTATS=y
+CONFIG_TASK_DELAY_ACCT=y
+CONFIG_AUDIT=y
+CONFIG_AUDITSYSCALL=y
+# CONFIG_IKCONFIG is not set
+CONFIG_CPUSETS=y
+CONFIG_RELAY=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+# CONFIG_EMBEDDED is not set
+CONFIG_UID16=y
+CONFIG_SYSCTL=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
+CONFIG_KALLSYMS_EXTRA_PASS=y
+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=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+CONFIG_MODULE_SIG=y
+# CONFIG_MODULE_SIG_FORCE is not set
+CONFIG_KMOD=y
+CONFIG_STOP_MACHINE=y
+
+#
+# Process debugging support
+#
+CONFIG_UTRACE=y
+CONFIG_PTRACE=y
+
+#
+# Block layer
+#
+CONFIG_LBD=y
+CONFIG_BLK_DEV_IO_TRACE=y
+CONFIG_LSF=y
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_DEFAULT_AS is not set
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+
+#
+# Processor type and features
+#
+CONFIG_X86_PC=y
+# CONFIG_X86_VSMP is not set
+# CONFIG_MK8 is not set
+# CONFIG_MPSC is not set
+CONFIG_GENERIC_CPU=y
+# CONFIG_X86_64_XEN is not set
+CONFIG_X86_L1_CACHE_BYTES=128
+CONFIG_X86_L1_CACHE_SHIFT=7
+CONFIG_X86_INTERNODE_CACHE_BYTES=128
+CONFIG_X86_TSC=y
+CONFIG_X86_GOOD_APIC=y
+CONFIG_MICROCODE=m
+CONFIG_X86_MSR=y
+CONFIG_X86_CPUID=y
+CONFIG_X86_HT=y
+CONFIG_X86_IO_APIC=y
+CONFIG_X86_LOCAL_APIC=y
+CONFIG_MTRR=y
+CONFIG_SMP=y
+CONFIG_SCHED_SMT=y
+CONFIG_SCHED_MC=y
+# CONFIG_PREEMPT_NONE is not set
+CONFIG_PREEMPT_VOLUNTARY=y
+# CONFIG_PREEMPT is not set
+CONFIG_PREEMPT_BKL=y
+CONFIG_NUMA=y
+CONFIG_K8_NUMA=y
+CONFIG_NODES_SHIFT=6
+CONFIG_X86_64_ACPI_NUMA=y
+# CONFIG_NUMA_EMU is not set
+CONFIG_ARCH_DISCONTIGMEM_ENABLE=y
+CONFIG_ARCH_DISCONTIGMEM_DEFAULT=y
+CONFIG_ARCH_SPARSEMEM_ENABLE=y
+CONFIG_SELECT_MEMORY_MODEL=y
+# CONFIG_FLATMEM_MANUAL is not set
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+CONFIG_SPARSEMEM_MANUAL=y
+CONFIG_SPARSEMEM=y
+CONFIG_NEED_MULTIPLE_NODES=y
+CONFIG_HAVE_MEMORY_PRESENT=y
+# CONFIG_SPARSEMEM_STATIC is not set
+CONFIG_SPARSEMEM_EXTREME=y
+
+#
+# Memory hotplug is currently incompatible with Software Suspend
+#
+CONFIG_SPLIT_PTLOCK_CPUS=4
+CONFIG_MIGRATION=y
+CONFIG_RESOURCES_64BIT=y
+CONFIG_HAVE_ARCH_EARLY_PFN_TO_NID=y
+CONFIG_NR_CPUS=255
+CONFIG_HOTPLUG_CPU=y
+CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
+CONFIG_HPET_TIMER=y
+CONFIG_HPET_EMULATE_RTC=y
+CONFIG_IOMMU=y
+CONFIG_CALGARY_IOMMU=y
+CONFIG_SWIOTLB=y
+CONFIG_X86_MCE=y
+CONFIG_X86_MCE_INTEL=y
+CONFIG_X86_MCE_AMD=y
+CONFIG_KEXEC=y
+# CONFIG_CRASH_DUMP is not set
+CONFIG_PHYSICAL_START=0x200000
+# CONFIG_SECCOMP is not set
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
+CONFIG_REORDER=y
+CONFIG_K8_NB=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_ISA_DMA_API=y
+CONFIG_GENERIC_PENDING_IRQ=y
+
+#
+# Power management options
+#
+CONFIG_PM=y
+CONFIG_PM_LEGACY=y
+# CONFIG_PM_DEBUG is not set
+CONFIG_SOFTWARE_SUSPEND=y
+CONFIG_PM_STD_PARTITION=""
+CONFIG_SUSPEND_SMP=y
+
+#
+# ACPI (Advanced Configuration and Power Interface) Support
+#
+CONFIG_ACPI=y
+CONFIG_ACPI_SLEEP=y
+CONFIG_ACPI_SLEEP_PROC_FS=y
+# CONFIG_ACPI_SLEEP_PROC_SLEEP is not set
+CONFIG_ACPI_AC=m
+CONFIG_ACPI_BATTERY=m
+CONFIG_ACPI_BUTTON=m
+CONFIG_ACPI_VIDEO=m
+# CONFIG_ACPI_HOTKEY is not set
+CONFIG_ACPI_FAN=y
+CONFIG_ACPI_DOCK=m
+CONFIG_ACPI_PROCESSOR=y
+CONFIG_ACPI_HOTPLUG_CPU=y
+CONFIG_ACPI_THERMAL=y
+CONFIG_ACPI_NUMA=y
+CONFIG_ACPI_ASUS=m
+CONFIG_ACPI_IBM=m
+CONFIG_ACPI_TOSHIBA=m
+CONFIG_ACPI_BLACKLIST_YEAR=0
+# CONFIG_ACPI_DEBUG is not set
+CONFIG_ACPI_EC=y
+CONFIG_ACPI_POWER=y
+CONFIG_ACPI_SYSTEM=y
+CONFIG_X86_PM_TIMER=y
+CONFIG_ACPI_CONTAINER=y
+CONFIG_ACPI_SBS=m
+
+#
+# CPU Frequency scaling
+#
+CONFIG_CPU_FREQ=y
+CONFIG_CPU_FREQ_TABLE=y
+CONFIG_CPU_FREQ_DEBUG=y
+CONFIG_CPU_FREQ_STAT=m
+CONFIG_CPU_FREQ_STAT_DETAILS=y
+# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set
+CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE=y
+CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
+CONFIG_CPU_FREQ_GOV_POWERSAVE=m
+CONFIG_CPU_FREQ_GOV_USERSPACE=y
+CONFIG_CPU_FREQ_GOV_ONDEMAND=m
+CONFIG_CPU_FREQ_GOV_CONSERVATIVE=m
+
+#
+# CPUFreq processor drivers
+#
+CONFIG_X86_POWERNOW_K8=y
+CONFIG_X86_POWERNOW_K8_ACPI=y
+CONFIG_X86_SPEEDSTEP_CENTRINO=y
+CONFIG_X86_SPEEDSTEP_CENTRINO_ACPI=y
+CONFIG_X86_ACPI_CPUFREQ=m
+
+#
+# shared options
+#
+# CONFIG_X86_ACPI_CPUFREQ_PROC_INTF is not set
+# CONFIG_X86_SPEEDSTEP_LIB is not set
+
+#
+# Bus options (PCI etc.)
+#
+CONFIG_PCI=y
+CONFIG_PCI_DIRECT=y
+CONFIG_PCI_MMCONFIG=y
+CONFIG_PCIEPORTBUS=y
+CONFIG_HOTPLUG_PCI_PCIE=m
+# CONFIG_HOTPLUG_PCI_PCIE_POLL_EVENT_MODE is not set
+CONFIG_PCI_MSI=y
+# CONFIG_PCI_DEBUG is not set
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+CONFIG_PCCARD=y
+# CONFIG_PCMCIA_DEBUG is not set
+CONFIG_PCMCIA=y
+CONFIG_PCMCIA_LOAD_CIS=y
+CONFIG_PCMCIA_IOCTL=y
+CONFIG_CARDBUS=y
+
+#
+# PC-card bridges
+#
+CONFIG_YENTA=y
+CONFIG_YENTA_O2=y
+CONFIG_YENTA_RICOH=y
+CONFIG_YENTA_TI=y
+CONFIG_YENTA_ENE_TUNE=y
+CONFIG_YENTA_TOSHIBA=y
+CONFIG_PD6729=m
+CONFIG_I82092=m
+CONFIG_PCCARD_NONSTATIC=y
+
+#
+# PCI Hotplug Support
+#
+CONFIG_HOTPLUG_PCI=y
+CONFIG_HOTPLUG_PCI_FAKE=m
+CONFIG_HOTPLUG_PCI_ACPI=m
+CONFIG_HOTPLUG_PCI_ACPI_IBM=m
+# CONFIG_HOTPLUG_PCI_CPCI is not set
+CONFIG_HOTPLUG_PCI_SHPC=m
+# CONFIG_HOTPLUG_PCI_SHPC_POLL_EVENT_MODE is not set
+
+#
+# Executable file formats / Emulations
+#
+CONFIG_BINFMT_ELF=y
+CONFIG_BINFMT_MISC=y
+CONFIG_IA32_EMULATION=y
+# CONFIG_IA32_AOUT is not set
+CONFIG_COMPAT=y
+CONFIG_SYSVIPC_COMPAT=y
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+# CONFIG_NETDEBUG is not set
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=y
+CONFIG_NET_KEY=m
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_ASK_IP_FIB_HASH=y
+# 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
+# CONFIG_IP_PNP is not set
+CONFIG_NET_IPIP=m
+CONFIG_NET_IPGRE=m
+CONFIG_NET_IPGRE_BROADCAST=y
+CONFIG_IP_MROUTE=y
+CONFIG_IP_PIMSM_V1=y
+CONFIG_IP_PIMSM_V2=y
+# CONFIG_ARPD is not set
+CONFIG_SYN_COOKIES=y
+CONFIG_INET_AH=m
+CONFIG_INET_ESP=m
+CONFIG_INET_IPCOMP=m
+CONFIG_INET_XFRM_TUNNEL=m
+CONFIG_INET_TUNNEL=m
+CONFIG_INET_XFRM_MODE_TRANSPORT=m
+CONFIG_INET_XFRM_MODE_TUNNEL=m
+CONFIG_INET_DIAG=m
+CONFIG_INET_TCP_DIAG=m
+CONFIG_TCP_CONG_ADVANCED=y
+
+#
+# TCP congestion control
+#
+CONFIG_TCP_CONG_BIC=y
+CONFIG_TCP_CONG_CUBIC=m
+CONFIG_TCP_CONG_WESTWOOD=m
+CONFIG_TCP_CONG_HTCP=m
+CONFIG_TCP_CONG_HSTCP=m
+CONFIG_TCP_CONG_HYBLA=m
+CONFIG_TCP_CONG_VEGAS=m
+CONFIG_TCP_CONG_SCALABLE=m
+CONFIG_TCP_CONG_LP=m
+CONFIG_TCP_CONG_VENO=m
+
+#
+# IP: Virtual Server Configuration
+#
+CONFIG_IP_VS=m
+# CONFIG_IP_VS_DEBUG is not set
+CONFIG_IP_VS_TAB_BITS=12
+
+#
+# IPVS transport protocol load balancing support
+#
+CONFIG_IP_VS_PROTO_TCP=y
+CONFIG_IP_VS_PROTO_UDP=y
+CONFIG_IP_VS_PROTO_ESP=y
+CONFIG_IP_VS_PROTO_AH=y
+
+#
+# IPVS scheduler
+#
+CONFIG_IP_VS_RR=m
+CONFIG_IP_VS_WRR=m
+CONFIG_IP_VS_LC=m
+CONFIG_IP_VS_WLC=m
+CONFIG_IP_VS_LBLC=m
+CONFIG_IP_VS_LBLCR=m
+CONFIG_IP_VS_DH=m
+CONFIG_IP_VS_SH=m
+CONFIG_IP_VS_SED=m
+CONFIG_IP_VS_NQ=m
+
+#
+# IPVS application helper
+#
+CONFIG_IP_VS_FTP=m
+CONFIG_IPV6=m
+CONFIG_IPV6_PRIVACY=y
+CONFIG_IPV6_ROUTER_PREF=y
+CONFIG_IPV6_ROUTE_INFO=y
+CONFIG_INET6_AH=m
+CONFIG_INET6_ESP=m
+CONFIG_INET6_IPCOMP=m
+CONFIG_INET6_XFRM_TUNNEL=m
+CONFIG_INET6_TUNNEL=m
+CONFIG_INET6_XFRM_MODE_TRANSPORT=m
+CONFIG_INET6_XFRM_MODE_TUNNEL=m
+CONFIG_IPV6_TUNNEL=m
+CONFIG_NETWORK_SECMARK=y
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_DEBUG is not set
+CONFIG_BRIDGE_NETFILTER=y
+
+#
+# Core Netfilter Configuration
+#
+CONFIG_NETFILTER_NETLINK=m
+CONFIG_NETFILTER_NETLINK_QUEUE=m
+CONFIG_NETFILTER_NETLINK_LOG=m
+CONFIG_NETFILTER_XTABLES=m
+CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
+CONFIG_NETFILTER_XT_TARGET_CONNMARK=m
+CONFIG_NETFILTER_XT_TARGET_MARK=m
+CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
+CONFIG_NETFILTER_XT_TARGET_NOTRACK=m
+CONFIG_NETFILTER_XT_TARGET_SECMARK=m
+CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=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_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_PHYSDEV=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
+
+#
+# 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=m
+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_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_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_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
+CONFIG_IP_NF_ARPTABLES=m
+CONFIG_IP_NF_ARPFILTER=m
+CONFIG_IP_NF_ARP_MANGLE=m
+
+#
+# IPv6: Netfilter Configuration (EXPERIMENTAL)
+#
+CONFIG_IP6_NF_QUEUE=m
+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_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
+
+#
+# DECnet: Netfilter Configuration
+#
+# CONFIG_DECNET_NF_GRABULATOR is not set
+
+#
+# Bridge: Netfilter Configuration
+#
+CONFIG_BRIDGE_NF_EBTABLES=m
+CONFIG_BRIDGE_EBT_BROUTE=m
+CONFIG_BRIDGE_EBT_T_FILTER=m
+CONFIG_BRIDGE_EBT_T_NAT=m
+CONFIG_BRIDGE_EBT_802_3=m
+CONFIG_BRIDGE_EBT_AMONG=m
+CONFIG_BRIDGE_EBT_ARP=m
+CONFIG_BRIDGE_EBT_IP=m
+CONFIG_BRIDGE_EBT_LIMIT=m
+CONFIG_BRIDGE_EBT_MARK=m
+CONFIG_BRIDGE_EBT_PKTTYPE=m
+CONFIG_BRIDGE_EBT_STP=m
+CONFIG_BRIDGE_EBT_VLAN=m
+CONFIG_BRIDGE_EBT_ARPREPLY=m
+CONFIG_BRIDGE_EBT_DNAT=m
+CONFIG_BRIDGE_EBT_MARK_T=m
+CONFIG_BRIDGE_EBT_REDIRECT=m
+CONFIG_BRIDGE_EBT_SNAT=m
+CONFIG_BRIDGE_EBT_LOG=m
+CONFIG_BRIDGE_EBT_ULOG=m
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+CONFIG_IP_DCCP=m
+CONFIG_INET_DCCP_DIAG=m
+CONFIG_IP_DCCP_ACKVEC=y
+
+#
+# DCCP CCIDs Configuration (EXPERIMENTAL)
+#
+CONFIG_IP_DCCP_CCID2=m
+CONFIG_IP_DCCP_CCID3=m
+CONFIG_IP_DCCP_TFRC_LIB=m
+
+#
+# DCCP Kernel Hacking
+#
+# CONFIG_IP_DCCP_DEBUG is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+CONFIG_IP_SCTP=m
+# CONFIG_SCTP_DBG_MSG is not set
+# CONFIG_SCTP_DBG_OBJCNT is not set
+# CONFIG_SCTP_HMAC_NONE is not set
+# CONFIG_SCTP_HMAC_SHA1 is not set
+CONFIG_SCTP_HMAC_MD5=y
+
+#
+# TIPC Configuration (EXPERIMENTAL)
+#
+CONFIG_TIPC=m
+# CONFIG_TIPC_ADVANCED is not set
+# CONFIG_TIPC_DEBUG is not set
+CONFIG_ATM=m
+CONFIG_ATM_CLIP=m
+# CONFIG_ATM_CLIP_NO_ICMP is not set
+CONFIG_ATM_LANE=m
+# CONFIG_ATM_MPOA is not set
+CONFIG_ATM_BR2684=m
+# CONFIG_ATM_BR2684_IPFILTER is not set
+CONFIG_BRIDGE=m
+CONFIG_VLAN_8021Q=m
+CONFIG_DECNET=m
+CONFIG_DECNET_ROUTER=y
+CONFIG_DECNET_ROUTE_FWMARK=y
+CONFIG_LLC=y
+# CONFIG_LLC2 is not set
+CONFIG_IPX=m
+# CONFIG_IPX_INTERN is not set
+CONFIG_ATALK=m
+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_ECONET is not set
+CONFIG_WAN_ROUTER=m
+
+#
+# QoS and/or fair queueing
+#
+CONFIG_NET_SCHED=y
+# CONFIG_NET_SCH_CLK_JIFFIES is not set
+CONFIG_NET_SCH_CLK_GETTIMEOFDAY=y
+# CONFIG_NET_SCH_CLK_CPU is not set
+
+#
+# Queueing/Scheduling
+#
+CONFIG_NET_SCH_CBQ=m
+CONFIG_NET_SCH_HTB=m
+CONFIG_NET_SCH_HFSC=m
+CONFIG_NET_SCH_ATM=m
+CONFIG_NET_SCH_PRIO=m
+CONFIG_NET_SCH_RED=m
+CONFIG_NET_SCH_SFQ=m
+CONFIG_NET_SCH_TEQL=m
+CONFIG_NET_SCH_TBF=m
+CONFIG_NET_SCH_GRED=m
+CONFIG_NET_SCH_DSMARK=m
+CONFIG_NET_SCH_NETEM=m
+CONFIG_NET_SCH_INGRESS=m
+
+#
+# Classification
+#
+CONFIG_NET_CLS=y
+CONFIG_NET_CLS_BASIC=m
+CONFIG_NET_CLS_TCINDEX=m
+CONFIG_NET_CLS_ROUTE4=m
+CONFIG_NET_CLS_ROUTE=y
+CONFIG_NET_CLS_FW=m
+CONFIG_NET_CLS_U32=m
+CONFIG_CLS_U32_PERF=y
+CONFIG_CLS_U32_MARK=y
+CONFIG_NET_CLS_RSVP=m
+CONFIG_NET_CLS_RSVP6=m
+CONFIG_NET_EMATCH=y
+CONFIG_NET_EMATCH_STACK=32
+CONFIG_NET_EMATCH_CMP=m
+CONFIG_NET_EMATCH_NBYTE=m
+CONFIG_NET_EMATCH_U32=m
+CONFIG_NET_EMATCH_META=m
+CONFIG_NET_EMATCH_TEXT=m
+CONFIG_NET_CLS_ACT=y
+CONFIG_NET_ACT_POLICE=m
+CONFIG_NET_ACT_GACT=m
+CONFIG_GACT_PROB=y
+CONFIG_NET_ACT_MIRRED=m
+CONFIG_NET_ACT_IPT=m
+CONFIG_NET_ACT_PEDIT=m
+CONFIG_NET_ACT_SIMP=m
+CONFIG_NET_CLS_IND=y
+CONFIG_NET_ESTIMATOR=y
+
+#
+# Network testing
+#
+CONFIG_NET_PKTGEN=m
+# CONFIG_NET_TCPPROBE is not set
+# CONFIG_HAMRADIO is not set
+CONFIG_IRDA=m
+
+#
+# IrDA protocols
+#
+CONFIG_IRLAN=m
+CONFIG_IRNET=m
+CONFIG_IRCOMM=m
+# CONFIG_IRDA_ULTRA is not set
+
+#
+# IrDA options
+#
+CONFIG_IRDA_CACHE_LAST_LSAP=y
+CONFIG_IRDA_FAST_RR=y
+# CONFIG_IRDA_DEBUG is not set
+
+#
+# Infrared-port device drivers
+#
+
+#
+# SIR device drivers
+#
+CONFIG_IRTTY_SIR=m
+
+#
+# Dongle support
+#
+CONFIG_DONGLE=y
+CONFIG_ESI_DONGLE=m
+CONFIG_ACTISYS_DONGLE=m
+CONFIG_TEKRAM_DONGLE=m
+CONFIG_TOIM3232_DONGLE=m
+CONFIG_LITELINK_DONGLE=m
+CONFIG_MA600_DONGLE=m
+CONFIG_GIRBIL_DONGLE=m
+CONFIG_MCP2120_DONGLE=m
+CONFIG_OLD_BELKIN_DONGLE=m
+CONFIG_ACT200L_DONGLE=m
+
+#
+# Old SIR device drivers
+#
+
+#
+# Old Serial dongle support
+#
+
+#
+# FIR device drivers
+#
+CONFIG_USB_IRDA=m
+CONFIG_SIGMATEL_FIR=m
+CONFIG_NSC_FIR=m
+CONFIG_WINBOND_FIR=m
+CONFIG_SMC_IRCC_FIR=m
+CONFIG_ALI_FIR=m
+CONFIG_VLSI_FIR=m
+CONFIG_VIA_FIR=m
+CONFIG_MCS_FIR=m
+CONFIG_BT=m
+CONFIG_BT_L2CAP=m
+CONFIG_BT_SCO=m
+CONFIG_BT_RFCOMM=m
+CONFIG_BT_RFCOMM_TTY=y
+CONFIG_BT_BNEP=m
+CONFIG_BT_BNEP_MC_FILTER=y
+CONFIG_BT_BNEP_PROTO_FILTER=y
+CONFIG_BT_CMTP=m
+CONFIG_BT_HIDP=m
+
+#
+# Bluetooth device drivers
+#
+CONFIG_BT_HCIUSB=m
+CONFIG_BT_HCIUSB_SCO=y
+CONFIG_BT_HCIUART=m
+CONFIG_BT_HCIUART_H4=y
+CONFIG_BT_HCIUART_BCSP=y
+CONFIG_BT_HCIBCM203X=m
+CONFIG_BT_HCIBPA10X=m
+CONFIG_BT_HCIBFUSB=m
+CONFIG_BT_HCIDTL1=m
+CONFIG_BT_HCIBT3C=m
+CONFIG_BT_HCIBLUECARD=m
+CONFIG_BT_HCIBTUART=m
+CONFIG_BT_HCIVHCI=m
+CONFIG_IEEE80211=m
+# CONFIG_IEEE80211_DEBUG is not set
+CONFIG_IEEE80211_CRYPT_WEP=m
+CONFIG_IEEE80211_CRYPT_CCMP=m
+CONFIG_IEEE80211_CRYPT_TKIP=m
+CONFIG_IEEE80211_SOFTMAC=m
+CONFIG_IEEE80211_SOFTMAC_DEBUG=y
+CONFIG_TUX=m
+
+#
+# TUX options
+#
+CONFIG_TUX_EXTCGI=y
+CONFIG_TUX_EXTENDED_LOG=y
+# CONFIG_TUX_DEBUG is not set
+CONFIG_WIRELESS_EXT=y
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_SYS_HYPERVISOR is not set
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+CONFIG_CONNECTOR=y
+CONFIG_PROC_EVENTS=y
+
+#
+# Memory Technology Devices (MTD)
+#
+CONFIG_MTD=m
+# CONFIG_MTD_DEBUG is not set
+CONFIG_MTD_CONCAT=m
+CONFIG_MTD_PARTITIONS=y
+CONFIG_MTD_REDBOOT_PARTS=m
+CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1
+# CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED is not set
+# CONFIG_MTD_REDBOOT_PARTS_READONLY is not set
+CONFIG_MTD_CMDLINE_PARTS=y
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=m
+CONFIG_MTD_BLOCK=m
+CONFIG_MTD_BLOCK_RO=m
+CONFIG_FTL=m
+CONFIG_NFTL=m
+CONFIG_NFTL_RW=y
+CONFIG_INFTL=m
+CONFIG_RFD_FTL=m
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=m
+CONFIG_MTD_JEDECPROBE=m
+CONFIG_MTD_GEN_PROBE=m
+# CONFIG_MTD_CFI_ADV_OPTIONS 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_CFI_INTELEXT=m
+CONFIG_MTD_CFI_AMDSTD=m
+CONFIG_MTD_CFI_STAA=m
+CONFIG_MTD_CFI_UTIL=m
+CONFIG_MTD_RAM=m
+CONFIG_MTD_ROM=m
+CONFIG_MTD_ABSENT=m
+# CONFIG_MTD_OBSOLETE_CHIPS is not set
+
+#
+# Mapping drivers for chip access
+#
+CONFIG_MTD_COMPLEX_MAPPINGS=y
+# CONFIG_MTD_PHYSMAP is not set
+# CONFIG_MTD_PNC2000 is not set
+CONFIG_MTD_SC520CDP=m
+CONFIG_MTD_NETSC520=m
+CONFIG_MTD_TS5500=m
+# CONFIG_MTD_SBC_GXX is not set
+# CONFIG_MTD_AMD76XROM is not set
+# CONFIG_MTD_ICHXROM is not set
+CONFIG_MTD_SCB2_FLASH=m
+# CONFIG_MTD_NETtel is not set
+# CONFIG_MTD_DILNETPC is not set
+# CONFIG_MTD_L440GX is not set
+CONFIG_MTD_PCI=m
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+CONFIG_MTD_PMC551=m
+# CONFIG_MTD_PMC551_BUGFIX is not set
+# CONFIG_MTD_PMC551_DEBUG is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+CONFIG_MTD_MTDRAM=m
+CONFIG_MTDRAM_TOTAL_SIZE=4096
+CONFIG_MTDRAM_ERASE_SIZE=128
+CONFIG_MTD_BLOCK2MTD=m
+
+#
+# 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=m
+# CONFIG_MTD_NAND_VERIFY_WRITE is not set
+CONFIG_MTD_NAND_ECC_SMC=y
+CONFIG_MTD_NAND_IDS=m
+CONFIG_MTD_NAND_DISKONCHIP=m
+# CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADVANCED is not set
+CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADDRESS=0
+# CONFIG_MTD_NAND_DISKONCHIP_BBTWRITE is not set
+CONFIG_MTD_NAND_NANDSIM=m
+
+#
+# OneNAND Flash Device Drivers
+#
+# CONFIG_MTD_ONENAND is not set
+
+#
+# Parallel port support
+#
+CONFIG_PARPORT=m
+CONFIG_PARPORT_PC=m
+CONFIG_PARPORT_SERIAL=m
+# CONFIG_PARPORT_PC_FIFO is not set
+# CONFIG_PARPORT_PC_SUPERIO is not set
+CONFIG_PARPORT_PC_PCMCIA=m
+CONFIG_PARPORT_NOT_PC=y
+# CONFIG_PARPORT_GSC is not set
+# CONFIG_PARPORT_AX88796 is not set
+CONFIG_PARPORT_1284=y
+
+#
+# Plug and Play support
+#
+CONFIG_PNP=y
+# CONFIG_PNP_DEBUG is not set
+
+#
+# Protocols
+#
+CONFIG_PNPACPI=y
+
+#
+# Block devices
+#
+CONFIG_BLK_DEV_FD=m
+CONFIG_PARIDE=m
+CONFIG_PARIDE_PARPORT=m
+
+#
+# Parallel IDE high-level drivers
+#
+CONFIG_PARIDE_PD=m
+CONFIG_PARIDE_PCD=m
+CONFIG_PARIDE_PF=m
+CONFIG_PARIDE_PT=m
+CONFIG_PARIDE_PG=m
+
+#
+# Parallel IDE protocol modules
+#
+CONFIG_PARIDE_ATEN=m
+CONFIG_PARIDE_BPCK=m
+CONFIG_PARIDE_COMM=m
+CONFIG_PARIDE_DSTR=m
+CONFIG_PARIDE_FIT2=m
+CONFIG_PARIDE_FIT3=m
+CONFIG_PARIDE_EPAT=m
+CONFIG_PARIDE_EPATC8=y
+CONFIG_PARIDE_EPIA=m
+CONFIG_PARIDE_FRIQ=m
+CONFIG_PARIDE_FRPW=m
+CONFIG_PARIDE_KBIC=m
+CONFIG_PARIDE_KTTI=m
+CONFIG_PARIDE_ON20=m
+CONFIG_PARIDE_ON26=m
+CONFIG_BLK_CPQ_DA=m
+CONFIG_BLK_CPQ_CISS_DA=m
+CONFIG_CISS_SCSI_TAPE=y
+CONFIG_BLK_DEV_DAC960=m
+CONFIG_BLK_DEV_UMEM=m
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=m
+CONFIG_BLK_DEV_CRYPTOLOOP=m
+CONFIG_BLK_DEV_NBD=m
+CONFIG_BLK_DEV_SX8=m
+CONFIG_BLK_DEV_UB=m
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=16384
+CONFIG_BLK_DEV_RAM_BLOCKSIZE=4096
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_CDROM_PKTCDVD=m
+CONFIG_CDROM_PKTCDVD_BUFFERS=8
+# CONFIG_CDROM_PKTCDVD_WCACHE is not set
+CONFIG_ATA_OVER_ETH=m
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+CONFIG_IDE=y
+CONFIG_BLK_DEV_IDE=y
+
+#
+# Please see Documentation/ide.txt for help/info on IDE drives
+#
+# CONFIG_BLK_DEV_IDE_SATA is not set
+# CONFIG_BLK_DEV_HD_IDE is not set
+CONFIG_BLK_DEV_IDEDISK=y
+CONFIG_IDEDISK_MULTI_MODE=y
+CONFIG_BLK_DEV_IDECS=m
+CONFIG_BLK_DEV_IDECD=m
+# CONFIG_BLK_DEV_IDETAPE is not set
+CONFIG_BLK_DEV_IDEFLOPPY=y
+CONFIG_BLK_DEV_IDESCSI=m
+CONFIG_IDE_TASK_IOCTL=y
+
+#
+# IDE chipset support/bugfixes
+#
+CONFIG_IDE_GENERIC=y
+# CONFIG_BLK_DEV_CMD640 is not set
+CONFIG_BLK_DEV_IDEPNP=y
+CONFIG_BLK_DEV_IDEPCI=y
+CONFIG_IDEPCI_SHARE_IRQ=y
+# CONFIG_BLK_DEV_OFFBOARD is not set
+CONFIG_BLK_DEV_GENERIC=y
+# CONFIG_BLK_DEV_OPTI621 is not set
+# CONFIG_BLK_DEV_RZ1000 is not set
+CONFIG_BLK_DEV_IDEDMA_PCI=y
+# CONFIG_BLK_DEV_IDEDMA_FORCED is not set
+CONFIG_IDEDMA_PCI_AUTO=y
+# CONFIG_IDEDMA_ONLYDISK is not set
+CONFIG_BLK_DEV_AEC62XX=y
+CONFIG_BLK_DEV_ALI15X3=y
+# CONFIG_WDC_ALI15X3 is not set
+CONFIG_BLK_DEV_AMD74XX=y
+CONFIG_BLK_DEV_ATIIXP=y
+CONFIG_BLK_DEV_CMD64X=y
+# CONFIG_BLK_DEV_TRIFLEX is not set
+# CONFIG_BLK_DEV_CY82C693 is not set
+# CONFIG_BLK_DEV_CS5520 is not set
+# CONFIG_BLK_DEV_CS5530 is not set
+CONFIG_BLK_DEV_HPT34X=y
+# CONFIG_HPT34X_AUTODMA is not set
+CONFIG_BLK_DEV_HPT366=y
+# CONFIG_BLK_DEV_SC1200 is not set
+CONFIG_BLK_DEV_PIIX=y
+CONFIG_BLK_DEV_IT821X=y
+# CONFIG_BLK_DEV_NS87415 is not set
+CONFIG_BLK_DEV_PDC202XX_OLD=y
+# CONFIG_PDC202XX_BURST is not set
+CONFIG_BLK_DEV_PDC202XX_NEW=y
+CONFIG_BLK_DEV_SVWKS=y
+CONFIG_BLK_DEV_SIIMAGE=y
+CONFIG_BLK_DEV_SIS5513=y
+# CONFIG_BLK_DEV_SLC90E66 is not set
+# CONFIG_BLK_DEV_TRM290 is not set
+CONFIG_BLK_DEV_VIA82CXXX=y
+# CONFIG_IDE_ARM is not set
+CONFIG_BLK_DEV_IDEDMA=y
+# CONFIG_IDEDMA_IVB is not set
+CONFIG_IDEDMA_AUTO=y
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# SCSI device support
+#
+CONFIG_RAID_ATTRS=m
+CONFIG_SCSI=m
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=m
+CONFIG_CHR_DEV_ST=m
+CONFIG_CHR_DEV_OSST=m
+CONFIG_BLK_DEV_SR=m
+CONFIG_BLK_DEV_SR_VENDOR=y
+CONFIG_CHR_DEV_SG=m
+CONFIG_CHR_DEV_SCH=m
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+CONFIG_SCSI_MULTI_LUN=y
+CONFIG_SCSI_CONSTANTS=y
+CONFIG_SCSI_LOGGING=y
+
+#
+# SCSI Transport Attributes
+#
+CONFIG_SCSI_SPI_ATTRS=m
+CONFIG_SCSI_FC_ATTRS=m
+CONFIG_SCSI_ISCSI_ATTRS=m
+CONFIG_SCSI_SAS_ATTRS=m
+
+#
+# SCSI low-level drivers
+#
+CONFIG_ISCSI_TCP=m
+CONFIG_BLK_DEV_3W_XXXX_RAID=m
+CONFIG_SCSI_3W_9XXX=m
+CONFIG_SCSI_ACARD=m
+CONFIG_SCSI_AACRAID=m
+CONFIG_SCSI_AIC7XXX=m
+CONFIG_AIC7XXX_CMDS_PER_DEVICE=4
+CONFIG_AIC7XXX_RESET_DELAY_MS=15000
+# CONFIG_AIC7XXX_DEBUG_ENABLE is not set
+CONFIG_AIC7XXX_DEBUG_MASK=0
+# CONFIG_AIC7XXX_REG_PRETTY_PRINT is not set
+CONFIG_SCSI_AIC7XXX_OLD=m
+CONFIG_SCSI_AIC79XX=m
+CONFIG_AIC79XX_CMDS_PER_DEVICE=4
+CONFIG_AIC79XX_RESET_DELAY_MS=15000
+# CONFIG_AIC79XX_ENABLE_RD_STRM is not set
+# CONFIG_AIC79XX_DEBUG_ENABLE is not set
+CONFIG_AIC79XX_DEBUG_MASK=0
+# CONFIG_AIC79XX_REG_PRETTY_PRINT is not set
+CONFIG_MEGARAID_NEWGEN=y
+CONFIG_MEGARAID_MM=m
+CONFIG_MEGARAID_MAILBOX=m
+CONFIG_MEGARAID_LEGACY=m
+CONFIG_MEGARAID_SAS=m
+CONFIG_SCSI_SATA=m
+CONFIG_SCSI_SATA_AHCI=m
+CONFIG_SCSI_SATA_SVW=m
+CONFIG_SCSI_ATA_PIIX=m
+CONFIG_SCSI_SATA_MV=m
+CONFIG_SCSI_SATA_NV=m
+CONFIG_SCSI_PDC_ADMA=m
+CONFIG_SCSI_HPTIOP=m
+CONFIG_SCSI_SATA_QSTOR=m
+CONFIG_SCSI_SATA_PROMISE=m
+CONFIG_SCSI_SATA_SX4=m
+CONFIG_SCSI_SATA_SIL=m
+CONFIG_SCSI_SATA_SIL24=m
+CONFIG_SCSI_SATA_SIS=m
+CONFIG_SCSI_SATA_ULI=m
+CONFIG_SCSI_SATA_VIA=m
+CONFIG_SCSI_SATA_VITESSE=m
+CONFIG_SCSI_SATA_INTEL_COMBINED=y
+CONFIG_SCSI_BUSLOGIC=m
+# CONFIG_SCSI_OMIT_FLASHPOINT is not set
+# CONFIG_SCSI_DMX3191D is not set
+# CONFIG_SCSI_EATA is not set
+# CONFIG_SCSI_FUTURE_DOMAIN is not set
+CONFIG_SCSI_GDTH=m
+CONFIG_SCSI_IPS=m
+CONFIG_SCSI_INITIO=m
+CONFIG_SCSI_INIA100=m
+CONFIG_SCSI_PPA=m
+CONFIG_SCSI_IMM=m
+# CONFIG_SCSI_IZIP_EPP16 is not set
+# CONFIG_SCSI_IZIP_SLOW_CTR is not set
+CONFIG_SCSI_SYM53C8XX_2=m
+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_QLOGIC_1280=m
+CONFIG_SCSI_QLA_FC=m
+CONFIG_SCSI_LPFC=m
+CONFIG_SCSI_DC395x=m
+CONFIG_SCSI_DC390T=m
+# CONFIG_SCSI_DEBUG is not set
+
+#
+# PCMCIA SCSI adapter support
+#
+# CONFIG_PCMCIA_FDOMAIN is not set
+CONFIG_PCMCIA_QLOGIC=m
+CONFIG_PCMCIA_SYM53C500=m
+
+#
+# Multi-device support (RAID and LVM)
+#
+CONFIG_MD=y
+CONFIG_BLK_DEV_MD=y
+CONFIG_MD_LINEAR=m
+CONFIG_MD_RAID0=m
+CONFIG_MD_RAID1=m
+CONFIG_MD_RAID10=m
+CONFIG_MD_RAID456=m
+CONFIG_MD_RAID5_RESHAPE=y
+CONFIG_MD_MULTIPATH=m
+CONFIG_MD_FAULTY=m
+CONFIG_BLK_DEV_DM=m
+CONFIG_DM_CRYPT=m
+CONFIG_DM_SNAPSHOT=m
+CONFIG_DM_MIRROR=m
+CONFIG_DM_ZERO=m
+CONFIG_DM_MULTIPATH=m
+CONFIG_DM_MULTIPATH_EMC=m
+
+#
+# Fusion MPT device support
+#
+CONFIG_FUSION=y
+CONFIG_FUSION_SPI=m
+CONFIG_FUSION_FC=m
+CONFIG_FUSION_SAS=m
+CONFIG_FUSION_MAX_SGE=40
+CONFIG_FUSION_CTL=m
+CONFIG_FUSION_LAN=m
+
+#
+# IEEE 1394 (FireWire) support
+#
+CONFIG_IEEE1394=m
+
+#
+# Subsystem Options
+#
+# CONFIG_IEEE1394_VERBOSEDEBUG is not set
+CONFIG_IEEE1394_OUI_DB=y
+CONFIG_IEEE1394_EXTRA_CONFIG_ROMS=y
+CONFIG_IEEE1394_CONFIG_ROM_IP1394=y
+# CONFIG_IEEE1394_EXPORT_FULL_API is not set
+
+#
+# Device Drivers
+#
+CONFIG_IEEE1394_PCILYNX=m
+CONFIG_IEEE1394_OHCI1394=m
+
+#
+# Protocol Drivers
+#
+CONFIG_IEEE1394_VIDEO1394=m
+CONFIG_IEEE1394_SBP2=m
+CONFIG_IEEE1394_ETH1394=m
+CONFIG_IEEE1394_DV1394=m
+CONFIG_IEEE1394_RAWIO=m
+
+#
+# I2O device support
+#
+CONFIG_I2O=m
+# CONFIG_I2O_LCT_NOTIFY_ON_CHANGES is not set
+CONFIG_I2O_EXT_ADAPTEC=y
+CONFIG_I2O_EXT_ADAPTEC_DMA64=y
+CONFIG_I2O_CONFIG=m
+CONFIG_I2O_CONFIG_OLD_IOCTL=y
+CONFIG_I2O_BUS=m
+CONFIG_I2O_BLOCK=m
+CONFIG_I2O_SCSI=m
+CONFIG_I2O_PROC=m
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+CONFIG_IFB=m
+CONFIG_DUMMY=m
+CONFIG_BONDING=m
+CONFIG_EQUALIZER=m
+CONFIG_TUN=m
+CONFIG_NET_SB1000=m
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+
+#
+# PHY device support
+#
+CONFIG_PHYLIB=m
+
+#
+# MII PHY device drivers
+#
+CONFIG_MARVELL_PHY=m
+CONFIG_DAVICOM_PHY=m
+CONFIG_QSEMI_PHY=m
+CONFIG_LXT_PHY=m
+CONFIG_CICADA_PHY=m
+CONFIG_VITESSE_PHY=m
+CONFIG_SMSC_PHY=m
+CONFIG_FIXED_PHY=m
+CONFIG_FIXED_MII_10_FDX=y
+CONFIG_FIXED_MII_100_FDX=y
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=m
+CONFIG_HAPPYMEAL=m
+CONFIG_SUNGEM=m
+CONFIG_CASSINI=m
+CONFIG_NET_VENDOR_3COM=y
+CONFIG_VORTEX=m
+CONFIG_TYPHOON=m
+
+#
+# Tulip family network device support
+#
+CONFIG_NET_TULIP=y
+CONFIG_DE2104X=m
+CONFIG_TULIP=m
+# CONFIG_TULIP_MWI is not set
+CONFIG_TULIP_MMIO=y
+# CONFIG_TULIP_NAPI is not set
+CONFIG_DE4X5=m
+CONFIG_WINBOND_840=m
+CONFIG_DM9102=m
+CONFIG_ULI526X=m
+CONFIG_PCMCIA_XIRCOM=m
+# CONFIG_HP100 is not set
+CONFIG_NET_PCI=y
+CONFIG_PCNET32=m
+CONFIG_AMD8111_ETH=m
+CONFIG_AMD8111E_NAPI=y
+CONFIG_ADAPTEC_STARFIRE=m
+CONFIG_ADAPTEC_STARFIRE_NAPI=y
+CONFIG_B44=m
+CONFIG_FORCEDETH=m
+# CONFIG_DGRS is not set
+# CONFIG_EEPRO100 is not set
+CONFIG_E100=m
+CONFIG_FEALNX=m
+CONFIG_NATSEMI=m
+CONFIG_NE2K_PCI=m
+CONFIG_8139CP=m
+CONFIG_8139TOO=m
+# CONFIG_8139TOO_PIO is not set
+# CONFIG_8139TOO_TUNE_TWISTER is not set
+CONFIG_8139TOO_8129=y
+# CONFIG_8139_OLD_RX_RESET is not set
+CONFIG_SIS900=m
+CONFIG_EPIC100=m
+CONFIG_SUNDANCE=m
+# CONFIG_SUNDANCE_MMIO is not set
+CONFIG_VIA_RHINE=m
+CONFIG_VIA_RHINE_MMIO=y
+CONFIG_VIA_RHINE_NAPI=y
+CONFIG_NET_POCKET=y
+CONFIG_ATP=m
+CONFIG_DE600=m
+CONFIG_DE620=m
+
+#
+# Ethernet (1000 Mbit)
+#
+CONFIG_ACENIC=m
+# CONFIG_ACENIC_OMIT_TIGON_I is not set
+CONFIG_DL2K=m
+CONFIG_E1000=m
+CONFIG_E1000_NAPI=y
+# CONFIG_E1000_DISABLE_PACKET_SPLIT is not set
+CONFIG_NS83820=m
+CONFIG_HAMACHI=m
+CONFIG_YELLOWFIN=m
+CONFIG_R8169=m
+CONFIG_R8169_NAPI=y
+CONFIG_R8169_VLAN=y
+CONFIG_SIS190=m
+CONFIG_SKGE=m
+CONFIG_SKY2=m
+# CONFIG_SK98LIN is not set
+CONFIG_VIA_VELOCITY=m
+CONFIG_TIGON3=m
+CONFIG_BNX2=m
+
+#
+# Ethernet (10000 Mbit)
+#
+CONFIG_CHELSIO_T1=m
+CONFIG_IXGB=m
+CONFIG_IXGB_NAPI=y
+CONFIG_S2IO=m
+CONFIG_S2IO_NAPI=y
+CONFIG_MYRI10GE=m
+
+#
+# Token Ring devices
+#
+CONFIG_TR=y
+CONFIG_IBMOL=m
+CONFIG_3C359=m
+# CONFIG_TMS380TR is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+CONFIG_NET_RADIO=y
+CONFIG_NET_WIRELESS_RTNETLINK=y
+
+#
+# Obsolete Wireless cards support (pre-802.11)
+#
+# CONFIG_STRIP is not set
+CONFIG_PCMCIA_WAVELAN=m
+CONFIG_PCMCIA_NETWAVE=m
+
+#
+# Wireless 802.11 Frequency Hopping cards support
+#
+# CONFIG_PCMCIA_RAYCS is not set
+
+#
+# Wireless 802.11b ISA/PCI cards support
+#
+CONFIG_IPW2100=m
+CONFIG_IPW2100_MONITOR=y
+# CONFIG_IPW2100_DEBUG is not set
+CONFIG_IPW2200=m
+CONFIG_IPW2200_MONITOR=y
+CONFIG_IPW2200_RADIOTAP=y
+CONFIG_IPW2200_PROMISCUOUS=y
+CONFIG_IPW2200_QOS=y
+# CONFIG_IPW2200_DEBUG is not set
+CONFIG_AIRO=m
+CONFIG_HERMES=m
+CONFIG_PLX_HERMES=m
+CONFIG_TMD_HERMES=m
+CONFIG_NORTEL_HERMES=m
+CONFIG_PCI_HERMES=m
+CONFIG_ATMEL=m
+CONFIG_PCI_ATMEL=m
+
+#
+# Wireless 802.11b Pcmcia/Cardbus cards support
+#
+CONFIG_PCMCIA_HERMES=m
+CONFIG_PCMCIA_SPECTRUM=m
+CONFIG_AIRO_CS=m
+CONFIG_PCMCIA_ATMEL=m
+CONFIG_PCMCIA_WL3501=m
+
+#
+# Prism GT/Duette 802.11(a/b/g) PCI/Cardbus support
+#
+CONFIG_PRISM54=m
+CONFIG_USB_ZD1201=m
+CONFIG_HOSTAP=m
+CONFIG_HOSTAP_FIRMWARE=y
+CONFIG_HOSTAP_FIRMWARE_NVRAM=y
+CONFIG_HOSTAP_PLX=m
+CONFIG_HOSTAP_PCI=m
+CONFIG_HOSTAP_CS=m
+CONFIG_BCM43XX=m
+CONFIG_BCM43XX_DEBUG=y
+CONFIG_BCM43XX_DMA=y
+CONFIG_BCM43XX_PIO=y
+CONFIG_BCM43XX_DMA_AND_PIO_MODE=y
+# CONFIG_BCM43XX_DMA_MODE is not set
+# CONFIG_BCM43XX_PIO_MODE is not set
+CONFIG_ZD1211RW=m
+# CONFIG_ZD1211RW_DEBUG is not set
+CONFIG_NET_WIRELESS=y
+
+#
+# PCMCIA network device support
+#
+CONFIG_NET_PCMCIA=y
+CONFIG_PCMCIA_3C589=m
+CONFIG_PCMCIA_3C574=m
+CONFIG_PCMCIA_FMVJ18X=m
+CONFIG_PCMCIA_PCNET=m
+CONFIG_PCMCIA_NMCLAN=m
+CONFIG_PCMCIA_SMC91C92=m
+CONFIG_PCMCIA_XIRC2PS=m
+CONFIG_PCMCIA_AXNET=m
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+
+#
+# ATM drivers
+#
+# CONFIG_ATM_DUMMY is not set
+CONFIG_ATM_TCP=m
+CONFIG_ATM_LANAI=m
+CONFIG_ATM_ENI=m
+# CONFIG_ATM_ENI_DEBUG is not set
+# CONFIG_ATM_ENI_TUNE_BURST is not set
+CONFIG_ATM_FIRESTREAM=m
+# CONFIG_ATM_ZATM is not set
+CONFIG_ATM_IDT77252=m
+# CONFIG_ATM_IDT77252_DEBUG is not set
+# CONFIG_ATM_IDT77252_RCV_ALL is not set
+CONFIG_ATM_IDT77252_USE_SUNI=y
+CONFIG_ATM_AMBASSADOR=m
+# CONFIG_ATM_AMBASSADOR_DEBUG is not set
+CONFIG_ATM_HORIZON=m
+# CONFIG_ATM_HORIZON_DEBUG is not set
+CONFIG_ATM_FORE200E_MAYBE=m
+# CONFIG_ATM_FORE200E_PCA is not set
+CONFIG_ATM_HE=m
+# CONFIG_ATM_HE_USE_SUNI is not set
+CONFIG_FDDI=y
+# CONFIG_DEFXX is not set
+CONFIG_SKFP=m
+# CONFIG_HIPPI is not set
+CONFIG_PLIP=m
+CONFIG_PPP=m
+CONFIG_PPP_MULTILINK=y
+CONFIG_PPP_FILTER=y
+CONFIG_PPP_ASYNC=m
+CONFIG_PPP_SYNC_TTY=m
+CONFIG_PPP_DEFLATE=m
+# CONFIG_PPP_BSDCOMP is not set
+CONFIG_PPP_MPPE=m
+CONFIG_PPPOE=m
+CONFIG_PPPOATM=m
+CONFIG_SLIP=m
+CONFIG_SLIP_COMPRESSED=y
+CONFIG_SLIP_SMART=y
+# CONFIG_SLIP_MODE_SLIP6 is not set
+CONFIG_NET_FC=y
+# CONFIG_SHAPER is not set
+CONFIG_NETCONSOLE=m
+CONFIG_NETPOLL=y
+# CONFIG_NETPOLL_RX is not set
+CONFIG_NETPOLL_TRAP=y
+CONFIG_NET_POLL_CONTROLLER=y
+
+#
+# ISDN subsystem
+#
+CONFIG_ISDN=m
+
+#
+# Old ISDN4Linux
+#
+CONFIG_ISDN_I4L=m
+CONFIG_ISDN_PPP=y
+CONFIG_ISDN_PPP_VJ=y
+CONFIG_ISDN_MPP=y
+CONFIG_IPPP_FILTER=y
+# CONFIG_ISDN_PPP_BSDCOMP is not set
+CONFIG_ISDN_AUDIO=y
+CONFIG_ISDN_TTY_FAX=y
+
+#
+# ISDN feature submodules
+#
+CONFIG_ISDN_DIVERSION=m
+
+#
+# ISDN4Linux hardware drivers
+#
+
+#
+# Passive cards
+#
+CONFIG_ISDN_DRV_HISAX=m
+
+#
+# D-channel protocol features
+#
+CONFIG_HISAX_EURO=y
+CONFIG_DE_AOC=y
+CONFIG_HISAX_NO_SENDCOMPLETE=y
+CONFIG_HISAX_NO_LLC=y
+CONFIG_HISAX_NO_KEYPAD=y
+CONFIG_HISAX_1TR6=y
+CONFIG_HISAX_NI1=y
+CONFIG_HISAX_MAX_CARDS=8
+
+#
+# HiSax supported cards
+#
+CONFIG_HISAX_16_3=y
+CONFIG_HISAX_TELESPCI=y
+CONFIG_HISAX_S0BOX=y
+CONFIG_HISAX_FRITZPCI=y
+CONFIG_HISAX_AVM_A1_PCMCIA=y
+CONFIG_HISAX_ELSA=y
+CONFIG_HISAX_DIEHLDIVA=y
+CONFIG_HISAX_SEDLBAUER=y
+CONFIG_HISAX_NETJET=y
+CONFIG_HISAX_NETJET_U=y
+CONFIG_HISAX_NICCY=y
+CONFIG_HISAX_BKM_A4T=y
+CONFIG_HISAX_SCT_QUADRO=y
+CONFIG_HISAX_GAZEL=y
+CONFIG_HISAX_HFC_PCI=y
+CONFIG_HISAX_W6692=y
+CONFIG_HISAX_HFC_SX=y
+CONFIG_HISAX_ENTERNOW_PCI=y
+# CONFIG_HISAX_DEBUG is not set
+
+#
+# HiSax PCMCIA card service modules
+#
+CONFIG_HISAX_SEDLBAUER_CS=m
+CONFIG_HISAX_ELSA_CS=m
+CONFIG_HISAX_AVM_A1_CS=m
+CONFIG_HISAX_TELES_CS=m
+
+#
+# HiSax sub driver modules
+#
+CONFIG_HISAX_ST5481=m
+# CONFIG_HISAX_HFCUSB is not set
+CONFIG_HISAX_HFC4S8S=m
+CONFIG_HISAX_FRITZ_PCIPNP=m
+CONFIG_HISAX_HDLC=y
+
+#
+# Active cards
+#
+
+#
+# Siemens Gigaset
+#
+CONFIG_ISDN_DRV_GIGASET=m
+CONFIG_GIGASET_BASE=m
+CONFIG_GIGASET_M105=m
+# CONFIG_GIGASET_DEBUG is not set
+# CONFIG_GIGASET_UNDOCREQ is not set
+
+#
+# CAPI subsystem
+#
+CONFIG_ISDN_CAPI=m
+CONFIG_ISDN_DRV_AVMB1_VERBOSE_REASON=y
+CONFIG_ISDN_CAPI_MIDDLEWARE=y
+CONFIG_ISDN_CAPI_CAPI20=m
+CONFIG_ISDN_CAPI_CAPIFS_BOOL=y
+CONFIG_ISDN_CAPI_CAPIFS=m
+CONFIG_ISDN_CAPI_CAPIDRV=m
+
+#
+# CAPI hardware drivers
+#
+
+#
+# Active AVM cards
+#
+CONFIG_CAPI_AVM=y
+CONFIG_ISDN_DRV_AVMB1_B1PCI=m
+CONFIG_ISDN_DRV_AVMB1_B1PCIV4=y
+CONFIG_ISDN_DRV_AVMB1_B1PCMCIA=m
+CONFIG_ISDN_DRV_AVMB1_AVM_CS=m
+CONFIG_ISDN_DRV_AVMB1_T1PCI=m
+CONFIG_ISDN_DRV_AVMB1_C4=m
+
+#
+# Active Eicon DIVA Server cards
+#
+# CONFIG_CAPI_EICON is not set
+
+#
+# Telephony Support
+#
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+
+#
+# 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=m
+# CONFIG_INPUT_TSDEV is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+CONFIG_KEYBOARD_ATKBD=y
+# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_KEYBOARD_LKKBD is not set
+# CONFIG_KEYBOARD_XTKBD is not set
+# CONFIG_KEYBOARD_NEWTON is not set
+CONFIG_INPUT_MOUSE=y
+CONFIG_MOUSE_PS2=y
+CONFIG_MOUSE_SERIAL=m
+CONFIG_MOUSE_VSXXXAA=m
+CONFIG_INPUT_JOYSTICK=y
+CONFIG_JOYSTICK_ANALOG=m
+CONFIG_JOYSTICK_A3D=m
+CONFIG_JOYSTICK_ADI=m
+CONFIG_JOYSTICK_COBRA=m
+CONFIG_JOYSTICK_GF2K=m
+CONFIG_JOYSTICK_GRIP=m
+CONFIG_JOYSTICK_GRIP_MP=m
+CONFIG_JOYSTICK_GUILLEMOT=m
+CONFIG_JOYSTICK_INTERACT=m
+CONFIG_JOYSTICK_SIDEWINDER=m
+CONFIG_JOYSTICK_TMDC=m
+CONFIG_JOYSTICK_IFORCE=m
+CONFIG_JOYSTICK_IFORCE_USB=y
+CONFIG_JOYSTICK_IFORCE_232=y
+CONFIG_JOYSTICK_WARRIOR=m
+CONFIG_JOYSTICK_MAGELLAN=m
+CONFIG_JOYSTICK_SPACEORB=m
+CONFIG_JOYSTICK_SPACEBALL=m
+CONFIG_JOYSTICK_STINGER=m
+CONFIG_JOYSTICK_TWIDJOY=m
+CONFIG_JOYSTICK_DB9=m
+CONFIG_JOYSTICK_GAMECON=m
+CONFIG_JOYSTICK_TURBOGRAFX=m
+CONFIG_JOYSTICK_JOYDUMP=m
+CONFIG_INPUT_TOUCHSCREEN=y
+CONFIG_TOUCHSCREEN_GUNZE=m
+CONFIG_TOUCHSCREEN_ELO=m
+CONFIG_TOUCHSCREEN_MTOUCH=m
+CONFIG_TOUCHSCREEN_MK712=m
+CONFIG_INPUT_MISC=y
+CONFIG_INPUT_PCSPKR=m
+CONFIG_INPUT_UINPUT=m
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+CONFIG_SERIO_I8042=y
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_CT82C710 is not set
+# CONFIG_SERIO_PARKBD is not set
+# CONFIG_SERIO_PCIPS2 is not set
+CONFIG_SERIO_LIBPS2=y
+CONFIG_SERIO_RAW=m
+CONFIG_GAMEPORT=m
+CONFIG_GAMEPORT_NS558=m
+CONFIG_GAMEPORT_L4=m
+CONFIG_GAMEPORT_EMU10K1=m
+CONFIG_GAMEPORT_FM801=m
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+CONFIG_VT_HW_CONSOLE_BINDING=y
+CONFIG_SERIAL_NONSTANDARD=y
+# CONFIG_COMPUTONE is not set
+# CONFIG_ROCKETPORT is not set
+CONFIG_CYCLADES=m
+# CONFIG_CYZ_INTR is not set
+# CONFIG_DIGIEPCA is not set
+# CONFIG_MOXA_INTELLIO is not set
+# CONFIG_MOXA_SMARTIO is not set
+# CONFIG_ISI is not set
+CONFIG_SYNCLINK=m
+CONFIG_SYNCLINKMP=m
+CONFIG_SYNCLINK_GT=m
+CONFIG_N_HDLC=m
+# CONFIG_SPECIALIX is not set
+# CONFIG_SX is not set
+# CONFIG_RIO is not set
+# CONFIG_STALDRV is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_PCI=y
+CONFIG_SERIAL_8250_PNP=y
+CONFIG_SERIAL_8250_CS=m
+CONFIG_SERIAL_8250_NR_UARTS=32
+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=y
+CONFIG_SERIAL_8250_RSA=y
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_SERIAL_JSM=m
+CONFIG_UNIX98_PTYS=y
+# CONFIG_LEGACY_PTYS is not set
+CONFIG_CRASH=m
+CONFIG_PRINTER=m
+CONFIG_LP_CONSOLE=y
+CONFIG_PPDEV=m
+CONFIG_TIPAR=m
+
+#
+# IPMI
+#
+CONFIG_IPMI_HANDLER=m
+# CONFIG_IPMI_PANIC_EVENT is not set
+CONFIG_IPMI_DEVICE_INTERFACE=m
+CONFIG_IPMI_SI=m
+CONFIG_IPMI_WATCHDOG=m
+CONFIG_IPMI_POWEROFF=m
+
+#
+# Watchdog Cards
+#
+CONFIG_WATCHDOG=y
+# CONFIG_WATCHDOG_NOWAYOUT is not set
+
+#
+# Watchdog Device Drivers
+#
+CONFIG_SOFT_WATCHDOG=m
+# CONFIG_ACQUIRE_WDT is not set
+# CONFIG_ADVANTECH_WDT is not set
+CONFIG_ALIM1535_WDT=m
+CONFIG_ALIM7101_WDT=m
+# CONFIG_SC520_WDT is not set
+# CONFIG_EUROTECH_WDT is not set
+# CONFIG_IB700_WDT is not set
+CONFIG_IBMASR=m
+# CONFIG_WAFER_WDT is not set
+CONFIG_I6300ESB_WDT=m
+CONFIG_I8XX_TCO=m
+# CONFIG_SC1200_WDT is not set
+# CONFIG_60XX_WDT is not set
+# CONFIG_SBC8360_WDT is not set
+# CONFIG_CPU5_WDT is not set
+CONFIG_W83627HF_WDT=m
+CONFIG_W83877F_WDT=m
+CONFIG_W83977F_WDT=m
+CONFIG_MACHZ_WDT=m
+# CONFIG_SBC_EPX_C3_WATCHDOG is not set
+
+#
+# PCI-based Watchdog Cards
+#
+CONFIG_PCIPCWATCHDOG=m
+CONFIG_WDTPCI=m
+CONFIG_WDT_501_PCI=y
+
+#
+# USB-based Watchdog Cards
+#
+CONFIG_USBPCWATCHDOG=m
+CONFIG_HW_RANDOM=y
+CONFIG_HW_RANDOM_INTEL=m
+CONFIG_HW_RANDOM_AMD=m
+# CONFIG_HW_RANDOM_GEODE is not set
+CONFIG_NVRAM=y
+CONFIG_RTC=y
+CONFIG_DTLK=m
+CONFIG_R3964=m
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+CONFIG_AGP=y
+CONFIG_AGP_AMD64=y
+CONFIG_AGP_INTEL=y
+CONFIG_AGP_SIS=y
+CONFIG_AGP_VIA=y
+CONFIG_DRM=m
+CONFIG_DRM_TDFX=m
+CONFIG_DRM_R128=m
+CONFIG_DRM_RADEON=m
+CONFIG_DRM_I810=m
+CONFIG_DRM_I830=m
+CONFIG_DRM_I915=m
+CONFIG_DRM_MGA=m
+CONFIG_DRM_SIS=m
+CONFIG_DRM_VIA=m
+CONFIG_DRM_SAVAGE=m
+
+#
+# PCMCIA character devices
+#
+# CONFIG_SYNCLINK_CS is not set
+CONFIG_CARDMAN_4000=m
+CONFIG_CARDMAN_4040=m
+CONFIG_MWAVE=m
+CONFIG_PC8736x_GPIO=m
+CONFIG_NSC_GPIO=m
+# CONFIG_RAW_DRIVER is not set
+CONFIG_HPET=y
+# CONFIG_HPET_RTC_IRQ is not set
+# CONFIG_HPET_MMAP is not set
+CONFIG_HANGCHECK_TIMER=m
+
+#
+# TPM devices
+#
+CONFIG_TCG_TPM=m
+CONFIG_TCG_TIS=m
+CONFIG_TCG_NSC=m
+CONFIG_TCG_ATMEL=m
+CONFIG_TCG_INFINEON=m
+# CONFIG_TELCLOCK is not set
+
+#
+# I2C support
+#
+CONFIG_I2C=m
+CONFIG_I2C_CHARDEV=m
+
+#
+# I2C Algorithms
+#
+CONFIG_I2C_ALGOBIT=m
+CONFIG_I2C_ALGOPCF=m
+CONFIG_I2C_ALGOPCA=m
+
+#
+# I2C Hardware Bus support
+#
+# CONFIG_I2C_ALI1535 is not set
+# CONFIG_I2C_ALI1563 is not set
+# CONFIG_I2C_ALI15X3 is not set
+CONFIG_I2C_AMD756=m
+CONFIG_I2C_AMD756_S4882=m
+CONFIG_I2C_AMD8111=m
+CONFIG_I2C_I801=m
+# CONFIG_I2C_I810 is not set
+# CONFIG_I2C_PIIX4 is not set
+CONFIG_I2C_ISA=m
+CONFIG_I2C_NFORCE2=m
+# CONFIG_I2C_OCORES is not set
+CONFIG_I2C_PARPORT=m
+CONFIG_I2C_PARPORT_LIGHT=m
+CONFIG_I2C_PROSAVAGE=m
+CONFIG_I2C_SAVAGE4=m
+# CONFIG_I2C_SIS5595 is not set
+# CONFIG_I2C_SIS630 is not set
+CONFIG_I2C_SIS96X=m
+CONFIG_I2C_STUB=m
+CONFIG_I2C_VIA=m
+CONFIG_I2C_VIAPRO=m
+CONFIG_I2C_VOODOO3=m
+CONFIG_I2C_PCA_ISA=m
+
+#
+# Miscellaneous I2C Chip support
+#
+CONFIG_SENSORS_DS1337=m
+CONFIG_SENSORS_DS1374=m
+CONFIG_SENSORS_EEPROM=m
+CONFIG_SENSORS_PCF8574=m
+CONFIG_SENSORS_PCA9539=m
+CONFIG_SENSORS_PCF8591=m
+CONFIG_SENSORS_MAX6875=m
+# 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 is not set
+# CONFIG_SPI_MASTER is not set
+
+#
+# Dallas's 1-wire bus
+#
+CONFIG_W1=m
+CONFIG_W1_CON=y
+
+#
+# 1-wire Bus Masters
+#
+CONFIG_W1_MASTER_MATROX=m
+CONFIG_W1_MASTER_DS2490=m
+CONFIG_W1_MASTER_DS2482=m
+
+#
+# 1-wire Slaves
+#
+CONFIG_W1_SLAVE_THERM=m
+CONFIG_W1_SLAVE_SMEM=m
+CONFIG_W1_SLAVE_DS2433=m
+CONFIG_W1_SLAVE_DS2433_CRC=y
+
+#
+# Hardware Monitoring support
+#
+CONFIG_HWMON=m
+CONFIG_HWMON_VID=m
+CONFIG_SENSORS_ABITUGURU=m
+CONFIG_SENSORS_ADM1021=m
+CONFIG_SENSORS_ADM1025=m
+CONFIG_SENSORS_ADM1026=m
+CONFIG_SENSORS_ADM1031=m
+CONFIG_SENSORS_ADM9240=m
+CONFIG_SENSORS_ASB100=m
+CONFIG_SENSORS_ATXP1=m
+CONFIG_SENSORS_DS1621=m
+CONFIG_SENSORS_F71805F=m
+CONFIG_SENSORS_FSCHER=m
+CONFIG_SENSORS_FSCPOS=m
+CONFIG_SENSORS_GL518SM=m
+CONFIG_SENSORS_GL520SM=m
+CONFIG_SENSORS_IT87=m
+CONFIG_SENSORS_LM63=m
+CONFIG_SENSORS_LM75=m
+CONFIG_SENSORS_LM77=m
+CONFIG_SENSORS_LM78=m
+CONFIG_SENSORS_LM80=m
+CONFIG_SENSORS_LM83=m
+CONFIG_SENSORS_LM85=m
+CONFIG_SENSORS_LM87=m
+CONFIG_SENSORS_LM90=m
+CONFIG_SENSORS_LM92=m
+CONFIG_SENSORS_MAX1619=m
+CONFIG_SENSORS_PC87360=m
+CONFIG_SENSORS_SIS5595=m
+CONFIG_SENSORS_SMSC47M1=m
+CONFIG_SENSORS_SMSC47M192=m
+CONFIG_SENSORS_SMSC47B397=m
+CONFIG_SENSORS_VIA686A=m
+CONFIG_SENSORS_VT8231=m
+CONFIG_SENSORS_W83781D=m
+CONFIG_SENSORS_W83791D=m
+CONFIG_SENSORS_W83792D=m
+CONFIG_SENSORS_W83L785TS=m
+CONFIG_SENSORS_W83627HF=m
+CONFIG_SENSORS_W83627EHF=m
+CONFIG_SENSORS_HDAPS=m
+# CONFIG_HWMON_DEBUG_CHIP is not set
+
+#
+# Misc devices
+#
+# CONFIG_IBM_ASM is not set
+
+#
+# Multimedia devices
+#
+CONFIG_VIDEO_DEV=m
+CONFIG_VIDEO_V4L1=y
+CONFIG_VIDEO_V4L1_COMPAT=y
+CONFIG_VIDEO_V4L2=y
+
+#
+# Video Capture Adapters
+#
+
+#
+# Video Capture Adapters
+#
+# CONFIG_VIDEO_ADV_DEBUG is not set
+# CONFIG_VIDEO_VIVI is not set
+CONFIG_VIDEO_BT848=m
+CONFIG_VIDEO_BT848_DVB=y
+CONFIG_VIDEO_SAA6588=m
+CONFIG_VIDEO_BWQCAM=m
+CONFIG_VIDEO_CQCAM=m
+CONFIG_VIDEO_W9966=m
+CONFIG_VIDEO_CPIA=m
+CONFIG_VIDEO_CPIA_PP=m
+CONFIG_VIDEO_CPIA_USB=m
+CONFIG_VIDEO_CPIA2=m
+CONFIG_VIDEO_SAA5246A=m
+CONFIG_VIDEO_SAA5249=m
+CONFIG_TUNER_3036=m
+CONFIG_VIDEO_STRADIS=m
+CONFIG_VIDEO_ZORAN=m
+CONFIG_VIDEO_ZORAN_BUZ=m
+CONFIG_VIDEO_ZORAN_DC10=m
+CONFIG_VIDEO_ZORAN_DC30=m
+CONFIG_VIDEO_ZORAN_LML33=m
+CONFIG_VIDEO_ZORAN_LML33R10=m
+CONFIG_VIDEO_ZORAN_AVS6EYES=m
+CONFIG_VIDEO_SAA7134=m
+CONFIG_VIDEO_SAA7134_ALSA=m
+CONFIG_VIDEO_SAA7134_DVB=m
+CONFIG_VIDEO_SAA7134_DVB_ALL_FRONTENDS=y
+CONFIG_VIDEO_MXB=m
+CONFIG_VIDEO_DPC=m
+CONFIG_VIDEO_HEXIUM_ORION=m
+CONFIG_VIDEO_HEXIUM_GEMINI=m
+CONFIG_VIDEO_CX88_VP3054=m
+CONFIG_VIDEO_CX88=m
+CONFIG_VIDEO_CX88_ALSA=m
+CONFIG_VIDEO_CX88_BLACKBIRD=m
+CONFIG_VIDEO_CX88_DVB=m
+CONFIG_VIDEO_CX88_DVB_ALL_FRONTENDS=y
+
+#
+# Encoders and Decoders
+#
+CONFIG_VIDEO_MSP3400=m
+CONFIG_VIDEO_CS53L32A=m
+CONFIG_VIDEO_TLV320AIC23B=m
+CONFIG_VIDEO_WM8775=m
+CONFIG_VIDEO_WM8739=m
+CONFIG_VIDEO_CX2341X=m
+CONFIG_VIDEO_CX25840=m
+CONFIG_VIDEO_SAA711X=m
+CONFIG_VIDEO_SAA7127=m
+CONFIG_VIDEO_UPD64031A=m
+CONFIG_VIDEO_UPD64083=m
+
+#
+# V4L USB devices
+#
+CONFIG_VIDEO_PVRUSB2=m
+CONFIG_VIDEO_PVRUSB2_24XXX=y
+CONFIG_VIDEO_PVRUSB2_SYSFS=y
+# CONFIG_VIDEO_PVRUSB2_DEBUGIFC is not set
+CONFIG_VIDEO_EM28XX=m
+CONFIG_VIDEO_USBVIDEO=m
+CONFIG_USB_VICAM=m
+CONFIG_USB_IBMCAM=m
+CONFIG_USB_KONICAWC=m
+CONFIG_USB_QUICKCAM_MESSENGER=m
+CONFIG_USB_ET61X251=m
+CONFIG_VIDEO_OVCAMCHIP=m
+CONFIG_USB_W9968CF=m
+CONFIG_USB_OV511=m
+CONFIG_USB_SE401=m
+CONFIG_USB_SN9C102=m
+CONFIG_USB_STV680=m
+CONFIG_USB_ZC0301=m
+CONFIG_USB_PWC=m
+# CONFIG_USB_PWC_DEBUG is not set
+
+#
+# Radio Adapters
+#
+CONFIG_RADIO_GEMTEK_PCI=m
+CONFIG_RADIO_MAXIRADIO=m
+CONFIG_RADIO_MAESTRO=m
+CONFIG_USB_DSBR=m
+
+#
+# Digital Video Broadcasting Devices
+#
+CONFIG_DVB=y
+CONFIG_DVB_CORE=m
+
+#
+# Supported SAA7146 based PCI Adapters
+#
+CONFIG_DVB_AV7110=m
+CONFIG_DVB_AV7110_OSD=y
+CONFIG_DVB_BUDGET=m
+CONFIG_DVB_BUDGET_CI=m
+CONFIG_DVB_BUDGET_AV=m
+CONFIG_DVB_BUDGET_PATCH=m
+
+#
+# Supported USB Adapters
+#
+CONFIG_DVB_USB=m
+# CONFIG_DVB_USB_DEBUG is not set
+CONFIG_DVB_USB_A800=m
+CONFIG_DVB_USB_DIBUSB_MB=m
+# CONFIG_DVB_USB_DIBUSB_MB_FAULTY is not set
+CONFIG_DVB_USB_DIBUSB_MC=m
+CONFIG_DVB_USB_UMT_010=m
+CONFIG_DVB_USB_CXUSB=m
+CONFIG_DVB_USB_DIGITV=m
+CONFIG_DVB_USB_VP7045=m
+CONFIG_DVB_USB_VP702X=m
+CONFIG_DVB_USB_GP8PSK=m
+CONFIG_DVB_USB_NOVA_T_USB2=m
+CONFIG_DVB_USB_DTT200U=m
+CONFIG_DVB_TTUSB_BUDGET=m
+CONFIG_DVB_TTUSB_DEC=m
+CONFIG_DVB_CINERGYT2=m
+CONFIG_DVB_CINERGYT2_TUNING=y
+CONFIG_DVB_CINERGYT2_STREAM_URB_COUNT=32
+CONFIG_DVB_CINERGYT2_STREAM_BUF_SIZE=512
+CONFIG_DVB_CINERGYT2_QUERY_INTERVAL=250
+CONFIG_DVB_CINERGYT2_ENABLE_RC_INPUT_DEVICE=y
+CONFIG_DVB_CINERGYT2_RC_QUERY_INTERVAL=100
+
+#
+# Supported FlexCopII (B2C2) Adapters
+#
+CONFIG_DVB_B2C2_FLEXCOP=m
+CONFIG_DVB_B2C2_FLEXCOP_PCI=m
+CONFIG_DVB_B2C2_FLEXCOP_USB=m
+# CONFIG_DVB_B2C2_FLEXCOP_DEBUG is not set
+
+#
+# Supported BT878 Adapters
+#
+CONFIG_DVB_BT8XX=m
+
+#
+# Supported Pluto2 Adapters
+#
+CONFIG_DVB_PLUTO2=m
+
+#
+# Supported DVB Frontends
+#
+
+#
+# Customise DVB Frontends
+#
+
+#
+# DVB-S (satellite) frontends
+#
+CONFIG_DVB_STV0299=m
+CONFIG_DVB_CX24110=m
+CONFIG_DVB_CX24123=m
+CONFIG_DVB_TDA8083=m
+CONFIG_DVB_MT312=m
+CONFIG_DVB_VES1X93=m
+CONFIG_DVB_S5H1420=m
+
+#
+# DVB-T (terrestrial) frontends
+#
+CONFIG_DVB_SP8870=m
+CONFIG_DVB_SP887X=m
+CONFIG_DVB_CX22700=m
+CONFIG_DVB_CX22702=m
+CONFIG_DVB_L64781=m
+CONFIG_DVB_TDA1004X=m
+CONFIG_DVB_NXT6000=m
+CONFIG_DVB_MT352=m
+CONFIG_DVB_ZL10353=m
+CONFIG_DVB_DIB3000MB=m
+CONFIG_DVB_DIB3000MC=m
+
+#
+# DVB-C (cable) frontends
+#
+CONFIG_DVB_VES1820=m
+CONFIG_DVB_TDA10021=m
+CONFIG_DVB_STV0297=m
+
+#
+# ATSC (North American/Korean Terrestrial/Cable DTV) frontends
+#
+CONFIG_DVB_NXT200X=m
+CONFIG_DVB_OR51211=m
+CONFIG_DVB_OR51132=m
+CONFIG_DVB_BCM3510=m
+CONFIG_DVB_LGDT330X=m
+
+#
+# Miscellaneous devices
+#
+CONFIG_DVB_PLL=m
+CONFIG_DVB_LNBP21=m
+CONFIG_DVB_ISL6421=m
+CONFIG_VIDEO_SAA7146=m
+CONFIG_VIDEO_SAA7146_VV=m
+CONFIG_VIDEO_VIDEOBUF=m
+CONFIG_VIDEO_TUNER=m
+CONFIG_VIDEO_BUF=m
+CONFIG_VIDEO_BUF_DVB=m
+CONFIG_VIDEO_BTCX=m
+CONFIG_VIDEO_IR=m
+CONFIG_VIDEO_TVEEPROM=m
+CONFIG_USB_DABUSB=m
+
+#
+# Graphics support
+#
+# CONFIG_FIRMWARE_EDID is not set
+CONFIG_FB=y
+CONFIG_FB_CFB_FILLRECT=y
+CONFIG_FB_CFB_COPYAREA=y
+CONFIG_FB_CFB_IMAGEBLIT=y
+# CONFIG_FB_MACMODES is not set
+# CONFIG_FB_BACKLIGHT is not set
+CONFIG_FB_MODE_HELPERS=y
+CONFIG_FB_TILEBLITTING=y
+CONFIG_FB_CIRRUS=m
+# CONFIG_FB_PM2 is not set
+# CONFIG_FB_CYBER2000 is not set
+# CONFIG_FB_ARC is not set
+# CONFIG_FB_ASILIANT is not set
+# CONFIG_FB_IMSTT is not set
+CONFIG_FB_VGA16=m
+CONFIG_FB_VESA=y
+# CONFIG_FB_HGA is not set
+# CONFIG_FB_S1D13XXX is not set
+CONFIG_FB_NVIDIA=m
+CONFIG_FB_NVIDIA_I2C=y
+CONFIG_FB_RIVA=m
+# CONFIG_FB_RIVA_I2C is not set
+# CONFIG_FB_RIVA_DEBUG is not set
+CONFIG_FB_INTEL=m
+# CONFIG_FB_INTEL_DEBUG is not set
+CONFIG_FB_MATROX=m
+CONFIG_FB_MATROX_MILLENIUM=y
+CONFIG_FB_MATROX_MYSTIQUE=y
+CONFIG_FB_MATROX_G=y
+CONFIG_FB_MATROX_I2C=m
+CONFIG_FB_MATROX_MAVEN=m
+CONFIG_FB_MATROX_MULTIHEAD=y
+CONFIG_FB_RADEON=m
+CONFIG_FB_RADEON_I2C=y
+# CONFIG_FB_RADEON_DEBUG is not set
+CONFIG_FB_ATY128=m
+CONFIG_FB_ATY=m
+CONFIG_FB_ATY_CT=y
+CONFIG_FB_ATY_GENERIC_LCD=y
+CONFIG_FB_ATY_GX=y
+CONFIG_FB_SAVAGE=m
+CONFIG_FB_SAVAGE_I2C=y
+CONFIG_FB_SAVAGE_ACCEL=y
+# CONFIG_FB_SIS is not set
+CONFIG_FB_NEOMAGIC=m
+CONFIG_FB_KYRO=m
+CONFIG_FB_3DFX=m
+CONFIG_FB_3DFX_ACCEL=y
+CONFIG_FB_VOODOO1=m
+CONFIG_FB_TRIDENT=m
+CONFIG_FB_TRIDENT_ACCEL=y
+# CONFIG_FB_GEODE is not set
+# CONFIG_FB_VIRTUAL is not set
+
+#
+# Console display driver support
+#
+CONFIG_VGA_CONSOLE=y
+CONFIG_VGACON_SOFT_SCROLLBACK=y
+CONFIG_VGACON_SOFT_SCROLLBACK_SIZE=64
+CONFIG_VIDEO_SELECT=y
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y
+# CONFIG_FONTS is not set
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
+
+#
+# Logo configuration
+#
+CONFIG_LOGO=y
+# CONFIG_LOGO_LINUX_MONO is not set
+# CONFIG_LOGO_LINUX_VGA16 is not set
+CONFIG_LOGO_LINUX_CLUT224=y
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+CONFIG_BACKLIGHT_CLASS_DEVICE=m
+CONFIG_BACKLIGHT_DEVICE=y
+CONFIG_LCD_CLASS_DEVICE=m
+CONFIG_LCD_DEVICE=y
+
+#
+# Sound
+#
+CONFIG_SOUND=m
+
+#
+# Advanced Linux Sound Architecture
+#
+CONFIG_SND=m
+CONFIG_SND_TIMER=m
+CONFIG_SND_PCM=m
+CONFIG_SND_HWDEP=m
+CONFIG_SND_RAWMIDI=m
+CONFIG_SND_SEQUENCER=m
+CONFIG_SND_SEQ_DUMMY=m
+CONFIG_SND_OSSEMUL=y
+CONFIG_SND_MIXER_OSS=m
+CONFIG_SND_PCM_OSS=m
+CONFIG_SND_PCM_OSS_PLUGINS=y
+CONFIG_SND_SEQUENCER_OSS=y
+CONFIG_SND_RTCTIMER=m
+CONFIG_SND_SEQ_RTCTIMER_DEFAULT=y
+CONFIG_SND_DYNAMIC_MINORS=y
+# CONFIG_SND_SUPPORT_OLD_API is not set
+CONFIG_SND_VERBOSE_PROCFS=y
+# CONFIG_SND_VERBOSE_PRINTK is not set
+# CONFIG_SND_DEBUG is not set
+
+#
+# Generic devices
+#
+CONFIG_SND_MPU401_UART=m
+CONFIG_SND_OPL3_LIB=m
+CONFIG_SND_VX_LIB=m
+CONFIG_SND_AC97_CODEC=m
+CONFIG_SND_AC97_BUS=m
+CONFIG_SND_DUMMY=m
+CONFIG_SND_VIRMIDI=m
+CONFIG_SND_MTPAV=m
+# CONFIG_SND_SERIAL_U16550 is not set
+CONFIG_SND_MPU401=m
+
+#
+# PCI devices
+#
+CONFIG_SND_AD1889=m
+CONFIG_SND_ALS300=m
+CONFIG_SND_ALS4000=m
+CONFIG_SND_ALI5451=m
+CONFIG_SND_ATIIXP=m
+CONFIG_SND_ATIIXP_MODEM=m
+CONFIG_SND_AU8810=m
+CONFIG_SND_AU8820=m
+CONFIG_SND_AU8830=m
+CONFIG_SND_AZT3328=m
+CONFIG_SND_BT87X=m
+# CONFIG_SND_BT87X_OVERCLOCK is not set
+CONFIG_SND_CA0106=m
+CONFIG_SND_CMIPCI=m
+CONFIG_SND_CS4281=m
+CONFIG_SND_CS46XX=m
+CONFIG_SND_CS46XX_NEW_DSP=y
+CONFIG_SND_DARLA20=m
+CONFIG_SND_GINA20=m
+CONFIG_SND_LAYLA20=m
+CONFIG_SND_DARLA24=m
+CONFIG_SND_GINA24=m
+CONFIG_SND_LAYLA24=m
+CONFIG_SND_MONA=m
+CONFIG_SND_MIA=m
+CONFIG_SND_ECHO3G=m
+CONFIG_SND_INDIGO=m
+CONFIG_SND_INDIGOIO=m
+CONFIG_SND_INDIGODJ=m
+CONFIG_SND_EMU10K1=m
+CONFIG_SND_EMU10K1X=m
+CONFIG_SND_ENS1370=m
+CONFIG_SND_ENS1371=m
+CONFIG_SND_ES1938=m
+CONFIG_SND_ES1968=m
+CONFIG_SND_FM801=m
+CONFIG_SND_FM801_TEA575X_BOOL=y
+CONFIG_SND_FM801_TEA575X=m
+CONFIG_SND_HDA_INTEL=m
+CONFIG_SND_HDSP=m
+CONFIG_SND_HDSPM=m
+CONFIG_SND_ICE1712=m
+CONFIG_SND_ICE1724=m
+CONFIG_SND_INTEL8X0=m
+CONFIG_SND_INTEL8X0M=m
+CONFIG_SND_KORG1212=m
+CONFIG_SND_MAESTRO3=m
+CONFIG_SND_MIXART=m
+CONFIG_SND_NM256=m
+CONFIG_SND_PCXHR=m
+CONFIG_SND_RIPTIDE=m
+CONFIG_SND_RME32=m
+CONFIG_SND_RME96=m
+CONFIG_SND_RME9652=m
+CONFIG_SND_SONICVIBES=m
+CONFIG_SND_TRIDENT=m
+CONFIG_SND_VIA82XX=m
+CONFIG_SND_VIA82XX_MODEM=m
+CONFIG_SND_VX222=m
+CONFIG_SND_YMFPCI=m
+
+#
+# USB devices
+#
+CONFIG_SND_USB_AUDIO=m
+CONFIG_SND_USB_USX2Y=m
+
+#
+# PCMCIA devices
+#
+# CONFIG_SND_VXPOCKET is not set
+# CONFIG_SND_PDAUDIOCF is not set
+
+#
+# Open Sound System
+#
+# CONFIG_SOUND_PRIME is not set
+
+#
+# USB support
+#
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB_ARCH_HAS_EHCI=y
+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_SUSPEND is not set
+# CONFIG_USB_OTG is not set
+
+#
+# USB Host Controller Drivers
+#
+CONFIG_USB_EHCI_HCD=m
+CONFIG_USB_EHCI_SPLIT_ISO=y
+CONFIG_USB_EHCI_ROOT_HUB_TT=y
+CONFIG_USB_EHCI_TT_NEWSCHED=y
+CONFIG_USB_ISP116X_HCD=m
+CONFIG_USB_OHCI_HCD=m
+# CONFIG_USB_OHCI_BIG_ENDIAN is not set
+CONFIG_USB_OHCI_LITTLE_ENDIAN=y
+CONFIG_USB_UHCI_HCD=m
+CONFIG_USB_SL811_HCD=m
+CONFIG_USB_SL811_CS=m
+
+#
+# USB Device Class drivers
+#
+CONFIG_USB_ACM=m
+CONFIG_USB_PRINTER=m
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+#
+
+#
+# may also be needed; see USB_STORAGE Help for more information
+#
+CONFIG_USB_STORAGE=m
+# CONFIG_USB_STORAGE_DEBUG is not set
+CONFIG_USB_STORAGE_DATAFAB=y
+CONFIG_USB_STORAGE_FREECOM=y
+CONFIG_USB_STORAGE_ISD200=y
+CONFIG_USB_STORAGE_DPCM=y
+CONFIG_USB_STORAGE_USBAT=y
+CONFIG_USB_STORAGE_SDDR09=y
+CONFIG_USB_STORAGE_SDDR55=y
+CONFIG_USB_STORAGE_JUMPSHOT=y
+CONFIG_USB_STORAGE_ALAUDA=y
+CONFIG_USB_LIBUSUAL=y
+
+#
+# USB Input Devices
+#
+CONFIG_USB_HID=y
+CONFIG_USB_HIDINPUT=y
+# CONFIG_USB_HIDINPUT_POWERBOOK is not set
+CONFIG_HID_FF=y
+CONFIG_HID_PID=y
+CONFIG_LOGITECH_FF=y
+CONFIG_THRUSTMASTER_FF=y
+CONFIG_USB_HIDDEV=y
+CONFIG_USB_AIPTEK=m
+CONFIG_USB_WACOM=m
+CONFIG_USB_ACECAD=m
+CONFIG_USB_KBTAB=m
+CONFIG_USB_POWERMATE=m
+CONFIG_USB_TOUCHSCREEN=m
+CONFIG_USB_TOUCHSCREEN_EGALAX=y
+CONFIG_USB_TOUCHSCREEN_PANJIT=y
+CONFIG_USB_TOUCHSCREEN_3M=y
+CONFIG_USB_TOUCHSCREEN_ITM=y
+# CONFIG_USB_YEALINK is not set
+CONFIG_USB_XPAD=m
+CONFIG_USB_ATI_REMOTE=m
+CONFIG_USB_ATI_REMOTE2=m
+CONFIG_USB_KEYSPAN_REMOTE=m
+CONFIG_USB_APPLETOUCH=m
+
+#
+# USB Imaging devices
+#
+CONFIG_USB_MDC800=m
+CONFIG_USB_MICROTEK=m
+
+#
+# USB Network Adapters
+#
+CONFIG_USB_CATC=m
+CONFIG_USB_KAWETH=m
+CONFIG_USB_PEGASUS=m
+CONFIG_USB_RTL8150=m
+CONFIG_USB_USBNET=m
+CONFIG_USB_NET_AX8817X=m
+CONFIG_USB_NET_CDCETHER=m
+CONFIG_USB_NET_GL620A=m
+CONFIG_USB_NET_NET1080=m
+CONFIG_USB_NET_PLUSB=m
+CONFIG_USB_NET_RNDIS_HOST=m
+CONFIG_USB_NET_CDC_SUBSET=m
+CONFIG_USB_ALI_M5632=y
+CONFIG_USB_AN2720=y
+CONFIG_USB_BELKIN=y
+CONFIG_USB_ARMLINUX=y
+CONFIG_USB_EPSON2888=y
+CONFIG_USB_NET_ZAURUS=m
+CONFIG_USB_MON=y
+
+#
+# USB port drivers
+#
+CONFIG_USB_USS720=m
+
+#
+# USB Serial Converter support
+#
+CONFIG_USB_SERIAL=m
+CONFIG_USB_SERIAL_GENERIC=y
+CONFIG_USB_SERIAL_AIRPRIME=m
+CONFIG_USB_SERIAL_ARK3116=m
+CONFIG_USB_SERIAL_BELKIN=m
+CONFIG_USB_SERIAL_WHITEHEAT=m
+CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m
+CONFIG_USB_SERIAL_CP2101=m
+CONFIG_USB_SERIAL_CYPRESS_M8=m
+CONFIG_USB_SERIAL_EMPEG=m
+CONFIG_USB_SERIAL_FTDI_SIO=m
+CONFIG_USB_SERIAL_FUNSOFT=m
+CONFIG_USB_SERIAL_VISOR=m
+CONFIG_USB_SERIAL_IPAQ=m
+CONFIG_USB_SERIAL_IR=m
+CONFIG_USB_SERIAL_EDGEPORT=m
+CONFIG_USB_SERIAL_EDGEPORT_TI=m
+CONFIG_USB_SERIAL_GARMIN=m
+CONFIG_USB_SERIAL_IPW=m
+CONFIG_USB_SERIAL_KEYSPAN_PDA=m
+CONFIG_USB_SERIAL_KEYSPAN=m
+CONFIG_USB_SERIAL_KEYSPAN_MPR=y
+CONFIG_USB_SERIAL_KEYSPAN_USA28=y
+CONFIG_USB_SERIAL_KEYSPAN_USA28X=y
+CONFIG_USB_SERIAL_KEYSPAN_USA28XA=y
+CONFIG_USB_SERIAL_KEYSPAN_USA28XB=y
+CONFIG_USB_SERIAL_KEYSPAN_USA19=y
+CONFIG_USB_SERIAL_KEYSPAN_USA18X=y
+CONFIG_USB_SERIAL_KEYSPAN_USA19W=y
+CONFIG_USB_SERIAL_KEYSPAN_USA19QW=y
+CONFIG_USB_SERIAL_KEYSPAN_USA19QI=y
+CONFIG_USB_SERIAL_KEYSPAN_USA49W=y
+CONFIG_USB_SERIAL_KEYSPAN_USA49WLC=y
+CONFIG_USB_SERIAL_KLSI=m
+CONFIG_USB_SERIAL_KOBIL_SCT=m
+CONFIG_USB_SERIAL_MCT_U232=m
+CONFIG_USB_SERIAL_NAVMAN=m
+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=m
+CONFIG_USB_SERIAL_TI=m
+CONFIG_USB_SERIAL_CYBERJACK=m
+CONFIG_USB_SERIAL_XIRCOM=m
+CONFIG_USB_SERIAL_OPTION=m
+CONFIG_USB_SERIAL_OMNINET=m
+CONFIG_USB_EZUSB=y
+
+#
+# USB Miscellaneous drivers
+#
+CONFIG_USB_EMI62=m
+CONFIG_USB_EMI26=m
+CONFIG_USB_AUERSWALD=m
+CONFIG_USB_RIO500=m
+CONFIG_USB_LEGOTOWER=m
+CONFIG_USB_LCD=m
+CONFIG_USB_LED=m
+# CONFIG_USB_CYPRESS_CY7C63 is not set
+# CONFIG_USB_CYTHERM is not set
+CONFIG_USB_PHIDGETKIT=m
+CONFIG_USB_PHIDGETSERVO=m
+CONFIG_USB_IDMOUSE=m
+CONFIG_USB_APPLEDISPLAY=m
+CONFIG_USB_SISUSBVGA=m
+CONFIG_USB_SISUSBVGA_CON=y
+CONFIG_USB_LD=m
+CONFIG_USB_TEST=m
+
+#
+# USB DSL modem support
+#
+CONFIG_USB_ATM=m
+CONFIG_USB_SPEEDTOUCH=m
+CONFIG_USB_CXACRU=m
+CONFIG_USB_UEAGLEATM=m
+CONFIG_USB_XUSBATM=m
+
+#
+# USB Gadget Support
+#
+# CONFIG_USB_GADGET is not set
+
+#
+# MMC/SD Card support
+#
+CONFIG_MMC=m
+# CONFIG_MMC_DEBUG is not set
+CONFIG_MMC_BLOCK=m
+CONFIG_MMC_SDHCI=m
+CONFIG_MMC_WBSD=m
+
+#
+# LED devices
+#
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+
+#
+# LED drivers
+#
+
+#
+# LED Triggers
+#
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_LEDS_TRIGGER_TIMER=m
+CONFIG_LEDS_TRIGGER_IDE_DISK=y
+CONFIG_LEDS_TRIGGER_HEARTBEAT=m
+
+#
+# InfiniBand support
+#
+CONFIG_INFINIBAND=m
+CONFIG_INFINIBAND_USER_MAD=m
+CONFIG_INFINIBAND_USER_ACCESS=m
+CONFIG_INFINIBAND_ADDR_TRANS=y
+CONFIG_INFINIBAND_MTHCA=m
+CONFIG_INFINIBAND_MTHCA_DEBUG=y
+CONFIG_IPATH_CORE=m
+CONFIG_INFINIBAND_IPATH=m
+CONFIG_INFINIBAND_IPOIB=m
+CONFIG_INFINIBAND_IPOIB_DEBUG=y
+CONFIG_INFINIBAND_IPOIB_DEBUG_DATA=y
+CONFIG_INFINIBAND_SRP=m
+CONFIG_INFINIBAND_ISER=m
+
+#
+# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
+#
+CONFIG_EDAC=y
+
+#
+# Reporting subsystems
+#
+# CONFIG_EDAC_DEBUG is not set
+CONFIG_EDAC_MM_EDAC=m
+CONFIG_EDAC_E752X=m
+CONFIG_EDAC_K8=m
+CONFIG_EDAC_POLL=y
+
+#
+# Real Time Clock
+#
+CONFIG_RTC_LIB=m
+CONFIG_RTC_CLASS=m
+
+#
+# RTC interfaces
+#
+CONFIG_RTC_INTF_SYSFS=m
+CONFIG_RTC_INTF_PROC=m
+CONFIG_RTC_INTF_DEV=m
+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
+
+#
+# RTC drivers
+#
+CONFIG_RTC_DRV_X1205=m
+CONFIG_RTC_DRV_DS1307=m
+CONFIG_RTC_DRV_DS1553=m
+CONFIG_RTC_DRV_ISL1208=m
+CONFIG_RTC_DRV_DS1672=m
+CONFIG_RTC_DRV_DS1742=m
+CONFIG_RTC_DRV_PCF8563=m
+CONFIG_RTC_DRV_PCF8583=m
+CONFIG_RTC_DRV_RS5C372=m
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_TEST is not set
+CONFIG_RTC_DRV_V3020=m
+
+#
+# DMA Engine support
+#
+CONFIG_DMA_ENGINE=y
+
+#
+# DMA Clients
+#
+CONFIG_NET_DMA=y
+
+#
+# DMA Devices
+#
+CONFIG_INTEL_IOATDMA=m
+
+#
+# Firmware Drivers
+#
+CONFIG_EDD=m
+CONFIG_DELL_RBU=m
+CONFIG_DCDBAS=m
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+CONFIG_EXT2_FS_POSIX_ACL=y
+CONFIG_EXT2_FS_SECURITY=y
+CONFIG_EXT2_FS_XIP=y
+CONFIG_FS_XIP=y
+CONFIG_EXT3_FS=m
+CONFIG_EXT3_FS_XATTR=y
+CONFIG_EXT3_FS_POSIX_ACL=y
+CONFIG_EXT3_FS_SECURITY=y
+CONFIG_JBD=m
+# CONFIG_JBD_DEBUG is not set
+CONFIG_FS_MBCACHE=y
+CONFIG_REISERFS_FS=m
+# CONFIG_REISERFS_CHECK is not set
+CONFIG_REISERFS_PROC_INFO=y
+CONFIG_REISERFS_FS_XATTR=y
+CONFIG_REISERFS_FS_POSIX_ACL=y
+CONFIG_REISERFS_FS_SECURITY=y
+CONFIG_JFS_FS=m
+CONFIG_JFS_POSIX_ACL=y
+CONFIG_JFS_SECURITY=y
+# CONFIG_JFS_DEBUG is not set
+# CONFIG_JFS_STATISTICS is not set
+CONFIG_FS_POSIX_ACL=y
+CONFIG_XFS_FS=m
+CONFIG_XFS_QUOTA=y
+CONFIG_XFS_SECURITY=y
+CONFIG_XFS_POSIX_ACL=y
+# CONFIG_XFS_RT is not set
+CONFIG_OCFS2_FS=m
+# CONFIG_OCFS2_DEBUG_MASKLOG is not set
+CONFIG_MINIX_FS=m
+CONFIG_ROMFS_FS=m
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+CONFIG_QUOTA=y
+# CONFIG_QFMT_V1 is not set
+CONFIG_QFMT_V2=y
+CONFIG_QUOTACTL=y
+CONFIG_DNOTIFY=y
+CONFIG_AUTOFS_FS=m
+CONFIG_AUTOFS4_FS=m
+CONFIG_FUSE_FS=m
+
+#
+# Caches
+#
+CONFIG_FSCACHE=m
+
+#
+# CD-ROM/DVD Filesystems
+#
+CONFIG_ISO9660_FS=y
+CONFIG_JOLIET=y
+CONFIG_ZISOFS=y
+CONFIG_ZISOFS_FS=y
+CONFIG_UDF_FS=m
+CONFIG_UDF_NLS=y
+CONFIG_CACHEFILES=m
+CONFIG_CACHEFILES_DEBUG=y
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=m
+CONFIG_MSDOS_FS=m
+CONFIG_VFAT_FS=m
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="ascii"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+CONFIG_HUGETLBFS=y
+CONFIG_HUGETLB_PAGE=y
+CONFIG_RAMFS=y
+CONFIG_CONFIGFS_FS=m
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+CONFIG_AFFS_FS=m
+CONFIG_HFS_FS=m
+CONFIG_HFSPLUS_FS=m
+CONFIG_BEFS_FS=m
+# CONFIG_BEFS_DEBUG is not set
+CONFIG_BFS_FS=m
+CONFIG_EFS_FS=m
+# CONFIG_JFFS_FS is not set
+CONFIG_JFFS2_FS=m
+CONFIG_JFFS2_FS_DEBUG=0
+CONFIG_JFFS2_FS_WRITEBUFFER=y
+CONFIG_JFFS2_SUMMARY=y
+# 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=m
+CONFIG_SQUASHFS=m
+# CONFIG_SQUASHFS_EMBEDDED is not set
+CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3
+# CONFIG_SQUASHFS_VMALLOC is not set
+CONFIG_VXFS_FS=m
+# CONFIG_HPFS_FS is not set
+CONFIG_QNX4FS_FS=m
+CONFIG_SYSV_FS=m
+CONFIG_UFS_FS=m
+# CONFIG_UFS_FS_WRITE is not set
+# CONFIG_UFS_DEBUG is not set
+
+#
+# Network File Systems
+#
+CONFIG_NFS_FS=m
+CONFIG_NFS_V3=y
+CONFIG_NFS_V3_ACL=y
+CONFIG_NFS_V4=y
+CONFIG_NFS_FSCACHE=y
+CONFIG_NFS_DIRECTIO=y
+CONFIG_NFSD=m
+CONFIG_NFSD_V2_ACL=y
+CONFIG_NFSD_V3=y
+CONFIG_NFSD_V3_ACL=y
+CONFIG_NFSD_V4=y
+CONFIG_NFSD_TCP=y
+CONFIG_LOCKD=m
+CONFIG_LOCKD_V4=y
+CONFIG_EXPORTFS=m
+CONFIG_NFS_ACL_SUPPORT=m
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=m
+CONFIG_SUNRPC_GSS=m
+CONFIG_RPCSEC_GSS_KRB5=m
+CONFIG_RPCSEC_GSS_SPKM3=m
+# CONFIG_SMB_FS is not set
+CONFIG_CIFS=m
+# CONFIG_CIFS_STATS is not set
+CONFIG_CIFS_WEAK_PW_HASH=y
+CONFIG_CIFS_XATTR=y
+CONFIG_CIFS_POSIX=y
+# CONFIG_CIFS_DEBUG2 is not set
+# CONFIG_CIFS_EXPERIMENTAL is not set
+CONFIG_NCP_FS=m
+CONFIG_NCPFS_PACKET_SIGNING=y
+CONFIG_NCPFS_IOCTL_LOCKING=y
+CONFIG_NCPFS_STRONG=y
+CONFIG_NCPFS_NFS_NS=y
+CONFIG_NCPFS_OS2_NS=y
+CONFIG_NCPFS_SMALLDOS=y
+CONFIG_NCPFS_NLS=y
+CONFIG_NCPFS_EXTRAS=y
+CONFIG_CODA_FS=m
+# CONFIG_CODA_FS_OLD_API is not set
+# CONFIG_AFS_FS is not set
+CONFIG_9P_FS=m
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+CONFIG_OSF_PARTITION=y
+CONFIG_AMIGA_PARTITION=y
+# CONFIG_ATARI_PARTITION is not set
+CONFIG_MAC_PARTITION=y
+CONFIG_MSDOS_PARTITION=y
+CONFIG_BSD_DISKLABEL=y
+CONFIG_MINIX_SUBPARTITION=y
+CONFIG_SOLARIS_X86_PARTITION=y
+CONFIG_UNIXWARE_DISKLABEL=y
+# CONFIG_LDM_PARTITION is not set
+CONFIG_SGI_PARTITION=y
+# CONFIG_ULTRIX_PARTITION is not set
+CONFIG_SUN_PARTITION=y
+CONFIG_KARMA_PARTITION=y
+CONFIG_EFI_PARTITION=y
+
+#
+# Native Language Support
+#
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="utf8"
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_CODEPAGE_737=m
+CONFIG_NLS_CODEPAGE_775=m
+CONFIG_NLS_CODEPAGE_850=m
+CONFIG_NLS_CODEPAGE_852=m
+CONFIG_NLS_CODEPAGE_855=m
+CONFIG_NLS_CODEPAGE_857=m
+CONFIG_NLS_CODEPAGE_860=m
+CONFIG_NLS_CODEPAGE_861=m
+CONFIG_NLS_CODEPAGE_862=m
+CONFIG_NLS_CODEPAGE_863=m
+CONFIG_NLS_CODEPAGE_864=m
+CONFIG_NLS_CODEPAGE_865=m
+CONFIG_NLS_CODEPAGE_866=m
+CONFIG_NLS_CODEPAGE_869=m
+CONFIG_NLS_CODEPAGE_936=m
+CONFIG_NLS_CODEPAGE_950=m
+CONFIG_NLS_CODEPAGE_932=m
+CONFIG_NLS_CODEPAGE_949=m
+CONFIG_NLS_CODEPAGE_874=m
+CONFIG_NLS_ISO8859_8=m
+CONFIG_NLS_CODEPAGE_1250=m
+CONFIG_NLS_CODEPAGE_1251=m
+CONFIG_NLS_ASCII=y
+CONFIG_NLS_ISO8859_1=m
+CONFIG_NLS_ISO8859_2=m
+CONFIG_NLS_ISO8859_3=m
+CONFIG_NLS_ISO8859_4=m
+CONFIG_NLS_ISO8859_5=m
+CONFIG_NLS_ISO8859_6=m
+CONFIG_NLS_ISO8859_7=m
+CONFIG_NLS_ISO8859_9=m
+CONFIG_NLS_ISO8859_13=m
+CONFIG_NLS_ISO8859_14=m
+CONFIG_NLS_ISO8859_15=m
+CONFIG_NLS_KOI8_R=m
+CONFIG_NLS_KOI8_U=m
+CONFIG_NLS_UTF8=m
+
+#
+# Instrumentation Support
+#
+CONFIG_PROFILING=y
+CONFIG_OPROFILE=m
+CONFIG_KPROBES=y
+
+#
+# Kernel hacking
+#
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+# CONFIG_PRINTK_TIME is not set
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_UNUSED_SYMBOLS is not set
+CONFIG_DEBUG_KERNEL=y
+CONFIG_LOG_BUF_SHIFT=17
+CONFIG_DETECT_SOFTLOCKUP=y
+CONFIG_SCHEDSTATS=y
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
+CONFIG_DEBUG_SPINLOCK=y
+# 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=y
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+# CONFIG_DEBUG_KOBJECT is not set
+CONFIG_DEBUG_INFO=y
+CONFIG_DEBUG_FS=y
+# CONFIG_DEBUG_VM is not set
+CONFIG_DEBUG_LIST=y
+# CONFIG_FRAME_POINTER is not set
+CONFIG_UNWIND_INFO=y
+CONFIG_STACK_UNWIND=y
+# CONFIG_FORCED_INLINING is not set
+CONFIG_BOOT_DELAY=y
+# CONFIG_RCU_TORTURE_TEST is not set
+CONFIG_DEBUG_RODATA=y
+# CONFIG_IOMMU_DEBUG is not set
+CONFIG_DEBUG_STACKOVERFLOW=y
+# CONFIG_DEBUG_STACK_USAGE is not set
+
+#
+# Security options
+#
+CONFIG_KEYS=y
+CONFIG_KEYS_DEBUG_PROC_KEYS=y
+CONFIG_SECURITY=y
+CONFIG_SECURITY_NETWORK=y
+# CONFIG_SECURITY_NETWORK_XFRM is not set
+CONFIG_SECURITY_CAPABILITIES=y
+# CONFIG_SECURITY_ROOTPLUG is not set
+# CONFIG_SECURITY_SECLVL is not set
+CONFIG_SECURITY_SELINUX=y
+CONFIG_SECURITY_SELINUX_BOOTPARAM=y
+CONFIG_SECURITY_SELINUX_BOOTPARAM_VALUE=1
+CONFIG_SECURITY_SELINUX_DISABLE=y
+CONFIG_SECURITY_SELINUX_DEVELOP=y
+CONFIG_SECURITY_SELINUX_AVC_STATS=y
+CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE=1
+# CONFIG_SECURITY_SELINUX_ENABLE_SECMARK_DEFAULT is not set
+# CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX is not set
+
+#
+# Cryptographic options
+#
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_NULL=m
+CONFIG_CRYPTO_MD4=m
+CONFIG_CRYPTO_MD5=m
+CONFIG_CRYPTO_SHA1=y
+CONFIG_CRYPTO_SHA256=m
+CONFIG_CRYPTO_SHA512=m
+CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_TGR192=m
+CONFIG_CRYPTO_DES=m
+CONFIG_CRYPTO_BLOWFISH=m
+CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_SERPENT=m
+CONFIG_CRYPTO_AES=m
+CONFIG_CRYPTO_AES_X86_64=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_TEST is not set
+CONFIG_CRYPTO_SIGNATURE=y
+CONFIG_CRYPTO_SIGNATURE_DSA=y
+CONFIG_CRYPTO_MPILIB=y
+
+#
+# Hardware crypto devices
+#
+
+#
+# Library routines
+#
+CONFIG_CRC_CCITT=m
+CONFIG_CRC16=m
+CONFIG_CRC32=y
+CONFIG_LIBCRC32C=m
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=m
+CONFIG_REED_SOLOMON=m
+CONFIG_REED_SOLOMON_DEC16=y
+CONFIG_TEXTSEARCH=y
+CONFIG_TEXTSEARCH_KMP=m
+CONFIG_TEXTSEARCH_BM=m
+CONFIG_TEXTSEARCH_FSM=m
+CONFIG_PLIST=y
diff --git a/drivers/acpi/cm_sbs.c b/drivers/acpi/cm_sbs.c
new file mode 100644
index 000000000..a01ce6700
--- /dev/null
+++ b/drivers/acpi/cm_sbs.c
@@ -0,0 +1,113 @@
+/*
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ *  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/acpi.h>
+#include <linux/types.h>
+#include <linux/proc_fs.h>
+#include <linux/seq_file.h>
+#include <acpi/acpi_bus.h>
+#include <acpi/acpi_drivers.h>
+#include <acpi/acmacros.h>
+#include <acpi/actypes.h>
+#include <acpi/acutils.h>
+
+ACPI_MODULE_NAME("cm_sbs")
+#define ACPI_AC_CLASS		"ac_adapter"
+#define ACPI_BATTERY_CLASS	"battery"
+#define ACPI_SBS_COMPONENT	0x00080000
+#define _COMPONENT		ACPI_SBS_COMPONENT
+static struct proc_dir_entry *acpi_ac_dir;
+static struct proc_dir_entry *acpi_battery_dir;
+
+static DEFINE_MUTEX(cm_sbs_mutex);
+
+static int lock_ac_dir_cnt;
+static int lock_battery_dir_cnt;
+
+struct proc_dir_entry *acpi_lock_ac_dir(void)
+{
+	mutex_lock(&cm_sbs_mutex);
+	if (!acpi_ac_dir)
+		acpi_ac_dir = proc_mkdir(ACPI_AC_CLASS, acpi_root_dir);
+	if (acpi_ac_dir) {
+		lock_ac_dir_cnt++;
+	} else {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+				  "Cannot create %s\n", ACPI_AC_CLASS));
+	}
+	mutex_unlock(&cm_sbs_mutex);
+	return acpi_ac_dir;
+}
+EXPORT_SYMBOL(acpi_lock_ac_dir);
+
+void acpi_unlock_ac_dir(struct proc_dir_entry *acpi_ac_dir_param)
+{
+	mutex_lock(&cm_sbs_mutex);
+	if (acpi_ac_dir_param)
+		lock_ac_dir_cnt--;
+	if (lock_ac_dir_cnt == 0 && acpi_ac_dir_param && acpi_ac_dir) {
+		remove_proc_entry(ACPI_AC_CLASS, acpi_root_dir);
+		acpi_ac_dir = 0;
+	}
+	mutex_unlock(&cm_sbs_mutex);
+}
+EXPORT_SYMBOL(acpi_unlock_ac_dir);
+
+struct proc_dir_entry *acpi_lock_battery_dir(void)
+{
+	mutex_lock(&cm_sbs_mutex);
+	if (!acpi_battery_dir) {
+		acpi_battery_dir =
+		    proc_mkdir(ACPI_BATTERY_CLASS, acpi_root_dir);
+	}
+	if (acpi_battery_dir) {
+		lock_battery_dir_cnt++;
+	} else {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+				  "Cannot create %s\n", ACPI_BATTERY_CLASS));
+	}
+	mutex_unlock(&cm_sbs_mutex);
+	return acpi_battery_dir;
+}
+EXPORT_SYMBOL(acpi_lock_battery_dir);
+
+void acpi_unlock_battery_dir(struct proc_dir_entry *acpi_battery_dir_param)
+{
+	mutex_lock(&cm_sbs_mutex);
+	if (acpi_battery_dir_param)
+		lock_battery_dir_cnt--;
+	if (lock_battery_dir_cnt == 0 && acpi_battery_dir_param
+	    && acpi_battery_dir) {
+		remove_proc_entry(ACPI_BATTERY_CLASS, acpi_root_dir);
+		acpi_battery_dir = 0;
+	}
+	mutex_unlock(&cm_sbs_mutex);
+	return;
+}
+EXPORT_SYMBOL(acpi_unlock_battery_dir);
+
+static int __init acpi_cm_sbs_init(void)
+{
+	return 0;
+}
+subsys_initcall(acpi_cm_sbs_init);
diff --git a/drivers/acpi/dock.c b/drivers/acpi/dock.c
new file mode 100644
index 000000000..578b99b71
--- /dev/null
+++ b/drivers/acpi/dock.c
@@ -0,0 +1,739 @@
+/*
+ *  dock.c - ACPI dock station driver
+ *
+ *  Copyright (C) 2006 Kristen Carlson Accardi <kristen.c.accardi@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/notifier.h>
+#include <acpi/acpi_bus.h>
+#include <acpi/acpi_drivers.h>
+
+#define ACPI_DOCK_DRIVER_NAME "ACPI Dock Station Driver"
+
+ACPI_MODULE_NAME("dock")
+MODULE_AUTHOR("Kristen Carlson Accardi");
+MODULE_DESCRIPTION(ACPI_DOCK_DRIVER_NAME);
+MODULE_LICENSE("GPL");
+
+static struct atomic_notifier_head dock_notifier_list;
+
+struct dock_station {
+	acpi_handle handle;
+	unsigned long last_dock_time;
+	u32 flags;
+	spinlock_t dd_lock;
+	spinlock_t hp_lock;
+	struct list_head dependent_devices;
+	struct list_head hotplug_devices;
+};
+
+struct dock_dependent_device {
+	struct list_head list;
+	struct list_head hotplug_list;
+	acpi_handle handle;
+	acpi_notify_handler handler;
+	void *context;
+};
+
+#define DOCK_DOCKING	0x00000001
+#define DOCK_EVENT	3
+#define UNDOCK_EVENT	2
+
+static struct dock_station *dock_station;
+
+/*****************************************************************************
+ *                         Dock Dependent device functions                   *
+ *****************************************************************************/
+/**
+ *  alloc_dock_dependent_device - allocate and init a dependent device
+ *  @handle: the acpi_handle of the dependent device
+ *
+ *  Allocate memory for a dependent device structure for a device referenced
+ *  by the acpi handle
+ */
+static struct dock_dependent_device *
+alloc_dock_dependent_device(acpi_handle handle)
+{
+	struct dock_dependent_device *dd;
+
+	dd = kzalloc(sizeof(*dd), GFP_KERNEL);
+	if (dd) {
+		dd->handle = handle;
+		INIT_LIST_HEAD(&dd->list);
+		INIT_LIST_HEAD(&dd->hotplug_list);
+	}
+	return dd;
+}
+
+/**
+ * add_dock_dependent_device - associate a device with the dock station
+ * @ds: The dock station
+ * @dd: The dependent device
+ *
+ * Add the dependent device to the dock's dependent device list.
+ */
+static void
+add_dock_dependent_device(struct dock_station *ds,
+			  struct dock_dependent_device *dd)
+{
+	spin_lock(&ds->dd_lock);
+	list_add_tail(&dd->list, &ds->dependent_devices);
+	spin_unlock(&ds->dd_lock);
+}
+
+/**
+ * dock_add_hotplug_device - associate a hotplug handler with the dock station
+ * @ds: The dock station
+ * @dd: The dependent device struct
+ *
+ * Add the dependent device to the dock's hotplug device list
+ */
+static void
+dock_add_hotplug_device(struct dock_station *ds,
+			struct dock_dependent_device *dd)
+{
+	spin_lock(&ds->hp_lock);
+	list_add_tail(&dd->hotplug_list, &ds->hotplug_devices);
+	spin_unlock(&ds->hp_lock);
+}
+
+/**
+ * dock_del_hotplug_device - remove a hotplug handler from the dock station
+ * @ds: The dock station
+ * @dd: the dependent device struct
+ *
+ * Delete the dependent device from the dock's hotplug device list
+ */
+static void
+dock_del_hotplug_device(struct dock_station *ds,
+			struct dock_dependent_device *dd)
+{
+	spin_lock(&ds->hp_lock);
+	list_del(&dd->hotplug_list);
+	spin_unlock(&ds->hp_lock);
+}
+
+/**
+ * find_dock_dependent_device - get a device dependent on this dock
+ * @ds: the dock station
+ * @handle: the acpi_handle of the device we want
+ *
+ * iterate over the dependent device list for this dock.  If the
+ * dependent device matches the handle, return.
+ */
+static struct dock_dependent_device *
+find_dock_dependent_device(struct dock_station *ds, acpi_handle handle)
+{
+	struct dock_dependent_device *dd;
+
+	spin_lock(&ds->dd_lock);
+	list_for_each_entry(dd, &ds->dependent_devices, list) {
+		if (handle == dd->handle) {
+			spin_unlock(&ds->dd_lock);
+			return dd;
+		}
+	}
+	spin_unlock(&ds->dd_lock);
+	return NULL;
+}
+
+/*****************************************************************************
+ *                         Dock functions                                    *
+ *****************************************************************************/
+/**
+ * is_dock - see if a device is a dock station
+ * @handle: acpi handle of the device
+ *
+ * If an acpi object has a _DCK method, then it is by definition a dock
+ * station, so return true.
+ */
+static int is_dock(acpi_handle handle)
+{
+	acpi_status status;
+	acpi_handle tmp;
+
+	status = acpi_get_handle(handle, "_DCK", &tmp);
+	if (ACPI_FAILURE(status))
+		return 0;
+	return 1;
+}
+
+/**
+ * is_dock_device - see if a device is on a dock station
+ * @handle: acpi handle of the device
+ *
+ * If this device is either the dock station itself,
+ * or is a device dependent on the dock station, then it
+ * is a dock device
+ */
+int is_dock_device(acpi_handle handle)
+{
+	if (!dock_station)
+		return 0;
+
+	if (is_dock(handle) || find_dock_dependent_device(dock_station, handle))
+		return 1;
+
+	return 0;
+}
+
+EXPORT_SYMBOL_GPL(is_dock_device);
+
+/**
+ * dock_present - see if the dock station is present.
+ * @ds: the dock station
+ *
+ * execute the _STA method.  note that present does not
+ * imply that we are docked.
+ */
+static int dock_present(struct dock_station *ds)
+{
+	unsigned long sta;
+	acpi_status status;
+
+	if (ds) {
+		status = acpi_evaluate_integer(ds->handle, "_STA", NULL, &sta);
+		if (ACPI_SUCCESS(status) && sta)
+			return 1;
+	}
+	return 0;
+}
+
+
+
+/**
+ * dock_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 * dock_create_acpi_device(acpi_handle handle)
+{
+	struct acpi_device *device = NULL;
+	struct acpi_device *parent_device;
+	acpi_handle parent;
+	int ret;
+
+	if (acpi_bus_get_device(handle, &device)) {
+		/*
+		 * no device created for this object,
+		 * so we should create one.
+		 */
+		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;
+}
+
+/**
+ * dock_remove_acpi_device - remove the acpi_device struct from acpi
+ * @handle - the handle of the device to remove
+ *
+ *  Tell acpi to remove the acpi_device.  This should cause any loaded
+ *  driver to have it's remove routine called.
+ */
+static void dock_remove_acpi_device(acpi_handle handle)
+{
+	struct acpi_device *device;
+	int ret;
+
+	if (!acpi_bus_get_device(handle, &device)) {
+		ret = acpi_bus_trim(device, 1);
+		if (ret)
+			pr_debug("error removing bus, %x\n", -ret);
+	}
+}
+
+
+/**
+ * hotplug_dock_devices - insert or remove devices on the dock station
+ * @ds: the dock station
+ * @event: either bus check or eject request
+ *
+ * Some devices on the dock station need to have drivers called
+ * to perform hotplug operations after a dock event has occurred.
+ * Traverse the list of dock devices that have registered a
+ * hotplug handler, and call the handler.
+ */
+static void hotplug_dock_devices(struct dock_station *ds, u32 event)
+{
+	struct dock_dependent_device *dd;
+
+	spin_lock(&ds->hp_lock);
+
+	/*
+	 * First call driver specific hotplug functions
+	 */
+	list_for_each_entry(dd, &ds->hotplug_devices, hotplug_list) {
+		if (dd->handler)
+			dd->handler(dd->handle, event, dd->context);
+	}
+
+	/*
+	 * Now make sure that an acpi_device is created for each
+	 * dependent device, or removed if this is an eject request.
+	 * This will cause acpi_drivers to be stopped/started if they
+	 * exist
+	 */
+	list_for_each_entry(dd, &ds->dependent_devices, list) {
+		if (event == ACPI_NOTIFY_EJECT_REQUEST)
+			dock_remove_acpi_device(dd->handle);
+		else
+			dock_create_acpi_device(dd->handle);
+	}
+	spin_unlock(&ds->hp_lock);
+}
+
+static void dock_event(struct dock_station *ds, u32 event, int num)
+{
+	/*
+	 * we don't do events until someone tells me that
+	 * they would like to have them.
+	 */
+}
+
+/**
+ * eject_dock - respond to a dock eject request
+ * @ds: the dock station
+ *
+ * This is called after _DCK is called, to execute the dock station's
+ * _EJ0 method.
+ */
+static void eject_dock(struct dock_station *ds)
+{
+	struct acpi_object_list arg_list;
+	union acpi_object arg;
+	acpi_status status;
+	acpi_handle tmp;
+
+	/* all dock devices should have _EJ0, but check anyway */
+	status = acpi_get_handle(ds->handle, "_EJ0", &tmp);
+	if (ACPI_FAILURE(status)) {
+		pr_debug("No _EJ0 support for dock device\n");
+		return;
+	}
+
+	arg_list.count = 1;
+	arg_list.pointer = &arg;
+	arg.type = ACPI_TYPE_INTEGER;
+	arg.integer.value = 1;
+
+	if (ACPI_FAILURE(acpi_evaluate_object(ds->handle, "_EJ0",
+					      &arg_list, NULL)))
+		pr_debug("Failed to evaluate _EJ0!\n");
+}
+
+/**
+ * handle_dock - handle a dock event
+ * @ds: the dock station
+ * @dock: to dock, or undock - that is the question
+ *
+ * Execute the _DCK method in response to an acpi event
+ */
+static void handle_dock(struct dock_station *ds, int dock)
+{
+	acpi_status status;
+	struct acpi_object_list arg_list;
+	union acpi_object arg;
+	struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
+	struct acpi_buffer name_buffer = { ACPI_ALLOCATE_BUFFER, NULL };
+	union acpi_object *obj;
+
+	acpi_get_name(ds->handle, ACPI_FULL_PATHNAME, &name_buffer);
+	obj = name_buffer.pointer;
+
+	printk(KERN_INFO PREFIX "%s\n", dock ? "docking" : "undocking");
+
+	/* _DCK method has one argument */
+	arg_list.count = 1;
+	arg_list.pointer = &arg;
+	arg.type = ACPI_TYPE_INTEGER;
+	arg.integer.value = dock;
+	status = acpi_evaluate_object(ds->handle, "_DCK", &arg_list, &buffer);
+	if (ACPI_FAILURE(status))
+		pr_debug("%s: failed to execute _DCK\n", obj->string.pointer);
+	kfree(buffer.pointer);
+	kfree(name_buffer.pointer);
+}
+
+static inline void dock(struct dock_station *ds)
+{
+	handle_dock(ds, 1);
+}
+
+static inline void undock(struct dock_station *ds)
+{
+	handle_dock(ds, 0);
+}
+
+static inline void begin_dock(struct dock_station *ds)
+{
+	ds->flags |= DOCK_DOCKING;
+}
+
+static inline void complete_dock(struct dock_station *ds)
+{
+	ds->flags &= ~(DOCK_DOCKING);
+	ds->last_dock_time = jiffies;
+}
+
+/**
+ * dock_in_progress - see if we are in the middle of handling a dock event
+ * @ds: the dock station
+ *
+ * Sometimes while docking, false dock events can be sent to the driver
+ * because good connections aren't made or some other reason.  Ignore these
+ * if we are in the middle of doing something.
+ */
+static int dock_in_progress(struct dock_station *ds)
+{
+	if ((ds->flags & DOCK_DOCKING) ||
+	    time_before(jiffies, (ds->last_dock_time + HZ)))
+		return 1;
+	return 0;
+}
+
+/**
+ * register_dock_notifier - add yourself to the dock notifier list
+ * @nb: the callers notifier block
+ *
+ * If a driver wishes to be notified about dock events, they can
+ * use this function to put a notifier block on the dock notifier list.
+ * this notifier call chain will be called after a dock event, but
+ * before hotplugging any new devices.
+ */
+int register_dock_notifier(struct notifier_block *nb)
+{
+	return atomic_notifier_chain_register(&dock_notifier_list, nb);
+}
+
+EXPORT_SYMBOL_GPL(register_dock_notifier);
+
+/**
+ * unregister_dock_notifier - remove yourself from the dock notifier list
+ * @nb: the callers notifier block
+ */
+void unregister_dock_notifier(struct notifier_block *nb)
+{
+	atomic_notifier_chain_unregister(&dock_notifier_list, nb);
+}
+
+EXPORT_SYMBOL_GPL(unregister_dock_notifier);
+
+/**
+ * register_hotplug_dock_device - register a hotplug function
+ * @handle: the handle of the device
+ * @handler: the acpi_notifier_handler to call after docking
+ * @context: device specific data
+ *
+ * If a driver would like to perform a hotplug operation after a dock
+ * event, they can register an acpi_notifiy_handler to be called by
+ * the dock driver after _DCK is executed.
+ */
+int
+register_hotplug_dock_device(acpi_handle handle, acpi_notify_handler handler,
+			     void *context)
+{
+	struct dock_dependent_device *dd;
+
+	if (!dock_station)
+		return -ENODEV;
+
+	/*
+	 * make sure this handle is for a device dependent on the dock,
+	 * this would include the dock station itself
+	 */
+	dd = find_dock_dependent_device(dock_station, handle);
+	if (dd) {
+		dd->handler = handler;
+		dd->context = context;
+		dock_add_hotplug_device(dock_station, dd);
+		return 0;
+	}
+
+	return -EINVAL;
+}
+
+EXPORT_SYMBOL_GPL(register_hotplug_dock_device);
+
+/**
+ * unregister_hotplug_dock_device - remove yourself from the hotplug list
+ * @handle: the acpi handle of the device
+ */
+void unregister_hotplug_dock_device(acpi_handle handle)
+{
+	struct dock_dependent_device *dd;
+
+	if (!dock_station)
+		return;
+
+	dd = find_dock_dependent_device(dock_station, handle);
+	if (dd)
+		dock_del_hotplug_device(dock_station, dd);
+}
+
+EXPORT_SYMBOL_GPL(unregister_hotplug_dock_device);
+
+/**
+ * dock_notify - act upon an acpi dock notification
+ * @handle: the dock station handle
+ * @event: the acpi event
+ * @data: our driver data struct
+ *
+ * If we are notified to dock, then check to see if the dock is
+ * present and then dock.  Notify all drivers of the dock event,
+ * and then hotplug and devices that may need hotplugging.  For undock
+ * check to make sure the dock device is still present, then undock
+ * and hotremove all the devices that may need removing.
+ */
+static void dock_notify(acpi_handle handle, u32 event, void *data)
+{
+	struct dock_station *ds = (struct dock_station *)data;
+
+	switch (event) {
+	case ACPI_NOTIFY_BUS_CHECK:
+		if (!dock_in_progress(ds) && dock_present(ds)) {
+			begin_dock(ds);
+			dock(ds);
+			if (!dock_present(ds)) {
+				printk(KERN_ERR PREFIX "Unable to dock!\n");
+				break;
+			}
+			atomic_notifier_call_chain(&dock_notifier_list,
+						   event, NULL);
+			hotplug_dock_devices(ds, event);
+			complete_dock(ds);
+			dock_event(ds, event, DOCK_EVENT);
+		}
+		break;
+	case ACPI_NOTIFY_DEVICE_CHECK:
+	/*
+         * According to acpi spec 3.0a, if a DEVICE_CHECK notification
+         * is sent and _DCK is present, it is assumed to mean an
+         * undock request.  This notify routine will only be called
+         * for objects defining _DCK, so we will fall through to eject
+         * request here.  However, we will pass an eject request through
+	 * to the driver who wish to hotplug.
+         */
+	case ACPI_NOTIFY_EJECT_REQUEST:
+		if (!dock_in_progress(ds) && dock_present(ds)) {
+			/*
+			 * here we need to generate the undock
+			 * event prior to actually doing the undock
+			 * so that the device struct still exists.
+			 */
+			dock_event(ds, event, UNDOCK_EVENT);
+			hotplug_dock_devices(ds, ACPI_NOTIFY_EJECT_REQUEST);
+			undock(ds);
+			eject_dock(ds);
+			if (dock_present(ds))
+				printk(KERN_ERR PREFIX "Unable to undock!\n");
+		}
+		break;
+	default:
+		printk(KERN_ERR PREFIX "Unknown dock event %d\n", event);
+	}
+}
+
+/**
+ * find_dock_devices - find devices on the dock station
+ * @handle: the handle of the device we are examining
+ * @lvl: unused
+ * @context: the dock station private data
+ * @rv: unused
+ *
+ * This function is called by acpi_walk_namespace.  It will
+ * check to see if an object has an _EJD method.  If it does, then it
+ * will see if it is dependent on the dock station.
+ */
+static acpi_status
+find_dock_devices(acpi_handle handle, u32 lvl, void *context, void **rv)
+{
+	acpi_status status;
+	acpi_handle tmp;
+	struct dock_station *ds = (struct dock_station *)context;
+	struct dock_dependent_device *dd;
+
+	status = acpi_bus_get_ejd(handle, &tmp);
+	if (ACPI_FAILURE(status))
+		return AE_OK;
+
+	if (tmp == ds->handle) {
+		dd = alloc_dock_dependent_device(handle);
+		if (dd)
+			add_dock_dependent_device(ds, dd);
+	}
+
+	return AE_OK;
+}
+
+/**
+ * dock_add - add a new dock station
+ * @handle: the dock station handle
+ *
+ * allocated and initialize a new dock station device.  Find all devices
+ * that are on the dock station, and register for dock event notifications.
+ */
+static int dock_add(acpi_handle handle)
+{
+	int ret;
+	acpi_status status;
+	struct dock_dependent_device *dd;
+
+	/* allocate & initialize the dock_station private data */
+	dock_station = kzalloc(sizeof(*dock_station), GFP_KERNEL);
+	if (!dock_station)
+		return -ENOMEM;
+	dock_station->handle = handle;
+	dock_station->last_dock_time = jiffies - HZ;
+	INIT_LIST_HEAD(&dock_station->dependent_devices);
+	INIT_LIST_HEAD(&dock_station->hotplug_devices);
+	spin_lock_init(&dock_station->dd_lock);
+	spin_lock_init(&dock_station->hp_lock);
+	ATOMIC_INIT_NOTIFIER_HEAD(&dock_notifier_list);
+
+	/* Find dependent devices */
+	acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
+			    ACPI_UINT32_MAX, find_dock_devices, dock_station,
+			    NULL);
+
+	/* add the dock station as a device dependent on itself */
+	dd = alloc_dock_dependent_device(handle);
+	if (!dd) {
+		kfree(dock_station);
+		return -ENOMEM;
+	}
+	add_dock_dependent_device(dock_station, dd);
+
+	/* register for dock events */
+	status = acpi_install_notify_handler(dock_station->handle,
+					     ACPI_SYSTEM_NOTIFY,
+					     dock_notify, dock_station);
+
+	if (ACPI_FAILURE(status)) {
+		printk(KERN_ERR PREFIX "Error installing notify handler\n");
+		ret = -ENODEV;
+		goto dock_add_err;
+	}
+
+	printk(KERN_INFO PREFIX "%s \n", ACPI_DOCK_DRIVER_NAME);
+
+	return 0;
+
+dock_add_err:
+	kfree(dock_station);
+	kfree(dd);
+	return ret;
+}
+
+/**
+ * dock_remove - free up resources related to the dock station
+ */
+static int dock_remove(void)
+{
+	struct dock_dependent_device *dd, *tmp;
+	acpi_status status;
+
+	if (!dock_station)
+		return 0;
+
+	/* remove dependent devices */
+	list_for_each_entry_safe(dd, tmp, &dock_station->dependent_devices,
+				 list)
+	    kfree(dd);
+
+	/* remove dock notify handler */
+	status = acpi_remove_notify_handler(dock_station->handle,
+					    ACPI_SYSTEM_NOTIFY,
+					    dock_notify);
+	if (ACPI_FAILURE(status))
+		printk(KERN_ERR "Error removing notify handler\n");
+
+	/* free dock station memory */
+	kfree(dock_station);
+	return 0;
+}
+
+/**
+ * find_dock - look for a dock station
+ * @handle: acpi handle of a device
+ * @lvl: unused
+ * @context: counter of dock stations found
+ * @rv: unused
+ *
+ * This is called by acpi_walk_namespace to look for dock stations.
+ */
+static acpi_status
+find_dock(acpi_handle handle, u32 lvl, void *context, void **rv)
+{
+	int *count = (int *)context;
+	acpi_status status = AE_OK;
+
+	if (is_dock(handle)) {
+		if (dock_add(handle) >= 0) {
+			(*count)++;
+			status = AE_CTRL_TERMINATE;
+		}
+	}
+	return status;
+}
+
+static int __init dock_init(void)
+{
+	int num = 0;
+
+	dock_station = NULL;
+
+	/* look for a dock station */
+	acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
+			    ACPI_UINT32_MAX, find_dock, &num, NULL);
+
+	if (!num)
+		return -ENODEV;
+
+	return 0;
+}
+
+static void __exit dock_exit(void)
+{
+	dock_remove();
+}
+
+postcore_initcall(dock_init);
+module_exit(dock_exit);
diff --git a/drivers/acpi/i2c_ec.c b/drivers/acpi/i2c_ec.c
new file mode 100644
index 000000000..6809c283e
--- /dev/null
+++ b/drivers/acpi/i2c_ec.c
@@ -0,0 +1,406 @@
+/*
+ * SMBus driver for ACPI Embedded Controller ($Revision: 1.3 $)
+ *
+ * Copyright (c) 2002, 2005 Ducrot Bruno
+ * Copyright (c) 2005 Rich Townsend (tiny hacks & tweaks)
+ *
+ * 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.
+ */
+
+#include <linux/version.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/kernel.h>
+#include <linux/stddef.h>
+#include <linux/sched.h>
+#include <linux/init.h>
+#include <linux/i2c.h>
+#include <linux/acpi.h>
+#include <linux/delay.h>
+
+#include "i2c_ec.h"
+
+#define	xudelay(t)	udelay(t)
+#define	xmsleep(t)	msleep(t)
+
+#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")
+
+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,
+	.class = ACPI_EC_HC_CLASS,
+	.ids = ACPI_EC_HC_HID,
+	.ops = {
+		.add = acpi_ec_hc_add,
+		.remove = acpi_ec_hc_remove,
+		},
+};
+
+/* Various bit mask for EC_SC (R) */
+#define OBF		0x01
+#define IBF		0x02
+#define CMD		0x08
+#define BURST		0x10
+#define SCI_EVT		0x20
+#define SMI_EVT		0x40
+
+/* Commands for EC_SC (W) */
+#define RD_EC		0x80
+#define WR_EC		0x81
+#define BE_EC		0x82
+#define BD_EC		0x83
+#define QR_EC		0x84
+
+/*
+ * ACPI 2.0 chapter 13 SMBus 2.0 EC register model
+ */
+
+#define ACPI_EC_SMB_PRTCL	0x00	/* protocol, PEC */
+#define ACPI_EC_SMB_STS		0x01	/* status */
+#define ACPI_EC_SMB_ADDR	0x02	/* address */
+#define ACPI_EC_SMB_CMD		0x03	/* command */
+#define ACPI_EC_SMB_DATA	0x04	/* 32 data registers */
+#define ACPI_EC_SMB_BCNT	0x24	/* number of data bytes */
+#define ACPI_EC_SMB_ALRM_A	0x25	/* alarm address */
+#define ACPI_EC_SMB_ALRM_D	0x26	/* 2 bytes alarm data */
+
+#define ACPI_EC_SMB_STS_DONE	0x80
+#define ACPI_EC_SMB_STS_ALRM	0x40
+#define ACPI_EC_SMB_STS_RES	0x20
+#define ACPI_EC_SMB_STS_STATUS	0x1f
+
+#define ACPI_EC_SMB_STATUS_OK		0x00
+#define ACPI_EC_SMB_STATUS_FAIL		0x07
+#define ACPI_EC_SMB_STATUS_DNAK		0x10
+#define ACPI_EC_SMB_STATUS_DERR		0x11
+#define ACPI_EC_SMB_STATUS_CMD_DENY	0x12
+#define ACPI_EC_SMB_STATUS_UNKNOWN	0x13
+#define ACPI_EC_SMB_STATUS_ACC_DENY	0x17
+#define ACPI_EC_SMB_STATUS_TIMEOUT	0x18
+#define ACPI_EC_SMB_STATUS_NOTSUP	0x19
+#define ACPI_EC_SMB_STATUS_BUSY		0x1A
+#define ACPI_EC_SMB_STATUS_PEC		0x1F
+
+#define ACPI_EC_SMB_PRTCL_WRITE			0x00
+#define ACPI_EC_SMB_PRTCL_READ			0x01
+#define ACPI_EC_SMB_PRTCL_QUICK			0x02
+#define ACPI_EC_SMB_PRTCL_BYTE			0x04
+#define ACPI_EC_SMB_PRTCL_BYTE_DATA		0x06
+#define ACPI_EC_SMB_PRTCL_WORD_DATA		0x08
+#define ACPI_EC_SMB_PRTCL_BLOCK_DATA		0x0a
+#define ACPI_EC_SMB_PRTCL_PROC_CALL		0x0c
+#define ACPI_EC_SMB_PRTCL_BLOCK_PROC_CALL	0x0d
+#define ACPI_EC_SMB_PRTCL_I2C_BLOCK_DATA	0x4a
+#define ACPI_EC_SMB_PRTCL_PEC			0x80
+
+/* Length of pre/post transaction sleep (msec) */
+#define ACPI_EC_SMB_TRANSACTION_SLEEP		1
+#define ACPI_EC_SMB_ACCESS_SLEEP1		1
+#define ACPI_EC_SMB_ACCESS_SLEEP2		10
+
+static int acpi_ec_smb_read(struct acpi_ec_smbus *smbus, u8 address, u8 * data)
+{
+	u8 val;
+	int err;
+
+	err = ec_read(smbus->base + address, &val);
+	if (!err) {
+		*data = val;
+	}
+	xmsleep(ACPI_EC_SMB_TRANSACTION_SLEEP);
+	return (err);
+}
+
+static int acpi_ec_smb_write(struct acpi_ec_smbus *smbus, u8 address, u8 data)
+{
+	int err;
+
+	err = ec_write(smbus->base + address, data);
+	return (err);
+}
+
+static int
+acpi_ec_smb_access(struct i2c_adapter *adap, u16 addr, unsigned short flags,
+		   char read_write, u8 command, int size,
+		   union i2c_smbus_data *data)
+{
+	struct acpi_ec_smbus *smbus = adap->algo_data;
+	unsigned char protocol, len = 0, pec, temp[2] = { 0, 0 };
+	int i;
+
+	if (read_write == I2C_SMBUS_READ) {
+		protocol = ACPI_EC_SMB_PRTCL_READ;
+	} else {
+		protocol = ACPI_EC_SMB_PRTCL_WRITE;
+	}
+	pec = (flags & I2C_CLIENT_PEC) ? ACPI_EC_SMB_PRTCL_PEC : 0;
+
+	switch (size) {
+
+	case I2C_SMBUS_QUICK:
+		protocol |= ACPI_EC_SMB_PRTCL_QUICK;
+		read_write = I2C_SMBUS_WRITE;
+		break;
+
+	case I2C_SMBUS_BYTE:
+		if (read_write == I2C_SMBUS_WRITE) {
+			acpi_ec_smb_write(smbus, ACPI_EC_SMB_DATA, data->byte);
+		}
+		protocol |= ACPI_EC_SMB_PRTCL_BYTE;
+		break;
+
+	case I2C_SMBUS_BYTE_DATA:
+		acpi_ec_smb_write(smbus, ACPI_EC_SMB_CMD, command);
+		if (read_write == I2C_SMBUS_WRITE) {
+			acpi_ec_smb_write(smbus, ACPI_EC_SMB_DATA, data->byte);
+		}
+		protocol |= ACPI_EC_SMB_PRTCL_BYTE_DATA;
+		break;
+
+	case I2C_SMBUS_WORD_DATA:
+		acpi_ec_smb_write(smbus, ACPI_EC_SMB_CMD, command);
+		if (read_write == I2C_SMBUS_WRITE) {
+			acpi_ec_smb_write(smbus, ACPI_EC_SMB_DATA, data->word);
+			acpi_ec_smb_write(smbus, ACPI_EC_SMB_DATA + 1,
+					  data->word >> 8);
+		}
+		protocol |= ACPI_EC_SMB_PRTCL_WORD_DATA | pec;
+		break;
+
+	case I2C_SMBUS_BLOCK_DATA:
+		acpi_ec_smb_write(smbus, ACPI_EC_SMB_CMD, command);
+		if (read_write == I2C_SMBUS_WRITE) {
+			len = min_t(u8, data->block[0], 32);
+			acpi_ec_smb_write(smbus, ACPI_EC_SMB_BCNT, len);
+			for (i = 0; i < len; i++)
+				acpi_ec_smb_write(smbus, ACPI_EC_SMB_DATA + i,
+						  data->block[i + 1]);
+		}
+		protocol |= ACPI_EC_SMB_PRTCL_BLOCK_DATA | pec;
+		break;
+
+	case I2C_SMBUS_I2C_BLOCK_DATA:
+		len = min_t(u8, data->block[0], 32);
+		acpi_ec_smb_write(smbus, ACPI_EC_SMB_CMD, command);
+		acpi_ec_smb_write(smbus, ACPI_EC_SMB_BCNT, len);
+		if (read_write == I2C_SMBUS_WRITE) {
+			for (i = 0; i < len; i++) {
+				acpi_ec_smb_write(smbus, ACPI_EC_SMB_DATA + i,
+						  data->block[i + 1]);
+			}
+		}
+		protocol |= ACPI_EC_SMB_PRTCL_I2C_BLOCK_DATA;
+		break;
+
+	case I2C_SMBUS_PROC_CALL:
+		acpi_ec_smb_write(smbus, ACPI_EC_SMB_CMD, command);
+		acpi_ec_smb_write(smbus, ACPI_EC_SMB_DATA, data->word);
+		acpi_ec_smb_write(smbus, ACPI_EC_SMB_DATA + 1, data->word >> 8);
+		protocol = ACPI_EC_SMB_PRTCL_PROC_CALL | pec;
+		read_write = I2C_SMBUS_READ;
+		break;
+
+	case I2C_SMBUS_BLOCK_PROC_CALL:
+		protocol |= pec;
+		len = min_t(u8, data->block[0], 31);
+		acpi_ec_smb_write(smbus, ACPI_EC_SMB_CMD, command);
+		acpi_ec_smb_write(smbus, ACPI_EC_SMB_BCNT, len);
+		for (i = 0; i < len; i++)
+			acpi_ec_smb_write(smbus, ACPI_EC_SMB_DATA + i,
+					  data->block[i + 1]);
+		protocol = ACPI_EC_SMB_PRTCL_BLOCK_PROC_CALL | pec;
+		read_write = I2C_SMBUS_READ;
+		break;
+
+	default:
+		ACPI_DEBUG_PRINT((ACPI_DB_WARN, "EC SMBus adapter: "
+				  "Unsupported transaction %d\n", size));
+		return (-1);
+	}
+
+	acpi_ec_smb_write(smbus, ACPI_EC_SMB_ADDR, addr << 1);
+	acpi_ec_smb_write(smbus, ACPI_EC_SMB_PRTCL, protocol);
+
+	acpi_ec_smb_read(smbus, ACPI_EC_SMB_STS, temp + 0);
+
+	if (~temp[0] & ACPI_EC_SMB_STS_DONE) {
+		xudelay(500);
+		acpi_ec_smb_read(smbus, ACPI_EC_SMB_STS, temp + 0);
+	}
+	if (~temp[0] & ACPI_EC_SMB_STS_DONE) {
+		xmsleep(ACPI_EC_SMB_ACCESS_SLEEP2);
+		acpi_ec_smb_read(smbus, ACPI_EC_SMB_STS, temp + 0);
+	}
+	if ((~temp[0] & ACPI_EC_SMB_STS_DONE)
+	    || (temp[0] & ACPI_EC_SMB_STS_STATUS)) {
+		return (-1);
+	}
+
+	if (read_write == I2C_SMBUS_WRITE) {
+		return (0);
+	}
+
+	switch (size) {
+
+	case I2C_SMBUS_BYTE:
+	case I2C_SMBUS_BYTE_DATA:
+		acpi_ec_smb_read(smbus, ACPI_EC_SMB_DATA, &data->byte);
+		break;
+
+	case I2C_SMBUS_WORD_DATA:
+	case I2C_SMBUS_PROC_CALL:
+		acpi_ec_smb_read(smbus, ACPI_EC_SMB_DATA, temp + 0);
+		acpi_ec_smb_read(smbus, ACPI_EC_SMB_DATA + 1, temp + 1);
+		data->word = (temp[1] << 8) | temp[0];
+		break;
+
+	case I2C_SMBUS_BLOCK_DATA:
+	case I2C_SMBUS_BLOCK_PROC_CALL:
+		len = 0;
+		acpi_ec_smb_read(smbus, ACPI_EC_SMB_BCNT, &len);
+		len = min_t(u8, len, 32);
+	case I2C_SMBUS_I2C_BLOCK_DATA:
+		for (i = 0; i < len; i++)
+			acpi_ec_smb_read(smbus, ACPI_EC_SMB_DATA + i,
+					 data->block + i + 1);
+		data->block[0] = len;
+		break;
+	}
+
+	return (0);
+}
+
+static u32 acpi_ec_smb_func(struct i2c_adapter *adapter)
+{
+
+	return (I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE |
+		I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA |
+		I2C_FUNC_SMBUS_BLOCK_DATA |
+		I2C_FUNC_SMBUS_PROC_CALL |
+		I2C_FUNC_SMBUS_BLOCK_PROC_CALL |
+		I2C_FUNC_SMBUS_I2C_BLOCK | I2C_FUNC_SMBUS_HWPEC_CALC);
+}
+
+static struct i2c_algorithm acpi_ec_smbus_algorithm = {
+	.smbus_xfer = acpi_ec_smb_access,
+	.functionality = acpi_ec_smb_func,
+};
+
+static int acpi_ec_hc_add(struct acpi_device *device)
+{
+	int status;
+	unsigned long val;
+	struct acpi_ec_hc *ec_hc;
+	struct acpi_ec_smbus *smbus;
+
+	if (!device) {
+		return -EINVAL;
+	}
+
+	ec_hc = kmalloc(sizeof(struct acpi_ec_hc), GFP_KERNEL);
+	if (!ec_hc) {
+		return -ENOMEM;
+	}
+	memset(ec_hc, 0, sizeof(struct acpi_ec_hc));
+
+	smbus = kmalloc(sizeof(struct acpi_ec_smbus), GFP_KERNEL);
+	if (!smbus) {
+		kfree(ec_hc);
+		return -ENOMEM;
+	}
+	memset(smbus, 0, sizeof(struct acpi_ec_smbus));
+
+	ec_hc->handle = device->handle;
+	strcpy(acpi_device_name(device), ACPI_EC_HC_DEVICE_NAME);
+	strcpy(acpi_device_class(device), ACPI_EC_HC_CLASS);
+	acpi_driver_data(device) = ec_hc;
+
+	status = acpi_evaluate_integer(ec_hc->handle, "_EC", NULL, &val);
+	if (ACPI_FAILURE(status)) {
+		ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Error obtaining _EC\n"));
+		kfree(ec_hc);
+		kfree(smbus);
+		return -EIO;
+	}
+
+	smbus->ec = acpi_driver_data(device->parent);
+	smbus->base = (val & 0xff00ull) >> 8;
+	smbus->alert = val & 0xffull;
+
+	smbus->adapter.owner = THIS_MODULE;
+	smbus->adapter.algo = &acpi_ec_smbus_algorithm;
+	smbus->adapter.algo_data = smbus;
+
+	if (i2c_add_adapter(&smbus->adapter)) {
+		ACPI_DEBUG_PRINT((ACPI_DB_WARN,
+				  "EC SMBus adapter: Failed to register adapter\n"));
+		kfree(smbus);
+		kfree(ec_hc);
+		return -EIO;
+	}
+
+	ec_hc->smbus = smbus;
+
+	printk(KERN_INFO PREFIX "%s [%s]\n",
+	       acpi_device_name(device), acpi_device_bid(device));
+
+	return AE_OK;
+}
+
+static int acpi_ec_hc_remove(struct acpi_device *device, int type)
+{
+	struct acpi_ec_hc *ec_hc;
+
+	if (!device) {
+		return -EINVAL;
+	}
+	ec_hc = acpi_driver_data(device);
+
+	i2c_del_adapter(&ec_hc->smbus->adapter);
+	kfree(ec_hc->smbus);
+	kfree(ec_hc);
+
+	return AE_OK;
+}
+
+static int __init acpi_ec_hc_init(void)
+{
+	int result;
+
+	result = acpi_bus_register_driver(&acpi_ec_hc_driver);
+	if (result < 0) {
+		return -ENODEV;
+	}
+	return 0;
+}
+
+static void __exit acpi_ec_hc_exit(void)
+{
+	acpi_bus_unregister_driver(&acpi_ec_hc_driver);
+}
+
+struct acpi_ec_hc *acpi_get_ec_hc(struct acpi_device *device)
+{
+	return ((struct acpi_ec_hc *)acpi_driver_data(device->parent));
+}
+
+EXPORT_SYMBOL(acpi_get_ec_hc);
+
+module_init(acpi_ec_hc_init);
+module_exit(acpi_ec_hc_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Ducrot Bruno");
+MODULE_DESCRIPTION("ACPI EC SMBus driver");
diff --git a/drivers/acpi/i2c_ec.h b/drivers/acpi/i2c_ec.h
new file mode 100644
index 000000000..7c53fb732
--- /dev/null
+++ b/drivers/acpi/i2c_ec.h
@@ -0,0 +1,23 @@
+/*
+ * SMBus driver for ACPI Embedded Controller ($Revision: 1.2 $)
+ *
+ * Copyright (c) 2002, 2005 Ducrot Bruno
+ *
+ * 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.
+ */
+
+struct acpi_ec_smbus {
+	struct i2c_adapter adapter;
+	union acpi_ec *ec;
+	int base;
+	int alert;
+};
+
+struct acpi_ec_hc {
+	acpi_handle handle;
+	struct acpi_ec_smbus *smbus;
+};
+
+struct acpi_ec_hc *acpi_get_ec_hc(struct acpi_device *device);
diff --git a/drivers/acpi/sbs.c b/drivers/acpi/sbs.c
new file mode 100644
index 000000000..62bef0b3b
--- /dev/null
+++ b/drivers/acpi/sbs.c
@@ -0,0 +1,1769 @@
+/*
+ *  acpi_sbs.c - ACPI Smart Battery System Driver ($Revision: 1.16 $)
+ *
+ *  Copyright (c) 2005 Rich Townsend <rhdt@bartol.udel.edu>
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ *  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/moduleparam.h>
+#include <linux/kernel.h>
+#include <linux/proc_fs.h>
+#include <linux/seq_file.h>
+#include <asm/uaccess.h>
+#include <linux/acpi.h>
+#include <linux/i2c.h>
+#include <linux/delay.h>
+
+#include "i2c_ec.h"
+
+#define	DEF_CAPACITY_UNIT	3
+#define	MAH_CAPACITY_UNIT	1
+#define	MWH_CAPACITY_UNIT	2
+#define	CAPACITY_UNIT		DEF_CAPACITY_UNIT
+
+#define	REQUEST_UPDATE_MODE	1
+#define	QUEUE_UPDATE_MODE	2
+
+#define	DATA_TYPE_COMMON	0
+#define	DATA_TYPE_INFO		1
+#define	DATA_TYPE_STATE		2
+#define	DATA_TYPE_ALARM		3
+#define	DATA_TYPE_AC_STATE	4
+
+extern struct proc_dir_entry *acpi_lock_ac_dir(void);
+extern struct proc_dir_entry *acpi_lock_battery_dir(void);
+extern void acpi_unlock_ac_dir(struct proc_dir_entry *acpi_ac_dir);
+extern void acpi_unlock_battery_dir(struct proc_dir_entry *acpi_battery_dir);
+
+#define ACPI_SBS_COMPONENT		0x00080000
+#define ACPI_SBS_CLASS			"sbs"
+#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"
+#define ACPI_SBS_FILE_ALARM		"alarm"
+#define ACPI_BATTERY_DIR_NAME		"BAT%i"
+#define ACPI_AC_DIR_NAME		"AC0"
+#define ACPI_SBC_SMBUS_ADDR		0x9
+#define ACPI_SBSM_SMBUS_ADDR		0xa
+#define ACPI_SB_SMBUS_ADDR		0xb
+#define ACPI_SBS_AC_NOTIFY_STATUS	0x80
+#define ACPI_SBS_BATTERY_NOTIFY_STATUS	0x80
+#define ACPI_SBS_BATTERY_NOTIFY_INFO	0x81
+
+#define _COMPONENT			ACPI_SBS_COMPONENT
+
+#define	MAX_SBS_BAT			4
+#define	MAX_SMBUS_ERR			1
+
+ACPI_MODULE_NAME("acpi_sbs");
+
+MODULE_AUTHOR("Rich Townsend");
+MODULE_DESCRIPTION("Smart Battery System ACPI interface driver");
+MODULE_LICENSE("GPL");
+
+static struct semaphore sbs_sem;
+
+#define	UPDATE_MODE		QUEUE_UPDATE_MODE
+/* REQUEST_UPDATE_MODE  QUEUE_UPDATE_MODE */
+#define	UPDATE_INFO_MODE	0
+#define	UPDATE_TIME		60
+#define	UPDATE_TIME2		0
+
+static int capacity_mode = CAPACITY_UNIT;
+static int update_mode = UPDATE_MODE;
+static int update_info_mode = UPDATE_INFO_MODE;
+static int update_time = UPDATE_TIME;
+static int update_time2 = UPDATE_TIME2;
+
+module_param(capacity_mode, int, CAPACITY_UNIT);
+module_param(update_mode, int, UPDATE_MODE);
+module_param(update_info_mode, int, UPDATE_INFO_MODE);
+module_param(update_time, int, UPDATE_TIME);
+module_param(update_time2, int, UPDATE_TIME2);
+
+static int acpi_sbs_add(struct acpi_device *device);
+static int acpi_sbs_remove(struct acpi_device *device, int type);
+static void acpi_battery_smbus_err_handler(struct acpi_ec_smbus *smbus);
+static void acpi_sbs_update_queue(void *data);
+
+static struct acpi_driver acpi_sbs_driver = {
+	.name = ACPI_SBS_DRIVER_NAME,
+	.class = ACPI_SBS_CLASS,
+	.ids = ACPI_SBS_HID,
+	.ops = {
+		.add = acpi_sbs_add,
+		.remove = acpi_sbs_remove,
+		},
+};
+
+struct acpi_battery_info {
+	int capacity_mode;
+	s16 full_charge_capacity;
+	s16 design_capacity;
+	s16 design_voltage;
+	int vscale;
+	int ipscale;
+	s16 serial_number;
+	char manufacturer_name[I2C_SMBUS_BLOCK_MAX + 3];
+	char device_name[I2C_SMBUS_BLOCK_MAX + 3];
+	char device_chemistry[I2C_SMBUS_BLOCK_MAX + 3];
+};
+
+struct acpi_battery_state {
+	s16 voltage;
+	s16 amperage;
+	s16 remaining_capacity;
+	s16 average_time_to_empty;
+	s16 average_time_to_full;
+	s16 battery_status;
+};
+
+struct acpi_battery_alarm {
+	s16 remaining_capacity;
+};
+
+struct acpi_battery {
+	int alive;
+	int battery_present;
+	int id;
+	int init_state;
+	struct acpi_sbs *sbs;
+	struct acpi_battery_info info;
+	struct acpi_battery_state state;
+	struct acpi_battery_alarm alarm;
+	struct proc_dir_entry *battery_entry;
+};
+
+struct acpi_sbs {
+	acpi_handle handle;
+	struct acpi_device *device;
+	struct acpi_ec_smbus *smbus;
+	int sbsm_present;
+	int sbsm_batteries_supported;
+	int ac_present;
+	struct proc_dir_entry *ac_entry;
+	struct acpi_battery battery[MAX_SBS_BAT];
+	int update_info_mode;
+	int zombie;
+	int update_time;
+	int update_time2;
+	struct timer_list update_timer;
+};
+
+static void acpi_update_delay(struct acpi_sbs *sbs);
+static int acpi_sbs_update_run(struct acpi_sbs *sbs, int data_type);
+
+/* --------------------------------------------------------------------------
+                               SMBus Communication
+   -------------------------------------------------------------------------- */
+
+static void acpi_battery_smbus_err_handler(struct acpi_ec_smbus *smbus)
+{
+	union i2c_smbus_data data;
+	int result = 0;
+	char *err_str;
+	int err_number;
+
+	data.word = 0;
+
+	result = smbus->adapter.algo->
+	    smbus_xfer(&smbus->adapter,
+		       ACPI_SB_SMBUS_ADDR,
+		       0, I2C_SMBUS_READ, 0x16, I2C_SMBUS_BLOCK_DATA, &data);
+
+	err_number = (data.word & 0x000f);
+
+	switch (data.word & 0x000f) {
+	case 0x0000:
+		err_str = "unexpected bus error";
+		break;
+	case 0x0001:
+		err_str = "busy";
+		break;
+	case 0x0002:
+		err_str = "reserved command";
+		break;
+	case 0x0003:
+		err_str = "unsupported command";
+		break;
+	case 0x0004:
+		err_str = "access denied";
+		break;
+	case 0x0005:
+		err_str = "overflow/underflow";
+		break;
+	case 0x0006:
+		err_str = "bad size";
+		break;
+	case 0x0007:
+		err_str = "unknown error";
+		break;
+	default:
+		err_str = "unrecognized error";
+	}
+	ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+			  "%s: ret %i, err %i\n", err_str, result, err_number));
+}
+
+static int
+acpi_sbs_smbus_read_word(struct acpi_ec_smbus *smbus, int addr, int func,
+			 u16 * word,
+			 void (*err_handler) (struct acpi_ec_smbus * smbus))
+{
+	union i2c_smbus_data data;
+	int result = 0;
+	int i;
+
+	if (err_handler == NULL) {
+		err_handler = acpi_battery_smbus_err_handler;
+	}
+
+	for (i = 0; i < MAX_SMBUS_ERR; i++) {
+		result =
+		    smbus->adapter.algo->smbus_xfer(&smbus->adapter, addr, 0,
+						    I2C_SMBUS_READ, func,
+						    I2C_SMBUS_WORD_DATA, &data);
+		if (result) {
+			ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+					  "try %i: smbus->adapter.algo->smbus_xfer() failed\n",
+					  i));
+			if (err_handler) {
+				err_handler(smbus);
+			}
+		} else {
+			*word = data.word;
+			break;
+		}
+	}
+
+	return result;
+}
+
+static int
+acpi_sbs_smbus_read_str(struct acpi_ec_smbus *smbus, int addr, int func,
+			char *str,
+			void (*err_handler) (struct acpi_ec_smbus * smbus))
+{
+	union i2c_smbus_data data;
+	int result = 0;
+	int i;
+
+	if (err_handler == NULL) {
+		err_handler = acpi_battery_smbus_err_handler;
+	}
+
+	for (i = 0; i < MAX_SMBUS_ERR; i++) {
+		result =
+		    smbus->adapter.algo->smbus_xfer(&smbus->adapter, addr, 0,
+						    I2C_SMBUS_READ, func,
+						    I2C_SMBUS_BLOCK_DATA,
+						    &data);
+		if (result) {
+			ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+					  "try %i: smbus->adapter.algo->smbus_xfer() failed\n",
+					  i));
+			if (err_handler) {
+				err_handler(smbus);
+			}
+		} else {
+			strncpy(str, (const char *)data.block + 1,
+				data.block[0]);
+			str[data.block[0]] = 0;
+			break;
+		}
+	}
+
+	return result;
+}
+
+static int
+acpi_sbs_smbus_write_word(struct acpi_ec_smbus *smbus, int addr, int func,
+			  int word,
+			  void (*err_handler) (struct acpi_ec_smbus * smbus))
+{
+	union i2c_smbus_data data;
+	int result = 0;
+	int i;
+
+	if (err_handler == NULL) {
+		err_handler = acpi_battery_smbus_err_handler;
+	}
+
+	data.word = word;
+
+	for (i = 0; i < MAX_SMBUS_ERR; i++) {
+		result =
+		    smbus->adapter.algo->smbus_xfer(&smbus->adapter, addr, 0,
+						    I2C_SMBUS_WRITE, func,
+						    I2C_SMBUS_WORD_DATA, &data);
+		if (result) {
+			ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+					  "try %i: smbus->adapter.algo"
+					  "->smbus_xfer() failed\n", i));
+			if (err_handler) {
+				err_handler(smbus);
+			}
+		} else {
+			break;
+		}
+	}
+
+	return result;
+}
+
+/* --------------------------------------------------------------------------
+                            Smart Battery System Management
+   -------------------------------------------------------------------------- */
+
+/* Smart Battery */
+
+static int acpi_sbs_generate_event(struct acpi_device *device,
+				   int event, int state, char *bid, char *class)
+{
+	char bid_saved[5];
+	char class_saved[20];
+	int result = 0;
+
+	strcpy(bid_saved, acpi_device_bid(device));
+	strcpy(class_saved, acpi_device_class(device));
+
+	strcpy(acpi_device_bid(device), bid);
+	strcpy(acpi_device_class(device), class);
+
+	result = acpi_bus_generate_event(device, event, state);
+
+	strcpy(acpi_device_bid(device), bid_saved);
+	strcpy(acpi_device_class(device), class_saved);
+
+	return result;
+}
+
+static int acpi_battery_get_present(struct acpi_battery *battery)
+{
+	s16 state;
+	int result = 0;
+	int is_present = 0;
+
+	result = acpi_sbs_smbus_read_word(battery->sbs->smbus,
+					  ACPI_SBSM_SMBUS_ADDR, 0x01,
+					  &state, NULL);
+	if (result) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+				  "acpi_sbs_smbus_read_word() failed"));
+	}
+	if (!result) {
+		is_present = (state & 0x000f) & (1 << battery->id);
+	}
+	battery->battery_present = is_present;
+
+	return result;
+}
+
+static int acpi_battery_is_present(struct acpi_battery *battery)
+{
+	return (battery->battery_present);
+}
+
+static int acpi_ac_is_present(struct acpi_sbs *sbs)
+{
+	return (sbs->ac_present);
+}
+
+static int acpi_battery_select(struct acpi_battery *battery)
+{
+	struct acpi_ec_smbus *smbus = battery->sbs->smbus;
+	int result = 0;
+	s16 state;
+	int foo;
+
+	if (battery->sbs->sbsm_present) {
+
+		/* Take special care not to knobble other nibbles of
+		 * state (aka selector_state), since
+		 * it causes charging to halt on SBSELs */
+
+		result =
+		    acpi_sbs_smbus_read_word(smbus, ACPI_SBSM_SMBUS_ADDR, 0x01,
+					     &state, NULL);
+		if (result) {
+			ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+					  "acpi_sbs_smbus_read_word() failed\n"));
+			goto end;
+		}
+
+		foo = (state & 0x0fff) | (1 << (battery->id + 12));
+		result =
+		    acpi_sbs_smbus_write_word(smbus, ACPI_SBSM_SMBUS_ADDR, 0x01,
+					      foo, NULL);
+		if (result) {
+			ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+					  "acpi_sbs_smbus_write_word() failed\n"));
+			goto end;
+		}
+	}
+
+      end:
+	return result;
+}
+
+static int acpi_sbsm_get_info(struct acpi_sbs *sbs)
+{
+	struct acpi_ec_smbus *smbus = sbs->smbus;
+	int result = 0;
+	s16 battery_system_info;
+
+	result = acpi_sbs_smbus_read_word(smbus, ACPI_SBSM_SMBUS_ADDR, 0x04,
+					  &battery_system_info, NULL);
+	if (result) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+				  "acpi_sbs_smbus_read_word() failed\n"));
+		goto end;
+	}
+
+	sbs->sbsm_batteries_supported = battery_system_info & 0x000f;
+
+      end:
+
+	return result;
+}
+
+static int acpi_battery_get_info(struct acpi_battery *battery)
+{
+	struct acpi_ec_smbus *smbus = battery->sbs->smbus;
+	int result = 0;
+	s16 battery_mode;
+	s16 specification_info;
+
+	result = acpi_sbs_smbus_read_word(smbus, ACPI_SB_SMBUS_ADDR, 0x03,
+					  &battery_mode,
+					  &acpi_battery_smbus_err_handler);
+	if (result) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+				  "acpi_sbs_smbus_read_word() failed\n"));
+		goto end;
+	}
+	battery->info.capacity_mode = (battery_mode & 0x8000) >> 15;
+
+	result = acpi_sbs_smbus_read_word(smbus, ACPI_SB_SMBUS_ADDR, 0x10,
+					  &battery->info.full_charge_capacity,
+					  &acpi_battery_smbus_err_handler);
+	if (result) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+				  "acpi_sbs_smbus_read_word() failed\n"));
+		goto end;
+	}
+
+	result = acpi_sbs_smbus_read_word(smbus, ACPI_SB_SMBUS_ADDR, 0x18,
+					  &battery->info.design_capacity,
+					  &acpi_battery_smbus_err_handler);
+
+	if (result) {
+		goto end;
+	}
+
+	result = acpi_sbs_smbus_read_word(smbus, ACPI_SB_SMBUS_ADDR, 0x19,
+					  &battery->info.design_voltage,
+					  &acpi_battery_smbus_err_handler);
+	if (result) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+				  "acpi_sbs_smbus_read_word() failed\n"));
+		goto end;
+	}
+
+	result = acpi_sbs_smbus_read_word(smbus, ACPI_SB_SMBUS_ADDR, 0x1a,
+					  &specification_info,
+					  &acpi_battery_smbus_err_handler);
+	if (result) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+				  "acpi_sbs_smbus_read_word() failed\n"));
+		goto end;
+	}
+
+	switch ((specification_info & 0x0f00) >> 8) {
+	case 1:
+		battery->info.vscale = 10;
+		break;
+	case 2:
+		battery->info.vscale = 100;
+		break;
+	case 3:
+		battery->info.vscale = 1000;
+		break;
+	default:
+		battery->info.vscale = 1;
+	}
+
+	switch ((specification_info & 0xf000) >> 12) {
+	case 1:
+		battery->info.ipscale = 10;
+		break;
+	case 2:
+		battery->info.ipscale = 100;
+		break;
+	case 3:
+		battery->info.ipscale = 1000;
+		break;
+	default:
+		battery->info.ipscale = 1;
+	}
+
+	result = acpi_sbs_smbus_read_word(smbus, ACPI_SB_SMBUS_ADDR, 0x1c,
+					  &battery->info.serial_number,
+					  &acpi_battery_smbus_err_handler);
+	if (result) {
+		goto end;
+	}
+
+	result = acpi_sbs_smbus_read_str(smbus, ACPI_SB_SMBUS_ADDR, 0x20,
+					 battery->info.manufacturer_name,
+					 &acpi_battery_smbus_err_handler);
+	if (result) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+				  "acpi_sbs_smbus_read_str() failed\n"));
+		goto end;
+	}
+
+	result = acpi_sbs_smbus_read_str(smbus, ACPI_SB_SMBUS_ADDR, 0x21,
+					 battery->info.device_name,
+					 &acpi_battery_smbus_err_handler);
+	if (result) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+				  "acpi_sbs_smbus_read_str() failed\n"));
+		goto end;
+	}
+
+	result = acpi_sbs_smbus_read_str(smbus, ACPI_SB_SMBUS_ADDR, 0x22,
+					 battery->info.device_chemistry,
+					 &acpi_battery_smbus_err_handler);
+	if (result) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+				  "acpi_sbs_smbus_read_str() failed\n"));
+		goto end;
+	}
+
+      end:
+	return result;
+}
+
+static void acpi_update_delay(struct acpi_sbs *sbs)
+{
+	if (sbs->zombie) {
+		return;
+	}
+	if (sbs->update_time2 > 0) {
+		msleep(sbs->update_time2 * 1000);
+	}
+}
+
+static int acpi_battery_get_state(struct acpi_battery *battery)
+{
+	struct acpi_ec_smbus *smbus = battery->sbs->smbus;
+	int result = 0;
+
+	acpi_update_delay(battery->sbs);
+	result = acpi_sbs_smbus_read_word(smbus, ACPI_SB_SMBUS_ADDR, 0x09,
+					  &battery->state.voltage,
+					  &acpi_battery_smbus_err_handler);
+	if (result) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+				  "acpi_sbs_smbus_read_word() failed\n"));
+		goto end;
+	}
+
+	acpi_update_delay(battery->sbs);
+	result = acpi_sbs_smbus_read_word(smbus, ACPI_SB_SMBUS_ADDR, 0x0a,
+					  &battery->state.amperage,
+					  &acpi_battery_smbus_err_handler);
+	if (result) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+				  "acpi_sbs_smbus_read_word() failed\n"));
+		goto end;
+	}
+
+	acpi_update_delay(battery->sbs);
+	result = acpi_sbs_smbus_read_word(smbus, ACPI_SB_SMBUS_ADDR, 0x0f,
+					  &battery->state.remaining_capacity,
+					  &acpi_battery_smbus_err_handler);
+	if (result) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+				  "acpi_sbs_smbus_read_word() failed\n"));
+		goto end;
+	}
+
+	acpi_update_delay(battery->sbs);
+	result = acpi_sbs_smbus_read_word(smbus, ACPI_SB_SMBUS_ADDR, 0x12,
+					  &battery->state.average_time_to_empty,
+					  &acpi_battery_smbus_err_handler);
+	if (result) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+				  "acpi_sbs_smbus_read_word() failed\n"));
+		goto end;
+	}
+
+	acpi_update_delay(battery->sbs);
+	result = acpi_sbs_smbus_read_word(smbus, ACPI_SB_SMBUS_ADDR, 0x13,
+					  &battery->state.average_time_to_full,
+					  &acpi_battery_smbus_err_handler);
+	if (result) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+				  "acpi_sbs_smbus_read_word() failed\n"));
+		goto end;
+	}
+
+	acpi_update_delay(battery->sbs);
+	result = acpi_sbs_smbus_read_word(smbus, ACPI_SB_SMBUS_ADDR, 0x16,
+					  &battery->state.battery_status,
+					  &acpi_battery_smbus_err_handler);
+	if (result) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+				  "acpi_sbs_smbus_read_word() failed\n"));
+		goto end;
+	}
+
+	acpi_update_delay(battery->sbs);
+
+      end:
+	return result;
+}
+
+static int acpi_battery_get_alarm(struct acpi_battery *battery)
+{
+	struct acpi_ec_smbus *smbus = battery->sbs->smbus;
+	int result = 0;
+
+	result = acpi_sbs_smbus_read_word(smbus, ACPI_SB_SMBUS_ADDR, 0x01,
+					  &battery->alarm.remaining_capacity,
+					  &acpi_battery_smbus_err_handler);
+	if (result) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+				  "acpi_sbs_smbus_read_word() failed\n"));
+		goto end;
+	}
+
+	acpi_update_delay(battery->sbs);
+
+      end:
+
+	return result;
+}
+
+static int acpi_battery_set_alarm(struct acpi_battery *battery,
+				  unsigned long alarm)
+{
+	struct acpi_ec_smbus *smbus = battery->sbs->smbus;
+	int result = 0;
+	s16 battery_mode;
+	int foo;
+
+	result = acpi_battery_select(battery);
+	if (result) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+				  "acpi_battery_select() failed\n"));
+		goto end;
+	}
+
+	/* If necessary, enable the alarm */
+
+	if (alarm > 0) {
+		result =
+		    acpi_sbs_smbus_read_word(smbus, ACPI_SB_SMBUS_ADDR, 0x03,
+					     &battery_mode,
+					     &acpi_battery_smbus_err_handler);
+		if (result) {
+			ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+					  "acpi_sbs_smbus_read_word() failed\n"));
+			goto end;
+		}
+
+		result =
+		    acpi_sbs_smbus_write_word(smbus, ACPI_SB_SMBUS_ADDR, 0x01,
+					      battery_mode & 0xbfff,
+					      &acpi_battery_smbus_err_handler);
+		if (result) {
+			ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+					  "acpi_sbs_smbus_write_word() failed\n"));
+			goto end;
+		}
+	}
+
+	foo = alarm / (battery->info.capacity_mode ? 10 : 1);
+	result = acpi_sbs_smbus_write_word(smbus, ACPI_SB_SMBUS_ADDR, 0x01,
+					   foo,
+					   &acpi_battery_smbus_err_handler);
+	if (result) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+				  "acpi_sbs_smbus_write_word() failed\n"));
+		goto end;
+	}
+
+      end:
+
+	return result;
+}
+
+static int acpi_battery_set_mode(struct acpi_battery *battery)
+{
+	int result = 0;
+	s16 battery_mode;
+
+	if (capacity_mode == DEF_CAPACITY_UNIT) {
+		goto end;
+	}
+
+	result = acpi_sbs_smbus_read_word(battery->sbs->smbus,
+					  ACPI_SB_SMBUS_ADDR, 0x03,
+					  &battery_mode, NULL);
+	if (result) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+				  "acpi_sbs_smbus_read_word() failed\n"));
+		goto end;
+	}
+
+	if (capacity_mode == MAH_CAPACITY_UNIT) {
+		battery_mode &= 0x7fff;
+	} else {
+		battery_mode |= 0x8000;
+	}
+	result = acpi_sbs_smbus_write_word(battery->sbs->smbus,
+					   ACPI_SB_SMBUS_ADDR, 0x03,
+					   battery_mode, NULL);
+	if (result) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+				  "acpi_sbs_smbus_write_word() failed\n"));
+		goto end;
+	}
+
+	result = acpi_sbs_smbus_read_word(battery->sbs->smbus,
+					  ACPI_SB_SMBUS_ADDR, 0x03,
+					  &battery_mode, NULL);
+	if (result) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+				  "acpi_sbs_smbus_read_word() failed\n"));
+		goto end;
+	}
+
+      end:
+	return result;
+}
+
+static int acpi_battery_init(struct acpi_battery *battery)
+{
+	int result = 0;
+
+	result = acpi_battery_select(battery);
+	if (result) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+				  "acpi_battery_init() failed\n"));
+		goto end;
+	}
+
+	result = acpi_battery_set_mode(battery);
+	if (result) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+				  "acpi_battery_set_mode() failed\n"));
+		goto end;
+	}
+
+	result = acpi_battery_get_info(battery);
+	if (result) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+				  "acpi_battery_get_info() failed\n"));
+		goto end;
+	}
+
+	result = acpi_battery_get_state(battery);
+	if (result) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+				  "acpi_battery_get_state() failed\n"));
+		goto end;
+	}
+
+	result = acpi_battery_get_alarm(battery);
+	if (result) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+				  "acpi_battery_get_alarm() failed\n"));
+		goto end;
+	}
+
+      end:
+	return result;
+}
+
+static int acpi_ac_get_present(struct acpi_sbs *sbs)
+{
+	struct acpi_ec_smbus *smbus = sbs->smbus;
+	int result = 0;
+	s16 charger_status;
+
+	result = acpi_sbs_smbus_read_word(smbus, ACPI_SBC_SMBUS_ADDR, 0x13,
+					  &charger_status, NULL);
+
+	if (result) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+				  "acpi_sbs_smbus_read_word() failed\n"));
+		goto end;
+	}
+
+	sbs->ac_present = (charger_status & 0x8000) >> 15;
+
+      end:
+
+	return result;
+}
+
+/* --------------------------------------------------------------------------
+                              FS Interface (/proc/acpi)
+   -------------------------------------------------------------------------- */
+
+/* Generic Routines */
+
+static int
+acpi_sbs_generic_add_fs(struct proc_dir_entry **dir,
+			struct proc_dir_entry *parent_dir,
+			char *dir_name,
+			struct file_operations *info_fops,
+			struct file_operations *state_fops,
+			struct file_operations *alarm_fops, void *data)
+{
+	struct proc_dir_entry *entry = NULL;
+
+	if (!*dir) {
+		*dir = proc_mkdir(dir_name, parent_dir);
+		if (!*dir) {
+			ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+					  "proc_mkdir() failed\n"));
+			return -ENODEV;
+		}
+		(*dir)->owner = THIS_MODULE;
+	}
+
+	/* 'info' [R] */
+	if (info_fops) {
+		entry = create_proc_entry(ACPI_SBS_FILE_INFO, S_IRUGO, *dir);
+		if (!entry) {
+			ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+					  "create_proc_entry() failed\n"));
+		} else {
+			entry->proc_fops = info_fops;
+			entry->data = data;
+			entry->owner = THIS_MODULE;
+		}
+	}
+
+	/* 'state' [R] */
+	if (state_fops) {
+		entry = create_proc_entry(ACPI_SBS_FILE_STATE, S_IRUGO, *dir);
+		if (!entry) {
+			ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+					  "create_proc_entry() failed\n"));
+		} else {
+			entry->proc_fops = state_fops;
+			entry->data = data;
+			entry->owner = THIS_MODULE;
+		}
+	}
+
+	/* 'alarm' [R/W] */
+	if (alarm_fops) {
+		entry = create_proc_entry(ACPI_SBS_FILE_ALARM, S_IRUGO, *dir);
+		if (!entry) {
+			ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+					  "create_proc_entry() failed\n"));
+		} else {
+			entry->proc_fops = alarm_fops;
+			entry->data = data;
+			entry->owner = THIS_MODULE;
+		}
+	}
+
+	return 0;
+}
+
+static void
+acpi_sbs_generic_remove_fs(struct proc_dir_entry **dir,
+			   struct proc_dir_entry *parent_dir)
+{
+
+	if (*dir) {
+		remove_proc_entry(ACPI_SBS_FILE_INFO, *dir);
+		remove_proc_entry(ACPI_SBS_FILE_STATE, *dir);
+		remove_proc_entry(ACPI_SBS_FILE_ALARM, *dir);
+		remove_proc_entry((*dir)->name, parent_dir);
+		*dir = NULL;
+	}
+
+}
+
+/* Smart Battery Interface */
+
+static struct proc_dir_entry *acpi_battery_dir = NULL;
+
+static int acpi_battery_read_info(struct seq_file *seq, void *offset)
+{
+	struct acpi_battery *battery = (struct acpi_battery *)seq->private;
+	int cscale;
+	int result = 0;
+
+	if (battery->sbs->zombie) {
+		return -ENODEV;
+	}
+
+	down(&sbs_sem);
+
+	if (update_mode == REQUEST_UPDATE_MODE) {
+		result = acpi_sbs_update_run(battery->sbs, DATA_TYPE_INFO);
+		if (result) {
+			ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+					  "acpi_sbs_update_run() failed\n"));
+		}
+	}
+
+	if (acpi_battery_is_present(battery)) {
+		seq_printf(seq, "present:                 yes\n");
+	} else {
+		seq_printf(seq, "present:                 no\n");
+		goto end;
+	}
+
+	if (battery->info.capacity_mode) {
+		cscale = battery->info.vscale * battery->info.ipscale;
+	} else {
+		cscale = battery->info.ipscale;
+	}
+	seq_printf(seq, "design capacity:         %i%s",
+		   battery->info.design_capacity * cscale,
+		   battery->info.capacity_mode ? "0 mWh\n" : " mAh\n");
+
+	seq_printf(seq, "last full capacity:      %i%s",
+		   battery->info.full_charge_capacity * cscale,
+		   battery->info.capacity_mode ? "0 mWh\n" : " mAh\n");
+
+	seq_printf(seq, "battery technology:      rechargeable\n");
+
+	seq_printf(seq, "design voltage:          %i mV\n",
+		   battery->info.design_voltage * battery->info.vscale);
+
+	seq_printf(seq, "design capacity warning: unknown\n");
+	seq_printf(seq, "design capacity low:     unknown\n");
+	seq_printf(seq, "capacity granularity 1:  unknown\n");
+	seq_printf(seq, "capacity granularity 2:  unknown\n");
+
+	seq_printf(seq, "model number:            %s\n",
+		   battery->info.device_name);
+
+	seq_printf(seq, "serial number:           %i\n",
+		   battery->info.serial_number);
+
+	seq_printf(seq, "battery type:            %s\n",
+		   battery->info.device_chemistry);
+
+	seq_printf(seq, "OEM info:                %s\n",
+		   battery->info.manufacturer_name);
+
+      end:
+
+	up(&sbs_sem);
+
+	return result;
+}
+
+static int acpi_battery_info_open_fs(struct inode *inode, struct file *file)
+{
+	return single_open(file, acpi_battery_read_info, PDE(inode)->data);
+}
+
+static int acpi_battery_read_state(struct seq_file *seq, void *offset)
+{
+	struct acpi_battery *battery = (struct acpi_battery *)seq->private;
+	int result = 0;
+	int cscale;
+	int foo;
+
+	if (battery->sbs->zombie) {
+		return -ENODEV;
+	}
+
+	down(&sbs_sem);
+
+	if (update_mode == REQUEST_UPDATE_MODE) {
+		result = acpi_sbs_update_run(battery->sbs, DATA_TYPE_STATE);
+		if (result) {
+			ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+					  "acpi_sbs_update_run() failed\n"));
+		}
+	}
+
+	if (acpi_battery_is_present(battery)) {
+		seq_printf(seq, "present:                 yes\n");
+	} else {
+		seq_printf(seq, "present:                 no\n");
+		goto end;
+	}
+
+	if (battery->info.capacity_mode) {
+		cscale = battery->info.vscale * battery->info.ipscale;
+	} else {
+		cscale = battery->info.ipscale;
+	}
+
+	if (battery->state.battery_status & 0x0010) {
+		seq_printf(seq, "capacity state:          critical\n");
+	} else {
+		seq_printf(seq, "capacity state:          ok\n");
+	}
+	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");
+	} 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");
+	} else {
+		seq_printf(seq, "charging state:          charged\n");
+		seq_printf(seq, "present rate:            0 %s\n",
+			   battery->info.capacity_mode ? "mW" : "mA");
+	}
+
+	seq_printf(seq, "remaining capacity:      %i%s",
+		   battery->state.remaining_capacity * cscale,
+		   battery->info.capacity_mode ? "0 mWh\n" : " mAh\n");
+
+	seq_printf(seq, "present voltage:         %i mV\n",
+		   battery->state.voltage * battery->info.vscale);
+
+      end:
+
+	up(&sbs_sem);
+
+	return result;
+}
+
+static int acpi_battery_state_open_fs(struct inode *inode, struct file *file)
+{
+	return single_open(file, acpi_battery_read_state, PDE(inode)->data);
+}
+
+static int acpi_battery_read_alarm(struct seq_file *seq, void *offset)
+{
+	struct acpi_battery *battery = (struct acpi_battery *)seq->private;
+	int result = 0;
+	int cscale;
+
+	if (battery->sbs->zombie) {
+		return -ENODEV;
+	}
+
+	down(&sbs_sem);
+
+	if (update_mode == REQUEST_UPDATE_MODE) {
+		result = acpi_sbs_update_run(battery->sbs, DATA_TYPE_ALARM);
+		if (result) {
+			ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+					  "acpi_sbs_update_run() failed\n"));
+		}
+	}
+
+	if (!acpi_battery_is_present(battery)) {
+		seq_printf(seq, "present:                 no\n");
+		goto end;
+	}
+
+	if (battery->info.capacity_mode) {
+		cscale = battery->info.vscale * battery->info.ipscale;
+	} else {
+		cscale = battery->info.ipscale;
+	}
+
+	seq_printf(seq, "alarm:                   ");
+	if (battery->alarm.remaining_capacity) {
+		seq_printf(seq, "%i%s",
+			   battery->alarm.remaining_capacity * cscale,
+			   battery->info.capacity_mode ? "0 mWh\n" : " mAh\n");
+	} else {
+		seq_printf(seq, "disabled\n");
+	}
+
+      end:
+
+	up(&sbs_sem);
+
+	return result;
+}
+
+static ssize_t
+acpi_battery_write_alarm(struct file *file, const char __user * buffer,
+			 size_t count, loff_t * ppos)
+{
+	struct seq_file *seq = (struct seq_file *)file->private_data;
+	struct acpi_battery *battery = (struct acpi_battery *)seq->private;
+	char alarm_string[12] = { '\0' };
+	int result, old_alarm, new_alarm;
+
+	if (battery->sbs->zombie) {
+		return -ENODEV;
+	}
+
+	down(&sbs_sem);
+
+	if (!acpi_battery_is_present(battery)) {
+		result = -ENODEV;
+		goto end;
+	}
+
+	if (count > sizeof(alarm_string) - 1) {
+		result = -EINVAL;
+		goto end;
+	}
+
+	if (copy_from_user(alarm_string, buffer, count)) {
+		result = -EFAULT;
+		goto end;
+	}
+
+	alarm_string[count] = 0;
+
+	old_alarm = battery->alarm.remaining_capacity;
+	new_alarm = simple_strtoul(alarm_string, NULL, 0);
+
+	result = acpi_battery_set_alarm(battery, new_alarm);
+	if (result) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+				  "acpi_battery_set_alarm() failed\n"));
+		(void)acpi_battery_set_alarm(battery, old_alarm);
+		goto end;
+	}
+	result = acpi_battery_get_alarm(battery);
+	if (result) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+				  "acpi_battery_get_alarm() failed\n"));
+		(void)acpi_battery_set_alarm(battery, old_alarm);
+		goto end;
+	}
+
+      end:
+	up(&sbs_sem);
+
+	if (result) {
+		return result;
+	} else {
+		return count;
+	}
+}
+
+static int acpi_battery_alarm_open_fs(struct inode *inode, struct file *file)
+{
+	return single_open(file, acpi_battery_read_alarm, PDE(inode)->data);
+}
+
+static struct file_operations acpi_battery_info_fops = {
+	.open = acpi_battery_info_open_fs,
+	.read = seq_read,
+	.llseek = seq_lseek,
+	.release = single_release,
+	.owner = THIS_MODULE,
+};
+
+static struct file_operations acpi_battery_state_fops = {
+	.open = acpi_battery_state_open_fs,
+	.read = seq_read,
+	.llseek = seq_lseek,
+	.release = single_release,
+	.owner = THIS_MODULE,
+};
+
+static struct file_operations acpi_battery_alarm_fops = {
+	.open = acpi_battery_alarm_open_fs,
+	.read = seq_read,
+	.write = acpi_battery_write_alarm,
+	.llseek = seq_lseek,
+	.release = single_release,
+	.owner = THIS_MODULE,
+};
+
+/* Legacy AC Adapter Interface */
+
+static struct proc_dir_entry *acpi_ac_dir = NULL;
+
+static int acpi_ac_read_state(struct seq_file *seq, void *offset)
+{
+	struct acpi_sbs *sbs = (struct acpi_sbs *)seq->private;
+	int result;
+
+	if (sbs->zombie) {
+		return -ENODEV;
+	}
+
+	down(&sbs_sem);
+
+	if (update_mode == REQUEST_UPDATE_MODE) {
+		result = acpi_sbs_update_run(sbs, DATA_TYPE_AC_STATE);
+		if (result) {
+			ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+					  "acpi_sbs_update_run() failed\n"));
+		}
+	}
+
+	seq_printf(seq, "state:                   %s\n",
+		   sbs->ac_present ? "on-line" : "off-line");
+
+	up(&sbs_sem);
+
+	return 0;
+}
+
+static int acpi_ac_state_open_fs(struct inode *inode, struct file *file)
+{
+	return single_open(file, acpi_ac_read_state, PDE(inode)->data);
+}
+
+static struct file_operations acpi_ac_state_fops = {
+	.open = acpi_ac_state_open_fs,
+	.read = seq_read,
+	.llseek = seq_lseek,
+	.release = single_release,
+	.owner = THIS_MODULE,
+};
+
+/* --------------------------------------------------------------------------
+                                 Driver Interface
+   -------------------------------------------------------------------------- */
+
+/* Smart Battery */
+
+static int acpi_battery_add(struct acpi_sbs *sbs, int id)
+{
+	int is_present;
+	int result;
+	char dir_name[32];
+	struct acpi_battery *battery;
+
+	battery = &sbs->battery[id];
+
+	battery->alive = 0;
+
+	battery->init_state = 0;
+	battery->id = id;
+	battery->sbs = sbs;
+
+	result = acpi_battery_select(battery);
+	if (result) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+				  "acpi_battery_select() failed\n"));
+		goto end;
+	}
+
+	result = acpi_battery_get_present(battery);
+	if (result) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+				  "acpi_battery_get_present() failed\n"));
+		goto end;
+	}
+
+	is_present = acpi_battery_is_present(battery);
+
+	if (is_present) {
+		result = acpi_battery_init(battery);
+		if (result) {
+			ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+					  "acpi_battery_init() failed\n"));
+			goto end;
+		}
+		battery->init_state = 1;
+	}
+
+	(void)sprintf(dir_name, ACPI_BATTERY_DIR_NAME, id);
+
+	result = acpi_sbs_generic_add_fs(&battery->battery_entry,
+					 acpi_battery_dir,
+					 dir_name,
+					 &acpi_battery_info_fops,
+					 &acpi_battery_state_fops,
+					 &acpi_battery_alarm_fops, battery);
+	if (result) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+				  "acpi_sbs_generic_add_fs() failed\n"));
+		goto end;
+	}
+	battery->alive = 1;
+
+      end:
+	return result;
+}
+
+static void acpi_battery_remove(struct acpi_sbs *sbs, int id)
+{
+
+	if (sbs->battery[id].battery_entry) {
+		acpi_sbs_generic_remove_fs(&(sbs->battery[id].battery_entry),
+					   acpi_battery_dir);
+	}
+}
+
+static int acpi_ac_add(struct acpi_sbs *sbs)
+{
+	int result;
+
+	result = acpi_ac_get_present(sbs);
+	if (result) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+				  "acpi_ac_get_present() failed\n"));
+		goto end;
+	}
+
+	result = acpi_sbs_generic_add_fs(&sbs->ac_entry,
+					 acpi_ac_dir,
+					 ACPI_AC_DIR_NAME,
+					 NULL, &acpi_ac_state_fops, NULL, sbs);
+	if (result) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+				  "acpi_sbs_generic_add_fs() failed\n"));
+		goto end;
+	}
+
+      end:
+
+	return result;
+}
+
+static void acpi_ac_remove(struct acpi_sbs *sbs)
+{
+
+	if (sbs->ac_entry) {
+		acpi_sbs_generic_remove_fs(&sbs->ac_entry, acpi_ac_dir);
+	}
+}
+
+static void acpi_sbs_update_queue_run(unsigned long data)
+{
+	acpi_os_execute(OSL_GPE_HANDLER, acpi_sbs_update_queue, (void *)data);
+}
+
+static int acpi_sbs_update_run(struct acpi_sbs *sbs, int data_type)
+{
+	struct acpi_battery *battery;
+	int result = 0;
+	int old_ac_present;
+	int old_battery_present;
+	int new_ac_present;
+	int new_battery_present;
+	int id;
+	char dir_name[32];
+	int do_battery_init, do_ac_init;
+	s16 old_remaining_capacity;
+
+	if (sbs->zombie) {
+		goto end;
+	}
+
+	old_ac_present = acpi_ac_is_present(sbs);
+
+	result = acpi_ac_get_present(sbs);
+	if (result) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+				  "acpi_ac_get_present() failed\n"));
+	}
+
+	new_ac_present = acpi_ac_is_present(sbs);
+
+	do_ac_init = (old_ac_present != new_ac_present);
+
+	if (data_type == DATA_TYPE_AC_STATE) {
+		goto end;
+	}
+
+	for (id = 0; id < MAX_SBS_BAT; id++) {
+		battery = &sbs->battery[id];
+		if (battery->alive == 0) {
+			continue;
+		}
+
+		old_remaining_capacity = battery->state.remaining_capacity;
+
+		old_battery_present = acpi_battery_is_present(battery);
+
+		result = acpi_battery_select(battery);
+		if (result) {
+			ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+					  "acpi_battery_select() failed\n"));
+		}
+		if (sbs->zombie) {
+			goto end;
+		}
+
+		result = acpi_battery_get_present(battery);
+		if (result) {
+			ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+					  "acpi_battery_get_present() failed\n"));
+		}
+		if (sbs->zombie) {
+			goto end;
+		}
+
+		new_battery_present = acpi_battery_is_present(battery);
+
+		do_battery_init = ((old_battery_present != new_battery_present)
+				   && new_battery_present);
+
+		if (sbs->zombie) {
+			goto end;
+		}
+		if (do_ac_init || do_battery_init ||
+		    update_info_mode || sbs->update_info_mode) {
+			if (sbs->update_info_mode) {
+				sbs->update_info_mode = 0;
+			} else {
+				sbs->update_info_mode = 1;
+			}
+			result = acpi_battery_init(battery);
+			if (result) {
+				ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+						  "acpi_battery_init() "
+						  "failed\n"));
+			}
+		}
+		if (data_type == DATA_TYPE_INFO) {
+			continue;
+		}
+
+		if (sbs->zombie) {
+			goto end;
+		}
+		if (new_battery_present) {
+			result = acpi_battery_get_alarm(battery);
+			if (result) {
+				ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+						  "acpi_battery_get_alarm() "
+						  "failed\n"));
+			}
+			if (data_type == DATA_TYPE_ALARM) {
+				continue;
+			}
+
+			result = acpi_battery_get_state(battery);
+			if (result) {
+				ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+						  "acpi_battery_get_state() "
+						  "failed\n"));
+			}
+		}
+		if (sbs->zombie) {
+			goto end;
+		}
+		if (data_type != DATA_TYPE_COMMON) {
+			continue;
+		}
+
+		if (old_battery_present != new_battery_present) {
+			(void)sprintf(dir_name, ACPI_BATTERY_DIR_NAME, id);
+			result = acpi_sbs_generate_event(sbs->device,
+							 ACPI_SBS_BATTERY_NOTIFY_STATUS,
+							 new_battery_present,
+							 dir_name,
+							 ACPI_BATTERY_CLASS);
+			if (result) {
+				ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+						  "acpi_sbs_generate_event() "
+						  "failed\n"));
+			}
+		}
+		if (old_remaining_capacity != battery->state.remaining_capacity) {
+			(void)sprintf(dir_name, ACPI_BATTERY_DIR_NAME, id);
+			result = acpi_sbs_generate_event(sbs->device,
+							 ACPI_SBS_BATTERY_NOTIFY_STATUS,
+							 new_battery_present,
+							 dir_name,
+							 ACPI_BATTERY_CLASS);
+			if (result) {
+				ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+						  "acpi_sbs_generate_event() failed\n"));
+			}
+		}
+
+	}
+	if (sbs->zombie) {
+		goto end;
+	}
+	if (data_type != DATA_TYPE_COMMON) {
+		goto end;
+	}
+
+	if (old_ac_present != new_ac_present) {
+		result = acpi_sbs_generate_event(sbs->device,
+						 ACPI_SBS_AC_NOTIFY_STATUS,
+						 new_ac_present,
+						 ACPI_AC_DIR_NAME,
+						 ACPI_AC_CLASS);
+		if (result) {
+			ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+					  "acpi_sbs_generate_event() failed\n"));
+		}
+	}
+
+      end:
+	return result;
+}
+
+static void acpi_sbs_update_queue(void *data)
+{
+	struct acpi_sbs *sbs = data;
+	unsigned long delay = -1;
+	int result;
+
+	if (sbs->zombie) {
+		goto end;
+	}
+
+	result = acpi_sbs_update_run(sbs, DATA_TYPE_COMMON);
+	if (result) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+				  "acpi_sbs_update_run() failed\n"));
+	}
+
+	if (sbs->zombie) {
+		goto end;
+	}
+
+	if (update_mode == REQUEST_UPDATE_MODE) {
+		goto end;
+	}
+
+	delay = jiffies + HZ * update_time;
+	sbs->update_timer.data = (unsigned long)data;
+	sbs->update_timer.function = acpi_sbs_update_queue_run;
+	sbs->update_timer.expires = delay;
+	add_timer(&sbs->update_timer);
+      end:
+	;
+}
+
+static int acpi_sbs_add(struct acpi_device *device)
+{
+	struct acpi_sbs *sbs = NULL;
+	struct acpi_ec_hc *ec_hc = NULL;
+	int result, remove_result = 0;
+	unsigned long sbs_obj;
+	int id, cnt;
+	acpi_status status = AE_OK;
+
+	sbs = kmalloc(sizeof(struct acpi_sbs), GFP_KERNEL);
+	if (!sbs) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "kmalloc() failed\n"));
+		return -ENOMEM;
+	}
+	memset(sbs, 0, sizeof(struct acpi_sbs));
+
+	cnt = 0;
+	while (cnt < 10) {
+		cnt++;
+		ec_hc = acpi_get_ec_hc(device);
+		if (ec_hc) {
+			break;
+		}
+		msleep(1000);
+	}
+
+	if (!ec_hc) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+				  "acpi_get_ec_hc() failed: "
+				  "NO driver found for EC HC SMBus\n"));
+		result = -ENODEV;
+		goto end;
+	}
+
+	sbs->device = device;
+	sbs->smbus = ec_hc->smbus;
+
+	strcpy(acpi_device_name(device), ACPI_SBS_DEVICE_NAME);
+	strcpy(acpi_device_class(device), ACPI_SBS_CLASS);
+	acpi_driver_data(device) = sbs;
+
+	sbs->update_time = 0;
+	sbs->update_time2 = 0;
+
+	result = acpi_ac_add(sbs);
+	if (result) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "acpi_ac_add() failed\n"));
+		goto end;
+	}
+	result = acpi_evaluate_integer(device->handle, "_SBS", NULL, &sbs_obj);
+	if (ACPI_FAILURE(result)) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+				  "acpi_evaluate_integer() failed\n"));
+		result = -EIO;
+		goto end;
+	}
+
+	if (sbs_obj > 0) {
+		result = acpi_sbsm_get_info(sbs);
+		if (result) {
+			ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+					  "acpi_sbsm_get_info() failed\n"));
+			goto end;
+		}
+		sbs->sbsm_present = 1;
+	}
+	if (sbs->sbsm_present == 0) {
+		result = acpi_battery_add(sbs, 0);
+		if (result) {
+			ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+					  "acpi_battery_add() failed\n"));
+			goto end;
+		}
+	} else {
+		for (id = 0; id < MAX_SBS_BAT; id++) {
+			if ((sbs->sbsm_batteries_supported & (1 << id))) {
+				result = acpi_battery_add(sbs, id);
+				if (result) {
+					ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+							  "acpi_battery_add() "
+							  "failed\n"));
+					goto end;
+				}
+			}
+		}
+	}
+
+	sbs->handle = device->handle;
+
+	init_timer(&sbs->update_timer);
+	if (update_mode == QUEUE_UPDATE_MODE) {
+		status = acpi_os_execute(OSL_GPE_HANDLER,
+					 acpi_sbs_update_queue, (void *)sbs);
+		if (status != AE_OK) {
+			ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+					  "acpi_os_execute() failed\n"));
+		}
+	}
+	sbs->update_time = update_time;
+	sbs->update_time2 = update_time2;
+
+	printk(KERN_INFO PREFIX "%s [%s]\n",
+	       acpi_device_name(device), acpi_device_bid(device));
+
+      end:
+	if (result) {
+		remove_result = acpi_sbs_remove(device, 0);
+		if (remove_result) {
+			ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+					  "acpi_sbs_remove() failed\n"));
+		}
+	}
+
+	return result;
+}
+
+int acpi_sbs_remove(struct acpi_device *device, int type)
+{
+	struct acpi_sbs *sbs = (struct acpi_sbs *)acpi_driver_data(device);
+	int id;
+
+	if (!device || !sbs) {
+		return -EINVAL;
+	}
+
+	sbs->zombie = 1;
+	sbs->update_time = 0;
+	sbs->update_time2 = 0;
+	del_timer_sync(&sbs->update_timer);
+	acpi_os_wait_events_complete(NULL);
+	del_timer_sync(&sbs->update_timer);
+
+	for (id = 0; id < MAX_SBS_BAT; id++) {
+		acpi_battery_remove(sbs, id);
+	}
+
+	acpi_ac_remove(sbs);
+
+	kfree(sbs);
+
+	return 0;
+}
+
+static int __init acpi_sbs_init(void)
+{
+	int result = 0;
+
+	if (acpi_disabled)
+		return -ENODEV;
+
+	init_MUTEX(&sbs_sem);
+
+	if (capacity_mode != DEF_CAPACITY_UNIT
+	    && capacity_mode != MAH_CAPACITY_UNIT
+	    && capacity_mode != MWH_CAPACITY_UNIT) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "acpi_sbs_init: "
+				  "invalid capacity_mode = %d\n",
+				  capacity_mode));
+		return -EINVAL;
+	}
+
+	acpi_ac_dir = acpi_lock_ac_dir();
+	if (!acpi_ac_dir) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+				  "acpi_lock_ac_dir() failed\n"));
+		return -ENODEV;
+	}
+
+	acpi_battery_dir = acpi_lock_battery_dir();
+	if (!acpi_battery_dir) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+				  "acpi_lock_battery_dir() failed\n"));
+		return -ENODEV;
+	}
+
+	result = acpi_bus_register_driver(&acpi_sbs_driver);
+	if (result < 0) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+				  "acpi_bus_register_driver() failed\n"));
+		return -ENODEV;
+	}
+
+	return 0;
+}
+
+static void __exit acpi_sbs_exit(void)
+{
+
+	acpi_bus_unregister_driver(&acpi_sbs_driver);
+
+	acpi_unlock_ac_dir(acpi_ac_dir);
+	acpi_ac_dir = NULL;
+	acpi_unlock_battery_dir(acpi_battery_dir);
+	acpi_battery_dir = NULL;
+
+	return;
+}
+
+module_init(acpi_sbs_init);
+module_exit(acpi_sbs_exit);
diff --git a/drivers/base/hypervisor.c b/drivers/base/hypervisor.c
new file mode 100644
index 000000000..0c85e9d6a
--- /dev/null
+++ b/drivers/base/hypervisor.c
@@ -0,0 +1,19 @@
+/*
+ * hypervisor.c - /sys/hypervisor subsystem.
+ *
+ * This file is released under the GPLv2
+ *
+ */
+
+#include <linux/kobject.h>
+#include <linux/device.h>
+
+#include "base.h"
+
+decl_subsys(hypervisor, NULL, NULL);
+EXPORT_SYMBOL_GPL(hypervisor_subsys);
+
+int __init hypervisor_init(void)
+{
+	return subsystem_register(&hypervisor_subsys);
+}
diff --git a/drivers/base/isa.c b/drivers/base/isa.c
new file mode 100644
index 000000000..d2222397a
--- /dev/null
+++ b/drivers/base/isa.c
@@ -0,0 +1,180 @@
+/*
+ * ISA bus.
+ */
+
+#include <linux/device.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/isa.h>
+
+static struct device isa_bus = {
+	.bus_id		= "isa"
+};
+
+struct isa_dev {
+	struct device dev;
+	struct device *next;
+	unsigned int id;
+};
+
+#define to_isa_dev(x) container_of((x), struct isa_dev, dev)
+
+static int isa_bus_match(struct device *dev, struct device_driver *driver)
+{
+	struct isa_driver *isa_driver = to_isa_driver(driver);
+
+	if (dev->platform_data == isa_driver) {
+		if (!isa_driver->match ||
+			isa_driver->match(dev, to_isa_dev(dev)->id))
+			return 1;
+		dev->platform_data = NULL;
+	}
+	return 0;
+}
+
+static int isa_bus_probe(struct device *dev)
+{
+	struct isa_driver *isa_driver = dev->platform_data;
+
+	if (isa_driver->probe)
+		return isa_driver->probe(dev, to_isa_dev(dev)->id);
+
+	return 0;
+}
+
+static int isa_bus_remove(struct device *dev)
+{
+	struct isa_driver *isa_driver = dev->platform_data;
+
+	if (isa_driver->remove)
+		return isa_driver->remove(dev, to_isa_dev(dev)->id);
+
+	return 0;
+}
+
+static void isa_bus_shutdown(struct device *dev)
+{
+	struct isa_driver *isa_driver = dev->platform_data;
+
+	if (isa_driver->shutdown)
+		isa_driver->shutdown(dev, to_isa_dev(dev)->id);
+}
+
+static int isa_bus_suspend(struct device *dev, pm_message_t state)
+{
+	struct isa_driver *isa_driver = dev->platform_data;
+
+	if (isa_driver->suspend)
+		return isa_driver->suspend(dev, to_isa_dev(dev)->id, state);
+
+	return 0;
+}
+
+static int isa_bus_resume(struct device *dev)
+{
+	struct isa_driver *isa_driver = dev->platform_data;
+
+	if (isa_driver->resume)
+		return isa_driver->resume(dev, to_isa_dev(dev)->id);
+
+	return 0;
+}
+
+static struct bus_type isa_bus_type = {
+	.name		= "isa",
+	.match		= isa_bus_match,
+	.probe		= isa_bus_probe,
+	.remove		= isa_bus_remove,
+	.shutdown	= isa_bus_shutdown,
+	.suspend	= isa_bus_suspend,
+	.resume		= isa_bus_resume
+};
+
+static void isa_dev_release(struct device *dev)
+{
+	kfree(to_isa_dev(dev));
+}
+
+void isa_unregister_driver(struct isa_driver *isa_driver)
+{
+	struct device *dev = isa_driver->devices;
+
+	while (dev) {
+		struct device *tmp = to_isa_dev(dev)->next;
+		device_unregister(dev);
+		dev = tmp;
+	}
+	driver_unregister(&isa_driver->driver);
+}
+EXPORT_SYMBOL_GPL(isa_unregister_driver);
+
+int isa_register_driver(struct isa_driver *isa_driver, unsigned int ndev)
+{
+	int error;
+	unsigned int id;
+
+	isa_driver->driver.bus	= &isa_bus_type;
+	isa_driver->devices	= NULL;
+
+	error = driver_register(&isa_driver->driver);
+	if (error)
+		return error;
+
+	for (id = 0; id < ndev; id++) {
+		struct isa_dev *isa_dev;
+
+		isa_dev = kzalloc(sizeof *isa_dev, GFP_KERNEL);
+		if (!isa_dev) {
+			error = -ENOMEM;
+			break;
+		}
+
+		isa_dev->dev.parent	= &isa_bus;
+		isa_dev->dev.bus	= &isa_bus_type;
+
+		snprintf(isa_dev->dev.bus_id, BUS_ID_SIZE, "%s.%u",
+				isa_driver->driver.name, id);
+
+		isa_dev->dev.platform_data	= isa_driver;
+		isa_dev->dev.release		= isa_dev_release;
+		isa_dev->id			= id;
+
+		error = device_register(&isa_dev->dev);
+		if (error) {
+			put_device(&isa_dev->dev);
+			break;
+		}
+
+		if (isa_dev->dev.platform_data) {
+			isa_dev->next = isa_driver->devices;
+			isa_driver->devices = &isa_dev->dev;
+		} else
+			device_unregister(&isa_dev->dev);
+	}
+
+	if (!error && !isa_driver->devices)
+		error = -ENODEV;
+
+	if (error)
+		isa_unregister_driver(isa_driver);
+
+	return error;
+}
+EXPORT_SYMBOL_GPL(isa_register_driver);
+
+static int __init isa_bus_init(void)
+{
+	int error;
+
+	error = bus_register(&isa_bus_type);
+	if (!error) {
+		error = device_register(&isa_bus);
+		if (error)
+			bus_unregister(&isa_bus_type);
+	}
+	return error;
+}
+
+device_initcall(isa_bus_init);
diff --git a/drivers/base/power/trace.c b/drivers/base/power/trace.c
new file mode 100644
index 000000000..a9ab30fef
--- /dev/null
+++ b/drivers/base/power/trace.c
@@ -0,0 +1,228 @@
+/*
+ * drivers/base/power/trace.c
+ *
+ * Copyright (C) 2006 Linus Torvalds
+ *
+ * Trace facility for suspend/resume problems, when none of the
+ * devices may be working.
+ */
+
+#include <linux/resume-trace.h>
+#include <linux/rtc.h>
+
+#include <asm/rtc.h>
+
+#include "power.h"
+
+/*
+ * Horrid, horrid, horrid.
+ *
+ * It turns out that the _only_ piece of hardware that actually
+ * keeps its value across a hard boot (and, more importantly, the
+ * POST init sequence) is literally the realtime clock.
+ *
+ * Never mind that an RTC chip has 114 bytes (and often a whole
+ * other bank of an additional 128 bytes) of nice SRAM that is
+ * _designed_ to keep data - the POST will clear it. So we literally
+ * can just use the few bytes of actual time data, which means that
+ * we're really limited.
+ *
+ * It means, for example, that we can't use the seconds at all
+ * (since the time between the hang and the boot might be more
+ * than a minute), and we'd better not depend on the low bits of
+ * the minutes either.
+ *
+ * There are the wday fields etc, but I wouldn't guarantee those
+ * are dependable either. And if the date isn't valid, either the
+ * hw or POST will do strange things.
+ *
+ * So we're left with:
+ *  - year: 0-99
+ *  - month: 0-11
+ *  - day-of-month: 1-28
+ *  - hour: 0-23
+ *  - min: (0-30)*2
+ *
+ * Giving us a total range of 0-16128000 (0xf61800), ie less
+ * than 24 bits of actual data we can save across reboots.
+ *
+ * And if your box can't boot in less than three minutes,
+ * you're screwed.
+ *
+ * Now, almost 24 bits of data is pitifully small, so we need
+ * to be pretty dense if we want to use it for anything nice.
+ * What we do is that instead of saving off nice readable info,
+ * we save off _hashes_ of information that we can hopefully
+ * regenerate after the reboot.
+ *
+ * In particular, this means that we might be unlucky, and hit
+ * a case where we have a hash collision, and we end up not
+ * being able to tell for certain exactly which case happened.
+ * But that's hopefully unlikely.
+ *
+ * What we do is to take the bits we can fit, and split them
+ * into three parts (16*997*1009 = 16095568), and use the values
+ * for:
+ *  - 0-15: user-settable
+ *  - 0-996: file + line number
+ *  - 0-1008: device
+ */
+#define USERHASH (16)
+#define FILEHASH (997)
+#define DEVHASH (1009)
+
+#define DEVSEED (7919)
+
+static unsigned int dev_hash_value;
+
+static int set_magic_time(unsigned int user, unsigned int file, unsigned int device)
+{
+	unsigned int n = user + USERHASH*(file + FILEHASH*device);
+
+	// June 7th, 2006
+	static struct rtc_time time = {
+		.tm_sec = 0,
+		.tm_min = 0,
+		.tm_hour = 0,
+		.tm_mday = 7,
+		.tm_mon = 5,	// June - counting from zero
+		.tm_year = 106,
+		.tm_wday = 3,
+		.tm_yday = 160,
+		.tm_isdst = 1
+	};
+
+	time.tm_year = (n % 100);
+	n /= 100;
+	time.tm_mon = (n % 12);
+	n /= 12;
+	time.tm_mday = (n % 28) + 1;
+	n /= 28;
+	time.tm_hour = (n % 24);
+	n /= 24;
+	time.tm_min = (n % 20) * 3;
+	n /= 20;
+	set_rtc_time(&time);
+	return n ? -1 : 0;
+}
+
+static unsigned int read_magic_time(void)
+{
+	struct rtc_time time;
+	unsigned int val;
+
+	get_rtc_time(&time);
+	printk("Time: %2d:%02d:%02d  Date: %02d/%02d/%02d\n",
+		time.tm_hour, time.tm_min, time.tm_sec,
+		time.tm_mon, time.tm_mday, time.tm_year);
+	val = time.tm_year;				/* 100 years */
+	if (val > 100)
+		val -= 100;
+	val += time.tm_mon * 100;			/* 12 months */
+	val += (time.tm_mday-1) * 100 * 12;		/* 28 month-days */
+	val += time.tm_hour * 100 * 12 * 28;		/* 24 hours */
+	val += (time.tm_min / 3) * 100 * 12 * 28 * 24;	/* 20 3-minute intervals */
+	return val;
+}
+
+/*
+ * This is just the sdbm hash function with a user-supplied
+ * seed and final size parameter.
+ */
+static unsigned int hash_string(unsigned int seed, const char *data, unsigned int mod)
+{
+	unsigned char c;
+	while ((c = *data++) != 0) {
+		seed = (seed << 16) + (seed << 6) - seed + c;
+	}
+	return seed % mod;
+}
+
+void set_trace_device(struct device *dev)
+{
+	dev_hash_value = hash_string(DEVSEED, dev->bus_id, DEVHASH);
+}
+
+/*
+ * We could just take the "tracedata" index into the .tracedata
+ * section instead. Generating a hash of the data gives us a
+ * chance to work across kernel versions, and perhaps more
+ * importantly it also gives us valid/invalid check (ie we will
+ * likely not give totally bogus reports - if the hash matches,
+ * it's not any guarantee, but it's a high _likelihood_ that
+ * the match is valid).
+ */
+void generate_resume_trace(void *tracedata, unsigned int user)
+{
+	unsigned short lineno = *(unsigned short *)tracedata;
+	const char *file = *(const char **)(tracedata + 2);
+	unsigned int user_hash_value, file_hash_value;
+
+	user_hash_value = user % USERHASH;
+	file_hash_value = hash_string(lineno, file, FILEHASH);
+	set_magic_time(user_hash_value, file_hash_value, dev_hash_value);
+}
+
+extern char __tracedata_start, __tracedata_end;
+static int show_file_hash(unsigned int value)
+{
+	int match;
+	char *tracedata;
+
+	match = 0;
+	for (tracedata = &__tracedata_start ; tracedata < &__tracedata_end ; tracedata += 6) {
+		unsigned short lineno = *(unsigned short *)tracedata;
+		const char *file = *(const char **)(tracedata + 2);
+		unsigned int hash = hash_string(lineno, file, FILEHASH);
+		if (hash != value)
+			continue;
+		printk("  hash matches %s:%u\n", file, lineno);
+		match++;
+	}
+	return match;
+}
+
+static int show_dev_hash(unsigned int value)
+{
+	int match = 0;
+	struct list_head * entry = dpm_active.prev;
+
+	while (entry != &dpm_active) {
+		struct device * dev = to_device(entry);
+		unsigned int hash = hash_string(DEVSEED, dev->bus_id, DEVHASH);
+		if (hash == value) {
+			printk("  hash matches device %s\n", dev->bus_id);
+			match++;
+		}
+		entry = entry->prev;
+	}
+	return match;
+}
+
+static unsigned int hash_value_early_read;
+
+static int early_resume_init(void)
+{
+	hash_value_early_read = read_magic_time();
+	return 0;
+}
+
+static int late_resume_init(void)
+{
+	unsigned int val = hash_value_early_read;
+	unsigned int user, file, dev;
+
+	user = val % USERHASH;
+	val = val / USERHASH;
+	file = val % FILEHASH;
+	val = val / FILEHASH;
+	dev = val /* % DEVHASH */;
+
+	printk("  Magic number: %d:%d:%d\n", user, file, dev);
+	show_file_hash(file);
+	show_dev_hash(dev);
+	return 0;
+}
+
+core_initcall(early_resume_init);
+late_initcall(late_resume_init);
diff --git a/drivers/char/hw_random/Kconfig b/drivers/char/hw_random/Kconfig
new file mode 100644
index 000000000..9f7635f75
--- /dev/null
+++ b/drivers/char/hw_random/Kconfig
@@ -0,0 +1,90 @@
+#
+# Hardware Random Number Generator (RNG) configuration
+#
+
+config HW_RANDOM
+	bool "Hardware Random Number Generator Core support"
+	default y
+	---help---
+	  Hardware Random Number Generator Core infrastructure.
+
+	  If unsure, say Y.
+
+config HW_RANDOM_INTEL
+	tristate "Intel HW Random Number Generator support"
+	depends on HW_RANDOM && (X86 || IA64) && PCI
+	default y
+	---help---
+	  This driver provides kernel-side support for the Random Number
+	  Generator hardware found on Intel i8xx-based motherboards.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called intel-rng.
+
+	  If unsure, say Y.
+
+config HW_RANDOM_AMD
+	tristate "AMD HW Random Number Generator support"
+	depends on HW_RANDOM && X86 && PCI
+	default y
+	---help---
+	  This driver provides kernel-side support for the Random Number
+	  Generator hardware found on AMD 76x-based motherboards.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called amd-rng.
+
+	  If unsure, say Y.
+
+config HW_RANDOM_GEODE
+	tristate "AMD Geode HW Random Number Generator support"
+	depends on HW_RANDOM && X86 && PCI
+	default y
+	---help---
+	  This driver provides kernel-side support for the Random Number
+	  Generator hardware found on the AMD Geode LX.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called geode-rng.
+
+	  If unsure, say Y.
+
+config HW_RANDOM_VIA
+	tristate "VIA HW Random Number Generator support"
+	depends on HW_RANDOM && X86_32
+	default y
+	---help---
+	  This driver provides kernel-side support for the Random Number
+	  Generator hardware found on VIA based motherboards.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called via-rng.
+
+	  If unsure, say Y.
+
+config HW_RANDOM_IXP4XX
+	tristate "Intel IXP4xx NPU HW Random Number Generator support"
+	depends on HW_RANDOM && ARCH_IXP4XX
+	default y
+	---help---
+	  This driver provides kernel-side support for the Random
+	  Number Generator hardware found on the Intel IXP4xx NPU.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called ixp4xx-rng.
+
+	  If unsure, say Y.
+
+config HW_RANDOM_OMAP
+	tristate "OMAP Random Number Generator support"
+	depends on HW_RANDOM && (ARCH_OMAP16XX || ARCH_OMAP24XX)
+	default y
+ 	---help---
+ 	  This driver provides kernel-side support for the Random Number
+	  Generator hardware found on OMAP16xx and OMAP24xx multimedia
+	  processors.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called omap-rng.
+
+ 	  If unsure, say Y.
diff --git a/drivers/char/hw_random/Makefile b/drivers/char/hw_random/Makefile
new file mode 100644
index 000000000..e263ae96f
--- /dev/null
+++ b/drivers/char/hw_random/Makefile
@@ -0,0 +1,11 @@
+#
+# Makefile for HW Random Number Generator (RNG) device drivers.
+#
+
+obj-$(CONFIG_HW_RANDOM) += core.o
+obj-$(CONFIG_HW_RANDOM_INTEL) += intel-rng.o
+obj-$(CONFIG_HW_RANDOM_AMD) += amd-rng.o
+obj-$(CONFIG_HW_RANDOM_GEODE) += geode-rng.o
+obj-$(CONFIG_HW_RANDOM_VIA) += via-rng.o
+obj-$(CONFIG_HW_RANDOM_IXP4XX) += ixp4xx-rng.o
+obj-$(CONFIG_HW_RANDOM_OMAP) += omap-rng.o
diff --git a/drivers/char/hw_random/amd-rng.c b/drivers/char/hw_random/amd-rng.c
new file mode 100644
index 000000000..71e4e0f3f
--- /dev/null
+++ b/drivers/char/hw_random/amd-rng.c
@@ -0,0 +1,152 @@
+/*
+ * RNG driver for AMD RNGs
+ *
+ * Copyright 2005 (c) MontaVista Software, Inc.
+ *
+ * with the majority of the code coming from:
+ *
+ * Hardware driver for the Intel/AMD/VIA Random Number Generators (RNG)
+ * (c) Copyright 2003 Red Hat Inc <jgarzik@redhat.com>
+ *
+ * derived from
+ *
+ * Hardware driver for the AMD 768 Random Number Generator (RNG)
+ * (c) Copyright 2001 Red Hat Inc <alan@redhat.com>
+ *
+ * derived from
+ *
+ * Hardware driver for Intel i810 Random Number Generator (RNG)
+ * Copyright 2000,2001 Jeff Garzik <jgarzik@pobox.com>
+ * Copyright 2000,2001 Philipp Rumpf <prumpf@mandrakesoft.com>
+ *
+ * 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 <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/hw_random.h>
+#include <asm/io.h>
+
+
+#define PFX	KBUILD_MODNAME ": "
+
+
+/*
+ * Data for PCI driver interface
+ *
+ * This data only exists for exporting the supported
+ * PCI ids via MODULE_DEVICE_TABLE.  We do not actually
+ * register a pci_driver, because someone else might one day
+ * want to register another driver on the same PCI id.
+ */
+static const struct pci_device_id pci_tbl[] = {
+	{ 0x1022, 0x7443, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, },
+	{ 0x1022, 0x746b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, },
+	{ 0, },	/* terminate list */
+};
+MODULE_DEVICE_TABLE(pci, pci_tbl);
+
+static struct pci_dev *amd_pdev;
+
+
+static int amd_rng_data_present(struct hwrng *rng)
+{
+	u32 pmbase = (u32)rng->priv;
+
+      	return !!(inl(pmbase + 0xF4) & 1);
+}
+
+static int amd_rng_data_read(struct hwrng *rng, u32 *data)
+{
+	u32 pmbase = (u32)rng->priv;
+
+	*data = inl(pmbase + 0xF0);
+
+	return 4;
+}
+
+static int amd_rng_init(struct hwrng *rng)
+{
+	u8 rnen;
+
+	pci_read_config_byte(amd_pdev, 0x40, &rnen);
+	rnen |= (1 << 7);	/* RNG on */
+	pci_write_config_byte(amd_pdev, 0x40, rnen);
+
+	pci_read_config_byte(amd_pdev, 0x41, &rnen);
+	rnen |= (1 << 7);	/* PMIO enable */
+	pci_write_config_byte(amd_pdev, 0x41, rnen);
+
+	return 0;
+}
+
+static void amd_rng_cleanup(struct hwrng *rng)
+{
+	u8 rnen;
+
+	pci_read_config_byte(amd_pdev, 0x40, &rnen);
+	rnen &= ~(1 << 7);	/* RNG off */
+	pci_write_config_byte(amd_pdev, 0x40, rnen);
+}
+
+
+static struct hwrng amd_rng = {
+	.name		= "amd",
+	.init		= amd_rng_init,
+	.cleanup	= amd_rng_cleanup,
+	.data_present	= amd_rng_data_present,
+	.data_read	= amd_rng_data_read,
+};
+
+
+static int __init mod_init(void)
+{
+	int err = -ENODEV;
+	struct pci_dev *pdev = NULL;
+	const struct pci_device_id *ent;
+	u32 pmbase;
+
+	for_each_pci_dev(pdev) {
+		ent = pci_match_id(pci_tbl, pdev);
+		if (ent)
+			goto found;
+	}
+	/* Device not found. */
+	goto out;
+
+found:
+	err = pci_read_config_dword(pdev, 0x58, &pmbase);
+	if (err)
+		goto out;
+	err = -EIO;
+	pmbase &= 0x0000FF00;
+	if (pmbase == 0)
+		goto out;
+	amd_rng.priv = (unsigned long)pmbase;
+	amd_pdev = pdev;
+
+	printk(KERN_INFO "AMD768 RNG detected\n");
+	err = hwrng_register(&amd_rng);
+	if (err) {
+		printk(KERN_ERR PFX "RNG registering failed (%d)\n",
+		       err);
+		goto out;
+	}
+out:
+	return err;
+}
+
+static void __exit mod_exit(void)
+{
+	hwrng_unregister(&amd_rng);
+}
+
+subsys_initcall(mod_init);
+module_exit(mod_exit);
+
+MODULE_AUTHOR("The Linux Kernel team");
+MODULE_DESCRIPTION("H/W RNG driver for AMD chipsets");
+MODULE_LICENSE("GPL");
diff --git a/drivers/char/hw_random/core.c b/drivers/char/hw_random/core.c
new file mode 100644
index 000000000..154a81d32
--- /dev/null
+++ b/drivers/char/hw_random/core.c
@@ -0,0 +1,354 @@
+/*
+        Added support for the AMD Geode LX RNG
+	(c) Copyright 2004-2005 Advanced Micro Devices, Inc.
+
+	derived from
+
+ 	Hardware driver for the Intel/AMD/VIA Random Number Generators (RNG)
+	(c) Copyright 2003 Red Hat Inc <jgarzik@redhat.com>
+
+ 	derived from
+
+        Hardware driver for the AMD 768 Random Number Generator (RNG)
+        (c) Copyright 2001 Red Hat Inc <alan@redhat.com>
+
+ 	derived from
+
+	Hardware driver for Intel i810 Random Number Generator (RNG)
+	Copyright 2000,2001 Jeff Garzik <jgarzik@pobox.com>
+	Copyright 2000,2001 Philipp Rumpf <prumpf@mandrakesoft.com>
+
+	Added generic RNG API
+	Copyright 2006 Michael Buesch <mbuesch@freenet.de>
+	Copyright 2005 (c) MontaVista Software, Inc.
+
+	Please read Documentation/hw_random.txt for details on use.
+
+	----------------------------------------------------------
+	This software may be used and distributed according to the terms
+        of the GNU General Public License, incorporated herein by reference.
+
+ */
+
+
+#include <linux/device.h>
+#include <linux/hw_random.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/fs.h>
+#include <linux/init.h>
+#include <linux/miscdevice.h>
+#include <linux/delay.h>
+#include <asm/uaccess.h>
+
+
+#define RNG_MODULE_NAME		"hw_random"
+#define PFX			RNG_MODULE_NAME ": "
+#define RNG_MISCDEV_MINOR	183 /* official */
+
+
+static struct hwrng *current_rng;
+static LIST_HEAD(rng_list);
+static DEFINE_MUTEX(rng_mutex);
+
+
+static inline int hwrng_init(struct hwrng *rng)
+{
+	if (!rng->init)
+		return 0;
+	return rng->init(rng);
+}
+
+static inline void hwrng_cleanup(struct hwrng *rng)
+{
+	if (rng && rng->cleanup)
+		rng->cleanup(rng);
+}
+
+static inline int hwrng_data_present(struct hwrng *rng)
+{
+	if (!rng->data_present)
+		return 1;
+	return rng->data_present(rng);
+}
+
+static inline int hwrng_data_read(struct hwrng *rng, u32 *data)
+{
+	return rng->data_read(rng, data);
+}
+
+
+static int rng_dev_open(struct inode *inode, struct file *filp)
+{
+	/* enforce read-only access to this chrdev */
+	if ((filp->f_mode & FMODE_READ) == 0)
+		return -EINVAL;
+	if (filp->f_mode & FMODE_WRITE)
+		return -EINVAL;
+	return 0;
+}
+
+static ssize_t rng_dev_read(struct file *filp, char __user *buf,
+			    size_t size, loff_t *offp)
+{
+	u32 data;
+	ssize_t ret = 0;
+	int i, err = 0;
+	int data_present;
+	int bytes_read;
+
+	while (size) {
+		err = -ERESTARTSYS;
+		if (mutex_lock_interruptible(&rng_mutex))
+			goto out;
+		if (!current_rng) {
+			mutex_unlock(&rng_mutex);
+			err = -ENODEV;
+			goto out;
+		}
+		if (filp->f_flags & O_NONBLOCK) {
+			data_present = hwrng_data_present(current_rng);
+		} else {
+			/* Some RNG require some time between data_reads to gather
+			 * new entropy. Poll it.
+			 */
+			for (i = 0; i < 20; i++) {
+				data_present = hwrng_data_present(current_rng);
+				if (data_present)
+					break;
+				udelay(10);
+			}
+		}
+		bytes_read = 0;
+		if (data_present)
+			bytes_read = hwrng_data_read(current_rng, &data);
+		mutex_unlock(&rng_mutex);
+
+		err = -EAGAIN;
+		if (!bytes_read && (filp->f_flags & O_NONBLOCK))
+			goto out;
+
+		err = -EFAULT;
+		while (bytes_read && size) {
+			if (put_user((u8)data, buf++))
+				goto out;
+			size--;
+			ret++;
+			bytes_read--;
+			data >>= 8;
+		}
+
+		if (need_resched())
+			schedule_timeout_interruptible(1);
+		err = -ERESTARTSYS;
+		if (signal_pending(current))
+			goto out;
+	}
+out:
+	return ret ? : err;
+}
+
+
+static const struct file_operations rng_chrdev_ops = {
+	.owner		= THIS_MODULE,
+	.open		= rng_dev_open,
+	.read		= rng_dev_read,
+};
+
+static struct miscdevice rng_miscdev = {
+	.minor		= RNG_MISCDEV_MINOR,
+	.name		= RNG_MODULE_NAME,
+	.fops		= &rng_chrdev_ops,
+};
+
+
+static ssize_t hwrng_attr_current_store(struct class_device *class,
+					const char *buf, size_t len)
+{
+	int err;
+	struct hwrng *rng;
+
+	err = mutex_lock_interruptible(&rng_mutex);
+	if (err)
+		return -ERESTARTSYS;
+	err = -ENODEV;
+	list_for_each_entry(rng, &rng_list, list) {
+		if (strcmp(rng->name, buf) == 0) {
+			if (rng == current_rng) {
+				err = 0;
+				break;
+			}
+			err = hwrng_init(rng);
+			if (err)
+				break;
+			hwrng_cleanup(current_rng);
+			current_rng = rng;
+			err = 0;
+			break;
+		}
+	}
+	mutex_unlock(&rng_mutex);
+
+	return err ? : len;
+}
+
+static ssize_t hwrng_attr_current_show(struct class_device *class,
+				       char *buf)
+{
+	int err;
+	ssize_t ret;
+	const char *name = "none";
+
+	err = mutex_lock_interruptible(&rng_mutex);
+	if (err)
+		return -ERESTARTSYS;
+	if (current_rng)
+		name = current_rng->name;
+	ret = snprintf(buf, PAGE_SIZE, "%s\n", name);
+	mutex_unlock(&rng_mutex);
+
+	return ret;
+}
+
+static ssize_t hwrng_attr_available_show(struct class_device *class,
+					 char *buf)
+{
+	int err;
+	ssize_t ret = 0;
+	struct hwrng *rng;
+
+	err = mutex_lock_interruptible(&rng_mutex);
+	if (err)
+		return -ERESTARTSYS;
+	buf[0] = '\0';
+	list_for_each_entry(rng, &rng_list, list) {
+		strncat(buf, rng->name, PAGE_SIZE - ret - 1);
+		ret += strlen(rng->name);
+		strncat(buf, " ", PAGE_SIZE - ret - 1);
+		ret++;
+	}
+	strncat(buf, "\n", PAGE_SIZE - ret - 1);
+	ret++;
+	mutex_unlock(&rng_mutex);
+
+	return ret;
+}
+
+static CLASS_DEVICE_ATTR(rng_current, S_IRUGO | S_IWUSR,
+			 hwrng_attr_current_show,
+			 hwrng_attr_current_store);
+static CLASS_DEVICE_ATTR(rng_available, S_IRUGO,
+			 hwrng_attr_available_show,
+			 NULL);
+
+
+static void unregister_miscdev(void)
+{
+	class_device_remove_file(rng_miscdev.class,
+				 &class_device_attr_rng_available);
+	class_device_remove_file(rng_miscdev.class,
+				 &class_device_attr_rng_current);
+	misc_deregister(&rng_miscdev);
+}
+
+static int register_miscdev(void)
+{
+	int err;
+
+	err = misc_register(&rng_miscdev);
+	if (err)
+		goto out;
+	err = class_device_create_file(rng_miscdev.class,
+				       &class_device_attr_rng_current);
+	if (err)
+		goto err_misc_dereg;
+	err = class_device_create_file(rng_miscdev.class,
+				       &class_device_attr_rng_available);
+	if (err)
+		goto err_remove_current;
+out:
+	return err;
+
+err_remove_current:
+	class_device_remove_file(rng_miscdev.class,
+				 &class_device_attr_rng_current);
+err_misc_dereg:
+	misc_deregister(&rng_miscdev);
+	goto out;
+}
+
+int hwrng_register(struct hwrng *rng)
+{
+	int must_register_misc;
+	int err = -EINVAL;
+	struct hwrng *old_rng, *tmp;
+
+	if (rng->name == NULL ||
+	    rng->data_read == NULL)
+		goto out;
+
+	mutex_lock(&rng_mutex);
+
+	/* Must not register two RNGs with the same name. */
+	err = -EEXIST;
+	list_for_each_entry(tmp, &rng_list, list) {
+		if (strcmp(tmp->name, rng->name) == 0)
+			goto out_unlock;
+	}
+
+	must_register_misc = (current_rng == NULL);
+	old_rng = current_rng;
+	if (!old_rng) {
+		err = hwrng_init(rng);
+		if (err)
+			goto out_unlock;
+		current_rng = rng;
+	}
+	err = 0;
+	if (must_register_misc) {
+		err = register_miscdev();
+		if (err) {
+			if (!old_rng) {
+				hwrng_cleanup(rng);
+				current_rng = NULL;
+			}
+			goto out_unlock;
+		}
+	}
+	INIT_LIST_HEAD(&rng->list);
+	list_add_tail(&rng->list, &rng_list);
+out_unlock:
+	mutex_unlock(&rng_mutex);
+out:
+	return err;
+}
+EXPORT_SYMBOL_GPL(hwrng_register);
+
+void hwrng_unregister(struct hwrng *rng)
+{
+	int err;
+
+	mutex_lock(&rng_mutex);
+
+	list_del(&rng->list);
+	if (current_rng == rng) {
+		hwrng_cleanup(rng);
+		if (list_empty(&rng_list)) {
+			current_rng = NULL;
+		} else {
+			current_rng = list_entry(rng_list.prev, struct hwrng, list);
+			err = hwrng_init(current_rng);
+			if (err)
+				current_rng = NULL;
+		}
+	}
+	if (list_empty(&rng_list))
+		unregister_miscdev();
+
+	mutex_unlock(&rng_mutex);
+}
+EXPORT_SYMBOL_GPL(hwrng_unregister);
+
+
+MODULE_DESCRIPTION("H/W Random Number Generator (RNG) driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/char/hw_random/geode-rng.c b/drivers/char/hw_random/geode-rng.c
new file mode 100644
index 000000000..d37ced0d1
--- /dev/null
+++ b/drivers/char/hw_random/geode-rng.c
@@ -0,0 +1,132 @@
+/*
+ * RNG driver for AMD Geode RNGs
+ *
+ * Copyright 2005 (c) MontaVista Software, Inc.
+ *
+ * with the majority of the code coming from:
+ *
+ * Hardware driver for the Intel/AMD/VIA Random Number Generators (RNG)
+ * (c) Copyright 2003 Red Hat Inc <jgarzik@redhat.com>
+ *
+ * derived from
+ *
+ * Hardware driver for the AMD 768 Random Number Generator (RNG)
+ * (c) Copyright 2001 Red Hat Inc <alan@redhat.com>
+ *
+ * derived from
+ *
+ * Hardware driver for Intel i810 Random Number Generator (RNG)
+ * Copyright 2000,2001 Jeff Garzik <jgarzik@pobox.com>
+ * Copyright 2000,2001 Philipp Rumpf <prumpf@mandrakesoft.com>
+ *
+ * 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 <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/hw_random.h>
+#include <asm/io.h>
+
+
+#define PFX	KBUILD_MODNAME ": "
+
+#define GEODE_RNG_DATA_REG   0x50
+#define GEODE_RNG_STATUS_REG 0x54
+
+/*
+ * Data for PCI driver interface
+ *
+ * This data only exists for exporting the supported
+ * PCI ids via MODULE_DEVICE_TABLE.  We do not actually
+ * register a pci_driver, because someone else might one day
+ * want to register another driver on the same PCI id.
+ */
+static const struct pci_device_id pci_tbl[] = {
+	{ PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_LX_AES,
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, },
+	{ 0, },	/* terminate list */
+};
+MODULE_DEVICE_TABLE(pci, pci_tbl);
+
+
+static int geode_rng_data_read(struct hwrng *rng, u32 *data)
+{
+	void __iomem *mem = (void __iomem *)rng->priv;
+
+	*data = readl(mem + GEODE_RNG_DATA_REG);
+
+	return 4;
+}
+
+static int geode_rng_data_present(struct hwrng *rng)
+{
+	void __iomem *mem = (void __iomem *)rng->priv;
+
+	return !!(readl(mem + GEODE_RNG_STATUS_REG));
+}
+
+
+static struct hwrng geode_rng = {
+	.name		= "geode",
+	.data_present	= geode_rng_data_present,
+	.data_read	= geode_rng_data_read,
+};
+
+
+static int __init mod_init(void)
+{
+	int err = -ENODEV;
+	struct pci_dev *pdev = NULL;
+	const struct pci_device_id *ent;
+	void __iomem *mem;
+	unsigned long rng_base;
+
+	for_each_pci_dev(pdev) {
+		ent = pci_match_id(pci_tbl, pdev);
+		if (ent)
+			goto found;
+	}
+	/* Device not found. */
+	goto out;
+
+found:
+	rng_base = pci_resource_start(pdev, 0);
+	if (rng_base == 0)
+		goto out;
+	err = -ENOMEM;
+	mem = ioremap(rng_base, 0x58);
+	if (!mem)
+		goto out;
+	geode_rng.priv = (unsigned long)mem;
+
+	printk(KERN_INFO "AMD Geode RNG detected\n");
+	err = hwrng_register(&geode_rng);
+	if (err) {
+		printk(KERN_ERR PFX "RNG registering failed (%d)\n",
+		       err);
+		goto err_unmap;
+	}
+out:
+	return err;
+
+err_unmap:
+	iounmap(mem);
+	goto out;
+}
+
+static void __exit mod_exit(void)
+{
+	void __iomem *mem = (void __iomem *)geode_rng.priv;
+
+	hwrng_unregister(&geode_rng);
+	iounmap(mem);
+}
+
+subsys_initcall(mod_init);
+module_exit(mod_exit);
+
+MODULE_DESCRIPTION("H/W RNG driver for AMD Geode LX CPUs");
+MODULE_LICENSE("GPL");
diff --git a/drivers/char/hw_random/intel-rng.c b/drivers/char/hw_random/intel-rng.c
new file mode 100644
index 000000000..8efbc9c0e
--- /dev/null
+++ b/drivers/char/hw_random/intel-rng.c
@@ -0,0 +1,357 @@
+/*
+ * RNG driver for Intel RNGs
+ *
+ * Copyright 2005 (c) MontaVista Software, Inc.
+ *
+ * with the majority of the code coming from:
+ *
+ * Hardware driver for the Intel/AMD/VIA Random Number Generators (RNG)
+ * (c) Copyright 2003 Red Hat Inc <jgarzik@redhat.com>
+ *
+ * derived from
+ *
+ * Hardware driver for the AMD 768 Random Number Generator (RNG)
+ * (c) Copyright 2001 Red Hat Inc <alan@redhat.com>
+ *
+ * derived from
+ *
+ * Hardware driver for Intel i810 Random Number Generator (RNG)
+ * Copyright 2000,2001 Jeff Garzik <jgarzik@pobox.com>
+ * Copyright 2000,2001 Philipp Rumpf <prumpf@mandrakesoft.com>
+ *
+ * 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 <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/hw_random.h>
+#include <asm/io.h>
+
+
+#define PFX	KBUILD_MODNAME ": "
+
+/*
+ * RNG registers
+ */
+#define INTEL_RNG_HW_STATUS			0
+#define         INTEL_RNG_PRESENT		0x40
+#define         INTEL_RNG_ENABLED		0x01
+#define INTEL_RNG_STATUS			1
+#define         INTEL_RNG_DATA_PRESENT		0x01
+#define INTEL_RNG_DATA				2
+
+/*
+ * Magic address at which Intel PCI bridges locate the RNG
+ */
+#define INTEL_RNG_ADDR				0xFFBC015F
+#define INTEL_RNG_ADDR_LEN			3
+
+/*
+ * LPC bridge PCI config space registers
+ */
+#define FWH_DEC_EN1_REG_OLD			0xe3
+#define FWH_DEC_EN1_REG_NEW			0xd9 /* high byte of 16-bit register */
+#define FWH_F8_EN_MASK				0x80
+
+#define BIOS_CNTL_REG_OLD			0x4e
+#define BIOS_CNTL_REG_NEW			0xdc
+#define BIOS_CNTL_WRITE_ENABLE_MASK		0x01
+#define BIOS_CNTL_LOCK_ENABLE_MASK		0x02
+
+/*
+ * Magic address at which Intel Firmware Hubs get accessed
+ */
+#define INTEL_FWH_ADDR				0xffff0000
+#define INTEL_FWH_ADDR_LEN			2
+
+/*
+ * Intel Firmware Hub command codes (write to any address inside the device)
+ */
+#define INTEL_FWH_RESET_CMD			0xff /* aka READ_ARRAY */
+#define INTEL_FWH_READ_ID_CMD			0x90
+
+/*
+ * Intel Firmware Hub Read ID command result addresses
+ */
+#define INTEL_FWH_MANUFACTURER_CODE_ADDRESS	0x000000
+#define INTEL_FWH_DEVICE_CODE_ADDRESS		0x000001
+
+/*
+ * Intel Firmware Hub Read ID command result values
+ */
+#define INTEL_FWH_MANUFACTURER_CODE		0x89
+#define INTEL_FWH_DEVICE_CODE_8M		0xac
+#define INTEL_FWH_DEVICE_CODE_4M		0xad
+
+/*
+ * Data for PCI driver interface
+ *
+ * This data only exists for exporting the supported
+ * PCI ids via MODULE_DEVICE_TABLE.  We do not actually
+ * register a pci_driver, because someone else might one day
+ * want to register another driver on the same PCI id.
+ */
+static const struct pci_device_id pci_tbl[] = {
+/* AA
+	{ 0x8086, 0x2418, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, */
+	{ 0x8086, 0x2410, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* AA */
+/* AB
+	{ 0x8086, 0x2428, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, */
+	{ 0x8086, 0x2420, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* AB */
+/* ??
+	{ 0x8086, 0x2430, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, */
+/* BAM, CAM, DBM, FBM, GxM
+	{ 0x8086, 0x2448, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, */
+	{ 0x8086, 0x244c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* BAM */
+	{ 0x8086, 0x248c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* CAM */
+	{ 0x8086, 0x24cc, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* DBM */
+	{ 0x8086, 0x2641, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* FBM */
+	{ 0x8086, 0x27b9, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* GxM */
+	{ 0x8086, 0x27bd, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* GxM DH */
+/* BA, CA, DB, Ex, 6300, Fx, 631x/632x, Gx
+	{ 0x8086, 0x244e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, */
+	{ 0x8086, 0x2440, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* BA */
+	{ 0x8086, 0x2480, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* CA */
+	{ 0x8086, 0x24c0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* DB */
+	{ 0x8086, 0x24d0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* Ex */
+	{ 0x8086, 0x25a1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* 6300 */
+	{ 0x8086, 0x2640, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* Fx */
+	{ 0x8086, 0x2670, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* 631x/632x */
+	{ 0x8086, 0x2671, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* 631x/632x */
+	{ 0x8086, 0x2672, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* 631x/632x */
+	{ 0x8086, 0x2673, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* 631x/632x */
+	{ 0x8086, 0x2674, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* 631x/632x */
+	{ 0x8086, 0x2675, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* 631x/632x */
+	{ 0x8086, 0x2676, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* 631x/632x */
+	{ 0x8086, 0x2677, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* 631x/632x */
+	{ 0x8086, 0x2678, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* 631x/632x */
+	{ 0x8086, 0x2679, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* 631x/632x */
+	{ 0x8086, 0x267a, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* 631x/632x */
+	{ 0x8086, 0x267b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* 631x/632x */
+	{ 0x8086, 0x267c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* 631x/632x */
+	{ 0x8086, 0x267d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* 631x/632x */
+	{ 0x8086, 0x267e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* 631x/632x */
+	{ 0x8086, 0x267f, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* 631x/632x */
+	{ 0x8086, 0x27b8, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* Gx */
+/* E
+	{ 0x8086, 0x245e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, */
+	{ 0x8086, 0x2450, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* E  */
+	{ 0, },	/* terminate list */
+};
+MODULE_DEVICE_TABLE(pci, pci_tbl);
+
+
+static inline u8 hwstatus_get(void __iomem *mem)
+{
+	return readb(mem + INTEL_RNG_HW_STATUS);
+}
+
+static inline u8 hwstatus_set(void __iomem *mem,
+			      u8 hw_status)
+{
+	writeb(hw_status, mem + INTEL_RNG_HW_STATUS);
+	return hwstatus_get(mem);
+}
+
+static int intel_rng_data_present(struct hwrng *rng)
+{
+	void __iomem *mem = (void __iomem *)rng->priv;
+
+	return !!(readb(mem + INTEL_RNG_STATUS) & INTEL_RNG_DATA_PRESENT);
+}
+
+static int intel_rng_data_read(struct hwrng *rng, u32 *data)
+{
+	void __iomem *mem = (void __iomem *)rng->priv;
+
+	*data = readb(mem + INTEL_RNG_DATA);
+
+	return 1;
+}
+
+static int intel_rng_init(struct hwrng *rng)
+{
+	void __iomem *mem = (void __iomem *)rng->priv;
+	u8 hw_status;
+	int err = -EIO;
+
+	hw_status = hwstatus_get(mem);
+	/* turn RNG h/w on, if it's off */
+	if ((hw_status & INTEL_RNG_ENABLED) == 0)
+		hw_status = hwstatus_set(mem, hw_status | INTEL_RNG_ENABLED);
+	if ((hw_status & INTEL_RNG_ENABLED) == 0) {
+		printk(KERN_ERR PFX "cannot enable RNG, aborting\n");
+		goto out;
+	}
+	err = 0;
+out:
+	return err;
+}
+
+static void intel_rng_cleanup(struct hwrng *rng)
+{
+	void __iomem *mem = (void __iomem *)rng->priv;
+	u8 hw_status;
+
+	hw_status = hwstatus_get(mem);
+	if (hw_status & INTEL_RNG_ENABLED)
+		hwstatus_set(mem, hw_status & ~INTEL_RNG_ENABLED);
+	else
+		printk(KERN_WARNING PFX "unusual: RNG already disabled\n");
+}
+
+
+static struct hwrng intel_rng = {
+	.name		= "intel",
+	.init		= intel_rng_init,
+	.cleanup	= intel_rng_cleanup,
+	.data_present	= intel_rng_data_present,
+	.data_read	= intel_rng_data_read,
+};
+
+
+#ifdef CONFIG_SMP
+static char __initdata waitflag;
+
+static void __init intel_init_wait(void *unused)
+{
+	while (waitflag)
+		cpu_relax();
+}
+#endif
+
+static int __init mod_init(void)
+{
+	int err = -ENODEV;
+	unsigned i;
+	struct pci_dev *dev = NULL;
+	void __iomem *mem;
+	unsigned long flags;
+	u8 bios_cntl_off, fwh_dec_en1_off;
+	u8 bios_cntl_val = 0xff, fwh_dec_en1_val = 0xff;
+	u8 hw_status, mfc, dvc;
+
+	for (i = 0; !dev && pci_tbl[i].vendor; ++i)
+		dev = pci_get_device(pci_tbl[i].vendor, pci_tbl[i].device, NULL);
+
+	if (!dev)
+		goto out; /* Device not found. */
+
+	/* Check for Intel 82802 */
+	if (dev->device < 0x2640) {
+		fwh_dec_en1_off = FWH_DEC_EN1_REG_OLD;
+		bios_cntl_off = BIOS_CNTL_REG_OLD;
+	} else {
+		fwh_dec_en1_off = FWH_DEC_EN1_REG_NEW;
+		bios_cntl_off = BIOS_CNTL_REG_NEW;
+	}
+
+	pci_read_config_byte(dev, fwh_dec_en1_off, &fwh_dec_en1_val);
+	pci_read_config_byte(dev, bios_cntl_off, &bios_cntl_val);
+
+	mem = ioremap_nocache(INTEL_FWH_ADDR, INTEL_FWH_ADDR_LEN);
+	if (mem == NULL) {
+		pci_dev_put(dev);
+		err = -EBUSY;
+		goto out;
+	}
+
+	/*
+	 * Since the BIOS code/data is going to disappear from its normal
+	 * location with the Read ID command, all activity on the system
+	 * must be stopped until the state is back to normal.
+	 */
+#ifdef CONFIG_SMP
+	set_mb(waitflag, 1);
+	if (smp_call_function(intel_init_wait, NULL, 1, 0) != 0) {
+		set_mb(waitflag, 0);
+		pci_dev_put(dev);
+		printk(KERN_ERR PFX "cannot run on all processors\n");
+		err = -EAGAIN;
+		goto err_unmap;
+	}
+#endif
+	local_irq_save(flags);
+
+	if (!(fwh_dec_en1_val & FWH_F8_EN_MASK))
+		pci_write_config_byte(dev,
+		                      fwh_dec_en1_off,
+		                      fwh_dec_en1_val | FWH_F8_EN_MASK);
+	if (!(bios_cntl_val &
+	      (BIOS_CNTL_LOCK_ENABLE_MASK|BIOS_CNTL_WRITE_ENABLE_MASK)))
+		pci_write_config_byte(dev,
+		                      bios_cntl_off,
+		                      bios_cntl_val | BIOS_CNTL_WRITE_ENABLE_MASK);
+
+	writeb(INTEL_FWH_RESET_CMD, mem);
+	writeb(INTEL_FWH_READ_ID_CMD, mem);
+	mfc = readb(mem + INTEL_FWH_MANUFACTURER_CODE_ADDRESS);
+	dvc = readb(mem + INTEL_FWH_DEVICE_CODE_ADDRESS);
+	writeb(INTEL_FWH_RESET_CMD, mem);
+
+	if (!(bios_cntl_val &
+	      (BIOS_CNTL_LOCK_ENABLE_MASK|BIOS_CNTL_WRITE_ENABLE_MASK)))
+		pci_write_config_byte(dev, bios_cntl_off, bios_cntl_val);
+	if (!(fwh_dec_en1_val & FWH_F8_EN_MASK))
+		pci_write_config_byte(dev, fwh_dec_en1_off, fwh_dec_en1_val);
+
+	local_irq_restore(flags);
+#ifdef CONFIG_SMP
+	/* Tell other CPUs to resume. */
+	set_mb(waitflag, 0);
+#endif
+
+	iounmap(mem);
+	pci_dev_put(dev);
+
+	if (mfc != INTEL_FWH_MANUFACTURER_CODE ||
+	    (dvc != INTEL_FWH_DEVICE_CODE_8M &&
+	     dvc != INTEL_FWH_DEVICE_CODE_4M)) {
+		printk(KERN_ERR PFX "FWH not detected\n");
+		err = -ENODEV;
+		goto out;
+	}
+
+	err = -ENOMEM;
+	mem = ioremap(INTEL_RNG_ADDR, INTEL_RNG_ADDR_LEN);
+	if (!mem)
+		goto out;
+	intel_rng.priv = (unsigned long)mem;
+
+	/* Check for Random Number Generator */
+	err = -ENODEV;
+	hw_status = hwstatus_get(mem);
+	if ((hw_status & INTEL_RNG_PRESENT) == 0)
+		goto err_unmap;
+
+	printk(KERN_INFO "Intel 82802 RNG detected\n");
+	err = hwrng_register(&intel_rng);
+	if (err) {
+		printk(KERN_ERR PFX "RNG registering failed (%d)\n",
+		       err);
+		goto err_unmap;
+	}
+out:
+	return err;
+
+err_unmap:
+	iounmap(mem);
+	goto out;
+}
+
+static void __exit mod_exit(void)
+{
+	void __iomem *mem = (void __iomem *)intel_rng.priv;
+
+	hwrng_unregister(&intel_rng);
+	iounmap(mem);
+}
+
+subsys_initcall(mod_init);
+module_exit(mod_exit);
+
+MODULE_DESCRIPTION("H/W RNG driver for Intel chipsets");
+MODULE_LICENSE("GPL");
diff --git a/drivers/char/hw_random/ixp4xx-rng.c b/drivers/char/hw_random/ixp4xx-rng.c
new file mode 100644
index 000000000..7f7615b11
--- /dev/null
+++ b/drivers/char/hw_random/ixp4xx-rng.c
@@ -0,0 +1,72 @@
+/*
+ * drivers/char/rng/ixp4xx-rng.c
+ *
+ * RNG driver for Intel IXP4xx family of NPUs
+ *
+ * Author: Deepak Saxena <dsaxena@plexity.net>
+ *
+ * Copyright 2005 (c) MontaVista Software, Inc.
+ *
+ * Fixes by Michael Buesch
+ *
+ * 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 <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/init.h>
+#include <linux/bitops.h>
+#include <linux/hw_random.h>
+
+#include <asm/io.h>
+#include <asm/hardware.h>
+
+
+static int ixp4xx_rng_data_read(struct hwrng *rng, u32 *buffer)
+{
+	void __iomem * rng_base = (void __iomem *)rng->priv;
+
+	*buffer = __raw_readl(rng_base);
+
+	return 4;
+}
+
+static struct hwrng ixp4xx_rng_ops = {
+	.name		= "ixp4xx",
+	.data_read	= ixp4xx_rng_data_read,
+};
+
+static int __init ixp4xx_rng_init(void)
+{
+	void __iomem * rng_base;
+	int err;
+
+	rng_base = ioremap(0x70002100, 4);
+	if (!rng_base)
+		return -ENOMEM;
+	ixp4xx_rng_ops.priv = (unsigned long)rng_base;
+	err = hwrng_register(&ixp4xx_rng_ops);
+	if (err)
+		iounmap(rng_base);
+
+	return err;
+}
+
+static void __exit ixp4xx_rng_exit(void)
+{
+	void __iomem * rng_base = (void __iomem *)ixp4xx_rng_ops.priv;
+
+	hwrng_unregister(&ixp4xx_rng_ops);
+	iounmap(rng_base);
+}
+
+subsys_initcall(ixp4xx_rng_init);
+module_exit(ixp4xx_rng_exit);
+
+MODULE_AUTHOR("Deepak Saxena <dsaxena@plexity.net>");
+MODULE_DESCRIPTION("H/W Random Number Generator (RNG) driver for IXP4xx");
+MODULE_LICENSE("GPL");
diff --git a/drivers/char/hw_random/omap-rng.c b/drivers/char/hw_random/omap-rng.c
new file mode 100644
index 000000000..a01d796d1
--- /dev/null
+++ b/drivers/char/hw_random/omap-rng.c
@@ -0,0 +1,205 @@
+/*
+ * driver/char/hw_random/omap-rng.c
+ *
+ * RNG driver for TI OMAP CPU family
+ *
+ * Author: Deepak Saxena <dsaxena@plexity.net>
+ *
+ * Copyright 2005 (c) MontaVista Software, Inc.
+ *
+ * Mostly based on original driver:
+ *
+ * Copyright (C) 2005 Nokia Corporation
+ * Author: Juha Yrj��<juha.yrjola@nokia.com>
+ *
+ * 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.
+ *
+ * TODO:
+ *
+ * - Make status updated be interrupt driven so we don't poll
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/random.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/platform_device.h>
+#include <linux/hw_random.h>
+
+#include <asm/io.h>
+
+#define RNG_OUT_REG		0x00		/* Output register */
+#define RNG_STAT_REG		0x04		/* Status register
+							[0] = STAT_BUSY */
+#define RNG_ALARM_REG		0x24		/* Alarm register
+							[7:0] = ALARM_COUNTER */
+#define RNG_CONFIG_REG		0x28		/* Configuration register
+							[11:6] = RESET_COUNT
+							[5:3]  = RING2_DELAY
+							[2:0]  = RING1_DELAY */
+#define RNG_REV_REG		0x3c		/* Revision register
+							[7:0] = REV_NB */
+#define RNG_MASK_REG		0x40		/* Mask and reset register
+							[2] = IT_EN
+							[1] = SOFTRESET
+							[0] = AUTOIDLE */
+#define RNG_SYSSTATUS		0x44		/* System status
+							[0] = RESETDONE */
+
+static void __iomem *rng_base;
+static struct clk *rng_ick;
+static struct platform_device *rng_dev;
+
+static u32 omap_rng_read_reg(int reg)
+{
+	return __raw_readl(rng_base + reg);
+}
+
+static void omap_rng_write_reg(int reg, u32 val)
+{
+	__raw_writel(val, rng_base + reg);
+}
+
+/* REVISIT: Does the status bit really work on 16xx? */
+static int omap_rng_data_present(struct hwrng *rng)
+{
+	return omap_rng_read_reg(RNG_STAT_REG) ? 0 : 1;
+}
+
+static int omap_rng_data_read(struct hwrng *rng, u32 *data)
+{
+	*data = omap_rng_read_reg(RNG_OUT_REG);
+
+	return 4;
+}
+
+static struct hwrng omap_rng_ops = {
+	.name		= "omap",
+	.data_present	= omap_rng_data_present,
+	.data_read	= omap_rng_data_read,
+};
+
+static int __init omap_rng_probe(struct platform_device *pdev)
+{
+	struct resource *res, *mem;
+	int ret;
+
+	/*
+	 * A bit ugly, and it will never actually happen but there can
+	 * be only one RNG and this catches any bork
+	 */
+	BUG_ON(rng_dev);
+
+	if (cpu_is_omap24xx()) {
+		rng_ick = clk_get(NULL, "rng_ick");
+		if (IS_ERR(rng_ick)) {
+			dev_err(&pdev->dev, "Could not get rng_ick\n");
+			ret = PTR_ERR(rng_ick);
+			return ret;
+		} else
+			clk_enable(rng_ick);
+	}
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+
+	if (!res)
+		return -ENOENT;
+
+	mem = request_mem_region(res->start, res->end - res->start + 1,
+				 pdev->name);
+	if (mem == NULL)
+		return -EBUSY;
+
+	dev_set_drvdata(&pdev->dev, mem);
+	rng_base = (u32 __iomem *)io_p2v(res->start);
+
+	ret = hwrng_register(&omap_rng_ops);
+	if (ret) {
+		release_resource(mem);
+		rng_base = NULL;
+		return ret;
+	}
+
+	dev_info(&pdev->dev, "OMAP Random Number Generator ver. %02x\n",
+		omap_rng_read_reg(RNG_REV_REG));
+	omap_rng_write_reg(RNG_MASK_REG, 0x1);
+
+	rng_dev = pdev;
+
+	return 0;
+}
+
+static int __exit omap_rng_remove(struct platform_device *pdev)
+{
+	struct resource *mem = dev_get_drvdata(&pdev->dev);
+
+	hwrng_unregister(&omap_rng_ops);
+
+	omap_rng_write_reg(RNG_MASK_REG, 0x0);
+
+	if (cpu_is_omap24xx()) {
+		clk_disable(rng_ick);
+		clk_put(rng_ick);
+	}
+
+	release_resource(mem);
+	rng_base = NULL;
+
+	return 0;
+}
+
+#ifdef CONFIG_PM
+
+static int omap_rng_suspend(struct platform_device *pdev, pm_message_t message)
+{
+	omap_rng_write_reg(RNG_MASK_REG, 0x0);
+	return 0;
+}
+
+static int omap_rng_resume(struct platform_device *pdev)
+{
+	omap_rng_write_reg(RNG_MASK_REG, 0x1);
+	return 0;
+}
+
+#else
+
+#define	omap_rng_suspend	NULL
+#define	omap_rng_resume		NULL
+
+#endif
+
+
+static struct platform_driver omap_rng_driver = {
+	.driver = {
+		.name		= "omap_rng",
+		.owner		= THIS_MODULE,
+	},
+	.probe		= omap_rng_probe,
+	.remove		= __exit_p(omap_rng_remove),
+	.suspend	= omap_rng_suspend,
+	.resume		= omap_rng_resume
+};
+
+static int __init omap_rng_init(void)
+{
+	if (!cpu_is_omap16xx() && !cpu_is_omap24xx())
+		return -ENODEV;
+
+	return platform_driver_register(&omap_rng_driver);
+}
+
+static void __exit omap_rng_exit(void)
+{
+	platform_driver_unregister(&omap_rng_driver);
+}
+
+module_init(omap_rng_init);
+module_exit(omap_rng_exit);
+
+MODULE_AUTHOR("Deepak Saxena (and others)");
+MODULE_LICENSE("GPL");
diff --git a/drivers/char/hw_random/via-rng.c b/drivers/char/hw_random/via-rng.c
new file mode 100644
index 000000000..0e786b617
--- /dev/null
+++ b/drivers/char/hw_random/via-rng.c
@@ -0,0 +1,183 @@
+/*
+ * RNG driver for VIA RNGs
+ *
+ * Copyright 2005 (c) MontaVista Software, Inc.
+ *
+ * with the majority of the code coming from:
+ *
+ * Hardware driver for the Intel/AMD/VIA Random Number Generators (RNG)
+ * (c) Copyright 2003 Red Hat Inc <jgarzik@redhat.com>
+ *
+ * derived from
+ *
+ * Hardware driver for the AMD 768 Random Number Generator (RNG)
+ * (c) Copyright 2001 Red Hat Inc <alan@redhat.com>
+ *
+ * derived from
+ *
+ * Hardware driver for Intel i810 Random Number Generator (RNG)
+ * Copyright 2000,2001 Jeff Garzik <jgarzik@pobox.com>
+ * Copyright 2000,2001 Philipp Rumpf <prumpf@mandrakesoft.com>
+ *
+ * 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 <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/hw_random.h>
+#include <asm/io.h>
+#include <asm/msr.h>
+#include <asm/cpufeature.h>
+
+
+#define PFX	KBUILD_MODNAME ": "
+
+
+enum {
+	VIA_STRFILT_CNT_SHIFT	= 16,
+	VIA_STRFILT_FAIL	= (1 << 15),
+	VIA_STRFILT_ENABLE	= (1 << 14),
+	VIA_RAWBITS_ENABLE	= (1 << 13),
+	VIA_RNG_ENABLE		= (1 << 6),
+	VIA_XSTORE_CNT_MASK	= 0x0F,
+
+	VIA_RNG_CHUNK_8		= 0x00,	/* 64 rand bits, 64 stored bits */
+	VIA_RNG_CHUNK_4		= 0x01,	/* 32 rand bits, 32 stored bits */
+	VIA_RNG_CHUNK_4_MASK	= 0xFFFFFFFF,
+	VIA_RNG_CHUNK_2		= 0x02,	/* 16 rand bits, 32 stored bits */
+	VIA_RNG_CHUNK_2_MASK	= 0xFFFF,
+	VIA_RNG_CHUNK_1		= 0x03,	/* 8 rand bits, 32 stored bits */
+	VIA_RNG_CHUNK_1_MASK	= 0xFF,
+};
+
+/*
+ * Investigate using the 'rep' prefix to obtain 32 bits of random data
+ * in one insn.  The upside is potentially better performance.  The
+ * downside is that the instruction becomes no longer atomic.  Due to
+ * this, just like familiar issues with /dev/random itself, the worst
+ * case of a 'rep xstore' could potentially pause a cpu for an
+ * unreasonably long time.  In practice, this condition would likely
+ * only occur when the hardware is failing.  (or so we hope :))
+ *
+ * Another possible performance boost may come from simply buffering
+ * until we have 4 bytes, thus returning a u32 at a time,
+ * instead of the current u8-at-a-time.
+ */
+
+static inline u32 xstore(u32 *addr, u32 edx_in)
+{
+	u32 eax_out;
+
+	asm(".byte 0x0F,0xA7,0xC0 /* xstore %%edi (addr=%0) */"
+		:"=m"(*addr), "=a"(eax_out)
+		:"D"(addr), "d"(edx_in));
+
+	return eax_out;
+}
+
+static int via_rng_data_present(struct hwrng *rng)
+{
+	u32 bytes_out;
+	u32 *via_rng_datum = (u32 *)(&rng->priv);
+
+	/* We choose the recommended 1-byte-per-instruction RNG rate,
+	 * for greater randomness at the expense of speed.  Larger
+	 * values 2, 4, or 8 bytes-per-instruction yield greater
+	 * speed at lesser randomness.
+	 *
+	 * If you change this to another VIA_CHUNK_n, you must also
+	 * change the ->n_bytes values in rng_vendor_ops[] tables.
+	 * VIA_CHUNK_8 requires further code changes.
+	 *
+	 * A copy of MSR_VIA_RNG is placed in eax_out when xstore
+	 * completes.
+	 */
+
+	*via_rng_datum = 0; /* paranoia, not really necessary */
+	bytes_out = xstore(via_rng_datum, VIA_RNG_CHUNK_1);
+	bytes_out &= VIA_XSTORE_CNT_MASK;
+	if (bytes_out == 0)
+		return 0;
+	return 1;
+}
+
+static int via_rng_data_read(struct hwrng *rng, u32 *data)
+{
+	u32 via_rng_datum = (u32)rng->priv;
+
+	*data = via_rng_datum;
+
+	return 1;
+}
+
+static int via_rng_init(struct hwrng *rng)
+{
+	u32 lo, hi, old_lo;
+
+	/* Control the RNG via MSR.  Tread lightly and pay very close
+	 * close attention to values written, as the reserved fields
+	 * are documented to be "undefined and unpredictable"; but it
+	 * does not say to write them as zero, so I make a guess that
+	 * we restore the values we find in the register.
+	 */
+	rdmsr(MSR_VIA_RNG, lo, hi);
+
+	old_lo = lo;
+	lo &= ~(0x7f << VIA_STRFILT_CNT_SHIFT);
+	lo &= ~VIA_XSTORE_CNT_MASK;
+	lo &= ~(VIA_STRFILT_ENABLE | VIA_STRFILT_FAIL | VIA_RAWBITS_ENABLE);
+	lo |= VIA_RNG_ENABLE;
+
+	if (lo != old_lo)
+		wrmsr(MSR_VIA_RNG, lo, hi);
+
+	/* perhaps-unnecessary sanity check; remove after testing if
+	   unneeded */
+	rdmsr(MSR_VIA_RNG, lo, hi);
+	if ((lo & VIA_RNG_ENABLE) == 0) {
+		printk(KERN_ERR PFX "cannot enable VIA C3 RNG, aborting\n");
+		return -ENODEV;
+	}
+
+	return 0;
+}
+
+
+static struct hwrng via_rng = {
+	.name		= "via",
+	.init		= via_rng_init,
+	.data_present	= via_rng_data_present,
+	.data_read	= via_rng_data_read,
+};
+
+
+static int __init mod_init(void)
+{
+	int err;
+
+	if (!cpu_has_xstore)
+		return -ENODEV;
+	printk(KERN_INFO "VIA RNG detected\n");
+	err = hwrng_register(&via_rng);
+	if (err) {
+		printk(KERN_ERR PFX "RNG registering failed (%d)\n",
+		       err);
+		goto out;
+	}
+out:
+	return err;
+}
+
+static void __exit mod_exit(void)
+{
+	hwrng_unregister(&via_rng);
+}
+
+subsys_initcall(mod_init);
+module_exit(mod_exit);
+
+MODULE_DESCRIPTION("H/W RNG driver for VIA chipsets");
+MODULE_LICENSE("GPL");
diff --git a/drivers/char/nsc_gpio.c b/drivers/char/nsc_gpio.c
new file mode 100644
index 000000000..4d47d79bc
--- /dev/null
+++ b/drivers/char/nsc_gpio.c
@@ -0,0 +1,139 @@
+/* linux/drivers/char/nsc_gpio.c
+
+   National Semiconductor common GPIO device-file/VFS methods.
+   Allows a user space process to control the GPIO pins.
+
+   Copyright (c) 2001,2002 Christer Weinigel <wingel@nano-system.com>
+   Copyright (c) 2005      Jim Cromie <jim.cromie@gmail.com>
+*/
+
+#include <linux/fs.h>
+#include <linux/module.h>
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/nsc_gpio.h>
+#include <linux/platform_device.h>
+#include <asm/uaccess.h>
+#include <asm/io.h>
+
+#define NAME "nsc_gpio"
+
+void nsc_gpio_dump(struct nsc_gpio_ops *amp, unsigned index)
+{
+	/* retrieve current config w/o changing it */
+	u32 config = amp->gpio_config(index, ~0, 0);
+
+	/* user requested via 'v' command, so its INFO */
+	dev_info(amp->dev, "io%02u: 0x%04x %s %s %s %s %s %s %s\tio:%d/%d\n",
+		 index, config,
+		 (config & 1) ? "OE" : "TS",      /* output-enabled/tristate */
+		 (config & 2) ? "PP" : "OD",      /* push pull / open drain */
+		 (config & 4) ? "PUE" : "PUD",    /* pull up enabled/disabled */
+		 (config & 8) ? "LOCKED" : "",    /* locked / unlocked */
+		 (config & 16) ? "LEVEL" : "EDGE",/* level/edge input */
+		 (config & 32) ? "HI" : "LO",     /* trigger on rise/fall edge */
+		 (config & 64) ? "DEBOUNCE" : "", /* debounce */
+
+		 amp->gpio_get(index), amp->gpio_current(index));
+}
+
+ssize_t nsc_gpio_write(struct file *file, const char __user *data,
+		       size_t len, loff_t *ppos)
+{
+	unsigned m = iminor(file->f_dentry->d_inode);
+	struct nsc_gpio_ops *amp = file->private_data;
+	struct device *dev = amp->dev;
+	size_t i;
+	int err = 0;
+
+	for (i = 0; i < len; ++i) {
+		char c;
+		if (get_user(c, data + i))
+			return -EFAULT;
+		switch (c) {
+		case '0':
+			amp->gpio_set(m, 0);
+			break;
+		case '1':
+			amp->gpio_set(m, 1);
+			break;
+		case 'O':
+			dev_dbg(dev, "GPIO%d output enabled\n", m);
+			amp->gpio_config(m, ~1, 1);
+			break;
+		case 'o':
+			dev_dbg(dev, "GPIO%d output disabled\n", m);
+			amp->gpio_config(m, ~1, 0);
+			break;
+		case 'T':
+			dev_dbg(dev, "GPIO%d output is push pull\n", m);
+			amp->gpio_config(m, ~2, 2);
+			break;
+		case 't':
+			dev_dbg(dev, "GPIO%d output is open drain\n", m);
+			amp->gpio_config(m, ~2, 0);
+			break;
+		case 'P':
+			dev_dbg(dev, "GPIO%d pull up enabled\n", m);
+			amp->gpio_config(m, ~4, 4);
+			break;
+		case 'p':
+			dev_dbg(dev, "GPIO%d pull up disabled\n", m);
+			amp->gpio_config(m, ~4, 0);
+			break;
+		case 'v':
+			/* View Current pin settings */
+			amp->gpio_dump(amp, m);
+			break;
+		case '\n':
+			/* end of settings string, do nothing */
+			break;
+		default:
+			dev_err(dev, "io%2d bad setting: chr<0x%2x>\n",
+				m, (int)c);
+			err++;
+		}
+	}
+	if (err)
+		return -EINVAL;	/* full string handled, report error */
+
+	return len;
+}
+
+ssize_t nsc_gpio_read(struct file *file, char __user * buf,
+		      size_t len, loff_t * ppos)
+{
+	unsigned m = iminor(file->f_dentry->d_inode);
+	int value;
+	struct nsc_gpio_ops *amp = file->private_data;
+
+	value = amp->gpio_get(m);
+	if (put_user(value ? '1' : '0', buf))
+		return -EFAULT;
+
+	return 1;
+}
+
+/* common file-ops routines for both scx200_gpio and pc87360_gpio */
+EXPORT_SYMBOL(nsc_gpio_write);
+EXPORT_SYMBOL(nsc_gpio_read);
+EXPORT_SYMBOL(nsc_gpio_dump);
+
+static int __init nsc_gpio_init(void)
+{
+	printk(KERN_DEBUG NAME " initializing\n");
+	return 0;
+}
+
+static void __exit nsc_gpio_cleanup(void)
+{
+	printk(KERN_DEBUG NAME " cleanup\n");
+}
+
+module_init(nsc_gpio_init);
+module_exit(nsc_gpio_cleanup);
+
+MODULE_AUTHOR("Jim Cromie <jim.cromie@gmail.com>");
+MODULE_DESCRIPTION("NatSemi GPIO Common Methods");
+MODULE_LICENSE("GPL");
diff --git a/drivers/char/pc8736x_gpio.c b/drivers/char/pc8736x_gpio.c
new file mode 100644
index 000000000..84e5a6863
--- /dev/null
+++ b/drivers/char/pc8736x_gpio.c
@@ -0,0 +1,357 @@
+/* linux/drivers/char/pc8736x_gpio.c
+
+   National Semiconductor PC8736x GPIO driver.  Allows a user space
+   process to play with the GPIO pins.
+
+   Copyright (c) 2005,2006 Jim Cromie <jim.cromie@gmail.com>
+
+   adapted from linux/drivers/char/scx200_gpio.c
+   Copyright (c) 2001,2002 Christer Weinigel <wingel@nano-system.com>,
+*/
+
+#include <linux/fs.h>
+#include <linux/module.h>
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/cdev.h>
+#include <linux/io.h>
+#include <linux/ioport.h>
+#include <linux/mutex.h>
+#include <linux/nsc_gpio.h>
+#include <linux/platform_device.h>
+#include <asm/uaccess.h>
+
+#define DEVNAME "pc8736x_gpio"
+
+MODULE_AUTHOR("Jim Cromie <jim.cromie@gmail.com>");
+MODULE_DESCRIPTION("NatSemi/Winbond PC-8736x GPIO Pin Driver");
+MODULE_LICENSE("GPL");
+
+static int major;		/* default to dynamic major */
+module_param(major, int, 0);
+MODULE_PARM_DESC(major, "Major device number");
+
+static DEFINE_MUTEX(pc8736x_gpio_config_lock);
+static unsigned pc8736x_gpio_base;
+static u8 pc8736x_gpio_shadow[4];
+
+#define SIO_BASE1       0x2E	/* 1st command-reg to check */
+#define SIO_BASE2       0x4E	/* alt command-reg to check */
+
+#define SIO_SID		0x20	/* SuperI/O ID Register */
+#define SIO_SID_VALUE	0xe9	/* Expected value in SuperI/O ID Register */
+
+#define SIO_CF1		0x21	/* chip config, bit0 is chip enable */
+
+#define PC8736X_GPIO_RANGE	16 /* ioaddr range */
+#define PC8736X_GPIO_CT		32 /* minors matching 4 8 bit ports */
+
+#define SIO_UNIT_SEL	0x7	/* unit select reg */
+#define SIO_UNIT_ACT	0x30	/* unit enable */
+#define SIO_GPIO_UNIT	0x7	/* unit number of GPIO */
+#define SIO_VLM_UNIT	0x0D
+#define SIO_TMS_UNIT	0x0E
+
+/* config-space addrs to read/write each unit's runtime addr */
+#define SIO_BASE_HADDR		0x60
+#define SIO_BASE_LADDR		0x61
+
+/* GPIO config-space pin-control addresses */
+#define SIO_GPIO_PIN_SELECT	0xF0
+#define SIO_GPIO_PIN_CONFIG     0xF1
+#define SIO_GPIO_PIN_EVENT      0xF2
+
+static unsigned char superio_cmd = 0;
+static unsigned char selected_device = 0xFF;	/* bogus start val */
+
+/* GPIO port runtime access, functionality */
+static int port_offset[] = { 0, 4, 8, 10 };	/* non-uniform offsets ! */
+/* static int event_capable[] = { 1, 1, 0, 0 };   ports 2,3 are hobbled */
+
+#define PORT_OUT	0
+#define PORT_IN		1
+#define PORT_EVT_EN	2
+#define PORT_EVT_STST	3
+
+static struct platform_device *pdev;  /* use in dev_*() */
+
+static inline void superio_outb(int addr, int val)
+{
+	outb_p(addr, superio_cmd);
+	outb_p(val, superio_cmd + 1);
+}
+
+static inline int superio_inb(int addr)
+{
+	outb_p(addr, superio_cmd);
+	return inb_p(superio_cmd + 1);
+}
+
+static int pc8736x_superio_present(void)
+{
+	/* try the 2 possible values, read a hardware reg to verify */
+	superio_cmd = SIO_BASE1;
+	if (superio_inb(SIO_SID) == SIO_SID_VALUE)
+		return superio_cmd;
+
+	superio_cmd = SIO_BASE2;
+	if (superio_inb(SIO_SID) == SIO_SID_VALUE)
+		return superio_cmd;
+
+	return 0;
+}
+
+static void device_select(unsigned devldn)
+{
+	superio_outb(SIO_UNIT_SEL, devldn);
+	selected_device = devldn;
+}
+
+static void select_pin(unsigned iminor)
+{
+	/* select GPIO port/pin from device minor number */
+	device_select(SIO_GPIO_UNIT);
+	superio_outb(SIO_GPIO_PIN_SELECT,
+		     ((iminor << 1) & 0xF0) | (iminor & 0x7));
+}
+
+static inline u32 pc8736x_gpio_configure_fn(unsigned index, u32 mask, u32 bits,
+					    u32 func_slct)
+{
+	u32 config, new_config;
+
+	mutex_lock(&pc8736x_gpio_config_lock);
+
+	device_select(SIO_GPIO_UNIT);
+	select_pin(index);
+
+	/* read current config value */
+	config = superio_inb(func_slct);
+
+	/* set new config */
+	new_config = (config & mask) | bits;
+	superio_outb(func_slct, new_config);
+
+	mutex_unlock(&pc8736x_gpio_config_lock);
+
+	return config;
+}
+
+static u32 pc8736x_gpio_configure(unsigned index, u32 mask, u32 bits)
+{
+	return pc8736x_gpio_configure_fn(index, mask, bits,
+					 SIO_GPIO_PIN_CONFIG);
+}
+
+static int pc8736x_gpio_get(unsigned minor)
+{
+	int port, bit, val;
+
+	port = minor >> 3;
+	bit = minor & 7;
+	val = inb_p(pc8736x_gpio_base + port_offset[port] + PORT_IN);
+	val >>= bit;
+	val &= 1;
+
+	dev_dbg(&pdev->dev, "_gpio_get(%d from %x bit %d) == val %d\n",
+		minor, pc8736x_gpio_base + port_offset[port] + PORT_IN, bit,
+		val);
+
+	return val;
+}
+
+static void pc8736x_gpio_set(unsigned minor, int val)
+{
+	int port, bit, curval;
+
+	minor &= 0x1f;
+	port = minor >> 3;
+	bit = minor & 7;
+	curval = inb_p(pc8736x_gpio_base + port_offset[port] + PORT_OUT);
+
+	dev_dbg(&pdev->dev, "addr:%x cur:%x bit-pos:%d cur-bit:%x + new:%d -> bit-new:%d\n",
+		pc8736x_gpio_base + port_offset[port] + PORT_OUT,
+		curval, bit, (curval & ~(1 << bit)), val, (val << bit));
+
+	val = (curval & ~(1 << bit)) | (val << bit);
+
+	dev_dbg(&pdev->dev, "gpio_set(minor:%d port:%d bit:%d)"
+		" %2x -> %2x\n", minor, port, bit, curval, val);
+
+	outb_p(val, pc8736x_gpio_base + port_offset[port] + PORT_OUT);
+
+	curval = inb_p(pc8736x_gpio_base + port_offset[port] + PORT_OUT);
+	val = inb_p(pc8736x_gpio_base + port_offset[port] + PORT_IN);
+
+	dev_dbg(&pdev->dev, "wrote %x, read: %x\n", curval, val);
+	pc8736x_gpio_shadow[port] = val;
+}
+
+static void pc8736x_gpio_set_high(unsigned index)
+{
+	pc8736x_gpio_set(index, 1);
+}
+
+static void pc8736x_gpio_set_low(unsigned index)
+{
+	pc8736x_gpio_set(index, 0);
+}
+
+static int pc8736x_gpio_current(unsigned minor)
+{
+	int port, bit;
+	minor &= 0x1f;
+	port = minor >> 3;
+	bit = minor & 7;
+	return ((pc8736x_gpio_shadow[port] >> bit) & 0x01);
+}
+
+static void pc8736x_gpio_change(unsigned index)
+{
+	pc8736x_gpio_set(index, !pc8736x_gpio_current(index));
+}
+
+static struct nsc_gpio_ops pc8736x_gpio_ops = {
+	.owner		= THIS_MODULE,
+	.gpio_config	= pc8736x_gpio_configure,
+	.gpio_dump	= nsc_gpio_dump,
+	.gpio_get	= pc8736x_gpio_get,
+	.gpio_set	= pc8736x_gpio_set,
+	.gpio_change	= pc8736x_gpio_change,
+	.gpio_current	= pc8736x_gpio_current
+};
+
+static int pc8736x_gpio_open(struct inode *inode, struct file *file)
+{
+	unsigned m = iminor(inode);
+	file->private_data = &pc8736x_gpio_ops;
+
+	dev_dbg(&pdev->dev, "open %d\n", m);
+
+	if (m >= PC8736X_GPIO_CT)
+		return -EINVAL;
+	return nonseekable_open(inode, file);
+}
+
+static const struct file_operations pc8736x_gpio_fileops = {
+	.owner	= THIS_MODULE,
+	.open	= pc8736x_gpio_open,
+	.write	= nsc_gpio_write,
+	.read	= nsc_gpio_read,
+};
+
+static void __init pc8736x_init_shadow(void)
+{
+	int port;
+
+	/* read the current values driven on the GPIO signals */
+	for (port = 0; port < 4; ++port)
+		pc8736x_gpio_shadow[port]
+		    = inb_p(pc8736x_gpio_base + port_offset[port]
+			    + PORT_OUT);
+
+}
+
+static struct cdev pc8736x_gpio_cdev;
+
+static int __init pc8736x_gpio_init(void)
+{
+	int rc;
+	dev_t devid;
+
+	pdev = platform_device_alloc(DEVNAME, 0);
+	if (!pdev)
+		return -ENOMEM;
+
+	rc = platform_device_add(pdev);
+	if (rc) {
+		rc = -ENODEV;
+		goto undo_platform_dev_alloc;
+	}
+	dev_info(&pdev->dev, "NatSemi pc8736x GPIO Driver Initializing\n");
+
+	if (!pc8736x_superio_present()) {
+		rc = -ENODEV;
+		dev_err(&pdev->dev, "no device found\n");
+		goto undo_platform_dev_add;
+	}
+	pc8736x_gpio_ops.dev = &pdev->dev;
+
+	/* Verify that chip and it's GPIO unit are both enabled.
+	   My BIOS does this, so I take minimum action here
+	 */
+	rc = superio_inb(SIO_CF1);
+	if (!(rc & 0x01)) {
+		rc = -ENODEV;
+		dev_err(&pdev->dev, "device not enabled\n");
+		goto undo_platform_dev_add;
+	}
+	device_select(SIO_GPIO_UNIT);
+	if (!superio_inb(SIO_UNIT_ACT)) {
+		rc = -ENODEV;
+		dev_err(&pdev->dev, "GPIO unit not enabled\n");
+		goto undo_platform_dev_add;
+	}
+
+	/* read the GPIO unit base addr that chip responds to */
+	pc8736x_gpio_base = (superio_inb(SIO_BASE_HADDR) << 8
+			     | superio_inb(SIO_BASE_LADDR));
+
+	if (!request_region(pc8736x_gpio_base, PC8736X_GPIO_RANGE, DEVNAME)) {
+		rc = -ENODEV;
+		dev_err(&pdev->dev, "GPIO ioport %x busy\n",
+			pc8736x_gpio_base);
+		goto undo_platform_dev_add;
+	}
+	dev_info(&pdev->dev, "GPIO ioport %x reserved\n", pc8736x_gpio_base);
+
+	if (major) {
+		devid = MKDEV(major, 0);
+		rc = register_chrdev_region(devid, PC8736X_GPIO_CT, DEVNAME);
+	} else {
+		rc = alloc_chrdev_region(&devid, 0, PC8736X_GPIO_CT, DEVNAME);
+		major = MAJOR(devid);
+	}
+
+	if (rc < 0) {
+		dev_err(&pdev->dev, "register-chrdev failed: %d\n", rc);
+		goto undo_request_region;
+	}
+	if (!major) {
+		major = rc;
+		dev_dbg(&pdev->dev, "got dynamic major %d\n", major);
+	}
+
+	pc8736x_init_shadow();
+
+	/* ignore minor errs, and succeed */
+	cdev_init(&pc8736x_gpio_cdev, &pc8736x_gpio_fileops);
+	cdev_add(&pc8736x_gpio_cdev, devid, PC8736X_GPIO_CT);
+
+	return 0;
+
+undo_request_region:
+	release_region(pc8736x_gpio_base, PC8736X_GPIO_RANGE);
+undo_platform_dev_add:
+	platform_device_del(pdev);
+undo_platform_dev_alloc:
+	platform_device_put(pdev);
+
+	return rc;
+}
+
+static void __exit pc8736x_gpio_cleanup(void)
+{
+	dev_dbg(&pdev->dev, "cleanup\n");
+
+	cdev_del(&pc8736x_gpio_cdev);
+	unregister_chrdev_region(MKDEV(major,0), PC8736X_GPIO_CT);
+	release_region(pc8736x_gpio_base, PC8736X_GPIO_RANGE);
+
+	platform_device_del(pdev);
+	platform_device_put(pdev);
+}
+
+module_init(pc8736x_gpio_init);
+module_exit(pc8736x_gpio_cleanup);
diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile
new file mode 100644
index 000000000..a52225470
--- /dev/null
+++ b/drivers/clocksource/Makefile
@@ -0,0 +1,3 @@
+obj-$(CONFIG_X86_CYCLONE_TIMER)	+= cyclone.o
+obj-$(CONFIG_X86_PM_TIMER)	+= acpi_pm.o
+obj-$(CONFIG_SCx200HR_TIMER)	+= scx200_hrt.o
diff --git a/drivers/clocksource/acpi_pm.c b/drivers/clocksource/acpi_pm.c
new file mode 100644
index 000000000..7ad3be8c0
--- /dev/null
+++ b/drivers/clocksource/acpi_pm.c
@@ -0,0 +1,177 @@
+/*
+ * linux/drivers/clocksource/acpi_pm.c
+ *
+ * This file contains the ACPI PM based clocksource.
+ *
+ * This code was largely moved from the i386 timer_pm.c file
+ * which was (C) Dominik Brodowski <linux@brodo.de> 2003
+ * and contained the following comments:
+ *
+ * Driver to use the Power Management Timer (PMTMR) available in some
+ * southbridges as primary timing source for the Linux kernel.
+ *
+ * Based on parts of linux/drivers/acpi/hardware/hwtimer.c, timer_pit.c,
+ * timer_hpet.c, and on Arjan van de Ven's implementation for 2.4.
+ *
+ * This file is licensed under the GPL v2.
+ */
+
+#include <linux/clocksource.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+#include <asm/io.h>
+
+/* Number of PMTMR ticks expected during calibration run */
+#define PMTMR_TICKS_PER_SEC 3579545
+
+/*
+ * The I/O port the PMTMR resides at.
+ * The location is detected during setup_arch(),
+ * in arch/i386/acpi/boot.c
+ */
+u32 pmtmr_ioport __read_mostly;
+
+#define ACPI_PM_MASK CLOCKSOURCE_MASK(24) /* limit it to 24 bits */
+
+static inline u32 read_pmtmr(void)
+{
+	/* mask the output to 24 bits */
+	return inl(pmtmr_ioport) & ACPI_PM_MASK;
+}
+
+static cycle_t acpi_pm_read_verified(void)
+{
+	u32 v1 = 0, v2 = 0, v3 = 0;
+
+	/*
+	 * It has been reported that because of various broken
+	 * chipsets (ICH4, PIIX4 and PIIX4E) where the ACPI PM clock
+	 * source is not latched, you must read it multiple
+	 * times to ensure a safe value is read:
+	 */
+	do {
+		v1 = read_pmtmr();
+		v2 = read_pmtmr();
+		v3 = read_pmtmr();
+	} while ((v1 > v2 && v1 < v3) || (v2 > v3 && v2 < v1)
+			|| (v3 > v1 && v3 < v2));
+
+	return (cycle_t)v2;
+}
+
+static cycle_t acpi_pm_read(void)
+{
+	return (cycle_t)read_pmtmr();
+}
+
+static struct clocksource clocksource_acpi_pm = {
+	.name		= "acpi_pm",
+	.rating		= 200,
+	.read		= acpi_pm_read,
+	.mask		= (cycle_t)ACPI_PM_MASK,
+	.mult		= 0, /*to be caluclated*/
+	.shift		= 22,
+	.is_continuous	= 1,
+};
+
+
+#ifdef CONFIG_PCI
+static int acpi_pm_good;
+static int __init acpi_pm_good_setup(char *__str)
+{
+       acpi_pm_good = 1;
+       return 1;
+}
+__setup("acpi_pm_good", acpi_pm_good_setup);
+
+static inline void acpi_pm_need_workaround(void)
+{
+	clocksource_acpi_pm.read = acpi_pm_read_verified;
+	clocksource_acpi_pm.rating = 110;
+}
+
+/*
+ * PIIX4 Errata:
+ *
+ * The power management timer may return improper results when read.
+ * Although the timer value settles properly after incrementing,
+ * while incrementing there is a 3 ns window every 69.8 ns where the
+ * timer value is indeterminate (a 4.2% chance that the data will be
+ * incorrect when read). As a result, the ACPI free running count up
+ * timer specification is violated due to erroneous reads.
+ */
+static void __devinit acpi_pm_check_blacklist(struct pci_dev *dev)
+{
+	u8 rev;
+
+	if (acpi_pm_good)
+		return;
+
+	pci_read_config_byte(dev, PCI_REVISION_ID, &rev);
+	/* the bug has been fixed in PIIX4M */
+	if (rev < 3) {
+		printk(KERN_WARNING "* Found PM-Timer Bug on the chipset."
+		       " Due to workarounds for a bug,\n"
+		       "* this clock source is slow. Consider trying"
+		       " other clock sources\n");
+
+		acpi_pm_need_workaround();
+	}
+}
+DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB_3,
+			acpi_pm_check_blacklist);
+
+static void __devinit acpi_pm_check_graylist(struct pci_dev *dev)
+{
+	if (acpi_pm_good)
+		return;
+
+	printk(KERN_WARNING "* The chipset may have PM-Timer Bug. Due to"
+	       " workarounds for a bug,\n"
+	       "* this clock source is slow. If you are sure your timer"
+	       " does not have\n"
+	       "* this bug, please use \"acpi_pm_good\" to disable the"
+	       " workaround\n");
+
+	acpi_pm_need_workaround();
+}
+DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_0,
+			acpi_pm_check_graylist);
+#endif
+
+
+static int __init init_acpi_pm_clocksource(void)
+{
+	u32 value1, value2;
+	unsigned int i;
+
+	if (!pmtmr_ioport)
+		return -ENODEV;
+
+	clocksource_acpi_pm.mult = clocksource_hz2mult(PMTMR_TICKS_PER_SEC,
+						clocksource_acpi_pm.shift);
+
+	/* "verify" this timing source: */
+	value1 = read_pmtmr();
+	for (i = 0; i < 10000; i++) {
+		value2 = read_pmtmr();
+		if (value2 == value1)
+			continue;
+		if (value2 > value1)
+			goto pm_good;
+		if ((value2 < value1) && ((value2) < 0xFFF))
+			goto pm_good;
+		printk(KERN_INFO "PM-Timer had inconsistent results:"
+			" 0x%#x, 0x%#x - aborting.\n", value1, value2);
+		return -EINVAL;
+	}
+	printk(KERN_INFO "PM-Timer had no reasonable result:"
+			" 0x%#x - aborting.\n", value1);
+	return -ENODEV;
+
+pm_good:
+	return clocksource_register(&clocksource_acpi_pm);
+}
+
+module_init(init_acpi_pm_clocksource);
diff --git a/drivers/clocksource/cyclone.c b/drivers/clocksource/cyclone.c
new file mode 100644
index 000000000..bf4d3d50d
--- /dev/null
+++ b/drivers/clocksource/cyclone.c
@@ -0,0 +1,119 @@
+#include <linux/clocksource.h>
+#include <linux/string.h>
+#include <linux/errno.h>
+#include <linux/timex.h>
+#include <linux/init.h>
+
+#include <asm/pgtable.h>
+#include <asm/io.h>
+
+#include "mach_timer.h"
+
+#define CYCLONE_CBAR_ADDR	0xFEB00CD0	/* base address ptr */
+#define CYCLONE_PMCC_OFFSET	0x51A0		/* offset to control register */
+#define CYCLONE_MPCS_OFFSET	0x51A8		/* offset to select register */
+#define CYCLONE_MPMC_OFFSET	0x51D0		/* offset to count register */
+#define CYCLONE_TIMER_FREQ	99780000	/* 100Mhz, but not really */
+#define CYCLONE_TIMER_MASK	CLOCKSOURCE_MASK(32) /* 32 bit mask */
+
+int use_cyclone = 0;
+static void __iomem *cyclone_ptr;
+
+static cycle_t read_cyclone(void)
+{
+	return (cycle_t)readl(cyclone_ptr);
+}
+
+static struct clocksource clocksource_cyclone = {
+	.name		= "cyclone",
+	.rating		= 250,
+	.read		= read_cyclone,
+	.mask		= CYCLONE_TIMER_MASK,
+	.mult		= 10,
+	.shift		= 0,
+	.is_continuous	= 1,
+};
+
+static int __init init_cyclone_clocksource(void)
+{
+	unsigned long base;	/* saved value from CBAR */
+	unsigned long offset;
+	u32 __iomem* volatile cyclone_timer;	/* Cyclone MPMC0 register */
+	u32 __iomem* reg;
+	int i;
+
+	/* make sure we're on a summit box: */
+	if (!use_cyclone)
+		return -ENODEV;
+
+	printk(KERN_INFO "Summit chipset: Starting Cyclone Counter.\n");
+
+	/* find base address: */
+	offset = CYCLONE_CBAR_ADDR;
+	reg = ioremap_nocache(offset, sizeof(reg));
+	if (!reg) {
+		printk(KERN_ERR "Summit chipset: Could not find valid CBAR register.\n");
+		return -ENODEV;
+	}
+	/* even on 64bit systems, this is only 32bits: */
+	base = readl(reg);
+	if (!base) {
+		printk(KERN_ERR "Summit chipset: Could not find valid CBAR value.\n");
+		return -ENODEV;
+	}
+	iounmap(reg);
+
+	/* setup PMCC: */
+	offset = base + CYCLONE_PMCC_OFFSET;
+	reg = ioremap_nocache(offset, sizeof(reg));
+	if (!reg) {
+		printk(KERN_ERR "Summit chipset: Could not find valid PMCC register.\n");
+		return -ENODEV;
+	}
+	writel(0x00000001,reg);
+	iounmap(reg);
+
+	/* setup MPCS: */
+	offset = base + CYCLONE_MPCS_OFFSET;
+	reg = ioremap_nocache(offset, sizeof(reg));
+	if (!reg) {
+		printk(KERN_ERR "Summit chipset: Could not find valid MPCS register.\n");
+		return -ENODEV;
+	}
+	writel(0x00000001,reg);
+	iounmap(reg);
+
+	/* map in cyclone_timer: */
+	offset = base + CYCLONE_MPMC_OFFSET;
+	cyclone_timer = ioremap_nocache(offset, sizeof(u64));
+	if (!cyclone_timer) {
+		printk(KERN_ERR "Summit chipset: Could not find valid MPMC register.\n");
+		return -ENODEV;
+	}
+
+	/* quick test to make sure its ticking: */
+	for (i = 0; i < 3; i++){
+		u32 old = readl(cyclone_timer);
+		int stall = 100;
+
+		while (stall--)
+			barrier();
+
+		if (readl(cyclone_timer) == old) {
+			printk(KERN_ERR "Summit chipset: Counter not counting! DISABLED\n");
+			iounmap(cyclone_timer);
+			cyclone_timer = NULL;
+			return -ENODEV;
+		}
+	}
+	cyclone_ptr = cyclone_timer;
+
+	/* sort out mult/shift values: */
+	clocksource_cyclone.shift = 22;
+	clocksource_cyclone.mult = clocksource_hz2mult(CYCLONE_TIMER_FREQ,
+						clocksource_cyclone.shift);
+
+	return clocksource_register(&clocksource_cyclone);
+}
+
+module_init(init_cyclone_clocksource);
diff --git a/drivers/clocksource/scx200_hrt.c b/drivers/clocksource/scx200_hrt.c
new file mode 100644
index 000000000..22915cc46
--- /dev/null
+++ b/drivers/clocksource/scx200_hrt.c
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2006 Jim Cromie
+ *
+ * This is a clocksource driver for the Geode SCx200's 1 or 27 MHz
+ * high-resolution timer.  The Geode SC-1100 (at least) has a buggy
+ * time stamp counter (TSC), which loses time unless 'idle=poll' is
+ * given as a boot-arg. In its absence, the Generic Timekeeping code
+ * will detect and de-rate the bad TSC, allowing this timer to take
+ * over timekeeping duties.
+ *
+ * Based on work by John Stultz, and Ted Phelps (in a 2.6.12-rc6 patch)
+ *
+ * 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/clocksource.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/ioport.h>
+#include <linux/scx200.h>
+
+#define NAME "scx200_hrt"
+
+static int mhz27;
+module_param(mhz27, int, 0);	/* load time only */
+MODULE_PARM_DESC(mhz27, "count at 27.0 MHz (default is 1.0 MHz)");
+
+static int ppm;
+module_param(ppm, int, 0);	/* load time only */
+MODULE_PARM_DESC(ppm, "+-adjust to actual XO freq (ppm)");
+
+/* HiRes Timer configuration register address */
+#define SCx200_TMCNFG_OFFSET (SCx200_TIMER_OFFSET + 5)
+
+/* and config settings */
+#define HR_TMEN (1 << 0)	/* timer interrupt enable */
+#define HR_TMCLKSEL (1 << 1)	/* 1|0 counts at 27|1 MHz */
+#define HR_TM27MPD (1 << 2)	/* 1 turns off input clock (power-down) */
+
+/* The base timer frequency, * 27 if selected */
+#define HRT_FREQ   1000000
+
+static cycle_t read_hrt(void)
+{
+	/* Read the timer value */
+	return (cycle_t) inl(scx200_cb_base + SCx200_TIMER_OFFSET);
+}
+
+#define HRT_SHIFT_1	22
+#define HRT_SHIFT_27	26
+
+static struct clocksource cs_hrt = {
+	.name		= "scx200_hrt",
+	.rating		= 250,
+	.read		= read_hrt,
+	.mask		= CLOCKSOURCE_MASK(32),
+	.is_continuous	= 1,
+	/* mult, shift are set based on mhz27 flag */
+};
+
+static int __init init_hrt_clocksource(void)
+{
+	/* Make sure scx200 has initialized the configuration block */
+	if (!scx200_cb_present())
+		return -ENODEV;
+
+	/* Reserve the timer's ISA io-region for ourselves */
+	if (!request_region(scx200_cb_base + SCx200_TIMER_OFFSET,
+			    SCx200_TIMER_SIZE,
+			    "NatSemi SCx200 High-Resolution Timer")) {
+		printk(KERN_WARNING NAME ": unable to lock timer region\n");
+		return -ENODEV;
+	}
+
+	/* write timer config */
+	outb(HR_TMEN | (mhz27 ? HR_TMCLKSEL : 0),
+	     scx200_cb_base + SCx200_TMCNFG_OFFSET);
+
+	if (mhz27) {
+		cs_hrt.shift = HRT_SHIFT_27;
+		cs_hrt.mult = clocksource_hz2mult((HRT_FREQ + ppm) * 27,
+						  cs_hrt.shift);
+	} else {
+		cs_hrt.shift = HRT_SHIFT_1;
+		cs_hrt.mult = clocksource_hz2mult(HRT_FREQ + ppm,
+						  cs_hrt.shift);
+	}
+	printk(KERN_INFO "enabling scx200 high-res timer (%s MHz +%d ppm)\n",
+		mhz27 ? "27":"1", ppm);
+
+	return clocksource_register(&cs_hrt);
+}
+
+module_init(init_hrt_clocksource);
+
+MODULE_AUTHOR("Jim Cromie <jim.cromie@gmail.com>");
+MODULE_DESCRIPTION("clocksource on SCx200 HiRes Timer");
+MODULE_LICENSE("GPL");
diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
new file mode 100644
index 000000000..30d021d1a
--- /dev/null
+++ b/drivers/dma/Kconfig
@@ -0,0 +1,34 @@
+#
+# DMA engine configuration
+#
+
+menu "DMA Engine support"
+
+config DMA_ENGINE
+	bool "Support for DMA engines"
+	---help---
+	  DMA engines offload copy operations from the CPU to dedicated
+	  hardware, allowing the copies to happen asynchronously.
+
+comment "DMA Clients"
+
+config NET_DMA
+	bool "Network: TCP receive copy offload"
+	depends on DMA_ENGINE && NET
+	default y
+	---help---
+	  This enables the use of DMA engines in the network stack to
+	  offload receive copy-to-user operations, freeing CPU cycles.
+	  Since this is the main user of the DMA engine, it should be enabled;
+	  say Y here.
+
+comment "DMA Devices"
+
+config INTEL_IOATDMA
+	tristate "Intel I/OAT DMA support"
+	depends on DMA_ENGINE && PCI
+	default m
+	---help---
+	  Enable support for the Intel(R) I/OAT DMA engine.
+
+endmenu
diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile
new file mode 100644
index 000000000..bdcfdbdb1
--- /dev/null
+++ b/drivers/dma/Makefile
@@ -0,0 +1,3 @@
+obj-$(CONFIG_DMA_ENGINE) += dmaengine.o
+obj-$(CONFIG_NET_DMA) += iovlock.o
+obj-$(CONFIG_INTEL_IOATDMA) += ioatdma.o
diff --git a/drivers/dma/dmaengine.c b/drivers/dma/dmaengine.c
new file mode 100644
index 000000000..152780442
--- /dev/null
+++ b/drivers/dma/dmaengine.c
@@ -0,0 +1,412 @@
+/*
+ * Copyright(c) 2004 - 2006 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59
+ * Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called COPYING.
+ */
+
+/*
+ * This code implements the DMA subsystem. It provides a HW-neutral interface
+ * for other kernel code to use asynchronous memory copy capabilities,
+ * if present, and allows different HW DMA drivers to register as providing
+ * this capability.
+ *
+ * Due to the fact we are accelerating what is already a relatively fast
+ * operation, the code goes to great lengths to avoid additional overhead,
+ * such as locking.
+ *
+ * LOCKING:
+ *
+ * The subsystem keeps two global lists, dma_device_list and dma_client_list.
+ * Both of these are protected by a mutex, dma_list_mutex.
+ *
+ * Each device has a channels list, which runs unlocked but is never modified
+ * once the device is registered, it's just setup by the driver.
+ *
+ * Each client has a channels list, it's only modified under the client->lock
+ * and in an RCU callback, so it's safe to read under rcu_read_lock().
+ *
+ * Each device has a kref, which is initialized to 1 when the device is
+ * registered. A kref_put is done for each class_device registered.  When the
+ * class_device is released, the coresponding kref_put is done in the release
+ * method. Every time one of the device's channels is allocated to a client,
+ * a kref_get occurs.  When the channel is freed, the coresponding kref_put
+ * happens. The device's release function does a completion, so
+ * unregister_device does a remove event, class_device_unregister, a kref_put
+ * for the first reference, then waits on the completion for all other
+ * references to finish.
+ *
+ * Each channel has an open-coded implementation of Rusty Russell's "bigref,"
+ * with a kref and a per_cpu local_t.  A single reference is set when on an
+ * ADDED event, and removed with a REMOVE event.  Net DMA client takes an
+ * extra reference per outstanding transaction.  The relase function does a
+ * kref_put on the device. -ChrisL
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/dmaengine.h>
+#include <linux/hardirq.h>
+#include <linux/spinlock.h>
+#include <linux/percpu.h>
+#include <linux/rcupdate.h>
+#include <linux/mutex.h>
+
+static DEFINE_MUTEX(dma_list_mutex);
+static LIST_HEAD(dma_device_list);
+static LIST_HEAD(dma_client_list);
+
+/* --- sysfs implementation --- */
+
+static ssize_t show_memcpy_count(struct class_device *cd, char *buf)
+{
+	struct dma_chan *chan = container_of(cd, struct dma_chan, class_dev);
+	unsigned long count = 0;
+	int i;
+
+	for_each_possible_cpu(i)
+		count += per_cpu_ptr(chan->local, i)->memcpy_count;
+
+	return sprintf(buf, "%lu\n", count);
+}
+
+static ssize_t show_bytes_transferred(struct class_device *cd, char *buf)
+{
+	struct dma_chan *chan = container_of(cd, struct dma_chan, class_dev);
+	unsigned long count = 0;
+	int i;
+
+	for_each_possible_cpu(i)
+		count += per_cpu_ptr(chan->local, i)->bytes_transferred;
+
+	return sprintf(buf, "%lu\n", count);
+}
+
+static ssize_t show_in_use(struct class_device *cd, char *buf)
+{
+	struct dma_chan *chan = container_of(cd, struct dma_chan, class_dev);
+
+	return sprintf(buf, "%d\n", (chan->client ? 1 : 0));
+}
+
+static struct class_device_attribute dma_class_attrs[] = {
+	__ATTR(memcpy_count, S_IRUGO, show_memcpy_count, NULL),
+	__ATTR(bytes_transferred, S_IRUGO, show_bytes_transferred, NULL),
+	__ATTR(in_use, S_IRUGO, show_in_use, NULL),
+	__ATTR_NULL
+};
+
+static void dma_async_device_cleanup(struct kref *kref);
+
+static void dma_class_dev_release(struct class_device *cd)
+{
+	struct dma_chan *chan = container_of(cd, struct dma_chan, class_dev);
+	kref_put(&chan->device->refcount, dma_async_device_cleanup);
+}
+
+static struct class dma_devclass = {
+	.name            = "dma",
+	.class_dev_attrs = dma_class_attrs,
+	.release = dma_class_dev_release,
+};
+
+/* --- client and device registration --- */
+
+/**
+ * dma_client_chan_alloc - try to allocate a channel to a client
+ * @client: &dma_client
+ *
+ * Called with dma_list_mutex held.
+ */
+static struct dma_chan *dma_client_chan_alloc(struct dma_client *client)
+{
+	struct dma_device *device;
+	struct dma_chan *chan;
+	unsigned long flags;
+	int desc;	/* allocated descriptor count */
+
+	/* Find a channel, any DMA engine will do */
+	list_for_each_entry(device, &dma_device_list, global_node) {
+		list_for_each_entry(chan, &device->channels, device_node) {
+			if (chan->client)
+				continue;
+
+			desc = chan->device->device_alloc_chan_resources(chan);
+			if (desc >= 0) {
+				kref_get(&device->refcount);
+				kref_init(&chan->refcount);
+				chan->slow_ref = 0;
+				INIT_RCU_HEAD(&chan->rcu);
+				chan->client = client;
+				spin_lock_irqsave(&client->lock, flags);
+				list_add_tail_rcu(&chan->client_node,
+				                  &client->channels);
+				spin_unlock_irqrestore(&client->lock, flags);
+				return chan;
+			}
+		}
+	}
+
+	return NULL;
+}
+
+/**
+ * dma_chan_cleanup - release a DMA channel's resources
+ * @kref: kernel reference structure that contains the DMA channel device
+ */
+void dma_chan_cleanup(struct kref *kref)
+{
+	struct dma_chan *chan = container_of(kref, struct dma_chan, refcount);
+	chan->device->device_free_chan_resources(chan);
+	chan->client = NULL;
+	kref_put(&chan->device->refcount, dma_async_device_cleanup);
+}
+
+static void dma_chan_free_rcu(struct rcu_head *rcu)
+{
+	struct dma_chan *chan = container_of(rcu, struct dma_chan, rcu);
+	int bias = 0x7FFFFFFF;
+	int i;
+	for_each_possible_cpu(i)
+		bias -= local_read(&per_cpu_ptr(chan->local, i)->refcount);
+	atomic_sub(bias, &chan->refcount.refcount);
+	kref_put(&chan->refcount, dma_chan_cleanup);
+}
+
+static void dma_client_chan_free(struct dma_chan *chan)
+{
+	atomic_add(0x7FFFFFFF, &chan->refcount.refcount);
+	chan->slow_ref = 1;
+	call_rcu(&chan->rcu, dma_chan_free_rcu);
+}
+
+/**
+ * dma_chans_rebalance - reallocate channels to clients
+ *
+ * When the number of DMA channel in the system changes,
+ * channels need to be rebalanced among clients.
+ */
+static void dma_chans_rebalance(void)
+{
+	struct dma_client *client;
+	struct dma_chan *chan;
+	unsigned long flags;
+
+	mutex_lock(&dma_list_mutex);
+
+	list_for_each_entry(client, &dma_client_list, global_node) {
+		while (client->chans_desired > client->chan_count) {
+			chan = dma_client_chan_alloc(client);
+			if (!chan)
+				break;
+			client->chan_count++;
+			client->event_callback(client,
+	                                       chan,
+	                                       DMA_RESOURCE_ADDED);
+		}
+		while (client->chans_desired < client->chan_count) {
+			spin_lock_irqsave(&client->lock, flags);
+			chan = list_entry(client->channels.next,
+			                  struct dma_chan,
+			                  client_node);
+			list_del_rcu(&chan->client_node);
+			spin_unlock_irqrestore(&client->lock, flags);
+			client->chan_count--;
+			client->event_callback(client,
+			                       chan,
+			                       DMA_RESOURCE_REMOVED);
+			dma_client_chan_free(chan);
+		}
+	}
+
+	mutex_unlock(&dma_list_mutex);
+}
+
+/**
+ * dma_async_client_register - allocate and register a &dma_client
+ * @event_callback: callback for notification of channel addition/removal
+ */
+struct dma_client *dma_async_client_register(dma_event_callback event_callback)
+{
+	struct dma_client *client;
+
+	client = kzalloc(sizeof(*client), GFP_KERNEL);
+	if (!client)
+		return NULL;
+
+	INIT_LIST_HEAD(&client->channels);
+	spin_lock_init(&client->lock);
+	client->chans_desired = 0;
+	client->chan_count = 0;
+	client->event_callback = event_callback;
+
+	mutex_lock(&dma_list_mutex);
+	list_add_tail(&client->global_node, &dma_client_list);
+	mutex_unlock(&dma_list_mutex);
+
+	return client;
+}
+
+/**
+ * dma_async_client_unregister - unregister a client and free the &dma_client
+ * @client: &dma_client to free
+ *
+ * Force frees any allocated DMA channels, frees the &dma_client memory
+ */
+void dma_async_client_unregister(struct dma_client *client)
+{
+	struct dma_chan *chan;
+
+	if (!client)
+		return;
+
+	rcu_read_lock();
+	list_for_each_entry_rcu(chan, &client->channels, client_node)
+		dma_client_chan_free(chan);
+	rcu_read_unlock();
+
+	mutex_lock(&dma_list_mutex);
+	list_del(&client->global_node);
+	mutex_unlock(&dma_list_mutex);
+
+	kfree(client);
+	dma_chans_rebalance();
+}
+
+/**
+ * dma_async_client_chan_request - request DMA channels
+ * @client: &dma_client
+ * @number: count of DMA channels requested
+ *
+ * Clients call dma_async_client_chan_request() to specify how many
+ * DMA channels they need, 0 to free all currently allocated.
+ * The resulting allocations/frees are indicated to the client via the
+ * event callback.
+ */
+void dma_async_client_chan_request(struct dma_client *client,
+			unsigned int number)
+{
+	client->chans_desired = number;
+	dma_chans_rebalance();
+}
+
+/**
+ * dma_async_device_register - registers DMA devices found
+ * @device: &dma_device
+ */
+int dma_async_device_register(struct dma_device *device)
+{
+	static int id;
+	int chancnt = 0;
+	struct dma_chan* chan;
+
+	if (!device)
+		return -ENODEV;
+
+	init_completion(&device->done);
+	kref_init(&device->refcount);
+	device->dev_id = id++;
+
+	/* represent channels in sysfs. Probably want devs too */
+	list_for_each_entry(chan, &device->channels, device_node) {
+		chan->local = alloc_percpu(typeof(*chan->local));
+		if (chan->local == NULL)
+			continue;
+
+		chan->chan_id = chancnt++;
+		chan->class_dev.class = &dma_devclass;
+		chan->class_dev.dev = NULL;
+		snprintf(chan->class_dev.class_id, BUS_ID_SIZE, "dma%dchan%d",
+		         device->dev_id, chan->chan_id);
+
+		kref_get(&device->refcount);
+		class_device_register(&chan->class_dev);
+	}
+
+	mutex_lock(&dma_list_mutex);
+	list_add_tail(&device->global_node, &dma_device_list);
+	mutex_unlock(&dma_list_mutex);
+
+	dma_chans_rebalance();
+
+	return 0;
+}
+
+/**
+ * dma_async_device_cleanup - function called when all references are released
+ * @kref: kernel reference object
+ */
+static void dma_async_device_cleanup(struct kref *kref)
+{
+	struct dma_device *device;
+
+	device = container_of(kref, struct dma_device, refcount);
+	complete(&device->done);
+}
+
+/**
+ * dma_async_device_unregister - unregisters DMA devices
+ * @device: &dma_device
+ */
+void dma_async_device_unregister(struct dma_device *device)
+{
+	struct dma_chan *chan;
+	unsigned long flags;
+
+	mutex_lock(&dma_list_mutex);
+	list_del(&device->global_node);
+	mutex_unlock(&dma_list_mutex);
+
+	list_for_each_entry(chan, &device->channels, device_node) {
+		if (chan->client) {
+			spin_lock_irqsave(&chan->client->lock, flags);
+			list_del(&chan->client_node);
+			chan->client->chan_count--;
+			spin_unlock_irqrestore(&chan->client->lock, flags);
+			chan->client->event_callback(chan->client,
+			                             chan,
+			                             DMA_RESOURCE_REMOVED);
+			dma_client_chan_free(chan);
+		}
+		class_device_unregister(&chan->class_dev);
+	}
+	dma_chans_rebalance();
+
+	kref_put(&device->refcount, dma_async_device_cleanup);
+	wait_for_completion(&device->done);
+}
+
+static int __init dma_bus_init(void)
+{
+	mutex_init(&dma_list_mutex);
+	return class_register(&dma_devclass);
+}
+
+subsys_initcall(dma_bus_init);
+
+EXPORT_SYMBOL(dma_async_client_register);
+EXPORT_SYMBOL(dma_async_client_unregister);
+EXPORT_SYMBOL(dma_async_client_chan_request);
+EXPORT_SYMBOL(dma_async_memcpy_buf_to_buf);
+EXPORT_SYMBOL(dma_async_memcpy_buf_to_pg);
+EXPORT_SYMBOL(dma_async_memcpy_pg_to_pg);
+EXPORT_SYMBOL(dma_async_memcpy_complete);
+EXPORT_SYMBOL(dma_async_memcpy_issue_pending);
+EXPORT_SYMBOL(dma_async_device_register);
+EXPORT_SYMBOL(dma_async_device_unregister);
+EXPORT_SYMBOL(dma_chan_cleanup);
diff --git a/drivers/dma/ioatdma.c b/drivers/dma/ioatdma.c
new file mode 100644
index 000000000..dbd4d6c36
--- /dev/null
+++ b/drivers/dma/ioatdma.c
@@ -0,0 +1,841 @@
+/*
+ * Copyright(c) 2004 - 2006 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59
+ * Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called COPYING.
+ */
+
+/*
+ * This driver supports an Intel I/OAT DMA engine, which does asynchronous
+ * copy operations.
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/interrupt.h>
+#include <linux/dmaengine.h>
+#include <linux/delay.h>
+#include <linux/dma-mapping.h>
+#include "ioatdma.h"
+#include "ioatdma_io.h"
+#include "ioatdma_registers.h"
+#include "ioatdma_hw.h"
+
+#define to_ioat_chan(chan) container_of(chan, struct ioat_dma_chan, common)
+#define to_ioat_device(dev) container_of(dev, struct ioat_device, common)
+#define to_ioat_desc(lh) container_of(lh, struct ioat_desc_sw, node)
+
+/* internal functions */
+static int __devinit ioat_probe(struct pci_dev *pdev, const struct pci_device_id *ent);
+static void __devexit ioat_remove(struct pci_dev *pdev);
+
+static int enumerate_dma_channels(struct ioat_device *device)
+{
+	u8 xfercap_scale;
+	u32 xfercap;
+	int i;
+	struct ioat_dma_chan *ioat_chan;
+
+	device->common.chancnt = ioatdma_read8(device, IOAT_CHANCNT_OFFSET);
+	xfercap_scale = ioatdma_read8(device, IOAT_XFERCAP_OFFSET);
+	xfercap = (xfercap_scale == 0 ? -1 : (1UL << xfercap_scale));
+
+	for (i = 0; i < device->common.chancnt; i++) {
+		ioat_chan = kzalloc(sizeof(*ioat_chan), GFP_KERNEL);
+		if (!ioat_chan) {
+			device->common.chancnt = i;
+			break;
+		}
+
+		ioat_chan->device = device;
+		ioat_chan->reg_base = device->reg_base + (0x80 * (i + 1));
+		ioat_chan->xfercap = xfercap;
+		spin_lock_init(&ioat_chan->cleanup_lock);
+		spin_lock_init(&ioat_chan->desc_lock);
+		INIT_LIST_HEAD(&ioat_chan->free_desc);
+		INIT_LIST_HEAD(&ioat_chan->used_desc);
+		/* This should be made common somewhere in dmaengine.c */
+		ioat_chan->common.device = &device->common;
+		ioat_chan->common.client = NULL;
+		list_add_tail(&ioat_chan->common.device_node,
+		              &device->common.channels);
+	}
+	return device->common.chancnt;
+}
+
+static struct ioat_desc_sw *ioat_dma_alloc_descriptor(
+	struct ioat_dma_chan *ioat_chan,
+	int flags)
+{
+	struct ioat_dma_descriptor *desc;
+	struct ioat_desc_sw *desc_sw;
+	struct ioat_device *ioat_device;
+	dma_addr_t phys;
+
+	ioat_device = to_ioat_device(ioat_chan->common.device);
+	desc = pci_pool_alloc(ioat_device->dma_pool, flags, &phys);
+	if (unlikely(!desc))
+		return NULL;
+
+	desc_sw = kzalloc(sizeof(*desc_sw), flags);
+	if (unlikely(!desc_sw)) {
+		pci_pool_free(ioat_device->dma_pool, desc, phys);
+		return NULL;
+	}
+
+	memset(desc, 0, sizeof(*desc));
+	desc_sw->hw = desc;
+	desc_sw->phys = phys;
+
+	return desc_sw;
+}
+
+#define INITIAL_IOAT_DESC_COUNT 128
+
+static void ioat_start_null_desc(struct ioat_dma_chan *ioat_chan);
+
+/* returns the actual number of allocated descriptors */
+static int ioat_dma_alloc_chan_resources(struct dma_chan *chan)
+{
+	struct ioat_dma_chan *ioat_chan = to_ioat_chan(chan);
+	struct ioat_desc_sw *desc = NULL;
+	u16 chanctrl;
+	u32 chanerr;
+	int i;
+	LIST_HEAD(tmp_list);
+
+	/*
+	 * In-use bit automatically set by reading chanctrl
+	 * If 0, we got it, if 1, someone else did
+	 */
+	chanctrl = ioatdma_chan_read16(ioat_chan, IOAT_CHANCTRL_OFFSET);
+	if (chanctrl & IOAT_CHANCTRL_CHANNEL_IN_USE)
+		return -EBUSY;
+
+        /* Setup register to interrupt and write completion status on error */
+	chanctrl = IOAT_CHANCTRL_CHANNEL_IN_USE |
+		IOAT_CHANCTRL_ERR_INT_EN |
+		IOAT_CHANCTRL_ANY_ERR_ABORT_EN |
+		IOAT_CHANCTRL_ERR_COMPLETION_EN;
+        ioatdma_chan_write16(ioat_chan, IOAT_CHANCTRL_OFFSET, chanctrl);
+
+	chanerr = ioatdma_chan_read32(ioat_chan, IOAT_CHANERR_OFFSET);
+	if (chanerr) {
+		printk("IOAT: CHANERR = %x, clearing\n", chanerr);
+		ioatdma_chan_write32(ioat_chan, IOAT_CHANERR_OFFSET, chanerr);
+	}
+
+	/* Allocate descriptors */
+	for (i = 0; i < INITIAL_IOAT_DESC_COUNT; i++) {
+		desc = ioat_dma_alloc_descriptor(ioat_chan, GFP_KERNEL);
+		if (!desc) {
+			printk(KERN_ERR "IOAT: Only %d initial descriptors\n", i);
+			break;
+		}
+		list_add_tail(&desc->node, &tmp_list);
+	}
+	spin_lock_bh(&ioat_chan->desc_lock);
+	list_splice(&tmp_list, &ioat_chan->free_desc);
+	spin_unlock_bh(&ioat_chan->desc_lock);
+
+	/* allocate a completion writeback area */
+	/* doing 2 32bit writes to mmio since 1 64b write doesn't work */
+	ioat_chan->completion_virt =
+		pci_pool_alloc(ioat_chan->device->completion_pool,
+		               GFP_KERNEL,
+		               &ioat_chan->completion_addr);
+	memset(ioat_chan->completion_virt, 0,
+	       sizeof(*ioat_chan->completion_virt));
+	ioatdma_chan_write32(ioat_chan, IOAT_CHANCMP_OFFSET_LOW,
+	               ((u64) ioat_chan->completion_addr) & 0x00000000FFFFFFFF);
+	ioatdma_chan_write32(ioat_chan, IOAT_CHANCMP_OFFSET_HIGH,
+	               ((u64) ioat_chan->completion_addr) >> 32);
+
+	ioat_start_null_desc(ioat_chan);
+	return i;
+}
+
+static void ioat_dma_memcpy_cleanup(struct ioat_dma_chan *ioat_chan);
+
+static void ioat_dma_free_chan_resources(struct dma_chan *chan)
+{
+	struct ioat_dma_chan *ioat_chan = to_ioat_chan(chan);
+	struct ioat_device *ioat_device = to_ioat_device(chan->device);
+	struct ioat_desc_sw *desc, *_desc;
+	u16 chanctrl;
+	int in_use_descs = 0;
+
+	ioat_dma_memcpy_cleanup(ioat_chan);
+
+	ioatdma_chan_write8(ioat_chan, IOAT_CHANCMD_OFFSET, IOAT_CHANCMD_RESET);
+
+	spin_lock_bh(&ioat_chan->desc_lock);
+	list_for_each_entry_safe(desc, _desc, &ioat_chan->used_desc, node) {
+		in_use_descs++;
+		list_del(&desc->node);
+		pci_pool_free(ioat_device->dma_pool, desc->hw, desc->phys);
+		kfree(desc);
+	}
+	list_for_each_entry_safe(desc, _desc, &ioat_chan->free_desc, node) {
+		list_del(&desc->node);
+		pci_pool_free(ioat_device->dma_pool, desc->hw, desc->phys);
+		kfree(desc);
+	}
+	spin_unlock_bh(&ioat_chan->desc_lock);
+
+	pci_pool_free(ioat_device->completion_pool,
+	              ioat_chan->completion_virt,
+	              ioat_chan->completion_addr);
+
+	/* one is ok since we left it on there on purpose */
+	if (in_use_descs > 1)
+		printk(KERN_ERR "IOAT: Freeing %d in use descriptors!\n",
+			in_use_descs - 1);
+
+	ioat_chan->last_completion = ioat_chan->completion_addr = 0;
+
+	/* Tell hw the chan is free */
+	chanctrl = ioatdma_chan_read16(ioat_chan, IOAT_CHANCTRL_OFFSET);
+	chanctrl &= ~IOAT_CHANCTRL_CHANNEL_IN_USE;
+	ioatdma_chan_write16(ioat_chan, IOAT_CHANCTRL_OFFSET, chanctrl);
+}
+
+/**
+ * do_ioat_dma_memcpy - actual function that initiates a IOAT DMA transaction
+ * @ioat_chan: IOAT DMA channel handle
+ * @dest: DMA destination address
+ * @src: DMA source address
+ * @len: transaction length in bytes
+ */
+
+static dma_cookie_t do_ioat_dma_memcpy(struct ioat_dma_chan *ioat_chan,
+                                       dma_addr_t dest,
+                                       dma_addr_t src,
+                                       size_t len)
+{
+	struct ioat_desc_sw *first;
+	struct ioat_desc_sw *prev;
+	struct ioat_desc_sw *new;
+	dma_cookie_t cookie;
+	LIST_HEAD(new_chain);
+	u32 copy;
+	size_t orig_len;
+	dma_addr_t orig_src, orig_dst;
+	unsigned int desc_count = 0;
+	unsigned int append = 0;
+
+	if (!ioat_chan || !dest || !src)
+		return -EFAULT;
+
+	if (!len)
+		return ioat_chan->common.cookie;
+
+	orig_len = len;
+	orig_src = src;
+	orig_dst = dest;
+
+	first = NULL;
+	prev = NULL;
+
+	spin_lock_bh(&ioat_chan->desc_lock);
+
+	while (len) {
+		if (!list_empty(&ioat_chan->free_desc)) {
+			new = to_ioat_desc(ioat_chan->free_desc.next);
+			list_del(&new->node);
+		} else {
+			/* try to get another desc */
+			new = ioat_dma_alloc_descriptor(ioat_chan, GFP_ATOMIC);
+			/* will this ever happen? */
+			/* TODO add upper limit on these */
+			BUG_ON(!new);
+		}
+
+		copy = min((u32) len, ioat_chan->xfercap);
+
+		new->hw->size = copy;
+		new->hw->ctl = 0;
+		new->hw->src_addr = src;
+		new->hw->dst_addr = dest;
+		new->cookie = 0;
+
+		/* chain together the physical address list for the HW */
+		if (!first)
+			first = new;
+		else
+			prev->hw->next = (u64) new->phys;
+
+		prev = new;
+
+		len  -= copy;
+		dest += copy;
+		src  += copy;
+
+		list_add_tail(&new->node, &new_chain);
+		desc_count++;
+	}
+	new->hw->ctl = IOAT_DMA_DESCRIPTOR_CTL_CP_STS;
+	new->hw->next = 0;
+
+	/* cookie incr and addition to used_list must be atomic */
+
+	cookie = ioat_chan->common.cookie;
+	cookie++;
+	if (cookie < 0)
+		cookie = 1;
+	ioat_chan->common.cookie = new->cookie = cookie;
+
+	pci_unmap_addr_set(new, src, orig_src);
+	pci_unmap_addr_set(new, dst, orig_dst);
+	pci_unmap_len_set(new, src_len, orig_len);
+	pci_unmap_len_set(new, dst_len, orig_len);
+
+	/* write address into NextDescriptor field of last desc in chain */
+	to_ioat_desc(ioat_chan->used_desc.prev)->hw->next = first->phys;
+	list_splice_init(&new_chain, ioat_chan->used_desc.prev);
+
+	ioat_chan->pending += desc_count;
+	if (ioat_chan->pending >= 20) {
+		append = 1;
+		ioat_chan->pending = 0;
+	}
+
+	spin_unlock_bh(&ioat_chan->desc_lock);
+
+	if (append)
+		ioatdma_chan_write8(ioat_chan,
+		                    IOAT_CHANCMD_OFFSET,
+		                    IOAT_CHANCMD_APPEND);
+	return cookie;
+}
+
+/**
+ * ioat_dma_memcpy_buf_to_buf - wrapper that takes src & dest bufs
+ * @chan: IOAT DMA channel handle
+ * @dest: DMA destination address
+ * @src: DMA source address
+ * @len: transaction length in bytes
+ */
+
+static dma_cookie_t ioat_dma_memcpy_buf_to_buf(struct dma_chan *chan,
+                                               void *dest,
+                                               void *src,
+                                               size_t len)
+{
+	dma_addr_t dest_addr;
+	dma_addr_t src_addr;
+	struct ioat_dma_chan *ioat_chan = to_ioat_chan(chan);
+
+	dest_addr = pci_map_single(ioat_chan->device->pdev,
+		dest, len, PCI_DMA_FROMDEVICE);
+	src_addr = pci_map_single(ioat_chan->device->pdev,
+		src, len, PCI_DMA_TODEVICE);
+
+	return do_ioat_dma_memcpy(ioat_chan, dest_addr, src_addr, len);
+}
+
+/**
+ * ioat_dma_memcpy_buf_to_pg - wrapper, copying from a buf to a page
+ * @chan: IOAT DMA channel handle
+ * @page: pointer to the page to copy to
+ * @offset: offset into that page
+ * @src: DMA source address
+ * @len: transaction length in bytes
+ */
+
+static dma_cookie_t ioat_dma_memcpy_buf_to_pg(struct dma_chan *chan,
+                                              struct page *page,
+                                              unsigned int offset,
+                                              void *src,
+                                              size_t len)
+{
+	dma_addr_t dest_addr;
+	dma_addr_t src_addr;
+	struct ioat_dma_chan *ioat_chan = to_ioat_chan(chan);
+
+	dest_addr = pci_map_page(ioat_chan->device->pdev,
+		page, offset, len, PCI_DMA_FROMDEVICE);
+	src_addr = pci_map_single(ioat_chan->device->pdev,
+		src, len, PCI_DMA_TODEVICE);
+
+	return do_ioat_dma_memcpy(ioat_chan, dest_addr, src_addr, len);
+}
+
+/**
+ * ioat_dma_memcpy_pg_to_pg - wrapper, copying between two pages
+ * @chan: IOAT DMA channel handle
+ * @dest_pg: pointer to the page to copy to
+ * @dest_off: offset into that page
+ * @src_pg: pointer to the page to copy from
+ * @src_off: offset into that page
+ * @len: transaction length in bytes. This is guaranteed not to make a copy
+ *	 across a page boundary.
+ */
+
+static dma_cookie_t ioat_dma_memcpy_pg_to_pg(struct dma_chan *chan,
+                                             struct page *dest_pg,
+                                             unsigned int dest_off,
+                                             struct page *src_pg,
+                                             unsigned int src_off,
+                                             size_t len)
+{
+	dma_addr_t dest_addr;
+	dma_addr_t src_addr;
+	struct ioat_dma_chan *ioat_chan = to_ioat_chan(chan);
+
+	dest_addr = pci_map_page(ioat_chan->device->pdev,
+		dest_pg, dest_off, len, PCI_DMA_FROMDEVICE);
+	src_addr = pci_map_page(ioat_chan->device->pdev,
+		src_pg, src_off, len, PCI_DMA_TODEVICE);
+
+	return do_ioat_dma_memcpy(ioat_chan, dest_addr, src_addr, len);
+}
+
+/**
+ * ioat_dma_memcpy_issue_pending - push potentially unrecognized appended descriptors to hw
+ * @chan: DMA channel handle
+ */
+
+static void ioat_dma_memcpy_issue_pending(struct dma_chan *chan)
+{
+	struct ioat_dma_chan *ioat_chan = to_ioat_chan(chan);
+
+	if (ioat_chan->pending != 0) {
+		ioat_chan->pending = 0;
+		ioatdma_chan_write8(ioat_chan,
+		                    IOAT_CHANCMD_OFFSET,
+		                    IOAT_CHANCMD_APPEND);
+	}
+}
+
+static void ioat_dma_memcpy_cleanup(struct ioat_dma_chan *chan)
+{
+	unsigned long phys_complete;
+	struct ioat_desc_sw *desc, *_desc;
+	dma_cookie_t cookie = 0;
+
+	prefetch(chan->completion_virt);
+
+	if (!spin_trylock(&chan->cleanup_lock))
+		return;
+
+	/* The completion writeback can happen at any time,
+	   so reads by the driver need to be atomic operations
+	   The descriptor physical addresses are limited to 32-bits
+	   when the CPU can only do a 32-bit mov */
+
+#if (BITS_PER_LONG == 64)
+	phys_complete =
+	chan->completion_virt->full & IOAT_CHANSTS_COMPLETED_DESCRIPTOR_ADDR;
+#else
+	phys_complete = chan->completion_virt->low & IOAT_LOW_COMPLETION_MASK;
+#endif
+
+	if ((chan->completion_virt->full & IOAT_CHANSTS_DMA_TRANSFER_STATUS) ==
+		IOAT_CHANSTS_DMA_TRANSFER_STATUS_HALTED) {
+		printk("IOAT: Channel halted, chanerr = %x\n",
+			ioatdma_chan_read32(chan, IOAT_CHANERR_OFFSET));
+
+		/* TODO do something to salvage the situation */
+	}
+
+	if (phys_complete == chan->last_completion) {
+		spin_unlock(&chan->cleanup_lock);
+		return;
+	}
+
+	spin_lock_bh(&chan->desc_lock);
+	list_for_each_entry_safe(desc, _desc, &chan->used_desc, node) {
+
+		/*
+		 * Incoming DMA requests may use multiple descriptors, due to
+		 * exceeding xfercap, perhaps. If so, only the last one will
+		 * have a cookie, and require unmapping.
+		 */
+		if (desc->cookie) {
+			cookie = desc->cookie;
+
+			/* yes we are unmapping both _page and _single alloc'd
+			   regions with unmap_page. Is this *really* that bad?
+			*/
+			pci_unmap_page(chan->device->pdev,
+					pci_unmap_addr(desc, dst),
+					pci_unmap_len(desc, dst_len),
+					PCI_DMA_FROMDEVICE);
+			pci_unmap_page(chan->device->pdev,
+					pci_unmap_addr(desc, src),
+					pci_unmap_len(desc, src_len),
+					PCI_DMA_TODEVICE);
+		}
+
+		if (desc->phys != phys_complete) {
+			/* a completed entry, but not the last, so cleanup */
+			list_del(&desc->node);
+			list_add_tail(&desc->node, &chan->free_desc);
+		} else {
+			/* last used desc. Do not remove, so we can append from
+			   it, but don't look at it next time, either */
+			desc->cookie = 0;
+
+			/* TODO check status bits? */
+			break;
+		}
+	}
+
+	spin_unlock_bh(&chan->desc_lock);
+
+	chan->last_completion = phys_complete;
+	if (cookie != 0)
+		chan->completed_cookie = cookie;
+
+	spin_unlock(&chan->cleanup_lock);
+}
+
+/**
+ * ioat_dma_is_complete - poll the status of a IOAT DMA transaction
+ * @chan: IOAT DMA channel handle
+ * @cookie: DMA transaction identifier
+ * @done: if not %NULL, updated with last completed transaction
+ * @used: if not %NULL, updated with last used transaction
+ */
+
+static enum dma_status ioat_dma_is_complete(struct dma_chan *chan,
+                                            dma_cookie_t cookie,
+                                            dma_cookie_t *done,
+                                            dma_cookie_t *used)
+{
+	struct ioat_dma_chan *ioat_chan = to_ioat_chan(chan);
+	dma_cookie_t last_used;
+	dma_cookie_t last_complete;
+	enum dma_status ret;
+
+	last_used = chan->cookie;
+	last_complete = ioat_chan->completed_cookie;
+
+	if (done)
+		*done= last_complete;
+	if (used)
+		*used = last_used;
+
+	ret = dma_async_is_complete(cookie, last_complete, last_used);
+	if (ret == DMA_SUCCESS)
+		return ret;
+
+	ioat_dma_memcpy_cleanup(ioat_chan);
+
+	last_used = chan->cookie;
+	last_complete = ioat_chan->completed_cookie;
+
+	if (done)
+		*done= last_complete;
+	if (used)
+		*used = last_used;
+
+	return dma_async_is_complete(cookie, last_complete, last_used);
+}
+
+/* PCI API */
+
+static struct pci_device_id ioat_pci_tbl[] = {
+	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT) },
+	{ 0, }
+};
+
+static struct pci_driver ioat_pci_drv = {
+	.name 	= "ioatdma",
+	.id_table = ioat_pci_tbl,
+	.probe	= ioat_probe,
+	.remove	= __devexit_p(ioat_remove),
+};
+
+static irqreturn_t ioat_do_interrupt(int irq, void *data, struct pt_regs *regs)
+{
+	struct ioat_device *instance = data;
+	unsigned long attnstatus;
+	u8 intrctrl;
+
+	intrctrl = ioatdma_read8(instance, IOAT_INTRCTRL_OFFSET);
+
+	if (!(intrctrl & IOAT_INTRCTRL_MASTER_INT_EN))
+		return IRQ_NONE;
+
+	if (!(intrctrl & IOAT_INTRCTRL_INT_STATUS)) {
+		ioatdma_write8(instance, IOAT_INTRCTRL_OFFSET, intrctrl);
+		return IRQ_NONE;
+	}
+
+	attnstatus = ioatdma_read32(instance, IOAT_ATTNSTATUS_OFFSET);
+
+	printk(KERN_ERR "ioatdma error: interrupt! status %lx\n", attnstatus);
+
+	ioatdma_write8(instance, IOAT_INTRCTRL_OFFSET, intrctrl);
+	return IRQ_HANDLED;
+}
+
+static void ioat_start_null_desc(struct ioat_dma_chan *ioat_chan)
+{
+	struct ioat_desc_sw *desc;
+
+	spin_lock_bh(&ioat_chan->desc_lock);
+
+	if (!list_empty(&ioat_chan->free_desc)) {
+		desc = to_ioat_desc(ioat_chan->free_desc.next);
+		list_del(&desc->node);
+	} else {
+		/* try to get another desc */
+		spin_unlock_bh(&ioat_chan->desc_lock);
+		desc = ioat_dma_alloc_descriptor(ioat_chan, GFP_KERNEL);
+		spin_lock_bh(&ioat_chan->desc_lock);
+		/* will this ever happen? */
+		BUG_ON(!desc);
+	}
+
+	desc->hw->ctl = IOAT_DMA_DESCRIPTOR_NUL;
+	desc->hw->next = 0;
+
+	list_add_tail(&desc->node, &ioat_chan->used_desc);
+	spin_unlock_bh(&ioat_chan->desc_lock);
+
+#if (BITS_PER_LONG == 64)
+	ioatdma_chan_write64(ioat_chan, IOAT_CHAINADDR_OFFSET, desc->phys);
+#else
+	ioatdma_chan_write32(ioat_chan,
+	                     IOAT_CHAINADDR_OFFSET_LOW,
+	                     (u32) desc->phys);
+	ioatdma_chan_write32(ioat_chan, IOAT_CHAINADDR_OFFSET_HIGH, 0);
+#endif
+	ioatdma_chan_write8(ioat_chan, IOAT_CHANCMD_OFFSET, IOAT_CHANCMD_START);
+}
+
+/*
+ * Perform a IOAT transaction to verify the HW works.
+ */
+#define IOAT_TEST_SIZE 2000
+
+static int ioat_self_test(struct ioat_device *device)
+{
+	int i;
+	u8 *src;
+	u8 *dest;
+	struct dma_chan *dma_chan;
+	dma_cookie_t cookie;
+	int err = 0;
+
+	src = kzalloc(sizeof(u8) * IOAT_TEST_SIZE, SLAB_KERNEL);
+	if (!src)
+		return -ENOMEM;
+	dest = kzalloc(sizeof(u8) * IOAT_TEST_SIZE, SLAB_KERNEL);
+	if (!dest) {
+		kfree(src);
+		return -ENOMEM;
+	}
+
+	/* Fill in src buffer */
+	for (i = 0; i < IOAT_TEST_SIZE; i++)
+		src[i] = (u8)i;
+
+	/* Start copy, using first DMA channel */
+	dma_chan = container_of(device->common.channels.next,
+	                        struct dma_chan,
+	                        device_node);
+	if (ioat_dma_alloc_chan_resources(dma_chan) < 1) {
+		err = -ENODEV;
+		goto out;
+	}
+
+	cookie = ioat_dma_memcpy_buf_to_buf(dma_chan, dest, src, IOAT_TEST_SIZE);
+	ioat_dma_memcpy_issue_pending(dma_chan);
+	msleep(1);
+
+	if (ioat_dma_is_complete(dma_chan, cookie, NULL, NULL) != DMA_SUCCESS) {
+		printk(KERN_ERR "ioatdma: Self-test copy timed out, disabling\n");
+		err = -ENODEV;
+		goto free_resources;
+	}
+	if (memcmp(src, dest, IOAT_TEST_SIZE)) {
+		printk(KERN_ERR "ioatdma: Self-test copy failed compare, disabling\n");
+		err = -ENODEV;
+		goto free_resources;
+	}
+
+free_resources:
+	ioat_dma_free_chan_resources(dma_chan);
+out:
+	kfree(src);
+	kfree(dest);
+	return err;
+}
+
+static int __devinit ioat_probe(struct pci_dev *pdev,
+                                const struct pci_device_id *ent)
+{
+	int err;
+	unsigned long mmio_start, mmio_len;
+	void *reg_base;
+	struct ioat_device *device;
+
+	err = pci_enable_device(pdev);
+	if (err)
+		goto err_enable_device;
+
+	err = pci_set_dma_mask(pdev, DMA_64BIT_MASK);
+	if (err)
+		err = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
+	if (err)
+		goto err_set_dma_mask;
+
+	err = pci_request_regions(pdev, ioat_pci_drv.name);
+	if (err)
+		goto err_request_regions;
+
+	mmio_start = pci_resource_start(pdev, 0);
+	mmio_len = pci_resource_len(pdev, 0);
+
+	reg_base = ioremap(mmio_start, mmio_len);
+	if (!reg_base) {
+		err = -ENOMEM;
+		goto err_ioremap;
+	}
+
+	device = kzalloc(sizeof(*device), GFP_KERNEL);
+	if (!device) {
+		err = -ENOMEM;
+		goto err_kzalloc;
+	}
+
+	/* DMA coherent memory pool for DMA descriptor allocations */
+	device->dma_pool = pci_pool_create("dma_desc_pool", pdev,
+		sizeof(struct ioat_dma_descriptor), 64, 0);
+	if (!device->dma_pool) {
+		err = -ENOMEM;
+		goto err_dma_pool;
+	}
+
+	device->completion_pool = pci_pool_create("completion_pool", pdev, sizeof(u64), SMP_CACHE_BYTES, SMP_CACHE_BYTES);
+	if (!device->completion_pool) {
+		err = -ENOMEM;
+		goto err_completion_pool;
+	}
+
+	device->pdev = pdev;
+	pci_set_drvdata(pdev, device);
+#ifdef CONFIG_PCI_MSI
+	if (pci_enable_msi(pdev) == 0) {
+		device->msi = 1;
+	} else {
+		device->msi = 0;
+	}
+#endif
+	err = request_irq(pdev->irq, &ioat_do_interrupt, IRQF_SHARED, "ioat",
+		device);
+	if (err)
+		goto err_irq;
+
+	device->reg_base = reg_base;
+
+	ioatdma_write8(device, IOAT_INTRCTRL_OFFSET, IOAT_INTRCTRL_MASTER_INT_EN);
+	pci_set_master(pdev);
+
+	INIT_LIST_HEAD(&device->common.channels);
+	enumerate_dma_channels(device);
+
+	device->common.device_alloc_chan_resources = ioat_dma_alloc_chan_resources;
+	device->common.device_free_chan_resources = ioat_dma_free_chan_resources;
+	device->common.device_memcpy_buf_to_buf = ioat_dma_memcpy_buf_to_buf;
+	device->common.device_memcpy_buf_to_pg = ioat_dma_memcpy_buf_to_pg;
+	device->common.device_memcpy_pg_to_pg = ioat_dma_memcpy_pg_to_pg;
+	device->common.device_memcpy_complete = ioat_dma_is_complete;
+	device->common.device_memcpy_issue_pending = ioat_dma_memcpy_issue_pending;
+	printk(KERN_INFO "Intel(R) I/OAT DMA Engine found, %d channels\n",
+		device->common.chancnt);
+
+	err = ioat_self_test(device);
+	if (err)
+		goto err_self_test;
+
+	dma_async_device_register(&device->common);
+
+	return 0;
+
+err_self_test:
+err_irq:
+	pci_pool_destroy(device->completion_pool);
+err_completion_pool:
+	pci_pool_destroy(device->dma_pool);
+err_dma_pool:
+	kfree(device);
+err_kzalloc:
+	iounmap(reg_base);
+err_ioremap:
+	pci_release_regions(pdev);
+err_request_regions:
+err_set_dma_mask:
+	pci_disable_device(pdev);
+err_enable_device:
+	return err;
+}
+
+static void __devexit ioat_remove(struct pci_dev *pdev)
+{
+	struct ioat_device *device;
+	struct dma_chan *chan, *_chan;
+	struct ioat_dma_chan *ioat_chan;
+
+	device = pci_get_drvdata(pdev);
+	dma_async_device_unregister(&device->common);
+
+	free_irq(device->pdev->irq, device);
+#ifdef CONFIG_PCI_MSI
+	if (device->msi)
+		pci_disable_msi(device->pdev);
+#endif
+	pci_pool_destroy(device->dma_pool);
+	pci_pool_destroy(device->completion_pool);
+	iounmap(device->reg_base);
+	pci_release_regions(pdev);
+	pci_disable_device(pdev);
+	list_for_each_entry_safe(chan, _chan, &device->common.channels, device_node) {
+		ioat_chan = to_ioat_chan(chan);
+		list_del(&chan->device_node);
+		kfree(ioat_chan);
+	}
+	kfree(device);
+}
+
+/* MODULE API */
+MODULE_VERSION("1.7");
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Intel Corporation");
+
+static int __init ioat_init_module(void)
+{
+	/* it's currently unsafe to unload this module */
+	/* if forced, worst case is that rmmod hangs */
+	__unsafe(THIS_MODULE);
+
+	return pci_register_driver(&ioat_pci_drv);
+}
+
+module_init(ioat_init_module);
+
+static void __exit ioat_exit_module(void)
+{
+	pci_unregister_driver(&ioat_pci_drv);
+}
+
+module_exit(ioat_exit_module);
diff --git a/drivers/dma/ioatdma.h b/drivers/dma/ioatdma.h
new file mode 100644
index 000000000..a5d3b3644
--- /dev/null
+++ b/drivers/dma/ioatdma.h
@@ -0,0 +1,125 @@
+/*
+ * Copyright(c) 2004 - 2006 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59
+ * Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called COPYING.
+ */
+#ifndef IOATDMA_H
+#define IOATDMA_H
+
+#include <linux/dmaengine.h>
+#include "ioatdma_hw.h"
+#include <linux/init.h>
+#include <linux/dmapool.h>
+#include <linux/cache.h>
+#include <linux/pci_ids.h>
+
+#define IOAT_LOW_COMPLETION_MASK	0xffffffc0
+
+extern struct list_head dma_device_list;
+extern struct list_head dma_client_list;
+
+/**
+ * struct ioat_device - internal representation of a IOAT device
+ * @pdev: PCI-Express device
+ * @reg_base: MMIO register space base address
+ * @dma_pool: for allocating DMA descriptors
+ * @common: embedded struct dma_device
+ * @msi: Message Signaled Interrupt number
+ */
+
+struct ioat_device {
+	struct pci_dev *pdev;
+	void *reg_base;
+	struct pci_pool *dma_pool;
+	struct pci_pool *completion_pool;
+
+	struct dma_device common;
+	u8 msi;
+};
+
+/**
+ * struct ioat_dma_chan - internal representation of a DMA channel
+ * @device:
+ * @reg_base:
+ * @sw_in_use:
+ * @completion:
+ * @completion_low:
+ * @completion_high:
+ * @completed_cookie: last cookie seen completed on cleanup
+ * @cookie: value of last cookie given to client
+ * @last_completion:
+ * @xfercap:
+ * @desc_lock:
+ * @free_desc:
+ * @used_desc:
+ * @resource:
+ * @device_node:
+ */
+
+struct ioat_dma_chan {
+
+	void *reg_base;
+
+	dma_cookie_t completed_cookie;
+	unsigned long last_completion;
+
+	u32 xfercap;	/* XFERCAP register value expanded out */
+
+	spinlock_t cleanup_lock;
+	spinlock_t desc_lock;
+	struct list_head free_desc;
+	struct list_head used_desc;
+
+	int pending;
+
+	struct ioat_device *device;
+	struct dma_chan common;
+
+	dma_addr_t completion_addr;
+	union {
+		u64 full; /* HW completion writeback */
+		struct {
+			u32 low;
+			u32 high;
+		};
+	} *completion_virt;
+};
+
+/* wrapper around hardware descriptor format + additional software fields */
+
+/**
+ * struct ioat_desc_sw - wrapper around hardware descriptor
+ * @hw: hardware DMA descriptor
+ * @node:
+ * @cookie:
+ * @phys:
+ */
+
+struct ioat_desc_sw {
+	struct ioat_dma_descriptor *hw;
+	struct list_head node;
+	dma_cookie_t cookie;
+	dma_addr_t phys;
+	DECLARE_PCI_UNMAP_ADDR(src)
+	DECLARE_PCI_UNMAP_LEN(src_len)
+	DECLARE_PCI_UNMAP_ADDR(dst)
+	DECLARE_PCI_UNMAP_LEN(dst_len)
+};
+
+#endif /* IOATDMA_H */
+
diff --git a/drivers/dma/ioatdma_hw.h b/drivers/dma/ioatdma_hw.h
new file mode 100644
index 000000000..4d7a12880
--- /dev/null
+++ b/drivers/dma/ioatdma_hw.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright(c) 2004 - 2006 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59
+ * Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called COPYING.
+ */
+#ifndef _IOAT_HW_H_
+#define _IOAT_HW_H_
+
+/* PCI Configuration Space Values */
+#define IOAT_PCI_VID			0x8086
+#define IOAT_PCI_DID			0x1A38
+#define IOAT_PCI_RID			0x00
+#define IOAT_PCI_SVID			0x8086
+#define IOAT_PCI_SID			0x8086
+#define IOAT_VER			0x12	/* Version 1.2 */
+
+struct ioat_dma_descriptor {
+	uint32_t	size;
+	uint32_t	ctl;
+	uint64_t	src_addr;
+	uint64_t	dst_addr;
+	uint64_t	next;
+	uint64_t	rsv1;
+	uint64_t	rsv2;
+	uint64_t	user1;
+	uint64_t	user2;
+};
+
+#define IOAT_DMA_DESCRIPTOR_CTL_INT_GN	0x00000001
+#define IOAT_DMA_DESCRIPTOR_CTL_SRC_SN	0x00000002
+#define IOAT_DMA_DESCRIPTOR_CTL_DST_SN	0x00000004
+#define IOAT_DMA_DESCRIPTOR_CTL_CP_STS	0x00000008
+#define IOAT_DMA_DESCRIPTOR_CTL_FRAME	0x00000010
+#define IOAT_DMA_DESCRIPTOR_NUL		0x00000020
+#define IOAT_DMA_DESCRIPTOR_OPCODE	0xFF000000
+
+#endif
diff --git a/drivers/dma/ioatdma_io.h b/drivers/dma/ioatdma_io.h
new file mode 100644
index 000000000..c0b4bf66c
--- /dev/null
+++ b/drivers/dma/ioatdma_io.h
@@ -0,0 +1,118 @@
+/*
+ * Copyright(c) 2004 - 2006 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59
+ * Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called COPYING.
+ */
+#ifndef IOATDMA_IO_H
+#define IOATDMA_IO_H
+
+#include <asm/io.h>
+
+/*
+ * device and per-channel MMIO register read and write functions
+ * this is a lot of anoying inline functions, but it's typesafe
+ */
+
+static inline u8 ioatdma_read8(struct ioat_device *device,
+                               unsigned int offset)
+{
+	return readb(device->reg_base + offset);
+}
+
+static inline u16 ioatdma_read16(struct ioat_device *device,
+                                 unsigned int offset)
+{
+	return readw(device->reg_base + offset);
+}
+
+static inline u32 ioatdma_read32(struct ioat_device *device,
+                                 unsigned int offset)
+{
+	return readl(device->reg_base + offset);
+}
+
+static inline void ioatdma_write8(struct ioat_device *device,
+                                  unsigned int offset, u8 value)
+{
+	writeb(value, device->reg_base + offset);
+}
+
+static inline void ioatdma_write16(struct ioat_device *device,
+                                   unsigned int offset, u16 value)
+{
+	writew(value, device->reg_base + offset);
+}
+
+static inline void ioatdma_write32(struct ioat_device *device,
+                                   unsigned int offset, u32 value)
+{
+	writel(value, device->reg_base + offset);
+}
+
+static inline u8 ioatdma_chan_read8(struct ioat_dma_chan *chan,
+                                    unsigned int offset)
+{
+	return readb(chan->reg_base + offset);
+}
+
+static inline u16 ioatdma_chan_read16(struct ioat_dma_chan *chan,
+                                      unsigned int offset)
+{
+	return readw(chan->reg_base + offset);
+}
+
+static inline u32 ioatdma_chan_read32(struct ioat_dma_chan *chan,
+                                      unsigned int offset)
+{
+	return readl(chan->reg_base + offset);
+}
+
+static inline void ioatdma_chan_write8(struct ioat_dma_chan *chan,
+                                       unsigned int offset, u8 value)
+{
+	writeb(value, chan->reg_base + offset);
+}
+
+static inline void ioatdma_chan_write16(struct ioat_dma_chan *chan,
+                                        unsigned int offset, u16 value)
+{
+	writew(value, chan->reg_base + offset);
+}
+
+static inline void ioatdma_chan_write32(struct ioat_dma_chan *chan,
+                                        unsigned int offset, u32 value)
+{
+	writel(value, chan->reg_base + offset);
+}
+
+#if (BITS_PER_LONG == 64)
+static inline u64 ioatdma_chan_read64(struct ioat_dma_chan *chan,
+                                      unsigned int offset)
+{
+	return readq(chan->reg_base + offset);
+}
+
+static inline void ioatdma_chan_write64(struct ioat_dma_chan *chan,
+                                        unsigned int offset, u64 value)
+{
+	writeq(value, chan->reg_base + offset);
+}
+#endif
+
+#endif /* IOATDMA_IO_H */
+
diff --git a/drivers/dma/ioatdma_registers.h b/drivers/dma/ioatdma_registers.h
new file mode 100644
index 000000000..a30c73490
--- /dev/null
+++ b/drivers/dma/ioatdma_registers.h
@@ -0,0 +1,126 @@
+/*
+ * Copyright(c) 2004 - 2006 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59
+ * Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called COPYING.
+ */
+#ifndef _IOAT_REGISTERS_H_
+#define _IOAT_REGISTERS_H_
+
+
+/* MMIO Device Registers */
+#define IOAT_CHANCNT_OFFSET			0x00	/*  8-bit */
+
+#define IOAT_XFERCAP_OFFSET			0x01	/*  8-bit */
+#define IOAT_XFERCAP_4KB			12
+#define IOAT_XFERCAP_8KB			13
+#define IOAT_XFERCAP_16KB			14
+#define IOAT_XFERCAP_32KB			15
+#define IOAT_XFERCAP_32GB			0
+
+#define IOAT_GENCTRL_OFFSET			0x02	/*  8-bit */
+#define IOAT_GENCTRL_DEBUG_EN			0x01
+
+#define IOAT_INTRCTRL_OFFSET			0x03	/*  8-bit */
+#define IOAT_INTRCTRL_MASTER_INT_EN		0x01	/* Master Interrupt Enable */
+#define IOAT_INTRCTRL_INT_STATUS		0x02	/* ATTNSTATUS -or- Channel Int */
+#define IOAT_INTRCTRL_INT			0x04	/* INT_STATUS -and- MASTER_INT_EN */
+
+#define IOAT_ATTNSTATUS_OFFSET			0x04	/* Each bit is a channel */
+
+#define IOAT_VER_OFFSET				0x08	/*  8-bit */
+#define IOAT_VER_MAJOR_MASK			0xF0
+#define IOAT_VER_MINOR_MASK			0x0F
+#define GET_IOAT_VER_MAJOR(x)			((x) & IOAT_VER_MAJOR_MASK)
+#define GET_IOAT_VER_MINOR(x)			((x) & IOAT_VER_MINOR_MASK)
+
+#define IOAT_PERPORTOFFSET_OFFSET		0x0A	/* 16-bit */
+
+#define IOAT_INTRDELAY_OFFSET			0x0C	/* 16-bit */
+#define IOAT_INTRDELAY_INT_DELAY_MASK		0x3FFF	/* Interrupt Delay Time */
+#define IOAT_INTRDELAY_COALESE_SUPPORT		0x8000	/* Interrupt Coalesing Supported */
+
+#define IOAT_DEVICE_STATUS_OFFSET		0x0E	/* 16-bit */
+#define IOAT_DEVICE_STATUS_DEGRADED_MODE	0x0001
+
+
+#define IOAT_CHANNEL_MMIO_SIZE			0x80	/* Each Channel MMIO space is this size */
+
+/* DMA Channel Registers */
+#define IOAT_CHANCTRL_OFFSET			0x00	/* 16-bit Channel Control Register */
+#define IOAT_CHANCTRL_CHANNEL_PRIORITY_MASK	0xF000
+#define IOAT_CHANCTRL_CHANNEL_IN_USE		0x0100
+#define IOAT_CHANCTRL_DESCRIPTOR_ADDR_SNOOP_CONTROL	0x0020
+#define IOAT_CHANCTRL_ERR_INT_EN		0x0010
+#define IOAT_CHANCTRL_ANY_ERR_ABORT_EN		0x0008
+#define IOAT_CHANCTRL_ERR_COMPLETION_EN		0x0004
+#define IOAT_CHANCTRL_INT_DISABLE		0x0001
+
+#define IOAT_DMA_COMP_OFFSET			0x02	/* 16-bit DMA channel compatability */
+#define IOAT_DMA_COMP_V1			0x0001	/* Compatability with DMA version 1 */
+
+#define IOAT_CHANSTS_OFFSET			0x04	/* 64-bit Channel Status Register */
+#define IOAT_CHANSTS_OFFSET_LOW			0x04
+#define IOAT_CHANSTS_OFFSET_HIGH		0x08
+#define IOAT_CHANSTS_COMPLETED_DESCRIPTOR_ADDR	0xFFFFFFFFFFFFFFC0UL
+#define IOAT_CHANSTS_SOFT_ERR			0x0000000000000010
+#define IOAT_CHANSTS_DMA_TRANSFER_STATUS	0x0000000000000007
+#define IOAT_CHANSTS_DMA_TRANSFER_STATUS_ACTIVE	0x0
+#define IOAT_CHANSTS_DMA_TRANSFER_STATUS_DONE	0x1
+#define IOAT_CHANSTS_DMA_TRANSFER_STATUS_SUSPENDED	0x2
+#define IOAT_CHANSTS_DMA_TRANSFER_STATUS_HALTED	0x3
+
+#define IOAT_CHAINADDR_OFFSET			0x0C	/* 64-bit Descriptor Chain Address Register */
+#define IOAT_CHAINADDR_OFFSET_LOW		0x0C
+#define IOAT_CHAINADDR_OFFSET_HIGH		0x10
+
+#define IOAT_CHANCMD_OFFSET			0x14	/*  8-bit DMA Channel Command Register */
+#define IOAT_CHANCMD_RESET			0x20
+#define IOAT_CHANCMD_RESUME			0x10
+#define IOAT_CHANCMD_ABORT			0x08
+#define IOAT_CHANCMD_SUSPEND			0x04
+#define IOAT_CHANCMD_APPEND			0x02
+#define IOAT_CHANCMD_START			0x01
+
+#define IOAT_CHANCMP_OFFSET			0x18	/* 64-bit Channel Completion Address Register */
+#define IOAT_CHANCMP_OFFSET_LOW			0x18
+#define IOAT_CHANCMP_OFFSET_HIGH		0x1C
+
+#define IOAT_CDAR_OFFSET			0x20	/* 64-bit Current Descriptor Address Register */
+#define IOAT_CDAR_OFFSET_LOW			0x20
+#define IOAT_CDAR_OFFSET_HIGH			0x24
+
+#define IOAT_CHANERR_OFFSET			0x28	/* 32-bit Channel Error Register */
+#define IOAT_CHANERR_DMA_TRANSFER_SRC_ADDR_ERR	0x0001
+#define IOAT_CHANERR_DMA_TRANSFER_DEST_ADDR_ERR	0x0002
+#define IOAT_CHANERR_NEXT_DESCRIPTOR_ADDR_ERR	0x0004
+#define IOAT_CHANERR_NEXT_DESCRIPTOR_ALIGNMENT_ERR	0x0008
+#define IOAT_CHANERR_CHAIN_ADDR_VALUE_ERR	0x0010
+#define IOAT_CHANERR_CHANCMD_ERR		0x0020
+#define IOAT_CHANERR_CHIPSET_UNCORRECTABLE_DATA_INTEGRITY_ERR	0x0040
+#define IOAT_CHANERR_DMA_UNCORRECTABLE_DATA_INTEGRITY_ERR	0x0080
+#define IOAT_CHANERR_READ_DATA_ERR		0x0100
+#define IOAT_CHANERR_WRITE_DATA_ERR		0x0200
+#define IOAT_CHANERR_DESCRIPTOR_CONTROL_ERR	0x0400
+#define IOAT_CHANERR_DESCRIPTOR_LENGTH_ERR	0x0800
+#define IOAT_CHANERR_COMPLETION_ADDR_ERR	0x1000
+#define IOAT_CHANERR_INT_CONFIGURATION_ERR	0x2000
+#define IOAT_CHANERR_SOFT_ERR			0x4000
+
+#define IOAT_CHANERR_MASK_OFFSET		0x2C	/* 32-bit Channel Error Register */
+
+#endif /* _IOAT_REGISTERS_H_ */
diff --git a/drivers/dma/iovlock.c b/drivers/dma/iovlock.c
new file mode 100644
index 000000000..d637555a8
--- /dev/null
+++ b/drivers/dma/iovlock.c
@@ -0,0 +1,301 @@
+/*
+ * Copyright(c) 2004 - 2006 Intel Corporation. All rights reserved.
+ * Portions based on net/core/datagram.c and copyrighted by their 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., 59
+ * Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called COPYING.
+ */
+
+/*
+ * This code allows the net stack to make use of a DMA engine for
+ * skb to iovec copies.
+ */
+
+#include <linux/dmaengine.h>
+#include <linux/pagemap.h>
+#include <net/tcp.h> /* for memcpy_toiovec */
+#include <asm/io.h>
+#include <asm/uaccess.h>
+
+static int num_pages_spanned(struct iovec *iov)
+{
+	return
+	((PAGE_ALIGN((unsigned long)iov->iov_base + iov->iov_len) -
+	((unsigned long)iov->iov_base & PAGE_MASK)) >> PAGE_SHIFT);
+}
+
+/*
+ * Pin down all the iovec pages needed for len bytes.
+ * Return a struct dma_pinned_list to keep track of pages pinned down.
+ *
+ * We are allocating a single chunk of memory, and then carving it up into
+ * 3 sections, the latter 2 whose size depends on the number of iovecs and the
+ * total number of pages, respectively.
+ */
+struct dma_pinned_list *dma_pin_iovec_pages(struct iovec *iov, size_t len)
+{
+	struct dma_pinned_list *local_list;
+	struct page **pages;
+	int i;
+	int ret;
+	int nr_iovecs = 0;
+	int iovec_len_used = 0;
+	int iovec_pages_used = 0;
+	long err;
+
+	/* don't pin down non-user-based iovecs */
+	if (segment_eq(get_fs(), KERNEL_DS))
+		return NULL;
+
+	/* determine how many iovecs/pages there are, up front */
+	do {
+		iovec_len_used += iov[nr_iovecs].iov_len;
+		iovec_pages_used += num_pages_spanned(&iov[nr_iovecs]);
+		nr_iovecs++;
+	} while (iovec_len_used < len);
+
+	/* single kmalloc for pinned list, page_list[], and the page arrays */
+	local_list = kmalloc(sizeof(*local_list)
+		+ (nr_iovecs * sizeof (struct dma_page_list))
+		+ (iovec_pages_used * sizeof (struct page*)), GFP_KERNEL);
+	if (!local_list) {
+		err = -ENOMEM;
+		goto out;
+	}
+
+	/* list of pages starts right after the page list array */
+	pages = (struct page **) &local_list->page_list[nr_iovecs];
+
+	for (i = 0; i < nr_iovecs; i++) {
+		struct dma_page_list *page_list = &local_list->page_list[i];
+
+		len -= iov[i].iov_len;
+
+		if (!access_ok(VERIFY_WRITE, iov[i].iov_base, iov[i].iov_len)) {
+			err = -EFAULT;
+			goto unpin;
+		}
+
+		page_list->nr_pages = num_pages_spanned(&iov[i]);
+		page_list->base_address = iov[i].iov_base;
+
+		page_list->pages = pages;
+		pages += page_list->nr_pages;
+
+		/* pin pages down */
+		down_read(&current->mm->mmap_sem);
+		ret = get_user_pages(
+			current,
+			current->mm,
+			(unsigned long) iov[i].iov_base,
+			page_list->nr_pages,
+			1,	/* write */
+			0,	/* force */
+			page_list->pages,
+			NULL);
+		up_read(&current->mm->mmap_sem);
+
+		if (ret != page_list->nr_pages) {
+			err = -ENOMEM;
+			goto unpin;
+		}
+
+		local_list->nr_iovecs = i + 1;
+	}
+
+	return local_list;
+
+unpin:
+	dma_unpin_iovec_pages(local_list);
+out:
+	return ERR_PTR(err);
+}
+
+void dma_unpin_iovec_pages(struct dma_pinned_list *pinned_list)
+{
+	int i, j;
+
+	if (!pinned_list)
+		return;
+
+	for (i = 0; i < pinned_list->nr_iovecs; i++) {
+		struct dma_page_list *page_list = &pinned_list->page_list[i];
+		for (j = 0; j < page_list->nr_pages; j++) {
+			set_page_dirty_lock(page_list->pages[j]);
+			page_cache_release(page_list->pages[j]);
+		}
+	}
+
+	kfree(pinned_list);
+}
+
+static dma_cookie_t dma_memcpy_to_kernel_iovec(struct dma_chan *chan, struct
+	iovec *iov, unsigned char *kdata, size_t len)
+{
+	dma_cookie_t dma_cookie = 0;
+
+	while (len > 0) {
+		if (iov->iov_len) {
+			int copy = min_t(unsigned int, iov->iov_len, len);
+			dma_cookie = dma_async_memcpy_buf_to_buf(
+					chan,
+					iov->iov_base,
+					kdata,
+					copy);
+			kdata += copy;
+			len -= copy;
+			iov->iov_len -= copy;
+			iov->iov_base += copy;
+		}
+		iov++;
+	}
+
+	return dma_cookie;
+}
+
+/*
+ * We have already pinned down the pages we will be using in the iovecs.
+ * Each entry in iov array has corresponding entry in pinned_list->page_list.
+ * Using array indexing to keep iov[] and page_list[] in sync.
+ * Initial elements in iov array's iov->iov_len will be 0 if already copied into
+ *   by another call.
+ * iov array length remaining guaranteed to be bigger than len.
+ */
+dma_cookie_t dma_memcpy_to_iovec(struct dma_chan *chan, struct iovec *iov,
+	struct dma_pinned_list *pinned_list, unsigned char *kdata, size_t len)
+{
+	int iov_byte_offset;
+	int copy;
+	dma_cookie_t dma_cookie = 0;
+	int iovec_idx;
+	int page_idx;
+
+	if (!chan)
+		return memcpy_toiovec(iov, kdata, len);
+
+	/* -> kernel copies (e.g. smbfs) */
+	if (!pinned_list)
+		return dma_memcpy_to_kernel_iovec(chan, iov, kdata, len);
+
+	iovec_idx = 0;
+	while (iovec_idx < pinned_list->nr_iovecs) {
+		struct dma_page_list *page_list;
+
+		/* skip already used-up iovecs */
+		while (!iov[iovec_idx].iov_len)
+			iovec_idx++;
+
+		page_list = &pinned_list->page_list[iovec_idx];
+
+		iov_byte_offset = ((unsigned long)iov[iovec_idx].iov_base & ~PAGE_MASK);
+		page_idx = (((unsigned long)iov[iovec_idx].iov_base & PAGE_MASK)
+			 - ((unsigned long)page_list->base_address & PAGE_MASK)) >> PAGE_SHIFT;
+
+		/* break up copies to not cross page boundary */
+		while (iov[iovec_idx].iov_len) {
+			copy = min_t(int, PAGE_SIZE - iov_byte_offset, len);
+			copy = min_t(int, copy, iov[iovec_idx].iov_len);
+
+			dma_cookie = dma_async_memcpy_buf_to_pg(chan,
+					page_list->pages[page_idx],
+					iov_byte_offset,
+					kdata,
+					copy);
+
+			len -= copy;
+			iov[iovec_idx].iov_len -= copy;
+			iov[iovec_idx].iov_base += copy;
+
+			if (!len)
+				return dma_cookie;
+
+			kdata += copy;
+			iov_byte_offset = 0;
+			page_idx++;
+		}
+		iovec_idx++;
+	}
+
+	/* really bad if we ever run out of iovecs */
+	BUG();
+	return -EFAULT;
+}
+
+dma_cookie_t dma_memcpy_pg_to_iovec(struct dma_chan *chan, struct iovec *iov,
+	struct dma_pinned_list *pinned_list, struct page *page,
+	unsigned int offset, size_t len)
+{
+	int iov_byte_offset;
+	int copy;
+	dma_cookie_t dma_cookie = 0;
+	int iovec_idx;
+	int page_idx;
+	int err;
+
+	/* this needs as-yet-unimplemented buf-to-buff, so punt. */
+	/* TODO: use dma for this */
+	if (!chan || !pinned_list) {
+		u8 *vaddr = kmap(page);
+		err = memcpy_toiovec(iov, vaddr + offset, len);
+		kunmap(page);
+		return err;
+	}
+
+	iovec_idx = 0;
+	while (iovec_idx < pinned_list->nr_iovecs) {
+		struct dma_page_list *page_list;
+
+		/* skip already used-up iovecs */
+		while (!iov[iovec_idx].iov_len)
+			iovec_idx++;
+
+		page_list = &pinned_list->page_list[iovec_idx];
+
+		iov_byte_offset = ((unsigned long)iov[iovec_idx].iov_base & ~PAGE_MASK);
+		page_idx = (((unsigned long)iov[iovec_idx].iov_base & PAGE_MASK)
+			 - ((unsigned long)page_list->base_address & PAGE_MASK)) >> PAGE_SHIFT;
+
+		/* break up copies to not cross page boundary */
+		while (iov[iovec_idx].iov_len) {
+			copy = min_t(int, PAGE_SIZE - iov_byte_offset, len);
+			copy = min_t(int, copy, iov[iovec_idx].iov_len);
+
+			dma_cookie = dma_async_memcpy_pg_to_pg(chan,
+					page_list->pages[page_idx],
+					iov_byte_offset,
+					page,
+					offset,
+					copy);
+
+			len -= copy;
+			iov[iovec_idx].iov_len -= copy;
+			iov[iovec_idx].iov_base += copy;
+
+			if (!len)
+				return dma_cookie;
+
+			offset += copy;
+			iov_byte_offset = 0;
+			page_idx++;
+		}
+		iovec_idx++;
+	}
+
+	/* really bad if we ever run out of iovecs */
+	BUG();
+	return -EFAULT;
+}
diff --git a/drivers/edac/k8_edac.c b/drivers/edac/k8_edac.c
new file mode 100644
index 000000000..d55f112cc
--- /dev/null
+++ b/drivers/edac/k8_edac.c
@@ -0,0 +1,1881 @@
+/*
+ * AMD K8 class Memory Controller kernel module
+ *
+ * This file may be distributed under the terms of the
+ * GNU General Public License.
+ *
+ * Written by Thayne Harbaugh Linux Networx (http://lnxi.com)
+ *
+ *      Changes by Douglas "norsk" Thompson  <norsk5@xmission.com>:
+ *          - K8 CPU Revision D and greater support
+ *
+ *      Changes by Dave Peterson <dsp@llnl.gov> <dave_peterson@pobox.com>:
+ *          - Module largely rewritten, with new (and hopefully correct)
+ *            code for dealing with node and chip select interleaving, various
+ *            code cleanup, and bug fixes
+ *          - Added support for memory hoisting using DRAM hole address
+ *            register
+ *
+ * This module is based on the following document (available from
+ * http://www.amd.com/):
+ *
+ *     Title: BIOS and Kernel Developer's Guide for AMD Athlon 64 and AMD
+ *            Opteron Processors
+ *     AMD publication #: 26094
+ *     Revision: 3.26
+ *
+ * Unless otherwise stated, section numbers mentioned in the comments below
+ * refer to this document.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+#include <linux/pci_ids.h>
+#include <linux/slab.h>
+#include <asm/mmzone.h>
+#include "edac_mc.h"
+
+#define k8_printk(level, fmt, arg...) \
+	edac_printk(level, "k8", fmt, ##arg)
+
+#define k8_mc_printk(mci, level, fmt, arg...) \
+	edac_mc_chipset_printk(mci, level, "k8", fmt, ##arg)
+
+/* Throughout the comments in this code, the terms SysAddr, DramAddr, and
+ * InputAddr are used.  These terms come directly from the k8 documentation
+ * (AMD publication #26094).  They are defined as follows:
+ *
+ *     SysAddr:
+ *         This is a physical address generated by a CPU core or a device
+ *         doing DMA.  If generated by a CPU core, a SysAddr is the result of
+ *         a virtual to physical address translation by the CPU core's address
+ *         translation mechanism (MMU).
+ *
+ *     DramAddr:
+ *         A DramAddr is derived from a SysAddr by subtracting an offset that
+ *         depends on which node the SysAddr maps to and whether the SysAddr
+ *         is within a range affected by memory hoisting.  The DRAM Base
+ *         (section 3.4.4.1) and DRAM Limit (section 3.4.4.2) registers
+ *         determine which node a SysAddr maps to.
+ *
+ *         If the DRAM Hole Address Register (DHAR) is enabled and the SysAddr
+ *         is within the range of addresses specified by this register, then
+ *         a value x from the DHAR is subtracted from the SysAddr to produce a
+ *         DramAddr.  Here, x represents the base address for the node that
+ *         the SysAddr maps to plus an offset due to memory hoisting.  See
+ *         section 3.4.8 and the comments in get_dram_hole_info() and
+ *         sys_addr_to_dram_addr() below for more information.
+ *
+ *         If the SysAddr is not affected by the DHAR then a value y is
+ *         subtracted from the SysAddr to produce a DramAddr.  Here, y is the
+ *         base address for the node that the SysAddr maps to.  See section
+ *         3.4.4 and the comments in sys_addr_to_dram_addr() below for more
+ *         information.
+ *
+ *     InputAddr:
+ *         A DramAddr is translated to an InputAddr before being passed to the
+ *         memory controller for the node that the DramAddr is associated
+ *         with.  The memory controller then maps the InputAddr to a csrow.
+ *         If node interleaving is not in use, then the InputAddr has the same
+ *         value as the DramAddr.  Otherwise, the InputAddr is produced by
+ *         discarding the bits used for node interleaving from the DramAddr.
+ *         See section 3.4.4 for more information.
+ *
+ *         The memory controller for a given node uses its DRAM CS Base and
+ *         DRAM CS Mask registers to map an InputAddr to a csrow.  See
+ *         sections 3.5.4 and 3.5.5 for more information.
+ */
+
+/*
+ * Alter this version for the K8 module when modifications are made
+ */
+#define EDAC_K8_VERSION    " Ver: 2.0.0 " __DATE__
+#define EDAC_MOD_STR	"k8_edac"
+
+#ifndef PCI_DEVICE_ID_AMD_OPT_0_HT
+#define PCI_DEVICE_ID_AMD_OPT_0_HT	0x1100
+#endif				/* PCI_DEVICE_ID_AMD_OPT_0_HT */
+
+#ifndef PCI_DEVICE_ID_AMD_OPT_1_ADDRMAP
+#define PCI_DEVICE_ID_AMD_OPT_1_ADDRMAP	0x1101
+#endif				/* PCI_DEVICE_ID_AMD_OPT_1_ADDRMAP */
+
+#ifndef PCI_DEVICE_ID_AMD_OPT_2_MEMCTL
+#define PCI_DEVICE_ID_AMD_OPT_2_MEMCTL	0x1102
+#endif				/* PCI_DEVICE_ID_AMD_OPT_2_MEMCTL */
+
+#ifndef PCI_DEVICE_ID_AMD_OPT_3_MISCCTL
+#define PCI_DEVICE_ID_AMD_OPT_3_MISCCTL	0x1103
+#endif				/* PCI_DEVICE_ID_AMD_OPT_3_MISCCTL */
+
+/* Extended Model from CPUID, for CPU Revision numbers */
+#define OPTERON_CPU_LE_REV_C    0
+#define OPTERON_CPU_REV_D       1
+#define OPTERON_CPU_REV_E       2
+
+#define K8_NR_CSROWS 8
+#define MAX_K8_NODES 8
+
+/* K8 register addresses - device 0 function 1 - Address Map */
+#define K8_DBR		0x40	/* DRAM Base Register (8 x 32b
+				 * interlaced with K8_DLR)
+				 *
+				 * 31:16 DRAM Base addr 39:24
+				 * 15:11 reserved
+				 * 10:8  interleave enable
+				 *  7:2  reserved
+				 *  1    write enable
+				 *  0    read enable
+				 */
+
+#define K8_DLR		0x44	/* DRAM Limit Register (8 x 32b
+				 * interlaced with K8_DBR)
+				 *
+				 * 31:16 DRAM Limit addr 32:24
+				 * 15:11 reserved
+				 * 10:8  interleave select
+				 *  7:3  reserved
+				 *  2:0  destination node ID
+				 */
+
+#define K8_DHAR         0xf0    /* DRAM Hole Address Register
+				 *
+				 * 31:24 DramHoleBase
+				 * 23:16 reserved
+				 * 15:8  DramHoleOffset
+				 *  7:1  reserved
+				 *    0  DramHoleValid
+				 */
+
+/* K8 register addresses - device 0 function 2 - DRAM controller */
+#define K8_DCSB		0x40	/* DRAM Chip-Select Base (8 x 32b)
+				 *
+				 * 31:21 Base addr high 35:25
+				 * 20:16 reserved
+				 * 15:9  Base addr low 19:13 (interlvd)
+				 *  8:1  reserved
+				 *  0    chip-select bank enable
+				 */
+
+#define K8_DCSM		0x60	/* DRAM Chip-Select Mask (8 x 32b)
+				 *
+				 * 31:30 reserved
+				 * 29:21 addr mask high 33:25
+				 * 20:16 reserved
+				 * 15:9  addr mask low  19:13
+				 *  8:0  reserved
+				 */
+
+/* selects bits 29-21 and 15-9 from DCSM */
+#define DCSM_MASK_BITS 0x3fe0fe00
+
+#define K8_DBAM		0x80	/* DRAM Base Addr Mapping (32b) */
+
+#define K8_DCL		0x90	/* DRAM configuration low reg (32b)
+				 *
+				 * 31:28 reserved
+				 * 27:25 Bypass Max: 000b=respect
+				 * 24    Dissable receivers - no sockets
+				 * 23:20 x4 DIMMS
+				 * 19    32byte chunks
+				 * 18    Unbuffered
+				 * 17    ECC enabled
+				 * 16    128/64 bit (dual/single chan)
+				 * 15:14 R/W Queue bypass count
+				 * 13    Self refresh
+				 * 12    exit self refresh
+				 * 11    mem clear status
+				 * 10    DRAM enable
+				 *  9    reserved
+				 *  8    DRAM init
+				 *  7:4  reserved
+				 *  3    dis DQS hysteresis
+				 *  2    QFC enabled
+				 *  1    DRAM drive strength
+				 *  0    Digital Locked Loop disable
+				 */
+
+/* K8 register addresses - device 0 function 3 - Misc Control */
+#define K8_NBCTL	0x40	/* MCA NB Control (32b)
+				 *
+				 *  1    MCA UE Reporting
+				 *  0    MCA CE Reporting
+				 */
+
+#define K8_NBCFG	0x44	/* MCA NB Config (32b)
+				 *
+				 * 23    Chip-kill x4 ECC enable
+				 * 22    ECC enable
+				 *  1    CPU ECC enable
+				 */
+
+#define K8_NBSL		0x48	/* MCA NB Status Low (32b)
+				 *
+				 * 31:24 Syndrome 15:8 chip-kill x4
+				 * 23:20 reserved
+				 * 19:16 Extended err code
+				 * 15:0  Err code
+				 */
+
+#define K8_NBSH		0x4C	/* MCA NB Status High (32b)
+				 *
+				 * 31    Err valid
+				 * 30    Err overflow
+				 * 29    Uncorrected err
+				 * 28    Err enable
+				 * 27    Misc err reg valid
+				 * 26    Err addr valid
+				 * 25    proc context corrupt
+				 * 24:23 reserved
+				 * 22:15 Syndrome 7:0
+				 * 14    CE
+				 * 13    UE
+				 * 12:9  reserved
+				 *  8    err found by scrubber
+				 *  7    reserved
+				 *  6:4  Hyper-transport link number
+				 *  3:2  reserved
+				 *  1    Err CPU 1
+				 *  0    Err CPU 0
+				 */
+
+#define K8_NBSH_VALID_BIT BIT(31)
+
+#define K8_NBEAL	0x50	/* MCA NB err addr low (32b)
+				 *
+				 * 31:3  Err addr low 31:3
+				 *  2:0  reserved
+				 */
+
+#define K8_NBEAH	0x54	/* MCA NB err addr high (32b)
+				 *
+				 * 31:8  reserved
+				 *  7:0  Err addr high 39:32
+				 */
+
+#define K8_NBCAP	0xE8	/* MCA NB capabilities (32b)
+				 *
+				 * 31:9  reserved
+				 *  4    S4ECD4ED capable
+				 *  3    SECDED capable
+				 */
+
+				/* MSR's */
+
+				/*
+				 * K8_MSR_MCxCTL (64b)
+				 * (0x400,404,408,40C,410)
+				 * 63    Enable reporting source 63
+				 *  .
+				 *  .
+				 *  .
+				 *  2    Enable error source 2
+				 *  1    Enable error source 1
+				 *  0    Enable error source 0
+				 */
+
+				/*
+				 * K8_MSR_MCxSTAT (64b)
+				 * (0x401,405,409,40D,411)
+				 * 63    Error valid
+				 * 62    Status overflow
+				 * 61    UE
+				 * 60    Enabled error condition
+				 * 59    Misc register valid (not used)
+				 * 58    Err addr register valid
+				 * 57    Processor context corrupt
+				 * 56:32 Other information
+				 * 31:16 Model specific error code
+				 * 15:0  MCA err code
+				 */
+
+				/*
+				 * K8_MSR_MCxADDR (64b)
+				 * (0x402,406,40A,40E,412)
+				 * 63:48 reserved
+				 * 47:0  Address
+				 */
+
+				/*
+				 * K8_MSR_MCxMISC (64b)
+				 * (0x403,407,40B,40F,413)
+				 * Unused on Athlon64 and K8
+				 */
+
+#define K8_MSR_MCGCTL	0x017b	/* Machine Chk Global report ctl (64b)
+				 *
+				 * 31:5  reserved
+				 *  4    North Bridge
+				 *  3    Load/Store
+				 *  2    Bus Unit
+				 *  1    Instruction Cache
+				 *  0    Data Cache
+				 */
+
+#define K8_MSR_MC4CTL	0x0410	/* North Bridge Check report ctl (64b) */
+#define K8_MSR_MC4STAT	0x0411	/* North Bridge status (64b) */
+#define K8_MSR_MC4ADDR	0x0412	/* North Bridge Address (64b) */
+
+static inline int MCI_TO_NODE_ID(struct mem_ctl_info *mci)
+{
+	return PCI_SLOT(to_pci_dev(mci->dev)->devfn) - 0x18;
+}
+
+/* Ugly hack that allows module to compile when built as part of a 32-bit
+ * kernel.  Just in case anyone wants to run a 32-bit kernel on their Opteron.
+ */
+#ifndef MAXNODE
+#define MAXNODE 8
+#endif
+
+/* Each entry holds the CPU revision of all CPU cores for the given node. */
+static int k8_node_revision_table[MAXNODE] = { 0 };
+
+static inline int node_rev(int node_id)
+{
+	return k8_node_revision_table[node_id];
+}
+
+static void store_node_revision(void *param)
+{
+	int node_id, revision;
+
+	/* Multiple CPU cores on the same node will all write their revision
+	 * number to the same array entry.  This is ok.  For a given node, all
+	 * CPU cores are on the same piece of silicon and share the same
+	 * revision number.
+	 */
+	node_id = (cpuid_ebx(1) >> 24) & 0x07;
+	revision = (cpuid_eax(1) >> 16) & 0x0f;
+	k8_node_revision_table[node_id] = revision;
+}
+
+/* Initialize k8_node_revision_table. */
+static void build_node_revision_table(void)
+{
+	static int initialized = 0;
+
+	if (initialized)
+		return;
+
+	on_each_cpu(store_node_revision, NULL, 1, 1);
+	initialized = 1;
+}
+
+enum k8_chips {
+	OPTERON = 0,
+};
+
+struct k8_pvt {
+	struct pci_dev *addr_map;
+	struct pci_dev *misc_ctl;
+
+	int node_id;  /* ID of this node */
+
+	/* The values of these registers will remain constant so we might as
+	 * well cache them here.
+	 */
+	u32 dcl;
+	u32 dbr[MAX_K8_NODES];
+	u32 dlr[MAX_K8_NODES];
+	u32 nbcap;
+	u32 dcsb[K8_NR_CSROWS];
+	u32 dcsm[K8_NR_CSROWS];
+	u32 dhar;
+	u32 dbam;
+};
+
+struct k8_error_info_regs {
+	u32 nbsh;
+	u32 nbsl;
+	u32 nbeah;
+	u32 nbeal;
+};
+
+struct k8_error_info {
+	struct k8_error_info_regs error_info;
+	u32 nbcfg;
+	int race_condition_detected;
+};
+
+struct k8_dev_info {
+	const char *ctl_name;
+	u16 addr_map;
+	u16 misc_ctl;
+};
+
+static const struct k8_dev_info k8_devs[] = {
+	[OPTERON] = {
+		     .ctl_name = "Athlon64/Opteron",
+		     .addr_map = PCI_DEVICE_ID_AMD_OPT_1_ADDRMAP,
+		     .misc_ctl = PCI_DEVICE_ID_AMD_OPT_3_MISCCTL},
+};
+
+static struct pci_dev * pci_get_related_function(unsigned int vendor,
+		unsigned int device, struct pci_dev *related)
+{
+	struct pci_dev *dev;
+
+	dev = NULL;
+
+	while ((dev = pci_get_device(vendor, device, dev)) != NULL) {
+		if ((dev->bus->number == related->bus->number) &&
+		    (PCI_SLOT(dev->devfn) == PCI_SLOT(related->devfn)))
+			break;
+	}
+
+	return dev;
+}
+
+/* FIXME - stolen from msr.c - the calls in msr.c could be exported */
+struct msr_command {
+	int cpu;
+	int err;
+	u32 reg;
+	u32 data[2];
+};
+
+static void smp_wrmsr(void *cmd_block)
+{
+	struct msr_command *cmd = cmd_block;
+	wrmsr(cmd->reg, cmd->data[0], cmd->data[1]);
+}
+
+static void smp_rdmsr(void *cmd_block)
+{
+	struct msr_command *cmd = cmd_block;
+	rdmsr(cmd->reg, cmd->data[0], cmd->data[1]);
+}
+
+static void do_wrmsr(int cpu, u32 reg, u32 eax, u32 edx)
+{
+	struct msr_command cmd;
+
+	cmd.cpu = raw_smp_processor_id();
+	cmd.reg = reg;
+	cmd.data[0] = eax;
+	cmd.data[1] = edx;
+	on_each_cpu(smp_wrmsr, &cmd, 1, 1);
+}
+
+static void do_rdmsr(int cpu, u32 reg, u32 *eax, u32 *edx)
+{
+	struct msr_command cmd;
+
+	cmd.cpu = raw_smp_processor_id();
+	cmd.reg = reg;
+	on_each_cpu(smp_rdmsr, &cmd, 1, 1);
+	*eax = cmd.data[0];
+	*edx = cmd.data[1];
+}
+
+/*
+ * FIXME - This is a large chunk of memory to suck up just to decode the
+ * syndrome.  It would be nice to discover a pattern in the syndromes that
+ * could be used to quickly identify the channel.  The big problems with
+ * this table is memory usage, lookup speed (could sort and binary search),
+ * correctness (there could be a transcription error).  A zero in any nibble
+ * for a syndrom is always channel 0, but that only decodes some of the
+ * syndromes.  Can anyone find any other patterns?
+ *
+ * The comment in the left column is the nibble that is in error.  The least
+ * significant nibble of the syndrome is the mask for the bits that are
+ * in error (need to be toggled) for the particular nibble.
+ */
+#define SYNDROME_TABLE_SIZE 270
+static const unsigned long syndromes_chan0[SYNDROME_TABLE_SIZE] = {
+	/*0 */ 0xe821, 0x7c32, 0x9413, 0xbb44, 0x5365, 0xc776, 0x2f57,
+	0xdd88, 0x35a9, 0xa1ba, 0x499b, 0x66cc, 0x8eed, 0x1afe, 0xf2df,
+	/*1 */ 0x5d31, 0xa612, 0xfb23, 0x9584, 0xc8b5, 0x3396, 0x6ea7,
+	0xeac8, 0xb7f9, 0x4cda, 0x11eb, 0x7f4c, 0x227d, 0xd95e, 0x846f,
+	/*2 */ 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007,
+	0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f,
+	/*3 */ 0x2021, 0x3032, 0x1013, 0x4044, 0x6065, 0x7076, 0x5057,
+	0x8088, 0xa0a9, 0xb0ba, 0x909b, 0xc0cc, 0xe0ed, 0xf0fe, 0xd0df,
+	/*4 */ 0x5041, 0xa082, 0xf0c3, 0x9054, 0xc015, 0x30d6, 0x6097,
+	0xe0a8, 0xb0e9, 0x402a, 0x106b, 0x70fc, 0x20bd, 0xd07e, 0x803f,
+	/*5 */ 0xbe21, 0xd732, 0x6913, 0x2144, 0x9f65, 0xf676, 0x4857,
+	0x3288, 0x8ca9, 0xe5ba, 0x5b9b, 0x13cc, 0xaded, 0xc4fe, 0x7adf,
+	/*6 */ 0x4951, 0x8ea2, 0xc7f3, 0x5394, 0x1ac5, 0xdd36, 0x9467,
+	0xa1e8, 0xe8b9, 0x2f4a, 0x661b, 0xf27c, 0xbb2d, 0x7cde, 0x358f,
+	/*7 */ 0x74e1, 0x9872, 0xec93, 0xd6b4, 0xa255, 0x4ec6, 0x3a27,
+	0x6bd8, 0x1f39, 0xf3aa, 0x874b, 0xbd6c, 0xc98d, 0x251e, 0x51ff,
+	/*8 */ 0x15c1, 0x2a42, 0x3f83, 0xcef4, 0xdb35, 0xe4b6, 0xf177,
+	0x4758, 0x5299, 0x6d1a, 0x78db, 0x89ac, 0x9c6d, 0xa3ee, 0xb62f,
+	/*9 */ 0x3d01, 0x1602, 0x2b03, 0x8504, 0xb805, 0x9306, 0xae07,
+	0xca08, 0xf709, 0xdc0a, 0xe10b, 0x4f0c, 0x720d, 0x590e, 0x640f,
+	/*a */ 0x9801, 0xec02, 0x7403, 0x6b04, 0xf305, 0x8706, 0x1f07,
+	0xbd08, 0x2509, 0x510a, 0xc90b, 0xd60c, 0x4e0d, 0x3a0e, 0xa20f,
+	/*b */ 0xd131, 0x6212, 0xb323, 0x3884, 0xe9b5, 0x5a96, 0x8ba7,
+	0x1cc8, 0xcdf9, 0x7eda, 0xafeb, 0x244c, 0xf57d, 0x465e, 0x976f,
+	/*c */ 0xe1d1, 0x7262, 0x93b3, 0xb834, 0x59e5, 0xca56, 0x2b87,
+	0xdc18, 0x3dc9, 0xae7a, 0x4fab, 0x542c, 0x85fd, 0x164e, 0xf79f,
+	/*d */ 0x6051, 0xb0a2, 0xd0f3, 0x1094, 0x70c5, 0xa036, 0xc067,
+	0x20e8, 0x40b9, 0x904a, 0x601b, 0x307c, 0x502d, 0x80de, 0xe08f,
+	/*e */ 0xa4c1, 0xf842, 0x5c83, 0xe6f4, 0x4235, 0x1eb6, 0xba77,
+	0x7b58, 0xdf99, 0x831a, 0x27db, 0x9dac, 0x396d, 0x65ee, 0xc12f,
+	/*f */ 0x11c1, 0x2242, 0x3383, 0xc8f4, 0xd935, 0xeab6, 0xfb77,
+	0x4c58, 0x5d99, 0x6e1a, 0x7fdb, 0x84ac, 0x9562, 0xa6ee, 0xb72f,
+
+	/*20 */ 0xbe01, 0xd702, 0x6903, 0x2104, 0x9f05, 0xf606, 0x4807,
+	0x3208, 0x8c09, 0xe50a, 0x5b0b, 0x130c, 0xad0d, 0xc40e, 0x7a0f,
+	/*21 */ 0x4101, 0x8202, 0xc303, 0x5804, 0x1905, 0xda06, 0x9b07,
+	0xac08, 0xed09, 0x2e0a, 0x6f0b, 0x640c, 0xb50d, 0x760e, 0x370f
+};
+
+static const unsigned long syndromes_chan1[SYNDROME_TABLE_SIZE] = {
+	/*10 */ 0x45d1, 0x8a62, 0xcfb3, 0x5e34, 0x1be5, 0xd456, 0x9187,
+	0xa718, 0xe2c9, 0x2d7a, 0x68ab, 0xf92c, 0xbcfd, 0x734e, 0x369f,
+	/*11 */ 0x63e1, 0xb172, 0xd293, 0x14b4, 0x7755, 0xa5c6, 0xc627,
+	0x28d8, 0x4b39, 0x99aa, 0xfa4b, 0x3c6c, 0x5f8d, 0x8d1e, 0xeeff,
+	/*12 */ 0xb741, 0xd982, 0x6ec3, 0x2254, 0x9515, 0xfbd6, 0x4c97,
+	0x33a8, 0x84e9, 0xea2a, 0x5d6b, 0x11fc, 0xa6bd, 0xc87e, 0x7f3f,
+	/*13 */ 0xdd41, 0x6682, 0xbbc3, 0x3554, 0xe815, 0x53d6, 0xce97,
+	0x1aa8, 0xc7e9, 0x7c2a, 0xa1fb, 0x2ffc, 0xf2bd, 0x497e, 0x943f,
+	/*14 */ 0x2bd1, 0x3d62, 0x16b3, 0x4f34, 0x64e5, 0x7256, 0x5987,
+	0x8518, 0xaec9, 0xb87a, 0x93ab, 0xca2c, 0xe1fd, 0xf74e, 0xdc9f,
+	/*15 */ 0x83c1, 0xc142, 0x4283, 0xa4f4, 0x2735, 0x65b6, 0xe677,
+	0xf858, 0x7b99, 0x391a, 0xbadb, 0x5cac, 0xdf6d, 0x9dee, 0x1e2f,
+	/*16 */ 0x8fd1, 0xc562, 0x4ab3, 0xa934, 0x26e5, 0x6c56, 0xe387,
+	0xfe18, 0x71c9, 0x3b7a, 0xb4ab, 0x572c, 0xd8fd, 0x924e, 0x1d9f,
+	/*17 */ 0x4791, 0x89e2, 0xce73, 0x5264, 0x15f5, 0xdb86, 0x9c17,
+	0xa3b8, 0xe429, 0x2a5a, 0x6dcb, 0xf1dc, 0xb64d, 0x783e, 0x3faf,
+	/*18 */ 0x5781, 0xa9c2, 0xfe43, 0x92a4, 0xc525, 0x3b66, 0x6ce7,
+	0xe3f8, 0xb479, 0x4a3a, 0x1dbb, 0x715c, 0x26dd, 0xd89e, 0x8f1f,
+	/*19 */ 0xbf41, 0xd582, 0x6ac3, 0x2954, 0x9615, 0xfcd6, 0x4397,
+	0x3ea8, 0x81e9, 0xeb2a, 0x546b, 0x17fc, 0xa8bd, 0xc27e, 0x7d3f,
+	/*1a */ 0x9891, 0xe1e2, 0x7273, 0x6464, 0xf7f5, 0x8586, 0x1617,
+	0xb8b8, 0x2b29, 0x595a, 0xcacb, 0xdcdc, 0x4f4d, 0x3d3e, 0xaeaf,
+	/*1b */ 0xcce1, 0x4472, 0x8893, 0xfdb4, 0x3f55, 0xb9c6, 0x7527,
+	0x56d8, 0x9a39, 0x12aa, 0xde4b, 0xab6c, 0x678d, 0xef1e, 0x23ff,
+	/*1c */ 0xa761, 0xf9b2, 0x5ed3, 0xe214, 0x4575, 0x1ba6, 0xbcc7,
+	0x7328, 0xd449, 0x8a9a, 0x2dfb, 0x913c, 0x365d, 0x688e, 0xcfef,
+	/*1d */ 0xff61, 0x55b2, 0xaad3, 0x7914, 0x8675, 0x2ca6, 0xd3c7,
+	0x9e28, 0x6149, 0xcb9a, 0x34fb, 0xe73c, 0x185d, 0xb28e, 0x4def,
+	/*1e */ 0x5451, 0xa8a2, 0xfcf3, 0x9694, 0xc2c5, 0x3e36, 0x6a67,
+	0xebe8, 0xbfb9, 0x434a, 0x171b, 0x7d7c, 0x292d, 0xd5de, 0x818f,
+	/*1f */ 0x6fc1, 0xb542, 0xda83, 0x19f4, 0x7635, 0xacb6, 0xc377,
+	0x2e58, 0x4199, 0x9b1a, 0xf4db, 0x37ac, 0x586d, 0x82ee, 0xed2f,
+
+	/*22 */ 0xc441, 0x4882, 0x8cc3, 0xf654, 0x3215, 0xbed6, 0x7a97,
+	0x5ba8, 0x9fe9, 0x132a, 0xd76b, 0xadfc, 0x69bd, 0xe57e, 0x213f,
+	/*23 */ 0x7621, 0x9b32, 0xed13, 0xda44, 0xac65, 0x4176, 0x3757,
+	0x6f88, 0x19a9, 0xf4ba, 0x829b, 0xb5cc, 0xc3ed, 0x2efe, 0x58df
+};
+
+static int chan_from_chipkill_syndrome(unsigned long syndrome)
+{
+	int i;
+
+	debugf0("%s()\n", __func__);
+
+	for (i = 0; i < SYNDROME_TABLE_SIZE; i++) {
+		if (syndromes_chan0[i] == syndrome)
+			return 0;
+		if (syndromes_chan1[i] == syndrome)
+			return 1;
+	}
+
+	debugf0("%s(): syndrome(%lx) not found\n", __func__, syndrome);
+	return -1;
+}
+
+static const char *tt_msgs[] = {	/* transaction type */
+	"inst",
+	"data",
+	"generic",
+	"reserved"
+};
+
+static const char *ll_msgs[] = {	/* cache level */
+	"0",
+	"1",
+	"2",
+	"generic"
+};
+
+static const char *memtt_msgs[] = {
+	"generic",
+	"generic read",
+	"generic write",
+	"data read",
+	"data write",
+	"inst fetch",
+	"prefetch",
+	"evict",
+	"snoop",
+	"unknown error 9",
+	"unknown error 10",
+	"unknown error 11",
+	"unknown error 12",
+	"unknown error 13",
+	"unknown error 14",
+	"unknown error 15"
+};
+
+static const char *pp_msgs[] = {	/* participating processor */
+	"local node origin",
+	"local node response",
+	"local node observed",
+	"generic"
+};
+
+static const char *to_msgs[] = {
+	"no timeout",
+	"timed out"
+};
+
+static const char *ii_msgs[] = {	/* memory or i/o */
+	"mem access",
+	"reserved",
+	"i/o access",
+	"generic"
+};
+
+static const char *ext_msgs[] = {	/* extended error */
+	"ECC error",
+	"CRC error",
+	"sync error",
+	"mst abort",
+	"tgt abort",
+	"GART error",
+	"RMW error",
+	"watchdog error",
+	"ECC chipkill x4 error",
+	"unknown error 9",
+	"unknown error 10",
+	"unknown error 11",
+	"unknown error 12",
+	"unknown error 13",
+	"unknown error 14",
+	"unknown error 15"
+};
+
+static const char *htlink_msgs[] = {
+	"none",
+	"1",
+	"2",
+	"1 2",
+	"3",
+	"1 3",
+	"2 3",
+	"1 2 3"
+};
+
+static inline u64 base_from_dcsb(u32 dcsb)
+{
+	/* 0xffe0fe00 selects bits 31-21 and 15-9 of a DRAM CS Base Address
+	 * Register (section 3.5.4).  Shifting the bits left 4 puts them in
+	 * their proper bit positions of 35-25 and 19-13.
+	 */
+	return ((u64) (dcsb & 0xffe0fe00)) << 4;
+}
+
+static u64 mask_from_dcsm(u32 dcsm)
+{
+	u64 dcsm_bits, other_bits;
+
+	/* Extract bits bits 29-21 and 15-9 from DCSM (section 3.5.5). */
+	dcsm_bits = dcsm & DCSM_MASK_BITS;
+
+	/* Set all bits except bits 33-25 and 19-13. */
+	other_bits = DCSM_MASK_BITS;
+	other_bits = ~(other_bits << 4);
+
+	/* The extracted bits from DCSM belong in the spaces represented by
+	 * the cleared bits in other_bits.
+	 */
+	return (dcsm_bits << 4) | other_bits;
+}
+
+/* In *base and *limit, pass back the full 40-bit base and limit physical
+ * addresses for the node given by node_id.  This information is obtained from
+ * DRAM Base (section 3.4.4.1) and DRAM Limit (section 3.4.4.2) registers. The
+ * base and limit addresses are of type SysAddr, as defined at the start of
+ * section 3.4.4 (p. 70).  They are the lowest and highest physical addresses
+ * in the address range they represent.
+ */
+static void get_base_and_limit(struct k8_pvt *pvt, int node_id,
+		u64 *base, u64 *limit)
+{
+	*base = ((u64) (pvt->dbr[node_id] & 0xffff0000)) << 8;
+
+	/* Since the limit represents the highest address in the range, we
+	 * must set its lowest 24 bits to 1.
+	 */
+	*limit = (((u64) (pvt->dlr[node_id] & 0xffff0000)) << 8) | 0xffffff;
+}
+
+/* Return 1 if the SysAddr given by sys_addr matches the base/limit associated
+ * with node_id
+ */
+static int base_limit_match(struct k8_pvt *pvt, u64 sys_addr, int node_id)
+{
+	u64 base, limit, addr;
+
+	get_base_and_limit(pvt, node_id, &base, &limit);
+
+	/* The k8 treats this as a 40-bit value.  However, bits 63-40 will be
+	 * all ones if the most significant implemented address bit is 1.
+	 * Here we discard bits 63-40.  See section 3.4.2 of AMD publication
+	 * 24592: AMD x86-64 Architecture Programmer's Manual Volume 1
+	 * Application Programming.
+	 */
+	addr = sys_addr & 0x000000ffffffffffull;
+
+	return (addr >= base) && (addr <= limit);
+}
+
+/* Attempt to map a SysAddr to a node.  On success, return a pointer to the
+ * mem_ctl_info structure for the node that the SysAddr maps to.  On failure,
+ * return NULL.
+ */
+static struct mem_ctl_info * find_mc_by_sys_addr(struct mem_ctl_info *mci,
+						u64 sys_addr)
+{
+	struct k8_pvt *pvt;
+	int node_id;
+	u32 intlv_en, bits;
+
+	/* Here we use the DRAM Base (section 3.4.4.1) and DRAM Limit (section
+	 * 3.4.4.2) registers to map the SysAddr to a node ID.
+	 */
+
+	pvt = mci->pvt_info;
+
+	/* The value of this field should be the same for all DRAM Base
+	 * registers.  Therefore we arbitrarily choose to read it from the
+	 * register for node 0.
+	 */
+	intlv_en = pvt->dbr[0] & (0x07 << 8);
+
+	if (intlv_en == 0) {  /* node interleaving is disabled */
+		debugf2("%s(): node interleaving disabled\n", __func__);
+		for (node_id = 0; ; ) {
+			if (base_limit_match(pvt, sys_addr, node_id))
+				break;
+
+			if (++node_id == MAX_K8_NODES) {
+				debugf2("%s(): sys_addr 0x%lx "
+					"does not match any node\n", __func__,
+					(unsigned long) sys_addr);
+				return NULL;
+			}
+		}
+
+		goto found;
+	}
+
+	if (unlikely((intlv_en != (0x01 << 8)) &&
+		     (intlv_en != (0x03 << 8)) &&
+		     (intlv_en != (0x07 << 8)))) {
+		k8_printk(KERN_WARNING,
+			  "%s(): junk value of 0x%x extracted from IntlvEn "
+			  "field of DRAM Base Register for node 0: This "
+			  "probably indicates a BIOS bug.\n", __func__,
+			  intlv_en);
+		return NULL;
+	}
+
+	/* If we get this far, node interleaving is enabled. */
+	debugf2("%s(): node interleaving enabled\n", __func__);
+	bits = (((u32) sys_addr) >> 12) & intlv_en;
+
+	for (node_id = 0; ; ) {
+		if ((pvt->dlr[node_id] & intlv_en) == bits)
+			break;  /* intlv_sel field matches */
+
+		if (++node_id == MAX_K8_NODES) {
+			debugf2("%s(): sys_addr 0x%lx does not match any "
+				"node\n", __func__, (unsigned long) sys_addr);
+			return NULL;
+		}
+	}
+
+	/* sanity test for sys_addr */
+	if (unlikely(!base_limit_match(pvt, sys_addr, node_id))) {
+		k8_printk(KERN_WARNING,
+			  "%s(): sys_addr 0x%lx falls outside base/limit "
+			  "address range for node %d with node interleaving "
+			  "enabled.\n", __func__, (unsigned long) sys_addr,
+			  node_id);
+		return NULL;
+	}
+
+found:
+	debugf2("%s(): sys_addr 0x%lx matches node %d\n", __func__,
+		(unsigned long) sys_addr, node_id);
+	return edac_mc_find(node_id);
+}
+
+/* Return the base value defined by the DRAM Base register for the node
+ * represented by mci.  This function returns the full 40-bit value despite
+ * the fact that the register only stores bits 39-24 of the value.  See
+ * section 3.4.4.1.
+ */
+static inline u64 get_dram_base(struct mem_ctl_info *mci)
+{
+	struct k8_pvt *pvt;
+
+	pvt = mci->pvt_info;
+	return ((u64) (pvt->dbr[pvt->node_id] & 0xffff0000)) << 8;
+}
+
+/* Obtain info from the DRAM Hole Address Register (section 3.4.8) for the
+ * node represented by mci.  Info is passed back in *hole_base, *hole_offset,
+ * and *hole_size.  Function returns 0 if info is valid or 1 if info is
+ * invalid.  Info may be invalid for either of the following reasons:
+ *
+ *     - The revision of the node is not E or greater.  In this case, the DRAM
+ *       Hole Address Register does not exist.
+ *     - The DramHoleValid bit is cleared in the DRAM Hole Address Register,
+ *       indicating that its contents are not valid.
+ *
+ * The values passed back in *hole_base, *hole_offset, and *hole_size are
+ * complete 32-bit values despite the fact that the bitfields in the DHAR
+ * only represent bits 31-24 of the base and offset values.
+ */
+static int get_dram_hole_info(struct mem_ctl_info *mci, u64 *hole_base,
+		u64 *hole_offset, u64 *hole_size)
+{
+	struct k8_pvt *pvt;
+	u64 base;
+
+	pvt = mci->pvt_info;
+
+	if (node_rev(pvt->node_id) < OPTERON_CPU_REV_E) {
+		debugf2("revision %d for node %d does not support DHAR\n",
+			node_rev(pvt->node_id), pvt->node_id);
+		return 1;
+	}
+
+	if ((pvt->dhar & 0x01) == 0) {
+		debugf2("DramHoleValid bit cleared in DHAR for node %d\n",
+			pvt->node_id);
+		return 1;  /* DramHoleValid bit is cleared */
+	}
+
+	/* +------------------+--------------------+--------------------+-----
+	 * | memory           | DRAM hole          | relocated          |
+	 * | [0, (x - 1)]     | [x, 0xffffffff]    | addresses from     |
+	 * |                  |                    | DRAM hole          |
+	 * |                  |                    | [0x100000000,      |
+	 * |                  |                    |  (0x100000000+     |
+	 * |                  |                    |   (0xffffffff-x))] |
+	 * +------------------+--------------------+--------------------+-----
+	 *
+	 * Above is a diagram of physical memory showing the DRAM hole and the
+	 * relocated addresses from the DRAM hole.  As shown, the DRAM hole
+	 * starts at address x (the base address) and extends through address
+	 * 0xffffffff.  The DRAM Hole Address Register (DHAR) relocates the
+	 * addresses in the hole so that they start at 0x100000000.
+	 */
+
+	base = pvt->dhar & 0xff000000;
+	*hole_base = base;
+	*hole_offset = (pvt->dhar & 0x0000ff00) << 16;
+	*hole_size = (0x1ull << 32) - base;
+	debugf2("DHAR info for node %d: base 0x%lx offset 0x%lx size 0x%lx\n",
+		pvt->node_id, (unsigned long) *hole_base,
+		(unsigned long) *hole_offset, (unsigned long) *hole_size);
+	return 0;
+}
+
+/* Return the DramAddr that the SysAddr given by sys_addr maps to.  It is
+ * assumed that sys_addr maps to the node given by mci.
+ */
+static u64 sys_addr_to_dram_addr(struct mem_ctl_info *mci, u64 sys_addr)
+{
+	u64 dram_base, hole_base, hole_offset, hole_size, dram_addr;
+
+	/* The first part of section 3.4.4 (p. 70) shows how the DRAM Base
+	 * (section 3.4.4.1) and DRAM Limit (section 3.4.4.2) registers are
+	 * used to translate a SysAddr to a DramAddr.  If the DRAM Hole
+	 * Address Register (DHAR) is enabled, then it is also involved in
+	 * translating a SysAddr to a DramAddr.  Sections 3.4.8 and 3.5.8.2
+	 * describe the DHAR and how it is used for memory hoisting.  These
+	 * parts of the documentation are unclear.  I interpret them as
+	 * follows:
+	 *
+	 *     When node n receives a SysAddr, it processes the SysAddr as
+	 *     follows:
+	 *
+	 *         1.  It extracts the DRAMBase and DRAMLimit values from the
+	 *             DRAM Base and DRAM Limit registers for node n.  If the
+	 *             SysAddr is not within the range specified by the base
+	 *             and limit values, then node n ignores the Sysaddr
+	 *             (since it does not map to node n).  Otherwise continue
+	 *             to step 2 below.
+	 *
+	 *         2.  If the DramHoleValid bit of the DHAR for node n is
+	 *             clear, the DHAR is disabled so skip to step 3 below.
+	 *             Otherwise see if the SysAddr is within the range of
+	 *             relocated addresses (starting at 0x100000000) from the
+	 *             DRAM hole.  If not, skip to step 3 below.  Else get the
+	 *             value of the DramHoleOffset field from the DHAR.  To
+	 *             obtain the DramAddr, subtract the offset defined by
+	 *             this value from the SysAddr.
+	 *
+	 *         3.  Obtain the base address for node n from the DRAMBase
+	 *             field of the DRAM Base register for node n.  To obtain
+	 *             the DramAddr, subtract the base address from the
+	 *             SysAddr, as shown near the start of section 3.4.4
+	 *             (p. 70).
+	 */
+
+	dram_base = get_dram_base(mci);
+
+	if (!get_dram_hole_info(mci, &hole_base, &hole_offset, &hole_size)) {
+		if ((sys_addr >= (1ull << 32)) &&
+		    (sys_addr < ((1ull << 32) + hole_size))) {
+			/* use DHAR to translate SysAddr to DramAddr */
+			dram_addr = sys_addr - hole_offset;
+			debugf2("using DHAR to translate SysAddr 0x%lx to "
+				"DramAddr 0x%lx\n",
+				(unsigned long) sys_addr,
+				(unsigned long) dram_addr);
+			return dram_addr;
+		}
+	}
+
+	/* Translate the SysAddr to a DramAddr as shown near the start of
+	 * section 3.4.4 (p. 70).  Although sys_addr is a 64-bit value, the k8
+	 * only deals with 40-bit values.  Therefore we discard bits 63-40 of
+	 * sys_addr below.  If bit 39 of sys_addr is 1 then the bits we
+	 * discard are all 1s.  Otherwise the bits we discard are all 0s.  See
+	 * section 3.4.2 of AMD publication 24592: AMD x86-64 Architecture
+	 * Programmer's Manual Volume 1 Application Programming.
+	 */
+	dram_addr = (sys_addr & 0xffffffffffull) - dram_base;
+
+	debugf2("using DRAM Base register to translate SysAddr 0x%lx to "
+		"DramAddr 0x%lx\n", (unsigned long) sys_addr,
+		(unsigned long) dram_addr);
+	return dram_addr;
+}
+
+/* Parameter intlv_en is the value of the IntlvEn field from a DRAM Base
+ * register (section 3.4.4.1).  Return the number of bits from a SysAddr that
+ * are used for node interleaving.
+ */
+static int num_node_interleave_bits(unsigned intlv_en)
+{
+	static const int intlv_shift_table[] = { 0, 1, 0, 2, 0, 0, 0, 3 };
+	int n;
+
+	BUG_ON(intlv_en > 7);
+	n = intlv_shift_table[intlv_en];
+	debugf2("using %d bits for node interleave\n", n);
+	return n;
+}
+
+/* Translate the DramAddr given by dram_addr to an InputAddr and return the
+ * result.
+ */
+static u64 dram_addr_to_input_addr(struct mem_ctl_info *mci, u64 dram_addr)
+{
+	struct k8_pvt *pvt;
+	int intlv_shift;
+	u64 input_addr;
+
+	pvt = mci->pvt_info;
+
+	/* Near the start of section 3.4.4 (p. 70), the k8 documentation gives
+	 * instructions for translating a DramAddr to an InputAddr.  Here we
+	 * are following these instructions.
+	 */
+	intlv_shift = num_node_interleave_bits((pvt->dbr[0] >> 8) & 0x07);
+	input_addr = ((dram_addr >> intlv_shift) & 0xffffff000ull) +
+	    (dram_addr & 0xfff);
+
+	debugf2("DramAddr 0x%lx translates to InputAddr 0x%lx\n",
+		(unsigned long) dram_addr, (unsigned long) input_addr);
+	return input_addr;
+}
+
+/* Translate the SysAddr represented by sys_addr to an InputAddr and return
+ * the result.  It is assumed that sys_addr maps to the node given by mci.
+ */
+static u64 sys_addr_to_input_addr(struct mem_ctl_info *mci, u64 sys_addr)
+{
+	u64 input_addr;
+
+	input_addr = dram_addr_to_input_addr(
+				mci, sys_addr_to_dram_addr(mci, sys_addr));
+	debugf2("%s(): SysAdddr 0x%lx translates to InputAddr 0x%lx\n",
+		__func__, (unsigned long) sys_addr,
+		(unsigned long) input_addr);
+	return input_addr;
+}
+
+/* input_addr is an InputAddr associated with the node given by mci.  Return
+ * the csrow that input_addr maps to, or -1 on failure (no csrow claims
+ * input_addr).
+ */
+static int input_addr_to_csrow(struct mem_ctl_info *mci, u64 input_addr)
+{
+	struct k8_pvt *pvt;
+	int i;
+	u32 dcsb, dcsm;
+	u64 base, mask;
+
+	pvt = mci->pvt_info;
+
+	/* Here we use the DRAM CS Base (section 3.5.4) and DRAM CS Mask
+	 * (section 3.5.5) registers.  For each CS base/mask register pair,
+	 * test the condition shown near the start of section 3.5.4 (p. 84).
+	 */
+
+	for (i = 0; i < K8_NR_CSROWS; i++) {
+		dcsb = pvt->dcsb[i];
+		dcsm = pvt->dcsm[i];
+
+		if ((dcsb & 0x01) == 0) {
+			debugf2("input_addr_to_csrow: CSBE bit is cleared "
+				"for csrow %d (node %d)\n", i,
+				pvt->node_id);
+			continue;  /* CSBE bit is cleared */
+		}
+
+		base = base_from_dcsb(dcsb);
+		mask = ~mask_from_dcsm(dcsm);
+
+		if ((input_addr & mask) == (base & mask)) {
+			debugf2("InputAddr 0x%lx matches csrow %d "
+				"(node %d)\n", (unsigned long) input_addr, i,
+				pvt->node_id);
+			return i;  /* success: csrow i matches */
+		}
+	}
+
+	debugf2("no matching csrow for InputAddr 0x%lx (node %d)\n",
+		(unsigned long) input_addr, pvt->node_id);
+	return -1;  /* failed to find matching csrow */
+}
+
+/* input_addr is an InputAddr associated with the node represented by mci.
+ * Translate input_addr to a DramAddr and return the result.
+ */
+static u64 input_addr_to_dram_addr(struct mem_ctl_info *mci, u64 input_addr)
+{
+	struct k8_pvt *pvt;
+	int node_id, intlv_shift;
+	u64 bits, dram_addr;
+	u32 intlv_sel;
+
+	/* Near the start of section 3.4.4 (p. 70), the k8 documentation shows
+	 * how to translate a DramAddr to an InputAddr.  Here we reverse this
+	 * procedure.  When translating from a DramAddr to an InputAddr, the
+	 * bits used for node interleaving are discarded.  Here we recover
+	 * these bits from the IntlvSel field of the DRAM Limit register
+	 * (section 3.4.4.2) for the node that input_addr is associated with.
+	 */
+
+	pvt = mci->pvt_info;
+	node_id = pvt->node_id;
+	BUG_ON((node_id < 0) || (node_id > 7));
+	intlv_shift = num_node_interleave_bits((pvt->dbr[0] >> 8) & 0x07);
+
+	if (intlv_shift == 0) {
+		debugf1("node interleaving disabled: InputAddr 0x%lx "
+			"translates to DramAddr of same value\n",
+			(unsigned long) input_addr);
+		return input_addr;
+	}
+
+	bits = ((input_addr & 0xffffff000ull) << intlv_shift) +
+	       (input_addr & 0xfff);
+	intlv_sel = pvt->dlr[node_id] & (((1 << intlv_shift) - 1) << 8);
+	dram_addr = bits + (intlv_sel << 4);
+	debugf1("InputAddr 0x%lx translates to DramAddr 0x%lx "
+		"(%d node interleave bits)\n", (unsigned long) input_addr,
+		(unsigned long) dram_addr, intlv_shift);
+	return dram_addr;
+}
+
+/* dram_addr is a DramAddr that maps to the node represented by mci.  Convert
+ * dram_addr to a SysAddr and return the result.
+ */
+static u64 dram_addr_to_sys_addr(struct mem_ctl_info *mci, u64 dram_addr)
+{
+	struct k8_pvt *pvt;
+	u64 hole_base, hole_offset, hole_size, base, limit, sys_addr;
+
+	pvt = mci->pvt_info;
+
+	if (!get_dram_hole_info(mci, &hole_base, &hole_offset, &hole_size)) {
+		if ((dram_addr >= hole_base) &&
+		    (dram_addr < (hole_base + hole_size))) {
+			/* use DHAR to translate DramAddr to SysAddr */
+			sys_addr = dram_addr + hole_offset;
+			debugf1("using DHAR to translate DramAddr 0x%lx to "
+				"SysAddr 0x%lx\n", (unsigned long) dram_addr,
+				(unsigned long) sys_addr);
+			return sys_addr;
+		}
+	}
+
+	get_base_and_limit(pvt, pvt->node_id, &base, &limit);
+	sys_addr = dram_addr + base;
+
+	/* The sys_addr we have computed up to this point is a 40-bit value
+	 * because the k8 deals with 40-bit values.  However, the value we are
+	 * supposed to return is a full 64-bit physical address.  The AMD
+	 * x86-64 architecture specifies that the most significant implemented
+	 * address bit through bit 63 of a physical address must be either all
+	 * 0s or all 1s.  Therefore we sign-extend the 40-bit sys_addr to a
+	 * 64-bit value below.  See section 3.4.2 of AMD publication 24592:
+	 * AMD x86-64 Architecture Programmer's Manual Volume 1 Application
+	 * Programming.
+	 */
+	sys_addr |= ~((sys_addr & (1ull << 39)) - 1);
+
+	debugf1("Using DRAM Base register for node %d to translate "
+		"DramAddr 0x%lx to SysAddr 0x%lx\n", pvt->node_id,
+		(unsigned long) dram_addr, (unsigned long) sys_addr);
+	return sys_addr;
+}
+
+/* input_addr is an InputAddr associated with the node given by mci.
+ * Translate input_addr to a SysAddr and return the result.
+ */
+static inline u64 input_addr_to_sys_addr(struct mem_ctl_info *mci,
+		u64 input_addr)
+{
+	return dram_addr_to_sys_addr(
+			mci, input_addr_to_dram_addr(mci, input_addr));
+}
+
+/* Find the minimum and maximum InputAddr values that map to the given csrow.
+ * Pass back these values in *input_addr_min and *input_addr_max.
+ */
+static void find_csrow_limits(struct mem_ctl_info *mci, int csrow,
+		u64 *input_addr_min, u64 *input_addr_max)
+{
+	struct k8_pvt *pvt;
+	u64 base, mask;
+
+	pvt = mci->pvt_info;
+	BUG_ON((csrow < 0) || (csrow >= K8_NR_CSROWS));
+	base = base_from_dcsb(pvt->dcsb[csrow]);
+	mask = mask_from_dcsm(pvt->dcsm[csrow]);
+	*input_addr_min = base & ~mask;
+
+	/* To find the max InputAddr for the csrow, start with the base
+	 * address and set all bits that are "don't care" bits in the test at
+	 * the start of section 3.5.4 (p. 84).  The "don't care" bits are all
+	 * set bits in the mask and all bits in the gaps between bit ranges
+	 * [35-25] and [19-13].  The value 0x1f01fff represents bits [24-20]
+	 * and [12-0], which are all bits in the above-mentioned gaps.
+	 */
+	*input_addr_max = base | mask | 0x1f01fff;
+}
+
+/* Extract error address from MCA NB Address Low (section 3.6.4.5) and
+ * MCA NB Address High (section 3.6.4.6) register values and return the
+ * result.
+ */
+static inline u64 error_address_from_k8_error_info(
+		struct k8_error_info *info)
+{
+	return (((u64) (info->error_info.nbeah & 0xff)) << 32) +
+	       (info->error_info.nbeal & ~0x03);
+}
+
+static inline void error_address_to_page_and_offset(u64 error_address,
+		u32 *page, u32 *offset)
+{
+	*page = (u32) (error_address >> PAGE_SHIFT);
+	*offset = ((u32) error_address) & ~PAGE_MASK;
+}
+
+/* Return 1 if registers contain valid error information.  Else return 0. */
+static inline int k8_error_info_valid(struct k8_error_info_regs *regs)
+{
+	return ((regs->nbsh & K8_NBSH_VALID_BIT) != 0);
+}
+
+/* return 0 if regs contains valid error info; else return 1 */
+static int k8_get_error_info_regs(struct mem_ctl_info *mci,
+		struct k8_error_info_regs *regs)
+{
+	struct k8_pvt *pvt;
+
+	pvt = mci->pvt_info;
+	pci_read_config_dword(pvt->misc_ctl, K8_NBSH, &regs->nbsh);
+
+	if (!k8_error_info_valid(regs))
+		return 1;
+
+	pci_read_config_dword(pvt->misc_ctl, K8_NBSL, &regs->nbsl);
+	pci_read_config_dword(pvt->misc_ctl, K8_NBEAH, &regs->nbeah);
+	pci_read_config_dword(pvt->misc_ctl, K8_NBEAL, &regs->nbeal);
+	return 0;
+}
+
+static void k8_get_error_info(struct mem_ctl_info *mci,
+		struct k8_error_info *info)
+{
+	struct k8_pvt *pvt;
+	struct k8_error_info_regs regs;
+
+	pvt = mci->pvt_info;
+	info->race_condition_detected = 0;
+
+	if (k8_get_error_info_regs(mci, &info->error_info))
+		return;
+
+	/*
+	 * Here's the problem with the K8's EDAC reporting:
+	 * There are four registers which report pieces of error
+	 * information.  These four registers are shared between
+	 * CEs and UEs.  Furthermore, contrary to what is stated in
+	 * the OBKG, the overflow bit is never used!  Every error
+	 * always updates the reporting registers.
+	 *
+	 * Can you see the race condition?  All four error reporting
+	 * registers must be read before a new error updates them!
+	 * There is no way to read all four registers atomically.  The
+	 * best than can be done is to detect that a race has occured
+	 * and then report the error without any kind of precision.
+	 *
+	 * What is still positive is that errors are
+	 * still reported and thus problems can still be detected -
+	 * just not localized because the syndrome and address are
+	 * spread out across registers.
+	 *
+	 * Grrrrr!!!!!  Here's hoping that AMD fixes this in some
+	 * future K8 rev. UEs and CEs should have separate
+	 * register sets with proper overflow bits that are used!
+	 * At very least the problem can be fixed by honoring the
+	 * ErrValid bit in nbsh and not updating registers - just
+	 * set the overflow bit - unless the current error is CE
+	 * and the new error is UE which would be the only situation
+	 * for overwriting the current values.
+	 */
+
+	regs = info->error_info;
+
+	/* Use info from the second read - most current */
+	if (unlikely(k8_get_error_info_regs(mci, &info->error_info)))
+		return;
+
+	/* clear the error */
+	pci_write_bits32(pvt->misc_ctl, K8_NBSH, 0, K8_NBSH_VALID_BIT);
+
+	pci_read_config_dword(pvt->misc_ctl, K8_NBCFG, &info->nbcfg);
+	info->race_condition_detected =
+	    ((regs.nbsh != info->error_info.nbsh) ||
+	     (regs.nbsl != info->error_info.nbsl) ||
+	     (regs.nbeah != info->error_info.nbeah) ||
+	     (regs.nbeal != info->error_info.nbeal));
+}
+
+static inline void decode_gart_tlb_error(struct mem_ctl_info *mci,
+					 struct k8_error_info *info)
+{
+	u32 err_code;
+	u32 ec_tt;		/* error code transaction type (2b) */
+	u32 ec_ll;		/* error code cache level (2b) */
+
+	err_code = info->error_info.nbsl & 0xffffUL;
+	ec_tt = (err_code >> 2) & 0x03UL;
+	ec_ll = (err_code >> 0) & 0x03UL;
+	k8_mc_printk(mci, KERN_ERR,
+		     "GART TLB errorr: transaction type(%s), "
+		     "cache level(%s)\n", tt_msgs[ec_tt], ll_msgs[ec_ll]);
+}
+
+static inline void decode_cache_error(struct mem_ctl_info *mci,
+				      struct k8_error_info *info)
+{
+	u32 err_code;
+	u32 ec_rrrr;		/* error code memory transaction (4b) */
+	u32 ec_tt;		/* error code transaction type (2b) */
+	u32 ec_ll;		/* error code cache level (2b) */
+
+	err_code = info->error_info.nbsl & 0xffffUL;
+	ec_rrrr = (err_code >> 4) & 0x0fUL;
+	ec_tt = (err_code >> 2) & 0x03UL;
+	ec_ll = (err_code >> 0) & 0x03UL;
+	k8_mc_printk(mci, KERN_ERR,
+		     "cache heirarchy error: memory transaction type(%s), "
+		     "transaction type(%s), cache level(%s)\n",
+		     memtt_msgs[ec_rrrr], tt_msgs[ec_tt], ll_msgs[ec_ll]);
+}
+
+/* sys_addr is an error address (a SysAddr) extracted from the MCA NB Address
+ * Low (section 3.6.4.5) and MCA NB Address High (section 3.6.4.6) registers
+ * of a node that detected an ECC memory error.  mci represents the node that
+ * the error address maps to (possibly different from the node that detected
+ * the error).  Return the number of the csrow that sys_addr maps to, or -1 on
+ * error.
+ */
+static int sys_addr_to_csrow(struct mem_ctl_info *mci, u64 sys_addr)
+{
+	int csrow;
+
+	csrow = input_addr_to_csrow(mci,
+				    sys_addr_to_input_addr(mci, sys_addr));
+
+	if (csrow == -1)
+		k8_mc_printk(mci, KERN_ERR,
+			     "Failed to translate InputAddr to csrow for "
+			     "address 0x%lx\n", (unsigned long) sys_addr);
+
+	return csrow;
+}
+
+static void k8_handle_ce(struct mem_ctl_info *mci, struct k8_error_info *info)
+{
+	struct k8_pvt *pvt;
+	unsigned syndrome;
+	u64 error_address;
+	u32 page, offset;
+	int channel, csrow;
+	struct mem_ctl_info *log_mci, *src_mci;
+
+	log_mci = mci;
+	pvt = mci->pvt_info;
+
+	if ((info->error_info.nbsh & BIT(26)) == 0)
+		goto no_info;  /* error address not valid */
+
+	error_address = error_address_from_k8_error_info(info);
+	syndrome = ((info->error_info.nbsh >> 15) & 0xff);
+
+	if (info->nbcfg & BIT(23)) {
+		/* chipkill ecc mode */
+		syndrome += (info->error_info.nbsl >> 16) & 0xff00;
+		channel = chan_from_chipkill_syndrome(syndrome);
+
+		if (channel < 0) {
+			/* If the syndrome couldn't be found then the race
+			 * condition for error reporting registers likely
+			 * occurred.  There's alot more in doubt than just the
+			 * channel.  Might as well just log the error without
+			 * any info.
+			 */
+			k8_mc_printk(mci, KERN_WARNING,
+				     "unknown syndrome 0x%x - possible error "
+				     "reporting race\n", syndrome);
+			goto no_info;
+		}
+	} else
+		/* non-chipkill ecc mode
+		 *
+		 * The k8 documentation is unclear about how to determine the
+		 * channel number when using non-chipkill memory.  This method
+		 * was obtained from email communication with someone at AMD.
+		 */
+		channel = ((error_address & BIT(3)) != 0);
+
+	/* Find out which node the error address belongs to.  This may be
+	 * different from the node that detected the error.
+	 */
+	if ((src_mci = find_mc_by_sys_addr(mci, error_address)) == NULL) {
+		k8_mc_printk(mci, KERN_ERR,
+			     "failed to map error address 0x%lx to a node\n",
+			     (unsigned long) error_address);
+		goto no_info;
+	}
+
+	log_mci = src_mci;
+
+	if ((csrow = sys_addr_to_csrow(log_mci, error_address)) < 0)
+		goto no_info;
+
+	error_address_to_page_and_offset(error_address, &page, &offset);
+	edac_mc_handle_ce(log_mci, page, offset, syndrome, csrow, channel,
+			  EDAC_MOD_STR);
+	return;
+
+no_info:
+	edac_mc_handle_ce_no_info(log_mci,EDAC_MOD_STR);
+}
+
+static void k8_handle_ue(struct mem_ctl_info *mci, struct k8_error_info *info)
+{
+	int csrow;
+	u64 error_address;
+	u32 page, offset;
+	struct mem_ctl_info *log_mci, *src_mci;
+
+	log_mci = mci;
+
+	if ((info->error_info.nbsh & BIT(26)) == 0)
+		goto no_info;  /* error address not valid */
+
+	error_address = error_address_from_k8_error_info(info);
+
+	/* Find out which node the error address belongs to.  This may be
+	 * different from the node that detected the error.
+	 */
+	if ((src_mci = find_mc_by_sys_addr(mci, error_address)) == NULL) {
+		k8_mc_printk(mci, KERN_ERR,
+			     "failed to map error address 0x%lx to a node\n",
+			     (unsigned long) error_address);
+		goto no_info;
+	}
+
+	log_mci = src_mci;
+
+	if ((csrow = sys_addr_to_csrow(log_mci, error_address)) < 0)
+		goto no_info;
+
+	error_address_to_page_and_offset(error_address, &page, &offset);
+	edac_mc_handle_ue(log_mci, page, offset, csrow, EDAC_MOD_STR);
+	return;
+
+no_info:
+	edac_mc_handle_ue_no_info(log_mci, EDAC_MOD_STR);
+}
+
+static void decode_bus_error(struct mem_ctl_info *mci,
+		struct k8_error_info *info)
+{
+	u32 err_code, ext_ec;
+	u32 ec_pp;    /* error code participating processor (2p) */
+	u32 ec_to;    /* error code timed out (1b) */
+	u32 ec_rrrr;  /* error code memory transaction (4b) */
+	u32 ec_ii;    /* error code memory or I/O (2b) */
+	u32 ec_ll;    /* error code cache level (2b) */
+
+	debugf0("MC%d: %s()\n", mci->mc_idx, __func__);
+	err_code = info->error_info.nbsl & 0xffffUL;
+	ec_pp = (err_code >> 9) & 0x03UL;
+	ec_to = (err_code >> 8) & 0x01UL;
+	ec_rrrr = (err_code >> 4) & 0x0fUL;
+	ec_ii = (err_code >> 2) & 0x03UL;
+	ec_ll = (err_code >> 0) & 0x03UL;
+	ext_ec = (info->error_info.nbsl >> 16) & 0xfUL;
+
+	/* FIXME - these should report through EDAC channels */
+	k8_mc_printk(mci, KERN_ERR, "general bus error: participating "
+		     "processor(%s), time-out(%s) memory transaction "
+		     "type(%s), mem or i/o(%s), cache level(%s)\n",
+		     pp_msgs[ec_pp], to_msgs[ec_to], memtt_msgs[ec_rrrr],
+		     ii_msgs[ec_ii], ll_msgs[ec_ll]);
+
+	if (ec_pp & 0x02)
+		return;  /* We aren't the node involved */
+
+	/* FIXME - other errors should have other error handling mechanisms */
+	if (ext_ec && (ext_ec != 0x8)) {
+		k8_mc_printk(mci, KERN_ERR,
+			     "no special error handling for this error\n");
+		return;
+	}
+
+	if (info->error_info.nbsh & BIT(14))
+		k8_handle_ce(mci, info);
+	else if (info->error_info.nbsh & BIT(13))
+		k8_handle_ue(mci, info);
+
+	/* If main error is CE then overflow must be CE.  If main error is UE
+	 * then overflow is unknown.  We'll call the overflow a CE - if
+	 * panic_on_ue is set then we're already panic'ed and won't arrive
+	 * here.  If panic_on_ue is not set then apparently someone doesn't
+	 * think that UE's are catastrophic.
+	 */
+	if (info->error_info.nbsh & BIT(30))
+		edac_mc_handle_ce_no_info(mci,
+		    EDAC_MOD_STR " Error Overflow set");
+}
+
+/* return 1 if error found or 0 if error not found */
+static int k8_process_error_info(struct mem_ctl_info *mci,
+		struct k8_error_info *info, int handle_errors)
+{
+	struct k8_pvt *pvt;
+	struct k8_error_info_regs *regs;
+	u32 err_code, ext_ec;
+	int gart_tlb_error;
+
+	pvt = mci->pvt_info;
+
+	/* check for an error */
+	if (!k8_error_info_valid(&info->error_info))
+		return 0;
+
+	if (!handle_errors)
+		return 1;
+
+	if (info->race_condition_detected)
+		k8_mc_printk(mci, KERN_WARNING, "race condition detected!\n");
+
+	gart_tlb_error = 0;
+	regs = &info->error_info;
+	err_code = info->error_info.nbsl & 0xffffUL;
+	ext_ec = (info->error_info.nbsl >> 16) & 0x0fUL;
+	debugf1("NorthBridge ERROR: mci(0x%p) node(%d) ErrAddr(0x%.8x-%.8x) "
+		"nbsh(0x%.8x) nbsl(0x%.8x)\n", mci, pvt->node_id, regs->nbeah,
+		regs->nbeal, regs->nbsh, regs->nbsl);
+
+	if ((err_code & 0xfff0UL) == 0x0010UL) {
+		debugf1("GART TLB error\n");
+		gart_tlb_error = 1;
+		decode_gart_tlb_error(mci, info);
+	} else if ((err_code & 0xff00UL) == 0x0100UL) {
+		debugf1("Cache error\n");
+		decode_cache_error(mci, info);
+	} else if ((err_code & 0xf800UL) == 0x0800UL) {
+		debugf1("Bus error\n");
+		decode_bus_error(mci, info);
+	} else
+		/* shouldn't reach here! */
+		k8_mc_printk(mci, KERN_WARNING,
+			     "%s(): unknown MCE error 0x%x\n", __func__,
+			     err_code);
+
+	k8_mc_printk(mci, KERN_ERR, "extended error code: %s\n",
+		     ext_msgs[ext_ec]);
+
+	if (((ext_ec >= 1 && ext_ec <= 4) || (ext_ec == 6)) &&
+	    ((info->error_info.nbsh >> 4) & 0x07UL))
+		k8_mc_printk(mci, KERN_ERR,
+		    "Error on hypertransport link: %s\n",
+		    htlink_msgs[(info->error_info.nbsh >> 4) & 0x07UL]);
+
+	/* GART errors are benign as per AMD, do not panic on them */
+	if (!gart_tlb_error && (regs->nbsh & BIT(29))) {
+		k8_mc_printk(mci, KERN_CRIT, "uncorrected error\n");
+		edac_mc_handle_ue_no_info(mci, "UE bit is set\n");
+	}
+
+	if (regs->nbsh & BIT(25))
+		panic("MC%d: processor context corrupt", mci->mc_idx);
+
+	return 1;
+}
+
+static void k8_check(struct mem_ctl_info *mci)
+{
+	struct k8_error_info info;
+
+	debugf3("%s()\n", __func__);
+	k8_get_error_info(mci, &info);
+	k8_process_error_info(mci, &info, 1);
+}
+
+static int k8_get_devs(struct mem_ctl_info *mci, int dev_idx)
+{
+	const struct k8_dev_info *k8_dev = &k8_devs[dev_idx];
+	struct k8_pvt *pvt;
+	struct pci_dev *pdev;
+
+	pdev = to_pci_dev(mci->dev);
+	pvt = mci->pvt_info;
+
+	/* The address mapping device provides a table that indicates which
+	 * physical address ranges are owned by which node.  Each node's
+	 * memory controller has memory controller addresses that begin at
+	 * 0x0.
+	 */
+	pvt->addr_map = pci_get_related_function(PCI_VENDOR_ID_AMD,
+						 k8_dev->addr_map, pdev);
+
+	if (pvt->addr_map == NULL) {
+		k8_printk(KERN_ERR, "error address map device not found: "
+			  "vendor %x device 0x%x (broken BIOS?)\n",
+			  PCI_VENDOR_ID_AMD, k8_dev->addr_map);
+		return 1;
+	}
+
+	debugf1("Addr Map device PCI Bus ID:\t%s\n",
+		pci_name(pvt->addr_map));
+
+	pvt->misc_ctl = pci_get_related_function(PCI_VENDOR_ID_AMD,
+						 k8_dev->misc_ctl, pdev);
+
+	if (pvt->misc_ctl == NULL) {
+		pci_dev_put(pvt->addr_map);
+		pvt->addr_map = NULL;
+		k8_printk(KERN_ERR, "error miscellaneous device not found: "
+			  "vendor %x device 0x%x (broken BIOS?)\n",
+			  PCI_VENDOR_ID_AMD, k8_dev->misc_ctl);
+		return 1;
+	}
+
+	debugf1("Misc device PCI Bus ID:\t\t%s\n",
+		pci_name(pvt->misc_ctl));
+
+	return 0;
+}
+
+static void k8_get_mc_regs(struct mem_ctl_info *mci)
+{
+	struct k8_pvt *pvt;
+	struct pci_dev *pdev;
+	int i;
+
+	pdev = to_pci_dev(mci->dev);
+	pvt = mci->pvt_info;
+	debugf1("k8 regs:\n");
+
+	for (i = 0; i < MAX_K8_NODES; i++) {
+		pci_read_config_dword(pvt->addr_map, K8_DBR + (i * 8),
+				      &pvt->dbr[i]);
+		pci_read_config_dword(pvt->addr_map, K8_DLR + (i * 8),
+				      &pvt->dlr[i]);
+		debugf1("    dbr[%d]: 0x%x\n", i, pvt->dbr[i]);
+		debugf1("    dlr[%d]: 0x%x\n", i, pvt->dlr[i]);
+	}
+
+	pci_read_config_dword(pvt->misc_ctl, K8_NBCAP, &pvt->nbcap);
+	debugf1("    nbcap: %u\n", pvt->nbcap);
+
+	for (i = 0; i < K8_NR_CSROWS; i++) {
+		pci_read_config_dword(pdev, K8_DCSB + (i * 4), &pvt->dcsb[i]);
+		pci_read_config_dword(pdev, K8_DCSM + (i * 4), &pvt->dcsm[i]);
+		debugf1("    dcsb[%d]: 0x%x\n", i, pvt->dcsb[i]);
+		debugf1("    dcsm[%d]: 0x%x\n", i, pvt->dcsm[i]);
+	}
+
+	pci_read_config_dword(pvt->addr_map, K8_DHAR, &pvt->dhar);
+	pci_read_config_dword(pdev, K8_DBAM, &pvt->dbam);
+	debugf1("    dhar: 0x%x\n", pvt->dhar);
+	debugf1("    dbam: 0x%x\n", pvt->dbam);
+}
+
+/* Return 1 if dual channel mode is active.  Else return 0. */
+static inline int dual_channel_active(u32 dcl)
+{
+	return (dcl >> 16) & 0x1;
+}
+
+static u32 csrow_nr_pages(int csrow_nr, struct k8_pvt *pvt)
+{
+	u32 cs;
+
+	/* The math on this doesn't look right on the surface because x/2*4
+	 * can be simplified to x*2 but this expression makes use of the fact
+	 * that it is integral math where 1/2=0
+	 */
+	cs = (pvt->dbam >> ((csrow_nr / 2) * 4)) & 0xF;  /* PG88 */
+
+	/* This line is tricky. It collapses the table used by revision D and
+	 * later to one that matches revision CG and earlier
+	 */
+	cs -= (node_rev(pvt->node_id) >= OPTERON_CPU_REV_D) ?
+	      (cs > 8 ? 4 : (cs > 5 ? 3 : (cs > 2 ? 1 : 0))) : 0;
+
+	/* 25 is 32MiB minimum DIMM size */
+	return 1 << (cs + 25 - PAGE_SHIFT + dual_channel_active(pvt->dcl));
+}
+
+static int k8_init_csrows(struct mem_ctl_info *mci)
+{
+	struct csrow_info *csrow;
+	struct k8_pvt *pvt;
+	int i, empty;
+	u64 input_addr_min, input_addr_max, sys_addr;
+	u32 nbcfg;
+
+	pvt = mci->pvt_info;
+	pci_read_config_dword(pvt->misc_ctl, K8_NBCFG, &nbcfg);
+	empty = 1;
+
+	for (i = 0; i < K8_NR_CSROWS; i++) {
+		csrow = &mci->csrows[i];
+
+		if ((pvt->dcsb[i] & 0x01) == 0) {
+			debugf1("csrow %d empty for node %d\n", i,
+				pvt->node_id);
+			continue;  /* empty */
+		}
+
+		debugf1("revision for this node (%d) is %d\n",
+			pvt->node_id, node_rev(pvt->node_id));
+		empty = 0;
+		csrow->nr_pages = csrow_nr_pages(i, pvt);
+		find_csrow_limits(mci, i, &input_addr_min, &input_addr_max);
+		sys_addr = input_addr_to_sys_addr(mci, input_addr_min);
+		csrow->first_page = (u32) (sys_addr >> PAGE_SHIFT);
+		sys_addr = input_addr_to_sys_addr(mci, input_addr_max);
+		csrow->last_page = (u32) (sys_addr >> PAGE_SHIFT);
+		csrow->page_mask = ~mask_from_dcsm(pvt->dcsm[i]);
+		csrow->grain = 8;  /* 8 bytes of resolution */
+		csrow->mtype = ((pvt->dcl >> 18) & 0x1) ? MEM_DDR : MEM_RDDR;
+		csrow->dtype = ((pvt->dcl >> (20 + (i / 2))) & 0x01) ?
+			       DEV_X4 : DEV_UNKNOWN;
+		debugf1("for node %d csrow %d:\n    nr_pages: %u "
+			"input_addr_min: 0x%lx input_addr_max: 0x%lx "
+			"sys_addr: 0x%lx first_page: 0x%lx last_page: 0x%lx "
+			"page_mask: 0x%lx\n", pvt->node_id, i,
+			(unsigned) csrow->nr_pages,
+			(unsigned long) input_addr_min,
+			(unsigned long) input_addr_max,
+			(unsigned long) sys_addr,
+			csrow->first_page, csrow->last_page,
+			csrow->page_mask);
+
+		if (nbcfg & BIT(22))
+			csrow->edac_mode = (nbcfg & BIT(23)) ?
+					   EDAC_S4ECD4ED : EDAC_SECDED;
+		else
+			csrow->edac_mode = EDAC_NONE;
+	}
+
+	return empty;
+}
+
+static void k8_enable_error_reporting(struct mem_ctl_info *mci)
+{
+	struct k8_pvt *pvt;
+	u32 mc4ctl_l=0, mc4ctl_h=0, mcgctl_l=0, mcgctl_h=0;
+
+	pvt = mci->pvt_info;
+	pci_write_bits32(pvt->misc_ctl, K8_NBCTL, 0x3UL, 0x3UL);
+	do_rdmsr(pvt->node_id, K8_MSR_MC4CTL, &mc4ctl_l, &mc4ctl_h);
+	mc4ctl_l |= BIT(0) | BIT(1);
+	do_wrmsr(pvt->node_id, K8_MSR_MC4CTL, mc4ctl_l, mc4ctl_h);
+	do_rdmsr(pvt->node_id, K8_MSR_MC4CTL, &mc4ctl_l, &mc4ctl_h);
+	do_rdmsr(pvt->node_id, K8_MSR_MCGCTL, &mcgctl_l, &mcgctl_h);
+	mcgctl_l |= BIT(4);
+	do_wrmsr(pvt->node_id, K8_MSR_MCGCTL, mcgctl_l, mcgctl_h);
+	do_rdmsr(pvt->node_id, K8_MSR_MCGCTL, &mcgctl_l, &mcgctl_h);
+}
+
+static int k8_probe1(struct pci_dev *pdev, int dev_idx)
+{
+	struct mem_ctl_info *mci;
+	struct k8_pvt *pvt;
+	u32 dcl, dual_channel;
+
+	debugf0("%s()\n", __func__);
+	build_node_revision_table();
+	debugf1("pdev bus %u devfn %u\n", pdev->bus->number, pdev->devfn);
+	pci_read_config_dword(pdev, K8_DCL, &dcl);
+	dual_channel = dual_channel_active(dcl);
+	debugf1("dual_channel is %u (dcl is 0x%x)\n", dual_channel, dcl);
+	mci = edac_mc_alloc(sizeof(*pvt), K8_NR_CSROWS, dual_channel + 1);
+
+	if (mci == NULL)
+		return -ENOMEM;
+
+	debugf0("%s(): mci = %p\n", __func__, mci);
+	pvt = mci->pvt_info;
+	pvt->dcl = dcl;
+	mci->dev = &pdev->dev;
+	pvt->node_id = MCI_TO_NODE_ID(mci);
+
+	if (k8_get_devs(mci, dev_idx))
+		goto fail0;
+
+	k8_get_mc_regs(mci);
+	mci->mtype_cap = MEM_FLAG_DDR | MEM_FLAG_RDDR;
+	mci->edac_ctl_cap = EDAC_FLAG_NONE;
+	debugf1("Initializing mci->edac_cap to EDAC_FLAG_NONE\n");
+	mci->edac_cap = EDAC_FLAG_NONE;
+
+	if ((pvt->nbcap >> 3) & 0x1)
+		mci->edac_ctl_cap |= EDAC_FLAG_SECDED;
+
+	if ((pvt->nbcap >> 4) & 0x1)
+		mci->edac_ctl_cap |= EDAC_FLAG_S4ECD4ED;
+
+	if ((pvt->dcl >> 17) & 0x1) {
+		debugf1("setting EDAC_FLAG_SECDED in mci->edac_cap\n");
+		mci->edac_cap |= EDAC_FLAG_SECDED;
+
+		if (dual_channel) {
+			debugf1("setting EDAC_FLAG_S4ECD4ED in "
+				"mci->edac_cap\n");
+			mci->edac_cap |= EDAC_FLAG_S4ECD4ED;
+		}
+	}
+
+	mci->mod_name = EDAC_MOD_STR;
+	mci->mod_ver = EDAC_K8_VERSION;
+	mci->ctl_name = k8_devs[dev_idx].ctl_name;
+	mci->edac_check = k8_check;
+	mci->ctl_page_to_phys = NULL;
+
+	if (k8_init_csrows(mci)) {
+		debugf1("Setting mci->edac_cap to EDAC_FLAG_NONE "
+			"because k8_init_csrows() returned nonzero "
+			"value\n");
+		mci->edac_cap = EDAC_FLAG_NONE;  /* no csrows found */
+	} else
+		k8_enable_error_reporting(mci);
+
+	if (edac_mc_add_mc(mci, pvt->node_id)) {
+		debugf1("%s(): failed edac_mc_add_mc()\n", __func__);
+		/* FIXME: perhaps some code should go here that disables error
+		 * reporting if we just enabled it
+		 */
+		goto fail1;
+	}
+
+	debugf1("%s(): success\n", __func__);
+	return 0;
+
+fail1:
+	pci_dev_put(pvt->addr_map);
+	pci_dev_put(pvt->misc_ctl);
+
+fail0:
+	edac_mc_free(mci);
+	return -ENODEV;
+}
+
+/* returns count (>= 0), or negative on error */
+static int __devinit k8_init_one(struct pci_dev *pdev,
+				 const struct pci_device_id *ent)
+{
+	debugf0("%s()\n", __func__);
+
+	/* wake up and enable device */
+	return pci_enable_device(pdev) ?
+	    -EIO : k8_probe1(pdev, ent->driver_data);
+}
+
+static void __devexit k8_remove_one(struct pci_dev *pdev)
+{
+	struct mem_ctl_info *mci;
+	struct k8_pvt *pvt;
+
+	debugf0("%s()\n", __func__);
+
+	if ((mci = edac_mc_del_mc(&pdev->dev)) == NULL)
+		return;
+
+	pvt = mci->pvt_info;
+	pci_dev_put(pvt->addr_map);
+	pci_dev_put(pvt->misc_ctl);
+	edac_mc_free(mci);
+}
+
+static const struct pci_device_id k8_pci_tbl[] __devinitdata = {
+	{PCI_VEND_DEV(AMD, OPT_2_MEMCTL), PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+	 OPTERON},
+	{0,}			/* 0 terminated list. */
+};
+
+MODULE_DEVICE_TABLE(pci, k8_pci_tbl);
+
+static struct pci_driver k8_driver = {
+	.name = EDAC_MOD_STR,
+	.probe = k8_init_one,
+	.remove = __devexit_p(k8_remove_one),
+	.id_table = k8_pci_tbl,
+};
+
+int __init k8_init(void)
+{
+	return pci_module_init(&k8_driver);
+}
+
+static void __exit k8_exit(void)
+{
+	pci_unregister_driver(&k8_driver);
+}
+
+module_init(k8_init);
+module_exit(k8_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Linux Networx (http://lnxi.com) Thayne Harbaugh");
+MODULE_DESCRIPTION("MC support for AMD K8 memory controllers - " EDAC_K8_VERSION );
diff --git a/drivers/hwmon/abituguru.c b/drivers/hwmon/abituguru.c
new file mode 100644
index 000000000..35ad1b032
--- /dev/null
+++ b/drivers/hwmon/abituguru.c
@@ -0,0 +1,1455 @@
+/*
+    abituguru.c Copyright (c) 2005-2006 Hans de Goede <j.w.r.degoede@hhs.nl>
+
+    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.
+*/
+/*
+    This driver supports the sensor part of the custom Abit uGuru chip found
+    on Abit uGuru motherboards. Note: because of lack of specs the CPU / RAM /
+    etc voltage & frequency control is not supported!
+*/
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/jiffies.h>
+#include <linux/mutex.h>
+#include <linux/err.h>
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include <linux/hwmon.h>
+#include <linux/hwmon-sysfs.h>
+#include <asm/io.h>
+
+/* Banks */
+#define ABIT_UGURU_ALARM_BANK			0x20 /* 1x 3 bytes */
+#define ABIT_UGURU_SENSOR_BANK1			0x21 /* 16x volt and temp */
+#define ABIT_UGURU_FAN_PWM			0x24 /* 3x 5 bytes */
+#define ABIT_UGURU_SENSOR_BANK2			0x26 /* fans */
+/* max nr of sensors in bank1, a bank1 sensor can be in, temp or nc */
+#define ABIT_UGURU_MAX_BANK1_SENSORS		16
+/* Warning if you increase one of the 2 MAX defines below to 10 or higher you
+   should adjust the belonging _NAMES_LENGTH macro for the 2 digit number! */
+/* max nr of sensors in bank2, currently mb's with max 6 fans are known */
+#define ABIT_UGURU_MAX_BANK2_SENSORS		6
+/* max nr of pwm outputs, currently mb's with max 5 pwm outputs are known */
+#define ABIT_UGURU_MAX_PWMS			5
+/* uGuru sensor bank 1 flags */			     /* Alarm if: */
+#define ABIT_UGURU_TEMP_HIGH_ALARM_ENABLE	0x01 /*  temp over warn */
+#define ABIT_UGURU_VOLT_HIGH_ALARM_ENABLE	0x02 /*  volt over max */
+#define ABIT_UGURU_VOLT_LOW_ALARM_ENABLE	0x04 /*  volt under min */
+#define ABIT_UGURU_TEMP_HIGH_ALARM_FLAG		0x10 /* temp is over warn */
+#define ABIT_UGURU_VOLT_HIGH_ALARM_FLAG		0x20 /* volt is over max */
+#define ABIT_UGURU_VOLT_LOW_ALARM_FLAG		0x40 /* volt is under min */
+/* uGuru sensor bank 2 flags */			     /* Alarm if: */
+#define ABIT_UGURU_FAN_LOW_ALARM_ENABLE		0x01 /*   fan under min */
+/* uGuru sensor bank common flags */
+#define ABIT_UGURU_BEEP_ENABLE			0x08 /* beep if alarm */
+#define ABIT_UGURU_SHUTDOWN_ENABLE		0x80 /* shutdown if alarm */
+/* uGuru fan PWM (speed control) flags */
+#define ABIT_UGURU_FAN_PWM_ENABLE		0x80 /* enable speed control */
+/* Values used for conversion */
+#define ABIT_UGURU_FAN_MAX			15300 /* RPM */
+/* Bank1 sensor types */
+#define ABIT_UGURU_IN_SENSOR			0
+#define ABIT_UGURU_TEMP_SENSOR			1
+#define ABIT_UGURU_NC				2
+/* In many cases we need to wait for the uGuru to reach a certain status, most
+   of the time it will reach this status within 30 - 90 ISA reads, and thus we
+   can best busy wait. This define gives the total amount of reads to try. */
+#define ABIT_UGURU_WAIT_TIMEOUT			125
+/* However sometimes older versions of the uGuru seem to be distracted and they
+   do not respond for a long time. To handle this we sleep before each of the
+   last ABIT_UGURU_WAIT_TIMEOUT_SLEEP tries. */
+#define ABIT_UGURU_WAIT_TIMEOUT_SLEEP		5
+/* Normally all expected status in abituguru_ready, are reported after the
+   first read, but sometimes not and we need to poll. */
+#define ABIT_UGURU_READY_TIMEOUT		5
+/* Maximum 3 retries on timedout reads/writes, delay 200 ms before retrying */
+#define ABIT_UGURU_MAX_RETRIES			3
+#define ABIT_UGURU_RETRY_DELAY			(HZ/5)
+/* Maximum 2 timeouts in abituguru_update_device, iow 3 in a row is an error */
+#define ABIT_UGURU_MAX_TIMEOUTS			2
+/* utility macros */
+#define ABIT_UGURU_NAME				"abituguru"
+#define ABIT_UGURU_DEBUG(level, format, arg...)				\
+	if (level <= verbose)						\
+		printk(KERN_DEBUG ABIT_UGURU_NAME ": "	format , ## arg)
+/* Macros to help calculate the sysfs_names array length */
+/* sum of strlen of: in??_input\0, in??_{min,max}\0, in??_{min,max}_alarm\0,
+   in??_{min,max}_alarm_enable\0, in??_beep\0, in??_shutdown\0 */
+#define ABITUGURU_IN_NAMES_LENGTH	(11 + 2 * 9 + 2 * 15 + 2 * 22 + 10 + 14)
+/* sum of strlen of: temp??_input\0, temp??_max\0, temp??_crit\0,
+   temp??_alarm\0, temp??_alarm_enable\0, temp??_beep\0, temp??_shutdown\0 */
+#define ABITUGURU_TEMP_NAMES_LENGTH	(13 + 11 + 12 + 13 + 20 + 12 + 16)
+/* sum of strlen of: fan?_input\0, fan?_min\0, fan?_alarm\0,
+   fan?_alarm_enable\0, fan?_beep\0, fan?_shutdown\0 */
+#define ABITUGURU_FAN_NAMES_LENGTH	(11 + 9 + 11 + 18 + 10 + 14)
+/* sum of strlen of: pwm?_enable\0, pwm?_auto_channels_temp\0,
+   pwm?_auto_point{1,2}_pwm\0, pwm?_auto_point{1,2}_temp\0 */
+#define ABITUGURU_PWM_NAMES_LENGTH	(12 + 24 + 2 * 21 + 2 * 22)
+/* IN_NAMES_LENGTH > TEMP_NAMES_LENGTH so assume all bank1 sensors are in */
+#define ABITUGURU_SYSFS_NAMES_LENGTH	( \
+	ABIT_UGURU_MAX_BANK1_SENSORS * ABITUGURU_IN_NAMES_LENGTH + \
+	ABIT_UGURU_MAX_BANK2_SENSORS * ABITUGURU_FAN_NAMES_LENGTH + \
+	ABIT_UGURU_MAX_PWMS * ABITUGURU_PWM_NAMES_LENGTH)
+
+/* All the macros below are named identical to the oguru and oguru2 programs
+   reverse engineered by Olle Sandberg, hence the names might not be 100%
+   logical. I could come up with better names, but I prefer keeping the names
+   identical so that this driver can be compared with his work more easily. */
+/* Two i/o-ports are used by uGuru */
+#define ABIT_UGURU_BASE				0x00E0
+/* Used to tell uGuru what to read and to read the actual data */
+#define ABIT_UGURU_CMD				0x00
+/* Mostly used to check if uGuru is busy */
+#define ABIT_UGURU_DATA				0x04
+#define ABIT_UGURU_REGION_LENGTH		5
+/* uGuru status' */
+#define ABIT_UGURU_STATUS_WRITE			0x00 /* Ready to be written */
+#define ABIT_UGURU_STATUS_READ			0x01 /* Ready to be read */
+#define ABIT_UGURU_STATUS_INPUT			0x08 /* More input */
+#define ABIT_UGURU_STATUS_READY			0x09 /* Ready to be written */
+
+/* Constants */
+/* in (Volt) sensors go up to 3494 mV, temp to 255000 millidegrees Celsius */
+static const int abituguru_bank1_max_value[2] = { 3494, 255000 };
+/* Min / Max allowed values for sensor2 (fan) alarm threshold, these values
+   correspond to 300-3000 RPM */
+static const u8 abituguru_bank2_min_threshold = 5;
+static const u8 abituguru_bank2_max_threshold = 50;
+/* Register 0 is a bitfield, 1 and 2 are pwm settings (255 = 100%), 3 and 4
+   are temperature trip points. */
+static const int abituguru_pwm_settings_multiplier[5] = { 0, 1, 1, 1000, 1000 };
+/* Min / Max allowed values for pwm_settings. Note: pwm1 (CPU fan) is a
+   special case the minium allowed pwm% setting for this is 30% (77) on
+   some MB's this special case is handled in the code! */
+static const u8 abituguru_pwm_min[5] = { 0, 170, 170, 25, 25 };
+static const u8 abituguru_pwm_max[5] = { 0, 255, 255, 75, 75 };
+
+
+/* Insmod parameters */
+static int force;
+module_param(force, bool, 0);
+MODULE_PARM_DESC(force, "Set to one to force detection.");
+static int bank1_types[ABIT_UGURU_MAX_BANK1_SENSORS] = { -1, -1, -1, -1, -1,
+	-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 };
+module_param_array(bank1_types, int, NULL, 0);
+MODULE_PARM_DESC(bank1_types, "Bank1 sensortype autodetection override:\n"
+	"   -1 autodetect\n"
+	"    0 volt sensor\n"
+	"    1 temp sensor\n"
+	"    2 not connected");
+static int fan_sensors;
+module_param(fan_sensors, int, 0);
+MODULE_PARM_DESC(fan_sensors, "Number of fan sensors on the uGuru "
+	"(0 = autodetect)");
+static int pwms;
+module_param(pwms, int, 0);
+MODULE_PARM_DESC(pwms, "Number of PWMs on the uGuru "
+	"(0 = autodetect)");
+
+/* Default verbose is 2, since this driver is still in the testing phase */
+static int verbose = 2;
+module_param(verbose, int, 0644);
+MODULE_PARM_DESC(verbose, "How verbose should the driver be? (0-3):\n"
+	"   0 normal output\n"
+	"   1 + verbose error reporting\n"
+	"   2 + sensors type probing info\n"
+	"   3 + retryable error reporting");
+
+
+/* For the Abit uGuru, we need to keep some data in memory.
+   The structure is dynamically allocated, at the same time when a new
+   abituguru device is allocated. */
+struct abituguru_data {
+	struct class_device *class_dev; /* hwmon registered device */
+	struct mutex update_lock;	/* protect access to data and uGuru */
+	unsigned long last_updated;	/* In jiffies */
+	unsigned short addr;		/* uguru base address */
+	char uguru_ready;		/* is the uguru in ready state? */
+	unsigned char update_timeouts;	/* number of update timeouts since last
+					   successful update */
+
+	/* The sysfs attr and their names are generated automatically, for bank1
+	   we cannot use a predefined array because we don't know beforehand
+	   of a sensor is a volt or a temp sensor, for bank2 and the pwms its
+	   easier todo things the same way.  For in sensors we have 9 (temp 7)
+	   sysfs entries per sensor, for bank2 and pwms 6. */
+	struct sensor_device_attribute_2 sysfs_attr[
+		ABIT_UGURU_MAX_BANK1_SENSORS * 9 +
+		ABIT_UGURU_MAX_BANK2_SENSORS * 6 + ABIT_UGURU_MAX_PWMS * 6];
+	/* Buffer to store the dynamically generated sysfs names */
+	char sysfs_names[ABITUGURU_SYSFS_NAMES_LENGTH];
+
+	/* Bank 1 data */
+	/* number of and addresses of [0] in, [1] temp sensors */
+	u8 bank1_sensors[2];
+	u8 bank1_address[2][ABIT_UGURU_MAX_BANK1_SENSORS];
+	u8 bank1_value[ABIT_UGURU_MAX_BANK1_SENSORS];
+	/* This array holds 3 entries per sensor for the bank 1 sensor settings
+	   (flags, min, max for voltage / flags, warn, shutdown for temp). */
+	u8 bank1_settings[ABIT_UGURU_MAX_BANK1_SENSORS][3];
+	/* Maximum value for each sensor used for scaling in mV/millidegrees
+	   Celsius. */
+	int bank1_max_value[ABIT_UGURU_MAX_BANK1_SENSORS];
+
+	/* Bank 2 data, ABIT_UGURU_MAX_BANK2_SENSORS entries for bank2 */
+	u8 bank2_sensors; /* actual number of bank2 sensors found */
+	u8 bank2_value[ABIT_UGURU_MAX_BANK2_SENSORS];
+	u8 bank2_settings[ABIT_UGURU_MAX_BANK2_SENSORS][2]; /* flags, min */
+
+	/* Alarms 2 bytes for bank1, 1 byte for bank2 */
+	u8 alarms[3];
+
+	/* Fan PWM (speed control) 5 bytes per PWM */
+	u8 pwms; /* actual number of pwms found */
+	u8 pwm_settings[ABIT_UGURU_MAX_PWMS][5];
+};
+
+/* wait till the uguru is in the specified state */
+static int abituguru_wait(struct abituguru_data *data, u8 state)
+{
+	int timeout = ABIT_UGURU_WAIT_TIMEOUT;
+
+	while (inb_p(data->addr + ABIT_UGURU_DATA) != state) {
+		timeout--;
+		if (timeout == 0)
+			return -EBUSY;
+		/* sleep a bit before our last few tries, see the comment on
+		   this where ABIT_UGURU_WAIT_TIMEOUT_SLEEP is defined. */
+		if (timeout <= ABIT_UGURU_WAIT_TIMEOUT_SLEEP)
+			msleep(0);
+	}
+	return 0;
+}
+
+/* Put the uguru in ready for input state */
+static int abituguru_ready(struct abituguru_data *data)
+{
+	int timeout = ABIT_UGURU_READY_TIMEOUT;
+
+	if (data->uguru_ready)
+		return 0;
+
+	/* Reset? / Prepare for next read/write cycle */
+	outb(0x00, data->addr + ABIT_UGURU_DATA);
+
+	/* Wait till the uguru is ready */
+	if (abituguru_wait(data, ABIT_UGURU_STATUS_READY)) {
+		ABIT_UGURU_DEBUG(1,
+			"timeout exceeded waiting for ready state\n");
+		return -EIO;
+	}
+
+	/* Cmd port MUST be read now and should contain 0xAC */
+	while (inb_p(data->addr + ABIT_UGURU_CMD) != 0xAC) {
+		timeout--;
+		if (timeout == 0) {
+			ABIT_UGURU_DEBUG(1,
+			   "CMD reg does not hold 0xAC after ready command\n");
+			return -EIO;
+		}
+		msleep(0);
+	}
+
+	/* After this the ABIT_UGURU_DATA port should contain
+	   ABIT_UGURU_STATUS_INPUT */
+	timeout = ABIT_UGURU_READY_TIMEOUT;
+	while (inb_p(data->addr + ABIT_UGURU_DATA) != ABIT_UGURU_STATUS_INPUT) {
+		timeout--;
+		if (timeout == 0) {
+			ABIT_UGURU_DEBUG(1,
+				"state != more input after ready command\n");
+			return -EIO;
+		}
+		msleep(0);
+	}
+
+	data->uguru_ready = 1;
+	return 0;
+}
+
+/* Send the bank and then sensor address to the uGuru for the next read/write
+   cycle. This function gets called as the first part of a read/write by
+   abituguru_read and abituguru_write. This function should never be
+   called by any other function. */
+static int abituguru_send_address(struct abituguru_data *data,
+	u8 bank_addr, u8 sensor_addr, int retries)
+{
+	/* assume the caller does error handling itself if it has not requested
+	   any retries, and thus be quiet. */
+	int report_errors = retries;
+
+	for (;;) {
+		/* Make sure the uguru is ready and then send the bank address,
+		   after this the uguru is no longer "ready". */
+		if (abituguru_ready(data) != 0)
+			return -EIO;
+		outb(bank_addr, data->addr + ABIT_UGURU_DATA);
+		data->uguru_ready = 0;
+
+		/* Wait till the uguru is ABIT_UGURU_STATUS_INPUT state again
+		   and send the sensor addr */
+		if (abituguru_wait(data, ABIT_UGURU_STATUS_INPUT)) {
+			if (retries) {
+				ABIT_UGURU_DEBUG(3, "timeout exceeded "
+					"waiting for more input state, %d "
+					"tries remaining\n", retries);
+				set_current_state(TASK_UNINTERRUPTIBLE);
+				schedule_timeout(ABIT_UGURU_RETRY_DELAY);
+				retries--;
+				continue;
+			}
+			if (report_errors)
+				ABIT_UGURU_DEBUG(1, "timeout exceeded "
+					"waiting for more input state "
+					"(bank: %d)\n", (int)bank_addr);
+			return -EBUSY;
+		}
+		outb(sensor_addr, data->addr + ABIT_UGURU_CMD);
+		return 0;
+	}
+}
+
+/* Read count bytes from sensor sensor_addr in bank bank_addr and store the
+   result in buf, retry the send address part of the read retries times. */
+static int abituguru_read(struct abituguru_data *data,
+	u8 bank_addr, u8 sensor_addr, u8 *buf, int count, int retries)
+{
+	int i;
+
+	/* Send the address */
+	i = abituguru_send_address(data, bank_addr, sensor_addr, retries);
+	if (i)
+		return i;
+
+	/* And read the data */
+	for (i = 0; i < count; i++) {
+		if (abituguru_wait(data, ABIT_UGURU_STATUS_READ)) {
+			ABIT_UGURU_DEBUG(retries ? 1 : 3,
+				"timeout exceeded waiting for "
+				"read state (bank: %d, sensor: %d)\n",
+				(int)bank_addr, (int)sensor_addr);
+			break;
+		}
+		buf[i] = inb(data->addr + ABIT_UGURU_CMD);
+	}
+
+	/* Last put the chip back in ready state */
+	abituguru_ready(data);
+
+	return i;
+}
+
+/* Write count bytes from buf to sensor sensor_addr in bank bank_addr, the send
+   address part of the write is always retried ABIT_UGURU_MAX_RETRIES times. */
+static int abituguru_write(struct abituguru_data *data,
+	u8 bank_addr, u8 sensor_addr, u8 *buf, int count)
+{
+	/* We use the ready timeout as we have to wait for 0xAC just like the
+	   ready function */
+	int i, timeout = ABIT_UGURU_READY_TIMEOUT;
+
+	/* Send the address */
+	i = abituguru_send_address(data, bank_addr, sensor_addr,
+		ABIT_UGURU_MAX_RETRIES);
+	if (i)
+		return i;
+
+	/* And write the data */
+	for (i = 0; i < count; i++) {
+		if (abituguru_wait(data, ABIT_UGURU_STATUS_WRITE)) {
+			ABIT_UGURU_DEBUG(1, "timeout exceeded waiting for "
+				"write state (bank: %d, sensor: %d)\n",
+				(int)bank_addr, (int)sensor_addr);
+			break;
+		}
+		outb(buf[i], data->addr + ABIT_UGURU_CMD);
+	}
+
+	/* Now we need to wait till the chip is ready to be read again,
+	   so that we can read 0xAC as confirmation that our write has
+	   succeeded. */
+	if (abituguru_wait(data, ABIT_UGURU_STATUS_READ)) {
+		ABIT_UGURU_DEBUG(1, "timeout exceeded waiting for read state "
+			"after write (bank: %d, sensor: %d)\n", (int)bank_addr,
+			(int)sensor_addr);
+		return -EIO;
+	}
+
+	/* Cmd port MUST be read now and should contain 0xAC */
+	while (inb_p(data->addr + ABIT_UGURU_CMD) != 0xAC) {
+		timeout--;
+		if (timeout == 0) {
+			ABIT_UGURU_DEBUG(1, "CMD reg does not hold 0xAC after "
+				"write (bank: %d, sensor: %d)\n",
+				(int)bank_addr, (int)sensor_addr);
+			return -EIO;
+		}
+		msleep(0);
+	}
+
+	/* Last put the chip back in ready state */
+	abituguru_ready(data);
+
+	return i;
+}
+
+/* Detect sensor type. Temp and Volt sensors are enabled with
+   different masks and will ignore enable masks not meant for them.
+   This enables us to test what kind of sensor we're dealing with.
+   By setting the alarm thresholds so that we will always get an
+   alarm for sensor type X and then enabling the sensor as sensor type
+   X, if we then get an alarm it is a sensor of type X. */
+static int __devinit
+abituguru_detect_bank1_sensor_type(struct abituguru_data *data,
+				   u8 sensor_addr)
+{
+	u8 val, buf[3];
+	int i, ret = -ENODEV; /* error is the most common used retval :| */
+
+	/* If overriden by the user return the user selected type */
+	if (bank1_types[sensor_addr] >= ABIT_UGURU_IN_SENSOR &&
+			bank1_types[sensor_addr] <= ABIT_UGURU_NC) {
+		ABIT_UGURU_DEBUG(2, "assuming sensor type %d for bank1 sensor "
+			"%d because of \"bank1_types\" module param\n",
+			bank1_types[sensor_addr], (int)sensor_addr);
+		return bank1_types[sensor_addr];
+	}
+
+	/* First read the sensor and the current settings */
+	if (abituguru_read(data, ABIT_UGURU_SENSOR_BANK1, sensor_addr, &val,
+			1, ABIT_UGURU_MAX_RETRIES) != 1)
+		return -ENODEV;
+
+	/* Test val is sane / usable for sensor type detection. */
+	if ((val < 10u) || (val > 240u)) {
+		printk(KERN_WARNING ABIT_UGURU_NAME
+			": bank1-sensor: %d reading (%d) too close to limits, "
+			"unable to determine sensor type, skipping sensor\n",
+			(int)sensor_addr, (int)val);
+		/* assume no sensor is there for sensors for which we can't
+		   determine the sensor type because their reading is too close
+		   to their limits, this usually means no sensor is there. */
+		return ABIT_UGURU_NC;
+	}
+
+	ABIT_UGURU_DEBUG(2, "testing bank1 sensor %d\n", (int)sensor_addr);
+	/* Volt sensor test, enable volt low alarm, set min value ridicously
+	   high. If its a volt sensor this should always give us an alarm. */
+	buf[0] = ABIT_UGURU_VOLT_LOW_ALARM_ENABLE;
+	buf[1] = 245;
+	buf[2] = 250;
+	if (abituguru_write(data, ABIT_UGURU_SENSOR_BANK1 + 2, sensor_addr,
+			buf, 3) != 3)
+		goto abituguru_detect_bank1_sensor_type_exit;
+	/* Now we need 20 ms to give the uguru time to read the sensors
+	   and raise a voltage alarm */
+	set_current_state(TASK_UNINTERRUPTIBLE);
+	schedule_timeout(HZ/50);
+	/* Check for alarm and check the alarm is a volt low alarm. */
+	if (abituguru_read(data, ABIT_UGURU_ALARM_BANK, 0, buf, 3,
+			ABIT_UGURU_MAX_RETRIES) != 3)
+		goto abituguru_detect_bank1_sensor_type_exit;
+	if (buf[sensor_addr/8] & (0x01 << (sensor_addr % 8))) {
+		if (abituguru_read(data, ABIT_UGURU_SENSOR_BANK1 + 1,
+				sensor_addr, buf, 3,
+				ABIT_UGURU_MAX_RETRIES) != 3)
+			goto abituguru_detect_bank1_sensor_type_exit;
+		if (buf[0] & ABIT_UGURU_VOLT_LOW_ALARM_FLAG) {
+			ABIT_UGURU_DEBUG(2, "  found volt sensor\n");
+			ret = ABIT_UGURU_IN_SENSOR;
+			goto abituguru_detect_bank1_sensor_type_exit;
+		} else
+			ABIT_UGURU_DEBUG(2, "  alarm raised during volt "
+				"sensor test, but volt low flag not set\n");
+	} else
+		ABIT_UGURU_DEBUG(2, "  alarm not raised during volt sensor "
+			"test\n");
+
+	/* Temp sensor test, enable sensor as a temp sensor, set beep value
+	   ridicously low (but not too low, otherwise uguru ignores it).
+	   If its a temp sensor this should always give us an alarm. */
+	buf[0] = ABIT_UGURU_TEMP_HIGH_ALARM_ENABLE;
+	buf[1] = 5;
+	buf[2] = 10;
+	if (abituguru_write(data, ABIT_UGURU_SENSOR_BANK1 + 2, sensor_addr,
+			buf, 3) != 3)
+		goto abituguru_detect_bank1_sensor_type_exit;
+	/* Now we need 50 ms to give the uguru time to read the sensors
+	   and raise a temp alarm */
+	set_current_state(TASK_UNINTERRUPTIBLE);
+	schedule_timeout(HZ/20);
+	/* Check for alarm and check the alarm is a temp high alarm. */
+	if (abituguru_read(data, ABIT_UGURU_ALARM_BANK, 0, buf, 3,
+			ABIT_UGURU_MAX_RETRIES) != 3)
+		goto abituguru_detect_bank1_sensor_type_exit;
+	if (buf[sensor_addr/8] & (0x01 << (sensor_addr % 8))) {
+		if (abituguru_read(data, ABIT_UGURU_SENSOR_BANK1 + 1,
+				sensor_addr, buf, 3,
+				ABIT_UGURU_MAX_RETRIES) != 3)
+			goto abituguru_detect_bank1_sensor_type_exit;
+		if (buf[0] & ABIT_UGURU_TEMP_HIGH_ALARM_FLAG) {
+			ABIT_UGURU_DEBUG(2, "  found temp sensor\n");
+			ret = ABIT_UGURU_TEMP_SENSOR;
+			goto abituguru_detect_bank1_sensor_type_exit;
+		} else
+			ABIT_UGURU_DEBUG(2, "  alarm raised during temp "
+				"sensor test, but temp high flag not set\n");
+	} else
+		ABIT_UGURU_DEBUG(2, "  alarm not raised during temp sensor "
+			"test\n");
+
+	ret = ABIT_UGURU_NC;
+abituguru_detect_bank1_sensor_type_exit:
+	/* Restore original settings, failing here is really BAD, it has been
+	   reported that some BIOS-es hang when entering the uGuru menu with
+	   invalid settings present in the uGuru, so we try this 3 times. */
+	for (i = 0; i < 3; i++)
+		if (abituguru_write(data, ABIT_UGURU_SENSOR_BANK1 + 2,
+				sensor_addr, data->bank1_settings[sensor_addr],
+				3) == 3)
+			break;
+	if (i == 3) {
+		printk(KERN_ERR ABIT_UGURU_NAME
+			": Fatal error could not restore original settings. "
+			"This should never happen please report this to the "
+			"abituguru maintainer (see MAINTAINERS)\n");
+		return -ENODEV;
+	}
+	return ret;
+}
+
+/* These functions try to find out how many sensors there are in bank2 and how
+   many pwms there are. The purpose of this is to make sure that we don't give
+   the user the possibility to change settings for non-existent sensors / pwm.
+   The uGuru will happily read / write whatever memory happens to be after the
+   memory storing the PWM settings when reading/writing to a PWM which is not
+   there. Notice even if we detect a PWM which doesn't exist we normally won't
+   write to it, unless the user tries to change the settings.
+
+   Although the uGuru allows reading (settings) from non existing bank2
+   sensors, my version of the uGuru does seem to stop writing to them, the
+   write function above aborts in this case with:
+   "CMD reg does not hold 0xAC after write"
+
+   Notice these 2 tests are non destructive iow read-only tests, otherwise
+   they would defeat their purpose. Although for the bank2_sensors detection a
+   read/write test would be feasible because of the reaction above, I've
+   however opted to stay on the safe side. */
+static void __devinit
+abituguru_detect_no_bank2_sensors(struct abituguru_data *data)
+{
+	int i;
+
+	if (fan_sensors > 0 && fan_sensors <= ABIT_UGURU_MAX_BANK2_SENSORS) {
+		data->bank2_sensors = fan_sensors;
+		ABIT_UGURU_DEBUG(2, "assuming %d fan sensors because of "
+			"\"fan_sensors\" module param\n",
+			(int)data->bank2_sensors);
+		return;
+	}
+
+	ABIT_UGURU_DEBUG(2, "detecting number of fan sensors\n");
+	for (i = 0; i < ABIT_UGURU_MAX_BANK2_SENSORS; i++) {
+		/* 0x89 are the known used bits:
+		   -0x80 enable shutdown
+		   -0x08 enable beep
+		   -0x01 enable alarm
+		   All other bits should be 0, but on some motherboards
+		   0x40 (bit 6) is also high for some of the fans?? */
+		if (data->bank2_settings[i][0] & ~0xC9) {
+			ABIT_UGURU_DEBUG(2, "  bank2 sensor %d does not seem "
+				"to be a fan sensor: settings[0] = %02X\n",
+				i, (unsigned int)data->bank2_settings[i][0]);
+			break;
+		}
+
+		/* check if the threshold is within the allowed range */
+		if (data->bank2_settings[i][1] <
+				abituguru_bank2_min_threshold) {
+			ABIT_UGURU_DEBUG(2, "  bank2 sensor %d does not seem "
+				"to be a fan sensor: the threshold (%d) is "
+				"below the minimum (%d)\n", i,
+				(int)data->bank2_settings[i][1],
+				(int)abituguru_bank2_min_threshold);
+			break;
+		}
+		if (data->bank2_settings[i][1] >
+				abituguru_bank2_max_threshold) {
+			ABIT_UGURU_DEBUG(2, "  bank2 sensor %d does not seem "
+				"to be a fan sensor: the threshold (%d) is "
+				"above the maximum (%d)\n", i,
+				(int)data->bank2_settings[i][1],
+				(int)abituguru_bank2_max_threshold);
+			break;
+		}
+	}
+
+	data->bank2_sensors = i;
+	ABIT_UGURU_DEBUG(2, " found: %d fan sensors\n",
+		(int)data->bank2_sensors);
+}
+
+static void __devinit
+abituguru_detect_no_pwms(struct abituguru_data *data)
+{
+	int i, j;
+
+	if (pwms > 0 && pwms <= ABIT_UGURU_MAX_PWMS) {
+		data->pwms = pwms;
+		ABIT_UGURU_DEBUG(2, "assuming %d PWM outputs because of "
+			"\"pwms\" module param\n", (int)data->pwms);
+		return;
+	}
+
+	ABIT_UGURU_DEBUG(2, "detecting number of PWM outputs\n");
+	for (i = 0; i < ABIT_UGURU_MAX_PWMS; i++) {
+		/* 0x80 is the enable bit and the low
+		   nibble is which temp sensor to use,
+		   the other bits should be 0 */
+		if (data->pwm_settings[i][0] & ~0x8F) {
+			ABIT_UGURU_DEBUG(2, "  pwm channel %d does not seem "
+				"to be a pwm channel: settings[0] = %02X\n",
+				i, (unsigned int)data->pwm_settings[i][0]);
+			break;
+		}
+
+		/* the low nibble must correspond to one of the temp sensors
+		   we've found */
+		for (j = 0; j < data->bank1_sensors[ABIT_UGURU_TEMP_SENSOR];
+				j++) {
+			if (data->bank1_address[ABIT_UGURU_TEMP_SENSOR][j] ==
+					(data->pwm_settings[i][0] & 0x0F))
+				break;
+		}
+		if (j == data->bank1_sensors[ABIT_UGURU_TEMP_SENSOR]) {
+			ABIT_UGURU_DEBUG(2, "  pwm channel %d does not seem "
+				"to be a pwm channel: %d is not a valid temp "
+				"sensor address\n", i,
+				data->pwm_settings[i][0] & 0x0F);
+			break;
+		}
+
+		/* check if all other settings are within the allowed range */
+		for (j = 1; j < 5; j++) {
+			u8 min;
+			/* special case pwm1 min pwm% */
+			if ((i == 0) && ((j == 1) || (j == 2)))
+				min = 77;
+			else
+				min = abituguru_pwm_min[j];
+			if (data->pwm_settings[i][j] < min) {
+				ABIT_UGURU_DEBUG(2, "  pwm channel %d does "
+					"not seem to be a pwm channel: "
+					"setting %d (%d) is below the minimum "
+					"value (%d)\n", i, j,
+					(int)data->pwm_settings[i][j],
+					(int)min);
+				goto abituguru_detect_no_pwms_exit;
+			}
+			if (data->pwm_settings[i][j] > abituguru_pwm_max[j]) {
+				ABIT_UGURU_DEBUG(2, "  pwm channel %d does "
+					"not seem to be a pwm channel: "
+					"setting %d (%d) is above the maximum "
+					"value (%d)\n", i, j,
+					(int)data->pwm_settings[i][j],
+					(int)abituguru_pwm_max[j]);
+				goto abituguru_detect_no_pwms_exit;
+			}
+		}
+
+		/* check that min temp < max temp and min pwm < max pwm */
+		if (data->pwm_settings[i][1] >= data->pwm_settings[i][2]) {
+			ABIT_UGURU_DEBUG(2, "  pwm channel %d does not seem "
+				"to be a pwm channel: min pwm (%d) >= "
+				"max pwm (%d)\n", i,
+				(int)data->pwm_settings[i][1],
+				(int)data->pwm_settings[i][2]);
+			break;
+		}
+		if (data->pwm_settings[i][3] >= data->pwm_settings[i][4]) {
+			ABIT_UGURU_DEBUG(2, "  pwm channel %d does not seem "
+				"to be a pwm channel: min temp (%d) >= "
+				"max temp (%d)\n", i,
+				(int)data->pwm_settings[i][3],
+				(int)data->pwm_settings[i][4]);
+			break;
+		}
+	}
+
+abituguru_detect_no_pwms_exit:
+	data->pwms = i;
+	ABIT_UGURU_DEBUG(2, " found: %d PWM outputs\n", (int)data->pwms);
+}
+
+/* Following are the sysfs callback functions. These functions expect:
+   sensor_device_attribute_2->index:   sensor address/offset in the bank
+   sensor_device_attribute_2->nr:      register offset, bitmask or NA. */
+static struct abituguru_data *abituguru_update_device(struct device *dev);
+
+static ssize_t show_bank1_value(struct device *dev,
+	struct device_attribute *devattr, char *buf)
+{
+	struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(devattr);
+	struct abituguru_data *data = abituguru_update_device(dev);
+	if (!data)
+		return -EIO;
+	return sprintf(buf, "%d\n", (data->bank1_value[attr->index] *
+		data->bank1_max_value[attr->index] + 128) / 255);
+}
+
+static ssize_t show_bank1_setting(struct device *dev,
+	struct device_attribute *devattr, char *buf)
+{
+	struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(devattr);
+	struct abituguru_data *data = dev_get_drvdata(dev);
+	return sprintf(buf, "%d\n",
+		(data->bank1_settings[attr->index][attr->nr] *
+		data->bank1_max_value[attr->index] + 128) / 255);
+}
+
+static ssize_t show_bank2_value(struct device *dev,
+	struct device_attribute *devattr, char *buf)
+{
+	struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(devattr);
+	struct abituguru_data *data = abituguru_update_device(dev);
+	if (!data)
+		return -EIO;
+	return sprintf(buf, "%d\n", (data->bank2_value[attr->index] *
+		ABIT_UGURU_FAN_MAX + 128) / 255);
+}
+
+static ssize_t show_bank2_setting(struct device *dev,
+	struct device_attribute *devattr, char *buf)
+{
+	struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(devattr);
+	struct abituguru_data *data = dev_get_drvdata(dev);
+	return sprintf(buf, "%d\n",
+		(data->bank2_settings[attr->index][attr->nr] *
+		ABIT_UGURU_FAN_MAX + 128) / 255);
+}
+
+static ssize_t store_bank1_setting(struct device *dev, struct device_attribute
+	*devattr, const char *buf, size_t count)
+{
+	struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(devattr);
+	struct abituguru_data *data = dev_get_drvdata(dev);
+	u8 val = (simple_strtoul(buf, NULL, 10) * 255 +
+		data->bank1_max_value[attr->index]/2) /
+		data->bank1_max_value[attr->index];
+	ssize_t ret = count;
+
+	mutex_lock(&data->update_lock);
+	if (data->bank1_settings[attr->index][attr->nr] != val) {
+		u8 orig_val = data->bank1_settings[attr->index][attr->nr];
+		data->bank1_settings[attr->index][attr->nr] = val;
+		if (abituguru_write(data, ABIT_UGURU_SENSOR_BANK1 + 2,
+				attr->index, data->bank1_settings[attr->index],
+				3) <= attr->nr) {
+			data->bank1_settings[attr->index][attr->nr] = orig_val;
+			ret = -EIO;
+		}
+	}
+	mutex_unlock(&data->update_lock);
+	return ret;
+}
+
+static ssize_t store_bank2_setting(struct device *dev, struct device_attribute
+	*devattr, const char *buf, size_t count)
+{
+	struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(devattr);
+	struct abituguru_data *data = dev_get_drvdata(dev);
+	u8 val = (simple_strtoul(buf, NULL, 10)*255 + ABIT_UGURU_FAN_MAX/2) /
+		ABIT_UGURU_FAN_MAX;
+	ssize_t ret = count;
+
+	/* this check can be done before taking the lock */
+	if ((val < abituguru_bank2_min_threshold) ||
+			(val > abituguru_bank2_max_threshold))
+		return -EINVAL;
+
+	mutex_lock(&data->update_lock);
+	if (data->bank2_settings[attr->index][attr->nr] != val) {
+		u8 orig_val = data->bank2_settings[attr->index][attr->nr];
+		data->bank2_settings[attr->index][attr->nr] = val;
+		if (abituguru_write(data, ABIT_UGURU_SENSOR_BANK2 + 2,
+				attr->index, data->bank2_settings[attr->index],
+				2) <= attr->nr) {
+			data->bank2_settings[attr->index][attr->nr] = orig_val;
+			ret = -EIO;
+		}
+	}
+	mutex_unlock(&data->update_lock);
+	return ret;
+}
+
+static ssize_t show_bank1_alarm(struct device *dev,
+	struct device_attribute *devattr, char *buf)
+{
+	struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(devattr);
+	struct abituguru_data *data = abituguru_update_device(dev);
+	if (!data)
+		return -EIO;
+	/* See if the alarm bit for this sensor is set, and if the
+	   alarm matches the type of alarm we're looking for (for volt
+	   it can be either low or high). The type is stored in a few
+	   readonly bits in the settings part of the relevant sensor.
+	   The bitmask of the type is passed to us in attr->nr. */
+	if ((data->alarms[attr->index / 8] & (0x01 << (attr->index % 8))) &&
+			(data->bank1_settings[attr->index][0] & attr->nr))
+		return sprintf(buf, "1\n");
+	else
+		return sprintf(buf, "0\n");
+}
+
+static ssize_t show_bank2_alarm(struct device *dev,
+	struct device_attribute *devattr, char *buf)
+{
+	struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(devattr);
+	struct abituguru_data *data = abituguru_update_device(dev);
+	if (!data)
+		return -EIO;
+	if (data->alarms[2] & (0x01 << attr->index))
+		return sprintf(buf, "1\n");
+	else
+		return sprintf(buf, "0\n");
+}
+
+static ssize_t show_bank1_mask(struct device *dev,
+	struct device_attribute *devattr, char *buf)
+{
+	struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(devattr);
+	struct abituguru_data *data = dev_get_drvdata(dev);
+	if (data->bank1_settings[attr->index][0] & attr->nr)
+		return sprintf(buf, "1\n");
+	else
+		return sprintf(buf, "0\n");
+}
+
+static ssize_t show_bank2_mask(struct device *dev,
+	struct device_attribute *devattr, char *buf)
+{
+	struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(devattr);
+	struct abituguru_data *data = dev_get_drvdata(dev);
+	if (data->bank2_settings[attr->index][0] & attr->nr)
+		return sprintf(buf, "1\n");
+	else
+		return sprintf(buf, "0\n");
+}
+
+static ssize_t store_bank1_mask(struct device *dev,
+	struct device_attribute *devattr, const char *buf, size_t count)
+{
+	struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(devattr);
+	struct abituguru_data *data = dev_get_drvdata(dev);
+	int mask = simple_strtoul(buf, NULL, 10);
+	ssize_t ret = count;
+	u8 orig_val;
+
+	mutex_lock(&data->update_lock);
+	orig_val = data->bank1_settings[attr->index][0];
+
+	if (mask)
+		data->bank1_settings[attr->index][0] |= attr->nr;
+	else
+		data->bank1_settings[attr->index][0] &= ~attr->nr;
+
+	if ((data->bank1_settings[attr->index][0] != orig_val) &&
+			(abituguru_write(data,
+			ABIT_UGURU_SENSOR_BANK1 + 2, attr->index,
+			data->bank1_settings[attr->index], 3) < 1)) {
+		data->bank1_settings[attr->index][0] = orig_val;
+		ret = -EIO;
+	}
+	mutex_unlock(&data->update_lock);
+	return ret;
+}
+
+static ssize_t store_bank2_mask(struct device *dev,
+	struct device_attribute *devattr, const char *buf, size_t count)
+{
+	struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(devattr);
+	struct abituguru_data *data = dev_get_drvdata(dev);
+	int mask = simple_strtoul(buf, NULL, 10);
+	ssize_t ret = count;
+	u8 orig_val;
+
+	mutex_lock(&data->update_lock);
+	orig_val = data->bank2_settings[attr->index][0];
+
+	if (mask)
+		data->bank2_settings[attr->index][0] |= attr->nr;
+	else
+		data->bank2_settings[attr->index][0] &= ~attr->nr;
+
+	if ((data->bank2_settings[attr->index][0] != orig_val) &&
+			(abituguru_write(data,
+			ABIT_UGURU_SENSOR_BANK2 + 2, attr->index,
+			data->bank2_settings[attr->index], 2) < 1)) {
+		data->bank2_settings[attr->index][0] = orig_val;
+		ret = -EIO;
+	}
+	mutex_unlock(&data->update_lock);
+	return ret;
+}
+
+/* Fan PWM (speed control) */
+static ssize_t show_pwm_setting(struct device *dev,
+	struct device_attribute *devattr, char *buf)
+{
+	struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(devattr);
+	struct abituguru_data *data = dev_get_drvdata(dev);
+	return sprintf(buf, "%d\n", data->pwm_settings[attr->index][attr->nr] *
+		abituguru_pwm_settings_multiplier[attr->nr]);
+}
+
+static ssize_t store_pwm_setting(struct device *dev, struct device_attribute
+	*devattr, const char *buf, size_t count)
+{
+	struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(devattr);
+	struct abituguru_data *data = dev_get_drvdata(dev);
+	u8 min, val = (simple_strtoul(buf, NULL, 10) +
+		abituguru_pwm_settings_multiplier[attr->nr]/2) /
+		abituguru_pwm_settings_multiplier[attr->nr];
+	ssize_t ret = count;
+
+	/* special case pwm1 min pwm% */
+	if ((attr->index == 0) && ((attr->nr == 1) || (attr->nr == 2)))
+		min = 77;
+	else
+		min = abituguru_pwm_min[attr->nr];
+
+	/* this check can be done before taking the lock */
+	if ((val < min) || (val > abituguru_pwm_max[attr->nr]))
+		return -EINVAL;
+
+	mutex_lock(&data->update_lock);
+	/* this check needs to be done after taking the lock */
+	if ((attr->nr & 1) &&
+			(val >= data->pwm_settings[attr->index][attr->nr + 1]))
+		ret = -EINVAL;
+	else if (!(attr->nr & 1) &&
+			(val <= data->pwm_settings[attr->index][attr->nr - 1]))
+		ret = -EINVAL;
+	else if (data->pwm_settings[attr->index][attr->nr] != val) {
+		u8 orig_val = data->pwm_settings[attr->index][attr->nr];
+		data->pwm_settings[attr->index][attr->nr] = val;
+		if (abituguru_write(data, ABIT_UGURU_FAN_PWM + 1,
+				attr->index, data->pwm_settings[attr->index],
+				5) <= attr->nr) {
+			data->pwm_settings[attr->index][attr->nr] =
+				orig_val;
+			ret = -EIO;
+		}
+	}
+	mutex_unlock(&data->update_lock);
+	return ret;
+}
+
+static ssize_t show_pwm_sensor(struct device *dev,
+	struct device_attribute *devattr, char *buf)
+{
+	struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(devattr);
+	struct abituguru_data *data = dev_get_drvdata(dev);
+	int i;
+	/* We need to walk to the temp sensor addresses to find what
+	   the userspace id of the configured temp sensor is. */
+	for (i = 0; i < data->bank1_sensors[ABIT_UGURU_TEMP_SENSOR]; i++)
+		if (data->bank1_address[ABIT_UGURU_TEMP_SENSOR][i] ==
+				(data->pwm_settings[attr->index][0] & 0x0F))
+			return sprintf(buf, "%d\n", i+1);
+
+	return -ENXIO;
+}
+
+static ssize_t store_pwm_sensor(struct device *dev, struct device_attribute
+	*devattr, const char *buf, size_t count)
+{
+	struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(devattr);
+	struct abituguru_data *data = dev_get_drvdata(dev);
+	unsigned long val = simple_strtoul(buf, NULL, 10) - 1;
+	ssize_t ret = count;
+
+	mutex_lock(&data->update_lock);
+	if (val < data->bank1_sensors[ABIT_UGURU_TEMP_SENSOR]) {
+		u8 orig_val = data->pwm_settings[attr->index][0];
+		u8 address = data->bank1_address[ABIT_UGURU_TEMP_SENSOR][val];
+		data->pwm_settings[attr->index][0] &= 0xF0;
+		data->pwm_settings[attr->index][0] |= address;
+		if (data->pwm_settings[attr->index][0] != orig_val) {
+			if (abituguru_write(data, ABIT_UGURU_FAN_PWM + 1,
+					attr->index,
+					data->pwm_settings[attr->index],
+					5) < 1) {
+				data->pwm_settings[attr->index][0] = orig_val;
+				ret = -EIO;
+			}
+		}
+	}
+	else
+		ret = -EINVAL;
+	mutex_unlock(&data->update_lock);
+	return ret;
+}
+
+static ssize_t show_pwm_enable(struct device *dev,
+	struct device_attribute *devattr, char *buf)
+{
+	struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(devattr);
+	struct abituguru_data *data = dev_get_drvdata(dev);
+	int res = 0;
+	if (data->pwm_settings[attr->index][0] & ABIT_UGURU_FAN_PWM_ENABLE)
+		res = 2;
+	return sprintf(buf, "%d\n", res);
+}
+
+static ssize_t store_pwm_enable(struct device *dev, struct device_attribute
+	*devattr, const char *buf, size_t count)
+{
+	struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(devattr);
+	struct abituguru_data *data = dev_get_drvdata(dev);
+	u8 orig_val, user_val = simple_strtoul(buf, NULL, 10);
+	ssize_t ret = count;
+
+	mutex_lock(&data->update_lock);
+	orig_val = data->pwm_settings[attr->index][0];
+	switch (user_val) {
+		case 0:
+			data->pwm_settings[attr->index][0] &=
+				~ABIT_UGURU_FAN_PWM_ENABLE;
+			break;
+		case 2:
+			data->pwm_settings[attr->index][0] |=
+				ABIT_UGURU_FAN_PWM_ENABLE;
+			break;
+		default:
+			ret = -EINVAL;
+	}
+	if ((data->pwm_settings[attr->index][0] != orig_val) &&
+			(abituguru_write(data, ABIT_UGURU_FAN_PWM + 1,
+			attr->index, data->pwm_settings[attr->index],
+			5) < 1)) {
+		data->pwm_settings[attr->index][0] = orig_val;
+		ret = -EIO;
+	}
+	mutex_unlock(&data->update_lock);
+	return ret;
+}
+
+static ssize_t show_name(struct device *dev,
+	struct device_attribute *devattr, char *buf)
+{
+	return sprintf(buf, "%s\n", ABIT_UGURU_NAME);
+}
+
+/* Sysfs attr templates, the real entries are generated automatically. */
+static const
+struct sensor_device_attribute_2 abituguru_sysfs_bank1_templ[2][9] = {
+	{
+	SENSOR_ATTR_2(in%d_input, 0444, show_bank1_value, NULL, 0, 0),
+	SENSOR_ATTR_2(in%d_min, 0644, show_bank1_setting,
+		store_bank1_setting, 1, 0),
+	SENSOR_ATTR_2(in%d_min_alarm, 0444, show_bank1_alarm, NULL,
+		ABIT_UGURU_VOLT_LOW_ALARM_FLAG, 0),
+	SENSOR_ATTR_2(in%d_max, 0644, show_bank1_setting,
+		store_bank1_setting, 2, 0),
+	SENSOR_ATTR_2(in%d_max_alarm, 0444, show_bank1_alarm, NULL,
+		ABIT_UGURU_VOLT_HIGH_ALARM_FLAG, 0),
+	SENSOR_ATTR_2(in%d_beep, 0644, show_bank1_mask,
+		store_bank1_mask, ABIT_UGURU_BEEP_ENABLE, 0),
+	SENSOR_ATTR_2(in%d_shutdown, 0644, show_bank1_mask,
+		store_bank1_mask, ABIT_UGURU_SHUTDOWN_ENABLE, 0),
+	SENSOR_ATTR_2(in%d_min_alarm_enable, 0644, show_bank1_mask,
+		store_bank1_mask, ABIT_UGURU_VOLT_LOW_ALARM_ENABLE, 0),
+	SENSOR_ATTR_2(in%d_max_alarm_enable, 0644, show_bank1_mask,
+		store_bank1_mask, ABIT_UGURU_VOLT_HIGH_ALARM_ENABLE, 0),
+	}, {
+	SENSOR_ATTR_2(temp%d_input, 0444, show_bank1_value, NULL, 0, 0),
+	SENSOR_ATTR_2(temp%d_alarm, 0444, show_bank1_alarm, NULL,
+		ABIT_UGURU_TEMP_HIGH_ALARM_FLAG, 0),
+	SENSOR_ATTR_2(temp%d_max, 0644, show_bank1_setting,
+		store_bank1_setting, 1, 0),
+	SENSOR_ATTR_2(temp%d_crit, 0644, show_bank1_setting,
+		store_bank1_setting, 2, 0),
+	SENSOR_ATTR_2(temp%d_beep, 0644, show_bank1_mask,
+		store_bank1_mask, ABIT_UGURU_BEEP_ENABLE, 0),
+	SENSOR_ATTR_2(temp%d_shutdown, 0644, show_bank1_mask,
+		store_bank1_mask, ABIT_UGURU_SHUTDOWN_ENABLE, 0),
+	SENSOR_ATTR_2(temp%d_alarm_enable, 0644, show_bank1_mask,
+		store_bank1_mask, ABIT_UGURU_TEMP_HIGH_ALARM_ENABLE, 0),
+	}
+};
+
+static const struct sensor_device_attribute_2 abituguru_sysfs_fan_templ[6] = {
+	SENSOR_ATTR_2(fan%d_input, 0444, show_bank2_value, NULL, 0, 0),
+	SENSOR_ATTR_2(fan%d_alarm, 0444, show_bank2_alarm, NULL, 0, 0),
+	SENSOR_ATTR_2(fan%d_min, 0644, show_bank2_setting,
+		store_bank2_setting, 1, 0),
+	SENSOR_ATTR_2(fan%d_beep, 0644, show_bank2_mask,
+		store_bank2_mask, ABIT_UGURU_BEEP_ENABLE, 0),
+	SENSOR_ATTR_2(fan%d_shutdown, 0644, show_bank2_mask,
+		store_bank2_mask, ABIT_UGURU_SHUTDOWN_ENABLE, 0),
+	SENSOR_ATTR_2(fan%d_alarm_enable, 0644, show_bank2_mask,
+		store_bank2_mask, ABIT_UGURU_FAN_LOW_ALARM_ENABLE, 0),
+};
+
+static const struct sensor_device_attribute_2 abituguru_sysfs_pwm_templ[6] = {
+	SENSOR_ATTR_2(pwm%d_enable, 0644, show_pwm_enable,
+		store_pwm_enable, 0, 0),
+	SENSOR_ATTR_2(pwm%d_auto_channels_temp, 0644, show_pwm_sensor,
+		store_pwm_sensor, 0, 0),
+	SENSOR_ATTR_2(pwm%d_auto_point1_pwm, 0644, show_pwm_setting,
+		store_pwm_setting, 1, 0),
+	SENSOR_ATTR_2(pwm%d_auto_point2_pwm, 0644, show_pwm_setting,
+		store_pwm_setting, 2, 0),
+	SENSOR_ATTR_2(pwm%d_auto_point1_temp, 0644, show_pwm_setting,
+		store_pwm_setting, 3, 0),
+	SENSOR_ATTR_2(pwm%d_auto_point2_temp, 0644, show_pwm_setting,
+		store_pwm_setting, 4, 0),
+};
+
+static struct sensor_device_attribute_2 abituguru_sysfs_attr[] = {
+	SENSOR_ATTR_2(name, 0444, show_name, NULL, 0, 0),
+};
+
+static int __devinit abituguru_probe(struct platform_device *pdev)
+{
+	struct abituguru_data *data;
+	int i, j, used, sysfs_names_free, sysfs_attr_i, res = -ENODEV;
+	char *sysfs_filename;
+
+	/* El weirdo probe order, to keep the sysfs order identical to the
+	   BIOS and window-appliction listing order. */
+	const u8 probe_order[ABIT_UGURU_MAX_BANK1_SENSORS] = {
+		0x00, 0x01, 0x03, 0x04, 0x0A, 0x08, 0x0E, 0x02,
+		0x09, 0x06, 0x05, 0x0B, 0x0F, 0x0D, 0x07, 0x0C };
+
+	if (!(data = kzalloc(sizeof(struct abituguru_data), GFP_KERNEL)))
+		return -ENOMEM;
+
+	data->addr = platform_get_resource(pdev, IORESOURCE_IO, 0)->start;
+	mutex_init(&data->update_lock);
+	platform_set_drvdata(pdev, data);
+
+	/* See if the uGuru is ready */
+	if (inb_p(data->addr + ABIT_UGURU_DATA) == ABIT_UGURU_STATUS_INPUT)
+		data->uguru_ready = 1;
+
+	/* Completely read the uGuru this has 2 purposes:
+	   - testread / see if one really is there.
+	   - make an in memory copy of all the uguru settings for future use. */
+	if (abituguru_read(data, ABIT_UGURU_ALARM_BANK, 0,
+			data->alarms, 3, ABIT_UGURU_MAX_RETRIES) != 3)
+		goto abituguru_probe_error;
+
+	for (i = 0; i < ABIT_UGURU_MAX_BANK1_SENSORS; i++) {
+		if (abituguru_read(data, ABIT_UGURU_SENSOR_BANK1, i,
+				&data->bank1_value[i], 1,
+				ABIT_UGURU_MAX_RETRIES) != 1)
+			goto abituguru_probe_error;
+		if (abituguru_read(data, ABIT_UGURU_SENSOR_BANK1+1, i,
+				data->bank1_settings[i], 3,
+				ABIT_UGURU_MAX_RETRIES) != 3)
+			goto abituguru_probe_error;
+	}
+	/* Note: We don't know how many bank2 sensors / pwms there really are,
+	   but in order to "detect" this we need to read the maximum amount
+	   anyways. If we read sensors/pwms not there we'll just read crap
+	   this can't hurt. We need the detection because we don't want
+	   unwanted writes, which will hurt! */
+	for (i = 0; i < ABIT_UGURU_MAX_BANK2_SENSORS; i++) {
+		if (abituguru_read(data, ABIT_UGURU_SENSOR_BANK2, i,
+				&data->bank2_value[i], 1,
+				ABIT_UGURU_MAX_RETRIES) != 1)
+			goto abituguru_probe_error;
+		if (abituguru_read(data, ABIT_UGURU_SENSOR_BANK2+1, i,
+				data->bank2_settings[i], 2,
+				ABIT_UGURU_MAX_RETRIES) != 2)
+			goto abituguru_probe_error;
+	}
+	for (i = 0; i < ABIT_UGURU_MAX_PWMS; i++) {
+		if (abituguru_read(data, ABIT_UGURU_FAN_PWM, i,
+				data->pwm_settings[i], 5,
+				ABIT_UGURU_MAX_RETRIES) != 5)
+			goto abituguru_probe_error;
+	}
+	data->last_updated = jiffies;
+
+	/* Detect sensor types and fill the sysfs attr for bank1 */
+	sysfs_attr_i = 0;
+	sysfs_filename = data->sysfs_names;
+	sysfs_names_free = ABITUGURU_SYSFS_NAMES_LENGTH;
+	for (i = 0; i < ABIT_UGURU_MAX_BANK1_SENSORS; i++) {
+		res = abituguru_detect_bank1_sensor_type(data, probe_order[i]);
+		if (res < 0)
+			goto abituguru_probe_error;
+		if (res == ABIT_UGURU_NC)
+			continue;
+
+		/* res 1 (temp) sensors have 7 sysfs entries, 0 (in) 9 */
+		for (j = 0; j < (res ? 7 : 9); j++) {
+			used = snprintf(sysfs_filename, sysfs_names_free,
+				abituguru_sysfs_bank1_templ[res][j].dev_attr.
+				attr.name, data->bank1_sensors[res] + res)
+				+ 1;
+			data->sysfs_attr[sysfs_attr_i] =
+				abituguru_sysfs_bank1_templ[res][j];
+			data->sysfs_attr[sysfs_attr_i].dev_attr.attr.name =
+				sysfs_filename;
+			data->sysfs_attr[sysfs_attr_i].index = probe_order[i];
+			sysfs_filename += used;
+			sysfs_names_free -= used;
+			sysfs_attr_i++;
+		}
+		data->bank1_max_value[probe_order[i]] =
+			abituguru_bank1_max_value[res];
+		data->bank1_address[res][data->bank1_sensors[res]] =
+			probe_order[i];
+		data->bank1_sensors[res]++;
+	}
+	/* Detect number of sensors and fill the sysfs attr for bank2 (fans) */
+	abituguru_detect_no_bank2_sensors(data);
+	for (i = 0; i < data->bank2_sensors; i++) {
+		for (j = 0; j < ARRAY_SIZE(abituguru_sysfs_fan_templ); j++) {
+			used = snprintf(sysfs_filename, sysfs_names_free,
+				abituguru_sysfs_fan_templ[j].dev_attr.attr.name,
+				i + 1) + 1;
+			data->sysfs_attr[sysfs_attr_i] =
+				abituguru_sysfs_fan_templ[j];
+			data->sysfs_attr[sysfs_attr_i].dev_attr.attr.name =
+				sysfs_filename;
+			data->sysfs_attr[sysfs_attr_i].index = i;
+			sysfs_filename += used;
+			sysfs_names_free -= used;
+			sysfs_attr_i++;
+		}
+	}
+	/* Detect number of sensors and fill the sysfs attr for pwms */
+	abituguru_detect_no_pwms(data);
+	for (i = 0; i < data->pwms; i++) {
+		for (j = 0; j < ARRAY_SIZE(abituguru_sysfs_pwm_templ); j++) {
+			used = snprintf(sysfs_filename, sysfs_names_free,
+				abituguru_sysfs_pwm_templ[j].dev_attr.attr.name,
+				i + 1) + 1;
+			data->sysfs_attr[sysfs_attr_i] =
+				abituguru_sysfs_pwm_templ[j];
+			data->sysfs_attr[sysfs_attr_i].dev_attr.attr.name =
+				sysfs_filename;
+			data->sysfs_attr[sysfs_attr_i].index = i;
+			sysfs_filename += used;
+			sysfs_names_free -= used;
+			sysfs_attr_i++;
+		}
+	}
+	/* Fail safe check, this should never happen! */
+	if (sysfs_names_free < 0) {
+		printk(KERN_ERR ABIT_UGURU_NAME ": Fatal error ran out of "
+		       "space for sysfs attr names. This should never "
+		       "happen please report to the abituguru maintainer "
+		       "(see MAINTAINERS)\n");
+		res = -ENAMETOOLONG;
+		goto abituguru_probe_error;
+	}
+	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);
+	for (i = 0; i < ARRAY_SIZE(abituguru_sysfs_attr); i++)
+		device_create_file(&pdev->dev,
+			&abituguru_sysfs_attr[i].dev_attr);
+
+	return 0;
+
+abituguru_probe_error:
+	kfree(data);
+	return res;
+}
+
+static int __devexit abituguru_remove(struct platform_device *pdev)
+{
+	struct abituguru_data *data = platform_get_drvdata(pdev);
+
+	platform_set_drvdata(pdev, NULL);
+	hwmon_device_unregister(data->class_dev);
+	kfree(data);
+
+	return 0;
+}
+
+static struct abituguru_data *abituguru_update_device(struct device *dev)
+{
+	int i, err;
+	struct abituguru_data *data = dev_get_drvdata(dev);
+	/* fake a complete successful read if no update necessary. */
+	char success = 1;
+
+	mutex_lock(&data->update_lock);
+	if (time_after(jiffies, data->last_updated + HZ)) {
+		success = 0;
+		if ((err = abituguru_read(data, ABIT_UGURU_ALARM_BANK, 0,
+				data->alarms, 3, 0)) != 3)
+			goto LEAVE_UPDATE;
+		for (i = 0; i < ABIT_UGURU_MAX_BANK1_SENSORS; i++) {
+			if ((err = abituguru_read(data,
+					ABIT_UGURU_SENSOR_BANK1, i,
+					&data->bank1_value[i], 1, 0)) != 1)
+				goto LEAVE_UPDATE;
+			if ((err = abituguru_read(data,
+					ABIT_UGURU_SENSOR_BANK1 + 1, i,
+					data->bank1_settings[i], 3, 0)) != 3)
+				goto LEAVE_UPDATE;
+		}
+		for (i = 0; i < data->bank2_sensors; i++)
+			if ((err = abituguru_read(data,
+					ABIT_UGURU_SENSOR_BANK2, i,
+					&data->bank2_value[i], 1, 0)) != 1)
+				goto LEAVE_UPDATE;
+		/* success! */
+		success = 1;
+		data->update_timeouts = 0;
+LEAVE_UPDATE:
+		/* handle timeout condition */
+		if (!success && (err == -EBUSY || err >= 0)) {
+			/* No overflow please */
+			if (data->update_timeouts < 255u)
+				data->update_timeouts++;
+			if (data->update_timeouts <= ABIT_UGURU_MAX_TIMEOUTS) {
+				ABIT_UGURU_DEBUG(3, "timeout exceeded, will "
+					"try again next update\n");
+				/* Just a timeout, fake a successful read */
+				success = 1;
+			} else
+				ABIT_UGURU_DEBUG(1, "timeout exceeded %d "
+					"times waiting for more input state\n",
+					(int)data->update_timeouts);
+		}
+		/* On success set last_updated */
+		if (success)
+			data->last_updated = jiffies;
+	}
+	mutex_unlock(&data->update_lock);
+
+	if (success)
+		return data;
+	else
+		return NULL;
+}
+
+static struct platform_driver abituguru_driver = {
+	.driver = {
+		.owner	= THIS_MODULE,
+		.name	= ABIT_UGURU_NAME,
+	},
+	.probe	= abituguru_probe,
+	.remove	= __devexit_p(abituguru_remove),
+};
+
+static int __init abituguru_detect(void)
+{
+	/* See if there is an uguru there. After a reboot uGuru will hold 0x00
+	   at DATA and 0xAC, when this driver has already been loaded once
+	   DATA will hold 0x08. For most uGuru's CMD will hold 0xAC in either
+	   scenario but some will hold 0x00.
+	   Some uGuru's initally hold 0x09 at DATA and will only hold 0x08
+	   after reading CMD first, so CMD must be read first! */
+	u8 cmd_val = inb_p(ABIT_UGURU_BASE + ABIT_UGURU_CMD);
+	u8 data_val = inb_p(ABIT_UGURU_BASE + ABIT_UGURU_DATA);
+	if (((data_val == 0x00) || (data_val == 0x08)) &&
+	    ((cmd_val == 0x00) || (cmd_val == 0xAC)))
+		return ABIT_UGURU_BASE;
+
+	ABIT_UGURU_DEBUG(2, "no Abit uGuru found, data = 0x%02X, cmd = "
+		"0x%02X\n", (unsigned int)data_val, (unsigned int)cmd_val);
+
+	if (force) {
+		printk(KERN_INFO ABIT_UGURU_NAME ": Assuming Abit uGuru is "
+				"present because of \"force\" parameter\n");
+		return ABIT_UGURU_BASE;
+	}
+
+	/* No uGuru found */
+	return -ENODEV;
+}
+
+static struct platform_device *abituguru_pdev;
+
+static int __init abituguru_init(void)
+{
+	int address, err;
+	struct resource res = { .flags = IORESOURCE_IO };
+
+	address = abituguru_detect();
+	if (address < 0)
+		return address;
+
+	err = platform_driver_register(&abituguru_driver);
+	if (err)
+		goto exit;
+
+	abituguru_pdev = platform_device_alloc(ABIT_UGURU_NAME, address);
+	if (!abituguru_pdev) {
+		printk(KERN_ERR ABIT_UGURU_NAME
+			": Device allocation failed\n");
+		err = -ENOMEM;
+		goto exit_driver_unregister;
+	}
+
+	res.start = address;
+	res.end = address + ABIT_UGURU_REGION_LENGTH - 1;
+	res.name = ABIT_UGURU_NAME;
+
+	err = platform_device_add_resources(abituguru_pdev, &res, 1);
+	if (err) {
+		printk(KERN_ERR ABIT_UGURU_NAME
+			": Device resource addition failed (%d)\n", err);
+		goto exit_device_put;
+	}
+
+	err = platform_device_add(abituguru_pdev);
+	if (err) {
+		printk(KERN_ERR ABIT_UGURU_NAME
+			": Device addition failed (%d)\n", err);
+		goto exit_device_put;
+	}
+
+	return 0;
+
+exit_device_put:
+	platform_device_put(abituguru_pdev);
+exit_driver_unregister:
+	platform_driver_unregister(&abituguru_driver);
+exit:
+	return err;
+}
+
+static void __exit abituguru_exit(void)
+{
+	platform_device_unregister(abituguru_pdev);
+	platform_driver_unregister(&abituguru_driver);
+}
+
+MODULE_AUTHOR("Hans de Goede <j.w.r.degoede@hhs.nl>");
+MODULE_DESCRIPTION("Abit uGuru Sensor device");
+MODULE_LICENSE("GPL");
+
+module_init(abituguru_init);
+module_exit(abituguru_exit);
diff --git a/drivers/hwmon/lm70.c b/drivers/hwmon/lm70.c
new file mode 100644
index 000000000..6ba84731b
--- /dev/null
+++ b/drivers/hwmon/lm70.c
@@ -0,0 +1,165 @@
+/*
+ * lm70.c
+ *
+ * The LM70 is a temperature sensor chip from National Semiconductor (NS).
+ * Copyright (C) 2006 Kaiwan N Billimoria <kaiwan@designergraphix.com>
+ *
+ * The LM70 communicates with a host processor via an SPI/Microwire Bus
+ * interface. The complete datasheet is available at National's website
+ * here:
+ * http://www.national.com/pf/LM/LM70.html
+ *
+ * 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/init.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/sysfs.h>
+#include <linux/hwmon.h>
+#include <linux/spi/spi.h>
+#include <asm/semaphore.h>
+
+#define DRVNAME		"lm70"
+
+struct lm70 {
+	struct class_device *cdev;
+	struct semaphore sem;
+};
+
+/* sysfs hook function */
+static ssize_t lm70_sense_temp(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	struct spi_device *spi = to_spi_device(dev);
+	int status, val;
+	u8 rxbuf[2];
+	s16 raw=0;
+	struct lm70 *p_lm70 = dev_get_drvdata(&spi->dev);
+
+	if (down_interruptible(&p_lm70->sem))
+		return -ERESTARTSYS;
+
+	/*
+	 * spi_read() requires a DMA-safe buffer; so we use
+	 * spi_write_then_read(), transmitting 0 bytes.
+	 */
+	status = spi_write_then_read(spi, NULL, 0, &rxbuf[0], 2);
+	if (status < 0) {
+		printk(KERN_WARNING
+		"spi_write_then_read failed with status %d\n", status);
+		goto out;
+	}
+	dev_dbg(dev, "rxbuf[1] : 0x%x rxbuf[0] : 0x%x\n", rxbuf[1], rxbuf[0]);
+
+	raw = (rxbuf[1] << 8) + rxbuf[0];
+	dev_dbg(dev, "raw=0x%x\n", raw);
+
+	/*
+	 * The "raw" temperature read into rxbuf[] is a 16-bit signed 2's
+	 * complement value. Only the MSB 11 bits (1 sign + 10 temperature
+	 * bits) are meaningful; the LSB 5 bits are to be discarded.
+	 * See the datasheet.
+	 *
+	 * Further, each bit represents 0.25 degrees Celsius; so, multiply
+	 * by 0.25. Also multiply by 1000 to represent in millidegrees
+	 * Celsius.
+	 * So it's equivalent to multiplying by 0.25 * 1000 = 250.
+	 */
+	val = ((int)raw/32) * 250;
+	status = sprintf(buf, "%+d\n", val); /* millidegrees Celsius */
+out:
+	up(&p_lm70->sem);
+	return status;
+}
+
+static DEVICE_ATTR(temp1_input, S_IRUGO, lm70_sense_temp, NULL);
+
+/*----------------------------------------------------------------------*/
+
+static int __devinit lm70_probe(struct spi_device *spi)
+{
+	struct lm70 *p_lm70;
+	int status;
+
+	p_lm70 = kzalloc(sizeof *p_lm70, GFP_KERNEL);
+	if (!p_lm70)
+		return -ENOMEM;
+
+	init_MUTEX(&p_lm70->sem);
+
+	/* sysfs hook */
+	p_lm70->cdev = hwmon_device_register(&spi->dev);
+	if (IS_ERR(p_lm70->cdev)) {
+		dev_dbg(&spi->dev, "hwmon_device_register failed.\n");
+		status = PTR_ERR(p_lm70->cdev);
+		goto out_dev_reg_failed;
+	}
+	dev_set_drvdata(&spi->dev, p_lm70);
+
+	if ((status = device_create_file(&spi->dev, &dev_attr_temp1_input))) {
+		dev_dbg(&spi->dev, "device_create_file failure.\n");
+		goto out_dev_create_file_failed;
+	}
+
+	return 0;
+
+out_dev_create_file_failed:
+	hwmon_device_unregister(p_lm70->cdev);
+out_dev_reg_failed:
+	dev_set_drvdata(&spi->dev, NULL);
+	kfree(p_lm70);
+	return status;
+}
+
+static int __exit lm70_remove(struct spi_device *spi)
+{
+	struct lm70 *p_lm70 = dev_get_drvdata(&spi->dev);
+
+	device_remove_file(&spi->dev, &dev_attr_temp1_input);
+	hwmon_device_unregister(p_lm70->cdev);
+	dev_set_drvdata(&spi->dev, NULL);
+	kfree(p_lm70);
+
+	return 0;
+}
+
+static struct spi_driver lm70_driver = {
+	.driver = {
+		.name	= "lm70",
+		.owner	= THIS_MODULE,
+	},
+	.probe	= lm70_probe,
+	.remove	= __devexit_p(lm70_remove),
+};
+
+static int __init init_lm70(void)
+{
+	return spi_register_driver(&lm70_driver);
+}
+
+static void __exit cleanup_lm70(void)
+{
+	spi_unregister_driver(&lm70_driver);
+}
+
+module_init(init_lm70);
+module_exit(cleanup_lm70);
+
+MODULE_AUTHOR("Kaiwan N Billimoria");
+MODULE_DESCRIPTION("National Semiconductor LM70 Linux driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/hwmon/smsc47m192.c b/drivers/hwmon/smsc47m192.c
new file mode 100644
index 000000000..bdc4570ac
--- /dev/null
+++ b/drivers/hwmon/smsc47m192.c
@@ -0,0 +1,648 @@
+/*
+    smsc47m192.c - Support for hardware monitoring block of
+                   SMSC LPC47M192 and LPC47M997 Super I/O chips
+
+    Copyright (C) 2006  Hartmut Rick <linux@rick.claranet.de>
+
+    Derived from lm78.c and other chip drivers.
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/jiffies.h>
+#include <linux/i2c.h>
+#include <linux/hwmon.h>
+#include <linux/hwmon-sysfs.h>
+#include <linux/hwmon-vid.h>
+#include <linux/err.h>
+
+/* Addresses to scan */
+static unsigned short normal_i2c[] = { 0x2c, 0x2d, I2C_CLIENT_END };
+
+/* Insmod parameters */
+I2C_CLIENT_INSMOD_1(smsc47m192);
+
+/* SMSC47M192 registers */
+#define SMSC47M192_REG_IN(nr)		((nr)<6 ? (0x20 + (nr)) : \
+					(0x50 + (nr) - 6))
+#define SMSC47M192_REG_IN_MAX(nr)	((nr)<6 ? (0x2b + (nr) * 2) : \
+					(0x54 + (((nr) - 6) * 2)))
+#define SMSC47M192_REG_IN_MIN(nr)	((nr)<6 ? (0x2c + (nr) * 2) : \
+					(0x55 + (((nr) - 6) * 2)))
+static u8 SMSC47M192_REG_TEMP[3] =	{ 0x27, 0x26, 0x52 };
+static u8 SMSC47M192_REG_TEMP_MAX[3] =	{ 0x39, 0x37, 0x58 };
+static u8 SMSC47M192_REG_TEMP_MIN[3] =	{ 0x3A, 0x38, 0x59 };
+#define SMSC47M192_REG_TEMP_OFFSET(nr)	((nr)==2 ? 0x1e : 0x1f)
+#define SMSC47M192_REG_ALARM1		0x41
+#define SMSC47M192_REG_ALARM2		0x42
+#define SMSC47M192_REG_VID		0x47
+#define SMSC47M192_REG_VID4		0x49
+#define SMSC47M192_REG_CONFIG		0x40
+#define SMSC47M192_REG_SFR		0x4f
+#define SMSC47M192_REG_COMPANY_ID	0x3e
+#define SMSC47M192_REG_VERSION		0x3f
+
+/* generalised scaling with integer rounding */
+static inline int SCALE(long val, int mul, int div)
+{
+	if (val < 0)
+		return (val * mul - div / 2) / div;
+	else
+		return (val * mul + div / 2) / div;
+}
+
+/* Conversions */
+
+/* smsc47m192 internally scales voltage measurements */
+static const u16 nom_mv[] = { 2500, 2250, 3300, 5000, 12000, 3300, 1500, 1800 };
+
+static inline unsigned int IN_FROM_REG(u8 reg, int n)
+{
+	return SCALE(reg, nom_mv[n], 192);
+}
+
+static inline u8 IN_TO_REG(unsigned long val, int n)
+{
+	return SENSORS_LIMIT(SCALE(val, 192, nom_mv[n]), 0, 255);
+}
+
+/* TEMP: 0.001 degC units (-128C to +127C)
+   REG: 1C/bit, two's complement */
+static inline s8 TEMP_TO_REG(int val)
+{
+	return SENSORS_LIMIT(SCALE(val, 1, 1000), -128000, 127000);
+}
+
+static inline int TEMP_FROM_REG(s8 val)
+{
+	return val * 1000;
+}
+
+struct smsc47m192_data {
+	struct i2c_client client;
+	struct class_device *class_dev;
+	struct semaphore update_lock;
+	char valid;		/* !=0 if following fields are valid */
+	unsigned long last_updated;	/* In jiffies */
+
+	u8 in[8];		/* Register value */
+	u8 in_max[8];		/* Register value */
+	u8 in_min[8];		/* Register value */
+	s8 temp[3];		/* Register value */
+	s8 temp_max[3];		/* Register value */
+	s8 temp_min[3];		/* Register value */
+	s8 temp_offset[3];	/* Register value */
+	u16 alarms;		/* Register encoding, combined */
+	u8 vid;			/* Register encoding, combined */
+	u8 vrm;
+};
+
+static int smsc47m192_attach_adapter(struct i2c_adapter *adapter);
+static int smsc47m192_detect(struct i2c_adapter *adapter, int address,
+		int kind);
+static int smsc47m192_detach_client(struct i2c_client *client);
+static struct smsc47m192_data *smsc47m192_update_device(struct device *dev);
+
+static struct i2c_driver smsc47m192_driver = {
+	.driver = {
+		.name	= "smsc47m192",
+	},
+	.attach_adapter	= smsc47m192_attach_adapter,
+	.detach_client	= smsc47m192_detach_client,
+};
+
+/* Voltages */
+static ssize_t show_in(struct device *dev, struct device_attribute *attr,
+		char *buf)
+{
+	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
+	int nr = sensor_attr->index;
+	struct smsc47m192_data *data = smsc47m192_update_device(dev);
+	return sprintf(buf, "%d\n", IN_FROM_REG(data->in[nr], nr));
+}
+
+static ssize_t show_in_min(struct device *dev, struct device_attribute *attr,
+		char *buf)
+{
+	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
+	int nr = sensor_attr->index;
+	struct smsc47m192_data *data = smsc47m192_update_device(dev);
+	return sprintf(buf, "%d\n", IN_FROM_REG(data->in_min[nr], nr));
+}
+
+static ssize_t show_in_max(struct device *dev, struct device_attribute *attr,
+		char *buf)
+{
+	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
+	int nr = sensor_attr->index;
+	struct smsc47m192_data *data = smsc47m192_update_device(dev);
+	return sprintf(buf, "%d\n", IN_FROM_REG(data->in_max[nr], nr));
+}
+
+static ssize_t set_in_min(struct device *dev, struct device_attribute *attr,
+		const char *buf, size_t count)
+{
+	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
+	int nr = sensor_attr->index;
+	struct i2c_client *client = to_i2c_client(dev);
+	struct smsc47m192_data *data = i2c_get_clientdata(client);
+	unsigned long val = simple_strtoul(buf, NULL, 10);
+
+	down(&data->update_lock);
+	data->in_min[nr] = IN_TO_REG(val, nr);
+	i2c_smbus_write_byte_data(client, SMSC47M192_REG_IN_MIN(nr),
+							data->in_min[nr]);
+	up(&data->update_lock);
+	return count;
+}
+
+static ssize_t set_in_max(struct device *dev, struct device_attribute *attr,
+		const char *buf, size_t count)
+{
+	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
+	int nr = sensor_attr->index;
+	struct i2c_client *client = to_i2c_client(dev);
+	struct smsc47m192_data *data = i2c_get_clientdata(client);
+	unsigned long val = simple_strtoul(buf, NULL, 10);
+
+	down(&data->update_lock);
+	data->in_max[nr] = IN_TO_REG(val, nr);
+	i2c_smbus_write_byte_data(client, SMSC47M192_REG_IN_MAX(nr),
+							data->in_max[nr]);
+	up(&data->update_lock);
+	return count;
+}
+
+#define show_in_offset(offset)					\
+static SENSOR_DEVICE_ATTR(in##offset##_input, S_IRUGO,		\
+		show_in, NULL, offset);				\
+static SENSOR_DEVICE_ATTR(in##offset##_min, S_IRUGO | S_IWUSR,	\
+		show_in_min, set_in_min, offset);		\
+static SENSOR_DEVICE_ATTR(in##offset##_max, S_IRUGO | S_IWUSR,	\
+		show_in_max, set_in_max, offset);
+
+show_in_offset(0)
+show_in_offset(1)
+show_in_offset(2)
+show_in_offset(3)
+show_in_offset(4)
+show_in_offset(5)
+show_in_offset(6)
+show_in_offset(7)
+
+/* Temperatures */
+static ssize_t show_temp(struct device *dev, struct device_attribute *attr,
+		char *buf)
+{
+	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
+	int nr = sensor_attr->index;
+	struct smsc47m192_data *data = smsc47m192_update_device(dev);
+	return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp[nr]));
+}
+
+static ssize_t show_temp_min(struct device *dev, struct device_attribute *attr,
+		char *buf)
+{
+	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
+	int nr = sensor_attr->index;
+	struct smsc47m192_data *data = smsc47m192_update_device(dev);
+	return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_min[nr]));
+}
+
+static ssize_t show_temp_max(struct device *dev, struct device_attribute *attr,
+		char *buf)
+{
+	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
+	int nr = sensor_attr->index;
+	struct smsc47m192_data *data = smsc47m192_update_device(dev);
+	return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_max[nr]));
+}
+
+static ssize_t set_temp_min(struct device *dev, struct device_attribute *attr,
+		const char *buf, size_t count)
+{
+	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
+	int nr = sensor_attr->index;
+	struct i2c_client *client = to_i2c_client(dev);
+	struct smsc47m192_data *data = i2c_get_clientdata(client);
+	long val = simple_strtol(buf, NULL, 10);
+
+	down(&data->update_lock);
+	data->temp_min[nr] = TEMP_TO_REG(val);
+	i2c_smbus_write_byte_data(client, SMSC47M192_REG_TEMP_MIN[nr],
+						data->temp_min[nr]);
+	up(&data->update_lock);
+	return count;
+}
+
+static ssize_t set_temp_max(struct device *dev, struct device_attribute *attr,
+		const char *buf, size_t count)
+{
+	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
+	int nr = sensor_attr->index;
+	struct i2c_client *client = to_i2c_client(dev);
+	struct smsc47m192_data *data = i2c_get_clientdata(client);
+	long val = simple_strtol(buf, NULL, 10);
+
+	down(&data->update_lock);
+	data->temp_max[nr] = TEMP_TO_REG(val);
+	i2c_smbus_write_byte_data(client, SMSC47M192_REG_TEMP_MAX[nr],
+						data->temp_max[nr]);
+	up(&data->update_lock);
+	return count;
+}
+
+static ssize_t show_temp_offset(struct device *dev, struct device_attribute
+		*attr, char *buf)
+{
+	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
+	int nr = sensor_attr->index;
+	struct smsc47m192_data *data = smsc47m192_update_device(dev);
+	return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_offset[nr]));
+}
+
+static ssize_t set_temp_offset(struct device *dev, struct device_attribute
+		*attr, const char *buf, size_t count)
+{
+	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
+	int nr = sensor_attr->index;
+	struct i2c_client *client = to_i2c_client(dev);
+	struct smsc47m192_data *data = i2c_get_clientdata(client);
+	u8 sfr = i2c_smbus_read_byte_data(client, SMSC47M192_REG_SFR);
+	long val = simple_strtol(buf, NULL, 10);
+
+	down(&data->update_lock);
+	data->temp_offset[nr] = TEMP_TO_REG(val);
+	if (nr>1)
+		i2c_smbus_write_byte_data(client,
+			SMSC47M192_REG_TEMP_OFFSET(nr), data->temp_offset[nr]);
+	else if (data->temp_offset[nr] != 0) {
+		/* offset[0] and offset[1] share the same register,
+			SFR bit 4 activates offset[0] */
+		i2c_smbus_write_byte_data(client, SMSC47M192_REG_SFR,
+					(sfr & 0xef) | (nr==0 ? 0x10 : 0));
+		data->temp_offset[1-nr] = 0;
+		i2c_smbus_write_byte_data(client,
+			SMSC47M192_REG_TEMP_OFFSET(nr), data->temp_offset[nr]);
+	} else if ((sfr & 0x10) == (nr==0 ? 0x10 : 0))
+		i2c_smbus_write_byte_data(client,
+					SMSC47M192_REG_TEMP_OFFSET(nr), 0);
+	up(&data->update_lock);
+	return count;
+}
+
+#define show_temp_index(index)						\
+static SENSOR_DEVICE_ATTR(temp##index##_input, S_IRUGO,			\
+		show_temp, NULL, index-1);				\
+static SENSOR_DEVICE_ATTR(temp##index##_min, S_IRUGO | S_IWUSR,		\
+		show_temp_min, set_temp_min, index-1);			\
+static SENSOR_DEVICE_ATTR(temp##index##_max, S_IRUGO | S_IWUSR,		\
+		show_temp_max, set_temp_max, index-1);			\
+static SENSOR_DEVICE_ATTR(temp##index##_offset, S_IRUGO | S_IWUSR,	\
+		show_temp_offset, set_temp_offset, index-1);
+
+show_temp_index(1)
+show_temp_index(2)
+show_temp_index(3)
+
+/* VID */
+static ssize_t show_vid(struct device *dev, struct device_attribute *attr,
+		char *buf)
+{
+	struct smsc47m192_data *data = smsc47m192_update_device(dev);
+	return sprintf(buf, "%d\n", vid_from_reg(data->vid, data->vrm));
+}
+static DEVICE_ATTR(cpu0_vid, S_IRUGO, show_vid, NULL);
+
+static ssize_t show_vrm(struct device *dev, struct device_attribute *attr,
+		char *buf)
+{
+	struct smsc47m192_data *data = smsc47m192_update_device(dev);
+	return sprintf(buf, "%d\n", data->vrm);
+}
+
+static ssize_t set_vrm(struct device *dev, struct device_attribute *attr,
+		const char *buf, size_t count)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct smsc47m192_data *data = i2c_get_clientdata(client);
+	data->vrm = simple_strtoul(buf, NULL, 10);
+	return count;
+}
+static DEVICE_ATTR(vrm, S_IRUGO | S_IWUSR, show_vrm, set_vrm);
+
+/* Alarms */
+static ssize_t show_alarm(struct device *dev, struct device_attribute *attr,
+		char *buf)
+{
+	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
+	int nr = sensor_attr->index;
+	struct smsc47m192_data *data = smsc47m192_update_device(dev);
+	return sprintf(buf, "%u\n", (data->alarms & nr) ? 1 : 0);
+}
+
+static SENSOR_DEVICE_ATTR(temp1_alarm, S_IRUGO, show_alarm, NULL, 0x0010);
+static SENSOR_DEVICE_ATTR(temp2_alarm, S_IRUGO, show_alarm, NULL, 0x0020);
+static SENSOR_DEVICE_ATTR(temp3_alarm, S_IRUGO, show_alarm, NULL, 0x0040);
+static SENSOR_DEVICE_ATTR(temp2_input_fault, S_IRUGO, show_alarm, NULL, 0x4000);
+static SENSOR_DEVICE_ATTR(temp3_input_fault, S_IRUGO, show_alarm, NULL, 0x8000);
+static SENSOR_DEVICE_ATTR(in0_alarm, S_IRUGO, show_alarm, NULL, 0x0001);
+static SENSOR_DEVICE_ATTR(in1_alarm, S_IRUGO, show_alarm, NULL, 0x0002);
+static SENSOR_DEVICE_ATTR(in2_alarm, S_IRUGO, show_alarm, NULL, 0x0004);
+static SENSOR_DEVICE_ATTR(in3_alarm, S_IRUGO, show_alarm, NULL, 0x0008);
+static SENSOR_DEVICE_ATTR(in4_alarm, S_IRUGO, show_alarm, NULL, 0x0100);
+static SENSOR_DEVICE_ATTR(in5_alarm, S_IRUGO, show_alarm, NULL, 0x0200);
+static SENSOR_DEVICE_ATTR(in6_alarm, S_IRUGO, show_alarm, NULL, 0x0400);
+static SENSOR_DEVICE_ATTR(in7_alarm, S_IRUGO, show_alarm, NULL, 0x0800);
+
+/* This function is called when:
+    * smsc47m192_driver is inserted (when this module is loaded), for each
+      available adapter
+    * when a new adapter is inserted (and smsc47m192_driver is still present) */
+static int smsc47m192_attach_adapter(struct i2c_adapter *adapter)
+{
+	if (!(adapter->class & I2C_CLASS_HWMON))
+		return 0;
+	return i2c_probe(adapter, &addr_data, smsc47m192_detect);
+}
+
+static void smsc47m192_init_client(struct i2c_client *client)
+{
+	int i;
+	u8 config = i2c_smbus_read_byte_data(client, SMSC47M192_REG_CONFIG);
+	u8 sfr = i2c_smbus_read_byte_data(client, SMSC47M192_REG_SFR);
+
+	/* select cycle mode (pause 1 sec between updates) */
+	i2c_smbus_write_byte_data(client, SMSC47M192_REG_SFR,
+						(sfr & 0xfd) | 0x02);
+	if (!(config & 0x01)) {
+		/* initialize alarm limits */
+		for (i=0; i<8; i++) {
+			i2c_smbus_write_byte_data(client,
+				SMSC47M192_REG_IN_MIN(i), 0);
+			i2c_smbus_write_byte_data(client,
+				SMSC47M192_REG_IN_MAX(i), 0xff);
+		}
+		for (i=0; i<3; i++) {
+			i2c_smbus_write_byte_data(client,
+				SMSC47M192_REG_TEMP_MIN[i], 0x80);
+			i2c_smbus_write_byte_data(client,
+				SMSC47M192_REG_TEMP_MAX[i], 0x7f);
+		}
+
+		/* start monitoring */
+		i2c_smbus_write_byte_data(client, SMSC47M192_REG_CONFIG,
+						(config & 0xf7) | 0x01);
+	}
+}
+
+/* This function is called by i2c_probe */
+static int smsc47m192_detect(struct i2c_adapter *adapter, int address,
+		int kind)
+{
+	struct i2c_client *client;
+	struct smsc47m192_data *data;
+	int err = 0;
+	int version, config;
+
+	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
+		goto exit;
+
+	if (!(data = kzalloc(sizeof(struct smsc47m192_data), GFP_KERNEL))) {
+		err = -ENOMEM;
+		goto exit;
+	}
+
+	client = &data->client;
+	i2c_set_clientdata(client, data);
+	client->addr = address;
+	client->adapter = adapter;
+	client->driver = &smsc47m192_driver;
+
+	if (kind == 0)
+		kind = smsc47m192;
+
+	/* Detection criteria from sensors_detect script */
+	if (kind < 0) {
+		if (i2c_smbus_read_byte_data(client,
+				SMSC47M192_REG_COMPANY_ID) == 0x55
+		 && ((version = i2c_smbus_read_byte_data(client,
+				SMSC47M192_REG_VERSION)) & 0xf0) == 0x20
+		 && (i2c_smbus_read_byte_data(client,
+				SMSC47M192_REG_VID) & 0x70) == 0x00
+		 && (i2c_smbus_read_byte_data(client,
+				SMSC47M192_REG_VID4) & 0xfe) == 0x80) {
+			dev_info(&adapter->dev,
+				 "found SMSC47M192 or SMSC47M997, "
+				 "version 2, stepping A%d\n", version & 0x0f);
+		} else {
+			dev_dbg(&adapter->dev,
+				"SMSC47M192 detection failed at 0x%02x\n",
+				address);
+			goto exit_free;
+		}
+	}
+
+	/* Fill in the remaining client fields and put into the global list */
+	strlcpy(client->name, "smsc47m192", I2C_NAME_SIZE);
+	data->vrm = vid_which_vrm();
+	init_MUTEX(&data->update_lock);
+
+	/* Tell the I2C layer a new client has arrived */
+	if ((err = i2c_attach_client(client)))
+		goto exit_free;
+
+	/* Initialize the SMSC47M192 chip */
+	smsc47m192_init_client(client);
+
+	/* Register sysfs hooks */
+	data->class_dev = hwmon_device_register(&client->dev);
+	if (IS_ERR(data->class_dev)) {
+		err = PTR_ERR(data->class_dev);
+		goto exit_detach;
+	}
+
+	device_create_file(&client->dev, &sensor_dev_attr_in0_input.dev_attr);
+	device_create_file(&client->dev, &sensor_dev_attr_in0_min.dev_attr);
+	device_create_file(&client->dev, &sensor_dev_attr_in0_max.dev_attr);
+	device_create_file(&client->dev, &sensor_dev_attr_in0_alarm.dev_attr);
+	device_create_file(&client->dev, &sensor_dev_attr_in1_input.dev_attr);
+	device_create_file(&client->dev, &sensor_dev_attr_in1_min.dev_attr);
+	device_create_file(&client->dev, &sensor_dev_attr_in1_max.dev_attr);
+	device_create_file(&client->dev, &sensor_dev_attr_in1_alarm.dev_attr);
+	device_create_file(&client->dev, &sensor_dev_attr_in2_input.dev_attr);
+	device_create_file(&client->dev, &sensor_dev_attr_in2_min.dev_attr);
+	device_create_file(&client->dev, &sensor_dev_attr_in2_max.dev_attr);
+	device_create_file(&client->dev, &sensor_dev_attr_in2_alarm.dev_attr);
+	device_create_file(&client->dev, &sensor_dev_attr_in3_input.dev_attr);
+	device_create_file(&client->dev, &sensor_dev_attr_in3_min.dev_attr);
+	device_create_file(&client->dev, &sensor_dev_attr_in3_max.dev_attr);
+	device_create_file(&client->dev, &sensor_dev_attr_in3_alarm.dev_attr);
+
+	/* Pin 110 is either in4 (+12V) or VID4 */
+	config = i2c_smbus_read_byte_data(client, SMSC47M192_REG_CONFIG);
+	if (!(config & 0x20)) {
+		device_create_file(&client->dev,
+				   &sensor_dev_attr_in4_input.dev_attr);
+		device_create_file(&client->dev,
+				   &sensor_dev_attr_in4_min.dev_attr);
+		device_create_file(&client->dev,
+				   &sensor_dev_attr_in4_max.dev_attr);
+		device_create_file(&client->dev,
+				   &sensor_dev_attr_in4_alarm.dev_attr);
+	}
+	device_create_file(&client->dev, &sensor_dev_attr_in5_input.dev_attr);
+	device_create_file(&client->dev, &sensor_dev_attr_in5_min.dev_attr);
+	device_create_file(&client->dev, &sensor_dev_attr_in5_max.dev_attr);
+	device_create_file(&client->dev, &sensor_dev_attr_in5_alarm.dev_attr);
+	device_create_file(&client->dev, &sensor_dev_attr_in6_input.dev_attr);
+	device_create_file(&client->dev, &sensor_dev_attr_in6_min.dev_attr);
+	device_create_file(&client->dev, &sensor_dev_attr_in6_max.dev_attr);
+	device_create_file(&client->dev, &sensor_dev_attr_in6_alarm.dev_attr);
+	device_create_file(&client->dev, &sensor_dev_attr_in7_input.dev_attr);
+	device_create_file(&client->dev, &sensor_dev_attr_in7_min.dev_attr);
+	device_create_file(&client->dev, &sensor_dev_attr_in7_max.dev_attr);
+	device_create_file(&client->dev, &sensor_dev_attr_in7_alarm.dev_attr);
+	device_create_file(&client->dev, &sensor_dev_attr_temp1_input.dev_attr);
+	device_create_file(&client->dev, &sensor_dev_attr_temp1_max.dev_attr);
+	device_create_file(&client->dev, &sensor_dev_attr_temp1_min.dev_attr);
+	device_create_file(&client->dev,
+			   &sensor_dev_attr_temp1_offset.dev_attr);
+	device_create_file(&client->dev, &sensor_dev_attr_temp1_alarm.dev_attr);
+	device_create_file(&client->dev, &sensor_dev_attr_temp2_input.dev_attr);
+	device_create_file(&client->dev, &sensor_dev_attr_temp2_max.dev_attr);
+	device_create_file(&client->dev, &sensor_dev_attr_temp2_min.dev_attr);
+	device_create_file(&client->dev,
+			   &sensor_dev_attr_temp2_offset.dev_attr);
+	device_create_file(&client->dev, &sensor_dev_attr_temp2_alarm.dev_attr);
+	device_create_file(&client->dev,
+			   &sensor_dev_attr_temp2_input_fault.dev_attr);
+	device_create_file(&client->dev, &sensor_dev_attr_temp3_input.dev_attr);
+	device_create_file(&client->dev, &sensor_dev_attr_temp3_max.dev_attr);
+	device_create_file(&client->dev, &sensor_dev_attr_temp3_min.dev_attr);
+	device_create_file(&client->dev,
+			   &sensor_dev_attr_temp3_offset.dev_attr);
+	device_create_file(&client->dev, &sensor_dev_attr_temp3_alarm.dev_attr);
+	device_create_file(&client->dev,
+			   &sensor_dev_attr_temp3_input_fault.dev_attr);
+	device_create_file(&client->dev, &dev_attr_cpu0_vid);
+	device_create_file(&client->dev, &dev_attr_vrm);
+
+	return 0;
+
+exit_detach:
+	i2c_detach_client(client);
+exit_free:
+	kfree(data);
+exit:
+	return err;
+}
+
+static int smsc47m192_detach_client(struct i2c_client *client)
+{
+	struct smsc47m192_data *data = i2c_get_clientdata(client);
+	int err;
+
+	hwmon_device_unregister(data->class_dev);
+
+	if ((err = i2c_detach_client(client)))
+		return err;
+
+	kfree(data);
+
+	return 0;
+}
+
+static struct smsc47m192_data *smsc47m192_update_device(struct device *dev)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct smsc47m192_data *data = i2c_get_clientdata(client);
+	int i, config;
+
+	down(&data->update_lock);
+
+	if (time_after(jiffies, data->last_updated + HZ + HZ / 2)
+	 || !data->valid) {
+		u8 sfr = i2c_smbus_read_byte_data(client, SMSC47M192_REG_SFR);
+
+		dev_dbg(&client->dev, "Starting smsc47m192 update\n");
+
+		for (i = 0; i <= 7; i++) {
+			data->in[i] = i2c_smbus_read_byte_data(client,
+						SMSC47M192_REG_IN(i));
+			data->in_min[i] = i2c_smbus_read_byte_data(client,
+						SMSC47M192_REG_IN_MIN(i));
+			data->in_max[i] = i2c_smbus_read_byte_data(client,
+						SMSC47M192_REG_IN_MAX(i));
+		}
+		for (i = 0; i < 3; i++) {
+			data->temp[i] = i2c_smbus_read_byte_data(client,
+						SMSC47M192_REG_TEMP[i]);
+			data->temp_max[i] = i2c_smbus_read_byte_data(client,
+						SMSC47M192_REG_TEMP_MAX[i]);
+			data->temp_min[i] = i2c_smbus_read_byte_data(client,
+						SMSC47M192_REG_TEMP_MIN[i]);
+		}
+		for (i = 1; i < 3; i++)
+			data->temp_offset[i] = i2c_smbus_read_byte_data(client,
+						SMSC47M192_REG_TEMP_OFFSET(i));
+		/* first offset is temp_offset[0] if SFR bit 4 is set,
+					temp_offset[1] otherwise */
+		if (sfr & 0x10) {
+			data->temp_offset[0] = data->temp_offset[1];
+			data->temp_offset[1] = 0;
+		} else
+			data->temp_offset[0] = 0;
+
+		data->vid = i2c_smbus_read_byte_data(client, SMSC47M192_REG_VID)
+			    & 0x0f;
+		config = i2c_smbus_read_byte_data(client,
+						  SMSC47M192_REG_CONFIG);
+		if (config & 0x20)
+			data->vid |= (i2c_smbus_read_byte_data(client,
+					SMSC47M192_REG_VID4) & 0x01) << 4;
+		data->alarms = i2c_smbus_read_byte_data(client,
+						SMSC47M192_REG_ALARM1) |
+			       (i2c_smbus_read_byte_data(client,
+		       				SMSC47M192_REG_ALARM2) << 8);
+
+		data->last_updated = jiffies;
+		data->valid = 1;
+	}
+
+	up(&data->update_lock);
+
+	return data;
+}
+
+static int __init smsc47m192_init(void)
+{
+	return i2c_add_driver(&smsc47m192_driver);
+}
+
+static void __exit smsc47m192_exit(void)
+{
+	i2c_del_driver(&smsc47m192_driver);
+}
+
+MODULE_AUTHOR("Hartmut Rick <linux@rick.claranet.de>");
+MODULE_DESCRIPTION("SMSC47M192 driver");
+MODULE_LICENSE("GPL");
+
+module_init(smsc47m192_init);
+module_exit(smsc47m192_exit);
diff --git a/drivers/hwmon/w83791d.c b/drivers/hwmon/w83791d.c
new file mode 100644
index 000000000..87f7312cc
--- /dev/null
+++ b/drivers/hwmon/w83791d.c
@@ -0,0 +1,1254 @@
+/*
+    w83791d.c - Part of lm_sensors, Linux kernel modules for hardware
+                monitoring
+
+    Copyright (C) 2006 Charles Spirakis <bezaur@gmail.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., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+/*
+    Supports following chips:
+
+    Chip	#vin	#fanin	#pwm	#temp	wchipid	vendid	i2c	ISA
+    w83791d	10	5	3	3	0x71	0x5ca3	yes	no
+
+    The w83791d chip appears to be part way between the 83781d and the
+    83792d. Thus, this file is derived from both the w83792d.c and
+    w83781d.c files, but its output is more along the lines of the
+    83781d (which means there are no changes to the user-mode sensors
+    program which treats the 83791d as an 83781d).
+*/
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/i2c.h>
+#include <linux/hwmon.h>
+#include <linux/hwmon-vid.h>
+#include <linux/hwmon-sysfs.h>
+#include <linux/err.h>
+#include <linux/mutex.h>
+
+#define NUMBER_OF_VIN		10
+#define NUMBER_OF_FANIN		5
+#define NUMBER_OF_TEMPIN	3
+
+/* Addresses to scan */
+static unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, 0x2f, I2C_CLIENT_END };
+
+/* Insmod parameters */
+I2C_CLIENT_INSMOD_1(w83791d);
+I2C_CLIENT_MODULE_PARM(force_subclients, "List of subclient addresses: "
+			"{bus, clientaddr, subclientaddr1, subclientaddr2}");
+
+static int reset;
+module_param(reset, bool, 0);
+MODULE_PARM_DESC(reset, "Set to one to force a hardware chip reset");
+
+static int init;
+module_param(init, bool, 0);
+MODULE_PARM_DESC(init, "Set to one to force extra software initialization");
+
+/* The W83791D registers */
+static const u8 W83791D_REG_IN[NUMBER_OF_VIN] = {
+	0x20,			/* VCOREA in DataSheet */
+	0x21,			/* VINR0 in DataSheet */
+	0x22,			/* +3.3VIN in DataSheet */
+	0x23,			/* VDD5V in DataSheet */
+	0x24,			/* +12VIN in DataSheet */
+	0x25,			/* -12VIN in DataSheet */
+	0x26,			/* -5VIN in DataSheet */
+	0xB0,			/* 5VSB in DataSheet */
+	0xB1,			/* VBAT in DataSheet */
+	0xB2			/* VINR1 in DataSheet */
+};
+
+static const u8 W83791D_REG_IN_MAX[NUMBER_OF_VIN] = {
+	0x2B,			/* VCOREA High Limit in DataSheet */
+	0x2D,			/* VINR0 High Limit in DataSheet */
+	0x2F,			/* +3.3VIN High Limit in DataSheet */
+	0x31,			/* VDD5V High Limit in DataSheet */
+	0x33,			/* +12VIN High Limit in DataSheet */
+	0x35,			/* -12VIN High Limit in DataSheet */
+	0x37,			/* -5VIN High Limit in DataSheet */
+	0xB4,			/* 5VSB High Limit in DataSheet */
+	0xB6,			/* VBAT High Limit in DataSheet */
+	0xB8			/* VINR1 High Limit in DataSheet */
+};
+static const u8 W83791D_REG_IN_MIN[NUMBER_OF_VIN] = {
+	0x2C,			/* VCOREA Low Limit in DataSheet */
+	0x2E,			/* VINR0 Low Limit in DataSheet */
+	0x30,			/* +3.3VIN Low Limit in DataSheet */
+	0x32,			/* VDD5V Low Limit in DataSheet */
+	0x34,			/* +12VIN Low Limit in DataSheet */
+	0x36,			/* -12VIN Low Limit in DataSheet */
+	0x38,			/* -5VIN Low Limit in DataSheet */
+	0xB5,			/* 5VSB Low Limit in DataSheet */
+	0xB7,			/* VBAT Low Limit in DataSheet */
+	0xB9			/* VINR1 Low Limit in DataSheet */
+};
+static const u8 W83791D_REG_FAN[NUMBER_OF_FANIN] = {
+	0x28,			/* FAN 1 Count in DataSheet */
+	0x29,			/* FAN 2 Count in DataSheet */
+	0x2A,			/* FAN 3 Count in DataSheet */
+	0xBA,			/* FAN 4 Count in DataSheet */
+	0xBB,			/* FAN 5 Count in DataSheet */
+};
+static const u8 W83791D_REG_FAN_MIN[NUMBER_OF_FANIN] = {
+	0x3B,			/* FAN 1 Count Low Limit in DataSheet */
+	0x3C,			/* FAN 2 Count Low Limit in DataSheet */
+	0x3D,			/* FAN 3 Count Low Limit in DataSheet */
+	0xBC,			/* FAN 4 Count Low Limit in DataSheet */
+	0xBD,			/* FAN 5 Count Low Limit in DataSheet */
+};
+
+static const u8 W83791D_REG_FAN_CFG[2] = {
+	0x84,			/* FAN 1/2 configuration */
+	0x95,			/* FAN 3 configuration */
+};
+
+static const u8 W83791D_REG_FAN_DIV[3] = {
+	0x47,			/* contains FAN1 and FAN2 Divisor */
+	0x4b,			/* contains FAN3 Divisor */
+	0x5C,			/* contains FAN4 and FAN5 Divisor */
+};
+
+#define W83791D_REG_BANK		0x4E
+#define W83791D_REG_TEMP2_CONFIG	0xC2
+#define W83791D_REG_TEMP3_CONFIG	0xCA
+
+static const u8 W83791D_REG_TEMP1[3] = {
+	0x27,			/* TEMP 1 in DataSheet */
+	0x39,			/* TEMP 1 Over in DataSheet */
+	0x3A,			/* TEMP 1 Hyst in DataSheet */
+};
+
+static const u8 W83791D_REG_TEMP_ADD[2][6] = {
+	{0xC0,			/* TEMP 2 in DataSheet */
+	 0xC1,			/* TEMP 2(0.5 deg) in DataSheet */
+	 0xC5,			/* TEMP 2 Over High part in DataSheet */
+	 0xC6,			/* TEMP 2 Over Low part in DataSheet */
+	 0xC3,			/* TEMP 2 Thyst High part in DataSheet */
+	 0xC4},			/* TEMP 2 Thyst Low part in DataSheet */
+	{0xC8,			/* TEMP 3 in DataSheet */
+	 0xC9,			/* TEMP 3(0.5 deg) in DataSheet */
+	 0xCD,			/* TEMP 3 Over High part in DataSheet */
+	 0xCE,			/* TEMP 3 Over Low part in DataSheet */
+	 0xCB,			/* TEMP 3 Thyst High part in DataSheet */
+	 0xCC}			/* TEMP 3 Thyst Low part in DataSheet */
+};
+
+#define W83791D_REG_BEEP_CONFIG		0x4D
+
+static const u8 W83791D_REG_BEEP_CTRL[3] = {
+	0x56,			/* BEEP Control Register 1 */
+	0x57,			/* BEEP Control Register 2 */
+	0xA3,			/* BEEP Control Register 3 */
+};
+
+#define W83791D_REG_CONFIG		0x40
+#define W83791D_REG_VID_FANDIV		0x47
+#define W83791D_REG_DID_VID4		0x49
+#define W83791D_REG_WCHIPID		0x58
+#define W83791D_REG_CHIPMAN		0x4F
+#define W83791D_REG_PIN			0x4B
+#define W83791D_REG_I2C_SUBADDR		0x4A
+
+#define W83791D_REG_ALARM1 0xA9	/* realtime status register1 */
+#define W83791D_REG_ALARM2 0xAA	/* realtime status register2 */
+#define W83791D_REG_ALARM3 0xAB	/* realtime status register3 */
+
+#define W83791D_REG_VBAT		0x5D
+#define W83791D_REG_I2C_ADDR		0x48
+
+/* The SMBus locks itself. The Winbond W83791D has a bank select register
+   (index 0x4e), but the driver only accesses registers in bank 0. Since
+   we don't switch banks, we don't need any special code to handle
+   locking access between bank switches */
+static inline int w83791d_read(struct i2c_client *client, u8 reg)
+{
+	return i2c_smbus_read_byte_data(client, reg);
+}
+
+static inline int w83791d_write(struct i2c_client *client, u8 reg, u8 value)
+{
+	return i2c_smbus_write_byte_data(client, reg, value);
+}
+
+/* The analog voltage inputs have 16mV LSB. Since the sysfs output is
+   in mV as would be measured on the chip input pin, need to just
+   multiply/divide by 16 to translate from/to register values. */
+#define IN_TO_REG(val)		(SENSORS_LIMIT((((val) + 8) / 16), 0, 255))
+#define IN_FROM_REG(val)	((val) * 16)
+
+static u8 fan_to_reg(long rpm, int div)
+{
+	if (rpm == 0)
+		return 255;
+	rpm = SENSORS_LIMIT(rpm, 1, 1000000);
+	return SENSORS_LIMIT((1350000 + rpm * div / 2) / (rpm * div), 1, 254);
+}
+
+#define FAN_FROM_REG(val,div)	((val) == 0   ? -1 : \
+				((val) == 255 ? 0 : \
+					1350000 / ((val) * (div))))
+
+/* for temp1 which is 8-bit resolution, LSB = 1 degree Celsius */
+#define TEMP1_FROM_REG(val)	((val) * 1000)
+#define TEMP1_TO_REG(val)	((val) <= -128000 ? -128 : \
+				 (val) >= 127000 ? 127 : \
+				 (val) < 0 ? ((val) - 500) / 1000 : \
+				 ((val) + 500) / 1000)
+
+/* for temp2 and temp3 which are 9-bit resolution, LSB = 0.5 degree Celsius
+   Assumes the top 8 bits are the integral amount and the bottom 8 bits
+   are the fractional amount. Since we only have 0.5 degree resolution,
+   the bottom 7 bits will always be zero */
+#define TEMP23_FROM_REG(val)	((val) / 128 * 500)
+#define TEMP23_TO_REG(val)	((val) <= -128000 ? 0x8000 : \
+				 (val) >= 127500 ? 0x7F80 : \
+				 (val) < 0 ? ((val) - 250) / 500 * 128 : \
+				 ((val) + 250) / 500 * 128)
+
+
+#define BEEP_MASK_TO_REG(val)		((val) & 0xffffff)
+#define BEEP_MASK_FROM_REG(val)		((val) & 0xffffff)
+
+#define DIV_FROM_REG(val)		(1 << (val))
+
+static u8 div_to_reg(int nr, long val)
+{
+	int i;
+	int max;
+
+	/* first three fan's divisor max out at 8, rest max out at 128 */
+	max = (nr < 3) ? 8 : 128;
+	val = SENSORS_LIMIT(val, 1, max) >> 1;
+	for (i = 0; i < 7; i++) {
+		if (val == 0)
+			break;
+		val >>= 1;
+	}
+	return (u8) i;
+}
+
+struct w83791d_data {
+	struct i2c_client client;
+	struct class_device *class_dev;
+	struct mutex update_lock;
+
+	char valid;			/* !=0 if following fields are valid */
+	unsigned long last_updated;	/* In jiffies */
+
+	/* array of 2 pointers to subclients */
+	struct i2c_client *lm75[2];
+
+	/* volts */
+	u8 in[NUMBER_OF_VIN];		/* Register value */
+	u8 in_max[NUMBER_OF_VIN];	/* Register value */
+	u8 in_min[NUMBER_OF_VIN];	/* Register value */
+
+	/* fans */
+	u8 fan[NUMBER_OF_FANIN];	/* Register value */
+	u8 fan_min[NUMBER_OF_FANIN];	/* Register value */
+	u8 fan_div[NUMBER_OF_FANIN];	/* Register encoding, shifted right */
+
+	/* Temperature sensors */
+
+	s8 temp1[3];		/* current, over, thyst */
+	s16 temp_add[2][3];	/* fixed point value. Top 8 bits are the
+				   integral part, bottom 8 bits are the
+				   fractional part. We only use the top
+				   9 bits as the resolution is only
+				   to the 0.5 degree C...
+				   two sensors with three values
+				   (cur, over, hyst)  */
+
+	/* Misc */
+	u32 alarms;		/* realtime status register encoding,combined */
+	u8 beep_enable;		/* Global beep enable */
+	u32 beep_mask;		/* Mask off specific beeps */
+	u8 vid;			/* Register encoding, combined */
+	u8 vrm;			/* hwmon-vid */
+};
+
+static int w83791d_attach_adapter(struct i2c_adapter *adapter);
+static int w83791d_detect(struct i2c_adapter *adapter, int address, int kind);
+static int w83791d_detach_client(struct i2c_client *client);
+
+static int w83791d_read(struct i2c_client *client, u8 register);
+static int w83791d_write(struct i2c_client *client, u8 register, u8 value);
+static struct w83791d_data *w83791d_update_device(struct device *dev);
+
+#ifdef DEBUG
+static void w83791d_print_debug(struct w83791d_data *data, struct device *dev);
+#endif
+
+static void w83791d_init_client(struct i2c_client *client);
+
+static struct i2c_driver w83791d_driver = {
+	.driver = {
+		.name = "w83791d",
+	},
+	.attach_adapter = w83791d_attach_adapter,
+	.detach_client = w83791d_detach_client,
+};
+
+/* following are the sysfs callback functions */
+#define show_in_reg(reg) \
+static ssize_t show_##reg(struct device *dev, struct device_attribute *attr, \
+			char *buf) \
+{ \
+	struct sensor_device_attribute *sensor_attr = \
+						to_sensor_dev_attr(attr); \
+	struct w83791d_data *data = w83791d_update_device(dev); \
+	int nr = sensor_attr->index; \
+	return sprintf(buf,"%d\n", IN_FROM_REG(data->reg[nr])); \
+}
+
+show_in_reg(in);
+show_in_reg(in_min);
+show_in_reg(in_max);
+
+#define store_in_reg(REG, reg) \
+static ssize_t store_in_##reg(struct device *dev, \
+				struct device_attribute *attr, \
+				const char *buf, size_t count) \
+{ \
+	struct sensor_device_attribute *sensor_attr = \
+						to_sensor_dev_attr(attr); \
+	struct i2c_client *client = to_i2c_client(dev); \
+	struct w83791d_data *data = i2c_get_clientdata(client); \
+	unsigned long val = simple_strtoul(buf, NULL, 10); \
+	int nr = sensor_attr->index; \
+	 \
+	mutex_lock(&data->update_lock); \
+	data->in_##reg[nr] = IN_TO_REG(val); \
+	w83791d_write(client, W83791D_REG_IN_##REG[nr], data->in_##reg[nr]); \
+	mutex_unlock(&data->update_lock); \
+	 \
+	return count; \
+}
+store_in_reg(MIN, min);
+store_in_reg(MAX, max);
+
+static struct sensor_device_attribute sda_in_input[] = {
+	SENSOR_ATTR(in0_input, S_IRUGO, show_in, NULL, 0),
+	SENSOR_ATTR(in1_input, S_IRUGO, show_in, NULL, 1),
+	SENSOR_ATTR(in2_input, S_IRUGO, show_in, NULL, 2),
+	SENSOR_ATTR(in3_input, S_IRUGO, show_in, NULL, 3),
+	SENSOR_ATTR(in4_input, S_IRUGO, show_in, NULL, 4),
+	SENSOR_ATTR(in5_input, S_IRUGO, show_in, NULL, 5),
+	SENSOR_ATTR(in6_input, S_IRUGO, show_in, NULL, 6),
+	SENSOR_ATTR(in7_input, S_IRUGO, show_in, NULL, 7),
+	SENSOR_ATTR(in8_input, S_IRUGO, show_in, NULL, 8),
+	SENSOR_ATTR(in9_input, S_IRUGO, show_in, NULL, 9),
+};
+
+static struct sensor_device_attribute sda_in_min[] = {
+	SENSOR_ATTR(in0_min, S_IWUSR | S_IRUGO, show_in_min, store_in_min, 0),
+	SENSOR_ATTR(in1_min, S_IWUSR | S_IRUGO, show_in_min, store_in_min, 1),
+	SENSOR_ATTR(in2_min, S_IWUSR | S_IRUGO, show_in_min, store_in_min, 2),
+	SENSOR_ATTR(in3_min, S_IWUSR | S_IRUGO, show_in_min, store_in_min, 3),
+	SENSOR_ATTR(in4_min, S_IWUSR | S_IRUGO, show_in_min, store_in_min, 4),
+	SENSOR_ATTR(in5_min, S_IWUSR | S_IRUGO, show_in_min, store_in_min, 5),
+	SENSOR_ATTR(in6_min, S_IWUSR | S_IRUGO, show_in_min, store_in_min, 6),
+	SENSOR_ATTR(in7_min, S_IWUSR | S_IRUGO, show_in_min, store_in_min, 7),
+	SENSOR_ATTR(in8_min, S_IWUSR | S_IRUGO, show_in_min, store_in_min, 8),
+	SENSOR_ATTR(in9_min, S_IWUSR | S_IRUGO, show_in_min, store_in_min, 9),
+};
+
+static struct sensor_device_attribute sda_in_max[] = {
+	SENSOR_ATTR(in0_max, S_IWUSR | S_IRUGO, show_in_max, store_in_max, 0),
+	SENSOR_ATTR(in1_max, S_IWUSR | S_IRUGO, show_in_max, store_in_max, 1),
+	SENSOR_ATTR(in2_max, S_IWUSR | S_IRUGO, show_in_max, store_in_max, 2),
+	SENSOR_ATTR(in3_max, S_IWUSR | S_IRUGO, show_in_max, store_in_max, 3),
+	SENSOR_ATTR(in4_max, S_IWUSR | S_IRUGO, show_in_max, store_in_max, 4),
+	SENSOR_ATTR(in5_max, S_IWUSR | S_IRUGO, show_in_max, store_in_max, 5),
+	SENSOR_ATTR(in6_max, S_IWUSR | S_IRUGO, show_in_max, store_in_max, 6),
+	SENSOR_ATTR(in7_max, S_IWUSR | S_IRUGO, show_in_max, store_in_max, 7),
+	SENSOR_ATTR(in8_max, S_IWUSR | S_IRUGO, show_in_max, store_in_max, 8),
+	SENSOR_ATTR(in9_max, S_IWUSR | S_IRUGO, show_in_max, store_in_max, 9),
+};
+
+#define show_fan_reg(reg) \
+static ssize_t show_##reg(struct device *dev, struct device_attribute *attr, \
+				char *buf) \
+{ \
+	struct sensor_device_attribute *sensor_attr = \
+						to_sensor_dev_attr(attr); \
+	struct w83791d_data *data = w83791d_update_device(dev); \
+	int nr = sensor_attr->index; \
+	return sprintf(buf,"%d\n", \
+		FAN_FROM_REG(data->reg[nr], DIV_FROM_REG(data->fan_div[nr]))); \
+}
+
+show_fan_reg(fan);
+show_fan_reg(fan_min);
+
+static ssize_t store_fan_min(struct device *dev, struct device_attribute *attr,
+				const char *buf, size_t count)
+{
+	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
+	struct i2c_client *client = to_i2c_client(dev);
+	struct w83791d_data *data = i2c_get_clientdata(client);
+	unsigned long val = simple_strtoul(buf, NULL, 10);
+	int nr = sensor_attr->index;
+
+	mutex_lock(&data->update_lock);
+	data->fan_min[nr] = fan_to_reg(val, DIV_FROM_REG(data->fan_div[nr]));
+	w83791d_write(client, W83791D_REG_FAN_MIN[nr], data->fan_min[nr]);
+	mutex_unlock(&data->update_lock);
+
+	return count;
+}
+
+static ssize_t show_fan_div(struct device *dev, struct device_attribute *attr,
+				char *buf)
+{
+	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
+	int nr = sensor_attr->index;
+	struct w83791d_data *data = w83791d_update_device(dev);
+	return sprintf(buf, "%u\n", DIV_FROM_REG(data->fan_div[nr]));
+}
+
+/* Note: we save and restore the fan minimum here, because its value is
+   determined in part by the fan divisor.  This follows the principle of
+   least suprise; the user doesn't expect the fan minimum to change just
+   because the divisor changed. */
+static ssize_t store_fan_div(struct device *dev, struct device_attribute *attr,
+				const char *buf, size_t count)
+{
+	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
+	struct i2c_client *client = to_i2c_client(dev);
+	struct w83791d_data *data = i2c_get_clientdata(client);
+	int nr = sensor_attr->index;
+	unsigned long min;
+	u8 tmp_fan_div;
+	u8 fan_div_reg;
+	int indx = 0;
+	u8 keep_mask = 0;
+	u8 new_shift = 0;
+
+	/* Save fan_min */
+	min = FAN_FROM_REG(data->fan_min[nr], DIV_FROM_REG(data->fan_div[nr]));
+
+	mutex_lock(&data->update_lock);
+	data->fan_div[nr] = div_to_reg(nr, simple_strtoul(buf, NULL, 10));
+
+	switch (nr) {
+	case 0:
+		indx = 0;
+		keep_mask = 0xcf;
+		new_shift = 4;
+		break;
+	case 1:
+		indx = 0;
+		keep_mask = 0x3f;
+		new_shift = 6;
+		break;
+	case 2:
+		indx = 1;
+		keep_mask = 0x3f;
+		new_shift = 6;
+		break;
+	case 3:
+		indx = 2;
+		keep_mask = 0xf8;
+		new_shift = 0;
+		break;
+	case 4:
+		indx = 2;
+		keep_mask = 0x8f;
+		new_shift = 4;
+		break;
+#ifdef DEBUG
+	default:
+		dev_warn(dev, "store_fan_div: Unexpected nr seen: %d\n", nr);
+		count = -EINVAL;
+		goto err_exit;
+#endif
+	}
+
+	fan_div_reg = w83791d_read(client, W83791D_REG_FAN_DIV[indx])
+			& keep_mask;
+	tmp_fan_div = (data->fan_div[nr] << new_shift) & ~keep_mask;
+
+	w83791d_write(client, W83791D_REG_FAN_DIV[indx],
+				fan_div_reg | tmp_fan_div);
+
+	/* Restore fan_min */
+	data->fan_min[nr] = fan_to_reg(min, DIV_FROM_REG(data->fan_div[nr]));
+	w83791d_write(client, W83791D_REG_FAN_MIN[nr], data->fan_min[nr]);
+
+#ifdef DEBUG
+err_exit:
+#endif
+	mutex_unlock(&data->update_lock);
+
+	return count;
+}
+
+static struct sensor_device_attribute sda_fan_input[] = {
+	SENSOR_ATTR(fan1_input, S_IRUGO, show_fan, NULL, 0),
+	SENSOR_ATTR(fan2_input, S_IRUGO, show_fan, NULL, 1),
+	SENSOR_ATTR(fan3_input, S_IRUGO, show_fan, NULL, 2),
+	SENSOR_ATTR(fan4_input, S_IRUGO, show_fan, NULL, 3),
+	SENSOR_ATTR(fan5_input, S_IRUGO, show_fan, NULL, 4),
+};
+
+static struct sensor_device_attribute sda_fan_min[] = {
+	SENSOR_ATTR(fan1_min, S_IWUSR | S_IRUGO,
+			show_fan_min, store_fan_min, 0),
+	SENSOR_ATTR(fan2_min, S_IWUSR | S_IRUGO,
+			show_fan_min, store_fan_min, 1),
+	SENSOR_ATTR(fan3_min, S_IWUSR | S_IRUGO,
+			show_fan_min, store_fan_min, 2),
+	SENSOR_ATTR(fan4_min, S_IWUSR | S_IRUGO,
+			show_fan_min, store_fan_min, 3),
+	SENSOR_ATTR(fan5_min, S_IWUSR | S_IRUGO,
+			show_fan_min, store_fan_min, 4),
+};
+
+static struct sensor_device_attribute sda_fan_div[] = {
+	SENSOR_ATTR(fan1_div, S_IWUSR | S_IRUGO,
+			show_fan_div, store_fan_div, 0),
+	SENSOR_ATTR(fan2_div, S_IWUSR | S_IRUGO,
+			show_fan_div, store_fan_div, 1),
+	SENSOR_ATTR(fan3_div, S_IWUSR | S_IRUGO,
+			show_fan_div, store_fan_div, 2),
+	SENSOR_ATTR(fan4_div, S_IWUSR | S_IRUGO,
+			show_fan_div, store_fan_div, 3),
+	SENSOR_ATTR(fan5_div, S_IWUSR | S_IRUGO,
+			show_fan_div, store_fan_div, 4),
+};
+
+/* read/write the temperature1, includes measured value and limits */
+static ssize_t show_temp1(struct device *dev, struct device_attribute *devattr,
+				char *buf)
+{
+	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+	struct w83791d_data *data = w83791d_update_device(dev);
+	return sprintf(buf, "%d\n", TEMP1_FROM_REG(data->temp1[attr->index]));
+}
+
+static ssize_t store_temp1(struct device *dev, struct device_attribute *devattr,
+				const char *buf, size_t count)
+{
+	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+	struct i2c_client *client = to_i2c_client(dev);
+	struct w83791d_data *data = i2c_get_clientdata(client);
+	long val = simple_strtol(buf, NULL, 10);
+	int nr = attr->index;
+
+	mutex_lock(&data->update_lock);
+	data->temp1[nr] = TEMP1_TO_REG(val);
+	w83791d_write(client, W83791D_REG_TEMP1[nr], data->temp1[nr]);
+	mutex_unlock(&data->update_lock);
+	return count;
+}
+
+/* read/write temperature2-3, includes measured value and limits */
+static ssize_t show_temp23(struct device *dev, struct device_attribute *devattr,
+				char *buf)
+{
+	struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(devattr);
+	struct w83791d_data *data = w83791d_update_device(dev);
+	int nr = attr->nr;
+	int index = attr->index;
+	return sprintf(buf, "%d\n", TEMP23_FROM_REG(data->temp_add[nr][index]));
+}
+
+static ssize_t store_temp23(struct device *dev,
+				struct device_attribute *devattr,
+				const char *buf, size_t count)
+{
+	struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(devattr);
+	struct i2c_client *client = to_i2c_client(dev);
+	struct w83791d_data *data = i2c_get_clientdata(client);
+	long val = simple_strtol(buf, NULL, 10);
+	int nr = attr->nr;
+	int index = attr->index;
+
+	mutex_lock(&data->update_lock);
+	data->temp_add[nr][index] = TEMP23_TO_REG(val);
+	w83791d_write(client, W83791D_REG_TEMP_ADD[nr][index * 2],
+				data->temp_add[nr][index] >> 8);
+	w83791d_write(client, W83791D_REG_TEMP_ADD[nr][index * 2 + 1],
+				data->temp_add[nr][index] & 0x80);
+	mutex_unlock(&data->update_lock);
+
+	return count;
+}
+
+static struct sensor_device_attribute_2 sda_temp_input[] = {
+	SENSOR_ATTR_2(temp1_input, S_IRUGO, show_temp1, NULL, 0, 0),
+	SENSOR_ATTR_2(temp2_input, S_IRUGO, show_temp23, NULL, 0, 0),
+	SENSOR_ATTR_2(temp3_input, S_IRUGO, show_temp23, NULL, 1, 0),
+};
+
+static struct sensor_device_attribute_2 sda_temp_max[] = {
+	SENSOR_ATTR_2(temp1_max, S_IRUGO | S_IWUSR,
+			show_temp1, store_temp1, 0, 1),
+	SENSOR_ATTR_2(temp2_max, S_IRUGO | S_IWUSR,
+			show_temp23, store_temp23, 0, 1),
+	SENSOR_ATTR_2(temp3_max, S_IRUGO | S_IWUSR,
+			show_temp23, store_temp23, 1, 1),
+};
+
+static struct sensor_device_attribute_2 sda_temp_max_hyst[] = {
+	SENSOR_ATTR_2(temp1_max_hyst, S_IRUGO | S_IWUSR,
+			show_temp1, store_temp1, 0, 2),
+	SENSOR_ATTR_2(temp2_max_hyst, S_IRUGO | S_IWUSR,
+			show_temp23, store_temp23, 0, 2),
+	SENSOR_ATTR_2(temp3_max_hyst, S_IRUGO | S_IWUSR,
+			show_temp23, store_temp23, 1, 2),
+};
+
+
+/* get reatime status of all sensors items: voltage, temp, fan */
+static ssize_t show_alarms_reg(struct device *dev,
+				struct device_attribute *attr, char *buf)
+{
+	struct w83791d_data *data = w83791d_update_device(dev);
+	return sprintf(buf, "%u\n", data->alarms);
+}
+
+static DEVICE_ATTR(alarms, S_IRUGO, show_alarms_reg, NULL);
+
+/* Beep control */
+
+#define GLOBAL_BEEP_ENABLE_SHIFT	15
+#define GLOBAL_BEEP_ENABLE_MASK		(1 << GLOBAL_BEEP_ENABLE_SHIFT)
+
+static ssize_t show_beep_enable(struct device *dev,
+				struct device_attribute *attr, char *buf)
+{
+	struct w83791d_data *data = w83791d_update_device(dev);
+	return sprintf(buf, "%d\n", data->beep_enable);
+}
+
+static ssize_t show_beep_mask(struct device *dev,
+				struct device_attribute *attr, char *buf)
+{
+	struct w83791d_data *data = w83791d_update_device(dev);
+	return sprintf(buf, "%d\n", BEEP_MASK_FROM_REG(data->beep_mask));
+}
+
+
+static ssize_t store_beep_mask(struct device *dev,
+				struct device_attribute *attr,
+				const char *buf, size_t count)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct w83791d_data *data = i2c_get_clientdata(client);
+	long val = simple_strtol(buf, NULL, 10);
+	int i;
+
+	mutex_lock(&data->update_lock);
+
+	/* The beep_enable state overrides any enabling request from
+	   the masks */
+	data->beep_mask = BEEP_MASK_TO_REG(val) & ~GLOBAL_BEEP_ENABLE_MASK;
+	data->beep_mask |= (data->beep_enable << GLOBAL_BEEP_ENABLE_SHIFT);
+
+	val = data->beep_mask;
+
+	for (i = 0; i < 3; i++) {
+		w83791d_write(client, W83791D_REG_BEEP_CTRL[i], (val & 0xff));
+		val >>= 8;
+	}
+
+	mutex_unlock(&data->update_lock);
+
+	return count;
+}
+
+static ssize_t store_beep_enable(struct device *dev,
+				struct device_attribute *attr,
+				const char *buf, size_t count)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct w83791d_data *data = i2c_get_clientdata(client);
+	long val = simple_strtol(buf, NULL, 10);
+
+	mutex_lock(&data->update_lock);
+
+	data->beep_enable = val ? 1 : 0;
+
+	/* Keep the full mask value in sync with the current enable */
+	data->beep_mask &= ~GLOBAL_BEEP_ENABLE_MASK;
+	data->beep_mask |= (data->beep_enable << GLOBAL_BEEP_ENABLE_SHIFT);
+
+	/* The global control is in the second beep control register
+	   so only need to update that register */
+	val = (data->beep_mask >> 8) & 0xff;
+
+	w83791d_write(client, W83791D_REG_BEEP_CTRL[1], val);
+
+	mutex_unlock(&data->update_lock);
+
+	return count;
+}
+
+static struct sensor_device_attribute sda_beep_ctrl[] = {
+	SENSOR_ATTR(beep_enable, S_IRUGO | S_IWUSR,
+			show_beep_enable, store_beep_enable, 0),
+	SENSOR_ATTR(beep_mask, S_IRUGO | S_IWUSR,
+			show_beep_mask, store_beep_mask, 1)
+};
+
+/* cpu voltage regulation information */
+static ssize_t show_vid_reg(struct device *dev,
+				struct device_attribute *attr, char *buf)
+{
+	struct w83791d_data *data = w83791d_update_device(dev);
+	return sprintf(buf, "%d\n", vid_from_reg(data->vid, data->vrm));
+}
+
+static DEVICE_ATTR(cpu0_vid, S_IRUGO, show_vid_reg, NULL);
+
+static ssize_t show_vrm_reg(struct device *dev,
+				struct device_attribute *attr, char *buf)
+{
+	struct w83791d_data *data = w83791d_update_device(dev);
+	return sprintf(buf, "%d\n", data->vrm);
+}
+
+static ssize_t store_vrm_reg(struct device *dev,
+				struct device_attribute *attr,
+				const char *buf, size_t count)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct w83791d_data *data = i2c_get_clientdata(client);
+	unsigned long val = simple_strtoul(buf, NULL, 10);
+
+	/* No lock needed as vrm is internal to the driver
+	   (not read from a chip register) and so is not
+	   updated in w83791d_update_device() */
+	data->vrm = val;
+
+	return count;
+}
+
+static DEVICE_ATTR(vrm, S_IRUGO | S_IWUSR, show_vrm_reg, store_vrm_reg);
+
+/* This function is called when:
+     * w83791d_driver is inserted (when this module is loaded), for each
+       available adapter
+     * when a new adapter is inserted (and w83791d_driver is still present) */
+static int w83791d_attach_adapter(struct i2c_adapter *adapter)
+{
+	if (!(adapter->class & I2C_CLASS_HWMON))
+		return 0;
+	return i2c_probe(adapter, &addr_data, w83791d_detect);
+}
+
+
+static int w83791d_create_subclient(struct i2c_adapter *adapter,
+				struct i2c_client *client, int addr,
+				struct i2c_client **sub_cli)
+{
+	int err;
+	struct i2c_client *sub_client;
+
+	(*sub_cli) = sub_client =
+			kzalloc(sizeof(struct i2c_client), GFP_KERNEL);
+	if (!(sub_client)) {
+		return -ENOMEM;
+	}
+	sub_client->addr = 0x48 + addr;
+	i2c_set_clientdata(sub_client, NULL);
+	sub_client->adapter = adapter;
+	sub_client->driver = &w83791d_driver;
+	strlcpy(sub_client->name, "w83791d subclient", I2C_NAME_SIZE);
+	if ((err = i2c_attach_client(sub_client))) {
+		dev_err(&client->dev, "subclient registration "
+			"at address 0x%x failed\n", sub_client->addr);
+		kfree(sub_client);
+		return err;
+	}
+	return 0;
+}
+
+
+static int w83791d_detect_subclients(struct i2c_adapter *adapter, int address,
+				int kind, struct i2c_client *client)
+{
+	struct w83791d_data *data = i2c_get_clientdata(client);
+	int i, id, err;
+	u8 val;
+
+	id = i2c_adapter_id(adapter);
+	if (force_subclients[0] == id && force_subclients[1] == address) {
+		for (i = 2; i <= 3; i++) {
+			if (force_subclients[i] < 0x48 ||
+			    force_subclients[i] > 0x4f) {
+				dev_err(&client->dev,
+					"invalid subclient "
+					"address %d; must be 0x48-0x4f\n",
+					force_subclients[i]);
+				err = -ENODEV;
+				goto error_sc_0;
+			}
+		}
+		w83791d_write(client, W83791D_REG_I2C_SUBADDR,
+					(force_subclients[2] & 0x07) |
+					((force_subclients[3] & 0x07) << 4));
+	}
+
+	val = w83791d_read(client, W83791D_REG_I2C_SUBADDR);
+	if (!(val & 0x08)) {
+		err = w83791d_create_subclient(adapter, client,
+						val & 0x7, &data->lm75[0]);
+		if (err < 0)
+			goto error_sc_0;
+	}
+	if (!(val & 0x80)) {
+		if ((data->lm75[0] != NULL) &&
+				((val & 0x7) == ((val >> 4) & 0x7))) {
+			dev_err(&client->dev,
+				"duplicate addresses 0x%x, "
+				"use force_subclient\n",
+				data->lm75[0]->addr);
+			err = -ENODEV;
+			goto error_sc_1;
+		}
+		err = w83791d_create_subclient(adapter, client,
+					(val >> 4) & 0x7, &data->lm75[1]);
+		if (err < 0)
+			goto error_sc_1;
+	}
+
+	return 0;
+
+/* Undo inits in case of errors */
+
+error_sc_1:
+	if (data->lm75[0] != NULL) {
+		i2c_detach_client(data->lm75[0]);
+		kfree(data->lm75[0]);
+	}
+error_sc_0:
+	return err;
+}
+
+
+static int w83791d_detect(struct i2c_adapter *adapter, int address, int kind)
+{
+	struct i2c_client *client;
+	struct device *dev;
+	struct w83791d_data *data;
+	int i, val1, val2;
+	int err = 0;
+	const char *client_name = "";
+
+	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
+		goto error0;
+	}
+
+	/* OK. For now, we presume we have a valid client. We now create the
+	   client structure, even though we cannot fill it completely yet.
+	   But it allows us to access w83791d_{read,write}_value. */
+	if (!(data = kzalloc(sizeof(struct w83791d_data), GFP_KERNEL))) {
+		err = -ENOMEM;
+		goto error0;
+	}
+
+	client = &data->client;
+	dev = &client->dev;
+	i2c_set_clientdata(client, data);
+	client->addr = address;
+	client->adapter = adapter;
+	client->driver = &w83791d_driver;
+	mutex_init(&data->update_lock);
+
+	/* Now, we do the remaining detection. */
+
+	/* The w83791d may be stuck in some other bank than bank 0. This may
+	   make reading other information impossible. Specify a force=...
+	   parameter, and the Winbond will be reset to the right bank. */
+	if (kind < 0) {
+		if (w83791d_read(client, W83791D_REG_CONFIG) & 0x80) {
+			dev_dbg(dev, "Detection failed at step 1\n");
+			goto error1;
+		}
+		val1 = w83791d_read(client, W83791D_REG_BANK);
+		val2 = w83791d_read(client, W83791D_REG_CHIPMAN);
+		/* Check for Winbond ID if in bank 0 */
+		if (!(val1 & 0x07)) {
+			/* yes it is Bank0 */
+			if (((!(val1 & 0x80)) && (val2 != 0xa3)) ||
+			    ((val1 & 0x80) && (val2 != 0x5c))) {
+				dev_dbg(dev, "Detection failed at step 2\n");
+				goto error1;
+			}
+		}
+		/* If Winbond chip, address of chip and W83791D_REG_I2C_ADDR
+		   should match */
+		if (w83791d_read(client, W83791D_REG_I2C_ADDR) != address) {
+			dev_dbg(dev, "Detection failed at step 3\n");
+			goto error1;
+		}
+	}
+
+	/* We either have a force parameter or we have reason to
+	   believe it is a Winbond chip. Either way, we want bank 0 and
+	   Vendor ID high byte */
+	val1 = w83791d_read(client, W83791D_REG_BANK) & 0x78;
+	w83791d_write(client, W83791D_REG_BANK, val1 | 0x80);
+
+	/* Verify it is a Winbond w83791d */
+	if (kind <= 0) {
+		/* get vendor ID */
+		val2 = w83791d_read(client, W83791D_REG_CHIPMAN);
+		if (val2 != 0x5c) {	/* the vendor is NOT Winbond */
+			dev_dbg(dev, "Detection failed at step 4\n");
+			goto error1;
+		}
+		val1 = w83791d_read(client, W83791D_REG_WCHIPID);
+		if (val1 == 0x71) {
+			kind = w83791d;
+		} else {
+			if (kind == 0)
+				dev_warn(dev,
+					"w83791d: Ignoring 'force' parameter "
+					"for unknown chip at adapter %d, "
+					"address 0x%02x\n",
+					i2c_adapter_id(adapter), address);
+			goto error1;
+		}
+	}
+
+	if (kind == w83791d) {
+		client_name = "w83791d";
+	} else {
+		dev_err(dev, "w83791d: Internal error: unknown kind (%d)?!?",
+			kind);
+		goto error1;
+	}
+
+#ifdef DEBUG
+	val1 = w83791d_read(client, W83791D_REG_DID_VID4);
+	dev_dbg(dev, "Device ID version: %d.%d (0x%02x)\n",
+			(val1 >> 5) & 0x07, (val1 >> 1) & 0x0f, val1);
+#endif
+
+	/* Fill in the remaining client fields and put into the global list */
+	strlcpy(client->name, client_name, I2C_NAME_SIZE);
+
+	/* Tell the I2C layer a new client has arrived */
+	if ((err = i2c_attach_client(client)))
+		goto error1;
+
+	if ((err = w83791d_detect_subclients(adapter, address, kind, client)))
+		goto error2;
+
+	/* Initialize the chip */
+	w83791d_init_client(client);
+
+	/* If the fan_div is changed, make sure there is a rational
+	   fan_min in place */
+	for (i = 0; i < NUMBER_OF_FANIN; i++) {
+		data->fan_min[i] = w83791d_read(client, W83791D_REG_FAN_MIN[i]);
+	}
+
+	/* Register sysfs hooks */
+	data->class_dev = hwmon_device_register(dev);
+	if (IS_ERR(data->class_dev)) {
+		err = PTR_ERR(data->class_dev);
+		goto error3;
+	}
+
+	for (i = 0; i < NUMBER_OF_VIN; i++) {
+		device_create_file(dev, &sda_in_input[i].dev_attr);
+		device_create_file(dev, &sda_in_min[i].dev_attr);
+		device_create_file(dev, &sda_in_max[i].dev_attr);
+	}
+
+	for (i = 0; i < NUMBER_OF_FANIN; i++) {
+		device_create_file(dev, &sda_fan_input[i].dev_attr);
+		device_create_file(dev, &sda_fan_div[i].dev_attr);
+		device_create_file(dev, &sda_fan_min[i].dev_attr);
+	}
+
+	for (i = 0; i < NUMBER_OF_TEMPIN; i++) {
+		device_create_file(dev, &sda_temp_input[i].dev_attr);
+		device_create_file(dev, &sda_temp_max[i].dev_attr);
+		device_create_file(dev, &sda_temp_max_hyst[i].dev_attr);
+	}
+
+	device_create_file(dev, &dev_attr_alarms);
+
+	for (i = 0; i < ARRAY_SIZE(sda_beep_ctrl); i++) {
+		device_create_file(dev, &sda_beep_ctrl[i].dev_attr);
+	}
+
+	device_create_file(dev, &dev_attr_cpu0_vid);
+	device_create_file(dev, &dev_attr_vrm);
+
+	return 0;
+
+error3:
+	if (data->lm75[0] != NULL) {
+		i2c_detach_client(data->lm75[0]);
+		kfree(data->lm75[0]);
+	}
+	if (data->lm75[1] != NULL) {
+		i2c_detach_client(data->lm75[1]);
+		kfree(data->lm75[1]);
+	}
+error2:
+	i2c_detach_client(client);
+error1:
+	kfree(data);
+error0:
+	return err;
+}
+
+static int w83791d_detach_client(struct i2c_client *client)
+{
+	struct w83791d_data *data = i2c_get_clientdata(client);
+	int err;
+
+	/* main client */
+	if (data)
+		hwmon_device_unregister(data->class_dev);
+
+	if ((err = i2c_detach_client(client)))
+		return err;
+
+	/* main client */
+	if (data)
+		kfree(data);
+	/* subclient */
+	else
+		kfree(client);
+
+	return 0;
+}
+
+static void w83791d_init_client(struct i2c_client *client)
+{
+	struct w83791d_data *data = i2c_get_clientdata(client);
+	u8 tmp;
+	u8 old_beep;
+
+	/* The difference between reset and init is that reset
+	   does a hard reset of the chip via index 0x40, bit 7,
+	   but init simply forces certain registers to have "sane"
+	   values. The hope is that the BIOS has done the right
+	   thing (which is why the default is reset=0, init=0),
+	   but if not, reset is the hard hammer and init
+	   is the soft mallet both of which are trying to whack
+	   things into place...
+	   NOTE: The data sheet makes a distinction between
+	   "power on defaults" and "reset by MR". As far as I can tell,
+	   the hard reset puts everything into a power-on state so I'm
+	   not sure what "reset by MR" means or how it can happen.
+	   */
+	if (reset || init) {
+		/* keep some BIOS settings when we... */
+		old_beep = w83791d_read(client, W83791D_REG_BEEP_CONFIG);
+
+		if (reset) {
+			/* ... reset the chip and ... */
+			w83791d_write(client, W83791D_REG_CONFIG, 0x80);
+		}
+
+		/* ... disable power-on abnormal beep */
+		w83791d_write(client, W83791D_REG_BEEP_CONFIG, old_beep | 0x80);
+
+		/* disable the global beep (not done by hard reset) */
+		tmp = w83791d_read(client, W83791D_REG_BEEP_CTRL[1]);
+		w83791d_write(client, W83791D_REG_BEEP_CTRL[1], tmp & 0xef);
+
+		if (init) {
+			/* Make sure monitoring is turned on for add-ons */
+			tmp = w83791d_read(client, W83791D_REG_TEMP2_CONFIG);
+			if (tmp & 1) {
+				w83791d_write(client, W83791D_REG_TEMP2_CONFIG,
+					tmp & 0xfe);
+			}
+
+			tmp = w83791d_read(client, W83791D_REG_TEMP3_CONFIG);
+			if (tmp & 1) {
+				w83791d_write(client, W83791D_REG_TEMP3_CONFIG,
+					tmp & 0xfe);
+			}
+
+			/* Start monitoring */
+			tmp = w83791d_read(client, W83791D_REG_CONFIG) & 0xf7;
+			w83791d_write(client, W83791D_REG_CONFIG, tmp | 0x01);
+		}
+	}
+
+	data->vrm = vid_which_vrm();
+}
+
+static struct w83791d_data *w83791d_update_device(struct device *dev)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct w83791d_data *data = i2c_get_clientdata(client);
+	int i, j;
+	u8 reg_array_tmp[3];
+
+	mutex_lock(&data->update_lock);
+
+	if (time_after(jiffies, data->last_updated + (HZ * 3))
+			|| !data->valid) {
+		dev_dbg(dev, "Starting w83791d device update\n");
+
+		/* Update the voltages measured value and limits */
+		for (i = 0; i < NUMBER_OF_VIN; i++) {
+			data->in[i] = w83791d_read(client,
+						W83791D_REG_IN[i]);
+			data->in_max[i] = w83791d_read(client,
+						W83791D_REG_IN_MAX[i]);
+			data->in_min[i] = w83791d_read(client,
+						W83791D_REG_IN_MIN[i]);
+		}
+
+		/* Update the fan counts and limits */
+		for (i = 0; i < NUMBER_OF_FANIN; i++) {
+			/* Update the Fan measured value and limits */
+			data->fan[i] = w83791d_read(client,
+						W83791D_REG_FAN[i]);
+			data->fan_min[i] = w83791d_read(client,
+						W83791D_REG_FAN_MIN[i]);
+		}
+
+		/* Update the fan divisor */
+		for (i = 0; i < 3; i++) {
+			reg_array_tmp[i] = w83791d_read(client,
+						W83791D_REG_FAN_DIV[i]);
+		}
+		data->fan_div[0] = (reg_array_tmp[0] >> 4) & 0x03;
+		data->fan_div[1] = (reg_array_tmp[0] >> 6) & 0x03;
+		data->fan_div[2] = (reg_array_tmp[1] >> 6) & 0x03;
+		data->fan_div[3] = reg_array_tmp[2] & 0x07;
+		data->fan_div[4] = (reg_array_tmp[2] >> 4) & 0x07;
+
+		/* Update the first temperature sensor */
+		for (i = 0; i < 3; i++) {
+			data->temp1[i] = w83791d_read(client,
+						W83791D_REG_TEMP1[i]);
+		}
+
+		/* Update the rest of the temperature sensors */
+		for (i = 0; i < 2; i++) {
+			for (j = 0; j < 3; j++) {
+				data->temp_add[i][j] =
+					(w83791d_read(client,
+					W83791D_REG_TEMP_ADD[i][j * 2]) << 8) |
+					w83791d_read(client,
+					W83791D_REG_TEMP_ADD[i][j * 2 + 1]);
+			}
+		}
+
+		/* Update the realtime status */
+		data->alarms =
+			w83791d_read(client, W83791D_REG_ALARM1) +
+			(w83791d_read(client, W83791D_REG_ALARM2) << 8) +
+			(w83791d_read(client, W83791D_REG_ALARM3) << 16);
+
+		/* Update the beep configuration information */
+		data->beep_mask =
+			w83791d_read(client, W83791D_REG_BEEP_CTRL[0]) +
+			(w83791d_read(client, W83791D_REG_BEEP_CTRL[1]) << 8) +
+			(w83791d_read(client, W83791D_REG_BEEP_CTRL[2]) << 16);
+
+		data->beep_enable =
+			(data->beep_mask >> GLOBAL_BEEP_ENABLE_SHIFT) & 0x01;
+
+		/* Update the cpu voltage information */
+		i = w83791d_read(client, W83791D_REG_VID_FANDIV);
+		data->vid = i & 0x0f;
+		data->vid |= (w83791d_read(client, W83791D_REG_DID_VID4) & 0x01)
+				<< 4;
+
+		data->last_updated = jiffies;
+		data->valid = 1;
+	}
+
+	mutex_unlock(&data->update_lock);
+
+#ifdef DEBUG
+	w83791d_print_debug(data, dev);
+#endif
+
+	return data;
+}
+
+#ifdef DEBUG
+static void w83791d_print_debug(struct w83791d_data *data, struct device *dev)
+{
+	int i = 0, j = 0;
+
+	dev_dbg(dev, "======Start of w83791d debug values======\n");
+	dev_dbg(dev, "%d set of Voltages: ===>\n", NUMBER_OF_VIN);
+	for (i = 0; i < NUMBER_OF_VIN; i++) {
+		dev_dbg(dev, "vin[%d] is:     0x%02x\n", i, data->in[i]);
+		dev_dbg(dev, "vin[%d] min is: 0x%02x\n", i, data->in_min[i]);
+		dev_dbg(dev, "vin[%d] max is: 0x%02x\n", i, data->in_max[i]);
+	}
+	dev_dbg(dev, "%d set of Fan Counts/Divisors: ===>\n", NUMBER_OF_FANIN);
+	for (i = 0; i < NUMBER_OF_FANIN; i++) {
+		dev_dbg(dev, "fan[%d] is:     0x%02x\n", i, data->fan[i]);
+		dev_dbg(dev, "fan[%d] min is: 0x%02x\n", i, data->fan_min[i]);
+		dev_dbg(dev, "fan_div[%d] is: 0x%02x\n", i, data->fan_div[i]);
+	}
+
+	/* temperature math is signed, but only print out the
+	   bits that matter */
+	dev_dbg(dev, "%d set of Temperatures: ===>\n", NUMBER_OF_TEMPIN);
+	for (i = 0; i < 3; i++) {
+		dev_dbg(dev, "temp1[%d] is: 0x%02x\n", i, (u8) data->temp1[i]);
+	}
+	for (i = 0; i < 2; i++) {
+		for (j = 0; j < 3; j++) {
+			dev_dbg(dev, "temp_add[%d][%d] is: 0x%04x\n", i, j,
+				(u16) data->temp_add[i][j]);
+		}
+	}
+
+	dev_dbg(dev, "Misc Information: ===>\n");
+	dev_dbg(dev, "alarm is:     0x%08x\n", data->alarms);
+	dev_dbg(dev, "beep_mask is: 0x%08x\n", data->beep_mask);
+	dev_dbg(dev, "beep_enable is: %d\n", data->beep_enable);
+	dev_dbg(dev, "vid is: 0x%02x\n", data->vid);
+	dev_dbg(dev, "vrm is: 0x%02x\n", data->vrm);
+	dev_dbg(dev, "=======End of w83791d debug values========\n");
+	dev_dbg(dev, "\n");
+}
+#endif
+
+static int __init sensors_w83791d_init(void)
+{
+	return i2c_add_driver(&w83791d_driver);
+}
+
+static void __exit sensors_w83791d_exit(void)
+{
+	i2c_del_driver(&w83791d_driver);
+}
+
+MODULE_AUTHOR("Charles Spirakis <bezaur@gmail.com>");
+MODULE_DESCRIPTION("W83791D driver");
+MODULE_LICENSE("GPL");
+
+module_init(sensors_w83791d_init);
+module_exit(sensors_w83791d_exit);
diff --git a/drivers/i2c/busses/i2c-ocores.c b/drivers/i2c/busses/i2c-ocores.c
new file mode 100644
index 000000000..820a75232
--- /dev/null
+++ b/drivers/i2c/busses/i2c-ocores.c
@@ -0,0 +1,340 @@
+/*
+ * i2c-ocores.c: I2C bus driver for OpenCores I2C controller
+ * (http://www.opencores.org/projects.cgi/web/i2c/overview).
+ *
+ * Peter Korsgaard <jacmet@sunsite.dk>
+ *
+ * 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 <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/platform_device.h>
+#include <linux/i2c.h>
+#include <linux/interrupt.h>
+#include <linux/wait.h>
+#include <linux/i2c-ocores.h>
+#include <asm/io.h>
+
+struct ocores_i2c {
+	void __iomem *base;
+	int regstep;
+	wait_queue_head_t wait;
+	struct i2c_adapter adap;
+	struct i2c_msg *msg;
+	int pos;
+	int nmsgs;
+	int state; /* see STATE_ */
+};
+
+/* registers */
+#define OCI2C_PRELOW		0
+#define OCI2C_PREHIGH		1
+#define OCI2C_CONTROL		2
+#define OCI2C_DATA		3
+#define OCI2C_CMD		4 /* write only */
+#define OCI2C_STATUS		4 /* read only, same address as OCI2C_CMD */
+
+#define OCI2C_CTRL_IEN		0x40
+#define OCI2C_CTRL_EN		0x80
+
+#define OCI2C_CMD_START		0x91
+#define OCI2C_CMD_STOP		0x41
+#define OCI2C_CMD_READ		0x21
+#define OCI2C_CMD_WRITE		0x11
+#define OCI2C_CMD_READ_ACK	0x21
+#define OCI2C_CMD_READ_NACK	0x29
+#define OCI2C_CMD_IACK		0x01
+
+#define OCI2C_STAT_IF		0x01
+#define OCI2C_STAT_TIP		0x02
+#define OCI2C_STAT_ARBLOST	0x20
+#define OCI2C_STAT_BUSY		0x40
+#define OCI2C_STAT_NACK		0x80
+
+#define STATE_DONE		0
+#define STATE_START		1
+#define STATE_WRITE		2
+#define STATE_READ		3
+#define STATE_ERROR		4
+
+static inline void oc_setreg(struct ocores_i2c *i2c, int reg, u8 value)
+{
+	iowrite8(value, i2c->base + reg * i2c->regstep);
+}
+
+static inline u8 oc_getreg(struct ocores_i2c *i2c, int reg)
+{
+	return ioread8(i2c->base + reg * i2c->regstep);
+}
+
+static void ocores_process(struct ocores_i2c *i2c)
+{
+	struct i2c_msg *msg = i2c->msg;
+	u8 stat = oc_getreg(i2c, OCI2C_STATUS);
+
+	if ((i2c->state == STATE_DONE) || (i2c->state == STATE_ERROR)) {
+		/* stop has been sent */
+		oc_setreg(i2c, OCI2C_CMD, OCI2C_CMD_IACK);
+		wake_up(&i2c->wait);
+		return;
+	}
+
+	/* error? */
+	if (stat & OCI2C_STAT_ARBLOST) {
+		i2c->state = STATE_ERROR;
+		oc_setreg(i2c, OCI2C_CMD, OCI2C_CMD_STOP);
+		return;
+	}
+
+	if ((i2c->state == STATE_START) || (i2c->state == STATE_WRITE)) {
+		i2c->state =
+			(msg->flags & I2C_M_RD) ? STATE_READ : STATE_WRITE;
+
+		if (stat & OCI2C_STAT_NACK) {
+			i2c->state = STATE_ERROR;
+			oc_setreg(i2c, OCI2C_CMD, OCI2C_CMD_STOP);
+			return;
+		}
+	} else
+		msg->buf[i2c->pos++] = oc_getreg(i2c, OCI2C_DATA);
+
+	/* end of msg? */
+	if (i2c->pos == msg->len) {
+		i2c->nmsgs--;
+		i2c->msg++;
+		i2c->pos = 0;
+		msg = i2c->msg;
+
+		if (i2c->nmsgs) {	/* end? */
+			/* send start? */
+			if (!(msg->flags & I2C_M_NOSTART)) {
+				u8 addr = (msg->addr << 1);
+
+				if (msg->flags & I2C_M_RD)
+					addr |= 1;
+
+				i2c->state = STATE_START;
+
+				oc_setreg(i2c, OCI2C_DATA, addr);
+				oc_setreg(i2c, OCI2C_CMD,  OCI2C_CMD_START);
+				return;
+			} else
+				i2c->state = (msg->flags & I2C_M_RD)
+					? STATE_READ : STATE_WRITE;
+		} else {
+			i2c->state = STATE_DONE;
+			oc_setreg(i2c, OCI2C_CMD, OCI2C_CMD_STOP);
+			return;
+		}
+	}
+
+	if (i2c->state == STATE_READ) {
+		oc_setreg(i2c, OCI2C_CMD, i2c->pos == (msg->len-1) ?
+			  OCI2C_CMD_READ_NACK : OCI2C_CMD_READ_ACK);
+	} else {
+		oc_setreg(i2c, OCI2C_DATA, msg->buf[i2c->pos++]);
+		oc_setreg(i2c, OCI2C_CMD, OCI2C_CMD_WRITE);
+	}
+}
+
+static irqreturn_t ocores_isr(int irq, void *dev_id, struct pt_regs *regs)
+{
+	struct ocores_i2c *i2c = dev_id;
+
+	ocores_process(i2c);
+
+	return IRQ_HANDLED;
+}
+
+static int ocores_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
+{
+	struct ocores_i2c *i2c = i2c_get_adapdata(adap);
+
+	i2c->msg = msgs;
+	i2c->pos = 0;
+	i2c->nmsgs = num;
+	i2c->state = STATE_START;
+
+	oc_setreg(i2c, OCI2C_DATA,
+			(i2c->msg->addr << 1) |
+			((i2c->msg->flags & I2C_M_RD) ? 1:0));
+
+	oc_setreg(i2c, OCI2C_CMD, OCI2C_CMD_START);
+
+	if (wait_event_timeout(i2c->wait, (i2c->state == STATE_ERROR) ||
+			       (i2c->state == STATE_DONE), HZ))
+		return (i2c->state == STATE_DONE) ? num : -EIO;
+	else
+		return -ETIMEDOUT;
+}
+
+static void ocores_init(struct ocores_i2c *i2c,
+			struct ocores_i2c_platform_data *pdata)
+{
+	int prescale;
+	u8 ctrl = oc_getreg(i2c, OCI2C_CONTROL);
+
+	/* make sure the device is disabled */
+	oc_setreg(i2c, OCI2C_CONTROL, ctrl & ~(OCI2C_CTRL_EN|OCI2C_CTRL_IEN));
+
+	prescale = (pdata->clock_khz / (5*100)) - 1;
+	oc_setreg(i2c, OCI2C_PRELOW, prescale & 0xff);
+	oc_setreg(i2c, OCI2C_PREHIGH, prescale >> 8);
+
+	/* Init the device */
+	oc_setreg(i2c, OCI2C_CMD, OCI2C_CMD_IACK);
+	oc_setreg(i2c, OCI2C_CONTROL, ctrl | OCI2C_CTRL_IEN | OCI2C_CTRL_EN);
+}
+
+
+static u32 ocores_func(struct i2c_adapter *adap)
+{
+	return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
+}
+
+static struct i2c_algorithm ocores_algorithm = {
+	.master_xfer	= ocores_xfer,
+	.functionality	= ocores_func,
+};
+
+static struct i2c_adapter ocores_adapter = {
+	.owner		= THIS_MODULE,
+	.name		= "i2c-ocores",
+	.class		= I2C_CLASS_HWMON,
+	.algo		= &ocores_algorithm,
+};
+
+
+static int __devinit ocores_i2c_probe(struct platform_device *pdev)
+{
+	struct ocores_i2c *i2c;
+	struct ocores_i2c_platform_data *pdata;
+	struct resource *res, *res2;
+	int ret;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res)
+		return -ENODEV;
+
+	res2 = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+	if (!res2)
+		return -ENODEV;
+
+	pdata = (struct ocores_i2c_platform_data*) pdev->dev.platform_data;
+	if (!pdata)
+		return -ENODEV;
+
+	i2c = kzalloc(sizeof(*i2c), GFP_KERNEL);
+	if (!i2c)
+		return -ENOMEM;
+
+	if (!request_mem_region(res->start, res->end - res->start + 1,
+				pdev->name)) {
+		dev_err(&pdev->dev, "Memory region busy\n");
+		ret = -EBUSY;
+		goto request_mem_failed;
+	}
+
+	i2c->base = ioremap(res->start, res->end - res->start + 1);
+	if (!i2c->base) {
+		dev_err(&pdev->dev, "Unable to map registers\n");
+		ret = -EIO;
+		goto map_failed;
+	}
+
+	i2c->regstep = pdata->regstep;
+	ocores_init(i2c, pdata);
+
+	init_waitqueue_head(&i2c->wait);
+	ret = request_irq(res2->start, ocores_isr, 0, pdev->name, i2c);
+	if (ret) {
+		dev_err(&pdev->dev, "Cannot claim IRQ\n");
+		goto request_irq_failed;
+	}
+
+	/* hook up driver to tree */
+	platform_set_drvdata(pdev, i2c);
+	i2c->adap = ocores_adapter;
+	i2c_set_adapdata(&i2c->adap, i2c);
+	i2c->adap.dev.parent = &pdev->dev;
+
+	/* add i2c adapter to i2c tree */
+	ret = i2c_add_adapter(&i2c->adap);
+	if (ret) {
+		dev_err(&pdev->dev, "Failed to add adapter\n");
+		goto add_adapter_failed;
+	}
+
+	return 0;
+
+add_adapter_failed:
+	free_irq(res2->start, i2c);
+request_irq_failed:
+	iounmap(i2c->base);
+map_failed:
+	release_mem_region(res->start, res->end - res->start + 1);
+request_mem_failed:
+	kfree(i2c);
+
+	return ret;
+}
+
+static int __devexit ocores_i2c_remove(struct platform_device* pdev)
+{
+	struct ocores_i2c *i2c = platform_get_drvdata(pdev);
+	struct resource *res;
+
+	/* disable i2c logic */
+	oc_setreg(i2c, OCI2C_CONTROL, oc_getreg(i2c, OCI2C_CONTROL)
+		  & ~(OCI2C_CTRL_EN|OCI2C_CTRL_IEN));
+
+	/* remove adapter & data */
+	i2c_del_adapter(&i2c->adap);
+	platform_set_drvdata(pdev, NULL);
+
+	res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+	if (res)
+		free_irq(res->start, i2c);
+
+	iounmap(i2c->base);
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (res)
+		release_mem_region(res->start, res->end - res->start + 1);
+
+	kfree(i2c);
+
+	return 0;
+}
+
+static struct platform_driver ocores_i2c_driver = {
+	.probe  = ocores_i2c_probe,
+	.remove = __devexit_p(ocores_i2c_remove),
+	.driver = {
+		.owner = THIS_MODULE,
+		.name = "ocores-i2c",
+	},
+};
+
+static int __init ocores_i2c_init(void)
+{
+	return platform_driver_register(&ocores_i2c_driver);
+}
+
+static void __exit ocores_i2c_exit(void)
+{
+	platform_driver_unregister(&ocores_i2c_driver);
+}
+
+module_init(ocores_i2c_init);
+module_exit(ocores_i2c_exit);
+
+MODULE_AUTHOR("Peter Korsgaard <jacmet@sunsite.dk>");
+MODULE_DESCRIPTION("OpenCores I2C bus driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/infiniband/core/addr.c b/drivers/infiniband/core/addr.c
new file mode 100644
index 000000000..1205e8027
--- /dev/null
+++ b/drivers/infiniband/core/addr.c
@@ -0,0 +1,365 @@
+/*
+ * Copyright (c) 2005 Voltaire Inc.  All rights reserved.
+ * Copyright (c) 2002-2005, Network Appliance, Inc. All rights reserved.
+ * Copyright (c) 1999-2005, Mellanox Technologies, Inc. All rights reserved.
+ * Copyright (c) 2005 Intel Corporation.  All rights reserved.
+ *
+ * This Software is licensed under one of the following licenses:
+ *
+ * 1) under the terms of the "Common Public License 1.0" a copy of which is
+ *    available from the Open Source Initiative, see
+ *    http://www.opensource.org/licenses/cpl.php.
+ *
+ * 2) under the terms of the "The BSD License" a copy of which is
+ *    available from the Open Source Initiative, see
+ *    http://www.opensource.org/licenses/bsd-license.php.
+ *
+ * 3) under the terms of the "GNU General Public License (GPL) Version 2" a
+ *    copy of which is available from the Open Source Initiative, see
+ *    http://www.opensource.org/licenses/gpl-license.php.
+ *
+ * Licensee has the right to choose one of the above licenses.
+ *
+ * Redistributions of source code must retain the above copyright
+ * notice and one of the license notices.
+ *
+ * Redistributions in binary form must reproduce both the above copyright
+ * notice, one of the license notices in the documentation
+ * and/or other materials provided with the distribution.
+ */
+
+#include <linux/mutex.h>
+#include <linux/inetdevice.h>
+#include <linux/workqueue.h>
+#include <linux/if_arp.h>
+#include <net/arp.h>
+#include <net/neighbour.h>
+#include <net/route.h>
+#include <net/netevent.h>
+#include <rdma/ib_addr.h>
+
+MODULE_AUTHOR("Sean Hefty");
+MODULE_DESCRIPTION("IB Address Translation");
+MODULE_LICENSE("Dual BSD/GPL");
+
+struct addr_req {
+	struct list_head list;
+	struct sockaddr src_addr;
+	struct sockaddr dst_addr;
+	struct rdma_dev_addr *addr;
+	void *context;
+	void (*callback)(int status, struct sockaddr *src_addr,
+			 struct rdma_dev_addr *addr, void *context);
+	unsigned long timeout;
+	int status;
+};
+
+static void process_req(void *data);
+
+static DEFINE_MUTEX(lock);
+static LIST_HEAD(req_list);
+static DECLARE_WORK(work, process_req, NULL);
+static struct workqueue_struct *addr_wq;
+
+static int copy_addr(struct rdma_dev_addr *dev_addr, struct net_device *dev,
+		     unsigned char *dst_dev_addr)
+{
+	switch (dev->type) {
+	case ARPHRD_INFINIBAND:
+		dev_addr->dev_type = IB_NODE_CA;
+		break;
+	default:
+		return -EADDRNOTAVAIL;
+	}
+
+	memcpy(dev_addr->src_dev_addr, dev->dev_addr, MAX_ADDR_LEN);
+	memcpy(dev_addr->broadcast, dev->broadcast, MAX_ADDR_LEN);
+	if (dst_dev_addr)
+		memcpy(dev_addr->dst_dev_addr, dst_dev_addr, MAX_ADDR_LEN);
+	return 0;
+}
+
+int rdma_translate_ip(struct sockaddr *addr, struct rdma_dev_addr *dev_addr)
+{
+	struct net_device *dev;
+	u32 ip = ((struct sockaddr_in *) addr)->sin_addr.s_addr;
+	int ret;
+
+	dev = ip_dev_find(ip);
+	if (!dev)
+		return -EADDRNOTAVAIL;
+
+	ret = copy_addr(dev_addr, dev, NULL);
+	dev_put(dev);
+	return ret;
+}
+EXPORT_SYMBOL(rdma_translate_ip);
+
+static void set_timeout(unsigned long time)
+{
+	unsigned long delay;
+
+	cancel_delayed_work(&work);
+
+	delay = time - jiffies;
+	if ((long)delay <= 0)
+		delay = 1;
+
+	queue_delayed_work(addr_wq, &work, delay);
+}
+
+static void queue_req(struct addr_req *req)
+{
+	struct addr_req *temp_req;
+
+	mutex_lock(&lock);
+	list_for_each_entry_reverse(temp_req, &req_list, list) {
+		if (time_after(req->timeout, temp_req->timeout))
+			break;
+	}
+
+	list_add(&req->list, &temp_req->list);
+
+	if (req_list.next == &req->list)
+		set_timeout(req->timeout);
+	mutex_unlock(&lock);
+}
+
+static void addr_send_arp(struct sockaddr_in *dst_in)
+{
+	struct rtable *rt;
+	struct flowi fl;
+	u32 dst_ip = dst_in->sin_addr.s_addr;
+
+	memset(&fl, 0, sizeof fl);
+	fl.nl_u.ip4_u.daddr = dst_ip;
+	if (ip_route_output_key(&rt, &fl))
+		return;
+
+	arp_send(ARPOP_REQUEST, ETH_P_ARP, rt->rt_gateway, rt->idev->dev,
+		 rt->rt_src, NULL, rt->idev->dev->dev_addr, NULL);
+	ip_rt_put(rt);
+}
+
+static int addr_resolve_remote(struct sockaddr_in *src_in,
+			       struct sockaddr_in *dst_in,
+			       struct rdma_dev_addr *addr)
+{
+	u32 src_ip = src_in->sin_addr.s_addr;
+	u32 dst_ip = dst_in->sin_addr.s_addr;
+	struct flowi fl;
+	struct rtable *rt;
+	struct neighbour *neigh;
+	int ret;
+
+	memset(&fl, 0, sizeof fl);
+	fl.nl_u.ip4_u.daddr = dst_ip;
+	fl.nl_u.ip4_u.saddr = src_ip;
+	ret = ip_route_output_key(&rt, &fl);
+	if (ret)
+		goto out;
+
+	/* If the device does ARP internally, return 'done' */
+	if (rt->idev->dev->flags & IFF_NOARP) {
+		copy_addr(addr, rt->idev->dev, NULL);
+		goto put;
+	}
+
+	neigh = neigh_lookup(&arp_tbl, &rt->rt_gateway, rt->idev->dev);
+	if (!neigh) {
+		ret = -ENODATA;
+		goto put;
+	}
+
+	if (!(neigh->nud_state & NUD_VALID)) {
+		ret = -ENODATA;
+		goto release;
+	}
+
+	if (!src_ip) {
+		src_in->sin_family = dst_in->sin_family;
+		src_in->sin_addr.s_addr = rt->rt_src;
+	}
+
+	ret = copy_addr(addr, neigh->dev, neigh->ha);
+release:
+	neigh_release(neigh);
+put:
+	ip_rt_put(rt);
+out:
+	return ret;
+}
+
+static void process_req(void *data)
+{
+	struct addr_req *req, *temp_req;
+	struct sockaddr_in *src_in, *dst_in;
+	struct list_head done_list;
+
+	INIT_LIST_HEAD(&done_list);
+
+	mutex_lock(&lock);
+	list_for_each_entry_safe(req, temp_req, &req_list, list) {
+		if (req->status) {
+			src_in = (struct sockaddr_in *) &req->src_addr;
+			dst_in = (struct sockaddr_in *) &req->dst_addr;
+			req->status = addr_resolve_remote(src_in, dst_in,
+							  req->addr);
+		}
+		if (req->status && time_after(jiffies, req->timeout))
+			req->status = -ETIMEDOUT;
+		else if (req->status == -ENODATA)
+			continue;
+
+		list_del(&req->list);
+		list_add_tail(&req->list, &done_list);
+	}
+
+	if (!list_empty(&req_list)) {
+		req = list_entry(req_list.next, struct addr_req, list);
+		set_timeout(req->timeout);
+	}
+	mutex_unlock(&lock);
+
+	list_for_each_entry_safe(req, temp_req, &done_list, list) {
+		list_del(&req->list);
+		req->callback(req->status, &req->src_addr, req->addr,
+			      req->context);
+		kfree(req);
+	}
+}
+
+static int addr_resolve_local(struct sockaddr_in *src_in,
+			      struct sockaddr_in *dst_in,
+			      struct rdma_dev_addr *addr)
+{
+	struct net_device *dev;
+	u32 src_ip = src_in->sin_addr.s_addr;
+	u32 dst_ip = dst_in->sin_addr.s_addr;
+	int ret;
+
+	dev = ip_dev_find(dst_ip);
+	if (!dev)
+		return -EADDRNOTAVAIL;
+
+	if (ZERONET(src_ip)) {
+		src_in->sin_family = dst_in->sin_family;
+		src_in->sin_addr.s_addr = dst_ip;
+		ret = copy_addr(addr, dev, dev->dev_addr);
+	} else if (LOOPBACK(src_ip)) {
+		ret = rdma_translate_ip((struct sockaddr *)dst_in, addr);
+		if (!ret)
+			memcpy(addr->dst_dev_addr, dev->dev_addr, MAX_ADDR_LEN);
+	} else {
+		ret = rdma_translate_ip((struct sockaddr *)src_in, addr);
+		if (!ret)
+			memcpy(addr->dst_dev_addr, dev->dev_addr, MAX_ADDR_LEN);
+	}
+
+	dev_put(dev);
+	return ret;
+}
+
+int rdma_resolve_ip(struct sockaddr *src_addr, struct sockaddr *dst_addr,
+		    struct rdma_dev_addr *addr, int timeout_ms,
+		    void (*callback)(int status, struct sockaddr *src_addr,
+				     struct rdma_dev_addr *addr, void *context),
+		    void *context)
+{
+	struct sockaddr_in *src_in, *dst_in;
+	struct addr_req *req;
+	int ret = 0;
+
+	req = kmalloc(sizeof *req, GFP_KERNEL);
+	if (!req)
+		return -ENOMEM;
+	memset(req, 0, sizeof *req);
+
+	if (src_addr)
+		memcpy(&req->src_addr, src_addr, ip_addr_size(src_addr));
+	memcpy(&req->dst_addr, dst_addr, ip_addr_size(dst_addr));
+	req->addr = addr;
+	req->callback = callback;
+	req->context = context;
+
+	src_in = (struct sockaddr_in *) &req->src_addr;
+	dst_in = (struct sockaddr_in *) &req->dst_addr;
+
+	req->status = addr_resolve_local(src_in, dst_in, addr);
+	if (req->status == -EADDRNOTAVAIL)
+		req->status = addr_resolve_remote(src_in, dst_in, addr);
+
+	switch (req->status) {
+	case 0:
+		req->timeout = jiffies;
+		queue_req(req);
+		break;
+	case -ENODATA:
+		req->timeout = msecs_to_jiffies(timeout_ms) + jiffies;
+		queue_req(req);
+		addr_send_arp(dst_in);
+		break;
+	default:
+		ret = req->status;
+		kfree(req);
+		break;
+	}
+	return ret;
+}
+EXPORT_SYMBOL(rdma_resolve_ip);
+
+void rdma_addr_cancel(struct rdma_dev_addr *addr)
+{
+	struct addr_req *req, *temp_req;
+
+	mutex_lock(&lock);
+	list_for_each_entry_safe(req, temp_req, &req_list, list) {
+		if (req->addr == addr) {
+			req->status = -ECANCELED;
+			req->timeout = jiffies;
+			list_del(&req->list);
+			list_add(&req->list, &req_list);
+			set_timeout(req->timeout);
+			break;
+		}
+	}
+	mutex_unlock(&lock);
+}
+EXPORT_SYMBOL(rdma_addr_cancel);
+
+static int netevent_callback(struct notifier_block *self, unsigned long event, 
+	void *ctx)
+{
+	if (event == NETEVENT_NEIGH_UPDATE) {  
+		struct neighbour *neigh = ctx;
+
+		if (neigh->dev->type == ARPHRD_INFINIBAND &&
+		    (neigh->nud_state & NUD_VALID)) {
+			set_timeout(jiffies);
+		}
+	}
+	return 0;
+}
+
+static struct notifier_block nb = {
+	.notifier_call = netevent_callback
+};
+
+static int addr_init(void)
+{
+	addr_wq = create_singlethread_workqueue("ib_addr_wq");
+	if (!addr_wq)
+		return -ENOMEM;
+
+	register_netevent_notifier(&nb);
+	return 0;
+}
+
+static void addr_cleanup(void)
+{
+	unregister_netevent_notifier(&nb);
+	destroy_workqueue(addr_wq);
+}
+
+module_init(addr_init);
+module_exit(addr_cleanup);
diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c
new file mode 100644
index 000000000..5d625a811
--- /dev/null
+++ b/drivers/infiniband/core/cma.c
@@ -0,0 +1,1929 @@
+/*
+ * Copyright (c) 2005 Voltaire Inc.  All rights reserved.
+ * Copyright (c) 2002-2005, Network Appliance, Inc. All rights reserved.
+ * Copyright (c) 1999-2005, Mellanox Technologies, Inc. All rights reserved.
+ * Copyright (c) 2005-2006 Intel Corporation.  All rights reserved.
+ *
+ * This Software is licensed under one of the following licenses:
+ *
+ * 1) under the terms of the "Common Public License 1.0" a copy of which is
+ *    available from the Open Source Initiative, see
+ *    http://www.opensource.org/licenses/cpl.php.
+ *
+ * 2) under the terms of the "The BSD License" a copy of which is
+ *    available from the Open Source Initiative, see
+ *    http://www.opensource.org/licenses/bsd-license.php.
+ *
+ * 3) under the terms of the "GNU General Public License (GPL) Version 2" a
+ *    copy of which is available from the Open Source Initiative, see
+ *    http://www.opensource.org/licenses/gpl-license.php.
+ *
+ * Licensee has the right to choose one of the above licenses.
+ *
+ * Redistributions of source code must retain the above copyright
+ * notice and one of the license notices.
+ *
+ * Redistributions in binary form must reproduce both the above copyright
+ * notice, one of the license notices in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ */
+
+#include <linux/completion.h>
+#include <linux/in.h>
+#include <linux/in6.h>
+#include <linux/mutex.h>
+#include <linux/random.h>
+#include <linux/idr.h>
+
+#include <net/tcp.h>
+
+#include <rdma/rdma_cm.h>
+#include <rdma/rdma_cm_ib.h>
+#include <rdma/ib_cache.h>
+#include <rdma/ib_cm.h>
+#include <rdma/ib_sa.h>
+
+MODULE_AUTHOR("Sean Hefty");
+MODULE_DESCRIPTION("Generic RDMA CM Agent");
+MODULE_LICENSE("Dual BSD/GPL");
+
+#define CMA_CM_RESPONSE_TIMEOUT 20
+#define CMA_MAX_CM_RETRIES 15
+
+static void cma_add_one(struct ib_device *device);
+static void cma_remove_one(struct ib_device *device);
+
+static struct ib_client cma_client = {
+	.name   = "cma",
+	.add    = cma_add_one,
+	.remove = cma_remove_one
+};
+
+static LIST_HEAD(dev_list);
+static LIST_HEAD(listen_any_list);
+static DEFINE_MUTEX(lock);
+static struct workqueue_struct *cma_wq;
+static DEFINE_IDR(sdp_ps);
+static DEFINE_IDR(tcp_ps);
+
+struct cma_device {
+	struct list_head	list;
+	struct ib_device	*device;
+	__be64			node_guid;
+	struct completion	comp;
+	atomic_t		refcount;
+	struct list_head	id_list;
+};
+
+enum cma_state {
+	CMA_IDLE,
+	CMA_ADDR_QUERY,
+	CMA_ADDR_RESOLVED,
+	CMA_ROUTE_QUERY,
+	CMA_ROUTE_RESOLVED,
+	CMA_CONNECT,
+	CMA_DISCONNECT,
+	CMA_ADDR_BOUND,
+	CMA_LISTEN,
+	CMA_DEVICE_REMOVAL,
+	CMA_DESTROYING
+};
+
+struct rdma_bind_list {
+	struct idr		*ps;
+	struct hlist_head	owners;
+	unsigned short		port;
+};
+
+/*
+ * Device removal can occur at anytime, so we need extra handling to
+ * serialize notifying the user of device removal with other callbacks.
+ * We do this by disabling removal notification while a callback is in process,
+ * and reporting it after the callback completes.
+ */
+struct rdma_id_private {
+	struct rdma_cm_id	id;
+
+	struct rdma_bind_list	*bind_list;
+	struct hlist_node	node;
+	struct list_head	list;
+	struct list_head	listen_list;
+	struct cma_device	*cma_dev;
+
+	enum cma_state		state;
+	spinlock_t		lock;
+	struct completion	comp;
+	atomic_t		refcount;
+	wait_queue_head_t	wait_remove;
+	atomic_t		dev_remove;
+
+	int			backlog;
+	int			timeout_ms;
+	struct ib_sa_query	*query;
+	int			query_id;
+	union {
+		struct ib_cm_id	*ib;
+	} cm_id;
+
+	u32			seq_num;
+	u32			qp_num;
+	enum ib_qp_type		qp_type;
+	u8			srq;
+};
+
+struct cma_work {
+	struct work_struct	work;
+	struct rdma_id_private	*id;
+	enum cma_state		old_state;
+	enum cma_state		new_state;
+	struct rdma_cm_event	event;
+};
+
+union cma_ip_addr {
+	struct in6_addr ip6;
+	struct {
+		__u32 pad[3];
+		__u32 addr;
+	} ip4;
+};
+
+struct cma_hdr {
+	u8 cma_version;
+	u8 ip_version;	/* IP version: 7:4 */
+	__u16 port;
+	union cma_ip_addr src_addr;
+	union cma_ip_addr dst_addr;
+};
+
+struct sdp_hh {
+	u8 bsdh[16];
+	u8 sdp_version; /* Major version: 7:4 */
+	u8 ip_version;	/* IP version: 7:4 */
+	u8 sdp_specific1[10];
+	__u16 port;
+	__u16 sdp_specific2;
+	union cma_ip_addr src_addr;
+	union cma_ip_addr dst_addr;
+};
+
+struct sdp_hah {
+	u8 bsdh[16];
+	u8 sdp_version;
+};
+
+#define CMA_VERSION 0x00
+#define SDP_MAJ_VERSION 0x2
+
+static int cma_comp(struct rdma_id_private *id_priv, enum cma_state comp)
+{
+	unsigned long flags;
+	int ret;
+
+	spin_lock_irqsave(&id_priv->lock, flags);
+	ret = (id_priv->state == comp);
+	spin_unlock_irqrestore(&id_priv->lock, flags);
+	return ret;
+}
+
+static int cma_comp_exch(struct rdma_id_private *id_priv,
+			 enum cma_state comp, enum cma_state exch)
+{
+	unsigned long flags;
+	int ret;
+
+	spin_lock_irqsave(&id_priv->lock, flags);
+	if ((ret = (id_priv->state == comp)))
+		id_priv->state = exch;
+	spin_unlock_irqrestore(&id_priv->lock, flags);
+	return ret;
+}
+
+static enum cma_state cma_exch(struct rdma_id_private *id_priv,
+			       enum cma_state exch)
+{
+	unsigned long flags;
+	enum cma_state old;
+
+	spin_lock_irqsave(&id_priv->lock, flags);
+	old = id_priv->state;
+	id_priv->state = exch;
+	spin_unlock_irqrestore(&id_priv->lock, flags);
+	return old;
+}
+
+static inline u8 cma_get_ip_ver(struct cma_hdr *hdr)
+{
+	return hdr->ip_version >> 4;
+}
+
+static inline void cma_set_ip_ver(struct cma_hdr *hdr, u8 ip_ver)
+{
+	hdr->ip_version = (ip_ver << 4) | (hdr->ip_version & 0xF);
+}
+
+static inline u8 sdp_get_majv(u8 sdp_version)
+{
+	return sdp_version >> 4;
+}
+
+static inline u8 sdp_get_ip_ver(struct sdp_hh *hh)
+{
+	return hh->ip_version >> 4;
+}
+
+static inline void sdp_set_ip_ver(struct sdp_hh *hh, u8 ip_ver)
+{
+	hh->ip_version = (ip_ver << 4) | (hh->ip_version & 0xF);
+}
+
+static void cma_attach_to_dev(struct rdma_id_private *id_priv,
+			      struct cma_device *cma_dev)
+{
+	atomic_inc(&cma_dev->refcount);
+	id_priv->cma_dev = cma_dev;
+	id_priv->id.device = cma_dev->device;
+	list_add_tail(&id_priv->list, &cma_dev->id_list);
+}
+
+static inline void cma_deref_dev(struct cma_device *cma_dev)
+{
+	if (atomic_dec_and_test(&cma_dev->refcount))
+		complete(&cma_dev->comp);
+}
+
+static void cma_detach_from_dev(struct rdma_id_private *id_priv)
+{
+	list_del(&id_priv->list);
+	cma_deref_dev(id_priv->cma_dev);
+	id_priv->cma_dev = NULL;
+}
+
+static int cma_acquire_ib_dev(struct rdma_id_private *id_priv)
+{
+	struct cma_device *cma_dev;
+	union ib_gid gid;
+	int ret = -ENODEV;
+
+	ib_addr_get_sgid(&id_priv->id.route.addr.dev_addr, &gid),
+
+	mutex_lock(&lock);
+	list_for_each_entry(cma_dev, &dev_list, list) {
+		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);
+			break;
+		}
+	}
+	mutex_unlock(&lock);
+	return ret;
+}
+
+static int cma_acquire_dev(struct rdma_id_private *id_priv)
+{
+	switch (id_priv->id.route.addr.dev_addr.dev_type) {
+	case IB_NODE_CA:
+		return cma_acquire_ib_dev(id_priv);
+	default:
+		return -ENODEV;
+	}
+}
+
+static void cma_deref_id(struct rdma_id_private *id_priv)
+{
+	if (atomic_dec_and_test(&id_priv->refcount))
+		complete(&id_priv->comp);
+}
+
+static void cma_release_remove(struct rdma_id_private *id_priv)
+{
+	if (atomic_dec_and_test(&id_priv->dev_remove))
+		wake_up(&id_priv->wait_remove);
+}
+
+struct rdma_cm_id *rdma_create_id(rdma_cm_event_handler event_handler,
+				  void *context, enum rdma_port_space ps)
+{
+	struct rdma_id_private *id_priv;
+
+	id_priv = kzalloc(sizeof *id_priv, GFP_KERNEL);
+	if (!id_priv)
+		return ERR_PTR(-ENOMEM);
+
+	id_priv->state = CMA_IDLE;
+	id_priv->id.context = context;
+	id_priv->id.event_handler = event_handler;
+	id_priv->id.ps = ps;
+	spin_lock_init(&id_priv->lock);
+	init_completion(&id_priv->comp);
+	atomic_set(&id_priv->refcount, 1);
+	init_waitqueue_head(&id_priv->wait_remove);
+	atomic_set(&id_priv->dev_remove, 0);
+	INIT_LIST_HEAD(&id_priv->listen_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)
+{
+	struct ib_qp_attr qp_attr;
+	struct rdma_dev_addr *dev_addr;
+	int 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);
+	if (ret)
+		return ret;
+
+	qp_attr.qp_state = IB_QPS_INIT;
+	qp_attr.qp_access_flags = IB_ACCESS_LOCAL_WRITE;
+	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);
+}
+
+int rdma_create_qp(struct rdma_cm_id *id, struct ib_pd *pd,
+		   struct ib_qp_init_attr *qp_init_attr)
+{
+	struct rdma_id_private *id_priv;
+	struct ib_qp *qp;
+	int ret;
+
+	id_priv = container_of(id, struct rdma_id_private, id);
+	if (id->device != pd->device)
+		return -EINVAL;
+
+	qp = ib_create_qp(pd, qp_init_attr);
+	if (IS_ERR(qp))
+		return PTR_ERR(qp);
+
+	switch (id->device->node_type) {
+	case IB_NODE_CA:
+		ret = cma_init_ib_qp(id_priv, qp);
+		break;
+	default:
+		ret = -ENOSYS;
+		break;
+	}
+
+	if (ret)
+		goto err;
+
+	id->qp = qp;
+	id_priv->qp_num = qp->qp_num;
+	id_priv->qp_type = qp->qp_type;
+	id_priv->srq = (qp->srq != NULL);
+	return 0;
+err:
+	ib_destroy_qp(qp);
+	return ret;
+}
+EXPORT_SYMBOL(rdma_create_qp);
+
+void rdma_destroy_qp(struct rdma_cm_id *id)
+{
+	ib_destroy_qp(id->qp);
+}
+EXPORT_SYMBOL(rdma_destroy_qp);
+
+static int cma_modify_qp_rtr(struct rdma_cm_id *id)
+{
+	struct ib_qp_attr qp_attr;
+	int qp_attr_mask, ret;
+
+	if (!id->qp)
+		return 0;
+
+	/* Need to update QP attributes from default values. */
+	qp_attr.qp_state = IB_QPS_INIT;
+	ret = rdma_init_qp_attr(id, &qp_attr, &qp_attr_mask);
+	if (ret)
+		return ret;
+
+	ret = ib_modify_qp(id->qp, &qp_attr, qp_attr_mask);
+	if (ret)
+		return ret;
+
+	qp_attr.qp_state = IB_QPS_RTR;
+	ret = rdma_init_qp_attr(id, &qp_attr, &qp_attr_mask);
+	if (ret)
+		return ret;
+
+	return ib_modify_qp(id->qp, &qp_attr, qp_attr_mask);
+}
+
+static int cma_modify_qp_rts(struct rdma_cm_id *id)
+{
+	struct ib_qp_attr qp_attr;
+	int qp_attr_mask, ret;
+
+	if (!id->qp)
+		return 0;
+
+	qp_attr.qp_state = IB_QPS_RTS;
+	ret = rdma_init_qp_attr(id, &qp_attr, &qp_attr_mask);
+	if (ret)
+		return ret;
+
+	return ib_modify_qp(id->qp, &qp_attr, qp_attr_mask);
+}
+
+static int cma_modify_qp_err(struct rdma_cm_id *id)
+{
+	struct ib_qp_attr qp_attr;
+
+	if (!id->qp)
+		return 0;
+
+	qp_attr.qp_state = IB_QPS_ERR;
+	return ib_modify_qp(id->qp, &qp_attr, IB_QP_STATE);
+}
+
+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;
+
+	id_priv = container_of(id, struct rdma_id_private, id);
+	switch (id_priv->id.device->node_type) {
+	case IB_NODE_CA:
+		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;
+	default:
+		ret = -ENOSYS;
+		break;
+	}
+
+	return ret;
+}
+EXPORT_SYMBOL(rdma_init_qp_attr);
+
+static inline int cma_zero_addr(struct sockaddr *addr)
+{
+	struct in6_addr *ip6;
+
+	if (addr->sa_family == AF_INET)
+		return ZERONET(((struct sockaddr_in *) addr)->sin_addr.s_addr);
+	else {
+		ip6 = &((struct sockaddr_in6 *) addr)->sin6_addr;
+		return (ip6->s6_addr32[0] | ip6->s6_addr32[1] |
+			ip6->s6_addr32[2] | ip6->s6_addr32[3]) == 0;
+	}
+}
+
+static inline int cma_loopback_addr(struct sockaddr *addr)
+{
+	return LOOPBACK(((struct sockaddr_in *) addr)->sin_addr.s_addr);
+}
+
+static inline int cma_any_addr(struct sockaddr *addr)
+{
+	return cma_zero_addr(addr) || cma_loopback_addr(addr);
+}
+
+static inline int cma_any_port(struct sockaddr *addr)
+{
+	return !((struct sockaddr_in *) addr)->sin_port;
+}
+
+static int cma_get_net_info(void *hdr, enum rdma_port_space ps,
+			    u8 *ip_ver, __u16 *port,
+			    union cma_ip_addr **src, union cma_ip_addr **dst)
+{
+	switch (ps) {
+	case RDMA_PS_SDP:
+		if (sdp_get_majv(((struct sdp_hh *) hdr)->sdp_version) !=
+		    SDP_MAJ_VERSION)
+			return -EINVAL;
+
+		*ip_ver	= sdp_get_ip_ver(hdr);
+		*port	= ((struct sdp_hh *) hdr)->port;
+		*src	= &((struct sdp_hh *) hdr)->src_addr;
+		*dst	= &((struct sdp_hh *) hdr)->dst_addr;
+		break;
+	default:
+		if (((struct cma_hdr *) hdr)->cma_version != CMA_VERSION)
+			return -EINVAL;
+
+		*ip_ver	= cma_get_ip_ver(hdr);
+		*port	= ((struct cma_hdr *) hdr)->port;
+		*src	= &((struct cma_hdr *) hdr)->src_addr;
+		*dst	= &((struct cma_hdr *) hdr)->dst_addr;
+		break;
+	}
+
+	if (*ip_ver != 4 && *ip_ver != 6)
+		return -EINVAL;
+	return 0;
+}
+
+static void cma_save_net_info(struct rdma_addr *addr,
+			      struct rdma_addr *listen_addr,
+			      u8 ip_ver, __u16 port,
+			      union cma_ip_addr *src, union cma_ip_addr *dst)
+{
+	struct sockaddr_in *listen4, *ip4;
+	struct sockaddr_in6 *listen6, *ip6;
+
+	switch (ip_ver) {
+	case 4:
+		listen4 = (struct sockaddr_in *) &listen_addr->src_addr;
+		ip4 = (struct sockaddr_in *) &addr->src_addr;
+		ip4->sin_family = listen4->sin_family;
+		ip4->sin_addr.s_addr = dst->ip4.addr;
+		ip4->sin_port = listen4->sin_port;
+
+		ip4 = (struct sockaddr_in *) &addr->dst_addr;
+		ip4->sin_family = listen4->sin_family;
+		ip4->sin_addr.s_addr = src->ip4.addr;
+		ip4->sin_port = port;
+		break;
+	case 6:
+		listen6 = (struct sockaddr_in6 *) &listen_addr->src_addr;
+		ip6 = (struct sockaddr_in6 *) &addr->src_addr;
+		ip6->sin6_family = listen6->sin6_family;
+		ip6->sin6_addr = dst->ip6;
+		ip6->sin6_port = listen6->sin6_port;
+
+		ip6 = (struct sockaddr_in6 *) &addr->dst_addr;
+		ip6->sin6_family = listen6->sin6_family;
+		ip6->sin6_addr = src->ip6;
+		ip6->sin6_port = port;
+		break;
+	default:
+		break;
+	}
+}
+
+static inline int cma_user_data_offset(enum rdma_port_space ps)
+{
+	switch (ps) {
+	case RDMA_PS_SDP:
+		return 0;
+	default:
+		return sizeof(struct cma_hdr);
+	}
+}
+
+static int cma_notify_user(struct rdma_id_private *id_priv,
+			   enum rdma_cm_event_type type, int status,
+			   void *data, u8 data_len)
+{
+	struct rdma_cm_event event;
+
+	event.event = type;
+	event.status = status;
+	event.private_data = data;
+	event.private_data_len = data_len;
+
+	return id_priv->id.event_handler(&id_priv->id, &event);
+}
+
+static void cma_cancel_route(struct rdma_id_private *id_priv)
+{
+	switch (id_priv->id.device->node_type) {
+	case IB_NODE_CA:
+		if (id_priv->query)
+			ib_sa_cancel_query(id_priv->query_id, id_priv->query);
+		break;
+	default:
+		break;
+	}
+}
+
+static inline int cma_internal_listen(struct rdma_id_private *id_priv)
+{
+	return (id_priv->state == CMA_LISTEN) && id_priv->cma_dev &&
+	       cma_any_addr(&id_priv->id.route.addr.src_addr);
+}
+
+static void cma_destroy_listen(struct rdma_id_private *id_priv)
+{
+	cma_exch(id_priv, CMA_DESTROYING);
+
+	if (id_priv->cma_dev) {
+		switch (id_priv->id.device->node_type) {
+		case IB_NODE_CA:
+	 		if (id_priv->cm_id.ib && !IS_ERR(id_priv->cm_id.ib))
+				ib_destroy_cm_id(id_priv->cm_id.ib);
+			break;
+		default:
+			break;
+		}
+		cma_detach_from_dev(id_priv);
+	}
+	list_del(&id_priv->listen_list);
+
+	cma_deref_id(id_priv);
+	wait_for_completion(&id_priv->comp);
+
+	kfree(id_priv);
+}
+
+static void cma_cancel_listens(struct rdma_id_private *id_priv)
+{
+	struct rdma_id_private *dev_id_priv;
+
+	mutex_lock(&lock);
+	list_del(&id_priv->list);
+
+	while (!list_empty(&id_priv->listen_list)) {
+		dev_id_priv = list_entry(id_priv->listen_list.next,
+					 struct rdma_id_private, listen_list);
+		cma_destroy_listen(dev_id_priv);
+	}
+	mutex_unlock(&lock);
+}
+
+static void cma_cancel_operation(struct rdma_id_private *id_priv,
+				 enum cma_state state)
+{
+	switch (state) {
+	case CMA_ADDR_QUERY:
+		rdma_addr_cancel(&id_priv->id.route.addr.dev_addr);
+		break;
+	case CMA_ROUTE_QUERY:
+		cma_cancel_route(id_priv);
+		break;
+	case CMA_LISTEN:
+		if (cma_any_addr(&id_priv->id.route.addr.src_addr) &&
+		    !id_priv->cma_dev)
+			cma_cancel_listens(id_priv);
+		break;
+	default:
+		break;
+	}
+}
+
+static void cma_release_port(struct rdma_id_private *id_priv)
+{
+	struct rdma_bind_list *bind_list = id_priv->bind_list;
+
+	if (!bind_list)
+		return;
+
+	mutex_lock(&lock);
+	hlist_del(&id_priv->node);
+	if (hlist_empty(&bind_list->owners)) {
+		idr_remove(bind_list->ps, bind_list->port);
+		kfree(bind_list);
+	}
+	mutex_unlock(&lock);
+}
+
+void rdma_destroy_id(struct rdma_cm_id *id)
+{
+	struct rdma_id_private *id_priv;
+	enum cma_state state;
+
+	id_priv = container_of(id, struct rdma_id_private, id);
+	state = cma_exch(id_priv, CMA_DESTROYING);
+	cma_cancel_operation(id_priv, state);
+
+	if (id_priv->cma_dev) {
+		switch (id->device->node_type) {
+		case IB_NODE_CA:
+	 		if (id_priv->cm_id.ib && !IS_ERR(id_priv->cm_id.ib))
+				ib_destroy_cm_id(id_priv->cm_id.ib);
+			break;
+		default:
+			break;
+		}
+	  	mutex_lock(&lock);
+		cma_detach_from_dev(id_priv);
+		mutex_unlock(&lock);
+	}
+
+	cma_release_port(id_priv);
+	cma_deref_id(id_priv);
+	wait_for_completion(&id_priv->comp);
+
+	kfree(id_priv->id.route.path_rec);
+	kfree(id_priv);
+}
+EXPORT_SYMBOL(rdma_destroy_id);
+
+static int cma_rep_recv(struct rdma_id_private *id_priv)
+{
+	int ret;
+
+	ret = cma_modify_qp_rtr(&id_priv->id);
+	if (ret)
+		goto reject;
+
+	ret = cma_modify_qp_rts(&id_priv->id);
+	if (ret)
+		goto reject;
+
+	ret = ib_send_cm_rtu(id_priv->cm_id.ib, NULL, 0);
+	if (ret)
+		goto reject;
+
+	return 0;
+reject:
+	cma_modify_qp_err(&id_priv->id);
+	ib_send_cm_rej(id_priv->cm_id.ib, IB_CM_REJ_CONSUMER_DEFINED,
+		       NULL, 0, NULL, 0);
+	return ret;
+}
+
+static int cma_verify_rep(struct rdma_id_private *id_priv, void *data)
+{
+	if (id_priv->id.ps == RDMA_PS_SDP &&
+	    sdp_get_majv(((struct sdp_hah *) data)->sdp_version) !=
+	    SDP_MAJ_VERSION)
+		return -EINVAL;
+
+	return 0;
+}
+
+static int cma_rtu_recv(struct rdma_id_private *id_priv)
+{
+	int ret;
+
+	ret = cma_modify_qp_rts(&id_priv->id);
+	if (ret)
+		goto reject;
+
+	return 0;
+reject:
+	cma_modify_qp_err(&id_priv->id);
+	ib_send_cm_rej(id_priv->cm_id.ib, IB_CM_REJ_CONSUMER_DEFINED,
+		       NULL, 0, NULL, 0);
+	return ret;
+}
+
+static int cma_ib_handler(struct ib_cm_id *cm_id, struct ib_cm_event *ib_event)
+{
+	struct rdma_id_private *id_priv = cm_id->context;
+	enum rdma_cm_event_type event;
+	u8 private_data_len = 0;
+	int ret = 0, status = 0;
+
+	atomic_inc(&id_priv->dev_remove);
+	if (!cma_comp(id_priv, CMA_CONNECT))
+		goto out;
+
+	switch (ib_event->event) {
+	case IB_CM_REQ_ERROR:
+	case IB_CM_REP_ERROR:
+		event = RDMA_CM_EVENT_UNREACHABLE;
+		status = -ETIMEDOUT;
+		break;
+	case IB_CM_REP_RECEIVED:
+		status = cma_verify_rep(id_priv, ib_event->private_data);
+		if (status)
+			event = RDMA_CM_EVENT_CONNECT_ERROR;
+		else if (id_priv->id.qp && id_priv->id.ps != RDMA_PS_SDP) {
+			status = cma_rep_recv(id_priv);
+			event = status ? RDMA_CM_EVENT_CONNECT_ERROR :
+					 RDMA_CM_EVENT_ESTABLISHED;
+		} else
+			event = RDMA_CM_EVENT_CONNECT_RESPONSE;
+		private_data_len = IB_CM_REP_PRIVATE_DATA_SIZE;
+		break;
+	case IB_CM_RTU_RECEIVED:
+		status = cma_rtu_recv(id_priv);
+		event = status ? RDMA_CM_EVENT_CONNECT_ERROR :
+				 RDMA_CM_EVENT_ESTABLISHED;
+		break;
+	case IB_CM_DREQ_ERROR:
+		status = -ETIMEDOUT; /* fall through */
+	case IB_CM_DREQ_RECEIVED:
+	case IB_CM_DREP_RECEIVED:
+		if (!cma_comp_exch(id_priv, CMA_CONNECT, CMA_DISCONNECT))
+			goto out;
+		event = RDMA_CM_EVENT_DISCONNECTED;
+		break;
+	case IB_CM_TIMEWAIT_EXIT:
+	case IB_CM_MRA_RECEIVED:
+		/* ignore event */
+		goto out;
+	case IB_CM_REJ_RECEIVED:
+		cma_modify_qp_err(&id_priv->id);
+		status = ib_event->param.rej_rcvd.reason;
+		event = RDMA_CM_EVENT_REJECTED;
+		private_data_len = IB_CM_REJ_PRIVATE_DATA_SIZE;
+		break;
+	default:
+		printk(KERN_ERR "RDMA CMA: unexpected IB CM event: %d",
+		       ib_event->event);
+		goto out;
+	}
+
+	ret = cma_notify_user(id_priv, event, status, ib_event->private_data,
+			      private_data_len);
+	if (ret) {
+		/* Destroy the CM ID by returning a non-zero value. */
+		id_priv->cm_id.ib = NULL;
+		cma_exch(id_priv, CMA_DESTROYING);
+		cma_release_remove(id_priv);
+		rdma_destroy_id(&id_priv->id);
+		return ret;
+	}
+out:
+	cma_release_remove(id_priv);
+	return ret;
+}
+
+static struct rdma_id_private *cma_new_id(struct rdma_cm_id *listen_id,
+					  struct ib_cm_event *ib_event)
+{
+	struct rdma_id_private *id_priv;
+	struct rdma_cm_id *id;
+	struct rdma_route *rt;
+	union cma_ip_addr *src, *dst;
+	__u16 port;
+	u8 ip_ver;
+
+	id = rdma_create_id(listen_id->event_handler, listen_id->context,
+			    listen_id->ps);
+	if (IS_ERR(id))
+		return NULL;
+
+	rt = &id->route;
+	rt->num_paths = ib_event->param.req_rcvd.alternate_path ? 2 : 1;
+	rt->path_rec = kmalloc(sizeof *rt->path_rec * rt->num_paths, GFP_KERNEL);
+	if (!rt->path_rec)
+		goto err;
+
+	if (cma_get_net_info(ib_event->private_data, listen_id->ps,
+			     &ip_ver, &port, &src, &dst))
+		goto err;
+
+	cma_save_net_info(&id->route.addr, &listen_id->route.addr,
+			  ip_ver, port, src, dst);
+	rt->path_rec[0] = *ib_event->param.req_rcvd.primary_path;
+	if (rt->num_paths == 2)
+		rt->path_rec[1] = *ib_event->param.req_rcvd.alternate_path;
+
+	ib_addr_set_sgid(&rt->addr.dev_addr, &rt->path_rec[0].sgid);
+	ib_addr_set_dgid(&rt->addr.dev_addr, &rt->path_rec[0].dgid);
+	ib_addr_set_pkey(&rt->addr.dev_addr, be16_to_cpu(rt->path_rec[0].pkey));
+	rt->addr.dev_addr.dev_type = IB_NODE_CA;
+
+	id_priv = container_of(id, struct rdma_id_private, id);
+	id_priv->state = CMA_CONNECT;
+	return id_priv;
+err:
+	rdma_destroy_id(id);
+	return NULL;
+}
+
+static int cma_req_handler(struct ib_cm_id *cm_id, struct ib_cm_event *ib_event)
+{
+	struct rdma_id_private *listen_id, *conn_id;
+	int offset, ret;
+
+	listen_id = cm_id->context;
+	atomic_inc(&listen_id->dev_remove);
+	if (!cma_comp(listen_id, CMA_LISTEN)) {
+		ret = -ECONNABORTED;
+		goto out;
+	}
+
+	conn_id = cma_new_id(&listen_id->id, ib_event);
+	if (!conn_id) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	atomic_inc(&conn_id->dev_remove);
+	ret = cma_acquire_ib_dev(conn_id);
+	if (ret) {
+		ret = -ENODEV;
+		cma_release_remove(conn_id);
+		rdma_destroy_id(&conn_id->id);
+		goto out;
+	}
+
+	conn_id->cm_id.ib = cm_id;
+	cm_id->context = conn_id;
+	cm_id->cm_handler = cma_ib_handler;
+
+	offset = cma_user_data_offset(listen_id->id.ps);
+	ret = cma_notify_user(conn_id, RDMA_CM_EVENT_CONNECT_REQUEST, 0,
+			      ib_event->private_data + offset,
+			      IB_CM_REQ_PRIVATE_DATA_SIZE - offset);
+	if (ret) {
+		/* Destroy the CM ID by returning a non-zero value. */
+		conn_id->cm_id.ib = NULL;
+		cma_exch(conn_id, CMA_DESTROYING);
+		cma_release_remove(conn_id);
+		rdma_destroy_id(&conn_id->id);
+	}
+out:
+	cma_release_remove(listen_id);
+	return ret;
+}
+
+static __be64 cma_get_service_id(enum rdma_port_space ps, struct sockaddr *addr)
+{
+	return cpu_to_be64(((u64)ps << 16) +
+	       be16_to_cpu(((struct sockaddr_in *) addr)->sin_port));
+}
+
+static void cma_set_compare_data(enum rdma_port_space ps, struct sockaddr *addr,
+				 struct ib_cm_compare_data *compare)
+{
+	struct cma_hdr *cma_data, *cma_mask;
+	struct sdp_hh *sdp_data, *sdp_mask;
+	__u32 ip4_addr;
+	struct in6_addr ip6_addr;
+
+	memset(compare, 0, sizeof *compare);
+	cma_data = (void *) compare->data;
+	cma_mask = (void *) compare->mask;
+	sdp_data = (void *) compare->data;
+	sdp_mask = (void *) compare->mask;
+
+	switch (addr->sa_family) {
+	case AF_INET:
+		ip4_addr = ((struct sockaddr_in *) addr)->sin_addr.s_addr;
+		if (ps == RDMA_PS_SDP) {
+			sdp_set_ip_ver(sdp_data, 4);
+			sdp_set_ip_ver(sdp_mask, 0xF);
+			sdp_data->dst_addr.ip4.addr = ip4_addr;
+			sdp_mask->dst_addr.ip4.addr = ~0;
+		} else {
+			cma_set_ip_ver(cma_data, 4);
+			cma_set_ip_ver(cma_mask, 0xF);
+			cma_data->dst_addr.ip4.addr = ip4_addr;
+			cma_mask->dst_addr.ip4.addr = ~0;
+		}
+		break;
+	case AF_INET6:
+		ip6_addr = ((struct sockaddr_in6 *) addr)->sin6_addr;
+		if (ps == RDMA_PS_SDP) {
+			sdp_set_ip_ver(sdp_data, 6);
+			sdp_set_ip_ver(sdp_mask, 0xF);
+			sdp_data->dst_addr.ip6 = ip6_addr;
+			memset(&sdp_mask->dst_addr.ip6, 0xFF,
+			       sizeof sdp_mask->dst_addr.ip6);
+		} else {
+			cma_set_ip_ver(cma_data, 6);
+			cma_set_ip_ver(cma_mask, 0xF);
+			cma_data->dst_addr.ip6 = ip6_addr;
+			memset(&cma_mask->dst_addr.ip6, 0xFF,
+			       sizeof cma_mask->dst_addr.ip6);
+		}
+		break;
+	default:
+		break;
+	}
+}
+
+static int cma_ib_listen(struct rdma_id_private *id_priv)
+{
+	struct ib_cm_compare_data compare_data;
+	struct sockaddr *addr;
+	__be64 svc_id;
+	int ret;
+
+	id_priv->cm_id.ib = ib_create_cm_id(id_priv->id.device, cma_req_handler,
+					    id_priv);
+	if (IS_ERR(id_priv->cm_id.ib))
+		return PTR_ERR(id_priv->cm_id.ib);
+
+	addr = &id_priv->id.route.addr.src_addr;
+	svc_id = cma_get_service_id(id_priv->id.ps, addr);
+	if (cma_any_addr(addr))
+		ret = ib_cm_listen(id_priv->cm_id.ib, svc_id, 0, NULL);
+	else {
+		cma_set_compare_data(id_priv->id.ps, addr, &compare_data);
+		ret = ib_cm_listen(id_priv->cm_id.ib, svc_id, 0, &compare_data);
+	}
+
+	if (ret) {
+		ib_destroy_cm_id(id_priv->cm_id.ib);
+		id_priv->cm_id.ib = NULL;
+	}
+
+	return ret;
+}
+
+static int cma_listen_handler(struct rdma_cm_id *id,
+			      struct rdma_cm_event *event)
+{
+	struct rdma_id_private *id_priv = id->context;
+
+	id->context = id_priv->id.context;
+	id->event_handler = id_priv->id.event_handler;
+	return id_priv->id.event_handler(id, event);
+}
+
+static void cma_listen_on_dev(struct rdma_id_private *id_priv,
+			      struct cma_device *cma_dev)
+{
+	struct rdma_id_private *dev_id_priv;
+	struct rdma_cm_id *id;
+	int ret;
+
+	id = rdma_create_id(cma_listen_handler, id_priv, id_priv->id.ps);
+	if (IS_ERR(id))
+		return;
+
+	dev_id_priv = container_of(id, struct rdma_id_private, id);
+
+	dev_id_priv->state = CMA_ADDR_BOUND;
+	memcpy(&id->route.addr.src_addr, &id_priv->id.route.addr.src_addr,
+	       ip_addr_size(&id_priv->id.route.addr.src_addr));
+
+	cma_attach_to_dev(dev_id_priv, cma_dev);
+	list_add_tail(&dev_id_priv->listen_list, &id_priv->listen_list);
+
+	ret = rdma_listen(id, id_priv->backlog);
+	if (ret)
+		goto err;
+
+	return;
+err:
+	cma_destroy_listen(dev_id_priv);
+}
+
+static void cma_listen_on_all(struct rdma_id_private *id_priv)
+{
+	struct cma_device *cma_dev;
+
+	mutex_lock(&lock);
+	list_add_tail(&id_priv->list, &listen_any_list);
+	list_for_each_entry(cma_dev, &dev_list, list)
+		cma_listen_on_dev(id_priv, cma_dev);
+	mutex_unlock(&lock);
+}
+
+static int cma_bind_any(struct rdma_cm_id *id, sa_family_t af)
+{
+	struct sockaddr_in addr_in;
+
+	memset(&addr_in, 0, sizeof addr_in);
+	addr_in.sin_family = af;
+	return rdma_bind_addr(id, (struct sockaddr *) &addr_in);
+}
+
+int rdma_listen(struct rdma_cm_id *id, int backlog)
+{
+	struct rdma_id_private *id_priv;
+	int ret;
+
+	id_priv = container_of(id, struct rdma_id_private, id);
+	if (id_priv->state == CMA_IDLE) {
+		ret = cma_bind_any(id, AF_INET);
+		if (ret)
+			return ret;
+	}
+
+	if (!cma_comp_exch(id_priv, CMA_ADDR_BOUND, CMA_LISTEN))
+		return -EINVAL;
+
+	id_priv->backlog = backlog;
+	if (id->device) {
+		switch (id->device->node_type) {
+		case IB_NODE_CA:
+			ret = cma_ib_listen(id_priv);
+			if (ret)
+				goto err;
+			break;
+		default:
+			ret = -ENOSYS;
+			goto err;
+		}
+	} else
+		cma_listen_on_all(id_priv);
+
+	return 0;
+err:
+	id_priv->backlog = 0;
+	cma_comp_exch(id_priv, CMA_LISTEN, CMA_ADDR_BOUND);
+	return ret;
+}
+EXPORT_SYMBOL(rdma_listen);
+
+static void cma_query_handler(int status, struct ib_sa_path_rec *path_rec,
+			      void *context)
+{
+	struct cma_work *work = context;
+	struct rdma_route *route;
+
+	route = &work->id->id.route;
+
+	if (!status) {
+		route->num_paths = 1;
+		*route->path_rec = *path_rec;
+	} else {
+		work->old_state = CMA_ROUTE_QUERY;
+		work->new_state = CMA_ADDR_RESOLVED;
+		work->event.event = RDMA_CM_EVENT_ROUTE_ERROR;
+	}
+
+	queue_work(cma_wq, &work->work);
+}
+
+static int cma_query_ib_route(struct rdma_id_private *id_priv, int timeout_ms,
+			      struct cma_work *work)
+{
+	struct rdma_dev_addr *addr = &id_priv->id.route.addr.dev_addr;
+	struct ib_sa_path_rec path_rec;
+
+	memset(&path_rec, 0, sizeof path_rec);
+	ib_addr_get_sgid(addr, &path_rec.sgid);
+	ib_addr_get_dgid(addr, &path_rec.dgid);
+	path_rec.pkey = cpu_to_be16(ib_addr_get_pkey(addr));
+	path_rec.numb_path = 1;
+
+	id_priv->query_id = ib_sa_path_rec_get(id_priv->id.device,
+				id_priv->id.port_num, &path_rec,
+				IB_SA_PATH_REC_DGID | IB_SA_PATH_REC_SGID |
+				IB_SA_PATH_REC_PKEY | IB_SA_PATH_REC_NUMB_PATH,
+				timeout_ms, GFP_KERNEL,
+				cma_query_handler, work, &id_priv->query);
+
+	return (id_priv->query_id < 0) ? id_priv->query_id : 0;
+}
+
+static void cma_work_handler(void *data)
+{
+	struct cma_work *work = data;
+	struct rdma_id_private *id_priv = work->id;
+	int destroy = 0;
+
+	atomic_inc(&id_priv->dev_remove);
+	if (!cma_comp_exch(id_priv, work->old_state, work->new_state))
+		goto out;
+
+	if (id_priv->id.event_handler(&id_priv->id, &work->event)) {
+		cma_exch(id_priv, CMA_DESTROYING);
+		destroy = 1;
+	}
+out:
+	cma_release_remove(id_priv);
+	cma_deref_id(id_priv);
+	if (destroy)
+		rdma_destroy_id(&id_priv->id);
+	kfree(work);
+}
+
+static int cma_resolve_ib_route(struct rdma_id_private *id_priv, int timeout_ms)
+{
+	struct rdma_route *route = &id_priv->id.route;
+	struct cma_work *work;
+	int ret;
+
+	work = kzalloc(sizeof *work, GFP_KERNEL);
+	if (!work)
+		return -ENOMEM;
+
+	work->id = id_priv;
+	INIT_WORK(&work->work, cma_work_handler, work);
+	work->old_state = CMA_ROUTE_QUERY;
+	work->new_state = CMA_ROUTE_RESOLVED;
+	work->event.event = RDMA_CM_EVENT_ROUTE_RESOLVED;
+
+	route->path_rec = kmalloc(sizeof *route->path_rec, GFP_KERNEL);
+	if (!route->path_rec) {
+		ret = -ENOMEM;
+		goto err1;
+	}
+
+	ret = cma_query_ib_route(id_priv, timeout_ms, work);
+	if (ret)
+		goto err2;
+
+	return 0;
+err2:
+	kfree(route->path_rec);
+	route->path_rec = NULL;
+err1:
+	kfree(work);
+	return ret;
+}
+
+int rdma_set_ib_paths(struct rdma_cm_id *id,
+		      struct ib_sa_path_rec *path_rec, int num_paths)
+{
+	struct rdma_id_private *id_priv;
+	int ret;
+
+	id_priv = container_of(id, struct rdma_id_private, id);
+	if (!cma_comp_exch(id_priv, CMA_ADDR_RESOLVED, CMA_ROUTE_RESOLVED))
+		return -EINVAL;
+
+	id->route.path_rec = kmalloc(sizeof *path_rec * num_paths, GFP_KERNEL);
+	if (!id->route.path_rec) {
+		ret = -ENOMEM;
+		goto err;
+	}
+
+	memcpy(id->route.path_rec, path_rec, sizeof *path_rec * num_paths);
+	return 0;
+err:
+	cma_comp_exch(id_priv, CMA_ROUTE_RESOLVED, CMA_ADDR_RESOLVED);
+	return ret;
+}
+EXPORT_SYMBOL(rdma_set_ib_paths);
+
+int rdma_resolve_route(struct rdma_cm_id *id, int timeout_ms)
+{
+	struct rdma_id_private *id_priv;
+	int ret;
+
+	id_priv = container_of(id, struct rdma_id_private, id);
+	if (!cma_comp_exch(id_priv, CMA_ADDR_RESOLVED, CMA_ROUTE_QUERY))
+		return -EINVAL;
+
+	atomic_inc(&id_priv->refcount);
+	switch (id->device->node_type) {
+	case IB_NODE_CA:
+		ret = cma_resolve_ib_route(id_priv, timeout_ms);
+		break;
+	default:
+		ret = -ENOSYS;
+		break;
+	}
+	if (ret)
+		goto err;
+
+	return 0;
+err:
+	cma_comp_exch(id_priv, CMA_ROUTE_QUERY, CMA_ADDR_RESOLVED);
+	cma_deref_id(id_priv);
+	return ret;
+}
+EXPORT_SYMBOL(rdma_resolve_route);
+
+static int cma_bind_loopback(struct rdma_id_private *id_priv)
+{
+	struct cma_device *cma_dev;
+	struct ib_port_attr port_attr;
+	union ib_gid gid;
+	u16 pkey;
+	int ret;
+	u8 p;
+
+	mutex_lock(&lock);
+	list_for_each_entry(cma_dev, &dev_list, list)
+		for (p = 1; p <= cma_dev->device->phys_port_cnt; ++p)
+			if (!ib_query_port (cma_dev->device, p, &port_attr) &&
+			    port_attr.state == IB_PORT_ACTIVE)
+				goto port_found;
+
+	if (!list_empty(&dev_list)) {
+		p = 1;
+		cma_dev = list_entry(dev_list.next, struct cma_device, list);
+	} else {
+		ret = -ENODEV;
+		goto out;
+	}
+
+port_found:
+	ret = ib_get_cached_gid(cma_dev->device, p, 0, &gid);
+	if (ret)
+		goto out;
+
+	ret = ib_get_cached_pkey(cma_dev->device, p, 0, &pkey);
+	if (ret)
+		goto out;
+
+	ib_addr_set_sgid(&id_priv->id.route.addr.dev_addr, &gid);
+	ib_addr_set_pkey(&id_priv->id.route.addr.dev_addr, pkey);
+	id_priv->id.port_num = p;
+	cma_attach_to_dev(id_priv, cma_dev);
+out:
+	mutex_unlock(&lock);
+	return ret;
+}
+
+static void addr_handler(int status, struct sockaddr *src_addr,
+			 struct rdma_dev_addr *dev_addr, void *context)
+{
+	struct rdma_id_private *id_priv = context;
+	enum rdma_cm_event_type event;
+
+	atomic_inc(&id_priv->dev_remove);
+	if (!id_priv->cma_dev && !status)
+		status = cma_acquire_dev(id_priv);
+
+	if (status) {
+		if (!cma_comp_exch(id_priv, CMA_ADDR_QUERY, CMA_ADDR_BOUND))
+			goto out;
+		event = RDMA_CM_EVENT_ADDR_ERROR;
+	} else {
+		if (!cma_comp_exch(id_priv, CMA_ADDR_QUERY, CMA_ADDR_RESOLVED))
+			goto out;
+		memcpy(&id_priv->id.route.addr.src_addr, src_addr,
+		       ip_addr_size(src_addr));
+		event = RDMA_CM_EVENT_ADDR_RESOLVED;
+	}
+
+	if (cma_notify_user(id_priv, event, status, NULL, 0)) {
+		cma_exch(id_priv, CMA_DESTROYING);
+		cma_release_remove(id_priv);
+		cma_deref_id(id_priv);
+		rdma_destroy_id(&id_priv->id);
+		return;
+	}
+out:
+	cma_release_remove(id_priv);
+	cma_deref_id(id_priv);
+}
+
+static int cma_resolve_loopback(struct rdma_id_private *id_priv)
+{
+	struct cma_work *work;
+	struct sockaddr_in *src_in, *dst_in;
+	union ib_gid gid;
+	int ret;
+
+	work = kzalloc(sizeof *work, GFP_KERNEL);
+	if (!work)
+		return -ENOMEM;
+
+	if (!id_priv->cma_dev) {
+		ret = cma_bind_loopback(id_priv);
+		if (ret)
+			goto err;
+	}
+
+	ib_addr_get_sgid(&id_priv->id.route.addr.dev_addr, &gid);
+	ib_addr_set_dgid(&id_priv->id.route.addr.dev_addr, &gid);
+
+	if (cma_zero_addr(&id_priv->id.route.addr.src_addr)) {
+		src_in = (struct sockaddr_in *)&id_priv->id.route.addr.src_addr;
+		dst_in = (struct sockaddr_in *)&id_priv->id.route.addr.dst_addr;
+		src_in->sin_family = dst_in->sin_family;
+		src_in->sin_addr.s_addr = dst_in->sin_addr.s_addr;
+	}
+
+	work->id = id_priv;
+	INIT_WORK(&work->work, cma_work_handler, work);
+	work->old_state = CMA_ADDR_QUERY;
+	work->new_state = CMA_ADDR_RESOLVED;
+	work->event.event = RDMA_CM_EVENT_ADDR_RESOLVED;
+	queue_work(cma_wq, &work->work);
+	return 0;
+err:
+	kfree(work);
+	return ret;
+}
+
+static int cma_bind_addr(struct rdma_cm_id *id, struct sockaddr *src_addr,
+			 struct sockaddr *dst_addr)
+{
+	if (src_addr && src_addr->sa_family)
+		return rdma_bind_addr(id, src_addr);
+	else
+		return cma_bind_any(id, dst_addr->sa_family);
+}
+
+int rdma_resolve_addr(struct rdma_cm_id *id, struct sockaddr *src_addr,
+		      struct sockaddr *dst_addr, int timeout_ms)
+{
+	struct rdma_id_private *id_priv;
+	int ret;
+
+	id_priv = container_of(id, struct rdma_id_private, id);
+	if (id_priv->state == CMA_IDLE) {
+		ret = cma_bind_addr(id, src_addr, dst_addr);
+		if (ret)
+			return ret;
+	}
+
+	if (!cma_comp_exch(id_priv, CMA_ADDR_BOUND, CMA_ADDR_QUERY))
+		return -EINVAL;
+
+	atomic_inc(&id_priv->refcount);
+	memcpy(&id->route.addr.dst_addr, dst_addr, ip_addr_size(dst_addr));
+	if (cma_any_addr(dst_addr))
+		ret = cma_resolve_loopback(id_priv);
+	else
+		ret = rdma_resolve_ip(&id->route.addr.src_addr, dst_addr,
+				      &id->route.addr.dev_addr,
+				      timeout_ms, addr_handler, id_priv);
+	if (ret)
+		goto err;
+
+	return 0;
+err:
+	cma_comp_exch(id_priv, CMA_ADDR_QUERY, CMA_ADDR_BOUND);
+	cma_deref_id(id_priv);
+	return ret;
+}
+EXPORT_SYMBOL(rdma_resolve_addr);
+
+static void cma_bind_port(struct rdma_bind_list *bind_list,
+			  struct rdma_id_private *id_priv)
+{
+	struct sockaddr_in *sin;
+
+	sin = (struct sockaddr_in *) &id_priv->id.route.addr.src_addr;
+	sin->sin_port = htons(bind_list->port);
+	id_priv->bind_list = bind_list;
+	hlist_add_head(&id_priv->node, &bind_list->owners);
+}
+
+static int cma_alloc_port(struct idr *ps, struct rdma_id_private *id_priv,
+			  unsigned short snum)
+{
+	struct rdma_bind_list *bind_list;
+	int port, start, ret;
+
+	bind_list = kzalloc(sizeof *bind_list, GFP_KERNEL);
+	if (!bind_list)
+		return -ENOMEM;
+
+	start = snum ? snum : sysctl_local_port_range[0];
+
+	do {
+		ret = idr_get_new_above(ps, bind_list, start, &port);
+	} while ((ret == -EAGAIN) && idr_pre_get(ps, GFP_KERNEL));
+
+	if (ret)
+		goto err;
+
+	if ((snum && port != snum) ||
+	    (!snum && port > sysctl_local_port_range[1])) {
+		idr_remove(ps, port);
+		ret = -EADDRNOTAVAIL;
+		goto err;
+	}
+
+	bind_list->ps = ps;
+	bind_list->port = (unsigned short) port;
+	cma_bind_port(bind_list, id_priv);
+	return 0;
+err:
+	kfree(bind_list);
+	return ret;
+}
+
+static int cma_use_port(struct idr *ps, struct rdma_id_private *id_priv)
+{
+	struct rdma_id_private *cur_id;
+	struct sockaddr_in *sin, *cur_sin;
+	struct rdma_bind_list *bind_list;
+	struct hlist_node *node;
+	unsigned short snum;
+
+	sin = (struct sockaddr_in *) &id_priv->id.route.addr.src_addr;
+	snum = ntohs(sin->sin_port);
+	if (snum < PROT_SOCK && !capable(CAP_NET_BIND_SERVICE))
+		return -EACCES;
+
+	bind_list = idr_find(ps, snum);
+	if (!bind_list)
+		return cma_alloc_port(ps, id_priv, snum);
+
+	/*
+	 * We don't support binding to any address if anyone is bound to
+	 * a specific address on the same port.
+	 */
+	if (cma_any_addr(&id_priv->id.route.addr.src_addr))
+		return -EADDRNOTAVAIL;
+
+	hlist_for_each_entry(cur_id, node, &bind_list->owners, node) {
+		if (cma_any_addr(&cur_id->id.route.addr.src_addr))
+			return -EADDRNOTAVAIL;
+		
+		cur_sin = (struct sockaddr_in *) &cur_id->id.route.addr.src_addr;
+		if (sin->sin_addr.s_addr == cur_sin->sin_addr.s_addr)
+			return -EADDRINUSE;
+	}
+
+	cma_bind_port(bind_list, id_priv);
+	return 0;
+}
+
+static int cma_get_port(struct rdma_id_private *id_priv)
+{
+	struct idr *ps;
+	int ret;
+
+	switch (id_priv->id.ps) {
+	case RDMA_PS_SDP:
+		ps = &sdp_ps;
+		break;
+	case RDMA_PS_TCP:
+		ps = &tcp_ps;
+		break;
+	default:
+		return -EPROTONOSUPPORT;
+	}
+
+	mutex_lock(&lock);
+	if (cma_any_port(&id_priv->id.route.addr.src_addr))
+		ret = cma_alloc_port(ps, id_priv, 0);
+	else
+		ret = cma_use_port(ps, id_priv);
+	mutex_unlock(&lock);
+
+	return ret;
+}
+
+int rdma_bind_addr(struct rdma_cm_id *id, struct sockaddr *addr)
+{
+	struct rdma_id_private *id_priv;
+	int ret;
+
+	if (addr->sa_family != AF_INET)
+		return -EAFNOSUPPORT;
+
+	id_priv = container_of(id, struct rdma_id_private, id);
+	if (!cma_comp_exch(id_priv, CMA_IDLE, CMA_ADDR_BOUND))
+		return -EINVAL;
+
+	if (!cma_any_addr(addr)) {
+		ret = rdma_translate_ip(addr, &id->route.addr.dev_addr);
+		if (!ret)
+			ret = cma_acquire_dev(id_priv);
+		if (ret)
+			goto err;
+	}
+
+	memcpy(&id->route.addr.src_addr, addr, ip_addr_size(addr));
+	ret = cma_get_port(id_priv);
+	if (ret)
+		goto err;
+
+	return 0;
+err:
+	cma_comp_exch(id_priv, CMA_ADDR_BOUND, CMA_IDLE);
+	return ret;
+}
+EXPORT_SYMBOL(rdma_bind_addr);
+
+static int cma_format_hdr(void *hdr, enum rdma_port_space ps,
+			  struct rdma_route *route)
+{
+	struct sockaddr_in *src4, *dst4;
+	struct cma_hdr *cma_hdr;
+	struct sdp_hh *sdp_hdr;
+
+	src4 = (struct sockaddr_in *) &route->addr.src_addr;
+	dst4 = (struct sockaddr_in *) &route->addr.dst_addr;
+
+	switch (ps) {
+	case RDMA_PS_SDP:
+		sdp_hdr = hdr;
+		if (sdp_get_majv(sdp_hdr->sdp_version) != SDP_MAJ_VERSION)
+			return -EINVAL;
+		sdp_set_ip_ver(sdp_hdr, 4);
+		sdp_hdr->src_addr.ip4.addr = src4->sin_addr.s_addr;
+		sdp_hdr->dst_addr.ip4.addr = dst4->sin_addr.s_addr;
+		sdp_hdr->port = src4->sin_port;
+		break;
+	default:
+		cma_hdr = hdr;
+		cma_hdr->cma_version = CMA_VERSION;
+		cma_set_ip_ver(cma_hdr, 4);
+		cma_hdr->src_addr.ip4.addr = src4->sin_addr.s_addr;
+		cma_hdr->dst_addr.ip4.addr = dst4->sin_addr.s_addr;
+		cma_hdr->port = src4->sin_port;
+		break;
+	}
+	return 0;
+}
+
+static int cma_connect_ib(struct rdma_id_private *id_priv,
+			  struct rdma_conn_param *conn_param)
+{
+	struct ib_cm_req_param req;
+	struct rdma_route *route;
+	void *private_data;
+	int offset, ret;
+
+	memset(&req, 0, sizeof req);
+	offset = cma_user_data_offset(id_priv->id.ps);
+	req.private_data_len = offset + conn_param->private_data_len;
+	private_data = kzalloc(req.private_data_len, GFP_ATOMIC);
+	if (!private_data)
+		return -ENOMEM;
+
+	if (conn_param->private_data && conn_param->private_data_len)
+		memcpy(private_data + offset, conn_param->private_data,
+		       conn_param->private_data_len);
+
+	id_priv->cm_id.ib = ib_create_cm_id(id_priv->id.device, cma_ib_handler,
+					    id_priv);
+	if (IS_ERR(id_priv->cm_id.ib)) {
+		ret = PTR_ERR(id_priv->cm_id.ib);
+		goto out;
+	}
+
+	route = &id_priv->id.route;
+	ret = cma_format_hdr(private_data, id_priv->id.ps, route);
+	if (ret)
+		goto out;
+	req.private_data = private_data;
+
+	req.primary_path = &route->path_rec[0];
+	if (route->num_paths == 2)
+		req.alternate_path = &route->path_rec[1];
+
+	req.service_id = cma_get_service_id(id_priv->id.ps,
+					    &route->addr.dst_addr);
+	req.qp_num = id_priv->qp_num;
+	req.qp_type = id_priv->qp_type;
+	req.starting_psn = id_priv->seq_num;
+	req.responder_resources = conn_param->responder_resources;
+	req.initiator_depth = conn_param->initiator_depth;
+	req.flow_control = conn_param->flow_control;
+	req.retry_count = conn_param->retry_count;
+	req.rnr_retry_count = conn_param->rnr_retry_count;
+	req.remote_cm_response_timeout = CMA_CM_RESPONSE_TIMEOUT;
+	req.local_cm_response_timeout = CMA_CM_RESPONSE_TIMEOUT;
+	req.max_cm_retries = CMA_MAX_CM_RETRIES;
+	req.srq = id_priv->srq ? 1 : 0;
+
+	ret = ib_send_cm_req(id_priv->cm_id.ib, &req);
+out:
+	kfree(private_data);
+	return ret;
+}
+
+int rdma_connect(struct rdma_cm_id *id, struct rdma_conn_param *conn_param)
+{
+	struct rdma_id_private *id_priv;
+	int ret;
+
+	id_priv = container_of(id, struct rdma_id_private, id);
+	if (!cma_comp_exch(id_priv, CMA_ROUTE_RESOLVED, CMA_CONNECT))
+		return -EINVAL;
+
+	if (!id->qp) {
+		id_priv->qp_num = conn_param->qp_num;
+		id_priv->qp_type = conn_param->qp_type;
+		id_priv->srq = conn_param->srq;
+	}
+
+	switch (id->device->node_type) {
+	case IB_NODE_CA:
+		ret = cma_connect_ib(id_priv, conn_param);
+		break;
+	default:
+		ret = -ENOSYS;
+		break;
+	}
+	if (ret)
+		goto err;
+
+	return 0;
+err:
+	cma_comp_exch(id_priv, CMA_CONNECT, CMA_ROUTE_RESOLVED);
+	return ret;
+}
+EXPORT_SYMBOL(rdma_connect);
+
+static int cma_accept_ib(struct rdma_id_private *id_priv,
+			 struct rdma_conn_param *conn_param)
+{
+	struct ib_cm_rep_param rep;
+	int ret;
+
+	ret = cma_modify_qp_rtr(&id_priv->id);
+	if (ret)
+		return ret;
+
+	memset(&rep, 0, sizeof rep);
+	rep.qp_num = id_priv->qp_num;
+	rep.starting_psn = id_priv->seq_num;
+	rep.private_data = conn_param->private_data;
+	rep.private_data_len = conn_param->private_data_len;
+	rep.responder_resources = conn_param->responder_resources;
+	rep.initiator_depth = conn_param->initiator_depth;
+	rep.target_ack_delay = CMA_CM_RESPONSE_TIMEOUT;
+	rep.failover_accepted = 0;
+	rep.flow_control = conn_param->flow_control;
+	rep.rnr_retry_count = conn_param->rnr_retry_count;
+	rep.srq = id_priv->srq ? 1 : 0;
+
+	return ib_send_cm_rep(id_priv->cm_id.ib, &rep);
+}
+
+int rdma_accept(struct rdma_cm_id *id, struct rdma_conn_param *conn_param)
+{
+	struct rdma_id_private *id_priv;
+	int ret;
+
+	id_priv = container_of(id, struct rdma_id_private, id);
+	if (!cma_comp(id_priv, CMA_CONNECT))
+		return -EINVAL;
+
+	if (!id->qp && conn_param) {
+		id_priv->qp_num = conn_param->qp_num;
+		id_priv->qp_type = conn_param->qp_type;
+		id_priv->srq = conn_param->srq;
+	}
+
+	switch (id->device->node_type) {
+	case IB_NODE_CA:
+		if (conn_param)
+			ret = cma_accept_ib(id_priv, conn_param);
+		else
+			ret = cma_rep_recv(id_priv);
+		break;
+	default:
+		ret = -ENOSYS;
+		break;
+	}
+
+	if (ret)
+		goto reject;
+
+	return 0;
+reject:
+	cma_modify_qp_err(id);
+	rdma_reject(id, NULL, 0);
+	return ret;
+}
+EXPORT_SYMBOL(rdma_accept);
+
+int rdma_reject(struct rdma_cm_id *id, const void *private_data,
+		u8 private_data_len)
+{
+	struct rdma_id_private *id_priv;
+	int ret;
+
+	id_priv = container_of(id, struct rdma_id_private, id);
+	if (!cma_comp(id_priv, CMA_CONNECT))
+		return -EINVAL;
+
+	switch (id->device->node_type) {
+	case IB_NODE_CA:
+		ret = ib_send_cm_rej(id_priv->cm_id.ib,
+				     IB_CM_REJ_CONSUMER_DEFINED, NULL, 0,
+				     private_data, private_data_len);
+		break;
+	default:
+		ret = -ENOSYS;
+		break;
+	}
+	return ret;
+}
+EXPORT_SYMBOL(rdma_reject);
+
+int rdma_disconnect(struct rdma_cm_id *id)
+{
+	struct rdma_id_private *id_priv;
+	int ret;
+
+	id_priv = container_of(id, struct rdma_id_private, id);
+	if (!cma_comp(id_priv, CMA_CONNECT) &&
+	    !cma_comp(id_priv, CMA_DISCONNECT))
+		return -EINVAL;
+
+	ret = cma_modify_qp_err(id);
+	if (ret)
+		goto out;
+
+	switch (id->device->node_type) {
+	case IB_NODE_CA:
+		/* Initiate or respond to a disconnect. */
+		if (ib_send_cm_dreq(id_priv->cm_id.ib, NULL, 0))
+			ib_send_cm_drep(id_priv->cm_id.ib, NULL, 0);
+		break;
+	default:
+		break;
+	}
+out:
+	return ret;
+}
+EXPORT_SYMBOL(rdma_disconnect);
+
+static void cma_add_one(struct ib_device *device)
+{
+	struct cma_device *cma_dev;
+	struct rdma_id_private *id_priv;
+
+	cma_dev = kmalloc(sizeof *cma_dev, GFP_KERNEL);
+	if (!cma_dev)
+		return;
+
+	cma_dev->device = device;
+	cma_dev->node_guid = device->node_guid;
+	if (!cma_dev->node_guid)
+		goto err;
+
+	init_completion(&cma_dev->comp);
+	atomic_set(&cma_dev->refcount, 1);
+	INIT_LIST_HEAD(&cma_dev->id_list);
+	ib_set_client_data(device, &cma_client, cma_dev);
+
+	mutex_lock(&lock);
+	list_add_tail(&cma_dev->list, &dev_list);
+	list_for_each_entry(id_priv, &listen_any_list, list)
+		cma_listen_on_dev(id_priv, cma_dev);
+	mutex_unlock(&lock);
+	return;
+err:
+	kfree(cma_dev);
+}
+
+static int cma_remove_id_dev(struct rdma_id_private *id_priv)
+{
+	enum cma_state state;
+
+	/* Record that we want to remove the device */
+	state = cma_exch(id_priv, CMA_DEVICE_REMOVAL);
+	if (state == CMA_DESTROYING)
+		return 0;
+
+	cma_cancel_operation(id_priv, state);
+	wait_event(id_priv->wait_remove, !atomic_read(&id_priv->dev_remove));
+
+	/* Check for destruction from another callback. */
+	if (!cma_comp(id_priv, CMA_DEVICE_REMOVAL))
+		return 0;
+
+	return cma_notify_user(id_priv, RDMA_CM_EVENT_DEVICE_REMOVAL,
+			       0, NULL, 0);
+}
+
+static void cma_process_remove(struct cma_device *cma_dev)
+{
+	struct list_head remove_list;
+	struct rdma_id_private *id_priv;
+	int ret;
+
+	INIT_LIST_HEAD(&remove_list);
+
+	mutex_lock(&lock);
+	while (!list_empty(&cma_dev->id_list)) {
+		id_priv = list_entry(cma_dev->id_list.next,
+				     struct rdma_id_private, list);
+
+		if (cma_internal_listen(id_priv)) {
+			cma_destroy_listen(id_priv);
+			continue;
+		}
+
+		list_del(&id_priv->list);
+		list_add_tail(&id_priv->list, &remove_list);
+		atomic_inc(&id_priv->refcount);
+		mutex_unlock(&lock);
+
+		ret = cma_remove_id_dev(id_priv);
+		cma_deref_id(id_priv);
+		if (ret)
+			rdma_destroy_id(&id_priv->id);
+
+		mutex_lock(&lock);
+	}
+	mutex_unlock(&lock);
+
+	cma_deref_dev(cma_dev);
+	wait_for_completion(&cma_dev->comp);
+}
+
+static void cma_remove_one(struct ib_device *device)
+{
+	struct cma_device *cma_dev;
+
+	cma_dev = ib_get_client_data(device, &cma_client);
+	if (!cma_dev)
+		return;
+
+	mutex_lock(&lock);
+	list_del(&cma_dev->list);
+	mutex_unlock(&lock);
+
+	cma_process_remove(cma_dev);
+	kfree(cma_dev);
+}
+
+static int cma_init(void)
+{
+	int ret;
+
+	cma_wq = create_singlethread_workqueue("rdma_cm_wq");
+	if (!cma_wq)
+		return -ENOMEM;
+
+	ret = ib_register_client(&cma_client);
+	if (ret)
+		goto err;
+	return 0;
+
+err:
+	destroy_workqueue(cma_wq);
+	return ret;
+}
+
+static void cma_cleanup(void)
+{
+	ib_unregister_client(&cma_client);
+	destroy_workqueue(cma_wq);
+	idr_destroy(&sdp_ps);
+	idr_destroy(&tcp_ps);
+}
+
+module_init(cma_init);
+module_exit(cma_cleanup);
diff --git a/drivers/infiniband/core/uverbs_marshall.c b/drivers/infiniband/core/uverbs_marshall.c
new file mode 100644
index 000000000..ce46b13ae
--- /dev/null
+++ b/drivers/infiniband/core/uverbs_marshall.c
@@ -0,0 +1,138 @@
+/*
+ * Copyright (c) 2005 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 <rdma/ib_marshall.h>
+
+static void ib_copy_ah_attr_to_user(struct ib_uverbs_ah_attr *dst,
+				    struct ib_ah_attr *src)
+{
+	memcpy(dst->grh.dgid, src->grh.dgid.raw, sizeof src->grh.dgid);
+	dst->grh.flow_label        = src->grh.flow_label;
+	dst->grh.sgid_index        = src->grh.sgid_index;
+	dst->grh.hop_limit         = src->grh.hop_limit;
+	dst->grh.traffic_class     = src->grh.traffic_class;
+	dst->dlid 	    	   = src->dlid;
+	dst->sl   	    	   = src->sl;
+	dst->src_path_bits 	   = src->src_path_bits;
+	dst->static_rate   	   = src->static_rate;
+	dst->is_global             = src->ah_flags & IB_AH_GRH ? 1 : 0;
+	dst->port_num 	    	   = src->port_num;
+}
+
+void ib_copy_qp_attr_to_user(struct ib_uverbs_qp_attr *dst,
+			     struct ib_qp_attr *src)
+{
+	dst->cur_qp_state	= src->cur_qp_state;
+	dst->path_mtu		= src->path_mtu;
+	dst->path_mig_state	= src->path_mig_state;
+	dst->qkey		= src->qkey;
+	dst->rq_psn		= src->rq_psn;
+	dst->sq_psn		= src->sq_psn;
+	dst->dest_qp_num	= src->dest_qp_num;
+	dst->qp_access_flags	= src->qp_access_flags;
+
+	dst->max_send_wr	= src->cap.max_send_wr;
+	dst->max_recv_wr	= src->cap.max_recv_wr;
+	dst->max_send_sge	= src->cap.max_send_sge;
+	dst->max_recv_sge	= src->cap.max_recv_sge;
+	dst->max_inline_data	= src->cap.max_inline_data;
+
+	ib_copy_ah_attr_to_user(&dst->ah_attr, &src->ah_attr);
+	ib_copy_ah_attr_to_user(&dst->alt_ah_attr, &src->alt_ah_attr);
+
+	dst->pkey_index		= src->pkey_index;
+	dst->alt_pkey_index	= src->alt_pkey_index;
+	dst->en_sqd_async_notify = src->en_sqd_async_notify;
+	dst->sq_draining	= src->sq_draining;
+	dst->max_rd_atomic	= src->max_rd_atomic;
+	dst->max_dest_rd_atomic	= src->max_dest_rd_atomic;
+	dst->min_rnr_timer	= src->min_rnr_timer;
+	dst->port_num		= src->port_num;
+	dst->timeout		= src->timeout;
+	dst->retry_cnt		= src->retry_cnt;
+	dst->rnr_retry		= src->rnr_retry;
+	dst->alt_port_num	= src->alt_port_num;
+	dst->alt_timeout	= src->alt_timeout;
+}
+EXPORT_SYMBOL(ib_copy_qp_attr_to_user);
+
+void ib_copy_path_rec_to_user(struct ib_user_path_rec *dst,
+			      struct ib_sa_path_rec *src)
+{
+	memcpy(dst->dgid, src->dgid.raw, sizeof src->dgid);
+	memcpy(dst->sgid, src->sgid.raw, sizeof src->sgid);
+
+	dst->dlid		= src->dlid;
+	dst->slid		= src->slid;
+	dst->raw_traffic	= src->raw_traffic;
+	dst->flow_label		= src->flow_label;
+	dst->hop_limit		= src->hop_limit;
+	dst->traffic_class	= src->traffic_class;
+	dst->reversible		= src->reversible;
+	dst->numb_path		= src->numb_path;
+	dst->pkey		= src->pkey;
+	dst->sl			= src->sl;
+	dst->mtu_selector	= src->mtu_selector;
+	dst->mtu		= src->mtu;
+	dst->rate_selector	= src->rate_selector;
+	dst->rate		= src->rate;
+	dst->packet_life_time	= src->packet_life_time;
+	dst->preference		= src->preference;
+	dst->packet_life_time_selector = src->packet_life_time_selector;
+}
+EXPORT_SYMBOL(ib_copy_path_rec_to_user);
+
+void ib_copy_path_rec_from_user(struct ib_sa_path_rec *dst,
+				struct ib_user_path_rec *src)
+{
+	memcpy(dst->dgid.raw, src->dgid, sizeof dst->dgid);
+	memcpy(dst->sgid.raw, src->sgid, sizeof dst->sgid);
+
+	dst->dlid		= src->dlid;
+	dst->slid		= src->slid;
+	dst->raw_traffic	= src->raw_traffic;
+	dst->flow_label		= src->flow_label;
+	dst->hop_limit		= src->hop_limit;
+	dst->traffic_class	= src->traffic_class;
+	dst->reversible		= src->reversible;
+	dst->numb_path		= src->numb_path;
+	dst->pkey		= src->pkey;
+	dst->sl			= src->sl;
+	dst->mtu_selector	= src->mtu_selector;
+	dst->mtu		= src->mtu;
+	dst->rate_selector	= src->rate_selector;
+	dst->rate		= src->rate;
+	dst->packet_life_time	= src->packet_life_time;
+	dst->preference		= src->preference;
+	dst->packet_life_time_selector = src->packet_life_time_selector;
+}
+EXPORT_SYMBOL(ib_copy_path_rec_from_user);
diff --git a/drivers/infiniband/ulp/iser/Kconfig b/drivers/infiniband/ulp/iser/Kconfig
new file mode 100644
index 000000000..fead87d1e
--- /dev/null
+++ b/drivers/infiniband/ulp/iser/Kconfig
@@ -0,0 +1,11 @@
+config INFINIBAND_ISER
+	tristate "ISCSI RDMA Protocol"
+	depends on INFINIBAND && SCSI
+	select SCSI_ISCSI_ATTRS
+	---help---
+	  Support for the ISCSI RDMA Protocol over InfiniBand.  This
+	  allows you to access storage devices that speak ISER/ISCSI
+	  over InfiniBand.
+
+	  The ISER protocol is defined by IETF.
+	  See <http://www.ietf.org/>.
diff --git a/drivers/infiniband/ulp/iser/Makefile b/drivers/infiniband/ulp/iser/Makefile
new file mode 100644
index 000000000..fe6cd15f2
--- /dev/null
+++ b/drivers/infiniband/ulp/iser/Makefile
@@ -0,0 +1,4 @@
+obj-$(CONFIG_INFINIBAND_ISER)	+= ib_iser.o
+
+ib_iser-y			:= iser_verbs.o iser_initiator.o iser_memory.o \
+				   iscsi_iser.o
diff --git a/drivers/infiniband/ulp/iser/iscsi_iser.c b/drivers/infiniband/ulp/iser/iscsi_iser.c
new file mode 100644
index 000000000..1437d7ee3
--- /dev/null
+++ b/drivers/infiniband/ulp/iser/iscsi_iser.c
@@ -0,0 +1,667 @@
+/*
+ * iSCSI Initiator over iSER Data-Path
+ *
+ * Copyright (C) 2004 Dmitry Yusupov
+ * Copyright (C) 2004 Alex Aizman
+ * Copyright (C) 2005 Mike Christie
+ * Copyright (c) 2005, 2006 Voltaire, Inc. All rights reserved.
+ * maintained by openib-general@openib.org
+ *
+ * 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.
+ *
+ * Credits:
+ *	Christoph Hellwig
+ *	FUJITA Tomonori
+ *	Arne Redlich
+ *	Zhenyu Wang
+ * Modified by:
+ *      Erez Zilber
+ *
+ *
+ * $Id: iscsi_iser.c 6965 2006-05-07 11:36:20Z ogerlitz $
+ */
+
+#include <linux/types.h>
+#include <linux/list.h>
+#include <linux/hardirq.h>
+#include <linux/kfifo.h>
+#include <linux/blkdev.h>
+#include <linux/init.h>
+#include <linux/ioctl.h>
+#include <linux/cdev.h>
+#include <linux/in.h>
+#include <linux/net.h>
+#include <linux/scatterlist.h>
+#include <linux/delay.h>
+
+#include <net/sock.h>
+
+#include <asm/uaccess.h>
+
+#include <scsi/scsi_cmnd.h>
+#include <scsi/scsi_device.h>
+#include <scsi/scsi_eh.h>
+#include <scsi/scsi_tcq.h>
+#include <scsi/scsi_host.h>
+#include <scsi/scsi.h>
+#include <scsi/scsi_transport_iscsi.h>
+
+#include "iscsi_iser.h"
+
+static unsigned int iscsi_max_lun = 512;
+module_param_named(max_lun, iscsi_max_lun, uint, S_IRUGO);
+
+int iser_debug_level = 0;
+
+MODULE_DESCRIPTION("iSER (iSCSI Extensions for RDMA) Datamover "
+		   "v" DRV_VER " (" DRV_DATE ")");
+MODULE_LICENSE("Dual BSD/GPL");
+MODULE_AUTHOR("Alex Nezhinsky, Dan Bar Dov, Or Gerlitz");
+
+module_param_named(debug_level, iser_debug_level, int, 0644);
+MODULE_PARM_DESC(debug_level, "Enable debug tracing if > 0 (default:disabled)");
+
+struct iser_global ig;
+
+void
+iscsi_iser_recv(struct iscsi_conn *conn,
+		struct iscsi_hdr *hdr, char *rx_data, int rx_data_len)
+{
+	int rc = 0;
+	uint32_t ret_itt;
+	int datalen;
+	int ahslen;
+
+	/* verify PDU length */
+	datalen = ntoh24(hdr->dlength);
+	if (datalen != rx_data_len) {
+		printk(KERN_ERR "iscsi_iser: datalen %d (hdr) != %d (IB) \n",
+		       datalen, rx_data_len);
+		rc = ISCSI_ERR_DATALEN;
+		goto error;
+	}
+
+	/* read AHS */
+	ahslen = hdr->hlength * 4;
+
+	/* verify itt (itt encoding: age+cid+itt) */
+	rc = iscsi_verify_itt(conn, hdr, &ret_itt);
+
+	if (!rc)
+		rc = iscsi_complete_pdu(conn, hdr, rx_data, rx_data_len);
+
+	if (rc && rc != ISCSI_ERR_NO_SCSI_CMD)
+		goto error;
+
+	return;
+error:
+	iscsi_conn_failure(conn, rc);
+}
+
+
+/**
+ * iscsi_iser_cmd_init - Initialize iSCSI SCSI_READ or SCSI_WRITE commands
+ *
+ **/
+static void
+iscsi_iser_cmd_init(struct iscsi_cmd_task *ctask)
+{
+	struct iscsi_iser_conn     *iser_conn  = ctask->conn->dd_data;
+	struct iscsi_iser_cmd_task *iser_ctask = ctask->dd_data;
+	struct scsi_cmnd  *sc = ctask->sc;
+
+	iser_ctask->command_sent = 0;
+	iser_ctask->iser_conn    = iser_conn;
+
+	if (sc->sc_data_direction == DMA_TO_DEVICE) {
+		BUG_ON(ctask->total_length == 0);
+		/* bytes to be sent via RDMA operations */
+		iser_ctask->rdma_data_count = ctask->total_length -
+					 ctask->imm_count -
+					 ctask->unsol_count;
+
+		debug_scsi("cmd [itt %x total %d imm %d unsol_data %d "
+			   "rdma_data %d]\n",
+			   ctask->itt, ctask->total_length, ctask->imm_count,
+			   ctask->unsol_count, iser_ctask->rdma_data_count);
+	} else
+		/* bytes to be sent via RDMA operations */
+		iser_ctask->rdma_data_count = ctask->total_length;
+
+	iser_ctask_rdma_init(iser_ctask);
+}
+
+/**
+ * iscsi_mtask_xmit - xmit management(immediate) task
+ * @conn: iscsi connection
+ * @mtask: task management task
+ *
+ * Notes:
+ *	The function can return -EAGAIN in which case caller must
+ *	call it again later, or recover. '0' return code means successful
+ *	xmit.
+ *
+ **/
+static int
+iscsi_iser_mtask_xmit(struct iscsi_conn *conn,
+		      struct iscsi_mgmt_task *mtask)
+{
+	int error = 0;
+
+	debug_scsi("mtask deq [cid %d itt 0x%x]\n", conn->id, mtask->itt);
+
+	error = iser_send_control(conn, mtask);
+
+	/* since iser xmits control with zero copy, mtasks can not be recycled
+	 * right after sending them.
+	 * The recycling scheme is based on whether a response is expected
+	 * - if yes, the mtask is recycled at iscsi_complete_pdu
+	 * - if no,  the mtask is recycled at iser_snd_completion
+	 */
+	if (error && error != -EAGAIN)
+		iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED);
+
+	return error;
+}
+
+static int
+iscsi_iser_ctask_xmit_unsol_data(struct iscsi_conn *conn,
+				 struct iscsi_cmd_task *ctask)
+{
+	struct iscsi_data  hdr;
+	int error = 0;
+	struct iscsi_iser_cmd_task *iser_ctask = ctask->dd_data;
+
+	/* Send data-out PDUs while there's still unsolicited data to send */
+	while (ctask->unsol_count > 0) {
+		iscsi_prep_unsolicit_data_pdu(ctask, &hdr,
+					      iser_ctask->rdma_data_count);
+
+		debug_scsi("Sending data-out: itt 0x%x, data count %d\n",
+			   hdr.itt, ctask->data_count);
+
+		/* the buffer description has been passed with the command */
+		/* Send the command */
+		error = iser_send_data_out(conn, ctask, &hdr);
+		if (error) {
+			ctask->unsol_datasn--;
+			goto iscsi_iser_ctask_xmit_unsol_data_exit;
+		}
+		ctask->unsol_count -= ctask->data_count;
+		debug_scsi("Need to send %d more as data-out PDUs\n",
+			   ctask->unsol_count);
+	}
+
+iscsi_iser_ctask_xmit_unsol_data_exit:
+	return error;
+}
+
+static int
+iscsi_iser_ctask_xmit(struct iscsi_conn *conn,
+		      struct iscsi_cmd_task *ctask)
+{
+	struct iscsi_iser_cmd_task *iser_ctask = ctask->dd_data;
+	int error = 0;
+
+	debug_scsi("ctask deq [cid %d itt 0x%x]\n",
+		   conn->id, ctask->itt);
+
+	/*
+	 * serialize with TMF AbortTask
+	 */
+	if (ctask->mtask)
+		return error;
+
+	/* Send the cmd PDU */
+	if (!iser_ctask->command_sent) {
+		error = iser_send_command(conn, ctask);
+		if (error)
+			goto iscsi_iser_ctask_xmit_exit;
+		iser_ctask->command_sent = 1;
+	}
+
+	/* Send unsolicited data-out PDU(s) if necessary */
+	if (ctask->unsol_count)
+		error = iscsi_iser_ctask_xmit_unsol_data(conn, ctask);
+
+ iscsi_iser_ctask_xmit_exit:
+	if (error && error != -EAGAIN)
+		iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED);
+	return error;
+}
+
+static void
+iscsi_iser_cleanup_ctask(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
+{
+	struct iscsi_iser_cmd_task *iser_ctask = ctask->dd_data;
+
+	if (iser_ctask->status == ISER_TASK_STATUS_STARTED) {
+		iser_ctask->status = ISER_TASK_STATUS_COMPLETED;
+		iser_ctask_rdma_finalize(iser_ctask);
+	}
+}
+
+static struct iser_conn *
+iscsi_iser_ib_conn_lookup(__u64 ep_handle)
+{
+	struct iser_conn *ib_conn;
+	struct iser_conn *uib_conn = (struct iser_conn *)(unsigned long)ep_handle;
+
+	mutex_lock(&ig.connlist_mutex);
+	list_for_each_entry(ib_conn, &ig.connlist, conn_list) {
+		if (ib_conn == uib_conn) {
+			mutex_unlock(&ig.connlist_mutex);
+			return ib_conn;
+		}
+	}
+	mutex_unlock(&ig.connlist_mutex);
+	iser_err("no conn exists for eph %llx\n",(unsigned long long)ep_handle);
+	return NULL;
+}
+
+static struct iscsi_cls_conn *
+iscsi_iser_conn_create(struct iscsi_cls_session *cls_session, uint32_t conn_idx)
+{
+	struct iscsi_conn *conn;
+	struct iscsi_cls_conn *cls_conn;
+	struct iscsi_iser_conn *iser_conn;
+
+	cls_conn = iscsi_conn_setup(cls_session, conn_idx);
+	if (!cls_conn)
+		return NULL;
+	conn = cls_conn->dd_data;
+
+	/*
+	 * due to issues with the login code re iser sematics
+	 * this not set in iscsi_conn_setup - FIXME
+	 */
+	conn->max_recv_dlength = 128;
+
+	iser_conn = kzalloc(sizeof(*iser_conn), GFP_KERNEL);
+	if (!iser_conn)
+		goto conn_alloc_fail;
+
+	/* currently this is the only field which need to be initiated */
+	rwlock_init(&iser_conn->lock);
+
+	conn->dd_data = iser_conn;
+	iser_conn->iscsi_conn = conn;
+
+	return cls_conn;
+
+conn_alloc_fail:
+	iscsi_conn_teardown(cls_conn);
+	return NULL;
+}
+
+static void
+iscsi_iser_conn_destroy(struct iscsi_cls_conn *cls_conn)
+{
+	struct iscsi_conn *conn = cls_conn->dd_data;
+	struct iscsi_iser_conn *iser_conn = conn->dd_data;
+
+	iscsi_conn_teardown(cls_conn);
+	kfree(iser_conn);
+}
+
+static int
+iscsi_iser_conn_bind(struct iscsi_cls_session *cls_session,
+		     struct iscsi_cls_conn *cls_conn, uint64_t transport_eph,
+		     int is_leading)
+{
+	struct iscsi_conn *conn = cls_conn->dd_data;
+	struct iscsi_iser_conn *iser_conn;
+	struct iser_conn *ib_conn;
+	int error;
+
+	error = iscsi_conn_bind(cls_session, cls_conn, is_leading);
+	if (error)
+		return error;
+
+	/* the transport ep handle comes from user space so it must be
+	 * verified against the global ib connections list */
+	ib_conn = iscsi_iser_ib_conn_lookup(transport_eph);
+	if (!ib_conn) {
+		iser_err("can't bind eph %llx\n",
+			 (unsigned long long)transport_eph);
+		return -EINVAL;
+	}
+	/* binds the iSER connection retrieved from the previously
+	 * connected ep_handle to the iSCSI layer connection. exchanges
+	 * connection pointers */
+	iser_err("binding iscsi conn %p to iser_conn %p\n",conn,ib_conn);
+	iser_conn = conn->dd_data;
+	ib_conn->iser_conn = iser_conn;
+	iser_conn->ib_conn  = ib_conn;
+
+	conn->recv_lock = &iser_conn->lock;
+
+	return 0;
+}
+
+static int
+iscsi_iser_conn_start(struct iscsi_cls_conn *cls_conn)
+{
+	struct iscsi_conn *conn = cls_conn->dd_data;
+	int err;
+
+	err = iscsi_conn_start(cls_conn);
+	if (err)
+		return err;
+
+	return iser_conn_set_full_featured_mode(conn);
+}
+
+static struct iscsi_transport iscsi_iser_transport;
+
+static struct iscsi_cls_session *
+iscsi_iser_session_create(struct iscsi_transport *iscsit,
+			 struct scsi_transport_template *scsit,
+			  uint32_t initial_cmdsn, uint32_t *hostno)
+{
+	struct iscsi_cls_session *cls_session;
+	struct iscsi_session *session;
+	int i;
+	uint32_t hn;
+	struct iscsi_cmd_task  *ctask;
+	struct iscsi_mgmt_task *mtask;
+	struct iscsi_iser_cmd_task *iser_ctask;
+	struct iser_desc *desc;
+
+	cls_session = iscsi_session_setup(iscsit, scsit,
+					  sizeof(struct iscsi_iser_cmd_task),
+					  sizeof(struct iser_desc),
+					  initial_cmdsn, &hn);
+	if (!cls_session)
+	return NULL;
+
+	*hostno = hn;
+	session = class_to_transport_session(cls_session);
+
+	/* libiscsi setup itts, data and pool so just set desc fields */
+	for (i = 0; i < session->cmds_max; i++) {
+		ctask      = session->cmds[i];
+		iser_ctask = ctask->dd_data;
+		ctask->hdr = (struct iscsi_cmd *)&iser_ctask->desc.iscsi_header;
+	}
+
+	for (i = 0; i < session->mgmtpool_max; i++) {
+		mtask      = session->mgmt_cmds[i];
+		desc       = mtask->dd_data;
+		mtask->hdr = &desc->iscsi_header;
+		desc->data = mtask->data;
+	}
+
+	return cls_session;
+}
+
+static int
+iscsi_iser_set_param(struct iscsi_cls_conn *cls_conn,
+		     enum iscsi_param param, char *buf, int buflen)
+{
+	int value;
+
+	switch (param) {
+	case ISCSI_PARAM_MAX_RECV_DLENGTH:
+		/* TBD */
+		break;
+	case ISCSI_PARAM_HDRDGST_EN:
+		sscanf(buf, "%d", &value);
+		if (value) {
+			printk(KERN_ERR "DataDigest wasn't negotiated to None");
+			return -EPROTO;
+		}
+		break;
+	case ISCSI_PARAM_DATADGST_EN:
+		sscanf(buf, "%d", &value);
+		if (value) {
+			printk(KERN_ERR "DataDigest wasn't negotiated to None");
+			return -EPROTO;
+		}
+		break;
+	case ISCSI_PARAM_IFMARKER_EN:
+		sscanf(buf, "%d", &value);
+		if (value) {
+			printk(KERN_ERR "IFMarker wasn't negotiated to No");
+			return -EPROTO;
+		}
+		break;
+	case ISCSI_PARAM_OFMARKER_EN:
+		sscanf(buf, "%d", &value);
+		if (value) {
+			printk(KERN_ERR "OFMarker wasn't negotiated to No");
+			return -EPROTO;
+		}
+		break;
+	default:
+		return iscsi_set_param(cls_conn, param, buf, buflen);
+	}
+
+	return 0;
+}
+
+static void
+iscsi_iser_conn_get_stats(struct iscsi_cls_conn *cls_conn, struct iscsi_stats *stats)
+{
+	struct iscsi_conn *conn = cls_conn->dd_data;
+
+	stats->txdata_octets = conn->txdata_octets;
+	stats->rxdata_octets = conn->rxdata_octets;
+	stats->scsicmd_pdus = conn->scsicmd_pdus_cnt;
+	stats->dataout_pdus = conn->dataout_pdus_cnt;
+	stats->scsirsp_pdus = conn->scsirsp_pdus_cnt;
+	stats->datain_pdus = conn->datain_pdus_cnt; /* always 0 */
+	stats->r2t_pdus = conn->r2t_pdus_cnt; /* always 0 */
+	stats->tmfcmd_pdus = conn->tmfcmd_pdus_cnt;
+	stats->tmfrsp_pdus = conn->tmfrsp_pdus_cnt;
+	stats->custom_length = 3;
+	strcpy(stats->custom[0].desc, "qp_tx_queue_full");
+	stats->custom[0].value = 0; /* TB iser_conn->qp_tx_queue_full; */
+	strcpy(stats->custom[1].desc, "fmr_map_not_avail");
+	stats->custom[1].value = 0; /* TB iser_conn->fmr_map_not_avail */;
+	strcpy(stats->custom[2].desc, "eh_abort_cnt");
+	stats->custom[2].value = conn->eh_abort_cnt;
+}
+
+static int
+iscsi_iser_ep_connect(struct sockaddr *dst_addr, int non_blocking,
+		      __u64 *ep_handle)
+{
+	int err;
+	struct iser_conn *ib_conn;
+
+	err = iser_conn_init(&ib_conn);
+	if (err)
+		goto out;
+
+	err = iser_connect(ib_conn, NULL, (struct sockaddr_in *)dst_addr, non_blocking);
+	if (!err)
+		*ep_handle = (__u64)(unsigned long)ib_conn;
+
+out:
+	return err;
+}
+
+static int
+iscsi_iser_ep_poll(__u64 ep_handle, int timeout_ms)
+{
+	struct iser_conn *ib_conn = iscsi_iser_ib_conn_lookup(ep_handle);
+	int rc;
+
+	if (!ib_conn)
+		return -EINVAL;
+
+	rc = wait_event_interruptible_timeout(ib_conn->wait,
+			     ib_conn->state == ISER_CONN_UP,
+			     msecs_to_jiffies(timeout_ms));
+
+	/* if conn establishment failed, return error code to iscsi */
+	if (!rc &&
+	    (ib_conn->state == ISER_CONN_TERMINATING ||
+	     ib_conn->state == ISER_CONN_DOWN))
+		rc = -1;
+
+	iser_err("ib conn %p rc = %d\n", ib_conn, rc);
+
+	if (rc > 0)
+		return 1; /* success, this is the equivalent of POLLOUT */
+	else if (!rc)
+		return 0; /* timeout */
+	else
+		return rc; /* signal */
+}
+
+static void
+iscsi_iser_ep_disconnect(__u64 ep_handle)
+{
+	struct iser_conn *ib_conn;
+
+	ib_conn = iscsi_iser_ib_conn_lookup(ep_handle);
+	if (!ib_conn)
+		return;
+
+	iser_err("ib conn %p state %d\n",ib_conn, ib_conn->state);
+	iser_conn_terminate(ib_conn);
+}
+
+static struct scsi_host_template iscsi_iser_sht = {
+	.name                   = "iSCSI Initiator over iSER, v." DRV_VER,
+	.queuecommand           = iscsi_queuecommand,
+	.can_queue		= ISCSI_XMIT_CMDS_MAX - 1,
+	.sg_tablesize           = ISCSI_ISER_SG_TABLESIZE,
+	.cmd_per_lun            = ISCSI_MAX_CMD_PER_LUN,
+	.eh_abort_handler       = iscsi_eh_abort,
+	.eh_host_reset_handler	= iscsi_eh_host_reset,
+	.use_clustering         = DISABLE_CLUSTERING,
+	.proc_name              = "iscsi_iser",
+	.this_id                = -1,
+};
+
+static struct iscsi_transport iscsi_iser_transport = {
+	.owner                  = THIS_MODULE,
+	.name                   = "iser",
+	.caps                   = CAP_RECOVERY_L0 | CAP_MULTI_R2T,
+	.param_mask		= ISCSI_MAX_RECV_DLENGTH |
+				  ISCSI_MAX_XMIT_DLENGTH |
+				  ISCSI_HDRDGST_EN |
+				  ISCSI_DATADGST_EN |
+				  ISCSI_INITIAL_R2T_EN |
+				  ISCSI_MAX_R2T |
+				  ISCSI_IMM_DATA_EN |
+				  ISCSI_FIRST_BURST |
+				  ISCSI_MAX_BURST |
+				  ISCSI_PDU_INORDER_EN |
+				  ISCSI_DATASEQ_INORDER_EN |
+				  ISCSI_EXP_STATSN |
+				  ISCSI_PERSISTENT_PORT |
+				  ISCSI_PERSISTENT_ADDRESS |
+				  ISCSI_TARGET_NAME |
+				  ISCSI_TPGT,
+	.host_template          = &iscsi_iser_sht,
+	.conndata_size		= sizeof(struct iscsi_conn),
+	.max_lun                = ISCSI_ISER_MAX_LUN,
+	.max_cmd_len            = ISCSI_ISER_MAX_CMD_LEN,
+	/* session management */
+	.create_session         = iscsi_iser_session_create,
+	.destroy_session        = iscsi_session_teardown,
+	/* connection management */
+	.create_conn            = iscsi_iser_conn_create,
+	.bind_conn              = iscsi_iser_conn_bind,
+	.destroy_conn           = iscsi_iser_conn_destroy,
+	.set_param              = iscsi_iser_set_param,
+	.get_conn_param		= iscsi_conn_get_param,
+	.get_session_param	= iscsi_session_get_param,
+	.start_conn             = iscsi_iser_conn_start,
+	.stop_conn              = iscsi_conn_stop,
+	/* IO */
+	.send_pdu		= iscsi_conn_send_pdu,
+	.get_stats		= iscsi_iser_conn_get_stats,
+	.init_cmd_task		= iscsi_iser_cmd_init,
+	.xmit_cmd_task		= iscsi_iser_ctask_xmit,
+	.xmit_mgmt_task		= iscsi_iser_mtask_xmit,
+	.cleanup_cmd_task	= iscsi_iser_cleanup_ctask,
+	/* recovery */
+	.session_recovery_timedout = iscsi_session_recovery_timedout,
+
+	.ep_connect             = iscsi_iser_ep_connect,
+	.ep_poll                = iscsi_iser_ep_poll,
+	.ep_disconnect          = iscsi_iser_ep_disconnect
+};
+
+static int __init iser_init(void)
+{
+	int err;
+
+	iser_dbg("Starting iSER datamover...\n");
+
+	if (iscsi_max_lun < 1) {
+		printk(KERN_ERR "Invalid max_lun value of %u\n", iscsi_max_lun);
+		return -EINVAL;
+	}
+
+	iscsi_iser_transport.max_lun = iscsi_max_lun;
+
+	memset(&ig, 0, sizeof(struct iser_global));
+
+	ig.desc_cache = kmem_cache_create("iser_descriptors",
+					  sizeof (struct iser_desc),
+					  0, SLAB_HWCACHE_ALIGN,
+					  NULL, NULL);
+	if (ig.desc_cache == NULL)
+		return -ENOMEM;
+
+	/* device init is called only after the first addr resolution */
+	mutex_init(&ig.device_list_mutex);
+	INIT_LIST_HEAD(&ig.device_list);
+	mutex_init(&ig.connlist_mutex);
+	INIT_LIST_HEAD(&ig.connlist);
+
+	if (!iscsi_register_transport(&iscsi_iser_transport)) {
+		iser_err("iscsi_register_transport failed\n");
+		err = -EINVAL;
+		goto register_transport_failure;
+	}
+
+	return 0;
+
+register_transport_failure:
+	kmem_cache_destroy(ig.desc_cache);
+
+	return err;
+}
+
+static void __exit iser_exit(void)
+{
+	iser_dbg("Removing iSER datamover...\n");
+	iscsi_unregister_transport(&iscsi_iser_transport);
+	kmem_cache_destroy(ig.desc_cache);
+}
+
+module_init(iser_init);
+module_exit(iser_exit);
diff --git a/drivers/infiniband/ulp/iser/iscsi_iser.h b/drivers/infiniband/ulp/iser/iscsi_iser.h
new file mode 100644
index 000000000..3350ba690
--- /dev/null
+++ b/drivers/infiniband/ulp/iser/iscsi_iser.h
@@ -0,0 +1,354 @@
+/*
+ * iSER transport for the Open iSCSI Initiator & iSER transport internals
+ *
+ * Copyright (C) 2004 Dmitry Yusupov
+ * Copyright (C) 2004 Alex Aizman
+ * Copyright (C) 2005 Mike Christie
+ * based on code maintained by open-iscsi@googlegroups.com
+ *
+ * Copyright (c) 2004, 2005, 2006 Voltaire, Inc. All rights reserved.
+ * Copyright (c) 2005, 2006 Cisco Systems.  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.
+ *
+ * $Id: iscsi_iser.h 7051 2006-05-10 12:29:11Z ogerlitz $
+ */
+#ifndef __ISCSI_ISER_H__
+#define __ISCSI_ISER_H__
+
+#include <linux/types.h>
+#include <linux/net.h>
+#include <scsi/libiscsi.h>
+#include <scsi/scsi_transport_iscsi.h>
+
+#include <linux/wait.h>
+#include <linux/sched.h>
+#include <linux/list.h>
+#include <linux/slab.h>
+#include <linux/dma-mapping.h>
+#include <linux/mutex.h>
+#include <linux/mempool.h>
+#include <linux/uio.h>
+
+#include <linux/socket.h>
+#include <linux/in.h>
+#include <linux/in6.h>
+
+#include <rdma/ib_verbs.h>
+#include <rdma/ib_fmr_pool.h>
+#include <rdma/rdma_cm.h>
+
+#define DRV_NAME	"iser"
+#define PFX		DRV_NAME ": "
+#define DRV_VER		"0.1"
+#define DRV_DATE	"May 7th, 2006"
+
+#define iser_dbg(fmt, arg...)				\
+	do {						\
+		if (iser_debug_level > 0)		\
+			printk(KERN_DEBUG PFX "%s:" fmt,\
+				__func__ , ## arg);	\
+	} while (0)
+
+#define iser_err(fmt, arg...)				\
+	do {						\
+		printk(KERN_ERR PFX "%s:" fmt,          \
+		       __func__ , ## arg);		\
+	} while (0)
+
+					/* support upto 512KB in one RDMA */
+#define ISCSI_ISER_SG_TABLESIZE         (0x80000 >> PAGE_SHIFT)
+#define ISCSI_ISER_MAX_LUN		256
+#define ISCSI_ISER_MAX_CMD_LEN		16
+
+/* QP settings */
+/* Maximal bounds on received asynchronous PDUs */
+#define ISER_MAX_RX_MISC_PDUS		4 /* NOOP_IN(2) , ASYNC_EVENT(2)   */
+
+#define ISER_MAX_TX_MISC_PDUS		6 /* NOOP_OUT(2), TEXT(1),         *
+					   * SCSI_TMFUNC(2), LOGOUT(1) */
+
+#define ISER_QP_MAX_RECV_DTOS		(ISCSI_XMIT_CMDS_MAX + \
+					ISER_MAX_RX_MISC_PDUS    +  \
+					ISER_MAX_TX_MISC_PDUS)
+
+/* the max TX (send) WR supported by the iSER QP is defined by                 *
+ * max_send_wr = T * (1 + D) + C ; D is how many inflight dataouts we expect   *
+ * to have at max for SCSI command. The tx posting & completion handling code  *
+ * supports -EAGAIN scheme where tx is suspended till the QP has room for more *
+ * send WR. D=8 comes from 64K/8K                                              */
+
+#define ISER_INFLIGHT_DATAOUTS		8
+
+#define ISER_QP_MAX_REQ_DTOS		(ISCSI_XMIT_CMDS_MAX *    \
+					(1 + ISER_INFLIGHT_DATAOUTS) + \
+					ISER_MAX_TX_MISC_PDUS        + \
+					ISER_MAX_RX_MISC_PDUS)
+
+#define ISER_VER			0x10
+#define ISER_WSV			0x08
+#define ISER_RSV			0x04
+
+struct iser_hdr {
+	u8      flags;
+	u8      rsvd[3];
+	__be32  write_stag; /* write rkey */
+	__be64  write_va;
+	__be32  read_stag;  /* read rkey */
+	__be64  read_va;
+} __attribute__((packed));
+
+
+/* Length of an object name string */
+#define ISER_OBJECT_NAME_SIZE		    64
+
+enum iser_ib_conn_state {
+	ISER_CONN_INIT,		   /* descriptor allocd, no conn          */
+	ISER_CONN_PENDING,	   /* in the process of being established */
+	ISER_CONN_UP,		   /* up and running                      */
+	ISER_CONN_TERMINATING,	   /* in the process of being terminated  */
+	ISER_CONN_DOWN,		   /* shut down                           */
+	ISER_CONN_STATES_NUM
+};
+
+enum iser_task_status {
+	ISER_TASK_STATUS_INIT = 0,
+	ISER_TASK_STATUS_STARTED,
+	ISER_TASK_STATUS_COMPLETED
+};
+
+enum iser_data_dir {
+	ISER_DIR_IN = 0,	   /* to initiator */
+	ISER_DIR_OUT,		   /* from initiator */
+	ISER_DIRS_NUM
+};
+
+struct iser_data_buf {
+	void               *buf;      /* pointer to the sg list               */
+	unsigned int       size;      /* num entries of this sg               */
+	unsigned long      data_len;  /* total data len                       */
+	unsigned int       dma_nents; /* returned by dma_map_sg               */
+	char       	   *copy_buf; /* allocated copy buf for SGs unaligned *
+	                               * for rdma which are copied            */
+	struct scatterlist sg_single; /* SG-ified clone of a non SG SC or     *
+				       * unaligned SG                         */
+  };
+
+/* fwd declarations */
+struct iser_device;
+struct iscsi_iser_conn;
+struct iscsi_iser_cmd_task;
+
+struct iser_mem_reg {
+	u32  lkey;
+	u32  rkey;
+	u64  va;
+	u64  len;
+	void *mem_h;
+};
+
+struct iser_regd_buf {
+	struct iser_mem_reg     reg;        /* memory registration info        */
+	void                    *virt_addr;
+	struct iser_device      *device;    /* device->device for dma_unmap    */
+	dma_addr_t              dma_addr;   /* if non zero, addr for dma_unmap */
+	enum dma_data_direction direction;  /* direction for dma_unmap	       */
+	unsigned int            data_size;
+	atomic_t                ref_count;  /* refcount, freed when dec to 0   */
+};
+
+#define MAX_REGD_BUF_VECTOR_LEN	2
+
+struct iser_dto {
+	struct iscsi_iser_cmd_task *ctask;
+	struct iscsi_iser_conn     *conn;
+	int                        notify_enable;
+
+	/* vector of registered buffers */
+	unsigned int               regd_vector_len;
+	struct iser_regd_buf       *regd[MAX_REGD_BUF_VECTOR_LEN];
+
+	/* offset into the registered buffer may be specified */
+	unsigned int               offset[MAX_REGD_BUF_VECTOR_LEN];
+
+	/* a smaller size may be specified, if 0, then full size is used */
+	unsigned int               used_sz[MAX_REGD_BUF_VECTOR_LEN];
+};
+
+enum iser_desc_type {
+	ISCSI_RX,
+	ISCSI_TX_CONTROL ,
+	ISCSI_TX_SCSI_COMMAND,
+	ISCSI_TX_DATAOUT
+};
+
+struct iser_desc {
+	struct iser_hdr              iser_header;
+	struct iscsi_hdr             iscsi_header;
+	struct iser_regd_buf         hdr_regd_buf;
+	void                         *data;         /* used by RX & TX_CONTROL */
+	struct iser_regd_buf         data_regd_buf; /* used by RX & TX_CONTROL */
+	enum   iser_desc_type        type;
+	struct iser_dto              dto;
+};
+
+struct iser_device {
+	struct ib_device             *ib_device;
+	struct ib_pd	             *pd;
+	struct ib_cq	             *cq;
+	struct ib_mr	             *mr;
+	struct tasklet_struct	     cq_tasklet;
+	struct list_head             ig_list; /* entry in ig devices list */
+	int                          refcount;
+};
+
+struct iser_conn {
+	struct iscsi_iser_conn       *iser_conn; /* iser conn for upcalls  */
+	enum iser_ib_conn_state	     state;	    /* rdma connection state   */
+	spinlock_t		     lock;	    /* used for state changes  */
+	struct iser_device           *device;       /* device context          */
+	struct rdma_cm_id            *cma_id;       /* CMA ID		       */
+	struct ib_qp	             *qp;           /* QP 		       */
+	struct ib_fmr_pool           *fmr_pool;     /* pool of IB FMRs         */
+	int                          disc_evt_flag; /* disconn event delivered */
+	wait_queue_head_t	     wait;          /* waitq for conn/disconn  */
+	atomic_t                     post_recv_buf_count; /* posted rx count   */
+	atomic_t                     post_send_buf_count; /* posted tx count   */
+	struct work_struct           comperror_work; /* conn term sleepable ctx*/
+	char 			     name[ISER_OBJECT_NAME_SIZE];
+	struct iser_page_vec         *page_vec;     /* represents SG to fmr maps*
+						     * maps serialized as tx is*/
+	struct list_head	     conn_list;       /* entry in ig conn list */
+};
+
+struct iscsi_iser_conn {
+	struct iscsi_conn            *iscsi_conn;/* ptr to iscsi conn */
+	struct iser_conn             *ib_conn;   /* iSER IB conn      */
+
+	rwlock_t		     lock;
+};
+
+struct iscsi_iser_cmd_task {
+	struct iser_desc             desc;
+	struct iscsi_iser_conn	     *iser_conn;
+	int			     rdma_data_count;/* RDMA bytes           */
+	enum iser_task_status 	     status;
+	int                          command_sent;  /* set if command  sent  */
+	int                          dir[ISER_DIRS_NUM];      /* set if dir use*/
+	struct iser_regd_buf         rdma_regd[ISER_DIRS_NUM];/* regd rdma buf */
+	struct iser_data_buf         data[ISER_DIRS_NUM];     /* orig. data des*/
+	struct iser_data_buf         data_copy[ISER_DIRS_NUM];/* contig. copy  */
+};
+
+struct iser_page_vec {
+	u64 *pages;
+	int length;
+	int offset;
+	int data_size;
+};
+
+struct iser_global {
+	struct mutex      device_list_mutex;/*                   */
+	struct list_head  device_list;	     /* all iSER devices */
+	struct mutex      connlist_mutex;
+	struct list_head  connlist;		/* all iSER IB connections */
+
+	kmem_cache_t *desc_cache;
+};
+
+extern struct iser_global ig;
+extern int iser_debug_level;
+
+/* allocate connection resources needed for rdma functionality */
+int iser_conn_set_full_featured_mode(struct iscsi_conn *conn);
+
+int iser_send_control(struct iscsi_conn      *conn,
+		      struct iscsi_mgmt_task *mtask);
+
+int iser_send_command(struct iscsi_conn      *conn,
+		      struct iscsi_cmd_task  *ctask);
+
+int iser_send_data_out(struct iscsi_conn     *conn,
+		       struct iscsi_cmd_task *ctask,
+		       struct iscsi_data          *hdr);
+
+void iscsi_iser_recv(struct iscsi_conn *conn,
+		     struct iscsi_hdr       *hdr,
+		     char                   *rx_data,
+		     int                    rx_data_len);
+
+int  iser_conn_init(struct iser_conn **ib_conn);
+
+void iser_conn_terminate(struct iser_conn *ib_conn);
+
+void iser_conn_release(struct iser_conn *ib_conn);
+
+void iser_rcv_completion(struct iser_desc *desc,
+			 unsigned long    dto_xfer_len);
+
+void iser_snd_completion(struct iser_desc *desc);
+
+void iser_ctask_rdma_init(struct iscsi_iser_cmd_task     *ctask);
+
+void iser_ctask_rdma_finalize(struct iscsi_iser_cmd_task *ctask);
+
+void iser_dto_buffs_release(struct iser_dto *dto);
+
+int  iser_regd_buff_release(struct iser_regd_buf *regd_buf);
+
+void iser_reg_single(struct iser_device      *device,
+		     struct iser_regd_buf    *regd_buf,
+		     enum dma_data_direction direction);
+
+int  iser_start_rdma_unaligned_sg(struct iscsi_iser_cmd_task    *ctask,
+				  enum iser_data_dir            cmd_dir);
+
+void iser_finalize_rdma_unaligned_sg(struct iscsi_iser_cmd_task *ctask,
+				     enum iser_data_dir         cmd_dir);
+
+int  iser_reg_rdma_mem(struct iscsi_iser_cmd_task *ctask,
+		       enum   iser_data_dir        cmd_dir);
+
+int  iser_connect(struct iser_conn   *ib_conn,
+		  struct sockaddr_in *src_addr,
+		  struct sockaddr_in *dst_addr,
+		  int                non_blocking);
+
+int  iser_reg_page_vec(struct iser_conn     *ib_conn,
+		       struct iser_page_vec *page_vec,
+		       struct iser_mem_reg  *mem_reg);
+
+void iser_unreg_mem(struct iser_mem_reg *mem_reg);
+
+int  iser_post_recv(struct iser_desc *rx_desc);
+int  iser_post_send(struct iser_desc *tx_desc);
+
+int iser_conn_state_comp(struct iser_conn *ib_conn,
+			 enum iser_ib_conn_state comp);
+#endif
diff --git a/drivers/infiniband/ulp/iser/iser_initiator.c b/drivers/infiniband/ulp/iser/iser_initiator.c
new file mode 100644
index 000000000..ccf56f6f7
--- /dev/null
+++ b/drivers/infiniband/ulp/iser/iser_initiator.c
@@ -0,0 +1,738 @@
+/*
+ * Copyright (c) 2004, 2005, 2006 Voltaire, 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
+ * 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.
+ *
+ * $Id: iser_initiator.c 6964 2006-05-07 11:11:43Z ogerlitz $
+ */
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/mm.h>
+#include <asm/io.h>
+#include <asm/scatterlist.h>
+#include <linux/scatterlist.h>
+#include <linux/kfifo.h>
+#include <scsi/scsi_cmnd.h>
+#include <scsi/scsi_host.h>
+
+#include "iscsi_iser.h"
+
+/* Constant PDU lengths calculations */
+#define ISER_TOTAL_HEADERS_LEN  (sizeof (struct iser_hdr) + \
+				 sizeof (struct iscsi_hdr))
+
+/* iser_dto_add_regd_buff - increments the reference count for *
+ * the registered buffer & adds it to the DTO object           */
+static void iser_dto_add_regd_buff(struct iser_dto *dto,
+				   struct iser_regd_buf *regd_buf,
+				   unsigned long use_offset,
+				   unsigned long use_size)
+{
+	int add_idx;
+
+	atomic_inc(&regd_buf->ref_count);
+
+	add_idx = dto->regd_vector_len;
+	dto->regd[add_idx] = regd_buf;
+	dto->used_sz[add_idx] = use_size;
+	dto->offset[add_idx] = use_offset;
+
+	dto->regd_vector_len++;
+}
+
+static int iser_dma_map_task_data(struct iscsi_iser_cmd_task *iser_ctask,
+				  struct iser_data_buf       *data,
+				  enum   iser_data_dir       iser_dir,
+				  enum   dma_data_direction  dma_dir)
+{
+	struct device *dma_device;
+
+	iser_ctask->dir[iser_dir] = 1;
+	dma_device = iser_ctask->iser_conn->ib_conn->device->ib_device->dma_device;
+
+	data->dma_nents = dma_map_sg(dma_device, data->buf, data->size, dma_dir);
+	if (data->dma_nents == 0) {
+		iser_err("dma_map_sg failed!!!\n");
+		return -EINVAL;
+	}
+	return 0;
+}
+
+static void iser_dma_unmap_task_data(struct iscsi_iser_cmd_task *iser_ctask)
+{
+	struct device  *dma_device;
+	struct iser_data_buf *data;
+
+	dma_device = iser_ctask->iser_conn->ib_conn->device->ib_device->dma_device;
+
+	if (iser_ctask->dir[ISER_DIR_IN]) {
+		data = &iser_ctask->data[ISER_DIR_IN];
+		dma_unmap_sg(dma_device, data->buf, data->size, DMA_FROM_DEVICE);
+	}
+
+	if (iser_ctask->dir[ISER_DIR_OUT]) {
+		data = &iser_ctask->data[ISER_DIR_OUT];
+		dma_unmap_sg(dma_device, data->buf, data->size, DMA_TO_DEVICE);
+	}
+}
+
+/* Register user buffer memory and initialize passive rdma
+ *  dto descriptor. Total data size is stored in
+ *  iser_ctask->data[ISER_DIR_IN].data_len
+ */
+static int iser_prepare_read_cmd(struct iscsi_cmd_task *ctask,
+				 unsigned int edtl)
+
+{
+	struct iscsi_iser_cmd_task *iser_ctask = ctask->dd_data;
+	struct iser_regd_buf *regd_buf;
+	int err;
+	struct iser_hdr *hdr = &iser_ctask->desc.iser_header;
+	struct iser_data_buf *buf_in = &iser_ctask->data[ISER_DIR_IN];
+
+	err = iser_dma_map_task_data(iser_ctask,
+				     buf_in,
+				     ISER_DIR_IN,
+				     DMA_FROM_DEVICE);
+	if (err)
+		return err;
+
+	if (edtl > iser_ctask->data[ISER_DIR_IN].data_len) {
+		iser_err("Total data length: %ld, less than EDTL: "
+			 "%d, in READ cmd BHS itt: %d, conn: 0x%p\n",
+			 iser_ctask->data[ISER_DIR_IN].data_len, edtl,
+			 ctask->itt, iser_ctask->iser_conn);
+		return -EINVAL;
+	}
+
+	err = iser_reg_rdma_mem(iser_ctask,ISER_DIR_IN);
+	if (err) {
+		iser_err("Failed to set up Data-IN RDMA\n");
+		return err;
+	}
+	regd_buf = &iser_ctask->rdma_regd[ISER_DIR_IN];
+
+	hdr->flags    |= ISER_RSV;
+	hdr->read_stag = cpu_to_be32(regd_buf->reg.rkey);
+	hdr->read_va   = cpu_to_be64(regd_buf->reg.va);
+
+	iser_dbg("Cmd itt:%d READ tags RKEY:%#.4X VA:%#llX\n",
+		 ctask->itt, regd_buf->reg.rkey,
+		 (unsigned long long)regd_buf->reg.va);
+
+	return 0;
+}
+
+/* Register user buffer memory and initialize passive rdma
+ *  dto descriptor. Total data size is stored in
+ *  ctask->data[ISER_DIR_OUT].data_len
+ */
+static int
+iser_prepare_write_cmd(struct iscsi_cmd_task *ctask,
+		       unsigned int imm_sz,
+		       unsigned int unsol_sz,
+		       unsigned int edtl)
+{
+	struct iscsi_iser_cmd_task *iser_ctask = ctask->dd_data;
+	struct iser_regd_buf *regd_buf;
+	int err;
+	struct iser_dto *send_dto = &iser_ctask->desc.dto;
+	struct iser_hdr *hdr = &iser_ctask->desc.iser_header;
+	struct iser_data_buf *buf_out = &iser_ctask->data[ISER_DIR_OUT];
+
+	err = iser_dma_map_task_data(iser_ctask,
+				     buf_out,
+				     ISER_DIR_OUT,
+				     DMA_TO_DEVICE);
+	if (err)
+		return err;
+
+	if (edtl > iser_ctask->data[ISER_DIR_OUT].data_len) {
+		iser_err("Total data length: %ld, less than EDTL: %d, "
+			 "in WRITE cmd BHS itt: %d, conn: 0x%p\n",
+			 iser_ctask->data[ISER_DIR_OUT].data_len,
+			 edtl, ctask->itt, ctask->conn);
+		return -EINVAL;
+	}
+
+	err = iser_reg_rdma_mem(iser_ctask,ISER_DIR_OUT);
+	if (err != 0) {
+		iser_err("Failed to register write cmd RDMA mem\n");
+		return err;
+	}
+
+	regd_buf = &iser_ctask->rdma_regd[ISER_DIR_OUT];
+
+	if (unsol_sz < edtl) {
+		hdr->flags     |= ISER_WSV;
+		hdr->write_stag = cpu_to_be32(regd_buf->reg.rkey);
+		hdr->write_va   = cpu_to_be64(regd_buf->reg.va + unsol_sz);
+
+		iser_dbg("Cmd itt:%d, WRITE tags, RKEY:%#.4X "
+			 "VA:%#llX + unsol:%d\n",
+			 ctask->itt, regd_buf->reg.rkey,
+			 (unsigned long long)regd_buf->reg.va, unsol_sz);
+	}
+
+	if (imm_sz > 0) {
+		iser_dbg("Cmd itt:%d, WRITE, adding imm.data sz: %d\n",
+			 ctask->itt, imm_sz);
+		iser_dto_add_regd_buff(send_dto,
+				       regd_buf,
+				       0,
+				       imm_sz);
+	}
+
+	return 0;
+}
+
+/**
+ * iser_post_receive_control - allocates, initializes and posts receive DTO.
+ */
+static int iser_post_receive_control(struct iscsi_conn *conn)
+{
+	struct iscsi_iser_conn *iser_conn = conn->dd_data;
+	struct iser_desc     *rx_desc;
+	struct iser_regd_buf *regd_hdr;
+	struct iser_regd_buf *regd_data;
+	struct iser_dto      *recv_dto = NULL;
+	struct iser_device  *device = iser_conn->ib_conn->device;
+	int rx_data_size, err = 0;
+
+	rx_desc = kmem_cache_alloc(ig.desc_cache, GFP_NOIO);
+	if (rx_desc == NULL) {
+		iser_err("Failed to alloc desc for post recv\n");
+		return -ENOMEM;
+	}
+	rx_desc->type = ISCSI_RX;
+
+	/* for the login sequence we must support rx of upto 8K; login is done
+	 * after conn create/bind (connect) and conn stop/bind (reconnect),
+	 * what's common for both schemes is that the connection is not started
+	 */
+	if (conn->c_stage != ISCSI_CONN_STARTED)
+		rx_data_size = DEFAULT_MAX_RECV_DATA_SEGMENT_LENGTH;
+	else /* FIXME till user space sets conn->max_recv_dlength correctly */
+		rx_data_size = 128;
+
+	rx_desc->data = kmalloc(rx_data_size, GFP_NOIO);
+	if (rx_desc->data == NULL) {
+		iser_err("Failed to alloc data buf for post recv\n");
+		err = -ENOMEM;
+		goto post_rx_kmalloc_failure;
+	}
+
+	recv_dto = &rx_desc->dto;
+	recv_dto->conn          = iser_conn;
+	recv_dto->regd_vector_len = 0;
+
+	regd_hdr = &rx_desc->hdr_regd_buf;
+	memset(regd_hdr, 0, sizeof(struct iser_regd_buf));
+	regd_hdr->device  = device;
+	regd_hdr->virt_addr  = rx_desc; /* == &rx_desc->iser_header */
+	regd_hdr->data_size  = ISER_TOTAL_HEADERS_LEN;
+
+	iser_reg_single(device, regd_hdr, DMA_FROM_DEVICE);
+
+	iser_dto_add_regd_buff(recv_dto, regd_hdr, 0, 0);
+
+	regd_data = &rx_desc->data_regd_buf;
+	memset(regd_data, 0, sizeof(struct iser_regd_buf));
+	regd_data->device  = device;
+	regd_data->virt_addr  = rx_desc->data;
+	regd_data->data_size  = rx_data_size;
+
+	iser_reg_single(device, regd_data, DMA_FROM_DEVICE);
+
+	iser_dto_add_regd_buff(recv_dto, regd_data, 0, 0);
+
+	err = iser_post_recv(rx_desc);
+	if (!err)
+		return 0;
+
+	/* iser_post_recv failed */
+	iser_dto_buffs_release(recv_dto);
+	kfree(rx_desc->data);
+post_rx_kmalloc_failure:
+	kmem_cache_free(ig.desc_cache, rx_desc);
+	return err;
+}
+
+/* creates a new tx descriptor and adds header regd buffer */
+static void iser_create_send_desc(struct iscsi_iser_conn *iser_conn,
+				  struct iser_desc       *tx_desc)
+{
+	struct iser_regd_buf *regd_hdr = &tx_desc->hdr_regd_buf;
+	struct iser_dto      *send_dto = &tx_desc->dto;
+
+	memset(regd_hdr, 0, sizeof(struct iser_regd_buf));
+	regd_hdr->device  = iser_conn->ib_conn->device;
+	regd_hdr->virt_addr  = tx_desc; /* == &tx_desc->iser_header */
+	regd_hdr->data_size  = ISER_TOTAL_HEADERS_LEN;
+
+	send_dto->conn          = iser_conn;
+	send_dto->notify_enable   = 1;
+	send_dto->regd_vector_len = 0;
+
+	memset(&tx_desc->iser_header, 0, sizeof(struct iser_hdr));
+	tx_desc->iser_header.flags = ISER_VER;
+
+	iser_dto_add_regd_buff(send_dto, regd_hdr, 0, 0);
+}
+
+/**
+ *  iser_conn_set_full_featured_mode - (iSER API)
+ */
+int iser_conn_set_full_featured_mode(struct iscsi_conn *conn)
+{
+	struct iscsi_iser_conn *iser_conn = conn->dd_data;
+
+	int i;
+	/* no need to keep it in a var, we are after login so if this should
+	 * be negotiated, by now the result should be available here */
+	int initial_post_recv_bufs_num = ISER_MAX_RX_MISC_PDUS;
+
+	iser_dbg("Initially post: %d\n", initial_post_recv_bufs_num);
+
+	/* Check that there is no posted recv or send buffers left - */
+	/* they must be consumed during the login phase */
+	BUG_ON(atomic_read(&iser_conn->ib_conn->post_recv_buf_count) != 0);
+	BUG_ON(atomic_read(&iser_conn->ib_conn->post_send_buf_count) != 0);
+
+	/* Initial post receive buffers */
+	for (i = 0; i < initial_post_recv_bufs_num; i++) {
+		if (iser_post_receive_control(conn) != 0) {
+			iser_err("Failed to post recv bufs at:%d conn:0x%p\n",
+				 i, conn);
+			return -ENOMEM;
+		}
+	}
+	iser_dbg("Posted %d post recv bufs, conn:0x%p\n", i, conn);
+	return 0;
+}
+
+static int
+iser_check_xmit(struct iscsi_conn *conn, void *task)
+{
+	int rc = 0;
+	struct iscsi_iser_conn *iser_conn = conn->dd_data;
+
+	write_lock_bh(conn->recv_lock);
+	if (atomic_read(&iser_conn->ib_conn->post_send_buf_count) ==
+	    ISER_QP_MAX_REQ_DTOS) {
+		iser_dbg("%ld can't xmit task %p, suspending tx\n",jiffies,task);
+		set_bit(ISCSI_SUSPEND_BIT, &conn->suspend_tx);
+		rc = -EAGAIN;
+	}
+	write_unlock_bh(conn->recv_lock);
+	return rc;
+}
+
+
+/**
+ * iser_send_command - send command PDU
+ */
+int iser_send_command(struct iscsi_conn     *conn,
+		      struct iscsi_cmd_task *ctask)
+{
+	struct iscsi_iser_conn *iser_conn = conn->dd_data;
+	struct iscsi_iser_cmd_task *iser_ctask = ctask->dd_data;
+	struct iser_dto *send_dto = NULL;
+	unsigned long edtl;
+	int err = 0;
+	struct iser_data_buf *data_buf;
+
+	struct iscsi_cmd *hdr =  ctask->hdr;
+	struct scsi_cmnd *sc  =  ctask->sc;
+
+	if (!iser_conn_state_comp(iser_conn->ib_conn, ISER_CONN_UP)) {
+		iser_err("Failed to send, conn: 0x%p is not up\n", iser_conn->ib_conn);
+		return -EPERM;
+	}
+	if (iser_check_xmit(conn, ctask))
+		return -EAGAIN;
+
+	edtl = ntohl(hdr->data_length);
+
+	/* build the tx desc regd header and add it to the tx desc dto */
+	iser_ctask->desc.type = ISCSI_TX_SCSI_COMMAND;
+	send_dto = &iser_ctask->desc.dto;
+	send_dto->ctask = iser_ctask;
+	iser_create_send_desc(iser_conn, &iser_ctask->desc);
+
+	if (hdr->flags & ISCSI_FLAG_CMD_READ)
+		data_buf = &iser_ctask->data[ISER_DIR_IN];
+	else
+		data_buf = &iser_ctask->data[ISER_DIR_OUT];
+
+	if (sc->use_sg) { /* using a scatter list */
+		data_buf->buf  = sc->request_buffer;
+		data_buf->size = sc->use_sg;
+	} else if (sc->request_bufflen) {
+		/* using a single buffer - convert it into one entry SG */
+		sg_init_one(&data_buf->sg_single,
+			    sc->request_buffer, sc->request_bufflen);
+		data_buf->buf   = &data_buf->sg_single;
+		data_buf->size  = 1;
+	}
+
+	data_buf->data_len = sc->request_bufflen;
+
+	if (hdr->flags & ISCSI_FLAG_CMD_READ) {
+		err = iser_prepare_read_cmd(ctask, edtl);
+		if (err)
+			goto send_command_error;
+	}
+	if (hdr->flags & ISCSI_FLAG_CMD_WRITE) {
+		err = iser_prepare_write_cmd(ctask,
+					     ctask->imm_count,
+				             ctask->imm_count +
+					     ctask->unsol_count,
+					     edtl);
+		if (err)
+			goto send_command_error;
+	}
+
+	iser_reg_single(iser_conn->ib_conn->device,
+			send_dto->regd[0], DMA_TO_DEVICE);
+
+	if (iser_post_receive_control(conn) != 0) {
+		iser_err("post_recv failed!\n");
+		err = -ENOMEM;
+		goto send_command_error;
+	}
+
+	iser_ctask->status = ISER_TASK_STATUS_STARTED;
+
+	err = iser_post_send(&iser_ctask->desc);
+	if (!err)
+		return 0;
+
+send_command_error:
+	iser_dto_buffs_release(send_dto);
+	iser_err("conn %p failed ctask->itt %d err %d\n",conn, ctask->itt, err);
+	return err;
+}
+
+/**
+ * iser_send_data_out - send data out PDU
+ */
+int iser_send_data_out(struct iscsi_conn     *conn,
+		       struct iscsi_cmd_task *ctask,
+		       struct iscsi_data *hdr)
+{
+	struct iscsi_iser_conn *iser_conn = conn->dd_data;
+	struct iscsi_iser_cmd_task *iser_ctask = ctask->dd_data;
+	struct iser_desc *tx_desc = NULL;
+	struct iser_dto *send_dto = NULL;
+	unsigned long buf_offset;
+	unsigned long data_seg_len;
+	unsigned int itt;
+	int err = 0;
+
+	if (!iser_conn_state_comp(iser_conn->ib_conn, ISER_CONN_UP)) {
+		iser_err("Failed to send, conn: 0x%p is not up\n", iser_conn->ib_conn);
+		return -EPERM;
+	}
+
+	if (iser_check_xmit(conn, ctask))
+		return -EAGAIN;
+
+	itt = ntohl(hdr->itt);
+	data_seg_len = ntoh24(hdr->dlength);
+	buf_offset   = ntohl(hdr->offset);
+
+	iser_dbg("%s itt %d dseg_len %d offset %d\n",
+		 __func__,(int)itt,(int)data_seg_len,(int)buf_offset);
+
+	tx_desc = kmem_cache_alloc(ig.desc_cache, GFP_NOIO);
+	if (tx_desc == NULL) {
+		iser_err("Failed to alloc desc for post dataout\n");
+		return -ENOMEM;
+	}
+
+	tx_desc->type = ISCSI_TX_DATAOUT;
+	memcpy(&tx_desc->iscsi_header, hdr, sizeof(struct iscsi_hdr));
+
+	/* build the tx desc regd header and add it to the tx desc dto */
+	send_dto = &tx_desc->dto;
+	send_dto->ctask = iser_ctask;
+	iser_create_send_desc(iser_conn, tx_desc);
+
+	iser_reg_single(iser_conn->ib_conn->device,
+			send_dto->regd[0], DMA_TO_DEVICE);
+
+	/* all data was registered for RDMA, we can use the lkey */
+	iser_dto_add_regd_buff(send_dto,
+			       &iser_ctask->rdma_regd[ISER_DIR_OUT],
+			       buf_offset,
+			       data_seg_len);
+
+	if (buf_offset + data_seg_len > iser_ctask->data[ISER_DIR_OUT].data_len) {
+		iser_err("Offset:%ld & DSL:%ld in Data-Out "
+			 "inconsistent with total len:%ld, itt:%d\n",
+			 buf_offset, data_seg_len,
+			 iser_ctask->data[ISER_DIR_OUT].data_len, itt);
+		err = -EINVAL;
+		goto send_data_out_error;
+	}
+	iser_dbg("data-out itt: %d, offset: %ld, sz: %ld\n",
+		 itt, buf_offset, data_seg_len);
+
+
+	err = iser_post_send(tx_desc);
+	if (!err)
+		return 0;
+
+send_data_out_error:
+	iser_dto_buffs_release(send_dto);
+	kmem_cache_free(ig.desc_cache, tx_desc);
+	iser_err("conn %p failed err %d\n",conn, err);
+	return err;
+}
+
+int iser_send_control(struct iscsi_conn *conn,
+		      struct iscsi_mgmt_task *mtask)
+{
+	struct iscsi_iser_conn *iser_conn = conn->dd_data;
+	struct iser_desc *mdesc = mtask->dd_data;
+	struct iser_dto *send_dto = NULL;
+	unsigned int itt;
+	unsigned long data_seg_len;
+	int err = 0;
+	unsigned char opcode;
+	struct iser_regd_buf *regd_buf;
+	struct iser_device *device;
+
+	if (!iser_conn_state_comp(iser_conn->ib_conn, ISER_CONN_UP)) {
+		iser_err("Failed to send, conn: 0x%p is not up\n", iser_conn->ib_conn);
+		return -EPERM;
+	}
+
+	if (iser_check_xmit(conn,mtask))
+		return -EAGAIN;
+
+	/* build the tx desc regd header and add it to the tx desc dto */
+	mdesc->type = ISCSI_TX_CONTROL;
+	send_dto = &mdesc->dto;
+	send_dto->ctask = NULL;
+	iser_create_send_desc(iser_conn, mdesc);
+
+	device = iser_conn->ib_conn->device;
+
+	iser_reg_single(device, send_dto->regd[0], DMA_TO_DEVICE);
+
+	itt = ntohl(mtask->hdr->itt);
+	opcode = mtask->hdr->opcode & ISCSI_OPCODE_MASK;
+	data_seg_len = ntoh24(mtask->hdr->dlength);
+
+	if (data_seg_len > 0) {
+		regd_buf = &mdesc->data_regd_buf;
+		memset(regd_buf, 0, sizeof(struct iser_regd_buf));
+		regd_buf->device = device;
+		regd_buf->virt_addr = mtask->data;
+		regd_buf->data_size = mtask->data_count;
+		iser_reg_single(device, regd_buf,
+				DMA_TO_DEVICE);
+		iser_dto_add_regd_buff(send_dto, regd_buf,
+				       0,
+				       data_seg_len);
+	}
+
+	if (iser_post_receive_control(conn) != 0) {
+		iser_err("post_rcv_buff failed!\n");
+		err = -ENOMEM;
+		goto send_control_error;
+	}
+
+	err = iser_post_send(mdesc);
+	if (!err)
+		return 0;
+
+send_control_error:
+	iser_dto_buffs_release(send_dto);
+	iser_err("conn %p failed err %d\n",conn, err);
+	return err;
+}
+
+/**
+ * iser_rcv_dto_completion - recv DTO completion
+ */
+void iser_rcv_completion(struct iser_desc *rx_desc,
+			 unsigned long dto_xfer_len)
+{
+	struct iser_dto        *dto = &rx_desc->dto;
+	struct iscsi_iser_conn *conn = dto->conn;
+	struct iscsi_session *session = conn->iscsi_conn->session;
+	struct iscsi_cmd_task *ctask;
+	struct iscsi_iser_cmd_task *iser_ctask;
+	struct iscsi_hdr *hdr;
+	char   *rx_data = NULL;
+	int     rx_data_len = 0;
+	unsigned int itt;
+	unsigned char opcode;
+
+	hdr = &rx_desc->iscsi_header;
+
+	iser_dbg("op 0x%x itt 0x%x\n", hdr->opcode,hdr->itt);
+
+	if (dto_xfer_len > ISER_TOTAL_HEADERS_LEN) { /* we have data */
+		rx_data_len = dto_xfer_len - ISER_TOTAL_HEADERS_LEN;
+		rx_data     = dto->regd[1]->virt_addr;
+		rx_data    += dto->offset[1];
+	}
+
+	opcode = hdr->opcode & ISCSI_OPCODE_MASK;
+
+	if (opcode == ISCSI_OP_SCSI_CMD_RSP) {
+	        itt = hdr->itt & ISCSI_ITT_MASK; /* mask out cid and age bits */
+		if (!(itt < session->cmds_max))
+			iser_err("itt can't be matched to task!!!"
+				 "conn %p opcode %d cmds_max %d itt %d\n",
+				 conn->iscsi_conn,opcode,session->cmds_max,itt);
+		/* use the mapping given with the cmds array indexed by itt */
+		ctask = (struct iscsi_cmd_task *)session->cmds[itt];
+		iser_ctask = ctask->dd_data;
+		iser_dbg("itt %d ctask %p\n",itt,ctask);
+		iser_ctask->status = ISER_TASK_STATUS_COMPLETED;
+		iser_ctask_rdma_finalize(iser_ctask);
+	}
+
+	iser_dto_buffs_release(dto);
+
+	iscsi_iser_recv(conn->iscsi_conn, hdr, rx_data, rx_data_len);
+
+	kfree(rx_desc->data);
+	kmem_cache_free(ig.desc_cache, rx_desc);
+
+	/* decrementing conn->post_recv_buf_count only --after-- freeing the   *
+	 * task eliminates the need to worry on tasks which are completed in   *
+	 * parallel to the execution of iser_conn_term. So the code that waits *
+	 * for the posted rx bufs refcount to become zero handles everything   */
+	atomic_dec(&conn->ib_conn->post_recv_buf_count);
+}
+
+void iser_snd_completion(struct iser_desc *tx_desc)
+{
+	struct iser_dto        *dto = &tx_desc->dto;
+	struct iscsi_iser_conn *iser_conn = dto->conn;
+	struct iscsi_conn      *conn = iser_conn->iscsi_conn;
+	struct iscsi_mgmt_task *mtask;
+
+	iser_dbg("Initiator, Data sent dto=0x%p\n", dto);
+
+	iser_dto_buffs_release(dto);
+
+	if (tx_desc->type == ISCSI_TX_DATAOUT)
+		kmem_cache_free(ig.desc_cache, tx_desc);
+
+	atomic_dec(&iser_conn->ib_conn->post_send_buf_count);
+
+	write_lock(conn->recv_lock);
+	if (conn->suspend_tx) {
+		iser_dbg("%ld resuming tx\n",jiffies);
+		clear_bit(ISCSI_SUSPEND_BIT, &conn->suspend_tx);
+		scsi_queue_work(conn->session->host, &conn->xmitwork);
+	}
+	write_unlock(conn->recv_lock);
+
+	if (tx_desc->type == ISCSI_TX_CONTROL) {
+		/* this arithmetic is legal by libiscsi dd_data allocation */
+		mtask = (void *) ((long)(void *)tx_desc -
+				  sizeof(struct iscsi_mgmt_task));
+		if (mtask->hdr->itt == cpu_to_be32(ISCSI_RESERVED_TAG)) {
+			struct iscsi_session *session = conn->session;
+
+			spin_lock(&conn->session->lock);
+			list_del(&mtask->running);
+			__kfifo_put(session->mgmtpool.queue, (void*)&mtask,
+				    sizeof(void*));
+			spin_unlock(&session->lock);
+		}
+	}
+}
+
+void iser_ctask_rdma_init(struct iscsi_iser_cmd_task *iser_ctask)
+
+{
+	iser_ctask->status = ISER_TASK_STATUS_INIT;
+
+	iser_ctask->dir[ISER_DIR_IN] = 0;
+	iser_ctask->dir[ISER_DIR_OUT] = 0;
+
+	iser_ctask->data[ISER_DIR_IN].data_len  = 0;
+	iser_ctask->data[ISER_DIR_OUT].data_len = 0;
+
+	memset(&iser_ctask->rdma_regd[ISER_DIR_IN], 0,
+	       sizeof(struct iser_regd_buf));
+	memset(&iser_ctask->rdma_regd[ISER_DIR_OUT], 0,
+	       sizeof(struct iser_regd_buf));
+}
+
+void iser_ctask_rdma_finalize(struct iscsi_iser_cmd_task *iser_ctask)
+{
+	int deferred;
+
+	/* if we were reading, copy back to unaligned sglist,
+	 * anyway dma_unmap and free the copy
+	 */
+	if (iser_ctask->data_copy[ISER_DIR_IN].copy_buf != NULL)
+		iser_finalize_rdma_unaligned_sg(iser_ctask, ISER_DIR_IN);
+	if (iser_ctask->data_copy[ISER_DIR_OUT].copy_buf != NULL)
+		iser_finalize_rdma_unaligned_sg(iser_ctask, ISER_DIR_OUT);
+
+	if (iser_ctask->dir[ISER_DIR_IN]) {
+		deferred = iser_regd_buff_release
+			(&iser_ctask->rdma_regd[ISER_DIR_IN]);
+		if (deferred) {
+			iser_err("References remain for BUF-IN rdma reg\n");
+			BUG();
+		}
+	}
+
+	if (iser_ctask->dir[ISER_DIR_OUT]) {
+		deferred = iser_regd_buff_release
+			(&iser_ctask->rdma_regd[ISER_DIR_OUT]);
+		if (deferred) {
+			iser_err("References remain for BUF-OUT rdma reg\n");
+			BUG();
+		}
+	}
+
+	iser_dma_unmap_task_data(iser_ctask);
+}
+
+void iser_dto_buffs_release(struct iser_dto *dto)
+{
+	int i;
+
+	for (i = 0; i < dto->regd_vector_len; i++)
+		iser_regd_buff_release(dto->regd[i]);
+}
+
diff --git a/drivers/infiniband/ulp/iser/iser_memory.c b/drivers/infiniband/ulp/iser/iser_memory.c
new file mode 100644
index 000000000..31950a522
--- /dev/null
+++ b/drivers/infiniband/ulp/iser/iser_memory.c
@@ -0,0 +1,401 @@
+/*
+ * Copyright (c) 2004, 2005, 2006 Voltaire, 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
+ * 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.
+ *
+ * $Id: iser_memory.c 6964 2006-05-07 11:11:43Z ogerlitz $
+ */
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/mm.h>
+#include <asm/io.h>
+#include <asm/scatterlist.h>
+#include <linux/scatterlist.h>
+
+#include "iscsi_iser.h"
+
+#define ISER_KMALLOC_THRESHOLD 0x20000 /* 128K - kmalloc limit */
+/**
+ * Decrements the reference count for the
+ * registered buffer & releases it
+ *
+ * returns 0 if released, 1 if deferred
+ */
+int iser_regd_buff_release(struct iser_regd_buf *regd_buf)
+{
+	struct device *dma_device;
+
+	if ((atomic_read(&regd_buf->ref_count) == 0) ||
+	    atomic_dec_and_test(&regd_buf->ref_count)) {
+		/* if we used the dma mr, unreg is just NOP */
+		if (regd_buf->reg.rkey != 0)
+			iser_unreg_mem(&regd_buf->reg);
+
+		if (regd_buf->dma_addr) {
+			dma_device = regd_buf->device->ib_device->dma_device;
+			dma_unmap_single(dma_device,
+					 regd_buf->dma_addr,
+					 regd_buf->data_size,
+					 regd_buf->direction);
+		}
+		/* else this regd buf is associated with task which we */
+		/* dma_unmap_single/sg later */
+		return 0;
+	} else {
+		iser_dbg("Release deferred, regd.buff: 0x%p\n", regd_buf);
+		return 1;
+	}
+}
+
+/**
+ * iser_reg_single - fills registered buffer descriptor with
+ *		     registration information
+ */
+void iser_reg_single(struct iser_device *device,
+		     struct iser_regd_buf *regd_buf,
+		     enum dma_data_direction direction)
+{
+	dma_addr_t dma_addr;
+
+	dma_addr  = dma_map_single(device->ib_device->dma_device,
+				   regd_buf->virt_addr,
+				   regd_buf->data_size, direction);
+	BUG_ON(dma_mapping_error(dma_addr));
+
+	regd_buf->reg.lkey = device->mr->lkey;
+	regd_buf->reg.rkey = 0; /* indicate there's no need to unreg */
+	regd_buf->reg.len  = regd_buf->data_size;
+	regd_buf->reg.va   = dma_addr;
+
+	regd_buf->dma_addr  = dma_addr;
+	regd_buf->direction = direction;
+}
+
+/**
+ * iser_start_rdma_unaligned_sg
+ */
+int iser_start_rdma_unaligned_sg(struct iscsi_iser_cmd_task  *iser_ctask,
+				 enum iser_data_dir cmd_dir)
+{
+	int dma_nents;
+	struct device *dma_device;
+	char *mem = NULL;
+	struct iser_data_buf *data = &iser_ctask->data[cmd_dir];
+	unsigned long  cmd_data_len = data->data_len;
+
+	if (cmd_data_len > ISER_KMALLOC_THRESHOLD)
+		mem = (void *)__get_free_pages(GFP_NOIO,
+		      long_log2(roundup_pow_of_two(cmd_data_len)) - PAGE_SHIFT);
+	else
+		mem = kmalloc(cmd_data_len, GFP_NOIO);
+
+	if (mem == NULL) {
+		iser_err("Failed to allocate mem size %d %d for copying sglist\n",
+			 data->size,(int)cmd_data_len);
+		return -ENOMEM;
+	}
+
+	if (cmd_dir == ISER_DIR_OUT) {
+		/* copy the unaligned sg the buffer which is used for RDMA */
+		struct scatterlist *sg = (struct scatterlist *)data->buf;
+		int i;
+		char *p, *from;
+
+		for (p = mem, i = 0; i < data->size; i++) {
+			from = kmap_atomic(sg[i].page, KM_USER0);
+			memcpy(p,
+			       from + sg[i].offset,
+			       sg[i].length);
+			kunmap_atomic(from, KM_USER0);
+			p += sg[i].length;
+		}
+	}
+
+	sg_init_one(&iser_ctask->data_copy[cmd_dir].sg_single, mem, cmd_data_len);
+	iser_ctask->data_copy[cmd_dir].buf  =
+		&iser_ctask->data_copy[cmd_dir].sg_single;
+	iser_ctask->data_copy[cmd_dir].size = 1;
+
+	iser_ctask->data_copy[cmd_dir].copy_buf  = mem;
+
+	dma_device = iser_ctask->iser_conn->ib_conn->device->ib_device->dma_device;
+
+	if (cmd_dir == ISER_DIR_OUT)
+		dma_nents = dma_map_sg(dma_device,
+				       &iser_ctask->data_copy[cmd_dir].sg_single,
+				       1, DMA_TO_DEVICE);
+	else
+		dma_nents = dma_map_sg(dma_device,
+				       &iser_ctask->data_copy[cmd_dir].sg_single,
+				       1, DMA_FROM_DEVICE);
+
+	BUG_ON(dma_nents == 0);
+
+	iser_ctask->data_copy[cmd_dir].dma_nents = dma_nents;
+	return 0;
+}
+
+/**
+ * iser_finalize_rdma_unaligned_sg
+ */
+void iser_finalize_rdma_unaligned_sg(struct iscsi_iser_cmd_task *iser_ctask,
+				     enum iser_data_dir         cmd_dir)
+{
+	struct device *dma_device;
+	struct iser_data_buf *mem_copy;
+	unsigned long  cmd_data_len;
+
+	dma_device = iser_ctask->iser_conn->ib_conn->device->ib_device->dma_device;
+	mem_copy   = &iser_ctask->data_copy[cmd_dir];
+
+	if (cmd_dir == ISER_DIR_OUT)
+		dma_unmap_sg(dma_device, &mem_copy->sg_single, 1,
+			     DMA_TO_DEVICE);
+	else
+		dma_unmap_sg(dma_device, &mem_copy->sg_single, 1,
+			     DMA_FROM_DEVICE);
+
+	if (cmd_dir == ISER_DIR_IN) {
+		char *mem;
+		struct scatterlist *sg;
+		unsigned char *p, *to;
+		unsigned int sg_size;
+		int i;
+
+		/* copy back read RDMA to unaligned sg */
+		mem	= mem_copy->copy_buf;
+
+		sg	= (struct scatterlist *)iser_ctask->data[ISER_DIR_IN].buf;
+		sg_size = iser_ctask->data[ISER_DIR_IN].size;
+
+		for (p = mem, i = 0; i < sg_size; i++){
+			to = kmap_atomic(sg[i].page, KM_SOFTIRQ0);
+			memcpy(to + sg[i].offset,
+			       p,
+			       sg[i].length);
+			kunmap_atomic(to, KM_SOFTIRQ0);
+			p += sg[i].length;
+		}
+	}
+
+	cmd_data_len = iser_ctask->data[cmd_dir].data_len;
+
+	if (cmd_data_len > ISER_KMALLOC_THRESHOLD)
+		free_pages((unsigned long)mem_copy->copy_buf,
+			   long_log2(roundup_pow_of_two(cmd_data_len)) - PAGE_SHIFT);
+	else
+		kfree(mem_copy->copy_buf);
+
+	mem_copy->copy_buf = NULL;
+}
+
+/**
+ * iser_sg_to_page_vec - Translates scatterlist entries to physical addresses
+ * and returns the length of resulting physical address array (may be less than
+ * the original due to possible compaction).
+ *
+ * we build a "page vec" under the assumption that the SG meets the RDMA
+ * alignment requirements. Other then the first and last SG elements, all
+ * the "internal" elements can be compacted into a list whose elements are
+ * dma addresses of physical pages. The code supports also the weird case
+ * where --few fragments of the same page-- are present in the SG as
+ * consecutive elements. Also, it handles one entry SG.
+ */
+static int iser_sg_to_page_vec(struct iser_data_buf *data,
+			       struct iser_page_vec *page_vec)
+{
+	struct scatterlist *sg = (struct scatterlist *)data->buf;
+	dma_addr_t first_addr, last_addr, page;
+	int start_aligned, end_aligned;
+	unsigned int cur_page = 0;
+	unsigned long total_sz = 0;
+	int i;
+
+	/* compute the offset of first element */
+	page_vec->offset = (u64) sg[0].offset;
+
+	for (i = 0; i < data->dma_nents; i++) {
+		total_sz += sg_dma_len(&sg[i]);
+
+		first_addr = sg_dma_address(&sg[i]);
+		last_addr  = first_addr + sg_dma_len(&sg[i]);
+
+		start_aligned = !(first_addr & ~PAGE_MASK);
+		end_aligned   = !(last_addr  & ~PAGE_MASK);
+
+		/* continue to collect page fragments till aligned or SG ends */
+		while (!end_aligned && (i + 1 < data->dma_nents)) {
+			i++;
+			total_sz += sg_dma_len(&sg[i]);
+			last_addr = sg_dma_address(&sg[i]) + sg_dma_len(&sg[i]);
+			end_aligned = !(last_addr  & ~PAGE_MASK);
+		}
+
+		first_addr = first_addr & PAGE_MASK;
+
+		for (page = first_addr; page < last_addr; page += PAGE_SIZE)
+			page_vec->pages[cur_page++] = page;
+
+	}
+	page_vec->data_size = total_sz;
+	iser_dbg("page_vec->data_size:%d cur_page %d\n", page_vec->data_size,cur_page);
+	return cur_page;
+}
+
+#define MASK_4K			((1UL << 12) - 1) /* 0xFFF */
+#define IS_4K_ALIGNED(addr)	((((unsigned long)addr) & MASK_4K) == 0)
+
+/**
+ * iser_data_buf_aligned_len - Tries to determine the maximal correctly aligned
+ * for RDMA sub-list of a scatter-gather list of memory buffers, and  returns
+ * the number of entries which are aligned correctly. Supports the case where
+ * consecutive SG elements are actually fragments of the same physcial page.
+ */
+static unsigned int iser_data_buf_aligned_len(struct iser_data_buf *data)
+{
+	struct scatterlist *sg;
+	dma_addr_t end_addr, next_addr;
+	int i, cnt;
+	unsigned int ret_len = 0;
+
+	sg = (struct scatterlist *)data->buf;
+
+	for (cnt = 0, i = 0; i < data->dma_nents; i++, cnt++) {
+		/* iser_dbg("Checking sg iobuf [%d]: phys=0x%08lX "
+		   "offset: %ld sz: %ld\n", i,
+		   (unsigned long)page_to_phys(sg[i].page),
+		   (unsigned long)sg[i].offset,
+		   (unsigned long)sg[i].length); */
+		end_addr = sg_dma_address(&sg[i]) +
+			   sg_dma_len(&sg[i]);
+		/* iser_dbg("Checking sg iobuf end address "
+		       "0x%08lX\n", end_addr); */
+		if (i + 1 < data->dma_nents) {
+			next_addr = sg_dma_address(&sg[i+1]);
+			/* are i, i+1 fragments of the same page? */
+			if (end_addr == next_addr)
+				continue;
+			else if (!IS_4K_ALIGNED(end_addr)) {
+				ret_len = cnt + 1;
+				break;
+			}
+		}
+	}
+	if (i == data->dma_nents)
+		ret_len = cnt;	/* loop ended */
+	iser_dbg("Found %d aligned entries out of %d in sg:0x%p\n",
+		 ret_len, data->dma_nents, data);
+	return ret_len;
+}
+
+static void iser_data_buf_dump(struct iser_data_buf *data)
+{
+	struct scatterlist *sg = (struct scatterlist *)data->buf;
+	int i;
+
+	for (i = 0; i < data->size; i++)
+		iser_err("sg[%d] dma_addr:0x%lX page:0x%p "
+			 "off:%d sz:%d dma_len:%d\n",
+			 i, (unsigned long)sg_dma_address(&sg[i]),
+			 sg[i].page, sg[i].offset,
+			 sg[i].length,sg_dma_len(&sg[i]));
+}
+
+static void iser_dump_page_vec(struct iser_page_vec *page_vec)
+{
+	int i;
+
+	iser_err("page vec length %d data size %d\n",
+		 page_vec->length, page_vec->data_size);
+	for (i = 0; i < page_vec->length; i++)
+		iser_err("%d %lx\n",i,(unsigned long)page_vec->pages[i]);
+}
+
+static void iser_page_vec_build(struct iser_data_buf *data,
+				struct iser_page_vec *page_vec)
+{
+	int page_vec_len = 0;
+
+	page_vec->length = 0;
+	page_vec->offset = 0;
+
+	iser_dbg("Translating sg sz: %d\n", data->dma_nents);
+	page_vec_len = iser_sg_to_page_vec(data,page_vec);
+	iser_dbg("sg len %d page_vec_len %d\n", data->dma_nents,page_vec_len);
+
+	page_vec->length = page_vec_len;
+
+	if (page_vec_len * PAGE_SIZE < page_vec->data_size) {
+		iser_err("page_vec too short to hold this SG\n");
+		iser_data_buf_dump(data);
+		iser_dump_page_vec(page_vec);
+		BUG();
+	}
+}
+
+/**
+ * iser_reg_rdma_mem - Registers memory intended for RDMA,
+ * obtaining rkey and va
+ *
+ * returns 0 on success, errno code on failure
+ */
+int iser_reg_rdma_mem(struct iscsi_iser_cmd_task *iser_ctask,
+		      enum   iser_data_dir        cmd_dir)
+{
+	struct iser_conn     *ib_conn = iser_ctask->iser_conn->ib_conn;
+	struct iser_data_buf *mem = &iser_ctask->data[cmd_dir];
+	struct iser_regd_buf *regd_buf;
+	int aligned_len;
+	int err;
+
+	regd_buf = &iser_ctask->rdma_regd[cmd_dir];
+
+	aligned_len = iser_data_buf_aligned_len(mem);
+	if (aligned_len != mem->size) {
+		iser_err("rdma alignment violation %d/%d aligned\n",
+			 aligned_len, mem->size);
+		iser_data_buf_dump(mem);
+		/* allocate copy buf, if we are writing, copy the */
+		/* unaligned scatterlist, dma map the copy        */
+		if (iser_start_rdma_unaligned_sg(iser_ctask, cmd_dir) != 0)
+				return -ENOMEM;
+		mem = &iser_ctask->data_copy[cmd_dir];
+	}
+
+	iser_page_vec_build(mem, ib_conn->page_vec);
+	err = iser_reg_page_vec(ib_conn, ib_conn->page_vec, &regd_buf->reg);
+	if (err)
+		return err;
+
+	/* take a reference on this regd buf such that it will not be released *
+	 * (eg in send dto completion) before we get the scsi response         */
+	atomic_inc(&regd_buf->ref_count);
+	return 0;
+}
diff --git a/drivers/infiniband/ulp/iser/iser_verbs.c b/drivers/infiniband/ulp/iser/iser_verbs.c
new file mode 100644
index 000000000..72febf1f8
--- /dev/null
+++ b/drivers/infiniband/ulp/iser/iser_verbs.c
@@ -0,0 +1,827 @@
+/*
+ * Copyright (c) 2004, 2005, 2006 Voltaire, Inc. All rights reserved.
+ * Copyright (c) 2005, 2006 Cisco Systems.  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.
+ *
+ * $Id: iser_verbs.c 7051 2006-05-10 12:29:11Z ogerlitz $
+ */
+#include <asm/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/smp_lock.h>
+#include <linux/delay.h>
+#include <linux/version.h>
+
+#include "iscsi_iser.h"
+
+#define ISCSI_ISER_MAX_CONN	8
+#define ISER_MAX_CQ_LEN		((ISER_QP_MAX_RECV_DTOS + \
+				ISER_QP_MAX_REQ_DTOS) *   \
+				 ISCSI_ISER_MAX_CONN)
+
+static void iser_cq_tasklet_fn(unsigned long data);
+static void iser_cq_callback(struct ib_cq *cq, void *cq_context);
+static void iser_comp_error_worker(void *data);
+
+static void iser_cq_event_callback(struct ib_event *cause, void *context)
+{
+	iser_err("got cq event %d \n", cause->event);
+}
+
+static void iser_qp_event_callback(struct ib_event *cause, void *context)
+{
+	iser_err("got qp event %d\n",cause->event);
+}
+
+/**
+ * iser_create_device_ib_res - creates Protection Domain (PD), Completion
+ * Queue (CQ), DMA Memory Region (DMA MR) with the device associated with
+ * the adapator.
+ *
+ * returns 0 on success, -1 on failure
+ */
+static int iser_create_device_ib_res(struct iser_device *device)
+{
+	device->pd = ib_alloc_pd(device->ib_device);
+	if (IS_ERR(device->pd))
+		goto pd_err;
+
+	device->cq = ib_create_cq(device->ib_device,
+				  iser_cq_callback,
+				  iser_cq_event_callback,
+				  (void *)device,
+				  ISER_MAX_CQ_LEN);
+	if (IS_ERR(device->cq))
+		goto cq_err;
+
+	if (ib_req_notify_cq(device->cq, IB_CQ_NEXT_COMP))
+		goto cq_arm_err;
+
+	tasklet_init(&device->cq_tasklet,
+		     iser_cq_tasklet_fn,
+		     (unsigned long)device);
+
+	device->mr = ib_get_dma_mr(device->pd,
+				   IB_ACCESS_LOCAL_WRITE);
+	if (IS_ERR(device->mr))
+		goto dma_mr_err;
+
+	return 0;
+
+dma_mr_err:
+	tasklet_kill(&device->cq_tasklet);
+cq_arm_err:
+	ib_destroy_cq(device->cq);
+cq_err:
+	ib_dealloc_pd(device->pd);
+pd_err:
+	iser_err("failed to allocate an IB resource\n");
+	return -1;
+}
+
+/**
+ * iser_free_device_ib_res - destory/dealloc/dereg the DMA MR,
+ * CQ and PD created with the device associated with the adapator.
+ */
+static void iser_free_device_ib_res(struct iser_device *device)
+{
+	BUG_ON(device->mr == NULL);
+
+	tasklet_kill(&device->cq_tasklet);
+
+	(void)ib_dereg_mr(device->mr);
+	(void)ib_destroy_cq(device->cq);
+	(void)ib_dealloc_pd(device->pd);
+
+	device->mr = NULL;
+	device->cq = NULL;
+	device->pd = NULL;
+}
+
+/**
+ * iser_create_ib_conn_res - Creates FMR pool and Queue-Pair (QP)
+ *
+ * returns 0 on success, -1 on failure
+ */
+static int iser_create_ib_conn_res(struct iser_conn *ib_conn)
+{
+	struct iser_device	*device;
+	struct ib_qp_init_attr	init_attr;
+	int			ret;
+	struct ib_fmr_pool_param params;
+
+	BUG_ON(ib_conn->device == NULL);
+
+	device = ib_conn->device;
+
+	ib_conn->page_vec = kmalloc(sizeof(struct iser_page_vec) +
+				    (sizeof(u64) * (ISCSI_ISER_SG_TABLESIZE +1)),
+				    GFP_KERNEL);
+	if (!ib_conn->page_vec) {
+		ret = -ENOMEM;
+		goto alloc_err;
+	}
+	ib_conn->page_vec->pages = (u64 *) (ib_conn->page_vec + 1);
+
+	params.page_shift        = PAGE_SHIFT;
+	/* when the first/last SG element are not start/end *
+	 * page aligned, the map whould be of N+1 pages     */
+	params.max_pages_per_fmr = ISCSI_ISER_SG_TABLESIZE + 1;
+	/* make the pool size twice the max number of SCSI commands *
+	 * the ML is expected to queue, watermark for unmap at 50%  */
+	params.pool_size	 = ISCSI_XMIT_CMDS_MAX * 2;
+	params.dirty_watermark	 = ISCSI_XMIT_CMDS_MAX;
+	params.cache		 = 0;
+	params.flush_function	 = NULL;
+	params.access		 = (IB_ACCESS_LOCAL_WRITE  |
+				    IB_ACCESS_REMOTE_WRITE |
+				    IB_ACCESS_REMOTE_READ);
+
+	ib_conn->fmr_pool = ib_create_fmr_pool(device->pd, &params);
+	if (IS_ERR(ib_conn->fmr_pool)) {
+		ret = PTR_ERR(ib_conn->fmr_pool);
+		goto fmr_pool_err;
+	}
+
+	memset(&init_attr, 0, sizeof init_attr);
+
+	init_attr.event_handler = iser_qp_event_callback;
+	init_attr.qp_context	= (void *)ib_conn;
+	init_attr.send_cq	= device->cq;
+	init_attr.recv_cq	= device->cq;
+	init_attr.cap.max_send_wr  = ISER_QP_MAX_REQ_DTOS;
+	init_attr.cap.max_recv_wr  = ISER_QP_MAX_RECV_DTOS;
+	init_attr.cap.max_send_sge = MAX_REGD_BUF_VECTOR_LEN;
+	init_attr.cap.max_recv_sge = 2;
+	init_attr.sq_sig_type	= IB_SIGNAL_REQ_WR;
+	init_attr.qp_type	= IB_QPT_RC;
+
+	ret = rdma_create_qp(ib_conn->cma_id, device->pd, &init_attr);
+	if (ret)
+		goto qp_err;
+
+	ib_conn->qp = ib_conn->cma_id->qp;
+	iser_err("setting conn %p cma_id %p: fmr_pool %p qp %p\n",
+		 ib_conn, ib_conn->cma_id,
+		 ib_conn->fmr_pool, ib_conn->cma_id->qp);
+	return ret;
+
+qp_err:
+	(void)ib_destroy_fmr_pool(ib_conn->fmr_pool);
+fmr_pool_err:
+	kfree(ib_conn->page_vec);
+alloc_err:
+	iser_err("unable to alloc mem or create resource, err %d\n", ret);
+	return ret;
+}
+
+/**
+ * releases the FMR pool, QP and CMA ID objects, returns 0 on success,
+ * -1 on failure
+ */
+static int iser_free_ib_conn_res(struct iser_conn *ib_conn)
+{
+	BUG_ON(ib_conn == NULL);
+
+	iser_err("freeing conn %p cma_id %p fmr pool %p qp %p\n",
+		 ib_conn, ib_conn->cma_id,
+		 ib_conn->fmr_pool, ib_conn->qp);
+
+	/* qp is created only once both addr & route are resolved */
+	if (ib_conn->fmr_pool != NULL)
+		ib_destroy_fmr_pool(ib_conn->fmr_pool);
+
+	if (ib_conn->qp != NULL)
+		rdma_destroy_qp(ib_conn->cma_id);
+
+	if (ib_conn->cma_id != NULL)
+		rdma_destroy_id(ib_conn->cma_id);
+
+	ib_conn->fmr_pool = NULL;
+	ib_conn->qp	  = NULL;
+	ib_conn->cma_id   = NULL;
+	kfree(ib_conn->page_vec);
+
+	return 0;
+}
+
+/**
+ * based on the resolved device node GUID see if there already allocated
+ * device for this device. If there's no such, create one.
+ */
+static
+struct iser_device *iser_device_find_by_ib_device(struct rdma_cm_id *cma_id)
+{
+	struct list_head    *p_list;
+	struct iser_device  *device = NULL;
+
+	mutex_lock(&ig.device_list_mutex);
+
+	p_list = ig.device_list.next;
+	while (p_list != &ig.device_list) {
+		device = list_entry(p_list, struct iser_device, ig_list);
+		/* find if there's a match using the node GUID */
+		if (device->ib_device->node_guid == cma_id->device->node_guid)
+			break;
+	}
+
+	if (device == NULL) {
+		device = kzalloc(sizeof *device, GFP_KERNEL);
+		if (device == NULL)
+			goto out;
+		/* assign this device to the device */
+		device->ib_device = cma_id->device;
+		/* init the device and link it into ig device list */
+		if (iser_create_device_ib_res(device)) {
+			kfree(device);
+			device = NULL;
+			goto out;
+		}
+		list_add(&device->ig_list, &ig.device_list);
+	}
+out:
+	BUG_ON(device == NULL);
+	device->refcount++;
+	mutex_unlock(&ig.device_list_mutex);
+	return device;
+}
+
+/* if there's no demand for this device, release it */
+static void iser_device_try_release(struct iser_device *device)
+{
+	mutex_lock(&ig.device_list_mutex);
+	device->refcount--;
+	iser_err("device %p refcount %d\n",device,device->refcount);
+	if (!device->refcount) {
+		iser_free_device_ib_res(device);
+		list_del(&device->ig_list);
+		kfree(device);
+	}
+	mutex_unlock(&ig.device_list_mutex);
+}
+
+int iser_conn_state_comp(struct iser_conn *ib_conn,
+			enum iser_ib_conn_state comp)
+{
+	int ret;
+
+	spin_lock_bh(&ib_conn->lock);
+	ret = (ib_conn->state == comp);
+	spin_unlock_bh(&ib_conn->lock);
+	return ret;
+}
+
+static int iser_conn_state_comp_exch(struct iser_conn *ib_conn,
+				     enum iser_ib_conn_state comp,
+				     enum iser_ib_conn_state exch)
+{
+	int ret;
+
+	spin_lock_bh(&ib_conn->lock);
+	if ((ret = (ib_conn->state == comp)))
+		ib_conn->state = exch;
+	spin_unlock_bh(&ib_conn->lock);
+	return ret;
+}
+
+/**
+ * triggers start of the disconnect procedures and wait for them to be done
+ */
+void iser_conn_terminate(struct iser_conn *ib_conn)
+{
+	int err = 0;
+
+	/* change the ib conn state only if the conn is UP, however always call
+	 * rdma_disconnect since this is the only way to cause the CMA to change
+	 * the QP state to ERROR
+	 */
+
+	iser_conn_state_comp_exch(ib_conn, ISER_CONN_UP, ISER_CONN_TERMINATING);
+	err = rdma_disconnect(ib_conn->cma_id);
+	if (err)
+		iser_err("Failed to disconnect, conn: 0x%p err %d\n",
+			 ib_conn,err);
+
+	wait_event_interruptible(ib_conn->wait,
+				 ib_conn->state == ISER_CONN_DOWN);
+
+	iser_conn_release(ib_conn);
+}
+
+static void iser_connect_error(struct rdma_cm_id *cma_id)
+{
+	struct iser_conn *ib_conn;
+	ib_conn = (struct iser_conn *)cma_id->context;
+
+	ib_conn->state = ISER_CONN_DOWN;
+	wake_up_interruptible(&ib_conn->wait);
+}
+
+static void iser_addr_handler(struct rdma_cm_id *cma_id)
+{
+	struct iser_device *device;
+	struct iser_conn   *ib_conn;
+	int    ret;
+
+	device = iser_device_find_by_ib_device(cma_id);
+	ib_conn = (struct iser_conn *)cma_id->context;
+	ib_conn->device = device;
+
+	ret = rdma_resolve_route(cma_id, 1000);
+	if (ret) {
+		iser_err("resolve route failed: %d\n", ret);
+		iser_connect_error(cma_id);
+	}
+	return;
+}
+
+static void iser_route_handler(struct rdma_cm_id *cma_id)
+{
+	struct rdma_conn_param conn_param;
+	int    ret;
+
+	ret = iser_create_ib_conn_res((struct iser_conn *)cma_id->context);
+	if (ret)
+		goto failure;
+
+	iser_dbg("path.mtu is %d setting it to %d\n",
+		 cma_id->route.path_rec->mtu, IB_MTU_1024);
+
+	/* we must set the MTU to 1024 as this is what the target is assuming */
+	if (cma_id->route.path_rec->mtu > IB_MTU_1024)
+		cma_id->route.path_rec->mtu = IB_MTU_1024;
+
+	memset(&conn_param, 0, sizeof conn_param);
+	conn_param.responder_resources = 4;
+	conn_param.initiator_depth     = 1;
+	conn_param.retry_count	       = 7;
+	conn_param.rnr_retry_count     = 6;
+
+	ret = rdma_connect(cma_id, &conn_param);
+	if (ret) {
+		iser_err("failure connecting: %d\n", ret);
+		goto failure;
+	}
+
+	return;
+failure:
+	iser_connect_error(cma_id);
+}
+
+static void iser_connected_handler(struct rdma_cm_id *cma_id)
+{
+	struct iser_conn *ib_conn;
+
+	ib_conn = (struct iser_conn *)cma_id->context;
+	ib_conn->state = ISER_CONN_UP;
+	wake_up_interruptible(&ib_conn->wait);
+}
+
+static void iser_disconnected_handler(struct rdma_cm_id *cma_id)
+{
+	struct iser_conn *ib_conn;
+
+	ib_conn = (struct iser_conn *)cma_id->context;
+	ib_conn->disc_evt_flag = 1;
+
+	/* getting here when the state is UP means that the conn is being *
+	 * terminated asynchronously from the iSCSI layer's perspective.  */
+	if (iser_conn_state_comp_exch(ib_conn, ISER_CONN_UP,
+				      ISER_CONN_TERMINATING))
+		iscsi_conn_failure(ib_conn->iser_conn->iscsi_conn,
+				   ISCSI_ERR_CONN_FAILED);
+
+	/* Complete the termination process if no posts are pending */
+	if ((atomic_read(&ib_conn->post_recv_buf_count) == 0) &&
+	    (atomic_read(&ib_conn->post_send_buf_count) == 0)) {
+		ib_conn->state = ISER_CONN_DOWN;
+		wake_up_interruptible(&ib_conn->wait);
+	}
+}
+
+static int iser_cma_handler(struct rdma_cm_id *cma_id, struct rdma_cm_event *event)
+{
+	int ret = 0;
+
+	iser_err("event %d conn %p id %p\n",event->event,cma_id->context,cma_id);
+
+	switch (event->event) {
+	case RDMA_CM_EVENT_ADDR_RESOLVED:
+		iser_addr_handler(cma_id);
+		break;
+	case RDMA_CM_EVENT_ROUTE_RESOLVED:
+		iser_route_handler(cma_id);
+		break;
+	case RDMA_CM_EVENT_ESTABLISHED:
+		iser_connected_handler(cma_id);
+		break;
+	case RDMA_CM_EVENT_ADDR_ERROR:
+	case RDMA_CM_EVENT_ROUTE_ERROR:
+	case RDMA_CM_EVENT_CONNECT_ERROR:
+	case RDMA_CM_EVENT_UNREACHABLE:
+	case RDMA_CM_EVENT_REJECTED:
+		iser_err("event: %d, error: %d\n", event->event, event->status);
+		iser_connect_error(cma_id);
+		break;
+	case RDMA_CM_EVENT_DISCONNECTED:
+		iser_disconnected_handler(cma_id);
+		break;
+	case RDMA_CM_EVENT_DEVICE_REMOVAL:
+		BUG();
+		break;
+	case RDMA_CM_EVENT_CONNECT_RESPONSE:
+		BUG();
+		break;
+	case RDMA_CM_EVENT_CONNECT_REQUEST:
+	default:
+		break;
+	}
+	return ret;
+}
+
+int iser_conn_init(struct iser_conn **ibconn)
+{
+	struct iser_conn *ib_conn;
+
+	ib_conn = kzalloc(sizeof *ib_conn, GFP_KERNEL);
+	if (!ib_conn) {
+		iser_err("can't alloc memory for struct iser_conn\n");
+		return -ENOMEM;
+	}
+	ib_conn->state = ISER_CONN_INIT;
+	init_waitqueue_head(&ib_conn->wait);
+	atomic_set(&ib_conn->post_recv_buf_count, 0);
+	atomic_set(&ib_conn->post_send_buf_count, 0);
+	INIT_WORK(&ib_conn->comperror_work, iser_comp_error_worker,
+		  ib_conn);
+	INIT_LIST_HEAD(&ib_conn->conn_list);
+	spin_lock_init(&ib_conn->lock);
+
+	*ibconn = ib_conn;
+	return 0;
+}
+
+ /**
+ * starts the process of connecting to the target
+ * sleeps untill the connection is established or rejected
+ */
+int iser_connect(struct iser_conn   *ib_conn,
+		 struct sockaddr_in *src_addr,
+		 struct sockaddr_in *dst_addr,
+		 int                 non_blocking)
+{
+	struct sockaddr *src, *dst;
+	int err = 0;
+
+	sprintf(ib_conn->name,"%d.%d.%d.%d:%d",
+		NIPQUAD(dst_addr->sin_addr.s_addr), dst_addr->sin_port);
+
+	/* the device is known only --after-- address resolution */
+	ib_conn->device = NULL;
+
+	iser_err("connecting to: %d.%d.%d.%d, port 0x%x\n",
+		 NIPQUAD(dst_addr->sin_addr), dst_addr->sin_port);
+
+	ib_conn->state = ISER_CONN_PENDING;
+
+	ib_conn->cma_id = rdma_create_id(iser_cma_handler,
+					     (void *)ib_conn,
+					     RDMA_PS_TCP);
+	if (IS_ERR(ib_conn->cma_id)) {
+		err = PTR_ERR(ib_conn->cma_id);
+		iser_err("rdma_create_id failed: %d\n", err);
+		goto id_failure;
+	}
+
+	src = (struct sockaddr *)src_addr;
+	dst = (struct sockaddr *)dst_addr;
+	err = rdma_resolve_addr(ib_conn->cma_id, src, dst, 1000);
+	if (err) {
+		iser_err("rdma_resolve_addr failed: %d\n", err);
+		goto addr_failure;
+	}
+
+	if (!non_blocking) {
+		wait_event_interruptible(ib_conn->wait,
+					 (ib_conn->state != ISER_CONN_PENDING));
+
+		if (ib_conn->state != ISER_CONN_UP) {
+			err =  -EIO;
+			goto connect_failure;
+		}
+	}
+
+	mutex_lock(&ig.connlist_mutex);
+	list_add(&ib_conn->conn_list, &ig.connlist);
+	mutex_unlock(&ig.connlist_mutex);
+	return 0;
+
+id_failure:
+	ib_conn->cma_id = NULL;
+addr_failure:
+	ib_conn->state = ISER_CONN_DOWN;
+connect_failure:
+	iser_conn_release(ib_conn);
+	return err;
+}
+
+/**
+ * Frees all conn objects and deallocs conn descriptor
+ */
+void iser_conn_release(struct iser_conn *ib_conn)
+{
+	struct iser_device  *device = ib_conn->device;
+
+	BUG_ON(ib_conn->state != ISER_CONN_DOWN);
+
+	mutex_lock(&ig.connlist_mutex);
+	list_del(&ib_conn->conn_list);
+	mutex_unlock(&ig.connlist_mutex);
+
+	iser_free_ib_conn_res(ib_conn);
+	ib_conn->device = NULL;
+	/* on EVENT_ADDR_ERROR there's no device yet for this conn */
+	if (device != NULL)
+		iser_device_try_release(device);
+	kfree(ib_conn);
+}
+
+
+/**
+ * iser_reg_page_vec - Register physical memory
+ *
+ * returns: 0 on success, errno code on failure
+ */
+int iser_reg_page_vec(struct iser_conn     *ib_conn,
+		      struct iser_page_vec *page_vec,
+		      struct iser_mem_reg  *mem_reg)
+{
+	struct ib_pool_fmr *mem;
+	u64		   io_addr;
+	u64		   *page_list;
+	int		   status;
+
+	page_list = page_vec->pages;
+	io_addr	  = page_list[0];
+
+	mem  = ib_fmr_pool_map_phys(ib_conn->fmr_pool,
+				    page_list,
+				    page_vec->length,
+				    io_addr);
+
+	if (IS_ERR(mem)) {
+		status = (int)PTR_ERR(mem);
+		iser_err("ib_fmr_pool_map_phys failed: %d\n", status);
+		return status;
+	}
+
+	mem_reg->lkey  = mem->fmr->lkey;
+	mem_reg->rkey  = mem->fmr->rkey;
+	mem_reg->len   = page_vec->length * PAGE_SIZE;
+	mem_reg->va    = io_addr;
+	mem_reg->mem_h = (void *)mem;
+
+	mem_reg->va   += page_vec->offset;
+	mem_reg->len   = page_vec->data_size;
+
+	iser_dbg("PHYSICAL Mem.register, [PHYS p_array: 0x%p, sz: %d, "
+		 "entry[0]: (0x%08lx,%ld)] -> "
+		 "[lkey: 0x%08X mem_h: 0x%p va: 0x%08lX sz: %ld]\n",
+		 page_vec, page_vec->length,
+		 (unsigned long)page_vec->pages[0],
+		 (unsigned long)page_vec->data_size,
+		 (unsigned int)mem_reg->lkey, mem_reg->mem_h,
+		 (unsigned long)mem_reg->va, (unsigned long)mem_reg->len);
+	return 0;
+}
+
+/**
+ * Unregister (previosuly registered) memory.
+ */
+void iser_unreg_mem(struct iser_mem_reg *reg)
+{
+	int ret;
+
+	iser_dbg("PHYSICAL Mem.Unregister mem_h %p\n",reg->mem_h);
+
+	ret = ib_fmr_pool_unmap((struct ib_pool_fmr *)reg->mem_h);
+	if (ret)
+		iser_err("ib_fmr_pool_unmap failed %d\n", ret);
+
+	reg->mem_h = NULL;
+}
+
+/**
+ * iser_dto_to_iov - builds IOV from a dto descriptor
+ */
+static void iser_dto_to_iov(struct iser_dto *dto, struct ib_sge *iov, int iov_len)
+{
+	int		     i;
+	struct ib_sge	     *sge;
+	struct iser_regd_buf *regd_buf;
+
+	if (dto->regd_vector_len > iov_len) {
+		iser_err("iov size %d too small for posting dto of len %d\n",
+			 iov_len, dto->regd_vector_len);
+		BUG();
+	}
+
+	for (i = 0; i < dto->regd_vector_len; i++) {
+		sge	    = &iov[i];
+		regd_buf  = dto->regd[i];
+
+		sge->addr   = regd_buf->reg.va;
+		sge->length = regd_buf->reg.len;
+		sge->lkey   = regd_buf->reg.lkey;
+
+		if (dto->used_sz[i] > 0)  /* Adjust size */
+			sge->length = dto->used_sz[i];
+
+		/* offset and length should not exceed the regd buf length */
+		if (sge->length + dto->offset[i] > regd_buf->reg.len) {
+			iser_err("Used len:%ld + offset:%d, exceed reg.buf.len:"
+				 "%ld in dto:0x%p [%d], va:0x%08lX\n",
+				 (unsigned long)sge->length, dto->offset[i],
+				 (unsigned long)regd_buf->reg.len, dto, i,
+				 (unsigned long)sge->addr);
+			BUG();
+		}
+
+		sge->addr += dto->offset[i]; /* Adjust offset */
+	}
+}
+
+/**
+ * iser_post_recv - Posts a receive buffer.
+ *
+ * returns 0 on success, -1 on failure
+ */
+int iser_post_recv(struct iser_desc *rx_desc)
+{
+	int		  ib_ret, ret_val = 0;
+	struct ib_recv_wr recv_wr, *recv_wr_failed;
+	struct ib_sge	  iov[2];
+	struct iser_conn  *ib_conn;
+	struct iser_dto   *recv_dto = &rx_desc->dto;
+
+	/* Retrieve conn */
+	ib_conn = recv_dto->conn->ib_conn;
+
+	iser_dto_to_iov(recv_dto, iov, 2);
+
+	recv_wr.next	= NULL;
+	recv_wr.sg_list = iov;
+	recv_wr.num_sge = recv_dto->regd_vector_len;
+	recv_wr.wr_id	= (unsigned long)rx_desc;
+
+	atomic_inc(&ib_conn->post_recv_buf_count);
+	ib_ret	= ib_post_recv(ib_conn->qp, &recv_wr, &recv_wr_failed);
+	if (ib_ret) {
+		iser_err("ib_post_recv failed ret=%d\n", ib_ret);
+		atomic_dec(&ib_conn->post_recv_buf_count);
+		ret_val = -1;
+	}
+
+	return ret_val;
+}
+
+/**
+ * iser_start_send - Initiate a Send DTO operation
+ *
+ * returns 0 on success, -1 on failure
+ */
+int iser_post_send(struct iser_desc *tx_desc)
+{
+	int		  ib_ret, ret_val = 0;
+	struct ib_send_wr send_wr, *send_wr_failed;
+	struct ib_sge	  iov[MAX_REGD_BUF_VECTOR_LEN];
+	struct iser_conn  *ib_conn;
+	struct iser_dto   *dto = &tx_desc->dto;
+
+	ib_conn = dto->conn->ib_conn;
+
+	iser_dto_to_iov(dto, iov, MAX_REGD_BUF_VECTOR_LEN);
+
+	send_wr.next	   = NULL;
+	send_wr.wr_id	   = (unsigned long)tx_desc;
+	send_wr.sg_list	   = iov;
+	send_wr.num_sge	   = dto->regd_vector_len;
+	send_wr.opcode	   = IB_WR_SEND;
+	send_wr.send_flags = dto->notify_enable ? IB_SEND_SIGNALED : 0;
+
+	atomic_inc(&ib_conn->post_send_buf_count);
+
+	ib_ret = ib_post_send(ib_conn->qp, &send_wr, &send_wr_failed);
+	if (ib_ret) {
+		iser_err("Failed to start SEND DTO, dto: 0x%p, IOV len: %d\n",
+			 dto, dto->regd_vector_len);
+		iser_err("ib_post_send failed, ret:%d\n", ib_ret);
+		atomic_dec(&ib_conn->post_send_buf_count);
+		ret_val = -1;
+	}
+
+	return ret_val;
+}
+
+static void iser_comp_error_worker(void *data)
+{
+	struct iser_conn *ib_conn = data;
+
+	/* getting here when the state is UP means that the conn is being *
+	 * terminated asynchronously from the iSCSI layer's perspective.  */
+	if (iser_conn_state_comp_exch(ib_conn, ISER_CONN_UP,
+				      ISER_CONN_TERMINATING))
+		iscsi_conn_failure(ib_conn->iser_conn->iscsi_conn,
+					ISCSI_ERR_CONN_FAILED);
+
+	/* complete the termination process if disconnect event was delivered *
+	 * note there are no more non completed posts to the QP               */
+	if (ib_conn->disc_evt_flag) {
+		ib_conn->state = ISER_CONN_DOWN;
+		wake_up_interruptible(&ib_conn->wait);
+	}
+}
+
+static void iser_handle_comp_error(struct iser_desc *desc)
+{
+	struct iser_dto  *dto     = &desc->dto;
+	struct iser_conn *ib_conn = dto->conn->ib_conn;
+
+	iser_dto_buffs_release(dto);
+
+	if (desc->type == ISCSI_RX) {
+		kfree(desc->data);
+		kmem_cache_free(ig.desc_cache, desc);
+		atomic_dec(&ib_conn->post_recv_buf_count);
+	} else { /* type is TX control/command/dataout */
+		if (desc->type == ISCSI_TX_DATAOUT)
+			kmem_cache_free(ig.desc_cache, desc);
+		atomic_dec(&ib_conn->post_send_buf_count);
+	}
+
+	if (atomic_read(&ib_conn->post_recv_buf_count) == 0 &&
+	    atomic_read(&ib_conn->post_send_buf_count) == 0)
+		schedule_work(&ib_conn->comperror_work);
+}
+
+static void iser_cq_tasklet_fn(unsigned long data)
+{
+	 struct iser_device  *device = (struct iser_device *)data;
+	 struct ib_cq	     *cq = device->cq;
+	 struct ib_wc	     wc;
+	 struct iser_desc    *desc;
+	 unsigned long	     xfer_len;
+
+	while (ib_poll_cq(cq, 1, &wc) == 1) {
+		desc	 = (struct iser_desc *) (unsigned long) wc.wr_id;
+		BUG_ON(desc == NULL);
+
+		if (wc.status == IB_WC_SUCCESS) {
+			if (desc->type == ISCSI_RX) {
+				xfer_len = (unsigned long)wc.byte_len;
+				iser_rcv_completion(desc, xfer_len);
+			} else /* type == ISCSI_TX_CONTROL/SCSI_CMD/DOUT */
+				iser_snd_completion(desc);
+		} else {
+			iser_err("comp w. error op %d status %d\n",desc->type,wc.status);
+			iser_handle_comp_error(desc);
+		}
+	}
+	/* #warning "it is assumed here that arming CQ only once its empty" *
+	 * " would not cause interrupts to be missed"                       */
+	ib_req_notify_cq(cq, IB_CQ_NEXT_COMP);
+}
+
+static void iser_cq_callback(struct ib_cq *cq, void *cq_context)
+{
+	struct iser_device  *device = (struct iser_device *)cq_context;
+
+	tasklet_schedule(&device->cq_tasklet);
+}
diff --git a/drivers/leds/leds-ams-delta.c b/drivers/leds/leds-ams-delta.c
new file mode 100644
index 000000000..599878c8e
--- /dev/null
+++ b/drivers/leds/leds-ams-delta.c
@@ -0,0 +1,161 @@
+/*
+ * LEDs driver for Amstrad Delta (E3)
+ *
+ * Copyright (C) 2006 Jonathan McDowell <noodles@earth.li>
+ *
+ * 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/platform_device.h>
+#include <linux/leds.h>
+#include <asm/arch/board-ams-delta.h>
+
+/*
+ * Our context
+ */
+struct ams_delta_led {
+	struct led_classdev	cdev;
+	u8			bitmask;
+};
+
+static void ams_delta_led_set(struct led_classdev *led_cdev,
+		enum led_brightness value)
+{
+	struct ams_delta_led *led_dev =
+		container_of(led_cdev, struct ams_delta_led, cdev);
+
+	if (value)
+		ams_delta_latch1_write(led_dev->bitmask, led_dev->bitmask);
+	else
+		ams_delta_latch1_write(led_dev->bitmask, 0);
+}
+
+static struct ams_delta_led ams_delta_leds[] = {
+	{
+		.cdev		= {
+			.name		= "ams-delta:camera",
+			.brightness_set = ams_delta_led_set,
+		},
+		.bitmask	= AMS_DELTA_LATCH1_LED_CAMERA,
+	},
+	{
+		.cdev		= {
+			.name		= "ams-delta:advert",
+			.brightness_set = ams_delta_led_set,
+		},
+		.bitmask	= AMS_DELTA_LATCH1_LED_ADVERT,
+	},
+	{
+		.cdev		= {
+			.name		= "ams-delta:email",
+			.brightness_set = ams_delta_led_set,
+		},
+		.bitmask	= AMS_DELTA_LATCH1_LED_EMAIL,
+	},
+	{
+		.cdev		= {
+			.name		= "ams-delta:handsfree",
+			.brightness_set = ams_delta_led_set,
+		},
+		.bitmask	= AMS_DELTA_LATCH1_LED_HANDSFREE,
+	},
+	{
+		.cdev		= {
+			.name		= "ams-delta:voicemail",
+			.brightness_set = ams_delta_led_set,
+		},
+		.bitmask	= AMS_DELTA_LATCH1_LED_VOICEMAIL,
+	},
+	{
+		.cdev		= {
+			.name		= "ams-delta:voice",
+			.brightness_set = ams_delta_led_set,
+		},
+		.bitmask	= AMS_DELTA_LATCH1_LED_VOICE,
+	},
+};
+
+#ifdef CONFIG_PM
+static int ams_delta_led_suspend(struct platform_device *dev,
+		pm_message_t state)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(ams_delta_leds); i++)
+		led_classdev_suspend(&ams_delta_leds[i].cdev);
+
+	return 0;
+}
+
+static int ams_delta_led_resume(struct platform_device *dev)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(ams_delta_leds); i++)
+		led_classdev_resume(&ams_delta_leds[i].cdev);
+
+	return 0;
+}
+#else
+#define ams_delta_led_suspend NULL
+#define ams_delta_led_resume NULL
+#endif
+
+static int ams_delta_led_probe(struct platform_device *pdev)
+{
+	int i;
+	int ret;
+
+	for (i = ret = 0; ret >= 0 && i < ARRAY_SIZE(ams_delta_leds); i++) {
+		ret = led_classdev_register(&pdev->dev,
+				&ams_delta_leds[i].cdev);
+	}
+
+	if (ret < 0 && i > 1) {
+		for (i = i - 2; i >= 0; i--)
+			led_classdev_unregister(&ams_delta_leds[i].cdev);
+	}
+
+	return ret;
+}
+
+static int ams_delta_led_remove(struct platform_device *pdev)
+{
+	int i;
+
+	for (i = ARRAY_SIZE(ams_delta_leds) - 1; i >= 0; i--)
+		led_classdev_unregister(&ams_delta_leds[i].cdev);
+
+	return 0;
+}
+
+static struct platform_driver ams_delta_led_driver = {
+	.probe		= ams_delta_led_probe,
+	.remove		= ams_delta_led_remove,
+	.suspend	= ams_delta_led_suspend,
+	.resume		= ams_delta_led_resume,
+	.driver		= {
+		.name = "ams-delta-led",
+	},
+};
+
+static int __init ams_delta_led_init(void)
+{
+	return platform_driver_register(&ams_delta_led_driver);
+}
+
+static void __exit ams_delta_led_exit(void)
+{
+	return platform_driver_unregister(&ams_delta_led_driver);
+}
+
+module_init(ams_delta_led_init);
+module_exit(ams_delta_led_exit);
+
+MODULE_AUTHOR("Jonathan McDowell <noodles@earth.li>");
+MODULE_DESCRIPTION("Amstrad Delta LED driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/leds/leds-net48xx.c b/drivers/leds/leds-net48xx.c
new file mode 100644
index 000000000..713c4a8aa
--- /dev/null
+++ b/drivers/leds/leds-net48xx.c
@@ -0,0 +1,116 @@
+/*
+ * LEDs driver for Soekris net48xx
+ *
+ * Copyright (C) 2006 Chris Boot <bootc@bootc.net>
+ *
+ * Based on leds-ams-delta.c
+ *
+ * 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/platform_device.h>
+#include <linux/leds.h>
+#include <linux/err.h>
+#include <asm/io.h>
+#include <linux/scx200_gpio.h>
+
+#define DRVNAME "net48xx-led"
+#define NET48XX_ERROR_LED_GPIO	20
+
+static struct platform_device *pdev;
+
+static void net48xx_error_led_set(struct led_classdev *led_cdev,
+		enum led_brightness value)
+{
+	if (value)
+		scx200_gpio_set_high(NET48XX_ERROR_LED_GPIO);
+	else
+		scx200_gpio_set_low(NET48XX_ERROR_LED_GPIO);
+}
+
+static struct led_classdev net48xx_error_led = {
+	.name		= "net48xx:error",
+	.brightness_set	= net48xx_error_led_set,
+};
+
+#ifdef CONFIG_PM
+static int net48xx_led_suspend(struct platform_device *dev,
+		pm_message_t state)
+{
+	led_classdev_suspend(&net48xx_error_led);
+	return 0;
+}
+
+static int net48xx_led_resume(struct platform_device *dev)
+{
+	led_classdev_resume(&net48xx_error_led);
+	return 0;
+}
+#else
+#define net48xx_led_suspend NULL
+#define net48xx_led_resume NULL
+#endif
+
+static int net48xx_led_probe(struct platform_device *pdev)
+{
+	return led_classdev_register(&pdev->dev, &net48xx_error_led);
+}
+
+static int net48xx_led_remove(struct platform_device *pdev)
+{
+	led_classdev_unregister(&net48xx_error_led);
+	return 0;
+}
+
+static struct platform_driver net48xx_led_driver = {
+	.probe		= net48xx_led_probe,
+	.remove		= net48xx_led_remove,
+	.suspend	= net48xx_led_suspend,
+	.resume		= net48xx_led_resume,
+	.driver		= {
+		.name		= DRVNAME,
+		.owner		= THIS_MODULE,
+	},
+};
+
+static int __init net48xx_led_init(void)
+{
+	int ret;
+
+	if (!scx200_gpio_present()) {
+		ret = -ENODEV;
+		goto out;
+	}
+
+	ret = platform_driver_register(&net48xx_led_driver);
+	if (ret < 0)
+		goto out;
+
+	pdev = platform_device_register_simple(DRVNAME, -1, NULL, 0);
+	if (IS_ERR(pdev)) {
+		ret = PTR_ERR(pdev);
+		platform_driver_unregister(&net48xx_led_driver);
+		goto out;
+	}
+
+out:
+	return ret;
+}
+
+static void __exit net48xx_led_exit(void)
+{
+	platform_device_unregister(pdev);
+	platform_driver_unregister(&net48xx_led_driver);
+}
+
+module_init(net48xx_led_init);
+module_exit(net48xx_led_exit);
+
+MODULE_AUTHOR("Chris Boot <bootc@bootc.net>");
+MODULE_DESCRIPTION("Soekris net48xx LED driver");
+MODULE_LICENSE("GPL");
+
diff --git a/drivers/leds/ledtrig-heartbeat.c b/drivers/leds/ledtrig-heartbeat.c
new file mode 100644
index 000000000..4bf8cec8b
--- /dev/null
+++ b/drivers/leds/ledtrig-heartbeat.c
@@ -0,0 +1,118 @@
+/*
+ * LED Heartbeat Trigger
+ *
+ * Copyright (C) 2006 Atsushi Nemoto <anemo@mba.ocn.ne.jp>
+ *
+ * Based on Richard Purdie's ledtrig-timer.c and some arch's
+ * CONFIG_HEARTBEAT code.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/timer.h>
+#include <linux/sched.h>
+#include <linux/leds.h>
+#include "leds.h"
+
+struct heartbeat_trig_data {
+	unsigned int phase;
+	unsigned int period;
+	struct timer_list timer;
+};
+
+static void led_heartbeat_function(unsigned long data)
+{
+	struct led_classdev *led_cdev = (struct led_classdev *) data;
+	struct heartbeat_trig_data *heartbeat_data = led_cdev->trigger_data;
+	unsigned long brightness = LED_OFF;
+	unsigned long delay = 0;
+
+	/* acts like an actual heart beat -- ie thump-thump-pause... */
+	switch (heartbeat_data->phase) {
+	case 0:
+		/*
+		 * The hyperbolic function below modifies the
+		 * heartbeat period length in dependency of the
+		 * current (1min) load. It goes through the points
+		 * f(0)=1260, f(1)=860, f(5)=510, f(inf)->300.
+		 */
+		heartbeat_data->period = 300 +
+			(6720 << FSHIFT) / (5 * avenrun[0] + (7 << FSHIFT));
+		heartbeat_data->period =
+			msecs_to_jiffies(heartbeat_data->period);
+		delay = msecs_to_jiffies(70);
+		heartbeat_data->phase++;
+		brightness = LED_FULL;
+		break;
+	case 1:
+		delay = heartbeat_data->period / 4 - msecs_to_jiffies(70);
+		heartbeat_data->phase++;
+		break;
+	case 2:
+		delay = msecs_to_jiffies(70);
+		heartbeat_data->phase++;
+		brightness = LED_FULL;
+		break;
+	default:
+		delay = heartbeat_data->period - heartbeat_data->period / 4 -
+			msecs_to_jiffies(70);
+		heartbeat_data->phase = 0;
+		break;
+	}
+
+	led_set_brightness(led_cdev, brightness);
+	mod_timer(&heartbeat_data->timer, jiffies + delay);
+}
+
+static void heartbeat_trig_activate(struct led_classdev *led_cdev)
+{
+	struct heartbeat_trig_data *heartbeat_data;
+
+	heartbeat_data = kzalloc(sizeof(*heartbeat_data), GFP_KERNEL);
+	if (!heartbeat_data)
+		return;
+
+	led_cdev->trigger_data = heartbeat_data;
+	setup_timer(&heartbeat_data->timer,
+		    led_heartbeat_function, (unsigned long) led_cdev);
+	heartbeat_data->phase = 0;
+	led_heartbeat_function(heartbeat_data->timer.data);
+}
+
+static void heartbeat_trig_deactivate(struct led_classdev *led_cdev)
+{
+	struct heartbeat_trig_data *heartbeat_data = led_cdev->trigger_data;
+
+	if (heartbeat_data) {
+		del_timer_sync(&heartbeat_data->timer);
+		kfree(heartbeat_data);
+	}
+}
+
+static struct led_trigger heartbeat_led_trigger = {
+	.name     = "heartbeat",
+	.activate = heartbeat_trig_activate,
+	.deactivate = heartbeat_trig_deactivate,
+};
+
+static int __init heartbeat_trig_init(void)
+{
+	return led_trigger_register(&heartbeat_led_trigger);
+}
+
+static void __exit heartbeat_trig_exit(void)
+{
+	led_trigger_unregister(&heartbeat_led_trigger);
+}
+
+module_init(heartbeat_trig_init);
+module_exit(heartbeat_trig_exit);
+
+MODULE_AUTHOR("Atsushi Nemoto <anemo@mba.ocn.ne.jp>");
+MODULE_DESCRIPTION("Heartbeat LED trigger");
+MODULE_LICENSE("GPL");
diff --git a/drivers/macintosh/via-pmu-backlight.c b/drivers/macintosh/via-pmu-backlight.c
new file mode 100644
index 000000000..6c29fe727
--- /dev/null
+++ b/drivers/macintosh/via-pmu-backlight.c
@@ -0,0 +1,187 @@
+/*
+ * Backlight code for via-pmu
+ *
+ * Copyright (C) 1998 Paul Mackerras and Fabio Riccardi.
+ * Copyright (C) 2001-2002 Benjamin Herrenschmidt
+ * Copyright (C) 2006      Michael Hanselmann <linux-kernel@hansmi.ch>
+ *
+ */
+
+#include <asm/ptrace.h>
+#include <linux/adb.h>
+#include <linux/pmu.h>
+#include <asm/backlight.h>
+#include <asm/prom.h>
+
+#define MAX_PMU_LEVEL 0xFF
+
+static struct backlight_properties pmu_backlight_data;
+static DEFINE_SPINLOCK(pmu_backlight_lock);
+static int sleeping;
+static u8 bl_curve[FB_BACKLIGHT_LEVELS];
+
+static void pmu_backlight_init_curve(u8 off, u8 min, u8 max)
+{
+	unsigned int i, flat, count, range = (max - min);
+
+	bl_curve[0] = off;
+
+	for (flat = 1; flat < (FB_BACKLIGHT_LEVELS / 16); ++flat)
+		bl_curve[flat] = min;
+
+	count = FB_BACKLIGHT_LEVELS * 15 / 16;
+	for (i = 0; i < count; ++i)
+		bl_curve[flat + i] = min + (range * (i + 1) / count);
+}
+
+static int pmu_backlight_curve_lookup(int value)
+{
+	int level = (FB_BACKLIGHT_LEVELS - 1);
+	int i, max = 0;
+
+	/* Look for biggest value */
+	for (i = 0; i < FB_BACKLIGHT_LEVELS; i++)
+		max = max((int)bl_curve[i], max);
+
+	/* Look for nearest value */
+	for (i = 0; i < FB_BACKLIGHT_LEVELS; i++) {
+		int diff = abs(bl_curve[i] - value);
+		if (diff < max) {
+			max = diff;
+			level = i;
+		}
+	}
+	return level;
+}
+
+static int pmu_backlight_get_level_brightness(int level)
+{
+	int pmulevel;
+
+	/* Get and convert the value */
+	pmulevel = bl_curve[level] * FB_BACKLIGHT_MAX / MAX_PMU_LEVEL;
+	if (pmulevel < 0)
+		pmulevel = 0;
+	else if (pmulevel > MAX_PMU_LEVEL)
+		pmulevel = MAX_PMU_LEVEL;
+
+	return pmulevel;
+}
+
+static int pmu_backlight_update_status(struct backlight_device *bd)
+{
+	struct adb_request req;
+	unsigned long flags;
+	int level = bd->props->brightness;
+
+	spin_lock_irqsave(&pmu_backlight_lock, flags);
+
+	/* Don't update brightness when sleeping */
+	if (sleeping)
+		goto out;
+
+	if (bd->props->power != FB_BLANK_UNBLANK ||
+	    bd->props->fb_blank != FB_BLANK_UNBLANK)
+		level = 0;
+
+	if (level > 0) {
+		int pmulevel = pmu_backlight_get_level_brightness(level);
+
+		pmu_request(&req, NULL, 2, PMU_BACKLIGHT_BRIGHT, pmulevel);
+		pmu_wait_complete(&req);
+
+		pmu_request(&req, NULL, 2, PMU_POWER_CTRL,
+			PMU_POW_BACKLIGHT | PMU_POW_ON);
+		pmu_wait_complete(&req);
+	} else {
+		pmu_request(&req, NULL, 2, PMU_POWER_CTRL,
+			PMU_POW_BACKLIGHT | PMU_POW_OFF);
+		pmu_wait_complete(&req);
+	}
+
+out:
+	spin_unlock_irqrestore(&pmu_backlight_lock, flags);
+
+	return 0;
+}
+
+static int pmu_backlight_get_brightness(struct backlight_device *bd)
+{
+	return bd->props->brightness;
+}
+
+static struct backlight_properties pmu_backlight_data = {
+	.owner		= THIS_MODULE,
+	.get_brightness	= pmu_backlight_get_brightness,
+	.update_status	= pmu_backlight_update_status,
+	.max_brightness	= (FB_BACKLIGHT_LEVELS - 1),
+};
+
+#ifdef CONFIG_PM
+void pmu_backlight_set_sleep(int sleep)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&pmu_backlight_lock, flags);
+	sleeping = sleep;
+	spin_unlock_irqrestore(&pmu_backlight_lock, flags);
+}
+#endif /* CONFIG_PM */
+
+void __init pmu_backlight_init()
+{
+	struct backlight_device *bd;
+	char name[10];
+	int level, autosave;
+
+	/* Special case for the old PowerBook since I can't test on it */
+	autosave =
+		machine_is_compatible("AAPL,3400/2400") ||
+		machine_is_compatible("AAPL,3500");
+
+	if (!autosave &&
+	    !pmac_has_backlight_type("pmu") &&
+	    !machine_is_compatible("AAPL,PowerBook1998") &&
+	    !machine_is_compatible("PowerBook1,1"))
+		return;
+
+	snprintf(name, sizeof(name), "pmubl");
+
+	bd = backlight_device_register(name, NULL, &pmu_backlight_data);
+	if (IS_ERR(bd)) {
+		printk("pmubl: Backlight registration failed\n");
+		goto error;
+	}
+	pmu_backlight_init_curve(0x7F, 0x46, 0x0E);
+
+	level = pmu_backlight_data.max_brightness;
+
+	if (autosave) {
+		/* read autosaved value if available */
+		struct adb_request req;
+		pmu_request(&req, NULL, 2, 0xd9, 0);
+		pmu_wait_complete(&req);
+
+		level = pmu_backlight_curve_lookup(
+				(req.reply[0] >> 4) *
+				pmu_backlight_data.max_brightness / 15);
+	}
+
+	down(&bd->sem);
+	bd->props->brightness = level;
+	bd->props->power = FB_BLANK_UNBLANK;
+	bd->props->update_status(bd);
+	up(&bd->sem);
+
+	mutex_lock(&pmac_backlight_mutex);
+	if (!pmac_backlight)
+		pmac_backlight = bd;
+	mutex_unlock(&pmac_backlight_mutex);
+
+	printk("pmubl: Backlight initialized (%s)\n", name);
+
+	return;
+
+error:
+	return;
+}
diff --git a/drivers/macintosh/via-pmu-event.c b/drivers/macintosh/via-pmu-event.c
new file mode 100644
index 000000000..25cd56542
--- /dev/null
+++ b/drivers/macintosh/via-pmu-event.c
@@ -0,0 +1,80 @@
+/*
+ * via-pmu event device for reporting some events that come through the PMU
+ *
+ * Copyright 2006 Johannes Berg <johannes@sipsolutions.net>
+ *
+ * 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, GOOD TITLE or
+ * NON INFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ *
+ */
+
+#include <linux/input.h>
+#include <linux/adb.h>
+#include <linux/pmu.h>
+#include "via-pmu-event.h"
+
+static struct input_dev *pmu_input_dev;
+
+static int __init via_pmu_event_init(void)
+{
+	int err;
+
+	/* do other models report button/lid status? */
+	if (pmu_get_model() != PMU_KEYLARGO_BASED)
+		return -ENODEV;
+
+	pmu_input_dev = input_allocate_device();
+	if (!pmu_input_dev)
+		return -ENOMEM;
+
+	pmu_input_dev->name = "PMU";
+	pmu_input_dev->id.bustype = BUS_HOST;
+	pmu_input_dev->id.vendor = 0x0001;
+	pmu_input_dev->id.product = 0x0001;
+	pmu_input_dev->id.version = 0x0100;
+
+	set_bit(EV_KEY, pmu_input_dev->evbit);
+	set_bit(EV_SW, pmu_input_dev->evbit);
+	set_bit(KEY_POWER, pmu_input_dev->keybit);
+	set_bit(SW_LID, pmu_input_dev->swbit);
+
+	err = input_register_device(pmu_input_dev);
+	if (err)
+		input_free_device(pmu_input_dev);
+	return err;
+}
+
+void via_pmu_event(int key, int down)
+{
+
+	if (unlikely(!pmu_input_dev))
+		return;
+
+	switch (key) {
+	case PMU_EVT_POWER:
+		input_report_key(pmu_input_dev, KEY_POWER, down);
+		break;
+	case PMU_EVT_LID:
+		input_report_switch(pmu_input_dev, SW_LID, down);
+		break;
+	default:
+		/* no such key handled */
+		return;
+	}
+
+	input_sync(pmu_input_dev);
+}
+
+late_initcall(via_pmu_event_init);
diff --git a/drivers/macintosh/via-pmu-event.h b/drivers/macintosh/via-pmu-event.h
new file mode 100644
index 000000000..72c54de40
--- /dev/null
+++ b/drivers/macintosh/via-pmu-event.h
@@ -0,0 +1,8 @@
+#ifndef __VIA_PMU_EVENT_H
+#define __VIA_PMU_EVENT_H
+
+#define PMU_EVT_POWER	0
+#define PMU_EVT_LID	1
+extern void via_pmu_event(int key, int down);
+
+#endif /* __VIA_PMU_EVENT_H */
diff --git a/drivers/macintosh/via-pmu-led.c b/drivers/macintosh/via-pmu-led.c
new file mode 100644
index 000000000..5189d5454
--- /dev/null
+++ b/drivers/macintosh/via-pmu-led.c
@@ -0,0 +1,144 @@
+/*
+ * via-pmu LED class device
+ *
+ * Copyright 2006 Johannes Berg <johannes@sipsolutions.net>
+ *
+ * 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, GOOD TITLE or
+ * NON INFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ *
+ */
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/device.h>
+#include <linux/leds.h>
+#include <linux/adb.h>
+#include <linux/pmu.h>
+#include <asm/prom.h>
+
+static spinlock_t pmu_blink_lock;
+static struct adb_request pmu_blink_req;
+/* -1: no change, 0: request off, 1: request on */
+static int requested_change;
+static int sleeping;
+
+static void pmu_req_done(struct adb_request * req)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&pmu_blink_lock, flags);
+	/* if someone requested a change in the meantime
+	 * (we only see the last one which is fine)
+	 * then apply it now */
+	if (requested_change != -1 && !sleeping)
+		pmu_request(&pmu_blink_req, NULL, 4, 0xee, 4, 0, requested_change);
+	/* reset requested change */
+	requested_change = -1;
+	spin_unlock_irqrestore(&pmu_blink_lock, flags);
+}
+
+static void pmu_led_set(struct led_classdev *led_cdev,
+			enum led_brightness brightness)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&pmu_blink_lock, flags);
+	switch (brightness) {
+	case LED_OFF:
+		requested_change = 0;
+		break;
+	case LED_FULL:
+		requested_change = 1;
+		break;
+	default:
+		goto out;
+		break;
+	}
+	/* if request isn't done, then don't do anything */
+	if (pmu_blink_req.complete && !sleeping)
+		pmu_request(&pmu_blink_req, NULL, 4, 0xee, 4, 0, requested_change);
+ out:
+ 	spin_unlock_irqrestore(&pmu_blink_lock, flags);
+}
+
+static struct led_classdev pmu_led = {
+	.name = "pmu-front-led",
+#ifdef CONFIG_ADB_PMU_LED_IDE
+	.default_trigger = "ide-disk",
+#endif
+	.brightness_set = pmu_led_set,
+};
+
+#ifdef CONFIG_PM
+static int pmu_led_sleep_call(struct pmu_sleep_notifier *self, int when)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&pmu_blink_lock, flags);
+
+	switch (when) {
+	case PBOOK_SLEEP_REQUEST:
+		sleeping = 1;
+		break;
+	case PBOOK_WAKE:
+		sleeping = 0;
+		break;
+	default:
+		/* do nothing */
+		break;
+	}
+	spin_unlock_irqrestore(&pmu_blink_lock, flags);
+
+	return PBOOK_SLEEP_OK;
+}
+
+static struct pmu_sleep_notifier via_pmu_led_sleep_notif = {
+	.notifier_call = pmu_led_sleep_call,
+};
+#endif
+
+static int __init via_pmu_led_init(void)
+{
+	struct device_node *dt;
+	const char *model;
+
+	/* only do this on keylargo based models */
+	if (pmu_get_model() != PMU_KEYLARGO_BASED)
+		return -ENODEV;
+
+	dt = of_find_node_by_path("/");
+	if (dt == NULL)
+		return -ENODEV;
+	model = (const char *)get_property(dt, "model", NULL);
+	if (model == NULL)
+		return -ENODEV;
+	if (strncmp(model, "PowerBook", strlen("PowerBook")) != 0 &&
+	    strncmp(model, "iBook", strlen("iBook")) != 0) {
+		of_node_put(dt);
+		/* ignore */
+		return -ENODEV;
+	}
+	of_node_put(dt);
+
+	spin_lock_init(&pmu_blink_lock);
+	/* no outstanding req */
+	pmu_blink_req.complete = 1;
+	pmu_blink_req.done = pmu_req_done;
+#ifdef CONFIG_PM
+	pmu_register_sleep_notifier(&via_pmu_led_sleep_notif);
+#endif
+	return led_classdev_register(NULL, &pmu_led);
+}
+
+late_initcall(via_pmu_led_init);
diff --git a/drivers/media/dvb/dvb-core/dvb_math.c b/drivers/media/dvb/dvb-core/dvb_math.c
new file mode 100644
index 000000000..beb7c93aa
--- /dev/null
+++ b/drivers/media/dvb/dvb-core/dvb_math.c
@@ -0,0 +1,145 @@
+/*
+ * dvb-math provides some complex fixed-point math
+ * operations shared between the dvb related stuff
+ *
+ * Copyright (C) 2006 Christoph Pfister (christophpfister@gmail.com)
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/bitops.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <asm/bug.h>
+#include "dvb_math.h"
+
+static const unsigned short logtable[256] = {
+	0x0000, 0x0171, 0x02e0, 0x044e, 0x05ba, 0x0725, 0x088e, 0x09f7,
+	0x0b5d, 0x0cc3, 0x0e27, 0x0f8a, 0x10eb, 0x124b, 0x13aa, 0x1508,
+	0x1664, 0x17bf, 0x1919, 0x1a71, 0x1bc8, 0x1d1e, 0x1e73, 0x1fc6,
+	0x2119, 0x226a, 0x23ba, 0x2508, 0x2656, 0x27a2, 0x28ed, 0x2a37,
+	0x2b80, 0x2cc8, 0x2e0f, 0x2f54, 0x3098, 0x31dc, 0x331e, 0x345f,
+	0x359f, 0x36de, 0x381b, 0x3958, 0x3a94, 0x3bce, 0x3d08, 0x3e41,
+	0x3f78, 0x40af, 0x41e4, 0x4319, 0x444c, 0x457f, 0x46b0, 0x47e1,
+	0x4910, 0x4a3f, 0x4b6c, 0x4c99, 0x4dc5, 0x4eef, 0x5019, 0x5142,
+	0x526a, 0x5391, 0x54b7, 0x55dc, 0x5700, 0x5824, 0x5946, 0x5a68,
+	0x5b89, 0x5ca8, 0x5dc7, 0x5ee5, 0x6003, 0x611f, 0x623a, 0x6355,
+	0x646f, 0x6588, 0x66a0, 0x67b7, 0x68ce, 0x69e4, 0x6af8, 0x6c0c,
+	0x6d20, 0x6e32, 0x6f44, 0x7055, 0x7165, 0x7274, 0x7383, 0x7490,
+	0x759d, 0x76aa, 0x77b5, 0x78c0, 0x79ca, 0x7ad3, 0x7bdb, 0x7ce3,
+	0x7dea, 0x7ef0, 0x7ff6, 0x80fb, 0x81ff, 0x8302, 0x8405, 0x8507,
+	0x8608, 0x8709, 0x8809, 0x8908, 0x8a06, 0x8b04, 0x8c01, 0x8cfe,
+	0x8dfa, 0x8ef5, 0x8fef, 0x90e9, 0x91e2, 0x92db, 0x93d2, 0x94ca,
+	0x95c0, 0x96b6, 0x97ab, 0x98a0, 0x9994, 0x9a87, 0x9b7a, 0x9c6c,
+	0x9d5e, 0x9e4f, 0x9f3f, 0xa02e, 0xa11e, 0xa20c, 0xa2fa, 0xa3e7,
+	0xa4d4, 0xa5c0, 0xa6ab, 0xa796, 0xa881, 0xa96a, 0xaa53, 0xab3c,
+	0xac24, 0xad0c, 0xadf2, 0xaed9, 0xafbe, 0xb0a4, 0xb188, 0xb26c,
+	0xb350, 0xb433, 0xb515, 0xb5f7, 0xb6d9, 0xb7ba, 0xb89a, 0xb97a,
+	0xba59, 0xbb38, 0xbc16, 0xbcf4, 0xbdd1, 0xbead, 0xbf8a, 0xc065,
+	0xc140, 0xc21b, 0xc2f5, 0xc3cf, 0xc4a8, 0xc580, 0xc658, 0xc730,
+	0xc807, 0xc8de, 0xc9b4, 0xca8a, 0xcb5f, 0xcc34, 0xcd08, 0xcddc,
+	0xceaf, 0xcf82, 0xd054, 0xd126, 0xd1f7, 0xd2c8, 0xd399, 0xd469,
+	0xd538, 0xd607, 0xd6d6, 0xd7a4, 0xd872, 0xd93f, 0xda0c, 0xdad9,
+	0xdba5, 0xdc70, 0xdd3b, 0xde06, 0xded0, 0xdf9a, 0xe063, 0xe12c,
+	0xe1f5, 0xe2bd, 0xe385, 0xe44c, 0xe513, 0xe5d9, 0xe69f, 0xe765,
+	0xe82a, 0xe8ef, 0xe9b3, 0xea77, 0xeb3b, 0xebfe, 0xecc1, 0xed83,
+	0xee45, 0xef06, 0xefc8, 0xf088, 0xf149, 0xf209, 0xf2c8, 0xf387,
+	0xf446, 0xf505, 0xf5c3, 0xf680, 0xf73e, 0xf7fb, 0xf8b7, 0xf973,
+	0xfa2f, 0xfaea, 0xfba5, 0xfc60, 0xfd1a, 0xfdd4, 0xfe8e, 0xff47
+};
+
+unsigned int intlog2(u32 value)
+{
+	/**
+	 *	returns: log2(value) * 2^24
+	 *	wrong result if value = 0 (log2(0) is undefined)
+	 */
+	unsigned int msb;
+	unsigned int logentry;
+	unsigned int significand;
+	unsigned int interpolation;
+
+	if (unlikely(value == 0)) {
+		WARN_ON(1);
+		return 0;
+	}
+
+	/* first detect the msb (count begins at 0) */
+	msb = fls(value) - 1;
+
+	/**
+	 *	now we use a logtable after the following method:
+	 *
+	 *	log2(2^x * y) * 2^24 = x * 2^24 + log2(y) * 2^24
+	 *	where x = msb and therefore 1 <= y < 2
+	 *	first y is determined by shifting the value left
+	 *	so that msb is bit 31
+	 *		0x00231f56 -> 0x8C7D5800
+	 *	the result is y * 2^31 -> "significand"
+	 *	then the highest 9 bits are used for a table lookup
+	 *	the highest bit is discarded because it's always set
+	 *	the highest nine bits in our example are 100011000
+	 *	so we would use the entry 0x18
+	 */
+	significand = value << (31 - msb);
+	logentry = (significand >> 23) & 0xff;
+
+	/**
+	 *	last step we do is interpolation because of the
+	 *	limitations of the log table the error is that part of
+	 *	the significand which isn't used for lookup then we
+	 *	compute the ratio between the error and the next table entry
+	 *	and interpolate it between the log table entry used and the
+	 *	next one the biggest error possible is 0x7fffff
+	 *	(in our example it's 0x7D5800)
+	 *	needed value for next table entry is 0x800000
+	 *	so the interpolation is
+	 *	(error / 0x800000) * (logtable_next - logtable_current)
+	 *	in the implementation the division is moved to the end for
+	 *	better accuracy there is also an overflow correction if
+	 *	logtable_next is 256
+	 */
+	interpolation = ((significand & 0x7fffff) *
+			((logtable[(logentry + 1) & 0xff] -
+			  logtable[logentry]) & 0xffff)) >> 15;
+
+	/* now we return the result */
+	return ((msb << 24) + (logtable[logentry] << 8) + interpolation);
+}
+EXPORT_SYMBOL(intlog2);
+
+unsigned int intlog10(u32 value)
+{
+	/**
+	 *	returns: log10(value) * 2^24
+	 *	wrong result if value = 0 (log10(0) is undefined)
+	 */
+	u64 log;
+
+	if (unlikely(value == 0)) {
+		WARN_ON(1);
+		return 0;
+	}
+
+	log = intlog2(value);
+
+	/**
+	 *	we use the following method:
+	 *	log10(x) = log2(x) * log10(2)
+	 */
+
+	return (log * 646456993) >> 31;
+}
+EXPORT_SYMBOL(intlog10);
diff --git a/drivers/media/dvb/dvb-core/dvb_math.h b/drivers/media/dvb/dvb-core/dvb_math.h
new file mode 100644
index 000000000..aecc867e9
--- /dev/null
+++ b/drivers/media/dvb/dvb-core/dvb_math.h
@@ -0,0 +1,58 @@
+/*
+ * dvb-math provides some complex fixed-point math
+ * operations shared between the dvb related stuff
+ *
+ * Copyright (C) 2006 Christoph Pfister (christophpfister@gmail.com)
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef __DVB_MATH_H
+#define __DVB_MATH_H
+
+#include <linux/types.h>
+
+/**
+ * computes log2 of a value; the result is shifted left by 24 bits
+ *
+ * to use rational values you can use the following method:
+ *   intlog2(value) = intlog2(value * 2^x) - x * 2^24
+ *
+ * example: intlog2(8) will give 3 << 24 = 3 * 2^24
+ * example: intlog2(9) will give 3 << 24 + ... = 3.16... * 2^24
+ * example: intlog2(1.5) = intlog2(3) - 2^24 = 0.584... * 2^24
+ *
+ * @param value The value (must be != 0)
+ * @return log2(value) * 2^24
+ */
+extern unsigned int intlog2(u32 value);
+
+/**
+ * computes log10 of a value; the result is shifted left by 24 bits
+ *
+ * to use rational values you can use the following method:
+ *   intlog10(value) = intlog10(value * 10^x) - x * 2^24
+ *
+ * example: intlog10(1000) will give 3 << 24 = 3 * 2^24
+ *   due to the implementation intlog10(1000) might be not exactly 3 * 2^24
+ *
+ * look at intlog2 for similar examples
+ *
+ * @param value The value (must be != 0)
+ * @return log10(value) * 2^24
+ */
+extern unsigned int intlog10(u32 value);
+
+#endif
diff --git a/drivers/media/dvb/dvb-usb/gp8psk-fe.c b/drivers/media/dvb/dvb-usb/gp8psk-fe.c
new file mode 100644
index 000000000..6ccbdc9cd
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/gp8psk-fe.c
@@ -0,0 +1,272 @@
+/* DVB USB compliant Linux driver for the
+ *  - GENPIX 8pks/qpsk USB2.0 DVB-S module
+ *
+ * Copyright (C) 2006 Alan Nisota (alannisota@gmail.com)
+ *
+ * Thanks to GENPIX for the sample code used to implement this module.
+ *
+ * This module is based off the vp7045 and vp702x modules
+ *
+ *	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.
+ *
+ * see Documentation/dvb/README.dvb-usb for more information
+ */
+#include "gp8psk.h"
+
+struct gp8psk_fe_state {
+	struct dvb_frontend fe;
+
+	struct dvb_usb_device *d;
+
+	u16 snr;
+
+	unsigned long next_snr_check;
+};
+
+static int gp8psk_fe_read_status(struct dvb_frontend* fe, fe_status_t *status)
+{
+	struct gp8psk_fe_state *st = fe->demodulator_priv;
+	u8 lock;
+
+	if (gp8psk_usb_in_op(st->d, GET_SIGNAL_LOCK, 0, 0, &lock,1))
+		return -EINVAL;
+
+	if (lock)
+		*status = FE_HAS_LOCK | FE_HAS_SYNC | FE_HAS_VITERBI | FE_HAS_SIGNAL | FE_HAS_CARRIER;
+	else
+		*status = 0;
+
+	return 0;
+}
+
+/* not supported by this Frontend */
+static int gp8psk_fe_read_ber(struct dvb_frontend* fe, u32 *ber)
+{
+	(void) fe;
+	*ber = 0;
+	return 0;
+}
+
+/* not supported by this Frontend */
+static int gp8psk_fe_read_unc_blocks(struct dvb_frontend* fe, u32 *unc)
+{
+	(void) fe;
+	*unc = 0;
+	return 0;
+}
+
+static int gp8psk_fe_read_snr(struct dvb_frontend* fe, u16 *snr)
+{
+	struct gp8psk_fe_state *st = fe->demodulator_priv;
+	u8 buf[2];
+
+	if (time_after(jiffies,st->next_snr_check)) {
+		gp8psk_usb_in_op(st->d,GET_SIGNAL_STRENGTH,0,0,buf,2);
+		*snr = (int)(buf[1]) << 8 | buf[0];
+		/* snr is reported in dBu*256 */
+		/* snr / 38.4 ~= 100% strength */
+		/* snr * 17 returns 100% strength as 65535 */
+		if (*snr <= 3855)
+			*snr = (*snr<<4) + *snr; // snr * 17
+		else
+			*snr = 65535;
+		st->next_snr_check = jiffies + (10*HZ)/1000;
+	} else {
+		*snr = st->snr;
+	}
+	return 0;
+}
+
+static int gp8psk_fe_read_signal_strength(struct dvb_frontend* fe, u16 *strength)
+{
+	return gp8psk_fe_read_snr(fe, strength);
+}
+
+static int gp8psk_fe_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings *tune)
+{
+	tune->min_delay_ms = 800;
+	return 0;
+}
+
+static int gp8psk_fe_set_frontend(struct dvb_frontend* fe,
+				  struct dvb_frontend_parameters *fep)
+{
+	struct gp8psk_fe_state *state = fe->demodulator_priv;
+	u8 cmd[10];
+	u32 freq = fep->frequency * 1000;
+
+	cmd[4] = freq         & 0xff;
+	cmd[5] = (freq >> 8)  & 0xff;
+	cmd[6] = (freq >> 16) & 0xff;
+	cmd[7] = (freq >> 24) & 0xff;
+
+	switch(fe->ops.info.type) {
+	case FE_QPSK:
+		cmd[0] =  fep->u.qpsk.symbol_rate        & 0xff;
+		cmd[1] = (fep->u.qpsk.symbol_rate >>  8) & 0xff;
+		cmd[2] = (fep->u.qpsk.symbol_rate >> 16) & 0xff;
+		cmd[3] = (fep->u.qpsk.symbol_rate >> 24) & 0xff;
+		cmd[8] = ADV_MOD_DVB_QPSK;
+		cmd[9] = 0x03; /*ADV_MOD_FEC_XXX*/
+		break;
+	default:
+		// other modes are unsuported right now
+		cmd[0] = 0;
+		cmd[1] = 0;
+		cmd[2] = 0;
+		cmd[3] = 0;
+		cmd[8] = 0;
+		cmd[9] = 0;
+		break;
+	}
+
+	gp8psk_usb_out_op(state->d,TUNE_8PSK,0,0,cmd,10);
+
+	state->next_snr_check = jiffies;
+
+	return 0;
+}
+
+static int gp8psk_fe_get_frontend(struct dvb_frontend* fe,
+				  struct dvb_frontend_parameters *fep)
+{
+	return 0;
+}
+
+
+static int gp8psk_fe_send_diseqc_msg (struct dvb_frontend* fe,
+				    struct dvb_diseqc_master_cmd *m)
+{
+	struct gp8psk_fe_state *st = fe->demodulator_priv;
+
+	deb_fe("%s\n",__FUNCTION__);
+
+	if (gp8psk_usb_out_op(st->d,SEND_DISEQC_COMMAND, m->msg[0], 0,
+			m->msg, m->msg_len)) {
+		return -EINVAL;
+	}
+	return 0;
+}
+
+static int gp8psk_fe_send_diseqc_burst (struct dvb_frontend* fe,
+				    fe_sec_mini_cmd_t burst)
+{
+	struct gp8psk_fe_state *st = fe->demodulator_priv;
+	u8 cmd;
+
+	deb_fe("%s\n",__FUNCTION__);
+
+	/* These commands are certainly wrong */
+	cmd = (burst == SEC_MINI_A) ? 0x00 : 0x01;
+
+	if (gp8psk_usb_out_op(st->d,SEND_DISEQC_COMMAND, cmd, 0,
+			&cmd, 0)) {
+		return -EINVAL;
+	}
+	return 0;
+}
+
+static int gp8psk_fe_set_tone (struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
+{
+	struct gp8psk_fe_state* state = fe->demodulator_priv;
+
+	if (gp8psk_usb_out_op(state->d,SET_22KHZ_TONE,
+		 (tone == SEC_TONE_ON), 0, NULL, 0)) {
+		return -EINVAL;
+	}
+	return 0;
+}
+
+static int gp8psk_fe_set_voltage (struct dvb_frontend* fe, fe_sec_voltage_t voltage)
+{
+	struct gp8psk_fe_state* state = fe->demodulator_priv;
+
+	if (gp8psk_usb_out_op(state->d,SET_LNB_VOLTAGE,
+			 voltage == SEC_VOLTAGE_18, 0, NULL, 0)) {
+		return -EINVAL;
+	}
+	return 0;
+}
+
+static int gp8psk_fe_send_legacy_dish_cmd (struct dvb_frontend* fe, unsigned long sw_cmd)
+{
+	struct gp8psk_fe_state* state = fe->demodulator_priv;
+	u8 cmd = sw_cmd & 0x7f;
+
+	if (gp8psk_usb_out_op(state->d,SET_DN_SWITCH, cmd, 0,
+			NULL, 0)) {
+		return -EINVAL;
+	}
+	if (gp8psk_usb_out_op(state->d,SET_LNB_VOLTAGE, !!(sw_cmd & 0x80),
+			0, NULL, 0)) {
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static void gp8psk_fe_release(struct dvb_frontend* fe)
+{
+	struct gp8psk_fe_state *state = fe->demodulator_priv;
+	kfree(state);
+}
+
+static struct dvb_frontend_ops gp8psk_fe_ops;
+
+struct dvb_frontend * gp8psk_fe_attach(struct dvb_usb_device *d)
+{
+	struct gp8psk_fe_state *s = kzalloc(sizeof(struct gp8psk_fe_state), GFP_KERNEL);
+	if (s == NULL)
+		goto error;
+
+	s->d = d;
+	memcpy(&s->fe.ops, &gp8psk_fe_ops, sizeof(struct dvb_frontend_ops));
+	s->fe.demodulator_priv = s;
+
+	goto success;
+error:
+	return NULL;
+success:
+	return &s->fe;
+}
+
+
+static struct dvb_frontend_ops gp8psk_fe_ops = {
+	.info = {
+		.name			= "Genpix 8psk-USB DVB-S",
+		.type			= FE_QPSK,
+		.frequency_min		= 950000,
+		.frequency_max		= 2150000,
+		.frequency_stepsize	= 100,
+		.symbol_rate_min        = 1000000,
+		.symbol_rate_max        = 45000000,
+		.symbol_rate_tolerance  = 500,  /* ppm */
+		.caps = FE_CAN_INVERSION_AUTO |
+				FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
+				FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
+				FE_CAN_QPSK
+	},
+
+	.release = gp8psk_fe_release,
+
+	.init = NULL,
+	.sleep = NULL,
+
+	.set_frontend = gp8psk_fe_set_frontend,
+	.get_frontend = gp8psk_fe_get_frontend,
+	.get_tune_settings = gp8psk_fe_get_tune_settings,
+
+	.read_status = gp8psk_fe_read_status,
+	.read_ber = gp8psk_fe_read_ber,
+	.read_signal_strength = gp8psk_fe_read_signal_strength,
+	.read_snr = gp8psk_fe_read_snr,
+	.read_ucblocks = gp8psk_fe_read_unc_blocks,
+
+	.diseqc_send_master_cmd = gp8psk_fe_send_diseqc_msg,
+	.diseqc_send_burst = gp8psk_fe_send_diseqc_burst,
+	.set_tone = gp8psk_fe_set_tone,
+	.set_voltage = gp8psk_fe_set_voltage,
+	.dishnetwork_send_legacy_command = gp8psk_fe_send_legacy_dish_cmd,
+};
diff --git a/drivers/media/dvb/dvb-usb/gp8psk.c b/drivers/media/dvb/dvb-usb/gp8psk.c
new file mode 100644
index 000000000..9a98f3fda
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/gp8psk.c
@@ -0,0 +1,256 @@
+/* DVB USB compliant Linux driver for the
+ *  - GENPIX 8pks/qpsk USB2.0 DVB-S module
+ *
+ * Copyright (C) 2006 Alan Nisota (alannisota@gmail.com)
+ *
+ * Thanks to GENPIX for the sample code used to implement this module.
+ *
+ * This module is based off the vp7045 and vp702x modules
+ *
+ *	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.
+ *
+ * see Documentation/dvb/README.dvb-usb for more information
+ */
+#include "gp8psk.h"
+
+/* debug */
+static char bcm4500_firmware[] = "dvb-usb-gp8psk-02.fw";
+int dvb_usb_gp8psk_debug;
+module_param_named(debug,dvb_usb_gp8psk_debug, int, 0644);
+MODULE_PARM_DESC(debug, "set debugging level (1=info,xfer=2,rc=4 (or-able))." DVB_USB_DEBUG_STATUS);
+
+int gp8psk_usb_in_op(struct dvb_usb_device *d, u8 req, u16 value, u16 index, u8 *b, int blen)
+{
+	int ret = 0,try = 0;
+
+	if ((ret = mutex_lock_interruptible(&d->usb_mutex)))
+		return ret;
+
+	while (ret >= 0 && ret != blen && try < 3) {
+		ret = usb_control_msg(d->udev,
+			usb_rcvctrlpipe(d->udev,0),
+			req,
+			USB_TYPE_VENDOR | USB_DIR_IN,
+			value,index,b,blen,
+			2000);
+		deb_info("reading number %d (ret: %d)\n",try,ret);
+		try++;
+	}
+
+	if (ret < 0 || ret != blen) {
+		warn("usb in operation failed.");
+		ret = -EIO;
+	} else
+		ret = 0;
+
+	deb_xfer("in: req. %x, val: %x, ind: %x, buffer: ",req,value,index);
+	debug_dump(b,blen,deb_xfer);
+
+	mutex_unlock(&d->usb_mutex);
+
+	return ret;
+}
+
+int gp8psk_usb_out_op(struct dvb_usb_device *d, u8 req, u16 value,
+			     u16 index, u8 *b, int blen)
+{
+	int ret;
+
+	deb_xfer("out: req. %x, val: %x, ind: %x, buffer: ",req,value,index);
+	debug_dump(b,blen,deb_xfer);
+
+	if ((ret = mutex_lock_interruptible(&d->usb_mutex)))
+		return ret;
+
+	if (usb_control_msg(d->udev,
+			usb_sndctrlpipe(d->udev,0),
+			req,
+			USB_TYPE_VENDOR | USB_DIR_OUT,
+			value,index,b,blen,
+			2000) != blen) {
+		warn("usb out operation failed.");
+		ret = -EIO;
+	} else
+		ret = 0;
+	mutex_unlock(&d->usb_mutex);
+
+	return ret;
+}
+
+static int gp8psk_load_bcm4500fw(struct dvb_usb_device *d)
+{
+	int ret;
+	const struct firmware *fw = NULL;
+	u8 *ptr, *buf;
+	if ((ret = request_firmware(&fw, bcm4500_firmware,
+					&d->udev->dev)) != 0) {
+		err("did not find the bcm4500 firmware file. (%s) "
+			"Please see linux/Documentation/dvb/ for more details on firmware-problems. (%d)",
+			bcm4500_firmware,ret);
+		return ret;
+	}
+
+	ret = -EINVAL;
+
+	if (gp8psk_usb_out_op(d, LOAD_BCM4500,1,0,NULL, 0))
+		goto out_rel_fw;
+
+	info("downloaidng bcm4500 firmware from file '%s'",bcm4500_firmware);
+
+	ptr = fw->data;
+	buf = kmalloc(512, GFP_KERNEL | GFP_DMA);
+
+	while (ptr[0] != 0xff) {
+		u16 buflen = ptr[0] + 4;
+		if (ptr + buflen >= fw->data + fw->size) {
+			err("failed to load bcm4500 firmware.");
+			goto out_free;
+		}
+		memcpy(buf, ptr, buflen);
+		if (dvb_usb_generic_write(d, buf, buflen)) {
+			err("failed to load bcm4500 firmware.");
+			goto out_free;
+		}
+		ptr += buflen;
+	}
+
+	ret = 0;
+
+out_free:
+	kfree(buf);
+out_rel_fw:
+	release_firmware(fw);
+
+	return ret;
+}
+
+static int gp8psk_power_ctrl(struct dvb_usb_device *d, int onoff)
+{
+	u8 status, buf;
+	if (onoff) {
+		gp8psk_usb_in_op(d, GET_8PSK_CONFIG,0,0,&status,1);
+		if (! (status & 0x01))  /* started */
+			if (gp8psk_usb_in_op(d, BOOT_8PSK, 1, 0, &buf, 1))
+				return -EINVAL;
+
+		if (! (status & 0x02)) /* BCM4500 firmware loaded */
+			if(gp8psk_load_bcm4500fw(d))
+				return EINVAL;
+
+		if (! (status & 0x04)) /* LNB Power */
+			if (gp8psk_usb_in_op(d, START_INTERSIL, 1, 0,
+					&buf, 1))
+				return EINVAL;
+
+		/* Set DVB mode */
+		if(gp8psk_usb_out_op(d, SET_DVB_MODE, 1, 0, NULL, 0))
+			return -EINVAL;
+		gp8psk_usb_in_op(d, GET_8PSK_CONFIG,0,0,&status,1);
+	} else {
+		/* Turn off LNB power */
+		if (gp8psk_usb_in_op(d, START_INTERSIL, 0, 0, &buf, 1))
+			return EINVAL;
+		/* Turn off 8psk power */
+		if (gp8psk_usb_in_op(d, BOOT_8PSK, 0, 0, &buf, 1))
+			return -EINVAL;
+
+	}
+	return 0;
+}
+
+
+static int gp8psk_streaming_ctrl(struct dvb_usb_device *d, int onoff)
+{
+	return gp8psk_usb_out_op(d, ARM_TRANSFER, onoff, 0 , NULL, 0);
+}
+
+static int gp8psk_frontend_attach(struct dvb_usb_device *d)
+{
+	d->fe = gp8psk_fe_attach(d);
+
+	return 0;
+}
+
+static struct dvb_usb_properties gp8psk_properties;
+
+static int gp8psk_usb_probe(struct usb_interface *intf,
+		const struct usb_device_id *id)
+{
+	return dvb_usb_device_init(intf,&gp8psk_properties,THIS_MODULE,NULL);
+}
+
+static struct usb_device_id gp8psk_usb_table [] = {
+	    { USB_DEVICE(USB_VID_GENPIX, USB_PID_GENPIX_8PSK_COLD) },
+	    { USB_DEVICE(USB_VID_GENPIX, USB_PID_GENPIX_8PSK_WARM) },
+	    { 0 },
+};
+MODULE_DEVICE_TABLE(usb, gp8psk_usb_table);
+
+static struct dvb_usb_properties gp8psk_properties = {
+	.caps = 0,
+
+	.usb_ctrl = CYPRESS_FX2,
+	.firmware = "dvb-usb-gp8psk-01.fw",
+
+	.streaming_ctrl   = gp8psk_streaming_ctrl,
+	.power_ctrl       = gp8psk_power_ctrl,
+	.frontend_attach  = gp8psk_frontend_attach,
+
+	.generic_bulk_ctrl_endpoint = 0x01,
+	/* parameter for the MPEG2-data transfer */
+	.urb = {
+		.type = DVB_USB_BULK,
+		.count = 7,
+		.endpoint = 0x82,
+		.u = {
+			.bulk = {
+				.buffersize = 8192,
+			}
+		}
+	},
+
+	.num_device_descs = 1,
+	.devices = {
+		{ .name = "Genpix 8PSK-USB DVB-S USB2.0 receiver",
+		  .cold_ids = { &gp8psk_usb_table[0], NULL },
+		  .warm_ids = { &gp8psk_usb_table[1], NULL },
+		},
+		{ 0 },
+	}
+};
+
+/* usb specific object needed to register this driver with the usb subsystem */
+static struct usb_driver gp8psk_usb_driver = {
+	.name		= "dvb_usb_gp8psk",
+	.probe		= gp8psk_usb_probe,
+	.disconnect = dvb_usb_device_exit,
+	.id_table	= gp8psk_usb_table,
+};
+
+/* module stuff */
+static int __init gp8psk_usb_module_init(void)
+{
+	int result;
+	if ((result = usb_register(&gp8psk_usb_driver))) {
+		err("usb_register failed. (%d)",result);
+		return result;
+	}
+
+	return 0;
+}
+
+static void __exit gp8psk_usb_module_exit(void)
+{
+	/* deregister this driver from the USB subsystem */
+	usb_deregister(&gp8psk_usb_driver);
+}
+
+module_init(gp8psk_usb_module_init);
+module_exit(gp8psk_usb_module_exit);
+
+MODULE_AUTHOR("Alan Nisota <alannisota@gamil.com>");
+MODULE_DESCRIPTION("Driver for Genpix 8psk-USB DVB-S USB2.0");
+MODULE_VERSION("1.0");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb/gp8psk.h b/drivers/media/dvb/dvb-usb/gp8psk.h
new file mode 100644
index 000000000..3eba70610
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/gp8psk.h
@@ -0,0 +1,79 @@
+/* DVB USB compliant Linux driver for the
+ *  - GENPIX 8pks/qpsk USB2.0 DVB-S module
+ *
+ * Copyright (C) 2006 Alan Nisota (alannisota@gmail.com)
+ *
+ * Thanks to GENPIX for the sample code used to implement this module.
+ *
+ * This module is based off the vp7045 and vp702x modules
+ *
+ *	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.
+ *
+ * see Documentation/dvb/README.dvb-usb for more information
+ */
+#ifndef _DVB_USB_GP8PSK_H_
+#define _DVB_USB_GP8PSK_H_
+
+#define DVB_USB_LOG_PREFIX "gp8psk"
+#include "dvb-usb.h"
+
+extern int dvb_usb_gp8psk_debug;
+#define deb_info(args...) dprintk(dvb_usb_gp8psk_debug,0x01,args)
+#define deb_xfer(args...) dprintk(dvb_usb_gp8psk_debug,0x02,args)
+#define deb_rc(args...)   dprintk(dvb_usb_gp8psk_debug,0x04,args)
+#define deb_fe(args...)   dprintk(dvb_usb_gp8psk_debug,0x08,args)
+/* gp8psk commands */
+
+/* Twinhan Vendor requests */
+#define TH_COMMAND_IN                     0xC0
+#define TH_COMMAND_OUT                    0xC1
+
+/* command bytes */
+#define GET_8PSK_CONFIG                 0x80
+#define SET_8PSK_CONFIG                 0x81
+#define ARM_TRANSFER                    0x85
+#define TUNE_8PSK                       0x86
+#define GET_SIGNAL_STRENGTH             0x87
+#define LOAD_BCM4500                    0x88
+#define BOOT_8PSK                       0x89
+#define START_INTERSIL                  0x8A
+#define SET_LNB_VOLTAGE                 0x8B
+#define SET_22KHZ_TONE                  0x8C
+#define SEND_DISEQC_COMMAND             0x8D
+#define SET_DVB_MODE                    0x8E
+#define SET_DN_SWITCH                   0x8F
+#define GET_SIGNAL_LOCK                 0x90
+
+/* Satellite modulation modes */
+#define ADV_MOD_DVB_QPSK 0     /* DVB-S QPSK */
+#define ADV_MOD_TURBO_QPSK 1   /* Turbo QPSK */
+#define ADV_MOD_TURBO_8PSK 2   /* Turbo 8PSK (also used for Trellis 8PSK) */
+#define ADV_MOD_TURBO_16QAM 3  /* Turbo 16QAM (also used for Trellis 8PSK) */
+
+#define ADV_MOD_DCII_C_QPSK 4  /* Digicipher II Combo */
+#define ADV_MOD_DCII_I_QPSK 5  /* Digicipher II I-stream */
+#define ADV_MOD_DCII_Q_QPSK 6  /* Digicipher II Q-stream */
+#define ADV_MOD_DCII_C_OQPSK 7 /* Digicipher II offset QPSK */
+#define ADV_MOD_DSS_QPSK 8     /* DSS (DIRECTV) QPSK */
+#define ADV_MOD_DVB_BPSK 9     /* DVB-S BPSK */
+
+#define GET_USB_SPEED                     0x07
+ #define USB_SPEED_LOW                    0
+ #define USB_SPEED_FULL                   1
+ #define USB_SPEED_HIGH                   2
+
+#define RESET_FX2                         0x13
+
+#define FW_VERSION_READ                   0x0B
+#define VENDOR_STRING_READ                0x0C
+#define PRODUCT_STRING_READ               0x0D
+#define FW_BCD_VERSION_READ               0x14
+
+extern struct dvb_frontend * gp8psk_fe_attach(struct dvb_usb_device *d);
+extern int gp8psk_usb_in_op(struct dvb_usb_device *d, u8 req, u16 value, u16 index, u8 *b, int blen);
+extern int gp8psk_usb_out_op(struct dvb_usb_device *d, u8 req, u16 value,
+			     u16 index, u8 *b, int blen);
+
+#endif
diff --git a/drivers/media/dvb/frontends/isl6421.c b/drivers/media/dvb/frontends/isl6421.c
new file mode 100644
index 000000000..58c34db31
--- /dev/null
+++ b/drivers/media/dvb/frontends/isl6421.c
@@ -0,0 +1,149 @@
+/*
+ * isl6421.h - driver for lnb supply and control ic ISL6421
+ *
+ * Copyright (C) 2006 Andrew de Quincey
+ * Copyright (C) 2006 Oliver Endriss
+ *
+ * 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.
+ * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
+ *
+ *
+ * the project's page is at http://www.linuxtv.org
+ */
+#include <linux/delay.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+
+#include "dvb_frontend.h"
+#include "isl6421.h"
+
+struct isl6421 {
+	u8			config;
+	u8			override_or;
+	u8			override_and;
+	struct i2c_adapter	*i2c;
+	u8			i2c_addr;
+	void			(*release_chain)(struct dvb_frontend* fe);
+};
+
+static int isl6421_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
+{
+	struct isl6421 *isl6421 = (struct isl6421 *) fe->misc_priv;
+	struct i2c_msg msg = {	.addr = isl6421->i2c_addr, .flags = 0,
+				.buf = &isl6421->config,
+				.len = sizeof(isl6421->config) };
+
+	isl6421->config &= ~(ISL6421_VSEL1 | ISL6421_EN1);
+
+	switch(voltage) {
+	case SEC_VOLTAGE_OFF:
+		break;
+	case SEC_VOLTAGE_13:
+		isl6421->config |= ISL6421_EN1;
+		break;
+	case SEC_VOLTAGE_18:
+		isl6421->config |= (ISL6421_EN1 | ISL6421_VSEL1);
+		break;
+	default:
+		return -EINVAL;
+	};
+
+	isl6421->config |= isl6421->override_or;
+	isl6421->config &= isl6421->override_and;
+
+	return (i2c_transfer(isl6421->i2c, &msg, 1) == 1) ? 0 : -EIO;
+}
+
+static int isl6421_enable_high_lnb_voltage(struct dvb_frontend *fe, long arg)
+{
+	struct isl6421 *isl6421 = (struct isl6421 *) fe->misc_priv;
+	struct i2c_msg msg = {	.addr = isl6421->i2c_addr, .flags = 0,
+				.buf = &isl6421->config,
+				.len = sizeof(isl6421->config) };
+
+	if (arg)
+		isl6421->config |= ISL6421_LLC1;
+	else
+		isl6421->config &= ~ISL6421_LLC1;
+
+	isl6421->config |= isl6421->override_or;
+	isl6421->config &= isl6421->override_and;
+
+	return (i2c_transfer(isl6421->i2c, &msg, 1) == 1) ? 0 : -EIO;
+}
+
+static void isl6421_release(struct dvb_frontend *fe)
+{
+	struct isl6421 *isl6421 = (struct isl6421 *) fe->misc_priv;
+
+	/* power off */
+	isl6421_set_voltage(fe, SEC_VOLTAGE_OFF);
+
+	/* free data & call next release routine */
+	fe->ops.release = isl6421->release_chain;
+	kfree(fe->misc_priv);
+	fe->misc_priv = NULL;
+	if (fe->ops.release)
+		fe->ops.release(fe);
+}
+
+int isl6421_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, u8 i2c_addr,
+		   u8 override_set, u8 override_clear)
+{
+	struct isl6421 *isl6421 = kmalloc(sizeof(struct isl6421), GFP_KERNEL);
+	if (!isl6421)
+		return -ENOMEM;
+
+	/* default configuration */
+	isl6421->config = ISL6421_ISEL1;
+	isl6421->i2c = i2c;
+	isl6421->i2c_addr = i2c_addr;
+	fe->misc_priv = isl6421;
+
+	/* bits which should be forced to '1' */
+	isl6421->override_or = override_set;
+
+	/* bits which should be forced to '0' */
+	isl6421->override_and = ~override_clear;
+
+	/* detect if it is present or not */
+	if (isl6421_set_voltage(fe, SEC_VOLTAGE_OFF)) {
+		kfree(isl6421);
+		fe->misc_priv = NULL;
+		return -EIO;
+	}
+
+	/* install release callback */
+	isl6421->release_chain = fe->ops.release;
+	fe->ops.release = isl6421_release;
+
+	/* override frontend ops */
+	fe->ops.set_voltage = isl6421_set_voltage;
+	fe->ops.enable_high_lnb_voltage = isl6421_enable_high_lnb_voltage;
+
+	return 0;
+}
+EXPORT_SYMBOL(isl6421_attach);
+
+MODULE_DESCRIPTION("Driver for lnb supply and control ic isl6421");
+MODULE_AUTHOR("Andrew de Quincey & Oliver Endriss");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/isl6421.h b/drivers/media/dvb/frontends/isl6421.h
new file mode 100644
index 000000000..675f80a19
--- /dev/null
+++ b/drivers/media/dvb/frontends/isl6421.h
@@ -0,0 +1,46 @@
+/*
+ * isl6421.h - driver for lnb supply and control ic ISL6421
+ *
+ * Copyright (C) 2006 Andrew de Quincey
+ * Copyright (C) 2006 Oliver Endriss
+ *
+ * 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.
+ * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
+ *
+ *
+ * the project's page is at http://www.linuxtv.org
+ */
+
+#ifndef _ISL6421_H
+#define _ISL6421_H
+
+#include <linux/dvb/frontend.h>
+
+/* system register bits */
+#define ISL6421_OLF1	0x01
+#define ISL6421_EN1	0x02
+#define ISL6421_VSEL1	0x04
+#define ISL6421_LLC1	0x08
+#define ISL6421_ENT1	0x10
+#define ISL6421_ISEL1	0x20
+#define ISL6421_DCL	0x40
+
+/* override_set and override_clear control which system register bits (above) to always set & clear */
+extern int isl6421_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, u8 i2c_addr,
+			  u8 override_set, u8 override_clear);
+
+#endif
diff --git a/drivers/media/dvb/frontends/lg_h06xf.h b/drivers/media/dvb/frontends/lg_h06xf.h
new file mode 100644
index 000000000..754d51d11
--- /dev/null
+++ b/drivers/media/dvb/frontends/lg_h06xf.h
@@ -0,0 +1,64 @@
+/*
+ *  lg_h06xf.h - ATSC Tuner support for LG TDVS-H06xF
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef _LG_H06XF_H_
+#define _LG_H06XF_H_
+#include "dvb-pll.h"
+
+static int lg_h06xf_pll_set(struct dvb_frontend* fe, struct i2c_adapter* i2c_adap,
+		     struct dvb_frontend_parameters* params)
+{
+	u8 buf[4];
+	struct i2c_msg msg = { .addr = 0x61, .flags = 0,
+			       .buf = buf, .len = sizeof(buf) };
+	int err;
+
+	dvb_pll_configure(&dvb_pll_lg_tdvs_h06xf, buf, params->frequency, 0);
+	if (fe->ops.i2c_gate_ctrl)
+		fe->ops.i2c_gate_ctrl(fe, 1);
+	if ((err = i2c_transfer(i2c_adap, &msg, 1)) != 1) {
+		printk(KERN_WARNING "lg_h06xf: %s error "
+			"(addr %02x <- %02x, err = %i)\n",
+			__FUNCTION__, buf[0], buf[1], err);
+		if (err < 0)
+			return err;
+		else
+			return -EREMOTEIO;
+	}
+
+	/* Set the Auxiliary Byte. */
+	buf[0] = buf[2];
+	buf[0] &= ~0x20;
+	buf[0] |= 0x18;
+	buf[1] = 0x50;
+	msg.len = 2;
+	if (fe->ops.i2c_gate_ctrl)
+		fe->ops.i2c_gate_ctrl(fe, 1);
+	if ((err = i2c_transfer(i2c_adap, &msg, 1)) != 1) {
+		printk(KERN_WARNING "lg_h06xf: %s error "
+			"(addr %02x <- %02x, err = %i)\n",
+			__FUNCTION__, buf[0], buf[1], err);
+		if (err < 0)
+			return err;
+		else
+			return -EREMOTEIO;
+	}
+
+	return 0;
+}
+#endif
diff --git a/drivers/media/dvb/frontends/lnbp21.c b/drivers/media/dvb/frontends/lnbp21.c
new file mode 100644
index 000000000..e933edc8d
--- /dev/null
+++ b/drivers/media/dvb/frontends/lnbp21.c
@@ -0,0 +1,145 @@
+/*
+ * lnbp21.h - driver for lnb supply and control ic lnbp21
+ *
+ * Copyright (C) 2006 Oliver Endriss
+ *
+ * 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.
+ * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
+ *
+ *
+ * the project's page is at http://www.linuxtv.org
+ */
+#include <linux/delay.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+
+#include "dvb_frontend.h"
+#include "lnbp21.h"
+
+struct lnbp21 {
+	u8			config;
+	u8			override_or;
+	u8			override_and;
+	struct i2c_adapter	*i2c;
+	void			(*release_chain)(struct dvb_frontend* fe);
+};
+
+static int lnbp21_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
+{
+	struct lnbp21 *lnbp21 = (struct lnbp21 *) fe->misc_priv;
+	struct i2c_msg msg = {	.addr = 0x08, .flags = 0,
+				.buf = &lnbp21->config,
+				.len = sizeof(lnbp21->config) };
+
+	lnbp21->config &= ~(LNBP21_VSEL | LNBP21_EN);
+
+	switch(voltage) {
+	case SEC_VOLTAGE_OFF:
+		break;
+	case SEC_VOLTAGE_13:
+		lnbp21->config |= LNBP21_EN;
+		break;
+	case SEC_VOLTAGE_18:
+		lnbp21->config |= (LNBP21_EN | LNBP21_VSEL);
+		break;
+	default:
+		return -EINVAL;
+	};
+
+	lnbp21->config |= lnbp21->override_or;
+	lnbp21->config &= lnbp21->override_and;
+
+	return (i2c_transfer(lnbp21->i2c, &msg, 1) == 1) ? 0 : -EIO;
+}
+
+static int lnbp21_enable_high_lnb_voltage(struct dvb_frontend *fe, long arg)
+{
+	struct lnbp21 *lnbp21 = (struct lnbp21 *) fe->misc_priv;
+	struct i2c_msg msg = {	.addr = 0x08, .flags = 0,
+				.buf = &lnbp21->config,
+				.len = sizeof(lnbp21->config) };
+
+	if (arg)
+		lnbp21->config |= LNBP21_LLC;
+	else
+		lnbp21->config &= ~LNBP21_LLC;
+
+	lnbp21->config |= lnbp21->override_or;
+	lnbp21->config &= lnbp21->override_and;
+
+	return (i2c_transfer(lnbp21->i2c, &msg, 1) == 1) ? 0 : -EIO;
+}
+
+static void lnbp21_release(struct dvb_frontend *fe)
+{
+	struct lnbp21 *lnbp21 = (struct lnbp21 *) fe->misc_priv;
+
+	/* LNBP power off */
+	lnbp21_set_voltage(fe, SEC_VOLTAGE_OFF);
+
+	/* free data & call next release routine */
+	fe->ops.release = lnbp21->release_chain;
+	kfree(fe->misc_priv);
+	fe->misc_priv = NULL;
+	if (fe->ops.release)
+		fe->ops.release(fe);
+}
+
+int lnbp21_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, u8 override_set, u8 override_clear)
+{
+	struct lnbp21 *lnbp21 = kmalloc(sizeof(struct lnbp21), GFP_KERNEL);
+	if (!lnbp21)
+		return -ENOMEM;
+
+	/* default configuration */
+	lnbp21->config = LNBP21_ISEL;
+	lnbp21->i2c = i2c;
+	fe->misc_priv = lnbp21;
+
+	/* bits which should be forced to '1' */
+	lnbp21->override_or = override_set;
+
+	/* bits which should be forced to '0' */
+	lnbp21->override_and = ~override_clear;
+
+	/* detect if it is present or not */
+	if (lnbp21_set_voltage(fe, SEC_VOLTAGE_OFF)) {
+		kfree(lnbp21);
+		fe->misc_priv = NULL;
+		return -EIO;
+	}
+
+	/* install release callback */
+	lnbp21->release_chain = fe->ops.release;
+	fe->ops.release = lnbp21_release;
+
+	/* override frontend ops */
+	fe->ops.set_voltage = lnbp21_set_voltage;
+	fe->ops.enable_high_lnb_voltage = lnbp21_enable_high_lnb_voltage;
+
+	return 0;
+}
+EXPORT_SYMBOL(lnbp21_attach);
+
+MODULE_DESCRIPTION("Driver for lnb supply and control ic lnbp21");
+MODULE_AUTHOR("Oliver Endriss");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/radio/dsbr100.c b/drivers/media/radio/dsbr100.c
new file mode 100644
index 000000000..f7e33f9ee
--- /dev/null
+++ b/drivers/media/radio/dsbr100.c
@@ -0,0 +1,430 @@
+/* A driver for the D-Link DSB-R100 USB radio.  The R100 plugs
+ into both the USB and an analog audio input, so this thing
+ only deals with initialisation and frequency setting, the
+ audio data has to be handled by a sound driver.
+
+ Major issue: I can't find out where the device reports the signal
+ strength, and indeed the windows software appearantly just looks
+ at the stereo indicator as well.  So, scanning will only find
+ stereo stations.  Sad, but I can't help it.
+
+ Also, the windows program sends oodles of messages over to the
+ device, and I couldn't figure out their meaning.  My suspicion
+ is that they don't have any:-)
+
+ You might find some interesting stuff about this module at
+ http://unimut.fsk.uni-heidelberg.de/unimut/demi/dsbr
+
+ Copyright (c) 2000 Markus Demleitner <msdemlei@cl.uni-heidelberg.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; 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
+
+ History:
+
+ Version 0.40:
+  Markus: Updates for 2.6.x kernels, code layout changes, name sanitizing
+
+ Version 0.30:
+	Markus: Updates for 2.5.x kernel and more ISO compliant source
+
+ Version 0.25:
+	PSL and Markus: Cleanup, radio now doesn't stop on device close
+
+ Version 0.24:
+	Markus: Hope I got these silly VIDEO_TUNER_LOW issues finally
+	right.  Some minor cleanup, improved standalone compilation
+
+ Version 0.23:
+	Markus: Sign extension bug fixed by declaring transfer_buffer unsigned
+
+ Version 0.22:
+	Markus: Some (brown bag) cleanup in what VIDIOCSTUNER returns,
+	thanks to Mike Cox for pointing the problem out.
+
+ Version 0.21:
+	Markus: Minor cleanup, warnings if something goes wrong, lame attempt
+	to adhere to Documentation/CodingStyle
+
+ Version 0.2:
+	Brad Hards <bradh@dynamite.com.au>: Fixes to make it work as non-module
+	Markus: Copyright clarification
+
+ Version 0.01: Markus: initial release
+
+*/
+
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/input.h>
+#include <linux/videodev.h>
+#include <media/v4l2-common.h>
+#include <linux/usb.h>
+#include <linux/smp_lock.h>
+
+/*
+ * Version Information
+ */
+#define DRIVER_VERSION "v0.40"
+#define DRIVER_AUTHOR "Markus Demleitner <msdemlei@tucana.harvard.edu>"
+#define DRIVER_DESC "D-Link DSB-R100 USB FM radio driver"
+
+#define DSB100_VENDOR 0x04b4
+#define DSB100_PRODUCT 0x1002
+
+/* Commands the device appears to understand */
+#define DSB100_TUNE 1
+#define DSB100_ONOFF 2
+
+#define TB_LEN 16
+
+/* Frequency limits in MHz -- these are European values.  For Japanese
+devices, that would be 76 and 91.  */
+#define FREQ_MIN  87.5
+#define FREQ_MAX 108.0
+#define FREQ_MUL 16000
+
+
+static int usb_dsbr100_probe(struct usb_interface *intf,
+			     const struct usb_device_id *id);
+static void usb_dsbr100_disconnect(struct usb_interface *intf);
+static int usb_dsbr100_ioctl(struct inode *inode, struct file *file,
+			     unsigned int cmd, unsigned long arg);
+static int usb_dsbr100_open(struct inode *inode, struct file *file);
+static int usb_dsbr100_close(struct inode *inode, struct file *file);
+
+static int radio_nr = -1;
+module_param(radio_nr, int, 0);
+
+/* Data for one (physical) device */
+typedef struct {
+	struct usb_device *usbdev;
+	struct video_device *videodev;
+	unsigned char transfer_buffer[TB_LEN];
+	int curfreq;
+	int stereo;
+	int users;
+	int removed;
+} dsbr100_device;
+
+
+/* File system interface */
+static struct file_operations usb_dsbr100_fops = {
+	.owner =	THIS_MODULE,
+	.open =		usb_dsbr100_open,
+	.release =     	usb_dsbr100_close,
+	.ioctl =        usb_dsbr100_ioctl,
+	.compat_ioctl = v4l_compat_ioctl32,
+	.llseek =       no_llseek,
+};
+
+/* V4L interface */
+static struct video_device dsbr100_videodev_template=
+{
+	.owner =	THIS_MODULE,
+	.name =		"D-Link DSB-R 100",
+	.type =		VID_TYPE_TUNER,
+	.hardware =	VID_HARDWARE_AZTECH,
+	.fops =         &usb_dsbr100_fops,
+	.release = video_device_release,
+};
+
+static struct usb_device_id usb_dsbr100_device_table [] = {
+	{ USB_DEVICE(DSB100_VENDOR, DSB100_PRODUCT) },
+	{ }						/* Terminating entry */
+};
+
+MODULE_DEVICE_TABLE (usb, usb_dsbr100_device_table);
+
+/* USB subsystem interface */
+static struct usb_driver usb_dsbr100_driver = {
+	.name =		"dsbr100",
+	.probe =	usb_dsbr100_probe,
+	.disconnect =	usb_dsbr100_disconnect,
+	.id_table =	usb_dsbr100_device_table,
+};
+
+/* Low-level device interface begins here */
+
+/* switch on radio */
+static int dsbr100_start(dsbr100_device *radio)
+{
+	if (usb_control_msg(radio->usbdev, usb_rcvctrlpipe(radio->usbdev, 0),
+			USB_REQ_GET_STATUS,
+			USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
+			0x00, 0xC7, radio->transfer_buffer, 8, 300)<0 ||
+	usb_control_msg(radio->usbdev, usb_rcvctrlpipe(radio->usbdev, 0),
+			DSB100_ONOFF,
+			USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
+			0x01, 0x00, radio->transfer_buffer, 8, 300)<0)
+		return -1;
+	return (radio->transfer_buffer)[0];
+}
+
+
+/* switch off radio */
+static int dsbr100_stop(dsbr100_device *radio)
+{
+	if (usb_control_msg(radio->usbdev, usb_rcvctrlpipe(radio->usbdev, 0),
+			USB_REQ_GET_STATUS,
+			USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
+			0x16, 0x1C, radio->transfer_buffer, 8, 300)<0 ||
+	usb_control_msg(radio->usbdev, usb_rcvctrlpipe(radio->usbdev, 0),
+			DSB100_ONOFF,
+			USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
+			0x00, 0x00, radio->transfer_buffer, 8, 300)<0)
+		return -1;
+	return (radio->transfer_buffer)[0];
+}
+
+/* set a frequency, freq is defined by v4l's TUNER_LOW, i.e. 1/16th kHz */
+static int dsbr100_setfreq(dsbr100_device *radio, int freq)
+{
+	freq = (freq/16*80)/1000+856;
+	if (usb_control_msg(radio->usbdev, usb_rcvctrlpipe(radio->usbdev, 0),
+			DSB100_TUNE,
+			USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
+			(freq>>8)&0x00ff, freq&0xff,
+			radio->transfer_buffer, 8, 300)<0 ||
+	   usb_control_msg(radio->usbdev, usb_rcvctrlpipe(radio->usbdev, 0),
+			USB_REQ_GET_STATUS,
+			USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
+			0x96, 0xB7, radio->transfer_buffer, 8, 300)<0 ||
+	usb_control_msg(radio->usbdev, usb_rcvctrlpipe(radio->usbdev, 0),
+			USB_REQ_GET_STATUS,
+			USB_TYPE_VENDOR | USB_RECIP_DEVICE |  USB_DIR_IN,
+			0x00, 0x24, radio->transfer_buffer, 8, 300)<0) {
+		radio->stereo = -1;
+		return -1;
+	}
+	radio->stereo = ! ((radio->transfer_buffer)[0]&0x01);
+	return (radio->transfer_buffer)[0];
+}
+
+/* return the device status.  This is, in effect, just whether it
+sees a stereo signal or not.  Pity. */
+static void dsbr100_getstat(dsbr100_device *radio)
+{
+	if (usb_control_msg(radio->usbdev, usb_rcvctrlpipe(radio->usbdev, 0),
+		USB_REQ_GET_STATUS,
+		USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
+		0x00 , 0x24, radio->transfer_buffer, 8, 300)<0)
+		radio->stereo = -1;
+	else
+		radio->stereo = ! (radio->transfer_buffer[0]&0x01);
+}
+
+
+/* USB subsystem interface begins here */
+
+/* check if the device is present and register with v4l and
+usb if it is */
+static int usb_dsbr100_probe(struct usb_interface *intf,
+			 const struct usb_device_id *id)
+{
+	dsbr100_device *radio;
+
+	if (!(radio = kmalloc(sizeof(dsbr100_device), GFP_KERNEL)))
+		return -ENOMEM;
+	if (!(radio->videodev = video_device_alloc())) {
+		kfree(radio);
+		return -ENOMEM;
+	}
+	memcpy(radio->videodev, &dsbr100_videodev_template,
+		sizeof(dsbr100_videodev_template));
+	radio->removed = 0;
+	radio->users = 0;
+	radio->usbdev = interface_to_usbdev(intf);
+	radio->curfreq = FREQ_MIN*FREQ_MUL;
+	video_set_drvdata(radio->videodev, radio);
+	if (video_register_device(radio->videodev, VFL_TYPE_RADIO,
+		radio_nr)) {
+		warn("Could not register video device");
+		video_device_release(radio->videodev);
+		kfree(radio);
+		return -EIO;
+	}
+	usb_set_intfdata(intf, radio);
+	return 0;
+}
+
+/* handle unplugging of the device, release data structures
+if nothing keeps us from doing it.  If something is still
+keeping us busy, the release callback of v4l will take care
+of releasing it.  stv680.c does not relase its private
+data, so I don't do this here either.  Checking out the
+code I'd expect I better did that, but if there's a memory
+leak here it's tiny (~50 bytes per disconnect) */
+static void usb_dsbr100_disconnect(struct usb_interface *intf)
+{
+	dsbr100_device *radio = usb_get_intfdata(intf);
+
+	usb_set_intfdata (intf, NULL);
+	if (radio) {
+		video_unregister_device(radio->videodev);
+		radio->videodev = NULL;
+		if (radio->users) {
+			kfree(radio);
+		} else {
+			radio->removed = 1;
+		}
+	}
+}
+
+
+/* Video for Linux interface */
+
+static int usb_dsbr100_do_ioctl(struct inode *inode, struct file *file,
+				unsigned int cmd, void *arg)
+{
+	dsbr100_device *radio=video_get_drvdata(video_devdata(file));
+
+	if (!radio)
+		return -EIO;
+
+	switch(cmd) {
+		case VIDIOCGCAP: {
+			struct video_capability *v = arg;
+
+			memset(v, 0, sizeof(*v));
+			v->type = VID_TYPE_TUNER;
+			v->channels = 1;
+			v->audios = 1;
+			strcpy(v->name, "D-Link R-100 USB FM Radio");
+			return 0;
+		}
+		case VIDIOCGTUNER: {
+			struct video_tuner *v = arg;
+
+			dsbr100_getstat(radio);
+			if(v->tuner)	/* Only 1 tuner */
+				return -EINVAL;
+			v->rangelow = FREQ_MIN*FREQ_MUL;
+			v->rangehigh = FREQ_MAX*FREQ_MUL;
+			v->flags = VIDEO_TUNER_LOW;
+			v->mode = VIDEO_MODE_AUTO;
+			v->signal = radio->stereo*0x7000;
+				/* Don't know how to get signal strength */
+			v->flags |= VIDEO_TUNER_STEREO_ON*radio->stereo;
+			strcpy(v->name, "DSB R-100");
+			return 0;
+		}
+		case VIDIOCSTUNER: {
+			struct video_tuner *v = arg;
+
+			if(v->tuner!=0)
+				return -EINVAL;
+			/* Only 1 tuner so no setting needed ! */
+			return 0;
+		}
+		case VIDIOCGFREQ: {
+			int *freq = arg;
+
+			if (radio->curfreq==-1)
+				return -EINVAL;
+			*freq = radio->curfreq;
+			return 0;
+		}
+		case VIDIOCSFREQ: {
+			int *freq = arg;
+
+			radio->curfreq = *freq;
+			if (dsbr100_setfreq(radio, radio->curfreq)==-1)
+				warn("Set frequency failed");
+			return 0;
+		}
+		case VIDIOCGAUDIO: {
+			struct video_audio *v = arg;
+
+			memset(v, 0, sizeof(*v));
+			v->flags |= VIDEO_AUDIO_MUTABLE;
+			v->mode = VIDEO_SOUND_STEREO;
+			v->volume = 1;
+			v->step = 1;
+			strcpy(v->name, "Radio");
+			return 0;
+		}
+		case VIDIOCSAUDIO: {
+			struct video_audio *v = arg;
+
+			if (v->audio)
+				return -EINVAL;
+			if (v->flags&VIDEO_AUDIO_MUTE) {
+				if (dsbr100_stop(radio)==-1)
+					warn("Radio did not respond properly");
+			}
+			else
+				if (dsbr100_start(radio)==-1)
+					warn("Radio did not respond properly");
+			return 0;
+		}
+		default:
+			return -ENOIOCTLCMD;
+	}
+}
+
+static int usb_dsbr100_ioctl(struct inode *inode, struct file *file,
+			     unsigned int cmd, unsigned long arg)
+{
+	return video_usercopy(inode, file, cmd, arg, usb_dsbr100_do_ioctl);
+}
+
+static int usb_dsbr100_open(struct inode *inode, struct file *file)
+{
+	dsbr100_device *radio=video_get_drvdata(video_devdata(file));
+
+	radio->users = 1;
+	if (dsbr100_start(radio)<0) {
+		warn("Radio did not start up properly");
+		radio->users = 0;
+		return -EIO;
+	}
+	dsbr100_setfreq(radio, radio->curfreq);
+	return 0;
+}
+
+static int usb_dsbr100_close(struct inode *inode, struct file *file)
+{
+	dsbr100_device *radio=video_get_drvdata(video_devdata(file));
+
+	if (!radio)
+		return -ENODEV;
+	radio->users = 0;
+	if (radio->removed) {
+		kfree(radio);
+	}
+	return 0;
+}
+
+static int __init dsbr100_init(void)
+{
+	int retval = usb_register(&usb_dsbr100_driver);
+	info(DRIVER_VERSION ":" DRIVER_DESC);
+	return retval;
+}
+
+static void __exit dsbr100_exit(void)
+{
+	usb_deregister(&usb_dsbr100_driver);
+}
+
+module_init (dsbr100_init);
+module_exit (dsbr100_exit);
+
+MODULE_AUTHOR( DRIVER_AUTHOR );
+MODULE_DESCRIPTION( DRIVER_DESC );
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/video/bt866.c b/drivers/media/video/bt866.c
new file mode 100644
index 000000000..05e42bbcf
--- /dev/null
+++ b/drivers/media/video/bt866.c
@@ -0,0 +1,377 @@
+/*
+    bt866 - BT866 Digital Video Encoder (Rockwell Part)
+
+    Copyright (C) 1999 Mike Bernson <mike@mlb.org>
+    Copyright (C) 1998 Dave Perks <dperks@ibm.net>
+
+    Modifications for LML33/DC10plus unified driver
+    Copyright (C) 2000 Serguei Miridonov <mirsev@cicese.mx>
+
+    This code was modify/ported from the saa7111 driver written
+    by Dave Perks.
+
+    This code was adapted for the bt866 by Christer Weinigel and ported
+    to 2.6 by Martin Samuelsson.
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/errno.h>
+#include <linux/fs.h>
+#include <linux/kernel.h>
+#include <linux/major.h>
+#include <linux/slab.h>
+#include <linux/mm.h>
+#include <linux/pci.h>
+#include <linux/signal.h>
+#include <asm/io.h>
+#include <asm/pgtable.h>
+#include <asm/page.h>
+#include <linux/sched.h>
+#include <linux/types.h>
+#include <linux/i2c.h>
+
+#include <linux/videodev.h>
+#include <asm/uaccess.h>
+
+#include <linux/video_encoder.h>
+
+MODULE_LICENSE("GPL");
+
+#define	BT866_DEVNAME	"bt866"
+#define I2C_BT866	0x88
+
+MODULE_LICENSE("GPL");
+
+#define DEBUG(x)		/* Debug driver */
+
+/* ----------------------------------------------------------------------- */
+
+struct bt866 {
+	struct i2c_client *i2c;
+	int addr;
+	unsigned char reg[128];
+
+	int norm;
+	int enable;
+	int bright;
+	int contrast;
+	int hue;
+	int sat;
+};
+
+static int bt866_write(struct bt866 *dev,
+			unsigned char subaddr, unsigned char data);
+
+static int bt866_do_command(struct bt866 *encoder,
+			unsigned int cmd, void *arg)
+{
+	switch (cmd) {
+	case ENCODER_GET_CAPABILITIES:
+	{
+		struct video_encoder_capability *cap = arg;
+
+		DEBUG(printk
+		      (KERN_INFO "%s: get capabilities\n",
+		       encoder->i2c->name));
+
+		cap->flags
+			= VIDEO_ENCODER_PAL
+			| VIDEO_ENCODER_NTSC
+			| VIDEO_ENCODER_CCIR;
+		cap->inputs = 2;
+		cap->outputs = 1;
+	}
+	break;
+
+	case ENCODER_SET_NORM:
+	{
+		int *iarg = arg;
+
+		DEBUG(printk(KERN_INFO "%s: set norm %d\n",
+			     encoder->i2c->name, *iarg));
+
+		switch (*iarg) {
+
+		case VIDEO_MODE_NTSC:
+			break;
+
+		case VIDEO_MODE_PAL:
+			break;
+
+		default:
+			return -EINVAL;
+
+		}
+		encoder->norm = *iarg;
+	}
+	break;
+
+	case ENCODER_SET_INPUT:
+	{
+		int *iarg = arg;
+		static const __u8 init[] = {
+			0xc8, 0xcc, /* CRSCALE */
+			0xca, 0x91, /* CBSCALE */
+			0xcc, 0x24, /* YC16 | OSDNUM */
+			0xda, 0x00, /*  */
+			0xdc, 0x24, /* SETMODE | PAL */
+			0xde, 0x02, /* EACTIVE */
+
+			/* overlay colors */
+			0x70, 0xEB, 0x90, 0x80, 0xB0, 0x80, /* white */
+			0x72, 0xA2, 0x92, 0x8E, 0xB2, 0x2C, /* yellow */
+			0x74, 0x83, 0x94, 0x2C, 0xB4, 0x9C, /* cyan */
+			0x76, 0x70, 0x96, 0x3A, 0xB6, 0x48, /* green */
+			0x78, 0x54, 0x98, 0xC6, 0xB8, 0xB8, /* magenta */
+			0x7A, 0x41, 0x9A, 0xD4, 0xBA, 0x64, /* red */
+			0x7C, 0x23, 0x9C, 0x72, 0xBC, 0xD4, /* blue */
+			0x7E, 0x10, 0x9E, 0x80, 0xBE, 0x80, /* black */
+
+			0x60, 0xEB, 0x80, 0x80, 0xc0, 0x80, /* white */
+			0x62, 0xA2, 0x82, 0x8E, 0xc2, 0x2C, /* yellow */
+			0x64, 0x83, 0x84, 0x2C, 0xc4, 0x9C, /* cyan */
+			0x66, 0x70, 0x86, 0x3A, 0xc6, 0x48, /* green */
+			0x68, 0x54, 0x88, 0xC6, 0xc8, 0xB8, /* magenta */
+			0x6A, 0x41, 0x8A, 0xD4, 0xcA, 0x64, /* red */
+			0x6C, 0x23, 0x8C, 0x72, 0xcC, 0xD4, /* blue */
+			0x6E, 0x10, 0x8E, 0x80, 0xcE, 0x80, /* black */
+		};
+		int i;
+		u8 val;
+
+		for (i = 0; i < ARRAY_SIZE(init) / 2; i += 2)
+			bt866_write(encoder, init[i], init[i+1]);
+
+		val = encoder->reg[0xdc];
+
+		if (*iarg == 0)
+			val |= 0x40; /* CBSWAP */
+		else
+			val &= ~0x40; /* !CBSWAP */
+
+		bt866_write(encoder, 0xdc, val);
+
+		val = encoder->reg[0xcc];
+		if (*iarg == 2)
+			val |= 0x01; /* OSDBAR */
+		else
+			val &= ~0x01; /* !OSDBAR */
+		bt866_write(encoder, 0xcc, val);
+
+		DEBUG(printk(KERN_INFO "%s: set input %d\n",
+			     encoder->i2c->name, *iarg));
+
+		switch (*iarg) {
+		case 0:
+			break;
+		case 1:
+			break;
+		default:
+			return -EINVAL;
+
+		}
+	}
+	break;
+
+	case ENCODER_SET_OUTPUT:
+	{
+		int *iarg = arg;
+
+		DEBUG(printk(KERN_INFO "%s: set output %d\n",
+			     encoder->i2c->name, *iarg));
+
+		/* not much choice of outputs */
+		if (*iarg != 0)
+			return -EINVAL;
+	}
+	break;
+
+	case ENCODER_ENABLE_OUTPUT:
+	{
+		int *iarg = arg;
+		encoder->enable = !!*iarg;
+
+		DEBUG(printk
+		      (KERN_INFO "%s: enable output %d\n",
+		       encoder->i2c->name, encoder->enable));
+	}
+	break;
+
+	case 4711:
+	{
+		int *iarg = arg;
+		__u8 val;
+
+		printk("bt866: square = %d\n", *iarg);
+
+		val = encoder->reg[0xdc];
+		if (*iarg)
+			val |= 1; /* SQUARE */
+		else
+			val &= ~1; /* !SQUARE */
+		bt866_write(encoder, 0xdc, val);
+		break;
+	}
+
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int bt866_write(struct bt866 *encoder,
+			unsigned char subaddr, unsigned char data)
+{
+	unsigned char buffer[2];
+	int err;
+
+	buffer[0] = subaddr;
+	buffer[1] = data;
+
+	encoder->reg[subaddr] = data;
+
+	DEBUG(printk
+	      ("%s: write 0x%02X = 0x%02X\n",
+	       encoder->i2c->name, subaddr, data));
+
+	for (err = 0; err < 3;) {
+		if (i2c_master_send(encoder->i2c, buffer, 2) == 2)
+			break;
+		err++;
+		printk(KERN_WARNING "%s: I/O error #%d "
+		       "(write 0x%02x/0x%02x)\n",
+		       encoder->i2c->name, err, encoder->addr, subaddr);
+		schedule_timeout_interruptible(HZ/10);
+	}
+	if (err == 3) {
+		printk(KERN_WARNING "%s: giving up\n",
+		       encoder->i2c->name);
+		return -1;
+	}
+
+	return 0;
+}
+
+static int bt866_attach(struct i2c_adapter *adapter);
+static int bt866_detach(struct i2c_client *client);
+static int bt866_command(struct i2c_client *client,
+			 unsigned int cmd, void *arg);
+
+
+/* Addresses to scan */
+static unsigned short normal_i2c[]	= {I2C_BT866>>1, I2C_CLIENT_END};
+static unsigned short probe[2]		= {I2C_CLIENT_END, I2C_CLIENT_END};
+static unsigned short ignore[2]		= {I2C_CLIENT_END, I2C_CLIENT_END};
+
+static struct i2c_client_address_data addr_data = {
+	normal_i2c,
+	probe,
+	ignore,
+};
+
+static struct i2c_driver i2c_driver_bt866 = {
+	.driver.name = BT866_DEVNAME,
+	.id = I2C_DRIVERID_BT866,
+	.attach_adapter = bt866_attach,
+	.detach_client = bt866_detach,
+	.command = bt866_command
+};
+
+
+static struct i2c_client bt866_client_tmpl =
+{
+	.name = "(nil)",
+	.addr = 0,
+	.adapter = NULL,
+	.driver = &i2c_driver_bt866,
+	.usage_count = 0
+};
+
+static int bt866_found_proc(struct i2c_adapter *adapter,
+			    int addr, int kind)
+{
+	struct bt866 *encoder;
+	struct i2c_client *client;
+
+	client = kzalloc(sizeof(*client), GFP_KERNEL);
+	if (client == NULL)
+		return -ENOMEM;
+	memcpy(client, &bt866_client_tmpl, sizeof(*client));
+
+	encoder = kzalloc(sizeof(*encoder), GFP_KERNEL);
+	if (encoder == NULL) {
+		kfree(client);
+		return -ENOMEM;
+	}
+
+	i2c_set_clientdata(client, encoder);
+	client->adapter = adapter;
+	client->addr = addr;
+	sprintf(client->name, "%s-%02x", BT866_DEVNAME, adapter->id);
+
+	encoder->i2c = client;
+	encoder->addr = addr;
+	//encoder->encoder_type = ENCODER_TYPE_UNKNOWN;
+
+	/* initialize */
+
+	i2c_attach_client(client);
+
+	return 0;
+}
+
+static int bt866_attach(struct i2c_adapter *adapter)
+{
+	if (adapter->id == I2C_HW_B_ZR36067)
+		return i2c_probe(adapter, &addr_data, bt866_found_proc);
+	return 0;
+}
+
+static int bt866_detach(struct i2c_client *client)
+{
+	struct bt866 *encoder = i2c_get_clientdata(client);
+
+	i2c_detach_client(client);
+	kfree(encoder);
+	kfree(client);
+
+	return 0;
+}
+
+static int bt866_command(struct i2c_client *client,
+			 unsigned int cmd, void *arg)
+{
+	struct bt866 *encoder = i2c_get_clientdata(client);
+	return bt866_do_command(encoder, cmd, arg);
+}
+
+static int __devinit bt866_init(void)
+{
+	i2c_add_driver(&i2c_driver_bt866);
+	return 0;
+}
+
+static void __devexit bt866_exit(void)
+{
+	i2c_del_driver(&i2c_driver_bt866);
+}
+
+module_init(bt866_init);
+module_exit(bt866_exit);
diff --git a/drivers/media/video/cx2341x.c b/drivers/media/video/cx2341x.c
new file mode 100644
index 000000000..65f00fc08
--- /dev/null
+++ b/drivers/media/video/cx2341x.c
@@ -0,0 +1,932 @@
+/*
+ * cx2341x - generic code for cx23415/6 based devices
+ *
+ * Copyright (C) 2006 Hans Verkuil <hverkuil@xs4all.nl>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/videodev2.h>
+#include <linux/i2c.h>
+
+#include <media/tuner.h>
+#include <media/cx2341x.h>
+#include <media/v4l2-common.h>
+
+MODULE_DESCRIPTION("cx23415/6 driver");
+MODULE_AUTHOR("Hans Verkuil");
+MODULE_LICENSE("GPL");
+
+static int debug = 0;
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "Debug level (0-1)");
+
+const u32 cx2341x_mpeg_ctrls[] = {
+	V4L2_CID_MPEG_CLASS,
+	V4L2_CID_MPEG_STREAM_TYPE,
+	V4L2_CID_MPEG_STREAM_VBI_FMT,
+	V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ,
+	V4L2_CID_MPEG_AUDIO_ENCODING,
+	V4L2_CID_MPEG_AUDIO_L2_BITRATE,
+	V4L2_CID_MPEG_AUDIO_MODE,
+	V4L2_CID_MPEG_AUDIO_MODE_EXTENSION,
+	V4L2_CID_MPEG_AUDIO_EMPHASIS,
+	V4L2_CID_MPEG_AUDIO_CRC,
+	V4L2_CID_MPEG_VIDEO_ENCODING,
+	V4L2_CID_MPEG_VIDEO_ASPECT,
+	V4L2_CID_MPEG_VIDEO_B_FRAMES,
+	V4L2_CID_MPEG_VIDEO_GOP_SIZE,
+	V4L2_CID_MPEG_VIDEO_GOP_CLOSURE,
+	V4L2_CID_MPEG_VIDEO_PULLDOWN,
+	V4L2_CID_MPEG_VIDEO_BITRATE_MODE,
+	V4L2_CID_MPEG_VIDEO_BITRATE,
+	V4L2_CID_MPEG_VIDEO_BITRATE_PEAK,
+	V4L2_CID_MPEG_VIDEO_TEMPORAL_DECIMATION,
+	V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE,
+	V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER,
+	V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE,
+	V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE,
+	V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE,
+	V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER,
+	V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE,
+	V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_BOTTOM,
+	V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_TOP,
+	V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_BOTTOM,
+	V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_TOP,
+	0
+};
+
+
+/* Map the control ID to the correct field in the cx2341x_mpeg_params
+   struct. Return -EINVAL if the ID is unknown, else return 0. */
+static int cx2341x_get_ctrl(struct cx2341x_mpeg_params *params,
+		struct v4l2_ext_control *ctrl)
+{
+	switch (ctrl->id) {
+	case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ:
+		ctrl->value = params->audio_sampling_freq;
+		break;
+	case V4L2_CID_MPEG_AUDIO_ENCODING:
+		ctrl->value = params->audio_encoding;
+		break;
+	case V4L2_CID_MPEG_AUDIO_L2_BITRATE:
+		ctrl->value = params->audio_l2_bitrate;
+		break;
+	case V4L2_CID_MPEG_AUDIO_MODE:
+		ctrl->value = params->audio_mode;
+		break;
+	case V4L2_CID_MPEG_AUDIO_MODE_EXTENSION:
+		ctrl->value = params->audio_mode_extension;
+		break;
+	case V4L2_CID_MPEG_AUDIO_EMPHASIS:
+		ctrl->value = params->audio_emphasis;
+		break;
+	case V4L2_CID_MPEG_AUDIO_CRC:
+		ctrl->value = params->audio_crc;
+		break;
+	case V4L2_CID_MPEG_VIDEO_ENCODING:
+		ctrl->value = params->video_encoding;
+		break;
+	case V4L2_CID_MPEG_VIDEO_ASPECT:
+		ctrl->value = params->video_aspect;
+		break;
+	case V4L2_CID_MPEG_VIDEO_B_FRAMES:
+		ctrl->value = params->video_b_frames;
+		break;
+	case V4L2_CID_MPEG_VIDEO_GOP_SIZE:
+		ctrl->value = params->video_gop_size;
+		break;
+	case V4L2_CID_MPEG_VIDEO_GOP_CLOSURE:
+		ctrl->value = params->video_gop_closure;
+		break;
+	case V4L2_CID_MPEG_VIDEO_PULLDOWN:
+		ctrl->value = params->video_pulldown;
+		break;
+	case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
+		ctrl->value = params->video_bitrate_mode;
+		break;
+	case V4L2_CID_MPEG_VIDEO_BITRATE:
+		ctrl->value = params->video_bitrate;
+		break;
+	case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK:
+		ctrl->value = params->video_bitrate_peak;
+		break;
+	case V4L2_CID_MPEG_VIDEO_TEMPORAL_DECIMATION:
+		ctrl->value = params->video_temporal_decimation;
+		break;
+	case V4L2_CID_MPEG_STREAM_TYPE:
+		ctrl->value = params->stream_type;
+		break;
+	case V4L2_CID_MPEG_STREAM_VBI_FMT:
+		ctrl->value = params->stream_vbi_fmt;
+		break;
+	case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE:
+		ctrl->value = params->video_spatial_filter_mode;
+		break;
+	case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER:
+		ctrl->value = params->video_spatial_filter;
+		break;
+	case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE:
+		ctrl->value = params->video_luma_spatial_filter_type;
+		break;
+	case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE:
+		ctrl->value = params->video_chroma_spatial_filter_type;
+		break;
+	case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE:
+		ctrl->value = params->video_temporal_filter_mode;
+		break;
+	case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER:
+		ctrl->value = params->video_temporal_filter;
+		break;
+	case V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE:
+		ctrl->value = params->video_median_filter_type;
+		break;
+	case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_TOP:
+		ctrl->value = params->video_luma_median_filter_top;
+		break;
+	case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_BOTTOM:
+		ctrl->value = params->video_luma_median_filter_bottom;
+		break;
+	case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_TOP:
+		ctrl->value = params->video_chroma_median_filter_top;
+		break;
+	case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_BOTTOM:
+		ctrl->value = params->video_chroma_median_filter_bottom;
+		break;
+	default:
+		return -EINVAL;
+	}
+	return 0;
+}
+
+/* Map the control ID to the correct field in the cx2341x_mpeg_params
+   struct. Return -EINVAL if the ID is unknown, else return 0. */
+static int cx2341x_set_ctrl(struct cx2341x_mpeg_params *params,
+		struct v4l2_ext_control *ctrl)
+{
+	switch (ctrl->id) {
+	case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ:
+		params->audio_sampling_freq = ctrl->value;
+		break;
+	case V4L2_CID_MPEG_AUDIO_ENCODING:
+		params->audio_encoding = ctrl->value;
+		break;
+	case V4L2_CID_MPEG_AUDIO_L2_BITRATE:
+		params->audio_l2_bitrate = ctrl->value;
+		break;
+	case V4L2_CID_MPEG_AUDIO_MODE:
+		params->audio_mode = ctrl->value;
+		break;
+	case V4L2_CID_MPEG_AUDIO_MODE_EXTENSION:
+		params->audio_mode_extension = ctrl->value;
+		break;
+	case V4L2_CID_MPEG_AUDIO_EMPHASIS:
+		params->audio_emphasis = ctrl->value;
+		break;
+	case V4L2_CID_MPEG_AUDIO_CRC:
+		params->audio_crc = ctrl->value;
+		break;
+	case V4L2_CID_MPEG_VIDEO_ASPECT:
+		params->video_aspect = ctrl->value;
+		break;
+	case V4L2_CID_MPEG_VIDEO_B_FRAMES: {
+		int b = ctrl->value + 1;
+		int gop = params->video_gop_size;
+		params->video_b_frames = ctrl->value;
+		params->video_gop_size = b * ((gop + b - 1) / b);
+		/* Max GOP size = 34 */
+		while (params->video_gop_size > 34)
+			params->video_gop_size -= b;
+		break;
+	}
+	case V4L2_CID_MPEG_VIDEO_GOP_SIZE: {
+		int b = params->video_b_frames + 1;
+		int gop = ctrl->value;
+		params->video_gop_size = b * ((gop + b - 1) / b);
+		/* Max GOP size = 34 */
+		while (params->video_gop_size > 34)
+			params->video_gop_size -= b;
+		ctrl->value = params->video_gop_size;
+		break;
+	}
+	case V4L2_CID_MPEG_VIDEO_GOP_CLOSURE:
+		params->video_gop_closure = ctrl->value;
+		break;
+	case V4L2_CID_MPEG_VIDEO_PULLDOWN:
+		params->video_pulldown = ctrl->value;
+		break;
+	case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
+		/* MPEG-1 only allows CBR */
+		if (params->video_encoding == V4L2_MPEG_VIDEO_ENCODING_MPEG_1 &&
+		    ctrl->value != V4L2_MPEG_VIDEO_BITRATE_MODE_CBR)
+			return -EINVAL;
+		params->video_bitrate_mode = ctrl->value;
+		break;
+	case V4L2_CID_MPEG_VIDEO_BITRATE:
+		params->video_bitrate = ctrl->value;
+		break;
+	case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK:
+		params->video_bitrate_peak = ctrl->value;
+		break;
+	case V4L2_CID_MPEG_VIDEO_TEMPORAL_DECIMATION:
+		params->video_temporal_decimation = ctrl->value;
+		break;
+	case V4L2_CID_MPEG_STREAM_TYPE:
+		params->stream_type = ctrl->value;
+		params->video_encoding =
+			(params->stream_type == V4L2_MPEG_STREAM_TYPE_MPEG1_SS ||
+			 params->stream_type == V4L2_MPEG_STREAM_TYPE_MPEG1_VCD) ?
+			V4L2_MPEG_VIDEO_ENCODING_MPEG_1 : V4L2_MPEG_VIDEO_ENCODING_MPEG_2;
+		if (params->video_encoding == V4L2_MPEG_VIDEO_ENCODING_MPEG_1) {
+			/* MPEG-1 implies CBR */
+			params->video_bitrate_mode = V4L2_MPEG_VIDEO_BITRATE_MODE_CBR;
+		}
+		break;
+	case V4L2_CID_MPEG_STREAM_VBI_FMT:
+		params->stream_vbi_fmt = ctrl->value;
+		break;
+	case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE:
+		params->video_spatial_filter_mode = ctrl->value;
+		break;
+	case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER:
+		params->video_spatial_filter = ctrl->value;
+		break;
+	case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE:
+		params->video_luma_spatial_filter_type = ctrl->value;
+		break;
+	case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE:
+		params->video_chroma_spatial_filter_type = ctrl->value;
+		break;
+	case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE:
+		params->video_temporal_filter_mode = ctrl->value;
+		break;
+	case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER:
+		params->video_temporal_filter = ctrl->value;
+		break;
+	case V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE:
+		params->video_median_filter_type = ctrl->value;
+		break;
+	case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_TOP:
+		params->video_luma_median_filter_top = ctrl->value;
+		break;
+	case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_BOTTOM:
+		params->video_luma_median_filter_bottom = ctrl->value;
+		break;
+	case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_TOP:
+		params->video_chroma_median_filter_top = ctrl->value;
+		break;
+	case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_BOTTOM:
+		params->video_chroma_median_filter_bottom = ctrl->value;
+		break;
+	default:
+		return -EINVAL;
+	}
+	return 0;
+}
+
+static int cx2341x_ctrl_query_fill(struct v4l2_queryctrl *qctrl, s32 min, s32 max, s32 step, s32 def)
+{
+	const char *name;
+
+	qctrl->flags = 0;
+	switch (qctrl->id) {
+	/* MPEG controls */
+	case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE:
+		name = "Spatial Filter Mode";
+		break;
+	case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER:
+		name = "Spatial Filter";
+		break;
+	case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE:
+		name = "Spatial Luma Filter Type";
+		break;
+	case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE:
+		name = "Spatial Chroma Filter Type";
+		break;
+	case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE:
+		name = "Temporal Filter Mode";
+		break;
+	case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER:
+		name = "Temporal Filter";
+		break;
+	case V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE:
+		name = "Median Filter Type";
+		break;
+	case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_TOP:
+		name = "Median Luma Filter Maximum";
+		break;
+	case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_BOTTOM:
+		name = "Median Luma Filter Minimum";
+		break;
+	case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_TOP:
+		name = "Median Chroma Filter Maximum";
+		break;
+	case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_BOTTOM:
+		name = "Median Chroma Filter Minimum";
+		break;
+
+	default:
+		return v4l2_ctrl_query_fill(qctrl, min, max, step, def);
+	}
+	switch (qctrl->id) {
+	case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE:
+	case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE:
+	case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE:
+	case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE:
+	case V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE:
+		qctrl->type = V4L2_CTRL_TYPE_MENU;
+		min = 0;
+		step = 1;
+		break;
+	default:
+		qctrl->type = V4L2_CTRL_TYPE_INTEGER;
+		break;
+	}
+	switch (qctrl->id) {
+	case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE:
+	case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE:
+	case V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE:
+		qctrl->flags |= V4L2_CTRL_FLAG_UPDATE;
+		break;
+	}
+	qctrl->minimum = min;
+	qctrl->maximum = max;
+	qctrl->step = step;
+	qctrl->default_value = def;
+	qctrl->reserved[0] = qctrl->reserved[1] = 0;
+	snprintf(qctrl->name, sizeof(qctrl->name), name);
+	return 0;
+}
+
+int cx2341x_ctrl_query(struct cx2341x_mpeg_params *params, struct v4l2_queryctrl *qctrl)
+{
+	int err;
+
+	switch (qctrl->id) {
+	case V4L2_CID_MPEG_AUDIO_ENCODING:
+		return v4l2_ctrl_query_fill(qctrl,
+				V4L2_MPEG_AUDIO_ENCODING_LAYER_2,
+				V4L2_MPEG_AUDIO_ENCODING_LAYER_2, 1,
+				V4L2_MPEG_AUDIO_ENCODING_LAYER_2);
+
+	case V4L2_CID_MPEG_AUDIO_L2_BITRATE:
+		return v4l2_ctrl_query_fill(qctrl,
+				V4L2_MPEG_AUDIO_L2_BITRATE_192K,
+				V4L2_MPEG_AUDIO_L2_BITRATE_384K, 1,
+				V4L2_MPEG_AUDIO_L2_BITRATE_224K);
+
+	case V4L2_CID_MPEG_AUDIO_L1_BITRATE:
+	case V4L2_CID_MPEG_AUDIO_L3_BITRATE:
+		return -EINVAL;
+
+	case V4L2_CID_MPEG_AUDIO_MODE_EXTENSION:
+		err = v4l2_ctrl_query_fill_std(qctrl);
+		if (err == 0 && params->audio_mode != V4L2_MPEG_AUDIO_MODE_JOINT_STEREO)
+			qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
+		return err;
+
+	case V4L2_CID_MPEG_VIDEO_ENCODING:
+		/* this setting is read-only for the cx2341x since the
+		   V4L2_CID_MPEG_STREAM_TYPE really determines the
+		   MPEG-1/2 setting */
+		err = v4l2_ctrl_query_fill_std(qctrl);
+		if (err == 0)
+			qctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY;
+		return err;
+
+	case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
+		err = v4l2_ctrl_query_fill_std(qctrl);
+		if (err == 0 && params->video_encoding == V4L2_MPEG_VIDEO_ENCODING_MPEG_1)
+			qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
+		return err;
+
+	case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK:
+		err = v4l2_ctrl_query_fill_std(qctrl);
+		if (err == 0 && params->video_bitrate_mode == V4L2_MPEG_VIDEO_BITRATE_MODE_CBR)
+			qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
+		return err;
+
+	case V4L2_CID_MPEG_STREAM_VBI_FMT:
+		if (params->capabilities & CX2341X_CAP_HAS_SLICED_VBI)
+			return v4l2_ctrl_query_fill_std(qctrl);
+		return cx2341x_ctrl_query_fill(qctrl,
+				V4L2_MPEG_STREAM_VBI_FMT_NONE,
+				V4L2_MPEG_STREAM_VBI_FMT_NONE, 1,
+				V4L2_MPEG_STREAM_VBI_FMT_NONE);
+
+	/* CX23415/6 specific */
+	case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE:
+		return cx2341x_ctrl_query_fill(qctrl,
+				V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_MANUAL,
+				V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_AUTO, 1,
+				V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_MANUAL);
+
+	case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER:
+		cx2341x_ctrl_query_fill(qctrl, 0, 15, 1, 0);
+		qctrl->flags |= V4L2_CTRL_FLAG_SLIDER;
+		if (params->video_spatial_filter_mode == V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_AUTO)
+		       qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
+		return 0;
+
+	case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE:
+		cx2341x_ctrl_query_fill(qctrl,
+				V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_OFF,
+				V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_2D_SYM_NON_SEPARABLE, 1,
+				V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_OFF);
+		if (params->video_spatial_filter_mode == V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_AUTO)
+		       qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
+		return 0;
+
+	case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE:
+		cx2341x_ctrl_query_fill(qctrl,
+				V4L2_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE_OFF,
+				V4L2_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE_1D_HOR, 1,
+				V4L2_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE_OFF);
+		if (params->video_spatial_filter_mode == V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_AUTO)
+		       qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
+		return 0;
+
+	case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE:
+		return cx2341x_ctrl_query_fill(qctrl,
+				V4L2_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE_MANUAL,
+				V4L2_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE_AUTO, 1,
+				V4L2_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE_MANUAL);
+
+	case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER:
+		cx2341x_ctrl_query_fill(qctrl, 0, 31, 1, 0);
+		qctrl->flags |= V4L2_CTRL_FLAG_SLIDER;
+		if (params->video_temporal_filter_mode == V4L2_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE_AUTO)
+		       qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
+		return 0;
+
+	case V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE:
+		return cx2341x_ctrl_query_fill(qctrl,
+				V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF,
+				V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_DIAG, 1,
+				V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF);
+
+	case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_TOP:
+		cx2341x_ctrl_query_fill(qctrl, 0, 255, 1, 255);
+		qctrl->flags |= V4L2_CTRL_FLAG_SLIDER;
+		if (params->video_median_filter_type == V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF)
+		       qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
+		return 0;
+
+	case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_BOTTOM:
+		cx2341x_ctrl_query_fill(qctrl, 0, 255, 1, 0);
+		qctrl->flags |= V4L2_CTRL_FLAG_SLIDER;
+		if (params->video_median_filter_type == V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF)
+		       qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
+		return 0;
+
+	case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_TOP:
+		cx2341x_ctrl_query_fill(qctrl, 0, 255, 1, 255);
+		qctrl->flags |= V4L2_CTRL_FLAG_SLIDER;
+		if (params->video_median_filter_type == V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF)
+		       qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
+		return 0;
+
+	case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_BOTTOM:
+		cx2341x_ctrl_query_fill(qctrl, 0, 255, 1, 0);
+		qctrl->flags |= V4L2_CTRL_FLAG_SLIDER;
+		if (params->video_median_filter_type == V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF)
+		       qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
+		return 0;
+
+	default:
+		return v4l2_ctrl_query_fill_std(qctrl);
+
+	}
+}
+
+const char **cx2341x_ctrl_get_menu(u32 id)
+{
+	static const char *mpeg_stream_type[] = {
+		"MPEG-2 Program Stream",
+		"",
+		"MPEG-1 System Stream",
+		"MPEG-2 DVD-compatible Stream",
+		"MPEG-1 VCD-compatible Stream",
+		"MPEG-2 SVCD-compatible Stream",
+		NULL
+	};
+
+	static const char *cx2341x_video_spatial_filter_mode_menu[] = {
+		"Manual",
+		"Auto",
+		NULL
+	};
+
+	static const char *cx2341x_video_luma_spatial_filter_type_menu[] = {
+		"Off",
+		"1D Horizontal",
+		"1D Vertical",
+		"2D H/V Separable",
+		"2D Symmetric non-separable",
+		NULL
+	};
+
+	static const char *cx2341x_video_chroma_spatial_filter_type_menu[] = {
+		"Off",
+		"1D Horizontal",
+		NULL
+	};
+
+	static const char *cx2341x_video_temporal_filter_mode_menu[] = {
+		"Manual",
+		"Auto",
+		NULL
+	};
+
+	static const char *cx2341x_video_median_filter_type_menu[] = {
+		"Off",
+		"Horizontal",
+		"Vertical",
+		"Horizontal/Vertical",
+		"Diagonal",
+		NULL
+	};
+
+	switch (id) {
+	case V4L2_CID_MPEG_STREAM_TYPE:
+		return mpeg_stream_type;
+	case V4L2_CID_MPEG_AUDIO_L1_BITRATE:
+	case V4L2_CID_MPEG_AUDIO_L3_BITRATE:
+		return NULL;
+	case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE:
+		return cx2341x_video_spatial_filter_mode_menu;
+	case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE:
+		return cx2341x_video_luma_spatial_filter_type_menu;
+	case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE:
+		return cx2341x_video_chroma_spatial_filter_type_menu;
+	case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE:
+		return cx2341x_video_temporal_filter_mode_menu;
+	case V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE:
+		return cx2341x_video_median_filter_type_menu;
+	default:
+		return v4l2_ctrl_get_menu(id);
+	}
+}
+
+static void cx2341x_calc_audio_properties(struct cx2341x_mpeg_params *params)
+{
+	params->audio_properties = (params->audio_sampling_freq << 0) |
+		((3 - params->audio_encoding) << 2) |
+		((1 + params->audio_l2_bitrate) << 4) |
+		(params->audio_mode << 8) |
+		(params->audio_mode_extension << 10) |
+		(((params->audio_emphasis == V4L2_MPEG_AUDIO_EMPHASIS_CCITT_J17) ?
+		  3 :
+		  params->audio_emphasis) << 12) |
+		(params->audio_crc << 14);
+}
+
+int cx2341x_ext_ctrls(struct cx2341x_mpeg_params *params,
+		  struct v4l2_ext_controls *ctrls, unsigned int cmd)
+{
+	int err = 0;
+	int i;
+
+	if (cmd == VIDIOC_G_EXT_CTRLS) {
+		for (i = 0; i < ctrls->count; i++) {
+			struct v4l2_ext_control *ctrl = ctrls->controls + i;
+
+			err = cx2341x_get_ctrl(params, ctrl);
+			if (err) {
+				ctrls->error_idx = i;
+				break;
+			}
+		}
+		return err;
+	}
+	for (i = 0; i < ctrls->count; i++) {
+		struct v4l2_ext_control *ctrl = ctrls->controls + i;
+		struct v4l2_queryctrl qctrl;
+		const char **menu_items = NULL;
+
+		qctrl.id = ctrl->id;
+		err = cx2341x_ctrl_query(params, &qctrl);
+		if (err)
+			break;
+		if (qctrl.type == V4L2_CTRL_TYPE_MENU)
+			menu_items = cx2341x_ctrl_get_menu(qctrl.id);
+		err = v4l2_ctrl_check(ctrl, &qctrl, menu_items);
+		if (err)
+			break;
+		err = cx2341x_set_ctrl(params, ctrl);
+		if (err)
+			break;
+	}
+	if (err == 0 && params->video_bitrate_mode == V4L2_MPEG_VIDEO_BITRATE_MODE_VBR &&
+			params->video_bitrate_peak < params->video_bitrate) {
+		err = -ERANGE;
+		ctrls->error_idx = ctrls->count;
+	}
+	if (err) {
+		ctrls->error_idx = i;
+	}
+	else {
+		cx2341x_calc_audio_properties(params);
+	}
+	return err;
+}
+
+void cx2341x_fill_defaults(struct cx2341x_mpeg_params *p)
+{
+	static struct cx2341x_mpeg_params default_params = {
+	/* misc */
+	.capabilities = 0,
+	.port = CX2341X_PORT_MEMORY,
+	.width = 720,
+	.height = 480,
+	.is_50hz = 0,
+
+	/* stream */
+	.stream_type = V4L2_MPEG_STREAM_TYPE_MPEG2_PS,
+	.stream_vbi_fmt = V4L2_MPEG_STREAM_VBI_FMT_NONE,
+
+	/* audio */
+	.audio_sampling_freq = V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000,
+	.audio_encoding = V4L2_MPEG_AUDIO_ENCODING_LAYER_2,
+	.audio_l2_bitrate = V4L2_MPEG_AUDIO_L2_BITRATE_224K,
+	.audio_mode = V4L2_MPEG_AUDIO_MODE_STEREO,
+	.audio_mode_extension = V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_4,
+	.audio_emphasis = V4L2_MPEG_AUDIO_EMPHASIS_NONE,
+	.audio_crc = V4L2_MPEG_AUDIO_CRC_NONE,
+
+	/* video */
+	.video_encoding = V4L2_MPEG_VIDEO_ENCODING_MPEG_2,
+	.video_aspect = V4L2_MPEG_VIDEO_ASPECT_4x3,
+	.video_b_frames = 2,
+	.video_gop_size = 12,
+	.video_gop_closure = 1,
+	.video_pulldown = 0,
+	.video_bitrate_mode = V4L2_MPEG_VIDEO_BITRATE_MODE_VBR,
+	.video_bitrate = 6000000,
+	.video_bitrate_peak = 8000000,
+	.video_temporal_decimation = 0,
+
+	/* encoding filters */
+	.video_spatial_filter_mode = V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_MANUAL,
+	.video_spatial_filter = 0,
+	.video_luma_spatial_filter_type = V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_1D_HOR,
+	.video_chroma_spatial_filter_type = V4L2_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE_1D_HOR,
+	.video_temporal_filter_mode = V4L2_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE_MANUAL,
+	.video_temporal_filter = 0,
+	.video_median_filter_type = V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF,
+	.video_luma_median_filter_top = 255,
+	.video_luma_median_filter_bottom = 0,
+	.video_chroma_median_filter_top = 255,
+	.video_chroma_median_filter_bottom = 0,
+	};
+
+	*p = default_params;
+	cx2341x_calc_audio_properties(p);
+}
+
+static int cx2341x_api(void *priv, cx2341x_mbox_func func, int cmd, int args, ...)
+{
+	u32 data[CX2341X_MBOX_MAX_DATA];
+	va_list vargs;
+	int i;
+
+	va_start(vargs, args);
+
+	for (i = 0; i < args; i++) {
+		data[i] = va_arg(vargs, int);
+	}
+	va_end(vargs);
+	return func(priv, cmd, args, 0, data);
+}
+
+int cx2341x_update(void *priv, cx2341x_mbox_func func,
+		const struct cx2341x_mpeg_params *old, const struct cx2341x_mpeg_params *new)
+{
+	static int mpeg_stream_type[] = {
+		0,	/* MPEG-2 PS */
+		1,	/* MPEG-2 TS */
+		2,	/* MPEG-1 SS */
+		14,	/* DVD */
+		11,	/* VCD */
+		12,	/* SVCD */
+	};
+
+	int err = 0;
+
+	cx2341x_api(priv, func, CX2341X_ENC_SET_OUTPUT_PORT, 2, new->port, 0);
+
+	if (old == NULL || old->is_50hz != new->is_50hz) {
+		err = cx2341x_api(priv, func, CX2341X_ENC_SET_FRAME_RATE, 1, new->is_50hz);
+		if (err) return err;
+	}
+
+	if (old == NULL || old->width != new->width || old->height != new->height ||
+			old->video_encoding != new->video_encoding) {
+		u16 w = new->width;
+		u16 h = new->height;
+
+		if (new->video_encoding == V4L2_MPEG_VIDEO_ENCODING_MPEG_1) {
+			w /= 2;
+			h /= 2;
+		}
+		err = cx2341x_api(priv, func, CX2341X_ENC_SET_FRAME_SIZE, 2, h, w);
+		if (err) return err;
+	}
+
+	if (old == NULL || old->stream_type != new->stream_type) {
+		err = cx2341x_api(priv, func, CX2341X_ENC_SET_STREAM_TYPE, 1, mpeg_stream_type[new->stream_type]);
+		if (err) return err;
+	}
+	if (old == NULL || old->video_aspect != new->video_aspect) {
+		err = cx2341x_api(priv, func, CX2341X_ENC_SET_ASPECT_RATIO, 1, 1 + new->video_aspect);
+		if (err) return err;
+	}
+	if (old == NULL || old->video_b_frames != new->video_b_frames ||
+		old->video_gop_size != new->video_gop_size) {
+		err = cx2341x_api(priv, func, CX2341X_ENC_SET_GOP_PROPERTIES, 2,
+				new->video_gop_size, new->video_b_frames + 1);
+		if (err) return err;
+	}
+	if (old == NULL || old->video_gop_closure != new->video_gop_closure) {
+		err = cx2341x_api(priv, func, CX2341X_ENC_SET_GOP_CLOSURE, 1, new->video_gop_closure);
+		if (err) return err;
+	}
+	if (old == NULL || old->video_pulldown != new->video_pulldown) {
+		err = cx2341x_api(priv, func, CX2341X_ENC_SET_3_2_PULLDOWN, 1, new->video_pulldown);
+		if (err) return err;
+	}
+	if (old == NULL || old->audio_properties != new->audio_properties) {
+		err = cx2341x_api(priv, func, CX2341X_ENC_SET_AUDIO_PROPERTIES, 1, new->audio_properties);
+		if (err) return err;
+	}
+	if (old == NULL || old->video_bitrate_mode != new->video_bitrate_mode ||
+		old->video_bitrate != new->video_bitrate ||
+		old->video_bitrate_peak != new->video_bitrate_peak) {
+		err = cx2341x_api(priv, func, CX2341X_ENC_SET_BIT_RATE, 5,
+				new->video_bitrate_mode, new->video_bitrate,
+				new->video_bitrate_peak / 400, 0, 0);
+		if (err) return err;
+	}
+	if (old == NULL || old->video_spatial_filter_mode != new->video_spatial_filter_mode ||
+		old->video_temporal_filter_mode != new->video_temporal_filter_mode ||
+		old->video_median_filter_type != new->video_median_filter_type) {
+		err = cx2341x_api(priv, func, CX2341X_ENC_SET_DNR_FILTER_MODE, 2,
+				new->video_spatial_filter_mode | (new->video_temporal_filter_mode << 1),
+				new->video_median_filter_type);
+		if (err) return err;
+	}
+	if (old == NULL ||
+		old->video_luma_median_filter_bottom != new->video_luma_median_filter_bottom ||
+		old->video_luma_median_filter_top != new->video_luma_median_filter_top ||
+		old->video_chroma_median_filter_bottom != new->video_chroma_median_filter_bottom ||
+		old->video_chroma_median_filter_top != new->video_chroma_median_filter_top) {
+		err = cx2341x_api(priv, func, CX2341X_ENC_SET_CORING_LEVELS, 4,
+				new->video_luma_median_filter_bottom,
+				new->video_luma_median_filter_top,
+				new->video_chroma_median_filter_bottom,
+				new->video_chroma_median_filter_top);
+		if (err) return err;
+	}
+	if (old == NULL ||
+		old->video_luma_spatial_filter_type != new->video_luma_spatial_filter_type ||
+		old->video_chroma_spatial_filter_type != new->video_chroma_spatial_filter_type) {
+		err = cx2341x_api(priv, func, CX2341X_ENC_SET_SPATIAL_FILTER_TYPE, 2,
+			new->video_luma_spatial_filter_type, new->video_chroma_spatial_filter_type);
+		if (err) return err;
+	}
+	if (old == NULL ||
+		old->video_spatial_filter != new->video_spatial_filter ||
+		old->video_temporal_filter != new->video_temporal_filter) {
+		err = cx2341x_api(priv, func, CX2341X_ENC_SET_DNR_FILTER_PROPS, 2,
+			new->video_spatial_filter, new->video_temporal_filter);
+		if (err) return err;
+	}
+	if (old == NULL || old->video_temporal_decimation != new->video_temporal_decimation) {
+		err = cx2341x_api(priv, func, CX2341X_ENC_SET_FRAME_DROP_RATE, 1,
+			new->video_temporal_decimation);
+		if (err) return err;
+	}
+	return 0;
+}
+
+static const char *cx2341x_menu_item(struct cx2341x_mpeg_params *p, u32 id)
+{
+	const char **menu = cx2341x_ctrl_get_menu(id);
+	struct v4l2_ext_control ctrl;
+
+	if (menu == NULL)
+		goto invalid;
+	ctrl.id = id;
+	if (cx2341x_get_ctrl(p, &ctrl))
+		goto invalid;
+	while (ctrl.value-- && *menu) menu++;
+	if (*menu == NULL)
+		goto invalid;
+	return *menu;
+
+invalid:
+	return "<invalid>";
+}
+
+void cx2341x_log_status(struct cx2341x_mpeg_params *p, const char *prefix)
+{
+	int is_mpeg1 = p->video_encoding == V4L2_MPEG_VIDEO_ENCODING_MPEG_1;
+
+	/* Stream */
+	printk(KERN_INFO "%s: Stream: %s\n",
+		prefix,
+		cx2341x_menu_item(p, V4L2_CID_MPEG_STREAM_TYPE));
+
+	/* Video */
+	printk(KERN_INFO "%s: Video:  %dx%d, %d fps\n",
+		prefix,
+		p->width / (is_mpeg1 ? 2 : 1), p->height / (is_mpeg1 ? 2 : 1),
+		p->is_50hz ? 25 : 30);
+	printk(KERN_INFO "%s: Video:  %s, %s, %s, %d",
+		prefix,
+		cx2341x_menu_item(p, V4L2_CID_MPEG_VIDEO_ENCODING),
+		cx2341x_menu_item(p, V4L2_CID_MPEG_VIDEO_ASPECT),
+		cx2341x_menu_item(p, V4L2_CID_MPEG_VIDEO_BITRATE_MODE),
+		p->video_bitrate);
+	if (p->video_bitrate_mode == V4L2_MPEG_VIDEO_BITRATE_MODE_VBR) {
+		printk(", Peak %d", p->video_bitrate_peak);
+	}
+	printk("\n");
+	printk(KERN_INFO "%s: Video:  GOP Size %d, %d B-Frames, %sGOP Closure, %s3:2 Pulldown\n",
+		prefix,
+		p->video_gop_size, p->video_b_frames,
+		p->video_gop_closure ? "" : "No ",
+		p->video_pulldown ? "" : "No ");
+	if (p->video_temporal_decimation) {
+		printk(KERN_INFO "%s: Video: Temporal Decimation %d\n",
+			prefix, p->video_temporal_decimation);
+	}
+
+	/* Audio */
+	printk(KERN_INFO "%s: Audio:  %s, %s, %s, %s",
+		prefix,
+		cx2341x_menu_item(p, V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ),
+		cx2341x_menu_item(p, V4L2_CID_MPEG_AUDIO_ENCODING),
+		cx2341x_menu_item(p, V4L2_CID_MPEG_AUDIO_L2_BITRATE),
+		cx2341x_menu_item(p, V4L2_CID_MPEG_AUDIO_MODE));
+	if (p->audio_mode == V4L2_MPEG_AUDIO_MODE_JOINT_STEREO) {
+		printk(", %s",
+			cx2341x_menu_item(p, V4L2_CID_MPEG_AUDIO_MODE_EXTENSION));
+	}
+	printk(", %s, %s\n",
+		cx2341x_menu_item(p, V4L2_CID_MPEG_AUDIO_EMPHASIS),
+		cx2341x_menu_item(p, V4L2_CID_MPEG_AUDIO_CRC));
+
+	/* Encoding filters */
+	printk(KERN_INFO "%s: Spatial Filter:  %s, Luma %s, Chroma %s, %d\n",
+		prefix,
+		cx2341x_menu_item(p, V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE),
+		cx2341x_menu_item(p, V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE),
+		cx2341x_menu_item(p, V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE),
+		p->video_spatial_filter);
+	printk(KERN_INFO "%s: Temporal Filter: %s, %d\n",
+		prefix,
+		cx2341x_menu_item(p, V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE),
+		p->video_temporal_filter);
+	printk(KERN_INFO "%s: Median Filter:   %s, Luma [%d, %d], Chroma [%d, %d]\n",
+		prefix,
+		cx2341x_menu_item(p, V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE),
+		p->video_luma_median_filter_bottom,
+		p->video_luma_median_filter_top,
+		p->video_chroma_median_filter_bottom,
+		p->video_chroma_median_filter_top);
+}
+
+EXPORT_SYMBOL(cx2341x_fill_defaults);
+EXPORT_SYMBOL(cx2341x_ctrl_query);
+EXPORT_SYMBOL(cx2341x_ctrl_get_menu);
+EXPORT_SYMBOL(cx2341x_ext_ctrls);
+EXPORT_SYMBOL(cx2341x_update);
+EXPORT_SYMBOL(cx2341x_log_status);
+EXPORT_SYMBOL(cx2341x_mpeg_ctrls);
+
+/*
+ * Local variables:
+ * c-basic-offset: 8
+ * End:
+ */
+
diff --git a/drivers/media/video/ks0127.c b/drivers/media/video/ks0127.c
new file mode 100644
index 000000000..3bf7ac4f5
--- /dev/null
+++ b/drivers/media/video/ks0127.c
@@ -0,0 +1,846 @@
+/*
+ * Video Capture Driver (Video for Linux 1/2)
+ * for the Matrox Marvel G200,G400 and Rainbow Runner-G series
+ *
+ * This module is an interface to the KS0127 video decoder chip.
+ *
+ * Copyright (C) 1999  Ryan Drake <stiletto@mediaone.net>
+ *
+ * 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.
+ *
+ *****************************************************************************
+ *
+ * Modified and extended by
+ *	Mike Bernson <mike@mlb.org>
+ *	Gerard v.d. Horst
+ *	Leon van Stuivenberg <l.vanstuivenberg@chello.nl>
+ *	Gernot Ziegler <gz@lysator.liu.se>
+ *
+ * Version History:
+ * V1.0 Ryan Drake	   Initial version by Ryan Drake
+ * V1.1 Gerard v.d. Horst  Added some debugoutput, reset the video-standard
+ */
+
+#ifndef __KERNEL__
+#define __KERNEL__
+#endif
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/proc_fs.h>
+#include "ks0127.h"
+
+#include <linux/i2c.h>
+#include <linux/video_decoder.h>
+
+#define dprintk     if (debug) printk
+
+/* i2c identification */
+#define I2C_KS0127_ADDON   0xD8
+#define I2C_KS0127_ONBOARD 0xDA
+
+#define KS_TYPE_UNKNOWN	0
+#define KS_TYPE_0122S	1
+#define KS_TYPE_0127	2
+#define KS_TYPE_0127B	3
+
+/* ks0127 control registers */
+#define KS_STAT     0x00
+#define KS_CMDA     0x01
+#define KS_CMDB     0x02
+#define KS_CMDC     0x03
+#define KS_CMDD     0x04
+#define KS_HAVB     0x05
+#define KS_HAVE     0x06
+#define KS_HS1B     0x07
+#define KS_HS1E     0x08
+#define KS_HS2B     0x09
+#define KS_HS2E     0x0a
+#define KS_AGC      0x0b
+#define KS_HXTRA    0x0c
+#define KS_CDEM     0x0d
+#define KS_PORTAB   0x0e
+#define KS_LUMA     0x0f
+#define KS_CON      0x10
+#define KS_BRT      0x11
+#define KS_CHROMA   0x12
+#define KS_CHROMB   0x13
+#define KS_DEMOD    0x14
+#define KS_SAT      0x15
+#define KS_HUE      0x16
+#define KS_VERTIA   0x17
+#define KS_VERTIB   0x18
+#define KS_VERTIC   0x19
+#define KS_HSCLL    0x1a
+#define KS_HSCLH    0x1b
+#define KS_VSCLL    0x1c
+#define KS_VSCLH    0x1d
+#define KS_OFMTA    0x1e
+#define KS_OFMTB    0x1f
+#define KS_VBICTL   0x20
+#define KS_CCDAT2   0x21
+#define KS_CCDAT1   0x22
+#define KS_VBIL30   0x23
+#define KS_VBIL74   0x24
+#define KS_VBIL118  0x25
+#define KS_VBIL1512 0x26
+#define KS_TTFRAM   0x27
+#define KS_TESTA    0x28
+#define KS_UVOFFH   0x29
+#define KS_UVOFFL   0x2a
+#define KS_UGAIN    0x2b
+#define KS_VGAIN    0x2c
+#define KS_VAVB     0x2d
+#define KS_VAVE     0x2e
+#define KS_CTRACK   0x2f
+#define KS_POLCTL   0x30
+#define KS_REFCOD   0x31
+#define KS_INVALY   0x32
+#define KS_INVALU   0x33
+#define KS_INVALV   0x34
+#define KS_UNUSEY   0x35
+#define KS_UNUSEU   0x36
+#define KS_UNUSEV   0x37
+#define KS_USRSAV   0x38
+#define KS_USREAV   0x39
+#define KS_SHS1A    0x3a
+#define KS_SHS1B    0x3b
+#define KS_SHS1C    0x3c
+#define KS_CMDE     0x3d
+#define KS_VSDEL    0x3e
+#define KS_CMDF     0x3f
+#define KS_GAMMA0   0x40
+#define KS_GAMMA1   0x41
+#define KS_GAMMA2   0x42
+#define KS_GAMMA3   0x43
+#define KS_GAMMA4   0x44
+#define KS_GAMMA5   0x45
+#define KS_GAMMA6   0x46
+#define KS_GAMMA7   0x47
+#define KS_GAMMA8   0x48
+#define KS_GAMMA9   0x49
+#define KS_GAMMA10  0x4a
+#define KS_GAMMA11  0x4b
+#define KS_GAMMA12  0x4c
+#define KS_GAMMA13  0x4d
+#define KS_GAMMA14  0x4e
+#define KS_GAMMA15  0x4f
+#define KS_GAMMA16  0x50
+#define KS_GAMMA17  0x51
+#define KS_GAMMA18  0x52
+#define KS_GAMMA19  0x53
+#define KS_GAMMA20  0x54
+#define KS_GAMMA21  0x55
+#define KS_GAMMA22  0x56
+#define KS_GAMMA23  0x57
+#define KS_GAMMA24  0x58
+#define KS_GAMMA25  0x59
+#define KS_GAMMA26  0x5a
+#define KS_GAMMA27  0x5b
+#define KS_GAMMA28  0x5c
+#define KS_GAMMA29  0x5d
+#define KS_GAMMA30  0x5e
+#define KS_GAMMA31  0x5f
+#define KS_GAMMAD0  0x60
+#define KS_GAMMAD1  0x61
+#define KS_GAMMAD2  0x62
+#define KS_GAMMAD3  0x63
+#define KS_GAMMAD4  0x64
+#define KS_GAMMAD5  0x65
+#define KS_GAMMAD6  0x66
+#define KS_GAMMAD7  0x67
+#define KS_GAMMAD8  0x68
+#define KS_GAMMAD9  0x69
+#define KS_GAMMAD10 0x6a
+#define KS_GAMMAD11 0x6b
+#define KS_GAMMAD12 0x6c
+#define KS_GAMMAD13 0x6d
+#define KS_GAMMAD14 0x6e
+#define KS_GAMMAD15 0x6f
+#define KS_GAMMAD16 0x70
+#define KS_GAMMAD17 0x71
+#define KS_GAMMAD18 0x72
+#define KS_GAMMAD19 0x73
+#define KS_GAMMAD20 0x74
+#define KS_GAMMAD21 0x75
+#define KS_GAMMAD22 0x76
+#define KS_GAMMAD23 0x77
+#define KS_GAMMAD24 0x78
+#define KS_GAMMAD25 0x79
+#define KS_GAMMAD26 0x7a
+#define KS_GAMMAD27 0x7b
+#define KS_GAMMAD28 0x7c
+#define KS_GAMMAD29 0x7d
+#define KS_GAMMAD30 0x7e
+#define KS_GAMMAD31 0x7f
+
+
+/****************************************************************************
+* mga_dev : represents one ks0127 chip.
+****************************************************************************/
+
+struct adjust {
+	int	contrast;
+	int	bright;
+	int	hue;
+	int	ugain;
+	int	vgain;
+};
+
+struct ks0127 {
+	struct i2c_client *client;
+	unsigned char	addr;
+	int		format_width;
+	int		format_height;
+	int		cap_width;
+	int		cap_height;
+	int		norm;
+	int		ks_type;
+	u8 		regs[256];
+};
+
+
+static int debug; /* insmod parameter */
+
+module_param(debug, int, 0);
+MODULE_PARM_DESC(debug, "Debug output");
+MODULE_LICENSE("GPL");
+
+static u8 reg_defaults[64];
+
+
+
+static void init_reg_defaults(void)
+{
+	u8 *table = reg_defaults;
+
+	table[KS_CMDA]     = 0x2c;  /* VSE=0, CCIR 601, autodetect standard */
+	table[KS_CMDB]     = 0x12;  /* VALIGN=0, AGC control and input */
+	table[KS_CMDC]     = 0x00;  /* Test options */
+	/* clock & input select, write 1 to PORTA */
+	table[KS_CMDD]     = 0x01;
+	table[KS_HAVB]     = 0x00;  /* HAV Start Control */
+	table[KS_HAVE]     = 0x00;  /* HAV End Control */
+	table[KS_HS1B]     = 0x10;  /* HS1 Start Control */
+	table[KS_HS1E]     = 0x00;  /* HS1 End Control */
+	table[KS_HS2B]     = 0x00;  /* HS2 Start Control */
+	table[KS_HS2E]     = 0x00;  /* HS2 End Control */
+	table[KS_AGC]      = 0x53;  /* Manual setting for AGC */
+	table[KS_HXTRA]    = 0x00;  /* Extra Bits for HAV and HS1/2 */
+	table[KS_CDEM]     = 0x00;  /* Chroma Demodulation Control */
+	table[KS_PORTAB]   = 0x0f;  /* port B is input, port A output GPPORT */
+	table[KS_LUMA]     = 0x01;  /* Luma control */
+	table[KS_CON]      = 0x00;  /* Contrast Control */
+	table[KS_BRT]      = 0x00;  /* Brightness Control */
+	table[KS_CHROMA]   = 0x2a;  /* Chroma control A */
+	table[KS_CHROMB]   = 0x90;  /* Chroma control B */
+	table[KS_DEMOD]    = 0x00;  /* Chroma Demodulation Control & Status */
+	table[KS_SAT]      = 0x00;  /* Color Saturation Control*/
+	table[KS_HUE]      = 0x00;  /* Hue Control */
+	table[KS_VERTIA]   = 0x00;  /* Vertical Processing Control A */
+	/* Vertical Processing Control B, luma 1 line delayed */
+	table[KS_VERTIB]   = 0x12;
+	table[KS_VERTIC]   = 0x0b;  /* Vertical Processing Control C */
+	table[KS_HSCLL]    = 0x00;  /* Horizontal Scaling Ratio Low */
+	table[KS_HSCLH]    = 0x00;  /* Horizontal Scaling Ratio High */
+	table[KS_VSCLL]    = 0x00;  /* Vertical Scaling Ratio Low */
+	table[KS_VSCLH]    = 0x00;  /* Vertical Scaling Ratio High */
+	/* 16 bit YCbCr 4:2:2 output; I can't make the bt866 like 8 bit /Sam */
+	table[KS_OFMTA]    = 0x30;
+	table[KS_OFMTB]    = 0x00;  /* Output Control B */
+	/* VBI Decoder Control; 4bit fmt: avoid Y overflow */
+	table[KS_VBICTL]   = 0x5d;
+	table[KS_CCDAT2]   = 0x00;  /* Read Only register */
+	table[KS_CCDAT1]   = 0x00;  /* Read Only register */
+	table[KS_VBIL30]   = 0xa8;  /* VBI data decoding options */
+	table[KS_VBIL74]   = 0xaa;  /* VBI data decoding options */
+	table[KS_VBIL118]  = 0x2a;  /* VBI data decoding options */
+	table[KS_VBIL1512] = 0x00;  /* VBI data decoding options */
+	table[KS_TTFRAM]   = 0x00;  /* Teletext frame alignment pattern */
+	table[KS_TESTA]    = 0x00;  /* test register, shouldn't be written */
+	table[KS_UVOFFH]   = 0x00;  /* UV Offset Adjustment High */
+	table[KS_UVOFFL]   = 0x00;  /* UV Offset Adjustment Low */
+	table[KS_UGAIN]    = 0x00;  /* U Component Gain Adjustment */
+	table[KS_VGAIN]    = 0x00;  /* V Component Gain Adjustment */
+	table[KS_VAVB]     = 0x07;  /* VAV Begin */
+	table[KS_VAVE]     = 0x00;  /* VAV End */
+	table[KS_CTRACK]   = 0x00;  /* Chroma Tracking Control */
+	table[KS_POLCTL]   = 0x41;  /* Timing Signal Polarity Control */
+	table[KS_REFCOD]   = 0x80;  /* Reference Code Insertion Control */
+	table[KS_INVALY]   = 0x10;  /* Invalid Y Code */
+	table[KS_INVALU]   = 0x80;  /* Invalid U Code */
+	table[KS_INVALV]   = 0x80;  /* Invalid V Code */
+	table[KS_UNUSEY]   = 0x10;  /* Unused Y Code */
+	table[KS_UNUSEU]   = 0x80;  /* Unused U Code */
+	table[KS_UNUSEV]   = 0x80;  /* Unused V Code */
+	table[KS_USRSAV]   = 0x00;  /* reserved */
+	table[KS_USREAV]   = 0x00;  /* reserved */
+	table[KS_SHS1A]    = 0x00;  /* User Defined SHS1 A */
+	/* User Defined SHS1 B, ALT656=1 on 0127B */
+	table[KS_SHS1B]    = 0x80;
+	table[KS_SHS1C]    = 0x00;  /* User Defined SHS1 C */
+	table[KS_CMDE]     = 0x00;  /* Command Register E */
+	table[KS_VSDEL]    = 0x00;  /* VS Delay Control */
+	/* Command Register F, update -immediately- */
+	/* (there might come no vsync)*/
+	table[KS_CMDF]     = 0x02;
+}
+
+
+/* We need to manually read because of a bug in the KS0127 chip.
+ *
+ * An explanation from kayork@mail.utexas.edu:
+ *
+ * During I2C reads, the KS0127 only samples for a stop condition
+ * during the place where the acknoledge bit should be. Any standard
+ * I2C implementation (correctly) throws in another clock transition
+ * at the 9th bit, and the KS0127 will not recognize the stop condition
+ * and will continue to clock out data.
+ *
+ * So we have to do the read ourself.  Big deal.
+	   workaround in i2c-algo-bit
+ */
+
+
+static u8 ks0127_read(struct ks0127 *ks, u8 reg)
+{
+	struct i2c_client *c = ks->client;
+	char val = 0;
+	struct i2c_msg msgs[] = {
+		{c->addr, 0, sizeof(reg), &reg},
+		{c->addr, I2C_M_RD | I2C_M_NO_RD_ACK, sizeof(val), &val}};
+	int ret;
+
+	ret = i2c_transfer(c->adapter, msgs, ARRAY_SIZE(msgs));
+	if (ret != ARRAY_SIZE(msgs))
+		dprintk("ks0127_write error\n");
+
+	return val;
+}
+
+
+static void ks0127_write(struct ks0127 *ks, u8 reg, u8 val)
+{
+	char msg[] = {reg, val};
+
+	if (i2c_master_send(ks->client, msg, sizeof(msg)) != sizeof(msg))
+		dprintk("ks0127_write error\n");
+
+	ks->regs[reg] = val;
+}
+
+
+/* generic bit-twiddling */
+static void ks0127_and_or(struct ks0127 *ks, u8 reg, u8 and_v, u8 or_v)
+{
+	u8 val = ks->regs[reg];
+	val = (val & and_v) | or_v;
+	ks0127_write(ks, reg, val);
+}
+
+
+
+/****************************************************************************
+* ks0127 private api
+****************************************************************************/
+static void ks0127_reset(struct ks0127* ks)
+{
+	int i;
+	u8 *table = reg_defaults;
+
+	ks->ks_type = KS_TYPE_UNKNOWN;
+
+	dprintk("ks0127: reset\n");
+	msleep(1);
+
+	/* initialize all registers to known values */
+	/* (except STAT, 0x21, 0x22, TEST and 0x38,0x39) */
+
+	for(i = 1; i < 33; i++)
+		ks0127_write(ks, i, table[i]);
+
+	for(i = 35; i < 40; i++)
+		ks0127_write(ks, i, table[i]);
+
+	for(i = 41; i < 56; i++)
+		ks0127_write(ks, i, table[i]);
+
+	for(i = 58; i < 64; i++)
+		ks0127_write(ks, i, table[i]);
+
+
+	if ((ks0127_read(ks, KS_STAT) & 0x80) == 0) {
+		ks->ks_type = KS_TYPE_0122S;
+		dprintk("ks0127: ks0122s Found\n");
+		return;
+	}
+
+	switch(ks0127_read(ks, KS_CMDE) & 0x0f) {
+
+	case 0:
+		ks->ks_type = KS_TYPE_0127;
+		dprintk("ks0127: ks0127 found\n");
+		break;
+
+	case 9:
+		ks->ks_type = KS_TYPE_0127B;
+		dprintk("ks0127: ks0127B Revision A found\n");
+		break;
+
+	default:
+		dprintk("ks0127: unknown revision\n");
+		break;
+	}
+}
+
+static int ks0127_command(struct i2c_client *client,
+			  unsigned int cmd, void *arg)
+{
+	struct ks0127 *ks = i2c_get_clientdata(client);
+
+	int		*iarg = (int*)arg;
+
+	int		status;
+
+	if (!ks)
+		return -ENODEV;
+
+	switch (cmd) {
+
+	case DECODER_INIT:
+		dprintk("ks0127: command DECODER_INIT\n");
+		ks0127_reset(ks);
+		break;
+
+	case DECODER_SET_INPUT:
+		switch(*iarg) {
+		case KS_INPUT_COMPOSITE_1:
+		case KS_INPUT_COMPOSITE_2:
+		case KS_INPUT_COMPOSITE_3:
+		case KS_INPUT_COMPOSITE_4:
+		case KS_INPUT_COMPOSITE_5:
+		case KS_INPUT_COMPOSITE_6:
+			dprintk("ks0127: command DECODER_SET_INPUT %d: "
+				"Composite\n", *iarg);
+			/* autodetect 50/60 Hz */
+			ks0127_and_or(ks, KS_CMDA,   0xfc, 0x00);
+			/* VSE=0 */
+			ks0127_and_or(ks, KS_CMDA,   ~0x40, 0x00);
+			/* set input line */
+			ks0127_and_or(ks, KS_CMDB,   0xb0, *iarg);
+			/* non-freerunning mode */
+			ks0127_and_or(ks, KS_CMDC,   0x70, 0x0a);
+			/* analog input */
+			ks0127_and_or(ks, KS_CMDD,   0x03, 0x00);
+			/* enable chroma demodulation */
+			ks0127_and_or(ks, KS_CTRACK, 0xcf, 0x00);
+			/* chroma trap, HYBWR=1 */
+			ks0127_and_or(ks, KS_LUMA,   0x00,
+				       (reg_defaults[KS_LUMA])|0x0c);
+			/* scaler fullbw, luma comb off */
+			ks0127_and_or(ks, KS_VERTIA, 0x08, 0x81);
+			/* manual chroma comb .25 .5 .25 */
+			ks0127_and_or(ks, KS_VERTIC, 0x0f, 0x90);
+
+			/* chroma path delay */
+			ks0127_and_or(ks, KS_CHROMB, 0x0f, 0x90);
+
+			ks0127_write(ks, KS_UGAIN, reg_defaults[KS_UGAIN]);
+			ks0127_write(ks, KS_VGAIN, reg_defaults[KS_VGAIN]);
+			ks0127_write(ks, KS_UVOFFH, reg_defaults[KS_UVOFFH]);
+			ks0127_write(ks, KS_UVOFFL, reg_defaults[KS_UVOFFL]);
+			break;
+
+		case KS_INPUT_SVIDEO_1:
+		case KS_INPUT_SVIDEO_2:
+		case KS_INPUT_SVIDEO_3:
+			dprintk("ks0127: command DECODER_SET_INPUT %d: "
+				"S-Video\n", *iarg);
+			/* autodetect 50/60 Hz */
+			ks0127_and_or(ks, KS_CMDA,   0xfc, 0x00);
+			/* VSE=0 */
+			ks0127_and_or(ks, KS_CMDA,   ~0x40, 0x00);
+			/* set input line */
+			ks0127_and_or(ks, KS_CMDB,   0xb0, *iarg);
+			/* non-freerunning mode */
+			ks0127_and_or(ks, KS_CMDC,   0x70, 0x0a);
+			/* analog input */
+			ks0127_and_or(ks, KS_CMDD,   0x03, 0x00);
+			/* enable chroma demodulation */
+			ks0127_and_or(ks, KS_CTRACK, 0xcf, 0x00);
+			ks0127_and_or(ks, KS_LUMA, 0x00,
+				       reg_defaults[KS_LUMA]);
+			/* disable luma comb */
+			ks0127_and_or(ks, KS_VERTIA, 0x08,
+				       (reg_defaults[KS_VERTIA]&0xf0)|0x01);
+			ks0127_and_or(ks, KS_VERTIC, 0x0f,
+				       reg_defaults[KS_VERTIC]&0xf0);
+
+			ks0127_and_or(ks, KS_CHROMB, 0x0f,
+				       reg_defaults[KS_CHROMB]&0xf0);
+
+			ks0127_write(ks, KS_UGAIN, reg_defaults[KS_UGAIN]);
+			ks0127_write(ks, KS_VGAIN, reg_defaults[KS_VGAIN]);
+			ks0127_write(ks, KS_UVOFFH, reg_defaults[KS_UVOFFH]);
+			ks0127_write(ks, KS_UVOFFL, reg_defaults[KS_UVOFFL]);
+			break;
+
+		case KS_INPUT_YUV656:
+			dprintk("ks0127: command DECODER_SET_INPUT 15: "
+				"YUV656\n");
+			if (ks->norm == VIDEO_MODE_NTSC ||
+			    ks->norm == KS_STD_PAL_M)
+				/* force 60 Hz */
+				ks0127_and_or(ks, KS_CMDA,   0xfc, 0x03);
+			else
+				/* force 50 Hz */
+				ks0127_and_or(ks, KS_CMDA,   0xfc, 0x02);
+
+			ks0127_and_or(ks, KS_CMDA,   0xff, 0x40); /* VSE=1 */
+			/* set input line and VALIGN */
+			ks0127_and_or(ks, KS_CMDB,   0xb0, (*iarg | 0x40));
+			/* freerunning mode, */
+			/* TSTGEN = 1 TSTGFR=11 TSTGPH=0 TSTGPK=0  VMEM=1*/
+			ks0127_and_or(ks, KS_CMDC,   0x70, 0x87);
+			/* digital input, SYNDIR = 0 INPSL=01 CLKDIR=0 EAV=0 */
+			ks0127_and_or(ks, KS_CMDD,   0x03, 0x08);
+			/* disable chroma demodulation */
+			ks0127_and_or(ks, KS_CTRACK, 0xcf, 0x30);
+			/* HYPK =01 CTRAP = 0 HYBWR=0 PED=1 RGBH=1 UNIT=1 */
+			ks0127_and_or(ks, KS_LUMA,   0x00, 0x71);
+			ks0127_and_or(ks, KS_VERTIC, 0x0f,
+				       reg_defaults[KS_VERTIC]&0xf0);
+
+			/* scaler fullbw, luma comb off */
+			ks0127_and_or(ks, KS_VERTIA, 0x08, 0x81);
+
+			ks0127_and_or(ks, KS_CHROMB, 0x0f,
+				       reg_defaults[KS_CHROMB]&0xf0);
+
+			ks0127_and_or(ks, KS_CON, 0x00, 0x00);
+			ks0127_and_or(ks, KS_BRT, 0x00, 32);	/* spec: 34 */
+				/* spec: 229 (e5) */
+			ks0127_and_or(ks, KS_SAT, 0x00, 0xe8);
+			ks0127_and_or(ks, KS_HUE, 0x00, 0);
+
+			ks0127_and_or(ks, KS_UGAIN, 0x00, 238);
+			ks0127_and_or(ks, KS_VGAIN, 0x00, 0x00);
+
+			/*UOFF:0x30, VOFF:0x30, TSTCGN=1 */
+			ks0127_and_or(ks, KS_UVOFFH, 0x00, 0x4f);
+			ks0127_and_or(ks, KS_UVOFFL, 0x00, 0x00);
+			break;
+
+		default:
+			dprintk("ks0127: command DECODER_SET_INPUT: "
+				"Unknown input %d\n", *iarg);
+			break;
+		}
+
+		/* hack: CDMLPF sometimes spontaneously switches on; */
+		/* force back off */
+		ks0127_write(ks, KS_DEMOD, reg_defaults[KS_DEMOD]);
+		break;
+
+	case DECODER_SET_OUTPUT:
+		switch(*iarg) {
+		case KS_OUTPUT_YUV656E:
+			dprintk("ks0127: command DECODER_SET_OUTPUT: "
+				"OUTPUT_YUV656E (Missing)\n");
+			return -EINVAL;
+			break;
+
+		case KS_OUTPUT_EXV:
+			dprintk("ks0127: command DECODER_SET_OUTPUT: "
+				"OUTPUT_EXV\n");
+			ks0127_and_or(ks, KS_OFMTA, 0xf0, 0x09);
+			break;
+		}
+		break;
+
+	case DECODER_SET_NORM: //sam This block mixes old and new norm names...
+		/* Set to automatic SECAM/Fsc mode */
+		ks0127_and_or(ks, KS_DEMOD, 0xf0, 0x00);
+
+		ks->norm = *iarg;
+		switch(*iarg)
+		{
+		/* this is untested !! */
+		/* It just detects PAL_N/NTSC_M (no special frequencies) */
+		/* And you have to set the standard a second time afterwards */
+		case VIDEO_MODE_AUTO:
+			dprintk("ks0127: command DECODER_SET_NORM: AUTO\n");
+
+			/* The chip determines the format */
+			/* based on the current field rate */
+			ks0127_and_or(ks, KS_CMDA,   0xfc, 0x00);
+			ks0127_and_or(ks, KS_CHROMA, 0x9f, 0x20);
+			/* This is wrong for PAL ! As I said, */
+			/* you need to set the standard once again !! */
+			ks->format_height = 240;
+			ks->format_width = 704;
+			break;
+
+		case VIDEO_MODE_NTSC:
+			dprintk("ks0127: command DECODER_SET_NORM: NTSC_M\n");
+			ks0127_and_or(ks, KS_CHROMA, 0x9f, 0x20);
+			ks->format_height = 240;
+			ks->format_width = 704;
+			break;
+
+		case KS_STD_NTSC_N:
+			dprintk("ks0127: command KS0127_SET_STANDARD: "
+				"NTSC_N (fixme)\n");
+			ks0127_and_or(ks, KS_CHROMA, 0x9f, 0x40);
+			ks->format_height = 240;
+			ks->format_width = 704;
+			break;
+
+		case VIDEO_MODE_PAL:
+			dprintk("ks0127: command DECODER_SET_NORM: PAL_N\n");
+			ks0127_and_or(ks, KS_CHROMA, 0x9f, 0x20);
+			ks->format_height = 290;
+			ks->format_width = 704;
+			break;
+
+		case KS_STD_PAL_M:
+			dprintk("ks0127: command KS0127_SET_STANDARD: "
+				"PAL_M (fixme)\n");
+			ks0127_and_or(ks, KS_CHROMA, 0x9f, 0x40);
+			ks->format_height = 290;
+			ks->format_width = 704;
+			break;
+
+		case VIDEO_MODE_SECAM:
+			dprintk("ks0127: command KS0127_SET_STANDARD: "
+				"SECAM\n");
+			ks->format_height = 290;
+			ks->format_width = 704;
+
+			/* set to secam autodetection */
+			ks0127_and_or(ks, KS_CHROMA, 0xdf, 0x20);
+			ks0127_and_or(ks, KS_DEMOD, 0xf0, 0x00);
+			schedule_timeout_interruptible(HZ/10+1);
+
+			/* did it autodetect? */
+			if (ks0127_read(ks, KS_DEMOD) & 0x40)
+				break;
+
+			/* force to secam mode */
+			ks0127_and_or(ks, KS_DEMOD, 0xf0, 0x0f);
+			break;
+
+		default:
+			dprintk("ks0127: command DECODER_SET_NORM: "
+				"Unknown norm %d\n", *iarg);
+			break;
+		}
+		break;
+
+	case DECODER_SET_PICTURE:
+		dprintk("ks0127: command DECODER_SET_PICTURE "
+			"not yet supported (fixme)\n");
+		return -EINVAL;
+
+	//sam todo: KS0127_SET_BRIGHTNESS: Merge into DECODER_SET_PICTURE
+	//sam todo: KS0127_SET_CONTRAST: Merge into DECODER_SET_PICTURE
+	//sam todo: KS0127_SET_HUE: Merge into DECODER_SET_PICTURE?
+	//sam todo: KS0127_SET_SATURATION: Merge into DECODER_SET_PICTURE
+	//sam todo: KS0127_SET_AGC_MODE:
+	//sam todo: KS0127_SET_AGC:
+	//sam todo: KS0127_SET_CHROMA_MODE:
+	//sam todo: KS0127_SET_PIXCLK_MODE:
+	//sam todo: KS0127_SET_GAMMA_MODE:
+	//sam todo: KS0127_SET_UGAIN:
+	//sam todo: KS0127_SET_VGAIN:
+	//sam todo: KS0127_SET_INVALY:
+	//sam todo: KS0127_SET_INVALU:
+	//sam todo: KS0127_SET_INVALV:
+	//sam todo: KS0127_SET_UNUSEY:
+	//sam todo: KS0127_SET_UNUSEU:
+	//sam todo: KS0127_SET_UNUSEV:
+	//sam todo: KS0127_SET_VSALIGN_MODE:
+
+	case DECODER_ENABLE_OUTPUT:
+	{
+
+		int *iarg = arg;
+		int enable = (*iarg != 0);
+			if (enable) {
+				dprintk("ks0127: command "
+					"DECODER_ENABLE_OUTPUT on "
+					"(%d)\n", enable);
+				/* All output pins on */
+				ks0127_and_or(ks, KS_OFMTA, 0xcf, 0x30);
+				/* Obey the OEN pin */
+				ks0127_and_or(ks, KS_CDEM, 0x7f, 0x00);
+			} else {
+				dprintk("ks0127: command "
+					"DECODER_ENABLE_OUTPUT off "
+					"(%d)\n", enable);
+				/* Video output pins off */
+				ks0127_and_or(ks, KS_OFMTA, 0xcf, 0x00);
+				/* Ignore the OEN pin */
+				ks0127_and_or(ks, KS_CDEM, 0x7f, 0x80);
+			}
+	}
+		break;
+
+	//sam todo: KS0127_SET_OUTPUT_MODE:
+	//sam todo: KS0127_SET_WIDTH:
+	//sam todo: KS0127_SET_HEIGHT:
+	//sam todo: KS0127_SET_HSCALE:
+
+	case DECODER_GET_STATUS:
+		dprintk("ks0127: command DECODER_GET_STATUS\n");
+		*iarg = 0;
+		status = ks0127_read(ks, KS_STAT);
+		if (!(status & 0x20))		 /* NOVID not set */
+			*iarg = (*iarg & DECODER_STATUS_GOOD);
+		if ((status & 0x01))		      /* CLOCK set */
+			*iarg = (*iarg & DECODER_STATUS_COLOR);
+		if ((status & 0x08))		   /* PALDET set */
+			*iarg = (*iarg & DECODER_STATUS_PAL);
+		else
+			*iarg = (*iarg & DECODER_STATUS_NTSC);
+		break;
+
+	//Catch any unknown command
+	default:
+		dprintk("ks0127: command unknown: %04X\n", cmd);
+		return -EINVAL;
+	}
+	return 0;
+}
+
+
+
+
+static int ks0127_probe(struct i2c_adapter *adapter);
+static int ks0127_detach(struct i2c_client *client);
+static int ks0127_command(struct i2c_client *client,
+			  unsigned int cmd, void *arg);
+
+
+
+/* Addresses to scan */
+static unsigned short normal_i2c[] = {I2C_KS0127_ADDON>>1,
+				       I2C_KS0127_ONBOARD>>1, I2C_CLIENT_END};
+static unsigned short probe[2] =	{I2C_CLIENT_END, I2C_CLIENT_END};
+static unsigned short ignore[2] = 	{I2C_CLIENT_END, I2C_CLIENT_END};
+static struct i2c_client_address_data addr_data = {
+	normal_i2c,
+	probe,
+	ignore,
+};
+
+static struct i2c_driver i2c_driver_ks0127 = {
+	.driver.name = "ks0127",
+	.id             = I2C_DRIVERID_KS0127,
+	.attach_adapter = ks0127_probe,
+	.detach_client  = ks0127_detach,
+	.command        = ks0127_command
+};
+
+static struct i2c_client ks0127_client_tmpl =
+{
+	.name = "(ks0127 unset)",
+	.addr = 0,
+	.adapter = NULL,
+	.driver = &i2c_driver_ks0127,
+	.usage_count = 0
+};
+
+static int ks0127_found_proc(struct i2c_adapter *adapter, int addr, int kind)
+{
+	struct ks0127 *ks;
+	struct i2c_client *client;
+
+	client = kzalloc(sizeof(*client), GFP_KERNEL);
+	if (client == NULL)
+		return -ENOMEM;
+	memcpy(client, &ks0127_client_tmpl, sizeof(*client));
+
+	ks = kzalloc(sizeof(*ks), GFP_KERNEL);
+	if (ks == NULL) {
+		kfree(client);
+		return -ENOMEM;
+	}
+
+	i2c_set_clientdata(client, ks);
+	client->adapter = adapter;
+	client->addr = addr;
+	sprintf(client->name, "ks0127-%02x", adapter->id);
+
+	ks->client = client;
+	ks->addr = addr;
+	ks->ks_type = KS_TYPE_UNKNOWN;
+
+	/* power up */
+	ks0127_write(ks, KS_CMDA, 0x2c);
+	mdelay(10);
+
+	/* reset the device */
+	ks0127_reset(ks);
+	printk(KERN_INFO "ks0127: attach: %s video decoder\n",
+	       ks->addr==(I2C_KS0127_ADDON>>1) ? "addon" : "on-board");
+
+	i2c_attach_client(client);
+	return 0;
+}
+
+
+static int ks0127_probe(struct i2c_adapter *adapter)
+{
+	if (adapter->id == I2C_HW_B_ZR36067)
+		return i2c_probe(adapter, &addr_data, ks0127_found_proc);
+	return 0;
+}
+
+static int ks0127_detach(struct i2c_client *client)
+{
+	struct ks0127 *ks = i2c_get_clientdata(client);
+
+	ks0127_write(ks, KS_OFMTA, 0x20); /*tristate*/
+	ks0127_write(ks, KS_CMDA, 0x2c | 0x80); /* power down */
+
+	i2c_detach_client(client);
+	kfree(ks);
+	kfree(client);
+
+	dprintk("ks0127: detach\n");
+	return 0;
+}
+
+
+static int __devinit ks0127_init_module(void)
+{
+	init_reg_defaults();
+	i2c_add_driver(&i2c_driver_ks0127);
+	return 0;
+}
+
+static void __devexit ks0127_cleanup_module(void)
+{
+	i2c_del_driver(&i2c_driver_ks0127);
+}
+
+
+module_init(ks0127_init_module);
+module_exit(ks0127_cleanup_module);
diff --git a/drivers/media/video/ks0127.h b/drivers/media/video/ks0127.h
new file mode 100644
index 000000000..1ec578833
--- /dev/null
+++ b/drivers/media/video/ks0127.h
@@ -0,0 +1,53 @@
+/*
+ * Video Capture Driver ( Video for Linux 1/2 )
+ * for the Matrox Marvel G200,G400 and Rainbow Runner-G series
+ *
+ * This module is an interface to the KS0127 video decoder chip.
+ *
+ * Copyright (C) 1999  Ryan Drake <stiletto@mediaone.net>
+ *
+ * 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.
+ */
+
+#ifndef KS0127_H
+#define KS0127_H
+
+#include <linux/videodev.h>
+
+/* input channels */
+#define KS_INPUT_COMPOSITE_1    0
+#define KS_INPUT_COMPOSITE_2    1
+#define KS_INPUT_COMPOSITE_3    2
+#define KS_INPUT_COMPOSITE_4    4
+#define KS_INPUT_COMPOSITE_5    5
+#define KS_INPUT_COMPOSITE_6    6
+
+#define KS_INPUT_SVIDEO_1       8
+#define KS_INPUT_SVIDEO_2       9
+#define KS_INPUT_SVIDEO_3       10
+
+#define KS_INPUT_YUV656		15
+#define KS_INPUT_COUNT          10
+
+/* output channels */
+#define KS_OUTPUT_YUV656E       0
+#define KS_OUTPUT_EXV           1
+
+/* video standards */
+#define KS_STD_NTSC_N           112       /* 50 Hz NTSC */
+#define KS_STD_PAL_M            113       /* 60 Hz PAL  */
+
+#endif /* KS0127_H */
+
diff --git a/drivers/media/video/pvrusb2/Kconfig b/drivers/media/video/pvrusb2/Kconfig
new file mode 100644
index 000000000..e43a97927
--- /dev/null
+++ b/drivers/media/video/pvrusb2/Kconfig
@@ -0,0 +1,57 @@
+config VIDEO_PVRUSB2
+	tristate "Hauppauge WinTV-PVR USB2 support"
+	depends on VIDEO_V4L2 && USB && I2C && EXPERIMENTAL
+	select FW_LOADER
+	select VIDEO_TUNER
+	select VIDEO_TVEEPROM
+	select VIDEO_CX2341X
+	select VIDEO_SAA711X
+	select VIDEO_MSP3400
+	---help---
+	  This is a video4linux driver for Conexant 23416 based
+	  usb2 personal video recorder devices.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called pvrusb2
+
+config VIDEO_PVRUSB2_24XXX
+	bool "Hauppauge WinTV-PVR USB2 support for 24xxx model series"
+	depends on VIDEO_PVRUSB2 && EXPERIMENTAL
+	select VIDEO_CX25840
+	select VIDEO_WM8775
+	---help---
+	  This option enables inclusion of additional logic to operate
+	  newer WinTV-PVR USB2 devices whose model number is of the
+	  form "24xxx" (leading prefix of "24" followed by 3 digits).
+	  To see if you may need this option, examine the white
+	  sticker on the underside of your device.  Enabling this
+	  option will not harm support for older devices.
+
+	  If you are in doubt, say Y.
+
+config VIDEO_PVRUSB2_SYSFS
+	bool "pvrusb2 sysfs support (EXPERIMENTAL)"
+	default y
+	depends on VIDEO_PVRUSB2 && SYSFS && EXPERIMENTAL
+	---help---
+	  This option enables the operation of a sysfs based
+	  interface for query and control of the pvrusb2 driver.
+
+	  This is not generally needed for v4l applications,
+	  although certain applications are optimized to take
+	  advantage of this feature.
+
+	  If you are in doubt, say Y.
+
+	  Note: This feature is experimental and subject to change.
+
+config VIDEO_PVRUSB2_DEBUGIFC
+	bool "pvrusb2 debug interface"
+	depends on VIDEO_PVRUSB2_SYSFS
+	---help---
+	  This option enables the inclusion of a debug interface
+	  in the pvrusb2 driver, hosted through sysfs.
+
+	  You do not need to select this option unless you plan
+	  on debugging the driver or performing a manual firmware
+	  extraction.
diff --git a/drivers/media/video/pvrusb2/Makefile b/drivers/media/video/pvrusb2/Makefile
new file mode 100644
index 000000000..02e414210
--- /dev/null
+++ b/drivers/media/video/pvrusb2/Makefile
@@ -0,0 +1,18 @@
+obj-pvrusb2-sysfs-$(CONFIG_VIDEO_PVRUSB2_SYSFS) := pvrusb2-sysfs.o
+obj-pvrusb2-debugifc-$(CONFIG_VIDEO_PVRUSB2_DEBUGIFC) := pvrusb2-debugifc.o
+
+obj-pvrusb2-24xxx-$(CONFIG_VIDEO_PVRUSB2_24XXX) := \
+		   pvrusb2-cx2584x-v4l.o \
+		   pvrusb2-wm8775.o
+
+pvrusb2-objs	:= pvrusb2-i2c-core.o pvrusb2-i2c-cmd-v4l2.o \
+		   pvrusb2-audio.o pvrusb2-i2c-chips-v4l2.o \
+		   pvrusb2-encoder.o pvrusb2-video-v4l.o \
+		   pvrusb2-eeprom.o pvrusb2-tuner.o \
+		   pvrusb2-main.o pvrusb2-hdw.o pvrusb2-v4l2.o \
+		   pvrusb2-ctrl.o pvrusb2-std.o \
+		   pvrusb2-context.o pvrusb2-io.o pvrusb2-ioread.o \
+		   $(obj-pvrusb2-24xxx-y) \
+		   $(obj-pvrusb2-sysfs-y) $(obj-pvrusb2-debugifc-y)
+
+obj-$(CONFIG_VIDEO_PVRUSB2) += pvrusb2.o
diff --git a/drivers/media/video/pvrusb2/pvrusb2-audio.c b/drivers/media/video/pvrusb2/pvrusb2-audio.c
new file mode 100644
index 000000000..9846c464e
--- /dev/null
+++ b/drivers/media/video/pvrusb2/pvrusb2-audio.c
@@ -0,0 +1,204 @@
+/*
+ *
+ *  $Id$
+ *
+ *  Copyright (C) 2005 Mike Isely <isely@pobox.com>
+ *  Copyright (C) 2004 Aurelien Alleaume <slts@free.fr>
+ *
+ *  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
+ *
+ *  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 "pvrusb2-audio.h"
+#include "pvrusb2-hdw-internal.h"
+#include "pvrusb2-debug.h"
+#include <linux/videodev2.h>
+#include <media/msp3400.h>
+#include <media/v4l2-common.h>
+
+struct pvr2_msp3400_handler {
+	struct pvr2_hdw *hdw;
+	struct pvr2_i2c_client *client;
+	struct pvr2_i2c_handler i2c_handler;
+	struct pvr2_audio_stat astat;
+	unsigned long stale_mask;
+};
+
+
+/* This function selects the correct audio input source */
+static void set_stereo(struct pvr2_msp3400_handler *ctxt)
+{
+	struct pvr2_hdw *hdw = ctxt->hdw;
+	struct v4l2_routing route;
+
+	pvr2_trace(PVR2_TRACE_CHIPS,"i2c msp3400 v4l2 set_stereo");
+
+	if (hdw->input_val == PVR2_CVAL_INPUT_TV) {
+		struct v4l2_tuner vt;
+		memset(&vt,0,sizeof(vt));
+		vt.audmode = hdw->audiomode_val;
+		pvr2_i2c_client_cmd(ctxt->client,VIDIOC_S_TUNER,&vt);
+	}
+
+	route.input = MSP_INPUT_DEFAULT;
+	route.output = MSP_OUTPUT(MSP_SC_IN_DSP_SCART1);
+	switch (hdw->input_val) {
+	case PVR2_CVAL_INPUT_TV:
+		break;
+	case PVR2_CVAL_INPUT_RADIO:
+		/* Assume that msp34xx also handle FM decoding, in which case
+		   we're still using the tuner. */
+		/* HV: actually it is more likely to be the SCART2 input if
+		   the ivtv experience is any indication. */
+		route.input = MSP_INPUT(MSP_IN_SCART2, MSP_IN_TUNER1,
+				    MSP_DSP_IN_SCART, MSP_DSP_IN_SCART);
+		break;
+	case PVR2_CVAL_INPUT_SVIDEO:
+	case PVR2_CVAL_INPUT_COMPOSITE:
+		/* SCART 1 input */
+		route.input = MSP_INPUT(MSP_IN_SCART1, MSP_IN_TUNER1,
+				    MSP_DSP_IN_SCART, MSP_DSP_IN_SCART);
+		break;
+	}
+	pvr2_i2c_client_cmd(ctxt->client,VIDIOC_INT_S_AUDIO_ROUTING,&route);
+}
+
+
+static int check_stereo(struct pvr2_msp3400_handler *ctxt)
+{
+	struct pvr2_hdw *hdw = ctxt->hdw;
+	return (hdw->input_dirty ||
+		hdw->audiomode_dirty);
+}
+
+
+struct pvr2_msp3400_ops {
+	void (*update)(struct pvr2_msp3400_handler *);
+	int (*check)(struct pvr2_msp3400_handler *);
+};
+
+
+static const struct pvr2_msp3400_ops msp3400_ops[] = {
+	{ .update = set_stereo, .check = check_stereo},
+};
+
+
+static int msp3400_check(struct pvr2_msp3400_handler *ctxt)
+{
+	unsigned long msk;
+	unsigned int idx;
+
+	for (idx = 0; idx < sizeof(msp3400_ops)/sizeof(msp3400_ops[0]);
+	     idx++) {
+		msk = 1 << idx;
+		if (ctxt->stale_mask & msk) continue;
+		if (msp3400_ops[idx].check(ctxt)) {
+			ctxt->stale_mask |= msk;
+		}
+	}
+	return ctxt->stale_mask != 0;
+}
+
+
+static void msp3400_update(struct pvr2_msp3400_handler *ctxt)
+{
+	unsigned long msk;
+	unsigned int idx;
+
+	for (idx = 0; idx < sizeof(msp3400_ops)/sizeof(msp3400_ops[0]);
+	     idx++) {
+		msk = 1 << idx;
+		if (!(ctxt->stale_mask & msk)) continue;
+		ctxt->stale_mask &= ~msk;
+		msp3400_ops[idx].update(ctxt);
+	}
+}
+
+
+/* This reads back the current signal type */
+static int get_audio_status(struct pvr2_msp3400_handler *ctxt)
+{
+	struct v4l2_tuner vt;
+	int stat;
+
+	memset(&vt,0,sizeof(vt));
+	stat = pvr2_i2c_client_cmd(ctxt->client,VIDIOC_G_TUNER,&vt);
+	if (stat < 0) return stat;
+
+	ctxt->hdw->flag_stereo = (vt.audmode & V4L2_TUNER_MODE_STEREO) != 0;
+	ctxt->hdw->flag_bilingual =
+		(vt.audmode & V4L2_TUNER_MODE_LANG2) != 0;
+	return 0;
+}
+
+
+static void pvr2_msp3400_detach(struct pvr2_msp3400_handler *ctxt)
+{
+	ctxt->client->handler = NULL;
+	ctxt->hdw->audio_stat = NULL;
+	kfree(ctxt);
+}
+
+
+static unsigned int pvr2_msp3400_describe(struct pvr2_msp3400_handler *ctxt,
+					  char *buf,unsigned int cnt)
+{
+	return scnprintf(buf,cnt,"handler: pvrusb2-audio v4l2");
+}
+
+
+const static struct pvr2_i2c_handler_functions msp3400_funcs = {
+	.detach = (void (*)(void *))pvr2_msp3400_detach,
+	.check = (int (*)(void *))msp3400_check,
+	.update = (void (*)(void *))msp3400_update,
+	.describe = (unsigned int (*)(void *,char *,unsigned int))pvr2_msp3400_describe,
+};
+
+
+int pvr2_i2c_msp3400_setup(struct pvr2_hdw *hdw,struct pvr2_i2c_client *cp)
+{
+	struct pvr2_msp3400_handler *ctxt;
+	if (hdw->audio_stat) return 0;
+	if (cp->handler) return 0;
+
+	ctxt = kmalloc(sizeof(*ctxt),GFP_KERNEL);
+	if (!ctxt) return 0;
+	memset(ctxt,0,sizeof(*ctxt));
+
+	ctxt->i2c_handler.func_data = ctxt;
+	ctxt->i2c_handler.func_table = &msp3400_funcs;
+	ctxt->client = cp;
+	ctxt->hdw = hdw;
+	ctxt->astat.ctxt = ctxt;
+	ctxt->astat.status = (int (*)(void *))get_audio_status;
+	ctxt->astat.detach = (void (*)(void *))pvr2_msp3400_detach;
+	ctxt->stale_mask = (1 << (sizeof(msp3400_ops)/
+				  sizeof(msp3400_ops[0]))) - 1;
+	cp->handler = &ctxt->i2c_handler;
+	hdw->audio_stat = &ctxt->astat;
+	pvr2_trace(PVR2_TRACE_CHIPS,"i2c 0x%x msp3400 V4L2 handler set up",
+		   cp->client->addr);
+	return !0;
+}
+
+
+/*
+  Stuff for Emacs to see, in order to encourage consistent editing style:
+  *** Local Variables: ***
+  *** mode: c ***
+  *** fill-column: 70 ***
+  *** tab-width: 8 ***
+  *** c-basic-offset: 8 ***
+  *** End: ***
+  */
diff --git a/drivers/media/video/pvrusb2/pvrusb2-audio.h b/drivers/media/video/pvrusb2/pvrusb2-audio.h
new file mode 100644
index 000000000..536339b68
--- /dev/null
+++ b/drivers/media/video/pvrusb2/pvrusb2-audio.h
@@ -0,0 +1,40 @@
+/*
+ *
+ *  $Id$
+ *
+ *  Copyright (C) 2005 Mike Isely <isely@pobox.com>
+ *  Copyright (C) 2004 Aurelien Alleaume <slts@free.fr>
+ *
+ *  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
+ *
+ *  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 __PVRUSB2_AUDIO_H
+#define __PVRUSB2_AUDIO_H
+
+#include "pvrusb2-i2c-core.h"
+
+int pvr2_i2c_msp3400_setup(struct pvr2_hdw *,struct pvr2_i2c_client *);
+
+#endif /* __PVRUSB2_AUDIO_H */
+
+/*
+  Stuff for Emacs to see, in order to encourage consistent editing style:
+  *** Local Variables: ***
+  *** mode: c ***
+  *** fill-column: 70 ***
+  *** tab-width: 8 ***
+  *** c-basic-offset: 8 ***
+  *** End: ***
+  */
diff --git a/drivers/media/video/pvrusb2/pvrusb2-context.c b/drivers/media/video/pvrusb2/pvrusb2-context.c
new file mode 100644
index 000000000..f129f316d
--- /dev/null
+++ b/drivers/media/video/pvrusb2/pvrusb2-context.c
@@ -0,0 +1,230 @@
+/*
+ *  $Id$
+ *
+ *  Copyright (C) 2005 Mike Isely <isely@pobox.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
+ *
+ *  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 "pvrusb2-context.h"
+#include "pvrusb2-io.h"
+#include "pvrusb2-ioread.h"
+#include "pvrusb2-hdw.h"
+#include "pvrusb2-debug.h"
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+#include <asm/semaphore.h>
+
+
+static void pvr2_context_destroy(struct pvr2_context *mp)
+{
+	if (mp->hdw) pvr2_hdw_destroy(mp->hdw);
+	pvr2_trace(PVR2_TRACE_STRUCT,"Destroying pvr_main id=%p",mp);
+	flush_workqueue(mp->workqueue);
+	destroy_workqueue(mp->workqueue);
+	kfree(mp);
+}
+
+
+static void pvr2_context_trigger_poll(struct pvr2_context *mp)
+{
+	queue_work(mp->workqueue,&mp->workpoll);
+}
+
+
+static void pvr2_context_poll(struct pvr2_context *mp)
+{
+	pvr2_context_enter(mp); do {
+		pvr2_hdw_poll(mp->hdw);
+	} while (0); pvr2_context_exit(mp);
+}
+
+
+static void pvr2_context_setup(struct pvr2_context *mp)
+{
+	pvr2_context_enter(mp); do {
+		if (!pvr2_hdw_dev_ok(mp->hdw)) break;
+		pvr2_hdw_setup(mp->hdw);
+		pvr2_hdw_setup_poll_trigger(
+			mp->hdw,
+			(void (*)(void *))pvr2_context_trigger_poll,
+			mp);
+		if (!pvr2_hdw_dev_ok(mp->hdw)) break;
+		if (!pvr2_hdw_init_ok(mp->hdw)) break;
+		mp->video_stream.stream = pvr2_hdw_get_video_stream(mp->hdw);
+		if (mp->setup_func) {
+			mp->setup_func(mp);
+		}
+	} while (0); pvr2_context_exit(mp);
+}
+
+
+struct pvr2_context *pvr2_context_create(
+	struct usb_interface *intf,
+	const struct usb_device_id *devid,
+	void (*setup_func)(struct pvr2_context *))
+{
+	struct pvr2_context *mp = NULL;
+	mp = kmalloc(sizeof(*mp),GFP_KERNEL);
+	if (!mp) goto done;
+	memset(mp,0,sizeof(*mp));
+	pvr2_trace(PVR2_TRACE_STRUCT,"Creating pvr_main id=%p",mp);
+	mp->setup_func = setup_func;
+	mutex_init(&mp->mutex);
+	mp->hdw = pvr2_hdw_create(intf,devid);
+	if (!mp->hdw) {
+		pvr2_context_destroy(mp);
+		mp = NULL;
+		goto done;
+	}
+
+	mp->workqueue = create_singlethread_workqueue("pvrusb2");
+	INIT_WORK(&mp->workinit,(void (*)(void*))pvr2_context_setup,mp);
+	INIT_WORK(&mp->workpoll,(void (*)(void*))pvr2_context_poll,mp);
+	queue_work(mp->workqueue,&mp->workinit);
+ done:
+	return mp;
+}
+
+
+void pvr2_context_enter(struct pvr2_context *mp)
+{
+	mutex_lock(&mp->mutex);
+	pvr2_trace(PVR2_TRACE_CREG,"pvr2_context_enter(id=%p)",mp);
+}
+
+
+void pvr2_context_exit(struct pvr2_context *mp)
+{
+	int destroy_flag = 0;
+	if (!(mp->mc_first || !mp->disconnect_flag)) {
+		destroy_flag = !0;
+	}
+	pvr2_trace(PVR2_TRACE_CREG,"pvr2_context_exit(id=%p) outside",mp);
+	mutex_unlock(&mp->mutex);
+	if (destroy_flag) pvr2_context_destroy(mp);
+}
+
+
+static void pvr2_context_run_checks(struct pvr2_context *mp)
+{
+	struct pvr2_channel *ch1,*ch2;
+	for (ch1 = mp->mc_first; ch1; ch1 = ch2) {
+		ch2 = ch1->mc_next;
+		if (ch1->check_func) {
+			ch1->check_func(ch1);
+		}
+	}
+}
+
+
+void pvr2_context_disconnect(struct pvr2_context *mp)
+{
+	pvr2_context_enter(mp); do {
+		pvr2_hdw_disconnect(mp->hdw);
+		mp->disconnect_flag = !0;
+		pvr2_context_run_checks(mp);
+	} while (0); pvr2_context_exit(mp);
+}
+
+
+void pvr2_channel_init(struct pvr2_channel *cp,struct pvr2_context *mp)
+{
+	cp->hdw = mp->hdw;
+	cp->mc_head = mp;
+	cp->mc_next = NULL;
+	cp->mc_prev = mp->mc_last;
+	if (mp->mc_last) {
+		mp->mc_last->mc_next = cp;
+	} else {
+		mp->mc_first = cp;
+	}
+	mp->mc_last = cp;
+}
+
+
+static void pvr2_channel_disclaim_stream(struct pvr2_channel *cp)
+{
+	if (!cp->stream) return;
+	pvr2_stream_kill(cp->stream->stream);
+	cp->stream->user = NULL;
+	cp->stream = NULL;
+}
+
+
+void pvr2_channel_done(struct pvr2_channel *cp)
+{
+	struct pvr2_context *mp = cp->mc_head;
+	pvr2_channel_disclaim_stream(cp);
+	if (cp->mc_next) {
+		cp->mc_next->mc_prev = cp->mc_prev;
+	} else {
+		mp->mc_last = cp->mc_prev;
+	}
+	if (cp->mc_prev) {
+		cp->mc_prev->mc_next = cp->mc_next;
+	} else {
+		mp->mc_first = cp->mc_next;
+	}
+	cp->hdw = NULL;
+}
+
+
+int pvr2_channel_claim_stream(struct pvr2_channel *cp,
+			      struct pvr2_context_stream *sp)
+{
+	int code = 0;
+	pvr2_context_enter(cp->mc_head); do {
+		if (sp == cp->stream) break;
+		if (sp->user) {
+			code = -EBUSY;
+			break;
+		}
+		pvr2_channel_disclaim_stream(cp);
+		if (!sp) break;
+		sp->user = cp;
+		cp->stream = sp;
+	} while (0); pvr2_context_exit(cp->mc_head);
+	return code;
+}
+
+
+// This is the marker for the real beginning of a legitimate mpeg2 stream.
+static char stream_sync_key[] = {
+	0x00, 0x00, 0x01, 0xba,
+};
+
+struct pvr2_ioread *pvr2_channel_create_mpeg_stream(
+	struct pvr2_context_stream *sp)
+{
+	struct pvr2_ioread *cp;
+	cp = pvr2_ioread_create();
+	if (!cp) return NULL;
+	pvr2_ioread_setup(cp,sp->stream);
+	pvr2_ioread_set_sync_key(cp,stream_sync_key,sizeof(stream_sync_key));
+	return cp;
+}
+
+
+/*
+  Stuff for Emacs to see, in order to encourage consistent editing style:
+  *** Local Variables: ***
+  *** mode: c ***
+  *** fill-column: 75 ***
+  *** tab-width: 8 ***
+  *** c-basic-offset: 8 ***
+  *** End: ***
+  */
diff --git a/drivers/media/video/pvrusb2/pvrusb2-context.h b/drivers/media/video/pvrusb2/pvrusb2-context.h
new file mode 100644
index 000000000..6327fa1f7
--- /dev/null
+++ b/drivers/media/video/pvrusb2/pvrusb2-context.h
@@ -0,0 +1,92 @@
+/*
+ *  $Id$
+ *
+ *  Copyright (C) 2005 Mike Isely <isely@pobox.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
+ *
+ *  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 __PVRUSB2_BASE_H
+#define __PVRUSB2_BASE_H
+
+#include <linux/mutex.h>
+#include <linux/usb.h>
+#include <linux/workqueue.h>
+
+struct pvr2_hdw;     /* hardware interface - defined elsewhere */
+struct pvr2_stream;  /* stream interface - defined elsewhere */
+
+struct pvr2_context;        /* All central state */
+struct pvr2_channel;        /* One I/O pathway to a user */
+struct pvr2_context_stream; /* Wrapper for a stream */
+struct pvr2_crit_reg;       /* Critical region pointer */
+struct pvr2_ioread;         /* Low level stream structure */
+
+struct pvr2_context_stream {
+	struct pvr2_channel *user;
+	struct pvr2_stream *stream;
+};
+
+struct pvr2_context {
+	struct pvr2_channel *mc_first;
+	struct pvr2_channel *mc_last;
+	struct pvr2_hdw *hdw;
+	struct pvr2_context_stream video_stream;
+	struct mutex mutex;
+	int disconnect_flag;
+
+	/* Called after pvr2_context initialization is complete */
+	void (*setup_func)(struct pvr2_context *);
+
+	/* Work queue overhead for out-of-line processing */
+	struct workqueue_struct *workqueue;
+	struct work_struct workinit;
+	struct work_struct workpoll;
+};
+
+struct pvr2_channel {
+	struct pvr2_context *mc_head;
+	struct pvr2_channel *mc_next;
+	struct pvr2_channel *mc_prev;
+	struct pvr2_context_stream *stream;
+	struct pvr2_hdw *hdw;
+	void (*check_func)(struct pvr2_channel *);
+};
+
+void pvr2_context_enter(struct pvr2_context *);
+void pvr2_context_exit(struct pvr2_context *);
+
+struct pvr2_context *pvr2_context_create(struct usb_interface *intf,
+					 const struct usb_device_id *devid,
+					 void (*setup_func)(struct pvr2_context *));
+void pvr2_context_disconnect(struct pvr2_context *);
+
+void pvr2_channel_init(struct pvr2_channel *,struct pvr2_context *);
+void pvr2_channel_done(struct pvr2_channel *);
+int pvr2_channel_claim_stream(struct pvr2_channel *,
+			      struct pvr2_context_stream *);
+struct pvr2_ioread *pvr2_channel_create_mpeg_stream(
+	struct pvr2_context_stream *);
+
+
+#endif /* __PVRUSB2_CONTEXT_H */
+/*
+  Stuff for Emacs to see, in order to encourage consistent editing style:
+  *** Local Variables: ***
+  *** mode: c ***
+  *** fill-column: 75 ***
+  *** tab-width: 8 ***
+  *** c-basic-offset: 8 ***
+  *** End: ***
+  */
diff --git a/drivers/media/video/pvrusb2/pvrusb2-ctrl.c b/drivers/media/video/pvrusb2/pvrusb2-ctrl.c
new file mode 100644
index 000000000..c77de859c
--- /dev/null
+++ b/drivers/media/video/pvrusb2/pvrusb2-ctrl.c
@@ -0,0 +1,602 @@
+/*
+ *
+ *  $Id$
+ *
+ *  Copyright (C) 2005 Mike Isely <isely@pobox.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
+ *
+ *  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 "pvrusb2-ctrl.h"
+#include "pvrusb2-hdw-internal.h"
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/mutex.h>
+
+
+/* Set the given control. */
+int pvr2_ctrl_set_value(struct pvr2_ctrl *cptr,int val)
+{
+	return pvr2_ctrl_set_mask_value(cptr,~0,val);
+}
+
+
+/* Set/clear specific bits of the given control. */
+int pvr2_ctrl_set_mask_value(struct pvr2_ctrl *cptr,int mask,int val)
+{
+	int ret = 0;
+	if (!cptr) return -EINVAL;
+	LOCK_TAKE(cptr->hdw->big_lock); do {
+		if (cptr->info->set_value != 0) {
+			if (cptr->info->type == pvr2_ctl_bitmask) {
+				mask &= cptr->info->def.type_bitmask.valid_bits;
+			} else if (cptr->info->type == pvr2_ctl_int) {
+				int lim;
+				lim = cptr->info->def.type_int.min_value;
+				if (cptr->info->get_min_value) {
+					cptr->info->get_min_value(cptr,&lim);
+				}
+				if (val < lim) break;
+				lim = cptr->info->def.type_int.max_value;
+				if (cptr->info->get_max_value) {
+					cptr->info->get_max_value(cptr,&lim);
+				}
+				if (val > lim) break;
+			} else if (cptr->info->type == pvr2_ctl_enum) {
+				if (val >= cptr->info->def.type_enum.count) {
+					break;
+				}
+			} else if (cptr->info->type != pvr2_ctl_bool) {
+				break;
+			}
+			ret = cptr->info->set_value(cptr,mask,val);
+		} else {
+			ret = -EPERM;
+		}
+	} while(0); LOCK_GIVE(cptr->hdw->big_lock);
+	return ret;
+}
+
+
+/* Get the current value of the given control. */
+int pvr2_ctrl_get_value(struct pvr2_ctrl *cptr,int *valptr)
+{
+	int ret = 0;
+	if (!cptr) return -EINVAL;
+	LOCK_TAKE(cptr->hdw->big_lock); do {
+		ret = cptr->info->get_value(cptr,valptr);
+	} while(0); LOCK_GIVE(cptr->hdw->big_lock);
+	return ret;
+}
+
+
+/* Retrieve control's type */
+enum pvr2_ctl_type pvr2_ctrl_get_type(struct pvr2_ctrl *cptr)
+{
+	if (!cptr) return pvr2_ctl_int;
+	return cptr->info->type;
+}
+
+
+/* Retrieve control's maximum value (int type) */
+int pvr2_ctrl_get_max(struct pvr2_ctrl *cptr)
+{
+	int ret = 0;
+	if (!cptr) return 0;
+	LOCK_TAKE(cptr->hdw->big_lock); do {
+		if (cptr->info->get_max_value) {
+			cptr->info->get_max_value(cptr,&ret);
+		} else if (cptr->info->type == pvr2_ctl_int) {
+			ret = cptr->info->def.type_int.max_value;
+		}
+	} while(0); LOCK_GIVE(cptr->hdw->big_lock);
+	return ret;
+}
+
+
+/* Retrieve control's minimum value (int type) */
+int pvr2_ctrl_get_min(struct pvr2_ctrl *cptr)
+{
+	int ret = 0;
+	if (!cptr) return 0;
+	LOCK_TAKE(cptr->hdw->big_lock); do {
+		if (cptr->info->get_min_value) {
+			cptr->info->get_min_value(cptr,&ret);
+		} else if (cptr->info->type == pvr2_ctl_int) {
+			ret = cptr->info->def.type_int.min_value;
+		}
+	} while(0); LOCK_GIVE(cptr->hdw->big_lock);
+	return ret;
+}
+
+
+/* Retrieve control's default value (any type) */
+int pvr2_ctrl_get_def(struct pvr2_ctrl *cptr)
+{
+	int ret = 0;
+	if (!cptr) return 0;
+	LOCK_TAKE(cptr->hdw->big_lock); do {
+		if (cptr->info->type == pvr2_ctl_int) {
+			ret = cptr->info->default_value;
+		}
+	} while(0); LOCK_GIVE(cptr->hdw->big_lock);
+	return ret;
+}
+
+
+/* Retrieve control's enumeration count (enum only) */
+int pvr2_ctrl_get_cnt(struct pvr2_ctrl *cptr)
+{
+	int ret = 0;
+	if (!cptr) return 0;
+	LOCK_TAKE(cptr->hdw->big_lock); do {
+		if (cptr->info->type == pvr2_ctl_enum) {
+			ret = cptr->info->def.type_enum.count;
+		}
+	} while(0); LOCK_GIVE(cptr->hdw->big_lock);
+	return ret;
+}
+
+
+/* Retrieve control's valid mask bits (bit mask only) */
+int pvr2_ctrl_get_mask(struct pvr2_ctrl *cptr)
+{
+	int ret = 0;
+	if (!cptr) return 0;
+	LOCK_TAKE(cptr->hdw->big_lock); do {
+		if (cptr->info->type == pvr2_ctl_bitmask) {
+			ret = cptr->info->def.type_bitmask.valid_bits;
+		}
+	} while(0); LOCK_GIVE(cptr->hdw->big_lock);
+	return ret;
+}
+
+
+/* Retrieve the control's name */
+const char *pvr2_ctrl_get_name(struct pvr2_ctrl *cptr)
+{
+	if (!cptr) return NULL;
+	return cptr->info->name;
+}
+
+
+/* Retrieve the control's desc */
+const char *pvr2_ctrl_get_desc(struct pvr2_ctrl *cptr)
+{
+	if (!cptr) return NULL;
+	return cptr->info->desc;
+}
+
+
+/* Retrieve a control enumeration or bit mask value */
+int pvr2_ctrl_get_valname(struct pvr2_ctrl *cptr,int val,
+			  char *bptr,unsigned int bmax,
+			  unsigned int *blen)
+{
+	int ret = -EINVAL;
+	if (!cptr) return 0;
+	*blen = 0;
+	LOCK_TAKE(cptr->hdw->big_lock); do {
+		if (cptr->info->type == pvr2_ctl_enum) {
+			const char **names;
+			names = cptr->info->def.type_enum.value_names;
+			if ((val >= 0) &&
+			    (val < cptr->info->def.type_enum.count)) {
+				if (names[val]) {
+					*blen = scnprintf(
+						bptr,bmax,"%s",
+						names[val]);
+				} else {
+					*blen = 0;
+				}
+				ret = 0;
+			}
+		} else if (cptr->info->type == pvr2_ctl_bitmask) {
+			const char **names;
+			unsigned int idx;
+			int msk;
+			names = cptr->info->def.type_bitmask.bit_names;
+			val &= cptr->info->def.type_bitmask.valid_bits;
+			for (idx = 0, msk = 1; val; idx++, msk <<= 1) {
+				if (val & msk) {
+					*blen = scnprintf(bptr,bmax,"%s",
+							  names[idx]);
+					ret = 0;
+					break;
+				}
+			}
+		}
+	} while(0); LOCK_GIVE(cptr->hdw->big_lock);
+	return ret;
+}
+
+
+/* Return V4L ID for this control or zero if none */
+int pvr2_ctrl_get_v4lid(struct pvr2_ctrl *cptr)
+{
+	if (!cptr) return 0;
+	return cptr->info->v4l_id;
+}
+
+
+unsigned int pvr2_ctrl_get_v4lflags(struct pvr2_ctrl *cptr)
+{
+	unsigned int flags = 0;
+
+	if (cptr->info->get_v4lflags) {
+		flags = cptr->info->get_v4lflags(cptr);
+	}
+
+	if (cptr->info->set_value) {
+		flags &= ~V4L2_CTRL_FLAG_READ_ONLY;
+	} else {
+		flags |= V4L2_CTRL_FLAG_READ_ONLY;
+	}
+
+	return flags;
+}
+
+
+/* Return true if control is writable */
+int pvr2_ctrl_is_writable(struct pvr2_ctrl *cptr)
+{
+	if (!cptr) return 0;
+	return cptr->info->set_value != 0;
+}
+
+
+/* Return true if control has custom symbolic representation */
+int pvr2_ctrl_has_custom_symbols(struct pvr2_ctrl *cptr)
+{
+	if (!cptr) return 0;
+	if (!cptr->info->val_to_sym) return 0;
+	if (!cptr->info->sym_to_val) return 0;
+	return !0;
+}
+
+
+/* Convert a given mask/val to a custom symbolic value */
+int pvr2_ctrl_custom_value_to_sym(struct pvr2_ctrl *cptr,
+				  int mask,int val,
+				  char *buf,unsigned int maxlen,
+				  unsigned int *len)
+{
+	if (!cptr) return -EINVAL;
+	if (!cptr->info->val_to_sym) return -EINVAL;
+	return cptr->info->val_to_sym(cptr,mask,val,buf,maxlen,len);
+}
+
+
+/* Convert a symbolic value to a mask/value pair */
+int pvr2_ctrl_custom_sym_to_value(struct pvr2_ctrl *cptr,
+				  const char *buf,unsigned int len,
+				  int *maskptr,int *valptr)
+{
+	if (!cptr) return -EINVAL;
+	if (!cptr->info->sym_to_val) return -EINVAL;
+	return cptr->info->sym_to_val(cptr,buf,len,maskptr,valptr);
+}
+
+
+static unsigned int gen_bitmask_string(int msk,int val,int msk_only,
+				       const char **names,
+				       char *ptr,unsigned int len)
+{
+	unsigned int idx;
+	long sm,um;
+	int spcFl;
+	unsigned int uc,cnt;
+	const char *idStr;
+
+	spcFl = 0;
+	uc = 0;
+	um = 0;
+	for (idx = 0, sm = 1; msk; idx++, sm <<= 1) {
+		if (sm & msk) {
+			msk &= ~sm;
+			idStr = names[idx];
+			if (idStr) {
+				cnt = scnprintf(ptr,len,"%s%s%s",
+						(spcFl ? " " : ""),
+						(msk_only ? "" :
+						 ((val & sm) ? "+" : "-")),
+						idStr);
+				ptr += cnt; len -= cnt; uc += cnt;
+				spcFl = !0;
+			} else {
+				um |= sm;
+			}
+		}
+	}
+	if (um) {
+		if (msk_only) {
+			cnt = scnprintf(ptr,len,"%s0x%lx",
+					(spcFl ? " " : ""),
+					um);
+			ptr += cnt; len -= cnt; uc += cnt;
+			spcFl = !0;
+		} else if (um & val) {
+			cnt = scnprintf(ptr,len,"%s+0x%lx",
+					(spcFl ? " " : ""),
+					um & val);
+			ptr += cnt; len -= cnt; uc += cnt;
+			spcFl = !0;
+		} else if (um & ~val) {
+			cnt = scnprintf(ptr,len,"%s+0x%lx",
+					(spcFl ? " " : ""),
+					um & ~val);
+			ptr += cnt; len -= cnt; uc += cnt;
+			spcFl = !0;
+		}
+	}
+	return uc;
+}
+
+
+static const char *boolNames[] = {
+	"false",
+	"true",
+	"no",
+	"yes",
+};
+
+
+static int parse_token(const char *ptr,unsigned int len,
+		       int *valptr,
+		       const char **names,unsigned int namecnt)
+{
+	char buf[33];
+	unsigned int slen;
+	unsigned int idx;
+	int negfl;
+	char *p2;
+	*valptr = 0;
+	if (!names) namecnt = 0;
+	for (idx = 0; idx < namecnt; idx++) {
+		if (!names[idx]) continue;
+		slen = strlen(names[idx]);
+		if (slen != len) continue;
+		if (memcmp(names[idx],ptr,slen)) continue;
+		*valptr = idx;
+		return 0;
+	}
+	negfl = 0;
+	if ((*ptr == '-') || (*ptr == '+')) {
+		negfl = (*ptr == '-');
+		ptr++; len--;
+	}
+	if (len >= sizeof(buf)) return -EINVAL;
+	memcpy(buf,ptr,len);
+	buf[len] = 0;
+	*valptr = simple_strtol(buf,&p2,0);
+	if (negfl) *valptr = -(*valptr);
+	if (*p2) return -EINVAL;
+	return 1;
+}
+
+
+static int parse_mtoken(const char *ptr,unsigned int len,
+			int *valptr,
+			const char **names,int valid_bits)
+{
+	char buf[33];
+	unsigned int slen;
+	unsigned int idx;
+	char *p2;
+	int msk;
+	*valptr = 0;
+	for (idx = 0, msk = 1; valid_bits; idx++, msk <<= 1) {
+		if (!msk & valid_bits) continue;
+		valid_bits &= ~msk;
+		if (!names[idx]) continue;
+		slen = strlen(names[idx]);
+		if (slen != len) continue;
+		if (memcmp(names[idx],ptr,slen)) continue;
+		*valptr = msk;
+		return 0;
+	}
+	if (len >= sizeof(buf)) return -EINVAL;
+	memcpy(buf,ptr,len);
+	buf[len] = 0;
+	*valptr = simple_strtol(buf,&p2,0);
+	if (*p2) return -EINVAL;
+	return 0;
+}
+
+
+static int parse_tlist(const char *ptr,unsigned int len,
+		       int *maskptr,int *valptr,
+		       const char **names,int valid_bits)
+{
+	unsigned int cnt;
+	int mask,val,kv,mode,ret;
+	mask = 0;
+	val = 0;
+	ret = 0;
+	while (len) {
+		cnt = 0;
+		while ((cnt < len) &&
+		       ((ptr[cnt] <= 32) ||
+			(ptr[cnt] >= 127))) cnt++;
+		ptr += cnt;
+		len -= cnt;
+		mode = 0;
+		if ((*ptr == '-') || (*ptr == '+')) {
+			mode = (*ptr == '-') ? -1 : 1;
+			ptr++;
+			len--;
+		}
+		cnt = 0;
+		while (cnt < len) {
+			if (ptr[cnt] <= 32) break;
+			if (ptr[cnt] >= 127) break;
+			cnt++;
+		}
+		if (!cnt) break;
+		if (parse_mtoken(ptr,cnt,&kv,names,valid_bits)) {
+			ret = -EINVAL;
+			break;
+		}
+		ptr += cnt;
+		len -= cnt;
+		switch (mode) {
+		case 0:
+			mask = valid_bits;
+			val |= kv;
+			break;
+		case -1:
+			mask |= kv;
+			val &= ~kv;
+			break;
+		case 1:
+			mask |= kv;
+			val |= kv;
+			break;
+		default:
+			break;
+		}
+	}
+	*maskptr = mask;
+	*valptr = val;
+	return ret;
+}
+
+
+/* Convert a symbolic value to a mask/value pair */
+int pvr2_ctrl_sym_to_value(struct pvr2_ctrl *cptr,
+			   const char *ptr,unsigned int len,
+			   int *maskptr,int *valptr)
+{
+	int ret = -EINVAL;
+	unsigned int cnt;
+
+	*maskptr = 0;
+	*valptr = 0;
+
+	cnt = 0;
+	while ((cnt < len) && ((ptr[cnt] <= 32) || (ptr[cnt] >= 127))) cnt++;
+	len -= cnt; ptr += cnt;
+	cnt = 0;
+	while ((cnt < len) && ((ptr[len-(cnt+1)] <= 32) ||
+			       (ptr[len-(cnt+1)] >= 127))) cnt++;
+	len -= cnt;
+
+	if (!len) return -EINVAL;
+
+	LOCK_TAKE(cptr->hdw->big_lock); do {
+		if (cptr->info->type == pvr2_ctl_int) {
+			ret = parse_token(ptr,len,valptr,NULL,0);
+			if ((ret >= 0) &&
+			    ((*valptr < cptr->info->def.type_int.min_value) ||
+			     (*valptr > cptr->info->def.type_int.max_value))) {
+				ret = -ERANGE;
+			}
+			if (maskptr) *maskptr = ~0;
+		} else if (cptr->info->type == pvr2_ctl_bool) {
+			ret = parse_token(
+				ptr,len,valptr,boolNames,
+				sizeof(boolNames)/sizeof(boolNames[0]));
+			if (ret == 1) {
+				*valptr = *valptr ? !0 : 0;
+			} else if (ret == 0) {
+				*valptr = (*valptr & 1) ? !0 : 0;
+			}
+			if (maskptr) *maskptr = 1;
+		} else if (cptr->info->type == pvr2_ctl_enum) {
+			ret = parse_token(
+				ptr,len,valptr,
+				cptr->info->def.type_enum.value_names,
+				cptr->info->def.type_enum.count);
+			if ((ret >= 0) &&
+			    ((*valptr < 0) ||
+			     (*valptr >= cptr->info->def.type_enum.count))) {
+				ret = -ERANGE;
+			}
+			if (maskptr) *maskptr = ~0;
+		} else if (cptr->info->type == pvr2_ctl_bitmask) {
+			ret = parse_tlist(
+				ptr,len,maskptr,valptr,
+				cptr->info->def.type_bitmask.bit_names,
+				cptr->info->def.type_bitmask.valid_bits);
+		}
+	} while(0); LOCK_GIVE(cptr->hdw->big_lock);
+	return ret;
+}
+
+
+/* Convert a given mask/val to a symbolic value */
+int pvr2_ctrl_value_to_sym_internal(struct pvr2_ctrl *cptr,
+				    int mask,int val,
+				    char *buf,unsigned int maxlen,
+				    unsigned int *len)
+{
+	int ret = -EINVAL;
+
+	*len = 0;
+	if (cptr->info->type == pvr2_ctl_int) {
+		*len = scnprintf(buf,maxlen,"%d",val);
+		ret = 0;
+	} else if (cptr->info->type == pvr2_ctl_bool) {
+		*len = scnprintf(buf,maxlen,"%s",val ? "true" : "false");
+		ret = 0;
+	} else if (cptr->info->type == pvr2_ctl_enum) {
+		const char **names;
+		names = cptr->info->def.type_enum.value_names;
+		if ((val >= 0) &&
+		    (val < cptr->info->def.type_enum.count)) {
+			if (names[val]) {
+				*len = scnprintf(
+					buf,maxlen,"%s",
+					names[val]);
+			} else {
+				*len = 0;
+			}
+			ret = 0;
+		}
+	} else if (cptr->info->type == pvr2_ctl_bitmask) {
+		*len = gen_bitmask_string(
+			val & mask & cptr->info->def.type_bitmask.valid_bits,
+			~0,!0,
+			cptr->info->def.type_bitmask.bit_names,
+			buf,maxlen);
+	}
+	return ret;
+}
+
+
+/* Convert a given mask/val to a symbolic value */
+int pvr2_ctrl_value_to_sym(struct pvr2_ctrl *cptr,
+			   int mask,int val,
+			   char *buf,unsigned int maxlen,
+			   unsigned int *len)
+{
+	int ret;
+	LOCK_TAKE(cptr->hdw->big_lock); do {
+		ret = pvr2_ctrl_value_to_sym_internal(cptr,mask,val,
+						      buf,maxlen,len);
+	} while(0); LOCK_GIVE(cptr->hdw->big_lock);
+	return ret;
+}
+
+
+/*
+  Stuff for Emacs to see, in order to encourage consistent editing style:
+  *** Local Variables: ***
+  *** mode: c ***
+  *** fill-column: 75 ***
+  *** tab-width: 8 ***
+  *** c-basic-offset: 8 ***
+  *** End: ***
+  */
diff --git a/drivers/media/video/pvrusb2/pvrusb2-ctrl.h b/drivers/media/video/pvrusb2/pvrusb2-ctrl.h
new file mode 100644
index 000000000..c1680053c
--- /dev/null
+++ b/drivers/media/video/pvrusb2/pvrusb2-ctrl.h
@@ -0,0 +1,123 @@
+/*
+ *
+ *  $Id$
+ *
+ *  Copyright (C) 2005 Mike Isely <isely@pobox.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
+ *
+ *  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 __PVRUSB2_CTRL_H
+#define __PVRUSB2_CTRL_H
+
+struct pvr2_ctrl;
+
+enum pvr2_ctl_type {
+	pvr2_ctl_int = 0,
+	pvr2_ctl_enum = 1,
+	pvr2_ctl_bitmask = 2,
+	pvr2_ctl_bool = 3,
+};
+
+
+/* Set the given control. */
+int pvr2_ctrl_set_value(struct pvr2_ctrl *,int val);
+
+/* Set/clear specific bits of the given control. */
+int pvr2_ctrl_set_mask_value(struct pvr2_ctrl *,int mask,int val);
+
+/* Get the current value of the given control. */
+int pvr2_ctrl_get_value(struct pvr2_ctrl *,int *valptr);
+
+/* Retrieve control's type */
+enum pvr2_ctl_type pvr2_ctrl_get_type(struct pvr2_ctrl *);
+
+/* Retrieve control's maximum value (int type) */
+int pvr2_ctrl_get_max(struct pvr2_ctrl *);
+
+/* Retrieve control's minimum value (int type) */
+int pvr2_ctrl_get_min(struct pvr2_ctrl *);
+
+/* Retrieve control's default value (any type) */
+int pvr2_ctrl_get_def(struct pvr2_ctrl *);
+
+/* Retrieve control's enumeration count (enum only) */
+int pvr2_ctrl_get_cnt(struct pvr2_ctrl *);
+
+/* Retrieve control's valid mask bits (bit mask only) */
+int pvr2_ctrl_get_mask(struct pvr2_ctrl *);
+
+/* Retrieve the control's name */
+const char *pvr2_ctrl_get_name(struct pvr2_ctrl *);
+
+/* Retrieve the control's desc */
+const char *pvr2_ctrl_get_desc(struct pvr2_ctrl *);
+
+/* Retrieve a control enumeration or bit mask value */
+int pvr2_ctrl_get_valname(struct pvr2_ctrl *,int,char *,unsigned int,
+			  unsigned int *);
+
+/* Return true if control is writable */
+int pvr2_ctrl_is_writable(struct pvr2_ctrl *);
+
+/* Return V4L flags value for control (or zero if there is no v4l control
+   actually under this control) */
+unsigned int pvr2_ctrl_get_v4lflags(struct pvr2_ctrl *);
+
+/* Return V4L ID for this control or zero if none */
+int pvr2_ctrl_get_v4lid(struct pvr2_ctrl *);
+
+/* Return true if control has custom symbolic representation */
+int pvr2_ctrl_has_custom_symbols(struct pvr2_ctrl *);
+
+/* Convert a given mask/val to a custom symbolic value */
+int pvr2_ctrl_custom_value_to_sym(struct pvr2_ctrl *,
+				  int mask,int val,
+				  char *buf,unsigned int maxlen,
+				  unsigned int *len);
+
+/* Convert a symbolic value to a mask/value pair */
+int pvr2_ctrl_custom_sym_to_value(struct pvr2_ctrl *,
+				  const char *buf,unsigned int len,
+				  int *maskptr,int *valptr);
+
+/* Convert a given mask/val to a symbolic value */
+int pvr2_ctrl_value_to_sym(struct pvr2_ctrl *,
+			   int mask,int val,
+			   char *buf,unsigned int maxlen,
+			   unsigned int *len);
+
+/* Convert a symbolic value to a mask/value pair */
+int pvr2_ctrl_sym_to_value(struct pvr2_ctrl *,
+			   const char *buf,unsigned int len,
+			   int *maskptr,int *valptr);
+
+/* Convert a given mask/val to a symbolic value - must already be
+   inside of critical region. */
+int pvr2_ctrl_value_to_sym_internal(struct pvr2_ctrl *,
+			   int mask,int val,
+			   char *buf,unsigned int maxlen,
+			   unsigned int *len);
+
+#endif /* __PVRUSB2_CTRL_H */
+
+/*
+  Stuff for Emacs to see, in order to encourage consistent editing style:
+  *** Local Variables: ***
+  *** mode: c ***
+  *** fill-column: 75 ***
+  *** tab-width: 8 ***
+  *** c-basic-offset: 8 ***
+  *** End: ***
+  */
diff --git a/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c b/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c
new file mode 100644
index 000000000..c80c26be6
--- /dev/null
+++ b/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c
@@ -0,0 +1,279 @@
+/*
+ *
+ *  $Id$
+ *
+ *  Copyright (C) 2005 Mike Isely <isely@pobox.com>
+ *  Copyright (C) 2004 Aurelien Alleaume <slts@free.fr>
+ *
+ *  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
+ *
+ *  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
+ *
+ */
+
+/*
+
+   This source file is specifically designed to interface with the
+   cx2584x, in kernels 2.6.16 or newer.
+
+*/
+
+#include "pvrusb2-cx2584x-v4l.h"
+#include "pvrusb2-video-v4l.h"
+#include "pvrusb2-i2c-cmd-v4l2.h"
+
+
+#include "pvrusb2-hdw-internal.h"
+#include "pvrusb2-debug.h"
+#include <media/cx25840.h>
+#include <linux/videodev2.h>
+#include <media/v4l2-common.h>
+#include <linux/errno.h>
+#include <linux/slab.h>
+
+struct pvr2_v4l_cx2584x {
+	struct pvr2_i2c_handler handler;
+	struct pvr2_decoder_ctrl ctrl;
+	struct pvr2_i2c_client *client;
+	struct pvr2_hdw *hdw;
+	unsigned long stale_mask;
+};
+
+
+static void set_input(struct pvr2_v4l_cx2584x *ctxt)
+{
+	struct pvr2_hdw *hdw = ctxt->hdw;
+	struct v4l2_routing route;
+	enum cx25840_video_input vid_input;
+	enum cx25840_audio_input aud_input;
+
+	memset(&route,0,sizeof(route));
+
+	switch(hdw->input_val) {
+	case PVR2_CVAL_INPUT_TV:
+		vid_input = CX25840_COMPOSITE7;
+		aud_input = CX25840_AUDIO8;
+		break;
+	case PVR2_CVAL_INPUT_COMPOSITE:
+		vid_input = CX25840_COMPOSITE3;
+		aud_input = CX25840_AUDIO_SERIAL;
+		break;
+	case PVR2_CVAL_INPUT_SVIDEO:
+		vid_input = CX25840_SVIDEO1;
+		aud_input = CX25840_AUDIO_SERIAL;
+		break;
+	case PVR2_CVAL_INPUT_RADIO:
+	default:
+		// Just set it to be composite input for now...
+		vid_input = CX25840_COMPOSITE3;
+		aud_input = CX25840_AUDIO_SERIAL;
+		break;
+	}
+
+	pvr2_trace(PVR2_TRACE_CHIPS,"i2c cx2584x set_input vid=0x%x aud=0x%x",
+		   vid_input,aud_input);
+	route.input = (u32)vid_input;
+	pvr2_i2c_client_cmd(ctxt->client,VIDIOC_INT_S_VIDEO_ROUTING,&route);
+	route.input = (u32)aud_input;
+	pvr2_i2c_client_cmd(ctxt->client,VIDIOC_INT_S_AUDIO_ROUTING,&route);
+}
+
+
+static int check_input(struct pvr2_v4l_cx2584x *ctxt)
+{
+	struct pvr2_hdw *hdw = ctxt->hdw;
+	return hdw->input_dirty != 0;
+}
+
+
+static void set_audio(struct pvr2_v4l_cx2584x *ctxt)
+{
+	u32 val;
+	struct pvr2_hdw *hdw = ctxt->hdw;
+
+	pvr2_trace(PVR2_TRACE_CHIPS,"i2c cx2584x set_audio %d",
+		   hdw->srate_val);
+	switch (hdw->srate_val) {
+	default:
+	case V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000:
+		val = 48000;
+		break;
+	case V4L2_MPEG_AUDIO_SAMPLING_FREQ_44100:
+		val = 44100;
+		break;
+	case V4L2_MPEG_AUDIO_SAMPLING_FREQ_32000:
+		val = 32000;
+		break;
+	}
+	pvr2_i2c_client_cmd(ctxt->client,VIDIOC_INT_AUDIO_CLOCK_FREQ,&val);
+}
+
+
+static int check_audio(struct pvr2_v4l_cx2584x *ctxt)
+{
+	struct pvr2_hdw *hdw = ctxt->hdw;
+	return hdw->srate_dirty != 0;
+}
+
+
+struct pvr2_v4l_cx2584x_ops {
+	void (*update)(struct pvr2_v4l_cx2584x *);
+	int (*check)(struct pvr2_v4l_cx2584x *);
+};
+
+
+static const struct pvr2_v4l_cx2584x_ops decoder_ops[] = {
+	{ .update = set_input, .check = check_input},
+	{ .update = set_audio, .check = check_audio},
+};
+
+
+static void decoder_detach(struct pvr2_v4l_cx2584x *ctxt)
+{
+	ctxt->client->handler = NULL;
+	ctxt->hdw->decoder_ctrl = NULL;
+	kfree(ctxt);
+}
+
+
+static int decoder_check(struct pvr2_v4l_cx2584x *ctxt)
+{
+	unsigned long msk;
+	unsigned int idx;
+
+	for (idx = 0; idx < sizeof(decoder_ops)/sizeof(decoder_ops[0]);
+	     idx++) {
+		msk = 1 << idx;
+		if (ctxt->stale_mask & msk) continue;
+		if (decoder_ops[idx].check(ctxt)) {
+			ctxt->stale_mask |= msk;
+		}
+	}
+	return ctxt->stale_mask != 0;
+}
+
+
+static void decoder_update(struct pvr2_v4l_cx2584x *ctxt)
+{
+	unsigned long msk;
+	unsigned int idx;
+
+	for (idx = 0; idx < sizeof(decoder_ops)/sizeof(decoder_ops[0]);
+	     idx++) {
+		msk = 1 << idx;
+		if (!(ctxt->stale_mask & msk)) continue;
+		ctxt->stale_mask &= ~msk;
+		decoder_ops[idx].update(ctxt);
+	}
+}
+
+
+static void decoder_enable(struct pvr2_v4l_cx2584x *ctxt,int fl)
+{
+	pvr2_trace(PVR2_TRACE_CHIPS,"i2c cx25840 decoder_enable(%d)",fl);
+	pvr2_v4l2_cmd_stream(ctxt->client,fl);
+}
+
+
+static int decoder_detect(struct pvr2_i2c_client *cp)
+{
+	int ret;
+	/* Attempt to query the decoder - let's see if it will answer */
+	struct v4l2_queryctrl qc;
+
+	memset(&qc,0,sizeof(qc));
+
+	qc.id = V4L2_CID_BRIGHTNESS;
+
+	ret = pvr2_i2c_client_cmd(cp,VIDIOC_QUERYCTRL,&qc);
+	return ret == 0; /* Return true if it answered */
+}
+
+
+static int decoder_is_tuned(struct pvr2_v4l_cx2584x *ctxt)
+{
+	struct v4l2_tuner vt;
+	int ret;
+
+	memset(&vt,0,sizeof(vt));
+	ret = pvr2_i2c_client_cmd(ctxt->client,VIDIOC_G_TUNER,&vt);
+	if (ret < 0) return -EINVAL;
+	return vt.signal ? 1 : 0;
+}
+
+
+static unsigned int decoder_describe(struct pvr2_v4l_cx2584x *ctxt,
+				     char *buf,unsigned int cnt)
+{
+	return scnprintf(buf,cnt,"handler: pvrusb2-cx2584x-v4l");
+}
+
+
+static void decoder_reset(struct pvr2_v4l_cx2584x *ctxt)
+{
+	int ret;
+	ret = pvr2_i2c_client_cmd(ctxt->client,VIDIOC_INT_RESET,NULL);
+	pvr2_trace(PVR2_TRACE_CHIPS,"i2c cx25840 decoder_reset (ret=%d)",ret);
+}
+
+
+const static struct pvr2_i2c_handler_functions hfuncs = {
+	.detach = (void (*)(void *))decoder_detach,
+	.check = (int (*)(void *))decoder_check,
+	.update = (void (*)(void *))decoder_update,
+	.describe = (unsigned int (*)(void *,char *,unsigned int))decoder_describe,
+};
+
+
+int pvr2_i2c_cx2584x_v4l_setup(struct pvr2_hdw *hdw,
+			       struct pvr2_i2c_client *cp)
+{
+	struct pvr2_v4l_cx2584x *ctxt;
+
+	if (hdw->decoder_ctrl) return 0;
+	if (cp->handler) return 0;
+	if (!decoder_detect(cp)) return 0;
+
+	ctxt = kmalloc(sizeof(*ctxt),GFP_KERNEL);
+	if (!ctxt) return 0;
+	memset(ctxt,0,sizeof(*ctxt));
+
+	ctxt->handler.func_data = ctxt;
+	ctxt->handler.func_table = &hfuncs;
+	ctxt->ctrl.ctxt = ctxt;
+	ctxt->ctrl.detach = (void (*)(void *))decoder_detach;
+	ctxt->ctrl.enable = (void (*)(void *,int))decoder_enable;
+	ctxt->ctrl.tuned = (int (*)(void *))decoder_is_tuned;
+	ctxt->ctrl.force_reset = (void (*)(void*))decoder_reset;
+	ctxt->client = cp;
+	ctxt->hdw = hdw;
+	ctxt->stale_mask = (1 << (sizeof(decoder_ops)/
+				  sizeof(decoder_ops[0]))) - 1;
+	hdw->decoder_ctrl = &ctxt->ctrl;
+	cp->handler = &ctxt->handler;
+	pvr2_trace(PVR2_TRACE_CHIPS,"i2c 0x%x cx2584x V4L2 handler set up",
+		   cp->client->addr);
+	return !0;
+}
+
+
+
+
+/*
+  Stuff for Emacs to see, in order to encourage consistent editing style:
+  *** Local Variables: ***
+  *** mode: c ***
+  *** fill-column: 70 ***
+  *** tab-width: 8 ***
+  *** c-basic-offset: 8 ***
+  *** End: ***
+  */
diff --git a/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.h b/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.h
new file mode 100644
index 000000000..54b2844e7
--- /dev/null
+++ b/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.h
@@ -0,0 +1,53 @@
+/*
+ *
+ *  $Id$
+ *
+ *  Copyright (C) 2005 Mike Isely <isely@pobox.com>
+ *  Copyright (C) 2004 Aurelien Alleaume <slts@free.fr>
+ *
+ *  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
+ *
+ *  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 __PVRUSB2_CX2584X_V4L_H
+#define __PVRUSB2_CX2584X_V4L_H
+
+/*
+
+   This module connects the pvrusb2 driver to the I2C chip level
+   driver which handles combined device audio & video processing.
+   This interface is used internally by the driver; higher level code
+   should only interact through the interface provided by
+   pvrusb2-hdw.h.
+
+*/
+
+
+
+#include "pvrusb2-i2c-core.h"
+
+int pvr2_i2c_cx2584x_v4l_setup(struct pvr2_hdw *,struct pvr2_i2c_client *);
+
+
+#endif /* __PVRUSB2_CX2584X_V4L_H */
+
+/*
+  Stuff for Emacs to see, in order to encourage consistent editing style:
+  *** Local Variables: ***
+  *** mode: c ***
+  *** fill-column: 70 ***
+  *** tab-width: 8 ***
+  *** c-basic-offset: 8 ***
+  *** End: ***
+  */
diff --git a/drivers/media/video/pvrusb2/pvrusb2-debug.h b/drivers/media/video/pvrusb2/pvrusb2-debug.h
new file mode 100644
index 000000000..d95a8588e
--- /dev/null
+++ b/drivers/media/video/pvrusb2/pvrusb2-debug.h
@@ -0,0 +1,67 @@
+/*
+ *  $Id$
+ *
+ *  Copyright (C) 2005 Mike Isely <isely@pobox.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
+ *
+ *  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 __PVRUSB2_DEBUG_H
+#define __PVRUSB2_DEBUG_H
+
+extern int pvrusb2_debug;
+
+#define pvr2_trace(msk, fmt, arg...) do {if(msk & pvrusb2_debug) printk(KERN_INFO "pvrusb2: " fmt "\n", ##arg); } while (0)
+
+/* These are listed in *rough* order of decreasing usefulness and
+   increasing noise level. */
+#define PVR2_TRACE_INFO       (1 <<  0) // Normal messages
+#define PVR2_TRACE_ERROR_LEGS (1 <<  1) // error messages
+#define PVR2_TRACE_TOLERANCE  (1 <<  2) // track tolerance-affected errors
+#define PVR2_TRACE_TRAP       (1 <<  3) // Trap & report misbehavior from app
+#define PVR2_TRACE_INIT       (1 <<  4) // misc initialization steps
+#define PVR2_TRACE_START_STOP (1 <<  5) // Streaming start / stop
+#define PVR2_TRACE_CTL        (1 <<  6) // commit of control changes
+#define PVR2_TRACE_DEBUG      (1 <<  7) // Temporary debug code
+#define PVR2_TRACE_EEPROM     (1 <<  8) // eeprom parsing / report
+#define PVR2_TRACE_STRUCT     (1 <<  9) // internal struct creation
+#define PVR2_TRACE_OPEN_CLOSE (1 << 10) // application open / close
+#define PVR2_TRACE_CREG       (1 << 11) // Main critical region entry / exit
+#define PVR2_TRACE_SYSFS      (1 << 12) // Sysfs driven I/O
+#define PVR2_TRACE_FIRMWARE   (1 << 13) // firmware upload actions
+#define PVR2_TRACE_CHIPS      (1 << 14) // chip broadcast operation
+#define PVR2_TRACE_I2C        (1 << 15) // I2C related stuff
+#define PVR2_TRACE_I2C_CMD    (1 << 16) // Software commands to I2C modules
+#define PVR2_TRACE_I2C_CORE   (1 << 17) // I2C core debugging
+#define PVR2_TRACE_I2C_TRAF   (1 << 18) // I2C traffic through the adapter
+#define PVR2_TRACE_V4LIOCTL   (1 << 19) // v4l ioctl details
+#define PVR2_TRACE_ENCODER    (1 << 20) // mpeg2 encoder operation
+#define PVR2_TRACE_BUF_POOL   (1 << 21) // Track buffer pool management
+#define PVR2_TRACE_BUF_FLOW   (1 << 22) // Track buffer flow in system
+#define PVR2_TRACE_DATA_FLOW  (1 << 23) // Track data flow
+#define PVR2_TRACE_DEBUGIFC   (1 << 24) // Debug interface actions
+#define PVR2_TRACE_GPIO       (1 << 25) // GPIO state bit changes
+
+
+#endif /* __PVRUSB2_HDW_INTERNAL_H */
+
+/*
+  Stuff for Emacs to see, in order to encourage consistent editing style:
+  *** Local Variables: ***
+  *** mode: c ***
+  *** fill-column: 75 ***
+  *** tab-width: 8 ***
+  *** c-basic-offset: 8 ***
+  *** End: ***
+  */
diff --git a/drivers/media/video/pvrusb2/pvrusb2-debugifc.c b/drivers/media/video/pvrusb2/pvrusb2-debugifc.c
new file mode 100644
index 000000000..f985f00d8
--- /dev/null
+++ b/drivers/media/video/pvrusb2/pvrusb2-debugifc.c
@@ -0,0 +1,478 @@
+/*
+ *
+ *  $Id$
+ *
+ *  Copyright (C) 2005 Mike Isely <isely@pobox.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
+ *
+ *  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/string.h>
+#include <linux/slab.h>
+#include "pvrusb2-debugifc.h"
+#include "pvrusb2-hdw.h"
+#include "pvrusb2-debug.h"
+#include "pvrusb2-i2c-core.h"
+
+struct debugifc_mask_item {
+	const char *name;
+	unsigned long msk;
+};
+
+static struct debugifc_mask_item mask_items[] = {
+	{"ENC_FIRMWARE",(1<<PVR2_SUBSYS_B_ENC_FIRMWARE)},
+	{"ENC_CFG",(1<<PVR2_SUBSYS_B_ENC_CFG)},
+	{"DIG_RUN",(1<<PVR2_SUBSYS_B_DIGITIZER_RUN)},
+	{"USB_RUN",(1<<PVR2_SUBSYS_B_USBSTREAM_RUN)},
+	{"ENC_RUN",(1<<PVR2_SUBSYS_B_ENC_RUN)},
+};
+
+
+static unsigned int debugifc_count_whitespace(const char *buf,
+					      unsigned int count)
+{
+	unsigned int scnt;
+	char ch;
+
+	for (scnt = 0; scnt < count; scnt++) {
+		ch = buf[scnt];
+		if (ch == ' ') continue;
+		if (ch == '\t') continue;
+		if (ch == '\n') continue;
+		break;
+	}
+	return scnt;
+}
+
+
+static unsigned int debugifc_count_nonwhitespace(const char *buf,
+						 unsigned int count)
+{
+	unsigned int scnt;
+	char ch;
+
+	for (scnt = 0; scnt < count; scnt++) {
+		ch = buf[scnt];
+		if (ch == ' ') break;
+		if (ch == '\t') break;
+		if (ch == '\n') break;
+	}
+	return scnt;
+}
+
+
+static unsigned int debugifc_isolate_word(const char *buf,unsigned int count,
+					  const char **wstrPtr,
+					  unsigned int *wlenPtr)
+{
+	const char *wptr;
+	unsigned int consume_cnt = 0;
+	unsigned int wlen;
+	unsigned int scnt;
+
+	wptr = NULL;
+	wlen = 0;
+	scnt = debugifc_count_whitespace(buf,count);
+	consume_cnt += scnt; count -= scnt; buf += scnt;
+	if (!count) goto done;
+
+	scnt = debugifc_count_nonwhitespace(buf,count);
+	if (!scnt) goto done;
+	wptr = buf;
+	wlen = scnt;
+	consume_cnt += scnt; count -= scnt; buf += scnt;
+
+ done:
+	*wstrPtr = wptr;
+	*wlenPtr = wlen;
+	return consume_cnt;
+}
+
+
+static int debugifc_parse_unsigned_number(const char *buf,unsigned int count,
+					  u32 *num_ptr)
+{
+	u32 result = 0;
+	u32 val;
+	int ch;
+	int radix = 10;
+	if ((count >= 2) && (buf[0] == '0') &&
+	    ((buf[1] == 'x') || (buf[1] == 'X'))) {
+		radix = 16;
+		count -= 2;
+		buf += 2;
+	} else if ((count >= 1) && (buf[0] == '0')) {
+		radix = 8;
+	}
+
+	while (count--) {
+		ch = *buf++;
+		if ((ch >= '0') && (ch <= '9')) {
+			val = ch - '0';
+		} else if ((ch >= 'a') && (ch <= 'f')) {
+			val = ch - 'a' + 10;
+		} else if ((ch >= 'A') && (ch <= 'F')) {
+			val = ch - 'A' + 10;
+		} else {
+			return -EINVAL;
+		}
+		if (val >= radix) return -EINVAL;
+		result *= radix;
+		result += val;
+	}
+	*num_ptr = result;
+	return 0;
+}
+
+
+static int debugifc_match_keyword(const char *buf,unsigned int count,
+				  const char *keyword)
+{
+	unsigned int kl;
+	if (!keyword) return 0;
+	kl = strlen(keyword);
+	if (kl != count) return 0;
+	return !memcmp(buf,keyword,kl);
+}
+
+
+static unsigned long debugifc_find_mask(const char *buf,unsigned int count)
+{
+	struct debugifc_mask_item *mip;
+	unsigned int idx;
+	for (idx = 0; idx < sizeof(mask_items)/sizeof(mask_items[0]); idx++) {
+		mip = mask_items + idx;
+		if (debugifc_match_keyword(buf,count,mip->name)) {
+			return mip->msk;
+		}
+	}
+	return 0;
+}
+
+
+static int debugifc_print_mask(char *buf,unsigned int sz,
+			       unsigned long msk,unsigned long val)
+{
+	struct debugifc_mask_item *mip;
+	unsigned int idx;
+	int bcnt = 0;
+	int ccnt;
+	for (idx = 0; idx < sizeof(mask_items)/sizeof(mask_items[0]); idx++) {
+		mip = mask_items + idx;
+		if (!(mip->msk & msk)) continue;
+		ccnt = scnprintf(buf,sz,"%s%c%s",
+				 (bcnt ? " " : ""),
+				 ((mip->msk & val) ? '+' : '-'),
+				 mip->name);
+		sz -= ccnt;
+		buf += ccnt;
+		bcnt += ccnt;
+	}
+	return bcnt;
+}
+
+static unsigned int debugifc_parse_subsys_mask(const char *buf,
+					       unsigned int count,
+					       unsigned long *mskPtr,
+					       unsigned long *valPtr)
+{
+	const char *wptr;
+	unsigned int consume_cnt = 0;
+	unsigned int scnt;
+	unsigned int wlen;
+	int mode;
+	unsigned long m1,msk,val;
+
+	msk = 0;
+	val = 0;
+
+	while (count) {
+		scnt = debugifc_isolate_word(buf,count,&wptr,&wlen);
+		if (!scnt) break;
+		consume_cnt += scnt; count -= scnt; buf += scnt;
+		if (!wptr) break;
+
+		mode = 0;
+		if (wlen) switch (wptr[0]) {
+		case '+':
+			wptr++;
+			wlen--;
+			break;
+		case '-':
+			mode = 1;
+			wptr++;
+			wlen--;
+			break;
+		}
+		if (!wlen) continue;
+		m1 = debugifc_find_mask(wptr,wlen);
+		if (!m1) break;
+		msk |= m1;
+		if (!mode) val |= m1;
+	}
+	*mskPtr = msk;
+	*valPtr = val;
+	return consume_cnt;
+}
+
+
+int pvr2_debugifc_print_info(struct pvr2_hdw *hdw,char *buf,unsigned int acnt)
+{
+	int bcnt = 0;
+	int ccnt;
+	struct pvr2_hdw_debug_info dbg;
+
+	pvr2_hdw_get_debug_info(hdw,&dbg);
+
+	ccnt = scnprintf(buf,acnt,"big lock %s; ctl lock %s",
+			 (dbg.big_lock_held ? "held" : "free"),
+			 (dbg.ctl_lock_held ? "held" : "free"));
+	bcnt += ccnt; acnt -= ccnt; buf += ccnt;
+	if (dbg.ctl_lock_held) {
+		ccnt = scnprintf(buf,acnt,"; cmd_state=%d cmd_code=%d"
+				 " cmd_wlen=%d cmd_rlen=%d"
+				 " wpend=%d rpend=%d tmout=%d rstatus=%d"
+				 " wstatus=%d",
+				 dbg.cmd_debug_state,dbg.cmd_code,
+				 dbg.cmd_debug_write_len,
+				 dbg.cmd_debug_read_len,
+				 dbg.cmd_debug_write_pend,
+				 dbg.cmd_debug_read_pend,
+				 dbg.cmd_debug_timeout,
+				 dbg.cmd_debug_rstatus,
+				 dbg.cmd_debug_wstatus);
+		bcnt += ccnt; acnt -= ccnt; buf += ccnt;
+	}
+	ccnt = scnprintf(buf,acnt,"\n");
+	bcnt += ccnt; acnt -= ccnt; buf += ccnt;
+	ccnt = scnprintf(
+		buf,acnt,"driver flags: %s %s %s\n",
+		(dbg.flag_init_ok ? "initialized" : "uninitialized"),
+		(dbg.flag_ok ? "ok" : "fail"),
+		(dbg.flag_disconnected ? "disconnected" : "connected"));
+	bcnt += ccnt; acnt -= ccnt; buf += ccnt;
+	ccnt = scnprintf(buf,acnt,"Subsystems enabled / configured: ");
+	bcnt += ccnt; acnt -= ccnt; buf += ccnt;
+	ccnt = debugifc_print_mask(buf,acnt,dbg.subsys_flags,dbg.subsys_flags);
+	bcnt += ccnt; acnt -= ccnt; buf += ccnt;
+	ccnt = scnprintf(buf,acnt,"\n");
+	bcnt += ccnt; acnt -= ccnt; buf += ccnt;
+	ccnt = scnprintf(buf,acnt,"Subsystems disabled / unconfigured: ");
+	bcnt += ccnt; acnt -= ccnt; buf += ccnt;
+	ccnt = debugifc_print_mask(buf,acnt,~dbg.subsys_flags,dbg.subsys_flags);
+	bcnt += ccnt; acnt -= ccnt; buf += ccnt;
+	ccnt = scnprintf(buf,acnt,"\n");
+	bcnt += ccnt; acnt -= ccnt; buf += ccnt;
+
+	ccnt = scnprintf(buf,acnt,"Attached I2C modules:\n");
+	bcnt += ccnt; acnt -= ccnt; buf += ccnt;
+	ccnt = pvr2_i2c_report(hdw,buf,acnt);
+	bcnt += ccnt; acnt -= ccnt; buf += ccnt;
+
+	return bcnt;
+}
+
+
+int pvr2_debugifc_print_status(struct pvr2_hdw *hdw,
+			       char *buf,unsigned int acnt)
+{
+	int bcnt = 0;
+	int ccnt;
+	unsigned long msk;
+	int ret;
+	u32 gpio_dir,gpio_in,gpio_out;
+
+	ret = pvr2_hdw_is_hsm(hdw);
+	ccnt = scnprintf(buf,acnt,"USB link speed: %s\n",
+			 (ret < 0 ? "FAIL" : (ret ? "high" : "full")));
+	bcnt += ccnt; acnt -= ccnt; buf += ccnt;
+
+	gpio_dir = 0; gpio_in = 0; gpio_out = 0;
+	pvr2_hdw_gpio_get_dir(hdw,&gpio_dir);
+	pvr2_hdw_gpio_get_out(hdw,&gpio_out);
+	pvr2_hdw_gpio_get_in(hdw,&gpio_in);
+	ccnt = scnprintf(buf,acnt,"GPIO state: dir=0x%x in=0x%x out=0x%x\n",
+			 gpio_dir,gpio_in,gpio_out);
+	bcnt += ccnt; acnt -= ccnt; buf += ccnt;
+
+	ccnt = scnprintf(buf,acnt,"Streaming is %s\n",
+			 pvr2_hdw_get_streaming(hdw) ? "on" : "off");
+	bcnt += ccnt; acnt -= ccnt; buf += ccnt;
+
+	msk = pvr2_hdw_subsys_get(hdw);
+	ccnt = scnprintf(buf,acnt,"Subsystems enabled / configured: ");
+	bcnt += ccnt; acnt -= ccnt; buf += ccnt;
+	ccnt = debugifc_print_mask(buf,acnt,msk,msk);
+	bcnt += ccnt; acnt -= ccnt; buf += ccnt;
+	ccnt = scnprintf(buf,acnt,"\n");
+	bcnt += ccnt; acnt -= ccnt; buf += ccnt;
+	ccnt = scnprintf(buf,acnt,"Subsystems disabled / unconfigured: ");
+	bcnt += ccnt; acnt -= ccnt; buf += ccnt;
+	ccnt = debugifc_print_mask(buf,acnt,~msk,msk);
+	bcnt += ccnt; acnt -= ccnt; buf += ccnt;
+	ccnt = scnprintf(buf,acnt,"\n");
+	bcnt += ccnt; acnt -= ccnt; buf += ccnt;
+
+	msk = pvr2_hdw_subsys_stream_get(hdw);
+	ccnt = scnprintf(buf,acnt,"Subsystems stopped on stream shutdown: ");
+	bcnt += ccnt; acnt -= ccnt; buf += ccnt;
+	ccnt = debugifc_print_mask(buf,acnt,msk,msk);
+	bcnt += ccnt; acnt -= ccnt; buf += ccnt;
+	ccnt = scnprintf(buf,acnt,"\n");
+	bcnt += ccnt; acnt -= ccnt; buf += ccnt;
+
+	return bcnt;
+}
+
+
+static int pvr2_debugifc_do1cmd(struct pvr2_hdw *hdw,const char *buf,
+				unsigned int count)
+{
+	const char *wptr;
+	unsigned int wlen;
+	unsigned int scnt;
+
+	scnt = debugifc_isolate_word(buf,count,&wptr,&wlen);
+	if (!scnt) return 0;
+	count -= scnt; buf += scnt;
+	if (!wptr) return 0;
+
+	pvr2_trace(PVR2_TRACE_DEBUGIFC,"debugifc cmd: \"%.*s\"",wlen,wptr);
+	if (debugifc_match_keyword(wptr,wlen,"reset")) {
+		scnt = debugifc_isolate_word(buf,count,&wptr,&wlen);
+		if (!scnt) return -EINVAL;
+		count -= scnt; buf += scnt;
+		if (!wptr) return -EINVAL;
+		if (debugifc_match_keyword(wptr,wlen,"cpu")) {
+			pvr2_hdw_cpureset_assert(hdw,!0);
+			pvr2_hdw_cpureset_assert(hdw,0);
+			return 0;
+		} else if (debugifc_match_keyword(wptr,wlen,"bus")) {
+			pvr2_hdw_device_reset(hdw);
+		} else if (debugifc_match_keyword(wptr,wlen,"soft")) {
+			return pvr2_hdw_cmd_powerup(hdw);
+		} else if (debugifc_match_keyword(wptr,wlen,"deep")) {
+			return pvr2_hdw_cmd_deep_reset(hdw);
+		} else if (debugifc_match_keyword(wptr,wlen,"firmware")) {
+			return pvr2_upload_firmware2(hdw);
+		} else if (debugifc_match_keyword(wptr,wlen,"decoder")) {
+			return pvr2_hdw_cmd_decoder_reset(hdw);
+		}
+		return -EINVAL;
+	} else if (debugifc_match_keyword(wptr,wlen,"subsys_flags")) {
+		unsigned long msk = 0;
+		unsigned long val = 0;
+		if (debugifc_parse_subsys_mask(buf,count,&msk,&val) != count) {
+			pvr2_trace(PVR2_TRACE_DEBUGIFC,
+				   "debugifc parse error on subsys mask");
+			return -EINVAL;
+		}
+		pvr2_hdw_subsys_bit_chg(hdw,msk,val);
+		return 0;
+	} else if (debugifc_match_keyword(wptr,wlen,"stream_flags")) {
+		unsigned long msk = 0;
+		unsigned long val = 0;
+		if (debugifc_parse_subsys_mask(buf,count,&msk,&val) != count) {
+			pvr2_trace(PVR2_TRACE_DEBUGIFC,
+				   "debugifc parse error on stream mask");
+			return -EINVAL;
+		}
+		pvr2_hdw_subsys_stream_bit_chg(hdw,msk,val);
+		return 0;
+	} else if (debugifc_match_keyword(wptr,wlen,"cpufw")) {
+		scnt = debugifc_isolate_word(buf,count,&wptr,&wlen);
+		if (!scnt) return -EINVAL;
+		count -= scnt; buf += scnt;
+		if (!wptr) return -EINVAL;
+		if (debugifc_match_keyword(wptr,wlen,"fetch")) {
+			pvr2_hdw_cpufw_set_enabled(hdw,!0);
+			return 0;
+		} else if (debugifc_match_keyword(wptr,wlen,"done")) {
+			pvr2_hdw_cpufw_set_enabled(hdw,0);
+			return 0;
+		} else {
+			return -EINVAL;
+		}
+	} else if (debugifc_match_keyword(wptr,wlen,"gpio")) {
+		int dir_fl = 0;
+		int ret;
+		u32 msk,val;
+		scnt = debugifc_isolate_word(buf,count,&wptr,&wlen);
+		if (!scnt) return -EINVAL;
+		count -= scnt; buf += scnt;
+		if (!wptr) return -EINVAL;
+		if (debugifc_match_keyword(wptr,wlen,"dir")) {
+			dir_fl = !0;
+		} else if (!debugifc_match_keyword(wptr,wlen,"out")) {
+			return -EINVAL;
+		}
+		scnt = debugifc_isolate_word(buf,count,&wptr,&wlen);
+		if (!scnt) return -EINVAL;
+		count -= scnt; buf += scnt;
+		if (!wptr) return -EINVAL;
+		ret = debugifc_parse_unsigned_number(wptr,wlen,&msk);
+		if (ret) return ret;
+		scnt = debugifc_isolate_word(buf,count,&wptr,&wlen);
+		if (wptr) {
+			ret = debugifc_parse_unsigned_number(wptr,wlen,&val);
+			if (ret) return ret;
+		} else {
+			val = msk;
+			msk = 0xffffffff;
+		}
+		if (dir_fl) {
+			ret = pvr2_hdw_gpio_chg_dir(hdw,msk,val);
+		} else {
+			ret = pvr2_hdw_gpio_chg_out(hdw,msk,val);
+		}
+		return ret;
+	}
+	pvr2_trace(PVR2_TRACE_DEBUGIFC,
+		   "debugifc failed to recognize cmd: \"%.*s\"",wlen,wptr);
+	return -EINVAL;
+}
+
+
+int pvr2_debugifc_docmd(struct pvr2_hdw *hdw,const char *buf,
+			unsigned int count)
+{
+	unsigned int bcnt = 0;
+	int ret;
+
+	while (count) {
+		for (bcnt = 0; bcnt < count; bcnt++) {
+			if (buf[bcnt] == '\n') break;
+		}
+
+		ret = pvr2_debugifc_do1cmd(hdw,buf,bcnt);
+		if (ret < 0) return ret;
+		if (bcnt < count) bcnt++;
+		buf += bcnt;
+		count -= bcnt;
+	}
+
+	return 0;
+}
+
+
+/*
+  Stuff for Emacs to see, in order to encourage consistent editing style:
+  *** Local Variables: ***
+  *** mode: c ***
+  *** fill-column: 75 ***
+  *** tab-width: 8 ***
+  *** c-basic-offset: 8 ***
+  *** End: ***
+  */
diff --git a/drivers/media/video/pvrusb2/pvrusb2-debugifc.h b/drivers/media/video/pvrusb2/pvrusb2-debugifc.h
new file mode 100644
index 000000000..990b02d35
--- /dev/null
+++ b/drivers/media/video/pvrusb2/pvrusb2-debugifc.h
@@ -0,0 +1,53 @@
+/*
+ *
+ *  $Id$
+ *
+ *  Copyright (C) 2005 Mike Isely <isely@pobox.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
+ *
+ *  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 __PVRUSB2_DEBUGIFC_H
+#define __PVRUSB2_DEBUGIFC_H
+
+struct pvr2_hdw;
+
+/* Non-intrusively print some useful debugging info from inside the
+   driver.  This should work even if the driver appears to be
+   wedged. */
+int pvr2_debugifc_print_info(struct pvr2_hdw *,
+			     char *buf_ptr,unsigned int buf_size);
+
+/* Print general status of driver.  This will also trigger a probe of
+   the USB link.  Unlike print_info(), this one synchronizes with the
+   driver so the information should be self-consistent (but it will
+   hang if the driver is wedged). */
+int pvr2_debugifc_print_status(struct pvr2_hdw *,
+			       char *buf_ptr,unsigned int buf_size);
+
+/* Parse a string command into a driver action. */
+int pvr2_debugifc_docmd(struct pvr2_hdw *,
+			const char *buf_ptr,unsigned int buf_size);
+
+#endif /* __PVRUSB2_DEBUGIFC_H */
+
+/*
+  Stuff for Emacs to see, in order to encourage consistent editing style:
+  *** Local Variables: ***
+  *** mode: c ***
+  *** fill-column: 75 ***
+  *** tab-width: 8 ***
+  *** c-basic-offset: 8 ***
+  *** End: ***
+  */
diff --git a/drivers/media/video/pvrusb2/pvrusb2-eeprom.c b/drivers/media/video/pvrusb2/pvrusb2-eeprom.c
new file mode 100644
index 000000000..6cff8e75f
--- /dev/null
+++ b/drivers/media/video/pvrusb2/pvrusb2-eeprom.c
@@ -0,0 +1,164 @@
+/*
+ *
+ *  $Id$
+ *
+ *  Copyright (C) 2005 Mike Isely <isely@pobox.com>
+ *  Copyright (C) 2004 Aurelien Alleaume <slts@free.fr>
+ *
+ *  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
+ *
+ *  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 "pvrusb2-eeprom.h"
+#include "pvrusb2-hdw-internal.h"
+#include "pvrusb2-debug.h"
+
+#define trace_eeprom(...) pvr2_trace(PVR2_TRACE_EEPROM,__VA_ARGS__)
+
+
+
+/*
+
+   Read and analyze data in the eeprom.  Use tveeprom to figure out
+   the packet structure, since this is another Hauppauge device and
+   internally it has a family resemblence to ivtv-type devices
+
+*/
+
+#include <media/tveeprom.h>
+
+/* We seem to only be interested in the last 128 bytes of the EEPROM */
+#define EEPROM_SIZE 128
+
+/* Grab EEPROM contents, needed for direct method. */
+static u8 *pvr2_eeprom_fetch(struct pvr2_hdw *hdw)
+{
+	struct i2c_msg msg[2];
+	u8 *eeprom;
+	u8 iadd[2];
+	u8 addr;
+	u16 eepromSize;
+	unsigned int offs;
+	int ret;
+	int mode16 = 0;
+	unsigned pcnt,tcnt;
+	eeprom = kmalloc(EEPROM_SIZE,GFP_KERNEL);
+	if (!eeprom) {
+		pvr2_trace(PVR2_TRACE_ERROR_LEGS,
+			   "Failed to allocate memory"
+			   " required to read eeprom");
+		return NULL;
+	}
+
+	trace_eeprom("Value for eeprom addr from controller was 0x%x",
+		     hdw->eeprom_addr);
+	addr = hdw->eeprom_addr;
+	/* Seems that if the high bit is set, then the *real* eeprom
+	   address is shifted right now bit position (noticed this in
+	   newer PVR USB2 hardware) */
+	if (addr & 0x80) addr >>= 1;
+
+	/* FX2 documentation states that a 16bit-addressed eeprom is
+	   expected if the I2C address is an odd number (yeah, this is
+	   strange but it's what they do) */
+	mode16 = (addr & 1);
+	eepromSize = (mode16 ? 4096 : 256);
+	trace_eeprom("Examining %d byte eeprom at location 0x%x"
+		     " using %d bit addressing",eepromSize,addr,
+		     mode16 ? 16 : 8);
+
+	msg[0].addr = addr;
+	msg[0].flags = 0;
+	msg[0].len = mode16 ? 2 : 1;
+	msg[0].buf = iadd;
+	msg[1].addr = addr;
+	msg[1].flags = I2C_M_RD;
+
+	/* We have to do the actual eeprom data fetch ourselves, because
+	   (1) we're only fetching part of the eeprom, and (2) if we were
+	   getting the whole thing our I2C driver can't grab it in one
+	   pass - which is what tveeprom is otherwise going to attempt */
+	memset(eeprom,0,EEPROM_SIZE);
+	for (tcnt = 0; tcnt < EEPROM_SIZE; tcnt += pcnt) {
+		pcnt = 16;
+		if (pcnt + tcnt > EEPROM_SIZE) pcnt = EEPROM_SIZE-tcnt;
+		offs = tcnt + (eepromSize - EEPROM_SIZE);
+		if (mode16) {
+			iadd[0] = offs >> 8;
+			iadd[1] = offs;
+		} else {
+			iadd[0] = offs;
+		}
+		msg[1].len = pcnt;
+		msg[1].buf = eeprom+tcnt;
+		if ((ret = i2c_transfer(
+			     &hdw->i2c_adap,
+			     msg,sizeof(msg)/sizeof(msg[0]))) != 2) {
+			pvr2_trace(PVR2_TRACE_ERROR_LEGS,
+				   "eeprom fetch set offs err=%d",ret);
+			kfree(eeprom);
+			return NULL;
+		}
+	}
+	return eeprom;
+}
+
+
+/* Directly call eeprom analysis function within tveeprom. */
+int pvr2_eeprom_analyze(struct pvr2_hdw *hdw)
+{
+	u8 *eeprom;
+	struct tveeprom tvdata;
+
+	memset(&tvdata,0,sizeof(tvdata));
+
+	eeprom = pvr2_eeprom_fetch(hdw);
+	if (!eeprom) return -EINVAL;
+
+	{
+		struct i2c_client fake_client;
+		/* Newer version expects a useless client interface */
+		fake_client.addr = hdw->eeprom_addr;
+		fake_client.adapter = &hdw->i2c_adap;
+		tveeprom_hauppauge_analog(&fake_client,&tvdata,eeprom);
+	}
+
+	trace_eeprom("eeprom assumed v4l tveeprom module");
+	trace_eeprom("eeprom direct call results:");
+	trace_eeprom("has_radio=%d",tvdata.has_radio);
+	trace_eeprom("tuner_type=%d",tvdata.tuner_type);
+	trace_eeprom("tuner_formats=0x%x",tvdata.tuner_formats);
+	trace_eeprom("audio_processor=%d",tvdata.audio_processor);
+	trace_eeprom("model=%d",tvdata.model);
+	trace_eeprom("revision=%d",tvdata.revision);
+	trace_eeprom("serial_number=%d",tvdata.serial_number);
+	trace_eeprom("rev_str=%s",tvdata.rev_str);
+	hdw->tuner_type = tvdata.tuner_type;
+	hdw->serial_number = tvdata.serial_number;
+	hdw->std_mask_eeprom = tvdata.tuner_formats;
+
+	kfree(eeprom);
+
+	return 0;
+}
+
+/*
+  Stuff for Emacs to see, in order to encourage consistent editing style:
+  *** Local Variables: ***
+  *** mode: c ***
+  *** fill-column: 70 ***
+  *** tab-width: 8 ***
+  *** c-basic-offset: 8 ***
+  *** End: ***
+  */
diff --git a/drivers/media/video/pvrusb2/pvrusb2-eeprom.h b/drivers/media/video/pvrusb2/pvrusb2-eeprom.h
new file mode 100644
index 000000000..84242975d
--- /dev/null
+++ b/drivers/media/video/pvrusb2/pvrusb2-eeprom.h
@@ -0,0 +1,40 @@
+/*
+ *
+ *  $Id$
+ *
+ *  Copyright (C) 2005 Mike Isely <isely@pobox.com>
+ *  Copyright (C) 2004 Aurelien Alleaume <slts@free.fr>
+ *
+ *  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
+ *
+ *  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 __PVRUSB2_EEPROM_H
+#define __PVRUSB2_EEPROM_H
+
+struct pvr2_hdw;
+
+int pvr2_eeprom_analyze(struct pvr2_hdw *);
+
+#endif /* __PVRUSB2_EEPROM_H */
+
+/*
+  Stuff for Emacs to see, in order to encourage consistent editing style:
+  *** Local Variables: ***
+  *** mode: c ***
+  *** fill-column: 70 ***
+  *** tab-width: 8 ***
+  *** c-basic-offset: 8 ***
+  *** End: ***
+  */
diff --git a/drivers/media/video/pvrusb2/pvrusb2-encoder.c b/drivers/media/video/pvrusb2/pvrusb2-encoder.c
new file mode 100644
index 000000000..18a707350
--- /dev/null
+++ b/drivers/media/video/pvrusb2/pvrusb2-encoder.c
@@ -0,0 +1,418 @@
+/*
+ *
+ *  $Id$
+ *
+ *  Copyright (C) 2005 Mike Isely <isely@pobox.com>
+ *  Copyright (C) 2004 Aurelien Alleaume <slts@free.fr>
+ *
+ *  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
+ *
+ *  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/device.h>   // for linux/firmware.h
+#include <linux/firmware.h>
+#include "pvrusb2-util.h"
+#include "pvrusb2-encoder.h"
+#include "pvrusb2-hdw-internal.h"
+#include "pvrusb2-debug.h"
+
+
+
+/* Firmware mailbox flags - definitions found from ivtv */
+#define IVTV_MBOX_FIRMWARE_DONE 0x00000004
+#define IVTV_MBOX_DRIVER_DONE 0x00000002
+#define IVTV_MBOX_DRIVER_BUSY 0x00000001
+
+
+static int pvr2_encoder_write_words(struct pvr2_hdw *hdw,
+				    const u32 *data, unsigned int dlen)
+{
+	unsigned int idx;
+	int ret;
+	unsigned int offs = 0;
+	unsigned int chunkCnt;
+
+	/*
+
+	Format: First byte must be 0x01.  Remaining 32 bit words are
+	spread out into chunks of 7 bytes each, little-endian ordered,
+	offset at zero within each 2 blank bytes following and a
+	single byte that is 0x44 plus the offset of the word.  Repeat
+	request for additional words, with offset adjusted
+	accordingly.
+
+	*/
+	while (dlen) {
+		chunkCnt = 8;
+		if (chunkCnt > dlen) chunkCnt = dlen;
+		memset(hdw->cmd_buffer,0,sizeof(hdw->cmd_buffer));
+		hdw->cmd_buffer[0] = 0x01;
+		for (idx = 0; idx < chunkCnt; idx++) {
+			hdw->cmd_buffer[1+(idx*7)+6] = 0x44 + idx + offs;
+			PVR2_DECOMPOSE_LE(hdw->cmd_buffer, 1+(idx*7),
+					  data[idx]);
+		}
+		ret = pvr2_send_request(hdw,
+					hdw->cmd_buffer,1+(chunkCnt*7),
+					NULL,0);
+		if (ret) return ret;
+		data += chunkCnt;
+		dlen -= chunkCnt;
+		offs += chunkCnt;
+	}
+
+	return 0;
+}
+
+
+static int pvr2_encoder_read_words(struct pvr2_hdw *hdw,int statusFl,
+				   u32 *data, unsigned int dlen)
+{
+	unsigned int idx;
+	int ret;
+	unsigned int offs = 0;
+	unsigned int chunkCnt;
+
+	/*
+
+	Format: First byte must be 0x02 (status check) or 0x28 (read
+	back block of 32 bit words).  Next 6 bytes must be zero,
+	followed by a single byte of 0x44+offset for portion to be
+	read.  Returned data is packed set of 32 bits words that were
+	read.
+
+	*/
+
+	while (dlen) {
+		chunkCnt = 16;
+		if (chunkCnt > dlen) chunkCnt = dlen;
+		memset(hdw->cmd_buffer,0,sizeof(hdw->cmd_buffer));
+		hdw->cmd_buffer[0] = statusFl ? 0x02 : 0x28;
+		hdw->cmd_buffer[7] = 0x44 + offs;
+		ret = pvr2_send_request(hdw,
+					hdw->cmd_buffer,8,
+					hdw->cmd_buffer,chunkCnt * 4);
+		if (ret) return ret;
+
+		for (idx = 0; idx < chunkCnt; idx++) {
+			data[idx] = PVR2_COMPOSE_LE(hdw->cmd_buffer,idx*4);
+		}
+		data += chunkCnt;
+		dlen -= chunkCnt;
+		offs += chunkCnt;
+	}
+
+	return 0;
+}
+
+
+/* This prototype is set up to be compatible with the
+   cx2341x_mbox_func prototype in cx2341x.h, which should be in
+   kernels 2.6.18 or later.  We do this so that we can enable
+   cx2341x.ko to write to our encoder (by handing it a pointer to this
+   function).  For earlier kernels this doesn't really matter. */
+static int pvr2_encoder_cmd(void *ctxt,
+			    int cmd,
+			    int arg_cnt_send,
+			    int arg_cnt_recv,
+			    u32 *argp)
+{
+	unsigned int poll_count;
+	int ret = 0;
+	unsigned int idx;
+	/* These sizes look to be limited by the FX2 firmware implementation */
+	u32 wrData[16];
+	u32 rdData[16];
+	struct pvr2_hdw *hdw = (struct pvr2_hdw *)ctxt;
+
+
+	/*
+
+	The encoder seems to speak entirely using blocks 32 bit words.
+	In ivtv driver terms, this is a mailbox which we populate with
+	data and watch what the hardware does with it.  The first word
+	is a set of flags used to control the transaction, the second
+	word is the command to execute, the third byte is zero (ivtv
+	driver suggests that this is some kind of return value), and
+	the fourth byte is a specified timeout (windows driver always
+	uses 0x00060000 except for one case when it is zero).  All
+	successive words are the argument words for the command.
+
+	First, write out the entire set of words, with the first word
+	being zero.
+
+	Next, write out just the first word again, but set it to
+	IVTV_MBOX_DRIVER_DONE | IVTV_DRIVER_BUSY this time (which
+	probably means "go").
+
+	Next, read back 16 words as status.  Check the first word,
+	which should have IVTV_MBOX_FIRMWARE_DONE set.  If however
+	that bit is not set, then the command isn't done so repeat the
+	read.
+
+	Next, read back 32 words and compare with the original
+	arugments.  Hopefully they will match.
+
+	Finally, write out just the first word again, but set it to
+	0x0 this time (which probably means "idle").
+
+	*/
+
+	if (arg_cnt_send > (sizeof(wrData)/sizeof(wrData[0]))-4) {
+		pvr2_trace(
+			PVR2_TRACE_ERROR_LEGS,
+			"Failed to write cx23416 command"
+			" - too many input arguments"
+			" (was given %u limit %u)",
+			arg_cnt_send,
+			(unsigned int)(sizeof(wrData)/sizeof(wrData[0])) - 4);
+		return -EINVAL;
+	}
+
+	if (arg_cnt_recv > (sizeof(rdData)/sizeof(rdData[0]))-4) {
+		pvr2_trace(
+			PVR2_TRACE_ERROR_LEGS,
+			"Failed to write cx23416 command"
+			" - too many return arguments"
+			" (was given %u limit %u)",
+			arg_cnt_recv,
+			(unsigned int)(sizeof(rdData)/sizeof(rdData[0])) - 4);
+		return -EINVAL;
+	}
+
+
+	LOCK_TAKE(hdw->ctl_lock); do {
+
+		wrData[0] = 0;
+		wrData[1] = cmd;
+		wrData[2] = 0;
+		wrData[3] = 0x00060000;
+		for (idx = 0; idx < arg_cnt_send; idx++) {
+			wrData[idx+4] = argp[idx];
+		}
+		for (; idx < (sizeof(wrData)/sizeof(wrData[0]))-4; idx++) {
+			wrData[idx+4] = 0;
+		}
+
+		ret = pvr2_encoder_write_words(hdw,wrData,idx);
+		if (ret) break;
+		wrData[0] = IVTV_MBOX_DRIVER_DONE|IVTV_MBOX_DRIVER_BUSY;
+		ret = pvr2_encoder_write_words(hdw,wrData,1);
+		if (ret) break;
+		poll_count = 0;
+		while (1) {
+			if (poll_count < 10000000) poll_count++;
+			ret = pvr2_encoder_read_words(hdw,!0,rdData,1);
+			if (ret) break;
+			if (rdData[0] & IVTV_MBOX_FIRMWARE_DONE) {
+				break;
+			}
+			if (poll_count == 100) {
+				pvr2_trace(
+					PVR2_TRACE_ERROR_LEGS,
+					"***WARNING*** device's encoder"
+					" appears to be stuck"
+					" (status=0%08x)",rdData[0]);
+				pvr2_trace(
+					PVR2_TRACE_ERROR_LEGS,
+					"Encoder command: 0x%02x",cmd);
+				for (idx = 4; idx < arg_cnt_send; idx++) {
+					pvr2_trace(
+						PVR2_TRACE_ERROR_LEGS,
+						"Encoder arg%d: 0x%08x",
+						idx-3,wrData[idx]);
+				}
+				pvr2_trace(
+					PVR2_TRACE_ERROR_LEGS,
+					"Giving up waiting."
+					"  It is likely that"
+					" this is a bad idea...");
+				ret = -EBUSY;
+				break;
+			}
+		}
+		if (ret) break;
+		wrData[0] = 0x7;
+		ret = pvr2_encoder_read_words(
+			hdw,0,rdData,
+			sizeof(rdData)/sizeof(rdData[0]));
+		if (ret) break;
+		for (idx = 0; idx < arg_cnt_recv; idx++) {
+			argp[idx] = rdData[idx+4];
+		}
+
+		wrData[0] = 0x0;
+		ret = pvr2_encoder_write_words(hdw,wrData,1);
+		if (ret) break;
+
+	} while(0); LOCK_GIVE(hdw->ctl_lock);
+
+	return ret;
+}
+
+
+static int pvr2_encoder_vcmd(struct pvr2_hdw *hdw, int cmd,
+			     int args, ...)
+{
+	va_list vl;
+	unsigned int idx;
+	u32 data[12];
+
+	if (args > sizeof(data)/sizeof(data[0])) {
+		pvr2_trace(
+			PVR2_TRACE_ERROR_LEGS,
+			"Failed to write cx23416 command"
+			" - too many arguments"
+			" (was given %u limit %u)",
+			args,(unsigned int)(sizeof(data)/sizeof(data[0])));
+		return -EINVAL;
+	}
+
+	va_start(vl, args);
+	for (idx = 0; idx < args; idx++) {
+		data[idx] = va_arg(vl, u32);
+	}
+	va_end(vl);
+
+	return pvr2_encoder_cmd(hdw,cmd,args,0,data);
+}
+
+int pvr2_encoder_configure(struct pvr2_hdw *hdw)
+{
+	int ret;
+	pvr2_trace(PVR2_TRACE_ENCODER,"pvr2_encoder_configure"
+		   " (cx2341x module)");
+	hdw->enc_ctl_state.port = CX2341X_PORT_STREAMING;
+	hdw->enc_ctl_state.width = hdw->res_hor_val;
+	hdw->enc_ctl_state.height = hdw->res_ver_val;
+	hdw->enc_ctl_state.is_50hz = ((hdw->std_mask_cur &
+				       (V4L2_STD_NTSC|V4L2_STD_PAL_M)) ?
+				      0 : 1);
+
+	ret = 0;
+
+	if (!ret) ret = pvr2_encoder_vcmd(
+		hdw,CX2341X_ENC_SET_NUM_VSYNC_LINES, 2,
+		0xf0, 0xf0);
+
+	/* setup firmware to notify us about some events (don't know why...) */
+	if (!ret) ret = pvr2_encoder_vcmd(
+		hdw,CX2341X_ENC_SET_EVENT_NOTIFICATION, 4,
+		0, 0, 0x10000000, 0xffffffff);
+
+	if (!ret) ret = pvr2_encoder_vcmd(
+		hdw,CX2341X_ENC_SET_VBI_LINE, 5,
+		0xffffffff,0,0,0,0);
+
+	if (ret) {
+		pvr2_trace(PVR2_TRACE_ERROR_LEGS,
+			   "Failed to configure cx32416");
+		return ret;
+	}
+
+	ret = cx2341x_update(hdw,pvr2_encoder_cmd,
+			     (hdw->enc_cur_valid ? &hdw->enc_cur_state : NULL),
+			     &hdw->enc_ctl_state);
+	if (ret) {
+		pvr2_trace(PVR2_TRACE_ERROR_LEGS,
+			   "Error from cx2341x module code=%d",ret);
+		return ret;
+	}
+
+	ret = 0;
+
+	if (!ret) ret = pvr2_encoder_vcmd(
+		hdw, CX2341X_ENC_INITIALIZE_INPUT, 0);
+
+	if (ret) {
+		pvr2_trace(PVR2_TRACE_ERROR_LEGS,
+			   "Failed to initialize cx32416 video input");
+		return ret;
+	}
+
+	hdw->subsys_enabled_mask |= (1<<PVR2_SUBSYS_B_ENC_CFG);
+	memcpy(&hdw->enc_cur_state,&hdw->enc_ctl_state,
+	       sizeof(struct cx2341x_mpeg_params));
+	hdw->enc_cur_valid = !0;
+	return 0;
+}
+
+
+int pvr2_encoder_start(struct pvr2_hdw *hdw)
+{
+	int status;
+
+	/* unmask some interrupts */
+	pvr2_write_register(hdw, 0x0048, 0xbfffffff);
+
+	/* change some GPIO data */
+	pvr2_hdw_gpio_chg_dir(hdw,0xffffffff,0x00000481);
+	pvr2_hdw_gpio_chg_out(hdw,0xffffffff,0x00000000);
+
+	if (hdw->config == pvr2_config_vbi) {
+		status = pvr2_encoder_vcmd(hdw,CX2341X_ENC_START_CAPTURE,2,
+					   0x01,0x14);
+	} else if (hdw->config == pvr2_config_mpeg) {
+		status = pvr2_encoder_vcmd(hdw,CX2341X_ENC_START_CAPTURE,2,
+					   0,0x13);
+	} else {
+		status = pvr2_encoder_vcmd(hdw,CX2341X_ENC_START_CAPTURE,2,
+					   0,0x13);
+	}
+	if (!status) {
+		hdw->subsys_enabled_mask |= (1<<PVR2_SUBSYS_B_ENC_RUN);
+	}
+	return status;
+}
+
+int pvr2_encoder_stop(struct pvr2_hdw *hdw)
+{
+	int status;
+
+	/* mask all interrupts */
+	pvr2_write_register(hdw, 0x0048, 0xffffffff);
+
+	if (hdw->config == pvr2_config_vbi) {
+		status = pvr2_encoder_vcmd(hdw,CX2341X_ENC_STOP_CAPTURE,3,
+					   0x01,0x01,0x14);
+	} else if (hdw->config == pvr2_config_mpeg) {
+		status = pvr2_encoder_vcmd(hdw,CX2341X_ENC_STOP_CAPTURE,3,
+					   0x01,0,0x13);
+	} else {
+		status = pvr2_encoder_vcmd(hdw,CX2341X_ENC_STOP_CAPTURE,3,
+					   0x01,0,0x13);
+	}
+
+	/* change some GPIO data */
+	/* Note: Bit d7 of dir appears to control the LED.  So we shut it
+	   off here. */
+	pvr2_hdw_gpio_chg_dir(hdw,0xffffffff,0x00000401);
+	pvr2_hdw_gpio_chg_out(hdw,0xffffffff,0x00000000);
+
+	if (!status) {
+		hdw->subsys_enabled_mask &= ~(1<<PVR2_SUBSYS_B_ENC_RUN);
+	}
+	return status;
+}
+
+
+/*
+  Stuff for Emacs to see, in order to encourage consistent editing style:
+  *** Local Variables: ***
+  *** mode: c ***
+  *** fill-column: 70 ***
+  *** tab-width: 8 ***
+  *** c-basic-offset: 8 ***
+  *** End: ***
+  */
diff --git a/drivers/media/video/pvrusb2/pvrusb2-encoder.h b/drivers/media/video/pvrusb2/pvrusb2-encoder.h
new file mode 100644
index 000000000..01b5a0b89
--- /dev/null
+++ b/drivers/media/video/pvrusb2/pvrusb2-encoder.h
@@ -0,0 +1,42 @@
+/*
+ *
+ *  $Id$
+ *
+ *  Copyright (C) 2005 Mike Isely <isely@pobox.com>
+ *  Copyright (C) 2004 Aurelien Alleaume <slts@free.fr>
+ *
+ *  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
+ *
+ *  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 __PVRUSB2_ENCODER_H
+#define __PVRUSB2_ENCODER_H
+
+struct pvr2_hdw;
+
+int pvr2_encoder_configure(struct pvr2_hdw *);
+int pvr2_encoder_start(struct pvr2_hdw *);
+int pvr2_encoder_stop(struct pvr2_hdw *);
+
+#endif /* __PVRUSB2_ENCODER_H */
+
+/*
+  Stuff for Emacs to see, in order to encourage consistent editing style:
+  *** Local Variables: ***
+  *** mode: c ***
+  *** fill-column: 70 ***
+  *** tab-width: 8 ***
+  *** c-basic-offset: 8 ***
+  *** End: ***
+  */
diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h b/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h
new file mode 100644
index 000000000..7dd6c3d83
--- /dev/null
+++ b/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h
@@ -0,0 +1,368 @@
+/*
+ *
+ *  $Id$
+ *
+ *  Copyright (C) 2005 Mike Isely <isely@pobox.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
+ *
+ *  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 __PVRUSB2_HDW_INTERNAL_H
+#define __PVRUSB2_HDW_INTERNAL_H
+
+/*
+
+  This header sets up all the internal structures and definitions needed to
+  track and coordinate the driver's interaction with the hardware.  ONLY
+  source files which actually implement part of that whole circus should be
+  including this header.  Higher levels, like the external layers to the
+  various public APIs (V4L, sysfs, etc) should NOT ever include this
+  private, internal header.  This means that pvrusb2-hdw, pvrusb2-encoder,
+  etc will include this, but pvrusb2-v4l should not.
+
+*/
+
+#include <linux/videodev2.h>
+#include <linux/i2c.h>
+#include <linux/mutex.h>
+#include "pvrusb2-hdw.h"
+#include "pvrusb2-io.h"
+#include <media/cx2341x.h>
+
+/* Legal values for the SRATE state variable */
+#define PVR2_CVAL_SRATE_48 0
+#define PVR2_CVAL_SRATE_44_1 1
+
+/* Legal values for the AUDIOBITRATE state variable */
+#define PVR2_CVAL_AUDIOBITRATE_384 0
+#define PVR2_CVAL_AUDIOBITRATE_320 1
+#define PVR2_CVAL_AUDIOBITRATE_256 2
+#define PVR2_CVAL_AUDIOBITRATE_224 3
+#define PVR2_CVAL_AUDIOBITRATE_192 4
+#define PVR2_CVAL_AUDIOBITRATE_160 5
+#define PVR2_CVAL_AUDIOBITRATE_128 6
+#define PVR2_CVAL_AUDIOBITRATE_112 7
+#define PVR2_CVAL_AUDIOBITRATE_96 8
+#define PVR2_CVAL_AUDIOBITRATE_80 9
+#define PVR2_CVAL_AUDIOBITRATE_64 10
+#define PVR2_CVAL_AUDIOBITRATE_56 11
+#define PVR2_CVAL_AUDIOBITRATE_48 12
+#define PVR2_CVAL_AUDIOBITRATE_32 13
+#define PVR2_CVAL_AUDIOBITRATE_VBR 14
+
+/* Legal values for the AUDIOEMPHASIS state variable */
+#define PVR2_CVAL_AUDIOEMPHASIS_NONE 0
+#define PVR2_CVAL_AUDIOEMPHASIS_50_15 1
+#define PVR2_CVAL_AUDIOEMPHASIS_CCITT 2
+
+/* Legal values for PVR2_CID_HSM */
+#define PVR2_CVAL_HSM_FAIL 0
+#define PVR2_CVAL_HSM_FULL 1
+#define PVR2_CVAL_HSM_HIGH 2
+
+#define PVR2_VID_ENDPOINT        0x84
+#define PVR2_UNK_ENDPOINT        0x86    /* maybe raw yuv ? */
+#define PVR2_VBI_ENDPOINT        0x88
+
+#define PVR2_CTL_BUFFSIZE        64
+
+#define FREQTABLE_SIZE 500
+
+#define LOCK_TAKE(x) do { mutex_lock(&x##_mutex); x##_held = !0; } while (0)
+#define LOCK_GIVE(x) do { x##_held = 0; mutex_unlock(&x##_mutex); } while (0)
+
+struct pvr2_decoder;
+
+typedef int (*pvr2_ctlf_is_dirty)(struct pvr2_ctrl *);
+typedef void (*pvr2_ctlf_clear_dirty)(struct pvr2_ctrl *);
+typedef int (*pvr2_ctlf_get_value)(struct pvr2_ctrl *,int *);
+typedef int (*pvr2_ctlf_set_value)(struct pvr2_ctrl *,int msk,int val);
+typedef int (*pvr2_ctlf_val_to_sym)(struct pvr2_ctrl *,int msk,int val,
+				    char *,unsigned int,unsigned int *);
+typedef int (*pvr2_ctlf_sym_to_val)(struct pvr2_ctrl *,
+				    const char *,unsigned int,
+				    int *mskp,int *valp);
+typedef unsigned int (*pvr2_ctlf_get_v4lflags)(struct pvr2_ctrl *);
+
+/* This structure describes a specific control.  A table of these is set up
+   in pvrusb2-hdw.c. */
+struct pvr2_ctl_info {
+	/* Control's name suitable for use as an identifier */
+	const char *name;
+
+	/* Short description of control */
+	const char *desc;
+
+	/* Control's implementation */
+	pvr2_ctlf_get_value get_value;      /* Get its value */
+	pvr2_ctlf_get_value get_min_value;  /* Get minimum allowed value */
+	pvr2_ctlf_get_value get_max_value;  /* Get maximum allowed value */
+	pvr2_ctlf_set_value set_value;      /* Set its value */
+	pvr2_ctlf_val_to_sym val_to_sym;    /* Custom convert value->symbol */
+	pvr2_ctlf_sym_to_val sym_to_val;    /* Custom convert symbol->value */
+	pvr2_ctlf_is_dirty is_dirty;        /* Return true if dirty */
+	pvr2_ctlf_clear_dirty clear_dirty;  /* Clear dirty state */
+	pvr2_ctlf_get_v4lflags get_v4lflags;/* Retrieve v4l flags */
+
+	/* Control's type (int, enum, bitmask) */
+	enum pvr2_ctl_type type;
+
+	/* Associated V4L control ID, if any */
+	int v4l_id;
+
+	/* Associated driver internal ID, if any */
+	int internal_id;
+
+	/* Don't implicitly initialize this control's value */
+	int skip_init;
+
+	/* Starting value for this control */
+	int default_value;
+
+	/* Type-specific control information */
+	union {
+		struct { /* Integer control */
+			long min_value; /* lower limit */
+			long max_value; /* upper limit */
+		} type_int;
+		struct { /* enumerated control */
+			unsigned int count;       /* enum value count */
+			const char **value_names; /* symbol names */
+		} type_enum;
+		struct { /* bitmask control */
+			unsigned int valid_bits; /* bits in use */
+			const char **bit_names;  /* symbol name/bit */
+		} type_bitmask;
+	} def;
+};
+
+
+/* Same as pvr2_ctl_info, but includes storage for the control description */
+#define PVR2_CTLD_INFO_DESC_SIZE 32
+struct pvr2_ctld_info {
+	struct pvr2_ctl_info info;
+	char desc[PVR2_CTLD_INFO_DESC_SIZE];
+};
+
+struct pvr2_ctrl {
+	const struct pvr2_ctl_info *info;
+	struct pvr2_hdw *hdw;
+};
+
+
+struct pvr2_audio_stat {
+	void *ctxt;
+	void (*detach)(void *);
+	int (*status)(void *);
+};
+
+struct pvr2_decoder_ctrl {
+	void *ctxt;
+	void (*detach)(void *);
+	void (*enable)(void *,int);
+	int (*tuned)(void *);
+	void (*force_reset)(void *);
+};
+
+#define PVR2_I2C_PEND_DETECT  0x01  /* Need to detect a client type */
+#define PVR2_I2C_PEND_CLIENT  0x02  /* Client needs a specific update */
+#define PVR2_I2C_PEND_REFRESH 0x04  /* Client has specific pending bits */
+#define PVR2_I2C_PEND_STALE   0x08  /* Broadcast pending bits */
+
+#define PVR2_I2C_PEND_ALL (PVR2_I2C_PEND_DETECT |\
+			   PVR2_I2C_PEND_CLIENT |\
+			   PVR2_I2C_PEND_REFRESH |\
+			   PVR2_I2C_PEND_STALE)
+
+/* Disposition of firmware1 loading situation */
+#define FW1_STATE_UNKNOWN 0
+#define FW1_STATE_MISSING 1
+#define FW1_STATE_FAILED 2
+#define FW1_STATE_RELOAD 3
+#define FW1_STATE_OK 4
+
+/* Known major hardware variants, keyed from device ID */
+#define PVR2_HDW_TYPE_29XXX 0
+#ifdef CONFIG_VIDEO_PVRUSB2_24XXX
+#define PVR2_HDW_TYPE_24XXX 1
+#endif
+
+typedef int (*pvr2_i2c_func)(struct pvr2_hdw *,u8,u8 *,u16,u8 *, u16);
+#define PVR2_I2C_FUNC_CNT 128
+
+/* This structure contains all state data directly needed to
+   manipulate the hardware (as opposed to complying with a kernel
+   interface) */
+struct pvr2_hdw {
+	/* Underlying USB device handle */
+	struct usb_device *usb_dev;
+	struct usb_interface *usb_intf;
+
+	/* Device type, one of PVR2_HDW_TYPE_xxxxx */
+	unsigned int hdw_type;
+
+	/* Video spigot */
+	struct pvr2_stream *vid_stream;
+
+	/* Mutex for all hardware state control */
+	struct mutex big_lock_mutex;
+	int big_lock_held;  /* For debugging */
+
+	void (*poll_trigger_func)(void *);
+	void *poll_trigger_data;
+
+	char name[32];
+
+	/* I2C stuff */
+	struct i2c_adapter i2c_adap;
+	struct i2c_algorithm i2c_algo;
+	pvr2_i2c_func i2c_func[PVR2_I2C_FUNC_CNT];
+	int i2c_cx25840_hack_state;
+	int i2c_linked;
+	unsigned int i2c_pend_types;    /* Which types of update are needed */
+	unsigned long i2c_pend_mask;    /* Change bits we need to scan */
+	unsigned long i2c_stale_mask;   /* Pending broadcast change bits */
+	unsigned long i2c_active_mask;  /* All change bits currently in use */
+	struct list_head i2c_clients;
+	struct mutex i2c_list_lock;
+
+	/* Frequency table */
+	unsigned int freqTable[FREQTABLE_SIZE];
+	unsigned int freqProgSlot;
+	unsigned int freqSlot;
+
+	/* Stuff for handling low level control interaction with device */
+	struct mutex ctl_lock_mutex;
+	int ctl_lock_held;  /* For debugging */
+	struct urb *ctl_write_urb;
+	struct urb *ctl_read_urb;
+	unsigned char *ctl_write_buffer;
+	unsigned char *ctl_read_buffer;
+	volatile int ctl_write_pend_flag;
+	volatile int ctl_read_pend_flag;
+	volatile int ctl_timeout_flag;
+	struct completion ctl_done;
+	unsigned char cmd_buffer[PVR2_CTL_BUFFSIZE];
+	int cmd_debug_state;               // Low level command debugging info
+	unsigned char cmd_debug_code;      //
+	unsigned int cmd_debug_write_len;  //
+	unsigned int cmd_debug_read_len;   //
+
+	int flag_ok;            // device in known good state
+	int flag_disconnected;  // flag_ok == 0 due to disconnect
+	int flag_init_ok;       // true if structure is fully initialized
+	int flag_streaming_enabled; // true if streaming should be on
+	int fw1_state;          // current situation with fw1
+
+	int flag_decoder_is_tuned;
+
+	struct pvr2_decoder_ctrl *decoder_ctrl;
+
+	// CPU firmware info (used to help find / save firmware data)
+	char *fw_buffer;
+	unsigned int fw_size;
+
+	// Which subsystem pieces have been enabled / configured
+	unsigned long subsys_enabled_mask;
+
+	// Which subsystems are manipulated to enable streaming
+	unsigned long subsys_stream_mask;
+
+	// True if there is a request to trigger logging of state in each
+	// module.
+	int log_requested;
+
+	/* Tuner / frequency control stuff */
+	unsigned int tuner_type;
+	int tuner_updated;
+	unsigned int freqVal;
+	int freqDirty;
+
+	/* Video standard handling */
+	v4l2_std_id std_mask_eeprom; // Hardware supported selections
+	v4l2_std_id std_mask_avail;  // Which standards we may select from
+	v4l2_std_id std_mask_cur;    // Currently selected standard(s)
+	unsigned int std_enum_cnt;   // # of enumerated standards
+	int std_enum_cur;            // selected standard enumeration value
+	int std_dirty;               // True if std_mask_cur has changed
+	struct pvr2_ctl_info std_info_enum;
+	struct pvr2_ctl_info std_info_avail;
+	struct pvr2_ctl_info std_info_cur;
+	struct v4l2_standard *std_defs;
+	const char **std_enum_names;
+
+	// Generated string names, one per actual V4L2 standard
+	const char *std_mask_ptrs[32];
+	char std_mask_names[32][10];
+
+	int unit_number;             /* ID for driver instance */
+	unsigned long serial_number; /* ID for hardware itself */
+
+	/* Minor number used by v4l logic (yes, this is a hack, as there should
+	   be no v4l junk here).  Probably a better way to do this. */
+	int v4l_minor_number;
+
+	/* Location of eeprom or a negative number if none */
+	int eeprom_addr;
+
+	enum pvr2_config config;
+
+	/* Information about what audio signal we're hearing */
+	int flag_stereo;
+	int flag_bilingual;
+	struct pvr2_audio_stat *audio_stat;
+
+	/* Control state needed for cx2341x module */
+	struct cx2341x_mpeg_params enc_cur_state;
+	struct cx2341x_mpeg_params enc_ctl_state;
+	/* True if an encoder attribute has changed */
+	int enc_stale;
+	/* True if enc_cur_state is valid */
+	int enc_cur_valid;
+
+	/* Control state */
+#define VCREATE_DATA(lab) int lab##_val; int lab##_dirty
+	VCREATE_DATA(brightness);
+	VCREATE_DATA(contrast);
+	VCREATE_DATA(saturation);
+	VCREATE_DATA(hue);
+	VCREATE_DATA(volume);
+	VCREATE_DATA(balance);
+	VCREATE_DATA(bass);
+	VCREATE_DATA(treble);
+	VCREATE_DATA(mute);
+	VCREATE_DATA(input);
+	VCREATE_DATA(audiomode);
+	VCREATE_DATA(res_hor);
+	VCREATE_DATA(res_ver);
+	VCREATE_DATA(srate);
+#undef VCREATE_DATA
+
+	struct pvr2_ctld_info *mpeg_ctrl_info;
+
+	struct pvr2_ctrl *controls;
+	unsigned int control_cnt;
+};
+
+#endif /* __PVRUSB2_HDW_INTERNAL_H */
+
+/*
+  Stuff for Emacs to see, in order to encourage consistent editing style:
+  *** Local Variables: ***
+  *** mode: c ***
+  *** fill-column: 75 ***
+  *** tab-width: 8 ***
+  *** c-basic-offset: 8 ***
+  *** End: ***
+  */
diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw.c b/drivers/media/video/pvrusb2/pvrusb2-hdw.c
new file mode 100644
index 000000000..a36a69d9e
--- /dev/null
+++ b/drivers/media/video/pvrusb2/pvrusb2-hdw.c
@@ -0,0 +1,3128 @@
+/*
+ *
+ *  $Id$
+ *
+ *  Copyright (C) 2005 Mike Isely <isely@pobox.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
+ *
+ *  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/errno.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+#include <linux/firmware.h>
+#include <linux/videodev2.h>
+#include <asm/semaphore.h>
+#include "pvrusb2.h"
+#include "pvrusb2-std.h"
+#include "pvrusb2-util.h"
+#include "pvrusb2-hdw.h"
+#include "pvrusb2-i2c-core.h"
+#include "pvrusb2-tuner.h"
+#include "pvrusb2-eeprom.h"
+#include "pvrusb2-hdw-internal.h"
+#include "pvrusb2-encoder.h"
+#include "pvrusb2-debug.h"
+
+struct usb_device_id pvr2_device_table[] = {
+	[PVR2_HDW_TYPE_29XXX] = { USB_DEVICE(0x2040, 0x2900) },
+#ifdef CONFIG_VIDEO_PVRUSB2_24XXX
+	[PVR2_HDW_TYPE_24XXX] = { USB_DEVICE(0x2040, 0x2400) },
+#endif
+	{ }
+};
+
+MODULE_DEVICE_TABLE(usb, pvr2_device_table);
+
+static const char *pvr2_device_names[] = {
+	[PVR2_HDW_TYPE_29XXX] = "WinTV PVR USB2 Model Category 29xxxx",
+#ifdef CONFIG_VIDEO_PVRUSB2_24XXX
+	[PVR2_HDW_TYPE_24XXX] = "WinTV PVR USB2 Model Category 24xxxx",
+#endif
+};
+
+struct pvr2_string_table {
+	const char **lst;
+	unsigned int cnt;
+};
+
+#ifdef CONFIG_VIDEO_PVRUSB2_24XXX
+// Names of other client modules to request for 24xxx model hardware
+static const char *pvr2_client_24xxx[] = {
+	"cx25840",
+	"tuner",
+	"wm8775",
+};
+#endif
+
+// Names of other client modules to request for 29xxx model hardware
+static const char *pvr2_client_29xxx[] = {
+	"msp3400",
+	"saa7115",
+	"tuner",
+};
+
+static struct pvr2_string_table pvr2_client_lists[] = {
+	[PVR2_HDW_TYPE_29XXX] = {
+		pvr2_client_29xxx,
+		sizeof(pvr2_client_29xxx)/sizeof(pvr2_client_29xxx[0]),
+	},
+#ifdef CONFIG_VIDEO_PVRUSB2_24XXX
+	[PVR2_HDW_TYPE_24XXX] = {
+		pvr2_client_24xxx,
+		sizeof(pvr2_client_24xxx)/sizeof(pvr2_client_24xxx[0]),
+	},
+#endif
+};
+
+static struct pvr2_hdw *unit_pointers[PVR_NUM] = {[ 0 ... PVR_NUM-1 ] = NULL};
+static DECLARE_MUTEX(pvr2_unit_sem);
+
+static int ctlchg = 0;
+static int initusbreset = 1;
+static int procreload = 0;
+static int tuner[PVR_NUM] = { [0 ... PVR_NUM-1] = -1 };
+static int tolerance[PVR_NUM] = { [0 ... PVR_NUM-1] = 0 };
+static int video_std[PVR_NUM] = { [0 ... PVR_NUM-1] = 0 };
+static int init_pause_msec = 0;
+
+module_param(ctlchg, int, S_IRUGO|S_IWUSR);
+MODULE_PARM_DESC(ctlchg, "0=optimize ctl change 1=always accept new ctl value");
+module_param(init_pause_msec, int, S_IRUGO|S_IWUSR);
+MODULE_PARM_DESC(init_pause_msec, "hardware initialization settling delay");
+module_param(initusbreset, int, S_IRUGO|S_IWUSR);
+MODULE_PARM_DESC(initusbreset, "Do USB reset device on probe");
+module_param(procreload, int, S_IRUGO|S_IWUSR);
+MODULE_PARM_DESC(procreload,
+		 "Attempt init failure recovery with firmware reload");
+module_param_array(tuner,    int, NULL, 0444);
+MODULE_PARM_DESC(tuner,"specify installed tuner type");
+module_param_array(video_std,    int, NULL, 0444);
+MODULE_PARM_DESC(video_std,"specify initial video standard");
+module_param_array(tolerance,    int, NULL, 0444);
+MODULE_PARM_DESC(tolerance,"specify stream error tolerance");
+
+#define PVR2_CTL_WRITE_ENDPOINT  0x01
+#define PVR2_CTL_READ_ENDPOINT   0x81
+
+#define PVR2_GPIO_IN 0x9008
+#define PVR2_GPIO_OUT 0x900c
+#define PVR2_GPIO_DIR 0x9020
+
+#define trace_firmware(...) pvr2_trace(PVR2_TRACE_FIRMWARE,__VA_ARGS__)
+
+#define PVR2_FIRMWARE_ENDPOINT   0x02
+
+/* size of a firmware chunk */
+#define FIRMWARE_CHUNK_SIZE 0x2000
+
+/* Define the list of additional controls we'll dynamically construct based
+   on query of the cx2341x module. */
+struct pvr2_mpeg_ids {
+	const char *strid;
+	int id;
+};
+static const struct pvr2_mpeg_ids mpeg_ids[] = {
+	{
+		.strid = "audio_layer",
+		.id = V4L2_CID_MPEG_AUDIO_ENCODING,
+	},{
+		.strid = "audio_bitrate",
+		.id = V4L2_CID_MPEG_AUDIO_L2_BITRATE,
+	},{
+		/* Already using audio_mode elsewhere :-( */
+		.strid = "mpeg_audio_mode",
+		.id = V4L2_CID_MPEG_AUDIO_MODE,
+	},{
+		.strid = "mpeg_audio_mode_extension",
+		.id = V4L2_CID_MPEG_AUDIO_MODE_EXTENSION,
+	},{
+		.strid = "audio_emphasis",
+		.id = V4L2_CID_MPEG_AUDIO_EMPHASIS,
+	},{
+		.strid = "audio_crc",
+		.id = V4L2_CID_MPEG_AUDIO_CRC,
+	},{
+		.strid = "video_aspect",
+		.id = V4L2_CID_MPEG_VIDEO_ASPECT,
+	},{
+		.strid = "video_b_frames",
+		.id = V4L2_CID_MPEG_VIDEO_B_FRAMES,
+	},{
+		.strid = "video_gop_size",
+		.id = V4L2_CID_MPEG_VIDEO_GOP_SIZE,
+	},{
+		.strid = "video_gop_closure",
+		.id = V4L2_CID_MPEG_VIDEO_GOP_CLOSURE,
+	},{
+		.strid = "video_pulldown",
+		.id = V4L2_CID_MPEG_VIDEO_PULLDOWN,
+	},{
+		.strid = "video_bitrate_mode",
+		.id = V4L2_CID_MPEG_VIDEO_BITRATE_MODE,
+	},{
+		.strid = "video_bitrate",
+		.id = V4L2_CID_MPEG_VIDEO_BITRATE,
+	},{
+		.strid = "video_bitrate_peak",
+		.id = V4L2_CID_MPEG_VIDEO_BITRATE_PEAK,
+	},{
+		.strid = "video_temporal_decimation",
+		.id = V4L2_CID_MPEG_VIDEO_TEMPORAL_DECIMATION,
+	},{
+		.strid = "stream_type",
+		.id = V4L2_CID_MPEG_STREAM_TYPE,
+	},{
+		.strid = "video_spatial_filter_mode",
+		.id = V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE,
+	},{
+		.strid = "video_spatial_filter",
+		.id = V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER,
+	},{
+		.strid = "video_luma_spatial_filter_type",
+		.id = V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE,
+	},{
+		.strid = "video_chroma_spatial_filter_type",
+		.id = V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE,
+	},{
+		.strid = "video_temporal_filter_mode",
+		.id = V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE,
+	},{
+		.strid = "video_temporal_filter",
+		.id = V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER,
+	},{
+		.strid = "video_median_filter_type",
+		.id = V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE,
+	},{
+		.strid = "video_luma_median_filter_top",
+		.id = V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_TOP,
+	},{
+		.strid = "video_luma_median_filter_bottom",
+		.id = V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_BOTTOM,
+	},{
+		.strid = "video_chroma_median_filter_top",
+		.id = V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_TOP,
+	},{
+		.strid = "video_chroma_median_filter_bottom",
+		.id = V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_BOTTOM,
+	}
+};
+#define MPEGDEF_COUNT (sizeof(mpeg_ids)/sizeof(mpeg_ids[0]))
+
+static const char *control_values_srate[] = {
+	[PVR2_CVAL_SRATE_48]   = "48KHz",
+	[PVR2_CVAL_SRATE_44_1] = "44.1KHz",
+};
+
+
+
+
+static const char *control_values_input[] = {
+	[PVR2_CVAL_INPUT_TV]        = "television",  /*xawtv needs this name*/
+	[PVR2_CVAL_INPUT_RADIO]     = "radio",
+	[PVR2_CVAL_INPUT_SVIDEO]    = "s-video",
+	[PVR2_CVAL_INPUT_COMPOSITE] = "composite",
+};
+
+
+static const char *control_values_audiomode[] = {
+	[V4L2_TUNER_MODE_MONO]   = "Mono",
+	[V4L2_TUNER_MODE_STEREO] = "Stereo",
+	[V4L2_TUNER_MODE_LANG1]  = "Lang1",
+	[V4L2_TUNER_MODE_LANG2]  = "Lang2",
+	[V4L2_TUNER_MODE_LANG1_LANG2] = "Lang1+Lang2",
+};
+
+
+static const char *control_values_hsm[] = {
+	[PVR2_CVAL_HSM_FAIL] = "Fail",
+	[PVR2_CVAL_HSM_HIGH] = "High",
+	[PVR2_CVAL_HSM_FULL] = "Full",
+};
+
+
+static const char *control_values_subsystem[] = {
+	[PVR2_SUBSYS_B_ENC_FIRMWARE]  = "enc_firmware",
+	[PVR2_SUBSYS_B_ENC_CFG] = "enc_config",
+	[PVR2_SUBSYS_B_DIGITIZER_RUN] = "digitizer_run",
+	[PVR2_SUBSYS_B_USBSTREAM_RUN] = "usbstream_run",
+	[PVR2_SUBSYS_B_ENC_RUN] = "enc_run",
+};
+
+static int pvr2_hdw_cmd_usbstream(struct pvr2_hdw *hdw,int runFl);
+static int pvr2_hdw_commit_ctl_internal(struct pvr2_hdw *hdw);
+static int pvr2_hdw_get_eeprom_addr(struct pvr2_hdw *hdw);
+static unsigned int pvr2_hdw_get_signal_status_internal(struct pvr2_hdw *hdw);
+static void pvr2_hdw_internal_find_stdenum(struct pvr2_hdw *hdw);
+static void pvr2_hdw_internal_set_std_avail(struct pvr2_hdw *hdw);
+static void pvr2_hdw_render_useless_unlocked(struct pvr2_hdw *hdw);
+static void pvr2_hdw_subsys_bit_chg_no_lock(struct pvr2_hdw *hdw,
+					    unsigned long msk,
+					    unsigned long val);
+static void pvr2_hdw_subsys_stream_bit_chg_no_lock(struct pvr2_hdw *hdw,
+						   unsigned long msk,
+						   unsigned long val);
+static int pvr2_send_request_ex(struct pvr2_hdw *hdw,
+				unsigned int timeout,int probe_fl,
+				void *write_data,unsigned int write_len,
+				void *read_data,unsigned int read_len);
+static int pvr2_write_u16(struct pvr2_hdw *hdw, u16 data, int res);
+static int pvr2_write_u8(struct pvr2_hdw *hdw, u8 data, int res);
+
+static int ctrl_channelfreq_get(struct pvr2_ctrl *cptr,int *vp)
+{
+	struct pvr2_hdw *hdw = cptr->hdw;
+	if ((hdw->freqProgSlot > 0) && (hdw->freqProgSlot <= FREQTABLE_SIZE)) {
+		*vp = hdw->freqTable[hdw->freqProgSlot-1];
+	} else {
+		*vp = 0;
+	}
+	return 0;
+}
+
+static int ctrl_channelfreq_set(struct pvr2_ctrl *cptr,int m,int v)
+{
+	struct pvr2_hdw *hdw = cptr->hdw;
+	if ((hdw->freqProgSlot > 0) && (hdw->freqProgSlot <= FREQTABLE_SIZE)) {
+		hdw->freqTable[hdw->freqProgSlot-1] = v;
+	}
+	return 0;
+}
+
+static int ctrl_channelprog_get(struct pvr2_ctrl *cptr,int *vp)
+{
+	*vp = cptr->hdw->freqProgSlot;
+	return 0;
+}
+
+static int ctrl_channelprog_set(struct pvr2_ctrl *cptr,int m,int v)
+{
+	struct pvr2_hdw *hdw = cptr->hdw;
+	if ((v >= 0) && (v <= FREQTABLE_SIZE)) {
+		hdw->freqProgSlot = v;
+	}
+	return 0;
+}
+
+static int ctrl_channel_get(struct pvr2_ctrl *cptr,int *vp)
+{
+	*vp = cptr->hdw->freqSlot;
+	return 0;
+}
+
+static int ctrl_channel_set(struct pvr2_ctrl *cptr,int m,int v)
+{
+	unsigned freq = 0;
+	struct pvr2_hdw *hdw = cptr->hdw;
+	hdw->freqSlot = v;
+	if ((hdw->freqSlot > 0) && (hdw->freqSlot <= FREQTABLE_SIZE)) {
+		freq = hdw->freqTable[hdw->freqSlot-1];
+	}
+	if (freq && (freq != hdw->freqVal)) {
+		hdw->freqVal = freq;
+		hdw->freqDirty = !0;
+	}
+	return 0;
+}
+
+static int ctrl_freq_get(struct pvr2_ctrl *cptr,int *vp)
+{
+	*vp = cptr->hdw->freqVal;
+	return 0;
+}
+
+static int ctrl_freq_is_dirty(struct pvr2_ctrl *cptr)
+{
+	return cptr->hdw->freqDirty != 0;
+}
+
+static void ctrl_freq_clear_dirty(struct pvr2_ctrl *cptr)
+{
+	cptr->hdw->freqDirty = 0;
+}
+
+static int ctrl_freq_set(struct pvr2_ctrl *cptr,int m,int v)
+{
+	struct pvr2_hdw *hdw = cptr->hdw;
+	hdw->freqVal = v;
+	hdw->freqDirty = !0;
+	hdw->freqSlot = 0;
+	return 0;
+}
+
+#ifdef CONFIG_VIDEO_PVRUSB2_24XXX
+static int ctrl_hres_max_get(struct pvr2_ctrl *cptr,int *vp)
+{
+	/* If we're dealing with a 24xxx device, force the horizontal
+	   maximum to be 720 no matter what, since we can't get the device
+	   to work properly with any other value.  Otherwise just return
+	   the normal value. */
+	*vp = cptr->info->def.type_int.max_value;
+	if (cptr->hdw->hdw_type == PVR2_HDW_TYPE_24XXX) *vp = 720;
+	return 0;
+}
+
+static int ctrl_hres_min_get(struct pvr2_ctrl *cptr,int *vp)
+{
+	/* If we're dealing with a 24xxx device, force the horizontal
+	   minimum to be 720 no matter what, since we can't get the device
+	   to work properly with any other value.  Otherwise just return
+	   the normal value. */
+	*vp = cptr->info->def.type_int.min_value;
+	if (cptr->hdw->hdw_type == PVR2_HDW_TYPE_24XXX) *vp = 720;
+	return 0;
+}
+#endif
+
+static int ctrl_cx2341x_is_dirty(struct pvr2_ctrl *cptr)
+{
+	return cptr->hdw->enc_stale != 0;
+}
+
+static void ctrl_cx2341x_clear_dirty(struct pvr2_ctrl *cptr)
+{
+	cptr->hdw->enc_stale = 0;
+}
+
+static int ctrl_cx2341x_get(struct pvr2_ctrl *cptr,int *vp)
+{
+	int ret;
+	struct v4l2_ext_controls cs;
+	struct v4l2_ext_control c1;
+	memset(&cs,0,sizeof(cs));
+	memset(&c1,0,sizeof(c1));
+	cs.controls = &c1;
+	cs.count = 1;
+	c1.id = cptr->info->v4l_id;
+	ret = cx2341x_ext_ctrls(&cptr->hdw->enc_ctl_state,&cs,
+				VIDIOC_G_EXT_CTRLS);
+	if (ret) return ret;
+	*vp = c1.value;
+	return 0;
+}
+
+static int ctrl_cx2341x_set(struct pvr2_ctrl *cptr,int m,int v)
+{
+	int ret;
+	struct v4l2_ext_controls cs;
+	struct v4l2_ext_control c1;
+	memset(&cs,0,sizeof(cs));
+	memset(&c1,0,sizeof(c1));
+	cs.controls = &c1;
+	cs.count = 1;
+	c1.id = cptr->info->v4l_id;
+	c1.value = v;
+	ret = cx2341x_ext_ctrls(&cptr->hdw->enc_ctl_state,&cs,
+				VIDIOC_S_EXT_CTRLS);
+	if (ret) return ret;
+	cptr->hdw->enc_stale = !0;
+	return 0;
+}
+
+static unsigned int ctrl_cx2341x_getv4lflags(struct pvr2_ctrl *cptr)
+{
+	struct v4l2_queryctrl qctrl;
+	struct pvr2_ctl_info *info;
+	qctrl.id = cptr->info->v4l_id;
+	cx2341x_ctrl_query(&cptr->hdw->enc_ctl_state,&qctrl);
+	/* Strip out the const so we can adjust a function pointer.  It's
+	   OK to do this here because we know this is a dynamically created
+	   control, so the underlying storage for the info pointer is (a)
+	   private to us, and (b) not in read-only storage.  Either we do
+	   this or we significantly complicate the underlying control
+	   implementation. */
+	info = (struct pvr2_ctl_info *)(cptr->info);
+	if (qctrl.flags & V4L2_CTRL_FLAG_READ_ONLY) {
+		if (info->set_value) {
+			info->set_value = NULL;
+		}
+	} else {
+		if (!(info->set_value)) {
+			info->set_value = ctrl_cx2341x_set;
+		}
+	}
+	return qctrl.flags;
+}
+
+static int ctrl_streamingenabled_get(struct pvr2_ctrl *cptr,int *vp)
+{
+	*vp = cptr->hdw->flag_streaming_enabled;
+	return 0;
+}
+
+static int ctrl_hsm_get(struct pvr2_ctrl *cptr,int *vp)
+{
+	int result = pvr2_hdw_is_hsm(cptr->hdw);
+	*vp = PVR2_CVAL_HSM_FULL;
+	if (result < 0) *vp = PVR2_CVAL_HSM_FAIL;
+	if (result) *vp = PVR2_CVAL_HSM_HIGH;
+	return 0;
+}
+
+static int ctrl_stdavail_get(struct pvr2_ctrl *cptr,int *vp)
+{
+	*vp = cptr->hdw->std_mask_avail;
+	return 0;
+}
+
+static int ctrl_stdavail_set(struct pvr2_ctrl *cptr,int m,int v)
+{
+	struct pvr2_hdw *hdw = cptr->hdw;
+	v4l2_std_id ns;
+	ns = hdw->std_mask_avail;
+	ns = (ns & ~m) | (v & m);
+	if (ns == hdw->std_mask_avail) return 0;
+	hdw->std_mask_avail = ns;
+	pvr2_hdw_internal_set_std_avail(hdw);
+	pvr2_hdw_internal_find_stdenum(hdw);
+	return 0;
+}
+
+static int ctrl_std_val_to_sym(struct pvr2_ctrl *cptr,int msk,int val,
+			       char *bufPtr,unsigned int bufSize,
+			       unsigned int *len)
+{
+	*len = pvr2_std_id_to_str(bufPtr,bufSize,msk & val);
+	return 0;
+}
+
+static int ctrl_std_sym_to_val(struct pvr2_ctrl *cptr,
+			       const char *bufPtr,unsigned int bufSize,
+			       int *mskp,int *valp)
+{
+	int ret;
+	v4l2_std_id id;
+	ret = pvr2_std_str_to_id(&id,bufPtr,bufSize);
+	if (ret < 0) return ret;
+	if (mskp) *mskp = id;
+	if (valp) *valp = id;
+	return 0;
+}
+
+static int ctrl_stdcur_get(struct pvr2_ctrl *cptr,int *vp)
+{
+	*vp = cptr->hdw->std_mask_cur;
+	return 0;
+}
+
+static int ctrl_stdcur_set(struct pvr2_ctrl *cptr,int m,int v)
+{
+	struct pvr2_hdw *hdw = cptr->hdw;
+	v4l2_std_id ns;
+	ns = hdw->std_mask_cur;
+	ns = (ns & ~m) | (v & m);
+	if (ns == hdw->std_mask_cur) return 0;
+	hdw->std_mask_cur = ns;
+	hdw->std_dirty = !0;
+	pvr2_hdw_internal_find_stdenum(hdw);
+	return 0;
+}
+
+static int ctrl_stdcur_is_dirty(struct pvr2_ctrl *cptr)
+{
+	return cptr->hdw->std_dirty != 0;
+}
+
+static void ctrl_stdcur_clear_dirty(struct pvr2_ctrl *cptr)
+{
+	cptr->hdw->std_dirty = 0;
+}
+
+static int ctrl_signal_get(struct pvr2_ctrl *cptr,int *vp)
+{
+	*vp = ((pvr2_hdw_get_signal_status_internal(cptr->hdw) &
+		PVR2_SIGNAL_OK) ? 1 : 0);
+	return 0;
+}
+
+static int ctrl_subsys_get(struct pvr2_ctrl *cptr,int *vp)
+{
+	*vp = cptr->hdw->subsys_enabled_mask;
+	return 0;
+}
+
+static int ctrl_subsys_set(struct pvr2_ctrl *cptr,int m,int v)
+{
+	pvr2_hdw_subsys_bit_chg_no_lock(cptr->hdw,m,v);
+	return 0;
+}
+
+static int ctrl_subsys_stream_get(struct pvr2_ctrl *cptr,int *vp)
+{
+	*vp = cptr->hdw->subsys_stream_mask;
+	return 0;
+}
+
+static int ctrl_subsys_stream_set(struct pvr2_ctrl *cptr,int m,int v)
+{
+	pvr2_hdw_subsys_stream_bit_chg_no_lock(cptr->hdw,m,v);
+	return 0;
+}
+
+static int ctrl_stdenumcur_set(struct pvr2_ctrl *cptr,int m,int v)
+{
+	struct pvr2_hdw *hdw = cptr->hdw;
+	if (v < 0) return -EINVAL;
+	if (v > hdw->std_enum_cnt) return -EINVAL;
+	hdw->std_enum_cur = v;
+	if (!v) return 0;
+	v--;
+	if (hdw->std_mask_cur == hdw->std_defs[v].id) return 0;
+	hdw->std_mask_cur = hdw->std_defs[v].id;
+	hdw->std_dirty = !0;
+	return 0;
+}
+
+
+static int ctrl_stdenumcur_get(struct pvr2_ctrl *cptr,int *vp)
+{
+	*vp = cptr->hdw->std_enum_cur;
+	return 0;
+}
+
+
+static int ctrl_stdenumcur_is_dirty(struct pvr2_ctrl *cptr)
+{
+	return cptr->hdw->std_dirty != 0;
+}
+
+
+static void ctrl_stdenumcur_clear_dirty(struct pvr2_ctrl *cptr)
+{
+	cptr->hdw->std_dirty = 0;
+}
+
+
+#define DEFINT(vmin,vmax) \
+	.type = pvr2_ctl_int, \
+	.def.type_int.min_value = vmin, \
+	.def.type_int.max_value = vmax
+
+#define DEFENUM(tab) \
+	.type = pvr2_ctl_enum, \
+	.def.type_enum.count = (sizeof(tab)/sizeof((tab)[0])), \
+	.def.type_enum.value_names = tab
+
+#define DEFBOOL \
+	.type = pvr2_ctl_bool
+
+#define DEFMASK(msk,tab) \
+	.type = pvr2_ctl_bitmask, \
+	.def.type_bitmask.valid_bits = msk, \
+	.def.type_bitmask.bit_names = tab
+
+#define DEFREF(vname) \
+	.set_value = ctrl_set_##vname, \
+	.get_value = ctrl_get_##vname, \
+	.is_dirty = ctrl_isdirty_##vname, \
+	.clear_dirty = ctrl_cleardirty_##vname
+
+
+#define VCREATE_FUNCS(vname) \
+static int ctrl_get_##vname(struct pvr2_ctrl *cptr,int *vp) \
+{*vp = cptr->hdw->vname##_val; return 0;} \
+static int ctrl_set_##vname(struct pvr2_ctrl *cptr,int m,int v) \
+{cptr->hdw->vname##_val = v; cptr->hdw->vname##_dirty = !0; return 0;} \
+static int ctrl_isdirty_##vname(struct pvr2_ctrl *cptr) \
+{return cptr->hdw->vname##_dirty != 0;} \
+static void ctrl_cleardirty_##vname(struct pvr2_ctrl *cptr) \
+{cptr->hdw->vname##_dirty = 0;}
+
+VCREATE_FUNCS(brightness)
+VCREATE_FUNCS(contrast)
+VCREATE_FUNCS(saturation)
+VCREATE_FUNCS(hue)
+VCREATE_FUNCS(volume)
+VCREATE_FUNCS(balance)
+VCREATE_FUNCS(bass)
+VCREATE_FUNCS(treble)
+VCREATE_FUNCS(mute)
+VCREATE_FUNCS(input)
+VCREATE_FUNCS(audiomode)
+VCREATE_FUNCS(res_hor)
+VCREATE_FUNCS(res_ver)
+VCREATE_FUNCS(srate)
+
+#define MIN_FREQ 55250000L
+#define MAX_FREQ 850000000L
+
+/* Table definition of all controls which can be manipulated */
+static const struct pvr2_ctl_info control_defs[] = {
+	{
+		.v4l_id = V4L2_CID_BRIGHTNESS,
+		.desc = "Brightness",
+		.name = "brightness",
+		.default_value = 128,
+		DEFREF(brightness),
+		DEFINT(0,255),
+	},{
+		.v4l_id = V4L2_CID_CONTRAST,
+		.desc = "Contrast",
+		.name = "contrast",
+		.default_value = 68,
+		DEFREF(contrast),
+		DEFINT(0,127),
+	},{
+		.v4l_id = V4L2_CID_SATURATION,
+		.desc = "Saturation",
+		.name = "saturation",
+		.default_value = 64,
+		DEFREF(saturation),
+		DEFINT(0,127),
+	},{
+		.v4l_id = V4L2_CID_HUE,
+		.desc = "Hue",
+		.name = "hue",
+		.default_value = 0,
+		DEFREF(hue),
+		DEFINT(-128,127),
+	},{
+		.v4l_id = V4L2_CID_AUDIO_VOLUME,
+		.desc = "Volume",
+		.name = "volume",
+		.default_value = 65535,
+		DEFREF(volume),
+		DEFINT(0,65535),
+	},{
+		.v4l_id = V4L2_CID_AUDIO_BALANCE,
+		.desc = "Balance",
+		.name = "balance",
+		.default_value = 0,
+		DEFREF(balance),
+		DEFINT(-32768,32767),
+	},{
+		.v4l_id = V4L2_CID_AUDIO_BASS,
+		.desc = "Bass",
+		.name = "bass",
+		.default_value = 0,
+		DEFREF(bass),
+		DEFINT(-32768,32767),
+	},{
+		.v4l_id = V4L2_CID_AUDIO_TREBLE,
+		.desc = "Treble",
+		.name = "treble",
+		.default_value = 0,
+		DEFREF(treble),
+		DEFINT(-32768,32767),
+	},{
+		.v4l_id = V4L2_CID_AUDIO_MUTE,
+		.desc = "Mute",
+		.name = "mute",
+		.default_value = 0,
+		DEFREF(mute),
+		DEFBOOL,
+	},{
+		.desc = "Video Source",
+		.name = "input",
+		.internal_id = PVR2_CID_INPUT,
+		.default_value = PVR2_CVAL_INPUT_TV,
+		DEFREF(input),
+		DEFENUM(control_values_input),
+	},{
+		.desc = "Audio Mode",
+		.name = "audio_mode",
+		.internal_id = PVR2_CID_AUDIOMODE,
+		.default_value = V4L2_TUNER_MODE_STEREO,
+		DEFREF(audiomode),
+		DEFENUM(control_values_audiomode),
+	},{
+		.desc = "Horizontal capture resolution",
+		.name = "resolution_hor",
+		.internal_id = PVR2_CID_HRES,
+		.default_value = 720,
+		DEFREF(res_hor),
+		DEFINT(320,720),
+#ifdef CONFIG_VIDEO_PVRUSB2_24XXX
+		/* Hook in check for clamp on horizontal resolution in
+		   order to avoid unsolved problem involving cx25840. */
+		.get_max_value = ctrl_hres_max_get,
+		.get_min_value = ctrl_hres_min_get,
+#endif
+	},{
+		.desc = "Vertical capture resolution",
+		.name = "resolution_ver",
+		.internal_id = PVR2_CID_VRES,
+		.default_value = 480,
+		DEFREF(res_ver),
+		DEFINT(200,625),
+	},{
+		.v4l_id = V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ,
+		.desc = "Sample rate",
+		.name = "srate",
+		.default_value = PVR2_CVAL_SRATE_48,
+		DEFREF(srate),
+		DEFENUM(control_values_srate),
+	},{
+		.desc = "Tuner Frequency (Hz)",
+		.name = "frequency",
+		.internal_id = PVR2_CID_FREQUENCY,
+		.default_value = 175250000L,
+		.set_value = ctrl_freq_set,
+		.get_value = ctrl_freq_get,
+		.is_dirty = ctrl_freq_is_dirty,
+		.clear_dirty = ctrl_freq_clear_dirty,
+		DEFINT(MIN_FREQ,MAX_FREQ),
+	},{
+		.desc = "Channel",
+		.name = "channel",
+		.set_value = ctrl_channel_set,
+		.get_value = ctrl_channel_get,
+		DEFINT(0,FREQTABLE_SIZE),
+	},{
+		.desc = "Channel Program Frequency",
+		.name = "freq_table_value",
+		.set_value = ctrl_channelfreq_set,
+		.get_value = ctrl_channelfreq_get,
+		DEFINT(MIN_FREQ,MAX_FREQ),
+	},{
+		.desc = "Channel Program ID",
+		.name = "freq_table_channel",
+		.set_value = ctrl_channelprog_set,
+		.get_value = ctrl_channelprog_get,
+		DEFINT(0,FREQTABLE_SIZE),
+	},{
+		.desc = "Streaming Enabled",
+		.name = "streaming_enabled",
+		.get_value = ctrl_streamingenabled_get,
+		DEFBOOL,
+	},{
+		.desc = "USB Speed",
+		.name = "usb_speed",
+		.get_value = ctrl_hsm_get,
+		DEFENUM(control_values_hsm),
+	},{
+		.desc = "Signal Present",
+		.name = "signal_present",
+		.get_value = ctrl_signal_get,
+		DEFBOOL,
+	},{
+		.desc = "Video Standards Available Mask",
+		.name = "video_standard_mask_available",
+		.internal_id = PVR2_CID_STDAVAIL,
+		.skip_init = !0,
+		.get_value = ctrl_stdavail_get,
+		.set_value = ctrl_stdavail_set,
+		.val_to_sym = ctrl_std_val_to_sym,
+		.sym_to_val = ctrl_std_sym_to_val,
+		.type = pvr2_ctl_bitmask,
+	},{
+		.desc = "Video Standards In Use Mask",
+		.name = "video_standard_mask_active",
+		.internal_id = PVR2_CID_STDCUR,
+		.skip_init = !0,
+		.get_value = ctrl_stdcur_get,
+		.set_value = ctrl_stdcur_set,
+		.is_dirty = ctrl_stdcur_is_dirty,
+		.clear_dirty = ctrl_stdcur_clear_dirty,
+		.val_to_sym = ctrl_std_val_to_sym,
+		.sym_to_val = ctrl_std_sym_to_val,
+		.type = pvr2_ctl_bitmask,
+	},{
+		.desc = "Subsystem enabled mask",
+		.name = "debug_subsys_mask",
+		.skip_init = !0,
+		.get_value = ctrl_subsys_get,
+		.set_value = ctrl_subsys_set,
+		DEFMASK(PVR2_SUBSYS_ALL,control_values_subsystem),
+	},{
+		.desc = "Subsystem stream mask",
+		.name = "debug_subsys_stream_mask",
+		.skip_init = !0,
+		.get_value = ctrl_subsys_stream_get,
+		.set_value = ctrl_subsys_stream_set,
+		DEFMASK(PVR2_SUBSYS_ALL,control_values_subsystem),
+	},{
+		.desc = "Video Standard Name",
+		.name = "video_standard",
+		.internal_id = PVR2_CID_STDENUM,
+		.skip_init = !0,
+		.get_value = ctrl_stdenumcur_get,
+		.set_value = ctrl_stdenumcur_set,
+		.is_dirty = ctrl_stdenumcur_is_dirty,
+		.clear_dirty = ctrl_stdenumcur_clear_dirty,
+		.type = pvr2_ctl_enum,
+	}
+};
+
+#define CTRLDEF_COUNT (sizeof(control_defs)/sizeof(control_defs[0]))
+
+
+const char *pvr2_config_get_name(enum pvr2_config cfg)
+{
+	switch (cfg) {
+	case pvr2_config_empty: return "empty";
+	case pvr2_config_mpeg: return "mpeg";
+	case pvr2_config_vbi: return "vbi";
+	case pvr2_config_radio: return "radio";
+	}
+	return "<unknown>";
+}
+
+
+struct usb_device *pvr2_hdw_get_dev(struct pvr2_hdw *hdw)
+{
+	return hdw->usb_dev;
+}
+
+
+unsigned long pvr2_hdw_get_sn(struct pvr2_hdw *hdw)
+{
+	return hdw->serial_number;
+}
+
+int pvr2_hdw_get_unit_number(struct pvr2_hdw *hdw)
+{
+	return hdw->unit_number;
+}
+
+
+/* Attempt to locate one of the given set of files.  Messages are logged
+   appropriate to what has been found.  The return value will be 0 or
+   greater on success (it will be the index of the file name found) and
+   fw_entry will be filled in.  Otherwise a negative error is returned on
+   failure.  If the return value is -ENOENT then no viable firmware file
+   could be located. */
+static int pvr2_locate_firmware(struct pvr2_hdw *hdw,
+				const struct firmware **fw_entry,
+				const char *fwtypename,
+				unsigned int fwcount,
+				const char *fwnames[])
+{
+	unsigned int idx;
+	int ret = -EINVAL;
+	for (idx = 0; idx < fwcount; idx++) {
+		ret = request_firmware(fw_entry,
+				       fwnames[idx],
+				       &hdw->usb_dev->dev);
+		if (!ret) {
+			trace_firmware("Located %s firmware: %s;"
+				       " uploading...",
+				       fwtypename,
+				       fwnames[idx]);
+			return idx;
+		}
+		if (ret == -ENOENT) continue;
+		pvr2_trace(PVR2_TRACE_ERROR_LEGS,
+			   "request_firmware fatal error with code=%d",ret);
+		return ret;
+	}
+	pvr2_trace(PVR2_TRACE_ERROR_LEGS,
+		   "***WARNING***"
+		   " Device %s firmware"
+		   " seems to be missing.",
+		   fwtypename);
+	pvr2_trace(PVR2_TRACE_ERROR_LEGS,
+		   "Did you install the pvrusb2 firmware files"
+		   " in their proper location?");
+	if (fwcount == 1) {
+		pvr2_trace(PVR2_TRACE_ERROR_LEGS,
+			   "request_firmware unable to locate %s file %s",
+			   fwtypename,fwnames[0]);
+	} else {
+		pvr2_trace(PVR2_TRACE_ERROR_LEGS,
+			   "request_firmware unable to locate"
+			   " one of the following %s files:",
+			   fwtypename);
+		for (idx = 0; idx < fwcount; idx++) {
+			pvr2_trace(PVR2_TRACE_ERROR_LEGS,
+				   "request_firmware: Failed to find %s",
+				   fwnames[idx]);
+		}
+	}
+	return ret;
+}
+
+
+/*
+ * pvr2_upload_firmware1().
+ *
+ * Send the 8051 firmware to the device.  After the upload, arrange for
+ * device to re-enumerate.
+ *
+ * NOTE : the pointer to the firmware data given by request_firmware()
+ * is not suitable for an usb transaction.
+ *
+ */
+static int pvr2_upload_firmware1(struct pvr2_hdw *hdw)
+{
+	const struct firmware *fw_entry = NULL;
+	void  *fw_ptr;
+	unsigned int pipe;
+	int ret;
+	u16 address;
+	static const char *fw_files_29xxx[] = {
+		"v4l-pvrusb2-29xxx-01.fw",
+	};
+#ifdef CONFIG_VIDEO_PVRUSB2_24XXX
+	static const char *fw_files_24xxx[] = {
+		"v4l-pvrusb2-24xxx-01.fw",
+	};
+#endif
+	static const struct pvr2_string_table fw_file_defs[] = {
+		[PVR2_HDW_TYPE_29XXX] = {
+			fw_files_29xxx,
+			sizeof(fw_files_29xxx)/sizeof(fw_files_29xxx[0]),
+		},
+#ifdef CONFIG_VIDEO_PVRUSB2_24XXX
+		[PVR2_HDW_TYPE_24XXX] = {
+			fw_files_24xxx,
+			sizeof(fw_files_24xxx)/sizeof(fw_files_24xxx[0]),
+		},
+#endif
+	};
+	hdw->fw1_state = FW1_STATE_FAILED; // default result
+
+	trace_firmware("pvr2_upload_firmware1");
+
+	ret = pvr2_locate_firmware(hdw,&fw_entry,"fx2 controller",
+				   fw_file_defs[hdw->hdw_type].cnt,
+				   fw_file_defs[hdw->hdw_type].lst);
+	if (ret < 0) {
+		if (ret == -ENOENT) hdw->fw1_state = FW1_STATE_MISSING;
+		return ret;
+	}
+
+	usb_settoggle(hdw->usb_dev, 0 & 0xf, !(0 & USB_DIR_IN), 0);
+	usb_clear_halt(hdw->usb_dev, usb_sndbulkpipe(hdw->usb_dev, 0 & 0x7f));
+
+	pipe = usb_sndctrlpipe(hdw->usb_dev, 0);
+
+	if (fw_entry->size != 0x2000){
+		pvr2_trace(PVR2_TRACE_ERROR_LEGS,"wrong fx2 firmware size");
+		release_firmware(fw_entry);
+		return -ENOMEM;
+	}
+
+	fw_ptr = kmalloc(0x800, GFP_KERNEL);
+	if (fw_ptr == NULL){
+		release_firmware(fw_entry);
+		return -ENOMEM;
+	}
+
+	/* We have to hold the CPU during firmware upload. */
+	pvr2_hdw_cpureset_assert(hdw,1);
+
+	/* upload the firmware to address 0000-1fff in 2048 (=0x800) bytes
+	   chunk. */
+
+	ret = 0;
+	for(address = 0; address < fw_entry->size; address += 0x800) {
+		memcpy(fw_ptr, fw_entry->data + address, 0x800);
+		ret += usb_control_msg(hdw->usb_dev, pipe, 0xa0, 0x40, address,
+				       0, fw_ptr, 0x800, HZ);
+	}
+
+	trace_firmware("Upload done, releasing device's CPU");
+
+	/* Now release the CPU.  It will disconnect and reconnect later. */
+	pvr2_hdw_cpureset_assert(hdw,0);
+
+	kfree(fw_ptr);
+	release_firmware(fw_entry);
+
+	trace_firmware("Upload done (%d bytes sent)",ret);
+
+	/* We should have written 8192 bytes */
+	if (ret == 8192) {
+		hdw->fw1_state = FW1_STATE_RELOAD;
+		return 0;
+	}
+
+	return -EIO;
+}
+
+
+/*
+ * pvr2_upload_firmware2()
+ *
+ * This uploads encoder firmware on endpoint 2.
+ *
+ */
+
+int pvr2_upload_firmware2(struct pvr2_hdw *hdw)
+{
+	const struct firmware *fw_entry = NULL;
+	void  *fw_ptr;
+	unsigned int pipe, fw_len, fw_done;
+	int actual_length;
+	int ret = 0;
+	int fwidx;
+	static const char *fw_files[] = {
+		CX2341X_FIRM_ENC_FILENAME,
+	};
+
+	trace_firmware("pvr2_upload_firmware2");
+
+	ret = pvr2_locate_firmware(hdw,&fw_entry,"encoder",
+				   sizeof(fw_files)/sizeof(fw_files[0]),
+				   fw_files);
+	if (ret < 0) return ret;
+	fwidx = ret;
+	ret = 0;
+	/* Since we're about to completely reinitialize the encoder,
+	   invalidate our cached copy of its configuration state.  Next
+	   time we configure the encoder, then we'll fully configure it. */
+	hdw->enc_cur_valid = 0;
+
+	/* First prepare firmware loading */
+	ret |= pvr2_write_register(hdw, 0x0048, 0xffffffff); /*interrupt mask*/
+	ret |= pvr2_hdw_gpio_chg_dir(hdw,0xffffffff,0x00000088); /*gpio dir*/
+	ret |= pvr2_hdw_gpio_chg_out(hdw,0xffffffff,0x00000008); /*gpio output state*/
+	ret |= pvr2_hdw_cmd_deep_reset(hdw);
+	ret |= pvr2_write_register(hdw, 0xa064, 0x00000000); /*APU command*/
+	ret |= pvr2_hdw_gpio_chg_dir(hdw,0xffffffff,0x00000408); /*gpio dir*/
+	ret |= pvr2_hdw_gpio_chg_out(hdw,0xffffffff,0x00000008); /*gpio output state*/
+	ret |= pvr2_write_register(hdw, 0x9058, 0xffffffed); /*VPU ctrl*/
+	ret |= pvr2_write_register(hdw, 0x9054, 0xfffffffd); /*reset hw blocks*/
+	ret |= pvr2_write_register(hdw, 0x07f8, 0x80000800); /*encoder SDRAM refresh*/
+	ret |= pvr2_write_register(hdw, 0x07fc, 0x0000001a); /*encoder SDRAM pre-charge*/
+	ret |= pvr2_write_register(hdw, 0x0700, 0x00000000); /*I2C clock*/
+	ret |= pvr2_write_register(hdw, 0xaa00, 0x00000000); /*unknown*/
+	ret |= pvr2_write_register(hdw, 0xaa04, 0x00057810); /*unknown*/
+	ret |= pvr2_write_register(hdw, 0xaa10, 0x00148500); /*unknown*/
+	ret |= pvr2_write_register(hdw, 0xaa18, 0x00840000); /*unknown*/
+	ret |= pvr2_write_u8(hdw, 0x52, 0);
+	ret |= pvr2_write_u16(hdw, 0x0600, 0);
+
+	if (ret) {
+		pvr2_trace(PVR2_TRACE_ERROR_LEGS,
+			   "firmware2 upload prep failed, ret=%d",ret);
+		release_firmware(fw_entry);
+		return ret;
+	}
+
+	/* Now send firmware */
+
+	fw_len = fw_entry->size;
+
+	if (fw_len % FIRMWARE_CHUNK_SIZE) {
+		pvr2_trace(PVR2_TRACE_ERROR_LEGS,
+			   "size of %s firmware"
+			   " must be a multiple of 8192B",
+			   fw_files[fwidx]);
+		release_firmware(fw_entry);
+		return -1;
+	}
+
+	fw_ptr = kmalloc(FIRMWARE_CHUNK_SIZE, GFP_KERNEL);
+	if (fw_ptr == NULL){
+		release_firmware(fw_entry);
+		pvr2_trace(PVR2_TRACE_ERROR_LEGS,
+			   "failed to allocate memory for firmware2 upload");
+		return -ENOMEM;
+	}
+
+	pipe = usb_sndbulkpipe(hdw->usb_dev, PVR2_FIRMWARE_ENDPOINT);
+
+	for (fw_done = 0 ; (fw_done < fw_len) && !ret ;
+	     fw_done += FIRMWARE_CHUNK_SIZE ) {
+		int i;
+		memcpy(fw_ptr, fw_entry->data + fw_done, FIRMWARE_CHUNK_SIZE);
+		/* Usbsnoop log  shows that we must swap bytes... */
+		for (i = 0; i < FIRMWARE_CHUNK_SIZE/4 ; i++)
+			((u32 *)fw_ptr)[i] = ___swab32(((u32 *)fw_ptr)[i]);
+
+		ret |= usb_bulk_msg(hdw->usb_dev, pipe, fw_ptr,
+				    FIRMWARE_CHUNK_SIZE,
+				    &actual_length, HZ);
+		ret |= (actual_length != FIRMWARE_CHUNK_SIZE);
+	}
+
+	trace_firmware("upload of %s : %i / %i ",
+		       fw_files[fwidx],fw_done,fw_len);
+
+	kfree(fw_ptr);
+	release_firmware(fw_entry);
+
+	if (ret) {
+		pvr2_trace(PVR2_TRACE_ERROR_LEGS,
+			   "firmware2 upload transfer failure");
+		return ret;
+	}
+
+	/* Finish upload */
+
+	ret |= pvr2_write_register(hdw, 0x9054, 0xffffffff); /*reset hw blocks*/
+	ret |= pvr2_write_register(hdw, 0x9058, 0xffffffe8); /*VPU ctrl*/
+	ret |= pvr2_write_u16(hdw, 0x0600, 0);
+
+	if (ret) {
+		pvr2_trace(PVR2_TRACE_ERROR_LEGS,
+			   "firmware2 upload post-proc failure");
+	} else {
+		hdw->subsys_enabled_mask |= (1<<PVR2_SUBSYS_B_ENC_FIRMWARE);
+	}
+	return ret;
+}
+
+
+#define FIRMWARE_RECOVERY_BITS \
+	((1<<PVR2_SUBSYS_B_ENC_CFG) | \
+	 (1<<PVR2_SUBSYS_B_ENC_RUN) | \
+	 (1<<PVR2_SUBSYS_B_ENC_FIRMWARE) | \
+	 (1<<PVR2_SUBSYS_B_USBSTREAM_RUN))
+
+/*
+
+  This single function is key to pretty much everything.  The pvrusb2
+  device can logically be viewed as a series of subsystems which can be
+  stopped / started or unconfigured / configured.  To get things streaming,
+  one must configure everything and start everything, but there may be
+  various reasons over time to deconfigure something or stop something.
+  This function handles all of this activity.  Everything EVERYWHERE that
+  must affect a subsystem eventually comes here to do the work.
+
+  The current state of all subsystems is represented by a single bit mask,
+  known as subsys_enabled_mask.  The bit positions are defined by the
+  PVR2_SUBSYS_xxxx macros, with one subsystem per bit position.  At any
+  time the set of configured or active subsystems can be queried just by
+  looking at that mask.  To change bits in that mask, this function here
+  must be called.  The "msk" argument indicates which bit positions to
+  change, and the "val" argument defines the new values for the positions
+  defined by "msk".
+
+  There is a priority ordering of starting / stopping things, and for
+  multiple requested changes, this function implements that ordering.
+  (Thus we will act on a request to load encoder firmware before we
+  configure the encoder.)  In addition to priority ordering, there is a
+  recovery strategy implemented here.  If a particular step fails and we
+  detect that failure, this function will clear the affected subsystem bits
+  and restart.  Thus we have a means for recovering from a dead encoder:
+  Clear all bits that correspond to subsystems that we need to restart /
+  reconfigure and start over.
+
+*/
+static void pvr2_hdw_subsys_bit_chg_no_lock(struct pvr2_hdw *hdw,
+					    unsigned long msk,
+					    unsigned long val)
+{
+	unsigned long nmsk;
+	unsigned long vmsk;
+	int ret;
+	unsigned int tryCount = 0;
+
+	if (!hdw->flag_ok) return;
+
+	msk &= PVR2_SUBSYS_ALL;
+	nmsk = (hdw->subsys_enabled_mask & ~msk) | (val & msk);
+	nmsk &= PVR2_SUBSYS_ALL;
+
+	for (;;) {
+		tryCount++;
+		if (!((nmsk ^ hdw->subsys_enabled_mask) &
+		      PVR2_SUBSYS_ALL)) break;
+		if (tryCount > 4) {
+			pvr2_trace(PVR2_TRACE_ERROR_LEGS,
+				   "Too many retries when configuring device;"
+				   " giving up");
+			pvr2_hdw_render_useless(hdw);
+			break;
+		}
+		if (tryCount > 1) {
+			pvr2_trace(PVR2_TRACE_ERROR_LEGS,
+				   "Retrying device reconfiguration");
+		}
+		pvr2_trace(PVR2_TRACE_INIT,
+			   "subsys mask changing 0x%lx:0x%lx"
+			   " from 0x%lx to 0x%lx",
+			   msk,val,hdw->subsys_enabled_mask,nmsk);
+
+		vmsk = (nmsk ^ hdw->subsys_enabled_mask) &
+			hdw->subsys_enabled_mask;
+		if (vmsk) {
+			if (vmsk & (1<<PVR2_SUBSYS_B_ENC_RUN)) {
+				pvr2_trace(PVR2_TRACE_CTL,
+					   "/*---TRACE_CTL----*/"
+					   " pvr2_encoder_stop");
+				ret = pvr2_encoder_stop(hdw);
+				if (ret) {
+					pvr2_trace(PVR2_TRACE_ERROR_LEGS,
+						   "Error recovery initiated");
+					hdw->subsys_enabled_mask &=
+						~FIRMWARE_RECOVERY_BITS;
+					continue;
+				}
+			}
+			if (vmsk & (1<<PVR2_SUBSYS_B_USBSTREAM_RUN)) {
+				pvr2_trace(PVR2_TRACE_CTL,
+					   "/*---TRACE_CTL----*/"
+					   " pvr2_hdw_cmd_usbstream(0)");
+				pvr2_hdw_cmd_usbstream(hdw,0);
+			}
+			if (vmsk & (1<<PVR2_SUBSYS_B_DIGITIZER_RUN)) {
+				pvr2_trace(PVR2_TRACE_CTL,
+					   "/*---TRACE_CTL----*/"
+					   " decoder disable");
+				if (hdw->decoder_ctrl) {
+					hdw->decoder_ctrl->enable(
+						hdw->decoder_ctrl->ctxt,0);
+				} else {
+					pvr2_trace(PVR2_TRACE_ERROR_LEGS,
+						   "WARNING:"
+						   " No decoder present");
+				}
+				hdw->subsys_enabled_mask &=
+					~(1<<PVR2_SUBSYS_B_DIGITIZER_RUN);
+			}
+			if (vmsk & PVR2_SUBSYS_CFG_ALL) {
+				hdw->subsys_enabled_mask &=
+					~(vmsk & PVR2_SUBSYS_CFG_ALL);
+			}
+		}
+		vmsk = (nmsk ^ hdw->subsys_enabled_mask) & nmsk;
+		if (vmsk) {
+			if (vmsk & (1<<PVR2_SUBSYS_B_ENC_FIRMWARE)) {
+				pvr2_trace(PVR2_TRACE_CTL,
+					   "/*---TRACE_CTL----*/"
+					   " pvr2_upload_firmware2");
+				ret = pvr2_upload_firmware2(hdw);
+				if (ret) {
+					pvr2_trace(PVR2_TRACE_ERROR_LEGS,
+						   "Failure uploading encoder"
+						   " firmware");
+					pvr2_hdw_render_useless(hdw);
+					break;
+				}
+			}
+			if (vmsk & (1<<PVR2_SUBSYS_B_ENC_CFG)) {
+				pvr2_trace(PVR2_TRACE_CTL,
+					   "/*---TRACE_CTL----*/"
+					   " pvr2_encoder_configure");
+				ret = pvr2_encoder_configure(hdw);
+				if (ret) {
+					pvr2_trace(PVR2_TRACE_ERROR_LEGS,
+						   "Error recovery initiated");
+					hdw->subsys_enabled_mask &=
+						~FIRMWARE_RECOVERY_BITS;
+					continue;
+				}
+			}
+			if (vmsk & (1<<PVR2_SUBSYS_B_DIGITIZER_RUN)) {
+				pvr2_trace(PVR2_TRACE_CTL,
+					   "/*---TRACE_CTL----*/"
+					   " decoder enable");
+				if (hdw->decoder_ctrl) {
+					hdw->decoder_ctrl->enable(
+						hdw->decoder_ctrl->ctxt,!0);
+				} else {
+					pvr2_trace(PVR2_TRACE_ERROR_LEGS,
+						   "WARNING:"
+						   " No decoder present");
+				}
+				hdw->subsys_enabled_mask |=
+					(1<<PVR2_SUBSYS_B_DIGITIZER_RUN);
+			}
+			if (vmsk & (1<<PVR2_SUBSYS_B_USBSTREAM_RUN)) {
+				pvr2_trace(PVR2_TRACE_CTL,
+					   "/*---TRACE_CTL----*/"
+					   " pvr2_hdw_cmd_usbstream(1)");
+				pvr2_hdw_cmd_usbstream(hdw,!0);
+			}
+			if (vmsk & (1<<PVR2_SUBSYS_B_ENC_RUN)) {
+				pvr2_trace(PVR2_TRACE_CTL,
+					   "/*---TRACE_CTL----*/"
+					   " pvr2_encoder_start");
+				ret = pvr2_encoder_start(hdw);
+				if (ret) {
+					pvr2_trace(PVR2_TRACE_ERROR_LEGS,
+						   "Error recovery initiated");
+					hdw->subsys_enabled_mask &=
+						~FIRMWARE_RECOVERY_BITS;
+					continue;
+				}
+			}
+		}
+	}
+}
+
+
+void pvr2_hdw_subsys_bit_chg(struct pvr2_hdw *hdw,
+			     unsigned long msk,unsigned long val)
+{
+	LOCK_TAKE(hdw->big_lock); do {
+		pvr2_hdw_subsys_bit_chg_no_lock(hdw,msk,val);
+	} while (0); LOCK_GIVE(hdw->big_lock);
+}
+
+
+unsigned long pvr2_hdw_subsys_get(struct pvr2_hdw *hdw)
+{
+	return hdw->subsys_enabled_mask;
+}
+
+
+unsigned long pvr2_hdw_subsys_stream_get(struct pvr2_hdw *hdw)
+{
+	return hdw->subsys_stream_mask;
+}
+
+
+static void pvr2_hdw_subsys_stream_bit_chg_no_lock(struct pvr2_hdw *hdw,
+						   unsigned long msk,
+						   unsigned long val)
+{
+	unsigned long val2;
+	msk &= PVR2_SUBSYS_ALL;
+	val2 = ((hdw->subsys_stream_mask & ~msk) | (val & msk));
+	pvr2_trace(PVR2_TRACE_INIT,
+		   "stream mask changing 0x%lx:0x%lx from 0x%lx to 0x%lx",
+		   msk,val,hdw->subsys_stream_mask,val2);
+	hdw->subsys_stream_mask = val2;
+}
+
+
+void pvr2_hdw_subsys_stream_bit_chg(struct pvr2_hdw *hdw,
+				    unsigned long msk,
+				    unsigned long val)
+{
+	LOCK_TAKE(hdw->big_lock); do {
+		pvr2_hdw_subsys_stream_bit_chg_no_lock(hdw,msk,val);
+	} while (0); LOCK_GIVE(hdw->big_lock);
+}
+
+
+static int pvr2_hdw_set_streaming_no_lock(struct pvr2_hdw *hdw,int enableFl)
+{
+	if ((!enableFl) == !(hdw->flag_streaming_enabled)) return 0;
+	if (enableFl) {
+		pvr2_trace(PVR2_TRACE_START_STOP,
+			   "/*--TRACE_STREAM--*/ enable");
+		pvr2_hdw_subsys_bit_chg_no_lock(hdw,~0,~0);
+	} else {
+		pvr2_trace(PVR2_TRACE_START_STOP,
+			   "/*--TRACE_STREAM--*/ disable");
+		pvr2_hdw_subsys_bit_chg_no_lock(hdw,hdw->subsys_stream_mask,0);
+	}
+	if (!hdw->flag_ok) return -EIO;
+	hdw->flag_streaming_enabled = enableFl != 0;
+	return 0;
+}
+
+
+int pvr2_hdw_get_streaming(struct pvr2_hdw *hdw)
+{
+	return hdw->flag_streaming_enabled != 0;
+}
+
+
+int pvr2_hdw_set_streaming(struct pvr2_hdw *hdw,int enable_flag)
+{
+	int ret;
+	LOCK_TAKE(hdw->big_lock); do {
+		ret = pvr2_hdw_set_streaming_no_lock(hdw,enable_flag);
+	} while (0); LOCK_GIVE(hdw->big_lock);
+	return ret;
+}
+
+
+static int pvr2_hdw_set_stream_type_no_lock(struct pvr2_hdw *hdw,
+					    enum pvr2_config config)
+{
+	unsigned long sm = hdw->subsys_enabled_mask;
+	if (!hdw->flag_ok) return -EIO;
+	pvr2_hdw_subsys_bit_chg_no_lock(hdw,hdw->subsys_stream_mask,0);
+	hdw->config = config;
+	pvr2_hdw_subsys_bit_chg_no_lock(hdw,~0,sm);
+	return 0;
+}
+
+
+int pvr2_hdw_set_stream_type(struct pvr2_hdw *hdw,enum pvr2_config config)
+{
+	int ret;
+	if (!hdw->flag_ok) return -EIO;
+	LOCK_TAKE(hdw->big_lock);
+	ret = pvr2_hdw_set_stream_type_no_lock(hdw,config);
+	LOCK_GIVE(hdw->big_lock);
+	return ret;
+}
+
+
+static int get_default_tuner_type(struct pvr2_hdw *hdw)
+{
+	int unit_number = hdw->unit_number;
+	int tp = -1;
+	if ((unit_number >= 0) && (unit_number < PVR_NUM)) {
+		tp = tuner[unit_number];
+	}
+	if (tp < 0) return -EINVAL;
+	hdw->tuner_type = tp;
+	return 0;
+}
+
+
+static v4l2_std_id get_default_standard(struct pvr2_hdw *hdw)
+{
+	int unit_number = hdw->unit_number;
+	int tp = 0;
+	if ((unit_number >= 0) && (unit_number < PVR_NUM)) {
+		tp = video_std[unit_number];
+	}
+	return tp;
+}
+
+
+static unsigned int get_default_error_tolerance(struct pvr2_hdw *hdw)
+{
+	int unit_number = hdw->unit_number;
+	int tp = 0;
+	if ((unit_number >= 0) && (unit_number < PVR_NUM)) {
+		tp = tolerance[unit_number];
+	}
+	return tp;
+}
+
+
+static int pvr2_hdw_check_firmware(struct pvr2_hdw *hdw)
+{
+	/* Try a harmless request to fetch the eeprom's address over
+	   endpoint 1.  See what happens.  Only the full FX2 image can
+	   respond to this.  If this probe fails then likely the FX2
+	   firmware needs be loaded. */
+	int result;
+	LOCK_TAKE(hdw->ctl_lock); do {
+		hdw->cmd_buffer[0] = 0xeb;
+		result = pvr2_send_request_ex(hdw,HZ*1,!0,
+					   hdw->cmd_buffer,1,
+					   hdw->cmd_buffer,1);
+		if (result < 0) break;
+	} while(0); LOCK_GIVE(hdw->ctl_lock);
+	if (result) {
+		pvr2_trace(PVR2_TRACE_INIT,
+			   "Probe of device endpoint 1 result status %d",
+			   result);
+	} else {
+		pvr2_trace(PVR2_TRACE_INIT,
+			   "Probe of device endpoint 1 succeeded");
+	}
+	return result == 0;
+}
+
+static void pvr2_hdw_setup_std(struct pvr2_hdw *hdw)
+{
+	char buf[40];
+	unsigned int bcnt;
+	v4l2_std_id std1,std2;
+
+	std1 = get_default_standard(hdw);
+
+	bcnt = pvr2_std_id_to_str(buf,sizeof(buf),hdw->std_mask_eeprom);
+	pvr2_trace(PVR2_TRACE_INIT,
+		   "Supported video standard(s) reported by eeprom: %.*s",
+		   bcnt,buf);
+
+	hdw->std_mask_avail = hdw->std_mask_eeprom;
+
+	std2 = std1 & ~hdw->std_mask_avail;
+	if (std2) {
+		bcnt = pvr2_std_id_to_str(buf,sizeof(buf),std2);
+		pvr2_trace(PVR2_TRACE_INIT,
+			   "Expanding supported video standards"
+			   " to include: %.*s",
+			   bcnt,buf);
+		hdw->std_mask_avail |= std2;
+	}
+
+	pvr2_hdw_internal_set_std_avail(hdw);
+
+	if (std1) {
+		bcnt = pvr2_std_id_to_str(buf,sizeof(buf),std1);
+		pvr2_trace(PVR2_TRACE_INIT,
+			   "Initial video standard forced to %.*s",
+			   bcnt,buf);
+		hdw->std_mask_cur = std1;
+		hdw->std_dirty = !0;
+		pvr2_hdw_internal_find_stdenum(hdw);
+		return;
+	}
+
+	if (hdw->std_enum_cnt > 1) {
+		// Autoselect the first listed standard
+		hdw->std_enum_cur = 1;
+		hdw->std_mask_cur = hdw->std_defs[hdw->std_enum_cur-1].id;
+		hdw->std_dirty = !0;
+		pvr2_trace(PVR2_TRACE_INIT,
+			   "Initial video standard auto-selected to %s",
+			   hdw->std_defs[hdw->std_enum_cur-1].name);
+		return;
+	}
+
+	pvr2_trace(PVR2_TRACE_ERROR_LEGS,
+		   "Unable to select a viable initial video standard");
+}
+
+
+static void pvr2_hdw_setup_low(struct pvr2_hdw *hdw)
+{
+	int ret;
+	unsigned int idx;
+	struct pvr2_ctrl *cptr;
+	int reloadFl = 0;
+	if (!reloadFl) {
+		reloadFl = (hdw->usb_intf->cur_altsetting->desc.bNumEndpoints
+			    == 0);
+		if (reloadFl) {
+			pvr2_trace(PVR2_TRACE_INIT,
+				   "USB endpoint config looks strange"
+				   "; possibly firmware needs to be loaded");
+		}
+	}
+	if (!reloadFl) {
+		reloadFl = !pvr2_hdw_check_firmware(hdw);
+		if (reloadFl) {
+			pvr2_trace(PVR2_TRACE_INIT,
+				   "Check for FX2 firmware failed"
+				   "; possibly firmware needs to be loaded");
+		}
+	}
+	if (reloadFl) {
+		if (pvr2_upload_firmware1(hdw) != 0) {
+			pvr2_trace(PVR2_TRACE_ERROR_LEGS,
+				   "Failure uploading firmware1");
+		}
+		return;
+	}
+	hdw->fw1_state = FW1_STATE_OK;
+
+	if (initusbreset) {
+		pvr2_hdw_device_reset(hdw);
+	}
+	if (!pvr2_hdw_dev_ok(hdw)) return;
+
+	for (idx = 0; idx < pvr2_client_lists[hdw->hdw_type].cnt; idx++) {
+		request_module(pvr2_client_lists[hdw->hdw_type].lst[idx]);
+	}
+
+	pvr2_hdw_cmd_powerup(hdw);
+	if (!pvr2_hdw_dev_ok(hdw)) return;
+
+	if (pvr2_upload_firmware2(hdw)){
+		pvr2_trace(PVR2_TRACE_ERROR_LEGS,"device unstable!!");
+		pvr2_hdw_render_useless(hdw);
+		return;
+	}
+
+	// This step MUST happen after the earlier powerup step.
+	pvr2_i2c_core_init(hdw);
+	if (!pvr2_hdw_dev_ok(hdw)) return;
+
+	for (idx = 0; idx < CTRLDEF_COUNT; idx++) {
+		cptr = hdw->controls + idx;
+		if (cptr->info->skip_init) continue;
+		if (!cptr->info->set_value) continue;
+		cptr->info->set_value(cptr,~0,cptr->info->default_value);
+	}
+
+	// Do not use pvr2_reset_ctl_endpoints() here.  It is not
+	// thread-safe against the normal pvr2_send_request() mechanism.
+	// (We should make it thread safe).
+
+	ret = pvr2_hdw_get_eeprom_addr(hdw);
+	if (!pvr2_hdw_dev_ok(hdw)) return;
+	if (ret < 0) {
+		pvr2_trace(PVR2_TRACE_ERROR_LEGS,
+			   "Unable to determine location of eeprom, skipping");
+	} else {
+		hdw->eeprom_addr = ret;
+		pvr2_eeprom_analyze(hdw);
+		if (!pvr2_hdw_dev_ok(hdw)) return;
+	}
+
+	pvr2_hdw_setup_std(hdw);
+
+	if (!get_default_tuner_type(hdw)) {
+		pvr2_trace(PVR2_TRACE_INIT,
+			   "pvr2_hdw_setup: Tuner type overridden to %d",
+			   hdw->tuner_type);
+	}
+
+	hdw->tuner_updated = !0;
+	pvr2_i2c_core_check_stale(hdw);
+	hdw->tuner_updated = 0;
+
+	if (!pvr2_hdw_dev_ok(hdw)) return;
+
+	pvr2_hdw_commit_ctl_internal(hdw);
+	if (!pvr2_hdw_dev_ok(hdw)) return;
+
+	hdw->vid_stream = pvr2_stream_create();
+	if (!pvr2_hdw_dev_ok(hdw)) return;
+	pvr2_trace(PVR2_TRACE_INIT,
+		   "pvr2_hdw_setup: video stream is %p",hdw->vid_stream);
+	if (hdw->vid_stream) {
+		idx = get_default_error_tolerance(hdw);
+		if (idx) {
+			pvr2_trace(PVR2_TRACE_INIT,
+				   "pvr2_hdw_setup: video stream %p"
+				   " setting tolerance %u",
+				   hdw->vid_stream,idx);
+		}
+		pvr2_stream_setup(hdw->vid_stream,hdw->usb_dev,
+				  PVR2_VID_ENDPOINT,idx);
+	}
+
+	if (!pvr2_hdw_dev_ok(hdw)) return;
+
+	/* Make sure everything is up to date */
+	pvr2_i2c_core_sync(hdw);
+
+	if (!pvr2_hdw_dev_ok(hdw)) return;
+
+	hdw->flag_init_ok = !0;
+}
+
+
+int pvr2_hdw_setup(struct pvr2_hdw *hdw)
+{
+	pvr2_trace(PVR2_TRACE_INIT,"pvr2_hdw_setup(hdw=%p) begin",hdw);
+	LOCK_TAKE(hdw->big_lock); do {
+		pvr2_hdw_setup_low(hdw);
+		pvr2_trace(PVR2_TRACE_INIT,
+			   "pvr2_hdw_setup(hdw=%p) done, ok=%d init_ok=%d",
+			   hdw,hdw->flag_ok,hdw->flag_init_ok);
+		if (pvr2_hdw_dev_ok(hdw)) {
+			if (pvr2_hdw_init_ok(hdw)) {
+				pvr2_trace(
+					PVR2_TRACE_INFO,
+					"Device initialization"
+					" completed successfully.");
+				break;
+			}
+			if (hdw->fw1_state == FW1_STATE_RELOAD) {
+				pvr2_trace(
+					PVR2_TRACE_INFO,
+					"Device microcontroller firmware"
+					" (re)loaded; it should now reset"
+					" and reconnect.");
+				break;
+			}
+			pvr2_trace(
+				PVR2_TRACE_ERROR_LEGS,
+				"Device initialization was not successful.");
+			if (hdw->fw1_state == FW1_STATE_MISSING) {
+				pvr2_trace(
+					PVR2_TRACE_ERROR_LEGS,
+					"Giving up since device"
+					" microcontroller firmware"
+					" appears to be missing.");
+				break;
+			}
+		}
+		if (procreload) {
+			pvr2_trace(
+				PVR2_TRACE_ERROR_LEGS,
+				"Attempting pvrusb2 recovery by reloading"
+				" primary firmware.");
+			pvr2_trace(
+				PVR2_TRACE_ERROR_LEGS,
+				"If this works, device should disconnect"
+				" and reconnect in a sane state.");
+			hdw->fw1_state = FW1_STATE_UNKNOWN;
+			pvr2_upload_firmware1(hdw);
+		} else {
+			pvr2_trace(
+				PVR2_TRACE_ERROR_LEGS,
+				"***WARNING*** pvrusb2 device hardware"
+				" appears to be jammed"
+				" and I can't clear it.");
+			pvr2_trace(
+				PVR2_TRACE_ERROR_LEGS,
+				"You might need to power cycle"
+				" the pvrusb2 device"
+				" in order to recover.");
+		}
+	} while (0); LOCK_GIVE(hdw->big_lock);
+	pvr2_trace(PVR2_TRACE_INIT,"pvr2_hdw_setup(hdw=%p) end",hdw);
+	return hdw->flag_init_ok;
+}
+
+
+/* Create and return a structure for interacting with the underlying
+   hardware */
+struct pvr2_hdw *pvr2_hdw_create(struct usb_interface *intf,
+				 const struct usb_device_id *devid)
+{
+	unsigned int idx,cnt1,cnt2;
+	struct pvr2_hdw *hdw;
+	unsigned int hdw_type;
+	int valid_std_mask;
+	struct pvr2_ctrl *cptr;
+	__u8 ifnum;
+	struct v4l2_queryctrl qctrl;
+	struct pvr2_ctl_info *ciptr;
+
+	hdw_type = devid - pvr2_device_table;
+	if (hdw_type >=
+	    sizeof(pvr2_device_names)/sizeof(pvr2_device_names[0])) {
+		pvr2_trace(PVR2_TRACE_ERROR_LEGS,
+			   "Bogus device type of %u reported",hdw_type);
+		return NULL;
+	}
+
+	hdw = kmalloc(sizeof(*hdw),GFP_KERNEL);
+	pvr2_trace(PVR2_TRACE_INIT,"pvr2_hdw_create: hdw=%p, type \"%s\"",
+		   hdw,pvr2_device_names[hdw_type]);
+	if (!hdw) goto fail;
+	memset(hdw,0,sizeof(*hdw));
+	cx2341x_fill_defaults(&hdw->enc_ctl_state);
+
+	hdw->control_cnt = CTRLDEF_COUNT;
+	hdw->control_cnt += MPEGDEF_COUNT;
+	hdw->controls = kmalloc(sizeof(struct pvr2_ctrl) * hdw->control_cnt,
+				GFP_KERNEL);
+	if (!hdw->controls) goto fail;
+	memset(hdw->controls,0,sizeof(struct pvr2_ctrl) * hdw->control_cnt);
+	hdw->hdw_type = hdw_type;
+	for (idx = 0; idx < hdw->control_cnt; idx++) {
+		cptr = hdw->controls + idx;
+		cptr->hdw = hdw;
+	}
+	for (idx = 0; idx < 32; idx++) {
+		hdw->std_mask_ptrs[idx] = hdw->std_mask_names[idx];
+	}
+	for (idx = 0; idx < CTRLDEF_COUNT; idx++) {
+		cptr = hdw->controls + idx;
+		cptr->info = control_defs+idx;
+	}
+	/* Define and configure additional controls from cx2341x module. */
+	hdw->mpeg_ctrl_info = kmalloc(
+		sizeof(*(hdw->mpeg_ctrl_info)) * MPEGDEF_COUNT, GFP_KERNEL);
+	if (!hdw->mpeg_ctrl_info) goto fail;
+	memset(hdw->mpeg_ctrl_info,0,
+	       sizeof(*(hdw->mpeg_ctrl_info)) * MPEGDEF_COUNT);
+	for (idx = 0; idx < MPEGDEF_COUNT; idx++) {
+		cptr = hdw->controls + idx + CTRLDEF_COUNT;
+		ciptr = &(hdw->mpeg_ctrl_info[idx].info);
+		ciptr->desc = hdw->mpeg_ctrl_info[idx].desc;
+		ciptr->name = mpeg_ids[idx].strid;
+		ciptr->v4l_id = mpeg_ids[idx].id;
+		ciptr->skip_init = !0;
+		ciptr->get_value = ctrl_cx2341x_get;
+		ciptr->get_v4lflags = ctrl_cx2341x_getv4lflags;
+		ciptr->is_dirty = ctrl_cx2341x_is_dirty;
+		if (!idx) ciptr->clear_dirty = ctrl_cx2341x_clear_dirty;
+		qctrl.id = ciptr->v4l_id;
+		cx2341x_ctrl_query(&hdw->enc_ctl_state,&qctrl);
+		if (!(qctrl.flags & V4L2_CTRL_FLAG_READ_ONLY)) {
+			ciptr->set_value = ctrl_cx2341x_set;
+		}
+		strncpy(hdw->mpeg_ctrl_info[idx].desc,qctrl.name,
+			PVR2_CTLD_INFO_DESC_SIZE);
+		hdw->mpeg_ctrl_info[idx].desc[PVR2_CTLD_INFO_DESC_SIZE-1] = 0;
+		ciptr->default_value = qctrl.default_value;
+		switch (qctrl.type) {
+		default:
+		case V4L2_CTRL_TYPE_INTEGER:
+			ciptr->type = pvr2_ctl_int;
+			ciptr->def.type_int.min_value = qctrl.minimum;
+			ciptr->def.type_int.max_value = qctrl.maximum;
+			break;
+		case V4L2_CTRL_TYPE_BOOLEAN:
+			ciptr->type = pvr2_ctl_bool;
+			break;
+		case V4L2_CTRL_TYPE_MENU:
+			ciptr->type = pvr2_ctl_enum;
+			ciptr->def.type_enum.value_names =
+				cx2341x_ctrl_get_menu(ciptr->v4l_id);
+			for (cnt1 = 0;
+			     ciptr->def.type_enum.value_names[cnt1] != NULL;
+			     cnt1++) { }
+			ciptr->def.type_enum.count = cnt1;
+			break;
+		}
+		cptr->info = ciptr;
+	}
+
+	// Initialize video standard enum dynamic control
+	cptr = pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_STDENUM);
+	if (cptr) {
+		memcpy(&hdw->std_info_enum,cptr->info,
+		       sizeof(hdw->std_info_enum));
+		cptr->info = &hdw->std_info_enum;
+
+	}
+	// Initialize control data regarding video standard masks
+	valid_std_mask = pvr2_std_get_usable();
+	for (idx = 0; idx < 32; idx++) {
+		if (!(valid_std_mask & (1 << idx))) continue;
+		cnt1 = pvr2_std_id_to_str(
+			hdw->std_mask_names[idx],
+			sizeof(hdw->std_mask_names[idx])-1,
+			1 << idx);
+		hdw->std_mask_names[idx][cnt1] = 0;
+	}
+	cptr = pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_STDAVAIL);
+	if (cptr) {
+		memcpy(&hdw->std_info_avail,cptr->info,
+		       sizeof(hdw->std_info_avail));
+		cptr->info = &hdw->std_info_avail;
+		hdw->std_info_avail.def.type_bitmask.bit_names =
+			hdw->std_mask_ptrs;
+		hdw->std_info_avail.def.type_bitmask.valid_bits =
+			valid_std_mask;
+	}
+	cptr = pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_STDCUR);
+	if (cptr) {
+		memcpy(&hdw->std_info_cur,cptr->info,
+		       sizeof(hdw->std_info_cur));
+		cptr->info = &hdw->std_info_cur;
+		hdw->std_info_cur.def.type_bitmask.bit_names =
+			hdw->std_mask_ptrs;
+		hdw->std_info_avail.def.type_bitmask.valid_bits =
+			valid_std_mask;
+	}
+
+	hdw->eeprom_addr = -1;
+	hdw->unit_number = -1;
+	hdw->v4l_minor_number = -1;
+	hdw->ctl_write_buffer = kmalloc(PVR2_CTL_BUFFSIZE,GFP_KERNEL);
+	if (!hdw->ctl_write_buffer) goto fail;
+	hdw->ctl_read_buffer = kmalloc(PVR2_CTL_BUFFSIZE,GFP_KERNEL);
+	if (!hdw->ctl_read_buffer) goto fail;
+	hdw->ctl_write_urb = usb_alloc_urb(0,GFP_KERNEL);
+	if (!hdw->ctl_write_urb) goto fail;
+	hdw->ctl_read_urb = usb_alloc_urb(0,GFP_KERNEL);
+	if (!hdw->ctl_read_urb) goto fail;
+
+	down(&pvr2_unit_sem); do {
+		for (idx = 0; idx < PVR_NUM; idx++) {
+			if (unit_pointers[idx]) continue;
+			hdw->unit_number = idx;
+			unit_pointers[idx] = hdw;
+			break;
+		}
+	} while (0); up(&pvr2_unit_sem);
+
+	cnt1 = 0;
+	cnt2 = scnprintf(hdw->name+cnt1,sizeof(hdw->name)-cnt1,"pvrusb2");
+	cnt1 += cnt2;
+	if (hdw->unit_number >= 0) {
+		cnt2 = scnprintf(hdw->name+cnt1,sizeof(hdw->name)-cnt1,"_%c",
+				 ('a' + hdw->unit_number));
+		cnt1 += cnt2;
+	}
+	if (cnt1 >= sizeof(hdw->name)) cnt1 = sizeof(hdw->name)-1;
+	hdw->name[cnt1] = 0;
+
+	pvr2_trace(PVR2_TRACE_INIT,"Driver unit number is %d, name is %s",
+		   hdw->unit_number,hdw->name);
+
+	hdw->tuner_type = -1;
+	hdw->flag_ok = !0;
+	/* Initialize the mask of subsystems that we will shut down when we
+	   stop streaming. */
+	hdw->subsys_stream_mask = PVR2_SUBSYS_RUN_ALL;
+	hdw->subsys_stream_mask |= (1<<PVR2_SUBSYS_B_ENC_CFG);
+
+	pvr2_trace(PVR2_TRACE_INIT,"subsys_stream_mask: 0x%lx",
+		   hdw->subsys_stream_mask);
+
+	hdw->usb_intf = intf;
+	hdw->usb_dev = interface_to_usbdev(intf);
+
+	ifnum = hdw->usb_intf->cur_altsetting->desc.bInterfaceNumber;
+	usb_set_interface(hdw->usb_dev,ifnum,0);
+
+	mutex_init(&hdw->ctl_lock_mutex);
+	mutex_init(&hdw->big_lock_mutex);
+
+	return hdw;
+ fail:
+	if (hdw) {
+		if (hdw->ctl_read_urb) usb_free_urb(hdw->ctl_read_urb);
+		if (hdw->ctl_write_urb) usb_free_urb(hdw->ctl_write_urb);
+		if (hdw->ctl_read_buffer) kfree(hdw->ctl_read_buffer);
+		if (hdw->ctl_write_buffer) kfree(hdw->ctl_write_buffer);
+		if (hdw->controls) kfree(hdw->controls);
+		if (hdw->mpeg_ctrl_info) kfree(hdw->mpeg_ctrl_info);
+		kfree(hdw);
+	}
+	return NULL;
+}
+
+
+/* Remove _all_ associations between this driver and the underlying USB
+   layer. */
+static void pvr2_hdw_remove_usb_stuff(struct pvr2_hdw *hdw)
+{
+	if (hdw->flag_disconnected) return;
+	pvr2_trace(PVR2_TRACE_INIT,"pvr2_hdw_remove_usb_stuff: hdw=%p",hdw);
+	if (hdw->ctl_read_urb) {
+		usb_kill_urb(hdw->ctl_read_urb);
+		usb_free_urb(hdw->ctl_read_urb);
+		hdw->ctl_read_urb = NULL;
+	}
+	if (hdw->ctl_write_urb) {
+		usb_kill_urb(hdw->ctl_write_urb);
+		usb_free_urb(hdw->ctl_write_urb);
+		hdw->ctl_write_urb = NULL;
+	}
+	if (hdw->ctl_read_buffer) {
+		kfree(hdw->ctl_read_buffer);
+		hdw->ctl_read_buffer = NULL;
+	}
+	if (hdw->ctl_write_buffer) {
+		kfree(hdw->ctl_write_buffer);
+		hdw->ctl_write_buffer = NULL;
+	}
+	pvr2_hdw_render_useless_unlocked(hdw);
+	hdw->flag_disconnected = !0;
+	hdw->usb_dev = NULL;
+	hdw->usb_intf = NULL;
+}
+
+
+/* Destroy hardware interaction structure */
+void pvr2_hdw_destroy(struct pvr2_hdw *hdw)
+{
+	pvr2_trace(PVR2_TRACE_INIT,"pvr2_hdw_destroy: hdw=%p",hdw);
+	if (hdw->fw_buffer) {
+		kfree(hdw->fw_buffer);
+		hdw->fw_buffer = NULL;
+	}
+	if (hdw->vid_stream) {
+		pvr2_stream_destroy(hdw->vid_stream);
+		hdw->vid_stream = NULL;
+	}
+	if (hdw->audio_stat) {
+		hdw->audio_stat->detach(hdw->audio_stat->ctxt);
+	}
+	if (hdw->decoder_ctrl) {
+		hdw->decoder_ctrl->detach(hdw->decoder_ctrl->ctxt);
+	}
+	pvr2_i2c_core_done(hdw);
+	pvr2_hdw_remove_usb_stuff(hdw);
+	down(&pvr2_unit_sem); do {
+		if ((hdw->unit_number >= 0) &&
+		    (hdw->unit_number < PVR_NUM) &&
+		    (unit_pointers[hdw->unit_number] == hdw)) {
+			unit_pointers[hdw->unit_number] = NULL;
+		}
+	} while (0); up(&pvr2_unit_sem);
+	if (hdw->controls) kfree(hdw->controls);
+	if (hdw->mpeg_ctrl_info) kfree(hdw->mpeg_ctrl_info);
+	if (hdw->std_defs) kfree(hdw->std_defs);
+	if (hdw->std_enum_names) kfree(hdw->std_enum_names);
+	kfree(hdw);
+}
+
+
+int pvr2_hdw_init_ok(struct pvr2_hdw *hdw)
+{
+	return hdw->flag_init_ok;
+}
+
+
+int pvr2_hdw_dev_ok(struct pvr2_hdw *hdw)
+{
+	return (hdw && hdw->flag_ok);
+}
+
+
+/* Called when hardware has been unplugged */
+void pvr2_hdw_disconnect(struct pvr2_hdw *hdw)
+{
+	pvr2_trace(PVR2_TRACE_INIT,"pvr2_hdw_disconnect(hdw=%p)",hdw);
+	LOCK_TAKE(hdw->big_lock);
+	LOCK_TAKE(hdw->ctl_lock);
+	pvr2_hdw_remove_usb_stuff(hdw);
+	LOCK_GIVE(hdw->ctl_lock);
+	LOCK_GIVE(hdw->big_lock);
+}
+
+
+// Attempt to autoselect an appropriate value for std_enum_cur given
+// whatever is currently in std_mask_cur
+static void pvr2_hdw_internal_find_stdenum(struct pvr2_hdw *hdw)
+{
+	unsigned int idx;
+	for (idx = 1; idx < hdw->std_enum_cnt; idx++) {
+		if (hdw->std_defs[idx-1].id == hdw->std_mask_cur) {
+			hdw->std_enum_cur = idx;
+			return;
+		}
+	}
+	hdw->std_enum_cur = 0;
+}
+
+
+// Calculate correct set of enumerated standards based on currently known
+// set of available standards bits.
+static void pvr2_hdw_internal_set_std_avail(struct pvr2_hdw *hdw)
+{
+	struct v4l2_standard *newstd;
+	unsigned int std_cnt;
+	unsigned int idx;
+
+	newstd = pvr2_std_create_enum(&std_cnt,hdw->std_mask_avail);
+
+	if (hdw->std_defs) {
+		kfree(hdw->std_defs);
+		hdw->std_defs = NULL;
+	}
+	hdw->std_enum_cnt = 0;
+	if (hdw->std_enum_names) {
+		kfree(hdw->std_enum_names);
+		hdw->std_enum_names = NULL;
+	}
+
+	if (!std_cnt) {
+		pvr2_trace(
+			PVR2_TRACE_ERROR_LEGS,
+			"WARNING: Failed to identify any viable standards");
+	}
+	hdw->std_enum_names = kmalloc(sizeof(char *)*(std_cnt+1),GFP_KERNEL);
+	hdw->std_enum_names[0] = "none";
+	for (idx = 0; idx < std_cnt; idx++) {
+		hdw->std_enum_names[idx+1] =
+			newstd[idx].name;
+	}
+	// Set up the dynamic control for this standard
+	hdw->std_info_enum.def.type_enum.value_names = hdw->std_enum_names;
+	hdw->std_info_enum.def.type_enum.count = std_cnt+1;
+	hdw->std_defs = newstd;
+	hdw->std_enum_cnt = std_cnt+1;
+	hdw->std_enum_cur = 0;
+	hdw->std_info_cur.def.type_bitmask.valid_bits = hdw->std_mask_avail;
+}
+
+
+int pvr2_hdw_get_stdenum_value(struct pvr2_hdw *hdw,
+			       struct v4l2_standard *std,
+			       unsigned int idx)
+{
+	int ret = -EINVAL;
+	if (!idx) return ret;
+	LOCK_TAKE(hdw->big_lock); do {
+		if (idx >= hdw->std_enum_cnt) break;
+		idx--;
+		memcpy(std,hdw->std_defs+idx,sizeof(*std));
+		ret = 0;
+	} while (0); LOCK_GIVE(hdw->big_lock);
+	return ret;
+}
+
+
+/* Get the number of defined controls */
+unsigned int pvr2_hdw_get_ctrl_count(struct pvr2_hdw *hdw)
+{
+	return hdw->control_cnt;
+}
+
+
+/* Retrieve a control handle given its index (0..count-1) */
+struct pvr2_ctrl *pvr2_hdw_get_ctrl_by_index(struct pvr2_hdw *hdw,
+					     unsigned int idx)
+{
+	if (idx >= hdw->control_cnt) return NULL;
+	return hdw->controls + idx;
+}
+
+
+/* Retrieve a control handle given its index (0..count-1) */
+struct pvr2_ctrl *pvr2_hdw_get_ctrl_by_id(struct pvr2_hdw *hdw,
+					  unsigned int ctl_id)
+{
+	struct pvr2_ctrl *cptr;
+	unsigned int idx;
+	int i;
+
+	/* This could be made a lot more efficient, but for now... */
+	for (idx = 0; idx < hdw->control_cnt; idx++) {
+		cptr = hdw->controls + idx;
+		i = cptr->info->internal_id;
+		if (i && (i == ctl_id)) return cptr;
+	}
+	return NULL;
+}
+
+
+/* Given a V4L ID, retrieve the control structure associated with it. */
+struct pvr2_ctrl *pvr2_hdw_get_ctrl_v4l(struct pvr2_hdw *hdw,unsigned int ctl_id)
+{
+	struct pvr2_ctrl *cptr;
+	unsigned int idx;
+	int i;
+
+	/* This could be made a lot more efficient, but for now... */
+	for (idx = 0; idx < hdw->control_cnt; idx++) {
+		cptr = hdw->controls + idx;
+		i = cptr->info->v4l_id;
+		if (i && (i == ctl_id)) return cptr;
+	}
+	return NULL;
+}
+
+
+/* Given a V4L ID for its immediate predecessor, retrieve the control
+   structure associated with it. */
+struct pvr2_ctrl *pvr2_hdw_get_ctrl_nextv4l(struct pvr2_hdw *hdw,
+					    unsigned int ctl_id)
+{
+	struct pvr2_ctrl *cptr,*cp2;
+	unsigned int idx;
+	int i;
+
+	/* This could be made a lot more efficient, but for now... */
+	cp2 = NULL;
+	for (idx = 0; idx < hdw->control_cnt; idx++) {
+		cptr = hdw->controls + idx;
+		i = cptr->info->v4l_id;
+		if (!i) continue;
+		if (i <= ctl_id) continue;
+		if (cp2 && (cp2->info->v4l_id < i)) continue;
+		cp2 = cptr;
+	}
+	return cp2;
+	return NULL;
+}
+
+
+static const char *get_ctrl_typename(enum pvr2_ctl_type tp)
+{
+	switch (tp) {
+	case pvr2_ctl_int: return "integer";
+	case pvr2_ctl_enum: return "enum";
+	case pvr2_ctl_bool: return "boolean";
+	case pvr2_ctl_bitmask: return "bitmask";
+	}
+	return "";
+}
+
+
+/* Commit all control changes made up to this point.  Subsystems can be
+   indirectly affected by these changes.  For a given set of things being
+   committed, we'll clear the affected subsystem bits and then once we're
+   done committing everything we'll make a request to restore the subsystem
+   state(s) back to their previous value before this function was called.
+   Thus we can automatically reconfigure affected pieces of the driver as
+   controls are changed. */
+static int pvr2_hdw_commit_ctl_internal(struct pvr2_hdw *hdw)
+{
+	unsigned long saved_subsys_mask = hdw->subsys_enabled_mask;
+	unsigned long stale_subsys_mask = 0;
+	unsigned int idx;
+	struct pvr2_ctrl *cptr;
+	int value;
+	int commit_flag = 0;
+	char buf[100];
+	unsigned int bcnt,ccnt;
+
+	for (idx = 0; idx < hdw->control_cnt; idx++) {
+		cptr = hdw->controls + idx;
+		if (cptr->info->is_dirty == 0) continue;
+		if (!cptr->info->is_dirty(cptr)) continue;
+		if (!commit_flag) {
+			commit_flag = !0;
+		}
+
+		bcnt = scnprintf(buf,sizeof(buf),"\"%s\" <-- ",
+				 cptr->info->name);
+		value = 0;
+		cptr->info->get_value(cptr,&value);
+		pvr2_ctrl_value_to_sym_internal(cptr,~0,value,
+						buf+bcnt,
+						sizeof(buf)-bcnt,&ccnt);
+		bcnt += ccnt;
+		bcnt += scnprintf(buf+bcnt,sizeof(buf)-bcnt," <%s>",
+				  get_ctrl_typename(cptr->info->type));
+		pvr2_trace(PVR2_TRACE_CTL,
+			   "/*--TRACE_COMMIT--*/ %.*s",
+			   bcnt,buf);
+	}
+
+	if (!commit_flag) {
+		/* Nothing has changed */
+		return 0;
+	}
+
+	/* When video standard changes, reset the hres and vres values -
+	   but if the user has pending changes there, then let the changes
+	   take priority. */
+	if (hdw->std_dirty) {
+		/* Rewrite the vertical resolution to be appropriate to the
+		   video standard that has been selected. */
+		int nvres;
+		if (hdw->std_mask_cur & V4L2_STD_525_60) {
+			nvres = 480;
+		} else {
+			nvres = 576;
+		}
+		if (nvres != hdw->res_ver_val) {
+			hdw->res_ver_val = nvres;
+			hdw->res_ver_dirty = !0;
+		}
+	}
+
+	if (hdw->std_dirty ||
+	    0) {
+		/* If any of this changes, then the encoder needs to be
+		   reconfigured, and we need to reset the stream. */
+		stale_subsys_mask |= (1<<PVR2_SUBSYS_B_ENC_CFG);
+		stale_subsys_mask |= hdw->subsys_stream_mask;
+	}
+
+	if (hdw->srate_dirty) {
+		/* Write new sample rate into control structure since
+		 * the master copy is stale.  We must track srate
+		 * separate from the mpeg control structure because
+		 * other logic also uses this value. */
+		struct v4l2_ext_controls cs;
+		struct v4l2_ext_control c1;
+		memset(&cs,0,sizeof(cs));
+		memset(&c1,0,sizeof(c1));
+		cs.controls = &c1;
+		cs.count = 1;
+		c1.id = V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ;
+		c1.value = hdw->srate_val;
+		cx2341x_ext_ctrls(&hdw->enc_ctl_state,&cs,VIDIOC_S_EXT_CTRLS);
+	}
+
+	/* Scan i2c core at this point - before we clear all the dirty
+	   bits.  Various parts of the i2c core will notice dirty bits as
+	   appropriate and arrange to broadcast or directly send updates to
+	   the client drivers in order to keep everything in sync */
+	pvr2_i2c_core_check_stale(hdw);
+
+	for (idx = 0; idx < hdw->control_cnt; idx++) {
+		cptr = hdw->controls + idx;
+		if (!cptr->info->clear_dirty) continue;
+		cptr->info->clear_dirty(cptr);
+	}
+
+	/* Now execute i2c core update */
+	pvr2_i2c_core_sync(hdw);
+
+	pvr2_hdw_subsys_bit_chg_no_lock(hdw,stale_subsys_mask,0);
+	pvr2_hdw_subsys_bit_chg_no_lock(hdw,~0,saved_subsys_mask);
+
+	return 0;
+}
+
+
+int pvr2_hdw_commit_ctl(struct pvr2_hdw *hdw)
+{
+	LOCK_TAKE(hdw->big_lock); do {
+		pvr2_hdw_commit_ctl_internal(hdw);
+	} while (0); LOCK_GIVE(hdw->big_lock);
+	return 0;
+}
+
+
+void pvr2_hdw_poll(struct pvr2_hdw *hdw)
+{
+	LOCK_TAKE(hdw->big_lock); do {
+		pvr2_i2c_core_sync(hdw);
+	} while (0); LOCK_GIVE(hdw->big_lock);
+}
+
+
+void pvr2_hdw_setup_poll_trigger(struct pvr2_hdw *hdw,
+				 void (*func)(void *),
+				 void *data)
+{
+	LOCK_TAKE(hdw->big_lock); do {
+		hdw->poll_trigger_func = func;
+		hdw->poll_trigger_data = data;
+	} while (0); LOCK_GIVE(hdw->big_lock);
+}
+
+
+void pvr2_hdw_poll_trigger_unlocked(struct pvr2_hdw *hdw)
+{
+	if (hdw->poll_trigger_func) {
+		hdw->poll_trigger_func(hdw->poll_trigger_data);
+	}
+}
+
+/* Return name for this driver instance */
+const char *pvr2_hdw_get_driver_name(struct pvr2_hdw *hdw)
+{
+	return hdw->name;
+}
+
+
+/* Return bit mask indicating signal status */
+static unsigned int pvr2_hdw_get_signal_status_internal(struct pvr2_hdw *hdw)
+{
+	unsigned int msk = 0;
+	switch (hdw->input_val) {
+	case PVR2_CVAL_INPUT_TV:
+	case PVR2_CVAL_INPUT_RADIO:
+		if (hdw->decoder_ctrl &&
+		    hdw->decoder_ctrl->tuned(hdw->decoder_ctrl->ctxt)) {
+			msk |= PVR2_SIGNAL_OK;
+			if (hdw->audio_stat &&
+			    hdw->audio_stat->status(hdw->audio_stat->ctxt)) {
+				if (hdw->flag_stereo) {
+					msk |= PVR2_SIGNAL_STEREO;
+				}
+				if (hdw->flag_bilingual) {
+					msk |= PVR2_SIGNAL_SAP;
+				}
+			}
+		}
+		break;
+	default:
+		msk |= PVR2_SIGNAL_OK | PVR2_SIGNAL_STEREO;
+	}
+	return msk;
+}
+
+
+int pvr2_hdw_is_hsm(struct pvr2_hdw *hdw)
+{
+	int result;
+	LOCK_TAKE(hdw->ctl_lock); do {
+		hdw->cmd_buffer[0] = 0x0b;
+		result = pvr2_send_request(hdw,
+					   hdw->cmd_buffer,1,
+					   hdw->cmd_buffer,1);
+		if (result < 0) break;
+		result = (hdw->cmd_buffer[0] != 0);
+	} while(0); LOCK_GIVE(hdw->ctl_lock);
+	return result;
+}
+
+
+/* Return bit mask indicating signal status */
+unsigned int pvr2_hdw_get_signal_status(struct pvr2_hdw *hdw)
+{
+	unsigned int msk = 0;
+	LOCK_TAKE(hdw->big_lock); do {
+		msk = pvr2_hdw_get_signal_status_internal(hdw);
+	} while (0); LOCK_GIVE(hdw->big_lock);
+	return msk;
+}
+
+
+/* Get handle to video output stream */
+struct pvr2_stream *pvr2_hdw_get_video_stream(struct pvr2_hdw *hp)
+{
+	return hp->vid_stream;
+}
+
+
+void pvr2_hdw_trigger_module_log(struct pvr2_hdw *hdw)
+{
+	int nr = pvr2_hdw_get_unit_number(hdw);
+	LOCK_TAKE(hdw->big_lock); do {
+		hdw->log_requested = !0;
+		printk(KERN_INFO "pvrusb2: =================  START STATUS CARD #%d  =================\n", nr);
+		pvr2_i2c_core_check_stale(hdw);
+		hdw->log_requested = 0;
+		pvr2_i2c_core_sync(hdw);
+		pvr2_trace(PVR2_TRACE_INFO,"cx2341x config:");
+		cx2341x_log_status(&hdw->enc_ctl_state, "pvrusb2");
+		printk(KERN_INFO "pvrusb2: ==================  END STATUS CARD #%d  ==================\n", nr);
+	} while (0); LOCK_GIVE(hdw->big_lock);
+}
+
+void pvr2_hdw_cpufw_set_enabled(struct pvr2_hdw *hdw, int enable_flag)
+{
+	int ret;
+	u16 address;
+	unsigned int pipe;
+	LOCK_TAKE(hdw->big_lock); do {
+		if ((hdw->fw_buffer == 0) == !enable_flag) break;
+
+		if (!enable_flag) {
+			pvr2_trace(PVR2_TRACE_FIRMWARE,
+				   "Cleaning up after CPU firmware fetch");
+			kfree(hdw->fw_buffer);
+			hdw->fw_buffer = NULL;
+			hdw->fw_size = 0;
+			/* Now release the CPU.  It will disconnect and
+			   reconnect later. */
+			pvr2_hdw_cpureset_assert(hdw,0);
+			break;
+		}
+
+		pvr2_trace(PVR2_TRACE_FIRMWARE,
+			   "Preparing to suck out CPU firmware");
+		hdw->fw_size = 0x2000;
+		hdw->fw_buffer = kmalloc(hdw->fw_size,GFP_KERNEL);
+		if (!hdw->fw_buffer) {
+			hdw->fw_size = 0;
+			break;
+		}
+
+		memset(hdw->fw_buffer,0,hdw->fw_size);
+
+		/* We have to hold the CPU during firmware upload. */
+		pvr2_hdw_cpureset_assert(hdw,1);
+
+		/* download the firmware from address 0000-1fff in 2048
+		   (=0x800) bytes chunk. */
+
+		pvr2_trace(PVR2_TRACE_FIRMWARE,"Grabbing CPU firmware");
+		pipe = usb_rcvctrlpipe(hdw->usb_dev, 0);
+		for(address = 0; address < hdw->fw_size; address += 0x800) {
+			ret = usb_control_msg(hdw->usb_dev,pipe,0xa0,0xc0,
+					      address,0,
+					      hdw->fw_buffer+address,0x800,HZ);
+			if (ret < 0) break;
+		}
+
+		pvr2_trace(PVR2_TRACE_FIRMWARE,"Done grabbing CPU firmware");
+
+	} while (0); LOCK_GIVE(hdw->big_lock);
+}
+
+
+/* Return true if we're in a mode for retrieval CPU firmware */
+int pvr2_hdw_cpufw_get_enabled(struct pvr2_hdw *hdw)
+{
+	return hdw->fw_buffer != 0;
+}
+
+
+int pvr2_hdw_cpufw_get(struct pvr2_hdw *hdw,unsigned int offs,
+		       char *buf,unsigned int cnt)
+{
+	int ret = -EINVAL;
+	LOCK_TAKE(hdw->big_lock); do {
+		if (!buf) break;
+		if (!cnt) break;
+
+		if (!hdw->fw_buffer) {
+			ret = -EIO;
+			break;
+		}
+
+		if (offs >= hdw->fw_size) {
+			pvr2_trace(PVR2_TRACE_FIRMWARE,
+				   "Read firmware data offs=%d EOF",
+				   offs);
+			ret = 0;
+			break;
+		}
+
+		if (offs + cnt > hdw->fw_size) cnt = hdw->fw_size - offs;
+
+		memcpy(buf,hdw->fw_buffer+offs,cnt);
+
+		pvr2_trace(PVR2_TRACE_FIRMWARE,
+			   "Read firmware data offs=%d cnt=%d",
+			   offs,cnt);
+		ret = cnt;
+	} while (0); LOCK_GIVE(hdw->big_lock);
+
+	return ret;
+}
+
+
+int pvr2_hdw_v4l_get_minor_number(struct pvr2_hdw *hdw)
+{
+	return hdw->v4l_minor_number;
+}
+
+
+/* Store the v4l minor device number */
+void pvr2_hdw_v4l_store_minor_number(struct pvr2_hdw *hdw,int v)
+{
+	hdw->v4l_minor_number = v;
+}
+
+
+static void pvr2_ctl_write_complete(struct urb *urb, struct pt_regs *regs)
+{
+	struct pvr2_hdw *hdw = urb->context;
+	hdw->ctl_write_pend_flag = 0;
+	if (hdw->ctl_read_pend_flag) return;
+	complete(&hdw->ctl_done);
+}
+
+
+static void pvr2_ctl_read_complete(struct urb *urb, struct pt_regs *regs)
+{
+	struct pvr2_hdw *hdw = urb->context;
+	hdw->ctl_read_pend_flag = 0;
+	if (hdw->ctl_write_pend_flag) return;
+	complete(&hdw->ctl_done);
+}
+
+
+static void pvr2_ctl_timeout(unsigned long data)
+{
+	struct pvr2_hdw *hdw = (struct pvr2_hdw *)data;
+	if (hdw->ctl_write_pend_flag || hdw->ctl_read_pend_flag) {
+		hdw->ctl_timeout_flag = !0;
+		if (hdw->ctl_write_pend_flag && hdw->ctl_write_urb) {
+			usb_unlink_urb(hdw->ctl_write_urb);
+		}
+		if (hdw->ctl_read_pend_flag && hdw->ctl_read_urb) {
+			usb_unlink_urb(hdw->ctl_read_urb);
+		}
+	}
+}
+
+
+/* Issue a command and get a response from the device.  This extended
+   version includes a probe flag (which if set means that device errors
+   should not be logged or treated as fatal) and a timeout in jiffies.
+   This can be used to non-lethally probe the health of endpoint 1. */
+static int pvr2_send_request_ex(struct pvr2_hdw *hdw,
+				unsigned int timeout,int probe_fl,
+				void *write_data,unsigned int write_len,
+				void *read_data,unsigned int read_len)
+{
+	unsigned int idx;
+	int status = 0;
+	struct timer_list timer;
+	if (!hdw->ctl_lock_held) {
+		pvr2_trace(PVR2_TRACE_ERROR_LEGS,
+			   "Attempted to execute control transfer"
+			   " without lock!!");
+		return -EDEADLK;
+	}
+	if ((!hdw->flag_ok) && !probe_fl) {
+		pvr2_trace(PVR2_TRACE_ERROR_LEGS,
+			   "Attempted to execute control transfer"
+			   " when device not ok");
+		return -EIO;
+	}
+	if (!(hdw->ctl_read_urb && hdw->ctl_write_urb)) {
+		if (!probe_fl) {
+			pvr2_trace(PVR2_TRACE_ERROR_LEGS,
+				   "Attempted to execute control transfer"
+				   " when USB is disconnected");
+		}
+		return -ENOTTY;
+	}
+
+	/* Ensure that we have sane parameters */
+	if (!write_data) write_len = 0;
+	if (!read_data) read_len = 0;
+	if (write_len > PVR2_CTL_BUFFSIZE) {
+		pvr2_trace(
+			PVR2_TRACE_ERROR_LEGS,
+			"Attempted to execute %d byte"
+			" control-write transfer (limit=%d)",
+			write_len,PVR2_CTL_BUFFSIZE);
+		return -EINVAL;
+	}
+	if (read_len > PVR2_CTL_BUFFSIZE) {
+		pvr2_trace(
+			PVR2_TRACE_ERROR_LEGS,
+			"Attempted to execute %d byte"
+			" control-read transfer (limit=%d)",
+			write_len,PVR2_CTL_BUFFSIZE);
+		return -EINVAL;
+	}
+	if ((!write_len) && (!read_len)) {
+		pvr2_trace(
+			PVR2_TRACE_ERROR_LEGS,
+			"Attempted to execute null control transfer?");
+		return -EINVAL;
+	}
+
+
+	hdw->cmd_debug_state = 1;
+	if (write_len) {
+		hdw->cmd_debug_code = ((unsigned char *)write_data)[0];
+	} else {
+		hdw->cmd_debug_code = 0;
+	}
+	hdw->cmd_debug_write_len = write_len;
+	hdw->cmd_debug_read_len = read_len;
+
+	/* Initialize common stuff */
+	init_completion(&hdw->ctl_done);
+	hdw->ctl_timeout_flag = 0;
+	hdw->ctl_write_pend_flag = 0;
+	hdw->ctl_read_pend_flag = 0;
+	init_timer(&timer);
+	timer.expires = jiffies + timeout;
+	timer.data = (unsigned long)hdw;
+	timer.function = pvr2_ctl_timeout;
+
+	if (write_len) {
+		hdw->cmd_debug_state = 2;
+		/* Transfer write data to internal buffer */
+		for (idx = 0; idx < write_len; idx++) {
+			hdw->ctl_write_buffer[idx] =
+				((unsigned char *)write_data)[idx];
+		}
+		/* Initiate a write request */
+		usb_fill_bulk_urb(hdw->ctl_write_urb,
+				  hdw->usb_dev,
+				  usb_sndbulkpipe(hdw->usb_dev,
+						  PVR2_CTL_WRITE_ENDPOINT),
+				  hdw->ctl_write_buffer,
+				  write_len,
+				  pvr2_ctl_write_complete,
+				  hdw);
+		hdw->ctl_write_urb->actual_length = 0;
+		hdw->ctl_write_pend_flag = !0;
+		status = usb_submit_urb(hdw->ctl_write_urb,GFP_KERNEL);
+		if (status < 0) {
+			pvr2_trace(PVR2_TRACE_ERROR_LEGS,
+				   "Failed to submit write-control"
+				   " URB status=%d",status);
+			hdw->ctl_write_pend_flag = 0;
+			goto done;
+		}
+	}
+
+	if (read_len) {
+		hdw->cmd_debug_state = 3;
+		memset(hdw->ctl_read_buffer,0x43,read_len);
+		/* Initiate a read request */
+		usb_fill_bulk_urb(hdw->ctl_read_urb,
+				  hdw->usb_dev,
+				  usb_rcvbulkpipe(hdw->usb_dev,
+						  PVR2_CTL_READ_ENDPOINT),
+				  hdw->ctl_read_buffer,
+				  read_len,
+				  pvr2_ctl_read_complete,
+				  hdw);
+		hdw->ctl_read_urb->actual_length = 0;
+		hdw->ctl_read_pend_flag = !0;
+		status = usb_submit_urb(hdw->ctl_read_urb,GFP_KERNEL);
+		if (status < 0) {
+			pvr2_trace(PVR2_TRACE_ERROR_LEGS,
+				   "Failed to submit read-control"
+				   " URB status=%d",status);
+			hdw->ctl_read_pend_flag = 0;
+			goto done;
+		}
+	}
+
+	/* Start timer */
+	add_timer(&timer);
+
+	/* Now wait for all I/O to complete */
+	hdw->cmd_debug_state = 4;
+	while (hdw->ctl_write_pend_flag || hdw->ctl_read_pend_flag) {
+		wait_for_completion(&hdw->ctl_done);
+	}
+	hdw->cmd_debug_state = 5;
+
+	/* Stop timer */
+	del_timer_sync(&timer);
+
+	hdw->cmd_debug_state = 6;
+	status = 0;
+
+	if (hdw->ctl_timeout_flag) {
+		status = -ETIMEDOUT;
+		if (!probe_fl) {
+			pvr2_trace(PVR2_TRACE_ERROR_LEGS,
+				   "Timed out control-write");
+		}
+		goto done;
+	}
+
+	if (write_len) {
+		/* Validate results of write request */
+		if ((hdw->ctl_write_urb->status != 0) &&
+		    (hdw->ctl_write_urb->status != -ENOENT) &&
+		    (hdw->ctl_write_urb->status != -ESHUTDOWN) &&
+		    (hdw->ctl_write_urb->status != -ECONNRESET)) {
+			/* USB subsystem is reporting some kind of failure
+			   on the write */
+			status = hdw->ctl_write_urb->status;
+			if (!probe_fl) {
+				pvr2_trace(PVR2_TRACE_ERROR_LEGS,
+					   "control-write URB failure,"
+					   " status=%d",
+					   status);
+			}
+			goto done;
+		}
+		if (hdw->ctl_write_urb->actual_length < write_len) {
+			/* Failed to write enough data */
+			status = -EIO;
+			if (!probe_fl) {
+				pvr2_trace(PVR2_TRACE_ERROR_LEGS,
+					   "control-write URB short,"
+					   " expected=%d got=%d",
+					   write_len,
+					   hdw->ctl_write_urb->actual_length);
+			}
+			goto done;
+		}
+	}
+	if (read_len) {
+		/* Validate results of read request */
+		if ((hdw->ctl_read_urb->status != 0) &&
+		    (hdw->ctl_read_urb->status != -ENOENT) &&
+		    (hdw->ctl_read_urb->status != -ESHUTDOWN) &&
+		    (hdw->ctl_read_urb->status != -ECONNRESET)) {
+			/* USB subsystem is reporting some kind of failure
+			   on the read */
+			status = hdw->ctl_read_urb->status;
+			if (!probe_fl) {
+				pvr2_trace(PVR2_TRACE_ERROR_LEGS,
+					   "control-read URB failure,"
+					   " status=%d",
+					   status);
+			}
+			goto done;
+		}
+		if (hdw->ctl_read_urb->actual_length < read_len) {
+			/* Failed to read enough data */
+			status = -EIO;
+			if (!probe_fl) {
+				pvr2_trace(PVR2_TRACE_ERROR_LEGS,
+					   "control-read URB short,"
+					   " expected=%d got=%d",
+					   read_len,
+					   hdw->ctl_read_urb->actual_length);
+			}
+			goto done;
+		}
+		/* Transfer retrieved data out from internal buffer */
+		for (idx = 0; idx < read_len; idx++) {
+			((unsigned char *)read_data)[idx] =
+				hdw->ctl_read_buffer[idx];
+		}
+	}
+
+ done:
+
+	hdw->cmd_debug_state = 0;
+	if ((status < 0) && (!probe_fl)) {
+		pvr2_hdw_render_useless_unlocked(hdw);
+	}
+	return status;
+}
+
+
+int pvr2_send_request(struct pvr2_hdw *hdw,
+		      void *write_data,unsigned int write_len,
+		      void *read_data,unsigned int read_len)
+{
+	return pvr2_send_request_ex(hdw,HZ*4,0,
+				    write_data,write_len,
+				    read_data,read_len);
+}
+
+int pvr2_write_register(struct pvr2_hdw *hdw, u16 reg, u32 data)
+{
+	int ret;
+
+	LOCK_TAKE(hdw->ctl_lock);
+
+	hdw->cmd_buffer[0] = 0x04;  /* write register prefix */
+	PVR2_DECOMPOSE_LE(hdw->cmd_buffer,1,data);
+	hdw->cmd_buffer[5] = 0;
+	hdw->cmd_buffer[6] = (reg >> 8) & 0xff;
+	hdw->cmd_buffer[7] = reg & 0xff;
+
+
+	ret = pvr2_send_request(hdw, hdw->cmd_buffer, 8, hdw->cmd_buffer, 0);
+
+	LOCK_GIVE(hdw->ctl_lock);
+
+	return ret;
+}
+
+
+static int pvr2_read_register(struct pvr2_hdw *hdw, u16 reg, u32 *data)
+{
+	int ret = 0;
+
+	LOCK_TAKE(hdw->ctl_lock);
+
+	hdw->cmd_buffer[0] = 0x05;  /* read register prefix */
+	hdw->cmd_buffer[1] = 0;
+	hdw->cmd_buffer[2] = 0;
+	hdw->cmd_buffer[3] = 0;
+	hdw->cmd_buffer[4] = 0;
+	hdw->cmd_buffer[5] = 0;
+	hdw->cmd_buffer[6] = (reg >> 8) & 0xff;
+	hdw->cmd_buffer[7] = reg & 0xff;
+
+	ret |= pvr2_send_request(hdw, hdw->cmd_buffer, 8, hdw->cmd_buffer, 4);
+	*data = PVR2_COMPOSE_LE(hdw->cmd_buffer,0);
+
+	LOCK_GIVE(hdw->ctl_lock);
+
+	return ret;
+}
+
+
+static int pvr2_write_u16(struct pvr2_hdw *hdw, u16 data, int res)
+{
+	int ret;
+
+	LOCK_TAKE(hdw->ctl_lock);
+
+	hdw->cmd_buffer[0] = (data >> 8) & 0xff;
+	hdw->cmd_buffer[1] = data & 0xff;
+
+	ret = pvr2_send_request(hdw, hdw->cmd_buffer, 2, hdw->cmd_buffer, res);
+
+	LOCK_GIVE(hdw->ctl_lock);
+
+	return ret;
+}
+
+
+static int pvr2_write_u8(struct pvr2_hdw *hdw, u8 data, int res)
+{
+	int ret;
+
+	LOCK_TAKE(hdw->ctl_lock);
+
+	hdw->cmd_buffer[0] = data;
+
+	ret = pvr2_send_request(hdw, hdw->cmd_buffer, 1, hdw->cmd_buffer, res);
+
+	LOCK_GIVE(hdw->ctl_lock);
+
+	return ret;
+}
+
+
+static void pvr2_hdw_render_useless_unlocked(struct pvr2_hdw *hdw)
+{
+	if (!hdw->flag_ok) return;
+	pvr2_trace(PVR2_TRACE_INIT,"render_useless");
+	hdw->flag_ok = 0;
+	if (hdw->vid_stream) {
+		pvr2_stream_setup(hdw->vid_stream,NULL,0,0);
+	}
+	hdw->flag_streaming_enabled = 0;
+	hdw->subsys_enabled_mask = 0;
+}
+
+
+void pvr2_hdw_render_useless(struct pvr2_hdw *hdw)
+{
+	LOCK_TAKE(hdw->ctl_lock);
+	pvr2_hdw_render_useless_unlocked(hdw);
+	LOCK_GIVE(hdw->ctl_lock);
+}
+
+
+void pvr2_hdw_device_reset(struct pvr2_hdw *hdw)
+{
+	int ret;
+	pvr2_trace(PVR2_TRACE_INIT,"Performing a device reset...");
+	ret = usb_lock_device_for_reset(hdw->usb_dev,NULL);
+	if (ret == 1) {
+		ret = usb_reset_device(hdw->usb_dev);
+		usb_unlock_device(hdw->usb_dev);
+	} else {
+		pvr2_trace(PVR2_TRACE_ERROR_LEGS,
+			   "Failed to lock USB device ret=%d",ret);
+	}
+	if (init_pause_msec) {
+		pvr2_trace(PVR2_TRACE_INFO,
+			   "Waiting %u msec for hardware to settle",
+			   init_pause_msec);
+		msleep(init_pause_msec);
+	}
+
+}
+
+
+void pvr2_hdw_cpureset_assert(struct pvr2_hdw *hdw,int val)
+{
+	char da[1];
+	unsigned int pipe;
+	int ret;
+
+	if (!hdw->usb_dev) return;
+
+	pvr2_trace(PVR2_TRACE_INIT,"cpureset_assert(%d)",val);
+
+	da[0] = val ? 0x01 : 0x00;
+
+	/* Write the CPUCS register on the 8051.  The lsb of the register
+	   is the reset bit; a 1 asserts reset while a 0 clears it. */
+	pipe = usb_sndctrlpipe(hdw->usb_dev, 0);
+	ret = usb_control_msg(hdw->usb_dev,pipe,0xa0,0x40,0xe600,0,da,1,HZ);
+	if (ret < 0) {
+		pvr2_trace(PVR2_TRACE_ERROR_LEGS,
+			   "cpureset_assert(%d) error=%d",val,ret);
+		pvr2_hdw_render_useless(hdw);
+	}
+}
+
+
+int pvr2_hdw_cmd_deep_reset(struct pvr2_hdw *hdw)
+{
+	int status;
+	LOCK_TAKE(hdw->ctl_lock); do {
+		pvr2_trace(PVR2_TRACE_INIT,"Requesting uproc hard reset");
+		hdw->flag_ok = !0;
+		hdw->cmd_buffer[0] = 0xdd;
+		status = pvr2_send_request(hdw,hdw->cmd_buffer,1,NULL,0);
+	} while (0); LOCK_GIVE(hdw->ctl_lock);
+	return status;
+}
+
+
+int pvr2_hdw_cmd_powerup(struct pvr2_hdw *hdw)
+{
+	int status;
+	LOCK_TAKE(hdw->ctl_lock); do {
+		pvr2_trace(PVR2_TRACE_INIT,"Requesting powerup");
+		hdw->cmd_buffer[0] = 0xde;
+		status = pvr2_send_request(hdw,hdw->cmd_buffer,1,NULL,0);
+	} while (0); LOCK_GIVE(hdw->ctl_lock);
+	return status;
+}
+
+
+int pvr2_hdw_cmd_decoder_reset(struct pvr2_hdw *hdw)
+{
+	if (!hdw->decoder_ctrl) {
+		pvr2_trace(PVR2_TRACE_INIT,
+			   "Unable to reset decoder: nothing attached");
+		return -ENOTTY;
+	}
+
+	if (!hdw->decoder_ctrl->force_reset) {
+		pvr2_trace(PVR2_TRACE_INIT,
+			   "Unable to reset decoder: not implemented");
+		return -ENOTTY;
+	}
+
+	pvr2_trace(PVR2_TRACE_INIT,
+		   "Requesting decoder reset");
+	hdw->decoder_ctrl->force_reset(hdw->decoder_ctrl->ctxt);
+	return 0;
+}
+
+
+/* Stop / start video stream transport */
+static int pvr2_hdw_cmd_usbstream(struct pvr2_hdw *hdw,int runFl)
+{
+	int status;
+	LOCK_TAKE(hdw->ctl_lock); do {
+		hdw->cmd_buffer[0] = (runFl ? 0x36 : 0x37);
+		status = pvr2_send_request(hdw,hdw->cmd_buffer,1,NULL,0);
+	} while (0); LOCK_GIVE(hdw->ctl_lock);
+	if (!status) {
+		hdw->subsys_enabled_mask =
+			((hdw->subsys_enabled_mask &
+			  ~(1<<PVR2_SUBSYS_B_USBSTREAM_RUN)) |
+			 (runFl ? (1<<PVR2_SUBSYS_B_USBSTREAM_RUN) : 0));
+	}
+	return status;
+}
+
+
+void pvr2_hdw_get_debug_info(const struct pvr2_hdw *hdw,
+			     struct pvr2_hdw_debug_info *ptr)
+{
+	ptr->big_lock_held = hdw->big_lock_held;
+	ptr->ctl_lock_held = hdw->ctl_lock_held;
+	ptr->flag_ok = hdw->flag_ok;
+	ptr->flag_disconnected = hdw->flag_disconnected;
+	ptr->flag_init_ok = hdw->flag_init_ok;
+	ptr->flag_streaming_enabled = hdw->flag_streaming_enabled;
+	ptr->subsys_flags = hdw->subsys_enabled_mask;
+	ptr->cmd_debug_state = hdw->cmd_debug_state;
+	ptr->cmd_code = hdw->cmd_debug_code;
+	ptr->cmd_debug_write_len = hdw->cmd_debug_write_len;
+	ptr->cmd_debug_read_len = hdw->cmd_debug_read_len;
+	ptr->cmd_debug_timeout = hdw->ctl_timeout_flag;
+	ptr->cmd_debug_write_pend = hdw->ctl_write_pend_flag;
+	ptr->cmd_debug_read_pend = hdw->ctl_read_pend_flag;
+	ptr->cmd_debug_rstatus = hdw->ctl_read_urb->status;
+	ptr->cmd_debug_wstatus = hdw->ctl_read_urb->status;
+}
+
+
+int pvr2_hdw_gpio_get_dir(struct pvr2_hdw *hdw,u32 *dp)
+{
+	return pvr2_read_register(hdw,PVR2_GPIO_DIR,dp);
+}
+
+
+int pvr2_hdw_gpio_get_out(struct pvr2_hdw *hdw,u32 *dp)
+{
+	return pvr2_read_register(hdw,PVR2_GPIO_OUT,dp);
+}
+
+
+int pvr2_hdw_gpio_get_in(struct pvr2_hdw *hdw,u32 *dp)
+{
+	return pvr2_read_register(hdw,PVR2_GPIO_IN,dp);
+}
+
+
+int pvr2_hdw_gpio_chg_dir(struct pvr2_hdw *hdw,u32 msk,u32 val)
+{
+	u32 cval,nval;
+	int ret;
+	if (~msk) {
+		ret = pvr2_read_register(hdw,PVR2_GPIO_DIR,&cval);
+		if (ret) return ret;
+		nval = (cval & ~msk) | (val & msk);
+		pvr2_trace(PVR2_TRACE_GPIO,
+			   "GPIO direction changing 0x%x:0x%x"
+			   " from 0x%x to 0x%x",
+			   msk,val,cval,nval);
+	} else {
+		nval = val;
+		pvr2_trace(PVR2_TRACE_GPIO,
+			   "GPIO direction changing to 0x%x",nval);
+	}
+	return pvr2_write_register(hdw,PVR2_GPIO_DIR,nval);
+}
+
+
+int pvr2_hdw_gpio_chg_out(struct pvr2_hdw *hdw,u32 msk,u32 val)
+{
+	u32 cval,nval;
+	int ret;
+	if (~msk) {
+		ret = pvr2_read_register(hdw,PVR2_GPIO_OUT,&cval);
+		if (ret) return ret;
+		nval = (cval & ~msk) | (val & msk);
+		pvr2_trace(PVR2_TRACE_GPIO,
+			   "GPIO output changing 0x%x:0x%x from 0x%x to 0x%x",
+			   msk,val,cval,nval);
+	} else {
+		nval = val;
+		pvr2_trace(PVR2_TRACE_GPIO,
+			   "GPIO output changing to 0x%x",nval);
+	}
+	return pvr2_write_register(hdw,PVR2_GPIO_OUT,nval);
+}
+
+
+/* Find I2C address of eeprom */
+static int pvr2_hdw_get_eeprom_addr(struct pvr2_hdw *hdw)
+{
+	int result;
+	LOCK_TAKE(hdw->ctl_lock); do {
+		hdw->cmd_buffer[0] = 0xeb;
+		result = pvr2_send_request(hdw,
+					   hdw->cmd_buffer,1,
+					   hdw->cmd_buffer,1);
+		if (result < 0) break;
+		result = hdw->cmd_buffer[0];
+	} while(0); LOCK_GIVE(hdw->ctl_lock);
+	return result;
+}
+
+
+/*
+  Stuff for Emacs to see, in order to encourage consistent editing style:
+  *** Local Variables: ***
+  *** mode: c ***
+  *** fill-column: 75 ***
+  *** tab-width: 8 ***
+  *** c-basic-offset: 8 ***
+  *** End: ***
+  */
diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw.h b/drivers/media/video/pvrusb2/pvrusb2-hdw.h
new file mode 100644
index 000000000..fd931b5da
--- /dev/null
+++ b/drivers/media/video/pvrusb2/pvrusb2-hdw.h
@@ -0,0 +1,303 @@
+/*
+ *
+ *  $Id$
+ *
+ *  Copyright (C) 2005 Mike Isely <isely@pobox.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
+ *
+ *  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 __PVRUSB2_HDW_H
+#define __PVRUSB2_HDW_H
+
+#include <linux/usb.h>
+#include <linux/videodev2.h>
+#include "pvrusb2-io.h"
+#include "pvrusb2-ctrl.h"
+
+
+/* Private internal control ids, look these up with
+   pvr2_hdw_get_ctrl_by_id() - these are NOT visible in V4L */
+#define PVR2_CID_STDENUM 1
+#define PVR2_CID_STDCUR 2
+#define PVR2_CID_STDAVAIL 3
+#define PVR2_CID_INPUT 4
+#define PVR2_CID_AUDIOMODE 5
+#define PVR2_CID_FREQUENCY 6
+#define PVR2_CID_HRES 7
+#define PVR2_CID_VRES 8
+
+/* Legal values for the INPUT state variable */
+#define PVR2_CVAL_INPUT_TV 0
+#define PVR2_CVAL_INPUT_SVIDEO 1
+#define PVR2_CVAL_INPUT_COMPOSITE 2
+#define PVR2_CVAL_INPUT_RADIO 3
+
+/* Values that pvr2_hdw_get_signal_status() returns */
+#define PVR2_SIGNAL_OK     0x0001
+#define PVR2_SIGNAL_STEREO 0x0002
+#define PVR2_SIGNAL_SAP    0x0004
+
+
+/* Subsystem definitions - these are various pieces that can be
+   independently stopped / started.  Usually you don't want to mess with
+   this directly (let the driver handle things itself), but it is useful
+   for debugging. */
+#define PVR2_SUBSYS_B_ENC_FIRMWARE        0
+#define PVR2_SUBSYS_B_ENC_CFG             1
+#define PVR2_SUBSYS_B_DIGITIZER_RUN       2
+#define PVR2_SUBSYS_B_USBSTREAM_RUN       3
+#define PVR2_SUBSYS_B_ENC_RUN             4
+
+#define PVR2_SUBSYS_CFG_ALL ( \
+	(1 << PVR2_SUBSYS_B_ENC_FIRMWARE) | \
+	(1 << PVR2_SUBSYS_B_ENC_CFG) )
+#define PVR2_SUBSYS_RUN_ALL ( \
+	(1 << PVR2_SUBSYS_B_DIGITIZER_RUN) | \
+	(1 << PVR2_SUBSYS_B_USBSTREAM_RUN) | \
+	(1 << PVR2_SUBSYS_B_ENC_RUN) )
+#define PVR2_SUBSYS_ALL ( \
+	PVR2_SUBSYS_CFG_ALL | \
+	PVR2_SUBSYS_RUN_ALL )
+
+enum pvr2_config {
+	pvr2_config_empty,
+	pvr2_config_mpeg,
+	pvr2_config_vbi,
+	pvr2_config_radio,
+};
+
+const char *pvr2_config_get_name(enum pvr2_config);
+
+struct pvr2_hdw;
+
+/* Create and return a structure for interacting with the underlying
+   hardware */
+struct pvr2_hdw *pvr2_hdw_create(struct usb_interface *intf,
+				 const struct usb_device_id *devid);
+
+/* Poll for background activity (if any) */
+void pvr2_hdw_poll(struct pvr2_hdw *);
+
+/* Trigger a poll to take place later at a convenient time */
+void pvr2_hdw_poll_trigger_unlocked(struct pvr2_hdw *);
+
+/* Register a callback used to trigger a future poll */
+void pvr2_hdw_setup_poll_trigger(struct pvr2_hdw *,
+				 void (*func)(void *),
+				 void *data);
+
+/* Destroy hardware interaction structure */
+void pvr2_hdw_destroy(struct pvr2_hdw *);
+
+/* Set up the structure and attempt to put the device into a usable state.
+   This can be a time-consuming operation, which is why it is not done
+   internally as part of the create() step.  Return value is exactly the
+   same as pvr2_hdw_init_ok(). */
+int pvr2_hdw_setup(struct pvr2_hdw *);
+
+/* Initialization succeeded */
+int pvr2_hdw_init_ok(struct pvr2_hdw *);
+
+/* Return true if in the ready (normal) state */
+int pvr2_hdw_dev_ok(struct pvr2_hdw *);
+
+/* Return small integer number [1..N] for logical instance number of this
+   device.  This is useful for indexing array-valued module parameters. */
+int pvr2_hdw_get_unit_number(struct pvr2_hdw *);
+
+/* Get pointer to underlying USB device */
+struct usb_device *pvr2_hdw_get_dev(struct pvr2_hdw *);
+
+/* Retrieve serial number of device */
+unsigned long pvr2_hdw_get_sn(struct pvr2_hdw *);
+
+/* Called when hardware has been unplugged */
+void pvr2_hdw_disconnect(struct pvr2_hdw *);
+
+/* Get the number of defined controls */
+unsigned int pvr2_hdw_get_ctrl_count(struct pvr2_hdw *);
+
+/* Retrieve a control handle given its index (0..count-1) */
+struct pvr2_ctrl *pvr2_hdw_get_ctrl_by_index(struct pvr2_hdw *,unsigned int);
+
+/* Retrieve a control handle given its internal ID (if any) */
+struct pvr2_ctrl *pvr2_hdw_get_ctrl_by_id(struct pvr2_hdw *,unsigned int);
+
+/* Retrieve a control handle given its V4L ID (if any) */
+struct pvr2_ctrl *pvr2_hdw_get_ctrl_v4l(struct pvr2_hdw *,unsigned int ctl_id);
+
+/* Retrieve a control handle given its immediate predecessor V4L ID (if any) */
+struct pvr2_ctrl *pvr2_hdw_get_ctrl_nextv4l(struct pvr2_hdw *,
+					    unsigned int ctl_id);
+
+/* Commit all control changes made up to this point */
+int pvr2_hdw_commit_ctl(struct pvr2_hdw *);
+
+/* Return name for this driver instance */
+const char *pvr2_hdw_get_driver_name(struct pvr2_hdw *);
+
+/* Return PVR2_SIGNAL_XXXX bit mask indicating signal status */
+unsigned int pvr2_hdw_get_signal_status(struct pvr2_hdw *);
+
+/* Query device and see if it thinks it is on a high-speed USB link */
+int pvr2_hdw_is_hsm(struct pvr2_hdw *);
+
+/* Turn streaming on/off */
+int pvr2_hdw_set_streaming(struct pvr2_hdw *,int);
+
+/* Find out if streaming is on */
+int pvr2_hdw_get_streaming(struct pvr2_hdw *);
+
+/* Configure the type of stream to generate */
+int pvr2_hdw_set_stream_type(struct pvr2_hdw *, enum pvr2_config);
+
+/* Get handle to video output stream */
+struct pvr2_stream *pvr2_hdw_get_video_stream(struct pvr2_hdw *);
+
+/* Emit a video standard struct */
+int pvr2_hdw_get_stdenum_value(struct pvr2_hdw *hdw,struct v4l2_standard *std,
+			       unsigned int idx);
+
+/* Enable / disable various pieces of hardware.  Items to change are
+   identified by bit positions within msk, and new state for each item is
+   identified by corresponding bit positions within val. */
+void pvr2_hdw_subsys_bit_chg(struct pvr2_hdw *hdw,
+			     unsigned long msk,unsigned long val);
+
+/* Retrieve mask indicating which pieces of hardware are currently enabled
+   / configured. */
+unsigned long pvr2_hdw_subsys_get(struct pvr2_hdw *);
+
+/* Adjust mask of what get shut down when streaming is stopped.  This is a
+   debugging aid. */
+void pvr2_hdw_subsys_stream_bit_chg(struct pvr2_hdw *hdw,
+				    unsigned long msk,unsigned long val);
+
+/* Retrieve mask indicating which pieces of hardware are disabled when
+   streaming is turned off. */
+unsigned long pvr2_hdw_subsys_stream_get(struct pvr2_hdw *);
+
+
+/* Enable / disable retrieval of CPU firmware.  This must be enabled before
+   pvr2_hdw_cpufw_get() will function.  Note that doing this may prevent
+   the device from running (and leaving this mode may imply a device
+   reset). */
+void pvr2_hdw_cpufw_set_enabled(struct pvr2_hdw *, int enable_flag);
+
+/* Return true if we're in a mode for retrieval CPU firmware */
+int pvr2_hdw_cpufw_get_enabled(struct pvr2_hdw *);
+
+/* Retrieve a piece of the CPU's firmware at the given offset.  Return
+   value is the number of bytes retrieved or zero if we're past the end or
+   an error otherwise (e.g. if firmware retrieval is not enabled). */
+int pvr2_hdw_cpufw_get(struct pvr2_hdw *,unsigned int offs,
+		       char *buf,unsigned int cnt);
+
+/* Retrieve previously stored v4l minor device number */
+int pvr2_hdw_v4l_get_minor_number(struct pvr2_hdw *);
+
+/* Store the v4l minor device number */
+void pvr2_hdw_v4l_store_minor_number(struct pvr2_hdw *,int);
+
+
+/* The following entry points are all lower level things you normally don't
+   want to worry about. */
+
+/* Issue a command and get a response from the device.  LOTS of higher
+   level stuff is built on this. */
+int pvr2_send_request(struct pvr2_hdw *,
+		      void *write_ptr,unsigned int write_len,
+		      void *read_ptr,unsigned int read_len);
+
+/* Slightly higher level device communication functions. */
+int pvr2_write_register(struct pvr2_hdw *, u16, u32);
+
+/* Call if for any reason we can't talk to the hardware anymore - this will
+   cause the driver to stop flailing on the device. */
+void pvr2_hdw_render_useless(struct pvr2_hdw *);
+
+/* Set / clear 8051's reset bit */
+void pvr2_hdw_cpureset_assert(struct pvr2_hdw *,int);
+
+/* Execute a USB-commanded device reset */
+void pvr2_hdw_device_reset(struct pvr2_hdw *);
+
+/* Execute hard reset command (after this point it's likely that the
+   encoder will have to be reconfigured).  This also clears the "useless"
+   state. */
+int pvr2_hdw_cmd_deep_reset(struct pvr2_hdw *);
+
+/* Execute simple reset command */
+int pvr2_hdw_cmd_powerup(struct pvr2_hdw *);
+
+/* Order decoder to reset */
+int pvr2_hdw_cmd_decoder_reset(struct pvr2_hdw *);
+
+/* Direct manipulation of GPIO bits */
+int pvr2_hdw_gpio_get_dir(struct pvr2_hdw *hdw,u32 *);
+int pvr2_hdw_gpio_get_out(struct pvr2_hdw *hdw,u32 *);
+int pvr2_hdw_gpio_get_in(struct pvr2_hdw *hdw,u32 *);
+int pvr2_hdw_gpio_chg_dir(struct pvr2_hdw *hdw,u32 msk,u32 val);
+int pvr2_hdw_gpio_chg_out(struct pvr2_hdw *hdw,u32 msk,u32 val);
+
+/* This data structure is specifically for the next function... */
+struct pvr2_hdw_debug_info {
+	int big_lock_held;
+	int ctl_lock_held;
+	int flag_ok;
+	int flag_disconnected;
+	int flag_init_ok;
+	int flag_streaming_enabled;
+	unsigned long subsys_flags;
+	int cmd_debug_state;
+	int cmd_debug_write_len;
+	int cmd_debug_read_len;
+	int cmd_debug_write_pend;
+	int cmd_debug_read_pend;
+	int cmd_debug_timeout;
+	int cmd_debug_rstatus;
+	int cmd_debug_wstatus;
+	unsigned char cmd_code;
+};
+
+/* Non-intrusively retrieve internal state info - this is useful for
+   diagnosing lockups.  Note that this operation is completed without any
+   kind of locking and so it is not atomic and may yield inconsistent
+   results.  This is *purely* a debugging aid. */
+void pvr2_hdw_get_debug_info(const struct pvr2_hdw *hdw,
+			     struct pvr2_hdw_debug_info *);
+
+/* Cause modules to log their state once */
+void pvr2_hdw_trigger_module_log(struct pvr2_hdw *hdw);
+
+/* Cause encoder firmware to be uploaded into the device.  This is normally
+   done autonomously, but the interface is exported here because it is also
+   a debugging aid. */
+int pvr2_upload_firmware2(struct pvr2_hdw *hdw);
+
+/* List of device types that we can match */
+extern struct usb_device_id pvr2_device_table[];
+
+#endif /* __PVRUSB2_HDW_H */
+
+/*
+  Stuff for Emacs to see, in order to encourage consistent editing style:
+  *** Local Variables: ***
+  *** mode: c ***
+  *** fill-column: 75 ***
+  *** tab-width: 8 ***
+  *** c-basic-offset: 8 ***
+  *** End: ***
+  */
diff --git a/drivers/media/video/pvrusb2/pvrusb2-i2c-chips-v4l2.c b/drivers/media/video/pvrusb2/pvrusb2-i2c-chips-v4l2.c
new file mode 100644
index 000000000..fbe6039ae
--- /dev/null
+++ b/drivers/media/video/pvrusb2/pvrusb2-i2c-chips-v4l2.c
@@ -0,0 +1,109 @@
+/*
+ *
+ *  $Id$
+ *
+ *  Copyright (C) 2005 Mike Isely <isely@pobox.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
+ *
+ *  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 "pvrusb2-i2c-core.h"
+#include "pvrusb2-hdw-internal.h"
+#include "pvrusb2-debug.h"
+#include "pvrusb2-i2c-cmd-v4l2.h"
+#include "pvrusb2-audio.h"
+#include "pvrusb2-tuner.h"
+#include "pvrusb2-video-v4l.h"
+#ifdef CONFIG_VIDEO_PVRUSB2_24XXX
+#include "pvrusb2-cx2584x-v4l.h"
+#include "pvrusb2-wm8775.h"
+#endif
+
+#define trace_i2c(...) pvr2_trace(PVR2_TRACE_I2C,__VA_ARGS__)
+
+#define OP_STANDARD 0
+#define OP_BCSH 1
+#define OP_VOLUME 2
+#define OP_FREQ 3
+#define OP_AUDIORATE 4
+#define OP_SIZE 5
+#define OP_LOG 6
+
+static const struct pvr2_i2c_op * const ops[] = {
+	[OP_STANDARD] = &pvr2_i2c_op_v4l2_standard,
+	[OP_BCSH] = &pvr2_i2c_op_v4l2_bcsh,
+	[OP_VOLUME] = &pvr2_i2c_op_v4l2_volume,
+	[OP_FREQ] = &pvr2_i2c_op_v4l2_frequency,
+	[OP_SIZE] = &pvr2_i2c_op_v4l2_size,
+	[OP_LOG] = &pvr2_i2c_op_v4l2_log,
+};
+
+void pvr2_i2c_probe(struct pvr2_hdw *hdw,struct pvr2_i2c_client *cp)
+{
+	int id;
+	id = cp->client->driver->id;
+	cp->ctl_mask = ((1 << OP_STANDARD) |
+			(1 << OP_BCSH) |
+			(1 << OP_VOLUME) |
+			(1 << OP_FREQ) |
+			(1 << OP_SIZE) |
+			(1 << OP_LOG));
+
+	if (id == I2C_DRIVERID_MSP3400) {
+		if (pvr2_i2c_msp3400_setup(hdw,cp)) {
+			return;
+		}
+	}
+	if (id == I2C_DRIVERID_TUNER) {
+		if (pvr2_i2c_tuner_setup(hdw,cp)) {
+			return;
+		}
+	}
+#ifdef CONFIG_VIDEO_PVRUSB2_24XXX
+	if (id == I2C_DRIVERID_CX25840) {
+		if (pvr2_i2c_cx2584x_v4l_setup(hdw,cp)) {
+			return;
+		}
+	}
+	if (id == I2C_DRIVERID_WM8775) {
+		if (pvr2_i2c_wm8775_setup(hdw,cp)) {
+			return;
+		}
+	}
+#endif
+	if (id == I2C_DRIVERID_SAA711X) {
+		if (pvr2_i2c_decoder_v4l_setup(hdw,cp)) {
+			return;
+		}
+	}
+}
+
+
+const struct pvr2_i2c_op *pvr2_i2c_get_op(unsigned int idx)
+{
+	if (idx >= sizeof(ops)/sizeof(ops[0])) return 0;
+	return ops[idx];
+}
+
+
+/*
+  Stuff for Emacs to see, in order to encourage consistent editing style:
+  *** Local Variables: ***
+  *** mode: c ***
+  *** fill-column: 75 ***
+  *** tab-width: 8 ***
+  *** c-basic-offset: 8 ***
+  *** End: ***
+  */
diff --git a/drivers/media/video/pvrusb2/pvrusb2-i2c-cmd-v4l2.c b/drivers/media/video/pvrusb2/pvrusb2-i2c-cmd-v4l2.c
new file mode 100644
index 000000000..8a9933dec
--- /dev/null
+++ b/drivers/media/video/pvrusb2/pvrusb2-i2c-cmd-v4l2.c
@@ -0,0 +1,232 @@
+/*
+ *
+ *  $Id$
+ *
+ *  Copyright (C) 2005 Mike Isely <isely@pobox.com>
+ *  Copyright (C) 2004 Aurelien Alleaume <slts@free.fr>
+ *
+ *  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
+ *
+ *  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 "pvrusb2-i2c-cmd-v4l2.h"
+#include "pvrusb2-hdw-internal.h"
+#include "pvrusb2-debug.h"
+#include <linux/videodev2.h>
+
+
+static void set_standard(struct pvr2_hdw *hdw)
+{
+	v4l2_std_id vs;
+	vs = hdw->std_mask_cur;
+	pvr2_trace(PVR2_TRACE_CHIPS,
+		   "i2c v4l2 set_standard(0x%llx)",(__u64)vs);
+
+	pvr2_i2c_core_cmd(hdw,VIDIOC_S_STD,&vs);
+}
+
+
+static int check_standard(struct pvr2_hdw *hdw)
+{
+	return hdw->std_dirty != 0;
+}
+
+
+const struct pvr2_i2c_op pvr2_i2c_op_v4l2_standard = {
+	.check = check_standard,
+	.update = set_standard,
+	.name = "v4l2_standard",
+};
+
+
+static void set_bcsh(struct pvr2_hdw *hdw)
+{
+	struct v4l2_control ctrl;
+	pvr2_trace(PVR2_TRACE_CHIPS,"i2c v4l2 set_bcsh"
+		   " b=%d c=%d s=%d h=%d",
+		   hdw->brightness_val,hdw->contrast_val,
+		   hdw->saturation_val,hdw->hue_val);
+	memset(&ctrl,0,sizeof(ctrl));
+	ctrl.id = V4L2_CID_BRIGHTNESS;
+	ctrl.value = hdw->brightness_val;
+	pvr2_i2c_core_cmd(hdw,VIDIOC_S_CTRL,&ctrl);
+	ctrl.id = V4L2_CID_CONTRAST;
+	ctrl.value = hdw->contrast_val;
+	pvr2_i2c_core_cmd(hdw,VIDIOC_S_CTRL,&ctrl);
+	ctrl.id = V4L2_CID_SATURATION;
+	ctrl.value = hdw->saturation_val;
+	pvr2_i2c_core_cmd(hdw,VIDIOC_S_CTRL,&ctrl);
+	ctrl.id = V4L2_CID_HUE;
+	ctrl.value = hdw->hue_val;
+	pvr2_i2c_core_cmd(hdw,VIDIOC_S_CTRL,&ctrl);
+}
+
+
+static int check_bcsh(struct pvr2_hdw *hdw)
+{
+	return (hdw->brightness_dirty ||
+		hdw->contrast_dirty ||
+		hdw->saturation_dirty ||
+		hdw->hue_dirty);
+}
+
+
+const struct pvr2_i2c_op pvr2_i2c_op_v4l2_bcsh = {
+	.check = check_bcsh,
+	.update = set_bcsh,
+	.name = "v4l2_bcsh",
+};
+
+
+static void set_volume(struct pvr2_hdw *hdw)
+{
+	struct v4l2_control ctrl;
+	pvr2_trace(PVR2_TRACE_CHIPS,
+		   "i2c v4l2 set_volume"
+		   "(vol=%d bal=%d bas=%d treb=%d mute=%d)",
+		   hdw->volume_val,
+		   hdw->balance_val,
+		   hdw->bass_val,
+		   hdw->treble_val,
+		   hdw->mute_val);
+	memset(&ctrl,0,sizeof(ctrl));
+	ctrl.id = V4L2_CID_AUDIO_MUTE;
+	ctrl.value = hdw->mute_val ? 1 : 0;
+	pvr2_i2c_core_cmd(hdw,VIDIOC_S_CTRL,&ctrl);
+	ctrl.id = V4L2_CID_AUDIO_VOLUME;
+	ctrl.value = hdw->volume_val;
+	pvr2_i2c_core_cmd(hdw,VIDIOC_S_CTRL,&ctrl);
+	ctrl.id = V4L2_CID_AUDIO_BALANCE;
+	ctrl.value = hdw->balance_val;
+	pvr2_i2c_core_cmd(hdw,VIDIOC_S_CTRL,&ctrl);
+	ctrl.id = V4L2_CID_AUDIO_BASS;
+	ctrl.value = hdw->bass_val;
+	pvr2_i2c_core_cmd(hdw,VIDIOC_S_CTRL,&ctrl);
+	ctrl.id = V4L2_CID_AUDIO_TREBLE;
+	ctrl.value = hdw->treble_val;
+	pvr2_i2c_core_cmd(hdw,VIDIOC_S_CTRL,&ctrl);
+}
+
+
+static int check_volume(struct pvr2_hdw *hdw)
+{
+	return (hdw->volume_dirty ||
+		hdw->balance_dirty ||
+		hdw->bass_dirty ||
+		hdw->treble_dirty ||
+		hdw->mute_dirty);
+}
+
+
+const struct pvr2_i2c_op pvr2_i2c_op_v4l2_volume = {
+	.check = check_volume,
+	.update = set_volume,
+	.name = "v4l2_volume",
+};
+
+
+static void set_frequency(struct pvr2_hdw *hdw)
+{
+	unsigned long fv;
+	struct v4l2_frequency freq;
+	fv = hdw->freqVal;
+	pvr2_trace(PVR2_TRACE_CHIPS,"i2c v4l2 set_freq(%lu)",fv);
+	memset(&freq,0,sizeof(freq));
+	freq.frequency = fv / 62500;
+	freq.tuner = 0;
+	freq.type = V4L2_TUNER_ANALOG_TV;
+	pvr2_i2c_core_cmd(hdw,VIDIOC_S_FREQUENCY,&freq);
+}
+
+
+static int check_frequency(struct pvr2_hdw *hdw)
+{
+	return hdw->freqDirty != 0;
+}
+
+
+const struct pvr2_i2c_op pvr2_i2c_op_v4l2_frequency = {
+	.check = check_frequency,
+	.update = set_frequency,
+	.name = "v4l2_freq",
+};
+
+
+static void set_size(struct pvr2_hdw *hdw)
+{
+	struct v4l2_format fmt;
+
+	memset(&fmt,0,sizeof(fmt));
+
+	fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+	fmt.fmt.pix.width = hdw->res_hor_val;
+	fmt.fmt.pix.height = hdw->res_ver_val;
+
+	pvr2_trace(PVR2_TRACE_CHIPS,"i2c v4l2 set_size(%dx%d)",
+			   fmt.fmt.pix.width,fmt.fmt.pix.height);
+
+	pvr2_i2c_core_cmd(hdw,VIDIOC_S_FMT,&fmt);
+}
+
+
+static int check_size(struct pvr2_hdw *hdw)
+{
+	return (hdw->res_hor_dirty || hdw->res_ver_dirty);
+}
+
+
+const struct pvr2_i2c_op pvr2_i2c_op_v4l2_size = {
+	.check = check_size,
+	.update = set_size,
+	.name = "v4l2_size",
+};
+
+
+static void do_log(struct pvr2_hdw *hdw)
+{
+	pvr2_trace(PVR2_TRACE_CHIPS,"i2c v4l2 do_log()");
+	pvr2_i2c_core_cmd(hdw,VIDIOC_LOG_STATUS,NULL);
+
+}
+
+
+static int check_log(struct pvr2_hdw *hdw)
+{
+	return hdw->log_requested != 0;
+}
+
+
+const struct pvr2_i2c_op pvr2_i2c_op_v4l2_log = {
+	.check = check_log,
+	.update = do_log,
+	.name = "v4l2_log",
+};
+
+
+void pvr2_v4l2_cmd_stream(struct pvr2_i2c_client *cp,int fl)
+{
+	pvr2_i2c_client_cmd(cp,
+			    (fl ? VIDIOC_STREAMON : VIDIOC_STREAMOFF),NULL);
+}
+
+
+/*
+  Stuff for Emacs to see, in order to encourage consistent editing style:
+  *** Local Variables: ***
+  *** mode: c ***
+  *** fill-column: 70 ***
+  *** tab-width: 8 ***
+  *** c-basic-offset: 8 ***
+  *** End: ***
+  */
diff --git a/drivers/media/video/pvrusb2/pvrusb2-i2c-cmd-v4l2.h b/drivers/media/video/pvrusb2/pvrusb2-i2c-cmd-v4l2.h
new file mode 100644
index 000000000..ecabddba1
--- /dev/null
+++ b/drivers/media/video/pvrusb2/pvrusb2-i2c-cmd-v4l2.h
@@ -0,0 +1,47 @@
+/*
+ *
+ *  $Id$
+ *
+ *  Copyright (C) 2005 Mike Isely <isely@pobox.com>
+ *  Copyright (C) 2004 Aurelien Alleaume <slts@free.fr>
+ *
+ *  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
+ *
+ *  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 __PVRUSB2_CMD_V4L2_H
+#define __PVRUSB2_CMD_V4L2_H
+
+#include "pvrusb2-i2c-core.h"
+
+extern const struct pvr2_i2c_op pvr2_i2c_op_v4l2_standard;
+extern const struct pvr2_i2c_op pvr2_i2c_op_v4l2_bcsh;
+extern const struct pvr2_i2c_op pvr2_i2c_op_v4l2_volume;
+extern const struct pvr2_i2c_op pvr2_i2c_op_v4l2_frequency;
+extern const struct pvr2_i2c_op pvr2_i2c_op_v4l2_size;
+extern const struct pvr2_i2c_op pvr2_i2c_op_v4l2_log;
+
+void pvr2_v4l2_cmd_stream(struct pvr2_i2c_client *,int);
+
+#endif /* __PVRUSB2_CMD_V4L2_H */
+
+/*
+  Stuff for Emacs to see, in order to encourage consistent editing style:
+  *** Local Variables: ***
+  *** mode: c ***
+  *** fill-column: 70 ***
+  *** tab-width: 8 ***
+  *** c-basic-offset: 8 ***
+  *** End: ***
+  */
diff --git a/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c b/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c
new file mode 100644
index 000000000..7fca47982
--- /dev/null
+++ b/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c
@@ -0,0 +1,941 @@
+/*
+ *
+ *  $Id$
+ *
+ *  Copyright (C) 2005 Mike Isely <isely@pobox.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
+ *
+ *  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 "pvrusb2-i2c-core.h"
+#include "pvrusb2-hdw-internal.h"
+#include "pvrusb2-debug.h"
+
+#define trace_i2c(...) pvr2_trace(PVR2_TRACE_I2C,__VA_ARGS__)
+
+/*
+
+  This module attempts to implement a compliant I2C adapter for the pvrusb2
+  device.  By doing this we can then make use of existing functionality in
+  V4L (e.g. tuner.c) rather than rolling our own.
+
+*/
+
+static unsigned int i2c_scan = 0;
+module_param(i2c_scan, int, S_IRUGO|S_IWUSR);
+MODULE_PARM_DESC(i2c_scan,"scan i2c bus at insmod time");
+
+static unsigned int pvr2_i2c_client_describe(struct pvr2_i2c_client *cp,
+					     unsigned int detail,
+					     char *buf,unsigned int maxlen);
+
+static int pvr2_i2c_write(struct pvr2_hdw *hdw, /* Context */
+			  u8 i2c_addr,      /* I2C address we're talking to */
+			  u8 *data,         /* Data to write */
+			  u16 length)       /* Size of data to write */
+{
+	/* Return value - default 0 means success */
+	int ret;
+
+
+	if (!data) length = 0;
+	if (length > (sizeof(hdw->cmd_buffer) - 3)) {
+		pvr2_trace(PVR2_TRACE_ERROR_LEGS,
+			   "Killing an I2C write to %u that is too large"
+			   " (desired=%u limit=%u)",
+			   i2c_addr,
+			   length,(unsigned int)(sizeof(hdw->cmd_buffer) - 3));
+		return -ENOTSUPP;
+	}
+
+	LOCK_TAKE(hdw->ctl_lock);
+
+	/* Clear the command buffer (likely to be paranoia) */
+	memset(hdw->cmd_buffer, 0, sizeof(hdw->cmd_buffer));
+
+	/* Set up command buffer for an I2C write */
+	hdw->cmd_buffer[0] = 0x08;      /* write prefix */
+	hdw->cmd_buffer[1] = i2c_addr;  /* i2c addr of chip */
+	hdw->cmd_buffer[2] = length;    /* length of what follows */
+	if (length) memcpy(hdw->cmd_buffer + 3, data, length);
+
+	/* Do the operation */
+	ret = pvr2_send_request(hdw,
+				hdw->cmd_buffer,
+				length + 3,
+				hdw->cmd_buffer,
+				1);
+	if (!ret) {
+		if (hdw->cmd_buffer[0] != 8) {
+			ret = -EIO;
+			if (hdw->cmd_buffer[0] != 7) {
+				trace_i2c("unexpected status"
+					  " from i2_write[%d]: %d",
+					  i2c_addr,hdw->cmd_buffer[0]);
+			}
+		}
+	}
+
+	LOCK_GIVE(hdw->ctl_lock);
+
+	return ret;
+}
+
+static int pvr2_i2c_read(struct pvr2_hdw *hdw, /* Context */
+			 u8 i2c_addr,       /* I2C address we're talking to */
+			 u8 *data,          /* Data to write */
+			 u16 dlen,          /* Size of data to write */
+			 u8 *res,           /* Where to put data we read */
+			 u16 rlen)          /* Amount of data to read */
+{
+	/* Return value - default 0 means success */
+	int ret;
+
+
+	if (!data) dlen = 0;
+	if (dlen > (sizeof(hdw->cmd_buffer) - 4)) {
+		pvr2_trace(PVR2_TRACE_ERROR_LEGS,
+			   "Killing an I2C read to %u that has wlen too large"
+			   " (desired=%u limit=%u)",
+			   i2c_addr,
+			   dlen,(unsigned int)(sizeof(hdw->cmd_buffer) - 4));
+		return -ENOTSUPP;
+	}
+	if (res && (rlen > (sizeof(hdw->cmd_buffer) - 1))) {
+		pvr2_trace(PVR2_TRACE_ERROR_LEGS,
+			   "Killing an I2C read to %u that has rlen too large"
+			   " (desired=%u limit=%u)",
+			   i2c_addr,
+			   rlen,(unsigned int)(sizeof(hdw->cmd_buffer) - 1));
+		return -ENOTSUPP;
+	}
+
+	LOCK_TAKE(hdw->ctl_lock);
+
+	/* Clear the command buffer (likely to be paranoia) */
+	memset(hdw->cmd_buffer, 0, sizeof(hdw->cmd_buffer));
+
+	/* Set up command buffer for an I2C write followed by a read */
+	hdw->cmd_buffer[0] = 0x09;  /* read prefix */
+	hdw->cmd_buffer[1] = dlen;  /* arg length */
+	hdw->cmd_buffer[2] = rlen;  /* answer length. Device will send one
+				       more byte (status). */
+	hdw->cmd_buffer[3] = i2c_addr;  /* i2c addr of chip */
+	if (dlen) memcpy(hdw->cmd_buffer + 4, data, dlen);
+
+	/* Do the operation */
+	ret = pvr2_send_request(hdw,
+				hdw->cmd_buffer,
+				4 + dlen,
+				hdw->cmd_buffer,
+				rlen + 1);
+	if (!ret) {
+		if (hdw->cmd_buffer[0] != 8) {
+			ret = -EIO;
+			if (hdw->cmd_buffer[0] != 7) {
+				trace_i2c("unexpected status"
+					  " from i2_read[%d]: %d",
+					  i2c_addr,hdw->cmd_buffer[0]);
+			}
+		}
+	}
+
+	/* Copy back the result */
+	if (res && rlen) {
+		if (ret) {
+			/* Error, just blank out the return buffer */
+			memset(res, 0, rlen);
+		} else {
+			memcpy(res, hdw->cmd_buffer + 1, rlen);
+		}
+	}
+
+	LOCK_GIVE(hdw->ctl_lock);
+
+	return ret;
+}
+
+/* This is the common low level entry point for doing I2C operations to the
+   hardware. */
+static int pvr2_i2c_basic_op(struct pvr2_hdw *hdw,
+			     u8 i2c_addr,
+			     u8 *wdata,
+			     u16 wlen,
+			     u8 *rdata,
+			     u16 rlen)
+{
+	if (!rdata) rlen = 0;
+	if (!wdata) wlen = 0;
+	if (rlen || !wlen) {
+		return pvr2_i2c_read(hdw,i2c_addr,wdata,wlen,rdata,rlen);
+	} else {
+		return pvr2_i2c_write(hdw,i2c_addr,wdata,wlen);
+	}
+}
+
+#ifdef CONFIG_VIDEO_PVRUSB2_24XXX
+
+/* This is a special entry point that is entered if an I2C operation is
+   attempted to a wm8775 chip on model 24xxx hardware.  Autodetect of this
+   part doesn't work, but we know it is really there.  So let's look for
+   the autodetect attempt and just return success if we see that. */
+static int i2c_hack_wm8775(struct pvr2_hdw *hdw,
+			   u8 i2c_addr,u8 *wdata,u16 wlen,u8 *rdata,u16 rlen)
+{
+	if (!(rlen || wlen)) {
+		// This is a probe attempt.  Just let it succeed.
+		return 0;
+	}
+	return pvr2_i2c_basic_op(hdw,i2c_addr,wdata,wlen,rdata,rlen);
+}
+
+/* This is a special entry point that is entered if an I2C operation is
+   attempted to a cx25840 chip on model 24xxx hardware.  This chip can
+   sometimes wedge itself.  Worse still, when this happens msp3400 can
+   falsely detect this part and then the system gets hosed up after msp3400
+   gets confused and dies.  What we want to do here is try to keep msp3400
+   away and also try to notice if the chip is wedged and send a warning to
+   the system log. */
+static int i2c_hack_cx25840(struct pvr2_hdw *hdw,
+			    u8 i2c_addr,u8 *wdata,u16 wlen,u8 *rdata,u16 rlen)
+{
+	int ret;
+	unsigned int subaddr;
+	u8 wbuf[2];
+	int state = hdw->i2c_cx25840_hack_state;
+
+	if (!(rlen || wlen)) {
+		// Probe attempt - always just succeed and don't bother the
+		// hardware (this helps to make the state machine further
+		// down somewhat easier).
+		return 0;
+	}
+
+	if (state == 3) {
+		return pvr2_i2c_basic_op(hdw,i2c_addr,wdata,wlen,rdata,rlen);
+	}
+
+	/* We're looking for the exact pattern where the revision register
+	   is being read.  The cx25840 module will always look at the
+	   revision register first.  Any other pattern of access therefore
+	   has to be a probe attempt from somebody else so we'll reject it.
+	   Normally we could just let each client just probe the part
+	   anyway, but when the cx25840 is wedged, msp3400 will get a false
+	   positive and that just screws things up... */
+
+	if (wlen == 0) {
+		switch (state) {
+		case 1: subaddr = 0x0100; break;
+		case 2: subaddr = 0x0101; break;
+		default: goto fail;
+		}
+	} else if (wlen == 2) {
+		subaddr = (wdata[0] << 8) | wdata[1];
+		switch (subaddr) {
+		case 0x0100: state = 1; break;
+		case 0x0101: state = 2; break;
+		default: goto fail;
+		}
+	} else {
+		goto fail;
+	}
+	if (!rlen) goto success;
+	state = 0;
+	if (rlen != 1) goto fail;
+
+	/* If we get to here then we have a legitimate read for one of the
+	   two revision bytes, so pass it through. */
+	wbuf[0] = subaddr >> 8;
+	wbuf[1] = subaddr;
+	ret = pvr2_i2c_basic_op(hdw,i2c_addr,wbuf,2,rdata,rlen);
+
+	if ((ret != 0) || (*rdata == 0x04) || (*rdata == 0x0a)) {
+		pvr2_trace(PVR2_TRACE_ERROR_LEGS,
+			   "WARNING: Detected a wedged cx25840 chip;"
+			   " the device will not work.");
+		pvr2_trace(PVR2_TRACE_ERROR_LEGS,
+			   "WARNING: Try power cycling the pvrusb2 device.");
+		pvr2_trace(PVR2_TRACE_ERROR_LEGS,
+			   "WARNING: Disabling further access to the device"
+			   " to prevent other foul-ups.");
+		// This blocks all further communication with the part.
+		hdw->i2c_func[0x44] = NULL;
+		pvr2_hdw_render_useless(hdw);
+		goto fail;
+	}
+
+	/* Success! */
+	pvr2_trace(PVR2_TRACE_CHIPS,"cx25840 appears to be OK.");
+	state = 3;
+
+ success:
+	hdw->i2c_cx25840_hack_state = state;
+	return 0;
+
+ fail:
+	hdw->i2c_cx25840_hack_state = state;
+	return -EIO;
+}
+
+#endif /* CONFIG_VIDEO_PVRUSB2_24XXX */
+
+/* This is a very, very limited I2C adapter implementation.  We can only
+   support what we actually know will work on the device... */
+static int pvr2_i2c_xfer(struct i2c_adapter *i2c_adap,
+			 struct i2c_msg msgs[],
+			 int num)
+{
+	int ret = -ENOTSUPP;
+	pvr2_i2c_func funcp = NULL;
+	struct pvr2_hdw *hdw = (struct pvr2_hdw *)(i2c_adap->algo_data);
+
+	if (!num) {
+		ret = -EINVAL;
+		goto done;
+	}
+	if ((msgs[0].flags & I2C_M_NOSTART)) {
+		trace_i2c("i2c refusing I2C_M_NOSTART");
+		goto done;
+	}
+	if (msgs[0].addr < PVR2_I2C_FUNC_CNT) {
+		funcp = hdw->i2c_func[msgs[0].addr];
+	}
+	if (!funcp) {
+		ret = -EIO;
+		goto done;
+	}
+
+	if (num == 1) {
+		if (msgs[0].flags & I2C_M_RD) {
+			/* Simple read */
+			u16 tcnt,bcnt,offs;
+			if (!msgs[0].len) {
+				/* Length == 0 read.  This is a probe. */
+				if (funcp(hdw,msgs[0].addr,NULL,0,NULL,0)) {
+					ret = -EIO;
+					goto done;
+				}
+				ret = 1;
+				goto done;
+			}
+			/* If the read is short enough we'll do the whole
+			   thing atomically.  Otherwise we have no choice
+			   but to break apart the reads. */
+			tcnt = msgs[0].len;
+			offs = 0;
+			while (tcnt) {
+				bcnt = tcnt;
+				if (bcnt > sizeof(hdw->cmd_buffer)-1) {
+					bcnt = sizeof(hdw->cmd_buffer)-1;
+				}
+				if (funcp(hdw,msgs[0].addr,NULL,0,
+					  msgs[0].buf+offs,bcnt)) {
+					ret = -EIO;
+					goto done;
+				}
+				offs += bcnt;
+				tcnt -= bcnt;
+			}
+			ret = 1;
+			goto done;
+		} else {
+			/* Simple write */
+			ret = 1;
+			if (funcp(hdw,msgs[0].addr,
+				  msgs[0].buf,msgs[0].len,NULL,0)) {
+				ret = -EIO;
+			}
+			goto done;
+		}
+	} else if (num == 2) {
+		if (msgs[0].addr != msgs[1].addr) {
+			trace_i2c("i2c refusing 2 phase transfer with"
+				  " conflicting target addresses");
+			ret = -ENOTSUPP;
+			goto done;
+		}
+		if ((!((msgs[0].flags & I2C_M_RD))) &&
+		    (msgs[1].flags & I2C_M_RD)) {
+			u16 tcnt,bcnt,wcnt,offs;
+			/* Write followed by atomic read.  If the read
+			   portion is short enough we'll do the whole thing
+			   atomically.  Otherwise we have no choice but to
+			   break apart the reads. */
+			tcnt = msgs[1].len;
+			wcnt = msgs[0].len;
+			offs = 0;
+			while (tcnt || wcnt) {
+				bcnt = tcnt;
+				if (bcnt > sizeof(hdw->cmd_buffer)-1) {
+					bcnt = sizeof(hdw->cmd_buffer)-1;
+				}
+				if (funcp(hdw,msgs[0].addr,
+					  msgs[0].buf,wcnt,
+					  msgs[1].buf+offs,bcnt)) {
+					ret = -EIO;
+					goto done;
+				}
+				offs += bcnt;
+				tcnt -= bcnt;
+				wcnt = 0;
+			}
+			ret = 2;
+			goto done;
+		} else {
+			trace_i2c("i2c refusing complex transfer"
+				  " read0=%d read1=%d",
+				  (msgs[0].flags & I2C_M_RD),
+				  (msgs[1].flags & I2C_M_RD));
+		}
+	} else {
+		trace_i2c("i2c refusing %d phase transfer",num);
+	}
+
+ done:
+	if (pvrusb2_debug & PVR2_TRACE_I2C_TRAF) {
+		unsigned int idx,offs,cnt;
+		for (idx = 0; idx < num; idx++) {
+			cnt = msgs[idx].len;
+			printk(KERN_INFO
+			       "pvrusb2 i2c xfer %u/%u:"
+			       " addr=0x%x len=%d %s%s",
+			       idx+1,num,
+			       msgs[idx].addr,
+			       cnt,
+			       (msgs[idx].flags & I2C_M_RD ?
+				"read" : "write"),
+			       (msgs[idx].flags & I2C_M_NOSTART ?
+				" nostart" : ""));
+			if ((ret > 0) || !(msgs[idx].flags & I2C_M_RD)) {
+				if (cnt > 8) cnt = 8;
+				printk(" [");
+				for (offs = 0; offs < (cnt>8?8:cnt); offs++) {
+					if (offs) printk(" ");
+					printk("%02x",msgs[idx].buf[offs]);
+				}
+				if (offs < cnt) printk(" ...");
+				printk("]");
+			}
+			if (idx+1 == num) {
+				printk(" result=%d",ret);
+			}
+			printk("\n");
+		}
+		if (!num) {
+			printk(KERN_INFO
+			       "pvrusb2 i2c xfer null transfer result=%d\n",
+			       ret);
+		}
+	}
+	return ret;
+}
+
+static int pvr2_i2c_control(struct i2c_adapter *adapter,
+			    unsigned int cmd, unsigned long arg)
+{
+	return 0;
+}
+
+static u32 pvr2_i2c_functionality(struct i2c_adapter *adap)
+{
+	return I2C_FUNC_SMBUS_EMUL | I2C_FUNC_I2C | I2C_FUNC_SMBUS_BYTE_DATA;
+}
+
+static int pvr2_i2c_core_singleton(struct i2c_client *cp,
+				   unsigned int cmd,void *arg)
+{
+	int stat;
+	if (!cp) return -EINVAL;
+	if (!(cp->driver)) return -EINVAL;
+	if (!(cp->driver->command)) return -EINVAL;
+	if (!try_module_get(cp->driver->driver.owner)) return -EAGAIN;
+	stat = cp->driver->command(cp,cmd,arg);
+	module_put(cp->driver->driver.owner);
+	return stat;
+}
+
+int pvr2_i2c_client_cmd(struct pvr2_i2c_client *cp,unsigned int cmd,void *arg)
+{
+	int stat;
+	if (pvrusb2_debug & PVR2_TRACE_I2C_CMD) {
+		char buf[100];
+		unsigned int cnt;
+		cnt = pvr2_i2c_client_describe(cp,PVR2_I2C_DETAIL_DEBUG,
+					       buf,sizeof(buf));
+		pvr2_trace(PVR2_TRACE_I2C_CMD,
+			   "i2c COMMAND (code=%u 0x%x) to %.*s",
+			   cmd,cmd,cnt,buf);
+	}
+	stat = pvr2_i2c_core_singleton(cp->client,cmd,arg);
+	if (pvrusb2_debug & PVR2_TRACE_I2C_CMD) {
+		char buf[100];
+		unsigned int cnt;
+		cnt = pvr2_i2c_client_describe(cp,PVR2_I2C_DETAIL_DEBUG,
+					       buf,sizeof(buf));
+		pvr2_trace(PVR2_TRACE_I2C_CMD,
+			   "i2c COMMAND to %.*s (ret=%d)",cnt,buf,stat);
+	}
+	return stat;
+}
+
+int pvr2_i2c_core_cmd(struct pvr2_hdw *hdw,unsigned int cmd,void *arg)
+{
+	struct list_head *item,*nc;
+	struct pvr2_i2c_client *cp;
+	int stat = -EINVAL;
+
+	if (!hdw) return stat;
+
+	mutex_lock(&hdw->i2c_list_lock);
+	list_for_each_safe(item,nc,&hdw->i2c_clients) {
+		cp = list_entry(item,struct pvr2_i2c_client,list);
+		if (!cp->recv_enable) continue;
+		mutex_unlock(&hdw->i2c_list_lock);
+		stat = pvr2_i2c_client_cmd(cp,cmd,arg);
+		mutex_lock(&hdw->i2c_list_lock);
+	}
+	mutex_unlock(&hdw->i2c_list_lock);
+	return stat;
+}
+
+
+static int handler_check(struct pvr2_i2c_client *cp)
+{
+	struct pvr2_i2c_handler *hp = cp->handler;
+	if (!hp) return 0;
+	if (!hp->func_table->check) return 0;
+	return hp->func_table->check(hp->func_data) != 0;
+}
+
+#define BUFSIZE 500
+
+void pvr2_i2c_core_sync(struct pvr2_hdw *hdw)
+{
+	unsigned long msk;
+	unsigned int idx;
+	struct list_head *item,*nc;
+	struct pvr2_i2c_client *cp;
+
+	if (!hdw->i2c_linked) return;
+	if (!(hdw->i2c_pend_types & PVR2_I2C_PEND_ALL)) {
+		return;
+	}
+	mutex_lock(&hdw->i2c_list_lock); do {
+		pvr2_trace(PVR2_TRACE_I2C_CORE,"i2c: core_sync BEGIN");
+		if (hdw->i2c_pend_types & PVR2_I2C_PEND_DETECT) {
+			/* One or more I2C clients have attached since we
+			   last synced.  So scan the list and identify the
+			   new clients. */
+			char *buf;
+			unsigned int cnt;
+			unsigned long amask = 0;
+			buf = kmalloc(BUFSIZE,GFP_KERNEL);
+			pvr2_trace(PVR2_TRACE_I2C_CORE,"i2c: PEND_DETECT");
+			hdw->i2c_pend_types &= ~PVR2_I2C_PEND_DETECT;
+			list_for_each(item,&hdw->i2c_clients) {
+				cp = list_entry(item,struct pvr2_i2c_client,
+						list);
+				if (!cp->detected_flag) {
+					cp->ctl_mask = 0;
+					pvr2_i2c_probe(hdw,cp);
+					cp->detected_flag = !0;
+					msk = cp->ctl_mask;
+					cnt = 0;
+					if (buf) {
+						cnt = pvr2_i2c_client_describe(
+							cp,
+							PVR2_I2C_DETAIL_ALL,
+							buf,BUFSIZE);
+					}
+					trace_i2c("Probed: %.*s",cnt,buf);
+					if (handler_check(cp)) {
+						hdw->i2c_pend_types |=
+							PVR2_I2C_PEND_CLIENT;
+					}
+					cp->pend_mask = msk;
+					hdw->i2c_pend_mask |= msk;
+					hdw->i2c_pend_types |=
+						PVR2_I2C_PEND_REFRESH;
+				}
+				amask |= cp->ctl_mask;
+			}
+			hdw->i2c_active_mask = amask;
+			if (buf) kfree(buf);
+		}
+		if (hdw->i2c_pend_types & PVR2_I2C_PEND_STALE) {
+			/* Need to do one or more global updates.  Arrange
+			   for this to happen. */
+			unsigned long m2;
+			pvr2_trace(PVR2_TRACE_I2C_CORE,
+				   "i2c: PEND_STALE (0x%lx)",
+				   hdw->i2c_stale_mask);
+			hdw->i2c_pend_types &= ~PVR2_I2C_PEND_STALE;
+			list_for_each(item,&hdw->i2c_clients) {
+				cp = list_entry(item,struct pvr2_i2c_client,
+						list);
+				m2 = hdw->i2c_stale_mask;
+				m2 &= cp->ctl_mask;
+				m2 &= ~cp->pend_mask;
+				if (m2) {
+					pvr2_trace(PVR2_TRACE_I2C_CORE,
+						   "i2c: cp=%p setting 0x%lx",
+						   cp,m2);
+					cp->pend_mask |= m2;
+				}
+			}
+			hdw->i2c_pend_mask |= hdw->i2c_stale_mask;
+			hdw->i2c_stale_mask = 0;
+			hdw->i2c_pend_types |= PVR2_I2C_PEND_REFRESH;
+		}
+		if (hdw->i2c_pend_types & PVR2_I2C_PEND_CLIENT) {
+			/* One or more client handlers are asking for an
+			   update.  Run through the list of known clients
+			   and update each one. */
+			pvr2_trace(PVR2_TRACE_I2C_CORE,"i2c: PEND_CLIENT");
+			hdw->i2c_pend_types &= ~PVR2_I2C_PEND_CLIENT;
+			list_for_each_safe(item,nc,&hdw->i2c_clients) {
+				cp = list_entry(item,struct pvr2_i2c_client,
+						list);
+				if (!cp->handler) continue;
+				if (!cp->handler->func_table->update) continue;
+				pvr2_trace(PVR2_TRACE_I2C_CORE,
+					   "i2c: cp=%p update",cp);
+				mutex_unlock(&hdw->i2c_list_lock);
+				cp->handler->func_table->update(
+					cp->handler->func_data);
+				mutex_lock(&hdw->i2c_list_lock);
+				/* If client's update function set some
+				   additional pending bits, account for that
+				   here. */
+				if (cp->pend_mask & ~hdw->i2c_pend_mask) {
+					hdw->i2c_pend_mask |= cp->pend_mask;
+					hdw->i2c_pend_types |=
+						PVR2_I2C_PEND_REFRESH;
+				}
+			}
+		}
+		if (hdw->i2c_pend_types & PVR2_I2C_PEND_REFRESH) {
+			const struct pvr2_i2c_op *opf;
+			unsigned long pm;
+			/* Some actual updates are pending.  Walk through
+			   each update type and perform it. */
+			pvr2_trace(PVR2_TRACE_I2C_CORE,"i2c: PEND_REFRESH"
+				   " (0x%lx)",hdw->i2c_pend_mask);
+			hdw->i2c_pend_types &= ~PVR2_I2C_PEND_REFRESH;
+			pm = hdw->i2c_pend_mask;
+			hdw->i2c_pend_mask = 0;
+			for (idx = 0, msk = 1; pm; idx++, msk <<= 1) {
+				if (!(pm & msk)) continue;
+				pm &= ~msk;
+				list_for_each(item,&hdw->i2c_clients) {
+					cp = list_entry(item,
+							struct pvr2_i2c_client,
+							list);
+					if (cp->pend_mask & msk) {
+						cp->pend_mask &= ~msk;
+						cp->recv_enable = !0;
+					} else {
+						cp->recv_enable = 0;
+					}
+				}
+				opf = pvr2_i2c_get_op(idx);
+				if (!opf) continue;
+				mutex_unlock(&hdw->i2c_list_lock);
+				opf->update(hdw);
+				mutex_lock(&hdw->i2c_list_lock);
+			}
+		}
+		pvr2_trace(PVR2_TRACE_I2C_CORE,"i2c: core_sync END");
+	} while (0); mutex_unlock(&hdw->i2c_list_lock);
+}
+
+int pvr2_i2c_core_check_stale(struct pvr2_hdw *hdw)
+{
+	unsigned long msk,sm,pm;
+	unsigned int idx;
+	const struct pvr2_i2c_op *opf;
+	struct list_head *item;
+	struct pvr2_i2c_client *cp;
+	unsigned int pt = 0;
+
+	pvr2_trace(PVR2_TRACE_I2C_CORE,"pvr2_i2c_core_check_stale BEGIN");
+
+	pm = hdw->i2c_active_mask;
+	sm = 0;
+	for (idx = 0, msk = 1; pm; idx++, msk <<= 1) {
+		if (!(msk & pm)) continue;
+		pm &= ~msk;
+		opf = pvr2_i2c_get_op(idx);
+		if (!opf) continue;
+		if (opf->check(hdw)) {
+			sm |= msk;
+		}
+	}
+	if (sm) pt |= PVR2_I2C_PEND_STALE;
+
+	list_for_each(item,&hdw->i2c_clients) {
+		cp = list_entry(item,struct pvr2_i2c_client,list);
+		if (!handler_check(cp)) continue;
+		pt |= PVR2_I2C_PEND_CLIENT;
+	}
+
+	if (pt) {
+		mutex_lock(&hdw->i2c_list_lock); do {
+			hdw->i2c_pend_types |= pt;
+			hdw->i2c_stale_mask |= sm;
+			hdw->i2c_pend_mask |= hdw->i2c_stale_mask;
+		} while (0); mutex_unlock(&hdw->i2c_list_lock);
+	}
+
+	pvr2_trace(PVR2_TRACE_I2C_CORE,
+		   "i2c: types=0x%x stale=0x%lx pend=0x%lx",
+		   hdw->i2c_pend_types,
+		   hdw->i2c_stale_mask,
+		   hdw->i2c_pend_mask);
+	pvr2_trace(PVR2_TRACE_I2C_CORE,"pvr2_i2c_core_check_stale END");
+
+	return (hdw->i2c_pend_types & PVR2_I2C_PEND_ALL) != 0;
+}
+
+static unsigned int pvr2_i2c_client_describe(struct pvr2_i2c_client *cp,
+					     unsigned int detail,
+					     char *buf,unsigned int maxlen)
+{
+	unsigned int ccnt,bcnt;
+	int spcfl = 0;
+	const struct pvr2_i2c_op *opf;
+
+	ccnt = 0;
+	if (detail & PVR2_I2C_DETAIL_DEBUG) {
+		bcnt = scnprintf(buf,maxlen,
+				 "ctxt=%p ctl_mask=0x%lx",
+				 cp,cp->ctl_mask);
+		ccnt += bcnt; buf += bcnt; maxlen -= bcnt;
+		spcfl = !0;
+	}
+	bcnt = scnprintf(buf,maxlen,
+			 "%s%s @ 0x%x",
+			 (spcfl ? " " : ""),
+			 cp->client->name,
+			 cp->client->addr);
+	ccnt += bcnt; buf += bcnt; maxlen -= bcnt;
+	if ((detail & PVR2_I2C_DETAIL_HANDLER) &&
+	    cp->handler && cp->handler->func_table->describe) {
+		bcnt = scnprintf(buf,maxlen," (");
+		ccnt += bcnt; buf += bcnt; maxlen -= bcnt;
+		bcnt = cp->handler->func_table->describe(
+			cp->handler->func_data,buf,maxlen);
+		ccnt += bcnt; buf += bcnt; maxlen -= bcnt;
+		bcnt = scnprintf(buf,maxlen,")");
+		ccnt += bcnt; buf += bcnt; maxlen -= bcnt;
+	}
+	if ((detail & PVR2_I2C_DETAIL_CTLMASK) && cp->ctl_mask) {
+		unsigned int idx;
+		unsigned long msk,sm;
+		int spcfl;
+		bcnt = scnprintf(buf,maxlen," [");
+		ccnt += bcnt; buf += bcnt; maxlen -= bcnt;
+		sm = 0;
+		spcfl = 0;
+		for (idx = 0, msk = 1; msk; idx++, msk <<= 1) {
+			if (!(cp->ctl_mask & msk)) continue;
+			opf = pvr2_i2c_get_op(idx);
+			if (opf) {
+				bcnt = scnprintf(buf,maxlen,"%s%s",
+						 spcfl ? " " : "",
+						 opf->name);
+				ccnt += bcnt; buf += bcnt; maxlen -= bcnt;
+				spcfl = !0;
+			} else {
+				sm |= msk;
+			}
+		}
+		if (sm) {
+			bcnt = scnprintf(buf,maxlen,"%s%lx",
+					 idx != 0 ? " " : "",sm);
+			ccnt += bcnt; buf += bcnt; maxlen -= bcnt;
+		}
+		bcnt = scnprintf(buf,maxlen,"]");
+		ccnt += bcnt; buf += bcnt; maxlen -= bcnt;
+	}
+	return ccnt;
+}
+
+unsigned int pvr2_i2c_report(struct pvr2_hdw *hdw,
+			     char *buf,unsigned int maxlen)
+{
+	unsigned int ccnt,bcnt;
+	struct list_head *item;
+	struct pvr2_i2c_client *cp;
+	ccnt = 0;
+	mutex_lock(&hdw->i2c_list_lock); do {
+		list_for_each(item,&hdw->i2c_clients) {
+			cp = list_entry(item,struct pvr2_i2c_client,list);
+			bcnt = pvr2_i2c_client_describe(
+				cp,
+				(PVR2_I2C_DETAIL_HANDLER|
+				 PVR2_I2C_DETAIL_CTLMASK),
+				buf,maxlen);
+			ccnt += bcnt; buf += bcnt; maxlen -= bcnt;
+			bcnt = scnprintf(buf,maxlen,"\n");
+			ccnt += bcnt; buf += bcnt; maxlen -= bcnt;
+		}
+	} while (0); mutex_unlock(&hdw->i2c_list_lock);
+	return ccnt;
+}
+
+static int pvr2_i2c_attach_inform(struct i2c_client *client)
+{
+	struct pvr2_hdw *hdw = (struct pvr2_hdw *)(client->adapter->algo_data);
+	struct pvr2_i2c_client *cp;
+	int fl = !(hdw->i2c_pend_types & PVR2_I2C_PEND_ALL);
+	cp = kmalloc(sizeof(*cp),GFP_KERNEL);
+	trace_i2c("i2c_attach [client=%s @ 0x%x ctxt=%p]",
+		  client->name,
+		  client->addr,cp);
+	if (!cp) return -ENOMEM;
+	memset(cp,0,sizeof(*cp));
+	INIT_LIST_HEAD(&cp->list);
+	cp->client = client;
+	mutex_lock(&hdw->i2c_list_lock); do {
+		list_add_tail(&cp->list,&hdw->i2c_clients);
+		hdw->i2c_pend_types |= PVR2_I2C_PEND_DETECT;
+	} while (0); mutex_unlock(&hdw->i2c_list_lock);
+	if (fl) pvr2_hdw_poll_trigger_unlocked(hdw);
+	return 0;
+}
+
+static int pvr2_i2c_detach_inform(struct i2c_client *client)
+{
+	struct pvr2_hdw *hdw = (struct pvr2_hdw *)(client->adapter->algo_data);
+	struct pvr2_i2c_client *cp;
+	struct list_head *item,*nc;
+	unsigned long amask = 0;
+	int foundfl = 0;
+	mutex_lock(&hdw->i2c_list_lock); do {
+		list_for_each_safe(item,nc,&hdw->i2c_clients) {
+			cp = list_entry(item,struct pvr2_i2c_client,list);
+			if (cp->client == client) {
+				trace_i2c("pvr2_i2c_detach"
+					  " [client=%s @ 0x%x ctxt=%p]",
+					  client->name,
+					  client->addr,cp);
+				if (cp->handler &&
+				    cp->handler->func_table->detach) {
+					cp->handler->func_table->detach(
+						cp->handler->func_data);
+				}
+				list_del(&cp->list);
+				kfree(cp);
+				foundfl = !0;
+				continue;
+			}
+			amask |= cp->ctl_mask;
+		}
+		hdw->i2c_active_mask = amask;
+	} while (0); mutex_unlock(&hdw->i2c_list_lock);
+	if (!foundfl) {
+		trace_i2c("pvr2_i2c_detach [client=%s @ 0x%x ctxt=<unknown>]",
+			  client->name,
+			  client->addr);
+	}
+	return 0;
+}
+
+static struct i2c_algorithm pvr2_i2c_algo_template = {
+	.master_xfer   = pvr2_i2c_xfer,
+	.algo_control  = pvr2_i2c_control,
+	.functionality = pvr2_i2c_functionality,
+};
+
+static struct i2c_adapter pvr2_i2c_adap_template = {
+	.owner         = THIS_MODULE,
+	.class	   = I2C_CLASS_TV_ANALOG,
+	.id            = I2C_HW_B_BT848,
+	.client_register = pvr2_i2c_attach_inform,
+	.client_unregister = pvr2_i2c_detach_inform,
+};
+
+static void do_i2c_scan(struct pvr2_hdw *hdw)
+{
+	struct i2c_msg msg[1];
+	int i,rc;
+	msg[0].addr = 0;
+	msg[0].flags = I2C_M_RD;
+	msg[0].len = 0;
+	msg[0].buf = NULL;
+	printk("%s: i2c scan beginning\n",hdw->name);
+	for (i = 0; i < 128; i++) {
+		msg[0].addr = i;
+		rc = i2c_transfer(&hdw->i2c_adap,msg,
+				  sizeof(msg)/sizeof(msg[0]));
+		if (rc != 1) continue;
+		printk("%s: i2c scan: found device @ 0x%x\n",hdw->name,i);
+	}
+	printk("%s: i2c scan done.\n",hdw->name);
+}
+
+void pvr2_i2c_core_init(struct pvr2_hdw *hdw)
+{
+	unsigned int idx;
+
+	// The default action for all possible I2C addresses is just to do
+	// the transfer normally.
+	for (idx = 0; idx < PVR2_I2C_FUNC_CNT; idx++) {
+		hdw->i2c_func[idx] = pvr2_i2c_basic_op;
+	}
+
+#ifdef CONFIG_VIDEO_PVRUSB2_24XXX
+	// If however we're dealing with new hardware, insert some hacks in
+	// the I2C transfer stack to let things work better.
+	if (hdw->hdw_type == PVR2_HDW_TYPE_24XXX) {
+		hdw->i2c_func[0x1b] = i2c_hack_wm8775;
+		hdw->i2c_func[0x44] = i2c_hack_cx25840;
+	}
+#endif
+
+	// Configure the adapter and set up everything else related to it.
+	memcpy(&hdw->i2c_adap,&pvr2_i2c_adap_template,sizeof(hdw->i2c_adap));
+	memcpy(&hdw->i2c_algo,&pvr2_i2c_algo_template,sizeof(hdw->i2c_algo));
+	strlcpy(hdw->i2c_adap.name,hdw->name,sizeof(hdw->i2c_adap.name));
+	hdw->i2c_adap.algo = &hdw->i2c_algo;
+	hdw->i2c_adap.algo_data = hdw;
+	hdw->i2c_pend_mask = 0;
+	hdw->i2c_stale_mask = 0;
+	hdw->i2c_active_mask = 0;
+	INIT_LIST_HEAD(&hdw->i2c_clients);
+	mutex_init(&hdw->i2c_list_lock);
+	hdw->i2c_linked = !0;
+	i2c_add_adapter(&hdw->i2c_adap);
+	if (i2c_scan) do_i2c_scan(hdw);
+}
+
+void pvr2_i2c_core_done(struct pvr2_hdw *hdw)
+{
+	if (hdw->i2c_linked) {
+		i2c_del_adapter(&hdw->i2c_adap);
+		hdw->i2c_linked = 0;
+	}
+}
+
+/*
+  Stuff for Emacs to see, in order to encourage consistent editing style:
+  *** Local Variables: ***
+  *** mode: c ***
+  *** fill-column: 75 ***
+  *** tab-width: 8 ***
+  *** c-basic-offset: 8 ***
+  *** End: ***
+  */
diff --git a/drivers/media/video/pvrusb2/pvrusb2-i2c-core.h b/drivers/media/video/pvrusb2/pvrusb2-i2c-core.h
new file mode 100644
index 000000000..6d7e25247
--- /dev/null
+++ b/drivers/media/video/pvrusb2/pvrusb2-i2c-core.h
@@ -0,0 +1,93 @@
+/*
+ *
+ *  $Id$
+ *
+ *  Copyright (C) 2005 Mike Isely <isely@pobox.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
+ *
+ *  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 __PVRUSB2_I2C_CORE_H
+#define __PVRUSB2_I2C_CORE_H
+
+#include <linux/list.h>
+#include <linux/i2c.h>
+
+struct pvr2_hdw;
+struct pvr2_i2c_client;
+struct pvr2_i2c_handler;
+struct pvr2_i2c_handler_functions;
+struct pvr2_i2c_op;
+struct pvr2_i2c_op_functions;
+
+struct pvr2_i2c_client {
+	struct i2c_client *client;
+	struct pvr2_i2c_handler *handler;
+	struct list_head list;
+	int detected_flag;
+	int recv_enable;
+	unsigned long pend_mask;
+	unsigned long ctl_mask;
+};
+
+struct pvr2_i2c_handler {
+	void *func_data;
+	const struct pvr2_i2c_handler_functions *func_table;
+};
+
+struct pvr2_i2c_handler_functions {
+	void (*detach)(void *);
+	int (*check)(void *);
+	void (*update)(void *);
+	unsigned int (*describe)(void *,char *,unsigned int);
+};
+
+struct pvr2_i2c_op {
+	int (*check)(struct pvr2_hdw *);
+	void (*update)(struct pvr2_hdw *);
+	const char *name;
+};
+
+void pvr2_i2c_core_init(struct pvr2_hdw *);
+void pvr2_i2c_core_done(struct pvr2_hdw *);
+
+int pvr2_i2c_client_cmd(struct pvr2_i2c_client *,unsigned int cmd,void *arg);
+int pvr2_i2c_core_cmd(struct pvr2_hdw *,unsigned int cmd,void *arg);
+
+int pvr2_i2c_core_check_stale(struct pvr2_hdw *);
+void pvr2_i2c_core_sync(struct pvr2_hdw *);
+unsigned int pvr2_i2c_report(struct pvr2_hdw *,char *buf,unsigned int maxlen);
+#define PVR2_I2C_DETAIL_DEBUG   0x0001
+#define PVR2_I2C_DETAIL_HANDLER 0x0002
+#define PVR2_I2C_DETAIL_CTLMASK 0x0004
+#define PVR2_I2C_DETAIL_ALL (\
+	PVR2_I2C_DETAIL_DEBUG |\
+	PVR2_I2C_DETAIL_HANDLER |\
+	PVR2_I2C_DETAIL_CTLMASK)
+
+void pvr2_i2c_probe(struct pvr2_hdw *,struct pvr2_i2c_client *);
+const struct pvr2_i2c_op *pvr2_i2c_get_op(unsigned int idx);
+
+#endif /* __PVRUSB2_I2C_CORE_H */
+
+
+/*
+  Stuff for Emacs to see, in order to encourage consistent editing style:
+  *** Local Variables: ***
+  *** mode: c ***
+  *** fill-column: 75 ***
+  *** tab-width: 8 ***
+  *** c-basic-offset: 8 ***
+  *** End: ***
+  */
diff --git a/drivers/media/video/pvrusb2/pvrusb2-io.c b/drivers/media/video/pvrusb2/pvrusb2-io.c
new file mode 100644
index 000000000..1e3937625
--- /dev/null
+++ b/drivers/media/video/pvrusb2/pvrusb2-io.c
@@ -0,0 +1,667 @@
+/*
+ *
+ *  $Id$
+ *
+ *  Copyright (C) 2005 Mike Isely <isely@pobox.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
+ *
+ *  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 "pvrusb2-io.h"
+#include "pvrusb2-debug.h"
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+#include <linux/mutex.h>
+
+static const char *pvr2_buffer_state_decode(enum pvr2_buffer_state);
+
+#define BUFFER_SIG 0x47653271
+
+// #define SANITY_CHECK_BUFFERS
+
+
+#ifdef SANITY_CHECK_BUFFERS
+#define BUFFER_CHECK(bp) do { \
+	if ((bp)->signature != BUFFER_SIG) { \
+		pvr2_trace(PVR2_TRACE_ERROR_LEGS, \
+		"Buffer %p is bad at %s:%d", \
+		(bp),__FILE__,__LINE__); \
+		pvr2_buffer_describe(bp,"BadSig"); \
+		BUG(); \
+	} \
+} while (0)
+#else
+#define BUFFER_CHECK(bp) do {} while(0)
+#endif
+
+struct pvr2_stream {
+	/* Buffers queued for reading */
+	struct list_head queued_list;
+	unsigned int q_count;
+	unsigned int q_bcount;
+	/* Buffers with retrieved data */
+	struct list_head ready_list;
+	unsigned int r_count;
+	unsigned int r_bcount;
+	/* Buffers available for use */
+	struct list_head idle_list;
+	unsigned int i_count;
+	unsigned int i_bcount;
+	/* Pointers to all buffers */
+	struct pvr2_buffer **buffers;
+	/* Array size of buffers */
+	unsigned int buffer_slot_count;
+	/* Total buffers actually in circulation */
+	unsigned int buffer_total_count;
+	/* Designed number of buffers to be in circulation */
+	unsigned int buffer_target_count;
+	/* Executed when ready list become non-empty */
+	pvr2_stream_callback callback_func;
+	void *callback_data;
+	/* Context for transfer endpoint */
+	struct usb_device *dev;
+	int endpoint;
+	/* Overhead for mutex enforcement */
+	spinlock_t list_lock;
+	struct mutex mutex;
+	/* Tracking state for tolerating errors */
+	unsigned int fail_count;
+	unsigned int fail_tolerance;
+};
+
+struct pvr2_buffer {
+	int id;
+	int signature;
+	enum pvr2_buffer_state state;
+	void *ptr;               /* Pointer to storage area */
+	unsigned int max_count;  /* Size of storage area */
+	unsigned int used_count; /* Amount of valid data in storage area */
+	int status;              /* Transfer result status */
+	struct pvr2_stream *stream;
+	struct list_head list_overhead;
+	struct urb *purb;
+};
+
+static const char *pvr2_buffer_state_decode(enum pvr2_buffer_state st)
+{
+	switch (st) {
+	case pvr2_buffer_state_none: return "none";
+	case pvr2_buffer_state_idle: return "idle";
+	case pvr2_buffer_state_queued: return "queued";
+	case pvr2_buffer_state_ready: return "ready";
+	}
+	return "unknown";
+}
+
+#ifdef SANITY_CHECK_BUFFERS
+static void pvr2_buffer_describe(struct pvr2_buffer *bp,const char *msg)
+{
+	pvr2_trace(PVR2_TRACE_INFO,
+		   "buffer%s%s %p state=%s id=%d status=%d"
+		   " stream=%p purb=%p sig=0x%x",
+		   (msg ? " " : ""),
+		   (msg ? msg : ""),
+		   bp,
+		   (bp ? pvr2_buffer_state_decode(bp->state) : "(invalid)"),
+		   (bp ? bp->id : 0),
+		   (bp ? bp->status : 0),
+		   (bp ? bp->stream : NULL),
+		   (bp ? bp->purb : NULL),
+		   (bp ? bp->signature : 0));
+}
+#endif  /*  SANITY_CHECK_BUFFERS  */
+
+static void pvr2_buffer_remove(struct pvr2_buffer *bp)
+{
+	unsigned int *cnt;
+	unsigned int *bcnt;
+	unsigned int ccnt;
+	struct pvr2_stream *sp = bp->stream;
+	switch (bp->state) {
+	case pvr2_buffer_state_idle:
+		cnt = &sp->i_count;
+		bcnt = &sp->i_bcount;
+		ccnt = bp->max_count;
+		break;
+	case pvr2_buffer_state_queued:
+		cnt = &sp->q_count;
+		bcnt = &sp->q_bcount;
+		ccnt = bp->max_count;
+		break;
+	case pvr2_buffer_state_ready:
+		cnt = &sp->r_count;
+		bcnt = &sp->r_bcount;
+		ccnt = bp->used_count;
+		break;
+	default:
+		return;
+	}
+	list_del_init(&bp->list_overhead);
+	(*cnt)--;
+	(*bcnt) -= ccnt;
+	pvr2_trace(PVR2_TRACE_BUF_FLOW,
+		   "/*---TRACE_FLOW---*/"
+		   " bufferPool     %8s dec cap=%07d cnt=%02d",
+		   pvr2_buffer_state_decode(bp->state),*bcnt,*cnt);
+	bp->state = pvr2_buffer_state_none;
+}
+
+static void pvr2_buffer_set_none(struct pvr2_buffer *bp)
+{
+	unsigned long irq_flags;
+	struct pvr2_stream *sp;
+	BUFFER_CHECK(bp);
+	sp = bp->stream;
+	pvr2_trace(PVR2_TRACE_BUF_FLOW,
+		   "/*---TRACE_FLOW---*/ bufferState    %p %6s --> %6s",
+		   bp,
+		   pvr2_buffer_state_decode(bp->state),
+		   pvr2_buffer_state_decode(pvr2_buffer_state_none));
+	spin_lock_irqsave(&sp->list_lock,irq_flags);
+	pvr2_buffer_remove(bp);
+	spin_unlock_irqrestore(&sp->list_lock,irq_flags);
+}
+
+static int pvr2_buffer_set_ready(struct pvr2_buffer *bp)
+{
+	int fl;
+	unsigned long irq_flags;
+	struct pvr2_stream *sp;
+	BUFFER_CHECK(bp);
+	sp = bp->stream;
+	pvr2_trace(PVR2_TRACE_BUF_FLOW,
+		   "/*---TRACE_FLOW---*/ bufferState    %p %6s --> %6s",
+		   bp,
+		   pvr2_buffer_state_decode(bp->state),
+		   pvr2_buffer_state_decode(pvr2_buffer_state_ready));
+	spin_lock_irqsave(&sp->list_lock,irq_flags);
+	fl = (sp->r_count == 0);
+	pvr2_buffer_remove(bp);
+	list_add_tail(&bp->list_overhead,&sp->ready_list);
+	bp->state = pvr2_buffer_state_ready;
+	(sp->r_count)++;
+	sp->r_bcount += bp->used_count;
+	pvr2_trace(PVR2_TRACE_BUF_FLOW,
+		   "/*---TRACE_FLOW---*/"
+		   " bufferPool     %8s inc cap=%07d cnt=%02d",
+		   pvr2_buffer_state_decode(bp->state),
+		   sp->r_bcount,sp->r_count);
+	spin_unlock_irqrestore(&sp->list_lock,irq_flags);
+	return fl;
+}
+
+static void pvr2_buffer_set_idle(struct pvr2_buffer *bp)
+{
+	unsigned long irq_flags;
+	struct pvr2_stream *sp;
+	BUFFER_CHECK(bp);
+	sp = bp->stream;
+	pvr2_trace(PVR2_TRACE_BUF_FLOW,
+		   "/*---TRACE_FLOW---*/ bufferState    %p %6s --> %6s",
+		   bp,
+		   pvr2_buffer_state_decode(bp->state),
+		   pvr2_buffer_state_decode(pvr2_buffer_state_idle));
+	spin_lock_irqsave(&sp->list_lock,irq_flags);
+	pvr2_buffer_remove(bp);
+	list_add_tail(&bp->list_overhead,&sp->idle_list);
+	bp->state = pvr2_buffer_state_idle;
+	(sp->i_count)++;
+	sp->i_bcount += bp->max_count;
+	pvr2_trace(PVR2_TRACE_BUF_FLOW,
+		   "/*---TRACE_FLOW---*/"
+		   " bufferPool     %8s inc cap=%07d cnt=%02d",
+		   pvr2_buffer_state_decode(bp->state),
+		   sp->i_bcount,sp->i_count);
+	spin_unlock_irqrestore(&sp->list_lock,irq_flags);
+}
+
+static void pvr2_buffer_set_queued(struct pvr2_buffer *bp)
+{
+	unsigned long irq_flags;
+	struct pvr2_stream *sp;
+	BUFFER_CHECK(bp);
+	sp = bp->stream;
+	pvr2_trace(PVR2_TRACE_BUF_FLOW,
+		   "/*---TRACE_FLOW---*/ bufferState    %p %6s --> %6s",
+		   bp,
+		   pvr2_buffer_state_decode(bp->state),
+		   pvr2_buffer_state_decode(pvr2_buffer_state_queued));
+	spin_lock_irqsave(&sp->list_lock,irq_flags);
+	pvr2_buffer_remove(bp);
+	list_add_tail(&bp->list_overhead,&sp->queued_list);
+	bp->state = pvr2_buffer_state_queued;
+	(sp->q_count)++;
+	sp->q_bcount += bp->max_count;
+	pvr2_trace(PVR2_TRACE_BUF_FLOW,
+		   "/*---TRACE_FLOW---*/"
+		   " bufferPool     %8s inc cap=%07d cnt=%02d",
+		   pvr2_buffer_state_decode(bp->state),
+		   sp->q_bcount,sp->q_count);
+	spin_unlock_irqrestore(&sp->list_lock,irq_flags);
+}
+
+static void pvr2_buffer_wipe(struct pvr2_buffer *bp)
+{
+	if (bp->state == pvr2_buffer_state_queued) {
+		usb_kill_urb(bp->purb);
+	}
+}
+
+static int pvr2_buffer_init(struct pvr2_buffer *bp,
+			    struct pvr2_stream *sp,
+			    unsigned int id)
+{
+	memset(bp,0,sizeof(*bp));
+	bp->signature = BUFFER_SIG;
+	bp->id = id;
+	pvr2_trace(PVR2_TRACE_BUF_POOL,
+		   "/*---TRACE_FLOW---*/ bufferInit     %p stream=%p",bp,sp);
+	bp->stream = sp;
+	bp->state = pvr2_buffer_state_none;
+	INIT_LIST_HEAD(&bp->list_overhead);
+	bp->purb = usb_alloc_urb(0,GFP_KERNEL);
+	if (! bp->purb) return -ENOMEM;
+#ifdef SANITY_CHECK_BUFFERS
+	pvr2_buffer_describe(bp,"create");
+#endif
+	return 0;
+}
+
+static void pvr2_buffer_done(struct pvr2_buffer *bp)
+{
+#ifdef SANITY_CHECK_BUFFERS
+	pvr2_buffer_describe(bp,"delete");
+#endif
+	pvr2_buffer_wipe(bp);
+	pvr2_buffer_set_none(bp);
+	bp->signature = 0;
+	bp->stream = NULL;
+	if (bp->purb) usb_free_urb(bp->purb);
+	pvr2_trace(PVR2_TRACE_BUF_POOL,"/*---TRACE_FLOW---*/"
+		   " bufferDone     %p",bp);
+}
+
+static int pvr2_stream_buffer_count(struct pvr2_stream *sp,unsigned int cnt)
+{
+	int ret;
+	unsigned int scnt;
+
+	/* Allocate buffers pointer array in multiples of 32 entries */
+	if (cnt == sp->buffer_total_count) return 0;
+
+	pvr2_trace(PVR2_TRACE_BUF_POOL,
+		   "/*---TRACE_FLOW---*/ poolResize    "
+		   " stream=%p cur=%d adj=%+d",
+		   sp,
+		   sp->buffer_total_count,
+		   cnt-sp->buffer_total_count);
+
+	scnt = cnt & ~0x1f;
+	if (cnt > scnt) scnt += 0x20;
+
+	if (cnt > sp->buffer_total_count) {
+		if (scnt > sp->buffer_slot_count) {
+			struct pvr2_buffer **nb;
+			nb = kmalloc(scnt * sizeof(*nb),GFP_KERNEL);
+			if (!nb) return -ENOMEM;
+			if (sp->buffer_slot_count) {
+				memcpy(nb,sp->buffers,
+				       sp->buffer_slot_count * sizeof(*nb));
+				kfree(sp->buffers);
+			}
+			sp->buffers = nb;
+			sp->buffer_slot_count = scnt;
+		}
+		while (sp->buffer_total_count < cnt) {
+			struct pvr2_buffer *bp;
+			bp = kmalloc(sizeof(*bp),GFP_KERNEL);
+			if (!bp) return -ENOMEM;
+			ret = pvr2_buffer_init(bp,sp,sp->buffer_total_count);
+			if (ret) {
+				kfree(bp);
+				return -ENOMEM;
+			}
+			sp->buffers[sp->buffer_total_count] = bp;
+			(sp->buffer_total_count)++;
+			pvr2_buffer_set_idle(bp);
+		}
+	} else {
+		while (sp->buffer_total_count > cnt) {
+			struct pvr2_buffer *bp;
+			bp = sp->buffers[sp->buffer_total_count - 1];
+			/* Paranoia */
+			sp->buffers[sp->buffer_total_count - 1] = NULL;
+			(sp->buffer_total_count)--;
+			pvr2_buffer_done(bp);
+			kfree(bp);
+		}
+		if (scnt < sp->buffer_slot_count) {
+			struct pvr2_buffer **nb = NULL;
+			if (scnt) {
+				nb = kmalloc(scnt * sizeof(*nb),GFP_KERNEL);
+				if (!nb) return -ENOMEM;
+				memcpy(nb,sp->buffers,scnt * sizeof(*nb));
+			}
+			kfree(sp->buffers);
+			sp->buffers = nb;
+			sp->buffer_slot_count = scnt;
+		}
+	}
+	return 0;
+}
+
+static int pvr2_stream_achieve_buffer_count(struct pvr2_stream *sp)
+{
+	struct pvr2_buffer *bp;
+	unsigned int cnt;
+
+	if (sp->buffer_total_count == sp->buffer_target_count) return 0;
+
+	pvr2_trace(PVR2_TRACE_BUF_POOL,
+		   "/*---TRACE_FLOW---*/"
+		   " poolCheck      stream=%p cur=%d tgt=%d",
+		   sp,sp->buffer_total_count,sp->buffer_target_count);
+
+	if (sp->buffer_total_count < sp->buffer_target_count) {
+		return pvr2_stream_buffer_count(sp,sp->buffer_target_count);
+	}
+
+	cnt = 0;
+	while ((sp->buffer_total_count - cnt) > sp->buffer_target_count) {
+		bp = sp->buffers[sp->buffer_total_count - (cnt + 1)];
+		if (bp->state != pvr2_buffer_state_idle) break;
+		cnt++;
+	}
+	if (cnt) {
+		pvr2_stream_buffer_count(sp,sp->buffer_total_count - cnt);
+	}
+
+	return 0;
+}
+
+static void pvr2_stream_internal_flush(struct pvr2_stream *sp)
+{
+	struct list_head *lp;
+	struct pvr2_buffer *bp1;
+	while ((lp = sp->queued_list.next) != &sp->queued_list) {
+		bp1 = list_entry(lp,struct pvr2_buffer,list_overhead);
+		pvr2_buffer_wipe(bp1);
+		/* At this point, we should be guaranteed that no
+		   completion callback may happen on this buffer.  But it's
+		   possible that it might have completed after we noticed
+		   it but before we wiped it.  So double check its status
+		   here first. */
+		if (bp1->state != pvr2_buffer_state_queued) continue;
+		pvr2_buffer_set_idle(bp1);
+	}
+	if (sp->buffer_total_count != sp->buffer_target_count) {
+		pvr2_stream_achieve_buffer_count(sp);
+	}
+}
+
+static void pvr2_stream_init(struct pvr2_stream *sp)
+{
+	spin_lock_init(&sp->list_lock);
+	mutex_init(&sp->mutex);
+	INIT_LIST_HEAD(&sp->queued_list);
+	INIT_LIST_HEAD(&sp->ready_list);
+	INIT_LIST_HEAD(&sp->idle_list);
+}
+
+static void pvr2_stream_done(struct pvr2_stream *sp)
+{
+	mutex_lock(&sp->mutex); do {
+		pvr2_stream_internal_flush(sp);
+		pvr2_stream_buffer_count(sp,0);
+	} while (0); mutex_unlock(&sp->mutex);
+}
+
+static void buffer_complete(struct urb *urb, struct pt_regs *regs)
+{
+	struct pvr2_buffer *bp = urb->context;
+	struct pvr2_stream *sp;
+	unsigned long irq_flags;
+	BUFFER_CHECK(bp);
+	sp = bp->stream;
+	bp->used_count = 0;
+	bp->status = 0;
+	pvr2_trace(PVR2_TRACE_BUF_FLOW,
+		   "/*---TRACE_FLOW---*/ bufferComplete %p stat=%d cnt=%d",
+		   bp,urb->status,urb->actual_length);
+	spin_lock_irqsave(&sp->list_lock,irq_flags);
+	if ((!(urb->status)) ||
+	    (urb->status == -ENOENT) ||
+	    (urb->status == -ECONNRESET) ||
+	    (urb->status == -ESHUTDOWN)) {
+		bp->used_count = urb->actual_length;
+		if (sp->fail_count) {
+			pvr2_trace(PVR2_TRACE_TOLERANCE,
+				   "stream %p transfer ok"
+				   " - fail count reset",sp);
+			sp->fail_count = 0;
+		}
+	} else if (sp->fail_count < sp->fail_tolerance) {
+		// We can tolerate this error, because we're below the
+		// threshold...
+		(sp->fail_count)++;
+		pvr2_trace(PVR2_TRACE_TOLERANCE,
+			   "stream %p ignoring error %d"
+			   " - fail count increased to %u",
+			   sp,urb->status,sp->fail_count);
+	} else {
+		bp->status = urb->status;
+	}
+	spin_unlock_irqrestore(&sp->list_lock,irq_flags);
+	pvr2_buffer_set_ready(bp);
+	if (sp && sp->callback_func) {
+		sp->callback_func(sp->callback_data);
+	}
+}
+
+struct pvr2_stream *pvr2_stream_create(void)
+{
+	struct pvr2_stream *sp;
+	sp = kmalloc(sizeof(*sp),GFP_KERNEL);
+	if (!sp) return sp;
+	memset(sp,0,sizeof(*sp));
+	pvr2_trace(PVR2_TRACE_INIT,"pvr2_stream_create: sp=%p",sp);
+	pvr2_stream_init(sp);
+	return sp;
+}
+
+void pvr2_stream_destroy(struct pvr2_stream *sp)
+{
+	if (!sp) return;
+	pvr2_trace(PVR2_TRACE_INIT,"pvr2_stream_destroy: sp=%p",sp);
+	pvr2_stream_done(sp);
+	kfree(sp);
+}
+
+void pvr2_stream_setup(struct pvr2_stream *sp,
+		       struct usb_device *dev,
+		       int endpoint,
+		       unsigned int tolerance)
+{
+	mutex_lock(&sp->mutex); do {
+		pvr2_stream_internal_flush(sp);
+		sp->dev = dev;
+		sp->endpoint = endpoint;
+		sp->fail_tolerance = tolerance;
+	} while(0); mutex_unlock(&sp->mutex);
+}
+
+void pvr2_stream_set_callback(struct pvr2_stream *sp,
+			      pvr2_stream_callback func,
+			      void *data)
+{
+	unsigned long irq_flags;
+	mutex_lock(&sp->mutex); do {
+		spin_lock_irqsave(&sp->list_lock,irq_flags);
+		sp->callback_data = data;
+		sp->callback_func = func;
+		spin_unlock_irqrestore(&sp->list_lock,irq_flags);
+	} while(0); mutex_unlock(&sp->mutex);
+}
+
+/* Query / set the nominal buffer count */
+int pvr2_stream_get_buffer_count(struct pvr2_stream *sp)
+{
+	return sp->buffer_target_count;
+}
+
+int pvr2_stream_set_buffer_count(struct pvr2_stream *sp,unsigned int cnt)
+{
+	int ret;
+	if (sp->buffer_target_count == cnt) return 0;
+	mutex_lock(&sp->mutex); do {
+		sp->buffer_target_count = cnt;
+		ret = pvr2_stream_achieve_buffer_count(sp);
+	} while(0); mutex_unlock(&sp->mutex);
+	return ret;
+}
+
+struct pvr2_buffer *pvr2_stream_get_idle_buffer(struct pvr2_stream *sp)
+{
+	struct list_head *lp = sp->idle_list.next;
+	if (lp == &sp->idle_list) return NULL;
+	return list_entry(lp,struct pvr2_buffer,list_overhead);
+}
+
+struct pvr2_buffer *pvr2_stream_get_ready_buffer(struct pvr2_stream *sp)
+{
+	struct list_head *lp = sp->ready_list.next;
+	if (lp == &sp->ready_list) return NULL;
+	return list_entry(lp,struct pvr2_buffer,list_overhead);
+}
+
+struct pvr2_buffer *pvr2_stream_get_buffer(struct pvr2_stream *sp,int id)
+{
+	if (id < 0) return NULL;
+	if (id >= sp->buffer_total_count) return NULL;
+	return sp->buffers[id];
+}
+
+int pvr2_stream_get_ready_count(struct pvr2_stream *sp)
+{
+	return sp->r_count;
+}
+
+void pvr2_stream_kill(struct pvr2_stream *sp)
+{
+	struct pvr2_buffer *bp;
+	mutex_lock(&sp->mutex); do {
+		pvr2_stream_internal_flush(sp);
+		while ((bp = pvr2_stream_get_ready_buffer(sp)) != 0) {
+			pvr2_buffer_set_idle(bp);
+		}
+		if (sp->buffer_total_count != sp->buffer_target_count) {
+			pvr2_stream_achieve_buffer_count(sp);
+		}
+	} while(0); mutex_unlock(&sp->mutex);
+}
+
+int pvr2_buffer_queue(struct pvr2_buffer *bp)
+{
+#undef SEED_BUFFER
+#ifdef SEED_BUFFER
+	unsigned int idx;
+	unsigned int val;
+#endif
+	int ret = 0;
+	struct pvr2_stream *sp;
+	if (!bp) return -EINVAL;
+	sp = bp->stream;
+	mutex_lock(&sp->mutex); do {
+		pvr2_buffer_wipe(bp);
+		if (!sp->dev) {
+			ret = -EIO;
+			break;
+		}
+		pvr2_buffer_set_queued(bp);
+#ifdef SEED_BUFFER
+		for (idx = 0; idx < (bp->max_count) / 4; idx++) {
+			val = bp->id << 24;
+			val |= idx;
+			((unsigned int *)(bp->ptr))[idx] = val;
+		}
+#endif
+		bp->status = -EINPROGRESS;
+		usb_fill_bulk_urb(bp->purb,      // struct urb *urb
+				  sp->dev,       // struct usb_device *dev
+				  // endpoint (below)
+				  usb_rcvbulkpipe(sp->dev,sp->endpoint),
+				  bp->ptr,       // void *transfer_buffer
+				  bp->max_count, // int buffer_length
+				  buffer_complete,
+				  bp);
+		usb_submit_urb(bp->purb,GFP_KERNEL);
+	} while(0); mutex_unlock(&sp->mutex);
+	return ret;
+}
+
+int pvr2_buffer_set_buffer(struct pvr2_buffer *bp,void *ptr,unsigned int cnt)
+{
+	int ret = 0;
+	unsigned long irq_flags;
+	struct pvr2_stream *sp;
+	if (!bp) return -EINVAL;
+	sp = bp->stream;
+	mutex_lock(&sp->mutex); do {
+		spin_lock_irqsave(&sp->list_lock,irq_flags);
+		if (bp->state != pvr2_buffer_state_idle) {
+			ret = -EPERM;
+		} else {
+			bp->ptr = ptr;
+			bp->stream->i_bcount -= bp->max_count;
+			bp->max_count = cnt;
+			bp->stream->i_bcount += bp->max_count;
+			pvr2_trace(PVR2_TRACE_BUF_FLOW,
+				   "/*---TRACE_FLOW---*/ bufferPool    "
+				   " %8s cap cap=%07d cnt=%02d",
+				   pvr2_buffer_state_decode(
+					   pvr2_buffer_state_idle),
+				   bp->stream->i_bcount,bp->stream->i_count);
+		}
+		spin_unlock_irqrestore(&sp->list_lock,irq_flags);
+	} while(0); mutex_unlock(&sp->mutex);
+	return ret;
+}
+
+unsigned int pvr2_buffer_get_count(struct pvr2_buffer *bp)
+{
+	return bp->used_count;
+}
+
+int pvr2_buffer_get_status(struct pvr2_buffer *bp)
+{
+	return bp->status;
+}
+
+int pvr2_buffer_get_id(struct pvr2_buffer *bp)
+{
+	return bp->id;
+}
+
+
+/*
+  Stuff for Emacs to see, in order to encourage consistent editing style:
+  *** Local Variables: ***
+  *** mode: c ***
+  *** fill-column: 75 ***
+  *** tab-width: 8 ***
+  *** c-basic-offset: 8 ***
+  *** End: ***
+  */
diff --git a/drivers/media/video/pvrusb2/pvrusb2-io.h b/drivers/media/video/pvrusb2/pvrusb2-io.h
new file mode 100644
index 000000000..93279cc2a
--- /dev/null
+++ b/drivers/media/video/pvrusb2/pvrusb2-io.h
@@ -0,0 +1,91 @@
+/*
+ *
+ *  $Id$
+ *
+ *  Copyright (C) 2005 Mike Isely <isely@pobox.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
+ *
+ *  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 __PVRUSB2_IO_H
+#define __PVRUSB2_IO_H
+
+#include <linux/usb.h>
+#include <linux/list.h>
+
+typedef void (*pvr2_stream_callback)(void *);
+
+enum pvr2_buffer_state {
+	pvr2_buffer_state_none = 0,   // Not on any list
+	pvr2_buffer_state_idle = 1,   // Buffer is ready to be used again
+	pvr2_buffer_state_queued = 2, // Buffer has been queued for filling
+	pvr2_buffer_state_ready = 3,  // Buffer has data available
+};
+
+struct pvr2_stream;
+struct pvr2_buffer;
+
+/* Initialize / tear down stream structure */
+struct pvr2_stream *pvr2_stream_create(void);
+void pvr2_stream_destroy(struct pvr2_stream *);
+void pvr2_stream_setup(struct pvr2_stream *,
+		       struct usb_device *dev,int endpoint,
+		       unsigned int tolerance);
+void pvr2_stream_set_callback(struct pvr2_stream *,
+			      pvr2_stream_callback func,
+			      void *data);
+
+/* Query / set the nominal buffer count */
+int pvr2_stream_get_buffer_count(struct pvr2_stream *);
+int pvr2_stream_set_buffer_count(struct pvr2_stream *,unsigned int);
+
+/* Get a pointer to a buffer that is either idle, ready, or is specified
+   named. */
+struct pvr2_buffer *pvr2_stream_get_idle_buffer(struct pvr2_stream *);
+struct pvr2_buffer *pvr2_stream_get_ready_buffer(struct pvr2_stream *);
+struct pvr2_buffer *pvr2_stream_get_buffer(struct pvr2_stream *sp,int id);
+
+/* Find out how many buffers are idle or ready */
+int pvr2_stream_get_ready_count(struct pvr2_stream *);
+
+
+/* Kill all pending buffers and throw away any ready buffers as well */
+void pvr2_stream_kill(struct pvr2_stream *);
+
+/* Set up the actual storage for a buffer */
+int pvr2_buffer_set_buffer(struct pvr2_buffer *,void *ptr,unsigned int cnt);
+
+/* Find out size of data in the given ready buffer */
+unsigned int pvr2_buffer_get_count(struct pvr2_buffer *);
+
+/* Retrieve completion code for given ready buffer */
+int pvr2_buffer_get_status(struct pvr2_buffer *);
+
+/* Retrieve ID of given buffer */
+int pvr2_buffer_get_id(struct pvr2_buffer *);
+
+/* Start reading into given buffer (kill it if needed) */
+int pvr2_buffer_queue(struct pvr2_buffer *);
+
+#endif /* __PVRUSB2_IO_H */
+
+/*
+  Stuff for Emacs to see, in order to encourage consistent editing style:
+  *** Local Variables: ***
+  *** mode: c ***
+  *** fill-column: 75 ***
+  *** tab-width: 8 ***
+  *** c-basic-offset: 8 ***
+  *** End: ***
+  */
diff --git a/drivers/media/video/pvrusb2/pvrusb2-ioread.c b/drivers/media/video/pvrusb2/pvrusb2-ioread.c
new file mode 100644
index 000000000..b71f9a961
--- /dev/null
+++ b/drivers/media/video/pvrusb2/pvrusb2-ioread.c
@@ -0,0 +1,510 @@
+/*
+ *
+ *  $Id$
+ *
+ *  Copyright (C) 2005 Mike Isely <isely@pobox.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
+ *
+ *  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 "pvrusb2-ioread.h"
+#include "pvrusb2-debug.h"
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+#include <linux/mutex.h>
+#include <asm/uaccess.h>
+
+#define BUFFER_COUNT 32
+#define BUFFER_SIZE PAGE_ALIGN(0x4000)
+
+struct pvr2_ioread {
+	struct pvr2_stream *stream;
+	char *buffer_storage[BUFFER_COUNT];
+	char *sync_key_ptr;
+	unsigned int sync_key_len;
+	unsigned int sync_buf_offs;
+	unsigned int sync_state;
+	unsigned int sync_trashed_count;
+	int enabled;         // Streaming is on
+	int spigot_open;     // OK to pass data to client
+	int stream_running;  // Passing data to client now
+
+	/* State relevant to current buffer being read */
+	struct pvr2_buffer *c_buf;
+	char *c_data_ptr;
+	unsigned int c_data_len;
+	unsigned int c_data_offs;
+	struct mutex mutex;
+};
+
+static int pvr2_ioread_init(struct pvr2_ioread *cp)
+{
+	unsigned int idx;
+
+	cp->stream = NULL;
+	mutex_init(&cp->mutex);
+
+	for (idx = 0; idx < BUFFER_COUNT; idx++) {
+		cp->buffer_storage[idx] = kmalloc(BUFFER_SIZE,GFP_KERNEL);
+		if (!(cp->buffer_storage[idx])) break;
+	}
+
+	if (idx < BUFFER_COUNT) {
+		// An allocation appears to have failed
+		for (idx = 0; idx < BUFFER_COUNT; idx++) {
+			if (!(cp->buffer_storage[idx])) continue;
+			kfree(cp->buffer_storage[idx]);
+		}
+		return -ENOMEM;
+	}
+	return 0;
+}
+
+static void pvr2_ioread_done(struct pvr2_ioread *cp)
+{
+	unsigned int idx;
+
+	pvr2_ioread_setup(cp,NULL);
+	for (idx = 0; idx < BUFFER_COUNT; idx++) {
+		if (!(cp->buffer_storage[idx])) continue;
+		kfree(cp->buffer_storage[idx]);
+	}
+}
+
+struct pvr2_ioread *pvr2_ioread_create(void)
+{
+	struct pvr2_ioread *cp;
+	cp = kmalloc(sizeof(*cp),GFP_KERNEL);
+	if (!cp) return NULL;
+	pvr2_trace(PVR2_TRACE_STRUCT,"pvr2_ioread_create id=%p",cp);
+	memset(cp,0,sizeof(*cp));
+	if (pvr2_ioread_init(cp) < 0) {
+		kfree(cp);
+		return NULL;
+	}
+	return cp;
+}
+
+void pvr2_ioread_destroy(struct pvr2_ioread *cp)
+{
+	if (!cp) return;
+	pvr2_ioread_done(cp);
+	pvr2_trace(PVR2_TRACE_STRUCT,"pvr2_ioread_destroy id=%p",cp);
+	if (cp->sync_key_ptr) {
+		kfree(cp->sync_key_ptr);
+		cp->sync_key_ptr = NULL;
+	}
+	kfree(cp);
+}
+
+void pvr2_ioread_set_sync_key(struct pvr2_ioread *cp,
+			      const char *sync_key_ptr,
+			      unsigned int sync_key_len)
+{
+	if (!cp) return;
+
+	if (!sync_key_ptr) sync_key_len = 0;
+	if ((sync_key_len == cp->sync_key_len) &&
+	    ((!sync_key_len) ||
+	     (!memcmp(sync_key_ptr,cp->sync_key_ptr,sync_key_len)))) return;
+
+	if (sync_key_len != cp->sync_key_len) {
+		if (cp->sync_key_ptr) {
+			kfree(cp->sync_key_ptr);
+			cp->sync_key_ptr = NULL;
+		}
+		cp->sync_key_len = 0;
+		if (sync_key_len) {
+			cp->sync_key_ptr = kmalloc(sync_key_len,GFP_KERNEL);
+			if (cp->sync_key_ptr) {
+				cp->sync_key_len = sync_key_len;
+			}
+		}
+	}
+	if (!cp->sync_key_len) return;
+	memcpy(cp->sync_key_ptr,sync_key_ptr,cp->sync_key_len);
+}
+
+static void pvr2_ioread_stop(struct pvr2_ioread *cp)
+{
+	if (!(cp->enabled)) return;
+	pvr2_trace(PVR2_TRACE_START_STOP,
+		   "/*---TRACE_READ---*/ pvr2_ioread_stop id=%p",cp);
+	pvr2_stream_kill(cp->stream);
+	cp->c_buf = NULL;
+	cp->c_data_ptr = NULL;
+	cp->c_data_len = 0;
+	cp->c_data_offs = 0;
+	cp->enabled = 0;
+	cp->stream_running = 0;
+	cp->spigot_open = 0;
+	if (cp->sync_state) {
+		pvr2_trace(PVR2_TRACE_DATA_FLOW,
+			   "/*---TRACE_READ---*/ sync_state <== 0");
+		cp->sync_state = 0;
+	}
+}
+
+static int pvr2_ioread_start(struct pvr2_ioread *cp)
+{
+	int stat;
+	struct pvr2_buffer *bp;
+	if (cp->enabled) return 0;
+	if (!(cp->stream)) return 0;
+	pvr2_trace(PVR2_TRACE_START_STOP,
+		   "/*---TRACE_READ---*/ pvr2_ioread_start id=%p",cp);
+	while ((bp = pvr2_stream_get_idle_buffer(cp->stream)) != 0) {
+		stat = pvr2_buffer_queue(bp);
+		if (stat < 0) {
+			pvr2_trace(PVR2_TRACE_DATA_FLOW,
+				   "/*---TRACE_READ---*/"
+				   " pvr2_ioread_start id=%p"
+				   " error=%d",
+				   cp,stat);
+			pvr2_ioread_stop(cp);
+			return stat;
+		}
+	}
+	cp->enabled = !0;
+	cp->c_buf = NULL;
+	cp->c_data_ptr = NULL;
+	cp->c_data_len = 0;
+	cp->c_data_offs = 0;
+	cp->stream_running = 0;
+	if (cp->sync_key_len) {
+		pvr2_trace(PVR2_TRACE_DATA_FLOW,
+			   "/*---TRACE_READ---*/ sync_state <== 1");
+		cp->sync_state = 1;
+		cp->sync_trashed_count = 0;
+		cp->sync_buf_offs = 0;
+	}
+	cp->spigot_open = 0;
+	return 0;
+}
+
+struct pvr2_stream *pvr2_ioread_get_stream(struct pvr2_ioread *cp)
+{
+	return cp->stream;
+}
+
+int pvr2_ioread_setup(struct pvr2_ioread *cp,struct pvr2_stream *sp)
+{
+	int ret;
+	unsigned int idx;
+	struct pvr2_buffer *bp;
+
+	mutex_lock(&cp->mutex); do {
+		if (cp->stream) {
+			pvr2_trace(PVR2_TRACE_START_STOP,
+				   "/*---TRACE_READ---*/"
+				   " pvr2_ioread_setup (tear-down) id=%p",cp);
+			pvr2_ioread_stop(cp);
+			pvr2_stream_kill(cp->stream);
+			if (pvr2_stream_get_buffer_count(cp->stream)) {
+				pvr2_stream_set_buffer_count(cp->stream,0);
+			}
+			cp->stream = NULL;
+		}
+		if (sp) {
+			pvr2_trace(PVR2_TRACE_START_STOP,
+				   "/*---TRACE_READ---*/"
+				   " pvr2_ioread_setup (setup) id=%p",cp);
+			pvr2_stream_kill(sp);
+			ret = pvr2_stream_set_buffer_count(sp,BUFFER_COUNT);
+			if (ret < 0) return ret;
+			for (idx = 0; idx < BUFFER_COUNT; idx++) {
+				bp = pvr2_stream_get_buffer(sp,idx);
+				pvr2_buffer_set_buffer(bp,
+						       cp->buffer_storage[idx],
+						       BUFFER_SIZE);
+			}
+			cp->stream = sp;
+		}
+	} while (0); mutex_unlock(&cp->mutex);
+
+	return 0;
+}
+
+int pvr2_ioread_set_enabled(struct pvr2_ioread *cp,int fl)
+{
+	int ret = 0;
+	if ((!fl) == (!(cp->enabled))) return ret;
+
+	mutex_lock(&cp->mutex); do {
+		if (fl) {
+			ret = pvr2_ioread_start(cp);
+		} else {
+			pvr2_ioread_stop(cp);
+		}
+	} while (0); mutex_unlock(&cp->mutex);
+	return ret;
+}
+
+static int pvr2_ioread_get_buffer(struct pvr2_ioread *cp)
+{
+	int stat;
+
+	while (cp->c_data_len <= cp->c_data_offs) {
+		if (cp->c_buf) {
+			// Flush out current buffer first.
+			stat = pvr2_buffer_queue(cp->c_buf);
+			if (stat < 0) {
+				// Streaming error...
+				pvr2_trace(PVR2_TRACE_DATA_FLOW,
+					   "/*---TRACE_READ---*/"
+					   " pvr2_ioread_read id=%p"
+					   " queue_error=%d",
+					   cp,stat);
+				pvr2_ioread_stop(cp);
+				return 0;
+			}
+			cp->c_buf = NULL;
+			cp->c_data_ptr = NULL;
+			cp->c_data_len = 0;
+			cp->c_data_offs = 0;
+		}
+		// Now get a freshly filled buffer.
+		cp->c_buf = pvr2_stream_get_ready_buffer(cp->stream);
+		if (!cp->c_buf) break; // Nothing ready; done.
+		cp->c_data_len = pvr2_buffer_get_count(cp->c_buf);
+		if (!cp->c_data_len) {
+			// Nothing transferred.  Was there an error?
+			stat = pvr2_buffer_get_status(cp->c_buf);
+			if (stat < 0) {
+				// Streaming error...
+				pvr2_trace(PVR2_TRACE_DATA_FLOW,
+					   "/*---TRACE_READ---*/"
+					   " pvr2_ioread_read id=%p"
+					   " buffer_error=%d",
+					   cp,stat);
+				pvr2_ioread_stop(cp);
+				// Give up.
+				return 0;
+			}
+			// Start over...
+			continue;
+		}
+		cp->c_data_offs = 0;
+		cp->c_data_ptr = cp->buffer_storage[
+			pvr2_buffer_get_id(cp->c_buf)];
+	}
+	return !0;
+}
+
+static void pvr2_ioread_filter(struct pvr2_ioread *cp)
+{
+	unsigned int idx;
+	if (!cp->enabled) return;
+	if (cp->sync_state != 1) return;
+
+	// Search the stream for our synchronization key.  This is made
+	// complicated by the fact that in order to be honest with
+	// ourselves here we must search across buffer boundaries...
+	mutex_lock(&cp->mutex); while (1) {
+		// Ensure we have a buffer
+		if (!pvr2_ioread_get_buffer(cp)) break;
+		if (!cp->c_data_len) break;
+
+		// Now walk the buffer contents until we match the key or
+		// run out of buffer data.
+		for (idx = cp->c_data_offs; idx < cp->c_data_len; idx++) {
+			if (cp->sync_buf_offs >= cp->sync_key_len) break;
+			if (cp->c_data_ptr[idx] ==
+			    cp->sync_key_ptr[cp->sync_buf_offs]) {
+				// Found the next key byte
+				(cp->sync_buf_offs)++;
+			} else {
+				// Whoops, mismatched.  Start key over...
+				cp->sync_buf_offs = 0;
+			}
+		}
+
+		// Consume what we've walked through
+		cp->c_data_offs += idx;
+		cp->sync_trashed_count += idx;
+
+		// If we've found the key, then update state and get out.
+		if (cp->sync_buf_offs >= cp->sync_key_len) {
+			cp->sync_trashed_count -= cp->sync_key_len;
+			pvr2_trace(PVR2_TRACE_DATA_FLOW,
+				   "/*---TRACE_READ---*/"
+				   " sync_state <== 2 (skipped %u bytes)",
+				   cp->sync_trashed_count);
+			cp->sync_state = 2;
+			cp->sync_buf_offs = 0;
+			break;
+		}
+
+		if (cp->c_data_offs < cp->c_data_len) {
+			// Sanity check - should NEVER get here
+			pvr2_trace(PVR2_TRACE_ERROR_LEGS,
+				   "ERROR: pvr2_ioread filter sync problem"
+				   " len=%u offs=%u",
+				   cp->c_data_len,cp->c_data_offs);
+			// Get out so we don't get stuck in an infinite
+			// loop.
+			break;
+		}
+
+		continue; // (for clarity)
+	} mutex_unlock(&cp->mutex);
+}
+
+int pvr2_ioread_avail(struct pvr2_ioread *cp)
+{
+	int ret;
+	if (!(cp->enabled)) {
+		// Stream is not enabled; so this is an I/O error
+		return -EIO;
+	}
+
+	if (cp->sync_state == 1) {
+		pvr2_ioread_filter(cp);
+		if (cp->sync_state == 1) return -EAGAIN;
+	}
+
+	ret = 0;
+	if (cp->stream_running) {
+		if (!pvr2_stream_get_ready_count(cp->stream)) {
+			// No data available at all right now.
+			ret = -EAGAIN;
+		}
+	} else {
+		if (pvr2_stream_get_ready_count(cp->stream) < BUFFER_COUNT/2) {
+			// Haven't buffered up enough yet; try again later
+			ret = -EAGAIN;
+		}
+	}
+
+	if ((!(cp->spigot_open)) != (!(ret == 0))) {
+		cp->spigot_open = (ret == 0);
+		pvr2_trace(PVR2_TRACE_DATA_FLOW,
+			   "/*---TRACE_READ---*/ data is %s",
+			   cp->spigot_open ? "available" : "pending");
+	}
+
+	return ret;
+}
+
+int pvr2_ioread_read(struct pvr2_ioread *cp,void __user *buf,unsigned int cnt)
+{
+	unsigned int copied_cnt;
+	unsigned int bcnt;
+	const char *src;
+	int stat;
+	int ret = 0;
+	unsigned int req_cnt = cnt;
+
+	if (!cnt) {
+		pvr2_trace(PVR2_TRACE_TRAP,
+			   "/*---TRACE_READ---*/ pvr2_ioread_read id=%p"
+			   " ZERO Request? Returning zero.",cp);
+		return 0;
+	}
+
+	stat = pvr2_ioread_avail(cp);
+	if (stat < 0) return stat;
+
+	cp->stream_running = !0;
+
+	mutex_lock(&cp->mutex); do {
+
+		// Suck data out of the buffers and copy to the user
+		copied_cnt = 0;
+		if (!buf) cnt = 0;
+		while (1) {
+			if (!pvr2_ioread_get_buffer(cp)) {
+				ret = -EIO;
+				break;
+			}
+
+			if (!cnt) break;
+
+			if (cp->sync_state == 2) {
+				// We're repeating the sync key data into
+				// the stream.
+				src = cp->sync_key_ptr + cp->sync_buf_offs;
+				bcnt = cp->sync_key_len - cp->sync_buf_offs;
+			} else {
+				// Normal buffer copy
+				src = cp->c_data_ptr + cp->c_data_offs;
+				bcnt = cp->c_data_len - cp->c_data_offs;
+			}
+
+			if (!bcnt) break;
+
+			// Don't run past user's buffer
+			if (bcnt > cnt) bcnt = cnt;
+
+			if (copy_to_user(buf,src,bcnt)) {
+				// User supplied a bad pointer?
+				// Give up - this *will* cause data
+				// to be lost.
+				ret = -EFAULT;
+				break;
+			}
+			cnt -= bcnt;
+			buf += bcnt;
+			copied_cnt += bcnt;
+
+			if (cp->sync_state == 2) {
+				// Update offset inside sync key that we're
+				// repeating back out.
+				cp->sync_buf_offs += bcnt;
+				if (cp->sync_buf_offs >= cp->sync_key_len) {
+					// Consumed entire key; switch mode
+					// to normal.
+					pvr2_trace(PVR2_TRACE_DATA_FLOW,
+						   "/*---TRACE_READ---*/"
+						   " sync_state <== 0");
+					cp->sync_state = 0;
+				}
+			} else {
+				// Update buffer offset.
+				cp->c_data_offs += bcnt;
+			}
+		}
+
+	} while (0); mutex_unlock(&cp->mutex);
+
+	if (!ret) {
+		if (copied_cnt) {
+			// If anything was copied, return that count
+			ret = copied_cnt;
+		} else {
+			// Nothing copied; suggest to caller that another
+			// attempt should be tried again later
+			ret = -EAGAIN;
+		}
+	}
+
+	pvr2_trace(PVR2_TRACE_DATA_FLOW,
+		   "/*---TRACE_READ---*/ pvr2_ioread_read"
+		   " id=%p request=%d result=%d",
+		   cp,req_cnt,ret);
+	return ret;
+}
+
+
+/*
+  Stuff for Emacs to see, in order to encourage consistent editing style:
+  *** Local Variables: ***
+  *** mode: c ***
+  *** fill-column: 75 ***
+  *** tab-width: 8 ***
+  *** c-basic-offset: 8 ***
+  *** End: ***
+  */
diff --git a/drivers/media/video/pvrusb2/pvrusb2-ioread.h b/drivers/media/video/pvrusb2/pvrusb2-ioread.h
new file mode 100644
index 000000000..1d362f833
--- /dev/null
+++ b/drivers/media/video/pvrusb2/pvrusb2-ioread.h
@@ -0,0 +1,49 @@
+/*
+ *
+ *  $Id$
+ *
+ *  Copyright (C) 2005 Mike Isely <isely@pobox.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
+ *
+ *  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 __PVRUSB2_IOREAD_H
+#define __PVRUSB2_IOREAD_H
+
+#include "pvrusb2-io.h"
+
+struct pvr2_ioread;
+
+struct pvr2_ioread *pvr2_ioread_create(void);
+void pvr2_ioread_destroy(struct pvr2_ioread *);
+int pvr2_ioread_setup(struct pvr2_ioread *,struct pvr2_stream *);
+struct pvr2_stream *pvr2_ioread_get_stream(struct pvr2_ioread *);
+void pvr2_ioread_set_sync_key(struct pvr2_ioread *,
+			      const char *sync_key_ptr,
+			      unsigned int sync_key_len);
+int pvr2_ioread_set_enabled(struct pvr2_ioread *,int fl);
+int pvr2_ioread_read(struct pvr2_ioread *,void __user *buf,unsigned int cnt);
+int pvr2_ioread_avail(struct pvr2_ioread *);
+
+#endif /* __PVRUSB2_IOREAD_H */
+
+/*
+  Stuff for Emacs to see, in order to encourage consistent editing style:
+  *** Local Variables: ***
+  *** mode: c ***
+  *** fill-column: 75 ***
+  *** tab-width: 8 ***
+  *** c-basic-offset: 8 ***
+  *** End: ***
+  */
diff --git a/drivers/media/video/pvrusb2/pvrusb2-main.c b/drivers/media/video/pvrusb2/pvrusb2-main.c
new file mode 100644
index 000000000..e976c484c
--- /dev/null
+++ b/drivers/media/video/pvrusb2/pvrusb2-main.c
@@ -0,0 +1,171 @@
+/*
+ *
+ *  $Id$
+ *
+ *  Copyright (C) 2005 Mike Isely <isely@pobox.com>
+ *  Copyright (C) 2004 Aurelien Alleaume <slts@free.fr>
+ *
+ *  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
+ *
+ *  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/errno.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/smp_lock.h>
+#include <linux/usb.h>
+#include <linux/videodev2.h>
+
+#include "pvrusb2-hdw.h"
+#include "pvrusb2-context.h"
+#include "pvrusb2-debug.h"
+#include "pvrusb2-v4l2.h"
+#ifdef CONFIG_VIDEO_PVRUSB2_SYSFS
+#include "pvrusb2-sysfs.h"
+#endif /* CONFIG_VIDEO_PVRUSB2_SYSFS */
+
+#define DRIVER_AUTHOR "Mike Isely <isely@pobox.com>"
+#define DRIVER_DESC "Hauppauge WinTV-PVR-USB2 MPEG2 Encoder/Tuner"
+#define DRIVER_VERSION "V4L in-tree version"
+
+#define DEFAULT_DEBUG_MASK (PVR2_TRACE_ERROR_LEGS| \
+			    PVR2_TRACE_INFO| \
+			    PVR2_TRACE_TOLERANCE| \
+			    PVR2_TRACE_TRAP| \
+			    0)
+
+int pvrusb2_debug = DEFAULT_DEBUG_MASK;
+
+module_param_named(debug,pvrusb2_debug,int,S_IRUGO|S_IWUSR);
+MODULE_PARM_DESC(debug, "Debug trace mask");
+
+#ifdef CONFIG_VIDEO_PVRUSB2_SYSFS
+static struct pvr2_sysfs_class *class_ptr = NULL;
+#endif /* CONFIG_VIDEO_PVRUSB2_SYSFS */
+
+static void pvr_setup_attach(struct pvr2_context *pvr)
+{
+	/* Create association with v4l layer */
+	pvr2_v4l2_create(pvr);
+#ifdef CONFIG_VIDEO_PVRUSB2_SYSFS
+	pvr2_sysfs_create(pvr,class_ptr);
+#endif /* CONFIG_VIDEO_PVRUSB2_SYSFS */
+}
+
+static int pvr_probe(struct usb_interface *intf,
+		     const struct usb_device_id *devid)
+{
+	struct pvr2_context *pvr;
+
+	/* Create underlying hardware interface */
+	pvr = pvr2_context_create(intf,devid,pvr_setup_attach);
+	if (!pvr) {
+		pvr2_trace(PVR2_TRACE_ERROR_LEGS,
+			   "Failed to create hdw handler");
+		return -ENOMEM;
+	}
+
+	pvr2_trace(PVR2_TRACE_INIT,"pvr_probe(pvr=%p)",pvr);
+
+	usb_set_intfdata(intf, pvr);
+
+	return 0;
+}
+
+/*
+ * pvr_disconnect()
+ *
+ */
+static void pvr_disconnect(struct usb_interface *intf)
+{
+	struct pvr2_context *pvr = usb_get_intfdata(intf);
+
+	pvr2_trace(PVR2_TRACE_INIT,"pvr_disconnect(pvr=%p) BEGIN",pvr);
+
+	usb_set_intfdata (intf, NULL);
+	pvr2_context_disconnect(pvr);
+
+	pvr2_trace(PVR2_TRACE_INIT,"pvr_disconnect(pvr=%p) DONE",pvr);
+
+}
+
+static struct usb_driver pvr_driver = {
+	.name =         "pvrusb2",
+	.id_table =     pvr2_device_table,
+	.probe =        pvr_probe,
+	.disconnect =   pvr_disconnect
+};
+
+/*
+ * pvr_init() / pvr_exit()
+ *
+ * This code is run to initialize/exit the driver.
+ *
+ */
+static int __init pvr_init(void)
+{
+	int ret;
+
+	pvr2_trace(PVR2_TRACE_INIT,"pvr_init");
+
+#ifdef CONFIG_VIDEO_PVRUSB2_SYSFS
+	class_ptr = pvr2_sysfs_class_create();
+#endif /* CONFIG_VIDEO_PVRUSB2_SYSFS */
+
+	ret = usb_register(&pvr_driver);
+
+	if (ret == 0)
+		info(DRIVER_DESC " : " DRIVER_VERSION);
+	if (pvrusb2_debug) info("Debug mask is %d (0x%x)",
+				pvrusb2_debug,pvrusb2_debug);
+
+	return ret;
+}
+
+static void __exit pvr_exit(void)
+{
+
+	pvr2_trace(PVR2_TRACE_INIT,"pvr_exit");
+
+#ifdef CONFIG_VIDEO_PVRUSB2_SYSFS
+	pvr2_sysfs_class_destroy(class_ptr);
+#endif /* CONFIG_VIDEO_PVRUSB2_SYSFS */
+
+	usb_deregister(&pvr_driver);
+}
+
+module_init(pvr_init);
+module_exit(pvr_exit);
+
+/* Mike Isely <mcisely@pobox.com> 11-Mar-2006: See pvrusb2-hdw.c for
+   MODULE_DEVICE_TABLE().  We have to declare that attribute there
+   because that's where the device table actually is now and it seems
+   that certain gcc configurations get angry if MODULE_DEVICE_TABLE()
+   is used on what ends up being an external symbol. */
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE("GPL");
+
+
+/*
+  Stuff for Emacs to see, in order to encourage consistent editing style:
+  *** Local Variables: ***
+  *** mode: c ***
+  *** fill-column: 70 ***
+  *** tab-width: 8 ***
+  *** c-basic-offset: 8 ***
+  *** End: ***
+  */
diff --git a/drivers/media/video/pvrusb2/pvrusb2-std.c b/drivers/media/video/pvrusb2/pvrusb2-std.c
new file mode 100644
index 000000000..f95c598ff
--- /dev/null
+++ b/drivers/media/video/pvrusb2/pvrusb2-std.c
@@ -0,0 +1,408 @@
+/*
+ *
+ *  $Id$
+ *
+ *  Copyright (C) 2005 Mike Isely <isely@pobox.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
+ *
+ *  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 "pvrusb2-std.h"
+#include "pvrusb2-debug.h"
+#include <asm/string.h>
+#include <linux/slab.h>
+
+struct std_name {
+	const char *name;
+	v4l2_std_id id;
+};
+
+
+#define CSTD_PAL \
+	(V4L2_STD_PAL_B| \
+	 V4L2_STD_PAL_B1| \
+	 V4L2_STD_PAL_G| \
+	 V4L2_STD_PAL_H| \
+	 V4L2_STD_PAL_I| \
+	 V4L2_STD_PAL_D| \
+	 V4L2_STD_PAL_D1| \
+	 V4L2_STD_PAL_K| \
+	 V4L2_STD_PAL_M| \
+	 V4L2_STD_PAL_N| \
+	 V4L2_STD_PAL_Nc| \
+	 V4L2_STD_PAL_60)
+
+#define CSTD_NTSC \
+	(V4L2_STD_NTSC_M| \
+	 V4L2_STD_NTSC_M_JP| \
+	 V4L2_STD_NTSC_M_KR| \
+	 V4L2_STD_NTSC_443)
+
+#define CSTD_SECAM \
+	(V4L2_STD_SECAM_B| \
+	 V4L2_STD_SECAM_D| \
+	 V4L2_STD_SECAM_G| \
+	 V4L2_STD_SECAM_H| \
+	 V4L2_STD_SECAM_K| \
+	 V4L2_STD_SECAM_K1| \
+	 V4L2_STD_SECAM_L| \
+	 V4L2_STD_SECAM_LC)
+
+#define TSTD_B   (V4L2_STD_PAL_B|V4L2_STD_SECAM_B)
+#define TSTD_B1  (V4L2_STD_PAL_B1)
+#define TSTD_D   (V4L2_STD_PAL_D|V4L2_STD_SECAM_D)
+#define TSTD_D1  (V4L2_STD_PAL_D1)
+#define TSTD_G   (V4L2_STD_PAL_G|V4L2_STD_SECAM_G)
+#define TSTD_H   (V4L2_STD_PAL_H|V4L2_STD_SECAM_H)
+#define TSTD_I   (V4L2_STD_PAL_I)
+#define TSTD_K   (V4L2_STD_PAL_K|V4L2_STD_SECAM_K)
+#define TSTD_K1  (V4L2_STD_SECAM_K1)
+#define TSTD_L   (V4L2_STD_SECAM_L)
+#define TSTD_M   (V4L2_STD_PAL_M|V4L2_STD_NTSC_M)
+#define TSTD_N   (V4L2_STD_PAL_N)
+#define TSTD_Nc  (V4L2_STD_PAL_Nc)
+#define TSTD_60  (V4L2_STD_PAL_60)
+
+#define CSTD_ALL (CSTD_PAL|CSTD_NTSC|CSTD_SECAM)
+
+/* Mapping of standard bits to color system */
+const static 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[] = {
+	{"B",TSTD_B},
+	{"B1",TSTD_B1},
+	{"D",TSTD_D},
+	{"D1",TSTD_D1},
+	{"G",TSTD_G},
+	{"H",TSTD_H},
+	{"I",TSTD_I},
+	{"K",TSTD_K},
+	{"K1",TSTD_K1},
+	{"L",TSTD_L},
+	{"LC",V4L2_STD_SECAM_LC},
+	{"M",TSTD_M},
+	{"Mj",V4L2_STD_NTSC_M_JP},
+	{"443",V4L2_STD_NTSC_443},
+	{"Mk",V4L2_STD_NTSC_M_KR},
+	{"N",TSTD_N},
+	{"Nc",TSTD_Nc},
+	{"60",TSTD_60},
+};
+
+
+// Search an array of std_name structures and return a pointer to the
+// element with the matching name.
+static const struct std_name *find_std_name(const struct std_name *arrPtr,
+					    unsigned int arrSize,
+					    const char *bufPtr,
+					    unsigned int bufSize)
+{
+	unsigned int idx;
+	const struct std_name *p;
+	for (idx = 0; idx < arrSize; idx++) {
+		p = arrPtr + idx;
+		if (strlen(p->name) != bufSize) continue;
+		if (!memcmp(bufPtr,p->name,bufSize)) return p;
+	}
+	return NULL;
+}
+
+
+int pvr2_std_str_to_id(v4l2_std_id *idPtr,const char *bufPtr,
+		       unsigned int bufSize)
+{
+	v4l2_std_id id = 0;
+	v4l2_std_id cmsk = 0;
+	v4l2_std_id t;
+	int mMode = 0;
+	unsigned int cnt;
+	char ch;
+	const struct std_name *sp;
+
+	while (bufSize) {
+		if (!mMode) {
+			cnt = 0;
+			while ((cnt < bufSize) && (bufPtr[cnt] != '-')) cnt++;
+			if (cnt >= bufSize) return 0; // No more characters
+			sp = find_std_name(
+				std_groups,
+				sizeof(std_groups)/sizeof(std_groups[0]),
+				bufPtr,cnt);
+			if (!sp) return 0; // Illegal color system name
+			cnt++;
+			bufPtr += cnt;
+			bufSize -= cnt;
+			mMode = !0;
+			cmsk = sp->id;
+			continue;
+		}
+		cnt = 0;
+		while (cnt < bufSize) {
+			ch = bufPtr[cnt];
+			if (ch == ';') {
+				mMode = 0;
+				break;
+			}
+			if (ch == '/') break;
+			cnt++;
+		}
+		sp = find_std_name(std_items,
+				   sizeof(std_items)/sizeof(std_items[0]),
+				   bufPtr,cnt);
+		if (!sp) return 0; // Illegal modulation system ID
+		t = sp->id & cmsk;
+		if (!t) return 0; // Specific color + modulation system illegal
+		id |= t;
+		if (cnt < bufSize) cnt++;
+		bufPtr += cnt;
+		bufSize -= cnt;
+	}
+
+	if (idPtr) *idPtr = id;
+	return !0;
+}
+
+
+unsigned int pvr2_std_id_to_str(char *bufPtr, unsigned int bufSize,
+				v4l2_std_id id)
+{
+	unsigned int idx1,idx2;
+	const struct std_name *ip,*gp;
+	int gfl,cfl;
+	unsigned int c1,c2;
+	cfl = 0;
+	c1 = 0;
+	for (idx1 = 0;
+	     idx1 < sizeof(std_groups)/sizeof(std_groups[0]);
+	     idx1++) {
+		gp = std_groups + idx1;
+		gfl = 0;
+		for (idx2 = 0;
+		     idx2 < sizeof(std_items)/sizeof(std_items[0]);
+		     idx2++) {
+			ip = std_items + idx2;
+			if (!(gp->id & ip->id & id)) continue;
+			if (!gfl) {
+				if (cfl) {
+					c2 = scnprintf(bufPtr,bufSize,";");
+					c1 += c2;
+					bufSize -= c2;
+					bufPtr += c2;
+				}
+				cfl = !0;
+				c2 = scnprintf(bufPtr,bufSize,
+					       "%s-",gp->name);
+				gfl = !0;
+			} else {
+				c2 = scnprintf(bufPtr,bufSize,"/");
+			}
+			c1 += c2;
+			bufSize -= c2;
+			bufPtr += c2;
+			c2 = scnprintf(bufPtr,bufSize,
+				       ip->name);
+			c1 += c2;
+			bufSize -= c2;
+			bufPtr += c2;
+		}
+	}
+	return c1;
+}
+
+
+// Template data for possible enumerated video standards.  Here we group
+// standards which share common frame rates and resolution.
+static struct v4l2_standard generic_standards[] = {
+	{
+		.id             = (TSTD_B|TSTD_B1|
+				   TSTD_D|TSTD_D1|
+				   TSTD_G|
+				   TSTD_H|
+				   TSTD_I|
+				   TSTD_K|TSTD_K1|
+				   TSTD_L|
+				   V4L2_STD_SECAM_LC |
+				   TSTD_N|TSTD_Nc),
+		.frameperiod    =
+		{
+			.numerator  = 1,
+			.denominator= 25
+		},
+		.framelines     = 625,
+		.reserved       = {0,0,0,0}
+	}, {
+		.id             = (TSTD_M|
+				   V4L2_STD_NTSC_M_JP|
+				   V4L2_STD_NTSC_M_KR),
+		.frameperiod    =
+		{
+			.numerator  = 1001,
+			.denominator= 30000
+		},
+		.framelines     = 525,
+		.reserved       = {0,0,0,0}
+	}, { // This is a total wild guess
+		.id             = (TSTD_60),
+		.frameperiod    =
+		{
+			.numerator  = 1001,
+			.denominator= 30000
+		},
+		.framelines     = 525,
+		.reserved       = {0,0,0,0}
+	}, { // This is total wild guess
+		.id             = V4L2_STD_NTSC_443,
+		.frameperiod    =
+		{
+			.numerator  = 1001,
+			.denominator= 30000
+		},
+		.framelines     = 525,
+		.reserved       = {0,0,0,0}
+	}
+};
+
+#define generic_standards_cnt (sizeof(generic_standards)/sizeof(generic_standards[0]))
+
+static struct v4l2_standard *match_std(v4l2_std_id id)
+{
+	unsigned int idx;
+	for (idx = 0; idx < generic_standards_cnt; idx++) {
+		if (generic_standards[idx].id & id) {
+			return generic_standards + idx;
+		}
+	}
+	return NULL;
+}
+
+static int pvr2_std_fill(struct v4l2_standard *std,v4l2_std_id id)
+{
+	struct v4l2_standard *template;
+	int idx;
+	unsigned int bcnt;
+	template = match_std(id);
+	if (!template) return 0;
+	idx = std->index;
+	memcpy(std,template,sizeof(*template));
+	std->index = idx;
+	std->id = id;
+	bcnt = pvr2_std_id_to_str(std->name,sizeof(std->name)-1,id);
+	std->name[bcnt] = 0;
+	pvr2_trace(PVR2_TRACE_INIT,"Set up standard idx=%u name=%s",
+		   std->index,std->name);
+	return !0;
+}
+
+/* These are special cases of combined standards that we should enumerate
+   separately if the component pieces are present. */
+static v4l2_std_id std_mixes[] = {
+	V4L2_STD_PAL_B | V4L2_STD_PAL_G,
+	V4L2_STD_PAL_D | V4L2_STD_PAL_K,
+	V4L2_STD_SECAM_B | V4L2_STD_SECAM_G,
+	V4L2_STD_SECAM_D | V4L2_STD_SECAM_K,
+};
+
+struct v4l2_standard *pvr2_std_create_enum(unsigned int *countptr,
+					   v4l2_std_id id)
+{
+	unsigned int std_cnt = 0;
+	unsigned int idx,bcnt,idx2;
+	v4l2_std_id idmsk,cmsk,fmsk;
+	struct v4l2_standard *stddefs;
+
+	if (pvrusb2_debug & PVR2_TRACE_INIT) {
+		char buf[50];
+		bcnt = pvr2_std_id_to_str(buf,sizeof(buf),id);
+		pvr2_trace(
+			PVR2_TRACE_INIT,"Mapping standards mask=0x%x (%.*s)",
+			(int)id,bcnt,buf);
+	}
+
+	*countptr = 0;
+	std_cnt = 0;
+	fmsk = 0;
+	for (idmsk = 1, cmsk = id; cmsk; idmsk <<= 1) {
+		if (!(idmsk & cmsk)) continue;
+		cmsk &= ~idmsk;
+		if (match_std(idmsk)) {
+			std_cnt++;
+			continue;
+		}
+		fmsk |= idmsk;
+	}
+
+	for (idx2 = 0; idx2 < sizeof(std_mixes)/sizeof(std_mixes[0]); idx2++) {
+		if ((id & std_mixes[idx2]) == std_mixes[idx2]) std_cnt++;
+	}
+
+	if (fmsk) {
+		char buf[50];
+		bcnt = pvr2_std_id_to_str(buf,sizeof(buf),fmsk);
+		pvr2_trace(
+			PVR2_TRACE_ERROR_LEGS,
+			"WARNING:"
+			" Failed to classify the following standard(s): %.*s",
+			bcnt,buf);
+	}
+
+	pvr2_trace(PVR2_TRACE_INIT,"Setting up %u unique standard(s)",
+		   std_cnt);
+	if (!std_cnt) return NULL; // paranoia
+
+	stddefs = kmalloc(sizeof(struct v4l2_standard) * std_cnt,
+			  GFP_KERNEL);
+	memset(stddefs,0,sizeof(struct v4l2_standard) * std_cnt);
+	for (idx = 0; idx < std_cnt; idx++) stddefs[idx].index = idx;
+
+	idx = 0;
+
+	/* Enumerate potential special cases */
+	for (idx2 = 0; ((idx2 < sizeof(std_mixes)/sizeof(std_mixes[0])) &&
+			(idx < std_cnt)); idx2++) {
+		if (!(id & std_mixes[idx2])) continue;
+		if (pvr2_std_fill(stddefs+idx,std_mixes[idx2])) idx++;
+	}
+	/* Now enumerate individual pieces */
+	for (idmsk = 1, cmsk = id; cmsk && (idx < std_cnt); idmsk <<= 1) {
+		if (!(idmsk & cmsk)) continue;
+		cmsk &= ~idmsk;
+		if (!pvr2_std_fill(stddefs+idx,idmsk)) continue;
+		idx++;
+	}
+
+	*countptr = std_cnt;
+	return stddefs;
+}
+
+v4l2_std_id pvr2_std_get_usable(void)
+{
+	return CSTD_ALL;
+}
+
+
+/*
+  Stuff for Emacs to see, in order to encourage consistent editing style:
+  *** Local Variables: ***
+  *** mode: c ***
+  *** fill-column: 75 ***
+  *** tab-width: 8 ***
+  *** c-basic-offset: 8 ***
+  *** End: ***
+  */
diff --git a/drivers/media/video/pvrusb2/pvrusb2-std.h b/drivers/media/video/pvrusb2/pvrusb2-std.h
new file mode 100644
index 000000000..07c399375
--- /dev/null
+++ b/drivers/media/video/pvrusb2/pvrusb2-std.h
@@ -0,0 +1,60 @@
+/*
+ *
+ *  $Id$
+ *
+ *  Copyright (C) 2005 Mike Isely <isely@pobox.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
+ *
+ *  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 __PVRUSB2_STD_H
+#define __PVRUSB2_STD_H
+
+#include <linux/videodev2.h>
+
+// Convert string describing one or more video standards into a mask of V4L
+// standard bits.  Return true if conversion succeeds otherwise return
+// false.  String is expected to be of the form: C1-x/y;C2-a/b where C1 and
+// C2 are color system names (e.g. "PAL", "NTSC") and x, y, a, and b are
+// modulation schemes (e.g. "M", "B", "G", etc).
+int pvr2_std_str_to_id(v4l2_std_id *idPtr,const char *bufPtr,
+		       unsigned int bufSize);
+
+// Convert any arbitrary set of video standard bits into an unambiguous
+// readable string.  Return value is the number of bytes consumed in the
+// buffer.  The formatted string is of a form that can be parsed by our
+// sibling std_std_to_id() function.
+unsigned int pvr2_std_id_to_str(char *bufPtr, unsigned int bufSize,
+				v4l2_std_id id);
+
+// Create an array of suitable v4l2_standard structures given a bit mask of
+// video standards to support.  The array is allocated from the heap, and
+// the number of elements is returned in the first argument.
+struct v4l2_standard *pvr2_std_create_enum(unsigned int *countptr,
+					   v4l2_std_id id);
+
+// Return mask of which video standard bits are valid
+v4l2_std_id pvr2_std_get_usable(void);
+
+#endif /* __PVRUSB2_STD_H */
+
+/*
+  Stuff for Emacs to see, in order to encourage consistent editing style:
+  *** Local Variables: ***
+  *** mode: c ***
+  *** fill-column: 75 ***
+  *** tab-width: 8 ***
+  *** c-basic-offset: 8 ***
+  *** End: ***
+  */
diff --git a/drivers/media/video/pvrusb2/pvrusb2-sysfs.c b/drivers/media/video/pvrusb2/pvrusb2-sysfs.c
new file mode 100644
index 000000000..38e9222dc
--- /dev/null
+++ b/drivers/media/video/pvrusb2/pvrusb2-sysfs.c
@@ -0,0 +1,925 @@
+/*
+ *
+ *  $Id$
+ *
+ *  Copyright (C) 2005 Mike Isely <isely@pobox.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
+ *
+ *  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/string.h>
+#include <linux/slab.h>
+#include <asm/semaphore.h>
+#include "pvrusb2-sysfs.h"
+#include "pvrusb2-hdw.h"
+#include "pvrusb2-debug.h"
+#ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC
+#include "pvrusb2-debugifc.h"
+#endif /* CONFIG_VIDEO_PVRUSB2_DEBUGIFC */
+
+#define pvr2_sysfs_trace(...) pvr2_trace(PVR2_TRACE_SYSFS,__VA_ARGS__)
+
+struct pvr2_sysfs {
+	struct pvr2_channel channel;
+	struct class_device *class_dev;
+#ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC
+	struct pvr2_sysfs_debugifc *debugifc;
+#endif /* CONFIG_VIDEO_PVRUSB2_DEBUGIFC */
+	struct pvr2_sysfs_ctl_item *item_first;
+	struct pvr2_sysfs_ctl_item *item_last;
+	struct sysfs_ops kops;
+	struct kobj_type ktype;
+	struct class_device_attribute attr_v4l_minor_number;
+	struct class_device_attribute attr_unit_number;
+	int v4l_minor_number_created_ok;
+	int unit_number_created_ok;
+};
+
+#ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC
+struct pvr2_sysfs_debugifc {
+	struct class_device_attribute attr_debugcmd;
+	struct class_device_attribute attr_debuginfo;
+	int debugcmd_created_ok;
+	int debuginfo_created_ok;
+};
+#endif /* CONFIG_VIDEO_PVRUSB2_DEBUGIFC */
+
+struct pvr2_sysfs_ctl_item {
+	struct class_device_attribute attr_name;
+	struct class_device_attribute attr_type;
+	struct class_device_attribute attr_min;
+	struct class_device_attribute attr_max;
+	struct class_device_attribute attr_enum;
+	struct class_device_attribute attr_bits;
+	struct class_device_attribute attr_val;
+	struct class_device_attribute attr_custom;
+	struct pvr2_ctrl *cptr;
+	struct pvr2_sysfs *chptr;
+	struct pvr2_sysfs_ctl_item *item_next;
+	struct attribute *attr_gen[7];
+	struct attribute_group grp;
+	int created_ok;
+	char name[80];
+};
+
+struct pvr2_sysfs_class {
+	struct class class;
+};
+
+static ssize_t show_name(int id,struct class_device *class_dev,char *buf)
+{
+	struct pvr2_ctrl *cptr;
+	struct pvr2_sysfs *sfp;
+	const char *name;
+
+	sfp = (struct pvr2_sysfs *)class_dev->class_data;
+	if (!sfp) return -EINVAL;
+	cptr = pvr2_hdw_get_ctrl_by_index(sfp->channel.hdw,id);
+	if (!cptr) return -EINVAL;
+
+	name = pvr2_ctrl_get_desc(cptr);
+	pvr2_sysfs_trace("pvr2_sysfs(%p) show_name(cid=%d) is %s",sfp,id,name);
+
+	if (!name) return -EINVAL;
+
+	return scnprintf(buf,PAGE_SIZE,"%s\n",name);
+}
+
+static ssize_t show_type(int id,struct class_device *class_dev,char *buf)
+{
+	struct pvr2_ctrl *cptr;
+	struct pvr2_sysfs *sfp;
+	const char *name;
+	enum pvr2_ctl_type tp;
+
+	sfp = (struct pvr2_sysfs *)class_dev->class_data;
+	if (!sfp) return -EINVAL;
+	cptr = pvr2_hdw_get_ctrl_by_index(sfp->channel.hdw,id);
+	if (!cptr) return -EINVAL;
+
+	tp = pvr2_ctrl_get_type(cptr);
+	switch (tp) {
+	case pvr2_ctl_int: name = "integer"; break;
+	case pvr2_ctl_enum: name = "enum"; break;
+	case pvr2_ctl_bitmask: name = "bitmask"; break;
+	case pvr2_ctl_bool: name = "boolean"; break;
+	default: name = "?"; break;
+	}
+	pvr2_sysfs_trace("pvr2_sysfs(%p) show_type(cid=%d) is %s",sfp,id,name);
+
+	if (!name) return -EINVAL;
+
+	return scnprintf(buf,PAGE_SIZE,"%s\n",name);
+}
+
+static ssize_t show_min(int id,struct class_device *class_dev,char *buf)
+{
+	struct pvr2_ctrl *cptr;
+	struct pvr2_sysfs *sfp;
+	long val;
+
+	sfp = (struct pvr2_sysfs *)class_dev->class_data;
+	if (!sfp) return -EINVAL;
+	cptr = pvr2_hdw_get_ctrl_by_index(sfp->channel.hdw,id);
+	if (!cptr) return -EINVAL;
+	val = pvr2_ctrl_get_min(cptr);
+
+	pvr2_sysfs_trace("pvr2_sysfs(%p) show_min(cid=%d) is %ld",sfp,id,val);
+
+	return scnprintf(buf,PAGE_SIZE,"%ld\n",val);
+}
+
+static ssize_t show_max(int id,struct class_device *class_dev,char *buf)
+{
+	struct pvr2_ctrl *cptr;
+	struct pvr2_sysfs *sfp;
+	long val;
+
+	sfp = (struct pvr2_sysfs *)class_dev->class_data;
+	if (!sfp) return -EINVAL;
+	cptr = pvr2_hdw_get_ctrl_by_index(sfp->channel.hdw,id);
+	if (!cptr) return -EINVAL;
+	val = pvr2_ctrl_get_max(cptr);
+
+	pvr2_sysfs_trace("pvr2_sysfs(%p) show_max(cid=%d) is %ld",sfp,id,val);
+
+	return scnprintf(buf,PAGE_SIZE,"%ld\n",val);
+}
+
+static ssize_t show_val_norm(int id,struct class_device *class_dev,char *buf)
+{
+	struct pvr2_ctrl *cptr;
+	struct pvr2_sysfs *sfp;
+	int val,ret;
+	unsigned int cnt = 0;
+
+	sfp = (struct pvr2_sysfs *)class_dev->class_data;
+	if (!sfp) return -EINVAL;
+	cptr = pvr2_hdw_get_ctrl_by_index(sfp->channel.hdw,id);
+	if (!cptr) return -EINVAL;
+
+	ret = pvr2_ctrl_get_value(cptr,&val);
+	if (ret < 0) return ret;
+
+	ret = pvr2_ctrl_value_to_sym(cptr,~0,val,
+				     buf,PAGE_SIZE-1,&cnt);
+
+	pvr2_sysfs_trace("pvr2_sysfs(%p) show_val_norm(cid=%d) is %.*s (%d)",
+			 sfp,id,cnt,buf,val);
+	buf[cnt] = '\n';
+	return cnt+1;
+}
+
+static ssize_t show_val_custom(int id,struct class_device *class_dev,char *buf)
+{
+	struct pvr2_ctrl *cptr;
+	struct pvr2_sysfs *sfp;
+	int val,ret;
+	unsigned int cnt = 0;
+
+	sfp = (struct pvr2_sysfs *)class_dev->class_data;
+	if (!sfp) return -EINVAL;
+	cptr = pvr2_hdw_get_ctrl_by_index(sfp->channel.hdw,id);
+	if (!cptr) return -EINVAL;
+
+	ret = pvr2_ctrl_get_value(cptr,&val);
+	if (ret < 0) return ret;
+
+	ret = pvr2_ctrl_custom_value_to_sym(cptr,~0,val,
+					    buf,PAGE_SIZE-1,&cnt);
+
+	pvr2_sysfs_trace("pvr2_sysfs(%p) show_val_custom(cid=%d) is %.*s (%d)",
+			 sfp,id,cnt,buf,val);
+	buf[cnt] = '\n';
+	return cnt+1;
+}
+
+static ssize_t show_enum(int id,struct class_device *class_dev,char *buf)
+{
+	struct pvr2_ctrl *cptr;
+	struct pvr2_sysfs *sfp;
+	long val;
+	unsigned int bcnt,ccnt,ecnt;
+
+	sfp = (struct pvr2_sysfs *)class_dev->class_data;
+	if (!sfp) return -EINVAL;
+	cptr = pvr2_hdw_get_ctrl_by_index(sfp->channel.hdw,id);
+	if (!cptr) return -EINVAL;
+	ecnt = pvr2_ctrl_get_cnt(cptr);
+	bcnt = 0;
+	for (val = 0; val < ecnt; val++) {
+		pvr2_ctrl_get_valname(cptr,val,buf+bcnt,PAGE_SIZE-bcnt,&ccnt);
+		if (!ccnt) continue;
+		bcnt += ccnt;
+		if (bcnt >= PAGE_SIZE) break;
+		buf[bcnt] = '\n';
+		bcnt++;
+	}
+	pvr2_sysfs_trace("pvr2_sysfs(%p) show_enum(cid=%d)",sfp,id);
+	return bcnt;
+}
+
+static ssize_t show_bits(int id,struct class_device *class_dev,char *buf)
+{
+	struct pvr2_ctrl *cptr;
+	struct pvr2_sysfs *sfp;
+	int valid_bits,msk;
+	unsigned int bcnt,ccnt;
+
+	sfp = (struct pvr2_sysfs *)class_dev->class_data;
+	if (!sfp) return -EINVAL;
+	cptr = pvr2_hdw_get_ctrl_by_index(sfp->channel.hdw,id);
+	if (!cptr) return -EINVAL;
+	valid_bits = pvr2_ctrl_get_mask(cptr);
+	bcnt = 0;
+	for (msk = 1; valid_bits; msk <<= 1) {
+		if (!(msk & valid_bits)) continue;
+		valid_bits &= ~msk;
+		pvr2_ctrl_get_valname(cptr,msk,buf+bcnt,PAGE_SIZE-bcnt,&ccnt);
+		bcnt += ccnt;
+		if (bcnt >= PAGE_SIZE) break;
+		buf[bcnt] = '\n';
+		bcnt++;
+	}
+	pvr2_sysfs_trace("pvr2_sysfs(%p) show_bits(cid=%d)",sfp,id);
+	return bcnt;
+}
+
+static int store_val_any(int id,int customfl,struct pvr2_sysfs *sfp,
+			 const char *buf,unsigned int count)
+{
+	struct pvr2_ctrl *cptr;
+	int ret;
+	int mask,val;
+
+	cptr = pvr2_hdw_get_ctrl_by_index(sfp->channel.hdw,id);
+	if (customfl) {
+		ret = pvr2_ctrl_custom_sym_to_value(cptr,buf,count,&mask,&val);
+	} else {
+		ret = pvr2_ctrl_sym_to_value(cptr,buf,count,&mask,&val);
+	}
+	if (ret < 0) return ret;
+	ret = pvr2_ctrl_set_mask_value(cptr,mask,val);
+	pvr2_hdw_commit_ctl(sfp->channel.hdw);
+	return ret;
+}
+
+static ssize_t store_val_norm(int id,struct class_device *class_dev,
+			     const char *buf,size_t count)
+{
+	struct pvr2_sysfs *sfp;
+	int ret;
+	sfp = (struct pvr2_sysfs *)class_dev->class_data;
+	ret = store_val_any(id,0,sfp,buf,count);
+	if (!ret) ret = count;
+	return ret;
+}
+
+static ssize_t store_val_custom(int id,struct class_device *class_dev,
+				const char *buf,size_t count)
+{
+	struct pvr2_sysfs *sfp;
+	int ret;
+	sfp = (struct pvr2_sysfs *)class_dev->class_data;
+	ret = store_val_any(id,1,sfp,buf,count);
+	if (!ret) ret = count;
+	return ret;
+}
+
+/*
+  Mike Isely <isely@pobox.com> 30-April-2005
+
+  This next batch of horrible preprocessor hackery is needed because the
+  kernel's class_device_attribute mechanism fails to pass the actual
+  attribute through to the show / store functions, which means we have no
+  way to package up any attribute-specific parameters, like for example the
+  control id.  So we work around this brain-damage by encoding the control
+  id into the show / store functions themselves and pick the function based
+  on the control id we're setting up.  These macros try to ease the pain.
+  Yuck.
+*/
+
+#define CREATE_SHOW_INSTANCE(sf_name,ctl_id) \
+static ssize_t sf_name##_##ctl_id(struct class_device *class_dev,char *buf) \
+{ return sf_name(ctl_id,class_dev,buf); }
+
+#define CREATE_STORE_INSTANCE(sf_name,ctl_id) \
+static ssize_t sf_name##_##ctl_id(struct class_device *class_dev,const char *buf,size_t count) \
+{ return sf_name(ctl_id,class_dev,buf,count); }
+
+#define CREATE_BATCH(ctl_id) \
+CREATE_SHOW_INSTANCE(show_name,ctl_id) \
+CREATE_SHOW_INSTANCE(show_type,ctl_id) \
+CREATE_SHOW_INSTANCE(show_min,ctl_id) \
+CREATE_SHOW_INSTANCE(show_max,ctl_id) \
+CREATE_SHOW_INSTANCE(show_val_norm,ctl_id) \
+CREATE_SHOW_INSTANCE(show_val_custom,ctl_id) \
+CREATE_SHOW_INSTANCE(show_enum,ctl_id) \
+CREATE_SHOW_INSTANCE(show_bits,ctl_id) \
+CREATE_STORE_INSTANCE(store_val_norm,ctl_id) \
+CREATE_STORE_INSTANCE(store_val_custom,ctl_id) \
+
+CREATE_BATCH(0)
+CREATE_BATCH(1)
+CREATE_BATCH(2)
+CREATE_BATCH(3)
+CREATE_BATCH(4)
+CREATE_BATCH(5)
+CREATE_BATCH(6)
+CREATE_BATCH(7)
+CREATE_BATCH(8)
+CREATE_BATCH(9)
+CREATE_BATCH(10)
+CREATE_BATCH(11)
+CREATE_BATCH(12)
+CREATE_BATCH(13)
+CREATE_BATCH(14)
+CREATE_BATCH(15)
+CREATE_BATCH(16)
+CREATE_BATCH(17)
+CREATE_BATCH(18)
+CREATE_BATCH(19)
+CREATE_BATCH(20)
+CREATE_BATCH(21)
+CREATE_BATCH(22)
+CREATE_BATCH(23)
+CREATE_BATCH(24)
+CREATE_BATCH(25)
+CREATE_BATCH(26)
+CREATE_BATCH(27)
+CREATE_BATCH(28)
+CREATE_BATCH(29)
+CREATE_BATCH(30)
+CREATE_BATCH(31)
+CREATE_BATCH(32)
+CREATE_BATCH(33)
+CREATE_BATCH(34)
+CREATE_BATCH(35)
+CREATE_BATCH(36)
+CREATE_BATCH(37)
+CREATE_BATCH(38)
+CREATE_BATCH(39)
+CREATE_BATCH(40)
+CREATE_BATCH(41)
+CREATE_BATCH(42)
+CREATE_BATCH(43)
+CREATE_BATCH(44)
+CREATE_BATCH(45)
+CREATE_BATCH(46)
+CREATE_BATCH(47)
+CREATE_BATCH(48)
+CREATE_BATCH(49)
+CREATE_BATCH(50)
+CREATE_BATCH(51)
+CREATE_BATCH(52)
+CREATE_BATCH(53)
+CREATE_BATCH(54)
+CREATE_BATCH(55)
+CREATE_BATCH(56)
+CREATE_BATCH(57)
+CREATE_BATCH(58)
+CREATE_BATCH(59)
+
+struct pvr2_sysfs_func_set {
+	ssize_t (*show_name)(struct class_device *,char *);
+	ssize_t (*show_type)(struct class_device *,char *);
+	ssize_t (*show_min)(struct class_device *,char *);
+	ssize_t (*show_max)(struct class_device *,char *);
+	ssize_t (*show_enum)(struct class_device *,char *);
+	ssize_t (*show_bits)(struct class_device *,char *);
+	ssize_t (*show_val_norm)(struct class_device *,char *);
+	ssize_t (*store_val_norm)(struct class_device *,
+				  const char *,size_t);
+	ssize_t (*show_val_custom)(struct class_device *,char *);
+	ssize_t (*store_val_custom)(struct class_device *,
+				    const char *,size_t);
+};
+
+#define INIT_BATCH(ctl_id) \
+[ctl_id] = { \
+    .show_name = show_name_##ctl_id, \
+    .show_type = show_type_##ctl_id, \
+    .show_min = show_min_##ctl_id, \
+    .show_max = show_max_##ctl_id, \
+    .show_enum = show_enum_##ctl_id, \
+    .show_bits = show_bits_##ctl_id, \
+    .show_val_norm = show_val_norm_##ctl_id, \
+    .store_val_norm = store_val_norm_##ctl_id, \
+    .show_val_custom = show_val_custom_##ctl_id, \
+    .store_val_custom = store_val_custom_##ctl_id, \
+} \
+
+static struct pvr2_sysfs_func_set funcs[] = {
+	INIT_BATCH(0),
+	INIT_BATCH(1),
+	INIT_BATCH(2),
+	INIT_BATCH(3),
+	INIT_BATCH(4),
+	INIT_BATCH(5),
+	INIT_BATCH(6),
+	INIT_BATCH(7),
+	INIT_BATCH(8),
+	INIT_BATCH(9),
+	INIT_BATCH(10),
+	INIT_BATCH(11),
+	INIT_BATCH(12),
+	INIT_BATCH(13),
+	INIT_BATCH(14),
+	INIT_BATCH(15),
+	INIT_BATCH(16),
+	INIT_BATCH(17),
+	INIT_BATCH(18),
+	INIT_BATCH(19),
+	INIT_BATCH(20),
+	INIT_BATCH(21),
+	INIT_BATCH(22),
+	INIT_BATCH(23),
+	INIT_BATCH(24),
+	INIT_BATCH(25),
+	INIT_BATCH(26),
+	INIT_BATCH(27),
+	INIT_BATCH(28),
+	INIT_BATCH(29),
+	INIT_BATCH(30),
+	INIT_BATCH(31),
+	INIT_BATCH(32),
+	INIT_BATCH(33),
+	INIT_BATCH(34),
+	INIT_BATCH(35),
+	INIT_BATCH(36),
+	INIT_BATCH(37),
+	INIT_BATCH(38),
+	INIT_BATCH(39),
+	INIT_BATCH(40),
+	INIT_BATCH(41),
+	INIT_BATCH(42),
+	INIT_BATCH(43),
+	INIT_BATCH(44),
+	INIT_BATCH(45),
+	INIT_BATCH(46),
+	INIT_BATCH(47),
+	INIT_BATCH(48),
+	INIT_BATCH(49),
+	INIT_BATCH(50),
+	INIT_BATCH(51),
+	INIT_BATCH(52),
+	INIT_BATCH(53),
+	INIT_BATCH(54),
+	INIT_BATCH(55),
+	INIT_BATCH(56),
+	INIT_BATCH(57),
+	INIT_BATCH(58),
+	INIT_BATCH(59),
+};
+
+
+static void pvr2_sysfs_add_control(struct pvr2_sysfs *sfp,int ctl_id)
+{
+	struct pvr2_sysfs_ctl_item *cip;
+	struct pvr2_sysfs_func_set *fp;
+	struct pvr2_ctrl *cptr;
+	unsigned int cnt,acnt;
+	int ret;
+
+	if ((ctl_id < 0) || (ctl_id >= (sizeof(funcs)/sizeof(funcs[0])))) {
+		return;
+	}
+
+	fp = funcs + ctl_id;
+	cptr = pvr2_hdw_get_ctrl_by_index(sfp->channel.hdw,ctl_id);
+	if (!cptr) return;
+
+	cip = kmalloc(sizeof(*cip),GFP_KERNEL);
+	if (!cip) return;
+	memset(cip,0,sizeof(*cip));
+	pvr2_sysfs_trace("Creating pvr2_sysfs_ctl_item id=%p",cip);
+
+	cip->cptr = cptr;
+
+	cip->chptr = sfp;
+	cip->item_next = NULL;
+	if (sfp->item_last) {
+		sfp->item_last->item_next = cip;
+	} else {
+		sfp->item_first = cip;
+	}
+	sfp->item_last = cip;
+
+	cip->attr_name.attr.owner = THIS_MODULE;
+	cip->attr_name.attr.name = "name";
+	cip->attr_name.attr.mode = S_IRUGO;
+	cip->attr_name.show = fp->show_name;
+
+	cip->attr_type.attr.owner = THIS_MODULE;
+	cip->attr_type.attr.name = "type";
+	cip->attr_type.attr.mode = S_IRUGO;
+	cip->attr_type.show = fp->show_type;
+
+	cip->attr_min.attr.owner = THIS_MODULE;
+	cip->attr_min.attr.name = "min_val";
+	cip->attr_min.attr.mode = S_IRUGO;
+	cip->attr_min.show = fp->show_min;
+
+	cip->attr_max.attr.owner = THIS_MODULE;
+	cip->attr_max.attr.name = "max_val";
+	cip->attr_max.attr.mode = S_IRUGO;
+	cip->attr_max.show = fp->show_max;
+
+	cip->attr_val.attr.owner = THIS_MODULE;
+	cip->attr_val.attr.name = "cur_val";
+	cip->attr_val.attr.mode = S_IRUGO;
+
+	cip->attr_custom.attr.owner = THIS_MODULE;
+	cip->attr_custom.attr.name = "custom_val";
+	cip->attr_custom.attr.mode = S_IRUGO;
+
+	cip->attr_enum.attr.owner = THIS_MODULE;
+	cip->attr_enum.attr.name = "enum_val";
+	cip->attr_enum.attr.mode = S_IRUGO;
+	cip->attr_enum.show = fp->show_enum;
+
+	cip->attr_bits.attr.owner = THIS_MODULE;
+	cip->attr_bits.attr.name = "bit_val";
+	cip->attr_bits.attr.mode = S_IRUGO;
+	cip->attr_bits.show = fp->show_bits;
+
+	if (pvr2_ctrl_is_writable(cptr)) {
+		cip->attr_val.attr.mode |= S_IWUSR|S_IWGRP;
+		cip->attr_custom.attr.mode |= S_IWUSR|S_IWGRP;
+	}
+
+	acnt = 0;
+	cip->attr_gen[acnt++] = &cip->attr_name.attr;
+	cip->attr_gen[acnt++] = &cip->attr_type.attr;
+	cip->attr_gen[acnt++] = &cip->attr_val.attr;
+	cip->attr_val.show = fp->show_val_norm;
+	cip->attr_val.store = fp->store_val_norm;
+	if (pvr2_ctrl_has_custom_symbols(cptr)) {
+		cip->attr_gen[acnt++] = &cip->attr_custom.attr;
+		cip->attr_custom.show = fp->show_val_custom;
+		cip->attr_custom.store = fp->store_val_custom;
+	}
+	switch (pvr2_ctrl_get_type(cptr)) {
+	case pvr2_ctl_enum:
+		// Control is an enumeration
+		cip->attr_gen[acnt++] = &cip->attr_enum.attr;
+		break;
+	case pvr2_ctl_int:
+		// Control is an integer
+		cip->attr_gen[acnt++] = &cip->attr_min.attr;
+		cip->attr_gen[acnt++] = &cip->attr_max.attr;
+		break;
+	case pvr2_ctl_bitmask:
+		// Control is an bitmask
+		cip->attr_gen[acnt++] = &cip->attr_bits.attr;
+		break;
+	default: break;
+	}
+
+	cnt = scnprintf(cip->name,sizeof(cip->name)-1,"ctl_%s",
+			pvr2_ctrl_get_name(cptr));
+	cip->name[cnt] = 0;
+	cip->grp.name = cip->name;
+	cip->grp.attrs = cip->attr_gen;
+
+	ret = sysfs_create_group(&sfp->class_dev->kobj,&cip->grp);
+	if (ret) {
+		printk(KERN_WARNING "%s: sysfs_create_group error: %d\n",
+		       __FUNCTION__, ret);
+		return;
+	}
+	cip->created_ok = !0;
+}
+
+#ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC
+static ssize_t debuginfo_show(struct class_device *,char *);
+static ssize_t debugcmd_show(struct class_device *,char *);
+static ssize_t debugcmd_store(struct class_device *,const char *,size_t count);
+
+static void pvr2_sysfs_add_debugifc(struct pvr2_sysfs *sfp)
+{
+	struct pvr2_sysfs_debugifc *dip;
+	int ret;
+
+	dip = kmalloc(sizeof(*dip),GFP_KERNEL);
+	if (!dip) return;
+	memset(dip,0,sizeof(*dip));
+	dip->attr_debugcmd.attr.owner = THIS_MODULE;
+	dip->attr_debugcmd.attr.name = "debugcmd";
+	dip->attr_debugcmd.attr.mode = S_IRUGO|S_IWUSR|S_IWGRP;
+	dip->attr_debugcmd.show = debugcmd_show;
+	dip->attr_debugcmd.store = debugcmd_store;
+	dip->attr_debuginfo.attr.owner = THIS_MODULE;
+	dip->attr_debuginfo.attr.name = "debuginfo";
+	dip->attr_debuginfo.attr.mode = S_IRUGO;
+	dip->attr_debuginfo.show = debuginfo_show;
+	sfp->debugifc = dip;
+	ret = class_device_create_file(sfp->class_dev,&dip->attr_debugcmd);
+	if (ret < 0) {
+		printk(KERN_WARNING "%s: class_device_create_file error: %d\n",
+		       __FUNCTION__, ret);
+	} else {
+		dip->debugcmd_created_ok = !0;
+	}
+	ret = class_device_create_file(sfp->class_dev,&dip->attr_debuginfo);
+	if (ret < 0) {
+		printk(KERN_WARNING "%s: class_device_create_file error: %d\n",
+		       __FUNCTION__, ret);
+	} else {
+		dip->debuginfo_created_ok = !0;
+	}
+}
+
+
+static void pvr2_sysfs_tear_down_debugifc(struct pvr2_sysfs *sfp)
+{
+	if (!sfp->debugifc) return;
+	if (sfp->debugifc->debuginfo_created_ok) {
+		class_device_remove_file(sfp->class_dev,
+					 &sfp->debugifc->attr_debuginfo);
+	}
+	if (sfp->debugifc->debugcmd_created_ok) {
+		class_device_remove_file(sfp->class_dev,
+					 &sfp->debugifc->attr_debugcmd);
+	}
+	kfree(sfp->debugifc);
+	sfp->debugifc = NULL;
+}
+#endif /* CONFIG_VIDEO_PVRUSB2_DEBUGIFC */
+
+
+static void pvr2_sysfs_add_controls(struct pvr2_sysfs *sfp)
+{
+	unsigned int idx,cnt;
+	cnt = pvr2_hdw_get_ctrl_count(sfp->channel.hdw);
+	for (idx = 0; idx < cnt; idx++) {
+		pvr2_sysfs_add_control(sfp,idx);
+	}
+}
+
+
+static void pvr2_sysfs_tear_down_controls(struct pvr2_sysfs *sfp)
+{
+	struct pvr2_sysfs_ctl_item *cip1,*cip2;
+	for (cip1 = sfp->item_first; cip1; cip1 = cip2) {
+		cip2 = cip1->item_next;
+		if (cip1->created_ok) {
+			sysfs_remove_group(&sfp->class_dev->kobj,&cip1->grp);
+		}
+		pvr2_sysfs_trace("Destroying pvr2_sysfs_ctl_item id=%p",cip1);
+		kfree(cip1);
+	}
+}
+
+
+static void pvr2_sysfs_class_release(struct class *class)
+{
+	struct pvr2_sysfs_class *clp;
+	clp = container_of(class,struct pvr2_sysfs_class,class);
+	pvr2_sysfs_trace("Destroying pvr2_sysfs_class id=%p",clp);
+	kfree(clp);
+}
+
+
+static void pvr2_sysfs_release(struct class_device *class_dev)
+{
+	pvr2_sysfs_trace("Releasing class_dev id=%p",class_dev);
+	kfree(class_dev);
+}
+
+
+static void class_dev_destroy(struct pvr2_sysfs *sfp)
+{
+	if (!sfp->class_dev) return;
+#ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC
+	pvr2_sysfs_tear_down_debugifc(sfp);
+#endif /* CONFIG_VIDEO_PVRUSB2_DEBUGIFC */
+	pvr2_sysfs_tear_down_controls(sfp);
+	if (sfp->v4l_minor_number_created_ok) {
+		class_device_remove_file(sfp->class_dev,
+					 &sfp->attr_v4l_minor_number);
+	}
+	if (sfp->unit_number_created_ok) {
+		class_device_remove_file(sfp->class_dev,
+					 &sfp->attr_unit_number);
+	}
+	pvr2_sysfs_trace("Destroying class_dev id=%p",sfp->class_dev);
+	sfp->class_dev->class_data = NULL;
+	class_device_unregister(sfp->class_dev);
+	sfp->class_dev = NULL;
+}
+
+
+static ssize_t v4l_minor_number_show(struct class_device *class_dev,char *buf)
+{
+	struct pvr2_sysfs *sfp;
+	sfp = (struct pvr2_sysfs *)class_dev->class_data;
+	if (!sfp) return -EINVAL;
+	return scnprintf(buf,PAGE_SIZE,"%d\n",
+			 pvr2_hdw_v4l_get_minor_number(sfp->channel.hdw));
+}
+
+
+static ssize_t unit_number_show(struct class_device *class_dev,char *buf)
+{
+	struct pvr2_sysfs *sfp;
+	sfp = (struct pvr2_sysfs *)class_dev->class_data;
+	if (!sfp) return -EINVAL;
+	return scnprintf(buf,PAGE_SIZE,"%d\n",
+			 pvr2_hdw_get_unit_number(sfp->channel.hdw));
+}
+
+
+static void class_dev_create(struct pvr2_sysfs *sfp,
+			     struct pvr2_sysfs_class *class_ptr)
+{
+	struct usb_device *usb_dev;
+	struct class_device *class_dev;
+	int ret;
+
+	usb_dev = pvr2_hdw_get_dev(sfp->channel.hdw);
+	if (!usb_dev) return;
+	class_dev = kmalloc(sizeof(*class_dev),GFP_KERNEL);
+	if (!class_dev) return;
+	memset(class_dev,0,sizeof(*class_dev));
+
+	pvr2_sysfs_trace("Creating class_dev id=%p",class_dev);
+
+	class_dev->class = &class_ptr->class;
+	if (pvr2_hdw_get_sn(sfp->channel.hdw)) {
+		snprintf(class_dev->class_id,BUS_ID_SIZE,"sn-%lu",
+			 pvr2_hdw_get_sn(sfp->channel.hdw));
+	} else if (pvr2_hdw_get_unit_number(sfp->channel.hdw) >= 0) {
+		snprintf(class_dev->class_id,BUS_ID_SIZE,"unit-%c",
+			 pvr2_hdw_get_unit_number(sfp->channel.hdw) + 'a');
+	} else {
+		kfree(class_dev);
+		return;
+	}
+
+	class_dev->dev = &usb_dev->dev;
+
+	sfp->class_dev = class_dev;
+	class_dev->class_data = sfp;
+	ret = class_device_register(class_dev);
+	if (ret) {
+		printk(KERN_ERR "%s: class_device_register failed\n",
+		       __FUNCTION__);
+		kfree(class_dev);
+		return;
+	}
+
+	sfp->attr_v4l_minor_number.attr.owner = THIS_MODULE;
+	sfp->attr_v4l_minor_number.attr.name = "v4l_minor_number";
+	sfp->attr_v4l_minor_number.attr.mode = S_IRUGO;
+	sfp->attr_v4l_minor_number.show = v4l_minor_number_show;
+	sfp->attr_v4l_minor_number.store = NULL;
+	ret = class_device_create_file(sfp->class_dev,
+				       &sfp->attr_v4l_minor_number);
+	if (ret < 0) {
+		printk(KERN_WARNING "%s: class_device_create_file error: %d\n",
+		       __FUNCTION__, ret);
+	} else {
+		sfp->v4l_minor_number_created_ok = !0;
+	}
+
+	sfp->attr_unit_number.attr.owner = THIS_MODULE;
+	sfp->attr_unit_number.attr.name = "unit_number";
+	sfp->attr_unit_number.attr.mode = S_IRUGO;
+	sfp->attr_unit_number.show = unit_number_show;
+	sfp->attr_unit_number.store = NULL;
+	ret = class_device_create_file(sfp->class_dev,&sfp->attr_unit_number);
+	if (ret < 0) {
+		printk(KERN_WARNING "%s: class_device_create_file error: %d\n",
+		       __FUNCTION__, ret);
+	} else {
+		sfp->unit_number_created_ok = !0;
+	}
+
+	pvr2_sysfs_add_controls(sfp);
+#ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC
+	pvr2_sysfs_add_debugifc(sfp);
+#endif /* CONFIG_VIDEO_PVRUSB2_DEBUGIFC */
+}
+
+
+static void pvr2_sysfs_internal_check(struct pvr2_channel *chp)
+{
+	struct pvr2_sysfs *sfp;
+	sfp = container_of(chp,struct pvr2_sysfs,channel);
+	if (!sfp->channel.mc_head->disconnect_flag) return;
+	pvr2_trace(PVR2_TRACE_STRUCT,"Destroying pvr2_sysfs id=%p",sfp);
+	class_dev_destroy(sfp);
+	pvr2_channel_done(&sfp->channel);
+	kfree(sfp);
+}
+
+
+struct pvr2_sysfs *pvr2_sysfs_create(struct pvr2_context *mp,
+				     struct pvr2_sysfs_class *class_ptr)
+{
+	struct pvr2_sysfs *sfp;
+	sfp = kmalloc(sizeof(*sfp),GFP_KERNEL);
+	if (!sfp) return sfp;
+	memset(sfp,0,sizeof(*sfp));
+	pvr2_trace(PVR2_TRACE_STRUCT,"Creating pvr2_sysfs id=%p",sfp);
+	pvr2_channel_init(&sfp->channel,mp);
+	sfp->channel.check_func = pvr2_sysfs_internal_check;
+
+	class_dev_create(sfp,class_ptr);
+	return sfp;
+}
+
+
+static int pvr2_sysfs_hotplug(struct class_device *cd,char **envp,
+			      int numenvp,char *buf,int size)
+{
+	/* Even though we don't do anything here, we still need this function
+	   because sysfs will still try to call it. */
+	return 0;
+}
+
+struct pvr2_sysfs_class *pvr2_sysfs_class_create(void)
+{
+	struct pvr2_sysfs_class *clp;
+	clp = kmalloc(sizeof(*clp),GFP_KERNEL);
+	if (!clp) return clp;
+	memset(clp,0,sizeof(*clp));
+	pvr2_sysfs_trace("Creating pvr2_sysfs_class id=%p",clp);
+	clp->class.name = "pvrusb2";
+	clp->class.class_release = pvr2_sysfs_class_release;
+	clp->class.release = pvr2_sysfs_release;
+	clp->class.uevent = pvr2_sysfs_hotplug;
+	if (class_register(&clp->class)) {
+		pvr2_sysfs_trace(
+			"Registration failed for pvr2_sysfs_class id=%p",clp);
+		kfree(clp);
+		clp = NULL;
+	}
+	return clp;
+}
+
+
+void pvr2_sysfs_class_destroy(struct pvr2_sysfs_class *clp)
+{
+	class_unregister(&clp->class);
+}
+
+
+#ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC
+static ssize_t debuginfo_show(struct class_device *class_dev,char *buf)
+{
+	struct pvr2_sysfs *sfp;
+	sfp = (struct pvr2_sysfs *)class_dev->class_data;
+	if (!sfp) return -EINVAL;
+	pvr2_hdw_trigger_module_log(sfp->channel.hdw);
+	return pvr2_debugifc_print_info(sfp->channel.hdw,buf,PAGE_SIZE);
+}
+
+
+static ssize_t debugcmd_show(struct class_device *class_dev,char *buf)
+{
+	struct pvr2_sysfs *sfp;
+	sfp = (struct pvr2_sysfs *)class_dev->class_data;
+	if (!sfp) return -EINVAL;
+	return pvr2_debugifc_print_status(sfp->channel.hdw,buf,PAGE_SIZE);
+}
+
+
+static ssize_t debugcmd_store(struct class_device *class_dev,
+			      const char *buf,size_t count)
+{
+	struct pvr2_sysfs *sfp;
+	int ret;
+
+	sfp = (struct pvr2_sysfs *)class_dev->class_data;
+	if (!sfp) return -EINVAL;
+
+	ret = pvr2_debugifc_docmd(sfp->channel.hdw,buf,count);
+	if (ret < 0) return ret;
+	return count;
+}
+#endif /* CONFIG_VIDEO_PVRUSB2_DEBUGIFC */
+
+
+/*
+  Stuff for Emacs to see, in order to encourage consistent editing style:
+  *** Local Variables: ***
+  *** mode: c ***
+  *** fill-column: 75 ***
+  *** tab-width: 8 ***
+  *** c-basic-offset: 8 ***
+  *** End: ***
+  */
diff --git a/drivers/media/video/pvrusb2/pvrusb2-sysfs.h b/drivers/media/video/pvrusb2/pvrusb2-sysfs.h
new file mode 100644
index 000000000..ff9373b47
--- /dev/null
+++ b/drivers/media/video/pvrusb2/pvrusb2-sysfs.h
@@ -0,0 +1,47 @@
+/*
+ *
+ *  $Id$
+ *
+ *  Copyright (C) 2005 Mike Isely <isely@pobox.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
+ *
+ *  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 __PVRUSB2_SYSFS_H
+#define __PVRUSB2_SYSFS_H
+
+#include <linux/list.h>
+#include <linux/sysfs.h>
+#include "pvrusb2-context.h"
+
+struct pvr2_sysfs;
+struct pvr2_sysfs_class;
+
+struct pvr2_sysfs_class *pvr2_sysfs_class_create(void);
+void pvr2_sysfs_class_destroy(struct pvr2_sysfs_class *);
+
+struct pvr2_sysfs *pvr2_sysfs_create(struct pvr2_context *,
+				     struct pvr2_sysfs_class *);
+
+#endif /* __PVRUSB2_SYSFS_H */
+
+/*
+  Stuff for Emacs to see, in order to encourage consistent editing style:
+  *** Local Variables: ***
+  *** mode: c ***
+  *** fill-column: 75 ***
+  *** tab-width: 8 ***
+  *** c-basic-offset: 8 ***
+  *** End: ***
+  */
diff --git a/drivers/media/video/pvrusb2/pvrusb2-tuner.c b/drivers/media/video/pvrusb2/pvrusb2-tuner.c
new file mode 100644
index 000000000..af9f246f8
--- /dev/null
+++ b/drivers/media/video/pvrusb2/pvrusb2-tuner.c
@@ -0,0 +1,122 @@
+/*
+ *
+ *  $Id$
+ *
+ *  Copyright (C) 2005 Mike Isely <isely@pobox.com>
+ *  Copyright (C) 2004 Aurelien Alleaume <slts@free.fr>
+ *
+ *  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
+ *
+ *  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 "pvrusb2.h"
+#include "pvrusb2-util.h"
+#include "pvrusb2-tuner.h"
+#include "pvrusb2-hdw-internal.h"
+#include "pvrusb2-debug.h"
+#include <linux/videodev2.h>
+#include <media/tuner.h>
+#include <media/v4l2-common.h>
+
+struct pvr2_tuner_handler {
+	struct pvr2_hdw *hdw;
+	struct pvr2_i2c_client *client;
+	struct pvr2_i2c_handler i2c_handler;
+	int type_update_fl;
+};
+
+
+static void set_type(struct pvr2_tuner_handler *ctxt)
+{
+	struct pvr2_hdw *hdw = ctxt->hdw;
+	struct tuner_setup setup;
+	pvr2_trace(PVR2_TRACE_CHIPS,"i2c tuner set_type(%d)",hdw->tuner_type);
+	if (((int)(hdw->tuner_type)) < 0) return;
+
+	setup.addr = ADDR_UNSET;
+	setup.type = hdw->tuner_type;
+	setup.mode_mask = T_RADIO | T_ANALOG_TV;
+	/* We may really want mode_mask to be T_ANALOG_TV for now */
+	pvr2_i2c_client_cmd(ctxt->client,TUNER_SET_TYPE_ADDR,&setup);
+	ctxt->type_update_fl = 0;
+}
+
+
+static int tuner_check(struct pvr2_tuner_handler *ctxt)
+{
+	struct pvr2_hdw *hdw = ctxt->hdw;
+	if (hdw->tuner_updated) ctxt->type_update_fl = !0;
+	return ctxt->type_update_fl != 0;
+}
+
+
+static void tuner_update(struct pvr2_tuner_handler *ctxt)
+{
+	if (ctxt->type_update_fl) set_type(ctxt);
+}
+
+
+static void pvr2_tuner_detach(struct pvr2_tuner_handler *ctxt)
+{
+	ctxt->client->handler = NULL;
+	kfree(ctxt);
+}
+
+
+static unsigned int pvr2_tuner_describe(struct pvr2_tuner_handler *ctxt,char *buf,unsigned int cnt)
+{
+	return scnprintf(buf,cnt,"handler: pvrusb2-tuner");
+}
+
+
+const static struct pvr2_i2c_handler_functions tuner_funcs = {
+	.detach = (void (*)(void *))pvr2_tuner_detach,
+	.check = (int (*)(void *))tuner_check,
+	.update = (void (*)(void *))tuner_update,
+	.describe = (unsigned int (*)(void *,char *,unsigned int))pvr2_tuner_describe,
+};
+
+
+int pvr2_i2c_tuner_setup(struct pvr2_hdw *hdw,struct pvr2_i2c_client *cp)
+{
+	struct pvr2_tuner_handler *ctxt;
+	if (cp->handler) return 0;
+
+	ctxt = kmalloc(sizeof(*ctxt),GFP_KERNEL);
+	if (!ctxt) return 0;
+	memset(ctxt,0,sizeof(*ctxt));
+
+	ctxt->i2c_handler.func_data = ctxt;
+	ctxt->i2c_handler.func_table = &tuner_funcs;
+	ctxt->type_update_fl = !0;
+	ctxt->client = cp;
+	ctxt->hdw = hdw;
+	cp->handler = &ctxt->i2c_handler;
+	pvr2_trace(PVR2_TRACE_CHIPS,"i2c 0x%x tuner handler set up",
+		   cp->client->addr);
+	return !0;
+}
+
+
+
+
+/*
+  Stuff for Emacs to see, in order to encourage consistent editing style:
+  *** Local Variables: ***
+  *** mode: c ***
+  *** fill-column: 70 ***
+  *** tab-width: 8 ***
+  *** c-basic-offset: 8 ***
+  *** End: ***
+  */
diff --git a/drivers/media/video/pvrusb2/pvrusb2-tuner.h b/drivers/media/video/pvrusb2/pvrusb2-tuner.h
new file mode 100644
index 000000000..556f12aa9
--- /dev/null
+++ b/drivers/media/video/pvrusb2/pvrusb2-tuner.h
@@ -0,0 +1,38 @@
+/*
+ *
+ *  $Id$
+ *
+ *  Copyright (C) 2005 Mike Isely <isely@pobox.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
+ *
+ *  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 __PVRUSB2_TUNER_H
+#define __PVRUSB2_TUNER_H
+
+#include "pvrusb2-i2c-core.h"
+
+int pvr2_i2c_tuner_setup(struct pvr2_hdw *,struct pvr2_i2c_client *);
+
+#endif /* __PVRUSB2_TUNER_H */
+
+/*
+  Stuff for Emacs to see, in order to encourage consistent editing style:
+  *** Local Variables: ***
+  *** mode: c ***
+  *** fill-column: 70 ***
+  *** tab-width: 8 ***
+  *** c-basic-offset: 8 ***
+  *** End: ***
+  */
diff --git a/drivers/media/video/pvrusb2/pvrusb2-util.h b/drivers/media/video/pvrusb2/pvrusb2-util.h
new file mode 100644
index 000000000..e53aee416
--- /dev/null
+++ b/drivers/media/video/pvrusb2/pvrusb2-util.h
@@ -0,0 +1,63 @@
+/*
+ *
+ *  $Id$
+ *
+ *  Copyright (C) 2005 Mike Isely <isely@pobox.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
+ *
+ *  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 __PVRUSB2_UTIL_H
+#define __PVRUSB2_UTIL_H
+
+#define PVR2_DECOMPOSE_LE(t,i,d) \
+    do {    \
+	(t)[i] = (d) & 0xff;\
+	(t)[i+1] = ((d) >> 8) & 0xff;\
+	(t)[i+2] = ((d) >> 16) & 0xff;\
+	(t)[i+3] = ((d) >> 24) & 0xff;\
+    } while(0)
+
+#define PVR2_DECOMPOSE_BE(t,i,d) \
+    do {    \
+	(t)[i+3] = (d) & 0xff;\
+	(t)[i+2] = ((d) >> 8) & 0xff;\
+	(t)[i+1] = ((d) >> 16) & 0xff;\
+	(t)[i] = ((d) >> 24) & 0xff;\
+    } while(0)
+
+#define PVR2_COMPOSE_LE(t,i) \
+    ((((u32)((t)[i+3])) << 24) | \
+     (((u32)((t)[i+2])) << 16) | \
+     (((u32)((t)[i+1])) << 8) | \
+     ((u32)((t)[i])))
+
+#define PVR2_COMPOSE_BE(t,i) \
+    ((((u32)((t)[i])) << 24) | \
+     (((u32)((t)[i+1])) << 16) | \
+     (((u32)((t)[i+2])) << 8) | \
+     ((u32)((t)[i+3])))
+
+
+#endif /* __PVRUSB2_UTIL_H */
+
+/*
+  Stuff for Emacs to see, in order to encourage consistent editing style:
+  *** Local Variables: ***
+  *** mode: c ***
+  *** fill-column: 75 ***
+  *** tab-width: 8 ***
+  *** c-basic-offset: 8 ***
+  *** End: ***
+  */
diff --git a/drivers/media/video/pvrusb2/pvrusb2-v4l2.c b/drivers/media/video/pvrusb2/pvrusb2-v4l2.c
new file mode 100644
index 000000000..72f444cf3
--- /dev/null
+++ b/drivers/media/video/pvrusb2/pvrusb2-v4l2.c
@@ -0,0 +1,1087 @@
+/*
+ *
+ *  $Id$
+ *
+ *  Copyright (C) 2005 Mike Isely <isely@pobox.com>
+ *  Copyright (C) 2004 Aurelien Alleaume <slts@free.fr>
+ *
+ *  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
+ *
+ *  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/version.h>
+#include <linux/videodev.h>
+#include "pvrusb2-context.h"
+#include "pvrusb2-hdw.h"
+#include "pvrusb2.h"
+#include "pvrusb2-debug.h"
+#include "pvrusb2-v4l2.h"
+#include "pvrusb2-ioread.h"
+#include <linux/videodev2.h>
+#include <media/v4l2-common.h>
+
+/* Mike Isely <isely@pobox.com> 23-Sep-2006 - This function is prototyped
+ * only for V4L1 but is implemented regardless of the V4L1 compatibility
+ * option state.  V4L2 has no replacement for this and we need it.  For now
+ * copy the prototype here so we can avoid the compiler warning. */
+extern struct video_device* video_devdata(struct file*);
+
+struct pvr2_v4l2_dev;
+struct pvr2_v4l2_fh;
+struct pvr2_v4l2;
+
+
+struct pvr2_v4l2_dev {
+	struct pvr2_v4l2 *v4lp;
+	struct video_device *vdev;
+	struct pvr2_context_stream *stream;
+	enum pvr2_config config;
+};
+
+struct pvr2_v4l2_fh {
+	struct pvr2_channel channel;
+	struct pvr2_v4l2_dev *dev_info;
+	enum v4l2_priority prio;
+	struct pvr2_ioread *rhp;
+	struct file *file;
+	struct pvr2_v4l2 *vhead;
+	struct pvr2_v4l2_fh *vnext;
+	struct pvr2_v4l2_fh *vprev;
+	wait_queue_head_t wait_data;
+	int fw_mode_flag;
+};
+
+struct pvr2_v4l2 {
+	struct pvr2_channel channel;
+	struct pvr2_v4l2_fh *vfirst;
+	struct pvr2_v4l2_fh *vlast;
+
+	struct v4l2_prio_state prio;
+
+	/* streams */
+	struct pvr2_v4l2_dev video_dev;
+};
+
+static int video_nr[PVR_NUM] = {[0 ... PVR_NUM-1] = -1};
+module_param_array(video_nr, int, NULL, 0444);
+MODULE_PARM_DESC(video_nr, "Offset for device's minor");
+
+static struct v4l2_capability pvr_capability ={
+	.driver         = "pvrusb2",
+	.card           = "Hauppauge WinTV pvr-usb2",
+	.bus_info       = "usb",
+	.version        = KERNEL_VERSION(0,8,0),
+	.capabilities   = (V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VBI_CAPTURE |
+			   V4L2_CAP_TUNER | V4L2_CAP_AUDIO |
+			   V4L2_CAP_READWRITE),
+	.reserved       = {0,0,0,0}
+};
+
+static struct v4l2_tuner pvr_v4l2_tuners[]= {
+	{
+		.index      = 0,
+		.name       = "TV Tuner",
+		.type           = V4L2_TUNER_ANALOG_TV,
+		.capability     = (V4L2_TUNER_CAP_NORM |
+				   V4L2_TUNER_CAP_STEREO |
+				   V4L2_TUNER_CAP_LANG1 |
+				   V4L2_TUNER_CAP_LANG2),
+		.rangelow   = 0,
+		.rangehigh  = 0,
+		.rxsubchans     = V4L2_TUNER_SUB_STEREO,
+		.audmode        = V4L2_TUNER_MODE_STEREO,
+		.signal         = 0,
+		.afc            = 0,
+		.reserved       = {0,0,0,0}
+	}
+};
+
+static struct v4l2_fmtdesc pvr_fmtdesc [] = {
+	{
+		.index          = 0,
+		.type           = V4L2_BUF_TYPE_VIDEO_CAPTURE,
+		.flags          = V4L2_FMT_FLAG_COMPRESSED,
+		.description    = "MPEG1/2",
+		// This should really be V4L2_PIX_FMT_MPEG, but xawtv
+		// breaks when I do that.
+		.pixelformat    = 0, // V4L2_PIX_FMT_MPEG,
+		.reserved       = { 0, 0, 0, 0 }
+	}
+};
+
+#define PVR_FORMAT_PIX  0
+#define PVR_FORMAT_VBI  1
+
+static struct v4l2_format pvr_format [] = {
+	[PVR_FORMAT_PIX] = {
+		.type   = V4L2_BUF_TYPE_VIDEO_CAPTURE,
+		.fmt    = {
+			.pix        = {
+				.width          = 720,
+				.height             = 576,
+				// This should really be V4L2_PIX_FMT_MPEG,
+				// but xawtv breaks when I do that.
+				.pixelformat    = 0, // V4L2_PIX_FMT_MPEG,
+				.field          = V4L2_FIELD_INTERLACED,
+				.bytesperline   = 0,  // doesn't make sense
+						      // here
+				//FIXME : Don't know what to put here...
+				.sizeimage          = (32*1024),
+				.colorspace     = 0, // doesn't make sense here
+				.priv           = 0
+			}
+		}
+	},
+	[PVR_FORMAT_VBI] = {
+		.type   = V4L2_BUF_TYPE_VBI_CAPTURE,
+		.fmt    = {
+			.vbi        = {
+				.sampling_rate = 27000000,
+				.offset = 248,
+				.samples_per_line = 1443,
+				.sample_format = V4L2_PIX_FMT_GREY,
+				.start = { 0, 0 },
+				.count = { 0, 0 },
+				.flags = 0,
+				.reserved = { 0, 0 }
+			}
+		}
+	}
+};
+
+/*
+ * pvr_ioctl()
+ *
+ * This is part of Video 4 Linux API. The procedure handles ioctl() calls.
+ *
+ */
+static int pvr2_v4l2_do_ioctl(struct inode *inode, struct file *file,
+			      unsigned int cmd, void *arg)
+{
+	struct pvr2_v4l2_fh *fh = file->private_data;
+	struct pvr2_v4l2 *vp = fh->vhead;
+	struct pvr2_v4l2_dev *dev_info = fh->dev_info;
+	struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
+	int ret = -EINVAL;
+
+	if (pvrusb2_debug & PVR2_TRACE_V4LIOCTL) {
+		v4l_print_ioctl(pvr2_hdw_get_driver_name(hdw),cmd);
+	}
+
+	if (!pvr2_hdw_dev_ok(hdw)) {
+		pvr2_trace(PVR2_TRACE_ERROR_LEGS,
+			   "ioctl failed - bad or no context");
+		return -EFAULT;
+	}
+
+	/* check priority */
+	switch (cmd) {
+	case VIDIOC_S_CTRL:
+	case VIDIOC_S_STD:
+	case VIDIOC_S_INPUT:
+	case VIDIOC_S_TUNER:
+	case VIDIOC_S_FREQUENCY:
+		ret = v4l2_prio_check(&vp->prio, &fh->prio);
+		if (ret)
+			return ret;
+	}
+
+	switch (cmd) {
+	case VIDIOC_QUERYCAP:
+	{
+		struct v4l2_capability *cap = arg;
+
+		memcpy(cap, &pvr_capability, sizeof(struct v4l2_capability));
+
+		ret = 0;
+		break;
+	}
+
+	case VIDIOC_G_PRIORITY:
+	{
+		enum v4l2_priority *p = arg;
+
+		*p = v4l2_prio_max(&vp->prio);
+		ret = 0;
+		break;
+	}
+
+	case VIDIOC_S_PRIORITY:
+	{
+		enum v4l2_priority *prio = arg;
+
+		ret = v4l2_prio_change(&vp->prio, &fh->prio, *prio);
+		break;
+	}
+
+	case VIDIOC_ENUMSTD:
+	{
+		struct v4l2_standard *vs = (struct v4l2_standard *)arg;
+		int idx = vs->index;
+		ret = pvr2_hdw_get_stdenum_value(hdw,vs,idx+1);
+		break;
+	}
+
+	case VIDIOC_G_STD:
+	{
+		int val = 0;
+		ret = pvr2_ctrl_get_value(
+			pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_STDCUR),&val);
+		*(v4l2_std_id *)arg = val;
+		break;
+	}
+
+	case VIDIOC_S_STD:
+	{
+		ret = pvr2_ctrl_set_value(
+			pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_STDCUR),
+			*(v4l2_std_id *)arg);
+		break;
+	}
+
+	case VIDIOC_ENUMINPUT:
+	{
+		struct pvr2_ctrl *cptr;
+		struct v4l2_input *vi = (struct v4l2_input *)arg;
+		struct v4l2_input tmp;
+		unsigned int cnt;
+
+		cptr = pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_INPUT);
+
+		memset(&tmp,0,sizeof(tmp));
+		tmp.index = vi->index;
+		ret = 0;
+		switch (vi->index) {
+		case PVR2_CVAL_INPUT_TV:
+		case PVR2_CVAL_INPUT_RADIO:
+			tmp.type = V4L2_INPUT_TYPE_TUNER;
+			break;
+		case PVR2_CVAL_INPUT_SVIDEO:
+		case PVR2_CVAL_INPUT_COMPOSITE:
+			tmp.type = V4L2_INPUT_TYPE_CAMERA;
+			break;
+		default:
+			ret = -EINVAL;
+			break;
+		}
+		if (ret < 0) break;
+
+		cnt = 0;
+		pvr2_ctrl_get_valname(cptr,vi->index,
+				      tmp.name,sizeof(tmp.name)-1,&cnt);
+		tmp.name[cnt] = 0;
+
+		/* Don't bother with audioset, since this driver currently
+		   always switches the audio whenever the video is
+		   switched. */
+
+		/* Handling std is a tougher problem.  It doesn't make
+		   sense in cases where a device might be multi-standard.
+		   We could just copy out the current value for the
+		   standard, but it can change over time.  For now just
+		   leave it zero. */
+
+		memcpy(vi, &tmp, sizeof(tmp));
+
+		ret = 0;
+		break;
+	}
+
+	case VIDIOC_G_INPUT:
+	{
+		struct pvr2_ctrl *cptr;
+		struct v4l2_input *vi = (struct v4l2_input *)arg;
+		int val;
+		cptr = pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_INPUT);
+		val = 0;
+		ret = pvr2_ctrl_get_value(cptr,&val);
+		vi->index = val;
+		break;
+	}
+
+	case VIDIOC_S_INPUT:
+	{
+		struct v4l2_input *vi = (struct v4l2_input *)arg;
+		ret = pvr2_ctrl_set_value(
+			pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_INPUT),
+			vi->index);
+		break;
+	}
+
+	case VIDIOC_ENUMAUDIO:
+	{
+		ret = -EINVAL;
+		break;
+	}
+
+	case VIDIOC_G_AUDIO:
+	{
+		ret = -EINVAL;
+		break;
+	}
+
+	case VIDIOC_S_AUDIO:
+	{
+		ret = -EINVAL;
+		break;
+	}
+	case VIDIOC_G_TUNER:
+	{
+		struct v4l2_tuner *vt = (struct v4l2_tuner *)arg;
+		unsigned int status_mask;
+		int val;
+		if (vt->index !=0) break;
+
+		status_mask = pvr2_hdw_get_signal_status(hdw);
+
+		memcpy(vt, &pvr_v4l2_tuners[vt->index],
+		       sizeof(struct v4l2_tuner));
+
+		vt->signal = 0;
+		if (status_mask & PVR2_SIGNAL_OK) {
+			if (status_mask & PVR2_SIGNAL_STEREO) {
+				vt->rxsubchans = V4L2_TUNER_SUB_STEREO;
+			} else {
+				vt->rxsubchans = V4L2_TUNER_SUB_MONO;
+			}
+			if (status_mask & PVR2_SIGNAL_SAP) {
+				vt->rxsubchans |= (V4L2_TUNER_SUB_LANG1 |
+						   V4L2_TUNER_SUB_LANG2);
+			}
+			vt->signal = 65535;
+		}
+
+		val = 0;
+		ret = pvr2_ctrl_get_value(
+			pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_AUDIOMODE),
+			&val);
+		vt->audmode = val;
+		break;
+	}
+
+	case VIDIOC_S_TUNER:
+	{
+		struct v4l2_tuner *vt=(struct v4l2_tuner *)arg;
+
+		if (vt->index != 0)
+			break;
+
+		ret = pvr2_ctrl_set_value(
+			pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_AUDIOMODE),
+			vt->audmode);
+	}
+
+	case VIDIOC_S_FREQUENCY:
+	{
+		const struct v4l2_frequency *vf = (struct v4l2_frequency *)arg;
+		ret = pvr2_ctrl_set_value(
+			pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_FREQUENCY),
+			vf->frequency * 62500);
+		break;
+	}
+
+	case VIDIOC_G_FREQUENCY:
+	{
+		struct v4l2_frequency *vf = (struct v4l2_frequency *)arg;
+		int val = 0;
+		ret = pvr2_ctrl_get_value(
+			pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_FREQUENCY),
+			&val);
+		val /= 62500;
+		vf->frequency = val;
+		break;
+	}
+
+	case VIDIOC_ENUM_FMT:
+	{
+		struct v4l2_fmtdesc *fd = (struct v4l2_fmtdesc *)arg;
+
+		/* Only one format is supported : mpeg.*/
+		if (fd->index != 0)
+			break;
+
+		memcpy(fd, pvr_fmtdesc, sizeof(struct v4l2_fmtdesc));
+		ret = 0;
+		break;
+	}
+
+	case VIDIOC_G_FMT:
+	{
+		struct v4l2_format *vf = (struct v4l2_format *)arg;
+		int val;
+		switch(vf->type) {
+		case V4L2_BUF_TYPE_VIDEO_CAPTURE:
+			memcpy(vf, &pvr_format[PVR_FORMAT_PIX],
+			       sizeof(struct v4l2_format));
+			val = 0;
+			pvr2_ctrl_get_value(
+				pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_HRES),
+				&val);
+			vf->fmt.pix.width = val;
+			val = 0;
+			pvr2_ctrl_get_value(
+				pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_VRES),
+				&val);
+			vf->fmt.pix.height = val;
+			ret = 0;
+			break;
+		case V4L2_BUF_TYPE_VBI_CAPTURE:
+			// ????? Still need to figure out to do VBI correctly
+			ret = -EINVAL;
+			break;
+		default:
+			ret = -EINVAL;
+			break;
+		}
+		break;
+	}
+
+	case VIDIOC_TRY_FMT:
+	case VIDIOC_S_FMT:
+	{
+		struct v4l2_format *vf = (struct v4l2_format *)arg;
+
+		ret = 0;
+		switch(vf->type) {
+		case V4L2_BUF_TYPE_VIDEO_CAPTURE: {
+			int lmin,lmax;
+			struct pvr2_ctrl *hcp,*vcp;
+			int h = vf->fmt.pix.height;
+			int w = vf->fmt.pix.width;
+			hcp = pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_HRES);
+			vcp = pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_VRES);
+
+			lmin = pvr2_ctrl_get_min(hcp);
+			lmax = pvr2_ctrl_get_max(hcp);
+			if (w < lmin) {
+				w = lmin;
+			} else if (w > lmax) {
+				w = lmax;
+			}
+			lmin = pvr2_ctrl_get_min(vcp);
+			lmax = pvr2_ctrl_get_max(vcp);
+			if (h < lmin) {
+				h = lmin;
+			} else if (h > lmax) {
+				h = lmax;
+			}
+
+			memcpy(vf, &pvr_format[PVR_FORMAT_PIX],
+			       sizeof(struct v4l2_format));
+			vf->fmt.pix.width = w;
+			vf->fmt.pix.height = h;
+
+			if (cmd == VIDIOC_S_FMT) {
+				pvr2_ctrl_set_value(hcp,vf->fmt.pix.width);
+				pvr2_ctrl_set_value(vcp,vf->fmt.pix.height);
+			}
+		} break;
+		case V4L2_BUF_TYPE_VBI_CAPTURE:
+			// ????? Still need to figure out to do VBI correctly
+			ret = -EINVAL;
+			break;
+		default:
+			ret = -EINVAL;
+			break;
+		}
+		break;
+	}
+
+	case VIDIOC_STREAMON:
+	{
+		ret = pvr2_hdw_set_stream_type(hdw,dev_info->config);
+		if (ret < 0) return ret;
+		ret = pvr2_hdw_set_streaming(hdw,!0);
+		break;
+	}
+
+	case VIDIOC_STREAMOFF:
+	{
+		ret = pvr2_hdw_set_streaming(hdw,0);
+		break;
+	}
+
+	case VIDIOC_QUERYCTRL:
+	{
+		struct pvr2_ctrl *cptr;
+		struct v4l2_queryctrl *vc = (struct v4l2_queryctrl *)arg;
+		ret = 0;
+		if (vc->id & V4L2_CTRL_FLAG_NEXT_CTRL) {
+			cptr = pvr2_hdw_get_ctrl_nextv4l(
+				hdw,(vc->id & ~V4L2_CTRL_FLAG_NEXT_CTRL));
+			if (cptr) vc->id = pvr2_ctrl_get_v4lid(cptr);
+		} else {
+			cptr = pvr2_hdw_get_ctrl_v4l(hdw,vc->id);
+		}
+		if (!cptr) {
+			pvr2_trace(PVR2_TRACE_V4LIOCTL,
+				   "QUERYCTRL id=0x%x not implemented here",
+				   vc->id);
+			ret = -EINVAL;
+			break;
+		}
+
+		pvr2_trace(PVR2_TRACE_V4LIOCTL,
+			   "QUERYCTRL id=0x%x mapping name=%s (%s)",
+			   vc->id,pvr2_ctrl_get_name(cptr),
+			   pvr2_ctrl_get_desc(cptr));
+		strlcpy(vc->name,pvr2_ctrl_get_desc(cptr),sizeof(vc->name));
+		vc->flags = pvr2_ctrl_get_v4lflags(cptr);
+		vc->default_value = pvr2_ctrl_get_def(cptr);
+		switch (pvr2_ctrl_get_type(cptr)) {
+		case pvr2_ctl_enum:
+			vc->type = V4L2_CTRL_TYPE_MENU;
+			vc->minimum = 0;
+			vc->maximum = pvr2_ctrl_get_cnt(cptr) - 1;
+			vc->step = 1;
+			break;
+		case pvr2_ctl_bool:
+			vc->type = V4L2_CTRL_TYPE_BOOLEAN;
+			vc->minimum = 0;
+			vc->maximum = 1;
+			vc->step = 1;
+			break;
+		case pvr2_ctl_int:
+			vc->type = V4L2_CTRL_TYPE_INTEGER;
+			vc->minimum = pvr2_ctrl_get_min(cptr);
+			vc->maximum = pvr2_ctrl_get_max(cptr);
+			vc->step = 1;
+			break;
+		default:
+			pvr2_trace(PVR2_TRACE_V4LIOCTL,
+				   "QUERYCTRL id=0x%x name=%s not mappable",
+				   vc->id,pvr2_ctrl_get_name(cptr));
+			ret = -EINVAL;
+			break;
+		}
+		break;
+	}
+
+	case VIDIOC_QUERYMENU:
+	{
+		struct v4l2_querymenu *vm = (struct v4l2_querymenu *)arg;
+		unsigned int cnt = 0;
+		ret = pvr2_ctrl_get_valname(pvr2_hdw_get_ctrl_v4l(hdw,vm->id),
+					    vm->index,
+					    vm->name,sizeof(vm->name)-1,
+					    &cnt);
+		vm->name[cnt] = 0;
+		break;
+	}
+
+	case VIDIOC_G_CTRL:
+	{
+		struct v4l2_control *vc = (struct v4l2_control *)arg;
+		int val = 0;
+		ret = pvr2_ctrl_get_value(pvr2_hdw_get_ctrl_v4l(hdw,vc->id),
+					  &val);
+		vc->value = val;
+		break;
+	}
+
+	case VIDIOC_S_CTRL:
+	{
+		struct v4l2_control *vc = (struct v4l2_control *)arg;
+		ret = pvr2_ctrl_set_value(pvr2_hdw_get_ctrl_v4l(hdw,vc->id),
+					  vc->value);
+		break;
+	}
+
+	case VIDIOC_G_EXT_CTRLS:
+	{
+		struct v4l2_ext_controls *ctls =
+			(struct v4l2_ext_controls *)arg;
+		struct v4l2_ext_control *ctrl;
+		unsigned int idx;
+		int val;
+		for (idx = 0; idx < ctls->count; idx++) {
+			ctrl = ctls->controls + idx;
+			ret = pvr2_ctrl_get_value(
+				pvr2_hdw_get_ctrl_v4l(hdw,ctrl->id),&val);
+			if (ret) {
+				ctls->error_idx = idx;
+				break;
+			}
+			/* Ensure that if read as a 64 bit value, the user
+			   will still get a hopefully sane value */
+			ctrl->value64 = 0;
+			ctrl->value = val;
+		}
+		break;
+	}
+
+	case VIDIOC_S_EXT_CTRLS:
+	{
+		struct v4l2_ext_controls *ctls =
+			(struct v4l2_ext_controls *)arg;
+		struct v4l2_ext_control *ctrl;
+		unsigned int idx;
+		for (idx = 0; idx < ctls->count; idx++) {
+			ctrl = ctls->controls + idx;
+			ret = pvr2_ctrl_set_value(
+				pvr2_hdw_get_ctrl_v4l(hdw,ctrl->id),
+				ctrl->value);
+			if (ret) {
+				ctls->error_idx = idx;
+				break;
+			}
+		}
+		break;
+	}
+
+	case VIDIOC_TRY_EXT_CTRLS:
+	{
+		struct v4l2_ext_controls *ctls =
+			(struct v4l2_ext_controls *)arg;
+		struct v4l2_ext_control *ctrl;
+		struct pvr2_ctrl *pctl;
+		unsigned int idx;
+		/* For the moment just validate that the requested control
+		   actually exists. */
+		for (idx = 0; idx < ctls->count; idx++) {
+			ctrl = ctls->controls + idx;
+			pctl = pvr2_hdw_get_ctrl_v4l(hdw,ctrl->id);
+			if (!pctl) {
+				ret = -EINVAL;
+				ctls->error_idx = idx;
+				break;
+			}
+		}
+		break;
+	}
+
+	case VIDIOC_LOG_STATUS:
+	{
+		pvr2_hdw_trigger_module_log(hdw);
+		ret = 0;
+		break;
+	}
+
+	default :
+		ret = v4l_compat_translate_ioctl(inode,file,cmd,
+						 arg,pvr2_v4l2_do_ioctl);
+	}
+
+	pvr2_hdw_commit_ctl(hdw);
+
+	if (ret < 0) {
+		if (pvrusb2_debug & PVR2_TRACE_V4LIOCTL) {
+			pvr2_trace(PVR2_TRACE_V4LIOCTL,
+				   "pvr2_v4l2_do_ioctl failure, ret=%d",ret);
+		} else {
+			if (pvrusb2_debug & PVR2_TRACE_V4LIOCTL) {
+				pvr2_trace(PVR2_TRACE_V4LIOCTL,
+					   "pvr2_v4l2_do_ioctl failure, ret=%d"
+					   " command was:",ret);
+				v4l_print_ioctl(pvr2_hdw_get_driver_name(hdw),
+						cmd);
+			}
+		}
+	} else {
+		pvr2_trace(PVR2_TRACE_V4LIOCTL,
+			   "pvr2_v4l2_do_ioctl complete, ret=%d (0x%x)",
+			   ret,ret);
+	}
+	return ret;
+}
+
+
+static void pvr2_v4l2_dev_destroy(struct pvr2_v4l2_dev *dip)
+{
+	printk(KERN_INFO "pvrusb2: unregistering device video%d [%s]\n",
+	       dip->vdev->minor,pvr2_config_get_name(dip->config));
+	video_unregister_device(dip->vdev);
+}
+
+
+static void pvr2_v4l2_destroy_no_lock(struct pvr2_v4l2 *vp)
+{
+	pvr2_hdw_v4l_store_minor_number(vp->channel.mc_head->hdw,-1);
+	pvr2_v4l2_dev_destroy(&vp->video_dev);
+
+	pvr2_trace(PVR2_TRACE_STRUCT,"Destroying pvr2_v4l2 id=%p",vp);
+	pvr2_channel_done(&vp->channel);
+	kfree(vp);
+}
+
+
+static void pvr2_v4l2_internal_check(struct pvr2_channel *chp)
+{
+	struct pvr2_v4l2 *vp;
+	vp = container_of(chp,struct pvr2_v4l2,channel);
+	if (!vp->channel.mc_head->disconnect_flag) return;
+	if (vp->vfirst) return;
+	pvr2_v4l2_destroy_no_lock(vp);
+}
+
+
+static int pvr2_v4l2_ioctl(struct inode *inode, struct file *file,
+			   unsigned int cmd, unsigned long arg)
+{
+
+/* Temporary hack : use ivtv api until a v4l2 one is available. */
+#define IVTV_IOC_G_CODEC        0xFFEE7703
+#define IVTV_IOC_S_CODEC        0xFFEE7704
+	if (cmd == IVTV_IOC_G_CODEC || cmd == IVTV_IOC_S_CODEC) return 0;
+	return video_usercopy(inode, file, cmd, arg, pvr2_v4l2_do_ioctl);
+}
+
+
+static int pvr2_v4l2_release(struct inode *inode, struct file *file)
+{
+	struct pvr2_v4l2_fh *fhp = file->private_data;
+	struct pvr2_v4l2 *vp = fhp->vhead;
+	struct pvr2_context *mp = fhp->vhead->channel.mc_head;
+
+	pvr2_trace(PVR2_TRACE_OPEN_CLOSE,"pvr2_v4l2_release");
+
+	if (fhp->rhp) {
+		struct pvr2_stream *sp;
+		struct pvr2_hdw *hdw;
+		hdw = fhp->channel.mc_head->hdw;
+		pvr2_hdw_set_streaming(hdw,0);
+		sp = pvr2_ioread_get_stream(fhp->rhp);
+		if (sp) pvr2_stream_set_callback(sp,NULL,NULL);
+		pvr2_ioread_destroy(fhp->rhp);
+		fhp->rhp = NULL;
+	}
+	v4l2_prio_close(&vp->prio, &fhp->prio);
+	file->private_data = NULL;
+
+	pvr2_context_enter(mp); do {
+		if (fhp->vnext) {
+			fhp->vnext->vprev = fhp->vprev;
+		} else {
+			vp->vlast = fhp->vprev;
+		}
+		if (fhp->vprev) {
+			fhp->vprev->vnext = fhp->vnext;
+		} else {
+			vp->vfirst = fhp->vnext;
+		}
+		fhp->vnext = NULL;
+		fhp->vprev = NULL;
+		fhp->vhead = NULL;
+		pvr2_channel_done(&fhp->channel);
+		pvr2_trace(PVR2_TRACE_STRUCT,
+			   "Destroying pvr_v4l2_fh id=%p",fhp);
+		kfree(fhp);
+		if (vp->channel.mc_head->disconnect_flag && !vp->vfirst) {
+			pvr2_v4l2_destroy_no_lock(vp);
+		}
+	} while (0); pvr2_context_exit(mp);
+	return 0;
+}
+
+
+static int pvr2_v4l2_open(struct inode *inode, struct file *file)
+{
+	struct pvr2_v4l2_dev *dip = NULL; /* Our own context pointer */
+	struct pvr2_v4l2_fh *fhp;
+	struct pvr2_v4l2 *vp;
+	struct pvr2_hdw *hdw;
+
+	{
+		struct video_device *vdev = video_devdata(file);
+		dip = (struct pvr2_v4l2_dev *)video_get_drvdata(vdev);
+	}
+
+	if (!dip) return -ENODEV; /* Should be impossible but I'm paranoid */
+
+	vp = dip->v4lp;
+	hdw = vp->channel.hdw;
+
+	pvr2_trace(PVR2_TRACE_OPEN_CLOSE,"pvr2_v4l2_open");
+
+	if (!pvr2_hdw_dev_ok(hdw)) {
+		pvr2_trace(PVR2_TRACE_OPEN_CLOSE,
+			   "pvr2_v4l2_open: hardware not ready");
+		return -EIO;
+	}
+
+	fhp = kmalloc(sizeof(*fhp),GFP_KERNEL);
+	if (!fhp) {
+		return -ENOMEM;
+	}
+	memset(fhp,0,sizeof(*fhp));
+
+	init_waitqueue_head(&fhp->wait_data);
+	fhp->dev_info = dip;
+
+	pvr2_context_enter(vp->channel.mc_head); do {
+		pvr2_trace(PVR2_TRACE_STRUCT,"Creating pvr_v4l2_fh id=%p",fhp);
+		pvr2_channel_init(&fhp->channel,vp->channel.mc_head);
+		fhp->vnext = NULL;
+		fhp->vprev = vp->vlast;
+		if (vp->vlast) {
+			vp->vlast->vnext = fhp;
+		} else {
+			vp->vfirst = fhp;
+		}
+		vp->vlast = fhp;
+		fhp->vhead = vp;
+	} while (0); pvr2_context_exit(vp->channel.mc_head);
+
+	fhp->file = file;
+	file->private_data = fhp;
+	v4l2_prio_open(&vp->prio,&fhp->prio);
+
+	fhp->fw_mode_flag = pvr2_hdw_cpufw_get_enabled(hdw);
+
+	return 0;
+}
+
+
+static void pvr2_v4l2_notify(struct pvr2_v4l2_fh *fhp)
+{
+	wake_up(&fhp->wait_data);
+}
+
+static int pvr2_v4l2_iosetup(struct pvr2_v4l2_fh *fh)
+{
+	int ret;
+	struct pvr2_stream *sp;
+	struct pvr2_hdw *hdw;
+	if (fh->rhp) return 0;
+
+	/* First read() attempt.  Try to claim the stream and start
+	   it... */
+	if ((ret = pvr2_channel_claim_stream(&fh->channel,
+					     fh->dev_info->stream)) != 0) {
+		/* Someone else must already have it */
+		return ret;
+	}
+
+	fh->rhp = pvr2_channel_create_mpeg_stream(fh->dev_info->stream);
+	if (!fh->rhp) {
+		pvr2_channel_claim_stream(&fh->channel,NULL);
+		return -ENOMEM;
+	}
+
+	hdw = fh->channel.mc_head->hdw;
+	sp = fh->dev_info->stream->stream;
+	pvr2_stream_set_callback(sp,(pvr2_stream_callback)pvr2_v4l2_notify,fh);
+	pvr2_hdw_set_stream_type(hdw,fh->dev_info->config);
+	pvr2_hdw_set_streaming(hdw,!0);
+	ret = pvr2_ioread_set_enabled(fh->rhp,!0);
+
+	return ret;
+}
+
+
+static ssize_t pvr2_v4l2_read(struct file *file,
+			      char __user *buff, size_t count, loff_t *ppos)
+{
+	struct pvr2_v4l2_fh *fh = file->private_data;
+	int ret;
+
+	if (fh->fw_mode_flag) {
+		struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
+		char *tbuf;
+		int c1,c2;
+		int tcnt = 0;
+		unsigned int offs = *ppos;
+
+		tbuf = kmalloc(PAGE_SIZE,GFP_KERNEL);
+		if (!tbuf) return -ENOMEM;
+
+		while (count) {
+			c1 = count;
+			if (c1 > PAGE_SIZE) c1 = PAGE_SIZE;
+			c2 = pvr2_hdw_cpufw_get(hdw,offs,tbuf,c1);
+			if (c2 < 0) {
+				tcnt = c2;
+				break;
+			}
+			if (!c2) break;
+			if (copy_to_user(buff,tbuf,c2)) {
+				tcnt = -EFAULT;
+				break;
+			}
+			offs += c2;
+			tcnt += c2;
+			buff += c2;
+			count -= c2;
+			*ppos += c2;
+		}
+		kfree(tbuf);
+		return tcnt;
+	}
+
+	if (!fh->rhp) {
+		ret = pvr2_v4l2_iosetup(fh);
+		if (ret) {
+			return ret;
+		}
+	}
+
+	for (;;) {
+		ret = pvr2_ioread_read(fh->rhp,buff,count);
+		if (ret >= 0) break;
+		if (ret != -EAGAIN) break;
+		if (file->f_flags & O_NONBLOCK) break;
+		/* Doing blocking I/O.  Wait here. */
+		ret = wait_event_interruptible(
+			fh->wait_data,
+			pvr2_ioread_avail(fh->rhp) >= 0);
+		if (ret < 0) break;
+	}
+
+	return ret;
+}
+
+
+static unsigned int pvr2_v4l2_poll(struct file *file, poll_table *wait)
+{
+	unsigned int mask = 0;
+	struct pvr2_v4l2_fh *fh = file->private_data;
+	int ret;
+
+	if (fh->fw_mode_flag) {
+		mask |= POLLIN | POLLRDNORM;
+		return mask;
+	}
+
+	if (!fh->rhp) {
+		ret = pvr2_v4l2_iosetup(fh);
+		if (ret) return POLLERR;
+	}
+
+	poll_wait(file,&fh->wait_data,wait);
+
+	if (pvr2_ioread_avail(fh->rhp) >= 0) {
+		mask |= POLLIN | POLLRDNORM;
+	}
+
+	return mask;
+}
+
+
+static struct file_operations vdev_fops = {
+	.owner      = THIS_MODULE,
+	.open       = pvr2_v4l2_open,
+	.release    = pvr2_v4l2_release,
+	.read       = pvr2_v4l2_read,
+	.ioctl      = pvr2_v4l2_ioctl,
+	.llseek     = no_llseek,
+	.poll       = pvr2_v4l2_poll,
+};
+
+
+#define VID_HARDWARE_PVRUSB2    38  /* FIXME : need a good value */
+
+static struct video_device vdev_template = {
+	.owner      = THIS_MODULE,
+	.type       = VID_TYPE_CAPTURE | VID_TYPE_TUNER,
+	.type2      = (V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VBI_CAPTURE
+		       | V4L2_CAP_TUNER | V4L2_CAP_AUDIO
+		       | V4L2_CAP_READWRITE),
+	.hardware   = VID_HARDWARE_PVRUSB2,
+	.fops       = &vdev_fops,
+};
+
+
+static void pvr2_v4l2_dev_init(struct pvr2_v4l2_dev *dip,
+			       struct pvr2_v4l2 *vp,
+			       enum pvr2_config cfg)
+{
+	int mindevnum;
+	int unit_number;
+	int v4l_type;
+	dip->v4lp = vp;
+	dip->config = cfg;
+
+
+	switch (cfg) {
+	case pvr2_config_mpeg:
+		v4l_type = VFL_TYPE_GRABBER;
+		dip->stream = &vp->channel.mc_head->video_stream;
+		break;
+	case pvr2_config_vbi:
+		v4l_type = VFL_TYPE_VBI;
+		break;
+	case pvr2_config_radio:
+		v4l_type = VFL_TYPE_RADIO;
+		break;
+	default:
+		/* Bail out (this should be impossible) */
+		err("Failed to set up pvrusb2 v4l dev"
+		    " due to unrecognized config");
+		return;
+	}
+
+	if (!dip->stream) {
+		err("Failed to set up pvrusb2 v4l dev"
+		    " due to missing stream instance");
+		return;
+	}
+
+	dip->vdev = video_device_alloc();
+	if (!dip->vdev) {
+		err("Alloc of pvrusb2 v4l video device failed");
+		return;
+	}
+
+	memcpy(dip->vdev,&vdev_template,sizeof(vdev_template));
+	dip->vdev->release = video_device_release;
+	video_set_drvdata(dip->vdev,dip);
+
+	mindevnum = -1;
+	unit_number = pvr2_hdw_get_unit_number(vp->channel.mc_head->hdw);
+	if ((unit_number >= 0) && (unit_number < PVR_NUM)) {
+		mindevnum = video_nr[unit_number];
+	}
+	if ((video_register_device(dip->vdev, v4l_type, mindevnum) < 0) &&
+	    (video_register_device(dip->vdev, v4l_type, -1) < 0)) {
+		err("Failed to register pvrusb2 v4l video device");
+	} else {
+		printk(KERN_INFO "pvrusb2: registered device video%d [%s]\n",
+		       dip->vdev->minor,pvr2_config_get_name(dip->config));
+	}
+
+
+	pvr2_hdw_v4l_store_minor_number(vp->channel.mc_head->hdw,
+					dip->vdev->minor);
+}
+
+
+struct pvr2_v4l2 *pvr2_v4l2_create(struct pvr2_context *mnp)
+{
+	struct pvr2_v4l2 *vp;
+
+	vp = kmalloc(sizeof(*vp),GFP_KERNEL);
+	if (!vp) return vp;
+	memset(vp,0,sizeof(*vp));
+	pvr2_channel_init(&vp->channel,mnp);
+	pvr2_trace(PVR2_TRACE_STRUCT,"Creating pvr2_v4l2 id=%p",vp);
+
+	vp->channel.check_func = pvr2_v4l2_internal_check;
+
+	/* register streams */
+	pvr2_v4l2_dev_init(&vp->video_dev,vp,pvr2_config_mpeg);
+
+
+	return vp;
+}
+
+/*
+  Stuff for Emacs to see, in order to encourage consistent editing style:
+  *** Local Variables: ***
+  *** mode: c ***
+  *** fill-column: 75 ***
+  *** tab-width: 8 ***
+  *** c-basic-offset: 8 ***
+  *** End: ***
+  */
diff --git a/drivers/media/video/pvrusb2/pvrusb2-v4l2.h b/drivers/media/video/pvrusb2/pvrusb2-v4l2.h
new file mode 100644
index 000000000..9a995e2d2
--- /dev/null
+++ b/drivers/media/video/pvrusb2/pvrusb2-v4l2.h
@@ -0,0 +1,40 @@
+/*
+ *
+ *  $Id$
+ *
+ *  Copyright (C) 2005 Mike Isely <isely@pobox.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
+ *
+ *  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 __PVRUSB2_V4L2_H
+#define __PVRUSB2_V4L2_H
+
+#include "pvrusb2-context.h"
+
+struct pvr2_v4l2;
+
+struct pvr2_v4l2 *pvr2_v4l2_create(struct pvr2_context *);
+
+#endif /* __PVRUSB2_V4L2_H */
+
+/*
+  Stuff for Emacs to see, in order to encourage consistent editing style:
+  *** Local Variables: ***
+  *** mode: c ***
+  *** fill-column: 75 ***
+  *** tab-width: 8 ***
+  *** c-basic-offset: 8 ***
+  *** End: ***
+  */
diff --git a/drivers/media/video/pvrusb2/pvrusb2-video-v4l.c b/drivers/media/video/pvrusb2/pvrusb2-video-v4l.c
new file mode 100644
index 000000000..05f2cddeb
--- /dev/null
+++ b/drivers/media/video/pvrusb2/pvrusb2-video-v4l.c
@@ -0,0 +1,253 @@
+/*
+ *
+ *  $Id$
+ *
+ *  Copyright (C) 2005 Mike Isely <isely@pobox.com>
+ *  Copyright (C) 2004 Aurelien Alleaume <slts@free.fr>
+ *
+ *  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
+ *
+ *  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
+ *
+ */
+
+/*
+
+   This source file is specifically designed to interface with the
+   saa711x support that is available in the v4l available starting
+   with linux 2.6.15.
+
+*/
+
+#include "pvrusb2-video-v4l.h"
+#include "pvrusb2-i2c-cmd-v4l2.h"
+
+
+#include "pvrusb2-hdw-internal.h"
+#include "pvrusb2-debug.h"
+#include <linux/videodev2.h>
+#include <media/v4l2-common.h>
+#include <media/saa7115.h>
+#include <linux/errno.h>
+#include <linux/slab.h>
+
+struct pvr2_v4l_decoder {
+	struct pvr2_i2c_handler handler;
+	struct pvr2_decoder_ctrl ctrl;
+	struct pvr2_i2c_client *client;
+	struct pvr2_hdw *hdw;
+	unsigned long stale_mask;
+};
+
+
+static void set_input(struct pvr2_v4l_decoder *ctxt)
+{
+	struct pvr2_hdw *hdw = ctxt->hdw;
+	struct v4l2_routing route;
+
+	pvr2_trace(PVR2_TRACE_CHIPS,"i2c v4l2 set_input(%d)",hdw->input_val);
+	switch(hdw->input_val) {
+	case PVR2_CVAL_INPUT_TV:
+		route.input = SAA7115_COMPOSITE4;
+		break;
+	case PVR2_CVAL_INPUT_COMPOSITE:
+		route.input = SAA7115_COMPOSITE5;
+		break;
+	case PVR2_CVAL_INPUT_SVIDEO:
+		route.input = SAA7115_SVIDEO2;
+		break;
+	case PVR2_CVAL_INPUT_RADIO:
+		// ????? No idea yet what to do here
+	default:
+		return;
+	}
+	route.output = 0;
+	pvr2_i2c_client_cmd(ctxt->client,VIDIOC_INT_S_VIDEO_ROUTING,&route);
+}
+
+
+static int check_input(struct pvr2_v4l_decoder *ctxt)
+{
+	struct pvr2_hdw *hdw = ctxt->hdw;
+	return hdw->input_dirty != 0;
+}
+
+
+static void set_audio(struct pvr2_v4l_decoder *ctxt)
+{
+	u32 val;
+	struct pvr2_hdw *hdw = ctxt->hdw;
+
+	pvr2_trace(PVR2_TRACE_CHIPS,"i2c v4l2 set_audio %d",
+		   hdw->srate_val);
+	switch (hdw->srate_val) {
+	default:
+	case V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000:
+		val = 48000;
+		break;
+	case V4L2_MPEG_AUDIO_SAMPLING_FREQ_44100:
+		val = 44100;
+		break;
+	case V4L2_MPEG_AUDIO_SAMPLING_FREQ_32000:
+		val = 32000;
+		break;
+	}
+	pvr2_i2c_client_cmd(ctxt->client,VIDIOC_INT_AUDIO_CLOCK_FREQ,&val);
+}
+
+
+static int check_audio(struct pvr2_v4l_decoder *ctxt)
+{
+	struct pvr2_hdw *hdw = ctxt->hdw;
+	return hdw->srate_dirty != 0;
+}
+
+
+struct pvr2_v4l_decoder_ops {
+	void (*update)(struct pvr2_v4l_decoder *);
+	int (*check)(struct pvr2_v4l_decoder *);
+};
+
+
+static const struct pvr2_v4l_decoder_ops decoder_ops[] = {
+	{ .update = set_input, .check = check_input},
+	{ .update = set_audio, .check = check_audio},
+};
+
+
+static void decoder_detach(struct pvr2_v4l_decoder *ctxt)
+{
+	ctxt->client->handler = NULL;
+	ctxt->hdw->decoder_ctrl = NULL;
+	kfree(ctxt);
+}
+
+
+static int decoder_check(struct pvr2_v4l_decoder *ctxt)
+{
+	unsigned long msk;
+	unsigned int idx;
+
+	for (idx = 0; idx < sizeof(decoder_ops)/sizeof(decoder_ops[0]);
+	     idx++) {
+		msk = 1 << idx;
+		if (ctxt->stale_mask & msk) continue;
+		if (decoder_ops[idx].check(ctxt)) {
+			ctxt->stale_mask |= msk;
+		}
+	}
+	return ctxt->stale_mask != 0;
+}
+
+
+static void decoder_update(struct pvr2_v4l_decoder *ctxt)
+{
+	unsigned long msk;
+	unsigned int idx;
+
+	for (idx = 0; idx < sizeof(decoder_ops)/sizeof(decoder_ops[0]);
+	     idx++) {
+		msk = 1 << idx;
+		if (!(ctxt->stale_mask & msk)) continue;
+		ctxt->stale_mask &= ~msk;
+		decoder_ops[idx].update(ctxt);
+	}
+}
+
+
+static int decoder_detect(struct pvr2_i2c_client *cp)
+{
+	/* Attempt to query the decoder - let's see if it will answer */
+	struct v4l2_tuner vt;
+	int ret;
+
+	memset(&vt,0,sizeof(vt));
+	ret = pvr2_i2c_client_cmd(cp,VIDIOC_G_TUNER,&vt);
+	return ret == 0; /* Return true if it answered */
+}
+
+
+static void decoder_enable(struct pvr2_v4l_decoder *ctxt,int fl)
+{
+	pvr2_trace(PVR2_TRACE_CHIPS,"i2c v4l2 decoder_enable(%d)",fl);
+	pvr2_v4l2_cmd_stream(ctxt->client,fl);
+}
+
+
+static int decoder_is_tuned(struct pvr2_v4l_decoder *ctxt)
+{
+	struct v4l2_tuner vt;
+	int ret;
+
+	memset(&vt,0,sizeof(vt));
+	ret = pvr2_i2c_client_cmd(ctxt->client,VIDIOC_G_TUNER,&vt);
+	if (ret < 0) return -EINVAL;
+	return vt.signal ? 1 : 0;
+}
+
+
+static unsigned int decoder_describe(struct pvr2_v4l_decoder *ctxt,char *buf,unsigned int cnt)
+{
+	return scnprintf(buf,cnt,"handler: pvrusb2-video-v4l");
+}
+
+
+const static struct pvr2_i2c_handler_functions hfuncs = {
+	.detach = (void (*)(void *))decoder_detach,
+	.check = (int (*)(void *))decoder_check,
+	.update = (void (*)(void *))decoder_update,
+	.describe = (unsigned int (*)(void *,char *,unsigned int))decoder_describe,
+};
+
+
+int pvr2_i2c_decoder_v4l_setup(struct pvr2_hdw *hdw,
+			       struct pvr2_i2c_client *cp)
+{
+	struct pvr2_v4l_decoder *ctxt;
+
+	if (hdw->decoder_ctrl) return 0;
+	if (cp->handler) return 0;
+	if (!decoder_detect(cp)) return 0;
+
+	ctxt = kmalloc(sizeof(*ctxt),GFP_KERNEL);
+	if (!ctxt) return 0;
+	memset(ctxt,0,sizeof(*ctxt));
+
+	ctxt->handler.func_data = ctxt;
+	ctxt->handler.func_table = &hfuncs;
+	ctxt->ctrl.ctxt = ctxt;
+	ctxt->ctrl.detach = (void (*)(void *))decoder_detach;
+	ctxt->ctrl.enable = (void (*)(void *,int))decoder_enable;
+	ctxt->ctrl.tuned = (int (*)(void *))decoder_is_tuned;
+	ctxt->client = cp;
+	ctxt->hdw = hdw;
+	ctxt->stale_mask = (1 << (sizeof(decoder_ops)/
+				  sizeof(decoder_ops[0]))) - 1;
+	hdw->decoder_ctrl = &ctxt->ctrl;
+	cp->handler = &ctxt->handler;
+	pvr2_trace(PVR2_TRACE_CHIPS,"i2c 0x%x saa711x V4L2 handler set up",
+		   cp->client->addr);
+	return !0;
+}
+
+
+
+
+/*
+  Stuff for Emacs to see, in order to encourage consistent editing style:
+  *** Local Variables: ***
+  *** mode: c ***
+  *** fill-column: 70 ***
+  *** tab-width: 8 ***
+  *** c-basic-offset: 8 ***
+  *** End: ***
+  */
diff --git a/drivers/media/video/pvrusb2/pvrusb2-video-v4l.h b/drivers/media/video/pvrusb2/pvrusb2-video-v4l.h
new file mode 100644
index 000000000..2b917fda0
--- /dev/null
+++ b/drivers/media/video/pvrusb2/pvrusb2-video-v4l.h
@@ -0,0 +1,52 @@
+/*
+ *
+ *  $Id$
+ *
+ *  Copyright (C) 2005 Mike Isely <isely@pobox.com>
+ *  Copyright (C) 2004 Aurelien Alleaume <slts@free.fr>
+ *
+ *  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
+ *
+ *  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 __PVRUSB2_VIDEO_V4L_H
+#define __PVRUSB2_VIDEO_V4L_H
+
+/*
+
+   This module connects the pvrusb2 driver to the I2C chip level
+   driver which handles device video processing.  This interface is
+   used internally by the driver; higher level code should only
+   interact through the interface provided by pvrusb2-hdw.h.
+
+*/
+
+
+
+#include "pvrusb2-i2c-core.h"
+
+int pvr2_i2c_decoder_v4l_setup(struct pvr2_hdw *,struct pvr2_i2c_client *);
+
+
+#endif /* __PVRUSB2_VIDEO_V4L_H */
+
+/*
+  Stuff for Emacs to see, in order to encourage consistent editing style:
+  *** Local Variables: ***
+  *** mode: c ***
+  *** fill-column: 70 ***
+  *** tab-width: 8 ***
+  *** c-basic-offset: 8 ***
+  *** End: ***
+  */
diff --git a/drivers/media/video/pvrusb2/pvrusb2-wm8775.c b/drivers/media/video/pvrusb2/pvrusb2-wm8775.c
new file mode 100644
index 000000000..2413e5198
--- /dev/null
+++ b/drivers/media/video/pvrusb2/pvrusb2-wm8775.c
@@ -0,0 +1,170 @@
+/*
+ *
+ *  $Id$
+ *
+ *  Copyright (C) 2005 Mike Isely <isely@pobox.com>
+ *  Copyright (C) 2004 Aurelien Alleaume <slts@free.fr>
+ *
+ *  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
+ *
+ *  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
+ *
+ */
+
+/*
+
+   This source file is specifically designed to interface with the
+   wm8775.
+
+*/
+
+#include "pvrusb2-wm8775.h"
+#include "pvrusb2-i2c-cmd-v4l2.h"
+
+
+#include "pvrusb2-hdw-internal.h"
+#include "pvrusb2-debug.h"
+#include <linux/videodev2.h>
+#include <media/v4l2-common.h>
+#include <linux/errno.h>
+#include <linux/slab.h>
+
+struct pvr2_v4l_wm8775 {
+	struct pvr2_i2c_handler handler;
+	struct pvr2_i2c_client *client;
+	struct pvr2_hdw *hdw;
+	unsigned long stale_mask;
+};
+
+
+static void set_input(struct pvr2_v4l_wm8775 *ctxt)
+{
+	struct v4l2_routing route;
+	struct pvr2_hdw *hdw = ctxt->hdw;
+	int msk = 0;
+
+	memset(&route,0,sizeof(route));
+
+	pvr2_trace(PVR2_TRACE_CHIPS,"i2c wm8775 set_input(val=%d msk=0x%x)",
+		   hdw->input_val,msk);
+
+	// Always point to input #1 no matter what
+	route.input = 2;
+	pvr2_i2c_client_cmd(ctxt->client,VIDIOC_INT_S_AUDIO_ROUTING,&route);
+}
+
+static int check_input(struct pvr2_v4l_wm8775 *ctxt)
+{
+	struct pvr2_hdw *hdw = ctxt->hdw;
+	return hdw->input_dirty != 0;
+}
+
+
+struct pvr2_v4l_wm8775_ops {
+	void (*update)(struct pvr2_v4l_wm8775 *);
+	int (*check)(struct pvr2_v4l_wm8775 *);
+};
+
+
+static const struct pvr2_v4l_wm8775_ops wm8775_ops[] = {
+	{ .update = set_input, .check = check_input},
+};
+
+
+static unsigned int wm8775_describe(struct pvr2_v4l_wm8775 *ctxt,
+				     char *buf,unsigned int cnt)
+{
+	return scnprintf(buf,cnt,"handler: pvrusb2-wm8775");
+}
+
+
+static void wm8775_detach(struct pvr2_v4l_wm8775 *ctxt)
+{
+	ctxt->client->handler = NULL;
+	kfree(ctxt);
+}
+
+
+static int wm8775_check(struct pvr2_v4l_wm8775 *ctxt)
+{
+	unsigned long msk;
+	unsigned int idx;
+
+	for (idx = 0; idx < sizeof(wm8775_ops)/sizeof(wm8775_ops[0]);
+	     idx++) {
+		msk = 1 << idx;
+		if (ctxt->stale_mask & msk) continue;
+		if (wm8775_ops[idx].check(ctxt)) {
+			ctxt->stale_mask |= msk;
+		}
+	}
+	return ctxt->stale_mask != 0;
+}
+
+
+static void wm8775_update(struct pvr2_v4l_wm8775 *ctxt)
+{
+	unsigned long msk;
+	unsigned int idx;
+
+	for (idx = 0; idx < sizeof(wm8775_ops)/sizeof(wm8775_ops[0]);
+	     idx++) {
+		msk = 1 << idx;
+		if (!(ctxt->stale_mask & msk)) continue;
+		ctxt->stale_mask &= ~msk;
+		wm8775_ops[idx].update(ctxt);
+	}
+}
+
+
+const static struct pvr2_i2c_handler_functions hfuncs = {
+	.detach = (void (*)(void *))wm8775_detach,
+	.check = (int (*)(void *))wm8775_check,
+	.update = (void (*)(void *))wm8775_update,
+	.describe = (unsigned int (*)(void *,char *,unsigned int))wm8775_describe,
+};
+
+
+int pvr2_i2c_wm8775_setup(struct pvr2_hdw *hdw,struct pvr2_i2c_client *cp)
+{
+	struct pvr2_v4l_wm8775 *ctxt;
+
+	if (cp->handler) return 0;
+
+	ctxt = kmalloc(sizeof(*ctxt),GFP_KERNEL);
+	if (!ctxt) return 0;
+	memset(ctxt,0,sizeof(*ctxt));
+
+	ctxt->handler.func_data = ctxt;
+	ctxt->handler.func_table = &hfuncs;
+	ctxt->client = cp;
+	ctxt->hdw = hdw;
+	ctxt->stale_mask = (1 << (sizeof(wm8775_ops)/
+				  sizeof(wm8775_ops[0]))) - 1;
+	cp->handler = &ctxt->handler;
+	pvr2_trace(PVR2_TRACE_CHIPS,"i2c 0x%x wm8775 V4L2 handler set up",
+		   cp->client->addr);
+	return !0;
+}
+
+
+
+
+/*
+  Stuff for Emacs to see, in order to encourage consistent editing style:
+  *** Local Variables: ***
+  *** mode: c ***
+  *** fill-column: 70 ***
+  *** tab-width: 8 ***
+  *** c-basic-offset: 8 ***
+  *** End: ***
+  */
diff --git a/drivers/media/video/pvrusb2/pvrusb2-wm8775.h b/drivers/media/video/pvrusb2/pvrusb2-wm8775.h
new file mode 100644
index 000000000..8aaeff4e1
--- /dev/null
+++ b/drivers/media/video/pvrusb2/pvrusb2-wm8775.h
@@ -0,0 +1,53 @@
+/*
+ *
+ *  $Id$
+ *
+ *  Copyright (C) 2005 Mike Isely <isely@pobox.com>
+ *  Copyright (C) 2004 Aurelien Alleaume <slts@free.fr>
+ *
+ *  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
+ *
+ *  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 __PVRUSB2_WM8775_H
+#define __PVRUSB2_WM8775_H
+
+/*
+
+   This module connects the pvrusb2 driver to the I2C chip level
+   driver which performs analog -> digital audio conversion for
+   external audio inputs.  This interface is used internally by the
+   driver; higher level code should only interact through the
+   interface provided by pvrusb2-hdw.h.
+
+*/
+
+
+
+#include "pvrusb2-i2c-core.h"
+
+int pvr2_i2c_wm8775_setup(struct pvr2_hdw *,struct pvr2_i2c_client *);
+
+
+#endif /* __PVRUSB2_WM8775_H */
+
+/*
+  Stuff for Emacs to see, in order to encourage consistent editing style:
+  *** Local Variables: ***
+  *** mode: c ***
+  *** fill-column: 70 ***
+  *** tab-width: 8 ***
+  *** c-basic-offset: 8 ***
+  *** End: ***
+  */
diff --git a/drivers/media/video/pvrusb2/pvrusb2.h b/drivers/media/video/pvrusb2/pvrusb2.h
new file mode 100644
index 000000000..074533e9c
--- /dev/null
+++ b/drivers/media/video/pvrusb2/pvrusb2.h
@@ -0,0 +1,43 @@
+/*
+ *
+ *  $Id$
+ *
+ *  Copyright (C) 2005 Mike Isely <isely@pobox.com>
+ *  Copyright (C) 2004 Aurelien Alleaume <slts@free.fr>
+ *
+ *  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
+ *
+ *  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 __PVRUSB2_H
+#define __PVRUSB2_H
+
+/* Maximum number of pvrusb2 instances we can track at once.  You
+   might want to increase this - however the driver operation will not
+   be impaired if it is too small.  Instead additional units just
+   won't have an ID assigned and it might not be possible to specify
+   module paramters for those extra units. */
+#define PVR_NUM 20
+
+#endif /* __PVRUSB2_H */
+
+/*
+  Stuff for Emacs to see, in order to encourage consistent editing style:
+  *** Local Variables: ***
+  *** mode: c ***
+  *** fill-column: 70 ***
+  *** tab-width: 8 ***
+  *** c-basic-offset: 8 ***
+  *** End: ***
+  */
diff --git a/drivers/media/video/pwc/pwc-dec1.c b/drivers/media/video/pwc/pwc-dec1.c
new file mode 100644
index 000000000..c29593f58
--- /dev/null
+++ b/drivers/media/video/pwc/pwc-dec1.c
@@ -0,0 +1,50 @@
+/* Linux driver for Philips webcam
+   Decompression for chipset version 1
+   (C) 2004-2006 Luc Saillard (luc@saillard.org)
+
+   NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx
+   driver and thus may have bugs that are not present in the original version.
+   Please send bug reports and support requests to <luc@saillard.org>.
+   The decompression routines have been implemented by reverse-engineering the
+   Nemosoft binary pwcx module. Caveat emptor.
+
+   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 "pwc-dec1.h"
+
+
+void pwc_dec1_init(int type, int release, void *buffer, void *table)
+{
+
+}
+
+void pwc_dec1_exit(void)
+{
+
+
+
+}
+
+int pwc_dec1_alloc(struct pwc_device *pwc)
+{
+	pwc->decompress_data = kmalloc(sizeof(struct pwc_dec1_private), GFP_KERNEL);
+	if (pwc->decompress_data == NULL)
+		return -ENOMEM;
+	return 0;
+}
+
diff --git a/drivers/media/video/pwc/pwc-dec1.h b/drivers/media/video/pwc/pwc-dec1.h
new file mode 100644
index 000000000..8b62ddcc5
--- /dev/null
+++ b/drivers/media/video/pwc/pwc-dec1.h
@@ -0,0 +1,43 @@
+/* Linux driver for Philips webcam
+   (C) 2004-2006 Luc Saillard (luc@saillard.org)
+
+   NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx
+   driver and thus may have bugs that are not present in the original version.
+   Please send bug reports and support requests to <luc@saillard.org>.
+   The decompression routines have been implemented by reverse-engineering the
+   Nemosoft binary pwcx module. Caveat emptor.
+
+   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
+*/
+
+
+
+#ifndef PWC_DEC1_H
+#define PWC_DEC1_H
+
+#include "pwc.h"
+
+struct pwc_dec1_private
+{
+	int version;
+
+};
+
+int  pwc_dec1_alloc(struct pwc_device *pwc);
+void pwc_dec1_init(int type, int release, void *buffer, void *private_data);
+void pwc_dec1_exit(void);
+
+#endif
+
diff --git a/drivers/media/video/pwc/pwc-dec23.c b/drivers/media/video/pwc/pwc-dec23.c
new file mode 100644
index 000000000..9e2d91f26
--- /dev/null
+++ b/drivers/media/video/pwc/pwc-dec23.c
@@ -0,0 +1,941 @@
+/* Linux driver for Philips webcam
+   Decompression for chipset version 2 et 3
+   (C) 2004-2006  Luc Saillard (luc@saillard.org)
+
+   NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx
+   driver and thus may have bugs that are not present in the original version.
+   Please send bug reports and support requests to <luc@saillard.org>.
+   The decompression routines have been implemented by reverse-engineering the
+   Nemosoft binary pwcx module. Caveat emptor.
+
+   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 "pwc-timon.h"
+#include "pwc-kiara.h"
+#include "pwc-dec23.h"
+#include <media/pwc-ioctl.h>
+
+#include <linux/string.h>
+
+/*
+ * USE_LOOKUP_TABLE_TO_CLAMP
+ *   0: use a C version of this tests:  {  a<0?0:(a>255?255:a) }
+ *   1: use a faster lookup table for cpu with a big cache (intel)
+ */
+#define USE_LOOKUP_TABLE_TO_CLAMP	1
+/*
+ * UNROLL_LOOP_FOR_COPYING_BLOCK
+ *   0: use a loop for a smaller code (but little slower)
+ *   1: when unrolling the loop, gcc produces some faster code (perhaps only
+ *   valid for intel processor class). Activating this option, automaticaly
+ *   activate USE_LOOKUP_TABLE_TO_CLAMP
+ */
+#define UNROLL_LOOP_FOR_COPY		1
+#if UNROLL_LOOP_FOR_COPY
+# undef USE_LOOKUP_TABLE_TO_CLAMP
+# define USE_LOOKUP_TABLE_TO_CLAMP 1
+#endif
+
+/*
+ * ENABLE_BAYER_DECODER
+ *   0: bayer decoder is not build (save some space)
+ *   1: bayer decoder is build and can be used
+ */
+#define ENABLE_BAYER_DECODER 0
+
+static void build_subblock_pattern(struct pwc_dec23_private *pdec)
+{
+	static const unsigned int initial_values[12] = {
+		-0x526500, -0x221200, 0x221200, 0x526500,
+			   -0x3de200, 0x3de200,
+		-0x6db480, -0x2d5d00, 0x2d5d00, 0x6db480,
+			   -0x12c200, 0x12c200
+
+	};
+	static const unsigned int values_derivated[12] = {
+		0xa4ca, 0x4424, -0x4424, -0xa4ca,
+			0x7bc4, -0x7bc4,
+		0xdb69, 0x5aba, -0x5aba, -0xdb69,
+			0x2584, -0x2584
+	};
+	unsigned int temp_values[12];
+	int i, j;
+
+	memcpy(temp_values, initial_values, sizeof(initial_values));
+	for (i = 0; i < 256; i++) {
+		for (j = 0; j < 12; j++) {
+			pdec->table_subblock[i][j] = temp_values[j];
+			temp_values[j] += values_derivated[j];
+		}
+	}
+}
+
+static void build_bit_powermask_table(struct pwc_dec23_private *pdec)
+{
+	unsigned char *p;
+	unsigned int bit, byte, mask, val;
+	unsigned int bitpower = 1;
+
+	for (bit = 0; bit < 8; bit++) {
+		mask = bitpower - 1;
+		p = pdec->table_bitpowermask[bit];
+		for (byte = 0; byte < 256; byte++) {
+			val = (byte & mask);
+			if (byte & bitpower)
+				val = -val;
+			*p++ = val;
+		}
+		bitpower<<=1;
+	}
+}
+
+
+static void build_table_color(const unsigned int romtable[16][8],
+			      unsigned char p0004[16][1024],
+			      unsigned char p8004[16][256])
+{
+	int compression_mode, j, k, bit, pw;
+	unsigned char *p0, *p8;
+	const unsigned int *r;
+
+	/* We have 16 compressions tables */
+	for (compression_mode = 0; compression_mode < 16; compression_mode++) {
+		p0 = p0004[compression_mode];
+		p8 = p8004[compression_mode];
+		r  = romtable[compression_mode];
+
+		for (j = 0; j < 8; j++, r++, p0 += 128) {
+
+			for (k = 0; k < 16; k++) {
+				if (k == 0)
+					bit = 1;
+				else if (k >= 1 && k < 3)
+					bit = (r[0] >> 15) & 7;
+				else if (k >= 3 && k < 6)
+					bit = (r[0] >> 12) & 7;
+				else if (k >= 6 && k < 10)
+					bit = (r[0] >> 9) & 7;
+				else if (k >= 10 && k < 13)
+					bit = (r[0] >> 6) & 7;
+				else if (k >= 13 && k < 15)
+					bit = (r[0] >> 3) & 7;
+				else
+					bit = (r[0]) & 7;
+				if (k == 0)
+					*p8++ = 8;
+				else
+					*p8++ = j - bit;
+				*p8++ = bit;
+
+				pw = 1 << bit;
+				p0[k + 0x00] = (1 * pw) + 0x80;
+				p0[k + 0x10] = (2 * pw) + 0x80;
+				p0[k + 0x20] = (3 * pw) + 0x80;
+				p0[k + 0x30] = (4 * pw) + 0x80;
+				p0[k + 0x40] = (-1 * pw) + 0x80;
+				p0[k + 0x50] = (-2 * pw) + 0x80;
+				p0[k + 0x60] = (-3 * pw) + 0x80;
+				p0[k + 0x70] = (-4 * pw) + 0x80;
+			}	/* end of for (k=0; k<16; k++, p8++) */
+		}	/* end of for (j=0; j<8; j++ , table++) */
+	} /* end of foreach compression_mode */
+}
+
+/*
+ *
+ */
+static void fill_table_dc00_d800(struct pwc_dec23_private *pdec)
+{
+#define SCALEBITS 15
+#define ONE_HALF  (1UL << (SCALEBITS - 1))
+	int i;
+	unsigned int offset1 = ONE_HALF;
+	unsigned int offset2 = 0x0000;
+
+	for (i=0; i<256; i++) {
+		pdec->table_dc00[i] = offset1 & ~(ONE_HALF);
+		pdec->table_d800[i] = offset2;
+
+		offset1 += 0x7bc4;
+		offset2 += 0x7bc4;
+	}
+}
+
+/*
+ * To decode the stream:
+ *   if look_bits(2) == 0:	# op == 2 in the lookup table
+ *      skip_bits(2)
+ *      end of the stream
+ *   elif look_bits(3) == 7:	# op == 1 in the lookup table
+ *      skip_bits(3)
+ *      yyyy = get_bits(4)
+ *      xxxx = get_bits(8)
+ *   else:			# op == 0 in the lookup table
+ *      skip_bits(x)
+ *
+ * For speedup processing, we build a lookup table and we takes the first 6 bits.
+ *
+ * struct {
+ *   unsigned char op;	    // operation to execute
+ *   unsigned char bits;    // bits use to perform operation
+ *   unsigned char offset1; // offset to add to access in the table_0004 % 16
+ *   unsigned char offset2; // offset to add to access in the table_0004
+ * }
+ *
+ * How to build this table ?
+ *   op == 2 when (i%4)==0
+ *   op == 1 when (i%8)==7
+ *   op == 0 otherwise
+ *
+ */
+static const unsigned char hash_table_ops[64*4] = {
+	0x02, 0x00, 0x00, 0x00,
+	0x00, 0x03, 0x01, 0x00,
+	0x00, 0x04, 0x01, 0x10,
+	0x00, 0x06, 0x01, 0x30,
+	0x02, 0x00, 0x00, 0x00,
+	0x00, 0x03, 0x01, 0x40,
+	0x00, 0x05, 0x01, 0x20,
+	0x01, 0x00, 0x00, 0x00,
+	0x02, 0x00, 0x00, 0x00,
+	0x00, 0x03, 0x01, 0x00,
+	0x00, 0x04, 0x01, 0x50,
+	0x00, 0x05, 0x02, 0x00,
+	0x02, 0x00, 0x00, 0x00,
+	0x00, 0x03, 0x01, 0x40,
+	0x00, 0x05, 0x03, 0x00,
+	0x01, 0x00, 0x00, 0x00,
+	0x02, 0x00, 0x00, 0x00,
+	0x00, 0x03, 0x01, 0x00,
+	0x00, 0x04, 0x01, 0x10,
+	0x00, 0x06, 0x02, 0x10,
+	0x02, 0x00, 0x00, 0x00,
+	0x00, 0x03, 0x01, 0x40,
+	0x00, 0x05, 0x01, 0x60,
+	0x01, 0x00, 0x00, 0x00,
+	0x02, 0x00, 0x00, 0x00,
+	0x00, 0x03, 0x01, 0x00,
+	0x00, 0x04, 0x01, 0x50,
+	0x00, 0x05, 0x02, 0x40,
+	0x02, 0x00, 0x00, 0x00,
+	0x00, 0x03, 0x01, 0x40,
+	0x00, 0x05, 0x03, 0x40,
+	0x01, 0x00, 0x00, 0x00,
+	0x02, 0x00, 0x00, 0x00,
+	0x00, 0x03, 0x01, 0x00,
+	0x00, 0x04, 0x01, 0x10,
+	0x00, 0x06, 0x01, 0x70,
+	0x02, 0x00, 0x00, 0x00,
+	0x00, 0x03, 0x01, 0x40,
+	0x00, 0x05, 0x01, 0x20,
+	0x01, 0x00, 0x00, 0x00,
+	0x02, 0x00, 0x00, 0x00,
+	0x00, 0x03, 0x01, 0x00,
+	0x00, 0x04, 0x01, 0x50,
+	0x00, 0x05, 0x02, 0x00,
+	0x02, 0x00, 0x00, 0x00,
+	0x00, 0x03, 0x01, 0x40,
+	0x00, 0x05, 0x03, 0x00,
+	0x01, 0x00, 0x00, 0x00,
+	0x02, 0x00, 0x00, 0x00,
+	0x00, 0x03, 0x01, 0x00,
+	0x00, 0x04, 0x01, 0x10,
+	0x00, 0x06, 0x02, 0x50,
+	0x02, 0x00, 0x00, 0x00,
+	0x00, 0x03, 0x01, 0x40,
+	0x00, 0x05, 0x01, 0x60,
+	0x01, 0x00, 0x00, 0x00,
+	0x02, 0x00, 0x00, 0x00,
+	0x00, 0x03, 0x01, 0x00,
+	0x00, 0x04, 0x01, 0x50,
+	0x00, 0x05, 0x02, 0x40,
+	0x02, 0x00, 0x00, 0x00,
+	0x00, 0x03, 0x01, 0x40,
+	0x00, 0x05, 0x03, 0x40,
+	0x01, 0x00, 0x00, 0x00
+};
+
+/*
+ *
+ */
+static const unsigned int MulIdx[16][16] = {
+	{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,},
+	{0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3,},
+	{0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3,},
+	{4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 4, 4, 4, 4,},
+	{6, 7, 8, 9, 7, 10, 11, 8, 8, 11, 10, 7, 9, 8, 7, 6,},
+	{4, 5, 5, 4, 4, 5, 5, 4, 4, 5, 5, 4, 4, 5, 5, 4,},
+	{1, 3, 0, 2, 1, 3, 0, 2, 1, 3, 0, 2, 1, 3, 0, 2,},
+	{0, 3, 3, 0, 1, 2, 2, 1, 2, 1, 1, 2, 3, 0, 0, 3,},
+	{0, 1, 2, 3, 3, 2, 1, 0, 3, 2, 1, 0, 0, 1, 2, 3,},
+	{1, 1, 1, 1, 3, 3, 3, 3, 0, 0, 0, 0, 2, 2, 2, 2,},
+	{7, 10, 11, 8, 9, 8, 7, 6, 6, 7, 8, 9, 8, 11, 10, 7,},
+	{4, 5, 5, 4, 5, 4, 4, 5, 5, 4, 4, 5, 4, 5, 5, 4,},
+	{7, 9, 6, 8, 10, 8, 7, 11, 11, 7, 8, 10, 8, 6, 9, 7,},
+	{1, 3, 0, 2, 2, 0, 3, 1, 2, 0, 3, 1, 1, 3, 0, 2,},
+	{1, 2, 2, 1, 3, 0, 0, 3, 0, 3, 3, 0, 2, 1, 1, 2,},
+	{10, 8, 7, 11, 8, 6, 9, 7, 7, 9, 6, 8, 11, 7, 8, 10}
+};
+
+#if USE_LOOKUP_TABLE_TO_CLAMP
+#define MAX_OUTER_CROP_VALUE	(512)
+static unsigned char pwc_crop_table[256 + 2*MAX_OUTER_CROP_VALUE];
+#define CLAMP(x) (pwc_crop_table[MAX_OUTER_CROP_VALUE+(x)])
+#else
+#define CLAMP(x) ((x)>255?255:((x)<0?0:x))
+#endif
+
+
+/* If the type or the command change, we rebuild the lookup table */
+int pwc_dec23_init(struct pwc_device *pwc, int type, unsigned char *cmd)
+{
+	int flags, version, shift, i;
+	struct pwc_dec23_private *pdec;
+
+	if (pwc->decompress_data == NULL) {
+		pdec = kmalloc(sizeof(struct pwc_dec23_private), GFP_KERNEL);
+		if (pdec == NULL)
+			return -ENOMEM;
+		pwc->decompress_data = pdec;
+	}
+	pdec = pwc->decompress_data;
+
+	if (DEVICE_USE_CODEC3(type)) {
+		flags = cmd[2] & 0x18;
+		if (flags == 8)
+			pdec->nbits = 7;	/* More bits, mean more bits to encode the stream, but better quality */
+		else if (flags == 0x10)
+			pdec->nbits = 8;
+		else
+			pdec->nbits = 6;
+
+		version = cmd[2] >> 5;
+		build_table_color(KiaraRomTable[version][0], pdec->table_0004_pass1, pdec->table_8004_pass1);
+		build_table_color(KiaraRomTable[version][1], pdec->table_0004_pass2, pdec->table_8004_pass2);
+
+	} else {
+
+		flags = cmd[2] & 6;
+		if (flags == 2)
+			pdec->nbits = 7;
+		else if (flags == 4)
+			pdec->nbits = 8;
+		else
+			pdec->nbits = 6;
+
+		version = cmd[2] >> 3;
+		build_table_color(TimonRomTable[version][0], pdec->table_0004_pass1, pdec->table_8004_pass1);
+		build_table_color(TimonRomTable[version][1], pdec->table_0004_pass2, pdec->table_8004_pass2);
+	}
+
+	/* Informations can be coded on a variable number of bits but never less than 8 */
+	shift = 8 - pdec->nbits;
+	pdec->scalebits = SCALEBITS - shift;
+	pdec->nbitsmask = 0xFF >> shift;
+
+	fill_table_dc00_d800(pdec);
+	build_subblock_pattern(pdec);
+	build_bit_powermask_table(pdec);
+
+#if USE_LOOKUP_TABLE_TO_CLAMP
+	/* Build the static table to clamp value [0-255] */
+	for (i=0;i<MAX_OUTER_CROP_VALUE;i++)
+		pwc_crop_table[i] = 0;
+	for (i=0; i<256; i++)
+		pwc_crop_table[MAX_OUTER_CROP_VALUE+i] = i;
+	for (i=0; i<MAX_OUTER_CROP_VALUE; i++)
+		pwc_crop_table[MAX_OUTER_CROP_VALUE+256+i] = 255;
+#endif
+
+	return 0;
+}
+
+/*
+ * Copy the 4x4 image block to Y plane buffer
+ */
+static void copy_image_block_Y(const int *src, unsigned char *dst, unsigned int bytes_per_line, unsigned int scalebits)
+{
+#if UNROLL_LOOP_FOR_COPY
+	const unsigned char *cm = pwc_crop_table+MAX_OUTER_CROP_VALUE;
+	const int *c = src;
+	unsigned char *d = dst;
+
+	*d++ = cm[c[0] >> scalebits];
+	*d++ = cm[c[1] >> scalebits];
+	*d++ = cm[c[2] >> scalebits];
+	*d++ = cm[c[3] >> scalebits];
+
+	d = dst + bytes_per_line;
+	*d++ = cm[c[4] >> scalebits];
+	*d++ = cm[c[5] >> scalebits];
+	*d++ = cm[c[6] >> scalebits];
+	*d++ = cm[c[7] >> scalebits];
+
+	d = dst + bytes_per_line*2;
+	*d++ = cm[c[8] >> scalebits];
+	*d++ = cm[c[9] >> scalebits];
+	*d++ = cm[c[10] >> scalebits];
+	*d++ = cm[c[11] >> scalebits];
+
+	d = dst + bytes_per_line*3;
+	*d++ = cm[c[12] >> scalebits];
+	*d++ = cm[c[13] >> scalebits];
+	*d++ = cm[c[14] >> scalebits];
+	*d++ = cm[c[15] >> scalebits];
+#else
+	int i;
+	const int *c = src;
+	unsigned char *d = dst;
+	for (i = 0; i < 4; i++, c++)
+		*d++ = CLAMP((*c) >> scalebits);
+
+	d = dst + bytes_per_line;
+	for (i = 0; i < 4; i++, c++)
+		*d++ = CLAMP((*c) >> scalebits);
+
+	d = dst + bytes_per_line*2;
+	for (i = 0; i < 4; i++, c++)
+		*d++ = CLAMP((*c) >> scalebits);
+
+	d = dst + bytes_per_line*3;
+	for (i = 0; i < 4; i++, c++)
+		*d++ = CLAMP((*c) >> scalebits);
+#endif
+}
+
+/*
+ * Copy the 4x4 image block to a CrCb plane buffer
+ *
+ */
+static void copy_image_block_CrCb(const int *src, unsigned char *dst, unsigned int bytes_per_line, unsigned int scalebits)
+{
+#if UNROLL_LOOP_FOR_COPY
+	/* Unroll all loops */
+	const unsigned char *cm = pwc_crop_table+MAX_OUTER_CROP_VALUE;
+	const int *c = src;
+	unsigned char *d = dst;
+
+	*d++ = cm[c[0] >> scalebits];
+	*d++ = cm[c[4] >> scalebits];
+	*d++ = cm[c[1] >> scalebits];
+	*d++ = cm[c[5] >> scalebits];
+	*d++ = cm[c[2] >> scalebits];
+	*d++ = cm[c[6] >> scalebits];
+	*d++ = cm[c[3] >> scalebits];
+	*d++ = cm[c[7] >> scalebits];
+
+	d = dst + bytes_per_line;
+	*d++ = cm[c[12] >> scalebits];
+	*d++ = cm[c[8] >> scalebits];
+	*d++ = cm[c[13] >> scalebits];
+	*d++ = cm[c[9] >> scalebits];
+	*d++ = cm[c[14] >> scalebits];
+	*d++ = cm[c[10] >> scalebits];
+	*d++ = cm[c[15] >> scalebits];
+	*d++ = cm[c[11] >> scalebits];
+#else
+	int i;
+	const int *c1 = src;
+	const int *c2 = src + 4;
+	unsigned char *d = dst;
+
+	for (i = 0; i < 4; i++, c1++, c2++) {
+		*d++ = CLAMP((*c1) >> scalebits);
+		*d++ = CLAMP((*c2) >> scalebits);
+	}
+	c1 = src + 12;
+	d = dst + bytes_per_line;
+	for (i = 0; i < 4; i++, c1++, c2++) {
+		*d++ = CLAMP((*c1) >> scalebits);
+		*d++ = CLAMP((*c2) >> scalebits);
+	}
+#endif
+}
+
+#if ENABLE_BAYER_DECODER
+/*
+ * Format: 8x2 pixels
+ *   . G . G . G . G . G . G . G
+ *   . . . . . . . . . . . . . .
+ *   . G . G . G . G . G . G . G
+ *   . . . . . . . . . . . . . .
+ *   or
+ *   . . . . . . . . . . . . . .
+ *   G . G . G . G . G . G . G .
+ *   . . . . . . . . . . . . . .
+ *   G . G . G . G . G . G . G .
+*/
+static void copy_image_block_Green(const int *src, unsigned char *dst, unsigned int bytes_per_line, unsigned int scalebits)
+{
+#if UNROLL_LOOP_FOR_COPY
+	/* Unroll all loops */
+	const unsigned char *cm = pwc_crop_table+MAX_OUTER_CROP_VALUE;
+	unsigned char *d = dst;
+	const int *c = src;
+
+	d[0] = cm[c[0] >> scalebits];
+	d[2] = cm[c[1] >> scalebits];
+	d[4] = cm[c[2] >> scalebits];
+	d[6] = cm[c[3] >> scalebits];
+	d[8] = cm[c[4] >> scalebits];
+	d[10] = cm[c[5] >> scalebits];
+	d[12] = cm[c[6] >> scalebits];
+	d[14] = cm[c[7] >> scalebits];
+
+	d = dst + bytes_per_line;
+	d[0] = cm[c[8] >> scalebits];
+	d[2] = cm[c[9] >> scalebits];
+	d[4] = cm[c[10] >> scalebits];
+	d[6] = cm[c[11] >> scalebits];
+	d[8] = cm[c[12] >> scalebits];
+	d[10] = cm[c[13] >> scalebits];
+	d[12] = cm[c[14] >> scalebits];
+	d[14] = cm[c[15] >> scalebits];
+#else
+	int i;
+	unsigned char *d;
+	const int *c = src;
+
+	d = dst;
+	for (i = 0; i < 8; i++, c++)
+		d[i*2] = CLAMP((*c) >> scalebits);
+
+	d = dst + bytes_per_line;
+	for (i = 0; i < 8; i++, c++)
+		d[i*2] = CLAMP((*c) >> scalebits);
+#endif
+}
+#endif
+
+#if ENABLE_BAYER_DECODER
+/*
+ * Format: 4x4 pixels
+ *   R . R . R . R
+ *   . B . B . B .
+ *   R . R . R . R
+ *   . B . B . B .
+ */
+static void copy_image_block_RedBlue(const int *src, unsigned char *dst, unsigned int bytes_per_line, unsigned int scalebits)
+{
+#if UNROLL_LOOP_FOR_COPY
+	/* Unroll all loops */
+	const unsigned char *cm = pwc_crop_table+MAX_OUTER_CROP_VALUE;
+	unsigned char *d = dst;
+	const int *c = src;
+
+	d[0] = cm[c[0] >> scalebits];
+	d[2] = cm[c[1] >> scalebits];
+	d[4] = cm[c[2] >> scalebits];
+	d[6] = cm[c[3] >> scalebits];
+
+	d = dst + bytes_per_line;
+	d[1] = cm[c[4] >> scalebits];
+	d[3] = cm[c[5] >> scalebits];
+	d[5] = cm[c[6] >> scalebits];
+	d[7] = cm[c[7] >> scalebits];
+
+	d = dst + bytes_per_line*2;
+	d[0] = cm[c[8] >> scalebits];
+	d[2] = cm[c[9] >> scalebits];
+	d[4] = cm[c[10] >> scalebits];
+	d[6] = cm[c[11] >> scalebits];
+
+	d = dst + bytes_per_line*3;
+	d[1] = cm[c[12] >> scalebits];
+	d[3] = cm[c[13] >> scalebits];
+	d[5] = cm[c[14] >> scalebits];
+	d[7] = cm[c[15] >> scalebits];
+#else
+	int i;
+	unsigned char *d;
+	const int *c = src;
+
+	d = dst;
+	for (i = 0; i < 4; i++, c++)
+		d[i*2] = CLAMP((*c) >> scalebits);
+
+	d = dst + bytes_per_line;
+	for (i = 0; i < 4; i++, c++)
+		d[i*2+1] = CLAMP((*c) >> scalebits);
+
+	d = dst + bytes_per_line*2;
+	for (i = 0; i < 4; i++, c++)
+		d[i*2] = CLAMP((*c) >> scalebits);
+
+	d = dst + bytes_per_line*3;
+	for (i = 0; i < 4; i++, c++)
+		d[i*2+1] = CLAMP((*c) >> scalebits);
+#endif
+}
+#endif
+
+/*
+ * To manage the stream, we keep bits in a 32 bits register.
+ * fill_nbits(n): fill the reservoir with at least n bits
+ * skip_bits(n): discard n bits from the reservoir
+ * get_bits(n): fill the reservoir, returns the first n bits and discard the
+ *              bits from the reservoir.
+ * __get_nbits(n): faster version of get_bits(n), but asumes that the reservoir
+ *                 contains at least n bits. bits returned is discarded.
+ */
+#define fill_nbits(pdec, nbits_wanted) do { \
+   while (pdec->nbits_in_reservoir<(nbits_wanted)) \
+    { \
+      pdec->reservoir |= (*(pdec->stream)++) << (pdec->nbits_in_reservoir); \
+      pdec->nbits_in_reservoir += 8; \
+    } \
+}  while(0);
+
+#define skip_nbits(pdec, nbits_to_skip) do { \
+   pdec->reservoir >>= (nbits_to_skip); \
+   pdec->nbits_in_reservoir -= (nbits_to_skip); \
+}  while(0);
+
+#define get_nbits(pdec, nbits_wanted, result) do { \
+   fill_nbits(pdec, nbits_wanted); \
+   result = (pdec->reservoir) & ((1U<<(nbits_wanted))-1); \
+   skip_nbits(pdec, nbits_wanted); \
+}  while(0);
+
+#define __get_nbits(pdec, nbits_wanted, result) do { \
+   result = (pdec->reservoir) & ((1U<<(nbits_wanted))-1); \
+   skip_nbits(pdec, nbits_wanted); \
+}  while(0);
+
+#define look_nbits(pdec, nbits_wanted) \
+   ((pdec->reservoir) & ((1U<<(nbits_wanted))-1))
+
+/*
+ * Decode a 4x4 pixel block
+ */
+static void decode_block(struct pwc_dec23_private *pdec,
+			 const unsigned char *ptable0004,
+			 const unsigned char *ptable8004)
+{
+	unsigned int primary_color;
+	unsigned int channel_v, offset1, op;
+	int i;
+
+	fill_nbits(pdec, 16);
+	__get_nbits(pdec, pdec->nbits, primary_color);
+
+	if (look_nbits(pdec,2) == 0) {
+		skip_nbits(pdec, 2);
+		/* Very simple, the color is the same for all pixels of the square */
+		for (i = 0; i < 16; i++)
+			pdec->temp_colors[i] = pdec->table_dc00[primary_color];
+
+		return;
+	}
+
+	/* This block is encoded with small pattern */
+	for (i = 0; i < 16; i++)
+		pdec->temp_colors[i] = pdec->table_d800[primary_color];
+
+	__get_nbits(pdec, 3, channel_v);
+	channel_v = ((channel_v & 1) << 2) | (channel_v & 2) | ((channel_v & 4) >> 2);
+
+	ptable0004 += (channel_v * 128);
+	ptable8004 += (channel_v * 32);
+
+	offset1 = 0;
+	do
+	{
+		unsigned int htable_idx, rows = 0;
+		const unsigned int *block;
+
+		/* [  zzzz y x x ]
+		 *     xx == 00 :=> end of the block def, remove the two bits from the stream
+		 *    yxx == 111
+		 *    yxx == any other value
+		 *
+		 */
+		fill_nbits(pdec, 16);
+		htable_idx = look_nbits(pdec, 6);
+		op = hash_table_ops[htable_idx * 4];
+
+		if (op == 2) {
+			skip_nbits(pdec, 2);
+
+		} else if (op == 1) {
+			/* 15bits [ xxxx xxxx yyyy 111 ]
+			 * yyy => offset in the table8004
+			 * xxx => offset in the tabled004 (tree)
+			 */
+			unsigned int mask, shift;
+			unsigned int nbits, col1;
+			unsigned int yyyy;
+
+			skip_nbits(pdec, 3);
+			/* offset1 += yyyy */
+			__get_nbits(pdec, 4, yyyy);
+			offset1 += 1 + yyyy;
+			offset1 &= 0x0F;
+			nbits = ptable8004[offset1 * 2];
+
+			/* col1 = xxxx xxxx */
+			__get_nbits(pdec, nbits+1, col1);
+
+			/* Bit mask table */
+			mask = pdec->table_bitpowermask[nbits][col1];
+			shift = ptable8004[offset1 * 2 + 1];
+			rows = ((mask << shift) + 0x80) & 0xFF;
+
+			block = pdec->table_subblock[rows];
+			for (i = 0; i < 16; i++)
+				pdec->temp_colors[i] += block[MulIdx[offset1][i]];
+
+		} else {
+			/* op == 0
+			 * offset1 is coded on 3 bits
+			 */
+			unsigned int shift;
+
+			offset1 += hash_table_ops [htable_idx * 4 + 2];
+			offset1 &= 0x0F;
+
+			rows = ptable0004[offset1 + hash_table_ops [htable_idx * 4 + 3]];
+			block = pdec->table_subblock[rows];
+			for (i = 0; i < 16; i++)
+				pdec->temp_colors[i] += block[MulIdx[offset1][i]];
+
+			shift = hash_table_ops[htable_idx * 4 + 1];
+			skip_nbits(pdec, shift);
+		}
+
+	} while (op != 2);
+
+}
+
+static void DecompressBand23(struct pwc_dec23_private *pdec,
+			     const unsigned char *rawyuv,
+			     unsigned char *planar_y,
+			     unsigned char *planar_u,
+			     unsigned char *planar_v,
+			     unsigned int   compressed_image_width,
+			     unsigned int   real_image_width)
+{
+	int compression_index, nblocks;
+	const unsigned char *ptable0004;
+	const unsigned char *ptable8004;
+
+	pdec->reservoir = 0;
+	pdec->nbits_in_reservoir = 0;
+	pdec->stream = rawyuv + 1;	/* The first byte of the stream is skipped */
+
+	get_nbits(pdec, 4, compression_index);
+
+	/* pass 1: uncompress Y component */
+	nblocks = compressed_image_width / 4;
+
+	ptable0004 = pdec->table_0004_pass1[compression_index];
+	ptable8004 = pdec->table_8004_pass1[compression_index];
+
+	/* Each block decode a square of 4x4 */
+	while (nblocks) {
+		decode_block(pdec, ptable0004, ptable8004);
+		copy_image_block_Y(pdec->temp_colors, planar_y, real_image_width, pdec->scalebits);
+		planar_y += 4;
+		nblocks--;
+	}
+
+	/* pass 2: uncompress UV component */
+	nblocks = compressed_image_width / 8;
+
+	ptable0004 = pdec->table_0004_pass2[compression_index];
+	ptable8004 = pdec->table_8004_pass2[compression_index];
+
+	/* Each block decode a square of 4x4 */
+	while (nblocks) {
+		decode_block(pdec, ptable0004, ptable8004);
+		copy_image_block_CrCb(pdec->temp_colors, planar_u, real_image_width/2, pdec->scalebits);
+
+		decode_block(pdec, ptable0004, ptable8004);
+		copy_image_block_CrCb(pdec->temp_colors, planar_v, real_image_width/2, pdec->scalebits);
+
+		planar_v += 8;
+		planar_u += 8;
+		nblocks -= 2;
+	}
+
+}
+
+#if ENABLE_BAYER_DECODER
+/*
+ * Size need to be a multiple of 8 in width
+ *
+ * Return a block of four line encoded like this:
+ *
+ *   G R G R G R G R G R G R G R G R
+ *   B G B G B G B G B G B G B G B G
+ *   G R G R G R G R G R G R G R G R
+ *   B G B G B G B G B G B G B G B G
+ *
+ */
+static void DecompressBandBayer(struct pwc_dec23_private *pdec,
+				const unsigned char *rawyuv,
+				unsigned char *rgbbayer,
+				unsigned int   compressed_image_width,
+				unsigned int   real_image_width)
+{
+	int compression_index, nblocks;
+	const unsigned char *ptable0004;
+	const unsigned char *ptable8004;
+	unsigned char *dest;
+
+	pdec->reservoir = 0;
+	pdec->nbits_in_reservoir = 0;
+	pdec->stream = rawyuv + 1;	/* The first byte of the stream is skipped */
+
+	get_nbits(pdec, 4, compression_index);
+
+	/* pass 1: uncompress RB component */
+	nblocks = compressed_image_width / 4;
+
+	ptable0004 = pdec->table_0004_pass1[compression_index];
+	ptable8004 = pdec->table_8004_pass1[compression_index];
+	dest = rgbbayer;
+
+	/* Each block decode a square of 4x4 */
+	while (nblocks) {
+		decode_block(pdec, ptable0004, ptable8004);
+		copy_image_block_RedBlue(pdec->temp_colors, rgbbayer, real_image_width, pdec->scalebits);
+		dest += 8;
+		nblocks--;
+	}
+
+	/* pass 2: uncompress G component */
+	nblocks = compressed_image_width / 8;
+
+	ptable0004 = pdec->table_0004_pass2[compression_index];
+	ptable8004 = pdec->table_8004_pass2[compression_index];
+
+	/* Each block decode a square of 4x4 */
+	while (nblocks) {
+		decode_block(pdec, ptable0004, ptable8004);
+		copy_image_block_Green(pdec->temp_colors, rgbbayer+1, real_image_width, pdec->scalebits);
+
+		decode_block(pdec, ptable0004, ptable8004);
+		copy_image_block_Green(pdec->temp_colors, rgbbayer+real_image_width, real_image_width, pdec->scalebits);
+
+		rgbbayer += 16;
+		nblocks -= 2;
+	}
+}
+#endif
+
+
+/**
+ *
+ * Uncompress a pwc23 buffer.
+ *
+ * pwc.view: size of the image wanted
+ * pwc.image: size of the image returned by the camera
+ * pwc.offset: (x,y) to displayer image in the view
+ *
+ * src: raw data
+ * dst: image output
+ * flags: PWCX_FLAG_PLANAR or PWCX_FLAG_BAYER
+ */
+void pwc_dec23_decompress(const struct pwc_device *pwc,
+			  const void *src,
+			  void *dst,
+			  int flags)
+{
+	int bandlines_left, stride, bytes_per_block;
+
+	bandlines_left = pwc->image.y / 4;
+	bytes_per_block = pwc->view.x * 4;
+
+	if (flags & PWCX_FLAG_BAYER) {
+#if ENABLE_BAYER_DECODER
+		/* RGB Bayer format */
+		unsigned char *rgbout;
+
+		stride = pwc->view.x * pwc->offset.y;
+		rgbout = dst + stride + pwc->offset.x;
+
+
+		while (bandlines_left--) {
+
+			DecompressBandBayer(pwc->decompress_data,
+					    src,
+					    rgbout,
+					    pwc->image.x, pwc->view.x);
+
+			src += pwc->vbandlength;
+			rgbout += bytes_per_block;
+
+		}
+#else
+		memset(dst, 0, pwc->view.x * pwc->view.y);
+#endif
+
+	} else {
+		/* YUV420P image format */
+		unsigned char *pout_planar_y;
+		unsigned char *pout_planar_u;
+		unsigned char *pout_planar_v;
+		unsigned int   plane_size;
+
+		plane_size = pwc->view.x * pwc->view.y;
+
+		/* offset in Y plane */
+		stride = pwc->view.x * pwc->offset.y;
+		pout_planar_y = dst + stride + pwc->offset.x;
+
+		/* offsets in U/V planes */
+		stride = (pwc->view.x * pwc->offset.y) / 4 + pwc->offset.x / 2;
+		pout_planar_u = dst + plane_size + stride;
+		pout_planar_v = dst + plane_size + plane_size / 4 + stride;
+
+		while (bandlines_left--) {
+
+			DecompressBand23(pwc->decompress_data,
+					 src,
+					 pout_planar_y, pout_planar_u, pout_planar_v,
+					 pwc->image.x, pwc->view.x);
+			src += pwc->vbandlength;
+			pout_planar_y += bytes_per_block;
+			pout_planar_u += pwc->view.x;
+			pout_planar_v += pwc->view.x;
+
+		}
+
+	}
+
+}
+
+void pwc_dec23_exit(void)
+{
+	/* Do nothing */
+
+}
+
+/**
+ * Allocate a private structure used by lookup table.
+ * You must call kfree() to free the memory allocated.
+ */
+int pwc_dec23_alloc(struct pwc_device *pwc)
+{
+	pwc->decompress_data = kmalloc(sizeof(struct pwc_dec23_private), GFP_KERNEL);
+	if (pwc->decompress_data == NULL)
+		return -ENOMEM;
+	return 0;
+}
+
+/* vim: set cino= formatoptions=croql cindent shiftwidth=8 tabstop=8: */
diff --git a/drivers/media/video/pwc/pwc-dec23.h b/drivers/media/video/pwc/pwc-dec23.h
new file mode 100644
index 000000000..1c55298ad
--- /dev/null
+++ b/drivers/media/video/pwc/pwc-dec23.h
@@ -0,0 +1,67 @@
+/* Linux driver for Philips webcam
+   (C) 2004-2006 Luc Saillard (luc@saillard.org)
+
+   NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx
+   driver and thus may have bugs that are not present in the original version.
+   Please send bug reports and support requests to <luc@saillard.org>.
+   The decompression routines have been implemented by reverse-engineering the
+   Nemosoft binary pwcx module. Caveat emptor.
+
+   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
+*/
+
+#ifndef PWC_DEC23_H
+#define PWC_DEC23_H
+
+#include "pwc.h"
+
+struct pwc_dec23_private
+{
+  unsigned int scalebits;
+  unsigned int nbitsmask, nbits; /* Number of bits of a color in the compressed stream */
+
+  unsigned int reservoir;
+  unsigned int nbits_in_reservoir;
+  const unsigned char *stream;
+  int temp_colors[16];
+
+  unsigned char table_0004_pass1[16][1024];
+  unsigned char table_0004_pass2[16][1024];
+  unsigned char table_8004_pass1[16][256];
+  unsigned char table_8004_pass2[16][256];
+  unsigned int  table_subblock[256][12];
+
+  unsigned char table_bitpowermask[8][256];
+  unsigned int  table_d800[256];
+  unsigned int  table_dc00[256];
+
+};
+
+
+int pwc_dec23_alloc(struct pwc_device *pwc);
+int pwc_dec23_init(struct pwc_device *pwc, int type, unsigned char *cmd);
+void pwc_dec23_exit(void);
+void pwc_dec23_decompress(const struct pwc_device *pwc,
+			  const void *src,
+			  void *dst,
+			  int flags);
+
+
+
+#endif
+
+
+/* vim: set cino= formatoptions=croql cindent shiftwidth=8 tabstop=8: */
+
diff --git a/drivers/media/video/pwc/pwc-v4l.c b/drivers/media/video/pwc/pwc-v4l.c
new file mode 100644
index 000000000..b7eb3ce3b
--- /dev/null
+++ b/drivers/media/video/pwc/pwc-v4l.c
@@ -0,0 +1,1202 @@
+/* Linux driver for Philips webcam
+   USB and Video4Linux interface part.
+   (C) 1999-2004 Nemosoft Unv.
+   (C) 2004-2006 Luc Saillard (luc@saillard.org)
+
+   NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx
+   driver and thus may have bugs that are not present in the original version.
+   Please send bug reports and support requests to <luc@saillard.org>.
+   The decompression routines have been implemented by reverse-engineering the
+   Nemosoft binary pwcx module. Caveat emptor.
+
+   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/errno.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/poll.h>
+#include <linux/slab.h>
+#include <linux/vmalloc.h>
+#include <asm/io.h>
+
+#include "pwc.h"
+
+static struct v4l2_queryctrl pwc_controls[] = {
+	{
+	    .id      = V4L2_CID_BRIGHTNESS,
+	    .type    = V4L2_CTRL_TYPE_INTEGER,
+	    .name    = "Brightness",
+	    .minimum = 0,
+	    .maximum = 128,
+	    .step    = 1,
+	    .default_value = 64,
+	},
+	{
+	    .id      = V4L2_CID_CONTRAST,
+	    .type    = V4L2_CTRL_TYPE_INTEGER,
+	    .name    = "Contrast",
+	    .minimum = 0,
+	    .maximum = 64,
+	    .step    = 1,
+	    .default_value = 0,
+	},
+	{
+	    .id      = V4L2_CID_SATURATION,
+	    .type    = V4L2_CTRL_TYPE_INTEGER,
+	    .name    = "Saturation",
+	    .minimum = -100,
+	    .maximum = 100,
+	    .step    = 1,
+	    .default_value = 0,
+	},
+	{
+	    .id      = V4L2_CID_GAMMA,
+	    .type    = V4L2_CTRL_TYPE_INTEGER,
+	    .name    = "Gamma",
+	    .minimum = 0,
+	    .maximum = 32,
+	    .step    = 1,
+	    .default_value = 0,
+	},
+	{
+	    .id      = V4L2_CID_RED_BALANCE,
+	    .type    = V4L2_CTRL_TYPE_INTEGER,
+	    .name    = "Red Gain",
+	    .minimum = 0,
+	    .maximum = 256,
+	    .step    = 1,
+	    .default_value = 0,
+	},
+	{
+	    .id      = V4L2_CID_BLUE_BALANCE,
+	    .type    = V4L2_CTRL_TYPE_INTEGER,
+	    .name    = "Blue Gain",
+	    .minimum = 0,
+	    .maximum = 256,
+	    .step    = 1,
+	    .default_value = 0,
+	},
+	{
+	    .id      = V4L2_CID_AUTO_WHITE_BALANCE,
+	    .type    = V4L2_CTRL_TYPE_BOOLEAN,
+	    .name    = "Auto White Balance",
+	    .minimum = 0,
+	    .maximum = 1,
+	    .step    = 1,
+	    .default_value = 0,
+	},
+	{
+	    .id      = V4L2_CID_EXPOSURE,
+	    .type    = V4L2_CTRL_TYPE_INTEGER,
+	    .name    = "Shutter Speed (Exposure)",
+	    .minimum = 0,
+	    .maximum = 256,
+	    .step    = 1,
+	    .default_value = 200,
+	},
+	{
+	    .id      = V4L2_CID_AUTOGAIN,
+	    .type    = V4L2_CTRL_TYPE_BOOLEAN,
+	    .name    = "Auto Gain Enabled",
+	    .minimum = 0,
+	    .maximum = 1,
+	    .step    = 1,
+	    .default_value = 1,
+	},
+	{
+	    .id      = V4L2_CID_GAIN,
+	    .type    = V4L2_CTRL_TYPE_INTEGER,
+	    .name    = "Gain Level",
+	    .minimum = 0,
+	    .maximum = 256,
+	    .step    = 1,
+	    .default_value = 0,
+	},
+	{
+	    .id      = V4L2_CID_PRIVATE_SAVE_USER,
+	    .type    = V4L2_CTRL_TYPE_BUTTON,
+	    .name    = "Save User Settings",
+	    .minimum = 0,
+	    .maximum = 0,
+	    .step    = 0,
+	    .default_value = 0,
+	},
+	{
+	    .id      = V4L2_CID_PRIVATE_RESTORE_USER,
+	    .type    = V4L2_CTRL_TYPE_BUTTON,
+	    .name    = "Restore User Settings",
+	    .minimum = 0,
+	    .maximum = 0,
+	    .step    = 0,
+	    .default_value = 0,
+	},
+	{
+	    .id      = V4L2_CID_PRIVATE_RESTORE_FACTORY,
+	    .type    = V4L2_CTRL_TYPE_BUTTON,
+	    .name    = "Restore Factory Settings",
+	    .minimum = 0,
+	    .maximum = 0,
+	    .step    = 0,
+	    .default_value = 0,
+	},
+	{
+	    .id      = V4L2_CID_PRIVATE_COLOUR_MODE,
+	    .type    = V4L2_CTRL_TYPE_BOOLEAN,
+	    .name    = "Colour mode",
+	    .minimum = 0,
+	    .maximum = 1,
+	    .step    = 1,
+	    .default_value = 0,
+	},
+	{
+	    .id      = V4L2_CID_PRIVATE_AUTOCONTOUR,
+	    .type    = V4L2_CTRL_TYPE_BOOLEAN,
+	    .name    = "Auto contour",
+	    .minimum = 0,
+	    .maximum = 1,
+	    .step    = 1,
+	    .default_value = 0,
+	},
+	{
+	    .id      = V4L2_CID_PRIVATE_CONTOUR,
+	    .type    = V4L2_CTRL_TYPE_INTEGER,
+	    .name    = "Contour",
+	    .minimum = 0,
+	    .maximum = 63,
+	    .step    = 1,
+	    .default_value = 0,
+	},
+	{
+	    .id      = V4L2_CID_PRIVATE_BACKLIGHT,
+	    .type    = V4L2_CTRL_TYPE_BOOLEAN,
+	    .name    = "Backlight compensation",
+	    .minimum = 0,
+	    .maximum = 1,
+	    .step    = 1,
+	    .default_value = 0,
+	},
+	{
+	  .id      = V4L2_CID_PRIVATE_FLICKERLESS,
+	    .type    = V4L2_CTRL_TYPE_BOOLEAN,
+	    .name    = "Flickerless",
+	    .minimum = 0,
+	    .maximum = 1,
+	    .step    = 1,
+	    .default_value = 0,
+	},
+	{
+	    .id      = V4L2_CID_PRIVATE_NOISE_REDUCTION,
+	    .type    = V4L2_CTRL_TYPE_INTEGER,
+	    .name    = "Noise reduction",
+	    .minimum = 0,
+	    .maximum = 3,
+	    .step    = 1,
+	    .default_value = 0,
+	},
+};
+
+
+static void pwc_vidioc_fill_fmt(const struct pwc_device *pdev, struct v4l2_format *f)
+{
+	memset(&f->fmt.pix, 0, sizeof(struct v4l2_pix_format));
+	f->fmt.pix.width        = pdev->view.x;
+	f->fmt.pix.height       = pdev->view.y;
+	f->fmt.pix.field        = V4L2_FIELD_NONE;
+	if (pdev->vpalette == VIDEO_PALETTE_YUV420P) {
+		f->fmt.pix.pixelformat  = V4L2_PIX_FMT_YUV420;
+		f->fmt.pix.bytesperline = (f->fmt.pix.width * 3)/2;
+		f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline;
+	} else {
+		/* vbandlength contains 4 lines ...  */
+		f->fmt.pix.bytesperline = pdev->vbandlength/4;
+		f->fmt.pix.sizeimage = pdev->frame_size + sizeof(struct pwc_raw_frame);
+		if (DEVICE_USE_CODEC1(pdev->type))
+			f->fmt.pix.pixelformat  = V4L2_PIX_FMT_PWC1;
+		else
+			f->fmt.pix.pixelformat  = V4L2_PIX_FMT_PWC2;
+	}
+	PWC_DEBUG_IOCTL("pwc_vidioc_fill_fmt() "
+			"width=%d, height=%d, bytesperline=%d, sizeimage=%d, pixelformat=%c%c%c%c\n",
+			f->fmt.pix.width,
+			f->fmt.pix.height,
+			f->fmt.pix.bytesperline,
+			f->fmt.pix.sizeimage,
+			(f->fmt.pix.pixelformat)&255,
+			(f->fmt.pix.pixelformat>>8)&255,
+			(f->fmt.pix.pixelformat>>16)&255,
+			(f->fmt.pix.pixelformat>>24)&255);
+}
+
+/* ioctl(VIDIOC_TRY_FMT) */
+static int pwc_vidioc_try_fmt(struct pwc_device *pdev, struct v4l2_format *f)
+{
+	if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
+		PWC_DEBUG_IOCTL("Bad video type must be V4L2_BUF_TYPE_VIDEO_CAPTURE\n");
+		return -EINVAL;
+	}
+
+	switch (f->fmt.pix.pixelformat) {
+		case V4L2_PIX_FMT_YUV420:
+			break;
+		case V4L2_PIX_FMT_PWC1:
+			if (DEVICE_USE_CODEC23(pdev->type)) {
+				PWC_DEBUG_IOCTL("codec1 is only supported for old pwc webcam\n");
+				return -EINVAL;
+			}
+			break;
+		case V4L2_PIX_FMT_PWC2:
+			if (DEVICE_USE_CODEC1(pdev->type)) {
+				PWC_DEBUG_IOCTL("codec23 is only supported for new pwc webcam\n");
+				return -EINVAL;
+			}
+			break;
+		default:
+			PWC_DEBUG_IOCTL("Unsupported pixel format\n");
+			return -EINVAL;
+
+	}
+
+	if (f->fmt.pix.width > pdev->view_max.x)
+		f->fmt.pix.width = pdev->view_max.x;
+	else if (f->fmt.pix.width < pdev->view_min.x)
+		f->fmt.pix.width = pdev->view_min.x;
+
+	if (f->fmt.pix.height > pdev->view_max.y)
+		f->fmt.pix.height = pdev->view_max.y;
+	else if (f->fmt.pix.height < pdev->view_min.y)
+		f->fmt.pix.height = pdev->view_min.y;
+
+	return 0;
+}
+
+/* ioctl(VIDIOC_SET_FMT) */
+static int pwc_vidioc_set_fmt(struct pwc_device *pdev, struct v4l2_format *f)
+{
+	int ret, fps, snapshot, compression, pixelformat;
+
+	ret = pwc_vidioc_try_fmt(pdev, f);
+	if (ret<0)
+		return ret;
+
+	pixelformat = f->fmt.pix.pixelformat;
+	compression = pdev->vcompression;
+	snapshot = 0;
+	fps = pdev->vframes;
+	if (f->fmt.pix.priv) {
+		compression = (f->fmt.pix.priv & PWC_QLT_MASK) >> PWC_QLT_SHIFT;
+		snapshot = !!(f->fmt.pix.priv & PWC_FPS_SNAPSHOT);
+		fps = (f->fmt.pix.priv & PWC_FPS_FRMASK) >> PWC_FPS_SHIFT;
+		if (fps == 0)
+			fps = pdev->vframes;
+	}
+
+	if (pixelformat == V4L2_PIX_FMT_YUV420)
+		pdev->vpalette = VIDEO_PALETTE_YUV420P;
+	else
+		pdev->vpalette = VIDEO_PALETTE_RAW;
+
+	PWC_DEBUG_IOCTL("Try to change format to: width=%d height=%d fps=%d "
+			"compression=%d snapshot=%d format=%c%c%c%c\n",
+			f->fmt.pix.width, f->fmt.pix.height, fps,
+			compression, snapshot,
+			(pixelformat)&255,
+			(pixelformat>>8)&255,
+			(pixelformat>>16)&255,
+			(pixelformat>>24)&255);
+
+	ret = pwc_try_video_mode(pdev,
+				 f->fmt.pix.width,
+				 f->fmt.pix.height,
+				 fps,
+				 compression,
+				 snapshot);
+
+	PWC_DEBUG_IOCTL("pwc_try_video_mode(), return=%d\n", ret);
+
+	if (ret)
+		return ret;
+
+	pwc_vidioc_fill_fmt(pdev, f);
+
+	return 0;
+
+}
+
+int pwc_video_do_ioctl(struct inode *inode, struct file *file,
+		       unsigned int cmd, void *arg)
+{
+	struct video_device *vdev = video_devdata(file);
+	struct pwc_device *pdev;
+	DECLARE_WAITQUEUE(wait, current);
+
+	if (vdev == NULL)
+		return -EFAULT;
+	pdev = vdev->priv;
+	if (pdev == NULL)
+		return -EFAULT;
+
+#if CONFIG_PWC_DEBUG
+	if (PWC_DEBUG_LEVEL_IOCTL & pwc_trace)
+		v4l_printk_ioctl(cmd);
+#endif
+
+
+	switch (cmd) {
+		/* Query cabapilities */
+		case VIDIOCGCAP:
+		{
+			struct video_capability *caps = arg;
+
+			strcpy(caps->name, vdev->name);
+			caps->type = VID_TYPE_CAPTURE;
+			caps->channels = 1;
+			caps->audios = 1;
+			caps->minwidth  = pdev->view_min.x;
+			caps->minheight = pdev->view_min.y;
+			caps->maxwidth  = pdev->view_max.x;
+			caps->maxheight = pdev->view_max.y;
+			break;
+		}
+
+		/* Channel functions (simulate 1 channel) */
+		case VIDIOCGCHAN:
+		{
+			struct video_channel *v = arg;
+
+			if (v->channel != 0)
+				return -EINVAL;
+			v->flags = 0;
+			v->tuners = 0;
+			v->type = VIDEO_TYPE_CAMERA;
+			strcpy(v->name, "Webcam");
+			return 0;
+		}
+
+		case VIDIOCSCHAN:
+		{
+			/* The spec says the argument is an integer, but
+			   the bttv driver uses a video_channel arg, which
+			   makes sense becasue it also has the norm flag.
+			 */
+			struct video_channel *v = arg;
+			if (v->channel != 0)
+				return -EINVAL;
+			return 0;
+		}
+
+
+		/* Picture functions; contrast etc. */
+		case VIDIOCGPICT:
+		{
+			struct video_picture *p = arg;
+			int val;
+
+			val = pwc_get_brightness(pdev);
+			if (val >= 0)
+				p->brightness = (val<<9);
+			else
+				p->brightness = 0xffff;
+			val = pwc_get_contrast(pdev);
+			if (val >= 0)
+				p->contrast = (val<<10);
+			else
+				p->contrast = 0xffff;
+			/* Gamma, Whiteness, what's the difference? :) */
+			val = pwc_get_gamma(pdev);
+			if (val >= 0)
+				p->whiteness = (val<<11);
+			else
+				p->whiteness = 0xffff;
+			if (pwc_get_saturation(pdev, &val)<0)
+				p->colour = 0xffff;
+			else
+				p->colour = 32768 + val * 327;
+			p->depth = 24;
+			p->palette = pdev->vpalette;
+			p->hue = 0xFFFF; /* N/A */
+			break;
+		}
+
+		case VIDIOCSPICT:
+		{
+			struct video_picture *p = arg;
+			/*
+			 *	FIXME:	Suppose we are mid read
+				ANSWER: No problem: the firmware of the camera
+					can handle brightness/contrast/etc
+					changes at _any_ time, and the palette
+					is used exactly once in the uncompress
+					routine.
+			 */
+			pwc_set_brightness(pdev, p->brightness);
+			pwc_set_contrast(pdev, p->contrast);
+			pwc_set_gamma(pdev, p->whiteness);
+			pwc_set_saturation(pdev, (p->colour-32768)/327);
+			if (p->palette && p->palette != pdev->vpalette) {
+				switch (p->palette) {
+					case VIDEO_PALETTE_YUV420P:
+					case VIDEO_PALETTE_RAW:
+						pdev->vpalette = p->palette;
+						return pwc_try_video_mode(pdev, pdev->image.x, pdev->image.y, pdev->vframes, pdev->vcompression, pdev->vsnapshot);
+						break;
+					default:
+						return -EINVAL;
+						break;
+				}
+			}
+			break;
+		}
+
+		/* Window/size parameters */
+		case VIDIOCGWIN:
+		{
+			struct video_window *vw = arg;
+
+			vw->x = 0;
+			vw->y = 0;
+			vw->width = pdev->view.x;
+			vw->height = pdev->view.y;
+			vw->chromakey = 0;
+			vw->flags = (pdev->vframes << PWC_FPS_SHIFT) |
+				   (pdev->vsnapshot ? PWC_FPS_SNAPSHOT : 0);
+			break;
+		}
+
+		case VIDIOCSWIN:
+		{
+			struct video_window *vw = arg;
+			int fps, snapshot, ret;
+
+			fps = (vw->flags & PWC_FPS_FRMASK) >> PWC_FPS_SHIFT;
+			snapshot = vw->flags & PWC_FPS_SNAPSHOT;
+			if (fps == 0)
+				fps = pdev->vframes;
+			if (pdev->view.x == vw->width && pdev->view.y && fps == pdev->vframes && snapshot == pdev->vsnapshot)
+				return 0;
+			ret = pwc_try_video_mode(pdev, vw->width, vw->height, fps, pdev->vcompression, snapshot);
+			if (ret)
+				return ret;
+			break;
+		}
+
+		/* We don't have overlay support (yet) */
+		case VIDIOCGFBUF:
+		{
+			struct video_buffer *vb = arg;
+
+			memset(vb,0,sizeof(*vb));
+			break;
+		}
+
+		/* mmap() functions */
+		case VIDIOCGMBUF:
+		{
+			/* Tell the user program how much memory is needed for a mmap() */
+			struct video_mbuf *vm = arg;
+			int i;
+
+			memset(vm, 0, sizeof(*vm));
+			vm->size = pwc_mbufs * pdev->len_per_image;
+			vm->frames = pwc_mbufs; /* double buffering should be enough for most applications */
+			for (i = 0; i < pwc_mbufs; i++)
+				vm->offsets[i] = i * pdev->len_per_image;
+			break;
+		}
+
+		case VIDIOCMCAPTURE:
+		{
+			/* Start capture into a given image buffer (called 'frame' in video_mmap structure) */
+			struct video_mmap *vm = arg;
+
+			PWC_DEBUG_READ("VIDIOCMCAPTURE: %dx%d, frame %d, format %d\n", vm->width, vm->height, vm->frame, vm->format);
+			if (vm->frame < 0 || vm->frame >= pwc_mbufs)
+				return -EINVAL;
+
+			/* xawtv is nasty. It probes the available palettes
+			   by setting a very small image size and trying
+			   various palettes... The driver doesn't support
+			   such small images, so I'm working around it.
+			 */
+			if (vm->format)
+			{
+				switch (vm->format)
+				{
+					case VIDEO_PALETTE_YUV420P:
+					case VIDEO_PALETTE_RAW:
+						break;
+					default:
+						return -EINVAL;
+						break;
+				}
+			}
+
+			if ((vm->width != pdev->view.x || vm->height != pdev->view.y) &&
+			    (vm->width >= pdev->view_min.x && vm->height >= pdev->view_min.y)) {
+				int ret;
+
+				PWC_DEBUG_OPEN("VIDIOCMCAPTURE: changing size to please xawtv :-(.\n");
+				ret = pwc_try_video_mode(pdev, vm->width, vm->height, pdev->vframes, pdev->vcompression, pdev->vsnapshot);
+				if (ret)
+					return ret;
+			} /* ... size mismatch */
+
+			/* FIXME: should we lock here? */
+			if (pdev->image_used[vm->frame])
+				return -EBUSY;	/* buffer wasn't available. Bummer */
+			pdev->image_used[vm->frame] = 1;
+
+			/* Okay, we're done here. In the SYNC call we wait until a
+			   frame comes available, then expand image into the given
+			   buffer.
+			   In contrast to the CPiA cam the Philips cams deliver a
+			   constant stream, almost like a grabber card. Also,
+			   we have separate buffers for the rawdata and the image,
+			   meaning we can nearly always expand into the requested buffer.
+			 */
+			PWC_DEBUG_READ("VIDIOCMCAPTURE done.\n");
+			break;
+		}
+
+		case VIDIOCSYNC:
+		{
+			/* The doc says: "Whenever a buffer is used it should
+			   call VIDIOCSYNC to free this frame up and continue."
+
+			   The only odd thing about this whole procedure is
+			   that MCAPTURE flags the buffer as "in use", and
+			   SYNC immediately unmarks it, while it isn't
+			   after SYNC that you know that the buffer actually
+			   got filled! So you better not start a CAPTURE in
+			   the same frame immediately (use double buffering).
+			   This is not a problem for this cam, since it has
+			   extra intermediate buffers, but a hardware
+			   grabber card will then overwrite the buffer
+			   you're working on.
+			 */
+			int *mbuf = arg;
+			int ret;
+
+			PWC_DEBUG_READ("VIDIOCSYNC called (%d).\n", *mbuf);
+
+			/* bounds check */
+			if (*mbuf < 0 || *mbuf >= pwc_mbufs)
+				return -EINVAL;
+			/* check if this buffer was requested anyway */
+			if (pdev->image_used[*mbuf] == 0)
+				return -EINVAL;
+
+			/* Add ourselves to the frame wait-queue.
+
+			   FIXME: needs auditing for safety.
+			   QUESTION: In what respect? I think that using the
+				     frameq is safe now.
+			 */
+			add_wait_queue(&pdev->frameq, &wait);
+			while (pdev->full_frames == NULL) {
+				/* Check for unplugged/etc. here */
+				if (pdev->error_status) {
+					remove_wait_queue(&pdev->frameq, &wait);
+					set_current_state(TASK_RUNNING);
+					return -pdev->error_status;
+				}
+
+				if (signal_pending(current)) {
+					remove_wait_queue(&pdev->frameq, &wait);
+					set_current_state(TASK_RUNNING);
+					return -ERESTARTSYS;
+				}
+				schedule();
+				set_current_state(TASK_INTERRUPTIBLE);
+			}
+			remove_wait_queue(&pdev->frameq, &wait);
+			set_current_state(TASK_RUNNING);
+
+			/* The frame is ready. Expand in the image buffer
+			   requested by the user. I don't care if you
+			   mmap() 5 buffers and request data in this order:
+			   buffer 4 2 3 0 1 2 3 0 4 3 1 . . .
+			   Grabber hardware may not be so forgiving.
+			 */
+			PWC_DEBUG_READ("VIDIOCSYNC: frame ready.\n");
+			pdev->fill_image = *mbuf; /* tell in which buffer we want the image to be expanded */
+			/* Decompress, etc */
+			ret = pwc_handle_frame(pdev);
+			pdev->image_used[*mbuf] = 0;
+			if (ret)
+				return -EFAULT;
+			break;
+		}
+
+		case VIDIOCGAUDIO:
+		{
+			struct video_audio *v = arg;
+
+			strcpy(v->name, "Microphone");
+			v->audio = -1; /* unknown audio minor */
+			v->flags = 0;
+			v->mode = VIDEO_SOUND_MONO;
+			v->volume = 0;
+			v->bass = 0;
+			v->treble = 0;
+			v->balance = 0x8000;
+			v->step = 1;
+			break;
+		}
+
+		case VIDIOCSAUDIO:
+		{
+			/* Dummy: nothing can be set */
+			break;
+		}
+
+		case VIDIOCGUNIT:
+		{
+			struct video_unit *vu = arg;
+
+			vu->video = pdev->vdev->minor & 0x3F;
+			vu->audio = -1; /* not known yet */
+			vu->vbi = -1;
+			vu->radio = -1;
+			vu->teletext = -1;
+			break;
+		}
+
+		/* V4L2 Layer */
+		case VIDIOC_QUERYCAP:
+		{
+		    struct v4l2_capability *cap = arg;
+
+		    PWC_DEBUG_IOCTL("ioctl(VIDIOC_QUERYCAP) This application "\
+				       "try to use the v4l2 layer\n");
+		    strcpy(cap->driver,PWC_NAME);
+		    strlcpy(cap->card, vdev->name, sizeof(cap->card));
+		    usb_make_path(pdev->udev,cap->bus_info,sizeof(cap->bus_info));
+		    cap->version = PWC_VERSION_CODE;
+		    cap->capabilities =
+			V4L2_CAP_VIDEO_CAPTURE	|
+			V4L2_CAP_STREAMING	|
+			V4L2_CAP_READWRITE;
+		    return 0;
+		}
+
+		case VIDIOC_ENUMINPUT:
+		{
+		    struct v4l2_input *i = arg;
+
+		    if ( i->index )	/* Only one INPUT is supported */
+			  return -EINVAL;
+
+		    memset(i, 0, sizeof(struct v4l2_input));
+		    strcpy(i->name, "usb");
+		    return 0;
+		}
+
+		case VIDIOC_G_INPUT:
+		{
+		    int *i = arg;
+		    *i = 0;	/* Only one INPUT is supported */
+		    return 0;
+		}
+		case VIDIOC_S_INPUT:
+		{
+			int *i = arg;
+
+			if ( *i ) {	/* Only one INPUT is supported */
+				PWC_DEBUG_IOCTL("Only one input source is"\
+					" supported with this webcam.\n");
+				return -EINVAL;
+			}
+			return 0;
+		}
+
+		/* TODO: */
+		case VIDIOC_QUERYCTRL:
+		{
+			struct v4l2_queryctrl *c = arg;
+			int i;
+
+			PWC_DEBUG_IOCTL("ioctl(VIDIOC_QUERYCTRL) query id=%d\n", c->id);
+			for (i=0; i<sizeof(pwc_controls)/sizeof(struct v4l2_queryctrl); i++) {
+				if (pwc_controls[i].id == c->id) {
+					PWC_DEBUG_IOCTL("ioctl(VIDIOC_QUERYCTRL) found\n");
+					memcpy(c,&pwc_controls[i],sizeof(struct v4l2_queryctrl));
+					return 0;
+				}
+			}
+			PWC_DEBUG_IOCTL("ioctl(VIDIOC_QUERYCTRL) not found\n");
+
+			return -EINVAL;
+		}
+		case VIDIOC_G_CTRL:
+		{
+			struct v4l2_control *c = arg;
+			int ret;
+
+			switch (c->id)
+			{
+				case V4L2_CID_BRIGHTNESS:
+					c->value = pwc_get_brightness(pdev);
+					if (c->value<0)
+						return -EINVAL;
+					return 0;
+				case V4L2_CID_CONTRAST:
+					c->value = pwc_get_contrast(pdev);
+					if (c->value<0)
+						return -EINVAL;
+					return 0;
+				case V4L2_CID_SATURATION:
+					ret = pwc_get_saturation(pdev, &c->value);
+					if (ret<0)
+						return -EINVAL;
+					return 0;
+				case V4L2_CID_GAMMA:
+					c->value = pwc_get_gamma(pdev);
+					if (c->value<0)
+						return -EINVAL;
+					return 0;
+				case V4L2_CID_RED_BALANCE:
+					ret = pwc_get_red_gain(pdev, &c->value);
+					if (ret<0)
+						return -EINVAL;
+					c->value >>= 8;
+					return 0;
+				case V4L2_CID_BLUE_BALANCE:
+					ret = pwc_get_blue_gain(pdev, &c->value);
+					if (ret<0)
+						return -EINVAL;
+					c->value >>= 8;
+					return 0;
+				case V4L2_CID_AUTO_WHITE_BALANCE:
+					ret = pwc_get_awb(pdev);
+					if (ret<0)
+						return -EINVAL;
+					c->value = (ret == PWC_WB_MANUAL)?0:1;
+					return 0;
+				case V4L2_CID_GAIN:
+					ret = pwc_get_agc(pdev, &c->value);
+					if (ret<0)
+						return -EINVAL;
+					c->value >>= 8;
+					return 0;
+				case V4L2_CID_AUTOGAIN:
+					ret = pwc_get_agc(pdev, &c->value);
+					if (ret<0)
+						return -EINVAL;
+					c->value = (c->value < 0)?1:0;
+					return 0;
+				case V4L2_CID_EXPOSURE:
+					ret = pwc_get_shutter_speed(pdev, &c->value);
+					if (ret<0)
+						return -EINVAL;
+					return 0;
+				case V4L2_CID_PRIVATE_COLOUR_MODE:
+					ret = pwc_get_colour_mode(pdev, &c->value);
+					if (ret < 0)
+						return -EINVAL;
+					return 0;
+				case V4L2_CID_PRIVATE_AUTOCONTOUR:
+					ret = pwc_get_contour(pdev, &c->value);
+					if (ret < 0)
+						return -EINVAL;
+					c->value=(c->value == -1?1:0);
+					return 0;
+				case V4L2_CID_PRIVATE_CONTOUR:
+					ret = pwc_get_contour(pdev, &c->value);
+					if (ret < 0)
+						return -EINVAL;
+					c->value >>= 10;
+					return 0;
+				case V4L2_CID_PRIVATE_BACKLIGHT:
+					ret = pwc_get_backlight(pdev, &c->value);
+					if (ret < 0)
+						return -EINVAL;
+					return 0;
+				case V4L2_CID_PRIVATE_FLICKERLESS:
+					ret = pwc_get_flicker(pdev, &c->value);
+					if (ret < 0)
+						return -EINVAL;
+					c->value=(c->value?1:0);
+					return 0;
+				case V4L2_CID_PRIVATE_NOISE_REDUCTION:
+					ret = pwc_get_dynamic_noise(pdev, &c->value);
+					if (ret < 0)
+						return -EINVAL;
+					return 0;
+
+				case V4L2_CID_PRIVATE_SAVE_USER:
+				case V4L2_CID_PRIVATE_RESTORE_USER:
+				case V4L2_CID_PRIVATE_RESTORE_FACTORY:
+					return -EINVAL;
+			}
+			return -EINVAL;
+		}
+		case VIDIOC_S_CTRL:
+		{
+			struct v4l2_control *c = arg;
+			int ret;
+
+			switch (c->id)
+			{
+				case V4L2_CID_BRIGHTNESS:
+					c->value <<= 9;
+					ret = pwc_set_brightness(pdev, c->value);
+					if (ret<0)
+						return -EINVAL;
+					return 0;
+				case V4L2_CID_CONTRAST:
+					c->value <<= 10;
+					ret = pwc_set_contrast(pdev, c->value);
+					if (ret<0)
+						return -EINVAL;
+					return 0;
+				case V4L2_CID_SATURATION:
+					ret = pwc_set_saturation(pdev, c->value);
+					if (ret<0)
+					  return -EINVAL;
+					return 0;
+				case V4L2_CID_GAMMA:
+					c->value <<= 11;
+					ret = pwc_set_gamma(pdev, c->value);
+					if (ret<0)
+						return -EINVAL;
+					return 0;
+				case V4L2_CID_RED_BALANCE:
+					c->value <<= 8;
+					ret = pwc_set_red_gain(pdev, c->value);
+					if (ret<0)
+						return -EINVAL;
+					return 0;
+				case V4L2_CID_BLUE_BALANCE:
+					c->value <<= 8;
+					ret = pwc_set_blue_gain(pdev, c->value);
+					if (ret<0)
+						return -EINVAL;
+					return 0;
+				case V4L2_CID_AUTO_WHITE_BALANCE:
+					c->value = (c->value == 0)?PWC_WB_MANUAL:PWC_WB_AUTO;
+					ret = pwc_set_awb(pdev, c->value);
+					if (ret<0)
+						return -EINVAL;
+					return 0;
+				case V4L2_CID_EXPOSURE:
+					c->value <<= 8;
+					ret = pwc_set_shutter_speed(pdev, c->value?0:1, c->value);
+					if (ret<0)
+						return -EINVAL;
+					return 0;
+				case V4L2_CID_AUTOGAIN:
+					/* autogain off means nothing without a gain */
+					if (c->value == 0)
+						return 0;
+					ret = pwc_set_agc(pdev, c->value, 0);
+					if (ret<0)
+						return -EINVAL;
+					return 0;
+				case V4L2_CID_GAIN:
+					c->value <<= 8;
+					ret = pwc_set_agc(pdev, 0, c->value);
+					if (ret<0)
+						return -EINVAL;
+					return 0;
+				case V4L2_CID_PRIVATE_SAVE_USER:
+					if (pwc_save_user(pdev))
+						return -EINVAL;
+					return 0;
+				case V4L2_CID_PRIVATE_RESTORE_USER:
+					if (pwc_restore_user(pdev))
+						return -EINVAL;
+					return 0;
+				case V4L2_CID_PRIVATE_RESTORE_FACTORY:
+					if (pwc_restore_factory(pdev))
+						return -EINVAL;
+					return 0;
+				case V4L2_CID_PRIVATE_COLOUR_MODE:
+					ret = pwc_set_colour_mode(pdev, c->value);
+					if (ret < 0)
+					  return -EINVAL;
+					return 0;
+				case V4L2_CID_PRIVATE_AUTOCONTOUR:
+				  c->value=(c->value == 1)?-1:0;
+				  ret = pwc_set_contour(pdev, c->value);
+				  if (ret < 0)
+				    return -EINVAL;
+				  return 0;
+				case V4L2_CID_PRIVATE_CONTOUR:
+				  c->value <<= 10;
+				  ret = pwc_set_contour(pdev, c->value);
+				  if (ret < 0)
+				    return -EINVAL;
+				  return 0;
+				case V4L2_CID_PRIVATE_BACKLIGHT:
+				  ret = pwc_set_backlight(pdev, c->value);
+				  if (ret < 0)
+				    return -EINVAL;
+				  return 0;
+				case V4L2_CID_PRIVATE_FLICKERLESS:
+				  ret = pwc_set_flicker(pdev, c->value);
+				  if (ret < 0)
+				    return -EINVAL;
+				case V4L2_CID_PRIVATE_NOISE_REDUCTION:
+				  ret = pwc_set_dynamic_noise(pdev, c->value);
+				  if (ret < 0)
+				    return -EINVAL;
+				  return 0;
+
+			}
+			return -EINVAL;
+		}
+
+		case VIDIOC_ENUM_FMT:
+		{
+			struct v4l2_fmtdesc *f = arg;
+			int index;
+
+			if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+			      return -EINVAL;
+
+			/* We only support two format: the raw format, and YUV */
+			index = f->index;
+			memset(f,0,sizeof(struct v4l2_fmtdesc));
+			f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+			f->index = index;
+			switch(index)
+			{
+				case 0:
+					/* RAW format */
+					f->pixelformat = pdev->type<=646?V4L2_PIX_FMT_PWC1:V4L2_PIX_FMT_PWC2;
+					f->flags = V4L2_FMT_FLAG_COMPRESSED;
+					strlcpy(f->description,"Raw Philips Webcam",sizeof(f->description));
+					break;
+				case 1:
+					f->pixelformat = V4L2_PIX_FMT_YUV420;
+					strlcpy(f->description,"4:2:0, planar, Y-Cb-Cr",sizeof(f->description));
+					break;
+				default:
+					return -EINVAL;
+			}
+			return 0;
+		}
+
+		case VIDIOC_G_FMT:
+		{
+			struct v4l2_format *f = arg;
+
+			PWC_DEBUG_IOCTL("ioctl(VIDIOC_G_FMT) return size %dx%d\n",pdev->image.x,pdev->image.y);
+			if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+			      return -EINVAL;
+
+			pwc_vidioc_fill_fmt(pdev, f);
+
+			return 0;
+		}
+
+		case VIDIOC_TRY_FMT:
+			return pwc_vidioc_try_fmt(pdev, arg);
+
+		case VIDIOC_S_FMT:
+			return pwc_vidioc_set_fmt(pdev, arg);
+
+		case VIDIOC_G_STD:
+		{
+			v4l2_std_id *std = arg;
+			*std = V4L2_STD_UNKNOWN;
+			return 0;
+		}
+
+		case VIDIOC_S_STD:
+		{
+			v4l2_std_id *std = arg;
+			if (*std != V4L2_STD_UNKNOWN)
+				return -EINVAL;
+			return 0;
+		}
+
+		case VIDIOC_ENUMSTD:
+		{
+			struct v4l2_standard *std = arg;
+			if (std->index != 0)
+				return -EINVAL;
+			std->id = V4L2_STD_UNKNOWN;
+			strncpy(std->name, "webcam", sizeof(std->name));
+			return 0;
+		}
+
+		case VIDIOC_REQBUFS:
+		{
+			struct v4l2_requestbuffers *rb = arg;
+			int nbuffers;
+
+			PWC_DEBUG_IOCTL("ioctl(VIDIOC_REQBUFS) count=%d\n",rb->count);
+			if (rb->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+				return -EINVAL;
+			if (rb->memory != V4L2_MEMORY_MMAP)
+				return -EINVAL;
+
+			nbuffers = rb->count;
+			if (nbuffers < 2)
+				nbuffers = 2;
+			else if (nbuffers > pwc_mbufs)
+				nbuffers = pwc_mbufs;
+			/* Force to use our # of buffers */
+			rb->count = pwc_mbufs;
+			return 0;
+		}
+
+		case VIDIOC_QUERYBUF:
+		{
+			struct v4l2_buffer *buf = arg;
+			int index;
+
+			PWC_DEBUG_IOCTL("ioctl(VIDIOC_QUERYBUF) index=%d\n",buf->index);
+			if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
+				PWC_DEBUG_IOCTL("ioctl(VIDIOC_QUERYBUF) Bad type\n");
+				return -EINVAL;
+			}
+			if (buf->memory != V4L2_MEMORY_MMAP) {
+				PWC_DEBUG_IOCTL("ioctl(VIDIOC_QUERYBUF) Bad memory type\n");
+				return -EINVAL;
+			}
+			index = buf->index;
+			if (index < 0 || index >= pwc_mbufs) {
+				PWC_DEBUG_IOCTL("ioctl(VIDIOC_QUERYBUF) Bad index %d\n", buf->index);
+				return -EINVAL;
+			}
+
+			memset(buf, 0, sizeof(struct v4l2_buffer));
+			buf->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+			buf->index = index;
+			buf->m.offset = index * pdev->len_per_image;
+			if (pdev->vpalette == VIDEO_PALETTE_RAW)
+				buf->bytesused = pdev->frame_size + sizeof(struct pwc_raw_frame);
+			else
+				buf->bytesused = pdev->view.size;
+			buf->field = V4L2_FIELD_NONE;
+			buf->memory = V4L2_MEMORY_MMAP;
+			//buf->flags = V4L2_BUF_FLAG_MAPPED;
+			buf->length = pdev->len_per_image;
+
+			PWC_DEBUG_READ("VIDIOC_QUERYBUF: index=%d\n",buf->index);
+			PWC_DEBUG_READ("VIDIOC_QUERYBUF: m.offset=%d\n",buf->m.offset);
+			PWC_DEBUG_READ("VIDIOC_QUERYBUF: bytesused=%d\n",buf->bytesused);
+
+			return 0;
+		}
+
+		case VIDIOC_QBUF:
+		{
+			struct v4l2_buffer *buf = arg;
+
+			PWC_DEBUG_IOCTL("ioctl(VIDIOC_QBUF) index=%d\n",buf->index);
+			if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+				return -EINVAL;
+			if (buf->memory != V4L2_MEMORY_MMAP)
+				return -EINVAL;
+			if (buf->index < 0 || buf->index >= pwc_mbufs)
+				return -EINVAL;
+
+			buf->flags |= V4L2_BUF_FLAG_QUEUED;
+			buf->flags &= ~V4L2_BUF_FLAG_DONE;
+
+			return 0;
+		}
+
+		case VIDIOC_DQBUF:
+		{
+			struct v4l2_buffer *buf = arg;
+			int ret;
+
+			PWC_DEBUG_IOCTL("ioctl(VIDIOC_DQBUF)\n");
+
+			if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+				return -EINVAL;
+
+			/* Add ourselves to the frame wait-queue.
+
+			   FIXME: needs auditing for safety.
+			   QUESTION: In what respect? I think that using the
+				     frameq is safe now.
+			 */
+			add_wait_queue(&pdev->frameq, &wait);
+			while (pdev->full_frames == NULL) {
+				if (pdev->error_status) {
+					remove_wait_queue(&pdev->frameq, &wait);
+					set_current_state(TASK_RUNNING);
+					return -pdev->error_status;
+				}
+
+				if (signal_pending(current)) {
+					remove_wait_queue(&pdev->frameq, &wait);
+					set_current_state(TASK_RUNNING);
+					return -ERESTARTSYS;
+				}
+				schedule();
+				set_current_state(TASK_INTERRUPTIBLE);
+			}
+			remove_wait_queue(&pdev->frameq, &wait);
+			set_current_state(TASK_RUNNING);
+
+			PWC_DEBUG_IOCTL("VIDIOC_DQBUF: frame ready.\n");
+			/* Decompress data in pdev->images[pdev->fill_image] */
+			ret = pwc_handle_frame(pdev);
+			if (ret)
+				return -EFAULT;
+			PWC_DEBUG_IOCTL("VIDIOC_DQBUF: after pwc_handle_frame\n");
+
+			buf->index = pdev->fill_image;
+			if (pdev->vpalette == VIDEO_PALETTE_RAW)
+				buf->bytesused = pdev->frame_size + sizeof(struct pwc_raw_frame);
+			else
+				buf->bytesused = pdev->view.size;
+			buf->flags = V4L2_BUF_FLAG_MAPPED;
+			buf->field = V4L2_FIELD_NONE;
+			do_gettimeofday(&buf->timestamp);
+			buf->sequence = 0;
+			buf->memory = V4L2_MEMORY_MMAP;
+			buf->m.offset = pdev->fill_image * pdev->len_per_image;
+			buf->length = buf->bytesused;
+			pwc_next_image(pdev);
+
+			PWC_DEBUG_IOCTL("VIDIOC_DQBUF: buf->index=%d\n",buf->index);
+			PWC_DEBUG_IOCTL("VIDIOC_DQBUF: buf->length=%d\n",buf->length);
+			PWC_DEBUG_IOCTL("VIDIOC_DQBUF: m.offset=%d\n",buf->m.offset);
+			PWC_DEBUG_IOCTL("VIDIOC_DQBUF: bytesused=%d\n",buf->bytesused);
+			PWC_DEBUG_IOCTL("VIDIOC_DQBUF: leaving\n");
+			return 0;
+
+		}
+
+		case VIDIOC_STREAMON:
+		{
+			/* WARNING: pwc_try_video_mode() called pwc_isoc_init */
+			pwc_isoc_init(pdev);
+			return 0;
+		}
+
+		case VIDIOC_STREAMOFF:
+		{
+			pwc_isoc_cleanup(pdev);
+			return 0;
+		}
+
+		default:
+			return pwc_ioctl(pdev, cmd, arg);
+	} /* ..switch */
+	return 0;
+}
+
+/* vim: set cino= formatoptions=croql cindent shiftwidth=8 tabstop=8: */
diff --git a/drivers/media/video/tlv320aic23b.c b/drivers/media/video/tlv320aic23b.c
new file mode 100644
index 000000000..76b2e9642
--- /dev/null
+++ b/drivers/media/video/tlv320aic23b.c
@@ -0,0 +1,217 @@
+/*
+ * tlv320aic23b - driver version 0.0.1
+ *
+ * Copyright (C) 2006 Scott Alfter <salfter@ssai.us>
+ *
+ * Based on wm8775 driver
+ *
+ * Copyright (C) 2004 Ulf Eklund <ivtv at eklund.to>
+ * Copyright (C) 2005 Hans Verkuil <hverkuil@xs4all.nl>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/ioctl.h>
+#include <asm/uaccess.h>
+#include <linux/i2c.h>
+#include <linux/i2c-id.h>
+#include <linux/videodev.h>
+#include <media/v4l2-common.h>
+
+MODULE_DESCRIPTION("tlv320aic23b driver");
+MODULE_AUTHOR("Scott Alfter, Ulf Eklund, Hans Verkuil");
+MODULE_LICENSE("GPL");
+
+static unsigned short normal_i2c[] = { 0x34 >> 1, I2C_CLIENT_END };
+
+
+I2C_CLIENT_INSMOD;
+
+/* ----------------------------------------------------------------------- */
+
+struct tlv320aic23b_state {
+	u8 muted;
+};
+
+static int tlv320aic23b_write(struct i2c_client *client, int reg, u16 val)
+{
+	int i;
+
+	if ((reg < 0 || reg > 9) && (reg != 15)) {
+		v4l_err(client, "Invalid register R%d\n", reg);
+		return -1;
+	}
+
+	for (i = 0; i < 3; i++) {
+		if (i2c_smbus_write_byte_data(client, (reg << 1) |
+					(val >> 8), val & 0xff) == 0) {
+			return 0;
+		}
+	}
+	v4l_err(client, "I2C: cannot write %03x to register R%d\n", val, reg);
+	return -1;
+}
+
+static int tlv320aic23b_command(struct i2c_client *client, unsigned int cmd,
+			  void *arg)
+{
+	struct tlv320aic23b_state *state = i2c_get_clientdata(client);
+	struct v4l2_control *ctrl = arg;
+	u32* freq = arg;
+
+	switch (cmd) {
+	case VIDIOC_INT_AUDIO_CLOCK_FREQ:
+		switch (*freq) {
+			case 32000: /* set sample rate to 32 kHz */
+				tlv320aic23b_write(client, 8, 0x018);
+				break;
+			case 44100: /* set sample rate to 44.1 kHz */
+				tlv320aic23b_write(client, 8, 0x022);
+				break;
+			case 48000: /* set sample rate to 48 kHz */
+				tlv320aic23b_write(client, 8, 0x000);
+				break;
+			default:
+				return -EINVAL;
+		}
+		break;
+
+	case VIDIOC_G_CTRL:
+		if (ctrl->id != V4L2_CID_AUDIO_MUTE)
+			return -EINVAL;
+		ctrl->value = state->muted;
+		break;
+
+	case VIDIOC_S_CTRL:
+		if (ctrl->id != V4L2_CID_AUDIO_MUTE)
+			return -EINVAL;
+		state->muted = ctrl->value;
+		tlv320aic23b_write(client, 0, 0x180); /* mute both channels */
+		/* set gain on both channels to +3.0 dB */
+		if (!state->muted)
+			tlv320aic23b_write(client, 0, 0x119);
+		break;
+
+	case VIDIOC_LOG_STATUS:
+		v4l_info(client, "Input: %s\n",
+			    state->muted ? "muted" : "active");
+		break;
+
+	default:
+		return -EINVAL;
+	}
+	return 0;
+}
+
+/* ----------------------------------------------------------------------- */
+
+/* i2c implementation */
+
+/*
+ * Generic i2c probe
+ * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1'
+ */
+
+static struct i2c_driver i2c_driver;
+
+static int tlv320aic23b_attach(struct i2c_adapter *adapter, int address, int kind)
+{
+	struct i2c_client *client;
+	struct tlv320aic23b_state *state;
+
+	/* Check if the adapter supports the needed features */
+	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
+		return 0;
+
+	client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL);
+	if (client == 0)
+		return -ENOMEM;
+
+	client->addr = address;
+	client->adapter = adapter;
+	client->driver = &i2c_driver;
+	snprintf(client->name, sizeof(client->name) - 1, "tlv320aic23b");
+
+	v4l_info(client, "chip found @ 0x%x (%s)\n", address << 1, adapter->name);
+
+	state = kmalloc(sizeof(struct tlv320aic23b_state), GFP_KERNEL);
+	if (state == NULL) {
+		kfree(client);
+		return -ENOMEM;
+	}
+	state->muted = 0;
+	i2c_set_clientdata(client, state);
+
+	/* initialize tlv320aic23b */
+	tlv320aic23b_write(client, 15, 0x000);	/* RESET */
+	tlv320aic23b_write(client, 6, 0x00A);   /* turn off DAC & mic input */
+	tlv320aic23b_write(client, 7, 0x049);   /* left-justified, 24-bit, master mode */
+	tlv320aic23b_write(client, 0, 0x119);   /* set gain on both channels to +3.0 dB */
+	tlv320aic23b_write(client, 8, 0x000);   /* set sample rate to 48 kHz */
+	tlv320aic23b_write(client, 9, 0x001);   /* activate digital interface */
+
+	i2c_attach_client(client);
+
+	return 0;
+}
+
+static int tlv320aic23b_probe(struct i2c_adapter *adapter)
+{
+	if (adapter->class & I2C_CLASS_TV_ANALOG)
+		return i2c_probe(adapter, &addr_data, tlv320aic23b_attach);
+	return 0;
+}
+
+static int tlv320aic23b_detach(struct i2c_client *client)
+{
+	int err;
+
+	err = i2c_detach_client(client);
+	if (err) {
+		return err;
+	}
+	kfree(client);
+
+	return 0;
+}
+
+/* ----------------------------------------------------------------------- */
+
+/* i2c implementation */
+static struct i2c_driver i2c_driver = {
+	.driver = {
+		.name = "tlv320aic23b",
+	},
+	.id             = I2C_DRIVERID_TLV320AIC23B,
+	.attach_adapter = tlv320aic23b_probe,
+	.detach_client  = tlv320aic23b_detach,
+	.command        = tlv320aic23b_command,
+};
+
+
+static int __init tlv320aic23b_init_module(void)
+{
+	return i2c_add_driver(&i2c_driver);
+}
+
+static void __exit tlv320aic23b_cleanup_module(void)
+{
+	i2c_del_driver(&i2c_driver);
+}
+
+module_init(tlv320aic23b_init_module);
+module_exit(tlv320aic23b_cleanup_module);
diff --git a/drivers/media/video/usbvideo/quickcam_messenger.c b/drivers/media/video/usbvideo/quickcam_messenger.c
new file mode 100644
index 000000000..56e01b622
--- /dev/null
+++ b/drivers/media/video/usbvideo/quickcam_messenger.c
@@ -0,0 +1,1120 @@
+/*
+ * Driver for Logitech Quickcam Messenger usb video camera
+ * Copyright (C) Jaya Kumar
+ *
+ * This work was sponsored by CIS(M) Sdn Bhd.
+ * History:
+ * 05/08/2006 - Jaya Kumar
+ * I wrote this based on the konicawc by Simon Evans.
+ * -
+ * Full credit for reverse engineering and creating an initial
+ * working linux driver for the VV6422 goes to the qce-ga project by
+ * Tuukka Toivonen, Jochen Hoenicke, Peter McConnell,
+ * Cristiano De Michele, Georg Acher, Jean-Frederic Clere as well as
+ * others.
+ * ---
+ * 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/input.h>
+#include <linux/usb/input.h>
+
+#include "usbvideo.h"
+#include "quickcam_messenger.h"
+
+/*
+ * Version Information
+ */
+
+#ifdef CONFIG_USB_DEBUG
+static int debug;
+#define DEBUG(n, format, arg...) \
+	if (n <= debug) {	 \
+		printk(KERN_DEBUG __FILE__ ":%s(): " format "\n", __FUNCTION__ , ## arg); \
+	}
+#else
+#define DEBUG(n, arg...)
+static const int debug = 0;
+#endif
+
+#define DRIVER_VERSION "v0.01"
+#define DRIVER_DESC "Logitech Quickcam Messenger USB"
+
+#define USB_LOGITECH_VENDOR_ID	0x046D
+#define USB_QCM_PRODUCT_ID	0x08F0
+
+#define MAX_CAMERAS	1
+
+#define MAX_COLOUR	32768
+#define MAX_HUE		32768
+#define MAX_BRIGHTNESS	32768
+#define MAX_CONTRAST	32768
+#define MAX_WHITENESS	32768
+
+static int size = SIZE_320X240;
+static int colour = MAX_COLOUR;
+static int hue = MAX_HUE;
+static int brightness =	MAX_BRIGHTNESS;
+static int contrast =	MAX_CONTRAST;
+static int whiteness =	MAX_WHITENESS;
+
+static struct usbvideo *cams;
+
+static struct usb_device_id qcm_table [] = {
+	{ USB_DEVICE(USB_LOGITECH_VENDOR_ID, USB_QCM_PRODUCT_ID) },
+	{ }
+};
+MODULE_DEVICE_TABLE(usb, qcm_table);
+
+#ifdef CONFIG_INPUT
+static void qcm_register_input(struct qcm *cam, struct usb_device *dev)
+{
+	struct input_dev *input_dev;
+
+	usb_make_path(dev, cam->input_physname, sizeof(cam->input_physname));
+	strncat(cam->input_physname, "/input0", sizeof(cam->input_physname));
+
+	cam->input = input_dev = input_allocate_device();
+	if (!input_dev) {
+		warn("insufficient mem for cam input device");
+		return;
+	}
+
+	input_dev->name = "QCM button";
+	input_dev->phys = cam->input_physname;
+	usb_to_input_id(dev, &input_dev->id);
+	input_dev->cdev.dev = &dev->dev;
+
+	input_dev->evbit[0] = BIT(EV_KEY);
+	input_dev->keybit[LONG(BTN_0)] = BIT(BTN_0);
+
+	input_dev->private = cam;
+
+	input_register_device(cam->input);
+}
+
+static void qcm_unregister_input(struct qcm *cam)
+{
+	if (cam->input) {
+		input_unregister_device(cam->input);
+		cam->input = NULL;
+	}
+}
+
+static void qcm_report_buttonstat(struct qcm *cam)
+{
+	if (cam->input) {
+		input_report_key(cam->input, BTN_0, cam->button_sts);
+		input_sync(cam->input);
+	}
+}
+
+static void qcm_int_irq(struct urb *urb, struct pt_regs *regs)
+{
+	int ret;
+	struct uvd *uvd = urb->context;
+	struct qcm *cam;
+
+	if (!CAMERA_IS_OPERATIONAL(uvd))
+		return;
+
+	if (!uvd->streaming)
+		return;
+
+	uvd->stats.urb_count++;
+
+	if (urb->status < 0)
+		uvd->stats.iso_err_count++;
+	else {
+		if (urb->actual_length > 0 ) {
+			cam = (struct qcm *) uvd->user_data;
+			if (cam->button_sts_buf == 0x88)
+				cam->button_sts = 0x0;
+			else if (cam->button_sts_buf == 0x80)
+				cam->button_sts = 0x1;
+			qcm_report_buttonstat(cam);
+		}
+	}
+
+	ret = usb_submit_urb(urb, GFP_ATOMIC);
+	if (ret < 0)
+		err("usb_submit_urb error (%d)", ret);
+}
+
+static int qcm_setup_input_int(struct qcm *cam, struct uvd *uvd)
+{
+	int errflag;
+	usb_fill_int_urb(cam->button_urb, uvd->dev,
+			usb_rcvintpipe(uvd->dev, uvd->video_endp + 1),
+			&cam->button_sts_buf,
+			1,
+			qcm_int_irq,
+			uvd, 16);
+
+	errflag = usb_submit_urb(cam->button_urb, GFP_KERNEL);
+	if (errflag)
+		err ("usb_submit_int ret %d", errflag);
+	return errflag;
+}
+
+static void qcm_stop_int_data(struct qcm *cam)
+{
+	usb_kill_urb(cam->button_urb);
+}
+
+static int qcm_alloc_int_urb(struct qcm *cam)
+{
+	cam->button_urb = usb_alloc_urb(0, GFP_KERNEL);
+
+	if (!cam->button_urb)
+		return -ENOMEM;
+
+	return 0;
+}
+
+static void qcm_free_int(struct qcm *cam)
+{
+	if (cam->button_urb)
+		usb_free_urb(cam->button_urb);
+}
+#endif /* CONFIG_INPUT */
+
+static int qcm_stv_setb(struct usb_device *dev, u16 reg, u8 val)
+{
+	int ret;
+
+	/* we'll wait up to 3 slices but no more */
+	ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
+		0x04, USB_TYPE_VENDOR | USB_DIR_OUT | USB_RECIP_DEVICE,
+		reg, 0, &val, 1, 3*HZ);
+	return ret;
+}
+
+static int qcm_stv_setw(struct usb_device *dev, u16 reg, u16 val)
+{
+	int ret;
+
+	/* we'll wait up to 3 slices but no more */
+	ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
+		0x04, USB_TYPE_VENDOR | USB_DIR_OUT | USB_RECIP_DEVICE,
+		reg, 0, &val, 2, 3*HZ);
+	return ret;
+}
+
+static int qcm_stv_getw(struct usb_device *dev, unsigned short reg,
+							__le16 *val)
+{
+	int ret;
+
+	/* we'll wait up to 3 slices but no more */
+	ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
+		0x04, USB_TYPE_VENDOR | USB_DIR_IN | USB_RECIP_DEVICE,
+		reg, 0, val, 2, 3*HZ);
+	return ret;
+}
+
+static int qcm_camera_on(struct uvd *uvd)
+{
+	int ret;
+	CHECK_RET(ret, qcm_stv_setb(uvd->dev, STV_ISO_ENABLE, 0x01));
+	return 0;
+}
+
+static int qcm_camera_off(struct uvd *uvd)
+{
+	int ret;
+	CHECK_RET(ret, qcm_stv_setb(uvd->dev, STV_ISO_ENABLE, 0x00));
+	return 0;
+}
+
+static void qcm_hsv2rgb(u16 hue, u16 sat, u16 val, u16 *r, u16 *g, u16 *b)
+{
+	unsigned int segment, valsat;
+	signed int   h = (signed int) hue;
+	unsigned int s = (sat - 32768) * 2;	/* rescale */
+	unsigned int v = val;
+	unsigned int p;
+
+	/*
+	the registers controling gain are 8 bit of which
+	we affect only the last 4 bits with our gain.
+	we know that if saturation is 0, (unsaturated) then
+	we're grayscale (center axis of the colour cone) so
+	we set rgb=value. we use a formula obtained from
+	wikipedia to map the cone to the RGB plane. it's
+	as follows for the human value case of h=0..360,
+	s=0..1, v=0..1
+	h_i = h/60 % 6 , f = h/60 - h_i , p = v(1-s)
+	q = v(1 - f*s) , t = v(1 - (1-f)s)
+	h_i==0 => r=v , g=t, b=p
+	h_i==1 => r=q , g=v, b=p
+	h_i==2 => r=p , g=v, b=t
+	h_i==3 => r=p , g=q, b=v
+	h_i==4 => r=t , g=p, b=v
+	h_i==5 => r=v , g=p, b=q
+	the bottom side (the point) and the stuff just up
+	of that is black so we simplify those two cases.
+	*/
+	if (sat < 32768) {
+		/* anything less than this is unsaturated */
+		*r = val;
+		*g = val;
+		*b = val;
+		return;
+	}
+	if (val <= (0xFFFF/8)) {
+		/* anything less than this is black */
+		*r = 0;
+		*g = 0;
+		*b = 0;
+		return;
+	}
+
+	/* the rest of this code is copying tukkat's
+	implementation of the hsv2rgb conversion as taken
+	from qc-usb-messenger code. the 10923 is 0xFFFF/6
+	to divide the cone into 6 sectors.  */
+
+	segment = (h + 10923) & 0xFFFF;
+	segment = segment*3 >> 16;		/* 0..2: 0=R, 1=G, 2=B */
+	hue -= segment * 21845;			/* -10923..10923 */
+	h = hue;
+	h *= 3;
+	valsat = v*s >> 16;			/* 0..65534 */
+	p = v - valsat;
+	if (h >= 0) {
+		unsigned int t = v - (valsat * (32769 - h) >> 15);
+		switch (segment) {
+		case 0:	/* R-> */
+			*r = v;
+			*g = t;
+			*b = p;
+			break;
+		case 1:	/* G-> */
+			*r = p;
+			*g = v;
+			*b = t;
+			break;
+		case 2:	/* B-> */
+			*r = t;
+			*g = p;
+			*b = v;
+			break;
+		}
+	} else {
+		unsigned int q = v - (valsat * (32769 + h) >> 15);
+		switch (segment) {
+		case 0:	/* ->R */
+			*r = v;
+			*g = p;
+			*b = q;
+			break;
+		case 1:	/* ->G */
+			*r = q;
+			*g = v;
+			*b = p;
+			break;
+		case 2:	/* ->B */
+			*r = p;
+			*g = q;
+			*b = v;
+			break;
+		}
+	}
+}
+
+static int qcm_sensor_set_gains(struct uvd *uvd, u16 hue,
+	u16 saturation, u16 value)
+{
+	int ret;
+	u16 r=0,g=0,b=0;
+
+	/* this code is based on qc-usb-messenger */
+	qcm_hsv2rgb(hue, saturation, value, &r, &g, &b);
+
+	r >>= 12;
+	g >>= 12;
+	b >>= 12;
+
+	/* min val is 8 */
+	r = max((u16) 8, r);
+	g = max((u16) 8, g);
+	b = max((u16) 8, b);
+
+	r |= 0x30;
+	g |= 0x30;
+	b |= 0x30;
+
+	/* set the r,g,b gain registers */
+	CHECK_RET(ret, qcm_stv_setb(uvd->dev, 0x0509, r));
+	CHECK_RET(ret, qcm_stv_setb(uvd->dev, 0x050A, g));
+	CHECK_RET(ret, qcm_stv_setb(uvd->dev, 0x050B, b));
+
+	/* doing as qc-usb did */
+	CHECK_RET(ret, qcm_stv_setb(uvd->dev, 0x050C, 0x2A));
+	CHECK_RET(ret, qcm_stv_setb(uvd->dev, 0x050D, 0x01));
+	CHECK_RET(ret, qcm_stv_setb(uvd->dev, 0x143F, 0x01));
+
+	return 0;
+}
+
+static int qcm_sensor_set_exposure(struct uvd *uvd, int exposure)
+{
+	int ret;
+	int formedval;
+
+	/* calculation was from qc-usb-messenger driver */
+	formedval = ( exposure >> 12 );
+
+	/* max value for formedval is 14 */
+	formedval = min(formedval, 14);
+
+	CHECK_RET(ret, qcm_stv_setb(uvd->dev,
+			0x143A, 0xF0 | formedval));
+	CHECK_RET(ret, qcm_stv_setb(uvd->dev, 0x143F, 0x01));
+	return 0;
+}
+
+static int qcm_sensor_setlevels(struct uvd *uvd, int brightness, int contrast,
+					int hue, int colour)
+{
+	int ret;
+	/* brightness is exposure, contrast is gain, colour is saturation */
+	CHECK_RET(ret,
+		qcm_sensor_set_exposure(uvd, brightness));
+	CHECK_RET(ret, qcm_sensor_set_gains(uvd, hue, colour, contrast));
+
+	return 0;
+}
+
+static int qcm_sensor_setsize(struct uvd *uvd, u8 size)
+{
+	int ret;
+
+	CHECK_RET(ret, qcm_stv_setb(uvd->dev, 0x1505, size));
+	return 0;
+}
+
+static int qcm_sensor_set_shutter(struct uvd *uvd, int whiteness)
+{
+	int ret;
+	/* some rescaling as done by the qc-usb-messenger code */
+	if (whiteness > 0xC000)
+		whiteness = 0xC000 + (whiteness & 0x3FFF)*8;
+
+	CHECK_RET(ret, qcm_stv_setb(uvd->dev, 0x143D,
+				(whiteness >> 8) & 0xFF));
+	CHECK_RET(ret, qcm_stv_setb(uvd->dev, 0x143E,
+				(whiteness >> 16) & 0x03));
+	CHECK_RET(ret, qcm_stv_setb(uvd->dev, 0x143F, 0x01));
+
+	return 0;
+}
+
+static int qcm_sensor_init(struct uvd *uvd)
+{
+	struct qcm *cam = (struct qcm *) uvd->user_data;
+	int ret;
+	int i;
+
+	for (i=0; i < sizeof(regval_table)/sizeof(regval_table[0]) ; i++) {
+		CHECK_RET(ret, qcm_stv_setb(uvd->dev,
+					regval_table[i].reg,
+					regval_table[i].val));
+	}
+
+	CHECK_RET(ret, qcm_stv_setw(uvd->dev, 0x15c1,
+				cpu_to_le16(ISOC_PACKET_SIZE)));
+	CHECK_RET(ret, qcm_stv_setb(uvd->dev, 0x15c3, 0x08));
+	CHECK_RET(ret, ret = qcm_stv_setb(uvd->dev, 0x143f, 0x01));
+
+	CHECK_RET(ret, qcm_stv_setb(uvd->dev, STV_ISO_ENABLE, 0x00));
+
+	CHECK_RET(ret, qcm_sensor_setsize(uvd, camera_sizes[cam->size].cmd));
+
+	CHECK_RET(ret, qcm_sensor_setlevels(uvd, uvd->vpic.brightness,
+			uvd->vpic.contrast, uvd->vpic.hue, uvd->vpic.colour));
+
+	CHECK_RET(ret, qcm_sensor_set_shutter(uvd, uvd->vpic.whiteness));
+	CHECK_RET(ret, qcm_sensor_setsize(uvd, camera_sizes[cam->size].cmd));
+
+	return 0;
+}
+
+static int qcm_set_camera_size(struct uvd *uvd)
+{
+	int ret;
+	struct qcm *cam = (struct qcm *) uvd->user_data;
+
+	CHECK_RET(ret, qcm_sensor_setsize(uvd, camera_sizes[cam->size].cmd));
+	cam->width = camera_sizes[cam->size].width;
+	cam->height = camera_sizes[cam->size].height;
+	uvd->videosize = VIDEOSIZE(cam->width, cam->height);
+
+	return 0;
+}
+
+static int qcm_setup_on_open(struct uvd *uvd)
+{
+	int ret;
+
+	CHECK_RET(ret, qcm_sensor_set_gains(uvd, uvd->vpic.hue,
+				uvd->vpic.colour, uvd->vpic.contrast));
+	CHECK_RET(ret, qcm_sensor_set_exposure(uvd, uvd->vpic.brightness));
+	CHECK_RET(ret, qcm_sensor_set_shutter(uvd, uvd->vpic.whiteness));
+	CHECK_RET(ret, qcm_set_camera_size(uvd));
+	CHECK_RET(ret, qcm_camera_on(uvd));
+	return 0;
+}
+
+static void qcm_adjust_picture(struct uvd *uvd)
+{
+	int ret;
+	struct qcm *cam = (struct qcm *) uvd->user_data;
+
+	ret = qcm_camera_off(uvd);
+	if (ret) {
+		err("can't turn camera off. abandoning pic adjustment");
+		return;
+	}
+
+	/* if there's been a change in contrast, hue, or
+	colour then we need to recalculate hsv in order
+	to update gains */
+	if ((cam->contrast != uvd->vpic.contrast) ||
+		(cam->hue != uvd->vpic.hue) ||
+		(cam->colour != uvd->vpic.colour)) {
+		cam->contrast = uvd->vpic.contrast;
+		cam->hue = uvd->vpic.hue;
+		cam->colour = uvd->vpic.colour;
+		ret = qcm_sensor_set_gains(uvd, cam->hue, cam->colour,
+						cam->contrast);
+		if (ret) {
+			err("can't set gains. abandoning pic adjustment");
+			return;
+		}
+	}
+
+	if (cam->brightness != uvd->vpic.brightness) {
+		cam->brightness = uvd->vpic.brightness;
+		ret = qcm_sensor_set_exposure(uvd, cam->brightness);
+		if (ret) {
+			err("can't set exposure. abandoning pic adjustment");
+			return;
+		}
+	}
+
+	if (cam->whiteness != uvd->vpic.whiteness) {
+		cam->whiteness = uvd->vpic.whiteness;
+		qcm_sensor_set_shutter(uvd, cam->whiteness);
+		if (ret) {
+			err("can't set shutter. abandoning pic adjustment");
+			return;
+		}
+	}
+
+	ret = qcm_camera_on(uvd);
+	if (ret) {
+		err("can't reenable camera. pic adjustment failed");
+		return;
+	}
+}
+
+static int qcm_process_frame(struct uvd *uvd, u8 *cdata, int framelen)
+{
+	int datalen;
+	int totaldata;
+	struct framehdr {
+		__be16 id;
+		__be16 len;
+	};
+	struct framehdr *fhdr;
+
+	totaldata = 0;
+	while (framelen) {
+		fhdr = (struct framehdr *) cdata;
+		datalen = be16_to_cpu(fhdr->len);
+		framelen -= 4;
+		cdata += 4;
+
+		if ((fhdr->id) == cpu_to_be16(0x8001)) {
+			RingQueue_Enqueue(&uvd->dp, marker, 4);
+			totaldata += 4;
+			continue;
+		}
+		if ((fhdr->id & cpu_to_be16(0xFF00)) == cpu_to_be16(0x0200)) {
+			RingQueue_Enqueue(&uvd->dp, cdata, datalen);
+			totaldata += datalen;
+		}
+		framelen -= datalen;
+		cdata += datalen;
+	}
+	return totaldata;
+}
+
+static int qcm_compress_iso(struct uvd *uvd, struct urb *dataurb)
+{
+	int totlen;
+	int i;
+	unsigned char *cdata;
+
+	totlen=0;
+	for (i = 0; i < dataurb->number_of_packets; i++) {
+		int n = dataurb->iso_frame_desc[i].actual_length;
+		int st = dataurb->iso_frame_desc[i].status;
+
+		cdata = dataurb->transfer_buffer +
+			dataurb->iso_frame_desc[i].offset;
+
+		if (st < 0) {
+			warn("Data error: packet=%d. len=%d. status=%d.",
+			      i, n, st);
+			uvd->stats.iso_err_count++;
+			continue;
+		}
+		if (!n)
+			continue;
+
+		totlen += qcm_process_frame(uvd, cdata, n);
+	}
+	return totlen;
+}
+
+static void resubmit_urb(struct uvd *uvd, struct urb *urb)
+{
+	int ret;
+
+	urb->dev = uvd->dev;
+	ret = usb_submit_urb(urb, GFP_ATOMIC);
+	if (ret)
+		err("usb_submit_urb error (%d)", ret);
+}
+
+static void qcm_isoc_irq(struct urb *urb, struct pt_regs *regs)
+{
+	int len;
+	struct uvd *uvd = urb->context;
+
+	if (!CAMERA_IS_OPERATIONAL(uvd))
+		return;
+
+	if (!uvd->streaming)
+		return;
+
+	uvd->stats.urb_count++;
+
+	if (!urb->actual_length) {
+		resubmit_urb(uvd, urb);
+		return;
+	}
+
+	len = qcm_compress_iso(uvd, urb);
+	resubmit_urb(uvd, urb);
+	uvd->stats.urb_length = len;
+	uvd->stats.data_count += len;
+	if (len)
+		RingQueue_WakeUpInterruptible(&uvd->dp);
+}
+
+static int qcm_start_data(struct uvd *uvd)
+{
+	struct qcm *cam = (struct qcm *) uvd->user_data;
+	int i;
+	int errflag;
+	int pktsz;
+	int err;
+
+	pktsz = uvd->iso_packet_len;
+	if (!CAMERA_IS_OPERATIONAL(uvd)) {
+		err("Camera is not operational");
+		return -EFAULT;
+	}
+
+	err = usb_set_interface(uvd->dev, uvd->iface, uvd->ifaceAltActive);
+	if (err < 0) {
+		err("usb_set_interface error");
+		uvd->last_error = err;
+		return -EBUSY;
+	}
+
+	for (i=0; i < USBVIDEO_NUMSBUF; i++) {
+		int j, k;
+		struct urb *urb = uvd->sbuf[i].urb;
+		urb->dev = uvd->dev;
+		urb->context = uvd;
+		urb->pipe = usb_rcvisocpipe(uvd->dev, uvd->video_endp);
+		urb->interval = 1;
+		urb->transfer_flags = URB_ISO_ASAP;
+		urb->transfer_buffer = uvd->sbuf[i].data;
+		urb->complete = qcm_isoc_irq;
+		urb->number_of_packets = FRAMES_PER_DESC;
+		urb->transfer_buffer_length = pktsz * FRAMES_PER_DESC;
+		for (j=k=0; j < FRAMES_PER_DESC; j++, k += pktsz) {
+			urb->iso_frame_desc[j].offset = k;
+			urb->iso_frame_desc[j].length = pktsz;
+		}
+	}
+
+	uvd->streaming = 1;
+	uvd->curframe = -1;
+	for (i=0; i < USBVIDEO_NUMSBUF; i++) {
+		errflag = usb_submit_urb(uvd->sbuf[i].urb, GFP_KERNEL);
+		if (errflag)
+			err ("usb_submit_isoc(%d) ret %d", i, errflag);
+	}
+
+	CHECK_RET(err, qcm_setup_input_int(cam, uvd));
+	CHECK_RET(err, qcm_camera_on(uvd));
+	return 0;
+}
+
+static void qcm_stop_data(struct uvd *uvd)
+{
+	struct qcm *cam = (struct qcm *) uvd->user_data;
+	int i, j;
+	int ret;
+
+	if ((uvd == NULL) || (!uvd->streaming) || (uvd->dev == NULL))
+		return;
+
+	ret = qcm_camera_off(uvd);
+	if (ret)
+		warn("couldn't turn the cam off.");
+
+	uvd->streaming = 0;
+
+	/* Unschedule all of the iso td's */
+	for (i=0; i < USBVIDEO_NUMSBUF; i++)
+		usb_kill_urb(uvd->sbuf[i].urb);
+
+	qcm_stop_int_data(cam);
+
+	if (!uvd->remove_pending) {
+		/* Set packet size to 0 */
+		j = usb_set_interface(uvd->dev, uvd->iface,
+					uvd->ifaceAltInactive);
+		if (j < 0) {
+			err("usb_set_interface() error %d.", j);
+			uvd->last_error = j;
+		}
+	}
+}
+
+static void qcm_process_isoc(struct uvd *uvd, struct usbvideo_frame *frame)
+{
+	struct qcm *cam = (struct qcm *) uvd->user_data;
+	int x;
+	struct rgb *rgbL0;
+	struct rgb *rgbL1;
+	struct bayL0 *bayL0;
+	struct bayL1 *bayL1;
+	int hor,ver,hordel,verdel;
+	assert(frame != NULL);
+
+	switch (cam->size) {
+	case SIZE_160X120:
+		hor = 162; ver = 124; hordel = 1; verdel = 2;
+		break;
+	case SIZE_320X240:
+	default:
+		hor = 324; ver = 248; hordel = 2; verdel = 4;
+		break;
+	}
+
+	if (frame->scanstate == ScanState_Scanning) {
+		while (RingQueue_GetLength(&uvd->dp) >=
+			 4 + (hor*verdel + hordel)) {
+			if ((RING_QUEUE_PEEK(&uvd->dp, 0) == 0x00) &&
+			    (RING_QUEUE_PEEK(&uvd->dp, 1) == 0xff) &&
+			    (RING_QUEUE_PEEK(&uvd->dp, 2) == 0x00) &&
+			    (RING_QUEUE_PEEK(&uvd->dp, 3) == 0xff)) {
+				frame->curline = 0;
+				frame->scanstate = ScanState_Lines;
+				frame->frameState = FrameState_Grabbing;
+				RING_QUEUE_DEQUEUE_BYTES(&uvd->dp, 4);
+			/*
+			* if we're starting, we need to discard the first
+			* 4 lines of y bayer data
+			* and the first 2 gr elements of x bayer data
+			*/
+				RING_QUEUE_DEQUEUE_BYTES(&uvd->dp,
+							(hor*verdel + hordel));
+				break;
+			}
+			RING_QUEUE_DEQUEUE_BYTES(&uvd->dp, 1);
+		}
+	}
+
+	if (frame->scanstate == ScanState_Scanning)
+		return;
+
+	/* now we can start processing bayer data so long as we have at least
+	* 2 lines worth of data. this is the simplest demosaicing method that
+	* I could think of. I use each 2x2 bayer element without interpolation
+	* to generate 4 rgb pixels.
+	*/
+	while ( frame->curline < cam->height &&
+		(RingQueue_GetLength(&uvd->dp) >= hor*2)) {
+		/* get 2 lines of bayer for demosaicing
+		 * into 2 lines of RGB */
+		RingQueue_Dequeue(&uvd->dp, cam->scratch, hor*2);
+		bayL0 = (struct bayL0 *) cam->scratch;
+		bayL1 = (struct bayL1 *) (cam->scratch + hor);
+		/* frame->curline is the rgb y line */
+		rgbL0 = (struct rgb *)
+				( frame->data + (cam->width*3*frame->curline));
+		/* w/2 because we're already doing 2 pixels */
+		rgbL1 = rgbL0 + (cam->width/2);
+
+		for (x=0; x < cam->width; x+=2) {
+			rgbL0->r = bayL0->r;
+			rgbL0->g = bayL0->g;
+			rgbL0->b = bayL1->b;
+
+			rgbL0->r2 = bayL0->r;
+			rgbL0->g2 = bayL1->g;
+			rgbL0->b2 = bayL1->b;
+
+			rgbL1->r = bayL0->r;
+			rgbL1->g = bayL1->g;
+			rgbL1->b = bayL1->b;
+
+			rgbL1->r2 = bayL0->r;
+			rgbL1->g2 = bayL1->g;
+			rgbL1->b2 = bayL1->b;
+
+			rgbL0++;
+			rgbL1++;
+
+			bayL0++;
+			bayL1++;
+		}
+
+		frame->seqRead_Length += cam->width*3*2;
+		frame->curline += 2;
+	}
+	/* See if we filled the frame */
+	if (frame->curline == cam->height) {
+		frame->frameState = FrameState_Done_Hold;
+		frame->curline = 0;
+		uvd->curframe = -1;
+		uvd->stats.frame_num++;
+	}
+}
+
+/* taken from konicawc */
+static int qcm_set_video_mode(struct uvd *uvd, struct video_window *vw)
+{
+	int ret;
+	int newsize;
+	int oldsize;
+	int x = vw->width;
+	int y = vw->height;
+	struct qcm *cam = (struct qcm *) uvd->user_data;
+
+	if (x > 0 && y > 0) {
+		DEBUG(2, "trying to find size %d,%d", x, y);
+		for (newsize = 0; newsize <= MAX_FRAME_SIZE; newsize++) {
+			if ((camera_sizes[newsize].width == x) &&
+				(camera_sizes[newsize].height == y))
+				break;
+		}
+	} else
+		newsize = cam->size;
+
+	if (newsize > MAX_FRAME_SIZE) {
+		DEBUG(1, "couldn't find size %d,%d", x, y);
+		return -EINVAL;
+	}
+
+	if (newsize == cam->size) {
+		DEBUG(1, "Nothing to do");
+		return 0;
+	}
+
+	qcm_stop_data(uvd);
+
+	if (cam->size != newsize) {
+		oldsize = cam->size;
+		cam->size = newsize;
+		ret = qcm_set_camera_size(uvd);
+		if (ret) {
+			err("Couldn't set camera size, err=%d",ret);
+			/* restore the original size */
+			cam->size = oldsize;
+			return ret;
+		}
+	}
+
+	/* Flush the input queue and clear any current frame in progress */
+
+	RingQueue_Flush(&uvd->dp);
+	if (uvd->curframe != -1) {
+		uvd->frame[uvd->curframe].curline = 0;
+		uvd->frame[uvd->curframe].seqRead_Length = 0;
+		uvd->frame[uvd->curframe].seqRead_Index = 0;
+	}
+
+	CHECK_RET(ret, qcm_start_data(uvd));
+	return 0;
+}
+
+static int qcm_configure_video(struct uvd *uvd)
+{
+	int ret;
+	memset(&uvd->vpic, 0, sizeof(uvd->vpic));
+	memset(&uvd->vpic_old, 0x55, sizeof(uvd->vpic_old));
+
+	uvd->vpic.colour = colour;
+	uvd->vpic.hue = hue;
+	uvd->vpic.brightness = brightness;
+	uvd->vpic.contrast = contrast;
+	uvd->vpic.whiteness = whiteness;
+	uvd->vpic.depth = 24;
+	uvd->vpic.palette = VIDEO_PALETTE_RGB24;
+
+	memset(&uvd->vcap, 0, sizeof(uvd->vcap));
+	strcpy(uvd->vcap.name, "QCM USB Camera");
+	uvd->vcap.type = VID_TYPE_CAPTURE;
+	uvd->vcap.channels = 1;
+	uvd->vcap.audios = 0;
+
+	uvd->vcap.minwidth = camera_sizes[SIZE_160X120].width;
+	uvd->vcap.minheight = camera_sizes[SIZE_160X120].height;
+	uvd->vcap.maxwidth = camera_sizes[SIZE_320X240].width;
+	uvd->vcap.maxheight = camera_sizes[SIZE_320X240].height;
+
+	memset(&uvd->vchan, 0, sizeof(uvd->vchan));
+	uvd->vchan.flags = 0 ;
+	uvd->vchan.tuners = 0;
+	uvd->vchan.channel = 0;
+	uvd->vchan.type = VIDEO_TYPE_CAMERA;
+	strcpy(uvd->vchan.name, "Camera");
+
+	CHECK_RET(ret, qcm_sensor_init(uvd));
+	return 0;
+}
+
+static int qcm_probe(struct usb_interface *intf,
+			const struct usb_device_id *devid)
+{
+	int err;
+	struct uvd *uvd;
+	struct usb_device *dev = interface_to_usbdev(intf);
+	struct qcm *cam;
+	size_t buffer_size;
+	unsigned char video_ep;
+	struct usb_host_interface *interface;
+	struct usb_endpoint_descriptor *endpoint;
+	int i,j;
+	unsigned int ifacenum, ifacenum_inact=0;
+	__le16 sensor_id;
+
+	/* we don't support multiconfig cams */
+	if (dev->descriptor.bNumConfigurations != 1)
+		return -ENODEV;
+
+	/* first check for the video interface and not
+	* the audio interface */
+	interface = &intf->cur_altsetting[0];
+	if ((interface->desc.bInterfaceClass != USB_CLASS_VENDOR_SPEC)
+		|| (interface->desc.bInterfaceSubClass !=
+			USB_CLASS_VENDOR_SPEC))
+		return -ENODEV;
+
+	/*
+	walk through each endpoint in each setting in the interface
+	stop when we find the one that's an isochronous IN endpoint.
+	*/
+	for (i=0; i < intf->num_altsetting; i++) {
+		interface = &intf->cur_altsetting[i];
+		ifacenum = interface->desc.bAlternateSetting;
+		/* walk the end points */
+		for (j=0; j < interface->desc.bNumEndpoints; j++) {
+			endpoint = &interface->endpoint[j].desc;
+
+			if ((endpoint->bEndpointAddress &
+				USB_ENDPOINT_DIR_MASK) != USB_DIR_IN)
+				continue; /* not input then not good */
+
+			buffer_size = le16_to_cpu(endpoint->wMaxPacketSize);
+			if (!buffer_size) {
+				ifacenum_inact = ifacenum;
+				continue; /* 0 pkt size is not what we want */
+			}
+
+			if ((endpoint->bmAttributes &
+				USB_ENDPOINT_XFERTYPE_MASK) ==
+				USB_ENDPOINT_XFER_ISOC) {
+				video_ep = endpoint->bEndpointAddress;
+				/* break out of the search */
+				goto good_videoep;
+			}
+		}
+	}
+	/* failed out since nothing useful was found */
+	err("No suitable endpoint was found\n");
+	return -ENODEV;
+
+good_videoep:
+	/* disable isochronous stream before doing anything else */
+	err = qcm_stv_setb(dev, STV_ISO_ENABLE, 0);
+	if (err < 0) {
+		err("Failed to disable sensor stream");
+		return -EIO;
+	}
+
+	/*
+	Check that this is the same unknown sensor that is known to work. This
+	sensor is suspected to be the ST VV6422C001. I'll check the same value
+	that the qc-usb driver checks. This value is probably not even the
+	sensor ID since it matches the USB dev ID. Oh well. If it doesn't
+	match, it's probably a diff sensor so exit and apologize.
+	*/
+	err = qcm_stv_getw(dev, CMOS_SENSOR_IDREV, &sensor_id);
+	if (err < 0) {
+		err("Couldn't read sensor values. Err %d\n",err);
+		return err;
+	}
+	if (sensor_id != cpu_to_le16(0x08F0)) {
+		err("Sensor ID %x != %x. Unsupported. Sorry\n",
+			le16_to_cpu(sensor_id), (0x08F0));
+		return -ENODEV;
+	}
+
+	uvd = usbvideo_AllocateDevice(cams);
+	if (!uvd)
+		return -ENOMEM;
+
+	cam = (struct qcm *) uvd->user_data;
+
+	/* buf for doing demosaicing */
+	cam->scratch = kmalloc(324*2, GFP_KERNEL);
+	if (!cam->scratch) /* uvd freed in dereg */
+		return -ENOMEM;
+
+	/* yes, if we fail after here, cam->scratch gets freed
+	by qcm_free_uvd */
+
+	err = qcm_alloc_int_urb(cam);
+	if (err < 0)
+		return err;
+
+	/* yes, if we fail after here, int urb gets freed
+	by qcm_free_uvd */
+
+	RESTRICT_TO_RANGE(size, SIZE_160X120, SIZE_320X240);
+	cam->width = camera_sizes[size].width;
+	cam->height = camera_sizes[size].height;
+	cam->size = size;
+
+	uvd->debug = debug;
+	uvd->flags = 0;
+	uvd->dev = dev;
+	uvd->iface = intf->altsetting->desc.bInterfaceNumber;
+	uvd->ifaceAltActive = ifacenum;
+	uvd->ifaceAltInactive = ifacenum_inact;
+	uvd->video_endp = video_ep;
+	uvd->iso_packet_len = buffer_size;
+	uvd->paletteBits = 1L << VIDEO_PALETTE_RGB24;
+	uvd->defaultPalette = VIDEO_PALETTE_RGB24;
+	uvd->canvas = VIDEOSIZE(320, 240);
+	uvd->videosize = VIDEOSIZE(cam->width, cam->height);
+	err = qcm_configure_video(uvd);
+	if (err) {
+		err("failed to configure video settings");
+		return err;
+	}
+
+	err = usbvideo_RegisterVideoDevice(uvd);
+	if (err) { /* the uvd gets freed in Deregister */
+		err("usbvideo_RegisterVideoDevice() failed.");
+		return err;
+	}
+
+	uvd->max_frame_size = (320 * 240 * 3);
+	qcm_register_input(cam, dev);
+	usb_set_intfdata(intf, uvd);
+	return 0;
+}
+
+static void qcm_free_uvd(struct uvd *uvd)
+{
+	struct qcm *cam = (struct qcm *) uvd->user_data;
+
+	kfree(cam->scratch);
+	qcm_unregister_input(cam);
+	qcm_free_int(cam);
+}
+
+static struct usbvideo_cb qcm_driver = {
+	.probe = 		qcm_probe,
+	.setupOnOpen = 		qcm_setup_on_open,
+	.processData = 		qcm_process_isoc,
+	.setVideoMode = 	qcm_set_video_mode,
+	.startDataPump = 	qcm_start_data,
+	.stopDataPump = 	qcm_stop_data,
+	.adjustPicture = 	qcm_adjust_picture,
+	.userFree = 		qcm_free_uvd
+};
+
+static int __init qcm_init(void)
+{
+	info(DRIVER_DESC " " DRIVER_VERSION);
+
+	return usbvideo_register(
+		&cams,
+		MAX_CAMERAS,
+		sizeof(struct qcm),
+		"QCM",
+		&qcm_driver,
+		THIS_MODULE,
+		qcm_table);
+}
+
+static void __exit qcm_exit(void)
+{
+	usbvideo_Deregister(&cams);
+}
+
+module_param(size, int, 0);
+MODULE_PARM_DESC(size, "Initial Size 0: 160x120 1: 320x240");
+module_param(colour, int, 0);
+MODULE_PARM_DESC(colour, "Initial colour");
+module_param(hue, int, 0);
+MODULE_PARM_DESC(hue, "Initial hue");
+module_param(brightness, int, 0);
+MODULE_PARM_DESC(brightness, "Initial brightness");
+module_param(contrast, int, 0);
+MODULE_PARM_DESC(contrast, "Initial contrast");
+module_param(whiteness, int, 0);
+MODULE_PARM_DESC(whiteness, "Initial whiteness");
+
+#ifdef CONFIG_USB_DEBUG
+module_param(debug, int, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(debug, "Debug level: 0-9 (default=0)");
+#endif
+
+module_init(qcm_init);
+module_exit(qcm_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Jaya Kumar");
+MODULE_DESCRIPTION("QCM USB Camera");
+MODULE_SUPPORTED_DEVICE("QCM USB Camera");
diff --git a/drivers/media/video/usbvideo/quickcam_messenger.h b/drivers/media/video/usbvideo/quickcam_messenger.h
new file mode 100644
index 000000000..baab9c081
--- /dev/null
+++ b/drivers/media/video/usbvideo/quickcam_messenger.h
@@ -0,0 +1,126 @@
+#ifndef quickcam_messenger_h
+#define quickcam_messenger_h
+
+#ifndef CONFIG_INPUT
+/* if we're not using input we dummy out these functions */
+#define qcm_register_input(...)
+#define qcm_unregister_input(...)
+#define qcm_report_buttonstat(...)
+#define qcm_setup_input_int(...) 0
+#define qcm_stop_int_data(...)
+#define qcm_alloc_int_urb(...) 0
+#define qcm_free_int(...)
+#endif
+
+
+#define CHECK_RET(ret, expr) \
+	if ((ret = expr) < 0) return ret
+
+/* Control Registers for the STVV6422 ASIC
+ * - this define is taken from the qc-usb-messenger code
+ */
+#define STV_ISO_ENABLE		0x1440
+#define ISOC_PACKET_SIZE	1023
+
+/* Chip identification number including revision indicator */
+#define CMOS_SENSOR_IDREV	0xE00A
+
+struct rgb {
+	u8 b;
+	u8 g;
+	u8 r;
+	u8 b2;
+	u8 g2;
+	u8 r2;
+};
+
+struct bayL0 {
+#ifdef __BIG_ENDIAN
+	u8 r;
+	u8 g;
+#elif __LITTLE_ENDIAN
+	u8 g;
+	u8 r;
+#else
+#error not byte order defined
+#endif
+};
+
+struct bayL1 {
+#ifdef __BIG_ENDIAN
+	u8 g;
+	u8 b;
+#elif __LITTLE_ENDIAN
+	u8 b;
+	u8 g;
+#else
+#error not byte order defined
+#endif
+};
+
+struct cam_size {
+	u16	width;
+	u16	height;
+	u8	cmd;
+};
+
+static const struct cam_size camera_sizes[] = {
+	{ 160, 120, 0xf },
+	{ 320, 240, 0x2 },
+};
+
+enum frame_sizes {
+	SIZE_160X120	= 0,
+	SIZE_320X240	= 1,
+};
+
+#define MAX_FRAME_SIZE SIZE_320X240
+
+struct qcm {
+	u16 colour;
+	u16 hue;
+	u16 brightness;
+	u16 contrast;
+	u16 whiteness;
+
+	u8 size;
+	int height;
+	int width;
+	u8 *scratch;
+	struct urb *button_urb;
+	u8 button_sts;
+	u8 button_sts_buf;
+
+#ifdef CONFIG_INPUT
+	struct input_dev *input;
+	char input_physname[64];
+#endif
+};
+
+struct regval {
+	u16 reg;
+	u8 val;
+};
+/* this table is derived from the
+qc-usb-messenger code */
+static const struct regval regval_table[] = {
+	{ STV_ISO_ENABLE, 0x00 },
+	{ 0x1436, 0x00 }, { 0x1432, 0x03 },
+	{ 0x143a, 0xF9 }, { 0x0509, 0x38 },
+	{ 0x050a, 0x38 }, { 0x050b, 0x38 },
+	{ 0x050c, 0x2A }, { 0x050d, 0x01 },
+	{ 0x1431, 0x00 }, { 0x1433, 0x34 },
+	{ 0x1438, 0x18 }, { 0x1439, 0x00 },
+	{ 0x143b, 0x05 }, { 0x143c, 0x00 },
+	{ 0x143e, 0x01 }, { 0x143d, 0x00 },
+	{ 0x1442, 0xe2 }, { 0x1500, 0xd0 },
+	{ 0x1500, 0xd0 }, { 0x1500, 0x50 },
+	{ 0x1501, 0xaf }, { 0x1502, 0xc2 },
+	{ 0x1503, 0x45 }, { 0x1505, 0x02 },
+	{ 0x150e, 0x8e }, { 0x150f, 0x37 },
+	{ 0x15c0, 0x00 },
+};
+
+static const unsigned char marker[] = { 0x00, 0xff, 0x00, 0xFF };
+
+#endif /* quickcam_messenger_h */
diff --git a/drivers/media/video/zc0301/zc0301_pb0330.c b/drivers/media/video/zc0301/zc0301_pb0330.c
new file mode 100644
index 000000000..ed8542e6c
--- /dev/null
+++ b/drivers/media/video/zc0301/zc0301_pb0330.c
@@ -0,0 +1,187 @@
+/***************************************************************************
+ * Plug-in for PB-0330 image sensor connected to the ZC0301[P] Image       *
+ * Processor and Control Chip                                              *
+ *                                                                         *
+ * Copyright (C) 2006 by Luca Risolia <luca.risolia@studio.unibo.it>       *
+ *                                                                         *
+ * Initialization values of the ZC0301[P] have been taken from the SPCA5XX *
+ * driver maintained by Michel Xhaard <mxhaard@magic.fr>                   *
+ *                                                                         *
+ * 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/delay.h>
+#include "zc0301_sensor.h"
+
+
+static struct zc0301_sensor pb0330;
+
+
+static int pb0330_init(struct zc0301_device* cam)
+{
+	int err = 0;
+
+	err += zc0301_write_reg(cam, 0x0000, 0x01);
+	err += zc0301_write_reg(cam, 0x0008, 0x03);
+	err += zc0301_write_reg(cam, 0x0010, 0x0A);
+	err += zc0301_write_reg(cam, 0x0002, 0x00);
+	err += zc0301_write_reg(cam, 0x0003, 0x02);
+	err += zc0301_write_reg(cam, 0x0004, 0x80);
+	err += zc0301_write_reg(cam, 0x0005, 0x01);
+	err += zc0301_write_reg(cam, 0x0006, 0xE0);
+	err += zc0301_write_reg(cam, 0x0001, 0x01);
+	err += zc0301_write_reg(cam, 0x0012, 0x05);
+	err += zc0301_write_reg(cam, 0x0012, 0x07);
+	err += zc0301_write_reg(cam, 0x0098, 0x00);
+	err += zc0301_write_reg(cam, 0x009A, 0x00);
+	err += zc0301_write_reg(cam, 0x011A, 0x00);
+	err += zc0301_write_reg(cam, 0x011C, 0x00);
+	err += zc0301_write_reg(cam, 0x0012, 0x05);
+
+	err += zc0301_i2c_write(cam, 0x01, 0x0006);
+	err += zc0301_i2c_write(cam, 0x02, 0x0011);
+	err += zc0301_i2c_write(cam, 0x03, 0x01E7);
+	err += zc0301_i2c_write(cam, 0x04, 0x0287);
+	err += zc0301_i2c_write(cam, 0x06, 0x0003);
+	err += zc0301_i2c_write(cam, 0x07, 0x3002);
+	err += zc0301_i2c_write(cam, 0x20, 0x1100);
+	err += zc0301_i2c_write(cam, 0x2F, 0xF7B0);
+	err += zc0301_i2c_write(cam, 0x30, 0x0005);
+	err += zc0301_i2c_write(cam, 0x31, 0x0000);
+	err += zc0301_i2c_write(cam, 0x34, 0x0100);
+	err += zc0301_i2c_write(cam, 0x35, 0x0060);
+	err += zc0301_i2c_write(cam, 0x3D, 0x068F);
+	err += zc0301_i2c_write(cam, 0x40, 0x01E0);
+	err += zc0301_i2c_write(cam, 0x58, 0x0078);
+	err += zc0301_i2c_write(cam, 0x62, 0x0411);
+
+	err += zc0301_write_reg(cam, 0x0087, 0x10);
+	err += zc0301_write_reg(cam, 0x0101, 0x37);
+	err += zc0301_write_reg(cam, 0x0012, 0x05);
+	err += zc0301_write_reg(cam, 0x0100, 0x0D);
+	err += zc0301_write_reg(cam, 0x0189, 0x06);
+	err += zc0301_write_reg(cam, 0x01AD, 0x00);
+	err += zc0301_write_reg(cam, 0x01C5, 0x03);
+	err += zc0301_write_reg(cam, 0x01CB, 0x13);
+	err += zc0301_write_reg(cam, 0x0250, 0x08);
+	err += zc0301_write_reg(cam, 0x0301, 0x08);
+	err += zc0301_write_reg(cam, 0x01A8, 0x60);
+	err += zc0301_write_reg(cam, 0x018D, 0x6C);
+	err += zc0301_write_reg(cam, 0x01AD, 0x09);
+	err += zc0301_write_reg(cam, 0x01AE, 0x15);
+	err += zc0301_write_reg(cam, 0x010A, 0x50);
+	err += zc0301_write_reg(cam, 0x010B, 0xF8);
+	err += zc0301_write_reg(cam, 0x010C, 0xF8);
+	err += zc0301_write_reg(cam, 0x010D, 0xF8);
+	err += zc0301_write_reg(cam, 0x010E, 0x50);
+	err += zc0301_write_reg(cam, 0x010F, 0xF8);
+	err += zc0301_write_reg(cam, 0x0110, 0xF8);
+	err += zc0301_write_reg(cam, 0x0111, 0xF8);
+	err += zc0301_write_reg(cam, 0x0112, 0x50);
+	err += zc0301_write_reg(cam, 0x0008, 0x03);
+	err += zc0301_write_reg(cam, 0x01C6, 0x08);
+	err += zc0301_write_reg(cam, 0x01CB, 0x0F);
+	err += zc0301_write_reg(cam, 0x010A, 0x50);
+	err += zc0301_write_reg(cam, 0x010B, 0xF8);
+	err += zc0301_write_reg(cam, 0x010C, 0xF8);
+	err += zc0301_write_reg(cam, 0x010D, 0xF8);
+	err += zc0301_write_reg(cam, 0x010E, 0x50);
+	err += zc0301_write_reg(cam, 0x010F, 0xF8);
+	err += zc0301_write_reg(cam, 0x0110, 0xF8);
+	err += zc0301_write_reg(cam, 0x0111, 0xF8);
+	err += zc0301_write_reg(cam, 0x0112, 0x50);
+	err += zc0301_write_reg(cam, 0x0180, 0x00);
+	err += zc0301_write_reg(cam, 0x0019, 0x00);
+
+	err += zc0301_i2c_write(cam, 0x05, 0x0066);
+	err += zc0301_i2c_write(cam, 0x09, 0x02B2);
+	err += zc0301_i2c_write(cam, 0x10, 0x0002);
+
+	err += zc0301_write_reg(cam, 0x011D, 0x60);
+	err += zc0301_write_reg(cam, 0x0190, 0x00);
+	err += zc0301_write_reg(cam, 0x0191, 0x07);
+	err += zc0301_write_reg(cam, 0x0192, 0x8C);
+	err += zc0301_write_reg(cam, 0x0195, 0x00);
+	err += zc0301_write_reg(cam, 0x0196, 0x00);
+	err += zc0301_write_reg(cam, 0x0197, 0x8A);
+	err += zc0301_write_reg(cam, 0x018C, 0x10);
+	err += zc0301_write_reg(cam, 0x018F, 0x20);
+	err += zc0301_write_reg(cam, 0x01A9, 0x14);
+	err += zc0301_write_reg(cam, 0x01AA, 0x24);
+	err += zc0301_write_reg(cam, 0x001D, 0xD7);
+	err += zc0301_write_reg(cam, 0x001E, 0xF0);
+	err += zc0301_write_reg(cam, 0x001F, 0xF8);
+	err += zc0301_write_reg(cam, 0x0020, 0xFF);
+	err += zc0301_write_reg(cam, 0x01AD, 0x09);
+	err += zc0301_write_reg(cam, 0x01AE, 0x15);
+	err += zc0301_write_reg(cam, 0x0180, 0x40);
+	err += zc0301_write_reg(cam, 0x0180, 0x42);
+
+	msleep(100);
+
+	return err;
+}
+
+
+static struct zc0301_sensor pb0330 = {
+	.name = "PB-0330",
+	.init = &pb0330_init,
+	.cropcap = {
+		.bounds = {
+			.left = 0,
+			.top = 0,
+			.width = 640,
+			.height = 480,
+		},
+		.defrect = {
+			.left = 0,
+			.top = 0,
+			.width = 640,
+			.height = 480,
+		},
+	},
+	.pix_format = {
+		.width = 640,
+		.height = 480,
+		.pixelformat = V4L2_PIX_FMT_JPEG,
+		.priv = 8,
+	},
+};
+
+
+int zc0301_probe_pb0330(struct zc0301_device* cam)
+{
+	int r0, err = 0;
+
+	err += zc0301_write_reg(cam, 0x0000, 0x01);
+	err += zc0301_write_reg(cam, 0x0010, 0x0a);
+	err += zc0301_write_reg(cam, 0x0001, 0x01);
+	err += zc0301_write_reg(cam, 0x0012, 0x03);
+	err += zc0301_write_reg(cam, 0x0012, 0x01);
+
+	msleep(10);
+
+	r0 = zc0301_i2c_read(cam, 0x00, 2);
+
+	if (r0 < 0 || err)
+		return -EIO;
+
+	if (r0 != 0x8243)
+		return -ENODEV;
+
+	zc0301_attach_sensor(cam, &pb0330);
+
+	return 0;
+}
diff --git a/drivers/mtd/nand/ams-delta.c b/drivers/mtd/nand/ams-delta.c
new file mode 100644
index 000000000..a0ba07c36
--- /dev/null
+++ b/drivers/mtd/nand/ams-delta.c
@@ -0,0 +1,239 @@
+/*
+ *  drivers/mtd/nand/ams-delta.c
+ *
+ *  Copyright (C) 2006 Jonathan McDowell <noodles@earth.li>
+ *
+ *  Derived from drivers/mtd/toto.c
+ *
+ * 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.
+ *
+ *  Overview:
+ *   This is a device driver for the NAND flash device found on the
+ *   Amstrad E3 (Delta).
+ */
+
+#include <linux/slab.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/partitions.h>
+#include <asm/io.h>
+#include <asm/arch/hardware.h>
+#include <asm/sizes.h>
+#include <asm/arch/gpio.h>
+#include <asm/arch/board-ams-delta.h>
+
+/*
+ * MTD structure for E3 (Delta)
+ */
+static struct mtd_info *ams_delta_mtd = NULL;
+
+#define NAND_MASK (AMS_DELTA_LATCH2_NAND_NRE | AMS_DELTA_LATCH2_NAND_NWE | AMS_DELTA_LATCH2_NAND_CLE | AMS_DELTA_LATCH2_NAND_ALE | AMS_DELTA_LATCH2_NAND_NCE | AMS_DELTA_LATCH2_NAND_NWP)
+
+/*
+ * Define partitions for flash devices
+ */
+
+static struct mtd_partition partition_info[] = {
+	{ .name		= "Kernel",
+	  .offset	= 0,
+	  .size		= 3 * SZ_1M + SZ_512K },
+	{ .name		= "u-boot",
+	  .offset	= 3 * SZ_1M + SZ_512K,
+	  .size		= SZ_256K },
+	{ .name		= "u-boot params",
+	  .offset	= 3 * SZ_1M + SZ_512K + SZ_256K,
+	  .size		= SZ_256K },
+	{ .name		= "Amstrad LDR",
+	  .offset	= 4 * SZ_1M,
+	  .size		= SZ_256K },
+	{ .name		= "File system",
+	  .offset	= 4 * SZ_1M + 1 * SZ_256K,
+	  .size		= 27 * SZ_1M },
+	{ .name		= "PBL reserved",
+	  .offset	= 32 * SZ_1M - 3 * SZ_256K,
+	  .size		=  3 * SZ_256K },
+};
+
+static void ams_delta_write_byte(struct mtd_info *mtd, u_char byte)
+{
+	struct nand_chip *this = mtd->priv;
+
+	omap_writew(0, (OMAP_MPUIO_BASE + OMAP_MPUIO_IO_CNTL));
+	omap_writew(byte, this->IO_ADDR_W);
+	ams_delta_latch2_write(AMS_DELTA_LATCH2_NAND_NWE, 0);
+	ndelay(40);
+	ams_delta_latch2_write(AMS_DELTA_LATCH2_NAND_NWE,
+			       AMS_DELTA_LATCH2_NAND_NWE);
+}
+
+static u_char ams_delta_read_byte(struct mtd_info *mtd)
+{
+	u_char res;
+	struct nand_chip *this = mtd->priv;
+
+	ams_delta_latch2_write(AMS_DELTA_LATCH2_NAND_NRE, 0);
+	ndelay(40);
+	omap_writew(~0, (OMAP_MPUIO_BASE + OMAP_MPUIO_IO_CNTL));
+	res = omap_readw(this->IO_ADDR_R);
+	ams_delta_latch2_write(AMS_DELTA_LATCH2_NAND_NRE,
+			       AMS_DELTA_LATCH2_NAND_NRE);
+
+	return res;
+}
+
+static void ams_delta_write_buf(struct mtd_info *mtd, const u_char *buf,
+				int len)
+{
+	int i;
+
+	for (i=0; i<len; i++)
+		ams_delta_write_byte(mtd, buf[i]);
+}
+
+static void ams_delta_read_buf(struct mtd_info *mtd, u_char *buf, int len)
+{
+	int i;
+
+	for (i=0; i<len; i++)
+		buf[i] = ams_delta_read_byte(mtd);
+}
+
+static int ams_delta_verify_buf(struct mtd_info *mtd, const u_char *buf,
+				int len)
+{
+	int i;
+
+	for (i=0; i<len; i++)
+		if (buf[i] != ams_delta_read_byte(mtd))
+			return -EFAULT;
+
+	return 0;
+}
+
+/*
+ * Command control function
+ *
+ * ctrl:
+ * NAND_NCE: bit 0 -> bit 2
+ * NAND_CLE: bit 1 -> bit 7
+ * NAND_ALE: bit 2 -> bit 6
+ */
+static void ams_delta_hwcontrol(struct mtd_info *mtd, int cmd,
+				unsigned int ctrl)
+{
+
+	if (ctrl & NAND_CTRL_CHANGE) {
+		unsigned long bits;
+
+		bits = (~ctrl & NAND_NCE) ? AMS_DELTA_LATCH2_NAND_NCE : 0;
+		bits |= (ctrl & NAND_CLE) ? AMS_DELTA_LATCH2_NAND_CLE : 0;
+		bits |= (ctrl & NAND_ALE) ? AMS_DELTA_LATCH2_NAND_ALE : 0;
+
+		ams_delta_latch2_write(AMS_DELTA_LATCH2_NAND_CLE |
+				AMS_DELTA_LATCH2_NAND_ALE |
+				AMS_DELTA_LATCH2_NAND_NCE, bits);
+	}
+
+	if (cmd != NAND_CMD_NONE)
+		ams_delta_write_byte(mtd, cmd);
+}
+
+static int ams_delta_nand_ready(struct mtd_info *mtd)
+{
+	return omap_get_gpio_datain(AMS_DELTA_GPIO_PIN_NAND_RB);
+}
+
+/*
+ * Main initialization routine
+ */
+static int __init ams_delta_init(void)
+{
+	struct nand_chip *this;
+	int err = 0;
+
+	/* Allocate memory for MTD device structure and private data */
+	ams_delta_mtd = kmalloc(sizeof(struct mtd_info) +
+				sizeof(struct nand_chip), GFP_KERNEL);
+	if (!ams_delta_mtd) {
+		printk (KERN_WARNING "Unable to allocate E3 NAND MTD device structure.\n");
+		err = -ENOMEM;
+		goto out;
+	}
+
+	ams_delta_mtd->owner = THIS_MODULE;
+
+	/* Get pointer to private data */
+	this = (struct nand_chip *) (&ams_delta_mtd[1]);
+
+	/* Initialize structures */
+	memset(ams_delta_mtd, 0, sizeof(struct mtd_info));
+	memset(this, 0, sizeof(struct nand_chip));
+
+	/* Link the private data with the MTD structure */
+	ams_delta_mtd->priv = this;
+
+	/* Set address of NAND IO lines */
+	this->IO_ADDR_R = (OMAP_MPUIO_BASE + OMAP_MPUIO_INPUT_LATCH);
+	this->IO_ADDR_W = (OMAP_MPUIO_BASE + OMAP_MPUIO_OUTPUT);
+	this->read_byte = ams_delta_read_byte;
+	this->write_buf = ams_delta_write_buf;
+	this->read_buf = ams_delta_read_buf;
+	this->verify_buf = ams_delta_verify_buf;
+	this->cmd_ctrl = ams_delta_hwcontrol;
+	if (!omap_request_gpio(AMS_DELTA_GPIO_PIN_NAND_RB)) {
+		this->dev_ready = ams_delta_nand_ready;
+	} else {
+		this->dev_ready = NULL;
+		printk(KERN_NOTICE "Couldn't request gpio for Delta NAND ready.\n");
+	}
+	/* 25 us command delay time */
+	this->chip_delay = 30;
+	this->ecc.mode = NAND_ECC_SOFT;
+
+	/* Set chip enabled, but  */
+	ams_delta_latch2_write(NAND_MASK, AMS_DELTA_LATCH2_NAND_NRE |
+					  AMS_DELTA_LATCH2_NAND_NWE |
+					  AMS_DELTA_LATCH2_NAND_NCE |
+					  AMS_DELTA_LATCH2_NAND_NWP);
+
+	/* Scan to find existance of the device */
+	if (nand_scan(ams_delta_mtd, 1)) {
+		err = -ENXIO;
+		goto out_mtd;
+	}
+
+	/* Register the partitions */
+	add_mtd_partitions(ams_delta_mtd, partition_info,
+			   ARRAY_SIZE(partition_info));
+
+	goto out;
+
+ out_mtd:
+	kfree(ams_delta_mtd);
+ out:
+	return err;
+}
+
+module_init(ams_delta_init);
+
+/*
+ * Clean up routine
+ */
+static void __exit ams_delta_cleanup(void)
+{
+	/* Release resources, unregister device */
+	nand_release(ams_delta_mtd);
+
+	/* Free the MTD device structure */
+	kfree(ams_delta_mtd);
+}
+module_exit(ams_delta_cleanup);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Jonathan McDowell <noodles@earth.li>");
+MODULE_DESCRIPTION("Glue layer for NAND flash on Amstrad E3 (Delta)");
diff --git a/drivers/mtd/nand/cs553x_nand.c b/drivers/mtd/nand/cs553x_nand.c
new file mode 100644
index 000000000..e0a1d386e
--- /dev/null
+++ b/drivers/mtd/nand/cs553x_nand.c
@@ -0,0 +1,353 @@
+/*
+ * drivers/mtd/nand/cs553x_nand.c
+ *
+ * (C) 2005, 2006 Red Hat Inc.
+ *
+ * Author: David Woodhouse <dwmw2@infradead.org>
+ *	   Tom Sylla <tom.sylla@amd.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ *  Overview:
+ *   This is a device driver for the NAND flash controller found on 
+ *   the AMD CS5535/CS5536 companion chipsets for the Geode processor.
+ *
+ */
+
+#include <linux/slab.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/pci.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/nand_ecc.h>
+#include <linux/mtd/partitions.h>
+
+#include <asm/msr.h>
+#include <asm/io.h>
+
+#define NR_CS553X_CONTROLLERS	4
+
+#define MSR_DIVIL_GLD_CAP	0x51400000	/* DIVIL capabilitiies */
+#define CAP_CS5535		0x2df000ULL
+#define CAP_CS5536		0x5df500ULL
+
+/* NAND Timing MSRs */
+#define MSR_NANDF_DATA		0x5140001b	/* NAND Flash Data Timing MSR */
+#define MSR_NANDF_CTL		0x5140001c	/* NAND Flash Control Timing */
+#define MSR_NANDF_RSVD		0x5140001d	/* Reserved */
+
+/* NAND BAR MSRs */
+#define MSR_DIVIL_LBAR_FLSH0	0x51400010	/* Flash Chip Select 0 */
+#define MSR_DIVIL_LBAR_FLSH1	0x51400011	/* Flash Chip Select 1 */
+#define MSR_DIVIL_LBAR_FLSH2	0x51400012	/* Flash Chip Select 2 */
+#define MSR_DIVIL_LBAR_FLSH3	0x51400013	/* Flash Chip Select 3 */
+	/* Each made up of... */
+#define FLSH_LBAR_EN		(1ULL<<32)
+#define FLSH_NOR_NAND		(1ULL<<33)	/* 1 for NAND */
+#define FLSH_MEM_IO		(1ULL<<34)	/* 1 for MMIO */
+	/* I/O BARs have BASE_ADDR in bits 15:4, IO_MASK in 47:36 */
+	/* MMIO BARs have BASE_ADDR in bits 31:12, MEM_MASK in 63:44 */
+
+/* Pin function selection MSR (IDE vs. flash on the IDE pins) */
+#define MSR_DIVIL_BALL_OPTS	0x51400015
+#define PIN_OPT_IDE		(1<<0)	/* 0 for flash, 1 for IDE */
+
+/* Registers within the NAND flash controller BAR -- memory mapped */
+#define MM_NAND_DATA		0x00	/* 0 to 0x7ff, in fact */
+#define MM_NAND_CTL		0x800	/* Any even address 0x800-0x80e */
+#define MM_NAND_IO		0x801	/* Any odd address 0x801-0x80f */
+#define MM_NAND_STS		0x810
+#define MM_NAND_ECC_LSB		0x811
+#define MM_NAND_ECC_MSB		0x812
+#define MM_NAND_ECC_COL		0x813
+#define MM_NAND_LAC		0x814
+#define MM_NAND_ECC_CTL		0x815
+
+/* Registers within the NAND flash controller BAR -- I/O mapped */
+#define IO_NAND_DATA		0x00	/* 0 to 3, in fact */
+#define IO_NAND_CTL		0x04
+#define IO_NAND_IO		0x05
+#define IO_NAND_STS		0x06
+#define IO_NAND_ECC_CTL		0x08
+#define IO_NAND_ECC_LSB		0x09
+#define IO_NAND_ECC_MSB		0x0a
+#define IO_NAND_ECC_COL		0x0b
+#define IO_NAND_LAC		0x0c
+
+#define CS_NAND_CTL_DIST_EN	(1<<4)	/* Enable NAND Distract interrupt */
+#define CS_NAND_CTL_RDY_INT_MASK	(1<<3)	/* Enable RDY/BUSY# interrupt */
+#define CS_NAND_CTL_ALE		(1<<2)
+#define CS_NAND_CTL_CLE		(1<<1)
+#define CS_NAND_CTL_CE		(1<<0)	/* Keep low; 1 to reset */
+
+#define CS_NAND_STS_FLASH_RDY	(1<<3)
+#define CS_NAND_CTLR_BUSY	(1<<2)
+#define CS_NAND_CMD_COMP	(1<<1)
+#define CS_NAND_DIST_ST		(1<<0)
+
+#define CS_NAND_ECC_PARITY	(1<<2)
+#define CS_NAND_ECC_CLRECC	(1<<1)
+#define CS_NAND_ECC_ENECC	(1<<0)
+
+static void cs553x_read_buf(struct mtd_info *mtd, u_char *buf, int len)
+{
+	struct nand_chip *this = mtd->priv;
+
+	while (unlikely(len > 0x800)) {
+		memcpy_fromio(buf, this->IO_ADDR_R, 0x800);
+		buf += 0x800;
+		len -= 0x800;
+	}
+	memcpy_fromio(buf, this->IO_ADDR_R, len);
+}
+
+static void cs553x_write_buf(struct mtd_info *mtd, const u_char *buf, int len)
+{
+	struct nand_chip *this = mtd->priv;
+
+	while (unlikely(len > 0x800)) {
+		memcpy_toio(this->IO_ADDR_R, buf, 0x800);
+		buf += 0x800;
+		len -= 0x800;
+	}
+	memcpy_toio(this->IO_ADDR_R, buf, len);
+}
+
+static unsigned char cs553x_read_byte(struct mtd_info *mtd)
+{
+	struct nand_chip *this = mtd->priv;
+	return readb(this->IO_ADDR_R);
+}
+
+static void cs553x_write_byte(struct mtd_info *mtd, u_char byte)
+{
+	struct nand_chip *this = mtd->priv;
+	int i = 100000;
+
+	while (i && readb(this->IO_ADDR_R + MM_NAND_STS) & CS_NAND_CTLR_BUSY) {
+		udelay(1);
+		i--;
+	}
+	writeb(byte, this->IO_ADDR_W + 0x801);
+}
+
+static void cs553x_hwcontrol(struct mtd_info *mtd, int cmd,
+			     unsigned int ctrl)
+{
+	struct nand_chip *this = mtd->priv;
+	void __iomem *mmio_base = this->IO_ADDR_R;
+	if (ctrl & NAND_CTRL_CHANGE) {
+		unsigned char ctl = (ctrl & ~NAND_CTRL_CHANGE ) ^ 0x01;
+		writeb(ctl, mmio_base + MM_NAND_CTL);
+	}
+	if (cmd != NAND_CMD_NONE)
+		cs553x_write_byte(mtd, cmd);
+}
+
+static int cs553x_device_ready(struct mtd_info *mtd)
+{
+	struct nand_chip *this = mtd->priv;
+	void __iomem *mmio_base = this->IO_ADDR_R;
+	unsigned char foo = readb(mmio_base + MM_NAND_STS);
+
+	return (foo & CS_NAND_STS_FLASH_RDY) && !(foo & CS_NAND_CTLR_BUSY);
+}
+
+static void cs_enable_hwecc(struct mtd_info *mtd, int mode)
+{
+	struct nand_chip *this = mtd->priv;
+	void __iomem *mmio_base = this->IO_ADDR_R;
+
+	writeb(0x07, mmio_base + MM_NAND_ECC_CTL);
+}
+
+static int cs_calculate_ecc(struct mtd_info *mtd, const u_char *dat, u_char *ecc_code)
+{
+	uint32_t ecc;
+	struct nand_chip *this = mtd->priv;
+	void __iomem *mmio_base = this->IO_ADDR_R;
+
+	ecc = readl(mmio_base + MM_NAND_STS);
+
+	ecc_code[1] = ecc >> 8;
+	ecc_code[0] = ecc >> 16;
+	ecc_code[2] = ecc >> 24;
+	return 0;
+}
+
+static struct mtd_info *cs553x_mtd[4];
+
+static int __init cs553x_init_one(int cs, int mmio, unsigned long adr)
+{
+	int err = 0;
+	struct nand_chip *this;
+	struct mtd_info *new_mtd;
+
+	printk(KERN_NOTICE "Probing CS553x NAND controller CS#%d at %sIO 0x%08lx\n", cs, mmio?"MM":"P", adr);
+
+	if (!mmio) {
+		printk(KERN_NOTICE "PIO mode not yet implemented for CS553X NAND controller\n");
+		return -ENXIO;
+	}
+
+	/* Allocate memory for MTD device structure and private data */
+	new_mtd = kmalloc(sizeof(struct mtd_info) + sizeof(struct nand_chip), GFP_KERNEL);
+	if (!new_mtd) {
+		printk(KERN_WARNING "Unable to allocate CS553X NAND MTD device structure.\n");
+		err = -ENOMEM;
+		goto out;
+	}
+
+	/* Get pointer to private data */
+	this = (struct nand_chip *)(&new_mtd[1]);
+
+	/* Initialize structures */
+	memset(new_mtd, 0, sizeof(struct mtd_info));
+	memset(this, 0, sizeof(struct nand_chip));
+
+	/* Link the private data with the MTD structure */
+	new_mtd->priv = this;
+	new_mtd->owner = THIS_MODULE;
+
+	/* map physical address */
+	this->IO_ADDR_R = this->IO_ADDR_W = ioremap(adr, 4096);
+	if (!this->IO_ADDR_R) {
+		printk(KERN_WARNING "ioremap cs553x NAND @0x%08lx failed\n", adr);
+		err = -EIO;
+		goto out_mtd;
+	}
+
+	this->cmd_ctrl = cs553x_hwcontrol;
+	this->dev_ready = cs553x_device_ready;
+	this->read_byte = cs553x_read_byte;
+	this->read_buf = cs553x_read_buf;
+	this->write_buf = cs553x_write_buf;
+
+	this->chip_delay = 0;
+
+	this->ecc.mode = NAND_ECC_HW;
+	this->ecc.size = 256;
+	this->ecc.bytes = 3;
+	this->ecc.hwctl  = cs_enable_hwecc;
+	this->ecc.calculate = cs_calculate_ecc;
+	this->ecc.correct  = nand_correct_data;
+
+	/* Enable the following for a flash based bad block table */
+	this->options = NAND_USE_FLASH_BBT | NAND_NO_AUTOINCR;
+
+	/* Scan to find existance of the device */
+	if (nand_scan(new_mtd, 1)) {
+		err = -ENXIO;
+		goto out_ior;
+	}
+
+	cs553x_mtd[cs] = new_mtd;
+	goto out;
+
+out_ior:
+	iounmap((void *)this->IO_ADDR_R);
+out_mtd:
+	kfree(new_mtd);
+out:
+	return err;
+}
+
+static int is_geode(void)
+{
+	/* These are the CPUs which will have a CS553[56] companion chip */
+	if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD &&
+	    boot_cpu_data.x86 == 5 &&
+	    boot_cpu_data.x86_model == 10)
+		return 1; /* Geode LX */
+
+	if ((boot_cpu_data.x86_vendor == X86_VENDOR_NSC ||
+	     boot_cpu_data.x86_vendor == X86_VENDOR_CYRIX) &&
+	    boot_cpu_data.x86 == 5 &&
+	    boot_cpu_data.x86_model == 5)
+		return 1; /* Geode GX (née GX2) */
+
+	return 0;
+}
+
+static int __init cs553x_init(void)
+{
+	int err = -ENXIO;
+	int i;
+	uint64_t val;
+
+	/* If the CPU isn't a Geode GX or LX, abort */
+	if (!is_geode())
+		return -ENXIO;
+
+	/* If it doesn't have the CS553[56], abort */
+	rdmsrl(MSR_DIVIL_GLD_CAP, val);
+	val &= ~0xFFULL;
+	if (val != CAP_CS5535 && val != CAP_CS5536)
+		return -ENXIO;
+
+	/* If it doesn't have the NAND controller enabled, abort */
+	rdmsrl(MSR_DIVIL_BALL_OPTS, val);
+	if (val & 1) {
+		printk(KERN_INFO "CS553x NAND controller: Flash I/O not enabled in MSR_DIVIL_BALL_OPTS.\n");
+		return -ENXIO;
+	}
+
+	for (i = 0; i < NR_CS553X_CONTROLLERS; i++) {
+		rdmsrl(MSR_DIVIL_LBAR_FLSH0 + i, val);
+
+		if ((val & (FLSH_LBAR_EN|FLSH_NOR_NAND)) == (FLSH_LBAR_EN|FLSH_NOR_NAND))
+			err = cs553x_init_one(i, !!(val & FLSH_MEM_IO), val & 0xFFFFFFFF);
+	}
+
+	/* Register all devices together here. This means we can easily hack it to 
+	   do mtdconcat etc. if we want to. */
+	for (i = 0; i < NR_CS553X_CONTROLLERS; i++) {
+		if (cs553x_mtd[i]) {
+			add_mtd_device(cs553x_mtd[i]);
+
+			/* If any devices registered, return success. Else the last error. */
+			err = 0;
+		}
+	}
+
+	return err;
+}
+
+module_init(cs553x_init);
+
+static void __exit cs553x_cleanup(void)
+{
+	int i;
+
+	for (i = 0; i < NR_CS553X_CONTROLLERS; i++) {
+		struct mtd_info *mtd = cs553x_mtd[i];
+		struct nand_chip *this;
+		void __iomem *mmio_base;
+
+		if (!mtd)
+			break;
+
+		this = cs553x_mtd[i]->priv;
+		mmio_base = this->IO_ADDR_R;
+
+		/* Release resources, unregister device */
+		nand_release(cs553x_mtd[i]);
+		cs553x_mtd[i] = NULL;
+
+		/* unmap physical adress */
+		iounmap(mmio_base);
+
+		/* Free the MTD device structure */
+		kfree(mtd);
+	}
+}
+
+module_exit(cs553x_cleanup);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("David Woodhouse <dwmw2@infradead.org>");
+MODULE_DESCRIPTION("NAND controller driver for AMD CS5535/CS5536 companion chip");
diff --git a/drivers/mtd/nand/ndfc.c b/drivers/mtd/nand/ndfc.c
new file mode 100644
index 000000000..e5bd88f2d
--- /dev/null
+++ b/drivers/mtd/nand/ndfc.c
@@ -0,0 +1,311 @@
+/*
+ *  drivers/mtd/ndfc.c
+ *
+ *  Overview:
+ *   Platform independend driver for NDFC (NanD Flash Controller)
+ *   integrated into EP440 cores
+ *
+ *  Author: Thomas Gleixner
+ *
+ *  Copyright 2006 IBM
+ *
+ *  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 <linux/mtd/nand.h>
+#include <linux/mtd/nand_ecc.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/ndfc.h>
+#include <linux/mtd/mtd.h>
+#include <linux/platform_device.h>
+
+#include <asm/io.h>
+#include <asm/ibm44x.h>
+
+struct ndfc_nand_mtd {
+	struct mtd_info			mtd;
+	struct nand_chip		chip;
+	struct platform_nand_chip	*pl_chip;
+};
+
+static struct ndfc_nand_mtd ndfc_mtd[NDFC_MAX_BANKS];
+
+struct ndfc_controller {
+	void __iomem		*ndfcbase;
+	struct nand_hw_control	ndfc_control;
+	atomic_t		childs_active;
+};
+
+static struct ndfc_controller ndfc_ctrl;
+
+static void ndfc_select_chip(struct mtd_info *mtd, int chip)
+{
+	uint32_t ccr;
+	struct ndfc_controller *ndfc = &ndfc_ctrl;
+	struct nand_chip *nandchip = mtd->priv;
+	struct ndfc_nand_mtd *nandmtd = nandchip->priv;
+	struct platform_nand_chip *pchip = nandmtd->pl_chip;
+
+	ccr = __raw_readl(ndfc->ndfcbase + NDFC_CCR);
+	if (chip >= 0) {
+		ccr &= ~NDFC_CCR_BS_MASK;
+		ccr |= NDFC_CCR_BS(chip + pchip->chip_offset);
+	} else
+		ccr |= NDFC_CCR_RESET_CE;
+	writel(ccr, ndfc->ndfcbase + NDFC_CCR);
+}
+
+static void ndfc_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl)
+{
+	struct ndfc_controller *ndfc = &ndfc_ctrl;
+
+	if (cmd == NAND_CMD_NONE)
+		return;
+
+	if (ctrl & NAND_CLE)
+		writel(cmd & 0xFF, ndfc->ndfcbase + NDFC_CMD);
+	else
+		writel(cmd & 0xFF, ndfc->ndfcbase + NDFC_ALE);
+}
+
+static int ndfc_ready(struct mtd_info *mtd)
+{
+	struct ndfc_controller *ndfc = &ndfc_ctrl;
+
+	return __raw_readl(ndfc->ndfcbase + NDFC_STAT) & NDFC_STAT_IS_READY;
+}
+
+static void ndfc_enable_hwecc(struct mtd_info *mtd, int mode)
+{
+	uint32_t ccr;
+	struct ndfc_controller *ndfc = &ndfc_ctrl;
+
+	ccr = __raw_readl(ndfc->ndfcbase + NDFC_CCR);
+	ccr |= NDFC_CCR_RESET_ECC;
+	__raw_writel(ccr, ndfc->ndfcbase + NDFC_CCR);
+	wmb();
+}
+
+static int ndfc_calculate_ecc(struct mtd_info *mtd,
+			      const u_char *dat, u_char *ecc_code)
+{
+	struct ndfc_controller *ndfc = &ndfc_ctrl;
+	uint32_t ecc;
+	uint8_t *p = (uint8_t *)&ecc;
+
+	wmb();
+	ecc = __raw_readl(ndfc->ndfcbase + NDFC_ECC);
+	ecc_code[0] = p[1];
+	ecc_code[1] = p[2];
+	ecc_code[2] = p[3];
+
+	return 0;
+}
+
+/*
+ * Speedups for buffer read/write/verify
+ *
+ * NDFC allows 32bit read/write of data. So we can speed up the buffer
+ * functions. No further checking, as nand_base will always read/write
+ * page aligned.
+ */
+static void ndfc_read_buf(struct mtd_info *mtd, uint8_t *buf, int len)
+{
+	struct ndfc_controller *ndfc = &ndfc_ctrl;
+	uint32_t *p = (uint32_t *) buf;
+
+	for(;len > 0; len -= 4)
+		*p++ = __raw_readl(ndfc->ndfcbase + NDFC_DATA);
+}
+
+static void ndfc_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len)
+{
+	struct ndfc_controller *ndfc = &ndfc_ctrl;
+	uint32_t *p = (uint32_t *) buf;
+
+	for(;len > 0; len -= 4)
+		__raw_writel(*p++, ndfc->ndfcbase + NDFC_DATA);
+}
+
+static int ndfc_verify_buf(struct mtd_info *mtd, const uint8_t *buf, int len)
+{
+	struct ndfc_controller *ndfc = &ndfc_ctrl;
+	uint32_t *p = (uint32_t *) buf;
+
+	for(;len > 0; len -= 4)
+		if (*p++ != __raw_readl(ndfc->ndfcbase + NDFC_DATA))
+			return -EFAULT;
+	return 0;
+}
+
+/*
+ * Initialize chip structure
+ */
+static void ndfc_chip_init(struct ndfc_nand_mtd *mtd)
+{
+	struct ndfc_controller *ndfc = &ndfc_ctrl;
+	struct nand_chip *chip = &mtd->chip;
+
+	chip->IO_ADDR_R = ndfc->ndfcbase + NDFC_DATA;
+	chip->IO_ADDR_W = ndfc->ndfcbase + NDFC_DATA;
+	chip->cmd_ctrl = ndfc_hwcontrol;
+	chip->dev_ready = ndfc_ready;
+	chip->select_chip = ndfc_select_chip;
+	chip->chip_delay = 50;
+	chip->priv = mtd;
+	chip->options = mtd->pl_chip->options;
+	chip->controller = &ndfc->ndfc_control;
+	chip->read_buf = ndfc_read_buf;
+	chip->write_buf = ndfc_write_buf;
+	chip->verify_buf = ndfc_verify_buf;
+	chip->ecc.correct = nand_correct_data;
+	chip->ecc.hwctl = ndfc_enable_hwecc;
+	chip->ecc.calculate = ndfc_calculate_ecc;
+	chip->ecc.mode = NAND_ECC_HW;
+	chip->ecc.size = 256;
+	chip->ecc.bytes = 3;
+	chip->ecclayout = mtd->pl_chip->ecclayout;
+	mtd->mtd.priv = chip;
+	mtd->mtd.owner = THIS_MODULE;
+}
+
+static int ndfc_chip_probe(struct platform_device *pdev)
+{
+	struct platform_nand_chip *nc = pdev->dev.platform_data;
+	struct ndfc_chip_settings *settings = nc->priv;
+	struct ndfc_controller *ndfc = &ndfc_ctrl;
+	struct ndfc_nand_mtd *nandmtd;
+
+	if (nc->chip_offset >= NDFC_MAX_BANKS || nc->nr_chips > NDFC_MAX_BANKS)
+		return -EINVAL;
+
+	/* Set the bank settings */
+	__raw_writel(settings->bank_settings,
+		     ndfc->ndfcbase + NDFC_BCFG0 + (nc->chip_offset << 2));
+
+	nandmtd = &ndfc_mtd[pdev->id];
+	if (nandmtd->pl_chip)
+		return -EBUSY;
+
+	nandmtd->pl_chip = nc;
+	ndfc_chip_init(nandmtd);
+
+	/* Scan for chips */
+	if (nand_scan(&nandmtd->mtd, nc->nr_chips)) {
+		nandmtd->pl_chip = NULL;
+		return -ENODEV;
+	}
+
+#ifdef CONFIG_MTD_PARTITIONS
+	printk("Number of partitions %d\n", nc->nr_partitions);
+	if (nc->nr_partitions) {
+		/* Add the full device, so complete dumps can be made */
+		add_mtd_device(&nandmtd->mtd);
+		add_mtd_partitions(&nandmtd->mtd, nc->partitions,
+				   nc->nr_partitions);
+
+	} else
+#else
+		add_mtd_device(&nandmtd->mtd);
+#endif
+
+	atomic_inc(&ndfc->childs_active);
+	return 0;
+}
+
+static int ndfc_chip_remove(struct platform_device *pdev)
+{
+	return 0;
+}
+
+static int ndfc_nand_probe(struct platform_device *pdev)
+{
+	struct platform_nand_ctrl *nc = pdev->dev.platform_data;
+	struct ndfc_controller_settings *settings = nc->priv;
+	struct resource *res = pdev->resource;
+	struct ndfc_controller *ndfc = &ndfc_ctrl;
+	unsigned long long phys = settings->ndfc_erpn | res->start;
+
+	ndfc->ndfcbase = ioremap64(phys, res->end - res->start + 1);
+	if (!ndfc->ndfcbase) {
+		printk(KERN_ERR "NDFC: ioremap failed\n");
+		return -EIO;
+	}
+
+	__raw_writel(settings->ccr_settings, ndfc->ndfcbase + NDFC_CCR);
+
+	spin_lock_init(&ndfc->ndfc_control.lock);
+	init_waitqueue_head(&ndfc->ndfc_control.wq);
+
+	platform_set_drvdata(pdev, ndfc);
+
+	printk("NDFC NAND Driver initialized. Chip-Rev: 0x%08x\n",
+	       __raw_readl(ndfc->ndfcbase + NDFC_REVID));
+
+	return 0;
+}
+
+static int ndfc_nand_remove(struct platform_device *pdev)
+{
+	struct ndfc_controller *ndfc = platform_get_drvdata(pdev);
+
+	if (atomic_read(&ndfc->childs_active))
+		return -EBUSY;
+
+	if (ndfc) {
+		platform_set_drvdata(pdev, NULL);
+		iounmap(ndfc_ctrl.ndfcbase);
+		ndfc_ctrl.ndfcbase = NULL;
+	}
+	return 0;
+}
+
+/* driver device registration */
+
+static struct platform_driver ndfc_chip_driver = {
+	.probe		= ndfc_chip_probe,
+	.remove		= ndfc_chip_remove,
+	.driver		= {
+		.name	= "ndfc-chip",
+		.owner	= THIS_MODULE,
+	},
+};
+
+static struct platform_driver ndfc_nand_driver = {
+	.probe		= ndfc_nand_probe,
+	.remove		= ndfc_nand_remove,
+	.driver		= {
+		.name	= "ndfc-nand",
+		.owner	= THIS_MODULE,
+	},
+};
+
+static int __init ndfc_nand_init(void)
+{
+	int ret;
+
+	spin_lock_init(&ndfc_ctrl.ndfc_control.lock);
+	init_waitqueue_head(&ndfc_ctrl.ndfc_control.wq);
+
+	ret = platform_driver_register(&ndfc_nand_driver);
+	if (!ret)
+		ret = platform_driver_register(&ndfc_chip_driver);
+	return ret;
+}
+
+static void __exit ndfc_nand_exit(void)
+{
+	platform_driver_unregister(&ndfc_chip_driver);
+	platform_driver_unregister(&ndfc_nand_driver);
+}
+
+module_init(ndfc_nand_init);
+module_exit(ndfc_nand_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Thomas Gleixner <tglx@linutronix.de>");
+MODULE_DESCRIPTION("Platform driver for NDFC");
diff --git a/drivers/mtd/nand/ts7250.c b/drivers/mtd/nand/ts7250.c
new file mode 100644
index 000000000..f40081069
--- /dev/null
+++ b/drivers/mtd/nand/ts7250.c
@@ -0,0 +1,206 @@
+/*
+ * drivers/mtd/nand/ts7250.c
+ *
+ * Copyright (C) 2004 Technologic Systems (support@embeddedARM.com)
+ *
+ * Derived from drivers/mtd/nand/edb7312.c
+ *   Copyright (C) 2004 Marius Gröger (mag@sysgo.de)
+ *
+ * Derived from drivers/mtd/nand/autcpu12.c
+ *   Copyright (c) 2001 Thomas Gleixner (gleixner@autronix.de)
+ *
+ * $Id: ts7250.c,v 1.4 2004/12/30 22:02:07 joff Exp $
+ *
+ * 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.
+ *
+ * Overview:
+ *   This is a device driver for the NAND flash device found on the
+ *   TS-7250 board which utilizes a Samsung 32 Mbyte part.
+ */
+
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/partitions.h>
+#include <asm/io.h>
+#include <asm/arch/hardware.h>
+#include <asm/sizes.h>
+#include <asm/mach-types.h>
+
+/*
+ * MTD structure for TS7250 board
+ */
+static struct mtd_info *ts7250_mtd = NULL;
+
+#ifdef CONFIG_MTD_PARTITIONS
+static const char *part_probes[] = { "cmdlinepart", NULL };
+
+#define NUM_PARTITIONS 3
+
+/*
+ * Define static partitions for flash device
+ */
+static struct mtd_partition partition_info32[] = {
+	{
+		.name		= "TS-BOOTROM",
+		.offset		= 0x00000000,
+		.size		= 0x00004000,
+	}, {
+		.name		= "Linux",
+		.offset		= 0x00004000,
+		.size		= 0x01d00000,
+	}, {
+		.name		= "RedBoot",
+		.offset		= 0x01d04000,
+		.size		= 0x002fc000,
+	},
+};
+
+/*
+ * Define static partitions for flash device
+ */
+static struct mtd_partition partition_info128[] = {
+	{
+		.name		= "TS-BOOTROM",
+		.offset		= 0x00000000,
+		.size		= 0x00004000,
+	}, {
+		.name		= "Linux",
+		.offset		= 0x00004000,
+		.size		= 0x07d00000,
+	}, {
+		.name		= "RedBoot",
+		.offset		= 0x07d04000,
+		.size		= 0x002fc000,
+	},
+};
+#endif
+
+
+/*
+ *	hardware specific access to control-lines
+ *
+ *	ctrl:
+ *	NAND_NCE: bit 0 -> bit 2
+ *	NAND_CLE: bit 1 -> bit 1
+ *	NAND_ALE: bit 2 -> bit 0
+ */
+static void ts7250_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl)
+{
+	struct nand_chip *chip = mtd->priv;
+
+	if (ctrl & NAND_CTRL_CHANGE) {
+		unsigned long addr = TS72XX_NAND_CONTROL_VIRT_BASE;
+		unsigned char bits;
+
+		bits = (ctrl & NAND_NCE) << 2;
+		bits |= ctrl & NAND_CLE;
+		bits |= (ctrl & NAND_ALE) >> 2;
+
+		__raw_writeb((__raw_readb(addr) & ~0x7) | bits, addr);
+	}
+
+	if (cmd != NAND_CMD_NONE)
+		writeb(cmd, chip->IO_ADDR_W);
+}
+
+/*
+ *	read device ready pin
+ */
+static int ts7250_device_ready(struct mtd_info *mtd)
+{
+	return __raw_readb(TS72XX_NAND_BUSY_VIRT_BASE) & 0x20;
+}
+
+/*
+ * Main initialization routine
+ */
+static int __init ts7250_init(void)
+{
+	struct nand_chip *this;
+	const char *part_type = 0;
+	int mtd_parts_nb = 0;
+	struct mtd_partition *mtd_parts = 0;
+
+	if (!machine_is_ts72xx() || board_is_ts7200())
+		return -ENXIO;
+
+	/* Allocate memory for MTD device structure and private data */
+	ts7250_mtd = kmalloc(sizeof(struct mtd_info) + sizeof(struct nand_chip), GFP_KERNEL);
+	if (!ts7250_mtd) {
+		printk("Unable to allocate TS7250 NAND MTD device structure.\n");
+		return -ENOMEM;
+	}
+
+	/* Get pointer to private data */
+	this = (struct nand_chip *)(&ts7250_mtd[1]);
+
+	/* Initialize structures */
+	memset(ts7250_mtd, 0, sizeof(struct mtd_info));
+	memset(this, 0, sizeof(struct nand_chip));
+
+	/* Link the private data with the MTD structure */
+	ts7250_mtd->priv = this;
+	ts7250_mtd->owner = THIS_MODULE;
+
+	/* insert callbacks */
+	this->IO_ADDR_R = (void *)TS72XX_NAND_DATA_VIRT_BASE;
+	this->IO_ADDR_W = (void *)TS72XX_NAND_DATA_VIRT_BASE;
+	this->cmd_ctrl = ts7250_hwcontrol;
+	this->dev_ready = ts7250_device_ready;
+	this->chip_delay = 15;
+	this->ecc.mode = NAND_ECC_SOFT;
+
+	printk("Searching for NAND flash...\n");
+	/* Scan to find existence of the device */
+	if (nand_scan(ts7250_mtd, 1)) {
+		kfree(ts7250_mtd);
+		return -ENXIO;
+	}
+#ifdef CONFIG_MTD_PARTITIONS
+	ts7250_mtd->name = "ts7250-nand";
+	mtd_parts_nb = parse_mtd_partitions(ts7250_mtd, part_probes, &mtd_parts, 0);
+	if (mtd_parts_nb > 0)
+		part_type = "command line";
+	else
+		mtd_parts_nb = 0;
+#endif
+	if (mtd_parts_nb == 0) {
+		mtd_parts = partition_info32;
+		if (ts7250_mtd->size >= (128 * 0x100000))
+			mtd_parts = partition_info128;
+		mtd_parts_nb = NUM_PARTITIONS;
+		part_type = "static";
+	}
+
+	/* Register the partitions */
+	printk(KERN_NOTICE "Using %s partition definition\n", part_type);
+	add_mtd_partitions(ts7250_mtd, mtd_parts, mtd_parts_nb);
+
+	/* Return happy */
+	return 0;
+}
+
+module_init(ts7250_init);
+
+/*
+ * Clean up routine
+ */
+static void __exit ts7250_cleanup(void)
+{
+	/* Unregister the device */
+	del_mtd_device(ts7250_mtd);
+
+	/* Free the MTD device structure */
+	kfree(ts7250_mtd);
+}
+
+module_exit(ts7250_cleanup);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Jesse Off <joff@embeddedARM.com>");
+MODULE_DESCRIPTION("MTD map driver for Technologic Systems TS-7250 board");
diff --git a/drivers/net/fs_enet/fec.h b/drivers/net/fs_enet/fec.h
new file mode 100644
index 000000000..e980527e2
--- /dev/null
+++ b/drivers/net/fs_enet/fec.h
@@ -0,0 +1,42 @@
+#ifndef FS_ENET_FEC_H
+#define FS_ENET_FEC_H
+
+/* CRC polynomium used by the FEC for the multicast group filtering */
+#define FEC_CRC_POLY   0x04C11DB7
+
+#define FEC_MAX_MULTICAST_ADDRS	64
+
+/* Interrupt events/masks.
+*/
+#define FEC_ENET_HBERR	0x80000000U	/* Heartbeat error          */
+#define FEC_ENET_BABR	0x40000000U	/* Babbling receiver        */
+#define FEC_ENET_BABT	0x20000000U	/* Babbling transmitter     */
+#define FEC_ENET_GRA	0x10000000U	/* Graceful stop complete   */
+#define FEC_ENET_TXF	0x08000000U	/* Full frame transmitted   */
+#define FEC_ENET_TXB	0x04000000U	/* A buffer was transmitted */
+#define FEC_ENET_RXF	0x02000000U	/* Full frame received      */
+#define FEC_ENET_RXB	0x01000000U	/* A buffer was received    */
+#define FEC_ENET_MII	0x00800000U	/* MII interrupt            */
+#define FEC_ENET_EBERR	0x00400000U	/* SDMA bus error           */
+
+#define FEC_ECNTRL_PINMUX	0x00000004
+#define FEC_ECNTRL_ETHER_EN	0x00000002
+#define FEC_ECNTRL_RESET	0x00000001
+
+#define FEC_RCNTRL_BC_REJ	0x00000010
+#define FEC_RCNTRL_PROM		0x00000008
+#define FEC_RCNTRL_MII_MODE	0x00000004
+#define FEC_RCNTRL_DRT		0x00000002
+#define FEC_RCNTRL_LOOP		0x00000001
+
+#define FEC_TCNTRL_FDEN		0x00000004
+#define FEC_TCNTRL_HBC		0x00000002
+#define FEC_TCNTRL_GTS		0x00000001
+
+
+
+/*
+ * Delay to wait for FEC reset command to complete (in us)
+ */
+#define FEC_RESET_DELAY		50
+#endif
diff --git a/drivers/net/fs_enet/mii-fec.c b/drivers/net/fs_enet/mii-fec.c
new file mode 100644
index 000000000..1328e10ca
--- /dev/null
+++ b/drivers/net/fs_enet/mii-fec.c
@@ -0,0 +1,243 @@
+/*
+ * Combined Ethernet driver for Motorola MPC8xx and MPC82xx.
+ *
+ * Copyright (c) 2003 Intracom S.A.
+ *  by Pantelis Antoniou <panto@intracom.gr>
+ *
+ * 2005 (c) MontaVista Software, Inc.
+ * Vitaly Bordug <vbordug@ru.mvista.com>
+ *
+ * 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 <linux/config.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/string.h>
+#include <linux/ptrace.h>
+#include <linux/errno.h>
+#include <linux/ioport.h>
+#include <linux/slab.h>
+#include <linux/interrupt.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/skbuff.h>
+#include <linux/spinlock.h>
+#include <linux/mii.h>
+#include <linux/ethtool.h>
+#include <linux/bitops.h>
+#include <linux/platform_device.h>
+
+#include <asm/pgtable.h>
+#include <asm/irq.h>
+#include <asm/uaccess.h>
+
+#include "fs_enet.h"
+#include "fec.h"
+
+/* Make MII read/write commands for the FEC.
+*/
+#define mk_mii_read(REG)	(0x60020000 | ((REG & 0x1f) << 18))
+#define mk_mii_write(REG, VAL)	(0x50020000 | ((REG & 0x1f) << 18) | (VAL & 0xffff))
+#define mk_mii_end		0
+
+#define FEC_MII_LOOPS	10000
+
+static int match_has_phy (struct device *dev, void* data)
+{
+	struct platform_device* pdev = container_of(dev, struct platform_device, dev);
+	struct fs_platform_info* fpi;
+	if(strcmp(pdev->name, (char*)data))
+	{
+	    return 0;
+	}
+
+	fpi = pdev->dev.platform_data;
+	if((fpi)&&(fpi->has_phy))
+		return 1;
+	return 0;
+}
+
+static int fs_mii_fec_init(struct fec_info* fec, struct fs_mii_fec_platform_info *fmpi)
+{
+	struct resource *r;
+	fec_t *fecp;
+	char* name = "fsl-cpm-fec";
+
+	/* we need fec in order to be useful */
+	struct platform_device *fec_pdev =
+		container_of(bus_find_device(&platform_bus_type, NULL, name, match_has_phy),
+				struct platform_device, dev);
+
+	if(fec_pdev == NULL) {
+		printk(KERN_ERR"Unable to find PHY for %s", name);
+		return -ENODEV;
+	}
+
+	r = platform_get_resource_byname(fec_pdev, IORESOURCE_MEM, "regs");
+
+	fec->fecp = fecp = (fec_t*)ioremap(r->start,sizeof(fec_t));
+	fec->mii_speed = fmpi->mii_speed;
+
+	setbits32(&fecp->fec_r_cntrl, FEC_RCNTRL_MII_MODE);	/* MII enable */
+	setbits32(&fecp->fec_ecntrl, FEC_ECNTRL_PINMUX | FEC_ECNTRL_ETHER_EN);
+	out_be32(&fecp->fec_ievent, FEC_ENET_MII);
+	out_be32(&fecp->fec_mii_speed, fec->mii_speed);
+
+	return 0;
+}
+
+static int fs_enet_fec_mii_read(struct mii_bus *bus , int phy_id, int location)
+{
+	struct fec_info* fec = bus->priv;
+	fec_t *fecp = fec->fecp;
+	int i, ret = -1;
+
+	if ((in_be32(&fecp->fec_r_cntrl) & FEC_RCNTRL_MII_MODE) == 0)
+		BUG();
+
+	/* Add PHY address to register command.  */
+	out_be32(&fecp->fec_mii_data, (phy_id << 23) | mk_mii_read(location));
+
+	for (i = 0; i < FEC_MII_LOOPS; i++)
+		if ((in_be32(&fecp->fec_ievent) & FEC_ENET_MII) != 0)
+			break;
+
+	if (i < FEC_MII_LOOPS) {
+		out_be32(&fecp->fec_ievent, FEC_ENET_MII);
+		ret = in_be32(&fecp->fec_mii_data) & 0xffff;
+	}
+
+	return ret;
+
+}
+
+static int fs_enet_fec_mii_write(struct mii_bus *bus, int phy_id, int location, u16 val)
+{
+	struct fec_info* fec = bus->priv;
+	fec_t *fecp = fec->fecp;
+	int i;
+
+	/* this must never happen */
+	if ((in_be32(&fecp->fec_r_cntrl) & FEC_RCNTRL_MII_MODE) == 0)
+		BUG();
+
+	/* Add PHY address to register command.  */
+	out_be32(&fecp->fec_mii_data, (phy_id << 23) | mk_mii_write(location, val));
+
+	for (i = 0; i < FEC_MII_LOOPS; i++)
+		if ((in_be32(&fecp->fec_ievent) & FEC_ENET_MII) != 0)
+			break;
+
+	if (i < FEC_MII_LOOPS)
+		out_be32(&fecp->fec_ievent, FEC_ENET_MII);
+
+	return 0;
+
+}
+
+static int fs_enet_fec_mii_reset(struct mii_bus *bus)
+{
+	/* nothing here - for now */
+	return 0;
+}
+
+static int __devinit fs_enet_fec_mdio_probe(struct device *dev)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct fs_mii_fec_platform_info *pdata;
+	struct mii_bus *new_bus;
+	struct fec_info *fec;
+	int err = 0;
+	if (NULL == dev)
+		return -EINVAL;
+	new_bus = kzalloc(sizeof(struct mii_bus), GFP_KERNEL);
+
+	if (NULL == new_bus)
+		return -ENOMEM;
+
+	fec = kzalloc(sizeof(struct fec_info), GFP_KERNEL);
+
+	if (NULL == fec)
+		return -ENOMEM;
+
+	new_bus->name = "FEC MII Bus",
+	new_bus->read = &fs_enet_fec_mii_read,
+	new_bus->write = &fs_enet_fec_mii_write,
+	new_bus->reset = &fs_enet_fec_mii_reset,
+	new_bus->id = pdev->id;
+
+	pdata = (struct fs_mii_fec_platform_info *)pdev->dev.platform_data;
+
+	if (NULL == pdata) {
+		printk(KERN_ERR "fs_enet FEC mdio %d: Missing platform data!\n", pdev->id);
+		return -ENODEV;
+	}
+
+	/*set up workspace*/
+
+	fs_mii_fec_init(fec, pdata);
+	new_bus->priv = fec;
+
+	new_bus->irq = pdata->irq;
+
+	new_bus->dev = dev;
+	dev_set_drvdata(dev, new_bus);
+
+	err = mdiobus_register(new_bus);
+
+	if (0 != err) {
+		printk (KERN_ERR "%s: Cannot register as MDIO bus\n",
+				new_bus->name);
+		goto bus_register_fail;
+	}
+
+	return 0;
+
+bus_register_fail:
+	kfree(new_bus);
+
+	return err;
+}
+
+
+static int fs_enet_fec_mdio_remove(struct device *dev)
+{
+	struct mii_bus *bus = dev_get_drvdata(dev);
+
+	mdiobus_unregister(bus);
+
+	dev_set_drvdata(dev, NULL);
+	kfree(bus->priv);
+
+	bus->priv = NULL;
+	kfree(bus);
+
+	return 0;
+}
+
+static struct device_driver fs_enet_fec_mdio_driver = {
+	.name = "fsl-cpm-fec-mdio",
+	.bus = &platform_bus_type,
+	.probe = fs_enet_fec_mdio_probe,
+	.remove = fs_enet_fec_mdio_remove,
+};
+
+int fs_enet_mdio_fec_init(void)
+{
+	return driver_register(&fs_enet_fec_mdio_driver);
+}
+
+void fs_enet_mdio_fec_exit(void)
+{
+	driver_unregister(&fs_enet_fec_mdio_driver);
+}
+
diff --git a/drivers/net/irda/mcs7780.c b/drivers/net/irda/mcs7780.c
new file mode 100644
index 000000000..415ba8dc9
--- /dev/null
+++ b/drivers/net/irda/mcs7780.c
@@ -0,0 +1,1008 @@
+/*****************************************************************************
+*
+* Filename:      mcs7780.c
+* Version:       0.4-alpha
+* Description:   Irda MosChip USB Dongle Driver
+* Authors:       Lukasz Stelmach <stlman@poczta.fm>
+* 		 Brian Pugh <bpugh@cs.pdx.edu>
+*		 Judy Fischbach <jfisch@cs.pdx.edu>
+*
+*       Based on stir4200 driver, but some things done differently.
+*       Based on earlier driver by Paul Stewart <stewart@parc.com>
+*
+*       Copyright (C) 2000, Roman Weissgaerber <weissg@vienna.at>
+*       Copyright (C) 2001, Dag Brattli <dag@brattli.net>
+*       Copyright (C) 2001, Jean Tourrilhes <jt@hpl.hp.com>
+*       Copyright (C) 2004, Stephen Hemminger <shemminger@osdl.org>
+*       Copyright (C) 2005, Lukasz Stelmach <stlman@poczta.fm>
+*       Copyright (C) 2005, Brian Pugh <bpugh@cs.pdx.edu>
+*       Copyright (C) 2005, Judy Fischbach <jfisch@cs.pdx.edu>
+*
+*       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.
+*
+*****************************************************************************/
+
+/*
+ * MCS7780 is a simple USB to IrDA bridge by MosChip. It is neither
+ * compatibile with irda-usb nor with stir4200. Although it is quite
+ * similar to the later as far as general idea of operation is concerned.
+ * That is it requires the software to do all the framing job at SIR speeds.
+ * The hardware does take care of the framing at MIR and FIR speeds.
+ * It supports all speeds from 2400 through 4Mbps
+ */
+
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/kref.h>
+#include <linux/usb.h>
+#include <linux/device.h>
+#include <linux/crc32.h>
+
+#include <asm/unaligned.h>
+#include <asm/byteorder.h>
+#include <asm/uaccess.h>
+
+#include <net/irda/irda.h>
+#include <net/irda/wrapper.h>
+#include <net/irda/crc.h>
+
+#include "mcs7780.h"
+
+#define MCS_VENDOR_ID 0x9710
+#define MCS_PRODUCT_ID 0x7780
+
+static struct usb_device_id mcs_table[] = {
+	/* MosChip Corp.,  MCS7780 FIR-USB Adapter */
+	{USB_DEVICE(MCS_VENDOR_ID, MCS_PRODUCT_ID)},
+	{},
+};
+
+MODULE_AUTHOR("Brian Pugh <bpugh@cs.pdx.edu>");
+MODULE_DESCRIPTION("IrDA-USB Dongle Driver for MosChip MCS7780");
+MODULE_VERSION("0.3alpha");
+MODULE_LICENSE("GPL");
+
+MODULE_DEVICE_TABLE(usb, mcs_table);
+
+static int qos_mtt_bits = 0x07 /* > 1ms */ ;
+module_param(qos_mtt_bits, int, 0);
+MODULE_PARM_DESC(qos_mtt_bits, "Minimum Turn Time");
+
+static int receive_mode = 0x1;
+module_param(receive_mode, int, 0);
+MODULE_PARM_DESC(receive_mode,
+		 "Receive mode of the device (1:fast, 0:slow, default:1)");
+
+static int sir_tweak = 1;
+module_param(sir_tweak, int, 0444);
+MODULE_PARM_DESC(sir_tweak,
+		 "Default pulse width (1:1.6us, 0:3/16 bit, default:1).");
+
+static int transceiver_type = MCS_TSC_VISHAY;
+module_param(transceiver_type, int, 0444);
+MODULE_PARM_DESC(transceiver_type, "IR transceiver type, see mcs7780.h.");
+
+static struct usb_driver mcs_driver = {
+	.name = "mcs7780",
+	.probe = mcs_probe,
+	.disconnect = mcs_disconnect,
+	.id_table = mcs_table,
+};
+
+/* speed flag selection by direct addressing.
+addr = (speed >> 8) & 0x0f
+
+0x1   57600	 0x2  115200	 0x4 1152000	 0x5    9600
+0x6   38400	 0x9    2400	 0xa  576000	 0xb   19200
+
+4Mbps (or 2400) must be checked separately. Since it also has
+to be programmed in a different manner that is not a big problem.
+*/
+static __u16 mcs_speed_set[16] = { 0,
+	MCS_SPEED_57600,
+	MCS_SPEED_115200,
+	0,
+	MCS_SPEED_1152000,
+	MCS_SPEED_9600,
+	MCS_SPEED_38400,
+	0, 0,
+	MCS_SPEED_2400,
+	MCS_SPEED_576000,
+	MCS_SPEED_19200,
+	0, 0, 0,
+};
+
+/* Set given 16 bit register with a 16 bit value. Send control message
+ * to set dongle register. */
+static int mcs_set_reg(struct mcs_cb *mcs, __u16 reg, __u16 val)
+{
+	struct usb_device *dev = mcs->usbdev;
+	return usb_control_msg(dev, usb_sndctrlpipe(dev, 0), MCS_WRREQ,
+			       MCS_WR_RTYPE, val, reg, NULL, 0,
+			       msecs_to_jiffies(MCS_CTRL_TIMEOUT));
+}
+
+/* Get 16 bit register value. Send contol message to read dongle register. */
+static int mcs_get_reg(struct mcs_cb *mcs, __u16 reg, __u16 * val)
+{
+	struct usb_device *dev = mcs->usbdev;
+	int ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), MCS_RDREQ,
+				  MCS_RD_RTYPE, 0, reg, val, 2,
+				  msecs_to_jiffies(MCS_CTRL_TIMEOUT));
+
+	return ret;
+}
+
+/* Setup a communication between mcs7780 and TFDU chips.  It is described
+ * in more detail in the data sheet.  The setup sequence puts the the
+ * vishay tranceiver into high speed mode.  It will also receive SIR speed
+ * packets but at reduced sensitivity.
+ */
+
+/* 0: OK 1:ERROR */
+static inline int mcs_setup_transceiver_vishay(struct mcs_cb *mcs)
+{
+	int ret = 0;
+	__u16 rval;
+
+	/* mcs_get_reg should read exactly two bytes from the dongle */
+	ret = mcs_get_reg(mcs, MCS_XCVR_REG, &rval);
+	if (unlikely(ret != 2)) {
+		ret = -EIO;
+		goto error;
+	}
+
+	/* The MCS_XCVR_CONF bit puts the transceiver into configuration
+	 * mode.  The MCS_MODE0 bit must start out high (1) and then
+	 * transition to low and the MCS_STFIR and MCS_MODE1 bits must
+	 * be low.
+	 */
+	rval |= (MCS_MODE0 | MCS_XCVR_CONF);
+	rval &= ~MCS_STFIR;
+	rval &= ~MCS_MODE1;
+	ret = mcs_set_reg(mcs, MCS_XCVR_REG, rval);
+	if (unlikely(ret))
+		goto error;
+
+	rval &= ~MCS_MODE0;
+	ret = mcs_set_reg(mcs, MCS_XCVR_REG, rval);
+	if (unlikely(ret))
+		goto error;
+
+	rval &= ~MCS_XCVR_CONF;
+	ret = mcs_set_reg(mcs, MCS_XCVR_REG, rval);
+	if (unlikely(ret))
+		goto error;
+
+	ret = 0;
+	error:
+		return ret;
+}
+
+/* Setup a communication between mcs7780 and agilent chip. */
+static inline int mcs_setup_transceiver_agilent(struct mcs_cb *mcs)
+{
+	IRDA_WARNING("This transceiver type is not supported yet.");
+	return 1;
+}
+
+/* Setup a communication between mcs7780 and sharp chip. */
+static inline int mcs_setup_transceiver_sharp(struct mcs_cb *mcs)
+{
+	IRDA_WARNING("This transceiver type is not supported yet.");
+	return 1;
+}
+
+/* Common setup for all transceivers */
+static inline int mcs_setup_transceiver(struct mcs_cb *mcs)
+{
+	int ret = 0;
+	__u16 rval;
+	char *msg;
+
+	msg = "Basic transceiver setup error.";
+
+	/* read value of MODE Register, set the DRIVER and RESET bits
+	* and write value back out to MODE Register
+	*/
+	ret = mcs_get_reg(mcs, MCS_MODE_REG, &rval);
+	if(unlikely(ret != 2))
+		goto error;
+	rval |= MCS_DRIVER;	/* put the mcs7780 into configuration mode. */
+	ret = mcs_set_reg(mcs, MCS_MODE_REG, rval);
+	if(unlikely(ret))
+		goto error;
+
+	rval = 0;		/* set min pulse width to 0 initially. */
+	ret = mcs_set_reg(mcs, MCS_MINRXPW_REG, rval);
+	if(unlikely(ret))
+		goto error;
+
+	ret = mcs_get_reg(mcs, MCS_MODE_REG, &rval);
+	if(unlikely(ret != 2))
+		goto error;
+
+	rval &= ~MCS_FIR;	/* turn off fir mode. */
+	if(mcs->sir_tweak)
+		rval |= MCS_SIR16US;	/* 1.6us pulse width */
+	else
+		rval &= ~MCS_SIR16US;	/* 3/16 bit time pulse width */
+
+	/* make sure ask mode and back to back packets are off. */
+	rval &= ~(MCS_BBTG | MCS_ASK);
+
+	rval &= ~MCS_SPEED_MASK;
+	rval |= MCS_SPEED_9600;		/* make sure initial speed is 9600. */
+	mcs->speed = 9600;
+	mcs->new_speed = 0;		/* new_speed is set to 0 */
+	rval &= ~MCS_PLLPWDN;		/* disable power down. */
+
+	/* make sure device determines direction and that the auto send sip
+	 * pulse are on.
+	 */
+	rval |= MCS_DTD | MCS_SIPEN;
+
+	ret = mcs_set_reg(mcs, MCS_MODE_REG, rval);
+	if(unlikely(ret))
+		goto error;
+
+	msg = "transceiver model specific setup error.";
+	switch (mcs->transceiver_type) {
+	case MCS_TSC_VISHAY:
+		ret = mcs_setup_transceiver_vishay(mcs);
+		break;
+
+	case MCS_TSC_SHARP:
+		ret = mcs_setup_transceiver_sharp(mcs);
+		break;
+
+	case MCS_TSC_AGILENT:
+		ret = mcs_setup_transceiver_agilent(mcs);
+		break;
+
+	default:
+		IRDA_WARNING("Unknown transceiver type: %d",
+			     mcs->transceiver_type);
+		ret = 1;
+	}
+	if (unlikely(ret))
+		goto error;
+
+	/* If transceiver is not SHARP, then if receive mode set
+	* on the RXFAST bit in the XCVR Register otherwise unset it
+	*/
+	if (mcs->transceiver_type != MCS_TSC_SHARP) {
+
+		ret = mcs_get_reg(mcs, MCS_XCVR_REG, &rval);
+		if (unlikely(ret != 2))
+			goto error;
+		if (mcs->receive_mode)
+			rval |= MCS_RXFAST;
+		else
+			rval &= ~MCS_RXFAST;
+		ret = mcs_set_reg(mcs, MCS_XCVR_REG, rval);
+		if (unlikely(ret))
+			goto error;
+	}
+
+	msg = "transceiver reset.";
+
+	ret = mcs_get_reg(mcs, MCS_MODE_REG, &rval);
+	if (unlikely(ret != 2))
+		goto error;
+
+	/* reset the mcs7780 so all changes take effect. */
+	rval &= ~MCS_RESET;
+	ret = mcs_set_reg(mcs, MCS_MODE_REG, rval);
+	if (unlikely(ret))
+		goto error;
+	else
+		return ret;
+
+error:
+	IRDA_ERROR("%s", msg);
+	return ret;
+}
+
+/* Wraps the data in format for SIR */
+static inline int mcs_wrap_sir_skb(struct sk_buff *skb, __u8 * buf)
+{
+	int wraplen;
+
+	/* 2: full frame length, including "the length" */
+	wraplen = async_wrap_skb(skb, buf + 2, 4094);
+
+	wraplen += 2;
+	buf[0] = wraplen & 0xff;
+	buf[1] = (wraplen >> 8) & 0xff;
+
+	return wraplen;
+}
+
+/* Wraps the data in format for FIR */
+static unsigned mcs_wrap_fir_skb(const struct sk_buff *skb, __u8 *buf)
+{
+	unsigned int len = 0;
+	__u32 fcs = ~(crc32_le(~0, skb->data, skb->len));
+
+	/* add 2 bytes for length value and 4 bytes for fcs. */
+	len = skb->len + 6;
+
+	/* The mcs7780 requires that the first two bytes are the packet
+	 * length in little endian order.  Note: the length value includes
+	 * the two bytes for the length value itself.
+	 */
+	buf[0] = len & 0xff;
+	buf[1] = (len >> 8) & 0xff;
+	/* copy the data into the tx buffer. */
+	memcpy(buf+2, skb->data, skb->len);
+	/* put the fcs in the last four bytes in little endian order. */
+	buf[len - 4] = fcs & 0xff;
+	buf[len - 3] = (fcs >> 8) & 0xff;
+	buf[len - 2] = (fcs >> 16) & 0xff;
+	buf[len - 1] = (fcs >> 24) & 0xff;
+
+	return len;
+}
+
+/* Wraps the data in format for MIR */
+static unsigned mcs_wrap_mir_skb(const struct sk_buff *skb, __u8 *buf)
+{
+	__u16 fcs = 0;
+	int len = skb->len + 4;
+
+	fcs = ~(irda_calc_crc16(~fcs, skb->data, skb->len));
+	/* put the total packet length in first.  Note: packet length
+	 * value includes the two bytes that hold the packet length
+	 * itself.
+	 */
+	buf[0] = len & 0xff;
+	buf[1] = (len >> 8) & 0xff;
+	/* copy the data */
+	memcpy(buf+2, skb->data, skb->len);
+	/* put the fcs in last two bytes in little endian order. */
+	buf[len - 2] = fcs & 0xff;
+	buf[len - 1] = (fcs >> 8) & 0xff;
+
+	return len;
+}
+
+/* Unwrap received packets at MIR speed.  A 16 bit crc_ccitt checksum is
+ * used for the fcs.  When performed over the entire packet the result
+ * should be GOOD_FCS = 0xf0b8.  Hands the unwrapped data off to the IrDA
+ * layer via a sk_buff.
+ */
+static void mcs_unwrap_mir(struct mcs_cb *mcs, __u8 *buf, int len)
+{
+	__u16 fcs;
+	int new_len;
+	struct sk_buff *skb;
+
+	/* Assume that the frames are going to fill a single packet
+	 * rather than span multiple packets.
+	 */
+
+	new_len = len - 2;
+	if(unlikely(new_len <= 0)) {
+		IRDA_ERROR("%s short frame length %d\n",
+			     mcs->netdev->name, new_len);
+		++mcs->stats.rx_errors;
+		++mcs->stats.rx_length_errors;
+		return;
+	}
+	fcs = 0;
+	fcs = irda_calc_crc16(~fcs, buf, len);
+
+	if(fcs != GOOD_FCS) {
+		IRDA_ERROR("crc error calc 0x%x len %d\n",
+			   fcs, new_len);
+		mcs->stats.rx_errors++;
+		mcs->stats.rx_crc_errors++;
+		return;
+	}
+
+	skb = dev_alloc_skb(new_len + 1);
+	if(unlikely(!skb)) {
+		++mcs->stats.rx_dropped;
+		return;
+	}
+
+	skb_reserve(skb, 1);
+	memcpy(skb->data, buf, new_len);
+	skb_put(skb, new_len);
+	skb->mac.raw = skb->data;
+	skb->protocol = htons(ETH_P_IRDA);
+	skb->dev = mcs->netdev;
+
+	netif_rx(skb);
+
+	mcs->stats.rx_packets++;
+	mcs->stats.rx_bytes += new_len;
+
+	return;
+}
+
+/* Unwrap received packets at FIR speed.  A 32 bit crc_ccitt checksum is
+ * used for the fcs.  Hands the unwrapped data off to the IrDA
+ * layer via a sk_buff.
+ */
+static void mcs_unwrap_fir(struct mcs_cb *mcs, __u8 *buf, int len)
+{
+	__u32 fcs;
+	int new_len;
+	struct sk_buff *skb;
+
+	/* Assume that the frames are going to fill a single packet
+	 * rather than span multiple packets.  This is most likely a false
+	 * assumption.
+	 */
+
+	new_len = len - 4;
+	if(unlikely(new_len <= 0)) {
+		IRDA_ERROR("%s short frame length %d\n",
+			   mcs->netdev->name, new_len);
+		++mcs->stats.rx_errors;
+		++mcs->stats.rx_length_errors;
+		return;
+	}
+
+	fcs = ~(crc32_le(~0, buf, new_len));
+	if(fcs != le32_to_cpu(get_unaligned((u32 *)(buf+new_len)))) {
+		IRDA_ERROR("crc error calc 0x%x len %d\n", fcs, new_len);
+		mcs->stats.rx_errors++;
+		mcs->stats.rx_crc_errors++;
+		return;
+	}
+
+	skb = dev_alloc_skb(new_len + 1);
+	if(unlikely(!skb)) {
+		++mcs->stats.rx_dropped;
+		return;
+	}
+
+	skb_reserve(skb, 1);
+	memcpy(skb->data, buf, new_len);
+	skb_put(skb, new_len);
+	skb->mac.raw = skb->data;
+	skb->protocol = htons(ETH_P_IRDA);
+	skb->dev = mcs->netdev;
+
+	netif_rx(skb);
+
+	mcs->stats.rx_packets++;
+	mcs->stats.rx_bytes += new_len;
+
+	return;
+}
+
+
+/* Allocates urbs for both receive and transmit.
+ * If alloc fails return error code 0 (fail) otherwise
+ * return error code 1 (success).
+ */
+static inline int mcs_setup_urbs(struct mcs_cb *mcs)
+{
+	mcs->rx_urb = NULL;
+
+	mcs->tx_urb = usb_alloc_urb(0, GFP_KERNEL);
+	if (!mcs->tx_urb)
+		return 0;
+
+	mcs->rx_urb = usb_alloc_urb(0, GFP_KERNEL);
+	if (!mcs->rx_urb)
+		return 0;
+
+	return 1;
+}
+
+/* Sets up state to be initially outside frame, gets receive urb,
+ * sets status to successful and then submits the urb to start
+ * receiving the data.
+ */
+static inline int mcs_receive_start(struct mcs_cb *mcs)
+{
+	mcs->rx_buff.in_frame = FALSE;
+	mcs->rx_buff.state = OUTSIDE_FRAME;
+
+	usb_fill_bulk_urb(mcs->rx_urb, mcs->usbdev,
+			  usb_rcvbulkpipe(mcs->usbdev, mcs->ep_in),
+			  mcs->in_buf, 4096, mcs_receive_irq, mcs);
+
+	mcs->rx_urb->status = 0;
+	return usb_submit_urb(mcs->rx_urb, GFP_KERNEL);
+}
+
+/* Finds the in and out endpoints for the mcs control block */
+static inline int mcs_find_endpoints(struct mcs_cb *mcs,
+				     struct usb_host_endpoint *ep, int epnum)
+{
+	int i;
+	int ret = 0;
+
+	/* If no place to store the endpoints just return */
+	if (!ep)
+		return ret;
+
+	/* cycle through all endpoints, find the first two that are DIR_IN */
+	for (i = 0; i < epnum; i++) {
+		if (ep[i].desc.bEndpointAddress & USB_DIR_IN)
+			mcs->ep_in = ep[i].desc.bEndpointAddress;
+		else
+			mcs->ep_out = ep[i].desc.bEndpointAddress;
+
+		/* MosChip says that the chip has only two bulk
+		 * endpoints. Find one for each direction and move on.
+		 */
+		if ((mcs->ep_in != 0) && (mcs->ep_out != 0)) {
+			ret = 1;
+			break;
+		}
+	}
+
+	return ret;
+}
+
+static void mcs_speed_work(void *arg)
+{
+	struct mcs_cb *mcs = arg;
+	struct net_device *netdev = mcs->netdev;
+
+	mcs_speed_change(mcs);
+	netif_wake_queue(netdev);
+}
+
+/* Function to change the speed of the mcs7780.  Fully supports SIR,
+ * MIR, and FIR speeds.
+ */
+static int mcs_speed_change(struct mcs_cb *mcs)
+{
+	int ret = 0;
+	int rst = 0;
+	int cnt = 0;
+	__u16 nspeed;
+	__u16 rval;
+
+	nspeed = mcs_speed_set[(mcs->new_speed >> 8) & 0x0f];
+
+	do {
+		mcs_get_reg(mcs, MCS_RESV_REG, &rval);
+	} while(cnt++ < 100 && (rval & MCS_IRINTX));
+
+	if(cnt >= 100) {
+		IRDA_ERROR("unable to change speed");
+		ret = -EIO;
+		goto error;
+	}
+
+	mcs_get_reg(mcs, MCS_MODE_REG, &rval);
+
+	/* MINRXPW values recomended by MosChip */
+	if (mcs->new_speed <= 115200) {
+		rval &= ~MCS_FIR;
+
+		if ((rst = (mcs->speed > 115200)))
+			mcs_set_reg(mcs, MCS_MINRXPW_REG, 0);
+
+	} else if (mcs->new_speed <= 1152000) {
+		rval &= ~MCS_FIR;
+
+		if ((rst = !(mcs->speed == 576000 || mcs->speed == 1152000)))
+			mcs_set_reg(mcs, MCS_MINRXPW_REG, 5);
+
+	} else {
+		rval |= MCS_FIR;
+
+		if ((rst = (mcs->speed != 4000000)))
+			mcs_set_reg(mcs, MCS_MINRXPW_REG, 5);
+
+	}
+
+	rval &= ~MCS_SPEED_MASK;
+	rval |= nspeed;
+
+	ret = mcs_set_reg(mcs, MCS_MODE_REG, rval);
+	if (unlikely(ret))
+		goto error;
+
+	if (rst)
+		switch (mcs->transceiver_type) {
+		case MCS_TSC_VISHAY:
+			ret = mcs_setup_transceiver_vishay(mcs);
+			break;
+
+		case MCS_TSC_SHARP:
+			ret = mcs_setup_transceiver_sharp(mcs);
+			break;
+
+		case MCS_TSC_AGILENT:
+			ret = mcs_setup_transceiver_agilent(mcs);
+			break;
+
+		default:
+			ret = 1;
+			IRDA_WARNING("Unknown transceiver type: %d",
+				     mcs->transceiver_type);
+		}
+	if (unlikely(ret))
+		goto error;
+
+	mcs_get_reg(mcs, MCS_MODE_REG, &rval);
+	rval &= ~MCS_RESET;
+	ret = mcs_set_reg(mcs, MCS_MODE_REG, rval);
+
+	mcs->speed = mcs->new_speed;
+	error:
+		mcs->new_speed = 0;
+		return ret;
+}
+
+/* Ioctl calls not supported at this time.  Can be an area of future work. */
+static int mcs_net_ioctl(struct net_device *netdev, struct ifreq *rq, int cmd)
+{
+	/* struct if_irda_req *irq = (struct if_irda_req *)rq; */
+	/* struct mcs_cb *mcs = netdev_priv(netdev); */
+	int ret = 0;
+
+	switch (cmd) {
+	default:
+		ret = -EOPNOTSUPP;
+	}
+
+	return ret;
+}
+
+/* Network device is taken down, done by "ifconfig irda0 down" */
+static int mcs_net_close(struct net_device *netdev)
+{
+	int ret = 0;
+	struct mcs_cb *mcs = netdev_priv(netdev);
+
+	/* Stop transmit processing */
+	netif_stop_queue(netdev);
+
+	/* kill and free the receive and transmit URBs */
+	usb_kill_urb(mcs->rx_urb);
+	usb_free_urb(mcs->rx_urb);
+	usb_kill_urb(mcs->tx_urb);
+	usb_free_urb(mcs->tx_urb);
+
+	/* Stop and remove instance of IrLAP */
+	if (mcs->irlap)
+		irlap_close(mcs->irlap);
+
+	mcs->irlap = NULL;
+	return ret;
+}
+
+/* Network device is taken up, done by "ifconfig irda0 up" */
+static int mcs_net_open(struct net_device *netdev)
+{
+	struct mcs_cb *mcs = netdev_priv(netdev);
+	char hwname[16];
+	int ret = 0;
+
+	ret = usb_clear_halt(mcs->usbdev,
+			     usb_sndbulkpipe(mcs->usbdev, mcs->ep_in));
+	if (ret)
+		goto error1;
+	ret = usb_clear_halt(mcs->usbdev,
+			     usb_rcvbulkpipe(mcs->usbdev, mcs->ep_out));
+	if (ret)
+		goto error1;
+
+	ret = mcs_setup_transceiver(mcs);
+	if (ret)
+		goto error1;
+
+	ret = -ENOMEM;
+
+	/* Initialize for SIR/FIR to copy data directly into skb.  */
+	mcs->receiving = 0;
+	mcs->rx_buff.truesize = IRDA_SKB_MAX_MTU;
+	mcs->rx_buff.skb = dev_alloc_skb(IRDA_SKB_MAX_MTU);
+	if (!mcs->rx_buff.skb)
+		goto error1;
+
+	skb_reserve(mcs->rx_buff.skb, 1);
+	mcs->rx_buff.head = mcs->rx_buff.skb->data;
+	do_gettimeofday(&mcs->rx_time);
+
+	/*
+	 * Now that everything should be initialized properly,
+	 * Open new IrLAP layer instance to take care of us...
+	 * Note : will send immediately a speed change...
+	 */
+	sprintf(hwname, "usb#%d", mcs->usbdev->devnum);
+	mcs->irlap = irlap_open(netdev, &mcs->qos, hwname);
+	if (!mcs->irlap) {
+		IRDA_ERROR("mcs7780: irlap_open failed");
+		goto error2;
+	}
+
+	if (!mcs_setup_urbs(mcs))
+	goto error3;
+
+	ret = mcs_receive_start(mcs);
+	if (ret)
+		goto error3;
+
+	netif_start_queue(netdev);
+	return 0;
+
+	error3:
+		irlap_close(mcs->irlap);
+	error2:
+		kfree_skb(mcs->rx_buff.skb);
+	error1:
+		return ret;
+}
+
+
+/* Get device stats for /proc/net/dev and ifconfig */
+static struct net_device_stats *mcs_net_get_stats(struct net_device *netdev)
+{
+	struct mcs_cb *mcs = netdev_priv(netdev);
+	return &mcs->stats;
+}
+
+/* Receive callback function.  */
+static void mcs_receive_irq(struct urb *urb, struct pt_regs *regs)
+{
+	__u8 *bytes;
+	struct mcs_cb *mcs = urb->context;
+	int i;
+	int ret;
+
+	if (!netif_running(mcs->netdev))
+		return;
+
+	if (urb->status)
+		return;
+
+	if (urb->actual_length > 0) {
+		bytes = urb->transfer_buffer;
+
+		/* MCS returns frames without BOF and EOF
+		 * I assume it returns whole frames.
+		 */
+		/* SIR speed */
+		if(mcs->speed < 576000) {
+			async_unwrap_char(mcs->netdev, &mcs->stats,
+				  &mcs->rx_buff, 0xc0);
+
+			for (i = 0; i < urb->actual_length; i++)
+				async_unwrap_char(mcs->netdev, &mcs->stats,
+					  &mcs->rx_buff, bytes[i]);
+
+			async_unwrap_char(mcs->netdev, &mcs->stats,
+				  &mcs->rx_buff, 0xc1);
+		}
+		/* MIR speed */
+		else if(mcs->speed == 576000 || mcs->speed == 1152000) {
+			mcs_unwrap_mir(mcs, urb->transfer_buffer,
+				urb->actual_length);
+		}
+		/* FIR speed */
+		else {
+			mcs_unwrap_fir(mcs, urb->transfer_buffer,
+				urb->actual_length);
+		}
+		mcs->netdev->last_rx = jiffies;
+		do_gettimeofday(&mcs->rx_time);
+	}
+
+	ret = usb_submit_urb(urb, GFP_ATOMIC);
+}
+
+/* Transmit callback funtion.  */
+static void mcs_send_irq(struct urb *urb, struct pt_regs *regs)
+{
+	struct mcs_cb *mcs = urb->context;
+	struct net_device *ndev = mcs->netdev;
+
+	if (unlikely(mcs->new_speed))
+		schedule_work(&mcs->work);
+	else
+		netif_wake_queue(ndev);
+}
+
+/* Transmit callback funtion.  */
+static int mcs_hard_xmit(struct sk_buff *skb, struct net_device *ndev)
+{
+	unsigned long flags;
+	struct mcs_cb *mcs;
+	int wraplen;
+	int ret = 0;
+
+
+	if (skb == NULL || ndev == NULL)
+		return -EINVAL;
+
+	netif_stop_queue(ndev);
+	mcs = netdev_priv(ndev);
+
+	spin_lock_irqsave(&mcs->lock, flags);
+
+	mcs->new_speed = irda_get_next_speed(skb);
+	if (likely(mcs->new_speed == mcs->speed))
+		mcs->new_speed = 0;
+
+	/* SIR speed */
+	if(mcs->speed < 576000) {
+		wraplen = mcs_wrap_sir_skb(skb, mcs->out_buf);
+	}
+	/* MIR speed */
+	else if(mcs->speed == 576000 || mcs->speed == 1152000) {
+		wraplen = mcs_wrap_mir_skb(skb, mcs->out_buf);
+	}
+	/* FIR speed */
+	else {
+		wraplen = mcs_wrap_fir_skb(skb, mcs->out_buf);
+	}
+	usb_fill_bulk_urb(mcs->tx_urb, mcs->usbdev,
+			  usb_sndbulkpipe(mcs->usbdev, mcs->ep_out),
+			  mcs->out_buf, wraplen, mcs_send_irq, mcs);
+
+	if ((ret = usb_submit_urb(mcs->tx_urb, GFP_ATOMIC))) {
+		IRDA_ERROR("failed tx_urb: %d", ret);
+		switch (ret) {
+		case -ENODEV:
+		case -EPIPE:
+			break;
+		default:
+			mcs->stats.tx_errors++;
+			netif_start_queue(ndev);
+		}
+	} else {
+		mcs->stats.tx_packets++;
+		mcs->stats.tx_bytes += skb->len;
+	}
+
+	dev_kfree_skb(skb);
+	spin_unlock_irqrestore(&mcs->lock, flags);
+	return ret;
+}
+
+/*
+ * This function is called by the USB subsystem for each new device in the
+ * system.  Need to verify the device and if it is, then start handling it.
+ */
+static int mcs_probe(struct usb_interface *intf,
+		     const struct usb_device_id *id)
+{
+	struct usb_device *udev = interface_to_usbdev(intf);
+	struct net_device *ndev = NULL;
+	struct mcs_cb *mcs;
+	int ret = -ENOMEM;
+
+	ndev = alloc_irdadev(sizeof(*mcs));
+	if (!ndev)
+		goto error1;
+
+	IRDA_DEBUG(1, "MCS7780 USB-IrDA bridge found at %d.", udev->devnum);
+
+	/* what is it realy for? */
+	SET_MODULE_OWNER(ndev);
+	SET_NETDEV_DEV(ndev, &intf->dev);
+
+	ret = usb_reset_configuration(udev);
+	if (ret != 0) {
+		IRDA_ERROR("mcs7780: usb reset configuration failed");
+		goto error2;
+	}
+
+	mcs = netdev_priv(ndev);
+	mcs->usbdev = udev;
+	mcs->netdev = ndev;
+	spin_lock_init(&mcs->lock);
+
+	/* Initialize QoS for this device */
+	irda_init_max_qos_capabilies(&mcs->qos);
+
+	/* That's the Rx capability. */
+	mcs->qos.baud_rate.bits &=
+	    IR_2400 | IR_9600 | IR_19200 | IR_38400 | IR_57600 | IR_115200
+		| IR_576000 | IR_1152000 | (IR_4000000 << 8);
+
+
+	mcs->qos.min_turn_time.bits &= qos_mtt_bits;
+	irda_qos_bits_to_value(&mcs->qos);
+
+	/* Speed change work initialisation*/
+	INIT_WORK(&mcs->work, mcs_speed_work, mcs);
+
+	/* Override the network functions we need to use */
+	ndev->hard_start_xmit = mcs_hard_xmit;
+	ndev->open = mcs_net_open;
+	ndev->stop = mcs_net_close;
+	ndev->get_stats = mcs_net_get_stats;
+	ndev->do_ioctl = mcs_net_ioctl;
+
+	if (!intf->cur_altsetting)
+		goto error2;
+
+	ret = mcs_find_endpoints(mcs, intf->cur_altsetting->endpoint,
+				 intf->cur_altsetting->desc.bNumEndpoints);
+	if (!ret) {
+		ret = -ENODEV;
+		goto error2;
+	}
+
+	ret = register_netdev(ndev);
+	if (ret != 0)
+		goto error2;
+
+	IRDA_DEBUG(1, "IrDA: Registered MosChip MCS7780 device as %s",
+		   ndev->name);
+
+	mcs->transceiver_type = transceiver_type;
+	mcs->sir_tweak = sir_tweak;
+	mcs->receive_mode = receive_mode;
+
+	usb_set_intfdata(intf, mcs);
+	return 0;
+
+	error2:
+		free_netdev(ndev);
+
+	error1:
+		return ret;
+}
+
+/* The current device is removed, the USB layer tells us to shut down. */
+static void mcs_disconnect(struct usb_interface *intf)
+{
+	struct mcs_cb *mcs = usb_get_intfdata(intf);
+
+	if (!mcs)
+		return;
+
+	flush_scheduled_work();
+
+	unregister_netdev(mcs->netdev);
+	free_netdev(mcs->netdev);
+
+	usb_set_intfdata(intf, NULL);
+	IRDA_DEBUG(0, "MCS7780 now disconnected.");
+}
+
+/* Module insertion */
+static int __init mcs_init(void)
+{
+	int result;
+
+	/* register this driver with the USB subsystem */
+	result = usb_register(&mcs_driver);
+	if (result)
+		IRDA_ERROR("usb_register failed. Error number %d", result);
+
+	return result;
+}
+module_init(mcs_init);
+
+/* Module removal */
+static void __exit mcs_exit(void)
+{
+	/* deregister this driver with the USB subsystem */
+	usb_deregister(&mcs_driver);
+}
+module_exit(mcs_exit);
+
diff --git a/drivers/net/irda/mcs7780.h b/drivers/net/irda/mcs7780.h
new file mode 100644
index 000000000..1a723d725
--- /dev/null
+++ b/drivers/net/irda/mcs7780.h
@@ -0,0 +1,167 @@
+/*****************************************************************************
+*
+* Filename:      mcs7780.h
+* Version:       0.2-alpha
+* Description:   Irda MosChip USB Dongle
+* Status:        Experimental
+* Authors:       Lukasz Stelmach <stlman@poczta.fm>
+*		 Brian Pugh <bpugh@cs.pdx.edu>
+*
+*       Copyright (C) 2005, Lukasz Stelmach <stlman@poczta.fm>
+*       Copyright (C) 2005, Brian Pugh <bpugh@cs.pdx.edu>
+*
+*       This program is free software; you can redistribute it and/or modify
+*       it under the terms of the GNU General Public License as published by
+*       the Free Software Foundation; either version 2 of the License, or
+*       (at your option) any later version.
+*
+*       This program is distributed in the hope that it will be useful,
+*       but WITHOUT ANY WARRANTY; without even the implied warranty of
+*       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*       GNU General Public License for more details.
+*
+*       You should have received a copy of the GNU General Public License
+*       along with this program; if not, write to the Free Software
+*       Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*
+*****************************************************************************/
+#ifndef _MCS7780_H
+#define _MCS7780_H
+
+#define MCS_MODE_SIR		0
+#define MCS_MODE_MIR		1
+#define MCS_MODE_FIR		2
+
+#define MCS_CTRL_TIMEOUT	500
+#define MCS_XMIT_TIMEOUT	500
+/* Possible transceiver types */
+#define MCS_TSC_VISHAY		0	/* Vishay TFD, default choice */
+#define MCS_TSC_AGILENT		1	/* Agilent 3602/3600 */
+#define MCS_TSC_SHARP		2	/* Sharp GP2W1000YP */
+
+/* Requests */
+#define MCS_RD_RTYPE 0xC0
+#define MCS_WR_RTYPE 0x40
+#define MCS_RDREQ    0x0F
+#define MCS_WRREQ    0x0E
+
+/* Register 0x00 */
+#define MCS_MODE_REG	0
+#define MCS_FIR		((__u16)0x0001)
+#define MCS_SIR16US	((__u16)0x0002)
+#define MCS_BBTG	((__u16)0x0004)
+#define MCS_ASK		((__u16)0x0008)
+#define MCS_PARITY	((__u16)0x0010)
+
+/* SIR/MIR speed constants */
+#define MCS_SPEED_SHIFT	    5
+#define MCS_SPEED_MASK	    ((__u16)0x00E0)
+#define MCS_SPEED(x)	    ((x & MCS_SPEED_MASK) >> MCS_SPEED_SHIFT)
+#define MCS_SPEED_2400	    ((0 << MCS_SPEED_SHIFT) & MCS_SPEED_MASK)
+#define MCS_SPEED_9600	    ((1 << MCS_SPEED_SHIFT) & MCS_SPEED_MASK)
+#define MCS_SPEED_19200	    ((2 << MCS_SPEED_SHIFT) & MCS_SPEED_MASK)
+#define MCS_SPEED_38400	    ((3 << MCS_SPEED_SHIFT) & MCS_SPEED_MASK)
+#define MCS_SPEED_57600	    ((4 << MCS_SPEED_SHIFT) & MCS_SPEED_MASK)
+#define MCS_SPEED_115200    ((5 << MCS_SPEED_SHIFT) & MCS_SPEED_MASK)
+#define MCS_SPEED_576000    ((6 << MCS_SPEED_SHIFT) & MCS_SPEED_MASK)
+#define MCS_SPEED_1152000   ((7 << MCS_SPEED_SHIFT) & MCS_SPEED_MASK)
+
+#define MCS_PLLPWDN	((__u16)0x0100)
+#define MCS_DRIVER	((__u16)0x0200)
+#define MCS_DTD		((__u16)0x0400)
+#define MCS_DIR		((__u16)0x0800)
+#define MCS_SIPEN	((__u16)0x1000)
+#define MCS_SENDSIP	((__u16)0x2000)
+#define MCS_CHGDIR	((__u16)0x4000)
+#define MCS_RESET	((__u16)0x8000)
+
+/* Register 0x02 */
+#define MCS_XCVR_REG	2
+#define MCS_MODE0	((__u16)0x0001)
+#define MCS_STFIR	((__u16)0x0002)
+#define MCS_XCVR_CONF	((__u16)0x0004)
+#define MCS_RXFAST	((__u16)0x0008)
+/* TXCUR [6:4] */
+#define MCS_TXCUR_SHIFT	4
+#define MCS_TXCUR_MASK	((__u16)0x0070)
+#define MCS_TXCUR(x)	((x & MCS_TXCUR_MASK) >> MCS_TXCUR_SHIFT)
+#define MCS_SETTXCUR(x,y) \
+	((x & ~MCS_TXCUR_MASK) | (y << MCS_TXCUR_SHIFT) & MCS_TXCUR_MASK)
+
+#define MCS_MODE1	((__u16)0x0080)
+#define MCS_SMODE0	((__u16)0x0100)
+#define MCS_SMODE1	((__u16)0x0200)
+#define MCS_INVTX	((__u16)0x0400)
+#define MCS_INVRX	((__u16)0x0800)
+
+#define MCS_MINRXPW_REG	4
+
+#define MCS_RESV_REG 7
+#define MCS_IRINTX	((__u16)0x0001)
+#define MCS_IRINRX	((__u16)0x0002)
+
+struct mcs_cb {
+	struct usb_device *usbdev;	/* init: probe_irda */
+	struct net_device *netdev;	/* network layer */
+	struct irlap_cb *irlap;	/* The link layer we are binded to */
+	struct net_device_stats stats;	/* network statistics */
+	struct qos_info qos;
+	unsigned int speed;	/* Current speed */
+	unsigned int new_speed;	/* new speed */
+
+	struct work_struct work; /* Change speed work */
+
+	struct sk_buff *tx_pending;
+	char in_buf[4096];	/* transmit/receive buffer */
+	char out_buf[4096];	/* transmit/receive buffer */
+	__u8 *fifo_status;
+
+	iobuff_t rx_buff;	/* receive unwrap state machine */
+	struct timeval rx_time;
+	spinlock_t lock;
+	int receiving;
+
+	__u8 ep_in;
+	__u8 ep_out;
+
+	struct urb *rx_urb;
+	struct urb *tx_urb;
+
+	int transceiver_type;
+	int sir_tweak;
+	int receive_mode;
+};
+
+static int mcs_set_reg(struct mcs_cb *mcs, __u16 reg, __u16 val);
+static int mcs_get_reg(struct mcs_cb *mcs, __u16 reg, __u16 * val);
+
+static inline int mcs_setup_transceiver_vishay(struct mcs_cb *mcs);
+static inline int mcs_setup_transceiver_agilent(struct mcs_cb *mcs);
+static inline int mcs_setup_transceiver_sharp(struct mcs_cb *mcs);
+static inline int mcs_setup_transceiver(struct mcs_cb *mcs);
+static inline int mcs_wrap_sir_skb(struct sk_buff *skb, __u8 * buf);
+static unsigned mcs_wrap_fir_skb(const struct sk_buff *skb, __u8 *buf);
+static unsigned mcs_wrap_mir_skb(const struct sk_buff *skb, __u8 *buf);
+static void mcs_unwrap_mir(struct mcs_cb *mcs, __u8 *buf, int len);
+static void mcs_unwrap_fir(struct mcs_cb *mcs, __u8 *buf, int len);
+static inline int mcs_setup_urbs(struct mcs_cb *mcs);
+static inline int mcs_receive_start(struct mcs_cb *mcs);
+static inline int mcs_find_endpoints(struct mcs_cb *mcs,
+				     struct usb_host_endpoint *ep, int epnum);
+
+static int mcs_speed_change(struct mcs_cb *mcs);
+
+static int mcs_net_ioctl(struct net_device *netdev, struct ifreq *rq, int cmd);
+static int mcs_net_close(struct net_device *netdev);
+static int mcs_net_open(struct net_device *netdev);
+static struct net_device_stats *mcs_net_get_stats(struct net_device *netdev);
+
+static void mcs_receive_irq(struct urb *urb, struct pt_regs *regs);
+static void mcs_send_irq(struct urb *urb, struct pt_regs *regs);
+static int mcs_hard_xmit(struct sk_buff *skb, struct net_device *netdev);
+
+static int mcs_probe(struct usb_interface *intf,
+		     const struct usb_device_id *id);
+static void mcs_disconnect(struct usb_interface *intf);
+
+#endif				/* _MCS7780_H */
diff --git a/drivers/net/myri10ge/Makefile b/drivers/net/myri10ge/Makefile
new file mode 100644
index 000000000..5df891647
--- /dev/null
+++ b/drivers/net/myri10ge/Makefile
@@ -0,0 +1,5 @@
+#
+# Makefile for the Myricom Myri-10G ethernet driver
+#
+
+obj-$(CONFIG_MYRI10GE) += myri10ge.o
diff --git a/drivers/net/myri10ge/myri10ge.c b/drivers/net/myri10ge/myri10ge.c
new file mode 100644
index 000000000..9bdd43ab3
--- /dev/null
+++ b/drivers/net/myri10ge/myri10ge.c
@@ -0,0 +1,2866 @@
+/*************************************************************************
+ * myri10ge.c: Myricom Myri-10G Ethernet driver.
+ *
+ * Copyright (C) 2005, 2006 Myricom, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of Myricom, Inc. nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *
+ * If the eeprom on your board is not recent enough, you will need to get a
+ * newer firmware image at:
+ *   http://www.myri.com/scs/download-Myri10GE.html
+ *
+ * Contact Information:
+ *   <help@myri.com>
+ *   Myricom, Inc., 325N Santa Anita Avenue, Arcadia, CA 91006
+ *************************************************************************/
+
+#include <linux/tcp.h>
+#include <linux/netdevice.h>
+#include <linux/skbuff.h>
+#include <linux/string.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/dma-mapping.h>
+#include <linux/etherdevice.h>
+#include <linux/if_ether.h>
+#include <linux/if_vlan.h>
+#include <linux/ip.h>
+#include <linux/inet.h>
+#include <linux/in.h>
+#include <linux/ethtool.h>
+#include <linux/firmware.h>
+#include <linux/delay.h>
+#include <linux/version.h>
+#include <linux/timer.h>
+#include <linux/vmalloc.h>
+#include <linux/crc32.h>
+#include <linux/moduleparam.h>
+#include <linux/io.h>
+#include <net/checksum.h>
+#include <asm/byteorder.h>
+#include <asm/io.h>
+#include <asm/processor.h>
+#ifdef CONFIG_MTRR
+#include <asm/mtrr.h>
+#endif
+
+#include "myri10ge_mcp.h"
+#include "myri10ge_mcp_gen_header.h"
+
+#define MYRI10GE_VERSION_STR "1.0.0"
+
+MODULE_DESCRIPTION("Myricom 10G driver (10GbE)");
+MODULE_AUTHOR("Maintainer: help@myri.com");
+MODULE_VERSION(MYRI10GE_VERSION_STR);
+MODULE_LICENSE("Dual BSD/GPL");
+
+#define MYRI10GE_MAX_ETHER_MTU 9014
+
+#define MYRI10GE_ETH_STOPPED 0
+#define MYRI10GE_ETH_STOPPING 1
+#define MYRI10GE_ETH_STARTING 2
+#define MYRI10GE_ETH_RUNNING 3
+#define MYRI10GE_ETH_OPEN_FAILED 4
+
+#define MYRI10GE_EEPROM_STRINGS_SIZE 256
+#define MYRI10GE_MAX_SEND_DESC_TSO ((65536 / 2048) * 2)
+
+#define MYRI10GE_NO_CONFIRM_DATA 0xffffffff
+#define MYRI10GE_NO_RESPONSE_RESULT 0xffffffff
+
+struct myri10ge_rx_buffer_state {
+	struct sk_buff *skb;
+	 DECLARE_PCI_UNMAP_ADDR(bus)
+	 DECLARE_PCI_UNMAP_LEN(len)
+};
+
+struct myri10ge_tx_buffer_state {
+	struct sk_buff *skb;
+	int last;
+	 DECLARE_PCI_UNMAP_ADDR(bus)
+	 DECLARE_PCI_UNMAP_LEN(len)
+};
+
+struct myri10ge_cmd {
+	u32 data0;
+	u32 data1;
+	u32 data2;
+};
+
+struct myri10ge_rx_buf {
+	struct mcp_kreq_ether_recv __iomem *lanai;	/* lanai ptr for recv ring */
+	u8 __iomem *wc_fifo;	/* w/c rx dma addr fifo address */
+	struct mcp_kreq_ether_recv *shadow;	/* host shadow of recv ring */
+	struct myri10ge_rx_buffer_state *info;
+	int cnt;
+	int alloc_fail;
+	int mask;		/* number of rx slots -1 */
+};
+
+struct myri10ge_tx_buf {
+	struct mcp_kreq_ether_send __iomem *lanai;	/* lanai ptr for sendq */
+	u8 __iomem *wc_fifo;	/* w/c send fifo address */
+	struct mcp_kreq_ether_send *req_list;	/* host shadow of sendq */
+	char *req_bytes;
+	struct myri10ge_tx_buffer_state *info;
+	int mask;		/* number of transmit slots -1  */
+	int boundary;		/* boundary transmits cannot cross */
+	int req ____cacheline_aligned;	/* transmit slots submitted     */
+	int pkt_start;		/* packets started */
+	int done ____cacheline_aligned;	/* transmit slots completed     */
+	int pkt_done;		/* packets completed */
+};
+
+struct myri10ge_rx_done {
+	struct mcp_slot *entry;
+	dma_addr_t bus;
+	int cnt;
+	int idx;
+};
+
+struct myri10ge_priv {
+	int running;		/* running?             */
+	int csum_flag;		/* rx_csums?            */
+	struct myri10ge_tx_buf tx;	/* transmit ring        */
+	struct myri10ge_rx_buf rx_small;
+	struct myri10ge_rx_buf rx_big;
+	struct myri10ge_rx_done rx_done;
+	int small_bytes;
+	struct net_device *dev;
+	struct net_device_stats stats;
+	u8 __iomem *sram;
+	int sram_size;
+	unsigned long board_span;
+	unsigned long iomem_base;
+	u32 __iomem *irq_claim;
+	u32 __iomem *irq_deassert;
+	char *mac_addr_string;
+	struct mcp_cmd_response *cmd;
+	dma_addr_t cmd_bus;
+	struct mcp_irq_data *fw_stats;
+	dma_addr_t fw_stats_bus;
+	struct pci_dev *pdev;
+	int msi_enabled;
+	unsigned int link_state;
+	unsigned int rdma_tags_available;
+	int intr_coal_delay;
+	u32 __iomem *intr_coal_delay_ptr;
+	int mtrr;
+	int wake_queue;
+	int stop_queue;
+	int down_cnt;
+	wait_queue_head_t down_wq;
+	struct work_struct watchdog_work;
+	struct timer_list watchdog_timer;
+	int watchdog_tx_done;
+	int watchdog_tx_req;
+	int watchdog_resets;
+	int tx_linearized;
+	int pause;
+	char *fw_name;
+	char eeprom_strings[MYRI10GE_EEPROM_STRINGS_SIZE];
+	char fw_version[128];
+	u8 mac_addr[6];		/* eeprom mac address */
+	unsigned long serial_number;
+	int vendor_specific_offset;
+	u32 devctl;
+	u16 msi_flags;
+	u32 read_dma;
+	u32 write_dma;
+	u32 read_write_dma;
+};
+
+static char *myri10ge_fw_unaligned = "myri10ge_ethp_z8e.dat";
+static char *myri10ge_fw_aligned = "myri10ge_eth_z8e.dat";
+
+static char *myri10ge_fw_name = NULL;
+module_param(myri10ge_fw_name, charp, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(myri10ge_fw_name, "Firmware image name\n");
+
+static int myri10ge_ecrc_enable = 1;
+module_param(myri10ge_ecrc_enable, int, S_IRUGO);
+MODULE_PARM_DESC(myri10ge_ecrc_enable, "Enable Extended CRC on PCI-E\n");
+
+static int myri10ge_max_intr_slots = 1024;
+module_param(myri10ge_max_intr_slots, int, S_IRUGO);
+MODULE_PARM_DESC(myri10ge_max_intr_slots, "Interrupt queue slots\n");
+
+static int myri10ge_small_bytes = -1;	/* -1 == auto */
+module_param(myri10ge_small_bytes, int, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(myri10ge_small_bytes, "Threshold of small packets\n");
+
+static int myri10ge_msi = 1;	/* enable msi by default */
+module_param(myri10ge_msi, int, S_IRUGO);
+MODULE_PARM_DESC(myri10ge_msi, "Enable Message Signalled Interrupts\n");
+
+static int myri10ge_intr_coal_delay = 25;
+module_param(myri10ge_intr_coal_delay, int, S_IRUGO);
+MODULE_PARM_DESC(myri10ge_intr_coal_delay, "Interrupt coalescing delay\n");
+
+static int myri10ge_flow_control = 1;
+module_param(myri10ge_flow_control, int, S_IRUGO);
+MODULE_PARM_DESC(myri10ge_flow_control, "Pause parameter\n");
+
+static int myri10ge_deassert_wait = 1;
+module_param(myri10ge_deassert_wait, int, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(myri10ge_deassert_wait,
+		 "Wait when deasserting legacy interrupts\n");
+
+static int myri10ge_force_firmware = 0;
+module_param(myri10ge_force_firmware, int, S_IRUGO);
+MODULE_PARM_DESC(myri10ge_force_firmware,
+		 "Force firmware to assume aligned completions\n");
+
+static int myri10ge_skb_cross_4k = 0;
+module_param(myri10ge_skb_cross_4k, int, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(myri10ge_skb_cross_4k,
+		 "Can a small skb cross a 4KB boundary?\n");
+
+static int myri10ge_initial_mtu = MYRI10GE_MAX_ETHER_MTU - ETH_HLEN;
+module_param(myri10ge_initial_mtu, int, S_IRUGO);
+MODULE_PARM_DESC(myri10ge_initial_mtu, "Initial MTU\n");
+
+static int myri10ge_napi_weight = 64;
+module_param(myri10ge_napi_weight, int, S_IRUGO);
+MODULE_PARM_DESC(myri10ge_napi_weight, "Set NAPI weight\n");
+
+static int myri10ge_watchdog_timeout = 1;
+module_param(myri10ge_watchdog_timeout, int, S_IRUGO);
+MODULE_PARM_DESC(myri10ge_watchdog_timeout, "Set watchdog timeout\n");
+
+static int myri10ge_max_irq_loops = 1048576;
+module_param(myri10ge_max_irq_loops, int, S_IRUGO);
+MODULE_PARM_DESC(myri10ge_max_irq_loops,
+		 "Set stuck legacy IRQ detection threshold\n");
+
+#define MYRI10GE_FW_OFFSET 1024*1024
+#define MYRI10GE_HIGHPART_TO_U32(X) \
+(sizeof (X) == 8) ? ((u32)((u64)(X) >> 32)) : (0)
+#define MYRI10GE_LOWPART_TO_U32(X) ((u32)(X))
+
+#define myri10ge_pio_copy(to,from,size) __iowrite64_copy(to,from,size/8)
+
+static int
+myri10ge_send_cmd(struct myri10ge_priv *mgp, u32 cmd,
+		  struct myri10ge_cmd *data, int atomic)
+{
+	struct mcp_cmd *buf;
+	char buf_bytes[sizeof(*buf) + 8];
+	struct mcp_cmd_response *response = mgp->cmd;
+	char __iomem *cmd_addr = mgp->sram + MXGEFW_CMD_OFFSET;
+	u32 dma_low, dma_high, result, value;
+	int sleep_total = 0;
+
+	/* ensure buf is aligned to 8 bytes */
+	buf = (struct mcp_cmd *)ALIGN((unsigned long)buf_bytes, 8);
+
+	buf->data0 = htonl(data->data0);
+	buf->data1 = htonl(data->data1);
+	buf->data2 = htonl(data->data2);
+	buf->cmd = htonl(cmd);
+	dma_low = MYRI10GE_LOWPART_TO_U32(mgp->cmd_bus);
+	dma_high = MYRI10GE_HIGHPART_TO_U32(mgp->cmd_bus);
+
+	buf->response_addr.low = htonl(dma_low);
+	buf->response_addr.high = htonl(dma_high);
+	response->result = MYRI10GE_NO_RESPONSE_RESULT;
+	mb();
+	myri10ge_pio_copy(cmd_addr, buf, sizeof(*buf));
+
+	/* wait up to 15ms. Longest command is the DMA benchmark,
+	 * which is capped at 5ms, but runs from a timeout handler
+	 * that runs every 7.8ms. So a 15ms timeout leaves us with
+	 * a 2.2ms margin
+	 */
+	if (atomic) {
+		/* if atomic is set, do not sleep,
+		 * and try to get the completion quickly
+		 * (1ms will be enough for those commands) */
+		for (sleep_total = 0;
+		     sleep_total < 1000
+		     && response->result == MYRI10GE_NO_RESPONSE_RESULT;
+		     sleep_total += 10)
+			udelay(10);
+	} else {
+		/* use msleep for most command */
+		for (sleep_total = 0;
+		     sleep_total < 15
+		     && response->result == MYRI10GE_NO_RESPONSE_RESULT;
+		     sleep_total++)
+			msleep(1);
+	}
+
+	result = ntohl(response->result);
+	value = ntohl(response->data);
+	if (result != MYRI10GE_NO_RESPONSE_RESULT) {
+		if (result == 0) {
+			data->data0 = value;
+			return 0;
+		} else {
+			dev_err(&mgp->pdev->dev,
+				"command %d failed, result = %d\n",
+				cmd, result);
+			return -ENXIO;
+		}
+	}
+
+	dev_err(&mgp->pdev->dev, "command %d timed out, result = %d\n",
+		cmd, result);
+	return -EAGAIN;
+}
+
+/*
+ * The eeprom strings on the lanaiX have the format
+ * SN=x\0
+ * MAC=x:x:x:x:x:x\0
+ * PT:ddd mmm xx xx:xx:xx xx\0
+ * PV:ddd mmm xx xx:xx:xx xx\0
+ */
+static int myri10ge_read_mac_addr(struct myri10ge_priv *mgp)
+{
+	char *ptr, *limit;
+	int i;
+
+	ptr = mgp->eeprom_strings;
+	limit = mgp->eeprom_strings + MYRI10GE_EEPROM_STRINGS_SIZE;
+
+	while (*ptr != '\0' && ptr < limit) {
+		if (memcmp(ptr, "MAC=", 4) == 0) {
+			ptr += 4;
+			mgp->mac_addr_string = ptr;
+			for (i = 0; i < 6; i++) {
+				if ((ptr + 2) > limit)
+					goto abort;
+				mgp->mac_addr[i] =
+				    simple_strtoul(ptr, &ptr, 16);
+				ptr += 1;
+			}
+		}
+		if (memcmp((const void *)ptr, "SN=", 3) == 0) {
+			ptr += 3;
+			mgp->serial_number = simple_strtoul(ptr, &ptr, 10);
+		}
+		while (ptr < limit && *ptr++) ;
+	}
+
+	return 0;
+
+abort:
+	dev_err(&mgp->pdev->dev, "failed to parse eeprom_strings\n");
+	return -ENXIO;
+}
+
+/*
+ * Enable or disable periodic RDMAs from the host to make certain
+ * chipsets resend dropped PCIe messages
+ */
+
+static void myri10ge_dummy_rdma(struct myri10ge_priv *mgp, int enable)
+{
+	char __iomem *submit;
+	u32 buf[16];
+	u32 dma_low, dma_high;
+	int i;
+
+	/* clear confirmation addr */
+	mgp->cmd->data = 0;
+	mb();
+
+	/* send a rdma command to the PCIe engine, and wait for the
+	 * response in the confirmation address.  The firmware should
+	 * write a -1 there to indicate it is alive and well
+	 */
+	dma_low = MYRI10GE_LOWPART_TO_U32(mgp->cmd_bus);
+	dma_high = MYRI10GE_HIGHPART_TO_U32(mgp->cmd_bus);
+
+	buf[0] = htonl(dma_high);	/* confirm addr MSW */
+	buf[1] = htonl(dma_low);	/* confirm addr LSW */
+	buf[2] = htonl(MYRI10GE_NO_CONFIRM_DATA);	/* confirm data */
+	buf[3] = htonl(dma_high);	/* dummy addr MSW */
+	buf[4] = htonl(dma_low);	/* dummy addr LSW */
+	buf[5] = htonl(enable);	/* enable? */
+
+	submit = mgp->sram + 0xfc01c0;
+
+	myri10ge_pio_copy(submit, &buf, sizeof(buf));
+	for (i = 0; mgp->cmd->data != MYRI10GE_NO_CONFIRM_DATA && i < 20; i++)
+		msleep(1);
+	if (mgp->cmd->data != MYRI10GE_NO_CONFIRM_DATA)
+		dev_err(&mgp->pdev->dev, "dummy rdma %s failed\n",
+			(enable ? "enable" : "disable"));
+}
+
+static int
+myri10ge_validate_firmware(struct myri10ge_priv *mgp,
+			   struct mcp_gen_header *hdr)
+{
+	struct device *dev = &mgp->pdev->dev;
+	int major, minor;
+
+	/* check firmware type */
+	if (ntohl(hdr->mcp_type) != MCP_TYPE_ETH) {
+		dev_err(dev, "Bad firmware type: 0x%x\n", ntohl(hdr->mcp_type));
+		return -EINVAL;
+	}
+
+	/* save firmware version for ethtool */
+	strncpy(mgp->fw_version, hdr->version, sizeof(mgp->fw_version));
+
+	sscanf(mgp->fw_version, "%d.%d", &major, &minor);
+
+	if (!(major == MXGEFW_VERSION_MAJOR && minor == MXGEFW_VERSION_MINOR)) {
+		dev_err(dev, "Found firmware version %s\n", mgp->fw_version);
+		dev_err(dev, "Driver needs %d.%d\n", MXGEFW_VERSION_MAJOR,
+			MXGEFW_VERSION_MINOR);
+		return -EINVAL;
+	}
+	return 0;
+}
+
+static int myri10ge_load_hotplug_firmware(struct myri10ge_priv *mgp, u32 * size)
+{
+	unsigned crc, reread_crc;
+	const struct firmware *fw;
+	struct device *dev = &mgp->pdev->dev;
+	struct mcp_gen_header *hdr;
+	size_t hdr_offset;
+	int status;
+	unsigned i;
+
+	if ((status = request_firmware(&fw, mgp->fw_name, dev)) < 0) {
+		dev_err(dev, "Unable to load %s firmware image via hotplug\n",
+			mgp->fw_name);
+		status = -EINVAL;
+		goto abort_with_nothing;
+	}
+
+	/* check size */
+
+	if (fw->size >= mgp->sram_size - MYRI10GE_FW_OFFSET ||
+	    fw->size < MCP_HEADER_PTR_OFFSET + 4) {
+		dev_err(dev, "Firmware size invalid:%d\n", (int)fw->size);
+		status = -EINVAL;
+		goto abort_with_fw;
+	}
+
+	/* check id */
+	hdr_offset = ntohl(*(u32 *) (fw->data + MCP_HEADER_PTR_OFFSET));
+	if ((hdr_offset & 3) || hdr_offset + sizeof(*hdr) > fw->size) {
+		dev_err(dev, "Bad firmware file\n");
+		status = -EINVAL;
+		goto abort_with_fw;
+	}
+	hdr = (void *)(fw->data + hdr_offset);
+
+	status = myri10ge_validate_firmware(mgp, hdr);
+	if (status != 0)
+		goto abort_with_fw;
+
+	crc = crc32(~0, fw->data, fw->size);
+	for (i = 0; i < fw->size; i += 256) {
+		myri10ge_pio_copy(mgp->sram + MYRI10GE_FW_OFFSET + i,
+				  fw->data + i,
+				  min(256U, (unsigned)(fw->size - i)));
+		mb();
+		readb(mgp->sram);
+	}
+	/* corruption checking is good for parity recovery and buggy chipset */
+	memcpy_fromio(fw->data, mgp->sram + MYRI10GE_FW_OFFSET, fw->size);
+	reread_crc = crc32(~0, fw->data, fw->size);
+	if (crc != reread_crc) {
+		dev_err(dev, "CRC failed(fw-len=%u), got 0x%x (expect 0x%x)\n",
+			(unsigned)fw->size, reread_crc, crc);
+		status = -EIO;
+		goto abort_with_fw;
+	}
+	*size = (u32) fw->size;
+
+abort_with_fw:
+	release_firmware(fw);
+
+abort_with_nothing:
+	return status;
+}
+
+static int myri10ge_adopt_running_firmware(struct myri10ge_priv *mgp)
+{
+	struct mcp_gen_header *hdr;
+	struct device *dev = &mgp->pdev->dev;
+	const size_t bytes = sizeof(struct mcp_gen_header);
+	size_t hdr_offset;
+	int status;
+
+	/* find running firmware header */
+	hdr_offset = ntohl(__raw_readl(mgp->sram + MCP_HEADER_PTR_OFFSET));
+
+	if ((hdr_offset & 3) || hdr_offset + sizeof(*hdr) > mgp->sram_size) {
+		dev_err(dev, "Running firmware has bad header offset (%d)\n",
+			(int)hdr_offset);
+		return -EIO;
+	}
+
+	/* copy header of running firmware from SRAM to host memory to
+	 * validate firmware */
+	hdr = kmalloc(bytes, GFP_KERNEL);
+	if (hdr == NULL) {
+		dev_err(dev, "could not malloc firmware hdr\n");
+		return -ENOMEM;
+	}
+	memcpy_fromio(hdr, mgp->sram + hdr_offset, bytes);
+	status = myri10ge_validate_firmware(mgp, hdr);
+	kfree(hdr);
+	return status;
+}
+
+static int myri10ge_load_firmware(struct myri10ge_priv *mgp)
+{
+	char __iomem *submit;
+	u32 buf[16];
+	u32 dma_low, dma_high, size;
+	int status, i;
+
+	size = 0;
+	status = myri10ge_load_hotplug_firmware(mgp, &size);
+	if (status) {
+		dev_warn(&mgp->pdev->dev, "hotplug firmware loading failed\n");
+
+		/* Do not attempt to adopt firmware if there
+		 * was a bad crc */
+		if (status == -EIO)
+			return status;
+
+		status = myri10ge_adopt_running_firmware(mgp);
+		if (status != 0) {
+			dev_err(&mgp->pdev->dev,
+				"failed to adopt running firmware\n");
+			return status;
+		}
+		dev_info(&mgp->pdev->dev,
+			 "Successfully adopted running firmware\n");
+		if (mgp->tx.boundary == 4096) {
+			dev_warn(&mgp->pdev->dev,
+				 "Using firmware currently running on NIC"
+				 ".  For optimal\n");
+			dev_warn(&mgp->pdev->dev,
+				 "performance consider loading optimized "
+				 "firmware\n");
+			dev_warn(&mgp->pdev->dev, "via hotplug\n");
+		}
+
+		mgp->fw_name = "adopted";
+		mgp->tx.boundary = 2048;
+		return status;
+	}
+
+	/* clear confirmation addr */
+	mgp->cmd->data = 0;
+	mb();
+
+	/* send a reload command to the bootstrap MCP, and wait for the
+	 *  response in the confirmation address.  The firmware should
+	 * write a -1 there to indicate it is alive and well
+	 */
+	dma_low = MYRI10GE_LOWPART_TO_U32(mgp->cmd_bus);
+	dma_high = MYRI10GE_HIGHPART_TO_U32(mgp->cmd_bus);
+
+	buf[0] = htonl(dma_high);	/* confirm addr MSW */
+	buf[1] = htonl(dma_low);	/* confirm addr LSW */
+	buf[2] = htonl(MYRI10GE_NO_CONFIRM_DATA);	/* confirm data */
+
+	/* FIX: All newest firmware should un-protect the bottom of
+	 * the sram before handoff. However, the very first interfaces
+	 * do not. Therefore the handoff copy must skip the first 8 bytes
+	 */
+	buf[3] = htonl(MYRI10GE_FW_OFFSET + 8);	/* where the code starts */
+	buf[4] = htonl(size - 8);	/* length of code */
+	buf[5] = htonl(8);	/* where to copy to */
+	buf[6] = htonl(0);	/* where to jump to */
+
+	submit = mgp->sram + 0xfc0000;
+
+	myri10ge_pio_copy(submit, &buf, sizeof(buf));
+	mb();
+	msleep(1);
+	mb();
+	i = 0;
+	while (mgp->cmd->data != MYRI10GE_NO_CONFIRM_DATA && i < 20) {
+		msleep(1);
+		i++;
+	}
+	if (mgp->cmd->data != MYRI10GE_NO_CONFIRM_DATA) {
+		dev_err(&mgp->pdev->dev, "handoff failed\n");
+		return -ENXIO;
+	}
+	dev_info(&mgp->pdev->dev, "handoff confirmed\n");
+	myri10ge_dummy_rdma(mgp, 1);
+
+	return 0;
+}
+
+static int myri10ge_update_mac_address(struct myri10ge_priv *mgp, u8 * addr)
+{
+	struct myri10ge_cmd cmd;
+	int status;
+
+	cmd.data0 = ((addr[0] << 24) | (addr[1] << 16)
+		     | (addr[2] << 8) | addr[3]);
+
+	cmd.data1 = ((addr[4] << 8) | (addr[5]));
+
+	status = myri10ge_send_cmd(mgp, MXGEFW_SET_MAC_ADDRESS, &cmd, 0);
+	return status;
+}
+
+static int myri10ge_change_pause(struct myri10ge_priv *mgp, int pause)
+{
+	struct myri10ge_cmd cmd;
+	int status, ctl;
+
+	ctl = pause ? MXGEFW_ENABLE_FLOW_CONTROL : MXGEFW_DISABLE_FLOW_CONTROL;
+	status = myri10ge_send_cmd(mgp, ctl, &cmd, 0);
+
+	if (status) {
+		printk(KERN_ERR
+		       "myri10ge: %s: Failed to set flow control mode\n",
+		       mgp->dev->name);
+		return status;
+	}
+	mgp->pause = pause;
+	return 0;
+}
+
+static void
+myri10ge_change_promisc(struct myri10ge_priv *mgp, int promisc, int atomic)
+{
+	struct myri10ge_cmd cmd;
+	int status, ctl;
+
+	ctl = promisc ? MXGEFW_ENABLE_PROMISC : MXGEFW_DISABLE_PROMISC;
+	status = myri10ge_send_cmd(mgp, ctl, &cmd, atomic);
+	if (status)
+		printk(KERN_ERR "myri10ge: %s: Failed to set promisc mode\n",
+		       mgp->dev->name);
+}
+
+static int myri10ge_reset(struct myri10ge_priv *mgp)
+{
+	struct myri10ge_cmd cmd;
+	int status;
+	size_t bytes;
+	u32 len;
+
+	/* try to send a reset command to the card to see if it
+	 * is alive */
+	memset(&cmd, 0, sizeof(cmd));
+	status = myri10ge_send_cmd(mgp, MXGEFW_CMD_RESET, &cmd, 0);
+	if (status != 0) {
+		dev_err(&mgp->pdev->dev, "failed reset\n");
+		return -ENXIO;
+	}
+
+	/* Now exchange information about interrupts  */
+
+	bytes = myri10ge_max_intr_slots * sizeof(*mgp->rx_done.entry);
+	memset(mgp->rx_done.entry, 0, bytes);
+	cmd.data0 = (u32) bytes;
+	status = myri10ge_send_cmd(mgp, MXGEFW_CMD_SET_INTRQ_SIZE, &cmd, 0);
+	cmd.data0 = MYRI10GE_LOWPART_TO_U32(mgp->rx_done.bus);
+	cmd.data1 = MYRI10GE_HIGHPART_TO_U32(mgp->rx_done.bus);
+	status |= myri10ge_send_cmd(mgp, MXGEFW_CMD_SET_INTRQ_DMA, &cmd, 0);
+
+	status |=
+	    myri10ge_send_cmd(mgp, MXGEFW_CMD_GET_IRQ_ACK_OFFSET, &cmd, 0);
+	mgp->irq_claim = (__iomem u32 *) (mgp->sram + cmd.data0);
+	if (!mgp->msi_enabled) {
+		status |= myri10ge_send_cmd
+		    (mgp, MXGEFW_CMD_GET_IRQ_DEASSERT_OFFSET, &cmd, 0);
+		mgp->irq_deassert = (__iomem u32 *) (mgp->sram + cmd.data0);
+
+	}
+	status |= myri10ge_send_cmd
+	    (mgp, MXGEFW_CMD_GET_INTR_COAL_DELAY_OFFSET, &cmd, 0);
+	mgp->intr_coal_delay_ptr = (__iomem u32 *) (mgp->sram + cmd.data0);
+	if (status != 0) {
+		dev_err(&mgp->pdev->dev, "failed set interrupt parameters\n");
+		return status;
+	}
+	__raw_writel(htonl(mgp->intr_coal_delay), mgp->intr_coal_delay_ptr);
+
+	/* Run a small DMA test.
+	 * The magic multipliers to the length tell the firmware
+	 * to do DMA read, write, or read+write tests.  The
+	 * results are returned in cmd.data0.  The upper 16
+	 * bits or the return is the number of transfers completed.
+	 * The lower 16 bits is the time in 0.5us ticks that the
+	 * transfers took to complete.
+	 */
+
+	len = mgp->tx.boundary;
+
+	cmd.data0 = MYRI10GE_LOWPART_TO_U32(mgp->rx_done.bus);
+	cmd.data1 = MYRI10GE_HIGHPART_TO_U32(mgp->rx_done.bus);
+	cmd.data2 = len * 0x10000;
+	status = myri10ge_send_cmd(mgp, MXGEFW_DMA_TEST, &cmd, 0);
+	if (status == 0)
+		mgp->read_dma = ((cmd.data0 >> 16) * len * 2) /
+		    (cmd.data0 & 0xffff);
+	else
+		dev_warn(&mgp->pdev->dev, "DMA read benchmark failed: %d\n",
+			 status);
+	cmd.data0 = MYRI10GE_LOWPART_TO_U32(mgp->rx_done.bus);
+	cmd.data1 = MYRI10GE_HIGHPART_TO_U32(mgp->rx_done.bus);
+	cmd.data2 = len * 0x1;
+	status = myri10ge_send_cmd(mgp, MXGEFW_DMA_TEST, &cmd, 0);
+	if (status == 0)
+		mgp->write_dma = ((cmd.data0 >> 16) * len * 2) /
+		    (cmd.data0 & 0xffff);
+	else
+		dev_warn(&mgp->pdev->dev, "DMA write benchmark failed: %d\n",
+			 status);
+
+	cmd.data0 = MYRI10GE_LOWPART_TO_U32(mgp->rx_done.bus);
+	cmd.data1 = MYRI10GE_HIGHPART_TO_U32(mgp->rx_done.bus);
+	cmd.data2 = len * 0x10001;
+	status = myri10ge_send_cmd(mgp, MXGEFW_DMA_TEST, &cmd, 0);
+	if (status == 0)
+		mgp->read_write_dma = ((cmd.data0 >> 16) * len * 2 * 2) /
+		    (cmd.data0 & 0xffff);
+	else
+		dev_warn(&mgp->pdev->dev,
+			 "DMA read/write benchmark failed: %d\n", status);
+
+	memset(mgp->rx_done.entry, 0, bytes);
+
+	/* reset mcp/driver shared state back to 0 */
+	mgp->tx.req = 0;
+	mgp->tx.done = 0;
+	mgp->tx.pkt_start = 0;
+	mgp->tx.pkt_done = 0;
+	mgp->rx_big.cnt = 0;
+	mgp->rx_small.cnt = 0;
+	mgp->rx_done.idx = 0;
+	mgp->rx_done.cnt = 0;
+	status = myri10ge_update_mac_address(mgp, mgp->dev->dev_addr);
+	myri10ge_change_promisc(mgp, 0, 0);
+	myri10ge_change_pause(mgp, mgp->pause);
+	return status;
+}
+
+static inline void
+myri10ge_submit_8rx(struct mcp_kreq_ether_recv __iomem * dst,
+		    struct mcp_kreq_ether_recv *src)
+{
+	u32 low;
+
+	low = src->addr_low;
+	src->addr_low = DMA_32BIT_MASK;
+	myri10ge_pio_copy(dst, src, 8 * sizeof(*src));
+	mb();
+	src->addr_low = low;
+	__raw_writel(low, &dst->addr_low);
+	mb();
+}
+
+/*
+ * Set of routines to get a new receive buffer.  Any buffer which
+ * crosses a 4KB boundary must start on a 4KB boundary due to PCIe
+ * wdma restrictions. We also try to align any smaller allocation to
+ * at least a 16 byte boundary for efficiency.  We assume the linux
+ * memory allocator works by powers of 2, and will not return memory
+ * smaller than 2KB which crosses a 4KB boundary.  If it does, we fall
+ * back to allocating 2x as much space as required.
+ *
+ * We intend to replace large (>4KB) skb allocations by using
+ * pages directly and building a fraglist in the near future.
+ */
+
+static inline struct sk_buff *myri10ge_alloc_big(int bytes)
+{
+	struct sk_buff *skb;
+	unsigned long data, roundup;
+
+	skb = dev_alloc_skb(bytes + 4096 + MXGEFW_PAD);
+	if (skb == NULL)
+		return NULL;
+
+	/* Correct skb->truesize so that socket buffer
+	 * accounting is not confused the rounding we must
+	 * do to satisfy alignment constraints.
+	 */
+	skb->truesize -= 4096;
+
+	data = (unsigned long)(skb->data);
+	roundup = (-data) & (4095);
+	skb_reserve(skb, roundup);
+	return skb;
+}
+
+/* Allocate 2x as much space as required and use whichever portion
+ * does not cross a 4KB boundary */
+static inline struct sk_buff *myri10ge_alloc_small_safe(unsigned int bytes)
+{
+	struct sk_buff *skb;
+	unsigned long data, boundary;
+
+	skb = dev_alloc_skb(2 * (bytes + MXGEFW_PAD) - 1);
+	if (unlikely(skb == NULL))
+		return NULL;
+
+	/* Correct skb->truesize so that socket buffer
+	 * accounting is not confused the rounding we must
+	 * do to satisfy alignment constraints.
+	 */
+	skb->truesize -= bytes + MXGEFW_PAD;
+
+	data = (unsigned long)(skb->data);
+	boundary = (data + 4095UL) & ~4095UL;
+	if ((boundary - data) >= (bytes + MXGEFW_PAD))
+		return skb;
+
+	skb_reserve(skb, boundary - data);
+	return skb;
+}
+
+/* Allocate just enough space, and verify that the allocated
+ * space does not cross a 4KB boundary */
+static inline struct sk_buff *myri10ge_alloc_small(int bytes)
+{
+	struct sk_buff *skb;
+	unsigned long roundup, data, end;
+
+	skb = dev_alloc_skb(bytes + 16 + MXGEFW_PAD);
+	if (unlikely(skb == NULL))
+		return NULL;
+
+	/* Round allocated buffer to 16 byte boundary */
+	data = (unsigned long)(skb->data);
+	roundup = (-data) & 15UL;
+	skb_reserve(skb, roundup);
+	/* Verify that the data buffer does not cross a page boundary */
+	data = (unsigned long)(skb->data);
+	end = data + bytes + MXGEFW_PAD - 1;
+	if (unlikely(((end >> 12) != (data >> 12)) && (data & 4095UL))) {
+		printk(KERN_NOTICE
+		       "myri10ge_alloc_small: small skb crossed 4KB boundary\n");
+		myri10ge_skb_cross_4k = 1;
+		dev_kfree_skb_any(skb);
+		skb = myri10ge_alloc_small_safe(bytes);
+	}
+	return skb;
+}
+
+static inline int
+myri10ge_getbuf(struct myri10ge_rx_buf *rx, struct pci_dev *pdev, int bytes,
+		int idx)
+{
+	struct sk_buff *skb;
+	dma_addr_t bus;
+	int len, retval = 0;
+
+	bytes += VLAN_HLEN;	/* account for 802.1q vlan tag */
+
+	if ((bytes + MXGEFW_PAD) > (4096 - 16) /* linux overhead */ )
+		skb = myri10ge_alloc_big(bytes);
+	else if (myri10ge_skb_cross_4k)
+		skb = myri10ge_alloc_small_safe(bytes);
+	else
+		skb = myri10ge_alloc_small(bytes);
+
+	if (unlikely(skb == NULL)) {
+		rx->alloc_fail++;
+		retval = -ENOBUFS;
+		goto done;
+	}
+
+	/* set len so that it only covers the area we
+	 * need mapped for DMA */
+	len = bytes + MXGEFW_PAD;
+
+	bus = pci_map_single(pdev, skb->data, len, PCI_DMA_FROMDEVICE);
+	rx->info[idx].skb = skb;
+	pci_unmap_addr_set(&rx->info[idx], bus, bus);
+	pci_unmap_len_set(&rx->info[idx], len, len);
+	rx->shadow[idx].addr_low = htonl(MYRI10GE_LOWPART_TO_U32(bus));
+	rx->shadow[idx].addr_high = htonl(MYRI10GE_HIGHPART_TO_U32(bus));
+
+done:
+	/* copy 8 descriptors (64-bytes) to the mcp at a time */
+	if ((idx & 7) == 7) {
+		if (rx->wc_fifo == NULL)
+			myri10ge_submit_8rx(&rx->lanai[idx - 7],
+					    &rx->shadow[idx - 7]);
+		else {
+			mb();
+			myri10ge_pio_copy(rx->wc_fifo,
+					  &rx->shadow[idx - 7], 64);
+		}
+	}
+	return retval;
+}
+
+static inline void myri10ge_vlan_ip_csum(struct sk_buff *skb, u16 hw_csum)
+{
+	struct vlan_hdr *vh = (struct vlan_hdr *)(skb->data);
+
+	if ((skb->protocol == ntohs(ETH_P_8021Q)) &&
+	    (vh->h_vlan_encapsulated_proto == htons(ETH_P_IP) ||
+	     vh->h_vlan_encapsulated_proto == htons(ETH_P_IPV6))) {
+		skb->csum = hw_csum;
+		skb->ip_summed = CHECKSUM_HW;
+	}
+}
+
+static inline unsigned long
+myri10ge_rx_done(struct myri10ge_priv *mgp, struct myri10ge_rx_buf *rx,
+		 int bytes, int len, int csum)
+{
+	dma_addr_t bus;
+	struct sk_buff *skb;
+	int idx, unmap_len;
+
+	idx = rx->cnt & rx->mask;
+	rx->cnt++;
+
+	/* save a pointer to the received skb */
+	skb = rx->info[idx].skb;
+	bus = pci_unmap_addr(&rx->info[idx], bus);
+	unmap_len = pci_unmap_len(&rx->info[idx], len);
+
+	/* try to replace the received skb */
+	if (myri10ge_getbuf(rx, mgp->pdev, bytes, idx)) {
+		/* drop the frame -- the old skbuf is re-cycled */
+		mgp->stats.rx_dropped += 1;
+		return 0;
+	}
+
+	/* unmap the recvd skb */
+	pci_unmap_single(mgp->pdev, bus, unmap_len, PCI_DMA_FROMDEVICE);
+
+	/* mcp implicitly skips 1st bytes so that packet is properly
+	 * aligned */
+	skb_reserve(skb, MXGEFW_PAD);
+
+	/* set the length of the frame */
+	skb_put(skb, len);
+
+	skb->protocol = eth_type_trans(skb, mgp->dev);
+	skb->dev = mgp->dev;
+	if (mgp->csum_flag) {
+		if ((skb->protocol == ntohs(ETH_P_IP)) ||
+		    (skb->protocol == ntohs(ETH_P_IPV6))) {
+			skb->csum = ntohs((u16) csum);
+			skb->ip_summed = CHECKSUM_HW;
+		} else
+			myri10ge_vlan_ip_csum(skb, ntohs((u16) csum));
+	}
+
+	netif_receive_skb(skb);
+	mgp->dev->last_rx = jiffies;
+	return 1;
+}
+
+static inline void myri10ge_tx_done(struct myri10ge_priv *mgp, int mcp_index)
+{
+	struct pci_dev *pdev = mgp->pdev;
+	struct myri10ge_tx_buf *tx = &mgp->tx;
+	struct sk_buff *skb;
+	int idx, len;
+	int limit = 0;
+
+	while (tx->pkt_done != mcp_index) {
+		idx = tx->done & tx->mask;
+		skb = tx->info[idx].skb;
+
+		/* Mark as free */
+		tx->info[idx].skb = NULL;
+		if (tx->info[idx].last) {
+			tx->pkt_done++;
+			tx->info[idx].last = 0;
+		}
+		tx->done++;
+		len = pci_unmap_len(&tx->info[idx], len);
+		pci_unmap_len_set(&tx->info[idx], len, 0);
+		if (skb) {
+			mgp->stats.tx_bytes += skb->len;
+			mgp->stats.tx_packets++;
+			dev_kfree_skb_irq(skb);
+			if (len)
+				pci_unmap_single(pdev,
+						 pci_unmap_addr(&tx->info[idx],
+								bus), len,
+						 PCI_DMA_TODEVICE);
+		} else {
+			if (len)
+				pci_unmap_page(pdev,
+					       pci_unmap_addr(&tx->info[idx],
+							      bus), len,
+					       PCI_DMA_TODEVICE);
+		}
+
+		/* limit potential for livelock by only handling
+		 * 2 full tx rings per call */
+		if (unlikely(++limit > 2 * tx->mask))
+			break;
+	}
+	/* start the queue if we've stopped it */
+	if (netif_queue_stopped(mgp->dev)
+	    && tx->req - tx->done < (tx->mask >> 1)) {
+		mgp->wake_queue++;
+		netif_wake_queue(mgp->dev);
+	}
+}
+
+static inline void myri10ge_clean_rx_done(struct myri10ge_priv *mgp, int *limit)
+{
+	struct myri10ge_rx_done *rx_done = &mgp->rx_done;
+	unsigned long rx_bytes = 0;
+	unsigned long rx_packets = 0;
+	unsigned long rx_ok;
+
+	int idx = rx_done->idx;
+	int cnt = rx_done->cnt;
+	u16 length;
+	u16 checksum;
+
+	while (rx_done->entry[idx].length != 0 && *limit != 0) {
+		length = ntohs(rx_done->entry[idx].length);
+		rx_done->entry[idx].length = 0;
+		checksum = ntohs(rx_done->entry[idx].checksum);
+		if (length <= mgp->small_bytes)
+			rx_ok = myri10ge_rx_done(mgp, &mgp->rx_small,
+						 mgp->small_bytes,
+						 length, checksum);
+		else
+			rx_ok = myri10ge_rx_done(mgp, &mgp->rx_big,
+						 mgp->dev->mtu + ETH_HLEN,
+						 length, checksum);
+		rx_packets += rx_ok;
+		rx_bytes += rx_ok * (unsigned long)length;
+		cnt++;
+		idx = cnt & (myri10ge_max_intr_slots - 1);
+
+		/* limit potential for livelock by only handling a
+		 * limited number of frames. */
+		(*limit)--;
+	}
+	rx_done->idx = idx;
+	rx_done->cnt = cnt;
+	mgp->stats.rx_packets += rx_packets;
+	mgp->stats.rx_bytes += rx_bytes;
+}
+
+static inline void myri10ge_check_statblock(struct myri10ge_priv *mgp)
+{
+	struct mcp_irq_data *stats = mgp->fw_stats;
+
+	if (unlikely(stats->stats_updated)) {
+		if (mgp->link_state != stats->link_up) {
+			mgp->link_state = stats->link_up;
+			if (mgp->link_state) {
+				printk(KERN_INFO "myri10ge: %s: link up\n",
+				       mgp->dev->name);
+				netif_carrier_on(mgp->dev);
+			} else {
+				printk(KERN_INFO "myri10ge: %s: link down\n",
+				       mgp->dev->name);
+				netif_carrier_off(mgp->dev);
+			}
+		}
+		if (mgp->rdma_tags_available !=
+		    ntohl(mgp->fw_stats->rdma_tags_available)) {
+			mgp->rdma_tags_available =
+			    ntohl(mgp->fw_stats->rdma_tags_available);
+			printk(KERN_WARNING "myri10ge: %s: RDMA timed out! "
+			       "%d tags left\n", mgp->dev->name,
+			       mgp->rdma_tags_available);
+		}
+		mgp->down_cnt += stats->link_down;
+		if (stats->link_down)
+			wake_up(&mgp->down_wq);
+	}
+}
+
+static int myri10ge_poll(struct net_device *netdev, int *budget)
+{
+	struct myri10ge_priv *mgp = netdev_priv(netdev);
+	struct myri10ge_rx_done *rx_done = &mgp->rx_done;
+	int limit, orig_limit, work_done;
+
+	/* process as many rx events as NAPI will allow */
+	limit = min(*budget, netdev->quota);
+	orig_limit = limit;
+	myri10ge_clean_rx_done(mgp, &limit);
+	work_done = orig_limit - limit;
+	*budget -= work_done;
+	netdev->quota -= work_done;
+
+	if (rx_done->entry[rx_done->idx].length == 0 || !netif_running(netdev)) {
+		netif_rx_complete(netdev);
+		__raw_writel(htonl(3), mgp->irq_claim);
+		return 0;
+	}
+	return 1;
+}
+
+static irqreturn_t myri10ge_intr(int irq, void *arg, struct pt_regs *regs)
+{
+	struct myri10ge_priv *mgp = arg;
+	struct mcp_irq_data *stats = mgp->fw_stats;
+	struct myri10ge_tx_buf *tx = &mgp->tx;
+	u32 send_done_count;
+	int i;
+
+	/* make sure it is our IRQ, and that the DMA has finished */
+	if (unlikely(!stats->valid))
+		return (IRQ_NONE);
+
+	/* low bit indicates receives are present, so schedule
+	 * napi poll handler */
+	if (stats->valid & 1)
+		netif_rx_schedule(mgp->dev);
+
+	if (!mgp->msi_enabled) {
+		__raw_writel(0, mgp->irq_deassert);
+		if (!myri10ge_deassert_wait)
+			stats->valid = 0;
+		mb();
+	} else
+		stats->valid = 0;
+
+	/* Wait for IRQ line to go low, if using INTx */
+	i = 0;
+	while (1) {
+		i++;
+		/* check for transmit completes and receives */
+		send_done_count = ntohl(stats->send_done_count);
+		if (send_done_count != tx->pkt_done)
+			myri10ge_tx_done(mgp, (int)send_done_count);
+		if (unlikely(i > myri10ge_max_irq_loops)) {
+			printk(KERN_WARNING "myri10ge: %s: irq stuck?\n",
+			       mgp->dev->name);
+			stats->valid = 0;
+			schedule_work(&mgp->watchdog_work);
+		}
+		if (likely(stats->valid == 0))
+			break;
+		cpu_relax();
+		barrier();
+	}
+
+	myri10ge_check_statblock(mgp);
+
+	__raw_writel(htonl(3), mgp->irq_claim + 1);
+	return (IRQ_HANDLED);
+}
+
+static int
+myri10ge_get_settings(struct net_device *netdev, struct ethtool_cmd *cmd)
+{
+	cmd->autoneg = AUTONEG_DISABLE;
+	cmd->speed = SPEED_10000;
+	cmd->duplex = DUPLEX_FULL;
+	return 0;
+}
+
+static void
+myri10ge_get_drvinfo(struct net_device *netdev, struct ethtool_drvinfo *info)
+{
+	struct myri10ge_priv *mgp = netdev_priv(netdev);
+
+	strlcpy(info->driver, "myri10ge", sizeof(info->driver));
+	strlcpy(info->version, MYRI10GE_VERSION_STR, sizeof(info->version));
+	strlcpy(info->fw_version, mgp->fw_version, sizeof(info->fw_version));
+	strlcpy(info->bus_info, pci_name(mgp->pdev), sizeof(info->bus_info));
+}
+
+static int
+myri10ge_get_coalesce(struct net_device *netdev, struct ethtool_coalesce *coal)
+{
+	struct myri10ge_priv *mgp = netdev_priv(netdev);
+	coal->rx_coalesce_usecs = mgp->intr_coal_delay;
+	return 0;
+}
+
+static int
+myri10ge_set_coalesce(struct net_device *netdev, struct ethtool_coalesce *coal)
+{
+	struct myri10ge_priv *mgp = netdev_priv(netdev);
+
+	mgp->intr_coal_delay = coal->rx_coalesce_usecs;
+	__raw_writel(htonl(mgp->intr_coal_delay), mgp->intr_coal_delay_ptr);
+	return 0;
+}
+
+static void
+myri10ge_get_pauseparam(struct net_device *netdev,
+			struct ethtool_pauseparam *pause)
+{
+	struct myri10ge_priv *mgp = netdev_priv(netdev);
+
+	pause->autoneg = 0;
+	pause->rx_pause = mgp->pause;
+	pause->tx_pause = mgp->pause;
+}
+
+static int
+myri10ge_set_pauseparam(struct net_device *netdev,
+			struct ethtool_pauseparam *pause)
+{
+	struct myri10ge_priv *mgp = netdev_priv(netdev);
+
+	if (pause->tx_pause != mgp->pause)
+		return myri10ge_change_pause(mgp, pause->tx_pause);
+	if (pause->rx_pause != mgp->pause)
+		return myri10ge_change_pause(mgp, pause->tx_pause);
+	if (pause->autoneg != 0)
+		return -EINVAL;
+	return 0;
+}
+
+static void
+myri10ge_get_ringparam(struct net_device *netdev,
+		       struct ethtool_ringparam *ring)
+{
+	struct myri10ge_priv *mgp = netdev_priv(netdev);
+
+	ring->rx_mini_max_pending = mgp->rx_small.mask + 1;
+	ring->rx_max_pending = mgp->rx_big.mask + 1;
+	ring->rx_jumbo_max_pending = 0;
+	ring->tx_max_pending = mgp->rx_small.mask + 1;
+	ring->rx_mini_pending = ring->rx_mini_max_pending;
+	ring->rx_pending = ring->rx_max_pending;
+	ring->rx_jumbo_pending = ring->rx_jumbo_max_pending;
+	ring->tx_pending = ring->tx_max_pending;
+}
+
+static u32 myri10ge_get_rx_csum(struct net_device *netdev)
+{
+	struct myri10ge_priv *mgp = netdev_priv(netdev);
+	if (mgp->csum_flag)
+		return 1;
+	else
+		return 0;
+}
+
+static int myri10ge_set_rx_csum(struct net_device *netdev, u32 csum_enabled)
+{
+	struct myri10ge_priv *mgp = netdev_priv(netdev);
+	if (csum_enabled)
+		mgp->csum_flag = MXGEFW_FLAGS_CKSUM;
+	else
+		mgp->csum_flag = 0;
+	return 0;
+}
+
+static const char myri10ge_gstrings_stats[][ETH_GSTRING_LEN] = {
+	"rx_packets", "tx_packets", "rx_bytes", "tx_bytes", "rx_errors",
+	"tx_errors", "rx_dropped", "tx_dropped", "multicast", "collisions",
+	"rx_length_errors", "rx_over_errors", "rx_crc_errors",
+	"rx_frame_errors", "rx_fifo_errors", "rx_missed_errors",
+	"tx_aborted_errors", "tx_carrier_errors", "tx_fifo_errors",
+	"tx_heartbeat_errors", "tx_window_errors",
+	/* device-specific stats */
+	"tx_boundary", "WC", "irq", "MSI",
+	"read_dma_bw_MBs", "write_dma_bw_MBs", "read_write_dma_bw_MBs",
+	"serial_number", "tx_pkt_start", "tx_pkt_done",
+	"tx_req", "tx_done", "rx_small_cnt", "rx_big_cnt",
+	"wake_queue", "stop_queue", "watchdog_resets", "tx_linearized",
+	"link_up", "dropped_link_overflow", "dropped_link_error_or_filtered",
+	"dropped_runt", "dropped_overrun", "dropped_no_small_buffer",
+	"dropped_no_big_buffer"
+};
+
+#define MYRI10GE_NET_STATS_LEN      21
+#define MYRI10GE_STATS_LEN  sizeof(myri10ge_gstrings_stats) / ETH_GSTRING_LEN
+
+static void
+myri10ge_get_strings(struct net_device *netdev, u32 stringset, u8 * data)
+{
+	switch (stringset) {
+	case ETH_SS_STATS:
+		memcpy(data, *myri10ge_gstrings_stats,
+		       sizeof(myri10ge_gstrings_stats));
+		break;
+	}
+}
+
+static int myri10ge_get_stats_count(struct net_device *netdev)
+{
+	return MYRI10GE_STATS_LEN;
+}
+
+static void
+myri10ge_get_ethtool_stats(struct net_device *netdev,
+			   struct ethtool_stats *stats, u64 * data)
+{
+	struct myri10ge_priv *mgp = netdev_priv(netdev);
+	int i;
+
+	for (i = 0; i < MYRI10GE_NET_STATS_LEN; i++)
+		data[i] = ((unsigned long *)&mgp->stats)[i];
+
+	data[i++] = (unsigned int)mgp->tx.boundary;
+	data[i++] = (unsigned int)(mgp->mtrr >= 0);
+	data[i++] = (unsigned int)mgp->pdev->irq;
+	data[i++] = (unsigned int)mgp->msi_enabled;
+	data[i++] = (unsigned int)mgp->read_dma;
+	data[i++] = (unsigned int)mgp->write_dma;
+	data[i++] = (unsigned int)mgp->read_write_dma;
+	data[i++] = (unsigned int)mgp->serial_number;
+	data[i++] = (unsigned int)mgp->tx.pkt_start;
+	data[i++] = (unsigned int)mgp->tx.pkt_done;
+	data[i++] = (unsigned int)mgp->tx.req;
+	data[i++] = (unsigned int)mgp->tx.done;
+	data[i++] = (unsigned int)mgp->rx_small.cnt;
+	data[i++] = (unsigned int)mgp->rx_big.cnt;
+	data[i++] = (unsigned int)mgp->wake_queue;
+	data[i++] = (unsigned int)mgp->stop_queue;
+	data[i++] = (unsigned int)mgp->watchdog_resets;
+	data[i++] = (unsigned int)mgp->tx_linearized;
+	data[i++] = (unsigned int)ntohl(mgp->fw_stats->link_up);
+	data[i++] = (unsigned int)ntohl(mgp->fw_stats->dropped_link_overflow);
+	data[i++] =
+	    (unsigned int)ntohl(mgp->fw_stats->dropped_link_error_or_filtered);
+	data[i++] = (unsigned int)ntohl(mgp->fw_stats->dropped_runt);
+	data[i++] = (unsigned int)ntohl(mgp->fw_stats->dropped_overrun);
+	data[i++] = (unsigned int)ntohl(mgp->fw_stats->dropped_no_small_buffer);
+	data[i++] = (unsigned int)ntohl(mgp->fw_stats->dropped_no_big_buffer);
+}
+
+static struct ethtool_ops myri10ge_ethtool_ops = {
+	.get_settings = myri10ge_get_settings,
+	.get_drvinfo = myri10ge_get_drvinfo,
+	.get_coalesce = myri10ge_get_coalesce,
+	.set_coalesce = myri10ge_set_coalesce,
+	.get_pauseparam = myri10ge_get_pauseparam,
+	.set_pauseparam = myri10ge_set_pauseparam,
+	.get_ringparam = myri10ge_get_ringparam,
+	.get_rx_csum = myri10ge_get_rx_csum,
+	.set_rx_csum = myri10ge_set_rx_csum,
+	.get_tx_csum = ethtool_op_get_tx_csum,
+	.set_tx_csum = ethtool_op_set_tx_hw_csum,
+	.get_sg = ethtool_op_get_sg,
+	.set_sg = ethtool_op_set_sg,
+#ifdef NETIF_F_TSO
+	.get_tso = ethtool_op_get_tso,
+	.set_tso = ethtool_op_set_tso,
+#endif
+	.get_strings = myri10ge_get_strings,
+	.get_stats_count = myri10ge_get_stats_count,
+	.get_ethtool_stats = myri10ge_get_ethtool_stats
+};
+
+static int myri10ge_allocate_rings(struct net_device *dev)
+{
+	struct myri10ge_priv *mgp;
+	struct myri10ge_cmd cmd;
+	int tx_ring_size, rx_ring_size;
+	int tx_ring_entries, rx_ring_entries;
+	int i, status;
+	size_t bytes;
+
+	mgp = netdev_priv(dev);
+
+	/* get ring sizes */
+
+	status = myri10ge_send_cmd(mgp, MXGEFW_CMD_GET_SEND_RING_SIZE, &cmd, 0);
+	tx_ring_size = cmd.data0;
+	status |= myri10ge_send_cmd(mgp, MXGEFW_CMD_GET_RX_RING_SIZE, &cmd, 0);
+	rx_ring_size = cmd.data0;
+
+	tx_ring_entries = tx_ring_size / sizeof(struct mcp_kreq_ether_send);
+	rx_ring_entries = rx_ring_size / sizeof(struct mcp_dma_addr);
+	mgp->tx.mask = tx_ring_entries - 1;
+	mgp->rx_small.mask = mgp->rx_big.mask = rx_ring_entries - 1;
+
+	/* allocate the host shadow rings */
+
+	bytes = 8 + (MYRI10GE_MAX_SEND_DESC_TSO + 4)
+	    * sizeof(*mgp->tx.req_list);
+	mgp->tx.req_bytes = kzalloc(bytes, GFP_KERNEL);
+	if (mgp->tx.req_bytes == NULL)
+		goto abort_with_nothing;
+
+	/* ensure req_list entries are aligned to 8 bytes */
+	mgp->tx.req_list = (struct mcp_kreq_ether_send *)
+	    ALIGN((unsigned long)mgp->tx.req_bytes, 8);
+
+	bytes = rx_ring_entries * sizeof(*mgp->rx_small.shadow);
+	mgp->rx_small.shadow = kzalloc(bytes, GFP_KERNEL);
+	if (mgp->rx_small.shadow == NULL)
+		goto abort_with_tx_req_bytes;
+
+	bytes = rx_ring_entries * sizeof(*mgp->rx_big.shadow);
+	mgp->rx_big.shadow = kzalloc(bytes, GFP_KERNEL);
+	if (mgp->rx_big.shadow == NULL)
+		goto abort_with_rx_small_shadow;
+
+	/* allocate the host info rings */
+
+	bytes = tx_ring_entries * sizeof(*mgp->tx.info);
+	mgp->tx.info = kzalloc(bytes, GFP_KERNEL);
+	if (mgp->tx.info == NULL)
+		goto abort_with_rx_big_shadow;
+
+	bytes = rx_ring_entries * sizeof(*mgp->rx_small.info);
+	mgp->rx_small.info = kzalloc(bytes, GFP_KERNEL);
+	if (mgp->rx_small.info == NULL)
+		goto abort_with_tx_info;
+
+	bytes = rx_ring_entries * sizeof(*mgp->rx_big.info);
+	mgp->rx_big.info = kzalloc(bytes, GFP_KERNEL);
+	if (mgp->rx_big.info == NULL)
+		goto abort_with_rx_small_info;
+
+	/* Fill the receive rings */
+
+	for (i = 0; i <= mgp->rx_small.mask; i++) {
+		status = myri10ge_getbuf(&mgp->rx_small, mgp->pdev,
+					 mgp->small_bytes, i);
+		if (status) {
+			printk(KERN_ERR
+			       "myri10ge: %s: alloced only %d small bufs\n",
+			       dev->name, i);
+			goto abort_with_rx_small_ring;
+		}
+	}
+
+	for (i = 0; i <= mgp->rx_big.mask; i++) {
+		status =
+		    myri10ge_getbuf(&mgp->rx_big, mgp->pdev,
+				    dev->mtu + ETH_HLEN, i);
+		if (status) {
+			printk(KERN_ERR
+			       "myri10ge: %s: alloced only %d big bufs\n",
+			       dev->name, i);
+			goto abort_with_rx_big_ring;
+		}
+	}
+
+	return 0;
+
+abort_with_rx_big_ring:
+	for (i = 0; i <= mgp->rx_big.mask; i++) {
+		if (mgp->rx_big.info[i].skb != NULL)
+			dev_kfree_skb_any(mgp->rx_big.info[i].skb);
+		if (pci_unmap_len(&mgp->rx_big.info[i], len))
+			pci_unmap_single(mgp->pdev,
+					 pci_unmap_addr(&mgp->rx_big.info[i],
+							bus),
+					 pci_unmap_len(&mgp->rx_big.info[i],
+						       len),
+					 PCI_DMA_FROMDEVICE);
+	}
+
+abort_with_rx_small_ring:
+	for (i = 0; i <= mgp->rx_small.mask; i++) {
+		if (mgp->rx_small.info[i].skb != NULL)
+			dev_kfree_skb_any(mgp->rx_small.info[i].skb);
+		if (pci_unmap_len(&mgp->rx_small.info[i], len))
+			pci_unmap_single(mgp->pdev,
+					 pci_unmap_addr(&mgp->rx_small.info[i],
+							bus),
+					 pci_unmap_len(&mgp->rx_small.info[i],
+						       len),
+					 PCI_DMA_FROMDEVICE);
+	}
+	kfree(mgp->rx_big.info);
+
+abort_with_rx_small_info:
+	kfree(mgp->rx_small.info);
+
+abort_with_tx_info:
+	kfree(mgp->tx.info);
+
+abort_with_rx_big_shadow:
+	kfree(mgp->rx_big.shadow);
+
+abort_with_rx_small_shadow:
+	kfree(mgp->rx_small.shadow);
+
+abort_with_tx_req_bytes:
+	kfree(mgp->tx.req_bytes);
+	mgp->tx.req_bytes = NULL;
+	mgp->tx.req_list = NULL;
+
+abort_with_nothing:
+	return status;
+}
+
+static void myri10ge_free_rings(struct net_device *dev)
+{
+	struct myri10ge_priv *mgp;
+	struct sk_buff *skb;
+	struct myri10ge_tx_buf *tx;
+	int i, len, idx;
+
+	mgp = netdev_priv(dev);
+
+	for (i = 0; i <= mgp->rx_big.mask; i++) {
+		if (mgp->rx_big.info[i].skb != NULL)
+			dev_kfree_skb_any(mgp->rx_big.info[i].skb);
+		if (pci_unmap_len(&mgp->rx_big.info[i], len))
+			pci_unmap_single(mgp->pdev,
+					 pci_unmap_addr(&mgp->rx_big.info[i],
+							bus),
+					 pci_unmap_len(&mgp->rx_big.info[i],
+						       len),
+					 PCI_DMA_FROMDEVICE);
+	}
+
+	for (i = 0; i <= mgp->rx_small.mask; i++) {
+		if (mgp->rx_small.info[i].skb != NULL)
+			dev_kfree_skb_any(mgp->rx_small.info[i].skb);
+		if (pci_unmap_len(&mgp->rx_small.info[i], len))
+			pci_unmap_single(mgp->pdev,
+					 pci_unmap_addr(&mgp->rx_small.info[i],
+							bus),
+					 pci_unmap_len(&mgp->rx_small.info[i],
+						       len),
+					 PCI_DMA_FROMDEVICE);
+	}
+
+	tx = &mgp->tx;
+	while (tx->done != tx->req) {
+		idx = tx->done & tx->mask;
+		skb = tx->info[idx].skb;
+
+		/* Mark as free */
+		tx->info[idx].skb = NULL;
+		tx->done++;
+		len = pci_unmap_len(&tx->info[idx], len);
+		pci_unmap_len_set(&tx->info[idx], len, 0);
+		if (skb) {
+			mgp->stats.tx_dropped++;
+			dev_kfree_skb_any(skb);
+			if (len)
+				pci_unmap_single(mgp->pdev,
+						 pci_unmap_addr(&tx->info[idx],
+								bus), len,
+						 PCI_DMA_TODEVICE);
+		} else {
+			if (len)
+				pci_unmap_page(mgp->pdev,
+					       pci_unmap_addr(&tx->info[idx],
+							      bus), len,
+					       PCI_DMA_TODEVICE);
+		}
+	}
+	kfree(mgp->rx_big.info);
+
+	kfree(mgp->rx_small.info);
+
+	kfree(mgp->tx.info);
+
+	kfree(mgp->rx_big.shadow);
+
+	kfree(mgp->rx_small.shadow);
+
+	kfree(mgp->tx.req_bytes);
+	mgp->tx.req_bytes = NULL;
+	mgp->tx.req_list = NULL;
+}
+
+static int myri10ge_open(struct net_device *dev)
+{
+	struct myri10ge_priv *mgp;
+	struct myri10ge_cmd cmd;
+	int status, big_pow2;
+
+	mgp = netdev_priv(dev);
+
+	if (mgp->running != MYRI10GE_ETH_STOPPED)
+		return -EBUSY;
+
+	mgp->running = MYRI10GE_ETH_STARTING;
+	status = myri10ge_reset(mgp);
+	if (status != 0) {
+		printk(KERN_ERR "myri10ge: %s: failed reset\n", dev->name);
+		mgp->running = MYRI10GE_ETH_STOPPED;
+		return -ENXIO;
+	}
+
+	/* decide what small buffer size to use.  For good TCP rx
+	 * performance, it is important to not receive 1514 byte
+	 * frames into jumbo buffers, as it confuses the socket buffer
+	 * accounting code, leading to drops and erratic performance.
+	 */
+
+	if (dev->mtu <= ETH_DATA_LEN)
+		mgp->small_bytes = 128;	/* enough for a TCP header */
+	else
+		mgp->small_bytes = ETH_FRAME_LEN;	/* enough for an ETH_DATA_LEN frame */
+
+	/* Override the small buffer size? */
+	if (myri10ge_small_bytes > 0)
+		mgp->small_bytes = myri10ge_small_bytes;
+
+	/* If the user sets an obscenely small MTU, adjust the small
+	 * bytes down to nearly nothing */
+	if (mgp->small_bytes >= (dev->mtu + ETH_HLEN))
+		mgp->small_bytes = 64;
+
+	/* get the lanai pointers to the send and receive rings */
+
+	status |= myri10ge_send_cmd(mgp, MXGEFW_CMD_GET_SEND_OFFSET, &cmd, 0);
+	mgp->tx.lanai =
+	    (struct mcp_kreq_ether_send __iomem *)(mgp->sram + cmd.data0);
+
+	status |=
+	    myri10ge_send_cmd(mgp, MXGEFW_CMD_GET_SMALL_RX_OFFSET, &cmd, 0);
+	mgp->rx_small.lanai =
+	    (struct mcp_kreq_ether_recv __iomem *)(mgp->sram + cmd.data0);
+
+	status |= myri10ge_send_cmd(mgp, MXGEFW_CMD_GET_BIG_RX_OFFSET, &cmd, 0);
+	mgp->rx_big.lanai =
+	    (struct mcp_kreq_ether_recv __iomem *)(mgp->sram + cmd.data0);
+
+	if (status != 0) {
+		printk(KERN_ERR
+		       "myri10ge: %s: failed to get ring sizes or locations\n",
+		       dev->name);
+		mgp->running = MYRI10GE_ETH_STOPPED;
+		return -ENXIO;
+	}
+
+	if (mgp->mtrr >= 0) {
+		mgp->tx.wc_fifo = (u8 __iomem *) mgp->sram + 0x200000;
+		mgp->rx_small.wc_fifo = (u8 __iomem *) mgp->sram + 0x300000;
+		mgp->rx_big.wc_fifo = (u8 __iomem *) mgp->sram + 0x340000;
+	} else {
+		mgp->tx.wc_fifo = NULL;
+		mgp->rx_small.wc_fifo = NULL;
+		mgp->rx_big.wc_fifo = NULL;
+	}
+
+	status = myri10ge_allocate_rings(dev);
+	if (status != 0)
+		goto abort_with_nothing;
+
+	/* Firmware needs the big buff size as a power of 2.  Lie and
+	 * tell him the buffer is larger, because we only use 1
+	 * buffer/pkt, and the mtu will prevent overruns.
+	 */
+	big_pow2 = dev->mtu + ETH_HLEN + MXGEFW_PAD;
+	while ((big_pow2 & (big_pow2 - 1)) != 0)
+		big_pow2++;
+
+	/* now give firmware buffers sizes, and MTU */
+	cmd.data0 = dev->mtu + ETH_HLEN + VLAN_HLEN;
+	status = myri10ge_send_cmd(mgp, MXGEFW_CMD_SET_MTU, &cmd, 0);
+	cmd.data0 = mgp->small_bytes;
+	status |=
+	    myri10ge_send_cmd(mgp, MXGEFW_CMD_SET_SMALL_BUFFER_SIZE, &cmd, 0);
+	cmd.data0 = big_pow2;
+	status |=
+	    myri10ge_send_cmd(mgp, MXGEFW_CMD_SET_BIG_BUFFER_SIZE, &cmd, 0);
+	if (status) {
+		printk(KERN_ERR "myri10ge: %s: Couldn't set buffer sizes\n",
+		       dev->name);
+		goto abort_with_rings;
+	}
+
+	cmd.data0 = MYRI10GE_LOWPART_TO_U32(mgp->fw_stats_bus);
+	cmd.data1 = MYRI10GE_HIGHPART_TO_U32(mgp->fw_stats_bus);
+	status = myri10ge_send_cmd(mgp, MXGEFW_CMD_SET_STATS_DMA, &cmd, 0);
+	if (status) {
+		printk(KERN_ERR "myri10ge: %s: Couldn't set stats DMA\n",
+		       dev->name);
+		goto abort_with_rings;
+	}
+
+	mgp->link_state = -1;
+	mgp->rdma_tags_available = 15;
+
+	netif_poll_enable(mgp->dev);	/* must happen prior to any irq */
+
+	status = myri10ge_send_cmd(mgp, MXGEFW_CMD_ETHERNET_UP, &cmd, 0);
+	if (status) {
+		printk(KERN_ERR "myri10ge: %s: Couldn't bring up link\n",
+		       dev->name);
+		goto abort_with_rings;
+	}
+
+	mgp->wake_queue = 0;
+	mgp->stop_queue = 0;
+	mgp->running = MYRI10GE_ETH_RUNNING;
+	mgp->watchdog_timer.expires = jiffies + myri10ge_watchdog_timeout * HZ;
+	add_timer(&mgp->watchdog_timer);
+	netif_wake_queue(dev);
+	return 0;
+
+abort_with_rings:
+	myri10ge_free_rings(dev);
+
+abort_with_nothing:
+	mgp->running = MYRI10GE_ETH_STOPPED;
+	return -ENOMEM;
+}
+
+static int myri10ge_close(struct net_device *dev)
+{
+	struct myri10ge_priv *mgp;
+	struct myri10ge_cmd cmd;
+	int status, old_down_cnt;
+
+	mgp = netdev_priv(dev);
+
+	if (mgp->running != MYRI10GE_ETH_RUNNING)
+		return 0;
+
+	if (mgp->tx.req_bytes == NULL)
+		return 0;
+
+	del_timer_sync(&mgp->watchdog_timer);
+	mgp->running = MYRI10GE_ETH_STOPPING;
+	netif_poll_disable(mgp->dev);
+	netif_carrier_off(dev);
+	netif_stop_queue(dev);
+	old_down_cnt = mgp->down_cnt;
+	mb();
+	status = myri10ge_send_cmd(mgp, MXGEFW_CMD_ETHERNET_DOWN, &cmd, 0);
+	if (status)
+		printk(KERN_ERR "myri10ge: %s: Couldn't bring down link\n",
+		       dev->name);
+
+	wait_event_timeout(mgp->down_wq, old_down_cnt != mgp->down_cnt, HZ);
+	if (old_down_cnt == mgp->down_cnt)
+		printk(KERN_ERR "myri10ge: %s never got down irq\n", dev->name);
+
+	netif_tx_disable(dev);
+
+	myri10ge_free_rings(dev);
+
+	mgp->running = MYRI10GE_ETH_STOPPED;
+	return 0;
+}
+
+/* copy an array of struct mcp_kreq_ether_send's to the mcp.  Copy
+ * backwards one at a time and handle ring wraps */
+
+static inline void
+myri10ge_submit_req_backwards(struct myri10ge_tx_buf *tx,
+			      struct mcp_kreq_ether_send *src, int cnt)
+{
+	int idx, starting_slot;
+	starting_slot = tx->req;
+	while (cnt > 1) {
+		cnt--;
+		idx = (starting_slot + cnt) & tx->mask;
+		myri10ge_pio_copy(&tx->lanai[idx], &src[cnt], sizeof(*src));
+		mb();
+	}
+}
+
+/*
+ * copy an array of struct mcp_kreq_ether_send's to the mcp.  Copy
+ * at most 32 bytes at a time, so as to avoid involving the software
+ * pio handler in the nic.   We re-write the first segment's flags
+ * to mark them valid only after writing the entire chain.
+ */
+
+static inline void
+myri10ge_submit_req(struct myri10ge_tx_buf *tx, struct mcp_kreq_ether_send *src,
+		    int cnt)
+{
+	int idx, i;
+	struct mcp_kreq_ether_send __iomem *dstp, *dst;
+	struct mcp_kreq_ether_send *srcp;
+	u8 last_flags;
+
+	idx = tx->req & tx->mask;
+
+	last_flags = src->flags;
+	src->flags = 0;
+	mb();
+	dst = dstp = &tx->lanai[idx];
+	srcp = src;
+
+	if ((idx + cnt) < tx->mask) {
+		for (i = 0; i < (cnt - 1); i += 2) {
+			myri10ge_pio_copy(dstp, srcp, 2 * sizeof(*src));
+			mb();	/* force write every 32 bytes */
+			srcp += 2;
+			dstp += 2;
+		}
+	} else {
+		/* submit all but the first request, and ensure
+		 * that it is submitted below */
+		myri10ge_submit_req_backwards(tx, src, cnt);
+		i = 0;
+	}
+	if (i < cnt) {
+		/* submit the first request */
+		myri10ge_pio_copy(dstp, srcp, sizeof(*src));
+		mb();		/* barrier before setting valid flag */
+	}
+
+	/* re-write the last 32-bits with the valid flags */
+	src->flags = last_flags;
+	__raw_writel(*((u32 *) src + 3), (u32 __iomem *) dst + 3);
+	tx->req += cnt;
+	mb();
+}
+
+static inline void
+myri10ge_submit_req_wc(struct myri10ge_tx_buf *tx,
+		       struct mcp_kreq_ether_send *src, int cnt)
+{
+	tx->req += cnt;
+	mb();
+	while (cnt >= 4) {
+		myri10ge_pio_copy(tx->wc_fifo, src, 64);
+		mb();
+		src += 4;
+		cnt -= 4;
+	}
+	if (cnt > 0) {
+		/* pad it to 64 bytes.  The src is 64 bytes bigger than it
+		 * needs to be so that we don't overrun it */
+		myri10ge_pio_copy(tx->wc_fifo + (cnt << 18), src, 64);
+		mb();
+	}
+}
+
+/*
+ * Transmit a packet.  We need to split the packet so that a single
+ * segment does not cross myri10ge->tx.boundary, so this makes segment
+ * counting tricky.  So rather than try to count segments up front, we
+ * just give up if there are too few segments to hold a reasonably
+ * fragmented packet currently available.  If we run
+ * out of segments while preparing a packet for DMA, we just linearize
+ * it and try again.
+ */
+
+static int myri10ge_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+	struct myri10ge_priv *mgp = netdev_priv(dev);
+	struct mcp_kreq_ether_send *req;
+	struct myri10ge_tx_buf *tx = &mgp->tx;
+	struct skb_frag_struct *frag;
+	dma_addr_t bus;
+	u32 low, high_swapped;
+	unsigned int len;
+	int idx, last_idx, avail, frag_cnt, frag_idx, count, mss, max_segments;
+	u16 pseudo_hdr_offset, cksum_offset;
+	int cum_len, seglen, boundary, rdma_count;
+	u8 flags, odd_flag;
+
+again:
+	req = tx->req_list;
+	avail = tx->mask - 1 - (tx->req - tx->done);
+
+	mss = 0;
+	max_segments = MXGEFW_MAX_SEND_DESC;
+
+#ifdef NETIF_F_TSO
+	if (skb->len > (dev->mtu + ETH_HLEN)) {
+		mss = skb_shinfo(skb)->gso_size;
+		if (mss != 0)
+			max_segments = MYRI10GE_MAX_SEND_DESC_TSO;
+	}
+#endif				/*NETIF_F_TSO */
+
+	if ((unlikely(avail < max_segments))) {
+		/* we are out of transmit resources */
+		mgp->stop_queue++;
+		netif_stop_queue(dev);
+		return 1;
+	}
+
+	/* Setup checksum offloading, if needed */
+	cksum_offset = 0;
+	pseudo_hdr_offset = 0;
+	odd_flag = 0;
+	flags = (MXGEFW_FLAGS_NO_TSO | MXGEFW_FLAGS_FIRST);
+	if (likely(skb->ip_summed == CHECKSUM_HW)) {
+		cksum_offset = (skb->h.raw - skb->data);
+		pseudo_hdr_offset = (skb->h.raw + skb->csum) - skb->data;
+		/* If the headers are excessively large, then we must
+		 * fall back to a software checksum */
+		if (unlikely(cksum_offset > 255 || pseudo_hdr_offset > 127)) {
+			if (skb_checksum_help(skb, 0))
+				goto drop;
+			cksum_offset = 0;
+			pseudo_hdr_offset = 0;
+		} else {
+			pseudo_hdr_offset = htons(pseudo_hdr_offset);
+			odd_flag = MXGEFW_FLAGS_ALIGN_ODD;
+			flags |= MXGEFW_FLAGS_CKSUM;
+		}
+	}
+
+	cum_len = 0;
+
+#ifdef NETIF_F_TSO
+	if (mss) {		/* TSO */
+		/* this removes any CKSUM flag from before */
+		flags = (MXGEFW_FLAGS_TSO_HDR | MXGEFW_FLAGS_FIRST);
+
+		/* negative cum_len signifies to the
+		 * send loop that we are still in the
+		 * header portion of the TSO packet.
+		 * TSO header must be at most 134 bytes long */
+		cum_len = -((skb->h.raw - skb->data) + (skb->h.th->doff << 2));
+
+		/* for TSO, pseudo_hdr_offset holds mss.
+		 * The firmware figures out where to put
+		 * the checksum by parsing the header. */
+		pseudo_hdr_offset = htons(mss);
+	} else
+#endif				/*NETIF_F_TSO */
+		/* Mark small packets, and pad out tiny packets */
+	if (skb->len <= MXGEFW_SEND_SMALL_SIZE) {
+		flags |= MXGEFW_FLAGS_SMALL;
+
+		/* pad frames to at least ETH_ZLEN bytes */
+		if (unlikely(skb->len < ETH_ZLEN)) {
+			if (skb_padto(skb, ETH_ZLEN)) {
+				/* The packet is gone, so we must
+				 * return 0 */
+				mgp->stats.tx_dropped += 1;
+				return 0;
+			}
+			/* adjust the len to account for the zero pad
+			 * so that the nic can know how long it is */
+			skb->len = ETH_ZLEN;
+		}
+	}
+
+	/* map the skb for DMA */
+	len = skb->len - skb->data_len;
+	idx = tx->req & tx->mask;
+	tx->info[idx].skb = skb;
+	bus = pci_map_single(mgp->pdev, skb->data, len, PCI_DMA_TODEVICE);
+	pci_unmap_addr_set(&tx->info[idx], bus, bus);
+	pci_unmap_len_set(&tx->info[idx], len, len);
+
+	frag_cnt = skb_shinfo(skb)->nr_frags;
+	frag_idx = 0;
+	count = 0;
+	rdma_count = 0;
+
+	/* "rdma_count" is the number of RDMAs belonging to the
+	 * current packet BEFORE the current send request. For
+	 * non-TSO packets, this is equal to "count".
+	 * For TSO packets, rdma_count needs to be reset
+	 * to 0 after a segment cut.
+	 *
+	 * The rdma_count field of the send request is
+	 * the number of RDMAs of the packet starting at
+	 * that request. For TSO send requests with one ore more cuts
+	 * in the middle, this is the number of RDMAs starting
+	 * after the last cut in the request. All previous
+	 * segments before the last cut implicitly have 1 RDMA.
+	 *
+	 * Since the number of RDMAs is not known beforehand,
+	 * it must be filled-in retroactively - after each
+	 * segmentation cut or at the end of the entire packet.
+	 */
+
+	while (1) {
+		/* Break the SKB or Fragment up into pieces which
+		 * do not cross mgp->tx.boundary */
+		low = MYRI10GE_LOWPART_TO_U32(bus);
+		high_swapped = htonl(MYRI10GE_HIGHPART_TO_U32(bus));
+		while (len) {
+			u8 flags_next;
+			int cum_len_next;
+
+			if (unlikely(count == max_segments))
+				goto abort_linearize;
+
+			boundary = (low + tx->boundary) & ~(tx->boundary - 1);
+			seglen = boundary - low;
+			if (seglen > len)
+				seglen = len;
+			flags_next = flags & ~MXGEFW_FLAGS_FIRST;
+			cum_len_next = cum_len + seglen;
+#ifdef NETIF_F_TSO
+			if (mss) {	/* TSO */
+				(req - rdma_count)->rdma_count = rdma_count + 1;
+
+				if (likely(cum_len >= 0)) {	/* payload */
+					int next_is_first, chop;
+
+					chop = (cum_len_next > mss);
+					cum_len_next = cum_len_next % mss;
+					next_is_first = (cum_len_next == 0);
+					flags |= chop * MXGEFW_FLAGS_TSO_CHOP;
+					flags_next |= next_is_first *
+					    MXGEFW_FLAGS_FIRST;
+					rdma_count |= -(chop | next_is_first);
+					rdma_count += chop & !next_is_first;
+				} else if (likely(cum_len_next >= 0)) {	/* header ends */
+					int small;
+
+					rdma_count = -1;
+					cum_len_next = 0;
+					seglen = -cum_len;
+					small = (mss <= MXGEFW_SEND_SMALL_SIZE);
+					flags_next = MXGEFW_FLAGS_TSO_PLD |
+					    MXGEFW_FLAGS_FIRST |
+					    (small * MXGEFW_FLAGS_SMALL);
+				}
+			}
+#endif				/* NETIF_F_TSO */
+			req->addr_high = high_swapped;
+			req->addr_low = htonl(low);
+			req->pseudo_hdr_offset = pseudo_hdr_offset;
+			req->pad = 0;	/* complete solid 16-byte block; does this matter? */
+			req->rdma_count = 1;
+			req->length = htons(seglen);
+			req->cksum_offset = cksum_offset;
+			req->flags = flags | ((cum_len & 1) * odd_flag);
+
+			low += seglen;
+			len -= seglen;
+			cum_len = cum_len_next;
+			flags = flags_next;
+			req++;
+			count++;
+			rdma_count++;
+			if (unlikely(cksum_offset > seglen))
+				cksum_offset -= seglen;
+			else
+				cksum_offset = 0;
+		}
+		if (frag_idx == frag_cnt)
+			break;
+
+		/* map next fragment for DMA */
+		idx = (count + tx->req) & tx->mask;
+		frag = &skb_shinfo(skb)->frags[frag_idx];
+		frag_idx++;
+		len = frag->size;
+		bus = pci_map_page(mgp->pdev, frag->page, frag->page_offset,
+				   len, PCI_DMA_TODEVICE);
+		pci_unmap_addr_set(&tx->info[idx], bus, bus);
+		pci_unmap_len_set(&tx->info[idx], len, len);
+	}
+
+	(req - rdma_count)->rdma_count = rdma_count;
+#ifdef NETIF_F_TSO
+	if (mss)
+		do {
+			req--;
+			req->flags |= MXGEFW_FLAGS_TSO_LAST;
+		} while (!(req->flags & (MXGEFW_FLAGS_TSO_CHOP |
+					 MXGEFW_FLAGS_FIRST)));
+#endif
+	idx = ((count - 1) + tx->req) & tx->mask;
+	tx->info[idx].last = 1;
+	if (tx->wc_fifo == NULL)
+		myri10ge_submit_req(tx, tx->req_list, count);
+	else
+		myri10ge_submit_req_wc(tx, tx->req_list, count);
+	tx->pkt_start++;
+	if ((avail - count) < MXGEFW_MAX_SEND_DESC) {
+		mgp->stop_queue++;
+		netif_stop_queue(dev);
+	}
+	dev->trans_start = jiffies;
+	return 0;
+
+abort_linearize:
+	/* Free any DMA resources we've alloced and clear out the skb
+	 * slot so as to not trip up assertions, and to avoid a
+	 * double-free if linearizing fails */
+
+	last_idx = (idx + 1) & tx->mask;
+	idx = tx->req & tx->mask;
+	tx->info[idx].skb = NULL;
+	do {
+		len = pci_unmap_len(&tx->info[idx], len);
+		if (len) {
+			if (tx->info[idx].skb != NULL)
+				pci_unmap_single(mgp->pdev,
+						 pci_unmap_addr(&tx->info[idx],
+								bus), len,
+						 PCI_DMA_TODEVICE);
+			else
+				pci_unmap_page(mgp->pdev,
+					       pci_unmap_addr(&tx->info[idx],
+							      bus), len,
+					       PCI_DMA_TODEVICE);
+			pci_unmap_len_set(&tx->info[idx], len, 0);
+			tx->info[idx].skb = NULL;
+		}
+		idx = (idx + 1) & tx->mask;
+	} while (idx != last_idx);
+	if (skb_is_gso(skb)) {
+		printk(KERN_ERR
+		       "myri10ge: %s: TSO but wanted to linearize?!?!?\n",
+		       mgp->dev->name);
+		goto drop;
+	}
+
+	if (skb_linearize(skb))
+		goto drop;
+
+	mgp->tx_linearized++;
+	goto again;
+
+drop:
+	dev_kfree_skb_any(skb);
+	mgp->stats.tx_dropped += 1;
+	return 0;
+
+}
+
+static struct net_device_stats *myri10ge_get_stats(struct net_device *dev)
+{
+	struct myri10ge_priv *mgp = netdev_priv(dev);
+	return &mgp->stats;
+}
+
+static void myri10ge_set_multicast_list(struct net_device *dev)
+{
+	/* can be called from atomic contexts,
+	 * pass 1 to force atomicity in myri10ge_send_cmd() */
+	myri10ge_change_promisc(netdev_priv(dev), dev->flags & IFF_PROMISC, 1);
+}
+
+static int myri10ge_set_mac_address(struct net_device *dev, void *addr)
+{
+	struct sockaddr *sa = addr;
+	struct myri10ge_priv *mgp = netdev_priv(dev);
+	int status;
+
+	if (!is_valid_ether_addr(sa->sa_data))
+		return -EADDRNOTAVAIL;
+
+	status = myri10ge_update_mac_address(mgp, sa->sa_data);
+	if (status != 0) {
+		printk(KERN_ERR
+		       "myri10ge: %s: changing mac address failed with %d\n",
+		       dev->name, status);
+		return status;
+	}
+
+	/* change the dev structure */
+	memcpy(dev->dev_addr, sa->sa_data, 6);
+	return 0;
+}
+
+static int myri10ge_change_mtu(struct net_device *dev, int new_mtu)
+{
+	struct myri10ge_priv *mgp = netdev_priv(dev);
+	int error = 0;
+
+	if ((new_mtu < 68) || (ETH_HLEN + new_mtu > MYRI10GE_MAX_ETHER_MTU)) {
+		printk(KERN_ERR "myri10ge: %s: new mtu (%d) is not valid\n",
+		       dev->name, new_mtu);
+		return -EINVAL;
+	}
+	printk(KERN_INFO "%s: changing mtu from %d to %d\n",
+	       dev->name, dev->mtu, new_mtu);
+	if (mgp->running) {
+		/* if we change the mtu on an active device, we must
+		 * reset the device so the firmware sees the change */
+		myri10ge_close(dev);
+		dev->mtu = new_mtu;
+		myri10ge_open(dev);
+	} else
+		dev->mtu = new_mtu;
+
+	return error;
+}
+
+/*
+ * Enable ECRC to align PCI-E Completion packets on an 8-byte boundary.
+ * Only do it if the bridge is a root port since we don't want to disturb
+ * any other device, except if forced with myri10ge_ecrc_enable > 1.
+ */
+
+static void myri10ge_enable_ecrc(struct myri10ge_priv *mgp)
+{
+	struct pci_dev *bridge = mgp->pdev->bus->self;
+	struct device *dev = &mgp->pdev->dev;
+	unsigned cap;
+	unsigned err_cap;
+	u16 val;
+	u8 ext_type;
+	int ret;
+
+	if (!myri10ge_ecrc_enable || !bridge)
+		return;
+
+	/* check that the bridge is a root port */
+	cap = pci_find_capability(bridge, PCI_CAP_ID_EXP);
+	pci_read_config_word(bridge, cap + PCI_CAP_FLAGS, &val);
+	ext_type = (val & PCI_EXP_FLAGS_TYPE) >> 4;
+	if (ext_type != PCI_EXP_TYPE_ROOT_PORT) {
+		if (myri10ge_ecrc_enable > 1) {
+			struct pci_dev *old_bridge = bridge;
+
+			/* Walk the hierarchy up to the root port
+			 * where ECRC has to be enabled */
+			do {
+				bridge = bridge->bus->self;
+				if (!bridge) {
+					dev_err(dev,
+						"Failed to find root port"
+						" to force ECRC\n");
+					return;
+				}
+				cap =
+				    pci_find_capability(bridge, PCI_CAP_ID_EXP);
+				pci_read_config_word(bridge,
+						     cap + PCI_CAP_FLAGS, &val);
+				ext_type = (val & PCI_EXP_FLAGS_TYPE) >> 4;
+			} while (ext_type != PCI_EXP_TYPE_ROOT_PORT);
+
+			dev_info(dev,
+				 "Forcing ECRC on non-root port %s"
+				 " (enabling on root port %s)\n",
+				 pci_name(old_bridge), pci_name(bridge));
+		} else {
+			dev_err(dev,
+				"Not enabling ECRC on non-root port %s\n",
+				pci_name(bridge));
+			return;
+		}
+	}
+
+	cap = pci_find_ext_capability(bridge, PCI_EXT_CAP_ID_ERR);
+	if (!cap)
+		return;
+
+	ret = pci_read_config_dword(bridge, cap + PCI_ERR_CAP, &err_cap);
+	if (ret) {
+		dev_err(dev, "failed reading ext-conf-space of %s\n",
+			pci_name(bridge));
+		dev_err(dev, "\t pci=nommconf in use? "
+			"or buggy/incomplete/absent ACPI MCFG attr?\n");
+		return;
+	}
+	if (!(err_cap & PCI_ERR_CAP_ECRC_GENC))
+		return;
+
+	err_cap |= PCI_ERR_CAP_ECRC_GENE;
+	pci_write_config_dword(bridge, cap + PCI_ERR_CAP, err_cap);
+	dev_info(dev, "Enabled ECRC on upstream bridge %s\n", pci_name(bridge));
+	mgp->tx.boundary = 4096;
+	mgp->fw_name = myri10ge_fw_aligned;
+}
+
+/*
+ * The Lanai Z8E PCI-E interface achieves higher Read-DMA throughput
+ * when the PCI-E Completion packets are aligned on an 8-byte
+ * boundary.  Some PCI-E chip sets always align Completion packets; on
+ * the ones that do not, the alignment can be enforced by enabling
+ * ECRC generation (if supported).
+ *
+ * When PCI-E Completion packets are not aligned, it is actually more
+ * efficient to limit Read-DMA transactions to 2KB, rather than 4KB.
+ *
+ * If the driver can neither enable ECRC nor verify that it has
+ * already been enabled, then it must use a firmware image which works
+ * around unaligned completion packets (myri10ge_ethp_z8e.dat), and it
+ * should also ensure that it never gives the device a Read-DMA which is
+ * larger than 2KB by setting the tx.boundary to 2KB.  If ECRC is
+ * enabled, then the driver should use the aligned (myri10ge_eth_z8e.dat)
+ * firmware image, and set tx.boundary to 4KB.
+ */
+
+#define PCI_DEVICE_ID_SERVERWORKS_HT2000_PCIE	0x0132
+
+static void myri10ge_select_firmware(struct myri10ge_priv *mgp)
+{
+	struct pci_dev *bridge = mgp->pdev->bus->self;
+
+	mgp->tx.boundary = 2048;
+	mgp->fw_name = myri10ge_fw_unaligned;
+
+	if (myri10ge_force_firmware == 0) {
+		myri10ge_enable_ecrc(mgp);
+
+		/* Check to see if the upstream bridge is known to
+		 * provide aligned completions */
+		if (bridge
+		    /* ServerWorks HT2000/HT1000 */
+		    && bridge->vendor == PCI_VENDOR_ID_SERVERWORKS
+		    && bridge->device ==
+		    PCI_DEVICE_ID_SERVERWORKS_HT2000_PCIE) {
+			dev_info(&mgp->pdev->dev,
+				 "Assuming aligned completions (0x%x:0x%x)\n",
+				 bridge->vendor, bridge->device);
+			mgp->tx.boundary = 4096;
+			mgp->fw_name = myri10ge_fw_aligned;
+		}
+	} else {
+		if (myri10ge_force_firmware == 1) {
+			dev_info(&mgp->pdev->dev,
+				 "Assuming aligned completions (forced)\n");
+			mgp->tx.boundary = 4096;
+			mgp->fw_name = myri10ge_fw_aligned;
+		} else {
+			dev_info(&mgp->pdev->dev,
+				 "Assuming unaligned completions (forced)\n");
+			mgp->tx.boundary = 2048;
+			mgp->fw_name = myri10ge_fw_unaligned;
+		}
+	}
+	if (myri10ge_fw_name != NULL) {
+		dev_info(&mgp->pdev->dev, "overriding firmware to %s\n",
+			 myri10ge_fw_name);
+		mgp->fw_name = myri10ge_fw_name;
+	}
+}
+
+static void myri10ge_save_state(struct myri10ge_priv *mgp)
+{
+	struct pci_dev *pdev = mgp->pdev;
+	int cap;
+
+	pci_save_state(pdev);
+	/* now save PCIe and MSI state that Linux will not
+	 * save for us */
+	cap = pci_find_capability(pdev, PCI_CAP_ID_EXP);
+	pci_read_config_dword(pdev, cap + PCI_EXP_DEVCTL, &mgp->devctl);
+	cap = pci_find_capability(pdev, PCI_CAP_ID_MSI);
+	pci_read_config_word(pdev, cap + PCI_MSI_FLAGS, &mgp->msi_flags);
+}
+
+static void myri10ge_restore_state(struct myri10ge_priv *mgp)
+{
+	struct pci_dev *pdev = mgp->pdev;
+	int cap;
+
+	/* restore PCIe and MSI state that linux will not */
+	cap = pci_find_capability(pdev, PCI_CAP_ID_EXP);
+	pci_write_config_dword(pdev, cap + PCI_CAP_ID_EXP, mgp->devctl);
+	cap = pci_find_capability(pdev, PCI_CAP_ID_MSI);
+	pci_write_config_word(pdev, cap + PCI_MSI_FLAGS, mgp->msi_flags);
+
+	pci_restore_state(pdev);
+}
+
+#ifdef CONFIG_PM
+
+static int myri10ge_suspend(struct pci_dev *pdev, pm_message_t state)
+{
+	struct myri10ge_priv *mgp;
+	struct net_device *netdev;
+
+	mgp = pci_get_drvdata(pdev);
+	if (mgp == NULL)
+		return -EINVAL;
+	netdev = mgp->dev;
+
+	netif_device_detach(netdev);
+	if (netif_running(netdev)) {
+		printk(KERN_INFO "myri10ge: closing %s\n", netdev->name);
+		rtnl_lock();
+		myri10ge_close(netdev);
+		rtnl_unlock();
+	}
+	myri10ge_dummy_rdma(mgp, 0);
+	free_irq(pdev->irq, mgp);
+	myri10ge_save_state(mgp);
+	pci_disable_device(pdev);
+	pci_set_power_state(pdev, pci_choose_state(pdev, state));
+	return 0;
+}
+
+static int myri10ge_resume(struct pci_dev *pdev)
+{
+	struct myri10ge_priv *mgp;
+	struct net_device *netdev;
+	int status;
+	u16 vendor;
+
+	mgp = pci_get_drvdata(pdev);
+	if (mgp == NULL)
+		return -EINVAL;
+	netdev = mgp->dev;
+	pci_set_power_state(pdev, 0);	/* zeros conf space as a side effect */
+	msleep(5);		/* give card time to respond */
+	pci_read_config_word(mgp->pdev, PCI_VENDOR_ID, &vendor);
+	if (vendor == 0xffff) {
+		printk(KERN_ERR "myri10ge: %s: device disappeared!\n",
+		       mgp->dev->name);
+		return -EIO;
+	}
+	myri10ge_restore_state(mgp);
+
+	status = pci_enable_device(pdev);
+	if (status < 0) {
+		dev_err(&pdev->dev, "failed to enable device\n");
+		return -EIO;
+	}
+
+	pci_set_master(pdev);
+
+	status = request_irq(pdev->irq, myri10ge_intr, IRQF_SHARED,
+			     netdev->name, mgp);
+	if (status != 0) {
+		dev_err(&pdev->dev, "failed to allocate IRQ\n");
+		goto abort_with_enabled;
+	}
+
+	myri10ge_reset(mgp);
+	myri10ge_dummy_rdma(mgp, 1);
+
+	/* Save configuration space to be restored if the
+	 * nic resets due to a parity error */
+	myri10ge_save_state(mgp);
+
+	if (netif_running(netdev)) {
+		rtnl_lock();
+		myri10ge_open(netdev);
+		rtnl_unlock();
+	}
+	netif_device_attach(netdev);
+
+	return 0;
+
+abort_with_enabled:
+	pci_disable_device(pdev);
+	return -EIO;
+
+}
+
+#endif				/* CONFIG_PM */
+
+static u32 myri10ge_read_reboot(struct myri10ge_priv *mgp)
+{
+	struct pci_dev *pdev = mgp->pdev;
+	int vs = mgp->vendor_specific_offset;
+	u32 reboot;
+
+	/*enter read32 mode */
+	pci_write_config_byte(pdev, vs + 0x10, 0x3);
+
+	/*read REBOOT_STATUS (0xfffffff0) */
+	pci_write_config_dword(pdev, vs + 0x18, 0xfffffff0);
+	pci_read_config_dword(pdev, vs + 0x14, &reboot);
+	return reboot;
+}
+
+/*
+ * This watchdog is used to check whether the board has suffered
+ * from a parity error and needs to be recovered.
+ */
+static void myri10ge_watchdog(void *arg)
+{
+	struct myri10ge_priv *mgp = arg;
+	u32 reboot;
+	int status;
+	u16 cmd, vendor;
+
+	mgp->watchdog_resets++;
+	pci_read_config_word(mgp->pdev, PCI_COMMAND, &cmd);
+	if ((cmd & PCI_COMMAND_MASTER) == 0) {
+		/* Bus master DMA disabled?  Check to see
+		 * if the card rebooted due to a parity error
+		 * For now, just report it */
+		reboot = myri10ge_read_reboot(mgp);
+		printk(KERN_ERR
+		       "myri10ge: %s: NIC rebooted (0x%x), resetting\n",
+		       mgp->dev->name, reboot);
+		/*
+		 * A rebooted nic will come back with config space as
+		 * it was after power was applied to PCIe bus.
+		 * Attempt to restore config space which was saved
+		 * when the driver was loaded, or the last time the
+		 * nic was resumed from power saving mode.
+		 */
+		myri10ge_restore_state(mgp);
+	} else {
+		/* if we get back -1's from our slot, perhaps somebody
+		 * powered off our card.  Don't try to reset it in
+		 * this case */
+		if (cmd == 0xffff) {
+			pci_read_config_word(mgp->pdev, PCI_VENDOR_ID, &vendor);
+			if (vendor == 0xffff) {
+				printk(KERN_ERR
+				       "myri10ge: %s: device disappeared!\n",
+				       mgp->dev->name);
+				return;
+			}
+		}
+		/* Perhaps it is a software error.  Try to reset */
+
+		printk(KERN_ERR "myri10ge: %s: device timeout, resetting\n",
+		       mgp->dev->name);
+		printk(KERN_INFO "myri10ge: %s: %d %d %d %d %d\n",
+		       mgp->dev->name, mgp->tx.req, mgp->tx.done,
+		       mgp->tx.pkt_start, mgp->tx.pkt_done,
+		       (int)ntohl(mgp->fw_stats->send_done_count));
+		msleep(2000);
+		printk(KERN_INFO "myri10ge: %s: %d %d %d %d %d\n",
+		       mgp->dev->name, mgp->tx.req, mgp->tx.done,
+		       mgp->tx.pkt_start, mgp->tx.pkt_done,
+		       (int)ntohl(mgp->fw_stats->send_done_count));
+	}
+	rtnl_lock();
+	myri10ge_close(mgp->dev);
+	status = myri10ge_load_firmware(mgp);
+	if (status != 0)
+		printk(KERN_ERR "myri10ge: %s: failed to load firmware\n",
+		       mgp->dev->name);
+	else
+		myri10ge_open(mgp->dev);
+	rtnl_unlock();
+}
+
+/*
+ * We use our own timer routine rather than relying upon
+ * netdev->tx_timeout because we have a very large hardware transmit
+ * queue.  Due to the large queue, the netdev->tx_timeout function
+ * cannot detect a NIC with a parity error in a timely fashion if the
+ * NIC is lightly loaded.
+ */
+static void myri10ge_watchdog_timer(unsigned long arg)
+{
+	struct myri10ge_priv *mgp;
+
+	mgp = (struct myri10ge_priv *)arg;
+	if (mgp->tx.req != mgp->tx.done &&
+	    mgp->tx.done == mgp->watchdog_tx_done &&
+	    mgp->watchdog_tx_req != mgp->watchdog_tx_done)
+		/* nic seems like it might be stuck.. */
+		schedule_work(&mgp->watchdog_work);
+	else
+		/* rearm timer */
+		mod_timer(&mgp->watchdog_timer,
+			  jiffies + myri10ge_watchdog_timeout * HZ);
+
+	mgp->watchdog_tx_done = mgp->tx.done;
+	mgp->watchdog_tx_req = mgp->tx.req;
+}
+
+static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
+{
+	struct net_device *netdev;
+	struct myri10ge_priv *mgp;
+	struct device *dev = &pdev->dev;
+	size_t bytes;
+	int i;
+	int status = -ENXIO;
+	int cap;
+	int dac_enabled;
+	u16 val;
+
+	netdev = alloc_etherdev(sizeof(*mgp));
+	if (netdev == NULL) {
+		dev_err(dev, "Could not allocate ethernet device\n");
+		return -ENOMEM;
+	}
+
+	mgp = netdev_priv(netdev);
+	memset(mgp, 0, sizeof(*mgp));
+	mgp->dev = netdev;
+	mgp->pdev = pdev;
+	mgp->csum_flag = MXGEFW_FLAGS_CKSUM;
+	mgp->pause = myri10ge_flow_control;
+	mgp->intr_coal_delay = myri10ge_intr_coal_delay;
+	init_waitqueue_head(&mgp->down_wq);
+
+	if (pci_enable_device(pdev)) {
+		dev_err(&pdev->dev, "pci_enable_device call failed\n");
+		status = -ENODEV;
+		goto abort_with_netdev;
+	}
+	myri10ge_select_firmware(mgp);
+
+	/* Find the vendor-specific cap so we can check
+	 * the reboot register later on */
+	mgp->vendor_specific_offset
+	    = pci_find_capability(pdev, PCI_CAP_ID_VNDR);
+
+	/* Set our max read request to 4KB */
+	cap = pci_find_capability(pdev, PCI_CAP_ID_EXP);
+	if (cap < 64) {
+		dev_err(&pdev->dev, "Bad PCI_CAP_ID_EXP location %d\n", cap);
+		goto abort_with_netdev;
+	}
+	status = pci_read_config_word(pdev, cap + PCI_EXP_DEVCTL, &val);
+	if (status != 0) {
+		dev_err(&pdev->dev, "Error %d reading PCI_EXP_DEVCTL\n",
+			status);
+		goto abort_with_netdev;
+	}
+	val = (val & ~PCI_EXP_DEVCTL_READRQ) | (5 << 12);
+	status = pci_write_config_word(pdev, cap + PCI_EXP_DEVCTL, val);
+	if (status != 0) {
+		dev_err(&pdev->dev, "Error %d writing PCI_EXP_DEVCTL\n",
+			status);
+		goto abort_with_netdev;
+	}
+
+	pci_set_master(pdev);
+	dac_enabled = 1;
+	status = pci_set_dma_mask(pdev, DMA_64BIT_MASK);
+	if (status != 0) {
+		dac_enabled = 0;
+		dev_err(&pdev->dev,
+			"64-bit pci address mask was refused, trying 32-bit");
+		status = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
+	}
+	if (status != 0) {
+		dev_err(&pdev->dev, "Error %d setting DMA mask\n", status);
+		goto abort_with_netdev;
+	}
+	mgp->cmd = dma_alloc_coherent(&pdev->dev, sizeof(*mgp->cmd),
+				      &mgp->cmd_bus, GFP_KERNEL);
+	if (mgp->cmd == NULL)
+		goto abort_with_netdev;
+
+	mgp->fw_stats = dma_alloc_coherent(&pdev->dev, sizeof(*mgp->fw_stats),
+					   &mgp->fw_stats_bus, GFP_KERNEL);
+	if (mgp->fw_stats == NULL)
+		goto abort_with_cmd;
+
+	mgp->board_span = pci_resource_len(pdev, 0);
+	mgp->iomem_base = pci_resource_start(pdev, 0);
+	mgp->mtrr = -1;
+#ifdef CONFIG_MTRR
+	mgp->mtrr = mtrr_add(mgp->iomem_base, mgp->board_span,
+			     MTRR_TYPE_WRCOMB, 1);
+#endif
+	/* Hack.  need to get rid of these magic numbers */
+	mgp->sram_size =
+	    2 * 1024 * 1024 - (2 * (48 * 1024) + (32 * 1024)) - 0x100;
+	if (mgp->sram_size > mgp->board_span) {
+		dev_err(&pdev->dev, "board span %ld bytes too small\n",
+			mgp->board_span);
+		goto abort_with_wc;
+	}
+	mgp->sram = ioremap(mgp->iomem_base, mgp->board_span);
+	if (mgp->sram == NULL) {
+		dev_err(&pdev->dev, "ioremap failed for %ld bytes at 0x%lx\n",
+			mgp->board_span, mgp->iomem_base);
+		status = -ENXIO;
+		goto abort_with_wc;
+	}
+	memcpy_fromio(mgp->eeprom_strings,
+		      mgp->sram + mgp->sram_size - MYRI10GE_EEPROM_STRINGS_SIZE,
+		      MYRI10GE_EEPROM_STRINGS_SIZE);
+	memset(mgp->eeprom_strings + MYRI10GE_EEPROM_STRINGS_SIZE - 2, 0, 2);
+	status = myri10ge_read_mac_addr(mgp);
+	if (status)
+		goto abort_with_ioremap;
+
+	for (i = 0; i < ETH_ALEN; i++)
+		netdev->dev_addr[i] = mgp->mac_addr[i];
+
+	/* allocate rx done ring */
+	bytes = myri10ge_max_intr_slots * sizeof(*mgp->rx_done.entry);
+	mgp->rx_done.entry = dma_alloc_coherent(&pdev->dev, bytes,
+						&mgp->rx_done.bus, GFP_KERNEL);
+	if (mgp->rx_done.entry == NULL)
+		goto abort_with_ioremap;
+	memset(mgp->rx_done.entry, 0, bytes);
+
+	status = myri10ge_load_firmware(mgp);
+	if (status != 0) {
+		dev_err(&pdev->dev, "failed to load firmware\n");
+		goto abort_with_rx_done;
+	}
+
+	status = myri10ge_reset(mgp);
+	if (status != 0) {
+		dev_err(&pdev->dev, "failed reset\n");
+		goto abort_with_firmware;
+	}
+
+	if (myri10ge_msi) {
+		status = pci_enable_msi(pdev);
+		if (status != 0)
+			dev_err(&pdev->dev,
+				"Error %d setting up MSI; falling back to xPIC\n",
+				status);
+		else
+			mgp->msi_enabled = 1;
+	}
+
+	status = request_irq(pdev->irq, myri10ge_intr, IRQF_SHARED,
+			     netdev->name, mgp);
+	if (status != 0) {
+		dev_err(&pdev->dev, "failed to allocate IRQ\n");
+		goto abort_with_firmware;
+	}
+
+	pci_set_drvdata(pdev, mgp);
+	if ((myri10ge_initial_mtu + ETH_HLEN) > MYRI10GE_MAX_ETHER_MTU)
+		myri10ge_initial_mtu = MYRI10GE_MAX_ETHER_MTU - ETH_HLEN;
+	if ((myri10ge_initial_mtu + ETH_HLEN) < 68)
+		myri10ge_initial_mtu = 68;
+	netdev->mtu = myri10ge_initial_mtu;
+	netdev->open = myri10ge_open;
+	netdev->stop = myri10ge_close;
+	netdev->hard_start_xmit = myri10ge_xmit;
+	netdev->get_stats = myri10ge_get_stats;
+	netdev->base_addr = mgp->iomem_base;
+	netdev->irq = pdev->irq;
+	netdev->change_mtu = myri10ge_change_mtu;
+	netdev->set_multicast_list = myri10ge_set_multicast_list;
+	netdev->set_mac_address = myri10ge_set_mac_address;
+	netdev->features = NETIF_F_SG | NETIF_F_HW_CSUM | NETIF_F_TSO;
+	if (dac_enabled)
+		netdev->features |= NETIF_F_HIGHDMA;
+	netdev->poll = myri10ge_poll;
+	netdev->weight = myri10ge_napi_weight;
+
+	/* Save configuration space to be restored if the
+	 * nic resets due to a parity error */
+	myri10ge_save_state(mgp);
+
+	/* Setup the watchdog timer */
+	setup_timer(&mgp->watchdog_timer, myri10ge_watchdog_timer,
+		    (unsigned long)mgp);
+
+	SET_ETHTOOL_OPS(netdev, &myri10ge_ethtool_ops);
+	INIT_WORK(&mgp->watchdog_work, myri10ge_watchdog, mgp);
+	status = register_netdev(netdev);
+	if (status != 0) {
+		dev_err(&pdev->dev, "register_netdev failed: %d\n", status);
+		goto abort_with_irq;
+	}
+	dev_info(dev, "%s IRQ %d, tx bndry %d, fw %s, WC %s\n",
+		 (mgp->msi_enabled ? "MSI" : "xPIC"),
+		 pdev->irq, mgp->tx.boundary, mgp->fw_name,
+		 (mgp->mtrr >= 0 ? "Enabled" : "Disabled"));
+
+	return 0;
+
+abort_with_irq:
+	free_irq(pdev->irq, mgp);
+	if (mgp->msi_enabled)
+		pci_disable_msi(pdev);
+
+abort_with_firmware:
+	myri10ge_dummy_rdma(mgp, 0);
+
+abort_with_rx_done:
+	bytes = myri10ge_max_intr_slots * sizeof(*mgp->rx_done.entry);
+	dma_free_coherent(&pdev->dev, bytes,
+			  mgp->rx_done.entry, mgp->rx_done.bus);
+
+abort_with_ioremap:
+	iounmap(mgp->sram);
+
+abort_with_wc:
+#ifdef CONFIG_MTRR
+	if (mgp->mtrr >= 0)
+		mtrr_del(mgp->mtrr, mgp->iomem_base, mgp->board_span);
+#endif
+	dma_free_coherent(&pdev->dev, sizeof(*mgp->fw_stats),
+			  mgp->fw_stats, mgp->fw_stats_bus);
+
+abort_with_cmd:
+	dma_free_coherent(&pdev->dev, sizeof(*mgp->cmd),
+			  mgp->cmd, mgp->cmd_bus);
+
+abort_with_netdev:
+
+	free_netdev(netdev);
+	return status;
+}
+
+/*
+ * myri10ge_remove
+ *
+ * Does what is necessary to shutdown one Myrinet device. Called
+ *   once for each Myrinet card by the kernel when a module is
+ *   unloaded.
+ */
+static void myri10ge_remove(struct pci_dev *pdev)
+{
+	struct myri10ge_priv *mgp;
+	struct net_device *netdev;
+	size_t bytes;
+
+	mgp = pci_get_drvdata(pdev);
+	if (mgp == NULL)
+		return;
+
+	flush_scheduled_work();
+	netdev = mgp->dev;
+	unregister_netdev(netdev);
+	free_irq(pdev->irq, mgp);
+	if (mgp->msi_enabled)
+		pci_disable_msi(pdev);
+
+	myri10ge_dummy_rdma(mgp, 0);
+
+	bytes = myri10ge_max_intr_slots * sizeof(*mgp->rx_done.entry);
+	dma_free_coherent(&pdev->dev, bytes,
+			  mgp->rx_done.entry, mgp->rx_done.bus);
+
+	iounmap(mgp->sram);
+
+#ifdef CONFIG_MTRR
+	if (mgp->mtrr >= 0)
+		mtrr_del(mgp->mtrr, mgp->iomem_base, mgp->board_span);
+#endif
+	dma_free_coherent(&pdev->dev, sizeof(*mgp->fw_stats),
+			  mgp->fw_stats, mgp->fw_stats_bus);
+
+	dma_free_coherent(&pdev->dev, sizeof(*mgp->cmd),
+			  mgp->cmd, mgp->cmd_bus);
+
+	free_netdev(netdev);
+	pci_set_drvdata(pdev, NULL);
+}
+
+#define PCI_DEVICE_ID_MYRICOM_MYRI10GE_Z8E 	0x0008
+
+static struct pci_device_id myri10ge_pci_tbl[] = {
+	{PCI_DEVICE(PCI_VENDOR_ID_MYRICOM, PCI_DEVICE_ID_MYRICOM_MYRI10GE_Z8E)},
+	{0},
+};
+
+static struct pci_driver myri10ge_driver = {
+	.name = "myri10ge",
+	.probe = myri10ge_probe,
+	.remove = myri10ge_remove,
+	.id_table = myri10ge_pci_tbl,
+#ifdef CONFIG_PM
+	.suspend = myri10ge_suspend,
+	.resume = myri10ge_resume,
+#endif
+};
+
+static __init int myri10ge_init_module(void)
+{
+	printk(KERN_INFO "%s: Version %s\n", myri10ge_driver.name,
+	       MYRI10GE_VERSION_STR);
+	return pci_register_driver(&myri10ge_driver);
+}
+
+module_init(myri10ge_init_module);
+
+static __exit void myri10ge_cleanup_module(void)
+{
+	pci_unregister_driver(&myri10ge_driver);
+}
+
+module_exit(myri10ge_cleanup_module);
diff --git a/drivers/net/myri10ge/myri10ge_mcp.h b/drivers/net/myri10ge/myri10ge_mcp.h
new file mode 100644
index 000000000..0a6cae6cb
--- /dev/null
+++ b/drivers/net/myri10ge/myri10ge_mcp.h
@@ -0,0 +1,205 @@
+#ifndef __MYRI10GE_MCP_H__
+#define __MYRI10GE_MCP_H__
+
+#define MXGEFW_VERSION_MAJOR	1
+#define MXGEFW_VERSION_MINOR	4
+
+/* 8 Bytes */
+struct mcp_dma_addr {
+	u32 high;
+	u32 low;
+};
+
+/* 4 Bytes */
+struct mcp_slot {
+	u16 checksum;
+	u16 length;
+};
+
+/* 64 Bytes */
+struct mcp_cmd {
+	u32 cmd;
+	u32 data0;		/* will be low portion if data > 32 bits */
+	/* 8 */
+	u32 data1;		/* will be high portion if data > 32 bits */
+	u32 data2;		/* currently unused.. */
+	/* 16 */
+	struct mcp_dma_addr response_addr;
+	/* 24 */
+	u8 pad[40];
+};
+
+/* 8 Bytes */
+struct mcp_cmd_response {
+	u32 data;
+	u32 result;
+};
+
+/*
+ * flags used in mcp_kreq_ether_send_t:
+ *
+ * The SMALL flag is only needed in the first segment. It is raised
+ * for packets that are total less or equal 512 bytes.
+ *
+ * The CKSUM flag must be set in all segments.
+ *
+ * The PADDED flags is set if the packet needs to be padded, and it
+ * must be set for all segments.
+ *
+ * The  MXGEFW_FLAGS_ALIGN_ODD must be set if the cumulative
+ * length of all previous segments was odd.
+ */
+
+#define MXGEFW_FLAGS_SMALL      0x1
+#define MXGEFW_FLAGS_TSO_HDR    0x1
+#define MXGEFW_FLAGS_FIRST      0x2
+#define MXGEFW_FLAGS_ALIGN_ODD  0x4
+#define MXGEFW_FLAGS_CKSUM      0x8
+#define MXGEFW_FLAGS_TSO_LAST   0x8
+#define MXGEFW_FLAGS_NO_TSO     0x10
+#define MXGEFW_FLAGS_TSO_CHOP   0x10
+#define MXGEFW_FLAGS_TSO_PLD    0x20
+
+#define MXGEFW_SEND_SMALL_SIZE  1520
+#define MXGEFW_MAX_MTU          9400
+
+union mcp_pso_or_cumlen {
+	u16 pseudo_hdr_offset;
+	u16 cum_len;
+};
+
+#define	MXGEFW_MAX_SEND_DESC 12
+#define MXGEFW_PAD	    2
+
+/* 16 Bytes */
+struct mcp_kreq_ether_send {
+	u32 addr_high;
+	u32 addr_low;
+	u16 pseudo_hdr_offset;
+	u16 length;
+	u8 pad;
+	u8 rdma_count;
+	u8 cksum_offset;	/* where to start computing cksum */
+	u8 flags;		/* as defined above */
+};
+
+/* 8 Bytes */
+struct mcp_kreq_ether_recv {
+	u32 addr_high;
+	u32 addr_low;
+};
+
+/* Commands */
+
+#define MXGEFW_CMD_OFFSET 0xf80000
+
+enum myri10ge_mcp_cmd_type {
+	MXGEFW_CMD_NONE = 0,
+	/* Reset the mcp, it is left in a safe state, waiting
+	 * for the driver to set all its parameters */
+	MXGEFW_CMD_RESET,
+
+	/* get the version number of the current firmware..
+	 * (may be available in the eeprom strings..? */
+	MXGEFW_GET_MCP_VERSION,
+
+	/* Parameters which must be set by the driver before it can
+	 * issue MXGEFW_CMD_ETHERNET_UP. They persist until the next
+	 * MXGEFW_CMD_RESET is issued */
+
+	MXGEFW_CMD_SET_INTRQ_DMA,
+	MXGEFW_CMD_SET_BIG_BUFFER_SIZE,	/* in bytes, power of 2 */
+	MXGEFW_CMD_SET_SMALL_BUFFER_SIZE,	/* in bytes */
+
+	/* Parameters which refer to lanai SRAM addresses where the
+	 * driver must issue PIO writes for various things */
+
+	MXGEFW_CMD_GET_SEND_OFFSET,
+	MXGEFW_CMD_GET_SMALL_RX_OFFSET,
+	MXGEFW_CMD_GET_BIG_RX_OFFSET,
+	MXGEFW_CMD_GET_IRQ_ACK_OFFSET,
+	MXGEFW_CMD_GET_IRQ_DEASSERT_OFFSET,
+
+	/* Parameters which refer to rings stored on the MCP,
+	 * and whose size is controlled by the mcp */
+
+	MXGEFW_CMD_GET_SEND_RING_SIZE,	/* in bytes */
+	MXGEFW_CMD_GET_RX_RING_SIZE,	/* in bytes */
+
+	/* Parameters which refer to rings stored in the host,
+	 * and whose size is controlled by the host.  Note that
+	 * all must be physically contiguous and must contain
+	 * a power of 2 number of entries.  */
+
+	MXGEFW_CMD_SET_INTRQ_SIZE,	/* in bytes */
+
+	/* command to bring ethernet interface up.  Above parameters
+	 * (plus mtu & mac address) must have been exchanged prior
+	 * to issuing this command  */
+	MXGEFW_CMD_ETHERNET_UP,
+
+	/* command to bring ethernet interface down.  No further sends
+	 * or receives may be processed until an MXGEFW_CMD_ETHERNET_UP
+	 * is issued, and all interrupt queues must be flushed prior
+	 * to ack'ing this command */
+
+	MXGEFW_CMD_ETHERNET_DOWN,
+
+	/* commands the driver may issue live, without resetting
+	 * the nic.  Note that increasing the mtu "live" should
+	 * only be done if the driver has already supplied buffers
+	 * sufficiently large to handle the new mtu.  Decreasing
+	 * the mtu live is safe */
+
+	MXGEFW_CMD_SET_MTU,
+	MXGEFW_CMD_GET_INTR_COAL_DELAY_OFFSET,	/* in microseconds */
+	MXGEFW_CMD_SET_STATS_INTERVAL,	/* in microseconds */
+	MXGEFW_CMD_SET_STATS_DMA,
+
+	MXGEFW_ENABLE_PROMISC,
+	MXGEFW_DISABLE_PROMISC,
+	MXGEFW_SET_MAC_ADDRESS,
+
+	MXGEFW_ENABLE_FLOW_CONTROL,
+	MXGEFW_DISABLE_FLOW_CONTROL,
+
+	/* do a DMA test
+	 * data0,data1 = DMA address
+	 * data2       = RDMA length (MSH), WDMA length (LSH)
+	 * command return data = repetitions (MSH), 0.5-ms ticks (LSH)
+	 */
+	MXGEFW_DMA_TEST
+};
+
+enum myri10ge_mcp_cmd_status {
+	MXGEFW_CMD_OK = 0,
+	MXGEFW_CMD_UNKNOWN,
+	MXGEFW_CMD_ERROR_RANGE,
+	MXGEFW_CMD_ERROR_BUSY,
+	MXGEFW_CMD_ERROR_EMPTY,
+	MXGEFW_CMD_ERROR_CLOSED,
+	MXGEFW_CMD_ERROR_HASH_ERROR,
+	MXGEFW_CMD_ERROR_BAD_PORT,
+	MXGEFW_CMD_ERROR_RESOURCES
+};
+
+/* 40 Bytes */
+struct mcp_irq_data {
+	u32 send_done_count;
+
+	u32 link_up;
+	u32 dropped_link_overflow;
+	u32 dropped_link_error_or_filtered;
+	u32 dropped_runt;
+	u32 dropped_overrun;
+	u32 dropped_no_small_buffer;
+	u32 dropped_no_big_buffer;
+	u32 rdma_tags_available;
+
+	u8 tx_stopped;
+	u8 link_down;
+	u8 stats_updated;
+	u8 valid;
+};
+
+#endif				/* __MYRI10GE_MCP_H__ */
diff --git a/drivers/net/myri10ge/myri10ge_mcp_gen_header.h b/drivers/net/myri10ge/myri10ge_mcp_gen_header.h
new file mode 100644
index 000000000..487f7792f
--- /dev/null
+++ b/drivers/net/myri10ge/myri10ge_mcp_gen_header.h
@@ -0,0 +1,58 @@
+#ifndef __MYRI10GE_MCP_GEN_HEADER_H__
+#define __MYRI10GE_MCP_GEN_HEADER_H__
+
+/* this file define a standard header used as a first entry point to
+ * exchange information between firmware/driver and driver.  The
+ * header structure can be anywhere in the mcp. It will usually be in
+ * the .data section, because some fields needs to be initialized at
+ * compile time.
+ * The 32bit word at offset MX_HEADER_PTR_OFFSET in the mcp must
+ * contains the location of the header.
+ *
+ * Typically a MCP will start with the following:
+ * .text
+ * .space 52    ! to help catch MEMORY_INT errors
+ * bt start     ! jump to real code
+ * nop
+ * .long _gen_mcp_header
+ *
+ * The source will have a definition like:
+ *
+ * mcp_gen_header_t gen_mcp_header = {
+ * .header_length = sizeof(mcp_gen_header_t),
+ * .mcp_type = MCP_TYPE_XXX,
+ * .version = "something $Id: mcp_gen_header.h,v 1.2 2006/05/13 10:04:35 bgoglin Exp $",
+ * .mcp_globals = (unsigned)&Globals
+ * };
+ */
+
+#define MCP_HEADER_PTR_OFFSET  0x3c
+
+#define MCP_TYPE_MX 0x4d582020	/* "MX  " */
+#define MCP_TYPE_PCIE 0x70636965	/* "PCIE" pcie-only MCP */
+#define MCP_TYPE_ETH 0x45544820	/* "ETH " */
+#define MCP_TYPE_MCP0 0x4d435030	/* "MCP0" */
+
+struct mcp_gen_header {
+	/* the first 4 fields are filled at compile time */
+	unsigned header_length;
+	unsigned mcp_type;
+	char version[128];
+	unsigned mcp_globals;	/* pointer to mcp-type specific structure */
+
+	/* filled by the MCP at run-time */
+	unsigned sram_size;
+	unsigned string_specs;	/* either the original STRING_SPECS or a superset */
+	unsigned string_specs_len;
+
+	/* Fields above this comment are guaranteed to be present.
+	 *
+	 * Fields below this comment are extensions added in later versions
+	 * of this struct, drivers should compare the header_length against
+	 * offsetof(field) to check wether a given MCP implements them.
+	 *
+	 * Never remove any field.  Keep everything naturally align.
+	 */
+};
+
+#endif				/* __MYRI10GE_MCP_GEN_HEADER_H__ */
diff --git a/drivers/net/netx-eth.c b/drivers/net/netx-eth.c
new file mode 100644
index 000000000..30ed9a5a4
--- /dev/null
+++ b/drivers/net/netx-eth.c
@@ -0,0 +1,515 @@
+/*
+ * drivers/net/netx-eth.c
+ *
+ * Copyright (c) 2005 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix
+ *
+ * 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 <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/delay.h>
+
+#include <linux/netdevice.h>
+#include <linux/platform_device.h>
+#include <linux/etherdevice.h>
+#include <linux/skbuff.h>
+#include <linux/mii.h>
+
+#include <asm/io.h>
+#include <asm/hardware.h>
+#include <asm/arch/hardware.h>
+#include <asm/arch/netx-regs.h>
+#include <asm/arch/pfifo.h>
+#include <asm/arch/xc.h>
+#include <asm/arch/eth.h>
+
+/* XC Fifo Offsets */
+#define EMPTY_PTR_FIFO(xcno)    (0 + ((xcno) << 3))	/* Index of the empty pointer FIFO */
+#define IND_FIFO_PORT_HI(xcno)  (1 + ((xcno) << 3))	/* Index of the FIFO where received */
+							/* Data packages are indicated by XC */
+#define IND_FIFO_PORT_LO(xcno)  (2 + ((xcno) << 3))	/* Index of the FIFO where received */
+							/* Data packages are indicated by XC */
+#define REQ_FIFO_PORT_HI(xcno)  (3 + ((xcno) << 3))	/* Index of the FIFO where Data packages */
+							/* have to be indicated by ARM which */
+							/* shall be sent */
+#define REQ_FIFO_PORT_LO(xcno)  (4 + ((xcno) << 3))	/* Index of the FIFO where Data packages */
+							/* have to be indicated by ARM which shall */
+							/* be sent */
+#define CON_FIFO_PORT_HI(xcno)  (5 + ((xcno) << 3))	/* Index of the FIFO where sent Data packages */
+							/* are confirmed */
+#define CON_FIFO_PORT_LO(xcno)  (6 + ((xcno) << 3))	/* Index of the FIFO where sent Data */
+							/* packages are confirmed */
+#define PFIFO_MASK(xcno)        (0x7f << (xcno*8))
+
+#define FIFO_PTR_FRAMELEN_SHIFT 0
+#define FIFO_PTR_FRAMELEN_MASK  (0x7ff << 0)
+#define FIFO_PTR_FRAMELEN(len)  (((len) << 0) & FIFO_PTR_FRAMELEN_MASK)
+#define FIFO_PTR_TIMETRIG       (1<<11)
+#define FIFO_PTR_MULTI_REQ
+#define FIFO_PTR_ORIGIN         (1<<14)
+#define FIFO_PTR_VLAN           (1<<15)
+#define FIFO_PTR_FRAMENO_SHIFT  16
+#define FIFO_PTR_FRAMENO_MASK   (0x3f << 16)
+#define FIFO_PTR_FRAMENO(no)    (((no) << 16) & FIFO_PTR_FRAMENO_MASK)
+#define FIFO_PTR_SEGMENT_SHIFT  22
+#define FIFO_PTR_SEGMENT_MASK   (0xf << 22)
+#define FIFO_PTR_SEGMENT(seg)   (((seg) & 0xf) << 22)
+#define FIFO_PTR_ERROR_SHIFT    28
+#define FIFO_PTR_ERROR_MASK     (0xf << 28)
+
+#define ISR_LINK_STATUS_CHANGE (1<<4)
+#define ISR_IND_LO             (1<<3)
+#define ISR_CON_LO             (1<<2)
+#define ISR_IND_HI             (1<<1)
+#define ISR_CON_HI             (1<<0)
+
+#define ETH_MAC_LOCAL_CONFIG 0x1560
+#define ETH_MAC_4321         0x1564
+#define ETH_MAC_65           0x1568
+
+#define MAC_TRAFFIC_CLASS_ARRANGEMENT_SHIFT 16
+#define MAC_TRAFFIC_CLASS_ARRANGEMENT_MASK (0xf<<MAC_TRAFFIC_CLASS_ARRANGEMENT_SHIFT)
+#define MAC_TRAFFIC_CLASS_ARRANGEMENT(x) (((x)<<MAC_TRAFFIC_CLASS_ARRANGEMENT_SHIFT) & MAC_TRAFFIC_CLASS_ARRANGEMENT_MASK)
+#define LOCAL_CONFIG_LINK_STATUS_IRQ_EN (1<<24)
+#define LOCAL_CONFIG_CON_LO_IRQ_EN (1<<23)
+#define LOCAL_CONFIG_CON_HI_IRQ_EN (1<<22)
+#define LOCAL_CONFIG_IND_LO_IRQ_EN (1<<21)
+#define LOCAL_CONFIG_IND_HI_IRQ_EN (1<<20)
+
+#define CARDNAME "netx-eth"
+
+/* LSB must be zero */
+#define INTERNAL_PHY_ADR 0x1c
+
+struct netx_eth_priv {
+	void                    __iomem *sram_base, *xpec_base, *xmac_base;
+	int                     id;
+	struct net_device_stats stats;
+	struct mii_if_info      mii;
+	u32                     msg_enable;
+	struct xc               *xc;
+	spinlock_t              lock;
+};
+
+static void netx_eth_set_multicast_list(struct net_device *ndev)
+{
+	/* implement me */
+}
+
+static int
+netx_eth_hard_start_xmit(struct sk_buff *skb, struct net_device *ndev)
+{
+	struct netx_eth_priv *priv = netdev_priv(ndev);
+	unsigned char *buf = skb->data;
+	unsigned int len = skb->len;
+
+	spin_lock_irq(&priv->lock);
+	memcpy_toio(priv->sram_base + 1560, (void *)buf, len);
+	if (len < 60) {
+		memset_io(priv->sram_base + 1560 + len, 0, 60 - len);
+		len = 60;
+	}
+
+	pfifo_push(REQ_FIFO_PORT_LO(priv->id),
+	           FIFO_PTR_SEGMENT(priv->id) |
+	           FIFO_PTR_FRAMENO(1) |
+	           FIFO_PTR_FRAMELEN(len));
+
+	ndev->trans_start = jiffies;
+	priv->stats.tx_packets++;
+	priv->stats.tx_bytes += skb->len;
+
+	netif_stop_queue(ndev);
+	spin_unlock_irq(&priv->lock);
+	dev_kfree_skb(skb);
+
+	return 0;
+}
+
+static void netx_eth_receive(struct net_device *ndev)
+{
+	struct netx_eth_priv *priv = netdev_priv(ndev);
+	unsigned int val, frameno, seg, len;
+	unsigned char *data;
+	struct sk_buff *skb;
+
+	val = pfifo_pop(IND_FIFO_PORT_LO(priv->id));
+
+	frameno = (val & FIFO_PTR_FRAMENO_MASK) >> FIFO_PTR_FRAMENO_SHIFT;
+	seg = (val & FIFO_PTR_SEGMENT_MASK) >> FIFO_PTR_SEGMENT_SHIFT;
+	len = (val & FIFO_PTR_FRAMELEN_MASK) >> FIFO_PTR_FRAMELEN_SHIFT;
+
+	skb = dev_alloc_skb(len);
+	if (unlikely(skb == NULL)) {
+		printk(KERN_NOTICE "%s: Low memory, packet dropped.\n",
+			ndev->name);
+		priv->stats.rx_dropped++;
+		return;
+	}
+
+	data = skb_put(skb, len);
+
+	memcpy_fromio(data, priv->sram_base + frameno * 1560, len);
+
+	pfifo_push(EMPTY_PTR_FIFO(priv->id),
+		FIFO_PTR_SEGMENT(seg) | FIFO_PTR_FRAMENO(frameno));
+
+	ndev->last_rx = jiffies;
+	skb->dev = ndev;
+	skb->protocol = eth_type_trans(skb, ndev);
+	netif_rx(skb);
+	priv->stats.rx_packets++;
+	priv->stats.rx_bytes += len;
+}
+
+static irqreturn_t
+netx_eth_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	struct net_device *ndev = dev_id;
+	struct netx_eth_priv *priv = netdev_priv(ndev);
+	int status;
+	unsigned long flags;
+
+	spin_lock_irqsave(&priv->lock, flags);
+
+	status = readl(NETX_PFIFO_XPEC_ISR(priv->id));
+	while (status) {
+		int fill_level;
+		writel(status, NETX_PFIFO_XPEC_ISR(priv->id));
+
+		if ((status & ISR_CON_HI) || (status & ISR_IND_HI))
+			printk("%s: unexpected status: 0x%08x\n",
+			    __FUNCTION__, status);
+
+		fill_level =
+		    readl(NETX_PFIFO_FILL_LEVEL(IND_FIFO_PORT_LO(priv->id)));
+		while (fill_level--)
+			netx_eth_receive(ndev);
+
+		if (status & ISR_CON_LO)
+			netif_wake_queue(ndev);
+
+		if (status & ISR_LINK_STATUS_CHANGE)
+			mii_check_media(&priv->mii, netif_msg_link(priv), 1);
+
+		status = readl(NETX_PFIFO_XPEC_ISR(priv->id));
+	}
+	spin_unlock_irqrestore(&priv->lock, flags);
+	return IRQ_HANDLED;
+}
+
+static struct net_device_stats *netx_eth_query_statistics(struct net_device *ndev)
+{
+	struct netx_eth_priv *priv = netdev_priv(ndev);
+	return &priv->stats;
+}
+
+static int netx_eth_open(struct net_device *ndev)
+{
+	struct netx_eth_priv *priv = netdev_priv(ndev);
+
+	if (request_irq
+	    (ndev->irq, &netx_eth_interrupt, IRQF_SHARED, ndev->name, ndev))
+		return -EAGAIN;
+
+	writel(ndev->dev_addr[0] |
+	       ndev->dev_addr[1]<<8 |
+	       ndev->dev_addr[2]<<16 |
+	       ndev->dev_addr[3]<<24,
+	       priv->xpec_base + NETX_XPEC_RAM_START_OFS + ETH_MAC_4321);
+	writel(ndev->dev_addr[4] |
+	       ndev->dev_addr[5]<<8,
+	       priv->xpec_base + NETX_XPEC_RAM_START_OFS + ETH_MAC_65);
+
+	writel(LOCAL_CONFIG_LINK_STATUS_IRQ_EN |
+		LOCAL_CONFIG_CON_LO_IRQ_EN |
+		LOCAL_CONFIG_CON_HI_IRQ_EN |
+		LOCAL_CONFIG_IND_LO_IRQ_EN |
+		LOCAL_CONFIG_IND_HI_IRQ_EN,
+		priv->xpec_base + NETX_XPEC_RAM_START_OFS +
+		ETH_MAC_LOCAL_CONFIG);
+
+	mii_check_media(&priv->mii, netif_msg_link(priv), 1);
+	netif_start_queue(ndev);
+
+	return 0;
+}
+
+static int netx_eth_close(struct net_device *ndev)
+{
+	struct netx_eth_priv *priv = netdev_priv(ndev);
+
+	netif_stop_queue(ndev);
+
+	writel(0,
+	    priv->xpec_base + NETX_XPEC_RAM_START_OFS + ETH_MAC_LOCAL_CONFIG);
+
+	free_irq(ndev->irq, ndev);
+
+	return 0;
+}
+
+static void netx_eth_timeout(struct net_device *ndev)
+{
+	struct netx_eth_priv *priv = netdev_priv(ndev);
+	int i;
+
+	printk(KERN_ERR "%s: transmit timed out, resetting\n", ndev->name);
+
+	spin_lock_irq(&priv->lock);
+
+	xc_reset(priv->xc);
+	xc_start(priv->xc);
+
+	for (i=2; i<=18; i++)
+		pfifo_push(EMPTY_PTR_FIFO(priv->id),
+			FIFO_PTR_FRAMENO(i) | FIFO_PTR_SEGMENT(priv->id));
+
+	spin_unlock_irq(&priv->lock);
+
+	netif_wake_queue(ndev);
+}
+
+static int
+netx_eth_phy_read(struct net_device *ndev, int phy_id, int reg)
+{
+	unsigned int val;
+
+	val = MIIMU_SNRDY | MIIMU_PREAMBLE | MIIMU_PHYADDR(phy_id) |
+	      MIIMU_REGADDR(reg) | MIIMU_PHY_NRES;
+
+	writel(val, NETX_MIIMU);
+	while (readl(NETX_MIIMU) & MIIMU_SNRDY);
+
+	return readl(NETX_MIIMU) >> 16;
+
+}
+
+static void
+netx_eth_phy_write(struct net_device *ndev, int phy_id, int reg, int value)
+{
+	unsigned int val;
+
+	val = MIIMU_SNRDY | MIIMU_PREAMBLE | MIIMU_PHYADDR(phy_id) |
+	      MIIMU_REGADDR(reg) | MIIMU_PHY_NRES | MIIMU_OPMODE_WRITE |
+	      MIIMU_DATA(value);
+
+	writel(val, NETX_MIIMU);
+	while (readl(NETX_MIIMU) & MIIMU_SNRDY);
+}
+
+static int netx_eth_enable(struct net_device *ndev)
+{
+	struct netx_eth_priv *priv = netdev_priv(ndev);
+	unsigned int mac4321, mac65;
+	int running, i;
+
+	ether_setup(ndev);
+
+	ndev->open = netx_eth_open;
+	ndev->stop = netx_eth_close;
+	ndev->hard_start_xmit = netx_eth_hard_start_xmit;
+	ndev->tx_timeout = netx_eth_timeout;
+	ndev->watchdog_timeo = msecs_to_jiffies(5000);
+	ndev->get_stats = netx_eth_query_statistics;
+	ndev->set_multicast_list = netx_eth_set_multicast_list;
+
+	priv->msg_enable       = NETIF_MSG_LINK;
+	priv->mii.phy_id_mask  = 0x1f;
+	priv->mii.reg_num_mask = 0x1f;
+	priv->mii.force_media  = 0;
+	priv->mii.full_duplex  = 0;
+	priv->mii.dev	     = ndev;
+	priv->mii.mdio_read    = netx_eth_phy_read;
+	priv->mii.mdio_write   = netx_eth_phy_write;
+	priv->mii.phy_id = INTERNAL_PHY_ADR + priv->id;
+
+	running = xc_running(priv->xc);
+	xc_stop(priv->xc);
+
+	/* if the xc engine is already running, assume the bootloader has
+	 * loaded the firmware for us
+	 */
+	if (running) {
+		/* get Node Address from hardware */
+		mac4321 = readl(priv->xpec_base +
+			NETX_XPEC_RAM_START_OFS + ETH_MAC_4321);
+		mac65 = readl(priv->xpec_base +
+			NETX_XPEC_RAM_START_OFS + ETH_MAC_65);
+
+		ndev->dev_addr[0] = mac4321 & 0xff;
+		ndev->dev_addr[1] = (mac4321 >> 8) & 0xff;
+		ndev->dev_addr[2] = (mac4321 >> 16) & 0xff;
+		ndev->dev_addr[3] = (mac4321 >> 24) & 0xff;
+		ndev->dev_addr[4] = mac65 & 0xff;
+		ndev->dev_addr[5] = (mac65 >> 8) & 0xff;
+	} else {
+		if (xc_request_firmware(priv->xc)) {
+			printk(CARDNAME ": requesting firmware failed\n");
+			return -ENODEV;
+		}
+	}
+
+	xc_reset(priv->xc);
+	xc_start(priv->xc);
+
+	if (!is_valid_ether_addr(ndev->dev_addr))
+		printk("%s: Invalid ethernet MAC address.  Please "
+		       "set using ifconfig\n", ndev->name);
+
+	for (i=2; i<=18; i++)
+		pfifo_push(EMPTY_PTR_FIFO(priv->id),
+			FIFO_PTR_FRAMENO(i) | FIFO_PTR_SEGMENT(priv->id));
+
+	return register_netdev(ndev);
+
+}
+
+static int netx_eth_drv_probe(struct platform_device *pdev)
+{
+	struct netx_eth_priv *priv;
+	struct net_device *ndev;
+	struct netxeth_platform_data *pdata;
+	int ret;
+
+	ndev = alloc_etherdev(sizeof (struct netx_eth_priv));
+	if (!ndev) {
+		printk("%s: could not allocate device.\n", CARDNAME);
+		ret = -ENOMEM;
+		goto exit;
+	}
+	SET_MODULE_OWNER(ndev);
+	SET_NETDEV_DEV(ndev, &pdev->dev);
+
+	platform_set_drvdata(pdev, ndev);
+
+	priv = netdev_priv(ndev);
+
+	pdata = (struct netxeth_platform_data *)pdev->dev.platform_data;
+	priv->xc = request_xc(pdata->xcno, &pdev->dev);
+	if (!priv->xc) {
+		dev_err(&pdev->dev, "unable to request xc engine\n");
+		ret = -ENODEV;
+		goto exit_free_netdev;
+	}
+
+	ndev->irq = priv->xc->irq;
+	priv->id = pdev->id;
+	priv->xpec_base = priv->xc->xpec_base;
+	priv->xmac_base = priv->xc->xmac_base;
+	priv->sram_base = priv->xc->sram_base;
+
+	ret = pfifo_request(PFIFO_MASK(priv->id));
+	if (ret) {
+		printk("unable to request PFIFO\n");
+		goto exit_free_xc;
+	}
+
+	ret = netx_eth_enable(ndev);
+	if (ret)
+		goto exit_free_pfifo;
+
+	return 0;
+exit_free_pfifo:
+	pfifo_free(PFIFO_MASK(priv->id));
+exit_free_xc:
+	free_xc(priv->xc);
+exit_free_netdev:
+	platform_set_drvdata(pdev, NULL);
+	free_netdev(ndev);
+exit:
+	return ret;
+}
+
+static int netx_eth_drv_remove(struct platform_device *pdev)
+{
+	struct net_device *ndev = dev_get_drvdata(&pdev->dev);
+	struct netx_eth_priv *priv = netdev_priv(ndev);
+
+	platform_set_drvdata(pdev, NULL);
+
+	unregister_netdev(ndev);
+	xc_stop(priv->xc);
+	free_xc(priv->xc);
+	free_netdev(ndev);
+	pfifo_free(PFIFO_MASK(priv->id));
+
+	return 0;
+}
+
+static int netx_eth_drv_suspend(struct platform_device *pdev, pm_message_t state)
+{
+	dev_err(&pdev->dev, "suspend not implemented\n");
+	return 0;
+}
+
+static int netx_eth_drv_resume(struct platform_device *pdev)
+{
+	dev_err(&pdev->dev, "resume not implemented\n");
+	return 0;
+}
+
+static struct platform_driver netx_eth_driver = {
+	.probe		= netx_eth_drv_probe,
+	.remove		= netx_eth_drv_remove,
+	.suspend	= netx_eth_drv_suspend,
+	.resume		= netx_eth_drv_resume,
+	.driver		= {
+		.name	= CARDNAME,
+		.owner	= THIS_MODULE,
+	},
+};
+
+static int __init netx_eth_init(void)
+{
+	unsigned int phy_control, val;
+
+	printk("NetX Ethernet driver\n");
+
+	phy_control = PHY_CONTROL_PHY_ADDRESS(INTERNAL_PHY_ADR>>1) |
+		      PHY_CONTROL_PHY1_MODE(PHY_MODE_ALL) |
+		      PHY_CONTROL_PHY1_AUTOMDIX |
+		      PHY_CONTROL_PHY1_EN |
+		      PHY_CONTROL_PHY0_MODE(PHY_MODE_ALL) |
+		      PHY_CONTROL_PHY0_AUTOMDIX |
+		      PHY_CONTROL_PHY0_EN |
+		      PHY_CONTROL_CLK_XLATIN;
+
+	val = readl(NETX_SYSTEM_IOC_ACCESS_KEY);
+	writel(val, NETX_SYSTEM_IOC_ACCESS_KEY);
+
+	writel(phy_control | PHY_CONTROL_RESET, NETX_SYSTEM_PHY_CONTROL);
+	udelay(100);
+
+	val = readl(NETX_SYSTEM_IOC_ACCESS_KEY);
+	writel(val, NETX_SYSTEM_IOC_ACCESS_KEY);
+
+	writel(phy_control, NETX_SYSTEM_PHY_CONTROL);
+
+	return platform_driver_register(&netx_eth_driver);
+}
+
+static void __exit netx_eth_cleanup(void)
+{
+	platform_driver_unregister(&netx_eth_driver);
+}
+
+module_init(netx_eth_init);
+module_exit(netx_eth_cleanup);
+
+MODULE_AUTHOR("Sascha Hauer, Pengutronix");
+MODULE_LICENSE("GPL");
+
diff --git a/drivers/net/phy/fixed.c b/drivers/net/phy/fixed.c
new file mode 100644
index 000000000..7e3364f55
--- /dev/null
+++ b/drivers/net/phy/fixed.c
@@ -0,0 +1,357 @@
+/*
+ * drivers/net/phy/fixed.c
+ *
+ * Driver for fixed PHYs, when transceiver is able to operate in one fixed mode.
+ *
+ * Author: Vitaly Bordug
+ *
+ * Copyright (c) 2006 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 as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ */
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/string.h>
+#include <linux/errno.h>
+#include <linux/unistd.h>
+#include <linux/slab.h>
+#include <linux/interrupt.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/skbuff.h>
+#include <linux/spinlock.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/mii.h>
+#include <linux/ethtool.h>
+#include <linux/phy.h>
+
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/uaccess.h>
+
+#define MII_REGS_NUM	7
+
+/*
+    The idea is to emulate normal phy behavior by responding with
+    pre-defined values to mii BMCR read, so that read_status hook could
+    take all the needed info.
+*/
+
+struct fixed_phy_status {
+	u8 	link;
+	u16	speed;
+	u8 	duplex;
+};
+
+/*-----------------------------------------------------------------------------
+ *  Private information hoder for mii_bus
+ *-----------------------------------------------------------------------------*/
+struct fixed_info {
+	u16 *regs;
+	u8 regs_num;
+	struct fixed_phy_status phy_status;
+	struct phy_device *phydev; /* pointer to the container */
+	/* link & speed cb */
+	int(*link_update)(struct net_device*, struct fixed_phy_status*);
+
+};
+
+/*-----------------------------------------------------------------------------
+ *  If something weird is required to be done with link/speed,
+ * network driver is able to assign a function to implement this.
+ * May be useful for PHY's that need to be software-driven.
+ *-----------------------------------------------------------------------------*/
+int fixed_mdio_set_link_update(struct phy_device* phydev,
+		int(*link_update)(struct net_device*, struct fixed_phy_status*))
+{
+	struct fixed_info *fixed;
+
+	if(link_update == NULL)
+		return -EINVAL;
+
+	if(phydev) {
+		if(phydev->bus)	{
+			fixed = phydev->bus->priv;
+			fixed->link_update = link_update;
+			return 0;
+		}
+	}
+	return -EINVAL;
+}
+EXPORT_SYMBOL(fixed_mdio_set_link_update);
+
+/*-----------------------------------------------------------------------------
+ *  This is used for updating internal mii regs from the status
+ *-----------------------------------------------------------------------------*/
+static int fixed_mdio_update_regs(struct fixed_info *fixed)
+{
+	u16 *regs = fixed->regs;
+	u16 bmsr = 0;
+	u16 bmcr = 0;
+
+	if(!regs) {
+		printk(KERN_ERR "%s: regs not set up", __FUNCTION__);
+		return -EINVAL;
+	}
+
+	if(fixed->phy_status.link)
+		bmsr |= BMSR_LSTATUS;
+
+	if(fixed->phy_status.duplex) {
+		bmcr |= BMCR_FULLDPLX;
+
+		switch ( fixed->phy_status.speed ) {
+		case 100:
+			bmsr |= BMSR_100FULL;
+			bmcr |= BMCR_SPEED100;
+		break;
+
+		case 10:
+			bmsr |= BMSR_10FULL;
+		break;
+		}
+	} else {
+		switch ( fixed->phy_status.speed ) {
+		case 100:
+			bmsr |= BMSR_100HALF;
+			bmcr |= BMCR_SPEED100;
+		break;
+
+		case 10:
+			bmsr |= BMSR_100HALF;
+		break;
+		}
+	}
+
+	regs[MII_BMCR] =  bmcr;
+	regs[MII_BMSR] =  bmsr | 0x800; /*we are always capable of 10 hdx*/
+
+	return 0;
+}
+
+static int fixed_mii_read(struct mii_bus *bus, int phy_id, int location)
+{
+	struct fixed_info *fixed = bus->priv;
+
+	/* if user has registered link update callback, use it */
+	if(fixed->phydev)
+		if(fixed->phydev->attached_dev) {
+			if(fixed->link_update) {
+				fixed->link_update(fixed->phydev->attached_dev,
+						&fixed->phy_status);
+				fixed_mdio_update_regs(fixed);
+			}
+	}
+
+	if ((unsigned int)location >= fixed->regs_num)
+		return -1;
+	return fixed->regs[location];
+}
+
+static int fixed_mii_write(struct mii_bus *bus, int phy_id, int location, u16 val)
+{
+	/* do nothing for now*/
+	return 0;
+}
+
+static int fixed_mii_reset(struct mii_bus *bus)
+{
+	/*nothing here - no way/need to reset it*/
+	return 0;
+}
+
+static int fixed_config_aneg(struct phy_device *phydev)
+{
+	/* :TODO:03/13/2006 09:45:37 PM::
+	 The full autoneg funcionality can be emulated,
+	 but no need to have anything here for now
+	 */
+	return 0;
+}
+
+/*-----------------------------------------------------------------------------
+ * the manual bind will do the magic - with phy_id_mask == 0
+ * match will never return true...
+ *-----------------------------------------------------------------------------*/
+static struct phy_driver fixed_mdio_driver = {
+	.name		= "Fixed PHY",
+	.features	= PHY_BASIC_FEATURES,
+	.config_aneg	= fixed_config_aneg,
+	.read_status	= genphy_read_status,
+	.driver 	= { .owner = THIS_MODULE,},
+};
+
+/*-----------------------------------------------------------------------------
+ *  This func is used to create all the necessary stuff, bind
+ * the fixed phy driver and register all it on the mdio_bus_type.
+ * speed is either 10 or 100, duplex is boolean.
+ * number is used to create multiple fixed PHYs, so that several devices can
+ * utilize them simultaneously.
+ *-----------------------------------------------------------------------------*/
+static int fixed_mdio_register_device(int number, int speed, int duplex)
+{
+	struct mii_bus *new_bus;
+	struct fixed_info *fixed;
+	struct phy_device *phydev;
+	int err = 0;
+
+	struct device* dev = kzalloc(sizeof(struct device), GFP_KERNEL);
+
+	if (NULL == dev)
+		return -ENOMEM;
+
+	new_bus = kzalloc(sizeof(struct mii_bus), GFP_KERNEL);
+
+	if (NULL == new_bus) {
+		kfree(dev);
+		return -ENOMEM;
+	}
+	fixed = kzalloc(sizeof(struct fixed_info), GFP_KERNEL);
+
+	if (NULL == fixed) {
+		kfree(dev);
+		kfree(new_bus);
+		return -ENOMEM;
+	}
+
+	fixed->regs = kzalloc(MII_REGS_NUM*sizeof(int), GFP_KERNEL);
+	fixed->regs_num = MII_REGS_NUM;
+	fixed->phy_status.speed = speed;
+	fixed->phy_status.duplex = duplex;
+	fixed->phy_status.link = 1;
+
+	new_bus->name = "Fixed MII Bus",
+	new_bus->read = &fixed_mii_read,
+	new_bus->write = &fixed_mii_write,
+	new_bus->reset = &fixed_mii_reset,
+
+	/*set up workspace*/
+	fixed_mdio_update_regs(fixed);
+	new_bus->priv = fixed;
+
+	new_bus->dev = dev;
+	dev_set_drvdata(dev, new_bus);
+
+	/* create phy_device and register it on the mdio bus */
+	phydev = phy_device_create(new_bus, 0, 0);
+
+	/*
+	 Put the phydev pointer into the fixed pack so that bus read/write code could
+	 be able to access for instance attached netdev. Well it doesn't have to do
+	 so, only in case of utilizing user-specified link-update...
+	 */
+	fixed->phydev = phydev;
+
+	if(NULL == phydev) {
+		err = -ENOMEM;
+		goto device_create_fail;
+	}
+
+	phydev->irq = -1;
+	phydev->dev.bus = &mdio_bus_type;
+
+	if(number)
+		snprintf(phydev->dev.bus_id, BUS_ID_SIZE,
+				"fixed_%d@%d:%d", number, speed, duplex);
+	else
+		snprintf(phydev->dev.bus_id, BUS_ID_SIZE,
+				"fixed@%d:%d", speed, duplex);
+	phydev->bus = new_bus;
+
+	err = device_register(&phydev->dev);
+	if(err) {
+		printk(KERN_ERR "Phy %s failed to register\n",
+				phydev->dev.bus_id);
+		goto bus_register_fail;
+	}
+
+	/*
+	   the mdio bus has phy_id match... In order not to do it
+	   artificially, we are binding the driver here by hand;
+	   it will be the same for all the fixed phys anyway.
+	 */
+	down_write(&phydev->dev.bus->subsys.rwsem);
+
+	phydev->dev.driver = &fixed_mdio_driver.driver;
+
+	err = phydev->dev.driver->probe(&phydev->dev);
+	if(err < 0) {
+		printk(KERN_ERR "Phy %s: problems with fixed driver\n",phydev->dev.bus_id);
+		up_write(&phydev->dev.bus->subsys.rwsem);
+		goto probe_fail;
+	}
+
+	device_bind_driver(&phydev->dev);
+	up_write(&phydev->dev.bus->subsys.rwsem);
+
+	return 0;
+
+probe_fail:
+	device_unregister(&phydev->dev);
+bus_register_fail:
+	kfree(phydev);
+device_create_fail:
+	kfree(dev);
+	kfree(new_bus);
+	kfree(fixed);
+
+	return err;
+}
+
+
+MODULE_DESCRIPTION("Fixed PHY device & driver for PAL");
+MODULE_AUTHOR("Vitaly Bordug");
+MODULE_LICENSE("GPL");
+
+static int __init fixed_init(void)
+{
+	int ret;
+	int duplex = 0;
+
+	/* register on the bus... Not expected to be matched with anything there... */
+	phy_driver_register(&fixed_mdio_driver);
+
+	/* So let the fun begin...
+	   We will create several mdio devices here, and will bound the upper
+	   driver to them.
+
+	   Then the external software can lookup the phy bus by searching
+	   fixed@speed:duplex, e.g. fixed@100:1, to be connected to the
+	   virtual 100M Fdx phy.
+
+	   In case several virtual PHYs required, the bus_id will be in form
+	   fixed_<num>@<speed>:<duplex>, which make it able even to define
+	   driver-specific link control callback, if for instance PHY is completely
+	   SW-driven.
+
+	*/
+
+#ifdef CONFIG_FIXED_MII_DUPLEX
+	duplex = 1;
+#endif
+
+#ifdef CONFIG_FIXED_MII_100_FDX
+	fixed_mdio_register_device(0, 100, 1);
+#endif
+
+#ifdef CONFIX_FIXED_MII_10_FDX
+	fixed_mdio_register_device(0, 10, 1);
+#endif
+	return 0;
+}
+
+static void __exit fixed_exit(void)
+{
+	phy_driver_unregister(&fixed_mdio_driver);
+	/* :WARNING:02/18/2006 04:32:40 AM:: Cleanup all the created stuff */
+}
+
+module_init(fixed_init);
+module_exit(fixed_exit);
diff --git a/drivers/net/phy/smsc.c b/drivers/net/phy/smsc.c
new file mode 100644
index 000000000..b1d8ed40a
--- /dev/null
+++ b/drivers/net/phy/smsc.c
@@ -0,0 +1,100 @@
+/*
+ * drivers/net/phy/smsc.c
+ *
+ * Driver for SMSC PHYs
+ *
+ * Author: Herbert Valerio Riedel
+ *
+ * Copyright (c) 2006 Herbert Valerio Riedel <hvr@gnu.org>
+ *
+ * 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/kernel.h>
+#include <linux/module.h>
+#include <linux/mii.h>
+#include <linux/ethtool.h>
+#include <linux/phy.h>
+#include <linux/netdevice.h>
+
+#define MII_LAN83C185_ISF 29 /* Interrupt Source Flags */
+#define MII_LAN83C185_IM  30 /* Interrupt Mask */
+
+#define MII_LAN83C185_ISF_INT1 (1<<1) /* Auto-Negotiation Page Received */
+#define MII_LAN83C185_ISF_INT2 (1<<2) /* Parallel Detection Fault */
+#define MII_LAN83C185_ISF_INT3 (1<<3) /* Auto-Negotiation LP Ack */
+#define MII_LAN83C185_ISF_INT4 (1<<4) /* Link Down */
+#define MII_LAN83C185_ISF_INT5 (1<<5) /* Remote Fault Detected */
+#define MII_LAN83C185_ISF_INT6 (1<<6) /* Auto-Negotiation complete */
+#define MII_LAN83C185_ISF_INT7 (1<<7) /* ENERGYON */
+
+#define MII_LAN83C185_ISF_INT_ALL (0x0e)
+
+#define MII_LAN83C185_ISF_INT_PHYLIB_EVENTS \
+	(MII_LAN83C185_ISF_INT6 | MII_LAN83C185_ISF_INT4)
+
+
+static int lan83c185_config_intr(struct phy_device *phydev)
+{
+	int rc = phy_write (phydev, MII_LAN83C185_IM,
+			((PHY_INTERRUPT_ENABLED == phydev->interrupts)
+			? MII_LAN83C185_ISF_INT_PHYLIB_EVENTS
+			: 0));
+
+	return rc < 0 ? rc : 0;
+}
+
+static int lan83c185_ack_interrupt(struct phy_device *phydev)
+{
+	int rc = phy_read (phydev, MII_LAN83C185_ISF);
+
+	return rc < 0 ? rc : 0;
+}
+
+static int lan83c185_config_init(struct phy_device *phydev)
+{
+	return lan83c185_ack_interrupt (phydev);
+}
+
+
+static struct phy_driver lan83c185_driver = {
+	.phy_id		= 0x0007c0a0, /* OUI=0x00800f, Model#=0x0a */
+	.phy_id_mask	= 0xfffffff0,
+	.name		= "SMSC LAN83C185",
+
+	.features	= (PHY_BASIC_FEATURES | SUPPORTED_Pause
+				| SUPPORTED_Asym_Pause),
+	.flags		= PHY_HAS_INTERRUPT | PHY_HAS_MAGICANEG,
+
+	/* basic functions */
+	.config_aneg	= genphy_config_aneg,
+	.read_status	= genphy_read_status,
+	.config_init	= lan83c185_config_init,
+
+	/* IRQ related */
+	.ack_interrupt	= lan83c185_ack_interrupt,
+	.config_intr	= lan83c185_config_intr,
+
+	.driver		= { .owner = THIS_MODULE, }
+};
+
+static int __init smsc_init(void)
+{
+	return phy_driver_register (&lan83c185_driver);
+}
+
+static void __exit smsc_exit(void)
+{
+	phy_driver_unregister (&lan83c185_driver);
+}
+
+MODULE_DESCRIPTION("SMSC PHY driver");
+MODULE_AUTHOR("Herbert Valerio Riedel");
+MODULE_LICENSE("GPL");
+
+module_init(smsc_init);
+module_exit(smsc_exit);
diff --git a/drivers/net/phy/vitesse.c b/drivers/net/phy/vitesse.c
new file mode 100644
index 000000000..792716beb
--- /dev/null
+++ b/drivers/net/phy/vitesse.c
@@ -0,0 +1,111 @@
+/*
+ * Driver for Vitesse PHYs
+ *
+ * Author: Kriston Carson
+ *
+ * Copyright (c) 2005 Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/mii.h>
+#include <linux/ethtool.h>
+#include <linux/phy.h>
+
+/* Vitesse Extended Control Register 1 */
+#define MII_VSC8244_EXT_CON1           0x17
+#define MII_VSC8244_EXTCON1_INIT       0x0000
+
+/* Vitesse Interrupt Mask Register */
+#define MII_VSC8244_IMASK		0x19
+#define MII_VSC8244_IMASK_IEN		0x8000
+#define MII_VSC8244_IMASK_SPEED		0x4000
+#define MII_VSC8244_IMASK_LINK		0x2000
+#define MII_VSC8244_IMASK_DUPLEX	0x1000
+#define MII_VSC8244_IMASK_MASK		0xf000
+
+/* Vitesse Interrupt Status Register */
+#define MII_VSC8244_ISTAT		0x1a
+#define MII_VSC8244_ISTAT_STATUS	0x8000
+#define MII_VSC8244_ISTAT_SPEED		0x4000
+#define MII_VSC8244_ISTAT_LINK		0x2000
+#define MII_VSC8244_ISTAT_DUPLEX	0x1000
+
+/* Vitesse Auxiliary Control/Status Register */
+#define MII_VSC8244_AUX_CONSTAT        	0x1c
+#define MII_VSC8244_AUXCONSTAT_INIT    	0x0004
+#define MII_VSC8244_AUXCONSTAT_DUPLEX  	0x0020
+#define MII_VSC8244_AUXCONSTAT_SPEED   	0x0018
+#define MII_VSC8244_AUXCONSTAT_GBIT    	0x0010
+#define MII_VSC8244_AUXCONSTAT_100     	0x0008
+
+MODULE_DESCRIPTION("Vitesse PHY driver");
+MODULE_AUTHOR("Kriston Carson");
+MODULE_LICENSE("GPL");
+
+static int vsc824x_config_init(struct phy_device *phydev)
+{
+	int err;
+
+	err = phy_write(phydev, MII_VSC8244_AUX_CONSTAT,
+			MII_VSC8244_AUXCONSTAT_INIT);
+	if (err < 0)
+		return err;
+
+	err = phy_write(phydev, MII_VSC8244_EXT_CON1,
+			MII_VSC8244_EXTCON1_INIT);
+	return err;
+}
+
+static int vsc824x_ack_interrupt(struct phy_device *phydev)
+{
+	int err = phy_read(phydev, MII_VSC8244_ISTAT);
+
+	return (err < 0) ? err : 0;
+}
+
+static int vsc824x_config_intr(struct phy_device *phydev)
+{
+	int err;
+
+	if (phydev->interrupts == PHY_INTERRUPT_ENABLED)
+		err = phy_write(phydev, MII_VSC8244_IMASK,
+				MII_VSC8244_IMASK_MASK);
+	else
+		err = phy_write(phydev, MII_VSC8244_IMASK, 0);
+	return err;
+}
+
+/* Vitesse 824x */
+static struct phy_driver vsc8244_driver = {
+	.phy_id		= 0x000fc6c2,
+	.name		= "Vitesse VSC8244",
+	.phy_id_mask	= 0x000fffc0,
+	.features	= PHY_GBIT_FEATURES,
+	.flags		= PHY_HAS_INTERRUPT,
+	.config_init	= &vsc824x_config_init,
+	.config_aneg	= &genphy_config_aneg,
+	.read_status	= &genphy_read_status,
+	.ack_interrupt	= &vsc824x_ack_interrupt,
+	.config_intr	= &vsc824x_config_intr,
+	.driver 	= { .owner = THIS_MODULE,},
+};
+
+static int __init vsc8244_init(void)
+{
+	return phy_driver_register(&vsc8244_driver);
+}
+
+static void __exit vsc8244_exit(void)
+{
+	phy_driver_unregister(&vsc8244_driver);
+}
+
+module_init(vsc8244_init);
+module_exit(vsc8244_exit);
diff --git a/drivers/net/smc911x.c b/drivers/net/smc911x.c
new file mode 100644
index 000000000..4438fe8c9
--- /dev/null
+++ b/drivers/net/smc911x.c
@@ -0,0 +1,2306 @@
+/*
+ * smc911x.c
+ * This is a driver for SMSC's LAN911{5,6,7,8} single-chip Ethernet devices.
+ *
+ * Copyright (C) 2005 Sensoria Corp
+ *	   Derived from the unified SMC91x driver by Nicolas Pitre
+ *	   and the smsc911x.c reference driver by SMSC
+ *
+ * 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
+ *
+ * Arguments:
+ *	 watchdog  = TX watchdog timeout
+ *	 tx_fifo_kb = Size of TX FIFO in KB
+ *
+ * History:
+ *	  04/16/05	Dustin McIntire		 Initial version
+ */
+static const char version[] =
+	 "smc911x.c: v1.0 04-16-2005 by Dustin McIntire <dustin@sensoria.com>\n";
+
+/* Debugging options */
+#define ENABLE_SMC_DEBUG_RX		0
+#define ENABLE_SMC_DEBUG_TX		0
+#define ENABLE_SMC_DEBUG_DMA		0
+#define ENABLE_SMC_DEBUG_PKTS		0
+#define ENABLE_SMC_DEBUG_MISC		0
+#define ENABLE_SMC_DEBUG_FUNC		0
+
+#define SMC_DEBUG_RX		((ENABLE_SMC_DEBUG_RX	? 1 : 0) << 0)
+#define SMC_DEBUG_TX		((ENABLE_SMC_DEBUG_TX	? 1 : 0) << 1)
+#define SMC_DEBUG_DMA		((ENABLE_SMC_DEBUG_DMA	? 1 : 0) << 2)
+#define SMC_DEBUG_PKTS		((ENABLE_SMC_DEBUG_PKTS ? 1 : 0) << 3)
+#define SMC_DEBUG_MISC		((ENABLE_SMC_DEBUG_MISC ? 1 : 0) << 4)
+#define SMC_DEBUG_FUNC		((ENABLE_SMC_DEBUG_FUNC ? 1 : 0) << 5)
+
+#ifndef SMC_DEBUG
+#define SMC_DEBUG	 ( SMC_DEBUG_RX	  | \
+			   SMC_DEBUG_TX	  | \
+			   SMC_DEBUG_DMA  | \
+			   SMC_DEBUG_PKTS | \
+			   SMC_DEBUG_MISC | \
+			   SMC_DEBUG_FUNC   \
+			 )
+#endif
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/errno.h>
+#include <linux/ioport.h>
+#include <linux/crc32.h>
+#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <linux/spinlock.h>
+#include <linux/ethtool.h>
+#include <linux/mii.h>
+#include <linux/workqueue.h>
+
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/skbuff.h>
+
+#include <asm/io.h>
+#include <asm/irq.h>
+
+#include "smc911x.h"
+
+/*
+ * Transmit timeout, default 5 seconds.
+ */
+static int watchdog = 5000;
+module_param(watchdog, int, 0400);
+MODULE_PARM_DESC(watchdog, "transmit timeout in milliseconds");
+
+static int tx_fifo_kb=8;
+module_param(tx_fifo_kb, int, 0400);
+MODULE_PARM_DESC(tx_fifo_kb,"transmit FIFO size in KB (1<x<15)(default=8)");
+
+MODULE_LICENSE("GPL");
+
+/*
+ * The internal workings of the driver.  If you are changing anything
+ * here with the SMC stuff, you should have the datasheet and know
+ * what you are doing.
+ */
+#define CARDNAME "smc911x"
+
+/*
+ * Use power-down feature of the chip
+ */
+#define POWER_DOWN		 1
+
+
+/* store this information for the driver.. */
+struct smc911x_local {
+	/*
+	 * If I have to wait until the DMA is finished and ready to reload a
+	 * packet, I will store the skbuff here. Then, the DMA will send it
+	 * out and free it.
+	 */
+	struct sk_buff *pending_tx_skb;
+
+	/*
+	 * these are things that the kernel wants me to keep, so users
+	 * can find out semi-useless statistics of how well the card is
+	 * performing
+	 */
+	struct net_device_stats stats;
+
+	/* version/revision of the SMC911x chip */
+	u16 version;
+	u16 revision;
+
+	/* FIFO sizes */
+	int tx_fifo_kb;
+	int tx_fifo_size;
+	int rx_fifo_size;
+	int afc_cfg;
+
+	/* Contains the current active receive/phy mode */
+	int ctl_rfduplx;
+	int ctl_rspeed;
+
+	u32 msg_enable;
+	u32 phy_type;
+	struct mii_if_info mii;
+
+	/* work queue */
+	struct work_struct phy_configure;
+	int work_pending;
+
+	int tx_throttle;
+	spinlock_t lock;
+
+#ifdef SMC_USE_DMA
+	/* DMA needs the physical address of the chip */
+	u_long physaddr;
+	int rxdma;
+	int txdma;
+	int rxdma_active;
+	int txdma_active;
+	struct sk_buff *current_rx_skb;
+	struct sk_buff *current_tx_skb;
+	struct device *dev;
+#endif
+};
+
+#if SMC_DEBUG > 0
+#define DBG(n, args...)				 \
+	do {					 \
+		if (SMC_DEBUG & (n))		 \
+			printk(args);		 \
+	} while (0)
+
+#define PRINTK(args...)   printk(args)
+#else
+#define DBG(n, args...)   do { } while (0)
+#define PRINTK(args...)   printk(KERN_DEBUG args)
+#endif
+
+#if SMC_DEBUG_PKTS > 0
+static void PRINT_PKT(u_char *buf, int length)
+{
+	int i;
+	int remainder;
+	int lines;
+
+	lines = length / 16;
+	remainder = length % 16;
+
+	for (i = 0; i < lines ; i ++) {
+		int cur;
+		for (cur = 0; cur < 8; cur++) {
+			u_char a, b;
+			a = *buf++;
+			b = *buf++;
+			printk("%02x%02x ", a, b);
+		}
+		printk("\n");
+	}
+	for (i = 0; i < remainder/2 ; i++) {
+		u_char a, b;
+		a = *buf++;
+		b = *buf++;
+		printk("%02x%02x ", a, b);
+	}
+	printk("\n");
+}
+#else
+#define PRINT_PKT(x...)  do { } while (0)
+#endif
+
+
+/* this enables an interrupt in the interrupt mask register */
+#define SMC_ENABLE_INT(x) do {				\
+	unsigned int  __mask;				\
+	unsigned long __flags;				\
+	spin_lock_irqsave(&lp->lock, __flags);		\
+	__mask = SMC_GET_INT_EN();			\
+	__mask |= (x);					\
+	SMC_SET_INT_EN(__mask);				\
+	spin_unlock_irqrestore(&lp->lock, __flags);	\
+} while (0)
+
+/* this disables an interrupt from the interrupt mask register */
+#define SMC_DISABLE_INT(x) do {				\
+	unsigned int  __mask;				\
+	unsigned long __flags;				\
+	spin_lock_irqsave(&lp->lock, __flags);		\
+	__mask = SMC_GET_INT_EN();			\
+	__mask &= ~(x);					\
+	SMC_SET_INT_EN(__mask);				\
+	spin_unlock_irqrestore(&lp->lock, __flags);	\
+} while (0)
+
+/*
+ * this does a soft reset on the device
+ */
+static void smc911x_reset(struct net_device *dev)
+{
+	unsigned long ioaddr = dev->base_addr;
+	struct smc911x_local *lp = netdev_priv(dev);
+	unsigned int reg, timeout=0, resets=1;
+	unsigned long flags;
+
+	DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __FUNCTION__);
+
+	/*	 Take out of PM setting first */
+	if ((SMC_GET_PMT_CTRL() & PMT_CTRL_READY_) == 0) {
+		/* Write to the bytetest will take out of powerdown */
+		SMC_SET_BYTE_TEST(0);
+		timeout=10;
+		do {
+			udelay(10);
+			reg = SMC_GET_PMT_CTRL() & PMT_CTRL_READY_;
+		} while ( timeout-- && !reg);
+		if (timeout == 0) {
+			PRINTK("%s: smc911x_reset timeout waiting for PM restore\n", dev->name);
+			return;
+		}
+	}
+
+	/* Disable all interrupts */
+	spin_lock_irqsave(&lp->lock, flags);
+	SMC_SET_INT_EN(0);
+	spin_unlock_irqrestore(&lp->lock, flags);
+
+	while (resets--) {
+		SMC_SET_HW_CFG(HW_CFG_SRST_);
+		timeout=10;
+		do {
+			udelay(10);
+			reg = SMC_GET_HW_CFG();
+			/* If chip indicates reset timeout then try again */
+			if (reg & HW_CFG_SRST_TO_) {
+				PRINTK("%s: chip reset timeout, retrying...\n", dev->name);
+				resets++;
+				break;
+			}
+		} while ( timeout-- && (reg & HW_CFG_SRST_));
+	}
+	if (timeout == 0) {
+		PRINTK("%s: smc911x_reset timeout waiting for reset\n", dev->name);
+		return;
+	}
+
+	/* make sure EEPROM has finished loading before setting GPIO_CFG */
+	timeout=1000;
+	while ( timeout-- && (SMC_GET_E2P_CMD() & E2P_CMD_EPC_BUSY_)) {
+		udelay(10);
+	}
+	if (timeout == 0){
+		PRINTK("%s: smc911x_reset timeout waiting for EEPROM busy\n", dev->name);
+		return;
+	}
+
+	/* Initialize interrupts */
+	SMC_SET_INT_EN(0);
+	SMC_ACK_INT(-1);
+
+	/* Reset the FIFO level and flow control settings */
+	SMC_SET_HW_CFG((lp->tx_fifo_kb & 0xF) << 16);
+//TODO: Figure out what appropriate pause time is
+	SMC_SET_FLOW(FLOW_FCPT_ | FLOW_FCEN_);
+	SMC_SET_AFC_CFG(lp->afc_cfg);
+
+
+	/* Set to LED outputs */
+	SMC_SET_GPIO_CFG(0x70070000);
+
+	/*
+	 * Deassert IRQ for 1*10us for edge type interrupts
+	 * and drive IRQ pin push-pull
+	 */
+	SMC_SET_IRQ_CFG( (1 << 24) | INT_CFG_IRQ_EN_ | INT_CFG_IRQ_TYPE_ );
+
+	/* clear anything saved */
+	if (lp->pending_tx_skb != NULL) {
+		dev_kfree_skb (lp->pending_tx_skb);
+		lp->pending_tx_skb = NULL;
+		lp->stats.tx_errors++;
+		lp->stats.tx_aborted_errors++;
+	}
+}
+
+/*
+ * Enable Interrupts, Receive, and Transmit
+ */
+static void smc911x_enable(struct net_device *dev)
+{
+	unsigned long ioaddr = dev->base_addr;
+	struct smc911x_local *lp = netdev_priv(dev);
+	unsigned mask, cfg, cr;
+	unsigned long flags;
+
+	DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __FUNCTION__);
+
+	SMC_SET_MAC_ADDR(dev->dev_addr);
+
+	/* Enable TX */
+	cfg = SMC_GET_HW_CFG();
+	cfg &= HW_CFG_TX_FIF_SZ_ | 0xFFF;
+	cfg |= HW_CFG_SF_;
+	SMC_SET_HW_CFG(cfg);
+	SMC_SET_FIFO_TDA(0xFF);
+	/* Update TX stats on every 64 packets received or every 1 sec */
+	SMC_SET_FIFO_TSL(64);
+	SMC_SET_GPT_CFG(GPT_CFG_TIMER_EN_ | 10000);
+
+	spin_lock_irqsave(&lp->lock, flags);
+	SMC_GET_MAC_CR(cr);
+	cr |= MAC_CR_TXEN_ | MAC_CR_HBDIS_;
+	SMC_SET_MAC_CR(cr);
+	SMC_SET_TX_CFG(TX_CFG_TX_ON_);
+	spin_unlock_irqrestore(&lp->lock, flags);
+
+	/* Add 2 byte padding to start of packets */
+	SMC_SET_RX_CFG((2<<8) & RX_CFG_RXDOFF_);
+
+	/* Turn on receiver and enable RX */
+	if (cr & MAC_CR_RXEN_)
+		DBG(SMC_DEBUG_RX, "%s: Receiver already enabled\n", dev->name);
+
+	spin_lock_irqsave(&lp->lock, flags);
+	SMC_SET_MAC_CR( cr | MAC_CR_RXEN_ );
+	spin_unlock_irqrestore(&lp->lock, flags);
+
+	/* Interrupt on every received packet */
+	SMC_SET_FIFO_RSA(0x01);
+	SMC_SET_FIFO_RSL(0x00);
+
+	/* now, enable interrupts */
+	mask = INT_EN_TDFA_EN_ | INT_EN_TSFL_EN_ | INT_EN_RSFL_EN_ |
+		INT_EN_GPT_INT_EN_ | INT_EN_RXDFH_INT_EN_ | INT_EN_RXE_EN_ |
+		INT_EN_PHY_INT_EN_;
+	if (IS_REV_A(lp->revision))
+		mask|=INT_EN_RDFL_EN_;
+	else {
+		mask|=INT_EN_RDFO_EN_;
+	}
+	SMC_ENABLE_INT(mask);
+}
+
+/*
+ * this puts the device in an inactive state
+ */
+static void smc911x_shutdown(struct net_device *dev)
+{
+	unsigned long ioaddr = dev->base_addr;
+	struct smc911x_local *lp = netdev_priv(dev);
+	unsigned cr;
+	unsigned long flags;
+
+	DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", CARDNAME, __FUNCTION__);
+
+	/* Disable IRQ's */
+	SMC_SET_INT_EN(0);
+
+	/* Turn of Rx and TX */
+	spin_lock_irqsave(&lp->lock, flags);
+	SMC_GET_MAC_CR(cr);
+	cr &= ~(MAC_CR_TXEN_ | MAC_CR_RXEN_ | MAC_CR_HBDIS_);
+	SMC_SET_MAC_CR(cr);
+	SMC_SET_TX_CFG(TX_CFG_STOP_TX_);
+	spin_unlock_irqrestore(&lp->lock, flags);
+}
+
+static inline void smc911x_drop_pkt(struct net_device *dev)
+{
+	unsigned long ioaddr = dev->base_addr;
+	unsigned int fifo_count, timeout, reg;
+
+	DBG(SMC_DEBUG_FUNC | SMC_DEBUG_RX, "%s: --> %s\n", CARDNAME, __FUNCTION__);
+	fifo_count = SMC_GET_RX_FIFO_INF() & 0xFFFF;
+	if (fifo_count <= 4) {
+		/* Manually dump the packet data */
+		while (fifo_count--)
+			SMC_GET_RX_FIFO();
+	} else	 {
+		/* Fast forward through the bad packet */
+		SMC_SET_RX_DP_CTRL(RX_DP_CTRL_FFWD_BUSY_);
+		timeout=50;
+		do {
+			udelay(10);
+			reg = SMC_GET_RX_DP_CTRL() & RX_DP_CTRL_FFWD_BUSY_;
+		} while ( timeout-- && reg);
+		if (timeout == 0) {
+			PRINTK("%s: timeout waiting for RX fast forward\n", dev->name);
+		}
+	}
+}
+
+/*
+ * This is the procedure to handle the receipt of a packet.
+ * It should be called after checking for packet presence in
+ * the RX status FIFO.	 It must be called with the spin lock
+ * already held.
+ */
+static inline void	 smc911x_rcv(struct net_device *dev)
+{
+	struct smc911x_local *lp = netdev_priv(dev);
+	unsigned long ioaddr = dev->base_addr;
+	unsigned int pkt_len, status;
+	struct sk_buff *skb;
+	unsigned char *data;
+
+	DBG(SMC_DEBUG_FUNC | SMC_DEBUG_RX, "%s: --> %s\n",
+		dev->name, __FUNCTION__);
+	status = SMC_GET_RX_STS_FIFO();
+	DBG(SMC_DEBUG_RX, "%s: Rx pkt len %d status 0x%08x \n",
+		dev->name, (status & 0x3fff0000) >> 16, status & 0xc000ffff);
+	pkt_len = (status & RX_STS_PKT_LEN_) >> 16;
+	if (status & RX_STS_ES_) {
+		/* Deal with a bad packet */
+		lp->stats.rx_errors++;
+		if (status & RX_STS_CRC_ERR_)
+			lp->stats.rx_crc_errors++;
+		else {
+			if (status & RX_STS_LEN_ERR_)
+				lp->stats.rx_length_errors++;
+			if (status & RX_STS_MCAST_)
+				lp->stats.multicast++;
+		}
+		/* Remove the bad packet data from the RX FIFO */
+		smc911x_drop_pkt(dev);
+	} else {
+		/* Receive a valid packet */
+		/* Alloc a buffer with extra room for DMA alignment */
+		skb=dev_alloc_skb(pkt_len+32);
+		if (unlikely(skb == NULL)) {
+			PRINTK( "%s: Low memory, rcvd packet dropped.\n",
+				dev->name);
+			lp->stats.rx_dropped++;
+			smc911x_drop_pkt(dev);
+			return;
+		}
+		/* Align IP header to 32 bits
+		 * Note that the device is configured to add a 2
+		 * byte padding to the packet start, so we really
+		 * want to write to the orignal data pointer */
+		data = skb->data;
+		skb_reserve(skb, 2);
+		skb_put(skb,pkt_len-4);
+#ifdef SMC_USE_DMA
+		{
+		unsigned int fifo;
+		/* Lower the FIFO threshold if possible */
+		fifo = SMC_GET_FIFO_INT();
+		if (fifo & 0xFF) fifo--;
+		DBG(SMC_DEBUG_RX, "%s: Setting RX stat FIFO threshold to %d\n",
+			dev->name, fifo & 0xff);
+		SMC_SET_FIFO_INT(fifo);
+		/* Setup RX DMA */
+		SMC_SET_RX_CFG(RX_CFG_RX_END_ALGN16_ | ((2<<8) & RX_CFG_RXDOFF_));
+		lp->rxdma_active = 1;
+		lp->current_rx_skb = skb;
+		SMC_PULL_DATA(data, (pkt_len+2+15) & ~15);
+		/* Packet processing deferred to DMA RX interrupt */
+		}
+#else
+		SMC_SET_RX_CFG(RX_CFG_RX_END_ALGN4_ | ((2<<8) & RX_CFG_RXDOFF_));
+		SMC_PULL_DATA(data, pkt_len+2+3);
+
+		DBG(SMC_DEBUG_PKTS, "%s: Received packet\n", dev->name,);
+		PRINT_PKT(data, ((pkt_len - 4) <= 64) ? pkt_len - 4 : 64);
+		dev->last_rx = jiffies;
+		skb->dev = dev;
+		skb->protocol = eth_type_trans(skb, dev);
+		netif_rx(skb);
+		lp->stats.rx_packets++;
+		lp->stats.rx_bytes += pkt_len-4;
+#endif
+	}
+}
+
+/*
+ * This is called to actually send a packet to the chip.
+ */
+static void smc911x_hardware_send_pkt(struct net_device *dev)
+{
+	struct smc911x_local *lp = netdev_priv(dev);
+	unsigned long ioaddr = dev->base_addr;
+	struct sk_buff *skb;
+	unsigned int cmdA, cmdB, len;
+	unsigned char *buf;
+	unsigned long flags;
+
+	DBG(SMC_DEBUG_FUNC | SMC_DEBUG_TX, "%s: --> %s\n", dev->name, __FUNCTION__);
+	BUG_ON(lp->pending_tx_skb == NULL);
+
+	skb = lp->pending_tx_skb;
+	lp->pending_tx_skb = NULL;
+
+	/* cmdA {25:24] data alignment [20:16] start offset [10:0] buffer length */
+	/* cmdB {31:16] pkt tag [10:0] length */
+#ifdef SMC_USE_DMA
+	/* 16 byte buffer alignment mode */
+	buf = (char*)((u32)(skb->data) & ~0xF);
+	len = (skb->len + 0xF + ((u32)skb->data & 0xF)) & ~0xF;
+	cmdA = (1<<24) | (((u32)skb->data & 0xF)<<16) |
+			TX_CMD_A_INT_FIRST_SEG_ | TX_CMD_A_INT_LAST_SEG_ |
+			skb->len;
+#else
+	buf = (char*)((u32)skb->data & ~0x3);
+	len = (skb->len + 3 + ((u32)skb->data & 3)) & ~0x3;
+	cmdA = (((u32)skb->data & 0x3) << 16) |
+			TX_CMD_A_INT_FIRST_SEG_ | TX_CMD_A_INT_LAST_SEG_ |
+			skb->len;
+#endif
+	/* tag is packet length so we can use this in stats update later */
+	cmdB = (skb->len  << 16) | (skb->len & 0x7FF);
+
+	DBG(SMC_DEBUG_TX, "%s: TX PKT LENGTH 0x%04x (%d) BUF 0x%p CMDA 0x%08x CMDB 0x%08x\n",
+		 dev->name, len, len, buf, cmdA, cmdB);
+	SMC_SET_TX_FIFO(cmdA);
+	SMC_SET_TX_FIFO(cmdB);
+
+	DBG(SMC_DEBUG_PKTS, "%s: Transmitted packet\n", dev->name);
+	PRINT_PKT(buf, len <= 64 ? len : 64);
+
+	/* Send pkt via PIO or DMA */
+#ifdef SMC_USE_DMA
+	lp->current_tx_skb = skb;
+	SMC_PUSH_DATA(buf, len);
+	/* DMA complete IRQ will free buffer and set jiffies */
+#else
+	SMC_PUSH_DATA(buf, len);
+	dev->trans_start = jiffies;
+	dev_kfree_skb(skb);
+#endif
+	spin_lock_irqsave(&lp->lock, flags);
+	if (!lp->tx_throttle) {
+		netif_wake_queue(dev);
+	}
+	spin_unlock_irqrestore(&lp->lock, flags);
+	SMC_ENABLE_INT(INT_EN_TDFA_EN_ | INT_EN_TSFL_EN_);
+}
+
+/*
+ * Since I am not sure if I will have enough room in the chip's ram
+ * to store the packet, I call this routine which either sends it
+ * now, or set the card to generates an interrupt when ready
+ * for the packet.
+ */
+static int smc911x_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+	struct smc911x_local *lp = netdev_priv(dev);
+	unsigned long ioaddr = dev->base_addr;
+	unsigned int free;
+	unsigned long flags;
+
+	DBG(SMC_DEBUG_FUNC | SMC_DEBUG_TX, "%s: --> %s\n",
+		dev->name, __FUNCTION__);
+
+	BUG_ON(lp->pending_tx_skb != NULL);
+
+	free = SMC_GET_TX_FIFO_INF() & TX_FIFO_INF_TDFREE_;
+	DBG(SMC_DEBUG_TX, "%s: TX free space %d\n", dev->name, free);
+
+	/* Turn off the flow when running out of space in FIFO */
+	if (free <= SMC911X_TX_FIFO_LOW_THRESHOLD) {
+		DBG(SMC_DEBUG_TX, "%s: Disabling data flow due to low FIFO space (%d)\n",
+			dev->name, free);
+		spin_lock_irqsave(&lp->lock, flags);
+		/* Reenable when at least 1 packet of size MTU present */
+		SMC_SET_FIFO_TDA((SMC911X_TX_FIFO_LOW_THRESHOLD)/64);
+		lp->tx_throttle = 1;
+		netif_stop_queue(dev);
+		spin_unlock_irqrestore(&lp->lock, flags);
+	}
+
+	/* Drop packets when we run out of space in TX FIFO
+	 * Account for overhead required for:
+	 *
+	 *	  Tx command words			 8 bytes
+	 *	  Start offset				 15 bytes
+	 *	  End padding				 15 bytes
+	 */
+	if (unlikely(free < (skb->len + 8 + 15 + 15))) {
+		printk("%s: No Tx free space %d < %d\n",
+			dev->name, free, skb->len);
+		lp->pending_tx_skb = NULL;
+		lp->stats.tx_errors++;
+		lp->stats.tx_dropped++;
+		dev_kfree_skb(skb);
+		return 0;
+	}
+
+#ifdef SMC_USE_DMA
+	{
+		/* If the DMA is already running then defer this packet Tx until
+		 * the DMA IRQ starts it
+		 */
+		spin_lock_irqsave(&lp->lock, flags);
+		if (lp->txdma_active) {
+			DBG(SMC_DEBUG_TX | SMC_DEBUG_DMA, "%s: Tx DMA running, deferring packet\n", dev->name);
+			lp->pending_tx_skb = skb;
+			netif_stop_queue(dev);
+			spin_unlock_irqrestore(&lp->lock, flags);
+			return 0;
+		} else {
+			DBG(SMC_DEBUG_TX | SMC_DEBUG_DMA, "%s: Activating Tx DMA\n", dev->name);
+			lp->txdma_active = 1;
+		}
+		spin_unlock_irqrestore(&lp->lock, flags);
+	}
+#endif
+	lp->pending_tx_skb = skb;
+	smc911x_hardware_send_pkt(dev);
+
+	return 0;
+}
+
+/*
+ * This handles a TX status interrupt, which is only called when:
+ * - a TX error occurred, or
+ * - TX of a packet completed.
+ */
+static void smc911x_tx(struct net_device *dev)
+{
+	unsigned long ioaddr = dev->base_addr;
+	struct smc911x_local *lp = netdev_priv(dev);
+	unsigned int tx_status;
+
+	DBG(SMC_DEBUG_FUNC | SMC_DEBUG_TX, "%s: --> %s\n",
+		dev->name, __FUNCTION__);
+
+	/* Collect the TX status */
+	while (((SMC_GET_TX_FIFO_INF() & TX_FIFO_INF_TSUSED_) >> 16) != 0) {
+		DBG(SMC_DEBUG_TX, "%s: Tx stat FIFO used 0x%04x\n",
+			dev->name,
+			(SMC_GET_TX_FIFO_INF() & TX_FIFO_INF_TSUSED_) >> 16);
+		tx_status = SMC_GET_TX_STS_FIFO();
+		lp->stats.tx_packets++;
+		lp->stats.tx_bytes+=tx_status>>16;
+		DBG(SMC_DEBUG_TX, "%s: Tx FIFO tag 0x%04x status 0x%04x\n",
+			dev->name, (tx_status & 0xffff0000) >> 16,
+			tx_status & 0x0000ffff);
+		/* count Tx errors, but ignore lost carrier errors when in
+		 * full-duplex mode */
+		if ((tx_status & TX_STS_ES_) && !(lp->ctl_rfduplx &&
+		    !(tx_status & 0x00000306))) {
+			lp->stats.tx_errors++;
+		}
+		if (tx_status & TX_STS_MANY_COLL_) {
+			lp->stats.collisions+=16;
+			lp->stats.tx_aborted_errors++;
+		} else {
+			lp->stats.collisions+=(tx_status & TX_STS_COLL_CNT_) >> 3;
+		}
+		/* carrier error only has meaning for half-duplex communication */
+		if ((tx_status & (TX_STS_LOC_ | TX_STS_NO_CARR_)) &&
+		    !lp->ctl_rfduplx) {
+			lp->stats.tx_carrier_errors++;
+		}
+		if (tx_status & TX_STS_LATE_COLL_) {
+			lp->stats.collisions++;
+			lp->stats.tx_aborted_errors++;
+		}
+	}
+}
+
+
+/*---PHY CONTROL AND CONFIGURATION-----------------------------------------*/
+/*
+ * Reads a register from the MII Management serial interface
+ */
+
+static int smc911x_phy_read(struct net_device *dev, int phyaddr, int phyreg)
+{
+	unsigned long ioaddr = dev->base_addr;
+	unsigned int phydata;
+
+	SMC_GET_MII(phyreg, phyaddr, phydata);
+
+	DBG(SMC_DEBUG_MISC, "%s: phyaddr=0x%x, phyreg=0x%02x, phydata=0x%04x\n",
+		__FUNCTION__, phyaddr, phyreg, phydata);
+	return phydata;
+}
+
+
+/*
+ * Writes a register to the MII Management serial interface
+ */
+static void smc911x_phy_write(struct net_device *dev, int phyaddr, int phyreg,
+			int phydata)
+{
+	unsigned long ioaddr = dev->base_addr;
+
+	DBG(SMC_DEBUG_MISC, "%s: phyaddr=0x%x, phyreg=0x%x, phydata=0x%x\n",
+		__FUNCTION__, phyaddr, phyreg, phydata);
+
+	SMC_SET_MII(phyreg, phyaddr, phydata);
+}
+
+/*
+ * Finds and reports the PHY address (115 and 117 have external
+ * PHY interface 118 has internal only
+ */
+static void smc911x_phy_detect(struct net_device *dev)
+{
+	unsigned long ioaddr = dev->base_addr;
+	struct smc911x_local *lp = netdev_priv(dev);
+	int phyaddr;
+	unsigned int cfg, id1, id2;
+
+	DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __FUNCTION__);
+
+	lp->phy_type = 0;
+
+	/*
+	 * Scan all 32 PHY addresses if necessary, starting at
+	 * PHY#1 to PHY#31, and then PHY#0 last.
+	 */
+	switch(lp->version) {
+		case 0x115:
+		case 0x117:
+			cfg = SMC_GET_HW_CFG();
+			if (cfg & HW_CFG_EXT_PHY_DET_) {
+				cfg &= ~HW_CFG_PHY_CLK_SEL_;
+				cfg |= HW_CFG_PHY_CLK_SEL_CLK_DIS_;
+				SMC_SET_HW_CFG(cfg);
+				udelay(10); /* Wait for clocks to stop */
+
+				cfg |= HW_CFG_EXT_PHY_EN_;
+				SMC_SET_HW_CFG(cfg);
+				udelay(10); /* Wait for clocks to stop */
+
+				cfg &= ~HW_CFG_PHY_CLK_SEL_;
+				cfg |= HW_CFG_PHY_CLK_SEL_EXT_PHY_;
+				SMC_SET_HW_CFG(cfg);
+				udelay(10); /* Wait for clocks to stop */
+
+				cfg |= HW_CFG_SMI_SEL_;
+				SMC_SET_HW_CFG(cfg);
+
+				for (phyaddr = 1; phyaddr < 32; ++phyaddr) {
+
+					/* Read the PHY identifiers */
+					SMC_GET_PHY_ID1(phyaddr & 31, id1);
+					SMC_GET_PHY_ID2(phyaddr & 31, id2);
+
+					/* Make sure it is a valid identifier */
+					if (id1 != 0x0000 && id1 != 0xffff &&
+					    id1 != 0x8000 && id2 != 0x0000 &&
+					    id2 != 0xffff && id2 != 0x8000) {
+						/* Save the PHY's address */
+						lp->mii.phy_id = phyaddr & 31;
+						lp->phy_type = id1 << 16 | id2;
+						break;
+					}
+				}
+			}
+		default:
+			/* Internal media only */
+			SMC_GET_PHY_ID1(1, id1);
+			SMC_GET_PHY_ID2(1, id2);
+			/* Save the PHY's address */
+			lp->mii.phy_id = 1;
+			lp->phy_type = id1 << 16 | id2;
+	}
+
+	DBG(SMC_DEBUG_MISC, "%s: phy_id1=0x%x, phy_id2=0x%x phyaddr=0x%d\n",
+		dev->name, id1, id2, lp->mii.phy_id);
+}
+
+/*
+ * Sets the PHY to a configuration as determined by the user.
+ * Called with spin_lock held.
+ */
+static int smc911x_phy_fixed(struct net_device *dev)
+{
+	struct smc911x_local *lp = netdev_priv(dev);
+	unsigned long ioaddr = dev->base_addr;
+	int phyaddr = lp->mii.phy_id;
+	int bmcr;
+
+	DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __FUNCTION__);
+
+	/* Enter Link Disable state */
+	SMC_GET_PHY_BMCR(phyaddr, bmcr);
+	bmcr |= BMCR_PDOWN;
+	SMC_SET_PHY_BMCR(phyaddr, bmcr);
+
+	/*
+	 * Set our fixed capabilities
+	 * Disable auto-negotiation
+	 */
+	bmcr &= ~BMCR_ANENABLE;
+	if (lp->ctl_rfduplx)
+		bmcr |= BMCR_FULLDPLX;
+
+	if (lp->ctl_rspeed == 100)
+		bmcr |= BMCR_SPEED100;
+
+	/* Write our capabilities to the phy control register */
+	SMC_SET_PHY_BMCR(phyaddr, bmcr);
+
+	/* Re-Configure the Receive/Phy Control register */
+	bmcr &= ~BMCR_PDOWN;
+	SMC_SET_PHY_BMCR(phyaddr, bmcr);
+
+	return 1;
+}
+
+/*
+ * smc911x_phy_reset - reset the phy
+ * @dev: net device
+ * @phy: phy address
+ *
+ * Issue a software reset for the specified PHY and
+ * wait up to 100ms for the reset to complete.	 We should
+ * not access the PHY for 50ms after issuing the reset.
+ *
+ * The time to wait appears to be dependent on the PHY.
+ *
+ */
+static int smc911x_phy_reset(struct net_device *dev, int phy)
+{
+	struct smc911x_local *lp = netdev_priv(dev);
+	unsigned long ioaddr = dev->base_addr;
+	int timeout;
+	unsigned long flags;
+	unsigned int reg;
+
+	DBG(SMC_DEBUG_FUNC, "%s: --> %s()\n", dev->name, __FUNCTION__);
+
+	spin_lock_irqsave(&lp->lock, flags);
+	reg = SMC_GET_PMT_CTRL();
+	reg &= ~0xfffff030;
+	reg |= PMT_CTRL_PHY_RST_;
+	SMC_SET_PMT_CTRL(reg);
+	spin_unlock_irqrestore(&lp->lock, flags);
+	for (timeout = 2; timeout; timeout--) {
+		msleep(50);
+		spin_lock_irqsave(&lp->lock, flags);
+		reg = SMC_GET_PMT_CTRL();
+		spin_unlock_irqrestore(&lp->lock, flags);
+		if (!(reg & PMT_CTRL_PHY_RST_)) {
+			/* extra delay required because the phy may
+			 * not be completed with its reset
+			 * when PHY_BCR_RESET_ is cleared. 256us
+			 * should suffice, but use 500us to be safe
+			 */
+			udelay(500);
+		break;
+		}
+	}
+
+	return reg & PMT_CTRL_PHY_RST_;
+}
+
+/*
+ * smc911x_phy_powerdown - powerdown phy
+ * @dev: net device
+ * @phy: phy address
+ *
+ * Power down the specified PHY
+ */
+static void smc911x_phy_powerdown(struct net_device *dev, int phy)
+{
+	unsigned long ioaddr = dev->base_addr;
+	unsigned int bmcr;
+
+	/* Enter Link Disable state */
+	SMC_GET_PHY_BMCR(phy, bmcr);
+	bmcr |= BMCR_PDOWN;
+	SMC_SET_PHY_BMCR(phy, bmcr);
+}
+
+/*
+ * smc911x_phy_check_media - check the media status and adjust BMCR
+ * @dev: net device
+ * @init: set true for initialisation
+ *
+ * Select duplex mode depending on negotiation state.	This
+ * also updates our carrier state.
+ */
+static void smc911x_phy_check_media(struct net_device *dev, int init)
+{
+	struct smc911x_local *lp = netdev_priv(dev);
+	unsigned long ioaddr = dev->base_addr;
+	int phyaddr = lp->mii.phy_id;
+	unsigned int bmcr, cr;
+
+	DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __FUNCTION__);
+
+	if (mii_check_media(&lp->mii, netif_msg_link(lp), init)) {
+		/* duplex state has changed */
+		SMC_GET_PHY_BMCR(phyaddr, bmcr);
+		SMC_GET_MAC_CR(cr);
+		if (lp->mii.full_duplex) {
+			DBG(SMC_DEBUG_MISC, "%s: Configuring for full-duplex mode\n", dev->name);
+			bmcr |= BMCR_FULLDPLX;
+			cr |= MAC_CR_RCVOWN_;
+		} else {
+			DBG(SMC_DEBUG_MISC, "%s: Configuring for half-duplex mode\n", dev->name);
+			bmcr &= ~BMCR_FULLDPLX;
+			cr &= ~MAC_CR_RCVOWN_;
+		}
+		SMC_SET_PHY_BMCR(phyaddr, bmcr);
+		SMC_SET_MAC_CR(cr);
+	}
+}
+
+/*
+ * Configures the specified PHY through the MII management interface
+ * using Autonegotiation.
+ * Calls smc911x_phy_fixed() if the user has requested a certain config.
+ * If RPC ANEG bit is set, the media selection is dependent purely on
+ * the selection by the MII (either in the MII BMCR reg or the result
+ * of autonegotiation.)  If the RPC ANEG bit is cleared, the selection
+ * is controlled by the RPC SPEED and RPC DPLX bits.
+ */
+static void smc911x_phy_configure(void *data)
+{
+	struct net_device *dev = data;
+	struct smc911x_local *lp = netdev_priv(dev);
+	unsigned long ioaddr = dev->base_addr;
+	int phyaddr = lp->mii.phy_id;
+	int my_phy_caps; /* My PHY capabilities */
+	int my_ad_caps; /* My Advertised capabilities */
+	int status;
+	unsigned long flags;
+
+	DBG(SMC_DEBUG_FUNC, "%s: --> %s()\n", dev->name, __FUNCTION__);
+
+	/*
+	 * We should not be called if phy_type is zero.
+	 */
+	if (lp->phy_type == 0)
+		 goto smc911x_phy_configure_exit;
+
+	if (smc911x_phy_reset(dev, phyaddr)) {
+		printk("%s: PHY reset timed out\n", dev->name);
+		goto smc911x_phy_configure_exit;
+	}
+	spin_lock_irqsave(&lp->lock, flags);
+
+	/*
+	 * Enable PHY Interrupts (for register 18)
+	 * Interrupts listed here are enabled
+	 */
+	SMC_SET_PHY_INT_MASK(phyaddr, PHY_INT_MASK_ENERGY_ON_ |
+		 PHY_INT_MASK_ANEG_COMP_ | PHY_INT_MASK_REMOTE_FAULT_ |
+		 PHY_INT_MASK_LINK_DOWN_);
+
+	/* If the user requested no auto neg, then go set his request */
+	if (lp->mii.force_media) {
+		smc911x_phy_fixed(dev);
+		goto smc911x_phy_configure_exit;
+	}
+
+	/* Copy our capabilities from MII_BMSR to MII_ADVERTISE */
+	SMC_GET_PHY_BMSR(phyaddr, my_phy_caps);
+	if (!(my_phy_caps & BMSR_ANEGCAPABLE)) {
+		printk(KERN_INFO "Auto negotiation NOT supported\n");
+		smc911x_phy_fixed(dev);
+		goto smc911x_phy_configure_exit;
+	}
+
+	/* CSMA capable w/ both pauses */
+	my_ad_caps = ADVERTISE_CSMA | ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM;
+
+	if (my_phy_caps & BMSR_100BASE4)
+		my_ad_caps |= ADVERTISE_100BASE4;
+	if (my_phy_caps & BMSR_100FULL)
+		my_ad_caps |= ADVERTISE_100FULL;
+	if (my_phy_caps & BMSR_100HALF)
+		my_ad_caps |= ADVERTISE_100HALF;
+	if (my_phy_caps & BMSR_10FULL)
+		my_ad_caps |= ADVERTISE_10FULL;
+	if (my_phy_caps & BMSR_10HALF)
+		my_ad_caps |= ADVERTISE_10HALF;
+
+	/* Disable capabilities not selected by our user */
+	if (lp->ctl_rspeed != 100)
+		my_ad_caps &= ~(ADVERTISE_100BASE4|ADVERTISE_100FULL|ADVERTISE_100HALF);
+
+	 if (!lp->ctl_rfduplx)
+		my_ad_caps &= ~(ADVERTISE_100FULL|ADVERTISE_10FULL);
+
+	/* Update our Auto-Neg Advertisement Register */
+	SMC_SET_PHY_MII_ADV(phyaddr, my_ad_caps);
+	lp->mii.advertising = my_ad_caps;
+
+	/*
+	 * Read the register back.	 Without this, it appears that when
+	 * auto-negotiation is restarted, sometimes it isn't ready and
+	 * the link does not come up.
+	 */
+	udelay(10);
+	SMC_GET_PHY_MII_ADV(phyaddr, status);
+
+	DBG(SMC_DEBUG_MISC, "%s: phy caps=0x%04x\n", dev->name, my_phy_caps);
+	DBG(SMC_DEBUG_MISC, "%s: phy advertised caps=0x%04x\n", dev->name, my_ad_caps);
+
+	/* Restart auto-negotiation process in order to advertise my caps */
+	SMC_SET_PHY_BMCR(phyaddr, BMCR_ANENABLE | BMCR_ANRESTART);
+
+	smc911x_phy_check_media(dev, 1);
+
+smc911x_phy_configure_exit:
+	spin_unlock_irqrestore(&lp->lock, flags);
+	lp->work_pending = 0;
+}
+
+/*
+ * smc911x_phy_interrupt
+ *
+ * Purpose:  Handle interrupts relating to PHY register 18. This is
+ *	 called from the "hard" interrupt handler under our private spinlock.
+ */
+static void smc911x_phy_interrupt(struct net_device *dev)
+{
+	struct smc911x_local *lp = netdev_priv(dev);
+	unsigned long ioaddr = dev->base_addr;
+	int phyaddr = lp->mii.phy_id;
+	int status;
+
+	DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __FUNCTION__);
+
+	if (lp->phy_type == 0)
+		return;
+
+	smc911x_phy_check_media(dev, 0);
+	/* read to clear status bits */
+	SMC_GET_PHY_INT_SRC(phyaddr,status);
+	DBG(SMC_DEBUG_MISC, "%s: PHY interrupt status 0x%04x\n",
+		dev->name, status & 0xffff);
+	DBG(SMC_DEBUG_MISC, "%s: AFC_CFG 0x%08x\n",
+		dev->name, SMC_GET_AFC_CFG());
+}
+
+/*--- END PHY CONTROL AND CONFIGURATION-------------------------------------*/
+
+/*
+ * This is the main routine of the driver, to handle the device when
+ * it needs some attention.
+ */
+static irqreturn_t smc911x_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	struct net_device *dev = dev_id;
+	unsigned long ioaddr = dev->base_addr;
+	struct smc911x_local *lp = netdev_priv(dev);
+	unsigned int status, mask, timeout;
+	unsigned int rx_overrun=0, cr, pkts;
+	unsigned long flags;
+
+	DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __FUNCTION__);
+
+	spin_lock_irqsave(&lp->lock, flags);
+
+	/* Spurious interrupt check */
+	if ((SMC_GET_IRQ_CFG() & (INT_CFG_IRQ_INT_ | INT_CFG_IRQ_EN_)) !=
+		(INT_CFG_IRQ_INT_ | INT_CFG_IRQ_EN_)) {
+		spin_unlock_irqrestore(&lp->lock, flags);
+		return IRQ_NONE;
+	}
+
+	mask = SMC_GET_INT_EN();
+	SMC_SET_INT_EN(0);
+
+	/* set a timeout value, so I don't stay here forever */
+	timeout = 8;
+
+
+	do {
+		status = SMC_GET_INT();
+
+		DBG(SMC_DEBUG_MISC, "%s: INT 0x%08x MASK 0x%08x OUTSIDE MASK 0x%08x\n",
+			dev->name, status, mask, status & ~mask);
+
+		status &= mask;
+		if (!status)
+			break;
+
+		/* Handle SW interrupt condition */
+		if (status & INT_STS_SW_INT_) {
+			SMC_ACK_INT(INT_STS_SW_INT_);
+			mask &= ~INT_EN_SW_INT_EN_;
+		}
+		/* Handle various error conditions */
+		if (status & INT_STS_RXE_) {
+			SMC_ACK_INT(INT_STS_RXE_);
+			lp->stats.rx_errors++;
+		}
+		if (status & INT_STS_RXDFH_INT_) {
+			SMC_ACK_INT(INT_STS_RXDFH_INT_);
+			lp->stats.rx_dropped+=SMC_GET_RX_DROP();
+		 }
+		/* Undocumented interrupt-what is the right thing to do here? */
+		if (status & INT_STS_RXDF_INT_) {
+			SMC_ACK_INT(INT_STS_RXDF_INT_);
+		}
+
+		/* Rx Data FIFO exceeds set level */
+		if (status & INT_STS_RDFL_) {
+			if (IS_REV_A(lp->revision)) {
+				rx_overrun=1;
+				SMC_GET_MAC_CR(cr);
+				cr &= ~MAC_CR_RXEN_;
+				SMC_SET_MAC_CR(cr);
+				DBG(SMC_DEBUG_RX, "%s: RX overrun\n", dev->name);
+				lp->stats.rx_errors++;
+				lp->stats.rx_fifo_errors++;
+			}
+			SMC_ACK_INT(INT_STS_RDFL_);
+		}
+		if (status & INT_STS_RDFO_) {
+			if (!IS_REV_A(lp->revision)) {
+				SMC_GET_MAC_CR(cr);
+				cr &= ~MAC_CR_RXEN_;
+				SMC_SET_MAC_CR(cr);
+				rx_overrun=1;
+				DBG(SMC_DEBUG_RX, "%s: RX overrun\n", dev->name);
+				lp->stats.rx_errors++;
+				lp->stats.rx_fifo_errors++;
+			}
+			SMC_ACK_INT(INT_STS_RDFO_);
+		}
+		/* Handle receive condition */
+		if ((status & INT_STS_RSFL_) || rx_overrun) {
+			unsigned int fifo;
+			DBG(SMC_DEBUG_RX, "%s: RX irq\n", dev->name);
+			fifo = SMC_GET_RX_FIFO_INF();
+			pkts = (fifo & RX_FIFO_INF_RXSUSED_) >> 16;
+			DBG(SMC_DEBUG_RX, "%s: Rx FIFO pkts %d, bytes %d\n",
+				dev->name, pkts, fifo & 0xFFFF );
+			if (pkts != 0) {
+#ifdef SMC_USE_DMA
+				unsigned int fifo;
+				if (lp->rxdma_active){
+					DBG(SMC_DEBUG_RX | SMC_DEBUG_DMA,
+						"%s: RX DMA active\n", dev->name);
+					/* The DMA is already running so up the IRQ threshold */
+					fifo = SMC_GET_FIFO_INT() & ~0xFF;
+					fifo |= pkts & 0xFF;
+					DBG(SMC_DEBUG_RX,
+						"%s: Setting RX stat FIFO threshold to %d\n",
+						dev->name, fifo & 0xff);
+					SMC_SET_FIFO_INT(fifo);
+				} else
+#endif
+				smc911x_rcv(dev);
+			}
+			SMC_ACK_INT(INT_STS_RSFL_);
+		}
+		/* Handle transmit FIFO available */
+		if (status & INT_STS_TDFA_) {
+			DBG(SMC_DEBUG_TX, "%s: TX data FIFO space available irq\n", dev->name);
+			SMC_SET_FIFO_TDA(0xFF);
+			lp->tx_throttle = 0;
+#ifdef SMC_USE_DMA
+			if (!lp->txdma_active)
+#endif
+				netif_wake_queue(dev);
+			SMC_ACK_INT(INT_STS_TDFA_);
+		}
+		/* Handle transmit done condition */
+#if 1
+		if (status & (INT_STS_TSFL_ | INT_STS_GPT_INT_)) {
+			DBG(SMC_DEBUG_TX | SMC_DEBUG_MISC,
+				"%s: Tx stat FIFO limit (%d) /GPT irq\n",
+				dev->name, (SMC_GET_FIFO_INT() & 0x00ff0000) >> 16);
+			smc911x_tx(dev);
+			SMC_SET_GPT_CFG(GPT_CFG_TIMER_EN_ | 10000);
+			SMC_ACK_INT(INT_STS_TSFL_);
+			SMC_ACK_INT(INT_STS_TSFL_ | INT_STS_GPT_INT_);
+		}
+#else
+		if (status & INT_STS_TSFL_) {
+			DBG(SMC_DEBUG_TX, "%s: TX status FIFO limit (%d) irq \n", dev->name, );
+			smc911x_tx(dev);
+			SMC_ACK_INT(INT_STS_TSFL_);
+		}
+
+		if (status & INT_STS_GPT_INT_) {
+			DBG(SMC_DEBUG_RX, "%s: IRQ_CFG 0x%08x FIFO_INT 0x%08x RX_CFG 0x%08x\n",
+				dev->name,
+				SMC_GET_IRQ_CFG(),
+				SMC_GET_FIFO_INT(),
+				SMC_GET_RX_CFG());
+			DBG(SMC_DEBUG_RX, "%s: Rx Stat FIFO Used 0x%02x "
+				"Data FIFO Used 0x%04x Stat FIFO 0x%08x\n",
+				dev->name,
+				(SMC_GET_RX_FIFO_INF() & 0x00ff0000) >> 16,
+				SMC_GET_RX_FIFO_INF() & 0xffff,
+				SMC_GET_RX_STS_FIFO_PEEK());
+			SMC_SET_GPT_CFG(GPT_CFG_TIMER_EN_ | 10000);
+			SMC_ACK_INT(INT_STS_GPT_INT_);
+		}
+#endif
+
+		/* Handle PHY interupt condition */
+		if (status & INT_STS_PHY_INT_) {
+			DBG(SMC_DEBUG_MISC, "%s: PHY irq\n", dev->name);
+			smc911x_phy_interrupt(dev);
+			SMC_ACK_INT(INT_STS_PHY_INT_);
+		}
+	} while (--timeout);
+
+	/* restore mask state */
+	SMC_SET_INT_EN(mask);
+
+	DBG(SMC_DEBUG_MISC, "%s: Interrupt done (%d loops)\n",
+		dev->name, 8-timeout);
+
+	spin_unlock_irqrestore(&lp->lock, flags);
+
+	DBG(3, "%s: Interrupt done (%d loops)\n", dev->name, 8-timeout);
+
+	return IRQ_HANDLED;
+}
+
+#ifdef SMC_USE_DMA
+static void
+smc911x_tx_dma_irq(int dma, void *data, struct pt_regs *regs)
+{
+	struct net_device *dev = (struct net_device *)data;
+	struct smc911x_local *lp = netdev_priv(dev);
+	struct sk_buff *skb = lp->current_tx_skb;
+	unsigned long flags;
+
+	DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __FUNCTION__);
+
+	DBG(SMC_DEBUG_TX | SMC_DEBUG_DMA, "%s: TX DMA irq handler\n", dev->name);
+	/* Clear the DMA interrupt sources */
+	SMC_DMA_ACK_IRQ(dev, dma);
+	BUG_ON(skb == NULL);
+	dma_unmap_single(NULL, tx_dmabuf, tx_dmalen, DMA_TO_DEVICE);
+	dev->trans_start = jiffies;
+	dev_kfree_skb_irq(skb);
+	lp->current_tx_skb = NULL;
+	if (lp->pending_tx_skb != NULL)
+		smc911x_hardware_send_pkt(dev);
+	else {
+		DBG(SMC_DEBUG_TX | SMC_DEBUG_DMA,
+			"%s: No pending Tx packets. DMA disabled\n", dev->name);
+		spin_lock_irqsave(&lp->lock, flags);
+		lp->txdma_active = 0;
+		if (!lp->tx_throttle) {
+			netif_wake_queue(dev);
+		}
+		spin_unlock_irqrestore(&lp->lock, flags);
+	}
+
+	DBG(SMC_DEBUG_TX | SMC_DEBUG_DMA,
+		"%s: TX DMA irq completed\n", dev->name);
+}
+static void
+smc911x_rx_dma_irq(int dma, void *data, struct pt_regs *regs)
+{
+	struct net_device *dev = (struct net_device *)data;
+	unsigned long ioaddr = dev->base_addr;
+	struct smc911x_local *lp = netdev_priv(dev);
+	struct sk_buff *skb = lp->current_rx_skb;
+	unsigned long flags;
+	unsigned int pkts;
+
+	DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __FUNCTION__);
+	DBG(SMC_DEBUG_RX | SMC_DEBUG_DMA, "%s: RX DMA irq handler\n", dev->name);
+	/* Clear the DMA interrupt sources */
+	SMC_DMA_ACK_IRQ(dev, dma);
+	dma_unmap_single(NULL, rx_dmabuf, rx_dmalen, DMA_FROM_DEVICE);
+	BUG_ON(skb == NULL);
+	lp->current_rx_skb = NULL;
+	PRINT_PKT(skb->data, skb->len);
+	dev->last_rx = jiffies;
+	skb->dev = dev;
+	skb->protocol = eth_type_trans(skb, dev);
+	netif_rx(skb);
+	lp->stats.rx_packets++;
+	lp->stats.rx_bytes += skb->len;
+
+	spin_lock_irqsave(&lp->lock, flags);
+	pkts = (SMC_GET_RX_FIFO_INF() & RX_FIFO_INF_RXSUSED_) >> 16;
+	if (pkts != 0) {
+		smc911x_rcv(dev);
+	}else {
+		lp->rxdma_active = 0;
+	}
+	spin_unlock_irqrestore(&lp->lock, flags);
+	DBG(SMC_DEBUG_RX | SMC_DEBUG_DMA,
+		"%s: RX DMA irq completed. DMA RX FIFO PKTS %d\n",
+		dev->name, pkts);
+}
+#endif	 /* SMC_USE_DMA */
+
+#ifdef CONFIG_NET_POLL_CONTROLLER
+/*
+ * Polling receive - used by netconsole and other diagnostic tools
+ * to allow network i/o with interrupts disabled.
+ */
+static void smc911x_poll_controller(struct net_device *dev)
+{
+	disable_irq(dev->irq);
+	smc911x_interrupt(dev->irq, dev, NULL);
+	enable_irq(dev->irq);
+}
+#endif
+
+/* Our watchdog timed out. Called by the networking layer */
+static void smc911x_timeout(struct net_device *dev)
+{
+	struct smc911x_local *lp = netdev_priv(dev);
+	unsigned long ioaddr = dev->base_addr;
+	int status, mask;
+	unsigned long flags;
+
+	DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __FUNCTION__);
+
+	spin_lock_irqsave(&lp->lock, flags);
+	status = SMC_GET_INT();
+	mask = SMC_GET_INT_EN();
+	spin_unlock_irqrestore(&lp->lock, flags);
+	DBG(SMC_DEBUG_MISC, "%s: INT 0x%02x MASK 0x%02x \n",
+		dev->name, status, mask);
+
+	/* Dump the current TX FIFO contents and restart */
+	mask = SMC_GET_TX_CFG();
+	SMC_SET_TX_CFG(mask | TX_CFG_TXS_DUMP_ | TX_CFG_TXD_DUMP_);
+	/*
+	 * Reconfiguring the PHY doesn't seem like a bad idea here, but
+	 * smc911x_phy_configure() calls msleep() which calls schedule_timeout()
+	 * which calls schedule().	 Hence we use a work queue.
+	 */
+	if (lp->phy_type != 0) {
+		if (schedule_work(&lp->phy_configure)) {
+			lp->work_pending = 1;
+		}
+	}
+
+	/* We can accept TX packets again */
+	dev->trans_start = jiffies;
+	netif_wake_queue(dev);
+}
+
+/*
+ * This routine will, depending on the values passed to it,
+ * either make it accept multicast packets, go into
+ * promiscuous mode (for TCPDUMP and cousins) or accept
+ * a select set of multicast packets
+ */
+static void smc911x_set_multicast_list(struct net_device *dev)
+{
+	struct smc911x_local *lp = netdev_priv(dev);
+	unsigned long ioaddr = dev->base_addr;
+	unsigned int multicast_table[2];
+	unsigned int mcr, update_multicast = 0;
+	unsigned long flags;
+	/* table for flipping the order of 5 bits */
+	static const unsigned char invert5[] =
+		{0x00, 0x10, 0x08, 0x18, 0x04, 0x14, 0x0C, 0x1C,
+		 0x02, 0x12, 0x0A, 0x1A, 0x06, 0x16, 0x0E, 0x1E,
+		 0x01, 0x11, 0x09, 0x19, 0x05, 0x15, 0x0D, 0x1D,
+		 0x03, 0x13, 0x0B, 0x1B, 0x07, 0x17, 0x0F, 0x1F};
+
+
+	DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __FUNCTION__);
+
+	spin_lock_irqsave(&lp->lock, flags);
+	SMC_GET_MAC_CR(mcr);
+	spin_unlock_irqrestore(&lp->lock, flags);
+
+	if (dev->flags & IFF_PROMISC) {
+
+		DBG(SMC_DEBUG_MISC, "%s: RCR_PRMS\n", dev->name);
+		mcr |= MAC_CR_PRMS_;
+	}
+	/*
+	 * Here, I am setting this to accept all multicast packets.
+	 * I don't need to zero the multicast table, because the flag is
+	 * checked before the table is
+	 */
+	else if (dev->flags & IFF_ALLMULTI || dev->mc_count > 16) {
+		DBG(SMC_DEBUG_MISC, "%s: RCR_ALMUL\n", dev->name);
+		mcr |= MAC_CR_MCPAS_;
+	}
+
+	/*
+	 * This sets the internal hardware table to filter out unwanted
+	 * multicast packets before they take up memory.
+	 *
+	 * The SMC chip uses a hash table where the high 6 bits of the CRC of
+	 * address are the offset into the table.	If that bit is 1, then the
+	 * multicast packet is accepted.  Otherwise, it's dropped silently.
+	 *
+	 * To use the 6 bits as an offset into the table, the high 1 bit is
+	 * the number of the 32 bit register, while the low 5 bits are the bit
+	 * within that register.
+	 */
+	else if (dev->mc_count)  {
+		int i;
+		struct dev_mc_list *cur_addr;
+
+		/* Set the Hash perfec mode */
+		mcr |= MAC_CR_HPFILT_;
+
+		/* start with a table of all zeros: reject all */
+		memset(multicast_table, 0, sizeof(multicast_table));
+
+		cur_addr = dev->mc_list;
+		for (i = 0; i < dev->mc_count; i++, cur_addr = cur_addr->next) {
+			int position;
+
+			/* do we have a pointer here? */
+			if (!cur_addr)
+				break;
+			/* make sure this is a multicast address -
+				shouldn't this be a given if we have it here ? */
+			if (!(*cur_addr->dmi_addr & 1))
+				 continue;
+
+			/* only use the low order bits */
+			position = crc32_le(~0, cur_addr->dmi_addr, 6) & 0x3f;
+
+			/* do some messy swapping to put the bit in the right spot */
+			multicast_table[invert5[position&0x1F]&0x1] |=
+				(1<<invert5[(position>>1)&0x1F]);
+		}
+
+		/* be sure I get rid of flags I might have set */
+		mcr &= ~(MAC_CR_PRMS_ | MAC_CR_MCPAS_);
+
+		/* now, the table can be loaded into the chipset */
+		update_multicast = 1;
+	} else	 {
+		DBG(SMC_DEBUG_MISC, "%s: ~(MAC_CR_PRMS_|MAC_CR_MCPAS_)\n",
+			dev->name);
+		mcr &= ~(MAC_CR_PRMS_ | MAC_CR_MCPAS_);
+
+		/*
+		 * since I'm disabling all multicast entirely, I need to
+		 * clear the multicast list
+		 */
+		memset(multicast_table, 0, sizeof(multicast_table));
+		update_multicast = 1;
+	}
+
+	spin_lock_irqsave(&lp->lock, flags);
+	SMC_SET_MAC_CR(mcr);
+	if (update_multicast) {
+		DBG(SMC_DEBUG_MISC,
+			"%s: update mcast hash table 0x%08x 0x%08x\n",
+			dev->name, multicast_table[0], multicast_table[1]);
+		SMC_SET_HASHL(multicast_table[0]);
+		SMC_SET_HASHH(multicast_table[1]);
+	}
+	spin_unlock_irqrestore(&lp->lock, flags);
+}
+
+
+/*
+ * Open and Initialize the board
+ *
+ * Set up everything, reset the card, etc..
+ */
+static int
+smc911x_open(struct net_device *dev)
+{
+	DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __FUNCTION__);
+
+	/*
+	 * Check that the address is valid.  If its not, refuse
+	 * to bring the device up.	 The user must specify an
+	 * address using ifconfig eth0 hw ether xx:xx:xx:xx:xx:xx
+	 */
+	if (!is_valid_ether_addr(dev->dev_addr)) {
+		PRINTK("%s: no valid ethernet hw addr\n", __FUNCTION__);
+		return -EINVAL;
+	}
+
+	/* reset the hardware */
+	smc911x_reset(dev);
+
+	/* Configure the PHY, initialize the link state */
+	smc911x_phy_configure(dev);
+
+	/* Turn on Tx + Rx */
+	smc911x_enable(dev);
+
+	netif_start_queue(dev);
+
+	return 0;
+}
+
+/*
+ * smc911x_close
+ *
+ * this makes the board clean up everything that it can
+ * and not talk to the outside world.	 Caused by
+ * an 'ifconfig ethX down'
+ */
+static int smc911x_close(struct net_device *dev)
+{
+	struct smc911x_local *lp = netdev_priv(dev);
+
+	DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __FUNCTION__);
+
+	netif_stop_queue(dev);
+	netif_carrier_off(dev);
+
+	/* clear everything */
+	smc911x_shutdown(dev);
+
+	if (lp->phy_type != 0) {
+		/* We need to ensure that no calls to
+		 * smc911x_phy_configure are pending.
+
+		 * flush_scheduled_work() cannot be called because we
+		 * are running with the netlink semaphore held (from
+		 * devinet_ioctl()) and the pending work queue
+		 * contains linkwatch_event() (scheduled by
+		 * netif_carrier_off() above). linkwatch_event() also
+		 * wants the netlink semaphore.
+		 */
+		while (lp->work_pending)
+			schedule();
+		smc911x_phy_powerdown(dev, lp->mii.phy_id);
+	}
+
+	if (lp->pending_tx_skb) {
+		dev_kfree_skb(lp->pending_tx_skb);
+		lp->pending_tx_skb = NULL;
+	}
+
+	return 0;
+}
+
+/*
+ * Get the current statistics.
+ * This may be called with the card open or closed.
+ */
+static struct net_device_stats *smc911x_query_statistics(struct net_device *dev)
+{
+	struct smc911x_local *lp = netdev_priv(dev);
+	DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __FUNCTION__);
+
+
+	return &lp->stats;
+}
+
+/*
+ * Ethtool support
+ */
+static int
+smc911x_ethtool_getsettings(struct net_device *dev, struct ethtool_cmd *cmd)
+{
+	struct smc911x_local *lp = netdev_priv(dev);
+	unsigned long ioaddr = dev->base_addr;
+	int ret, status;
+	unsigned long flags;
+
+	DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __FUNCTION__);
+	cmd->maxtxpkt = 1;
+	cmd->maxrxpkt = 1;
+
+	if (lp->phy_type != 0) {
+		spin_lock_irqsave(&lp->lock, flags);
+		ret = mii_ethtool_gset(&lp->mii, cmd);
+		spin_unlock_irqrestore(&lp->lock, flags);
+	} else {
+		cmd->supported = SUPPORTED_10baseT_Half |
+				SUPPORTED_10baseT_Full |
+				SUPPORTED_TP | SUPPORTED_AUI;
+
+		if (lp->ctl_rspeed == 10)
+			cmd->speed = SPEED_10;
+		else if (lp->ctl_rspeed == 100)
+			cmd->speed = SPEED_100;
+
+		cmd->autoneg = AUTONEG_DISABLE;
+		if (lp->mii.phy_id==1)
+			cmd->transceiver = XCVR_INTERNAL;
+		else
+			cmd->transceiver = XCVR_EXTERNAL;
+		cmd->port = 0;
+		SMC_GET_PHY_SPECIAL(lp->mii.phy_id, status);
+		cmd->duplex =
+			(status & (PHY_SPECIAL_SPD_10FULL_ | PHY_SPECIAL_SPD_100FULL_)) ?
+				DUPLEX_FULL : DUPLEX_HALF;
+		ret = 0;
+	}
+
+	return ret;
+}
+
+static int
+smc911x_ethtool_setsettings(struct net_device *dev, struct ethtool_cmd *cmd)
+{
+	struct smc911x_local *lp = netdev_priv(dev);
+	int ret;
+	unsigned long flags;
+
+	if (lp->phy_type != 0) {
+		spin_lock_irqsave(&lp->lock, flags);
+		ret = mii_ethtool_sset(&lp->mii, cmd);
+		spin_unlock_irqrestore(&lp->lock, flags);
+	} else {
+		if (cmd->autoneg != AUTONEG_DISABLE ||
+			cmd->speed != SPEED_10 ||
+			(cmd->duplex != DUPLEX_HALF && cmd->duplex != DUPLEX_FULL) ||
+			(cmd->port != PORT_TP && cmd->port != PORT_AUI))
+			return -EINVAL;
+
+		lp->ctl_rfduplx = cmd->duplex == DUPLEX_FULL;
+
+		ret = 0;
+	}
+
+	return ret;
+}
+
+static void
+smc911x_ethtool_getdrvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
+{
+	strncpy(info->driver, CARDNAME, sizeof(info->driver));
+	strncpy(info->version, version, sizeof(info->version));
+	strncpy(info->bus_info, dev->class_dev.dev->bus_id, sizeof(info->bus_info));
+}
+
+static int smc911x_ethtool_nwayreset(struct net_device *dev)
+{
+	struct smc911x_local *lp = netdev_priv(dev);
+	int ret = -EINVAL;
+	unsigned long flags;
+
+	if (lp->phy_type != 0) {
+		spin_lock_irqsave(&lp->lock, flags);
+		ret = mii_nway_restart(&lp->mii);
+		spin_unlock_irqrestore(&lp->lock, flags);
+	}
+
+	return ret;
+}
+
+static u32 smc911x_ethtool_getmsglevel(struct net_device *dev)
+{
+	struct smc911x_local *lp = netdev_priv(dev);
+	return lp->msg_enable;
+}
+
+static void smc911x_ethtool_setmsglevel(struct net_device *dev, u32 level)
+{
+	struct smc911x_local *lp = netdev_priv(dev);
+	lp->msg_enable = level;
+}
+
+static int smc911x_ethtool_getregslen(struct net_device *dev)
+{
+	/* System regs + MAC regs + PHY regs */
+	return (((E2P_CMD - ID_REV)/4 + 1) +
+			(WUCSR - MAC_CR)+1 + 32) * sizeof(u32);
+}
+
+static void smc911x_ethtool_getregs(struct net_device *dev,
+										 struct ethtool_regs* regs, void *buf)
+{
+	unsigned long ioaddr = dev->base_addr;
+	struct smc911x_local *lp = netdev_priv(dev);
+	unsigned long flags;
+	u32 reg,i,j=0;
+	u32 *data = (u32*)buf;
+
+	regs->version = lp->version;
+	for(i=ID_REV;i<=E2P_CMD;i+=4) {
+		data[j++] = SMC_inl(ioaddr,i);
+	}
+	for(i=MAC_CR;i<=WUCSR;i++) {
+		spin_lock_irqsave(&lp->lock, flags);
+		SMC_GET_MAC_CSR(i, reg);
+		spin_unlock_irqrestore(&lp->lock, flags);
+		data[j++] = reg;
+	}
+	for(i=0;i<=31;i++) {
+		spin_lock_irqsave(&lp->lock, flags);
+		SMC_GET_MII(i, lp->mii.phy_id, reg);
+		spin_unlock_irqrestore(&lp->lock, flags);
+		data[j++] = reg & 0xFFFF;
+	}
+}
+
+static int smc911x_ethtool_wait_eeprom_ready(struct net_device *dev)
+{
+	unsigned long ioaddr = dev->base_addr;
+	unsigned int timeout;
+	int e2p_cmd;
+
+	e2p_cmd = SMC_GET_E2P_CMD();
+	for(timeout=10;(e2p_cmd & E2P_CMD_EPC_BUSY_) && timeout; timeout--) {
+		if (e2p_cmd & E2P_CMD_EPC_TIMEOUT_) {
+			PRINTK("%s: %s timeout waiting for EEPROM to respond\n",
+				dev->name, __FUNCTION__);
+			return -EFAULT;
+		}
+		mdelay(1);
+		e2p_cmd = SMC_GET_E2P_CMD();
+	}
+	if (timeout == 0) {
+		PRINTK("%s: %s timeout waiting for EEPROM CMD not busy\n",
+			dev->name, __FUNCTION__);
+		return -ETIMEDOUT;
+	}
+	return 0;
+}
+
+static inline int smc911x_ethtool_write_eeprom_cmd(struct net_device *dev,
+													int cmd, int addr)
+{
+	unsigned long ioaddr = dev->base_addr;
+	int ret;
+
+	if ((ret = smc911x_ethtool_wait_eeprom_ready(dev))!=0)
+		return ret;
+	SMC_SET_E2P_CMD(E2P_CMD_EPC_BUSY_ |
+		((cmd) & (0x7<<28)) |
+		((addr) & 0xFF));
+	return 0;
+}
+
+static inline int smc911x_ethtool_read_eeprom_byte(struct net_device *dev,
+													u8 *data)
+{
+	unsigned long ioaddr = dev->base_addr;
+	int ret;
+
+	if ((ret = smc911x_ethtool_wait_eeprom_ready(dev))!=0)
+		return ret;
+	*data = SMC_GET_E2P_DATA();
+	return 0;
+}
+
+static inline int smc911x_ethtool_write_eeprom_byte(struct net_device *dev,
+													 u8 data)
+{
+	unsigned long ioaddr = dev->base_addr;
+	int ret;
+
+	if ((ret = smc911x_ethtool_wait_eeprom_ready(dev))!=0)
+		return ret;
+	SMC_SET_E2P_DATA(data);
+	return 0;
+}
+
+static int smc911x_ethtool_geteeprom(struct net_device *dev,
+									  struct ethtool_eeprom *eeprom, u8 *data)
+{
+	u8 eebuf[SMC911X_EEPROM_LEN];
+	int i, ret;
+
+	for(i=0;i<SMC911X_EEPROM_LEN;i++) {
+		if ((ret=smc911x_ethtool_write_eeprom_cmd(dev, E2P_CMD_EPC_CMD_READ_, i ))!=0)
+			return ret;
+		if ((ret=smc911x_ethtool_read_eeprom_byte(dev, &eebuf[i]))!=0)
+			return ret;
+		}
+	memcpy(data, eebuf+eeprom->offset, eeprom->len);
+	return 0;
+}
+
+static int smc911x_ethtool_seteeprom(struct net_device *dev,
+									   struct ethtool_eeprom *eeprom, u8 *data)
+{
+	int i, ret;
+
+	/* Enable erase */
+	if ((ret=smc911x_ethtool_write_eeprom_cmd(dev, E2P_CMD_EPC_CMD_EWEN_, 0 ))!=0)
+		return ret;
+	for(i=eeprom->offset;i<(eeprom->offset+eeprom->len);i++) {
+		/* erase byte */
+		if ((ret=smc911x_ethtool_write_eeprom_cmd(dev, E2P_CMD_EPC_CMD_ERASE_, i ))!=0)
+			return ret;
+		/* write byte */
+		if ((ret=smc911x_ethtool_write_eeprom_byte(dev, *data))!=0)
+			 return ret;
+		if ((ret=smc911x_ethtool_write_eeprom_cmd(dev, E2P_CMD_EPC_CMD_WRITE_, i ))!=0)
+			return ret;
+		}
+	 return 0;
+}
+
+static int smc911x_ethtool_geteeprom_len(struct net_device *dev)
+{
+	 return SMC911X_EEPROM_LEN;
+}
+
+static struct ethtool_ops smc911x_ethtool_ops = {
+	.get_settings	 = smc911x_ethtool_getsettings,
+	.set_settings	 = smc911x_ethtool_setsettings,
+	.get_drvinfo	 = smc911x_ethtool_getdrvinfo,
+	.get_msglevel	 = smc911x_ethtool_getmsglevel,
+	.set_msglevel	 = smc911x_ethtool_setmsglevel,
+	.nway_reset = smc911x_ethtool_nwayreset,
+	.get_link	 = ethtool_op_get_link,
+	.get_regs_len	 = smc911x_ethtool_getregslen,
+	.get_regs	 = smc911x_ethtool_getregs,
+	.get_eeprom_len = smc911x_ethtool_geteeprom_len,
+	.get_eeprom = smc911x_ethtool_geteeprom,
+	.set_eeprom = smc911x_ethtool_seteeprom,
+};
+
+/*
+ * smc911x_findirq
+ *
+ * This routine has a simple purpose -- make the SMC chip generate an
+ * interrupt, so an auto-detect routine can detect it, and find the IRQ,
+ */
+static int __init smc911x_findirq(unsigned long ioaddr)
+{
+	int timeout = 20;
+	unsigned long cookie;
+
+	DBG(SMC_DEBUG_FUNC, "--> %s\n", __FUNCTION__);
+
+	cookie = probe_irq_on();
+
+	/*
+	 * Force a SW interrupt
+	 */
+
+	SMC_SET_INT_EN(INT_EN_SW_INT_EN_);
+
+	/*
+	 * Wait until positive that the interrupt has been generated
+	 */
+	do {
+		int int_status;
+		udelay(10);
+		int_status = SMC_GET_INT_EN();
+		if (int_status & INT_EN_SW_INT_EN_)
+			 break;		/* got the interrupt */
+	} while (--timeout);
+
+	/*
+	 * there is really nothing that I can do here if timeout fails,
+	 * as autoirq_report will return a 0 anyway, which is what I
+	 * want in this case.	 Plus, the clean up is needed in both
+	 * cases.
+	 */
+
+	/* and disable all interrupts again */
+	SMC_SET_INT_EN(0);
+
+	/* and return what I found */
+	return probe_irq_off(cookie);
+}
+
+/*
+ * Function: smc911x_probe(unsigned long ioaddr)
+ *
+ * Purpose:
+ *	 Tests to see if a given ioaddr points to an SMC911x chip.
+ *	 Returns a 0 on success
+ *
+ * Algorithm:
+ *	 (1) see if the endian word is OK
+ *	 (1) see if I recognize the chip ID in the appropriate register
+ *
+ * Here I do typical initialization tasks.
+ *
+ * o  Initialize the structure if needed
+ * o  print out my vanity message if not done so already
+ * o  print out what type of hardware is detected
+ * o  print out the ethernet address
+ * o  find the IRQ
+ * o  set up my private data
+ * o  configure the dev structure with my subroutines
+ * o  actually GRAB the irq.
+ * o  GRAB the region
+ */
+static int __init smc911x_probe(struct net_device *dev, unsigned long ioaddr)
+{
+	struct smc911x_local *lp = netdev_priv(dev);
+	int i, retval;
+	unsigned int val, chip_id, revision;
+	const char *version_string;
+
+	DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __FUNCTION__);
+
+	/* First, see if the endian word is recognized */
+	val = SMC_GET_BYTE_TEST();
+	DBG(SMC_DEBUG_MISC, "%s: endian probe returned 0x%04x\n", CARDNAME, val);
+	if (val != 0x87654321) {
+		printk(KERN_ERR "Invalid chip endian 0x08%x\n",val);
+		retval = -ENODEV;
+		goto err_out;
+	}
+
+	/*
+	 * check if the revision register is something that I
+	 * recognize.	These might need to be added to later,
+	 * as future revisions could be added.
+	 */
+	chip_id = SMC_GET_PN();
+	DBG(SMC_DEBUG_MISC, "%s: id probe returned 0x%04x\n", CARDNAME, chip_id);
+	for(i=0;chip_ids[i].id != 0; i++) {
+		if (chip_ids[i].id == chip_id) break;
+	}
+	if (!chip_ids[i].id) {
+		printk(KERN_ERR "Unknown chip ID %04x\n", chip_id);
+		retval = -ENODEV;
+		goto err_out;
+	}
+	version_string = chip_ids[i].name;
+
+	revision = SMC_GET_REV();
+	DBG(SMC_DEBUG_MISC, "%s: revision = 0x%04x\n", CARDNAME, revision);
+
+	/* At this point I'll assume that the chip is an SMC911x. */
+	DBG(SMC_DEBUG_MISC, "%s: Found a %s\n", CARDNAME, chip_ids[i].name);
+
+	/* Validate the TX FIFO size requested */
+	if ((tx_fifo_kb < 2) || (tx_fifo_kb > 14)) {
+		printk(KERN_ERR "Invalid TX FIFO size requested %d\n", tx_fifo_kb);
+		retval = -EINVAL;
+		goto err_out;
+	}
+
+	/* fill in some of the fields */
+	dev->base_addr = ioaddr;
+	lp->version = chip_ids[i].id;
+	lp->revision = revision;
+	lp->tx_fifo_kb = tx_fifo_kb;
+	/* Reverse calculate the RX FIFO size from the TX */
+	lp->tx_fifo_size=(lp->tx_fifo_kb<<10) - 512;
+	lp->rx_fifo_size= ((0x4000 - 512 - lp->tx_fifo_size) / 16) * 15;
+
+	/* Set the automatic flow control values */
+	switch(lp->tx_fifo_kb) {
+		/*
+		 *	 AFC_HI is about ((Rx Data Fifo Size)*2/3)/64
+		 *	 AFC_LO is AFC_HI/2
+		 *	 BACK_DUR is about 5uS*(AFC_LO) rounded down
+		 */
+		case 2:/* 13440 Rx Data Fifo Size */
+			lp->afc_cfg=0x008C46AF;break;
+		case 3:/* 12480 Rx Data Fifo Size */
+			lp->afc_cfg=0x0082419F;break;
+		case 4:/* 11520 Rx Data Fifo Size */
+			lp->afc_cfg=0x00783C9F;break;
+		case 5:/* 10560 Rx Data Fifo Size */
+			lp->afc_cfg=0x006E374F;break;
+		case 6:/* 9600 Rx Data Fifo Size */
+			lp->afc_cfg=0x0064328F;break;
+		case 7:/* 8640 Rx Data Fifo Size */
+			lp->afc_cfg=0x005A2D7F;break;
+		case 8:/* 7680 Rx Data Fifo Size */
+			lp->afc_cfg=0x0050287F;break;
+		case 9:/* 6720 Rx Data Fifo Size */
+			lp->afc_cfg=0x0046236F;break;
+		case 10:/* 5760 Rx Data Fifo Size */
+			lp->afc_cfg=0x003C1E6F;break;
+		case 11:/* 4800 Rx Data Fifo Size */
+			lp->afc_cfg=0x0032195F;break;
+		/*
+		 *	 AFC_HI is ~1520 bytes less than RX Data Fifo Size
+		 *	 AFC_LO is AFC_HI/2
+		 *	 BACK_DUR is about 5uS*(AFC_LO) rounded down
+		 */
+		case 12:/* 3840 Rx Data Fifo Size */
+			lp->afc_cfg=0x0024124F;break;
+		case 13:/* 2880 Rx Data Fifo Size */
+			lp->afc_cfg=0x0015073F;break;
+		case 14:/* 1920 Rx Data Fifo Size */
+			lp->afc_cfg=0x0006032F;break;
+		 default:
+			 PRINTK("%s: ERROR -- no AFC_CFG setting found",
+				dev->name);
+			 break;
+	}
+
+	DBG(SMC_DEBUG_MISC | SMC_DEBUG_TX | SMC_DEBUG_RX,
+		"%s: tx_fifo %d rx_fifo %d afc_cfg 0x%08x\n", CARDNAME,
+		lp->tx_fifo_size, lp->rx_fifo_size, lp->afc_cfg);
+
+	spin_lock_init(&lp->lock);
+
+	/* Get the MAC address */
+	SMC_GET_MAC_ADDR(dev->dev_addr);
+
+	/* now, reset the chip, and put it into a known state */
+	smc911x_reset(dev);
+
+	/*
+	 * If dev->irq is 0, then the device has to be banged on to see
+	 * what the IRQ is.
+	 *
+	 * Specifying an IRQ is done with the assumption that the user knows
+	 * what (s)he is doing.  No checking is done!!!!
+	 */
+	if (dev->irq < 1) {
+		int trials;
+
+		trials = 3;
+		while (trials--) {
+			dev->irq = smc911x_findirq(ioaddr);
+			if (dev->irq)
+				break;
+			/* kick the card and try again */
+			smc911x_reset(dev);
+		}
+	}
+	if (dev->irq == 0) {
+		printk("%s: Couldn't autodetect your IRQ. Use irq=xx.\n",
+			dev->name);
+		retval = -ENODEV;
+		goto err_out;
+	}
+	dev->irq = irq_canonicalize(dev->irq);
+
+	/* Fill in the fields of the device structure with ethernet values. */
+	ether_setup(dev);
+
+	dev->open = smc911x_open;
+	dev->stop = smc911x_close;
+	dev->hard_start_xmit = smc911x_hard_start_xmit;
+	dev->tx_timeout = smc911x_timeout;
+	dev->watchdog_timeo = msecs_to_jiffies(watchdog);
+	dev->get_stats = smc911x_query_statistics;
+	dev->set_multicast_list = smc911x_set_multicast_list;
+	dev->ethtool_ops = &smc911x_ethtool_ops;
+#ifdef CONFIG_NET_POLL_CONTROLLER
+	dev->poll_controller = smc911x_poll_controller;
+#endif
+
+	INIT_WORK(&lp->phy_configure, smc911x_phy_configure, dev);
+	lp->mii.phy_id_mask = 0x1f;
+	lp->mii.reg_num_mask = 0x1f;
+	lp->mii.force_media = 0;
+	lp->mii.full_duplex = 0;
+	lp->mii.dev = dev;
+	lp->mii.mdio_read = smc911x_phy_read;
+	lp->mii.mdio_write = smc911x_phy_write;
+
+	/*
+	 * Locate the phy, if any.
+	 */
+	smc911x_phy_detect(dev);
+
+	/* Set default parameters */
+	lp->msg_enable = NETIF_MSG_LINK;
+	lp->ctl_rfduplx = 1;
+	lp->ctl_rspeed = 100;
+
+	/* Grab the IRQ */
+	retval = request_irq(dev->irq, &smc911x_interrupt, IRQF_SHARED, dev->name, dev);
+	if (retval)
+		goto err_out;
+
+	set_irq_type(dev->irq, IRQT_FALLING);
+
+#ifdef SMC_USE_DMA
+	lp->rxdma = SMC_DMA_REQUEST(dev, smc911x_rx_dma_irq);
+	lp->txdma = SMC_DMA_REQUEST(dev, smc911x_tx_dma_irq);
+	lp->rxdma_active = 0;
+	lp->txdma_active = 0;
+	dev->dma = lp->rxdma;
+#endif
+
+	retval = register_netdev(dev);
+	if (retval == 0) {
+		/* now, print out the card info, in a short format.. */
+		printk("%s: %s (rev %d) at %#lx IRQ %d",
+			dev->name, version_string, lp->revision,
+			dev->base_addr, dev->irq);
+
+#ifdef SMC_USE_DMA
+		if (lp->rxdma != -1)
+			printk(" RXDMA %d ", lp->rxdma);
+
+		if (lp->txdma != -1)
+			printk("TXDMA %d", lp->txdma);
+#endif
+		printk("\n");
+		if (!is_valid_ether_addr(dev->dev_addr)) {
+			printk("%s: Invalid ethernet MAC address. Please "
+					"set using ifconfig\n", dev->name);
+		} else {
+			/* Print the Ethernet address */
+			printk("%s: Ethernet addr: ", dev->name);
+			for (i = 0; i < 5; i++)
+				printk("%2.2x:", dev->dev_addr[i]);
+			printk("%2.2x\n", dev->dev_addr[5]);
+		}
+
+		if (lp->phy_type == 0) {
+			PRINTK("%s: No PHY found\n", dev->name);
+		} else if ((lp->phy_type & ~0xff) == LAN911X_INTERNAL_PHY_ID) {
+			PRINTK("%s: LAN911x Internal PHY\n", dev->name);
+		} else {
+			PRINTK("%s: External PHY 0x%08x\n", dev->name, lp->phy_type);
+		}
+	}
+
+err_out:
+#ifdef SMC_USE_DMA
+	if (retval) {
+		if (lp->rxdma != -1) {
+			SMC_DMA_FREE(dev, lp->rxdma);
+		}
+		if (lp->txdma != -1) {
+			SMC_DMA_FREE(dev, lp->txdma);
+		}
+	}
+#endif
+	return retval;
+}
+
+/*
+ * smc911x_init(void)
+ *
+ *	  Output:
+ *	 0 --> there is a device
+ *	 anything else, error
+ */
+static int smc911x_drv_probe(struct platform_device *pdev)
+{
+	struct net_device *ndev;
+	struct resource *res;
+	unsigned int *addr;
+	int ret;
+
+	DBG(SMC_DEBUG_FUNC, "--> %s\n",  __FUNCTION__);
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res) {
+		ret = -ENODEV;
+		goto out;
+	}
+
+	/*
+	 * Request the regions.
+	 */
+	if (!request_mem_region(res->start, SMC911X_IO_EXTENT, CARDNAME)) {
+		 ret = -EBUSY;
+		 goto out;
+	}
+
+	ndev = alloc_etherdev(sizeof(struct smc911x_local));
+	if (!ndev) {
+		printk("%s: could not allocate device.\n", CARDNAME);
+		ret = -ENOMEM;
+		goto release_1;
+	}
+	SET_MODULE_OWNER(ndev);
+	SET_NETDEV_DEV(ndev, &pdev->dev);
+
+	ndev->dma = (unsigned char)-1;
+	ndev->irq = platform_get_irq(pdev, 0);
+
+	addr = ioremap(res->start, SMC911X_IO_EXTENT);
+	if (!addr) {
+		ret = -ENOMEM;
+		goto release_both;
+	}
+
+	platform_set_drvdata(pdev, ndev);
+	ret = smc911x_probe(ndev, (unsigned long)addr);
+	if (ret != 0) {
+		platform_set_drvdata(pdev, NULL);
+		iounmap(addr);
+release_both:
+		free_netdev(ndev);
+release_1:
+		release_mem_region(res->start, SMC911X_IO_EXTENT);
+out:
+		printk("%s: not found (%d).\n", CARDNAME, ret);
+	}
+#ifdef SMC_USE_DMA
+	else {
+		struct smc911x_local *lp = netdev_priv(ndev);
+		lp->physaddr = res->start;
+		lp->dev = &pdev->dev;
+	}
+#endif
+
+	return ret;
+}
+
+static int smc911x_drv_remove(struct platform_device *pdev)
+{
+	struct net_device *ndev = platform_get_drvdata(pdev);
+	struct resource *res;
+
+	DBG(SMC_DEBUG_FUNC, "--> %s\n", __FUNCTION__);
+	platform_set_drvdata(pdev, NULL);
+
+	unregister_netdev(ndev);
+
+	free_irq(ndev->irq, ndev);
+
+#ifdef SMC_USE_DMA
+	{
+		struct smc911x_local *lp = netdev_priv(ndev);
+		if (lp->rxdma != -1) {
+			SMC_DMA_FREE(dev, lp->rxdma);
+		}
+		if (lp->txdma != -1) {
+			SMC_DMA_FREE(dev, lp->txdma);
+		}
+	}
+#endif
+	iounmap((void *)ndev->base_addr);
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	release_mem_region(res->start, SMC911X_IO_EXTENT);
+
+	free_netdev(ndev);
+	return 0;
+}
+
+static int smc911x_drv_suspend(struct platform_device *dev, pm_message_t state)
+{
+	struct net_device *ndev = platform_get_drvdata(dev);
+	unsigned long ioaddr = ndev->base_addr;
+
+	DBG(SMC_DEBUG_FUNC, "--> %s\n", __FUNCTION__);
+	if (ndev) {
+		if (netif_running(ndev)) {
+			netif_device_detach(ndev);
+			smc911x_shutdown(ndev);
+#if POWER_DOWN
+			/* Set D2 - Energy detect only setting */
+			SMC_SET_PMT_CTRL(2<<12);
+#endif
+		}
+	}
+	return 0;
+}
+
+static int smc911x_drv_resume(struct platform_device *dev)
+{
+	struct net_device *ndev = platform_get_drvdata(dev);
+
+	DBG(SMC_DEBUG_FUNC, "--> %s\n", __FUNCTION__);
+	if (ndev) {
+		struct smc911x_local *lp = netdev_priv(ndev);
+
+		if (netif_running(ndev)) {
+			smc911x_reset(ndev);
+			smc911x_enable(ndev);
+			if (lp->phy_type != 0)
+				smc911x_phy_configure(ndev);
+			netif_device_attach(ndev);
+		}
+	}
+	return 0;
+}
+
+static struct platform_driver smc911x_driver = {
+	.probe		 = smc911x_drv_probe,
+	.remove	 = smc911x_drv_remove,
+	.suspend	 = smc911x_drv_suspend,
+	.resume	 = smc911x_drv_resume,
+	.driver	 = {
+		.name	 = CARDNAME,
+	},
+};
+
+static int __init smc911x_init(void)
+{
+	return platform_driver_register(&smc911x_driver);
+}
+
+static void __exit smc911x_cleanup(void)
+{
+	platform_driver_unregister(&smc911x_driver);
+}
+
+module_init(smc911x_init);
+module_exit(smc911x_cleanup);
diff --git a/drivers/net/smc911x.h b/drivers/net/smc911x.h
new file mode 100644
index 000000000..962a71045
--- /dev/null
+++ b/drivers/net/smc911x.h
@@ -0,0 +1,835 @@
+/*------------------------------------------------------------------------
+ . smc911x.h - macros for SMSC's LAN911{5,6,7,8} single-chip Ethernet device.
+ .
+ . Copyright (C) 2005 Sensoria Corp.
+ . Derived from the unified SMC91x driver by Nicolas Pitre
+ .
+ . 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
+ .
+ . Information contained in this file was obtained from the LAN9118
+ . manual from SMC.  To get a copy, if you really want one, you can find
+ . information under www.smsc.com.
+ .
+ . Authors
+ .	 Dustin McIntire		 <dustin@sensoria.com>
+ .
+ ---------------------------------------------------------------------------*/
+#ifndef _SMC911X_H_
+#define _SMC911X_H_
+
+/*
+ * Use the DMA feature on PXA chips
+ */
+#ifdef CONFIG_ARCH_PXA
+  #define SMC_USE_PXA_DMA	1
+  #define SMC_USE_16BIT		0
+  #define SMC_USE_32BIT		1
+#endif
+
+
+/*
+ * Define the bus width specific IO macros
+ */
+
+#if	SMC_USE_16BIT
+#define SMC_inb(a, r)			 readb((a) + (r))
+#define SMC_inw(a, r)			 readw((a) + (r))
+#define SMC_inl(a, r)			 ((SMC_inw(a, r) & 0xFFFF)+(SMC_inw(a+2, r)<<16))
+#define SMC_outb(v, a, r)		 writeb(v, (a) + (r))
+#define SMC_outw(v, a, r)		 writew(v, (a) + (r))
+#define SMC_outl(v, a, r) 			 \
+	do{					 \
+		 writel(v & 0xFFFF, (a) + (r));	 \
+		 writel(v >> 16, (a) + (r) + 2); \
+	 } while (0)
+#define SMC_insl(a, r, p, l)	 readsw((short*)((a) + (r)), p, l*2)
+#define SMC_outsl(a, r, p, l)	 writesw((short*)((a) + (r)), p, l*2)
+
+#elif	SMC_USE_32BIT
+#define SMC_inb(a, r)		 readb((a) + (r))
+#define SMC_inw(a, r)		 readw((a) + (r))
+#define SMC_inl(a, r)		 readl((a) + (r))
+#define SMC_outb(v, a, r)	 writeb(v, (a) + (r))
+#define SMC_outl(v, a, r)	 writel(v, (a) + (r))
+#define SMC_insl(a, r, p, l)	 readsl((int*)((a) + (r)), p, l)
+#define SMC_outsl(a, r, p, l)	 writesl((int*)((a) + (r)), p, l)
+
+#endif /* SMC_USE_16BIT */
+
+
+
+#if	 SMC_USE_PXA_DMA
+#define SMC_USE_DMA
+
+/*
+ * Define the request and free functions
+ * These are unfortunately architecture specific as no generic allocation
+ * mechanism exits
+ */
+#define SMC_DMA_REQUEST(dev, handler) \
+	 pxa_request_dma(dev->name, DMA_PRIO_LOW, handler, dev)
+
+#define SMC_DMA_FREE(dev, dma) \
+	 pxa_free_dma(dma)
+
+#define SMC_DMA_ACK_IRQ(dev, dma)					\
+{									\
+	if (DCSR(dma) & DCSR_BUSERR) {					\
+		printk("%s: DMA %d bus error!\n", dev->name, dma);	\
+	}								\
+	DCSR(dma) = DCSR_STARTINTR|DCSR_ENDINTR|DCSR_BUSERR;		\
+}
+
+/*
+ * Use a DMA for RX and TX packets.
+ */
+#include <linux/dma-mapping.h>
+#include <asm/dma.h>
+#include <asm/arch/pxa-regs.h>
+
+static dma_addr_t rx_dmabuf, tx_dmabuf;
+static int rx_dmalen, tx_dmalen;
+
+#ifdef SMC_insl
+#undef SMC_insl
+#define SMC_insl(a, r, p, l) \
+	smc_pxa_dma_insl(lp->dev, a, lp->physaddr, r, lp->rxdma, p, l)
+
+static inline void
+smc_pxa_dma_insl(struct device *dev, u_long ioaddr, u_long physaddr,
+		int reg, int dma, u_char *buf, int len)
+{
+	/* 64 bit alignment is required for memory to memory DMA */
+	if ((long)buf & 4) {
+		*((u32 *)buf) = SMC_inl(ioaddr, reg);
+		buf += 4;
+		len--;
+	}
+
+	len *= 4;
+	rx_dmabuf = dma_map_single(dev, buf, len, DMA_FROM_DEVICE);
+	rx_dmalen = len;
+	DCSR(dma) = DCSR_NODESC;
+	DTADR(dma) = rx_dmabuf;
+	DSADR(dma) = physaddr + reg;
+	DCMD(dma) = (DCMD_INCTRGADDR | DCMD_BURST32 |
+		DCMD_WIDTH4 | DCMD_ENDIRQEN | (DCMD_LENGTH & rx_dmalen));
+	DCSR(dma) = DCSR_NODESC | DCSR_RUN;
+}
+#endif
+
+#ifdef SMC_insw
+#undef SMC_insw
+#define SMC_insw(a, r, p, l) \
+	smc_pxa_dma_insw(lp->dev, a, lp->physaddr, r, lp->rxdma, p, l)
+
+static inline void
+smc_pxa_dma_insw(struct device *dev, u_long ioaddr, u_long physaddr,
+		int reg, int dma, u_char *buf, int len)
+{
+	/* 64 bit alignment is required for memory to memory DMA */
+	while ((long)buf & 6) {
+		*((u16 *)buf) = SMC_inw(ioaddr, reg);
+		buf += 2;
+		len--;
+	}
+
+	len *= 2;
+	rx_dmabuf = dma_map_single(dev, buf, len, DMA_FROM_DEVICE);
+	rx_dmalen = len;
+	DCSR(dma) = DCSR_NODESC;
+	DTADR(dma) = rx_dmabuf;
+	DSADR(dma) = physaddr + reg;
+	DCMD(dma) = (DCMD_INCTRGADDR | DCMD_BURST32 |
+		DCMD_WIDTH2 | DCMD_ENDIRQEN | (DCMD_LENGTH & rx_dmalen));
+	DCSR(dma) = DCSR_NODESC | DCSR_RUN;
+}
+#endif
+
+#ifdef SMC_outsl
+#undef SMC_outsl
+#define SMC_outsl(a, r, p, l) \
+	 smc_pxa_dma_outsl(lp->dev, a, lp->physaddr, r, lp->txdma, p, l)
+
+static inline void
+smc_pxa_dma_outsl(struct device *dev, u_long ioaddr, u_long physaddr,
+		int reg, int dma, u_char *buf, int len)
+{
+	/* 64 bit alignment is required for memory to memory DMA */
+	if ((long)buf & 4) {
+		SMC_outl(*((u32 *)buf), ioaddr, reg);
+		buf += 4;
+		len--;
+	}
+
+	len *= 4;
+	tx_dmabuf = dma_map_single(dev, buf, len, DMA_TO_DEVICE);
+	tx_dmalen = len;
+	DCSR(dma) = DCSR_NODESC;
+	DSADR(dma) = tx_dmabuf;
+	DTADR(dma) = physaddr + reg;
+	DCMD(dma) = (DCMD_INCSRCADDR | DCMD_BURST32 |
+		DCMD_WIDTH4 | DCMD_ENDIRQEN | (DCMD_LENGTH & tx_dmalen));
+	DCSR(dma) = DCSR_NODESC | DCSR_RUN;
+}
+#endif
+
+#ifdef SMC_outsw
+#undef SMC_outsw
+#define SMC_outsw(a, r, p, l) \
+	smc_pxa_dma_outsw(lp->dev, a, lp->physaddr, r, lp->txdma, p, l)
+
+static inline void
+smc_pxa_dma_outsw(struct device *dev, u_long ioaddr, u_long physaddr,
+		  int reg, int dma, u_char *buf, int len)
+{
+	/* 64 bit alignment is required for memory to memory DMA */
+	while ((long)buf & 6) {
+		SMC_outw(*((u16 *)buf), ioaddr, reg);
+		buf += 2;
+		len--;
+	}
+
+	len *= 2;
+	tx_dmabuf = dma_map_single(dev, buf, len, DMA_TO_DEVICE);
+	tx_dmalen = len;
+	DCSR(dma) = DCSR_NODESC;
+	DSADR(dma) = tx_dmabuf;
+	DTADR(dma) = physaddr + reg;
+	DCMD(dma) = (DCMD_INCSRCADDR | DCMD_BURST32 |
+		DCMD_WIDTH2 | DCMD_ENDIRQEN | (DCMD_LENGTH & tx_dmalen));
+	DCSR(dma) = DCSR_NODESC | DCSR_RUN;
+}
+#endif
+
+#endif	 /* SMC_USE_PXA_DMA */
+
+
+/* Chip Parameters and Register Definitions */
+
+#define SMC911X_TX_FIFO_LOW_THRESHOLD	(1536*2)
+
+#define SMC911X_IO_EXTENT	 0x100
+
+#define SMC911X_EEPROM_LEN	 7
+
+/* Below are the register offsets and bit definitions
+ * of the Lan911x memory space
+ */
+#define RX_DATA_FIFO		 (0x00)
+
+#define TX_DATA_FIFO		 (0x20)
+#define	TX_CMD_A_INT_ON_COMP_		(0x80000000)
+#define	TX_CMD_A_INT_BUF_END_ALGN_	(0x03000000)
+#define	TX_CMD_A_INT_4_BYTE_ALGN_	(0x00000000)
+#define	TX_CMD_A_INT_16_BYTE_ALGN_	(0x01000000)
+#define	TX_CMD_A_INT_32_BYTE_ALGN_	(0x02000000)
+#define	TX_CMD_A_INT_DATA_OFFSET_	(0x001F0000)
+#define	TX_CMD_A_INT_FIRST_SEG_		(0x00002000)
+#define	TX_CMD_A_INT_LAST_SEG_		(0x00001000)
+#define	TX_CMD_A_BUF_SIZE_		(0x000007FF)
+#define	TX_CMD_B_PKT_TAG_		(0xFFFF0000)
+#define	TX_CMD_B_ADD_CRC_DISABLE_	(0x00002000)
+#define	TX_CMD_B_DISABLE_PADDING_	(0x00001000)
+#define	TX_CMD_B_PKT_BYTE_LENGTH_	(0x000007FF)
+
+#define RX_STATUS_FIFO		(0x40)
+#define	RX_STS_PKT_LEN_			(0x3FFF0000)
+#define	RX_STS_ES_			(0x00008000)
+#define	RX_STS_BCST_			(0x00002000)
+#define	RX_STS_LEN_ERR_			(0x00001000)
+#define	RX_STS_RUNT_ERR_		(0x00000800)
+#define	RX_STS_MCAST_			(0x00000400)
+#define	RX_STS_TOO_LONG_		(0x00000080)
+#define	RX_STS_COLL_			(0x00000040)
+#define	RX_STS_ETH_TYPE_		(0x00000020)
+#define	RX_STS_WDOG_TMT_		(0x00000010)
+#define	RX_STS_MII_ERR_			(0x00000008)
+#define	RX_STS_DRIBBLING_		(0x00000004)
+#define	RX_STS_CRC_ERR_			(0x00000002)
+#define RX_STATUS_FIFO_PEEK 	(0x44)
+#define TX_STATUS_FIFO		(0x48)
+#define	TX_STS_TAG_			(0xFFFF0000)
+#define	TX_STS_ES_			(0x00008000)
+#define	TX_STS_LOC_			(0x00000800)
+#define	TX_STS_NO_CARR_			(0x00000400)
+#define	TX_STS_LATE_COLL_		(0x00000200)
+#define	TX_STS_MANY_COLL_		(0x00000100)
+#define	TX_STS_COLL_CNT_		(0x00000078)
+#define	TX_STS_MANY_DEFER_		(0x00000004)
+#define	TX_STS_UNDERRUN_		(0x00000002)
+#define	TX_STS_DEFERRED_		(0x00000001)
+#define TX_STATUS_FIFO_PEEK	(0x4C)
+#define ID_REV			(0x50)
+#define	ID_REV_CHIP_ID_			(0xFFFF0000)  /* RO */
+#define	ID_REV_REV_ID_			(0x0000FFFF)  /* RO */
+
+#define INT_CFG			(0x54)
+#define	INT_CFG_INT_DEAS_		(0xFF000000)  /* R/W */
+#define	INT_CFG_INT_DEAS_CLR_		(0x00004000)
+#define	INT_CFG_INT_DEAS_STS_		(0x00002000)
+#define	INT_CFG_IRQ_INT_		(0x00001000)  /* RO */
+#define	INT_CFG_IRQ_EN_			(0x00000100)  /* R/W */
+#define	INT_CFG_IRQ_POL_		(0x00000010)  /* R/W Not Affected by SW Reset */
+#define	INT_CFG_IRQ_TYPE_		(0x00000001)  /* R/W Not Affected by SW Reset */
+
+#define INT_STS			(0x58)
+#define	INT_STS_SW_INT_			(0x80000000)  /* R/WC */
+#define	INT_STS_TXSTOP_INT_		(0x02000000)  /* R/WC */
+#define	INT_STS_RXSTOP_INT_		(0x01000000)  /* R/WC */
+#define	INT_STS_RXDFH_INT_		(0x00800000)  /* R/WC */
+#define	INT_STS_RXDF_INT_		(0x00400000)  /* R/WC */
+#define	INT_STS_TX_IOC_			(0x00200000)  /* R/WC */
+#define	INT_STS_RXD_INT_		(0x00100000)  /* R/WC */
+#define	INT_STS_GPT_INT_		(0x00080000)  /* R/WC */
+#define	INT_STS_PHY_INT_		(0x00040000)  /* RO */
+#define	INT_STS_PME_INT_		(0x00020000)  /* R/WC */
+#define	INT_STS_TXSO_			(0x00010000)  /* R/WC */
+#define	INT_STS_RWT_			(0x00008000)  /* R/WC */
+#define	INT_STS_RXE_			(0x00004000)  /* R/WC */
+#define	INT_STS_TXE_			(0x00002000)  /* R/WC */
+//#define	INT_STS_ERX_		(0x00001000)  /* R/WC */
+#define	INT_STS_TDFU_			(0x00000800)  /* R/WC */
+#define	INT_STS_TDFO_			(0x00000400)  /* R/WC */
+#define	INT_STS_TDFA_			(0x00000200)  /* R/WC */
+#define	INT_STS_TSFF_			(0x00000100)  /* R/WC */
+#define	INT_STS_TSFL_			(0x00000080)  /* R/WC */
+//#define	INT_STS_RXDF_		(0x00000040)  /* R/WC */
+#define	INT_STS_RDFO_			(0x00000040)  /* R/WC */
+#define	INT_STS_RDFL_			(0x00000020)  /* R/WC */
+#define	INT_STS_RSFF_			(0x00000010)  /* R/WC */
+#define	INT_STS_RSFL_			(0x00000008)  /* R/WC */
+#define	INT_STS_GPIO2_INT_		(0x00000004)  /* R/WC */
+#define	INT_STS_GPIO1_INT_		(0x00000002)  /* R/WC */
+#define	INT_STS_GPIO0_INT_		(0x00000001)  /* R/WC */
+
+#define INT_EN			(0x5C)
+#define	INT_EN_SW_INT_EN_		(0x80000000)  /* R/W */
+#define	INT_EN_TXSTOP_INT_EN_		(0x02000000)  /* R/W */
+#define	INT_EN_RXSTOP_INT_EN_		(0x01000000)  /* R/W */
+#define	INT_EN_RXDFH_INT_EN_		(0x00800000)  /* R/W */
+//#define	INT_EN_RXDF_INT_EN_		(0x00400000)  /* R/W */
+#define	INT_EN_TIOC_INT_EN_		(0x00200000)  /* R/W */
+#define	INT_EN_RXD_INT_EN_		(0x00100000)  /* R/W */
+#define	INT_EN_GPT_INT_EN_		(0x00080000)  /* R/W */
+#define	INT_EN_PHY_INT_EN_		(0x00040000)  /* R/W */
+#define	INT_EN_PME_INT_EN_		(0x00020000)  /* R/W */
+#define	INT_EN_TXSO_EN_			(0x00010000)  /* R/W */
+#define	INT_EN_RWT_EN_			(0x00008000)  /* R/W */
+#define	INT_EN_RXE_EN_			(0x00004000)  /* R/W */
+#define	INT_EN_TXE_EN_			(0x00002000)  /* R/W */
+//#define	INT_EN_ERX_EN_			(0x00001000)  /* R/W */
+#define	INT_EN_TDFU_EN_			(0x00000800)  /* R/W */
+#define	INT_EN_TDFO_EN_			(0x00000400)  /* R/W */
+#define	INT_EN_TDFA_EN_			(0x00000200)  /* R/W */
+#define	INT_EN_TSFF_EN_			(0x00000100)  /* R/W */
+#define	INT_EN_TSFL_EN_			(0x00000080)  /* R/W */
+//#define	INT_EN_RXDF_EN_			(0x00000040)  /* R/W */
+#define	INT_EN_RDFO_EN_			(0x00000040)  /* R/W */
+#define	INT_EN_RDFL_EN_			(0x00000020)  /* R/W */
+#define	INT_EN_RSFF_EN_			(0x00000010)  /* R/W */
+#define	INT_EN_RSFL_EN_			(0x00000008)  /* R/W */
+#define	INT_EN_GPIO2_INT_		(0x00000004)  /* R/W */
+#define	INT_EN_GPIO1_INT_		(0x00000002)  /* R/W */
+#define	INT_EN_GPIO0_INT_		(0x00000001)  /* R/W */
+
+#define BYTE_TEST		(0x64)
+#define FIFO_INT		(0x68)
+#define	FIFO_INT_TX_AVAIL_LEVEL_	(0xFF000000)  /* R/W */
+#define	FIFO_INT_TX_STS_LEVEL_		(0x00FF0000)  /* R/W */
+#define	FIFO_INT_RX_AVAIL_LEVEL_	(0x0000FF00)  /* R/W */
+#define	FIFO_INT_RX_STS_LEVEL_		(0x000000FF)  /* R/W */
+
+#define RX_CFG			(0x6C)
+#define	RX_CFG_RX_END_ALGN_		(0xC0000000)  /* R/W */
+#define		RX_CFG_RX_END_ALGN4_		(0x00000000)  /* R/W */
+#define		RX_CFG_RX_END_ALGN16_		(0x40000000)  /* R/W */
+#define		RX_CFG_RX_END_ALGN32_		(0x80000000)  /* R/W */
+#define	RX_CFG_RX_DMA_CNT_		(0x0FFF0000)  /* R/W */
+#define	RX_CFG_RX_DUMP_			(0x00008000)  /* R/W */
+#define	RX_CFG_RXDOFF_			(0x00001F00)  /* R/W */
+//#define	RX_CFG_RXBAD_			(0x00000001)  /* R/W */
+
+#define TX_CFG			(0x70)
+//#define	TX_CFG_TX_DMA_LVL_		(0xE0000000)	 /* R/W */
+//#define	TX_CFG_TX_DMA_CNT_		(0x0FFF0000)	 /* R/W Self Clearing */
+#define	TX_CFG_TXS_DUMP_		(0x00008000)  /* Self Clearing */
+#define	TX_CFG_TXD_DUMP_		(0x00004000)  /* Self Clearing */
+#define	TX_CFG_TXSAO_			(0x00000004)  /* R/W */
+#define	TX_CFG_TX_ON_			(0x00000002)  /* R/W */
+#define	TX_CFG_STOP_TX_			(0x00000001)  /* Self Clearing */
+
+#define HW_CFG			(0x74)
+#define	HW_CFG_TTM_			(0x00200000)  /* R/W */
+#define	HW_CFG_SF_			(0x00100000)  /* R/W */
+#define	HW_CFG_TX_FIF_SZ_		(0x000F0000)  /* R/W */
+#define	HW_CFG_TR_			(0x00003000)  /* R/W */
+#define	HW_CFG_PHY_CLK_SEL_		(0x00000060)  /* R/W */
+#define		 HW_CFG_PHY_CLK_SEL_INT_PHY_ 	(0x00000000) /* R/W */
+#define		 HW_CFG_PHY_CLK_SEL_EXT_PHY_ 	(0x00000020) /* R/W */
+#define		 HW_CFG_PHY_CLK_SEL_CLK_DIS_ 	(0x00000040) /* R/W */
+#define	HW_CFG_SMI_SEL_			(0x00000010)  /* R/W */
+#define	HW_CFG_EXT_PHY_DET_		(0x00000008)  /* RO */
+#define	HW_CFG_EXT_PHY_EN_		(0x00000004)  /* R/W */
+#define	HW_CFG_32_16_BIT_MODE_		(0x00000004)  /* RO */
+#define	HW_CFG_SRST_TO_			(0x00000002)  /* RO */
+#define	HW_CFG_SRST_			(0x00000001)  /* Self Clearing */
+
+#define RX_DP_CTRL		(0x78)
+#define	RX_DP_CTRL_RX_FFWD_		(0x80000000)  /* R/W */
+#define	RX_DP_CTRL_FFWD_BUSY_		(0x80000000)  /* RO */
+
+#define RX_FIFO_INF		(0x7C)
+#define	 RX_FIFO_INF_RXSUSED_		(0x00FF0000)  /* RO */
+#define	 RX_FIFO_INF_RXDUSED_		(0x0000FFFF)  /* RO */
+
+#define TX_FIFO_INF		(0x80)
+#define	TX_FIFO_INF_TSUSED_		(0x00FF0000)  /* RO */
+#define	TX_FIFO_INF_TDFREE_		(0x0000FFFF)  /* RO */
+
+#define PMT_CTRL		(0x84)
+#define	PMT_CTRL_PM_MODE_		(0x00003000)  /* Self Clearing */
+#define	PMT_CTRL_PHY_RST_		(0x00000400)  /* Self Clearing */
+#define	PMT_CTRL_WOL_EN_		(0x00000200)  /* R/W */
+#define	PMT_CTRL_ED_EN_			(0x00000100)  /* R/W */
+#define	PMT_CTRL_PME_TYPE_		(0x00000040)  /* R/W Not Affected by SW Reset */
+#define	PMT_CTRL_WUPS_			(0x00000030)  /* R/WC */
+#define		PMT_CTRL_WUPS_NOWAKE_		(0x00000000)  /* R/WC */
+#define		PMT_CTRL_WUPS_ED_		(0x00000010)  /* R/WC */
+#define		PMT_CTRL_WUPS_WOL_		(0x00000020)  /* R/WC */
+#define		PMT_CTRL_WUPS_MULTI_		(0x00000030)  /* R/WC */
+#define	PMT_CTRL_PME_IND_		(0x00000008)  /* R/W */
+#define	PMT_CTRL_PME_POL_		(0x00000004)  /* R/W */
+#define	PMT_CTRL_PME_EN_		(0x00000002)  /* R/W Not Affected by SW Reset */
+#define	PMT_CTRL_READY_			(0x00000001)  /* RO */
+
+#define GPIO_CFG		(0x88)
+#define	GPIO_CFG_LED3_EN_		(0x40000000)  /* R/W */
+#define	GPIO_CFG_LED2_EN_		(0x20000000)  /* R/W */
+#define	GPIO_CFG_LED1_EN_		(0x10000000)  /* R/W */
+#define	GPIO_CFG_GPIO2_INT_POL_		(0x04000000)  /* R/W */
+#define	GPIO_CFG_GPIO1_INT_POL_		(0x02000000)  /* R/W */
+#define	GPIO_CFG_GPIO0_INT_POL_		(0x01000000)  /* R/W */
+#define	GPIO_CFG_EEPR_EN_		(0x00700000)  /* R/W */
+#define	GPIO_CFG_GPIOBUF2_		(0x00040000)  /* R/W */
+#define	GPIO_CFG_GPIOBUF1_		(0x00020000)  /* R/W */
+#define	GPIO_CFG_GPIOBUF0_		(0x00010000)  /* R/W */
+#define	GPIO_CFG_GPIODIR2_		(0x00000400)  /* R/W */
+#define	GPIO_CFG_GPIODIR1_		(0x00000200)  /* R/W */
+#define	GPIO_CFG_GPIODIR0_		(0x00000100)  /* R/W */
+#define	GPIO_CFG_GPIOD4_		(0x00000010)  /* R/W */
+#define	GPIO_CFG_GPIOD3_		(0x00000008)  /* R/W */
+#define	GPIO_CFG_GPIOD2_		(0x00000004)  /* R/W */
+#define	GPIO_CFG_GPIOD1_		(0x00000002)  /* R/W */
+#define	GPIO_CFG_GPIOD0_		(0x00000001)  /* R/W */
+
+#define GPT_CFG			(0x8C)
+#define	GPT_CFG_TIMER_EN_		(0x20000000)  /* R/W */
+#define	GPT_CFG_GPT_LOAD_		(0x0000FFFF)  /* R/W */
+
+#define GPT_CNT			(0x90)
+#define	GPT_CNT_GPT_CNT_		(0x0000FFFF)  /* RO */
+
+#define ENDIAN			(0x98)
+#define FREE_RUN		(0x9C)
+#define RX_DROP			(0xA0)
+#define MAC_CSR_CMD		(0xA4)
+#define	 MAC_CSR_CMD_CSR_BUSY_		(0x80000000)  /* Self Clearing */
+#define	 MAC_CSR_CMD_R_NOT_W_		(0x40000000)  /* R/W */
+#define	 MAC_CSR_CMD_CSR_ADDR_		(0x000000FF)  /* R/W */
+
+#define MAC_CSR_DATA		(0xA8)
+#define AFC_CFG			(0xAC)
+#define		AFC_CFG_AFC_HI_			(0x00FF0000)  /* R/W */
+#define		AFC_CFG_AFC_LO_			(0x0000FF00)  /* R/W */
+#define		AFC_CFG_BACK_DUR_		(0x000000F0)  /* R/W */
+#define		AFC_CFG_FCMULT_			(0x00000008)  /* R/W */
+#define		AFC_CFG_FCBRD_			(0x00000004)  /* R/W */
+#define		AFC_CFG_FCADD_			(0x00000002)  /* R/W */
+#define		AFC_CFG_FCANY_			(0x00000001)  /* R/W */
+
+#define E2P_CMD			(0xB0)
+#define	E2P_CMD_EPC_BUSY_		(0x80000000)  /* Self Clearing */
+#define	E2P_CMD_EPC_CMD_			(0x70000000)  /* R/W */
+#define		E2P_CMD_EPC_CMD_READ_		(0x00000000)  /* R/W */
+#define		E2P_CMD_EPC_CMD_EWDS_		(0x10000000)  /* R/W */
+#define		E2P_CMD_EPC_CMD_EWEN_		(0x20000000)  /* R/W */
+#define		E2P_CMD_EPC_CMD_WRITE_		(0x30000000)  /* R/W */
+#define		E2P_CMD_EPC_CMD_WRAL_		(0x40000000)  /* R/W */
+#define		E2P_CMD_EPC_CMD_ERASE_		(0x50000000)  /* R/W */
+#define		E2P_CMD_EPC_CMD_ERAL_		(0x60000000)  /* R/W */
+#define		E2P_CMD_EPC_CMD_RELOAD_		(0x70000000)  /* R/W */
+#define	E2P_CMD_EPC_TIMEOUT_		(0x00000200)  /* RO */
+#define	E2P_CMD_MAC_ADDR_LOADED_	(0x00000100)  /* RO */
+#define	E2P_CMD_EPC_ADDR_		(0x000000FF)  /* R/W */
+
+#define E2P_DATA		(0xB4)
+#define	E2P_DATA_EEPROM_DATA_		(0x000000FF)  /* R/W */
+/* end of LAN register offsets and bit definitions */
+
+/*
+ ****************************************************************************
+ ****************************************************************************
+ * MAC Control and Status Register (Indirect Address)
+ * Offset (through the MAC_CSR CMD and DATA port)
+ ****************************************************************************
+ ****************************************************************************
+ *
+ */
+#define MAC_CR			(0x01)  /* R/W */
+
+/* MAC_CR - MAC Control Register */
+#define MAC_CR_RXALL_			(0x80000000)
+// TODO: delete this bit? It is not described in the data sheet.
+#define MAC_CR_HBDIS_			(0x10000000)
+#define MAC_CR_RCVOWN_			(0x00800000)
+#define MAC_CR_LOOPBK_			(0x00200000)
+#define MAC_CR_FDPX_			(0x00100000)
+#define MAC_CR_MCPAS_			(0x00080000)
+#define MAC_CR_PRMS_			(0x00040000)
+#define MAC_CR_INVFILT_			(0x00020000)
+#define MAC_CR_PASSBAD_			(0x00010000)
+#define MAC_CR_HFILT_			(0x00008000)
+#define MAC_CR_HPFILT_			(0x00002000)
+#define MAC_CR_LCOLL_			(0x00001000)
+#define MAC_CR_BCAST_			(0x00000800)
+#define MAC_CR_DISRTY_			(0x00000400)
+#define MAC_CR_PADSTR_			(0x00000100)
+#define MAC_CR_BOLMT_MASK_		(0x000000C0)
+#define MAC_CR_DFCHK_			(0x00000020)
+#define MAC_CR_TXEN_			(0x00000008)
+#define MAC_CR_RXEN_			(0x00000004)
+
+#define ADDRH			(0x02)	  /* R/W mask 0x0000FFFFUL */
+#define ADDRL			(0x03)	  /* R/W mask 0xFFFFFFFFUL */
+#define HASHH			(0x04)	  /* R/W */
+#define HASHL			(0x05)	  /* R/W */
+
+#define MII_ACC			(0x06)	  /* R/W */
+#define MII_ACC_PHY_ADDR_		(0x0000F800)
+#define MII_ACC_MIIRINDA_		(0x000007C0)
+#define MII_ACC_MII_WRITE_		(0x00000002)
+#define MII_ACC_MII_BUSY_		(0x00000001)
+
+#define MII_DATA		(0x07)	  /* R/W mask 0x0000FFFFUL */
+
+#define FLOW			(0x08)	  /* R/W */
+#define FLOW_FCPT_			(0xFFFF0000)
+#define FLOW_FCPASS_			(0x00000004)
+#define FLOW_FCEN_			(0x00000002)
+#define FLOW_FCBSY_			(0x00000001)
+
+#define VLAN1			(0x09)	  /* R/W mask 0x0000FFFFUL */
+#define VLAN1_VTI1_			(0x0000ffff)
+
+#define VLAN2			(0x0A)	  /* R/W mask 0x0000FFFFUL */
+#define VLAN2_VTI2_			(0x0000ffff)
+
+#define WUFF			(0x0B)	  /* WO */
+
+#define WUCSR			(0x0C)	  /* R/W */
+#define WUCSR_GUE_			(0x00000200)
+#define WUCSR_WUFR_			(0x00000040)
+#define WUCSR_MPR_			(0x00000020)
+#define WUCSR_WAKE_EN_			(0x00000004)
+#define WUCSR_MPEN_			(0x00000002)
+
+/*
+ ****************************************************************************
+ * Chip Specific MII Defines
+ ****************************************************************************
+ *
+ * Phy register offsets and bit definitions
+ *
+ */
+
+#define PHY_MODE_CTRL_STS	((u32)17)	/* Mode Control/Status Register */
+//#define MODE_CTRL_STS_FASTRIP_	  ((u16)0x4000)
+#define MODE_CTRL_STS_EDPWRDOWN_	 ((u16)0x2000)
+//#define MODE_CTRL_STS_LOWSQEN_	   ((u16)0x0800)
+//#define MODE_CTRL_STS_MDPREBP_	   ((u16)0x0400)
+//#define MODE_CTRL_STS_FARLOOPBACK_  ((u16)0x0200)
+//#define MODE_CTRL_STS_FASTEST_	   ((u16)0x0100)
+//#define MODE_CTRL_STS_REFCLKEN_	   ((u16)0x0010)
+//#define MODE_CTRL_STS_PHYADBP_	   ((u16)0x0008)
+//#define MODE_CTRL_STS_FORCE_G_LINK_ ((u16)0x0004)
+#define MODE_CTRL_STS_ENERGYON_	 	((u16)0x0002)
+
+#define PHY_INT_SRC			((u32)29)
+#define PHY_INT_SRC_ENERGY_ON_			((u16)0x0080)
+#define PHY_INT_SRC_ANEG_COMP_			((u16)0x0040)
+#define PHY_INT_SRC_REMOTE_FAULT_		((u16)0x0020)
+#define PHY_INT_SRC_LINK_DOWN_			((u16)0x0010)
+#define PHY_INT_SRC_ANEG_LP_ACK_		((u16)0x0008)
+#define PHY_INT_SRC_PAR_DET_FAULT_		((u16)0x0004)
+#define PHY_INT_SRC_ANEG_PGRX_			((u16)0x0002)
+
+#define PHY_INT_MASK			((u32)30)
+#define PHY_INT_MASK_ENERGY_ON_			((u16)0x0080)
+#define PHY_INT_MASK_ANEG_COMP_			((u16)0x0040)
+#define PHY_INT_MASK_REMOTE_FAULT_		((u16)0x0020)
+#define PHY_INT_MASK_LINK_DOWN_			((u16)0x0010)
+#define PHY_INT_MASK_ANEG_LP_ACK_		((u16)0x0008)
+#define PHY_INT_MASK_PAR_DET_FAULT_		((u16)0x0004)
+#define PHY_INT_MASK_ANEG_PGRX_			((u16)0x0002)
+
+#define PHY_SPECIAL			((u32)31)
+#define PHY_SPECIAL_ANEG_DONE_			((u16)0x1000)
+#define PHY_SPECIAL_RES_			((u16)0x0040)
+#define PHY_SPECIAL_RES_MASK_			((u16)0x0FE1)
+#define PHY_SPECIAL_SPD_			((u16)0x001C)
+#define PHY_SPECIAL_SPD_10HALF_			((u16)0x0004)
+#define PHY_SPECIAL_SPD_10FULL_			((u16)0x0014)
+#define PHY_SPECIAL_SPD_100HALF_		((u16)0x0008)
+#define PHY_SPECIAL_SPD_100FULL_		((u16)0x0018)
+
+#define LAN911X_INTERNAL_PHY_ID		(0x0007C000)
+
+/* Chip ID values */
+#define CHIP_9115	0x115
+#define CHIP_9116	0x116
+#define CHIP_9117	0x117
+#define CHIP_9118	0x118
+
+struct chip_id {
+	u16 id;
+	char *name;
+};
+
+static const struct chip_id chip_ids[] =  {
+	{ CHIP_9115, "LAN9115" },
+	{ CHIP_9116, "LAN9116" },
+	{ CHIP_9117, "LAN9117" },
+	{ CHIP_9118, "LAN9118" },
+	{ 0, NULL },
+};
+
+#define IS_REV_A(x)	((x & 0xFFFF)==0)
+
+/*
+ * Macros to abstract register access according to the data bus
+ * capabilities.  Please use those and not the in/out primitives.
+ */
+/* FIFO read/write macros */
+#define SMC_PUSH_DATA(p, l)	SMC_outsl( ioaddr, TX_DATA_FIFO, p, (l) >> 2 )
+#define SMC_PULL_DATA(p, l)	SMC_insl ( ioaddr, RX_DATA_FIFO, p, (l) >> 2 )
+#define SMC_SET_TX_FIFO(x) 	SMC_outl( x, ioaddr, TX_DATA_FIFO )
+#define SMC_GET_RX_FIFO()	SMC_inl( ioaddr, RX_DATA_FIFO )
+
+
+/* I/O mapped register read/write macros */
+#define SMC_GET_TX_STS_FIFO()		SMC_inl( ioaddr, TX_STATUS_FIFO )
+#define SMC_GET_RX_STS_FIFO()		SMC_inl( ioaddr, RX_STATUS_FIFO )
+#define SMC_GET_RX_STS_FIFO_PEEK()	SMC_inl( ioaddr, RX_STATUS_FIFO_PEEK )
+#define SMC_GET_PN()			(SMC_inl( ioaddr, ID_REV ) >> 16)
+#define SMC_GET_REV()			(SMC_inl( ioaddr, ID_REV ) & 0xFFFF)
+#define SMC_GET_IRQ_CFG()		SMC_inl( ioaddr, INT_CFG )
+#define SMC_SET_IRQ_CFG(x)		SMC_outl( x, ioaddr, INT_CFG )
+#define SMC_GET_INT()			SMC_inl( ioaddr, INT_STS )
+#define SMC_ACK_INT(x)			SMC_outl( x, ioaddr, INT_STS )
+#define SMC_GET_INT_EN()		SMC_inl( ioaddr, INT_EN )
+#define SMC_SET_INT_EN(x)		SMC_outl( x, ioaddr, INT_EN )
+#define SMC_GET_BYTE_TEST()		SMC_inl( ioaddr, BYTE_TEST )
+#define SMC_SET_BYTE_TEST(x)		SMC_outl( x, ioaddr, BYTE_TEST )
+#define SMC_GET_FIFO_INT()		SMC_inl( ioaddr, FIFO_INT )
+#define SMC_SET_FIFO_INT(x)		SMC_outl( x, ioaddr, FIFO_INT )
+#define SMC_SET_FIFO_TDA(x)					\
+	do {							\
+		unsigned long __flags;				\
+		int __mask;					\
+		local_irq_save(__flags);			\
+		__mask = SMC_GET_FIFO_INT() & ~(0xFF<<24);	\
+		SMC_SET_FIFO_INT( __mask | (x)<<24 );		\
+		local_irq_restore(__flags);			\
+	} while (0)
+#define SMC_SET_FIFO_TSL(x)					\
+	do {							\
+		unsigned long __flags;				\
+		int __mask;					\
+		local_irq_save(__flags);			\
+		__mask = SMC_GET_FIFO_INT() & ~(0xFF<<16);	\
+		SMC_SET_FIFO_INT( __mask | (((x) & 0xFF)<<16));	\
+		local_irq_restore(__flags);			\
+	} while (0)
+#define SMC_SET_FIFO_RSA(x)					\
+	do {							\
+		unsigned long __flags;				\
+		int __mask;					\
+		local_irq_save(__flags);			\
+		__mask = SMC_GET_FIFO_INT() & ~(0xFF<<8);	\
+		SMC_SET_FIFO_INT( __mask | (((x) & 0xFF)<<8));	\
+		local_irq_restore(__flags);			\
+	} while (0)
+#define SMC_SET_FIFO_RSL(x)					\
+	do {							\
+		unsigned long __flags;				\
+		int __mask;					\
+		local_irq_save(__flags);			\
+		__mask = SMC_GET_FIFO_INT() & ~0xFF;		\
+		SMC_SET_FIFO_INT( __mask | ((x) & 0xFF));	\
+		local_irq_restore(__flags);			\
+	} while (0)
+#define SMC_GET_RX_CFG()		SMC_inl( ioaddr, RX_CFG )
+#define SMC_SET_RX_CFG(x)		SMC_outl( x, ioaddr, RX_CFG )
+#define SMC_GET_TX_CFG()		SMC_inl( ioaddr, TX_CFG )
+#define SMC_SET_TX_CFG(x)		SMC_outl( x, ioaddr, TX_CFG )
+#define SMC_GET_HW_CFG()		SMC_inl( ioaddr, HW_CFG )
+#define SMC_SET_HW_CFG(x)		SMC_outl( x, ioaddr, HW_CFG )
+#define SMC_GET_RX_DP_CTRL()		SMC_inl( ioaddr, RX_DP_CTRL )
+#define SMC_SET_RX_DP_CTRL(x)		SMC_outl( x, ioaddr, RX_DP_CTRL )
+#define SMC_GET_PMT_CTRL()		SMC_inl( ioaddr, PMT_CTRL )
+#define SMC_SET_PMT_CTRL(x)		SMC_outl( x, ioaddr, PMT_CTRL )
+#define SMC_GET_GPIO_CFG()		SMC_inl( ioaddr, GPIO_CFG )
+#define SMC_SET_GPIO_CFG(x)		SMC_outl( x, ioaddr, GPIO_CFG )
+#define SMC_GET_RX_FIFO_INF()		SMC_inl( ioaddr, RX_FIFO_INF )
+#define SMC_SET_RX_FIFO_INF(x)		SMC_outl( x, ioaddr, RX_FIFO_INF )
+#define SMC_GET_TX_FIFO_INF()		SMC_inl( ioaddr, TX_FIFO_INF )
+#define SMC_SET_TX_FIFO_INF(x)		SMC_outl( x, ioaddr, TX_FIFO_INF )
+#define SMC_GET_GPT_CFG()		SMC_inl( ioaddr, GPT_CFG )
+#define SMC_SET_GPT_CFG(x)		SMC_outl( x, ioaddr, GPT_CFG )
+#define SMC_GET_RX_DROP()		SMC_inl( ioaddr, RX_DROP )
+#define SMC_SET_RX_DROP(x)		SMC_outl( x, ioaddr, RX_DROP )
+#define SMC_GET_MAC_CMD()		SMC_inl( ioaddr, MAC_CSR_CMD )
+#define SMC_SET_MAC_CMD(x)		SMC_outl( x, ioaddr, MAC_CSR_CMD )
+#define SMC_GET_MAC_DATA()		SMC_inl( ioaddr, MAC_CSR_DATA )
+#define SMC_SET_MAC_DATA(x)		SMC_outl( x, ioaddr, MAC_CSR_DATA )
+#define SMC_GET_AFC_CFG()		SMC_inl( ioaddr, AFC_CFG )
+#define SMC_SET_AFC_CFG(x)		SMC_outl( x, ioaddr, AFC_CFG )
+#define SMC_GET_E2P_CMD()		SMC_inl( ioaddr, E2P_CMD )
+#define SMC_SET_E2P_CMD(x)		SMC_outl( x, ioaddr, E2P_CMD )
+#define SMC_GET_E2P_DATA()		SMC_inl( ioaddr, E2P_DATA )
+#define SMC_SET_E2P_DATA(x)		SMC_outl( x, ioaddr, E2P_DATA )
+
+/* MAC register read/write macros */
+#define SMC_GET_MAC_CSR(a,v)						\
+	do {								\
+		while (SMC_GET_MAC_CMD() & MAC_CSR_CMD_CSR_BUSY_);	\
+		SMC_SET_MAC_CMD(MAC_CSR_CMD_CSR_BUSY_ |			\
+			MAC_CSR_CMD_R_NOT_W_ | (a) );			\
+		while (SMC_GET_MAC_CMD() & MAC_CSR_CMD_CSR_BUSY_);	\
+		v = SMC_GET_MAC_DATA();					\
+	} while (0)
+#define SMC_SET_MAC_CSR(a,v)						\
+	do {								\
+		while (SMC_GET_MAC_CMD() & MAC_CSR_CMD_CSR_BUSY_);	\
+		SMC_SET_MAC_DATA(v);					\
+		SMC_SET_MAC_CMD(MAC_CSR_CMD_CSR_BUSY_ | (a) );		\
+		while (SMC_GET_MAC_CMD() & MAC_CSR_CMD_CSR_BUSY_);	\
+	} while (0)
+#define SMC_GET_MAC_CR(x)	SMC_GET_MAC_CSR( MAC_CR, x )
+#define SMC_SET_MAC_CR(x)	SMC_SET_MAC_CSR( MAC_CR, x )
+#define SMC_GET_ADDRH(x)	SMC_GET_MAC_CSR( ADDRH, x )
+#define SMC_SET_ADDRH(x)	SMC_SET_MAC_CSR( ADDRH, x )
+#define SMC_GET_ADDRL(x)	SMC_GET_MAC_CSR( ADDRL, x )
+#define SMC_SET_ADDRL(x)	SMC_SET_MAC_CSR( ADDRL, x )
+#define SMC_GET_HASHH(x)	SMC_GET_MAC_CSR( HASHH, x )
+#define SMC_SET_HASHH(x)	SMC_SET_MAC_CSR( HASHH, x )
+#define SMC_GET_HASHL(x)	SMC_GET_MAC_CSR( HASHL, x )
+#define SMC_SET_HASHL(x)	SMC_SET_MAC_CSR( HASHL, x )
+#define SMC_GET_MII_ACC(x)	SMC_GET_MAC_CSR( MII_ACC, x )
+#define SMC_SET_MII_ACC(x)	SMC_SET_MAC_CSR( MII_ACC, x )
+#define SMC_GET_MII_DATA(x)	SMC_GET_MAC_CSR( MII_DATA, x )
+#define SMC_SET_MII_DATA(x)	SMC_SET_MAC_CSR( MII_DATA, x )
+#define SMC_GET_FLOW(x)		SMC_GET_MAC_CSR( FLOW, x )
+#define SMC_SET_FLOW(x)		SMC_SET_MAC_CSR( FLOW, x )
+#define SMC_GET_VLAN1(x)	SMC_GET_MAC_CSR( VLAN1, x )
+#define SMC_SET_VLAN1(x)	SMC_SET_MAC_CSR( VLAN1, x )
+#define SMC_GET_VLAN2(x)	SMC_GET_MAC_CSR( VLAN2, x )
+#define SMC_SET_VLAN2(x)	SMC_SET_MAC_CSR( VLAN2, x )
+#define SMC_SET_WUFF(x)		SMC_SET_MAC_CSR( WUFF, x )
+#define SMC_GET_WUCSR(x)	SMC_GET_MAC_CSR( WUCSR, x )
+#define SMC_SET_WUCSR(x)	SMC_SET_MAC_CSR( WUCSR, x )
+
+/* PHY register read/write macros */
+#define SMC_GET_MII(a,phy,v)					\
+	do {							\
+		u32 __v;					\
+		do {						\
+			SMC_GET_MII_ACC(__v);			\
+		} while ( __v & MII_ACC_MII_BUSY_ );		\
+		SMC_SET_MII_ACC( ((phy)<<11) | ((a)<<6) |	\
+			MII_ACC_MII_BUSY_);			\
+		do {						\
+			SMC_GET_MII_ACC(__v);			\
+		} while ( __v & MII_ACC_MII_BUSY_ );		\
+		SMC_GET_MII_DATA(v);				\
+	} while (0)
+#define SMC_SET_MII(a,phy,v)					\
+	do {							\
+		u32 __v;					\
+		do {						\
+			SMC_GET_MII_ACC(__v);			\
+		} while ( __v & MII_ACC_MII_BUSY_ );		\
+		SMC_SET_MII_DATA(v);				\
+		SMC_SET_MII_ACC( ((phy)<<11) | ((a)<<6) |	\
+			MII_ACC_MII_BUSY_	 |		\
+			MII_ACC_MII_WRITE_  );			\
+		do {						\
+			SMC_GET_MII_ACC(__v);			\
+		} while ( __v & MII_ACC_MII_BUSY_ );		\
+	} while (0)
+#define SMC_GET_PHY_BMCR(phy,x)		SMC_GET_MII( MII_BMCR, phy, x )
+#define SMC_SET_PHY_BMCR(phy,x)		SMC_SET_MII( MII_BMCR, phy, x )
+#define SMC_GET_PHY_BMSR(phy,x)		SMC_GET_MII( MII_BMSR, phy, x )
+#define SMC_GET_PHY_ID1(phy,x)		SMC_GET_MII( MII_PHYSID1, phy, x )
+#define SMC_GET_PHY_ID2(phy,x)		SMC_GET_MII( MII_PHYSID2, phy, x )
+#define SMC_GET_PHY_MII_ADV(phy,x)	SMC_GET_MII( MII_ADVERTISE, phy, x )
+#define SMC_SET_PHY_MII_ADV(phy,x)	SMC_SET_MII( MII_ADVERTISE, phy, x )
+#define SMC_GET_PHY_MII_LPA(phy,x)	SMC_GET_MII( MII_LPA, phy, x )
+#define SMC_SET_PHY_MII_LPA(phy,x)	SMC_SET_MII( MII_LPA, phy, x )
+#define SMC_GET_PHY_CTRL_STS(phy,x)	SMC_GET_MII( PHY_MODE_CTRL_STS, phy, x )
+#define SMC_SET_PHY_CTRL_STS(phy,x)	SMC_SET_MII( PHY_MODE_CTRL_STS, phy, x )
+#define SMC_GET_PHY_INT_SRC(phy,x)	SMC_GET_MII( PHY_INT_SRC, phy, x )
+#define SMC_SET_PHY_INT_SRC(phy,x)	SMC_SET_MII( PHY_INT_SRC, phy, x )
+#define SMC_GET_PHY_INT_MASK(phy,x)	SMC_GET_MII( PHY_INT_MASK, phy, x )
+#define SMC_SET_PHY_INT_MASK(phy,x)	SMC_SET_MII( PHY_INT_MASK, phy, x )
+#define SMC_GET_PHY_SPECIAL(phy,x)	SMC_GET_MII( PHY_SPECIAL, phy, x )
+
+
+
+/* Misc read/write macros */
+
+#ifndef SMC_GET_MAC_ADDR
+#define SMC_GET_MAC_ADDR(addr)					\
+	do {							\
+		unsigned int __v;				\
+								\
+		SMC_GET_MAC_CSR(ADDRL, __v);			\
+		addr[0] = __v; addr[1] = __v >> 8;		\
+		addr[2] = __v >> 16; addr[3] = __v >> 24;	\
+		SMC_GET_MAC_CSR(ADDRH, __v);			\
+		addr[4] = __v; addr[5] = __v >> 8;		\
+	} while (0)
+#endif
+
+#define SMC_SET_MAC_ADDR(addr)					\
+	do {							\
+		 SMC_SET_MAC_CSR(ADDRL,				\
+				 addr[0] |			\
+				(addr[1] << 8) |		\
+				(addr[2] << 16) |		\
+				(addr[3] << 24));		\
+		 SMC_SET_MAC_CSR(ADDRH, addr[4]|(addr[5] << 8));\
+	} while (0)
+
+
+#define SMC_WRITE_EEPROM_CMD(cmd, addr)					\
+	do {								\
+		while (SMC_GET_E2P_CMD() & MAC_CSR_CMD_CSR_BUSY_);	\
+		SMC_SET_MAC_CMD(MAC_CSR_CMD_R_NOT_W_ | a );		\
+		while (SMC_GET_MAC_CMD() & MAC_CSR_CMD_CSR_BUSY_);	\
+	} while (0)
+
+#endif	 /* _SMC911X_H_ */
diff --git a/drivers/net/ucc_geth.c b/drivers/net/ucc_geth.c
new file mode 100644
index 000000000..47f49ef72
--- /dev/null
+++ b/drivers/net/ucc_geth.c
@@ -0,0 +1,4278 @@
+/*
+ * Copyright (C) Freescale Semicondutor, Inc. 2006. All rights reserved.
+ *
+ * Author: Shlomi Gridish <gridish@freescale.com>
+ *
+ * Description:
+ * QE UCC Gigabit Ethernet Driver
+ *
+ * Changelog:
+ * Jul 6, 2006 Li Yang <LeoLi@freescale.com>
+ * - Rearrange code and style fixes
+ *
+ * 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/kernel.h>
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/slab.h>
+#include <linux/stddef.h>
+#include <linux/interrupt.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/skbuff.h>
+#include <linux/spinlock.h>
+#include <linux/mm.h>
+#include <linux/ethtool.h>
+#include <linux/delay.h>
+#include <linux/dma-mapping.h>
+#include <linux/fsl_devices.h>
+#include <linux/ethtool.h>
+#include <linux/platform_device.h>
+#include <linux/mii.h>
+
+#include <asm/uaccess.h>
+#include <asm/irq.h>
+#include <asm/io.h>
+#include <asm/immap_qe.h>
+#include <asm/qe.h>
+#include <asm/ucc.h>
+#include <asm/ucc_fast.h>
+
+#include "ucc_geth.h"
+#include "ucc_geth_phy.h"
+
+#undef DEBUG
+
+#define DRV_DESC "QE UCC Gigabit Ethernet Controller version:June 20, 2006"
+#define DRV_NAME "ucc_geth"
+
+#define ugeth_printk(level, format, arg...)  \
+        printk(level format "\n", ## arg)
+
+#define ugeth_dbg(format, arg...)            \
+        ugeth_printk(KERN_DEBUG , format , ## arg)
+#define ugeth_err(format, arg...)            \
+        ugeth_printk(KERN_ERR , format , ## arg)
+#define ugeth_info(format, arg...)           \
+        ugeth_printk(KERN_INFO , format , ## arg)
+#define ugeth_warn(format, arg...)           \
+        ugeth_printk(KERN_WARNING , format , ## arg)
+
+#ifdef UGETH_VERBOSE_DEBUG
+#define ugeth_vdbg ugeth_dbg
+#else
+#define ugeth_vdbg(fmt, args...) do { } while (0)
+#endif				/* UGETH_VERBOSE_DEBUG */
+
+static DEFINE_SPINLOCK(ugeth_lock);
+
+static ucc_geth_info_t ugeth_primary_info = {
+	.uf_info = {
+		    .bd_mem_part = MEM_PART_SYSTEM,
+		    .rtsm = UCC_FAST_SEND_IDLES_BETWEEN_FRAMES,
+		    .max_rx_buf_length = 1536,
+/* FIXME: should be changed in run time for 1G and 100M */
+#ifdef CONFIG_UGETH_HAS_GIGA
+		    .urfs = UCC_GETH_URFS_GIGA_INIT,
+		    .urfet = UCC_GETH_URFET_GIGA_INIT,
+		    .urfset = UCC_GETH_URFSET_GIGA_INIT,
+		    .utfs = UCC_GETH_UTFS_GIGA_INIT,
+		    .utfet = UCC_GETH_UTFET_GIGA_INIT,
+		    .utftt = UCC_GETH_UTFTT_GIGA_INIT,
+#else
+		    .urfs = UCC_GETH_URFS_INIT,
+		    .urfet = UCC_GETH_URFET_INIT,
+		    .urfset = UCC_GETH_URFSET_INIT,
+		    .utfs = UCC_GETH_UTFS_INIT,
+		    .utfet = UCC_GETH_UTFET_INIT,
+		    .utftt = UCC_GETH_UTFTT_INIT,
+#endif
+		    .ufpt = 256,
+		    .mode = UCC_FAST_PROTOCOL_MODE_ETHERNET,
+		    .ttx_trx = UCC_FAST_GUMR_TRANSPARENT_TTX_TRX_NORMAL,
+		    .tenc = UCC_FAST_TX_ENCODING_NRZ,
+		    .renc = UCC_FAST_RX_ENCODING_NRZ,
+		    .tcrc = UCC_FAST_16_BIT_CRC,
+		    .synl = UCC_FAST_SYNC_LEN_NOT_USED,
+		    },
+	.numQueuesTx = 1,
+	.numQueuesRx = 1,
+	.extendedFilteringChainPointer = ((uint32_t) NULL),
+	.typeorlen = 3072 /*1536 */ ,
+	.nonBackToBackIfgPart1 = 0x40,
+	.nonBackToBackIfgPart2 = 0x60,
+	.miminumInterFrameGapEnforcement = 0x50,
+	.backToBackInterFrameGap = 0x60,
+	.mblinterval = 128,
+	.nortsrbytetime = 5,
+	.fracsiz = 1,
+	.strictpriorityq = 0xff,
+	.altBebTruncation = 0xa,
+	.excessDefer = 1,
+	.maxRetransmission = 0xf,
+	.collisionWindow = 0x37,
+	.receiveFlowControl = 1,
+	.maxGroupAddrInHash = 4,
+	.maxIndAddrInHash = 4,
+	.prel = 7,
+	.maxFrameLength = 1518,
+	.minFrameLength = 64,
+	.maxD1Length = 1520,
+	.maxD2Length = 1520,
+	.vlantype = 0x8100,
+	.ecamptr = ((uint32_t) NULL),
+	.eventRegMask = UCCE_OTHER,
+	.pausePeriod = 0xf000,
+	.interruptcoalescingmaxvalue = {1, 1, 1, 1, 1, 1, 1, 1},
+	.bdRingLenTx = {
+			TX_BD_RING_LEN,
+			TX_BD_RING_LEN,
+			TX_BD_RING_LEN,
+			TX_BD_RING_LEN,
+			TX_BD_RING_LEN,
+			TX_BD_RING_LEN,
+			TX_BD_RING_LEN,
+			TX_BD_RING_LEN},
+
+	.bdRingLenRx = {
+			RX_BD_RING_LEN,
+			RX_BD_RING_LEN,
+			RX_BD_RING_LEN,
+			RX_BD_RING_LEN,
+			RX_BD_RING_LEN,
+			RX_BD_RING_LEN,
+			RX_BD_RING_LEN,
+			RX_BD_RING_LEN},
+
+	.numStationAddresses = UCC_GETH_NUM_OF_STATION_ADDRESSES_1,
+	.largestexternallookupkeysize =
+	    QE_FLTR_LARGEST_EXTERNAL_TABLE_LOOKUP_KEY_SIZE_NONE,
+	.statisticsMode = UCC_GETH_STATISTICS_GATHERING_MODE_NONE,
+	.vlanOperationTagged = UCC_GETH_VLAN_OPERATION_TAGGED_NOP,
+	.vlanOperationNonTagged = UCC_GETH_VLAN_OPERATION_NON_TAGGED_NOP,
+	.rxQoSMode = UCC_GETH_QOS_MODE_DEFAULT,
+	.aufc = UPSMR_AUTOMATIC_FLOW_CONTROL_MODE_NONE,
+	.padAndCrc = MACCFG2_PAD_AND_CRC_MODE_PAD_AND_CRC,
+	.numThreadsTx = UCC_GETH_NUM_OF_THREADS_4,
+	.numThreadsRx = UCC_GETH_NUM_OF_THREADS_4,
+	.riscTx = QE_RISC_ALLOCATION_RISC1_AND_RISC2,
+	.riscRx = QE_RISC_ALLOCATION_RISC1_AND_RISC2,
+};
+
+static ucc_geth_info_t ugeth_info[8];
+
+#ifdef DEBUG
+static void mem_disp(u8 *addr, int size)
+{
+	u8 *i;
+	int size16Aling = (size >> 4) << 4;
+	int size4Aling = (size >> 2) << 2;
+	int notAlign = 0;
+	if (size % 16)
+		notAlign = 1;
+
+	for (i = addr; (u32) i < (u32) addr + size16Aling; i += 16)
+		printk("0x%08x: %08x %08x %08x %08x\r\n",
+		       (u32) i,
+		       *((u32 *) (i)),
+		       *((u32 *) (i + 4)),
+		       *((u32 *) (i + 8)), *((u32 *) (i + 12)));
+	if (notAlign == 1)
+		printk("0x%08x: ", (u32) i);
+	for (; (u32) i < (u32) addr + size4Aling; i += 4)
+		printk("%08x ", *((u32 *) (i)));
+	for (; (u32) i < (u32) addr + size; i++)
+		printk("%02x", *((u8 *) (i)));
+	if (notAlign == 1)
+		printk("\r\n");
+}
+#endif /* DEBUG */
+
+#ifdef CONFIG_UGETH_FILTERING
+static void enqueue(struct list_head *node, struct list_head *lh)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(ugeth_lock, flags);
+	list_add_tail(node, lh);
+	spin_unlock_irqrestore(ugeth_lock, flags);
+}
+#endif /* CONFIG_UGETH_FILTERING */
+
+static struct list_head *dequeue(struct list_head *lh)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(ugeth_lock, flags);
+	if (!list_empty(lh)) {
+		struct list_head *node = lh->next;
+		list_del(node);
+		spin_unlock_irqrestore(ugeth_lock, flags);
+		return node;
+	} else {
+		spin_unlock_irqrestore(ugeth_lock, flags);
+		return NULL;
+	}
+}
+
+static int get_interface_details(enet_interface_e enet_interface,
+				 enet_speed_e *speed,
+				 int *r10m,
+				 int *rmm,
+				 int *rpm,
+				 int *tbi, int *limited_to_full_duplex)
+{
+	/* Analyze enet_interface according to Interface Mode
+	Configuration table */
+	switch (enet_interface) {
+	case ENET_10_MII:
+		*speed = ENET_SPEED_10BT;
+		break;
+	case ENET_10_RMII:
+		*speed = ENET_SPEED_10BT;
+		*r10m = 1;
+		*rmm = 1;
+		break;
+	case ENET_10_RGMII:
+		*speed = ENET_SPEED_10BT;
+		*rpm = 1;
+		*r10m = 1;
+		*limited_to_full_duplex = 1;
+		break;
+	case ENET_100_MII:
+		*speed = ENET_SPEED_100BT;
+		break;
+	case ENET_100_RMII:
+		*speed = ENET_SPEED_100BT;
+		*rmm = 1;
+		break;
+	case ENET_100_RGMII:
+		*speed = ENET_SPEED_100BT;
+		*rpm = 1;
+		*limited_to_full_duplex = 1;
+		break;
+	case ENET_1000_GMII:
+		*speed = ENET_SPEED_1000BT;
+		*limited_to_full_duplex = 1;
+		break;
+	case ENET_1000_RGMII:
+		*speed = ENET_SPEED_1000BT;
+		*rpm = 1;
+		*limited_to_full_duplex = 1;
+		break;
+	case ENET_1000_TBI:
+		*speed = ENET_SPEED_1000BT;
+		*tbi = 1;
+		*limited_to_full_duplex = 1;
+		break;
+	case ENET_1000_RTBI:
+		*speed = ENET_SPEED_1000BT;
+		*rpm = 1;
+		*tbi = 1;
+		*limited_to_full_duplex = 1;
+		break;
+	default:
+		return -EINVAL;
+		break;
+	}
+
+	return 0;
+}
+
+static struct sk_buff *get_new_skb(ucc_geth_private_t *ugeth, u8 *bd)
+{
+	struct sk_buff *skb = NULL;
+
+	skb = dev_alloc_skb(ugeth->ug_info->uf_info.max_rx_buf_length +
+				  UCC_GETH_RX_DATA_BUF_ALIGNMENT);
+
+	if (skb == NULL)
+		return NULL;
+
+	/* We need the data buffer to be aligned properly.  We will reserve
+	 * as many bytes as needed to align the data properly
+	 */
+	skb_reserve(skb,
+		    UCC_GETH_RX_DATA_BUF_ALIGNMENT -
+		    (((unsigned)skb->data) & (UCC_GETH_RX_DATA_BUF_ALIGNMENT -
+					      1)));
+
+	skb->dev = ugeth->dev;
+
+	BD_BUFFER_SET(bd,
+		      dma_map_single(NULL,
+				     skb->data,
+				     ugeth->ug_info->uf_info.max_rx_buf_length +
+				     UCC_GETH_RX_DATA_BUF_ALIGNMENT,
+				     DMA_FROM_DEVICE));
+
+	BD_STATUS_AND_LENGTH_SET(bd,
+				 (R_E | R_I |
+				  (BD_STATUS_AND_LENGTH(bd) & R_W)));
+
+	return skb;
+}
+
+static int rx_bd_buffer_set(ucc_geth_private_t *ugeth, u8 rxQ)
+{
+	u8 *bd;
+	u32 bd_status;
+	struct sk_buff *skb;
+	int i;
+
+	bd = ugeth->p_rx_bd_ring[rxQ];
+	i = 0;
+
+	do {
+		bd_status = BD_STATUS_AND_LENGTH(bd);
+		skb = get_new_skb(ugeth, bd);
+
+		if (!skb)	/* If can not allocate data buffer,
+				abort. Cleanup will be elsewhere */
+			return -ENOMEM;
+
+		ugeth->rx_skbuff[rxQ][i] = skb;
+
+		/* advance the BD pointer */
+		bd += UCC_GETH_SIZE_OF_BD;
+		i++;
+	} while (!(bd_status & R_W));
+
+	return 0;
+}
+
+static int fill_init_enet_entries(ucc_geth_private_t *ugeth,
+				  volatile u32 *p_start,
+				  u8 num_entries,
+				  u32 thread_size,
+				  u32 thread_alignment,
+				  qe_risc_allocation_e risc,
+				  int skip_page_for_first_entry)
+{
+	u32 init_enet_offset;
+	u8 i;
+	int snum;
+
+	for (i = 0; i < num_entries; i++) {
+		if ((snum = qe_get_snum()) < 0) {
+			ugeth_err("fill_init_enet_entries: Can not get SNUM.");
+			return snum;
+		}
+		if ((i == 0) && skip_page_for_first_entry)
+		/* First entry of Rx does not have page */
+			init_enet_offset = 0;
+		else {
+			init_enet_offset =
+			    qe_muram_alloc(thread_size, thread_alignment);
+			if (IS_MURAM_ERR(init_enet_offset)) {
+				ugeth_err
+		("fill_init_enet_entries: Can not allocate DPRAM memory.");
+				qe_put_snum((u8) snum);
+				return -ENOMEM;
+			}
+		}
+		*(p_start++) =
+		    ((u8) snum << ENET_INIT_PARAM_SNUM_SHIFT) | init_enet_offset
+		    | risc;
+	}
+
+	return 0;
+}
+
+static int return_init_enet_entries(ucc_geth_private_t *ugeth,
+				    volatile u32 *p_start,
+				    u8 num_entries,
+				    qe_risc_allocation_e risc,
+				    int skip_page_for_first_entry)
+{
+	u32 init_enet_offset;
+	u8 i;
+	int snum;
+
+	for (i = 0; i < num_entries; i++) {
+		/* Check that this entry was actually valid --
+		needed in case failed in allocations */
+		if ((*p_start & ENET_INIT_PARAM_RISC_MASK) == risc) {
+			snum =
+			    (u32) (*p_start & ENET_INIT_PARAM_SNUM_MASK) >>
+			    ENET_INIT_PARAM_SNUM_SHIFT;
+			qe_put_snum((u8) snum);
+			if (!((i == 0) && skip_page_for_first_entry)) {
+			/* First entry of Rx does not have page */
+				init_enet_offset =
+				    (in_be32(p_start) &
+				     ENET_INIT_PARAM_PTR_MASK);
+				qe_muram_free(init_enet_offset);
+			}
+			*(p_start++) = 0;	/* Just for cosmetics */
+		}
+	}
+
+	return 0;
+}
+
+#ifdef DEBUG
+static int dump_init_enet_entries(ucc_geth_private_t *ugeth,
+				  volatile u32 *p_start,
+				  u8 num_entries,
+				  u32 thread_size,
+				  qe_risc_allocation_e risc,
+				  int skip_page_for_first_entry)
+{
+	u32 init_enet_offset;
+	u8 i;
+	int snum;
+
+	for (i = 0; i < num_entries; i++) {
+		/* Check that this entry was actually valid --
+		needed in case failed in allocations */
+		if ((*p_start & ENET_INIT_PARAM_RISC_MASK) == risc) {
+			snum =
+			    (u32) (*p_start & ENET_INIT_PARAM_SNUM_MASK) >>
+			    ENET_INIT_PARAM_SNUM_SHIFT;
+			qe_put_snum((u8) snum);
+			if (!((i == 0) && skip_page_for_first_entry)) {
+			/* First entry of Rx does not have page */
+				init_enet_offset =
+				    (in_be32(p_start) &
+				     ENET_INIT_PARAM_PTR_MASK);
+				ugeth_info("Init enet entry %d:", i);
+				ugeth_info("Base address: 0x%08x",
+					   (u32)
+					   qe_muram_addr(init_enet_offset));
+				mem_disp(qe_muram_addr(init_enet_offset),
+					 thread_size);
+			}
+			p_start++;
+		}
+	}
+
+	return 0;
+}
+#endif
+
+#ifdef CONFIG_UGETH_FILTERING
+static enet_addr_container_t *get_enet_addr_container(void)
+{
+	enet_addr_container_t *enet_addr_cont;
+
+	/* allocate memory */
+	enet_addr_cont = kmalloc(sizeof(enet_addr_container_t), GFP_KERNEL);
+	if (!enet_addr_cont) {
+		ugeth_err("%s: No memory for enet_addr_container_t object.",
+			  __FUNCTION__);
+		return NULL;
+	}
+
+	return enet_addr_cont;
+}
+#endif /* CONFIG_UGETH_FILTERING */
+
+static void put_enet_addr_container(enet_addr_container_t *enet_addr_cont)
+{
+	kfree(enet_addr_cont);
+}
+
+#ifdef CONFIG_UGETH_FILTERING
+static int hw_add_addr_in_paddr(ucc_geth_private_t *ugeth,
+				enet_addr_t *p_enet_addr, u8 paddr_num)
+{
+	ucc_geth_82xx_address_filtering_pram_t *p_82xx_addr_filt;
+
+	if (!(paddr_num < NUM_OF_PADDRS)) {
+		ugeth_warn("%s: Illagel paddr_num.", __FUNCTION__);
+		return -EINVAL;
+	}
+
+	p_82xx_addr_filt =
+	    (ucc_geth_82xx_address_filtering_pram_t *) ugeth->p_rx_glbl_pram->
+	    addressfiltering;
+
+	/* Ethernet frames are defined in Little Endian mode,    */
+	/* therefore to insert the address we reverse the bytes. */
+	out_be16(&p_82xx_addr_filt->paddr[paddr_num].h,
+		 (u16) (((u16) (((u16) ((*p_enet_addr)[5])) << 8)) |
+			(u16) (*p_enet_addr)[4]));
+	out_be16(&p_82xx_addr_filt->paddr[paddr_num].m,
+		 (u16) (((u16) (((u16) ((*p_enet_addr)[3])) << 8)) |
+			(u16) (*p_enet_addr)[2]));
+	out_be16(&p_82xx_addr_filt->paddr[paddr_num].l,
+		 (u16) (((u16) (((u16) ((*p_enet_addr)[1])) << 8)) |
+			(u16) (*p_enet_addr)[0]));
+
+	return 0;
+}
+#endif /* CONFIG_UGETH_FILTERING */
+
+static int hw_clear_addr_in_paddr(ucc_geth_private_t *ugeth, u8 paddr_num)
+{
+	ucc_geth_82xx_address_filtering_pram_t *p_82xx_addr_filt;
+
+	if (!(paddr_num < NUM_OF_PADDRS)) {
+		ugeth_warn("%s: Illagel paddr_num.", __FUNCTION__);
+		return -EINVAL;
+	}
+
+	p_82xx_addr_filt =
+	    (ucc_geth_82xx_address_filtering_pram_t *) ugeth->p_rx_glbl_pram->
+	    addressfiltering;
+
+	/* Writing address ff.ff.ff.ff.ff.ff disables address
+	recognition for this register */
+	out_be16(&p_82xx_addr_filt->paddr[paddr_num].h, 0xffff);
+	out_be16(&p_82xx_addr_filt->paddr[paddr_num].m, 0xffff);
+	out_be16(&p_82xx_addr_filt->paddr[paddr_num].l, 0xffff);
+
+	return 0;
+}
+
+static void hw_add_addr_in_hash(ucc_geth_private_t *ugeth,
+				enet_addr_t *p_enet_addr)
+{
+	ucc_geth_82xx_address_filtering_pram_t *p_82xx_addr_filt;
+	u32 cecr_subblock;
+
+	p_82xx_addr_filt =
+	    (ucc_geth_82xx_address_filtering_pram_t *) ugeth->p_rx_glbl_pram->
+	    addressfiltering;
+
+	cecr_subblock =
+	    ucc_fast_get_qe_cr_subblock(ugeth->ug_info->uf_info.ucc_num);
+
+	/* Ethernet frames are defined in Little Endian mode,
+	therefor to insert */
+	/* the address to the hash (Big Endian mode), we reverse the bytes.*/
+	out_be16(&p_82xx_addr_filt->taddr.h,
+		 (u16) (((u16) (((u16) ((*p_enet_addr)[5])) << 8)) |
+			(u16) (*p_enet_addr)[4]));
+	out_be16(&p_82xx_addr_filt->taddr.m,
+		 (u16) (((u16) (((u16) ((*p_enet_addr)[3])) << 8)) |
+			(u16) (*p_enet_addr)[2]));
+	out_be16(&p_82xx_addr_filt->taddr.l,
+		 (u16) (((u16) (((u16) ((*p_enet_addr)[1])) << 8)) |
+			(u16) (*p_enet_addr)[0]));
+
+	qe_issue_cmd(QE_SET_GROUP_ADDRESS, cecr_subblock,
+		     (u8) QE_CR_PROTOCOL_ETHERNET, 0);
+}
+
+#ifdef CONFIG_UGETH_MAGIC_PACKET
+static void magic_packet_detection_enable(ucc_geth_private_t *ugeth)
+{
+	ucc_fast_private_t *uccf;
+	ucc_geth_t *ug_regs;
+	u32 maccfg2, uccm;
+
+	uccf = ugeth->uccf;
+	ug_regs = ugeth->ug_regs;
+
+	/* Enable interrupts for magic packet detection */
+	uccm = in_be32(uccf->p_uccm);
+	uccm |= UCCE_MPD;
+	out_be32(uccf->p_uccm, uccm);
+
+	/* Enable magic packet detection */
+	maccfg2 = in_be32(&ug_regs->maccfg2);
+	maccfg2 |= MACCFG2_MPE;
+	out_be32(&ug_regs->maccfg2, maccfg2);
+}
+
+static void magic_packet_detection_disable(ucc_geth_private_t *ugeth)
+{
+	ucc_fast_private_t *uccf;
+	ucc_geth_t *ug_regs;
+	u32 maccfg2, uccm;
+
+	uccf = ugeth->uccf;
+	ug_regs = ugeth->ug_regs;
+
+	/* Disable interrupts for magic packet detection */
+	uccm = in_be32(uccf->p_uccm);
+	uccm &= ~UCCE_MPD;
+	out_be32(uccf->p_uccm, uccm);
+
+	/* Disable magic packet detection */
+	maccfg2 = in_be32(&ug_regs->maccfg2);
+	maccfg2 &= ~MACCFG2_MPE;
+	out_be32(&ug_regs->maccfg2, maccfg2);
+}
+#endif /* MAGIC_PACKET */
+
+static inline int compare_addr(enet_addr_t *addr1, enet_addr_t *addr2)
+{
+	return memcmp(addr1, addr2, ENET_NUM_OCTETS_PER_ADDRESS);
+}
+
+#ifdef DEBUG
+static void get_statistics(ucc_geth_private_t *ugeth,
+			   ucc_geth_tx_firmware_statistics_t *
+			   tx_firmware_statistics,
+			   ucc_geth_rx_firmware_statistics_t *
+			   rx_firmware_statistics,
+			   ucc_geth_hardware_statistics_t *hardware_statistics)
+{
+	ucc_fast_t *uf_regs;
+	ucc_geth_t *ug_regs;
+	ucc_geth_tx_firmware_statistics_pram_t *p_tx_fw_statistics_pram;
+	ucc_geth_rx_firmware_statistics_pram_t *p_rx_fw_statistics_pram;
+
+	ug_regs = ugeth->ug_regs;
+	uf_regs = (ucc_fast_t *) ug_regs;
+	p_tx_fw_statistics_pram = ugeth->p_tx_fw_statistics_pram;
+	p_rx_fw_statistics_pram = ugeth->p_rx_fw_statistics_pram;
+
+	/* Tx firmware only if user handed pointer and driver actually
+	gathers Tx firmware statistics */
+	if (tx_firmware_statistics && p_tx_fw_statistics_pram) {
+		tx_firmware_statistics->sicoltx =
+		    in_be32(&p_tx_fw_statistics_pram->sicoltx);
+		tx_firmware_statistics->mulcoltx =
+		    in_be32(&p_tx_fw_statistics_pram->mulcoltx);
+		tx_firmware_statistics->latecoltxfr =
+		    in_be32(&p_tx_fw_statistics_pram->latecoltxfr);
+		tx_firmware_statistics->frabortduecol =
+		    in_be32(&p_tx_fw_statistics_pram->frabortduecol);
+		tx_firmware_statistics->frlostinmactxer =
+		    in_be32(&p_tx_fw_statistics_pram->frlostinmactxer);
+		tx_firmware_statistics->carriersenseertx =
+		    in_be32(&p_tx_fw_statistics_pram->carriersenseertx);
+		tx_firmware_statistics->frtxok =
+		    in_be32(&p_tx_fw_statistics_pram->frtxok);
+		tx_firmware_statistics->txfrexcessivedefer =
+		    in_be32(&p_tx_fw_statistics_pram->txfrexcessivedefer);
+		tx_firmware_statistics->txpkts256 =
+		    in_be32(&p_tx_fw_statistics_pram->txpkts256);
+		tx_firmware_statistics->txpkts512 =
+		    in_be32(&p_tx_fw_statistics_pram->txpkts512);
+		tx_firmware_statistics->txpkts1024 =
+		    in_be32(&p_tx_fw_statistics_pram->txpkts1024);
+		tx_firmware_statistics->txpktsjumbo =
+		    in_be32(&p_tx_fw_statistics_pram->txpktsjumbo);
+	}
+
+	/* Rx firmware only if user handed pointer and driver actually
+	 * gathers Rx firmware statistics */
+	if (rx_firmware_statistics && p_rx_fw_statistics_pram) {
+		int i;
+		rx_firmware_statistics->frrxfcser =
+		    in_be32(&p_rx_fw_statistics_pram->frrxfcser);
+		rx_firmware_statistics->fraligner =
+		    in_be32(&p_rx_fw_statistics_pram->fraligner);
+		rx_firmware_statistics->inrangelenrxer =
+		    in_be32(&p_rx_fw_statistics_pram->inrangelenrxer);
+		rx_firmware_statistics->outrangelenrxer =
+		    in_be32(&p_rx_fw_statistics_pram->outrangelenrxer);
+		rx_firmware_statistics->frtoolong =
+		    in_be32(&p_rx_fw_statistics_pram->frtoolong);
+		rx_firmware_statistics->runt =
+		    in_be32(&p_rx_fw_statistics_pram->runt);
+		rx_firmware_statistics->verylongevent =
+		    in_be32(&p_rx_fw_statistics_pram->verylongevent);
+		rx_firmware_statistics->symbolerror =
+		    in_be32(&p_rx_fw_statistics_pram->symbolerror);
+		rx_firmware_statistics->dropbsy =
+		    in_be32(&p_rx_fw_statistics_pram->dropbsy);
+		for (i = 0; i < 0x8; i++)
+			rx_firmware_statistics->res0[i] =
+			    p_rx_fw_statistics_pram->res0[i];
+		rx_firmware_statistics->mismatchdrop =
+		    in_be32(&p_rx_fw_statistics_pram->mismatchdrop);
+		rx_firmware_statistics->underpkts =
+		    in_be32(&p_rx_fw_statistics_pram->underpkts);
+		rx_firmware_statistics->pkts256 =
+		    in_be32(&p_rx_fw_statistics_pram->pkts256);
+		rx_firmware_statistics->pkts512 =
+		    in_be32(&p_rx_fw_statistics_pram->pkts512);
+		rx_firmware_statistics->pkts1024 =
+		    in_be32(&p_rx_fw_statistics_pram->pkts1024);
+		rx_firmware_statistics->pktsjumbo =
+		    in_be32(&p_rx_fw_statistics_pram->pktsjumbo);
+		rx_firmware_statistics->frlossinmacer =
+		    in_be32(&p_rx_fw_statistics_pram->frlossinmacer);
+		rx_firmware_statistics->pausefr =
+		    in_be32(&p_rx_fw_statistics_pram->pausefr);
+		for (i = 0; i < 0x4; i++)
+			rx_firmware_statistics->res1[i] =
+			    p_rx_fw_statistics_pram->res1[i];
+		rx_firmware_statistics->removevlan =
+		    in_be32(&p_rx_fw_statistics_pram->removevlan);
+		rx_firmware_statistics->replacevlan =
+		    in_be32(&p_rx_fw_statistics_pram->replacevlan);
+		rx_firmware_statistics->insertvlan =
+		    in_be32(&p_rx_fw_statistics_pram->insertvlan);
+	}
+
+	/* Hardware only if user handed pointer and driver actually
+	gathers hardware statistics */
+	if (hardware_statistics && (in_be32(&uf_regs->upsmr) & UPSMR_HSE)) {
+		hardware_statistics->tx64 = in_be32(&ug_regs->tx64);
+		hardware_statistics->tx127 = in_be32(&ug_regs->tx127);
+		hardware_statistics->tx255 = in_be32(&ug_regs->tx255);
+		hardware_statistics->rx64 = in_be32(&ug_regs->rx64);
+		hardware_statistics->rx127 = in_be32(&ug_regs->rx127);
+		hardware_statistics->rx255 = in_be32(&ug_regs->rx255);
+		hardware_statistics->txok = in_be32(&ug_regs->txok);
+		hardware_statistics->txcf = in_be16(&ug_regs->txcf);
+		hardware_statistics->tmca = in_be32(&ug_regs->tmca);
+		hardware_statistics->tbca = in_be32(&ug_regs->tbca);
+		hardware_statistics->rxfok = in_be32(&ug_regs->rxfok);
+		hardware_statistics->rxbok = in_be32(&ug_regs->rxbok);
+		hardware_statistics->rbyt = in_be32(&ug_regs->rbyt);
+		hardware_statistics->rmca = in_be32(&ug_regs->rmca);
+		hardware_statistics->rbca = in_be32(&ug_regs->rbca);
+	}
+}
+
+static void dump_bds(ucc_geth_private_t *ugeth)
+{
+	int i;
+	int length;
+
+	for (i = 0; i < ugeth->ug_info->numQueuesTx; i++) {
+		if (ugeth->p_tx_bd_ring[i]) {
+			length =
+			    (ugeth->ug_info->bdRingLenTx[i] *
+			     UCC_GETH_SIZE_OF_BD);
+			ugeth_info("TX BDs[%d]", i);
+			mem_disp(ugeth->p_tx_bd_ring[i], length);
+		}
+	}
+	for (i = 0; i < ugeth->ug_info->numQueuesRx; i++) {
+		if (ugeth->p_rx_bd_ring[i]) {
+			length =
+			    (ugeth->ug_info->bdRingLenRx[i] *
+			     UCC_GETH_SIZE_OF_BD);
+			ugeth_info("RX BDs[%d]", i);
+			mem_disp(ugeth->p_rx_bd_ring[i], length);
+		}
+	}
+}
+
+static void dump_regs(ucc_geth_private_t *ugeth)
+{
+	int i;
+
+	ugeth_info("UCC%d Geth registers:", ugeth->ug_info->uf_info.ucc_num);
+	ugeth_info("Base address: 0x%08x", (u32) ugeth->ug_regs);
+
+	ugeth_info("maccfg1    : addr - 0x%08x, val - 0x%08x",
+		   (u32) & ugeth->ug_regs->maccfg1,
+		   in_be32(&ugeth->ug_regs->maccfg1));
+	ugeth_info("maccfg2    : addr - 0x%08x, val - 0x%08x",
+		   (u32) & ugeth->ug_regs->maccfg2,
+		   in_be32(&ugeth->ug_regs->maccfg2));
+	ugeth_info("ipgifg     : addr - 0x%08x, val - 0x%08x",
+		   (u32) & ugeth->ug_regs->ipgifg,
+		   in_be32(&ugeth->ug_regs->ipgifg));
+	ugeth_info("hafdup     : addr - 0x%08x, val - 0x%08x",
+		   (u32) & ugeth->ug_regs->hafdup,
+		   in_be32(&ugeth->ug_regs->hafdup));
+	ugeth_info("miimcfg    : addr - 0x%08x, val - 0x%08x",
+		   (u32) & ugeth->ug_regs->miimng.miimcfg,
+		   in_be32(&ugeth->ug_regs->miimng.miimcfg));
+	ugeth_info("miimcom    : addr - 0x%08x, val - 0x%08x",
+		   (u32) & ugeth->ug_regs->miimng.miimcom,
+		   in_be32(&ugeth->ug_regs->miimng.miimcom));
+	ugeth_info("miimadd    : addr - 0x%08x, val - 0x%08x",
+		   (u32) & ugeth->ug_regs->miimng.miimadd,
+		   in_be32(&ugeth->ug_regs->miimng.miimadd));
+	ugeth_info("miimcon    : addr - 0x%08x, val - 0x%08x",
+		   (u32) & ugeth->ug_regs->miimng.miimcon,
+		   in_be32(&ugeth->ug_regs->miimng.miimcon));
+	ugeth_info("miimstat   : addr - 0x%08x, val - 0x%08x",
+		   (u32) & ugeth->ug_regs->miimng.miimstat,
+		   in_be32(&ugeth->ug_regs->miimng.miimstat));
+	ugeth_info("miimmind   : addr - 0x%08x, val - 0x%08x",
+		   (u32) & ugeth->ug_regs->miimng.miimind,
+		   in_be32(&ugeth->ug_regs->miimng.miimind));
+	ugeth_info("ifctl      : addr - 0x%08x, val - 0x%08x",
+		   (u32) & ugeth->ug_regs->ifctl,
+		   in_be32(&ugeth->ug_regs->ifctl));
+	ugeth_info("ifstat     : addr - 0x%08x, val - 0x%08x",
+		   (u32) & ugeth->ug_regs->ifstat,
+		   in_be32(&ugeth->ug_regs->ifstat));
+	ugeth_info("macstnaddr1: addr - 0x%08x, val - 0x%08x",
+		   (u32) & ugeth->ug_regs->macstnaddr1,
+		   in_be32(&ugeth->ug_regs->macstnaddr1));
+	ugeth_info("macstnaddr2: addr - 0x%08x, val - 0x%08x",
+		   (u32) & ugeth->ug_regs->macstnaddr2,
+		   in_be32(&ugeth->ug_regs->macstnaddr2));
+	ugeth_info("uempr      : addr - 0x%08x, val - 0x%08x",
+		   (u32) & ugeth->ug_regs->uempr,
+		   in_be32(&ugeth->ug_regs->uempr));
+	ugeth_info("utbipar    : addr - 0x%08x, val - 0x%08x",
+		   (u32) & ugeth->ug_regs->utbipar,
+		   in_be32(&ugeth->ug_regs->utbipar));
+	ugeth_info("uescr      : addr - 0x%08x, val - 0x%04x",
+		   (u32) & ugeth->ug_regs->uescr,
+		   in_be16(&ugeth->ug_regs->uescr));
+	ugeth_info("tx64       : addr - 0x%08x, val - 0x%08x",
+		   (u32) & ugeth->ug_regs->tx64,
+		   in_be32(&ugeth->ug_regs->tx64));
+	ugeth_info("tx127      : addr - 0x%08x, val - 0x%08x",
+		   (u32) & ugeth->ug_regs->tx127,
+		   in_be32(&ugeth->ug_regs->tx127));
+	ugeth_info("tx255      : addr - 0x%08x, val - 0x%08x",
+		   (u32) & ugeth->ug_regs->tx255,
+		   in_be32(&ugeth->ug_regs->tx255));
+	ugeth_info("rx64       : addr - 0x%08x, val - 0x%08x",
+		   (u32) & ugeth->ug_regs->rx64,
+		   in_be32(&ugeth->ug_regs->rx64));
+	ugeth_info("rx127      : addr - 0x%08x, val - 0x%08x",
+		   (u32) & ugeth->ug_regs->rx127,
+		   in_be32(&ugeth->ug_regs->rx127));
+	ugeth_info("rx255      : addr - 0x%08x, val - 0x%08x",
+		   (u32) & ugeth->ug_regs->rx255,
+		   in_be32(&ugeth->ug_regs->rx255));
+	ugeth_info("txok       : addr - 0x%08x, val - 0x%08x",
+		   (u32) & ugeth->ug_regs->txok,
+		   in_be32(&ugeth->ug_regs->txok));
+	ugeth_info("txcf       : addr - 0x%08x, val - 0x%04x",
+		   (u32) & ugeth->ug_regs->txcf,
+		   in_be16(&ugeth->ug_regs->txcf));
+	ugeth_info("tmca       : addr - 0x%08x, val - 0x%08x",
+		   (u32) & ugeth->ug_regs->tmca,
+		   in_be32(&ugeth->ug_regs->tmca));
+	ugeth_info("tbca       : addr - 0x%08x, val - 0x%08x",
+		   (u32) & ugeth->ug_regs->tbca,
+		   in_be32(&ugeth->ug_regs->tbca));
+	ugeth_info("rxfok      : addr - 0x%08x, val - 0x%08x",
+		   (u32) & ugeth->ug_regs->rxfok,
+		   in_be32(&ugeth->ug_regs->rxfok));
+	ugeth_info("rxbok      : addr - 0x%08x, val - 0x%08x",
+		   (u32) & ugeth->ug_regs->rxbok,
+		   in_be32(&ugeth->ug_regs->rxbok));
+	ugeth_info("rbyt       : addr - 0x%08x, val - 0x%08x",
+		   (u32) & ugeth->ug_regs->rbyt,
+		   in_be32(&ugeth->ug_regs->rbyt));
+	ugeth_info("rmca       : addr - 0x%08x, val - 0x%08x",
+		   (u32) & ugeth->ug_regs->rmca,
+		   in_be32(&ugeth->ug_regs->rmca));
+	ugeth_info("rbca       : addr - 0x%08x, val - 0x%08x",
+		   (u32) & ugeth->ug_regs->rbca,
+		   in_be32(&ugeth->ug_regs->rbca));
+	ugeth_info("scar       : addr - 0x%08x, val - 0x%08x",
+		   (u32) & ugeth->ug_regs->scar,
+		   in_be32(&ugeth->ug_regs->scar));
+	ugeth_info("scam       : addr - 0x%08x, val - 0x%08x",
+		   (u32) & ugeth->ug_regs->scam,
+		   in_be32(&ugeth->ug_regs->scam));
+
+	if (ugeth->p_thread_data_tx) {
+		int numThreadsTxNumerical;
+		switch (ugeth->ug_info->numThreadsTx) {
+		case UCC_GETH_NUM_OF_THREADS_1:
+			numThreadsTxNumerical = 1;
+			break;
+		case UCC_GETH_NUM_OF_THREADS_2:
+			numThreadsTxNumerical = 2;
+			break;
+		case UCC_GETH_NUM_OF_THREADS_4:
+			numThreadsTxNumerical = 4;
+			break;
+		case UCC_GETH_NUM_OF_THREADS_6:
+			numThreadsTxNumerical = 6;
+			break;
+		case UCC_GETH_NUM_OF_THREADS_8:
+			numThreadsTxNumerical = 8;
+			break;
+		default:
+			numThreadsTxNumerical = 0;
+			break;
+		}
+
+		ugeth_info("Thread data TXs:");
+		ugeth_info("Base address: 0x%08x",
+			   (u32) ugeth->p_thread_data_tx);
+		for (i = 0; i < numThreadsTxNumerical; i++) {
+			ugeth_info("Thread data TX[%d]:", i);
+			ugeth_info("Base address: 0x%08x",
+				   (u32) & ugeth->p_thread_data_tx[i]);
+			mem_disp((u8 *) & ugeth->p_thread_data_tx[i],
+				 sizeof(ucc_geth_thread_data_tx_t));
+		}
+	}
+	if (ugeth->p_thread_data_rx) {
+		int numThreadsRxNumerical;
+		switch (ugeth->ug_info->numThreadsRx) {
+		case UCC_GETH_NUM_OF_THREADS_1:
+			numThreadsRxNumerical = 1;
+			break;
+		case UCC_GETH_NUM_OF_THREADS_2:
+			numThreadsRxNumerical = 2;
+			break;
+		case UCC_GETH_NUM_OF_THREADS_4:
+			numThreadsRxNumerical = 4;
+			break;
+		case UCC_GETH_NUM_OF_THREADS_6:
+			numThreadsRxNumerical = 6;
+			break;
+		case UCC_GETH_NUM_OF_THREADS_8:
+			numThreadsRxNumerical = 8;
+			break;
+		default:
+			numThreadsRxNumerical = 0;
+			break;
+		}
+
+		ugeth_info("Thread data RX:");
+		ugeth_info("Base address: 0x%08x",
+			   (u32) ugeth->p_thread_data_rx);
+		for (i = 0; i < numThreadsRxNumerical; i++) {
+			ugeth_info("Thread data RX[%d]:", i);
+			ugeth_info("Base address: 0x%08x",
+				   (u32) & ugeth->p_thread_data_rx[i]);
+			mem_disp((u8 *) & ugeth->p_thread_data_rx[i],
+				 sizeof(ucc_geth_thread_data_rx_t));
+		}
+	}
+	if (ugeth->p_exf_glbl_param) {
+		ugeth_info("EXF global param:");
+		ugeth_info("Base address: 0x%08x",
+			   (u32) ugeth->p_exf_glbl_param);
+		mem_disp((u8 *) ugeth->p_exf_glbl_param,
+			 sizeof(*ugeth->p_exf_glbl_param));
+	}
+	if (ugeth->p_tx_glbl_pram) {
+		ugeth_info("TX global param:");
+		ugeth_info("Base address: 0x%08x", (u32) ugeth->p_tx_glbl_pram);
+		ugeth_info("temoder      : addr - 0x%08x, val - 0x%04x",
+			   (u32) & ugeth->p_tx_glbl_pram->temoder,
+			   in_be16(&ugeth->p_tx_glbl_pram->temoder));
+		ugeth_info("sqptr        : addr - 0x%08x, val - 0x%08x",
+			   (u32) & ugeth->p_tx_glbl_pram->sqptr,
+			   in_be32(&ugeth->p_tx_glbl_pram->sqptr));
+		ugeth_info("schedulerbasepointer: addr - 0x%08x, val - 0x%08x",
+			   (u32) & ugeth->p_tx_glbl_pram->schedulerbasepointer,
+			   in_be32(&ugeth->p_tx_glbl_pram->
+				   schedulerbasepointer));
+		ugeth_info("txrmonbaseptr: addr - 0x%08x, val - 0x%08x",
+			   (u32) & ugeth->p_tx_glbl_pram->txrmonbaseptr,
+			   in_be32(&ugeth->p_tx_glbl_pram->txrmonbaseptr));
+		ugeth_info("tstate       : addr - 0x%08x, val - 0x%08x",
+			   (u32) & ugeth->p_tx_glbl_pram->tstate,
+			   in_be32(&ugeth->p_tx_glbl_pram->tstate));
+		ugeth_info("iphoffset[0] : addr - 0x%08x, val - 0x%02x",
+			   (u32) & ugeth->p_tx_glbl_pram->iphoffset[0],
+			   ugeth->p_tx_glbl_pram->iphoffset[0]);
+		ugeth_info("iphoffset[1] : addr - 0x%08x, val - 0x%02x",
+			   (u32) & ugeth->p_tx_glbl_pram->iphoffset[1],
+			   ugeth->p_tx_glbl_pram->iphoffset[1]);
+		ugeth_info("iphoffset[2] : addr - 0x%08x, val - 0x%02x",
+			   (u32) & ugeth->p_tx_glbl_pram->iphoffset[2],
+			   ugeth->p_tx_glbl_pram->iphoffset[2]);
+		ugeth_info("iphoffset[3] : addr - 0x%08x, val - 0x%02x",
+			   (u32) & ugeth->p_tx_glbl_pram->iphoffset[3],
+			   ugeth->p_tx_glbl_pram->iphoffset[3]);
+		ugeth_info("iphoffset[4] : addr - 0x%08x, val - 0x%02x",
+			   (u32) & ugeth->p_tx_glbl_pram->iphoffset[4],
+			   ugeth->p_tx_glbl_pram->iphoffset[4]);
+		ugeth_info("iphoffset[5] : addr - 0x%08x, val - 0x%02x",
+			   (u32) & ugeth->p_tx_glbl_pram->iphoffset[5],
+			   ugeth->p_tx_glbl_pram->iphoffset[5]);
+		ugeth_info("iphoffset[6] : addr - 0x%08x, val - 0x%02x",
+			   (u32) & ugeth->p_tx_glbl_pram->iphoffset[6],
+			   ugeth->p_tx_glbl_pram->iphoffset[6]);
+		ugeth_info("iphoffset[7] : addr - 0x%08x, val - 0x%02x",
+			   (u32) & ugeth->p_tx_glbl_pram->iphoffset[7],
+			   ugeth->p_tx_glbl_pram->iphoffset[7]);
+		ugeth_info("vtagtable[0] : addr - 0x%08x, val - 0x%08x",
+			   (u32) & ugeth->p_tx_glbl_pram->vtagtable[0],
+			   in_be32(&ugeth->p_tx_glbl_pram->vtagtable[0]));
+		ugeth_info("vtagtable[1] : addr - 0x%08x, val - 0x%08x",
+			   (u32) & ugeth->p_tx_glbl_pram->vtagtable[1],
+			   in_be32(&ugeth->p_tx_glbl_pram->vtagtable[1]));
+		ugeth_info("vtagtable[2] : addr - 0x%08x, val - 0x%08x",
+			   (u32) & ugeth->p_tx_glbl_pram->vtagtable[2],
+			   in_be32(&ugeth->p_tx_glbl_pram->vtagtable[2]));
+		ugeth_info("vtagtable[3] : addr - 0x%08x, val - 0x%08x",
+			   (u32) & ugeth->p_tx_glbl_pram->vtagtable[3],
+			   in_be32(&ugeth->p_tx_glbl_pram->vtagtable[3]));
+		ugeth_info("vtagtable[4] : addr - 0x%08x, val - 0x%08x",
+			   (u32) & ugeth->p_tx_glbl_pram->vtagtable[4],
+			   in_be32(&ugeth->p_tx_glbl_pram->vtagtable[4]));
+		ugeth_info("vtagtable[5] : addr - 0x%08x, val - 0x%08x",
+			   (u32) & ugeth->p_tx_glbl_pram->vtagtable[5],
+			   in_be32(&ugeth->p_tx_glbl_pram->vtagtable[5]));
+		ugeth_info("vtagtable[6] : addr - 0x%08x, val - 0x%08x",
+			   (u32) & ugeth->p_tx_glbl_pram->vtagtable[6],
+			   in_be32(&ugeth->p_tx_glbl_pram->vtagtable[6]));
+		ugeth_info("vtagtable[7] : addr - 0x%08x, val - 0x%08x",
+			   (u32) & ugeth->p_tx_glbl_pram->vtagtable[7],
+			   in_be32(&ugeth->p_tx_glbl_pram->vtagtable[7]));
+		ugeth_info("tqptr        : addr - 0x%08x, val - 0x%08x",
+			   (u32) & ugeth->p_tx_glbl_pram->tqptr,
+			   in_be32(&ugeth->p_tx_glbl_pram->tqptr));
+	}
+	if (ugeth->p_rx_glbl_pram) {
+		ugeth_info("RX global param:");
+		ugeth_info("Base address: 0x%08x", (u32) ugeth->p_rx_glbl_pram);
+		ugeth_info("remoder         : addr - 0x%08x, val - 0x%08x",
+			   (u32) & ugeth->p_rx_glbl_pram->remoder,
+			   in_be32(&ugeth->p_rx_glbl_pram->remoder));
+		ugeth_info("rqptr           : addr - 0x%08x, val - 0x%08x",
+			   (u32) & ugeth->p_rx_glbl_pram->rqptr,
+			   in_be32(&ugeth->p_rx_glbl_pram->rqptr));
+		ugeth_info("typeorlen       : addr - 0x%08x, val - 0x%04x",
+			   (u32) & ugeth->p_rx_glbl_pram->typeorlen,
+			   in_be16(&ugeth->p_rx_glbl_pram->typeorlen));
+		ugeth_info("rxgstpack       : addr - 0x%08x, val - 0x%02x",
+			   (u32) & ugeth->p_rx_glbl_pram->rxgstpack,
+			   ugeth->p_rx_glbl_pram->rxgstpack);
+		ugeth_info("rxrmonbaseptr   : addr - 0x%08x, val - 0x%08x",
+			   (u32) & ugeth->p_rx_glbl_pram->rxrmonbaseptr,
+			   in_be32(&ugeth->p_rx_glbl_pram->rxrmonbaseptr));
+		ugeth_info("intcoalescingptr: addr - 0x%08x, val - 0x%08x",
+			   (u32) & ugeth->p_rx_glbl_pram->intcoalescingptr,
+			   in_be32(&ugeth->p_rx_glbl_pram->intcoalescingptr));
+		ugeth_info("rstate          : addr - 0x%08x, val - 0x%02x",
+			   (u32) & ugeth->p_rx_glbl_pram->rstate,
+			   ugeth->p_rx_glbl_pram->rstate);
+		ugeth_info("mrblr           : addr - 0x%08x, val - 0x%04x",
+			   (u32) & ugeth->p_rx_glbl_pram->mrblr,
+			   in_be16(&ugeth->p_rx_glbl_pram->mrblr));
+		ugeth_info("rbdqptr         : addr - 0x%08x, val - 0x%08x",
+			   (u32) & ugeth->p_rx_glbl_pram->rbdqptr,
+			   in_be32(&ugeth->p_rx_glbl_pram->rbdqptr));
+		ugeth_info("mflr            : addr - 0x%08x, val - 0x%04x",
+			   (u32) & ugeth->p_rx_glbl_pram->mflr,
+			   in_be16(&ugeth->p_rx_glbl_pram->mflr));
+		ugeth_info("minflr          : addr - 0x%08x, val - 0x%04x",
+			   (u32) & ugeth->p_rx_glbl_pram->minflr,
+			   in_be16(&ugeth->p_rx_glbl_pram->minflr));
+		ugeth_info("maxd1           : addr - 0x%08x, val - 0x%04x",
+			   (u32) & ugeth->p_rx_glbl_pram->maxd1,
+			   in_be16(&ugeth->p_rx_glbl_pram->maxd1));
+		ugeth_info("maxd2           : addr - 0x%08x, val - 0x%04x",
+			   (u32) & ugeth->p_rx_glbl_pram->maxd2,
+			   in_be16(&ugeth->p_rx_glbl_pram->maxd2));
+		ugeth_info("ecamptr         : addr - 0x%08x, val - 0x%08x",
+			   (u32) & ugeth->p_rx_glbl_pram->ecamptr,
+			   in_be32(&ugeth->p_rx_glbl_pram->ecamptr));
+		ugeth_info("l2qt            : addr - 0x%08x, val - 0x%08x",
+			   (u32) & ugeth->p_rx_glbl_pram->l2qt,
+			   in_be32(&ugeth->p_rx_glbl_pram->l2qt));
+		ugeth_info("l3qt[0]         : addr - 0x%08x, val - 0x%08x",
+			   (u32) & ugeth->p_rx_glbl_pram->l3qt[0],
+			   in_be32(&ugeth->p_rx_glbl_pram->l3qt[0]));
+		ugeth_info("l3qt[1]         : addr - 0x%08x, val - 0x%08x",
+			   (u32) & ugeth->p_rx_glbl_pram->l3qt[1],
+			   in_be32(&ugeth->p_rx_glbl_pram->l3qt[1]));
+		ugeth_info("l3qt[2]         : addr - 0x%08x, val - 0x%08x",
+			   (u32) & ugeth->p_rx_glbl_pram->l3qt[2],
+			   in_be32(&ugeth->p_rx_glbl_pram->l3qt[2]));
+		ugeth_info("l3qt[3]         : addr - 0x%08x, val - 0x%08x",
+			   (u32) & ugeth->p_rx_glbl_pram->l3qt[3],
+			   in_be32(&ugeth->p_rx_glbl_pram->l3qt[3]));
+		ugeth_info("l3qt[4]         : addr - 0x%08x, val - 0x%08x",
+			   (u32) & ugeth->p_rx_glbl_pram->l3qt[4],
+			   in_be32(&ugeth->p_rx_glbl_pram->l3qt[4]));
+		ugeth_info("l3qt[5]         : addr - 0x%08x, val - 0x%08x",
+			   (u32) & ugeth->p_rx_glbl_pram->l3qt[5],
+			   in_be32(&ugeth->p_rx_glbl_pram->l3qt[5]));
+		ugeth_info("l3qt[6]         : addr - 0x%08x, val - 0x%08x",
+			   (u32) & ugeth->p_rx_glbl_pram->l3qt[6],
+			   in_be32(&ugeth->p_rx_glbl_pram->l3qt[6]));
+		ugeth_info("l3qt[7]         : addr - 0x%08x, val - 0x%08x",
+			   (u32) & ugeth->p_rx_glbl_pram->l3qt[7],
+			   in_be32(&ugeth->p_rx_glbl_pram->l3qt[7]));
+		ugeth_info("vlantype        : addr - 0x%08x, val - 0x%04x",
+			   (u32) & ugeth->p_rx_glbl_pram->vlantype,
+			   in_be16(&ugeth->p_rx_glbl_pram->vlantype));
+		ugeth_info("vlantci         : addr - 0x%08x, val - 0x%04x",
+			   (u32) & ugeth->p_rx_glbl_pram->vlantci,
+			   in_be16(&ugeth->p_rx_glbl_pram->vlantci));
+		for (i = 0; i < 64; i++)
+			ugeth_info
+		    ("addressfiltering[%d]: addr - 0x%08x, val - 0x%02x",
+			     i,
+			     (u32) & ugeth->p_rx_glbl_pram->addressfiltering[i],
+			     ugeth->p_rx_glbl_pram->addressfiltering[i]);
+		ugeth_info("exfGlobalParam  : addr - 0x%08x, val - 0x%08x",
+			   (u32) & ugeth->p_rx_glbl_pram->exfGlobalParam,
+			   in_be32(&ugeth->p_rx_glbl_pram->exfGlobalParam));
+	}
+	if (ugeth->p_send_q_mem_reg) {
+		ugeth_info("Send Q memory registers:");
+		ugeth_info("Base address: 0x%08x",
+			   (u32) ugeth->p_send_q_mem_reg);
+		for (i = 0; i < ugeth->ug_info->numQueuesTx; i++) {
+			ugeth_info("SQQD[%d]:", i);
+			ugeth_info("Base address: 0x%08x",
+				   (u32) & ugeth->p_send_q_mem_reg->sqqd[i]);
+			mem_disp((u8 *) & ugeth->p_send_q_mem_reg->sqqd[i],
+				 sizeof(ucc_geth_send_queue_qd_t));
+		}
+	}
+	if (ugeth->p_scheduler) {
+		ugeth_info("Scheduler:");
+		ugeth_info("Base address: 0x%08x", (u32) ugeth->p_scheduler);
+		mem_disp((u8 *) ugeth->p_scheduler,
+			 sizeof(*ugeth->p_scheduler));
+	}
+	if (ugeth->p_tx_fw_statistics_pram) {
+		ugeth_info("TX FW statistics pram:");
+		ugeth_info("Base address: 0x%08x",
+			   (u32) ugeth->p_tx_fw_statistics_pram);
+		mem_disp((u8 *) ugeth->p_tx_fw_statistics_pram,
+			 sizeof(*ugeth->p_tx_fw_statistics_pram));
+	}
+	if (ugeth->p_rx_fw_statistics_pram) {
+		ugeth_info("RX FW statistics pram:");
+		ugeth_info("Base address: 0x%08x",
+			   (u32) ugeth->p_rx_fw_statistics_pram);
+		mem_disp((u8 *) ugeth->p_rx_fw_statistics_pram,
+			 sizeof(*ugeth->p_rx_fw_statistics_pram));
+	}
+	if (ugeth->p_rx_irq_coalescing_tbl) {
+		ugeth_info("RX IRQ coalescing tables:");
+		ugeth_info("Base address: 0x%08x",
+			   (u32) ugeth->p_rx_irq_coalescing_tbl);
+		for (i = 0; i < ugeth->ug_info->numQueuesRx; i++) {
+			ugeth_info("RX IRQ coalescing table entry[%d]:", i);
+			ugeth_info("Base address: 0x%08x",
+				   (u32) & ugeth->p_rx_irq_coalescing_tbl->
+				   coalescingentry[i]);
+			ugeth_info
+		("interruptcoalescingmaxvalue: addr - 0x%08x, val - 0x%08x",
+			     (u32) & ugeth->p_rx_irq_coalescing_tbl->
+			     coalescingentry[i].interruptcoalescingmaxvalue,
+			     in_be32(&ugeth->p_rx_irq_coalescing_tbl->
+				     coalescingentry[i].
+				     interruptcoalescingmaxvalue));
+			ugeth_info
+		("interruptcoalescingcounter : addr - 0x%08x, val - 0x%08x",
+			     (u32) & ugeth->p_rx_irq_coalescing_tbl->
+			     coalescingentry[i].interruptcoalescingcounter,
+			     in_be32(&ugeth->p_rx_irq_coalescing_tbl->
+				     coalescingentry[i].
+				     interruptcoalescingcounter));
+		}
+	}
+	if (ugeth->p_rx_bd_qs_tbl) {
+		ugeth_info("RX BD QS tables:");
+		ugeth_info("Base address: 0x%08x", (u32) ugeth->p_rx_bd_qs_tbl);
+		for (i = 0; i < ugeth->ug_info->numQueuesRx; i++) {
+			ugeth_info("RX BD QS table[%d]:", i);
+			ugeth_info("Base address: 0x%08x",
+				   (u32) & ugeth->p_rx_bd_qs_tbl[i]);
+			ugeth_info
+			    ("bdbaseptr        : addr - 0x%08x, val - 0x%08x",
+			     (u32) & ugeth->p_rx_bd_qs_tbl[i].bdbaseptr,
+			     in_be32(&ugeth->p_rx_bd_qs_tbl[i].bdbaseptr));
+			ugeth_info
+			    ("bdptr            : addr - 0x%08x, val - 0x%08x",
+			     (u32) & ugeth->p_rx_bd_qs_tbl[i].bdptr,
+			     in_be32(&ugeth->p_rx_bd_qs_tbl[i].bdptr));
+			ugeth_info
+			    ("externalbdbaseptr: addr - 0x%08x, val - 0x%08x",
+			     (u32) & ugeth->p_rx_bd_qs_tbl[i].externalbdbaseptr,
+			     in_be32(&ugeth->p_rx_bd_qs_tbl[i].
+				     externalbdbaseptr));
+			ugeth_info
+			    ("externalbdptr    : addr - 0x%08x, val - 0x%08x",
+			     (u32) & ugeth->p_rx_bd_qs_tbl[i].externalbdptr,
+			     in_be32(&ugeth->p_rx_bd_qs_tbl[i].externalbdptr));
+			ugeth_info("ucode RX Prefetched BDs:");
+			ugeth_info("Base address: 0x%08x",
+				   (u32)
+				   qe_muram_addr(in_be32
+						 (&ugeth->p_rx_bd_qs_tbl[i].
+						  bdbaseptr)));
+			mem_disp((u8 *)
+				 qe_muram_addr(in_be32
+					       (&ugeth->p_rx_bd_qs_tbl[i].
+						bdbaseptr)),
+				 sizeof(ucc_geth_rx_prefetched_bds_t));
+		}
+	}
+	if (ugeth->p_init_enet_param_shadow) {
+		int size;
+		ugeth_info("Init enet param shadow:");
+		ugeth_info("Base address: 0x%08x",
+			   (u32) ugeth->p_init_enet_param_shadow);
+		mem_disp((u8 *) ugeth->p_init_enet_param_shadow,
+			 sizeof(*ugeth->p_init_enet_param_shadow));
+
+		size = sizeof(ucc_geth_thread_rx_pram_t);
+		if (ugeth->ug_info->rxExtendedFiltering) {
+			size +=
+			    THREAD_RX_PRAM_ADDITIONAL_FOR_EXTENDED_FILTERING;
+			if (ugeth->ug_info->largestexternallookupkeysize ==
+			    QE_FLTR_TABLE_LOOKUP_KEY_SIZE_8_BYTES)
+				size +=
+			THREAD_RX_PRAM_ADDITIONAL_FOR_EXTENDED_FILTERING_8;
+			if (ugeth->ug_info->largestexternallookupkeysize ==
+			    QE_FLTR_TABLE_LOOKUP_KEY_SIZE_16_BYTES)
+				size +=
+			THREAD_RX_PRAM_ADDITIONAL_FOR_EXTENDED_FILTERING_16;
+		}
+
+		dump_init_enet_entries(ugeth,
+				       &(ugeth->p_init_enet_param_shadow->
+					 txthread[0]),
+				       ENET_INIT_PARAM_MAX_ENTRIES_TX,
+				       sizeof(ucc_geth_thread_tx_pram_t),
+				       ugeth->ug_info->riscTx, 0);
+		dump_init_enet_entries(ugeth,
+				       &(ugeth->p_init_enet_param_shadow->
+					 rxthread[0]),
+				       ENET_INIT_PARAM_MAX_ENTRIES_RX, size,
+				       ugeth->ug_info->riscRx, 1);
+	}
+}
+#endif /* DEBUG */
+
+static void init_default_reg_vals(volatile u32 *upsmr_register,
+				  volatile u32 *maccfg1_register,
+				  volatile u32 *maccfg2_register)
+{
+	out_be32(upsmr_register, UCC_GETH_UPSMR_INIT);
+	out_be32(maccfg1_register, UCC_GETH_MACCFG1_INIT);
+	out_be32(maccfg2_register, UCC_GETH_MACCFG2_INIT);
+}
+
+static int init_half_duplex_params(int alt_beb,
+				   int back_pressure_no_backoff,
+				   int no_backoff,
+				   int excess_defer,
+				   u8 alt_beb_truncation,
+				   u8 max_retransmissions,
+				   u8 collision_window,
+				   volatile u32 *hafdup_register)
+{
+	u32 value = 0;
+
+	if ((alt_beb_truncation > HALFDUP_ALT_BEB_TRUNCATION_MAX) ||
+	    (max_retransmissions > HALFDUP_MAX_RETRANSMISSION_MAX) ||
+	    (collision_window > HALFDUP_COLLISION_WINDOW_MAX))
+		return -EINVAL;
+
+	value = (u32) (alt_beb_truncation << HALFDUP_ALT_BEB_TRUNCATION_SHIFT);
+
+	if (alt_beb)
+		value |= HALFDUP_ALT_BEB;
+	if (back_pressure_no_backoff)
+		value |= HALFDUP_BACK_PRESSURE_NO_BACKOFF;
+	if (no_backoff)
+		value |= HALFDUP_NO_BACKOFF;
+	if (excess_defer)
+		value |= HALFDUP_EXCESSIVE_DEFER;
+
+	value |= (max_retransmissions << HALFDUP_MAX_RETRANSMISSION_SHIFT);
+
+	value |= collision_window;
+
+	out_be32(hafdup_register, value);
+	return 0;
+}
+
+static int init_inter_frame_gap_params(u8 non_btb_cs_ipg,
+				       u8 non_btb_ipg,
+				       u8 min_ifg,
+				       u8 btb_ipg,
+				       volatile u32 *ipgifg_register)
+{
+	u32 value = 0;
+
+	/* Non-Back-to-back IPG part 1 should be <= Non-Back-to-back
+	IPG part 2 */
+	if (non_btb_cs_ipg > non_btb_ipg)
+		return -EINVAL;
+
+	if ((non_btb_cs_ipg > IPGIFG_NON_BACK_TO_BACK_IFG_PART1_MAX) ||
+	    (non_btb_ipg > IPGIFG_NON_BACK_TO_BACK_IFG_PART2_MAX) ||
+	    /*(min_ifg        > IPGIFG_MINIMUM_IFG_ENFORCEMENT_MAX) || */
+	    (btb_ipg > IPGIFG_BACK_TO_BACK_IFG_MAX))
+		return -EINVAL;
+
+	value |=
+	    ((non_btb_cs_ipg << IPGIFG_NON_BACK_TO_BACK_IFG_PART1_SHIFT) &
+	     IPGIFG_NBTB_CS_IPG_MASK);
+	value |=
+	    ((non_btb_ipg << IPGIFG_NON_BACK_TO_BACK_IFG_PART2_SHIFT) &
+	     IPGIFG_NBTB_IPG_MASK);
+	value |=
+	    ((min_ifg << IPGIFG_MINIMUM_IFG_ENFORCEMENT_SHIFT) &
+	     IPGIFG_MIN_IFG_MASK);
+	value |= (btb_ipg & IPGIFG_BTB_IPG_MASK);
+
+	out_be32(ipgifg_register, value);
+	return 0;
+}
+
+static int init_flow_control_params(u32 automatic_flow_control_mode,
+				    int rx_flow_control_enable,
+				    int tx_flow_control_enable,
+				    u16 pause_period,
+				    u16 extension_field,
+				    volatile u32 *upsmr_register,
+				    volatile u32 *uempr_register,
+				    volatile u32 *maccfg1_register)
+{
+	u32 value = 0;
+
+	/* Set UEMPR register */
+	value = (u32) pause_period << UEMPR_PAUSE_TIME_VALUE_SHIFT;
+	value |= (u32) extension_field << UEMPR_EXTENDED_PAUSE_TIME_VALUE_SHIFT;
+	out_be32(uempr_register, value);
+
+	/* Set UPSMR register */
+	value = in_be32(upsmr_register);
+	value |= automatic_flow_control_mode;
+	out_be32(upsmr_register, value);
+
+	value = in_be32(maccfg1_register);
+	if (rx_flow_control_enable)
+		value |= MACCFG1_FLOW_RX;
+	if (tx_flow_control_enable)
+		value |= MACCFG1_FLOW_TX;
+	out_be32(maccfg1_register, value);
+
+	return 0;
+}
+
+static int init_hw_statistics_gathering_mode(int enable_hardware_statistics,
+					     int auto_zero_hardware_statistics,
+					     volatile u32 *upsmr_register,
+					     volatile u16 *uescr_register)
+{
+	u32 upsmr_value = 0;
+	u16 uescr_value = 0;
+	/* Enable hardware statistics gathering if requested */
+	if (enable_hardware_statistics) {
+		upsmr_value = in_be32(upsmr_register);
+		upsmr_value |= UPSMR_HSE;
+		out_be32(upsmr_register, upsmr_value);
+	}
+
+	/* Clear hardware statistics counters */
+	uescr_value = in_be16(uescr_register);
+	uescr_value |= UESCR_CLRCNT;
+	/* Automatically zero hardware statistics counters on read,
+	if requested */
+	if (auto_zero_hardware_statistics)
+		uescr_value |= UESCR_AUTOZ;
+	out_be16(uescr_register, uescr_value);
+
+	return 0;
+}
+
+static int init_firmware_statistics_gathering_mode(int
+		enable_tx_firmware_statistics,
+		int enable_rx_firmware_statistics,
+		volatile u32 *tx_rmon_base_ptr,
+		u32 tx_firmware_statistics_structure_address,
+		volatile u32 *rx_rmon_base_ptr,
+		u32 rx_firmware_statistics_structure_address,
+		volatile u16 *temoder_register,
+		volatile u32 *remoder_register)
+{
+	/* Note: this function does not check if */
+	/* the parameters it receives are NULL   */
+	u16 temoder_value;
+	u32 remoder_value;
+
+	if (enable_tx_firmware_statistics) {
+		out_be32(tx_rmon_base_ptr,
+			 tx_firmware_statistics_structure_address);
+		temoder_value = in_be16(temoder_register);
+		temoder_value |= TEMODER_TX_RMON_STATISTICS_ENABLE;
+		out_be16(temoder_register, temoder_value);
+	}
+
+	if (enable_rx_firmware_statistics) {
+		out_be32(rx_rmon_base_ptr,
+			 rx_firmware_statistics_structure_address);
+		remoder_value = in_be32(remoder_register);
+		remoder_value |= REMODER_RX_RMON_STATISTICS_ENABLE;
+		out_be32(remoder_register, remoder_value);
+	}
+
+	return 0;
+}
+
+static int init_mac_station_addr_regs(u8 address_byte_0,
+				      u8 address_byte_1,
+				      u8 address_byte_2,
+				      u8 address_byte_3,
+				      u8 address_byte_4,
+				      u8 address_byte_5,
+				      volatile u32 *macstnaddr1_register,
+				      volatile u32 *macstnaddr2_register)
+{
+	u32 value = 0;
+
+	/* Example: for a station address of 0x12345678ABCD, */
+	/* 0x12 is byte 0, 0x34 is byte 1 and so on and 0xCD is byte 5 */
+
+	/* MACSTNADDR1 Register: */
+
+	/* 0                      7   8                      15  */
+	/* station address byte 5     station address byte 4     */
+	/* 16                     23  24                     31  */
+	/* station address byte 3     station address byte 2     */
+	value |= (u32) ((address_byte_2 << 0) & 0x000000FF);
+	value |= (u32) ((address_byte_3 << 8) & 0x0000FF00);
+	value |= (u32) ((address_byte_4 << 16) & 0x00FF0000);
+	value |= (u32) ((address_byte_5 << 24) & 0xFF000000);
+
+	out_be32(macstnaddr1_register, value);
+
+	/* MACSTNADDR2 Register: */
+
+	/* 0                      7   8                      15  */
+	/* station address byte 1     station address byte 0     */
+	/* 16                     23  24                     31  */
+	/*         reserved                   reserved           */
+	value = 0;
+	value |= (u32) ((address_byte_0 << 16) & 0x00FF0000);
+	value |= (u32) ((address_byte_1 << 24) & 0xFF000000);
+
+	out_be32(macstnaddr2_register, value);
+
+	return 0;
+}
+
+static int init_mac_duplex_mode(int full_duplex,
+				int limited_to_full_duplex,
+				volatile u32 *maccfg2_register)
+{
+	u32 value = 0;
+
+	/* some interfaces must work in full duplex mode */
+	if ((full_duplex == 0) && (limited_to_full_duplex == 1))
+		return -EINVAL;
+
+	value = in_be32(maccfg2_register);
+
+	if (full_duplex)
+		value |= MACCFG2_FDX;
+	else
+		value &= ~MACCFG2_FDX;
+
+	out_be32(maccfg2_register, value);
+	return 0;
+}
+
+static int init_check_frame_length_mode(int length_check,
+					volatile u32 *maccfg2_register)
+{
+	u32 value = 0;
+
+	value = in_be32(maccfg2_register);
+
+	if (length_check)
+		value |= MACCFG2_LC;
+	else
+		value &= ~MACCFG2_LC;
+
+	out_be32(maccfg2_register, value);
+	return 0;
+}
+
+static int init_preamble_length(u8 preamble_length,
+				volatile u32 *maccfg2_register)
+{
+	u32 value = 0;
+
+	if ((preamble_length < 3) || (preamble_length > 7))
+		return -EINVAL;
+
+	value = in_be32(maccfg2_register);
+	value &= ~MACCFG2_PREL_MASK;
+	value |= (preamble_length << MACCFG2_PREL_SHIFT);
+	out_be32(maccfg2_register, value);
+	return 0;
+}
+
+static int init_mii_management_configuration(int reset_mgmt,
+					     int preamble_supress,
+					     volatile u32 *miimcfg_register,
+					     volatile u32 *miimind_register)
+{
+	unsigned int timeout = PHY_INIT_TIMEOUT;
+	u32 value = 0;
+
+	value = in_be32(miimcfg_register);
+	if (reset_mgmt) {
+		value |= MIIMCFG_RESET_MANAGEMENT;
+		out_be32(miimcfg_register, value);
+	}
+
+	value = 0;
+
+	if (preamble_supress)
+		value |= MIIMCFG_NO_PREAMBLE;
+
+	value |= UCC_GETH_MIIMCFG_MNGMNT_CLC_DIV_INIT;
+	out_be32(miimcfg_register, value);
+
+	/* Wait until the bus is free */
+	while ((in_be32(miimind_register) & MIIMIND_BUSY) && timeout--)
+		cpu_relax();
+
+	if (timeout <= 0) {
+		ugeth_err("%s: The MII Bus is stuck!", __FUNCTION__);
+		return -ETIMEDOUT;
+	}
+
+	return 0;
+}
+
+static int init_rx_parameters(int reject_broadcast,
+			      int receive_short_frames,
+			      int promiscuous, volatile u32 *upsmr_register)
+{
+	u32 value = 0;
+
+	value = in_be32(upsmr_register);
+
+	if (reject_broadcast)
+		value |= UPSMR_BRO;
+	else
+		value &= ~UPSMR_BRO;
+
+	if (receive_short_frames)
+		value |= UPSMR_RSH;
+	else
+		value &= ~UPSMR_RSH;
+
+	if (promiscuous)
+		value |= UPSMR_PRO;
+	else
+		value &= ~UPSMR_PRO;
+
+	out_be32(upsmr_register, value);
+
+	return 0;
+}
+
+static int init_max_rx_buff_len(u16 max_rx_buf_len,
+				volatile u16 *mrblr_register)
+{
+	/* max_rx_buf_len value must be a multiple of 128 */
+	if ((max_rx_buf_len == 0)
+	    || (max_rx_buf_len % UCC_GETH_MRBLR_ALIGNMENT))
+		return -EINVAL;
+
+	out_be16(mrblr_register, max_rx_buf_len);
+	return 0;
+}
+
+static int init_min_frame_len(u16 min_frame_length,
+			      volatile u16 *minflr_register,
+			      volatile u16 *mrblr_register)
+{
+	u16 mrblr_value = 0;
+
+	mrblr_value = in_be16(mrblr_register);
+	if (min_frame_length >= (mrblr_value - 4))
+		return -EINVAL;
+
+	out_be16(minflr_register, min_frame_length);
+	return 0;
+}
+
+static int adjust_enet_interface(ucc_geth_private_t *ugeth)
+{
+	ucc_geth_info_t *ug_info;
+	ucc_geth_t *ug_regs;
+	ucc_fast_t *uf_regs;
+	enet_speed_e speed;
+	int ret_val, rpm = 0, tbi = 0, r10m = 0, rmm =
+	    0, limited_to_full_duplex = 0;
+	u32 upsmr, maccfg2, utbipar, tbiBaseAddress;
+	u16 value;
+
+	ugeth_vdbg("%s: IN", __FUNCTION__);
+
+	ug_info = ugeth->ug_info;
+	ug_regs = ugeth->ug_regs;
+	uf_regs = ugeth->uccf->uf_regs;
+
+	/* Analyze enet_interface according to Interface Mode Configuration
+	table */
+	ret_val =
+	    get_interface_details(ug_info->enet_interface, &speed, &r10m, &rmm,
+				  &rpm, &tbi, &limited_to_full_duplex);
+	if (ret_val != 0) {
+		ugeth_err
+		  ("%s: half duplex not supported in requested configuration.",
+		     __FUNCTION__);
+		return ret_val;
+	}
+
+	/*                    Set MACCFG2                    */
+	maccfg2 = in_be32(&ug_regs->maccfg2);
+	maccfg2 &= ~MACCFG2_INTERFACE_MODE_MASK;
+	if ((speed == ENET_SPEED_10BT) || (speed == ENET_SPEED_100BT))
+		maccfg2 |= MACCFG2_INTERFACE_MODE_NIBBLE;
+	else if (speed == ENET_SPEED_1000BT)
+		maccfg2 |= MACCFG2_INTERFACE_MODE_BYTE;
+	maccfg2 |= ug_info->padAndCrc;
+	out_be32(&ug_regs->maccfg2, maccfg2);
+
+	/*                    Set UPSMR                      */
+	upsmr = in_be32(&uf_regs->upsmr);
+	upsmr &= ~(UPSMR_RPM | UPSMR_R10M | UPSMR_TBIM | UPSMR_RMM);
+	if (rpm)
+		upsmr |= UPSMR_RPM;
+	if (r10m)
+		upsmr |= UPSMR_R10M;
+	if (tbi)
+		upsmr |= UPSMR_TBIM;
+	if (rmm)
+		upsmr |= UPSMR_RMM;
+	out_be32(&uf_regs->upsmr, upsmr);
+
+	/*                    Set UTBIPAR                    */
+	utbipar = in_be32(&ug_regs->utbipar);
+	utbipar &= ~UTBIPAR_PHY_ADDRESS_MASK;
+	if (tbi)
+		utbipar |=
+		    (ug_info->phy_address +
+		     ugeth->ug_info->uf_info.
+		     ucc_num) << UTBIPAR_PHY_ADDRESS_SHIFT;
+	else
+		utbipar |=
+		    (0x10 +
+		     ugeth->ug_info->uf_info.
+		     ucc_num) << UTBIPAR_PHY_ADDRESS_SHIFT;
+	out_be32(&ug_regs->utbipar, utbipar);
+
+	/* Disable autonegotiation in tbi mode, because by default it
+	comes up in autonegotiation mode. */
+	/* Note that this depends on proper setting in utbipar register. */
+	if (tbi) {
+		tbiBaseAddress = in_be32(&ug_regs->utbipar);
+		tbiBaseAddress &= UTBIPAR_PHY_ADDRESS_MASK;
+		tbiBaseAddress >>= UTBIPAR_PHY_ADDRESS_SHIFT;
+		value =
+		    ugeth->mii_info->mdio_read(ugeth->dev, (u8) tbiBaseAddress,
+					       ENET_TBI_MII_CR);
+		value &= ~0x1000;	/* Turn off autonegotiation */
+		ugeth->mii_info->mdio_write(ugeth->dev, (u8) tbiBaseAddress,
+					    ENET_TBI_MII_CR, value);
+	}
+
+	ret_val = init_mac_duplex_mode(1,
+				       limited_to_full_duplex,
+				       &ug_regs->maccfg2);
+	if (ret_val != 0) {
+		ugeth_err
+		("%s: half duplex not supported in requested configuration.",
+		     __FUNCTION__);
+		return ret_val;
+	}
+
+	init_check_frame_length_mode(ug_info->lengthCheckRx, &ug_regs->maccfg2);
+
+	ret_val = init_preamble_length(ug_info->prel, &ug_regs->maccfg2);
+	if (ret_val != 0) {
+		ugeth_err
+		    ("%s: Preamble length must be between 3 and 7 inclusive.",
+		     __FUNCTION__);
+		return ret_val;
+	}
+
+	return 0;
+}
+
+/* Called every time the controller might need to be made
+ * aware of new link state.  The PHY code conveys this
+ * information through variables in the ugeth structure, and this
+ * function converts those variables into the appropriate
+ * register values, and can bring down the device if needed.
+ */
+static void adjust_link(struct net_device *dev)
+{
+	ucc_geth_private_t *ugeth = netdev_priv(dev);
+	ucc_geth_t *ug_regs;
+	u32 tempval;
+	struct ugeth_mii_info *mii_info = ugeth->mii_info;
+
+	ug_regs = ugeth->ug_regs;
+
+	if (mii_info->link) {
+		/* Now we make sure that we can be in full duplex mode.
+		 * If not, we operate in half-duplex mode. */
+		if (mii_info->duplex != ugeth->oldduplex) {
+			if (!(mii_info->duplex)) {
+				tempval = in_be32(&ug_regs->maccfg2);
+				tempval &= ~(MACCFG2_FDX);
+				out_be32(&ug_regs->maccfg2, tempval);
+
+				ugeth_info("%s: Half Duplex", dev->name);
+			} else {
+				tempval = in_be32(&ug_regs->maccfg2);
+				tempval |= MACCFG2_FDX;
+				out_be32(&ug_regs->maccfg2, tempval);
+
+				ugeth_info("%s: Full Duplex", dev->name);
+			}
+
+			ugeth->oldduplex = mii_info->duplex;
+		}
+
+		if (mii_info->speed != ugeth->oldspeed) {
+			switch (mii_info->speed) {
+			case 1000:
+#ifdef CONFIG_MPC836x
+/* FIXME: This code is for 100Mbs BUG fixing,
+remove this when it is fixed!!! */
+				if (ugeth->ug_info->enet_interface ==
+				    ENET_1000_GMII)
+				/* Run the commands which initialize the PHY */
+				{
+					tempval =
+					    (u32) mii_info->mdio_read(ugeth->
+						dev, mii_info->mii_id, 0x1b);
+					tempval |= 0x000f;
+					mii_info->mdio_write(ugeth->dev,
+						mii_info->mii_id, 0x1b,
+						(u16) tempval);
+					tempval =
+					    (u32) mii_info->mdio_read(ugeth->
+						dev, mii_info->mii_id,
+						MII_BMCR);
+					mii_info->mdio_write(ugeth->dev,
+						mii_info->mii_id, MII_BMCR,
+						(u16) (tempval | BMCR_RESET));
+				} else if (ugeth->ug_info->enet_interface ==
+					   ENET_1000_RGMII)
+				/* Run the commands which initialize the PHY */
+				{
+					tempval =
+					    (u32) mii_info->mdio_read(ugeth->
+						dev, mii_info->mii_id, 0x1b);
+					tempval = (tempval & ~0x000f) | 0x000b;
+					mii_info->mdio_write(ugeth->dev,
+						mii_info->mii_id, 0x1b,
+						(u16) tempval);
+					tempval =
+					    (u32) mii_info->mdio_read(ugeth->
+						dev, mii_info->mii_id,
+						MII_BMCR);
+					mii_info->mdio_write(ugeth->dev,
+						mii_info->mii_id, MII_BMCR,
+						(u16) (tempval | BMCR_RESET));
+				}
+				msleep(4000);
+#endif				/* CONFIG_MPC8360 */
+				adjust_enet_interface(ugeth);
+				break;
+			case 100:
+			case 10:
+#ifdef CONFIG_MPC836x
+/* FIXME: This code is for 100Mbs BUG fixing,
+remove this lines when it will be fixed!!! */
+				ugeth->ug_info->enet_interface = ENET_100_RGMII;
+				tempval =
+				    (u32) mii_info->mdio_read(ugeth->dev,
+							      mii_info->mii_id,
+							      0x1b);
+				tempval = (tempval & ~0x000f) | 0x000b;
+				mii_info->mdio_write(ugeth->dev,
+						     mii_info->mii_id, 0x1b,
+						     (u16) tempval);
+				tempval =
+				    (u32) mii_info->mdio_read(ugeth->dev,
+							      mii_info->mii_id,
+							      MII_BMCR);
+				mii_info->mdio_write(ugeth->dev,
+						     mii_info->mii_id, MII_BMCR,
+						     (u16) (tempval |
+							    BMCR_RESET));
+				msleep(4000);
+#endif				/* CONFIG_MPC8360 */
+				adjust_enet_interface(ugeth);
+				break;
+			default:
+				ugeth_warn
+				    ("%s: Ack!  Speed (%d) is not 10/100/1000!",
+				     dev->name, mii_info->speed);
+				break;
+			}
+
+			ugeth_info("%s: Speed %dBT", dev->name,
+				   mii_info->speed);
+
+			ugeth->oldspeed = mii_info->speed;
+		}
+
+		if (!ugeth->oldlink) {
+			ugeth_info("%s: Link is up", dev->name);
+			ugeth->oldlink = 1;
+			netif_carrier_on(dev);
+			netif_schedule(dev);
+		}
+	} else {
+		if (ugeth->oldlink) {
+			ugeth_info("%s: Link is down", dev->name);
+			ugeth->oldlink = 0;
+			ugeth->oldspeed = 0;
+			ugeth->oldduplex = -1;
+			netif_carrier_off(dev);
+		}
+	}
+}
+
+/* Configure the PHY for dev.
+ * returns 0 if success.  -1 if failure
+ */
+static int init_phy(struct net_device *dev)
+{
+	ucc_geth_private_t *ugeth = netdev_priv(dev);
+	struct phy_info *curphy;
+	ucc_mii_mng_t *mii_regs;
+	struct ugeth_mii_info *mii_info;
+	int err;
+
+	mii_regs = &ugeth->ug_regs->miimng;
+
+	ugeth->oldlink = 0;
+	ugeth->oldspeed = 0;
+	ugeth->oldduplex = -1;
+
+	mii_info = kmalloc(sizeof(struct ugeth_mii_info), GFP_KERNEL);
+
+	if (NULL == mii_info) {
+		ugeth_err("%s: Could not allocate mii_info", dev->name);
+		return -ENOMEM;
+	}
+
+	mii_info->mii_regs = mii_regs;
+	mii_info->speed = SPEED_1000;
+	mii_info->duplex = DUPLEX_FULL;
+	mii_info->pause = 0;
+	mii_info->link = 0;
+
+	mii_info->advertising = (ADVERTISED_10baseT_Half |
+				 ADVERTISED_10baseT_Full |
+				 ADVERTISED_100baseT_Half |
+				 ADVERTISED_100baseT_Full |
+				 ADVERTISED_1000baseT_Full);
+	mii_info->autoneg = 1;
+
+	mii_info->mii_id = ugeth->ug_info->phy_address;
+
+	mii_info->dev = dev;
+
+	mii_info->mdio_read = &read_phy_reg;
+	mii_info->mdio_write = &write_phy_reg;
+
+	ugeth->mii_info = mii_info;
+
+	spin_lock_irq(&ugeth->lock);
+
+	/* Set this UCC to be the master of the MII managment */
+	ucc_set_qe_mux_mii_mng(ugeth->ug_info->uf_info.ucc_num);
+
+	if (init_mii_management_configuration(1,
+					      ugeth->ug_info->
+					      miiPreambleSupress,
+					      &mii_regs->miimcfg,
+					      &mii_regs->miimind)) {
+		ugeth_err("%s: The MII Bus is stuck!", dev->name);
+		err = -1;
+		goto bus_fail;
+	}
+
+	spin_unlock_irq(&ugeth->lock);
+
+	/* get info for this PHY */
+	curphy = get_phy_info(ugeth->mii_info);
+
+	if (curphy == NULL) {
+		ugeth_err("%s: No PHY found", dev->name);
+		err = -1;
+		goto no_phy;
+	}
+
+	mii_info->phyinfo = curphy;
+
+	/* Run the commands which initialize the PHY */
+	if (curphy->init) {
+		err = curphy->init(ugeth->mii_info);
+		if (err)
+			goto phy_init_fail;
+	}
+
+	return 0;
+
+      phy_init_fail:
+      no_phy:
+      bus_fail:
+	kfree(mii_info);
+
+	return err;
+}
+
+#ifdef CONFIG_UGETH_TX_ON_DEMOND
+static int ugeth_transmit_on_demand(ucc_geth_private_t *ugeth)
+{
+	ucc_fast_transmit_on_demand(ugeth->uccf);
+
+	return 0;
+}
+#endif
+
+static int ugeth_graceful_stop_tx(ucc_geth_private_t *ugeth)
+{
+	ucc_fast_private_t *uccf;
+	u32 cecr_subblock;
+	u32 temp;
+
+	uccf = ugeth->uccf;
+
+	/* Mask GRACEFUL STOP TX interrupt bit and clear it */
+	temp = in_be32(uccf->p_uccm);
+	temp &= ~UCCE_GRA;
+	out_be32(uccf->p_uccm, temp);
+	out_be32(uccf->p_ucce, UCCE_GRA);	/* clear by writing 1 */
+
+	/* Issue host command */
+	cecr_subblock =
+	    ucc_fast_get_qe_cr_subblock(ugeth->ug_info->uf_info.ucc_num);
+	qe_issue_cmd(QE_GRACEFUL_STOP_TX, cecr_subblock,
+		     (u8) QE_CR_PROTOCOL_ETHERNET, 0);
+
+	/* Wait for command to complete */
+	do {
+		temp = in_be32(uccf->p_ucce);
+	} while (!(temp & UCCE_GRA));
+
+	uccf->stopped_tx = 1;
+
+	return 0;
+}
+
+static int ugeth_graceful_stop_rx(ucc_geth_private_t * ugeth)
+{
+	ucc_fast_private_t *uccf;
+	u32 cecr_subblock;
+	u8 temp;
+
+	uccf = ugeth->uccf;
+
+	/* Clear acknowledge bit */
+	temp = ugeth->p_rx_glbl_pram->rxgstpack;
+	temp &= ~GRACEFUL_STOP_ACKNOWLEDGE_RX;
+	ugeth->p_rx_glbl_pram->rxgstpack = temp;
+
+	/* Keep issuing command and checking acknowledge bit until
+	it is asserted, according to spec */
+	do {
+		/* Issue host command */
+		cecr_subblock =
+		    ucc_fast_get_qe_cr_subblock(ugeth->ug_info->uf_info.
+						ucc_num);
+		qe_issue_cmd(QE_GRACEFUL_STOP_RX, cecr_subblock,
+			     (u8) QE_CR_PROTOCOL_ETHERNET, 0);
+
+		temp = ugeth->p_rx_glbl_pram->rxgstpack;
+	} while (!(temp & GRACEFUL_STOP_ACKNOWLEDGE_RX));
+
+	uccf->stopped_rx = 1;
+
+	return 0;
+}
+
+static int ugeth_restart_tx(ucc_geth_private_t *ugeth)
+{
+	ucc_fast_private_t *uccf;
+	u32 cecr_subblock;
+
+	uccf = ugeth->uccf;
+
+	cecr_subblock =
+	    ucc_fast_get_qe_cr_subblock(ugeth->ug_info->uf_info.ucc_num);
+	qe_issue_cmd(QE_RESTART_TX, cecr_subblock, (u8) QE_CR_PROTOCOL_ETHERNET,
+		     0);
+	uccf->stopped_tx = 0;
+
+	return 0;
+}
+
+static int ugeth_restart_rx(ucc_geth_private_t *ugeth)
+{
+	ucc_fast_private_t *uccf;
+	u32 cecr_subblock;
+
+	uccf = ugeth->uccf;
+
+	cecr_subblock =
+	    ucc_fast_get_qe_cr_subblock(ugeth->ug_info->uf_info.ucc_num);
+	qe_issue_cmd(QE_RESTART_RX, cecr_subblock, (u8) QE_CR_PROTOCOL_ETHERNET,
+		     0);
+	uccf->stopped_rx = 0;
+
+	return 0;
+}
+
+static int ugeth_enable(ucc_geth_private_t *ugeth, comm_dir_e mode)
+{
+	ucc_fast_private_t *uccf;
+	int enabled_tx, enabled_rx;
+
+	uccf = ugeth->uccf;
+
+	/* check if the UCC number is in range. */
+	if (ugeth->ug_info->uf_info.ucc_num >= UCC_MAX_NUM) {
+		ugeth_err("%s: ucc_num out of range.", __FUNCTION__);
+		return -EINVAL;
+	}
+
+	enabled_tx = uccf->enabled_tx;
+	enabled_rx = uccf->enabled_rx;
+
+	/* Get Tx and Rx going again, in case this channel was actively
+	disabled. */
+	if ((mode & COMM_DIR_TX) && (!enabled_tx) && uccf->stopped_tx)
+		ugeth_restart_tx(ugeth);
+	if ((mode & COMM_DIR_RX) && (!enabled_rx) && uccf->stopped_rx)
+		ugeth_restart_rx(ugeth);
+
+	ucc_fast_enable(uccf, mode);	/* OK to do even if not disabled */
+
+	return 0;
+
+}
+
+static int ugeth_disable(ucc_geth_private_t * ugeth, comm_dir_e mode)
+{
+	ucc_fast_private_t *uccf;
+
+	uccf = ugeth->uccf;
+
+	/* check if the UCC number is in range. */
+	if (ugeth->ug_info->uf_info.ucc_num >= UCC_MAX_NUM) {
+		ugeth_err("%s: ucc_num out of range.", __FUNCTION__);
+		return -EINVAL;
+	}
+
+	/* Stop any transmissions */
+	if ((mode & COMM_DIR_TX) && uccf->enabled_tx && !uccf->stopped_tx)
+		ugeth_graceful_stop_tx(ugeth);
+
+	/* Stop any receptions */
+	if ((mode & COMM_DIR_RX) && uccf->enabled_rx && !uccf->stopped_rx)
+		ugeth_graceful_stop_rx(ugeth);
+
+	ucc_fast_disable(ugeth->uccf, mode); /* OK to do even if not enabled */
+
+	return 0;
+}
+
+static void ugeth_dump_regs(ucc_geth_private_t *ugeth)
+{
+#ifdef DEBUG
+	ucc_fast_dump_regs(ugeth->uccf);
+	dump_regs(ugeth);
+	dump_bds(ugeth);
+#endif
+}
+
+#ifdef CONFIG_UGETH_FILTERING
+static int ugeth_ext_filtering_serialize_tad(ucc_geth_tad_params_t *
+					     p_UccGethTadParams,
+					     qe_fltr_tad_t *qe_fltr_tad)
+{
+	u16 temp;
+
+	/* Zero serialized TAD */
+	memset(qe_fltr_tad, 0, QE_FLTR_TAD_SIZE);
+
+	qe_fltr_tad->serialized[0] |= UCC_GETH_TAD_V;	/* Must have this */
+	if (p_UccGethTadParams->rx_non_dynamic_extended_features_mode ||
+	    (p_UccGethTadParams->vtag_op != UCC_GETH_VLAN_OPERATION_TAGGED_NOP)
+	    || (p_UccGethTadParams->vnontag_op !=
+		UCC_GETH_VLAN_OPERATION_NON_TAGGED_NOP)
+	    )
+		qe_fltr_tad->serialized[0] |= UCC_GETH_TAD_EF;
+	if (p_UccGethTadParams->reject_frame)
+		qe_fltr_tad->serialized[0] |= UCC_GETH_TAD_REJ;
+	temp =
+	    (u16) (((u16) p_UccGethTadParams->
+		    vtag_op) << UCC_GETH_TAD_VTAG_OP_SHIFT);
+	qe_fltr_tad->serialized[0] |= (u8) (temp >> 8);	/* upper bits */
+
+	qe_fltr_tad->serialized[1] |= (u8) (temp & 0x00ff);	/* lower bits */
+	if (p_UccGethTadParams->vnontag_op ==
+	    UCC_GETH_VLAN_OPERATION_NON_TAGGED_Q_TAG_INSERT)
+		qe_fltr_tad->serialized[1] |= UCC_GETH_TAD_V_NON_VTAG_OP;
+	qe_fltr_tad->serialized[1] |=
+	    p_UccGethTadParams->rqos << UCC_GETH_TAD_RQOS_SHIFT;
+
+	qe_fltr_tad->serialized[2] |=
+	    p_UccGethTadParams->vpri << UCC_GETH_TAD_V_PRIORITY_SHIFT;
+	/* upper bits */
+	qe_fltr_tad->serialized[2] |= (u8) (p_UccGethTadParams->vid >> 8);
+	/* lower bits */
+	qe_fltr_tad->serialized[3] |= (u8) (p_UccGethTadParams->vid & 0x00ff);
+
+	return 0;
+}
+
+static enet_addr_container_t
+    *ugeth_82xx_filtering_get_match_addr_in_hash(ucc_geth_private_t *ugeth,
+						 enet_addr_t *p_enet_addr)
+{
+	enet_addr_container_t *enet_addr_cont;
+	struct list_head *p_lh;
+	u16 i, num;
+	int32_t j;
+	u8 *p_counter;
+
+	if ((*p_enet_addr)[0] & ENET_GROUP_ADDR) {
+		p_lh = &ugeth->group_hash_q;
+		p_counter = &(ugeth->numGroupAddrInHash);
+	} else {
+		p_lh = &ugeth->ind_hash_q;
+		p_counter = &(ugeth->numIndAddrInHash);
+	}
+
+	if (!p_lh)
+		return NULL;
+
+	num = *p_counter;
+
+	for (i = 0; i < num; i++) {
+		enet_addr_cont =
+		    (enet_addr_container_t *)
+		    ENET_ADDR_CONT_ENTRY(dequeue(p_lh));
+		for (j = ENET_NUM_OCTETS_PER_ADDRESS - 1; j >= 0; j--) {
+			if ((*p_enet_addr)[j] != (enet_addr_cont->address)[j])
+				break;
+			if (j == 0)
+				return enet_addr_cont;	/* Found */
+		}
+		enqueue(p_lh, &enet_addr_cont->node);	/* Put it back */
+	}
+	return NULL;
+}
+
+static int ugeth_82xx_filtering_add_addr_in_hash(ucc_geth_private_t *ugeth,
+						 enet_addr_t *p_enet_addr)
+{
+	ucc_geth_enet_address_recognition_location_e location;
+	enet_addr_container_t *enet_addr_cont;
+	struct list_head *p_lh;
+	u8 i;
+	u32 limit;
+	u8 *p_counter;
+
+	if ((*p_enet_addr)[0] & ENET_GROUP_ADDR) {
+		p_lh = &ugeth->group_hash_q;
+		limit = ugeth->ug_info->maxGroupAddrInHash;
+		location =
+		    UCC_GETH_ENET_ADDRESS_RECOGNITION_LOCATION_GROUP_HASH;
+		p_counter = &(ugeth->numGroupAddrInHash);
+	} else {
+		p_lh = &ugeth->ind_hash_q;
+		limit = ugeth->ug_info->maxIndAddrInHash;
+		location =
+		    UCC_GETH_ENET_ADDRESS_RECOGNITION_LOCATION_INDIVIDUAL_HASH;
+		p_counter = &(ugeth->numIndAddrInHash);
+	}
+
+	if ((enet_addr_cont =
+	     ugeth_82xx_filtering_get_match_addr_in_hash(ugeth, p_enet_addr))) {
+		list_add(p_lh, &enet_addr_cont->node);	/* Put it back */
+		return 0;
+	}
+	if ((!p_lh) || (!(*p_counter < limit)))
+		return -EBUSY;
+	if (!(enet_addr_cont = get_enet_addr_container()))
+		return -ENOMEM;
+	for (i = 0; i < ENET_NUM_OCTETS_PER_ADDRESS; i++)
+		(enet_addr_cont->address)[i] = (*p_enet_addr)[i];
+	enet_addr_cont->location = location;
+	enqueue(p_lh, &enet_addr_cont->node);	/* Put it back */
+	++(*p_counter);
+
+	hw_add_addr_in_hash(ugeth, &(enet_addr_cont->address));
+
+	return 0;
+}
+
+static int ugeth_82xx_filtering_clear_addr_in_hash(ucc_geth_private_t *ugeth,
+						   enet_addr_t *p_enet_addr)
+{
+	ucc_geth_82xx_address_filtering_pram_t *p_82xx_addr_filt;
+	enet_addr_container_t *enet_addr_cont;
+	ucc_fast_private_t *uccf;
+	comm_dir_e comm_dir;
+	u16 i, num;
+	struct list_head *p_lh;
+	u32 *addr_h, *addr_l;
+	u8 *p_counter;
+
+	uccf = ugeth->uccf;
+
+	p_82xx_addr_filt =
+	    (ucc_geth_82xx_address_filtering_pram_t *) ugeth->p_rx_glbl_pram->
+	    addressfiltering;
+
+	if (!
+	    (enet_addr_cont =
+	     ugeth_82xx_filtering_get_match_addr_in_hash(ugeth, p_enet_addr)))
+		return -ENOENT;
+
+	/* It's been found and removed from the CQ. */
+	/* Now destroy its container */
+	put_enet_addr_container(enet_addr_cont);
+
+	if ((*p_enet_addr)[0] & ENET_GROUP_ADDR) {
+		addr_h = &(p_82xx_addr_filt->gaddr_h);
+		addr_l = &(p_82xx_addr_filt->gaddr_l);
+		p_lh = &ugeth->group_hash_q;
+		p_counter = &(ugeth->numGroupAddrInHash);
+	} else {
+		addr_h = &(p_82xx_addr_filt->iaddr_h);
+		addr_l = &(p_82xx_addr_filt->iaddr_l);
+		p_lh = &ugeth->ind_hash_q;
+		p_counter = &(ugeth->numIndAddrInHash);
+	}
+
+	comm_dir = 0;
+	if (uccf->enabled_tx)
+		comm_dir |= COMM_DIR_TX;
+	if (uccf->enabled_rx)
+		comm_dir |= COMM_DIR_RX;
+	if (comm_dir)
+		ugeth_disable(ugeth, comm_dir);
+
+	/* Clear the hash table. */
+	out_be32(addr_h, 0x00000000);
+	out_be32(addr_l, 0x00000000);
+
+	/* Add all remaining CQ elements back into hash */
+	num = --(*p_counter);
+	for (i = 0; i < num; i++) {
+		enet_addr_cont =
+		    (enet_addr_container_t *)
+		    ENET_ADDR_CONT_ENTRY(dequeue(p_lh));
+		hw_add_addr_in_hash(ugeth, &(enet_addr_cont->address));
+		enqueue(p_lh, &enet_addr_cont->node);	/* Put it back */
+	}
+
+	if (comm_dir)
+		ugeth_enable(ugeth, comm_dir);
+
+	return 0;
+}
+#endif /* CONFIG_UGETH_FILTERING */
+
+static int ugeth_82xx_filtering_clear_all_addr_in_hash(ucc_geth_private_t *
+						       ugeth,
+						       enet_addr_type_e
+						       enet_addr_type)
+{
+	ucc_geth_82xx_address_filtering_pram_t *p_82xx_addr_filt;
+	ucc_fast_private_t *uccf;
+	comm_dir_e comm_dir;
+	struct list_head *p_lh;
+	u16 i, num;
+	u32 *addr_h, *addr_l;
+	u8 *p_counter;
+
+	uccf = ugeth->uccf;
+
+	p_82xx_addr_filt =
+	    (ucc_geth_82xx_address_filtering_pram_t *) ugeth->p_rx_glbl_pram->
+	    addressfiltering;
+
+	if (enet_addr_type == ENET_ADDR_TYPE_GROUP) {
+		addr_h = &(p_82xx_addr_filt->gaddr_h);
+		addr_l = &(p_82xx_addr_filt->gaddr_l);
+		p_lh = &ugeth->group_hash_q;
+		p_counter = &(ugeth->numGroupAddrInHash);
+	} else if (enet_addr_type == ENET_ADDR_TYPE_INDIVIDUAL) {
+		addr_h = &(p_82xx_addr_filt->iaddr_h);
+		addr_l = &(p_82xx_addr_filt->iaddr_l);
+		p_lh = &ugeth->ind_hash_q;
+		p_counter = &(ugeth->numIndAddrInHash);
+	} else
+		return -EINVAL;
+
+	comm_dir = 0;
+	if (uccf->enabled_tx)
+		comm_dir |= COMM_DIR_TX;
+	if (uccf->enabled_rx)
+		comm_dir |= COMM_DIR_RX;
+	if (comm_dir)
+		ugeth_disable(ugeth, comm_dir);
+
+	/* Clear the hash table. */
+	out_be32(addr_h, 0x00000000);
+	out_be32(addr_l, 0x00000000);
+
+	if (!p_lh)
+		return 0;
+
+	num = *p_counter;
+
+	/* Delete all remaining CQ elements */
+	for (i = 0; i < num; i++)
+		put_enet_addr_container(ENET_ADDR_CONT_ENTRY(dequeue(p_lh)));
+
+	*p_counter = 0;
+
+	if (comm_dir)
+		ugeth_enable(ugeth, comm_dir);
+
+	return 0;
+}
+
+#ifdef CONFIG_UGETH_FILTERING
+static int ugeth_82xx_filtering_add_addr_in_paddr(ucc_geth_private_t *ugeth,
+						  enet_addr_t *p_enet_addr,
+						  u8 paddr_num)
+{
+	int i;
+
+	if ((*p_enet_addr)[0] & ENET_GROUP_ADDR)
+		ugeth_warn
+		    ("%s: multicast address added to paddr will have no "
+		     "effect - is this what you wanted?",
+		     __FUNCTION__);
+
+	ugeth->indAddrRegUsed[paddr_num] = 1;	/* mark this paddr as used */
+	/* store address in our database */
+	for (i = 0; i < ENET_NUM_OCTETS_PER_ADDRESS; i++)
+		ugeth->paddr[paddr_num][i] = (*p_enet_addr)[i];
+	/* put in hardware */
+	return hw_add_addr_in_paddr(ugeth, p_enet_addr, paddr_num);
+}
+#endif /* CONFIG_UGETH_FILTERING */
+
+static int ugeth_82xx_filtering_clear_addr_in_paddr(ucc_geth_private_t *ugeth,
+						    u8 paddr_num)
+{
+	ugeth->indAddrRegUsed[paddr_num] = 0; /* mark this paddr as not used */
+	return hw_clear_addr_in_paddr(ugeth, paddr_num);/* clear in hardware */
+}
+
+static void ucc_geth_memclean(ucc_geth_private_t *ugeth)
+{
+	u16 i, j;
+	u8 *bd;
+
+	if (!ugeth)
+		return;
+
+	if (ugeth->uccf)
+		ucc_fast_free(ugeth->uccf);
+
+	if (ugeth->p_thread_data_tx) {
+		qe_muram_free(ugeth->thread_dat_tx_offset);
+		ugeth->p_thread_data_tx = NULL;
+	}
+	if (ugeth->p_thread_data_rx) {
+		qe_muram_free(ugeth->thread_dat_rx_offset);
+		ugeth->p_thread_data_rx = NULL;
+	}
+	if (ugeth->p_exf_glbl_param) {
+		qe_muram_free(ugeth->exf_glbl_param_offset);
+		ugeth->p_exf_glbl_param = NULL;
+	}
+	if (ugeth->p_rx_glbl_pram) {
+		qe_muram_free(ugeth->rx_glbl_pram_offset);
+		ugeth->p_rx_glbl_pram = NULL;
+	}
+	if (ugeth->p_tx_glbl_pram) {
+		qe_muram_free(ugeth->tx_glbl_pram_offset);
+		ugeth->p_tx_glbl_pram = NULL;
+	}
+	if (ugeth->p_send_q_mem_reg) {
+		qe_muram_free(ugeth->send_q_mem_reg_offset);
+		ugeth->p_send_q_mem_reg = NULL;
+	}
+	if (ugeth->p_scheduler) {
+		qe_muram_free(ugeth->scheduler_offset);
+		ugeth->p_scheduler = NULL;
+	}
+	if (ugeth->p_tx_fw_statistics_pram) {
+		qe_muram_free(ugeth->tx_fw_statistics_pram_offset);
+		ugeth->p_tx_fw_statistics_pram = NULL;
+	}
+	if (ugeth->p_rx_fw_statistics_pram) {
+		qe_muram_free(ugeth->rx_fw_statistics_pram_offset);
+		ugeth->p_rx_fw_statistics_pram = NULL;
+	}
+	if (ugeth->p_rx_irq_coalescing_tbl) {
+		qe_muram_free(ugeth->rx_irq_coalescing_tbl_offset);
+		ugeth->p_rx_irq_coalescing_tbl = NULL;
+	}
+	if (ugeth->p_rx_bd_qs_tbl) {
+		qe_muram_free(ugeth->rx_bd_qs_tbl_offset);
+		ugeth->p_rx_bd_qs_tbl = NULL;
+	}
+	if (ugeth->p_init_enet_param_shadow) {
+		return_init_enet_entries(ugeth,
+					 &(ugeth->p_init_enet_param_shadow->
+					   rxthread[0]),
+					 ENET_INIT_PARAM_MAX_ENTRIES_RX,
+					 ugeth->ug_info->riscRx, 1);
+		return_init_enet_entries(ugeth,
+					 &(ugeth->p_init_enet_param_shadow->
+					   txthread[0]),
+					 ENET_INIT_PARAM_MAX_ENTRIES_TX,
+					 ugeth->ug_info->riscTx, 0);
+		kfree(ugeth->p_init_enet_param_shadow);
+		ugeth->p_init_enet_param_shadow = NULL;
+	}
+	for (i = 0; i < ugeth->ug_info->numQueuesTx; i++) {
+		bd = ugeth->p_tx_bd_ring[i];
+		for (j = 0; j < ugeth->ug_info->bdRingLenTx[i]; j++) {
+			if (ugeth->tx_skbuff[i][j]) {
+				dma_unmap_single(NULL,
+						 BD_BUFFER_ARG(bd),
+						 (BD_STATUS_AND_LENGTH(bd) &
+						  BD_LENGTH_MASK),
+						 DMA_TO_DEVICE);
+				dev_kfree_skb_any(ugeth->tx_skbuff[i][j]);
+				ugeth->tx_skbuff[i][j] = NULL;
+			}
+		}
+
+		kfree(ugeth->tx_skbuff[i]);
+
+		if (ugeth->p_tx_bd_ring[i]) {
+			if (ugeth->ug_info->uf_info.bd_mem_part ==
+			    MEM_PART_SYSTEM)
+				kfree((void *)ugeth->tx_bd_ring_offset[i]);
+			else if (ugeth->ug_info->uf_info.bd_mem_part ==
+				 MEM_PART_MURAM)
+				qe_muram_free(ugeth->tx_bd_ring_offset[i]);
+			ugeth->p_tx_bd_ring[i] = NULL;
+		}
+	}
+	for (i = 0; i < ugeth->ug_info->numQueuesRx; i++) {
+		if (ugeth->p_rx_bd_ring[i]) {
+			/* Return existing data buffers in ring */
+			bd = ugeth->p_rx_bd_ring[i];
+			for (j = 0; j < ugeth->ug_info->bdRingLenRx[i]; j++) {
+				if (ugeth->rx_skbuff[i][j]) {
+					dma_unmap_single(NULL, BD_BUFFER(bd),
+						 ugeth->ug_info->
+						 uf_info.
+						 max_rx_buf_length +
+						 UCC_GETH_RX_DATA_BUF_ALIGNMENT,
+						 DMA_FROM_DEVICE);
+
+					dev_kfree_skb_any(ugeth->
+							  rx_skbuff[i][j]);
+					ugeth->rx_skbuff[i][j] = NULL;
+				}
+				bd += UCC_GETH_SIZE_OF_BD;
+			}
+
+			kfree(ugeth->rx_skbuff[i]);
+
+			if (ugeth->ug_info->uf_info.bd_mem_part ==
+			    MEM_PART_SYSTEM)
+				kfree((void *)ugeth->rx_bd_ring_offset[i]);
+			else if (ugeth->ug_info->uf_info.bd_mem_part ==
+				 MEM_PART_MURAM)
+				qe_muram_free(ugeth->rx_bd_ring_offset[i]);
+			ugeth->p_rx_bd_ring[i] = NULL;
+		}
+	}
+	while (!list_empty(&ugeth->group_hash_q))
+		put_enet_addr_container(ENET_ADDR_CONT_ENTRY
+					(dequeue(&ugeth->group_hash_q)));
+	while (!list_empty(&ugeth->ind_hash_q))
+		put_enet_addr_container(ENET_ADDR_CONT_ENTRY
+					(dequeue(&ugeth->ind_hash_q)));
+
+}
+
+static void ucc_geth_set_multi(struct net_device *dev)
+{
+	ucc_geth_private_t *ugeth;
+	struct dev_mc_list *dmi;
+	ucc_fast_t *uf_regs;
+	ucc_geth_82xx_address_filtering_pram_t *p_82xx_addr_filt;
+	enet_addr_t tempaddr;
+	u8 *mcptr, *tdptr;
+	int i, j;
+
+	ugeth = netdev_priv(dev);
+
+	uf_regs = ugeth->uccf->uf_regs;
+
+	if (dev->flags & IFF_PROMISC) {
+
+		/* Log any net taps. */
+		printk("%s: Promiscuous mode enabled.\n", dev->name);
+		uf_regs->upsmr |= UPSMR_PRO;
+
+	} else {
+
+		uf_regs->upsmr &= ~UPSMR_PRO;
+
+		p_82xx_addr_filt =
+		    (ucc_geth_82xx_address_filtering_pram_t *) ugeth->
+		    p_rx_glbl_pram->addressfiltering;
+
+		if (dev->flags & IFF_ALLMULTI) {
+			/* Catch all multicast addresses, so set the
+			 * filter to all 1's.
+			 */
+			out_be32(&p_82xx_addr_filt->gaddr_h, 0xffffffff);
+			out_be32(&p_82xx_addr_filt->gaddr_l, 0xffffffff);
+		} else {
+			/* Clear filter and add the addresses in the list.
+			 */
+			out_be32(&p_82xx_addr_filt->gaddr_h, 0x0);
+			out_be32(&p_82xx_addr_filt->gaddr_l, 0x0);
+
+			dmi = dev->mc_list;
+
+			for (i = 0; i < dev->mc_count; i++, dmi = dmi->next) {
+
+				/* Only support group multicast for now.
+				 */
+				if (!(dmi->dmi_addr[0] & 1))
+					continue;
+
+				/* The address in dmi_addr is LSB first,
+				 * and taddr is MSB first.  We have to
+				 * copy bytes MSB first from dmi_addr.
+				 */
+				mcptr = (u8 *) dmi->dmi_addr + 5;
+				tdptr = (u8 *) & tempaddr;
+				for (j = 0; j < 6; j++)
+					*tdptr++ = *mcptr--;
+
+				/* Ask CPM to run CRC and set bit in
+				 * filter mask.
+				 */
+				hw_add_addr_in_hash(ugeth, &tempaddr);
+
+			}
+		}
+	}
+}
+
+static void ucc_geth_stop(ucc_geth_private_t *ugeth)
+{
+	ucc_geth_t *ug_regs = ugeth->ug_regs;
+	u32 tempval;
+
+	ugeth_vdbg("%s: IN", __FUNCTION__);
+
+	/* Disable the controller */
+	ugeth_disable(ugeth, COMM_DIR_RX_AND_TX);
+
+	/* Tell the kernel the link is down */
+	ugeth->mii_info->link = 0;
+	adjust_link(ugeth->dev);
+
+	/* Mask all interrupts */
+	out_be32(ugeth->uccf->p_ucce, 0x00000000);
+
+	/* Clear all interrupts */
+	out_be32(ugeth->uccf->p_ucce, 0xffffffff);
+
+	/* Disable Rx and Tx */
+	tempval = in_be32(&ug_regs->maccfg1);
+	tempval &= ~(MACCFG1_ENABLE_RX | MACCFG1_ENABLE_TX);
+	out_be32(&ug_regs->maccfg1, tempval);
+
+	if (ugeth->ug_info->board_flags & FSL_UGETH_BRD_HAS_PHY_INTR) {
+		/* Clear any pending interrupts */
+		mii_clear_phy_interrupt(ugeth->mii_info);
+
+		/* Disable PHY Interrupts */
+		mii_configure_phy_interrupt(ugeth->mii_info,
+					    MII_INTERRUPT_DISABLED);
+	}
+
+	free_irq(ugeth->ug_info->uf_info.irq, ugeth->dev);
+
+	if (ugeth->ug_info->board_flags & FSL_UGETH_BRD_HAS_PHY_INTR) {
+		free_irq(ugeth->ug_info->phy_interrupt, ugeth->dev);
+	} else {
+		del_timer_sync(&ugeth->phy_info_timer);
+	}
+
+	ucc_geth_memclean(ugeth);
+}
+
+static int ucc_geth_startup(ucc_geth_private_t *ugeth)
+{
+	ucc_geth_82xx_address_filtering_pram_t *p_82xx_addr_filt;
+	ucc_geth_init_pram_t *p_init_enet_pram;
+	ucc_fast_private_t *uccf;
+	ucc_geth_info_t *ug_info;
+	ucc_fast_info_t *uf_info;
+	ucc_fast_t *uf_regs;
+	ucc_geth_t *ug_regs;
+	int ret_val = -EINVAL;
+	u32 remoder = UCC_GETH_REMODER_INIT;
+	u32 init_enet_pram_offset, cecr_subblock, command, maccfg1;
+	u32 ifstat, i, j, size, l2qt, l3qt, length;
+	u16 temoder = UCC_GETH_TEMODER_INIT;
+	u16 test;
+	u8 function_code = 0;
+	u8 *bd, *endOfRing;
+	u8 numThreadsRxNumerical, numThreadsTxNumerical;
+
+	ugeth_vdbg("%s: IN", __FUNCTION__);
+
+	ug_info = ugeth->ug_info;
+	uf_info = &ug_info->uf_info;
+
+	if (!((uf_info->bd_mem_part == MEM_PART_SYSTEM) ||
+	      (uf_info->bd_mem_part == MEM_PART_MURAM))) {
+		ugeth_err("%s: Bad memory partition value.", __FUNCTION__);
+		return -EINVAL;
+	}
+
+	/* Rx BD lengths */
+	for (i = 0; i < ug_info->numQueuesRx; i++) {
+		if ((ug_info->bdRingLenRx[i] < UCC_GETH_RX_BD_RING_SIZE_MIN) ||
+		    (ug_info->bdRingLenRx[i] %
+		     UCC_GETH_RX_BD_RING_SIZE_ALIGNMENT)) {
+			ugeth_err
+			    ("%s: Rx BD ring length must be multiple of 4,"
+				" no smaller than 8.", __FUNCTION__);
+			return -EINVAL;
+		}
+	}
+
+	/* Tx BD lengths */
+	for (i = 0; i < ug_info->numQueuesTx; i++) {
+		if (ug_info->bdRingLenTx[i] < UCC_GETH_TX_BD_RING_SIZE_MIN) {
+			ugeth_err
+			    ("%s: Tx BD ring length must be no smaller than 2.",
+			     __FUNCTION__);
+			return -EINVAL;
+		}
+	}
+
+	/* mrblr */
+	if ((uf_info->max_rx_buf_length == 0) ||
+	    (uf_info->max_rx_buf_length % UCC_GETH_MRBLR_ALIGNMENT)) {
+		ugeth_err
+		    ("%s: max_rx_buf_length must be non-zero multiple of 128.",
+		     __FUNCTION__);
+		return -EINVAL;
+	}
+
+	/* num Tx queues */
+	if (ug_info->numQueuesTx > NUM_TX_QUEUES) {
+		ugeth_err("%s: number of tx queues too large.", __FUNCTION__);
+		return -EINVAL;
+	}
+
+	/* num Rx queues */
+	if (ug_info->numQueuesRx > NUM_RX_QUEUES) {
+		ugeth_err("%s: number of rx queues too large.", __FUNCTION__);
+		return -EINVAL;
+	}
+
+	/* l2qt */
+	for (i = 0; i < UCC_GETH_VLAN_PRIORITY_MAX; i++) {
+		if (ug_info->l2qt[i] >= ug_info->numQueuesRx) {
+			ugeth_err
+			    ("%s: VLAN priority table entry must not be"
+				" larger than number of Rx queues.",
+			     __FUNCTION__);
+			return -EINVAL;
+		}
+	}
+
+	/* l3qt */
+	for (i = 0; i < UCC_GETH_IP_PRIORITY_MAX; i++) {
+		if (ug_info->l3qt[i] >= ug_info->numQueuesRx) {
+			ugeth_err
+			    ("%s: IP priority table entry must not be"
+				" larger than number of Rx queues.",
+			     __FUNCTION__);
+			return -EINVAL;
+		}
+	}
+
+	if (ug_info->cam && !ug_info->ecamptr) {
+		ugeth_err("%s: If cam mode is chosen, must supply cam ptr.",
+			  __FUNCTION__);
+		return -EINVAL;
+	}
+
+	if ((ug_info->numStationAddresses !=
+	     UCC_GETH_NUM_OF_STATION_ADDRESSES_1)
+	    && ug_info->rxExtendedFiltering) {
+		ugeth_err("%s: Number of station addresses greater than 1 "
+			  "not allowed in extended parsing mode.",
+			  __FUNCTION__);
+		return -EINVAL;
+	}
+
+	/* Generate uccm_mask for receive */
+	uf_info->uccm_mask = ug_info->eventRegMask & UCCE_OTHER;/* Errors */
+	for (i = 0; i < ug_info->numQueuesRx; i++)
+		uf_info->uccm_mask |= (UCCE_RXBF_SINGLE_MASK << i);
+
+	for (i = 0; i < ug_info->numQueuesTx; i++)
+		uf_info->uccm_mask |= (UCCE_TXBF_SINGLE_MASK << i);
+	/* Initialize the general fast UCC block. */
+	if (ucc_fast_init(uf_info, &uccf)) {
+		ugeth_err("%s: Failed to init uccf.", __FUNCTION__);
+		ucc_geth_memclean(ugeth);
+		return -ENOMEM;
+	}
+	ugeth->uccf = uccf;
+
+	switch (ug_info->numThreadsRx) {
+	case UCC_GETH_NUM_OF_THREADS_1:
+		numThreadsRxNumerical = 1;
+		break;
+	case UCC_GETH_NUM_OF_THREADS_2:
+		numThreadsRxNumerical = 2;
+		break;
+	case UCC_GETH_NUM_OF_THREADS_4:
+		numThreadsRxNumerical = 4;
+		break;
+	case UCC_GETH_NUM_OF_THREADS_6:
+		numThreadsRxNumerical = 6;
+		break;
+	case UCC_GETH_NUM_OF_THREADS_8:
+		numThreadsRxNumerical = 8;
+		break;
+	default:
+		ugeth_err("%s: Bad number of Rx threads value.", __FUNCTION__);
+		ucc_geth_memclean(ugeth);
+		return -EINVAL;
+		break;
+	}
+
+	switch (ug_info->numThreadsTx) {
+	case UCC_GETH_NUM_OF_THREADS_1:
+		numThreadsTxNumerical = 1;
+		break;
+	case UCC_GETH_NUM_OF_THREADS_2:
+		numThreadsTxNumerical = 2;
+		break;
+	case UCC_GETH_NUM_OF_THREADS_4:
+		numThreadsTxNumerical = 4;
+		break;
+	case UCC_GETH_NUM_OF_THREADS_6:
+		numThreadsTxNumerical = 6;
+		break;
+	case UCC_GETH_NUM_OF_THREADS_8:
+		numThreadsTxNumerical = 8;
+		break;
+	default:
+		ugeth_err("%s: Bad number of Tx threads value.", __FUNCTION__);
+		ucc_geth_memclean(ugeth);
+		return -EINVAL;
+		break;
+	}
+
+	/* Calculate rx_extended_features */
+	ugeth->rx_non_dynamic_extended_features = ug_info->ipCheckSumCheck ||
+	    ug_info->ipAddressAlignment ||
+	    (ug_info->numStationAddresses !=
+	     UCC_GETH_NUM_OF_STATION_ADDRESSES_1);
+
+	ugeth->rx_extended_features = ugeth->rx_non_dynamic_extended_features ||
+	    (ug_info->vlanOperationTagged != UCC_GETH_VLAN_OPERATION_TAGGED_NOP)
+	    || (ug_info->vlanOperationNonTagged !=
+		UCC_GETH_VLAN_OPERATION_NON_TAGGED_NOP);
+
+	uf_regs = uccf->uf_regs;
+	ug_regs = (ucc_geth_t *) (uccf->uf_regs);
+	ugeth->ug_regs = ug_regs;
+
+	init_default_reg_vals(&uf_regs->upsmr,
+			      &ug_regs->maccfg1, &ug_regs->maccfg2);
+
+	/*                    Set UPSMR                      */
+	/* For more details see the hardware spec.           */
+	init_rx_parameters(ug_info->bro,
+			   ug_info->rsh, ug_info->pro, &uf_regs->upsmr);
+
+	/* We're going to ignore other registers for now, */
+	/* except as needed to get up and running         */
+
+	/*                    Set MACCFG1                    */
+	/* For more details see the hardware spec.           */
+	init_flow_control_params(ug_info->aufc,
+				 ug_info->receiveFlowControl,
+				 1,
+				 ug_info->pausePeriod,
+				 ug_info->extensionField,
+				 &uf_regs->upsmr,
+				 &ug_regs->uempr, &ug_regs->maccfg1);
+
+	maccfg1 = in_be32(&ug_regs->maccfg1);
+	maccfg1 |= MACCFG1_ENABLE_RX;
+	maccfg1 |= MACCFG1_ENABLE_TX;
+	out_be32(&ug_regs->maccfg1, maccfg1);
+
+	/*                    Set IPGIFG                     */
+	/* For more details see the hardware spec.           */
+	ret_val = init_inter_frame_gap_params(ug_info->nonBackToBackIfgPart1,
+					      ug_info->nonBackToBackIfgPart2,
+					      ug_info->
+					      miminumInterFrameGapEnforcement,
+					      ug_info->backToBackInterFrameGap,
+					      &ug_regs->ipgifg);
+	if (ret_val != 0) {
+		ugeth_err("%s: IPGIFG initialization parameter too large.",
+			  __FUNCTION__);
+		ucc_geth_memclean(ugeth);
+		return ret_val;
+	}
+
+	/*                    Set HAFDUP                     */
+	/* For more details see the hardware spec.           */
+	ret_val = init_half_duplex_params(ug_info->altBeb,
+					  ug_info->backPressureNoBackoff,
+					  ug_info->noBackoff,
+					  ug_info->excessDefer,
+					  ug_info->altBebTruncation,
+					  ug_info->maxRetransmission,
+					  ug_info->collisionWindow,
+					  &ug_regs->hafdup);
+	if (ret_val != 0) {
+		ugeth_err("%s: Half Duplex initialization parameter too large.",
+			  __FUNCTION__);
+		ucc_geth_memclean(ugeth);
+		return ret_val;
+	}
+
+	/*                    Set IFSTAT                     */
+	/* For more details see the hardware spec.           */
+	/* Read only - resets upon read                      */
+	ifstat = in_be32(&ug_regs->ifstat);
+
+	/*                    Clear UEMPR                    */
+	/* For more details see the hardware spec.           */
+	out_be32(&ug_regs->uempr, 0);
+
+	/*                    Set UESCR                      */
+	/* For more details see the hardware spec.           */
+	init_hw_statistics_gathering_mode((ug_info->statisticsMode &
+				UCC_GETH_STATISTICS_GATHERING_MODE_HARDWARE),
+				0, &uf_regs->upsmr, &ug_regs->uescr);
+
+	/* Allocate Tx bds */
+	for (j = 0; j < ug_info->numQueuesTx; j++) {
+		/* Allocate in multiple of
+		   UCC_GETH_TX_BD_RING_SIZE_MEMORY_ALIGNMENT,
+		   according to spec */
+		length = ((ug_info->bdRingLenTx[j] * UCC_GETH_SIZE_OF_BD)
+			  / UCC_GETH_TX_BD_RING_SIZE_MEMORY_ALIGNMENT)
+		    * UCC_GETH_TX_BD_RING_SIZE_MEMORY_ALIGNMENT;
+		if ((ug_info->bdRingLenTx[j] * UCC_GETH_SIZE_OF_BD) %
+		    UCC_GETH_TX_BD_RING_SIZE_MEMORY_ALIGNMENT)
+			length += UCC_GETH_TX_BD_RING_SIZE_MEMORY_ALIGNMENT;
+		if (uf_info->bd_mem_part == MEM_PART_SYSTEM) {
+			u32 align = 4;
+			if (UCC_GETH_TX_BD_RING_ALIGNMENT > 4)
+				align = UCC_GETH_TX_BD_RING_ALIGNMENT;
+			ugeth->tx_bd_ring_offset[j] =
+				(u32) (kmalloc((u32) (length + align),
+				GFP_KERNEL));
+			if (ugeth->tx_bd_ring_offset[j] != 0)
+				ugeth->p_tx_bd_ring[j] =
+					(void*)((ugeth->tx_bd_ring_offset[j] +
+					align) & ~(align - 1));
+		} else if (uf_info->bd_mem_part == MEM_PART_MURAM) {
+			ugeth->tx_bd_ring_offset[j] =
+			    qe_muram_alloc(length,
+					   UCC_GETH_TX_BD_RING_ALIGNMENT);
+			if (!IS_MURAM_ERR(ugeth->tx_bd_ring_offset[j]))
+				ugeth->p_tx_bd_ring[j] =
+				    (u8 *) qe_muram_addr(ugeth->
+							 tx_bd_ring_offset[j]);
+		}
+		if (!ugeth->p_tx_bd_ring[j]) {
+			ugeth_err
+			    ("%s: Can not allocate memory for Tx bd rings.",
+			     __FUNCTION__);
+			ucc_geth_memclean(ugeth);
+			return -ENOMEM;
+		}
+		/* Zero unused end of bd ring, according to spec */
+		memset(ugeth->p_tx_bd_ring[j] +
+		       ug_info->bdRingLenTx[j] * UCC_GETH_SIZE_OF_BD, 0,
+		       length - ug_info->bdRingLenTx[j] * UCC_GETH_SIZE_OF_BD);
+	}
+
+	/* Allocate Rx bds */
+	for (j = 0; j < ug_info->numQueuesRx; j++) {
+		length = ug_info->bdRingLenRx[j] * UCC_GETH_SIZE_OF_BD;
+		if (uf_info->bd_mem_part == MEM_PART_SYSTEM) {
+			u32 align = 4;
+			if (UCC_GETH_RX_BD_RING_ALIGNMENT > 4)
+				align = UCC_GETH_RX_BD_RING_ALIGNMENT;
+			ugeth->rx_bd_ring_offset[j] =
+			    (u32) (kmalloc((u32) (length + align), GFP_KERNEL));
+			if (ugeth->rx_bd_ring_offset[j] != 0)
+				ugeth->p_rx_bd_ring[j] =
+					(void*)((ugeth->rx_bd_ring_offset[j] +
+					align) & ~(align - 1));
+		} else if (uf_info->bd_mem_part == MEM_PART_MURAM) {
+			ugeth->rx_bd_ring_offset[j] =
+			    qe_muram_alloc(length,
+					   UCC_GETH_RX_BD_RING_ALIGNMENT);
+			if (!IS_MURAM_ERR(ugeth->rx_bd_ring_offset[j]))
+				ugeth->p_rx_bd_ring[j] =
+				    (u8 *) qe_muram_addr(ugeth->
+							 rx_bd_ring_offset[j]);
+		}
+		if (!ugeth->p_rx_bd_ring[j]) {
+			ugeth_err
+			    ("%s: Can not allocate memory for Rx bd rings.",
+			     __FUNCTION__);
+			ucc_geth_memclean(ugeth);
+			return -ENOMEM;
+		}
+	}
+
+	/* Init Tx bds */
+	for (j = 0; j < ug_info->numQueuesTx; j++) {
+		/* Setup the skbuff rings */
+		ugeth->tx_skbuff[j] =
+		    (struct sk_buff **)kmalloc(sizeof(struct sk_buff *) *
+					       ugeth->ug_info->bdRingLenTx[j],
+					       GFP_KERNEL);
+
+		if (ugeth->tx_skbuff[j] == NULL) {
+			ugeth_err("%s: Could not allocate tx_skbuff",
+				  __FUNCTION__);
+			ucc_geth_memclean(ugeth);
+			return -ENOMEM;
+		}
+
+		for (i = 0; i < ugeth->ug_info->bdRingLenTx[j]; i++)
+			ugeth->tx_skbuff[j][i] = NULL;
+
+		ugeth->skb_curtx[j] = ugeth->skb_dirtytx[j] = 0;
+		bd = ugeth->confBd[j] = ugeth->txBd[j] = ugeth->p_tx_bd_ring[j];
+		for (i = 0; i < ug_info->bdRingLenTx[j]; i++) {
+			BD_BUFFER_CLEAR(bd);
+			BD_STATUS_AND_LENGTH_SET(bd, 0);
+			bd += UCC_GETH_SIZE_OF_BD;
+		}
+		bd -= UCC_GETH_SIZE_OF_BD;
+		BD_STATUS_AND_LENGTH_SET(bd, T_W);/* for last BD set Wrap bit */
+	}
+
+	/* Init Rx bds */
+	for (j = 0; j < ug_info->numQueuesRx; j++) {
+		/* Setup the skbuff rings */
+		ugeth->rx_skbuff[j] =
+		    (struct sk_buff **)kmalloc(sizeof(struct sk_buff *) *
+					       ugeth->ug_info->bdRingLenRx[j],
+					       GFP_KERNEL);
+
+		if (ugeth->rx_skbuff[j] == NULL) {
+			ugeth_err("%s: Could not allocate rx_skbuff",
+				  __FUNCTION__);
+			ucc_geth_memclean(ugeth);
+			return -ENOMEM;
+		}
+
+		for (i = 0; i < ugeth->ug_info->bdRingLenRx[j]; i++)
+			ugeth->rx_skbuff[j][i] = NULL;
+
+		ugeth->skb_currx[j] = 0;
+		bd = ugeth->rxBd[j] = ugeth->p_rx_bd_ring[j];
+		for (i = 0; i < ug_info->bdRingLenRx[j]; i++) {
+			BD_STATUS_AND_LENGTH_SET(bd, R_I);
+			BD_BUFFER_CLEAR(bd);
+			bd += UCC_GETH_SIZE_OF_BD;
+		}
+		bd -= UCC_GETH_SIZE_OF_BD;
+		BD_STATUS_AND_LENGTH_SET(bd, R_W);/* for last BD set Wrap bit */
+	}
+
+	/*
+	 * Global PRAM
+	 */
+	/* Tx global PRAM */
+	/* Allocate global tx parameter RAM page */
+	ugeth->tx_glbl_pram_offset =
+	    qe_muram_alloc(sizeof(ucc_geth_tx_global_pram_t),
+			   UCC_GETH_TX_GLOBAL_PRAM_ALIGNMENT);
+	if (IS_MURAM_ERR(ugeth->tx_glbl_pram_offset)) {
+		ugeth_err
+		    ("%s: Can not allocate DPRAM memory for p_tx_glbl_pram.",
+		     __FUNCTION__);
+		ucc_geth_memclean(ugeth);
+		return -ENOMEM;
+	}
+	ugeth->p_tx_glbl_pram =
+	    (ucc_geth_tx_global_pram_t *) qe_muram_addr(ugeth->
+							tx_glbl_pram_offset);
+	/* Zero out p_tx_glbl_pram */
+	memset(ugeth->p_tx_glbl_pram, 0, sizeof(ucc_geth_tx_global_pram_t));
+
+	/* Fill global PRAM */
+
+	/* TQPTR */
+	/* Size varies with number of Tx threads */
+	ugeth->thread_dat_tx_offset =
+	    qe_muram_alloc(numThreadsTxNumerical *
+			   sizeof(ucc_geth_thread_data_tx_t) +
+			   32 * (numThreadsTxNumerical == 1),
+			   UCC_GETH_THREAD_DATA_ALIGNMENT);
+	if (IS_MURAM_ERR(ugeth->thread_dat_tx_offset)) {
+		ugeth_err
+		    ("%s: Can not allocate DPRAM memory for p_thread_data_tx.",
+		     __FUNCTION__);
+		ucc_geth_memclean(ugeth);
+		return -ENOMEM;
+	}
+
+	ugeth->p_thread_data_tx =
+	    (ucc_geth_thread_data_tx_t *) qe_muram_addr(ugeth->
+							thread_dat_tx_offset);
+	out_be32(&ugeth->p_tx_glbl_pram->tqptr, ugeth->thread_dat_tx_offset);
+
+	/* vtagtable */
+	for (i = 0; i < UCC_GETH_TX_VTAG_TABLE_ENTRY_MAX; i++)
+		out_be32(&ugeth->p_tx_glbl_pram->vtagtable[i],
+			 ug_info->vtagtable[i]);
+
+	/* iphoffset */
+	for (i = 0; i < TX_IP_OFFSET_ENTRY_MAX; i++)
+		ugeth->p_tx_glbl_pram->iphoffset[i] = ug_info->iphoffset[i];
+
+	/* SQPTR */
+	/* Size varies with number of Tx queues */
+	ugeth->send_q_mem_reg_offset =
+	    qe_muram_alloc(ug_info->numQueuesTx *
+			   sizeof(ucc_geth_send_queue_qd_t),
+			   UCC_GETH_SEND_QUEUE_QUEUE_DESCRIPTOR_ALIGNMENT);
+	if (IS_MURAM_ERR(ugeth->send_q_mem_reg_offset)) {
+		ugeth_err
+		    ("%s: Can not allocate DPRAM memory for p_send_q_mem_reg.",
+		     __FUNCTION__);
+		ucc_geth_memclean(ugeth);
+		return -ENOMEM;
+	}
+
+	ugeth->p_send_q_mem_reg =
+	    (ucc_geth_send_queue_mem_region_t *) qe_muram_addr(ugeth->
+			send_q_mem_reg_offset);
+	out_be32(&ugeth->p_tx_glbl_pram->sqptr, ugeth->send_q_mem_reg_offset);
+
+	/* Setup the table */
+	/* Assume BD rings are already established */
+	for (i = 0; i < ug_info->numQueuesTx; i++) {
+		endOfRing =
+		    ugeth->p_tx_bd_ring[i] + (ug_info->bdRingLenTx[i] -
+					      1) * UCC_GETH_SIZE_OF_BD;
+		if (ugeth->ug_info->uf_info.bd_mem_part == MEM_PART_SYSTEM) {
+			out_be32(&ugeth->p_send_q_mem_reg->sqqd[i].bd_ring_base,
+				 (u32) virt_to_phys(ugeth->p_tx_bd_ring[i]));
+			out_be32(&ugeth->p_send_q_mem_reg->sqqd[i].
+				 last_bd_completed_address,
+				 (u32) virt_to_phys(endOfRing));
+		} else if (ugeth->ug_info->uf_info.bd_mem_part ==
+			   MEM_PART_MURAM) {
+			out_be32(&ugeth->p_send_q_mem_reg->sqqd[i].bd_ring_base,
+				 (u32) immrbar_virt_to_phys(ugeth->
+							    p_tx_bd_ring[i]));
+			out_be32(&ugeth->p_send_q_mem_reg->sqqd[i].
+				 last_bd_completed_address,
+				 (u32) immrbar_virt_to_phys(endOfRing));
+		}
+	}
+
+	/* schedulerbasepointer */
+
+	if (ug_info->numQueuesTx > 1) {
+	/* scheduler exists only if more than 1 tx queue */
+		ugeth->scheduler_offset =
+		    qe_muram_alloc(sizeof(ucc_geth_scheduler_t),
+				   UCC_GETH_SCHEDULER_ALIGNMENT);
+		if (IS_MURAM_ERR(ugeth->scheduler_offset)) {
+			ugeth_err
+			 ("%s: Can not allocate DPRAM memory for p_scheduler.",
+			     __FUNCTION__);
+			ucc_geth_memclean(ugeth);
+			return -ENOMEM;
+		}
+
+		ugeth->p_scheduler =
+		    (ucc_geth_scheduler_t *) qe_muram_addr(ugeth->
+							   scheduler_offset);
+		out_be32(&ugeth->p_tx_glbl_pram->schedulerbasepointer,
+			 ugeth->scheduler_offset);
+		/* Zero out p_scheduler */
+		memset(ugeth->p_scheduler, 0, sizeof(ucc_geth_scheduler_t));
+
+		/* Set values in scheduler */
+		out_be32(&ugeth->p_scheduler->mblinterval,
+			 ug_info->mblinterval);
+		out_be16(&ugeth->p_scheduler->nortsrbytetime,
+			 ug_info->nortsrbytetime);
+		ugeth->p_scheduler->fracsiz = ug_info->fracsiz;
+		ugeth->p_scheduler->strictpriorityq = ug_info->strictpriorityq;
+		ugeth->p_scheduler->txasap = ug_info->txasap;
+		ugeth->p_scheduler->extrabw = ug_info->extrabw;
+		for (i = 0; i < NUM_TX_QUEUES; i++)
+			ugeth->p_scheduler->weightfactor[i] =
+			    ug_info->weightfactor[i];
+
+		/* Set pointers to cpucount registers in scheduler */
+		ugeth->p_cpucount[0] = &(ugeth->p_scheduler->cpucount0);
+		ugeth->p_cpucount[1] = &(ugeth->p_scheduler->cpucount1);
+		ugeth->p_cpucount[2] = &(ugeth->p_scheduler->cpucount2);
+		ugeth->p_cpucount[3] = &(ugeth->p_scheduler->cpucount3);
+		ugeth->p_cpucount[4] = &(ugeth->p_scheduler->cpucount4);
+		ugeth->p_cpucount[5] = &(ugeth->p_scheduler->cpucount5);
+		ugeth->p_cpucount[6] = &(ugeth->p_scheduler->cpucount6);
+		ugeth->p_cpucount[7] = &(ugeth->p_scheduler->cpucount7);
+	}
+
+	/* schedulerbasepointer */
+	/* TxRMON_PTR (statistics) */
+	if (ug_info->
+	    statisticsMode & UCC_GETH_STATISTICS_GATHERING_MODE_FIRMWARE_TX) {
+		ugeth->tx_fw_statistics_pram_offset =
+		    qe_muram_alloc(sizeof
+				   (ucc_geth_tx_firmware_statistics_pram_t),
+				   UCC_GETH_TX_STATISTICS_ALIGNMENT);
+		if (IS_MURAM_ERR(ugeth->tx_fw_statistics_pram_offset)) {
+			ugeth_err
+			    ("%s: Can not allocate DPRAM memory for"
+				" p_tx_fw_statistics_pram.", __FUNCTION__);
+			ucc_geth_memclean(ugeth);
+			return -ENOMEM;
+		}
+		ugeth->p_tx_fw_statistics_pram =
+		    (ucc_geth_tx_firmware_statistics_pram_t *)
+		    qe_muram_addr(ugeth->tx_fw_statistics_pram_offset);
+		/* Zero out p_tx_fw_statistics_pram */
+		memset(ugeth->p_tx_fw_statistics_pram,
+		       0, sizeof(ucc_geth_tx_firmware_statistics_pram_t));
+	}
+
+	/* temoder */
+	/* Already has speed set */
+
+	if (ug_info->numQueuesTx > 1)
+		temoder |= TEMODER_SCHEDULER_ENABLE;
+	if (ug_info->ipCheckSumGenerate)
+		temoder |= TEMODER_IP_CHECKSUM_GENERATE;
+	temoder |= ((ug_info->numQueuesTx - 1) << TEMODER_NUM_OF_QUEUES_SHIFT);
+	out_be16(&ugeth->p_tx_glbl_pram->temoder, temoder);
+
+	test = in_be16(&ugeth->p_tx_glbl_pram->temoder);
+
+	/* Function code register value to be used later */
+	function_code = QE_BMR_BYTE_ORDER_BO_MOT | UCC_FAST_FUNCTION_CODE_GBL;
+	/* Required for QE */
+
+	/* function code register */
+	out_be32(&ugeth->p_tx_glbl_pram->tstate, ((u32) function_code) << 24);
+
+	/* Rx global PRAM */
+	/* Allocate global rx parameter RAM page */
+	ugeth->rx_glbl_pram_offset =
+	    qe_muram_alloc(sizeof(ucc_geth_rx_global_pram_t),
+			   UCC_GETH_RX_GLOBAL_PRAM_ALIGNMENT);
+	if (IS_MURAM_ERR(ugeth->rx_glbl_pram_offset)) {
+		ugeth_err
+		    ("%s: Can not allocate DPRAM memory for p_rx_glbl_pram.",
+		     __FUNCTION__);
+		ucc_geth_memclean(ugeth);
+		return -ENOMEM;
+	}
+	ugeth->p_rx_glbl_pram =
+	    (ucc_geth_rx_global_pram_t *) qe_muram_addr(ugeth->
+							rx_glbl_pram_offset);
+	/* Zero out p_rx_glbl_pram */
+	memset(ugeth->p_rx_glbl_pram, 0, sizeof(ucc_geth_rx_global_pram_t));
+
+	/* Fill global PRAM */
+
+	/* RQPTR */
+	/* Size varies with number of Rx threads */
+	ugeth->thread_dat_rx_offset =
+	    qe_muram_alloc(numThreadsRxNumerical *
+			   sizeof(ucc_geth_thread_data_rx_t),
+			   UCC_GETH_THREAD_DATA_ALIGNMENT);
+	if (IS_MURAM_ERR(ugeth->thread_dat_rx_offset)) {
+		ugeth_err
+		    ("%s: Can not allocate DPRAM memory for p_thread_data_rx.",
+		     __FUNCTION__);
+		ucc_geth_memclean(ugeth);
+		return -ENOMEM;
+	}
+
+	ugeth->p_thread_data_rx =
+	    (ucc_geth_thread_data_rx_t *) qe_muram_addr(ugeth->
+							thread_dat_rx_offset);
+	out_be32(&ugeth->p_rx_glbl_pram->rqptr, ugeth->thread_dat_rx_offset);
+
+	/* typeorlen */
+	out_be16(&ugeth->p_rx_glbl_pram->typeorlen, ug_info->typeorlen);
+
+	/* rxrmonbaseptr (statistics) */
+	if (ug_info->
+	    statisticsMode & UCC_GETH_STATISTICS_GATHERING_MODE_FIRMWARE_RX) {
+		ugeth->rx_fw_statistics_pram_offset =
+		    qe_muram_alloc(sizeof
+				   (ucc_geth_rx_firmware_statistics_pram_t),
+				   UCC_GETH_RX_STATISTICS_ALIGNMENT);
+		if (IS_MURAM_ERR(ugeth->rx_fw_statistics_pram_offset)) {
+			ugeth_err
+				("%s: Can not allocate DPRAM memory for"
+				" p_rx_fw_statistics_pram.", __FUNCTION__);
+			ucc_geth_memclean(ugeth);
+			return -ENOMEM;
+		}
+		ugeth->p_rx_fw_statistics_pram =
+		    (ucc_geth_rx_firmware_statistics_pram_t *)
+		    qe_muram_addr(ugeth->rx_fw_statistics_pram_offset);
+		/* Zero out p_rx_fw_statistics_pram */
+		memset(ugeth->p_rx_fw_statistics_pram, 0,
+		       sizeof(ucc_geth_rx_firmware_statistics_pram_t));
+	}
+
+	/* intCoalescingPtr */
+
+	/* Size varies with number of Rx queues */
+	ugeth->rx_irq_coalescing_tbl_offset =
+	    qe_muram_alloc(ug_info->numQueuesRx *
+			   sizeof(ucc_geth_rx_interrupt_coalescing_entry_t),
+			   UCC_GETH_RX_INTERRUPT_COALESCING_ALIGNMENT);
+	if (IS_MURAM_ERR(ugeth->rx_irq_coalescing_tbl_offset)) {
+		ugeth_err
+		    ("%s: Can not allocate DPRAM memory for"
+			" p_rx_irq_coalescing_tbl.", __FUNCTION__);
+		ucc_geth_memclean(ugeth);
+		return -ENOMEM;
+	}
+
+	ugeth->p_rx_irq_coalescing_tbl =
+	    (ucc_geth_rx_interrupt_coalescing_table_t *)
+	    qe_muram_addr(ugeth->rx_irq_coalescing_tbl_offset);
+	out_be32(&ugeth->p_rx_glbl_pram->intcoalescingptr,
+		 ugeth->rx_irq_coalescing_tbl_offset);
+
+	/* Fill interrupt coalescing table */
+	for (i = 0; i < ug_info->numQueuesRx; i++) {
+		out_be32(&ugeth->p_rx_irq_coalescing_tbl->coalescingentry[i].
+			 interruptcoalescingmaxvalue,
+			 ug_info->interruptcoalescingmaxvalue[i]);
+		out_be32(&ugeth->p_rx_irq_coalescing_tbl->coalescingentry[i].
+			 interruptcoalescingcounter,
+			 ug_info->interruptcoalescingmaxvalue[i]);
+	}
+
+	/* MRBLR */
+	init_max_rx_buff_len(uf_info->max_rx_buf_length,
+			     &ugeth->p_rx_glbl_pram->mrblr);
+	/* MFLR */
+	out_be16(&ugeth->p_rx_glbl_pram->mflr, ug_info->maxFrameLength);
+	/* MINFLR */
+	init_min_frame_len(ug_info->minFrameLength,
+			   &ugeth->p_rx_glbl_pram->minflr,
+			   &ugeth->p_rx_glbl_pram->mrblr);
+	/* MAXD1 */
+	out_be16(&ugeth->p_rx_glbl_pram->maxd1, ug_info->maxD1Length);
+	/* MAXD2 */
+	out_be16(&ugeth->p_rx_glbl_pram->maxd2, ug_info->maxD2Length);
+
+	/* l2qt */
+	l2qt = 0;
+	for (i = 0; i < UCC_GETH_VLAN_PRIORITY_MAX; i++)
+		l2qt |= (ug_info->l2qt[i] << (28 - 4 * i));
+	out_be32(&ugeth->p_rx_glbl_pram->l2qt, l2qt);
+
+	/* l3qt */
+	for (j = 0; j < UCC_GETH_IP_PRIORITY_MAX; j += 8) {
+		l3qt = 0;
+		for (i = 0; i < 8; i++)
+			l3qt |= (ug_info->l3qt[j + i] << (28 - 4 * i));
+		out_be32(&ugeth->p_rx_glbl_pram->l3qt[j], l3qt);
+	}
+
+	/* vlantype */
+	out_be16(&ugeth->p_rx_glbl_pram->vlantype, ug_info->vlantype);
+
+	/* vlantci */
+	out_be16(&ugeth->p_rx_glbl_pram->vlantci, ug_info->vlantci);
+
+	/* ecamptr */
+	out_be32(&ugeth->p_rx_glbl_pram->ecamptr, ug_info->ecamptr);
+
+	/* RBDQPTR */
+	/* Size varies with number of Rx queues */
+	ugeth->rx_bd_qs_tbl_offset =
+	    qe_muram_alloc(ug_info->numQueuesRx *
+			   (sizeof(ucc_geth_rx_bd_queues_entry_t) +
+			    sizeof(ucc_geth_rx_prefetched_bds_t)),
+			   UCC_GETH_RX_BD_QUEUES_ALIGNMENT);
+	if (IS_MURAM_ERR(ugeth->rx_bd_qs_tbl_offset)) {
+		ugeth_err
+		    ("%s: Can not allocate DPRAM memory for p_rx_bd_qs_tbl.",
+		     __FUNCTION__);
+		ucc_geth_memclean(ugeth);
+		return -ENOMEM;
+	}
+
+	ugeth->p_rx_bd_qs_tbl =
+	    (ucc_geth_rx_bd_queues_entry_t *) qe_muram_addr(ugeth->
+				    rx_bd_qs_tbl_offset);
+	out_be32(&ugeth->p_rx_glbl_pram->rbdqptr, ugeth->rx_bd_qs_tbl_offset);
+	/* Zero out p_rx_bd_qs_tbl */
+	memset(ugeth->p_rx_bd_qs_tbl,
+	       0,
+	       ug_info->numQueuesRx * (sizeof(ucc_geth_rx_bd_queues_entry_t) +
+				       sizeof(ucc_geth_rx_prefetched_bds_t)));
+
+	/* Setup the table */
+	/* Assume BD rings are already established */
+	for (i = 0; i < ug_info->numQueuesRx; i++) {
+		if (ugeth->ug_info->uf_info.bd_mem_part == MEM_PART_SYSTEM) {
+			out_be32(&ugeth->p_rx_bd_qs_tbl[i].externalbdbaseptr,
+				 (u32) virt_to_phys(ugeth->p_rx_bd_ring[i]));
+		} else if (ugeth->ug_info->uf_info.bd_mem_part ==
+			   MEM_PART_MURAM) {
+			out_be32(&ugeth->p_rx_bd_qs_tbl[i].externalbdbaseptr,
+				 (u32) immrbar_virt_to_phys(ugeth->
+							    p_rx_bd_ring[i]));
+		}
+		/* rest of fields handled by QE */
+	}
+
+	/* remoder */
+	/* Already has speed set */
+
+	if (ugeth->rx_extended_features)
+		remoder |= REMODER_RX_EXTENDED_FEATURES;
+	if (ug_info->rxExtendedFiltering)
+		remoder |= REMODER_RX_EXTENDED_FILTERING;
+	if (ug_info->dynamicMaxFrameLength)
+		remoder |= REMODER_DYNAMIC_MAX_FRAME_LENGTH;
+	if (ug_info->dynamicMinFrameLength)
+		remoder |= REMODER_DYNAMIC_MIN_FRAME_LENGTH;
+	remoder |=
+	    ug_info->vlanOperationTagged << REMODER_VLAN_OPERATION_TAGGED_SHIFT;
+	remoder |=
+	    ug_info->
+	    vlanOperationNonTagged << REMODER_VLAN_OPERATION_NON_TAGGED_SHIFT;
+	remoder |= ug_info->rxQoSMode << REMODER_RX_QOS_MODE_SHIFT;
+	remoder |= ((ug_info->numQueuesRx - 1) << REMODER_NUM_OF_QUEUES_SHIFT);
+	if (ug_info->ipCheckSumCheck)
+		remoder |= REMODER_IP_CHECKSUM_CHECK;
+	if (ug_info->ipAddressAlignment)
+		remoder |= REMODER_IP_ADDRESS_ALIGNMENT;
+	out_be32(&ugeth->p_rx_glbl_pram->remoder, remoder);
+
+	/* Note that this function must be called */
+	/* ONLY AFTER p_tx_fw_statistics_pram */
+	/* andp_UccGethRxFirmwareStatisticsPram are allocated ! */
+	init_firmware_statistics_gathering_mode((ug_info->
+		statisticsMode &
+		UCC_GETH_STATISTICS_GATHERING_MODE_FIRMWARE_TX),
+		(ug_info->statisticsMode &
+		UCC_GETH_STATISTICS_GATHERING_MODE_FIRMWARE_RX),
+		&ugeth->p_tx_glbl_pram->txrmonbaseptr,
+		ugeth->tx_fw_statistics_pram_offset,
+		&ugeth->p_rx_glbl_pram->rxrmonbaseptr,
+		ugeth->rx_fw_statistics_pram_offset,
+		&ugeth->p_tx_glbl_pram->temoder,
+		&ugeth->p_rx_glbl_pram->remoder);
+
+	/* function code register */
+	ugeth->p_rx_glbl_pram->rstate = function_code;
+
+	/* initialize extended filtering */
+	if (ug_info->rxExtendedFiltering) {
+		if (!ug_info->extendedFilteringChainPointer) {
+			ugeth_err("%s: Null Extended Filtering Chain Pointer.",
+				  __FUNCTION__);
+			ucc_geth_memclean(ugeth);
+			return -EINVAL;
+		}
+
+		/* Allocate memory for extended filtering Mode Global
+		Parameters */
+		ugeth->exf_glbl_param_offset =
+		    qe_muram_alloc(sizeof(ucc_geth_exf_global_pram_t),
+		UCC_GETH_RX_EXTENDED_FILTERING_GLOBAL_PARAMETERS_ALIGNMENT);
+		if (IS_MURAM_ERR(ugeth->exf_glbl_param_offset)) {
+			ugeth_err
+				("%s: Can not allocate DPRAM memory for"
+				" p_exf_glbl_param.", __FUNCTION__);
+			ucc_geth_memclean(ugeth);
+			return -ENOMEM;
+		}
+
+		ugeth->p_exf_glbl_param =
+		    (ucc_geth_exf_global_pram_t *) qe_muram_addr(ugeth->
+				 exf_glbl_param_offset);
+		out_be32(&ugeth->p_rx_glbl_pram->exfGlobalParam,
+			 ugeth->exf_glbl_param_offset);
+		out_be32(&ugeth->p_exf_glbl_param->l2pcdptr,
+			 (u32) ug_info->extendedFilteringChainPointer);
+
+	} else {		/* initialize 82xx style address filtering */
+
+		/* Init individual address recognition registers to disabled */
+
+		for (j = 0; j < NUM_OF_PADDRS; j++)
+			ugeth_82xx_filtering_clear_addr_in_paddr(ugeth, (u8) j);
+
+		/* Create CQs for hash tables */
+		if (ug_info->maxGroupAddrInHash > 0) {
+			INIT_LIST_HEAD(&ugeth->group_hash_q);
+		}
+		if (ug_info->maxIndAddrInHash > 0) {
+			INIT_LIST_HEAD(&ugeth->ind_hash_q);
+		}
+		p_82xx_addr_filt =
+		    (ucc_geth_82xx_address_filtering_pram_t *) ugeth->
+		    p_rx_glbl_pram->addressfiltering;
+
+		ugeth_82xx_filtering_clear_all_addr_in_hash(ugeth,
+			ENET_ADDR_TYPE_GROUP);
+		ugeth_82xx_filtering_clear_all_addr_in_hash(ugeth,
+			ENET_ADDR_TYPE_INDIVIDUAL);
+	}
+
+	/*
+	 * Initialize UCC at QE level
+	 */
+
+	command = QE_INIT_TX_RX;
+
+	/* Allocate shadow InitEnet command parameter structure.
+	 * This is needed because after the InitEnet command is executed,
+	 * the structure in DPRAM is released, because DPRAM is a premium
+	 * resource.
+	 * This shadow structure keeps a copy of what was done so that the
+	 * allocated resources can be released when the channel is freed.
+	 */
+	if (!(ugeth->p_init_enet_param_shadow =
+	     (ucc_geth_init_pram_t *) kmalloc(sizeof(ucc_geth_init_pram_t),
+					      GFP_KERNEL))) {
+		ugeth_err
+		    ("%s: Can not allocate memory for"
+			" p_UccInitEnetParamShadows.", __FUNCTION__);
+		ucc_geth_memclean(ugeth);
+		return -ENOMEM;
+	}
+	/* Zero out *p_init_enet_param_shadow */
+	memset((char *)ugeth->p_init_enet_param_shadow,
+	       0, sizeof(ucc_geth_init_pram_t));
+
+	/* Fill shadow InitEnet command parameter structure */
+
+	ugeth->p_init_enet_param_shadow->resinit1 =
+	    ENET_INIT_PARAM_MAGIC_RES_INIT1;
+	ugeth->p_init_enet_param_shadow->resinit2 =
+	    ENET_INIT_PARAM_MAGIC_RES_INIT2;
+	ugeth->p_init_enet_param_shadow->resinit3 =
+	    ENET_INIT_PARAM_MAGIC_RES_INIT3;
+	ugeth->p_init_enet_param_shadow->resinit4 =
+	    ENET_INIT_PARAM_MAGIC_RES_INIT4;
+	ugeth->p_init_enet_param_shadow->resinit5 =
+	    ENET_INIT_PARAM_MAGIC_RES_INIT5;
+	ugeth->p_init_enet_param_shadow->rgftgfrxglobal |=
+	    ((u32) ug_info->numThreadsRx) << ENET_INIT_PARAM_RGF_SHIFT;
+	ugeth->p_init_enet_param_shadow->rgftgfrxglobal |=
+	    ((u32) ug_info->numThreadsTx) << ENET_INIT_PARAM_TGF_SHIFT;
+
+	ugeth->p_init_enet_param_shadow->rgftgfrxglobal |=
+	    ugeth->rx_glbl_pram_offset | ug_info->riscRx;
+	if ((ug_info->largestexternallookupkeysize !=
+	     QE_FLTR_LARGEST_EXTERNAL_TABLE_LOOKUP_KEY_SIZE_NONE)
+	    && (ug_info->largestexternallookupkeysize !=
+		QE_FLTR_LARGEST_EXTERNAL_TABLE_LOOKUP_KEY_SIZE_8_BYTES)
+	    && (ug_info->largestexternallookupkeysize !=
+		QE_FLTR_LARGEST_EXTERNAL_TABLE_LOOKUP_KEY_SIZE_16_BYTES)) {
+		ugeth_err("%s: Invalid largest External Lookup Key Size.",
+			  __FUNCTION__);
+		ucc_geth_memclean(ugeth);
+		return -EINVAL;
+	}
+	ugeth->p_init_enet_param_shadow->largestexternallookupkeysize =
+	    ug_info->largestexternallookupkeysize;
+	size = sizeof(ucc_geth_thread_rx_pram_t);
+	if (ug_info->rxExtendedFiltering) {
+		size += THREAD_RX_PRAM_ADDITIONAL_FOR_EXTENDED_FILTERING;
+		if (ug_info->largestexternallookupkeysize ==
+		    QE_FLTR_TABLE_LOOKUP_KEY_SIZE_8_BYTES)
+			size +=
+			    THREAD_RX_PRAM_ADDITIONAL_FOR_EXTENDED_FILTERING_8;
+		if (ug_info->largestexternallookupkeysize ==
+		    QE_FLTR_TABLE_LOOKUP_KEY_SIZE_16_BYTES)
+			size +=
+			    THREAD_RX_PRAM_ADDITIONAL_FOR_EXTENDED_FILTERING_16;
+	}
+
+	if ((ret_val = fill_init_enet_entries(ugeth, &(ugeth->
+		p_init_enet_param_shadow->rxthread[0]),
+		(u8) (numThreadsRxNumerical + 1)
+		/* Rx needs one extra for terminator */
+		, size, UCC_GETH_THREAD_RX_PRAM_ALIGNMENT,
+		ug_info->riscRx, 1)) != 0) {
+			ugeth_err("%s: Can not fill p_init_enet_param_shadow.",
+				__FUNCTION__);
+		ucc_geth_memclean(ugeth);
+		return ret_val;
+	}
+
+	ugeth->p_init_enet_param_shadow->txglobal =
+	    ugeth->tx_glbl_pram_offset | ug_info->riscTx;
+	if ((ret_val =
+	     fill_init_enet_entries(ugeth,
+				    &(ugeth->p_init_enet_param_shadow->
+				      txthread[0]), numThreadsTxNumerical,
+				    sizeof(ucc_geth_thread_tx_pram_t),
+				    UCC_GETH_THREAD_TX_PRAM_ALIGNMENT,
+				    ug_info->riscTx, 0)) != 0) {
+		ugeth_err("%s: Can not fill p_init_enet_param_shadow.",
+			  __FUNCTION__);
+		ucc_geth_memclean(ugeth);
+		return ret_val;
+	}
+
+	/* Load Rx bds with buffers */
+	for (i = 0; i < ug_info->numQueuesRx; i++) {
+		if ((ret_val = rx_bd_buffer_set(ugeth, (u8) i)) != 0) {
+			ugeth_err("%s: Can not fill Rx bds with buffers.",
+				  __FUNCTION__);
+			ucc_geth_memclean(ugeth);
+			return ret_val;
+		}
+	}
+
+	/* Allocate InitEnet command parameter structure */
+	init_enet_pram_offset = qe_muram_alloc(sizeof(ucc_geth_init_pram_t), 4);
+	if (IS_MURAM_ERR(init_enet_pram_offset)) {
+		ugeth_err
+		    ("%s: Can not allocate DPRAM memory for p_init_enet_pram.",
+		     __FUNCTION__);
+		ucc_geth_memclean(ugeth);
+		return -ENOMEM;
+	}
+	p_init_enet_pram =
+	    (ucc_geth_init_pram_t *) qe_muram_addr(init_enet_pram_offset);
+
+	/* Copy shadow InitEnet command parameter structure into PRAM */
+	p_init_enet_pram->resinit1 = ugeth->p_init_enet_param_shadow->resinit1;
+	p_init_enet_pram->resinit2 = ugeth->p_init_enet_param_shadow->resinit2;
+	p_init_enet_pram->resinit3 = ugeth->p_init_enet_param_shadow->resinit3;
+	p_init_enet_pram->resinit4 = ugeth->p_init_enet_param_shadow->resinit4;
+	out_be16(&p_init_enet_pram->resinit5,
+		 ugeth->p_init_enet_param_shadow->resinit5);
+	p_init_enet_pram->largestexternallookupkeysize =
+	    ugeth->p_init_enet_param_shadow->largestexternallookupkeysize;
+	out_be32(&p_init_enet_pram->rgftgfrxglobal,
+		 ugeth->p_init_enet_param_shadow->rgftgfrxglobal);
+	for (i = 0; i < ENET_INIT_PARAM_MAX_ENTRIES_RX; i++)
+		out_be32(&p_init_enet_pram->rxthread[i],
+			 ugeth->p_init_enet_param_shadow->rxthread[i]);
+	out_be32(&p_init_enet_pram->txglobal,
+		 ugeth->p_init_enet_param_shadow->txglobal);
+	for (i = 0; i < ENET_INIT_PARAM_MAX_ENTRIES_TX; i++)
+		out_be32(&p_init_enet_pram->txthread[i],
+			 ugeth->p_init_enet_param_shadow->txthread[i]);
+
+	/* Issue QE command */
+	cecr_subblock =
+	    ucc_fast_get_qe_cr_subblock(ugeth->ug_info->uf_info.ucc_num);
+	qe_issue_cmd(command, cecr_subblock, (u8) QE_CR_PROTOCOL_ETHERNET,
+		     init_enet_pram_offset);
+
+	/* Free InitEnet command parameter */
+	qe_muram_free(init_enet_pram_offset);
+
+	return 0;
+}
+
+/* returns a net_device_stats structure pointer */
+static struct net_device_stats *ucc_geth_get_stats(struct net_device *dev)
+{
+	ucc_geth_private_t *ugeth = netdev_priv(dev);
+
+	return &(ugeth->stats);
+}
+
+/* ucc_geth_timeout gets called when a packet has not been
+ * transmitted after a set amount of time.
+ * For now, assume that clearing out all the structures, and
+ * starting over will fix the problem. */
+static void ucc_geth_timeout(struct net_device *dev)
+{
+	ucc_geth_private_t *ugeth = netdev_priv(dev);
+
+	ugeth_vdbg("%s: IN", __FUNCTION__);
+
+	ugeth->stats.tx_errors++;
+
+	ugeth_dump_regs(ugeth);
+
+	if (dev->flags & IFF_UP) {
+		ucc_geth_stop(ugeth);
+		ucc_geth_startup(ugeth);
+	}
+
+	netif_schedule(dev);
+}
+
+/* This is called by the kernel when a frame is ready for transmission. */
+/* It is pointed to by the dev->hard_start_xmit function pointer */
+static int ucc_geth_start_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+	ucc_geth_private_t *ugeth = netdev_priv(dev);
+	u8 *bd;			/* BD pointer */
+	u32 bd_status;
+	u8 txQ = 0;
+
+	ugeth_vdbg("%s: IN", __FUNCTION__);
+
+	spin_lock_irq(&ugeth->lock);
+
+	ugeth->stats.tx_bytes += skb->len;
+
+	/* Start from the next BD that should be filled */
+	bd = ugeth->txBd[txQ];
+	bd_status = BD_STATUS_AND_LENGTH(bd);
+	/* Save the skb pointer so we can free it later */
+	ugeth->tx_skbuff[txQ][ugeth->skb_curtx[txQ]] = skb;
+
+	/* Update the current skb pointer (wrapping if this was the last) */
+	ugeth->skb_curtx[txQ] =
+	    (ugeth->skb_curtx[txQ] +
+	     1) & TX_RING_MOD_MASK(ugeth->ug_info->bdRingLenTx[txQ]);
+
+	/* set up the buffer descriptor */
+	BD_BUFFER_SET(bd,
+		      dma_map_single(NULL, skb->data, skb->len, DMA_TO_DEVICE));
+
+	//printk(KERN_DEBUG"skb->data is 0x%x\n",skb->data);
+
+	bd_status = (bd_status & T_W) | T_R | T_I | T_L | skb->len;
+
+	BD_STATUS_AND_LENGTH_SET(bd, bd_status);
+
+	dev->trans_start = jiffies;
+
+	/* Move to next BD in the ring */
+	if (!(bd_status & T_W))
+		ugeth->txBd[txQ] = bd + UCC_GETH_SIZE_OF_BD;
+	else
+		ugeth->txBd[txQ] = ugeth->p_tx_bd_ring[txQ];
+
+	/* If the next BD still needs to be cleaned up, then the bds
+	   are full.  We need to tell the kernel to stop sending us stuff. */
+	if (bd == ugeth->confBd[txQ]) {
+		if (!netif_queue_stopped(dev))
+			netif_stop_queue(dev);
+	}
+
+	if (ugeth->p_scheduler) {
+		ugeth->cpucount[txQ]++;
+		/* Indicate to QE that there are more Tx bds ready for
+		transmission */
+		/* This is done by writing a running counter of the bd
+		count to the scheduler PRAM. */
+		out_be16(ugeth->p_cpucount[txQ], ugeth->cpucount[txQ]);
+	}
+
+	spin_unlock_irq(&ugeth->lock);
+
+	return 0;
+}
+
+static int ucc_geth_rx(ucc_geth_private_t *ugeth, u8 rxQ, int rx_work_limit)
+{
+	struct sk_buff *skb;
+	u8 *bd;
+	u16 length, howmany = 0;
+	u32 bd_status;
+	u8 *bdBuffer;
+
+	ugeth_vdbg("%s: IN", __FUNCTION__);
+
+	spin_lock(&ugeth->lock);
+	/* collect received buffers */
+	bd = ugeth->rxBd[rxQ];
+
+	bd_status = BD_STATUS_AND_LENGTH(bd);
+
+	/* while there are received buffers and BD is full (~R_E) */
+	while (!((bd_status & (R_E)) || (--rx_work_limit < 0))) {
+		bdBuffer = (u8 *) BD_BUFFER(bd);
+		length = (u16) ((bd_status & BD_LENGTH_MASK) - 4);
+		skb = ugeth->rx_skbuff[rxQ][ugeth->skb_currx[rxQ]];
+
+		/* determine whether buffer is first, last, first and last
+		(single buffer frame) or middle (not first and not last) */
+		if (!skb ||
+		    (!(bd_status & (R_F | R_L))) ||
+		    (bd_status & R_ERRORS_FATAL)) {
+			ugeth_vdbg("%s, %d: ERROR!!! skb - 0x%08x",
+				   __FUNCTION__, __LINE__, (u32) skb);
+			if (skb)
+				dev_kfree_skb_any(skb);
+
+			ugeth->rx_skbuff[rxQ][ugeth->skb_currx[rxQ]] = NULL;
+			ugeth->stats.rx_dropped++;
+		} else {
+			ugeth->stats.rx_packets++;
+			howmany++;
+
+			/* Prep the skb for the packet */
+			skb_put(skb, length);
+
+			/* Tell the skb what kind of packet this is */
+			skb->protocol = eth_type_trans(skb, ugeth->dev);
+
+			ugeth->stats.rx_bytes += length;
+			/* Send the packet up the stack */
+#ifdef CONFIG_UGETH_NAPI
+			netif_receive_skb(skb);
+#else
+			netif_rx(skb);
+#endif				/* CONFIG_UGETH_NAPI */
+		}
+
+		ugeth->dev->last_rx = jiffies;
+
+		skb = get_new_skb(ugeth, bd);
+		if (!skb) {
+			ugeth_warn("%s: No Rx Data Buffer", __FUNCTION__);
+			spin_unlock(&ugeth->lock);
+			ugeth->stats.rx_dropped++;
+			break;
+		}
+
+		ugeth->rx_skbuff[rxQ][ugeth->skb_currx[rxQ]] = skb;
+
+		/* update to point at the next skb */
+		ugeth->skb_currx[rxQ] =
+		    (ugeth->skb_currx[rxQ] +
+		     1) & RX_RING_MOD_MASK(ugeth->ug_info->bdRingLenRx[rxQ]);
+
+		if (bd_status & R_W)
+			bd = ugeth->p_rx_bd_ring[rxQ];
+		else
+			bd += UCC_GETH_SIZE_OF_BD;
+
+		bd_status = BD_STATUS_AND_LENGTH(bd);
+	}
+
+	ugeth->rxBd[rxQ] = bd;
+	spin_unlock(&ugeth->lock);
+	return howmany;
+}
+
+static int ucc_geth_tx(struct net_device *dev, u8 txQ)
+{
+	/* Start from the next BD that should be filled */
+	ucc_geth_private_t *ugeth = netdev_priv(dev);
+	u8 *bd;			/* BD pointer */
+	u32 bd_status;
+
+	bd = ugeth->confBd[txQ];
+	bd_status = BD_STATUS_AND_LENGTH(bd);
+
+	/* Normal processing. */
+	while ((bd_status & T_R) == 0) {
+		/* BD contains already transmitted buffer.   */
+		/* Handle the transmitted buffer and release */
+		/* the BD to be used with the current frame  */
+
+		if ((bd = ugeth->txBd[txQ]) && (netif_queue_stopped(dev) == 0))
+			break;
+
+		ugeth->stats.tx_packets++;
+
+		/* Free the sk buffer associated with this TxBD */
+		dev_kfree_skb_irq(ugeth->
+				  tx_skbuff[txQ][ugeth->skb_dirtytx[txQ]]);
+		ugeth->tx_skbuff[txQ][ugeth->skb_dirtytx[txQ]] = NULL;
+		ugeth->skb_dirtytx[txQ] =
+		    (ugeth->skb_dirtytx[txQ] +
+		     1) & TX_RING_MOD_MASK(ugeth->ug_info->bdRingLenTx[txQ]);
+
+		/* We freed a buffer, so now we can restart transmission */
+		if (netif_queue_stopped(dev))
+			netif_wake_queue(dev);
+
+		/* Advance the confirmation BD pointer */
+		if (!(bd_status & T_W))
+			ugeth->confBd[txQ] += UCC_GETH_SIZE_OF_BD;
+		else
+			ugeth->confBd[txQ] = ugeth->p_tx_bd_ring[txQ];
+	}
+	return 0;
+}
+
+#ifdef CONFIG_UGETH_NAPI
+static int ucc_geth_poll(struct net_device *dev, int *budget)
+{
+	ucc_geth_private_t *ugeth = netdev_priv(dev);
+	int howmany;
+	int rx_work_limit = *budget;
+	u8 rxQ = 0;
+
+	if (rx_work_limit > dev->quota)
+		rx_work_limit = dev->quota;
+
+	howmany = ucc_geth_rx(ugeth, rxQ, rx_work_limit);
+
+	dev->quota -= howmany;
+	rx_work_limit -= howmany;
+	*budget -= howmany;
+
+	if (rx_work_limit >= 0)
+		netif_rx_complete(dev);
+
+	return (rx_work_limit < 0) ? 1 : 0;
+}
+#endif				/* CONFIG_UGETH_NAPI */
+
+static irqreturn_t ucc_geth_irq_handler(int irq, void *info,
+					struct pt_regs *regs)
+{
+	struct net_device *dev = (struct net_device *)info;
+	ucc_geth_private_t *ugeth = netdev_priv(dev);
+	ucc_fast_private_t *uccf;
+	ucc_geth_info_t *ug_info;
+	register u32 ucce = 0;
+	register u32 bit_mask = UCCE_RXBF_SINGLE_MASK;
+	register u32 tx_mask = UCCE_TXBF_SINGLE_MASK;
+	register u8 i;
+
+	ugeth_vdbg("%s: IN", __FUNCTION__);
+
+	if (!ugeth)
+		return IRQ_NONE;
+
+	uccf = ugeth->uccf;
+	ug_info = ugeth->ug_info;
+
+	do {
+		ucce |= (u32) (in_be32(uccf->p_ucce) & in_be32(uccf->p_uccm));
+
+		/* clear event bits for next time */
+		/* Side effect here is to mask ucce variable
+		for future processing below. */
+		out_be32(uccf->p_ucce, ucce);	/* Clear with ones,
+						but only bits in UCCM */
+
+		/* We ignore Tx interrupts because Tx confirmation is
+		done inside Tx routine */
+
+		for (i = 0; i < ug_info->numQueuesRx; i++) {
+			if (ucce & bit_mask)
+				ucc_geth_rx(ugeth, i,
+					    (int)ugeth->ug_info->
+					    bdRingLenRx[i]);
+			ucce &= ~bit_mask;
+			bit_mask <<= 1;
+		}
+
+		for (i = 0; i < ug_info->numQueuesTx; i++) {
+			if (ucce & tx_mask)
+				ucc_geth_tx(dev, i);
+			ucce &= ~tx_mask;
+			tx_mask <<= 1;
+		}
+
+		/* Exceptions */
+		if (ucce & UCCE_BSY) {
+			ugeth_vdbg("Got BUSY irq!!!!");
+			ugeth->stats.rx_errors++;
+			ucce &= ~UCCE_BSY;
+		}
+		if (ucce & UCCE_OTHER) {
+			ugeth_vdbg("Got frame with error (ucce - 0x%08x)!!!!",
+				   ucce);
+			ugeth->stats.rx_errors++;
+			ucce &= ~ucce;
+		}
+	}
+	while (ucce);
+
+	return IRQ_HANDLED;
+}
+
+static irqreturn_t phy_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	struct net_device *dev = (struct net_device *)dev_id;
+	ucc_geth_private_t *ugeth = netdev_priv(dev);
+
+	ugeth_vdbg("%s: IN", __FUNCTION__);
+
+	/* Clear the interrupt */
+	mii_clear_phy_interrupt(ugeth->mii_info);
+
+	/* Disable PHY interrupts */
+	mii_configure_phy_interrupt(ugeth->mii_info, MII_INTERRUPT_DISABLED);
+
+	/* Schedule the phy change */
+	schedule_work(&ugeth->tq);
+
+	return IRQ_HANDLED;
+}
+
+/* Scheduled by the phy_interrupt/timer to handle PHY changes */
+static void ugeth_phy_change(void *data)
+{
+	struct net_device *dev = (struct net_device *)data;
+	ucc_geth_private_t *ugeth = netdev_priv(dev);
+	ucc_geth_t *ug_regs;
+	int result = 0;
+
+	ugeth_vdbg("%s: IN", __FUNCTION__);
+
+	ug_regs = ugeth->ug_regs;
+
+	/* Delay to give the PHY a chance to change the
+	 * register state */
+	msleep(1);
+
+	/* Update the link, speed, duplex */
+	result = ugeth->mii_info->phyinfo->read_status(ugeth->mii_info);
+
+	/* Adjust the known status as long as the link
+	 * isn't still coming up */
+	if ((0 == result) || (ugeth->mii_info->link == 0))
+		adjust_link(dev);
+
+	/* Reenable interrupts, if needed */
+	if (ugeth->ug_info->board_flags & FSL_UGETH_BRD_HAS_PHY_INTR)
+		mii_configure_phy_interrupt(ugeth->mii_info,
+					    MII_INTERRUPT_ENABLED);
+}
+
+/* Called every so often on systems that don't interrupt
+ * the core for PHY changes */
+static void ugeth_phy_timer(unsigned long data)
+{
+	struct net_device *dev = (struct net_device *)data;
+	ucc_geth_private_t *ugeth = netdev_priv(dev);
+
+	schedule_work(&ugeth->tq);
+
+	mod_timer(&ugeth->phy_info_timer, jiffies + PHY_CHANGE_TIME * HZ);
+}
+
+/* Keep trying aneg for some time
+ * If, after GFAR_AN_TIMEOUT seconds, it has not
+ * finished, we switch to forced.
+ * Either way, once the process has completed, we either
+ * request the interrupt, or switch the timer over to
+ * using ugeth_phy_timer to check status */
+static void ugeth_phy_startup_timer(unsigned long data)
+{
+	struct ugeth_mii_info *mii_info = (struct ugeth_mii_info *)data;
+	ucc_geth_private_t *ugeth = netdev_priv(mii_info->dev);
+	static int secondary = UGETH_AN_TIMEOUT;
+	int result;
+
+	/* Configure the Auto-negotiation */
+	result = mii_info->phyinfo->config_aneg(mii_info);
+
+	/* If autonegotiation failed to start, and
+	 * we haven't timed out, reset the timer, and return */
+	if (result && secondary--) {
+		mod_timer(&ugeth->phy_info_timer, jiffies + HZ);
+		return;
+	} else if (result) {
+		/* Couldn't start autonegotiation.
+		 * Try switching to forced */
+		mii_info->autoneg = 0;
+		result = mii_info->phyinfo->config_aneg(mii_info);
+
+		/* Forcing failed!  Give up */
+		if (result) {
+			ugeth_err("%s: Forcing failed!", mii_info->dev->name);
+			return;
+		}
+	}
+
+	/* Kill the timer so it can be restarted */
+	del_timer_sync(&ugeth->phy_info_timer);
+
+	/* Grab the PHY interrupt, if necessary/possible */
+	if (ugeth->ug_info->board_flags & FSL_UGETH_BRD_HAS_PHY_INTR) {
+		if (request_irq(ugeth->ug_info->phy_interrupt,
+				phy_interrupt,
+				SA_SHIRQ, "phy_interrupt", mii_info->dev) < 0) {
+			ugeth_err("%s: Can't get IRQ %d (PHY)",
+				  mii_info->dev->name,
+				  ugeth->ug_info->phy_interrupt);
+		} else {
+			mii_configure_phy_interrupt(ugeth->mii_info,
+						    MII_INTERRUPT_ENABLED);
+			return;
+		}
+	}
+
+	/* Start the timer again, this time in order to
+	 * handle a change in status */
+	init_timer(&ugeth->phy_info_timer);
+	ugeth->phy_info_timer.function = &ugeth_phy_timer;
+	ugeth->phy_info_timer.data = (unsigned long)mii_info->dev;
+	mod_timer(&ugeth->phy_info_timer, jiffies + PHY_CHANGE_TIME * HZ);
+}
+
+/* Called when something needs to use the ethernet device */
+/* Returns 0 for success. */
+static int ucc_geth_open(struct net_device *dev)
+{
+	ucc_geth_private_t *ugeth = netdev_priv(dev);
+	int err;
+
+	ugeth_vdbg("%s: IN", __FUNCTION__);
+
+	/* Test station address */
+	if (dev->dev_addr[0] & ENET_GROUP_ADDR) {
+		ugeth_err("%s: Multicast address used for station address"
+			  " - is this what you wanted?", __FUNCTION__);
+		return -EINVAL;
+	}
+
+	err = ucc_geth_startup(ugeth);
+	if (err) {
+		ugeth_err("%s: Cannot configure net device, aborting.",
+			  dev->name);
+		return err;
+	}
+
+	err = adjust_enet_interface(ugeth);
+	if (err) {
+		ugeth_err("%s: Cannot configure net device, aborting.",
+			  dev->name);
+		return err;
+	}
+
+	/*       Set MACSTNADDR1, MACSTNADDR2                */
+	/* For more details see the hardware spec.           */
+	init_mac_station_addr_regs(dev->dev_addr[0],
+				   dev->dev_addr[1],
+				   dev->dev_addr[2],
+				   dev->dev_addr[3],
+				   dev->dev_addr[4],
+				   dev->dev_addr[5],
+				   &ugeth->ug_regs->macstnaddr1,
+				   &ugeth->ug_regs->macstnaddr2);
+
+	err = init_phy(dev);
+	if (err) {
+		ugeth_err("%s: Cannot initialzie PHY, aborting.", dev->name);
+		return err;
+	}
+#ifndef CONFIG_UGETH_NAPI
+	err =
+	    request_irq(ugeth->ug_info->uf_info.irq, ucc_geth_irq_handler, 0,
+			"UCC Geth", dev);
+	if (err) {
+		ugeth_err("%s: Cannot get IRQ for net device, aborting.",
+			  dev->name);
+		ucc_geth_stop(ugeth);
+		return err;
+	}
+#endif				/* CONFIG_UGETH_NAPI */
+
+	/* Set up the PHY change work queue */
+	INIT_WORK(&ugeth->tq, ugeth_phy_change, dev);
+
+	init_timer(&ugeth->phy_info_timer);
+	ugeth->phy_info_timer.function = &ugeth_phy_startup_timer;
+	ugeth->phy_info_timer.data = (unsigned long)ugeth->mii_info;
+	mod_timer(&ugeth->phy_info_timer, jiffies + HZ);
+
+	err = ugeth_enable(ugeth, COMM_DIR_RX_AND_TX);
+	if (err) {
+		ugeth_err("%s: Cannot enable net device, aborting.", dev->name);
+		ucc_geth_stop(ugeth);
+		return err;
+	}
+
+	netif_start_queue(dev);
+
+	return err;
+}
+
+/* Stops the kernel queue, and halts the controller */
+static int ucc_geth_close(struct net_device *dev)
+{
+	ucc_geth_private_t *ugeth = netdev_priv(dev);
+
+	ugeth_vdbg("%s: IN", __FUNCTION__);
+
+	ucc_geth_stop(ugeth);
+
+	/* Shutdown the PHY */
+	if (ugeth->mii_info->phyinfo->close)
+		ugeth->mii_info->phyinfo->close(ugeth->mii_info);
+
+	kfree(ugeth->mii_info);
+
+	netif_stop_queue(dev);
+
+	return 0;
+}
+
+struct ethtool_ops ucc_geth_ethtool_ops = {
+	.get_settings = NULL,
+	.get_drvinfo = NULL,
+	.get_regs_len = NULL,
+	.get_regs = NULL,
+	.get_link = NULL,
+	.get_coalesce = NULL,
+	.set_coalesce = NULL,
+	.get_ringparam = NULL,
+	.set_ringparam = NULL,
+	.get_strings = NULL,
+	.get_stats_count = NULL,
+	.get_ethtool_stats = NULL,
+};
+
+static int ucc_geth_probe(struct device *device)
+{
+	struct platform_device *pdev = to_platform_device(device);
+	struct ucc_geth_platform_data *ugeth_pdata;
+	struct net_device *dev = NULL;
+	struct ucc_geth_private *ugeth = NULL;
+	struct ucc_geth_info *ug_info;
+	int err;
+	static int mii_mng_configured = 0;
+
+	ugeth_vdbg("%s: IN", __FUNCTION__);
+
+	ugeth_pdata = (struct ucc_geth_platform_data *)pdev->dev.platform_data;
+
+	ug_info = &ugeth_info[pdev->id];
+	ug_info->uf_info.ucc_num = pdev->id;
+	ug_info->uf_info.rx_clock = ugeth_pdata->rx_clock;
+	ug_info->uf_info.tx_clock = ugeth_pdata->tx_clock;
+	ug_info->uf_info.regs = ugeth_pdata->phy_reg_addr;
+	ug_info->uf_info.irq = platform_get_irq(pdev, 0);
+	ug_info->phy_address = ugeth_pdata->phy_id;
+	ug_info->enet_interface = ugeth_pdata->phy_interface;
+	ug_info->board_flags = ugeth_pdata->board_flags;
+	ug_info->phy_interrupt = ugeth_pdata->phy_interrupt;
+
+	printk(KERN_INFO "ucc_geth: UCC%1d at 0x%8x (irq = %d) \n",
+		ug_info->uf_info.ucc_num + 1, ug_info->uf_info.regs,
+		ug_info->uf_info.irq);
+
+	if (ug_info == NULL) {
+		ugeth_err("%s: [%d] Missing additional data!", __FUNCTION__,
+			  pdev->id);
+		return -ENODEV;
+	}
+
+	if (!mii_mng_configured) {
+		ucc_set_qe_mux_mii_mng(ug_info->uf_info.ucc_num);
+		mii_mng_configured = 1;
+	}
+
+	/* Create an ethernet device instance */
+	dev = alloc_etherdev(sizeof(*ugeth));
+
+	if (dev == NULL)
+		return -ENOMEM;
+
+	ugeth = netdev_priv(dev);
+	spin_lock_init(&ugeth->lock);
+
+	dev_set_drvdata(device, dev);
+
+	/* Set the dev->base_addr to the gfar reg region */
+	dev->base_addr = (unsigned long)(ug_info->uf_info.regs);
+
+	SET_MODULE_OWNER(dev);
+	SET_NETDEV_DEV(dev, device);
+
+	/* Fill in the dev structure */
+	dev->open = ucc_geth_open;
+	dev->hard_start_xmit = ucc_geth_start_xmit;
+	dev->tx_timeout = ucc_geth_timeout;
+	dev->watchdog_timeo = TX_TIMEOUT;
+#ifdef CONFIG_UGETH_NAPI
+	dev->poll = ucc_geth_poll;
+	dev->weight = UCC_GETH_DEV_WEIGHT;
+#endif				/* CONFIG_UGETH_NAPI */
+	dev->stop = ucc_geth_close;
+	dev->get_stats = ucc_geth_get_stats;
+//    dev->change_mtu = ucc_geth_change_mtu;
+	dev->mtu = 1500;
+	dev->set_multicast_list = ucc_geth_set_multi;
+	dev->ethtool_ops = &ucc_geth_ethtool_ops;
+
+	err = register_netdev(dev);
+	if (err) {
+		ugeth_err("%s: Cannot register net device, aborting.",
+			  dev->name);
+		free_netdev(dev);
+		return err;
+	}
+
+	ugeth->ug_info = ug_info;
+	ugeth->dev = dev;
+	memcpy(dev->dev_addr, ugeth_pdata->mac_addr, 6);
+
+	return 0;
+}
+
+static int ucc_geth_remove(struct device *device)
+{
+	struct net_device *dev = dev_get_drvdata(device);
+	struct ucc_geth_private *ugeth = netdev_priv(dev);
+
+	dev_set_drvdata(device, NULL);
+	ucc_geth_memclean(ugeth);
+	free_netdev(dev);
+
+	return 0;
+}
+
+/* Structure for a device driver */
+static struct device_driver ucc_geth_driver = {
+	.name = DRV_NAME,
+	.bus = &platform_bus_type,
+	.probe = ucc_geth_probe,
+	.remove = ucc_geth_remove,
+};
+
+static int __init ucc_geth_init(void)
+{
+	int i;
+	printk(KERN_INFO "ucc_geth: " DRV_DESC "\n");
+	for (i = 0; i < 8; i++)
+		memcpy(&(ugeth_info[i]), &ugeth_primary_info,
+		       sizeof(ugeth_primary_info));
+
+	return driver_register(&ucc_geth_driver);
+}
+
+static void __exit ucc_geth_exit(void)
+{
+	driver_unregister(&ucc_geth_driver);
+}
+
+module_init(ucc_geth_init);
+module_exit(ucc_geth_exit);
+
+MODULE_AUTHOR("Freescale Semiconductor, Inc");
+MODULE_DESCRIPTION(DRV_DESC);
+MODULE_LICENSE("GPL");
diff --git a/drivers/net/ucc_geth.h b/drivers/net/ucc_geth.h
new file mode 100644
index 000000000..005965f5d
--- /dev/null
+++ b/drivers/net/ucc_geth.h
@@ -0,0 +1,1339 @@
+/*
+ * Copyright (C) Freescale Semicondutor, Inc. 2006. All rights reserved.
+ *
+ * Author: Shlomi Gridish <gridish@freescale.com>
+ *
+ * Description:
+ * Internal header file for UCC Gigabit Ethernet unit routines.
+ *
+ * Changelog:
+ * Jun 28, 2006 Li Yang <LeoLi@freescale.com>
+ * - Rearrange code and style fixes
+ *
+ * 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 __UCC_GETH_H__
+#define __UCC_GETH_H__
+
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/fsl_devices.h>
+
+#include <asm/immap_qe.h>
+#include <asm/qe.h>
+
+#include <asm/ucc.h>
+#include <asm/ucc_fast.h>
+
+#define NUM_TX_QUEUES                   8
+#define NUM_RX_QUEUES                   8
+#define NUM_BDS_IN_PREFETCHED_BDS       4
+#define TX_IP_OFFSET_ENTRY_MAX          8
+#define NUM_OF_PADDRS                   4
+#define ENET_INIT_PARAM_MAX_ENTRIES_RX  9
+#define ENET_INIT_PARAM_MAX_ENTRIES_TX  8
+
+typedef struct ucc_mii_mng {
+	u32 miimcfg;		/* MII management configuration reg */
+	u32 miimcom;		/* MII management command reg */
+	u32 miimadd;		/* MII management address reg */
+	u32 miimcon;		/* MII management control reg */
+	u32 miimstat;		/* MII management status reg */
+	u32 miimind;		/* MII management indication reg */
+} __attribute__ ((packed)) ucc_mii_mng_t;
+
+typedef struct ucc_geth {
+	ucc_fast_t uccf;
+
+	u32 maccfg1;		/* mac configuration reg. 1 */
+	u32 maccfg2;		/* mac configuration reg. 2 */
+	u32 ipgifg;		/* interframe gap reg.  */
+	u32 hafdup;		/* half-duplex reg.  */
+	u8 res1[0x10];
+	ucc_mii_mng_t miimng;	/* MII management structure */
+	u32 ifctl;		/* interface control reg */
+	u32 ifstat;		/* interface statux reg */
+	u32 macstnaddr1;	/* mac station address part 1 reg */
+	u32 macstnaddr2;	/* mac station address part 2 reg */
+	u8 res2[0x8];
+	u32 uempr;		/* UCC Ethernet Mac parameter reg */
+	u32 utbipar;		/* UCC tbi address reg */
+	u16 uescr;		/* UCC Ethernet statistics control reg */
+	u8 res3[0x180 - 0x15A];
+	u32 tx64;		/* Total number of frames (including bad
+				   frames) transmitted that were exactly of the
+				   minimal length (64 for un tagged, 68 for
+				   tagged, or with length exactly equal to the
+				   parameter MINLength */
+	u32 tx127;		/* Total number of frames (including bad
+				   frames) transmitted that were between
+				   MINLength (Including FCS length==4) and 127
+				   octets */
+	u32 tx255;		/* Total number of frames (including bad
+				   frames) transmitted that were between 128
+				   (Including FCS length==4) and 255 octets */
+	u32 rx64;		/* Total number of frames received including
+				   bad frames that were exactly of the mninimal
+				   length (64 bytes) */
+	u32 rx127;		/* Total number of frames (including bad
+				   frames) received that were between MINLength
+				   (Including FCS length==4) and 127 octets */
+	u32 rx255;		/* Total number of frames (including bad
+				   frames) received that were between 128
+				   (Including FCS length==4) and 255 octets */
+	u32 txok;		/* Total number of octets residing in frames
+				   that where involved in succesfull
+				   transmission */
+	u16 txcf;		/* Total number of PAUSE control frames
+				   transmitted by this MAC */
+	u8 res4[0x2];
+	u32 tmca;		/* Total number of frames that were transmitted
+				   succesfully with the group address bit set
+				   that are not broadcast frames */
+	u32 tbca;		/* Total number of frames transmitted
+				   succesfully that had destination address
+				   field equal to the broadcast address */
+	u32 rxfok;		/* Total number of frames received OK */
+	u32 rxbok;		/* Total number of octets received OK */
+	u32 rbyt;		/* Total number of octets received including
+				   octets in bad frames. Must be implemented in
+				   HW because it includes octets in frames that
+				   never even reach the UCC */
+	u32 rmca;		/* Total number of frames that were received
+				   succesfully with the group address bit set
+				   that are not broadcast frames */
+	u32 rbca;		/* Total number of frames received succesfully
+				   that had destination address equal to the
+				   broadcast address */
+	u32 scar;		/* Statistics carry register */
+	u32 scam;		/* Statistics caryy mask register */
+	u8 res5[0x200 - 0x1c4];
+} __attribute__ ((packed)) ucc_geth_t;
+
+/* UCC GETH TEMODR Register */
+#define TEMODER_TX_RMON_STATISTICS_ENABLE       0x0100	/* enable Tx statistics
+							 */
+#define TEMODER_SCHEDULER_ENABLE                0x2000	/* enable scheduler */
+#define TEMODER_IP_CHECKSUM_GENERATE            0x0400	/* generate IPv4
+							   checksums */
+#define TEMODER_PERFORMANCE_OPTIMIZATION_MODE1  0x0200	/* enable performance
+							   optimization
+							   enhancement (mode1) */
+#define TEMODER_RMON_STATISTICS                 0x0100	/* enable tx statistics
+							 */
+#define TEMODER_NUM_OF_QUEUES_SHIFT             (15-15)	/* Number of queues <<
+							   shift */
+
+/* UCC GETH TEMODR Register */
+#define REMODER_RX_RMON_STATISTICS_ENABLE       0x00001000	/* enable Rx
+								   statistics */
+#define REMODER_RX_EXTENDED_FEATURES            0x80000000	/* enable
+								   extended
+								   features */
+#define REMODER_VLAN_OPERATION_TAGGED_SHIFT     (31-9 )	/* vlan operation
+							   tagged << shift */
+#define REMODER_VLAN_OPERATION_NON_TAGGED_SHIFT (31-10)	/* vlan operation non
+							   tagged << shift */
+#define REMODER_RX_QOS_MODE_SHIFT               (31-15)	/* rx QoS mode << shift
+							 */
+#define REMODER_RMON_STATISTICS                 0x00001000	/* enable rx
+								   statistics */
+#define REMODER_RX_EXTENDED_FILTERING           0x00000800	/* extended
+								   filtering
+								   vs.
+								   mpc82xx-like
+								   filtering */
+#define REMODER_NUM_OF_QUEUES_SHIFT             (31-23)	/* Number of queues <<
+							   shift */
+#define REMODER_DYNAMIC_MAX_FRAME_LENGTH        0x00000008	/* enable
+								   dynamic max
+								   frame length
+								 */
+#define REMODER_DYNAMIC_MIN_FRAME_LENGTH        0x00000004	/* enable
+								   dynamic min
+								   frame length
+								 */
+#define REMODER_IP_CHECKSUM_CHECK               0x00000002	/* check IPv4
+								   checksums */
+#define REMODER_IP_ADDRESS_ALIGNMENT            0x00000001	/* align ip
+								   address to
+								   4-byte
+								   boundary */
+
+/* UCC GETH Event Register */
+#define UCCE_MPD                                0x80000000	/* Magic packet
+								   detection */
+#define UCCE_SCAR                               0x40000000
+#define UCCE_GRA                                0x20000000	/* Tx graceful
+								   stop
+								   complete */
+#define UCCE_CBPR                               0x10000000
+#define UCCE_BSY                                0x08000000
+#define UCCE_RXC                                0x04000000
+#define UCCE_TXC                                0x02000000
+#define UCCE_TXE                                0x01000000
+#define UCCE_TXB7                               0x00800000
+#define UCCE_TXB6                               0x00400000
+#define UCCE_TXB5                               0x00200000
+#define UCCE_TXB4                               0x00100000
+#define UCCE_TXB3                               0x00080000
+#define UCCE_TXB2                               0x00040000
+#define UCCE_TXB1                               0x00020000
+#define UCCE_TXB0                               0x00010000
+#define UCCE_RXB7                               0x00008000
+#define UCCE_RXB6                               0x00004000
+#define UCCE_RXB5                               0x00002000
+#define UCCE_RXB4                               0x00001000
+#define UCCE_RXB3                               0x00000800
+#define UCCE_RXB2                               0x00000400
+#define UCCE_RXB1                               0x00000200
+#define UCCE_RXB0                               0x00000100
+#define UCCE_RXF7                               0x00000080
+#define UCCE_RXF6                               0x00000040
+#define UCCE_RXF5                               0x00000020
+#define UCCE_RXF4                               0x00000010
+#define UCCE_RXF3                               0x00000008
+#define UCCE_RXF2                               0x00000004
+#define UCCE_RXF1                               0x00000002
+#define UCCE_RXF0                               0x00000001
+
+#define UCCE_RXBF_SINGLE_MASK                   (UCCE_RXF0)
+#define UCCE_TXBF_SINGLE_MASK                   (UCCE_TXB0)
+
+#define UCCE_TXB         (UCCE_TXB7 | UCCE_TXB6 | UCCE_TXB5 | UCCE_TXB4 |\
+			UCCE_TXB3 | UCCE_TXB2 | UCCE_TXB1 | UCCE_TXB0)
+#define UCCE_RXB         (UCCE_RXB7 | UCCE_RXB6 | UCCE_RXB5 | UCCE_RXB4 |\
+			UCCE_RXB3 | UCCE_RXB2 | UCCE_RXB1 | UCCE_RXB0)
+#define UCCE_RXF         (UCCE_RXF7 | UCCE_RXF6 | UCCE_RXF5 | UCCE_RXF4 |\
+			UCCE_RXF3 | UCCE_RXF2 | UCCE_RXF1 | UCCE_RXF0)
+#define UCCE_OTHER       (UCCE_SCAR | UCCE_GRA  | UCCE_CBPR | UCCE_BSY  |\
+			UCCE_RXC  | UCCE_TXC  | UCCE_TXE)
+
+/* UCC GETH UPSMR (Protocol Specific Mode Register) */
+#define UPSMR_ECM                               0x04000000	/* Enable CAM
+								   Miss or
+								   Enable
+								   Filtering
+								   Miss */
+#define UPSMR_HSE                               0x02000000	/* Hardware
+								   Statistics
+								   Enable */
+#define UPSMR_PRO                               0x00400000	/* Promiscuous*/
+#define UPSMR_CAP                               0x00200000	/* CAM polarity
+								 */
+#define UPSMR_RSH                               0x00100000	/* Receive
+								   Short Frames
+								 */
+#define UPSMR_RPM                               0x00080000	/* Reduced Pin
+								   Mode
+								   interfaces */
+#define UPSMR_R10M                              0x00040000	/* RGMII/RMII
+								   10 Mode */
+#define UPSMR_RLPB                              0x00020000	/* RMII
+								   Loopback
+								   Mode */
+#define UPSMR_TBIM                              0x00010000	/* Ten-bit
+								   Interface
+								   Mode */
+#define UPSMR_RMM                               0x00001000	/* RMII/RGMII
+								   Mode */
+#define UPSMR_CAM                               0x00000400	/* CAM Address
+								   Matching */
+#define UPSMR_BRO                               0x00000200	/* Broadcast
+								   Address */
+#define UPSMR_RES1                              0x00002000	/* Reserved
+								   feild - must
+								   be 1 */
+
+/* UCC GETH MACCFG1 (MAC Configuration 1 Register) */
+#define MACCFG1_FLOW_RX                         0x00000020	/* Flow Control
+								   Rx */
+#define MACCFG1_FLOW_TX                         0x00000010	/* Flow Control
+								   Tx */
+#define MACCFG1_ENABLE_SYNCHED_RX               0x00000008	/* Rx Enable
+								   synchronized
+								   to Rx stream
+								 */
+#define MACCFG1_ENABLE_RX                       0x00000004	/* Enable Rx */
+#define MACCFG1_ENABLE_SYNCHED_TX               0x00000002	/* Tx Enable
+								   synchronized
+								   to Tx stream
+								 */
+#define MACCFG1_ENABLE_TX                       0x00000001	/* Enable Tx */
+
+/* UCC GETH MACCFG2 (MAC Configuration 2 Register) */
+#define MACCFG2_PREL_SHIFT                      (31 - 19)	/* Preamble
+								   Length <<
+								   shift */
+#define MACCFG2_PREL_MASK                       0x0000f000	/* Preamble
+								   Length mask */
+#define MACCFG2_SRP                             0x00000080	/* Soft Receive
+								   Preamble */
+#define MACCFG2_STP                             0x00000040	/* Soft
+								   Transmit
+								   Preamble */
+#define MACCFG2_RESERVED_1                      0x00000020	/* Reserved -
+								   must be set
+								   to 1 */
+#define MACCFG2_LC                              0x00000010	/* Length Check
+								 */
+#define MACCFG2_MPE                             0x00000008	/* Magic packet
+								   detect */
+#define MACCFG2_FDX                             0x00000001	/* Full Duplex */
+#define MACCFG2_FDX_MASK                        0x00000001	/* Full Duplex
+								   mask */
+#define MACCFG2_PAD_CRC                         0x00000004
+#define MACCFG2_CRC_EN                          0x00000002
+#define MACCFG2_PAD_AND_CRC_MODE_NONE           0x00000000	/* Neither
+								   Padding
+								   short frames
+								   nor CRC */
+#define MACCFG2_PAD_AND_CRC_MODE_CRC_ONLY       0x00000002	/* Append CRC
+								   only */
+#define MACCFG2_PAD_AND_CRC_MODE_PAD_AND_CRC    0x00000004
+#define MACCFG2_INTERFACE_MODE_NIBBLE           0x00000100	/* nibble mode
+								   (MII/RMII/RGMII
+								   10/100bps) */
+#define MACCFG2_INTERFACE_MODE_BYTE             0x00000200	/* byte mode
+								   (GMII/TBI/RTB/RGMII
+								   1000bps ) */
+#define MACCFG2_INTERFACE_MODE_MASK             0x00000300	/* mask
+								   covering all
+								   relevant
+								   bits */
+
+/* UCC GETH IPGIFG (Inter-frame Gap / Inter-Frame Gap Register) */
+#define IPGIFG_NON_BACK_TO_BACK_IFG_PART1_SHIFT (31 -  7)	/* Non
+								   back-to-back
+								   inter frame
+								   gap part 1.
+								   << shift */
+#define IPGIFG_NON_BACK_TO_BACK_IFG_PART2_SHIFT (31 - 15)	/* Non
+								   back-to-back
+								   inter frame
+								   gap part 2.
+								   << shift */
+#define IPGIFG_MINIMUM_IFG_ENFORCEMENT_SHIFT    (31 - 23)	/* Mimimum IFG
+								   Enforcement
+								   << shift */
+#define IPGIFG_BACK_TO_BACK_IFG_SHIFT           (31 - 31)	/* back-to-back
+								   inter frame
+								   gap << shift
+								 */
+#define IPGIFG_NON_BACK_TO_BACK_IFG_PART1_MAX   127	/* Non back-to-back
+							   inter frame gap part
+							   1. max val */
+#define IPGIFG_NON_BACK_TO_BACK_IFG_PART2_MAX   127	/* Non back-to-back
+							   inter frame gap part
+							   2. max val */
+#define IPGIFG_MINIMUM_IFG_ENFORCEMENT_MAX      255	/* Mimimum IFG
+							   Enforcement max val */
+#define IPGIFG_BACK_TO_BACK_IFG_MAX             127	/* back-to-back inter
+							   frame gap max val */
+#define IPGIFG_NBTB_CS_IPG_MASK                 0x7F000000
+#define IPGIFG_NBTB_IPG_MASK                    0x007F0000
+#define IPGIFG_MIN_IFG_MASK                     0x0000FF00
+#define IPGIFG_BTB_IPG_MASK                     0x0000007F
+
+/* UCC GETH HAFDUP (Half Duplex Register) */
+#define HALFDUP_ALT_BEB_TRUNCATION_SHIFT        (31 - 11)	/* Alternate
+								   Binary
+								   Exponential
+								   Backoff
+								   Truncation
+								   << shift */
+#define HALFDUP_ALT_BEB_TRUNCATION_MAX          0xf	/* Alternate Binary
+							   Exponential Backoff
+							   Truncation max val */
+#define HALFDUP_ALT_BEB                         0x00080000	/* Alternate
+								   Binary
+								   Exponential
+								   Backoff */
+#define HALFDUP_BACK_PRESSURE_NO_BACKOFF        0x00040000	/* Back
+								   pressure no
+								   backoff */
+#define HALFDUP_NO_BACKOFF                      0x00020000	/* No Backoff */
+#define HALFDUP_EXCESSIVE_DEFER                 0x00010000	/* Excessive
+								   Defer */
+#define HALFDUP_MAX_RETRANSMISSION_SHIFT        (31 - 19)	/* Maximum
+								   Retransmission
+								   << shift */
+#define HALFDUP_MAX_RETRANSMISSION_MAX          0xf	/* Maximum
+							   Retransmission max
+							   val */
+#define HALFDUP_COLLISION_WINDOW_SHIFT          (31 - 31)	/* Collision
+								   Window <<
+								   shift */
+#define HALFDUP_COLLISION_WINDOW_MAX            0x3f	/* Collision Window max
+							   val */
+#define HALFDUP_ALT_BEB_TR_MASK                 0x00F00000
+#define HALFDUP_RETRANS_MASK                    0x0000F000
+#define HALFDUP_COL_WINDOW_MASK                 0x0000003F
+
+/* UCC GETH UCCS (Ethernet Status Register) */
+#define UCCS_BPR                                0x02	/* Back pressure (in
+							   half duplex mode) */
+#define UCCS_PAU                                0x02	/* Pause state (in full
+							   duplex mode) */
+#define UCCS_MPD                                0x01	/* Magic Packet
+							   Detected */
+
+/* UCC GETH MIIMCFG (MII Management Configuration Register) */
+#define MIIMCFG_RESET_MANAGEMENT                0x80000000	/* Reset
+								   management */
+#define MIIMCFG_NO_PREAMBLE                     0x00000010	/* Preamble
+								   suppress */
+#define MIIMCFG_CLOCK_DIVIDE_SHIFT              (31 - 31)	/* clock divide
+								   << shift */
+#define MIIMCFG_CLOCK_DIVIDE_MAX                0xf	/* clock divide max val
+							 */
+#define MIIMCFG_MANAGEMENT_CLOCK_DIVIDE_BY_2    0x00000000	/* divide by 2 */
+#define MIIMCFG_MANAGEMENT_CLOCK_DIVIDE_BY_4    0x00000001	/* divide by 4 */
+#define MIIMCFG_MANAGEMENT_CLOCK_DIVIDE_BY_6    0x00000002	/* divide by 6 */
+#define MIIMCFG_MANAGEMENT_CLOCK_DIVIDE_BY_8    0x00000003	/* divide by 8 */
+#define MIIMCFG_MANAGEMENT_CLOCK_DIVIDE_BY_10   0x00000004	/* divide by 10
+								 */
+#define MIIMCFG_MANAGEMENT_CLOCK_DIVIDE_BY_14   0x00000005	/* divide by 14
+								 */
+#define MIIMCFG_MANAGEMENT_CLOCK_DIVIDE_BY_16   0x00000008	/* divide by 16
+								 */
+#define MIIMCFG_MANAGEMENT_CLOCK_DIVIDE_BY_20   0x00000006	/* divide by 20
+								 */
+#define MIIMCFG_MANAGEMENT_CLOCK_DIVIDE_BY_28   0x00000007	/* divide by 28
+								 */
+#define MIIMCFG_MANAGEMENT_CLOCK_DIVIDE_BY_32   0x00000009	/* divide by 32
+								 */
+#define MIIMCFG_MANAGEMENT_CLOCK_DIVIDE_BY_48   0x0000000a	/* divide by 48
+								 */
+#define MIIMCFG_MANAGEMENT_CLOCK_DIVIDE_BY_64   0x0000000b	/* divide by 64
+								 */
+#define MIIMCFG_MANAGEMENT_CLOCK_DIVIDE_BY_80   0x0000000c	/* divide by 80
+								 */
+#define MIIMCFG_MANAGEMENT_CLOCK_DIVIDE_BY_112  0x0000000d	/* divide by
+								   112 */
+#define MIIMCFG_MANAGEMENT_CLOCK_DIVIDE_BY_160  0x0000000e	/* divide by
+								   160 */
+#define MIIMCFG_MANAGEMENT_CLOCK_DIVIDE_BY_224  0x0000000f	/* divide by
+								   224 */
+
+/* UCC GETH MIIMCOM (MII Management Command Register) */
+#define MIIMCOM_SCAN_CYCLE                      0x00000002	/* Scan cycle */
+#define MIIMCOM_READ_CYCLE                      0x00000001	/* Read cycle */
+
+/* UCC GETH MIIMADD (MII Management Address Register) */
+#define MIIMADD_PHY_ADDRESS_SHIFT               (31 - 23)	/* PHY Address
+								   << shift */
+#define MIIMADD_PHY_REGISTER_SHIFT              (31 - 31)	/* PHY Register
+								   << shift */
+
+/* UCC GETH MIIMCON (MII Management Control Register) */
+#define MIIMCON_PHY_CONTROL_SHIFT               (31 - 31)	/* PHY Control
+								   << shift */
+#define MIIMCON_PHY_STATUS_SHIFT                (31 - 31)	/* PHY Status
+								   << shift */
+
+/* UCC GETH MIIMIND (MII Management Indicator Register) */
+#define MIIMIND_NOT_VALID                       0x00000004	/* Not valid */
+#define MIIMIND_SCAN                            0x00000002	/* Scan in
+								   progress */
+#define MIIMIND_BUSY                            0x00000001
+
+/* UCC GETH IFSTAT (Interface Status Register) */
+#define IFSTAT_EXCESS_DEFER                     0x00000200	/* Excessive
+								   transmission
+								   defer */
+
+/* UCC GETH MACSTNADDR1 (Station Address Part 1 Register) */
+#define MACSTNADDR1_OCTET_6_SHIFT               (31 -  7)	/* Station
+								   address 6th
+								   octet <<
+								   shift */
+#define MACSTNADDR1_OCTET_5_SHIFT               (31 - 15)	/* Station
+								   address 5th
+								   octet <<
+								   shift */
+#define MACSTNADDR1_OCTET_4_SHIFT               (31 - 23)	/* Station
+								   address 4th
+								   octet <<
+								   shift */
+#define MACSTNADDR1_OCTET_3_SHIFT               (31 - 31)	/* Station
+								   address 3rd
+								   octet <<
+								   shift */
+
+/* UCC GETH MACSTNADDR2 (Station Address Part 2 Register) */
+#define MACSTNADDR2_OCTET_2_SHIFT               (31 -  7)	/* Station
+								   address 2nd
+								   octet <<
+								   shift */
+#define MACSTNADDR2_OCTET_1_SHIFT               (31 - 15)	/* Station
+								   address 1st
+								   octet <<
+								   shift */
+
+/* UCC GETH UEMPR (Ethernet Mac Parameter Register) */
+#define UEMPR_PAUSE_TIME_VALUE_SHIFT            (31 - 15)	/* Pause time
+								   value <<
+								   shift */
+#define UEMPR_EXTENDED_PAUSE_TIME_VALUE_SHIFT   (31 - 31)	/* Extended
+								   pause time
+								   value <<
+								   shift */
+
+/* UCC GETH UTBIPAR (Ten Bit Interface Physical Address Register) */
+#define UTBIPAR_PHY_ADDRESS_SHIFT               (31 - 31)	/* Phy address
+								   << shift */
+#define UTBIPAR_PHY_ADDRESS_MASK                0x0000001f	/* Phy address
+								   mask */
+
+/* UCC GETH UESCR (Ethernet Statistics Control Register) */
+#define UESCR_AUTOZ                             0x8000	/* Automatically zero
+							   addressed
+							   statistical counter
+							   values */
+#define UESCR_CLRCNT                            0x4000	/* Clear all statistics
+							   counters */
+#define UESCR_MAXCOV_SHIFT                      (15 -  7)	/* Max
+								   Coalescing
+								   Value <<
+								   shift */
+#define UESCR_SCOV_SHIFT                        (15 - 15)	/* Status
+								   Coalescing
+								   Value <<
+								   shift */
+
+/* UCC GETH UDSR (Data Synchronization Register) */
+#define UDSR_MAGIC                              0x067E
+
+typedef struct ucc_geth_thread_data_tx {
+	u8 res0[104];
+} __attribute__ ((packed)) ucc_geth_thread_data_tx_t;
+
+typedef struct ucc_geth_thread_data_rx {
+	u8 res0[40];
+} __attribute__ ((packed)) ucc_geth_thread_data_rx_t;
+
+/* Send Queue Queue-Descriptor */
+typedef struct ucc_geth_send_queue_qd {
+	u32 bd_ring_base;	/* pointer to BD ring base address */
+	u8 res0[0x8];
+	u32 last_bd_completed_address;/* initialize to last entry in BD ring */
+	u8 res1[0x30];
+} __attribute__ ((packed)) ucc_geth_send_queue_qd_t;
+
+typedef struct ucc_geth_send_queue_mem_region {
+	ucc_geth_send_queue_qd_t sqqd[NUM_TX_QUEUES];
+} __attribute__ ((packed)) ucc_geth_send_queue_mem_region_t;
+
+typedef struct ucc_geth_thread_tx_pram {
+	u8 res0[64];
+} __attribute__ ((packed)) ucc_geth_thread_tx_pram_t;
+
+typedef struct ucc_geth_thread_rx_pram {
+	u8 res0[128];
+} __attribute__ ((packed)) ucc_geth_thread_rx_pram_t;
+
+#define THREAD_RX_PRAM_ADDITIONAL_FOR_EXTENDED_FILTERING        64
+#define THREAD_RX_PRAM_ADDITIONAL_FOR_EXTENDED_FILTERING_8      64
+#define THREAD_RX_PRAM_ADDITIONAL_FOR_EXTENDED_FILTERING_16     96
+
+typedef struct ucc_geth_scheduler {
+	u16 cpucount0;		/* CPU packet counter */
+	u16 cpucount1;		/* CPU packet counter */
+	u16 cecount0;		/* QE packet counter */
+	u16 cecount1;		/* QE packet counter */
+	u16 cpucount2;		/* CPU packet counter */
+	u16 cpucount3;		/* CPU packet counter */
+	u16 cecount2;		/* QE packet counter */
+	u16 cecount3;		/* QE packet counter */
+	u16 cpucount4;		/* CPU packet counter */
+	u16 cpucount5;		/* CPU packet counter */
+	u16 cecount4;		/* QE packet counter */
+	u16 cecount5;		/* QE packet counter */
+	u16 cpucount6;		/* CPU packet counter */
+	u16 cpucount7;		/* CPU packet counter */
+	u16 cecount6;		/* QE packet counter */
+	u16 cecount7;		/* QE packet counter */
+	u32 weightstatus[NUM_TX_QUEUES];	/* accumulated weight factor */
+	u32 rtsrshadow;		/* temporary variable handled by QE */
+	u32 time;		/* temporary variable handled by QE */
+	u32 ttl;		/* temporary variable handled by QE */
+	u32 mblinterval;	/* max burst length interval */
+	u16 nortsrbytetime;	/* normalized value of byte time in tsr units */
+	u8 fracsiz;		/* radix 2 log value of denom. of
+				   NorTSRByteTime */
+	u8 res0[1];
+	u8 strictpriorityq;	/* Strict Priority Mask register */
+	u8 txasap;		/* Transmit ASAP register */
+	u8 extrabw;		/* Extra BandWidth register */
+	u8 oldwfqmask;		/* temporary variable handled by QE */
+	u8 weightfactor[NUM_TX_QUEUES];
+				      /**< weight factor for queues   */
+	u32 minw;		/* temporary variable handled by QE */
+	u8 res1[0x70 - 0x64];
+} __attribute__ ((packed)) ucc_geth_scheduler_t;
+
+typedef struct ucc_geth_tx_firmware_statistics_pram {
+	u32 sicoltx;		/* single collision */
+	u32 mulcoltx;		/* multiple collision */
+	u32 latecoltxfr;	/* late collision */
+	u32 frabortduecol;	/* frames aborted due to transmit collision */
+	u32 frlostinmactxer;	/* frames lost due to internal MAC error
+				   transmission that are not counted on any
+				   other counter */
+	u32 carriersenseertx;	/* carrier sense error */
+	u32 frtxok;		/* frames transmitted OK */
+	u32 txfrexcessivedefer;	/* frames with defferal time greater than
+				   specified threshold */
+	u32 txpkts256;		/* total packets (including bad) between 256
+				   and 511 octets */
+	u32 txpkts512;		/* total packets (including bad) between 512
+				   and 1023 octets */
+	u32 txpkts1024;		/* total packets (including bad) between 1024
+				   and 1518 octets */
+	u32 txpktsjumbo;	/* total packets (including bad) between 1024
+				   and MAXLength octets */
+} __attribute__ ((packed)) ucc_geth_tx_firmware_statistics_pram_t;
+
+typedef struct ucc_geth_rx_firmware_statistics_pram {
+	u32 frrxfcser;		/* frames with crc error */
+	u32 fraligner;		/* frames with alignment error */
+	u32 inrangelenrxer;	/* in range length error */
+	u32 outrangelenrxer;	/* out of range length error */
+	u32 frtoolong;		/* frame too long */
+	u32 runt;		/* runt */
+	u32 verylongevent;	/* very long event */
+	u32 symbolerror;	/* symbol error */
+	u32 dropbsy;		/* drop because of BD not ready */
+	u8 res0[0x8];
+	u32 mismatchdrop;	/* drop because of MAC filtering (e.g. address
+				   or type mismatch) */
+	u32 underpkts;		/* total frames less than 64 octets */
+	u32 pkts256;		/* total frames (including bad) between 256 and
+				   511 octets */
+	u32 pkts512;		/* total frames (including bad) between 512 and
+				   1023 octets */
+	u32 pkts1024;		/* total frames (including bad) between 1024
+				   and 1518 octets */
+	u32 pktsjumbo;		/* total frames (including bad) between 1024
+				   and MAXLength octets */
+	u32 frlossinmacer;	/* frames lost because of internal MAC error
+				   that is not counted in any other counter */
+	u32 pausefr;		/* pause frames */
+	u8 res1[0x4];
+	u32 removevlan;		/* total frames that had their VLAN tag removed
+				 */
+	u32 replacevlan;	/* total frames that had their VLAN tag
+				   replaced */
+	u32 insertvlan;		/* total frames that had their VLAN tag
+				   inserted */
+} __attribute__ ((packed)) ucc_geth_rx_firmware_statistics_pram_t;
+
+typedef struct ucc_geth_rx_interrupt_coalescing_entry {
+	u32 interruptcoalescingmaxvalue;	/* interrupt coalescing max
+						   value */
+	u32 interruptcoalescingcounter;	/* interrupt coalescing counter,
+					   initialize to
+					   interruptcoalescingmaxvalue */
+} __attribute__ ((packed)) ucc_geth_rx_interrupt_coalescing_entry_t;
+
+typedef struct ucc_geth_rx_interrupt_coalescing_table {
+	ucc_geth_rx_interrupt_coalescing_entry_t coalescingentry[NUM_RX_QUEUES];
+				       /**< interrupt coalescing entry */
+} __attribute__ ((packed)) ucc_geth_rx_interrupt_coalescing_table_t;
+
+typedef struct ucc_geth_rx_prefetched_bds {
+	qe_bd_t bd[NUM_BDS_IN_PREFETCHED_BDS];	/* prefetched bd */
+} __attribute__ ((packed)) ucc_geth_rx_prefetched_bds_t;
+
+typedef struct ucc_geth_rx_bd_queues_entry {
+	u32 bdbaseptr;		/* BD base pointer */
+	u32 bdptr;		/* BD pointer */
+	u32 externalbdbaseptr;	/* external BD base pointer */
+	u32 externalbdptr;	/* external BD pointer */
+} __attribute__ ((packed)) ucc_geth_rx_bd_queues_entry_t;
+
+typedef struct ucc_geth_tx_global_pram {
+	u16 temoder;
+	u8 res0[0x38 - 0x02];
+	u32 sqptr;		/* a base pointer to send queue memory region */
+	u32 schedulerbasepointer;	/* a base pointer to scheduler memory
+					   region */
+	u32 txrmonbaseptr;	/* base pointer to Tx RMON statistics counter */
+	u32 tstate;		/* tx internal state. High byte contains
+				   function code */
+	u8 iphoffset[TX_IP_OFFSET_ENTRY_MAX];
+	u32 vtagtable[0x8];	/* 8 4-byte VLAN tags */
+	u32 tqptr;		/* a base pointer to the Tx Queues Memory
+				   Region */
+	u8 res2[0x80 - 0x74];
+} __attribute__ ((packed)) ucc_geth_tx_global_pram_t;
+
+/* structure representing Extended Filtering Global Parameters in PRAM */
+typedef struct ucc_geth_exf_global_pram {
+	u32 l2pcdptr;		/* individual address filter, high */
+	u8 res0[0x10 - 0x04];
+} __attribute__ ((packed)) ucc_geth_exf_global_pram_t;
+
+typedef struct ucc_geth_rx_global_pram {
+	u32 remoder;		/* ethernet mode reg. */
+	u32 rqptr;		/* base pointer to the Rx Queues Memory Region*/
+	u32 res0[0x1];
+	u8 res1[0x20 - 0xC];
+	u16 typeorlen;		/* cutoff point less than which, type/len field
+				   is considered length */
+	u8 res2[0x1];
+	u8 rxgstpack;		/* acknowledgement on GRACEFUL STOP RX command*/
+	u32 rxrmonbaseptr;	/* base pointer to Rx RMON statistics counter */
+	u8 res3[0x30 - 0x28];
+	u32 intcoalescingptr;	/* Interrupt coalescing table pointer */
+	u8 res4[0x36 - 0x34];
+	u8 rstate;		/* rx internal state. High byte contains
+				   function code */
+	u8 res5[0x46 - 0x37];
+	u16 mrblr;		/* max receive buffer length reg. */
+	u32 rbdqptr;		/* base pointer to RxBD parameter table
+				   description */
+	u16 mflr;		/* max frame length reg. */
+	u16 minflr;		/* min frame length reg. */
+	u16 maxd1;		/* max dma1 length reg. */
+	u16 maxd2;		/* max dma2 length reg. */
+	u32 ecamptr;		/* external CAM address */
+	u32 l2qt;		/* VLAN priority mapping table. */
+	u32 l3qt[0x8];		/* IP priority mapping table. */
+	u16 vlantype;		/* vlan type */
+	u16 vlantci;		/* default vlan tci */
+	u8 addressfiltering[64];	/* address filtering data structure */
+	u32 exfGlobalParam;	/* base address for extended filtering global
+				   parameters */
+	u8 res6[0x100 - 0xC4];	/* Initialize to zero */
+} __attribute__ ((packed)) ucc_geth_rx_global_pram_t;
+
+#define GRACEFUL_STOP_ACKNOWLEDGE_RX            0x01
+
+/* structure representing InitEnet command */
+typedef struct ucc_geth_init_pram {
+	u8 resinit1;
+	u8 resinit2;
+	u8 resinit3;
+	u8 resinit4;
+	u16 resinit5;
+	u8 res1[0x1];
+	u8 largestexternallookupkeysize;
+	u32 rgftgfrxglobal;
+	u32 rxthread[ENET_INIT_PARAM_MAX_ENTRIES_RX];	/* rx threads */
+	u8 res2[0x38 - 0x30];
+	u32 txglobal;		/* tx global */
+	u32 txthread[ENET_INIT_PARAM_MAX_ENTRIES_TX];	/* tx threads */
+	u8 res3[0x1];
+} __attribute__ ((packed)) ucc_geth_init_pram_t;
+
+#define ENET_INIT_PARAM_RGF_SHIFT               (32 - 4)
+#define ENET_INIT_PARAM_TGF_SHIFT               (32 - 8)
+
+#define ENET_INIT_PARAM_RISC_MASK               0x0000003f
+#define ENET_INIT_PARAM_PTR_MASK                0x00ffffc0
+#define ENET_INIT_PARAM_SNUM_MASK               0xff000000
+#define ENET_INIT_PARAM_SNUM_SHIFT              24
+
+#define ENET_INIT_PARAM_MAGIC_RES_INIT1         0x06
+#define ENET_INIT_PARAM_MAGIC_RES_INIT2         0x30
+#define ENET_INIT_PARAM_MAGIC_RES_INIT3         0xff
+#define ENET_INIT_PARAM_MAGIC_RES_INIT4         0x00
+#define ENET_INIT_PARAM_MAGIC_RES_INIT5         0x0400
+
+/* structure representing 82xx Address Filtering Enet Address in PRAM */
+typedef struct ucc_geth_82xx_enet_address {
+	u8 res1[0x2];
+	u16 h;			/* address (MSB) */
+	u16 m;			/* address */
+	u16 l;			/* address (LSB) */
+} __attribute__ ((packed)) ucc_geth_82xx_enet_address_t;
+
+/* structure representing 82xx Address Filtering PRAM */
+typedef struct ucc_geth_82xx_address_filtering_pram {
+	u32 iaddr_h;		/* individual address filter, high */
+	u32 iaddr_l;		/* individual address filter, low */
+	u32 gaddr_h;		/* group address filter, high */
+	u32 gaddr_l;		/* group address filter, low */
+	ucc_geth_82xx_enet_address_t taddr;
+	ucc_geth_82xx_enet_address_t paddr[NUM_OF_PADDRS];
+	u8 res0[0x40 - 0x38];
+} __attribute__ ((packed)) ucc_geth_82xx_address_filtering_pram_t;
+
+/* GETH Tx firmware statistics structure, used when calling
+   UCC_GETH_GetStatistics. */
+typedef struct ucc_geth_tx_firmware_statistics {
+	u32 sicoltx;		/* single collision */
+	u32 mulcoltx;		/* multiple collision */
+	u32 latecoltxfr;	/* late collision */
+	u32 frabortduecol;	/* frames aborted due to transmit collision */
+	u32 frlostinmactxer;	/* frames lost due to internal MAC error
+				   transmission that are not counted on any
+				   other counter */
+	u32 carriersenseertx;	/* carrier sense error */
+	u32 frtxok;		/* frames transmitted OK */
+	u32 txfrexcessivedefer;	/* frames with defferal time greater than
+				   specified threshold */
+	u32 txpkts256;		/* total packets (including bad) between 256
+				   and 511 octets */
+	u32 txpkts512;		/* total packets (including bad) between 512
+				   and 1023 octets */
+	u32 txpkts1024;		/* total packets (including bad) between 1024
+				   and 1518 octets */
+	u32 txpktsjumbo;	/* total packets (including bad) between 1024
+				   and MAXLength octets */
+} __attribute__ ((packed)) ucc_geth_tx_firmware_statistics_t;
+
+/* GETH Rx firmware statistics structure, used when calling
+   UCC_GETH_GetStatistics. */
+typedef struct ucc_geth_rx_firmware_statistics {
+	u32 frrxfcser;		/* frames with crc error */
+	u32 fraligner;		/* frames with alignment error */
+	u32 inrangelenrxer;	/* in range length error */
+	u32 outrangelenrxer;	/* out of range length error */
+	u32 frtoolong;		/* frame too long */
+	u32 runt;		/* runt */
+	u32 verylongevent;	/* very long event */
+	u32 symbolerror;	/* symbol error */
+	u32 dropbsy;		/* drop because of BD not ready */
+	u8 res0[0x8];
+	u32 mismatchdrop;	/* drop because of MAC filtering (e.g. address
+				   or type mismatch) */
+	u32 underpkts;		/* total frames less than 64 octets */
+	u32 pkts256;		/* total frames (including bad) between 256 and
+				   511 octets */
+	u32 pkts512;		/* total frames (including bad) between 512 and
+				   1023 octets */
+	u32 pkts1024;		/* total frames (including bad) between 1024
+				   and 1518 octets */
+	u32 pktsjumbo;		/* total frames (including bad) between 1024
+				   and MAXLength octets */
+	u32 frlossinmacer;	/* frames lost because of internal MAC error
+				   that is not counted in any other counter */
+	u32 pausefr;		/* pause frames */
+	u8 res1[0x4];
+	u32 removevlan;		/* total frames that had their VLAN tag removed
+				 */
+	u32 replacevlan;	/* total frames that had their VLAN tag
+				   replaced */
+	u32 insertvlan;		/* total frames that had their VLAN tag
+				   inserted */
+} __attribute__ ((packed)) ucc_geth_rx_firmware_statistics_t;
+
+/* GETH hardware statistics structure, used when calling
+   UCC_GETH_GetStatistics. */
+typedef struct ucc_geth_hardware_statistics {
+	u32 tx64;		/* Total number of frames (including bad
+				   frames) transmitted that were exactly of the
+				   minimal length (64 for un tagged, 68 for
+				   tagged, or with length exactly equal to the
+				   parameter MINLength */
+	u32 tx127;		/* Total number of frames (including bad
+				   frames) transmitted that were between
+				   MINLength (Including FCS length==4) and 127
+				   octets */
+	u32 tx255;		/* Total number of frames (including bad
+				   frames) transmitted that were between 128
+				   (Including FCS length==4) and 255 octets */
+	u32 rx64;		/* Total number of frames received including
+				   bad frames that were exactly of the mninimal
+				   length (64 bytes) */
+	u32 rx127;		/* Total number of frames (including bad
+				   frames) received that were between MINLength
+				   (Including FCS length==4) and 127 octets */
+	u32 rx255;		/* Total number of frames (including bad
+				   frames) received that were between 128
+				   (Including FCS length==4) and 255 octets */
+	u32 txok;		/* Total number of octets residing in frames
+				   that where involved in succesfull
+				   transmission */
+	u16 txcf;		/* Total number of PAUSE control frames
+				   transmitted by this MAC */
+	u32 tmca;		/* Total number of frames that were transmitted
+				   succesfully with the group address bit set
+				   that are not broadcast frames */
+	u32 tbca;		/* Total number of frames transmitted
+				   succesfully that had destination address
+				   field equal to the broadcast address */
+	u32 rxfok;		/* Total number of frames received OK */
+	u32 rxbok;		/* Total number of octets received OK */
+	u32 rbyt;		/* Total number of octets received including
+				   octets in bad frames. Must be implemented in
+				   HW because it includes octets in frames that
+				   never even reach the UCC */
+	u32 rmca;		/* Total number of frames that were received
+				   succesfully with the group address bit set
+				   that are not broadcast frames */
+	u32 rbca;		/* Total number of frames received succesfully
+				   that had destination address equal to the
+				   broadcast address */
+} __attribute__ ((packed)) ucc_geth_hardware_statistics_t;
+
+/* UCC GETH Tx errors returned via TxConf callback */
+#define TX_ERRORS_DEF      0x0200
+#define TX_ERRORS_EXDEF    0x0100
+#define TX_ERRORS_LC       0x0080
+#define TX_ERRORS_RL       0x0040
+#define TX_ERRORS_RC_MASK  0x003C
+#define TX_ERRORS_RC_SHIFT 2
+#define TX_ERRORS_UN       0x0002
+#define TX_ERRORS_CSL      0x0001
+
+/* UCC GETH Rx errors returned via RxStore callback */
+#define RX_ERRORS_CMR      0x0200
+#define RX_ERRORS_M        0x0100
+#define RX_ERRORS_BC       0x0080
+#define RX_ERRORS_MC       0x0040
+
+/* Transmit BD. These are in addition to values defined in uccf. */
+#define T_VID      0x003c0000	/* insert VLAN id index mask. */
+#define T_DEF      (((u32) TX_ERRORS_DEF     ) << 16)
+#define T_EXDEF    (((u32) TX_ERRORS_EXDEF   ) << 16)
+#define T_LC       (((u32) TX_ERRORS_LC      ) << 16)
+#define T_RL       (((u32) TX_ERRORS_RL      ) << 16)
+#define T_RC_MASK  (((u32) TX_ERRORS_RC_MASK ) << 16)
+#define T_UN       (((u32) TX_ERRORS_UN      ) << 16)
+#define T_CSL      (((u32) TX_ERRORS_CSL     ) << 16)
+#define T_ERRORS_REPORT  (T_DEF | T_EXDEF | T_LC | T_RL | T_RC_MASK \
+		| T_UN | T_CSL)	/* transmit errors to report */
+
+/* Receive BD. These are in addition to values defined in uccf. */
+#define R_LG    0x00200000	/* Frame length violation.  */
+#define R_NO    0x00100000	/* Non-octet aligned frame.  */
+#define R_SH    0x00080000	/* Short frame.  */
+#define R_CR    0x00040000	/* CRC error.  */
+#define R_OV    0x00020000	/* Overrun.  */
+#define R_IPCH  0x00010000	/* IP checksum check failed. */
+#define R_CMR   (((u32) RX_ERRORS_CMR  ) << 16)
+#define R_M     (((u32) RX_ERRORS_M    ) << 16)
+#define R_BC    (((u32) RX_ERRORS_BC   ) << 16)
+#define R_MC    (((u32) RX_ERRORS_MC   ) << 16)
+#define R_ERRORS_REPORT (R_CMR | R_M | R_BC | R_MC)	/* receive errors to
+							   report */
+#define R_ERRORS_FATAL  (R_LG  | R_NO | R_SH | R_CR | \
+		R_OV | R_IPCH)	/* receive errors to discard */
+
+/* Alignments */
+#define UCC_GETH_RX_GLOBAL_PRAM_ALIGNMENT	256
+#define UCC_GETH_TX_GLOBAL_PRAM_ALIGNMENT       128
+#define UCC_GETH_THREAD_RX_PRAM_ALIGNMENT       128
+#define UCC_GETH_THREAD_TX_PRAM_ALIGNMENT       64
+#define UCC_GETH_THREAD_DATA_ALIGNMENT          256	/* spec gives values
+							   based on num of
+							   threads, but always
+							   using the maximum is
+							   easier */
+#define UCC_GETH_SEND_QUEUE_QUEUE_DESCRIPTOR_ALIGNMENT	32
+#define UCC_GETH_SCHEDULER_ALIGNMENT		4	/* This is a guess */
+#define UCC_GETH_TX_STATISTICS_ALIGNMENT	4	/* This is a guess */
+#define UCC_GETH_RX_STATISTICS_ALIGNMENT	4	/* This is a guess */
+#define UCC_GETH_RX_INTERRUPT_COALESCING_ALIGNMENT	4	/* This is a
+								   guess */
+#define UCC_GETH_RX_BD_QUEUES_ALIGNMENT		8	/* This is a guess */
+#define UCC_GETH_RX_PREFETCHED_BDS_ALIGNMENT	128	/* This is a guess */
+#define UCC_GETH_RX_EXTENDED_FILTERING_GLOBAL_PARAMETERS_ALIGNMENT 4	/* This
+									   is a
+									   guess
+									 */
+#define UCC_GETH_RX_BD_RING_ALIGNMENT		32
+#define UCC_GETH_TX_BD_RING_ALIGNMENT		32
+#define UCC_GETH_MRBLR_ALIGNMENT		128
+#define UCC_GETH_RX_BD_RING_SIZE_ALIGNMENT	4
+#define UCC_GETH_TX_BD_RING_SIZE_MEMORY_ALIGNMENT	32
+#define UCC_GETH_RX_DATA_BUF_ALIGNMENT		64
+
+#define UCC_GETH_TAD_EF                         0x80
+#define UCC_GETH_TAD_V                          0x40
+#define UCC_GETH_TAD_REJ                        0x20
+#define UCC_GETH_TAD_VTAG_OP_RIGHT_SHIFT        2
+#define UCC_GETH_TAD_VTAG_OP_SHIFT              6
+#define UCC_GETH_TAD_V_NON_VTAG_OP              0x20
+#define UCC_GETH_TAD_RQOS_SHIFT                 0
+#define UCC_GETH_TAD_V_PRIORITY_SHIFT           5
+#define UCC_GETH_TAD_CFI                        0x10
+
+#define UCC_GETH_VLAN_PRIORITY_MAX              8
+#define UCC_GETH_IP_PRIORITY_MAX                64
+#define UCC_GETH_TX_VTAG_TABLE_ENTRY_MAX        8
+#define UCC_GETH_RX_BD_RING_SIZE_MIN            8
+#define UCC_GETH_TX_BD_RING_SIZE_MIN            2
+
+#define UCC_GETH_SIZE_OF_BD                     QE_SIZEOF_BD
+
+/* Driver definitions */
+#define TX_BD_RING_LEN                          0x10
+#define RX_BD_RING_LEN                          0x10
+#define UCC_GETH_DEV_WEIGHT                     TX_BD_RING_LEN
+
+#define TX_RING_MOD_MASK(size)                  (size-1)
+#define RX_RING_MOD_MASK(size)                  (size-1)
+
+#define ENET_NUM_OCTETS_PER_ADDRESS             6
+#define ENET_GROUP_ADDR                         0x01	/* Group address mask
+							   for ethernet
+							   addresses */
+
+#define TX_TIMEOUT                              (1*HZ)
+#define SKB_ALLOC_TIMEOUT                       100000
+#define PHY_INIT_TIMEOUT                        100000
+#define PHY_CHANGE_TIME                         2
+
+/* Fast Ethernet (10/100 Mbps) */
+#define UCC_GETH_URFS_INIT                      512	/* Rx virtual FIFO size
+							 */
+#define UCC_GETH_URFET_INIT                     256	/* 1/2 urfs */
+#define UCC_GETH_URFSET_INIT                    384	/* 3/4 urfs */
+#define UCC_GETH_UTFS_INIT                      512	/* Tx virtual FIFO size
+							 */
+#define UCC_GETH_UTFET_INIT                     256	/* 1/2 utfs */
+#define UCC_GETH_UTFTT_INIT                     128
+/* Gigabit Ethernet (1000 Mbps) */
+#define UCC_GETH_URFS_GIGA_INIT                 4096/*2048*/	/* Rx virtual
+								   FIFO size */
+#define UCC_GETH_URFET_GIGA_INIT                2048/*1024*/	/* 1/2 urfs */
+#define UCC_GETH_URFSET_GIGA_INIT               3072/*1536*/	/* 3/4 urfs */
+#define UCC_GETH_UTFS_GIGA_INIT                 8192/*2048*/	/* Tx virtual
+								   FIFO size */
+#define UCC_GETH_UTFET_GIGA_INIT                4096/*1024*/	/* 1/2 utfs */
+#define UCC_GETH_UTFTT_GIGA_INIT                0x400/*0x40*/	/* */
+
+#define UCC_GETH_REMODER_INIT                   0	/* bits that must be
+							   set */
+#define UCC_GETH_TEMODER_INIT                   0xC000	/* bits that must */
+#define UCC_GETH_UPSMR_INIT                     (UPSMR_RES1)	/* Start value
+								   for this
+								   register */
+#define UCC_GETH_MACCFG1_INIT                   0
+#define UCC_GETH_MACCFG2_INIT                   (MACCFG2_RESERVED_1)
+#define UCC_GETH_MIIMCFG_MNGMNT_CLC_DIV_INIT    \
+				(MIIMCFG_MANAGEMENT_CLOCK_DIVIDE_BY_112)
+
+/* Ethernet speed */
+typedef enum enet_speed {
+	ENET_SPEED_10BT,	/* 10 Base T */
+	ENET_SPEED_100BT,	/* 100 Base T */
+	ENET_SPEED_1000BT	/* 1000 Base T */
+} enet_speed_e;
+
+/* Ethernet Address Type. */
+typedef enum enet_addr_type {
+	ENET_ADDR_TYPE_INDIVIDUAL,
+	ENET_ADDR_TYPE_GROUP,
+	ENET_ADDR_TYPE_BROADCAST
+} enet_addr_type_e;
+
+/* TBI / MII Set Register */
+typedef enum enet_tbi_mii_reg {
+	ENET_TBI_MII_CR = 0x00,	/* Control (CR ) */
+	ENET_TBI_MII_SR = 0x01,	/* Status (SR ) */
+	ENET_TBI_MII_ANA = 0x04,	/* AN advertisement (ANA ) */
+	ENET_TBI_MII_ANLPBPA = 0x05,	/* AN link partner base page ability
+					   (ANLPBPA) */
+	ENET_TBI_MII_ANEX = 0x06,	/* AN expansion (ANEX ) */
+	ENET_TBI_MII_ANNPT = 0x07,	/* AN next page transmit (ANNPT ) */
+	ENET_TBI_MII_ANLPANP = 0x08,	/* AN link partner ability next page
+					   (ANLPANP) */
+	ENET_TBI_MII_EXST = 0x0F,	/* Extended status (EXST ) */
+	ENET_TBI_MII_JD = 0x10,	/* Jitter diagnostics (JD ) */
+	ENET_TBI_MII_TBICON = 0x11	/* TBI control (TBICON ) */
+} enet_tbi_mii_reg_e;
+
+/* UCC GETH 82xx Ethernet Address Recognition Location */
+typedef enum ucc_geth_enet_address_recognition_location {
+	UCC_GETH_ENET_ADDRESS_RECOGNITION_LOCATION_STATION_ADDRESS,/* station
+								      address */
+	UCC_GETH_ENET_ADDRESS_RECOGNITION_LOCATION_PADDR_FIRST,	/* additional
+								   station
+								   address
+								   paddr1 */
+	UCC_GETH_ENET_ADDRESS_RECOGNITION_LOCATION_PADDR2,	/* additional
+								   station
+								   address
+								   paddr2 */
+	UCC_GETH_ENET_ADDRESS_RECOGNITION_LOCATION_PADDR3,	/* additional
+								   station
+								   address
+								   paddr3 */
+	UCC_GETH_ENET_ADDRESS_RECOGNITION_LOCATION_PADDR_LAST,	/* additional
+								   station
+								   address
+								   paddr4 */
+	UCC_GETH_ENET_ADDRESS_RECOGNITION_LOCATION_GROUP_HASH,	/* group hash */
+	UCC_GETH_ENET_ADDRESS_RECOGNITION_LOCATION_INDIVIDUAL_HASH /* individual
+								      hash */
+} ucc_geth_enet_address_recognition_location_e;
+
+/* UCC GETH vlan operation tagged */
+typedef enum ucc_geth_vlan_operation_tagged {
+	UCC_GETH_VLAN_OPERATION_TAGGED_NOP = 0x0,	/* Tagged - nop */
+	UCC_GETH_VLAN_OPERATION_TAGGED_REPLACE_VID_PORTION_OF_Q_TAG
+		= 0x1,	/* Tagged - replace vid portion of q tag */
+	UCC_GETH_VLAN_OPERATION_TAGGED_IF_VID0_REPLACE_VID_WITH_DEFAULT_VALUE
+		= 0x2,	/* Tagged - if vid0 replace vid with default value  */
+	UCC_GETH_VLAN_OPERATION_TAGGED_EXTRACT_Q_TAG_FROM_FRAME
+		= 0x3	/* Tagged - extract q tag from frame */
+} ucc_geth_vlan_operation_tagged_e;
+
+/* UCC GETH vlan operation non-tagged */
+typedef enum ucc_geth_vlan_operation_non_tagged {
+	UCC_GETH_VLAN_OPERATION_NON_TAGGED_NOP = 0x0,	/* Non tagged - nop */
+	UCC_GETH_VLAN_OPERATION_NON_TAGGED_Q_TAG_INSERT = 0x1	/* Non tagged -
+								   q tag insert
+								 */
+} ucc_geth_vlan_operation_non_tagged_e;
+
+/* UCC GETH Rx Quality of Service Mode */
+typedef enum ucc_geth_qos_mode {
+	UCC_GETH_QOS_MODE_DEFAULT = 0x0,	/* default queue */
+	UCC_GETH_QOS_MODE_QUEUE_NUM_FROM_L2_CRITERIA = 0x1,	/* queue
+								   determined
+								   by L2
+								   criteria */
+	UCC_GETH_QOS_MODE_QUEUE_NUM_FROM_L3_CRITERIA = 0x2	/* queue
+								   determined
+								   by L3
+								   criteria */
+} ucc_geth_qos_mode_e;
+
+/* UCC GETH Statistics Gathering Mode - These are bit flags, 'or' them together
+   for combined functionality */
+typedef enum ucc_geth_statistics_gathering_mode {
+	UCC_GETH_STATISTICS_GATHERING_MODE_NONE = 0x00000000,	/* No
+								   statistics
+								   gathering */
+	UCC_GETH_STATISTICS_GATHERING_MODE_HARDWARE = 0x00000001,/* Enable
+								    hardware
+								    statistics
+								    gathering
+								  */
+	UCC_GETH_STATISTICS_GATHERING_MODE_FIRMWARE_TX = 0x00000004,/*Enable
+								      firmware
+								      tx
+								      statistics
+								      gathering
+								     */
+	UCC_GETH_STATISTICS_GATHERING_MODE_FIRMWARE_RX = 0x00000008/* Enable
+								      firmware
+								      rx
+								      statistics
+								      gathering
+								    */
+} ucc_geth_statistics_gathering_mode_e;
+
+/* UCC GETH Pad and CRC Mode - Note, Padding without CRC is not possible */
+typedef enum ucc_geth_maccfg2_pad_and_crc_mode {
+	UCC_GETH_PAD_AND_CRC_MODE_NONE
+		= MACCFG2_PAD_AND_CRC_MODE_NONE,	/* Neither Padding
+							   short frames
+							   nor CRC */
+	UCC_GETH_PAD_AND_CRC_MODE_CRC_ONLY
+		= MACCFG2_PAD_AND_CRC_MODE_CRC_ONLY,	/* Append
+							   CRC only */
+	UCC_GETH_PAD_AND_CRC_MODE_PAD_AND_CRC =
+	    MACCFG2_PAD_AND_CRC_MODE_PAD_AND_CRC
+} ucc_geth_maccfg2_pad_and_crc_mode_e;
+
+/* UCC GETH upsmr Flow Control Mode */
+typedef enum ucc_geth_flow_control_mode {
+	UPSMR_AUTOMATIC_FLOW_CONTROL_MODE_NONE = 0x00000000,	/* No automatic
+								   flow control
+								 */
+	UPSMR_AUTOMATIC_FLOW_CONTROL_MODE_PAUSE_WHEN_EMERGENCY
+		= 0x00004000	/* Send pause frame when RxFIFO reaches its
+				   emergency threshold */
+} ucc_geth_flow_control_mode_e;
+
+/* UCC GETH number of threads */
+typedef enum ucc_geth_num_of_threads {
+	UCC_GETH_NUM_OF_THREADS_1 = 0x1,	/* 1 */
+	UCC_GETH_NUM_OF_THREADS_2 = 0x2,	/* 2 */
+	UCC_GETH_NUM_OF_THREADS_4 = 0x0,	/* 4 */
+	UCC_GETH_NUM_OF_THREADS_6 = 0x3,	/* 6 */
+	UCC_GETH_NUM_OF_THREADS_8 = 0x4	/* 8 */
+} ucc_geth_num_of_threads_e;
+
+/* UCC GETH number of station addresses */
+typedef enum ucc_geth_num_of_station_addresses {
+	UCC_GETH_NUM_OF_STATION_ADDRESSES_1,	/* 1 */
+	UCC_GETH_NUM_OF_STATION_ADDRESSES_5	/* 5 */
+} ucc_geth_num_of_station_addresses_e;
+
+typedef u8 enet_addr_t[ENET_NUM_OCTETS_PER_ADDRESS];
+
+/* UCC GETH 82xx Ethernet Address Container */
+typedef struct enet_addr_container {
+	enet_addr_t address;	/* ethernet address */
+	ucc_geth_enet_address_recognition_location_e location;	/* location in
+								   82xx address
+								   recognition
+								   hardware */
+	struct list_head node;
+} enet_addr_container_t;
+
+#define ENET_ADDR_CONT_ENTRY(ptr) list_entry(ptr, enet_addr_container_t, node)
+
+/* UCC GETH Termination Action Descriptor (TAD) structure. */
+typedef struct ucc_geth_tad_params {
+	int rx_non_dynamic_extended_features_mode;
+	int reject_frame;
+	ucc_geth_vlan_operation_tagged_e vtag_op;
+	ucc_geth_vlan_operation_non_tagged_e vnontag_op;
+	ucc_geth_qos_mode_e rqos;
+	u8 vpri;
+	u16 vid;
+} ucc_geth_tad_params_t;
+
+/* GETH protocol initialization structure */
+typedef struct ucc_geth_info {
+	ucc_fast_info_t uf_info;
+	u8 numQueuesTx;
+	u8 numQueuesRx;
+	int ipCheckSumCheck;
+	int ipCheckSumGenerate;
+	int rxExtendedFiltering;
+	u32 extendedFilteringChainPointer;
+	u16 typeorlen;
+	int dynamicMaxFrameLength;
+	int dynamicMinFrameLength;
+	u8 nonBackToBackIfgPart1;
+	u8 nonBackToBackIfgPart2;
+	u8 miminumInterFrameGapEnforcement;
+	u8 backToBackInterFrameGap;
+	int ipAddressAlignment;
+	int lengthCheckRx;
+	u32 mblinterval;
+	u16 nortsrbytetime;
+	u8 fracsiz;
+	u8 strictpriorityq;
+	u8 txasap;
+	u8 extrabw;
+	int miiPreambleSupress;
+	u8 altBebTruncation;
+	int altBeb;
+	int backPressureNoBackoff;
+	int noBackoff;
+	int excessDefer;
+	u8 maxRetransmission;
+	u8 collisionWindow;
+	int pro;
+	int cap;
+	int rsh;
+	int rlpb;
+	int cam;
+	int bro;
+	int ecm;
+	int receiveFlowControl;
+	u8 maxGroupAddrInHash;
+	u8 maxIndAddrInHash;
+	u8 prel;
+	u16 maxFrameLength;
+	u16 minFrameLength;
+	u16 maxD1Length;
+	u16 maxD2Length;
+	u16 vlantype;
+	u16 vlantci;
+	u32 ecamptr;
+	u32 eventRegMask;
+	u16 pausePeriod;
+	u16 extensionField;
+	u8 phy_address;
+	u32 board_flags;
+	u32 phy_interrupt;
+	u8 weightfactor[NUM_TX_QUEUES];
+	u8 interruptcoalescingmaxvalue[NUM_RX_QUEUES];
+	u8 l2qt[UCC_GETH_VLAN_PRIORITY_MAX];
+	u8 l3qt[UCC_GETH_IP_PRIORITY_MAX];
+	u32 vtagtable[UCC_GETH_TX_VTAG_TABLE_ENTRY_MAX];
+	u8 iphoffset[TX_IP_OFFSET_ENTRY_MAX];
+	u16 bdRingLenTx[NUM_TX_QUEUES];
+	u16 bdRingLenRx[NUM_RX_QUEUES];
+	enet_interface_e enet_interface;
+	ucc_geth_num_of_station_addresses_e numStationAddresses;
+	 qe_fltr_largest_external_tbl_lookup_key_size_e
+	    largestexternallookupkeysize;
+	ucc_geth_statistics_gathering_mode_e statisticsMode;
+	ucc_geth_vlan_operation_tagged_e vlanOperationTagged;
+	ucc_geth_vlan_operation_non_tagged_e vlanOperationNonTagged;
+	ucc_geth_qos_mode_e rxQoSMode;
+	ucc_geth_flow_control_mode_e aufc;
+	ucc_geth_maccfg2_pad_and_crc_mode_e padAndCrc;
+	ucc_geth_num_of_threads_e numThreadsTx;
+	ucc_geth_num_of_threads_e numThreadsRx;
+	qe_risc_allocation_e riscTx;
+	qe_risc_allocation_e riscRx;
+} ucc_geth_info_t;
+
+/* structure representing UCC GETH */
+typedef struct ucc_geth_private {
+	ucc_geth_info_t *ug_info;
+	ucc_fast_private_t *uccf;
+	struct net_device *dev;
+	struct net_device_stats stats;	/* linux network statistics */
+	ucc_geth_t *ug_regs;
+	ucc_geth_init_pram_t *p_init_enet_param_shadow;
+	ucc_geth_exf_global_pram_t *p_exf_glbl_param;
+	u32 exf_glbl_param_offset;
+	ucc_geth_rx_global_pram_t *p_rx_glbl_pram;
+	u32 rx_glbl_pram_offset;
+	ucc_geth_tx_global_pram_t *p_tx_glbl_pram;
+	u32 tx_glbl_pram_offset;
+	ucc_geth_send_queue_mem_region_t *p_send_q_mem_reg;
+	u32 send_q_mem_reg_offset;
+	ucc_geth_thread_data_tx_t *p_thread_data_tx;
+	u32 thread_dat_tx_offset;
+	ucc_geth_thread_data_rx_t *p_thread_data_rx;
+	u32 thread_dat_rx_offset;
+	ucc_geth_scheduler_t *p_scheduler;
+	u32 scheduler_offset;
+	ucc_geth_tx_firmware_statistics_pram_t *p_tx_fw_statistics_pram;
+	u32 tx_fw_statistics_pram_offset;
+	ucc_geth_rx_firmware_statistics_pram_t *p_rx_fw_statistics_pram;
+	u32 rx_fw_statistics_pram_offset;
+	ucc_geth_rx_interrupt_coalescing_table_t *p_rx_irq_coalescing_tbl;
+	u32 rx_irq_coalescing_tbl_offset;
+	ucc_geth_rx_bd_queues_entry_t *p_rx_bd_qs_tbl;
+	u32 rx_bd_qs_tbl_offset;
+	u8 *p_tx_bd_ring[NUM_TX_QUEUES];
+	u32 tx_bd_ring_offset[NUM_TX_QUEUES];
+	u8 *p_rx_bd_ring[NUM_RX_QUEUES];
+	u32 rx_bd_ring_offset[NUM_RX_QUEUES];
+	u8 *confBd[NUM_TX_QUEUES];
+	u8 *txBd[NUM_TX_QUEUES];
+	u8 *rxBd[NUM_RX_QUEUES];
+	int badFrame[NUM_RX_QUEUES];
+	u16 cpucount[NUM_TX_QUEUES];
+	volatile u16 *p_cpucount[NUM_TX_QUEUES];
+	int indAddrRegUsed[NUM_OF_PADDRS];
+	enet_addr_t paddr[NUM_OF_PADDRS];
+	u8 numGroupAddrInHash;
+	u8 numIndAddrInHash;
+	u8 numIndAddrInReg;
+	int rx_extended_features;
+	int rx_non_dynamic_extended_features;
+	struct list_head conf_skbs;
+	struct list_head group_hash_q;
+	struct list_head ind_hash_q;
+	u32 saved_uccm;
+	spinlock_t lock;
+	/* pointers to arrays of skbuffs for tx and rx */
+	struct sk_buff **tx_skbuff[NUM_TX_QUEUES];
+	struct sk_buff **rx_skbuff[NUM_RX_QUEUES];
+	/* indices pointing to the next free sbk in skb arrays */
+	u16 skb_curtx[NUM_TX_QUEUES];
+	u16 skb_currx[NUM_RX_QUEUES];
+	/* index of the first skb which hasn't been transmitted yet. */
+	u16 skb_dirtytx[NUM_TX_QUEUES];
+
+	struct work_struct tq;
+	struct timer_list phy_info_timer;
+	struct ugeth_mii_info *mii_info;
+	int oldspeed;
+	int oldduplex;
+	int oldlink;
+} ucc_geth_private_t;
+
+#endif				/* __UCC_GETH_H__ */
diff --git a/drivers/net/ucc_geth_phy.c b/drivers/net/ucc_geth_phy.c
new file mode 100644
index 000000000..f91028c53
--- /dev/null
+++ b/drivers/net/ucc_geth_phy.c
@@ -0,0 +1,801 @@
+/*
+ * Copyright (C) Freescale Semicondutor, Inc. 2006. All rights reserved.
+ *
+ * Author: Shlomi Gridish <gridish@freescale.com>
+ *
+ * Description:
+ * UCC GETH Driver -- PHY handling
+ *
+ * Changelog:
+ * Jun 28, 2006 Li Yang <LeoLi@freescale.com>
+ * - Rearrange code and style fixes
+ *
+ * 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/config.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/string.h>
+#include <linux/errno.h>
+#include <linux/slab.h>
+#include <linux/interrupt.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/skbuff.h>
+#include <linux/spinlock.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/version.h>
+#include <linux/crc32.h>
+#include <linux/mii.h>
+#include <linux/ethtool.h>
+
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/uaccess.h>
+
+#include "ucc_geth.h"
+#include "ucc_geth_phy.h"
+#include <platforms/83xx/mpc8360e_pb.h>
+
+#define ugphy_printk(level, format, arg...)  \
+        printk(level format "\n", ## arg)
+
+#define ugphy_dbg(format, arg...)            \
+        ugphy_printk(KERN_DEBUG, format , ## arg)
+#define ugphy_err(format, arg...)            \
+        ugphy_printk(KERN_ERR, format , ## arg)
+#define ugphy_info(format, arg...)           \
+        ugphy_printk(KERN_INFO, format , ## arg)
+#define ugphy_warn(format, arg...)           \
+        ugphy_printk(KERN_WARNING, format , ## arg)
+
+#ifdef UGETH_VERBOSE_DEBUG
+#define ugphy_vdbg ugphy_dbg
+#else
+#define ugphy_vdbg(fmt, args...) do { } while (0)
+#endif				/* UGETH_VERBOSE_DEBUG */
+
+static void config_genmii_advert(struct ugeth_mii_info *mii_info);
+static void genmii_setup_forced(struct ugeth_mii_info *mii_info);
+static void genmii_restart_aneg(struct ugeth_mii_info *mii_info);
+static int gbit_config_aneg(struct ugeth_mii_info *mii_info);
+static int genmii_config_aneg(struct ugeth_mii_info *mii_info);
+static int genmii_update_link(struct ugeth_mii_info *mii_info);
+static int genmii_read_status(struct ugeth_mii_info *mii_info);
+u16 phy_read(struct ugeth_mii_info *mii_info, u16 regnum);
+void phy_write(struct ugeth_mii_info *mii_info, u16 regnum, u16 val);
+
+static u8 *bcsr_regs = NULL;
+
+/* Write value to the PHY for this device to the register at regnum, */
+/* waiting until the write is done before it returns.  All PHY */
+/* configuration has to be done through the TSEC1 MIIM regs */
+void write_phy_reg(struct net_device *dev, int mii_id, int regnum, int value)
+{
+	ucc_geth_private_t *ugeth = netdev_priv(dev);
+	ucc_mii_mng_t *mii_regs;
+	enet_tbi_mii_reg_e mii_reg = (enet_tbi_mii_reg_e) regnum;
+	u32 tmp_reg;
+
+	ugphy_vdbg("%s: IN", __FUNCTION__);
+
+	spin_lock_irq(&ugeth->lock);
+
+	mii_regs = ugeth->mii_info->mii_regs;
+
+	/* Set this UCC to be the master of the MII managment */
+	ucc_set_qe_mux_mii_mng(ugeth->ug_info->uf_info.ucc_num);
+
+	/* Stop the MII management read cycle */
+	out_be32(&mii_regs->miimcom, 0);
+	/* Setting up the MII Mangement Address Register */
+	tmp_reg = ((u32) mii_id << MIIMADD_PHY_ADDRESS_SHIFT) | mii_reg;
+	out_be32(&mii_regs->miimadd, tmp_reg);
+
+	/* Setting up the MII Mangement Control Register with the value */
+	out_be32(&mii_regs->miimcon, (u32) value);
+
+	/* Wait till MII management write is complete */
+	while ((in_be32(&mii_regs->miimind)) & MIIMIND_BUSY)
+		cpu_relax();
+
+	spin_unlock_irq(&ugeth->lock);
+
+	udelay(10000);
+}
+
+/* Reads from register regnum in the PHY for device dev, */
+/* returning the value.  Clears miimcom first.  All PHY */
+/* configuration has to be done through the TSEC1 MIIM regs */
+int read_phy_reg(struct net_device *dev, int mii_id, int regnum)
+{
+	ucc_geth_private_t *ugeth = netdev_priv(dev);
+	ucc_mii_mng_t *mii_regs;
+	enet_tbi_mii_reg_e mii_reg = (enet_tbi_mii_reg_e) regnum;
+	u32 tmp_reg;
+	u16 value;
+
+	ugphy_vdbg("%s: IN", __FUNCTION__);
+
+	spin_lock_irq(&ugeth->lock);
+
+	mii_regs = ugeth->mii_info->mii_regs;
+
+	/* Setting up the MII Mangement Address Register */
+	tmp_reg = ((u32) mii_id << MIIMADD_PHY_ADDRESS_SHIFT) | mii_reg;
+	out_be32(&mii_regs->miimadd, tmp_reg);
+
+	/* Perform an MII management read cycle */
+	out_be32(&mii_regs->miimcom, MIIMCOM_READ_CYCLE);
+
+	/* Wait till MII management write is complete */
+	while ((in_be32(&mii_regs->miimind)) & MIIMIND_BUSY)
+		cpu_relax();
+
+	udelay(10000);
+
+	/* Read MII management status  */
+	value = (u16) in_be32(&mii_regs->miimstat);
+	out_be32(&mii_regs->miimcom, 0);
+	if (value == 0xffff)
+		ugphy_warn("read wrong value : mii_id %d,mii_reg %d, base %08x",
+			   mii_id, mii_reg, (u32) & (mii_regs->miimcfg));
+
+	spin_unlock_irq(&ugeth->lock);
+
+	return (value);
+}
+
+void mii_clear_phy_interrupt(struct ugeth_mii_info *mii_info)
+{
+	ugphy_vdbg("%s: IN", __FUNCTION__);
+
+	if (mii_info->phyinfo->ack_interrupt)
+		mii_info->phyinfo->ack_interrupt(mii_info);
+}
+
+void mii_configure_phy_interrupt(struct ugeth_mii_info *mii_info,
+				 u32 interrupts)
+{
+	ugphy_vdbg("%s: IN", __FUNCTION__);
+
+	mii_info->interrupts = interrupts;
+	if (mii_info->phyinfo->config_intr)
+		mii_info->phyinfo->config_intr(mii_info);
+}
+
+/* Writes MII_ADVERTISE with the appropriate values, after
+ * sanitizing advertise to make sure only supported features
+ * are advertised
+ */
+static void config_genmii_advert(struct ugeth_mii_info *mii_info)
+{
+	u32 advertise;
+	u16 adv;
+
+	ugphy_vdbg("%s: IN", __FUNCTION__);
+
+	/* Only allow advertising what this PHY supports */
+	mii_info->advertising &= mii_info->phyinfo->features;
+	advertise = mii_info->advertising;
+
+	/* Setup standard advertisement */
+	adv = phy_read(mii_info, MII_ADVERTISE);
+	adv &= ~(ADVERTISE_ALL | ADVERTISE_100BASE4);
+	if (advertise & ADVERTISED_10baseT_Half)
+		adv |= ADVERTISE_10HALF;
+	if (advertise & ADVERTISED_10baseT_Full)
+		adv |= ADVERTISE_10FULL;
+	if (advertise & ADVERTISED_100baseT_Half)
+		adv |= ADVERTISE_100HALF;
+	if (advertise & ADVERTISED_100baseT_Full)
+		adv |= ADVERTISE_100FULL;
+	phy_write(mii_info, MII_ADVERTISE, adv);
+}
+
+static void genmii_setup_forced(struct ugeth_mii_info *mii_info)
+{
+	u16 ctrl;
+	u32 features = mii_info->phyinfo->features;
+
+	ugphy_vdbg("%s: IN", __FUNCTION__);
+
+	ctrl = phy_read(mii_info, MII_BMCR);
+
+	ctrl &=
+	    ~(BMCR_FULLDPLX | BMCR_SPEED100 | BMCR_SPEED1000 | BMCR_ANENABLE);
+	ctrl |= BMCR_RESET;
+
+	switch (mii_info->speed) {
+	case SPEED_1000:
+		if (features & (SUPPORTED_1000baseT_Half
+				| SUPPORTED_1000baseT_Full)) {
+			ctrl |= BMCR_SPEED1000;
+			break;
+		}
+		mii_info->speed = SPEED_100;
+	case SPEED_100:
+		if (features & (SUPPORTED_100baseT_Half
+				| SUPPORTED_100baseT_Full)) {
+			ctrl |= BMCR_SPEED100;
+			break;
+		}
+		mii_info->speed = SPEED_10;
+	case SPEED_10:
+		if (features & (SUPPORTED_10baseT_Half
+				| SUPPORTED_10baseT_Full))
+			break;
+	default:		/* Unsupported speed! */
+		ugphy_err("%s: Bad speed!", mii_info->dev->name);
+		break;
+	}
+
+	phy_write(mii_info, MII_BMCR, ctrl);
+}
+
+/* Enable and Restart Autonegotiation */
+static void genmii_restart_aneg(struct ugeth_mii_info *mii_info)
+{
+	u16 ctl;
+
+	ugphy_vdbg("%s: IN", __FUNCTION__);
+
+	ctl = phy_read(mii_info, MII_BMCR);
+	ctl |= (BMCR_ANENABLE | BMCR_ANRESTART);
+	phy_write(mii_info, MII_BMCR, ctl);
+}
+
+static int gbit_config_aneg(struct ugeth_mii_info *mii_info)
+{
+	u16 adv;
+	u32 advertise;
+
+	ugphy_vdbg("%s: IN", __FUNCTION__);
+
+	if (mii_info->autoneg) {
+		/* Configure the ADVERTISE register */
+		config_genmii_advert(mii_info);
+		advertise = mii_info->advertising;
+
+		adv = phy_read(mii_info, MII_1000BASETCONTROL);
+		adv &= ~(MII_1000BASETCONTROL_FULLDUPLEXCAP |
+			 MII_1000BASETCONTROL_HALFDUPLEXCAP);
+		if (advertise & SUPPORTED_1000baseT_Half)
+			adv |= MII_1000BASETCONTROL_HALFDUPLEXCAP;
+		if (advertise & SUPPORTED_1000baseT_Full)
+			adv |= MII_1000BASETCONTROL_FULLDUPLEXCAP;
+		phy_write(mii_info, MII_1000BASETCONTROL, adv);
+
+		/* Start/Restart aneg */
+		genmii_restart_aneg(mii_info);
+	} else
+		genmii_setup_forced(mii_info);
+
+	return 0;
+}
+
+static int genmii_config_aneg(struct ugeth_mii_info *mii_info)
+{
+	ugphy_vdbg("%s: IN", __FUNCTION__);
+
+	if (mii_info->autoneg) {
+		config_genmii_advert(mii_info);
+		genmii_restart_aneg(mii_info);
+	} else
+		genmii_setup_forced(mii_info);
+
+	return 0;
+}
+
+static int genmii_update_link(struct ugeth_mii_info *mii_info)
+{
+	u16 status;
+
+	ugphy_vdbg("%s: IN", __FUNCTION__);
+
+	/* Do a fake read */
+	phy_read(mii_info, MII_BMSR);
+
+	/* Read link and autonegotiation status */
+	status = phy_read(mii_info, MII_BMSR);
+	if ((status & BMSR_LSTATUS) == 0)
+		mii_info->link = 0;
+	else
+		mii_info->link = 1;
+
+	/* If we are autonegotiating, and not done,
+	 * return an error */
+	if (mii_info->autoneg && !(status & BMSR_ANEGCOMPLETE))
+		return -EAGAIN;
+
+	return 0;
+}
+
+static int genmii_read_status(struct ugeth_mii_info *mii_info)
+{
+	u16 status;
+	int err;
+
+	ugphy_vdbg("%s: IN", __FUNCTION__);
+
+	/* Update the link, but return if there
+	 * was an error */
+	err = genmii_update_link(mii_info);
+	if (err)
+		return err;
+
+	if (mii_info->autoneg) {
+		status = phy_read(mii_info, MII_LPA);
+
+		if (status & (LPA_10FULL | LPA_100FULL))
+			mii_info->duplex = DUPLEX_FULL;
+		else
+			mii_info->duplex = DUPLEX_HALF;
+		if (status & (LPA_100FULL | LPA_100HALF))
+			mii_info->speed = SPEED_100;
+		else
+			mii_info->speed = SPEED_10;
+		mii_info->pause = 0;
+	}
+	/* On non-aneg, we assume what we put in BMCR is the speed,
+	 * though magic-aneg shouldn't prevent this case from occurring
+	 */
+
+	return 0;
+}
+
+static int marvell_init(struct ugeth_mii_info *mii_info)
+{
+	ugphy_vdbg("%s: IN", __FUNCTION__);
+
+	phy_write(mii_info, 0x14, 0x0cd2);
+	phy_write(mii_info, MII_BMCR,
+		  phy_read(mii_info, MII_BMCR) | BMCR_RESET);
+	msleep(4000);
+
+	return 0;
+}
+
+static int marvell_config_aneg(struct ugeth_mii_info *mii_info)
+{
+	ugphy_vdbg("%s: IN", __FUNCTION__);
+
+	/* The Marvell PHY has an errata which requires
+	 * that certain registers get written in order
+	 * to restart autonegotiation */
+	phy_write(mii_info, MII_BMCR, BMCR_RESET);
+
+	phy_write(mii_info, 0x1d, 0x1f);
+	phy_write(mii_info, 0x1e, 0x200c);
+	phy_write(mii_info, 0x1d, 0x5);
+	phy_write(mii_info, 0x1e, 0);
+	phy_write(mii_info, 0x1e, 0x100);
+
+	gbit_config_aneg(mii_info);
+
+	return 0;
+}
+
+static int marvell_read_status(struct ugeth_mii_info *mii_info)
+{
+	u16 status;
+	int err;
+
+	ugphy_vdbg("%s: IN", __FUNCTION__);
+
+	/* Update the link, but return if there
+	 * was an error */
+	err = genmii_update_link(mii_info);
+	if (err)
+		return err;
+
+	/* If the link is up, read the speed and duplex */
+	/* If we aren't autonegotiating, assume speeds
+	 * are as set */
+	if (mii_info->autoneg && mii_info->link) {
+		int speed;
+		status = phy_read(mii_info, MII_M1011_PHY_SPEC_STATUS);
+
+		/* Get the duplexity */
+		if (status & MII_M1011_PHY_SPEC_STATUS_FULLDUPLEX)
+			mii_info->duplex = DUPLEX_FULL;
+		else
+			mii_info->duplex = DUPLEX_HALF;
+
+		/* Get the speed */
+		speed = status & MII_M1011_PHY_SPEC_STATUS_SPD_MASK;
+		switch (speed) {
+		case MII_M1011_PHY_SPEC_STATUS_1000:
+			mii_info->speed = SPEED_1000;
+			break;
+		case MII_M1011_PHY_SPEC_STATUS_100:
+			mii_info->speed = SPEED_100;
+			break;
+		default:
+			mii_info->speed = SPEED_10;
+			break;
+		}
+		mii_info->pause = 0;
+	}
+
+	return 0;
+}
+
+static int marvell_ack_interrupt(struct ugeth_mii_info *mii_info)
+{
+	ugphy_vdbg("%s: IN", __FUNCTION__);
+
+	/* Clear the interrupts by reading the reg */
+	phy_read(mii_info, MII_M1011_IEVENT);
+
+	return 0;
+}
+
+static int marvell_config_intr(struct ugeth_mii_info *mii_info)
+{
+	ugphy_vdbg("%s: IN", __FUNCTION__);
+
+	if (mii_info->interrupts == MII_INTERRUPT_ENABLED)
+		phy_write(mii_info, MII_M1011_IMASK, MII_M1011_IMASK_INIT);
+	else
+		phy_write(mii_info, MII_M1011_IMASK, MII_M1011_IMASK_CLEAR);
+
+	return 0;
+}
+
+static int cis820x_init(struct ugeth_mii_info *mii_info)
+{
+	ugphy_vdbg("%s: IN", __FUNCTION__);
+
+	phy_write(mii_info, MII_CIS8201_AUX_CONSTAT,
+		  MII_CIS8201_AUXCONSTAT_INIT);
+	phy_write(mii_info, MII_CIS8201_EXT_CON1, MII_CIS8201_EXTCON1_INIT);
+
+	return 0;
+}
+
+static int cis820x_read_status(struct ugeth_mii_info *mii_info)
+{
+	u16 status;
+	int err;
+
+	ugphy_vdbg("%s: IN", __FUNCTION__);
+
+	/* Update the link, but return if there
+	 * was an error */
+	err = genmii_update_link(mii_info);
+	if (err)
+		return err;
+
+	/* If the link is up, read the speed and duplex */
+	/* If we aren't autonegotiating, assume speeds
+	 * are as set */
+	if (mii_info->autoneg && mii_info->link) {
+		int speed;
+
+		status = phy_read(mii_info, MII_CIS8201_AUX_CONSTAT);
+		if (status & MII_CIS8201_AUXCONSTAT_DUPLEX)
+			mii_info->duplex = DUPLEX_FULL;
+		else
+			mii_info->duplex = DUPLEX_HALF;
+
+		speed = status & MII_CIS8201_AUXCONSTAT_SPEED;
+
+		switch (speed) {
+		case MII_CIS8201_AUXCONSTAT_GBIT:
+			mii_info->speed = SPEED_1000;
+			break;
+		case MII_CIS8201_AUXCONSTAT_100:
+			mii_info->speed = SPEED_100;
+			break;
+		default:
+			mii_info->speed = SPEED_10;
+			break;
+		}
+	}
+
+	return 0;
+}
+
+static int cis820x_ack_interrupt(struct ugeth_mii_info *mii_info)
+{
+	ugphy_vdbg("%s: IN", __FUNCTION__);
+
+	phy_read(mii_info, MII_CIS8201_ISTAT);
+
+	return 0;
+}
+
+static int cis820x_config_intr(struct ugeth_mii_info *mii_info)
+{
+	ugphy_vdbg("%s: IN", __FUNCTION__);
+
+	if (mii_info->interrupts == MII_INTERRUPT_ENABLED)
+		phy_write(mii_info, MII_CIS8201_IMASK, MII_CIS8201_IMASK_MASK);
+	else
+		phy_write(mii_info, MII_CIS8201_IMASK, 0);
+
+	return 0;
+}
+
+#define DM9161_DELAY 10
+
+static int dm9161_read_status(struct ugeth_mii_info *mii_info)
+{
+	u16 status;
+	int err;
+
+	ugphy_vdbg("%s: IN", __FUNCTION__);
+
+	/* Update the link, but return if there
+	 * was an error */
+	err = genmii_update_link(mii_info);
+	if (err)
+		return err;
+
+	/* If the link is up, read the speed and duplex */
+	/* If we aren't autonegotiating, assume speeds
+	 * are as set */
+	if (mii_info->autoneg && mii_info->link) {
+		status = phy_read(mii_info, MII_DM9161_SCSR);
+		if (status & (MII_DM9161_SCSR_100F | MII_DM9161_SCSR_100H))
+			mii_info->speed = SPEED_100;
+		else
+			mii_info->speed = SPEED_10;
+
+		if (status & (MII_DM9161_SCSR_100F | MII_DM9161_SCSR_10F))
+			mii_info->duplex = DUPLEX_FULL;
+		else
+			mii_info->duplex = DUPLEX_HALF;
+	}
+
+	return 0;
+}
+
+static int dm9161_config_aneg(struct ugeth_mii_info *mii_info)
+{
+	struct dm9161_private *priv = mii_info->priv;
+
+	ugphy_vdbg("%s: IN", __FUNCTION__);
+
+	if (0 == priv->resetdone)
+		return -EAGAIN;
+
+	return 0;
+}
+
+static void dm9161_timer(unsigned long data)
+{
+	struct ugeth_mii_info *mii_info = (struct ugeth_mii_info *)data;
+	struct dm9161_private *priv = mii_info->priv;
+	u16 status = phy_read(mii_info, MII_BMSR);
+
+	ugphy_vdbg("%s: IN", __FUNCTION__);
+
+	if (status & BMSR_ANEGCOMPLETE) {
+		priv->resetdone = 1;
+	} else
+		mod_timer(&priv->timer, jiffies + DM9161_DELAY * HZ);
+}
+
+static int dm9161_init(struct ugeth_mii_info *mii_info)
+{
+	struct dm9161_private *priv;
+
+	ugphy_vdbg("%s: IN", __FUNCTION__);
+
+	/* Allocate the private data structure */
+	priv = kmalloc(sizeof(struct dm9161_private), GFP_KERNEL);
+
+	if (NULL == priv)
+		return -ENOMEM;
+
+	mii_info->priv = priv;
+
+	/* Reset is not done yet */
+	priv->resetdone = 0;
+
+	phy_write(mii_info, MII_BMCR,
+		  phy_read(mii_info, MII_BMCR) | BMCR_RESET);
+
+	phy_write(mii_info, MII_BMCR,
+		  phy_read(mii_info, MII_BMCR) & ~BMCR_ISOLATE);
+
+	config_genmii_advert(mii_info);
+	/* Start/Restart aneg */
+	genmii_config_aneg(mii_info);
+
+	/* Start a timer for DM9161_DELAY seconds to wait
+	 * for the PHY to be ready */
+	init_timer(&priv->timer);
+	priv->timer.function = &dm9161_timer;
+	priv->timer.data = (unsigned long)mii_info;
+	mod_timer(&priv->timer, jiffies + DM9161_DELAY * HZ);
+
+	return 0;
+}
+
+static void dm9161_close(struct ugeth_mii_info *mii_info)
+{
+	struct dm9161_private *priv = mii_info->priv;
+
+	ugphy_vdbg("%s: IN", __FUNCTION__);
+
+	del_timer_sync(&priv->timer);
+	kfree(priv);
+}
+
+static int dm9161_ack_interrupt(struct ugeth_mii_info *mii_info)
+{
+/* FIXME: This lines are for BUG fixing in the mpc8325.
+Remove this from here when it's fixed */
+	if (bcsr_regs == NULL)
+		bcsr_regs = (u8 *) ioremap(BCSR_PHYS_ADDR, BCSR_SIZE);
+	bcsr_regs[14] |= 0x40;
+	ugphy_vdbg("%s: IN", __FUNCTION__);
+
+	/* Clear the interrupts by reading the reg */
+	phy_read(mii_info, MII_DM9161_INTR);
+
+
+	return 0;
+}
+
+static int dm9161_config_intr(struct ugeth_mii_info *mii_info)
+{
+/* FIXME: This lines are for BUG fixing in the mpc8325.
+Remove this from here when it's fixed */
+	if (bcsr_regs == NULL) {
+		bcsr_regs = (u8 *) ioremap(BCSR_PHYS_ADDR, BCSR_SIZE);
+		bcsr_regs[14] &= ~0x40;
+	}
+	ugphy_vdbg("%s: IN", __FUNCTION__);
+
+	if (mii_info->interrupts == MII_INTERRUPT_ENABLED)
+		phy_write(mii_info, MII_DM9161_INTR, MII_DM9161_INTR_INIT);
+	else
+		phy_write(mii_info, MII_DM9161_INTR, MII_DM9161_INTR_STOP);
+
+	return 0;
+}
+
+/* Cicada 820x */
+static struct phy_info phy_info_cis820x = {
+	.phy_id = 0x000fc440,
+	.name = "Cicada Cis8204",
+	.phy_id_mask = 0x000fffc0,
+	.features = MII_GBIT_FEATURES,
+	.init = &cis820x_init,
+	.config_aneg = &gbit_config_aneg,
+	.read_status = &cis820x_read_status,
+	.ack_interrupt = &cis820x_ack_interrupt,
+	.config_intr = &cis820x_config_intr,
+};
+
+static struct phy_info phy_info_dm9161 = {
+	.phy_id = 0x0181b880,
+	.phy_id_mask = 0x0ffffff0,
+	.name = "Davicom DM9161E",
+	.init = dm9161_init,
+	.config_aneg = dm9161_config_aneg,
+	.read_status = dm9161_read_status,
+	.close = dm9161_close,
+};
+
+static struct phy_info phy_info_dm9161a = {
+	.phy_id = 0x0181b8a0,
+	.phy_id_mask = 0x0ffffff0,
+	.name = "Davicom DM9161A",
+	.features = MII_BASIC_FEATURES,
+	.init = dm9161_init,
+	.config_aneg = dm9161_config_aneg,
+	.read_status = dm9161_read_status,
+	.ack_interrupt = dm9161_ack_interrupt,
+	.config_intr = dm9161_config_intr,
+	.close = dm9161_close,
+};
+
+static struct phy_info phy_info_marvell = {
+	.phy_id = 0x01410c00,
+	.phy_id_mask = 0xffffff00,
+	.name = "Marvell 88E11x1",
+	.features = MII_GBIT_FEATURES,
+	.init = &marvell_init,
+	.config_aneg = &marvell_config_aneg,
+	.read_status = &marvell_read_status,
+	.ack_interrupt = &marvell_ack_interrupt,
+	.config_intr = &marvell_config_intr,
+};
+
+static struct phy_info phy_info_genmii = {
+	.phy_id = 0x00000000,
+	.phy_id_mask = 0x00000000,
+	.name = "Generic MII",
+	.features = MII_BASIC_FEATURES,
+	.config_aneg = genmii_config_aneg,
+	.read_status = genmii_read_status,
+};
+
+static struct phy_info *phy_info[] = {
+	&phy_info_cis820x,
+	&phy_info_marvell,
+	&phy_info_dm9161,
+	&phy_info_dm9161a,
+	&phy_info_genmii,
+	NULL
+};
+
+u16 phy_read(struct ugeth_mii_info *mii_info, u16 regnum)
+{
+	u16 retval;
+	unsigned long flags;
+
+	ugphy_vdbg("%s: IN", __FUNCTION__);
+
+	spin_lock_irqsave(&mii_info->mdio_lock, flags);
+	retval = mii_info->mdio_read(mii_info->dev, mii_info->mii_id, regnum);
+	spin_unlock_irqrestore(&mii_info->mdio_lock, flags);
+
+	return retval;
+}
+
+void phy_write(struct ugeth_mii_info *mii_info, u16 regnum, u16 val)
+{
+	unsigned long flags;
+
+	ugphy_vdbg("%s: IN", __FUNCTION__);
+
+	spin_lock_irqsave(&mii_info->mdio_lock, flags);
+	mii_info->mdio_write(mii_info->dev, mii_info->mii_id, regnum, val);
+	spin_unlock_irqrestore(&mii_info->mdio_lock, flags);
+}
+
+/* Use the PHY ID registers to determine what type of PHY is attached
+ * to device dev.  return a struct phy_info structure describing that PHY
+ */
+struct phy_info *get_phy_info(struct ugeth_mii_info *mii_info)
+{
+	u16 phy_reg;
+	u32 phy_ID;
+	int i;
+	struct phy_info *theInfo = NULL;
+	struct net_device *dev = mii_info->dev;
+
+	ugphy_vdbg("%s: IN", __FUNCTION__);
+
+	/* Grab the bits from PHYIR1, and put them in the upper half */
+	phy_reg = phy_read(mii_info, MII_PHYSID1);
+	phy_ID = (phy_reg & 0xffff) << 16;
+
+	/* Grab the bits from PHYIR2, and put them in the lower half */
+	phy_reg = phy_read(mii_info, MII_PHYSID2);
+	phy_ID |= (phy_reg & 0xffff);
+
+	/* loop through all the known PHY types, and find one that */
+	/* matches the ID we read from the PHY. */
+	for (i = 0; phy_info[i]; i++)
+		if (phy_info[i]->phy_id == (phy_ID & phy_info[i]->phy_id_mask)){
+			theInfo = phy_info[i];
+			break;
+		}
+
+	/* This shouldn't happen, as we have generic PHY support */
+	if (theInfo == NULL) {
+		ugphy_info("%s: PHY id %x is not supported!", dev->name,
+			   phy_ID);
+		return NULL;
+	} else {
+		ugphy_info("%s: PHY is %s (%x)", dev->name, theInfo->name,
+			   phy_ID);
+	}
+
+	return theInfo;
+}
diff --git a/drivers/net/ucc_geth_phy.h b/drivers/net/ucc_geth_phy.h
new file mode 100644
index 000000000..2f98b8f1b
--- /dev/null
+++ b/drivers/net/ucc_geth_phy.h
@@ -0,0 +1,217 @@
+/*
+ * Copyright (C) Freescale Semicondutor, Inc. 2006. All rights reserved.
+ *
+ * Author: Shlomi Gridish <gridish@freescale.com>
+ *
+ * Description:
+ * UCC GETH Driver -- PHY handling
+ *
+ * Changelog:
+ * Jun 28, 2006 Li Yang <LeoLi@freescale.com>
+ * - Rearrange code and style fixes
+ *
+ * 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 __UCC_GETH_PHY_H__
+#define __UCC_GETH_PHY_H__
+
+#define MII_end ((u32)-2)
+#define MII_read ((u32)-1)
+
+#define MIIMIND_BUSY            0x00000001
+#define MIIMIND_NOTVALID        0x00000004
+
+#define UGETH_AN_TIMEOUT        2000
+
+/* 1000BT control (Marvell & BCM54xx at least) */
+#define MII_1000BASETCONTROL                  0x09
+#define MII_1000BASETCONTROL_FULLDUPLEXCAP    0x0200
+#define MII_1000BASETCONTROL_HALFDUPLEXCAP    0x0100
+
+/* Cicada Extended Control Register 1 */
+#define MII_CIS8201_EXT_CON1        0x17
+#define MII_CIS8201_EXTCON1_INIT    0x0000
+
+/* Cicada Interrupt Mask Register */
+#define MII_CIS8201_IMASK           0x19
+#define MII_CIS8201_IMASK_IEN       0x8000
+#define MII_CIS8201_IMASK_SPEED     0x4000
+#define MII_CIS8201_IMASK_LINK      0x2000
+#define MII_CIS8201_IMASK_DUPLEX    0x1000
+#define MII_CIS8201_IMASK_MASK      0xf000
+
+/* Cicada Interrupt Status Register */
+#define MII_CIS8201_ISTAT           0x1a
+#define MII_CIS8201_ISTAT_STATUS    0x8000
+#define MII_CIS8201_ISTAT_SPEED     0x4000
+#define MII_CIS8201_ISTAT_LINK      0x2000
+#define MII_CIS8201_ISTAT_DUPLEX    0x1000
+
+/* Cicada Auxiliary Control/Status Register */
+#define MII_CIS8201_AUX_CONSTAT        0x1c
+#define MII_CIS8201_AUXCONSTAT_INIT    0x0004
+#define MII_CIS8201_AUXCONSTAT_DUPLEX  0x0020
+#define MII_CIS8201_AUXCONSTAT_SPEED   0x0018
+#define MII_CIS8201_AUXCONSTAT_GBIT    0x0010
+#define MII_CIS8201_AUXCONSTAT_100     0x0008
+
+/* 88E1011 PHY Status Register */
+#define MII_M1011_PHY_SPEC_STATUS               0x11
+#define MII_M1011_PHY_SPEC_STATUS_1000          0x8000
+#define MII_M1011_PHY_SPEC_STATUS_100           0x4000
+#define MII_M1011_PHY_SPEC_STATUS_SPD_MASK      0xc000
+#define MII_M1011_PHY_SPEC_STATUS_FULLDUPLEX    0x2000
+#define MII_M1011_PHY_SPEC_STATUS_RESOLVED      0x0800
+#define MII_M1011_PHY_SPEC_STATUS_LINK          0x0400
+
+#define MII_M1011_IEVENT                0x13
+#define MII_M1011_IEVENT_CLEAR          0x0000
+
+#define MII_M1011_IMASK                 0x12
+#define MII_M1011_IMASK_INIT            0x6400
+#define MII_M1011_IMASK_CLEAR           0x0000
+
+#define MII_DM9161_SCR                  0x10
+#define MII_DM9161_SCR_INIT             0x0610
+
+/* DM9161 Specified Configuration and Status Register */
+#define MII_DM9161_SCSR                 0x11
+#define MII_DM9161_SCSR_100F            0x8000
+#define MII_DM9161_SCSR_100H            0x4000
+#define MII_DM9161_SCSR_10F             0x2000
+#define MII_DM9161_SCSR_10H             0x1000
+
+/* DM9161 Interrupt Register */
+#define MII_DM9161_INTR                 0x15
+#define MII_DM9161_INTR_PEND            0x8000
+#define MII_DM9161_INTR_DPLX_MASK       0x0800
+#define MII_DM9161_INTR_SPD_MASK        0x0400
+#define MII_DM9161_INTR_LINK_MASK       0x0200
+#define MII_DM9161_INTR_MASK            0x0100
+#define MII_DM9161_INTR_DPLX_CHANGE     0x0010
+#define MII_DM9161_INTR_SPD_CHANGE      0x0008
+#define MII_DM9161_INTR_LINK_CHANGE     0x0004
+#define MII_DM9161_INTR_INIT            0x0000
+#define MII_DM9161_INTR_STOP    \
+(MII_DM9161_INTR_DPLX_MASK | MII_DM9161_INTR_SPD_MASK \
+ | MII_DM9161_INTR_LINK_MASK | MII_DM9161_INTR_MASK)
+
+/* DM9161 10BT Configuration/Status */
+#define MII_DM9161_10BTCSR              0x12
+#define MII_DM9161_10BTCSR_INIT         0x7800
+
+#define MII_BASIC_FEATURES    (SUPPORTED_10baseT_Half | \
+                 SUPPORTED_10baseT_Full | \
+                 SUPPORTED_100baseT_Half | \
+                 SUPPORTED_100baseT_Full | \
+                 SUPPORTED_Autoneg | \
+                 SUPPORTED_TP | \
+                 SUPPORTED_MII)
+
+#define MII_GBIT_FEATURES    (MII_BASIC_FEATURES | \
+                 SUPPORTED_1000baseT_Half | \
+                 SUPPORTED_1000baseT_Full)
+
+#define MII_READ_COMMAND                0x00000001
+
+#define MII_INTERRUPT_DISABLED          0x0
+#define MII_INTERRUPT_ENABLED           0x1
+/* Taken from mii_if_info and sungem_phy.h */
+struct ugeth_mii_info {
+	/* Information about the PHY type */
+	/* And management functions */
+	struct phy_info *phyinfo;
+
+	ucc_mii_mng_t *mii_regs;
+
+	/* forced speed & duplex (no autoneg)
+	 * partner speed & duplex & pause (autoneg)
+	 */
+	int speed;
+	int duplex;
+	int pause;
+
+	/* The most recently read link state */
+	int link;
+
+	/* Enabled Interrupts */
+	u32 interrupts;
+
+	u32 advertising;
+	int autoneg;
+	int mii_id;
+
+	/* private data pointer */
+	/* For use by PHYs to maintain extra state */
+	void *priv;
+
+	/* Provided by host chip */
+	struct net_device *dev;
+
+	/* A lock to ensure that only one thing can read/write
+	 * the MDIO bus at a time */
+	spinlock_t mdio_lock;
+
+	/* Provided by ethernet driver */
+	int (*mdio_read) (struct net_device * dev, int mii_id, int reg);
+	void (*mdio_write) (struct net_device * dev, int mii_id, int reg,
+			    int val);
+};
+
+/* struct phy_info: a structure which defines attributes for a PHY
+ *
+ * id will contain a number which represents the PHY.  During
+ * startup, the driver will poll the PHY to find out what its
+ * UID--as defined by registers 2 and 3--is.  The 32-bit result
+ * gotten from the PHY will be ANDed with phy_id_mask to
+ * discard any bits which may change based on revision numbers
+ * unimportant to functionality
+ *
+ * There are 6 commands which take a ugeth_mii_info structure.
+ * Each PHY must declare config_aneg, and read_status.
+ */
+struct phy_info {
+	u32 phy_id;
+	char *name;
+	unsigned int phy_id_mask;
+	u32 features;
+
+	/* Called to initialize the PHY */
+	int (*init) (struct ugeth_mii_info * mii_info);
+
+	/* Called to suspend the PHY for power */
+	int (*suspend) (struct ugeth_mii_info * mii_info);
+
+	/* Reconfigures autonegotiation (or disables it) */
+	int (*config_aneg) (struct ugeth_mii_info * mii_info);
+
+	/* Determines the negotiated speed and duplex */
+	int (*read_status) (struct ugeth_mii_info * mii_info);
+
+	/* Clears any pending interrupts */
+	int (*ack_interrupt) (struct ugeth_mii_info * mii_info);
+
+	/* Enables or disables interrupts */
+	int (*config_intr) (struct ugeth_mii_info * mii_info);
+
+	/* Clears up any memory if needed */
+	void (*close) (struct ugeth_mii_info * mii_info);
+};
+
+struct phy_info *get_phy_info(struct ugeth_mii_info *mii_info);
+void write_phy_reg(struct net_device *dev, int mii_id, int regnum, int value);
+int read_phy_reg(struct net_device *dev, int mii_id, int regnum);
+void mii_clear_phy_interrupt(struct ugeth_mii_info *mii_info);
+void mii_configure_phy_interrupt(struct ugeth_mii_info *mii_info,
+				 u32 interrupts);
+
+struct dm9161_private {
+	struct timer_list timer;
+	int resetdone;
+};
+
+#endif				/* __UCC_GETH_PHY_H__ */
diff --git a/drivers/net/wireless/orinoco_pci.h b/drivers/net/wireless/orinoco_pci.h
new file mode 100644
index 000000000..be1abea4b
--- /dev/null
+++ b/drivers/net/wireless/orinoco_pci.h
@@ -0,0 +1,104 @@
+/* orinoco_pci.h
+ * 
+ * Common code for all Orinoco drivers for PCI devices, including
+ * both native PCI and PCMCIA-to-PCI bridges.
+ *
+ * Copyright (C) 2005, Pavel Roskin.
+ * See orinoco.c for license.
+ */
+
+#ifndef _ORINOCO_PCI_H
+#define _ORINOCO_PCI_H
+
+#include <linux/netdevice.h>
+
+/* Driver specific data */
+struct orinoco_pci_card {
+	void __iomem *bridge_io;
+	void __iomem *attr_io;
+};
+
+#ifdef CONFIG_PM
+static int orinoco_pci_suspend(struct pci_dev *pdev, pm_message_t state)
+{
+	struct net_device *dev = pci_get_drvdata(pdev);
+	struct orinoco_private *priv = netdev_priv(dev);
+	unsigned long flags;
+	int err;
+
+	err = orinoco_lock(priv, &flags);
+	if (err) {
+		printk(KERN_ERR "%s: cannot lock hardware for suspend\n",
+		       dev->name);
+		return err;
+	}
+
+	err = __orinoco_down(dev);
+	if (err)
+		printk(KERN_WARNING "%s: error %d bringing interface down "
+		       "for suspend\n", dev->name, err);
+	
+	netif_device_detach(dev);
+
+	priv->hw_unavailable++;
+	
+	orinoco_unlock(priv, &flags);
+
+	free_irq(pdev->irq, dev);
+	pci_save_state(pdev);
+	pci_disable_device(pdev);
+	pci_set_power_state(pdev, PCI_D3hot);
+
+	return 0;
+}
+
+static int orinoco_pci_resume(struct pci_dev *pdev)
+{
+	struct net_device *dev = pci_get_drvdata(pdev);
+	struct orinoco_private *priv = netdev_priv(dev);
+	unsigned long flags;
+	int err;
+
+	pci_set_power_state(pdev, 0);
+	pci_enable_device(pdev);
+	pci_restore_state(pdev);
+
+	err = request_irq(pdev->irq, orinoco_interrupt, IRQF_SHARED,
+			  dev->name, dev);
+	if (err) {
+		printk(KERN_ERR "%s: cannot re-allocate IRQ on resume\n",
+		       dev->name);
+		pci_disable_device(pdev);
+		return -EBUSY;
+	}
+
+	err = orinoco_reinit_firmware(dev);
+	if (err) {
+		printk(KERN_ERR "%s: error %d re-initializing firmware "
+		       "on resume\n", dev->name, err);
+		return err;
+	}
+
+	spin_lock_irqsave(&priv->lock, flags);
+
+	netif_device_attach(dev);
+
+	priv->hw_unavailable--;
+
+	if (priv->open && (! priv->hw_unavailable)) {
+		err = __orinoco_up(dev);
+		if (err)
+			printk(KERN_ERR "%s: Error %d restarting card on resume\n",
+			       dev->name, err);
+	}
+	
+	spin_unlock_irqrestore(&priv->lock, flags);
+
+	return 0;
+}
+#else
+#define orinoco_pci_suspend NULL
+#define orinoco_pci_resume NULL
+#endif
+
+#endif /* _ORINOCO_PCI_H */
diff --git a/drivers/net/wireless/zd1201.c b/drivers/net/wireless/zd1201.c
new file mode 100644
index 000000000..c52e9bcf8
--- /dev/null
+++ b/drivers/net/wireless/zd1201.c
@@ -0,0 +1,1931 @@
+/*
+ *	Driver for ZyDAS zd1201 based wireless USB devices.
+ *
+ *	Copyright (c) 2004, 2005 Jeroen Vreeken (pe1rxq@amsat.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.
+ *
+ *	Parts of this driver have been derived from a wlan-ng version
+ *	modified by ZyDAS. They also made documentation available, thanks!
+ *	Copyright (C) 1999 AbsoluteValue Systems, Inc.  All Rights Reserved.
+ */
+
+#include <linux/module.h>
+#include <linux/usb.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/wireless.h>
+#include <net/iw_handler.h>
+#include <linux/string.h>
+#include <linux/if_arp.h>
+#include <linux/firmware.h>
+#include <net/ieee80211.h>
+#include "zd1201.h"
+
+static struct usb_device_id zd1201_table[] = {
+	{USB_DEVICE(0x0586, 0x3400)}, /* Peabird Wireless USB Adapter */
+	{USB_DEVICE(0x0ace, 0x1201)}, /* ZyDAS ZD1201 Wireless USB Adapter */
+	{USB_DEVICE(0x050d, 0x6051)}, /* Belkin F5D6051 usb  adapter */
+	{USB_DEVICE(0x0db0, 0x6823)}, /* MSI UB11B usb  adapter */
+	{USB_DEVICE(0x1044, 0x8005)}, /* GIGABYTE GN-WLBZ201 usb adapter */
+	{}
+};
+
+static int ap;	/* Are we an AP or a normal station? */
+
+#define ZD1201_VERSION	"0.15"
+
+MODULE_AUTHOR("Jeroen Vreeken <pe1rxq@amsat.org>");
+MODULE_DESCRIPTION("Driver for ZyDAS ZD1201 based USB Wireless adapters");
+MODULE_VERSION(ZD1201_VERSION);
+MODULE_LICENSE("GPL");
+module_param(ap, int, 0);
+MODULE_PARM_DESC(ap, "If non-zero Access Point firmware will be loaded");
+MODULE_DEVICE_TABLE(usb, zd1201_table);
+
+
+static int zd1201_fw_upload(struct usb_device *dev, int apfw)
+{
+	const struct firmware *fw_entry;
+	char *data;
+	unsigned long len;
+	int err;
+	unsigned char ret;
+	char *buf;
+	char *fwfile;
+
+	if (apfw)
+		fwfile = "zd1201-ap.fw";
+	else
+		fwfile = "zd1201.fw";
+
+	err = request_firmware(&fw_entry, fwfile, &dev->dev);
+	if (err) {
+		dev_err(&dev->dev, "Failed to load %s firmware file!\n", fwfile);
+		dev_err(&dev->dev, "Make sure the hotplug firmware loader is installed.\n");
+		dev_err(&dev->dev, "Goto http://linux-lc100020.sourceforge.net for more info.\n");
+		return err;
+	}
+
+	data = fw_entry->data;
+        len = fw_entry->size;
+
+	buf = kmalloc(1024, GFP_ATOMIC);
+	if (!buf)
+		goto exit;
+	
+	while (len > 0) {
+		int translen = (len > 1024) ? 1024 : len;
+		memcpy(buf, data, translen);
+
+		err = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), 0,
+		    USB_DIR_OUT | 0x40, 0, 0, buf, translen,
+		    ZD1201_FW_TIMEOUT);
+		if (err < 0)
+			goto exit;
+
+		len -= translen;
+		data += translen;
+	}
+                                        
+	err = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), 0x2,
+	    USB_DIR_OUT | 0x40, 0, 0, NULL, 0, ZD1201_FW_TIMEOUT);
+	if (err < 0)
+		goto exit;
+
+	err = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), 0x4,
+	    USB_DIR_IN | 0x40, 0,0, &ret, sizeof(ret), ZD1201_FW_TIMEOUT);
+	if (err < 0)
+		goto exit;
+
+	if (ret & 0x80) {
+		err = -EIO;
+		goto exit;
+	}
+
+	err = 0;
+exit:
+	kfree(buf);
+	release_firmware(fw_entry);
+	return err;
+}
+
+static void zd1201_usbfree(struct urb *urb, struct pt_regs *regs)
+{
+	struct zd1201 *zd = urb->context;
+
+	switch(urb->status) {
+		case -EILSEQ:
+		case -ENODEV:
+		case -ETIMEDOUT:
+		case -ENOENT:
+		case -EPIPE:
+		case -EOVERFLOW:
+		case -ESHUTDOWN:
+			dev_warn(&zd->usb->dev, "%s: urb failed: %d\n", 
+			    zd->dev->name, urb->status);
+	}
+
+	kfree(urb->transfer_buffer);
+	usb_free_urb(urb);
+	return;
+}
+
+/* cmdreq message: 
+	u32 type
+	u16 cmd
+	u16 parm0
+	u16 parm1
+	u16 parm2
+	u8  pad[4]
+
+	total: 4 + 2 + 2 + 2 + 2 + 4 = 16
+*/
+static int zd1201_docmd(struct zd1201 *zd, int cmd, int parm0,
+			int parm1, int parm2)
+{
+	unsigned char *command;
+	int ret;
+	struct urb *urb;
+
+	command = kmalloc(16, GFP_ATOMIC);
+	if (!command)
+		return -ENOMEM;
+
+	*((__le32*)command) = cpu_to_le32(ZD1201_USB_CMDREQ);
+	*((__le16*)&command[4]) = cpu_to_le16(cmd);
+	*((__le16*)&command[6]) = cpu_to_le16(parm0);
+	*((__le16*)&command[8]) = cpu_to_le16(parm1);
+	*((__le16*)&command[10])= cpu_to_le16(parm2);
+
+	urb = usb_alloc_urb(0, GFP_ATOMIC);
+	if (!urb) {
+		kfree(command);
+		return -ENOMEM;
+	}
+	usb_fill_bulk_urb(urb, zd->usb, usb_sndbulkpipe(zd->usb, zd->endp_out2),
+			  command, 16, zd1201_usbfree, zd);
+	ret = usb_submit_urb(urb, GFP_ATOMIC);
+	if (ret) {
+		kfree(command);
+		usb_free_urb(urb);
+	}
+
+	return ret;
+}
+
+/* Callback after sending out a packet */
+static void zd1201_usbtx(struct urb *urb, struct pt_regs *regs)
+{
+	struct zd1201 *zd = urb->context;
+	netif_wake_queue(zd->dev);
+	return;
+}
+
+/* Incoming data */
+static void zd1201_usbrx(struct urb *urb, struct pt_regs *regs)
+{
+	struct zd1201 *zd = urb->context;
+	int free = 0;
+	unsigned char *data = urb->transfer_buffer;
+	struct sk_buff *skb;
+	unsigned char type;
+
+	if (!zd) {
+		free = 1;
+		goto exit;
+	}
+
+	switch(urb->status) {
+		case -EILSEQ:
+		case -ENODEV:
+		case -ETIMEDOUT:
+		case -ENOENT:
+		case -EPIPE:
+		case -EOVERFLOW:
+		case -ESHUTDOWN:
+			dev_warn(&zd->usb->dev, "%s: rx urb failed: %d\n",
+			    zd->dev->name, urb->status);
+			free = 1;
+			goto exit;
+	}
+	
+	if (urb->status != 0 || urb->actual_length == 0)
+		goto resubmit;
+
+	type = data[0];
+	if (type == ZD1201_PACKET_EVENTSTAT || type == ZD1201_PACKET_RESOURCE) {
+		memcpy(zd->rxdata, data, urb->actual_length);
+		zd->rxlen = urb->actual_length;
+		zd->rxdatas = 1;
+		wake_up(&zd->rxdataq);
+	}
+	/* Info frame */
+	if (type == ZD1201_PACKET_INQUIRE) {
+		int i = 0;
+		unsigned short infotype, framelen, copylen;
+		framelen = le16_to_cpu(*(__le16*)&data[4]);
+		infotype = le16_to_cpu(*(__le16*)&data[6]);
+
+		if (infotype == ZD1201_INF_LINKSTATUS) {
+			short linkstatus;
+
+			linkstatus = le16_to_cpu(*(__le16*)&data[8]);
+			switch(linkstatus) {
+				case 1:
+					netif_carrier_on(zd->dev);
+					break;
+				case 2:
+					netif_carrier_off(zd->dev);
+					break;
+				case 3:
+					netif_carrier_off(zd->dev);
+					break;
+				case 4:
+					netif_carrier_on(zd->dev);
+					break;
+				default:
+					netif_carrier_off(zd->dev);
+			}
+			goto resubmit;
+		}
+		if (infotype == ZD1201_INF_ASSOCSTATUS) {
+			short status = le16_to_cpu(*(__le16*)(data+8));
+			int event;
+			union iwreq_data wrqu;
+
+			switch (status) {
+				case ZD1201_ASSOCSTATUS_STAASSOC:
+				case ZD1201_ASSOCSTATUS_REASSOC:
+					event = IWEVREGISTERED;
+					break;
+				case ZD1201_ASSOCSTATUS_DISASSOC:
+				case ZD1201_ASSOCSTATUS_ASSOCFAIL:
+				case ZD1201_ASSOCSTATUS_AUTHFAIL:
+				default:
+					event = IWEVEXPIRED;
+			}
+			memcpy(wrqu.addr.sa_data, data+10, ETH_ALEN);
+			wrqu.addr.sa_family = ARPHRD_ETHER;
+
+			/* Send event to user space */
+			wireless_send_event(zd->dev, event, &wrqu, NULL);
+
+			goto resubmit;
+		}
+		if (infotype == ZD1201_INF_AUTHREQ) {
+			union iwreq_data wrqu;
+
+			memcpy(wrqu.addr.sa_data, data+8, ETH_ALEN);
+			wrqu.addr.sa_family = ARPHRD_ETHER;
+			/* There isn't a event that trully fits this request.
+			   We assume that userspace will be smart enough to
+			   see a new station being expired and sends back a
+			   authstation ioctl to authorize it. */
+			wireless_send_event(zd->dev, IWEVEXPIRED, &wrqu, NULL);
+			goto resubmit;
+		}
+		/* Other infotypes are handled outside this handler */
+		zd->rxlen = 0;
+		while (i < urb->actual_length) {
+			copylen = le16_to_cpu(*(__le16*)&data[i+2]);
+			/* Sanity check, sometimes we get junk */
+			if (copylen+zd->rxlen > sizeof(zd->rxdata))
+				break;
+			memcpy(zd->rxdata+zd->rxlen, data+i+4, copylen);
+			zd->rxlen += copylen;
+			i += 64;
+		}
+		if (i >= urb->actual_length) {
+			zd->rxdatas = 1;
+			wake_up(&zd->rxdataq);
+		}
+		goto  resubmit;
+	}
+	/* Actual data */
+	if (data[urb->actual_length-1] == ZD1201_PACKET_RXDATA) {
+		int datalen = urb->actual_length-1;
+		unsigned short len, fc, seq;
+		struct hlist_node *node;
+
+		len = ntohs(*(__be16 *)&data[datalen-2]);
+		if (len>datalen)
+			len=datalen;
+		fc = le16_to_cpu(*(__le16 *)&data[datalen-16]);
+		seq = le16_to_cpu(*(__le16 *)&data[datalen-24]);
+
+		if (zd->monitor) {
+			if (datalen < 24)
+				goto resubmit;
+			if (!(skb = dev_alloc_skb(datalen+24)))
+				goto resubmit;
+			
+			memcpy(skb_put(skb, 2), &data[datalen-16], 2);
+			memcpy(skb_put(skb, 2), &data[datalen-2], 2);
+			memcpy(skb_put(skb, 6), &data[datalen-14], 6);
+			memcpy(skb_put(skb, 6), &data[datalen-22], 6);
+			memcpy(skb_put(skb, 6), &data[datalen-8], 6);
+			memcpy(skb_put(skb, 2), &data[datalen-24], 2);
+			memcpy(skb_put(skb, len), data, len);
+			skb->dev = zd->dev;
+			skb->dev->last_rx = jiffies;
+			skb->protocol = eth_type_trans(skb, zd->dev);
+			zd->stats.rx_packets++;
+			zd->stats.rx_bytes += skb->len;
+			netif_rx(skb);
+			goto resubmit;
+		}
+			
+		if ((seq & IEEE80211_SCTL_FRAG) ||
+		    (fc & IEEE80211_FCTL_MOREFRAGS)) {
+			struct zd1201_frag *frag = NULL;
+			char *ptr;
+
+			if (datalen<14)
+				goto resubmit;
+			if ((seq & IEEE80211_SCTL_FRAG) == 0) {
+				frag = kmalloc(sizeof(*frag), GFP_ATOMIC);
+				if (!frag)
+					goto resubmit;
+				skb = dev_alloc_skb(IEEE80211_DATA_LEN +14+2);
+				if (!skb) {
+					kfree(frag);
+					goto resubmit;
+				}
+				frag->skb = skb;
+				frag->seq = seq & IEEE80211_SCTL_SEQ;
+				skb_reserve(skb, 2);
+				memcpy(skb_put(skb, 12), &data[datalen-14], 12);
+				memcpy(skb_put(skb, 2), &data[6], 2);
+				memcpy(skb_put(skb, len), data+8, len);
+				hlist_add_head(&frag->fnode, &zd->fraglist);
+				goto resubmit;
+			}
+			hlist_for_each_entry(frag, node, &zd->fraglist, fnode)
+				if (frag->seq == (seq&IEEE80211_SCTL_SEQ))
+					break;
+			if (!frag)
+				goto resubmit;
+			skb = frag->skb;
+			ptr = skb_put(skb, len);
+			if (ptr)
+				memcpy(ptr, data+8, len);
+			if (fc & IEEE80211_FCTL_MOREFRAGS)
+				goto resubmit;
+			hlist_del_init(&frag->fnode);
+			kfree(frag);
+		} else {
+			if (datalen<14)
+				goto resubmit;
+			skb = dev_alloc_skb(len + 14 + 2);
+			if (!skb)
+				goto resubmit;
+			skb_reserve(skb, 2);
+			memcpy(skb_put(skb, 12), &data[datalen-14], 12);
+			memcpy(skb_put(skb, 2), &data[6], 2);
+			memcpy(skb_put(skb, len), data+8, len);
+		}
+		skb->dev = zd->dev;
+		skb->dev->last_rx = jiffies;
+		skb->protocol = eth_type_trans(skb, zd->dev);
+		zd->stats.rx_packets++;
+		zd->stats.rx_bytes += skb->len;
+		netif_rx(skb);
+	}
+resubmit:
+	memset(data, 0, ZD1201_RXSIZE);
+
+	urb->status = 0;
+	urb->dev = zd->usb;
+	if(usb_submit_urb(urb, GFP_ATOMIC))
+		free = 1;
+
+exit:
+	if (free) {
+		zd->rxlen = 0;
+		zd->rxdatas = 1;
+		wake_up(&zd->rxdataq);
+		kfree(urb->transfer_buffer);
+	}
+	return;
+}
+
+static int zd1201_getconfig(struct zd1201 *zd, int rid, void *riddata,
+	unsigned int riddatalen)
+{
+	int err;
+	int i = 0;
+	int code;
+	int rid_fid;
+	int length;
+	unsigned char *pdata;
+
+	zd->rxdatas = 0;
+	err = zd1201_docmd(zd, ZD1201_CMDCODE_ACCESS, rid, 0, 0);
+	if (err)
+		return err;
+
+	wait_event_interruptible(zd->rxdataq, zd->rxdatas);
+	if (!zd->rxlen)
+		return -EIO;
+
+	code = le16_to_cpu(*(__le16*)(&zd->rxdata[4]));
+	rid_fid = le16_to_cpu(*(__le16*)(&zd->rxdata[6]));
+	length = le16_to_cpu(*(__le16*)(&zd->rxdata[8]));
+	if (length > zd->rxlen)
+		length = zd->rxlen-6;
+
+	/* If access bit is not on, then error */
+	if ((code & ZD1201_ACCESSBIT) != ZD1201_ACCESSBIT || rid_fid != rid )
+		return -EINVAL;
+
+	/* Not enough buffer for allocating data */
+	if (riddatalen != (length - 4)) {
+		dev_dbg(&zd->usb->dev, "riddatalen mismatches, expected=%u, (packet=%u) length=%u, rid=0x%04X, rid_fid=0x%04X\n",
+		    riddatalen, zd->rxlen, length, rid, rid_fid);
+		return -ENODATA;
+	}
+
+	zd->rxdatas = 0;
+	/* Issue SetRxRid commnd */			
+	err = zd1201_docmd(zd, ZD1201_CMDCODE_SETRXRID, rid, 0, length);
+	if (err)
+		return err;
+
+	/* Receive RID record from resource packets */
+	wait_event_interruptible(zd->rxdataq, zd->rxdatas);
+	if (!zd->rxlen)
+		return -EIO;
+
+	if (zd->rxdata[zd->rxlen - 1] != ZD1201_PACKET_RESOURCE) {
+		dev_dbg(&zd->usb->dev, "Packet type mismatch: 0x%x not 0x3\n",
+		    zd->rxdata[zd->rxlen-1]);
+		return -EINVAL;
+	}
+
+	/* Set the data pointer and received data length */
+	pdata = zd->rxdata;
+	length = zd->rxlen;
+
+	do {
+		int actual_length;
+
+		actual_length = (length > 64) ? 64 : length;
+
+		if (pdata[0] != 0x3) {
+			dev_dbg(&zd->usb->dev, "Rx Resource packet type error: %02X\n",
+			    pdata[0]);
+			return -EINVAL;
+		}
+
+		if (actual_length != 64) {
+			/* Trim the last packet type byte */
+			actual_length--;
+		}
+
+		/* Skip the 4 bytes header (RID length and RID) */
+		if (i == 0) {
+			pdata += 8;
+			actual_length -= 8;
+		} else {
+			pdata += 4;
+			actual_length -= 4;
+		}
+		
+		memcpy(riddata, pdata, actual_length);
+		riddata += actual_length;
+		pdata += actual_length;
+		length -= 64;
+		i++;
+	} while (length > 0);
+
+	return 0;
+}
+
+/*
+ *	resreq:
+ *		byte	type
+ *		byte	sequence
+ *		u16	reserved
+ *		byte	data[12]
+ *	total: 16
+ */
+static int zd1201_setconfig(struct zd1201 *zd, int rid, void *buf, int len, int wait)
+{
+	int err;
+	unsigned char *request;
+	int reqlen;
+	char seq=0;
+	struct urb *urb;
+	gfp_t gfp_mask = wait ? GFP_NOIO : GFP_ATOMIC;
+
+	len += 4;			/* first 4 are for header */
+
+	zd->rxdatas = 0;
+	zd->rxlen = 0;
+	for (seq=0; len > 0; seq++) {
+		request = kmalloc(16, gfp_mask);
+		if (!request)
+			return -ENOMEM;
+		urb = usb_alloc_urb(0, gfp_mask);
+		if (!urb) {
+			kfree(request);
+			return -ENOMEM;
+		}
+		memset(request, 0, 16);
+		reqlen = len>12 ? 12 : len;
+		request[0] = ZD1201_USB_RESREQ;
+		request[1] = seq;
+		request[2] = 0;
+		request[3] = 0;
+		if (request[1] == 0) {
+			/* add header */
+			*(__le16*)&request[4] = cpu_to_le16((len-2+1)/2);
+			*(__le16*)&request[6] = cpu_to_le16(rid);
+			memcpy(request+8, buf, reqlen-4);
+			buf += reqlen-4;
+		} else {
+			memcpy(request+4, buf, reqlen);
+			buf += reqlen;
+		}
+
+		len -= reqlen;
+
+		usb_fill_bulk_urb(urb, zd->usb, usb_sndbulkpipe(zd->usb,
+		    zd->endp_out2), request, 16, zd1201_usbfree, zd);
+		err = usb_submit_urb(urb, gfp_mask);
+		if (err)
+			goto err;
+	}
+
+	request = kmalloc(16, gfp_mask);
+	if (!request)
+		return -ENOMEM;
+	urb = usb_alloc_urb(0, gfp_mask);
+	if (!urb) {
+		kfree(request);
+		return -ENOMEM;
+	}
+	*((__le32*)request) = cpu_to_le32(ZD1201_USB_CMDREQ);
+	*((__le16*)&request[4]) = 
+	    cpu_to_le16(ZD1201_CMDCODE_ACCESS|ZD1201_ACCESSBIT);
+	*((__le16*)&request[6]) = cpu_to_le16(rid);
+	*((__le16*)&request[8]) = cpu_to_le16(0);
+	*((__le16*)&request[10]) = cpu_to_le16(0);
+	usb_fill_bulk_urb(urb, zd->usb, usb_sndbulkpipe(zd->usb, zd->endp_out2),
+	     request, 16, zd1201_usbfree, zd);
+	err = usb_submit_urb(urb, gfp_mask);
+	if (err)
+		goto err;
+	
+	if (wait) {
+		wait_event_interruptible(zd->rxdataq, zd->rxdatas);
+		if (!zd->rxlen || le16_to_cpu(*(__le16*)&zd->rxdata[6]) != rid) {
+			dev_dbg(&zd->usb->dev, "wrong or no RID received\n");
+		}
+	}
+
+	return 0;
+err:
+	kfree(request);
+	usb_free_urb(urb);
+	return err;
+}
+
+static inline int zd1201_getconfig16(struct zd1201 *zd, int rid, short *val)
+{
+	int err;
+	__le16 zdval;
+
+	err = zd1201_getconfig(zd, rid, &zdval, sizeof(__le16));
+	if (err)
+		return err;
+	*val = le16_to_cpu(zdval);
+	return 0;
+}
+
+static inline int zd1201_setconfig16(struct zd1201 *zd, int rid, short val)
+{
+	__le16 zdval = cpu_to_le16(val);
+	return (zd1201_setconfig(zd, rid, &zdval, sizeof(__le16), 1));
+}
+
+static int zd1201_drvr_start(struct zd1201 *zd)
+{
+	int err, i;
+	short max;
+	__le16 zdmax;
+	unsigned char *buffer;
+
+	buffer = kzalloc(ZD1201_RXSIZE, GFP_KERNEL);
+	if (!buffer)
+		return -ENOMEM;
+
+	usb_fill_bulk_urb(zd->rx_urb, zd->usb, 
+	    usb_rcvbulkpipe(zd->usb, zd->endp_in), buffer, ZD1201_RXSIZE,
+	    zd1201_usbrx, zd);
+
+	err = usb_submit_urb(zd->rx_urb, GFP_KERNEL);
+	if (err)
+		goto err_buffer;
+
+	err = zd1201_docmd(zd, ZD1201_CMDCODE_INIT, 0, 0, 0);
+	if (err)
+		goto err_urb;
+
+	err = zd1201_getconfig(zd, ZD1201_RID_CNFMAXTXBUFFERNUMBER, &zdmax,
+	    sizeof(__le16));
+	if (err)
+		goto err_urb;
+
+	max = le16_to_cpu(zdmax);
+	for (i=0; i<max; i++) {
+		err = zd1201_docmd(zd, ZD1201_CMDCODE_ALLOC, 1514, 0, 0);
+		if (err)
+			goto err_urb;
+	}
+
+	return 0;
+
+err_urb:
+	usb_kill_urb(zd->rx_urb);
+	return err;
+err_buffer:
+	kfree(buffer);
+	return err;
+}
+
+/*	Magic alert: The firmware doesn't seem to like the MAC state being
+ *	toggled in promisc (aka monitor) mode.
+ *	(It works a number of times, but will halt eventually)
+ *	So we turn it of before disabling and on after enabling if needed.
+ */
+static int zd1201_enable(struct zd1201 *zd)
+{
+	int err;
+
+	if (zd->mac_enabled)
+		return 0;
+
+	err = zd1201_docmd(zd, ZD1201_CMDCODE_ENABLE, 0, 0, 0);
+	if (!err)
+		zd->mac_enabled = 1;
+
+	if (zd->monitor)
+		err = zd1201_setconfig16(zd, ZD1201_RID_PROMISCUOUSMODE, 1);
+
+	return err;
+}
+
+static int zd1201_disable(struct zd1201 *zd)
+{
+	int err;
+
+	if (!zd->mac_enabled)
+		return 0;
+	if (zd->monitor) {
+		err = zd1201_setconfig16(zd, ZD1201_RID_PROMISCUOUSMODE, 0);
+		if (err)
+			return err;
+	}
+
+	err = zd1201_docmd(zd, ZD1201_CMDCODE_DISABLE, 0, 0, 0);
+	if (!err)
+		zd->mac_enabled = 0;
+	return err;
+}
+
+static int zd1201_mac_reset(struct zd1201 *zd)
+{
+	if (!zd->mac_enabled)
+		return 0;
+	zd1201_disable(zd);
+	return zd1201_enable(zd);
+}
+
+static int zd1201_join(struct zd1201 *zd, char *essid, int essidlen)
+{
+	int err, val;
+	char buf[IW_ESSID_MAX_SIZE+2];
+
+	err = zd1201_disable(zd);
+	if (err)
+		return err;
+
+	val = ZD1201_CNFAUTHENTICATION_OPENSYSTEM;
+	val |= ZD1201_CNFAUTHENTICATION_SHAREDKEY;
+	err = zd1201_setconfig16(zd, ZD1201_RID_CNFAUTHENTICATION, val);
+	if (err)
+		return err;
+
+	*(__le16 *)buf = cpu_to_le16(essidlen);
+	memcpy(buf+2, essid, essidlen);
+	if (!zd->ap) {	/* Normal station */
+		err = zd1201_setconfig(zd, ZD1201_RID_CNFDESIREDSSID, buf,
+		    IW_ESSID_MAX_SIZE+2, 1);
+		if (err)
+			return err;
+	} else {	/* AP */
+		err = zd1201_setconfig(zd, ZD1201_RID_CNFOWNSSID, buf,
+		    IW_ESSID_MAX_SIZE+2, 1);
+		if (err)
+			return err;
+	}
+
+	err = zd1201_setconfig(zd, ZD1201_RID_CNFOWNMACADDR, 
+	    zd->dev->dev_addr, zd->dev->addr_len, 1);
+	if (err)
+		return err;
+
+	err = zd1201_enable(zd);
+	if (err)
+		return err;
+
+	msleep(100);
+	return 0;
+}
+
+static int zd1201_net_open(struct net_device *dev)
+{
+	struct zd1201 *zd = (struct zd1201 *)dev->priv;
+
+	/* Start MAC with wildcard if no essid set */
+	if (!zd->mac_enabled)
+		zd1201_join(zd, zd->essid, zd->essidlen);
+	netif_start_queue(dev);
+
+	return 0;
+}
+
+static int zd1201_net_stop(struct net_device *dev)
+{
+	netif_stop_queue(dev);
+	return 0;
+}
+
+/*
+	RFC 1042 encapsulates Ethernet frames in 802.11 frames
+	by prefixing them with 0xaa, 0xaa, 0x03) followed by a SNAP OID of 0
+	(0x00, 0x00, 0x00). Zd requires an additional padding, copy
+	of ethernet addresses, length of the standard RFC 1042 packet
+	and a command byte (which is nul for tx).
+	
+	tx frame (from Wlan NG):
+	RFC 1042:
+		llc		0xAA 0xAA 0x03 (802.2 LLC)
+		snap		0x00 0x00 0x00 (Ethernet encapsulated)
+		type		2 bytes, Ethernet type field
+		payload		(minus eth header)
+	Zydas specific:
+		padding		1B if (skb->len+8+1)%64==0
+		Eth MAC addr	12 bytes, Ethernet MAC addresses
+		length		2 bytes, RFC 1042 packet length 
+				(llc+snap+type+payload)
+		zd		1 null byte, zd1201 packet type
+ */
+static int zd1201_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+	struct zd1201 *zd = (struct zd1201 *)dev->priv;
+	unsigned char *txbuf = zd->txdata;
+	int txbuflen, pad = 0, err;
+	struct urb *urb = zd->tx_urb;
+
+	if (!zd->mac_enabled || zd->monitor) {
+		zd->stats.tx_dropped++;
+		kfree_skb(skb);
+		return 0;
+	}
+	netif_stop_queue(dev);
+
+	txbuflen = skb->len + 8 + 1;
+	if (txbuflen%64 == 0) {
+		pad = 1;
+		txbuflen++;
+	}
+	txbuf[0] = 0xAA;
+	txbuf[1] = 0xAA;
+	txbuf[2] = 0x03;
+	txbuf[3] = 0x00;	/* rfc1042 */
+	txbuf[4] = 0x00;
+	txbuf[5] = 0x00;
+
+	memcpy(txbuf+6, skb->data+12, skb->len-12);
+	if (pad)
+		txbuf[skb->len-12+6]=0;
+	memcpy(txbuf+skb->len-12+6+pad, skb->data, 12);
+	*(__be16*)&txbuf[skb->len+6+pad] = htons(skb->len-12+6);
+	txbuf[txbuflen-1] = 0;
+
+	usb_fill_bulk_urb(urb, zd->usb, usb_sndbulkpipe(zd->usb, zd->endp_out),
+	    txbuf, txbuflen, zd1201_usbtx, zd);
+
+	err = usb_submit_urb(zd->tx_urb, GFP_ATOMIC);
+	if (err) {
+		zd->stats.tx_errors++;
+		netif_start_queue(dev);
+		return err;
+	}
+	zd->stats.tx_packets++;
+	zd->stats.tx_bytes += skb->len;
+	dev->trans_start = jiffies;
+	kfree_skb(skb);
+
+	return 0;
+}
+
+static void zd1201_tx_timeout(struct net_device *dev)
+{
+	struct zd1201 *zd = (struct zd1201 *)dev->priv;
+
+	if (!zd)
+		return;
+	dev_warn(&zd->usb->dev, "%s: TX timeout, shooting down urb\n",
+	    dev->name);
+	usb_unlink_urb(zd->tx_urb);
+	zd->stats.tx_errors++;
+	/* Restart the timeout to quiet the watchdog: */
+	dev->trans_start = jiffies;
+}
+
+static int zd1201_set_mac_address(struct net_device *dev, void *p)
+{
+	struct sockaddr *addr = p;
+	struct zd1201 *zd = (struct zd1201 *)dev->priv;
+	int err;
+
+	if (!zd)
+		return -ENODEV;
+
+	err = zd1201_setconfig(zd, ZD1201_RID_CNFOWNMACADDR, 
+	    addr->sa_data, dev->addr_len, 1);
+	if (err)
+		return err;
+	memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
+
+	return zd1201_mac_reset(zd);
+}
+
+static struct net_device_stats *zd1201_get_stats(struct net_device *dev)
+{
+	struct zd1201 *zd = (struct zd1201 *)dev->priv;
+
+	return &zd->stats;
+}
+
+static struct iw_statistics *zd1201_get_wireless_stats(struct net_device *dev)
+{
+	struct zd1201 *zd = (struct zd1201 *)dev->priv;
+
+	return &zd->iwstats;
+}
+
+static void zd1201_set_multicast(struct net_device *dev)
+{
+	struct zd1201 *zd = (struct zd1201 *)dev->priv;
+	struct dev_mc_list *mc = dev->mc_list;
+	unsigned char reqbuf[ETH_ALEN*ZD1201_MAXMULTI];
+	int i;
+
+	if (dev->mc_count > ZD1201_MAXMULTI)
+		return;
+
+	for (i=0; i<dev->mc_count; i++) {
+		memcpy(reqbuf+i*ETH_ALEN, mc->dmi_addr, ETH_ALEN);
+		mc = mc->next;
+	}
+	zd1201_setconfig(zd, ZD1201_RID_CNFGROUPADDRESS, reqbuf,
+	    dev->mc_count*ETH_ALEN, 0);
+	
+}
+
+static int zd1201_config_commit(struct net_device *dev, 
+    struct iw_request_info *info, struct iw_point *data, char *essid)
+{
+	struct zd1201 *zd = (struct zd1201 *)dev->priv;
+
+	return zd1201_mac_reset(zd);
+}
+
+static int zd1201_get_name(struct net_device *dev,
+    struct iw_request_info *info, char *name, char *extra)
+{
+	strcpy(name, "IEEE 802.11b");
+	return 0;
+}
+
+static int zd1201_set_freq(struct net_device *dev,
+    struct iw_request_info *info, struct iw_freq *freq, char *extra)
+{
+	struct zd1201 *zd = (struct zd1201 *)dev->priv;
+	short channel = 0;
+	int err;
+
+	if (freq->e == 0)
+		channel = freq->m;
+	else {
+		if (freq->m >= 2482)
+			channel = 14;
+		if (freq->m >= 2407)
+			channel = (freq->m-2407)/5;
+	}
+
+	err = zd1201_setconfig16(zd, ZD1201_RID_CNFOWNCHANNEL, channel);
+	if (err)
+		return err;
+
+	zd1201_mac_reset(zd);
+
+	return 0;
+}
+
+static int zd1201_get_freq(struct net_device *dev,
+    struct iw_request_info *info, struct iw_freq *freq, char *extra)
+{
+	struct zd1201 *zd = (struct zd1201 *)dev->priv;
+	short channel;
+	int err;
+
+	err = zd1201_getconfig16(zd, ZD1201_RID_CNFOWNCHANNEL, &channel);
+	if (err)
+		return err;
+	freq->e = 0;
+	freq->m = channel;
+
+	return 0;
+}
+
+static int zd1201_set_mode(struct net_device *dev,
+    struct iw_request_info *info, __u32 *mode, char *extra)
+{
+	struct zd1201 *zd = (struct zd1201 *)dev->priv;
+	short porttype, monitor = 0;
+	unsigned char buffer[IW_ESSID_MAX_SIZE+2];
+	int err;
+
+	if (zd->ap) {
+		if (*mode != IW_MODE_MASTER)
+			return -EINVAL;
+		return 0;
+	}
+
+	err = zd1201_setconfig16(zd, ZD1201_RID_PROMISCUOUSMODE, 0);
+	if (err)
+		return err;
+	zd->dev->type = ARPHRD_ETHER;
+	switch(*mode) {
+		case IW_MODE_MONITOR:
+			monitor = 1;
+			zd->dev->type = ARPHRD_IEEE80211;
+			/* Make sure we are no longer associated with by
+			   setting an 'impossible' essid.
+			   (otherwise we mess up firmware)
+			 */
+			zd1201_join(zd, "\0-*#\0", 5);
+			/* Put port in pIBSS */
+		case 8: /* No pseudo-IBSS in wireless extensions (yet) */
+			porttype = ZD1201_PORTTYPE_PSEUDOIBSS;
+			break;
+		case IW_MODE_ADHOC:
+			porttype = ZD1201_PORTTYPE_IBSS;
+			break;
+		case IW_MODE_INFRA:
+			porttype = ZD1201_PORTTYPE_BSS;
+			break;
+		default:
+			return -EINVAL;
+	}
+
+	err = zd1201_setconfig16(zd, ZD1201_RID_CNFPORTTYPE, porttype);
+	if (err)
+		return err;
+	if (zd->monitor && !monitor) {
+			zd1201_disable(zd);
+			*(__le16 *)buffer = cpu_to_le16(zd->essidlen);
+			memcpy(buffer+2, zd->essid, zd->essidlen);
+			err = zd1201_setconfig(zd, ZD1201_RID_CNFDESIREDSSID,
+			    buffer, IW_ESSID_MAX_SIZE+2, 1);
+			if (err)
+				return err;
+	}
+	zd->monitor = monitor;
+	/* If monitor mode is set we don't actually turn it on here since it
+	 * is done during mac reset anyway (see zd1201_mac_enable).
+	 */
+	zd1201_mac_reset(zd);
+
+	return 0;
+}
+
+static int zd1201_get_mode(struct net_device *dev,
+    struct iw_request_info *info, __u32 *mode, char *extra)
+{
+	struct zd1201 *zd = (struct zd1201 *)dev->priv;
+	short porttype;
+	int err;
+
+	err = zd1201_getconfig16(zd, ZD1201_RID_CNFPORTTYPE, &porttype);
+	if (err)
+		return err;
+	switch(porttype) {
+		case ZD1201_PORTTYPE_IBSS:
+			*mode = IW_MODE_ADHOC;
+			break;
+		case ZD1201_PORTTYPE_BSS:
+			*mode = IW_MODE_INFRA;
+			break;
+		case ZD1201_PORTTYPE_WDS:
+			*mode = IW_MODE_REPEAT;
+			break;
+		case ZD1201_PORTTYPE_PSEUDOIBSS:
+			*mode = 8;/* No Pseudo-IBSS... */
+			break;
+		case ZD1201_PORTTYPE_AP:
+			*mode = IW_MODE_MASTER;
+			break;
+		default:
+			dev_dbg(&zd->usb->dev, "Unknown porttype: %d\n",
+			    porttype);
+			*mode = IW_MODE_AUTO;
+	}
+	if (zd->monitor)
+		*mode = IW_MODE_MONITOR;
+
+	return 0;
+}
+
+static int zd1201_get_range(struct net_device *dev,
+    struct iw_request_info *info, struct iw_point *wrq, char *extra)
+{
+	struct iw_range *range = (struct iw_range *)extra;
+
+	wrq->length = sizeof(struct iw_range);
+	memset(range, 0, sizeof(struct iw_range));
+	range->we_version_compiled = WIRELESS_EXT;
+	range->we_version_source = WIRELESS_EXT;
+
+	range->max_qual.qual = 128;
+	range->max_qual.level = 128;
+	range->max_qual.noise = 128;
+	range->max_qual.updated = 7;
+
+	range->encoding_size[0] = 5;
+	range->encoding_size[1] = 13;
+	range->num_encoding_sizes = 2;
+	range->max_encoding_tokens = ZD1201_NUMKEYS;
+
+	range->num_bitrates = 4;
+	range->bitrate[0] = 1000000;
+	range->bitrate[1] = 2000000;
+	range->bitrate[2] = 5500000;
+	range->bitrate[3] = 11000000;
+
+	range->min_rts = 0;
+	range->min_frag = ZD1201_FRAGMIN;
+	range->max_rts = ZD1201_RTSMAX;
+	range->min_frag = ZD1201_FRAGMAX;
+
+	return 0;
+}
+
+/*	Little bit of magic here: we only get the quality if we poll
+ *	for it, and we never get an actual request to trigger such
+ *	a poll. Therefore we 'assume' that the user will soon ask for
+ *	the stats after asking the bssid.
+ */
+static int zd1201_get_wap(struct net_device *dev,
+    struct iw_request_info *info, struct sockaddr *ap_addr, char *extra)
+{
+	struct zd1201 *zd = (struct zd1201 *)dev->priv;
+	unsigned char buffer[6];
+
+	if (!zd1201_getconfig(zd, ZD1201_RID_COMMSQUALITY, buffer, 6)) {
+		/* Unfortunately the quality and noise reported is useless.
+		   they seem to be accumulators that increase until you
+		   read them, unless we poll on a fixed interval we can't
+		   use them
+		 */
+		/*zd->iwstats.qual.qual = le16_to_cpu(((__le16 *)buffer)[0]);*/
+		zd->iwstats.qual.level = le16_to_cpu(((__le16 *)buffer)[1]);
+		/*zd->iwstats.qual.noise = le16_to_cpu(((__le16 *)buffer)[2]);*/
+		zd->iwstats.qual.updated = 2;
+	}
+
+	return zd1201_getconfig(zd, ZD1201_RID_CURRENTBSSID, ap_addr->sa_data, 6);
+}
+
+static int zd1201_set_scan(struct net_device *dev,
+    struct iw_request_info *info, struct iw_point *srq, char *extra)
+{
+	/* We do everything in get_scan */
+	return 0;
+}
+
+static int zd1201_get_scan(struct net_device *dev,
+    struct iw_request_info *info, struct iw_point *srq, char *extra)
+{
+	struct zd1201 *zd = (struct zd1201 *)dev->priv;
+	int err, i, j, enabled_save;
+	struct iw_event iwe;
+	char *cev = extra;
+	char *end_buf = extra + IW_SCAN_MAX_DATA;
+
+	/* No scanning in AP mode */
+	if (zd->ap)
+		return -EOPNOTSUPP;
+
+	/* Scan doesn't seem to work if disabled */
+	enabled_save = zd->mac_enabled;
+	zd1201_enable(zd);
+
+	zd->rxdatas = 0;
+	err = zd1201_docmd(zd, ZD1201_CMDCODE_INQUIRE, 
+	     ZD1201_INQ_SCANRESULTS, 0, 0);
+	if (err)
+		return err;
+
+	wait_event_interruptible(zd->rxdataq, zd->rxdatas);
+	if (!zd->rxlen)
+		return -EIO;
+
+	if (le16_to_cpu(*(__le16*)&zd->rxdata[2]) != ZD1201_INQ_SCANRESULTS)
+		return -EIO;
+
+	for(i=8; i<zd->rxlen; i+=62) {
+		iwe.cmd = SIOCGIWAP;
+		iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
+		memcpy(iwe.u.ap_addr.sa_data, zd->rxdata+i+6, 6);
+		cev = iwe_stream_add_event(cev, end_buf, &iwe, IW_EV_ADDR_LEN);
+
+		iwe.cmd = SIOCGIWESSID;
+		iwe.u.data.length = zd->rxdata[i+16];
+		iwe.u.data.flags = 1;
+		cev = iwe_stream_add_point(cev, end_buf, &iwe, zd->rxdata+i+18);
+
+		iwe.cmd = SIOCGIWMODE;
+		if (zd->rxdata[i+14]&0x01)
+			iwe.u.mode = IW_MODE_MASTER;
+		else
+			iwe.u.mode = IW_MODE_ADHOC;
+		cev = iwe_stream_add_event(cev, end_buf, &iwe, IW_EV_UINT_LEN);
+		
+		iwe.cmd = SIOCGIWFREQ;
+		iwe.u.freq.m = zd->rxdata[i+0];
+		iwe.u.freq.e = 0;
+		cev = iwe_stream_add_event(cev, end_buf, &iwe, IW_EV_FREQ_LEN);
+		
+		iwe.cmd = SIOCGIWRATE;
+		iwe.u.bitrate.fixed = 0;
+		iwe.u.bitrate.disabled = 0;
+		for (j=0; j<10; j++) if (zd->rxdata[i+50+j]) {
+			iwe.u.bitrate.value = (zd->rxdata[i+50+j]&0x7f)*500000;
+			cev=iwe_stream_add_event(cev, end_buf, &iwe,
+			    IW_EV_PARAM_LEN);
+		}
+		
+		iwe.cmd = SIOCGIWENCODE;
+		iwe.u.data.length = 0;
+		if (zd->rxdata[i+14]&0x10)
+			iwe.u.data.flags = IW_ENCODE_ENABLED;
+		else
+			iwe.u.data.flags = IW_ENCODE_DISABLED;
+		cev = iwe_stream_add_point(cev, end_buf, &iwe, NULL);
+		
+		iwe.cmd = IWEVQUAL;
+		iwe.u.qual.qual = zd->rxdata[i+4];
+		iwe.u.qual.noise= zd->rxdata[i+2]/10-100;
+		iwe.u.qual.level = (256+zd->rxdata[i+4]*100)/255-100;
+		iwe.u.qual.updated = 7;
+		cev = iwe_stream_add_event(cev, end_buf, &iwe, IW_EV_QUAL_LEN);
+	}
+
+	if (!enabled_save)
+		zd1201_disable(zd);
+
+	srq->length = cev - extra;
+	srq->flags = 0;
+
+	return 0;
+}
+
+static int zd1201_set_essid(struct net_device *dev,
+    struct iw_request_info *info, struct iw_point *data, char *essid)
+{
+	struct zd1201 *zd = (struct zd1201 *)dev->priv;
+
+	if (data->length > IW_ESSID_MAX_SIZE)
+		return -EINVAL;
+	if (data->length < 1)
+		data->length = 1;
+	zd->essidlen = data->length-1;
+	memset(zd->essid, 0, IW_ESSID_MAX_SIZE+1);
+	memcpy(zd->essid, essid, data->length);
+	return zd1201_join(zd, zd->essid, zd->essidlen);
+}
+
+static int zd1201_get_essid(struct net_device *dev,
+    struct iw_request_info *info, struct iw_point *data, char *essid)
+{
+	struct zd1201 *zd = (struct zd1201 *)dev->priv;
+
+	memcpy(essid, zd->essid, zd->essidlen);
+	data->flags = 1;
+	data->length = zd->essidlen;
+
+	return 0;
+}
+
+static int zd1201_get_nick(struct net_device *dev, struct iw_request_info *info,
+    struct iw_point *data, char *nick)
+{
+	strcpy(nick, "zd1201");
+	data->flags = 1;
+	data->length = strlen(nick);
+	return 0;
+}
+
+static int zd1201_set_rate(struct net_device *dev,
+    struct iw_request_info *info, struct iw_param *rrq, char *extra)
+{
+	struct zd1201 *zd = (struct zd1201 *)dev->priv;
+	short rate;
+	int err;
+
+	switch (rrq->value) {
+		case 1000000:
+			rate = ZD1201_RATEB1;
+			break;
+		case 2000000:
+			rate = ZD1201_RATEB2;
+			break;
+		case 5500000:
+			rate = ZD1201_RATEB5;
+			break;
+		case 11000000:
+		default:
+			rate = ZD1201_RATEB11;
+			break;
+	}
+	if (!rrq->fixed) { /* Also enable all lower bitrates */
+		rate |= rate-1;
+	}
+
+	err = zd1201_setconfig16(zd, ZD1201_RID_TXRATECNTL, rate);
+	if (err)
+		return err;
+
+	return zd1201_mac_reset(zd);
+}
+
+static int zd1201_get_rate(struct net_device *dev,
+    struct iw_request_info *info, struct iw_param *rrq, char *extra)
+{
+	struct zd1201 *zd = (struct zd1201 *)dev->priv;
+	short rate;
+	int err;
+
+	err = zd1201_getconfig16(zd, ZD1201_RID_CURRENTTXRATE, &rate);
+	if (err)
+		return err;
+
+	switch(rate) {
+		case 1:
+			rrq->value = 1000000;
+			break;
+		case 2:
+			rrq->value = 2000000;
+			break;
+		case 5:
+			rrq->value = 5500000;
+			break;
+		case 11:
+			rrq->value = 11000000;
+			break;
+		default:
+			rrq->value = 0;
+	}
+	rrq->fixed = 0;
+	rrq->disabled = 0;
+
+	return 0;
+}
+
+static int zd1201_set_rts(struct net_device *dev, struct iw_request_info *info,
+    struct iw_param *rts, char *extra)
+{
+	struct zd1201 *zd = (struct zd1201 *)dev->priv;
+	int err;
+	short val = rts->value;
+
+	if (rts->disabled || !rts->fixed)
+		val = ZD1201_RTSMAX;
+	if (val > ZD1201_RTSMAX)
+		return -EINVAL;
+	if (val < 0)
+		return -EINVAL;
+
+	err = zd1201_setconfig16(zd, ZD1201_RID_CNFRTSTHRESHOLD, val);
+	if (err)
+		return err;
+	return zd1201_mac_reset(zd);
+}
+
+static int zd1201_get_rts(struct net_device *dev, struct iw_request_info *info,
+    struct iw_param *rts, char *extra)
+{
+	struct zd1201 *zd = (struct zd1201 *)dev->priv;
+	short rtst;
+	int err;
+
+	err = zd1201_getconfig16(zd, ZD1201_RID_CNFRTSTHRESHOLD, &rtst);
+	if (err)
+		return err;
+	rts->value = rtst;
+	rts->disabled = (rts->value == ZD1201_RTSMAX);
+	rts->fixed = 1;
+
+	return 0;
+}
+
+static int zd1201_set_frag(struct net_device *dev, struct iw_request_info *info,
+    struct iw_param *frag, char *extra)
+{
+	struct zd1201 *zd = (struct zd1201 *)dev->priv;
+	int err;
+	short val = frag->value;
+
+	if (frag->disabled || !frag->fixed)
+		val = ZD1201_FRAGMAX;
+	if (val > ZD1201_FRAGMAX)
+		return -EINVAL;
+	if (val < ZD1201_FRAGMIN)
+		return -EINVAL;
+	if (val & 1)
+		return -EINVAL;
+	err = zd1201_setconfig16(zd, ZD1201_RID_CNFFRAGTHRESHOLD, val);
+	if (err)
+		return err;
+	return zd1201_mac_reset(zd);
+}
+
+static int zd1201_get_frag(struct net_device *dev, struct iw_request_info *info,
+    struct iw_param *frag, char *extra)
+{
+	struct zd1201 *zd = (struct zd1201 *)dev->priv;
+	short fragt;
+	int err;
+
+	err = zd1201_getconfig16(zd, ZD1201_RID_CNFFRAGTHRESHOLD, &fragt);
+	if (err)
+		return err;
+	frag->value = fragt;
+	frag->disabled = (frag->value == ZD1201_FRAGMAX);
+	frag->fixed = 1;
+
+	return 0;
+}
+
+static int zd1201_set_retry(struct net_device *dev,
+    struct iw_request_info *info, struct iw_param *rrq, char *extra)
+{
+	return 0;
+}
+
+static int zd1201_get_retry(struct net_device *dev,
+    struct iw_request_info *info, struct iw_param *rrq, char *extra)
+{
+	return 0;
+}
+
+static int zd1201_set_encode(struct net_device *dev,
+    struct iw_request_info *info, struct iw_point *erq, char *key)
+{
+	struct zd1201 *zd = (struct zd1201 *)dev->priv;
+	short i;
+	int err, rid;
+
+	if (erq->length > ZD1201_MAXKEYLEN)
+		return -EINVAL;
+
+	i = (erq->flags & IW_ENCODE_INDEX)-1;
+	if (i == -1) {
+		err = zd1201_getconfig16(zd,ZD1201_RID_CNFDEFAULTKEYID,&i);
+		if (err)
+			return err;
+	} else {
+		err = zd1201_setconfig16(zd, ZD1201_RID_CNFDEFAULTKEYID, i);
+		if (err)
+			return err;
+	}
+
+	if (i < 0 || i >= ZD1201_NUMKEYS)
+		return -EINVAL;
+
+	rid = ZD1201_RID_CNFDEFAULTKEY0 + i;
+	err = zd1201_setconfig(zd, rid, key, erq->length, 1);
+	if (err)
+		return err;
+	zd->encode_keylen[i] = erq->length;
+	memcpy(zd->encode_keys[i], key, erq->length);
+
+	i=0;
+	if (!(erq->flags & IW_ENCODE_DISABLED & IW_ENCODE_MODE)) {
+		i |= 0x01;
+		zd->encode_enabled = 1;
+	} else
+		zd->encode_enabled = 0;
+	if (erq->flags & IW_ENCODE_RESTRICTED & IW_ENCODE_MODE) {
+		i |= 0x02;
+		zd->encode_restricted = 1;
+	} else
+		zd->encode_restricted = 0;
+	err = zd1201_setconfig16(zd, ZD1201_RID_CNFWEBFLAGS, i);
+	if (err)
+		return err;
+
+	if (zd->encode_enabled)
+		i = ZD1201_CNFAUTHENTICATION_SHAREDKEY;
+	else
+		i = ZD1201_CNFAUTHENTICATION_OPENSYSTEM;
+	err = zd1201_setconfig16(zd, ZD1201_RID_CNFAUTHENTICATION, i);
+	if (err)
+		return err;
+
+	return zd1201_mac_reset(zd);
+}
+
+static int zd1201_get_encode(struct net_device *dev,
+    struct iw_request_info *info, struct iw_point *erq, char *key)
+{
+	struct zd1201 *zd = (struct zd1201 *)dev->priv;
+	short i;
+	int err;
+
+	if (zd->encode_enabled)
+		erq->flags = IW_ENCODE_ENABLED;
+	else
+		erq->flags = IW_ENCODE_DISABLED;
+	if (zd->encode_restricted)
+		erq->flags |= IW_ENCODE_RESTRICTED;
+	else
+		erq->flags |= IW_ENCODE_OPEN;
+
+	i = (erq->flags & IW_ENCODE_INDEX) -1;
+	if (i == -1) {
+		err = zd1201_getconfig16(zd, ZD1201_RID_CNFDEFAULTKEYID, &i);
+		if (err)
+			return err;
+	}
+	if (i<0 || i>= ZD1201_NUMKEYS)
+		return -EINVAL;
+
+	erq->flags |= i+1;
+
+	erq->length = zd->encode_keylen[i];
+	memcpy(key, zd->encode_keys[i], erq->length);
+
+	return 0;
+}
+
+static int zd1201_set_power(struct net_device *dev, 
+    struct iw_request_info *info, struct iw_param *vwrq, char *extra)
+{
+	struct zd1201 *zd = (struct zd1201 *)dev->priv;
+	short enabled, duration, level;
+	int err;
+
+	enabled = vwrq->disabled ? 0 : 1;
+	if (enabled) {
+		if (vwrq->flags & IW_POWER_PERIOD) {
+			duration = vwrq->value;
+			err = zd1201_setconfig16(zd, 
+			    ZD1201_RID_CNFMAXSLEEPDURATION, duration);
+			if (err)
+				return err;
+			goto out;
+		}
+		if (vwrq->flags & IW_POWER_TIMEOUT) {
+			err = zd1201_getconfig16(zd, 
+			    ZD1201_RID_CNFMAXSLEEPDURATION, &duration);
+			if (err)
+				return err;
+			level = vwrq->value * 4 / duration;
+			if (level > 4)
+				level = 4;
+			if (level < 0)
+				level = 0;
+			err = zd1201_setconfig16(zd, ZD1201_RID_CNFPMEPS,
+			    level);
+			if (err)
+				return err;
+			goto out;
+		}
+		return -EINVAL;
+	}
+out:
+	return zd1201_setconfig16(zd, ZD1201_RID_CNFPMENABLED, enabled);
+}
+
+static int zd1201_get_power(struct net_device *dev,
+    struct iw_request_info *info, struct iw_param *vwrq, char *extra)
+{
+	struct zd1201 *zd = (struct zd1201 *)dev->priv;
+	short enabled, level, duration;
+	int err;
+
+	err = zd1201_getconfig16(zd, ZD1201_RID_CNFPMENABLED, &enabled);
+	if (err)
+		return err;
+	err = zd1201_getconfig16(zd, ZD1201_RID_CNFPMEPS, &level);
+	if (err)
+		return err;
+	err = zd1201_getconfig16(zd, ZD1201_RID_CNFMAXSLEEPDURATION, &duration);
+	if (err)
+		return err;
+	vwrq->disabled = enabled ? 0 : 1;
+	if (vwrq->flags & IW_POWER_TYPE) {
+		if (vwrq->flags & IW_POWER_PERIOD) {
+			vwrq->value = duration;
+			vwrq->flags = IW_POWER_PERIOD;
+		} else {
+			vwrq->value = duration * level / 4;
+			vwrq->flags = IW_POWER_TIMEOUT;
+		}
+	}
+	if (vwrq->flags & IW_POWER_MODE) {
+		if (enabled && level)
+			vwrq->flags = IW_POWER_UNICAST_R;
+		else
+			vwrq->flags = IW_POWER_ALL_R;
+	}
+
+	return 0;
+}
+
+
+static const iw_handler zd1201_iw_handler[] =
+{
+	(iw_handler) zd1201_config_commit,	/* SIOCSIWCOMMIT */
+	(iw_handler) zd1201_get_name,    	/* SIOCGIWNAME */
+	(iw_handler) NULL,			/* SIOCSIWNWID */
+	(iw_handler) NULL,			/* SIOCGIWNWID */
+	(iw_handler) zd1201_set_freq,		/* SIOCSIWFREQ */
+	(iw_handler) zd1201_get_freq,		/* SIOCGIWFREQ */
+	(iw_handler) zd1201_set_mode,		/* SIOCSIWMODE */
+	(iw_handler) zd1201_get_mode,		/* SIOCGIWMODE */
+	(iw_handler) NULL,                  	/* SIOCSIWSENS */
+	(iw_handler) NULL,           		/* SIOCGIWSENS */
+	(iw_handler) NULL,			/* SIOCSIWRANGE */
+	(iw_handler) zd1201_get_range,           /* SIOCGIWRANGE */
+	(iw_handler) NULL,			/* SIOCSIWPRIV */
+	(iw_handler) NULL,			/* SIOCGIWPRIV */
+	(iw_handler) NULL,			/* SIOCSIWSTATS */
+	(iw_handler) NULL,			/* SIOCGIWSTATS */
+	(iw_handler) NULL,			/* SIOCSIWSPY */
+	(iw_handler) NULL,			/* SIOCGIWSPY */
+	(iw_handler) NULL,			/* -- hole -- */
+	(iw_handler) NULL,			/* -- hole -- */
+	(iw_handler) NULL/*zd1201_set_wap*/,		/* SIOCSIWAP */
+	(iw_handler) zd1201_get_wap,		/* SIOCGIWAP */
+	(iw_handler) NULL,			/* -- hole -- */
+	(iw_handler) NULL,       		/* SIOCGIWAPLIST */
+	(iw_handler) zd1201_set_scan,		/* SIOCSIWSCAN */
+	(iw_handler) zd1201_get_scan,		/* SIOCGIWSCAN */
+	(iw_handler) zd1201_set_essid,		/* SIOCSIWESSID */
+	(iw_handler) zd1201_get_essid,		/* SIOCGIWESSID */
+	(iw_handler) NULL,         		/* SIOCSIWNICKN */
+	(iw_handler) zd1201_get_nick, 		/* SIOCGIWNICKN */
+	(iw_handler) NULL,			/* -- hole -- */
+	(iw_handler) NULL,			/* -- hole -- */
+	(iw_handler) zd1201_set_rate,		/* SIOCSIWRATE */
+	(iw_handler) zd1201_get_rate,		/* SIOCGIWRATE */
+	(iw_handler) zd1201_set_rts,		/* SIOCSIWRTS */
+	(iw_handler) zd1201_get_rts,		/* SIOCGIWRTS */
+	(iw_handler) zd1201_set_frag,		/* SIOCSIWFRAG */
+	(iw_handler) zd1201_get_frag,		/* SIOCGIWFRAG */
+	(iw_handler) NULL,         		/* SIOCSIWTXPOW */
+	(iw_handler) NULL,          		/* SIOCGIWTXPOW */
+	(iw_handler) zd1201_set_retry,		/* SIOCSIWRETRY */
+	(iw_handler) zd1201_get_retry,		/* SIOCGIWRETRY */
+	(iw_handler) zd1201_set_encode,		/* SIOCSIWENCODE */
+	(iw_handler) zd1201_get_encode,		/* SIOCGIWENCODE */
+	(iw_handler) zd1201_set_power,		/* SIOCSIWPOWER */
+	(iw_handler) zd1201_get_power,		/* SIOCGIWPOWER */
+};
+
+static int zd1201_set_hostauth(struct net_device *dev,
+    struct iw_request_info *info, struct iw_param *rrq, char *extra)
+{
+	struct zd1201 *zd = (struct zd1201 *)dev->priv;
+
+	if (!zd->ap)
+		return -EOPNOTSUPP;
+
+	return zd1201_setconfig16(zd, ZD1201_RID_CNFHOSTAUTH, rrq->value);
+}
+
+static int zd1201_get_hostauth(struct net_device *dev,
+    struct iw_request_info *info, struct iw_param *rrq, char *extra)
+{
+	struct zd1201 *zd = (struct zd1201 *)dev->priv;
+	short hostauth;
+	int err;
+
+	if (!zd->ap)
+		return -EOPNOTSUPP;
+
+	err = zd1201_getconfig16(zd, ZD1201_RID_CNFHOSTAUTH, &hostauth);
+	if (err)
+		return err;
+	rrq->value = hostauth;
+	rrq->fixed = 1;
+
+	return 0;
+}
+
+static int zd1201_auth_sta(struct net_device *dev,
+    struct iw_request_info *info, struct sockaddr *sta, char *extra)
+{
+	struct zd1201 *zd = (struct zd1201 *)dev->priv;
+	unsigned char buffer[10];
+
+	if (!zd->ap)
+		return -EOPNOTSUPP;
+
+	memcpy(buffer, sta->sa_data, ETH_ALEN);
+	*(short*)(buffer+6) = 0;	/* 0==success, 1==failure */
+	*(short*)(buffer+8) = 0;
+
+	return zd1201_setconfig(zd, ZD1201_RID_AUTHENTICATESTA, buffer, 10, 1);
+}
+
+static int zd1201_set_maxassoc(struct net_device *dev,
+    struct iw_request_info *info, struct iw_param *rrq, char *extra)
+{
+	struct zd1201 *zd = (struct zd1201 *)dev->priv;
+	int err;
+
+	if (!zd->ap)
+		return -EOPNOTSUPP;
+
+	err = zd1201_setconfig16(zd, ZD1201_RID_CNFMAXASSOCSTATIONS, rrq->value);
+	if (err)
+		return err;
+	return 0;
+}
+
+static int zd1201_get_maxassoc(struct net_device *dev,
+    struct iw_request_info *info, struct iw_param *rrq, char *extra)
+{
+	struct zd1201 *zd = (struct zd1201 *)dev->priv;
+	short maxassoc;
+	int err;
+
+	if (!zd->ap)
+		return -EOPNOTSUPP;
+
+	err = zd1201_getconfig16(zd, ZD1201_RID_CNFMAXASSOCSTATIONS, &maxassoc);
+	if (err)
+		return err;
+	rrq->value = maxassoc;
+	rrq->fixed = 1;
+
+	return 0;
+}
+
+static const iw_handler zd1201_private_handler[] = {
+	(iw_handler) zd1201_set_hostauth,	/* ZD1201SIWHOSTAUTH */
+	(iw_handler) zd1201_get_hostauth,	/* ZD1201GIWHOSTAUTH */
+	(iw_handler) zd1201_auth_sta,		/* ZD1201SIWAUTHSTA */
+	(iw_handler) NULL,			/* nothing to get */
+	(iw_handler) zd1201_set_maxassoc,	/* ZD1201SIMAXASSOC */
+	(iw_handler) zd1201_get_maxassoc,	/* ZD1201GIMAXASSOC */
+};
+
+static const struct iw_priv_args zd1201_private_args[] = {
+	{ ZD1201SIWHOSTAUTH, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+	    IW_PRIV_TYPE_NONE, "sethostauth" },
+	{ ZD1201GIWHOSTAUTH, IW_PRIV_TYPE_NONE,
+	    IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "gethostauth" },
+	{ ZD1201SIWAUTHSTA, IW_PRIV_TYPE_ADDR | IW_PRIV_SIZE_FIXED | 1,
+	    IW_PRIV_TYPE_NONE, "authstation" },
+	{ ZD1201SIWMAXASSOC, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+	    IW_PRIV_TYPE_NONE, "setmaxassoc" },
+	{ ZD1201GIWMAXASSOC, IW_PRIV_TYPE_NONE,
+	    IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getmaxassoc" },
+};
+
+static const struct iw_handler_def zd1201_iw_handlers = {
+	.num_standard 		= ARRAY_SIZE(zd1201_iw_handler),
+	.num_private 		= ARRAY_SIZE(zd1201_private_handler),
+	.num_private_args 	= ARRAY_SIZE(zd1201_private_args),
+	.standard 		= (iw_handler *)zd1201_iw_handler,
+	.private 		= (iw_handler *)zd1201_private_handler,
+	.private_args 		= (struct iw_priv_args *) zd1201_private_args,
+	.get_wireless_stats	= zd1201_get_wireless_stats,
+};
+
+static int zd1201_probe(struct usb_interface *interface,
+			const struct usb_device_id *id)
+{
+	struct zd1201 *zd;
+	struct usb_device *usb;
+	int err;
+	short porttype;
+	char buf[IW_ESSID_MAX_SIZE+2];
+
+	usb = interface_to_usbdev(interface);
+
+	zd = kzalloc(sizeof(struct zd1201), GFP_KERNEL);
+	if (!zd)
+		return -ENOMEM;
+	zd->ap = ap;
+	zd->usb = usb;
+	zd->removed = 0;
+	init_waitqueue_head(&zd->rxdataq);
+	INIT_HLIST_HEAD(&zd->fraglist);
+	
+	err = zd1201_fw_upload(usb, zd->ap);
+	if (err) {
+		dev_err(&usb->dev, "zd1201 firmware upload failed: %d\n", err);
+		goto err_zd;
+	}
+	
+	zd->endp_in = 1;
+	zd->endp_out = 1;
+	zd->endp_out2 = 2;
+	zd->rx_urb = usb_alloc_urb(0, GFP_KERNEL);
+	zd->tx_urb = usb_alloc_urb(0, GFP_KERNEL);
+	if (!zd->rx_urb || !zd->tx_urb)
+		goto err_zd;
+
+	mdelay(100);
+	err = zd1201_drvr_start(zd);
+	if (err)
+		goto err_zd;
+
+	err = zd1201_setconfig16(zd, ZD1201_RID_CNFMAXDATALEN, 2312);
+	if (err)
+		goto err_start;
+
+	err = zd1201_setconfig16(zd, ZD1201_RID_TXRATECNTL,
+	    ZD1201_RATEB1 | ZD1201_RATEB2 | ZD1201_RATEB5 | ZD1201_RATEB11);
+	if (err)
+		goto err_start;
+
+	zd->dev = alloc_etherdev(0);
+	if (!zd->dev)
+		goto err_start;
+
+	zd->dev->priv = zd;
+	zd->dev->open = zd1201_net_open;
+	zd->dev->stop = zd1201_net_stop;
+	zd->dev->get_stats = zd1201_get_stats;
+	zd->dev->wireless_handlers =
+	    (struct iw_handler_def *)&zd1201_iw_handlers;
+	zd->dev->hard_start_xmit = zd1201_hard_start_xmit;
+	zd->dev->watchdog_timeo = ZD1201_TX_TIMEOUT;
+	zd->dev->tx_timeout = zd1201_tx_timeout;
+	zd->dev->set_multicast_list = zd1201_set_multicast;
+	zd->dev->set_mac_address = zd1201_set_mac_address;
+	strcpy(zd->dev->name, "wlan%d");
+
+	err = zd1201_getconfig(zd, ZD1201_RID_CNFOWNMACADDR, 
+	    zd->dev->dev_addr, zd->dev->addr_len);
+	if (err)
+		goto err_net;
+
+	/* Set wildcard essid to match zd->essid */
+	*(__le16 *)buf = cpu_to_le16(0);
+	err = zd1201_setconfig(zd, ZD1201_RID_CNFDESIREDSSID, buf,
+	    IW_ESSID_MAX_SIZE+2, 1);
+	if (err)
+		goto err_net;
+
+	if (zd->ap)
+		porttype = ZD1201_PORTTYPE_AP;
+	else
+		porttype = ZD1201_PORTTYPE_BSS;
+	err = zd1201_setconfig16(zd, ZD1201_RID_CNFPORTTYPE, porttype);
+	if (err)
+		goto err_net;
+
+	SET_NETDEV_DEV(zd->dev, &usb->dev);
+
+	err = register_netdev(zd->dev);
+	if (err)
+		goto err_net;
+	dev_info(&usb->dev, "%s: ZD1201 USB Wireless interface\n",
+	    zd->dev->name);
+
+	usb_set_intfdata(interface, zd);
+	zd1201_enable(zd);	/* zd1201 likes to startup enabled, */
+	zd1201_disable(zd);	/* interfering with all the wifis in range */
+	return 0;
+
+err_net:
+	free_netdev(zd->dev);
+err_start:
+	/* Leave the device in reset state */
+	zd1201_docmd(zd, ZD1201_CMDCODE_INIT, 0, 0, 0);
+err_zd:
+	if (zd->tx_urb)
+		usb_free_urb(zd->tx_urb);
+	if (zd->rx_urb)
+		usb_free_urb(zd->rx_urb);
+	kfree(zd);
+	return err;
+}
+
+static void zd1201_disconnect(struct usb_interface *interface)
+{
+	struct zd1201 *zd=(struct zd1201 *)usb_get_intfdata(interface);
+	struct hlist_node *node, *node2;
+	struct zd1201_frag *frag;
+
+	if (!zd)
+		return;
+	usb_set_intfdata(interface, NULL);
+	if (zd->dev) {
+		unregister_netdev(zd->dev);
+		free_netdev(zd->dev);
+	}
+
+	hlist_for_each_entry_safe(frag, node, node2, &zd->fraglist, fnode) {
+		hlist_del_init(&frag->fnode);
+		kfree_skb(frag->skb);
+		kfree(frag);
+	}
+
+	if (zd->tx_urb) {
+		usb_kill_urb(zd->tx_urb);
+		usb_free_urb(zd->tx_urb);
+	}
+	if (zd->rx_urb) {
+		usb_kill_urb(zd->rx_urb);
+		usb_free_urb(zd->rx_urb);
+	}
+	kfree(zd);
+}
+
+#ifdef CONFIG_PM
+
+static int zd1201_suspend(struct usb_interface *interface,
+			   pm_message_t message)
+{
+	struct zd1201 *zd = usb_get_intfdata(interface);
+
+	netif_device_detach(zd->dev);
+
+	zd->was_enabled = zd->mac_enabled;
+
+	if (zd->was_enabled)
+		return zd1201_disable(zd);
+	else
+		return 0;
+}
+
+static int zd1201_resume(struct usb_interface *interface)
+{
+	struct zd1201 *zd = usb_get_intfdata(interface);
+
+	if (!zd || !zd->dev)
+		return -ENODEV;
+
+	netif_device_attach(zd->dev);
+
+	if (zd->was_enabled)
+		return zd1201_enable(zd);
+	else
+		return 0;
+}
+
+#else
+
+#define zd1201_suspend NULL
+#define zd1201_resume  NULL
+
+#endif
+
+static struct usb_driver zd1201_usb = {
+	.name = "zd1201",
+	.probe = zd1201_probe,
+	.disconnect = zd1201_disconnect,
+	.id_table = zd1201_table,
+	.suspend = zd1201_suspend,
+	.resume = zd1201_resume,
+};
+
+static int __init zd1201_init(void)
+{
+	return usb_register(&zd1201_usb);
+}
+
+static void __exit zd1201_cleanup(void)
+{
+	usb_deregister(&zd1201_usb);
+}
+
+module_init(zd1201_init);
+module_exit(zd1201_cleanup);
diff --git a/drivers/net/wireless/zd1201.h b/drivers/net/wireless/zd1201.h
new file mode 100644
index 000000000..235f0ee34
--- /dev/null
+++ b/drivers/net/wireless/zd1201.h
@@ -0,0 +1,148 @@
+/*
+ *	Copyright (c) 2004, 2005 Jeroen Vreeken (pe1rxq@amsat.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.
+ *
+ *	Parts of this driver have been derived from a wlan-ng version
+ *	modified by ZyDAS.
+ *	Copyright (C) 1999 AbsoluteValue Systems, Inc.  All Rights Reserved.
+ */
+
+#ifndef _INCLUDE_ZD1201_H_
+#define _INCLUDE_ZD1201_H_
+
+#define ZD1201_NUMKEYS		4
+#define ZD1201_MAXKEYLEN	13
+#define ZD1201_MAXMULTI		16
+#define ZD1201_FRAGMAX		2500
+#define ZD1201_FRAGMIN		256
+#define ZD1201_RTSMAX		2500
+
+#define ZD1201_RXSIZE		3000
+
+struct zd1201 {
+	struct usb_device	*usb;
+	int			removed;
+	struct net_device	*dev;
+	struct net_device_stats stats;
+	struct iw_statistics	iwstats;
+
+	int			endp_in;
+	int			endp_out;
+	int			endp_out2;
+	struct urb		*rx_urb;
+	struct urb		*tx_urb;
+
+	unsigned char 		rxdata[ZD1201_RXSIZE];
+	int			rxlen;
+	wait_queue_head_t	rxdataq;
+	int			rxdatas;
+	struct hlist_head	fraglist;
+	unsigned char		txdata[ZD1201_RXSIZE];
+
+	int			ap;
+	char			essid[IW_ESSID_MAX_SIZE+1];
+	int			essidlen;
+	int			mac_enabled;
+	int			was_enabled;
+	int			monitor;
+	int			encode_enabled;
+	int			encode_restricted;
+	unsigned char		encode_keys[ZD1201_NUMKEYS][ZD1201_MAXKEYLEN];
+	int			encode_keylen[ZD1201_NUMKEYS];
+};
+
+struct zd1201_frag {
+	struct hlist_node	fnode;
+	int			seq;
+	struct sk_buff		*skb;
+};
+
+#define ZD1201SIWHOSTAUTH SIOCIWFIRSTPRIV
+#define ZD1201GIWHOSTAUTH ZD1201SIWHOSTAUTH+1
+#define ZD1201SIWAUTHSTA SIOCIWFIRSTPRIV+2
+#define ZD1201SIWMAXASSOC SIOCIWFIRSTPRIV+4
+#define ZD1201GIWMAXASSOC ZD1201SIWMAXASSOC+1
+
+#define ZD1201_FW_TIMEOUT	(1000)
+
+#define ZD1201_TX_TIMEOUT	(2000)
+
+#define ZD1201_USB_CMDREQ	0
+#define ZD1201_USB_RESREQ	1
+
+#define	ZD1201_CMDCODE_INIT	0x00
+#define ZD1201_CMDCODE_ENABLE	0x01
+#define ZD1201_CMDCODE_DISABLE	0x02
+#define ZD1201_CMDCODE_ALLOC	0x0a
+#define ZD1201_CMDCODE_INQUIRE	0x11
+#define ZD1201_CMDCODE_SETRXRID	0x17
+#define ZD1201_CMDCODE_ACCESS	0x21
+
+#define ZD1201_PACKET_EVENTSTAT	0x0
+#define ZD1201_PACKET_RXDATA	0x1
+#define ZD1201_PACKET_INQUIRE	0x2
+#define ZD1201_PACKET_RESOURCE	0x3
+
+#define ZD1201_ACCESSBIT	0x0100
+
+#define ZD1201_RID_CNFPORTTYPE		0xfc00
+#define ZD1201_RID_CNFOWNMACADDR	0xfc01
+#define ZD1201_RID_CNFDESIREDSSID	0xfc02
+#define ZD1201_RID_CNFOWNCHANNEL	0xfc03
+#define ZD1201_RID_CNFOWNSSID		0xfc04
+#define ZD1201_RID_CNFMAXDATALEN	0xfc07
+#define ZD1201_RID_CNFPMENABLED		0xfc09
+#define ZD1201_RID_CNFPMEPS		0xfc0a
+#define ZD1201_RID_CNFMAXSLEEPDURATION	0xfc0c
+#define ZD1201_RID_CNFDEFAULTKEYID	0xfc23
+#define ZD1201_RID_CNFDEFAULTKEY0	0xfc24
+#define ZD1201_RID_CNFDEFAULTKEY1	0xfc25
+#define ZD1201_RID_CNFDEFAULTKEY2	0xfc26
+#define ZD1201_RID_CNFDEFAULTKEY3	0xfc27
+#define ZD1201_RID_CNFWEBFLAGS		0xfc28
+#define ZD1201_RID_CNFAUTHENTICATION	0xfc2a
+#define ZD1201_RID_CNFMAXASSOCSTATIONS	0xfc2b
+#define ZD1201_RID_CNFHOSTAUTH		0xfc2e
+#define ZD1201_RID_CNFGROUPADDRESS	0xfc80
+#define ZD1201_RID_CNFFRAGTHRESHOLD	0xfc82
+#define ZD1201_RID_CNFRTSTHRESHOLD	0xfc83
+#define ZD1201_RID_TXRATECNTL		0xfc84
+#define ZD1201_RID_PROMISCUOUSMODE	0xfc85
+#define ZD1201_RID_CNFBASICRATES	0xfcb3
+#define ZD1201_RID_AUTHENTICATESTA	0xfce3
+#define ZD1201_RID_CURRENTBSSID		0xfd42
+#define ZD1201_RID_COMMSQUALITY		0xfd43
+#define ZD1201_RID_CURRENTTXRATE	0xfd44
+#define ZD1201_RID_CNFMAXTXBUFFERNUMBER	0xfda0
+#define ZD1201_RID_CURRENTCHANNEL	0xfdc1
+
+#define ZD1201_INQ_SCANRESULTS		0xf101
+
+#define ZD1201_INF_LINKSTATUS		0xf200
+#define ZD1201_INF_ASSOCSTATUS		0xf201
+#define ZD1201_INF_AUTHREQ		0xf202
+
+#define ZD1201_ASSOCSTATUS_STAASSOC	0x1
+#define ZD1201_ASSOCSTATUS_REASSOC	0x2
+#define ZD1201_ASSOCSTATUS_DISASSOC	0x3
+#define ZD1201_ASSOCSTATUS_ASSOCFAIL	0x4
+#define ZD1201_ASSOCSTATUS_AUTHFAIL	0x5
+
+#define ZD1201_PORTTYPE_IBSS		0
+#define ZD1201_PORTTYPE_BSS		1
+#define ZD1201_PORTTYPE_WDS		2
+#define ZD1201_PORTTYPE_PSEUDOIBSS	3
+#define ZD1201_PORTTYPE_AP		6
+
+#define ZD1201_RATEB1	1
+#define ZD1201_RATEB2	2
+#define ZD1201_RATEB5	4	/* 5.5 really, but 5 is shorter :) */
+#define ZD1201_RATEB11	8
+
+#define ZD1201_CNFAUTHENTICATION_OPENSYSTEM	0x0001
+#define ZD1201_CNFAUTHENTICATION_SHAREDKEY	0x0002
+
+#endif /* _INCLUDE_ZD1201_H_ */
diff --git a/drivers/net/wireless/zd1211rw/Kconfig b/drivers/net/wireless/zd1211rw/Kconfig
new file mode 100644
index 000000000..66ed55bc5
--- /dev/null
+++ b/drivers/net/wireless/zd1211rw/Kconfig
@@ -0,0 +1,19 @@
+config ZD1211RW
+	tristate "ZyDAS ZD1211/ZD1211B USB-wireless support"
+	depends on USB && IEEE80211 && IEEE80211_SOFTMAC && NET_RADIO && EXPERIMENTAL
+	select FW_LOADER
+	---help---
+	  This is an experimental driver for the ZyDAS ZD1211/ZD1211B wireless
+	  chip, present in many USB-wireless adapters.
+
+	  Device firmware is required alongside this driver. You can download the
+	  firmware distribution from http://zd1211.ath.cx/get-firmware
+
+config ZD1211RW_DEBUG
+	bool "ZyDAS ZD1211 debugging"
+	depends on ZD1211RW
+	---help---
+	  ZD1211 debugging messages. Choosing Y will result in additional debug
+	  messages being saved to your kernel logs, which may help debug any
+	  problems.
+
diff --git a/drivers/net/wireless/zd1211rw/Makefile b/drivers/net/wireless/zd1211rw/Makefile
new file mode 100644
index 000000000..500314fc7
--- /dev/null
+++ b/drivers/net/wireless/zd1211rw/Makefile
@@ -0,0 +1,11 @@
+obj-$(CONFIG_ZD1211RW) += zd1211rw.o
+
+zd1211rw-objs := zd_chip.o zd_ieee80211.o \
+		zd_mac.o zd_netdev.o \
+		zd_rf_al2230.o zd_rf_rf2959.o \
+		zd_rf.o zd_usb.o zd_util.o
+
+ifeq ($(CONFIG_ZD1211RW_DEBUG),y)
+EXTRA_CFLAGS += -DDEBUG
+endif
+
diff --git a/drivers/net/wireless/zd1211rw/zd_chip.c b/drivers/net/wireless/zd1211rw/zd_chip.c
new file mode 100644
index 000000000..4b971a997
--- /dev/null
+++ b/drivers/net/wireless/zd1211rw/zd_chip.c
@@ -0,0 +1,1646 @@
+/* zd_chip.c
+ *
+ * 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
+ */
+
+/* This file implements all the hardware specific functions for the ZD1211
+ * and ZD1211B chips. Support for the ZD1211B was possible after Timothy
+ * Legge sent me a ZD1211B device. Thank you Tim. -- Uli
+ */
+
+#include <linux/kernel.h>
+#include <linux/errno.h>
+
+#include "zd_def.h"
+#include "zd_chip.h"
+#include "zd_ieee80211.h"
+#include "zd_mac.h"
+#include "zd_rf.h"
+#include "zd_util.h"
+
+void zd_chip_init(struct zd_chip *chip,
+	         struct net_device *netdev,
+		 struct usb_interface *intf)
+{
+	memset(chip, 0, sizeof(*chip));
+	mutex_init(&chip->mutex);
+	zd_usb_init(&chip->usb, netdev, intf);
+	zd_rf_init(&chip->rf);
+}
+
+void zd_chip_clear(struct zd_chip *chip)
+{
+	mutex_lock(&chip->mutex);
+	zd_usb_clear(&chip->usb);
+	zd_rf_clear(&chip->rf);
+	mutex_unlock(&chip->mutex);
+	mutex_destroy(&chip->mutex);
+	memset(chip, 0, sizeof(*chip));
+}
+
+static int scnprint_mac_oui(const u8 *addr, char *buffer, size_t size)
+{
+	return scnprintf(buffer, size, "%02x-%02x-%02x",
+		         addr[0], addr[1], addr[2]);
+}
+
+/* Prints an identifier line, which will support debugging. */
+static int scnprint_id(struct zd_chip *chip, char *buffer, size_t size)
+{
+	int i = 0;
+
+	i = scnprintf(buffer, size, "zd1211%s chip ",
+		      chip->is_zd1211b ? "b" : "");
+	i += zd_usb_scnprint_id(&chip->usb, buffer+i, size-i);
+	i += scnprintf(buffer+i, size-i, " ");
+	i += scnprint_mac_oui(chip->e2p_mac, buffer+i, size-i);
+	i += scnprintf(buffer+i, size-i, " ");
+	i += zd_rf_scnprint_id(&chip->rf, buffer+i, size-i);
+	i += scnprintf(buffer+i, size-i, " pa%1x %c%c%c", chip->pa_type,
+		chip->patch_cck_gain ? 'g' : '-',
+		chip->patch_cr157 ? '7' : '-',
+		chip->patch_6m_band_edge ? '6' : '-');
+	return i;
+}
+
+static void print_id(struct zd_chip *chip)
+{
+	char buffer[80];
+
+	scnprint_id(chip, buffer, sizeof(buffer));
+	buffer[sizeof(buffer)-1] = 0;
+	dev_info(zd_chip_dev(chip), "%s\n", buffer);
+}
+
+/* Read a variable number of 32-bit values. Parameter count is not allowed to
+ * exceed USB_MAX_IOREAD32_COUNT.
+ */
+int zd_ioread32v_locked(struct zd_chip *chip, u32 *values, const zd_addr_t *addr,
+		 unsigned int count)
+{
+	int r;
+	int i;
+	zd_addr_t *a16 = (zd_addr_t *)NULL;
+	u16 *v16;
+	unsigned int count16;
+
+	if (count > USB_MAX_IOREAD32_COUNT)
+		return -EINVAL;
+
+	/* Allocate a single memory block for values and addresses. */
+	count16 = 2*count;
+	a16 = (zd_addr_t *)kmalloc(count16 * (sizeof(zd_addr_t) + sizeof(u16)),
+		                   GFP_NOFS);
+	if (!a16) {
+		dev_dbg_f(zd_chip_dev(chip),
+			  "error ENOMEM in allocation of a16\n");
+		r = -ENOMEM;
+		goto out;
+	}
+	v16 = (u16 *)(a16 + count16);
+
+	for (i = 0; i < count; i++) {
+		int j = 2*i;
+		/* We read the high word always first. */
+		a16[j] = zd_inc_word(addr[i]);
+		a16[j+1] = addr[i];
+	}
+
+	r = zd_ioread16v_locked(chip, v16, a16, count16);
+	if (r) {
+		dev_dbg_f(zd_chip_dev(chip),
+			  "error: zd_ioread16v_locked. Error number %d\n", r);
+		goto out;
+	}
+
+	for (i = 0; i < count; i++) {
+		int j = 2*i;
+		values[i] = (v16[j] << 16) | v16[j+1];
+	}
+
+out:
+	kfree((void *)a16);
+	return r;
+}
+
+int _zd_iowrite32v_locked(struct zd_chip *chip, const struct zd_ioreq32 *ioreqs,
+	           unsigned int count)
+{
+	int i, j, r;
+	struct zd_ioreq16 *ioreqs16;
+	unsigned int count16;
+
+	ZD_ASSERT(mutex_is_locked(&chip->mutex));
+
+	if (count == 0)
+		return 0;
+	if (count > USB_MAX_IOWRITE32_COUNT)
+		return -EINVAL;
+
+	/* Allocate a single memory block for values and addresses. */
+	count16 = 2*count;
+	ioreqs16 = kmalloc(count16 * sizeof(struct zd_ioreq16), GFP_NOFS);
+	if (!ioreqs16) {
+		r = -ENOMEM;
+		dev_dbg_f(zd_chip_dev(chip),
+			  "error %d in ioreqs16 allocation\n", r);
+		goto out;
+	}
+
+	for (i = 0; i < count; i++) {
+		j = 2*i;
+		/* We write the high word always first. */
+		ioreqs16[j].value   = ioreqs[i].value >> 16;
+		ioreqs16[j].addr    = zd_inc_word(ioreqs[i].addr);
+		ioreqs16[j+1].value = ioreqs[i].value;
+		ioreqs16[j+1].addr  = ioreqs[i].addr;
+	}
+
+	r = zd_usb_iowrite16v(&chip->usb, ioreqs16, count16);
+#ifdef DEBUG
+	if (r) {
+		dev_dbg_f(zd_chip_dev(chip),
+			  "error %d in zd_usb_write16v\n", r);
+	}
+#endif /* DEBUG */
+out:
+	kfree(ioreqs16);
+	return r;
+}
+
+int zd_iowrite16a_locked(struct zd_chip *chip,
+                  const struct zd_ioreq16 *ioreqs, unsigned int count)
+{
+	int r;
+	unsigned int i, j, t, max;
+
+	ZD_ASSERT(mutex_is_locked(&chip->mutex));
+	for (i = 0; i < count; i += j + t) {
+		t = 0;
+		max = count-i;
+		if (max > USB_MAX_IOWRITE16_COUNT)
+			max = USB_MAX_IOWRITE16_COUNT;
+		for (j = 0; j < max; j++) {
+			if (!ioreqs[i+j].addr) {
+				t = 1;
+				break;
+			}
+		}
+
+		r = zd_usb_iowrite16v(&chip->usb, &ioreqs[i], j);
+		if (r) {
+			dev_dbg_f(zd_chip_dev(chip),
+				  "error zd_usb_iowrite16v. Error number %d\n",
+				  r);
+			return r;
+		}
+	}
+
+	return 0;
+}
+
+/* Writes a variable number of 32 bit registers. The functions will split
+ * that in several USB requests. A split can be forced by inserting an IO
+ * request with an zero address field.
+ */
+int zd_iowrite32a_locked(struct zd_chip *chip,
+	          const struct zd_ioreq32 *ioreqs, unsigned int count)
+{
+	int r;
+	unsigned int i, j, t, max;
+
+	for (i = 0; i < count; i += j + t) {
+		t = 0;
+		max = count-i;
+		if (max > USB_MAX_IOWRITE32_COUNT)
+			max = USB_MAX_IOWRITE32_COUNT;
+		for (j = 0; j < max; j++) {
+			if (!ioreqs[i+j].addr) {
+				t = 1;
+				break;
+			}
+		}
+
+		r = _zd_iowrite32v_locked(chip, &ioreqs[i], j);
+		if (r) {
+			dev_dbg_f(zd_chip_dev(chip),
+				"error _zd_iowrite32v_locked."
+				" Error number %d\n", r);
+			return r;
+		}
+	}
+
+	return 0;
+}
+
+int zd_ioread16(struct zd_chip *chip, zd_addr_t addr, u16 *value)
+{
+	int r;
+
+	ZD_ASSERT(!mutex_is_locked(&chip->mutex));
+	mutex_lock(&chip->mutex);
+	r = zd_ioread16_locked(chip, value, addr);
+	mutex_unlock(&chip->mutex);
+	return r;
+}
+
+int zd_ioread32(struct zd_chip *chip, zd_addr_t addr, u32 *value)
+{
+	int r;
+
+	ZD_ASSERT(!mutex_is_locked(&chip->mutex));
+	mutex_lock(&chip->mutex);
+	r = zd_ioread32_locked(chip, value, addr);
+	mutex_unlock(&chip->mutex);
+	return r;
+}
+
+int zd_iowrite16(struct zd_chip *chip, zd_addr_t addr, u16 value)
+{
+	int r;
+
+	ZD_ASSERT(!mutex_is_locked(&chip->mutex));
+	mutex_lock(&chip->mutex);
+	r = zd_iowrite16_locked(chip, value, addr);
+	mutex_unlock(&chip->mutex);
+	return r;
+}
+
+int zd_iowrite32(struct zd_chip *chip, zd_addr_t addr, u32 value)
+{
+	int r;
+
+	ZD_ASSERT(!mutex_is_locked(&chip->mutex));
+	mutex_lock(&chip->mutex);
+	r = zd_iowrite32_locked(chip, value, addr);
+	mutex_unlock(&chip->mutex);
+	return r;
+}
+
+int zd_ioread32v(struct zd_chip *chip, const zd_addr_t *addresses,
+	          u32 *values, unsigned int count)
+{
+	int r;
+
+	ZD_ASSERT(!mutex_is_locked(&chip->mutex));
+	mutex_lock(&chip->mutex);
+	r = zd_ioread32v_locked(chip, values, addresses, count);
+	mutex_unlock(&chip->mutex);
+	return r;
+}
+
+int zd_iowrite32a(struct zd_chip *chip, const struct zd_ioreq32 *ioreqs,
+	          unsigned int count)
+{
+	int r;
+
+	ZD_ASSERT(!mutex_is_locked(&chip->mutex));
+	mutex_lock(&chip->mutex);
+	r = zd_iowrite32a_locked(chip, ioreqs, count);
+	mutex_unlock(&chip->mutex);
+	return r;
+}
+
+static int read_pod(struct zd_chip *chip, u8 *rf_type)
+{
+	int r;
+	u32 value;
+
+	ZD_ASSERT(mutex_is_locked(&chip->mutex));
+	r = zd_ioread32_locked(chip, &value, E2P_POD);
+	if (r)
+		goto error;
+	dev_dbg_f(zd_chip_dev(chip), "E2P_POD %#010x\n", value);
+
+	/* FIXME: AL2230 handling (Bit 7 in POD) */
+	*rf_type = value & 0x0f;
+	chip->pa_type = (value >> 16) & 0x0f;
+	chip->patch_cck_gain = (value >> 8) & 0x1;
+	chip->patch_cr157 = (value >> 13) & 0x1;
+	chip->patch_6m_band_edge = (value >> 21) & 0x1;
+
+	dev_dbg_f(zd_chip_dev(chip),
+		"RF %s %#01x PA type %#01x patch CCK %d patch CR157 %d "
+		"patch 6M %d\n",
+		zd_rf_name(*rf_type), *rf_type,
+		chip->pa_type, chip->patch_cck_gain,
+		chip->patch_cr157, chip->patch_6m_band_edge);
+	return 0;
+error:
+	*rf_type = 0;
+	chip->pa_type = 0;
+	chip->patch_cck_gain = 0;
+	chip->patch_cr157 = 0;
+	chip->patch_6m_band_edge = 0;
+	return r;
+}
+
+static int _read_mac_addr(struct zd_chip *chip, u8 *mac_addr,
+	                  const zd_addr_t *addr)
+{
+	int r;
+	u32 parts[2];
+
+	r = zd_ioread32v_locked(chip, parts, (const zd_addr_t *)addr, 2);
+	if (r) {
+		dev_dbg_f(zd_chip_dev(chip),
+			"error: couldn't read e2p macs. Error number %d\n", r);
+		return r;
+	}
+
+	mac_addr[0] = parts[0];
+	mac_addr[1] = parts[0] >>  8;
+	mac_addr[2] = parts[0] >> 16;
+	mac_addr[3] = parts[0] >> 24;
+	mac_addr[4] = parts[1];
+	mac_addr[5] = parts[1] >>  8;
+
+	return 0;
+}
+
+static int read_e2p_mac_addr(struct zd_chip *chip)
+{
+	static const zd_addr_t addr[2] = { E2P_MAC_ADDR_P1, E2P_MAC_ADDR_P2 };
+
+	ZD_ASSERT(mutex_is_locked(&chip->mutex));
+	return _read_mac_addr(chip, chip->e2p_mac, (const zd_addr_t *)addr);
+}
+
+/* MAC address: if custom mac addresses are to to be used CR_MAC_ADDR_P1 and
+ *              CR_MAC_ADDR_P2 must be overwritten
+ */
+void zd_get_e2p_mac_addr(struct zd_chip *chip, u8 *mac_addr)
+{
+	mutex_lock(&chip->mutex);
+	memcpy(mac_addr, chip->e2p_mac, ETH_ALEN);
+	mutex_unlock(&chip->mutex);
+}
+
+static int read_mac_addr(struct zd_chip *chip, u8 *mac_addr)
+{
+	static const zd_addr_t addr[2] = { CR_MAC_ADDR_P1, CR_MAC_ADDR_P2 };
+	return _read_mac_addr(chip, mac_addr, (const zd_addr_t *)addr);
+}
+
+int zd_read_mac_addr(struct zd_chip *chip, u8 *mac_addr)
+{
+	int r;
+
+	dev_dbg_f(zd_chip_dev(chip), "\n");
+	mutex_lock(&chip->mutex);
+	r = read_mac_addr(chip, mac_addr);
+	mutex_unlock(&chip->mutex);
+	return r;
+}
+
+int zd_write_mac_addr(struct zd_chip *chip, const u8 *mac_addr)
+{
+	int r;
+	struct zd_ioreq32 reqs[2] = {
+		[0] = { .addr = CR_MAC_ADDR_P1 },
+		[1] = { .addr = CR_MAC_ADDR_P2 },
+	};
+
+	reqs[0].value = (mac_addr[3] << 24)
+		      | (mac_addr[2] << 16)
+		      | (mac_addr[1] <<  8)
+		      |  mac_addr[0];
+	reqs[1].value = (mac_addr[5] <<  8)
+		      |  mac_addr[4];
+
+	dev_dbg_f(zd_chip_dev(chip),
+		"mac addr " MAC_FMT "\n", MAC_ARG(mac_addr));
+
+	mutex_lock(&chip->mutex);
+	r = zd_iowrite32a_locked(chip, reqs, ARRAY_SIZE(reqs));
+#ifdef DEBUG
+	{
+		u8 tmp[ETH_ALEN];
+		read_mac_addr(chip, tmp);
+	}
+#endif /* DEBUG */
+	mutex_unlock(&chip->mutex);
+	return r;
+}
+
+int zd_read_regdomain(struct zd_chip *chip, u8 *regdomain)
+{
+	int r;
+	u32 value;
+
+	mutex_lock(&chip->mutex);
+	r = zd_ioread32_locked(chip, &value, E2P_SUBID);
+	mutex_unlock(&chip->mutex);
+	if (r)
+		return r;
+
+	*regdomain = value >> 16;
+	dev_dbg_f(zd_chip_dev(chip), "regdomain: %#04x\n", *regdomain);
+
+	return 0;
+}
+
+static int read_values(struct zd_chip *chip, u8 *values, size_t count,
+	               zd_addr_t e2p_addr, u32 guard)
+{
+	int r;
+	int i;
+	u32 v;
+
+	ZD_ASSERT(mutex_is_locked(&chip->mutex));
+	for (i = 0;;) {
+		r = zd_ioread32_locked(chip, &v, e2p_addr+i/2);
+		if (r)
+			return r;
+		v -= guard;
+		if (i+4 < count) {
+			values[i++] = v;
+			values[i++] = v >>  8;
+			values[i++] = v >> 16;
+			values[i++] = v >> 24;
+			continue;
+		}
+		for (;i < count; i++)
+			values[i] = v >> (8*(i%3));
+		return 0;
+	}
+}
+
+static int read_pwr_cal_values(struct zd_chip *chip)
+{
+	return read_values(chip, chip->pwr_cal_values,
+		        E2P_CHANNEL_COUNT, E2P_PWR_CAL_VALUE1,
+			0);
+}
+
+static int read_pwr_int_values(struct zd_chip *chip)
+{
+	return read_values(chip, chip->pwr_int_values,
+		        E2P_CHANNEL_COUNT, E2P_PWR_INT_VALUE1,
+			E2P_PWR_INT_GUARD);
+}
+
+static int read_ofdm_cal_values(struct zd_chip *chip)
+{
+	int r;
+	int i;
+	static const zd_addr_t addresses[] = {
+		E2P_36M_CAL_VALUE1,
+		E2P_48M_CAL_VALUE1,
+		E2P_54M_CAL_VALUE1,
+	};
+
+	for (i = 0; i < 3; i++) {
+		r = read_values(chip, chip->ofdm_cal_values[i],
+				E2P_CHANNEL_COUNT, addresses[i], 0);
+		if (r)
+			return r;
+	}
+	return 0;
+}
+
+static int read_cal_int_tables(struct zd_chip *chip)
+{
+	int r;
+
+	r = read_pwr_cal_values(chip);
+	if (r)
+		return r;
+	r = read_pwr_int_values(chip);
+	if (r)
+		return r;
+	r = read_ofdm_cal_values(chip);
+	if (r)
+		return r;
+	return 0;
+}
+
+/* phy means physical registers */
+int zd_chip_lock_phy_regs(struct zd_chip *chip)
+{
+	int r;
+	u32 tmp;
+
+	ZD_ASSERT(mutex_is_locked(&chip->mutex));
+	r = zd_ioread32_locked(chip, &tmp, CR_REG1);
+	if (r) {
+		dev_err(zd_chip_dev(chip), "error ioread32(CR_REG1): %d\n", r);
+		return r;
+	}
+
+	dev_dbg_f(zd_chip_dev(chip),
+		"CR_REG1: 0x%02x -> 0x%02x\n", tmp, tmp & ~UNLOCK_PHY_REGS);
+	tmp &= ~UNLOCK_PHY_REGS;
+
+	r = zd_iowrite32_locked(chip, tmp, CR_REG1);
+	if (r)
+		dev_err(zd_chip_dev(chip), "error iowrite32(CR_REG1): %d\n", r);
+	return r;
+}
+
+int zd_chip_unlock_phy_regs(struct zd_chip *chip)
+{
+	int r;
+	u32 tmp;
+
+	ZD_ASSERT(mutex_is_locked(&chip->mutex));
+	r = zd_ioread32_locked(chip, &tmp, CR_REG1);
+	if (r) {
+		dev_err(zd_chip_dev(chip),
+			"error ioread32(CR_REG1): %d\n", r);
+		return r;
+	}
+
+	dev_dbg_f(zd_chip_dev(chip),
+		"CR_REG1: 0x%02x -> 0x%02x\n", tmp, tmp | UNLOCK_PHY_REGS);
+	tmp |= UNLOCK_PHY_REGS;
+
+	r = zd_iowrite32_locked(chip, tmp, CR_REG1);
+	if (r)
+		dev_err(zd_chip_dev(chip), "error iowrite32(CR_REG1): %d\n", r);
+	return r;
+}
+
+/* CR157 can be optionally patched by the EEPROM */
+static int patch_cr157(struct zd_chip *chip)
+{
+	int r;
+	u32 value;
+
+	if (!chip->patch_cr157)
+		return 0;
+
+	r = zd_ioread32_locked(chip, &value, E2P_PHY_REG);
+	if (r)
+		return r;
+
+	dev_dbg_f(zd_chip_dev(chip), "patching value %x\n", value >> 8);
+	return zd_iowrite32_locked(chip, value >> 8, CR157);
+}
+
+/*
+ * 6M band edge can be optionally overwritten for certain RF's
+ * Vendor driver says: for FCC regulation, enabled per HWFeature 6M band edge
+ * bit (for AL2230, AL2230S)
+ */
+static int patch_6m_band_edge(struct zd_chip *chip, int channel)
+{
+	struct zd_ioreq16 ioreqs[] = {
+		{ CR128, 0x14 }, { CR129, 0x12 }, { CR130, 0x10 },
+		{ CR47,  0x1e },
+	};
+
+	if (!chip->patch_6m_band_edge || !chip->rf.patch_6m_band_edge)
+		return 0;
+
+	/* FIXME: Channel 11 is not the edge for all regulatory domains. */
+	if (channel == 1 || channel == 11)
+		ioreqs[0].value = 0x12;
+
+	dev_dbg_f(zd_chip_dev(chip), "patching for channel %d\n", channel);
+	return zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
+}
+
+static int zd1211_hw_reset_phy(struct zd_chip *chip)
+{
+	static const struct zd_ioreq16 ioreqs[] = {
+		{ CR0,   0x0a }, { CR1,   0x06 }, { CR2,   0x26 },
+		{ CR3,   0x38 }, { CR4,   0x80 }, { CR9,   0xa0 },
+		{ CR10,  0x81 }, { CR11,  0x00 }, { CR12,  0x7f },
+		{ CR13,  0x8c }, { CR14,  0x80 }, { CR15,  0x3d },
+		{ CR16,  0x20 }, { CR17,  0x1e }, { CR18,  0x0a },
+		{ CR19,  0x48 }, { CR20,  0x0c }, { CR21,  0x0c },
+		{ CR22,  0x23 }, { CR23,  0x90 }, { CR24,  0x14 },
+		{ CR25,  0x40 }, { CR26,  0x10 }, { CR27,  0x19 },
+		{ CR28,  0x7f }, { CR29,  0x80 }, { CR30,  0x4b },
+		{ CR31,  0x60 }, { CR32,  0x43 }, { CR33,  0x08 },
+		{ CR34,  0x06 }, { CR35,  0x0a }, { CR36,  0x00 },
+		{ CR37,  0x00 }, { CR38,  0x38 }, { CR39,  0x0c },
+		{ CR40,  0x84 }, { CR41,  0x2a }, { CR42,  0x80 },
+		{ CR43,  0x10 }, { CR44,  0x12 }, { CR46,  0xff },
+		{ CR47,  0x1E }, { CR48,  0x26 }, { CR49,  0x5b },
+		{ CR64,  0xd0 }, { CR65,  0x04 }, { CR66,  0x58 },
+		{ CR67,  0xc9 }, { CR68,  0x88 }, { CR69,  0x41 },
+		{ CR70,  0x23 }, { CR71,  0x10 }, { CR72,  0xff },
+		{ CR73,  0x32 }, { CR74,  0x30 }, { CR75,  0x65 },
+		{ CR76,  0x41 }, { CR77,  0x1b }, { CR78,  0x30 },
+		{ CR79,  0x68 }, { CR80,  0x64 }, { CR81,  0x64 },
+		{ CR82,  0x00 }, { CR83,  0x00 }, { CR84,  0x00 },
+		{ CR85,  0x02 }, { CR86,  0x00 }, { CR87,  0x00 },
+		{ CR88,  0xff }, { CR89,  0xfc }, { CR90,  0x00 },
+		{ CR91,  0x00 }, { CR92,  0x00 }, { CR93,  0x08 },
+		{ CR94,  0x00 }, { CR95,  0x00 }, { CR96,  0xff },
+		{ CR97,  0xe7 }, { CR98,  0x00 }, { CR99,  0x00 },
+		{ CR100, 0x00 }, { CR101, 0xae }, { CR102, 0x02 },
+		{ CR103, 0x00 }, { CR104, 0x03 }, { CR105, 0x65 },
+		{ CR106, 0x04 }, { CR107, 0x00 }, { CR108, 0x0a },
+		{ CR109, 0xaa }, { CR110, 0xaa }, { CR111, 0x25 },
+		{ CR112, 0x25 }, { CR113, 0x00 }, { CR119, 0x1e },
+		{ CR125, 0x90 }, { CR126, 0x00 }, { CR127, 0x00 },
+		{ },
+		{ CR5,   0x00 }, { CR6,   0x00 }, { CR7,   0x00 },
+		{ CR8,   0x00 }, { CR9,   0x20 }, { CR12,  0xf0 },
+		{ CR20,  0x0e }, { CR21,  0x0e }, { CR27,  0x10 },
+		{ CR44,  0x33 }, { CR47,  0x1E }, { CR83,  0x24 },
+		{ CR84,  0x04 }, { CR85,  0x00 }, { CR86,  0x0C },
+		{ CR87,  0x12 }, { CR88,  0x0C }, { CR89,  0x00 },
+		{ CR90,  0x10 }, { CR91,  0x08 }, { CR93,  0x00 },
+		{ CR94,  0x01 }, { CR95,  0x00 }, { CR96,  0x50 },
+		{ CR97,  0x37 }, { CR98,  0x35 }, { CR101, 0x13 },
+		{ CR102, 0x27 }, { CR103, 0x27 }, { CR104, 0x18 },
+		{ CR105, 0x12 }, { CR109, 0x27 }, { CR110, 0x27 },
+		{ CR111, 0x27 }, { CR112, 0x27 }, { CR113, 0x27 },
+		{ CR114, 0x27 }, { CR115, 0x26 }, { CR116, 0x24 },
+		{ CR117, 0xfc }, { CR118, 0xfa }, { CR120, 0x4f },
+		{ CR123, 0x27 }, { CR125, 0xaa }, { CR127, 0x03 },
+		{ CR128, 0x14 }, { CR129, 0x12 }, { CR130, 0x10 },
+		{ CR131, 0x0C }, { CR136, 0xdf }, { CR137, 0x40 },
+		{ CR138, 0xa0 }, { CR139, 0xb0 }, { CR140, 0x99 },
+		{ CR141, 0x82 }, { CR142, 0x54 }, { CR143, 0x1c },
+		{ CR144, 0x6c }, { CR147, 0x07 }, { CR148, 0x4c },
+		{ CR149, 0x50 }, { CR150, 0x0e }, { CR151, 0x18 },
+		{ CR160, 0xfe }, { CR161, 0xee }, { CR162, 0xaa },
+		{ CR163, 0xfa }, { CR164, 0xfa }, { CR165, 0xea },
+		{ CR166, 0xbe }, { CR167, 0xbe }, { CR168, 0x6a },
+		{ CR169, 0xba }, { CR170, 0xba }, { CR171, 0xba },
+		/* Note: CR204 must lead the CR203 */
+		{ CR204, 0x7d },
+		{ },
+		{ CR203, 0x30 },
+	};
+
+	int r, t;
+
+	dev_dbg_f(zd_chip_dev(chip), "\n");
+
+	r = zd_chip_lock_phy_regs(chip);
+	if (r)
+		goto out;
+
+	r = zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
+	if (r)
+		goto unlock;
+
+	r = patch_cr157(chip);
+unlock:
+	t = zd_chip_unlock_phy_regs(chip);
+	if (t && !r)
+		r = t;
+out:
+	return r;
+}
+
+static int zd1211b_hw_reset_phy(struct zd_chip *chip)
+{
+	static const struct zd_ioreq16 ioreqs[] = {
+		{ CR0,   0x14 }, { CR1,   0x06 }, { CR2,   0x26 },
+		{ CR3,   0x38 }, { CR4,   0x80 }, { CR9,   0xe0 },
+		{ CR10,  0x81 },
+		/* power control { { CR11,  1 << 6 }, */
+		{ CR11,  0x00 },
+		{ CR12,  0xf0 }, { CR13,  0x8c }, { CR14,  0x80 },
+		{ CR15,  0x3d }, { CR16,  0x20 }, { CR17,  0x1e },
+		{ CR18,  0x0a }, { CR19,  0x48 },
+		{ CR20,  0x10 }, /* Org:0x0E, ComTrend:RalLink AP */
+		{ CR21,  0x0e }, { CR22,  0x23 }, { CR23,  0x90 },
+		{ CR24,  0x14 }, { CR25,  0x40 }, { CR26,  0x10 },
+		{ CR27,  0x10 }, { CR28,  0x7f }, { CR29,  0x80 },
+		{ CR30,  0x4b }, /* ASIC/FWT, no jointly decoder */
+		{ CR31,  0x60 }, { CR32,  0x43 }, { CR33,  0x08 },
+		{ CR34,  0x06 }, { CR35,  0x0a }, { CR36,  0x00 },
+		{ CR37,  0x00 }, { CR38,  0x38 }, { CR39,  0x0c },
+		{ CR40,  0x84 }, { CR41,  0x2a }, { CR42,  0x80 },
+		{ CR43,  0x10 }, { CR44,  0x33 }, { CR46,  0xff },
+		{ CR47,  0x1E }, { CR48,  0x26 }, { CR49,  0x5b },
+		{ CR64,  0xd0 }, { CR65,  0x04 }, { CR66,  0x58 },
+		{ CR67,  0xc9 }, { CR68,  0x88 }, { CR69,  0x41 },
+		{ CR70,  0x23 }, { CR71,  0x10 }, { CR72,  0xff },
+		{ CR73,  0x32 }, { CR74,  0x30 }, { CR75,  0x65 },
+		{ CR76,  0x41 }, { CR77,  0x1b }, { CR78,  0x30 },
+		{ CR79,  0xf0 }, { CR80,  0x64 }, { CR81,  0x64 },
+		{ CR82,  0x00 }, { CR83,  0x24 }, { CR84,  0x04 },
+		{ CR85,  0x00 }, { CR86,  0x0c }, { CR87,  0x12 },
+		{ CR88,  0x0c }, { CR89,  0x00 }, { CR90,  0x58 },
+		{ CR91,  0x04 }, { CR92,  0x00 }, { CR93,  0x00 },
+		{ CR94,  0x01 },
+		{ CR95,  0x20 }, /* ZD1211B */
+		{ CR96,  0x50 }, { CR97,  0x37 }, { CR98,  0x35 },
+		{ CR99,  0x00 }, { CR100, 0x01 }, { CR101, 0x13 },
+		{ CR102, 0x27 }, { CR103, 0x27 }, { CR104, 0x18 },
+		{ CR105, 0x12 }, { CR106, 0x04 }, { CR107, 0x00 },
+		{ CR108, 0x0a }, { CR109, 0x27 }, { CR110, 0x27 },
+		{ CR111, 0x27 }, { CR112, 0x27 }, { CR113, 0x27 },
+		{ CR114, 0x27 }, { CR115, 0x26 }, { CR116, 0x24 },
+		{ CR117, 0xfc }, { CR118, 0xfa }, { CR119, 0x1e },
+		{ CR125, 0x90 }, { CR126, 0x00 }, { CR127, 0x00 },
+		{ CR128, 0x14 }, { CR129, 0x12 }, { CR130, 0x10 },
+		{ CR131, 0x0c }, { CR136, 0xdf }, { CR137, 0xa0 },
+		{ CR138, 0xa8 }, { CR139, 0xb4 }, { CR140, 0x98 },
+		{ CR141, 0x82 }, { CR142, 0x53 }, { CR143, 0x1c },
+		{ CR144, 0x6c }, { CR147, 0x07 }, { CR148, 0x40 },
+		{ CR149, 0x40 }, /* Org:0x50 ComTrend:RalLink AP */
+		{ CR150, 0x14 }, /* Org:0x0E ComTrend:RalLink AP */
+		{ CR151, 0x18 }, { CR159, 0x70 }, { CR160, 0xfe },
+		{ CR161, 0xee }, { CR162, 0xaa }, { CR163, 0xfa },
+		{ CR164, 0xfa }, { CR165, 0xea }, { CR166, 0xbe },
+		{ CR167, 0xbe }, { CR168, 0x6a }, { CR169, 0xba },
+		{ CR170, 0xba }, { CR171, 0xba },
+		/* Note: CR204 must lead the CR203 */
+		{ CR204, 0x7d },
+		{},
+		{ CR203, 0x30 },
+	};
+
+	int r, t;
+
+	dev_dbg_f(zd_chip_dev(chip), "\n");
+
+	r = zd_chip_lock_phy_regs(chip);
+	if (r)
+		goto out;
+
+	r = zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
+	if (r)
+		goto unlock;
+
+	r = patch_cr157(chip);
+unlock:
+	t = zd_chip_unlock_phy_regs(chip);
+	if (t && !r)
+		r = t;
+out:
+	return r;
+}
+
+static int hw_reset_phy(struct zd_chip *chip)
+{
+	return chip->is_zd1211b ? zd1211b_hw_reset_phy(chip) :
+		                  zd1211_hw_reset_phy(chip);
+}
+
+static int zd1211_hw_init_hmac(struct zd_chip *chip)
+{
+	static const struct zd_ioreq32 ioreqs[] = {
+		{ CR_ACK_TIMEOUT_EXT,		0x20 },
+		{ CR_ADDA_MBIAS_WARMTIME,	0x30000808 },
+		{ CR_ZD1211_RETRY_MAX,		0x2 },
+		{ CR_SNIFFER_ON,		0 },
+		{ CR_RX_FILTER,			STA_RX_FILTER },
+		{ CR_GROUP_HASH_P1,		0x00 },
+		{ CR_GROUP_HASH_P2,		0x80000000 },
+		{ CR_REG1,			0xa4 },
+		{ CR_ADDA_PWR_DWN,		0x7f },
+		{ CR_BCN_PLCP_CFG,		0x00f00401 },
+		{ CR_PHY_DELAY,			0x00 },
+		{ CR_ACK_TIMEOUT_EXT,		0x80 },
+		{ CR_ADDA_PWR_DWN,		0x00 },
+		{ CR_ACK_TIME_80211,		0x100 },
+		{ CR_IFS_VALUE,			0x547c032 },
+		{ CR_RX_PE_DELAY,		0x70 },
+		{ CR_PS_CTRL,			0x10000000 },
+		{ CR_RTS_CTS_RATE,		0x02030203 },
+		{ CR_RX_THRESHOLD,		0x000c0640 },
+		{ CR_AFTER_PNP,			0x1 },
+		{ CR_WEP_PROTECT,		0x114 },
+	};
+
+	int r;
+
+	dev_dbg_f(zd_chip_dev(chip), "\n");
+	ZD_ASSERT(mutex_is_locked(&chip->mutex));
+	r = zd_iowrite32a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
+#ifdef DEBUG
+	if (r) {
+		dev_err(zd_chip_dev(chip),
+			"error in zd_iowrite32a_locked. Error number %d\n", r);
+	}
+#endif /* DEBUG */
+	return r;
+}
+
+static int zd1211b_hw_init_hmac(struct zd_chip *chip)
+{
+	static const struct zd_ioreq32 ioreqs[] = {
+		{ CR_ACK_TIMEOUT_EXT,		0x20 },
+		{ CR_ADDA_MBIAS_WARMTIME,	0x30000808 },
+		{ CR_ZD1211B_RETRY_MAX,		0x02020202 },
+		{ CR_ZD1211B_TX_PWR_CTL4,	0x007f003f },
+		{ CR_ZD1211B_TX_PWR_CTL3,	0x007f003f },
+		{ CR_ZD1211B_TX_PWR_CTL2,       0x003f001f },
+		{ CR_ZD1211B_TX_PWR_CTL1,       0x001f000f },
+		{ CR_ZD1211B_AIFS_CTL1,		0x00280028 },
+		{ CR_ZD1211B_AIFS_CTL2,		0x008C003C },
+		{ CR_ZD1211B_TXOP,		0x01800824 },
+		{ CR_SNIFFER_ON,		0 },
+		{ CR_RX_FILTER,			STA_RX_FILTER },
+		{ CR_GROUP_HASH_P1,		0x00 },
+		{ CR_GROUP_HASH_P2,		0x80000000 },
+		{ CR_REG1,			0xa4 },
+		{ CR_ADDA_PWR_DWN,		0x7f },
+		{ CR_BCN_PLCP_CFG,		0x00f00401 },
+		{ CR_PHY_DELAY,			0x00 },
+		{ CR_ACK_TIMEOUT_EXT,		0x80 },
+		{ CR_ADDA_PWR_DWN,		0x00 },
+		{ CR_ACK_TIME_80211,		0x100 },
+		{ CR_IFS_VALUE,			0x547c032 },
+		{ CR_RX_PE_DELAY,		0x70 },
+		{ CR_PS_CTRL,			0x10000000 },
+		{ CR_RTS_CTS_RATE,		0x02030203 },
+		{ CR_RX_THRESHOLD,		0x000c0640 },
+		{ CR_AFTER_PNP,			0x1 },
+		{ CR_WEP_PROTECT,		0x114 },
+	};
+
+	int r;
+
+	dev_dbg_f(zd_chip_dev(chip), "\n");
+	ZD_ASSERT(mutex_is_locked(&chip->mutex));
+	r = zd_iowrite32a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
+	if (r) {
+		dev_dbg_f(zd_chip_dev(chip),
+			"error in zd_iowrite32a_locked. Error number %d\n", r);
+	}
+	return r;
+}
+
+static int hw_init_hmac(struct zd_chip *chip)
+{
+	return chip->is_zd1211b ?
+		zd1211b_hw_init_hmac(chip) : zd1211_hw_init_hmac(chip);
+}
+
+struct aw_pt_bi {
+	u32 atim_wnd_period;
+	u32 pre_tbtt;
+	u32 beacon_interval;
+};
+
+static int get_aw_pt_bi(struct zd_chip *chip, struct aw_pt_bi *s)
+{
+	int r;
+	static const zd_addr_t aw_pt_bi_addr[] =
+		{ CR_ATIM_WND_PERIOD, CR_PRE_TBTT, CR_BCN_INTERVAL };
+	u32 values[3];
+
+	r = zd_ioread32v_locked(chip, values, (const zd_addr_t *)aw_pt_bi_addr,
+		         ARRAY_SIZE(aw_pt_bi_addr));
+	if (r) {
+		memset(s, 0, sizeof(*s));
+		return r;
+	}
+
+	s->atim_wnd_period = values[0];
+	s->pre_tbtt = values[1];
+	s->beacon_interval = values[2];
+	dev_dbg_f(zd_chip_dev(chip), "aw %u pt %u bi %u\n",
+		s->atim_wnd_period, s->pre_tbtt, s->beacon_interval);
+	return 0;
+}
+
+static int set_aw_pt_bi(struct zd_chip *chip, struct aw_pt_bi *s)
+{
+	struct zd_ioreq32 reqs[3];
+
+	if (s->beacon_interval <= 5)
+		s->beacon_interval = 5;
+	if (s->pre_tbtt < 4 || s->pre_tbtt >= s->beacon_interval)
+		s->pre_tbtt = s->beacon_interval - 1;
+	if (s->atim_wnd_period >= s->pre_tbtt)
+		s->atim_wnd_period = s->pre_tbtt - 1;
+
+	reqs[0].addr = CR_ATIM_WND_PERIOD;
+	reqs[0].value = s->atim_wnd_period;
+	reqs[1].addr = CR_PRE_TBTT;
+	reqs[1].value = s->pre_tbtt;
+	reqs[2].addr = CR_BCN_INTERVAL;
+	reqs[2].value = s->beacon_interval;
+
+	dev_dbg_f(zd_chip_dev(chip),
+		"aw %u pt %u bi %u\n", s->atim_wnd_period, s->pre_tbtt,
+		                       s->beacon_interval);
+	return zd_iowrite32a_locked(chip, reqs, ARRAY_SIZE(reqs));
+}
+
+
+static int set_beacon_interval(struct zd_chip *chip, u32 interval)
+{
+	int r;
+	struct aw_pt_bi s;
+
+	ZD_ASSERT(mutex_is_locked(&chip->mutex));
+	r = get_aw_pt_bi(chip, &s);
+	if (r)
+		return r;
+	s.beacon_interval = interval;
+	return set_aw_pt_bi(chip, &s);
+}
+
+int zd_set_beacon_interval(struct zd_chip *chip, u32 interval)
+{
+	int r;
+
+	mutex_lock(&chip->mutex);
+	r = set_beacon_interval(chip, interval);
+	mutex_unlock(&chip->mutex);
+	return r;
+}
+
+static int hw_init(struct zd_chip *chip)
+{
+	int r;
+
+	dev_dbg_f(zd_chip_dev(chip), "\n");
+	ZD_ASSERT(mutex_is_locked(&chip->mutex));
+	r = hw_reset_phy(chip);
+	if (r)
+		return r;
+
+	r = hw_init_hmac(chip);
+	if (r)
+		return r;
+	r = set_beacon_interval(chip, 100);
+	if (r)
+		return r;
+	return 0;
+}
+
+#ifdef DEBUG
+static int dump_cr(struct zd_chip *chip, const zd_addr_t addr,
+	           const char *addr_string)
+{
+	int r;
+	u32 value;
+
+	r = zd_ioread32_locked(chip, &value, addr);
+	if (r) {
+		dev_dbg_f(zd_chip_dev(chip),
+			"error reading %s. Error number %d\n", addr_string, r);
+		return r;
+	}
+
+	dev_dbg_f(zd_chip_dev(chip), "%s %#010x\n",
+		addr_string, (unsigned int)value);
+	return 0;
+}
+
+static int test_init(struct zd_chip *chip)
+{
+	int r;
+
+	r = dump_cr(chip, CR_AFTER_PNP, "CR_AFTER_PNP");
+	if (r)
+		return r;
+	r = dump_cr(chip, CR_GPI_EN, "CR_GPI_EN");
+	if (r)
+		return r;
+	return dump_cr(chip, CR_INTERRUPT, "CR_INTERRUPT");
+}
+
+static void dump_fw_registers(struct zd_chip *chip)
+{
+	static const zd_addr_t addr[4] = {
+		FW_FIRMWARE_VER, FW_USB_SPEED, FW_FIX_TX_RATE,
+		FW_LINK_STATUS
+	};
+
+	int r;
+	u16 values[4];
+
+	r = zd_ioread16v_locked(chip, values, (const zd_addr_t*)addr,
+		         ARRAY_SIZE(addr));
+	if (r) {
+		dev_dbg_f(zd_chip_dev(chip), "error %d zd_ioread16v_locked\n",
+			 r);
+		return;
+	}
+
+	dev_dbg_f(zd_chip_dev(chip), "FW_FIRMWARE_VER %#06hx\n", values[0]);
+	dev_dbg_f(zd_chip_dev(chip), "FW_USB_SPEED %#06hx\n", values[1]);
+	dev_dbg_f(zd_chip_dev(chip), "FW_FIX_TX_RATE %#06hx\n", values[2]);
+	dev_dbg_f(zd_chip_dev(chip), "FW_LINK_STATUS %#06hx\n", values[3]);
+}
+#endif /* DEBUG */
+
+static int print_fw_version(struct zd_chip *chip)
+{
+	int r;
+	u16 version;
+
+	r = zd_ioread16_locked(chip, &version, FW_FIRMWARE_VER);
+	if (r)
+		return r;
+
+	dev_info(zd_chip_dev(chip),"firmware version %04hx\n", version);
+	return 0;
+}
+
+static int set_mandatory_rates(struct zd_chip *chip, enum ieee80211_std std)
+{
+	u32 rates;
+	ZD_ASSERT(mutex_is_locked(&chip->mutex));
+	/* This sets the mandatory rates, which only depend from the standard
+	 * that the device is supporting. Until further notice we should try
+	 * to support 802.11g also for full speed USB.
+	 */
+	switch (std) {
+	case IEEE80211B:
+		rates = CR_RATE_1M|CR_RATE_2M|CR_RATE_5_5M|CR_RATE_11M;
+		break;
+	case IEEE80211G:
+		rates = CR_RATE_1M|CR_RATE_2M|CR_RATE_5_5M|CR_RATE_11M|
+			CR_RATE_6M|CR_RATE_12M|CR_RATE_24M;
+		break;
+	default:
+		return -EINVAL;
+	}
+	return zd_iowrite32_locked(chip, rates, CR_MANDATORY_RATE_TBL);
+}
+
+int zd_chip_enable_hwint(struct zd_chip *chip)
+{
+	int r;
+
+	mutex_lock(&chip->mutex);
+	r = zd_iowrite32_locked(chip, HWINT_ENABLED, CR_INTERRUPT);
+	mutex_unlock(&chip->mutex);
+	return r;
+}
+
+static int disable_hwint(struct zd_chip *chip)
+{
+	return zd_iowrite32_locked(chip, HWINT_DISABLED, CR_INTERRUPT);
+}
+
+int zd_chip_disable_hwint(struct zd_chip *chip)
+{
+	int r;
+
+	mutex_lock(&chip->mutex);
+	r = disable_hwint(chip);
+	mutex_unlock(&chip->mutex);
+	return r;
+}
+
+int zd_chip_init_hw(struct zd_chip *chip, u8 device_type)
+{
+	int r;
+	u8 rf_type;
+
+	dev_dbg_f(zd_chip_dev(chip), "\n");
+
+	mutex_lock(&chip->mutex);
+	chip->is_zd1211b = (device_type == DEVICE_ZD1211B) != 0;
+
+#ifdef DEBUG
+	r = test_init(chip);
+	if (r)
+		goto out;
+#endif
+	r = zd_iowrite32_locked(chip, 1, CR_AFTER_PNP);
+	if (r)
+		goto out;
+
+	r = zd_usb_init_hw(&chip->usb);
+	if (r)
+		goto out;
+
+	/* GPI is always disabled, also in the other driver.
+	 */
+	r = zd_iowrite32_locked(chip, 0, CR_GPI_EN);
+	if (r)
+		goto out;
+	r = zd_iowrite32_locked(chip, CWIN_SIZE, CR_CWMIN_CWMAX);
+	if (r)
+		goto out;
+	/* Currently we support IEEE 802.11g for full and high speed USB.
+	 * It might be discussed, whether we should suppport pure b mode for
+	 * full speed USB.
+	 */
+	r = set_mandatory_rates(chip, IEEE80211G);
+	if (r)
+		goto out;
+	/* Disabling interrupts is certainly a smart thing here.
+	 */
+	r = disable_hwint(chip);
+	if (r)
+		goto out;
+	r = read_pod(chip, &rf_type);
+	if (r)
+		goto out;
+	r = hw_init(chip);
+	if (r)
+		goto out;
+	r = zd_rf_init_hw(&chip->rf, rf_type);
+	if (r)
+		goto out;
+
+	r = print_fw_version(chip);
+	if (r)
+		goto out;
+
+#ifdef DEBUG
+	dump_fw_registers(chip);
+	r = test_init(chip);
+	if (r)
+		goto out;
+#endif /* DEBUG */
+
+	r = read_e2p_mac_addr(chip);
+	if (r)
+		goto out;
+
+	r = read_cal_int_tables(chip);
+	if (r)
+		goto out;
+
+	print_id(chip);
+out:
+	mutex_unlock(&chip->mutex);
+	return r;
+}
+
+static int update_pwr_int(struct zd_chip *chip, u8 channel)
+{
+	u8 value = chip->pwr_int_values[channel - 1];
+	dev_dbg_f(zd_chip_dev(chip), "channel %d pwr_int %#04x\n",
+		 channel, value);
+	return zd_iowrite32_locked(chip, value, CR31);
+}
+
+static int update_pwr_cal(struct zd_chip *chip, u8 channel)
+{
+	u8 value = chip->pwr_cal_values[channel-1];
+	dev_dbg_f(zd_chip_dev(chip), "channel %d pwr_cal %#04x\n",
+		 channel, value);
+	return zd_iowrite32_locked(chip, value, CR68);
+}
+
+static int update_ofdm_cal(struct zd_chip *chip, u8 channel)
+{
+	struct zd_ioreq32 ioreqs[3];
+
+	ioreqs[0].addr = CR67;
+	ioreqs[0].value = chip->ofdm_cal_values[OFDM_36M_INDEX][channel-1];
+	ioreqs[1].addr = CR66;
+	ioreqs[1].value = chip->ofdm_cal_values[OFDM_48M_INDEX][channel-1];
+	ioreqs[2].addr = CR65;
+	ioreqs[2].value = chip->ofdm_cal_values[OFDM_54M_INDEX][channel-1];
+
+	dev_dbg_f(zd_chip_dev(chip),
+		"channel %d ofdm_cal 36M %#04x 48M %#04x 54M %#04x\n",
+		channel, ioreqs[0].value, ioreqs[1].value, ioreqs[2].value);
+	return zd_iowrite32a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
+}
+
+static int update_channel_integration_and_calibration(struct zd_chip *chip,
+	                                              u8 channel)
+{
+	int r;
+
+	r = update_pwr_int(chip, channel);
+	if (r)
+		return r;
+	if (chip->is_zd1211b) {
+		static const struct zd_ioreq32 ioreqs[] = {
+			{ CR69, 0x28 },
+			{},
+			{ CR69, 0x2a },
+		};
+
+		r = update_ofdm_cal(chip, channel);
+		if (r)
+			return r;
+		r = update_pwr_cal(chip, channel);
+		if (r)
+			return r;
+		r = zd_iowrite32a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
+		if (r)
+			return r;
+	}
+
+	return 0;
+}
+
+/* The CCK baseband gain can be optionally patched by the EEPROM */
+static int patch_cck_gain(struct zd_chip *chip)
+{
+	int r;
+	u32 value;
+
+	if (!chip->patch_cck_gain)
+		return 0;
+
+	ZD_ASSERT(mutex_is_locked(&chip->mutex));
+	r = zd_ioread32_locked(chip, &value, E2P_PHY_REG);
+	if (r)
+		return r;
+	dev_dbg_f(zd_chip_dev(chip), "patching value %x\n", value & 0xff);
+	return zd_iowrite32_locked(chip, value & 0xff, CR47);
+}
+
+int zd_chip_set_channel(struct zd_chip *chip, u8 channel)
+{
+	int r, t;
+
+	mutex_lock(&chip->mutex);
+	r = zd_chip_lock_phy_regs(chip);
+	if (r)
+		goto out;
+	r = zd_rf_set_channel(&chip->rf, channel);
+	if (r)
+		goto unlock;
+	r = update_channel_integration_and_calibration(chip, channel);
+	if (r)
+		goto unlock;
+	r = patch_cck_gain(chip);
+	if (r)
+		goto unlock;
+	r = patch_6m_band_edge(chip, channel);
+	if (r)
+		goto unlock;
+	r = zd_iowrite32_locked(chip, 0, CR_CONFIG_PHILIPS);
+unlock:
+	t = zd_chip_unlock_phy_regs(chip);
+	if (t && !r)
+		r = t;
+out:
+	mutex_unlock(&chip->mutex);
+	return r;
+}
+
+u8 zd_chip_get_channel(struct zd_chip *chip)
+{
+	u8 channel;
+
+	mutex_lock(&chip->mutex);
+	channel = chip->rf.channel;
+	mutex_unlock(&chip->mutex);
+	return channel;
+}
+
+static u16 led_mask(int led)
+{
+	switch (led) {
+	case 1:
+		return LED1;
+	case 2:
+		return LED2;
+	default:
+		return 0;
+	}
+}
+
+static int read_led_reg(struct zd_chip *chip, u16 *status)
+{
+	ZD_ASSERT(mutex_is_locked(&chip->mutex));
+	return zd_ioread16_locked(chip, status, CR_LED);
+}
+
+static int write_led_reg(struct zd_chip *chip, u16 status)
+{
+	ZD_ASSERT(mutex_is_locked(&chip->mutex));
+	return zd_iowrite16_locked(chip, status, CR_LED);
+}
+
+int zd_chip_led_status(struct zd_chip *chip, int led, enum led_status status)
+{
+	int r, ret;
+	u16 mask = led_mask(led);
+	u16 reg;
+
+	if (!mask)
+		return -EINVAL;
+	mutex_lock(&chip->mutex);
+	r = read_led_reg(chip, &reg);
+	if (r)
+		return r;
+	switch (status) {
+	case LED_STATUS:
+		return (reg & mask) ? LED_ON : LED_OFF;
+	case LED_OFF:
+		reg &= ~mask;
+		ret = LED_OFF;
+		break;
+	case LED_FLIP:
+		reg ^= mask;
+		ret = (reg&mask) ? LED_ON : LED_OFF;
+		break;
+	case LED_ON:
+		reg |= mask;
+		ret = LED_ON;
+		break;
+	default:
+		return -EINVAL;
+	}
+	r = write_led_reg(chip, reg);
+	if (r) {
+		ret = r;
+		goto out;
+	}
+out:
+	mutex_unlock(&chip->mutex);
+	return r;
+}
+
+int zd_chip_led_flip(struct zd_chip *chip, int led,
+	const unsigned int *phases_msecs, unsigned int count)
+{
+	int i, r;
+	enum led_status status;
+
+	r = zd_chip_led_status(chip, led, LED_STATUS);
+	if (r)
+		return r;
+	status = r;
+	for (i = 0; i < count; i++) {
+		r = zd_chip_led_status(chip, led, LED_FLIP);
+		if (r < 0)
+			goto out;
+		msleep(phases_msecs[i]);
+	}
+
+out:
+	zd_chip_led_status(chip, led, status);
+	return r;
+}
+
+int zd_chip_set_basic_rates(struct zd_chip *chip, u16 cr_rates)
+{
+	int r;
+
+	if (cr_rates & ~(CR_RATES_80211B|CR_RATES_80211G))
+		return -EINVAL;
+
+	mutex_lock(&chip->mutex);
+	r = zd_iowrite32_locked(chip, cr_rates, CR_BASIC_RATE_TBL);
+	mutex_unlock(&chip->mutex);
+	return r;
+}
+
+static int ofdm_qual_db(u8 status_quality, u8 rate, unsigned int size)
+{
+	static const u16 constants[] = {
+		715, 655, 585, 540, 470, 410, 360, 315,
+		270, 235, 205, 175, 150, 125, 105,  85,
+		 65,  50,  40,  25,  15
+	};
+
+	int i;
+	u32 x;
+
+	/* It seems that their quality parameter is somehow per signal
+	 * and is now transferred per bit.
+	 */
+	switch (rate) {
+	case ZD_OFDM_RATE_6M:
+	case ZD_OFDM_RATE_12M:
+	case ZD_OFDM_RATE_24M:
+		size *= 2;
+		break;
+	case ZD_OFDM_RATE_9M:
+	case ZD_OFDM_RATE_18M:
+	case ZD_OFDM_RATE_36M:
+	case ZD_OFDM_RATE_54M:
+		size *= 4;
+		size /= 3;
+		break;
+	case ZD_OFDM_RATE_48M:
+		size *= 3;
+		size /= 2;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	x = (10000 * status_quality)/size;
+	for (i = 0; i < ARRAY_SIZE(constants); i++) {
+		if (x > constants[i])
+			break;
+	}
+
+	switch (rate) {
+	case ZD_OFDM_RATE_6M:
+	case ZD_OFDM_RATE_9M:
+		i += 3;
+		break;
+	case ZD_OFDM_RATE_12M:
+	case ZD_OFDM_RATE_18M:
+		i += 5;
+		break;
+	case ZD_OFDM_RATE_24M:
+	case ZD_OFDM_RATE_36M:
+		i += 9;
+		break;
+	case ZD_OFDM_RATE_48M:
+	case ZD_OFDM_RATE_54M:
+		i += 15;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return i;
+}
+
+static int ofdm_qual_percent(u8 status_quality, u8 rate, unsigned int size)
+{
+	int r;
+
+	r = ofdm_qual_db(status_quality, rate, size);
+	ZD_ASSERT(r >= 0);
+	if (r < 0)
+		r = 0;
+
+	r = (r * 100)/29;
+	return r <= 100 ? r : 100;
+}
+
+static unsigned int log10times100(unsigned int x)
+{
+	static const u8 log10[] = {
+		  0,
+		  0,   30,   47,   60,   69,   77,   84,   90,   95,  100,
+		104,  107,  111,  114,  117,  120,  123,  125,  127,  130,
+		132,  134,  136,  138,  139,  141,  143,  144,  146,  147,
+		149,  150,  151,  153,  154,  155,  156,  157,  159,  160,
+		161,  162,  163,  164,  165,  166,  167,  168,  169,  169,
+		170,  171,  172,  173,  174,  174,  175,  176,  177,  177,
+		178,  179,  179,  180,  181,  181,  182,  183,  183,  184,
+		185,  185,  186,  186,  187,  188,  188,  189,  189,  190,
+		190,  191,  191,  192,  192,  193,  193,  194,  194,  195,
+		195,  196,  196,  197,  197,  198,  198,  199,  199,  200,
+		200,  200,  201,  201,  202,  202,  202,  203,  203,  204,
+		204,  204,  205,  205,  206,  206,  206,  207,  207,  207,
+		208,  208,  208,  209,  209,  210,  210,  210,  211,  211,
+		211,  212,  212,  212,  213,  213,  213,  213,  214,  214,
+		214,  215,  215,  215,  216,  216,  216,  217,  217,  217,
+		217,  218,  218,  218,  219,  219,  219,  219,  220,  220,
+		220,  220,  221,  221,  221,  222,  222,  222,  222,  223,
+		223,  223,  223,  224,  224,  224,  224,
+	};
+
+	return x < ARRAY_SIZE(log10) ? log10[x] : 225;
+}
+
+enum {
+	MAX_CCK_EVM_DB = 45,
+};
+
+static int cck_evm_db(u8 status_quality)
+{
+	return (20 * log10times100(status_quality)) / 100;
+}
+
+static int cck_snr_db(u8 status_quality)
+{
+	int r = MAX_CCK_EVM_DB - cck_evm_db(status_quality);
+	ZD_ASSERT(r >= 0);
+	return r;
+}
+
+static int cck_qual_percent(u8 status_quality)
+{
+	int r;
+
+	r = cck_snr_db(status_quality);
+	r = (100*r)/17;
+	return r <= 100 ? r : 100;
+}
+
+u8 zd_rx_qual_percent(const void *rx_frame, unsigned int size,
+	              const struct rx_status *status)
+{
+	return (status->frame_status&ZD_RX_OFDM) ?
+		ofdm_qual_percent(status->signal_quality_ofdm,
+			          zd_ofdm_plcp_header_rate(rx_frame),
+			          size) :
+		cck_qual_percent(status->signal_quality_cck);
+}
+
+u8 zd_rx_strength_percent(u8 rssi)
+{
+	int r = (rssi*100) / 41;
+	if (r > 100)
+		r = 100;
+	return (u8) r;
+}
+
+u16 zd_rx_rate(const void *rx_frame, const struct rx_status *status)
+{
+	static const u16 ofdm_rates[] = {
+		[ZD_OFDM_RATE_6M]  = 60,
+		[ZD_OFDM_RATE_9M]  = 90,
+		[ZD_OFDM_RATE_12M] = 120,
+		[ZD_OFDM_RATE_18M] = 180,
+		[ZD_OFDM_RATE_24M] = 240,
+		[ZD_OFDM_RATE_36M] = 360,
+		[ZD_OFDM_RATE_48M] = 480,
+		[ZD_OFDM_RATE_54M] = 540,
+	};
+	u16 rate;
+	if (status->frame_status & ZD_RX_OFDM) {
+		u8 ofdm_rate = zd_ofdm_plcp_header_rate(rx_frame);
+		rate = ofdm_rates[ofdm_rate & 0xf];
+	} else {
+		u8 cck_rate = zd_cck_plcp_header_rate(rx_frame);
+		switch (cck_rate) {
+		case ZD_CCK_SIGNAL_1M:
+			rate = 10;
+			break;
+		case ZD_CCK_SIGNAL_2M:
+			rate = 20;
+			break;
+		case ZD_CCK_SIGNAL_5M5:
+			rate = 55;
+			break;
+		case ZD_CCK_SIGNAL_11M:
+			rate = 110;
+			break;
+		default:
+			rate = 0;
+		}
+	}
+
+	return rate;
+}
+
+int zd_chip_switch_radio_on(struct zd_chip *chip)
+{
+	int r;
+
+	mutex_lock(&chip->mutex);
+	r = zd_switch_radio_on(&chip->rf);
+	mutex_unlock(&chip->mutex);
+	return r;
+}
+
+int zd_chip_switch_radio_off(struct zd_chip *chip)
+{
+	int r;
+
+	mutex_lock(&chip->mutex);
+	r = zd_switch_radio_off(&chip->rf);
+	mutex_unlock(&chip->mutex);
+	return r;
+}
+
+int zd_chip_enable_int(struct zd_chip *chip)
+{
+	int r;
+
+	mutex_lock(&chip->mutex);
+	r = zd_usb_enable_int(&chip->usb);
+	mutex_unlock(&chip->mutex);
+	return r;
+}
+
+void zd_chip_disable_int(struct zd_chip *chip)
+{
+	mutex_lock(&chip->mutex);
+	zd_usb_disable_int(&chip->usb);
+	mutex_unlock(&chip->mutex);
+}
+
+int zd_chip_enable_rx(struct zd_chip *chip)
+{
+	int r;
+
+	mutex_lock(&chip->mutex);
+	r = zd_usb_enable_rx(&chip->usb);
+	mutex_unlock(&chip->mutex);
+	return r;
+}
+
+void zd_chip_disable_rx(struct zd_chip *chip)
+{
+	mutex_lock(&chip->mutex);
+	zd_usb_disable_rx(&chip->usb);
+	mutex_unlock(&chip->mutex);
+}
+
+int zd_rfwritev_locked(struct zd_chip *chip,
+	               const u32* values, unsigned int count, u8 bits)
+{
+	int r;
+	unsigned int i;
+
+	for (i = 0; i < count; i++) {
+		r = zd_rfwrite_locked(chip, values[i], bits);
+		if (r)
+			return r;
+	}
+
+	return 0;
+}
diff --git a/drivers/net/wireless/zd1211rw/zd_chip.h b/drivers/net/wireless/zd1211rw/zd_chip.h
new file mode 100644
index 000000000..069d2b467
--- /dev/null
+++ b/drivers/net/wireless/zd1211rw/zd_chip.h
@@ -0,0 +1,827 @@
+/* zd_chip.h
+ *
+ * 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
+ */
+
+#ifndef _ZD_CHIP_H
+#define _ZD_CHIP_H
+
+#include "zd_types.h"
+#include "zd_rf.h"
+#include "zd_usb.h"
+
+/* Header for the Media Access Controller (MAC) and the Baseband Processor
+ * (BBP). It appears that the ZD1211 wraps the old ZD1205 with USB glue and
+ * adds a processor for handling the USB protocol.
+ */
+
+/* 8-bit hardware registers */
+#define CR0   CTL_REG(0x0000)
+#define CR1   CTL_REG(0x0004)
+#define CR2   CTL_REG(0x0008)
+#define CR3   CTL_REG(0x000C)
+
+#define CR5   CTL_REG(0x0010)
+/*	bit 5: if set short preamble used
+ *	bit 6: filter band - Japan channel 14 on, else off
+ */
+#define CR6   CTL_REG(0x0014)
+#define CR7   CTL_REG(0x0018)
+#define CR8   CTL_REG(0x001C)
+
+#define CR4   CTL_REG(0x0020)
+
+#define CR9   CTL_REG(0x0024)
+/*	bit 2: antenna switch (together with CR10) */
+#define CR10  CTL_REG(0x0028)
+/*	bit 1: antenna switch (together with CR9)
+ *	RF2959 controls with CR11 radion on and off
+ */
+#define CR11  CTL_REG(0x002C)
+/*	bit 6:  TX power control for OFDM
+ *	RF2959 controls with CR10 radio on and off
+ */
+#define CR12  CTL_REG(0x0030)
+#define CR13  CTL_REG(0x0034)
+#define CR14  CTL_REG(0x0038)
+#define CR15  CTL_REG(0x003C)
+#define CR16  CTL_REG(0x0040)
+#define CR17  CTL_REG(0x0044)
+#define CR18  CTL_REG(0x0048)
+#define CR19  CTL_REG(0x004C)
+#define CR20  CTL_REG(0x0050)
+#define CR21  CTL_REG(0x0054)
+#define CR22  CTL_REG(0x0058)
+#define CR23  CTL_REG(0x005C)
+#define CR24  CTL_REG(0x0060)	/* CCA threshold */
+#define CR25  CTL_REG(0x0064)
+#define CR26  CTL_REG(0x0068)
+#define CR27  CTL_REG(0x006C)
+#define CR28  CTL_REG(0x0070)
+#define CR29  CTL_REG(0x0074)
+#define CR30  CTL_REG(0x0078)
+#define CR31  CTL_REG(0x007C)	/* TX power control for RF in CCK mode */
+#define CR32  CTL_REG(0x0080)
+#define CR33  CTL_REG(0x0084)
+#define CR34  CTL_REG(0x0088)
+#define CR35  CTL_REG(0x008C)
+#define CR36  CTL_REG(0x0090)
+#define CR37  CTL_REG(0x0094)
+#define CR38  CTL_REG(0x0098)
+#define CR39  CTL_REG(0x009C)
+#define CR40  CTL_REG(0x00A0)
+#define CR41  CTL_REG(0x00A4)
+#define CR42  CTL_REG(0x00A8)
+#define CR43  CTL_REG(0x00AC)
+#define CR44  CTL_REG(0x00B0)
+#define CR45  CTL_REG(0x00B4)
+#define CR46  CTL_REG(0x00B8)
+#define CR47  CTL_REG(0x00BC)	/* CCK baseband gain
+	                         * (patch value might be in EEPROM)
+				 */
+#define CR48  CTL_REG(0x00C0)
+#define CR49  CTL_REG(0x00C4)
+#define CR50  CTL_REG(0x00C8)
+#define CR51  CTL_REG(0x00CC)	/* TX power control for RF in 6-36M modes */
+#define CR52  CTL_REG(0x00D0)	/* TX power control for RF in 48M mode */
+#define CR53  CTL_REG(0x00D4)	/* TX power control for RF in 54M mode */
+#define CR54  CTL_REG(0x00D8)
+#define CR55  CTL_REG(0x00DC)
+#define CR56  CTL_REG(0x00E0)
+#define CR57  CTL_REG(0x00E4)
+#define CR58  CTL_REG(0x00E8)
+#define CR59  CTL_REG(0x00EC)
+#define CR60  CTL_REG(0x00F0)
+#define CR61  CTL_REG(0x00F4)
+#define CR62  CTL_REG(0x00F8)
+#define CR63  CTL_REG(0x00FC)
+#define CR64  CTL_REG(0x0100)
+#define CR65  CTL_REG(0x0104) /* OFDM 54M calibration */
+#define CR66  CTL_REG(0x0108) /* OFDM 48M calibration */
+#define CR67  CTL_REG(0x010C) /* OFDM 36M calibration */
+#define CR68  CTL_REG(0x0110) /* CCK calibration */
+#define CR69  CTL_REG(0x0114)
+#define CR70  CTL_REG(0x0118)
+#define CR71  CTL_REG(0x011C)
+#define CR72  CTL_REG(0x0120)
+#define CR73  CTL_REG(0x0124)
+#define CR74  CTL_REG(0x0128)
+#define CR75  CTL_REG(0x012C)
+#define CR76  CTL_REG(0x0130)
+#define CR77  CTL_REG(0x0134)
+#define CR78  CTL_REG(0x0138)
+#define CR79  CTL_REG(0x013C)
+#define CR80  CTL_REG(0x0140)
+#define CR81  CTL_REG(0x0144)
+#define CR82  CTL_REG(0x0148)
+#define CR83  CTL_REG(0x014C)
+#define CR84  CTL_REG(0x0150)
+#define CR85  CTL_REG(0x0154)
+#define CR86  CTL_REG(0x0158)
+#define CR87  CTL_REG(0x015C)
+#define CR88  CTL_REG(0x0160)
+#define CR89  CTL_REG(0x0164)
+#define CR90  CTL_REG(0x0168)
+#define CR91  CTL_REG(0x016C)
+#define CR92  CTL_REG(0x0170)
+#define CR93  CTL_REG(0x0174)
+#define CR94  CTL_REG(0x0178)
+#define CR95  CTL_REG(0x017C)
+#define CR96  CTL_REG(0x0180)
+#define CR97  CTL_REG(0x0184)
+#define CR98  CTL_REG(0x0188)
+#define CR99  CTL_REG(0x018C)
+#define CR100 CTL_REG(0x0190)
+#define CR101 CTL_REG(0x0194)
+#define CR102 CTL_REG(0x0198)
+#define CR103 CTL_REG(0x019C)
+#define CR104 CTL_REG(0x01A0)
+#define CR105 CTL_REG(0x01A4)
+#define CR106 CTL_REG(0x01A8)
+#define CR107 CTL_REG(0x01AC)
+#define CR108 CTL_REG(0x01B0)
+#define CR109 CTL_REG(0x01B4)
+#define CR110 CTL_REG(0x01B8)
+#define CR111 CTL_REG(0x01BC)
+#define CR112 CTL_REG(0x01C0)
+#define CR113 CTL_REG(0x01C4)
+#define CR114 CTL_REG(0x01C8)
+#define CR115 CTL_REG(0x01CC)
+#define CR116 CTL_REG(0x01D0)
+#define CR117 CTL_REG(0x01D4)
+#define CR118 CTL_REG(0x01D8)
+#define CR119 CTL_REG(0x01DC)
+#define CR120 CTL_REG(0x01E0)
+#define CR121 CTL_REG(0x01E4)
+#define CR122 CTL_REG(0x01E8)
+#define CR123 CTL_REG(0x01EC)
+#define CR124 CTL_REG(0x01F0)
+#define CR125 CTL_REG(0x01F4)
+#define CR126 CTL_REG(0x01F8)
+#define CR127 CTL_REG(0x01FC)
+#define CR128 CTL_REG(0x0200)
+#define CR129 CTL_REG(0x0204)
+#define CR130 CTL_REG(0x0208)
+#define CR131 CTL_REG(0x020C)
+#define CR132 CTL_REG(0x0210)
+#define CR133 CTL_REG(0x0214)
+#define CR134 CTL_REG(0x0218)
+#define CR135 CTL_REG(0x021C)
+#define CR136 CTL_REG(0x0220)
+#define CR137 CTL_REG(0x0224)
+#define CR138 CTL_REG(0x0228)
+#define CR139 CTL_REG(0x022C)
+#define CR140 CTL_REG(0x0230)
+#define CR141 CTL_REG(0x0234)
+#define CR142 CTL_REG(0x0238)
+#define CR143 CTL_REG(0x023C)
+#define CR144 CTL_REG(0x0240)
+#define CR145 CTL_REG(0x0244)
+#define CR146 CTL_REG(0x0248)
+#define CR147 CTL_REG(0x024C)
+#define CR148 CTL_REG(0x0250)
+#define CR149 CTL_REG(0x0254)
+#define CR150 CTL_REG(0x0258)
+#define CR151 CTL_REG(0x025C)
+#define CR152 CTL_REG(0x0260)
+#define CR153 CTL_REG(0x0264)
+#define CR154 CTL_REG(0x0268)
+#define CR155 CTL_REG(0x026C)
+#define CR156 CTL_REG(0x0270)
+#define CR157 CTL_REG(0x0274)
+#define CR158 CTL_REG(0x0278)
+#define CR159 CTL_REG(0x027C)
+#define CR160 CTL_REG(0x0280)
+#define CR161 CTL_REG(0x0284)
+#define CR162 CTL_REG(0x0288)
+#define CR163 CTL_REG(0x028C)
+#define CR164 CTL_REG(0x0290)
+#define CR165 CTL_REG(0x0294)
+#define CR166 CTL_REG(0x0298)
+#define CR167 CTL_REG(0x029C)
+#define CR168 CTL_REG(0x02A0)
+#define CR169 CTL_REG(0x02A4)
+#define CR170 CTL_REG(0x02A8)
+#define CR171 CTL_REG(0x02AC)
+#define CR172 CTL_REG(0x02B0)
+#define CR173 CTL_REG(0x02B4)
+#define CR174 CTL_REG(0x02B8)
+#define CR175 CTL_REG(0x02BC)
+#define CR176 CTL_REG(0x02C0)
+#define CR177 CTL_REG(0x02C4)
+#define CR178 CTL_REG(0x02C8)
+#define CR179 CTL_REG(0x02CC)
+#define CR180 CTL_REG(0x02D0)
+#define CR181 CTL_REG(0x02D4)
+#define CR182 CTL_REG(0x02D8)
+#define CR183 CTL_REG(0x02DC)
+#define CR184 CTL_REG(0x02E0)
+#define CR185 CTL_REG(0x02E4)
+#define CR186 CTL_REG(0x02E8)
+#define CR187 CTL_REG(0x02EC)
+#define CR188 CTL_REG(0x02F0)
+#define CR189 CTL_REG(0x02F4)
+#define CR190 CTL_REG(0x02F8)
+#define CR191 CTL_REG(0x02FC)
+#define CR192 CTL_REG(0x0300)
+#define CR193 CTL_REG(0x0304)
+#define CR194 CTL_REG(0x0308)
+#define CR195 CTL_REG(0x030C)
+#define CR196 CTL_REG(0x0310)
+#define CR197 CTL_REG(0x0314)
+#define CR198 CTL_REG(0x0318)
+#define CR199 CTL_REG(0x031C)
+#define CR200 CTL_REG(0x0320)
+#define CR201 CTL_REG(0x0324)
+#define CR202 CTL_REG(0x0328)
+#define CR203 CTL_REG(0x032C)	/* I2C bus template value & flash control */
+#define CR204 CTL_REG(0x0330)
+#define CR205 CTL_REG(0x0334)
+#define CR206 CTL_REG(0x0338)
+#define CR207 CTL_REG(0x033C)
+#define CR208 CTL_REG(0x0340)
+#define CR209 CTL_REG(0x0344)
+#define CR210 CTL_REG(0x0348)
+#define CR211 CTL_REG(0x034C)
+#define CR212 CTL_REG(0x0350)
+#define CR213 CTL_REG(0x0354)
+#define CR214 CTL_REG(0x0358)
+#define CR215 CTL_REG(0x035C)
+#define CR216 CTL_REG(0x0360)
+#define CR217 CTL_REG(0x0364)
+#define CR218 CTL_REG(0x0368)
+#define CR219 CTL_REG(0x036C)
+#define CR220 CTL_REG(0x0370)
+#define CR221 CTL_REG(0x0374)
+#define CR222 CTL_REG(0x0378)
+#define CR223 CTL_REG(0x037C)
+#define CR224 CTL_REG(0x0380)
+#define CR225 CTL_REG(0x0384)
+#define CR226 CTL_REG(0x0388)
+#define CR227 CTL_REG(0x038C)
+#define CR228 CTL_REG(0x0390)
+#define CR229 CTL_REG(0x0394)
+#define CR230 CTL_REG(0x0398)
+#define CR231 CTL_REG(0x039C)
+#define CR232 CTL_REG(0x03A0)
+#define CR233 CTL_REG(0x03A4)
+#define CR234 CTL_REG(0x03A8)
+#define CR235 CTL_REG(0x03AC)
+#define CR236 CTL_REG(0x03B0)
+
+#define CR240 CTL_REG(0x03C0)
+/*	bit 7:  host-controlled RF register writes
+ * CR241-CR245: for hardware controlled writing of RF bits, not needed for
+ *              USB
+ */
+#define CR241 CTL_REG(0x03C4)
+#define CR242 CTL_REG(0x03C8)
+#define CR243 CTL_REG(0x03CC)
+#define CR244 CTL_REG(0x03D0)
+#define CR245 CTL_REG(0x03D4)
+
+#define CR251 CTL_REG(0x03EC)	/* only used for activation and deactivation of
+				 * Airoha RFs AL2230 and AL7230B
+				 */
+#define CR252 CTL_REG(0x03F0)
+#define CR253 CTL_REG(0x03F4)
+#define CR254 CTL_REG(0x03F8)
+#define CR255 CTL_REG(0x03FC)
+
+#define CR_MAX_PHY_REG 255
+
+/* Taken from the ZYDAS driver, not all of them are relevant for the ZSD1211
+ * driver.
+ */
+
+#define CR_RF_IF_CLK			CTL_REG(0x0400)
+#define CR_RF_IF_DATA			CTL_REG(0x0404)
+#define CR_PE1_PE2			CTL_REG(0x0408)
+#define CR_PE2_DLY			CTL_REG(0x040C)
+#define CR_LE1				CTL_REG(0x0410)
+#define CR_LE2				CTL_REG(0x0414)
+/* Seems to enable/disable GPI (General Purpose IO?) */
+#define CR_GPI_EN			CTL_REG(0x0418)
+#define CR_RADIO_PD			CTL_REG(0x042C)
+#define CR_RF2948_PD			CTL_REG(0x042C)
+#define CR_ENABLE_PS_MANUAL_AGC		CTL_REG(0x043C)
+#define CR_CONFIG_PHILIPS		CTL_REG(0x0440)
+#define CR_SA2400_SER_AP		CTL_REG(0x0444)
+#define CR_I2C_WRITE			CTL_REG(0x0444)
+#define CR_SA2400_SER_RP		CTL_REG(0x0448)
+#define CR_RADIO_PE			CTL_REG(0x0458)
+#define CR_RST_BUS_MASTER		CTL_REG(0x045C)
+#define CR_RFCFG			CTL_REG(0x0464)
+#define CR_HSTSCHG			CTL_REG(0x046C)
+#define CR_PHY_ON			CTL_REG(0x0474)
+#define CR_RX_DELAY			CTL_REG(0x0478)
+#define CR_RX_PE_DELAY			CTL_REG(0x047C)
+#define CR_GPIO_1			CTL_REG(0x0490)
+#define CR_GPIO_2			CTL_REG(0x0494)
+#define CR_EncryBufMux			CTL_REG(0x04A8)
+#define CR_PS_CTRL			CTL_REG(0x0500)
+#define CR_ADDA_PWR_DWN			CTL_REG(0x0504)
+#define CR_ADDA_MBIAS_WARMTIME		CTL_REG(0x0508)
+#define CR_MAC_PS_STATE			CTL_REG(0x050C)
+
+#define CR_INTERRUPT			CTL_REG(0x0510)
+#define INT_TX_COMPLETE			0x00000001
+#define INT_RX_COMPLETE			0x00000002
+#define INT_RETRY_FAIL			0x00000004
+#define INT_WAKEUP			0x00000008
+#define INT_DTIM_NOTIFY			0x00000020
+#define INT_CFG_NEXT_BCN		0x00000040
+#define INT_BUS_ABORT			0x00000080
+#define INT_TX_FIFO_READY		0x00000100
+#define INT_UART			0x00000200
+#define INT_TX_COMPLETE_EN		0x00010000
+#define INT_RX_COMPLETE_EN		0x00020000
+#define INT_RETRY_FAIL_EN		0x00040000
+#define INT_WAKEUP_EN			0x00080000
+#define INT_DTIM_NOTIFY_EN		0x00200000
+#define INT_CFG_NEXT_BCN_EN		0x00400000
+#define INT_BUS_ABORT_EN		0x00800000
+#define INT_TX_FIFO_READY_EN		0x01000000
+#define INT_UART_EN			0x02000000
+
+#define CR_TSF_LOW_PART			CTL_REG(0x0514)
+#define CR_TSF_HIGH_PART		CTL_REG(0x0518)
+
+/* Following three values are in time units (1024us)
+ * Following condition must be met:
+ * atim < tbtt < bcn
+ */
+#define CR_ATIM_WND_PERIOD		CTL_REG(0x051C)
+#define CR_BCN_INTERVAL			CTL_REG(0x0520)
+#define CR_PRE_TBTT			CTL_REG(0x0524)
+/* in units of TU(1024us) */
+
+/* for UART support */
+#define CR_UART_RBR_THR_DLL		CTL_REG(0x0540)
+#define CR_UART_DLM_IER			CTL_REG(0x0544)
+#define CR_UART_IIR_FCR			CTL_REG(0x0548)
+#define CR_UART_LCR			CTL_REG(0x054c)
+#define CR_UART_MCR			CTL_REG(0x0550)
+#define CR_UART_LSR			CTL_REG(0x0554)
+#define CR_UART_MSR			CTL_REG(0x0558)
+#define CR_UART_ECR			CTL_REG(0x055c)
+#define CR_UART_STATUS			CTL_REG(0x0560)
+
+#define CR_PCI_TX_ADDR_P1		CTL_REG(0x0600)
+#define CR_PCI_TX_AddR_P2		CTL_REG(0x0604)
+#define CR_PCI_RX_AddR_P1		CTL_REG(0x0608)
+#define CR_PCI_RX_AddR_P2		CTL_REG(0x060C)
+
+/* must be overwritten if custom MAC address will be used */
+#define CR_MAC_ADDR_P1			CTL_REG(0x0610)
+#define CR_MAC_ADDR_P2			CTL_REG(0x0614)
+#define CR_BSSID_P1			CTL_REG(0x0618)
+#define CR_BSSID_P2			CTL_REG(0x061C)
+#define CR_BCN_PLCP_CFG			CTL_REG(0x0620)
+#define CR_GROUP_HASH_P1		CTL_REG(0x0624)
+#define CR_GROUP_HASH_P2		CTL_REG(0x0628)
+#define CR_RX_TIMEOUT			CTL_REG(0x062C)
+
+/* Basic rates supported by the BSS. When producing ACK or CTS messages, the
+ * device will use a rate in this table that is less than or equal to the rate
+ * of the incoming frame which prompted the response */
+#define CR_BASIC_RATE_TBL		CTL_REG(0x0630)
+#define CR_RATE_1M	0x0001	/* 802.11b */
+#define CR_RATE_2M	0x0002	/* 802.11b */
+#define CR_RATE_5_5M	0x0004	/* 802.11b */
+#define CR_RATE_11M	0x0008	/* 802.11b */
+#define CR_RATE_6M      0x0100	/* 802.11g */
+#define CR_RATE_9M      0x0200	/* 802.11g */
+#define CR_RATE_12M	0x0400	/* 802.11g */
+#define CR_RATE_18M	0x0800	/* 802.11g */
+#define CR_RATE_24M     0x1000	/* 802.11g */
+#define CR_RATE_36M     0x2000	/* 802.11g */
+#define CR_RATE_48M     0x4000	/* 802.11g */
+#define CR_RATE_54M     0x8000	/* 802.11g */
+#define CR_RATES_80211G	0xff00
+#define CR_RATES_80211B	0x000f
+
+/* Mandatory rates required in the BSS. When producing ACK or CTS messages, if
+ * the device could not find an appropriate rate in CR_BASIC_RATE_TBL, it will
+ * look for a rate in this table that is less than or equal to the rate of
+ * the incoming frame. */
+#define CR_MANDATORY_RATE_TBL		CTL_REG(0x0634)
+#define CR_RTS_CTS_RATE			CTL_REG(0x0638)
+
+#define CR_WEP_PROTECT			CTL_REG(0x063C)
+#define CR_RX_THRESHOLD			CTL_REG(0x0640)
+
+/* register for controlling the LEDS */
+#define CR_LED				CTL_REG(0x0644)
+/* masks for controlling LEDs */
+#define LED1				0x0100
+#define LED2				0x0200
+
+/* Seems to indicate that the configuration is over.
+ */
+#define CR_AFTER_PNP			CTL_REG(0x0648)
+#define CR_ACK_TIME_80211		CTL_REG(0x0658)
+
+#define CR_RX_OFFSET			CTL_REG(0x065c)
+
+#define CR_PHY_DELAY			CTL_REG(0x066C)
+#define CR_BCN_FIFO			CTL_REG(0x0670)
+#define CR_SNIFFER_ON			CTL_REG(0x0674)
+
+#define CR_ENCRYPTION_TYPE		CTL_REG(0x0678)
+#define NO_WEP				0
+#define WEP64				1
+#define WEP128				5
+#define WEP256				6
+#define ENC_SNIFFER			8
+
+#define CR_ZD1211_RETRY_MAX		CTL_REG(0x067C)
+
+#define CR_REG1				CTL_REG(0x0680)
+/* Setting the bit UNLOCK_PHY_REGS disallows the write access to physical
+ * registers, so one could argue it is a LOCK bit. But calling it
+ * LOCK_PHY_REGS makes it confusing.
+ */
+#define UNLOCK_PHY_REGS			0x0080
+
+#define CR_DEVICE_STATE			CTL_REG(0x0684)
+#define CR_UNDERRUN_CNT			CTL_REG(0x0688)
+
+#define CR_RX_FILTER			CTL_REG(0x068c)
+#define RX_FILTER_ASSOC_RESPONSE	0x0002
+#define RX_FILTER_REASSOC_RESPONSE	0x0008
+#define RX_FILTER_PROBE_RESPONSE	0x0020
+#define RX_FILTER_BEACON		0x0100
+#define RX_FILTER_DISASSOC		0x0400
+#define RX_FILTER_AUTH			0x0800
+#define AP_RX_FILTER			0x0400feff
+#define STA_RX_FILTER			0x0000ffff
+
+/* Monitor mode sets filter to 0xfffff */
+
+#define CR_ACK_TIMEOUT_EXT		CTL_REG(0x0690)
+#define CR_BCN_FIFO_SEMAPHORE		CTL_REG(0x0694)
+#define CR_IFS_VALUE			CTL_REG(0x0698)
+#define CR_RX_TIME_OUT			CTL_REG(0x069C)
+#define CR_TOTAL_RX_FRM			CTL_REG(0x06A0)
+#define CR_CRC32_CNT			CTL_REG(0x06A4)
+#define CR_CRC16_CNT			CTL_REG(0x06A8)
+#define CR_DECRYPTION_ERR_UNI		CTL_REG(0x06AC)
+#define CR_RX_FIFO_OVERRUN		CTL_REG(0x06B0)
+
+#define CR_DECRYPTION_ERR_MUL		CTL_REG(0x06BC)
+
+#define CR_NAV_CNT			CTL_REG(0x06C4)
+#define CR_NAV_CCA			CTL_REG(0x06C8)
+#define CR_RETRY_CNT			CTL_REG(0x06CC)
+
+#define CR_READ_TCB_ADDR		CTL_REG(0x06E8)
+#define CR_READ_RFD_ADDR		CTL_REG(0x06EC)
+#define CR_CWMIN_CWMAX			CTL_REG(0x06F0)
+#define CR_TOTAL_TX_FRM			CTL_REG(0x06F4)
+
+/* CAM: Continuous Access Mode (power management) */
+#define CR_CAM_MODE			CTL_REG(0x0700)
+#define CR_CAM_ROLL_TB_LOW		CTL_REG(0x0704)
+#define CR_CAM_ROLL_TB_HIGH		CTL_REG(0x0708)
+#define CR_CAM_ADDRESS			CTL_REG(0x070C)
+#define CR_CAM_DATA			CTL_REG(0x0710)
+
+#define CR_ROMDIR			CTL_REG(0x0714)
+
+#define CR_DECRY_ERR_FLG_LOW		CTL_REG(0x0714)
+#define CR_DECRY_ERR_FLG_HIGH		CTL_REG(0x0718)
+
+#define CR_WEPKEY0			CTL_REG(0x0720)
+#define CR_WEPKEY1			CTL_REG(0x0724)
+#define CR_WEPKEY2			CTL_REG(0x0728)
+#define CR_WEPKEY3			CTL_REG(0x072C)
+#define CR_WEPKEY4			CTL_REG(0x0730)
+#define CR_WEPKEY5			CTL_REG(0x0734)
+#define CR_WEPKEY6			CTL_REG(0x0738)
+#define CR_WEPKEY7			CTL_REG(0x073C)
+#define CR_WEPKEY8			CTL_REG(0x0740)
+#define CR_WEPKEY9			CTL_REG(0x0744)
+#define CR_WEPKEY10			CTL_REG(0x0748)
+#define CR_WEPKEY11			CTL_REG(0x074C)
+#define CR_WEPKEY12			CTL_REG(0x0750)
+#define CR_WEPKEY13			CTL_REG(0x0754)
+#define CR_WEPKEY14			CTL_REG(0x0758)
+#define CR_WEPKEY15			CTL_REG(0x075c)
+#define CR_TKIP_MODE			CTL_REG(0x0760)
+
+#define CR_EEPROM_PROTECT0		CTL_REG(0x0758)
+#define CR_EEPROM_PROTECT1		CTL_REG(0x075C)
+
+#define CR_DBG_FIFO_RD			CTL_REG(0x0800)
+#define CR_DBG_SELECT			CTL_REG(0x0804)
+#define CR_FIFO_Length			CTL_REG(0x0808)
+
+
+#define CR_RSSI_MGC			CTL_REG(0x0810)
+
+#define CR_PON				CTL_REG(0x0818)
+#define CR_RX_ON			CTL_REG(0x081C)
+#define CR_TX_ON			CTL_REG(0x0820)
+#define CR_CHIP_EN			CTL_REG(0x0824)
+#define CR_LO_SW			CTL_REG(0x0828)
+#define CR_TXRX_SW			CTL_REG(0x082C)
+#define CR_S_MD				CTL_REG(0x0830)
+
+#define CR_USB_DEBUG_PORT		CTL_REG(0x0888)
+
+#define CR_ZD1211B_TX_PWR_CTL1		CTL_REG(0x0b00)
+#define CR_ZD1211B_TX_PWR_CTL2		CTL_REG(0x0b04)
+#define CR_ZD1211B_TX_PWR_CTL3		CTL_REG(0x0b08)
+#define CR_ZD1211B_TX_PWR_CTL4		CTL_REG(0x0b0c)
+#define CR_ZD1211B_AIFS_CTL1		CTL_REG(0x0b10)
+#define CR_ZD1211B_AIFS_CTL2		CTL_REG(0x0b14)
+#define CR_ZD1211B_TXOP			CTL_REG(0x0b20)
+#define CR_ZD1211B_RETRY_MAX		CTL_REG(0x0b28)
+
+#define CWIN_SIZE			0x007f043f
+
+
+#define HWINT_ENABLED			0x004f0000
+#define HWINT_DISABLED			0
+
+#define E2P_PWR_INT_GUARD		8
+#define E2P_CHANNEL_COUNT		14
+
+/* If you compare this addresses with the ZYDAS orignal driver, please notify
+ * that we use word mapping for the EEPROM.
+ */
+
+/*
+ * Upper 16 bit contains the regulatory domain.
+ */
+#define E2P_SUBID		E2P_REG(0x00)
+#define E2P_POD			E2P_REG(0x02)
+#define E2P_MAC_ADDR_P1		E2P_REG(0x04)
+#define E2P_MAC_ADDR_P2		E2P_REG(0x06)
+#define E2P_PWR_CAL_VALUE1	E2P_REG(0x08)
+#define E2P_PWR_CAL_VALUE2	E2P_REG(0x0a)
+#define E2P_PWR_CAL_VALUE3	E2P_REG(0x0c)
+#define E2P_PWR_CAL_VALUE4      E2P_REG(0x0e)
+#define E2P_PWR_INT_VALUE1	E2P_REG(0x10)
+#define E2P_PWR_INT_VALUE2	E2P_REG(0x12)
+#define E2P_PWR_INT_VALUE3	E2P_REG(0x14)
+#define E2P_PWR_INT_VALUE4	E2P_REG(0x16)
+
+/* Contains a bit for each allowed channel. It gives for Europe (ETSI 0x30)
+ * also only 11 channels. */
+#define E2P_ALLOWED_CHANNEL	E2P_REG(0x18)
+
+#define E2P_PHY_REG		E2P_REG(0x1a)
+#define E2P_DEVICE_VER		E2P_REG(0x20)
+#define E2P_36M_CAL_VALUE1	E2P_REG(0x28)
+#define E2P_36M_CAL_VALUE2      E2P_REG(0x2a)
+#define E2P_36M_CAL_VALUE3      E2P_REG(0x2c)
+#define E2P_36M_CAL_VALUE4	E2P_REG(0x2e)
+#define E2P_11A_INT_VALUE1	E2P_REG(0x30)
+#define E2P_11A_INT_VALUE2	E2P_REG(0x32)
+#define E2P_11A_INT_VALUE3	E2P_REG(0x34)
+#define E2P_11A_INT_VALUE4	E2P_REG(0x36)
+#define E2P_48M_CAL_VALUE1	E2P_REG(0x38)
+#define E2P_48M_CAL_VALUE2	E2P_REG(0x3a)
+#define E2P_48M_CAL_VALUE3	E2P_REG(0x3c)
+#define E2P_48M_CAL_VALUE4	E2P_REG(0x3e)
+#define E2P_48M_INT_VALUE1	E2P_REG(0x40)
+#define E2P_48M_INT_VALUE2	E2P_REG(0x42)
+#define E2P_48M_INT_VALUE3	E2P_REG(0x44)
+#define E2P_48M_INT_VALUE4	E2P_REG(0x46)
+#define E2P_54M_CAL_VALUE1	E2P_REG(0x48)	/* ??? */
+#define E2P_54M_CAL_VALUE2	E2P_REG(0x4a)
+#define E2P_54M_CAL_VALUE3	E2P_REG(0x4c)
+#define E2P_54M_CAL_VALUE4	E2P_REG(0x4e)
+#define E2P_54M_INT_VALUE1	E2P_REG(0x50)
+#define E2P_54M_INT_VALUE2	E2P_REG(0x52)
+#define E2P_54M_INT_VALUE3	E2P_REG(0x54)
+#define E2P_54M_INT_VALUE4	E2P_REG(0x56)
+
+/* All 16 bit values */
+#define FW_FIRMWARE_VER         FW_REG(0)
+/* non-zero if USB high speed connection */
+#define FW_USB_SPEED            FW_REG(1)
+#define FW_FIX_TX_RATE          FW_REG(2)
+/* Seems to be able to control LEDs over the firmware */
+#define FW_LINK_STATUS          FW_REG(3)
+#define FW_SOFT_RESET           FW_REG(4)
+#define FW_FLASH_CHK            FW_REG(5)
+
+enum {
+	CR_BASE_OFFSET			= 0x9000,
+	FW_START_OFFSET			= 0xee00,
+	FW_BASE_ADDR_OFFSET		= FW_START_OFFSET + 0x1d,
+	EEPROM_START_OFFSET		= 0xf800,
+	EEPROM_SIZE			= 0x800, /* words */
+	LOAD_CODE_SIZE			= 0xe, /* words */
+	LOAD_VECT_SIZE			= 0x10000 - 0xfff7, /* words */
+	EEPROM_REGS_OFFSET		= LOAD_CODE_SIZE + LOAD_VECT_SIZE,
+	E2P_BASE_OFFSET			= EEPROM_START_OFFSET +
+		                          EEPROM_REGS_OFFSET,
+};
+
+#define FW_REG_TABLE_ADDR	USB_ADDR(FW_START_OFFSET + 0x1d)
+
+enum {
+	/* indices for ofdm_cal_values */
+	OFDM_36M_INDEX = 0,
+	OFDM_48M_INDEX = 1,
+	OFDM_54M_INDEX = 2,
+};
+
+struct zd_chip {
+	struct zd_usb usb;
+	struct zd_rf rf;
+	struct mutex mutex;
+	u8 e2p_mac[ETH_ALEN];
+	/* EepSetPoint in the vendor driver */
+	u8 pwr_cal_values[E2P_CHANNEL_COUNT];
+	/* integration values in the vendor driver */
+	u8 pwr_int_values[E2P_CHANNEL_COUNT];
+	/* SetPointOFDM in the vendor driver */
+	u8 ofdm_cal_values[3][E2P_CHANNEL_COUNT];
+	u8 pa_type:4, patch_cck_gain:1, patch_cr157:1, patch_6m_band_edge:1,
+	   is_zd1211b:1;
+};
+
+static inline struct zd_chip *zd_usb_to_chip(struct zd_usb *usb)
+{
+	return container_of(usb, struct zd_chip, usb);
+}
+
+static inline struct zd_chip *zd_rf_to_chip(struct zd_rf *rf)
+{
+	return container_of(rf, struct zd_chip, rf);
+}
+
+#define zd_chip_dev(chip) (&(chip)->usb.intf->dev)
+
+void zd_chip_init(struct zd_chip *chip,
+	         struct net_device *netdev,
+	         struct usb_interface *intf);
+void zd_chip_clear(struct zd_chip *chip);
+int zd_chip_init_hw(struct zd_chip *chip, u8 device_type);
+int zd_chip_reset(struct zd_chip *chip);
+
+static inline int zd_ioread16v_locked(struct zd_chip *chip, u16 *values,
+	                              const zd_addr_t *addresses,
+				      unsigned int count)
+{
+	ZD_ASSERT(mutex_is_locked(&chip->mutex));
+	return zd_usb_ioread16v(&chip->usb, values, addresses, count);
+}
+
+static inline int zd_ioread16_locked(struct zd_chip *chip, u16 *value,
+	                             const zd_addr_t addr)
+{
+	ZD_ASSERT(mutex_is_locked(&chip->mutex));
+	return zd_usb_ioread16(&chip->usb, value, addr);
+}
+
+int zd_ioread32v_locked(struct zd_chip *chip, u32 *values,
+	                const zd_addr_t *addresses, unsigned int count);
+
+static inline int zd_ioread32_locked(struct zd_chip *chip, u32 *value,
+	                             const zd_addr_t addr)
+{
+	return zd_ioread32v_locked(chip, value, (const zd_addr_t *)&addr, 1);
+}
+
+static inline int zd_iowrite16_locked(struct zd_chip *chip, u16 value,
+	                              zd_addr_t addr)
+{
+	struct zd_ioreq16 ioreq;
+
+	ZD_ASSERT(mutex_is_locked(&chip->mutex));
+	ioreq.addr = addr;
+	ioreq.value = value;
+
+	return zd_usb_iowrite16v(&chip->usb, &ioreq, 1);
+}
+
+int zd_iowrite16a_locked(struct zd_chip *chip,
+                         const struct zd_ioreq16 *ioreqs, unsigned int count);
+
+int _zd_iowrite32v_locked(struct zd_chip *chip, const struct zd_ioreq32 *ioreqs,
+			  unsigned int count);
+
+static inline int zd_iowrite32_locked(struct zd_chip *chip, u32 value,
+	                              zd_addr_t addr)
+{
+	struct zd_ioreq32 ioreq;
+
+	ioreq.addr = addr;
+	ioreq.value = value;
+
+	return _zd_iowrite32v_locked(chip, &ioreq, 1);
+}
+
+int zd_iowrite32a_locked(struct zd_chip *chip,
+	                 const struct zd_ioreq32 *ioreqs, unsigned int count);
+
+static inline int zd_rfwrite_locked(struct zd_chip *chip, u32 value, u8 bits)
+{
+	ZD_ASSERT(mutex_is_locked(&chip->mutex));
+	return zd_usb_rfwrite(&chip->usb, value, bits);
+}
+
+int zd_rfwritev_locked(struct zd_chip *chip,
+	               const u32* values, unsigned int count, u8 bits);
+
+/* Locking functions for reading and writing registers.
+ * The different parameters are intentional.
+ */
+int zd_ioread16(struct zd_chip *chip, zd_addr_t addr, u16 *value);
+int zd_iowrite16(struct zd_chip *chip, zd_addr_t addr, u16 value);
+int zd_ioread32(struct zd_chip *chip, zd_addr_t addr, u32 *value);
+int zd_iowrite32(struct zd_chip *chip, zd_addr_t addr, u32 value);
+int zd_ioread32v(struct zd_chip *chip, const zd_addr_t *addresses,
+	          u32 *values, unsigned int count);
+int zd_iowrite32a(struct zd_chip *chip, const struct zd_ioreq32 *ioreqs,
+	           unsigned int count);
+
+int zd_chip_set_channel(struct zd_chip *chip, u8 channel);
+static inline u8 _zd_chip_get_channel(struct zd_chip *chip)
+{
+	return chip->rf.channel;
+}
+u8  zd_chip_get_channel(struct zd_chip *chip);
+int zd_read_regdomain(struct zd_chip *chip, u8 *regdomain);
+void zd_get_e2p_mac_addr(struct zd_chip *chip, u8 *mac_addr);
+int zd_read_mac_addr(struct zd_chip *chip, u8 *mac_addr);
+int zd_write_mac_addr(struct zd_chip *chip, const u8 *mac_addr);
+int zd_chip_switch_radio_on(struct zd_chip *chip);
+int zd_chip_switch_radio_off(struct zd_chip *chip);
+int zd_chip_enable_int(struct zd_chip *chip);
+void zd_chip_disable_int(struct zd_chip *chip);
+int zd_chip_enable_rx(struct zd_chip *chip);
+void zd_chip_disable_rx(struct zd_chip *chip);
+int zd_chip_enable_hwint(struct zd_chip *chip);
+int zd_chip_disable_hwint(struct zd_chip *chip);
+
+static inline int zd_get_encryption_type(struct zd_chip *chip, u32 *type)
+{
+	return zd_ioread32(chip, CR_ENCRYPTION_TYPE, type);
+}
+
+static inline int zd_set_encryption_type(struct zd_chip *chip, u32 type)
+{
+	return zd_iowrite32(chip, CR_ENCRYPTION_TYPE, type);
+}
+
+static inline int zd_chip_get_basic_rates(struct zd_chip *chip, u16 *cr_rates)
+{
+	return zd_ioread16(chip, CR_BASIC_RATE_TBL, cr_rates);
+}
+
+int zd_chip_set_basic_rates(struct zd_chip *chip, u16 cr_rates);
+
+static inline int zd_chip_set_rx_filter(struct zd_chip *chip, u32 filter)
+{
+	return zd_iowrite32(chip, CR_RX_FILTER, filter);
+}
+
+int zd_chip_lock_phy_regs(struct zd_chip *chip);
+int zd_chip_unlock_phy_regs(struct zd_chip *chip);
+
+enum led_status {
+	LED_OFF	   = 0,
+	LED_ON     = 1,
+	LED_FLIP   = 2,
+	LED_STATUS = 3,
+};
+
+int zd_chip_led_status(struct zd_chip *chip, int led, enum led_status status);
+int zd_chip_led_flip(struct zd_chip *chip, int led,
+	             const unsigned int *phases_msecs, unsigned int count);
+
+int zd_set_beacon_interval(struct zd_chip *chip, u32 interval);
+
+static inline int zd_get_beacon_interval(struct zd_chip *chip, u32 *interval)
+{
+	return zd_ioread32(chip, CR_BCN_INTERVAL, interval);
+}
+
+struct rx_status;
+
+u8 zd_rx_qual_percent(const void *rx_frame, unsigned int size,
+	               const struct rx_status *status);
+u8 zd_rx_strength_percent(u8 rssi);
+
+u16 zd_rx_rate(const void *rx_frame, const struct rx_status *status);
+
+#endif /* _ZD_CHIP_H */
diff --git a/drivers/net/wireless/zd1211rw/zd_def.h b/drivers/net/wireless/zd1211rw/zd_def.h
new file mode 100644
index 000000000..465906812
--- /dev/null
+++ b/drivers/net/wireless/zd1211rw/zd_def.h
@@ -0,0 +1,48 @@
+/* zd_def.h
+ *
+ * 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
+ */
+
+#ifndef _ZD_DEF_H
+#define _ZD_DEF_H
+
+#include <linux/kernel.h>
+#include <linux/stringify.h>
+#include <linux/device.h>
+#include <linux/kernel.h>
+
+#define dev_printk_f(level, dev, fmt, args...) \
+	dev_printk(level, dev, "%s() " fmt, __func__, ##args)
+
+#ifdef DEBUG
+#  define dev_dbg_f(dev, fmt, args...) \
+	  dev_printk_f(KERN_DEBUG, dev, fmt, ## args)
+#else
+#  define dev_dbg_f(dev, fmt, args...) do { (void)(dev); } while (0)
+#endif /* DEBUG */
+
+#ifdef DEBUG
+#  define ZD_ASSERT(x) \
+do { \
+	if (!(x)) { \
+		pr_debug("%s:%d ASSERT %s VIOLATED!\n", \
+			__FILE__, __LINE__, __stringify(x)); \
+	} \
+} while (0)
+#else
+#  define ZD_ASSERT(x) do { } while (0)
+#endif
+
+#endif /* _ZD_DEF_H */
diff --git a/drivers/net/wireless/zd1211rw/zd_ieee80211.c b/drivers/net/wireless/zd1211rw/zd_ieee80211.c
new file mode 100644
index 000000000..66905f7b6
--- /dev/null
+++ b/drivers/net/wireless/zd1211rw/zd_ieee80211.c
@@ -0,0 +1,191 @@
+/* zd_ieee80211.c
+ *
+ * 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
+ */
+
+/*
+ * A lot of this code is generic and should be moved into the upper layers
+ * at some point.
+ */
+
+#include <linux/errno.h>
+#include <linux/wireless.h>
+#include <linux/kernel.h>
+#include <net/ieee80211.h>
+
+#include "zd_def.h"
+#include "zd_ieee80211.h"
+#include "zd_mac.h"
+
+static const struct channel_range channel_ranges[] = {
+	[0]			 = { 0,  0},
+	[ZD_REGDOMAIN_FCC]	 = { 1, 12},
+	[ZD_REGDOMAIN_IC]	 = { 1, 12},
+	[ZD_REGDOMAIN_ETSI]	 = { 1, 14},
+	[ZD_REGDOMAIN_JAPAN]	 = { 1, 14},
+	[ZD_REGDOMAIN_SPAIN]	 = { 1, 14},
+	[ZD_REGDOMAIN_FRANCE]	 = { 1, 14},
+	[ZD_REGDOMAIN_JAPAN_ADD] = {14, 15},
+};
+
+const struct channel_range *zd_channel_range(u8 regdomain)
+{
+	if (regdomain >= ARRAY_SIZE(channel_ranges))
+		regdomain = 0;
+	return &channel_ranges[regdomain];
+}
+
+int zd_regdomain_supports_channel(u8 regdomain, u8 channel)
+{
+	const struct channel_range *range = zd_channel_range(regdomain);
+	return range->start <= channel && channel < range->end;
+}
+
+int zd_regdomain_supported(u8 regdomain)
+{
+	const struct channel_range *range = zd_channel_range(regdomain);
+	return range->start != 0;
+}
+
+/* Stores channel frequencies in MHz. */
+static const u16 channel_frequencies[] = {
+	2412, 2417, 2422, 2427, 2432, 2437, 2442, 2447,
+	2452, 2457, 2462, 2467, 2472, 2484,
+};
+
+#define NUM_CHANNELS ARRAY_SIZE(channel_frequencies)
+
+static int compute_freq(struct iw_freq *freq, u32 mhz, u32 hz)
+{
+	u32 factor;
+
+	freq->e = 0;
+	if (mhz >= 1000000000U) {
+		pr_debug("zd1211 mhz %u to large\n", mhz);
+		freq->m = 0;
+		return -EINVAL;
+	}
+
+	factor = 1000;
+	while (mhz >= factor) {
+
+		freq->e += 1;
+		factor *= 10;
+	}
+
+	factor /= 1000U;
+	freq->m = mhz * (1000000U/factor) + hz/factor;
+
+	return 0;
+}
+
+int zd_channel_to_freq(struct iw_freq *freq, u8 channel)
+{
+	if (channel > NUM_CHANNELS) {
+		freq->m = 0;
+		freq->e = 0;
+		return -EINVAL;
+	}
+	if (!channel) {
+		freq->m = 0;
+		freq->e = 0;
+		return -EINVAL;
+	}
+	return compute_freq(freq, channel_frequencies[channel-1], 0);
+}
+
+static int freq_to_mhz(const struct iw_freq *freq)
+{
+	u32 factor;
+	int e;
+
+	/* Such high frequencies are not supported. */
+	if (freq->e > 6)
+		return -EINVAL;
+
+	factor = 1;
+	for (e = freq->e; e > 0; --e) {
+		factor *= 10;
+	}
+	factor = 1000000U / factor;
+
+	if (freq->m % factor) {
+		return -EINVAL;
+	}
+
+	return freq->m / factor;
+}
+
+int zd_find_channel(u8 *channel, const struct iw_freq *freq)
+{
+	int i, r;
+	u32 mhz;
+
+	if (!(freq->flags & IW_FREQ_FIXED))
+		return 0;
+
+	if (freq->m < 1000) {
+		if (freq->m  > NUM_CHANNELS || freq->m == 0)
+			return -EINVAL;
+		*channel = freq->m;
+		return 1;
+	}
+
+	r = freq_to_mhz(freq);
+	if (r < 0)
+		return r;
+	mhz = r;
+
+	for (i = 0; i < NUM_CHANNELS; i++) {
+		if (mhz == channel_frequencies[i]) {
+			*channel = i+1;
+			return 1;
+		}
+	}
+
+	return -EINVAL;
+}
+
+int zd_geo_init(struct ieee80211_device *ieee, u8 regdomain)
+{
+	struct ieee80211_geo geo;
+	const struct channel_range *range;
+	int i;
+	u8 channel;
+
+	dev_dbg(zd_mac_dev(zd_netdev_mac(ieee->dev)),
+		"regdomain %#04x\n", regdomain);
+
+	range = zd_channel_range(regdomain);
+	if (range->start == 0) {
+		dev_err(zd_mac_dev(zd_netdev_mac(ieee->dev)),
+			"zd1211 regdomain %#04x not supported\n",
+			regdomain);
+		return -EINVAL;
+	}
+
+	memset(&geo, 0, sizeof(geo));
+
+	for (i = 0, channel = range->start; channel < range->end; channel++) {
+		struct ieee80211_channel *chan = &geo.bg[i++];
+		chan->freq = channel_frequencies[channel - 1];
+		chan->channel = channel;
+	}
+
+	geo.bg_channels = i;
+	memcpy(geo.name, "XX ", 4);
+	ieee80211_set_geo(ieee, &geo);
+	return 0;
+}
diff --git a/drivers/net/wireless/zd1211rw/zd_ieee80211.h b/drivers/net/wireless/zd1211rw/zd_ieee80211.h
new file mode 100644
index 000000000..36329890d
--- /dev/null
+++ b/drivers/net/wireless/zd1211rw/zd_ieee80211.h
@@ -0,0 +1,85 @@
+#ifndef _ZD_IEEE80211_H
+#define _ZD_IEEE80211_H
+
+#include <net/ieee80211.h>
+#include "zd_types.h"
+
+/* Additional definitions from the standards.
+ */
+
+#define ZD_REGDOMAIN_FCC	0x10
+#define ZD_REGDOMAIN_IC		0x20
+#define ZD_REGDOMAIN_ETSI	0x30
+#define ZD_REGDOMAIN_SPAIN	0x31
+#define ZD_REGDOMAIN_FRANCE	0x32
+#define ZD_REGDOMAIN_JAPAN_ADD	0x40
+#define ZD_REGDOMAIN_JAPAN	0x41
+
+enum {
+	MIN_CHANNEL24 = 1,
+	MAX_CHANNEL24 = 14,
+};
+
+struct channel_range {
+	u8 start;
+	u8 end; /* exclusive (channel must be less than end) */
+};
+
+struct iw_freq;
+
+int zd_geo_init(struct ieee80211_device *ieee, u8 regdomain);
+
+const struct channel_range *zd_channel_range(u8 regdomain);
+int zd_regdomain_supports_channel(u8 regdomain, u8 channel);
+int zd_regdomain_supported(u8 regdomain);
+
+/* for 2.4 GHz band */
+int zd_channel_to_freq(struct iw_freq *freq, u8 channel);
+int zd_find_channel(u8 *channel, const struct iw_freq *freq);
+
+#define ZD_PLCP_SERVICE_LENGTH_EXTENSION 0x80
+
+struct ofdm_plcp_header {
+	u8 prefix[3];
+	__le16 service;
+} __attribute__((packed));
+
+static inline u8 zd_ofdm_plcp_header_rate(
+	const struct ofdm_plcp_header *header)
+{
+	return header->prefix[0] & 0xf;
+}
+
+#define ZD_OFDM_RATE_6M		0xb
+#define ZD_OFDM_RATE_9M		0xf
+#define ZD_OFDM_RATE_12M	0xa
+#define ZD_OFDM_RATE_18M	0xe
+#define ZD_OFDM_RATE_24M	0x9
+#define ZD_OFDM_RATE_36M	0xd
+#define ZD_OFDM_RATE_48M	0x8
+#define ZD_OFDM_RATE_54M	0xc
+
+struct cck_plcp_header {
+	u8 signal;
+	u8 service;
+	__le16 length;
+	__le16 crc16;
+} __attribute__((packed));
+
+static inline u8 zd_cck_plcp_header_rate(const struct cck_plcp_header *header)
+{
+	return header->signal;
+}
+
+#define ZD_CCK_SIGNAL_1M	0x0a
+#define ZD_CCK_SIGNAL_2M	0x14
+#define ZD_CCK_SIGNAL_5M5	0x37
+#define ZD_CCK_SIGNAL_11M	0x6e
+
+enum ieee80211_std {
+	IEEE80211B = 0x01,
+	IEEE80211A = 0x02,
+	IEEE80211G = 0x04,
+};
+
+#endif /* _ZD_IEEE80211_H */
diff --git a/drivers/net/wireless/zd1211rw/zd_mac.c b/drivers/net/wireless/zd1211rw/zd_mac.c
new file mode 100644
index 000000000..a9bd80a08
--- /dev/null
+++ b/drivers/net/wireless/zd1211rw/zd_mac.c
@@ -0,0 +1,1084 @@
+/* zd_mac.c
+ *
+ * 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/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/wireless.h>
+#include <linux/usb.h>
+#include <linux/jiffies.h>
+#include <net/ieee80211_radiotap.h>
+
+#include "zd_def.h"
+#include "zd_chip.h"
+#include "zd_mac.h"
+#include "zd_ieee80211.h"
+#include "zd_netdev.h"
+#include "zd_rf.h"
+#include "zd_util.h"
+
+static void ieee_init(struct ieee80211_device *ieee);
+static void softmac_init(struct ieee80211softmac_device *sm);
+
+int zd_mac_init(struct zd_mac *mac,
+	        struct net_device *netdev,
+	        struct usb_interface *intf)
+{
+	struct ieee80211_device *ieee = zd_netdev_ieee80211(netdev);
+
+	memset(mac, 0, sizeof(*mac));
+	spin_lock_init(&mac->lock);
+	mac->netdev = netdev;
+
+	ieee_init(ieee);
+	softmac_init(ieee80211_priv(netdev));
+	zd_chip_init(&mac->chip, netdev, intf);
+	return 0;
+}
+
+static int reset_channel(struct zd_mac *mac)
+{
+	int r;
+	unsigned long flags;
+	const struct channel_range *range;
+
+	spin_lock_irqsave(&mac->lock, flags);
+	range = zd_channel_range(mac->regdomain);
+	if (!range->start) {
+		r = -EINVAL;
+		goto out;
+	}
+	mac->requested_channel = range->start;
+	r = 0;
+out:
+	spin_unlock_irqrestore(&mac->lock, flags);
+	return r;
+}
+
+int zd_mac_init_hw(struct zd_mac *mac, u8 device_type)
+{
+	int r;
+	struct zd_chip *chip = &mac->chip;
+	u8 addr[ETH_ALEN];
+	u8 default_regdomain;
+
+	r = zd_chip_enable_int(chip);
+	if (r)
+		goto out;
+	r = zd_chip_init_hw(chip, device_type);
+	if (r)
+		goto disable_int;
+
+	zd_get_e2p_mac_addr(chip, addr);
+	r = zd_write_mac_addr(chip, addr);
+	if (r)
+		goto disable_int;
+	ZD_ASSERT(!irqs_disabled());
+	spin_lock_irq(&mac->lock);
+	memcpy(mac->netdev->dev_addr, addr, ETH_ALEN);
+	spin_unlock_irq(&mac->lock);
+
+	r = zd_read_regdomain(chip, &default_regdomain);
+	if (r)
+		goto disable_int;
+	if (!zd_regdomain_supported(default_regdomain)) {
+		dev_dbg_f(zd_mac_dev(mac),
+			  "Regulatory Domain %#04x is not supported.\n",
+		          default_regdomain);
+		r = -EINVAL;
+		goto disable_int;
+	}
+	spin_lock_irq(&mac->lock);
+	mac->regdomain = mac->default_regdomain = default_regdomain;
+	spin_unlock_irq(&mac->lock);
+	r = reset_channel(mac);
+	if (r)
+		goto disable_int;
+
+	/* We must inform the device that we are doing encryption/decryption in
+	 * software at the moment. */
+	r = zd_set_encryption_type(chip, ENC_SNIFFER);
+	if (r)
+		goto disable_int;
+
+	r = zd_geo_init(zd_mac_to_ieee80211(mac), mac->regdomain);
+	if (r)
+		goto disable_int;
+
+	r = 0;
+disable_int:
+	zd_chip_disable_int(chip);
+out:
+	return r;
+}
+
+void zd_mac_clear(struct zd_mac *mac)
+{
+	/* Aquire the lock. */
+	spin_lock(&mac->lock);
+	spin_unlock(&mac->lock);
+	zd_chip_clear(&mac->chip);
+	memset(mac, 0, sizeof(*mac));
+}
+
+static int reset_mode(struct zd_mac *mac)
+{
+	struct ieee80211_device *ieee = zd_mac_to_ieee80211(mac);
+	struct zd_ioreq32 ioreqs[3] = {
+		{ CR_RX_FILTER, STA_RX_FILTER },
+		{ CR_SNIFFER_ON, 0U },
+	};
+
+	if (ieee->iw_mode == IW_MODE_MONITOR) {
+		ioreqs[0].value = 0xffffffff;
+		ioreqs[1].value = 0x1;
+		ioreqs[2].value = ENC_SNIFFER;
+	}
+
+	return zd_iowrite32a(&mac->chip, ioreqs, 3);
+}
+
+int zd_mac_open(struct net_device *netdev)
+{
+	struct zd_mac *mac = zd_netdev_mac(netdev);
+	struct zd_chip *chip = &mac->chip;
+	int r;
+
+	r = zd_chip_enable_int(chip);
+	if (r < 0)
+		goto out;
+
+	r = zd_chip_set_basic_rates(chip, CR_RATES_80211B | CR_RATES_80211G);
+	if (r < 0)
+		goto disable_int;
+	r = reset_mode(mac);
+	if (r)
+		goto disable_int;
+	r = zd_chip_switch_radio_on(chip);
+	if (r < 0)
+		goto disable_int;
+	r = zd_chip_set_channel(chip, mac->requested_channel);
+	if (r < 0)
+		goto disable_radio;
+	r = zd_chip_enable_rx(chip);
+	if (r < 0)
+		goto disable_radio;
+	r = zd_chip_enable_hwint(chip);
+	if (r < 0)
+		goto disable_rx;
+
+	ieee80211softmac_start(netdev);
+	return 0;
+disable_rx:
+	zd_chip_disable_rx(chip);
+disable_radio:
+	zd_chip_switch_radio_off(chip);
+disable_int:
+	zd_chip_disable_int(chip);
+out:
+	return r;
+}
+
+int zd_mac_stop(struct net_device *netdev)
+{
+	struct zd_mac *mac = zd_netdev_mac(netdev);
+	struct zd_chip *chip = &mac->chip;
+
+	netif_stop_queue(netdev);
+
+	/*
+	 * The order here deliberately is a little different from the open()
+	 * method, since we need to make sure there is no opportunity for RX
+	 * frames to be processed by softmac after we have stopped it.
+	 */
+
+	zd_chip_disable_rx(chip);
+	ieee80211softmac_stop(netdev);
+
+	zd_chip_disable_hwint(chip);
+	zd_chip_switch_radio_off(chip);
+	zd_chip_disable_int(chip);
+
+	return 0;
+}
+
+int zd_mac_set_mac_address(struct net_device *netdev, void *p)
+{
+	int r;
+	unsigned long flags;
+	struct sockaddr *addr = p;
+	struct zd_mac *mac = zd_netdev_mac(netdev);
+	struct zd_chip *chip = &mac->chip;
+
+	if (!is_valid_ether_addr(addr->sa_data))
+		return -EADDRNOTAVAIL;
+
+	dev_dbg_f(zd_mac_dev(mac),
+		  "Setting MAC to " MAC_FMT "\n", MAC_ARG(addr->sa_data));
+
+	r = zd_write_mac_addr(chip, addr->sa_data);
+	if (r)
+		return r;
+
+	spin_lock_irqsave(&mac->lock, flags);
+	memcpy(netdev->dev_addr, addr->sa_data, ETH_ALEN);
+	spin_unlock_irqrestore(&mac->lock, flags);
+
+	return 0;
+}
+
+int zd_mac_set_regdomain(struct zd_mac *mac, u8 regdomain)
+{
+	int r;
+	u8 channel;
+
+	ZD_ASSERT(!irqs_disabled());
+	spin_lock_irq(&mac->lock);
+	if (regdomain == 0) {
+		regdomain = mac->default_regdomain;
+	}
+	if (!zd_regdomain_supported(regdomain)) {
+		spin_unlock_irq(&mac->lock);
+		return -EINVAL;
+	}
+	mac->regdomain = regdomain;
+	channel = mac->requested_channel;
+	spin_unlock_irq(&mac->lock);
+
+	r = zd_geo_init(zd_mac_to_ieee80211(mac), regdomain);
+	if (r)
+		return r;
+	if (!zd_regdomain_supports_channel(regdomain, channel)) {
+		r = reset_channel(mac);
+		if (r)
+			return r;
+	}
+
+	return 0;
+}
+
+u8 zd_mac_get_regdomain(struct zd_mac *mac)
+{
+	unsigned long flags;
+	u8 regdomain;
+
+	spin_lock_irqsave(&mac->lock, flags);
+	regdomain = mac->regdomain;
+	spin_unlock_irqrestore(&mac->lock, flags);
+	return regdomain;
+}
+
+static void set_channel(struct net_device *netdev, u8 channel)
+{
+	struct zd_mac *mac = zd_netdev_mac(netdev);
+
+	dev_dbg_f(zd_mac_dev(mac), "channel %d\n", channel);
+
+	zd_chip_set_channel(&mac->chip, channel);
+}
+
+/* TODO: Should not work in Managed mode. */
+int zd_mac_request_channel(struct zd_mac *mac, u8 channel)
+{
+	unsigned long lock_flags;
+	struct ieee80211_device *ieee = zd_mac_to_ieee80211(mac);
+
+	if (ieee->iw_mode == IW_MODE_INFRA)
+		return -EPERM;
+
+	spin_lock_irqsave(&mac->lock, lock_flags);
+	if (!zd_regdomain_supports_channel(mac->regdomain, channel)) {
+		spin_unlock_irqrestore(&mac->lock, lock_flags);
+		return -EINVAL;
+	}
+	mac->requested_channel = channel;
+	spin_unlock_irqrestore(&mac->lock, lock_flags);
+	if (netif_running(mac->netdev))
+		return zd_chip_set_channel(&mac->chip, channel);
+	else
+		return 0;
+}
+
+int zd_mac_get_channel(struct zd_mac *mac, u8 *channel, u8 *flags)
+{
+	struct ieee80211_device *ieee = zd_mac_to_ieee80211(mac);
+
+	*channel = zd_chip_get_channel(&mac->chip);
+	if (ieee->iw_mode != IW_MODE_INFRA) {
+		spin_lock_irq(&mac->lock);
+		*flags = *channel == mac->requested_channel ?
+			MAC_FIXED_CHANNEL : 0;
+		spin_unlock(&mac->lock);
+	} else {
+		*flags = 0;
+	}
+	dev_dbg_f(zd_mac_dev(mac), "channel %u flags %u\n", *channel, *flags);
+	return 0;
+}
+
+/* If wrong rate is given, we are falling back to the slowest rate: 1MBit/s */
+static u8 cs_typed_rate(u8 cs_rate)
+{
+	static const u8 typed_rates[16] = {
+		[ZD_CS_CCK_RATE_1M]	= ZD_CS_CCK|ZD_CS_CCK_RATE_1M,
+		[ZD_CS_CCK_RATE_2M]	= ZD_CS_CCK|ZD_CS_CCK_RATE_2M,
+		[ZD_CS_CCK_RATE_5_5M]	= ZD_CS_CCK|ZD_CS_CCK_RATE_5_5M,
+		[ZD_CS_CCK_RATE_11M]	= ZD_CS_CCK|ZD_CS_CCK_RATE_11M,
+		[ZD_OFDM_RATE_6M]	= ZD_CS_OFDM|ZD_OFDM_RATE_6M,
+		[ZD_OFDM_RATE_9M]	= ZD_CS_OFDM|ZD_OFDM_RATE_9M,
+		[ZD_OFDM_RATE_12M]	= ZD_CS_OFDM|ZD_OFDM_RATE_12M,
+		[ZD_OFDM_RATE_18M]	= ZD_CS_OFDM|ZD_OFDM_RATE_18M,
+		[ZD_OFDM_RATE_24M]	= ZD_CS_OFDM|ZD_OFDM_RATE_24M,
+		[ZD_OFDM_RATE_36M]	= ZD_CS_OFDM|ZD_OFDM_RATE_36M,
+		[ZD_OFDM_RATE_48M]	= ZD_CS_OFDM|ZD_OFDM_RATE_48M,
+		[ZD_OFDM_RATE_54M]	= ZD_CS_OFDM|ZD_OFDM_RATE_54M,
+	};
+
+	ZD_ASSERT(ZD_CS_RATE_MASK == 0x0f);
+	return typed_rates[cs_rate & ZD_CS_RATE_MASK];
+}
+
+/* Fallback to lowest rate, if rate is unknown. */
+static u8 rate_to_cs_rate(u8 rate)
+{
+	switch (rate) {
+	case IEEE80211_CCK_RATE_2MB:
+		return ZD_CS_CCK_RATE_2M;
+	case IEEE80211_CCK_RATE_5MB:
+		return ZD_CS_CCK_RATE_5_5M;
+	case IEEE80211_CCK_RATE_11MB:
+		return ZD_CS_CCK_RATE_11M;
+	case IEEE80211_OFDM_RATE_6MB:
+		return ZD_OFDM_RATE_6M;
+	case IEEE80211_OFDM_RATE_9MB:
+		return ZD_OFDM_RATE_9M;
+	case IEEE80211_OFDM_RATE_12MB:
+		return ZD_OFDM_RATE_12M;
+	case IEEE80211_OFDM_RATE_18MB:
+		return ZD_OFDM_RATE_18M;
+	case IEEE80211_OFDM_RATE_24MB:
+		return ZD_OFDM_RATE_24M;
+	case IEEE80211_OFDM_RATE_36MB:
+		return ZD_OFDM_RATE_36M;
+	case IEEE80211_OFDM_RATE_48MB:
+		return ZD_OFDM_RATE_48M;
+	case IEEE80211_OFDM_RATE_54MB:
+		return ZD_OFDM_RATE_54M;
+	}
+	return ZD_CS_CCK_RATE_1M;
+}
+
+int zd_mac_set_mode(struct zd_mac *mac, u32 mode)
+{
+	struct ieee80211_device *ieee;
+
+	switch (mode) {
+	case IW_MODE_AUTO:
+	case IW_MODE_ADHOC:
+	case IW_MODE_INFRA:
+		mac->netdev->type = ARPHRD_ETHER;
+		break;
+	case IW_MODE_MONITOR:
+		mac->netdev->type = ARPHRD_IEEE80211_RADIOTAP;
+		break;
+	default:
+		dev_dbg_f(zd_mac_dev(mac), "wrong mode %u\n", mode);
+		return -EINVAL;
+	}
+
+	ieee = zd_mac_to_ieee80211(mac);
+	ZD_ASSERT(!irqs_disabled());
+	spin_lock_irq(&ieee->lock);
+	ieee->iw_mode = mode;
+	spin_unlock_irq(&ieee->lock);
+
+	if (netif_running(mac->netdev))
+		return reset_mode(mac);
+
+	return 0;
+}
+
+int zd_mac_get_mode(struct zd_mac *mac, u32 *mode)
+{
+	unsigned long flags;
+	struct ieee80211_device *ieee;
+
+	ieee = zd_mac_to_ieee80211(mac);
+	spin_lock_irqsave(&ieee->lock, flags);
+	*mode = ieee->iw_mode;
+	spin_unlock_irqrestore(&ieee->lock, flags);
+	return 0;
+}
+
+int zd_mac_get_range(struct zd_mac *mac, struct iw_range *range)
+{
+	int i;
+	const struct channel_range *channel_range;
+	u8 regdomain;
+
+	memset(range, 0, sizeof(*range));
+
+	/* FIXME: Not so important and depends on the mode. For 802.11g
+	 * usually this value is used. It seems to be that Bit/s number is
+	 * given here.
+	 */
+	range->throughput = 27 * 1000 * 1000;
+
+	range->max_qual.qual = 100;
+	range->max_qual.level = 100;
+
+	/* FIXME: Needs still to be tuned. */
+	range->avg_qual.qual = 71;
+	range->avg_qual.level = 80;
+
+	/* FIXME: depends on standard? */
+	range->min_rts = 256;
+	range->max_rts = 2346;
+
+	range->min_frag = MIN_FRAG_THRESHOLD;
+	range->max_frag = MAX_FRAG_THRESHOLD;
+
+	range->max_encoding_tokens = WEP_KEYS;
+	range->num_encoding_sizes = 2;
+	range->encoding_size[0] = 5;
+	range->encoding_size[1] = WEP_KEY_LEN;
+
+	range->we_version_compiled = WIRELESS_EXT;
+	range->we_version_source = 20;
+
+	ZD_ASSERT(!irqs_disabled());
+	spin_lock_irq(&mac->lock);
+	regdomain = mac->regdomain;
+	spin_unlock_irq(&mac->lock);
+	channel_range = zd_channel_range(regdomain);
+
+	range->num_channels = channel_range->end - channel_range->start;
+	range->old_num_channels = range->num_channels;
+	range->num_frequency = range->num_channels;
+	range->old_num_frequency = range->num_frequency;
+
+	for (i = 0; i < range->num_frequency; i++) {
+		struct iw_freq *freq = &range->freq[i];
+		freq->i = channel_range->start + i;
+		zd_channel_to_freq(freq, freq->i);
+	}
+
+	return 0;
+}
+
+static int zd_calc_tx_length_us(u8 *service, u8 cs_rate, u16 tx_length)
+{
+	static const u8 rate_divisor[] = {
+		[ZD_CS_CCK_RATE_1M]	=  1,
+		[ZD_CS_CCK_RATE_2M]	=  2,
+		[ZD_CS_CCK_RATE_5_5M]	= 11, /* bits must be doubled */
+		[ZD_CS_CCK_RATE_11M]	= 11,
+		[ZD_OFDM_RATE_6M]	=  6,
+		[ZD_OFDM_RATE_9M]	=  9,
+		[ZD_OFDM_RATE_12M]	= 12,
+		[ZD_OFDM_RATE_18M]	= 18,
+		[ZD_OFDM_RATE_24M]	= 24,
+		[ZD_OFDM_RATE_36M]	= 36,
+		[ZD_OFDM_RATE_48M]	= 48,
+		[ZD_OFDM_RATE_54M]	= 54,
+	};
+
+	u32 bits = (u32)tx_length * 8;
+	u32 divisor;
+
+	divisor = rate_divisor[cs_rate];
+	if (divisor == 0)
+		return -EINVAL;
+
+	switch (cs_rate) {
+	case ZD_CS_CCK_RATE_5_5M:
+		bits = (2*bits) + 10; /* round up to the next integer */
+		break;
+	case ZD_CS_CCK_RATE_11M:
+		if (service) {
+			u32 t = bits % 11;
+			*service &= ~ZD_PLCP_SERVICE_LENGTH_EXTENSION;
+			if (0 < t && t <= 3) {
+				*service |= ZD_PLCP_SERVICE_LENGTH_EXTENSION;
+			}
+		}
+		bits += 10; /* round up to the next integer */
+		break;
+	}
+
+	return bits/divisor;
+}
+
+enum {
+	R2M_SHORT_PREAMBLE = 0x01,
+	R2M_11A		   = 0x02,
+};
+
+static u8 cs_rate_to_modulation(u8 cs_rate, int flags)
+{
+	u8 modulation;
+
+	modulation = cs_typed_rate(cs_rate);
+	if (flags & R2M_SHORT_PREAMBLE) {
+		switch (ZD_CS_RATE(modulation)) {
+		case ZD_CS_CCK_RATE_2M:
+		case ZD_CS_CCK_RATE_5_5M:
+		case ZD_CS_CCK_RATE_11M:
+			modulation |= ZD_CS_CCK_PREA_SHORT;
+			return modulation;
+		}
+	}
+	if (flags & R2M_11A) {
+		if (ZD_CS_TYPE(modulation) == ZD_CS_OFDM)
+			modulation |= ZD_CS_OFDM_MODE_11A;
+	}
+	return modulation;
+}
+
+static void cs_set_modulation(struct zd_mac *mac, struct zd_ctrlset *cs,
+	                      struct ieee80211_hdr_4addr *hdr)
+{
+	struct ieee80211softmac_device *softmac = ieee80211_priv(mac->netdev);
+	u16 ftype = WLAN_FC_GET_TYPE(le16_to_cpu(hdr->frame_ctl));
+	u8 rate, cs_rate;
+	int is_mgt = (ftype == IEEE80211_FTYPE_MGMT) != 0;
+
+	/* FIXME: 802.11a? short preamble? */
+	rate = ieee80211softmac_suggest_txrate(softmac,
+		is_multicast_ether_addr(hdr->addr1), is_mgt);
+
+	cs_rate = rate_to_cs_rate(rate);
+	cs->modulation = cs_rate_to_modulation(cs_rate, 0);
+}
+
+static void cs_set_control(struct zd_mac *mac, struct zd_ctrlset *cs,
+	                   struct ieee80211_hdr_4addr *header)
+{
+	unsigned int tx_length = le16_to_cpu(cs->tx_length);
+	u16 fctl = le16_to_cpu(header->frame_ctl);
+	u16 ftype = WLAN_FC_GET_TYPE(fctl);
+	u16 stype = WLAN_FC_GET_STYPE(fctl);
+
+	/*
+	 * CONTROL:
+	 * - start at 0x00
+	 * - if fragment 0, enable bit 0
+	 * - if backoff needed, enable bit 0
+	 * - if burst (backoff not needed) disable bit 0
+	 * - if multicast, enable bit 1
+	 * - if PS-POLL frame, enable bit 2
+	 * - if in INDEPENDENT_BSS mode and zd1205_DestPowerSave, then enable
+	 *   bit 4 (FIXME: wtf)
+	 * - if frag_len > RTS threshold, set bit 5 as long if it isnt
+	 *   multicast or mgt
+	 * - if bit 5 is set, and we are in OFDM mode, unset bit 5 and set bit
+	 *   7
+	 */
+
+	cs->control = 0;
+
+	/* First fragment */
+	if (WLAN_GET_SEQ_FRAG(le16_to_cpu(header->seq_ctl)) == 0)
+		cs->control |= ZD_CS_NEED_RANDOM_BACKOFF;
+
+	/* Multicast */
+	if (is_multicast_ether_addr(header->addr1))
+		cs->control |= ZD_CS_MULTICAST;
+
+	/* PS-POLL */
+	if (stype == IEEE80211_STYPE_PSPOLL)
+		cs->control |= ZD_CS_PS_POLL_FRAME;
+
+	if (!is_multicast_ether_addr(header->addr1) &&
+	    ftype != IEEE80211_FTYPE_MGMT &&
+	    tx_length > zd_netdev_ieee80211(mac->netdev)->rts)
+	{
+		/* FIXME: check the logic */
+		if (ZD_CS_TYPE(cs->modulation) == ZD_CS_OFDM) {
+			/* 802.11g */
+			cs->control |= ZD_CS_SELF_CTS;
+		} else { /* 802.11b */
+			cs->control |= ZD_CS_RTS;
+		}
+	}
+
+	/* FIXME: Management frame? */
+}
+
+static int fill_ctrlset(struct zd_mac *mac,
+	                struct ieee80211_txb *txb,
+			int frag_num)
+{
+	int r;
+	struct sk_buff *skb = txb->fragments[frag_num];
+	struct ieee80211_hdr_4addr *hdr =
+		(struct ieee80211_hdr_4addr *) skb->data;
+	unsigned int frag_len = skb->len + IEEE80211_FCS_LEN;
+	unsigned int next_frag_len;
+	unsigned int packet_length;
+	struct zd_ctrlset *cs = (struct zd_ctrlset *)
+		skb_push(skb, sizeof(struct zd_ctrlset));
+
+	if (frag_num+1  < txb->nr_frags) {
+		next_frag_len = txb->fragments[frag_num+1]->len +
+			        IEEE80211_FCS_LEN;
+	} else {
+		next_frag_len = 0;
+	}
+	ZD_ASSERT(frag_len <= 0xffff);
+	ZD_ASSERT(next_frag_len <= 0xffff);
+
+	cs_set_modulation(mac, cs, hdr);
+
+	cs->tx_length = cpu_to_le16(frag_len);
+
+	cs_set_control(mac, cs, hdr);
+
+	packet_length = frag_len + sizeof(struct zd_ctrlset) + 10;
+	ZD_ASSERT(packet_length <= 0xffff);
+	/* ZD1211B: Computing the length difference this way, gives us
+	 * flexibility to compute the packet length.
+	 */
+	cs->packet_length = cpu_to_le16(mac->chip.is_zd1211b ?
+			packet_length - frag_len : packet_length);
+
+	/*
+	 * CURRENT LENGTH:
+	 * - transmit frame length in microseconds
+	 * - seems to be derived from frame length
+	 * - see Cal_Us_Service() in zdinlinef.h
+	 * - if macp->bTxBurstEnable is enabled, then multiply by 4
+	 *  - bTxBurstEnable is never set in the vendor driver
+	 *
+	 * SERVICE:
+	 * - "for PLCP configuration"
+	 * - always 0 except in some situations at 802.11b 11M
+	 * - see line 53 of zdinlinef.h
+	 */
+	cs->service = 0;
+	r = zd_calc_tx_length_us(&cs->service, ZD_CS_RATE(cs->modulation),
+		                 le16_to_cpu(cs->tx_length));
+	if (r < 0)
+		return r;
+	cs->current_length = cpu_to_le16(r);
+
+	if (next_frag_len == 0) {
+		cs->next_frame_length = 0;
+	} else {
+		r = zd_calc_tx_length_us(NULL, ZD_CS_RATE(cs->modulation),
+			                 next_frag_len);
+		if (r < 0)
+			return r;
+		cs->next_frame_length = cpu_to_le16(r);
+	}
+
+	return 0;
+}
+
+static int zd_mac_tx(struct zd_mac *mac, struct ieee80211_txb *txb, int pri)
+{
+	int i, r;
+
+	for (i = 0; i < txb->nr_frags; i++) {
+		struct sk_buff *skb = txb->fragments[i];
+
+		r = fill_ctrlset(mac, txb, i);
+		if (r)
+			return r;
+		r = zd_usb_tx(&mac->chip.usb, skb->data, skb->len);
+		if (r)
+			return r;
+	}
+
+	/* FIXME: shouldn't this be handled by the upper layers? */
+	mac->netdev->trans_start = jiffies;
+
+	ieee80211_txb_free(txb);
+	return 0;
+}
+
+struct zd_rt_hdr {
+	struct ieee80211_radiotap_header rt_hdr;
+	u8  rt_flags;
+	u8  rt_rate;
+	u16 rt_channel;
+	u16 rt_chbitmask;
+} __attribute__((packed));
+
+static void fill_rt_header(void *buffer, struct zd_mac *mac,
+	                   const struct ieee80211_rx_stats *stats,
+			   const struct rx_status *status)
+{
+	struct zd_rt_hdr *hdr = buffer;
+
+	hdr->rt_hdr.it_version = PKTHDR_RADIOTAP_VERSION;
+	hdr->rt_hdr.it_pad = 0;
+	hdr->rt_hdr.it_len = cpu_to_le16(sizeof(struct zd_rt_hdr));
+	hdr->rt_hdr.it_present = cpu_to_le32((1 << IEEE80211_RADIOTAP_FLAGS) |
+		                 (1 << IEEE80211_RADIOTAP_CHANNEL) |
+				 (1 << IEEE80211_RADIOTAP_RATE));
+
+	hdr->rt_flags = 0;
+	if (status->decryption_type & (ZD_RX_WEP64|ZD_RX_WEP128|ZD_RX_WEP256))
+		hdr->rt_flags |= IEEE80211_RADIOTAP_F_WEP;
+
+	hdr->rt_rate = stats->rate / 5;
+
+	/* FIXME: 802.11a */
+	hdr->rt_channel = cpu_to_le16(ieee80211chan2mhz(
+		                             _zd_chip_get_channel(&mac->chip)));
+	hdr->rt_chbitmask = cpu_to_le16(IEEE80211_CHAN_2GHZ |
+		((status->frame_status & ZD_RX_FRAME_MODULATION_MASK) ==
+		ZD_RX_OFDM ? IEEE80211_CHAN_OFDM : IEEE80211_CHAN_CCK));
+}
+
+/* Returns 1 if the data packet is for us and 0 otherwise. */
+static int is_data_packet_for_us(struct ieee80211_device *ieee,
+	                         struct ieee80211_hdr_4addr *hdr)
+{
+	struct net_device *netdev = ieee->dev;
+	u16 fc = le16_to_cpu(hdr->frame_ctl);
+
+	ZD_ASSERT(WLAN_FC_GET_TYPE(fc) == IEEE80211_FTYPE_DATA);
+
+	switch (ieee->iw_mode) {
+	case IW_MODE_ADHOC:
+		if ((fc & (IEEE80211_FCTL_TODS|IEEE80211_FCTL_FROMDS)) != 0 ||
+		    memcmp(hdr->addr3, ieee->bssid, ETH_ALEN) != 0)
+			return 0;
+		break;
+	case IW_MODE_AUTO:
+	case IW_MODE_INFRA:
+		if ((fc & (IEEE80211_FCTL_TODS|IEEE80211_FCTL_FROMDS)) !=
+		    IEEE80211_FCTL_FROMDS ||
+		    memcmp(hdr->addr2, ieee->bssid, ETH_ALEN) != 0)
+			return 0;
+		break;
+	default:
+		ZD_ASSERT(ieee->iw_mode != IW_MODE_MONITOR);
+		return 0;
+	}
+
+	return memcmp(hdr->addr1, netdev->dev_addr, ETH_ALEN) == 0 ||
+	       is_multicast_ether_addr(hdr->addr1) ||
+	       (netdev->flags & IFF_PROMISC);
+}
+
+/* Filters receiving packets. If it returns 1 send it to ieee80211_rx, if 0
+ * return. If an error is detected -EINVAL is returned. ieee80211_rx_mgt() is
+ * called here.
+ *
+ * It has been based on ieee80211_rx_any.
+ */
+static int filter_rx(struct ieee80211_device *ieee,
+	             const u8 *buffer, unsigned int length,
+		     struct ieee80211_rx_stats *stats)
+{
+	struct ieee80211_hdr_4addr *hdr;
+	u16 fc;
+
+	if (ieee->iw_mode == IW_MODE_MONITOR)
+		return 1;
+
+	hdr = (struct ieee80211_hdr_4addr *)buffer;
+	fc = le16_to_cpu(hdr->frame_ctl);
+	if ((fc & IEEE80211_FCTL_VERS) != 0)
+		return -EINVAL;
+
+	switch (WLAN_FC_GET_TYPE(fc)) {
+	case IEEE80211_FTYPE_MGMT:
+		if (length < sizeof(struct ieee80211_hdr_3addr))
+			return -EINVAL;
+		ieee80211_rx_mgt(ieee, hdr, stats);
+		return 0;
+	case IEEE80211_FTYPE_CTL:
+		/* Ignore invalid short buffers */
+		return 0;
+	case IEEE80211_FTYPE_DATA:
+		if (length < sizeof(struct ieee80211_hdr_3addr))
+			return -EINVAL;
+		return is_data_packet_for_us(ieee, hdr);
+	}
+
+	return -EINVAL;
+}
+
+static void update_qual_rssi(struct zd_mac *mac,
+			     const u8 *buffer, unsigned int length,
+			     u8 qual_percent, u8 rssi_percent)
+{
+	unsigned long flags;
+	struct ieee80211_hdr_3addr *hdr;
+	int i;
+
+	hdr = (struct ieee80211_hdr_3addr *)buffer;
+	if (length < offsetof(struct ieee80211_hdr_3addr, addr3))
+		return;
+	if (memcmp(hdr->addr2, zd_mac_to_ieee80211(mac)->bssid, ETH_ALEN) != 0)
+		return;
+
+	spin_lock_irqsave(&mac->lock, flags);
+	i = mac->stats_count % ZD_MAC_STATS_BUFFER_SIZE;
+	mac->qual_buffer[i] = qual_percent;
+	mac->rssi_buffer[i] = rssi_percent;
+	mac->stats_count++;
+	spin_unlock_irqrestore(&mac->lock, flags);
+}
+
+static int fill_rx_stats(struct ieee80211_rx_stats *stats,
+	                 const struct rx_status **pstatus,
+		         struct zd_mac *mac,
+			 const u8 *buffer, unsigned int length)
+{
+	const struct rx_status *status;
+
+	*pstatus = status = zd_tail(buffer, length, sizeof(struct rx_status));
+	if (status->frame_status & ZD_RX_ERROR) {
+		/* FIXME: update? */
+		return -EINVAL;
+	}
+	memset(stats, 0, sizeof(struct ieee80211_rx_stats));
+	stats->len = length - (ZD_PLCP_HEADER_SIZE + IEEE80211_FCS_LEN +
+		               + sizeof(struct rx_status));
+	/* FIXME: 802.11a */
+	stats->freq = IEEE80211_24GHZ_BAND;
+	stats->received_channel = _zd_chip_get_channel(&mac->chip);
+	stats->rssi = zd_rx_strength_percent(status->signal_strength);
+	stats->signal = zd_rx_qual_percent(buffer,
+		                          length - sizeof(struct rx_status),
+		                          status);
+	stats->mask = IEEE80211_STATMASK_RSSI | IEEE80211_STATMASK_SIGNAL;
+	stats->rate = zd_rx_rate(buffer, status);
+	if (stats->rate)
+		stats->mask |= IEEE80211_STATMASK_RATE;
+
+	return 0;
+}
+
+int zd_mac_rx(struct zd_mac *mac, const u8 *buffer, unsigned int length)
+{
+	int r;
+	struct ieee80211_device *ieee = zd_mac_to_ieee80211(mac);
+	struct ieee80211_rx_stats stats;
+	const struct rx_status *status;
+	struct sk_buff *skb;
+
+	if (length < ZD_PLCP_HEADER_SIZE + IEEE80211_1ADDR_LEN +
+	             IEEE80211_FCS_LEN + sizeof(struct rx_status))
+		return -EINVAL;
+
+	r = fill_rx_stats(&stats, &status, mac, buffer, length);
+	if (r)
+		return r;
+
+	length -= ZD_PLCP_HEADER_SIZE+IEEE80211_FCS_LEN+
+		  sizeof(struct rx_status);
+	buffer += ZD_PLCP_HEADER_SIZE;
+
+	update_qual_rssi(mac, buffer, length, stats.signal, stats.rssi);
+
+	r = filter_rx(ieee, buffer, length, &stats);
+	if (r <= 0)
+		return r;
+
+	skb = dev_alloc_skb(sizeof(struct zd_rt_hdr) + length);
+	if (!skb)
+		return -ENOMEM;
+	if (ieee->iw_mode == IW_MODE_MONITOR)
+		fill_rt_header(skb_put(skb, sizeof(struct zd_rt_hdr)), mac,
+			       &stats, status);
+	memcpy(skb_put(skb, length), buffer, length);
+
+	r = ieee80211_rx(ieee, skb, &stats);
+	if (!r) {
+		ZD_ASSERT(in_irq());
+		dev_kfree_skb_irq(skb);
+	}
+	return 0;
+}
+
+static int netdev_tx(struct ieee80211_txb *txb, struct net_device *netdev,
+		     int pri)
+{
+	return zd_mac_tx(zd_netdev_mac(netdev), txb, pri);
+}
+
+static void set_security(struct net_device *netdev,
+			 struct ieee80211_security *sec)
+{
+	struct ieee80211_device *ieee = zd_netdev_ieee80211(netdev);
+	struct ieee80211_security *secinfo = &ieee->sec;
+	int keyidx;
+
+	dev_dbg_f(zd_mac_dev(zd_netdev_mac(netdev)), "\n");
+
+	for (keyidx = 0; keyidx<WEP_KEYS; keyidx++)
+		if (sec->flags & (1<<keyidx)) {
+			secinfo->encode_alg[keyidx] = sec->encode_alg[keyidx];
+			secinfo->key_sizes[keyidx] = sec->key_sizes[keyidx];
+			memcpy(secinfo->keys[keyidx], sec->keys[keyidx],
+			       SCM_KEY_LEN);
+		}
+
+	if (sec->flags & SEC_ACTIVE_KEY) {
+		secinfo->active_key = sec->active_key;
+		dev_dbg_f(zd_mac_dev(zd_netdev_mac(netdev)),
+			"   .active_key = %d\n", sec->active_key);
+	}
+	if (sec->flags & SEC_UNICAST_GROUP) {
+		secinfo->unicast_uses_group = sec->unicast_uses_group;
+		dev_dbg_f(zd_mac_dev(zd_netdev_mac(netdev)),
+			"   .unicast_uses_group = %d\n",
+			sec->unicast_uses_group);
+	}
+	if (sec->flags & SEC_LEVEL) {
+		secinfo->level = sec->level;
+		dev_dbg_f(zd_mac_dev(zd_netdev_mac(netdev)),
+			"   .level = %d\n", sec->level);
+	}
+	if (sec->flags & SEC_ENABLED) {
+		secinfo->enabled = sec->enabled;
+		dev_dbg_f(zd_mac_dev(zd_netdev_mac(netdev)),
+			"   .enabled = %d\n", sec->enabled);
+	}
+	if (sec->flags & SEC_ENCRYPT) {
+		secinfo->encrypt = sec->encrypt;
+		dev_dbg_f(zd_mac_dev(zd_netdev_mac(netdev)),
+			"   .encrypt = %d\n", sec->encrypt);
+	}
+	if (sec->flags & SEC_AUTH_MODE) {
+		secinfo->auth_mode = sec->auth_mode;
+		dev_dbg_f(zd_mac_dev(zd_netdev_mac(netdev)),
+			"   .auth_mode = %d\n", sec->auth_mode);
+	}
+}
+
+static void ieee_init(struct ieee80211_device *ieee)
+{
+	ieee->mode = IEEE_B | IEEE_G;
+	ieee->freq_band = IEEE80211_24GHZ_BAND;
+	ieee->modulation = IEEE80211_OFDM_MODULATION | IEEE80211_CCK_MODULATION;
+	ieee->tx_headroom = sizeof(struct zd_ctrlset);
+	ieee->set_security = set_security;
+	ieee->hard_start_xmit = netdev_tx;
+
+	/* Software encryption/decryption for now */
+	ieee->host_build_iv = 0;
+	ieee->host_encrypt = 1;
+	ieee->host_decrypt = 1;
+
+	/* FIXME: default to managed mode, until ieee80211 and zd1211rw can
+	 * correctly support AUTO */
+	ieee->iw_mode = IW_MODE_INFRA;
+}
+
+static void softmac_init(struct ieee80211softmac_device *sm)
+{
+	sm->set_channel = set_channel;
+}
+
+struct iw_statistics *zd_mac_get_wireless_stats(struct net_device *ndev)
+{
+	struct zd_mac *mac = zd_netdev_mac(ndev);
+	struct iw_statistics *iw_stats = &mac->iw_stats;
+	unsigned int i, count, qual_total, rssi_total;
+
+	memset(iw_stats, 0, sizeof(struct iw_statistics));
+	/* We are not setting the status, because ieee->state is not updated
+	 * at all and this driver doesn't track authentication state.
+	 */
+	spin_lock_irq(&mac->lock);
+	count = mac->stats_count < ZD_MAC_STATS_BUFFER_SIZE ?
+		mac->stats_count : ZD_MAC_STATS_BUFFER_SIZE;
+	qual_total = rssi_total = 0;
+	for (i = 0; i < count; i++) {
+		qual_total += mac->qual_buffer[i];
+		rssi_total += mac->rssi_buffer[i];
+	}
+	spin_unlock_irq(&mac->lock);
+	iw_stats->qual.updated = IW_QUAL_NOISE_INVALID;
+	if (count > 0) {
+		iw_stats->qual.qual = qual_total / count;
+		iw_stats->qual.level = rssi_total / count;
+		iw_stats->qual.updated |=
+			IW_QUAL_QUAL_UPDATED|IW_QUAL_LEVEL_UPDATED;
+	} else {
+		iw_stats->qual.updated |=
+			IW_QUAL_QUAL_INVALID|IW_QUAL_LEVEL_INVALID;
+	}
+	/* TODO: update counter */
+	return iw_stats;
+}
+
+#ifdef DEBUG
+static const char* decryption_types[] = {
+	[ZD_RX_NO_WEP] = "none",
+	[ZD_RX_WEP64] = "WEP64",
+	[ZD_RX_TKIP] = "TKIP",
+	[ZD_RX_AES] = "AES",
+	[ZD_RX_WEP128] = "WEP128",
+	[ZD_RX_WEP256] = "WEP256",
+};
+
+static const char *decryption_type_string(u8 type)
+{
+	const char *s;
+
+	if (type < ARRAY_SIZE(decryption_types)) {
+		s = decryption_types[type];
+	} else {
+		s = NULL;
+	}
+	return s ? s : "unknown";
+}
+
+static int is_ofdm(u8 frame_status)
+{
+	return (frame_status & ZD_RX_OFDM);
+}
+
+void zd_dump_rx_status(const struct rx_status *status)
+{
+	const char* modulation;
+	u8 quality;
+
+	if (is_ofdm(status->frame_status)) {
+		modulation = "ofdm";
+		quality = status->signal_quality_ofdm;
+	} else {
+		modulation = "cck";
+		quality = status->signal_quality_cck;
+	}
+	pr_debug("rx status %s strength %#04x qual %#04x decryption %s\n",
+		modulation, status->signal_strength, quality,
+		decryption_type_string(status->decryption_type));
+	if (status->frame_status & ZD_RX_ERROR) {
+		pr_debug("rx error %s%s%s%s%s%s\n",
+			(status->frame_status & ZD_RX_TIMEOUT_ERROR) ?
+				"timeout " : "",
+			(status->frame_status & ZD_RX_FIFO_OVERRUN_ERROR) ?
+				"fifo " : "",
+			(status->frame_status & ZD_RX_DECRYPTION_ERROR) ?
+				"decryption " : "",
+			(status->frame_status & ZD_RX_CRC32_ERROR) ?
+				"crc32 " : "",
+			(status->frame_status & ZD_RX_NO_ADDR1_MATCH_ERROR) ?
+				"addr1 " : "",
+			(status->frame_status & ZD_RX_CRC16_ERROR) ?
+				"crc16" : "");
+	}
+}
+#endif /* DEBUG */
diff --git a/drivers/net/wireless/zd1211rw/zd_mac.h b/drivers/net/wireless/zd1211rw/zd_mac.h
new file mode 100644
index 000000000..b3ba49b84
--- /dev/null
+++ b/drivers/net/wireless/zd1211rw/zd_mac.h
@@ -0,0 +1,193 @@
+/* zd_mac.h
+ *
+ * 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
+ */
+
+#ifndef _ZD_MAC_H
+#define _ZD_MAC_H
+
+#include <linux/wireless.h>
+#include <linux/kernel.h>
+#include <net/ieee80211.h>
+#include <net/ieee80211softmac.h>
+
+#include "zd_chip.h"
+#include "zd_netdev.h"
+
+struct zd_ctrlset {
+	u8     modulation;
+	__le16 tx_length;
+	u8     control;
+	/* stores only the difference to tx_length on ZD1211B */
+	__le16 packet_length;
+	__le16 current_length;
+	u8     service;
+	__le16  next_frame_length;
+} __attribute__((packed));
+
+#define ZD_CS_RESERVED_SIZE	25
+
+/* zd_crtlset field modulation */
+#define ZD_CS_RATE_MASK		0x0f
+#define ZD_CS_TYPE_MASK		0x10
+#define ZD_CS_RATE(modulation) ((modulation) & ZD_CS_RATE_MASK)
+#define ZD_CS_TYPE(modulation) ((modulation) & ZD_CS_TYPE_MASK)
+
+#define ZD_CS_CCK		0x00
+#define ZD_CS_OFDM		0x10
+
+#define ZD_CS_CCK_RATE_1M	0x00
+#define ZD_CS_CCK_RATE_2M	0x01
+#define ZD_CS_CCK_RATE_5_5M	0x02
+#define ZD_CS_CCK_RATE_11M	0x03
+/* The rates for OFDM are encoded as in the PLCP header. Use ZD_OFDM_RATE_*.
+ */
+
+/* bit 5 is preamble (when in CCK mode), or a/g selection (when in OFDM mode) */
+#define ZD_CS_CCK_PREA_LONG	0x00
+#define ZD_CS_CCK_PREA_SHORT	0x20
+#define ZD_CS_OFDM_MODE_11G	0x00
+#define ZD_CS_OFDM_MODE_11A	0x20
+
+/* zd_ctrlset control field */
+#define ZD_CS_NEED_RANDOM_BACKOFF	0x01
+#define ZD_CS_MULTICAST			0x02
+
+#define ZD_CS_FRAME_TYPE_MASK		0x0c
+#define ZD_CS_DATA_FRAME		0x00
+#define ZD_CS_PS_POLL_FRAME		0x04
+#define ZD_CS_MANAGEMENT_FRAME		0x08
+#define ZD_CS_NO_SEQUENCE_CTL_FRAME	0x0c
+
+#define ZD_CS_WAKE_DESTINATION		0x10
+#define ZD_CS_RTS			0x20
+#define ZD_CS_ENCRYPT			0x40
+#define ZD_CS_SELF_CTS			0x80
+
+/* Incoming frames are prepended by a PLCP header */
+#define ZD_PLCP_HEADER_SIZE		5
+
+struct rx_length_info {
+	__le16 length[3];
+	__le16 tag;
+} __attribute__((packed));
+
+#define RX_LENGTH_INFO_TAG		0x697e
+
+struct rx_status {
+	u8 signal_quality_cck;
+	/* rssi */
+	u8 signal_strength;
+	u8 signal_quality_ofdm;
+	u8 decryption_type;
+	u8 frame_status;
+} __attribute__((packed));
+
+/* rx_status field decryption_type */
+#define ZD_RX_NO_WEP	0
+#define ZD_RX_WEP64	1
+#define ZD_RX_TKIP	2
+#define ZD_RX_AES	4
+#define ZD_RX_WEP128	5
+#define ZD_RX_WEP256	6
+
+/* rx_status field frame_status */
+#define ZD_RX_FRAME_MODULATION_MASK	0x01
+#define ZD_RX_CCK			0x00
+#define ZD_RX_OFDM			0x01
+
+#define ZD_RX_TIMEOUT_ERROR		0x02
+#define ZD_RX_FIFO_OVERRUN_ERROR	0x04
+#define ZD_RX_DECRYPTION_ERROR		0x08
+#define ZD_RX_CRC32_ERROR		0x10
+#define ZD_RX_NO_ADDR1_MATCH_ERROR	0x20
+#define ZD_RX_CRC16_ERROR		0x40
+#define ZD_RX_ERROR			0x80
+
+enum mac_flags {
+	MAC_FIXED_CHANNEL = 0x01,
+};
+
+#define ZD_MAC_STATS_BUFFER_SIZE 16
+
+struct zd_mac {
+	struct net_device *netdev;
+	struct zd_chip chip;
+	spinlock_t lock;
+	/* Unlocked reading possible */
+	struct iw_statistics iw_stats;
+	unsigned int stats_count;
+	u8 qual_buffer[ZD_MAC_STATS_BUFFER_SIZE];
+	u8 rssi_buffer[ZD_MAC_STATS_BUFFER_SIZE];
+	u8 regdomain;
+	u8 default_regdomain;
+	u8 requested_channel;
+};
+
+static inline struct ieee80211_device *zd_mac_to_ieee80211(struct zd_mac *mac)
+{
+	return zd_netdev_ieee80211(mac->netdev);
+}
+
+static inline struct zd_mac *zd_netdev_mac(struct net_device *netdev)
+{
+	return ieee80211softmac_priv(netdev);
+}
+
+static inline struct zd_mac *zd_chip_to_mac(struct zd_chip *chip)
+{
+	return container_of(chip, struct zd_mac, chip);
+}
+
+static inline struct zd_mac *zd_usb_to_mac(struct zd_usb *usb)
+{
+	return zd_chip_to_mac(zd_usb_to_chip(usb));
+}
+
+#define zd_mac_dev(mac) (zd_chip_dev(&(mac)->chip))
+
+int zd_mac_init(struct zd_mac *mac,
+                struct net_device *netdev,
+		struct usb_interface *intf);
+void zd_mac_clear(struct zd_mac *mac);
+
+int zd_mac_init_hw(struct zd_mac *mac, u8 device_type);
+
+int zd_mac_open(struct net_device *netdev);
+int zd_mac_stop(struct net_device *netdev);
+int zd_mac_set_mac_address(struct net_device *dev, void *p);
+
+int zd_mac_rx(struct zd_mac *mac, const u8 *buffer, unsigned int length);
+
+int zd_mac_set_regdomain(struct zd_mac *zd_mac, u8 regdomain);
+u8 zd_mac_get_regdomain(struct zd_mac *zd_mac);
+
+int zd_mac_request_channel(struct zd_mac *mac, u8 channel);
+int zd_mac_get_channel(struct zd_mac *mac, u8 *channel, u8 *flags);
+
+int zd_mac_set_mode(struct zd_mac *mac, u32 mode);
+int zd_mac_get_mode(struct zd_mac *mac, u32 *mode);
+
+int zd_mac_get_range(struct zd_mac *mac, struct iw_range *range);
+
+struct iw_statistics *zd_mac_get_wireless_stats(struct net_device *ndev);
+
+#ifdef DEBUG
+void zd_dump_rx_status(const struct rx_status *status);
+#else
+#define zd_dump_rx_status(status)
+#endif /* DEBUG */
+
+#endif /* _ZD_MAC_H */
diff --git a/drivers/net/wireless/zd1211rw/zd_netdev.c b/drivers/net/wireless/zd1211rw/zd_netdev.c
new file mode 100644
index 000000000..9df232c2c
--- /dev/null
+++ b/drivers/net/wireless/zd1211rw/zd_netdev.c
@@ -0,0 +1,267 @@
+/* zd_netdev.c
+ *
+ * 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/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/skbuff.h>
+#include <net/ieee80211.h>
+#include <net/ieee80211softmac.h>
+#include <net/ieee80211softmac_wx.h>
+#include <net/iw_handler.h>
+
+#include "zd_def.h"
+#include "zd_netdev.h"
+#include "zd_mac.h"
+#include "zd_ieee80211.h"
+
+/* Region 0 means reset regdomain to default. */
+static int zd_set_regdomain(struct net_device *netdev,
+	                    struct iw_request_info *info,
+			    union iwreq_data *req, char *extra)
+{
+	const u8 *regdomain = (u8 *)req;
+	return zd_mac_set_regdomain(zd_netdev_mac(netdev), *regdomain);
+}
+
+static int zd_get_regdomain(struct net_device *netdev,
+	                    struct iw_request_info *info,
+			    union iwreq_data *req, char *extra)
+{
+	u8 *regdomain = (u8 *)req;
+	if (!regdomain)
+		return -EINVAL;
+	*regdomain = zd_mac_get_regdomain(zd_netdev_mac(netdev));
+	return 0;
+}
+
+static const struct iw_priv_args zd_priv_args[] = {
+	{
+		.cmd = ZD_PRIV_SET_REGDOMAIN,
+		.set_args = IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1,
+		.name = "set_regdomain",
+	},
+	{
+		.cmd = ZD_PRIV_GET_REGDOMAIN,
+		.get_args = IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1,
+		.name = "get_regdomain",
+	},
+};
+
+#define PRIV_OFFSET(x) [(x)-SIOCIWFIRSTPRIV]
+
+static const iw_handler zd_priv_handler[] = {
+	PRIV_OFFSET(ZD_PRIV_SET_REGDOMAIN) = zd_set_regdomain,
+	PRIV_OFFSET(ZD_PRIV_GET_REGDOMAIN) = zd_get_regdomain,
+};
+
+static int iw_get_name(struct net_device *netdev,
+	               struct iw_request_info *info,
+		       union iwreq_data *req, char *extra)
+{
+	/* FIXME: check whether 802.11a will also supported, add also
+	 *        zd1211B, if we support it.
+	 */
+	strlcpy(req->name, "802.11g zd1211", IFNAMSIZ);
+	return 0;
+}
+
+static int iw_set_freq(struct net_device *netdev,
+	               struct iw_request_info *info,
+		       union iwreq_data *req, char *extra)
+{
+	int r;
+	struct zd_mac *mac = zd_netdev_mac(netdev);
+	struct iw_freq *freq = &req->freq;
+	u8 channel;
+
+	r = zd_find_channel(&channel, freq);
+	if (r < 0)
+		return r;
+	r = zd_mac_request_channel(mac, channel);
+	return r;
+}
+
+static int iw_get_freq(struct net_device *netdev,
+	           struct iw_request_info *info,
+		   union iwreq_data *req, char *extra)
+{
+	int r;
+	struct zd_mac *mac = zd_netdev_mac(netdev);
+	struct iw_freq *freq = &req->freq;
+	u8 channel;
+	u8 flags;
+
+	r = zd_mac_get_channel(mac, &channel, &flags);
+	if (r)
+		return r;
+
+	freq->flags = (flags & MAC_FIXED_CHANNEL) ?
+		      IW_FREQ_FIXED : IW_FREQ_AUTO;
+	dev_dbg_f(zd_mac_dev(mac), "channel %s\n",
+		  (flags & MAC_FIXED_CHANNEL) ? "fixed" : "auto");
+	return zd_channel_to_freq(freq, channel);
+}
+
+static int iw_set_mode(struct net_device *netdev,
+	               struct iw_request_info *info,
+		       union iwreq_data *req, char *extra)
+{
+	return zd_mac_set_mode(zd_netdev_mac(netdev), req->mode);
+}
+
+static int iw_get_mode(struct net_device *netdev,
+	               struct iw_request_info *info,
+		       union iwreq_data *req, char *extra)
+{
+	return zd_mac_get_mode(zd_netdev_mac(netdev), &req->mode);
+}
+
+static int iw_get_range(struct net_device *netdev,
+	               struct iw_request_info *info,
+		       union iwreq_data *req, char *extra)
+{
+	struct iw_range *range = (struct iw_range *)extra;
+
+	dev_dbg_f(zd_mac_dev(zd_netdev_mac(netdev)), "\n");
+	req->data.length = sizeof(*range);
+	return zd_mac_get_range(zd_netdev_mac(netdev), range);
+}
+
+static int iw_set_encode(struct net_device *netdev,
+			 struct iw_request_info *info,
+			 union iwreq_data *data,
+			 char *extra)
+{
+	return ieee80211_wx_set_encode(zd_netdev_ieee80211(netdev), info,
+		data, extra);
+}
+
+static int iw_get_encode(struct net_device *netdev,
+			 struct iw_request_info *info,
+			 union iwreq_data *data,
+			 char *extra)
+{
+	return ieee80211_wx_get_encode(zd_netdev_ieee80211(netdev), info,
+		data, extra);
+}
+
+static int iw_set_encodeext(struct net_device *netdev,
+			 struct iw_request_info *info,
+			 union iwreq_data *data,
+			 char *extra)
+{
+	return ieee80211_wx_set_encodeext(zd_netdev_ieee80211(netdev), info,
+		data, extra);
+}
+
+static int iw_get_encodeext(struct net_device *netdev,
+			 struct iw_request_info *info,
+			 union iwreq_data *data,
+			 char *extra)
+{
+	return ieee80211_wx_get_encodeext(zd_netdev_ieee80211(netdev), info,
+		data, extra);
+}
+
+#define WX(x) [(x)-SIOCIWFIRST]
+
+static const iw_handler zd_standard_iw_handlers[] = {
+	WX(SIOCGIWNAME)		= iw_get_name,
+	WX(SIOCSIWFREQ)		= iw_set_freq,
+	WX(SIOCGIWFREQ)		= iw_get_freq,
+	WX(SIOCSIWMODE)		= iw_set_mode,
+	WX(SIOCGIWMODE)		= iw_get_mode,
+	WX(SIOCGIWRANGE)	= iw_get_range,
+	WX(SIOCSIWENCODE)	= iw_set_encode,
+	WX(SIOCGIWENCODE)	= iw_get_encode,
+	WX(SIOCSIWENCODEEXT)	= iw_set_encodeext,
+	WX(SIOCGIWENCODEEXT)	= iw_get_encodeext,
+	WX(SIOCSIWAUTH)		= ieee80211_wx_set_auth,
+	WX(SIOCGIWAUTH)		= ieee80211_wx_get_auth,
+	WX(SIOCSIWSCAN)		= ieee80211softmac_wx_trigger_scan,
+	WX(SIOCGIWSCAN)		= ieee80211softmac_wx_get_scan_results,
+	WX(SIOCSIWESSID)	= ieee80211softmac_wx_set_essid,
+	WX(SIOCGIWESSID)	= ieee80211softmac_wx_get_essid,
+	WX(SIOCSIWAP)		= ieee80211softmac_wx_set_wap,
+	WX(SIOCGIWAP)		= ieee80211softmac_wx_get_wap,
+	WX(SIOCSIWRATE)		= ieee80211softmac_wx_set_rate,
+	WX(SIOCGIWRATE)		= ieee80211softmac_wx_get_rate,
+	WX(SIOCSIWGENIE)	= ieee80211softmac_wx_set_genie,
+	WX(SIOCGIWGENIE)	= ieee80211softmac_wx_get_genie,
+	WX(SIOCSIWMLME)		= ieee80211softmac_wx_set_mlme,
+};
+
+static const struct iw_handler_def iw_handler_def = {
+	.standard		= zd_standard_iw_handlers,
+	.num_standard		= ARRAY_SIZE(zd_standard_iw_handlers),
+	.private		= zd_priv_handler,
+	.num_private		= ARRAY_SIZE(zd_priv_handler),
+	.private_args		= zd_priv_args,
+	.num_private_args	= ARRAY_SIZE(zd_priv_args),
+	.get_wireless_stats	= zd_mac_get_wireless_stats,
+};
+
+struct net_device *zd_netdev_alloc(struct usb_interface *intf)
+{
+	int r;
+	struct net_device *netdev;
+	struct zd_mac *mac;
+
+	netdev = alloc_ieee80211softmac(sizeof(struct zd_mac));
+	if (!netdev) {
+		dev_dbg_f(&intf->dev, "out of memory\n");
+		return NULL;
+	}
+
+	mac = zd_netdev_mac(netdev);
+	r = zd_mac_init(mac, netdev, intf);
+	if (r) {
+		usb_set_intfdata(intf, NULL);
+		free_ieee80211(netdev);
+		return NULL;
+	}
+
+	SET_MODULE_OWNER(netdev);
+	SET_NETDEV_DEV(netdev, &intf->dev);
+
+	dev_dbg_f(&intf->dev, "netdev->flags %#06hx\n", netdev->flags);
+	dev_dbg_f(&intf->dev, "netdev->features %#010lx\n", netdev->features);
+
+	netdev->open = zd_mac_open;
+	netdev->stop = zd_mac_stop;
+	/* netdev->get_stats = */
+	/* netdev->set_multicast_list = */
+	netdev->set_mac_address = zd_mac_set_mac_address;
+	netdev->wireless_handlers = &iw_handler_def;
+	/* netdev->ethtool_ops = */
+
+	return netdev;
+}
+
+void zd_netdev_free(struct net_device *netdev)
+{
+	if (!netdev)
+		return;
+
+	zd_mac_clear(zd_netdev_mac(netdev));
+	free_ieee80211(netdev);
+}
+
+void zd_netdev_disconnect(struct net_device *netdev)
+{
+	unregister_netdev(netdev);
+}
diff --git a/drivers/net/wireless/zd1211rw/zd_netdev.h b/drivers/net/wireless/zd1211rw/zd_netdev.h
new file mode 100644
index 000000000..374a95707
--- /dev/null
+++ b/drivers/net/wireless/zd1211rw/zd_netdev.h
@@ -0,0 +1,45 @@
+/* zd_netdev.h: Header for net device related functions.
+ *
+ * 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
+ */
+
+#ifndef _ZD_NETDEV_H
+#define _ZD_NETDEV_H
+
+#include <linux/usb.h>
+#include <linux/netdevice.h>
+#include <net/ieee80211.h>
+
+#define ZD_PRIV_SET_REGDOMAIN (SIOCIWFIRSTPRIV)
+#define ZD_PRIV_GET_REGDOMAIN (SIOCIWFIRSTPRIV+1)
+
+static inline struct ieee80211_device *zd_netdev_ieee80211(
+	struct net_device *ndev)
+{
+	return netdev_priv(ndev);
+}
+
+static inline struct net_device *zd_ieee80211_to_netdev(
+	struct ieee80211_device *ieee)
+{
+	return ieee->dev;
+}
+
+struct net_device *zd_netdev_alloc(struct usb_interface *intf);
+void zd_netdev_free(struct net_device *netdev);
+
+void zd_netdev_disconnect(struct net_device *netdev);
+
+#endif /* _ZD_NETDEV_H */
diff --git a/drivers/net/wireless/zd1211rw/zd_rf.c b/drivers/net/wireless/zd1211rw/zd_rf.c
new file mode 100644
index 000000000..d3770d2c6
--- /dev/null
+++ b/drivers/net/wireless/zd1211rw/zd_rf.c
@@ -0,0 +1,151 @@
+/* zd_rf.c
+ *
+ * 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/errno.h>
+#include <linux/string.h>
+
+#include "zd_def.h"
+#include "zd_rf.h"
+#include "zd_ieee80211.h"
+#include "zd_chip.h"
+
+static const char *rfs[] = {
+	[0]		= "unknown RF0",
+	[1]		= "unknown RF1",
+	[UW2451_RF]	= "UW2451_RF",
+	[UCHIP_RF]	= "UCHIP_RF",
+	[AL2230_RF]	= "AL2230_RF",
+	[AL7230B_RF]	= "AL7230B_RF",
+	[THETA_RF]	= "THETA_RF",
+	[AL2210_RF]	= "AL2210_RF",
+	[MAXIM_NEW_RF]	= "MAXIM_NEW_RF",
+	[UW2453_RF]	= "UW2453_RF",
+	[AL2230S_RF]	= "AL2230S_RF",
+	[RALINK_RF]	= "RALINK_RF",
+	[INTERSIL_RF]	= "INTERSIL_RF",
+	[RF2959_RF]	= "RF2959_RF",
+	[MAXIM_NEW2_RF]	= "MAXIM_NEW2_RF",
+	[PHILIPS_RF]	= "PHILIPS_RF",
+};
+
+const char *zd_rf_name(u8 type)
+{
+	if (type & 0xf0)
+		type = 0;
+	return rfs[type];
+}
+
+void zd_rf_init(struct zd_rf *rf)
+{
+	memset(rf, 0, sizeof(*rf));
+}
+
+void zd_rf_clear(struct zd_rf *rf)
+{
+	memset(rf, 0, sizeof(*rf));
+}
+
+int zd_rf_init_hw(struct zd_rf *rf, u8 type)
+{
+	int r, t;
+	struct zd_chip *chip = zd_rf_to_chip(rf);
+
+	ZD_ASSERT(mutex_is_locked(&chip->mutex));
+	switch (type) {
+	case RF2959_RF:
+		r = zd_rf_init_rf2959(rf);
+		if (r)
+			return r;
+		break;
+	case AL2230_RF:
+		r = zd_rf_init_al2230(rf);
+		if (r)
+			return r;
+		break;
+	default:
+		dev_err(zd_chip_dev(chip),
+			"RF %s %#x is not supported\n", zd_rf_name(type), type);
+		rf->type = 0;
+		return -ENODEV;
+	}
+
+	rf->type = type;
+
+	r = zd_chip_lock_phy_regs(chip);
+	if (r)
+		return r;
+	t = rf->init_hw(rf);
+	r = zd_chip_unlock_phy_regs(chip);
+	if (t)
+		r = t;
+	return r;
+}
+
+int zd_rf_scnprint_id(struct zd_rf *rf, char *buffer, size_t size)
+{
+	return scnprintf(buffer, size, "%s", zd_rf_name(rf->type));
+}
+
+int zd_rf_set_channel(struct zd_rf *rf, u8 channel)
+{
+	int r;
+
+	ZD_ASSERT(mutex_is_locked(&zd_rf_to_chip(rf)->mutex));
+	if (channel < MIN_CHANNEL24)
+		return -EINVAL;
+	if (channel > MAX_CHANNEL24)
+		return -EINVAL;
+	dev_dbg_f(zd_chip_dev(zd_rf_to_chip(rf)), "channel: %d\n", channel);
+
+	r = rf->set_channel(rf, channel);
+	if (r >= 0)
+		rf->channel = channel;
+	return r;
+}
+
+int zd_switch_radio_on(struct zd_rf *rf)
+{
+	int r, t;
+	struct zd_chip *chip = zd_rf_to_chip(rf);
+
+	ZD_ASSERT(mutex_is_locked(&chip->mutex));
+	r = zd_chip_lock_phy_regs(chip);
+	if (r)
+		return r;
+	t = rf->switch_radio_on(rf);
+	r = zd_chip_unlock_phy_regs(chip);
+	if (t)
+		r = t;
+	return r;
+}
+
+int zd_switch_radio_off(struct zd_rf *rf)
+{
+	int r, t;
+	struct zd_chip *chip = zd_rf_to_chip(rf);
+
+	/* TODO: move phy regs handling to zd_chip */
+	ZD_ASSERT(mutex_is_locked(&chip->mutex));
+	r = zd_chip_lock_phy_regs(chip);
+	if (r)
+		return r;
+	t = rf->switch_radio_off(rf);
+	r = zd_chip_unlock_phy_regs(chip);
+	if (t)
+		r = t;
+	return r;
+}
diff --git a/drivers/net/wireless/zd1211rw/zd_rf.h b/drivers/net/wireless/zd1211rw/zd_rf.h
new file mode 100644
index 000000000..ea30f693f
--- /dev/null
+++ b/drivers/net/wireless/zd1211rw/zd_rf.h
@@ -0,0 +1,82 @@
+/* zd_rf.h
+ *
+ * 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
+ */
+
+#ifndef _ZD_RF_H
+#define _ZD_RF_H
+
+#include "zd_types.h"
+
+#define UW2451_RF			0x2
+#define UCHIP_RF			0x3
+#define AL2230_RF			0x4
+#define AL7230B_RF			0x5	/* a,b,g */
+#define THETA_RF			0x6
+#define AL2210_RF			0x7
+#define MAXIM_NEW_RF			0x8
+#define UW2453_RF			0x9
+#define AL2230S_RF			0xa
+#define RALINK_RF			0xb
+#define INTERSIL_RF			0xc
+#define RF2959_RF			0xd
+#define MAXIM_NEW2_RF			0xe
+#define PHILIPS_RF			0xf
+
+#define RF_CHANNEL(ch) [(ch)-1]
+
+/* Provides functions of the RF transceiver. */
+
+enum {
+	RF_REG_BITS = 6,
+	RF_VALUE_BITS = 18,
+	RF_RV_BITS = RF_REG_BITS + RF_VALUE_BITS,
+};
+
+struct zd_rf {
+	u8 type;
+
+	u8 channel;
+	/*
+	 * Whether this RF should patch the 6M band edge
+	 * (assuming E2P_POD agrees)
+	 */
+	u8 patch_6m_band_edge:1;
+
+	/* RF-specific functions */
+	int (*init_hw)(struct zd_rf *rf);
+	int (*set_channel)(struct zd_rf *rf, u8 channel);
+	int (*switch_radio_on)(struct zd_rf *rf);
+	int (*switch_radio_off)(struct zd_rf *rf);
+};
+
+const char *zd_rf_name(u8 type);
+void zd_rf_init(struct zd_rf *rf);
+void zd_rf_clear(struct zd_rf *rf);
+int zd_rf_init_hw(struct zd_rf *rf, u8 type);
+
+int zd_rf_scnprint_id(struct zd_rf *rf, char *buffer, size_t size);
+
+int zd_rf_set_channel(struct zd_rf *rf, u8 channel);
+
+int zd_switch_radio_on(struct zd_rf *rf);
+int zd_switch_radio_off(struct zd_rf *rf);
+
+/* Functions for individual RF chips */
+
+int zd_rf_init_rf2959(struct zd_rf *rf);
+int zd_rf_init_al2230(struct zd_rf *rf);
+
+#endif /* _ZD_RF_H */
diff --git a/drivers/net/wireless/zd1211rw/zd_rf_al2230.c b/drivers/net/wireless/zd1211rw/zd_rf_al2230.c
new file mode 100644
index 000000000..0948b25f6
--- /dev/null
+++ b/drivers/net/wireless/zd1211rw/zd_rf_al2230.c
@@ -0,0 +1,308 @@
+/* zd_rf_al2230.c: Functions for the AL2230 RF controller
+ *
+ * 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 "zd_rf.h"
+#include "zd_usb.h"
+#include "zd_chip.h"
+
+static const u32 al2230_table[][3] = {
+	RF_CHANNEL( 1) = { 0x03f790, 0x033331, 0x00000d, },
+	RF_CHANNEL( 2) = { 0x03f790, 0x0b3331, 0x00000d, },
+	RF_CHANNEL( 3) = { 0x03e790, 0x033331, 0x00000d, },
+	RF_CHANNEL( 4) = { 0x03e790, 0x0b3331, 0x00000d, },
+	RF_CHANNEL( 5) = { 0x03f7a0, 0x033331, 0x00000d, },
+	RF_CHANNEL( 6) = { 0x03f7a0, 0x0b3331, 0x00000d, },
+	RF_CHANNEL( 7) = { 0x03e7a0, 0x033331, 0x00000d, },
+	RF_CHANNEL( 8) = { 0x03e7a0, 0x0b3331, 0x00000d, },
+	RF_CHANNEL( 9) = { 0x03f7b0, 0x033331, 0x00000d, },
+	RF_CHANNEL(10) = { 0x03f7b0, 0x0b3331, 0x00000d, },
+	RF_CHANNEL(11) = { 0x03e7b0, 0x033331, 0x00000d, },
+	RF_CHANNEL(12) = { 0x03e7b0, 0x0b3331, 0x00000d, },
+	RF_CHANNEL(13) = { 0x03f7c0, 0x033331, 0x00000d, },
+	RF_CHANNEL(14) = { 0x03e7c0, 0x066661, 0x00000d, },
+};
+
+static int zd1211_al2230_init_hw(struct zd_rf *rf)
+{
+	int r;
+	struct zd_chip *chip = zd_rf_to_chip(rf);
+
+	static const struct zd_ioreq16 ioreqs[] = {
+		{ CR15,   0x20 }, { CR23,   0x40 }, { CR24,  0x20 },
+		{ CR26,   0x11 }, { CR28,   0x3e }, { CR29,  0x00 },
+		{ CR44,   0x33 }, { CR106,  0x2a }, { CR107, 0x1a },
+		{ CR109,  0x09 }, { CR110,  0x27 }, { CR111, 0x2b },
+		{ CR112,  0x2b }, { CR119,  0x0a }, { CR10,  0x89 },
+		/* for newest (3rd cut) AL2300 */
+		{ CR17,   0x28 },
+		{ CR26,   0x93 }, { CR34,   0x30 },
+		/* for newest (3rd cut) AL2300 */
+		{ CR35,   0x3e },
+		{ CR41,   0x24 }, { CR44,   0x32 },
+		/* for newest (3rd cut) AL2300 */
+		{ CR46,   0x96 },
+		{ CR47,   0x1e }, { CR79,   0x58 }, { CR80,  0x30 },
+		{ CR81,   0x30 }, { CR87,   0x0a }, { CR89,  0x04 },
+		{ CR92,   0x0a }, { CR99,   0x28 }, { CR100, 0x00 },
+		{ CR101,  0x13 }, { CR102,  0x27 }, { CR106, 0x24 },
+		{ CR107,  0x2a }, { CR109,  0x09 }, { CR110, 0x13 },
+		{ CR111,  0x1f }, { CR112,  0x1f }, { CR113, 0x27 },
+		{ CR114,  0x27 },
+		/* for newest (3rd cut) AL2300 */
+		{ CR115,  0x24 },
+		{ CR116,  0x24 }, { CR117,  0xf4 }, { CR118, 0xfc },
+		{ CR119,  0x10 }, { CR120,  0x4f }, { CR121, 0x77 },
+		{ CR122,  0xe0 }, { CR137,  0x88 }, { CR252, 0xff },
+		{ CR253,  0xff },
+
+		/* These following happen separately in the vendor driver */
+		{ },
+
+		/* shdnb(PLL_ON)=0 */
+		{ CR251,  0x2f },
+		/* shdnb(PLL_ON)=1 */
+		{ CR251,  0x3f },
+		{ CR138,  0x28 }, { CR203,  0x06 },
+	};
+
+	static const u32 rv[] = {
+		/* Channel 1 */
+		0x03f790,
+		0x033331,
+		0x00000d,
+
+		0x0b3331,
+		0x03b812,
+		0x00fff3,
+		0x000da4,
+		0x0f4dc5, /* fix freq shift, 0x04edc5 */
+		0x0805b6,
+		0x011687,
+		0x000688,
+		0x0403b9, /* external control TX power (CR31) */
+		0x00dbba,
+		0x00099b,
+		0x0bdffc,
+		0x00000d,
+		0x00500f,
+
+		/* These writes happen separately in the vendor driver */
+		0x00d00f,
+		0x004c0f,
+		0x00540f,
+		0x00700f,
+		0x00500f,
+	};
+
+	r = zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
+	if (r)
+		return r;
+
+	r = zd_rfwritev_locked(chip, rv, ARRAY_SIZE(rv), RF_RV_BITS);
+	if (r)
+		return r;
+
+	return 0;
+}
+
+static int zd1211b_al2230_init_hw(struct zd_rf *rf)
+{
+	int r;
+	struct zd_chip *chip = zd_rf_to_chip(rf);
+
+	static const struct zd_ioreq16 ioreqs1[] = {
+		{ CR10,  0x89 }, { CR15,  0x20 },
+		{ CR17,  0x2B }, /* for newest(3rd cut) AL2230 */
+		{ CR23,  0x40 }, { CR24,  0x20 }, { CR26,  0x93 },
+		{ CR28,  0x3e }, { CR29,  0x00 },
+		{ CR33,  0x28 }, /* 5621 */
+		{ CR34,  0x30 },
+		{ CR35,  0x3e }, /* for newest(3rd cut) AL2230 */
+		{ CR41,  0x24 }, { CR44,  0x32 },
+		{ CR46,  0x99 }, /* for newest(3rd cut) AL2230 */
+		{ CR47,  0x1e },
+
+		/* ZD1211B 05.06.10 */
+		{ CR48,  0x00 }, { CR49,  0x00 }, { CR51,  0x01 },
+		{ CR52,  0x80 }, { CR53,  0x7e }, { CR65,  0x00 },
+		{ CR66,  0x00 }, { CR67,  0x00 }, { CR68,  0x00 },
+		{ CR69,  0x28 },
+
+		{ CR79,  0x58 }, { CR80,  0x30 }, { CR81,  0x30 },
+		{ CR87,  0x0a }, { CR89,  0x04 },
+		{ CR91,  0x00 }, /* 5621 */
+		{ CR92,  0x0a },
+		{ CR98,  0x8d }, /* 4804,  for 1212 new algorithm */
+		{ CR99,  0x00 }, /* 5621 */
+		{ CR101, 0x13 }, { CR102, 0x27 },
+		{ CR106, 0x24 }, /* for newest(3rd cut) AL2230 */
+		{ CR107, 0x2a },
+		{ CR109, 0x13 }, /* 4804, for 1212 new algorithm */
+		{ CR110, 0x1f }, /* 4804, for 1212 new algorithm */
+		{ CR111, 0x1f }, { CR112, 0x1f }, { CR113, 0x27 },
+		{ CR114, 0x27 },
+		{ CR115, 0x26 }, /* 24->26 at 4902 for newest(3rd cut) AL2230 */
+		{ CR116, 0x24 },
+		{ CR117, 0xfa }, /* for 1211b */
+		{ CR118, 0xfa }, /* for 1211b */
+		{ CR119, 0x10 },
+		{ CR120, 0x4f },
+		{ CR121, 0x6c }, /* for 1211b */
+		{ CR122, 0xfc }, /* E0->FC at 4902 */
+		{ CR123, 0x57 }, /* 5623 */
+		{ CR125, 0xad }, /* 4804, for 1212 new algorithm */
+		{ CR126, 0x6c }, /* 5614 */
+		{ CR127, 0x03 }, /* 4804, for 1212 new algorithm */
+		{ CR137, 0x50 }, /* 5614 */
+		{ CR138, 0xa8 },
+		{ CR144, 0xac }, /* 5621 */
+		{ CR150, 0x0d }, { CR252, 0x00 }, { CR253, 0x00 },
+	};
+
+	static const u32 rv1[] = {
+		/* channel 1 */
+		0x03f790,
+		0x033331,
+		0x00000d,
+
+		0x0b3331,
+		0x03b812,
+		0x00fff3,
+		0x0005a4,
+		0x0f4dc5, /* fix freq shift 0x044dc5 */
+		0x0805b6,
+		0x0146c7,
+		0x000688,
+		0x0403b9, /* External control TX power (CR31) */
+		0x00dbba,
+		0x00099b,
+		0x0bdffc,
+		0x00000d,
+		0x00580f,
+	};
+
+	static const struct zd_ioreq16 ioreqs2[] = {
+		{ CR47,  0x1e }, { CR_RFCFG, 0x03 },
+	};
+
+	static const u32 rv2[] = {
+		0x00880f,
+		0x00080f,
+	};
+
+	static const struct zd_ioreq16 ioreqs3[] = {
+		{ CR_RFCFG, 0x00 }, { CR47, 0x1e }, { CR251, 0x7f },
+	};
+
+	static const u32 rv3[] = {
+		0x00d80f,
+		0x00780f,
+		0x00580f,
+	};
+
+	static const struct zd_ioreq16 ioreqs4[] = {
+		{ CR138, 0x28 }, { CR203, 0x06 },
+	};
+
+	r = zd_iowrite16a_locked(chip, ioreqs1, ARRAY_SIZE(ioreqs1));
+	if (r)
+		return r;
+	r = zd_rfwritev_locked(chip, rv1, ARRAY_SIZE(rv1), RF_RV_BITS);
+	if (r)
+		return r;
+	r = zd_iowrite16a_locked(chip, ioreqs2, ARRAY_SIZE(ioreqs2));
+	if (r)
+		return r;
+	r = zd_rfwritev_locked(chip, rv2, ARRAY_SIZE(rv2), RF_RV_BITS);
+	if (r)
+		return r;
+	r = zd_iowrite16a_locked(chip, ioreqs3, ARRAY_SIZE(ioreqs3));
+	if (r)
+		return r;
+	r = zd_rfwritev_locked(chip, rv3, ARRAY_SIZE(rv3), RF_RV_BITS);
+	if (r)
+		return r;
+	return zd_iowrite16a_locked(chip, ioreqs4, ARRAY_SIZE(ioreqs4));
+}
+
+static int al2230_set_channel(struct zd_rf *rf, u8 channel)
+{
+	int r;
+	const u32 *rv = al2230_table[channel-1];
+	struct zd_chip *chip = zd_rf_to_chip(rf);
+	static const struct zd_ioreq16 ioreqs[] = {
+		{ CR138, 0x28 },
+		{ CR203, 0x06 },
+	};
+
+	r = zd_rfwritev_locked(chip, rv, 3, RF_RV_BITS);
+	if (r)
+		return r;
+	return zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
+}
+
+static int zd1211_al2230_switch_radio_on(struct zd_rf *rf)
+{
+	struct zd_chip *chip = zd_rf_to_chip(rf);
+	static const struct zd_ioreq16 ioreqs[] = {
+		{ CR11,  0x00 },
+		{ CR251, 0x3f },
+	};
+
+	return zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
+}
+
+static int zd1211b_al2230_switch_radio_on(struct zd_rf *rf)
+{
+	struct zd_chip *chip = zd_rf_to_chip(rf);
+	static const struct zd_ioreq16 ioreqs[] = {
+		{ CR11,  0x00 },
+		{ CR251, 0x7f },
+	};
+
+	return zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
+}
+
+static int al2230_switch_radio_off(struct zd_rf *rf)
+{
+	struct zd_chip *chip = zd_rf_to_chip(rf);
+	static const struct zd_ioreq16 ioreqs[] = {
+		{ CR11,  0x04 },
+		{ CR251, 0x2f },
+	};
+
+	return zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
+}
+
+int zd_rf_init_al2230(struct zd_rf *rf)
+{
+	struct zd_chip *chip = zd_rf_to_chip(rf);
+
+	rf->set_channel = al2230_set_channel;
+	rf->switch_radio_off = al2230_switch_radio_off;
+	if (chip->is_zd1211b) {
+		rf->init_hw = zd1211b_al2230_init_hw;
+		rf->switch_radio_on = zd1211b_al2230_switch_radio_on;
+	} else {
+		rf->init_hw = zd1211_al2230_init_hw;
+		rf->switch_radio_on = zd1211_al2230_switch_radio_on;
+	}
+	rf->patch_6m_band_edge = 1;
+	return 0;
+}
diff --git a/drivers/net/wireless/zd1211rw/zd_rf_rf2959.c b/drivers/net/wireless/zd1211rw/zd_rf_rf2959.c
new file mode 100644
index 000000000..58247271c
--- /dev/null
+++ b/drivers/net/wireless/zd1211rw/zd_rf_rf2959.c
@@ -0,0 +1,279 @@
+/* zd_rf_rfmd.c: Functions for the RFMD RF controller
+ *
+ * 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 "zd_rf.h"
+#include "zd_usb.h"
+#include "zd_chip.h"
+
+static u32 rf2959_table[][2] = {
+	RF_CHANNEL( 1) = { 0x181979, 0x1e6666 },
+	RF_CHANNEL( 2) = { 0x181989, 0x1e6666 },
+	RF_CHANNEL( 3) = { 0x181999, 0x1e6666 },
+	RF_CHANNEL( 4) = { 0x1819a9, 0x1e6666 },
+	RF_CHANNEL( 5) = { 0x1819b9, 0x1e6666 },
+	RF_CHANNEL( 6) = { 0x1819c9, 0x1e6666 },
+	RF_CHANNEL( 7) = { 0x1819d9, 0x1e6666 },
+	RF_CHANNEL( 8) = { 0x1819e9, 0x1e6666 },
+	RF_CHANNEL( 9) = { 0x1819f9, 0x1e6666 },
+	RF_CHANNEL(10) = { 0x181a09, 0x1e6666 },
+	RF_CHANNEL(11) = { 0x181a19, 0x1e6666 },
+	RF_CHANNEL(12) = { 0x181a29, 0x1e6666 },
+	RF_CHANNEL(13) = { 0x181a39, 0x1e6666 },
+	RF_CHANNEL(14) = { 0x181a60, 0x1c0000 },
+};
+
+#if 0
+static int bits(u32 rw, int from, int to)
+{
+	rw &= ~(0xffffffffU << (to+1));
+	rw >>= from;
+	return rw;
+}
+
+static int bit(u32 rw, int bit)
+{
+	return bits(rw, bit, bit);
+}
+
+static void dump_regwrite(u32 rw)
+{
+	int reg = bits(rw, 18, 22);
+	int rw_flag = bits(rw, 23, 23);
+	PDEBUG("rf2959 %#010x reg %d rw %d", rw, reg, rw_flag);
+
+	switch (reg) {
+	case 0:
+		PDEBUG("reg0 CFG1 ref_sel %d hybernate %d rf_vco_reg_en %d"
+		       " if_vco_reg_en %d if_vga_en %d",
+		       bits(rw, 14, 15), bit(rw, 3), bit(rw, 2), bit(rw, 1),
+		       bit(rw, 0));
+		break;
+	case 1:
+		PDEBUG("reg1 IFPLL1 pll_en1 %d kv_en1 %d vtc_en1 %d lpf1 %d"
+		       " cpl1 %d pdp1 %d autocal_en1 %d ld_en1 %d ifloopr %d"
+		       " ifloopc %d dac1 %d",
+		       bit(rw, 17), bit(rw, 16), bit(rw, 15), bit(rw, 14),
+		       bit(rw, 13), bit(rw, 12), bit(rw, 11), bit(rw, 10),
+		       bits(rw, 7, 9), bits(rw, 4, 6), bits(rw, 0, 3));
+		break;
+	case 2:
+		PDEBUG("reg2 IFPLL2 n1 %d num1 %d",
+		       bits(rw, 6, 17), bits(rw, 0, 5));
+		break;
+	case 3:
+		PDEBUG("reg3 IFPLL3 num %d", bits(rw, 0, 17));
+		break;
+	case 4:
+		PDEBUG("reg4 IFPLL4 dn1 %#04x ct_def1 %d kv_def1 %d",
+		       bits(rw, 8, 16), bits(rw, 4, 7), bits(rw, 0, 3));
+		break;
+	case 5:
+		PDEBUG("reg5 RFPLL1 pll_en %d kv_en %d vtc_en %d lpf %d cpl %d"
+		       " pdp %d autocal_en %d ld_en %d rfloopr %d rfloopc %d"
+		       " dac %d",
+		       bit(rw, 17), bit(rw, 16), bit(rw, 15), bit(rw, 14),
+		       bit(rw, 13), bit(rw, 12), bit(rw, 11), bit(rw, 10),
+		       bits(rw, 7, 9), bits(rw, 4, 6), bits(rw, 0,3));
+		break;
+	case 6:
+		PDEBUG("reg6 RFPLL2 n %d num %d",
+		       bits(rw, 6, 17), bits(rw, 0, 5));
+		break;
+	case 7:
+		PDEBUG("reg7 RFPLL3 num2 %d", bits(rw, 0, 17));
+		break;
+	case 8:
+		PDEBUG("reg8 RFPLL4 dn %#06x ct_def %d kv_def %d",
+		       bits(rw, 8, 16), bits(rw, 4, 7), bits(rw, 0, 3));
+		break;
+	case 9:
+		PDEBUG("reg9 CAL1 tvco %d tlock %d m_ct_value %d ld_window %d",
+		       bits(rw, 13, 17), bits(rw, 8, 12), bits(rw, 3, 7),
+		       bits(rw, 0, 2));
+		break;
+	case 10:
+		PDEBUG("reg10 TXRX1 rxdcfbbyps %d pcontrol %d txvgc %d"
+		       " rxlpfbw %d txlpfbw %d txdiffmode %d txenmode %d"
+		       " intbiasen %d tybypass %d",
+		       bit(rw, 17), bits(rw, 15, 16), bits(rw, 10, 14),
+		       bits(rw, 7, 9), bits(rw, 4, 6), bit(rw, 3), bit(rw, 2),
+		       bit(rw, 1), bit(rw, 0));
+		break;
+	case 11:
+		PDEBUG("reg11 PCNT1 mid_bias %d p_desired %d pc_offset %d"
+			" tx_delay %d",
+			bits(rw, 15, 17), bits(rw, 9, 14), bits(rw, 3, 8),
+			bits(rw, 0, 2));
+		break;
+	case 12:
+		PDEBUG("reg12 PCNT2 max_power %d mid_power %d min_power %d",
+		       bits(rw, 12, 17), bits(rw, 6, 11), bits(rw, 0, 5));
+		break;
+	case 13:
+		PDEBUG("reg13 VCOT1 rfpll vco comp %d ifpll vco comp %d"
+		       " lobias %d if_biasbuf %d if_biasvco %d rf_biasbuf %d"
+		       " rf_biasvco %d",
+		       bit(rw, 17), bit(rw, 16), bit(rw, 15),
+		       bits(rw, 8, 9), bits(rw, 5, 7), bits(rw, 3, 4),
+		       bits(rw, 0, 2));
+		break;
+	case 14:
+		PDEBUG("reg14 IQCAL rx_acal %d rx_pcal %d"
+		       " tx_acal %d tx_pcal %d",
+		       bits(rw, 13, 17), bits(rw, 9, 12), bits(rw, 4, 8),
+		       bits(rw, 0, 3));
+		break;
+	}
+}
+#endif /* 0 */
+
+static int rf2959_init_hw(struct zd_rf *rf)
+{
+	int r;
+	struct zd_chip *chip = zd_rf_to_chip(rf);
+
+	static const struct zd_ioreq16 ioreqs[] = {
+		{ CR2,   0x1E }, { CR9,   0x20 }, { CR10,  0x89 },
+		{ CR11,  0x00 }, { CR15,  0xD0 }, { CR17,  0x68 },
+		{ CR19,  0x4a }, { CR20,  0x0c }, { CR21,  0x0E },
+		{ CR23,  0x48 },
+		/* normal size for cca threshold */
+		{ CR24,  0x14 },
+		/* { CR24,  0x20 }, */
+		{ CR26,  0x90 }, { CR27,  0x30 }, { CR29,  0x20 },
+		{ CR31,  0xb2 }, { CR32,  0x43 }, { CR33,  0x28 },
+		{ CR38,  0x30 }, { CR34,  0x0f }, { CR35,  0xF0 },
+		{ CR41,  0x2a }, { CR46,  0x7F }, { CR47,  0x1E },
+		{ CR51,  0xc5 }, { CR52,  0xc5 }, { CR53,  0xc5 },
+		{ CR79,  0x58 }, { CR80,  0x30 }, { CR81,  0x30 },
+		{ CR82,  0x00 }, { CR83,  0x24 }, { CR84,  0x04 },
+		{ CR85,  0x00 }, { CR86,  0x10 }, { CR87,  0x2A },
+		{ CR88,  0x10 }, { CR89,  0x24 }, { CR90,  0x18 },
+		/* { CR91,  0x18 }, */
+		/* should solve continous CTS frame problems */
+		{ CR91,  0x00 },
+		{ CR92,  0x0a }, { CR93,  0x00 }, { CR94,  0x01 },
+		{ CR95,  0x00 }, { CR96,  0x40 }, { CR97,  0x37 },
+		{ CR98,  0x05 }, { CR99,  0x28 }, { CR100, 0x00 },
+		{ CR101, 0x13 }, { CR102, 0x27 }, { CR103, 0x27 },
+		{ CR104, 0x18 }, { CR105, 0x12 },
+		/* normal size */
+		{ CR106, 0x1a },
+		/* { CR106, 0x22 }, */
+		{ CR107, 0x24 }, { CR108, 0x0a }, { CR109, 0x13 },
+		{ CR110, 0x2F }, { CR111, 0x27 }, { CR112, 0x27 },
+		{ CR113, 0x27 }, { CR114, 0x27 }, { CR115, 0x40 },
+		{ CR116, 0x40 }, { CR117, 0xF0 }, { CR118, 0xF0 },
+		{ CR119, 0x16 },
+		/* no TX continuation */
+		{ CR122, 0x00 },
+		/* { CR122, 0xff }, */
+		{ CR127, 0x03 }, { CR131, 0x08 }, { CR138, 0x28 },
+		{ CR148, 0x44 }, { CR150, 0x10 }, { CR169, 0xBB },
+		{ CR170, 0xBB },
+	};
+
+	static const u32 rv[] = {
+		0x000007,  /* REG0(CFG1) */
+		0x07dd43,  /* REG1(IFPLL1) */
+		0x080959,  /* REG2(IFPLL2) */
+		0x0e6666,
+		0x116a57,  /* REG4 */
+		0x17dd43,  /* REG5 */
+		0x1819f9,  /* REG6 */
+		0x1e6666,
+		0x214554,
+		0x25e7fa,
+		0x27fffa,
+		/* The Zydas driver somehow forgets to set this value. It's
+		 * only set for Japan. We are using internal power control
+		 * for now.
+		 */
+		0x294128, /* internal power */
+		/* 0x28252c, */ /* External control TX power */
+		/* CR31_CCK, CR51_6-36M, CR52_48M, CR53_54M */
+		0x2c0000,
+		0x300000,
+		0x340000,  /* REG13(0xD) */
+		0x381e0f,  /* REG14(0xE) */
+		/* Bogus, RF2959's data sheet doesn't know register 27, which is
+		 * actually referenced here. The commented 0x11 is 17.
+		 */
+		0x6c180f,  /* REG27(0x11) */
+	};
+
+	r = zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
+	if (r)
+		return r;
+
+	return zd_rfwritev_locked(chip, rv, ARRAY_SIZE(rv), RF_RV_BITS);
+}
+
+static int rf2959_set_channel(struct zd_rf *rf, u8 channel)
+{
+	int i, r;
+	u32 *rv = rf2959_table[channel-1];
+	struct zd_chip *chip = zd_rf_to_chip(rf);
+
+	for (i = 0; i < 2; i++) {
+		r = zd_rfwrite_locked(chip, rv[i], RF_RV_BITS);
+		if (r)
+			return r;
+	}
+	return 0;
+}
+
+static int rf2959_switch_radio_on(struct zd_rf *rf)
+{
+	static const struct zd_ioreq16 ioreqs[] = {
+		{ CR10, 0x89 },
+		{ CR11, 0x00 },
+	};
+	struct zd_chip *chip = zd_rf_to_chip(rf);
+
+	return zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
+}
+
+static int rf2959_switch_radio_off(struct zd_rf *rf)
+{
+	static const struct zd_ioreq16 ioreqs[] = {
+		{ CR10, 0x15 },
+		{ CR11, 0x81 },
+	};
+	struct zd_chip *chip = zd_rf_to_chip(rf);
+
+	return zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
+}
+
+int zd_rf_init_rf2959(struct zd_rf *rf)
+{
+	struct zd_chip *chip = zd_rf_to_chip(rf);
+
+	if (chip->is_zd1211b) {
+		dev_err(zd_chip_dev(chip),
+		       "RF2959 is currently not supported for ZD1211B"
+		       " devices\n");
+		return -ENODEV;
+	}
+	rf->init_hw = rf2959_init_hw;
+	rf->set_channel = rf2959_set_channel;
+	rf->switch_radio_on = rf2959_switch_radio_on;
+	rf->switch_radio_off = rf2959_switch_radio_off;
+	return 0;
+}
diff --git a/drivers/net/wireless/zd1211rw/zd_types.h b/drivers/net/wireless/zd1211rw/zd_types.h
new file mode 100644
index 000000000..0155a1584
--- /dev/null
+++ b/drivers/net/wireless/zd1211rw/zd_types.h
@@ -0,0 +1,71 @@
+/* zd_types.h
+ *
+ * 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
+ */
+
+#ifndef _ZD_TYPES_H
+#define _ZD_TYPES_H
+
+#include <linux/types.h>
+
+/* We have three register spaces mapped into the overall USB address space of
+ * 64K words (16-bit values). There is the control register space of
+ * double-word registers, the eeprom register space and the firmware register
+ * space. The control register space is byte mapped, the others are word
+ * mapped.
+ *
+ * For that reason, we are using byte offsets for control registers and word
+ * offsets for everything else.
+ */
+
+typedef u32 __nocast zd_addr_t;
+
+enum {
+	ADDR_BASE_MASK		= 0xff000000,
+	ADDR_OFFSET_MASK	= 0x0000ffff,
+	ADDR_ZERO_MASK		= 0x00ff0000,
+	NULL_BASE		= 0x00000000,
+	USB_BASE		= 0x01000000,
+	CR_BASE			= 0x02000000,
+	CR_MAX_OFFSET		= 0x0b30,
+	E2P_BASE		= 0x03000000,
+	E2P_MAX_OFFSET		= 0x007e,
+	FW_BASE			= 0x04000000,
+	FW_MAX_OFFSET		= 0x0005,
+};
+
+#define ZD_ADDR_BASE(addr) ((u32)(addr) & ADDR_BASE_MASK)
+#define ZD_OFFSET(addr) ((u32)(addr) & ADDR_OFFSET_MASK)
+
+#define ZD_ADDR(base, offset) \
+	((zd_addr_t)(((base) & ADDR_BASE_MASK) | ((offset) & ADDR_OFFSET_MASK)))
+
+#define ZD_NULL_ADDR    ((zd_addr_t)0)
+#define USB_REG(offset)  ZD_ADDR(USB_BASE, offset)	/* word addressing */
+#define CTL_REG(offset)  ZD_ADDR(CR_BASE, offset)	/* byte addressing */
+#define E2P_REG(offset)  ZD_ADDR(E2P_BASE, offset)	/* word addressing */
+#define FW_REG(offset)   ZD_ADDR(FW_BASE, offset)	/* word addressing */
+
+static inline zd_addr_t zd_inc_word(zd_addr_t addr)
+{
+	u32 base = ZD_ADDR_BASE(addr);
+	u32 offset = ZD_OFFSET(addr);
+
+	offset += base == CR_BASE ? 2 : 1;
+
+	return base | offset;
+}
+
+#endif /* _ZD_TYPES_H */
diff --git a/drivers/net/wireless/zd1211rw/zd_usb.c b/drivers/net/wireless/zd1211rw/zd_usb.c
new file mode 100644
index 000000000..632098412
--- /dev/null
+++ b/drivers/net/wireless/zd1211rw/zd_usb.c
@@ -0,0 +1,1309 @@
+/* zd_usb.c
+ *
+ * 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 <asm/unaligned.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/firmware.h>
+#include <linux/device.h>
+#include <linux/errno.h>
+#include <linux/skbuff.h>
+#include <linux/usb.h>
+#include <net/ieee80211.h>
+
+#include "zd_def.h"
+#include "zd_netdev.h"
+#include "zd_mac.h"
+#include "zd_usb.h"
+#include "zd_util.h"
+
+static struct usb_device_id usb_ids[] = {
+	/* ZD1211 */
+	{ USB_DEVICE(0x0ace, 0x1211), .driver_info = DEVICE_ZD1211 },
+	{ USB_DEVICE(0x07b8, 0x6001), .driver_info = DEVICE_ZD1211 },
+	{ USB_DEVICE(0x126f, 0xa006), .driver_info = DEVICE_ZD1211 },
+	{ USB_DEVICE(0x6891, 0xa727), .driver_info = DEVICE_ZD1211 },
+	{ USB_DEVICE(0x0df6, 0x9071), .driver_info = DEVICE_ZD1211 },
+	{ USB_DEVICE(0x157e, 0x300b), .driver_info = DEVICE_ZD1211 },
+	/* ZD1211B */
+	{ USB_DEVICE(0x0ace, 0x1215), .driver_info = DEVICE_ZD1211B },
+	{ USB_DEVICE(0x157e, 0x300d), .driver_info = DEVICE_ZD1211B },
+	{}
+};
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("USB driver for devices with the ZD1211 chip.");
+MODULE_AUTHOR("Ulrich Kunitz");
+MODULE_AUTHOR("Daniel Drake");
+MODULE_VERSION("1.0");
+MODULE_DEVICE_TABLE(usb, usb_ids);
+
+#define FW_ZD1211_PREFIX	"zd1211/zd1211_"
+#define FW_ZD1211B_PREFIX	"zd1211/zd1211b_"
+
+/* register address handling */
+
+#ifdef DEBUG
+static int check_addr(struct zd_usb *usb, zd_addr_t addr)
+{
+	u32 base = ZD_ADDR_BASE(addr);
+	u32 offset = ZD_OFFSET(addr);
+
+	if ((u32)addr & ADDR_ZERO_MASK)
+		goto invalid_address;
+	switch (base) {
+	case USB_BASE:
+		break;
+	case CR_BASE:
+		if (offset > CR_MAX_OFFSET) {
+			dev_dbg(zd_usb_dev(usb),
+				"CR offset %#010x larger than"
+				" CR_MAX_OFFSET %#10x\n",
+				offset, CR_MAX_OFFSET);
+			goto invalid_address;
+		}
+		if (offset & 1) {
+			dev_dbg(zd_usb_dev(usb),
+				"CR offset %#010x is not a multiple of 2\n",
+				offset);
+			goto invalid_address;
+		}
+		break;
+	case E2P_BASE:
+		if (offset > E2P_MAX_OFFSET) {
+			dev_dbg(zd_usb_dev(usb),
+				"E2P offset %#010x larger than"
+				" E2P_MAX_OFFSET %#010x\n",
+				offset, E2P_MAX_OFFSET);
+			goto invalid_address;
+		}
+		break;
+	case FW_BASE:
+		if (!usb->fw_base_offset) {
+			dev_dbg(zd_usb_dev(usb),
+			       "ERROR: fw base offset has not been set\n");
+			return -EAGAIN;
+		}
+		if (offset > FW_MAX_OFFSET) {
+			dev_dbg(zd_usb_dev(usb),
+				"FW offset %#10x is larger than"
+				" FW_MAX_OFFSET %#010x\n",
+				offset, FW_MAX_OFFSET);
+			goto invalid_address;
+		}
+		break;
+	default:
+		dev_dbg(zd_usb_dev(usb),
+			"address has unsupported base %#010x\n", addr);
+		goto invalid_address;
+	}
+
+	return 0;
+invalid_address:
+	dev_dbg(zd_usb_dev(usb),
+		"ERROR: invalid address: %#010x\n", addr);
+	return -EINVAL;
+}
+#endif /* DEBUG */
+
+static u16 usb_addr(struct zd_usb *usb, zd_addr_t addr)
+{
+	u32 base;
+	u16 offset;
+
+	base = ZD_ADDR_BASE(addr);
+	offset = ZD_OFFSET(addr);
+
+	ZD_ASSERT(check_addr(usb, addr) == 0);
+
+	switch (base) {
+	case CR_BASE:
+		offset += CR_BASE_OFFSET;
+		break;
+	case E2P_BASE:
+		offset += E2P_BASE_OFFSET;
+		break;
+	case FW_BASE:
+		offset += usb->fw_base_offset;
+		break;
+	}
+
+	return offset;
+}
+
+/* USB device initialization */
+
+static int request_fw_file(
+	const struct firmware **fw, const char *name, struct device *device)
+{
+	int r;
+
+	dev_dbg_f(device, "fw name %s\n", name);
+
+	r = request_firmware(fw, name, device);
+	if (r)
+		dev_err(device,
+		       "Could not load firmware file %s. Error number %d\n",
+		       name, r);
+	return r;
+}
+
+static inline u16 get_bcdDevice(const struct usb_device *udev)
+{
+	return le16_to_cpu(udev->descriptor.bcdDevice);
+}
+
+enum upload_code_flags {
+	REBOOT = 1,
+};
+
+/* Ensures that MAX_TRANSFER_SIZE is even. */
+#define MAX_TRANSFER_SIZE (USB_MAX_TRANSFER_SIZE & ~1)
+
+static int upload_code(struct usb_device *udev,
+	const u8 *data, size_t size, u16 code_offset, int flags)
+{
+	u8 *p;
+	int r;
+
+	/* USB request blocks need "kmalloced" buffers.
+	 */
+	p = kmalloc(MAX_TRANSFER_SIZE, GFP_KERNEL);
+	if (!p) {
+		dev_err(&udev->dev, "out of memory\n");
+		r = -ENOMEM;
+		goto error;
+	}
+
+	size &= ~1;
+	while (size > 0) {
+		size_t transfer_size = size <= MAX_TRANSFER_SIZE ?
+			size : MAX_TRANSFER_SIZE;
+
+		dev_dbg_f(&udev->dev, "transfer size %zu\n", transfer_size);
+
+		memcpy(p, data, transfer_size);
+		r = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
+			USB_REQ_FIRMWARE_DOWNLOAD,
+			USB_DIR_OUT | USB_TYPE_VENDOR,
+			code_offset, 0, p, transfer_size, 1000 /* ms */);
+		if (r < 0) {
+			dev_err(&udev->dev,
+			       "USB control request for firmware upload"
+			       " failed. Error number %d\n", r);
+			goto error;
+		}
+		transfer_size = r & ~1;
+
+		size -= transfer_size;
+		data += transfer_size;
+		code_offset += transfer_size/sizeof(u16);
+	}
+
+	if (flags & REBOOT) {
+		u8 ret;
+
+		r = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
+			USB_REQ_FIRMWARE_CONFIRM,
+			USB_DIR_IN | USB_TYPE_VENDOR,
+			0, 0, &ret, sizeof(ret), 5000 /* ms */);
+		if (r != sizeof(ret)) {
+			dev_err(&udev->dev,
+				"control request firmeware confirmation failed."
+				" Return value %d\n", r);
+			if (r >= 0)
+				r = -ENODEV;
+			goto error;
+		}
+		if (ret & 0x80) {
+			dev_err(&udev->dev,
+				"Internal error while downloading."
+				" Firmware confirm return value %#04x\n",
+				(unsigned int)ret);
+			r = -ENODEV;
+			goto error;
+		}
+		dev_dbg_f(&udev->dev, "firmware confirm return value %#04x\n",
+			(unsigned int)ret);
+	}
+
+	r = 0;
+error:
+	kfree(p);
+	return r;
+}
+
+static u16 get_word(const void *data, u16 offset)
+{
+	const __le16 *p = data;
+	return le16_to_cpu(p[offset]);
+}
+
+static char *get_fw_name(char *buffer, size_t size, u8 device_type,
+	               const char* postfix)
+{
+	scnprintf(buffer, size, "%s%s",
+		device_type == DEVICE_ZD1211B ?
+			FW_ZD1211B_PREFIX : FW_ZD1211_PREFIX,
+		postfix);
+	return buffer;
+}
+
+static int upload_firmware(struct usb_device *udev, u8 device_type)
+{
+	int r;
+	u16 fw_bcdDevice;
+	u16 bcdDevice;
+	const struct firmware *ub_fw = NULL;
+	const struct firmware *uph_fw = NULL;
+	char fw_name[128];
+
+	bcdDevice = get_bcdDevice(udev);
+
+	r = request_fw_file(&ub_fw,
+		get_fw_name(fw_name, sizeof(fw_name), device_type,  "ub"),
+		&udev->dev);
+	if (r)
+		goto error;
+
+	fw_bcdDevice = get_word(ub_fw->data, EEPROM_REGS_OFFSET);
+
+	/* FIXME: do we have any reason to perform the kludge that the vendor
+	 * driver does when there is a version mismatch? (their driver uploads
+	 * different firmwares and stuff)
+	 */
+	if (fw_bcdDevice != bcdDevice) {
+		dev_info(&udev->dev,
+			"firmware device id %#06x and actual device id "
+			"%#06x differ, continuing anyway\n",
+			fw_bcdDevice, bcdDevice);
+	} else {
+		dev_dbg_f(&udev->dev,
+			"firmware device id %#06x is equal to the "
+			"actual device id\n", fw_bcdDevice);
+	}
+
+
+	r = request_fw_file(&uph_fw,
+		get_fw_name(fw_name, sizeof(fw_name), device_type, "uphr"),
+		&udev->dev);
+	if (r)
+		goto error;
+
+	r = upload_code(udev, uph_fw->data, uph_fw->size, FW_START_OFFSET,
+		        REBOOT);
+	if (r) {
+		dev_err(&udev->dev,
+			"Could not upload firmware code uph. Error number %d\n",
+			r);
+	}
+
+	/* FALL-THROUGH */
+error:
+	release_firmware(ub_fw);
+	release_firmware(uph_fw);
+	return r;
+}
+
+static void disable_read_regs_int(struct zd_usb *usb)
+{
+	struct zd_usb_interrupt *intr = &usb->intr;
+
+	spin_lock(&intr->lock);
+	intr->read_regs_enabled = 0;
+	spin_unlock(&intr->lock);
+}
+
+#define urb_dev(urb) (&(urb)->dev->dev)
+
+static inline void handle_regs_int(struct urb *urb)
+{
+	struct zd_usb *usb = urb->context;
+	struct zd_usb_interrupt *intr = &usb->intr;
+	int len;
+
+	ZD_ASSERT(in_interrupt());
+	spin_lock(&intr->lock);
+
+	if (intr->read_regs_enabled) {
+		intr->read_regs.length = len = urb->actual_length;
+
+		if (len > sizeof(intr->read_regs.buffer))
+			len = sizeof(intr->read_regs.buffer);
+		memcpy(intr->read_regs.buffer, urb->transfer_buffer, len);
+		intr->read_regs_enabled = 0;
+		complete(&intr->read_regs.completion);
+		goto out;
+	}
+
+	dev_dbg_f(urb_dev(urb), "regs interrupt ignored\n");
+out:
+	spin_unlock(&intr->lock);
+}
+
+static inline void handle_retry_failed_int(struct urb *urb)
+{
+	dev_dbg_f(urb_dev(urb), "retry failed interrupt\n");
+}
+
+
+static void int_urb_complete(struct urb *urb, struct pt_regs *pt_regs)
+{
+	int r;
+	struct usb_int_header *hdr;
+
+	switch (urb->status) {
+	case 0:
+		break;
+	case -ESHUTDOWN:
+	case -EINVAL:
+	case -ENODEV:
+	case -ENOENT:
+	case -ECONNRESET:
+	case -EPIPE:
+		goto kfree;
+	default:
+		goto resubmit;
+	}
+
+	if (urb->actual_length < sizeof(hdr)) {
+		dev_dbg_f(urb_dev(urb), "error: urb %p to small\n", urb);
+		goto resubmit;
+	}
+
+	hdr = urb->transfer_buffer;
+	if (hdr->type != USB_INT_TYPE) {
+		dev_dbg_f(urb_dev(urb), "error: urb %p wrong type\n", urb);
+		goto resubmit;
+	}
+
+	switch (hdr->id) {
+	case USB_INT_ID_REGS:
+		handle_regs_int(urb);
+		break;
+	case USB_INT_ID_RETRY_FAILED:
+		handle_retry_failed_int(urb);
+		break;
+	default:
+		dev_dbg_f(urb_dev(urb), "error: urb %p unknown id %x\n", urb,
+			(unsigned int)hdr->id);
+		goto resubmit;
+	}
+
+resubmit:
+	r = usb_submit_urb(urb, GFP_ATOMIC);
+	if (r) {
+		dev_dbg_f(urb_dev(urb), "resubmit urb %p\n", urb);
+		goto kfree;
+	}
+	return;
+kfree:
+	kfree(urb->transfer_buffer);
+}
+
+static inline int int_urb_interval(struct usb_device *udev)
+{
+	switch (udev->speed) {
+	case USB_SPEED_HIGH:
+		return 4;
+	case USB_SPEED_LOW:
+		return 10;
+	case USB_SPEED_FULL:
+	default:
+		return 1;
+	}
+}
+
+static inline int usb_int_enabled(struct zd_usb *usb)
+{
+	unsigned long flags;
+	struct zd_usb_interrupt *intr = &usb->intr;
+	struct urb *urb;
+
+	spin_lock_irqsave(&intr->lock, flags);
+	urb = intr->urb;
+	spin_unlock_irqrestore(&intr->lock, flags);
+	return urb != NULL;
+}
+
+int zd_usb_enable_int(struct zd_usb *usb)
+{
+	int r;
+	struct usb_device *udev;
+	struct zd_usb_interrupt *intr = &usb->intr;
+	void *transfer_buffer = NULL;
+	struct urb *urb;
+
+	dev_dbg_f(zd_usb_dev(usb), "\n");
+
+	urb = usb_alloc_urb(0, GFP_NOFS);
+	if (!urb) {
+		r = -ENOMEM;
+		goto out;
+	}
+
+	ZD_ASSERT(!irqs_disabled());
+	spin_lock_irq(&intr->lock);
+	if (intr->urb) {
+		spin_unlock_irq(&intr->lock);
+		r = 0;
+		goto error_free_urb;
+	}
+	intr->urb = urb;
+	spin_unlock_irq(&intr->lock);
+
+	/* TODO: make it a DMA buffer */
+	r = -ENOMEM;
+	transfer_buffer = kmalloc(USB_MAX_EP_INT_BUFFER, GFP_NOFS);
+	if (!transfer_buffer) {
+		dev_dbg_f(zd_usb_dev(usb),
+			"couldn't allocate transfer_buffer\n");
+		goto error_set_urb_null;
+	}
+
+	udev = zd_usb_to_usbdev(usb);
+	usb_fill_int_urb(urb, udev, usb_rcvintpipe(udev, EP_INT_IN),
+			 transfer_buffer, USB_MAX_EP_INT_BUFFER,
+			 int_urb_complete, usb,
+			 intr->interval);
+
+	dev_dbg_f(zd_usb_dev(usb), "submit urb %p\n", intr->urb);
+	r = usb_submit_urb(urb, GFP_NOFS);
+	if (r) {
+		dev_dbg_f(zd_usb_dev(usb),
+			 "Couldn't submit urb. Error number %d\n", r);
+		goto error;
+	}
+
+	return 0;
+error:
+	kfree(transfer_buffer);
+error_set_urb_null:
+	spin_lock_irq(&intr->lock);
+	intr->urb = NULL;
+	spin_unlock_irq(&intr->lock);
+error_free_urb:
+	usb_free_urb(urb);
+out:
+	return r;
+}
+
+void zd_usb_disable_int(struct zd_usb *usb)
+{
+	unsigned long flags;
+	struct zd_usb_interrupt *intr = &usb->intr;
+	struct urb *urb;
+
+	spin_lock_irqsave(&intr->lock, flags);
+	urb = intr->urb;
+	if (!urb) {
+		spin_unlock_irqrestore(&intr->lock, flags);
+		return;
+	}
+	intr->urb = NULL;
+	spin_unlock_irqrestore(&intr->lock, flags);
+
+	usb_kill_urb(urb);
+	dev_dbg_f(zd_usb_dev(usb), "urb %p killed\n", urb);
+	usb_free_urb(urb);
+}
+
+static void handle_rx_packet(struct zd_usb *usb, const u8 *buffer,
+			     unsigned int length)
+{
+	int i;
+	struct zd_mac *mac = zd_usb_to_mac(usb);
+	const struct rx_length_info *length_info;
+
+	if (length < sizeof(struct rx_length_info)) {
+		/* It's not a complete packet anyhow. */
+		return;
+	}
+	length_info = (struct rx_length_info *)
+		(buffer + length - sizeof(struct rx_length_info));
+
+	/* It might be that three frames are merged into a single URB
+	 * transaction. We have to check for the length info tag.
+	 *
+	 * While testing we discovered that length_info might be unaligned,
+	 * because if USB transactions are merged, the last packet will not
+	 * be padded. Unaligned access might also happen if the length_info
+	 * structure is not present.
+	 */
+	if (get_unaligned(&length_info->tag) == cpu_to_le16(RX_LENGTH_INFO_TAG))
+	{
+		unsigned int l, k, n;
+		for (i = 0, l = 0;; i++) {
+			k = le16_to_cpu(get_unaligned(&length_info->length[i]));
+			n = l+k;
+			if (n > length)
+				return;
+			zd_mac_rx(mac, buffer+l, k);
+			if (i >= 2)
+				return;
+			l = (n+3) & ~3;
+		}
+	} else {
+		zd_mac_rx(mac, buffer, length);
+	}
+}
+
+static void rx_urb_complete(struct urb *urb, struct pt_regs *pt_regs)
+{
+	struct zd_usb *usb;
+	struct zd_usb_rx *rx;
+	const u8 *buffer;
+	unsigned int length;
+
+	switch (urb->status) {
+	case 0:
+		break;
+	case -ESHUTDOWN:
+	case -EINVAL:
+	case -ENODEV:
+	case -ENOENT:
+	case -ECONNRESET:
+	case -EPIPE:
+		return;
+	default:
+		dev_dbg_f(urb_dev(urb), "urb %p error %d\n", urb, urb->status);
+		goto resubmit;
+	}
+
+	buffer = urb->transfer_buffer;
+	length = urb->actual_length;
+	usb = urb->context;
+	rx = &usb->rx;
+
+	if (length%rx->usb_packet_size > rx->usb_packet_size-4) {
+		/* If there is an old first fragment, we don't care. */
+		dev_dbg_f(urb_dev(urb), "*** first fragment ***\n");
+		ZD_ASSERT(length <= ARRAY_SIZE(rx->fragment));
+		spin_lock(&rx->lock);
+		memcpy(rx->fragment, buffer, length);
+		rx->fragment_length = length;
+		spin_unlock(&rx->lock);
+		goto resubmit;
+	}
+
+	spin_lock(&rx->lock);
+	if (rx->fragment_length > 0) {
+		/* We are on a second fragment, we believe */
+		ZD_ASSERT(length + rx->fragment_length <=
+			  ARRAY_SIZE(rx->fragment));
+		dev_dbg_f(urb_dev(urb), "*** second fragment ***\n");
+		memcpy(rx->fragment+rx->fragment_length, buffer, length);
+		handle_rx_packet(usb, rx->fragment,
+			         rx->fragment_length + length);
+		rx->fragment_length = 0;
+		spin_unlock(&rx->lock);
+	} else {
+		spin_unlock(&rx->lock);
+		handle_rx_packet(usb, buffer, length);
+	}
+
+resubmit:
+	usb_submit_urb(urb, GFP_ATOMIC);
+}
+
+struct urb *alloc_urb(struct zd_usb *usb)
+{
+	struct usb_device *udev = zd_usb_to_usbdev(usb);
+	struct urb *urb;
+	void *buffer;
+
+	urb = usb_alloc_urb(0, GFP_NOFS);
+	if (!urb)
+		return NULL;
+	buffer = usb_buffer_alloc(udev, USB_MAX_RX_SIZE, GFP_NOFS,
+		                  &urb->transfer_dma);
+	if (!buffer) {
+		usb_free_urb(urb);
+		return NULL;
+	}
+
+	usb_fill_bulk_urb(urb, udev, usb_rcvbulkpipe(udev, EP_DATA_IN),
+		          buffer, USB_MAX_RX_SIZE,
+			  rx_urb_complete, usb);
+	urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
+
+	return urb;
+}
+
+void free_urb(struct urb *urb)
+{
+	if (!urb)
+		return;
+	usb_buffer_free(urb->dev, urb->transfer_buffer_length,
+		        urb->transfer_buffer, urb->transfer_dma);
+	usb_free_urb(urb);
+}
+
+int zd_usb_enable_rx(struct zd_usb *usb)
+{
+	int i, r;
+	struct zd_usb_rx *rx = &usb->rx;
+	struct urb **urbs;
+
+	dev_dbg_f(zd_usb_dev(usb), "\n");
+
+	r = -ENOMEM;
+	urbs = kcalloc(URBS_COUNT, sizeof(struct urb *), GFP_NOFS);
+	if (!urbs)
+		goto error;
+	for (i = 0; i < URBS_COUNT; i++) {
+		urbs[i] = alloc_urb(usb);
+		if (!urbs[i])
+			goto error;
+	}
+
+	ZD_ASSERT(!irqs_disabled());
+	spin_lock_irq(&rx->lock);
+	if (rx->urbs) {
+		spin_unlock_irq(&rx->lock);
+		r = 0;
+		goto error;
+	}
+	rx->urbs = urbs;
+	rx->urbs_count = URBS_COUNT;
+	spin_unlock_irq(&rx->lock);
+
+	for (i = 0; i < URBS_COUNT; i++) {
+		r = usb_submit_urb(urbs[i], GFP_NOFS);
+		if (r)
+			goto error_submit;
+	}
+
+	return 0;
+error_submit:
+	for (i = 0; i < URBS_COUNT; i++) {
+		usb_kill_urb(urbs[i]);
+	}
+	spin_lock_irq(&rx->lock);
+	rx->urbs = NULL;
+	rx->urbs_count = 0;
+	spin_unlock_irq(&rx->lock);
+error:
+	if (urbs) {
+		for (i = 0; i < URBS_COUNT; i++)
+			free_urb(urbs[i]);
+	}
+	return r;
+}
+
+void zd_usb_disable_rx(struct zd_usb *usb)
+{
+	int i;
+	unsigned long flags;
+	struct urb **urbs;
+	unsigned int count;
+	struct zd_usb_rx *rx = &usb->rx;
+
+	spin_lock_irqsave(&rx->lock, flags);
+	urbs = rx->urbs;
+	count = rx->urbs_count;
+	spin_unlock_irqrestore(&rx->lock, flags);
+	if (!urbs)
+		return;
+
+	for (i = 0; i < count; i++) {
+		usb_kill_urb(urbs[i]);
+		free_urb(urbs[i]);
+	}
+	kfree(urbs);
+
+	spin_lock_irqsave(&rx->lock, flags);
+	rx->urbs = NULL;
+	rx->urbs_count = 0;
+	spin_unlock_irqrestore(&rx->lock, flags);
+}
+
+static void tx_urb_complete(struct urb *urb, struct pt_regs *pt_regs)
+{
+	int r;
+
+	switch (urb->status) {
+	case 0:
+		break;
+	case -ESHUTDOWN:
+	case -EINVAL:
+	case -ENODEV:
+	case -ENOENT:
+	case -ECONNRESET:
+	case -EPIPE:
+		dev_dbg_f(urb_dev(urb), "urb %p error %d\n", urb, urb->status);
+		break;
+	default:
+		dev_dbg_f(urb_dev(urb), "urb %p error %d\n", urb, urb->status);
+		goto resubmit;
+	}
+free_urb:
+	usb_buffer_free(urb->dev, urb->transfer_buffer_length,
+		        urb->transfer_buffer, urb->transfer_dma);
+	usb_free_urb(urb);
+	return;
+resubmit:
+	r = usb_submit_urb(urb, GFP_ATOMIC);
+	if (r) {
+		dev_dbg_f(urb_dev(urb), "error resubmit urb %p %d\n", urb, r);
+		goto free_urb;
+	}
+}
+
+/* Puts the frame on the USB endpoint. It doesn't wait for
+ * completion. The frame must contain the control set.
+ */
+int zd_usb_tx(struct zd_usb *usb, const u8 *frame, unsigned int length)
+{
+	int r;
+	struct usb_device *udev = zd_usb_to_usbdev(usb);
+	struct urb *urb;
+	void *buffer;
+
+	urb = usb_alloc_urb(0, GFP_ATOMIC);
+	if (!urb) {
+		r = -ENOMEM;
+		goto out;
+	}
+
+	buffer = usb_buffer_alloc(zd_usb_to_usbdev(usb), length, GFP_ATOMIC,
+		                  &urb->transfer_dma);
+	if (!buffer) {
+		r = -ENOMEM;
+		goto error_free_urb;
+	}
+	memcpy(buffer, frame, length);
+
+	usb_fill_bulk_urb(urb, udev, usb_sndbulkpipe(udev, EP_DATA_OUT),
+		          buffer, length, tx_urb_complete, NULL);
+	urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
+
+	r = usb_submit_urb(urb, GFP_ATOMIC);
+	if (r)
+		goto error;
+	return 0;
+error:
+	usb_buffer_free(zd_usb_to_usbdev(usb), length, buffer,
+		        urb->transfer_dma);
+error_free_urb:
+	usb_free_urb(urb);
+out:
+	return r;
+}
+
+static inline void init_usb_interrupt(struct zd_usb *usb)
+{
+	struct zd_usb_interrupt *intr = &usb->intr;
+
+	spin_lock_init(&intr->lock);
+	intr->interval = int_urb_interval(zd_usb_to_usbdev(usb));
+	init_completion(&intr->read_regs.completion);
+	intr->read_regs.cr_int_addr = cpu_to_le16(usb_addr(usb, CR_INTERRUPT));
+}
+
+static inline void init_usb_rx(struct zd_usb *usb)
+{
+	struct zd_usb_rx *rx = &usb->rx;
+	spin_lock_init(&rx->lock);
+	if (interface_to_usbdev(usb->intf)->speed == USB_SPEED_HIGH) {
+		rx->usb_packet_size = 512;
+	} else {
+		rx->usb_packet_size = 64;
+	}
+	ZD_ASSERT(rx->fragment_length == 0);
+}
+
+static inline void init_usb_tx(struct zd_usb *usb)
+{
+	/* FIXME: at this point we will allocate a fixed number of urb's for
+	 * use in a cyclic scheme */
+}
+
+void zd_usb_init(struct zd_usb *usb, struct net_device *netdev,
+	         struct usb_interface *intf)
+{
+	memset(usb, 0, sizeof(*usb));
+	usb->intf = usb_get_intf(intf);
+	usb_set_intfdata(usb->intf, netdev);
+	init_usb_interrupt(usb);
+	init_usb_tx(usb);
+	init_usb_rx(usb);
+}
+
+int zd_usb_init_hw(struct zd_usb *usb)
+{
+	int r;
+	struct zd_chip *chip = zd_usb_to_chip(usb);
+
+	ZD_ASSERT(mutex_is_locked(&chip->mutex));
+	r = zd_ioread16_locked(chip, &usb->fw_base_offset,
+		        USB_REG((u16)FW_BASE_ADDR_OFFSET));
+	if (r)
+		return r;
+	dev_dbg_f(zd_usb_dev(usb), "fw_base_offset: %#06hx\n",
+		 usb->fw_base_offset);
+
+	return 0;
+}
+
+void zd_usb_clear(struct zd_usb *usb)
+{
+	usb_set_intfdata(usb->intf, NULL);
+	usb_put_intf(usb->intf);
+	memset(usb, 0, sizeof(*usb));
+	/* FIXME: usb_interrupt, usb_tx, usb_rx? */
+}
+
+static const char *speed(enum usb_device_speed speed)
+{
+	switch (speed) {
+	case USB_SPEED_LOW:
+		return "low";
+	case USB_SPEED_FULL:
+		return "full";
+	case USB_SPEED_HIGH:
+		return "high";
+	default:
+		return "unknown speed";
+	}
+}
+
+static int scnprint_id(struct usb_device *udev, char *buffer, size_t size)
+{
+	return scnprintf(buffer, size, "%04hx:%04hx v%04hx %s",
+		le16_to_cpu(udev->descriptor.idVendor),
+		le16_to_cpu(udev->descriptor.idProduct),
+		get_bcdDevice(udev),
+		speed(udev->speed));
+}
+
+int zd_usb_scnprint_id(struct zd_usb *usb, char *buffer, size_t size)
+{
+	struct usb_device *udev = interface_to_usbdev(usb->intf);
+	return scnprint_id(udev, buffer, size);
+}
+
+#ifdef DEBUG
+static void print_id(struct usb_device *udev)
+{
+	char buffer[40];
+
+	scnprint_id(udev, buffer, sizeof(buffer));
+	buffer[sizeof(buffer)-1] = 0;
+	dev_dbg_f(&udev->dev, "%s\n", buffer);
+}
+#else
+#define print_id(udev) do { } while (0)
+#endif
+
+static int probe(struct usb_interface *intf, const struct usb_device_id *id)
+{
+	int r;
+	struct usb_device *udev = interface_to_usbdev(intf);
+	struct net_device *netdev = NULL;
+
+	print_id(udev);
+
+	switch (udev->speed) {
+	case USB_SPEED_LOW:
+	case USB_SPEED_FULL:
+	case USB_SPEED_HIGH:
+		break;
+	default:
+		dev_dbg_f(&intf->dev, "Unknown USB speed\n");
+		r = -ENODEV;
+		goto error;
+	}
+
+	netdev = zd_netdev_alloc(intf);
+	if (netdev == NULL) {
+		r = -ENOMEM;
+		goto error;
+	}
+
+	r = upload_firmware(udev, id->driver_info);
+	if (r) {
+		dev_err(&intf->dev,
+		       "couldn't load firmware. Error number %d\n", r);
+		goto error;
+	}
+
+	r = usb_reset_configuration(udev);
+	if (r) {
+		dev_dbg_f(&intf->dev,
+			"couldn't reset configuration. Error number %d\n", r);
+		goto error;
+	}
+
+	/* At this point the interrupt endpoint is not generally enabled. We
+	 * save the USB bandwidth until the network device is opened. But
+	 * notify that the initialization of the MAC will require the
+	 * interrupts to be temporary enabled.
+	 */
+	r = zd_mac_init_hw(zd_netdev_mac(netdev), id->driver_info);
+	if (r) {
+		dev_dbg_f(&intf->dev,
+		         "couldn't initialize mac. Error number %d\n", r);
+		goto error;
+	}
+
+	r = register_netdev(netdev);
+	if (r) {
+		dev_dbg_f(&intf->dev,
+			 "couldn't register netdev. Error number %d\n", r);
+		goto error;
+	}
+
+	dev_dbg_f(&intf->dev, "successful\n");
+	dev_info(&intf->dev,"%s\n", netdev->name);
+	return 0;
+error:
+	usb_reset_device(interface_to_usbdev(intf));
+	zd_netdev_free(netdev);
+	return r;
+}
+
+static void disconnect(struct usb_interface *intf)
+{
+	struct net_device *netdev = zd_intf_to_netdev(intf);
+	struct zd_mac *mac = zd_netdev_mac(netdev);
+	struct zd_usb *usb = &mac->chip.usb;
+
+	dev_dbg_f(zd_usb_dev(usb), "\n");
+
+	zd_netdev_disconnect(netdev);
+
+	/* Just in case something has gone wrong! */
+	zd_usb_disable_rx(usb);
+	zd_usb_disable_int(usb);
+
+	/* If the disconnect has been caused by a removal of the
+	 * driver module, the reset allows reloading of the driver. If the
+	 * reset will not be executed here, the upload of the firmware in the
+	 * probe function caused by the reloading of the driver will fail.
+	 */
+	usb_reset_device(interface_to_usbdev(intf));
+
+	/* If somebody still waits on this lock now, this is an error. */
+	zd_netdev_free(netdev);
+	dev_dbg(&intf->dev, "disconnected\n");
+}
+
+static struct usb_driver driver = {
+	.name		= "zd1211rw",
+	.id_table	= usb_ids,
+	.probe		= probe,
+	.disconnect	= disconnect,
+};
+
+static int __init usb_init(void)
+{
+	int r;
+
+	pr_debug("usb_init()\n");
+
+	r = usb_register(&driver);
+	if (r) {
+		printk(KERN_ERR "usb_register() failed. Error number %d\n", r);
+		return r;
+	}
+
+	pr_debug("zd1211rw initialized\n");
+	return 0;
+}
+
+static void __exit usb_exit(void)
+{
+	pr_debug("usb_exit()\n");
+	usb_deregister(&driver);
+}
+
+module_init(usb_init);
+module_exit(usb_exit);
+
+static int usb_int_regs_length(unsigned int count)
+{
+	return sizeof(struct usb_int_regs) + count * sizeof(struct reg_data);
+}
+
+static void prepare_read_regs_int(struct zd_usb *usb)
+{
+	struct zd_usb_interrupt *intr = &usb->intr;
+
+	spin_lock(&intr->lock);
+	intr->read_regs_enabled = 1;
+	INIT_COMPLETION(intr->read_regs.completion);
+	spin_unlock(&intr->lock);
+}
+
+static int get_results(struct zd_usb *usb, u16 *values,
+	               struct usb_req_read_regs *req, unsigned int count)
+{
+	int r;
+	int i;
+	struct zd_usb_interrupt *intr = &usb->intr;
+	struct read_regs_int *rr = &intr->read_regs;
+	struct usb_int_regs *regs = (struct usb_int_regs *)rr->buffer;
+
+	spin_lock(&intr->lock);
+
+	r = -EIO;
+	/* The created block size seems to be larger than expected.
+	 * However results appear to be correct.
+	 */
+	if (rr->length < usb_int_regs_length(count)) {
+		dev_dbg_f(zd_usb_dev(usb),
+			 "error: actual length %d less than expected %d\n",
+			 rr->length, usb_int_regs_length(count));
+		goto error_unlock;
+	}
+	if (rr->length > sizeof(rr->buffer)) {
+		dev_dbg_f(zd_usb_dev(usb),
+			 "error: actual length %d exceeds buffer size %zu\n",
+			 rr->length, sizeof(rr->buffer));
+		goto error_unlock;
+	}
+
+	for (i = 0; i < count; i++) {
+		struct reg_data *rd = &regs->regs[i];
+		if (rd->addr != req->addr[i]) {
+			dev_dbg_f(zd_usb_dev(usb),
+				 "rd[%d] addr %#06hx expected %#06hx\n", i,
+				 le16_to_cpu(rd->addr),
+				 le16_to_cpu(req->addr[i]));
+			goto error_unlock;
+		}
+		values[i] = le16_to_cpu(rd->value);
+	}
+
+	r = 0;
+error_unlock:
+	spin_unlock(&intr->lock);
+	return r;
+}
+
+int zd_usb_ioread16v(struct zd_usb *usb, u16 *values,
+	             const zd_addr_t *addresses, unsigned int count)
+{
+	int r;
+	int i, req_len, actual_req_len;
+	struct usb_device *udev;
+	struct usb_req_read_regs *req = NULL;
+	unsigned long timeout;
+
+	if (count < 1) {
+		dev_dbg_f(zd_usb_dev(usb), "error: count is zero\n");
+		return -EINVAL;
+	}
+	if (count > USB_MAX_IOREAD16_COUNT) {
+		dev_dbg_f(zd_usb_dev(usb),
+			 "error: count %u exceeds possible max %u\n",
+			 count, USB_MAX_IOREAD16_COUNT);
+		return -EINVAL;
+	}
+	if (in_atomic()) {
+		dev_dbg_f(zd_usb_dev(usb),
+			 "error: io in atomic context not supported\n");
+		return -EWOULDBLOCK;
+	}
+	if (!usb_int_enabled(usb)) {
+		 dev_dbg_f(zd_usb_dev(usb),
+			  "error: usb interrupt not enabled\n");
+		return -EWOULDBLOCK;
+	}
+
+	req_len = sizeof(struct usb_req_read_regs) + count * sizeof(__le16);
+	req = kmalloc(req_len, GFP_NOFS);
+	if (!req)
+		return -ENOMEM;
+	req->id = cpu_to_le16(USB_REQ_READ_REGS);
+	for (i = 0; i < count; i++)
+		req->addr[i] = cpu_to_le16(usb_addr(usb, addresses[i]));
+
+	udev = zd_usb_to_usbdev(usb);
+	prepare_read_regs_int(usb);
+	r = usb_bulk_msg(udev, usb_sndbulkpipe(udev, EP_REGS_OUT),
+		         req, req_len, &actual_req_len, 1000 /* ms */);
+	if (r) {
+		dev_dbg_f(zd_usb_dev(usb),
+			"error in usb_bulk_msg(). Error number %d\n", r);
+		goto error;
+	}
+	if (req_len != actual_req_len) {
+		dev_dbg_f(zd_usb_dev(usb), "error in usb_bulk_msg()\n"
+			" req_len %d != actual_req_len %d\n",
+			req_len, actual_req_len);
+		r = -EIO;
+		goto error;
+	}
+
+	timeout = wait_for_completion_timeout(&usb->intr.read_regs.completion,
+	                                      msecs_to_jiffies(1000));
+	if (!timeout) {
+		disable_read_regs_int(usb);
+		dev_dbg_f(zd_usb_dev(usb), "read timed out\n");
+		r = -ETIMEDOUT;
+		goto error;
+	}
+
+	r = get_results(usb, values, req, count);
+error:
+	kfree(req);
+	return r;
+}
+
+int zd_usb_iowrite16v(struct zd_usb *usb, const struct zd_ioreq16 *ioreqs,
+	              unsigned int count)
+{
+	int r;
+	struct usb_device *udev;
+	struct usb_req_write_regs *req = NULL;
+	int i, req_len, actual_req_len;
+
+	if (count == 0)
+		return 0;
+	if (count > USB_MAX_IOWRITE16_COUNT) {
+		dev_dbg_f(zd_usb_dev(usb),
+			"error: count %u exceeds possible max %u\n",
+			count, USB_MAX_IOWRITE16_COUNT);
+		return -EINVAL;
+	}
+	if (in_atomic()) {
+		dev_dbg_f(zd_usb_dev(usb),
+			"error: io in atomic context not supported\n");
+		return -EWOULDBLOCK;
+	}
+
+	req_len = sizeof(struct usb_req_write_regs) +
+		  count * sizeof(struct reg_data);
+	req = kmalloc(req_len, GFP_NOFS);
+	if (!req)
+		return -ENOMEM;
+
+	req->id = cpu_to_le16(USB_REQ_WRITE_REGS);
+	for (i = 0; i < count; i++) {
+		struct reg_data *rw  = &req->reg_writes[i];
+		rw->addr = cpu_to_le16(usb_addr(usb, ioreqs[i].addr));
+		rw->value = cpu_to_le16(ioreqs[i].value);
+	}
+
+	udev = zd_usb_to_usbdev(usb);
+	r = usb_bulk_msg(udev, usb_sndbulkpipe(udev, EP_REGS_OUT),
+		         req, req_len, &actual_req_len, 1000 /* ms */);
+	if (r) {
+		dev_dbg_f(zd_usb_dev(usb),
+			"error in usb_bulk_msg(). Error number %d\n", r);
+		goto error;
+	}
+	if (req_len != actual_req_len) {
+		dev_dbg_f(zd_usb_dev(usb),
+			"error in usb_bulk_msg()"
+			" req_len %d != actual_req_len %d\n",
+			req_len, actual_req_len);
+		r = -EIO;
+		goto error;
+	}
+
+	/* FALL-THROUGH with r == 0 */
+error:
+	kfree(req);
+	return r;
+}
+
+int zd_usb_rfwrite(struct zd_usb *usb, u32 value, u8 bits)
+{
+	int r;
+	struct usb_device *udev;
+	struct usb_req_rfwrite *req = NULL;
+	int i, req_len, actual_req_len;
+	u16 bit_value_template;
+
+	if (in_atomic()) {
+		dev_dbg_f(zd_usb_dev(usb),
+			"error: io in atomic context not supported\n");
+		return -EWOULDBLOCK;
+	}
+	if (bits < USB_MIN_RFWRITE_BIT_COUNT) {
+		dev_dbg_f(zd_usb_dev(usb),
+			"error: bits %d are smaller than"
+			" USB_MIN_RFWRITE_BIT_COUNT %d\n",
+			bits, USB_MIN_RFWRITE_BIT_COUNT);
+		return -EINVAL;
+	}
+	if (bits > USB_MAX_RFWRITE_BIT_COUNT) {
+		dev_dbg_f(zd_usb_dev(usb),
+			"error: bits %d exceed USB_MAX_RFWRITE_BIT_COUNT %d\n",
+			bits, USB_MAX_RFWRITE_BIT_COUNT);
+		return -EINVAL;
+	}
+#ifdef DEBUG
+	if (value & (~0UL << bits)) {
+		dev_dbg_f(zd_usb_dev(usb),
+			"error: value %#09x has bits >= %d set\n",
+			value, bits);
+		return -EINVAL;
+	}
+#endif /* DEBUG */
+
+	dev_dbg_f(zd_usb_dev(usb), "value %#09x bits %d\n", value, bits);
+
+	r = zd_usb_ioread16(usb, &bit_value_template, CR203);
+	if (r) {
+		dev_dbg_f(zd_usb_dev(usb),
+			"error %d: Couldn't read CR203\n", r);
+		goto out;
+	}
+	bit_value_template &= ~(RF_IF_LE|RF_CLK|RF_DATA);
+
+	req_len = sizeof(struct usb_req_rfwrite) + bits * sizeof(__le16);
+	req = kmalloc(req_len, GFP_NOFS);
+	if (!req)
+		return -ENOMEM;
+
+	req->id = cpu_to_le16(USB_REQ_WRITE_RF);
+	/* 1: 3683a, but not used in ZYDAS driver */
+	req->value = cpu_to_le16(2);
+	req->bits = cpu_to_le16(bits);
+
+	for (i = 0; i < bits; i++) {
+		u16 bv = bit_value_template;
+		if (value & (1 << (bits-1-i)))
+			bv |= RF_DATA;
+		req->bit_values[i] = cpu_to_le16(bv);
+	}
+
+	udev = zd_usb_to_usbdev(usb);
+	r = usb_bulk_msg(udev, usb_sndbulkpipe(udev, EP_REGS_OUT),
+		         req, req_len, &actual_req_len, 1000 /* ms */);
+	if (r) {
+		dev_dbg_f(zd_usb_dev(usb),
+			"error in usb_bulk_msg(). Error number %d\n", r);
+		goto out;
+	}
+	if (req_len != actual_req_len) {
+		dev_dbg_f(zd_usb_dev(usb), "error in usb_bulk_msg()"
+			" req_len %d != actual_req_len %d\n",
+			req_len, actual_req_len);
+		r = -EIO;
+		goto out;
+	}
+
+	/* FALL-THROUGH with r == 0 */
+out:
+	kfree(req);
+	return r;
+}
diff --git a/drivers/net/wireless/zd1211rw/zd_usb.h b/drivers/net/wireless/zd1211rw/zd_usb.h
new file mode 100644
index 000000000..d6420283b
--- /dev/null
+++ b/drivers/net/wireless/zd1211rw/zd_usb.h
@@ -0,0 +1,240 @@
+/* zd_usb.h: Header for USB interface implemented by ZD1211 chip
+ *
+ * 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
+ */
+
+#ifndef _ZD_USB_H
+#define _ZD_USB_H
+
+#include <linux/completion.h>
+#include <linux/netdevice.h>
+#include <linux/spinlock.h>
+#include <linux/skbuff.h>
+#include <linux/usb.h>
+
+#include "zd_def.h"
+#include "zd_types.h"
+
+enum devicetype {
+	DEVICE_ZD1211  = 0,
+	DEVICE_ZD1211B = 1,
+};
+
+enum endpoints {
+	EP_CTRL	    = 0,
+	EP_DATA_OUT = 1,
+	EP_DATA_IN  = 2,
+	EP_INT_IN   = 3,
+	EP_REGS_OUT = 4,
+};
+
+enum {
+	USB_MAX_TRANSFER_SIZE		= 4096, /* bytes */
+	/* FIXME: The original driver uses this value. We have to check,
+	 * whether the MAX_TRANSFER_SIZE is sufficient and this needs only be
+	 * used if one combined frame is split over two USB transactions.
+	 */
+	USB_MAX_RX_SIZE			= 4800, /* bytes */
+	USB_MAX_IOWRITE16_COUNT		= 15,
+	USB_MAX_IOWRITE32_COUNT		= USB_MAX_IOWRITE16_COUNT/2,
+	USB_MAX_IOREAD16_COUNT		= 15,
+	USB_MAX_IOREAD32_COUNT		= USB_MAX_IOREAD16_COUNT/2,
+	USB_MIN_RFWRITE_BIT_COUNT	= 16,
+	USB_MAX_RFWRITE_BIT_COUNT	= 28,
+	USB_MAX_EP_INT_BUFFER		= 64,
+	USB_ZD1211B_BCD_DEVICE		= 0x4810,
+};
+
+enum control_requests {
+	USB_REQ_WRITE_REGS		= 0x21,
+	USB_REQ_READ_REGS		= 0x22,
+	USB_REQ_WRITE_RF		= 0x23,
+	USB_REQ_PROG_FLASH		= 0x24,
+	USB_REQ_EEPROM_START		= 0x0128, /* ? request is a byte */
+	USB_REQ_EEPROM_MID		= 0x28,
+	USB_REQ_EEPROM_END		= 0x0228, /* ? request is a byte */
+	USB_REQ_FIRMWARE_DOWNLOAD	= 0x30,
+	USB_REQ_FIRMWARE_CONFIRM	= 0x31,
+	USB_REQ_FIRMWARE_READ_DATA	= 0x32,
+};
+
+struct usb_req_read_regs {
+	__le16 id;
+	__le16 addr[0];
+} __attribute__((packed));
+
+struct reg_data {
+	__le16 addr;
+	__le16 value;
+} __attribute__((packed));
+
+struct usb_req_write_regs {
+	__le16 id;
+	struct reg_data reg_writes[0];
+} __attribute__((packed));
+
+enum {
+	RF_IF_LE = 0x02,
+	RF_CLK   = 0x04,
+	RF_DATA	 = 0x08,
+};
+
+struct usb_req_rfwrite {
+	__le16 id;
+	__le16 value;
+	/* 1: 3683a */
+	/* 2: other (default) */
+	__le16 bits;
+	/* RF2595: 24 */
+	__le16 bit_values[0];
+	/* (CR203 & ~(RF_IF_LE | RF_CLK | RF_DATA)) | (bit ? RF_DATA : 0) */
+} __attribute__((packed));
+
+/* USB interrupt */
+
+enum usb_int_id {
+	USB_INT_TYPE			= 0x01,
+	USB_INT_ID_REGS			= 0x90,
+	USB_INT_ID_RETRY_FAILED		= 0xa0,
+};
+
+enum usb_int_flags {
+	USB_INT_READ_REGS_EN		= 0x01,
+};
+
+struct usb_int_header {
+	u8 type;	/* must always be 1 */
+	u8 id;
+} __attribute__((packed));
+
+struct usb_int_regs {
+	struct usb_int_header hdr;
+	struct reg_data regs[0];
+} __attribute__((packed));
+
+struct usb_int_retry_fail {
+	struct usb_int_header hdr;
+	u8 new_rate;
+	u8 _dummy;
+	u8 addr[ETH_ALEN];
+	u8 ibss_wakeup_dest;
+} __attribute__((packed));
+
+struct read_regs_int {
+	struct completion completion;
+	/* Stores the USB int structure and contains the USB address of the
+	 * first requested register before request.
+	 */
+	u8 buffer[USB_MAX_EP_INT_BUFFER];
+	int length;
+	__le16 cr_int_addr;
+};
+
+struct zd_ioreq16 {
+	zd_addr_t addr;
+	u16 value;
+};
+
+struct zd_ioreq32 {
+	zd_addr_t addr;
+	u32 value;
+};
+
+struct zd_usb_interrupt {
+	struct read_regs_int read_regs;
+	spinlock_t lock;
+	struct urb *urb;
+	int interval;
+	u8 read_regs_enabled:1;
+};
+
+static inline struct usb_int_regs *get_read_regs(struct zd_usb_interrupt *intr)
+{
+	return (struct usb_int_regs *)intr->read_regs.buffer;
+}
+
+#define URBS_COUNT 5
+
+struct zd_usb_rx {
+	spinlock_t lock;
+	u8 fragment[2*USB_MAX_RX_SIZE];
+	unsigned int fragment_length;
+	unsigned int usb_packet_size;
+	struct urb **urbs;
+	int urbs_count;
+};
+
+struct zd_usb_tx {
+	spinlock_t lock;
+};
+
+/* Contains the usb parts. The structure doesn't require a lock, because intf
+ * and fw_base_offset, will not be changed after initialization.
+ */
+struct zd_usb {
+	struct zd_usb_interrupt intr;
+	struct zd_usb_rx rx;
+	struct zd_usb_tx tx;
+	struct usb_interface *intf;
+	u16 fw_base_offset;
+};
+
+#define zd_usb_dev(usb) (&usb->intf->dev)
+
+static inline struct usb_device *zd_usb_to_usbdev(struct zd_usb *usb)
+{
+	return interface_to_usbdev(usb->intf);
+}
+
+static inline struct net_device *zd_intf_to_netdev(struct usb_interface *intf)
+{
+	return usb_get_intfdata(intf);
+}
+
+static inline struct net_device *zd_usb_to_netdev(struct zd_usb *usb)
+{
+	return zd_intf_to_netdev(usb->intf);
+}
+
+void zd_usb_init(struct zd_usb *usb, struct net_device *netdev,
+	         struct usb_interface *intf);
+int zd_usb_init_hw(struct zd_usb *usb);
+void zd_usb_clear(struct zd_usb *usb);
+
+int zd_usb_scnprint_id(struct zd_usb *usb, char *buffer, size_t size);
+
+int zd_usb_enable_int(struct zd_usb *usb);
+void zd_usb_disable_int(struct zd_usb *usb);
+
+int zd_usb_enable_rx(struct zd_usb *usb);
+void zd_usb_disable_rx(struct zd_usb *usb);
+
+int zd_usb_tx(struct zd_usb *usb, const u8 *frame, unsigned int length);
+
+int zd_usb_ioread16v(struct zd_usb *usb, u16 *values,
+	         const zd_addr_t *addresses, unsigned int count);
+
+static inline int zd_usb_ioread16(struct zd_usb *usb, u16 *value,
+	                      const zd_addr_t addr)
+{
+	return zd_usb_ioread16v(usb, value, (const zd_addr_t *)&addr, 1);
+}
+
+int zd_usb_iowrite16v(struct zd_usb *usb, const struct zd_ioreq16 *ioreqs,
+	              unsigned int count);
+
+int zd_usb_rfwrite(struct zd_usb *usb, u32 value, u8 bits);
+
+#endif /* _ZD_USB_H */
diff --git a/drivers/net/wireless/zd1211rw/zd_util.c b/drivers/net/wireless/zd1211rw/zd_util.c
new file mode 100644
index 000000000..d20036c15
--- /dev/null
+++ b/drivers/net/wireless/zd1211rw/zd_util.c
@@ -0,0 +1,82 @@
+/* zd_util.c
+ *
+ * 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
+ *
+ * Utility program
+ */
+
+#include "zd_def.h"
+#include "zd_util.h"
+
+#ifdef DEBUG
+static char hex(u8 v)
+{
+	v &= 0xf;
+	return (v < 10 ? '0' : 'a' - 10) + v;
+}
+
+static char hex_print(u8 c)
+{
+	return (0x20 <= c && c < 0x7f) ? c : '.';
+}
+
+static void dump_line(const u8 *bytes, size_t size)
+{
+	char c;
+	size_t i;
+
+	size = size <= 8 ? size : 8;
+	printk(KERN_DEBUG "zd1211 %p ", bytes);
+	for (i = 0; i < 8; i++) {
+		switch (i) {
+		case 1:
+		case 5:
+			c = '.';
+			break;
+		case 3:
+			c = ':';
+			break;
+		default:
+			c = ' ';
+		}
+		if (i < size) {
+			printk("%c%c%c", hex(bytes[i] >> 4), hex(bytes[i]), c);
+		} else {
+			printk("  %c", c);
+		}
+	}
+
+	for (i = 0; i < size; i++)
+		printk("%c", hex_print(bytes[i]));
+	printk("\n");
+}
+
+void zd_hexdump(const void *bytes, size_t size)
+{
+	size_t i = 0;
+
+	do {
+		dump_line((u8 *)bytes + i, size-i);
+		i += 8;
+	} while (i < size);
+}
+#endif /* DEBUG */
+
+void *zd_tail(const void *buffer, size_t buffer_size, size_t tail_size)
+{
+	if (buffer_size < tail_size)
+		return NULL;
+	return (u8 *)buffer + (buffer_size - tail_size);
+}
diff --git a/drivers/net/wireless/zd1211rw/zd_util.h b/drivers/net/wireless/zd1211rw/zd_util.h
new file mode 100644
index 000000000..ce26f7ade
--- /dev/null
+++ b/drivers/net/wireless/zd1211rw/zd_util.h
@@ -0,0 +1,29 @@
+/* zd_util.h
+ *
+ * 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
+ */
+
+#ifndef _ZD_UTIL_H
+#define _ZD_UTIL_H
+
+void *zd_tail(const void *buffer, size_t buffer_size, size_t tail_size);
+
+#ifdef DEBUG
+void zd_hexdump(const void *bytes, size_t size);
+#else
+#define zd_hexdump(bytes, size)
+#endif /* DEBUG */
+
+#endif /* _ZD_UTIL_H */
diff --git a/drivers/parport/parport_ax88796.c b/drivers/parport/parport_ax88796.c
new file mode 100644
index 000000000..185063259
--- /dev/null
+++ b/drivers/parport/parport_ax88796.c
@@ -0,0 +1,443 @@
+/* linux/drivers/parport/parport_ax88796.c
+ *
+ * (c) 2005,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 version 2 as
+ * published by the Free Software Foundation.
+ *
+*/
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/parport.h>
+#include <linux/interrupt.h>
+#include <linux/errno.h>
+#include <linux/platform_device.h>
+
+#include <asm/io.h>
+#include <asm/irq.h>
+
+#define AX_SPR_BUSY		(1<<7)
+#define AX_SPR_ACK		(1<<6)
+#define AX_SPR_PE		(1<<5)
+#define AX_SPR_SLCT		(1<<4)
+#define AX_SPR_ERR		(1<<3)
+
+#define AX_CPR_nDOE		(1<<5)
+#define AX_CPR_SLCTIN		(1<<3)
+#define AX_CPR_nINIT		(1<<2)
+#define AX_CPR_ATFD		(1<<1)
+#define AX_CPR_STRB		(1<<0)
+
+struct ax_drvdata {
+	struct parport		*parport;
+	struct parport_state	 suspend;
+
+	struct device		*dev;
+	struct resource		*io;
+
+	unsigned char		 irq_enabled;
+
+	void __iomem		*base;
+	void __iomem		*spp_data;
+	void __iomem		*spp_spr;
+	void __iomem		*spp_cpr;
+};
+
+static inline struct ax_drvdata *pp_to_drv(struct parport *p)
+{
+	return p->private_data;
+}
+
+static unsigned char
+parport_ax88796_read_data(struct parport *p)
+{
+	struct ax_drvdata *dd = pp_to_drv(p);
+
+	return readb(dd->spp_data);
+}
+
+static void
+parport_ax88796_write_data(struct parport *p, unsigned char data)
+{
+	struct ax_drvdata *dd = pp_to_drv(p);
+
+	writeb(data, dd->spp_data);
+}
+
+static unsigned char
+parport_ax88796_read_control(struct parport *p)
+{
+	struct ax_drvdata *dd = pp_to_drv(p);
+	unsigned int cpr = readb(dd->spp_cpr);
+	unsigned int ret = 0;
+
+	if (!(cpr & AX_CPR_STRB))
+		ret |= PARPORT_CONTROL_STROBE;
+
+	if (!(cpr & AX_CPR_ATFD))
+		ret |= PARPORT_CONTROL_AUTOFD;
+
+	if (cpr & AX_CPR_nINIT)
+		ret |= PARPORT_CONTROL_INIT;
+
+	if (!(cpr & AX_CPR_SLCTIN))
+		ret |= PARPORT_CONTROL_SELECT;
+
+	return ret;
+}
+
+static void
+parport_ax88796_write_control(struct parport *p, unsigned char control)
+{
+	struct ax_drvdata *dd = pp_to_drv(p);
+	unsigned int cpr = readb(dd->spp_cpr);
+
+	cpr &= AX_CPR_nDOE;
+
+	if (!(control & PARPORT_CONTROL_STROBE))
+		cpr |= AX_CPR_STRB;
+
+	if (!(control & PARPORT_CONTROL_AUTOFD))
+		cpr |= AX_CPR_ATFD;
+
+	if (control & PARPORT_CONTROL_INIT)
+		cpr |= AX_CPR_nINIT;
+
+	if (!(control & PARPORT_CONTROL_SELECT))
+		cpr |= AX_CPR_SLCTIN;
+
+	dev_dbg(dd->dev, "write_control: ctrl=%02x, cpr=%02x\n", control, cpr);
+	writeb(cpr, dd->spp_cpr);
+
+	if (parport_ax88796_read_control(p) != control) {
+		dev_err(dd->dev, "write_control: read != set (%02x, %02x)\n",
+			parport_ax88796_read_control(p), control);
+	}
+}
+
+static unsigned char
+parport_ax88796_read_status(struct parport *p)
+{
+	struct ax_drvdata *dd = pp_to_drv(p);
+	unsigned int status = readb(dd->spp_spr);
+	unsigned int ret = 0;
+
+	if (status & AX_SPR_BUSY)
+		ret |= PARPORT_STATUS_BUSY;
+
+	if (status & AX_SPR_ACK)
+		ret |= PARPORT_STATUS_ACK;
+
+	if (status & AX_SPR_ERR)
+		ret |= PARPORT_STATUS_ERROR;
+
+	if (status & AX_SPR_SLCT)
+		ret |= PARPORT_STATUS_SELECT;
+
+	if (status & AX_SPR_PE)
+		ret |= PARPORT_STATUS_PAPEROUT;
+
+	return ret;
+}
+
+static unsigned char
+parport_ax88796_frob_control(struct parport *p, unsigned char mask,
+			     unsigned char val)
+{
+	struct ax_drvdata *dd = pp_to_drv(p);
+	unsigned char old = parport_ax88796_read_control(p);
+
+	dev_dbg(dd->dev, "frob: mask=%02x, val=%02x, old=%02x\n",
+		mask, val, old);
+
+	parport_ax88796_write_control(p, (old & ~mask) | val);
+	return old;
+}
+
+static void
+parport_ax88796_enable_irq(struct parport *p)
+{
+	struct ax_drvdata *dd = pp_to_drv(p);
+	unsigned long flags;
+
+	local_irq_save(flags);
+	if (!dd->irq_enabled) {
+		enable_irq(p->irq);
+		dd->irq_enabled = 1;
+	}
+	local_irq_restore(flags);
+}
+
+static void
+parport_ax88796_disable_irq(struct parport *p)
+{
+	struct ax_drvdata *dd = pp_to_drv(p);
+	unsigned long flags;
+
+	local_irq_save(flags);
+	if (dd->irq_enabled) {
+		disable_irq(p->irq);
+		dd->irq_enabled = 0;
+	}
+	local_irq_restore(flags);
+}
+
+static void
+parport_ax88796_data_forward(struct parport *p)
+{
+	struct ax_drvdata *dd = pp_to_drv(p);
+	void __iomem *cpr = dd->spp_cpr;
+
+	writeb((readb(cpr) & ~AX_CPR_nDOE), cpr);
+}
+
+static void
+parport_ax88796_data_reverse(struct parport *p)
+{
+	struct ax_drvdata *dd = pp_to_drv(p);
+	void __iomem *cpr = dd->spp_cpr;
+
+	writeb(readb(cpr) | AX_CPR_nDOE, cpr);
+}
+
+static void
+parport_ax88796_init_state(struct pardevice *d, struct parport_state *s)
+{
+	struct ax_drvdata *dd = pp_to_drv(d->port);
+
+	memset(s, 0, sizeof(struct parport_state));
+
+	dev_dbg(dd->dev, "init_state: %p: state=%p\n", d, s);
+	s->u.ax88796.cpr = readb(dd->spp_cpr);
+}
+
+static void
+parport_ax88796_save_state(struct parport *p, struct parport_state *s)
+{
+	struct ax_drvdata *dd = pp_to_drv(p);
+
+	dev_dbg(dd->dev, "save_state: %p: state=%p\n", p, s);
+	s->u.ax88796.cpr = readb(dd->spp_cpr);
+}
+
+static void
+parport_ax88796_restore_state(struct parport *p, struct parport_state *s)
+{
+	struct ax_drvdata *dd = pp_to_drv(p);
+
+	dev_dbg(dd->dev, "restore_state: %p: state=%p\n", p, s);
+	writeb(s->u.ax88796.cpr, dd->spp_cpr);
+}
+
+static irqreturn_t
+parport_ax88796_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+        parport_generic_irq(irq, dev_id, regs);
+        return IRQ_HANDLED;
+}
+
+
+static struct parport_operations parport_ax88796_ops = {
+	.write_data	= parport_ax88796_write_data,
+	.read_data	= parport_ax88796_read_data,
+
+	.write_control	= parport_ax88796_write_control,
+	.read_control	= parport_ax88796_read_control,
+	.frob_control	= parport_ax88796_frob_control,
+
+	.read_status	= parport_ax88796_read_status,
+
+	.enable_irq	= parport_ax88796_enable_irq,
+	.disable_irq	= parport_ax88796_disable_irq,
+
+	.data_forward	= parport_ax88796_data_forward,
+	.data_reverse	= parport_ax88796_data_reverse,
+
+	.init_state	= parport_ax88796_init_state,
+	.save_state	= parport_ax88796_save_state,
+	.restore_state	= parport_ax88796_restore_state,
+
+	.epp_write_data	= parport_ieee1284_epp_write_data,
+	.epp_read_data	= parport_ieee1284_epp_read_data,
+	.epp_write_addr	= parport_ieee1284_epp_write_addr,
+	.epp_read_addr	= parport_ieee1284_epp_read_addr,
+
+	.ecp_write_data	= parport_ieee1284_ecp_write_data,
+	.ecp_read_data	= parport_ieee1284_ecp_read_data,
+	.ecp_write_addr	= parport_ieee1284_ecp_write_addr,
+
+	.compat_write_data	= parport_ieee1284_write_compat,
+	.nibble_read_data	= parport_ieee1284_read_nibble,
+	.byte_read_data		= parport_ieee1284_read_byte,
+
+	.owner		= THIS_MODULE,
+};
+
+static int parport_ax88796_probe(struct platform_device *pdev)
+{
+	struct device *_dev = &pdev->dev;
+	struct ax_drvdata *dd;
+	struct parport *pp = NULL;
+	struct resource *res;
+	unsigned long size;
+	int spacing;
+	int irq;
+	int ret;
+
+	dd = kzalloc(sizeof(struct ax_drvdata), GFP_KERNEL);
+	if (dd == NULL) {
+		dev_err(_dev, "no memory for private data\n");
+		return -ENOMEM;
+	}
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (res == NULL) {
+		dev_err(_dev, "no MEM specified\n");
+		ret = -ENXIO;
+		goto exit_mem;
+	}
+
+	size = (res->end - res->start) + 1;
+	spacing = size / 3;
+
+	dd->io = request_mem_region(res->start, size, pdev->name);
+	if (dd->io == NULL) {
+		dev_err(_dev, "cannot reserve memory\n");
+		ret = -ENXIO;
+		goto exit_mem;
+	}
+
+	dd->base = ioremap(res->start, size);
+	if (dd->base == NULL) {
+		dev_err(_dev, "cannot ioremap region\n");
+		ret = -ENXIO;
+		goto exit_res;
+	}
+
+	irq = platform_get_irq(pdev, 0);
+	if (irq <= 0)
+		irq = PARPORT_IRQ_NONE;
+
+	pp = parport_register_port((unsigned long)dd->base, irq,
+				   PARPORT_DMA_NONE,
+				   &parport_ax88796_ops);
+
+	if (pp == NULL) {
+		dev_err(_dev, "failed to register parallel port\n");
+		ret = -ENOMEM;
+		goto exit_unmap;
+	}
+
+	pp->private_data = dd;
+	dd->parport = pp;
+	dd->dev = _dev;
+
+	dd->spp_data = dd->base;
+	dd->spp_spr  = dd->base + (spacing * 1);
+	dd->spp_cpr  = dd->base + (spacing * 2);
+
+	/* initialise the port controls */
+	writeb(AX_CPR_STRB, dd->spp_cpr);
+
+	if (irq >= 0) {
+		/* request irq */
+		ret = request_irq(irq, parport_ax88796_interrupt,
+				  IRQF_TRIGGER_FALLING, pdev->name, pp);
+
+		if (ret < 0)
+			goto exit_port;
+
+		dd->irq_enabled = 1;
+	}
+
+	platform_set_drvdata(pdev, pp);
+
+	dev_info(_dev, "attached parallel port driver\n");
+	parport_announce_port(pp);
+
+	return 0;
+
+ exit_port:
+	parport_remove_port(pp);
+ exit_unmap:
+	iounmap(dd->base);
+ exit_res:
+	release_resource(dd->io);
+	kfree(dd->io);
+ exit_mem:
+	kfree(dd);
+	return ret;
+}
+
+static int parport_ax88796_remove(struct platform_device *pdev)
+{
+	struct parport *p = platform_get_drvdata(pdev);
+	struct ax_drvdata *dd = pp_to_drv(p);
+
+	free_irq(p->irq, p);
+	parport_remove_port(p);
+	iounmap(dd->base);
+	release_resource(dd->io);
+	kfree(dd->io);
+	kfree(dd);
+
+	return 0;
+}
+
+#ifdef CONFIG_PM
+
+static int parport_ax88796_suspend(struct platform_device *dev,
+				   pm_message_t state)
+{
+	struct parport *p = platform_get_drvdata(dev);
+	struct ax_drvdata *dd = pp_to_drv(p);
+
+	parport_ax88796_save_state(p, &dd->suspend);
+	writeb(AX_CPR_nDOE | AX_CPR_STRB, dd->spp_cpr);
+	return 0;
+}
+
+static int parport_ax88796_resume(struct platform_device *dev)
+{
+	struct parport *p = platform_get_drvdata(dev);
+	struct ax_drvdata *dd = pp_to_drv(p);
+
+	parport_ax88796_restore_state(p, &dd->suspend);
+	return 0;
+}
+
+#else
+#define parport_ax88796_suspend NULL
+#define parport_ax88796_resume  NULL
+#endif
+
+static struct platform_driver axdrv = {
+	.driver		= {
+		.name	= "ax88796-pp",
+		.owner	= THIS_MODULE,
+	},
+	.probe		= parport_ax88796_probe,
+	.remove		= parport_ax88796_remove,
+	.suspend	= parport_ax88796_suspend,
+	.resume		= parport_ax88796_resume,
+};
+
+static int __init parport_ax88796_init(void)
+{
+	return platform_driver_register(&axdrv);
+}
+
+static void __exit parport_ax88796_exit(void)
+{
+	platform_driver_unregister(&axdrv);
+}
+
+module_init(parport_ax88796_init)
+module_exit(parport_ax88796_exit)
+
+MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>");
+MODULE_DESCRIPTION("AX88796 Parport parallel port driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/pci/msi-altix.c b/drivers/pci/msi-altix.c
new file mode 100644
index 000000000..bed4183a5
--- /dev/null
+++ b/drivers/pci/msi-altix.c
@@ -0,0 +1,210 @@
+/*
+ * 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 Silicon Graphics, Inc.  All Rights Reserved.
+ */
+
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/cpumask.h>
+
+#include <asm/sn/addrs.h>
+#include <asm/sn/intr.h>
+#include <asm/sn/pcibus_provider_defs.h>
+#include <asm/sn/pcidev.h>
+#include <asm/sn/nodepda.h>
+
+#include "msi.h"
+
+struct sn_msi_info {
+	u64 pci_addr;
+	struct sn_irq_info *sn_irq_info;
+};
+
+static struct sn_msi_info *sn_msi_info;
+
+static void
+sn_msi_teardown(unsigned int vector)
+{
+	nasid_t nasid;
+	int widget;
+	struct pci_dev *pdev;
+	struct pcidev_info *sn_pdev;
+	struct sn_irq_info *sn_irq_info;
+	struct pcibus_bussoft *bussoft;
+	struct sn_pcibus_provider *provider;
+
+	sn_irq_info = sn_msi_info[vector].sn_irq_info;
+	if (sn_irq_info == NULL || sn_irq_info->irq_int_bit >= 0)
+		return;
+
+	sn_pdev = (struct pcidev_info *)sn_irq_info->irq_pciioinfo;
+	pdev = sn_pdev->pdi_linux_pcidev;
+	provider = SN_PCIDEV_BUSPROVIDER(pdev);
+
+	(*provider->dma_unmap)(pdev,
+			       sn_msi_info[vector].pci_addr,
+			       PCI_DMA_FROMDEVICE);
+	sn_msi_info[vector].pci_addr = 0;
+
+	bussoft = SN_PCIDEV_BUSSOFT(pdev);
+	nasid = NASID_GET(bussoft->bs_base);
+	widget = (nasid & 1) ?
+			TIO_SWIN_WIDGETNUM(bussoft->bs_base) :
+			SWIN_WIDGETNUM(bussoft->bs_base);
+
+	sn_intr_free(nasid, widget, sn_irq_info);
+	sn_msi_info[vector].sn_irq_info = NULL;
+
+	return;
+}
+
+int
+sn_msi_setup(struct pci_dev *pdev, unsigned int vector,
+	     u32 *addr_hi, u32 *addr_lo, u32 *data)
+{
+	int widget;
+	int status;
+	nasid_t nasid;
+	u64 bus_addr;
+	struct sn_irq_info *sn_irq_info;
+	struct pcibus_bussoft *bussoft = SN_PCIDEV_BUSSOFT(pdev);
+	struct sn_pcibus_provider *provider = SN_PCIDEV_BUSPROVIDER(pdev);
+
+	if (bussoft == NULL)
+		return -EINVAL;
+
+	if (provider == NULL || provider->dma_map_consistent == NULL)
+		return -EINVAL;
+
+	/*
+	 * Set up the vector plumbing.  Let the prom (via sn_intr_alloc)
+	 * decide which cpu to direct this msi at by default.
+	 */
+
+	nasid = NASID_GET(bussoft->bs_base);
+	widget = (nasid & 1) ?
+			TIO_SWIN_WIDGETNUM(bussoft->bs_base) :
+			SWIN_WIDGETNUM(bussoft->bs_base);
+
+	sn_irq_info = kzalloc(sizeof(struct sn_irq_info), GFP_KERNEL);
+	if (! sn_irq_info)
+		return -ENOMEM;
+
+	status = sn_intr_alloc(nasid, widget, sn_irq_info, vector, -1, -1);
+	if (status) {
+		kfree(sn_irq_info);
+		return -ENOMEM;
+	}
+
+	sn_irq_info->irq_int_bit = -1;		/* mark this as an MSI irq */
+	sn_irq_fixup(pdev, sn_irq_info);
+
+	/* Prom probably should fill these in, but doesn't ... */
+	sn_irq_info->irq_bridge_type = bussoft->bs_asic_type;
+	sn_irq_info->irq_bridge = (void *)bussoft->bs_base;
+
+	/*
+	 * Map the xio address into bus space
+	 */
+	bus_addr = (*provider->dma_map_consistent)(pdev,
+					sn_irq_info->irq_xtalkaddr,
+					sizeof(sn_irq_info->irq_xtalkaddr),
+					SN_DMA_MSI|SN_DMA_ADDR_XIO);
+	if (! bus_addr) {
+		sn_intr_free(nasid, widget, sn_irq_info);
+		kfree(sn_irq_info);
+		return -ENOMEM;
+	}
+
+	sn_msi_info[vector].sn_irq_info = sn_irq_info;
+	sn_msi_info[vector].pci_addr = bus_addr;
+
+	*addr_hi = (u32)(bus_addr >> 32);
+	*addr_lo = (u32)(bus_addr & 0x00000000ffffffff);
+
+	/*
+	 * In the SN platform, bit 16 is a "send vector" bit which
+	 * must be present in order to move the vector through the system.
+	 */
+	*data = 0x100 + (unsigned int)vector;
+
+#ifdef CONFIG_SMP
+	set_irq_affinity_info((vector & 0xff), sn_irq_info->irq_cpuid, 0);
+#endif
+
+	return 0;
+}
+
+static void
+sn_msi_target(unsigned int vector, unsigned int cpu,
+	      u32 *addr_hi, u32 *addr_lo)
+{
+	int slice;
+	nasid_t nasid;
+	u64 bus_addr;
+	struct pci_dev *pdev;
+	struct pcidev_info *sn_pdev;
+	struct sn_irq_info *sn_irq_info;
+	struct sn_irq_info *new_irq_info;
+	struct sn_pcibus_provider *provider;
+
+	sn_irq_info = sn_msi_info[vector].sn_irq_info;
+	if (sn_irq_info == NULL || sn_irq_info->irq_int_bit >= 0)
+		return;
+
+	/*
+	 * Release XIO resources for the old MSI PCI address
+	 */
+
+        sn_pdev = (struct pcidev_info *)sn_irq_info->irq_pciioinfo;
+	pdev = sn_pdev->pdi_linux_pcidev;
+	provider = SN_PCIDEV_BUSPROVIDER(pdev);
+
+	bus_addr = (u64)(*addr_hi) << 32 | (u64)(*addr_lo);
+	(*provider->dma_unmap)(pdev, bus_addr, PCI_DMA_FROMDEVICE);
+	sn_msi_info[vector].pci_addr = 0;
+
+	nasid = cpuid_to_nasid(cpu);
+	slice = cpuid_to_slice(cpu);
+
+	new_irq_info = sn_retarget_vector(sn_irq_info, nasid, slice);
+	sn_msi_info[vector].sn_irq_info = new_irq_info;
+	if (new_irq_info == NULL)
+		return;
+
+	/*
+	 * Map the xio address into bus space
+	 */
+
+	bus_addr = (*provider->dma_map_consistent)(pdev,
+					new_irq_info->irq_xtalkaddr,
+					sizeof(new_irq_info->irq_xtalkaddr),
+					SN_DMA_MSI|SN_DMA_ADDR_XIO);
+
+	sn_msi_info[vector].pci_addr = bus_addr;
+	*addr_hi = (u32)(bus_addr >> 32);
+	*addr_lo = (u32)(bus_addr & 0x00000000ffffffff);
+}
+
+struct msi_ops sn_msi_ops = {
+	.setup = sn_msi_setup,
+	.teardown = sn_msi_teardown,
+#ifdef CONFIG_SMP
+	.target = sn_msi_target,
+#endif
+};
+
+int
+sn_msi_init(void)
+{
+	sn_msi_info =
+		kzalloc(sizeof(struct sn_msi_info) * NR_VECTORS, GFP_KERNEL);
+	if (! sn_msi_info)
+		return -ENOMEM;
+
+	msi_register(&sn_msi_ops);
+	return 0;
+}
diff --git a/drivers/pci/msi-apic.c b/drivers/pci/msi-apic.c
new file mode 100644
index 000000000..5ed798b31
--- /dev/null
+++ b/drivers/pci/msi-apic.c
@@ -0,0 +1,101 @@
+/*
+ * MSI hooks for standard x86 apic
+ */
+
+#include <linux/pci.h>
+#include <linux/irq.h>
+#include <asm/smp.h>
+
+#include "msi.h"
+
+/*
+ * Shifts for APIC-based data
+ */
+
+#define MSI_DATA_VECTOR_SHIFT		0
+#define	    MSI_DATA_VECTOR(v)		(((u8)v) << MSI_DATA_VECTOR_SHIFT)
+
+#define MSI_DATA_DELIVERY_SHIFT		8
+#define     MSI_DATA_DELIVERY_FIXED	(0 << MSI_DATA_DELIVERY_SHIFT)
+#define     MSI_DATA_DELIVERY_LOWPRI	(1 << MSI_DATA_DELIVERY_SHIFT)
+
+#define MSI_DATA_LEVEL_SHIFT		14
+#define     MSI_DATA_LEVEL_DEASSERT	(0 << MSI_DATA_LEVEL_SHIFT)
+#define     MSI_DATA_LEVEL_ASSERT	(1 << MSI_DATA_LEVEL_SHIFT)
+
+#define MSI_DATA_TRIGGER_SHIFT		15
+#define     MSI_DATA_TRIGGER_EDGE	(0 << MSI_DATA_TRIGGER_SHIFT)
+#define     MSI_DATA_TRIGGER_LEVEL	(1 << MSI_DATA_TRIGGER_SHIFT)
+
+/*
+ * Shift/mask fields for APIC-based bus address
+ */
+
+#define MSI_ADDR_HEADER			0xfee00000
+
+#define MSI_ADDR_DESTID_MASK		0xfff0000f
+#define     MSI_ADDR_DESTID_CPU(cpu)	((cpu) << MSI_TARGET_CPU_SHIFT)
+
+#define MSI_ADDR_DESTMODE_SHIFT		2
+#define     MSI_ADDR_DESTMODE_PHYS	(0 << MSI_ADDR_DESTMODE_SHIFT)
+#define	    MSI_ADDR_DESTMODE_LOGIC	(1 << MSI_ADDR_DESTMODE_SHIFT)
+
+#define MSI_ADDR_REDIRECTION_SHIFT	3
+#define     MSI_ADDR_REDIRECTION_CPU	(0 << MSI_ADDR_REDIRECTION_SHIFT)
+#define     MSI_ADDR_REDIRECTION_LOWPRI	(1 << MSI_ADDR_REDIRECTION_SHIFT)
+
+
+static void
+msi_target_apic(unsigned int vector,
+		unsigned int dest_cpu,
+		u32 *address_hi,	/* in/out */
+		u32 *address_lo)	/* in/out */
+{
+	u32 addr = *address_lo;
+
+	addr &= MSI_ADDR_DESTID_MASK;
+	addr |= MSI_ADDR_DESTID_CPU(cpu_physical_id(dest_cpu));
+
+	*address_lo = addr;
+}
+
+static int
+msi_setup_apic(struct pci_dev *pdev,	/* unused in generic */
+		unsigned int vector,
+		u32 *address_hi,
+		u32 *address_lo,
+		u32 *data)
+{
+	unsigned long	dest_phys_id;
+
+	dest_phys_id = cpu_physical_id(first_cpu(cpu_online_map));
+
+	*address_hi = 0;
+	*address_lo =	MSI_ADDR_HEADER |
+			MSI_ADDR_DESTMODE_PHYS |
+			MSI_ADDR_REDIRECTION_CPU |
+			MSI_ADDR_DESTID_CPU(dest_phys_id);
+
+	*data = MSI_DATA_TRIGGER_EDGE |
+		MSI_DATA_LEVEL_ASSERT |
+		MSI_DATA_DELIVERY_FIXED |
+		MSI_DATA_VECTOR(vector);
+
+	return 0;
+}
+
+static void
+msi_teardown_apic(unsigned int vector)
+{
+	return;		/* no-op */
+}
+
+/*
+ * Generic ops used on most IA archs/platforms.  Set with msi_register()
+ */
+
+struct msi_ops msi_apic_ops = {
+	.setup = msi_setup_apic,
+	.teardown = msi_teardown_apic,
+	.target = msi_target_apic,
+};
diff --git a/drivers/rtc/rtc-at91.c b/drivers/rtc/rtc-at91.c
new file mode 100644
index 000000000..dfd0ce86f
--- /dev/null
+++ b/drivers/rtc/rtc-at91.c
@@ -0,0 +1,407 @@
+/*
+ *	Real Time Clock interface for Linux on Atmel AT91RM9200
+ *
+ *	Copyright (C) 2002 Rick Bronson
+ *
+ *	Converted to RTC class model by Andrew Victor
+ *
+ *	Ported to Linux 2.6 by Steven Scholz
+ *	Based on s3c2410-rtc.c Simtec Electronics
+ *
+ *	Based on sa1100-rtc.c by Nils Faerber
+ *	Based on rtc.c by Paul Gortmaker
+ *
+ *	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 <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/time.h>
+#include <linux/rtc.h>
+#include <linux/bcd.h>
+#include <linux/interrupt.h>
+#include <linux/ioctl.h>
+#include <linux/completion.h>
+
+#include <asm/uaccess.h>
+#include <asm/rtc.h>
+
+#include <asm/mach/time.h>
+
+
+#define AT91_RTC_FREQ		1
+#define AT91_RTC_EPOCH		1900UL	/* just like arch/arm/common/rtctime.c */
+
+static DECLARE_COMPLETION(at91_rtc_updated);
+static unsigned int at91_alarm_year = AT91_RTC_EPOCH;
+
+/*
+ * Decode time/date into rtc_time structure
+ */
+static void at91_rtc_decodetime(unsigned int timereg, unsigned int calreg,
+				struct rtc_time *tm)
+{
+	unsigned int time, date;
+
+	/* must read twice in case it changes */
+	do {
+		time = at91_sys_read(timereg);
+		date = at91_sys_read(calreg);
+	} while ((time != at91_sys_read(timereg)) ||
+			(date != at91_sys_read(calreg)));
+
+	tm->tm_sec  = BCD2BIN((time & AT91_RTC_SEC) >> 0);
+	tm->tm_min  = BCD2BIN((time & AT91_RTC_MIN) >> 8);
+	tm->tm_hour = BCD2BIN((time & AT91_RTC_HOUR) >> 16);
+
+	/*
+	 * The Calendar Alarm register does not have a field for
+	 * the year - so these will return an invalid value.  When an
+	 * alarm is set, at91_alarm_year wille store the current year.
+	 */
+	tm->tm_year  = BCD2BIN(date & AT91_RTC_CENT) * 100;	/* century */
+	tm->tm_year += BCD2BIN((date & AT91_RTC_YEAR) >> 8);	/* year */
+
+	tm->tm_wday = BCD2BIN((date & AT91_RTC_DAY) >> 21) - 1;	/* day of the week [0-6], Sunday=0 */
+	tm->tm_mon  = BCD2BIN((date & AT91_RTC_MONTH) >> 16) - 1;
+	tm->tm_mday = BCD2BIN((date & AT91_RTC_DATE) >> 24);
+}
+
+/*
+ * Read current time and date in RTC
+ */
+static int at91_rtc_readtime(struct device *dev, struct rtc_time *tm)
+{
+	at91_rtc_decodetime(AT91_RTC_TIMR, AT91_RTC_CALR, tm);
+	tm->tm_yday = rtc_year_days(tm->tm_mday, tm->tm_mon, tm->tm_year);
+	tm->tm_year = tm->tm_year - 1900;
+
+	pr_debug("%s(): %4d-%02d-%02d %02d:%02d:%02d\n", __FUNCTION__,
+		1900 + tm->tm_year, tm->tm_mon, tm->tm_mday,
+		tm->tm_hour, tm->tm_min, tm->tm_sec);
+
+	return 0;
+}
+
+/*
+ * Set current time and date in RTC
+ */
+static int at91_rtc_settime(struct device *dev, struct rtc_time *tm)
+{
+	unsigned long cr;
+
+	pr_debug("%s(): %4d-%02d-%02d %02d:%02d:%02d\n", __FUNCTION__,
+		1900 + tm->tm_year, tm->tm_mon, tm->tm_mday,
+		tm->tm_hour, tm->tm_min, tm->tm_sec);
+
+	/* Stop Time/Calendar from counting */
+	cr = at91_sys_read(AT91_RTC_CR);
+	at91_sys_write(AT91_RTC_CR, cr | AT91_RTC_UPDCAL | AT91_RTC_UPDTIM);
+
+	at91_sys_write(AT91_RTC_IER, AT91_RTC_ACKUPD);
+	wait_for_completion(&at91_rtc_updated);	/* wait for ACKUPD interrupt */
+	at91_sys_write(AT91_RTC_IDR, AT91_RTC_ACKUPD);
+
+	at91_sys_write(AT91_RTC_TIMR,
+			  BIN2BCD(tm->tm_sec) << 0
+			| BIN2BCD(tm->tm_min) << 8
+			| BIN2BCD(tm->tm_hour) << 16);
+
+	at91_sys_write(AT91_RTC_CALR,
+			  BIN2BCD((tm->tm_year + 1900) / 100)	/* century */
+			| BIN2BCD(tm->tm_year % 100) << 8	/* year */
+			| BIN2BCD(tm->tm_mon + 1) << 16		/* tm_mon starts at zero */
+			| BIN2BCD(tm->tm_wday + 1) << 21	/* day of the week [0-6], Sunday=0 */
+			| BIN2BCD(tm->tm_mday) << 24);
+
+	/* Restart Time/Calendar */
+	cr = at91_sys_read(AT91_RTC_CR);
+	at91_sys_write(AT91_RTC_CR, cr & ~(AT91_RTC_UPDCAL | AT91_RTC_UPDTIM));
+
+	return 0;
+}
+
+/*
+ * Read alarm time and date in RTC
+ */
+static int at91_rtc_readalarm(struct device *dev, struct rtc_wkalrm *alrm)
+{
+	struct rtc_time *tm = &alrm->time;
+
+	at91_rtc_decodetime(AT91_RTC_TIMALR, AT91_RTC_CALALR, tm);
+	tm->tm_yday = rtc_year_days(tm->tm_mday, tm->tm_mon, tm->tm_year);
+	tm->tm_year = at91_alarm_year - 1900;
+
+	pr_debug("%s(): %4d-%02d-%02d %02d:%02d:%02d\n", __FUNCTION__,
+		1900 + tm->tm_year, tm->tm_mon, tm->tm_mday,
+		tm->tm_hour, tm->tm_min, tm->tm_sec);
+
+	return 0;
+}
+
+/*
+ * Set alarm time and date in RTC
+ */
+static int at91_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm)
+{
+	struct rtc_time tm;
+
+	at91_rtc_decodetime(AT91_RTC_TIMR, AT91_RTC_CALR, &tm);
+
+	at91_alarm_year = tm.tm_year;
+
+	tm.tm_hour = alrm->time.tm_hour;
+	tm.tm_min = alrm->time.tm_min;
+	tm.tm_sec = alrm->time.tm_sec;
+
+	at91_sys_write(AT91_RTC_TIMALR,
+		  BIN2BCD(tm.tm_sec) << 0
+		| BIN2BCD(tm.tm_min) << 8
+		| BIN2BCD(tm.tm_hour) << 16
+		| AT91_RTC_HOUREN | AT91_RTC_MINEN | AT91_RTC_SECEN);
+	at91_sys_write(AT91_RTC_CALALR,
+		  BIN2BCD(tm.tm_mon + 1) << 16		/* tm_mon starts at zero */
+		| BIN2BCD(tm.tm_mday) << 24
+		| AT91_RTC_DATEEN | AT91_RTC_MTHEN);
+
+	pr_debug("%s(): %4d-%02d-%02d %02d:%02d:%02d\n", __FUNCTION__,
+		at91_alarm_year, tm.tm_mon, tm.tm_mday, tm.tm_hour,
+		tm.tm_min, tm.tm_sec);
+
+	return 0;
+}
+
+/*
+ * Handle commands from user-space
+ */
+static int at91_rtc_ioctl(struct device *dev, unsigned int cmd,
+			unsigned long arg)
+{
+	int ret = 0;
+
+	pr_debug("%s(): cmd=%08x, arg=%08lx.\n", __FUNCTION__, cmd, arg);
+
+	switch (cmd) {
+	case RTC_AIE_OFF:	/* alarm off */
+		at91_sys_write(AT91_RTC_IDR, AT91_RTC_ALARM);
+		break;
+	case RTC_AIE_ON:	/* alarm on */
+		at91_sys_write(AT91_RTC_IER, AT91_RTC_ALARM);
+		break;
+	case RTC_UIE_OFF:	/* update off */
+	case RTC_PIE_OFF:	/* periodic off */
+		at91_sys_write(AT91_RTC_IDR, AT91_RTC_SECEV);
+		break;
+	case RTC_UIE_ON:	/* update on */
+	case RTC_PIE_ON:	/* periodic on */
+		at91_sys_write(AT91_RTC_IER, AT91_RTC_SECEV);
+		break;
+	case RTC_IRQP_READ:	/* read periodic alarm frequency */
+		ret = put_user(AT91_RTC_FREQ, (unsigned long *) arg);
+		break;
+	case RTC_IRQP_SET:	/* set periodic alarm frequency */
+		if (arg != AT91_RTC_FREQ)
+			ret = -EINVAL;
+		break;
+	default:
+		ret = -ENOIOCTLCMD;
+		break;
+	}
+
+	return ret;
+}
+
+/*
+ * Provide additional RTC information in /proc/driver/rtc
+ */
+static int at91_rtc_proc(struct device *dev, struct seq_file *seq)
+{
+	unsigned long imr = at91_sys_read(AT91_RTC_IMR);
+
+	seq_printf(seq, "alarm_IRQ\t: %s\n",
+			(imr & AT91_RTC_ALARM) ? "yes" : "no");
+	seq_printf(seq, "update_IRQ\t: %s\n",
+			(imr & AT91_RTC_ACKUPD) ? "yes" : "no");
+	seq_printf(seq, "periodic_IRQ\t: %s\n",
+			(imr & AT91_RTC_SECEV) ? "yes" : "no");
+	seq_printf(seq, "periodic_freq\t: %ld\n",
+			(unsigned long) AT91_RTC_FREQ);
+
+	return 0;
+}
+
+/*
+ * IRQ handler for the RTC
+ */
+static irqreturn_t at91_rtc_interrupt(int irq, void *dev_id,
+					struct pt_regs *regs)
+{
+	struct platform_device *pdev = dev_id;
+	struct rtc_device *rtc = platform_get_drvdata(pdev);
+	unsigned int rtsr;
+	unsigned long events = 0;
+
+	rtsr = at91_sys_read(AT91_RTC_SR) & at91_sys_read(AT91_RTC_IMR);
+	if (rtsr) {		/* this interrupt is shared!  Is it ours? */
+		if (rtsr & AT91_RTC_ALARM)
+			events |= (RTC_AF | RTC_IRQF);
+		if (rtsr & AT91_RTC_SECEV)
+			events |= (RTC_UF | RTC_IRQF);
+		if (rtsr & AT91_RTC_ACKUPD)
+			complete(&at91_rtc_updated);
+
+		at91_sys_write(AT91_RTC_SCCR, rtsr);	/* clear status reg */
+
+		rtc_update_irq(&rtc->class_dev, 1, events);
+
+		pr_debug("%s(): num=%ld, events=0x%02lx\n", __FUNCTION__,
+			events >> 8, events & 0x000000FF);
+
+		return IRQ_HANDLED;
+	}
+	return IRQ_NONE;		/* not handled */
+}
+
+static struct rtc_class_ops at91_rtc_ops = {
+	.ioctl		= at91_rtc_ioctl,
+	.read_time	= at91_rtc_readtime,
+	.set_time	= at91_rtc_settime,
+	.read_alarm	= at91_rtc_readalarm,
+	.set_alarm	= at91_rtc_setalarm,
+	.proc		= at91_rtc_proc,
+};
+
+/*
+ * Initialize and install RTC driver
+ */
+static int __init at91_rtc_probe(struct platform_device *pdev)
+{
+	struct rtc_device *rtc;
+	int ret;
+
+	at91_sys_write(AT91_RTC_CR, 0);
+	at91_sys_write(AT91_RTC_MR, 0);		/* 24 hour mode */
+
+	/* Disable all interrupts */
+	at91_sys_write(AT91_RTC_IDR, AT91_RTC_ACKUPD | AT91_RTC_ALARM |
+					AT91_RTC_SECEV | AT91_RTC_TIMEV |
+					AT91_RTC_CALEV);
+
+	ret = request_irq(AT91_ID_SYS, at91_rtc_interrupt,
+				IRQF_SHARED, "at91_rtc", pdev);
+	if (ret) {
+		printk(KERN_ERR "at91_rtc: IRQ %d already in use.\n",
+				AT91_ID_SYS);
+		return ret;
+	}
+
+	rtc = rtc_device_register(pdev->name, &pdev->dev,
+				&at91_rtc_ops, THIS_MODULE);
+	if (IS_ERR(rtc)) {
+		free_irq(AT91_ID_SYS, pdev);
+		return PTR_ERR(rtc);
+	}
+	platform_set_drvdata(pdev, rtc);
+
+	printk(KERN_INFO "AT91 Real Time Clock driver.\n");
+	return 0;
+}
+
+/*
+ * Disable and remove the RTC driver
+ */
+static int __devexit at91_rtc_remove(struct platform_device *pdev)
+{
+	struct rtc_device *rtc = platform_get_drvdata(pdev);
+
+	/* Disable all interrupts */
+	at91_sys_write(AT91_RTC_IDR, AT91_RTC_ACKUPD | AT91_RTC_ALARM |
+					AT91_RTC_SECEV | AT91_RTC_TIMEV |
+					AT91_RTC_CALEV);
+	free_irq(AT91_ID_SYS, pdev);
+
+	rtc_device_unregister(rtc);
+	platform_set_drvdata(pdev, NULL);
+
+	return 0;
+}
+
+#ifdef CONFIG_PM
+
+/* AT91RM9200 RTC Power management control */
+
+static struct timespec at91_rtc_delta;
+
+static int at91_rtc_suspend(struct platform_device *pdev, pm_message_t state)
+{
+	struct rtc_time tm;
+	struct timespec time;
+
+	time.tv_nsec = 0;
+
+	/* calculate time delta for suspend */
+	at91_rtc_readtime(&pdev->dev, &tm);
+	rtc_tm_to_time(&tm, &time.tv_sec);
+	save_time_delta(&at91_rtc_delta, &time);
+
+	pr_debug("%s(): %4d-%02d-%02d %02d:%02d:%02d\n", __FUNCTION__,
+		1900 + tm.tm_year, tm.tm_mon, tm.tm_mday,
+		tm.tm_hour, tm.tm_min, tm.tm_sec);
+
+	return 0;
+}
+
+static int at91_rtc_resume(struct platform_device *pdev)
+{
+	struct rtc_time tm;
+	struct timespec time;
+
+	time.tv_nsec = 0;
+
+	at91_rtc_readtime(&pdev->dev, &tm);
+	rtc_tm_to_time(&tm, &time.tv_sec);
+	restore_time_delta(&at91_rtc_delta, &time);
+
+	pr_debug("%s(): %4d-%02d-%02d %02d:%02d:%02d\n", __FUNCTION__,
+		1900 + tm.tm_year, tm.tm_mon, tm.tm_mday,
+		tm.tm_hour, tm.tm_min, tm.tm_sec);
+
+	return 0;
+}
+#else
+#define at91_rtc_suspend NULL
+#define at91_rtc_resume  NULL
+#endif
+
+static struct platform_driver at91_rtc_driver = {
+	.probe		= at91_rtc_probe,
+	.remove		= at91_rtc_remove,
+	.suspend	= at91_rtc_suspend,
+	.resume		= at91_rtc_resume,
+	.driver		= {
+		.name	= "at91_rtc",
+		.owner	= THIS_MODULE,
+	},
+};
+
+static int __init at91_rtc_init(void)
+{
+	return platform_driver_register(&at91_rtc_driver);
+}
+
+static void __exit at91_rtc_exit(void)
+{
+	platform_driver_unregister(&at91_rtc_driver);
+}
+
+module_init(at91_rtc_init);
+module_exit(at91_rtc_exit);
+
+MODULE_AUTHOR("Rick Bronson");
+MODULE_DESCRIPTION("RTC driver for Atmel AT91RM9200");
+MODULE_LICENSE("GPL");
diff --git a/drivers/rtc/rtc-ds1307.c b/drivers/rtc/rtc-ds1307.c
new file mode 100644
index 000000000..e8afb9384
--- /dev/null
+++ b/drivers/rtc/rtc-ds1307.c
@@ -0,0 +1,388 @@
+/*
+ * rtc-ds1307.c - RTC driver for some mostly-compatible I2C chips.
+ *
+ *  Copyright (C) 2005 James Chapman (ds1337 core)
+ *  Copyright (C) 2006 David Brownell
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/i2c.h>
+#include <linux/string.h>
+#include <linux/rtc.h>
+#include <linux/bcd.h>
+
+
+
+/* We can't determine type by probing, but if we expect pre-Linux code
+ * to have set the chip up as a clock (turning on the oscillator and
+ * setting the date and time), Linux can ignore the non-clock features.
+ * That's a natural job for a factory or repair bench.
+ *
+ * If the I2C "force" mechanism is used, we assume the chip is a ds1337.
+ * (Much better would be board-specific tables of I2C devices, along with
+ * the platform_data drivers would use to sort such issues out.)
+ */
+enum ds_type {
+	unknown = 0,
+	ds_1307,		/* or ds1338, ... */
+	ds_1337,		/* or ds1339, ... */
+	ds_1340,		/* or st m41t00, ... */
+	// rs5c372 too?  different address...
+};
+
+static unsigned short normal_i2c[] = { 0x68, I2C_CLIENT_END };
+
+I2C_CLIENT_INSMOD;
+
+
+
+/* RTC registers don't differ much, except for the century flag */
+#define DS1307_REG_SECS		0x00	/* 00-59 */
+#	define DS1307_BIT_CH		0x80
+#define DS1307_REG_MIN		0x01	/* 00-59 */
+#define DS1307_REG_HOUR		0x02	/* 00-23, or 1-12{am,pm} */
+#	define DS1340_BIT_CENTURY_EN	0x80	/* in REG_HOUR */
+#	define DS1340_BIT_CENTURY	0x40	/* in REG_HOUR */
+#define DS1307_REG_WDAY		0x03	/* 01-07 */
+#define DS1307_REG_MDAY		0x04	/* 01-31 */
+#define DS1307_REG_MONTH	0x05	/* 01-12 */
+#	define DS1337_BIT_CENTURY	0x80	/* in REG_MONTH */
+#define DS1307_REG_YEAR		0x06	/* 00-99 */
+
+/* Other registers (control, status, alarms, trickle charge, NVRAM, etc)
+ * start at 7, and they differ a lot. Only control and status matter for RTC;
+ * be careful using them.
+ */
+#define DS1307_REG_CONTROL	0x07
+#	define DS1307_BIT_OUT		0x80
+#	define DS1307_BIT_SQWE		0x10
+#	define DS1307_BIT_RS1		0x02
+#	define DS1307_BIT_RS0		0x01
+#define DS1337_REG_CONTROL	0x0e
+#	define DS1337_BIT_nEOSC		0x80
+#	define DS1337_BIT_RS2		0x10
+#	define DS1337_BIT_RS1		0x08
+#	define DS1337_BIT_INTCN		0x04
+#	define DS1337_BIT_A2IE		0x02
+#	define DS1337_BIT_A1IE		0x01
+#define DS1337_REG_STATUS	0x0f
+#	define DS1337_BIT_OSF		0x80
+#	define DS1337_BIT_A2I		0x02
+#	define DS1337_BIT_A1I		0x01
+#define DS1339_REG_TRICKLE	0x10
+
+
+
+struct ds1307 {
+	u8			reg_addr;
+	u8			regs[8];
+	enum ds_type		type;
+	struct i2c_msg		msg[2];
+	struct i2c_client	client;
+	struct rtc_device	*rtc;
+};
+
+
+static int ds1307_get_time(struct device *dev, struct rtc_time *t)
+{
+	struct ds1307	*ds1307 = dev_get_drvdata(dev);
+	int		tmp;
+
+	/* read the RTC registers all at once */
+	ds1307->msg[1].flags = I2C_M_RD;
+	ds1307->msg[1].len = 7;
+
+	tmp = i2c_transfer(ds1307->client.adapter, ds1307->msg, 2);
+	if (tmp != 2) {
+		dev_err(dev, "%s error %d\n", "read", tmp);
+		return -EIO;
+	}
+
+	dev_dbg(dev, "%s: %02x %02x %02x %02x %02x %02x %02x\n",
+			"read",
+			ds1307->regs[0], ds1307->regs[1],
+			ds1307->regs[2], ds1307->regs[3],
+			ds1307->regs[4], ds1307->regs[5],
+			ds1307->regs[6]);
+
+	t->tm_sec = BCD2BIN(ds1307->regs[DS1307_REG_SECS] & 0x7f);
+	t->tm_min = BCD2BIN(ds1307->regs[DS1307_REG_MIN] & 0x7f);
+	tmp = ds1307->regs[DS1307_REG_HOUR] & 0x3f;
+	t->tm_hour = BCD2BIN(tmp);
+	t->tm_wday = BCD2BIN(ds1307->regs[DS1307_REG_WDAY] & 0x07) - 1;
+	t->tm_mday = BCD2BIN(ds1307->regs[DS1307_REG_MDAY] & 0x3f);
+	tmp = ds1307->regs[DS1307_REG_MONTH] & 0x1f;
+	t->tm_mon = BCD2BIN(tmp) - 1;
+
+	/* assume 20YY not 19YY, and ignore DS1337_BIT_CENTURY */
+	t->tm_year = BCD2BIN(ds1307->regs[DS1307_REG_YEAR]) + 100;
+
+	dev_dbg(dev, "%s secs=%d, mins=%d, "
+		"hours=%d, mday=%d, mon=%d, year=%d, wday=%d\n",
+		"read", t->tm_sec, t->tm_min,
+		t->tm_hour, t->tm_mday,
+		t->tm_mon, t->tm_year, t->tm_wday);
+
+	return 0;
+}
+
+static int ds1307_set_time(struct device *dev, struct rtc_time *t)
+{
+	struct ds1307	*ds1307 = dev_get_drvdata(dev);
+	int		result;
+	int		tmp;
+	u8		*buf = ds1307->regs;
+
+	dev_dbg(dev, "%s secs=%d, mins=%d, "
+		"hours=%d, mday=%d, mon=%d, year=%d, wday=%d\n",
+		"write", dt->tm_sec, dt->tm_min,
+		dt->tm_hour, dt->tm_mday,
+		dt->tm_mon, dt->tm_year, dt->tm_wday);
+
+	*buf++ = 0;		/* first register addr */
+	buf[DS1307_REG_SECS] = BIN2BCD(t->tm_sec);
+	buf[DS1307_REG_MIN] = BIN2BCD(t->tm_min);
+	buf[DS1307_REG_HOUR] = BIN2BCD(t->tm_hour);
+	buf[DS1307_REG_WDAY] = BIN2BCD(t->tm_wday + 1);
+	buf[DS1307_REG_MDAY] = BIN2BCD(t->tm_mday);
+	buf[DS1307_REG_MONTH] = BIN2BCD(t->tm_mon + 1);
+
+	/* assume 20YY not 19YY */
+	tmp = t->tm_year - 100;
+	buf[DS1307_REG_YEAR] = BIN2BCD(tmp);
+
+	if (ds1307->type == ds_1337)
+		buf[DS1307_REG_MONTH] |= DS1337_BIT_CENTURY;
+	else if (ds1307->type == ds_1340)
+		buf[DS1307_REG_HOUR] |= DS1340_BIT_CENTURY_EN
+				| DS1340_BIT_CENTURY;
+
+	ds1307->msg[1].flags = 0;
+	ds1307->msg[1].len = 8;
+
+	dev_dbg(dev, "%s: %02x %02x %02x %02x %02x %02x %02x\n",
+		"write", buf[0], buf[1], buf[2], buf[3],
+		buf[4], buf[5], buf[6]);
+
+	result = i2c_transfer(ds1307->client.adapter, &ds1307->msg[1], 1);
+	if (result != 1) {
+		dev_err(dev, "%s error %d\n", "write", tmp);
+		return -EIO;
+	}
+	return 0;
+}
+
+static struct rtc_class_ops ds13xx_rtc_ops = {
+	.read_time	= ds1307_get_time,
+	.set_time	= ds1307_set_time,
+};
+
+static struct i2c_driver ds1307_driver;
+
+static int __devinit
+ds1307_detect(struct i2c_adapter *adapter, int address, int kind)
+{
+	struct ds1307		*ds1307;
+	int			err = -ENODEV;
+	struct i2c_client	*client;
+	int			tmp;
+
+	if (!(ds1307 = kzalloc(sizeof(struct ds1307), GFP_KERNEL))) {
+		err = -ENOMEM;
+		goto exit;
+	}
+
+	client = &ds1307->client;
+	client->addr = address;
+	client->adapter = adapter;
+	client->driver = &ds1307_driver;
+	client->flags = 0;
+
+	i2c_set_clientdata(client, ds1307);
+
+	ds1307->msg[0].addr = client->addr;
+	ds1307->msg[0].flags = 0;
+	ds1307->msg[0].len = 1;
+	ds1307->msg[0].buf = &ds1307->reg_addr;
+
+	ds1307->msg[1].addr = client->addr;
+	ds1307->msg[1].flags = I2C_M_RD;
+	ds1307->msg[1].len = sizeof(ds1307->regs);
+	ds1307->msg[1].buf = ds1307->regs;
+
+	/* HACK: "force" implies "needs ds1337-style-oscillator setup" */
+	if (kind >= 0) {
+		ds1307->type = ds_1337;
+
+		ds1307->reg_addr = DS1337_REG_CONTROL;
+		ds1307->msg[1].len = 2;
+
+		tmp = i2c_transfer(client->adapter, ds1307->msg, 2);
+		if (tmp != 2) {
+			pr_debug("read error %d\n", tmp);
+			err = -EIO;
+			goto exit_free;
+		}
+
+		ds1307->reg_addr = 0;
+		ds1307->msg[1].len = sizeof(ds1307->regs);
+
+		/* oscillator is off; need to turn it on */
+		if ((ds1307->regs[0] & DS1337_BIT_nEOSC)
+				|| (ds1307->regs[1] & DS1337_BIT_OSF)) {
+			printk(KERN_ERR "no ds1337 oscillator code\n");
+			goto exit_free;
+		}
+	} else
+		ds1307->type = ds_1307;
+
+read_rtc:
+	/* read RTC registers */
+
+	tmp = i2c_transfer(client->adapter, ds1307->msg, 2);
+	if (tmp != 2) {
+		pr_debug("read error %d\n", tmp);
+		err = -EIO;
+		goto exit_free;
+	}
+
+	/* minimal sanity checking; some chips (like DS1340) don't
+	 * specify the extra bits as must-be-zero, but there are
+	 * still a few values that are clearly out-of-range.
+	 */
+	tmp = ds1307->regs[DS1307_REG_SECS];
+	if (tmp & DS1307_BIT_CH) {
+		if (ds1307->type && ds1307->type != ds_1307) {
+			pr_debug("not a ds1307?\n");
+			goto exit_free;
+		}
+		ds1307->type = ds_1307;
+
+		/* this partial initialization should work for ds1307,
+		 * ds1338, ds1340, st m41t00, and more.
+		 */
+		dev_warn(&client->dev, "oscillator started; SET TIME!\n");
+		i2c_smbus_write_byte_data(client, 0, 0);
+		goto read_rtc;
+	}
+	tmp = BCD2BIN(tmp & 0x7f);
+	if (tmp > 60)
+		goto exit_free;
+	tmp = BCD2BIN(ds1307->regs[DS1307_REG_MIN] & 0x7f);
+	if (tmp > 60)
+		goto exit_free;
+
+	tmp = BCD2BIN(ds1307->regs[DS1307_REG_MDAY] & 0x3f);
+	if (tmp == 0 || tmp > 31)
+		goto exit_free;
+
+	tmp = BCD2BIN(ds1307->regs[DS1307_REG_MONTH] & 0x1f);
+	if (tmp == 0 || tmp > 12)
+		goto exit_free;
+
+	/* force into in 24 hour mode (most chips) or
+	 * disable century bit (ds1340)
+	 */
+	tmp = ds1307->regs[DS1307_REG_HOUR];
+	if (tmp & (1 << 6)) {
+		if (tmp & (1 << 5))
+			tmp = BCD2BIN(tmp & 0x1f) + 12;
+		else
+			tmp = BCD2BIN(tmp);
+		i2c_smbus_write_byte_data(client,
+				DS1307_REG_HOUR,
+				BIN2BCD(tmp));
+	}
+
+	/* FIXME chips like 1337 can generate alarm irqs too; those are
+	 * worth exposing through the API (especially when the irq is
+	 * wakeup-capable).
+	 */
+
+	switch (ds1307->type) {
+	case unknown:
+		strlcpy(client->name, "unknown", I2C_NAME_SIZE);
+		break;
+	case ds_1307:
+		strlcpy(client->name, "ds1307", I2C_NAME_SIZE);
+		break;
+	case ds_1337:
+		strlcpy(client->name, "ds1337", I2C_NAME_SIZE);
+		break;
+	case ds_1340:
+		strlcpy(client->name, "ds1340", I2C_NAME_SIZE);
+		break;
+	}
+
+	/* Tell the I2C layer a new client has arrived */
+	if ((err = i2c_attach_client(client)))
+		goto exit_free;
+
+	ds1307->rtc = rtc_device_register(client->name, &client->dev,
+				&ds13xx_rtc_ops, THIS_MODULE);
+	if (IS_ERR(ds1307->rtc)) {
+		err = PTR_ERR(ds1307->rtc);
+		dev_err(&client->dev,
+			"unable to register the class device\n");
+		goto exit_detach;
+	}
+
+	return 0;
+
+exit_detach:
+	i2c_detach_client(client);
+exit_free:
+	kfree(ds1307);
+exit:
+	return err;
+}
+
+static int __devinit
+ds1307_attach_adapter(struct i2c_adapter *adapter)
+{
+	if (!i2c_check_functionality(adapter, I2C_FUNC_I2C))
+		return 0;
+	return i2c_probe(adapter, &addr_data, ds1307_detect);
+}
+
+static int __devexit ds1307_detach_client(struct i2c_client *client)
+{
+	int		err;
+	struct ds1307	*ds1307 = i2c_get_clientdata(client);
+
+	rtc_device_unregister(ds1307->rtc);
+	if ((err = i2c_detach_client(client)))
+		return err;
+	kfree(ds1307);
+	return 0;
+}
+
+static struct i2c_driver ds1307_driver = {
+	.driver = {
+		.name	= "ds1307",
+		.owner	= THIS_MODULE,
+	},
+	.attach_adapter	= ds1307_attach_adapter,
+	.detach_client	= __devexit_p(ds1307_detach_client),
+};
+
+static int __init ds1307_init(void)
+{
+	return i2c_add_driver(&ds1307_driver);
+}
+module_init(ds1307_init);
+
+static void __exit ds1307_exit(void)
+{
+	i2c_del_driver(&ds1307_driver);
+}
+module_exit(ds1307_exit);
+
+MODULE_DESCRIPTION("RTC driver for DS1307 and similar chips");
+MODULE_LICENSE("GPL");
diff --git a/drivers/rtc/rtc-ds1553.c b/drivers/rtc/rtc-ds1553.c
new file mode 100644
index 000000000..209001495
--- /dev/null
+++ b/drivers/rtc/rtc-ds1553.c
@@ -0,0 +1,414 @@
+/*
+ * An rtc driver for the Dallas DS1553
+ *
+ * Copyright (C) 2006 Atsushi Nemoto <anemo@mba.ocn.ne.jp>
+ *
+ * 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/bcd.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/delay.h>
+#include <linux/jiffies.h>
+#include <linux/interrupt.h>
+#include <linux/rtc.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+
+#define DRV_VERSION "0.1"
+
+#define RTC_REG_SIZE		0x2000
+#define RTC_OFFSET		0x1ff0
+
+#define RTC_FLAGS		(RTC_OFFSET + 0)
+#define RTC_SECONDS_ALARM	(RTC_OFFSET + 2)
+#define RTC_MINUTES_ALARM	(RTC_OFFSET + 3)
+#define RTC_HOURS_ALARM		(RTC_OFFSET + 4)
+#define RTC_DATE_ALARM		(RTC_OFFSET + 5)
+#define RTC_INTERRUPTS		(RTC_OFFSET + 6)
+#define RTC_WATCHDOG		(RTC_OFFSET + 7)
+#define RTC_CONTROL		(RTC_OFFSET + 8)
+#define RTC_CENTURY		(RTC_OFFSET + 8)
+#define RTC_SECONDS		(RTC_OFFSET + 9)
+#define RTC_MINUTES		(RTC_OFFSET + 10)
+#define RTC_HOURS		(RTC_OFFSET + 11)
+#define RTC_DAY			(RTC_OFFSET + 12)
+#define RTC_DATE		(RTC_OFFSET + 13)
+#define RTC_MONTH		(RTC_OFFSET + 14)
+#define RTC_YEAR		(RTC_OFFSET + 15)
+
+#define RTC_CENTURY_MASK	0x3f
+#define RTC_SECONDS_MASK	0x7f
+#define RTC_DAY_MASK		0x07
+
+/* Bits in the Control/Century register */
+#define RTC_WRITE		0x80
+#define RTC_READ		0x40
+
+/* Bits in the Seconds register */
+#define RTC_STOP		0x80
+
+/* Bits in the Flags register */
+#define RTC_FLAGS_AF		0x40
+#define RTC_FLAGS_BLF		0x10
+
+/* Bits in the Interrupts register */
+#define RTC_INTS_AE		0x80
+
+struct rtc_plat_data {
+	struct rtc_device *rtc;
+	void __iomem *ioaddr;
+	unsigned long baseaddr;
+	unsigned long last_jiffies;
+	int irq;
+	unsigned int irqen;
+	int alrm_sec;
+	int alrm_min;
+	int alrm_hour;
+	int alrm_mday;
+};
+
+static int ds1553_rtc_set_time(struct device *dev, struct rtc_time *tm)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
+	void __iomem *ioaddr = pdata->ioaddr;
+	u8 century;
+
+	century = BIN2BCD((tm->tm_year + 1900) / 100);
+
+	writeb(RTC_WRITE, pdata->ioaddr + RTC_CONTROL);
+
+	writeb(BIN2BCD(tm->tm_year % 100), ioaddr + RTC_YEAR);
+	writeb(BIN2BCD(tm->tm_mon + 1), ioaddr + RTC_MONTH);
+	writeb(BIN2BCD(tm->tm_wday) & RTC_DAY_MASK, ioaddr + RTC_DAY);
+	writeb(BIN2BCD(tm->tm_mday), ioaddr + RTC_DATE);
+	writeb(BIN2BCD(tm->tm_hour), ioaddr + RTC_HOURS);
+	writeb(BIN2BCD(tm->tm_min), ioaddr + RTC_MINUTES);
+	writeb(BIN2BCD(tm->tm_sec) & RTC_SECONDS_MASK, ioaddr + RTC_SECONDS);
+
+	/* RTC_CENTURY and RTC_CONTROL share same register */
+	writeb(RTC_WRITE | (century & RTC_CENTURY_MASK), ioaddr + RTC_CENTURY);
+	writeb(century & RTC_CENTURY_MASK, ioaddr + RTC_CONTROL);
+	return 0;
+}
+
+static int ds1553_rtc_read_time(struct device *dev, struct rtc_time *tm)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
+	void __iomem *ioaddr = pdata->ioaddr;
+	unsigned int year, month, day, hour, minute, second, week;
+	unsigned int century;
+
+	/* give enough time to update RTC in case of continuous read */
+	if (pdata->last_jiffies == jiffies)
+		msleep(1);
+	pdata->last_jiffies = jiffies;
+	writeb(RTC_READ, ioaddr + RTC_CONTROL);
+	second = readb(ioaddr + RTC_SECONDS) & RTC_SECONDS_MASK;
+	minute = readb(ioaddr + RTC_MINUTES);
+	hour = readb(ioaddr + RTC_HOURS);
+	day = readb(ioaddr + RTC_DATE);
+	week = readb(ioaddr + RTC_DAY) & RTC_DAY_MASK;
+	month = readb(ioaddr + RTC_MONTH);
+	year = readb(ioaddr + RTC_YEAR);
+	century = readb(ioaddr + RTC_CENTURY) & RTC_CENTURY_MASK;
+	writeb(0, ioaddr + RTC_CONTROL);
+	tm->tm_sec = BCD2BIN(second);
+	tm->tm_min = BCD2BIN(minute);
+	tm->tm_hour = BCD2BIN(hour);
+	tm->tm_mday = BCD2BIN(day);
+	tm->tm_wday = BCD2BIN(week);
+	tm->tm_mon = BCD2BIN(month) - 1;
+	/* year is 1900 + tm->tm_year */
+	tm->tm_year = BCD2BIN(year) + BCD2BIN(century) * 100 - 1900;
+
+	if (rtc_valid_tm(tm) < 0) {
+		dev_err(dev, "retrieved date/time is not valid.\n");
+		rtc_time_to_tm(0, tm);
+	}
+	return 0;
+}
+
+static void ds1553_rtc_update_alarm(struct rtc_plat_data *pdata)
+{
+	void __iomem *ioaddr = pdata->ioaddr;
+	unsigned long flags;
+
+	spin_lock_irqsave(&pdata->rtc->irq_lock, flags);
+	writeb(pdata->alrm_mday < 0 || (pdata->irqen & RTC_UF) ?
+	       0x80 : BIN2BCD(pdata->alrm_mday),
+	       ioaddr + RTC_DATE_ALARM);
+	writeb(pdata->alrm_hour < 0 || (pdata->irqen & RTC_UF) ?
+	       0x80 : BIN2BCD(pdata->alrm_hour),
+	       ioaddr + RTC_HOURS_ALARM);
+	writeb(pdata->alrm_min < 0 || (pdata->irqen & RTC_UF) ?
+	       0x80 : BIN2BCD(pdata->alrm_min),
+	       ioaddr + RTC_MINUTES_ALARM);
+	writeb(pdata->alrm_sec < 0 || (pdata->irqen & RTC_UF) ?
+	       0x80 : BIN2BCD(pdata->alrm_sec),
+	       ioaddr + RTC_SECONDS_ALARM);
+	writeb(pdata->irqen ? RTC_INTS_AE : 0, ioaddr + RTC_INTERRUPTS);
+	readb(ioaddr + RTC_FLAGS);	/* clear interrupts */
+	spin_unlock_irqrestore(&pdata->rtc->irq_lock, flags);
+}
+
+static int ds1553_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
+
+	if (pdata->irq < 0)
+		return -EINVAL;
+	pdata->alrm_mday = alrm->time.tm_mday;
+	pdata->alrm_hour = alrm->time.tm_hour;
+	pdata->alrm_min = alrm->time.tm_min;
+	pdata->alrm_sec = alrm->time.tm_sec;
+	if (alrm->enabled)
+		pdata->irqen |= RTC_AF;
+	ds1553_rtc_update_alarm(pdata);
+	return 0;
+}
+
+static int ds1553_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
+
+	if (pdata->irq < 0)
+		return -EINVAL;
+	alrm->time.tm_mday = pdata->alrm_mday < 0 ? 0 : pdata->alrm_mday;
+	alrm->time.tm_hour = pdata->alrm_hour < 0 ? 0 : pdata->alrm_hour;
+	alrm->time.tm_min = pdata->alrm_min < 0 ? 0 : pdata->alrm_min;
+	alrm->time.tm_sec = pdata->alrm_sec < 0 ? 0 : pdata->alrm_sec;
+	alrm->enabled = (pdata->irqen & RTC_AF) ? 1 : 0;
+	return 0;
+}
+
+static irqreturn_t ds1553_rtc_interrupt(int irq, void *dev_id,
+					struct pt_regs *regs)
+{
+	struct platform_device *pdev = dev_id;
+	struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
+	void __iomem *ioaddr = pdata->ioaddr;
+	unsigned long events = RTC_IRQF;
+
+	/* read and clear interrupt */
+	if (!(readb(ioaddr + RTC_FLAGS) & RTC_FLAGS_AF))
+		return IRQ_NONE;
+	if (readb(ioaddr + RTC_SECONDS_ALARM) & 0x80)
+		events |= RTC_UF;
+	else
+		events |= RTC_AF;
+	rtc_update_irq(&pdata->rtc->class_dev, 1, events);
+	return IRQ_HANDLED;
+}
+
+static void ds1553_rtc_release(struct device *dev)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
+
+	if (pdata->irq >= 0) {
+		pdata->irqen = 0;
+		ds1553_rtc_update_alarm(pdata);
+	}
+}
+
+static int ds1553_rtc_ioctl(struct device *dev, unsigned int cmd,
+			    unsigned long arg)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
+
+	if (pdata->irq < 0)
+		return -ENOIOCTLCMD; /* fall back into rtc-dev's emulation */
+	switch (cmd) {
+	case RTC_AIE_OFF:
+		pdata->irqen &= ~RTC_AF;
+		ds1553_rtc_update_alarm(pdata);
+		break;
+	case RTC_AIE_ON:
+		pdata->irqen |= RTC_AF;
+		ds1553_rtc_update_alarm(pdata);
+		break;
+	case RTC_UIE_OFF:
+		pdata->irqen &= ~RTC_UF;
+		ds1553_rtc_update_alarm(pdata);
+		break;
+	case RTC_UIE_ON:
+		pdata->irqen |= RTC_UF;
+		ds1553_rtc_update_alarm(pdata);
+		break;
+	default:
+		return -ENOIOCTLCMD;
+	}
+	return 0;
+}
+
+static struct rtc_class_ops ds1553_rtc_ops = {
+	.read_time	= ds1553_rtc_read_time,
+	.set_time	= ds1553_rtc_set_time,
+	.read_alarm	= ds1553_rtc_read_alarm,
+	.set_alarm	= ds1553_rtc_set_alarm,
+	.release	= ds1553_rtc_release,
+	.ioctl		= ds1553_rtc_ioctl,
+};
+
+static ssize_t ds1553_nvram_read(struct kobject *kobj, char *buf,
+				 loff_t pos, size_t size)
+{
+	struct platform_device *pdev =
+		to_platform_device(container_of(kobj, struct device, kobj));
+	struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
+	void __iomem *ioaddr = pdata->ioaddr;
+	ssize_t count;
+
+	for (count = 0; size > 0 && pos < RTC_OFFSET; count++, size--)
+		*buf++ = readb(ioaddr + pos++);
+	return count;
+}
+
+static ssize_t ds1553_nvram_write(struct kobject *kobj, char *buf,
+				  loff_t pos, size_t size)
+{
+	struct platform_device *pdev =
+		to_platform_device(container_of(kobj, struct device, kobj));
+	struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
+	void __iomem *ioaddr = pdata->ioaddr;
+	ssize_t count;
+
+	for (count = 0; size > 0 && pos < RTC_OFFSET; count++, size--)
+		writeb(*buf++, ioaddr + pos++);
+	return count;
+}
+
+static struct bin_attribute ds1553_nvram_attr = {
+	.attr = {
+		.name = "nvram",
+		.mode = S_IRUGO | S_IWUGO,
+		.owner = THIS_MODULE,
+	},
+	.size = RTC_OFFSET,
+	.read = ds1553_nvram_read,
+	.write = ds1553_nvram_write,
+};
+
+static int __init ds1553_rtc_probe(struct platform_device *pdev)
+{
+	struct rtc_device *rtc;
+	struct resource *res;
+	unsigned int cen, sec;
+	struct rtc_plat_data *pdata = NULL;
+	void __iomem *ioaddr = NULL;
+	int ret = 0;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res)
+		return -ENODEV;
+	pdata = kzalloc(sizeof(*pdata), GFP_KERNEL);
+	if (!pdata)
+		return -ENOMEM;
+	pdata->irq = -1;
+	if (!request_mem_region(res->start, RTC_REG_SIZE, pdev->name)) {
+		ret = -EBUSY;
+		goto out;
+	}
+	pdata->baseaddr = res->start;
+	ioaddr = ioremap(pdata->baseaddr, RTC_REG_SIZE);
+	if (!ioaddr) {
+		ret = -ENOMEM;
+		goto out;
+	}
+	pdata->ioaddr = ioaddr;
+	pdata->irq = platform_get_irq(pdev, 0);
+
+	/* turn RTC on if it was not on */
+	sec = readb(ioaddr + RTC_SECONDS);
+	if (sec & RTC_STOP) {
+		sec &= RTC_SECONDS_MASK;
+		cen = readb(ioaddr + RTC_CENTURY) & RTC_CENTURY_MASK;
+		writeb(RTC_WRITE, ioaddr + RTC_CONTROL);
+		writeb(sec, ioaddr + RTC_SECONDS);
+		writeb(cen & RTC_CENTURY_MASK, ioaddr + RTC_CONTROL);
+	}
+	if (readb(ioaddr + RTC_FLAGS) & RTC_FLAGS_BLF)
+		dev_warn(&pdev->dev, "voltage-low detected.\n");
+
+	if (pdata->irq >= 0) {
+		writeb(0, ioaddr + RTC_INTERRUPTS);
+		if (request_irq(pdata->irq, ds1553_rtc_interrupt, IRQF_SHARED,
+				pdev->name, pdev) < 0) {
+			dev_warn(&pdev->dev, "interrupt not available.\n");
+			pdata->irq = -1;
+		}
+	}
+
+	rtc = rtc_device_register(pdev->name, &pdev->dev,
+				  &ds1553_rtc_ops, THIS_MODULE);
+	if (IS_ERR(rtc)) {
+		ret = PTR_ERR(rtc);
+		goto out;
+	}
+	pdata->rtc = rtc;
+	pdata->last_jiffies = jiffies;
+	platform_set_drvdata(pdev, pdata);
+	sysfs_create_bin_file(&pdev->dev.kobj, &ds1553_nvram_attr);
+	return 0;
+ out:
+	if (pdata->irq >= 0)
+		free_irq(pdata->irq, pdev);
+	if (ioaddr)
+		iounmap(ioaddr);
+	if (pdata->baseaddr)
+		release_mem_region(pdata->baseaddr, RTC_REG_SIZE);
+	kfree(pdata);
+	return ret;
+}
+
+static int __devexit ds1553_rtc_remove(struct platform_device *pdev)
+{
+	struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
+
+	sysfs_remove_bin_file(&pdev->dev.kobj, &ds1553_nvram_attr);
+	rtc_device_unregister(pdata->rtc);
+	if (pdata->irq >= 0) {
+		writeb(0, pdata->ioaddr + RTC_INTERRUPTS);
+		free_irq(pdata->irq, pdev);
+	}
+	iounmap(pdata->ioaddr);
+	release_mem_region(pdata->baseaddr, RTC_REG_SIZE);
+	kfree(pdata);
+	return 0;
+}
+
+static struct platform_driver ds1553_rtc_driver = {
+	.probe		= ds1553_rtc_probe,
+	.remove		= __devexit_p(ds1553_rtc_remove),
+	.driver		= {
+		.name	= "ds1553",
+		.owner	= THIS_MODULE,
+	},
+};
+
+static __init int ds1553_init(void)
+{
+	return platform_driver_register(&ds1553_rtc_driver);
+}
+
+static __exit void ds1553_exit(void)
+{
+	return platform_driver_unregister(&ds1553_rtc_driver);
+}
+
+module_init(ds1553_init);
+module_exit(ds1553_exit);
+
+MODULE_AUTHOR("Atsushi Nemoto <anemo@mba.ocn.ne.jp>");
+MODULE_DESCRIPTION("Dallas DS1553 RTC driver");
+MODULE_LICENSE("GPL");
+MODULE_VERSION(DRV_VERSION);
diff --git a/drivers/rtc/rtc-ds1742.c b/drivers/rtc/rtc-ds1742.c
new file mode 100644
index 000000000..8e47e5a06
--- /dev/null
+++ b/drivers/rtc/rtc-ds1742.c
@@ -0,0 +1,259 @@
+/*
+ * An rtc driver for the Dallas DS1742
+ *
+ * Copyright (C) 2006 Atsushi Nemoto <anemo@mba.ocn.ne.jp>
+ *
+ * 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/bcd.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/delay.h>
+#include <linux/jiffies.h>
+#include <linux/rtc.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+
+#define DRV_VERSION "0.1"
+
+#define RTC_REG_SIZE		0x800
+#define RTC_OFFSET		0x7f8
+
+#define RTC_CONTROL		(RTC_OFFSET + 0)
+#define RTC_CENTURY		(RTC_OFFSET + 0)
+#define RTC_SECONDS		(RTC_OFFSET + 1)
+#define RTC_MINUTES		(RTC_OFFSET + 2)
+#define RTC_HOURS		(RTC_OFFSET + 3)
+#define RTC_DAY			(RTC_OFFSET + 4)
+#define RTC_DATE		(RTC_OFFSET + 5)
+#define RTC_MONTH		(RTC_OFFSET + 6)
+#define RTC_YEAR		(RTC_OFFSET + 7)
+
+#define RTC_CENTURY_MASK	0x3f
+#define RTC_SECONDS_MASK	0x7f
+#define RTC_DAY_MASK		0x07
+
+/* Bits in the Control/Century register */
+#define RTC_WRITE		0x80
+#define RTC_READ		0x40
+
+/* Bits in the Seconds register */
+#define RTC_STOP		0x80
+
+/* Bits in the Day register */
+#define RTC_BATT_FLAG		0x80
+
+struct rtc_plat_data {
+	struct rtc_device *rtc;
+	void __iomem *ioaddr;
+	unsigned long baseaddr;
+	unsigned long last_jiffies;
+};
+
+static int ds1742_rtc_set_time(struct device *dev, struct rtc_time *tm)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
+	void __iomem *ioaddr = pdata->ioaddr;
+	u8 century;
+
+	century = BIN2BCD((tm->tm_year + 1900) / 100);
+
+	writeb(RTC_WRITE, ioaddr + RTC_CONTROL);
+
+	writeb(BIN2BCD(tm->tm_year % 100), ioaddr + RTC_YEAR);
+	writeb(BIN2BCD(tm->tm_mon + 1), ioaddr + RTC_MONTH);
+	writeb(BIN2BCD(tm->tm_wday) & RTC_DAY_MASK, ioaddr + RTC_DAY);
+	writeb(BIN2BCD(tm->tm_mday), ioaddr + RTC_DATE);
+	writeb(BIN2BCD(tm->tm_hour), ioaddr + RTC_HOURS);
+	writeb(BIN2BCD(tm->tm_min), ioaddr + RTC_MINUTES);
+	writeb(BIN2BCD(tm->tm_sec) & RTC_SECONDS_MASK, ioaddr + RTC_SECONDS);
+
+	/* RTC_CENTURY and RTC_CONTROL share same register */
+	writeb(RTC_WRITE | (century & RTC_CENTURY_MASK), ioaddr + RTC_CENTURY);
+	writeb(century & RTC_CENTURY_MASK, ioaddr + RTC_CONTROL);
+	return 0;
+}
+
+static int ds1742_rtc_read_time(struct device *dev, struct rtc_time *tm)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
+	void __iomem *ioaddr = pdata->ioaddr;
+	unsigned int year, month, day, hour, minute, second, week;
+	unsigned int century;
+
+	/* give enough time to update RTC in case of continuous read */
+	if (pdata->last_jiffies == jiffies)
+		msleep(1);
+	pdata->last_jiffies = jiffies;
+	writeb(RTC_READ, ioaddr + RTC_CONTROL);
+	second = readb(ioaddr + RTC_SECONDS) & RTC_SECONDS_MASK;
+	minute = readb(ioaddr + RTC_MINUTES);
+	hour = readb(ioaddr + RTC_HOURS);
+	day = readb(ioaddr + RTC_DATE);
+	week = readb(ioaddr + RTC_DAY) & RTC_DAY_MASK;
+	month = readb(ioaddr + RTC_MONTH);
+	year = readb(ioaddr + RTC_YEAR);
+	century = readb(ioaddr + RTC_CENTURY) & RTC_CENTURY_MASK;
+	writeb(0, ioaddr + RTC_CONTROL);
+	tm->tm_sec = BCD2BIN(second);
+	tm->tm_min = BCD2BIN(minute);
+	tm->tm_hour = BCD2BIN(hour);
+	tm->tm_mday = BCD2BIN(day);
+	tm->tm_wday = BCD2BIN(week);
+	tm->tm_mon = BCD2BIN(month) - 1;
+	/* year is 1900 + tm->tm_year */
+	tm->tm_year = BCD2BIN(year) + BCD2BIN(century) * 100 - 1900;
+
+	if (rtc_valid_tm(tm) < 0) {
+		dev_err(dev, "retrieved date/time is not valid.\n");
+		rtc_time_to_tm(0, tm);
+	}
+	return 0;
+}
+
+static struct rtc_class_ops ds1742_rtc_ops = {
+	.read_time	= ds1742_rtc_read_time,
+	.set_time	= ds1742_rtc_set_time,
+};
+
+static ssize_t ds1742_nvram_read(struct kobject *kobj, char *buf,
+				 loff_t pos, size_t size)
+{
+	struct platform_device *pdev =
+		to_platform_device(container_of(kobj, struct device, kobj));
+	struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
+	void __iomem *ioaddr = pdata->ioaddr;
+	ssize_t count;
+
+	for (count = 0; size > 0 && pos < RTC_OFFSET; count++, size--)
+		*buf++ = readb(ioaddr + pos++);
+	return count;
+}
+
+static ssize_t ds1742_nvram_write(struct kobject *kobj, char *buf,
+				  loff_t pos, size_t size)
+{
+	struct platform_device *pdev =
+		to_platform_device(container_of(kobj, struct device, kobj));
+	struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
+	void __iomem *ioaddr = pdata->ioaddr;
+	ssize_t count;
+
+	for (count = 0; size > 0 && pos < RTC_OFFSET; count++, size--)
+		writeb(*buf++, ioaddr + pos++);
+	return count;
+}
+
+static struct bin_attribute ds1742_nvram_attr = {
+	.attr = {
+		.name = "nvram",
+		.mode = S_IRUGO | S_IWUGO,
+		.owner = THIS_MODULE,
+	},
+	.size = RTC_OFFSET,
+	.read = ds1742_nvram_read,
+	.write = ds1742_nvram_write,
+};
+
+static int __init ds1742_rtc_probe(struct platform_device *pdev)
+{
+	struct rtc_device *rtc;
+	struct resource *res;
+	unsigned int cen, sec;
+	struct rtc_plat_data *pdata = NULL;
+	void __iomem *ioaddr = NULL;
+	int ret = 0;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res)
+		return -ENODEV;
+	pdata = kzalloc(sizeof(*pdata), GFP_KERNEL);
+	if (!pdata)
+		return -ENOMEM;
+	if (!request_mem_region(res->start, RTC_REG_SIZE, pdev->name)) {
+		ret = -EBUSY;
+		goto out;
+	}
+	pdata->baseaddr = res->start;
+	ioaddr = ioremap(pdata->baseaddr, RTC_REG_SIZE);
+	if (!ioaddr) {
+		ret = -ENOMEM;
+		goto out;
+	}
+	pdata->ioaddr = ioaddr;
+
+	/* turn RTC on if it was not on */
+	sec = readb(ioaddr + RTC_SECONDS);
+	if (sec & RTC_STOP) {
+		sec &= RTC_SECONDS_MASK;
+		cen = readb(ioaddr + RTC_CENTURY) & RTC_CENTURY_MASK;
+		writeb(RTC_WRITE, ioaddr + RTC_CONTROL);
+		writeb(sec, ioaddr + RTC_SECONDS);
+		writeb(cen & RTC_CENTURY_MASK, ioaddr + RTC_CONTROL);
+	}
+	if (readb(ioaddr + RTC_DAY) & RTC_BATT_FLAG)
+		dev_warn(&pdev->dev, "voltage-low detected.\n");
+
+	rtc = rtc_device_register(pdev->name, &pdev->dev,
+				  &ds1742_rtc_ops, THIS_MODULE);
+	if (IS_ERR(rtc)) {
+		ret = PTR_ERR(rtc);
+		goto out;
+	}
+	pdata->rtc = rtc;
+	pdata->last_jiffies = jiffies;
+	platform_set_drvdata(pdev, pdata);
+	sysfs_create_bin_file(&pdev->dev.kobj, &ds1742_nvram_attr);
+	return 0;
+ out:
+	if (ioaddr)
+		iounmap(ioaddr);
+	if (pdata->baseaddr)
+		release_mem_region(pdata->baseaddr, RTC_REG_SIZE);
+	kfree(pdata);
+	return ret;
+}
+
+static int __devexit ds1742_rtc_remove(struct platform_device *pdev)
+{
+	struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
+
+	sysfs_remove_bin_file(&pdev->dev.kobj, &ds1742_nvram_attr);
+	rtc_device_unregister(pdata->rtc);
+	iounmap(pdata->ioaddr);
+	release_mem_region(pdata->baseaddr, RTC_REG_SIZE);
+	kfree(pdata);
+	return 0;
+}
+
+static struct platform_driver ds1742_rtc_driver = {
+	.probe		= ds1742_rtc_probe,
+	.remove		= __devexit_p(ds1742_rtc_remove),
+	.driver		= {
+		.name	= "ds1742",
+		.owner	= THIS_MODULE,
+	},
+};
+
+static __init int ds1742_init(void)
+{
+	return platform_driver_register(&ds1742_rtc_driver);
+}
+
+static __exit void ds1742_exit(void)
+{
+	return platform_driver_unregister(&ds1742_rtc_driver);
+}
+
+module_init(ds1742_init);
+module_exit(ds1742_exit);
+
+MODULE_AUTHOR("Atsushi Nemoto <anemo@mba.ocn.ne.jp>");
+MODULE_DESCRIPTION("Dallas DS1742 RTC driver");
+MODULE_LICENSE("GPL");
+MODULE_VERSION(DRV_VERSION);
diff --git a/drivers/rtc/rtc-isl1208.c b/drivers/rtc/rtc-isl1208.c
new file mode 100644
index 000000000..f324d0a63
--- /dev/null
+++ b/drivers/rtc/rtc-isl1208.c
@@ -0,0 +1,591 @@
+/*
+ * Intersil ISL1208 rtc class driver
+ *
+ * Copyright 2005,2006 Hebert Valerio Riedel <hvr@gnu.org>
+ *
+ *  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 <linux/i2c.h>
+#include <linux/bcd.h>
+#include <linux/rtc.h>
+
+#define DRV_NAME "isl1208"
+#define DRV_VERSION "0.2"
+
+/* Register map */
+/* rtc section */
+#define ISL1208_REG_SC  0x00
+#define ISL1208_REG_MN  0x01
+#define ISL1208_REG_HR  0x02
+#define ISL1208_REG_HR_MIL     (1<<7) /* 24h/12h mode */
+#define ISL1208_REG_HR_PM      (1<<5) /* PM/AM bit in 12h mode */
+#define ISL1208_REG_DT  0x03
+#define ISL1208_REG_MO  0x04
+#define ISL1208_REG_YR  0x05
+#define ISL1208_REG_DW  0x06
+#define ISL1208_RTC_SECTION_LEN 7
+
+/* control/status section */
+#define ISL1208_REG_SR  0x07
+#define ISL1208_REG_SR_ARST    (1<<7) /* auto reset */
+#define ISL1208_REG_SR_XTOSCB  (1<<6) /* crystal oscillator */
+#define ISL1208_REG_SR_WRTC    (1<<4) /* write rtc */
+#define ISL1208_REG_SR_ALM     (1<<2) /* alarm */
+#define ISL1208_REG_SR_BAT     (1<<1) /* battery */
+#define ISL1208_REG_SR_RTCF    (1<<0) /* rtc fail */
+#define ISL1208_REG_INT 0x08
+#define ISL1208_REG_09  0x09 /* reserved */
+#define ISL1208_REG_ATR 0x0a
+#define ISL1208_REG_DTR 0x0b
+
+/* alarm section */
+#define ISL1208_REG_SCA 0x0c
+#define ISL1208_REG_MNA 0x0d
+#define ISL1208_REG_HRA 0x0e
+#define ISL1208_REG_DTA 0x0f
+#define ISL1208_REG_MOA 0x10
+#define ISL1208_REG_DWA 0x11
+#define ISL1208_ALARM_SECTION_LEN 6
+
+/* user section */
+#define ISL1208_REG_USR1 0x12
+#define ISL1208_REG_USR2 0x13
+#define ISL1208_USR_SECTION_LEN 2
+
+/* i2c configuration */
+#define ISL1208_I2C_ADDR 0xde
+
+static unsigned short normal_i2c[] = {
+	ISL1208_I2C_ADDR>>1, I2C_CLIENT_END
+};
+I2C_CLIENT_INSMOD; /* defines addr_data */
+
+static int isl1208_attach_adapter(struct i2c_adapter *adapter);
+static int isl1208_detach_client(struct i2c_client *client);
+
+static struct i2c_driver isl1208_driver = {
+	.driver		= {
+		.name	= DRV_NAME,
+	},
+	.id		= I2C_DRIVERID_ISL1208,
+	.attach_adapter = &isl1208_attach_adapter,
+	.detach_client	= &isl1208_detach_client,
+};
+
+/* block read */
+static int
+isl1208_i2c_read_regs(struct i2c_client *client, u8 reg, u8 buf[],
+		       unsigned len)
+{
+	u8 reg_addr[1] = { reg };
+	struct i2c_msg msgs[2] = {
+		{ client->addr, client->flags, sizeof(reg_addr), reg_addr },
+		{ client->addr, client->flags | I2C_M_RD, len, buf }
+	};
+	int ret;
+
+	BUG_ON(len == 0);
+	BUG_ON(reg > ISL1208_REG_USR2);
+	BUG_ON(reg + len > ISL1208_REG_USR2 + 1);
+
+	ret = i2c_transfer(client->adapter, msgs, 2);
+	if (ret > 0)
+		ret = 0;
+	return ret;
+}
+
+/* block write */
+static int
+isl1208_i2c_set_regs(struct i2c_client *client, u8 reg, u8 const buf[],
+		       unsigned len)
+{
+	u8 i2c_buf[ISL1208_REG_USR2 + 2];
+	struct i2c_msg msgs[1] = {
+		{ client->addr, client->flags, len + 1, i2c_buf }
+	};
+	int ret;
+
+	BUG_ON(len == 0);
+	BUG_ON(reg > ISL1208_REG_USR2);
+	BUG_ON(reg + len > ISL1208_REG_USR2 + 1);
+
+	i2c_buf[0] = reg;
+	memcpy(&i2c_buf[1], &buf[0], len);
+
+	ret = i2c_transfer(client->adapter, msgs, 1);
+	if (ret > 0)
+		ret = 0;
+	return ret;
+}
+
+/* simple check to see wether we have a isl1208 */
+static int isl1208_i2c_validate_client(struct i2c_client *client)
+{
+	u8 regs[ISL1208_RTC_SECTION_LEN] = { 0, };
+	u8 zero_mask[ISL1208_RTC_SECTION_LEN] = {
+		0x80, 0x80, 0x40, 0xc0, 0xe0, 0x00, 0xf8
+	};
+	int i;
+	int ret;
+
+	ret = isl1208_i2c_read_regs(client, 0, regs, ISL1208_RTC_SECTION_LEN);
+	if (ret < 0)
+		return ret;
+
+	for (i = 0; i < ISL1208_RTC_SECTION_LEN; ++i) {
+		if (regs[i] & zero_mask[i]) /* check if bits are cleared */
+			return -ENODEV;
+	}
+
+	return 0;
+}
+
+static int isl1208_i2c_get_sr(struct i2c_client *client)
+{
+	return i2c_smbus_read_byte_data(client, ISL1208_REG_SR) == -1 ? -EIO:0;
+}
+
+static int isl1208_i2c_get_atr(struct i2c_client *client)
+{
+	int atr = i2c_smbus_read_byte_data(client, ISL1208_REG_ATR);
+
+	if (atr < 0)
+		return -EIO;
+
+	/* The 6bit value in the ATR register controls the load
+	 * capacitance C_load * in steps of 0.25pF
+	 *
+	 * bit (1<<5) of the ATR register is inverted
+	 *
+	 * C_load(ATR=0x20) =  4.50pF
+	 * C_load(ATR=0x00) = 12.50pF
+	 * C_load(ATR=0x1f) = 20.25pF
+	 *
+	 */
+
+	atr &= 0x3f; /* mask out lsb */
+	atr ^= 1<<5; /* invert 6th bit */
+	atr += 2*9; /* add offset of 4.5pF; unit[atr] = 0.25pF */
+
+	return atr;
+}
+
+static int isl1208_i2c_get_dtr(struct i2c_client *client)
+{
+	int dtr = i2c_smbus_read_byte_data(client, ISL1208_REG_DTR);
+
+	if (dtr < 0)
+		return -EIO;
+
+	/* dtr encodes adjustments of {-60,-40,-20,0,20,40,60} ppm */
+	dtr = ((dtr & 0x3) * 20) * (dtr & (1<<2) ? -1 : 1);
+
+	return dtr;
+}
+
+static int isl1208_i2c_get_usr(struct i2c_client *client)
+{
+	u8 buf[ISL1208_USR_SECTION_LEN] = { 0, };
+	int ret;
+
+	ret = isl1208_i2c_read_regs (client, ISL1208_REG_USR1, buf,
+				   ISL1208_USR_SECTION_LEN);
+	if (ret < 0)
+		return ret;
+
+	return (buf[1] << 8) | buf[0];
+}
+
+static int isl1208_i2c_set_usr(struct i2c_client *client, u16 usr)
+{
+	u8 buf[ISL1208_USR_SECTION_LEN];
+
+	buf[0] = usr & 0xff;
+	buf[1] = (usr >> 8) & 0xff;
+
+	return isl1208_i2c_set_regs (client, ISL1208_REG_USR1, buf,
+				     ISL1208_USR_SECTION_LEN);
+}
+
+static int isl1208_rtc_proc(struct device *dev, struct seq_file *seq)
+{
+	struct i2c_client *const client = to_i2c_client(dev);
+	int sr, dtr, atr, usr;
+
+	sr = isl1208_i2c_get_sr(client);
+	if (sr < 0) {
+		dev_err(&client->dev, "%s: reading SR failed\n", __func__);
+		return sr;
+	}
+
+	seq_printf(seq, "status_reg\t:%s%s%s%s%s%s (0x%.2x)\n",
+		   (sr & ISL1208_REG_SR_RTCF) ? " RTCF" : "",
+		   (sr & ISL1208_REG_SR_BAT) ? " BAT" : "",
+		   (sr & ISL1208_REG_SR_ALM) ? " ALM" : "",
+		   (sr & ISL1208_REG_SR_WRTC) ? " WRTC" : "",
+		   (sr & ISL1208_REG_SR_XTOSCB) ? " XTOSCB" : "",
+		   (sr & ISL1208_REG_SR_ARST) ? " ARST" : "",
+		   sr);
+
+	seq_printf(seq, "batt_status\t: %s\n",
+		   (sr & ISL1208_REG_SR_RTCF) ? "bad" : "okay");
+
+	dtr = isl1208_i2c_get_dtr(client);
+	if (dtr >= 0 -1)
+		seq_printf(seq, "digital_trim\t: %d ppm\n", dtr);
+
+	atr = isl1208_i2c_get_atr(client);
+	if (atr >= 0)
+		seq_printf(seq, "analog_trim\t: %d.%.2d pF\n",
+			   atr>>2, (atr&0x3)*25);
+
+	usr = isl1208_i2c_get_usr(client);
+	if (usr >= 0)
+		seq_printf(seq, "user_data\t: 0x%.4x\n", usr);
+
+	return 0;
+}
+
+
+static int isl1208_i2c_read_time(struct i2c_client *client,
+				 struct rtc_time *tm)
+{
+	int sr;
+	u8 regs[ISL1208_RTC_SECTION_LEN] = { 0, };
+
+	sr = isl1208_i2c_get_sr(client);
+	if (sr < 0) {
+		dev_err(&client->dev, "%s: reading SR failed\n", __func__);
+		return -EIO;
+	}
+
+	sr = isl1208_i2c_read_regs(client, 0, regs, ISL1208_RTC_SECTION_LEN);
+	if (sr < 0) {
+		dev_err(&client->dev, "%s: reading RTC section failed\n",
+			__func__);
+		return sr;
+	}
+
+	tm->tm_sec = BCD2BIN(regs[ISL1208_REG_SC]);
+	tm->tm_min = BCD2BIN(regs[ISL1208_REG_MN]);
+	{ /* HR field has a more complex interpretation */
+		const u8 _hr = regs[ISL1208_REG_HR];
+		if (_hr & ISL1208_REG_HR_MIL) /* 24h format */
+			tm->tm_hour = BCD2BIN(_hr & 0x3f);
+		else { // 12h format
+			tm->tm_hour = BCD2BIN(_hr & 0x1f);
+			if (_hr & ISL1208_REG_HR_PM) /* PM flag set */
+				tm->tm_hour += 12;
+		}
+	}
+
+	tm->tm_mday = BCD2BIN(regs[ISL1208_REG_DT]);
+	tm->tm_mon = BCD2BIN(regs[ISL1208_REG_MO]) - 1; /* rtc starts at 1 */
+	tm->tm_year = BCD2BIN(regs[ISL1208_REG_YR]) + 100;
+	tm->tm_wday = BCD2BIN(regs[ISL1208_REG_DW]);
+
+	return 0;
+}
+
+static int isl1208_i2c_read_alarm(struct i2c_client *client,
+				  struct rtc_wkalrm *alarm)
+{
+	struct rtc_time *const tm = &alarm->time;
+	u8 regs[ISL1208_ALARM_SECTION_LEN] = { 0, };
+	int sr;
+
+	sr = isl1208_i2c_get_sr(client);
+	if (sr < 0) {
+		dev_err(&client->dev, "%s: reading SR failed\n", __func__);
+		return sr;
+	}
+
+	sr = isl1208_i2c_read_regs(client, ISL1208_REG_SCA, regs,
+				  ISL1208_ALARM_SECTION_LEN);
+	if (sr < 0) {
+		dev_err(&client->dev, "%s: reading alarm section failed\n",
+			__func__);
+		return sr;
+	}
+
+	/* MSB of each alarm register is an enable bit */
+	tm->tm_sec  = BCD2BIN(regs[ISL1208_REG_SCA-ISL1208_REG_SCA] & 0x7f);
+	tm->tm_min  = BCD2BIN(regs[ISL1208_REG_MNA-ISL1208_REG_SCA] & 0x7f);
+	tm->tm_hour = BCD2BIN(regs[ISL1208_REG_HRA-ISL1208_REG_SCA] & 0x3f);
+	tm->tm_mday = BCD2BIN(regs[ISL1208_REG_DTA-ISL1208_REG_SCA] & 0x3f);
+	tm->tm_mon  = BCD2BIN(regs[ISL1208_REG_MOA-ISL1208_REG_SCA] & 0x1f)-1;
+	tm->tm_wday = BCD2BIN(regs[ISL1208_REG_DWA-ISL1208_REG_SCA] & 0x03);
+
+	return 0;
+}
+
+static int isl1208_rtc_read_time(struct device *dev, struct rtc_time *tm)
+{
+	return isl1208_i2c_read_time(to_i2c_client(dev), tm);
+}
+
+static int isl1208_i2c_set_time(struct i2c_client *client,
+				struct rtc_time const *tm)
+{
+	int sr;
+	u8 regs[ISL1208_RTC_SECTION_LEN] = { 0, };
+
+	regs[ISL1208_REG_SC] = BIN2BCD(tm->tm_sec);
+	regs[ISL1208_REG_MN] = BIN2BCD(tm->tm_min);
+	regs[ISL1208_REG_HR] = BIN2BCD(tm->tm_hour) | ISL1208_REG_HR_MIL;
+
+	regs[ISL1208_REG_DT] = BIN2BCD(tm->tm_mday);
+	regs[ISL1208_REG_MO] = BIN2BCD(tm->tm_mon + 1);
+	regs[ISL1208_REG_YR] = BIN2BCD(tm->tm_year - 100);
+
+	regs[ISL1208_REG_DW] = BIN2BCD(tm->tm_wday & 7);
+
+	sr = isl1208_i2c_get_sr(client);
+	if (sr < 0) {
+		dev_err(&client->dev, "%s: reading SR failed\n", __func__);
+		return sr;
+	}
+
+	/* set WRTC */
+	sr = i2c_smbus_write_byte_data (client, ISL1208_REG_SR,
+				       sr | ISL1208_REG_SR_WRTC);
+	if (sr < 0) {
+		dev_err(&client->dev, "%s: writing SR failed\n", __func__);
+		return sr;
+	}
+
+	/* write RTC registers */
+	sr = isl1208_i2c_set_regs(client, 0, regs, ISL1208_RTC_SECTION_LEN);
+	if (sr < 0) {
+		dev_err(&client->dev, "%s: writing RTC section failed\n",
+			__func__);
+		return sr;
+	}
+
+	/* clear WRTC again */
+	sr = i2c_smbus_write_byte_data (client, ISL1208_REG_SR,
+				       sr & ~ISL1208_REG_SR_WRTC);
+	if (sr < 0) {
+		dev_err(&client->dev, "%s: writing SR failed\n", __func__);
+		return sr;
+	}
+
+	return 0;
+}
+
+
+static int isl1208_rtc_set_time(struct device *dev, struct rtc_time *tm)
+{
+	return isl1208_i2c_set_time(to_i2c_client(dev), tm);
+}
+
+static int isl1208_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
+{
+	return isl1208_i2c_read_alarm(to_i2c_client(dev), alarm);
+}
+
+static struct rtc_class_ops isl1208_rtc_ops = {
+	.proc		= isl1208_rtc_proc,
+	.read_time	= isl1208_rtc_read_time,
+	.set_time	= isl1208_rtc_set_time,
+	.read_alarm	= isl1208_rtc_read_alarm,
+	//.set_alarm	= isl1208_rtc_set_alarm,
+};
+
+/* sysfs interface */
+
+static ssize_t isl1208_sysfs_show_atrim(struct device *dev,
+					struct device_attribute *attr,
+					char *buf)
+{
+	int atr;
+
+	atr = isl1208_i2c_get_atr(to_i2c_client(dev));
+	if (atr < 0)
+		return atr;
+
+	return sprintf(buf, "%d.%.2d pF\n", atr>>2, (atr&0x3)*25);
+}
+static DEVICE_ATTR(atrim, S_IRUGO, isl1208_sysfs_show_atrim, NULL);
+
+static ssize_t isl1208_sysfs_show_dtrim(struct device *dev,
+					struct device_attribute *attr,
+					char *buf)
+{
+	int dtr;
+
+	dtr = isl1208_i2c_get_dtr(to_i2c_client(dev));
+	if (dtr < 0)
+		return dtr;
+
+	return sprintf(buf, "%d ppm\n", dtr);
+}
+static DEVICE_ATTR(dtrim, S_IRUGO, isl1208_sysfs_show_dtrim, NULL);
+
+static ssize_t isl1208_sysfs_show_usr(struct device *dev,
+				       struct device_attribute *attr,
+				       char *buf)
+{
+	int usr;
+
+	usr = isl1208_i2c_get_usr(to_i2c_client(dev));
+	if (usr < 0)
+		return usr;
+
+	return sprintf(buf, "0x%.4x\n", usr);
+}
+
+static ssize_t isl1208_sysfs_store_usr(struct device *dev,
+				       struct device_attribute *attr,
+				       const char *buf, size_t count)
+{
+	int usr = -1;
+
+	if (buf[0] == '0' && (buf[1] == 'x' || buf[1] == 'X')) {
+		if (sscanf(buf, "%x", &usr) != 1)
+			return -EINVAL;
+	} else {
+		if (sscanf(buf, "%d", &usr) != 1)
+			return -EINVAL;
+	}
+
+	if (usr < 0 || usr > 0xffff)
+		return -EINVAL;
+
+	return isl1208_i2c_set_usr(to_i2c_client(dev), usr) ? -EIO : count;
+}
+static DEVICE_ATTR(usr, S_IRUGO | S_IWUSR, isl1208_sysfs_show_usr,
+		   isl1208_sysfs_store_usr);
+
+static int
+isl1208_probe(struct i2c_adapter *adapter, int addr, int kind)
+{
+	int rc = 0;
+	struct i2c_client *new_client = NULL;
+	struct rtc_device *rtc = NULL;
+
+	if (!i2c_check_functionality(adapter, I2C_FUNC_I2C)) {
+		rc = -ENODEV;
+		goto failout;
+	}
+
+	new_client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL);
+	if (new_client == NULL) {
+		rc = -ENOMEM;
+		goto failout;
+	}
+
+	new_client->addr = addr;
+	new_client->adapter = adapter;
+	new_client->driver = &isl1208_driver;
+	new_client->flags = 0;
+	strcpy(new_client->name, DRV_NAME);
+
+	if (kind < 0) {
+		rc = isl1208_i2c_validate_client(new_client);
+		if (rc < 0)
+			goto failout;
+	}
+
+	rc = i2c_attach_client(new_client);
+	if (rc < 0)
+		goto failout;
+
+	dev_info(&new_client->dev,
+		 "chip found, driver version " DRV_VERSION "\n");
+
+	rtc = rtc_device_register(isl1208_driver.driver.name,
+				  &new_client->dev,
+				  &isl1208_rtc_ops, THIS_MODULE);
+
+	if (IS_ERR(rtc)) {
+		rc = PTR_ERR(rtc);
+		goto failout_detach;
+	}
+
+	i2c_set_clientdata(new_client, rtc);
+
+	rc = isl1208_i2c_get_sr(new_client);
+	if (rc < 0) {
+		dev_err(&new_client->dev, "reading status failed\n");
+		goto failout_unregister;
+	}
+
+	if (rc & ISL1208_REG_SR_RTCF)
+		dev_warn(&new_client->dev, "rtc power failure detected, "
+			 "please set clock.\n");
+
+	rc = device_create_file(&new_client->dev, &dev_attr_atrim);
+	if (rc < 0)
+		goto failout_unregister;
+	rc = device_create_file(&new_client->dev, &dev_attr_dtrim);
+	if (rc < 0)
+		goto failout_atrim;
+	rc = device_create_file(&new_client->dev, &dev_attr_usr);
+	if (rc < 0)
+		goto failout_dtrim;
+
+	return 0;
+
+ failout_dtrim:
+	device_remove_file(&new_client->dev, &dev_attr_dtrim);
+ failout_atrim:
+	device_remove_file(&new_client->dev, &dev_attr_atrim);
+ failout_unregister:
+	rtc_device_unregister(rtc);
+ failout_detach:
+	i2c_detach_client(new_client);
+ failout:
+	kfree(new_client);
+	return rc;
+}
+
+static int
+isl1208_attach_adapter (struct i2c_adapter *adapter)
+{
+	return i2c_probe(adapter, &addr_data, isl1208_probe);
+}
+
+static int
+isl1208_detach_client(struct i2c_client *client)
+{
+	int rc;
+	struct rtc_device *const rtc = i2c_get_clientdata(client);
+
+	if (rtc)
+		rtc_device_unregister(rtc); /* do we need to kfree? */
+
+	rc = i2c_detach_client(client);
+	if (rc)
+		return rc;
+
+	kfree(client);
+
+	return 0;
+}
+
+/* module management */
+
+static int __init isl1208_init(void)
+{
+	return i2c_add_driver(&isl1208_driver);
+}
+
+static void __exit isl1208_exit(void)
+{
+	i2c_del_driver(&isl1208_driver);
+}
+
+MODULE_AUTHOR("Herbert Valerio Riedel <hvr@gnu.org>");
+MODULE_DESCRIPTION("Intersil ISL1208 RTC driver");
+MODULE_LICENSE("GPL");
+MODULE_VERSION(DRV_VERSION);
+
+module_init(isl1208_init);
+module_exit(isl1208_exit);
diff --git a/drivers/rtc/rtc-max6902.c b/drivers/rtc/rtc-max6902.c
new file mode 100644
index 000000000..480ce6cdc
--- /dev/null
+++ b/drivers/rtc/rtc-max6902.c
@@ -0,0 +1,285 @@
+/* drivers/char/max6902.c
+ *
+ * Copyright (C) 2006 8D Technologies inc.
+ * Copyright (C) 2004 Compulab Ltd.
+ *
+ * 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.
+ *
+ * Driver for MAX6902 spi RTC
+ *
+ * Changelog:
+ *
+ * 24-May-2006: Raphael Assenat <raph@8d.com>
+ *                - Major rework
+ *   				Converted to rtc_device and uses the SPI layer.
+ *
+ * ??-???-2005: Someone at Compulab
+ *                - Initial driver creation.
+ */
+
+#include <linux/module.h>
+#include <linux/version.h>
+
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/init.h>
+#include <linux/rtc.h>
+#include <linux/spi/spi.h>
+#include <linux/bcd.h>
+#include <linux/delay.h>
+
+#define MAX6902_REG_SECONDS		0x01
+#define MAX6902_REG_MINUTES		0x03
+#define MAX6902_REG_HOURS		0x05
+#define MAX6902_REG_DATE		0x07
+#define MAX6902_REG_MONTH		0x09
+#define MAX6902_REG_DAY			0x0B
+#define MAX6902_REG_YEAR		0x0D
+#define MAX6902_REG_CONTROL		0x0F
+#define MAX6902_REG_CENTURY		0x13
+
+#undef MAX6902_DEBUG
+
+struct max6902 {
+	struct rtc_device *rtc;
+	u8 buf[9]; /* Burst read cmd + 8 registers */
+	u8 tx_buf[2];
+	u8 rx_buf[2];
+};
+
+static void max6902_set_reg(struct device *dev, unsigned char address,
+				unsigned char data)
+{
+	struct spi_device *spi = to_spi_device(dev);
+	unsigned char buf[2];
+
+	/* MSB must be '0' to write */
+	buf[0] = address & 0x7f;
+	buf[1] = data;
+
+	spi_write(spi, buf, 2);
+}
+
+static int max6902_get_reg(struct device *dev, unsigned char address,
+				unsigned char *data)
+{
+	struct spi_device *spi = to_spi_device(dev);
+	struct max6902 *chip = dev_get_drvdata(dev);
+	struct spi_message message;
+	struct spi_transfer xfer;
+	int status;
+
+	if (!data)
+		return -EINVAL;
+
+	/* Build our spi message */
+	spi_message_init(&message);
+	memset(&xfer, 0, sizeof(xfer));
+	xfer.len = 2;
+	/* Can tx_buf and rx_buf be equal? The doc in spi.h is not sure... */
+	xfer.tx_buf = chip->tx_buf;
+	xfer.rx_buf = chip->rx_buf;
+
+	/* Set MSB to indicate read */
+	chip->tx_buf[0] = address | 0x80;
+
+	spi_message_add_tail(&xfer, &message);
+
+	/* do the i/o */
+	status = spi_sync(spi, &message);
+	if (status == 0)
+		status = message.status;
+	else
+		return status;
+
+	*data = chip->rx_buf[1];
+
+	return status;
+}
+
+static int max6902_get_datetime(struct device *dev, struct rtc_time *dt)
+{
+	unsigned char tmp;
+	int century;
+	int err;
+	struct spi_device *spi = to_spi_device(dev);
+	struct max6902 *chip = dev_get_drvdata(dev);
+	struct spi_message message;
+	struct spi_transfer xfer;
+	int status;
+
+	err = max6902_get_reg(dev, MAX6902_REG_CENTURY, &tmp);
+	if (err)
+		return err;
+
+	/* build the message */
+	spi_message_init(&message);
+	memset(&xfer, 0, sizeof(xfer));
+	xfer.len = 1 + 7;	/* Burst read command + 7 registers */
+	xfer.tx_buf = chip->buf;
+	xfer.rx_buf = chip->buf;
+	chip->buf[0] = 0xbf;	/* Burst read */
+	spi_message_add_tail(&xfer, &message);
+
+	/* do the i/o */
+	status = spi_sync(spi, &message);
+	if (status == 0)
+		status = message.status;
+	else
+		return status;
+
+	/* The chip sends data in this order:
+	 * Seconds, Minutes, Hours, Date, Month, Day, Year */
+	dt->tm_sec	= BCD2BIN(chip->buf[1]);
+	dt->tm_min	= BCD2BIN(chip->buf[2]);
+	dt->tm_hour	= BCD2BIN(chip->buf[3]);
+	dt->tm_mday	= BCD2BIN(chip->buf[4]);
+	dt->tm_mon	= BCD2BIN(chip->buf[5]) - 1;
+	dt->tm_wday	= BCD2BIN(chip->buf[6]);
+	dt->tm_year = BCD2BIN(chip->buf[7]);
+
+	century = BCD2BIN(tmp) * 100;
+
+	dt->tm_year += century;
+	dt->tm_year -= 1900;
+
+#ifdef MAX6902_DEBUG
+	printk("\n%s : Read RTC values\n",__FUNCTION__);
+	printk("tm_hour: %i\n",dt->tm_hour);
+	printk("tm_min : %i\n",dt->tm_min);
+	printk("tm_sec : %i\n",dt->tm_sec);
+	printk("tm_year: %i\n",dt->tm_year);
+	printk("tm_mon : %i\n",dt->tm_mon);
+	printk("tm_mday: %i\n",dt->tm_mday);
+	printk("tm_wday: %i\n",dt->tm_wday);
+#endif
+
+	return 0;
+}
+
+static int max6902_set_datetime(struct device *dev, struct rtc_time *dt)
+{
+	dt->tm_year = dt->tm_year+1900;
+
+#ifdef MAX6902_DEBUG
+	printk("\n%s : Setting RTC values\n",__FUNCTION__);
+	printk("tm_sec : %i\n",dt->tm_sec);
+	printk("tm_min : %i\n",dt->tm_min);
+	printk("tm_hour: %i\n",dt->tm_hour);
+	printk("tm_mday: %i\n",dt->tm_mday);
+	printk("tm_wday: %i\n",dt->tm_wday);
+	printk("tm_year: %i\n",dt->tm_year);
+#endif
+
+	/* Remove write protection */
+	max6902_set_reg(dev, 0xF, 0);
+
+	max6902_set_reg(dev, 0x01, BIN2BCD(dt->tm_sec));
+	max6902_set_reg(dev, 0x03, BIN2BCD(dt->tm_min));
+	max6902_set_reg(dev, 0x05, BIN2BCD(dt->tm_hour));
+
+	max6902_set_reg(dev, 0x07, BIN2BCD(dt->tm_mday));
+	max6902_set_reg(dev, 0x09, BIN2BCD(dt->tm_mon+1));
+	max6902_set_reg(dev, 0x0B, BIN2BCD(dt->tm_wday));
+	max6902_set_reg(dev, 0x0D, BIN2BCD(dt->tm_year%100));
+	max6902_set_reg(dev, 0x13, BIN2BCD(dt->tm_year/100));
+
+	/* Compulab used a delay here. However, the datasheet
+	 * does not mention a delay being required anywhere... */
+	/* delay(2000); */
+
+	/* Write protect */
+	max6902_set_reg(dev, 0xF, 0x80);
+
+	return 0;
+}
+
+static int max6902_read_time(struct device *dev, struct rtc_time *tm)
+{
+	return max6902_get_datetime(dev, tm);
+}
+
+static int max6902_set_time(struct device *dev, struct rtc_time *tm)
+{
+	return max6902_set_datetime(dev, tm);
+}
+
+static struct rtc_class_ops max6902_rtc_ops = {
+	.read_time	= max6902_read_time,
+	.set_time	= max6902_set_time,
+};
+
+static int __devinit max6902_probe(struct spi_device *spi)
+{
+	struct rtc_device *rtc;
+	unsigned char tmp;
+	struct max6902 *chip;
+	int res;
+
+	rtc = rtc_device_register("max6902",
+				&spi->dev, &max6902_rtc_ops, THIS_MODULE);
+	if (IS_ERR(rtc))
+		return PTR_ERR(rtc);
+
+	spi->mode = SPI_MODE_3;
+	spi->bits_per_word = 8;
+	spi_setup(spi);
+
+	chip = kzalloc(sizeof *chip, GFP_KERNEL);
+	if (!chip) {
+		rtc_device_unregister(rtc);
+		return -ENOMEM;
+	}
+	chip->rtc = rtc;
+	dev_set_drvdata(&spi->dev, chip);
+
+	res = max6902_get_reg(&spi->dev, MAX6902_REG_SECONDS, &tmp);
+	if (res) {
+		rtc_device_unregister(rtc);
+		return res;
+	}
+
+	return 0;
+}
+
+static int __devexit max6902_remove(struct spi_device *spi)
+{
+	struct max6902 *chip = platform_get_drvdata(spi);
+	struct rtc_device *rtc = chip->rtc;
+
+	if (rtc)
+		rtc_device_unregister(rtc);
+
+	kfree(chip);
+
+	return 0;
+}
+
+static struct spi_driver max6902_driver = {
+	.driver = {
+		.name 	= "max6902",
+		.bus	= &spi_bus_type,
+		.owner	= THIS_MODULE,
+	},
+	.probe 	= max6902_probe,
+	.remove = __devexit_p(max6902_remove),
+};
+
+static __init int max6902_init(void)
+{
+	printk("max6902 spi driver\n");
+	return spi_register_driver(&max6902_driver);
+}
+module_init(max6902_init);
+
+static __exit void max6902_exit(void)
+{
+	spi_unregister_driver(&max6902_driver);
+}
+module_exit(max6902_exit);
+
+MODULE_DESCRIPTION ("max6902 spi RTC driver");
+MODULE_AUTHOR ("Raphael Assenat");
+MODULE_LICENSE ("GPL");
diff --git a/drivers/rtc/rtc-pcf8583.c b/drivers/rtc/rtc-pcf8583.c
new file mode 100644
index 000000000..b235a30cb
--- /dev/null
+++ b/drivers/rtc/rtc-pcf8583.c
@@ -0,0 +1,394 @@
+/*
+ *  drivers/rtc/rtc-pcf8583.c
+ *
+ *  Copyright (C) 2000 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ *  Driver for PCF8583 RTC & RAM chip
+ *
+ *  Converted to the generic RTC susbsystem by G. Liakhovetski (2006)
+ */
+#include <linux/module.h>
+#include <linux/i2c.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+#include <linux/mc146818rtc.h>
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/bcd.h>
+
+struct rtc_mem {
+	unsigned int	loc;
+	unsigned int	nr;
+	unsigned char	*data;
+};
+
+struct pcf8583 {
+	struct i2c_client client;
+	struct rtc_device *rtc;
+	unsigned char ctrl;
+};
+
+#define CTRL_STOP	0x80
+#define CTRL_HOLD	0x40
+#define CTRL_32KHZ	0x00
+#define CTRL_MASK	0x08
+#define CTRL_ALARMEN	0x04
+#define CTRL_ALARM	0x02
+#define CTRL_TIMER	0x01
+
+static unsigned short normal_i2c[] = { I2C_CLIENT_END };
+
+/* Module parameters */
+I2C_CLIENT_INSMOD;
+
+static struct i2c_driver pcf8583_driver;
+
+#define get_ctrl(x)    ((struct pcf8583 *)i2c_get_clientdata(x))->ctrl
+#define set_ctrl(x, v) get_ctrl(x) = v
+
+#define CMOS_YEAR	(64 + 128)
+#define CMOS_CHECKSUM	(63)
+
+static int pcf8583_get_datetime(struct i2c_client *client, struct rtc_time *dt)
+{
+	unsigned char buf[8], addr[1] = { 1 };
+	struct i2c_msg msgs[2] = {
+		{
+			.addr = client->addr,
+			.flags = 0,
+			.len = 1,
+			.buf = addr,
+		}, {
+			.addr = client->addr,
+			.flags = I2C_M_RD,
+			.len = 6,
+			.buf = buf,
+		}
+	};
+	int ret;
+
+	memset(buf, 0, sizeof(buf));
+
+	ret = i2c_transfer(client->adapter, msgs, 2);
+	if (ret == 2) {
+		dt->tm_year = buf[4] >> 6;
+		dt->tm_wday = buf[5] >> 5;
+
+		buf[4] &= 0x3f;
+		buf[5] &= 0x1f;
+
+		dt->tm_sec = BCD_TO_BIN(buf[1]);
+		dt->tm_min = BCD_TO_BIN(buf[2]);
+		dt->tm_hour = BCD_TO_BIN(buf[3]);
+		dt->tm_mday = BCD_TO_BIN(buf[4]);
+		dt->tm_mon = BCD_TO_BIN(buf[5]);
+	}
+
+	return ret == 2 ? 0 : -EIO;
+}
+
+static int pcf8583_set_datetime(struct i2c_client *client, struct rtc_time *dt, int datetoo)
+{
+	unsigned char buf[8];
+	int ret, len = 6;
+
+	buf[0] = 0;
+	buf[1] = get_ctrl(client) | 0x80;
+	buf[2] = 0;
+	buf[3] = BIN_TO_BCD(dt->tm_sec);
+	buf[4] = BIN_TO_BCD(dt->tm_min);
+	buf[5] = BIN_TO_BCD(dt->tm_hour);
+
+	if (datetoo) {
+		len = 8;
+		buf[6] = BIN_TO_BCD(dt->tm_mday) | (dt->tm_year << 6);
+		buf[7] = BIN_TO_BCD(dt->tm_mon)  | (dt->tm_wday << 5);
+	}
+
+	ret = i2c_master_send(client, (char *)buf, len);
+	if (ret != len)
+		return -EIO;
+
+	buf[1] = get_ctrl(client);
+	ret = i2c_master_send(client, (char *)buf, 2);
+
+	return ret == 2 ? 0 : -EIO;
+}
+
+static int pcf8583_get_ctrl(struct i2c_client *client, unsigned char *ctrl)
+{
+	*ctrl = get_ctrl(client);
+	return 0;
+}
+
+static int pcf8583_set_ctrl(struct i2c_client *client, unsigned char *ctrl)
+{
+	unsigned char buf[2];
+
+	buf[0] = 0;
+	buf[1] = *ctrl;
+	set_ctrl(client, *ctrl);
+
+	return i2c_master_send(client, (char *)buf, 2);
+}
+
+static int pcf8583_read_mem(struct i2c_client *client, struct rtc_mem *mem)
+{
+	unsigned char addr[1];
+	struct i2c_msg msgs[2] = {
+		{
+			.addr = client->addr,
+			.flags = 0,
+			.len = 1,
+			.buf = addr,
+		}, {
+			.addr = client->addr,
+			.flags = I2C_M_RD,
+			.len = mem->nr,
+			.buf = mem->data,
+		}
+	};
+
+	if (mem->loc < 8)
+		return -EINVAL;
+
+	addr[0] = mem->loc;
+
+	return i2c_transfer(client->adapter, msgs, 2) == 2 ? 0 : -EIO;
+}
+
+static int pcf8583_write_mem(struct i2c_client *client, struct rtc_mem *mem)
+{
+	unsigned char addr[1];
+	struct i2c_msg msgs[2] = {
+		{
+			.addr = client->addr,
+			.flags = 0,
+			.len = 1,
+			.buf = addr,
+		}, {
+			.addr = client->addr,
+			.flags = I2C_M_NOSTART,
+			.len = mem->nr,
+			.buf = mem->data,
+		}
+	};
+
+	if (mem->loc < 8)
+		return -EINVAL;
+
+	addr[0] = mem->loc;
+
+	return i2c_transfer(client->adapter, msgs, 2) == 2 ? 0 : -EIO;
+}
+
+static int pcf8583_rtc_read_time(struct device *dev, struct rtc_time *tm)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	unsigned char ctrl, year[2];
+	struct rtc_mem mem = { CMOS_YEAR, sizeof(year), year };
+	int real_year, year_offset, err;
+
+	/*
+	 * Ensure that the RTC is running.
+	 */
+	pcf8583_get_ctrl(client, &ctrl);
+	if (ctrl & (CTRL_STOP | CTRL_HOLD)) {
+		unsigned char new_ctrl = ctrl & ~(CTRL_STOP | CTRL_HOLD);
+
+		printk(KERN_WARNING "RTC: resetting control %02x -> %02x\n",
+		       ctrl, new_ctrl);
+
+		if ((err = pcf8583_set_ctrl(client, &new_ctrl)) < 0)
+			return err;
+	}
+
+	if (pcf8583_get_datetime(client, tm) ||
+	    pcf8583_read_mem(client, &mem))
+		return -EIO;
+
+	real_year = year[0];
+
+	/*
+	 * The RTC year holds the LSB two bits of the current
+	 * year, which should reflect the LSB two bits of the
+	 * CMOS copy of the year.  Any difference indicates
+	 * that we have to correct the CMOS version.
+	 */
+	year_offset = tm->tm_year - (real_year & 3);
+	if (year_offset < 0)
+		/*
+		 * RTC year wrapped.  Adjust it appropriately.
+		 */
+		year_offset += 4;
+
+	tm->tm_year = real_year + year_offset + year[1] * 100;
+
+	return 0;
+}
+
+static int pcf8583_rtc_set_time(struct device *dev, struct rtc_time *tm)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	unsigned char year[2], chk;
+	struct rtc_mem cmos_year  = { CMOS_YEAR, sizeof(year), year };
+	struct rtc_mem cmos_check = { CMOS_CHECKSUM, 1, &chk };
+	int ret;
+
+	/*
+	 * The RTC's own 2-bit year must reflect the least
+	 * significant two bits of the CMOS year.
+	 */
+
+	ret = pcf8583_set_datetime(client, tm, 1);
+	if (ret)
+		return ret;
+
+	ret = pcf8583_read_mem(client, &cmos_check);
+	if (ret)
+		return ret;
+
+	ret = pcf8583_read_mem(client, &cmos_year);
+	if (ret)
+		return ret;
+
+	chk -= year[1] + year[0];
+
+	year[1] = tm->tm_year / 100;
+	year[0] = tm->tm_year % 100;
+
+	chk += year[1] + year[0];
+
+	ret = pcf8583_write_mem(client, &cmos_year);
+
+	if (ret)
+		return ret;
+
+	ret = pcf8583_write_mem(client, &cmos_check);
+
+	return ret;
+}
+
+static struct rtc_class_ops pcf8583_rtc_ops = {
+	.read_time	= pcf8583_rtc_read_time,
+	.set_time	= pcf8583_rtc_set_time,
+};
+
+static int pcf8583_probe(struct i2c_adapter *adap, int addr, int kind);
+
+static int pcf8583_attach(struct i2c_adapter *adap)
+{
+	return i2c_probe(adap, &addr_data, pcf8583_probe);
+}
+
+static int pcf8583_detach(struct i2c_client *client)
+{
+	int err;
+	struct pcf8583 *pcf = i2c_get_clientdata(client);
+	struct rtc_device *rtc = pcf->rtc;
+
+	if (rtc)
+		rtc_device_unregister(rtc);
+
+	if ((err = i2c_detach_client(client)))
+		return err;
+
+	kfree(pcf);
+	return 0;
+}
+
+static struct i2c_driver pcf8583_driver = {
+	.driver = {
+		.name	= "pcf8583",
+	},
+	.id		= I2C_DRIVERID_PCF8583,
+	.attach_adapter	= pcf8583_attach,
+	.detach_client	= pcf8583_detach,
+};
+
+static int pcf8583_probe(struct i2c_adapter *adap, int addr, int kind)
+{
+	struct pcf8583 *pcf;
+	struct i2c_client *client;
+	struct rtc_device *rtc;
+	unsigned char buf[1], ad[1] = { 0 };
+	int err;
+	struct i2c_msg msgs[2] = {
+		{
+			.addr = addr,
+			.flags = 0,
+			.len = 1,
+			.buf = ad,
+		}, {
+			.addr = addr,
+			.flags = I2C_M_RD,
+			.len = 1,
+			.buf = buf,
+		}
+	};
+
+	pcf = kzalloc(sizeof(*pcf), GFP_KERNEL);
+	if (!pcf)
+		return -ENOMEM;
+
+	client = &pcf->client;
+
+	client->addr		= addr;
+	client->adapter	= adap;
+	client->driver	= &pcf8583_driver;
+
+	strlcpy(client->name, pcf8583_driver.driver.name, I2C_NAME_SIZE);
+
+	if (i2c_transfer(client->adapter, msgs, 2) != 2) {
+		err = -EIO;
+		goto exit_kfree;
+	}
+
+	err = i2c_attach_client(client);
+
+	if (err)
+		goto exit_kfree;
+
+	rtc = rtc_device_register(pcf8583_driver.driver.name, &client->dev,
+				  &pcf8583_rtc_ops, THIS_MODULE);
+
+	if (IS_ERR(rtc)) {
+		err = PTR_ERR(rtc);
+		goto exit_detach;
+	}
+
+	pcf->rtc = rtc;
+	i2c_set_clientdata(client, pcf);
+	set_ctrl(client, buf[0]);
+
+	return 0;
+
+exit_detach:
+	i2c_detach_client(client);
+
+exit_kfree:
+	kfree(pcf);
+
+	return err;
+}
+
+static __init int pcf8583_init(void)
+{
+	return i2c_add_driver(&pcf8583_driver);
+}
+
+static __exit void pcf8583_exit(void)
+{
+	i2c_del_driver(&pcf8583_driver);
+}
+
+module_init(pcf8583_init);
+module_exit(pcf8583_exit);
+
+MODULE_AUTHOR("Russell King");
+MODULE_DESCRIPTION("PCF8583 I2C RTC driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/rtc/rtc-pl031.c b/drivers/rtc/rtc-pl031.c
new file mode 100644
index 000000000..d6d1c5726
--- /dev/null
+++ b/drivers/rtc/rtc-pl031.c
@@ -0,0 +1,233 @@
+/*
+ * drivers/rtc/rtc-pl031.c
+ *
+ * Real Time Clock interface for ARM AMBA PrimeCell 031 RTC
+ *
+ * Author: Deepak Saxena <dsaxena@plexity.net>
+ *
+ * Copyright 2006 (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
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/platform_device.h>
+#include <linux/module.h>
+#include <linux/rtc.h>
+#include <linux/init.h>
+#include <linux/fs.h>
+#include <linux/interrupt.h>
+#include <linux/string.h>
+#include <linux/pm.h>
+
+#include <linux/amba/bus.h>
+
+#include <asm/io.h>
+#include <asm/bitops.h>
+#include <asm/hardware.h>
+#include <asm/irq.h>
+#include <asm/rtc.h>
+
+/*
+ * Register definitions
+ */
+#define	RTC_DR		0x00	/* Data read register */
+#define	RTC_MR		0x04	/* Match register */
+#define	RTC_LR		0x08	/* Data load register */
+#define	RTC_CR		0x0c	/* Control register */
+#define	RTC_IMSC	0x10	/* Interrupt mask and set register */
+#define	RTC_RIS		0x14	/* Raw interrupt status register */
+#define	RTC_MIS		0x18	/* Masked interrupt status register */
+#define	RTC_ICR		0x1c	/* Interrupt clear register */
+
+struct pl031_local {
+	struct rtc_device *rtc;
+	void __iomem *base;
+};
+
+static irqreturn_t pl031_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	struct rtc_device *rtc = dev_id;
+
+	rtc_update_irq(&rtc->class_dev, 1, RTC_AF);
+
+	return IRQ_HANDLED;
+}
+
+static int pl031_open(struct device *dev)
+{
+	/*
+	 * We request IRQ in pl031_probe, so nothing to do here...
+	 */
+	return 0;
+}
+
+static void pl031_release(struct device *dev)
+{
+}
+
+static int pl031_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
+{
+	struct pl031_local *ldata = dev_get_drvdata(dev);
+
+	switch (cmd) {
+	case RTC_AIE_OFF:
+		__raw_writel(1, ldata->base + RTC_MIS);
+		return 0;
+	case RTC_AIE_ON:
+		__raw_writel(0, ldata->base + RTC_MIS);
+		return 0;
+	}
+
+	return -ENOIOCTLCMD;
+}
+
+static int pl031_read_time(struct device *dev, struct rtc_time *tm)
+{
+	struct pl031_local *ldata = dev_get_drvdata(dev);
+
+	rtc_time_to_tm(__raw_readl(ldata->base + RTC_DR), tm);
+
+	return 0;
+}
+
+static int pl031_set_time(struct device *dev, struct rtc_time *tm)
+{
+	unsigned long time;
+	struct pl031_local *ldata = dev_get_drvdata(dev);
+
+	rtc_tm_to_time(tm, &time);
+	__raw_writel(time, ldata->base + RTC_LR);
+
+	return 0;
+}
+
+static int pl031_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
+{
+	struct pl031_local *ldata = dev_get_drvdata(dev);
+
+	rtc_time_to_tm(__raw_readl(ldata->base + RTC_MR), &alarm->time);
+	alarm->pending = __raw_readl(ldata->base + RTC_RIS);
+	alarm->enabled = __raw_readl(ldata->base + RTC_IMSC);
+
+	return 0;
+}
+
+static int pl031_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
+{
+	struct pl031_local *ldata = dev_get_drvdata(dev);
+	unsigned long time;
+
+	rtc_tm_to_time(&alarm->time, &time);
+
+	__raw_writel(time, ldata->base + RTC_MR);
+	__raw_writel(!alarm->enabled, ldata->base + RTC_MIS);
+
+	return 0;
+}
+
+static struct rtc_class_ops pl031_ops = {
+	.open = pl031_open,
+	.release = pl031_release,
+	.ioctl = pl031_ioctl,
+	.read_time = pl031_read_time,
+	.set_time = pl031_set_time,
+	.read_alarm = pl031_read_alarm,
+	.set_alarm = pl031_set_alarm,
+};
+
+static int pl031_remove(struct amba_device *adev)
+{
+	struct pl031_local *ldata = dev_get_drvdata(&adev->dev);
+
+	if (ldata) {
+		dev_set_drvdata(&adev->dev, NULL);
+		free_irq(adev->irq[0], ldata->rtc);
+		rtc_device_unregister(ldata->rtc);
+		iounmap(ldata->base);
+		kfree(ldata);
+	}
+
+	return 0;
+}
+
+static int pl031_probe(struct amba_device *adev, void *id)
+{
+	int ret;
+	struct pl031_local *ldata;
+
+
+	ldata = kmalloc(sizeof(struct pl031_local), GFP_KERNEL);
+	if (!ldata) {
+		ret = -ENOMEM;
+		goto out;
+	}
+	dev_set_drvdata(&adev->dev, ldata);
+
+	ldata->base = ioremap(adev->res.start,
+			      adev->res.end - adev->res.start + 1);
+	if (!ldata->base) {
+		ret = -ENOMEM;
+		goto out_no_remap;
+	}
+
+	if (request_irq(adev->irq[0], pl031_interrupt, IRQF_DISABLED,
+			"rtc-pl031", ldata->rtc)) {
+		ret = -EIO;
+		goto out_no_irq;
+	}
+
+	ldata->rtc = rtc_device_register("pl031", &adev->dev, &pl031_ops,
+					 THIS_MODULE);
+	if (IS_ERR(ldata->rtc)) {
+		ret = PTR_ERR(ldata->rtc);
+		goto out_no_rtc;
+	}
+
+	return 0;
+
+out_no_rtc:
+	free_irq(adev->irq[0], ldata->rtc);
+out_no_irq:
+	iounmap(ldata->base);
+out_no_remap:
+	dev_set_drvdata(&adev->dev, NULL);
+	kfree(ldata);
+out:
+	return ret;
+}
+
+static struct amba_id pl031_ids[] __initdata = {
+	{
+		 .id = 0x00041031,
+	 	.mask = 0x000fffff, },
+	{0, 0},
+};
+
+static struct amba_driver pl031_driver = {
+	.drv = {
+		.name = "rtc-pl031",
+	},
+	.id_table = pl031_ids,
+	.probe = pl031_probe,
+	.remove = pl031_remove,
+};
+
+static int __init pl031_init(void)
+{
+	return amba_driver_register(&pl031_driver);
+}
+
+static void __exit pl031_exit(void)
+{
+	amba_driver_unregister(&pl031_driver);
+}
+
+module_init(pl031_init);
+module_exit(pl031_exit);
+
+MODULE_AUTHOR("Deepak Saxena <dsaxena@plexity.net");
+MODULE_DESCRIPTION("ARM AMBA PL031 RTC Driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/rtc/rtc-rs5c348.c b/drivers/rtc/rtc-rs5c348.c
new file mode 100644
index 000000000..0964d1dba
--- /dev/null
+++ b/drivers/rtc/rtc-rs5c348.c
@@ -0,0 +1,246 @@
+/*
+ * A SPI driver for the Ricoh RS5C348 RTC
+ *
+ * Copyright (C) 2006 Atsushi Nemoto <anemo@mba.ocn.ne.jp>
+ *
+ * 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.
+ *
+ * The board specific init code should provide characteristics of this
+ * device:
+ *     Mode 1 (High-Active, Shift-Then-Sample), High Avtive CS
+ */
+
+#include <linux/bcd.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/rtc.h>
+#include <linux/workqueue.h>
+#include <linux/spi/spi.h>
+
+#define DRV_VERSION "0.1"
+
+#define RS5C348_REG_SECS	0
+#define RS5C348_REG_MINS	1
+#define RS5C348_REG_HOURS	2
+#define RS5C348_REG_WDAY	3
+#define RS5C348_REG_DAY	4
+#define RS5C348_REG_MONTH	5
+#define RS5C348_REG_YEAR	6
+#define RS5C348_REG_CTL1	14
+#define RS5C348_REG_CTL2	15
+
+#define RS5C348_SECS_MASK	0x7f
+#define RS5C348_MINS_MASK	0x7f
+#define RS5C348_HOURS_MASK	0x3f
+#define RS5C348_WDAY_MASK	0x03
+#define RS5C348_DAY_MASK	0x3f
+#define RS5C348_MONTH_MASK	0x1f
+
+#define RS5C348_BIT_PM	0x20	/* REG_HOURS */
+#define RS5C348_BIT_Y2K	0x80	/* REG_MONTH */
+#define RS5C348_BIT_24H	0x20	/* REG_CTL1 */
+#define RS5C348_BIT_XSTP	0x10	/* REG_CTL2 */
+#define RS5C348_BIT_VDET	0x40	/* REG_CTL2 */
+
+#define RS5C348_CMD_W(addr)	(((addr) << 4) | 0x08)	/* single write */
+#define RS5C348_CMD_R(addr)	(((addr) << 4) | 0x0c)	/* single read */
+#define RS5C348_CMD_MW(addr)	(((addr) << 4) | 0x00)	/* burst write */
+#define RS5C348_CMD_MR(addr)	(((addr) << 4) | 0x04)	/* burst read */
+
+struct rs5c348_plat_data {
+	struct rtc_device *rtc;
+	int rtc_24h;
+};
+
+static int
+rs5c348_rtc_set_time(struct device *dev, struct rtc_time *tm)
+{
+	struct spi_device *spi = to_spi_device(dev);
+	struct rs5c348_plat_data *pdata = spi->dev.platform_data;
+	u8 txbuf[5+7], *txp;
+	int ret;
+
+	/* Transfer 5 bytes before writing SEC.  This gives 31us for carry. */
+	txp = txbuf;
+	txbuf[0] = RS5C348_CMD_R(RS5C348_REG_CTL2); /* cmd, ctl2 */
+	txbuf[1] = 0;	/* dummy */
+	txbuf[2] = RS5C348_CMD_R(RS5C348_REG_CTL2); /* cmd, ctl2 */
+	txbuf[3] = 0;	/* dummy */
+	txbuf[4] = RS5C348_CMD_MW(RS5C348_REG_SECS); /* cmd, sec, ... */
+	txp = &txbuf[5];
+	txp[RS5C348_REG_SECS] = BIN2BCD(tm->tm_sec);
+	txp[RS5C348_REG_MINS] = BIN2BCD(tm->tm_min);
+	if (pdata->rtc_24h) {
+		txp[RS5C348_REG_HOURS] = BIN2BCD(tm->tm_hour);
+	} else {
+		/* hour 0 is AM12, noon is PM12 */
+		txp[RS5C348_REG_HOURS] = BIN2BCD((tm->tm_hour + 11) % 12 + 1) |
+			(tm->tm_hour >= 12 ? RS5C348_BIT_PM : 0);
+	}
+	txp[RS5C348_REG_WDAY] = BIN2BCD(tm->tm_wday);
+	txp[RS5C348_REG_DAY] = BIN2BCD(tm->tm_mday);
+	txp[RS5C348_REG_MONTH] = BIN2BCD(tm->tm_mon + 1) |
+		(tm->tm_year >= 100 ? RS5C348_BIT_Y2K : 0);
+	txp[RS5C348_REG_YEAR] = BIN2BCD(tm->tm_year % 100);
+	/* write in one transfer to avoid data inconsistency */
+	ret = spi_write_then_read(spi, txbuf, sizeof(txbuf), NULL, 0);
+	udelay(62);	/* Tcsr 62us */
+	return ret;
+}
+
+static int
+rs5c348_rtc_read_time(struct device *dev, struct rtc_time *tm)
+{
+	struct spi_device *spi = to_spi_device(dev);
+	struct rs5c348_plat_data *pdata = spi->dev.platform_data;
+	u8 txbuf[5], rxbuf[7];
+	int ret;
+
+	/* Transfer 5 byte befores reading SEC.  This gives 31us for carry. */
+	txbuf[0] = RS5C348_CMD_R(RS5C348_REG_CTL2); /* cmd, ctl2 */
+	txbuf[1] = 0;	/* dummy */
+	txbuf[2] = RS5C348_CMD_R(RS5C348_REG_CTL2); /* cmd, ctl2 */
+	txbuf[3] = 0;	/* dummy */
+	txbuf[4] = RS5C348_CMD_MR(RS5C348_REG_SECS); /* cmd, sec, ... */
+
+	/* read in one transfer to avoid data inconsistency */
+	ret = spi_write_then_read(spi, txbuf, sizeof(txbuf),
+				  rxbuf, sizeof(rxbuf));
+	udelay(62);	/* Tcsr 62us */
+	if (ret < 0)
+		return ret;
+
+	tm->tm_sec = BCD2BIN(rxbuf[RS5C348_REG_SECS] & RS5C348_SECS_MASK);
+	tm->tm_min = BCD2BIN(rxbuf[RS5C348_REG_MINS] & RS5C348_MINS_MASK);
+	tm->tm_hour = BCD2BIN(rxbuf[RS5C348_REG_HOURS] & RS5C348_HOURS_MASK);
+	if (!pdata->rtc_24h) {
+		tm->tm_hour %= 12;
+		if (rxbuf[RS5C348_REG_HOURS] & RS5C348_BIT_PM)
+			tm->tm_hour += 12;
+	}
+	tm->tm_wday = BCD2BIN(rxbuf[RS5C348_REG_WDAY] & RS5C348_WDAY_MASK);
+	tm->tm_mday = BCD2BIN(rxbuf[RS5C348_REG_DAY] & RS5C348_DAY_MASK);
+	tm->tm_mon =
+		BCD2BIN(rxbuf[RS5C348_REG_MONTH] & RS5C348_MONTH_MASK) - 1;
+	/* year is 1900 + tm->tm_year */
+	tm->tm_year = BCD2BIN(rxbuf[RS5C348_REG_YEAR]) +
+		((rxbuf[RS5C348_REG_MONTH] & RS5C348_BIT_Y2K) ? 100 : 0);
+
+	if (rtc_valid_tm(tm) < 0) {
+		dev_err(&spi->dev, "retrieved date/time is not valid.\n");
+		rtc_time_to_tm(0, tm);
+	}
+
+	return 0;
+}
+
+static struct rtc_class_ops rs5c348_rtc_ops = {
+	.read_time	= rs5c348_rtc_read_time,
+	.set_time	= rs5c348_rtc_set_time,
+};
+
+static struct spi_driver rs5c348_driver;
+
+static int __devinit rs5c348_probe(struct spi_device *spi)
+{
+	int ret;
+	struct rtc_device *rtc;
+	struct rs5c348_plat_data *pdata;
+
+	pdata = kzalloc(sizeof(struct rs5c348_plat_data), GFP_KERNEL);
+	if (!pdata)
+		return -ENOMEM;
+	spi->dev.platform_data = pdata;
+
+	/* Check D7 of SECOND register */
+	ret = spi_w8r8(spi, RS5C348_CMD_R(RS5C348_REG_SECS));
+	if (ret < 0 || (ret & 0x80)) {
+		dev_err(&spi->dev, "not found.\n");
+		goto kfree_exit;
+	}
+
+	dev_info(&spi->dev, "chip found, driver version " DRV_VERSION "\n");
+	dev_info(&spi->dev, "spiclk %u KHz.\n",
+		 (spi->max_speed_hz + 500) / 1000);
+
+	/* turn RTC on if it was not on */
+	ret = spi_w8r8(spi, RS5C348_CMD_R(RS5C348_REG_CTL2));
+	if (ret < 0)
+		goto kfree_exit;
+	if (ret & (RS5C348_BIT_XSTP | RS5C348_BIT_VDET)) {
+		u8 buf[2];
+		if (ret & RS5C348_BIT_VDET)
+			dev_warn(&spi->dev, "voltage-low detected.\n");
+		buf[0] = RS5C348_CMD_W(RS5C348_REG_CTL2);
+		buf[1] = 0;
+		ret = spi_write_then_read(spi, buf, sizeof(buf), NULL, 0);
+		if (ret < 0)
+			goto kfree_exit;
+	}
+
+	ret = spi_w8r8(spi, RS5C348_CMD_R(RS5C348_REG_CTL1));
+	if (ret < 0)
+		goto kfree_exit;
+	if (ret & RS5C348_BIT_24H)
+		pdata->rtc_24h = 1;
+
+	rtc = rtc_device_register(rs5c348_driver.driver.name, &spi->dev,
+				  &rs5c348_rtc_ops, THIS_MODULE);
+
+	if (IS_ERR(rtc)) {
+		ret = PTR_ERR(rtc);
+		goto kfree_exit;
+	}
+
+	pdata->rtc = rtc;
+
+	return 0;
+ kfree_exit:
+	kfree(pdata);
+	return ret;
+}
+
+static int __devexit rs5c348_remove(struct spi_device *spi)
+{
+	struct rs5c348_plat_data *pdata = spi->dev.platform_data;
+	struct rtc_device *rtc = pdata->rtc;
+
+	if (rtc)
+		rtc_device_unregister(rtc);
+	kfree(pdata);
+	return 0;
+}
+
+static struct spi_driver rs5c348_driver = {
+	.driver = {
+		.name	= "rs5c348",
+		.bus	= &spi_bus_type,
+		.owner	= THIS_MODULE,
+	},
+	.probe	= rs5c348_probe,
+	.remove	= __devexit_p(rs5c348_remove),
+};
+
+static __init int rs5c348_init(void)
+{
+	return spi_register_driver(&rs5c348_driver);
+}
+
+static __exit void rs5c348_exit(void)
+{
+	spi_unregister_driver(&rs5c348_driver);
+}
+
+module_init(rs5c348_init);
+module_exit(rs5c348_exit);
+
+MODULE_AUTHOR("Atsushi Nemoto <anemo@mba.ocn.ne.jp>");
+MODULE_DESCRIPTION("Ricoh RS5C348 RTC driver");
+MODULE_LICENSE("GPL");
+MODULE_VERSION(DRV_VERSION);
diff --git a/drivers/rtc/rtc-s3c.c b/drivers/rtc/rtc-s3c.c
new file mode 100644
index 000000000..2c7de79c8
--- /dev/null
+++ b/drivers/rtc/rtc-s3c.c
@@ -0,0 +1,621 @@
+/* drivers/rtc/rtc-s3c.c
+ *
+ * Copyright (c) 2004,2006 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/S3C2440/S3C24XX Internal RTC Driver
+*/
+
+#include <linux/module.h>
+#include <linux/fs.h>
+#include <linux/string.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/interrupt.h>
+#include <linux/rtc.h>
+#include <linux/bcd.h>
+#include <linux/clk.h>
+
+#include <asm/hardware.h>
+#include <asm/uaccess.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/rtc.h>
+
+#include <asm/mach/time.h>
+
+#include <asm/arch/regs-rtc.h>
+
+/* I have yet to find an S3C implementation with more than one
+ * of these rtc blocks in */
+
+static struct resource *s3c_rtc_mem;
+
+static void __iomem *s3c_rtc_base;
+static int s3c_rtc_alarmno = NO_IRQ;
+static int s3c_rtc_tickno  = NO_IRQ;
+static int s3c_rtc_freq    = 1;
+
+static DEFINE_SPINLOCK(s3c_rtc_pie_lock);
+static unsigned int tick_count;
+
+/* IRQ Handlers */
+
+static irqreturn_t s3c_rtc_alarmirq(int irq, void *id, struct pt_regs *r)
+{
+	struct rtc_device *rdev = id;
+
+	rtc_update_irq(&rdev->class_dev, 1, RTC_AF | RTC_IRQF);
+	return IRQ_HANDLED;
+}
+
+static irqreturn_t s3c_rtc_tickirq(int irq, void *id, struct pt_regs *r)
+{
+	struct rtc_device *rdev = id;
+
+	rtc_update_irq(&rdev->class_dev, tick_count++, RTC_PF | RTC_IRQF);
+	return IRQ_HANDLED;
+}
+
+/* Update control registers */
+static void s3c_rtc_setaie(int to)
+{
+	unsigned int tmp;
+
+	pr_debug("%s: aie=%d\n", __FUNCTION__, to);
+
+	tmp = readb(s3c_rtc_base + S3C2410_RTCALM) & ~S3C2410_RTCALM_ALMEN;
+
+	if (to)
+		tmp |= S3C2410_RTCALM_ALMEN;
+
+	writeb(tmp, s3c_rtc_base + S3C2410_RTCALM);
+}
+
+static void s3c_rtc_setpie(int to)
+{
+	unsigned int tmp;
+
+	pr_debug("%s: pie=%d\n", __FUNCTION__, to);
+
+	spin_lock_irq(&s3c_rtc_pie_lock);
+	tmp = readb(s3c_rtc_base + S3C2410_TICNT) & ~S3C2410_TICNT_ENABLE;
+
+	if (to)
+		tmp |= S3C2410_TICNT_ENABLE;
+
+	writeb(tmp, s3c_rtc_base + S3C2410_TICNT);
+	spin_unlock_irq(&s3c_rtc_pie_lock);
+}
+
+static void s3c_rtc_setfreq(int freq)
+{
+	unsigned int tmp;
+
+	spin_lock_irq(&s3c_rtc_pie_lock);
+	tmp = readb(s3c_rtc_base + S3C2410_TICNT) & S3C2410_TICNT_ENABLE;
+
+	s3c_rtc_freq = freq;
+
+	tmp |= (128 / freq)-1;
+
+	writeb(tmp, s3c_rtc_base + S3C2410_TICNT);
+	spin_unlock_irq(&s3c_rtc_pie_lock);
+}
+
+/* Time read/write */
+
+static int s3c_rtc_gettime(struct device *dev, struct rtc_time *rtc_tm)
+{
+	unsigned int have_retried = 0;
+	void __iomem *base = s3c_rtc_base;
+
+ retry_get_time:
+	rtc_tm->tm_min  = readb(base + S3C2410_RTCMIN);
+	rtc_tm->tm_hour = readb(base + S3C2410_RTCHOUR);
+	rtc_tm->tm_mday = readb(base + S3C2410_RTCDATE);
+	rtc_tm->tm_mon  = readb(base + S3C2410_RTCMON);
+	rtc_tm->tm_year = readb(base + S3C2410_RTCYEAR);
+	rtc_tm->tm_sec  = readb(base + S3C2410_RTCSEC);
+
+	/* the only way to work out wether the system was mid-update
+	 * when we read it is to check the second counter, and if it
+	 * is zero, then we re-try the entire read
+	 */
+
+	if (rtc_tm->tm_sec == 0 && !have_retried) {
+		have_retried = 1;
+		goto retry_get_time;
+	}
+
+	pr_debug("read time %02x.%02x.%02x %02x/%02x/%02x\n",
+		 rtc_tm->tm_year, rtc_tm->tm_mon, rtc_tm->tm_mday,
+		 rtc_tm->tm_hour, rtc_tm->tm_min, rtc_tm->tm_sec);
+
+	BCD_TO_BIN(rtc_tm->tm_sec);
+	BCD_TO_BIN(rtc_tm->tm_min);
+	BCD_TO_BIN(rtc_tm->tm_hour);
+	BCD_TO_BIN(rtc_tm->tm_mday);
+	BCD_TO_BIN(rtc_tm->tm_mon);
+	BCD_TO_BIN(rtc_tm->tm_year);
+
+	rtc_tm->tm_year += 100;
+	rtc_tm->tm_mon -= 1;
+
+	return 0;
+}
+
+static int s3c_rtc_settime(struct device *dev, struct rtc_time *tm)
+{
+	void __iomem *base = s3c_rtc_base;
+	int year = tm->tm_year - 100;
+
+	pr_debug("set time %02d.%02d.%02d %02d/%02d/%02d\n",
+		 tm->tm_year, tm->tm_mon, tm->tm_mday,
+		 tm->tm_hour, tm->tm_min, tm->tm_sec);
+
+	/* we get around y2k by simply not supporting it */
+
+	if (year < 0 || year >= 100) {
+		dev_err(dev, "rtc only supports 100 years\n");
+		return -EINVAL;
+	}
+
+	writeb(BIN2BCD(tm->tm_sec),  base + S3C2410_RTCSEC);
+	writeb(BIN2BCD(tm->tm_min),  base + S3C2410_RTCMIN);
+	writeb(BIN2BCD(tm->tm_hour), base + S3C2410_RTCHOUR);
+	writeb(BIN2BCD(tm->tm_mday), base + S3C2410_RTCDATE);
+	writeb(BIN2BCD(tm->tm_mon + 1), base + S3C2410_RTCMON);
+	writeb(BIN2BCD(year), base + S3C2410_RTCYEAR);
+
+	return 0;
+}
+
+static int s3c_rtc_getalarm(struct device *dev, struct rtc_wkalrm *alrm)
+{
+	struct rtc_time *alm_tm = &alrm->time;
+	void __iomem *base = s3c_rtc_base;
+	unsigned int alm_en;
+
+	alm_tm->tm_sec  = readb(base + S3C2410_ALMSEC);
+	alm_tm->tm_min  = readb(base + S3C2410_ALMMIN);
+	alm_tm->tm_hour = readb(base + S3C2410_ALMHOUR);
+	alm_tm->tm_mon  = readb(base + S3C2410_ALMMON);
+	alm_tm->tm_mday = readb(base + S3C2410_ALMDATE);
+	alm_tm->tm_year = readb(base + S3C2410_ALMYEAR);
+
+	alm_en = readb(base + S3C2410_RTCALM);
+
+	pr_debug("read alarm %02x %02x.%02x.%02x %02x/%02x/%02x\n",
+		 alm_en,
+		 alm_tm->tm_year, alm_tm->tm_mon, alm_tm->tm_mday,
+		 alm_tm->tm_hour, alm_tm->tm_min, alm_tm->tm_sec);
+
+
+	/* decode the alarm enable field */
+
+	if (alm_en & S3C2410_RTCALM_SECEN)
+		BCD_TO_BIN(alm_tm->tm_sec);
+	else
+		alm_tm->tm_sec = 0xff;
+
+	if (alm_en & S3C2410_RTCALM_MINEN)
+		BCD_TO_BIN(alm_tm->tm_min);
+	else
+		alm_tm->tm_min = 0xff;
+
+	if (alm_en & S3C2410_RTCALM_HOUREN)
+		BCD_TO_BIN(alm_tm->tm_hour);
+	else
+		alm_tm->tm_hour = 0xff;
+
+	if (alm_en & S3C2410_RTCALM_DAYEN)
+		BCD_TO_BIN(alm_tm->tm_mday);
+	else
+		alm_tm->tm_mday = 0xff;
+
+	if (alm_en & S3C2410_RTCALM_MONEN) {
+		BCD_TO_BIN(alm_tm->tm_mon);
+		alm_tm->tm_mon -= 1;
+	} else {
+		alm_tm->tm_mon = 0xff;
+	}
+
+	if (alm_en & S3C2410_RTCALM_YEAREN)
+		BCD_TO_BIN(alm_tm->tm_year);
+	else
+		alm_tm->tm_year = 0xffff;
+
+	return 0;
+}
+
+static int s3c_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm)
+{
+	struct rtc_time *tm = &alrm->time;
+	void __iomem *base = s3c_rtc_base;
+	unsigned int alrm_en;
+
+	pr_debug("s3c_rtc_setalarm: %d, %02x/%02x/%02x %02x.%02x.%02x\n",
+		 alrm->enabled,
+		 tm->tm_mday & 0xff, tm->tm_mon & 0xff, tm->tm_year & 0xff,
+		 tm->tm_hour & 0xff, tm->tm_min & 0xff, tm->tm_sec);
+
+
+	alrm_en = readb(base + S3C2410_RTCALM) & S3C2410_RTCALM_ALMEN;
+	writeb(0x00, base + S3C2410_RTCALM);
+
+	if (tm->tm_sec < 60 && tm->tm_sec >= 0) {
+		alrm_en |= S3C2410_RTCALM_SECEN;
+		writeb(BIN2BCD(tm->tm_sec), base + S3C2410_ALMSEC);
+	}
+
+	if (tm->tm_min < 60 && tm->tm_min >= 0) {
+		alrm_en |= S3C2410_RTCALM_MINEN;
+		writeb(BIN2BCD(tm->tm_min), base + S3C2410_ALMMIN);
+	}
+
+	if (tm->tm_hour < 24 && tm->tm_hour >= 0) {
+		alrm_en |= S3C2410_RTCALM_HOUREN;
+		writeb(BIN2BCD(tm->tm_hour), base + S3C2410_ALMHOUR);
+	}
+
+	pr_debug("setting S3C2410_RTCALM to %08x\n", alrm_en);
+
+	writeb(alrm_en, base + S3C2410_RTCALM);
+
+	if (0) {
+		alrm_en = readb(base + S3C2410_RTCALM);
+		alrm_en &= ~S3C2410_RTCALM_ALMEN;
+		writeb(alrm_en, base + S3C2410_RTCALM);
+		disable_irq_wake(s3c_rtc_alarmno);
+	}
+
+	if (alrm->enabled)
+		enable_irq_wake(s3c_rtc_alarmno);
+	else
+		disable_irq_wake(s3c_rtc_alarmno);
+
+	return 0;
+}
+
+static int s3c_rtc_ioctl(struct device *dev,
+			 unsigned int cmd, unsigned long arg)
+{
+	unsigned int ret = -ENOIOCTLCMD;
+
+	switch (cmd) {
+	case RTC_AIE_OFF:
+	case RTC_AIE_ON:
+		s3c_rtc_setaie((cmd == RTC_AIE_ON) ? 1 : 0);
+		ret = 0;
+		break;
+
+	case RTC_PIE_OFF:
+	case RTC_PIE_ON:
+		tick_count = 0;
+		s3c_rtc_setpie((cmd == RTC_PIE_ON) ? 1 : 0);
+		ret = 0;
+		break;
+
+	case RTC_IRQP_READ:
+		ret = put_user(s3c_rtc_freq, (unsigned long __user *)arg);
+		break;
+
+	case RTC_IRQP_SET:
+		/* check for power of 2 */
+
+		if ((arg & (arg-1)) != 0 || arg < 1) {
+			ret = -EINVAL;
+			goto exit;
+		}
+
+		pr_debug("s3c2410_rtc: setting frequency %ld\n", arg);
+
+		s3c_rtc_setfreq(arg);
+		ret = 0;
+		break;
+
+	case RTC_UIE_ON:
+	case RTC_UIE_OFF:
+		ret = -EINVAL;
+	}
+
+ exit:
+	return ret;
+}
+
+static int s3c_rtc_proc(struct device *dev, struct seq_file *seq)
+{
+	unsigned int rtcalm = readb(s3c_rtc_base + S3C2410_RTCALM);
+	unsigned int ticnt = readb(s3c_rtc_base + S3C2410_TICNT);
+
+	seq_printf(seq, "alarm_IRQ\t: %s\n",
+		   (rtcalm & S3C2410_RTCALM_ALMEN) ? "yes" : "no" );
+
+	seq_printf(seq, "periodic_IRQ\t: %s\n",
+		     (ticnt & S3C2410_TICNT_ENABLE) ? "yes" : "no" );
+
+	seq_printf(seq, "periodic_freq\t: %d\n", s3c_rtc_freq);
+
+	return 0;
+}
+
+static int s3c_rtc_open(struct device *dev)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct rtc_device *rtc_dev = platform_get_drvdata(pdev);
+	int ret;
+
+	ret = request_irq(s3c_rtc_alarmno, s3c_rtc_alarmirq,
+			  SA_INTERRUPT,  "s3c2410-rtc alarm", rtc_dev);
+
+	if (ret) {
+		dev_err(dev, "IRQ%d error %d\n", s3c_rtc_alarmno, ret);
+		return ret;
+	}
+
+	ret = request_irq(s3c_rtc_tickno, s3c_rtc_tickirq,
+			  SA_INTERRUPT,  "s3c2410-rtc tick", rtc_dev);
+
+	if (ret) {
+		dev_err(dev, "IRQ%d error %d\n", s3c_rtc_tickno, ret);
+		goto tick_err;
+	}
+
+	return ret;
+
+ tick_err:
+	free_irq(s3c_rtc_alarmno, rtc_dev);
+	return ret;
+}
+
+static void s3c_rtc_release(struct device *dev)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct rtc_device *rtc_dev = platform_get_drvdata(pdev);
+
+	/* do not clear AIE here, it may be needed for wake */
+
+	s3c_rtc_setpie(0);
+	free_irq(s3c_rtc_alarmno, rtc_dev);
+	free_irq(s3c_rtc_tickno, rtc_dev);
+}
+
+static struct rtc_class_ops s3c_rtcops = {
+	.open		= s3c_rtc_open,
+	.release	= s3c_rtc_release,
+	.ioctl		= s3c_rtc_ioctl,
+	.read_time	= s3c_rtc_gettime,
+	.set_time	= s3c_rtc_settime,
+	.read_alarm	= s3c_rtc_getalarm,
+	.set_alarm	= s3c_rtc_setalarm,
+	.proc	        = s3c_rtc_proc,
+};
+
+static void s3c_rtc_enable(struct platform_device *pdev, int en)
+{
+	void __iomem *base = s3c_rtc_base;
+	unsigned int tmp;
+
+	if (s3c_rtc_base == NULL)
+		return;
+
+	if (!en) {
+		tmp = readb(base + S3C2410_RTCCON);
+		writeb(tmp & ~S3C2410_RTCCON_RTCEN, base + S3C2410_RTCCON);
+
+		tmp = readb(base + S3C2410_TICNT);
+		writeb(tmp & ~S3C2410_TICNT_ENABLE, base + S3C2410_TICNT);
+	} else {
+		/* re-enable the device, and check it is ok */
+
+		if ((readb(base+S3C2410_RTCCON) & S3C2410_RTCCON_RTCEN) == 0){
+			dev_info(&pdev->dev, "rtc disabled, re-enabling\n");
+
+			tmp = readb(base + S3C2410_RTCCON);
+			writeb(tmp|S3C2410_RTCCON_RTCEN, base+S3C2410_RTCCON);
+		}
+
+		if ((readb(base + S3C2410_RTCCON) & S3C2410_RTCCON_CNTSEL)){
+			dev_info(&pdev->dev, "removing RTCCON_CNTSEL\n");
+
+			tmp = readb(base + S3C2410_RTCCON);
+			writeb(tmp& ~S3C2410_RTCCON_CNTSEL, base+S3C2410_RTCCON);
+		}
+
+		if ((readb(base + S3C2410_RTCCON) & S3C2410_RTCCON_CLKRST)){
+			dev_info(&pdev->dev, "removing RTCCON_CLKRST\n");
+
+			tmp = readb(base + S3C2410_RTCCON);
+			writeb(tmp & ~S3C2410_RTCCON_CLKRST, base+S3C2410_RTCCON);
+		}
+	}
+}
+
+static int s3c_rtc_remove(struct platform_device *dev)
+{
+	struct rtc_device *rtc = platform_get_drvdata(dev);
+
+	platform_set_drvdata(dev, NULL);
+	rtc_device_unregister(rtc);
+
+	s3c_rtc_setpie(0);
+	s3c_rtc_setaie(0);
+
+	iounmap(s3c_rtc_base);
+	release_resource(s3c_rtc_mem);
+	kfree(s3c_rtc_mem);
+
+	return 0;
+}
+
+static int s3c_rtc_probe(struct platform_device *pdev)
+{
+	struct rtc_device *rtc;
+	struct resource *res;
+	int ret;
+
+	pr_debug("%s: probe=%p\n", __FUNCTION__, pdev);
+
+	/* find the IRQs */
+
+	s3c_rtc_tickno = platform_get_irq(pdev, 1);
+	if (s3c_rtc_tickno < 0) {
+		dev_err(&pdev->dev, "no irq for rtc tick\n");
+		return -ENOENT;
+	}
+
+	s3c_rtc_alarmno = platform_get_irq(pdev, 0);
+	if (s3c_rtc_alarmno < 0) {
+		dev_err(&pdev->dev, "no irq for alarm\n");
+		return -ENOENT;
+	}
+
+	pr_debug("s3c2410_rtc: tick irq %d, alarm irq %d\n",
+		 s3c_rtc_tickno, s3c_rtc_alarmno);
+
+	/* get the memory region */
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (res == NULL) {
+		dev_err(&pdev->dev, "failed to get memory region resource\n");
+		return -ENOENT;
+	}
+
+	s3c_rtc_mem = request_mem_region(res->start,
+					 res->end-res->start+1,
+					 pdev->name);
+
+	if (s3c_rtc_mem == NULL) {
+		dev_err(&pdev->dev, "failed to reserve memory region\n");
+		ret = -ENOENT;
+		goto err_nores;
+	}
+
+	s3c_rtc_base = ioremap(res->start, res->end - res->start + 1);
+	if (s3c_rtc_base == NULL) {
+		dev_err(&pdev->dev, "failed ioremap()\n");
+		ret = -EINVAL;
+		goto err_nomap;
+	}
+
+	/* check to see if everything is setup correctly */
+
+	s3c_rtc_enable(pdev, 1);
+
+ 	pr_debug("s3c2410_rtc: RTCCON=%02x\n",
+		 readb(s3c_rtc_base + S3C2410_RTCCON));
+
+	s3c_rtc_setfreq(s3c_rtc_freq);
+
+	/* register RTC and exit */
+
+	rtc = rtc_device_register("s3c", &pdev->dev, &s3c_rtcops,
+				  THIS_MODULE);
+
+	if (IS_ERR(rtc)) {
+		dev_err(&pdev->dev, "cannot attach rtc\n");
+		ret = PTR_ERR(rtc);
+		goto err_nortc;
+	}
+
+	rtc->max_user_freq = 128;
+
+	platform_set_drvdata(pdev, rtc);
+	return 0;
+
+ err_nortc:
+	s3c_rtc_enable(pdev, 0);
+	iounmap(s3c_rtc_base);
+
+ err_nomap:
+	release_resource(s3c_rtc_mem);
+
+ err_nores:
+	return ret;
+}
+
+#ifdef CONFIG_PM
+
+/* RTC Power management control */
+
+static struct timespec s3c_rtc_delta;
+
+static int ticnt_save;
+
+static int s3c_rtc_suspend(struct platform_device *pdev, pm_message_t state)
+{
+	struct rtc_time tm;
+	struct timespec time;
+
+	time.tv_nsec = 0;
+
+	/* save TICNT for anyone using periodic interrupts */
+
+	ticnt_save = readb(s3c_rtc_base + S3C2410_TICNT);
+
+	/* calculate time delta for suspend */
+
+	s3c_rtc_gettime(&pdev->dev, &tm);
+	rtc_tm_to_time(&tm, &time.tv_sec);
+	save_time_delta(&s3c_rtc_delta, &time);
+	s3c_rtc_enable(pdev, 0);
+
+	return 0;
+}
+
+static int s3c_rtc_resume(struct platform_device *pdev)
+{
+	struct rtc_time tm;
+	struct timespec time;
+
+	time.tv_nsec = 0;
+
+	s3c_rtc_enable(pdev, 1);
+	s3c_rtc_gettime(&pdev->dev, &tm);
+	rtc_tm_to_time(&tm, &time.tv_sec);
+	restore_time_delta(&s3c_rtc_delta, &time);
+
+	writeb(ticnt_save, s3c_rtc_base + S3C2410_TICNT);
+	return 0;
+}
+#else
+#define s3c_rtc_suspend NULL
+#define s3c_rtc_resume  NULL
+#endif
+
+static struct platform_driver s3c2410_rtcdrv = {
+	.probe		= s3c_rtc_probe,
+	.remove		= s3c_rtc_remove,
+	.suspend	= s3c_rtc_suspend,
+	.resume		= s3c_rtc_resume,
+	.driver		= {
+		.name	= "s3c2410-rtc",
+		.owner	= THIS_MODULE,
+	},
+};
+
+static char __initdata banner[] = "S3C24XX RTC, (c) 2004,2006 Simtec Electronics\n";
+
+static int __init s3c_rtc_init(void)
+{
+	printk(banner);
+	return platform_driver_register(&s3c2410_rtcdrv);
+}
+
+static void __exit s3c_rtc_exit(void)
+{
+	platform_driver_unregister(&s3c2410_rtcdrv);
+}
+
+module_init(s3c_rtc_init);
+module_exit(s3c_rtc_exit);
+
+MODULE_DESCRIPTION("Samsung S3C RTC Driver");
+MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/rtc/rtc-v3020.c b/drivers/rtc/rtc-v3020.c
new file mode 100644
index 000000000..a40f400ac
--- /dev/null
+++ b/drivers/rtc/rtc-v3020.c
@@ -0,0 +1,264 @@
+/* drivers/rtc/rtc-v3020.c
+ *
+ * Copyright (C) 2006 8D Technologies inc.
+ * Copyright (C) 2004 Compulab Ltd.
+ *
+ * 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.
+ *
+ * Driver for the V3020 RTC
+ *
+ * Changelog:
+ *
+ *  10-May-2006: Raphael Assenat <raph@8d.com>
+ *				- Converted to platform driver
+ *				- Use the generic rtc class
+ *
+ *  ??-???-2004: Someone at Compulab
+ *  			- Initial driver creation.
+ *
+ */
+#include <linux/platform_device.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/rtc.h>
+#include <linux/types.h>
+#include <linux/bcd.h>
+#include <linux/rtc-v3020.h>
+
+#include <asm/io.h>
+
+#undef DEBUG
+
+struct v3020 {
+	void __iomem *ioaddress;
+	int leftshift;
+	struct rtc_device *rtc;
+};
+
+static void v3020_set_reg(struct v3020 *chip, unsigned char address,
+			unsigned char data)
+{
+	int i;
+	unsigned char tmp;
+
+	tmp = address;
+	for (i = 0; i < 4; i++) {
+		writel((tmp & 1) << chip->leftshift, chip->ioaddress);
+		tmp >>= 1;
+	}
+
+	/* Commands dont have data */
+	if (!V3020_IS_COMMAND(address)) {
+		for (i = 0; i < 8; i++) {
+			writel((data & 1) << chip->leftshift, chip->ioaddress);
+			data >>= 1;
+		}
+	}
+}
+
+static unsigned char v3020_get_reg(struct v3020 *chip, unsigned char address)
+{
+	unsigned int data=0;
+	int i;
+
+	for (i = 0; i < 4; i++) {
+		writel((address & 1) << chip->leftshift, chip->ioaddress);
+		address >>= 1;
+	}
+
+	for (i = 0; i < 8; i++) {
+		data >>= 1;
+		if (readl(chip->ioaddress) & (1 << chip->leftshift))
+			data |= 0x80;
+	}
+
+	return data;
+}
+
+static int v3020_read_time(struct device *dev, struct rtc_time *dt)
+{
+	struct v3020 *chip = dev_get_drvdata(dev);
+	int tmp;
+
+	/* Copy the current time to ram... */
+	v3020_set_reg(chip, V3020_CMD_CLOCK2RAM, 0);
+
+	/* ...and then read constant values. */
+	tmp = v3020_get_reg(chip, V3020_SECONDS);
+	dt->tm_sec	= BCD2BIN(tmp);
+	tmp = v3020_get_reg(chip, V3020_MINUTES);
+	dt->tm_min	= BCD2BIN(tmp);
+	tmp = v3020_get_reg(chip, V3020_HOURS);
+	dt->tm_hour	= BCD2BIN(tmp);
+	tmp = v3020_get_reg(chip, V3020_MONTH_DAY);
+	dt->tm_mday	= BCD2BIN(tmp);
+	tmp = v3020_get_reg(chip, V3020_MONTH);
+	dt->tm_mon	= BCD2BIN(tmp);
+	tmp = v3020_get_reg(chip, V3020_WEEK_DAY);
+	dt->tm_wday	= BCD2BIN(tmp);
+	tmp = v3020_get_reg(chip, V3020_YEAR);
+	dt->tm_year = BCD2BIN(tmp)+100;
+
+#ifdef DEBUG
+	printk("\n%s : Read RTC values\n",__FUNCTION__);
+	printk("tm_hour: %i\n",dt->tm_hour);
+	printk("tm_min : %i\n",dt->tm_min);
+	printk("tm_sec : %i\n",dt->tm_sec);
+	printk("tm_year: %i\n",dt->tm_year);
+	printk("tm_mon : %i\n",dt->tm_mon);
+	printk("tm_mday: %i\n",dt->tm_mday);
+	printk("tm_wday: %i\n",dt->tm_wday);
+#endif
+
+	return 0;
+}
+
+
+static int v3020_set_time(struct device *dev, struct rtc_time *dt)
+{
+	struct v3020 *chip = dev_get_drvdata(dev);
+
+#ifdef DEBUG
+	printk("\n%s : Setting RTC values\n",__FUNCTION__);
+	printk("tm_sec : %i\n",dt->tm_sec);
+	printk("tm_min : %i\n",dt->tm_min);
+	printk("tm_hour: %i\n",dt->tm_hour);
+	printk("tm_mday: %i\n",dt->tm_mday);
+	printk("tm_wday: %i\n",dt->tm_wday);
+	printk("tm_year: %i\n",dt->tm_year);
+#endif
+
+	/* Write all the values to ram... */
+	v3020_set_reg(chip, V3020_SECONDS, 	BIN2BCD(dt->tm_sec));
+	v3020_set_reg(chip, V3020_MINUTES, 	BIN2BCD(dt->tm_min));
+	v3020_set_reg(chip, V3020_HOURS, 	BIN2BCD(dt->tm_hour));
+	v3020_set_reg(chip, V3020_MONTH_DAY,	BIN2BCD(dt->tm_mday));
+	v3020_set_reg(chip, V3020_MONTH, 	BIN2BCD(dt->tm_mon));
+	v3020_set_reg(chip, V3020_WEEK_DAY, 	BIN2BCD(dt->tm_wday));
+	v3020_set_reg(chip, V3020_YEAR, 	BIN2BCD(dt->tm_year % 100));
+
+	/* ...and set the clock. */
+	v3020_set_reg(chip, V3020_CMD_RAM2CLOCK, 0);
+
+	/* Compulab used this delay here. I dont know why,
+	 * the datasheet does not specify a delay. */
+	/*mdelay(5);*/
+
+	return 0;
+}
+
+static struct rtc_class_ops v3020_rtc_ops = {
+	.read_time	= v3020_read_time,
+	.set_time	= v3020_set_time,
+};
+
+static int rtc_probe(struct platform_device *pdev)
+{
+	struct v3020_platform_data *pdata = pdev->dev.platform_data;
+	struct v3020 *chip;
+	struct rtc_device *rtc;
+	int retval = -EBUSY;
+	int i;
+	int temp;
+
+	if (pdev->num_resources != 1)
+		return -EBUSY;
+
+	if (pdev->resource[0].flags != IORESOURCE_MEM)
+		return -EBUSY;
+
+	if (pdev == NULL)
+		return -EBUSY;
+
+	chip = kzalloc(sizeof *chip, GFP_KERNEL);
+	if (!chip)
+		return -ENOMEM;
+
+	chip->leftshift = pdata->leftshift;
+	chip->ioaddress = ioremap(pdev->resource[0].start, 1);
+	if (chip->ioaddress == NULL)
+		goto err_chip;
+
+	/* Make sure the v3020 expects a communication cycle
+	 * by reading 8 times */
+	for (i = 0; i < 8; i++)
+		temp = readl(chip->ioaddress);
+
+	/* Test chip by doing a write/read sequence
+	 * to the chip ram */
+	v3020_set_reg(chip, V3020_SECONDS, 0x33);
+	if(v3020_get_reg(chip, V3020_SECONDS) != 0x33) {
+		retval = -ENODEV;
+		goto err_io;
+	}
+
+	/* Make sure frequency measurment mode, test modes, and lock
+	 * are all disabled */
+	v3020_set_reg(chip, V3020_STATUS_0, 0x0);
+
+	dev_info(&pdev->dev, "Chip available at physical address 0x%p,"
+		"data connected to D%d\n",
+		(void*)pdev->resource[0].start,
+		chip->leftshift);
+
+	platform_set_drvdata(pdev, chip);
+
+	rtc = rtc_device_register("v3020",
+				&pdev->dev, &v3020_rtc_ops, THIS_MODULE);
+	if (IS_ERR(rtc)) {
+		retval = PTR_ERR(rtc);
+		goto err_io;
+	}
+	chip->rtc = rtc;
+
+	return 0;
+
+err_io:
+	iounmap(chip->ioaddress);
+err_chip:
+	kfree(chip);
+
+	return retval;
+}
+
+static int rtc_remove(struct platform_device *dev)
+{
+	struct v3020 *chip = platform_get_drvdata(dev);
+	struct rtc_device *rtc = chip->rtc;
+
+	if (rtc)
+		rtc_device_unregister(rtc);
+
+	iounmap(chip->ioaddress);
+	kfree(chip);
+
+	return 0;
+}
+
+static struct platform_driver rtc_device_driver = {
+	.probe	= rtc_probe,
+	.remove = rtc_remove,
+	.driver = {
+		.name	= "v3020",
+		.owner	= THIS_MODULE,
+	},
+};
+
+static __init int v3020_init(void)
+{
+	return platform_driver_register(&rtc_device_driver);
+}
+
+static __exit void v3020_exit(void)
+{
+	platform_driver_unregister(&rtc_device_driver);
+}
+
+module_init(v3020_init);
+module_exit(v3020_exit);
+
+MODULE_DESCRIPTION("V3020 RTC");
+MODULE_AUTHOR("Raphael Assenat");
+MODULE_LICENSE("GPL");
diff --git a/drivers/scsi/hptiop.c b/drivers/scsi/hptiop.c
new file mode 100644
index 000000000..28bfb8f9f
--- /dev/null
+++ b/drivers/scsi/hptiop.c
@@ -0,0 +1,942 @@
+/*
+ * HighPoint RR3xxx controller driver for Linux
+ * Copyright (C) 2006 HighPoint Technologies, 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 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.
+ *
+ * Please report bugs/comments/suggestions to linux@highpoint-tech.com
+ *
+ * For more information, visit http://www.highpoint-tech.com
+ */
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/string.h>
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/interrupt.h>
+#include <linux/errno.h>
+#include <linux/delay.h>
+#include <linux/timer.h>
+#include <linux/spinlock.h>
+#include <linux/hdreg.h>
+#include <asm/uaccess.h>
+#include <asm/io.h>
+#include <asm/div64.h>
+#include <scsi/scsi_cmnd.h>
+#include <scsi/scsi_device.h>
+#include <scsi/scsi.h>
+#include <scsi/scsi_tcq.h>
+#include <scsi/scsi_host.h>
+
+#include "hptiop.h"
+
+MODULE_AUTHOR("HighPoint Technologies, Inc.");
+MODULE_DESCRIPTION("HighPoint RocketRAID 3xxx SATA Controller Driver");
+
+static char driver_name[] = "hptiop";
+static const char driver_name_long[] = "RocketRAID 3xxx SATA Controller driver";
+static const char driver_ver[] = "v1.0 (060426)";
+
+static void hptiop_host_request_callback(struct hptiop_hba *hba, u32 tag);
+static void hptiop_iop_request_callback(struct hptiop_hba *hba, u32 tag);
+static void hptiop_message_callback(struct hptiop_hba *hba, u32 msg);
+
+static inline void hptiop_pci_posting_flush(struct hpt_iopmu __iomem *iop)
+{
+	readl(&iop->outbound_intstatus);
+}
+
+static int iop_wait_ready(struct hpt_iopmu __iomem *iop, u32 millisec)
+{
+	u32 req = 0;
+	int i;
+
+	for (i = 0; i < millisec; i++) {
+		req = readl(&iop->inbound_queue);
+		if (req != IOPMU_QUEUE_EMPTY)
+			break;
+		msleep(1);
+	}
+
+	if (req != IOPMU_QUEUE_EMPTY) {
+		writel(req, &iop->outbound_queue);
+		hptiop_pci_posting_flush(iop);
+		return 0;
+	}
+
+	return -1;
+}
+
+static void hptiop_request_callback(struct hptiop_hba *hba, u32 tag)
+{
+	if ((tag & IOPMU_QUEUE_MASK_HOST_BITS) == IOPMU_QUEUE_ADDR_HOST_BIT)
+		return hptiop_host_request_callback(hba,
+				tag & ~IOPMU_QUEUE_ADDR_HOST_BIT);
+	else
+		return hptiop_iop_request_callback(hba, tag);
+}
+
+static inline void hptiop_drain_outbound_queue(struct hptiop_hba *hba)
+{
+	u32 req;
+
+	while ((req = readl(&hba->iop->outbound_queue)) != IOPMU_QUEUE_EMPTY) {
+
+		if (req & IOPMU_QUEUE_MASK_HOST_BITS)
+			hptiop_request_callback(hba, req);
+		else {
+			struct hpt_iop_request_header __iomem * p;
+
+			p = (struct hpt_iop_request_header __iomem *)
+				((char __iomem *)hba->iop + req);
+
+			if (readl(&p->flags) & IOP_REQUEST_FLAG_SYNC_REQUEST) {
+				if (readl(&p->context))
+					hptiop_request_callback(hba, req);
+				else
+					writel(1, &p->context);
+			}
+			else
+				hptiop_request_callback(hba, req);
+		}
+	}
+}
+
+static int __iop_intr(struct hptiop_hba *hba)
+{
+	struct hpt_iopmu __iomem *iop = hba->iop;
+	u32 status;
+	int ret = 0;
+
+	status = readl(&iop->outbound_intstatus);
+
+	if (status & IOPMU_OUTBOUND_INT_MSG0) {
+		u32 msg = readl(&iop->outbound_msgaddr0);
+		dprintk("received outbound msg %x\n", msg);
+		writel(IOPMU_OUTBOUND_INT_MSG0, &iop->outbound_intstatus);
+		hptiop_message_callback(hba, msg);
+		ret = 1;
+	}
+
+	if (status & IOPMU_OUTBOUND_INT_POSTQUEUE) {
+		hptiop_drain_outbound_queue(hba);
+		ret = 1;
+	}
+
+	return ret;
+}
+
+static int iop_send_sync_request(struct hptiop_hba *hba,
+					void __iomem *_req, u32 millisec)
+{
+	struct hpt_iop_request_header __iomem *req = _req;
+	u32 i;
+
+	writel(readl(&req->flags) | IOP_REQUEST_FLAG_SYNC_REQUEST,
+			&req->flags);
+
+	writel(0, &req->context);
+
+	writel((unsigned long)req - (unsigned long)hba->iop,
+			&hba->iop->inbound_queue);
+
+	hptiop_pci_posting_flush(hba->iop);
+
+	for (i = 0; i < millisec; i++) {
+		__iop_intr(hba);
+		if (readl(&req->context))
+			return 0;
+		msleep(1);
+	}
+
+	return -1;
+}
+
+static int iop_send_sync_msg(struct hptiop_hba *hba, u32 msg, u32 millisec)
+{
+	u32 i;
+
+	hba->msg_done = 0;
+
+	writel(msg, &hba->iop->inbound_msgaddr0);
+
+	hptiop_pci_posting_flush(hba->iop);
+
+	for (i = 0; i < millisec; i++) {
+		spin_lock_irq(hba->host->host_lock);
+		__iop_intr(hba);
+		spin_unlock_irq(hba->host->host_lock);
+		if (hba->msg_done)
+			break;
+		msleep(1);
+	}
+
+	return hba->msg_done? 0 : -1;
+}
+
+static int iop_get_config(struct hptiop_hba *hba,
+				struct hpt_iop_request_get_config *config)
+{
+	u32 req32;
+	struct hpt_iop_request_get_config __iomem *req;
+
+	req32 = readl(&hba->iop->inbound_queue);
+	if (req32 == IOPMU_QUEUE_EMPTY)
+		return -1;
+
+	req = (struct hpt_iop_request_get_config __iomem *)
+			((unsigned long)hba->iop + req32);
+
+	writel(0, &req->header.flags);
+	writel(IOP_REQUEST_TYPE_GET_CONFIG, &req->header.type);
+	writel(sizeof(struct hpt_iop_request_get_config), &req->header.size);
+	writel(IOP_RESULT_PENDING, &req->header.result);
+
+	if (iop_send_sync_request(hba, req, 20000)) {
+		dprintk("Get config send cmd failed\n");
+		return -1;
+	}
+
+	memcpy_fromio(config, req, sizeof(*config));
+	writel(req32, &hba->iop->outbound_queue);
+	return 0;
+}
+
+static int iop_set_config(struct hptiop_hba *hba,
+				struct hpt_iop_request_set_config *config)
+{
+	u32 req32;
+	struct hpt_iop_request_set_config __iomem *req;
+
+	req32 = readl(&hba->iop->inbound_queue);
+	if (req32 == IOPMU_QUEUE_EMPTY)
+		return -1;
+
+	req = (struct hpt_iop_request_set_config __iomem *)
+			((unsigned long)hba->iop + req32);
+
+	memcpy_toio((u8 __iomem *)req + sizeof(struct hpt_iop_request_header),
+		(u8 *)config + sizeof(struct hpt_iop_request_header),
+		sizeof(struct hpt_iop_request_set_config) -
+			sizeof(struct hpt_iop_request_header));
+
+	writel(0, &req->header.flags);
+	writel(IOP_REQUEST_TYPE_SET_CONFIG, &req->header.type);
+	writel(sizeof(struct hpt_iop_request_set_config), &req->header.size);
+	writel(IOP_RESULT_PENDING, &req->header.result);
+
+	if (iop_send_sync_request(hba, req, 20000)) {
+		dprintk("Set config send cmd failed\n");
+		return -1;
+	}
+
+	writel(req32, &hba->iop->outbound_queue);
+	return 0;
+}
+
+static int hptiop_initialize_iop(struct hptiop_hba *hba)
+{
+	struct hpt_iopmu __iomem *iop = hba->iop;
+
+	/* enable interrupts */
+	writel(~(IOPMU_OUTBOUND_INT_POSTQUEUE | IOPMU_OUTBOUND_INT_MSG0),
+			&iop->outbound_intmask);
+
+	hba->initialized = 1;
+
+	/* start background tasks */
+	if (iop_send_sync_msg(hba,
+			IOPMU_INBOUND_MSG0_START_BACKGROUND_TASK, 5000)) {
+		printk(KERN_ERR "scsi%d: fail to start background task\n",
+			hba->host->host_no);
+		return -1;
+	}
+	return 0;
+}
+
+static int hptiop_map_pci_bar(struct hptiop_hba *hba)
+{
+	u32 mem_base_phy, length;
+	void __iomem *mem_base_virt;
+	struct pci_dev *pcidev = hba->pcidev;
+
+	if (!(pci_resource_flags(pcidev, 0) & IORESOURCE_MEM)) {
+		printk(KERN_ERR "scsi%d: pci resource invalid\n",
+				hba->host->host_no);
+		return -1;
+	}
+
+	mem_base_phy = pci_resource_start(pcidev, 0);
+	length = pci_resource_len(pcidev, 0);
+	mem_base_virt = ioremap(mem_base_phy, length);
+
+	if (!mem_base_virt) {
+		printk(KERN_ERR "scsi%d: Fail to ioremap memory space\n",
+				hba->host->host_no);
+		return -1;
+	}
+
+	hba->iop = mem_base_virt;
+	dprintk("hptiop_map_pci_bar: iop=%p\n", hba->iop);
+	return 0;
+}
+
+static void hptiop_message_callback(struct hptiop_hba *hba, u32 msg)
+{
+	dprintk("iop message 0x%x\n", msg);
+
+	if (!hba->initialized)
+		return;
+
+	if (msg == IOPMU_INBOUND_MSG0_RESET) {
+		atomic_set(&hba->resetting, 0);
+		wake_up(&hba->reset_wq);
+	}
+	else if (msg <= IOPMU_INBOUND_MSG0_MAX)
+		hba->msg_done = 1;
+}
+
+static inline struct hptiop_request *get_req(struct hptiop_hba *hba)
+{
+	struct hptiop_request *ret;
+
+	dprintk("get_req : req=%p\n", hba->req_list);
+
+	ret = hba->req_list;
+	if (ret)
+		hba->req_list = ret->next;
+
+	return ret;
+}
+
+static inline void free_req(struct hptiop_hba *hba, struct hptiop_request *req)
+{
+	dprintk("free_req(%d, %p)\n", req->index, req);
+	req->next = hba->req_list;
+	hba->req_list = req;
+}
+
+static void hptiop_host_request_callback(struct hptiop_hba *hba, u32 tag)
+{
+	struct hpt_iop_request_scsi_command *req;
+	struct scsi_cmnd *scp;
+
+	req = (struct hpt_iop_request_scsi_command *)hba->reqs[tag].req_virt;
+	dprintk("hptiop_host_request_callback: req=%p, type=%d, "
+			"result=%d, context=0x%x tag=%d\n",
+			req, req->header.type, req->header.result,
+			req->header.context, tag);
+
+	BUG_ON(!req->header.result);
+	BUG_ON(req->header.type != cpu_to_le32(IOP_REQUEST_TYPE_SCSI_COMMAND));
+
+	scp = hba->reqs[tag].scp;
+
+	if (HPT_SCP(scp)->mapped) {
+		if (scp->use_sg)
+			pci_unmap_sg(hba->pcidev,
+				(struct scatterlist *)scp->request_buffer,
+				scp->use_sg,
+				scp->sc_data_direction
+			);
+		else
+			pci_unmap_single(hba->pcidev,
+				HPT_SCP(scp)->dma_handle,
+				scp->request_bufflen,
+				scp->sc_data_direction
+			);
+	}
+
+	switch (le32_to_cpu(req->header.result)) {
+	case IOP_RESULT_SUCCESS:
+		scp->result = (DID_OK<<16);
+		break;
+	case IOP_RESULT_BAD_TARGET:
+		scp->result = (DID_BAD_TARGET<<16);
+		break;
+	case IOP_RESULT_BUSY:
+		scp->result = (DID_BUS_BUSY<<16);
+		break;
+	case IOP_RESULT_RESET:
+		scp->result = (DID_RESET<<16);
+		break;
+	case IOP_RESULT_FAIL:
+		scp->result = (DID_ERROR<<16);
+		break;
+	case IOP_RESULT_INVALID_REQUEST:
+		scp->result = (DID_ABORT<<16);
+		break;
+	case IOP_RESULT_MODE_SENSE_CHECK_CONDITION:
+		scp->result = SAM_STAT_CHECK_CONDITION;
+		memset(&scp->sense_buffer,
+				0, sizeof(scp->sense_buffer));
+		memcpy(&scp->sense_buffer,
+			&req->sg_list, le32_to_cpu(req->dataxfer_length));
+		break;
+
+	default:
+		scp->result = ((DRIVER_INVALID|SUGGEST_ABORT)<<24) |
+					(DID_ABORT<<16);
+		break;
+	}
+
+	dprintk("scsi_done(%p)\n", scp);
+	scp->scsi_done(scp);
+	free_req(hba, &hba->reqs[tag]);
+}
+
+void hptiop_iop_request_callback(struct hptiop_hba *hba, u32 tag)
+{
+	struct hpt_iop_request_header __iomem *req;
+	struct hpt_iop_request_ioctl_command __iomem *p;
+	struct hpt_ioctl_k *arg;
+
+	req = (struct hpt_iop_request_header __iomem *)
+			((unsigned long)hba->iop + tag);
+	dprintk("hptiop_iop_request_callback: req=%p, type=%d, "
+			"result=%d, context=0x%x tag=%d\n",
+			req, readl(&req->type), readl(&req->result),
+			readl(&req->context), tag);
+
+	BUG_ON(!readl(&req->result));
+	BUG_ON(readl(&req->type) != IOP_REQUEST_TYPE_IOCTL_COMMAND);
+
+	p = (struct hpt_iop_request_ioctl_command __iomem *)req;
+	arg = (struct hpt_ioctl_k *)(unsigned long)
+		(readl(&req->context) |
+			((u64)readl(&req->context_hi32)<<32));
+
+	if (readl(&req->result) == IOP_RESULT_SUCCESS) {
+		arg->result = HPT_IOCTL_RESULT_OK;
+
+		if (arg->outbuf_size)
+			memcpy_fromio(arg->outbuf,
+				&p->buf[(readl(&p->inbuf_size) + 3)& ~3],
+				arg->outbuf_size);
+
+		if (arg->bytes_returned)
+			*arg->bytes_returned = arg->outbuf_size;
+	}
+	else
+		arg->result = HPT_IOCTL_RESULT_FAILED;
+
+	arg->done(arg);
+	writel(tag, &hba->iop->outbound_queue);
+}
+
+static irqreturn_t hptiop_intr(int irq, void *dev_id, struct pt_regs *regs)
+{
+	struct hptiop_hba  *hba = dev_id;
+	int  handled;
+	unsigned long flags;
+
+	spin_lock_irqsave(hba->host->host_lock, flags);
+	handled = __iop_intr(hba);
+	spin_unlock_irqrestore(hba->host->host_lock, flags);
+
+	return handled;
+}
+
+static int hptiop_buildsgl(struct scsi_cmnd *scp, struct hpt_iopsg *psg)
+{
+	struct Scsi_Host *host = scp->device->host;
+	struct hptiop_hba *hba = (struct hptiop_hba *)host->hostdata;
+	struct scatterlist *sglist = (struct scatterlist *)scp->request_buffer;
+
+	/*
+	 * though we'll not get non-use_sg fields anymore,
+	 * keep use_sg checking anyway
+	 */
+	if (scp->use_sg) {
+		int idx;
+
+		HPT_SCP(scp)->sgcnt = pci_map_sg(hba->pcidev,
+				sglist, scp->use_sg,
+				scp->sc_data_direction);
+		HPT_SCP(scp)->mapped = 1;
+		BUG_ON(HPT_SCP(scp)->sgcnt > hba->max_sg_descriptors);
+
+		for (idx = 0; idx < HPT_SCP(scp)->sgcnt; idx++) {
+			psg[idx].pci_address =
+				cpu_to_le64(sg_dma_address(&sglist[idx]));
+			psg[idx].size = cpu_to_le32(sg_dma_len(&sglist[idx]));
+			psg[idx].eot = (idx == HPT_SCP(scp)->sgcnt - 1) ?
+				cpu_to_le32(1) : 0;
+		}
+
+		return HPT_SCP(scp)->sgcnt;
+	} else {
+		HPT_SCP(scp)->dma_handle = pci_map_single(
+				hba->pcidev,
+				scp->request_buffer,
+				scp->request_bufflen,
+				scp->sc_data_direction
+			);
+		HPT_SCP(scp)->mapped = 1;
+		psg->pci_address = cpu_to_le64(HPT_SCP(scp)->dma_handle);
+		psg->size = cpu_to_le32(scp->request_bufflen);
+		psg->eot = cpu_to_le32(1);
+		return 1;
+	}
+}
+
+static int hptiop_queuecommand(struct scsi_cmnd *scp,
+				void (*done)(struct scsi_cmnd *))
+{
+	struct Scsi_Host *host = scp->device->host;
+	struct hptiop_hba *hba = (struct hptiop_hba *)host->hostdata;
+	struct hpt_iop_request_scsi_command *req;
+	int sg_count = 0;
+	struct hptiop_request *_req;
+
+	BUG_ON(!done);
+	scp->scsi_done = done;
+
+	_req = get_req(hba);
+	if (_req == NULL) {
+		dprintk("hptiop_queuecmd : no free req\n");
+		return SCSI_MLQUEUE_HOST_BUSY;
+	}
+
+	_req->scp = scp;
+
+	dprintk("hptiop_queuecmd(scp=%p) %d/%d/%d/%d cdb=(%x-%x-%x) "
+			"req_index=%d, req=%p\n",
+			scp,
+			host->host_no, scp->device->channel,
+			scp->device->id, scp->device->lun,
+			*((u32 *)&scp->cmnd),
+			*((u32 *)&scp->cmnd + 1),
+			*((u32 *)&scp->cmnd + 2),
+			_req->index, _req->req_virt);
+
+	scp->result = 0;
+
+	if (scp->device->channel || scp->device->lun ||
+			scp->device->id > hba->max_devices) {
+		scp->result = DID_BAD_TARGET << 16;
+		free_req(hba, _req);
+		goto cmd_done;
+	}
+
+	req = (struct hpt_iop_request_scsi_command *)_req->req_virt;
+
+	/* build S/G table */
+	if (scp->request_bufflen)
+		sg_count = hptiop_buildsgl(scp, req->sg_list);
+	else
+		HPT_SCP(scp)->mapped = 0;
+
+	req->header.flags = cpu_to_le32(IOP_REQUEST_FLAG_OUTPUT_CONTEXT);
+	req->header.type = cpu_to_le32(IOP_REQUEST_TYPE_SCSI_COMMAND);
+	req->header.result = cpu_to_le32(IOP_RESULT_PENDING);
+	req->header.context = cpu_to_le32(IOPMU_QUEUE_ADDR_HOST_BIT |
+							(u32)_req->index);
+	req->header.context_hi32 = 0;
+	req->dataxfer_length = cpu_to_le32(scp->request_bufflen);
+	req->channel = scp->device->channel;
+	req->target = scp->device->id;
+	req->lun = scp->device->lun;
+	req->header.size = cpu_to_le32(
+				sizeof(struct hpt_iop_request_scsi_command)
+				 - sizeof(struct hpt_iopsg)
+				 + sg_count * sizeof(struct hpt_iopsg));
+
+	memcpy(req->cdb, scp->cmnd, sizeof(req->cdb));
+
+	writel(IOPMU_QUEUE_ADDR_HOST_BIT | _req->req_shifted_phy,
+			&hba->iop->inbound_queue);
+
+	return 0;
+
+cmd_done:
+	dprintk("scsi_done(scp=%p)\n", scp);
+	scp->scsi_done(scp);
+	return 0;
+}
+
+static const char *hptiop_info(struct Scsi_Host *host)
+{
+	return driver_name_long;
+}
+
+static int hptiop_reset_hba(struct hptiop_hba *hba)
+{
+	if (atomic_xchg(&hba->resetting, 1) == 0) {
+		atomic_inc(&hba->reset_count);
+		writel(IOPMU_INBOUND_MSG0_RESET,
+				&hba->iop->inbound_msgaddr0);
+		hptiop_pci_posting_flush(hba->iop);
+	}
+
+	wait_event_timeout(hba->reset_wq,
+			atomic_read(&hba->resetting) == 0, 60 * HZ);
+
+	if (atomic_read(&hba->resetting)) {
+		/* IOP is in unkown state, abort reset */
+		printk(KERN_ERR "scsi%d: reset failed\n", hba->host->host_no);
+		return -1;
+	}
+
+	if (iop_send_sync_msg(hba,
+		IOPMU_INBOUND_MSG0_START_BACKGROUND_TASK, 5000)) {
+		dprintk("scsi%d: fail to start background task\n",
+				hba->host->host_no);
+	}
+
+	return 0;
+}
+
+static int hptiop_reset(struct scsi_cmnd *scp)
+{
+	struct Scsi_Host * host = scp->device->host;
+	struct hptiop_hba * hba = (struct hptiop_hba *)host->hostdata;
+
+	printk(KERN_WARNING "hptiop_reset(%d/%d/%d) scp=%p\n",
+			scp->device->host->host_no, scp->device->channel,
+			scp->device->id, scp);
+
+	return hptiop_reset_hba(hba)? FAILED : SUCCESS;
+}
+
+static int hptiop_adjust_disk_queue_depth(struct scsi_device *sdev,
+						int queue_depth)
+{
+	if(queue_depth > 256)
+		queue_depth = 256;
+	scsi_adjust_queue_depth(sdev, MSG_ORDERED_TAG, queue_depth);
+	return queue_depth;
+}
+
+static ssize_t hptiop_show_version(struct class_device *class_dev, char *buf)
+{
+	return snprintf(buf, PAGE_SIZE, "%s\n", driver_ver);
+}
+
+static ssize_t hptiop_show_fw_version(struct class_device *class_dev, char *buf)
+{
+	struct Scsi_Host *host = class_to_shost(class_dev);
+	struct hptiop_hba *hba = (struct hptiop_hba *)host->hostdata;
+
+	return snprintf(buf, PAGE_SIZE, "%d.%d.%d.%d\n",
+				hba->firmware_version >> 24,
+				(hba->firmware_version >> 16) & 0xff,
+				(hba->firmware_version >> 8) & 0xff,
+				hba->firmware_version & 0xff);
+}
+
+static struct class_device_attribute hptiop_attr_version = {
+	.attr = {
+		.name = "driver-version",
+		.mode = S_IRUGO,
+	},
+	.show = hptiop_show_version,
+};
+
+static struct class_device_attribute hptiop_attr_fw_version = {
+	.attr = {
+		.name = "firmware-version",
+		.mode = S_IRUGO,
+	},
+	.show = hptiop_show_fw_version,
+};
+
+static struct class_device_attribute *hptiop_attrs[] = {
+	&hptiop_attr_version,
+	&hptiop_attr_fw_version,
+	NULL
+};
+
+static struct scsi_host_template driver_template = {
+	.module                     = THIS_MODULE,
+	.name                       = driver_name,
+	.queuecommand               = hptiop_queuecommand,
+	.eh_device_reset_handler    = hptiop_reset,
+	.eh_bus_reset_handler       = hptiop_reset,
+	.info                       = hptiop_info,
+	.unchecked_isa_dma          = 0,
+	.emulated                   = 0,
+	.use_clustering             = ENABLE_CLUSTERING,
+	.proc_name                  = driver_name,
+	.shost_attrs                = hptiop_attrs,
+	.this_id                    = -1,
+	.change_queue_depth         = hptiop_adjust_disk_queue_depth,
+};
+
+static int __devinit hptiop_probe(struct pci_dev *pcidev,
+					const struct pci_device_id *id)
+{
+	struct Scsi_Host *host = NULL;
+	struct hptiop_hba *hba;
+	struct hpt_iop_request_get_config iop_config;
+	struct hpt_iop_request_set_config set_config;
+	dma_addr_t start_phy;
+	void *start_virt;
+	u32 offset, i, req_size;
+
+	dprintk("hptiop_probe(%p)\n", pcidev);
+
+	if (pci_enable_device(pcidev)) {
+		printk(KERN_ERR "hptiop: fail to enable pci device\n");
+		return -ENODEV;
+	}
+
+	printk(KERN_INFO "adapter at PCI %d:%d:%d, IRQ %d\n",
+		pcidev->bus->number, pcidev->devfn >> 3, pcidev->devfn & 7,
+		pcidev->irq);
+
+	pci_set_master(pcidev);
+
+	/* Enable 64bit DMA if possible */
+	if (pci_set_dma_mask(pcidev, DMA_64BIT_MASK)) {
+		if (pci_set_dma_mask(pcidev, DMA_32BIT_MASK)) {
+			printk(KERN_ERR "hptiop: fail to set dma_mask\n");
+			goto disable_pci_device;
+		}
+	}
+
+	if (pci_request_regions(pcidev, driver_name)) {
+		printk(KERN_ERR "hptiop: pci_request_regions failed\n");
+		goto disable_pci_device;
+	}
+
+	host = scsi_host_alloc(&driver_template, sizeof(struct hptiop_hba));
+	if (!host) {
+		printk(KERN_ERR "hptiop: fail to alloc scsi host\n");
+		goto free_pci_regions;
+	}
+
+	hba = (struct hptiop_hba *)host->hostdata;
+
+	hba->pcidev = pcidev;
+	hba->host = host;
+	hba->initialized = 0;
+
+	atomic_set(&hba->resetting, 0);
+	atomic_set(&hba->reset_count, 0);
+
+	init_waitqueue_head(&hba->reset_wq);
+	init_waitqueue_head(&hba->ioctl_wq);
+
+	host->max_lun = 1;
+	host->max_channel = 0;
+	host->io_port = 0;
+	host->n_io_port = 0;
+	host->irq = pcidev->irq;
+
+	if (hptiop_map_pci_bar(hba))
+		goto free_scsi_host;
+
+	if (iop_wait_ready(hba->iop, 20000)) {
+		printk(KERN_ERR "scsi%d: firmware not ready\n",
+				hba->host->host_no);
+		goto unmap_pci_bar;
+	}
+
+	if (iop_get_config(hba, &iop_config)) {
+		printk(KERN_ERR "scsi%d: get config failed\n",
+				hba->host->host_no);
+		goto unmap_pci_bar;
+	}
+
+	hba->max_requests = min(le32_to_cpu(iop_config.max_requests),
+				HPTIOP_MAX_REQUESTS);
+	hba->max_devices = le32_to_cpu(iop_config.max_devices);
+	hba->max_request_size = le32_to_cpu(iop_config.request_size);
+	hba->max_sg_descriptors = le32_to_cpu(iop_config.max_sg_count);
+	hba->firmware_version = le32_to_cpu(iop_config.firmware_version);
+	hba->sdram_size = le32_to_cpu(iop_config.sdram_size);
+
+	host->max_sectors = le32_to_cpu(iop_config.data_transfer_length) >> 9;
+	host->max_id = le32_to_cpu(iop_config.max_devices);
+	host->sg_tablesize = le32_to_cpu(iop_config.max_sg_count);
+	host->can_queue = le32_to_cpu(iop_config.max_requests);
+	host->cmd_per_lun = le32_to_cpu(iop_config.max_requests);
+	host->max_cmd_len = 16;
+
+	set_config.vbus_id = cpu_to_le32(host->host_no);
+	set_config.iop_id = cpu_to_le32(host->host_no);
+
+	if (iop_set_config(hba, &set_config)) {
+		printk(KERN_ERR "scsi%d: set config failed\n",
+				hba->host->host_no);
+		goto unmap_pci_bar;
+	}
+
+	pci_set_drvdata(pcidev, host);
+
+	if (request_irq(pcidev->irq, hptiop_intr, IRQF_SHARED,
+					driver_name, hba)) {
+		printk(KERN_ERR "scsi%d: request irq %d failed\n",
+					hba->host->host_no, pcidev->irq);
+		goto unmap_pci_bar;
+	}
+
+	/* Allocate request mem */
+	req_size = sizeof(struct hpt_iop_request_scsi_command)
+		+ sizeof(struct hpt_iopsg) * (hba->max_sg_descriptors - 1);
+	if ((req_size& 0x1f) != 0)
+		req_size = (req_size + 0x1f) & ~0x1f;
+
+	dprintk("req_size=%d, max_requests=%d\n", req_size, hba->max_requests);
+
+	hba->req_size = req_size;
+	start_virt = dma_alloc_coherent(&pcidev->dev,
+				hba->req_size*hba->max_requests + 0x20,
+				&start_phy, GFP_KERNEL);
+
+	if (!start_virt) {
+		printk(KERN_ERR "scsi%d: fail to alloc request mem\n",
+					hba->host->host_no);
+		goto free_request_irq;
+	}
+
+	hba->dma_coherent = start_virt;
+	hba->dma_coherent_handle = start_phy;
+
+	if ((start_phy & 0x1f) != 0)
+	{
+		offset = ((start_phy + 0x1f) & ~0x1f) - start_phy;
+		start_phy += offset;
+		start_virt += offset;
+	}
+
+	hba->req_list = start_virt;
+	for (i = 0; i < hba->max_requests; i++) {
+		hba->reqs[i].next = NULL;
+		hba->reqs[i].req_virt = start_virt;
+		hba->reqs[i].req_shifted_phy = start_phy >> 5;
+		hba->reqs[i].index = i;
+		free_req(hba, &hba->reqs[i]);
+		start_virt = (char *)start_virt + hba->req_size;
+		start_phy = start_phy + hba->req_size;
+	}
+
+	/* Enable Interrupt and start background task */
+	if (hptiop_initialize_iop(hba))
+		goto free_request_mem;
+
+	if (scsi_add_host(host, &pcidev->dev)) {
+		printk(KERN_ERR "scsi%d: scsi_add_host failed\n",
+					hba->host->host_no);
+		goto free_request_mem;
+	}
+
+
+	scsi_scan_host(host);
+
+	dprintk("scsi%d: hptiop_probe successfully\n", hba->host->host_no);
+	return 0;
+
+free_request_mem:
+	dma_free_coherent(&hba->pcidev->dev,
+			hba->req_size*hba->max_requests + 0x20,
+			hba->dma_coherent, hba->dma_coherent_handle);
+
+free_request_irq:
+	free_irq(hba->pcidev->irq, hba);
+
+unmap_pci_bar:
+	iounmap(hba->iop);
+
+free_pci_regions:
+	pci_release_regions(pcidev) ;
+
+free_scsi_host:
+	scsi_host_put(host);
+
+disable_pci_device:
+	pci_disable_device(pcidev);
+
+	dprintk("scsi%d: hptiop_probe fail\n", host->host_no);
+	return -ENODEV;
+}
+
+static void hptiop_shutdown(struct pci_dev *pcidev)
+{
+	struct Scsi_Host *host = pci_get_drvdata(pcidev);
+	struct hptiop_hba *hba = (struct hptiop_hba *)host->hostdata;
+	struct hpt_iopmu __iomem *iop = hba->iop;
+	u32    int_mask;
+
+	dprintk("hptiop_shutdown(%p)\n", hba);
+
+	/* stop the iop */
+	if (iop_send_sync_msg(hba, IOPMU_INBOUND_MSG0_SHUTDOWN, 60000))
+		printk(KERN_ERR "scsi%d: shutdown the iop timeout\n",
+					hba->host->host_no);
+
+	/* disable all outbound interrupts */
+	int_mask = readl(&iop->outbound_intmask);
+	writel(int_mask |
+		IOPMU_OUTBOUND_INT_MSG0 | IOPMU_OUTBOUND_INT_POSTQUEUE,
+		&iop->outbound_intmask);
+	hptiop_pci_posting_flush(iop);
+}
+
+static void hptiop_remove(struct pci_dev *pcidev)
+{
+	struct Scsi_Host *host = pci_get_drvdata(pcidev);
+	struct hptiop_hba *hba = (struct hptiop_hba *)host->hostdata;
+
+	dprintk("scsi%d: hptiop_remove\n", hba->host->host_no);
+
+	scsi_remove_host(host);
+
+	hptiop_shutdown(pcidev);
+
+	free_irq(hba->pcidev->irq, hba);
+
+	dma_free_coherent(&hba->pcidev->dev,
+			hba->req_size * hba->max_requests + 0x20,
+			hba->dma_coherent,
+			hba->dma_coherent_handle);
+
+	iounmap(hba->iop);
+
+	pci_release_regions(hba->pcidev);
+	pci_set_drvdata(hba->pcidev, NULL);
+	pci_disable_device(hba->pcidev);
+
+	scsi_host_put(host);
+}
+
+static struct pci_device_id hptiop_id_table[] = {
+	{ PCI_DEVICE(0x1103, 0x3220) },
+	{ PCI_DEVICE(0x1103, 0x3320) },
+	{},
+};
+
+MODULE_DEVICE_TABLE(pci, hptiop_id_table);
+
+static struct pci_driver hptiop_pci_driver = {
+	.name       = driver_name,
+	.id_table   = hptiop_id_table,
+	.probe      = hptiop_probe,
+	.remove     = hptiop_remove,
+	.shutdown   = hptiop_shutdown,
+};
+
+static int __init hptiop_module_init(void)
+{
+	printk(KERN_INFO "%s %s\n", driver_name_long, driver_ver);
+	return pci_register_driver(&hptiop_pci_driver);
+}
+
+static void __exit hptiop_module_exit(void)
+{
+	pci_unregister_driver(&hptiop_pci_driver);
+}
+
+
+module_init(hptiop_module_init);
+module_exit(hptiop_module_exit);
+
+MODULE_LICENSE("GPL");
diff --git a/drivers/scsi/hptiop.h b/drivers/scsi/hptiop.h
new file mode 100644
index 000000000..f04f7e81d
--- /dev/null
+++ b/drivers/scsi/hptiop.h
@@ -0,0 +1,465 @@
+/*
+ * HighPoint RR3xxx controller driver for Linux
+ * Copyright (C) 2006 HighPoint Technologies, 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 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.
+ *
+ * Please report bugs/comments/suggestions to linux@highpoint-tech.com
+ *
+ * For more information, visit http://www.highpoint-tech.com
+ */
+#ifndef _HPTIOP_H_
+#define _HPTIOP_H_
+
+/*
+ * logical device type.
+ * Identify array (logical device) and physical device.
+ */
+#define LDT_ARRAY   1
+#define LDT_DEVICE  2
+
+/*
+ * Array types
+ */
+#define AT_UNKNOWN  0
+#define AT_RAID0    1
+#define AT_RAID1    2
+#define AT_RAID5    3
+#define AT_RAID6    4
+#define AT_JBOD     7
+
+#define MAX_NAME_LENGTH     36
+#define MAX_ARRAYNAME_LEN   16
+
+#define MAX_ARRAY_MEMBERS_V1 8
+#define MAX_ARRAY_MEMBERS_V2 16
+
+/* keep definition for source code compatiblity */
+#define MAX_ARRAY_MEMBERS MAX_ARRAY_MEMBERS_V1
+
+/*
+ * array flags
+ */
+#define ARRAY_FLAG_DISABLED         0x00000001 /* The array is disabled */
+#define ARRAY_FLAG_NEEDBUILDING     0x00000002 /* need to be rebuilt */
+#define ARRAY_FLAG_REBUILDING       0x00000004 /* in rebuilding process */
+#define ARRAY_FLAG_BROKEN           0x00000008 /* broken but still working */
+#define ARRAY_FLAG_BOOTDISK         0x00000010 /* has a active partition */
+#define ARRAY_FLAG_BOOTMARK         0x00000040 /* array has boot mark set */
+#define ARRAY_FLAG_NEED_AUTOREBUILD 0x00000080 /* auto-rebuild should start */
+#define ARRAY_FLAG_VERIFYING        0x00000100 /* is being verified */
+#define ARRAY_FLAG_INITIALIZING     0x00000200 /* is being initialized */
+#define ARRAY_FLAG_TRANSFORMING     0x00000400 /* tranform in progress */
+#define ARRAY_FLAG_NEEDTRANSFORM    0x00000800 /* array need tranform */
+#define ARRAY_FLAG_NEEDINITIALIZING 0x00001000 /* initialization not done */
+#define ARRAY_FLAG_BROKEN_REDUNDANT 0x00002000 /* broken but redundant */
+
+/*
+ * device flags
+ */
+#define DEVICE_FLAG_DISABLED        0x00000001 /* device is disabled */
+#define DEVICE_FLAG_UNINITIALIZED   0x00010000 /* device is not initialized */
+#define DEVICE_FLAG_LEGACY          0x00020000 /* lagacy drive */
+#define DEVICE_FLAG_IS_SPARE        0x80000000 /* is a spare disk */
+
+/*
+ * ioctl codes
+ */
+#define HPT_CTL_CODE(x) (x+0xFF00)
+#define HPT_CTL_CODE_LINUX_TO_IOP(x) ((x)-0xff00)
+
+#define HPT_IOCTL_GET_CONTROLLER_INFO       HPT_CTL_CODE(2)
+#define HPT_IOCTL_GET_CHANNEL_INFO          HPT_CTL_CODE(3)
+#define HPT_IOCTL_GET_LOGICAL_DEVICES       HPT_CTL_CODE(4)
+#define HPT_IOCTL_GET_DRIVER_CAPABILITIES   HPT_CTL_CODE(19)
+#define HPT_IOCTL_GET_DEVICE_INFO_V3        HPT_CTL_CODE(46)
+#define HPT_IOCTL_GET_CONTROLLER_INFO_V2    HPT_CTL_CODE(47)
+
+/*
+ * Controller information.
+ */
+struct hpt_controller_info {
+	u8      chip_type;                    /* chip type */
+	u8      interrupt_level;              /* IRQ level */
+	u8      num_buses;                    /* bus count */
+	u8      chip_flags;
+
+	u8      product_id[MAX_NAME_LENGTH];/* product name */
+	u8      vendor_id[MAX_NAME_LENGTH]; /* vendor name */
+}
+__attribute__((packed));
+
+/*
+ * Channel information.
+ */
+struct hpt_channel_info {
+	__le32  io_port;         /* IDE Base Port Address */
+	__le32  control_port;    /* IDE Control Port Address */
+	__le32  devices[2];      /* device connected to this channel */
+}
+__attribute__((packed));
+
+/*
+ * Array information.
+ */
+struct hpt_array_info_v3 {
+	u8      name[MAX_ARRAYNAME_LEN]; /* array name */
+	u8      description[64];         /* array description */
+	u8      create_manager[16];      /* who created it */
+	__le32  create_time;             /* when created it */
+
+	u8      array_type;              /* array type */
+	u8      block_size_shift;        /* stripe size */
+	u8      ndisk;                   /* Number of ID in Members[] */
+	u8      reserved;
+
+	__le32  flags;                   /* working flags, see ARRAY_FLAG_XXX */
+	__le32  members[MAX_ARRAY_MEMBERS_V2];  /* member array/disks */
+
+	__le32  rebuilding_progress;
+	__le64  rebuilt_sectors; /* rebuilding point (LBA) for single member */
+
+	__le32  transform_source;
+	__le32  transform_target;    /* destination device ID */
+	__le32  transforming_progress;
+	__le32  signature;              /* persistent identification*/
+	__le16  critical_members;       /* bit mask of critical members */
+	__le16  reserve2;
+	__le32  reserve;
+}
+__attribute__((packed));
+
+/*
+ * physical device information.
+ */
+#define MAX_PARENTS_PER_DISK    8
+
+struct hpt_device_info_v2 {
+	u8   ctlr_id;             /* controller id */
+	u8   path_id;             /* bus */
+	u8   target_id;           /* id */
+	u8   device_mode_setting; /* Current Data Transfer mode: 0-4 PIO0-4 */
+				  /* 5-7 MW DMA0-2, 8-13 UDMA0-5 */
+	u8   device_type;         /* device type */
+	u8   usable_mode;         /* highest usable mode */
+
+#ifdef __BIG_ENDIAN_BITFIELD
+	u8   NCQ_enabled: 1;
+	u8   NCQ_supported: 1;
+	u8   TCQ_enabled: 1;
+	u8   TCQ_supported: 1;
+	u8   write_cache_enabled: 1;
+	u8   write_cache_supported: 1;
+	u8   read_ahead_enabled: 1;
+	u8   read_ahead_supported: 1;
+	u8   reserved6: 6;
+	u8   spin_up_mode: 2;
+#else
+	u8   read_ahead_supported: 1;
+	u8   read_ahead_enabled: 1;
+	u8   write_cache_supported: 1;
+	u8   write_cache_enabled: 1;
+	u8   TCQ_supported: 1;
+	u8   TCQ_enabled: 1;
+	u8   NCQ_supported: 1;
+	u8   NCQ_enabled: 1;
+	u8   spin_up_mode: 2;
+	u8   reserved6: 6;
+#endif
+
+	__le32  flags;         /* working flags, see DEVICE_FLAG_XXX */
+	u8      ident[150];    /* (partitial) Identify Data of this device */
+
+	__le64  total_free;
+	__le64  max_free;
+	__le64  bad_sectors;
+	__le32  parent_arrays[MAX_PARENTS_PER_DISK];
+}
+__attribute__((packed));
+
+/*
+ * Logical device information.
+ */
+#define INVALID_TARGET_ID   0xFF
+#define INVALID_BUS_ID      0xFF
+
+struct hpt_logical_device_info_v3 {
+	u8       type;                   /* LDT_ARRAY or LDT_DEVICE */
+	u8       cache_policy;           /* refer to CACHE_POLICY_xxx */
+	u8       vbus_id;                /* vbus sequence in vbus_list */
+	u8       target_id;              /* OS target id. 0xFF is invalid */
+					 /* OS name: DISK $VBusId_$TargetId */
+	__le64   capacity;               /* array capacity */
+	__le32   parent_array;           /* don't use this field for physical
+					    device. use ParentArrays field in
+					    hpt_device_info_v2 */
+	/* reserved statistic fields */
+	__le32   stat1;
+	__le32   stat2;
+	__le32   stat3;
+	__le32   stat4;
+
+	union {
+		struct hpt_array_info_v3 array;
+		struct hpt_device_info_v2 device;
+	} __attribute__((packed)) u;
+
+}
+__attribute__((packed));
+
+/*
+ * ioctl structure
+ */
+#define HPT_IOCTL_MAGIC   0xA1B2C3D4
+
+struct hpt_ioctl_u {
+	u32   magic;            /* used to check if it's a valid ioctl packet */
+	u32   ioctl_code;       /* operation control code */
+	void __user *inbuf;     /* input data buffer */
+	u32   inbuf_size;       /* size of input data buffer */
+	void __user *outbuf;    /* output data buffer */
+	u32   outbuf_size;      /* size of output data buffer */
+	void __user *bytes_returned;   /* count of bytes returned */
+}
+__attribute__((packed));
+
+
+struct hpt_iopmu
+{
+	__le32 resrved0[4];
+	__le32 inbound_msgaddr0;
+	__le32 inbound_msgaddr1;
+	__le32 outbound_msgaddr0;
+	__le32 outbound_msgaddr1;
+	__le32 inbound_doorbell;
+	__le32 inbound_intstatus;
+	__le32 inbound_intmask;
+	__le32 outbound_doorbell;
+	__le32 outbound_intstatus;
+	__le32 outbound_intmask;
+	__le32 reserved1[2];
+	__le32 inbound_queue;
+	__le32 outbound_queue;
+};
+
+#define IOPMU_QUEUE_EMPTY            0xffffffff
+#define IOPMU_QUEUE_MASK_HOST_BITS   0xf0000000
+#define IOPMU_QUEUE_ADDR_HOST_BIT    0x80000000
+
+#define IOPMU_OUTBOUND_INT_MSG0      1
+#define IOPMU_OUTBOUND_INT_MSG1      2
+#define IOPMU_OUTBOUND_INT_DOORBELL  4
+#define IOPMU_OUTBOUND_INT_POSTQUEUE 8
+#define IOPMU_OUTBOUND_INT_PCI       0x10
+
+#define IOPMU_INBOUND_INT_MSG0       1
+#define IOPMU_INBOUND_INT_MSG1       2
+#define IOPMU_INBOUND_INT_DOORBELL   4
+#define IOPMU_INBOUND_INT_ERROR      8
+#define IOPMU_INBOUND_INT_POSTQUEUE  0x10
+
+enum hpt_iopmu_message {
+	/* host-to-iop messages */
+	IOPMU_INBOUND_MSG0_NOP = 0,
+	IOPMU_INBOUND_MSG0_RESET,
+	IOPMU_INBOUND_MSG0_FLUSH,
+	IOPMU_INBOUND_MSG0_SHUTDOWN,
+	IOPMU_INBOUND_MSG0_STOP_BACKGROUND_TASK,
+	IOPMU_INBOUND_MSG0_START_BACKGROUND_TASK,
+	IOPMU_INBOUND_MSG0_MAX = 0xff,
+	/* iop-to-host messages */
+	IOPMU_OUTBOUND_MSG0_REGISTER_DEVICE_0 = 0x100,
+	IOPMU_OUTBOUND_MSG0_REGISTER_DEVICE_MAX = 0x1ff,
+	IOPMU_OUTBOUND_MSG0_UNREGISTER_DEVICE_0 = 0x200,
+	IOPMU_OUTBOUND_MSG0_UNREGISTER_DEVICE_MAX = 0x2ff,
+	IOPMU_OUTBOUND_MSG0_REVALIDATE_DEVICE_0 = 0x300,
+	IOPMU_OUTBOUND_MSG0_REVALIDATE_DEVICE_MAX = 0x3ff,
+};
+
+struct hpt_iop_request_header
+{
+	__le32 size;
+	__le32 type;
+	__le32 flags;
+	__le32 result;
+	__le32 context; /* host context */
+	__le32 context_hi32;
+};
+
+#define IOP_REQUEST_FLAG_SYNC_REQUEST 1
+#define IOP_REQUEST_FLAG_BIST_REQUEST 2
+#define IOP_REQUEST_FLAG_REMAPPED     4
+#define IOP_REQUEST_FLAG_OUTPUT_CONTEXT 8
+
+enum hpt_iop_request_type {
+	IOP_REQUEST_TYPE_GET_CONFIG = 0,
+	IOP_REQUEST_TYPE_SET_CONFIG,
+	IOP_REQUEST_TYPE_BLOCK_COMMAND,
+	IOP_REQUEST_TYPE_SCSI_COMMAND,
+	IOP_REQUEST_TYPE_IOCTL_COMMAND,
+	IOP_REQUEST_TYPE_MAX
+};
+
+enum hpt_iop_result_type {
+	IOP_RESULT_PENDING = 0,
+	IOP_RESULT_SUCCESS,
+	IOP_RESULT_FAIL,
+	IOP_RESULT_BUSY,
+	IOP_RESULT_RESET,
+	IOP_RESULT_INVALID_REQUEST,
+	IOP_RESULT_BAD_TARGET,
+	IOP_RESULT_MODE_SENSE_CHECK_CONDITION,
+};
+
+struct hpt_iop_request_get_config
+{
+	struct hpt_iop_request_header header;
+	__le32 interface_version;
+	__le32 firmware_version;
+	__le32 max_requests;
+	__le32 request_size;
+	__le32 max_sg_count;
+	__le32 data_transfer_length;
+	__le32 alignment_mask;
+	__le32 max_devices;
+	__le32 sdram_size;
+};
+
+struct hpt_iop_request_set_config
+{
+	struct hpt_iop_request_header header;
+	__le32 iop_id;
+	__le32 vbus_id;
+	__le32 reserve[6];
+};
+
+struct hpt_iopsg
+{
+	__le32 size;
+	__le32 eot; /* non-zero: end of table */
+	__le64 pci_address;
+};
+
+struct hpt_iop_request_block_command
+{
+	struct hpt_iop_request_header header;
+	u8     channel;
+	u8     target;
+	u8     lun;
+	u8     pad1;
+	__le16 command; /* IOP_BLOCK_COMMAND_{READ,WRITE} */
+	__le16 sectors;
+	__le64 lba;
+	struct hpt_iopsg sg_list[1];
+};
+
+#define IOP_BLOCK_COMMAND_READ     1
+#define IOP_BLOCK_COMMAND_WRITE    2
+#define IOP_BLOCK_COMMAND_VERIFY   3
+#define IOP_BLOCK_COMMAND_FLUSH    4
+#define IOP_BLOCK_COMMAND_SHUTDOWN 5
+
+struct hpt_iop_request_scsi_command
+{
+	struct hpt_iop_request_header header;
+	u8     channel;
+	u8     target;
+	u8     lun;
+	u8     pad1;
+	u8     cdb[16];
+	__le32 dataxfer_length;
+	struct hpt_iopsg sg_list[1];
+};
+
+struct hpt_iop_request_ioctl_command
+{
+	struct hpt_iop_request_header header;
+	__le32 ioctl_code;
+	__le32 inbuf_size;
+	__le32 outbuf_size;
+	__le32 bytes_returned;
+	u8     buf[1];
+	/* out data should be put at buf[(inbuf_size+3)&~3] */
+};
+
+#define HPTIOP_MAX_REQUESTS  256u
+
+struct hptiop_request {
+	struct hptiop_request * next;
+	void *                  req_virt;
+	u32                     req_shifted_phy;
+	struct scsi_cmnd *      scp;
+	int                     index;
+};
+
+struct hpt_scsi_pointer {
+	int mapped;
+	int sgcnt;
+	dma_addr_t dma_handle;
+};
+
+#define HPT_SCP(scp) ((struct hpt_scsi_pointer *)&(scp)->SCp)
+
+struct hptiop_hba {
+	struct hpt_iopmu __iomem * iop;
+	struct Scsi_Host * host;
+	struct pci_dev * pcidev;
+
+	struct list_head link;
+
+	/* IOP config info */
+	u32     firmware_version;
+	u32     sdram_size;
+	u32     max_devices;
+	u32     max_requests;
+	u32     max_request_size;
+	u32     max_sg_descriptors;
+
+	u32     req_size; /* host-allocated request buffer size */
+	int     initialized;
+	int     msg_done;
+
+	struct hptiop_request * req_list;
+	struct hptiop_request reqs[HPTIOP_MAX_REQUESTS];
+
+	/* used to free allocated dma area */
+	void *      dma_coherent;
+	dma_addr_t  dma_coherent_handle;
+
+	atomic_t    reset_count;
+	atomic_t    resetting;
+
+	wait_queue_head_t reset_wq;
+	wait_queue_head_t ioctl_wq;
+};
+
+struct hpt_ioctl_k
+{
+	struct hptiop_hba * hba;
+	u32    ioctl_code;
+	u32    inbuf_size;
+	u32    outbuf_size;
+	void * inbuf;
+	void * outbuf;
+	u32  * bytes_returned;
+	void (*done)(struct hpt_ioctl_k *);
+	int    result; /* HPT_IOCTL_RESULT_ */
+};
+
+#define HPT_IOCTL_RESULT_OK         0
+#define HPT_IOCTL_RESULT_FAILED     (-1)
+
+#if 0
+#define dprintk(fmt, args...) do { printk(fmt, ##args); } while(0)
+#else
+#define dprintk(fmt, args...)
+#endif
+
+#endif
diff --git a/drivers/scsi/libata-eh.c b/drivers/scsi/libata-eh.c
new file mode 100644
index 000000000..2c34af996
--- /dev/null
+++ b/drivers/scsi/libata-eh.c
@@ -0,0 +1,2245 @@
+/*
+ *  libata-eh.c - libata error handling
+ *
+ *  Maintained by:  Jeff Garzik <jgarzik@pobox.com>
+ *    		    Please ALWAYS copy linux-ide@vger.kernel.org
+ *		    on emails.
+ *
+ *  Copyright 2006 Tejun Heo <htejun@gmail.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; see the file COPYING.  If not, write to
+ *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139,
+ *  USA.
+ *
+ *
+ *  libata documentation is available via 'make {ps|pdf}docs',
+ *  as Documentation/DocBook/libata.*
+ *
+ *  Hardware documentation available from http://www.t13.org/ and
+ *  http://www.sata-io.org/
+ *
+ */
+
+#include <linux/kernel.h>
+#include <scsi/scsi.h>
+#include <scsi/scsi_host.h>
+#include <scsi/scsi_eh.h>
+#include <scsi/scsi_device.h>
+#include <scsi/scsi_cmnd.h>
+#include "scsi_transport_api.h"
+
+#include <linux/libata.h>
+
+#include "libata.h"
+
+static void __ata_port_freeze(struct ata_port *ap);
+static void ata_eh_finish(struct ata_port *ap);
+static void ata_eh_handle_port_suspend(struct ata_port *ap);
+static void ata_eh_handle_port_resume(struct ata_port *ap);
+
+static void ata_ering_record(struct ata_ering *ering, int is_io,
+			     unsigned int err_mask)
+{
+	struct ata_ering_entry *ent;
+
+	WARN_ON(!err_mask);
+
+	ering->cursor++;
+	ering->cursor %= ATA_ERING_SIZE;
+
+	ent = &ering->ring[ering->cursor];
+	ent->is_io = is_io;
+	ent->err_mask = err_mask;
+	ent->timestamp = get_jiffies_64();
+}
+
+static struct ata_ering_entry * ata_ering_top(struct ata_ering *ering)
+{
+	struct ata_ering_entry *ent = &ering->ring[ering->cursor];
+	if (!ent->err_mask)
+		return NULL;
+	return ent;
+}
+
+static int ata_ering_map(struct ata_ering *ering,
+			 int (*map_fn)(struct ata_ering_entry *, void *),
+			 void *arg)
+{
+	int idx, rc = 0;
+	struct ata_ering_entry *ent;
+
+	idx = ering->cursor;
+	do {
+		ent = &ering->ring[idx];
+		if (!ent->err_mask)
+			break;
+		rc = map_fn(ent, arg);
+		if (rc)
+			break;
+		idx = (idx - 1 + ATA_ERING_SIZE) % ATA_ERING_SIZE;
+	} while (idx != ering->cursor);
+
+	return rc;
+}
+
+static unsigned int ata_eh_dev_action(struct ata_device *dev)
+{
+	struct ata_eh_context *ehc = &dev->ap->eh_context;
+
+	return ehc->i.action | ehc->i.dev_action[dev->devno];
+}
+
+static void ata_eh_clear_action(struct ata_device *dev,
+				struct ata_eh_info *ehi, unsigned int action)
+{
+	int i;
+
+	if (!dev) {
+		ehi->action &= ~action;
+		for (i = 0; i < ATA_MAX_DEVICES; i++)
+			ehi->dev_action[i] &= ~action;
+	} else {
+		/* doesn't make sense for port-wide EH actions */
+		WARN_ON(!(action & ATA_EH_PERDEV_MASK));
+
+		/* break ehi->action into ehi->dev_action */
+		if (ehi->action & action) {
+			for (i = 0; i < ATA_MAX_DEVICES; i++)
+				ehi->dev_action[i] |= ehi->action & action;
+			ehi->action &= ~action;
+		}
+
+		/* turn off the specified per-dev action */
+		ehi->dev_action[dev->devno] &= ~action;
+	}
+}
+
+/**
+ *	ata_scsi_timed_out - SCSI layer time out callback
+ *	@cmd: timed out SCSI command
+ *
+ *	Handles SCSI layer timeout.  We race with normal completion of
+ *	the qc for @cmd.  If the qc is already gone, we lose and let
+ *	the scsi command finish (EH_HANDLED).  Otherwise, the qc has
+ *	timed out and EH should be invoked.  Prevent ata_qc_complete()
+ *	from finishing it by setting EH_SCHEDULED and return
+ *	EH_NOT_HANDLED.
+ *
+ *	TODO: kill this function once old EH is gone.
+ *
+ *	LOCKING:
+ *	Called from timer context
+ *
+ *	RETURNS:
+ *	EH_HANDLED or EH_NOT_HANDLED
+ */
+enum scsi_eh_timer_return ata_scsi_timed_out(struct scsi_cmnd *cmd)
+{
+	struct Scsi_Host *host = cmd->device->host;
+	struct ata_port *ap = ata_shost_to_port(host);
+	unsigned long flags;
+	struct ata_queued_cmd *qc;
+	enum scsi_eh_timer_return ret;
+
+	DPRINTK("ENTER\n");
+
+	if (ap->ops->error_handler) {
+		ret = EH_NOT_HANDLED;
+		goto out;
+	}
+
+	ret = EH_HANDLED;
+	spin_lock_irqsave(ap->lock, flags);
+	qc = ata_qc_from_tag(ap, ap->active_tag);
+	if (qc) {
+		WARN_ON(qc->scsicmd != cmd);
+		qc->flags |= ATA_QCFLAG_EH_SCHEDULED;
+		qc->err_mask |= AC_ERR_TIMEOUT;
+		ret = EH_NOT_HANDLED;
+	}
+	spin_unlock_irqrestore(ap->lock, flags);
+
+ out:
+	DPRINTK("EXIT, ret=%d\n", ret);
+	return ret;
+}
+
+/**
+ *	ata_scsi_error - SCSI layer error handler callback
+ *	@host: SCSI host on which error occurred
+ *
+ *	Handles SCSI-layer-thrown error events.
+ *
+ *	LOCKING:
+ *	Inherited from SCSI layer (none, can sleep)
+ *
+ *	RETURNS:
+ *	Zero.
+ */
+void ata_scsi_error(struct Scsi_Host *host)
+{
+	struct ata_port *ap = ata_shost_to_port(host);
+	int i, repeat_cnt = ATA_EH_MAX_REPEAT;
+	unsigned long flags;
+
+	DPRINTK("ENTER\n");
+
+	/* synchronize with port task */
+	ata_port_flush_task(ap);
+
+	/* synchronize with host_set lock and sort out timeouts */
+
+	/* For new EH, all qcs are finished in one of three ways -
+	 * normal completion, error completion, and SCSI timeout.
+	 * Both cmpletions can race against SCSI timeout.  When normal
+	 * completion wins, the qc never reaches EH.  When error
+	 * completion wins, the qc has ATA_QCFLAG_FAILED set.
+	 *
+	 * When SCSI timeout wins, things are a bit more complex.
+	 * Normal or error completion can occur after the timeout but
+	 * before this point.  In such cases, both types of
+	 * completions are honored.  A scmd is determined to have
+	 * timed out iff its associated qc is active and not failed.
+	 */
+	if (ap->ops->error_handler) {
+		struct scsi_cmnd *scmd, *tmp;
+		int nr_timedout = 0;
+
+		spin_lock_irqsave(ap->lock, flags);
+
+		list_for_each_entry_safe(scmd, tmp, &host->eh_cmd_q, eh_entry) {
+			struct ata_queued_cmd *qc;
+
+			for (i = 0; i < ATA_MAX_QUEUE; i++) {
+				qc = __ata_qc_from_tag(ap, i);
+				if (qc->flags & ATA_QCFLAG_ACTIVE &&
+				    qc->scsicmd == scmd)
+					break;
+			}
+
+			if (i < ATA_MAX_QUEUE) {
+				/* the scmd has an associated qc */
+				if (!(qc->flags & ATA_QCFLAG_FAILED)) {
+					/* which hasn't failed yet, timeout */
+					qc->err_mask |= AC_ERR_TIMEOUT;
+					qc->flags |= ATA_QCFLAG_FAILED;
+					nr_timedout++;
+				}
+			} else {
+				/* Normal completion occurred after
+				 * SCSI timeout but before this point.
+				 * Successfully complete it.
+				 */
+				scmd->retries = scmd->allowed;
+				scsi_eh_finish_cmd(scmd, &ap->eh_done_q);
+			}
+		}
+
+		/* If we have timed out qcs.  They belong to EH from
+		 * this point but the state of the controller is
+		 * unknown.  Freeze the port to make sure the IRQ
+		 * handler doesn't diddle with those qcs.  This must
+		 * be done atomically w.r.t. setting QCFLAG_FAILED.
+		 */
+		if (nr_timedout)
+			__ata_port_freeze(ap);
+
+		spin_unlock_irqrestore(ap->lock, flags);
+	} else
+		spin_unlock_wait(ap->lock);
+
+ repeat:
+	/* invoke error handler */
+	if (ap->ops->error_handler) {
+		/* process port resume request */
+		ata_eh_handle_port_resume(ap);
+
+		/* fetch & clear EH info */
+		spin_lock_irqsave(ap->lock, flags);
+
+		memset(&ap->eh_context, 0, sizeof(ap->eh_context));
+		ap->eh_context.i = ap->eh_info;
+		memset(&ap->eh_info, 0, sizeof(ap->eh_info));
+
+		ap->pflags |= ATA_PFLAG_EH_IN_PROGRESS;
+		ap->pflags &= ~ATA_PFLAG_EH_PENDING;
+
+		spin_unlock_irqrestore(ap->lock, flags);
+
+		/* invoke EH, skip if unloading or suspended */
+		if (!(ap->pflags & (ATA_PFLAG_UNLOADING | ATA_PFLAG_SUSPENDED)))
+			ap->ops->error_handler(ap);
+		else
+			ata_eh_finish(ap);
+
+		/* process port suspend request */
+		ata_eh_handle_port_suspend(ap);
+
+		/* Exception might have happend after ->error_handler
+		 * recovered the port but before this point.  Repeat
+		 * EH in such case.
+		 */
+		spin_lock_irqsave(ap->lock, flags);
+
+		if (ap->pflags & ATA_PFLAG_EH_PENDING) {
+			if (--repeat_cnt) {
+				ata_port_printk(ap, KERN_INFO,
+					"EH pending after completion, "
+					"repeating EH (cnt=%d)\n", repeat_cnt);
+				spin_unlock_irqrestore(ap->lock, flags);
+				goto repeat;
+			}
+			ata_port_printk(ap, KERN_ERR, "EH pending after %d "
+					"tries, giving up\n", ATA_EH_MAX_REPEAT);
+		}
+
+		/* this run is complete, make sure EH info is clear */
+		memset(&ap->eh_info, 0, sizeof(ap->eh_info));
+
+		/* Clear host_eh_scheduled while holding ap->lock such
+		 * that if exception occurs after this point but
+		 * before EH completion, SCSI midlayer will
+		 * re-initiate EH.
+		 */
+		host->host_eh_scheduled = 0;
+
+		spin_unlock_irqrestore(ap->lock, flags);
+	} else {
+		WARN_ON(ata_qc_from_tag(ap, ap->active_tag) == NULL);
+		ap->ops->eng_timeout(ap);
+	}
+
+	/* finish or retry handled scmd's and clean up */
+	WARN_ON(host->host_failed || !list_empty(&host->eh_cmd_q));
+
+	scsi_eh_flush_done_q(&ap->eh_done_q);
+
+	/* clean up */
+	spin_lock_irqsave(ap->lock, flags);
+
+	if (ap->pflags & ATA_PFLAG_LOADING)
+		ap->pflags &= ~ATA_PFLAG_LOADING;
+	else if (ap->pflags & ATA_PFLAG_SCSI_HOTPLUG)
+		queue_work(ata_aux_wq, &ap->hotplug_task);
+
+	if (ap->pflags & ATA_PFLAG_RECOVERED)
+		ata_port_printk(ap, KERN_INFO, "EH complete\n");
+
+	ap->pflags &= ~(ATA_PFLAG_SCSI_HOTPLUG | ATA_PFLAG_RECOVERED);
+
+	/* tell wait_eh that we're done */
+	ap->pflags &= ~ATA_PFLAG_EH_IN_PROGRESS;
+	wake_up_all(&ap->eh_wait_q);
+
+	spin_unlock_irqrestore(ap->lock, flags);
+
+	DPRINTK("EXIT\n");
+}
+
+/**
+ *	ata_port_wait_eh - Wait for the currently pending EH to complete
+ *	@ap: Port to wait EH for
+ *
+ *	Wait until the currently pending EH is complete.
+ *
+ *	LOCKING:
+ *	Kernel thread context (may sleep).
+ */
+void ata_port_wait_eh(struct ata_port *ap)
+{
+	unsigned long flags;
+	DEFINE_WAIT(wait);
+
+ retry:
+	spin_lock_irqsave(ap->lock, flags);
+
+	while (ap->pflags & (ATA_PFLAG_EH_PENDING | ATA_PFLAG_EH_IN_PROGRESS)) {
+		prepare_to_wait(&ap->eh_wait_q, &wait, TASK_UNINTERRUPTIBLE);
+		spin_unlock_irqrestore(ap->lock, flags);
+		schedule();
+		spin_lock_irqsave(ap->lock, flags);
+	}
+	finish_wait(&ap->eh_wait_q, &wait);
+
+	spin_unlock_irqrestore(ap->lock, flags);
+
+	/* make sure SCSI EH is complete */
+	if (scsi_host_in_recovery(ap->host)) {
+		msleep(10);
+		goto retry;
+	}
+}
+
+/**
+ *	ata_qc_timeout - Handle timeout of queued command
+ *	@qc: Command that timed out
+ *
+ *	Some part of the kernel (currently, only the SCSI layer)
+ *	has noticed that the active command on port @ap has not
+ *	completed after a specified length of time.  Handle this
+ *	condition by disabling DMA (if necessary) and completing
+ *	transactions, with error if necessary.
+ *
+ *	This also handles the case of the "lost interrupt", where
+ *	for some reason (possibly hardware bug, possibly driver bug)
+ *	an interrupt was not delivered to the driver, even though the
+ *	transaction completed successfully.
+ *
+ *	TODO: kill this function once old EH is gone.
+ *
+ *	LOCKING:
+ *	Inherited from SCSI layer (none, can sleep)
+ */
+static void ata_qc_timeout(struct ata_queued_cmd *qc)
+{
+	struct ata_port *ap = qc->ap;
+	u8 host_stat = 0, drv_stat;
+	unsigned long flags;
+
+	DPRINTK("ENTER\n");
+
+	ap->hsm_task_state = HSM_ST_IDLE;
+
+	spin_lock_irqsave(ap->lock, flags);
+
+	switch (qc->tf.protocol) {
+
+	case ATA_PROT_DMA:
+	case ATA_PROT_ATAPI_DMA:
+		host_stat = ap->ops->bmdma_status(ap);
+
+		/* before we do anything else, clear DMA-Start bit */
+		ap->ops->bmdma_stop(qc);
+
+		/* fall through */
+
+	default:
+		ata_altstatus(ap);
+		drv_stat = ata_chk_status(ap);
+
+		/* ack bmdma irq events */
+		ap->ops->irq_clear(ap);
+
+		ata_dev_printk(qc->dev, KERN_ERR, "command 0x%x timeout, "
+			       "stat 0x%x host_stat 0x%x\n",
+			       qc->tf.command, drv_stat, host_stat);
+
+		/* complete taskfile transaction */
+		qc->err_mask |= AC_ERR_TIMEOUT;
+		break;
+	}
+
+	spin_unlock_irqrestore(ap->lock, flags);
+
+	ata_eh_qc_complete(qc);
+
+	DPRINTK("EXIT\n");
+}
+
+/**
+ *	ata_eng_timeout - Handle timeout of queued command
+ *	@ap: Port on which timed-out command is active
+ *
+ *	Some part of the kernel (currently, only the SCSI layer)
+ *	has noticed that the active command on port @ap has not
+ *	completed after a specified length of time.  Handle this
+ *	condition by disabling DMA (if necessary) and completing
+ *	transactions, with error if necessary.
+ *
+ *	This also handles the case of the "lost interrupt", where
+ *	for some reason (possibly hardware bug, possibly driver bug)
+ *	an interrupt was not delivered to the driver, even though the
+ *	transaction completed successfully.
+ *
+ *	TODO: kill this function once old EH is gone.
+ *
+ *	LOCKING:
+ *	Inherited from SCSI layer (none, can sleep)
+ */
+void ata_eng_timeout(struct ata_port *ap)
+{
+	DPRINTK("ENTER\n");
+
+	ata_qc_timeout(ata_qc_from_tag(ap, ap->active_tag));
+
+	DPRINTK("EXIT\n");
+}
+
+/**
+ *	ata_qc_schedule_eh - schedule qc for error handling
+ *	@qc: command to schedule error handling for
+ *
+ *	Schedule error handling for @qc.  EH will kick in as soon as
+ *	other commands are drained.
+ *
+ *	LOCKING:
+ *	spin_lock_irqsave(host_set lock)
+ */
+void ata_qc_schedule_eh(struct ata_queued_cmd *qc)
+{
+	struct ata_port *ap = qc->ap;
+
+	WARN_ON(!ap->ops->error_handler);
+
+	qc->flags |= ATA_QCFLAG_FAILED;
+	qc->ap->pflags |= ATA_PFLAG_EH_PENDING;
+
+	/* The following will fail if timeout has already expired.
+	 * ata_scsi_error() takes care of such scmds on EH entry.
+	 * Note that ATA_QCFLAG_FAILED is unconditionally set after
+	 * this function completes.
+	 */
+	scsi_req_abort_cmd(qc->scsicmd);
+}
+
+/**
+ *	ata_port_schedule_eh - schedule error handling without a qc
+ *	@ap: ATA port to schedule EH for
+ *
+ *	Schedule error handling for @ap.  EH will kick in as soon as
+ *	all commands are drained.
+ *
+ *	LOCKING:
+ *	spin_lock_irqsave(host_set lock)
+ */
+void ata_port_schedule_eh(struct ata_port *ap)
+{
+	WARN_ON(!ap->ops->error_handler);
+
+	ap->pflags |= ATA_PFLAG_EH_PENDING;
+	scsi_schedule_eh(ap->host);
+
+	DPRINTK("port EH scheduled\n");
+}
+
+/**
+ *	ata_port_abort - abort all qc's on the port
+ *	@ap: ATA port to abort qc's for
+ *
+ *	Abort all active qc's of @ap and schedule EH.
+ *
+ *	LOCKING:
+ *	spin_lock_irqsave(host_set lock)
+ *
+ *	RETURNS:
+ *	Number of aborted qc's.
+ */
+int ata_port_abort(struct ata_port *ap)
+{
+	int tag, nr_aborted = 0;
+
+	WARN_ON(!ap->ops->error_handler);
+
+	for (tag = 0; tag < ATA_MAX_QUEUE; tag++) {
+		struct ata_queued_cmd *qc = ata_qc_from_tag(ap, tag);
+
+		if (qc) {
+			qc->flags |= ATA_QCFLAG_FAILED;
+			ata_qc_complete(qc);
+			nr_aborted++;
+		}
+	}
+
+	if (!nr_aborted)
+		ata_port_schedule_eh(ap);
+
+	return nr_aborted;
+}
+
+/**
+ *	__ata_port_freeze - freeze port
+ *	@ap: ATA port to freeze
+ *
+ *	This function is called when HSM violation or some other
+ *	condition disrupts normal operation of the port.  Frozen port
+ *	is not allowed to perform any operation until the port is
+ *	thawed, which usually follows a successful reset.
+ *
+ *	ap->ops->freeze() callback can be used for freezing the port
+ *	hardware-wise (e.g. mask interrupt and stop DMA engine).  If a
+ *	port cannot be frozen hardware-wise, the interrupt handler
+ *	must ack and clear interrupts unconditionally while the port
+ *	is frozen.
+ *
+ *	LOCKING:
+ *	spin_lock_irqsave(host_set lock)
+ */
+static void __ata_port_freeze(struct ata_port *ap)
+{
+	WARN_ON(!ap->ops->error_handler);
+
+	if (ap->ops->freeze)
+		ap->ops->freeze(ap);
+
+	ap->pflags |= ATA_PFLAG_FROZEN;
+
+	DPRINTK("ata%u port frozen\n", ap->id);
+}
+
+/**
+ *	ata_port_freeze - abort & freeze port
+ *	@ap: ATA port to freeze
+ *
+ *	Abort and freeze @ap.
+ *
+ *	LOCKING:
+ *	spin_lock_irqsave(host_set lock)
+ *
+ *	RETURNS:
+ *	Number of aborted commands.
+ */
+int ata_port_freeze(struct ata_port *ap)
+{
+	int nr_aborted;
+
+	WARN_ON(!ap->ops->error_handler);
+
+	nr_aborted = ata_port_abort(ap);
+	__ata_port_freeze(ap);
+
+	return nr_aborted;
+}
+
+/**
+ *	ata_eh_freeze_port - EH helper to freeze port
+ *	@ap: ATA port to freeze
+ *
+ *	Freeze @ap.
+ *
+ *	LOCKING:
+ *	None.
+ */
+void ata_eh_freeze_port(struct ata_port *ap)
+{
+	unsigned long flags;
+
+	if (!ap->ops->error_handler)
+		return;
+
+	spin_lock_irqsave(ap->lock, flags);
+	__ata_port_freeze(ap);
+	spin_unlock_irqrestore(ap->lock, flags);
+}
+
+/**
+ *	ata_port_thaw_port - EH helper to thaw port
+ *	@ap: ATA port to thaw
+ *
+ *	Thaw frozen port @ap.
+ *
+ *	LOCKING:
+ *	None.
+ */
+void ata_eh_thaw_port(struct ata_port *ap)
+{
+	unsigned long flags;
+
+	if (!ap->ops->error_handler)
+		return;
+
+	spin_lock_irqsave(ap->lock, flags);
+
+	ap->pflags &= ~ATA_PFLAG_FROZEN;
+
+	if (ap->ops->thaw)
+		ap->ops->thaw(ap);
+
+	spin_unlock_irqrestore(ap->lock, flags);
+
+	DPRINTK("ata%u port thawed\n", ap->id);
+}
+
+static void ata_eh_scsidone(struct scsi_cmnd *scmd)
+{
+	/* nada */
+}
+
+static void __ata_eh_qc_complete(struct ata_queued_cmd *qc)
+{
+	struct ata_port *ap = qc->ap;
+	struct scsi_cmnd *scmd = qc->scsicmd;
+	unsigned long flags;
+
+	spin_lock_irqsave(ap->lock, flags);
+	qc->scsidone = ata_eh_scsidone;
+	__ata_qc_complete(qc);
+	WARN_ON(ata_tag_valid(qc->tag));
+	spin_unlock_irqrestore(ap->lock, flags);
+
+	scsi_eh_finish_cmd(scmd, &ap->eh_done_q);
+}
+
+/**
+ *	ata_eh_qc_complete - Complete an active ATA command from EH
+ *	@qc: Command to complete
+ *
+ *	Indicate to the mid and upper layers that an ATA command has
+ *	completed.  To be used from EH.
+ */
+void ata_eh_qc_complete(struct ata_queued_cmd *qc)
+{
+	struct scsi_cmnd *scmd = qc->scsicmd;
+	scmd->retries = scmd->allowed;
+	__ata_eh_qc_complete(qc);
+}
+
+/**
+ *	ata_eh_qc_retry - Tell midlayer to retry an ATA command after EH
+ *	@qc: Command to retry
+ *
+ *	Indicate to the mid and upper layers that an ATA command
+ *	should be retried.  To be used from EH.
+ *
+ *	SCSI midlayer limits the number of retries to scmd->allowed.
+ *	scmd->retries is decremented for commands which get retried
+ *	due to unrelated failures (qc->err_mask is zero).
+ */
+void ata_eh_qc_retry(struct ata_queued_cmd *qc)
+{
+	struct scsi_cmnd *scmd = qc->scsicmd;
+	if (!qc->err_mask && scmd->retries)
+		scmd->retries--;
+	__ata_eh_qc_complete(qc);
+}
+
+/**
+ *	ata_eh_detach_dev - detach ATA device
+ *	@dev: ATA device to detach
+ *
+ *	Detach @dev.
+ *
+ *	LOCKING:
+ *	None.
+ */
+static void ata_eh_detach_dev(struct ata_device *dev)
+{
+	struct ata_port *ap = dev->ap;
+	unsigned long flags;
+
+	ata_dev_disable(dev);
+
+	spin_lock_irqsave(ap->lock, flags);
+
+	dev->flags &= ~ATA_DFLAG_DETACH;
+
+	if (ata_scsi_offline_dev(dev)) {
+		dev->flags |= ATA_DFLAG_DETACHED;
+		ap->pflags |= ATA_PFLAG_SCSI_HOTPLUG;
+	}
+
+	/* clear per-dev EH actions */
+	ata_eh_clear_action(dev, &ap->eh_info, ATA_EH_PERDEV_MASK);
+	ata_eh_clear_action(dev, &ap->eh_context.i, ATA_EH_PERDEV_MASK);
+
+	spin_unlock_irqrestore(ap->lock, flags);
+}
+
+/**
+ *	ata_eh_about_to_do - about to perform eh_action
+ *	@ap: target ATA port
+ *	@dev: target ATA dev for per-dev action (can be NULL)
+ *	@action: action about to be performed
+ *
+ *	Called just before performing EH actions to clear related bits
+ *	in @ap->eh_info such that eh actions are not unnecessarily
+ *	repeated.
+ *
+ *	LOCKING:
+ *	None.
+ */
+static void ata_eh_about_to_do(struct ata_port *ap, struct ata_device *dev,
+			       unsigned int action)
+{
+	unsigned long flags;
+	struct ata_eh_info *ehi = &ap->eh_info;
+	struct ata_eh_context *ehc = &ap->eh_context;
+
+	spin_lock_irqsave(ap->lock, flags);
+
+	/* Reset is represented by combination of actions and EHI
+	 * flags.  Suck in all related bits before clearing eh_info to
+	 * avoid losing requested action.
+	 */
+	if (action & ATA_EH_RESET_MASK) {
+		ehc->i.action |= ehi->action & ATA_EH_RESET_MASK;
+		ehc->i.flags |= ehi->flags & ATA_EHI_RESET_MODIFIER_MASK;
+
+		/* make sure all reset actions are cleared & clear EHI flags */
+		action |= ATA_EH_RESET_MASK;
+		ehi->flags &= ~ATA_EHI_RESET_MODIFIER_MASK;
+	}
+
+	ata_eh_clear_action(dev, ehi, action);
+
+	if (!(ehc->i.flags & ATA_EHI_QUIET))
+		ap->pflags |= ATA_PFLAG_RECOVERED;
+
+	spin_unlock_irqrestore(ap->lock, flags);
+}
+
+/**
+ *	ata_eh_done - EH action complete
+ *	@ap: target ATA port
+ *	@dev: target ATA dev for per-dev action (can be NULL)
+ *	@action: action just completed
+ *
+ *	Called right after performing EH actions to clear related bits
+ *	in @ap->eh_context.
+ *
+ *	LOCKING:
+ *	None.
+ */
+static void ata_eh_done(struct ata_port *ap, struct ata_device *dev,
+			unsigned int action)
+{
+	/* if reset is complete, clear all reset actions & reset modifier */
+	if (action & ATA_EH_RESET_MASK) {
+		action |= ATA_EH_RESET_MASK;
+		ap->eh_context.i.flags &= ~ATA_EHI_RESET_MODIFIER_MASK;
+	}
+
+	ata_eh_clear_action(dev, &ap->eh_context.i, action);
+}
+
+/**
+ *	ata_err_string - convert err_mask to descriptive string
+ *	@err_mask: error mask to convert to string
+ *
+ *	Convert @err_mask to descriptive string.  Errors are
+ *	prioritized according to severity and only the most severe
+ *	error is reported.
+ *
+ *	LOCKING:
+ *	None.
+ *
+ *	RETURNS:
+ *	Descriptive string for @err_mask
+ */
+static const char * ata_err_string(unsigned int err_mask)
+{
+	if (err_mask & AC_ERR_HOST_BUS)
+		return "host bus error";
+	if (err_mask & AC_ERR_ATA_BUS)
+		return "ATA bus error";
+	if (err_mask & AC_ERR_TIMEOUT)
+		return "timeout";
+	if (err_mask & AC_ERR_HSM)
+		return "HSM violation";
+	if (err_mask & AC_ERR_SYSTEM)
+		return "internal error";
+	if (err_mask & AC_ERR_MEDIA)
+		return "media error";
+	if (err_mask & AC_ERR_INVALID)
+		return "invalid argument";
+	if (err_mask & AC_ERR_DEV)
+		return "device error";
+	return "unknown error";
+}
+
+/**
+ *	ata_read_log_page - read a specific log page
+ *	@dev: target device
+ *	@page: page to read
+ *	@buf: buffer to store read page
+ *	@sectors: number of sectors to read
+ *
+ *	Read log page using READ_LOG_EXT command.
+ *
+ *	LOCKING:
+ *	Kernel thread context (may sleep).
+ *
+ *	RETURNS:
+ *	0 on success, AC_ERR_* mask otherwise.
+ */
+static unsigned int ata_read_log_page(struct ata_device *dev,
+				      u8 page, void *buf, unsigned int sectors)
+{
+	struct ata_taskfile tf;
+	unsigned int err_mask;
+
+	DPRINTK("read log page - page %d\n", page);
+
+	ata_tf_init(dev, &tf);
+	tf.command = ATA_CMD_READ_LOG_EXT;
+	tf.lbal = page;
+	tf.nsect = sectors;
+	tf.hob_nsect = sectors >> 8;
+	tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_LBA48 | ATA_TFLAG_DEVICE;
+	tf.protocol = ATA_PROT_PIO;
+
+	err_mask = ata_exec_internal(dev, &tf, NULL, DMA_FROM_DEVICE,
+				     buf, sectors * ATA_SECT_SIZE);
+
+	DPRINTK("EXIT, err_mask=%x\n", err_mask);
+	return err_mask;
+}
+
+/**
+ *	ata_eh_read_log_10h - Read log page 10h for NCQ error details
+ *	@dev: Device to read log page 10h from
+ *	@tag: Resulting tag of the failed command
+ *	@tf: Resulting taskfile registers of the failed command
+ *
+ *	Read log page 10h to obtain NCQ error details and clear error
+ *	condition.
+ *
+ *	LOCKING:
+ *	Kernel thread context (may sleep).
+ *
+ *	RETURNS:
+ *	0 on success, -errno otherwise.
+ */
+static int ata_eh_read_log_10h(struct ata_device *dev,
+			       int *tag, struct ata_taskfile *tf)
+{
+	u8 *buf = dev->ap->sector_buf;
+	unsigned int err_mask;
+	u8 csum;
+	int i;
+
+	err_mask = ata_read_log_page(dev, ATA_LOG_SATA_NCQ, buf, 1);
+	if (err_mask)
+		return -EIO;
+
+	csum = 0;
+	for (i = 0; i < ATA_SECT_SIZE; i++)
+		csum += buf[i];
+	if (csum)
+		ata_dev_printk(dev, KERN_WARNING,
+			       "invalid checksum 0x%x on log page 10h\n", csum);
+
+	if (buf[0] & 0x80)
+		return -ENOENT;
+
+	*tag = buf[0] & 0x1f;
+
+	tf->command = buf[2];
+	tf->feature = buf[3];
+	tf->lbal = buf[4];
+	tf->lbam = buf[5];
+	tf->lbah = buf[6];
+	tf->device = buf[7];
+	tf->hob_lbal = buf[8];
+	tf->hob_lbam = buf[9];
+	tf->hob_lbah = buf[10];
+	tf->nsect = buf[12];
+	tf->hob_nsect = buf[13];
+
+	return 0;
+}
+
+/**
+ *	atapi_eh_request_sense - perform ATAPI REQUEST_SENSE
+ *	@dev: device to perform REQUEST_SENSE to
+ *	@sense_buf: result sense data buffer (SCSI_SENSE_BUFFERSIZE bytes long)
+ *
+ *	Perform ATAPI REQUEST_SENSE after the device reported CHECK
+ *	SENSE.  This function is EH helper.
+ *
+ *	LOCKING:
+ *	Kernel thread context (may sleep).
+ *
+ *	RETURNS:
+ *	0 on success, AC_ERR_* mask on failure
+ */
+static unsigned int atapi_eh_request_sense(struct ata_device *dev,
+					   unsigned char *sense_buf)
+{
+	struct ata_port *ap = dev->ap;
+	struct ata_taskfile tf;
+	u8 cdb[ATAPI_CDB_LEN];
+
+	DPRINTK("ATAPI request sense\n");
+
+	ata_tf_init(dev, &tf);
+
+	/* FIXME: is this needed? */
+	memset(sense_buf, 0, SCSI_SENSE_BUFFERSIZE);
+
+	/* XXX: why tf_read here? */
+	ap->ops->tf_read(ap, &tf);
+
+	/* fill these in, for the case where they are -not- overwritten */
+	sense_buf[0] = 0x70;
+	sense_buf[2] = tf.feature >> 4;
+
+	memset(cdb, 0, ATAPI_CDB_LEN);
+	cdb[0] = REQUEST_SENSE;
+	cdb[4] = SCSI_SENSE_BUFFERSIZE;
+
+	tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE;
+	tf.command = ATA_CMD_PACKET;
+
+	/* is it pointless to prefer PIO for "safety reasons"? */
+	if (ap->flags & ATA_FLAG_PIO_DMA) {
+		tf.protocol = ATA_PROT_ATAPI_DMA;
+		tf.feature |= ATAPI_PKT_DMA;
+	} else {
+		tf.protocol = ATA_PROT_ATAPI;
+		tf.lbam = (8 * 1024) & 0xff;
+		tf.lbah = (8 * 1024) >> 8;
+	}
+
+	return ata_exec_internal(dev, &tf, cdb, DMA_FROM_DEVICE,
+				 sense_buf, SCSI_SENSE_BUFFERSIZE);
+}
+
+/**
+ *	ata_eh_analyze_serror - analyze SError for a failed port
+ *	@ap: ATA port to analyze SError for
+ *
+ *	Analyze SError if available and further determine cause of
+ *	failure.
+ *
+ *	LOCKING:
+ *	None.
+ */
+static void ata_eh_analyze_serror(struct ata_port *ap)
+{
+	struct ata_eh_context *ehc = &ap->eh_context;
+	u32 serror = ehc->i.serror;
+	unsigned int err_mask = 0, action = 0;
+
+	if (serror & SERR_PERSISTENT) {
+		err_mask |= AC_ERR_ATA_BUS;
+		action |= ATA_EH_HARDRESET;
+	}
+	if (serror &
+	    (SERR_DATA_RECOVERED | SERR_COMM_RECOVERED | SERR_DATA)) {
+		err_mask |= AC_ERR_ATA_BUS;
+		action |= ATA_EH_SOFTRESET;
+	}
+	if (serror & SERR_PROTOCOL) {
+		err_mask |= AC_ERR_HSM;
+		action |= ATA_EH_SOFTRESET;
+	}
+	if (serror & SERR_INTERNAL) {
+		err_mask |= AC_ERR_SYSTEM;
+		action |= ATA_EH_SOFTRESET;
+	}
+	if (serror & (SERR_PHYRDY_CHG | SERR_DEV_XCHG))
+		ata_ehi_hotplugged(&ehc->i);
+
+	ehc->i.err_mask |= err_mask;
+	ehc->i.action |= action;
+}
+
+/**
+ *	ata_eh_analyze_ncq_error - analyze NCQ error
+ *	@ap: ATA port to analyze NCQ error for
+ *
+ *	Read log page 10h, determine the offending qc and acquire
+ *	error status TF.  For NCQ device errors, all LLDDs have to do
+ *	is setting AC_ERR_DEV in ehi->err_mask.  This function takes
+ *	care of the rest.
+ *
+ *	LOCKING:
+ *	Kernel thread context (may sleep).
+ */
+static void ata_eh_analyze_ncq_error(struct ata_port *ap)
+{
+	struct ata_eh_context *ehc = &ap->eh_context;
+	struct ata_device *dev = ap->device;
+	struct ata_queued_cmd *qc;
+	struct ata_taskfile tf;
+	int tag, rc;
+
+	/* if frozen, we can't do much */
+	if (ap->pflags & ATA_PFLAG_FROZEN)
+		return;
+
+	/* is it NCQ device error? */
+	if (!ap->sactive || !(ehc->i.err_mask & AC_ERR_DEV))
+		return;
+
+	/* has LLDD analyzed already? */
+	for (tag = 0; tag < ATA_MAX_QUEUE; tag++) {
+		qc = __ata_qc_from_tag(ap, tag);
+
+		if (!(qc->flags & ATA_QCFLAG_FAILED))
+			continue;
+
+		if (qc->err_mask)
+			return;
+	}
+
+	/* okay, this error is ours */
+	rc = ata_eh_read_log_10h(dev, &tag, &tf);
+	if (rc) {
+		ata_port_printk(ap, KERN_ERR, "failed to read log page 10h "
+				"(errno=%d)\n", rc);
+		return;
+	}
+
+	if (!(ap->sactive & (1 << tag))) {
+		ata_port_printk(ap, KERN_ERR, "log page 10h reported "
+				"inactive tag %d\n", tag);
+		return;
+	}
+
+	/* we've got the perpetrator, condemn it */
+	qc = __ata_qc_from_tag(ap, tag);
+	memcpy(&qc->result_tf, &tf, sizeof(tf));
+	qc->err_mask |= AC_ERR_DEV;
+	ehc->i.err_mask &= ~AC_ERR_DEV;
+}
+
+/**
+ *	ata_eh_analyze_tf - analyze taskfile of a failed qc
+ *	@qc: qc to analyze
+ *	@tf: Taskfile registers to analyze
+ *
+ *	Analyze taskfile of @qc and further determine cause of
+ *	failure.  This function also requests ATAPI sense data if
+ *	avaliable.
+ *
+ *	LOCKING:
+ *	Kernel thread context (may sleep).
+ *
+ *	RETURNS:
+ *	Determined recovery action
+ */
+static unsigned int ata_eh_analyze_tf(struct ata_queued_cmd *qc,
+				      const struct ata_taskfile *tf)
+{
+	unsigned int tmp, action = 0;
+	u8 stat = tf->command, err = tf->feature;
+
+	if ((stat & (ATA_BUSY | ATA_DRQ | ATA_DRDY)) != ATA_DRDY) {
+		qc->err_mask |= AC_ERR_HSM;
+		return ATA_EH_SOFTRESET;
+	}
+
+	if (!(qc->err_mask & AC_ERR_DEV))
+		return 0;
+
+	switch (qc->dev->class) {
+	case ATA_DEV_ATA:
+		if (err & ATA_ICRC)
+			qc->err_mask |= AC_ERR_ATA_BUS;
+		if (err & ATA_UNC)
+			qc->err_mask |= AC_ERR_MEDIA;
+		if (err & ATA_IDNF)
+			qc->err_mask |= AC_ERR_INVALID;
+		break;
+
+	case ATA_DEV_ATAPI:
+		tmp = atapi_eh_request_sense(qc->dev,
+					     qc->scsicmd->sense_buffer);
+		if (!tmp) {
+			/* ATA_QCFLAG_SENSE_VALID is used to tell
+			 * atapi_qc_complete() that sense data is
+			 * already valid.
+			 *
+			 * TODO: interpret sense data and set
+			 * appropriate err_mask.
+			 */
+			qc->flags |= ATA_QCFLAG_SENSE_VALID;
+		} else
+			qc->err_mask |= tmp;
+	}
+
+	if (qc->err_mask & (AC_ERR_HSM | AC_ERR_TIMEOUT | AC_ERR_ATA_BUS))
+		action |= ATA_EH_SOFTRESET;
+
+	return action;
+}
+
+static int ata_eh_categorize_ering_entry(struct ata_ering_entry *ent)
+{
+	if (ent->err_mask & (AC_ERR_ATA_BUS | AC_ERR_TIMEOUT))
+		return 1;
+
+	if (ent->is_io) {
+		if (ent->err_mask & AC_ERR_HSM)
+			return 1;
+		if ((ent->err_mask &
+		     (AC_ERR_DEV|AC_ERR_MEDIA|AC_ERR_INVALID)) == AC_ERR_DEV)
+			return 2;
+	}
+
+	return 0;
+}
+
+struct speed_down_needed_arg {
+	u64 since;
+	int nr_errors[3];
+};
+
+static int speed_down_needed_cb(struct ata_ering_entry *ent, void *void_arg)
+{
+	struct speed_down_needed_arg *arg = void_arg;
+
+	if (ent->timestamp < arg->since)
+		return -1;
+
+	arg->nr_errors[ata_eh_categorize_ering_entry(ent)]++;
+	return 0;
+}
+
+/**
+ *	ata_eh_speed_down_needed - Determine wheter speed down is necessary
+ *	@dev: Device of interest
+ *
+ *	This function examines error ring of @dev and determines
+ *	whether speed down is necessary.  Speed down is necessary if
+ *	there have been more than 3 of Cat-1 errors or 10 of Cat-2
+ *	errors during last 15 minutes.
+ *
+ *	Cat-1 errors are ATA_BUS, TIMEOUT for any command and HSM
+ *	violation for known supported commands.
+ *
+ *	Cat-2 errors are unclassified DEV error for known supported
+ *	command.
+ *
+ *	LOCKING:
+ *	Inherited from caller.
+ *
+ *	RETURNS:
+ *	1 if speed down is necessary, 0 otherwise
+ */
+static int ata_eh_speed_down_needed(struct ata_device *dev)
+{
+	const u64 interval = 15LLU * 60 * HZ;
+	static const int err_limits[3] = { -1, 3, 10 };
+	struct speed_down_needed_arg arg;
+	struct ata_ering_entry *ent;
+	int err_cat;
+	u64 j64;
+
+	ent = ata_ering_top(&dev->ering);
+	if (!ent)
+		return 0;
+
+	err_cat = ata_eh_categorize_ering_entry(ent);
+	if (err_cat == 0)
+		return 0;
+
+	memset(&arg, 0, sizeof(arg));
+
+	j64 = get_jiffies_64();
+	if (j64 >= interval)
+		arg.since = j64 - interval;
+	else
+		arg.since = 0;
+
+	ata_ering_map(&dev->ering, speed_down_needed_cb, &arg);
+
+	return arg.nr_errors[err_cat] > err_limits[err_cat];
+}
+
+/**
+ *	ata_eh_speed_down - record error and speed down if necessary
+ *	@dev: Failed device
+ *	@is_io: Did the device fail during normal IO?
+ *	@err_mask: err_mask of the error
+ *
+ *	Record error and examine error history to determine whether
+ *	adjusting transmission speed is necessary.  It also sets
+ *	transmission limits appropriately if such adjustment is
+ *	necessary.
+ *
+ *	LOCKING:
+ *	Kernel thread context (may sleep).
+ *
+ *	RETURNS:
+ *	0 on success, -errno otherwise
+ */
+static int ata_eh_speed_down(struct ata_device *dev, int is_io,
+			     unsigned int err_mask)
+{
+	if (!err_mask)
+		return 0;
+
+	/* record error and determine whether speed down is necessary */
+	ata_ering_record(&dev->ering, is_io, err_mask);
+
+	if (!ata_eh_speed_down_needed(dev))
+		return 0;
+
+	/* speed down SATA link speed if possible */
+	if (sata_down_spd_limit(dev->ap) == 0)
+		return ATA_EH_HARDRESET;
+
+	/* lower transfer mode */
+	if (ata_down_xfermask_limit(dev, 0) == 0)
+		return ATA_EH_SOFTRESET;
+
+	ata_dev_printk(dev, KERN_ERR,
+		       "speed down requested but no transfer mode left\n");
+	return 0;
+}
+
+/**
+ *	ata_eh_autopsy - analyze error and determine recovery action
+ *	@ap: ATA port to perform autopsy on
+ *
+ *	Analyze why @ap failed and determine which recovery action is
+ *	needed.  This function also sets more detailed AC_ERR_* values
+ *	and fills sense data for ATAPI CHECK SENSE.
+ *
+ *	LOCKING:
+ *	Kernel thread context (may sleep).
+ */
+static void ata_eh_autopsy(struct ata_port *ap)
+{
+	struct ata_eh_context *ehc = &ap->eh_context;
+	unsigned int all_err_mask = 0;
+	int tag, is_io = 0;
+	u32 serror;
+	int rc;
+
+	DPRINTK("ENTER\n");
+
+	if (ehc->i.flags & ATA_EHI_NO_AUTOPSY)
+		return;
+
+	/* obtain and analyze SError */
+	rc = sata_scr_read(ap, SCR_ERROR, &serror);
+	if (rc == 0) {
+		ehc->i.serror |= serror;
+		ata_eh_analyze_serror(ap);
+	} else if (rc != -EOPNOTSUPP)
+		ehc->i.action |= ATA_EH_HARDRESET;
+
+	/* analyze NCQ failure */
+	ata_eh_analyze_ncq_error(ap);
+
+	/* any real error trumps AC_ERR_OTHER */
+	if (ehc->i.err_mask & ~AC_ERR_OTHER)
+		ehc->i.err_mask &= ~AC_ERR_OTHER;
+
+	all_err_mask |= ehc->i.err_mask;
+
+	for (tag = 0; tag < ATA_MAX_QUEUE; tag++) {
+		struct ata_queued_cmd *qc = __ata_qc_from_tag(ap, tag);
+
+		if (!(qc->flags & ATA_QCFLAG_FAILED))
+			continue;
+
+		/* inherit upper level err_mask */
+		qc->err_mask |= ehc->i.err_mask;
+
+		/* analyze TF */
+		ehc->i.action |= ata_eh_analyze_tf(qc, &qc->result_tf);
+
+		/* DEV errors are probably spurious in case of ATA_BUS error */
+		if (qc->err_mask & AC_ERR_ATA_BUS)
+			qc->err_mask &= ~(AC_ERR_DEV | AC_ERR_MEDIA |
+					  AC_ERR_INVALID);
+
+		/* any real error trumps unknown error */
+		if (qc->err_mask & ~AC_ERR_OTHER)
+			qc->err_mask &= ~AC_ERR_OTHER;
+
+		/* SENSE_VALID trumps dev/unknown error and revalidation */
+		if (qc->flags & ATA_QCFLAG_SENSE_VALID) {
+			qc->err_mask &= ~(AC_ERR_DEV | AC_ERR_OTHER);
+			ehc->i.action &= ~ATA_EH_REVALIDATE;
+		}
+
+		/* accumulate error info */
+		ehc->i.dev = qc->dev;
+		all_err_mask |= qc->err_mask;
+		if (qc->flags & ATA_QCFLAG_IO)
+			is_io = 1;
+	}
+
+	/* enforce default EH actions */
+	if (ap->pflags & ATA_PFLAG_FROZEN ||
+	    all_err_mask & (AC_ERR_HSM | AC_ERR_TIMEOUT))
+		ehc->i.action |= ATA_EH_SOFTRESET;
+	else if (all_err_mask)
+		ehc->i.action |= ATA_EH_REVALIDATE;
+
+	/* if we have offending qcs and the associated failed device */
+	if (ehc->i.dev) {
+		/* speed down */
+		ehc->i.action |= ata_eh_speed_down(ehc->i.dev, is_io,
+						   all_err_mask);
+
+		/* perform per-dev EH action only on the offending device */
+		ehc->i.dev_action[ehc->i.dev->devno] |=
+			ehc->i.action & ATA_EH_PERDEV_MASK;
+		ehc->i.action &= ~ATA_EH_PERDEV_MASK;
+	}
+
+	DPRINTK("EXIT\n");
+}
+
+/**
+ *	ata_eh_report - report error handling to user
+ *	@ap: ATA port EH is going on
+ *
+ *	Report EH to user.
+ *
+ *	LOCKING:
+ *	None.
+ */
+static void ata_eh_report(struct ata_port *ap)
+{
+	struct ata_eh_context *ehc = &ap->eh_context;
+	const char *frozen, *desc;
+	int tag, nr_failed = 0;
+
+	desc = NULL;
+	if (ehc->i.desc[0] != '\0')
+		desc = ehc->i.desc;
+
+	for (tag = 0; tag < ATA_MAX_QUEUE; tag++) {
+		struct ata_queued_cmd *qc = __ata_qc_from_tag(ap, tag);
+
+		if (!(qc->flags & ATA_QCFLAG_FAILED))
+			continue;
+		if (qc->flags & ATA_QCFLAG_SENSE_VALID && !qc->err_mask)
+			continue;
+
+		nr_failed++;
+	}
+
+	if (!nr_failed && !ehc->i.err_mask)
+		return;
+
+	frozen = "";
+	if (ap->pflags & ATA_PFLAG_FROZEN)
+		frozen = " frozen";
+
+	if (ehc->i.dev) {
+		ata_dev_printk(ehc->i.dev, KERN_ERR, "exception Emask 0x%x "
+			       "SAct 0x%x SErr 0x%x action 0x%x%s\n",
+			       ehc->i.err_mask, ap->sactive, ehc->i.serror,
+			       ehc->i.action, frozen);
+		if (desc)
+			ata_dev_printk(ehc->i.dev, KERN_ERR, "(%s)\n", desc);
+	} else {
+		ata_port_printk(ap, KERN_ERR, "exception Emask 0x%x "
+				"SAct 0x%x SErr 0x%x action 0x%x%s\n",
+				ehc->i.err_mask, ap->sactive, ehc->i.serror,
+				ehc->i.action, frozen);
+		if (desc)
+			ata_port_printk(ap, KERN_ERR, "(%s)\n", desc);
+	}
+
+	for (tag = 0; tag < ATA_MAX_QUEUE; tag++) {
+		struct ata_queued_cmd *qc = __ata_qc_from_tag(ap, tag);
+
+		if (!(qc->flags & ATA_QCFLAG_FAILED) || !qc->err_mask)
+			continue;
+
+		ata_dev_printk(qc->dev, KERN_ERR, "tag %d cmd 0x%x "
+			       "Emask 0x%x stat 0x%x err 0x%x (%s)\n",
+			       qc->tag, qc->tf.command, qc->err_mask,
+			       qc->result_tf.command, qc->result_tf.feature,
+			       ata_err_string(qc->err_mask));
+	}
+}
+
+static int ata_do_reset(struct ata_port *ap, ata_reset_fn_t reset,
+			unsigned int *classes)
+{
+	int i, rc;
+
+	for (i = 0; i < ATA_MAX_DEVICES; i++)
+		classes[i] = ATA_DEV_UNKNOWN;
+
+	rc = reset(ap, classes);
+	if (rc)
+		return rc;
+
+	/* If any class isn't ATA_DEV_UNKNOWN, consider classification
+	 * is complete and convert all ATA_DEV_UNKNOWN to
+	 * ATA_DEV_NONE.
+	 */
+	for (i = 0; i < ATA_MAX_DEVICES; i++)
+		if (classes[i] != ATA_DEV_UNKNOWN)
+			break;
+
+	if (i < ATA_MAX_DEVICES)
+		for (i = 0; i < ATA_MAX_DEVICES; i++)
+			if (classes[i] == ATA_DEV_UNKNOWN)
+				classes[i] = ATA_DEV_NONE;
+
+	return 0;
+}
+
+static int ata_eh_followup_srst_needed(int rc, int classify,
+				       const unsigned int *classes)
+{
+	if (rc == -EAGAIN)
+		return 1;
+	if (rc != 0)
+		return 0;
+	if (classify && classes[0] == ATA_DEV_UNKNOWN)
+		return 1;
+	return 0;
+}
+
+static int ata_eh_reset(struct ata_port *ap, int classify,
+			ata_prereset_fn_t prereset, ata_reset_fn_t softreset,
+			ata_reset_fn_t hardreset, ata_postreset_fn_t postreset)
+{
+	struct ata_eh_context *ehc = &ap->eh_context;
+	unsigned int *classes = ehc->classes;
+	int tries = ATA_EH_RESET_TRIES;
+	int verbose = !(ehc->i.flags & ATA_EHI_QUIET);
+	unsigned int action;
+	ata_reset_fn_t reset;
+	int i, did_followup_srst, rc;
+
+	/* about to reset */
+	ata_eh_about_to_do(ap, NULL, ehc->i.action & ATA_EH_RESET_MASK);
+
+	/* Determine which reset to use and record in ehc->i.action.
+	 * prereset() may examine and modify it.
+	 */
+	action = ehc->i.action;
+	ehc->i.action &= ~ATA_EH_RESET_MASK;
+	if (softreset && (!hardreset || (!sata_set_spd_needed(ap) &&
+					 !(action & ATA_EH_HARDRESET))))
+		ehc->i.action |= ATA_EH_SOFTRESET;
+	else
+		ehc->i.action |= ATA_EH_HARDRESET;
+
+	if (prereset) {
+		rc = prereset(ap);
+		if (rc) {
+			ata_port_printk(ap, KERN_ERR,
+					"prereset failed (errno=%d)\n", rc);
+			return rc;
+		}
+	}
+
+	/* prereset() might have modified ehc->i.action */
+	if (ehc->i.action & ATA_EH_HARDRESET)
+		reset = hardreset;
+	else if (ehc->i.action & ATA_EH_SOFTRESET)
+		reset = softreset;
+	else {
+		/* prereset told us not to reset, bang classes and return */
+		for (i = 0; i < ATA_MAX_DEVICES; i++)
+			classes[i] = ATA_DEV_NONE;
+		return 0;
+	}
+
+	/* did prereset() screw up?  if so, fix up to avoid oopsing */
+	if (!reset) {
+		ata_port_printk(ap, KERN_ERR, "BUG: prereset() requested "
+				"invalid reset type\n");
+		if (softreset)
+			reset = softreset;
+		else
+			reset = hardreset;
+	}
+
+ retry:
+	/* shut up during boot probing */
+	if (verbose)
+		ata_port_printk(ap, KERN_INFO, "%s resetting port\n",
+				reset == softreset ? "soft" : "hard");
+
+	/* mark that this EH session started with reset */
+	ehc->i.flags |= ATA_EHI_DID_RESET;
+
+	rc = ata_do_reset(ap, reset, classes);
+
+	did_followup_srst = 0;
+	if (reset == hardreset &&
+	    ata_eh_followup_srst_needed(rc, classify, classes)) {
+		/* okay, let's do follow-up softreset */
+		did_followup_srst = 1;
+		reset = softreset;
+
+		if (!reset) {
+			ata_port_printk(ap, KERN_ERR,
+					"follow-up softreset required "
+					"but no softreset avaliable\n");
+			return -EINVAL;
+		}
+
+		ata_eh_about_to_do(ap, NULL, ATA_EH_RESET_MASK);
+		rc = ata_do_reset(ap, reset, classes);
+
+		if (rc == 0 && classify &&
+		    classes[0] == ATA_DEV_UNKNOWN) {
+			ata_port_printk(ap, KERN_ERR,
+					"classification failed\n");
+			return -EINVAL;
+		}
+	}
+
+	if (rc && --tries) {
+		const char *type;
+
+		if (reset == softreset) {
+			if (did_followup_srst)
+				type = "follow-up soft";
+			else
+				type = "soft";
+		} else
+			type = "hard";
+
+		ata_port_printk(ap, KERN_WARNING,
+				"%sreset failed, retrying in 5 secs\n", type);
+		ssleep(5);
+
+		if (reset == hardreset)
+			sata_down_spd_limit(ap);
+		if (hardreset)
+			reset = hardreset;
+		goto retry;
+	}
+
+	if (rc == 0) {
+		/* After the reset, the device state is PIO 0 and the
+		 * controller state is undefined.  Record the mode.
+		 */
+		for (i = 0; i < ATA_MAX_DEVICES; i++)
+			ap->device[i].pio_mode = XFER_PIO_0;
+
+		if (postreset)
+			postreset(ap, classes);
+
+		/* reset successful, schedule revalidation */
+		ata_eh_done(ap, NULL, ehc->i.action & ATA_EH_RESET_MASK);
+		ehc->i.action |= ATA_EH_REVALIDATE;
+	}
+
+	return rc;
+}
+
+static int ata_eh_revalidate_and_attach(struct ata_port *ap,
+					struct ata_device **r_failed_dev)
+{
+	struct ata_eh_context *ehc = &ap->eh_context;
+	struct ata_device *dev;
+	unsigned long flags;
+	int i, rc = 0;
+
+	DPRINTK("ENTER\n");
+
+	for (i = 0; i < ATA_MAX_DEVICES; i++) {
+		unsigned int action;
+
+		dev = &ap->device[i];
+		action = ata_eh_dev_action(dev);
+
+		if (action & ATA_EH_REVALIDATE && ata_dev_ready(dev)) {
+			if (ata_port_offline(ap)) {
+				rc = -EIO;
+				break;
+			}
+
+			ata_eh_about_to_do(ap, dev, ATA_EH_REVALIDATE);
+			rc = ata_dev_revalidate(dev,
+					ehc->i.flags & ATA_EHI_DID_RESET);
+			if (rc)
+				break;
+
+			ata_eh_done(ap, dev, ATA_EH_REVALIDATE);
+
+			/* schedule the scsi_rescan_device() here */
+			queue_work(ata_aux_wq, &(ap->scsi_rescan_task));
+		} else if (dev->class == ATA_DEV_UNKNOWN &&
+			   ehc->tries[dev->devno] &&
+			   ata_class_enabled(ehc->classes[dev->devno])) {
+			dev->class = ehc->classes[dev->devno];
+
+			rc = ata_dev_read_id(dev, &dev->class, 1, dev->id);
+			if (rc == 0)
+				rc = ata_dev_configure(dev, 1);
+
+			if (rc) {
+				dev->class = ATA_DEV_UNKNOWN;
+				break;
+			}
+
+			spin_lock_irqsave(ap->lock, flags);
+			ap->pflags |= ATA_PFLAG_SCSI_HOTPLUG;
+			spin_unlock_irqrestore(ap->lock, flags);
+		}
+	}
+
+	if (rc)
+		*r_failed_dev = dev;
+
+	DPRINTK("EXIT\n");
+	return rc;
+}
+
+/**
+ *	ata_eh_suspend - handle suspend EH action
+ *	@ap: target host port
+ *	@r_failed_dev: result parameter to indicate failing device
+ *
+ *	Handle suspend EH action.  Disk devices are spinned down and
+ *	other types of devices are just marked suspended.  Once
+ *	suspended, no EH action to the device is allowed until it is
+ *	resumed.
+ *
+ *	LOCKING:
+ *	Kernel thread context (may sleep).
+ *
+ *	RETURNS:
+ *	0 on success, -errno otherwise
+ */
+static int ata_eh_suspend(struct ata_port *ap, struct ata_device **r_failed_dev)
+{
+	struct ata_device *dev;
+	int i, rc = 0;
+
+	DPRINTK("ENTER\n");
+
+	for (i = 0; i < ATA_MAX_DEVICES; i++) {
+		unsigned long flags;
+		unsigned int action, err_mask;
+
+		dev = &ap->device[i];
+		action = ata_eh_dev_action(dev);
+
+		if (!ata_dev_enabled(dev) || !(action & ATA_EH_SUSPEND))
+			continue;
+
+		WARN_ON(dev->flags & ATA_DFLAG_SUSPENDED);
+
+		ata_eh_about_to_do(ap, dev, ATA_EH_SUSPEND);
+
+		if (dev->class == ATA_DEV_ATA && !(action & ATA_EH_PM_FREEZE)) {
+			/* flush cache */
+			rc = ata_flush_cache(dev);
+			if (rc)
+				break;
+
+			/* spin down */
+			err_mask = ata_do_simple_cmd(dev, ATA_CMD_STANDBYNOW1);
+			if (err_mask) {
+				ata_dev_printk(dev, KERN_ERR, "failed to "
+					       "spin down (err_mask=0x%x)\n",
+					       err_mask);
+				rc = -EIO;
+				break;
+			}
+		}
+
+		spin_lock_irqsave(ap->lock, flags);
+		dev->flags |= ATA_DFLAG_SUSPENDED;
+		spin_unlock_irqrestore(ap->lock, flags);
+
+		ata_eh_done(ap, dev, ATA_EH_SUSPEND);
+	}
+
+	if (rc)
+		*r_failed_dev = dev;
+
+	DPRINTK("EXIT\n");
+	return 0;
+}
+
+/**
+ *	ata_eh_prep_resume - prep for resume EH action
+ *	@ap: target host port
+ *
+ *	Clear SUSPENDED in preparation for scheduled resume actions.
+ *	This allows other parts of EH to access the devices being
+ *	resumed.
+ *
+ *	LOCKING:
+ *	Kernel thread context (may sleep).
+ */
+static void ata_eh_prep_resume(struct ata_port *ap)
+{
+	struct ata_device *dev;
+	unsigned long flags;
+	int i;
+
+	DPRINTK("ENTER\n");
+
+	for (i = 0; i < ATA_MAX_DEVICES; i++) {
+		unsigned int action;
+
+		dev = &ap->device[i];
+		action = ata_eh_dev_action(dev);
+
+		if (!ata_dev_enabled(dev) || !(action & ATA_EH_RESUME))
+			continue;
+
+		spin_lock_irqsave(ap->lock, flags);
+		dev->flags &= ~ATA_DFLAG_SUSPENDED;
+		spin_unlock_irqrestore(ap->lock, flags);
+	}
+
+	DPRINTK("EXIT\n");
+}
+
+/**
+ *	ata_eh_resume - handle resume EH action
+ *	@ap: target host port
+ *	@r_failed_dev: result parameter to indicate failing device
+ *
+ *	Handle resume EH action.  Target devices are already reset and
+ *	revalidated.  Spinning up is the only operation left.
+ *
+ *	LOCKING:
+ *	Kernel thread context (may sleep).
+ *
+ *	RETURNS:
+ *	0 on success, -errno otherwise
+ */
+static int ata_eh_resume(struct ata_port *ap, struct ata_device **r_failed_dev)
+{
+	struct ata_device *dev;
+	int i, rc = 0;
+
+	DPRINTK("ENTER\n");
+
+	for (i = 0; i < ATA_MAX_DEVICES; i++) {
+		unsigned int action, err_mask;
+
+		dev = &ap->device[i];
+		action = ata_eh_dev_action(dev);
+
+		if (!ata_dev_enabled(dev) || !(action & ATA_EH_RESUME))
+			continue;
+
+		ata_eh_about_to_do(ap, dev, ATA_EH_RESUME);
+
+		if (dev->class == ATA_DEV_ATA && !(action & ATA_EH_PM_FREEZE)) {
+			err_mask = ata_do_simple_cmd(dev,
+						     ATA_CMD_IDLEIMMEDIATE);
+			if (err_mask) {
+				ata_dev_printk(dev, KERN_ERR, "failed to "
+					       "spin up (err_mask=0x%x)\n",
+					       err_mask);
+				rc = -EIO;
+				break;
+			}
+		}
+
+		ata_eh_done(ap, dev, ATA_EH_RESUME);
+	}
+
+	if (rc)
+		*r_failed_dev = dev;
+
+	DPRINTK("EXIT\n");
+	return 0;
+}
+
+static int ata_port_nr_enabled(struct ata_port *ap)
+{
+	int i, cnt = 0;
+
+	for (i = 0; i < ATA_MAX_DEVICES; i++)
+		if (ata_dev_enabled(&ap->device[i]))
+			cnt++;
+	return cnt;
+}
+
+static int ata_port_nr_vacant(struct ata_port *ap)
+{
+	int i, cnt = 0;
+
+	for (i = 0; i < ATA_MAX_DEVICES; i++)
+		if (ap->device[i].class == ATA_DEV_UNKNOWN)
+			cnt++;
+	return cnt;
+}
+
+static int ata_eh_skip_recovery(struct ata_port *ap)
+{
+	struct ata_eh_context *ehc = &ap->eh_context;
+	int i;
+
+	/* skip if all possible devices are suspended */
+	for (i = 0; i < ata_port_max_devices(ap); i++) {
+		struct ata_device *dev = &ap->device[i];
+
+		if (!(dev->flags & ATA_DFLAG_SUSPENDED))
+			break;
+	}
+
+	if (i == ata_port_max_devices(ap))
+		return 1;
+
+	/* thaw frozen port, resume link and recover failed devices */
+	if ((ap->pflags & ATA_PFLAG_FROZEN) ||
+	    (ehc->i.flags & ATA_EHI_RESUME_LINK) || ata_port_nr_enabled(ap))
+		return 0;
+
+	/* skip if class codes for all vacant slots are ATA_DEV_NONE */
+	for (i = 0; i < ATA_MAX_DEVICES; i++) {
+		struct ata_device *dev = &ap->device[i];
+
+		if (dev->class == ATA_DEV_UNKNOWN &&
+		    ehc->classes[dev->devno] != ATA_DEV_NONE)
+			return 0;
+	}
+
+	return 1;
+}
+
+/**
+ *	ata_eh_recover - recover host port after error
+ *	@ap: host port to recover
+ *	@prereset: prereset method (can be NULL)
+ *	@softreset: softreset method (can be NULL)
+ *	@hardreset: hardreset method (can be NULL)
+ *	@postreset: postreset method (can be NULL)
+ *
+ *	This is the alpha and omega, eum and yang, heart and soul of
+ *	libata exception handling.  On entry, actions required to
+ *	recover the port and hotplug requests are recorded in
+ *	eh_context.  This function executes all the operations with
+ *	appropriate retrials and fallbacks to resurrect failed
+ *	devices, detach goners and greet newcomers.
+ *
+ *	LOCKING:
+ *	Kernel thread context (may sleep).
+ *
+ *	RETURNS:
+ *	0 on success, -errno on failure.
+ */
+static int ata_eh_recover(struct ata_port *ap, ata_prereset_fn_t prereset,
+			  ata_reset_fn_t softreset, ata_reset_fn_t hardreset,
+			  ata_postreset_fn_t postreset)
+{
+	struct ata_eh_context *ehc = &ap->eh_context;
+	struct ata_device *dev;
+	int down_xfermask, i, rc;
+
+	DPRINTK("ENTER\n");
+
+	/* prep for recovery */
+	for (i = 0; i < ATA_MAX_DEVICES; i++) {
+		dev = &ap->device[i];
+
+		ehc->tries[dev->devno] = ATA_EH_DEV_TRIES;
+
+		/* process hotplug request */
+		if (dev->flags & ATA_DFLAG_DETACH)
+			ata_eh_detach_dev(dev);
+
+		if (!ata_dev_enabled(dev) &&
+		    ((ehc->i.probe_mask & (1 << dev->devno)) &&
+		     !(ehc->did_probe_mask & (1 << dev->devno)))) {
+			ata_eh_detach_dev(dev);
+			ata_dev_init(dev);
+			ehc->did_probe_mask |= (1 << dev->devno);
+			ehc->i.action |= ATA_EH_SOFTRESET;
+		}
+	}
+
+ retry:
+	down_xfermask = 0;
+	rc = 0;
+
+	/* if UNLOADING, finish immediately */
+	if (ap->pflags & ATA_PFLAG_UNLOADING)
+		goto out;
+
+	/* prep for resume */
+	ata_eh_prep_resume(ap);
+
+	/* skip EH if possible. */
+	if (ata_eh_skip_recovery(ap))
+		ehc->i.action = 0;
+
+	for (i = 0; i < ATA_MAX_DEVICES; i++)
+		ehc->classes[i] = ATA_DEV_UNKNOWN;
+
+	/* reset */
+	if (ehc->i.action & ATA_EH_RESET_MASK) {
+		ata_eh_freeze_port(ap);
+
+		rc = ata_eh_reset(ap, ata_port_nr_vacant(ap), prereset,
+				  softreset, hardreset, postreset);
+		if (rc) {
+			ata_port_printk(ap, KERN_ERR,
+					"reset failed, giving up\n");
+			goto out;
+		}
+
+		ata_eh_thaw_port(ap);
+	}
+
+	/* revalidate existing devices and attach new ones */
+	rc = ata_eh_revalidate_and_attach(ap, &dev);
+	if (rc)
+		goto dev_fail;
+
+	/* resume devices */
+	rc = ata_eh_resume(ap, &dev);
+	if (rc)
+		goto dev_fail;
+
+	/* configure transfer mode if the port has been reset */
+	if (ehc->i.flags & ATA_EHI_DID_RESET) {
+		rc = ata_set_mode(ap, &dev);
+		if (rc) {
+			down_xfermask = 1;
+			goto dev_fail;
+		}
+	}
+
+	/* suspend devices */
+	rc = ata_eh_suspend(ap, &dev);
+	if (rc)
+		goto dev_fail;
+
+	goto out;
+
+ dev_fail:
+	switch (rc) {
+	case -ENODEV:
+		/* device missing, schedule probing */
+		ehc->i.probe_mask |= (1 << dev->devno);
+	case -EINVAL:
+		ehc->tries[dev->devno] = 0;
+		break;
+	case -EIO:
+		sata_down_spd_limit(ap);
+	default:
+		ehc->tries[dev->devno]--;
+		if (down_xfermask &&
+		    ata_down_xfermask_limit(dev, ehc->tries[dev->devno] == 1))
+			ehc->tries[dev->devno] = 0;
+	}
+
+	if (ata_dev_enabled(dev) && !ehc->tries[dev->devno]) {
+		/* disable device if it has used up all its chances */
+		ata_dev_disable(dev);
+
+		/* detach if offline */
+		if (ata_port_offline(ap))
+			ata_eh_detach_dev(dev);
+
+		/* probe if requested */
+		if ((ehc->i.probe_mask & (1 << dev->devno)) &&
+		    !(ehc->did_probe_mask & (1 << dev->devno))) {
+			ata_eh_detach_dev(dev);
+			ata_dev_init(dev);
+
+			ehc->tries[dev->devno] = ATA_EH_DEV_TRIES;
+			ehc->did_probe_mask |= (1 << dev->devno);
+			ehc->i.action |= ATA_EH_SOFTRESET;
+		}
+	} else {
+		/* soft didn't work?  be haaaaard */
+		if (ehc->i.flags & ATA_EHI_DID_RESET)
+			ehc->i.action |= ATA_EH_HARDRESET;
+		else
+			ehc->i.action |= ATA_EH_SOFTRESET;
+	}
+
+	if (ata_port_nr_enabled(ap)) {
+		ata_port_printk(ap, KERN_WARNING, "failed to recover some "
+				"devices, retrying in 5 secs\n");
+		ssleep(5);
+	} else {
+		/* no device left, repeat fast */
+		msleep(500);
+	}
+
+	goto retry;
+
+ out:
+	if (rc) {
+		for (i = 0; i < ATA_MAX_DEVICES; i++)
+			ata_dev_disable(&ap->device[i]);
+	}
+
+	DPRINTK("EXIT, rc=%d\n", rc);
+	return rc;
+}
+
+/**
+ *	ata_eh_finish - finish up EH
+ *	@ap: host port to finish EH for
+ *
+ *	Recovery is complete.  Clean up EH states and retry or finish
+ *	failed qcs.
+ *
+ *	LOCKING:
+ *	None.
+ */
+static void ata_eh_finish(struct ata_port *ap)
+{
+	int tag;
+
+	/* retry or finish qcs */
+	for (tag = 0; tag < ATA_MAX_QUEUE; tag++) {
+		struct ata_queued_cmd *qc = __ata_qc_from_tag(ap, tag);
+
+		if (!(qc->flags & ATA_QCFLAG_FAILED))
+			continue;
+
+		if (qc->err_mask) {
+			/* FIXME: Once EH migration is complete,
+			 * generate sense data in this function,
+			 * considering both err_mask and tf.
+			 */
+			if (qc->err_mask & AC_ERR_INVALID)
+				ata_eh_qc_complete(qc);
+			else
+				ata_eh_qc_retry(qc);
+		} else {
+			if (qc->flags & ATA_QCFLAG_SENSE_VALID) {
+				ata_eh_qc_complete(qc);
+			} else {
+				/* feed zero TF to sense generation */
+				memset(&qc->result_tf, 0, sizeof(qc->result_tf));
+				ata_eh_qc_retry(qc);
+			}
+		}
+	}
+}
+
+/**
+ *	ata_do_eh - do standard error handling
+ *	@ap: host port to handle error for
+ *	@prereset: prereset method (can be NULL)
+ *	@softreset: softreset method (can be NULL)
+ *	@hardreset: hardreset method (can be NULL)
+ *	@postreset: postreset method (can be NULL)
+ *
+ *	Perform standard error handling sequence.
+ *
+ *	LOCKING:
+ *	Kernel thread context (may sleep).
+ */
+void ata_do_eh(struct ata_port *ap, ata_prereset_fn_t prereset,
+	       ata_reset_fn_t softreset, ata_reset_fn_t hardreset,
+	       ata_postreset_fn_t postreset)
+{
+	ata_eh_autopsy(ap);
+	ata_eh_report(ap);
+	ata_eh_recover(ap, prereset, softreset, hardreset, postreset);
+	ata_eh_finish(ap);
+}
+
+/**
+ *	ata_eh_handle_port_suspend - perform port suspend operation
+ *	@ap: port to suspend
+ *
+ *	Suspend @ap.
+ *
+ *	LOCKING:
+ *	Kernel thread context (may sleep).
+ */
+static void ata_eh_handle_port_suspend(struct ata_port *ap)
+{
+	unsigned long flags;
+	int rc = 0;
+
+	/* are we suspending? */
+	spin_lock_irqsave(ap->lock, flags);
+	if (!(ap->pflags & ATA_PFLAG_PM_PENDING) ||
+	    ap->pm_mesg.event == PM_EVENT_ON) {
+		spin_unlock_irqrestore(ap->lock, flags);
+		return;
+	}
+	spin_unlock_irqrestore(ap->lock, flags);
+
+	WARN_ON(ap->pflags & ATA_PFLAG_SUSPENDED);
+
+	/* suspend */
+	ata_eh_freeze_port(ap);
+
+	if (ap->ops->port_suspend)
+		rc = ap->ops->port_suspend(ap, ap->pm_mesg);
+
+	/* report result */
+	spin_lock_irqsave(ap->lock, flags);
+
+	ap->pflags &= ~ATA_PFLAG_PM_PENDING;
+	if (rc == 0)
+		ap->pflags |= ATA_PFLAG_SUSPENDED;
+	else
+		ata_port_schedule_eh(ap);
+
+	if (ap->pm_result) {
+		*ap->pm_result = rc;
+		ap->pm_result = NULL;
+	}
+
+	spin_unlock_irqrestore(ap->lock, flags);
+
+	return;
+}
+
+/**
+ *	ata_eh_handle_port_resume - perform port resume operation
+ *	@ap: port to resume
+ *
+ *	Resume @ap.
+ *
+ *	This function also waits upto one second until all devices
+ *	hanging off this port requests resume EH action.  This is to
+ *	prevent invoking EH and thus reset multiple times on resume.
+ *
+ *	On DPM resume, where some of devices might not be resumed
+ *	together, this may delay port resume upto one second, but such
+ *	DPM resumes are rare and 1 sec delay isn't too bad.
+ *
+ *	LOCKING:
+ *	Kernel thread context (may sleep).
+ */
+static void ata_eh_handle_port_resume(struct ata_port *ap)
+{
+	unsigned long timeout;
+	unsigned long flags;
+	int i, rc = 0;
+
+	/* are we resuming? */
+	spin_lock_irqsave(ap->lock, flags);
+	if (!(ap->pflags & ATA_PFLAG_PM_PENDING) ||
+	    ap->pm_mesg.event != PM_EVENT_ON) {
+		spin_unlock_irqrestore(ap->lock, flags);
+		return;
+	}
+	spin_unlock_irqrestore(ap->lock, flags);
+
+	/* spurious? */
+	if (!(ap->pflags & ATA_PFLAG_SUSPENDED))
+		goto done;
+
+	if (ap->ops->port_resume)
+		rc = ap->ops->port_resume(ap);
+
+	/* give devices time to request EH */
+	timeout = jiffies + HZ; /* 1s max */
+	while (1) {
+		for (i = 0; i < ATA_MAX_DEVICES; i++) {
+			struct ata_device *dev = &ap->device[i];
+			unsigned int action = ata_eh_dev_action(dev);
+
+			if ((dev->flags & ATA_DFLAG_SUSPENDED) &&
+			    !(action & ATA_EH_RESUME))
+				break;
+		}
+
+		if (i == ATA_MAX_DEVICES || time_after(jiffies, timeout))
+			break;
+		msleep(10);
+	}
+
+ done:
+	spin_lock_irqsave(ap->lock, flags);
+	ap->pflags &= ~(ATA_PFLAG_PM_PENDING | ATA_PFLAG_SUSPENDED);
+	if (ap->pm_result) {
+		*ap->pm_result = rc;
+		ap->pm_result = NULL;
+	}
+	spin_unlock_irqrestore(ap->lock, flags);
+}
diff --git a/drivers/scsi/scsi_transport_api.h b/drivers/scsi/scsi_transport_api.h
new file mode 100644
index 000000000..934f0e62b
--- /dev/null
+++ b/drivers/scsi/scsi_transport_api.h
@@ -0,0 +1,6 @@
+#ifndef _SCSI_TRANSPORT_API_H
+#define _SCSI_TRANSPORT_API_H
+
+void scsi_schedule_eh(struct Scsi_Host *shost);
+
+#endif /* _SCSI_TRANSPORT_API_H */
diff --git a/drivers/serial/netx-serial.c b/drivers/serial/netx-serial.c
new file mode 100644
index 000000000..7502109d3
--- /dev/null
+++ b/drivers/serial/netx-serial.c
@@ -0,0 +1,747 @@
+/*
+ * drivers/serial/netx-serial.c
+ *
+ * Copyright (c) 2005 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix
+ *
+ * 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
+ */
+
+#if defined(CONFIG_SERIAL_NETX_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
+#define SUPPORT_SYSRQ
+#endif
+
+#include <linux/device.h>
+#include <linux/module.h>
+#include <linux/ioport.h>
+#include <linux/init.h>
+#include <linux/console.h>
+#include <linux/sysrq.h>
+#include <linux/platform_device.h>
+#include <linux/tty.h>
+#include <linux/tty_flip.h>
+#include <linux/serial_core.h>
+#include <linux/serial.h>
+
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/hardware.h>
+#include <asm/arch/netx-regs.h>
+
+/* We've been assigned a range on the "Low-density serial ports" major */
+#define SERIAL_NX_MAJOR	204
+#define MINOR_START	170
+
+#ifdef CONFIG_SERIAL_NETX_CONSOLE
+
+enum uart_regs {
+	UART_DR              = 0x00,
+	UART_SR              = 0x04,
+	UART_LINE_CR         = 0x08,
+	UART_BAUDDIV_MSB     = 0x0c,
+	UART_BAUDDIV_LSB     = 0x10,
+	UART_CR              = 0x14,
+	UART_FR              = 0x18,
+	UART_IIR             = 0x1c,
+	UART_ILPR            = 0x20,
+	UART_RTS_CR          = 0x24,
+	UART_RTS_LEAD        = 0x28,
+	UART_RTS_TRAIL       = 0x2c,
+	UART_DRV_ENABLE      = 0x30,
+	UART_BRM_CR          = 0x34,
+	UART_RXFIFO_IRQLEVEL = 0x38,
+	UART_TXFIFO_IRQLEVEL = 0x3c,
+};
+
+#define SR_FE (1<<0)
+#define SR_PE (1<<1)
+#define SR_BE (1<<2)
+#define SR_OE (1<<3)
+
+#define LINE_CR_BRK       (1<<0)
+#define LINE_CR_PEN       (1<<1)
+#define LINE_CR_EPS       (1<<2)
+#define LINE_CR_STP2      (1<<3)
+#define LINE_CR_FEN       (1<<4)
+#define LINE_CR_5BIT      (0<<5)
+#define LINE_CR_6BIT      (1<<5)
+#define LINE_CR_7BIT      (2<<5)
+#define LINE_CR_8BIT      (3<<5)
+#define LINE_CR_BITS_MASK (3<<5)
+
+#define CR_UART_EN (1<<0)
+#define CR_SIREN   (1<<1)
+#define CR_SIRLP   (1<<2)
+#define CR_MSIE    (1<<3)
+#define CR_RIE     (1<<4)
+#define CR_TIE     (1<<5)
+#define CR_RTIE    (1<<6)
+#define CR_LBE     (1<<7)
+
+#define FR_CTS  (1<<0)
+#define FR_DSR  (1<<1)
+#define FR_DCD  (1<<2)
+#define FR_BUSY (1<<3)
+#define FR_RXFE (1<<4)
+#define FR_TXFF (1<<5)
+#define FR_RXFF (1<<6)
+#define FR_TXFE (1<<7)
+
+#define IIR_MIS (1<<0)
+#define IIR_RIS (1<<1)
+#define IIR_TIS (1<<2)
+#define IIR_RTIS (1<<3)
+#define IIR_MASK 0xf
+
+#define RTS_CR_AUTO (1<<0)
+#define RTS_CR_RTS  (1<<1)
+#define RTS_CR_COUNT (1<<2)
+#define RTS_CR_MOD2  (1<<3)
+#define RTS_CR_RTS_POL (1<<4)
+#define RTS_CR_CTS_CTR (1<<5)
+#define RTS_CR_CTS_POL (1<<6)
+#define RTS_CR_STICK   (1<<7)
+
+#define UART_PORT_SIZE 0x40
+#define DRIVER_NAME "netx-uart"
+
+struct netx_port {
+	struct uart_port	port;
+};
+
+static void netx_stop_tx(struct uart_port *port)
+{
+	unsigned int val;
+	val = readl(port->membase + UART_CR);
+	writel(val & ~CR_TIE,  port->membase + UART_CR);
+}
+
+static void netx_stop_rx(struct uart_port *port)
+{
+	unsigned int val;
+	val = readl(port->membase + UART_CR);
+	writel(val & ~CR_RIE,  port->membase + UART_CR);
+}
+
+static void netx_enable_ms(struct uart_port *port)
+{
+	unsigned int val;
+	val = readl(port->membase + UART_CR);
+	writel(val | CR_MSIE, port->membase + UART_CR);
+}
+
+static inline void netx_transmit_buffer(struct uart_port *port)
+{
+	struct circ_buf *xmit = &port->info->xmit;
+
+	if (port->x_char) {
+		writel(port->x_char, port->membase + UART_DR);
+		port->icount.tx++;
+		port->x_char = 0;
+		return;
+	}
+
+	if (uart_tx_stopped(port) || uart_circ_empty(xmit)) {
+		netx_stop_tx(port);
+		return;
+	}
+
+	do {
+		/* send xmit->buf[xmit->tail]
+		 * out the port here */
+		writel(xmit->buf[xmit->tail], port->membase + UART_DR);
+		xmit->tail = (xmit->tail + 1) &
+		         (UART_XMIT_SIZE - 1);
+		port->icount.tx++;
+		if (uart_circ_empty(xmit))
+			break;
+	} while (!(readl(port->membase + UART_FR) & FR_TXFF));
+
+	if (uart_circ_empty(xmit))
+		netx_stop_tx(port);
+}
+
+static void netx_start_tx(struct uart_port *port)
+{
+	writel(
+	    readl(port->membase + UART_CR) | CR_TIE, port->membase + UART_CR);
+
+	if (!(readl(port->membase + UART_FR) & FR_TXFF))
+		netx_transmit_buffer(port);
+}
+
+static unsigned int netx_tx_empty(struct uart_port *port)
+{
+	return readl(port->membase + UART_FR) & FR_BUSY ? 0 : TIOCSER_TEMT;
+}
+
+static void netx_txint(struct uart_port *port)
+{
+	struct circ_buf *xmit = &port->info->xmit;
+
+	if (uart_circ_empty(xmit) || uart_tx_stopped(port)) {
+		netx_stop_tx(port);
+		return;
+	}
+
+	netx_transmit_buffer(port);
+
+	if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
+		uart_write_wakeup(port);
+}
+
+static void netx_rxint(struct uart_port *port, struct pt_regs *regs)
+{
+	unsigned char rx, flg, status;
+	struct tty_struct *tty = port->info->tty;
+
+	while (!(readl(port->membase + UART_FR) & FR_RXFE)) {
+		rx = readl(port->membase + UART_DR);
+		flg = TTY_NORMAL;
+		port->icount.rx++;
+		status = readl(port->membase + UART_SR);
+		if (status & SR_BE) {
+			writel(0, port->membase + UART_SR);
+			if (uart_handle_break(port))
+				continue;
+		}
+
+		if (unlikely(status & (SR_FE | SR_PE | SR_OE))) {
+
+			if (status & SR_PE)
+				port->icount.parity++;
+			else if (status & SR_FE)
+				port->icount.frame++;
+			if (status & SR_OE)
+				port->icount.overrun++;
+
+			status &= port->read_status_mask;
+
+			if (status & SR_BE)
+				flg = TTY_BREAK;
+			else if (status & SR_PE)
+				flg = TTY_PARITY;
+			else if (status & SR_FE)
+				flg = TTY_FRAME;
+		}
+
+		if (uart_handle_sysrq_char(port, rx, regs))
+			continue;
+
+		uart_insert_char(port, status, SR_OE, rx, flg);
+	}
+
+	tty_flip_buffer_push(tty);
+	return;
+}
+
+static irqreturn_t netx_int(int irq, void *dev_id, struct pt_regs *regs)
+{
+	struct uart_port *port = (struct uart_port *)dev_id;
+	unsigned long flags;
+	unsigned char status;
+
+	spin_lock_irqsave(&port->lock,flags);
+
+	status = readl(port->membase + UART_IIR) & IIR_MASK;
+	while (status) {
+		if (status & IIR_RIS)
+			netx_rxint(port, regs);
+		if (status & IIR_TIS)
+			netx_txint(port);
+		if (status & IIR_MIS) {
+			if (readl(port->membase + UART_FR) & FR_CTS)
+				uart_handle_cts_change(port, 1);
+			else
+				uart_handle_cts_change(port, 0);
+		}
+		writel(0, port->membase + UART_IIR);
+		status = readl(port->membase + UART_IIR) & IIR_MASK;
+	}
+
+	spin_unlock_irqrestore(&port->lock,flags);
+	return IRQ_HANDLED;
+}
+
+static unsigned int netx_get_mctrl(struct uart_port *port)
+{
+	unsigned int ret = TIOCM_DSR | TIOCM_CAR;
+
+	if (readl(port->membase + UART_FR) & FR_CTS)
+		ret |= TIOCM_CTS;
+
+	return ret;
+}
+
+static void netx_set_mctrl(struct uart_port *port, unsigned int mctrl)
+{
+	unsigned int val;
+
+	if (mctrl & TIOCM_RTS) {
+		val = readl(port->membase + UART_RTS_CR);
+		writel(val | RTS_CR_RTS, port->membase + UART_RTS_CR);
+	}
+}
+
+static void netx_break_ctl(struct uart_port *port, int break_state)
+{
+	unsigned int line_cr;
+	spin_lock_irq(&port->lock);
+
+	line_cr = readl(port->membase + UART_LINE_CR);
+	if (break_state != 0)
+		line_cr |= LINE_CR_BRK;
+	else
+		line_cr &= ~LINE_CR_BRK;
+	writel(line_cr, port->membase + UART_LINE_CR);
+
+	spin_unlock_irq(&port->lock);
+}
+
+static int netx_startup(struct uart_port *port)
+{
+	int ret;
+
+	ret = request_irq(port->irq, netx_int, 0,
+			     DRIVER_NAME, port);
+	if (ret) {
+		dev_err(port->dev, "unable to grab irq%d\n",port->irq);
+		goto exit;
+	}
+
+	writel(readl(port->membase + UART_LINE_CR) | LINE_CR_FEN,
+		port->membase + UART_LINE_CR);
+
+	writel(CR_MSIE | CR_RIE | CR_TIE | CR_RTIE | CR_UART_EN,
+		port->membase + UART_CR);
+
+exit:
+	return ret;
+}
+
+static void netx_shutdown(struct uart_port *port)
+{
+	writel(0, port->membase + UART_CR) ;
+
+	free_irq(port->irq, port);
+}
+
+static void
+netx_set_termios(struct uart_port *port, struct termios *termios,
+		   struct termios *old)
+{
+	unsigned int baud, quot;
+	unsigned char old_cr;
+	unsigned char line_cr = LINE_CR_FEN;
+	unsigned char rts_cr = 0;
+
+	switch (termios->c_cflag & CSIZE) {
+	case CS5:
+		line_cr |= LINE_CR_5BIT;
+		break;
+	case CS6:
+		line_cr |= LINE_CR_6BIT;
+		break;
+	case CS7:
+		line_cr |= LINE_CR_7BIT;
+		break;
+	case CS8:
+		line_cr |= LINE_CR_8BIT;
+		break;
+	}
+
+	if (termios->c_cflag & CSTOPB)
+		line_cr |= LINE_CR_STP2;
+
+	if (termios->c_cflag & PARENB) {
+		line_cr |= LINE_CR_PEN;
+		if (!(termios->c_cflag & PARODD))
+			line_cr |= LINE_CR_EPS;
+	}
+
+	if (termios->c_cflag & CRTSCTS)
+		rts_cr = RTS_CR_AUTO | RTS_CR_CTS_CTR | RTS_CR_RTS_POL;
+
+	baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/16);
+	quot = baud * 4096;
+	quot /= 1000;
+	quot *= 256;
+	quot /= 100000;
+
+	spin_lock_irq(&port->lock);
+
+	uart_update_timeout(port, termios->c_cflag, baud);
+
+	old_cr = readl(port->membase + UART_CR);
+
+	/* disable interrupts */
+	writel(old_cr & ~(CR_MSIE | CR_RIE | CR_TIE | CR_RTIE),
+		port->membase + UART_CR);
+
+	/* drain transmitter */
+	while (readl(port->membase + UART_FR) & FR_BUSY);
+
+	/* disable UART */
+	writel(old_cr & ~CR_UART_EN, port->membase + UART_CR);
+
+	/* modem status interrupts */
+	old_cr &= ~CR_MSIE;
+	if (UART_ENABLE_MS(port, termios->c_cflag))
+		old_cr |= CR_MSIE;
+
+	writel((quot>>8) & 0xff, port->membase + UART_BAUDDIV_MSB);
+	writel(quot & 0xff, port->membase + UART_BAUDDIV_LSB);
+	writel(line_cr, port->membase + UART_LINE_CR);
+
+	writel(rts_cr, port->membase + UART_RTS_CR);
+
+	/*
+	 * Characters to ignore
+	 */
+	port->ignore_status_mask = 0;
+	if (termios->c_iflag & IGNPAR)
+		port->ignore_status_mask |= SR_PE;
+	if (termios->c_iflag & IGNBRK) {
+		port->ignore_status_mask |= SR_BE;
+		/*
+		 * If we're ignoring parity and break indicators,
+		 * ignore overruns too (for real raw support).
+		 */
+		if (termios->c_iflag & IGNPAR)
+			port->ignore_status_mask |= SR_PE;
+	}
+
+	port->read_status_mask = 0;
+	if (termios->c_iflag & (BRKINT | PARMRK))
+		port->read_status_mask |= SR_BE;
+	if (termios->c_iflag & INPCK)
+		port->read_status_mask |= SR_PE | SR_FE;
+
+	writel(old_cr, port->membase + UART_CR);
+
+	spin_unlock_irq(&port->lock);
+}
+
+static const char *netx_type(struct uart_port *port)
+{
+	return port->type == PORT_NETX ? "NETX" : NULL;
+}
+
+static void netx_release_port(struct uart_port *port)
+{
+	release_mem_region(port->mapbase, UART_PORT_SIZE);
+}
+
+static int netx_request_port(struct uart_port *port)
+{
+	return request_mem_region(port->mapbase, UART_PORT_SIZE,
+			DRIVER_NAME) != NULL ? 0 : -EBUSY;
+}
+
+static void netx_config_port(struct uart_port *port, int flags)
+{
+	if (flags & UART_CONFIG_TYPE && netx_request_port(port) == 0)
+		port->type = PORT_NETX;
+}
+
+static int
+netx_verify_port(struct uart_port *port, struct serial_struct *ser)
+{
+	int ret = 0;
+
+	if (ser->type != PORT_UNKNOWN && ser->type != PORT_NETX)
+		ret = -EINVAL;
+
+	return ret;
+}
+
+static struct uart_ops netx_pops = {
+	.tx_empty	= netx_tx_empty,
+	.set_mctrl	= netx_set_mctrl,
+	.get_mctrl	= netx_get_mctrl,
+	.stop_tx	= netx_stop_tx,
+	.start_tx	= netx_start_tx,
+	.stop_rx	= netx_stop_rx,
+	.enable_ms	= netx_enable_ms,
+	.break_ctl	= netx_break_ctl,
+	.startup	= netx_startup,
+	.shutdown	= netx_shutdown,
+	.set_termios	= netx_set_termios,
+	.type		= netx_type,
+	.release_port	= netx_release_port,
+	.request_port	= netx_request_port,
+	.config_port	= netx_config_port,
+	.verify_port	= netx_verify_port,
+};
+
+static struct netx_port netx_ports[] = {
+	{
+	.port = {
+		.type = PORT_NETX,
+		.iotype = UPIO_MEM,
+		.membase = (char __iomem *)io_p2v(NETX_PA_UART0),
+		.mapbase = NETX_PA_UART0,
+		.irq = NETX_IRQ_UART0,
+		.uartclk = 100000000,
+		.fifosize = 16,
+		.flags = UPF_BOOT_AUTOCONF,
+		.ops = &netx_pops,
+		.line = 0,
+	},
+	}, {
+	.port = {
+		.type = PORT_NETX,
+		.iotype = UPIO_MEM,
+		.membase = (char __iomem *)io_p2v(NETX_PA_UART1),
+		.mapbase = NETX_PA_UART1,
+		.irq = NETX_IRQ_UART1,
+		.uartclk = 100000000,
+		.fifosize = 16,
+		.flags = UPF_BOOT_AUTOCONF,
+		.ops = &netx_pops,
+		.line = 1,
+	},
+	}, {
+	.port = {
+		.type = PORT_NETX,
+		.iotype = UPIO_MEM,
+		.membase = (char __iomem *)io_p2v(NETX_PA_UART2),
+		.mapbase = NETX_PA_UART2,
+		.irq = NETX_IRQ_UART2,
+		.uartclk = 100000000,
+		.fifosize = 16,
+		.flags = UPF_BOOT_AUTOCONF,
+		.ops = &netx_pops,
+		.line = 2,
+	},
+	}
+};
+
+static void netx_console_putchar(struct uart_port *port, int ch)
+{
+	while (readl(port->membase + UART_FR) & FR_BUSY);
+	writel(ch, port->membase + UART_DR);
+}
+
+static void
+netx_console_write(struct console *co, const char *s, unsigned int count)
+{
+	struct uart_port *port = &netx_ports[co->index].port;
+	unsigned char cr_save;
+
+	cr_save = readl(port->membase + UART_CR);
+	writel(cr_save | CR_UART_EN, port->membase + UART_CR);
+
+	uart_console_write(port, s, count, netx_console_putchar);
+
+	while (readl(port->membase + UART_FR) & FR_BUSY);
+	writel(cr_save, port->membase + UART_CR);
+}
+
+static void __init
+netx_console_get_options(struct uart_port *port, int *baud,
+			int *parity, int *bits, int *flow)
+{
+	unsigned char line_cr;
+
+	*baud = (readl(port->membase + UART_BAUDDIV_MSB) << 8) |
+		readl(port->membase + UART_BAUDDIV_LSB);
+	*baud *= 1000;
+	*baud /= 4096;
+	*baud *= 1000;
+	*baud /= 256;
+	*baud *= 100;
+
+	line_cr = readl(port->membase + UART_LINE_CR);
+	*parity = 'n';
+	if (line_cr & LINE_CR_PEN) {
+		if (line_cr & LINE_CR_EPS)
+			*parity = 'e';
+		else
+			*parity = 'o';
+	}
+
+	switch (line_cr & LINE_CR_BITS_MASK) {
+	case LINE_CR_8BIT:
+		*bits = 8;
+		break;
+	case LINE_CR_7BIT:
+		*bits = 7;
+		break;
+	case LINE_CR_6BIT:
+		*bits = 6;
+		break;
+	case LINE_CR_5BIT:
+		*bits = 5;
+		break;
+	}
+
+	if (readl(port->membase + UART_RTS_CR) & RTS_CR_AUTO)
+		*flow = 'r';
+}
+
+static int __init
+netx_console_setup(struct console *co, char *options)
+{
+	struct netx_port *sport;
+	int baud = 9600;
+	int bits = 8;
+	int parity = 'n';
+	int flow = 'n';
+
+	/*
+	 * Check whether an invalid uart number has been specified, and
+	 * if so, search for the first available port that does have
+	 * console support.
+	 */
+	if (co->index == -1 || co->index >= ARRAY_SIZE(netx_ports))
+		co->index = 0;
+	sport = &netx_ports[co->index];
+
+	if (options) {
+		uart_parse_options(options, &baud, &parity, &bits, &flow);
+	} else {
+		/* if the UART is enabled, assume it has been correctly setup
+		 * by the bootloader and get the options
+		 */
+		if (readl(sport->port.membase + UART_CR) & CR_UART_EN) {
+			netx_console_get_options(&sport->port, &baud,
+			&parity, &bits, &flow);
+		}
+
+	}
+
+	return uart_set_options(&sport->port, co, baud, parity, bits, flow);
+}
+
+static struct uart_driver netx_reg;
+static struct console netx_console = {
+	.name		= "ttyNX",
+	.write		= netx_console_write,
+	.device		= uart_console_device,
+	.setup		= netx_console_setup,
+	.flags		= CON_PRINTBUFFER,
+	.index		= -1,
+	.data		= &netx_reg,
+};
+
+static int __init netx_console_init(void)
+{
+	register_console(&netx_console);
+	return 0;
+}
+console_initcall(netx_console_init);
+
+#define NETX_CONSOLE	&netx_console
+#else
+#define NETX_CONSOLE	NULL
+#endif
+
+static struct uart_driver netx_reg = {
+	.owner          = THIS_MODULE,
+	.driver_name    = DRIVER_NAME,
+	.dev_name       = "ttyNX",
+	.major          = SERIAL_NX_MAJOR,
+	.minor          = MINOR_START,
+	.nr             = ARRAY_SIZE(netx_ports),
+	.cons           = NETX_CONSOLE,
+};
+
+static int serial_netx_suspend(struct platform_device *pdev, pm_message_t state)
+{
+	struct netx_port *sport = platform_get_drvdata(pdev);
+
+	if (sport)
+		uart_suspend_port(&netx_reg, &sport->port);
+
+	return 0;
+}
+
+static int serial_netx_resume(struct platform_device *pdev)
+{
+	struct netx_port *sport = platform_get_drvdata(pdev);
+
+	if (sport)
+		uart_resume_port(&netx_reg, &sport->port);
+
+	return 0;
+}
+
+static int serial_netx_probe(struct platform_device *pdev)
+{
+	struct uart_port *port = &netx_ports[pdev->id].port;
+
+	dev_info(&pdev->dev, "initialising\n");
+
+	port->dev = &pdev->dev;
+
+	writel(1, port->membase + UART_RXFIFO_IRQLEVEL);
+	uart_add_one_port(&netx_reg, &netx_ports[pdev->id].port);
+	platform_set_drvdata(pdev, &netx_ports[pdev->id]);
+
+	return 0;
+}
+
+static int serial_netx_remove(struct platform_device *pdev)
+{
+	struct netx_port *sport = platform_get_drvdata(pdev);
+
+	platform_set_drvdata(pdev, NULL);
+
+	if (sport)
+		uart_remove_one_port(&netx_reg, &sport->port);
+
+	return 0;
+}
+
+static struct platform_driver serial_netx_driver = {
+	.probe          = serial_netx_probe,
+	.remove         = serial_netx_remove,
+
+	.suspend	= serial_netx_suspend,
+	.resume		= serial_netx_resume,
+
+	.driver		= {
+		.name   = DRIVER_NAME,
+	},
+};
+
+static int __init netx_serial_init(void)
+{
+	int ret;
+
+	printk(KERN_INFO "Serial: NetX driver\n");
+
+	ret = uart_register_driver(&netx_reg);
+	if (ret)
+		return ret;
+
+	ret = platform_driver_register(&serial_netx_driver);
+	if (ret != 0)
+		uart_unregister_driver(&netx_reg);
+
+	return 0;
+}
+
+static void __exit netx_serial_exit(void)
+{
+	platform_driver_unregister(&serial_netx_driver);
+	uart_unregister_driver(&netx_reg);
+}
+
+module_init(netx_serial_init);
+module_exit(netx_serial_exit);
+
+MODULE_AUTHOR("Sascha Hauer");
+MODULE_DESCRIPTION("NetX serial port driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/usb/core/endpoint.c b/drivers/usb/core/endpoint.c
new file mode 100644
index 000000000..247b5a491
--- /dev/null
+++ b/drivers/usb/core/endpoint.c
@@ -0,0 +1,275 @@
+/*
+ * drivers/usb/core/endpoint.c
+ *
+ * (C) Copyright 2002,2004,2006 Greg Kroah-Hartman
+ * (C) Copyright 2002,2004 IBM Corp.
+ * (C) Copyright 2006 Novell Inc.
+ *
+ * Endpoint sysfs stuff
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/usb.h>
+#include "usb.h"
+
+/* endpoint stuff */
+
+struct ep_device {
+	struct usb_endpoint_descriptor *desc;
+	struct usb_device *udev;
+	struct device dev;
+};
+#define to_ep_device(_dev) \
+	container_of(_dev, struct ep_device, dev)
+
+struct ep_attribute {
+	struct attribute attr;
+	ssize_t (*show)(struct usb_device *,
+			struct usb_endpoint_descriptor *, char *);
+};
+#define to_ep_attribute(_attr) \
+	container_of(_attr, struct ep_attribute, attr)
+
+#define usb_ep_attr(field, format_string)			\
+static ssize_t show_ep_##field(struct device *dev,		\
+			       struct device_attribute *attr,	\
+			       char *buf)			\
+{								\
+	struct ep_device *ep = to_ep_device(dev);		\
+	return sprintf(buf, format_string, ep->desc->field);	\
+}								\
+static DEVICE_ATTR(field, S_IRUGO, show_ep_##field, NULL);
+
+usb_ep_attr(bLength, "%02x\n")
+usb_ep_attr(bEndpointAddress, "%02x\n")
+usb_ep_attr(bmAttributes, "%02x\n")
+usb_ep_attr(bInterval, "%02x\n")
+
+static ssize_t show_ep_wMaxPacketSize(struct device *dev,
+				      struct device_attribute *attr, char *buf)
+{
+	struct ep_device *ep = to_ep_device(dev);
+	return sprintf(buf, "%04x\n",
+			le16_to_cpu(ep->desc->wMaxPacketSize) & 0x07ff);
+}
+static DEVICE_ATTR(wMaxPacketSize, S_IRUGO, show_ep_wMaxPacketSize, NULL);
+
+static ssize_t show_ep_type(struct device *dev, struct device_attribute *attr,
+			    char *buf)
+{
+	struct ep_device *ep = to_ep_device(dev);
+	char *type = "unknown";
+
+	switch (ep->desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) {
+	case USB_ENDPOINT_XFER_CONTROL:
+		type = "Control";
+		break;
+	case USB_ENDPOINT_XFER_ISOC:
+		type = "Isoc";
+		break;
+	case USB_ENDPOINT_XFER_BULK:
+		type = "Bulk";
+		break;
+	case USB_ENDPOINT_XFER_INT:
+		type = "Interrupt";
+		break;
+	}
+	return sprintf(buf, "%s\n", type);
+}
+static DEVICE_ATTR(type, S_IRUGO, show_ep_type, NULL);
+
+static ssize_t show_ep_interval(struct device *dev,
+				struct device_attribute *attr, char *buf)
+{
+	struct ep_device *ep = to_ep_device(dev);
+	char unit;
+	unsigned interval = 0;
+	unsigned in;
+
+	in = (ep->desc->bEndpointAddress & USB_DIR_IN);
+
+	switch (ep->desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) {
+	case USB_ENDPOINT_XFER_CONTROL:
+		if (ep->udev->speed == USB_SPEED_HIGH) 	/* uframes per NAK */
+			interval = ep->desc->bInterval;
+		break;
+	case USB_ENDPOINT_XFER_ISOC:
+		interval = 1 << (ep->desc->bInterval - 1);
+		break;
+	case USB_ENDPOINT_XFER_BULK:
+		if (ep->udev->speed == USB_SPEED_HIGH && !in) /* uframes per NAK */
+			interval = ep->desc->bInterval;
+		break;
+	case USB_ENDPOINT_XFER_INT:
+		if (ep->udev->speed == USB_SPEED_HIGH)
+			interval = 1 << (ep->desc->bInterval - 1);
+		else
+			interval = ep->desc->bInterval;
+		break;
+	}
+	interval *= (ep->udev->speed == USB_SPEED_HIGH) ? 125 : 1000;
+	if (interval % 1000)
+		unit = 'u';
+	else {
+		unit = 'm';
+		interval /= 1000;
+	}
+
+	return sprintf(buf, "%d%cs\n", interval, unit);
+}
+static DEVICE_ATTR(interval, S_IRUGO, show_ep_interval, NULL);
+
+static ssize_t show_ep_direction(struct device *dev,
+				 struct device_attribute *attr, char *buf)
+{
+	struct ep_device *ep = to_ep_device(dev);
+	char *direction;
+
+	if ((ep->desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) ==
+			USB_ENDPOINT_XFER_CONTROL)
+		direction = "both";
+	else if (ep->desc->bEndpointAddress & USB_DIR_IN)
+		direction = "in";
+	else
+		direction = "out";
+	return sprintf(buf, "%s\n", direction);
+}
+static DEVICE_ATTR(direction, S_IRUGO, show_ep_direction, NULL);
+
+static struct attribute *ep_dev_attrs[] = {
+	&dev_attr_bLength.attr,
+	&dev_attr_bEndpointAddress.attr,
+	&dev_attr_bmAttributes.attr,
+	&dev_attr_bInterval.attr,
+	&dev_attr_wMaxPacketSize.attr,
+	&dev_attr_interval.attr,
+	&dev_attr_type.attr,
+	&dev_attr_direction.attr,
+	NULL,
+};
+static struct attribute_group ep_dev_attr_grp = {
+	.attrs = ep_dev_attrs,
+};
+
+static struct endpoint_class {
+	struct kref kref;
+	struct class *class;
+} *ep_class;
+
+static int init_endpoint_class(void)
+{
+	int result = 0;
+
+	if (ep_class != NULL) {
+		kref_get(&ep_class->kref);
+		goto exit;
+	}
+
+	ep_class = kmalloc(sizeof(*ep_class), GFP_KERNEL);
+	if (!ep_class) {
+		result = -ENOMEM;
+		goto exit;
+	}
+
+	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);
+		kfree(ep_class);
+		ep_class = NULL;
+		goto exit;
+	}
+
+exit:
+	return result;
+}
+
+static void release_endpoint_class(struct kref *kref)
+{
+	/* Ok, we cheat as we know we only have one ep_class */
+	class_destroy(ep_class->class);
+	kfree(ep_class);
+	ep_class = NULL;
+}
+
+static void destroy_endpoint_class(void)
+{
+	if (ep_class)
+		kref_put(&ep_class->kref, release_endpoint_class);
+}
+
+static void ep_device_release(struct device *dev)
+{
+	struct ep_device *ep_dev = to_ep_device(dev);
+
+	dev_dbg(dev, "%s called for %s\n", __FUNCTION__, dev->bus_id);
+	kfree(ep_dev);
+}
+
+void usb_create_ep_files(struct device *parent,
+			 struct usb_host_endpoint *endpoint,
+			 struct usb_device *udev)
+{
+	char name[8];
+	struct ep_device *ep_dev;
+	int minor;
+	int retval;
+
+	retval = init_endpoint_class();
+	if (retval)
+		goto exit;
+
+	ep_dev = kzalloc(sizeof(*ep_dev), GFP_KERNEL);
+	if (!ep_dev) {
+		retval = -ENOMEM;
+		goto exit;
+	}
+
+	/* fun calculation to determine the minor of this endpoint */
+	minor = (((udev->bus->busnum - 1) * 128) * 16) + (udev->devnum - 1);
+
+	ep_dev->desc = &endpoint->desc;
+	ep_dev->udev = udev;
+	ep_dev->dev.devt = MKDEV(442, minor);	// FIXME fake number...
+	ep_dev->dev.class = ep_class->class;
+	ep_dev->dev.parent = parent;
+	ep_dev->dev.release = ep_device_release;
+	snprintf(ep_dev->dev.bus_id, BUS_ID_SIZE, "usbdev%d.%d_ep%02x",
+		 udev->bus->busnum, udev->devnum,
+		 endpoint->desc.bEndpointAddress);
+
+	retval = device_register(&ep_dev->dev);
+	if (retval)
+		goto error;
+	sysfs_create_group(&ep_dev->dev.kobj, &ep_dev_attr_grp);
+
+	endpoint->ep_dev = ep_dev;
+
+	/* create the symlink to the old-style "ep_XX" directory */
+	sprintf(name, "ep_%02x", endpoint->desc.bEndpointAddress);
+	sysfs_create_link(&parent->kobj, &endpoint->ep_dev->dev.kobj, name);
+
+exit:
+	return;
+error:
+	kfree(ep_dev);
+	return;
+}
+
+void usb_remove_ep_files(struct usb_host_endpoint *endpoint)
+{
+
+	if (endpoint->ep_dev) {
+		char name[8];
+
+		sprintf(name, "ep_%02x", endpoint->desc.bEndpointAddress);
+		sysfs_remove_link(&endpoint->ep_dev->dev.parent->kobj, name);
+		sysfs_remove_group(&endpoint->ep_dev->dev.kobj, &ep_dev_attr_grp);
+		device_unregister(&endpoint->ep_dev->dev);
+		endpoint->ep_dev = NULL;
+	}
+	destroy_endpoint_class();
+}
+
+
diff --git a/drivers/usb/host/ohci-ep93xx.c b/drivers/usb/host/ohci-ep93xx.c
new file mode 100644
index 000000000..6531c4d26
--- /dev/null
+++ b/drivers/usb/host/ohci-ep93xx.c
@@ -0,0 +1,225 @@
+/*
+ * OHCI HCD (Host Controller Driver) for USB.
+ *
+ * (C) Copyright 1999 Roman Weissgaerber <weissg@vienna.at>
+ * (C) Copyright 2000-2002 David Brownell <dbrownell@users.sourceforge.net>
+ * (C) Copyright 2002 Hewlett-Packard Company
+ *
+ * Bus Glue for ep93xx.
+ *
+ * Written by Christopher Hoover <ch@hpl.hp.com>
+ * Based on fragments of previous driver by Russell King et al.
+ *
+ * Modified for LH7A404 from ohci-sa1111.c
+ *  by Durgesh Pattamatta <pattamattad@sharpsec.com>
+ *
+ * Modified for pxa27x from ohci-lh7a404.c
+ *  by Nick Bane <nick@cecomputing.co.uk> 26-8-2004
+ *
+ * Modified for ep93xx from ohci-pxa27x.c
+ *  by Lennert Buytenhek <buytenh@wantstofly.org> 28-2-2006
+ *  Based on an earlier driver by Ray Lehtiniemi
+ *
+ * This file is licenced under the GPL.
+ */
+
+#include <linux/clk.h>
+#include <linux/device.h>
+#include <linux/signal.h>
+#include <linux/platform_device.h>
+
+#include <asm/mach-types.h>
+#include <asm/hardware.h>
+
+static struct clk *usb_host_clock;
+
+static void ep93xx_start_hc(struct device *dev)
+{
+	clk_enable(usb_host_clock);
+}
+
+static void ep93xx_stop_hc(struct device *dev)
+{
+	clk_disable(usb_host_clock);
+}
+
+static int usb_hcd_ep93xx_probe(const struct hc_driver *driver,
+			 struct platform_device *pdev)
+{
+	int retval;
+	struct usb_hcd *hcd;
+
+	if (pdev->resource[1].flags != IORESOURCE_IRQ) {
+		pr_debug("resource[1] is not IORESOURCE_IRQ");
+		return -ENOMEM;
+	}
+
+	hcd = usb_create_hcd(driver, &pdev->dev, "ep93xx");
+	if (hcd == NULL)
+		return -ENOMEM;
+
+	hcd->rsrc_start = pdev->resource[0].start;
+	hcd->rsrc_len = pdev->resource[0].end - pdev->resource[0].start + 1;
+	if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) {
+		usb_put_hcd(hcd);
+		retval = -EBUSY;
+		goto err1;
+	}
+
+	hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len);
+	if (hcd->regs == NULL) {
+		pr_debug("ioremap failed");
+		retval = -ENOMEM;
+		goto err2;
+	}
+
+	usb_host_clock = clk_get(&pdev->dev, "usb_host");
+	ep93xx_start_hc(&pdev->dev);
+
+	ohci_hcd_init(hcd_to_ohci(hcd));
+
+	retval = usb_add_hcd(hcd, pdev->resource[1].start, SA_INTERRUPT);
+	if (retval == 0)
+		return retval;
+
+	ep93xx_stop_hc(&pdev->dev);
+	iounmap(hcd->regs);
+err2:
+	release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
+err1:
+	usb_put_hcd(hcd);
+
+	return retval;
+}
+
+static void usb_hcd_ep93xx_remove(struct usb_hcd *hcd,
+			struct platform_device *pdev)
+{
+	usb_remove_hcd(hcd);
+	ep93xx_stop_hc(&pdev->dev);
+	clk_put(usb_host_clock);
+	iounmap(hcd->regs);
+	release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
+	usb_put_hcd(hcd);
+}
+
+static int __devinit ohci_ep93xx_start(struct usb_hcd *hcd)
+{
+	struct ohci_hcd *ohci = hcd_to_ohci(hcd);
+	int ret;
+
+	if ((ret = ohci_init(ohci)) < 0)
+		return ret;
+
+	if ((ret = ohci_run(ohci)) < 0) {
+		err("can't start %s", hcd->self.bus_name);
+		ohci_stop(hcd);
+		return ret;
+	}
+
+	return 0;
+}
+
+static struct hc_driver ohci_ep93xx_hc_driver = {
+	.description		= hcd_name,
+	.product_desc		= "EP93xx OHCI",
+	.hcd_priv_size		= sizeof(struct ohci_hcd),
+	.irq			= ohci_irq,
+	.flags			= HCD_USB11 | HCD_MEMORY,
+	.start			= ohci_ep93xx_start,
+	.stop			= ohci_stop,
+	.urb_enqueue		= ohci_urb_enqueue,
+	.urb_dequeue		= ohci_urb_dequeue,
+	.endpoint_disable	= ohci_endpoint_disable,
+	.get_frame_number	= ohci_get_frame,
+	.hub_status_data	= ohci_hub_status_data,
+	.hub_control		= ohci_hub_control,
+#ifdef CONFIG_PM
+	.bus_suspend		= ohci_bus_suspend,
+	.bus_resume		= ohci_bus_resume,
+#endif
+	.start_port_reset	= ohci_start_port_reset,
+};
+
+extern int usb_disabled(void);
+
+static int ohci_hcd_ep93xx_drv_probe(struct platform_device *pdev)
+{
+	int ret;
+
+	ret = -ENODEV;
+	if (!usb_disabled())
+		ret = usb_hcd_ep93xx_probe(&ohci_ep93xx_hc_driver, pdev);
+
+	return ret;
+}
+
+static int ohci_hcd_ep93xx_drv_remove(struct platform_device *pdev)
+{
+	struct usb_hcd *hcd = platform_get_drvdata(pdev);
+
+	usb_hcd_ep93xx_remove(hcd, pdev);
+
+	return 0;
+}
+
+#ifdef CONFIG_PM
+static int ohci_hcd_ep93xx_drv_suspend(struct platform_device *pdev, pm_message_t state)
+{
+	struct usb_hcd *hcd = platform_get_drvdata(pdev);
+	struct ochi_hcd *ohci = hcd_to_ohci(hcd);
+
+	if (time_before(jiffies, ohci->next_statechange))
+		msleep(5);
+	ohci->next_statechange = jiffies;
+
+	ep93xx_stop_hc(&pdev->dev);
+	hcd->state = HC_STATE_SUSPENDED;
+	pdev->dev.power.power_state = PMSG_SUSPEND;
+
+	return 0;
+}
+
+static int ohci_hcd_ep93xx_drv_resume(struct platform_device *pdev)
+{
+	struct usb_hcd *hcd = platform_get_drvdata(pdev);
+	struct ohci_hcd *ohci = hcd_to_ohci(hcd);
+	int status;
+
+	if (time_before(jiffies, ohci->next_statechange))
+		msleep(5);
+	ohci->next_statechange = jiffies;
+
+	ep93xx_start_hc(&pdev->dev);
+	pdev->dev.power.power_state = PMSG_ON;
+	usb_hcd_resume_root_hub(hcd);
+
+	return 0;
+}
+#endif
+
+
+static struct platform_driver ohci_hcd_ep93xx_driver = {
+	.probe		= ohci_hcd_ep93xx_drv_probe,
+	.remove		= ohci_hcd_ep93xx_drv_remove,
+#ifdef CONFIG_PM
+	.suspend	= ohci_hcd_ep93xx_drv_suspend,
+	.resume		= ohci_hcd_ep93xx_drv_resume,
+#endif
+	.driver		= {
+		.name	= "ep93xx-ohci",
+	},
+};
+
+static int __init ohci_hcd_ep93xx_init(void)
+{
+	return platform_driver_register(&ohci_hcd_ep93xx_driver);
+}
+
+static void __exit ohci_hcd_ep93xx_cleanup(void)
+{
+	platform_driver_unregister(&ohci_hcd_ep93xx_driver);
+}
+
+module_init(ohci_hcd_ep93xx_init);
+module_exit(ohci_hcd_ep93xx_cleanup);
diff --git a/drivers/usb/misc/appledisplay.c b/drivers/usb/misc/appledisplay.c
new file mode 100644
index 000000000..fc6cc1479
--- /dev/null
+++ b/drivers/usb/misc/appledisplay.c
@@ -0,0 +1,382 @@
+/*
+ * Apple Cinema Display driver
+ *
+ * Copyright (C) 2006  Michael Hanselmann (linux-kernel@hansmi.ch)
+ *
+ * Thanks to Caskey L. Dickson for his work with acdctl.
+ *
+ * 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/kernel.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/usb.h>
+#include <linux/backlight.h>
+#include <linux/timer.h>
+#include <linux/workqueue.h>
+#include <asm/atomic.h>
+#include <asm/semaphore.h>
+
+#define APPLE_VENDOR_ID		0x05AC
+
+#define USB_REQ_GET_REPORT	0x01
+#define USB_REQ_SET_REPORT	0x09
+
+#define ACD_USB_TIMEOUT		250
+
+#define ACD_USB_EDID		0x0302
+#define ACD_USB_BRIGHTNESS	0x0310
+
+#define ACD_BTN_NONE		0
+#define ACD_BTN_BRIGHT_UP	3
+#define ACD_BTN_BRIGHT_DOWN	4
+
+#define ACD_URB_BUFFER_LEN	2
+#define ACD_MSG_BUFFER_LEN	2
+
+#define APPLEDISPLAY_DEVICE(prod)				\
+	.match_flags = USB_DEVICE_ID_MATCH_DEVICE |		\
+		       USB_DEVICE_ID_MATCH_INT_CLASS |		\
+		       USB_DEVICE_ID_MATCH_INT_PROTOCOL,	\
+	.idVendor = APPLE_VENDOR_ID,				\
+	.idProduct = (prod),					\
+	.bInterfaceClass = USB_CLASS_HID,			\
+	.bInterfaceProtocol = 0x00
+
+/* table of devices that work with this driver */
+static struct usb_device_id appledisplay_table [] = {
+	{ APPLEDISPLAY_DEVICE(0x9218) },
+	{ APPLEDISPLAY_DEVICE(0x9219) },
+	{ APPLEDISPLAY_DEVICE(0x921d) },
+
+	/* Terminating entry */
+	{ }
+};
+MODULE_DEVICE_TABLE(usb, appledisplay_table);
+
+/* Structure to hold all of our device specific stuff */
+struct appledisplay {
+	struct usb_device *udev;	/* usb device */
+	struct urb *urb;		/* usb request block */
+	struct backlight_device *bd;	/* backlight device */
+	char *urbdata;			/* interrupt URB data buffer */
+	char *msgdata;			/* control message data buffer */
+
+	struct work_struct work;
+	int button_pressed;
+	spinlock_t lock;
+};
+
+static atomic_t count_displays = ATOMIC_INIT(0);
+static struct workqueue_struct *wq;
+
+static void appledisplay_complete(struct urb *urb, struct pt_regs *regs)
+{
+	struct appledisplay *pdata = urb->context;
+	unsigned long flags;
+	int retval;
+
+	switch (urb->status) {
+	case 0:
+		/* success */
+		break;
+	case -EOVERFLOW:
+		printk(KERN_ERR "appletouch: OVERFLOW with data "
+			"length %d, actual length is %d\n",
+			ACD_URB_BUFFER_LEN, pdata->urb->actual_length);
+	case -ECONNRESET:
+	case -ENOENT:
+	case -ESHUTDOWN:
+		/* This urb is terminated, clean up */
+		dbg("%s - urb shutting down with status: %d",
+			__FUNCTION__, urb->status);
+		return;
+	default:
+		dbg("%s - nonzero urb status received: %d",
+			__FUNCTION__, urb->status);
+		goto exit;
+	}
+
+	spin_lock_irqsave(&pdata->lock, flags);
+
+	switch(pdata->urbdata[1]) {
+	case ACD_BTN_BRIGHT_UP:
+	case ACD_BTN_BRIGHT_DOWN:
+		pdata->button_pressed = 1;
+		queue_work(wq, &pdata->work);
+		break;
+	case ACD_BTN_NONE:
+	default:
+		pdata->button_pressed = 0;
+		break;
+	}
+
+	spin_unlock_irqrestore(&pdata->lock, flags);
+
+exit:
+	retval = usb_submit_urb(pdata->urb, GFP_ATOMIC);
+	if (retval) {
+		err("%s - usb_submit_urb failed with result %d",
+			__FUNCTION__, retval);
+	}
+}
+
+static int appledisplay_bl_update_status(struct backlight_device *bd)
+{
+	struct appledisplay *pdata = class_get_devdata(&bd->class_dev);
+	int retval;
+
+	pdata->msgdata[0] = 0x10;
+	pdata->msgdata[1] = bd->props->brightness;
+
+	retval = usb_control_msg(
+		pdata->udev,
+		usb_sndctrlpipe(pdata->udev, 0),
+		USB_REQ_SET_REPORT,
+		USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
+		ACD_USB_BRIGHTNESS,
+		0,
+		pdata->msgdata, 2,
+		ACD_USB_TIMEOUT);
+
+	return retval;
+}
+
+static int appledisplay_bl_get_brightness(struct backlight_device *bd)
+{
+	struct appledisplay *pdata = class_get_devdata(&bd->class_dev);
+	int retval;
+
+	retval = usb_control_msg(
+		pdata->udev,
+		usb_rcvctrlpipe(pdata->udev, 0),
+		USB_REQ_GET_REPORT,
+		USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
+		ACD_USB_BRIGHTNESS,
+		0,
+		pdata->msgdata, 2,
+		ACD_USB_TIMEOUT);
+
+	if (retval < 0)
+		return retval;
+	else
+		return pdata->msgdata[1];
+}
+
+static struct backlight_properties appledisplay_bl_data = {
+	.owner		= THIS_MODULE,
+	.get_brightness	= appledisplay_bl_get_brightness,
+	.update_status	= appledisplay_bl_update_status,
+	.max_brightness	= 0xFF
+};
+
+static void appledisplay_work(void *private)
+{
+	struct appledisplay *pdata = private;
+	int retval;
+
+	up(&pdata->bd->sem);
+	retval = appledisplay_bl_get_brightness(pdata->bd);
+	if (retval >= 0)
+		pdata->bd->props->brightness = retval;
+	down(&pdata->bd->sem);
+
+	/* Poll again in about 125ms if there's still a button pressed */
+	if (pdata->button_pressed)
+		schedule_delayed_work(&pdata->work, HZ / 8);
+}
+
+static int appledisplay_probe(struct usb_interface *iface,
+	const struct usb_device_id *id)
+{
+	struct appledisplay *pdata;
+	struct usb_device *udev = interface_to_usbdev(iface);
+	struct usb_host_interface *iface_desc;
+	struct usb_endpoint_descriptor *endpoint;
+	int int_in_endpointAddr = 0;
+	int i, retval = -ENOMEM, brightness;
+	char bl_name[20];
+
+	/* set up the endpoint information */
+	/* use only the first interrupt-in endpoint */
+	iface_desc = iface->cur_altsetting;
+	for (i = 0; i < iface_desc->desc.bNumEndpoints; i++) {
+		endpoint = &iface_desc->endpoint[i].desc;
+		if (!int_in_endpointAddr &&
+		    (endpoint->bEndpointAddress & USB_DIR_IN) &&
+		    ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) ==
+		     USB_ENDPOINT_XFER_INT)) {
+			/* we found an interrupt in endpoint */
+			int_in_endpointAddr = endpoint->bEndpointAddress;
+			break;
+		}
+	}
+	if (!int_in_endpointAddr) {
+		err("Could not find int-in endpoint");
+		return -EIO;
+	}
+
+	/* allocate memory for our device state and initialize it */
+	pdata = kzalloc(sizeof(struct appledisplay), GFP_KERNEL);
+	if (!pdata) {
+		retval = -ENOMEM;
+		err("Out of memory");
+		goto error;
+	}
+
+	pdata->udev = udev;
+
+	spin_lock_init(&pdata->lock);
+	INIT_WORK(&pdata->work, appledisplay_work, pdata);
+
+	/* Allocate buffer for control messages */
+	pdata->msgdata = kmalloc(ACD_MSG_BUFFER_LEN, GFP_KERNEL);
+	if (!pdata->msgdata) {
+		retval = -ENOMEM;
+		err("appledisplay: Allocating buffer for control messages "
+			"failed");
+		goto error;
+	}
+
+	/* Allocate interrupt URB */
+	pdata->urb = usb_alloc_urb(0, GFP_KERNEL);
+	if (!pdata->urb) {
+		retval = -ENOMEM;
+		err("appledisplay: Allocating URB failed");
+		goto error;
+	}
+
+	/* Allocate buffer for interrupt data */
+	pdata->urbdata = usb_buffer_alloc(pdata->udev, ACD_URB_BUFFER_LEN,
+		GFP_KERNEL, &pdata->urb->transfer_dma);
+	if (!pdata->urbdata) {
+		retval = -ENOMEM;
+		err("appledisplay: Allocating URB buffer failed");
+		goto error;
+	}
+
+	/* Configure interrupt URB */
+	usb_fill_int_urb(pdata->urb, udev,
+		usb_rcvintpipe(udev, int_in_endpointAddr),
+		pdata->urbdata, ACD_URB_BUFFER_LEN, appledisplay_complete,
+		pdata, 1);
+	if (usb_submit_urb(pdata->urb, GFP_KERNEL)) {
+		retval = -EIO;
+		err("appledisplay: Submitting URB failed");
+		goto error;
+	}
+
+	/* Register backlight device */
+	snprintf(bl_name, sizeof(bl_name), "appledisplay%d",
+		atomic_inc_return(&count_displays) - 1);
+	pdata->bd = backlight_device_register(bl_name, pdata,
+						&appledisplay_bl_data);
+	if (IS_ERR(pdata->bd)) {
+		err("appledisplay: Backlight registration failed");
+		goto error;
+	}
+
+	/* Try to get brightness */
+	up(&pdata->bd->sem);
+	brightness = appledisplay_bl_get_brightness(pdata->bd);
+	down(&pdata->bd->sem);
+
+	if (brightness < 0) {
+		retval = brightness;
+		err("appledisplay: Error while getting initial brightness: %d", retval);
+		goto error;
+	}
+
+	/* Set brightness in backlight device */
+	up(&pdata->bd->sem);
+	pdata->bd->props->brightness = brightness;
+	down(&pdata->bd->sem);
+
+	/* save our data pointer in the interface device */
+	usb_set_intfdata(iface, pdata);
+
+	printk(KERN_INFO "appledisplay: Apple Cinema Display connected\n");
+
+	return 0;
+
+error:
+	if (pdata) {
+		if (pdata->urb) {
+			usb_kill_urb(pdata->urb);
+			if (pdata->urbdata)
+				usb_buffer_free(pdata->udev, ACD_URB_BUFFER_LEN,
+					pdata->urbdata, pdata->urb->transfer_dma);
+			usb_free_urb(pdata->urb);
+		}
+		if (pdata->bd)
+			backlight_device_unregister(pdata->bd);
+		kfree(pdata->msgdata);
+	}
+	usb_set_intfdata(iface, NULL);
+	kfree(pdata);
+	return retval;
+}
+
+static void appledisplay_disconnect(struct usb_interface *iface)
+{
+	struct appledisplay *pdata = usb_get_intfdata(iface);
+
+	if (pdata) {
+		usb_kill_urb(pdata->urb);
+		cancel_delayed_work(&pdata->work);
+		backlight_device_unregister(pdata->bd);
+		usb_buffer_free(pdata->udev, ACD_URB_BUFFER_LEN,
+			pdata->urbdata, pdata->urb->transfer_dma);
+		usb_free_urb(pdata->urb);
+		kfree(pdata->msgdata);
+		kfree(pdata);
+	}
+
+	printk(KERN_INFO "appledisplay: Apple Cinema Display disconnected\n");
+}
+
+static struct usb_driver appledisplay_driver = {
+	.name		= "appledisplay",
+	.probe		= appledisplay_probe,
+	.disconnect	= appledisplay_disconnect,
+	.id_table	= appledisplay_table,
+};
+
+static int __init appledisplay_init(void)
+{
+	wq = create_singlethread_workqueue("appledisplay");
+	if (!wq) {
+		err("Could not create work queue\n");
+		return -ENOMEM;
+	}
+
+	return usb_register(&appledisplay_driver);
+}
+
+static void __exit appledisplay_exit(void)
+{
+	flush_workqueue(wq);
+	destroy_workqueue(wq);
+	usb_deregister(&appledisplay_driver);
+}
+
+MODULE_AUTHOR("Michael Hanselmann");
+MODULE_DESCRIPTION("Apple Cinema Display driver");
+MODULE_LICENSE("GPL");
+
+module_init(appledisplay_init);
+module_exit(appledisplay_exit);
diff --git a/drivers/usb/misc/cypress_cy7c63.c b/drivers/usb/misc/cypress_cy7c63.c
new file mode 100644
index 000000000..9c46746d5
--- /dev/null
+++ b/drivers/usb/misc/cypress_cy7c63.c
@@ -0,0 +1,284 @@
+/*
+* cypress_cy7c63.c
+*
+* Copyright (c) 2006 Oliver Bock (o.bock@fh-wolfenbuettel.de)
+*
+*	This driver is based on the Cypress USB Driver by Marcus Maul
+*	(cyport) and the 2.0 version of Greg Kroah-Hartman's
+*	USB Skeleton driver.
+*
+*	This is a generic driver for the Cypress CY7C63xxx family.
+*	For the time being it enables you to read from and write to
+*	the single I/O ports of the device.
+*
+*	Supported vendors:	AK Modul-Bus Computer GmbH
+*				(Firmware "Port-Chip")
+*
+*	Supported devices:	CY7C63001A-PC
+*				CY7C63001C-PXC
+*				CY7C63001C-SXC
+*
+*	Supported functions:	Read/Write Ports
+*
+*
+*	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.
+*/
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/usb.h>
+
+#define DRIVER_AUTHOR		"Oliver Bock (o.bock@fh-wolfenbuettel.de)"
+#define DRIVER_DESC		"Cypress CY7C63xxx USB driver"
+
+#define CYPRESS_VENDOR_ID	0xa2c
+#define CYPRESS_PRODUCT_ID	0x8
+
+#define CYPRESS_READ_PORT	0x4
+#define CYPRESS_WRITE_PORT	0x5
+
+#define CYPRESS_READ_RAM	0x2
+#define CYPRESS_WRITE_RAM	0x3
+#define CYPRESS_READ_ROM	0x1
+
+#define CYPRESS_READ_PORT_ID0	0
+#define CYPRESS_WRITE_PORT_ID0	0
+#define CYPRESS_READ_PORT_ID1	0x2
+#define CYPRESS_WRITE_PORT_ID1	1
+
+#define CYPRESS_MAX_REQSIZE	8
+
+
+/* table of devices that work with this driver */
+static struct usb_device_id cypress_table [] = {
+	{ USB_DEVICE(CYPRESS_VENDOR_ID, CYPRESS_PRODUCT_ID) },
+	{ }
+};
+MODULE_DEVICE_TABLE(usb, cypress_table);
+
+/* structure to hold all of our device specific stuff */
+struct cypress {
+	struct usb_device *	udev;
+	unsigned char		port[2];
+};
+
+/* used to send usb control messages to device */
+static int vendor_command(struct cypress *dev, unsigned char request,
+			  unsigned char address, unsigned char data)
+{
+	int retval = 0;
+	unsigned int pipe;
+	unsigned char *iobuf;
+
+	/* allocate some memory for the i/o buffer*/
+	iobuf = kzalloc(CYPRESS_MAX_REQSIZE, GFP_KERNEL);
+	if (!iobuf) {
+		dev_err(&dev->udev->dev, "Out of memory!\n");
+		retval = -ENOMEM;
+		goto error;
+	}
+
+	dev_dbg(&dev->udev->dev, "Sending usb_control_msg (data: %d)\n", data);
+
+	/* prepare usb control message and send it upstream */
+	pipe = usb_rcvctrlpipe(dev->udev, 0);
+	retval = usb_control_msg(dev->udev, pipe, request,
+				 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_OTHER,
+				 address, data, iobuf, CYPRESS_MAX_REQSIZE,
+				 USB_CTRL_GET_TIMEOUT);
+
+	/* store returned data (more READs to be added) */
+	switch (request) {
+		case CYPRESS_READ_PORT:
+			if (address == CYPRESS_READ_PORT_ID0) {
+				dev->port[0] = iobuf[1];
+				dev_dbg(&dev->udev->dev,
+					"READ_PORT0 returned: %d\n",
+					dev->port[0]);
+			}
+			else if (address == CYPRESS_READ_PORT_ID1) {
+				dev->port[1] = iobuf[1];
+				dev_dbg(&dev->udev->dev,
+					"READ_PORT1 returned: %d\n",
+					dev->port[1]);
+			}
+			break;
+	}
+
+	kfree(iobuf);
+error:
+	return retval;
+}
+
+/* write port value */
+static ssize_t write_port(struct device *dev, struct device_attribute *attr,
+			  const char *buf, size_t count,
+			  int port_num, int write_id)
+{
+	int value = -1;
+	int result = 0;
+
+	struct usb_interface *intf = to_usb_interface(dev);
+	struct cypress *cyp = usb_get_intfdata(intf);
+
+	dev_dbg(&cyp->udev->dev, "WRITE_PORT%d called\n", port_num);
+
+	/* validate input data */
+	if (sscanf(buf, "%d", &value) < 1) {
+		result = -EINVAL;
+		goto error;
+	}
+	if (value < 0 || value > 255) {
+		result = -EINVAL;
+		goto error;
+	}
+
+	result = vendor_command(cyp, CYPRESS_WRITE_PORT, write_id,
+				(unsigned char)value);
+
+	dev_dbg(&cyp->udev->dev, "Result of vendor_command: %d\n\n", result);
+error:
+	return result < 0 ? result : count;
+}
+
+/* attribute callback handler (write) */
+static ssize_t set_port0_handler(struct device *dev,
+				 struct device_attribute *attr,
+				 const char *buf, size_t count)
+{
+	return write_port(dev, attr, buf, count, 0, CYPRESS_WRITE_PORT_ID0);
+}
+
+/* attribute callback handler (write) */
+static ssize_t set_port1_handler(struct device *dev,
+				 struct device_attribute *attr,
+				 const char *buf, size_t count)
+{
+	return write_port(dev, attr, buf, count, 1, CYPRESS_WRITE_PORT_ID1);
+}
+
+/* read port value */
+static ssize_t read_port(struct device *dev, struct device_attribute *attr,
+			 char *buf, int port_num, int read_id)
+{
+	int result = 0;
+
+	struct usb_interface *intf = to_usb_interface(dev);
+	struct cypress *cyp = usb_get_intfdata(intf);
+
+	dev_dbg(&cyp->udev->dev, "READ_PORT%d called\n", port_num);
+
+	result = vendor_command(cyp, CYPRESS_READ_PORT, read_id, 0);
+
+	dev_dbg(&cyp->udev->dev, "Result of vendor_command: %d\n\n", result);
+
+	return sprintf(buf, "%d", cyp->port[port_num]);
+}
+
+/* attribute callback handler (read) */
+static ssize_t get_port0_handler(struct device *dev,
+				 struct device_attribute *attr, char *buf)
+{
+	return read_port(dev, attr, buf, 0, CYPRESS_READ_PORT_ID0);
+}
+
+/* attribute callback handler (read) */
+static ssize_t get_port1_handler(struct device *dev,
+				 struct device_attribute *attr, char *buf)
+{
+	return read_port(dev, attr, buf, 1, CYPRESS_READ_PORT_ID1);
+}
+
+static DEVICE_ATTR(port0, S_IWUGO | S_IRUGO,
+		   get_port0_handler, set_port0_handler);
+
+static DEVICE_ATTR(port1, S_IWUGO | S_IRUGO,
+		   get_port1_handler, set_port1_handler);
+
+
+static int cypress_probe(struct usb_interface *interface,
+			 const struct usb_device_id *id)
+{
+	struct cypress *dev = NULL;
+	int retval = -ENOMEM;
+
+	/* allocate memory for our device state and initialize it */
+	dev = kzalloc(sizeof(*dev), GFP_KERNEL);
+	if (dev == NULL) {
+		dev_err(&interface->dev, "Out of memory!\n");
+		goto error;
+	}
+
+	dev->udev = usb_get_dev(interface_to_usbdev(interface));
+
+	/* save our data pointer in this interface device */
+	usb_set_intfdata(interface, dev);
+
+	/* create device attribute files */
+	device_create_file(&interface->dev, &dev_attr_port0);
+	device_create_file(&interface->dev, &dev_attr_port1);
+
+	/* let the user know that the device is now attached */
+	dev_info(&interface->dev,
+		 "Cypress CY7C63xxx device now attached\n");
+
+	retval = 0;
+error:
+	return retval;
+}
+
+static void cypress_disconnect(struct usb_interface *interface)
+{
+	struct cypress *dev;
+
+	dev = usb_get_intfdata(interface);
+	usb_set_intfdata(interface, NULL);
+
+	/* remove device attribute files */
+	device_remove_file(&interface->dev, &dev_attr_port0);
+	device_remove_file(&interface->dev, &dev_attr_port1);
+
+	usb_put_dev(dev->udev);
+
+	dev_info(&interface->dev,
+		 "Cypress CY7C63xxx device now disconnected\n");
+
+	kfree(dev);
+}
+
+static struct usb_driver cypress_driver = {
+	.name = "cypress_cy7c63",
+	.probe = cypress_probe,
+	.disconnect = cypress_disconnect,
+	.id_table = cypress_table,
+};
+
+static int __init cypress_init(void)
+{
+	int result;
+
+	/* register this driver with the USB subsystem */
+	result = usb_register(&cypress_driver);
+	if (result) {
+		err("Function usb_register failed! Error number: %d\n", result);
+	}
+
+	return result;
+}
+
+static void __exit cypress_exit(void)
+{
+	/* deregister this driver with the USB subsystem */
+	usb_deregister(&cypress_driver);
+}
+
+module_init(cypress_init);
+module_exit(cypress_exit);
+
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_DESC);
+
+MODULE_LICENSE("GPL");
diff --git a/drivers/usb/serial/sierra.c b/drivers/usb/serial/sierra.c
new file mode 100644
index 000000000..d29638daa
--- /dev/null
+++ b/drivers/usb/serial/sierra.c
@@ -0,0 +1,75 @@
+/*
+ * Sierra Wireless CDMA Wireless Serial USB driver
+ *
+ * Current Copy modified by: Kevin Lloyd <linux@sierrawireless.com>
+ * Original Copyright (C) 2005-2006 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 version
+ *	2 as published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/tty.h>
+#include <linux/module.h>
+#include <linux/usb.h>
+#include <linux/usb/serial.h>
+
+static struct usb_device_id id_table [] = {
+	{ USB_DEVICE(0x1199, 0x0018) },	/* Sierra Wireless MC5720 */
+	{ USB_DEVICE(0x1199, 0x0020) },	/* Sierra Wireless MC5725 */
+	{ USB_DEVICE(0x1199, 0x0017) },	/* Sierra Wireless EM5625 */
+	{ USB_DEVICE(0x1199, 0x0019) },	/* Sierra Wireless AirCard 595 */
+	{ USB_DEVICE(0x1199, 0x6802) },	/* Sierra Wireless MC8755 */
+	{ USB_DEVICE(0x1199, 0x6803) },	/* Sierra Wireless MC8765 */
+	{ USB_DEVICE(0x1199, 0x6812) },	/* Sierra Wireless MC8775 */
+	{ USB_DEVICE(0x1199, 0x6820) },	/* Sierra Wireless AirCard 875 */
+	/* Following devices are supported in the airprime.c driver */
+	/* { USB_DEVICE(0x1199, 0x0112) }, */	/* Sierra Wireless AirCard 580 */
+	/* { USB_DEVICE(0x0F3D, 0x0112) }, */	/* AirPrime/Sierra PC 5220 */
+	{ }
+};
+MODULE_DEVICE_TABLE(usb, id_table);
+
+static struct usb_driver sierra_driver = {
+	.name =		"sierra_wireless",
+	.probe =	usb_serial_probe,
+	.disconnect =	usb_serial_disconnect,
+	.id_table =	id_table,
+};
+
+static struct usb_serial_driver sierra_device = {
+	.driver = {
+	.owner =		THIS_MODULE,
+	.name =			"Sierra_Wireless",
+	},
+	.id_table =		id_table,
+	.num_interrupt_in =	NUM_DONT_CARE,
+	.num_bulk_in =		NUM_DONT_CARE,
+	.num_bulk_out =		NUM_DONT_CARE,
+	.num_ports =		3,
+};
+
+static int __init sierra_init(void)
+{
+	int retval;
+
+	retval = usb_serial_register(&sierra_device);
+	if (retval)
+		return retval;
+	retval = usb_register(&sierra_driver);
+	if (retval)
+		usb_serial_deregister(&sierra_device);
+	return retval;
+}
+
+static void __exit sierra_exit(void)
+{
+	usb_deregister(&sierra_driver);
+	usb_serial_deregister(&sierra_device);
+}
+
+module_init(sierra_init);
+module_exit(sierra_exit);
+MODULE_LICENSE("GPL");
diff --git a/drivers/video/aty/radeon_backlight.c b/drivers/video/aty/radeon_backlight.c
new file mode 100644
index 000000000..585eb7b9e
--- /dev/null
+++ b/drivers/video/aty/radeon_backlight.c
@@ -0,0 +1,247 @@
+/*
+ * Backlight code for ATI Radeon based graphic cards
+ *
+ * Copyright (c) 2000 Ani Joshi <ajoshi@kernel.crashing.org>
+ * Copyright (c) 2003 Benjamin Herrenschmidt <benh@kernel.crashing.org>
+ * Copyright (c) 2006 Michael Hanselmann <linux-kernel@hansmi.ch>
+ *
+ * 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 "radeonfb.h"
+#include <linux/backlight.h>
+
+#ifdef CONFIG_PMAC_BACKLIGHT
+#include <asm/backlight.h>
+#endif
+
+#define MAX_RADEON_LEVEL 0xFF
+
+static struct backlight_properties radeon_bl_data;
+
+struct radeon_bl_privdata {
+	struct radeonfb_info *rinfo;
+	uint8_t negative;
+};
+
+static int radeon_bl_get_level_brightness(struct radeon_bl_privdata *pdata,
+		int level)
+{
+	struct fb_info *info = pdata->rinfo->info;
+	int rlevel;
+
+	mutex_lock(&info->bl_mutex);
+
+	/* Get and convert the value */
+	rlevel = pdata->rinfo->info->bl_curve[level] *
+		 FB_BACKLIGHT_MAX / MAX_RADEON_LEVEL;
+
+	mutex_unlock(&info->bl_mutex);
+
+	if (rlevel < 0)
+		rlevel = 0;
+	else if (rlevel > MAX_RADEON_LEVEL)
+		rlevel = MAX_RADEON_LEVEL;
+
+	if (pdata->negative)
+		rlevel = MAX_RADEON_LEVEL - rlevel;
+
+	return rlevel;
+}
+
+static int radeon_bl_update_status(struct backlight_device *bd)
+{
+	struct radeon_bl_privdata *pdata = class_get_devdata(&bd->class_dev);
+	struct radeonfb_info *rinfo = pdata->rinfo;
+	u32 lvds_gen_cntl, tmpPixclksCntl;
+	int level;
+
+	if (rinfo->mon1_type != MT_LCD)
+		return 0;
+
+	/* We turn off the LCD completely instead of just dimming the
+	 * backlight. This provides some greater power saving and the display
+	 * is useless without backlight anyway.
+	 */
+        if (bd->props->power != FB_BLANK_UNBLANK ||
+	    bd->props->fb_blank != FB_BLANK_UNBLANK)
+		level = 0;
+	else
+		level = bd->props->brightness;
+
+	del_timer_sync(&rinfo->lvds_timer);
+	radeon_engine_idle();
+
+	lvds_gen_cntl = INREG(LVDS_GEN_CNTL);
+	if (level > 0) {
+		lvds_gen_cntl &= ~LVDS_DISPLAY_DIS;
+		if (!(lvds_gen_cntl & LVDS_BLON) || !(lvds_gen_cntl & LVDS_ON)) {
+			lvds_gen_cntl |= (rinfo->init_state.lvds_gen_cntl & LVDS_DIGON);
+			lvds_gen_cntl |= LVDS_BLON | LVDS_EN;
+			OUTREG(LVDS_GEN_CNTL, lvds_gen_cntl);
+			lvds_gen_cntl &= ~LVDS_BL_MOD_LEVEL_MASK;
+			lvds_gen_cntl |=
+				(radeon_bl_get_level_brightness(pdata, level) <<
+				 LVDS_BL_MOD_LEVEL_SHIFT);
+			lvds_gen_cntl |= LVDS_ON;
+			lvds_gen_cntl |= (rinfo->init_state.lvds_gen_cntl & LVDS_BL_MOD_EN);
+			rinfo->pending_lvds_gen_cntl = lvds_gen_cntl;
+			mod_timer(&rinfo->lvds_timer,
+				  jiffies + msecs_to_jiffies(rinfo->panel_info.pwr_delay));
+		} else {
+			lvds_gen_cntl &= ~LVDS_BL_MOD_LEVEL_MASK;
+			lvds_gen_cntl |=
+				(radeon_bl_get_level_brightness(pdata, level) <<
+				 LVDS_BL_MOD_LEVEL_SHIFT);
+			OUTREG(LVDS_GEN_CNTL, lvds_gen_cntl);
+		}
+		rinfo->init_state.lvds_gen_cntl &= ~LVDS_STATE_MASK;
+		rinfo->init_state.lvds_gen_cntl |= rinfo->pending_lvds_gen_cntl
+			& LVDS_STATE_MASK;
+	} else {
+		/* Asic bug, when turning off LVDS_ON, we have to make sure
+		   RADEON_PIXCLK_LVDS_ALWAYS_ON bit is off
+		*/
+		tmpPixclksCntl = INPLL(PIXCLKS_CNTL);
+		if (rinfo->is_mobility || rinfo->is_IGP)
+			OUTPLLP(PIXCLKS_CNTL, 0, ~PIXCLK_LVDS_ALWAYS_ONb);
+		lvds_gen_cntl &= ~(LVDS_BL_MOD_LEVEL_MASK | LVDS_BL_MOD_EN);
+		lvds_gen_cntl |= (radeon_bl_get_level_brightness(pdata, 0) <<
+				  LVDS_BL_MOD_LEVEL_SHIFT);
+		lvds_gen_cntl |= LVDS_DISPLAY_DIS;
+		OUTREG(LVDS_GEN_CNTL, lvds_gen_cntl);
+		udelay(100);
+		lvds_gen_cntl &= ~(LVDS_ON | LVDS_EN);
+		OUTREG(LVDS_GEN_CNTL, lvds_gen_cntl);
+		lvds_gen_cntl &= ~(LVDS_DIGON);
+		rinfo->pending_lvds_gen_cntl = lvds_gen_cntl;
+		mod_timer(&rinfo->lvds_timer,
+			  jiffies + msecs_to_jiffies(rinfo->panel_info.pwr_delay));
+		if (rinfo->is_mobility || rinfo->is_IGP)
+			OUTPLL(PIXCLKS_CNTL, tmpPixclksCntl);
+	}
+	rinfo->init_state.lvds_gen_cntl &= ~LVDS_STATE_MASK;
+	rinfo->init_state.lvds_gen_cntl |= (lvds_gen_cntl & LVDS_STATE_MASK);
+
+	return 0;
+}
+
+static int radeon_bl_get_brightness(struct backlight_device *bd)
+{
+	return bd->props->brightness;
+}
+
+static struct backlight_properties radeon_bl_data = {
+	.owner		= THIS_MODULE,
+	.get_brightness = radeon_bl_get_brightness,
+	.update_status	= radeon_bl_update_status,
+	.max_brightness = (FB_BACKLIGHT_LEVELS - 1),
+};
+
+void radeonfb_bl_init(struct radeonfb_info *rinfo)
+{
+	struct backlight_device *bd;
+	struct radeon_bl_privdata *pdata;
+	char name[12];
+
+	if (rinfo->mon1_type != MT_LCD)
+		return;
+
+#ifdef CONFIG_PMAC_BACKLIGHT
+	if (!pmac_has_backlight_type("ati") &&
+	    !pmac_has_backlight_type("mnca"))
+		return;
+#endif
+
+	pdata = kmalloc(sizeof(struct radeon_bl_privdata), GFP_KERNEL);
+	if (!pdata) {
+		printk("radeonfb: Memory allocation failed\n");
+		goto error;
+	}
+
+	snprintf(name, sizeof(name), "radeonbl%d", rinfo->info->node);
+
+	bd = backlight_device_register(name, pdata, &radeon_bl_data);
+	if (IS_ERR(bd)) {
+		rinfo->info->bl_dev = NULL;
+		printk("radeonfb: Backlight registration failed\n");
+		goto error;
+	}
+
+	pdata->rinfo = rinfo;
+
+	/* Pardon me for that hack... maybe some day we can figure out in what
+	 * direction backlight should work on a given panel?
+	 */
+	pdata->negative =
+		(rinfo->family != CHIP_FAMILY_RV200 &&
+		 rinfo->family != CHIP_FAMILY_RV250 &&
+		 rinfo->family != CHIP_FAMILY_RV280 &&
+		 rinfo->family != CHIP_FAMILY_RV350);
+
+#ifdef CONFIG_PMAC_BACKLIGHT
+	pdata->negative = pdata->negative ||
+		machine_is_compatible("PowerBook4,3") ||
+		machine_is_compatible("PowerBook6,3") ||
+		machine_is_compatible("PowerBook6,5");
+#endif
+
+	mutex_lock(&rinfo->info->bl_mutex);
+	rinfo->info->bl_dev = bd;
+	fb_bl_default_curve(rinfo->info, 0,
+		 63 * FB_BACKLIGHT_MAX / MAX_RADEON_LEVEL,
+		217 * FB_BACKLIGHT_MAX / MAX_RADEON_LEVEL);
+	mutex_unlock(&rinfo->info->bl_mutex);
+
+	down(&bd->sem);
+	bd->props->brightness = radeon_bl_data.max_brightness;
+	bd->props->power = FB_BLANK_UNBLANK;
+	bd->props->update_status(bd);
+	up(&bd->sem);
+
+#ifdef CONFIG_PMAC_BACKLIGHT
+	mutex_lock(&pmac_backlight_mutex);
+	if (!pmac_backlight)
+		pmac_backlight = bd;
+	mutex_unlock(&pmac_backlight_mutex);
+#endif
+
+	printk("radeonfb: Backlight initialized (%s)\n", name);
+
+	return;
+
+error:
+	kfree(pdata);
+	return;
+}
+
+void radeonfb_bl_exit(struct radeonfb_info *rinfo)
+{
+#ifdef CONFIG_PMAC_BACKLIGHT
+	mutex_lock(&pmac_backlight_mutex);
+#endif
+
+	mutex_lock(&rinfo->info->bl_mutex);
+	if (rinfo->info->bl_dev) {
+		struct radeon_bl_privdata *pdata;
+
+#ifdef CONFIG_PMAC_BACKLIGHT
+		if (pmac_backlight == rinfo->info->bl_dev)
+			pmac_backlight = NULL;
+#endif
+
+		pdata = class_get_devdata(&rinfo->info->bl_dev->class_dev);
+		backlight_device_unregister(rinfo->info->bl_dev);
+		kfree(pdata);
+		rinfo->info->bl_dev = NULL;
+
+		printk("radeonfb: Backlight unloaded\n");
+	}
+	mutex_unlock(&rinfo->info->bl_mutex);
+
+#ifdef CONFIG_PMAC_BACKLIGHT
+	mutex_unlock(&pmac_backlight_mutex);
+#endif
+}
diff --git a/drivers/video/fb_notify.c b/drivers/video/fb_notify.c
new file mode 100644
index 000000000..8c020389e
--- /dev/null
+++ b/drivers/video/fb_notify.c
@@ -0,0 +1,46 @@
+/*
+ *  linux/drivers/video/fb_notify.c
+ *
+ *  Copyright (C) 2006 Antonino Daplas <adaplas@pol.net>
+ *
+ *	2001 - Documented with DocBook
+ *	- Brad Douglas <brad@neruo.com>
+ *
+ * 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.
+ */
+#include <linux/fb.h>
+#include <linux/notifier.h>
+
+static BLOCKING_NOTIFIER_HEAD(fb_notifier_list);
+
+/**
+ *	fb_register_client - register a client notifier
+ *	@nb: notifier block to callback on events
+ */
+int fb_register_client(struct notifier_block *nb)
+{
+	return blocking_notifier_chain_register(&fb_notifier_list, nb);
+}
+EXPORT_SYMBOL(fb_register_client);
+
+/**
+ *	fb_unregister_client - unregister a client notifier
+ *	@nb: notifier block to callback on events
+ */
+int fb_unregister_client(struct notifier_block *nb)
+{
+	return blocking_notifier_chain_unregister(&fb_notifier_list, nb);
+}
+EXPORT_SYMBOL(fb_unregister_client);
+
+/**
+ * fb_notifier_call_chain - notify clients of fb_events
+ *
+ */
+int fb_notifier_call_chain(unsigned long val, void *v)
+{
+	return blocking_notifier_call_chain(&fb_notifier_list, val, v);
+}
+EXPORT_SYMBOL_GPL(fb_notifier_call_chain);
diff --git a/drivers/video/imacfb.c b/drivers/video/imacfb.c
new file mode 100644
index 000000000..18ea4a549
--- /dev/null
+++ b/drivers/video/imacfb.c
@@ -0,0 +1,380 @@
+/*
+ * framebuffer driver for Intel Based Mac's
+ *
+ * (c) 2006 Edgar Hucek <gimli@dark-green.com>
+ * Original imac driver written by Gerd Knorr <kraxel@goldbach.in-berlin.de>
+ *
+ */
+
+#include <linux/delay.h>
+#include <linux/errno.h>
+#include <linux/fb.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/screen_info.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+#include <linux/dmi.h>
+#include <linux/efi.h>
+
+#include <asm/io.h>
+
+#include <video/vga.h>
+
+typedef enum _MAC_TYPE {
+	M_I17,
+	M_I20,
+	M_MINI,
+	M_MACBOOK,
+	M_UNKNOWN
+} MAC_TYPE;
+
+/* --------------------------------------------------------------------- */
+
+static struct fb_var_screeninfo imacfb_defined __initdata = {
+	.activate		= FB_ACTIVATE_NOW,
+	.height			= -1,
+	.width			= -1,
+	.right_margin		= 32,
+	.upper_margin		= 16,
+	.lower_margin		= 4,
+	.vsync_len		= 4,
+	.vmode			= FB_VMODE_NONINTERLACED,
+};
+
+static struct fb_fix_screeninfo imacfb_fix __initdata = {
+	.id			= "IMAC VGA",
+	.type			= FB_TYPE_PACKED_PIXELS,
+	.accel			= FB_ACCEL_NONE,
+	.visual			= FB_VISUAL_TRUECOLOR,
+};
+
+static int inverse;
+static int model		= M_UNKNOWN;
+static int manual_height;
+static int manual_width;
+
+static int set_system(struct dmi_system_id *id)
+{
+	printk(KERN_INFO "imacfb: %s detected - set system to %ld\n",
+		id->ident, (long)id->driver_data);
+
+	model = (long)id->driver_data;
+
+	return 0;
+}
+
+static struct dmi_system_id __initdata dmi_system_table[] = {
+	{ set_system, "iMac4,1", {
+	  DMI_MATCH(DMI_BIOS_VENDOR,"Apple Computer, Inc."),
+	  DMI_MATCH(DMI_PRODUCT_NAME,"iMac4,1") }, (void*)M_I17},
+	{ set_system, "MacBookPro1,1", {
+	  DMI_MATCH(DMI_BIOS_VENDOR,"Apple Computer, Inc."),
+	  DMI_MATCH(DMI_PRODUCT_NAME,"MacBookPro1,1") }, (void*)M_I17},
+	{ set_system, "MacBook1,1", {
+	  DMI_MATCH(DMI_BIOS_VENDOR,"Apple Computer, Inc."),
+	  DMI_MATCH(DMI_PRODUCT_NAME,"MacBook1,1")}, (void *)M_MACBOOK},
+	{ set_system, "Macmini1,1", {
+	  DMI_MATCH(DMI_BIOS_VENDOR,"Apple Computer, Inc."),
+	  DMI_MATCH(DMI_PRODUCT_NAME,"Macmini1,1")}, (void *)M_MINI},
+	{},
+};
+
+#define	DEFAULT_FB_MEM	1024*1024*16
+
+/* --------------------------------------------------------------------- */
+
+static int imacfb_setcolreg(unsigned regno, unsigned red, unsigned green,
+			    unsigned blue, unsigned transp,
+			    struct fb_info *info)
+{
+	/*
+	 *  Set a single color register. The values supplied are
+	 *  already rounded down to the hardware's capabilities
+	 *  (according to the entries in the `var' structure). Return
+	 *  != 0 for invalid regno.
+	 */
+
+	if (regno >= info->cmap.len)
+		return 1;
+
+	if (regno < 16) {
+		red   >>= 8;
+		green >>= 8;
+		blue  >>= 8;
+		((u32 *)(info->pseudo_palette))[regno] =
+			(red   << info->var.red.offset)   |
+			(green << info->var.green.offset) |
+			(blue  << info->var.blue.offset);
+	}
+	return 0;
+}
+
+static struct fb_ops imacfb_ops = {
+	.owner		= THIS_MODULE,
+	.fb_setcolreg	= imacfb_setcolreg,
+	.fb_fillrect	= cfb_fillrect,
+	.fb_copyarea	= cfb_copyarea,
+	.fb_imageblit	= cfb_imageblit,
+};
+
+static int __init imacfb_setup(char *options)
+{
+	char *this_opt;
+
+	if (!options || !*options)
+		return 0;
+
+	while ((this_opt = strsep(&options, ",")) != NULL) {
+		if (!*this_opt) continue;
+
+		if (!strcmp(this_opt, "inverse"))
+			inverse = 1;
+		else if (!strcmp(this_opt, "i17"))
+			model = M_I17;
+		else if (!strcmp(this_opt, "i20"))
+			model = M_I20;
+		else if (!strcmp(this_opt, "mini"))
+			model = M_MINI;
+		else if (!strcmp(this_opt, "macbook"))
+			model = M_MACBOOK;
+		else if (!strncmp(this_opt, "height:", 7))
+			manual_height = simple_strtoul(this_opt+7, NULL, 0);
+		else if (!strncmp(this_opt, "width:", 6))
+			manual_width = simple_strtoul(this_opt+6, NULL, 0);
+	}
+	return 0;
+}
+
+static int __init imacfb_probe(struct platform_device *dev)
+{
+	struct fb_info *info;
+	int err;
+	unsigned int size_vmode;
+	unsigned int size_remap;
+	unsigned int size_total;
+
+	screen_info.lfb_depth = 32;
+	screen_info.lfb_size = DEFAULT_FB_MEM / 0x10000;
+	screen_info.pages=1;
+	screen_info.blue_size = 8;
+	screen_info.blue_pos = 0;
+	screen_info.green_size = 8;
+	screen_info.green_pos = 8;
+	screen_info.red_size = 8;
+	screen_info.red_pos = 16;
+	screen_info.rsvd_size = 8;
+	screen_info.rsvd_pos = 24;
+
+	switch (model) {
+	case M_I17:
+		screen_info.lfb_width = 1440;
+		screen_info.lfb_height = 900;
+		screen_info.lfb_linelength = 1472 * 4;
+		screen_info.lfb_base = 0x80010000;
+		break;
+	case M_I20:
+		screen_info.lfb_width = 1680;
+		screen_info.lfb_height = 1050;
+		screen_info.lfb_linelength = 1728 * 4;
+		screen_info.lfb_base = 0x80010000;
+		break;
+	case M_MINI:
+		screen_info.lfb_width = 1024;
+		screen_info.lfb_height = 768;
+		screen_info.lfb_linelength = 2048 * 4;
+		screen_info.lfb_base = 0x80000000;
+		break;
+	case M_MACBOOK:
+		screen_info.lfb_width = 1280;
+		screen_info.lfb_height = 800;
+		screen_info.lfb_linelength = 2048 * 4;
+		screen_info.lfb_base = 0x80000000;
+		break;
+ 	}
+
+	/* if the user wants to manually specify height/width,
+	   we will override the defaults */
+	/* TODO: eventually get auto-detection working */
+	if (manual_height > 0)
+		screen_info.lfb_height = manual_height;
+	if (manual_width > 0)
+		screen_info.lfb_width = manual_width;
+
+	imacfb_fix.smem_start = screen_info.lfb_base;
+	imacfb_defined.bits_per_pixel = screen_info.lfb_depth;
+	imacfb_defined.xres = screen_info.lfb_width;
+	imacfb_defined.yres = screen_info.lfb_height;
+	imacfb_fix.line_length = screen_info.lfb_linelength;
+
+	/*   size_vmode -- that is the amount of memory needed for the
+	 *                 used video mode, i.e. the minimum amount of
+	 *                 memory we need. */
+	size_vmode = imacfb_defined.yres * imacfb_fix.line_length;
+
+	/*   size_total -- all video memory we have. Used for
+	 *                 entries, ressource allocation and bounds
+	 *                 checking. */
+	size_total = screen_info.lfb_size * 65536;
+	if (size_total < size_vmode)
+		size_total = size_vmode;
+
+	/*   size_remap -- the amount of video memory we are going to
+	 *                 use for imacfb.  With modern cards it is no
+	 *                 option to simply use size_total as that
+	 *                 wastes plenty of kernel address space. */
+	size_remap  = size_vmode * 2;
+	if (size_remap < size_vmode)
+		size_remap = size_vmode;
+	if (size_remap > size_total)
+		size_remap = size_total;
+	imacfb_fix.smem_len = size_remap;
+
+#ifndef __i386__
+	screen_info.imacpm_seg = 0;
+#endif
+
+	if (!request_mem_region(imacfb_fix.smem_start, size_total, "imacfb")) {
+		printk(KERN_WARNING
+		       "imacfb: cannot reserve video memory at 0x%lx\n",
+			imacfb_fix.smem_start);
+		/* We cannot make this fatal. Sometimes this comes from magic
+		   spaces our resource handlers simply don't know about */
+	}
+
+	info = framebuffer_alloc(sizeof(u32) * 16, &dev->dev);
+	if (!info) {
+		err = -ENOMEM;
+		goto err_release_mem;
+	}
+	info->pseudo_palette = info->par;
+	info->par = NULL;
+
+	info->screen_base = ioremap(imacfb_fix.smem_start, imacfb_fix.smem_len);
+	if (!info->screen_base) {
+		printk(KERN_ERR "imacfb: abort, cannot ioremap video memory "
+				"0x%x @ 0x%lx\n",
+			imacfb_fix.smem_len, imacfb_fix.smem_start);
+		err = -EIO;
+		goto err_unmap;
+	}
+
+	printk(KERN_INFO "imacfb: framebuffer at 0x%lx, mapped to 0x%p, "
+	       "using %dk, total %dk\n",
+	       imacfb_fix.smem_start, info->screen_base,
+	       size_remap/1024, size_total/1024);
+	printk(KERN_INFO "imacfb: mode is %dx%dx%d, linelength=%d, pages=%d\n",
+	       imacfb_defined.xres, imacfb_defined.yres,
+	       imacfb_defined.bits_per_pixel, imacfb_fix.line_length,
+	       screen_info.pages);
+
+	imacfb_defined.xres_virtual = imacfb_defined.xres;
+	imacfb_defined.yres_virtual = imacfb_fix.smem_len /
+					imacfb_fix.line_length;
+	printk(KERN_INFO "imacfb: scrolling: redraw\n");
+	imacfb_defined.yres_virtual = imacfb_defined.yres;
+
+	/* some dummy values for timing to make fbset happy */
+	imacfb_defined.pixclock     = 10000000 / imacfb_defined.xres *
+					1000 / imacfb_defined.yres;
+	imacfb_defined.left_margin  = (imacfb_defined.xres / 8) & 0xf8;
+	imacfb_defined.hsync_len    = (imacfb_defined.xres / 8) & 0xf8;
+
+	imacfb_defined.red.offset    = screen_info.red_pos;
+	imacfb_defined.red.length    = screen_info.red_size;
+	imacfb_defined.green.offset  = screen_info.green_pos;
+	imacfb_defined.green.length  = screen_info.green_size;
+	imacfb_defined.blue.offset   = screen_info.blue_pos;
+	imacfb_defined.blue.length   = screen_info.blue_size;
+	imacfb_defined.transp.offset = screen_info.rsvd_pos;
+	imacfb_defined.transp.length = screen_info.rsvd_size;
+
+	printk(KERN_INFO "imacfb: %s: "
+	       "size=%d:%d:%d:%d, shift=%d:%d:%d:%d\n",
+	       "Truecolor",
+	       screen_info.rsvd_size,
+	       screen_info.red_size,
+	       screen_info.green_size,
+	       screen_info.blue_size,
+	       screen_info.rsvd_pos,
+	       screen_info.red_pos,
+	       screen_info.green_pos,
+	       screen_info.blue_pos);
+
+	imacfb_fix.ypanstep  = 0;
+	imacfb_fix.ywrapstep = 0;
+
+	/* request failure does not faze us, as vgacon probably has this
+	 * region already (FIXME) */
+	request_region(0x3c0, 32, "imacfb");
+
+	info->fbops = &imacfb_ops;
+	info->var = imacfb_defined;
+	info->fix = imacfb_fix;
+	info->flags = FBINFO_FLAG_DEFAULT;
+
+	if (fb_alloc_cmap(&info->cmap, 256, 0) < 0) {
+		err = -ENOMEM;
+		goto err_unmap;
+	}
+	if (register_framebuffer(info)<0) {
+		err = -EINVAL;
+		goto err_fb_dealoc;
+	}
+	printk(KERN_INFO "fb%d: %s frame buffer device\n",
+	       info->node, info->fix.id);
+	return 0;
+
+err_fb_dealoc:
+	fb_dealloc_cmap(&info->cmap);
+err_unmap:
+	iounmap(info->screen_base);
+	framebuffer_release(info);
+err_release_mem:
+	release_mem_region(imacfb_fix.smem_start, size_total);
+	return err;
+}
+
+static struct platform_driver imacfb_driver = {
+	.probe	= imacfb_probe,
+	.driver	= {
+		.name	= "imacfb",
+	},
+};
+
+static struct platform_device imacfb_device = {
+	.name	= "imacfb",
+};
+
+static int __init imacfb_init(void)
+{
+	int ret;
+	char *option = NULL;
+
+	if (!efi_enabled)
+		return -ENODEV;
+	if (!dmi_check_system(dmi_system_table))
+		return -ENODEV;
+	if (model == M_UNKNOWN)
+		return -ENODEV;
+
+	if (fb_get_options("imacfb", &option))
+		return -ENODEV;
+
+	imacfb_setup(option);
+	ret = platform_driver_register(&imacfb_driver);
+
+	if (!ret) {
+		ret = platform_device_register(&imacfb_device);
+		if (ret)
+			platform_driver_unregister(&imacfb_driver);
+	}
+	return ret;
+}
+module_init(imacfb_init);
+
+MODULE_LICENSE("GPL");
diff --git a/drivers/video/mbx/Makefile b/drivers/video/mbx/Makefile
new file mode 100644
index 000000000..16c1165cf
--- /dev/null
+++ b/drivers/video/mbx/Makefile
@@ -0,0 +1,4 @@
+# Makefile for the 2700G controller driver.
+
+obj-$(CONFIG_FB_MBX)	   += mbxfb.o
+obj-$(CONFIG_FB_MBX_DEBUG) += mbxfbdebugfs.o
diff --git a/drivers/video/mbx/mbxdebugfs.c b/drivers/video/mbx/mbxdebugfs.c
new file mode 100644
index 000000000..84aab3ad0
--- /dev/null
+++ b/drivers/video/mbx/mbxdebugfs.c
@@ -0,0 +1,188 @@
+#include <linux/debugfs.h>
+
+#define BIG_BUFFER_SIZE	(1024)
+
+static char big_buffer[BIG_BUFFER_SIZE];
+
+struct mbxfb_debugfs_data {
+	struct dentry *dir;
+	struct dentry *sysconf;
+	struct dentry *clock;
+	struct dentry *display;
+	struct dentry *gsctl;
+};
+
+static int open_file_generic(struct inode *inode, struct file *file)
+{
+	file->private_data = inode->u.generic_ip;
+	return 0;
+}
+
+static ssize_t write_file_dummy(struct file *file, const char __user *buf,
+				size_t count, loff_t *ppos)
+{
+	return count;
+}
+
+static ssize_t sysconf_read_file(struct file *file, char __user *userbuf,
+				 size_t count, loff_t *ppos)
+{
+	char * s = big_buffer;
+
+	s += sprintf(s, "SYSCFG = %08lx\n", SYSCFG);
+	s += sprintf(s, "PFBASE = %08lx\n", PFBASE);
+	s += sprintf(s, "PFCEIL = %08lx\n", PFCEIL);
+	s += sprintf(s, "POLLFLAG = %08lx\n", POLLFLAG);
+	s += sprintf(s, "SYSRST = %08lx\n", SYSRST);
+
+	return  simple_read_from_buffer(userbuf, count, ppos,
+					big_buffer, s-big_buffer);
+}
+
+
+static ssize_t gsctl_read_file(struct file *file, char __user *userbuf,
+			       size_t count, loff_t *ppos)
+{
+	char * s = big_buffer;
+
+	s += sprintf(s, "GSCTRL = %08lx\n", GSCTRL);
+	s += sprintf(s, "VSCTRL = %08lx\n", VSCTRL);
+	s += sprintf(s, "GBBASE = %08lx\n", GBBASE);
+	s += sprintf(s, "VBBASE = %08lx\n", VBBASE);
+	s += sprintf(s, "GDRCTRL = %08lx\n", GDRCTRL);
+	s += sprintf(s, "VCMSK = %08lx\n", VCMSK);
+	s += sprintf(s, "GSCADR = %08lx\n", GSCADR);
+	s += sprintf(s, "VSCADR = %08lx\n", VSCADR);
+	s += sprintf(s, "VUBASE = %08lx\n", VUBASE);
+	s += sprintf(s, "VVBASE = %08lx\n", VVBASE);
+	s += sprintf(s, "GSADR = %08lx\n", GSADR);
+	s += sprintf(s, "VSADR = %08lx\n", VSADR);
+	s += sprintf(s, "HCCTRL = %08lx\n", HCCTRL);
+	s += sprintf(s, "HCSIZE = %08lx\n", HCSIZE);
+	s += sprintf(s, "HCPOS = %08lx\n", HCPOS);
+	s += sprintf(s, "HCBADR = %08lx\n", HCBADR);
+	s += sprintf(s, "HCCKMSK = %08lx\n", HCCKMSK);
+	s += sprintf(s, "GPLUT = %08lx\n", GPLUT);
+
+	return  simple_read_from_buffer(userbuf, count, ppos,
+					big_buffer, s-big_buffer);
+}
+
+static ssize_t display_read_file(struct file *file, char __user *userbuf,
+				 size_t count, loff_t *ppos)
+{
+	char * s = big_buffer;
+
+	s += sprintf(s, "DSCTRL = %08lx\n", DSCTRL);
+	s += sprintf(s, "DHT01 = %08lx\n", DHT01);
+	s += sprintf(s, "DHT02 = %08lx\n", DHT02);
+	s += sprintf(s, "DHT03 = %08lx\n", DHT03);
+	s += sprintf(s, "DVT01 = %08lx\n", DVT01);
+	s += sprintf(s, "DVT02 = %08lx\n", DVT02);
+	s += sprintf(s, "DVT03 = %08lx\n", DVT03);
+	s += sprintf(s, "DBCOL = %08lx\n", DBCOL);
+	s += sprintf(s, "BGCOLOR = %08lx\n", BGCOLOR);
+	s += sprintf(s, "DINTRS = %08lx\n", DINTRS);
+	s += sprintf(s, "DINTRE = %08lx\n", DINTRE);
+	s += sprintf(s, "DINTRCNT = %08lx\n", DINTRCNT);
+	s += sprintf(s, "DSIG = %08lx\n", DSIG);
+	s += sprintf(s, "DMCTRL = %08lx\n", DMCTRL);
+	s += sprintf(s, "CLIPCTRL = %08lx\n", CLIPCTRL);
+	s += sprintf(s, "SPOCTRL = %08lx\n", SPOCTRL);
+	s += sprintf(s, "SVCTRL = %08lx\n", SVCTRL);
+	s += sprintf(s, "DLSTS = %08lx\n", DLSTS);
+	s += sprintf(s, "DLLCTRL = %08lx\n", DLLCTRL);
+	s += sprintf(s, "DVLNUM = %08lx\n", DVLNUM);
+	s += sprintf(s, "DUCTRL = %08lx\n", DUCTRL);
+	s += sprintf(s, "DVECTRL = %08lx\n", DVECTRL);
+	s += sprintf(s, "DHDET = %08lx\n", DHDET);
+	s += sprintf(s, "DVDET = %08lx\n", DVDET);
+	s += sprintf(s, "DODMSK = %08lx\n", DODMSK);
+	s += sprintf(s, "CSC01 = %08lx\n", CSC01);
+	s += sprintf(s, "CSC02 = %08lx\n", CSC02);
+	s += sprintf(s, "CSC03 = %08lx\n", CSC03);
+	s += sprintf(s, "CSC04 = %08lx\n", CSC04);
+	s += sprintf(s, "CSC05 = %08lx\n", CSC05);
+
+	return  simple_read_from_buffer(userbuf, count, ppos,
+					big_buffer, s-big_buffer);
+}
+
+static ssize_t clock_read_file(struct file *file, char __user *userbuf,
+			       size_t count, loff_t *ppos)
+{
+	char * s = big_buffer;
+
+	s += sprintf(s, "SYSCLKSRC = %08lx\n", SYSCLKSRC);
+	s += sprintf(s, "PIXCLKSRC = %08lx\n", PIXCLKSRC);
+	s += sprintf(s, "CLKSLEEP = %08lx\n", CLKSLEEP);
+	s += sprintf(s, "COREPLL = %08lx\n", COREPLL);
+	s += sprintf(s, "DISPPLL = %08lx\n", DISPPLL);
+	s += sprintf(s, "PLLSTAT = %08lx\n", PLLSTAT);
+	s += sprintf(s, "VOVRCLK = %08lx\n", VOVRCLK);
+	s += sprintf(s, "PIXCLK = %08lx\n", PIXCLK);
+	s += sprintf(s, "MEMCLK = %08lx\n", MEMCLK);
+	s += sprintf(s, "M24CLK = %08lx\n", M24CLK);
+	s += sprintf(s, "MBXCLK = %08lx\n", MBXCLK);
+	s += sprintf(s, "SDCLK = %08lx\n", SDCLK);
+	s += sprintf(s, "PIXCLKDIV = %08lx\n", PIXCLKDIV);
+
+	return  simple_read_from_buffer(userbuf, count, ppos,
+					big_buffer, s-big_buffer);
+}
+
+static struct file_operations sysconf_fops = {
+	.read = sysconf_read_file,
+	.write = write_file_dummy,
+	.open = open_file_generic,
+};
+
+static struct file_operations clock_fops = {
+	.read = clock_read_file,
+	.write = write_file_dummy,
+	.open = open_file_generic,
+};
+
+static struct file_operations display_fops = {
+	.read = display_read_file,
+	.write = write_file_dummy,
+	.open = open_file_generic,
+};
+
+static struct file_operations gsctl_fops = {
+	.read = gsctl_read_file,
+	.write = write_file_dummy,
+	.open = open_file_generic,
+};
+
+
+static void __devinit mbxfb_debugfs_init(struct fb_info *fbi)
+{
+	struct mbxfb_info *mfbi = fbi->par;
+	struct mbxfb_debugfs_data *dbg;
+
+	dbg = kzalloc(sizeof(struct mbxfb_debugfs_data), GFP_KERNEL);
+	mfbi->debugfs_data = dbg;
+
+	dbg->dir = debugfs_create_dir("mbxfb", NULL);
+	dbg->sysconf = debugfs_create_file("sysconf", 0444, dbg->dir,
+				      fbi, &sysconf_fops);
+	dbg->clock = debugfs_create_file("clock", 0444, dbg->dir,
+				    fbi, &clock_fops);
+	dbg->display = debugfs_create_file("display", 0444, dbg->dir,
+				      fbi, &display_fops);
+	dbg->gsctl = debugfs_create_file("gsctl", 0444, dbg->dir,
+				    fbi, &gsctl_fops);
+}
+
+static void __devexit mbxfb_debugfs_remove(struct fb_info *fbi)
+{
+	struct mbxfb_info *mfbi = fbi->par;
+	struct mbxfb_debugfs_data *dbg = mfbi->debugfs_data;
+
+	debugfs_remove(dbg->gsctl);
+	debugfs_remove(dbg->display);
+	debugfs_remove(dbg->clock);
+	debugfs_remove(dbg->sysconf);
+	debugfs_remove(dbg->dir);
+}
diff --git a/drivers/video/mbx/mbxfb.c b/drivers/video/mbx/mbxfb.c
new file mode 100644
index 000000000..6849ab75d
--- /dev/null
+++ b/drivers/video/mbx/mbxfb.c
@@ -0,0 +1,683 @@
+/*
+ *  linux/drivers/video/mbx/mbxfb.c
+ *
+ *  Copyright (C) 2006 Compulab, Ltd.
+ *  Mike Rapoport <mike@compulab.co.il>
+ *
+ *   Based on pxafb.c
+ *
+ * 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.
+ *
+ *   Intel 2700G (Marathon) Graphics Accelerator Frame Buffer Driver
+ *
+ */
+
+#include <linux/delay.h>
+#include <linux/fb.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+
+#include <asm/io.h>
+
+#include <video/mbxfb.h>
+
+#include "regs.h"
+#include "reg_bits.h"
+
+static unsigned long virt_base_2700;
+
+#define MIN_XRES	16
+#define MIN_YRES	16
+#define MAX_XRES	2048
+#define MAX_YRES	2048
+
+#define MAX_PALETTES	16
+
+/* FIXME: take care of different chip revisions with different sizes
+   of ODFB */
+#define MEMORY_OFFSET	0x60000
+
+struct mbxfb_info {
+	struct device *dev;
+
+	struct resource *fb_res;
+	struct resource *fb_req;
+
+	struct resource *reg_res;
+	struct resource *reg_req;
+
+	void __iomem *fb_virt_addr;
+	unsigned long fb_phys_addr;
+
+	void __iomem *reg_virt_addr;
+	unsigned long reg_phys_addr;
+
+	int (*platform_probe) (struct fb_info * fb);
+	int (*platform_remove) (struct fb_info * fb);
+
+	u32 pseudo_palette[MAX_PALETTES];
+#ifdef CONFIG_FB_MBX_DEBUG
+	void *debugfs_data;
+#endif
+
+};
+
+static struct fb_var_screeninfo mbxfb_default __devinitdata = {
+	.xres = 640,
+	.yres = 480,
+	.xres_virtual = 640,
+	.yres_virtual = 480,
+	.bits_per_pixel = 16,
+	.red = {11, 5, 0},
+	.green = {5, 6, 0},
+	.blue = {0, 5, 0},
+	.activate = FB_ACTIVATE_TEST,
+	.height = -1,
+	.width = -1,
+	.pixclock = 40000,
+	.left_margin = 48,
+	.right_margin = 16,
+	.upper_margin = 33,
+	.lower_margin = 10,
+	.hsync_len = 96,
+	.vsync_len = 2,
+	.vmode = FB_VMODE_NONINTERLACED,
+	.sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+};
+
+static struct fb_fix_screeninfo mbxfb_fix  __devinitdata = {
+	.id = "MBX",
+	.type = FB_TYPE_PACKED_PIXELS,
+	.visual = FB_VISUAL_TRUECOLOR,
+	.xpanstep = 0,
+	.ypanstep = 0,
+	.ywrapstep = 0,
+	.accel = FB_ACCEL_NONE,
+};
+
+struct pixclock_div {
+	u8 m;
+	u8 n;
+	u8 p;
+};
+
+static unsigned int mbxfb_get_pixclock(unsigned int pixclock_ps,
+				       struct pixclock_div *div)
+{
+	u8 m, n, p;
+	unsigned int err = 0;
+	unsigned int min_err = ~0x0;
+	unsigned int clk;
+	unsigned int best_clk = 0;
+	unsigned int ref_clk = 13000;	/* FIXME: take from platform data */
+	unsigned int pixclock;
+
+	/* convert pixclock to KHz */
+	pixclock = PICOS2KHZ(pixclock_ps);
+
+	for (m = 1; m < 64; m++) {
+		for (n = 1; n < 8; n++) {
+			for (p = 0; p < 8; p++) {
+				clk = (ref_clk * m) / (n * (1 << p));
+				err = (clk > pixclock) ? (clk - pixclock) :
+					(pixclock - clk);
+				if (err < min_err) {
+					min_err = err;
+					best_clk = clk;
+					div->m = m;
+					div->n = n;
+					div->p = p;
+				}
+			}
+		}
+	}
+	return KHZ2PICOS(best_clk);
+}
+
+static int mbxfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
+			   u_int trans, struct fb_info *info)
+{
+	u32 val, ret = 1;
+
+	if (regno < MAX_PALETTES) {
+		u32 *pal = info->pseudo_palette;
+
+		val = (red & 0xf800) | ((green & 0xfc00) >> 5) |
+			((blue & 0xf800) >> 11);
+		pal[regno] = val;
+		ret = 0;
+	}
+
+	return ret;
+}
+
+static int mbxfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
+{
+	struct pixclock_div div;
+
+	var->pixclock = mbxfb_get_pixclock(var->pixclock, &div);
+
+	if (var->xres < MIN_XRES)
+		var->xres = MIN_XRES;
+	if (var->yres < MIN_YRES)
+		var->yres = MIN_YRES;
+	if (var->xres > MAX_XRES)
+		return -EINVAL;
+	if (var->yres > MAX_YRES)
+		return -EINVAL;
+	var->xres_virtual = max(var->xres_virtual, var->xres);
+	var->yres_virtual = max(var->yres_virtual, var->yres);
+
+	switch (var->bits_per_pixel) {
+		/* 8 bits-per-pixel is not supported yet */
+	case 8:
+		return -EINVAL;
+	case 16:
+		var->green.length = (var->green.length == 5) ? 5 : 6;
+		var->red.length = 5;
+		var->blue.length = 5;
+		var->transp.length = 6 - var->green.length;
+		var->blue.offset = 0;
+		var->green.offset = 5;
+		var->red.offset = 5 + var->green.length;
+		var->transp.offset = (5 + var->red.offset) & 15;
+		break;
+	case 24:		/* RGB 888   */
+	case 32:		/* RGBA 8888 */
+		var->red.offset = 16;
+		var->red.length = 8;
+		var->green.offset = 8;
+		var->green.length = 8;
+		var->blue.offset = 0;
+		var->blue.length = 8;
+		var->transp.length = var->bits_per_pixel - 24;
+		var->transp.offset = (var->transp.length) ? 24 : 0;
+		break;
+	}
+	var->red.msb_right = 0;
+	var->green.msb_right = 0;
+	var->blue.msb_right = 0;
+	var->transp.msb_right = 0;
+
+	return 0;
+}
+
+static int mbxfb_set_par(struct fb_info *info)
+{
+	struct fb_var_screeninfo *var = &info->var;
+	struct pixclock_div div;
+	ushort hbps, ht, hfps, has;
+	ushort vbps, vt, vfps, vas;
+	u32 gsctrl = readl(GSCTRL);
+	u32 gsadr = readl(GSADR);
+
+	info->fix.line_length = var->xres_virtual * var->bits_per_pixel / 8;
+
+	/* setup color mode */
+	gsctrl &= ~(FMsk(GSCTRL_GPIXFMT));
+	/* FIXME: add *WORKING* support for 8-bits per color */
+	if (info->var.bits_per_pixel == 8) {
+		return -EINVAL;
+	} else {
+		fb_dealloc_cmap(&info->cmap);
+		gsctrl &= ~GSCTRL_LUT_EN;
+
+		info->fix.visual = FB_VISUAL_TRUECOLOR;
+		switch (info->var.bits_per_pixel) {
+		case 16:
+			if (info->var.green.length == 5)
+				gsctrl |= GSCTRL_GPIXFMT_ARGB1555;
+			else
+				gsctrl |= GSCTRL_GPIXFMT_RGB565;
+			break;
+		case 24:
+			gsctrl |= GSCTRL_GPIXFMT_RGB888;
+			break;
+		case 32:
+			gsctrl |= GSCTRL_GPIXFMT_ARGB8888;
+			break;
+		}
+	}
+
+	/* setup resolution */
+	gsctrl &= ~(FMsk(GSCTRL_GSWIDTH) | FMsk(GSCTRL_GSHEIGHT));
+	gsctrl |= Gsctrl_Width(info->var.xres - 1) |
+		Gsctrl_Height(info->var.yres - 1);
+	writel(gsctrl, GSCTRL);
+	udelay(1000);
+
+	gsadr &= ~(FMsk(GSADR_SRCSTRIDE));
+	gsadr |= Gsadr_Srcstride(info->var.xres * info->var.bits_per_pixel /
+				 (8 * 16) - 1);
+	writel(gsadr, GSADR);
+	udelay(1000);
+
+	/* setup timings */
+	var->pixclock = mbxfb_get_pixclock(info->var.pixclock, &div);
+
+	writel((Disp_Pll_M(div.m) | Disp_Pll_N(div.n) |
+		Disp_Pll_P(div.p) | DISP_PLL_EN), DISPPLL);
+
+	hbps = var->hsync_len;
+	has = hbps + var->left_margin;
+	hfps = has + var->xres;
+	ht = hfps + var->right_margin;
+
+	vbps = var->vsync_len;
+	vas = vbps + var->upper_margin;
+	vfps = vas + var->yres;
+	vt = vfps + var->lower_margin;
+
+	writel((Dht01_Hbps(hbps) | Dht01_Ht(ht)), DHT01);
+	writel((Dht02_Hlbs(has) | Dht02_Has(has)), DHT02);
+	writel((Dht03_Hfps(hfps) | Dht03_Hrbs(hfps)), DHT03);
+	writel((Dhdet_Hdes(has) | Dhdet_Hdef(hfps)), DHDET);
+
+	writel((Dvt01_Vbps(vbps) | Dvt01_Vt(vt)), DVT01);
+	writel((Dvt02_Vtbs(vas) | Dvt02_Vas(vas)), DVT02);
+	writel((Dvt03_Vfps(vfps) | Dvt03_Vbbs(vfps)), DVT03);
+	writel((Dvdet_Vdes(vas) | Dvdet_Vdef(vfps)), DVDET);
+	writel((Dvectrl_Vevent(vfps) | Dvectrl_Vfetch(vbps)), DVECTRL);
+
+	writel((readl(DSCTRL) | DSCTRL_SYNCGEN_EN), DSCTRL);
+
+	return 0;
+}
+
+static int mbxfb_blank(int blank, struct fb_info *info)
+{
+	switch (blank) {
+	case FB_BLANK_POWERDOWN:
+	case FB_BLANK_VSYNC_SUSPEND:
+	case FB_BLANK_HSYNC_SUSPEND:
+	case FB_BLANK_NORMAL:
+		writel((readl(DSCTRL) & ~DSCTRL_SYNCGEN_EN), DSCTRL);
+		udelay(1000);
+		writel((readl(PIXCLK) & ~PIXCLK_EN), PIXCLK);
+		udelay(1000);
+		writel((readl(VOVRCLK) & ~VOVRCLK_EN), VOVRCLK);
+		udelay(1000);
+		break;
+	case FB_BLANK_UNBLANK:
+		writel((readl(DSCTRL) | DSCTRL_SYNCGEN_EN), DSCTRL);
+		udelay(1000);
+		writel((readl(PIXCLK) | PIXCLK_EN), PIXCLK);
+		udelay(1000);
+		break;
+	}
+	return 0;
+}
+
+static struct fb_ops mbxfb_ops = {
+	.owner = THIS_MODULE,
+	.fb_check_var = mbxfb_check_var,
+	.fb_set_par = mbxfb_set_par,
+	.fb_setcolreg = mbxfb_setcolreg,
+	.fb_fillrect = cfb_fillrect,
+	.fb_copyarea = cfb_copyarea,
+	.fb_imageblit = cfb_imageblit,
+	.fb_blank = mbxfb_blank,
+};
+
+/*
+  Enable external SDRAM controller. Assume that all clocks are active
+  by now.
+*/
+static void __devinit setup_memc(struct fb_info *fbi)
+{
+	struct mbxfb_info *mfbi = fbi->par;
+	unsigned long tmp;
+	int i;
+
+	/* FIXME: use platfrom specific parameters */
+	/* setup SDRAM controller */
+	writel((LMCFG_LMC_DS | LMCFG_LMC_TS | LMCFG_LMD_TS |
+		LMCFG_LMA_TS),
+	       LMCFG);
+	udelay(1000);
+
+	writel(LMPWR_MC_PWR_ACT, LMPWR);
+	udelay(1000);
+
+	/* setup SDRAM timings */
+	writel((Lmtim_Tras(7) | Lmtim_Trp(3) | Lmtim_Trcd(3) |
+		Lmtim_Trc(9) | Lmtim_Tdpl(2)),
+	       LMTIM);
+	udelay(1000);
+	/* setup SDRAM refresh rate */
+	writel(0xc2b, LMREFRESH);
+	udelay(1000);
+	/* setup SDRAM type parameters */
+	writel((LMTYPE_CASLAT_3 | LMTYPE_BKSZ_2 | LMTYPE_ROWSZ_11 |
+		LMTYPE_COLSZ_8),
+	       LMTYPE);
+	udelay(1000);
+	/* enable memory controller */
+	writel(LMPWR_MC_PWR_ACT, LMPWR);
+	udelay(1000);
+
+	/* perform dummy reads */
+	for ( i = 0; i < 16; i++ ) {
+		tmp = readl(fbi->screen_base);
+	}
+}
+
+static void enable_clocks(struct fb_info *fbi)
+{
+	/* enable clocks */
+	writel(SYSCLKSRC_PLL_2, SYSCLKSRC);
+	udelay(1000);
+	writel(PIXCLKSRC_PLL_1, PIXCLKSRC);
+	udelay(1000);
+	writel(0x00000000, CLKSLEEP);
+	udelay(1000);
+	writel((Core_Pll_M(0x17) | Core_Pll_N(0x3) | Core_Pll_P(0x0) |
+		CORE_PLL_EN),
+	       COREPLL);
+	udelay(1000);
+	writel((Disp_Pll_M(0x1b) | Disp_Pll_N(0x7) | Disp_Pll_P(0x1) |
+		DISP_PLL_EN),
+	       DISPPLL);
+
+	writel(0x00000000, VOVRCLK);
+	udelay(1000);
+	writel(PIXCLK_EN, PIXCLK);
+	udelay(1000);
+	writel(MEMCLK_EN, MEMCLK);
+	udelay(1000);
+	writel(0x00000006, M24CLK);
+	udelay(1000);
+	writel(0x00000006, MBXCLK);
+	udelay(1000);
+	writel(SDCLK_EN, SDCLK);
+	udelay(1000);
+	writel(0x00000001, PIXCLKDIV);
+	udelay(1000);
+}
+
+static void __devinit setup_graphics(struct fb_info *fbi)
+{
+	unsigned long gsctrl;
+
+	gsctrl = GSCTRL_GAMMA_EN | Gsctrl_Width(fbi->var.xres - 1) |
+		Gsctrl_Height(fbi->var.yres - 1);
+	switch (fbi->var.bits_per_pixel) {
+	case 16:
+		if (fbi->var.green.length == 5)
+			gsctrl |= GSCTRL_GPIXFMT_ARGB1555;
+		else
+			gsctrl |= GSCTRL_GPIXFMT_RGB565;
+		break;
+	case 24:
+		gsctrl |= GSCTRL_GPIXFMT_RGB888;
+		break;
+	case 32:
+		gsctrl |= GSCTRL_GPIXFMT_ARGB8888;
+		break;
+	}
+
+	writel(gsctrl, GSCTRL);
+	udelay(1000);
+	writel(0x00000000, GBBASE);
+	udelay(1000);
+	writel(0x00ffffff, GDRCTRL);
+	udelay(1000);
+	writel((GSCADR_STR_EN | Gscadr_Gbase_Adr(0x6000)), GSCADR);
+	udelay(1000);
+	writel(0x00000000, GPLUT);
+	udelay(1000);
+}
+
+static void __devinit setup_display(struct fb_info *fbi)
+{
+	unsigned long dsctrl = 0;
+
+	dsctrl = DSCTRL_BLNK_POL;
+	if (fbi->var.sync & FB_SYNC_HOR_HIGH_ACT)
+		dsctrl |= DSCTRL_HS_POL;
+	if (fbi->var.sync & FB_SYNC_VERT_HIGH_ACT)
+		dsctrl |= DSCTRL_VS_POL;
+	writel(dsctrl, DSCTRL);
+	udelay(1000);
+	writel(0xd0303010, DMCTRL);
+	udelay(1000);
+	writel((readl(DSCTRL) | DSCTRL_SYNCGEN_EN), DSCTRL);
+}
+
+static void __devinit enable_controller(struct fb_info *fbi)
+{
+	writel(SYSRST_RST, SYSRST);
+	udelay(1000);
+
+
+	enable_clocks(fbi);
+	setup_memc(fbi);
+	setup_graphics(fbi);
+	setup_display(fbi);
+}
+
+#ifdef CONFIG_PM
+/*
+ * Power management hooks.  Note that we won't be called from IRQ context,
+ * unlike the blank functions above, so we may sleep.
+ */
+static int mbxfb_suspend(struct platform_device *dev, pm_message_t state)
+{
+	/* make frame buffer memory enter self-refresh mode */
+	writel(LMPWR_MC_PWR_SRM, LMPWR);
+	while (LMPWRSTAT != LMPWRSTAT_MC_PWR_SRM)
+		; /* empty statement */
+
+	/* reset the device, since it's initial state is 'mostly sleeping' */
+	writel(SYSRST_RST, SYSRST);
+	return 0;
+}
+
+static int mbxfb_resume(struct platform_device *dev)
+{
+	struct fb_info *fbi = platform_get_drvdata(dev);
+
+	enable_clocks(fbi);
+/* 	setup_graphics(fbi); */
+/* 	setup_display(fbi); */
+
+	writel((readl(DSCTRL) | DSCTRL_SYNCGEN_EN), DSCTRL);
+	return 0;
+}
+#else
+#define mbxfb_suspend	NULL
+#define mbxfb_resume	NULL
+#endif
+
+/* debugfs entries */
+#ifndef CONFIG_FB_MBX_DEBUG
+#define mbxfb_debugfs_init(x)	do {} while(0)
+#define mbxfb_debugfs_remove(x)	do {} while(0)
+#endif
+
+#define res_size(_r) (((_r)->end - (_r)->start) + 1)
+
+static int __devinit mbxfb_probe(struct platform_device *dev)
+{
+	int ret;
+	struct fb_info *fbi;
+	struct mbxfb_info *mfbi;
+	struct mbxfb_platform_data *pdata;
+
+	dev_dbg(dev, "mbxfb_probe\n");
+
+	fbi = framebuffer_alloc(sizeof(struct mbxfb_info), &dev->dev);
+	if (fbi == NULL) {
+		dev_err(&dev->dev, "framebuffer_alloc failed\n");
+		return -ENOMEM;
+	}
+
+	mfbi = fbi->par;
+	fbi->pseudo_palette = mfbi->pseudo_palette;
+	pdata = dev->dev.platform_data;
+	if (pdata->probe)
+		mfbi->platform_probe = pdata->probe;
+	if (pdata->remove)
+		mfbi->platform_remove = pdata->remove;
+
+	mfbi->fb_res = platform_get_resource(dev, IORESOURCE_MEM, 0);
+	mfbi->reg_res = platform_get_resource(dev, IORESOURCE_MEM, 1);
+
+	if (!mfbi->fb_res || !mfbi->reg_res) {
+		dev_err(&dev->dev, "no resources found\n");
+		ret = -ENODEV;
+		goto err1;
+	}
+
+	mfbi->fb_req = request_mem_region(mfbi->fb_res->start,
+					  res_size(mfbi->fb_res), dev->name);
+	if (mfbi->fb_req == NULL) {
+		dev_err(&dev->dev, "failed to claim framebuffer memory\n");
+		ret = -EINVAL;
+		goto err1;
+	}
+	mfbi->fb_phys_addr = mfbi->fb_res->start;
+
+	mfbi->reg_req = request_mem_region(mfbi->reg_res->start,
+					   res_size(mfbi->reg_res), dev->name);
+	if (mfbi->reg_req == NULL) {
+		dev_err(&dev->dev, "failed to claim Marathon registers\n");
+		ret = -EINVAL;
+		goto err2;
+	}
+	mfbi->reg_phys_addr = mfbi->reg_res->start;
+
+	mfbi->reg_virt_addr = ioremap_nocache(mfbi->reg_phys_addr,
+					      res_size(mfbi->reg_req));
+	if (!mfbi->reg_virt_addr) {
+		dev_err(&dev->dev, "failed to ioremap Marathon registers\n");
+		ret = -EINVAL;
+		goto err3;
+	}
+	virt_base_2700 = (unsigned long)mfbi->reg_virt_addr;
+
+	mfbi->fb_virt_addr = ioremap_nocache(mfbi->fb_phys_addr,
+					     res_size(mfbi->fb_req));
+	if (!mfbi->reg_virt_addr) {
+		dev_err(&dev->dev, "failed to ioremap frame buffer\n");
+		ret = -EINVAL;
+		goto err4;
+	}
+
+	/* FIXME: get from platform */
+	fbi->screen_base = (char __iomem *)(mfbi->fb_virt_addr + 0x60000);
+	fbi->screen_size = 8 * 1024 * 1024;	/* 8 Megs */
+	fbi->fbops = &mbxfb_ops;
+
+	fbi->var = mbxfb_default;
+	fbi->fix = mbxfb_fix;
+	fbi->fix.smem_start = mfbi->fb_phys_addr + 0x60000;
+	fbi->fix.smem_len = 8 * 1024 * 1024;
+	fbi->fix.line_length = 640 * 2;
+
+	ret = fb_alloc_cmap(&fbi->cmap, 256, 0);
+	if (ret < 0) {
+		dev_err(&dev->dev, "fb_alloc_cmap failed\n");
+		ret = -EINVAL;
+		goto err5;
+	}
+
+	platform_set_drvdata(dev, fbi);
+
+	printk(KERN_INFO "fb%d: mbx frame buffer device\n", fbi->node);
+
+	if (mfbi->platform_probe)
+		mfbi->platform_probe(fbi);
+
+	enable_controller(fbi);
+
+	mbxfb_debugfs_init(fbi);
+
+	ret = register_framebuffer(fbi);
+	if (ret < 0) {
+		dev_err(&dev->dev, "register_framebuffer failed\n");
+		ret = -EINVAL;
+		goto err6;
+	}
+
+	return 0;
+
+err6:
+	fb_dealloc_cmap(&fbi->cmap);
+err5:
+	iounmap(mfbi->fb_virt_addr);
+err4:
+	iounmap(mfbi->reg_virt_addr);
+err3:
+	release_mem_region(mfbi->reg_res->start, res_size(mfbi->reg_res));
+err2:
+	release_mem_region(mfbi->fb_res->start, res_size(mfbi->fb_res));
+err1:
+	framebuffer_release(fbi);
+
+	return ret;
+}
+
+static int __devexit mbxfb_remove(struct platform_device *dev)
+{
+	struct fb_info *fbi = platform_get_drvdata(dev);
+
+	writel(SYSRST_RST, SYSRST);
+	udelay(1000);
+
+	mbxfb_debugfs_remove(fbi);
+
+	if (fbi) {
+		struct mbxfb_info *mfbi = fbi->par;
+
+		unregister_framebuffer(fbi);
+		if (mfbi) {
+			if (mfbi->platform_remove)
+				mfbi->platform_remove(fbi);
+
+			if (mfbi->fb_virt_addr)
+				iounmap(mfbi->fb_virt_addr);
+			if (mfbi->reg_virt_addr)
+				iounmap(mfbi->reg_virt_addr);
+			if (mfbi->reg_req)
+				release_mem_region(mfbi->reg_req->start,
+						   res_size(mfbi->reg_req));
+			if (mfbi->fb_req)
+				release_mem_region(mfbi->fb_req->start,
+						   res_size(mfbi->fb_req));
+		}
+		framebuffer_release(fbi);
+	}
+
+	return 0;
+}
+
+static struct platform_driver mbxfb_driver = {
+	.probe = mbxfb_probe,
+	.remove = mbxfb_remove,
+	.suspend = mbxfb_suspend,
+	.resume = mbxfb_resume,
+	.driver = {
+		.name = "mbx-fb",
+	},
+};
+
+int __devinit mbxfb_init(void)
+{
+	return platform_driver_register(&mbxfb_driver);
+}
+
+static void __devexit mbxfb_exit(void)
+{
+	platform_driver_unregister(&mbxfb_driver);
+}
+
+module_init(mbxfb_init);
+module_exit(mbxfb_exit);
+
+MODULE_DESCRIPTION("loadable framebuffer driver for Marathon device");
+MODULE_AUTHOR("Mike Rapoport, Compulab");
+MODULE_LICENSE("GPL");
diff --git a/drivers/video/mbx/reg_bits.h b/drivers/video/mbx/reg_bits.h
new file mode 100644
index 000000000..c226a8e45
--- /dev/null
+++ b/drivers/video/mbx/reg_bits.h
@@ -0,0 +1,418 @@
+#ifndef __REG_BITS_2700G_
+#define __REG_BITS_2700G_
+
+/* use defines from asm-arm/arch-pxa/bitfields.h for bit fields access */
+#define UData(Data)	((unsigned long) (Data))
+#define Fld(Size, Shft)	(((Size) << 16) + (Shft))
+#define FSize(Field)	((Field) >> 16)
+#define FShft(Field)	((Field) & 0x0000FFFF)
+#define FMsk(Field)	(((UData (1) << FSize (Field)) - 1) << FShft (Field))
+#define FAlnMsk(Field)	((UData (1) << FSize (Field)) - 1)
+#define F1stBit(Field)	(UData (1) << FShft (Field))
+
+#define SYSRST_RST	(1 << 0)
+
+/* SYSCLKSRC - SYSCLK Source Control Register */
+#define SYSCLKSRC_SEL	Fld(2,0)
+#define SYSCLKSRC_REF	((0x0) << FShft(SYSCLKSRC_SEL))
+#define SYSCLKSRC_PLL_1	((0x1) << FShft(SYSCLKSRC_SEL))
+#define SYSCLKSRC_PLL_2	((0x2) << FShft(SYSCLKSRC_SEL))
+
+/* PIXCLKSRC - PIXCLK Source Control Register */
+#define PIXCLKSRC_SEL	Fld(2,0)
+#define PIXCLKSRC_REF	((0x0) << FShft(PIXCLKSRC_SEL))
+#define PIXCLKSRC_PLL_1	((0x1) << FShft(PIXCLKSRC_SEL))
+#define PIXCLKSRC_PLL_2	((0x2) << FShft(PIXCLKSRC_SEL))
+
+/* Clock Disable Register */
+#define CLKSLEEP_SLP	(1 << 0)
+
+/* Core PLL Control Register */
+#define CORE_PLL_M	Fld(6,7)
+#define Core_Pll_M(x)	((x) << FShft(CORE_PLL_M))
+#define CORE_PLL_N	Fld(3,4)
+#define Core_Pll_N(x)	((x) << FShft(CORE_PLL_N))
+#define CORE_PLL_P	Fld(3,1)
+#define Core_Pll_P(x)	((x) << FShft(CORE_PLL_P))
+#define CORE_PLL_EN	(1 << 0)
+
+/* Display PLL Control Register */
+#define DISP_PLL_M	Fld(6,7)
+#define Disp_Pll_M(x)	((x) << FShft(DISP_PLL_M))
+#define DISP_PLL_N	Fld(3,4)
+#define Disp_Pll_N(x)	((x) << FShft(DISP_PLL_N))
+#define DISP_PLL_P	Fld(3,1)
+#define Disp_Pll_P(x)	((x) << FShft(DISP_PLL_P))
+#define DISP_PLL_EN	(1 << 0)
+
+/* PLL status register */
+#define PLLSTAT_CORE_PLL_LOST_L	(1 << 3)
+#define PLLSTAT_CORE_PLL_LSTS	(1 << 2)
+#define PLLSTAT_DISP_PLL_LOST_L	(1 << 1)
+#define PLLSTAT_DISP_PLL_LSTS	(1 << 0)
+
+/* Video and scale clock control register */
+#define VOVRCLK_EN	(1 << 0)
+
+/* Pixel clock control register */
+#define PIXCLK_EN	(1 << 0)
+
+/* Memory clock control register */
+#define MEMCLK_EN	(1 << 0)
+
+/* MBX clock control register */
+#define MBXCLK_DIV	Fld(2,2)
+#define MBXCLK_DIV_1	((0x0) << FShft(MBXCLK_DIV))
+#define MBXCLK_DIV_2	((0x1) << FShft(MBXCLK_DIV))
+#define MBXCLK_DIV_3	((0x2) << FShft(MBXCLK_DIV))
+#define MBXCLK_DIV_4	((0x3) << FShft(MBXCLK_DIV))
+#define MBXCLK_EN	Fld(2,0)
+#define MBXCLK_EN_NONE	((0x0) << FShft(MBXCLK_EN))
+#define MBXCLK_EN_2D	((0x1) << FShft(MBXCLK_EN))
+#define MBXCLK_EN_BOTH	((0x2) << FShft(MBXCLK_EN))
+
+/* M24 clock control register */
+#define M24CLK_DIV	Fld(2,1)
+#define M24CLK_DIV_1	((0x0) << FShft(M24CLK_DIV))
+#define M24CLK_DIV_2	((0x1) << FShft(M24CLK_DIV))
+#define M24CLK_DIV_3	((0x2) << FShft(M24CLK_DIV))
+#define M24CLK_DIV_4	((0x3) << FShft(M24CLK_DIV))
+#define M24CLK_EN	(1 << 0)
+
+/* SDRAM clock control register */
+#define SDCLK_EN	(1 << 0)
+
+/* PixClk Divisor Register */
+#define PIXCLKDIV_PD	Fld(9,0)
+#define Pixclkdiv_Pd(x)	((x) << FShft(PIXCLKDIV_PD))
+
+/* LCD Config control register */
+#define LCDCFG_IN_FMT	Fld(3,28)
+#define Lcdcfg_In_Fmt(x)	((x) << FShft(LCDCFG_IN_FMT))
+#define LCDCFG_LCD1DEN_POL	(1 << 27)
+#define LCDCFG_LCD1FCLK_POL	(1 << 26)
+#define LCDCFG_LCD1LCLK_POL	(1 << 25)
+#define LCDCFG_LCD1D_POL	(1 << 24)
+#define LCDCFG_LCD2DEN_POL	(1 << 23)
+#define LCDCFG_LCD2FCLK_POL	(1 << 22)
+#define LCDCFG_LCD2LCLK_POL	(1 << 21)
+#define LCDCFG_LCD2D_POL	(1 << 20)
+#define LCDCFG_LCD1_TS		(1 << 19)
+#define LCDCFG_LCD1D_DS		(1 << 18)
+#define LCDCFG_LCD1C_DS		(1 << 17)
+#define LCDCFG_LCD1_IS_IN	(1 << 16)
+#define LCDCFG_LCD2_TS		(1 << 3)
+#define LCDCFG_LCD2D_DS		(1 << 2)
+#define LCDCFG_LCD2C_DS		(1 << 1)
+#define LCDCFG_LCD2_IS_IN	(1 << 0)
+
+/* On-Die Frame Buffer Power Control Register */
+#define ODFBPWR_SLOW	(1 << 2)
+#define ODFBPWR_MODE	Fld(2,0)
+#define ODFBPWR_MODE_ACT	((0x0) << FShft(ODFBPWR_MODE))
+#define ODFBPWR_MODE_ACT_LP	((0x1) << FShft(ODFBPWR_MODE))
+#define ODFBPWR_MODE_SLEEP	((0x2) << FShft(ODFBPWR_MODE))
+#define ODFBPWR_MODE_SHUTD	((0x3) << FShft(ODFBPWR_MODE))
+
+/* On-Die Frame Buffer Power State Status Register */
+#define ODFBSTAT_ACT	(1 << 2)
+#define ODFBSTAT_SLP	(1 << 1)
+#define ODFBSTAT_SDN	(1 << 0)
+
+/* LMRST - Local Memory (SDRAM) Reset */
+#define LMRST_MC_RST	(1 << 0)
+
+/* LMCFG - Local Memory (SDRAM) Configuration Register */
+#define LMCFG_LMC_DS	(1 << 5)
+#define LMCFG_LMD_DS	(1 << 4)
+#define LMCFG_LMA_DS	(1 << 3)
+#define LMCFG_LMC_TS	(1 << 2)
+#define LMCFG_LMD_TS	(1 << 1)
+#define LMCFG_LMA_TS	(1 << 0)
+
+/* LMPWR - Local Memory (SDRAM) Power Control Register */
+#define LMPWR_MC_PWR_CNT	Fld(2,0)
+#define LMPWR_MC_PWR_ACT	((0x0) << FShft(LMPWR_MC_PWR_CNT)) /* Active */
+#define LMPWR_MC_PWR_SRM	((0x1) << FShft(LMPWR_MC_PWR_CNT)) /* Self-refresh */
+#define LMPWR_MC_PWR_DPD	((0x3) << FShft(LMPWR_MC_PWR_CNT)) /* deep power down */
+
+/* LMPWRSTAT - Local Memory (SDRAM) Power Status Register */
+#define LMPWRSTAT_MC_PWR_CNT	Fld(2,0)
+#define LMPWRSTAT_MC_PWR_ACT	((0x0) << FShft(LMPWRSTAT_MC_PWR_CNT)) /* Active */
+#define LMPWRSTAT_MC_PWR_SRM	((0x1) << FShft(LMPWRSTAT_MC_PWR_CNT)) /* Self-refresh */
+#define LMPWRSTAT_MC_PWR_DPD	((0x3) << FShft(LMPWRSTAT_MC_PWR_CNT)) /* deep power down */
+
+/* LMTYPE - Local Memory (SDRAM) Type Register */
+#define LMTYPE_CASLAT	Fld(3,10)
+#define LMTYPE_CASLAT_1	((0x1) << FShft(LMTYPE_CASLAT))
+#define LMTYPE_CASLAT_2	((0x2) << FShft(LMTYPE_CASLAT))
+#define LMTYPE_CASLAT_3	((0x3) << FShft(LMTYPE_CASLAT))
+#define LMTYPE_BKSZ	Fld(2,8)
+#define LMTYPE_BKSZ_1	((0x1) << FShft(LMTYPE_BKSZ))
+#define LMTYPE_BKSZ_2	((0x2) << FShft(LMTYPE_BKSZ))
+#define LMTYPE_ROWSZ	Fld(4,4)
+#define LMTYPE_ROWSZ_11	((0xb) << FShft(LMTYPE_ROWSZ))
+#define LMTYPE_ROWSZ_12	((0xc) << FShft(LMTYPE_ROWSZ))
+#define LMTYPE_ROWSZ_13	((0xd) << FShft(LMTYPE_ROWSZ))
+#define LMTYPE_COLSZ	Fld(4,0)
+#define LMTYPE_COLSZ_7	((0x7) << FShft(LMTYPE_COLSZ))
+#define LMTYPE_COLSZ_8	((0x8) << FShft(LMTYPE_COLSZ))
+#define LMTYPE_COLSZ_9	((0x9) << FShft(LMTYPE_COLSZ))
+#define LMTYPE_COLSZ_10	((0xa) << FShft(LMTYPE_COLSZ))
+#define LMTYPE_COLSZ_11	((0xb) << FShft(LMTYPE_COLSZ))
+#define LMTYPE_COLSZ_12	((0xc) << FShft(LMTYPE_COLSZ))
+
+/* LMTIM - Local Memory (SDRAM) Timing Register */
+#define LMTIM_TRAS	Fld(4,16)
+#define Lmtim_Tras(x)	((x) << FShft(LMTIM_TRAS))
+#define LMTIM_TRP	Fld(4,12)
+#define Lmtim_Trp(x)	((x) << FShft(LMTIM_TRP))
+#define LMTIM_TRCD	Fld(4,8)
+#define Lmtim_Trcd(x)	((x) << FShft(LMTIM_TRCD))
+#define LMTIM_TRC	Fld(4,4)
+#define Lmtim_Trc(x)	((x) << FShft(LMTIM_TRC))
+#define LMTIM_TDPL	Fld(4,0)
+#define Lmtim_Tdpl(x)	((x) << FShft(LMTIM_TDPL))
+
+/* LMREFRESH - Local Memory (SDRAM) tREF Control Register */
+#define LMREFRESH_TREF	Fld(2,0)
+#define Lmrefresh_Tref(x)	((x) << FShft(LMREFRESH_TREF))
+
+/* GSCTRL - Graphics surface control register */
+#define GSCTRL_LUT_EN	(1 << 31)
+#define GSCTRL_GPIXFMT	Fld(4,27)
+#define GSCTRL_GPIXFMT_INDEXED	((0x0) << FShft(GSCTRL_GPIXFMT))
+#define GSCTRL_GPIXFMT_ARGB4444	((0x4) << FShft(GSCTRL_GPIXFMT))
+#define GSCTRL_GPIXFMT_ARGB1555	((0x5) << FShft(GSCTRL_GPIXFMT))
+#define GSCTRL_GPIXFMT_RGB888	((0x6) << FShft(GSCTRL_GPIXFMT))
+#define GSCTRL_GPIXFMT_RGB565	((0x7) << FShft(GSCTRL_GPIXFMT))
+#define GSCTRL_GPIXFMT_ARGB8888	((0x8) << FShft(GSCTRL_GPIXFMT))
+#define GSCTRL_GAMMA_EN	(1 << 26)
+
+#define GSCTRL_GSWIDTH Fld(11,11)
+#define Gsctrl_Width(Pixel)	/* Display Width [1..2048 pix.]  */ \
+                        (((Pixel) - 1) << FShft(GSCTRL_GSWIDTH))
+
+#define GSCTRL_GSHEIGHT Fld(11,0)
+#define Gsctrl_Height(Pixel)	/* Display Height [1..2048 pix.]  */ \
+                        (((Pixel) - 1) << FShft(GSCTRL_GSHEIGHT))
+
+/* GBBASE fileds */
+#define GBBASE_GLALPHA Fld(8,24)
+#define Gbbase_Glalpha(x)	((x) << FShft(GBBASE_GLALPHA))
+
+#define GBBASE_COLKEY Fld(24,0)
+#define Gbbase_Colkey(x)	((x) << FShft(GBBASE_COLKEY))
+
+/* GDRCTRL fields */
+#define GDRCTRL_PIXDBL	(1 << 31)
+#define GDRCTRL_PIXHLV	(1 << 30)
+#define GDRCTRL_LNDBL	(1 << 29)
+#define GDRCTRL_LNHLV	(1 << 28)
+#define GDRCTRL_COLKEYM	Fld(24,0)
+#define Gdrctrl_Colkeym(x)	((x) << FShft(GDRCTRL_COLKEYM))
+
+/* GSCADR graphics stream control address register fields */
+#define GSCADR_STR_EN	(1 << 31)
+#define GSCADR_COLKEY_EN	(1 << 30)
+#define GSCADR_COLKEYSCR	(1 << 29)
+#define GSCADR_BLEND_M	Fld(2,27)
+#define GSCADR_BLEND_NONE	((0x0) << FShft(GSCADR_BLEND_M))
+#define GSCADR_BLEND_INV	((0x1) << FShft(GSCADR_BLEND_M))
+#define GSCADR_BLEND_GLOB	((0x2) << FShft(GSCADR_BLEND_M))
+#define GSCADR_BLEND_PIX	((0x3) << FShft(GSCADR_BLEND_M))
+#define GSCADR_BLEND_POS	Fld(2,24)
+#define GSCADR_BLEND_GFX	((0x0) << FShft(GSCADR_BLEND_POS))
+#define GSCADR_BLEND_VID	((0x1) << FShft(GSCADR_BLEND_POS))
+#define GSCADR_BLEND_CUR	((0x2) << FShft(GSCADR_BLEND_POS))
+#define GSCADR_GBASE_ADR	Fld(23,0)
+#define Gscadr_Gbase_Adr(x)	((x) << FShft(GSCADR_GBASE_ADR))
+
+/* GSADR graphics stride address register fields */
+#define GSADR_SRCSTRIDE	Fld(10,22)
+#define Gsadr_Srcstride(x)	((x) << FShft(GSADR_SRCSTRIDE))
+#define GSADR_XSTART	Fld(11,11)
+#define Gsadr_Xstart(x)		((x) << FShft(GSADR_XSTART))
+#define GSADR_YSTART	Fld(11,0)
+#define Gsadr_Ystart(y)		((y) << FShft(GSADR_YSTART))
+
+/* GPLUT graphics palette register fields */
+#define GPLUT_LUTADR	Fld(8,24)
+#define Gplut_Lutadr(x)	((x) << FShft(GPLUT_LUTADR))
+#define GPLUT_LUTDATA	Fld(24,0)
+#define Gplut_Lutdata(x)	((x) << FShft(GPLUT_LUTDATA))
+
+/* HCCTRL - Hardware Cursor Register fields */
+#define HCCTRL_CUR_EN	(1 << 31)
+#define HCCTRL_COLKEY_EN	(1 << 29)
+#define HCCTRL_COLKEYSRC	(1 << 28)
+#define HCCTRL_BLEND_M	Fld(2,26)
+#define HCCTRL_BLEND_NONE	((0x0) << FShft(HCCTRL_BLEND_M))
+#define HCCTRL_BLEND_INV	((0x1) << FShft(HCCTRL_BLEND_M))
+#define HCCTRL_BLEND_GLOB	((0x2) << FShft(HCCTRL_BLEND_M))
+#define HCCTRL_BLEND_PIX	((0x3) << FShft(HCCTRL_BLEND_M))
+#define HCCTRL_CPIXFMT	Fld(3,23)
+#define HCCTRL_CPIXFMT_RGB332	((0x3) << FShft(HCCTRL_CPIXFMT))
+#define HCCTRL_CPIXFMT_ARGB4444	((0x4) << FShft(HCCTRL_CPIXFMT))
+#define HCCTRL_CPIXFMT_ARGB1555	((0x5) << FShft(HCCTRL_CPIXFMT))
+#define HCCTRL_CBASE_ADR	Fld(23,0)
+#define Hcctrl_Cbase_Adr(x)	((x) << FShft(HCCTRL_CBASE_ADR))
+
+/* HCSIZE Hardware Cursor Size Register fields */
+#define HCSIZE_BLEND_POS	Fld(2,29)
+#define HCSIZE_BLEND_GFX	((0x0) << FShft(HCSIZE_BLEND_POS))
+#define HCSIZE_BLEND_VID	((0x1) << FShft(HCSIZE_BLEND_POS))
+#define HCSIZE_BLEND_CUR	((0x2) << FShft(HCSIZE_BLEND_POS))
+#define HCSIZE_CWIDTH	Fld(3,16)
+#define Hcsize_Cwidth(x)	((x) << FShft(HCSIZE_CWIDTH))
+#define HCSIZE_CHEIGHT	Fld(3,0)
+#define Hcsize_Cheight(x)	((x) << FShft(HCSIZE_CHEIGHT))
+
+/* HCPOS Hardware Cursor Position Register fields */
+#define HCPOS_SWITCHSRC	(1 << 30)
+#define HCPOS_CURBLINK	Fld(6,24)
+#define Hcpos_Curblink(x)	((x) << FShft(HCPOS_CURBLINK))
+#define HCPOS_XSTART	Fld(12,12)
+#define Hcpos_Xstart(x)	((x) << FShft(HCPOS_XSTART))
+#define HCPOS_YSTART	Fld(12,0)
+#define Hcpos_Ystart(y)	((y) << FShft(HCPOS_YSTART))
+
+/* HCBADR Hardware Cursor Blend Address Register */
+#define HCBADR_GLALPHA	Fld(8,24)
+#define Hcbadr_Glalpha(x)	((x) << FShft(HCBADR_GLALPHA))
+#define HCBADR_COLKEY	Fld(24,0)
+#define Hcbadr_Colkey(x)	((x) << FShft(HCBADR_COLKEY))
+
+/* HCCKMSK - Hardware Cursor Color Key Mask Register */
+#define HCCKMSK_COLKEY_M	Fld(24,0)
+#define Hcckmsk_Colkey_M(x)	((x) << FShft(HCCKMSK_COLKEY_M))
+
+/* DSCTRL - Display sync control register */
+#define DSCTRL_SYNCGEN_EN	(1 << 31)
+#define DSCTRL_DPL_RST		(1 << 29)
+#define DSCTRL_PWRDN_M		(1 << 28)
+#define DSCTRL_UPDSYNCCNT	(1 << 26)
+#define DSCTRL_UPDINTCNT	(1 << 25)
+#define DSCTRL_UPDCNT		(1 << 24)
+#define DSCTRL_UPDWAIT	Fld(4,16)
+#define Dsctrl_Updwait(x)	((x) << FShft(DSCTRL_UPDWAIT))
+#define DSCTRL_CLKPOL		(1 << 11)
+#define DSCTRL_CSYNC_EN		(1 << 10)
+#define DSCTRL_VS_SLAVE		(1 << 7)
+#define DSCTRL_HS_SLAVE		(1 << 6)
+#define DSCTRL_BLNK_POL		(1 << 5)
+#define DSCTRL_BLNK_DIS		(1 << 4)
+#define DSCTRL_VS_POL		(1 << 3)
+#define DSCTRL_VS_DIS		(1 << 2)
+#define DSCTRL_HS_POL		(1 << 1)
+#define DSCTRL_HS_DIS		(1 << 0)
+
+/* DHT01 - Display horizontal timing register 01 */
+#define DHT01_HBPS	Fld(12,16)
+#define Dht01_Hbps(x)	((x) << FShft(DHT01_HBPS))
+#define DHT01_HT	Fld(12,0)
+#define Dht01_Ht(x)	((x) << FShft(DHT01_HT))
+
+/* DHT02 - Display horizontal timing register 02 */
+#define DHT02_HAS	Fld(12,16)
+#define Dht02_Has(x)	((x) << FShft(DHT02_HAS))
+#define DHT02_HLBS	Fld(12,0)
+#define Dht02_Hlbs(x)	((x) << FShft(DHT02_HLBS))
+
+/* DHT03 - Display horizontal timing register 03 */
+#define DHT03_HFPS	Fld(12,16)
+#define Dht03_Hfps(x)	((x) << FShft(DHT03_HFPS))
+#define DHT03_HRBS	Fld(12,0)
+#define Dht03_Hrbs(x)	((x) << FShft(DHT03_HRBS))
+
+/* DVT01 - Display vertical timing register 01 */
+#define DVT01_VBPS	Fld(12,16)
+#define Dvt01_Vbps(x)	((x) << FShft(DVT01_VBPS))
+#define DVT01_VT	Fld(12,0)
+#define Dvt01_Vt(x)	((x) << FShft(DVT01_VT))
+
+/* DVT02 - Display vertical timing register 02 */
+#define DVT02_VAS	Fld(12,16)
+#define Dvt02_Vas(x)	((x) << FShft(DVT02_VAS))
+#define DVT02_VTBS	Fld(12,0)
+#define Dvt02_Vtbs(x)	((x) << FShft(DVT02_VTBS))
+
+/* DVT03 - Display vertical timing register 03 */
+#define DVT03_VFPS	Fld(12,16)
+#define Dvt03_Vfps(x)	((x) << FShft(DVT03_VFPS))
+#define DVT03_VBBS	Fld(12,0)
+#define Dvt03_Vbbs(x)	((x) << FShft(DVT03_VBBS))
+
+/* DVECTRL - display vertical event control register */
+#define DVECTRL_VEVENT	Fld(12,16)
+#define Dvectrl_Vevent(x)	((x) << FShft(DVECTRL_VEVENT))
+#define DVECTRL_VFETCH	Fld(12,0)
+#define Dvectrl_Vfetch(x)	((x) << FShft(DVECTRL_VFETCH))
+
+/* DHDET - display horizontal DE timing register */
+#define DHDET_HDES	Fld(12,16)
+#define Dhdet_Hdes(x)	((x) << FShft(DHDET_HDES))
+#define DHDET_HDEF	Fld(12,0)
+#define Dhdet_Hdef(x)	((x) << FShft(DHDET_HDEF))
+
+/* DVDET - display vertical DE timing register */
+#define DVDET_VDES	Fld(12,16)
+#define Dvdet_Vdes(x)	((x) << FShft(DVDET_VDES))
+#define DVDET_VDEF	Fld(12,0)
+#define Dvdet_Vdef(x)	((x) << FShft(DVDET_VDEF))
+
+/* DODMSK - display output data mask register */
+#define DODMSK_MASK_LVL	(1 << 31)
+#define DODMSK_BLNK_LVL	(1 << 30)
+#define DODMSK_MASK_B	Fld(8,16)
+#define Dodmsk_Mask_B(x)	((x) << FShft(DODMSK_MASK_B))
+#define DODMSK_MASK_G	Fld(8,8)
+#define Dodmsk_Mask_G(x)	((x) << FShft(DODMSK_MASK_G))
+#define DODMSK_MASK_R	Fld(8,0)
+#define Dodmsk_Mask_R(x)	((x) << FShft(DODMSK_MASK_R))
+
+/* DBCOL - display border color control register */
+#define DBCOL_BORDCOL	Fld(24,0)
+#define Dbcol_Bordcol(x)	((x) << FShft(DBCOL_BORDCOL))
+
+/* DVLNUM - display vertical line number register */
+#define DVLNUM_VLINE	Fld(12,0)
+#define Dvlnum_Vline(x)	((x) << FShft(DVLNUM_VLINE))
+
+/* DMCTRL - Display Memory Control Register */
+#define DMCTRL_MEM_REF	Fld(2,30)
+#define DMCTRL_MEM_REF_ACT	((0x0) << FShft(DMCTRL_MEM_REF))
+#define DMCTRL_MEM_REF_HB	((0x1) << FShft(DMCTRL_MEM_REF))
+#define DMCTRL_MEM_REF_VB	((0x2) << FShft(DMCTRL_MEM_REF))
+#define DMCTRL_MEM_REF_BOTH	((0x3) << FShft(DMCTRL_MEM_REF))
+#define DMCTRL_UV_THRHLD	Fld(6,24)
+#define Dmctrl_Uv_Thrhld(x)	((x) << FShft(DMCTRL_UV_THRHLD))
+#define DMCTRL_V_THRHLD		Fld(7,16)
+#define Dmctrl_V_Thrhld(x)	((x) << FShft(DMCTRL_V_THRHLD))
+#define DMCTRL_D_THRHLD		Fld(7,8)
+#define Dmctrl_D_Thrhld(x)	((x) << FShft(DMCTRL_D_THRHLD))
+#define DMCTRL_BURSTLEN	Fld(6,0)
+#define Dmctrl_Burstlen(x)	((x) << FShft(DMCTRL_BURSTLEN))
+
+
+/* DLSTS - display load status register */
+#define DLSTS_RLD_ADONE	(1 << 23)
+/* #define DLSTS_RLD_ADOUT	Fld(23,0) */
+
+/* DLLCTRL - display list load control register */
+#define DLLCTRL_RLD_ADRLN	Fld(8,24)
+#define Dllctrl_Rld_Adrln(x)	((x) << FShft(DLLCTRL_RLD_ADRLN))
+
+/* SPOCTRL - Scale Pitch/Order Control Register */
+#define SPOCTRL_H_SC_BP		(1 << 31)
+#define SPOCTRL_V_SC_BP		(1 << 30)
+#define SPOCTRL_HV_SC_OR	(1 << 29)
+#define SPOCTRL_VS_UR_C		(1 << 27)
+#define SPOCTRL_VORDER	Fld(2,16)
+#define SPOCTRL_VORDER_1TAP	((0x0) << FShft(SPOCTRL_VORDER))
+#define SPOCTRL_VORDER_2TAP	((0x1) << FShft(SPOCTRL_VORDER))
+#define SPOCTRL_VORDER_4TAP	((0x3) << FShft(SPOCTRL_VORDER))
+#define SPOCTRL_VPITCH	Fld(16,0)
+#define Spoctrl_Vpitch(x)	((x) << FShft(SPOCTRL_VPITCH))
+
+#endif /* __REG_BITS_2700G_ */
diff --git a/drivers/video/mbx/regs.h b/drivers/video/mbx/regs.h
new file mode 100644
index 000000000..ad20be076
--- /dev/null
+++ b/drivers/video/mbx/regs.h
@@ -0,0 +1,195 @@
+#ifndef __REGS_2700G_
+#define __REGS_2700G_
+
+/* extern unsigned long virt_base_2700; */
+/* #define __REG_2700G(x)	(*(volatile unsigned long*)((x)+virt_base_2700)) */
+#define __REG_2700G(x)	((x)+virt_base_2700)
+
+/* System Configuration Registers (0x0000_0000  0x0000_0010) */
+#define SYSCFG		__REG_2700G(0x00000000)
+#define PFBASE		__REG_2700G(0x00000004)
+#define PFCEIL		__REG_2700G(0x00000008)
+#define POLLFLAG	__REG_2700G(0x0000000c)
+#define SYSRST		__REG_2700G(0x00000010)
+
+/* Interrupt Control Registers (0x0000_0014  0x0000_002F) */
+#define NINTPW		__REG_2700G(0x00000014)
+#define MINTENABLE	__REG_2700G(0x00000018)
+#define MINTSTAT	__REG_2700G(0x0000001c)
+#define SINTENABLE	__REG_2700G(0x00000020)
+#define SINTSTAT	__REG_2700G(0x00000024)
+#define SINTCLR		__REG_2700G(0x00000028)
+
+/* Clock Control Registers (0x0000_002C  0x0000_005F) */
+#define SYSCLKSRC	__REG_2700G(0x0000002c)
+#define PIXCLKSRC	__REG_2700G(0x00000030)
+#define CLKSLEEP	__REG_2700G(0x00000034)
+#define COREPLL		__REG_2700G(0x00000038)
+#define DISPPLL		__REG_2700G(0x0000003c)
+#define PLLSTAT		__REG_2700G(0x00000040)
+#define VOVRCLK		__REG_2700G(0x00000044)
+#define PIXCLK		__REG_2700G(0x00000048)
+#define MEMCLK		__REG_2700G(0x0000004c)
+#define M24CLK		__REG_2700G(0x00000054)
+#define MBXCLK		__REG_2700G(0x00000054)
+#define SDCLK		__REG_2700G(0x00000058)
+#define PIXCLKDIV	__REG_2700G(0x0000005c)
+
+/* LCD Port Control Register (0x0000_0060  0x0000_006F) */
+#define LCD_CONFIG	__REG_2700G(0x00000060)
+
+/* On-Die Frame Buffer Registers (0x0000_0064  0x0000_006B) */
+#define ODFBPWR		__REG_2700G(0x00000064)
+#define ODFBSTAT	__REG_2700G(0x00000068)
+
+/* GPIO Registers (0x0000_006C  0x0000_007F) */
+#define GPIOCGF		__REG_2700G(0x0000006c)
+#define GPIOHI		__REG_2700G(0x00000070)
+#define GPIOLO		__REG_2700G(0x00000074)
+#define GPIOSTAT	__REG_2700G(0x00000078)
+
+/* Pulse Width Modulator (PWM) Registers (0x0000_0200  0x0000_02FF) */
+#define PWMRST		__REG_2700G(0x00000200)
+#define PWMCFG		__REG_2700G(0x00000204)
+#define PWM0DIV		__REG_2700G(0x00000210)
+#define PWM0DUTY	__REG_2700G(0x00000214)
+#define PWM0PER		__REG_2700G(0x00000218)
+#define PWM1DIV		__REG_2700G(0x00000220)
+#define PWM1DUTY	__REG_2700G(0x00000224)
+#define PWM1PER		__REG_2700G(0x00000228)
+
+/* Identification (ID) Registers (0x0000_0300  0x0000_0FFF) */
+#define ID		__REG_2700G(0x00000FF0)
+
+/* Local Memory (SDRAM) Interface Registers (0x0000_1000  0x0000_1FFF) */
+#define LMRST		__REG_2700G(0x00001000)
+#define LMCFG		__REG_2700G(0x00001004)
+#define LMPWR		__REG_2700G(0x00001008)
+#define LMPWRSTAT	__REG_2700G(0x0000100c)
+#define LMCEMR		__REG_2700G(0x00001010)
+#define LMTYPE		__REG_2700G(0x00001014)
+#define LMTIM		__REG_2700G(0x00001018)
+#define LMREFRESH	__REG_2700G(0x0000101c)
+#define LMPROTMIN	__REG_2700G(0x00001020)
+#define LMPROTMAX	__REG_2700G(0x00001024)
+#define LMPROTCFG	__REG_2700G(0x00001028)
+#define LMPROTERR	__REG_2700G(0x0000102c)
+
+/* Plane Controller Registers (0x0000_2000  0x0000_2FFF) */
+#define GSCTRL		__REG_2700G(0x00002000)
+#define VSCTRL		__REG_2700G(0x00002004)
+#define GBBASE		__REG_2700G(0x00002020)
+#define VBBASE		__REG_2700G(0x00002024)
+#define GDRCTRL		__REG_2700G(0x00002040)
+#define VCMSK		__REG_2700G(0x00002044)
+#define GSCADR		__REG_2700G(0x00002060)
+#define VSCADR		__REG_2700G(0x00002064)
+#define VUBASE		__REG_2700G(0x00002084)
+#define VVBASE		__REG_2700G(0x000020a4)
+#define GSADR		__REG_2700G(0x000020c0)
+#define VSADR		__REG_2700G(0x000020c4)
+#define HCCTRL		__REG_2700G(0x00002100)
+#define HCSIZE		__REG_2700G(0x00002110)
+#define HCPOS		__REG_2700G(0x00002120)
+#define HCBADR		__REG_2700G(0x00002130)
+#define HCCKMSK		__REG_2700G(0x00002140)
+#define GPLUT		__REG_2700G(0x00002150)
+#define DSCTRL		__REG_2700G(0x00002154)
+#define DHT01		__REG_2700G(0x00002158)
+#define DHT02		__REG_2700G(0x0000215c)
+#define DHT03		__REG_2700G(0x00002160)
+#define DVT01		__REG_2700G(0x00002164)
+#define DVT02		__REG_2700G(0x00002168)
+#define DVT03		__REG_2700G(0x0000216c)
+#define DBCOL		__REG_2700G(0x00002170)
+#define BGCOLOR		__REG_2700G(0x00002174)
+#define DINTRS		__REG_2700G(0x00002178)
+#define DINTRE		__REG_2700G(0x0000217c)
+#define DINTRCNT	__REG_2700G(0x00002180)
+#define DSIG		__REG_2700G(0x00002184)
+#define DMCTRL		__REG_2700G(0x00002188)
+#define CLIPCTRL	__REG_2700G(0x0000218c)
+#define SPOCTRL		__REG_2700G(0x00002190)
+#define SVCTRL		__REG_2700G(0x00002194)
+
+/* 0x0000_2198 */
+/* 0x0000_21A8 VSCOEFF[0:4] Video Scalar Vertical Coefficient [0:4] 4.14.5 */
+#define VSCOEFF0	__REG_2700G(0x00002198)
+#define VSCOEFF1	__REG_2700G(0x0000219c)
+#define VSCOEFF2	__REG_2700G(0x000021a0)
+#define VSCOEFF3	__REG_2700G(0x000021a4)
+#define VSCOEFF4	__REG_2700G(0x000021a8)
+
+#define SHCTRL		__REG_2700G(0x000021b0)
+
+/* 0x0000_21B4 */
+/* 0x0000_21D4 HSCOEFF[0:8] Video Scalar Horizontal Coefficient [0:8] 4.14.7 */
+#define HSCOEFF0	__REG_2700G(0x000021b4)
+#define HSCOEFF1	__REG_2700G(0x000021b8)
+#define HSCOEFF2	__REG_2700G(0x000021bc)
+#define HSCOEFF3	__REG_2700G(0x000021b0)
+#define HSCOEFF4	__REG_2700G(0x000021c4)
+#define HSCOEFF5	__REG_2700G(0x000021c8)
+#define HSCOEFF6	__REG_2700G(0x000021cc)
+#define HSCOEFF7	__REG_2700G(0x000021d0)
+#define HSCOEFF8	__REG_2700G(0x000021d4)
+
+#define SSSIZE		__REG_2700G(0x000021D8)
+
+/* 0x0000_2200 */
+/* 0x0000_2240 VIDGAM[0:16] Video Gamma LUT Index [0:16] 4.15.2 */
+#define VIDGAM0		__REG_2700G(0x00002200)
+#define VIDGAM1		__REG_2700G(0x00002204)
+#define VIDGAM2		__REG_2700G(0x00002208)
+#define VIDGAM3		__REG_2700G(0x0000220c)
+#define VIDGAM4		__REG_2700G(0x00002210)
+#define VIDGAM5		__REG_2700G(0x00002214)
+#define VIDGAM6		__REG_2700G(0x00002218)
+#define VIDGAM7		__REG_2700G(0x0000221c)
+#define VIDGAM8		__REG_2700G(0x00002220)
+#define VIDGAM9		__REG_2700G(0x00002224)
+#define VIDGAM10	__REG_2700G(0x00002228)
+#define VIDGAM11	__REG_2700G(0x0000222c)
+#define VIDGAM12	__REG_2700G(0x00002230)
+#define VIDGAM13	__REG_2700G(0x00002234)
+#define VIDGAM14	__REG_2700G(0x00002238)
+#define VIDGAM15	__REG_2700G(0x0000223c)
+#define VIDGAM16	__REG_2700G(0x00002240)
+
+/* 0x0000_2250 */
+/* 0x0000_2290 GFXGAM[0:16] Graphics Gamma LUT Index [0:16] 4.15.3 */
+#define GFXGAM0		__REG_2700G(0x00002250)
+#define GFXGAM1		__REG_2700G(0x00002254)
+#define GFXGAM2		__REG_2700G(0x00002258)
+#define GFXGAM3		__REG_2700G(0x0000225c)
+#define GFXGAM4		__REG_2700G(0x00002260)
+#define GFXGAM5		__REG_2700G(0x00002264)
+#define GFXGAM6		__REG_2700G(0x00002268)
+#define GFXGAM7		__REG_2700G(0x0000226c)
+#define GFXGAM8		__REG_2700G(0x00002270)
+#define GFXGAM9		__REG_2700G(0x00002274)
+#define GFXGAM10	__REG_2700G(0x00002278)
+#define GFXGAM11	__REG_2700G(0x0000227c)
+#define GFXGAM12	__REG_2700G(0x00002280)
+#define GFXGAM13	__REG_2700G(0x00002284)
+#define GFXGAM14	__REG_2700G(0x00002288)
+#define GFXGAM15	__REG_2700G(0x0000228c)
+#define GFXGAM16	__REG_2700G(0x00002290)
+
+#define DLSTS		__REG_2700G(0x00002300)
+#define DLLCTRL		__REG_2700G(0x00002304)
+#define DVLNUM		__REG_2700G(0x00002308)
+#define DUCTRL		__REG_2700G(0x0000230c)
+#define DVECTRL		__REG_2700G(0x00002310)
+#define DHDET		__REG_2700G(0x00002314)
+#define DVDET		__REG_2700G(0x00002318)
+#define DODMSK		__REG_2700G(0x0000231c)
+#define CSC01		__REG_2700G(0x00002330)
+#define CSC02		__REG_2700G(0x00002334)
+#define CSC03		__REG_2700G(0x00002338)
+#define CSC04		__REG_2700G(0x0000233c)
+#define CSC05		__REG_2700G(0x00002340)
+
+#define FB_MEMORY_START	__REG_2700G(0x00060000)
+
+#endif /* __REGS_2700G_ */
diff --git a/drivers/video/nvidia/nv_backlight.c b/drivers/video/nvidia/nv_backlight.c
new file mode 100644
index 000000000..5b75ae4e9
--- /dev/null
+++ b/drivers/video/nvidia/nv_backlight.c
@@ -0,0 +1,203 @@
+/*
+ * Backlight code for nVidia based graphic cards
+ *
+ * Copyright 2004 Antonino Daplas <adaplas@pol.net>
+ * Copyright (c) 2006 Michael Hanselmann <linux-kernel@hansmi.ch>
+ *
+ * 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/backlight.h>
+#include <linux/fb.h>
+#include <linux/pci.h>
+#include "nv_local.h"
+#include "nv_type.h"
+#include "nv_proto.h"
+
+#ifdef CONFIG_PMAC_BACKLIGHT
+#include <asm/backlight.h>
+#include <asm/machdep.h>
+#endif
+
+/* We do not have any information about which values are allowed, thus
+ * we used safe values.
+ */
+#define MIN_LEVEL 0x158
+#define MAX_LEVEL 0x534
+#define LEVEL_STEP ((MAX_LEVEL - MIN_LEVEL) / FB_BACKLIGHT_MAX)
+
+static struct backlight_properties nvidia_bl_data;
+
+/* Call with fb_info->bl_mutex held */
+static int nvidia_bl_get_level_brightness(struct nvidia_par *par,
+		int level)
+{
+	struct fb_info *info = pci_get_drvdata(par->pci_dev);
+	int nlevel;
+
+	/* Get and convert the value */
+	nlevel = MIN_LEVEL + info->bl_curve[level] * LEVEL_STEP;
+
+	if (nlevel < 0)
+		nlevel = 0;
+	else if (nlevel < MIN_LEVEL)
+		nlevel = MIN_LEVEL;
+	else if (nlevel > MAX_LEVEL)
+		nlevel = MAX_LEVEL;
+
+	return nlevel;
+}
+
+/* Call with fb_info->bl_mutex held */
+static int __nvidia_bl_update_status(struct backlight_device *bd)
+{
+	struct nvidia_par *par = class_get_devdata(&bd->class_dev);
+	u32 tmp_pcrt, tmp_pmc, fpcontrol;
+	int level;
+
+	if (!par->FlatPanel)
+		return 0;
+
+	if (bd->props->power != FB_BLANK_UNBLANK ||
+	    bd->props->fb_blank != FB_BLANK_UNBLANK)
+		level = 0;
+	else
+		level = bd->props->brightness;
+
+	tmp_pmc = NV_RD32(par->PMC, 0x10F0) & 0x0000FFFF;
+	tmp_pcrt = NV_RD32(par->PCRTC0, 0x081C) & 0xFFFFFFFC;
+	fpcontrol = NV_RD32(par->PRAMDAC, 0x0848) & 0xCFFFFFCC;
+
+	if (level > 0) {
+		tmp_pcrt |= 0x1;
+		tmp_pmc |= (1 << 31); /* backlight bit */
+		tmp_pmc |= nvidia_bl_get_level_brightness(par, level) << 16;
+		fpcontrol |= par->fpSyncs;
+	} else
+		fpcontrol |= 0x20000022;
+
+	NV_WR32(par->PCRTC0, 0x081C, tmp_pcrt);
+	NV_WR32(par->PMC, 0x10F0, tmp_pmc);
+	NV_WR32(par->PRAMDAC, 0x848, fpcontrol);
+
+	return 0;
+}
+
+static int nvidia_bl_update_status(struct backlight_device *bd)
+{
+	struct nvidia_par *par = class_get_devdata(&bd->class_dev);
+	struct fb_info *info = pci_get_drvdata(par->pci_dev);
+	int ret;
+
+	mutex_lock(&info->bl_mutex);
+	ret = __nvidia_bl_update_status(bd);
+	mutex_unlock(&info->bl_mutex);
+
+	return ret;
+}
+
+static int nvidia_bl_get_brightness(struct backlight_device *bd)
+{
+	return bd->props->brightness;
+}
+
+static struct backlight_properties nvidia_bl_data = {
+	.owner		= THIS_MODULE,
+	.get_brightness = nvidia_bl_get_brightness,
+	.update_status	= nvidia_bl_update_status,
+	.max_brightness = (FB_BACKLIGHT_LEVELS - 1),
+};
+
+void nvidia_bl_set_power(struct fb_info *info, int power)
+{
+	mutex_lock(&info->bl_mutex);
+
+	if (info->bl_dev) {
+		down(&info->bl_dev->sem);
+		info->bl_dev->props->power = power;
+		__nvidia_bl_update_status(info->bl_dev);
+		up(&info->bl_dev->sem);
+	}
+
+	mutex_unlock(&info->bl_mutex);
+}
+
+void nvidia_bl_init(struct nvidia_par *par)
+{
+	struct fb_info *info = pci_get_drvdata(par->pci_dev);
+	struct backlight_device *bd;
+	char name[12];
+
+	if (!par->FlatPanel)
+		return;
+
+#ifdef CONFIG_PMAC_BACKLIGHT
+	if (!machine_is(powermac) ||
+	    !pmac_has_backlight_type("mnca"))
+		return;
+#endif
+
+	snprintf(name, sizeof(name), "nvidiabl%d", info->node);
+
+	bd = backlight_device_register(name, par, &nvidia_bl_data);
+	if (IS_ERR(bd)) {
+		info->bl_dev = NULL;
+		printk(KERN_WARNING "nvidia: Backlight registration failed\n");
+		goto error;
+	}
+
+	mutex_lock(&info->bl_mutex);
+	info->bl_dev = bd;
+	fb_bl_default_curve(info, 0,
+		0x158 * FB_BACKLIGHT_MAX / MAX_LEVEL,
+		0x534 * FB_BACKLIGHT_MAX / MAX_LEVEL);
+	mutex_unlock(&info->bl_mutex);
+
+	down(&bd->sem);
+	bd->props->brightness = nvidia_bl_data.max_brightness;
+	bd->props->power = FB_BLANK_UNBLANK;
+	bd->props->update_status(bd);
+	up(&bd->sem);
+
+#ifdef CONFIG_PMAC_BACKLIGHT
+	mutex_lock(&pmac_backlight_mutex);
+	if (!pmac_backlight)
+		pmac_backlight = bd;
+	mutex_unlock(&pmac_backlight_mutex);
+#endif
+
+	printk("nvidia: Backlight initialized (%s)\n", name);
+
+	return;
+
+error:
+	return;
+}
+
+void nvidia_bl_exit(struct nvidia_par *par)
+{
+	struct fb_info *info = pci_get_drvdata(par->pci_dev);
+
+#ifdef CONFIG_PMAC_BACKLIGHT
+	mutex_lock(&pmac_backlight_mutex);
+#endif
+
+	mutex_lock(&info->bl_mutex);
+	if (info->bl_dev) {
+#ifdef CONFIG_PMAC_BACKLIGHT
+		if (pmac_backlight == info->bl_dev)
+			pmac_backlight = NULL;
+#endif
+
+		backlight_device_unregister(info->bl_dev);
+
+		printk("nvidia: Backlight unloaded\n");
+	}
+	mutex_unlock(&info->bl_mutex);
+
+#ifdef CONFIG_PMAC_BACKLIGHT
+	mutex_unlock(&pmac_backlight_mutex);
+#endif
+}
diff --git a/drivers/video/pnx4008/Makefile b/drivers/video/pnx4008/Makefile
new file mode 100644
index 000000000..636aaccf0
--- /dev/null
+++ b/drivers/video/pnx4008/Makefile
@@ -0,0 +1,7 @@
+#
+# Makefile for the new PNX4008 framebuffer device driver
+#
+
+obj-$(CONFIG_FB_PNX4008_DUM) += sdum.o
+obj-$(CONFIG_FB_PNX4008_DUM_RGB) += pnxrgbfb.o
+
diff --git a/drivers/video/pnx4008/dum.h b/drivers/video/pnx4008/dum.h
new file mode 100644
index 000000000..d80a614d8
--- /dev/null
+++ b/drivers/video/pnx4008/dum.h
@@ -0,0 +1,211 @@
+/*
+ * linux/drivers/video/pnx4008/dum.h
+ *
+ * Internal header for SDUM
+ *
+ * 2005 (c) Koninklijke Philips N.V. 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 __PNX008_DUM_H__
+#define __PNX008_DUM_H__
+
+#include <asm/arch/platform.h>
+
+#define PNX4008_DUMCONF_VA_BASE		IO_ADDRESS(PNX4008_DUMCONF_BASE)
+#define PNX4008_DUM_MAIN_VA_BASE	IO_ADDRESS(PNX4008_DUM_MAINCFG_BASE)
+
+/* DUM CFG ADDRESSES */
+#define DUM_CH_BASE_ADR		(PNX4008_DUMCONF_VA_BASE + 0x00)
+#define DUM_CH_MIN_ADR		(PNX4008_DUMCONF_VA_BASE + 0x00)
+#define DUM_CH_MAX_ADR		(PNX4008_DUMCONF_VA_BASE + 0x04)
+#define DUM_CH_CONF_ADR		(PNX4008_DUMCONF_VA_BASE + 0x08)
+#define DUM_CH_STAT_ADR		(PNX4008_DUMCONF_VA_BASE + 0x0C)
+#define DUM_CH_CTRL_ADR		(PNX4008_DUMCONF_VA_BASE + 0x10)
+
+#define CH_MARG		(0x100 / sizeof(u32))
+#define DUM_CH_MIN(i)	(*((volatile u32 *)DUM_CH_MIN_ADR + (i) * CH_MARG))
+#define DUM_CH_MAX(i)	(*((volatile u32 *)DUM_CH_MAX_ADR + (i) * CH_MARG))
+#define DUM_CH_CONF(i)	(*((volatile u32 *)DUM_CH_CONF_ADR + (i) * CH_MARG))
+#define DUM_CH_STAT(i)	(*((volatile u32 *)DUM_CH_STAT_ADR + (i) * CH_MARG))
+#define DUM_CH_CTRL(i)	(*((volatile u32 *)DUM_CH_CTRL_ADR + (i) * CH_MARG))
+
+#define DUM_CONF_ADR          (PNX4008_DUM_MAIN_VA_BASE + 0x00)
+#define DUM_CTRL_ADR          (PNX4008_DUM_MAIN_VA_BASE + 0x04)
+#define DUM_STAT_ADR          (PNX4008_DUM_MAIN_VA_BASE + 0x08)
+#define DUM_DECODE_ADR        (PNX4008_DUM_MAIN_VA_BASE + 0x0C)
+#define DUM_COM_BASE_ADR      (PNX4008_DUM_MAIN_VA_BASE + 0x10)
+#define DUM_SYNC_C_ADR        (PNX4008_DUM_MAIN_VA_BASE + 0x14)
+#define DUM_CLK_DIV_ADR       (PNX4008_DUM_MAIN_VA_BASE + 0x18)
+#define DUM_DIRTY_LOW_ADR     (PNX4008_DUM_MAIN_VA_BASE + 0x20)
+#define DUM_DIRTY_HIGH_ADR    (PNX4008_DUM_MAIN_VA_BASE + 0x24)
+#define DUM_FORMAT_ADR        (PNX4008_DUM_MAIN_VA_BASE + 0x28)
+#define DUM_WTCFG1_ADR        (PNX4008_DUM_MAIN_VA_BASE + 0x30)
+#define DUM_RTCFG1_ADR        (PNX4008_DUM_MAIN_VA_BASE + 0x34)
+#define DUM_WTCFG2_ADR        (PNX4008_DUM_MAIN_VA_BASE + 0x38)
+#define DUM_RTCFG2_ADR        (PNX4008_DUM_MAIN_VA_BASE + 0x3C)
+#define DUM_TCFG_ADR          (PNX4008_DUM_MAIN_VA_BASE + 0x40)
+#define DUM_OUTP_FORMAT1_ADR  (PNX4008_DUM_MAIN_VA_BASE + 0x44)
+#define DUM_OUTP_FORMAT2_ADR  (PNX4008_DUM_MAIN_VA_BASE + 0x48)
+#define DUM_SYNC_MODE_ADR     (PNX4008_DUM_MAIN_VA_BASE + 0x4C)
+#define DUM_SYNC_OUT_C_ADR    (PNX4008_DUM_MAIN_VA_BASE + 0x50)
+
+#define DUM_CONF              (*(volatile u32 *)(DUM_CONF_ADR))
+#define DUM_CTRL              (*(volatile u32 *)(DUM_CTRL_ADR))
+#define DUM_STAT              (*(volatile u32 *)(DUM_STAT_ADR))
+#define DUM_DECODE            (*(volatile u32 *)(DUM_DECODE_ADR))
+#define DUM_COM_BASE          (*(volatile u32 *)(DUM_COM_BASE_ADR))
+#define DUM_SYNC_C            (*(volatile u32 *)(DUM_SYNC_C_ADR))
+#define DUM_CLK_DIV           (*(volatile u32 *)(DUM_CLK_DIV_ADR))
+#define DUM_DIRTY_LOW         (*(volatile u32 *)(DUM_DIRTY_LOW_ADR))
+#define DUM_DIRTY_HIGH        (*(volatile u32 *)(DUM_DIRTY_HIGH_ADR))
+#define DUM_FORMAT            (*(volatile u32 *)(DUM_FORMAT_ADR))
+#define DUM_WTCFG1            (*(volatile u32 *)(DUM_WTCFG1_ADR))
+#define DUM_RTCFG1            (*(volatile u32 *)(DUM_RTCFG1_ADR))
+#define DUM_WTCFG2            (*(volatile u32 *)(DUM_WTCFG2_ADR))
+#define DUM_RTCFG2            (*(volatile u32 *)(DUM_RTCFG2_ADR))
+#define DUM_TCFG              (*(volatile u32 *)(DUM_TCFG_ADR))
+#define DUM_OUTP_FORMAT1      (*(volatile u32 *)(DUM_OUTP_FORMAT1_ADR))
+#define DUM_OUTP_FORMAT2      (*(volatile u32 *)(DUM_OUTP_FORMAT2_ADR))
+#define DUM_SYNC_MODE         (*(volatile u32 *)(DUM_SYNC_MODE_ADR))
+#define DUM_SYNC_OUT_C        (*(volatile u32 *)(DUM_SYNC_OUT_C_ADR))
+
+/* DUM SLAVE ADDRESSES */
+#define DUM_SLAVE_WRITE_ADR      (PNX4008_DUM_MAINCFG_BASE + 0x0000000)
+#define DUM_SLAVE_READ1_I_ADR    (PNX4008_DUM_MAINCFG_BASE + 0x1000000)
+#define DUM_SLAVE_READ1_R_ADR    (PNX4008_DUM_MAINCFG_BASE + 0x1000004)
+#define DUM_SLAVE_READ2_I_ADR    (PNX4008_DUM_MAINCFG_BASE + 0x1000008)
+#define DUM_SLAVE_READ2_R_ADR    (PNX4008_DUM_MAINCFG_BASE + 0x100000C)
+
+#define DUM_SLAVE_WRITE_W  ((volatile u32 *)(DUM_SLAVE_WRITE_ADR))
+#define DUM_SLAVE_WRITE_HW ((volatile u16 *)(DUM_SLAVE_WRITE_ADR))
+#define DUM_SLAVE_READ1_I  ((volatile u8 *)(DUM_SLAVE_READ1_I_ADR))
+#define DUM_SLAVE_READ1_R  ((volatile u16 *)(DUM_SLAVE_READ1_R_ADR))
+#define DUM_SLAVE_READ2_I  ((volatile u8 *)(DUM_SLAVE_READ2_I_ADR))
+#define DUM_SLAVE_READ2_R  ((volatile u16 *)(DUM_SLAVE_READ2_R_ADR))
+
+/* Sony display register addresses */
+#define DISP_0_REG            (0x00)
+#define DISP_1_REG            (0x01)
+#define DISP_CAL_REG          (0x20)
+#define DISP_ID_REG           (0x2A)
+#define DISP_XMIN_L_REG       (0x30)
+#define DISP_XMIN_H_REG       (0x31)
+#define DISP_YMIN_REG         (0x32)
+#define DISP_XMAX_L_REG       (0x34)
+#define DISP_XMAX_H_REG       (0x35)
+#define DISP_YMAX_REG         (0x36)
+#define DISP_SYNC_EN_REG      (0x38)
+#define DISP_SYNC_RISE_L_REG  (0x3C)
+#define DISP_SYNC_RISE_H_REG  (0x3D)
+#define DISP_SYNC_FALL_L_REG  (0x3E)
+#define DISP_SYNC_FALL_H_REG  (0x3F)
+#define DISP_PIXEL_REG        (0x0B)
+#define DISP_DUMMY1_REG       (0x28)
+#define DISP_DUMMY2_REG       (0x29)
+#define DISP_TIMING_REG       (0x98)
+#define DISP_DUMP_REG         (0x99)
+
+/* Sony display constants */
+#define SONY_ID1              (0x22)
+#define SONY_ID2              (0x23)
+
+/* Philips display register addresses */
+#define PH_DISP_ORIENT_REG    (0x003)
+#define PH_DISP_YPOINT_REG    (0x200)
+#define PH_DISP_XPOINT_REG    (0x201)
+#define PH_DISP_PIXEL_REG     (0x202)
+#define PH_DISP_YMIN_REG      (0x406)
+#define PH_DISP_YMAX_REG      (0x407)
+#define PH_DISP_XMIN_REG      (0x408)
+#define PH_DISP_XMAX_REG      (0x409)
+
+/* Misc constants */
+#define NO_VALID_DISPLAY_FOUND      (0)
+#define DISPLAY2_IS_NOT_CONNECTED   (0)
+
+/* register values */
+#define V_BAC_ENABLE		(BIT(0))
+#define V_BAC_DISABLE_IDLE	(BIT(1))
+#define V_BAC_DISABLE_TRIG	(BIT(2))
+#define V_DUM_RESET		(BIT(3))
+#define V_MUX_RESET		(BIT(4))
+#define BAC_ENABLED		(BIT(0))
+#define BAC_DISABLED		0
+
+/* Sony LCD commands */
+#define V_LCD_STANDBY_OFF	((BIT(25)) | (0 << 16) | DISP_0_REG)
+#define V_LCD_USE_9BIT_BUS	((BIT(25)) | (2 << 16) | DISP_1_REG)
+#define V_LCD_SYNC_RISE_L	((BIT(25)) | (0 << 16) | DISP_SYNC_RISE_L_REG)
+#define V_LCD_SYNC_RISE_H	((BIT(25)) | (0 << 16) | DISP_SYNC_RISE_H_REG)
+#define V_LCD_SYNC_FALL_L	((BIT(25)) | (160 << 16) | DISP_SYNC_FALL_L_REG)
+#define V_LCD_SYNC_FALL_H	((BIT(25)) | (0 << 16) | DISP_SYNC_FALL_H_REG)
+#define V_LCD_SYNC_ENABLE	((BIT(25)) | (128 << 16) | DISP_SYNC_EN_REG)
+#define V_LCD_DISPLAY_ON	((BIT(25)) | (64 << 16) | DISP_0_REG)
+
+enum {
+	PAD_NONE,
+	PAD_512,
+	PAD_1024
+};
+
+enum {
+	RGB888,
+	RGB666,
+	RGB565,
+	BGR565,
+	ARGB1555,
+	ABGR1555,
+	ARGB4444,
+	ABGR4444
+};
+
+struct dum_setup {
+	int sync_neg_edge;
+	int round_robin;
+	int mux_int;
+	int synced_dirty_flag_int;
+	int dirty_flag_int;
+	int error_int;
+	int pf_empty_int;
+	int sf_empty_int;
+	int bac_dis_int;
+	u32 dirty_base_adr;
+	u32 command_base_adr;
+	u32 sync_clk_div;
+	int sync_output;
+	u32 sync_restart_val;
+	u32 set_sync_high;
+	u32 set_sync_low;
+};
+
+struct dum_ch_setup {
+	int disp_no;
+	u32 xmin;
+	u32 ymin;
+	u32 xmax;
+	u32 ymax;
+	int xmirror;
+	int ymirror;
+	int rotate;
+	u32 minadr;
+	u32 maxadr;
+	u32 dirtybuffer;
+	int pad;
+	int format;
+	int hwdirty;
+	int slave_trans;
+};
+
+struct disp_window {
+	u32 xmin_l;
+	u32 xmin_h;
+	u32 ymin;
+	u32 xmax_l;
+	u32 xmax_h;
+	u32 ymax;
+};
+
+#endif				/* #ifndef __PNX008_DUM_H__ */
diff --git a/drivers/video/pnx4008/fbcommon.h b/drivers/video/pnx4008/fbcommon.h
new file mode 100644
index 000000000..4ebc87daf
--- /dev/null
+++ b/drivers/video/pnx4008/fbcommon.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2005 Philips Semiconductors
+ *
+ * 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; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA, or http://www.gnu.org/licenses/gpl.html
+*/
+
+#define QCIF_W  (176)
+#define QCIF_H  (144)
+
+#define CIF_W   (352)
+#define CIF_H   (288)
+
+#define LCD_X_RES	208
+#define LCD_Y_RES	320
+#define LCD_X_PAD	256
+#define LCD_BBP		4	/* Bytes Per Pixel */
+
+#define DISP_MAX_X_SIZE     (320)
+#define DISP_MAX_Y_SIZE     (208)
+
+#define RETURNVAL_BASE (0x400)
+
+enum fb_ioctl_returntype {
+	ENORESOURCESLEFT = RETURNVAL_BASE,
+	ERESOURCESNOTFREED,
+	EPROCNOTOWNER,
+	EFBNOTOWNER,
+	ECOPYFAILED,
+	EIOREMAPFAILED,
+};
diff --git a/drivers/video/pnx4008/pnxrgbfb.c b/drivers/video/pnx4008/pnxrgbfb.c
new file mode 100644
index 000000000..7d9453c91
--- /dev/null
+++ b/drivers/video/pnx4008/pnxrgbfb.c
@@ -0,0 +1,213 @@
+/*
+ * drivers/video/pnx4008/pnxrgbfb.c
+ *
+ * PNX4008's framebuffer support
+ *
+ * Author: Grigory Tolstolytkin <gtolstolytkin@ru.mvista.com>
+ * Based on Philips Semiconductors's code
+ *
+ * Copyrght (c) 2005 MontaVista Software, Inc.
+ * Copyright (c) 2005 Philips Semiconductors
+ * 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 <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/slab.h>
+#include <linux/vmalloc.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/fb.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+
+#include <asm/uaccess.h>
+#include "sdum.h"
+#include "fbcommon.h"
+
+static u32 colreg[16];
+
+static struct fb_var_screeninfo rgbfb_var __initdata = {
+	.xres = LCD_X_RES,
+	.yres = LCD_Y_RES,
+	.xres_virtual = LCD_X_RES,
+	.yres_virtual = LCD_Y_RES,
+	.bits_per_pixel = 32,
+	.red.offset = 16,
+	.red.length = 8,
+	.green.offset = 8,
+	.green.length = 8,
+	.blue.offset = 0,
+	.blue.length = 8,
+	.left_margin = 0,
+	.right_margin = 0,
+	.upper_margin = 0,
+	.lower_margin = 0,
+	.vmode = FB_VMODE_NONINTERLACED,
+};
+static struct fb_fix_screeninfo rgbfb_fix __initdata = {
+	.id = "RGBFB",
+	.line_length = LCD_X_RES * LCD_BBP,
+	.type = FB_TYPE_PACKED_PIXELS,
+	.visual = FB_VISUAL_TRUECOLOR,
+	.xpanstep = 0,
+	.ypanstep = 0,
+	.ywrapstep = 0,
+	.accel = FB_ACCEL_NONE,
+};
+
+static int channel_owned;
+
+static int no_cursor(struct fb_info *info, struct fb_cursor *cursor)
+{
+	return 0;
+}
+
+static int rgbfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
+			   u_int transp, struct fb_info *info)
+{
+	if (regno > 15)
+		return 1;
+
+	colreg[regno] = ((red & 0xff00) << 8) | (green & 0xff00) |
+	    ((blue & 0xff00) >> 8);
+	return 0;
+}
+
+static int rgbfb_mmap(struct fb_info *info, struct vm_area_struct *vma)
+{
+	return pnx4008_sdum_mmap(info, vma, NULL);
+}
+
+static struct fb_ops rgbfb_ops = {
+	.fb_mmap = rgbfb_mmap,
+	.fb_setcolreg = rgbfb_setcolreg,
+	.fb_fillrect = cfb_fillrect,
+	.fb_copyarea = cfb_copyarea,
+	.fb_imageblit = cfb_imageblit,
+};
+
+static int rgbfb_remove(struct platform_device *pdev)
+{
+	struct fb_info *info = platform_get_drvdata(pdev);
+
+	if (info) {
+		unregister_framebuffer(info);
+		fb_dealloc_cmap(&info->cmap);
+		framebuffer_release(info);
+		platform_set_drvdata(pdev, NULL);
+		kfree(info);
+	}
+
+	pnx4008_free_dum_channel(channel_owned, pdev->id);
+	pnx4008_set_dum_exit_notification(pdev->id);
+
+	return 0;
+}
+
+static int __devinit rgbfb_probe(struct platform_device *pdev)
+{
+	struct fb_info *info;
+	struct dumchannel_uf chan_uf;
+	int ret;
+	char *option;
+
+	info = framebuffer_alloc(sizeof(u32) * 16, &pdev->dev);
+	if (!info) {
+		ret = -ENOMEM;
+		goto err;
+	}
+
+	pnx4008_get_fb_addresses(FB_TYPE_RGB, (void **)&info->screen_base,
+				 (dma_addr_t *) &rgbfb_fix.smem_start,
+				 &rgbfb_fix.smem_len);
+
+	if ((ret = pnx4008_alloc_dum_channel(pdev->id)) < 0)
+		goto err0;
+	else {
+		channel_owned = ret;
+		chan_uf.channelnr = channel_owned;
+		chan_uf.dirty = (u32 *) NULL;
+		chan_uf.source = (u32 *) rgbfb_fix.smem_start;
+		chan_uf.x_offset = 0;
+		chan_uf.y_offset = 0;
+		chan_uf.width = LCD_X_RES;
+		chan_uf.height = LCD_Y_RES;
+
+		if ((ret = pnx4008_put_dum_channel_uf(chan_uf, pdev->id))< 0)
+			goto err1;
+
+		if ((ret =
+		     pnx4008_set_dum_channel_sync(channel_owned, CONF_SYNC_ON,
+						  pdev->id)) < 0)
+			goto err1;
+
+		if ((ret =
+		     pnx4008_set_dum_channel_dirty_detect(channel_owned,
+							 CONF_DIRTYDETECTION_ON,
+							 pdev->id)) < 0)
+			goto err1;
+	}
+
+	if (!fb_get_options("pnxrgbfb", &option) && !strcmp(option, "nocursor"))
+		rgbfb_ops.fb_cursor = no_cursor;
+
+	info->node = -1;
+	info->flags = FBINFO_FLAG_DEFAULT;
+	info->fbops = &rgbfb_ops;
+	info->fix = rgbfb_fix;
+	info->var = rgbfb_var;
+	info->screen_size = rgbfb_fix.smem_len;
+	info->pseudo_palette = info->par;
+	info->par = NULL;
+
+	ret = fb_alloc_cmap(&info->cmap, 256, 0);
+	if (ret < 0)
+		goto err2;
+
+	ret = register_framebuffer(info);
+	if (ret < 0)
+		goto err3;
+	platform_set_drvdata(pdev, info);
+
+	return 0;
+
+err3:
+	fb_dealloc_cmap(&info->cmap);
+err2:
+	framebuffer_release(info);
+err1:
+	pnx4008_free_dum_channel(channel_owned, pdev->id);
+err0:
+	kfree(info);
+err:
+	return ret;
+}
+
+static struct platform_driver rgbfb_driver = {
+	.driver = {
+		.name = "rgbfb",
+	},
+	.probe = rgbfb_probe,
+	.remove = rgbfb_remove,
+};
+
+static int __init rgbfb_init(void)
+{
+	return platform_driver_register(&rgbfb_driver);
+}
+
+static void __exit rgbfb_exit(void)
+{
+	platform_driver_unregister(&rgbfb_driver);
+}
+
+module_init(rgbfb_init);
+module_exit(rgbfb_exit);
+
+MODULE_LICENSE("GPL");
diff --git a/drivers/video/pnx4008/sdum.c b/drivers/video/pnx4008/sdum.c
new file mode 100644
index 000000000..51f0ecc2a
--- /dev/null
+++ b/drivers/video/pnx4008/sdum.c
@@ -0,0 +1,872 @@
+/*
+ * drivers/video/pnx4008/sdum.c
+ *
+ * Display Update Master support
+ *
+ * Authors: Grigory Tolstolytkin <gtolstolytkin@ru.mvista.com>
+ *          Vitaly Wool <vitalywool@gmail.com>
+ * Based on Philips Semiconductors's code
+ *
+ * Copyrght (c) 2005-2006 MontaVista Software, Inc.
+ * Copyright (c) 2005 Philips Semiconductors
+ * 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 <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/tty.h>
+#include <linux/slab.h>
+#include <linux/vmalloc.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <linux/fb.h>
+#include <linux/init.h>
+#include <linux/dma-mapping.h>
+#include <linux/clk.h>
+#include <asm/uaccess.h>
+#include <asm/arch/gpio.h>
+
+#include "sdum.h"
+#include "fbcommon.h"
+#include "dum.h"
+
+/* Framebuffers we have */
+
+static struct pnx4008_fb_addr {
+	int fb_type;
+	long addr_offset;
+	long fb_length;
+} fb_addr[] = {
+	[0] = {
+		FB_TYPE_YUV, 0, 0xB0000
+	},
+	[1] = {
+		FB_TYPE_RGB, 0xB0000, 0x50000
+	},
+};
+
+static struct dum_data {
+	u32 lcd_phys_start;
+	u32 lcd_virt_start;
+	u32 slave_phys_base;
+	u32 *slave_virt_base;
+	int fb_owning_channel[MAX_DUM_CHANNELS];
+	struct dumchannel_uf chan_uf_store[MAX_DUM_CHANNELS];
+} dum_data;
+
+/* Different local helper functions */
+
+static u32 nof_pixels_dx(struct dum_ch_setup *ch_setup)
+{
+	return (ch_setup->xmax - ch_setup->xmin + 1);
+}
+
+static u32 nof_pixels_dy(struct dum_ch_setup *ch_setup)
+{
+	return (ch_setup->ymax - ch_setup->ymin + 1);
+}
+
+static u32 nof_pixels_dxy(struct dum_ch_setup *ch_setup)
+{
+	return (nof_pixels_dx(ch_setup) * nof_pixels_dy(ch_setup));
+}
+
+static u32 nof_bytes(struct dum_ch_setup *ch_setup)
+{
+	u32 r = nof_pixels_dxy(ch_setup);
+	switch (ch_setup->format) {
+	case RGB888:
+	case RGB666:
+		r *= 4;
+		break;
+
+	default:
+		r *= 2;
+		break;
+	}
+	return r;
+}
+
+static u32 build_command(int disp_no, u32 reg, u32 val)
+{
+	return ((disp_no << 26) | BIT(25) | (val << 16) | (disp_no << 10) |
+		(reg << 0));
+}
+
+static u32 build_double_index(int disp_no, u32 val)
+{
+	return ((disp_no << 26) | (val << 16) | (disp_no << 10) | (val << 0));
+}
+
+static void build_disp_window(struct dum_ch_setup * ch_setup, struct disp_window * dw)
+{
+	dw->ymin = ch_setup->ymin;
+	dw->ymax = ch_setup->ymax;
+	dw->xmin_l = ch_setup->xmin & 0xFF;
+	dw->xmin_h = (ch_setup->xmin & BIT(8)) >> 8;
+	dw->xmax_l = ch_setup->xmax & 0xFF;
+	dw->xmax_h = (ch_setup->xmax & BIT(8)) >> 8;
+}
+
+static int put_channel(struct dumchannel chan)
+{
+	int i = chan.channelnr;
+
+	if (i < 0 || i > MAX_DUM_CHANNELS)
+		return -EINVAL;
+	else {
+		DUM_CH_MIN(i) = chan.dum_ch_min;
+		DUM_CH_MAX(i) = chan.dum_ch_max;
+		DUM_CH_CONF(i) = chan.dum_ch_conf;
+		DUM_CH_CTRL(i) = chan.dum_ch_ctrl;
+	}
+
+	return 0;
+}
+
+static void clear_channel(int channr)
+{
+	struct dumchannel chan;
+
+	chan.channelnr = channr;
+	chan.dum_ch_min = 0;
+	chan.dum_ch_max = 0;
+	chan.dum_ch_conf = 0;
+	chan.dum_ch_ctrl = 0;
+
+	put_channel(chan);
+}
+
+static int put_cmd_string(struct cmdstring cmds)
+{
+	u16 *cmd_str_virtaddr;
+	u32 *cmd_ptr0_virtaddr;
+	u32 cmd_str_physaddr;
+
+	int i = cmds.channelnr;
+
+	if (i < 0 || i > MAX_DUM_CHANNELS)
+		return -EINVAL;
+	else if ((cmd_ptr0_virtaddr =
+		  (int *)ioremap_nocache(DUM_COM_BASE,
+					 sizeof(int) * MAX_DUM_CHANNELS)) ==
+		 NULL)
+		return -EIOREMAPFAILED;
+	else {
+		cmd_str_physaddr = ioread32(&cmd_ptr0_virtaddr[cmds.channelnr]);
+		if ((cmd_str_virtaddr =
+		     (u16 *) ioremap_nocache(cmd_str_physaddr,
+					     sizeof(cmds))) == NULL) {
+			iounmap(cmd_ptr0_virtaddr);
+			return -EIOREMAPFAILED;
+		} else {
+			int t;
+			for (t = 0; t < 8; t++)
+				iowrite16(*((u16 *)&cmds.prestringlen + t),
+					  cmd_str_virtaddr + t);
+
+			for (t = 0; t < cmds.prestringlen / 2; t++)
+				 iowrite16(*((u16 *)&cmds.precmd + t),
+					   cmd_str_virtaddr + t + 8);
+
+			for (t = 0; t < cmds.poststringlen / 2; t++)
+				iowrite16(*((u16 *)&cmds.postcmd + t),
+					  cmd_str_virtaddr + t + 8 +
+					  	cmds.prestringlen / 2);
+
+			iounmap(cmd_ptr0_virtaddr);
+			iounmap(cmd_str_virtaddr);
+		}
+	}
+
+	return 0;
+}
+
+static u32 dum_ch_setup(int ch_no, struct dum_ch_setup * ch_setup)
+{
+	struct cmdstring cmds_c;
+	struct cmdstring *cmds = &cmds_c;
+	struct disp_window dw;
+	int standard;
+	u32 orientation = 0;
+	struct dumchannel chan = { 0 };
+	int ret;
+
+	if ((ch_setup->xmirror) || (ch_setup->ymirror) || (ch_setup->rotate)) {
+		standard = 0;
+
+		orientation = BIT(1);	/* always set 9-bit-bus */
+		if (ch_setup->xmirror)
+			orientation |= BIT(4);
+		if (ch_setup->ymirror)
+			orientation |= BIT(3);
+		if (ch_setup->rotate)
+			orientation |= BIT(0);
+	} else
+		standard = 1;
+
+	cmds->channelnr = ch_no;
+
+	/* build command string header */
+	if (standard) {
+		cmds->prestringlen = 32;
+		cmds->poststringlen = 0;
+	} else {
+		cmds->prestringlen = 48;
+		cmds->poststringlen = 16;
+	}
+
+	cmds->format =
+	    (u16) ((ch_setup->disp_no << 4) | (BIT(3)) | (ch_setup->format));
+	cmds->reserved = 0x0;
+	cmds->startaddr_low = (ch_setup->minadr & 0xFFFF);
+	cmds->startaddr_high = (ch_setup->minadr >> 16);
+
+	if ((ch_setup->minadr == 0) && (ch_setup->maxadr == 0)
+	    && (ch_setup->xmin == 0)
+	    && (ch_setup->ymin == 0) && (ch_setup->xmax == 0)
+	    && (ch_setup->ymax == 0)) {
+		cmds->pixdatlen_low = 0;
+		cmds->pixdatlen_high = 0;
+	} else {
+		u32 nbytes = nof_bytes(ch_setup);
+		cmds->pixdatlen_low = (nbytes & 0xFFFF);
+		cmds->pixdatlen_high = (nbytes >> 16);
+	}
+
+	if (ch_setup->slave_trans)
+		cmds->pixdatlen_high |= BIT(15);
+
+	/* build pre-string */
+	build_disp_window(ch_setup, &dw);
+
+	if (standard) {
+		cmds->precmd[0] =
+		    build_command(ch_setup->disp_no, DISP_XMIN_L_REG, 0x99);
+		cmds->precmd[1] =
+		    build_command(ch_setup->disp_no, DISP_XMIN_L_REG,
+				  dw.xmin_l);
+		cmds->precmd[2] =
+		    build_command(ch_setup->disp_no, DISP_XMIN_H_REG,
+				  dw.xmin_h);
+		cmds->precmd[3] =
+		    build_command(ch_setup->disp_no, DISP_YMIN_REG, dw.ymin);
+		cmds->precmd[4] =
+		    build_command(ch_setup->disp_no, DISP_XMAX_L_REG,
+				  dw.xmax_l);
+		cmds->precmd[5] =
+		    build_command(ch_setup->disp_no, DISP_XMAX_H_REG,
+				  dw.xmax_h);
+		cmds->precmd[6] =
+		    build_command(ch_setup->disp_no, DISP_YMAX_REG, dw.ymax);
+		cmds->precmd[7] =
+		    build_double_index(ch_setup->disp_no, DISP_PIXEL_REG);
+	} else {
+		if (dw.xmin_l == ch_no)
+			cmds->precmd[0] =
+			    build_command(ch_setup->disp_no, DISP_XMIN_L_REG,
+					  0x99);
+		else
+			cmds->precmd[0] =
+			    build_command(ch_setup->disp_no, DISP_XMIN_L_REG,
+					  ch_no);
+
+		cmds->precmd[1] =
+		    build_command(ch_setup->disp_no, DISP_XMIN_L_REG,
+				  dw.xmin_l);
+		cmds->precmd[2] =
+		    build_command(ch_setup->disp_no, DISP_XMIN_H_REG,
+				  dw.xmin_h);
+		cmds->precmd[3] =
+		    build_command(ch_setup->disp_no, DISP_YMIN_REG, dw.ymin);
+		cmds->precmd[4] =
+		    build_command(ch_setup->disp_no, DISP_XMAX_L_REG,
+				  dw.xmax_l);
+		cmds->precmd[5] =
+		    build_command(ch_setup->disp_no, DISP_XMAX_H_REG,
+				  dw.xmax_h);
+		cmds->precmd[6] =
+		    build_command(ch_setup->disp_no, DISP_YMAX_REG, dw.ymax);
+		cmds->precmd[7] =
+		    build_command(ch_setup->disp_no, DISP_1_REG, orientation);
+		cmds->precmd[8] =
+		    build_double_index(ch_setup->disp_no, DISP_PIXEL_REG);
+		cmds->precmd[9] =
+		    build_double_index(ch_setup->disp_no, DISP_PIXEL_REG);
+		cmds->precmd[0xA] =
+		    build_double_index(ch_setup->disp_no, DISP_PIXEL_REG);
+		cmds->precmd[0xB] =
+		    build_double_index(ch_setup->disp_no, DISP_PIXEL_REG);
+		cmds->postcmd[0] =
+		    build_command(ch_setup->disp_no, DISP_1_REG, BIT(1));
+		cmds->postcmd[1] =
+		    build_command(ch_setup->disp_no, DISP_DUMMY1_REG, 1);
+		cmds->postcmd[2] =
+		    build_command(ch_setup->disp_no, DISP_DUMMY1_REG, 2);
+		cmds->postcmd[3] =
+		    build_command(ch_setup->disp_no, DISP_DUMMY1_REG, 3);
+	}
+
+	if ((ret = put_cmd_string(cmds_c)) != 0) {
+		return ret;
+	}
+
+	chan.channelnr = cmds->channelnr;
+	chan.dum_ch_min = ch_setup->dirtybuffer + ch_setup->minadr;
+	chan.dum_ch_max = ch_setup->dirtybuffer + ch_setup->maxadr;
+	chan.dum_ch_conf = 0x002;
+	chan.dum_ch_ctrl = 0x04;
+
+	put_channel(chan);
+
+	return 0;
+}
+
+static u32 display_open(int ch_no, int auto_update, u32 * dirty_buffer,
+			u32 * frame_buffer, u32 xpos, u32 ypos, u32 w, u32 h)
+{
+
+	struct dum_ch_setup k;
+	int ret;
+
+	/* keep width & height within display area */
+	if ((xpos + w) > DISP_MAX_X_SIZE)
+		w = DISP_MAX_X_SIZE - xpos;
+
+	if ((ypos + h) > DISP_MAX_Y_SIZE)
+		h = DISP_MAX_Y_SIZE - ypos;
+
+	/* assume 1 display only */
+	k.disp_no = 0;
+	k.xmin = xpos;
+	k.ymin = ypos;
+	k.xmax = xpos + (w - 1);
+	k.ymax = ypos + (h - 1);
+
+	/* adjust min and max values if necessary */
+	if (k.xmin > DISP_MAX_X_SIZE - 1)
+		k.xmin = DISP_MAX_X_SIZE - 1;
+	if (k.ymin > DISP_MAX_Y_SIZE - 1)
+		k.ymin = DISP_MAX_Y_SIZE - 1;
+
+	if (k.xmax > DISP_MAX_X_SIZE - 1)
+		k.xmax = DISP_MAX_X_SIZE - 1;
+	if (k.ymax > DISP_MAX_Y_SIZE - 1)
+		k.ymax = DISP_MAX_Y_SIZE - 1;
+
+	k.xmirror = 0;
+	k.ymirror = 0;
+	k.rotate = 0;
+	k.minadr = (u32) frame_buffer;
+	k.maxadr = (u32) frame_buffer + (((w - 1) << 10) | ((h << 2) - 2));
+	k.pad = PAD_1024;
+	k.dirtybuffer = (u32) dirty_buffer;
+	k.format = RGB888;
+	k.hwdirty = 0;
+	k.slave_trans = 0;
+
+	ret = dum_ch_setup(ch_no, &k);
+
+	return ret;
+}
+
+static void lcd_reset(void)
+{
+	u32 *dum_pio_base = (u32 *)IO_ADDRESS(PNX4008_PIO_BASE);
+
+	udelay(1);
+	iowrite32(BIT(19), &dum_pio_base[2]);
+	udelay(1);
+	iowrite32(BIT(19), &dum_pio_base[1]);
+	udelay(1);
+}
+
+static int dum_init(struct platform_device *pdev)
+{
+	struct clk *clk;
+
+	/* enable DUM clock */
+	clk = clk_get(&pdev->dev, "dum_ck");
+	if (IS_ERR(clk)) {
+		printk(KERN_ERR "pnx4008_dum: Unable to access DUM clock\n");
+		return PTR_ERR(clk);
+	}
+
+	clk_set_rate(clk, 1);
+	clk_put(clk);
+
+	DUM_CTRL = V_DUM_RESET;
+
+	/* set priority to "round-robin". All other params to "false" */
+	DUM_CONF = BIT(9);
+
+	/* Display 1 */
+	DUM_WTCFG1 = PNX4008_DUM_WT_CFG;
+	DUM_RTCFG1 = PNX4008_DUM_RT_CFG;
+	DUM_TCFG = PNX4008_DUM_T_CFG;
+
+	return 0;
+}
+
+static void dum_chan_init(void)
+{
+	int i = 0, ch = 0;
+	u32 *cmdptrs;
+	u32 *cmdstrings;
+
+	DUM_COM_BASE =
+		CMDSTRING_BASEADDR + BYTES_PER_CMDSTRING * NR_OF_CMDSTRINGS;
+
+	if ((cmdptrs =
+	     (u32 *) ioremap_nocache(DUM_COM_BASE,
+				     sizeof(u32) * NR_OF_CMDSTRINGS)) == NULL)
+		return;
+
+	for (ch = 0; ch < NR_OF_CMDSTRINGS; ch++)
+		iowrite32(CMDSTRING_BASEADDR + BYTES_PER_CMDSTRING * ch,
+			  cmdptrs + ch);
+
+	for (ch = 0; ch < MAX_DUM_CHANNELS; ch++)
+		clear_channel(ch);
+
+	/* Clear the cmdstrings */
+	cmdstrings =
+	    (u32 *)ioremap_nocache(*cmdptrs,
+				   BYTES_PER_CMDSTRING * NR_OF_CMDSTRINGS);
+
+	if (!cmdstrings)
+		goto out;
+
+	for (i = 0; i < NR_OF_CMDSTRINGS * BYTES_PER_CMDSTRING / sizeof(u32);
+	     i++)
+		iowrite32(0, cmdstrings + i);
+
+	iounmap((u32 *)cmdstrings);
+
+out:
+	iounmap((u32 *)cmdptrs);
+}
+
+static void lcd_init(void)
+{
+	lcd_reset();
+
+	DUM_OUTP_FORMAT1 = 0; /* RGB666 */
+
+	udelay(1);
+	iowrite32(V_LCD_STANDBY_OFF, dum_data.slave_virt_base);
+	udelay(1);
+	iowrite32(V_LCD_USE_9BIT_BUS, dum_data.slave_virt_base);
+	udelay(1);
+	iowrite32(V_LCD_SYNC_RISE_L, dum_data.slave_virt_base);
+	udelay(1);
+	iowrite32(V_LCD_SYNC_RISE_H, dum_data.slave_virt_base);
+	udelay(1);
+	iowrite32(V_LCD_SYNC_FALL_L, dum_data.slave_virt_base);
+	udelay(1);
+	iowrite32(V_LCD_SYNC_FALL_H, dum_data.slave_virt_base);
+	udelay(1);
+	iowrite32(V_LCD_SYNC_ENABLE, dum_data.slave_virt_base);
+	udelay(1);
+	iowrite32(V_LCD_DISPLAY_ON, dum_data.slave_virt_base);
+	udelay(1);
+}
+
+/* Interface exported to framebuffer drivers */
+
+int pnx4008_get_fb_addresses(int fb_type, void **virt_addr,
+			     dma_addr_t *phys_addr, int *fb_length)
+{
+	int i;
+	int ret = -1;
+	for (i = 0; i < ARRAY_SIZE(fb_addr); i++)
+		if (fb_addr[i].fb_type == fb_type) {
+			*virt_addr = (void *)(dum_data.lcd_virt_start +
+					fb_addr[i].addr_offset);
+			*phys_addr =
+			    dum_data.lcd_phys_start + fb_addr[i].addr_offset;
+			*fb_length = fb_addr[i].fb_length;
+			ret = 0;
+			break;
+		}
+
+	return ret;
+}
+
+EXPORT_SYMBOL(pnx4008_get_fb_addresses);
+
+int pnx4008_alloc_dum_channel(int dev_id)
+{
+	int i = 0;
+
+	while ((i < MAX_DUM_CHANNELS) && (dum_data.fb_owning_channel[i] != -1))
+		i++;
+
+	if (i == MAX_DUM_CHANNELS)
+		return -ENORESOURCESLEFT;
+	else {
+		dum_data.fb_owning_channel[i] = dev_id;
+		return i;
+	}
+}
+
+EXPORT_SYMBOL(pnx4008_alloc_dum_channel);
+
+int pnx4008_free_dum_channel(int channr, int dev_id)
+{
+	if (channr < 0 || channr > MAX_DUM_CHANNELS)
+		return -EINVAL;
+	else if (dum_data.fb_owning_channel[channr] != dev_id)
+		return -EFBNOTOWNER;
+	else {
+		clear_channel(channr);
+		dum_data.fb_owning_channel[channr] = -1;
+	}
+
+	return 0;
+}
+
+EXPORT_SYMBOL(pnx4008_free_dum_channel);
+
+int pnx4008_put_dum_channel_uf(struct dumchannel_uf chan_uf, int dev_id)
+{
+	int i = chan_uf.channelnr;
+	int ret;
+
+	if (i < 0 || i > MAX_DUM_CHANNELS)
+		return -EINVAL;
+	else if (dum_data.fb_owning_channel[i] != dev_id)
+		return -EFBNOTOWNER;
+	else if ((ret =
+		  display_open(chan_uf.channelnr, 0, chan_uf.dirty,
+			       chan_uf.source, chan_uf.y_offset,
+			       chan_uf.x_offset, chan_uf.height,
+			       chan_uf.width)) != 0)
+		return ret;
+	else {
+		dum_data.chan_uf_store[i].dirty = chan_uf.dirty;
+		dum_data.chan_uf_store[i].source = chan_uf.source;
+		dum_data.chan_uf_store[i].x_offset = chan_uf.x_offset;
+		dum_data.chan_uf_store[i].y_offset = chan_uf.y_offset;
+		dum_data.chan_uf_store[i].width = chan_uf.width;
+		dum_data.chan_uf_store[i].height = chan_uf.height;
+	}
+
+	return 0;
+}
+
+EXPORT_SYMBOL(pnx4008_put_dum_channel_uf);
+
+int pnx4008_set_dum_channel_sync(int channr, int val, int dev_id)
+{
+	if (channr < 0 || channr > MAX_DUM_CHANNELS)
+		return -EINVAL;
+	else if (dum_data.fb_owning_channel[channr] != dev_id)
+		return -EFBNOTOWNER;
+	else {
+		if (val == CONF_SYNC_ON) {
+			DUM_CH_CONF(channr) |= CONF_SYNCENABLE;
+			DUM_CH_CONF(channr) |= DUM_CHANNEL_CFG_SYNC_MASK |
+				DUM_CHANNEL_CFG_SYNC_MASK_SET;
+		} else if (val == CONF_SYNC_OFF)
+			DUM_CH_CONF(channr) &= ~CONF_SYNCENABLE;
+		else
+			return -EINVAL;
+	}
+
+	return 0;
+}
+
+EXPORT_SYMBOL(pnx4008_set_dum_channel_sync);
+
+int pnx4008_set_dum_channel_dirty_detect(int channr, int val, int dev_id)
+{
+	if (channr < 0 || channr > MAX_DUM_CHANNELS)
+		return -EINVAL;
+	else if (dum_data.fb_owning_channel[channr] != dev_id)
+		return -EFBNOTOWNER;
+	else {
+		if (val == CONF_DIRTYDETECTION_ON)
+			DUM_CH_CONF(channr) |= CONF_DIRTYENABLE;
+		else if (val == CONF_DIRTYDETECTION_OFF)
+			DUM_CH_CONF(channr) &= ~CONF_DIRTYENABLE;
+		else
+			return -EINVAL;
+	}
+
+	return 0;
+}
+
+EXPORT_SYMBOL(pnx4008_set_dum_channel_dirty_detect);
+
+#if 0 /* Functions not used currently, but likely to be used in future */
+
+static int get_channel(struct dumchannel *p_chan)
+{
+	int i = p_chan->channelnr;
+
+	if (i < 0 || i > MAX_DUM_CHANNELS)
+		return -EINVAL;
+	else {
+		p_chan->dum_ch_min = DUM_CH_MIN(i);
+		p_chan->dum_ch_max = DUM_CH_MAX(i);
+		p_chan->dum_ch_conf = DUM_CH_CONF(i);
+		p_chan->dum_ch_stat = DUM_CH_STAT(i);
+		p_chan->dum_ch_ctrl = 0;	/* WriteOnly control register */
+	}
+
+	return 0;
+}
+
+int pnx4008_get_dum_channel_uf(struct dumchannel_uf *p_chan_uf, int dev_id)
+{
+	int i = p_chan_uf->channelnr;
+
+	if (i < 0 || i > MAX_DUM_CHANNELS)
+		return -EINVAL;
+	else if (dum_data.fb_owning_channel[i] != dev_id)
+		return -EFBNOTOWNER;
+	else {
+		p_chan_uf->dirty = dum_data.chan_uf_store[i].dirty;
+		p_chan_uf->source = dum_data.chan_uf_store[i].source;
+		p_chan_uf->x_offset = dum_data.chan_uf_store[i].x_offset;
+		p_chan_uf->y_offset = dum_data.chan_uf_store[i].y_offset;
+		p_chan_uf->width = dum_data.chan_uf_store[i].width;
+		p_chan_uf->height = dum_data.chan_uf_store[i].height;
+	}
+
+	return 0;
+}
+
+EXPORT_SYMBOL(pnx4008_get_dum_channel_uf);
+
+int pnx4008_get_dum_channel_config(int channr, int dev_id)
+{
+	int ret;
+	struct dumchannel chan;
+
+	if (channr < 0 || channr > MAX_DUM_CHANNELS)
+		return -EINVAL;
+	else if (dum_data.fb_owning_channel[channr] != dev_id)
+		return -EFBNOTOWNER;
+	else {
+		chan.channelnr = channr;
+		if ((ret = get_channel(&chan)) != 0)
+			return ret;
+	}
+
+	return (chan.dum_ch_conf & DUM_CHANNEL_CFG_MASK);
+}
+
+EXPORT_SYMBOL(pnx4008_get_dum_channel_config);
+
+int pnx4008_force_update_dum_channel(int channr, int dev_id)
+{
+	if (channr < 0 || channr > MAX_DUM_CHANNELS)
+		return -EINVAL;
+
+	else if (dum_data.fb_owning_channel[channr] != dev_id)
+		return -EFBNOTOWNER;
+	else
+		DUM_CH_CTRL(channr) = CTRL_SETDIRTY;
+
+	return 0;
+}
+
+EXPORT_SYMBOL(pnx4008_force_update_dum_channel);
+
+#endif
+
+int pnx4008_sdum_mmap(struct fb_info *info, struct vm_area_struct *vma,
+		      struct device *dev)
+{
+	unsigned long off = vma->vm_pgoff << PAGE_SHIFT;
+
+	if (off < info->fix.smem_len) {
+		vma->vm_pgoff += 1;
+		return dma_mmap_writecombine(dev, vma,
+				(void *)dum_data.lcd_virt_start,
+				dum_data.lcd_phys_start,
+				FB_DMA_SIZE);
+	}
+	return -EINVAL;
+}
+
+EXPORT_SYMBOL(pnx4008_sdum_mmap);
+
+int pnx4008_set_dum_exit_notification(int dev_id)
+{
+	int i;
+
+	for (i = 0; i < MAX_DUM_CHANNELS; i++)
+		if (dum_data.fb_owning_channel[i] == dev_id)
+			return -ERESOURCESNOTFREED;
+
+	return 0;
+}
+
+EXPORT_SYMBOL(pnx4008_set_dum_exit_notification);
+
+/* Platform device driver for DUM */
+
+static int sdum_suspend(struct platform_device *pdev, pm_message_t state)
+{
+	int retval = 0;
+	struct clk *clk;
+
+	clk = clk_get(0, "dum_ck");
+	if (!IS_ERR(clk)) {
+		clk_set_rate(clk, 0);
+		clk_put(clk);
+	} else
+		retval = PTR_ERR(clk);
+
+	/* disable BAC */
+	DUM_CTRL = V_BAC_DISABLE_IDLE;
+
+	/* LCD standby & turn off display */
+	lcd_reset();
+
+	return retval;
+}
+
+static int sdum_resume(struct platform_device *pdev)
+{
+	int retval = 0;
+	struct clk *clk;
+
+	clk = clk_get(0, "dum_ck");
+	if (!IS_ERR(clk)) {
+		clk_set_rate(clk, 1);
+		clk_put(clk);
+	} else
+		retval = PTR_ERR(clk);
+
+	/* wait for BAC disable */
+	DUM_CTRL = V_BAC_DISABLE_TRIG;
+
+	while (DUM_CTRL & BAC_ENABLED)
+		udelay(10);
+
+	/* re-init LCD */
+	lcd_init();
+
+	/* enable BAC and reset MUX */
+	DUM_CTRL = V_BAC_ENABLE;
+	udelay(1);
+	DUM_CTRL = V_MUX_RESET;
+	return 0;
+}
+
+static int __devinit sdum_probe(struct platform_device *pdev)
+{
+	int ret = 0, i = 0;
+
+	/* map frame buffer */
+	dum_data.lcd_virt_start = (u32) dma_alloc_writecombine(&pdev->dev,
+						       FB_DMA_SIZE,
+						       &dum_data.lcd_phys_start,
+						       GFP_KERNEL);
+
+	if (!dum_data.lcd_virt_start) {
+		ret = -ENOMEM;
+		goto out_3;
+	}
+
+	/* map slave registers */
+	dum_data.slave_phys_base = PNX4008_DUM_SLAVE_BASE;
+	dum_data.slave_virt_base =
+	    (u32 *) ioremap_nocache(dum_data.slave_phys_base, sizeof(u32));
+
+	if (dum_data.slave_virt_base == NULL) {
+		ret = -ENOMEM;
+		goto out_2;
+	}
+
+	/* initialize DUM and LCD display */
+	ret = dum_init(pdev);
+	if (ret)
+		goto out_1;
+
+	dum_chan_init();
+	lcd_init();
+
+	DUM_CTRL = V_BAC_ENABLE;
+	udelay(1);
+	DUM_CTRL = V_MUX_RESET;
+
+	/* set decode address and sync clock divider */
+	DUM_DECODE = dum_data.lcd_phys_start & DUM_DECODE_MASK;
+	DUM_CLK_DIV = PNX4008_DUM_CLK_DIV;
+
+	for (i = 0; i < MAX_DUM_CHANNELS; i++)
+		dum_data.fb_owning_channel[i] = -1;
+
+	/*setup wakeup interrupt */
+	start_int_set_rising_edge(SE_DISP_SYNC_INT);
+	start_int_ack(SE_DISP_SYNC_INT);
+	start_int_umask(SE_DISP_SYNC_INT);
+
+	return 0;
+
+out_1:
+	iounmap((void *)dum_data.slave_virt_base);
+out_2:
+	dma_free_writecombine(&pdev->dev, FB_DMA_SIZE,
+			(void *)dum_data.lcd_virt_start,
+			dum_data.lcd_phys_start);
+out_3:
+	return ret;
+}
+
+static int sdum_remove(struct platform_device *pdev)
+{
+	struct clk *clk;
+
+	start_int_mask(SE_DISP_SYNC_INT);
+
+	clk = clk_get(0, "dum_ck");
+	if (!IS_ERR(clk)) {
+		clk_set_rate(clk, 0);
+		clk_put(clk);
+	}
+
+	iounmap((void *)dum_data.slave_virt_base);
+
+	dma_free_writecombine(&pdev->dev, FB_DMA_SIZE,
+			(void *)dum_data.lcd_virt_start,
+			dum_data.lcd_phys_start);
+
+	return 0;
+}
+
+static struct platform_driver sdum_driver = {
+	.driver = {
+		.name = "sdum",
+	},
+	.probe = sdum_probe,
+	.remove = sdum_remove,
+	.suspend = sdum_suspend,
+	.resume = sdum_resume,
+};
+
+int __init sdum_init(void)
+{
+	return platform_driver_register(&sdum_driver);
+}
+
+static void __exit sdum_exit(void)
+{
+	platform_driver_unregister(&sdum_driver);
+};
+
+module_init(sdum_init);
+module_exit(sdum_exit);
+
+MODULE_LICENSE("GPL");
diff --git a/drivers/video/pnx4008/sdum.h b/drivers/video/pnx4008/sdum.h
new file mode 100644
index 000000000..e8c5dcdd8
--- /dev/null
+++ b/drivers/video/pnx4008/sdum.h
@@ -0,0 +1,139 @@
+/*
+ * Copyright (C) 2005 Philips Semiconductors
+ *
+ * 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; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA, or http://www.gnu.org/licenses/gpl.html
+*/
+
+#define MAX_DUM_CHANNELS	64
+
+#define RGB_MEM_WINDOW(x) (0x10000000 + (x)*0x00100000)
+
+#define QCIF_OFFSET(x) (((x) == 0) ? 0x00000: ((x) == 1) ? 0x30000: -1)
+#define CIF_OFFSET(x)  (((x) == 0) ? 0x00000: ((x) == 1) ? 0x60000: -1)
+
+#define CTRL_SETDIRTY	 	(0x00000001)
+#define CONF_DIRTYENABLE	(0x00000020)
+#define CONF_SYNCENABLE		(0x00000004)
+
+#define DIRTY_ENABLED(conf)	((conf) & 0x0020)
+#define SYNC_ENABLED(conf) 	((conf) & 0x0004)
+
+/* Display 1 & 2 Write Timing Configuration */
+#define PNX4008_DUM_WT_CFG		0x00372000
+
+/* Display 1 & 2 Read Timing Configuration */
+#define PNX4008_DUM_RT_CFG		0x00003A47
+
+/* DUM Transit State Timing Configuration */
+#define PNX4008_DUM_T_CFG		0x1D	/* 29 HCLK cycles */
+
+/* DUM Sync count clock divider */
+#define PNX4008_DUM_CLK_DIV		0x02DD
+
+/* Memory size for framebuffer, allocated through dma_alloc_writecombine().
+ * Must be PAGE aligned
+ */
+#define FB_DMA_SIZE (PAGE_ALIGN(SZ_1M + PAGE_SIZE))
+
+#define OFFSET_RGBBUFFER (0xB0000)
+#define OFFSET_YUVBUFFER (0x00000)
+
+#define YUVBUFFER (lcd_video_start + OFFSET_YUVBUFFER)
+#define RGBBUFFER (lcd_video_start + OFFSET_RGBBUFFER)
+
+#define CMDSTRING_BASEADDR	(0x00C000)	/* iram */
+#define BYTES_PER_CMDSTRING	(0x80)
+#define NR_OF_CMDSTRINGS	(64)
+
+#define MAX_NR_PRESTRINGS (0x40)
+#define MAX_NR_POSTSTRINGS (0x40)
+
+/* various mask definitions */
+#define DUM_CLK_ENABLE 0x01
+#define DUM_CLK_DISABLE 0
+#define DUM_DECODE_MASK 0x1FFFFFFF
+#define DUM_CHANNEL_CFG_MASK 0x01FF
+#define DUM_CHANNEL_CFG_SYNC_MASK 0xFFFE00FF
+#define DUM_CHANNEL_CFG_SYNC_MASK_SET 0x0CA00
+
+#define SDUM_RETURNVAL_BASE (0x500)
+
+#define CONF_SYNC_OFF		(0x602)
+#define CONF_SYNC_ON		(0x603)
+
+#define CONF_DIRTYDETECTION_OFF	(0x600)
+#define CONF_DIRTYDETECTION_ON	(0x601)
+
+/* Set the corresponding bit. */
+#define BIT(n) (0x1U << (n))
+
+struct dumchannel_uf {
+	int channelnr;
+	u32 *dirty;
+	u32 *source;
+	u32 x_offset;
+	u32 y_offset;
+	u32 width;
+	u32 height;
+};
+
+enum {
+	FB_TYPE_YUV,
+	FB_TYPE_RGB
+};
+
+struct cmdstring {
+	int channelnr;
+	uint16_t prestringlen;
+	uint16_t poststringlen;
+	uint16_t format;
+	uint16_t reserved;
+	uint16_t startaddr_low;
+	uint16_t startaddr_high;
+	uint16_t pixdatlen_low;
+	uint16_t pixdatlen_high;
+	u32 precmd[MAX_NR_PRESTRINGS];
+	u32 postcmd[MAX_NR_POSTSTRINGS];
+
+};
+
+struct dumchannel {
+	int channelnr;
+	int dum_ch_min;
+	int dum_ch_max;
+	int dum_ch_conf;
+	int dum_ch_stat;
+	int dum_ch_ctrl;
+};
+
+int pnx4008_alloc_dum_channel(int dev_id);
+int pnx4008_free_dum_channel(int channr, int dev_id);
+
+int pnx4008_get_dum_channel_uf(struct dumchannel_uf *pChan_uf, int dev_id);
+int pnx4008_put_dum_channel_uf(struct dumchannel_uf chan_uf, int dev_id);
+
+int pnx4008_set_dum_channel_sync(int channr, int val, int dev_id);
+int pnx4008_set_dum_channel_dirty_detect(int channr, int val, int dev_id);
+
+int pnx4008_force_dum_update_channel(int channr, int dev_id);
+
+int pnx4008_get_dum_channel_config(int channr, int dev_id);
+
+int pnx4008_sdum_mmap(struct fb_info *info, struct vm_area_struct *vma, struct device *dev);
+int pnx4008_set_dum_exit_notification(int dev_id);
+
+int pnx4008_get_fb_addresses(int fb_type, void **virt_addr,
+			     dma_addr_t * phys_addr, int *fb_length);
diff --git a/drivers/w1/masters/ds2490.c b/drivers/w1/masters/ds2490.c
new file mode 100644
index 000000000..299e274d2
--- /dev/null
+++ b/drivers/w1/masters/ds2490.c
@@ -0,0 +1,947 @@
+/*
+ *	dscore.c
+ *
+ * Copyright (c) 2004 Evgeniy Polyakov <johnpol@2ka.mipt.ru>
+ *
+ *
+ * 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/kernel.h>
+#include <linux/mod_devicetable.h>
+#include <linux/usb.h>
+
+#include "../w1_int.h"
+#include "../w1.h"
+
+/* COMMAND TYPE CODES */
+#define CONTROL_CMD			0x00
+#define COMM_CMD			0x01
+#define MODE_CMD			0x02
+
+/* CONTROL COMMAND CODES */
+#define CTL_RESET_DEVICE		0x0000
+#define CTL_START_EXE			0x0001
+#define CTL_RESUME_EXE			0x0002
+#define CTL_HALT_EXE_IDLE		0x0003
+#define CTL_HALT_EXE_DONE		0x0004
+#define CTL_FLUSH_COMM_CMDS		0x0007
+#define CTL_FLUSH_RCV_BUFFER		0x0008
+#define CTL_FLUSH_XMT_BUFFER		0x0009
+#define CTL_GET_COMM_CMDS		0x000A
+
+/* MODE COMMAND CODES */
+#define MOD_PULSE_EN			0x0000
+#define MOD_SPEED_CHANGE_EN		0x0001
+#define MOD_1WIRE_SPEED			0x0002
+#define MOD_STRONG_PU_DURATION		0x0003
+#define MOD_PULLDOWN_SLEWRATE		0x0004
+#define MOD_PROG_PULSE_DURATION		0x0005
+#define MOD_WRITE1_LOWTIME		0x0006
+#define MOD_DSOW0_TREC			0x0007
+
+/* COMMUNICATION COMMAND CODES */
+#define COMM_ERROR_ESCAPE		0x0601
+#define COMM_SET_DURATION		0x0012
+#define COMM_BIT_IO			0x0020
+#define COMM_PULSE			0x0030
+#define COMM_1_WIRE_RESET		0x0042
+#define COMM_BYTE_IO			0x0052
+#define COMM_MATCH_ACCESS		0x0064
+#define COMM_BLOCK_IO			0x0074
+#define COMM_READ_STRAIGHT		0x0080
+#define COMM_DO_RELEASE			0x6092
+#define COMM_SET_PATH			0x00A2
+#define COMM_WRITE_SRAM_PAGE		0x00B2
+#define COMM_WRITE_EPROM		0x00C4
+#define COMM_READ_CRC_PROT_PAGE		0x00D4
+#define COMM_READ_REDIRECT_PAGE_CRC	0x21E4
+#define COMM_SEARCH_ACCESS		0x00F4
+
+/* Communication command bits */
+#define COMM_TYPE			0x0008
+#define COMM_SE				0x0008
+#define COMM_D				0x0008
+#define COMM_Z				0x0008
+#define COMM_CH				0x0008
+#define COMM_SM				0x0008
+#define COMM_R				0x0008
+#define COMM_IM				0x0001
+
+#define COMM_PS				0x4000
+#define COMM_PST			0x4000
+#define COMM_CIB			0x4000
+#define COMM_RTS			0x4000
+#define COMM_DT				0x2000
+#define COMM_SPU			0x1000
+#define COMM_F				0x0800
+#define COMM_NTP			0x0400
+#define COMM_ICP			0x0200
+#define COMM_RST			0x0100
+
+#define PULSE_PROG			0x01
+#define PULSE_SPUE			0x02
+
+#define BRANCH_MAIN			0xCC
+#define BRANCH_AUX			0x33
+
+/*
+ * Duration of the strong pull-up pulse in milliseconds.
+ */
+#define PULLUP_PULSE_DURATION		750
+
+/* Status flags */
+#define ST_SPUA				0x01  /* Strong Pull-up is active */
+#define ST_PRGA				0x02  /* 12V programming pulse is being generated */
+#define ST_12VP				0x04  /* external 12V programming voltage is present */
+#define ST_PMOD				0x08  /* DS2490 powered from USB and external sources */
+#define ST_HALT				0x10  /* DS2490 is currently halted */
+#define ST_IDLE				0x20  /* DS2490 is currently idle */
+#define ST_EPOF				0x80
+
+#define SPEED_NORMAL			0x00
+#define SPEED_FLEXIBLE			0x01
+#define SPEED_OVERDRIVE			0x02
+
+#define NUM_EP				4
+#define EP_CONTROL			0
+#define EP_STATUS			1
+#define EP_DATA_OUT			2
+#define EP_DATA_IN			3
+
+struct ds_device
+{
+	struct list_head	ds_entry;
+
+	struct usb_device	*udev;
+	struct usb_interface	*intf;
+
+	int			ep[NUM_EP];
+
+	struct w1_bus_master	master;
+};
+
+struct ds_status
+{
+	u8			enable;
+	u8			speed;
+	u8			pullup_dur;
+	u8			ppuls_dur;
+	u8			pulldown_slew;
+	u8			write1_time;
+	u8			write0_time;
+	u8			reserved0;
+	u8			status;
+	u8			command0;
+	u8			command1;
+	u8			command_buffer_status;
+	u8			data_out_buffer_status;
+	u8			data_in_buffer_status;
+	u8			reserved1;
+	u8			reserved2;
+
+};
+
+static struct usb_device_id ds_id_table [] = {
+	{ USB_DEVICE(0x04fa, 0x2490) },
+	{ },
+};
+MODULE_DEVICE_TABLE(usb, ds_id_table);
+
+static int ds_probe(struct usb_interface *, const struct usb_device_id *);
+static void ds_disconnect(struct usb_interface *);
+
+static inline void ds_dump_status(unsigned char *, unsigned char *, int);
+static int ds_send_control(struct ds_device *, u16, u16);
+static int ds_send_control_cmd(struct ds_device *, u16, u16);
+
+static LIST_HEAD(ds_devices);
+static DEFINE_MUTEX(ds_mutex);
+
+static struct usb_driver ds_driver = {
+	.name =		"DS9490R",
+	.probe =	ds_probe,
+	.disconnect =	ds_disconnect,
+	.id_table =	ds_id_table,
+};
+
+static int ds_send_control_cmd(struct ds_device *dev, u16 value, u16 index)
+{
+	int err;
+
+	err = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, dev->ep[EP_CONTROL]),
+			CONTROL_CMD, 0x40, value, index, NULL, 0, 1000);
+	if (err < 0) {
+		printk(KERN_ERR "Failed to send command control message %x.%x: err=%d.\n",
+				value, index, err);
+		return err;
+	}
+
+	return err;
+}
+#if 0
+static int ds_send_control_mode(struct ds_device *dev, u16 value, u16 index)
+{
+	int err;
+
+	err = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, dev->ep[EP_CONTROL]),
+			MODE_CMD, 0x40, value, index, NULL, 0, 1000);
+	if (err < 0) {
+		printk(KERN_ERR "Failed to send mode control message %x.%x: err=%d.\n",
+				value, index, err);
+		return err;
+	}
+
+	return err;
+}
+#endif
+static int ds_send_control(struct ds_device *dev, u16 value, u16 index)
+{
+	int err;
+
+	err = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, dev->ep[EP_CONTROL]),
+			COMM_CMD, 0x40, value, index, NULL, 0, 1000);
+	if (err < 0) {
+		printk(KERN_ERR "Failed to send control message %x.%x: err=%d.\n",
+				value, index, err);
+		return err;
+	}
+
+	return err;
+}
+
+static inline void ds_dump_status(unsigned char *buf, unsigned char *str, int off)
+{
+	printk("%45s: %8x\n", str, buf[off]);
+}
+
+static int ds_recv_status_nodump(struct ds_device *dev, struct ds_status *st,
+				 unsigned char *buf, int size)
+{
+	int count, err;
+
+	memset(st, 0, sizeof(st));
+
+	count = 0;
+	err = usb_bulk_msg(dev->udev, usb_rcvbulkpipe(dev->udev, dev->ep[EP_STATUS]), buf, size, &count, 100);
+	if (err < 0) {
+		printk(KERN_ERR "Failed to read 1-wire data from 0x%x: err=%d.\n", dev->ep[EP_STATUS], err);
+		return err;
+	}
+
+	if (count >= sizeof(*st))
+		memcpy(st, buf, sizeof(*st));
+
+	return count;
+}
+
+static int ds_recv_status(struct ds_device *dev, struct ds_status *st)
+{
+	unsigned char buf[64];
+	int count, err = 0, i;
+
+	memcpy(st, buf, sizeof(*st));
+
+	count = ds_recv_status_nodump(dev, st, buf, sizeof(buf));
+	if (count < 0)
+		return err;
+
+	printk("0x%x: count=%d, status: ", dev->ep[EP_STATUS], count);
+	for (i=0; i<count; ++i)
+		printk("%02x ", buf[i]);
+	printk("\n");
+
+	if (count >= 16) {
+		ds_dump_status(buf, "enable flag", 0);
+		ds_dump_status(buf, "1-wire speed", 1);
+		ds_dump_status(buf, "strong pullup duration", 2);
+		ds_dump_status(buf, "programming pulse duration", 3);
+		ds_dump_status(buf, "pulldown slew rate control", 4);
+		ds_dump_status(buf, "write-1 low time", 5);
+		ds_dump_status(buf, "data sample offset/write-0 recovery time", 6);
+		ds_dump_status(buf, "reserved (test register)", 7);
+		ds_dump_status(buf, "device status flags", 8);
+		ds_dump_status(buf, "communication command byte 1", 9);
+		ds_dump_status(buf, "communication command byte 2", 10);
+		ds_dump_status(buf, "communication command buffer status", 11);
+		ds_dump_status(buf, "1-wire data output buffer status", 12);
+		ds_dump_status(buf, "1-wire data input buffer status", 13);
+		ds_dump_status(buf, "reserved", 14);
+		ds_dump_status(buf, "reserved", 15);
+	}
+
+	memcpy(st, buf, sizeof(*st));
+
+	if (st->status & ST_EPOF) {
+		printk(KERN_INFO "Resetting device after ST_EPOF.\n");
+		err = ds_send_control_cmd(dev, CTL_RESET_DEVICE, 0);
+		if (err)
+			return err;
+		count = ds_recv_status_nodump(dev, st, buf, sizeof(buf));
+		if (count < 0)
+			return err;
+	}
+#if 0
+	if (st->status & ST_IDLE) {
+		printk(KERN_INFO "Resetting pulse after ST_IDLE.\n");
+		err = ds_start_pulse(dev, PULLUP_PULSE_DURATION);
+		if (err)
+			return err;
+	}
+#endif
+
+	return err;
+}
+
+static int ds_recv_data(struct ds_device *dev, unsigned char *buf, int size)
+{
+	int count, err;
+	struct ds_status st;
+
+	count = 0;
+	err = usb_bulk_msg(dev->udev, usb_rcvbulkpipe(dev->udev, dev->ep[EP_DATA_IN]),
+				buf, size, &count, 1000);
+	if (err < 0) {
+		printk(KERN_INFO "Clearing ep0x%x.\n", dev->ep[EP_DATA_IN]);
+		usb_clear_halt(dev->udev, usb_rcvbulkpipe(dev->udev, dev->ep[EP_DATA_IN]));
+		ds_recv_status(dev, &st);
+		return err;
+	}
+
+#if 0
+	{
+		int i;
+
+		printk("%s: count=%d: ", __func__, count);
+		for (i=0; i<count; ++i)
+			printk("%02x ", buf[i]);
+		printk("\n");
+	}
+#endif
+	return count;
+}
+
+static int ds_send_data(struct ds_device *dev, unsigned char *buf, int len)
+{
+	int count, err;
+
+	count = 0;
+	err = usb_bulk_msg(dev->udev, usb_sndbulkpipe(dev->udev, dev->ep[EP_DATA_OUT]), buf, len, &count, 1000);
+	if (err < 0) {
+		printk(KERN_ERR "Failed to read 1-wire data from 0x02: err=%d.\n", err);
+		return err;
+	}
+
+	return err;
+}
+
+#if 0
+
+int ds_stop_pulse(struct ds_device *dev, int limit)
+{
+	struct ds_status st;
+	int count = 0, err = 0;
+	u8 buf[0x20];
+
+	do {
+		err = ds_send_control(dev, CTL_HALT_EXE_IDLE, 0);
+		if (err)
+			break;
+		err = ds_send_control(dev, CTL_RESUME_EXE, 0);
+		if (err)
+			break;
+		err = ds_recv_status_nodump(dev, &st, buf, sizeof(buf));
+		if (err)
+			break;
+
+		if ((st.status & ST_SPUA) == 0) {
+			err = ds_send_control_mode(dev, MOD_PULSE_EN, 0);
+			if (err)
+				break;
+		}
+	} while(++count < limit);
+
+	return err;
+}
+
+int ds_detect(struct ds_device *dev, struct ds_status *st)
+{
+	int err;
+
+	err = ds_send_control_cmd(dev, CTL_RESET_DEVICE, 0);
+	if (err)
+		return err;
+
+	err = ds_send_control(dev, COMM_SET_DURATION | COMM_IM, 0);
+	if (err)
+		return err;
+
+	err = ds_send_control(dev, COMM_SET_DURATION | COMM_IM | COMM_TYPE, 0x40);
+	if (err)
+		return err;
+
+	err = ds_send_control_mode(dev, MOD_PULSE_EN, PULSE_PROG);
+	if (err)
+		return err;
+
+	err = ds_recv_status(dev, st);
+
+	return err;
+}
+
+#endif  /*  0  */
+
+static int ds_wait_status(struct ds_device *dev, struct ds_status *st)
+{
+	u8 buf[0x20];
+	int err, count = 0;
+
+	do {
+		err = ds_recv_status_nodump(dev, st, buf, sizeof(buf));
+#if 0
+		if (err >= 0) {
+			int i;
+			printk("0x%x: count=%d, status: ", dev->ep[EP_STATUS], err);
+			for (i=0; i<err; ++i)
+				printk("%02x ", buf[i]);
+			printk("\n");
+		}
+#endif
+	} while(!(buf[0x08] & 0x20) && !(err < 0) && ++count < 100);
+
+
+	if (((err > 16) && (buf[0x10] & 0x01)) || count >= 100 || err < 0) {
+		ds_recv_status(dev, st);
+		return -1;
+	} else
+		return 0;
+}
+
+static int ds_reset(struct ds_device *dev, struct ds_status *st)
+{
+	int err;
+
+	//err = ds_send_control(dev, COMM_1_WIRE_RESET | COMM_F | COMM_IM | COMM_SE, SPEED_FLEXIBLE);
+	err = ds_send_control(dev, 0x43, SPEED_NORMAL);
+	if (err)
+		return err;
+
+	ds_wait_status(dev, st);
+#if 0
+	if (st->command_buffer_status) {
+		printk(KERN_INFO "Short circuit.\n");
+		return -EIO;
+	}
+#endif
+
+	return 0;
+}
+
+#if 0
+static int ds_set_speed(struct ds_device *dev, int speed)
+{
+	int err;
+
+	if (speed != SPEED_NORMAL && speed != SPEED_FLEXIBLE && speed != SPEED_OVERDRIVE)
+		return -EINVAL;
+
+	if (speed != SPEED_OVERDRIVE)
+		speed = SPEED_FLEXIBLE;
+
+	speed &= 0xff;
+
+	err = ds_send_control_mode(dev, MOD_1WIRE_SPEED, speed);
+	if (err)
+		return err;
+
+	return err;
+}
+#endif  /*  0  */
+
+static int ds_start_pulse(struct ds_device *dev, int delay)
+{
+	int err;
+	u8 del = 1 + (u8)(delay >> 4);
+	struct ds_status st;
+
+#if 0
+	err = ds_stop_pulse(dev, 10);
+	if (err)
+		return err;
+
+	err = ds_send_control_mode(dev, MOD_PULSE_EN, PULSE_SPUE);
+	if (err)
+		return err;
+#endif
+	err = ds_send_control(dev, COMM_SET_DURATION | COMM_IM, del);
+	if (err)
+		return err;
+
+	err = ds_send_control(dev, COMM_PULSE | COMM_IM | COMM_F, 0);
+	if (err)
+		return err;
+
+	mdelay(delay);
+
+	ds_wait_status(dev, &st);
+
+	return err;
+}
+
+static int ds_touch_bit(struct ds_device *dev, u8 bit, u8 *tbit)
+{
+	int err, count;
+	struct ds_status st;
+	u16 value = (COMM_BIT_IO | COMM_IM) | ((bit) ? COMM_D : 0);
+	u16 cmd;
+
+	err = ds_send_control(dev, value, 0);
+	if (err)
+		return err;
+
+	count = 0;
+	do {
+		err = ds_wait_status(dev, &st);
+		if (err)
+			return err;
+
+		cmd = st.command0 | (st.command1 << 8);
+	} while (cmd != value && ++count < 10);
+
+	if (err < 0 || count >= 10) {
+		printk(KERN_ERR "Failed to obtain status.\n");
+		return -EINVAL;
+	}
+
+	err = ds_recv_data(dev, tbit, sizeof(*tbit));
+	if (err < 0)
+		return err;
+
+	return 0;
+}
+
+static int ds_write_bit(struct ds_device *dev, u8 bit)
+{
+	int err;
+	struct ds_status st;
+
+	err = ds_send_control(dev, COMM_BIT_IO | COMM_IM | (bit) ? COMM_D : 0, 0);
+	if (err)
+		return err;
+
+	ds_wait_status(dev, &st);
+
+	return 0;
+}
+
+static int ds_write_byte(struct ds_device *dev, u8 byte)
+{
+	int err;
+	struct ds_status st;
+	u8 rbyte;
+
+	err = ds_send_control(dev, COMM_BYTE_IO | COMM_IM | COMM_SPU, byte);
+	if (err)
+		return err;
+
+	err = ds_wait_status(dev, &st);
+	if (err)
+		return err;
+
+	err = ds_recv_data(dev, &rbyte, sizeof(rbyte));
+	if (err < 0)
+		return err;
+
+	ds_start_pulse(dev, PULLUP_PULSE_DURATION);
+
+	return !(byte == rbyte);
+}
+
+static int ds_read_byte(struct ds_device *dev, u8 *byte)
+{
+	int err;
+	struct ds_status st;
+
+	err = ds_send_control(dev, COMM_BYTE_IO | COMM_IM , 0xff);
+	if (err)
+		return err;
+
+	ds_wait_status(dev, &st);
+
+	err = ds_recv_data(dev, byte, sizeof(*byte));
+	if (err < 0)
+		return err;
+
+	return 0;
+}
+
+static int ds_read_block(struct ds_device *dev, u8 *buf, int len)
+{
+	struct ds_status st;
+	int err;
+
+	if (len > 64*1024)
+		return -E2BIG;
+
+	memset(buf, 0xFF, len);
+
+	err = ds_send_data(dev, buf, len);
+	if (err < 0)
+		return err;
+
+	err = ds_send_control(dev, COMM_BLOCK_IO | COMM_IM | COMM_SPU, len);
+	if (err)
+		return err;
+
+	ds_wait_status(dev, &st);
+
+	memset(buf, 0x00, len);
+	err = ds_recv_data(dev, buf, len);
+
+	return err;
+}
+
+static int ds_write_block(struct ds_device *dev, u8 *buf, int len)
+{
+	int err;
+	struct ds_status st;
+
+	err = ds_send_data(dev, buf, len);
+	if (err < 0)
+		return err;
+
+	ds_wait_status(dev, &st);
+
+	err = ds_send_control(dev, COMM_BLOCK_IO | COMM_IM | COMM_SPU, len);
+	if (err)
+		return err;
+
+	ds_wait_status(dev, &st);
+
+	err = ds_recv_data(dev, buf, len);
+	if (err < 0)
+		return err;
+
+	ds_start_pulse(dev, PULLUP_PULSE_DURATION);
+
+	return !(err == len);
+}
+
+#if 0
+
+static int ds_search(struct ds_device *dev, u64 init, u64 *buf, u8 id_number, int conditional_search)
+{
+	int err;
+	u16 value, index;
+	struct ds_status st;
+
+	memset(buf, 0, sizeof(buf));
+
+	err = ds_send_data(ds_dev, (unsigned char *)&init, 8);
+	if (err)
+		return err;
+
+	ds_wait_status(ds_dev, &st);
+
+	value = COMM_SEARCH_ACCESS | COMM_IM | COMM_SM | COMM_F | COMM_RTS;
+	index = (conditional_search ? 0xEC : 0xF0) | (id_number << 8);
+	err = ds_send_control(ds_dev, value, index);
+	if (err)
+		return err;
+
+	ds_wait_status(ds_dev, &st);
+
+	err = ds_recv_data(ds_dev, (unsigned char *)buf, 8*id_number);
+	if (err < 0)
+		return err;
+
+	return err/8;
+}
+
+static int ds_match_access(struct ds_device *dev, u64 init)
+{
+	int err;
+	struct ds_status st;
+
+	err = ds_send_data(dev, (unsigned char *)&init, sizeof(init));
+	if (err)
+		return err;
+
+	ds_wait_status(dev, &st);
+
+	err = ds_send_control(dev, COMM_MATCH_ACCESS | COMM_IM | COMM_RST, 0x0055);
+	if (err)
+		return err;
+
+	ds_wait_status(dev, &st);
+
+	return 0;
+}
+
+static int ds_set_path(struct ds_device *dev, u64 init)
+{
+	int err;
+	struct ds_status st;
+	u8 buf[9];
+
+	memcpy(buf, &init, 8);
+	buf[8] = BRANCH_MAIN;
+
+	err = ds_send_data(dev, buf, sizeof(buf));
+	if (err)
+		return err;
+
+	ds_wait_status(dev, &st);
+
+	err = ds_send_control(dev, COMM_SET_PATH | COMM_IM | COMM_RST, 0);
+	if (err)
+		return err;
+
+	ds_wait_status(dev, &st);
+
+	return 0;
+}
+
+#endif  /*  0  */
+
+static u8 ds9490r_touch_bit(void *data, u8 bit)
+{
+	u8 ret;
+	struct ds_device *dev = data;
+
+	if (ds_touch_bit(dev, bit, &ret))
+		return 0;
+
+	return ret;
+}
+
+static void ds9490r_write_bit(void *data, u8 bit)
+{
+	struct ds_device *dev = data;
+
+	ds_write_bit(dev, bit);
+}
+
+static void ds9490r_write_byte(void *data, u8 byte)
+{
+	struct ds_device *dev = data;
+
+	ds_write_byte(dev, byte);
+}
+
+static u8 ds9490r_read_bit(void *data)
+{
+	struct ds_device *dev = data;
+	int err;
+	u8 bit = 0;
+
+	err = ds_touch_bit(dev, 1, &bit);
+	if (err)
+		return 0;
+
+	return bit & 1;
+}
+
+static u8 ds9490r_read_byte(void *data)
+{
+	struct ds_device *dev = data;
+	int err;
+	u8 byte = 0;
+
+	err = ds_read_byte(dev, &byte);
+	if (err)
+		return 0;
+
+	return byte;
+}
+
+static void ds9490r_write_block(void *data, const u8 *buf, int len)
+{
+	struct ds_device *dev = data;
+
+	ds_write_block(dev, (u8 *)buf, len);
+}
+
+static u8 ds9490r_read_block(void *data, u8 *buf, int len)
+{
+	struct ds_device *dev = data;
+	int err;
+
+	err = ds_read_block(dev, buf, len);
+	if (err < 0)
+		return 0;
+
+	return len;
+}
+
+static u8 ds9490r_reset(void *data)
+{
+	struct ds_device *dev = data;
+	struct ds_status st;
+	int err;
+
+	memset(&st, 0, sizeof(st));
+
+	err = ds_reset(dev, &st);
+	if (err)
+		return 1;
+
+	return 0;
+}
+
+static int ds_w1_init(struct ds_device *dev)
+{
+	memset(&dev->master, 0, sizeof(struct w1_bus_master));
+
+	dev->master.data	= dev;
+	dev->master.touch_bit	= &ds9490r_touch_bit;
+	dev->master.read_bit	= &ds9490r_read_bit;
+	dev->master.write_bit	= &ds9490r_write_bit;
+	dev->master.read_byte	= &ds9490r_read_byte;
+	dev->master.write_byte	= &ds9490r_write_byte;
+	dev->master.read_block	= &ds9490r_read_block;
+	dev->master.write_block	= &ds9490r_write_block;
+	dev->master.reset_bus	= &ds9490r_reset;
+
+	return w1_add_master_device(&dev->master);
+}
+
+static void ds_w1_fini(struct ds_device *dev)
+{
+	w1_remove_master_device(&dev->master);
+}
+
+static int ds_probe(struct usb_interface *intf,
+		    const struct usb_device_id *udev_id)
+{
+	struct usb_device *udev = interface_to_usbdev(intf);
+	struct usb_endpoint_descriptor *endpoint;
+	struct usb_host_interface *iface_desc;
+	struct ds_device *dev;
+	int i, err;
+
+	dev = kmalloc(sizeof(struct ds_device), GFP_KERNEL);
+	if (!dev) {
+		printk(KERN_INFO "Failed to allocate new DS9490R structure.\n");
+		return -ENOMEM;
+	}
+	dev->udev = usb_get_dev(udev);
+	if (!dev->udev) {
+		err = -ENOMEM;
+		goto err_out_free;
+	}
+	memset(dev->ep, 0, sizeof(dev->ep));
+
+	usb_set_intfdata(intf, dev);
+
+	err = usb_set_interface(dev->udev, intf->altsetting[0].desc.bInterfaceNumber, 3);
+	if (err) {
+		printk(KERN_ERR "Failed to set alternative setting 3 for %d interface: err=%d.\n",
+				intf->altsetting[0].desc.bInterfaceNumber, err);
+		goto err_out_clear;
+	}
+
+	err = usb_reset_configuration(dev->udev);
+	if (err) {
+		printk(KERN_ERR "Failed to reset configuration: err=%d.\n", err);
+		goto err_out_clear;
+	}
+
+	iface_desc = &intf->altsetting[0];
+	if (iface_desc->desc.bNumEndpoints != NUM_EP-1) {
+		printk(KERN_INFO "Num endpoints=%d. It is not DS9490R.\n", iface_desc->desc.bNumEndpoints);
+		err = -EINVAL;
+		goto err_out_clear;
+	}
+
+	/*
+	 * This loop doesn'd show control 0 endpoint,
+	 * so we will fill only 1-3 endpoints entry.
+	 */
+	for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {
+		endpoint = &iface_desc->endpoint[i].desc;
+
+		dev->ep[i+1] = endpoint->bEndpointAddress;
+#if 0
+		printk("%d: addr=%x, size=%d, dir=%s, type=%x\n",
+			i, endpoint->bEndpointAddress, le16_to_cpu(endpoint->wMaxPacketSize),
+			(endpoint->bEndpointAddress & USB_DIR_IN)?"IN":"OUT",
+			endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK);
+#endif
+	}
+
+	err = ds_w1_init(dev);
+	if (err)
+		goto err_out_clear;
+
+	mutex_lock(&ds_mutex);
+	list_add_tail(&dev->ds_entry, &ds_devices);
+	mutex_unlock(&ds_mutex);
+
+	return 0;
+
+err_out_clear:
+	usb_set_intfdata(intf, NULL);
+	usb_put_dev(dev->udev);
+err_out_free:
+	kfree(dev);
+	return err;
+}
+
+static void ds_disconnect(struct usb_interface *intf)
+{
+	struct ds_device *dev;
+
+	dev = usb_get_intfdata(intf);
+	if (!dev)
+		return;
+
+	mutex_lock(&ds_mutex);
+	list_del(&dev->ds_entry);
+	mutex_unlock(&ds_mutex);
+
+	ds_w1_fini(dev);
+
+	usb_set_intfdata(intf, NULL);
+
+	usb_put_dev(dev->udev);
+	kfree(dev);
+}
+
+static int ds_init(void)
+{
+	int err;
+
+	err = usb_register(&ds_driver);
+	if (err) {
+		printk(KERN_INFO "Failed to register DS9490R USB device: err=%d.\n", err);
+		return err;
+	}
+
+	return 0;
+}
+
+static void ds_fini(void)
+{
+	usb_deregister(&ds_driver);
+}
+
+module_init(ds_init);
+module_exit(ds_fini);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Evgeniy Polyakov <johnpol@2ka.mipt.ru>");
+MODULE_DESCRIPTION("DS2490 USB <-> W1 bus master driver (DS9490*)");
diff --git a/drivers/xen/blktap/blktapmain.c b/drivers/xen/blktap/blktapmain.c
new file mode 100644
index 000000000..15b368b9e
--- /dev/null
+++ b/drivers/xen/blktap/blktapmain.c
@@ -0,0 +1,1393 @@
+/******************************************************************************
+ * drivers/xen/blktap/blktap.c
+ * 
+ * Back-end driver for user level virtual block devices. This portion of the
+ * driver exports a 'unified' block-device interface that can be accessed
+ * by any operating system that implements a compatible front end. Requests
+ * are remapped to a user-space memory region.
+ *
+ * Based on the blkback driver code.
+ * 
+ * Copyright (c) 2004-2005, Andrew Warfield and Julian Chesterfield
+ *
+ * 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; or, when distributed
+ * separately from the Linux kernel or incorporated into other
+ * software packages, subject to the following license:
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this source file (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy, modify,
+ * merge, publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * 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/spinlock.h>
+#include <linux/kthread.h>
+#include <linux/list.h>
+#include <asm/hypervisor.h>
+#include "common.h"
+#include <xen/balloon.h>
+#include <linux/kernel.h>
+#include <linux/fs.h>
+#include <linux/mm.h>
+#include <linux/errno.h>
+#include <linux/major.h>
+#include <linux/gfp.h>
+#include <linux/poll.h>
+#include <asm/tlbflush.h>
+
+#define MAX_TAP_DEV 100     /*the maximum number of tapdisk ring devices    */
+#define MAX_DEV_NAME 100    /*the max tapdisk ring device name e.g. blktap0 */
+
+
+struct class *xen_class;
+EXPORT_SYMBOL_GPL(xen_class);
+
+/*
+ * Setup the xen class.  This should probably go in another file, but
+ * since blktap is the only user of it so far, it gets to keep it.
+ */
+int setup_xen_class(void)
+{
+	int ret;
+
+	if (xen_class)
+		return 0;
+
+	xen_class = class_create(THIS_MODULE, "xen");
+	if ((ret = IS_ERR(xen_class))) {
+		xen_class = NULL;
+		return ret;
+	}
+
+	return 0;
+}
+
+/*
+ * The maximum number of requests that can be outstanding at any time
+ * is determined by 
+ *
+ *   [mmap_alloc * MAX_PENDING_REQS * BLKIF_MAX_SEGMENTS_PER_REQUEST] 
+ *
+ * where mmap_alloc < MAX_DYNAMIC_MEM.
+ *
+ * TODO:
+ * mmap_alloc is initialised to 2 and should be adjustable on the fly via
+ * sysfs.
+ */
+#define MAX_DYNAMIC_MEM 64
+#define MAX_PENDING_REQS 64   
+#define MMAP_PAGES (MAX_PENDING_REQS * BLKIF_MAX_SEGMENTS_PER_REQUEST)
+#define MMAP_VADDR(_start, _req,_seg)                                   \
+        (_start +                                                       \
+         ((_req) * BLKIF_MAX_SEGMENTS_PER_REQUEST * PAGE_SIZE) +        \
+         ((_seg) * PAGE_SIZE))
+static int blkif_reqs = MAX_PENDING_REQS;
+static int mmap_pages = MMAP_PAGES;
+
+#define RING_PAGES 1 /* BLKTAP - immediately before the mmap area, we
+		      * have a bunch of pages reserved for shared
+		      * memory rings.
+		      */
+
+/*Data struct associated with each of the tapdisk devices*/
+typedef struct tap_blkif {
+	struct vm_area_struct *vma;   /*Shared memory area                   */
+	unsigned long rings_vstart;   /*Kernel memory mapping                */
+	unsigned long user_vstart;    /*User memory mapping                  */
+	unsigned long dev_inuse;      /*One process opens device at a time.  */
+	unsigned long dev_pending;    /*In process of being opened           */
+	unsigned long ring_ok;        /*make this ring->state                */
+	blkif_front_ring_t ufe_ring;  /*Rings up to user space.              */
+	wait_queue_head_t wait;       /*for poll                             */
+	unsigned long mode;           /*current switching mode               */
+	int minor;                    /*Minor number for tapdisk device      */
+	pid_t pid;                    /*tapdisk process id                   */
+	enum { RUNNING, CLEANSHUTDOWN } status; /*Detect a clean userspace 
+						  shutdown                   */
+	unsigned long *idx_map;       /*Record the user ring id to kern 
+					[req id, idx] tuple                  */
+	blkif_t *blkif;               /*Associate blkif with tapdev          */
+	int sysfs_set;                /*Set if it has a class device.        */
+} tap_blkif_t;
+
+/*Data struct handed back to userspace for tapdisk device to VBD mapping*/
+typedef struct domid_translate {
+	unsigned short domid;
+	unsigned short busid;
+} domid_translate_t ;
+
+static domid_translate_t  translate_domid[MAX_TAP_DEV];
+static tap_blkif_t *tapfds[MAX_TAP_DEV];
+
+static int __init set_blkif_reqs(char *str)
+{
+	get_option(&str, &blkif_reqs);
+	return 1;
+}
+__setup("blkif_reqs=", set_blkif_reqs);
+
+/* Run-time switchable: /sys/module/blktap/parameters/ */
+static unsigned int log_stats = 0;
+static unsigned int debug_lvl = 0;
+module_param(log_stats, int, 0644);
+module_param(debug_lvl, int, 0644);
+
+/*
+ * Each outstanding request that we've passed to the lower device layers has a 
+ * 'pending_req' allocated to it. Each buffer_head that completes decrements 
+ * the pendcnt towards zero. When it hits zero, the specified domain has a 
+ * response queued for it, with the saved 'id' passed back.
+ */
+typedef struct {
+	blkif_t       *blkif;
+	unsigned long  id;
+	unsigned short mem_idx;
+	int            nr_pages;
+	atomic_t       pendcnt;
+	unsigned short operation;
+	int            status;
+	struct list_head free_list;
+	int            inuse;
+} pending_req_t;
+
+static pending_req_t *pending_reqs[MAX_PENDING_REQS];
+static struct list_head pending_free;
+static DEFINE_SPINLOCK(pending_free_lock);
+static DECLARE_WAIT_QUEUE_HEAD (pending_free_wq);
+static int alloc_pending_reqs;
+
+typedef unsigned int PEND_RING_IDX;
+
+static inline int MASK_PEND_IDX(int i) { 
+	return (i & (MAX_PENDING_REQS-1));
+}
+
+static inline unsigned int RTN_PEND_IDX(pending_req_t *req, int idx) {
+	return (req - pending_reqs[idx]);
+}
+
+#define NR_PENDING_REQS (MAX_PENDING_REQS - pending_prod + pending_cons)
+
+#define BLKBACK_INVALID_HANDLE (~0)
+
+static struct page **foreign_pages[MAX_DYNAMIC_MEM];
+static inline unsigned long idx_to_kaddr(
+	unsigned int mmap_idx, unsigned int req_idx, unsigned int sg_idx)
+{
+	unsigned int arr_idx = req_idx*BLKIF_MAX_SEGMENTS_PER_REQUEST + sg_idx;
+	unsigned long pfn = page_to_pfn(foreign_pages[mmap_idx][arr_idx]);
+	return (unsigned long)pfn_to_kaddr(pfn);
+}
+
+static unsigned short mmap_alloc = 0;
+static unsigned short mmap_lock = 0;
+static unsigned short mmap_inuse = 0;
+
+/******************************************************************
+ * GRANT HANDLES
+ */
+
+/* When using grant tables to map a frame for device access then the
+ * handle returned must be used to unmap the frame. This is needed to
+ * drop the ref count on the frame.
+ */
+struct grant_handle_pair
+{
+        grant_handle_t kernel;
+        grant_handle_t user;
+};
+
+static struct grant_handle_pair 
+    pending_grant_handles[MAX_DYNAMIC_MEM][MMAP_PAGES];
+#define pending_handle(_id, _idx, _i) \
+    (pending_grant_handles[_id][((_idx) * BLKIF_MAX_SEGMENTS_PER_REQUEST) \
+    + (_i)])
+
+
+static int blktap_read_ufe_ring(tap_blkif_t *info); /*local prototypes*/
+
+#define BLKTAP_MINOR 0  /*/dev/xen/blktap has a dynamic major */
+#define BLKTAP_DEV_DIR  "/dev/xen"
+
+static int blktap_major;
+
+/* blktap IOCTLs: */
+#define BLKTAP_IOCTL_KICK_FE         1
+#define BLKTAP_IOCTL_KICK_BE         2 /* currently unused */
+#define BLKTAP_IOCTL_SETMODE         3
+#define BLKTAP_IOCTL_SENDPID	     4
+#define BLKTAP_IOCTL_NEWINTF	     5
+#define BLKTAP_IOCTL_MINOR	     6
+#define BLKTAP_IOCTL_MAJOR	     7
+#define BLKTAP_QUERY_ALLOC_REQS      8
+#define BLKTAP_IOCTL_FREEINTF        9
+#define BLKTAP_IOCTL_PRINT_IDXS      100  
+
+/* blktap switching modes: (Set with BLKTAP_IOCTL_SETMODE)             */
+#define BLKTAP_MODE_PASSTHROUGH      0x00000000  /* default            */
+#define BLKTAP_MODE_INTERCEPT_FE     0x00000001
+#define BLKTAP_MODE_INTERCEPT_BE     0x00000002  /* unimp.             */
+
+#define BLKTAP_MODE_INTERPOSE \
+           (BLKTAP_MODE_INTERCEPT_FE | BLKTAP_MODE_INTERCEPT_BE)
+
+
+static inline int BLKTAP_MODE_VALID(unsigned long arg)
+{
+	return ((arg == BLKTAP_MODE_PASSTHROUGH ) ||
+		(arg == BLKTAP_MODE_INTERCEPT_FE) ||
+                (arg == BLKTAP_MODE_INTERPOSE   ));
+}
+
+/* Requests passing through the tap to userspace are re-assigned an ID.
+ * We must record a mapping between the BE [IDX,ID] tuple and the userspace
+ * ring ID. 
+ */
+
+static inline unsigned long MAKE_ID(domid_t fe_dom, PEND_RING_IDX idx)
+{
+        return ((fe_dom << 16) | MASK_PEND_IDX(idx));
+}
+
+extern inline PEND_RING_IDX ID_TO_IDX(unsigned long id)
+{
+        return (PEND_RING_IDX)(id & 0x0000ffff);
+}
+
+extern inline int ID_TO_MIDX(unsigned long id)
+{
+        return (int)(id >> 16);
+}
+
+#define INVALID_REQ 0xdead0000
+
+/*TODO: Convert to a free list*/
+static inline int GET_NEXT_REQ(unsigned long *idx_map)
+{
+	int i;
+	for (i = 0; i < MAX_PENDING_REQS; i++)
+		if (idx_map[i] == INVALID_REQ)
+			return i;
+
+	return INVALID_REQ;
+}
+
+
+#define BLKTAP_INVALID_HANDLE(_g) \
+    (((_g->kernel) == 0xFFFF) && ((_g->user) == 0xFFFF))
+
+#define BLKTAP_INVALIDATE_HANDLE(_g) do {       \
+    (_g)->kernel = 0xFFFF; (_g)->user = 0xFFFF; \
+    } while(0)
+
+
+/******************************************************************
+ * BLKTAP VM OPS
+ */
+
+static struct page *blktap_nopage(struct vm_area_struct *vma,
+				  unsigned long address,
+				  int *type)
+{
+	/*
+	 * if the page has not been mapped in by the driver then return
+	 * NOPAGE_SIGBUS to the domain.
+	 */
+
+	return NOPAGE_SIGBUS;
+}
+
+struct vm_operations_struct blktap_vm_ops = {
+	nopage:   blktap_nopage,
+};
+
+/******************************************************************
+ * BLKTAP FILE OPS
+ */
+ 
+/*Function Declarations*/
+static int get_next_free_dev(void);
+static int blktap_open(struct inode *inode, struct file *filp);
+static int blktap_release(struct inode *inode, struct file *filp);
+static int blktap_mmap(struct file *filp, struct vm_area_struct *vma);
+static int blktap_ioctl(struct inode *inode, struct file *filp,
+                        unsigned int cmd, unsigned long arg);
+static unsigned int blktap_poll(struct file *file, poll_table *wait);
+
+static struct file_operations blktap_fops = {
+	.owner   = THIS_MODULE,
+	.poll    = blktap_poll,
+	.ioctl   = blktap_ioctl,
+	.open    = blktap_open,
+	.release = blktap_release,
+	.mmap    = blktap_mmap,
+};
+
+
+static int get_next_free_dev(void)
+{
+	tap_blkif_t *info;
+	int i = 0, ret = -1;
+	unsigned long flags;
+
+	spin_lock_irqsave(&pending_free_lock, flags);
+	
+	while (i < MAX_TAP_DEV) {
+		info = tapfds[i];
+		if ( (tapfds[i] != NULL) && (info->dev_inuse == 0)
+			&& (info->dev_pending == 0) ) {
+			info->dev_pending = 1;
+			ret = i;
+			goto done;
+		}
+		i++;
+	}
+	
+done:
+	spin_unlock_irqrestore(&pending_free_lock, flags);
+
+	/*
+	 * We are protected by having the dev_pending set.
+	 */
+	if (!tapfds[i]->sysfs_set && xen_class) {
+		class_device_create(xen_class, NULL,
+				    MKDEV(blktap_major, ret), NULL,
+				    "blktap%d", ret);
+		tapfds[i]->sysfs_set = 1;
+	}
+	return ret;
+}
+
+int dom_to_devid(domid_t domid, int xenbus_id, blkif_t *blkif) 
+{
+	int i;
+		
+	for (i = 0; i < MAX_TAP_DEV; i++)
+		if ( (translate_domid[i].domid == domid)
+		    && (translate_domid[i].busid == xenbus_id) ) {
+			tapfds[i]->blkif = blkif;
+			tapfds[i]->status = RUNNING;
+			return i;
+		}
+	return -1;
+}
+
+void signal_tapdisk(int idx) 
+{
+	tap_blkif_t *info;
+	struct task_struct *ptask;
+
+	info = tapfds[idx];
+	if ( (idx > 0) && (idx < MAX_TAP_DEV) && (info->pid > 0) ) {
+		ptask = find_task_by_pid(info->pid);
+		if (ptask)
+			info->status = CLEANSHUTDOWN;
+	}
+	info->blkif = NULL;
+	return;
+}
+
+static int blktap_open(struct inode *inode, struct file *filp)
+{
+	blkif_sring_t *sring;
+	int idx = iminor(inode) - BLKTAP_MINOR;
+	tap_blkif_t *info;
+	int i;
+	
+	if (tapfds[idx] == NULL) {
+		WPRINTK("Unable to open device /dev/xen/blktap%d\n",
+		       idx);
+		return -ENOMEM;
+	}
+	DPRINTK("Opening device /dev/xen/blktap%d\n",idx);
+	
+	info = tapfds[idx];
+	
+	/*Only one process can access device at a time*/
+	if (test_and_set_bit(0, &info->dev_inuse))
+		return -EBUSY;
+
+	info->dev_pending = 0;
+	    
+	/* Allocate the fe ring. */
+	sring = (blkif_sring_t *)get_zeroed_page(GFP_KERNEL);
+	if (sring == NULL)
+		goto fail_nomem;
+
+	SetPageReserved(virt_to_page(sring));
+    
+	SHARED_RING_INIT(sring);
+	FRONT_RING_INIT(&info->ufe_ring, sring, PAGE_SIZE);
+	
+	filp->private_data = info;
+	info->vma = NULL;
+
+	info->idx_map = kmalloc(sizeof(unsigned long) * MAX_PENDING_REQS, 
+				GFP_KERNEL);
+	
+	if (idx > 0) {
+		init_waitqueue_head(&info->wait);
+		for (i = 0; i < MAX_PENDING_REQS; i++) 
+			info->idx_map[i] = INVALID_REQ;
+	}
+
+	DPRINTK("Tap open: device /dev/xen/blktap%d\n",idx);
+	return 0;
+
+ fail_nomem:
+	return -ENOMEM;
+}
+
+static int blktap_release(struct inode *inode, struct file *filp)
+{
+	tap_blkif_t *info = filp->private_data;
+	
+	/* can this ever happen? - sdr */
+	if (!info) {
+		WPRINTK("Trying to free device that doesn't exist "
+		       "[/dev/xen/blktap%d]\n",iminor(inode) - BLKTAP_MINOR);
+		return -EBADF;
+	}
+	info->dev_inuse = 0;
+	DPRINTK("Freeing device [/dev/xen/blktap%d]\n",info->minor);
+
+	/* Free the ring page. */
+	ClearPageReserved(virt_to_page(info->ufe_ring.sring));
+	free_page((unsigned long) info->ufe_ring.sring);
+
+	/* Clear any active mappings and free foreign map table */
+	if (info->vma) {
+		zap_page_range(
+			info->vma, info->vma->vm_start, 
+			info->vma->vm_end - info->vma->vm_start, NULL);
+		info->vma = NULL;
+	}
+	
+	if ( (info->status != CLEANSHUTDOWN) && (info->blkif != NULL) ) {
+		kthread_stop(info->blkif->xenblkd);
+		info->blkif->xenblkd = NULL;
+		info->status = CLEANSHUTDOWN;
+	}	
+	return 0;
+}
+
+
+/* Note on mmap:
+ * We need to map pages to user space in a way that will allow the block
+ * subsystem set up direct IO to them.  This couldn't be done before, because
+ * there isn't really a sane way to translate a user virtual address down to a 
+ * physical address when the page belongs to another domain.
+ *
+ * My first approach was to map the page in to kernel memory, add an entry
+ * for it in the physical frame list (using alloc_lomem_region as in blkback)
+ * and then attempt to map that page up to user space.  This is disallowed
+ * by xen though, which realizes that we don't really own the machine frame
+ * underlying the physical page.
+ *
+ * The new approach is to provide explicit support for this in xen linux.
+ * The VMA now has a flag, VM_FOREIGN, to indicate that it contains pages
+ * mapped from other vms.  vma->vm_private_data is set up as a mapping 
+ * from pages to actual page structs.  There is a new clause in get_user_pages
+ * that does the right thing for this sort of mapping.
+ */
+static int blktap_mmap(struct file *filp, struct vm_area_struct *vma)
+{
+	int size;
+	struct page **map;
+	int i;
+	tap_blkif_t *info = filp->private_data;
+
+	if (info == NULL) {
+		WPRINTK("blktap: mmap, retrieving idx failed\n");
+		return -ENOMEM;
+	}
+	
+	vma->vm_flags |= VM_RESERVED;
+	vma->vm_ops = &blktap_vm_ops;
+
+	size = vma->vm_end - vma->vm_start;
+	if (size != ((mmap_pages + RING_PAGES) << PAGE_SHIFT)) {
+		WPRINTK("you _must_ map exactly %d pages!\n",
+		       mmap_pages + RING_PAGES);
+		return -EAGAIN;
+	}
+
+	size >>= PAGE_SHIFT;
+	info->rings_vstart = vma->vm_start;
+	info->user_vstart  = info->rings_vstart + (RING_PAGES << PAGE_SHIFT);
+    
+	/* Map the ring pages to the start of the region and reserve it. */
+	vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+
+	if (remap_pfn_range(vma, vma->vm_start, 
+			    __pa(info->ufe_ring.sring) >> PAGE_SHIFT, 
+			    PAGE_SIZE, vma->vm_page_prot)) {
+		WPRINTK("Mapping user ring failed!\n");
+		goto fail;
+	}
+
+	/* Mark this VM as containing foreign pages, and set up mappings. */
+	map = kzalloc(((vma->vm_end - vma->vm_start) >> PAGE_SHIFT)
+		      * sizeof(struct page_struct*),
+		      GFP_KERNEL);
+	if (map == NULL) {
+		WPRINTK("Couldn't alloc VM_FOREIGN map.\n");
+		goto fail;
+	}
+
+	for (i = 0; i < ((vma->vm_end - vma->vm_start) >> PAGE_SHIFT); i++)
+		map[i] = NULL;
+    
+	vma->vm_private_data = map;
+	vma->vm_flags |= VM_FOREIGN;
+
+	info->vma = vma;
+	info->ring_ok = 1;
+	return 0;
+ fail:
+	/* Clear any active mappings. */
+	zap_page_range(vma, vma->vm_start, 
+		       vma->vm_end - vma->vm_start, NULL);
+
+	return -ENOMEM;
+}
+
+
+static int blktap_ioctl(struct inode *inode, struct file *filp,
+                        unsigned int cmd, unsigned long arg)
+{
+	tap_blkif_t *info = filp->private_data;
+
+	switch(cmd) {
+	case BLKTAP_IOCTL_KICK_FE: 
+	{
+		/* There are fe messages to process. */
+		return blktap_read_ufe_ring(info);
+	}
+	case BLKTAP_IOCTL_SETMODE:
+	{
+		if (info) {
+			if (BLKTAP_MODE_VALID(arg)) {
+				info->mode = arg;
+				/* XXX: may need to flush rings here. */
+				DPRINTK("blktap: set mode to %lx\n", 
+				       arg);
+				return 0;
+			}
+		}
+		return 0;
+	}
+	case BLKTAP_IOCTL_PRINT_IDXS:
+        {
+		if (info) {
+			printk("User Rings: \n-----------\n");
+			printk("UF: rsp_cons: %2d, req_prod_prv: %2d "
+				"| req_prod: %2d, rsp_prod: %2d\n",
+				info->ufe_ring.rsp_cons,
+				info->ufe_ring.req_prod_pvt,
+				info->ufe_ring.sring->req_prod,
+				info->ufe_ring.sring->rsp_prod);
+		}
+            	return 0;
+        }
+	case BLKTAP_IOCTL_SENDPID:
+	{
+		if (info) {
+			info->pid = (pid_t)arg;
+			DPRINTK("blktap: pid received %d\n", 
+			       info->pid);
+		}
+		return 0;
+	}
+	case BLKTAP_IOCTL_NEWINTF:
+	{		
+		uint64_t val = (uint64_t)arg;
+		domid_translate_t *tr = (domid_translate_t *)&val;
+		int newdev;
+
+		DPRINTK("NEWINTF Req for domid %d and bus id %d\n", 
+		       tr->domid, tr->busid);
+		newdev = get_next_free_dev();
+		if (newdev < 1) {
+			WPRINTK("Error initialising /dev/xen/blktap - "
+				"No more devices\n");
+			return -1;
+		}
+		translate_domid[newdev].domid = tr->domid;
+		translate_domid[newdev].busid = tr->busid;
+		return newdev;
+	}
+	case BLKTAP_IOCTL_FREEINTF:
+	{
+		unsigned long dev = arg;
+		unsigned long flags;
+
+		/* Looking at another device */
+		info = NULL;
+
+		if ( (dev > 0) && (dev < MAX_TAP_DEV) )
+			info = tapfds[dev];
+
+		spin_lock_irqsave(&pending_free_lock, flags);
+		if ( (info != NULL) && (info->dev_pending) )
+			info->dev_pending = 0;
+		spin_unlock_irqrestore(&pending_free_lock, flags);
+
+		return 0;
+	}
+	case BLKTAP_IOCTL_MINOR:
+	{
+		unsigned long dev = arg;
+
+		/* Looking at another device */
+		info = NULL;
+		
+		if ( (dev > 0) && (dev < MAX_TAP_DEV) )
+			info = tapfds[dev];
+		
+		if (info != NULL)
+			return info->minor;
+		else
+			return -1;
+	}
+	case BLKTAP_IOCTL_MAJOR:
+		return blktap_major;
+
+	case BLKTAP_QUERY_ALLOC_REQS:
+	{
+		WPRINTK("BLKTAP_QUERY_ALLOC_REQS ioctl: %d/%d\n",
+		       alloc_pending_reqs, blkif_reqs);
+		return (alloc_pending_reqs/blkif_reqs) * 100;
+	}
+	}
+	return -ENOIOCTLCMD;
+}
+
+static unsigned int blktap_poll(struct file *filp, poll_table *wait)
+{
+	tap_blkif_t *info = filp->private_data;
+	
+	if (!info) {
+		WPRINTK(" poll, retrieving idx failed\n");
+		return 0;
+	}
+
+	/* do not work on the control device */
+	if (!info->minor)
+		return 0;
+
+	poll_wait(filp, &info->wait, wait);
+	if (info->ufe_ring.req_prod_pvt != info->ufe_ring.sring->req_prod) {
+		RING_PUSH_REQUESTS(&info->ufe_ring);
+		return POLLIN | POLLRDNORM;
+	}
+	return 0;
+}
+
+void blktap_kick_user(int idx)
+{
+	tap_blkif_t *info;
+
+	if (idx == 0)
+		return;
+	
+	info = tapfds[idx];
+	
+	if (info != NULL)
+		wake_up_interruptible(&info->wait);
+
+	return;
+}
+
+static int do_block_io_op(blkif_t *blkif);
+static void dispatch_rw_block_io(blkif_t *blkif,
+				 blkif_request_t *req,
+				 pending_req_t *pending_req);
+static void make_response(blkif_t *blkif, unsigned long id, 
+                          unsigned short op, int st);
+
+/******************************************************************
+ * misc small helpers
+ */
+static int req_increase(void)
+{
+	int i, j;
+
+	if (mmap_alloc >= MAX_PENDING_REQS || mmap_lock) 
+		return -EINVAL;
+
+	pending_reqs[mmap_alloc]  = kzalloc(sizeof(pending_req_t)
+					    * blkif_reqs, GFP_KERNEL);
+	foreign_pages[mmap_alloc] = alloc_empty_pages_and_pagevec(mmap_pages);
+
+	if (!pending_reqs[mmap_alloc] || !foreign_pages[mmap_alloc])
+		goto out_of_memory;
+
+	DPRINTK("%s: reqs=%d, pages=%d\n",
+		__FUNCTION__, blkif_reqs, mmap_pages);
+
+	for (i = 0; i < MAX_PENDING_REQS; i++) {
+		list_add_tail(&pending_reqs[mmap_alloc][i].free_list, 
+			      &pending_free);
+		pending_reqs[mmap_alloc][i].mem_idx = mmap_alloc;
+		for (j = 0; j < BLKIF_MAX_SEGMENTS_PER_REQUEST; j++)
+			BLKTAP_INVALIDATE_HANDLE(&pending_handle(mmap_alloc, 
+								 i, j));
+	}
+
+	mmap_alloc++;
+	DPRINTK("# MMAPs increased to %d\n",mmap_alloc);
+	return 0;
+
+ out_of_memory:
+	free_empty_pages_and_pagevec(foreign_pages[mmap_alloc], mmap_pages);
+	kfree(pending_reqs[mmap_alloc]);
+	WPRINTK("%s: out of memory\n", __FUNCTION__);
+	return -ENOMEM;
+}
+
+static void mmap_req_del(int mmap)
+{
+	BUG_ON(!spin_is_locked(&pending_free_lock));
+
+	kfree(pending_reqs[mmap]);
+	pending_reqs[mmap] = NULL;
+
+	free_empty_pages_and_pagevec(foreign_pages[mmap_alloc], mmap_pages);
+	foreign_pages[mmap] = NULL;
+
+	mmap_lock = 0;
+	DPRINTK("# MMAPs decreased to %d\n",mmap_alloc);
+	mmap_alloc--;
+}
+
+static pending_req_t* alloc_req(void)
+{
+	pending_req_t *req = NULL;
+	unsigned long flags;
+
+	spin_lock_irqsave(&pending_free_lock, flags);
+
+	if (!list_empty(&pending_free)) {
+		req = list_entry(pending_free.next, pending_req_t, free_list);
+		list_del(&req->free_list);
+	}
+
+	if (req) {
+		req->inuse = 1;
+		alloc_pending_reqs++;
+	}
+	spin_unlock_irqrestore(&pending_free_lock, flags);
+
+	return req;
+}
+
+static void free_req(pending_req_t *req)
+{
+	unsigned long flags;
+	int was_empty;
+
+	spin_lock_irqsave(&pending_free_lock, flags);
+
+	alloc_pending_reqs--;
+	req->inuse = 0;
+	if (mmap_lock && (req->mem_idx == mmap_alloc-1)) {
+		mmap_inuse--;
+		if (mmap_inuse == 0) mmap_req_del(mmap_alloc-1);
+		spin_unlock_irqrestore(&pending_free_lock, flags);
+		return;
+	}
+	was_empty = list_empty(&pending_free);
+	list_add(&req->free_list, &pending_free);
+
+	spin_unlock_irqrestore(&pending_free_lock, flags);
+
+	if (was_empty)
+		wake_up(&pending_free_wq);
+}
+
+static void fast_flush_area(pending_req_t *req, int k_idx, int u_idx, int 
+			    tapidx)
+{
+	struct gnttab_unmap_grant_ref unmap[BLKIF_MAX_SEGMENTS_PER_REQUEST*2];
+	unsigned int i, invcount = 0;
+	struct grant_handle_pair *khandle;
+	uint64_t ptep;
+	int ret, mmap_idx;
+	unsigned long kvaddr, uvaddr;
+
+	tap_blkif_t *info = tapfds[tapidx];
+	
+	if (info == NULL) {
+		WPRINTK("fast_flush: Couldn't get info!\n");
+		return;
+	}
+	mmap_idx = req->mem_idx;
+
+	for (i = 0; i < req->nr_pages; i++) {
+		kvaddr = idx_to_kaddr(mmap_idx, k_idx, i);
+		uvaddr = MMAP_VADDR(info->user_vstart, u_idx, i);
+
+		khandle = &pending_handle(mmap_idx, k_idx, i);
+		if (BLKTAP_INVALID_HANDLE(khandle)) {
+			WPRINTK("BLKTAP_INVALID_HANDLE\n");
+			continue;
+		}
+		gnttab_set_unmap_op(&unmap[invcount], 
+				    idx_to_kaddr(mmap_idx, k_idx, i), 
+				    GNTMAP_host_map, khandle->kernel);
+		invcount++;
+
+		if (create_lookup_pte_addr(
+		    info->vma->vm_mm,
+		    MMAP_VADDR(info->user_vstart, u_idx, i), 
+		    &ptep) !=0) {
+			WPRINTK("Couldn't get a pte addr!\n");
+			return;
+		}
+
+		gnttab_set_unmap_op(&unmap[invcount], 
+			ptep, GNTMAP_host_map,
+			khandle->user);
+		invcount++;
+            
+		BLKTAP_INVALIDATE_HANDLE(khandle);
+	}
+	ret = HYPERVISOR_grant_table_op(
+		GNTTABOP_unmap_grant_ref, unmap, invcount);
+	BUG_ON(ret);
+	
+	if (info->vma != NULL)
+		zap_page_range(info->vma, 
+			       MMAP_VADDR(info->user_vstart, u_idx, 0), 
+			       req->nr_pages << PAGE_SHIFT, NULL);
+}
+
+/******************************************************************
+ * SCHEDULER FUNCTIONS
+ */
+
+static void print_stats(blkif_t *blkif)
+{
+	printk(KERN_DEBUG "%s: oo %3d  |  rd %4d  |  wr %4d\n",
+	       current->comm, blkif->st_oo_req,
+	       blkif->st_rd_req, blkif->st_wr_req);
+	blkif->st_print = jiffies + msecs_to_jiffies(10 * 1000);
+	blkif->st_rd_req = 0;
+	blkif->st_wr_req = 0;
+	blkif->st_oo_req = 0;
+}
+
+int tap_blkif_schedule(void *arg)
+{
+	blkif_t *blkif = arg;
+
+	blkif_get(blkif);
+
+	if (debug_lvl)
+		printk(KERN_DEBUG "%s: started\n", current->comm);
+
+	while (!kthread_should_stop()) {
+		wait_event_interruptible(
+			blkif->wq,
+			blkif->waiting_reqs || kthread_should_stop());
+		wait_event_interruptible(
+			pending_free_wq,
+			!list_empty(&pending_free) || kthread_should_stop());
+
+		blkif->waiting_reqs = 0;
+		smp_mb(); /* clear flag *before* checking for work */
+
+		if (do_block_io_op(blkif))
+			blkif->waiting_reqs = 1;
+
+		if (log_stats && time_after(jiffies, blkif->st_print))
+			print_stats(blkif);
+	}
+
+	if (log_stats)
+		print_stats(blkif);
+	if (debug_lvl)
+		printk(KERN_DEBUG "%s: exiting\n", current->comm);
+
+	blkif->xenblkd = NULL;
+	blkif_put(blkif);
+
+	return 0;
+}
+
+/******************************************************************
+ * COMPLETION CALLBACK -- Called by user level ioctl()
+ */
+
+static int blktap_read_ufe_ring(tap_blkif_t *info)
+{
+	/* This is called to read responses from the UFE ring. */
+	RING_IDX i, j, rp;
+	blkif_response_t *resp;
+	blkif_t *blkif=NULL;
+	int pending_idx, usr_idx, mmap_idx;
+	pending_req_t *pending_req;
+	
+	if (!info)
+		return 0;
+
+	/* We currently only forward packets in INTERCEPT_FE mode. */
+	if (!(info->mode & BLKTAP_MODE_INTERCEPT_FE))
+		return 0;
+
+	/* for each outstanding message on the UFEring  */
+	rp = info->ufe_ring.sring->rsp_prod;
+	rmb();
+        
+	for (i = info->ufe_ring.rsp_cons; i != rp; i++) {
+		resp = RING_GET_RESPONSE(&info->ufe_ring, i);
+		++info->ufe_ring.rsp_cons;
+
+		/*retrieve [usr_idx] to [mmap_idx,pending_idx] mapping*/
+		usr_idx = (int)resp->id;
+		pending_idx = MASK_PEND_IDX(ID_TO_IDX(info->idx_map[usr_idx]));
+		mmap_idx = ID_TO_MIDX(info->idx_map[usr_idx]);
+
+		if ( (mmap_idx >= mmap_alloc) || 
+		   (ID_TO_IDX(info->idx_map[usr_idx]) >= MAX_PENDING_REQS) )
+			WPRINTK("Incorrect req map"
+			       "[%d], internal map [%d,%d (%d)]\n", 
+			       usr_idx, mmap_idx, 
+			       ID_TO_IDX(info->idx_map[usr_idx]),
+			       MASK_PEND_IDX(
+				       ID_TO_IDX(info->idx_map[usr_idx])));
+
+		pending_req = &pending_reqs[mmap_idx][pending_idx];
+		blkif = pending_req->blkif;
+
+		for (j = 0; j < pending_req->nr_pages; j++) {
+
+			unsigned long kvaddr, uvaddr;
+			struct page **map = info->vma->vm_private_data;
+			struct page *pg;
+			int offset;
+
+			uvaddr = MMAP_VADDR(info->user_vstart, usr_idx, j);
+			kvaddr = idx_to_kaddr(mmap_idx, pending_idx, j);
+
+			pg = pfn_to_page(__pa(kvaddr) >> PAGE_SHIFT);
+			ClearPageReserved(pg);
+			offset = (uvaddr - info->vma->vm_start) 
+				>> PAGE_SHIFT;
+			map[offset] = NULL;
+		}
+		fast_flush_area(pending_req, pending_idx, usr_idx, info->minor);
+		make_response(blkif, pending_req->id, resp->operation,
+			      resp->status);
+		info->idx_map[usr_idx] = INVALID_REQ;
+		blkif_put(pending_req->blkif);
+		free_req(pending_req);
+	}
+		
+	return 0;
+}
+
+
+/******************************************************************************
+ * NOTIFICATION FROM GUEST OS.
+ */
+
+static void blkif_notify_work(blkif_t *blkif)
+{
+	blkif->waiting_reqs = 1;
+	wake_up(&blkif->wq);
+}
+
+irqreturn_t tap_blkif_be_int(int irq, void *dev_id, struct pt_regs *regs)
+{
+	blkif_notify_work(dev_id);
+	return IRQ_HANDLED;
+}
+
+
+
+/******************************************************************
+ * DOWNWARD CALLS -- These interface with the block-device layer proper.
+ */
+static int print_dbug = 1;
+static int do_block_io_op(blkif_t *blkif)
+{
+	blkif_back_ring_t *blk_ring = &blkif->blk_ring;
+	blkif_request_t *req;
+	pending_req_t *pending_req;
+	RING_IDX rc, rp;
+	int more_to_do = 0;
+	tap_blkif_t *info;
+
+	rc = blk_ring->req_cons;
+	rp = blk_ring->sring->req_prod;
+	rmb(); /* Ensure we see queued requests up to 'rp'. */
+
+	/*Check blkif has corresponding UE ring*/
+	if (blkif->dev_num == -1) {
+		/*oops*/
+		if (print_dbug) {
+			WPRINTK("Corresponding UE " 
+			       "ring does not exist!\n");
+			print_dbug = 0; /*We only print this message once*/
+		}
+		return 0;
+	}
+
+	info = tapfds[blkif->dev_num];
+	if (info == NULL || !info->dev_inuse) {
+		if (print_dbug) {
+			WPRINTK("Can't get UE info!\n");
+			print_dbug = 0;
+		}
+		return 0;
+	}
+
+	while (rc != rp) {
+		
+		if (RING_FULL(&info->ufe_ring)) {
+			WPRINTK("RING_FULL! More to do\n");
+			more_to_do = 1;
+			break;
+		}
+		
+		if (RING_REQUEST_CONS_OVERFLOW(blk_ring, rc)) {
+			WPRINTK("RING_REQUEST_CONS_OVERFLOW!"
+			       " More to do\n");
+			more_to_do = 1;
+			break;		
+		}
+
+		pending_req = alloc_req();
+		if (NULL == pending_req) {
+			blkif->st_oo_req++;
+			more_to_do = 1;
+			break;
+		}
+
+		req = RING_GET_REQUEST(blk_ring, rc);
+		blk_ring->req_cons = ++rc; /* before make_response() */	
+
+		switch (req->operation) {
+		case BLKIF_OP_READ:
+			blkif->st_rd_req++;
+			dispatch_rw_block_io(blkif, req, pending_req);
+			break;
+
+		case BLKIF_OP_WRITE:
+			blkif->st_wr_req++;
+			dispatch_rw_block_io(blkif, req, pending_req);
+			break;
+
+		default:
+			WPRINTK("unknown operation [%d]\n",
+				req->operation);
+			make_response(blkif, req->id, req->operation,
+				      BLKIF_RSP_ERROR);
+			free_req(pending_req);
+			break;
+		}
+	}
+		
+	blktap_kick_user(blkif->dev_num);
+
+	return more_to_do;
+}
+
+static void dispatch_rw_block_io(blkif_t *blkif,
+				 blkif_request_t *req,
+				 pending_req_t *pending_req)
+{
+	extern void ll_rw_block(int rw, int nr, struct buffer_head * bhs[]);
+	int op, operation = (req->operation == BLKIF_OP_WRITE) ? WRITE : READ;
+	struct gnttab_map_grant_ref map[BLKIF_MAX_SEGMENTS_PER_REQUEST*2];
+	unsigned int nseg;
+	int ret, i;
+	tap_blkif_t *info = tapfds[blkif->dev_num];
+	uint64_t sector;
+	
+	blkif_request_t *target;
+	int pending_idx = RTN_PEND_IDX(pending_req,pending_req->mem_idx);
+	int usr_idx = GET_NEXT_REQ(info->idx_map);
+	uint16_t mmap_idx = pending_req->mem_idx;
+
+	/*Check we have space on user ring - should never fail*/
+	if(usr_idx == INVALID_REQ) goto fail_flush;
+	
+	/* Check that number of segments is sane. */
+	nseg = req->nr_segments;
+	if ( unlikely(nseg == 0) || 
+	    unlikely(nseg > BLKIF_MAX_SEGMENTS_PER_REQUEST) ) {
+		WPRINTK("Bad number of segments in request (%d)\n", nseg);
+		goto fail_response;
+	}
+	
+	/* Make sure userspace is ready. */
+	if (!info->ring_ok) {
+		WPRINTK("blktap: ring not ready for requests!\n");
+		goto fail_response;
+	}
+
+	if (RING_FULL(&info->ufe_ring)) {
+		WPRINTK("blktap: fe_ring is full, can't add "
+			"IO Request will be dropped. %d %d\n",
+			RING_SIZE(&info->ufe_ring),
+			RING_SIZE(&blkif->blk_ring));
+		goto fail_response;
+	}
+
+	pending_req->blkif     = blkif;
+	pending_req->id        = req->id;
+	pending_req->operation = operation;
+	pending_req->status    = BLKIF_RSP_OKAY;
+	pending_req->nr_pages  = nseg;
+	op = 0;
+	for (i = 0; i < nseg; i++) {
+		unsigned long uvaddr;
+		unsigned long kvaddr;
+		uint64_t ptep;
+		struct page *page;
+		uint32_t flags;
+
+		uvaddr = MMAP_VADDR(info->user_vstart, usr_idx, i);
+		kvaddr = idx_to_kaddr(mmap_idx, pending_idx, i);
+		page = virt_to_page(kvaddr);
+
+		sector = req->sector_number + (8*i);
+		if( (blkif->sectors > 0) && (sector >= blkif->sectors) ) {
+			WPRINTK("BLKTAP: Sector request greater" 
+			       "than size\n");
+			WPRINTK("BLKTAP: %s request sector" 
+			       "[%llu,%llu], Total [%llu]\n",
+			       (req->operation == 
+				BLKIF_OP_WRITE ? "WRITE" : "READ"),
+				(long long unsigned) sector,
+				(long long unsigned) sector>>9,
+				blkif->sectors);
+		}
+
+		flags = GNTMAP_host_map;
+		if (operation == WRITE)
+			flags |= GNTMAP_readonly;
+		gnttab_set_map_op(&map[op], kvaddr, flags,
+				  req->seg[i].gref, blkif->domid);
+		op++;
+
+		/* Now map it to user. */
+		ret = create_lookup_pte_addr(info->vma->vm_mm, 
+					     uvaddr, &ptep);
+		if (ret) {
+			WPRINTK("Couldn't get a pte addr!\n");
+			fast_flush_area(pending_req, pending_idx, usr_idx, 
+					blkif->dev_num);
+			goto fail_flush;
+		}
+
+		flags = GNTMAP_host_map | GNTMAP_application_map
+			| GNTMAP_contains_pte;
+		if (operation == WRITE)
+			flags |= GNTMAP_readonly;
+		gnttab_set_map_op(&map[op], ptep, flags,
+				  req->seg[i].gref, blkif->domid);
+		op++;
+	}
+
+	ret = HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, map, op);
+	BUG_ON(ret);
+
+	for (i = 0; i < (nseg*2); i+=2) {
+		unsigned long uvaddr;
+		unsigned long kvaddr;
+		unsigned long offset;
+		struct page *pg;
+
+		uvaddr = MMAP_VADDR(info->user_vstart, usr_idx, i/2);
+		kvaddr = idx_to_kaddr(mmap_idx, pending_idx, i/2);
+
+		if (unlikely(map[i].status != 0)) {
+			WPRINTK("invalid kernel buffer -- "
+				"could not remap it\n");
+			goto fail_flush;
+		}
+
+		if (unlikely(map[i+1].status != 0)) {
+			WPRINTK("invalid user buffer -- "
+				"could not remap it\n");
+			goto fail_flush;
+		}
+
+		pending_handle(mmap_idx, pending_idx, i/2).kernel 
+			= map[i].handle;
+		pending_handle(mmap_idx, pending_idx, i/2).user   
+			= map[i+1].handle;
+		set_phys_to_machine(__pa(kvaddr) >> PAGE_SHIFT,
+			FOREIGN_FRAME(map[i].dev_bus_addr >> PAGE_SHIFT));
+		offset = (uvaddr - info->vma->vm_start) >> PAGE_SHIFT;
+		pg = pfn_to_page(__pa(kvaddr) >> PAGE_SHIFT);
+		((struct page **)info->vma->vm_private_data)[offset] =
+			pg;
+	}
+	/* Mark mapped pages as reserved: */
+	for (i = 0; i < req->nr_segments; i++) {
+		unsigned long kvaddr;
+		struct page *pg;
+
+		kvaddr = idx_to_kaddr(mmap_idx, pending_idx, i);
+		pg = pfn_to_page(__pa(kvaddr) >> PAGE_SHIFT);
+		SetPageReserved(pg);
+	}
+	
+	/*record [mmap_idx,pending_idx] to [usr_idx] mapping*/
+	info->idx_map[usr_idx] = MAKE_ID(mmap_idx, pending_idx);
+
+	blkif_get(blkif);
+	/* Finally, write the request message to the user ring. */
+	target = RING_GET_REQUEST(&info->ufe_ring,
+				  info->ufe_ring.req_prod_pvt);
+	memcpy(target, req, sizeof(*req));
+	target->id = usr_idx;
+	info->ufe_ring.req_prod_pvt++;
+	return;
+
+ fail_flush:
+	WPRINTK("Reached Fail_flush\n");
+	fast_flush_area(pending_req, pending_idx, usr_idx, blkif->dev_num);
+ fail_response:
+	make_response(blkif, req->id, req->operation, BLKIF_RSP_ERROR);
+	free_req(pending_req);
+} 
+
+
+
+/******************************************************************
+ * MISCELLANEOUS SETUP / TEARDOWN / DEBUGGING
+ */
+
+
+static void make_response(blkif_t *blkif, unsigned long id, 
+                          unsigned short op, int st)
+{
+	blkif_response_t *resp;
+	unsigned long     flags;
+	blkif_back_ring_t *blk_ring = &blkif->blk_ring;
+	int more_to_do = 0;
+	int notify;
+
+	spin_lock_irqsave(&blkif->blk_ring_lock, flags);
+	/* Place on the response ring for the relevant domain. */ 
+	resp = RING_GET_RESPONSE(blk_ring, blk_ring->rsp_prod_pvt);
+	resp->id        = id;
+	resp->operation = op;
+	resp->status    = st;
+	blk_ring->rsp_prod_pvt++;
+	RING_PUSH_RESPONSES_AND_CHECK_NOTIFY(blk_ring, notify);
+
+	if (blk_ring->rsp_prod_pvt == blk_ring->req_cons) {
+		/*
+		 * Tail check for pending requests. Allows frontend to avoid
+		 * notifications if requests are already in flight (lower
+		 * overheads and promotes batching).
+		 */
+		RING_FINAL_CHECK_FOR_REQUESTS(blk_ring, more_to_do);
+	} else if (RING_HAS_UNCONSUMED_REQUESTS(blk_ring)) {
+		more_to_do = 1;
+
+	}	
+	spin_unlock_irqrestore(&blkif->blk_ring_lock, flags);
+	if (more_to_do)
+		blkif_notify_work(blkif);
+	if (notify)
+		notify_remote_via_irq(blkif->irq);
+}
+
+static int __init blkif_init(void)
+{
+	int i, ret;
+	tap_blkif_t *info;
+
+	if (!is_running_on_xen())
+		return -ENODEV;
+
+	INIT_LIST_HEAD(&pending_free);
+        for(i = 0; i < 2; i++) {
+		ret = req_increase();
+		if (ret)
+			break;
+	}
+	if (i == 0)
+		return ret;
+
+	tap_blkif_interface_init();
+
+	alloc_pending_reqs = 0;
+
+	tap_blkif_xenbus_init();
+
+	/*Create the blktap devices, but do not map memory or waitqueue*/
+	for(i = 0; i < MAX_TAP_DEV; i++) translate_domid[i].domid = 0xFFFF;
+
+	/* Dynamically allocate a major for this device */
+	ret = register_chrdev(0, "blktap", &blktap_fops);
+
+	if ( (ret < 0) ) {
+		WPRINTK("Couldn't register /dev/xen/blktap\n");
+		return -ENOMEM;
+	}	
+	
+	blktap_major = ret;
+
+	for(i = 0; i < MAX_TAP_DEV; i++ ) {
+		info = tapfds[i] = kzalloc(sizeof(tap_blkif_t),GFP_KERNEL);
+		if(tapfds[i] == NULL)
+			return -ENOMEM;
+		info->minor = i;
+		info->pid = 0;
+		info->blkif = NULL;
+
+		info->dev_pending = info->dev_inuse = 0;
+
+		DPRINTK("Created misc_dev [/dev/xen/blktap%d]\n",i);
+	}
+	
+	/* Make sure the xen class exists */
+	if (!setup_xen_class()) {
+		/*
+		 * This will allow udev to create the blktap ctrl device.
+		 * We only want to create blktap0 first.  We don't want
+		 * to flood the sysfs system with needless blktap devices.
+		 * We only create the device when a request of a new device is
+		 * made.
+		 */
+		class_device_create(xen_class, NULL,
+				    MKDEV(blktap_major, 0), NULL,
+				    "blktap0");
+		tapfds[0]->sysfs_set = 1;
+	} else {
+		/* this is bad, but not fatal */
+		WPRINTK("blktap: sysfs xen_class not created\n");
+	}
+
+	DPRINTK("Blktap device successfully created\n");
+
+	return 0;
+}
+
+module_init(blkif_init);
+
+MODULE_LICENSE("Dual BSD/GPL");
diff --git a/drivers/xen/xenfb/Makefile b/drivers/xen/xenfb/Makefile
new file mode 100644
index 000000000..de96da7a9
--- /dev/null
+++ b/drivers/xen/xenfb/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_XEN_FRAMEBUFFER)	:= xenfb.o
diff --git a/drivers/xen/xenfb/xenfb.c b/drivers/xen/xenfb/xenfb.c
new file mode 100644
index 000000000..481aef672
--- /dev/null
+++ b/drivers/xen/xenfb/xenfb.c
@@ -0,0 +1,571 @@
+/*
+ * linux/drivers/video/xenfb.c -- Xen para-virtual frame buffer device
+ *
+ * Copyright (C) 2005-2006
+ *
+ *      Anthony Liguori <aliguori@us.ibm.com>
+ *
+ *  Based on linux/drivers/video/q40fb.c
+ *
+ *  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.
+ */
+
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/fb.h>
+#include <linux/module.h>
+#include <linux/vmalloc.h>
+#include <linux/mm.h>
+#include <asm/hypervisor.h>
+#include <xen/evtchn.h>
+#include <xen/xenbus.h>
+#include <linux/xenfb.h>
+#include <linux/kthread.h>
+
+#define XENFB_WIDTH 800
+#define XENFB_HEIGHT 600
+#define XENFB_DEPTH 32
+
+static int xenfb_fps = 20;
+static unsigned long xenfb_mem_len = XENFB_WIDTH * XENFB_HEIGHT * XENFB_DEPTH / 8;
+
+struct xenfb_mapping
+{
+	struct list_head	next;
+	struct vm_area_struct	*vma;
+	atomic_t		map_refs;
+	int			faults;
+	struct xenfb_info	*info;
+};
+
+struct xenfb_info
+{
+	struct task_struct		*kthread;
+	wait_queue_head_t		wq;
+
+	unsigned char			*fb;
+	struct fb_fix_screeninfo	*fix;
+	struct fb_var_screeninfo	*var;
+	struct fb_info			*fb_info;
+	struct timer_list		refresh;
+	int				dirty;
+	int				y1, y2;
+	int				x1, x2;
+
+	struct semaphore		mm_lock;
+	int				nr_pages;
+	struct page			**pages;
+	struct list_head		mappings;
+
+	unsigned			evtchn;
+	int				irq;
+	struct xenfb_page		*page;
+	unsigned long 			*mfns;
+	u32				flags;
+};
+
+static void xenfb_do_update(struct xenfb_info *info,
+			    int x, int y, int w, int h)
+{
+	union xenfb_out_event event;
+	__u32 prod;
+
+	event.type = XENFB_TYPE_UPDATE;
+	event.update.x = x;
+	event.update.y = y;
+	event.update.width = w;
+	event.update.height = h;
+
+	prod = info->page->out_prod;
+	if (prod - info->page->out_cons == XENFB_OUT_RING_LEN)
+		return;		/* ring buffer full, event lost */
+	mb();			/* ensure ring space available */
+	XENFB_OUT_RING_REF(info->page, prod) = event;
+	wmb();			/* ensure ring contents visible */
+	info->page->out_prod = prod + 1;
+
+	notify_remote_via_evtchn(info->evtchn);
+}
+
+static int xenfb_queue_full(struct xenfb_info *info)
+{
+	__u32 cons, prod;
+
+	prod = info->page->out_prod;
+	cons = info->page->out_cons;
+	return prod - cons == XENFB_OUT_RING_LEN;
+}
+
+static void xenfb_update_screen(struct xenfb_info *info)
+{
+	int y1, y2, x1, x2;
+	struct list_head *item;
+	struct xenfb_mapping *map;
+
+	if (!(info->flags & XENFB_FLAG_UPDATE))
+		return;
+	if (xenfb_queue_full(info))
+		return;
+
+	y1 = info->y1;
+	y2 = info->y2;
+	x1 = info->x1;
+	x2 = info->x2;
+	info->y1 = info->y2 = info->x1 = info->x2 = 0;
+	down(&info->mm_lock);
+	list_for_each(item, &info->mappings) {
+		map = list_entry(item, struct xenfb_mapping, next);
+		if (!map->faults)
+			continue;
+		zap_page_range(map->vma, map->vma->vm_start,
+			       map->vma->vm_end - map->vma->vm_start, NULL);
+		map->faults = 0;
+	}
+	up(&info->mm_lock);
+
+	xenfb_do_update(info, x1, y1, x2 - x1, y2 - y1);
+}
+
+static int xenfb_thread(void *data)
+{
+	struct xenfb_info *info = data;
+
+	for (;;) {
+		if (kthread_should_stop())
+			break;
+		if (info->dirty) {
+			info->dirty = 0;
+			xenfb_update_screen(info);
+		}
+		wait_event_interruptible(info->wq,
+			kthread_should_stop() || info->dirty);
+	}
+	return 0;
+}
+
+static int xenfb_setcolreg(unsigned regno, unsigned red, unsigned green,
+			   unsigned blue, unsigned transp,
+			   struct fb_info *info)
+{
+	u32 v;
+
+	if (regno > info->cmap.len)
+		return 1;
+
+	red   >>= (16 - info->var.red.length);
+	green >>= (16 - info->var.green.length);
+	blue  >>= (16 - info->var.blue.length);
+
+	v = (red << info->var.red.offset) |
+	    (green << info->var.green.offset) |
+	    (blue << info->var.blue.offset);
+
+	switch (info->var.bits_per_pixel) {
+	case 16:
+	case 24:
+	case 32:
+		((u32 *)info->pseudo_palette)[regno] = v;
+		break;
+	}
+	
+	return 0;
+}
+
+static void xenfb_timer(unsigned long data)
+{
+	struct xenfb_info *info = (struct xenfb_info *)data;
+	info->dirty = 1;
+	wake_up(&info->wq);
+}
+
+static void xenfb_refresh(struct xenfb_info *info,
+			  int x1, int y1, int w, int h)
+{
+	int y2, x2;
+
+	y2 = y1 + h;
+	x2 = x1 + w;
+	if (info->y2 == 0) {
+		info->y1 = y1;
+		info->y2 = y2;
+	}
+	if (info->x2 == 0) {
+		info->x1 = x1;
+		info->x2 = x2;
+	}
+
+	if (info->y1 > y1)
+		info->y1 = y1;
+	if (info->y2 < y2)
+		info->y2 = y2;
+	if (info->x1 > x1)
+		info->x1 = x1;
+	if (info->x2 < x2)
+		info->x2 = x2;
+
+	if (timer_pending(&info->refresh))
+		return;
+
+	mod_timer(&info->refresh, jiffies + HZ/xenfb_fps);
+}
+
+static void xenfb_fillrect(struct fb_info *p, const struct fb_fillrect *rect)
+{
+	struct xenfb_info *info = p->par;
+
+	cfb_fillrect(p, rect);
+	xenfb_refresh(info, rect->dx, rect->dy, rect->width, rect->height);
+}
+
+static void xenfb_imageblit(struct fb_info *p, const struct fb_image *image)
+{
+	struct xenfb_info *info = p->par;
+
+	cfb_imageblit(p, image);
+	xenfb_refresh(info, image->dx, image->dy, image->width, image->height);
+}
+
+static void xenfb_copyarea(struct fb_info *p, const struct fb_copyarea *area)
+{
+	struct xenfb_info *info = p->par;
+
+	cfb_copyarea(p, area);
+	xenfb_refresh(info, area->dx, area->dy, area->width, area->height);
+}
+
+static void xenfb_vm_open(struct vm_area_struct *vma)
+{
+	struct xenfb_mapping *map = vma->vm_private_data;
+	atomic_inc(&map->map_refs);
+}
+
+static void xenfb_vm_close(struct vm_area_struct *vma)
+{
+	struct xenfb_mapping *map = vma->vm_private_data;
+	struct xenfb_info *info = map->info;
+
+	down(&info->mm_lock);
+	if (atomic_dec_and_test(&map->map_refs)) {
+		list_del(&map->next);
+		kfree(map);
+	}
+	up(&info->mm_lock);
+}
+
+static struct page *xenfb_vm_nopage(struct vm_area_struct *vma,
+				    unsigned long vaddr, int *type)
+{
+	struct xenfb_mapping *map = vma->vm_private_data;
+	struct xenfb_info *info = map->info;
+	int pgnr = (vaddr - vma->vm_start) >> PAGE_SHIFT;
+	struct page *page;
+	int y1, y2;
+
+	if (pgnr >= info->nr_pages)
+		return NOPAGE_SIGBUS;
+
+	down(&info->mm_lock);
+	page = info->pages[pgnr];
+	get_page(page);
+	map->faults++;
+
+	y1 = pgnr * PAGE_SIZE / info->fix->line_length;
+	y2 = (pgnr * PAGE_SIZE + PAGE_SIZE - 1) / info->fix->line_length;
+	if (y2 > info->var->yres)
+		y2 = info->var->yres;
+	xenfb_refresh(info, 0, y1, info->var->xres, y2 - y1);
+	up(&info->mm_lock);
+
+	if (type)
+		*type = VM_FAULT_MINOR;
+
+	return page;
+}
+
+static struct vm_operations_struct xenfb_vm_ops = {
+	.open	= xenfb_vm_open,
+	.close	= xenfb_vm_close,
+	.nopage	= xenfb_vm_nopage,
+};
+
+static int xenfb_mmap(struct fb_info *fb_info, struct vm_area_struct *vma)
+{
+	struct xenfb_info *info = fb_info->par;
+	struct xenfb_mapping *map;
+	int ret;
+	int map_pages;
+
+	down(&info->mm_lock);
+
+	ret = -EINVAL;
+	if (!(vma->vm_flags & VM_WRITE))
+		goto out;
+	if (!(vma->vm_flags & VM_SHARED))
+		goto out;
+	if (vma->vm_pgoff != 0)
+		goto out;
+
+	map_pages = (vma->vm_end - vma->vm_start + PAGE_SIZE-1) >> PAGE_SHIFT;
+	if (map_pages > info->nr_pages)
+		goto out;
+
+	ret = -ENOMEM;
+	map = kmalloc(sizeof(*map), GFP_KERNEL);
+	if (map == NULL)
+		goto out;
+	memset(map, 0, sizeof(*map));
+
+	map->vma = vma;
+	map->faults = 0;
+	map->info = info;
+	atomic_set(&map->map_refs, 1);
+	list_add(&map->next, &info->mappings);
+	vma->vm_ops = &xenfb_vm_ops;
+	vma->vm_flags |= (VM_DONTEXPAND | VM_RESERVED);
+	vma->vm_private_data = map;
+	ret = 0;
+
+ out:
+	up(&info->mm_lock);
+	return ret;
+}
+
+static struct fb_ops xenfb_fb_ops = {
+	.owner		= THIS_MODULE,
+	.fb_setcolreg	= xenfb_setcolreg,
+	.fb_fillrect	= xenfb_fillrect,
+	.fb_copyarea	= xenfb_copyarea,
+	.fb_imageblit	= xenfb_imageblit,
+	.fb_mmap	= xenfb_mmap,
+};
+
+static irqreturn_t xenfb_event_handler(int rq, void *dev_id,
+				       struct pt_regs *regs)
+{
+	struct xenfb_info *info = dev_id;
+	__u32 cons, prod;
+
+	prod = info->page->in_prod;
+	rmb();			/* ensure we see ring contents up to prod */
+	for (cons = info->page->in_cons; cons != prod; cons++) {
+		union xenfb_in_event *event;
+		event = &XENFB_IN_RING_REF(info->page, cons);
+
+		switch (event->type) {
+		case XENFB_TYPE_SET_EVENTS:
+			info->flags = event->set_events.flags;
+			break;
+		}
+	}
+	mb();			/* ensure we're done with ring contents */
+	info->page->in_cons = cons;
+	notify_remote_via_evtchn(info->evtchn);
+
+	return IRQ_HANDLED;
+}
+
+static unsigned long vmalloc_to_mfn(void *address)
+{
+	return pfn_to_mfn(vmalloc_to_pfn(address));
+	//return arbitrary_virt_to_machine(address) >> PAGE_SHIFT;
+}
+
+static struct xenfb_info *xenfb_info;
+
+static int __init xenfb_probe(void)
+{
+	struct xenfb_info *info;
+	int i, ret;
+	struct fb_info *fb_info;
+	struct evtchn_alloc_unbound alloc_unbound;
+	struct evtchn_close close;
+	struct xenbus_transaction xbt;
+
+        /* Nothing to do if running in dom0. */
+        if (is_initial_xendomain())
+		return -ENODEV;
+#if 1
+        /* if we're not set up to use graphics mode, then don't initialize */
+	if (xenbus_scanf(XBT_NIL, "console", "use_graphics", "%d", &ret) < 0)
+		return -ENODEV;
+	if (ret == 0)
+		return -ENODEV;
+#endif
+
+	info = kmalloc(sizeof(*info), GFP_KERNEL);
+	if (info == NULL)
+		return -ENOMEM;
+	memset(info, 0, sizeof(*info));
+
+	INIT_LIST_HEAD(&info->mappings);
+
+	info->fb = vmalloc(xenfb_mem_len);
+	if (info->fb == NULL)
+		goto error;
+	memset(info->fb, 0, xenfb_mem_len);
+	info->nr_pages = (xenfb_mem_len + PAGE_SIZE - 1) >> PAGE_SHIFT;
+	info->pages = kmalloc(sizeof(struct page*)*info->nr_pages, GFP_KERNEL);
+	if (info->pages == NULL)
+		goto error_vfree;
+	for (i = 0; i < info->nr_pages; i++)
+		info->pages[i] = vmalloc_to_page(info->fb + i * PAGE_SIZE);
+
+	fb_info = framebuffer_alloc(sizeof(u32) * 256, NULL);
+	// FIXME sizeof(struct xenfb_info)
+	if (fb_info == NULL)
+		goto error_kfree;
+
+	info->mfns = vmalloc(sizeof(unsigned long) * info->nr_pages);
+	/* set up shared page */
+	info->page = (void *)__get_free_page(GFP_KERNEL);
+	if (!info->page)
+		goto error_kfree;
+	/* set up event channel */
+	alloc_unbound.dom = DOMID_SELF;
+	alloc_unbound.remote_dom = 0;
+	ret = HYPERVISOR_event_channel_op(EVTCHNOP_alloc_unbound,
+					  &alloc_unbound);
+	if (ret)
+		goto error_freep;
+	info->evtchn = alloc_unbound.port;
+
+	for (i = 0; i < info->nr_pages; i++)
+		info->mfns[i] = vmalloc_to_mfn(info->fb + i * PAGE_SIZE);
+	info->page->pd[0] = vmalloc_to_mfn(info->mfns);
+	info->page->pd[1] = 0;
+	info->page->width = XENFB_WIDTH;
+	info->page->height = XENFB_HEIGHT;
+	info->page->depth = XENFB_DEPTH;
+	info->page->line_length = (info->page->depth / 8) * info->page->width;
+	info->page->mem_length = xenfb_mem_len;
+	info->page->in_cons = info->page->in_prod = 0;
+	info->page->out_cons = info->page->out_prod = 0;
+
+	ret = bind_evtchn_to_irqhandler(info->evtchn, xenfb_event_handler,
+					0, "xenfb", info);
+	if (ret < 0) {
+		close.port = info->evtchn;
+		HYPERVISOR_event_channel_op(EVTCHNOP_close, &close);
+		goto error_freep;
+	}
+
+	info->irq = ret;
+	xenfb_info = info;
+
+	fb_info->pseudo_palette = fb_info->par;
+	fb_info->par = info;
+	fb_info->screen_base = info->fb;
+
+	memset(&fb_info->var, 0, sizeof(fb_info->var));
+	memset(&fb_info->fix, 0, sizeof(fb_info->fix));
+
+	fb_info->fbops = &xenfb_fb_ops;
+	fb_info->var.xres_virtual = fb_info->var.xres = info->page->width;
+	fb_info->var.yres_virtual = fb_info->var.yres = info->page->height;
+	fb_info->var.bits_per_pixel = info->page->depth;
+
+	fb_info->var.red = (struct fb_bitfield){16, 8, 0};
+	fb_info->var.green = (struct fb_bitfield){8, 8, 0};
+	fb_info->var.blue = (struct fb_bitfield){0, 8, 0};
+
+	fb_info->var.activate = FB_ACTIVATE_NOW;
+	fb_info->var.height = -1;
+	fb_info->var.width = -1;
+	fb_info->var.vmode = FB_VMODE_NONINTERLACED;
+
+	fb_info->fix.visual = FB_VISUAL_TRUECOLOR;
+	fb_info->fix.line_length = info->page->line_length;
+	fb_info->fix.smem_start = 0;
+	fb_info->fix.smem_len = xenfb_mem_len;
+	strcpy(fb_info->fix.id, "xen");
+	fb_info->fix.type = FB_TYPE_PACKED_PIXELS;
+	fb_info->fix.accel = FB_ACCEL_NONE;
+
+	fb_info->flags = FBINFO_FLAG_DEFAULT;
+
+	fb_alloc_cmap(&fb_info->cmap, 256, 0);
+
+	info->fb_info = fb_info;
+	info->fix = &fb_info->fix;
+	info->var = &fb_info->var;
+
+	init_MUTEX(&info->mm_lock);
+	init_waitqueue_head(&info->wq);
+	init_timer(&info->refresh);
+	info->refresh.function = xenfb_timer;
+	info->refresh.data = (unsigned long)info;
+
+	info->kthread = kthread_run(xenfb_thread, info, "xenfb thread");
+	if (IS_ERR(info->kthread))
+		goto error_unbind;
+
+	ret = register_framebuffer(fb_info);
+	if (ret)
+		goto error_unbind;
+
+ again:
+	ret = xenbus_transaction_start(&xbt);
+	if (ret)
+		goto error_unreg;
+	ret = xenbus_printf(xbt, "vfb", "page-ref", "%lu",
+			    virt_to_mfn(info->page));
+	// FIXME grant tables?
+	if (ret)
+		goto error_xenbus;
+	ret = xenbus_printf(xbt, "vfb", "event-channel", "%u",
+			    info->evtchn);
+	if (ret)
+		goto error_xenbus;
+	ret = xenbus_transaction_end(xbt, 0);
+	if (ret) {
+		if (ret == -EAGAIN)
+			goto again;
+		goto error_unreg;
+	}
+
+	return 0;
+
+ error_xenbus:
+	xenbus_transaction_end(xbt, 1);
+ error_unreg:
+	unregister_framebuffer(fb_info);
+ error_unbind:
+	unbind_from_irqhandler(info->irq, info);
+	// FIXME do we have to stop info->kthread?
+ error_freep:
+	free_page((unsigned long)info->page);
+ error_kfree:
+	kfree(info->pages);
+ error_vfree:
+	vfree(info->fb);
+ error:
+	kfree(info);
+	xenfb_info = NULL;
+
+	return -ENODEV;
+}
+
+static int __init xenfb_init(void)
+{
+	return xenfb_probe();
+}
+
+static void __exit xenfb_cleanup(void)
+{
+	struct xenfb_info *info = xenfb_info;
+
+	unregister_framebuffer(info->fb_info);
+	unbind_from_irqhandler(info->irq, info);
+	free_page((unsigned long)info->page);
+	kfree(info->pages);
+	vfree(info->fb);
+	kfree(info);
+	xenfb_info = NULL;
+}
+
+module_init(xenfb_init);
+module_exit(xenfb_cleanup);
+
+MODULE_LICENSE("GPL");
diff --git a/drivers/xen/xenkbd/Makefile b/drivers/xen/xenkbd/Makefile
new file mode 100644
index 000000000..724efe2bf
--- /dev/null
+++ b/drivers/xen/xenkbd/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_XEN_KEYBOARD)	+= xenkbd.o
diff --git a/drivers/xen/xenkbd/xenkbd.c b/drivers/xen/xenkbd/xenkbd.c
new file mode 100644
index 000000000..26749ff2b
--- /dev/null
+++ b/drivers/xen/xenkbd/xenkbd.c
@@ -0,0 +1,178 @@
+/*
+ * linux/drivers/input/keyboard/xenkbd.c -- Xen para-virtual input device
+ *
+ * Copyright (C) 2005
+ *
+ *      Anthony Liguori <aliguori@us.ibm.com>
+ *
+ *  Based on linux/drivers/input/mouse/sermouse.c
+ *
+ *  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.
+ */
+
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/module.h>
+#include <linux/input.h>
+#include <asm/hypervisor.h>
+#include <xen/evtchn.h>
+#include <xen/xenbus.h>
+#include <linux/xenkbd.h>
+
+struct xenkbd_device
+{
+	struct input_dev *dev;
+	struct xenkbd_info *info;
+	unsigned evtchn;
+	int irq;
+};
+
+static irqreturn_t input_handler(int rq, void *dev_id, struct pt_regs *regs)
+{
+	struct xenkbd_device *dev = dev_id;
+	struct xenkbd_info *info = dev ? dev->info : 0;
+	static int button_map[3] = { BTN_RIGHT, BTN_MIDDLE, BTN_LEFT };
+	__u32 cons, prod;
+
+	prod = info->in_prod;
+	rmb();			/* ensure we see ring contents up to prod */
+	for (cons = info->in_cons; cons != prod; cons++) {
+		union xenkbd_in_event *event;
+		event = &XENKBD_IN_RING_REF(info, cons);
+	
+		switch (event->type) {
+		case XENKBD_TYPE_MOTION:
+			input_report_rel(dev->dev, REL_X, event->motion.rel_x);
+			input_report_rel(dev->dev, REL_Y, event->motion.rel_y);
+			break;
+		case XENKBD_TYPE_BUTTON:
+			if (event->button.button < 3)
+				input_report_key(dev->dev,
+						 button_map[event->button.button],
+						 event->button.pressed);
+			break;
+		case XENKBD_TYPE_KEY:
+			input_report_key(dev->dev, event->key.keycode, event->key.pressed);
+			break;
+		}
+	}
+	input_sync(dev->dev);
+	mb();			/* ensure we got ring contents */
+	info->in_cons = cons;
+	notify_remote_via_evtchn(dev->evtchn);
+
+	return IRQ_HANDLED;
+}
+
+static struct xenkbd_device *xenkbd_dev;
+
+int __init xenkbd_init(void)
+{
+	int ret = 0;
+	int i;
+	struct xenkbd_device *dev;
+	struct input_dev *input_dev;
+	struct evtchn_alloc_unbound alloc_unbound;
+	struct xenbus_transaction xbt;
+
+        /* Nothing to do if running in dom0. */
+        if (is_initial_xendomain())
+	  return -ENODEV;
+#if 1
+        /* if we're not set up to use graphics mode, then don't initialize */
+	if (xenbus_scanf(XBT_NIL, "console", "use_graphics", "%d", &ret) < 0)
+	  return -ENODEV;
+	if (ret == 0)
+	  return -ENODEV;
+#endif
+
+	dev = kmalloc(sizeof(*dev), GFP_KERNEL);
+	input_dev = input_allocate_device();
+	if (!dev || !input_dev)
+		return -ENOMEM;
+
+	dev->dev = input_dev;
+	dev->info = (void *)__get_free_page(GFP_KERNEL);
+	if (!dev->info) {
+		ret = -ENOMEM;
+		goto error;
+	}
+
+	alloc_unbound.dom = DOMID_SELF;
+	alloc_unbound.remote_dom = 0;
+	ret = HYPERVISOR_event_channel_op(EVTCHNOP_alloc_unbound,
+					  &alloc_unbound);
+	if (ret)
+		goto error_freep;
+	dev->evtchn = alloc_unbound.port;
+	ret = bind_evtchn_to_irqhandler(dev->evtchn, input_handler, 0,
+					"xenkbd", dev);
+	if (ret < 0)
+		goto error_freep;
+	dev->irq = ret;
+
+	input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL);
+	input_dev->keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) | BIT(BTN_RIGHT);
+	input_dev->relbit[0] = BIT(REL_X) | BIT(REL_Y);
+
+	/* FIXME not sure this is quite right */
+	for (i = 0; i < 256; i++)
+		set_bit(i, input_dev->keybit);
+
+	input_dev->name = "Xen Virtual Keyboard/Mouse";
+
+	input_register_device(input_dev);
+
+ again:
+	ret = xenbus_transaction_start(&xbt);
+	if (ret)
+		goto error_unreg;
+	ret = xenbus_printf(xbt, "vkbd", "page-ref", "%lu",
+			    virt_to_mfn(dev->info));
+	if (ret)
+		goto error_xenbus;
+	ret = xenbus_printf(xbt, "vkbd", "event-channel", "%u",
+			    dev->evtchn);
+	if (ret)
+		goto error_xenbus;
+	ret = xenbus_transaction_end(xbt, 0);
+	if (ret) {
+		if (ret == -EAGAIN)
+			goto again;
+		goto error_unreg;
+	}
+
+	dev->info->in_cons = dev->info->in_prod = 0;
+	dev->info->out_cons = dev->info->out_prod = 0;
+	xenkbd_dev = dev;
+
+	return ret;
+
+	
+ error_xenbus:
+	xenbus_transaction_end(xbt, 1);
+ error_unreg:
+	input_unregister_device(input_dev);
+	unbind_from_irqhandler(dev->irq, dev);
+ error_freep:
+	free_page((unsigned long)dev->info);
+ error:
+	kfree(dev);
+	return ret;
+}
+
+static void __exit xenkbd_cleanup(void)
+{
+	input_unregister_device(xenkbd_dev->dev);
+	unbind_from_irqhandler(xenkbd_dev->irq, xenkbd_dev);
+	free_page((unsigned long)xenkbd_dev->info);
+	kfree(xenkbd_dev);
+	xenkbd_dev = NULL;
+}
+
+module_init(xenkbd_init);
+module_exit(xenkbd_cleanup);
+
+MODULE_LICENSE("GPL");
diff --git a/fs/cachefiles/Makefile b/fs/cachefiles/Makefile
new file mode 100644
index 000000000..c1522d98b
--- /dev/null
+++ b/fs/cachefiles/Makefile
@@ -0,0 +1,18 @@
+#
+# Makefile for caching in a mounted filesystem
+#
+
+cachefiles-objs := \
+	cf-bind.o \
+	cf-interface.o \
+	cf-key.o \
+	cf-main.o \
+	cf-namei.o \
+	cf-proc.o \
+	cf-xattr.o
+
+ifeq ($(CONFIG_SYSCTL),y)
+cachefiles-objs += cf-sysctl.o
+endif
+
+obj-$(CONFIG_CACHEFILES) := cachefiles.o
diff --git a/fs/cachefiles/cf-bind.c b/fs/cachefiles/cf-bind.c
new file mode 100644
index 000000000..d8cb4c394
--- /dev/null
+++ b/fs/cachefiles/cf-bind.c
@@ -0,0 +1,279 @@
+/* cf-bind.c: bind and unbind a cache from the filesystem backing it
+ *
+ * Copyright (C) 2006 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@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.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/completion.h>
+#include <linux/slab.h>
+#include <linux/fs.h>
+#include <linux/file.h>
+#include <linux/namei.h>
+#include <linux/mount.h>
+#include <linux/namespace.h>
+#include <linux/statfs.h>
+#include <linux/proc_fs.h>
+#include <linux/ctype.h>
+#include "internal.h"
+
+static int cachefiles_proc_add_cache(struct cachefiles_cache *cache,
+				     struct vfsmount *mnt);
+
+/*****************************************************************************/
+/*
+ * bind a directory as a cache
+ */
+int cachefiles_proc_bind(struct cachefiles_cache *cache, char *args)
+{
+	_enter("{%u,%u,%u},%s",
+	       cache->brun_percent,
+	       cache->bcull_percent,
+	       cache->bstop_percent,
+	       args);
+
+	/* start by checking things over */
+	ASSERT(cache->bstop_percent >= 0 &&
+	       cache->bstop_percent < cache->bcull_percent &&
+	       cache->bcull_percent < cache->brun_percent &&
+	       cache->brun_percent  < 100);
+
+	if (*args) {
+		kerror("'bind' command doesn't take an argument");
+		return -EINVAL;
+	}
+
+	if (!cache->rootdirname) {
+		kerror("No cache directory specified");
+		return -EINVAL;
+	}
+
+	/* don't permit already bound caches to be re-bound */
+	if (test_bit(CACHEFILES_READY, &cache->flags)) {
+		kerror("Cache already bound");
+		return -EBUSY;
+	}
+
+	/* make sure we have copies of the tag and dirname strings */
+	if (!cache->tag) {
+		/* the tag string is released by the fops->release()
+		 * function, so we don't release it on error here */
+		cache->tag = kstrdup("CacheFiles", GFP_KERNEL);
+		if (!cache->tag)
+			return -ENOMEM;
+	}
+
+	/* add the cache */
+	return cachefiles_proc_add_cache(cache, NULL);
+}
+
+/*****************************************************************************/
+/*
+ * add a cache
+ */
+static int cachefiles_proc_add_cache(struct cachefiles_cache *cache,
+				     struct vfsmount *mnt)
+{
+	struct cachefiles_object *fsdef;
+	struct nameidata nd;
+	struct kstatfs stats;
+	struct dentry *graveyard, *cachedir, *root;
+	int ret;
+
+	_enter("");
+
+	/* allocate the root index object */
+	ret = -ENOMEM;
+
+	fsdef = kmem_cache_alloc(cachefiles_object_jar, SLAB_KERNEL);
+	if (!fsdef)
+		goto error_root_object;
+
+	atomic_set(&fsdef->usage, 1);
+	atomic_set(&fsdef->fscache_usage, 1);
+	fsdef->type = FSCACHE_COOKIE_TYPE_INDEX;
+
+	_debug("- fsdef %p", fsdef);
+
+	/* look up the directory at the root of the cache */
+	memset(&nd, 0, sizeof(nd));
+
+	ret = path_lookup(cache->rootdirname, LOOKUP_DIRECTORY, &nd);
+	if (ret < 0)
+		goto error_open_root;
+
+	/* bind to the special mountpoint we've prepared */
+	if (mnt) {
+		atomic_inc(&nd.mnt->mnt_sb->s_active);
+		mnt->mnt_sb = nd.mnt->mnt_sb;
+		mnt->mnt_flags = nd.mnt->mnt_flags;
+		mnt->mnt_flags |= MNT_NOSUID | MNT_NOEXEC | MNT_NODEV;
+		mnt->mnt_root = dget(nd.dentry);
+		mnt->mnt_mountpoint = mnt->mnt_root;
+
+		/* copy the name, but ignore kstrdup() failing ENOMEM - we'll
+		 * just end up with an devicenameless mountpoint */
+		mnt->mnt_devname = kstrdup(nd.mnt->mnt_devname, GFP_KERNEL);
+		path_release(&nd);
+
+		cache->mnt = mntget(mnt);
+		root = dget(mnt->mnt_root);
+	} else {
+		cache->mnt = nd.mnt;
+		root = nd.dentry;
+
+		nd.mnt = NULL;
+		nd.dentry = NULL;
+		path_release(&nd);
+	}
+
+	/* check parameters */
+	ret = -EOPNOTSUPP;
+	if (!root->d_inode ||
+	    !root->d_inode->i_op ||
+	    !root->d_inode->i_op->lookup ||
+	    !root->d_inode->i_op->mkdir ||
+	    !root->d_inode->i_op->setxattr ||
+	    !root->d_inode->i_op->getxattr ||
+	    !root->d_sb ||
+	    !root->d_sb->s_op ||
+	    !root->d_sb->s_op->statfs ||
+	    !root->d_sb->s_op->sync_fs)
+		goto error_unsupported;
+
+	ret = -EROFS;
+	if (root->d_sb->s_flags & MS_RDONLY)
+		goto error_unsupported;
+
+	/* get the cache size and blocksize */
+	ret = root->d_sb->s_op->statfs(root, &stats);
+	if (ret < 0)
+		goto error_unsupported;
+
+	ret = -ERANGE;
+	if (stats.f_bsize <= 0)
+		goto error_unsupported;
+
+	ret = -EOPNOTSUPP;
+	if (stats.f_bsize > PAGE_SIZE)
+		goto error_unsupported;
+
+	cache->bsize = stats.f_bsize;
+	cache->bshift = 0;
+	if (stats.f_bsize < PAGE_SIZE)
+		cache->bshift = PAGE_SHIFT - long_log2(stats.f_bsize);
+
+	_debug("blksize %u (shift %u)",
+	       cache->bsize, cache->bshift);
+
+	_debug("size %llu, avail %llu", stats.f_blocks, stats.f_bavail);
+
+	/* set up caching limits */
+	stats.f_blocks >>= cache->bshift;
+	do_div(stats.f_blocks, 100);
+	cache->bstop = stats.f_blocks * cache->bstop_percent;
+	cache->bcull = stats.f_blocks * cache->bcull_percent;
+	cache->brun  = stats.f_blocks * cache->brun_percent;
+
+	_debug("limits {%llu,%llu,%llu}",
+	       cache->brun,
+	       cache->bcull,
+	       cache->bstop);
+
+	/* get the cache directory and check its type */
+	cachedir = cachefiles_get_directory(cache, root, "cache");
+	if (IS_ERR(cachedir)) {
+		ret = PTR_ERR(cachedir);
+		goto error_unsupported;
+	}
+
+	fsdef->dentry = cachedir;
+
+	ret = cachefiles_check_object_type(fsdef);
+	if (ret < 0)
+		goto error_unsupported;
+
+	/* get the graveyard directory */
+	graveyard = cachefiles_get_directory(cache, root, "graveyard");
+	if (IS_ERR(graveyard)) {
+		ret = PTR_ERR(graveyard);
+		goto error_unsupported;
+	}
+
+	cache->graveyard = graveyard;
+
+	/* publish the cache */
+	fscache_init_cache(&cache->cache,
+			   &cachefiles_cache_ops,
+			   "%02x:%02x",
+			   MAJOR(fsdef->dentry->d_sb->s_dev),
+			   MINOR(fsdef->dentry->d_sb->s_dev)
+			   );
+
+	ret = fscache_add_cache(&cache->cache, &fsdef->fscache, cache->tag);
+	if (ret < 0)
+		goto error_add_cache;
+
+	/* done */
+	set_bit(CACHEFILES_READY, &cache->flags);
+	dput(root);
+
+	printk(KERN_INFO "CacheFiles:"
+	       " File cache on %s registered\n",
+	       cache->cache.identifier);
+
+	/* check how much space the cache has */
+	cachefiles_has_space(cache, 0);
+
+	return 0;
+
+error_add_cache:
+	dput(cache->graveyard);
+	cache->graveyard = NULL;
+error_unsupported:
+	mntput(cache->mnt);
+	cache->mnt = NULL;
+	dput(fsdef->dentry);
+	fsdef->dentry = NULL;
+	dput(root);
+error_open_root:
+	kmem_cache_free(cachefiles_object_jar, fsdef);
+error_root_object:
+	kerror("Failed to register: %d", ret);
+	return ret;
+}
+
+/*****************************************************************************/
+/*
+ * unbind a cache on fd release
+ */
+void cachefiles_proc_unbind(struct cachefiles_cache *cache)
+{
+	_enter("");
+
+	if (test_bit(CACHEFILES_READY, &cache->flags)) {
+		printk(KERN_INFO "CacheFiles:"
+		       " File cache on %s unregistering\n",
+		       cache->cache.identifier);
+
+		fscache_withdraw_cache(&cache->cache);
+	}
+
+	if (cache->cache.fsdef)
+		cache->cache.ops->put_object(cache->cache.fsdef);
+
+	dput(cache->graveyard);
+	mntput(cache->mnt);
+
+	kfree(cache->rootdirname);
+	kfree(cache->tag);
+
+	_leave("");
+}
diff --git a/fs/cachefiles/cf-interface.c b/fs/cachefiles/cf-interface.c
new file mode 100644
index 000000000..b5ca30f76
--- /dev/null
+++ b/fs/cachefiles/cf-interface.c
@@ -0,0 +1,1299 @@
+/* cf-interface.c: CacheFiles to FS-Cache interface
+ *
+ * Copyright (C) 2006 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@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.
+ */
+
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/file.h>
+#include <linux/mount.h>
+#include <linux/statfs.h>
+#include <linux/buffer_head.h>
+#include "internal.h"
+
+#define list_to_page(head) (list_entry((head)->prev, struct page, lru))
+#define log2(n) ffz(~(n))
+
+/*****************************************************************************/
+/*
+ * look up the nominated node in this cache, creating it if necessary
+ */
+static struct fscache_object *cachefiles_lookup_object(
+	struct fscache_cache *_cache,
+	struct fscache_object *_parent,
+	struct fscache_cookie *cookie)
+{
+	struct cachefiles_object *parent, *object;
+	struct cachefiles_cache *cache;
+	struct cachefiles_xattr *auxdata;
+	unsigned keylen, auxlen;
+	void *buffer;
+	char *key;
+	int ret;
+
+	ASSERT(_parent);
+
+	cache = container_of(_cache, struct cachefiles_cache, cache);
+	parent = container_of(_parent, struct cachefiles_object, fscache);
+
+	_enter("{%s},%p,%p", cache->cache.identifier, parent, cookie);
+
+	/* create a new object record and a temporary leaf image */
+	object = kmem_cache_alloc(cachefiles_object_jar, SLAB_KERNEL);
+	if (!object)
+		goto nomem_object;
+
+	atomic_set(&object->usage, 1);
+	atomic_set(&object->fscache_usage, 1);
+
+	fscache_object_init(&object->fscache);
+	object->fscache.cookie = cookie;
+	object->fscache.cache = parent->fscache.cache;
+
+	object->type = cookie->def->type;
+
+	/* get hold of the raw key
+	 * - stick the length on the front and leave space on the back for the
+	 *   encoder
+	 */
+	buffer = kmalloc((2 + 512) + 3, GFP_KERNEL);
+	if (!buffer)
+		goto nomem_buffer;
+
+	keylen = cookie->def->get_key(cookie->netfs_data, buffer + 2, 512);
+	ASSERTCMP(keylen, <, 512);
+
+	*(uint16_t *)buffer = keylen;
+	((char *)buffer)[keylen + 2] = 0;
+	((char *)buffer)[keylen + 3] = 0;
+	((char *)buffer)[keylen + 4] = 0;
+
+	/* turn the raw key into something that can work with as a filename */
+	key = cachefiles_cook_key(buffer, keylen + 2, object->type);
+	if (!key)
+		goto nomem_key;
+
+	/* get hold of the auxiliary data and prepend the object type */
+	auxdata = buffer;
+	auxlen = 0;
+	if (cookie->def->get_aux) {
+		auxlen = cookie->def->get_aux(cookie->netfs_data,
+					      auxdata->data, 511);
+		ASSERTCMP(auxlen, <, 511);
+	}
+
+	auxdata->len = auxlen + 1;
+	auxdata->type = cookie->def->type;
+
+	/* look up the key, creating any missing bits */
+	ret = cachefiles_walk_to_object(parent, object, key, auxdata);
+	if (ret < 0)
+		goto lookup_failed;
+
+	kfree(buffer);
+	kfree(key);
+	_leave(" = %p", &object->fscache);
+	return &object->fscache;
+
+lookup_failed:
+	kmem_cache_free(cachefiles_object_jar, object);
+	kfree(buffer);
+	kfree(key);
+	_leave(" = %d", ret);
+	return ERR_PTR(ret);
+
+nomem_key:
+	kfree(buffer);
+nomem_buffer:
+	kmem_cache_free(cachefiles_object_jar, object);
+nomem_object:
+	_leave(" = -ENOMEM");
+	return ERR_PTR(-ENOMEM);
+
+}
+
+/*****************************************************************************/
+/*
+ * increment the usage count on an inode object (may fail if unmounting)
+ */
+static struct fscache_object *cachefiles_grab_object(struct fscache_object *_object)
+{
+	struct cachefiles_object *object;
+
+	_enter("%p", _object);
+
+	object = container_of(_object, struct cachefiles_object, fscache);
+
+#ifdef CACHEFILES_DEBUG_SLAB
+	ASSERT((atomic_read(&object->fscache_usage) & 0xffff0000) != 0x6b6b0000);
+#endif
+
+	atomic_inc(&object->fscache_usage);
+	return &object->fscache;
+
+}
+
+/*****************************************************************************/
+/*
+ * lock the semaphore on an object object
+ */
+static void cachefiles_lock_object(struct fscache_object *_object)
+{
+	struct cachefiles_object *object;
+
+	_enter("%p", _object);
+
+	object = container_of(_object, struct cachefiles_object, fscache);
+
+#ifdef CACHEFILES_DEBUG_SLAB
+	ASSERT((atomic_read(&object->fscache_usage) & 0xffff0000) != 0x6b6b0000);
+#endif
+
+	down_write(&object->sem);
+
+}
+
+/*****************************************************************************/
+/*
+ * unlock the semaphore on an object object
+ */
+static void cachefiles_unlock_object(struct fscache_object *_object)
+{
+	struct cachefiles_object *object;
+
+	_enter("%p", _object);
+
+	object = container_of(_object, struct cachefiles_object, fscache);
+	up_write(&object->sem);
+
+}
+
+/*****************************************************************************/
+/*
+ * update the auxilliary data for an object object on disk
+ */
+static void cachefiles_update_object(struct fscache_object *_object)
+{
+	struct cachefiles_object *object;
+	struct cachefiles_cache *cache;
+
+	_enter("%p", _object);
+
+	object = container_of(_object, struct cachefiles_object, fscache);
+	cache = container_of(object->fscache.cache, struct cachefiles_cache, cache);
+
+	//cachefiles_tree_update_object(super, object);
+
+}
+
+/*****************************************************************************/
+/*
+ * dispose of a reference to an object object
+ */
+static void cachefiles_put_object(struct fscache_object *_object)
+{
+	struct cachefiles_object *object;
+	struct cachefiles_cache *cache;
+
+	ASSERT(_object);
+
+	object = container_of(_object, struct cachefiles_object, fscache);
+	_enter("%p{%d}", object, atomic_read(&object->usage));
+
+	ASSERT(object);
+
+	cache = container_of(object->fscache.cache,
+			     struct cachefiles_cache, cache);
+
+#ifdef CACHEFILES_DEBUG_SLAB
+	ASSERT((atomic_read(&object->fscache_usage) & 0xffff0000) != 0x6b6b0000);
+#endif
+
+	if (!atomic_dec_and_test(&object->fscache_usage))
+		return;
+
+	_debug("- kill object %p", object);
+
+	/* delete retired objects */
+	if (test_bit(FSCACHE_OBJECT_RECYCLING, &object->fscache.flags) &&
+	    _object != cache->cache.fsdef
+	    ) {
+		_debug("- retire object %p", object);
+		cachefiles_delete_object(cache, object);
+	}
+
+	/* close the filesystem stuff attached to the object */
+	if (object->backer != object->dentry) {
+		dput(object->backer);
+		object->backer = NULL;
+	}
+
+	/* note that an object is now inactive */
+	write_lock(&cache->active_lock);
+	rb_erase(&object->active_node, &cache->active_nodes);
+	write_unlock(&cache->active_lock);
+
+	dput(object->dentry);
+	object->dentry = NULL;
+
+	/* then dispose of the object */
+	kmem_cache_free(cachefiles_object_jar, object);
+
+	_leave("");
+
+}
+
+/*****************************************************************************/
+/*
+ * sync a cache
+ */
+static void cachefiles_sync_cache(struct fscache_cache *_cache)
+{
+	struct cachefiles_cache *cache;
+	int ret;
+
+	_enter("%p", _cache);
+
+	cache = container_of(_cache, struct cachefiles_cache, cache);
+
+	/* make sure all pages pinned by operations on behalf of the netfs are
+	 * written to disc */
+	ret = fsync_super(cache->mnt->mnt_sb);
+	if (ret == -EIO)
+		cachefiles_io_error(cache,
+				    "Attempt to sync backing fs superblock"
+				    " returned error %d",
+				    ret);
+
+}
+
+/*****************************************************************************/
+/*
+ * set the data size on an object
+ */
+static int cachefiles_set_i_size(struct fscache_object *_object, loff_t i_size)
+{
+	struct cachefiles_object *object;
+	struct iattr newattrs;
+	int ret;
+
+	_enter("%p,%llu", _object, i_size);
+
+	object = container_of(_object, struct cachefiles_object, fscache);
+
+	if (i_size == object->i_size)
+		return 0;
+
+	if (!object->backer)
+		return -ENOBUFS;
+
+	ASSERT(S_ISREG(object->backer->d_inode->i_mode));
+
+	newattrs.ia_size = i_size;
+	newattrs.ia_valid = ATTR_SIZE;
+
+	mutex_lock(&object->backer->d_inode->i_mutex);
+	ret = notify_change(object->backer, &newattrs);
+	mutex_unlock(&object->backer->d_inode->i_mutex);
+
+	if (ret == -EIO) {
+		cachefiles_io_error_obj(object, "Size set failed");
+		ret = -ENOBUFS;
+	}
+
+	_leave(" = %d", ret);
+	return ret;
+
+}
+
+/*****************************************************************************/
+/*
+ * see if we have space for a number of pages in the cache
+ */
+int cachefiles_has_space(struct cachefiles_cache *cache, unsigned nr)
+{
+	struct kstatfs stats;
+	int ret;
+
+	_enter("{%llu,%llu,%llu},%d",
+	       cache->brun, cache->bcull, cache->bstop,  nr);
+
+	/* find out how many pages of blockdev are available */
+	memset(&stats, 0, sizeof(stats));
+
+	ret = cache->mnt->mnt_sb->s_op->statfs(cache->mnt->mnt_root, &stats);
+	if (ret < 0) {
+		if (ret == -EIO)
+			cachefiles_io_error(cache, "statfs failed");
+		return ret;
+	}
+
+	stats.f_bavail >>= cache->bshift;
+
+	_debug("avail %llu", stats.f_bavail);
+
+	/* see if there is sufficient space */
+	stats.f_bavail -= nr;
+
+	ret = -ENOBUFS;
+	if (stats.f_bavail < cache->bstop)
+		goto begin_cull;
+
+	ret = 0;
+	if (stats.f_bavail < cache->bcull)
+		goto begin_cull;
+
+	if (test_bit(CACHEFILES_CULLING, &cache->flags) &&
+	    stats.f_bavail >= cache->brun
+	    ) {
+		if (test_and_clear_bit(CACHEFILES_CULLING, &cache->flags)) {
+			_debug("cease culling");
+			send_sigurg(&cache->cachefilesd->f_owner);
+		}
+	}
+
+	_leave(" = 0");
+	return 0;
+
+begin_cull:
+	if (!test_and_set_bit(CACHEFILES_CULLING, &cache->flags)) {
+		_debug("### CULL CACHE ###");
+		send_sigurg(&cache->cachefilesd->f_owner);
+	}
+
+	_leave(" = %d", ret);
+	return ret;
+
+}
+
+/*****************************************************************************/
+/*
+ * waiting reading backing files
+ */
+static int cachefiles_read_waiter(wait_queue_t *wait, unsigned mode,
+				  int sync, void *_key)
+{
+	struct cachefiles_one_read *monitor =
+		container_of(wait, struct cachefiles_one_read, monitor);
+	struct wait_bit_key *key = _key;
+	struct page *page = wait->private;
+
+	ASSERT(key);
+
+	_enter("{%lu},%u,%d,{%p,%u}",
+	       monitor->netfs_page->index, mode, sync,
+	       key->flags, key->bit_nr);
+
+	if (key->flags != &page->flags ||
+	    key->bit_nr != PG_locked)
+		return 0;
+
+	_debug("--- monitor %p %lx ---", page, page->flags);
+
+	if (!PageUptodate(page) && !PageError(page))
+		dump_stack();
+
+	/* remove from the waitqueue */
+	list_del(&wait->task_list);
+
+	/* move onto the action list and queue for keventd */
+	ASSERT(monitor->object);
+
+	spin_lock(&monitor->object->work_lock);
+	list_move(&monitor->obj_link, &monitor->object->read_list);
+	spin_unlock(&monitor->object->work_lock);
+
+	schedule_work(&monitor->object->read_work);
+
+	return 0;
+
+}
+
+/*****************************************************************************/
+/*
+ * let keventd drive the copying of pages
+ */
+void cachefiles_read_copier_work(void *_object)
+{
+	struct cachefiles_one_read *monitor;
+	struct cachefiles_object *object = _object;
+	struct fscache_cookie *cookie = object->fscache.cookie;
+	struct pagevec pagevec;
+	int error, max;
+
+	_enter("{ino=%lu}", object->backer->d_inode->i_ino);
+
+	pagevec_init(&pagevec, 0);
+
+	max = 8;
+	spin_lock_irq(&object->work_lock);
+
+	while (!list_empty(&object->read_list)) {
+		monitor = list_entry(object->read_list.next,
+				     struct cachefiles_one_read, obj_link);
+		list_del(&monitor->obj_link);
+
+		spin_unlock_irq(&object->work_lock);
+
+		_debug("- copy {%lu}", monitor->back_page->index);
+
+		error = -EIO;
+		if (PageUptodate(monitor->back_page)) {
+			copy_highpage(monitor->netfs_page, monitor->back_page);
+
+			pagevec_add(&pagevec, monitor->netfs_page);
+			cookie->def->mark_pages_cached(
+				cookie->netfs_data,
+				monitor->netfs_page->mapping,
+				&pagevec);
+			pagevec_reinit(&pagevec);
+
+			error = 0;
+		}
+
+		if (error)
+			cachefiles_io_error_obj(
+				object,
+				"readpage failed on backing file %lx",
+				(unsigned long) monitor->back_page->flags);
+
+		page_cache_release(monitor->back_page);
+
+		monitor->end_io_func(monitor->netfs_page,
+				     monitor->context,
+				     error);
+
+		page_cache_release(monitor->netfs_page);
+		fscache_put_context(cookie, monitor->context);
+		kfree(monitor);
+
+		/* let keventd have some air occasionally */
+		max--;
+		if (max < 0 || need_resched()) {
+			if (!list_empty(&object->read_list))
+				schedule_work(&object->read_work);
+			_leave(" [maxed out]");
+			return;
+		}
+
+		spin_lock_irq(&object->work_lock);
+	}
+
+	spin_unlock_irq(&object->work_lock);
+
+	_leave("");
+
+}
+
+/*****************************************************************************/
+/*
+ * read the corresponding page to the given set from the backing file
+ * - an uncertain page is simply discarded, to be tried again another time
+ */
+static int cachefiles_read_backing_file_one(struct cachefiles_object *object,
+					    fscache_rw_complete_t end_io_func,
+					    void *context,
+					    struct page *netpage,
+					    struct pagevec *lru_pvec)
+{
+	struct cachefiles_one_read *monitor;
+	struct address_space *bmapping;
+	struct page *newpage, *backpage;
+	int ret;
+
+	_enter("");
+
+	ASSERTCMP(pagevec_count(lru_pvec), ==, 0);
+	pagevec_reinit(lru_pvec);
+
+	_debug("read back %p{%lu,%d}",
+	       netpage, netpage->index, page_count(netpage));
+
+	monitor = kzalloc(sizeof(*monitor), GFP_KERNEL);
+	if (!monitor)
+		goto nomem;
+
+	monitor->netfs_page = netpage;
+	monitor->object = object;
+	monitor->end_io_func = end_io_func;
+	monitor->context = fscache_get_context(object->fscache.cookie,
+					       context);
+
+	init_waitqueue_func_entry(&monitor->monitor, cachefiles_read_waiter);
+
+	/* attempt to get hold of the backing page */
+	bmapping = object->backer->d_inode->i_mapping;
+	newpage = NULL;
+
+	for (;;) {
+		backpage = find_get_page(bmapping, netpage->index);
+		if (backpage)
+			goto backing_page_already_present;
+
+		if (!newpage) {
+			newpage = page_cache_alloc_cold(bmapping);
+			if (!newpage)
+				goto nomem_monitor;
+		}
+
+		ret = add_to_page_cache(newpage, bmapping,
+					netpage->index, GFP_KERNEL);
+		if (ret == 0)
+			goto installed_new_backing_page;
+		if (ret != -EEXIST)
+			goto nomem_page;
+	}
+
+	/* we've installed a new backing page, so now we need to add it
+	 * to the LRU list and start it reading */
+installed_new_backing_page:
+	_debug("- new %p", newpage);
+
+	backpage = newpage;
+	newpage = NULL;
+
+	page_cache_get(backpage);
+	pagevec_add(lru_pvec, backpage);
+	__pagevec_lru_add(lru_pvec);
+
+	ret = bmapping->a_ops->readpage(NULL, backpage);
+	if (ret < 0)
+		goto read_error;
+
+	/* set the monitor to transfer the data across */
+monitor_backing_page:
+	_debug("- monitor add");
+
+	/* install the monitor */
+	page_cache_get(monitor->netfs_page);
+	page_cache_get(backpage);
+	monitor->back_page = backpage;
+
+	spin_lock_irq(&object->work_lock);
+	list_add_tail(&monitor->obj_link, &object->read_pend_list);
+	spin_unlock_irq(&object->work_lock);
+
+	monitor->monitor.private = backpage;
+	install_page_waitqueue_monitor(backpage, &monitor->monitor);
+	monitor = NULL;
+
+	/* but the page may have been read before the monitor was
+	 * installed, so the monitor may miss the event - so we have to
+	 * ensure that we do get one in such a case */
+	if (!TestSetPageLocked(backpage))
+		unlock_page(backpage);
+	goto success;
+
+	/* if the backing page is already present, it can be in one of
+	 * three states: read in progress, read failed or read okay */
+backing_page_already_present:
+	_debug("- present");
+
+	if (newpage) {
+		page_cache_release(newpage);
+		newpage = NULL;
+	}
+
+	if (PageError(backpage))
+		goto io_error;
+
+	if (PageUptodate(backpage))
+		goto backing_page_already_uptodate;
+
+	goto monitor_backing_page;
+
+	/* the backing page is already up to date, attach the netfs
+	 * page to the pagecache and LRU and copy the data across */
+backing_page_already_uptodate:
+	_debug("- uptodate");
+
+	copy_highpage(netpage, backpage);
+	end_io_func(netpage, context, 0);
+
+success:
+	_debug("success");
+	ret = 0;
+
+out:
+	if (backpage)
+		page_cache_release(backpage);
+	if (monitor) {
+		fscache_put_context(object->fscache.cookie, monitor->context);
+		kfree(monitor);
+	}
+
+	_leave(" = %d", ret);
+	return ret;
+
+read_error:
+	_debug("read error %d", ret);
+	if (ret == -ENOMEM)
+		goto out;
+io_error:
+	cachefiles_io_error_obj(object, "page read error on backing file");
+	ret = -EIO;
+	goto out;
+
+nomem_page:
+	page_cache_release(newpage);
+nomem_monitor:
+	fscache_put_context(object->fscache.cookie, monitor->context);
+	kfree(monitor);
+nomem:
+	_leave(" = -ENOMEM");
+	return -ENOMEM;
+
+}
+
+/*****************************************************************************/
+/*
+ * read a page from the cache or allocate a block in which to store it
+ * - cache withdrawal is prevented by the caller
+ * - returns -EINTR if interrupted
+ * - returns -ENOMEM if ran out of memory
+ * - returns -ENOBUFS if no buffers can be made available
+ * - returns -ENOBUFS if page is beyond EOF
+ * - if the page is backed by a block in the cache:
+ *   - a read will be started which will call the callback on completion
+ *   - 0 will be returned
+ * - else if the page is unbacked:
+ *   - the metadata will be retained
+ *   - -ENODATA will be returned
+ */
+static int cachefiles_read_or_alloc_page(struct fscache_object *_object,
+					 struct page *page,
+					 fscache_rw_complete_t end_io_func,
+					 void *context,
+					 unsigned long gfp)
+{
+	struct cachefiles_object *object;
+	struct cachefiles_cache *cache;
+	struct fscache_cookie *cookie;
+	struct pagevec pagevec;
+	struct inode *inode;
+	sector_t block0, block;
+	unsigned shift;
+	int ret;
+
+	object = container_of(_object, struct cachefiles_object, fscache);
+	cache = container_of(object->fscache.cache, struct cachefiles_cache, cache);
+
+	_enter("{%p},{%lx},,,", object, page->index);
+
+	if (!object->backer)
+		return -ENOBUFS;
+
+	inode = object->backer->d_inode;
+	ASSERT(S_ISREG(inode->i_mode));
+	ASSERT(inode->i_mapping->a_ops->bmap);
+	ASSERT(inode->i_mapping->a_ops->readpages);
+
+	/* calculate the shift required to use bmap */
+	if (inode->i_sb->s_blocksize > PAGE_SIZE)
+		return -ENOBUFS;
+
+	shift = PAGE_SHIFT - inode->i_sb->s_blocksize_bits;
+
+	cookie = object->fscache.cookie;
+
+	pagevec_init(&pagevec, 0);
+
+	/* we assume the absence or presence of the first block is a good
+	 * enough indication for the page as a whole
+	 * - TODO: don't use bmap() for this as it is _not_ actually good
+	 *   enough for this as it doesn't indicate errors, but it's all we've
+	 *   got for the moment
+	 */
+	block0 = page->index;
+	block0 <<= shift;
+
+	block = inode->i_mapping->a_ops->bmap(inode->i_mapping, block0);
+	_debug("%llx -> %llx", block0, block);
+
+	if (block) {
+		/* submit the apparently valid page to the backing fs to be
+		 * read from disk */
+		ret = cachefiles_read_backing_file_one(object,
+						       end_io_func,
+						       context,
+						       page,
+						       &pagevec);
+		ret = 0;
+	} else if (cachefiles_has_space(cache, 1) == 0) {
+		/* there's space in the cache we can use */
+		pagevec_add(&pagevec, page);
+		cookie->def->mark_pages_cached(cookie->netfs_data,
+					       page->mapping, &pagevec);
+		ret = -ENODATA;
+	} else {
+		ret = -ENOBUFS;
+	}
+
+	_leave(" = %d", ret);
+	return ret;
+
+}
+
+/*****************************************************************************/
+/*
+ * read the corresponding pages to the given set from the backing file
+ * - any uncertain pages are simply discarded, to be tried again another time
+ */
+static int cachefiles_read_backing_file(struct cachefiles_object *object,
+					fscache_rw_complete_t end_io_func,
+					void *context,
+					struct address_space *mapping,
+					struct list_head *list,
+					struct pagevec *lru_pvec)
+{
+	struct cachefiles_one_read *monitor = NULL;
+	struct address_space *bmapping = object->backer->d_inode->i_mapping;
+	struct page *newpage = NULL, *netpage, *_n, *backpage = NULL;
+	int ret = 0;
+
+	_enter("");
+
+	ASSERTCMP(pagevec_count(lru_pvec), ==, 0);
+	pagevec_reinit(lru_pvec);
+
+	list_for_each_entry_safe(netpage, _n, list, lru) {
+		list_del(&netpage->lru);
+
+		_debug("read back %p{%lu,%d}",
+		       netpage, netpage->index, page_count(netpage));
+
+		if (!monitor) {
+			monitor = kzalloc(sizeof(*monitor), GFP_KERNEL);
+			if (!monitor)
+				goto nomem;
+
+			monitor->object = object;
+			monitor->end_io_func = end_io_func;
+			monitor->context = fscache_get_context(
+				object->fscache.cookie, context);
+
+			init_waitqueue_func_entry(&monitor->monitor,
+						  cachefiles_read_waiter);
+		}
+
+		for (;;) {
+			backpage = find_get_page(bmapping, netpage->index);
+			if (backpage)
+				goto backing_page_already_present;
+
+			if (!newpage) {
+				newpage = page_cache_alloc_cold(bmapping);
+				if (!newpage)
+					goto nomem;
+			}
+
+			ret = add_to_page_cache(newpage, bmapping,
+						netpage->index, GFP_KERNEL);
+			if (ret == 0)
+				goto installed_new_backing_page;
+			if (ret != -EEXIST)
+				goto nomem;
+		}
+
+		/* we've installed a new backing page, so now we need to add it
+		 * to the LRU list and start it reading */
+	installed_new_backing_page:
+		_debug("- new %p", newpage);
+
+		backpage = newpage;
+		newpage = NULL;
+
+		page_cache_get(backpage);
+		if (!pagevec_add(lru_pvec, backpage))
+			__pagevec_lru_add(lru_pvec);
+
+	reread_backing_page:
+		ret = bmapping->a_ops->readpage(NULL, backpage);
+		if (ret < 0)
+			goto read_error;
+
+		/* add the netfs page to the pagecache and LRU, and set the
+		 * monitor to transfer the data across */
+	monitor_backing_page:
+		_debug("- monitor add");
+
+		ret = add_to_page_cache(netpage, mapping, netpage->index,
+					GFP_KERNEL);
+		if (ret < 0) {
+			if (ret == -EEXIST) {
+				page_cache_release(netpage);
+				continue;
+			}
+			goto nomem;
+		}
+
+		page_cache_get(netpage);
+		if (!pagevec_add(lru_pvec, netpage))
+			__pagevec_lru_add(lru_pvec);
+
+		/* install a monitor */
+		page_cache_get(netpage);
+		monitor->netfs_page = netpage;
+
+		page_cache_get(backpage);
+		monitor->back_page = backpage;
+
+		spin_lock_irq(&object->work_lock);
+		list_add_tail(&monitor->obj_link, &object->read_pend_list);
+		spin_unlock_irq(&object->work_lock);
+
+		monitor->monitor.private = backpage;
+		install_page_waitqueue_monitor(backpage, &monitor->monitor);
+		monitor = NULL;
+
+		/* but the page may have been read before the monitor was
+		 * installed, so the monitor may miss the event - so we have to
+		 * ensure that we do get one in such a case */
+		if (!TestSetPageLocked(backpage)) {
+			_debug("2unlock %p", backpage);
+			unlock_page(backpage);
+		}
+
+		page_cache_release(backpage);
+		backpage = NULL;
+
+		page_cache_release(netpage);
+		netpage = NULL;
+		continue;
+
+		/* if the backing page is already present, it can be in one of
+		 * three states: read in progress, read failed or read okay */
+	backing_page_already_present:
+		_debug("- present %p", backpage);
+
+		if (PageError(backpage))
+			goto io_error;
+
+		if (PageUptodate(backpage))
+			goto backing_page_already_uptodate;
+
+		_debug("- not ready %p{%lx}", backpage, backpage->flags);
+
+		if (TestSetPageLocked(backpage))
+			goto monitor_backing_page;
+
+		if (PageError(backpage)) {
+			unlock_page(backpage);
+			goto io_error;
+		}
+
+		if (PageUptodate(backpage))
+			goto backing_page_already_uptodate_unlock;
+
+		/* we've locked a page that's neither up to date nor erroneous,
+		 * so we need to attempt to read it again */
+		goto reread_backing_page;
+
+		/* the backing page is already up to date, attach the netfs
+		 * page to the pagecache and LRU and copy the data across */
+	backing_page_already_uptodate_unlock:
+		unlock_page(backpage);
+	backing_page_already_uptodate:
+		_debug("- uptodate");
+
+		ret = add_to_page_cache(netpage, mapping, netpage->index,
+					GFP_KERNEL);
+		if (ret < 0) {
+			if (ret == -EEXIST) {
+				page_cache_release(netpage);
+				continue;
+			}
+			goto nomem;
+		}
+
+		copy_highpage(netpage, backpage);
+
+		page_cache_release(backpage);
+		backpage = NULL;
+
+		page_cache_get(netpage);
+		if (!pagevec_add(lru_pvec, netpage))
+			__pagevec_lru_add(lru_pvec);
+
+		end_io_func(netpage, context, 0);
+
+		page_cache_release(netpage);
+		netpage = NULL;
+		continue;
+	}
+
+	netpage = NULL;
+
+	_debug("out");
+
+out:
+	/* tidy up */
+	pagevec_lru_add(lru_pvec);
+
+	if (newpage)
+		page_cache_release(newpage);
+	if (netpage)
+		page_cache_release(netpage);
+	if (backpage)
+		page_cache_release(backpage);
+	if (monitor) {
+		fscache_put_context(object->fscache.cookie, monitor->context);
+		kfree(monitor);
+	}
+
+	list_for_each_entry_safe(netpage, _n, list, lru) {
+		list_del(&netpage->lru);
+		page_cache_release(netpage);
+	}
+
+	_leave(" = %d", ret);
+	return ret;
+
+nomem:
+	_debug("nomem");
+	ret = -ENOMEM;
+	goto out;
+
+read_error:
+	_debug("read error %d", ret);
+	if (ret == -ENOMEM)
+		goto out;
+io_error:
+	cachefiles_io_error_obj(object, "page read error on backing file");
+	ret = -EIO;
+	goto out;
+
+}
+
+/*****************************************************************************/
+/*
+ * read a list of pages from the cache or allocate blocks in which to store
+ * them
+ */
+static int cachefiles_read_or_alloc_pages(struct fscache_object *_object,
+					  struct address_space *mapping,
+					  struct list_head *pages,
+					  unsigned *nr_pages,
+					  fscache_rw_complete_t end_io_func,
+					  void *context,
+					  unsigned long gfp)
+{
+	struct cachefiles_object *object;
+	struct cachefiles_cache *cache;
+	struct fscache_cookie *cookie;
+	struct list_head backpages;
+	struct pagevec pagevec;
+	struct inode *inode;
+	struct page *page, *_n;
+	unsigned shift, nrbackpages;
+	int ret, ret2, space;
+
+	object = container_of(_object, struct cachefiles_object, fscache);
+	cache = container_of(object->fscache.cache, struct cachefiles_cache, cache);
+
+	_enter("{%p},,%d,,", object, *nr_pages);
+
+	if (!object->backer)
+		return -ENOBUFS;
+
+	space = 1;
+	if (cachefiles_has_space(cache, *nr_pages) < 0)
+		space = 0;
+
+	inode = object->backer->d_inode;
+	ASSERT(S_ISREG(inode->i_mode));
+	ASSERT(inode->i_mapping->a_ops->bmap);
+	ASSERT(inode->i_mapping->a_ops->readpages);
+
+	/* calculate the shift required to use bmap */
+	if (inode->i_sb->s_blocksize > PAGE_SIZE)
+		return -ENOBUFS;
+
+	shift = PAGE_SHIFT - inode->i_sb->s_blocksize_bits;
+
+	pagevec_init(&pagevec, 0);
+
+	cookie = object->fscache.cookie;
+
+	INIT_LIST_HEAD(&backpages);
+	nrbackpages = 0;
+
+	ret = space ? -ENODATA : -ENOBUFS;
+	list_for_each_entry_safe(page, _n, pages, lru) {
+		sector_t block0, block;
+
+		/* we assume the absence or presence of the first block is a
+		 * good enough indication for the page as a whole
+		 * - TODO: don't use bmap() for this as it is _not_ actually
+		 *   good enough for this as it doesn't indicate errors, but
+		 *   it's all we've got for the moment
+		 */
+		block0 = page->index;
+		block0 <<= shift;
+
+		block = inode->i_mapping->a_ops->bmap(inode->i_mapping,
+						      block0);
+		_debug("%llx -> %llx", block0, block);
+
+		if (block) {
+			/* we have data - add it to the list to give to the
+			 * backing fs */
+			list_move(&page->lru, &backpages);
+			(*nr_pages)--;
+			nrbackpages++;
+		} else if (space && pagevec_add(&pagevec, page) == 0) {
+			cookie->def->mark_pages_cached(cookie->netfs_data,
+						       mapping, &pagevec);
+			pagevec_reinit(&pagevec);
+			ret = -ENODATA;
+		}
+	}
+
+	if (pagevec_count(&pagevec) > 0) {
+		cookie->def->mark_pages_cached(cookie->netfs_data,
+					       mapping, &pagevec);
+		pagevec_reinit(&pagevec);
+	}
+
+	if (list_empty(pages))
+		ret = 0;
+
+	/* submit the apparently valid pages to the backing fs to be read from disk */
+	if (nrbackpages > 0) {
+		ret2 = cachefiles_read_backing_file(object,
+						    end_io_func,
+						    context,
+						    mapping,
+						    &backpages,
+						    &pagevec);
+
+		ASSERTCMP(pagevec_count(&pagevec), ==, 0);
+
+		if (ret2 == -ENOMEM || ret2 == -EINTR)
+			ret = ret2;
+	}
+
+	_leave(" = %d [nr=%u%s]",
+	       ret, *nr_pages, list_empty(pages) ? " empty" : "");
+	return ret;
+
+}
+
+/*****************************************************************************/
+/*
+ * read a page from the cache or allocate a block in which to store it
+ * - cache withdrawal is prevented by the caller
+ * - returns -EINTR if interrupted
+ * - returns -ENOMEM if ran out of memory
+ * - returns -ENOBUFS if no buffers can be made available
+ * - returns -ENOBUFS if page is beyond EOF
+ * - otherwise:
+ *   - the metadata will be retained
+ *   - 0 will be returned
+ */
+static int cachefiles_allocate_page(struct fscache_object *_object,
+				    struct page *page,
+				    unsigned long gfp)
+{
+	struct cachefiles_object *object;
+	struct cachefiles_cache *cache;
+
+	object = container_of(_object, struct cachefiles_object, fscache);
+	cache = container_of(object->fscache.cache,
+			     struct cachefiles_cache, cache);
+
+	_enter("%p,{%lx},,,", object, page->index);
+
+	return cachefiles_has_space(cache, 1);
+
+}
+
+/*****************************************************************************/
+/*
+ * page storer
+ */
+void cachefiles_write_work(void *_object)
+{
+	struct cachefiles_one_write *writer;
+	struct cachefiles_object *object = _object;
+	int ret, max;
+
+	_enter("%p", object);
+
+	ASSERT(!irqs_disabled());
+
+	spin_lock_irq(&object->work_lock);
+	max = 8;
+
+	while (!list_empty(&object->write_list)) {
+		writer = list_entry(object->write_list.next,
+				    struct cachefiles_one_write, obj_link);
+		list_del(&writer->obj_link);
+
+		spin_unlock_irq(&object->work_lock);
+
+		_debug("- store {%lu}", writer->netfs_page->index);
+
+		ret = generic_file_buffered_write_one_kernel_page(
+			object->backer->d_inode->i_mapping,
+			writer->netfs_page->index,
+			writer->netfs_page);
+
+		if (ret == -ENOSPC) {
+			ret = -ENOBUFS;
+		} else if (ret == -EIO) {
+			cachefiles_io_error_obj(object,
+						"write page to backing file"
+						" failed");
+			ret = -ENOBUFS;
+		}
+
+		_debug("- callback");
+		writer->end_io_func(writer->netfs_page,
+				    writer->context,
+				    ret);
+
+		_debug("- put net");
+		page_cache_release(writer->netfs_page);
+		fscache_put_context(object->fscache.cookie, writer->context);
+		kfree(writer);
+
+		/* let keventd have some air occasionally */
+		max--;
+		if (max < 0 || need_resched()) {
+			if (!list_empty(&object->write_list))
+				schedule_work(&object->write_work);
+			_leave(" [maxed out]");
+			return;
+		}
+
+		_debug("- next");
+		spin_lock_irq(&object->work_lock);
+	}
+
+	spin_unlock_irq(&object->work_lock);
+	_leave("");
+
+}
+
+/*****************************************************************************/
+/*
+ * request a page be stored in the cache
+ * - cache withdrawal is prevented by the caller
+ * - this request may be ignored if there's no cache block available, in which
+ *   case -ENOBUFS will be returned
+ * - if the op is in progress, 0 will be returned
+ */
+static int cachefiles_write_page(struct fscache_object *_object,
+				 struct page *page,
+				 fscache_rw_complete_t end_io_func,
+				 void *context,
+				 unsigned long gfp)
+{
+//	struct cachefiles_one_write *writer;
+	struct cachefiles_object *object;
+	int ret;
+
+	object = container_of(_object, struct cachefiles_object, fscache);
+
+	_enter("%p,%p{%lx},,,", object, page, page->index);
+
+	if (!object->backer)
+		return -ENOBUFS;
+
+	ASSERT(S_ISREG(object->backer->d_inode->i_mode));
+
+#if 0 // set to 1 for deferred writing
+	/* queue the operation for deferred processing by keventd */
+	writer = kzalloc(sizeof(*writer), GFP_KERNEL);
+	if (!writer)
+		return -ENOMEM;
+
+	page_cache_get(page);
+	writer->netfs_page = page;
+	writer->object = object;
+	writer->end_io_func = end_io_func;
+	writer->context = facache_get_context(object->fscache.cookie, context);
+
+	spin_lock_irq(&object->work_lock);
+	list_add_tail(&writer->obj_link, &object->write_list);
+	spin_unlock_irq(&object->work_lock);
+
+	schedule_work(&object->write_work);
+	ret = 0;
+
+#else
+	/* copy the page to ext3 and let it store it in its own time */
+	ret = generic_file_buffered_write_one_kernel_page(
+		object->backer->d_inode->i_mapping, page->index, page);
+
+	if (ret != 0) {
+		if (ret == -EIO)
+			cachefiles_io_error_obj(object,
+						"write page to backing file"
+						" failed");
+		ret = -ENOBUFS;
+	}
+
+	end_io_func(page, context, ret);
+#endif
+
+	_leave(" = %d", ret);
+	return ret;
+
+}
+
+/*****************************************************************************/
+/*
+ * detach a backing block from a page
+ * - cache withdrawal is prevented by the caller
+ */
+static void cachefiles_uncache_pages(struct fscache_object *_object,
+				     struct pagevec *pagevec)
+{
+	struct cachefiles_object *object;
+	struct cachefiles_cache *cache;
+
+	object = container_of(_object, struct cachefiles_object, fscache);
+	cache = container_of(object->fscache.cache,
+			     struct cachefiles_cache, cache);
+
+	_enter("%p,{%lu,%lx},,,",
+	       object, pagevec->nr, pagevec->pages[0]->index);
+
+}
+
+/*****************************************************************************/
+/*
+ * dissociate a cache from all the pages it was backing
+ */
+static void cachefiles_dissociate_pages(struct fscache_cache *cache)
+{
+	_enter("");
+
+}
+
+struct fscache_cache_ops cachefiles_cache_ops = {
+	.name			= "cachefiles",
+	.lookup_object		= cachefiles_lookup_object,
+	.grab_object		= cachefiles_grab_object,
+	.lock_object		= cachefiles_lock_object,
+	.unlock_object		= cachefiles_unlock_object,
+	.update_object		= cachefiles_update_object,
+	.put_object		= cachefiles_put_object,
+	.sync_cache		= cachefiles_sync_cache,
+	.set_i_size		= cachefiles_set_i_size,
+	.read_or_alloc_page	= cachefiles_read_or_alloc_page,
+	.read_or_alloc_pages	= cachefiles_read_or_alloc_pages,
+	.allocate_page		= cachefiles_allocate_page,
+	.write_page		= cachefiles_write_page,
+	.uncache_pages		= cachefiles_uncache_pages,
+	.dissociate_pages	= cachefiles_dissociate_pages,
+};
diff --git a/fs/cachefiles/cf-key.c b/fs/cachefiles/cf-key.c
new file mode 100644
index 000000000..cfae5a715
--- /dev/null
+++ b/fs/cachefiles/cf-key.c
@@ -0,0 +1,157 @@
+/* cf-key.c: Key to pathname encoder
+ *
+ * Copyright (C) 2006 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@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.
+ */
+
+#include <linux/slab.h>
+#include "internal.h"
+
+static const char cachefiles_charmap[64] =
+	"0123456789"			/* 0 - 9 */
+	"abcdefghijklmnopqrstuvwxyz"	/* 10 - 35 */
+	"ABCDEFGHIJKLMNOPQRSTUVWXYZ"	/* 36 - 61 */
+	"_-"				/* 62 - 63 */
+	;
+
+static const char cachefiles_filecharmap[256] = {
+	/* we skip space and tab and control chars */
+	[ 33 ... 46 ] = 1,		/* '!' -> '.' */
+	/* we skip '/' as it's significant to pathwalk */
+	[ 48 ... 127 ] = 1,		/* '0' -> '~' */
+};
+
+/*****************************************************************************/
+/*
+ * turn the raw key into something cooked
+ * - the raw key should include the length in the two bytes at the front
+ * - the key may be up to 514 bytes in length (including the length word)
+ *   - "base64" encode the strange keys, mapping 3 bytes of raw to four of
+ *     cooked
+ *   - need to cut the cooked key into 252 char lengths (189 raw bytes)
+ */
+char *cachefiles_cook_key(const u8 *raw, int keylen, uint8_t type)
+{
+	unsigned char csum, ch;
+	unsigned int acc;
+	char *key;
+	int loop, len, max, seg, mark, print;
+
+	_enter(",%d", keylen);
+
+	BUG_ON(keylen < 2 || keylen > 514);
+
+	csum = raw[0] + raw[1];
+	print = 1;
+	for (loop = 2; loop < keylen; loop++) {
+		ch = raw[loop];
+		csum += ch;
+		print &= cachefiles_filecharmap[ch];
+	}
+
+	if (print) {
+		/* if the path is usable ASCII, then we render it directly */
+		max = keylen - 2;
+		max += 2;	/* two base64'd length chars on the front */
+		max += 5;	/* @checksum/M */
+		max += 3 * 2;	/* maximum number of segment dividers (".../M")
+				 * is ((514 + 251) / 252) = 3
+				 */
+		max += 1;	/* NUL on end */
+	} else {
+		/* calculate the maximum length of the cooked key */
+		keylen = (keylen + 2) / 3;
+
+		max = keylen * 4;
+		max += 5;	/* @checksum/M */
+		max += 3 * 2;	/* maximum number of segment dividers (".../M")
+				 * is ((514 + 188) / 189) = 3
+				 */
+		max += 1;	/* NUL on end */
+	}
+
+	_debug("max: %d", max);
+
+	key = kmalloc(max, GFP_KERNEL);
+	if (!key)
+		return NULL;
+
+	len = 0;
+
+	/* build the cooked key */
+	sprintf(key, "@%02x/+", (unsigned) csum);
+	len = 5;
+	mark = len - 1;
+
+	if (print) {
+		acc = *(uint16_t *) raw;
+		raw += 2;
+
+		key[len + 1] = cachefiles_charmap[acc & 63];
+		acc >>= 6;
+		key[len] = cachefiles_charmap[acc & 63];
+		len += 2;
+
+		seg = 250;
+		for (loop = keylen; loop > 0; loop--) {
+			if (seg <= 0) {
+				key[len++] = '/';
+				mark = len;
+				key[len++] = '+';
+				seg = 252;
+			}
+
+			key[len++] = *raw++;
+			ASSERT(len < max);
+		}
+
+		switch (type) {
+		case FSCACHE_COOKIE_TYPE_INDEX:		type = 'I';	break;
+		case FSCACHE_COOKIE_TYPE_DATAFILE:	type = 'D';	break;
+		default:				type = 'S';	break;
+		}
+	} else {
+		seg = 252;
+		for (loop = keylen; loop > 0; loop--) {
+			if (seg <= 0) {
+				key[len++] = '/';
+				mark = len;
+				key[len++] = '+';
+				seg = 252;
+			}
+
+			acc = *raw++;
+			acc |= *raw++ << 8;
+			acc |= *raw++ << 16;
+
+			_debug("acc: %06x", acc);
+
+			key[len++] = cachefiles_charmap[acc & 63];
+			acc >>= 6;
+			key[len++] = cachefiles_charmap[acc & 63];
+			acc >>= 6;
+			key[len++] = cachefiles_charmap[acc & 63];
+			acc >>= 6;
+			key[len++] = cachefiles_charmap[acc & 63];
+
+			ASSERT(len < max);
+		}
+
+		switch (type) {
+		case FSCACHE_COOKIE_TYPE_INDEX:		type = 'J';	break;
+		case FSCACHE_COOKIE_TYPE_DATAFILE:	type = 'E';	break;
+		default:				type = 'T';	break;
+		}
+	}
+
+	key[mark] = type;
+	key[len] = 0;
+
+	_leave(" = %p %d:[%s]", key, len, key);
+	return key;
+}
diff --git a/fs/cachefiles/cf-main.c b/fs/cachefiles/cf-main.c
new file mode 100644
index 000000000..da8d02010
--- /dev/null
+++ b/fs/cachefiles/cf-main.c
@@ -0,0 +1,129 @@
+/* cf-main.c: network filesystem caching backend to use cache files on a
+ *            premounted filesystem
+ *
+ * Copyright (C) 2006 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@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.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/completion.h>
+#include <linux/slab.h>
+#include <linux/fs.h>
+#include <linux/file.h>
+#include <linux/namei.h>
+#include <linux/mount.h>
+#include <linux/statfs.h>
+#include <linux/proc_fs.h>
+#include <linux/sysctl.h>
+#include "internal.h"
+
+unsigned long cachefiles_debug;
+
+static int cachefiles_init(void);
+static void cachefiles_exit(void);
+
+fs_initcall(cachefiles_init);
+module_exit(cachefiles_exit);
+
+MODULE_DESCRIPTION("Mounted-filesystem based cache");
+MODULE_AUTHOR("Red Hat, Inc.");
+MODULE_LICENSE("GPL");
+
+kmem_cache_t *cachefiles_object_jar;
+
+static void cachefiles_object_init_once(void *_object, kmem_cache_t *cachep,
+					unsigned long flags)
+{
+	struct cachefiles_object *object = _object;
+
+	switch (flags & (SLAB_CTOR_VERIFY | SLAB_CTOR_CONSTRUCTOR)) {
+	case SLAB_CTOR_CONSTRUCTOR:
+		memset(object, 0, sizeof(*object));
+		fscache_object_init(&object->fscache);
+		init_rwsem(&object->sem);
+		spin_lock_init(&object->work_lock);
+		INIT_LIST_HEAD(&object->read_list);
+		INIT_LIST_HEAD(&object->read_pend_list);
+		INIT_WORK(&object->read_work, &cachefiles_read_copier_work,
+			  object);
+		INIT_LIST_HEAD(&object->write_list);
+		INIT_WORK(&object->write_work, &cachefiles_write_work, object);
+		break;
+
+	default:
+		break;
+	}
+}
+
+/*****************************************************************************/
+/*
+ * initialise the fs caching module
+ */
+static int __init cachefiles_init(void)
+{
+	struct proc_dir_entry *pde;
+	int ret;
+
+	/* create a proc entry to use as a handle for the userspace daemon */
+	ret = -ENOMEM;
+
+	pde = create_proc_entry("cachefiles", 0600, proc_root_fs);
+	if (!pde) {
+		kerror("Unable to create /proc/fs/cachefiles");
+		goto error_proc;
+	}
+
+	if (cachefiles_sysctl_init() < 0) {
+		kerror("Unable to create sysctl parameters");
+		goto error_object_jar;
+	}
+
+	pde->owner = THIS_MODULE;
+	pde->proc_fops = &cachefiles_proc_fops;
+	cachefiles_proc = pde;
+
+	/* create an object jar */
+	cachefiles_object_jar =
+		kmem_cache_create("cachefiles_object_jar",
+				  sizeof(struct cachefiles_object),
+				  0,
+				  SLAB_HWCACHE_ALIGN,
+				  cachefiles_object_init_once,
+				  NULL);
+	if (!cachefiles_object_jar) {
+		printk(KERN_NOTICE
+		       "CacheFiles: Failed to allocate an object jar\n");
+		goto error_sysctl;
+	}
+
+	printk(KERN_INFO "CacheFiles: Loaded\n");
+	return 0;
+
+error_sysctl:
+	cachefiles_sysctl_cleanup();
+error_object_jar:
+	remove_proc_entry("cachefiles", proc_root_fs);
+error_proc:
+	kerror("failed to register: %d", ret);
+	return ret;
+}
+
+/*****************************************************************************/
+/*
+ * clean up on module removal
+ */
+static void __exit cachefiles_exit(void)
+{
+	printk(KERN_INFO "CacheFiles: Unloading\n");
+
+	kmem_cache_destroy(cachefiles_object_jar);
+	remove_proc_entry("cachefiles", proc_root_fs);
+	cachefiles_sysctl_cleanup();
+}
diff --git a/fs/cachefiles/cf-namei.c b/fs/cachefiles/cf-namei.c
new file mode 100644
index 000000000..20db88ada
--- /dev/null
+++ b/fs/cachefiles/cf-namei.c
@@ -0,0 +1,825 @@
+/* cf-namei.c: CacheFiles path walking and related routines
+ *
+ * Copyright (C) 2006 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@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.
+ */
+
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/file.h>
+#include <linux/fs.h>
+#include <linux/fsnotify.h>
+#include <linux/quotaops.h>
+#include <linux/xattr.h>
+#include <linux/mount.h>
+#include <linux/namei.h>
+#include "internal.h"
+
+/*****************************************************************************/
+/*
+ * record the fact that an object is now active
+ */
+static void cachefiles_mark_object_active(struct cachefiles_cache *cache,
+					  struct cachefiles_object *object)
+{
+	struct cachefiles_object *xobject;
+	struct rb_node **_p, *_parent = NULL;
+	struct dentry *dentry;
+
+	write_lock(&cache->active_lock);
+
+	dentry = object->dentry;
+	_p = &cache->active_nodes.rb_node;
+	while (*_p) {
+		_parent = *_p;
+		xobject = rb_entry(_parent,
+				   struct cachefiles_object, active_node);
+
+		if (xobject->dentry > dentry)
+			_p = &(*_p)->rb_left;
+		else if (xobject->dentry < dentry)
+			_p = &(*_p)->rb_right;
+		else
+			BUG(); /* uh oh... this dentry shouldn't be here */
+	}
+
+	rb_link_node(&object->active_node, _parent, _p);
+	rb_insert_color(&object->active_node, &cache->active_nodes);
+
+	write_unlock(&cache->active_lock);
+}
+
+/*****************************************************************************/
+/*
+ * delete an object representation from the cache
+ * - file backed objects are unlinked
+ * - directory backed objects are stuffed into the graveyard for userspace to
+ *   delete
+ * - unlocks the directory mutex
+ */
+static int cachefiles_bury_object(struct cachefiles_cache *cache,
+				  struct dentry *dir,
+				  struct dentry *rep)
+{
+	struct dentry *grave, *alt, *trap;
+	struct qstr name;
+	const char *old_name;
+	char nbuffer[8 + 8 + 1];
+	int ret;
+
+	_enter(",'%*.*s','%*.*s'",
+	       dir->d_name.len, dir->d_name.len, dir->d_name.name,
+	       rep->d_name.len, rep->d_name.len, rep->d_name.name);
+
+	/* non-directories can just be unlinked */
+	if (!S_ISDIR(rep->d_inode->i_mode)) {
+		_debug("unlink stale object");
+		ret = dir->d_inode->i_op->unlink(dir->d_inode, rep);
+
+		mutex_unlock(&dir->d_inode->i_mutex);
+
+		if (ret == 0) {
+			_debug("d_delete");
+			d_delete(rep);
+		} else if (ret == -EIO) {
+			cachefiles_io_error(cache, "Unlink failed");
+		}
+
+		_leave(" = %d", ret);
+		return ret;
+	}
+
+	/* directories have to be moved to the graveyard */
+	_debug("move stale object to graveyard");
+	mutex_unlock(&dir->d_inode->i_mutex);
+
+try_again:
+	/* first step is to make up a grave dentry in the graveyard */
+	sprintf(nbuffer, "%08x%08x",
+		(uint32_t) xtime.tv_sec,
+		(uint32_t) atomic_inc_return(&cache->gravecounter));
+
+	name.name = nbuffer;
+	name.len = strlen(name.name);
+
+	/* hash the name */
+	name.hash = full_name_hash(name.name, name.len);
+
+	if (dir->d_op && dir->d_op->d_hash) {
+		ret = dir->d_op->d_hash(dir, &name);
+		if (ret < 0) {
+			if (ret == -EIO)
+				cachefiles_io_error(cache, "Hash failed");
+
+			_leave(" = %d", ret);
+			return ret;
+		}
+	}
+
+	/* do the multiway lock magic */
+	trap = lock_rename(cache->graveyard, dir);
+
+	/* do some checks before getting the grave dentry */
+	if (rep->d_parent != dir) {
+		/* the entry was probably culled when we dropped the parent dir
+		 * lock */
+		unlock_rename(cache->graveyard, dir);
+		_leave(" = 0 [culled?]");
+		return 0;
+	}
+
+	if (!S_ISDIR(cache->graveyard->d_inode->i_mode)) {
+		unlock_rename(cache->graveyard, dir);
+		cachefiles_io_error(cache, "Graveyard no longer a directory");
+		return -EIO;
+	}
+
+	if (trap == rep) {
+		unlock_rename(cache->graveyard, dir);
+		cachefiles_io_error(cache, "May not make directory loop");
+		return -EIO;
+	}
+
+	if (d_mountpoint(rep)) {
+		unlock_rename(cache->graveyard, dir);
+		cachefiles_io_error(cache, "Mountpoint in cache");
+		return -EIO;
+	}
+
+	/* see if there's a dentry already there for this name */
+	grave = d_lookup(cache->graveyard, &name);
+	if (!grave) {
+		_debug("not found");
+
+		grave = d_alloc(cache->graveyard, &name);
+		if (!grave) {
+			unlock_rename(cache->graveyard, dir);
+			_leave(" = -ENOMEM");
+			return -ENOMEM;
+		}
+
+		alt = cache->graveyard->d_inode->i_op->lookup(
+			cache->graveyard->d_inode, grave, NULL);
+		if (IS_ERR(alt)) {
+			unlock_rename(cache->graveyard, dir);
+			dput(grave);
+
+			if (PTR_ERR(alt) == -ENOMEM) {
+				_leave(" = -ENOMEM");
+				return -ENOMEM;
+			}
+
+			cachefiles_io_error(cache, "Lookup error %ld",
+					    PTR_ERR(alt));
+			return -EIO;
+		}
+
+		if (alt) {
+			dput(grave);
+			grave = alt;
+		}
+	}
+
+	if (grave->d_inode) {
+		unlock_rename(cache->graveyard, dir);
+		dput(grave);
+		grave = NULL;
+		cond_resched();
+		goto try_again;
+	}
+
+	if (d_mountpoint(grave)) {
+		unlock_rename(cache->graveyard, dir);
+		dput(grave);
+		cachefiles_io_error(cache, "Mountpoint in graveyard");
+		return -EIO;
+	}
+
+	/* target should not be an ancestor of source */
+	if (trap == grave) {
+		unlock_rename(cache->graveyard, dir);
+		dput(grave);
+		cachefiles_io_error(cache, "May not make directory loop");
+		return -EIO;
+	}
+
+	/* attempt the rename */
+	DQUOT_INIT(dir->d_inode);
+	DQUOT_INIT(cache->graveyard->d_inode);
+
+	old_name = fsnotify_oldname_init(rep->d_name.name);
+
+	ret = dir->d_inode->i_op->rename(dir->d_inode, rep,
+					 cache->graveyard->d_inode, grave);
+
+	if (ret == 0) {
+		d_move(rep, grave);
+		fsnotify_move(dir->d_inode, cache->graveyard->d_inode,
+			      old_name, rep->d_name.name, 1,
+			      grave->d_inode, rep->d_inode);
+	} else if (ret != -ENOMEM) {
+		cachefiles_io_error(cache, "Rename failed with error %d", ret);
+	}
+
+	fsnotify_oldname_free(old_name);
+
+	unlock_rename(cache->graveyard, dir);
+	dput(grave);
+	_leave(" = 0");
+	return 0;
+}
+
+/*****************************************************************************/
+/*
+ * delete an object representation from the cache
+ */
+int cachefiles_delete_object(struct cachefiles_cache *cache,
+			     struct cachefiles_object *object)
+{
+	struct dentry *dir;
+	int ret;
+
+	_enter(",{%p}", object->dentry);
+
+	ASSERT(object->dentry);
+	ASSERT(object->dentry->d_inode);
+	ASSERT(object->dentry->d_parent);
+
+	dir = dget_parent(object->dentry);
+
+	mutex_lock(&dir->d_inode->i_mutex);
+	ret = cachefiles_bury_object(cache, dir, object->dentry);
+
+	dput(dir);
+	_leave(" = %d", ret);
+	return ret;
+}
+
+/*****************************************************************************/
+/*
+ * walk from the parent object to the child object through the backing
+ * filesystem, creating directories as we go
+ */
+int cachefiles_walk_to_object(struct cachefiles_object *parent,
+			      struct cachefiles_object *object,
+			      char *key,
+			      struct cachefiles_xattr *auxdata)
+{
+	struct cachefiles_cache *cache;
+	struct dentry *dir, *next = NULL, *new;
+	struct qstr name;
+	uid_t fsuid;
+	gid_t fsgid;
+	int ret;
+
+	_enter("{%p}", parent->dentry);
+
+	cache = container_of(parent->fscache.cache,
+			     struct cachefiles_cache, cache);
+
+	ASSERT(parent->dentry);
+	ASSERT(parent->dentry->d_inode);
+
+	if (!(S_ISDIR(parent->dentry->d_inode->i_mode))) {
+		// TODO: convert file to dir
+		_leave("looking up in none directory");
+		return -ENOBUFS;
+	}
+
+	fsuid = current->fsuid;
+	fsgid = current->fsgid;
+	current->fsuid = 0;
+	current->fsgid = 0;
+
+	dir = dget(parent->dentry);
+
+advance:
+	/* attempt to transit the first directory component */
+	name.name = key;
+	key = strchr(key, '/');
+	if (key) {
+		name.len = key - (char *) name.name;
+		*key++ = 0;
+	} else {
+		name.len = strlen(name.name);
+	}
+
+	/* hash the name */
+	name.hash = full_name_hash(name.name, name.len);
+
+	if (dir->d_op && dir->d_op->d_hash) {
+		ret = dir->d_op->d_hash(dir, &name);
+		if (ret < 0) {
+			cachefiles_io_error(cache, "Hash failed");
+			goto error_out2;
+		}
+	}
+
+lookup_again:
+	/* search the current directory for the element name */
+	_debug("lookup '%s' %x", name.name, name.hash);
+
+	mutex_lock(&dir->d_inode->i_mutex);
+
+	next = d_lookup(dir, &name);
+	if (!next) {
+		_debug("not found");
+
+		new = d_alloc(dir, &name);
+		if (!new)
+			goto nomem_d_alloc;
+
+		ASSERT(dir->d_inode->i_op);
+		ASSERT(dir->d_inode->i_op->lookup);
+
+		next = dir->d_inode->i_op->lookup(dir->d_inode, new, NULL);
+		if (IS_ERR(next))
+			goto lookup_error;
+
+		if (!next)
+			next = new;
+		else
+			dput(new);
+
+		if (next->d_inode) {
+			ret = -EPERM;
+			if (!next->d_inode->i_op ||
+			    !next->d_inode->i_op->setxattr ||
+			    !next->d_inode->i_op->getxattr ||
+			    !next->d_inode->i_op->removexattr)
+				goto error;
+
+			if (key && (!next->d_inode->i_op->lookup ||
+				    !next->d_inode->i_op->mkdir ||
+				    !next->d_inode->i_op->create ||
+				    !next->d_inode->i_op->rename ||
+				    !next->d_inode->i_op->rmdir ||
+				    !next->d_inode->i_op->unlink))
+				goto error;
+		}
+	}
+
+	_debug("next -> %p %s", next, next->d_inode ? "positive" : "negative");
+
+	if (!key)
+		object->new = !next->d_inode;
+
+	/* we need to create the object if it's negative */
+	if (key || object->type == FSCACHE_COOKIE_TYPE_INDEX) {
+		/* index objects and intervening tree levels must be subdirs */
+		if (!next->d_inode) {
+			DQUOT_INIT(dir->d_inode);
+			ret = dir->d_inode->i_op->mkdir(dir->d_inode, next, 0);
+			if (ret < 0)
+				goto create_error;
+
+			ASSERT(next->d_inode);
+
+			fsnotify_mkdir(dir->d_inode, next);
+
+			_debug("mkdir -> %p{%p{ino=%lu}}",
+			       next, next->d_inode, next->d_inode->i_ino);
+
+		} else if (!S_ISDIR(next->d_inode->i_mode)) {
+			kerror("inode %lu is not a directory",
+			       next->d_inode->i_ino);
+			ret = -ENOBUFS;
+			goto error;
+		}
+
+	} else {
+		/* non-index objects start out life as files */
+		if (!next->d_inode) {
+			DQUOT_INIT(dir->d_inode);
+			ret = dir->d_inode->i_op->create(dir->d_inode, next,
+							 S_IFREG, NULL);
+			if (ret < 0)
+				goto create_error;
+
+			ASSERT(next->d_inode);
+
+			fsnotify_create(dir->d_inode, next);
+
+			_debug("create -> %p{%p{ino=%lu}}",
+			       next, next->d_inode, next->d_inode->i_ino);
+
+		} else if (!S_ISDIR(next->d_inode->i_mode) &&
+			   !S_ISREG(next->d_inode->i_mode)
+			   ) {
+			kerror("inode %lu is not a file or directory",
+			       next->d_inode->i_ino);
+			ret = -ENOBUFS;
+			goto error;
+		}
+	}
+
+	/* process the next component */
+	if (key) {
+		_debug("advance");
+		mutex_unlock(&dir->d_inode->i_mutex);
+		dput(dir);
+		dir = next;
+		next = NULL;
+		goto advance;
+	}
+
+	/* we've found the object we were looking for */
+	object->dentry = next;
+
+	/* if we've found that the terminal object exists, then we need to
+	 * check its attributes and delete it if it's out of date */
+	if (!object->new) {
+		_debug("validate '%*.*s'",
+		       next->d_name.len, next->d_name.len, next->d_name.name);
+
+		ret = cachefiles_check_object_xattr(object, auxdata);
+		if (ret == -ESTALE) {
+			/* delete the object (the deleter drops the directory
+			 * mutex) */
+			object->dentry = NULL;
+
+			ret = cachefiles_bury_object(cache, dir, next);
+			dput(next);
+			next = NULL;
+
+			if (ret < 0)
+				goto delete_error;
+
+			_debug("redo lookup");
+			goto lookup_again;
+		}
+	}
+
+	/* note that we're now using this object */
+	cachefiles_mark_object_active(cache, object);
+
+	mutex_unlock(&dir->d_inode->i_mutex);
+	dput(dir);
+	dir = NULL;
+
+	if (object->new) {
+		/* attach data to a newly constructed terminal object */
+		ret = cachefiles_set_object_xattr(object, auxdata);
+		if (ret < 0)
+			goto check_error;
+	} else {
+		/* always update the atime on an object we've just looked up
+		 * (this is used to keep track of culling, and atimes are only
+		 * updated by read, write and readdir but not lookup or
+		 * open) */
+		touch_atime(cache->mnt, next);
+	}
+
+	/* open a file interface onto a data file */
+	if (object->type != FSCACHE_COOKIE_TYPE_INDEX) {
+		if (S_ISREG(object->dentry->d_inode->i_mode)) {
+			const struct address_space_operations *aops;
+
+			ret = -EPERM;
+			aops = object->dentry->d_inode->i_mapping->a_ops;
+			if (!aops->bmap ||
+			    !aops->prepare_write ||
+			    !aops->commit_write)
+				goto check_error;
+
+			object->backer = object->dentry;
+		} else {
+			BUG(); // TODO: open file in data-class subdir
+		}
+	}
+
+	current->fsuid = fsuid;
+	current->fsgid = fsgid;
+	object->new = 0;
+
+	_leave(" = 0 [%lu]", object->dentry->d_inode->i_ino);
+	return 0;
+
+create_error:
+	if (ret == -EIO)
+		cachefiles_io_error(cache, "create/mkdir failed");
+	goto error;
+
+check_error:
+	write_lock(&cache->active_lock);
+	rb_erase(&object->active_node, &cache->active_nodes);
+	write_unlock(&cache->active_lock);
+
+	dput(object->dentry);
+	object->dentry = NULL;
+	goto error_out;
+
+delete_error:
+	_debug("delete error %d", ret);
+	goto error_out2;
+
+lookup_error:
+	_debug("lookup error %ld", PTR_ERR(next));
+	dput(new);
+	ret = PTR_ERR(next);
+	if (ret == -EIO)
+		cachefiles_io_error(cache, "Lookup failed");
+	next = NULL;
+	goto error;
+
+nomem_d_alloc:
+	ret = -ENOMEM;
+error:
+	mutex_unlock(&dir->d_inode->i_mutex);
+	dput(next);
+error_out2:
+	dput(dir);
+error_out:
+	current->fsuid = fsuid;
+	current->fsgid = fsgid;
+
+	_leave(" = ret");
+	return ret;
+}
+
+/*****************************************************************************/
+/*
+ * get a subdirectory
+ */
+struct dentry *cachefiles_get_directory(struct cachefiles_cache *cache,
+					struct dentry *dir,
+					const char *dirname)
+{
+	struct dentry *subdir, *new;
+	struct qstr name;
+	uid_t fsuid;
+	gid_t fsgid;
+	int ret;
+
+	_enter("");
+
+	/* set up the name */
+	name.name = dirname;
+	name.len = strlen(dirname);
+	name.hash = full_name_hash(name.name, name.len);
+
+	if (dir->d_op && dir->d_op->d_hash) {
+		ret = dir->d_op->d_hash(dir, &name);
+		if (ret < 0) {
+			if (ret == -EIO)
+				kerror("Hash failed");
+			_leave(" = %d", ret);
+			return ERR_PTR(ret);
+		}
+	}
+
+	/* search the current directory for the element name */
+	_debug("lookup '%s' %x", name.name, name.hash);
+
+	fsuid = current->fsuid;
+	fsgid = current->fsgid;
+	current->fsuid = 0;
+	current->fsgid = 0;
+
+	mutex_lock(&dir->d_inode->i_mutex);
+
+	subdir = d_lookup(dir, &name);
+	if (!subdir) {
+		_debug("not found");
+
+		new = d_alloc(dir, &name);
+		if (!new)
+			goto nomem_d_alloc;
+
+		subdir = dir->d_inode->i_op->lookup(dir->d_inode, new, NULL);
+		if (IS_ERR(subdir))
+			goto lookup_error;
+
+		if (!subdir)
+			subdir = new;
+		else
+			dput(new);
+	}
+
+	_debug("subdir -> %p %s",
+	       subdir, subdir->d_inode ? "positive" : "negative");
+
+	/* we need to create the subdir if it doesn't exist yet */
+	if (!subdir->d_inode) {
+		DQUOT_INIT(dir->d_inode);
+		ret = dir->d_inode->i_op->mkdir(dir->d_inode, subdir, 0700);
+		if (ret < 0)
+			goto mkdir_error;
+
+		ASSERT(subdir->d_inode);
+
+		fsnotify_mkdir(dir->d_inode, subdir);
+
+		_debug("mkdir -> %p{%p{ino=%lu}}",
+		       subdir,
+		       subdir->d_inode,
+		       subdir->d_inode->i_ino);
+	}
+
+	mutex_unlock(&dir->d_inode->i_mutex);
+
+	current->fsuid = fsuid;
+	current->fsgid = fsgid;
+
+	/* we need to make sure the subdir is a directory */
+	ASSERT(subdir->d_inode);
+
+	if (!S_ISDIR(subdir->d_inode->i_mode)) {
+		kerror("%s is not a directory", dirname);
+		ret = -EIO;
+		goto check_error;
+	}
+
+	ret = -EPERM;
+	if (!subdir->d_inode->i_op ||
+	    !subdir->d_inode->i_op->setxattr ||
+	    !subdir->d_inode->i_op->getxattr ||
+	    !subdir->d_inode->i_op->lookup ||
+	    !subdir->d_inode->i_op->mkdir ||
+	    !subdir->d_inode->i_op->create ||
+	    !subdir->d_inode->i_op->rename ||
+	    !subdir->d_inode->i_op->rmdir ||
+	    !subdir->d_inode->i_op->unlink)
+		goto check_error;
+
+	_leave(" = [%lu]", subdir->d_inode->i_ino);
+	return subdir;
+
+check_error:
+	dput(subdir);
+	_leave(" = %d [check]", ret);
+	return ERR_PTR(ret);
+
+mkdir_error:
+	mutex_unlock(&dir->d_inode->i_mutex);
+	kerror("mkdir %s failed with error %d", dirname, ret);
+	goto error_out;
+
+lookup_error:
+	mutex_unlock(&dir->d_inode->i_mutex);
+	dput(new);
+	ret = PTR_ERR(subdir);
+	kerror("Lookup %s failed with error %d", dirname, ret);
+	goto error_out;
+
+nomem_d_alloc:
+	mutex_unlock(&dir->d_inode->i_mutex);
+	ret = -ENOMEM;
+	goto error_out;
+
+error_out:
+	current->fsuid = fsuid;
+	current->fsgid = fsgid;
+	_leave(" = %d", ret);
+	return ERR_PTR(ret);
+}
+
+/*****************************************************************************/
+/*
+ * cull an object if it's not in use
+ * - called only by cache manager daemon
+ */
+int cachefiles_cull(struct cachefiles_cache *cache, struct dentry *dir,
+		    char *filename)
+{
+	struct cachefiles_object *object;
+	struct rb_node *_n;
+	struct dentry *victim, *new;
+	struct qstr name;
+	int ret;
+
+	_enter(",%*.*s/,%s",
+	       dir->d_name.len, dir->d_name.len, dir->d_name.name, filename);
+
+	/* set up the name */
+	name.name = filename;
+	name.len = strlen(filename);
+	name.hash = full_name_hash(name.name, name.len);
+
+	if (dir->d_op && dir->d_op->d_hash) {
+		ret = dir->d_op->d_hash(dir, &name);
+		if (ret < 0) {
+			if (ret == -EIO)
+				cachefiles_io_error(cache, "Hash failed");
+			_leave(" = %d", ret);
+			return ret;
+		}
+	}
+
+	/* look up the victim */
+	mutex_lock(&dir->d_inode->i_mutex);
+
+	victim = d_lookup(dir, &name);
+	if (!victim) {
+		_debug("not found");
+
+		new = d_alloc(dir, &name);
+		if (!new)
+			goto nomem_d_alloc;
+
+		victim = dir->d_inode->i_op->lookup(dir->d_inode, new, NULL);
+		if (IS_ERR(victim))
+			goto lookup_error;
+
+		if (!victim)
+			victim = new;
+		else
+			dput(new);
+	}
+
+	_debug("victim -> %p %s",
+	       victim, victim->d_inode ? "positive" : "negative");
+
+	/* if the object is no longer there then we probably retired the object
+	 * at the netfs's request whilst the cull was in progress
+	 */
+	if (!victim->d_inode) {
+		mutex_unlock(&dir->d_inode->i_mutex);
+		dput(victim);
+		_leave(" = -ENOENT [absent]");
+		return -ENOENT;
+	}
+
+	/* check to see if we're using this object */
+	read_lock(&cache->active_lock);
+
+	_n = cache->active_nodes.rb_node;
+
+	while (_n) {
+		object = rb_entry(_n, struct cachefiles_object, active_node);
+
+		if (object->dentry > victim)
+			_n = _n->rb_left;
+		else if (object->dentry < victim)
+			_n = _n->rb_right;
+		else
+			goto object_in_use;
+	}
+
+	read_unlock(&cache->active_lock);
+
+	/* okay... the victim is not being used so we can cull it
+	 * - start by marking it as stale
+	 */
+	_debug("victim is cullable");
+
+	ret = cachefiles_remove_object_xattr(cache, victim);
+	if (ret < 0)
+		goto error_unlock;
+
+	/*  actually remove the victim (drops the dir mutex) */
+	_debug("bury");
+
+	ret = cachefiles_bury_object(cache, dir, victim);
+	if (ret < 0)
+		goto error;
+
+	dput(victim);
+	_leave(" = 0");
+	return 0;
+
+
+object_in_use:
+	read_unlock(&cache->active_lock);
+	mutex_unlock(&dir->d_inode->i_mutex);
+	dput(victim);
+	_leave(" = -EBUSY [in use]");
+	return -EBUSY;
+
+nomem_d_alloc:
+	mutex_unlock(&dir->d_inode->i_mutex);
+	_leave(" = -ENOMEM");
+	return -ENOMEM;
+
+lookup_error:
+	mutex_unlock(&dir->d_inode->i_mutex);
+	dput(new);
+	ret = PTR_ERR(victim);
+	if (ret == -EIO)
+		cachefiles_io_error(cache, "Lookup failed");
+	goto choose_error;
+
+error_unlock:
+	mutex_unlock(&dir->d_inode->i_mutex);
+error:
+	dput(victim);
+choose_error:
+	if (ret == -ENOENT) {
+		/* file or dir now absent - probably retired by netfs */
+		_leave(" = -ESTALE [absent]");
+		return -ESTALE;
+	}
+
+	if (ret != -ENOMEM) {
+		kerror("Internal error: %d", ret);
+		ret = -EIO;
+	}
+
+	_leave(" = %d", ret);
+	return ret;
+}
diff --git a/fs/cachefiles/cf-proc.c b/fs/cachefiles/cf-proc.c
new file mode 100644
index 000000000..c14320e0a
--- /dev/null
+++ b/fs/cachefiles/cf-proc.c
@@ -0,0 +1,498 @@
+/* cf-proc.c: /proc/fs/cachefiles interface
+ *
+ * Copyright (C) 2006 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@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.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/completion.h>
+#include <linux/slab.h>
+#include <linux/fs.h>
+#include <linux/file.h>
+#include <linux/namei.h>
+#include <linux/mount.h>
+#include <linux/namespace.h>
+#include <linux/statfs.h>
+#include <linux/proc_fs.h>
+#include <linux/ctype.h>
+#include "internal.h"
+
+static int cachefiles_proc_open(struct inode *, struct file *);
+static int cachefiles_proc_release(struct inode *, struct file *);
+static ssize_t cachefiles_proc_read(struct file *, char __user *, size_t, loff_t *);
+static ssize_t cachefiles_proc_write(struct file *, const char __user *, size_t, loff_t *);
+static int cachefiles_proc_brun(struct cachefiles_cache *cache, char *args);
+static int cachefiles_proc_bcull(struct cachefiles_cache *cache, char *args);
+static int cachefiles_proc_bstop(struct cachefiles_cache *cache, char *args);
+static int cachefiles_proc_cull(struct cachefiles_cache *cache, char *args);
+static int cachefiles_proc_debug(struct cachefiles_cache *cache, char *args);
+static int cachefiles_proc_dir(struct cachefiles_cache *cache, char *args);
+static int cachefiles_proc_tag(struct cachefiles_cache *cache, char *args);
+
+struct proc_dir_entry *cachefiles_proc;
+
+static unsigned long cachefiles_open;
+
+struct file_operations cachefiles_proc_fops = {
+	.open		= cachefiles_proc_open,
+	.release	= cachefiles_proc_release,
+	.read		= cachefiles_proc_read,
+	.write		= cachefiles_proc_write,
+};
+
+struct cachefiles_proc_cmd {
+	char name[8];
+	int (*handler)(struct cachefiles_cache *cache, char *args);
+};
+
+static const struct cachefiles_proc_cmd cachefiles_proc_cmds[] = {
+	{ "bind",	cachefiles_proc_bind	},
+	{ "brun",	cachefiles_proc_brun	},
+	{ "bcull",	cachefiles_proc_bcull	},
+	{ "bstop",	cachefiles_proc_bstop	},
+	{ "cull",	cachefiles_proc_cull	},
+	{ "debug",	cachefiles_proc_debug	},
+	{ "dir",	cachefiles_proc_dir	},
+	{ "tag",	cachefiles_proc_tag	},
+	{ "",		NULL			}
+};
+
+
+/*****************************************************************************/
+/*
+ * do various checks
+ */
+static int cachefiles_proc_open(struct inode *inode, struct file *file)
+{
+	struct cachefiles_cache *cache;
+
+	_enter("");
+
+	/* only the superuser may do this */
+	if (!capable(CAP_SYS_ADMIN))
+		return -EPERM;
+
+	/* /proc/fs/cachefiles may only be open once at a time */
+	if (xchg(&cachefiles_open, 1) == 1)
+		return -EBUSY;
+
+	/* allocate a cache record */
+	cache = kzalloc(sizeof(struct cachefiles_cache), GFP_KERNEL);
+	if (!cache) {
+		cachefiles_open = 0;
+		return -ENOMEM;
+	}
+
+	cache->active_nodes = RB_ROOT;
+	rwlock_init(&cache->active_lock);
+
+	/* set default caching limits
+	 * - limit at 1% free space
+	 * - cull below 5% free space
+	 * - cease culling above 7% free space
+	 */
+	cache->brun_percent = 7;
+	cache->bcull_percent = 5;
+	cache->bstop_percent = 1;
+
+	file->private_data = cache;
+	cache->cachefilesd = file;
+	return 0;
+}
+
+/*****************************************************************************/
+/*
+ * release a cache
+ */
+static int cachefiles_proc_release(struct inode *inode, struct file *file)
+{
+	struct cachefiles_cache *cache = file->private_data;
+
+	_enter("");
+
+	ASSERT(cache);
+
+	set_bit(CACHEFILES_DEAD, &cache->flags);
+
+	cachefiles_proc_unbind(cache);
+
+	ASSERT(!cache->active_nodes.rb_node);
+
+	/* clean up the control file interface */
+	cache->cachefilesd = NULL;
+	file->private_data = NULL;
+	cachefiles_open = 0;
+
+	kfree(cache);
+
+	_leave("");
+	return 0;
+}
+
+/*****************************************************************************/
+/*
+ * read the cache state
+ */
+static ssize_t cachefiles_proc_read(struct file *file, char __user *_buffer,
+				    size_t buflen, loff_t *pos)
+{
+	struct cachefiles_cache *cache = file->private_data;
+	char buffer[256];
+	int n;
+
+	_enter(",,%zu,", buflen);
+
+	if (!test_bit(CACHEFILES_READY, &cache->flags))
+		return 0;
+
+	/* check how much space the cache has */
+	cachefiles_has_space(cache, 0);
+
+	/* summarise */
+	n = snprintf(buffer, sizeof(buffer),
+		     "cull=%c"
+		     " brun=%llx"
+		     " bcull=%llx"
+		     " bstop=%llx",
+		     test_bit(CACHEFILES_CULLING, &cache->flags) ? '1' : '0',
+		     cache->brun,
+		     cache->bcull,
+		     cache->bstop
+		     );
+
+	if (n > buflen)
+		return -EMSGSIZE;
+
+	if (copy_to_user(_buffer, buffer, n) != 0)
+		return -EFAULT;
+
+	return n;
+}
+
+/*****************************************************************************/
+/*
+ * command the cache
+ */
+static ssize_t cachefiles_proc_write(struct file *file,
+				     const char __user *_data, size_t datalen,
+				     loff_t *pos)
+{
+	const struct cachefiles_proc_cmd *cmd;
+	struct cachefiles_cache *cache = file->private_data;
+	ssize_t ret;
+	char *data, *args, *cp;
+
+	_enter(",,%zu,", datalen);
+
+	ASSERT(cache);
+
+	if (test_bit(CACHEFILES_DEAD, &cache->flags))
+		return -EIO;
+
+	if (datalen < 0 || datalen > PAGE_SIZE - 1)
+		return -EOPNOTSUPP;
+
+	/* drag the command string into the kernel so we can parse it */
+	data = kmalloc(datalen + 1, GFP_KERNEL);
+	if (!data)
+		return -ENOMEM;
+
+	ret = -EFAULT;
+	if (copy_from_user(data, _data, datalen) != 0)
+		goto error;
+
+	data[datalen] = '\0';
+
+	ret = -EINVAL;
+	if (memchr(data, '\0', datalen))
+		goto error;
+
+	/* strip any newline */
+	cp = memchr(data, '\n', datalen);
+	if (cp) {
+		if (cp == data)
+			goto error;
+
+		*cp = '\0';
+	}
+
+	/* parse the command */
+	ret = -EOPNOTSUPP;
+
+	for (args = data; *args; args++)
+		if (isspace(*args))
+			break;
+	if (*args) {
+		if (args == data)
+			goto error;
+		*args = '\0';
+		for (args++; isspace(*args); args++)
+			continue;
+	}
+
+	/* run the appropriate command handler */
+	for (cmd = cachefiles_proc_cmds; cmd->name[0]; cmd++)
+		if (strcmp(cmd->name, data) == 0)
+			goto found_command;
+
+error:
+	kfree(data);
+	_leave(" = %d", ret);
+	return ret;
+
+found_command:
+	mutex_lock(&file->f_dentry->d_inode->i_mutex);
+
+	ret = -EIO;
+	if (!test_bit(CACHEFILES_DEAD, &cache->flags))
+		ret = cmd->handler(cache, args);
+
+	mutex_unlock(&file->f_dentry->d_inode->i_mutex);
+
+	if (ret == 0)
+		ret = datalen;
+	goto error;
+}
+
+/*****************************************************************************/
+/*
+ * give a range error for cache space constraints
+ * - can be tail-called
+ */
+static int cachefiles_proc_range_error(struct cachefiles_cache *cache, char *args)
+{
+	kerror("Free space limits must be in range"
+	       " 0%%<=bstop<bcull<brun<100%%");
+
+	return -EINVAL;
+}
+
+/*****************************************************************************/
+/*
+ * set the percentage of blocks at which to stop culling
+ * - command: "brun <N>%"
+ */
+static int cachefiles_proc_brun(struct cachefiles_cache *cache, char *args)
+{
+	unsigned long brun;
+
+	_enter(",%s", args);
+
+	if (!*args)
+		return -EINVAL;
+
+	brun = simple_strtoul(args, &args, 10);
+	if (args[0] != '%' || args[1] != '\0')
+		return -EINVAL;
+
+	if (brun <= cache->bcull_percent || brun >= 100)
+		return cachefiles_proc_range_error(cache, args);
+
+	cache->brun_percent = brun;
+	return 0;
+}
+
+/*****************************************************************************/
+/*
+ * set the percentage of blocks at which to start culling
+ * - command: "bcull <N>%"
+ */
+static int cachefiles_proc_bcull(struct cachefiles_cache *cache, char *args)
+{
+	unsigned long bcull;
+
+	_enter(",%s", args);
+
+	if (!*args)
+		return -EINVAL;
+
+	bcull = simple_strtoul(args, &args, 10);
+	if (args[0] != '%' || args[1] != '\0')
+		return -EINVAL;
+
+	if (bcull <= cache->bstop_percent || bcull >= cache->brun_percent)
+		return cachefiles_proc_range_error(cache, args);
+
+	cache->bcull_percent = bcull;
+	return 0;
+}
+
+/*****************************************************************************/
+/*
+ * set the percentage of blocks at which to stop allocating
+ * - command: "bstop <N>%"
+ */
+static int cachefiles_proc_bstop(struct cachefiles_cache *cache, char *args)
+{
+	unsigned long bstop;
+
+	_enter(",%s", args);
+
+	if (!*args)
+		return -EINVAL;
+
+	bstop = simple_strtoul(args, &args, 10);
+	if (args[0] != '%' || args[1] != '\0')
+		return -EINVAL;
+
+	if (bstop < 0 || bstop >= cache->bcull_percent)
+		return cachefiles_proc_range_error(cache, args);
+
+	cache->bstop_percent = bstop;
+	return 0;
+}
+
+/*****************************************************************************/
+/*
+ * set the cache directory
+ * - command: "dir <name>"
+ */
+static int cachefiles_proc_dir(struct cachefiles_cache *cache, char *args)
+{
+	char *dir;
+
+	_enter(",%s", args);
+
+	if (!*args) {
+		kerror("Empty directory specified");
+		return -EINVAL;
+	}
+
+	if (cache->rootdirname) {
+		kerror("Second cache directory specified");
+		return -EEXIST;
+	}
+
+	dir = kstrdup(args, GFP_KERNEL);
+	if (!dir)
+		return -ENOMEM;
+
+	cache->rootdirname = dir;
+	return 0;
+}
+
+/*****************************************************************************/
+/*
+ * set the cache tag
+ * - command: "tag <name>"
+ */
+static int cachefiles_proc_tag(struct cachefiles_cache *cache, char *args)
+{
+	char *tag;
+
+	_enter(",%s", args);
+
+	if (!*args) {
+		kerror("Empty tag specified");
+		return -EINVAL;
+	}
+
+	if (cache->tag)
+		return -EEXIST;
+
+	tag = kstrdup(args, GFP_KERNEL);
+	if (!tag)
+		return -ENOMEM;
+
+	cache->tag = tag;
+	return 0;
+}
+
+/*****************************************************************************/
+/*
+ * request a node in the cache be culled
+ * - command: "cull <dirfd> <name>"
+ */
+static int cachefiles_proc_cull(struct cachefiles_cache *cache, char *args)
+{
+	struct dentry *dir;
+	struct file *dirfile;
+	int dirfd, fput_needed, ret;
+
+	_enter(",%s", args);
+
+	dirfd = simple_strtoul(args, &args, 0);
+
+	if (!args || !isspace(*args))
+		goto inval;
+
+	while (isspace(*args))
+		args++;
+
+	if (!*args)
+		goto inval;
+
+	if (strchr(args, '/'))
+		goto inval;
+
+	if (!test_bit(CACHEFILES_READY, &cache->flags)) {
+		kerror("cull applied to unready cache");
+		return -EIO;
+	}
+
+	if (test_bit(CACHEFILES_DEAD, &cache->flags)) {
+		kerror("cull applied to dead cache");
+		return -EIO;
+	}
+
+	/* extract the directory dentry from the fd */
+	dirfile = fget_light(dirfd, &fput_needed);
+	if (!dirfile) {
+		kerror("cull dirfd not open");
+		return -EBADF;
+	}
+
+	dir = dget(dirfile->f_dentry);
+	fput_light(dirfile, fput_needed);
+	dirfile = NULL;
+
+	if (!S_ISDIR(dir->d_inode->i_mode))
+		goto notdir;
+
+	ret = cachefiles_cull(cache, dir, args);
+
+	dput(dir);
+	_leave(" = %d", ret);
+	return ret;
+
+notdir:
+	dput(dir);
+	kerror("cull command requires dirfd to be a directory");
+	return -ENOTDIR;
+
+inval:
+	kerror("cull command requires dirfd and filename");
+	return -EINVAL;
+}
+
+/*****************************************************************************/
+/*
+ * set debugging mode
+ * - command: "debug <mask>"
+ */
+static int cachefiles_proc_debug(struct cachefiles_cache *cache, char *args)
+{
+	unsigned long mask;
+
+	_enter(",%s", args);
+
+	mask = simple_strtoul(args, &args, 0);
+
+	if (!args || !isspace(*args))
+		goto inval;
+
+	cachefiles_debug = mask;
+	_leave(" = 0");
+	return 0;
+
+inval:
+	kerror("debug command requires mask");
+	return -EINVAL;
+}
diff --git a/fs/cachefiles/cf-sysctl.c b/fs/cachefiles/cf-sysctl.c
new file mode 100644
index 000000000..4d6fc04ca
--- /dev/null
+++ b/fs/cachefiles/cf-sysctl.c
@@ -0,0 +1,69 @@
+/* cf-sysctl.c: Control parameters
+ *
+ * Copyright (C) 2006 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@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.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/sysctl.h>
+#include "internal.h"
+
+static struct ctl_table_header *cachefiles_sysctl;
+
+/*
+ * Something that isn't CTL_ANY, CTL_NONE or a value that may clash.
+ * Use the same values as fs/nfs/sysctl.c
+ */
+#define CTL_UNNUMBERED -2
+
+static ctl_table cachefiles_sysctl_table[] = {
+        {
+		.ctl_name	= CTL_UNNUMBERED,
+		.procname	= "debug",
+		.data		= &cachefiles_debug,
+		.maxlen		= sizeof(unsigned long),
+		.mode		= 0644,
+		.proc_handler	= &proc_doulongvec_minmax
+	},
+	{ .ctl_name = 0 }
+};
+
+static ctl_table cachefiles_sysctl_dir[] = {
+	{
+		.ctl_name	= CTL_UNNUMBERED,
+		.procname	= "cachefiles",
+		.maxlen		= 0,
+		.mode		= 0555,
+		.child		= cachefiles_sysctl_table
+	},
+	{ .ctl_name = 0 }
+};
+
+static ctl_table cachefiles_sysctl_root[] = {
+	{
+		.ctl_name = CTL_FS,
+		.procname = "fs",
+		.mode = 0555,
+		.child = cachefiles_sysctl_dir,
+	},
+	{ .ctl_name = 0 }
+};
+
+int __init cachefiles_sysctl_init(void)
+{
+	cachefiles_sysctl = register_sysctl_table(cachefiles_sysctl_root, 0);
+	if (!cachefiles_sysctl)
+		return -ENOMEM;
+	return 0;
+}
+
+void __exit cachefiles_sysctl_cleanup(void)
+{
+	unregister_sysctl_table(cachefiles_sysctl);
+}
diff --git a/fs/cachefiles/cf-xattr.c b/fs/cachefiles/cf-xattr.c
new file mode 100644
index 000000000..8952bf0fe
--- /dev/null
+++ b/fs/cachefiles/cf-xattr.c
@@ -0,0 +1,295 @@
+/* cf-xattr.c: CacheFiles extended attribute management
+ *
+ * Copyright (C) 2006 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@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.
+ */
+
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/file.h>
+#include <linux/fs.h>
+#include <linux/fsnotify.h>
+#include <linux/quotaops.h>
+#include <linux/xattr.h>
+#include "internal.h"
+
+static const char cachefiles_xattr_cache[] = XATTR_USER_PREFIX "CacheFiles.cache";
+
+/*****************************************************************************/
+/*
+ * check the type label on an object
+ * - done using xattrs
+ */
+int cachefiles_check_object_type(struct cachefiles_object *object)
+{
+	struct dentry *dentry = object->dentry;
+	char type[3], xtype[3];
+	int ret;
+
+	ASSERT(dentry);
+	ASSERT(dentry->d_inode);
+	ASSERT(dentry->d_inode->i_op);
+	ASSERT(dentry->d_inode->i_op->setxattr);
+	ASSERT(dentry->d_inode->i_op->getxattr);
+
+	if (!object->fscache.cookie)
+		strcpy(type, "C3");
+	else
+		snprintf(type, 3, "%02x", object->fscache.cookie->def->type);
+
+	_enter("%p{%s}", object, type);
+
+	mutex_lock(&dentry->d_inode->i_mutex);
+
+	/* attempt to install a type label directly */
+	ret = dentry->d_inode->i_op->setxattr(dentry, cachefiles_xattr_cache,
+					      type, 2, XATTR_CREATE);
+	if (ret == 0) {
+		_debug("SET");
+		fsnotify_xattr(dentry);
+		mutex_unlock(&dentry->d_inode->i_mutex);
+		goto error;
+	}
+
+	if (ret != -EEXIST) {
+		kerror("Can't set xattr on %*.*s [%lu] (err %d)",
+		       dentry->d_name.len, dentry->d_name.len,
+		       dentry->d_name.name, dentry->d_inode->i_ino,
+		       -ret);
+		goto error;
+	}
+
+	/* read the current type label */
+	ret = dentry->d_inode->i_op->getxattr(dentry, cachefiles_xattr_cache,
+					      xtype, 3);
+	if (ret < 0) {
+		if (ret == -ERANGE)
+			goto bad_type_length;
+
+		kerror("Can't read xattr on %*.*s [%lu] (err %d)",
+		       dentry->d_name.len, dentry->d_name.len,
+		       dentry->d_name.name, dentry->d_inode->i_ino,
+		       -ret);
+		goto error;
+	}
+
+	/* check the type is what we're expecting */
+	if (ret != 2)
+		goto bad_type_length;
+
+	if (xtype[0] != type[0] || xtype[1] != type[1])
+		goto bad_type;
+
+	ret = 0;
+
+error:
+	mutex_unlock(&dentry->d_inode->i_mutex);
+	_leave(" = %d", ret);
+	return ret;
+
+bad_type_length:
+	kerror("Cache object %lu type xattr length incorrect",
+	       dentry->d_inode->i_ino);
+	ret = -EIO;
+	goto error;
+
+bad_type:
+	xtype[2] = 0;
+	kerror("Cache object %*.*s [%lu] type %s not %s",
+	       dentry->d_name.len, dentry->d_name.len,
+	       dentry->d_name.name, dentry->d_inode->i_ino,
+	       xtype, type);
+	ret = -EIO;
+	goto error;
+}
+
+/*****************************************************************************/
+/*
+ * set the state xattr on a cache file
+ */
+int cachefiles_set_object_xattr(struct cachefiles_object *object,
+				struct cachefiles_xattr *auxdata)
+{
+	struct dentry *dentry = object->dentry;
+	int ret;
+
+	ASSERT(object->fscache.cookie);
+	ASSERT(dentry);
+	ASSERT(dentry->d_inode->i_op->setxattr);
+
+	_enter("%p,#%d", object, auxdata->len);
+
+	/* attempt to install the cache metadata directly */
+	mutex_lock(&dentry->d_inode->i_mutex);
+
+	_debug("SET %s #%u",
+	       object->fscache.cookie->def->name, auxdata->len);
+
+	ret = dentry->d_inode->i_op->setxattr(dentry, cachefiles_xattr_cache,
+					      &auxdata->type, auxdata->len,
+					      XATTR_CREATE);
+	if (ret == 0)
+		fsnotify_xattr(dentry);
+	else if (ret != -ENOMEM)
+		cachefiles_io_error_obj(object,
+					"Failed to set xattr with error %d",
+					ret);
+
+	mutex_unlock(&dentry->d_inode->i_mutex);
+	_leave(" = %d", ret);
+	return ret;
+}
+
+/*****************************************************************************/
+/*
+ * check the state xattr on a cache file
+ * - return -ESTALE if the object should be deleted
+ */
+int cachefiles_check_object_xattr(struct cachefiles_object *object,
+				  struct cachefiles_xattr *auxdata)
+{
+	struct cachefiles_xattr *auxbuf;
+	struct dentry *dentry = object->dentry;
+	int ret;
+
+	_enter("%p,#%d", object, auxdata->len);
+
+	ASSERT(dentry);
+	ASSERT(dentry->d_inode);
+	ASSERT(dentry->d_inode->i_op->setxattr);
+	ASSERT(dentry->d_inode->i_op->getxattr);
+
+	auxbuf = kmalloc(sizeof(struct cachefiles_xattr) + 512, GFP_KERNEL);
+	if (!auxbuf) {
+		_leave(" = -ENOMEM");
+		return -ENOMEM;
+	}
+
+	mutex_lock(&dentry->d_inode->i_mutex);
+
+	/* read the current type label */
+	ret = dentry->d_inode->i_op->getxattr(dentry, cachefiles_xattr_cache,
+					      &auxbuf->type, 512 + 1);
+	if (ret < 0) {
+		if (ret == -ENODATA)
+			goto stale; /* no attribute - power went off
+				     * mid-cull? */
+
+		if (ret == -ERANGE)
+			goto bad_type_length;
+
+		cachefiles_io_error_obj(object,
+					"can't read xattr on %lu (err %d)",
+					dentry->d_inode->i_ino, -ret);
+		goto error;
+	}
+
+	/* check the on-disk object */
+	if (ret < 1)
+		goto bad_type_length;
+
+	if (auxbuf->type != auxdata->type)
+		goto stale;
+
+	auxbuf->len = ret;
+
+	/* consult the netfs */
+	if (object->fscache.cookie->def->check_aux) {
+		fscache_checkaux_t result;
+		unsigned int dlen;
+
+		dlen = auxbuf->len - 1;
+
+		_debug("checkaux %s #%u",
+		       object->fscache.cookie->def->name, dlen);
+
+		result = object->fscache.cookie->def->check_aux(
+			object->fscache.cookie->netfs_data,
+			&auxbuf->data, dlen);
+
+		switch (result) {
+			/* entry okay as is */
+		case FSCACHE_CHECKAUX_OKAY:
+			goto okay;
+
+			/* entry requires update */
+		case FSCACHE_CHECKAUX_NEEDS_UPDATE:
+			break;
+
+			/* entry requires deletion */
+		case FSCACHE_CHECKAUX_OBSOLETE:
+			goto stale;
+
+		default:
+			BUG();
+		}
+
+		/* update the current label */
+		ret = dentry->d_inode->i_op->setxattr(dentry,
+						      cachefiles_xattr_cache,
+						      &auxdata->type,
+						      auxdata->len,
+						      XATTR_REPLACE);
+		if (ret < 0) {
+			cachefiles_io_error_obj(object,
+						"Can't update xattr on %lu"
+						" (error %d)",
+						dentry->d_inode->i_ino, -ret);
+			goto error;
+		}
+	}
+
+okay:
+	ret = 0;
+
+error:
+	mutex_unlock(&dentry->d_inode->i_mutex);
+	kfree(auxbuf);
+	_leave(" = %d", ret);
+	return ret;
+
+bad_type_length:
+	kerror("Cache object %lu xattr length incorrect",
+	       dentry->d_inode->i_ino);
+	ret = -EIO;
+	goto error;
+
+stale:
+	ret = -ESTALE;
+	goto error;
+}
+
+/*****************************************************************************/
+/*
+ * remove the object's xattr to mark it stale
+ */
+int cachefiles_remove_object_xattr(struct cachefiles_cache *cache,
+				   struct dentry *dentry)
+{
+	int ret;
+
+	mutex_lock(&dentry->d_inode->i_mutex);
+
+	ret = dentry->d_inode->i_op->removexattr(dentry,
+						 cachefiles_xattr_cache);
+
+	mutex_unlock(&dentry->d_inode->i_mutex);
+
+	if (ret < 0) {
+		if (ret == -ENOENT || ret == -ENODATA)
+			ret = 0;
+		else if (ret != -ENOMEM)
+			cachefiles_io_error(cache,
+					    "Can't remove xattr from %lu"
+					    " (error %d)",
+					    dentry->d_inode->i_ino, -ret);
+	}
+
+	_leave(" = %d", ret);
+	return ret;
+}
diff --git a/fs/cachefiles/internal.h b/fs/cachefiles/internal.h
new file mode 100644
index 000000000..edda6e776
--- /dev/null
+++ b/fs/cachefiles/internal.h
@@ -0,0 +1,308 @@
+/* internal.h: general netfs cache on cache files internal defs
+ *
+ * Copyright (C) 2006 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@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.
+ *
+ *
+ * CacheFiles layout:
+ *
+ *	/..../CacheDir/
+ *		index
+ *		0/
+ *		1/
+ *		2/
+ *		  index
+ *		  0/
+ *		  1/
+ *		  2/
+ *		    index
+ *		    0
+ *		    1
+ *		    2
+ */
+
+#include <linux/fscache-cache.h>
+#include <linux/timer.h>
+#include <linux/wait.h>
+#include <linux/workqueue.h>
+
+struct cachefiles_cache;
+struct cachefiles_object;
+
+extern unsigned long cachefiles_debug;
+#define CACHEFILES_DEBUG_KENTER	1
+#define CACHEFILES_DEBUG_KLEAVE	2
+#define CACHEFILES_DEBUG_KDEBUG	4
+
+extern struct fscache_cache_ops cachefiles_cache_ops;
+extern struct proc_dir_entry *cachefiles_proc;
+extern struct file_operations cachefiles_proc_fops;
+
+/*****************************************************************************/
+/*
+ * node records
+ */
+struct cachefiles_object {
+	struct fscache_object		fscache;	/* fscache handle */
+	struct dentry			*dentry;	/* the file/dir representing this object */
+	struct dentry			*backer;	/* backing file */
+	loff_t				i_size;		/* object size */
+	atomic_t			usage;		/* basic object usage count */
+	atomic_t			fscache_usage;	/* FSDEF object usage count */
+	uint8_t				type;		/* object type */
+	uint8_t				new;		/* T if object new */
+	spinlock_t			work_lock;
+	struct rw_semaphore		sem;
+	struct work_struct		read_work;	/* read page copier */
+	struct list_head		read_list;	/* pages to copy */
+	struct list_head		read_pend_list;	/* pages to pending read from backer */
+	struct work_struct		write_work;	/* page writer */
+	struct list_head		write_list;	/* pages to store */
+	struct rb_node			active_node;	/* link in active tree (dentry is key) */
+};
+
+extern kmem_cache_t *cachefiles_object_jar;
+
+/*****************************************************************************/
+/*
+ * Cache files cache definition
+ */
+struct cachefiles_cache {
+	struct fscache_cache		cache;		/* FS-Cache record */
+	struct vfsmount			*mnt;		/* mountpoint holding the cache */
+	struct dentry			*graveyard;	/* directory into which dead objects go */
+	struct file			*cachefilesd;	/* manager daemon handle */
+	struct rb_root			active_nodes;	/* active nodes (can't be culled) */
+	rwlock_t			active_lock;	/* lock for active_nodes */
+	atomic_t			gravecounter;	/* graveyard uniquifier */
+	unsigned			brun_percent;	/* when to stop culling (%) */
+	unsigned			bcull_percent;	/* when to start culling (%) */
+	unsigned			bstop_percent;	/* when to stop allocating (%) */
+	unsigned			bsize;		/* cache's block size */
+	unsigned			bshift;		/* min(log2 (PAGE_SIZE / bsize), 0) */
+	sector_t			brun;		/* when to stop culling */
+	sector_t			bcull;		/* when to start culling */
+	sector_t			bstop;		/* when to stop allocating */
+	unsigned long			flags;
+#define CACHEFILES_READY		0	/* T if cache prepared */
+#define CACHEFILES_DEAD			1	/* T if cache dead */
+#define CACHEFILES_CULLING		2	/* T if cull engaged */
+	char				*rootdirname;	/* name of cache root directory */
+	char				*tag;		/* cache binding tag */
+};
+
+/*****************************************************************************/
+/*
+ * backing file read tracking
+ */
+struct cachefiles_one_read {
+	wait_queue_t			monitor;	/* link into monitored waitqueue */
+	struct page			*back_page;	/* backing file page we're waiting for */
+	struct page			*netfs_page;	/* netfs page we're going to fill */
+	struct cachefiles_object	*object;
+	struct list_head		obj_link;	/* link in object's lists */
+	fscache_rw_complete_t		end_io_func;
+	void				*context;
+};
+
+/*****************************************************************************/
+/*
+ * backing file write tracking
+ */
+struct cachefiles_one_write {
+	struct page			*netfs_page;	/* netfs page to copy */
+	struct cachefiles_object	*object;
+	struct list_head		obj_link;	/* link in object's lists */
+	fscache_rw_complete_t		end_io_func;
+	void				*context;
+};
+
+/*****************************************************************************/
+/*
+ * auxiliary data xattr buffer
+ */
+struct cachefiles_xattr {
+	uint16_t			len;
+	uint8_t				type;
+	uint8_t				data[];
+};
+
+
+/* cf-bind.c */
+extern int cachefiles_proc_bind(struct cachefiles_cache *cache, char *args);
+extern void cachefiles_proc_unbind(struct cachefiles_cache *cache);
+
+/* cf-interface.c */
+extern void cachefiles_read_copier_work(void *_object);
+extern void cachefiles_write_work(void *_object);
+extern int cachefiles_has_space(struct cachefiles_cache *cache, unsigned nr);
+
+/* cf-key.c */
+extern char *cachefiles_cook_key(const u8 *raw, int keylen, uint8_t type);
+
+/* cf-namei.c */
+extern int cachefiles_delete_object(struct cachefiles_cache *cache,
+				    struct cachefiles_object *object);
+extern int cachefiles_walk_to_object(struct cachefiles_object *parent,
+				     struct cachefiles_object *object,
+				     char *key,
+				     struct cachefiles_xattr *auxdata);
+extern struct dentry *cachefiles_get_directory(struct cachefiles_cache *cache,
+					       struct dentry *dir,
+					       const char *name);
+
+extern int cachefiles_cull(struct cachefiles_cache *cache, struct dentry *dir,
+			   char *filename);
+
+/* cf-sysctl.c */
+extern int __init cachefiles_sysctl_init(void);
+extern void __exit cachefiles_sysctl_cleanup(void);
+
+/* cf-xattr.c */
+extern int cachefiles_check_object_type(struct cachefiles_object *object);
+extern int cachefiles_set_object_xattr(struct cachefiles_object *object,
+				       struct cachefiles_xattr *auxdata);
+extern int cachefiles_check_object_xattr(struct cachefiles_object *object,
+					 struct cachefiles_xattr *auxdata);
+extern int cachefiles_remove_object_xattr(struct cachefiles_cache *cache,
+					  struct dentry *dentry);
+
+
+/*****************************************************************************/
+/*
+ * error handling
+ */
+#define kerror(FMT,...) printk(KERN_ERR "CacheFiles: "FMT"\n" ,##__VA_ARGS__);
+
+#define cachefiles_io_error(___cache, FMT, ...)		\
+do {							\
+	kerror("I/O Error: " FMT ,##__VA_ARGS__);	\
+	fscache_io_error(&(___cache)->cache);		\
+	set_bit(CACHEFILES_DEAD, &(___cache)->flags);	\
+} while(0)
+
+#define cachefiles_io_error_obj(object, FMT, ...)			\
+do {									\
+	struct cachefiles_cache *___cache;				\
+									\
+	___cache = container_of((object)->fscache.cache,		\
+				struct cachefiles_cache, cache);	\
+	cachefiles_io_error(___cache, FMT ,##__VA_ARGS__);		\
+} while(0)
+
+
+/*****************************************************************************/
+/*
+ * debug tracing
+ */
+#define dbgprintk(FMT,...) \
+	printk("[%-6.6s] "FMT"\n",current->comm ,##__VA_ARGS__)
+
+/* make sure we maintain the format strings, even when debugging is disabled */
+static inline void _dbprintk(const char *fmt, ...)
+	__attribute__((format(printf,1,2)));
+static inline void _dbprintk(const char *fmt, ...)
+{
+}
+
+#define kenter(FMT,...)	dbgprintk("==> %s("FMT")",__FUNCTION__ ,##__VA_ARGS__)
+#define kleave(FMT,...)	dbgprintk("<== %s()"FMT"",__FUNCTION__ ,##__VA_ARGS__)
+#define kdebug(FMT,...)	dbgprintk(FMT ,##__VA_ARGS__)
+
+
+#if defined(__KDEBUG)
+#define _enter(FMT,...)	kenter(FMT,##__VA_ARGS__)
+#define _leave(FMT,...)	kleave(FMT,##__VA_ARGS__)
+#define _debug(FMT,...)	kdebug(FMT,##__VA_ARGS__)
+
+#elif defined(CONFIG_CACHEFILES_DEBUG)
+#define _enter(FMT,...)					\
+do {							\
+	if (cachefiles_debug & CACHEFILES_DEBUG_KENTER)	\
+		kenter(FMT,##__VA_ARGS__);		\
+} while (0)
+
+#define _leave(FMT,...)					\
+do {							\
+	if (cachefiles_debug & CACHEFILES_DEBUG_KLEAVE)	\
+		kleave(FMT,##__VA_ARGS__);		\
+} while (0)
+
+#define _debug(FMT,...)					\
+do {							\
+	if (cachefiles_debug & CACHEFILES_DEBUG_KDEBUG)	\
+		kdebug(FMT,##__VA_ARGS__);		\
+} while (0)
+
+#else
+#define _enter(FMT,...)	_dbprintk("==> %s("FMT")",__FUNCTION__ ,##__VA_ARGS__)
+#define _leave(FMT,...)	_dbprintk("<== %s()"FMT"",__FUNCTION__ ,##__VA_ARGS__)
+#define _debug(FMT,...)	_dbprintk(FMT ,##__VA_ARGS__)
+#endif
+
+#if 1 // defined(__KDEBUGALL)
+
+#define ASSERT(X)							\
+do {									\
+	if (unlikely(!(X))) {						\
+		printk(KERN_ERR "\n");					\
+		printk(KERN_ERR "CacheFiles: Assertion failed\n");	\
+		BUG();							\
+	}								\
+} while(0)
+
+#define ASSERTCMP(X, OP, Y)						\
+do {									\
+	if (unlikely(!((X) OP (Y)))) {					\
+		printk(KERN_ERR "\n");					\
+		printk(KERN_ERR "CacheFiles: Assertion failed\n");	\
+		printk(KERN_ERR "%lx " #OP " %lx is false\n",		\
+		       (unsigned long)(X), (unsigned long)(Y));		\
+		BUG();							\
+	}								\
+} while(0)
+
+#define ASSERTIF(C, X)							\
+do {									\
+	if (unlikely((C) && !(X))) {					\
+		printk(KERN_ERR "\n");					\
+		printk(KERN_ERR "CacheFiles: Assertion failed\n");	\
+		BUG();							\
+	}								\
+} while(0)
+
+#define ASSERTIFCMP(C, X, OP, Y)					\
+do {									\
+	if (unlikely((C) && !((X) OP (Y)))) {				\
+		printk(KERN_ERR "\n");					\
+		printk(KERN_ERR "CacheFiles: Assertion failed\n");	\
+		printk(KERN_ERR "%lx " #OP " %lx is false\n",		\
+		       (unsigned long)(X), (unsigned long)(Y));		\
+		BUG();							\
+	}								\
+} while(0)
+
+#else
+
+#define ASSERT(X)				\
+do {						\
+} while(0)
+
+#define ASSERTCMP(X, OP, Y)			\
+do {						\
+} while(0)
+
+#define ASSERTIF(C, X)				\
+do {						\
+} while(0)
+
+#define ASSERTIFCMP(C, X, OP, Y)		\
+do {						\
+} while(0)
+
+#endif
diff --git a/fs/cifs/sess.c b/fs/cifs/sess.c
new file mode 100644
index 000000000..d1705ab81
--- /dev/null
+++ b/fs/cifs/sess.c
@@ -0,0 +1,538 @@
+/*
+ *   fs/cifs/sess.c
+ *
+ *   SMB/CIFS session setup handling routines
+ *
+ *   Copyright (c) International Business Machines  Corp., 2006
+ *   Author(s): Steve French (sfrench@us.ibm.com)
+ *
+ *   This library is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU Lesser General Public License as published
+ *   by the Free Software Foundation; either version 2.1 of the License, or
+ *   (at your option) any later version.
+ *
+ *   This library 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 Lesser General Public License for more details.
+ *
+ *   You should have received a copy of the GNU Lesser General Public License
+ *   along with this library; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "cifspdu.h"
+#include "cifsglob.h"
+#include "cifsproto.h"
+#include "cifs_unicode.h"
+#include "cifs_debug.h"
+#include "ntlmssp.h"
+#include "nterr.h"
+#include <linux/utsname.h>
+
+extern void SMBNTencrypt(unsigned char *passwd, unsigned char *c8,
+                         unsigned char *p24);
+
+static __u32 cifs_ssetup_hdr(struct cifsSesInfo *ses, SESSION_SETUP_ANDX *pSMB)
+{
+	__u32 capabilities = 0;
+
+	/* init fields common to all four types of SessSetup */
+	/* note that header is initialized to zero in header_assemble */
+	pSMB->req.AndXCommand = 0xFF;
+	pSMB->req.MaxBufferSize = cpu_to_le16(ses->server->maxBuf);
+	pSMB->req.MaxMpxCount = cpu_to_le16(ses->server->maxReq);
+
+	/* Now no need to set SMBFLG_CASELESS or obsolete CANONICAL PATH */
+
+	/* BB verify whether signing required on neg or just on auth frame 
+	   (and NTLM case) */
+
+	capabilities = CAP_LARGE_FILES | CAP_NT_SMBS | CAP_LEVEL_II_OPLOCKS |
+			CAP_LARGE_WRITE_X | CAP_LARGE_READ_X;
+
+	if(ses->server->secMode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
+		pSMB->req.hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
+
+	if (ses->capabilities & CAP_UNICODE) {
+		pSMB->req.hdr.Flags2 |= SMBFLG2_UNICODE;
+		capabilities |= CAP_UNICODE;
+	}
+	if (ses->capabilities & CAP_STATUS32) {
+		pSMB->req.hdr.Flags2 |= SMBFLG2_ERR_STATUS;
+		capabilities |= CAP_STATUS32;
+	}
+	if (ses->capabilities & CAP_DFS) {
+		pSMB->req.hdr.Flags2 |= SMBFLG2_DFS;
+		capabilities |= CAP_DFS;
+	}
+	if (ses->capabilities & CAP_UNIX) {
+		capabilities |= CAP_UNIX;
+	}
+
+	/* BB check whether to init vcnum BB */
+	return capabilities;
+}
+
+static void unicode_ssetup_strings(char ** pbcc_area, struct cifsSesInfo *ses,
+			    const struct nls_table * nls_cp)
+{
+	char * bcc_ptr = *pbcc_area;
+	int bytes_ret = 0;
+
+	/* BB FIXME add check that strings total less
+	than 335 or will need to send them as arrays */
+
+	/* unicode strings, must be word aligned before the call */
+/*	if ((long) bcc_ptr % 2)	{
+		*bcc_ptr = 0;
+		bcc_ptr++;
+	} */
+	/* copy user */
+	if(ses->userName == NULL) {
+		/* BB what about null user mounts - check that we do this BB */
+	} else { /* 300 should be long enough for any conceivable user name */
+		bytes_ret = cifs_strtoUCS((__le16 *) bcc_ptr, ses->userName,
+					  300, nls_cp);
+	}
+	bcc_ptr += 2 * bytes_ret;
+	bcc_ptr += 2; /* account for null termination */
+	/* copy domain */
+	if(ses->domainName == NULL)
+		bytes_ret = cifs_strtoUCS((__le16 *) bcc_ptr,
+					  "CIFS_LINUX_DOM", 32, nls_cp);
+	else
+		bytes_ret = cifs_strtoUCS((__le16 *) bcc_ptr, ses->domainName, 
+					  256, nls_cp);
+	bcc_ptr += 2 * bytes_ret;
+	bcc_ptr += 2;  /* account for null terminator */
+
+	/* Copy OS version */
+	bytes_ret = cifs_strtoUCS((__le16 *)bcc_ptr, "Linux version ", 32,
+				  nls_cp);
+	bcc_ptr += 2 * bytes_ret;
+	bytes_ret = cifs_strtoUCS((__le16 *) bcc_ptr, system_utsname.release,
+				  32, nls_cp);
+	bcc_ptr += 2 * bytes_ret;
+	bcc_ptr += 2; /* trailing null */
+
+	bytes_ret = cifs_strtoUCS((__le16 *) bcc_ptr, CIFS_NETWORK_OPSYS,
+                                  32, nls_cp);
+	bcc_ptr += 2 * bytes_ret;
+	bcc_ptr += 2; /* trailing null */
+
+	*pbcc_area = bcc_ptr;
+}
+
+static void ascii_ssetup_strings(char ** pbcc_area, struct cifsSesInfo *ses,
+			  const struct nls_table * nls_cp)
+{
+	char * bcc_ptr = *pbcc_area;
+
+	/* copy user */
+	/* BB what about null user mounts - check that we do this BB */
+        /* copy user */
+        if(ses->userName == NULL) {
+                /* BB what about null user mounts - check that we do this BB */
+        } else { /* 300 should be long enough for any conceivable user name */
+                strncpy(bcc_ptr, ses->userName, 300);
+        }
+	/* BB improve check for overflow */
+        bcc_ptr += strnlen(ses->userName, 300);
+	*bcc_ptr = 0;
+        bcc_ptr++; /* account for null termination */
+
+        /* copy domain */
+	
+        if(ses->domainName == NULL) {
+                strcpy(bcc_ptr, "CIFS_LINUX_DOM");
+		bcc_ptr += 14;  /* strlen(CIFS_LINUX_DOM) */
+ 	} else {
+                strncpy(bcc_ptr, ses->domainName, 256); 
+		bcc_ptr += strnlen(ses->domainName, 256);
+	}
+	*bcc_ptr = 0;
+	bcc_ptr++;
+
+	/* BB check for overflow here */
+
+	strcpy(bcc_ptr, "Linux version ");
+	bcc_ptr += strlen("Linux version ");
+	strcpy(bcc_ptr, system_utsname.release);
+	bcc_ptr += strlen(system_utsname.release) + 1;
+
+	strcpy(bcc_ptr, CIFS_NETWORK_OPSYS);
+	bcc_ptr += strlen(CIFS_NETWORK_OPSYS) + 1;
+
+        *pbcc_area = bcc_ptr;
+}
+
+static int decode_unicode_ssetup(char ** pbcc_area, int bleft, struct cifsSesInfo *ses,
+                            const struct nls_table * nls_cp)
+{
+	int rc = 0;
+	int words_left, len;
+	char * data = *pbcc_area;
+
+
+
+	cFYI(1,("bleft %d",bleft));
+
+
+	/* word align, if bytes remaining is not even */
+	if(bleft % 2) {
+		bleft--;
+		data++;
+	}
+	words_left = bleft / 2;
+
+	/* save off server operating system */
+	len = UniStrnlen((wchar_t *) data, words_left);
+
+/* We look for obvious messed up bcc or strings in response so we do not go off
+   the end since (at least) WIN2K and Windows XP have a major bug in not null
+   terminating last Unicode string in response  */
+	if(len >= words_left)
+		return rc;
+
+	if(ses->serverOS)
+		kfree(ses->serverOS);
+	/* UTF-8 string will not grow more than four times as big as UCS-16 */
+	ses->serverOS = kzalloc(4 * len, GFP_KERNEL);
+	if(ses->serverOS != NULL) {
+		cifs_strfromUCS_le(ses->serverOS, (__le16 *)data, len,
+				   nls_cp);
+	}
+	data += 2 * (len + 1);
+	words_left -= len + 1;
+
+	/* save off server network operating system */
+	len = UniStrnlen((wchar_t *) data, words_left);
+
+	if(len >= words_left)
+		return rc;
+
+	if(ses->serverNOS)
+		kfree(ses->serverNOS);
+	ses->serverNOS = kzalloc(4 * len, GFP_KERNEL); /* BB this is wrong length FIXME BB */
+	if(ses->serverNOS != NULL) {
+		cifs_strfromUCS_le(ses->serverNOS, (__le16 *)data, len,
+				   nls_cp);
+		if(strncmp(ses->serverNOS, "NT LAN Manager 4",16) == 0) {
+			cFYI(1,("NT4 server"));
+			ses->flags |= CIFS_SES_NT4;
+		}
+	}
+	data += 2 * (len + 1);
+	words_left -= len + 1;
+
+        /* save off server domain */
+        len = UniStrnlen((wchar_t *) data, words_left);
+
+        if(len > words_left)
+                return rc;
+
+        if(ses->serverDomain)
+                kfree(ses->serverDomain);
+        ses->serverDomain = kzalloc(2 * (len + 1), GFP_KERNEL); /* BB FIXME wrong length */
+        if(ses->serverDomain != NULL) {
+                cifs_strfromUCS_le(ses->serverDomain, (__le16 *)data, len,
+                                   nls_cp);
+                ses->serverDomain[2*len] = 0;
+                ses->serverDomain[(2*len) + 1] = 0;
+        }
+        data += 2 * (len + 1);
+        words_left -= len + 1;
+	
+	cFYI(1,("words left: %d",words_left));
+
+	return rc;
+}
+
+static int decode_ascii_ssetup(char ** pbcc_area, int bleft, struct cifsSesInfo *ses,
+                            const struct nls_table * nls_cp)
+{
+	int rc = 0;
+	int len;
+	char * bcc_ptr = *pbcc_area;
+
+	cFYI(1,("decode sessetup ascii. bleft %d", bleft));
+	
+	len = strnlen(bcc_ptr, bleft);
+	if(len >= bleft)
+		return rc;
+	
+	if(ses->serverOS)
+		kfree(ses->serverOS);
+
+	ses->serverOS = kzalloc(len + 1, GFP_KERNEL);
+	if(ses->serverOS)
+		strncpy(ses->serverOS, bcc_ptr, len);
+
+	bcc_ptr += len + 1;
+	bleft -= len + 1;
+
+	len = strnlen(bcc_ptr, bleft);
+	if(len >= bleft)
+		return rc;
+
+	if(ses->serverNOS)
+		kfree(ses->serverNOS);
+
+	ses->serverNOS = kzalloc(len + 1, GFP_KERNEL);
+	if(ses->serverNOS)
+		strncpy(ses->serverNOS, bcc_ptr, len);
+
+	bcc_ptr += len + 1;
+	bleft -= len + 1;
+
+        len = strnlen(bcc_ptr, bleft);
+        if(len > bleft)
+                return rc;
+
+        if(ses->serverDomain)
+                kfree(ses->serverDomain);
+
+        ses->serverDomain = kzalloc(len + 1, GFP_KERNEL);
+        if(ses->serverOS)
+                strncpy(ses->serverOS, bcc_ptr, len);
+
+        bcc_ptr += len + 1;
+	bleft -= len + 1;
+
+	cFYI(1,("ascii: bytes left %d",bleft));
+
+	return rc;
+}
+
+int 
+CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, int first_time,
+		const struct nls_table *nls_cp)
+{
+	int rc = 0;
+	int wct;
+	struct smb_hdr *smb_buf;
+	char *bcc_ptr;
+	char *str_area;
+	SESSION_SETUP_ANDX *pSMB;
+	__u32 capabilities;
+	int count;
+	int resp_buf_type = 0;
+	struct kvec iov[2];
+	enum securityEnum type;
+	__u16 action;
+	int bytes_remaining;
+
+	if(ses == NULL)
+		return -EINVAL;
+
+	type = ses->server->secType;
+
+	cFYI(1,("sess setup type %d",type));
+	if(type == LANMAN) {
+#ifndef CONFIG_CIFS_WEAK_PW_HASH
+		/* LANMAN and plaintext are less secure and off by default.
+		So we make this explicitly be turned on in kconfig (in the
+		build) and turned on at runtime (changed from the default)
+		in proc/fs/cifs or via mount parm.  Unfortunately this is
+		needed for old Win (e.g. Win95), some obscure NAS and OS/2 */
+		return -EOPNOTSUPP;
+#endif
+		wct = 10; /* lanman 2 style sessionsetup */
+	} else if((type == NTLM) || (type == NTLMv2)) { 
+		/* For NTLMv2 failures eventually may need to retry NTLM */
+		wct = 13; /* old style NTLM sessionsetup */
+	} else /* same size for negotiate or auth, NTLMSSP or extended security */
+		wct = 12;
+
+	rc = small_smb_init_no_tc(SMB_COM_SESSION_SETUP_ANDX, wct, ses,
+			    (void **)&smb_buf);
+	if(rc)
+		return rc;
+
+	pSMB = (SESSION_SETUP_ANDX *)smb_buf;
+
+	capabilities = cifs_ssetup_hdr(ses, pSMB);
+
+	/* we will send the SMB in two pieces,
+	a fixed length beginning part, and a
+	second part which will include the strings
+	and rest of bcc area, in order to avoid having
+	to do a large buffer 17K allocation */
+        iov[0].iov_base = (char *)pSMB;
+        iov[0].iov_len = smb_buf->smb_buf_length + 4;
+
+	/* 2000 big enough to fit max user, domain, NOS name etc. */
+	str_area = kmalloc(2000, GFP_KERNEL);
+	bcc_ptr = str_area;
+
+	if(type == LANMAN) {
+#ifdef CONFIG_CIFS_WEAK_PW_HASH
+		char lnm_session_key[CIFS_SESS_KEY_SIZE];
+
+		/* no capabilities flags in old lanman negotiation */
+
+		pSMB->old_req.PasswordLength = cpu_to_le16(CIFS_SESS_KEY_SIZE); 
+		/* BB calculate hash with password */
+		/* and copy into bcc */
+
+		calc_lanman_hash(ses, lnm_session_key);
+
+/* #ifdef CONFIG_CIFS_DEBUG2
+		cifs_dump_mem("cryptkey: ",ses->server->cryptKey,
+			CIFS_SESS_KEY_SIZE);
+#endif */
+		memcpy(bcc_ptr, (char *)lnm_session_key, CIFS_SESS_KEY_SIZE);
+		bcc_ptr += CIFS_SESS_KEY_SIZE;
+
+		/* can not sign if LANMAN negotiated so no need
+		to calculate signing key? but what if server
+		changed to do higher than lanman dialect and
+		we reconnected would we ever calc signing_key? */
+
+		cFYI(1,("Negotiating LANMAN setting up strings"));
+		/* Unicode not allowed for LANMAN dialects */
+		ascii_ssetup_strings(&bcc_ptr, ses, nls_cp);
+#endif    
+	} else if (type == NTLM) {
+		char ntlm_session_key[CIFS_SESS_KEY_SIZE];
+
+		pSMB->req_no_secext.Capabilities = cpu_to_le32(capabilities);
+		pSMB->req_no_secext.CaseInsensitivePasswordLength =
+			cpu_to_le16(CIFS_SESS_KEY_SIZE);
+		pSMB->req_no_secext.CaseSensitivePasswordLength =
+			cpu_to_le16(CIFS_SESS_KEY_SIZE);
+	
+		/* calculate session key */
+		SMBNTencrypt(ses->password, ses->server->cryptKey,
+			     ntlm_session_key);
+
+		if(first_time) /* should this be moved into common code 
+				  with similar ntlmv2 path? */
+			cifs_calculate_mac_key(ses->server->mac_signing_key,
+				ntlm_session_key, ses->password);
+		/* copy session key */
+
+		memcpy(bcc_ptr, (char *)ntlm_session_key,CIFS_SESS_KEY_SIZE);
+		bcc_ptr += CIFS_SESS_KEY_SIZE;
+		memcpy(bcc_ptr, (char *)ntlm_session_key,CIFS_SESS_KEY_SIZE);
+		bcc_ptr += CIFS_SESS_KEY_SIZE;
+		if(ses->capabilities & CAP_UNICODE) {
+			/* unicode strings must be word aligned */
+			if (iov[0].iov_len % 2) {
+				*bcc_ptr = 0;
+				bcc_ptr++;		
+			}	
+			unicode_ssetup_strings(&bcc_ptr, ses, nls_cp);
+		} else
+			ascii_ssetup_strings(&bcc_ptr, ses, nls_cp);
+	} else if (type == NTLMv2) {
+		char * v2_sess_key = 
+			kmalloc(sizeof(struct ntlmv2_resp), GFP_KERNEL);
+
+		/* BB FIXME change all users of v2_sess_key to
+		   struct ntlmv2_resp */
+
+		if(v2_sess_key == NULL) {
+			cifs_small_buf_release(smb_buf);
+			return -ENOMEM;
+		}
+
+		pSMB->req_no_secext.Capabilities = cpu_to_le32(capabilities);
+
+		/* LM2 password would be here if we supported it */
+		pSMB->req_no_secext.CaseInsensitivePasswordLength = 0;
+		/*	cpu_to_le16(LM2_SESS_KEY_SIZE); */
+
+		pSMB->req_no_secext.CaseSensitivePasswordLength =
+			cpu_to_le16(sizeof(struct ntlmv2_resp));
+
+		/* calculate session key */
+		setup_ntlmv2_rsp(ses, v2_sess_key, nls_cp);
+		if(first_time) /* should this be moved into common code
+			          with similar ntlmv2 path? */
+		/*   cifs_calculate_ntlmv2_mac_key(ses->server->mac_signing_key,
+				response BB FIXME, v2_sess_key); */
+
+		/* copy session key */
+
+	/*	memcpy(bcc_ptr, (char *)ntlm_session_key,LM2_SESS_KEY_SIZE);
+		bcc_ptr += LM2_SESS_KEY_SIZE; */
+		memcpy(bcc_ptr, (char *)v2_sess_key, sizeof(struct ntlmv2_resp));
+		bcc_ptr += sizeof(struct ntlmv2_resp);
+		kfree(v2_sess_key);
+		if(ses->capabilities & CAP_UNICODE) {
+			if(iov[0].iov_len % 2) {
+				*bcc_ptr = 0;
+			}	bcc_ptr++;
+			unicode_ssetup_strings(&bcc_ptr, ses, nls_cp);
+		} else
+			ascii_ssetup_strings(&bcc_ptr, ses, nls_cp);
+	} else /* NTLMSSP or SPNEGO */ {
+		pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC;
+		capabilities |= CAP_EXTENDED_SECURITY;
+		pSMB->req.Capabilities = cpu_to_le32(capabilities);
+		/* BB set password lengths */
+	}
+
+	count = (long) bcc_ptr - (long) str_area;
+	smb_buf->smb_buf_length += count;
+
+	BCC_LE(smb_buf) = cpu_to_le16(count);
+
+	iov[1].iov_base = str_area;
+	iov[1].iov_len = count; 
+	rc = SendReceive2(xid, ses, iov, 2 /* num_iovecs */, &resp_buf_type, 0);
+	/* SMB request buf freed in SendReceive2 */
+
+	cFYI(1,("ssetup rc from sendrecv2 is %d",rc));
+	if(rc)
+		goto ssetup_exit;
+
+	pSMB = (SESSION_SETUP_ANDX *)iov[0].iov_base;
+	smb_buf = (struct smb_hdr *)iov[0].iov_base;
+
+	if((smb_buf->WordCount != 3) && (smb_buf->WordCount != 4)) {
+		rc = -EIO;
+		cERROR(1,("bad word count %d", smb_buf->WordCount));
+		goto ssetup_exit;
+	}
+	action = le16_to_cpu(pSMB->resp.Action);
+	if (action & GUEST_LOGIN)
+		cFYI(1, ("Guest login")); /* BB mark SesInfo struct? */
+	ses->Suid = smb_buf->Uid;   /* UID left in wire format (le) */
+	cFYI(1, ("UID = %d ", ses->Suid));
+	/* response can have either 3 or 4 word count - Samba sends 3 */
+	/* and lanman response is 3 */
+	bytes_remaining = BCC(smb_buf);
+	bcc_ptr = pByteArea(smb_buf);
+
+	if(smb_buf->WordCount == 4) {
+		__u16 blob_len;
+		blob_len = le16_to_cpu(pSMB->resp.SecurityBlobLength);
+		bcc_ptr += blob_len;
+		if(blob_len > bytes_remaining) {
+			cERROR(1,("bad security blob length %d", blob_len));
+			rc = -EINVAL;
+			goto ssetup_exit;
+		}
+		bytes_remaining -= blob_len;
+	}	
+
+	/* BB check if Unicode and decode strings */
+	if(smb_buf->Flags2 & SMBFLG2_UNICODE)
+		rc = decode_unicode_ssetup(&bcc_ptr, bytes_remaining,
+						   ses, nls_cp);
+	else
+		rc = decode_ascii_ssetup(&bcc_ptr, bytes_remaining, ses,nls_cp);
+	
+ssetup_exit:
+	kfree(str_area);
+	if(resp_buf_type == CIFS_SMALL_BUFFER) {
+		cFYI(1,("ssetup freeing small buf %p", iov[0].iov_base));
+		cifs_small_buf_release(iov[0].iov_base);
+	} else if(resp_buf_type == CIFS_LARGE_BUFFER)
+		cifs_buf_release(iov[0].iov_base);
+
+	return rc;
+}
diff --git a/fs/fscache/Makefile b/fs/fscache/Makefile
new file mode 100644
index 000000000..10f17a38f
--- /dev/null
+++ b/fs/fscache/Makefile
@@ -0,0 +1,11 @@
+#
+# Makefile for general filesystem caching code
+#
+
+fscache-objs := \
+	cookie.o \
+	fsdef.o \
+	main.o \
+	page.o
+
+obj-$(CONFIG_FSCACHE) := fscache.o
diff --git a/fs/fscache/cookie.c b/fs/fscache/cookie.c
new file mode 100644
index 000000000..9a6ac8b70
--- /dev/null
+++ b/fs/fscache/cookie.c
@@ -0,0 +1,1045 @@
+/* cookie.c: general filesystem cache cookie management
+ *
+ * Copyright (C) 2004-5 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@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.
+ */
+
+#include <linux/module.h>
+#include "fscache-int.h"
+
+static LIST_HEAD(fscache_cache_tag_list);
+static LIST_HEAD(fscache_cache_list);
+static LIST_HEAD(fscache_netfs_list);
+static DECLARE_RWSEM(fscache_addremove_sem);
+static struct fscache_cache_tag fscache_nomem_tag;
+
+kmem_cache_t *fscache_cookie_jar;
+
+static void fscache_withdraw_object(struct fscache_cache *cache,
+				    struct fscache_object *object);
+
+static void __fscache_cookie_put(struct fscache_cookie *cookie);
+
+static inline void fscache_cookie_put(struct fscache_cookie *cookie)
+{
+	/* check to see whether the cookie has already been released by looking
+	 * for the poison when slab debugging is on */
+#ifdef CONFIG_DEBUG_SLAB
+	BUG_ON((atomic_read(&cookie->usage) & 0xffff0000) == 0x6b6b0000);
+#endif
+
+	BUG_ON(atomic_read(&cookie->usage) <= 0);
+
+	if (atomic_dec_and_test(&cookie->usage))
+		__fscache_cookie_put(cookie);
+
+}
+
+/*****************************************************************************/
+/*
+ * look up a cache tag
+ */
+struct fscache_cache_tag *__fscache_lookup_cache_tag(const char *name)
+{
+	struct fscache_cache_tag *tag, *xtag;
+
+	/* firstly check for the existence of the tag under read lock */
+	down_read(&fscache_addremove_sem);
+
+	list_for_each_entry(tag, &fscache_cache_tag_list, link) {
+		if (strcmp(tag->name, name) == 0) {
+			atomic_inc(&tag->usage);
+			up_read(&fscache_addremove_sem);
+			return tag;
+		}
+	}
+
+	up_read(&fscache_addremove_sem);
+
+	/* the tag does not exist - create a candidate */
+	xtag = kmalloc(sizeof(*xtag) + strlen(name) + 1, GFP_KERNEL);
+	if (!xtag)
+		/* return a dummy tag if out of memory */
+		return &fscache_nomem_tag;
+
+	atomic_set(&xtag->usage, 1);
+	strcpy(xtag->name, name);
+
+	/* write lock, search again and add if still not present */
+	down_write(&fscache_addremove_sem);
+
+	list_for_each_entry(tag, &fscache_cache_tag_list, link) {
+		if (strcmp(tag->name, name) == 0) {
+			atomic_inc(&tag->usage);
+			up_write(&fscache_addremove_sem);
+			kfree(xtag);
+			return tag;
+		}
+	}
+
+	list_add_tail(&xtag->link, &fscache_cache_tag_list);
+	up_write(&fscache_addremove_sem);
+	return xtag;
+}
+
+/*****************************************************************************/
+/*
+ * release a reference to a cache tag
+ */
+void __fscache_release_cache_tag(struct fscache_cache_tag *tag)
+{
+	if (tag != &fscache_nomem_tag) {
+		down_write(&fscache_addremove_sem);
+
+		if (atomic_dec_and_test(&tag->usage))
+			list_del_init(&tag->link);
+		else
+			tag = NULL;
+
+		up_write(&fscache_addremove_sem);
+
+		kfree(tag);
+	}
+}
+
+/*****************************************************************************/
+/*
+ * register a network filesystem for caching
+ */
+int __fscache_register_netfs(struct fscache_netfs *netfs)
+{
+	struct fscache_netfs *ptr;
+	int ret;
+
+	_enter("{%s}", netfs->name);
+
+	INIT_LIST_HEAD(&netfs->link);
+
+	/* allocate a cookie for the primary index */
+	netfs->primary_index =
+		kmem_cache_zalloc(fscache_cookie_jar, SLAB_KERNEL);
+
+	if (!netfs->primary_index) {
+		_leave(" = -ENOMEM");
+		return -ENOMEM;
+	}
+
+	/* initialise the primary index cookie */
+	atomic_set(&netfs->primary_index->usage, 1);
+	atomic_set(&netfs->primary_index->children, 0);
+
+	netfs->primary_index->def		= &fscache_fsdef_netfs_def;
+	netfs->primary_index->parent		= &fscache_fsdef_index;
+	netfs->primary_index->netfs		= netfs;
+	netfs->primary_index->netfs_data	= netfs;
+
+	atomic_inc(&netfs->primary_index->parent->usage);
+	atomic_inc(&netfs->primary_index->parent->children);
+
+	init_rwsem(&netfs->primary_index->sem);
+	INIT_HLIST_HEAD(&netfs->primary_index->backing_objects);
+
+	/* check the netfs type is not already present */
+	down_write(&fscache_addremove_sem);
+
+	ret = -EEXIST;
+	list_for_each_entry(ptr, &fscache_netfs_list, link) {
+		if (strcmp(ptr->name, netfs->name) == 0)
+			goto already_registered;
+	}
+
+	list_add(&netfs->link, &fscache_netfs_list);
+	ret = 0;
+
+	printk("FS-Cache: netfs '%s' registered for caching\n", netfs->name);
+
+already_registered:
+	up_write(&fscache_addremove_sem);
+
+	if (ret < 0) {
+		netfs->primary_index->parent = NULL;
+		__fscache_cookie_put(netfs->primary_index);
+		netfs->primary_index = NULL;
+	}
+
+	_leave(" = %d", ret);
+	return ret;
+}
+
+EXPORT_SYMBOL(__fscache_register_netfs);
+
+/*****************************************************************************/
+/*
+ * unregister a network filesystem from the cache
+ * - all cookies must have been released first
+ */
+void __fscache_unregister_netfs(struct fscache_netfs *netfs)
+{
+	_enter("{%s.%u}", netfs->name, netfs->version);
+
+	down_write(&fscache_addremove_sem);
+
+	list_del(&netfs->link);
+	fscache_relinquish_cookie(netfs->primary_index, 0);
+
+	up_write(&fscache_addremove_sem);
+
+	printk("FS-Cache: netfs '%s' unregistered from caching\n",
+	       netfs->name);
+
+	_leave("");
+}
+
+EXPORT_SYMBOL(__fscache_unregister_netfs);
+
+/*****************************************************************************/
+/*
+ * initialise a cache record
+ */
+void fscache_init_cache(struct fscache_cache *cache,
+			struct fscache_cache_ops *ops,
+			const char *idfmt,
+			...)
+{
+	va_list va;
+
+	memset(cache, 0, sizeof(*cache));
+
+	cache->ops = ops;
+
+	va_start(va, idfmt);
+	vsnprintf(cache->identifier, sizeof(cache->identifier), idfmt, va);
+	va_end(va);
+
+	INIT_LIST_HEAD(&cache->link);
+	INIT_LIST_HEAD(&cache->object_list);
+	spin_lock_init(&cache->object_list_lock);
+	init_rwsem(&cache->withdrawal_sem);
+}
+
+EXPORT_SYMBOL(fscache_init_cache);
+
+/*****************************************************************************/
+/*
+ * declare a mounted cache as being open for business
+ */
+int fscache_add_cache(struct fscache_cache *cache,
+		      struct fscache_object *ifsdef,
+		      const char *tagname)
+{
+	struct fscache_cache_tag *tag;
+
+	BUG_ON(!cache->ops);
+	BUG_ON(!ifsdef);
+
+	cache->flags = 0;
+
+	if (!tagname)
+		tagname = cache->identifier;
+
+	BUG_ON(!tagname[0]);
+
+	_enter("{%s.%s},,%s", cache->ops->name, cache->identifier, tagname);
+
+	if (!cache->ops->grab_object(ifsdef))
+		BUG();
+
+	ifsdef->cookie = &fscache_fsdef_index;
+	ifsdef->cache = cache;
+	cache->fsdef = ifsdef;
+
+	down_write(&fscache_addremove_sem);
+
+	/* instantiate or allocate a cache tag */
+	list_for_each_entry(tag, &fscache_cache_tag_list, link) {
+		if (strcmp(tag->name, tagname) == 0) {
+			if (tag->cache) {
+				printk(KERN_ERR
+				       "FS-Cache: cache tag '%s' already in use\n",
+				       tagname);
+				up_write(&fscache_addremove_sem);
+				return -EEXIST;
+			}
+
+			atomic_inc(&tag->usage);
+			goto found_cache_tag;
+		}
+	}
+
+	tag = kmalloc(sizeof(*tag) + strlen(tagname) + 1, GFP_KERNEL);
+	if (!tag) {
+		up_write(&fscache_addremove_sem);
+		return -ENOMEM;
+	}
+
+	atomic_set(&tag->usage, 1);
+	strcpy(tag->name, tagname);
+	list_add_tail(&tag->link, &fscache_cache_tag_list);
+
+found_cache_tag:
+	tag->cache = cache;
+	cache->tag = tag;
+
+	/* add the cache to the list */
+	list_add(&cache->link, &fscache_cache_list);
+
+	/* add the cache's netfs definition index object to the cache's
+	 * list */
+	spin_lock(&cache->object_list_lock);
+	list_add_tail(&ifsdef->cache_link, &cache->object_list);
+	spin_unlock(&cache->object_list_lock);
+
+	/* add the cache's netfs definition index object to the top level index
+	 * cookie as a known backing object */
+	down_write(&fscache_fsdef_index.sem);
+
+	hlist_add_head(&ifsdef->cookie_link,
+		       &fscache_fsdef_index.backing_objects);
+
+	atomic_inc(&fscache_fsdef_index.usage);
+
+	/* done */
+	up_write(&fscache_fsdef_index.sem);
+	up_write(&fscache_addremove_sem);
+
+	printk(KERN_NOTICE
+	       "FS-Cache: Cache \"%s\" added (type %s)\n",
+	       cache->tag->name, cache->ops->name);
+
+	_leave(" = 0 [%s]", cache->identifier);
+	return 0;
+}
+
+EXPORT_SYMBOL(fscache_add_cache);
+
+/*****************************************************************************/
+/*
+ * note a cache I/O error
+ */
+void fscache_io_error(struct fscache_cache *cache)
+{
+	set_bit(FSCACHE_IOERROR, &cache->flags);
+
+	printk(KERN_ERR "FS-Cache: Cache %s stopped due to I/O error\n",
+	       cache->ops->name);
+}
+
+EXPORT_SYMBOL(fscache_io_error);
+
+/*****************************************************************************/
+/*
+ * withdraw an unmounted cache from the active service
+ */
+void fscache_withdraw_cache(struct fscache_cache *cache)
+{
+	struct fscache_object *object;
+
+	_enter("");
+
+	printk(KERN_NOTICE
+	       "FS-Cache: Withdrawing cache \"%s\"\n",
+	       cache->tag->name);
+
+	/* make the cache unavailable for cookie acquisition */
+	down_write(&cache->withdrawal_sem);
+
+	down_write(&fscache_addremove_sem);
+	list_del_init(&cache->link);
+	cache->tag->cache = NULL;
+	up_write(&fscache_addremove_sem);
+
+	/* mark all objects as being withdrawn */
+	spin_lock(&cache->object_list_lock);
+	list_for_each_entry(object, &cache->object_list, cache_link) {
+		set_bit(FSCACHE_OBJECT_WITHDRAWN, &object->flags);
+	}
+	spin_unlock(&cache->object_list_lock);
+
+	/* make sure all pages pinned by operations on behalf of the netfs are
+	 * written to disc */
+	cache->ops->sync_cache(cache);
+
+	/* dissociate all the netfs pages backed by this cache from the block
+	 * mappings in the cache */
+	cache->ops->dissociate_pages(cache);
+
+	/* we now have to destroy all the active objects pertaining to this
+	 * cache */
+	spin_lock(&cache->object_list_lock);
+
+	while (!list_empty(&cache->object_list)) {
+		object = list_entry(cache->object_list.next,
+				    struct fscache_object, cache_link);
+		list_del_init(&object->cache_link);
+		spin_unlock(&cache->object_list_lock);
+
+		_debug("withdraw %p", object->cookie);
+
+		/* we've extracted an active object from the tree - now dispose
+		 * of it */
+		fscache_withdraw_object(cache, object);
+
+		spin_lock(&cache->object_list_lock);
+	}
+
+	spin_unlock(&cache->object_list_lock);
+
+	fscache_release_cache_tag(cache->tag);
+	cache->tag = NULL;
+
+	_leave("");
+}
+
+EXPORT_SYMBOL(fscache_withdraw_cache);
+
+/*****************************************************************************/
+/*
+ * withdraw an object from active service at the behest of the cache
+ * - need break the links to a cached object cookie
+ * - called under two situations:
+ *   (1) recycler decides to reclaim an in-use object
+ *   (2) a cache is unmounted
+ * - have to take care as the cookie can be being relinquished by the netfs
+ *   simultaneously
+ * - the active object is pinned by the caller holding a refcount on it
+ */
+static void fscache_withdraw_object(struct fscache_cache *cache,
+				    struct fscache_object *object)
+{
+	struct fscache_cookie *cookie, *xcookie = NULL;
+
+	_enter(",%p", object);
+
+	/* first of all we have to break the links between the object and the
+	 * cookie
+	 * - we have to hold both semaphores BUT we have to get the cookie sem
+	 *   FIRST
+	 */
+	cache->ops->lock_object(object);
+
+	cookie = object->cookie;
+	if (cookie) {
+		/* pin the cookie so that is doesn't escape */
+		atomic_inc(&cookie->usage);
+
+		/* re-order the locks to avoid deadlock */
+		cache->ops->unlock_object(object);
+		down_write(&cookie->sem);
+		cache->ops->lock_object(object);
+
+		/* erase references from the object to the cookie */
+		hlist_del_init(&object->cookie_link);
+
+		xcookie = object->cookie;
+		object->cookie = NULL;
+
+		up_write(&cookie->sem);
+	}
+
+	cache->ops->unlock_object(object);
+
+	/* we've broken the links between cookie and object */
+	if (xcookie) {
+		fscache_cookie_put(xcookie);
+		cache->ops->put_object(object);
+	}
+
+	/* unpin the cookie */
+	if (cookie) {
+		if (cookie->def && cookie->def->now_uncached)
+			cookie->def->now_uncached(cookie->netfs_data);
+		fscache_cookie_put(cookie);
+	}
+
+	_leave("");
+}
+
+/*****************************************************************************/
+/*
+ * select a cache on which to store an object
+ * - the cache addremove semaphore must be at least read-locked by the caller
+ * - the object will never be an index
+ */
+static struct fscache_cache *fscache_select_cache_for_object(struct fscache_cookie *cookie)
+{
+	struct fscache_cache_tag *tag;
+	struct fscache_object *object;
+	struct fscache_cache *cache;
+
+	_enter("");
+
+	if (list_empty(&fscache_cache_list)) {
+		_leave(" = NULL [no cache]");
+		return NULL;
+	}
+
+	/* we check the parent to determine the cache to use */
+	down_read(&cookie->parent->sem);
+
+	/* the first in the parent's backing list should be the preferred
+	 * cache */
+	if (!hlist_empty(&cookie->parent->backing_objects)) {
+		object = hlist_entry(cookie->parent->backing_objects.first,
+				     struct fscache_object, cookie_link);
+
+		cache = object->cache;
+		if (test_bit(FSCACHE_IOERROR, &cache->flags))
+			cache = NULL;
+
+		up_read(&cookie->parent->sem);
+		_leave(" = %p [parent]", cache);
+		return cache;
+	}
+
+	/* the parent is unbacked */
+	if (cookie->parent->def->type != FSCACHE_COOKIE_TYPE_INDEX) {
+		/* parent not an index and is unbacked */
+		up_read(&cookie->parent->sem);
+		_leave(" = NULL [parent ubni]");
+		return NULL;
+	}
+
+	up_read(&cookie->parent->sem);
+
+	if (!cookie->parent->def->select_cache)
+		goto no_preference;
+
+	/* ask the netfs for its preference */
+	tag = cookie->parent->def->select_cache(
+		cookie->parent->parent->netfs_data,
+		cookie->parent->netfs_data);
+
+	if (!tag)
+		goto no_preference;
+
+	if (tag == &fscache_nomem_tag) {
+		_leave(" = NULL [nomem tag]");
+		return NULL;
+	}
+
+	if (!tag->cache) {
+		_leave(" = NULL [unbacked tag]");
+		return NULL;
+	}
+
+	if (test_bit(FSCACHE_IOERROR, &tag->cache->flags))
+		return NULL;
+
+	_leave(" = %p [specific]", tag->cache);
+	return tag->cache;
+
+no_preference:
+	/* netfs has no preference - just select first cache */
+	cache = list_entry(fscache_cache_list.next,
+			   struct fscache_cache, link);
+	_leave(" = %p [first]", cache);
+	return cache;
+}
+
+/*****************************************************************************/
+/*
+ * get a backing object for a cookie from the chosen cache
+ * - the cookie must be write-locked by the caller
+ * - all parent indexes will be obtained recursively first
+ */
+static struct fscache_object *fscache_lookup_object(struct fscache_cookie *cookie,
+						    struct fscache_cache *cache)
+{
+	struct fscache_cookie *parent = cookie->parent;
+	struct fscache_object *pobject, *object;
+	struct hlist_node *_p;
+
+	_enter("{%s/%s},",
+	       parent && parent->def ? parent->def->name : "",
+	       cookie->def ? (char *) cookie->def->name : "<file>");
+
+	if (test_bit(FSCACHE_IOERROR, &cache->flags))
+		return NULL;
+
+	/* see if we have the backing object for this cookie + cache immediately
+	 * to hand
+	 */
+	object = NULL;
+	hlist_for_each_entry(object, _p,
+			     &cookie->backing_objects, cookie_link
+			     ) {
+		if (object->cache == cache)
+			break;
+	}
+
+	if (object) {
+		_leave(" = %p [old]", object);
+		return object;
+	}
+
+	BUG_ON(!parent); /* FSDEF entries don't have a parent */
+
+	/* we don't have a backing cookie, so we need to consult the object's
+	 * parent index in the selected cache and maybe insert an entry
+	 * therein; so the first thing to do is make sure that the parent index
+	 * is represented on disc
+	 */
+	down_read(&parent->sem);
+
+	pobject = NULL;
+	hlist_for_each_entry(pobject, _p,
+			     &parent->backing_objects, cookie_link
+			     ) {
+		if (pobject->cache == cache)
+			break;
+	}
+
+	if (!pobject) {
+		/* we don't know about the parent object */
+		up_read(&parent->sem);
+		down_write(&parent->sem);
+
+		pobject = fscache_lookup_object(parent, cache);
+		if (IS_ERR(pobject)) {
+			up_write(&parent->sem);
+			_leave(" = %ld [no ipobj]", PTR_ERR(pobject));
+			return pobject;
+		}
+
+		_debug("pobject=%p", pobject);
+
+		BUG_ON(pobject->cookie != parent);
+
+		downgrade_write(&parent->sem);
+	}
+
+	/* now we can attempt to look up this object in the parent, possibly
+	 * creating a representation on disc when we do so
+	 */
+	object = cache->ops->lookup_object(cache, pobject, cookie);
+	up_read(&parent->sem);
+
+	if (IS_ERR(object)) {
+		_leave(" = %ld [no obj]", PTR_ERR(object));
+		return object;
+	}
+
+	/* keep track of it */
+	cache->ops->lock_object(object);
+
+	BUG_ON(!hlist_unhashed(&object->cookie_link));
+
+	/* attach to the cache's object list */
+	if (list_empty(&object->cache_link)) {
+		spin_lock(&cache->object_list_lock);
+		list_add(&object->cache_link, &cache->object_list);
+		spin_unlock(&cache->object_list_lock);
+	}
+
+	/* attach to the cookie */
+	object->cookie = cookie;
+	atomic_inc(&cookie->usage);
+	hlist_add_head(&object->cookie_link, &cookie->backing_objects);
+
+	/* done */
+	cache->ops->unlock_object(object);
+	_leave(" = %p [new]", object);
+	return object;
+}
+
+/*****************************************************************************/
+/*
+ * request a cookie to represent an object (index, datafile, xattr, etc)
+ * - parent specifies the parent object
+ *   - the top level index cookie for each netfs is stored in the fscache_netfs
+ *     struct upon registration
+ * - idef points to the definition
+ * - the netfs_data will be passed to the functions pointed to in *def
+ * - all attached caches will be searched to see if they contain this object
+ * - index objects aren't stored on disk until there's a dependent file that
+ *   needs storing
+ * - other objects are stored in a selected cache immediately, and all the
+ *   indexes forming the path to it are instantiated if necessary
+ * - we never let on to the netfs about errors
+ *   - we may set a negative cookie pointer, but that's okay
+ */
+struct fscache_cookie *__fscache_acquire_cookie(struct fscache_cookie *parent,
+						struct fscache_cookie_def *def,
+						void *netfs_data)
+{
+	struct fscache_cookie *cookie;
+	struct fscache_cache *cache;
+	struct fscache_object *object;
+	int ret = 0;
+
+	BUG_ON(!def);
+
+	_enter("{%s},{%s},%p",
+	       parent ? (char *) parent->def->name : "<no-parent>",
+	       def->name, netfs_data);
+
+	/* if there's no parent cookie, then we don't create one here either */
+	if (!parent) {
+		_leave(" [no parent]");
+		return NULL;
+	}
+
+	/* validate the definition */
+	BUG_ON(!def->get_key);
+	BUG_ON(!def->name[0]);
+
+	BUG_ON(def->type == FSCACHE_COOKIE_TYPE_INDEX &&
+	       parent->def->type != FSCACHE_COOKIE_TYPE_INDEX);
+
+	/* allocate and initialise a cookie */
+	cookie = kmem_cache_alloc(fscache_cookie_jar, SLAB_KERNEL);
+	if (!cookie) {
+		_leave(" [ENOMEM]");
+		return NULL;
+	}
+
+	atomic_set(&cookie->usage, 1);
+	atomic_set(&cookie->children, 0);
+
+	atomic_inc(&parent->usage);
+	atomic_inc(&parent->children);
+
+	cookie->def		= def;
+	cookie->parent		= parent;
+	cookie->netfs		= parent->netfs;
+	cookie->netfs_data	= netfs_data;
+
+	/* now we need to see whether the backing objects for this cookie yet
+	 * exist, if not there'll be nothing to search */
+	down_read(&fscache_addremove_sem);
+
+	if (list_empty(&fscache_cache_list)) {
+		up_read(&fscache_addremove_sem);
+		_leave(" = %p [no caches]", cookie);
+		return cookie;
+	}
+
+	/* if the object is an index then we need do nothing more here - we
+	 * create indexes on disk when we need them as an index may exist in
+	 * multiple caches */
+	if (cookie->def->type != FSCACHE_COOKIE_TYPE_INDEX) {
+		down_write(&cookie->sem);
+
+		/* the object is a file - we need to select a cache in which to
+		 * store it */
+		cache = fscache_select_cache_for_object(cookie);
+		if (!cache)
+			goto no_cache; /* couldn't decide on a cache */
+
+		/* create a file index entry on disc, along with all the
+		 * indexes required to find it again later */
+		object = fscache_lookup_object(cookie, cache);
+		if (IS_ERR(object)) {
+			ret = PTR_ERR(object);
+			goto error;
+		}
+
+		up_write(&cookie->sem);
+	}
+out:
+	up_read(&fscache_addremove_sem);
+	_leave(" = %p", cookie);
+	return cookie;
+
+no_cache:
+	ret = -ENOMEDIUM;
+	goto error_cleanup;
+error:
+	printk(KERN_ERR "FS-Cache: error from cache: %d\n", ret);
+error_cleanup:
+	if (cookie) {
+		up_write(&cookie->sem);
+		__fscache_cookie_put(cookie);
+		cookie = NULL;
+		atomic_dec(&parent->children);
+	}
+
+	goto out;
+}
+
+EXPORT_SYMBOL(__fscache_acquire_cookie);
+
+/*****************************************************************************/
+/*
+ * release a cookie back to the cache
+ * - the object will be marked as recyclable on disc if retire is true
+ * - all dependents of this cookie must have already been unregistered
+ *   (indexes/files/pages)
+ */
+void __fscache_relinquish_cookie(struct fscache_cookie *cookie, int retire)
+{
+	struct fscache_cache *cache;
+	struct fscache_object *object;
+	struct hlist_node *_p;
+
+	if (!cookie) {
+		_leave(" [no cookie]");
+		return;
+	}
+
+	_enter("%p{%s},%d", cookie, cookie->def->name, retire);
+
+	if (atomic_read(&cookie->children) != 0) {
+		printk("FS-Cache: cookie still has children\n");
+		BUG();
+	}
+
+	/* detach pointers back to the netfs */
+	down_write(&cookie->sem);
+
+	cookie->netfs_data	= NULL;
+	cookie->def		= NULL;
+
+	/* mark retired objects for recycling */
+	if (retire) {
+		hlist_for_each_entry(object, _p,
+				     &cookie->backing_objects,
+				     cookie_link
+				     ) {
+			set_bit(FSCACHE_OBJECT_RECYCLING, &object->flags);
+		}
+	}
+
+	/* break links with all the active objects */
+	while (!hlist_empty(&cookie->backing_objects)) {
+		object = hlist_entry(cookie->backing_objects.first,
+				     struct fscache_object,
+				     cookie_link);
+
+		/* detach each cache object from the object cookie */
+		set_bit(FSCACHE_OBJECT_RELEASING, &object->flags);
+
+		hlist_del_init(&object->cookie_link);
+
+		cache = object->cache;
+		cache->ops->lock_object(object);
+		object->cookie = NULL;
+		cache->ops->unlock_object(object);
+
+		if (atomic_dec_and_test(&cookie->usage))
+			/* the cookie refcount shouldn't be reduced to 0 yet */
+			BUG();
+
+		spin_lock(&cache->object_list_lock);
+		list_del_init(&object->cache_link);
+		spin_unlock(&cache->object_list_lock);
+
+		cache->ops->put_object(object);
+	}
+
+	up_write(&cookie->sem);
+
+	if (cookie->parent) {
+#ifdef CONFIG_DEBUG_SLAB
+		BUG_ON((atomic_read(&cookie->parent->children) & 0xffff0000) == 0x6b6b0000);
+#endif
+		atomic_dec(&cookie->parent->children);
+	}
+
+	/* finally dispose of the cookie */
+	fscache_cookie_put(cookie);
+
+	_leave("");
+}
+
+EXPORT_SYMBOL(__fscache_relinquish_cookie);
+
+/*****************************************************************************/
+/*
+ * update the index entries backing a cookie
+ */
+void __fscache_update_cookie(struct fscache_cookie *cookie)
+{
+	struct fscache_object *object;
+	struct hlist_node *_p;
+
+	if (!cookie) {
+		_leave(" [no cookie]");
+		return;
+	}
+
+	_enter("{%s}", cookie->def->name);
+
+	BUG_ON(!cookie->def->get_aux);
+
+	down_write(&cookie->sem);
+	down_read(&cookie->parent->sem);
+
+	/* update the index entry on disc in each cache backing this cookie */
+	hlist_for_each_entry(object, _p,
+			     &cookie->backing_objects, cookie_link
+			     ) {
+		if (!test_bit(FSCACHE_IOERROR, &object->cache->flags))
+			object->cache->ops->update_object(object);
+	}
+
+	up_read(&cookie->parent->sem);
+	up_write(&cookie->sem);
+	_leave("");
+}
+
+EXPORT_SYMBOL(__fscache_update_cookie);
+
+/*****************************************************************************/
+/*
+ * destroy a cookie
+ */
+static void __fscache_cookie_put(struct fscache_cookie *cookie)
+{
+	struct fscache_cookie *parent;
+
+	_enter("%p", cookie);
+
+	for (;;) {
+		parent = cookie->parent;
+		BUG_ON(!hlist_empty(&cookie->backing_objects));
+		kmem_cache_free(fscache_cookie_jar, cookie);
+
+		if (!parent)
+			break;
+
+		cookie = parent;
+		BUG_ON(atomic_read(&cookie->usage) <= 0);
+		if (!atomic_dec_and_test(&cookie->usage))
+			break;
+	}
+
+	_leave("");
+}
+
+/*****************************************************************************/
+/*
+ * initialise an cookie jar slab element prior to any use
+ */
+void fscache_cookie_init_once(void *_cookie, kmem_cache_t *cachep,
+			      unsigned long flags)
+{
+	struct fscache_cookie *cookie = _cookie;
+
+	if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) ==
+	    SLAB_CTOR_CONSTRUCTOR) {
+		memset(cookie, 0, sizeof(*cookie));
+		init_rwsem(&cookie->sem);
+		INIT_HLIST_HEAD(&cookie->backing_objects);
+	}
+}
+
+/*****************************************************************************/
+/*
+ * pin an object into the cache
+ */
+int __fscache_pin_cookie(struct fscache_cookie *cookie)
+{
+	struct fscache_object *object;
+	int ret;
+
+	_enter("%p", cookie);
+
+	if (hlist_empty(&cookie->backing_objects)) {
+		_leave(" = -ENOBUFS");
+		return -ENOBUFS;
+	}
+
+	/* not supposed to use this for indexes */
+	BUG_ON(cookie->def->type == FSCACHE_COOKIE_TYPE_INDEX);
+
+	/* prevent the file from being uncached whilst we access it and exclude
+	 * read and write attempts on pages
+	 */
+	down_write(&cookie->sem);
+
+	ret = -ENOBUFS;
+	if (!hlist_empty(&cookie->backing_objects)) {
+		/* get and pin the backing object */
+		object = hlist_entry(cookie->backing_objects.first,
+				     struct fscache_object, cookie_link);
+
+		if (test_bit(FSCACHE_IOERROR, &object->cache->flags))
+			goto out;
+
+		if (!object->cache->ops->pin_object) {
+			ret = -EOPNOTSUPP;
+			goto out;
+		}
+
+		/* prevent the cache from being withdrawn */
+		if (fscache_operation_lock(object)) {
+			if (object->cache->ops->grab_object(object)) {
+				/* ask the cache to honour the operation */
+				ret = object->cache->ops->pin_object(object);
+
+				object->cache->ops->put_object(object);
+			}
+
+			fscache_operation_unlock(object);
+		}
+	}
+
+out:
+	up_write(&cookie->sem);
+	_leave(" = %d", ret);
+	return ret;
+}
+
+EXPORT_SYMBOL(__fscache_pin_cookie);
+
+/*****************************************************************************/
+/*
+ * unpin an object into the cache
+ */
+void __fscache_unpin_cookie(struct fscache_cookie *cookie)
+{
+	struct fscache_object *object;
+	int ret;
+
+	_enter("%p", cookie);
+
+	if (hlist_empty(&cookie->backing_objects)) {
+		_leave(" [no obj]");
+		return;
+	}
+
+	/* not supposed to use this for indexes */
+	BUG_ON(cookie->def->type == FSCACHE_COOKIE_TYPE_INDEX);
+
+	/* prevent the file from being uncached whilst we access it and exclude
+	 * read and write attempts on pages
+	 */
+	down_write(&cookie->sem);
+
+	ret = -ENOBUFS;
+	if (!hlist_empty(&cookie->backing_objects)) {
+		/* get and unpin the backing object */
+		object = hlist_entry(cookie->backing_objects.first,
+				     struct fscache_object, cookie_link);
+
+		if (test_bit(FSCACHE_IOERROR, &object->cache->flags))
+			goto out;
+
+		if (!object->cache->ops->unpin_object)
+			goto out;
+
+		/* prevent the cache from being withdrawn */
+		if (fscache_operation_lock(object)) {
+			if (object->cache->ops->grab_object(object)) {
+				/* ask the cache to honour the operation */
+				object->cache->ops->unpin_object(object);
+
+				object->cache->ops->put_object(object);
+			}
+
+			fscache_operation_unlock(object);
+		}
+	}
+
+out:
+	up_write(&cookie->sem);
+	_leave("");
+}
+
+EXPORT_SYMBOL(__fscache_unpin_cookie);
diff --git a/fs/fscache/fscache-int.h b/fs/fscache/fscache-int.h
new file mode 100644
index 000000000..d075660c4
--- /dev/null
+++ b/fs/fscache/fscache-int.h
@@ -0,0 +1,93 @@
+/* fscache-int.h: internal definitions
+ *
+ * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@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.
+ */
+
+#ifndef _FSCACHE_INT_H
+#define _FSCACHE_INT_H
+
+#include <linux/fscache-cache.h>
+#include <linux/timer.h>
+#include <linux/bio.h>
+
+extern kmem_cache_t *fscache_cookie_jar;
+
+extern struct fscache_cookie fscache_fsdef_index;
+extern struct fscache_cookie_def fscache_fsdef_netfs_def;
+
+extern void fscache_cookie_init_once(void *_cookie, kmem_cache_t *cachep, unsigned long flags);
+
+/*
+ * prevent the cache from being withdrawn whilst an operation is in progress
+ * - returns false if the cache is being withdrawn already or if the cache is
+ *   waiting to withdraw itself
+ * - returns true if the cache was not being withdrawn
+ * - fscache_withdraw_cache() will wait using down_write() until all ops are
+ *   complete
+ */
+static inline int fscache_operation_lock(struct fscache_object *object)
+{
+	return down_read_trylock(&object->cache->withdrawal_sem);
+}
+
+/*
+ * release the operation lock
+ */
+static inline void fscache_operation_unlock(struct fscache_object *object)
+{
+	up_read(&object->cache->withdrawal_sem);
+}
+
+
+/*****************************************************************************/
+/*
+ * debug tracing
+ */
+#define dbgprintk(FMT,...) \
+	printk("[%-6.6s] "FMT"\n",current->comm ,##__VA_ARGS__)
+#define _dbprintk(FMT,...) do { } while(0)
+
+#define kenter(FMT,...)	dbgprintk("==> %s("FMT")",__FUNCTION__ ,##__VA_ARGS__)
+#define kleave(FMT,...)	dbgprintk("<== %s()"FMT"",__FUNCTION__ ,##__VA_ARGS__)
+#define kdebug(FMT,...)	dbgprintk(FMT ,##__VA_ARGS__)
+
+#define kjournal(FMT,...) _dbprintk(FMT ,##__VA_ARGS__)
+
+#define dbgfree(ADDR)  _dbprintk("%p:%d: FREEING %p",__FILE__,__LINE__,ADDR)
+
+#define dbgpgalloc(PAGE)						\
+do {									\
+	_dbprintk("PGALLOC %s:%d: %p {%lx,%lu}\n",			\
+		  __FILE__,__LINE__,					\
+		  (PAGE),(PAGE)->mapping->host->i_ino,(PAGE)->index	\
+		  );							\
+} while(0)
+
+#define dbgpgfree(PAGE)						\
+do {								\
+	if ((PAGE))						\
+		_dbprintk("PGFREE %s:%d: %p {%lx,%lu}\n",	\
+			  __FILE__,__LINE__,			\
+			  (PAGE),				\
+			  (PAGE)->mapping->host->i_ino,		\
+			  (PAGE)->index				\
+			  );					\
+} while(0)
+
+#ifdef __KDEBUG
+#define _enter(FMT,...)	kenter(FMT,##__VA_ARGS__)
+#define _leave(FMT,...)	kleave(FMT,##__VA_ARGS__)
+#define _debug(FMT,...)	kdebug(FMT,##__VA_ARGS__)
+#else
+#define _enter(FMT,...)	do { } while(0)
+#define _leave(FMT,...)	do { } while(0)
+#define _debug(FMT,...)	do { } while(0)
+#endif
+
+#endif /* _FSCACHE_INT_H */
diff --git a/fs/fscache/fsdef.c b/fs/fscache/fsdef.c
new file mode 100644
index 000000000..495f63355
--- /dev/null
+++ b/fs/fscache/fsdef.c
@@ -0,0 +1,110 @@
+/* fsdef.c: filesystem index definition
+ *
+ * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@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.
+ */
+
+#include <linux/module.h>
+#include "fscache-int.h"
+
+static uint16_t fscache_fsdef_netfs_get_key(const void *cookie_netfs_data,
+					    void *buffer, uint16_t bufmax);
+
+static uint16_t fscache_fsdef_netfs_get_aux(const void *cookie_netfs_data,
+					    void *buffer, uint16_t bufmax);
+
+static fscache_checkaux_t fscache_fsdef_netfs_check_aux(void *cookie_netfs_data,
+							const void *data,
+							uint16_t datalen);
+
+struct fscache_cookie_def fscache_fsdef_netfs_def = {
+	.name		= "FSDEF.netfs",
+	.type		= FSCACHE_COOKIE_TYPE_INDEX,
+	.get_key	= fscache_fsdef_netfs_get_key,
+	.get_aux	= fscache_fsdef_netfs_get_aux,
+	.check_aux	= fscache_fsdef_netfs_check_aux,
+};
+
+struct fscache_cookie fscache_fsdef_index = {
+	.usage		= ATOMIC_INIT(1),
+	.def		= NULL,
+	.sem		= __RWSEM_INITIALIZER(fscache_fsdef_index.sem),
+	.backing_objects = HLIST_HEAD_INIT,
+};
+
+EXPORT_SYMBOL(fscache_fsdef_index);
+
+/*****************************************************************************/
+/*
+ * get the key data for an FSDEF index record
+ */
+static uint16_t fscache_fsdef_netfs_get_key(const void *cookie_netfs_data,
+					    void *buffer, uint16_t bufmax)
+{
+	const struct fscache_netfs *netfs = cookie_netfs_data;
+	unsigned klen;
+
+	_enter("{%s.%u},", netfs->name, netfs->version);
+
+	klen = strlen(netfs->name);
+	if (klen > bufmax)
+		return 0;
+
+	memcpy(buffer, netfs->name, klen);
+	return klen;
+}
+
+/*****************************************************************************/
+/*
+ * get the auxilliary data for an FSDEF index record
+ */
+static uint16_t fscache_fsdef_netfs_get_aux(const void *cookie_netfs_data,
+					    void *buffer, uint16_t bufmax)
+{
+	const struct fscache_netfs *netfs = cookie_netfs_data;
+	unsigned dlen;
+
+	_enter("{%s.%u},", netfs->name, netfs->version);
+
+	dlen = sizeof(uint32_t);
+	if (dlen > bufmax)
+		return 0;
+
+	memcpy(buffer, &netfs->version, dlen);
+	return dlen;
+}
+
+/*****************************************************************************/
+/*
+ * check that the version stored in the auxilliary data is correct
+ */
+static fscache_checkaux_t fscache_fsdef_netfs_check_aux(void *cookie_netfs_data,
+							const void *data,
+							uint16_t datalen)
+{
+	struct fscache_netfs *netfs = cookie_netfs_data;
+	uint32_t version;
+
+	_enter("{%s},,%hu", netfs->name, datalen);
+
+	if (datalen != sizeof(version)) {
+		_leave(" = OBSOLETE [dl=%d v=%d]",
+		       datalen, sizeof(version));
+		return FSCACHE_CHECKAUX_OBSOLETE;
+	}
+
+	memcpy(&version, data, sizeof(version));
+	if (version != netfs->version) {
+		_leave(" = OBSOLETE [ver=%x net=%x]",
+		       version, netfs->version);
+		return FSCACHE_CHECKAUX_OBSOLETE;
+	}
+
+	_leave(" = OKAY");
+	return FSCACHE_CHECKAUX_OKAY;
+}
diff --git a/fs/fscache/main.c b/fs/fscache/main.c
new file mode 100644
index 000000000..d73068cb0
--- /dev/null
+++ b/fs/fscache/main.c
@@ -0,0 +1,105 @@
+/* main.c: general filesystem caching manager
+ *
+ * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@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.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/completion.h>
+#include <linux/slab.h>
+#include "fscache-int.h"
+
+int fscache_debug;
+
+static int fscache_init(void);
+static void fscache_exit(void);
+
+fs_initcall(fscache_init);
+module_exit(fscache_exit);
+
+MODULE_DESCRIPTION("FS Cache Manager");
+MODULE_AUTHOR("Red Hat, Inc.");
+MODULE_LICENSE("GPL");
+
+static void fscache_ktype_release(struct kobject *kobject);
+
+static struct sysfs_ops fscache_sysfs_ops = {
+	.show		= NULL,
+	.store		= NULL,
+};
+
+static struct kobj_type fscache_ktype = {
+	.release	= fscache_ktype_release,
+	.sysfs_ops	= &fscache_sysfs_ops,
+	.default_attrs	= NULL,
+};
+
+struct kset fscache_kset = {
+	.kobj.name	= "fscache",
+	.kobj.kset	= &fs_subsys.kset,
+	.ktype		= &fscache_ktype,
+};
+
+EXPORT_SYMBOL(fscache_kset);
+
+/*****************************************************************************/
+/*
+ * initialise the fs caching module
+ */
+static int __init fscache_init(void)
+{
+	int ret;
+
+	fscache_cookie_jar =
+		kmem_cache_create("fscache_cookie_jar",
+				  sizeof(struct fscache_cookie),
+				  0,
+				  0,
+				  fscache_cookie_init_once,
+				  NULL);
+
+	if (!fscache_cookie_jar) {
+		printk(KERN_NOTICE
+		       "FS-Cache: Failed to allocate a cookie jar\n");
+		return -ENOMEM;
+	}
+
+	ret = kset_register(&fscache_kset);
+	if (ret < 0) {
+		kmem_cache_destroy(fscache_cookie_jar);
+		return ret;
+	}
+
+	printk(KERN_NOTICE "FS-Cache: Loaded\n");
+	return 0;
+
+}
+
+/*****************************************************************************/
+/*
+ * clean up on module removal
+ */
+static void __exit fscache_exit(void)
+{
+	_enter("");
+
+	kset_unregister(&fscache_kset);
+	kmem_cache_destroy(fscache_cookie_jar);
+	printk(KERN_NOTICE "FS-Cache: unloaded\n");
+
+}
+
+/*****************************************************************************/
+/*
+ * release the ktype
+ */
+static void fscache_ktype_release(struct kobject *kobject)
+{
+}
diff --git a/fs/fscache/page.c b/fs/fscache/page.c
new file mode 100644
index 000000000..fbb771606
--- /dev/null
+++ b/fs/fscache/page.c
@@ -0,0 +1,537 @@
+/* page.c: general filesystem cache cookie management
+ *
+ * Copyright (C) 2004-5 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@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.
+ */
+
+#include <linux/module.h>
+#include <linux/fscache-cache.h>
+#include <linux/buffer_head.h>
+#include <linux/pagevec.h>
+#include "fscache-int.h"
+
+/*****************************************************************************/
+/*
+ * set the data file size on an object in the cache
+ */
+int __fscache_set_i_size(struct fscache_cookie *cookie, loff_t i_size)
+{
+	struct fscache_object *object;
+	int ret;
+
+	_enter("%p,%llu,", cookie, i_size);
+
+	if (hlist_empty(&cookie->backing_objects)) {
+		_leave(" = -ENOBUFS");
+		return -ENOBUFS;
+	}
+
+	/* not supposed to use this for indexes */
+	BUG_ON(cookie->def->type == FSCACHE_COOKIE_TYPE_INDEX);
+
+	/* prevent the file from being uncached whilst we access it and exclude
+	 * read and write attempts on pages
+	 */
+	down_write(&cookie->sem);
+
+	ret = -ENOBUFS;
+	if (!hlist_empty(&cookie->backing_objects)) {
+		/* get and pin the backing object */
+		object = hlist_entry(cookie->backing_objects.first,
+				     struct fscache_object, cookie_link);
+
+		if (test_bit(FSCACHE_IOERROR, &object->cache->flags))
+			goto out;
+
+		/* prevent the cache from being withdrawn */
+		if (object->cache->ops->set_i_size &&
+		    fscache_operation_lock(object)
+		    ) {
+			if (object->cache->ops->grab_object(object)) {
+				/* ask the cache to honour the operation */
+				ret = object->cache->ops->set_i_size(object,
+								     i_size);
+
+				object->cache->ops->put_object(object);
+			}
+
+			fscache_operation_unlock(object);
+		}
+	}
+
+out:
+	up_write(&cookie->sem);
+	_leave(" = %d", ret);
+	return ret;
+}
+
+EXPORT_SYMBOL(__fscache_set_i_size);
+
+/*****************************************************************************/
+/*
+ * reserve space for an object
+ */
+int __fscache_reserve_space(struct fscache_cookie *cookie, loff_t size)
+{
+	struct fscache_object *object;
+	int ret;
+
+	_enter("%p,%llu,", cookie, size);
+
+	if (hlist_empty(&cookie->backing_objects)) {
+		_leave(" = -ENOBUFS");
+		return -ENOBUFS;
+	}
+
+	/* not supposed to use this for indexes */
+	BUG_ON(cookie->def->type == FSCACHE_COOKIE_TYPE_INDEX);
+
+	/* prevent the file from being uncached whilst we access it and exclude
+	 * read and write attempts on pages
+	 */
+	down_write(&cookie->sem);
+
+	ret = -ENOBUFS;
+	if (!hlist_empty(&cookie->backing_objects)) {
+		/* get and pin the backing object */
+		object = hlist_entry(cookie->backing_objects.first,
+				     struct fscache_object, cookie_link);
+
+		if (test_bit(FSCACHE_IOERROR, &object->cache->flags))
+			goto out;
+
+		if (!object->cache->ops->reserve_space) {
+			ret = -EOPNOTSUPP;
+			goto out;
+		}
+
+		/* prevent the cache from being withdrawn */
+		if (fscache_operation_lock(object)) {
+			if (object->cache->ops->grab_object(object)) {
+				/* ask the cache to honour the operation */
+				ret = object->cache->ops->reserve_space(object,
+									size);
+
+				object->cache->ops->put_object(object);
+			}
+
+			fscache_operation_unlock(object);
+		}
+	}
+
+out:
+	up_write(&cookie->sem);
+	_leave(" = %d", ret);
+	return ret;
+}
+
+EXPORT_SYMBOL(__fscache_reserve_space);
+
+/*****************************************************************************/
+/*
+ * read a page from the cache or allocate a block in which to store it
+ * - we return:
+ *   -ENOMEM	- out of memory, nothing done
+ *   -EINTR	- interrupted
+ *   -ENOBUFS	- no backing object available in which to cache the block
+ *   -ENODATA	- no data available in the backing object for this block
+ *   0		- dispatched a read - it'll call end_io_func() when finished
+ */
+int __fscache_read_or_alloc_page(struct fscache_cookie *cookie,
+				 struct page *page,
+				 fscache_rw_complete_t end_io_func,
+				 void *context,
+				 gfp_t gfp)
+{
+	struct fscache_object *object;
+	int ret;
+
+	_enter("%p,{%lu},", cookie, page->index);
+
+	if (hlist_empty(&cookie->backing_objects)) {
+		_leave(" -ENOBUFS [no backing objects]");
+		return -ENOBUFS;
+	}
+
+	/* not supposed to use this for indexes */
+	BUG_ON(cookie->def->type == FSCACHE_COOKIE_TYPE_INDEX);
+
+	/* prevent the file from being uncached whilst we access it */
+	down_read(&cookie->sem);
+
+	ret = -ENOBUFS;
+	if (!hlist_empty(&cookie->backing_objects)) {
+		/* get and pin the backing object */
+		object = hlist_entry(cookie->backing_objects.first,
+				     struct fscache_object, cookie_link);
+
+		if (test_bit(FSCACHE_IOERROR, &object->cache->flags))
+			goto out;
+
+		/* prevent the cache from being withdrawn */
+		if (fscache_operation_lock(object)) {
+			if (object->cache->ops->grab_object(object)) {
+				/* ask the cache to honour the operation */
+				ret = object->cache->ops->read_or_alloc_page(
+					object,
+					page,
+					end_io_func,
+					context,
+					gfp);
+
+				object->cache->ops->put_object(object);
+			}
+
+			fscache_operation_unlock(object);
+		}
+	}
+
+out:
+	up_read(&cookie->sem);
+	_leave(" = %d", ret);
+	return ret;
+}
+
+EXPORT_SYMBOL(__fscache_read_or_alloc_page);
+
+/*****************************************************************************/
+/*
+ * read a list of page from the cache or allocate a block in which to store
+ * them
+ * - we return:
+ *   -ENOMEM	- out of memory, some pages may be being read
+ *   -EINTR	- interrupted, some pages may be being read
+ *   -ENOBUFS	- no backing object or space available in which to cache any
+ *                pages not being read
+ *   -ENODATA	- no data available in the backing object for some or all of
+ *                the pages
+ *   0		- dispatched a read on all pages
+ *
+ * end_io_func() will be called for each page read from the cache as it is
+ * finishes being read
+ *
+ * any pages for which a read is dispatched will be removed from pages and
+ * nr_pages
+ */
+int __fscache_read_or_alloc_pages(struct fscache_cookie *cookie,
+				  struct address_space *mapping,
+				  struct list_head *pages,
+				  unsigned *nr_pages,
+				  fscache_rw_complete_t end_io_func,
+				  void *context,
+				  gfp_t gfp)
+{
+	struct fscache_object *object;
+	int ret;
+
+	_enter("%p,,%d,,,", cookie, *nr_pages);
+
+	if (hlist_empty(&cookie->backing_objects)) {
+		_leave(" -ENOBUFS [no backing objects]");
+		return -ENOBUFS;
+	}
+
+	/* not supposed to use this for indexes */
+	BUG_ON(cookie->def->type == FSCACHE_COOKIE_TYPE_INDEX);
+	BUG_ON(list_empty(pages));
+	BUG_ON(*nr_pages <= 0);
+
+	/* prevent the file from being uncached whilst we access it */
+	down_read(&cookie->sem);
+
+	ret = -ENOBUFS;
+	if (!hlist_empty(&cookie->backing_objects)) {
+		/* get and pin the backing object */
+		object = hlist_entry(cookie->backing_objects.first,
+				     struct fscache_object, cookie_link);
+
+		if (test_bit(FSCACHE_IOERROR, &object->cache->flags))
+			goto out;
+
+		/* prevent the cache from being withdrawn */
+		if (fscache_operation_lock(object)) {
+			if (object->cache->ops->grab_object(object)) {
+				/* ask the cache to honour the operation */
+				ret = object->cache->ops->read_or_alloc_pages(
+					object,
+					mapping,
+					pages,
+					nr_pages,
+					end_io_func,
+					context,
+					gfp);
+
+				object->cache->ops->put_object(object);
+			}
+
+			fscache_operation_unlock(object);
+		}
+	}
+
+out:
+	up_read(&cookie->sem);
+	_leave(" = %d", ret);
+	return ret;
+}
+
+EXPORT_SYMBOL(__fscache_read_or_alloc_pages);
+
+/*****************************************************************************/
+/*
+ * allocate a block in the cache on which to store a page
+ * - we return:
+ *   -ENOMEM	- out of memory, nothing done
+ *   -EINTR	- interrupted
+ *   -ENOBUFS	- no backing object available in which to cache the block
+ *   0		- block allocated
+ */
+int __fscache_alloc_page(struct fscache_cookie *cookie,
+			 struct page *page,
+			 gfp_t gfp)
+{
+	struct fscache_object *object;
+	int ret;
+
+	_enter("%p,{%lu},", cookie, page->index);
+
+	if (hlist_empty(&cookie->backing_objects)) {
+		_leave(" -ENOBUFS [no backing objects]");
+		return -ENOBUFS;
+	}
+
+	/* not supposed to use this for indexes */
+	BUG_ON(cookie->def->type == FSCACHE_COOKIE_TYPE_INDEX);
+
+	/* prevent the file from being uncached whilst we access it */
+	down_read(&cookie->sem);
+
+	ret = -ENOBUFS;
+	if (!hlist_empty(&cookie->backing_objects)) {
+		/* get and pin the backing object */
+		object = hlist_entry(cookie->backing_objects.first,
+				     struct fscache_object, cookie_link);
+
+		if (test_bit(FSCACHE_IOERROR, &object->cache->flags))
+			goto out;
+
+		/* prevent the cache from being withdrawn */
+		if (fscache_operation_lock(object)) {
+			if (object->cache->ops->grab_object(object)) {
+				/* ask the cache to honour the operation */
+				ret = object->cache->ops->allocate_page(object,
+									page,
+									gfp);
+
+				object->cache->ops->put_object(object);
+			}
+
+			fscache_operation_unlock(object);
+		}
+	}
+
+out:
+	up_read(&cookie->sem);
+	_leave(" = %d", ret);
+	return ret;
+}
+
+EXPORT_SYMBOL(__fscache_alloc_page);
+
+/*****************************************************************************/
+/*
+ * request a page be stored in the cache
+ * - returns:
+ *   -ENOMEM	- out of memory, nothing done
+ *   -EINTR	- interrupted
+ *   -ENOBUFS	- no backing object available in which to cache the page
+ *   0		- dispatched a write - it'll call end_io_func() when finished
+ */
+int __fscache_write_page(struct fscache_cookie *cookie,
+			 struct page *page,
+			 fscache_rw_complete_t end_io_func,
+			 void *context,
+			 gfp_t gfp)
+{
+	struct fscache_object *object;
+	int ret;
+
+	_enter("%p,{%lu},", cookie, page->index);
+
+	/* not supposed to use this for indexes */
+	BUG_ON(cookie->def->type == FSCACHE_COOKIE_TYPE_INDEX);
+
+	/* prevent the file from been uncached whilst we deal with it */
+	down_read(&cookie->sem);
+
+	ret = -ENOBUFS;
+	if (!hlist_empty(&cookie->backing_objects)) {
+		object = hlist_entry(cookie->backing_objects.first,
+				     struct fscache_object, cookie_link);
+
+		if (test_bit(FSCACHE_IOERROR, &object->cache->flags))
+			goto out;
+
+		/* prevent the cache from being withdrawn */
+		if (fscache_operation_lock(object)) {
+			/* ask the cache to honour the operation */
+			ret = object->cache->ops->write_page(object,
+							     page,
+							     end_io_func,
+							     context,
+							     gfp);
+			fscache_operation_unlock(object);
+		}
+	}
+
+out:
+	up_read(&cookie->sem);
+	_leave(" = %d", ret);
+	return ret;
+}
+
+EXPORT_SYMBOL(__fscache_write_page);
+
+/*****************************************************************************/
+/*
+ * request several pages be stored in the cache
+ * - returns:
+ *   -ENOMEM	- out of memory, nothing done
+ *   -EINTR	- interrupted
+ *   -ENOBUFS	- no backing object available in which to cache the page
+ *   0		- dispatched a write - it'll call end_io_func() when finished
+ */
+int __fscache_write_pages(struct fscache_cookie *cookie,
+			  struct pagevec *pagevec,
+			  fscache_rw_complete_t end_io_func,
+			  void *context,
+			  gfp_t gfp)
+{
+	struct fscache_object *object;
+	int ret;
+
+	_enter("%p,{%ld},", cookie, pagevec->nr);
+
+	/* not supposed to use this for indexes */
+	BUG_ON(cookie->def->type == FSCACHE_COOKIE_TYPE_INDEX);
+
+	/* prevent the file from been uncached whilst we deal with it */
+	down_read(&cookie->sem);
+
+	ret = -ENOBUFS;
+	if (!hlist_empty(&cookie->backing_objects)) {
+		object = hlist_entry(cookie->backing_objects.first,
+				     struct fscache_object, cookie_link);
+
+		if (test_bit(FSCACHE_IOERROR, &object->cache->flags))
+			goto out;
+
+		/* prevent the cache from being withdrawn */
+		if (fscache_operation_lock(object)) {
+			/* ask the cache to honour the operation */
+			ret = object->cache->ops->write_pages(object,
+							      pagevec,
+							      end_io_func,
+							      context,
+							      gfp);
+			fscache_operation_unlock(object);
+		}
+	}
+
+out:
+	up_read(&cookie->sem);
+	_leave(" = %d", ret);
+	return ret;
+}
+
+EXPORT_SYMBOL(__fscache_write_pages);
+
+/*****************************************************************************/
+/*
+ * remove a page from the cache
+ */
+void __fscache_uncache_page(struct fscache_cookie *cookie, struct page *page)
+{
+	struct fscache_object *object;
+	struct pagevec pagevec;
+
+	_enter(",{%lu}", page->index);
+
+	/* not supposed to use this for indexes */
+	BUG_ON(cookie->def->type == FSCACHE_COOKIE_TYPE_INDEX);
+
+	if (hlist_empty(&cookie->backing_objects)) {
+		_leave(" [no backing]");
+		return;
+	}
+
+	pagevec_init(&pagevec, 0);
+	pagevec_add(&pagevec, page);
+
+	/* ask the cache to honour the operation */
+	down_read(&cookie->sem);
+
+	if (!hlist_empty(&cookie->backing_objects)) {
+		object = hlist_entry(cookie->backing_objects.first,
+				     struct fscache_object, cookie_link);
+
+		/* prevent the cache from being withdrawn */
+		if (fscache_operation_lock(object)) {
+			object->cache->ops->uncache_pages(object, &pagevec);
+			fscache_operation_unlock(object);
+		}
+	}
+
+	up_read(&cookie->sem);
+
+	_leave("");
+}
+
+EXPORT_SYMBOL(__fscache_uncache_page);
+
+/*****************************************************************************/
+/*
+ * remove a bunch of pages from the cache
+ */
+void __fscache_uncache_pages(struct fscache_cookie *cookie,
+			     struct pagevec *pagevec)
+{
+	struct fscache_object *object;
+
+	_enter(",{%ld}", pagevec->nr);
+
+	BUG_ON(pagevec->nr <= 0);
+	BUG_ON(!pagevec->pages[0]);
+
+	/* not supposed to use this for indexes */
+	BUG_ON(cookie->def->type == FSCACHE_COOKIE_TYPE_INDEX);
+
+	if (hlist_empty(&cookie->backing_objects)) {
+		_leave(" [no backing]");
+		return;
+	}
+
+	/* ask the cache to honour the operation */
+	down_read(&cookie->sem);
+
+	if (!hlist_empty(&cookie->backing_objects)) {
+		object = hlist_entry(cookie->backing_objects.first,
+				     struct fscache_object, cookie_link);
+
+		/* prevent the cache from being withdrawn */
+		if (fscache_operation_lock(object)) {
+			object->cache->ops->uncache_pages(object, pagevec);
+			fscache_operation_unlock(object);
+		}
+	}
+
+	up_read(&cookie->sem);
+
+	_leave("");
+}
+
+EXPORT_SYMBOL(__fscache_uncache_pages);
diff --git a/fs/fuse/control.c b/fs/fuse/control.c
new file mode 100644
index 000000000..79ec1f23d
--- /dev/null
+++ b/fs/fuse/control.c
@@ -0,0 +1,218 @@
+/*
+  FUSE: Filesystem in Userspace
+  Copyright (C) 2001-2006  Miklos Szeredi <miklos@szeredi.hu>
+
+  This program can be distributed under the terms of the GNU GPL.
+  See the file COPYING.
+*/
+
+#include "fuse_i.h"
+
+#include <linux/init.h>
+#include <linux/module.h>
+
+#define FUSE_CTL_SUPER_MAGIC 0x65735543
+
+/*
+ * This is non-NULL when the single instance of the control filesystem
+ * exists.  Protected by fuse_mutex
+ */
+static struct super_block *fuse_control_sb;
+
+static struct fuse_conn *fuse_ctl_file_conn_get(struct file *file)
+{
+	struct fuse_conn *fc;
+	mutex_lock(&fuse_mutex);
+	fc = file->f_dentry->d_inode->i_private;
+	if (fc)
+		fc = fuse_conn_get(fc);
+	mutex_unlock(&fuse_mutex);
+	return fc;
+}
+
+static ssize_t fuse_conn_abort_write(struct file *file, const char __user *buf,
+				     size_t count, loff_t *ppos)
+{
+	struct fuse_conn *fc = fuse_ctl_file_conn_get(file);
+	if (fc) {
+		fuse_abort_conn(fc);
+		fuse_conn_put(fc);
+	}
+	return count;
+}
+
+static ssize_t fuse_conn_waiting_read(struct file *file, char __user *buf,
+				      size_t len, loff_t *ppos)
+{
+	char tmp[32];
+	size_t size;
+
+	if (!*ppos) {
+		struct fuse_conn *fc = fuse_ctl_file_conn_get(file);
+		if (!fc)
+			return 0;
+
+		file->private_data=(void *)(long)atomic_read(&fc->num_waiting);
+		fuse_conn_put(fc);
+	}
+	size = sprintf(tmp, "%ld\n", (long)file->private_data);
+	return simple_read_from_buffer(buf, len, ppos, tmp, size);
+}
+
+static const struct file_operations fuse_ctl_abort_ops = {
+	.open = nonseekable_open,
+	.write = fuse_conn_abort_write,
+};
+
+static const struct file_operations fuse_ctl_waiting_ops = {
+	.open = nonseekable_open,
+	.read = fuse_conn_waiting_read,
+};
+
+static struct dentry *fuse_ctl_add_dentry(struct dentry *parent,
+					  struct fuse_conn *fc,
+					  const char *name,
+					  int mode, int nlink,
+					  struct inode_operations *iop,
+					  const struct file_operations *fop)
+{
+	struct dentry *dentry;
+	struct inode *inode;
+
+	BUG_ON(fc->ctl_ndents >= FUSE_CTL_NUM_DENTRIES);
+	dentry = d_alloc_name(parent, name);
+	if (!dentry)
+		return NULL;
+
+	fc->ctl_dentry[fc->ctl_ndents++] = dentry;
+	inode = new_inode(fuse_control_sb);
+	if (!inode)
+		return NULL;
+
+	inode->i_mode = mode;
+	inode->i_uid = fc->user_id;
+	inode->i_gid = fc->group_id;
+	inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
+	/* setting ->i_op to NULL is not allowed */
+	if (iop)
+		inode->i_op = iop;
+	inode->i_fop = fop;
+	inode->i_nlink = nlink;
+	inode->i_private = fc;
+	d_add(dentry, inode);
+	return dentry;
+}
+
+/*
+ * Add a connection to the control filesystem (if it exists).  Caller
+ * must hold fuse_mutex
+ */
+int fuse_ctl_add_conn(struct fuse_conn *fc)
+{
+	struct dentry *parent;
+	char name[32];
+
+	if (!fuse_control_sb)
+		return 0;
+
+	parent = fuse_control_sb->s_root;
+	parent->d_inode->i_nlink++;
+	sprintf(name, "%llu", (unsigned long long) fc->id);
+	parent = fuse_ctl_add_dentry(parent, fc, name, S_IFDIR | 0500, 2,
+				     &simple_dir_inode_operations,
+				     &simple_dir_operations);
+	if (!parent)
+		goto err;
+
+	if (!fuse_ctl_add_dentry(parent, fc, "waiting", S_IFREG | 0400, 1,
+				NULL, &fuse_ctl_waiting_ops) ||
+	    !fuse_ctl_add_dentry(parent, fc, "abort", S_IFREG | 0200, 1,
+				 NULL, &fuse_ctl_abort_ops))
+		goto err;
+
+	return 0;
+
+ err:
+	fuse_ctl_remove_conn(fc);
+	return -ENOMEM;
+}
+
+/*
+ * Remove a connection from the control filesystem (if it exists).
+ * Caller must hold fuse_mutex
+ */
+void fuse_ctl_remove_conn(struct fuse_conn *fc)
+{
+	int i;
+
+	if (!fuse_control_sb)
+		return;
+
+	for (i = fc->ctl_ndents - 1; i >= 0; i--) {
+		struct dentry *dentry = fc->ctl_dentry[i];
+		dentry->d_inode->i_private = NULL;
+		d_drop(dentry);
+		dput(dentry);
+	}
+	fuse_control_sb->s_root->d_inode->i_nlink--;
+}
+
+static int fuse_ctl_fill_super(struct super_block *sb, void *data, int silent)
+{
+	struct tree_descr empty_descr = {""};
+	struct fuse_conn *fc;
+	int err;
+
+	err = simple_fill_super(sb, FUSE_CTL_SUPER_MAGIC, &empty_descr);
+	if (err)
+		return err;
+
+	mutex_lock(&fuse_mutex);
+	BUG_ON(fuse_control_sb);
+	fuse_control_sb = sb;
+	list_for_each_entry(fc, &fuse_conn_list, entry) {
+		err = fuse_ctl_add_conn(fc);
+		if (err) {
+			fuse_control_sb = NULL;
+			mutex_unlock(&fuse_mutex);
+			return err;
+		}
+	}
+	mutex_unlock(&fuse_mutex);
+
+	return 0;
+}
+
+static int fuse_ctl_get_sb(struct file_system_type *fs_type, int flags,
+			const char *dev_name, void *raw_data,
+			struct vfsmount *mnt)
+{
+	return get_sb_single(fs_type, flags, raw_data,
+				fuse_ctl_fill_super, mnt);
+}
+
+static void fuse_ctl_kill_sb(struct super_block *sb)
+{
+	mutex_lock(&fuse_mutex);
+	fuse_control_sb = NULL;
+	mutex_unlock(&fuse_mutex);
+
+	kill_litter_super(sb);
+}
+
+static struct file_system_type fuse_ctl_fs_type = {
+	.owner		= THIS_MODULE,
+	.name		= "fusectl",
+	.get_sb		= fuse_ctl_get_sb,
+	.kill_sb	= fuse_ctl_kill_sb,
+};
+
+int __init fuse_ctl_init(void)
+{
+	return register_filesystem(&fuse_ctl_fs_type);
+}
+
+void fuse_ctl_cleanup(void)
+{
+	unregister_filesystem(&fuse_ctl_fs_type);
+}
diff --git a/fs/inotify_user.c b/fs/inotify_user.c
new file mode 100644
index 000000000..017cb0f13
--- /dev/null
+++ b/fs/inotify_user.c
@@ -0,0 +1,719 @@
+/*
+ * fs/inotify_user.c - inotify support for userspace
+ *
+ * Authors:
+ *	John McCutchan	<ttb@tentacle.dhs.org>
+ *	Robert Love	<rml@novell.com>
+ *
+ * Copyright (C) 2005 John McCutchan
+ * Copyright 2006 Hewlett-Packard Development Company, L.P.
+ *
+ * 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.
+ */
+
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/fs.h>
+#include <linux/file.h>
+#include <linux/mount.h>
+#include <linux/namei.h>
+#include <linux/poll.h>
+#include <linux/init.h>
+#include <linux/list.h>
+#include <linux/inotify.h>
+#include <linux/syscalls.h>
+
+#include <asm/ioctls.h>
+
+static kmem_cache_t *watch_cachep __read_mostly;
+static kmem_cache_t *event_cachep __read_mostly;
+
+static struct vfsmount *inotify_mnt __read_mostly;
+
+/* these are configurable via /proc/sys/fs/inotify/ */
+int inotify_max_user_instances __read_mostly;
+int inotify_max_user_watches __read_mostly;
+int inotify_max_queued_events __read_mostly;
+
+/*
+ * Lock ordering:
+ *
+ * inotify_dev->up_mutex (ensures we don't re-add the same watch)
+ * 	inode->inotify_mutex (protects inode's watch list)
+ * 		inotify_handle->mutex (protects inotify_handle's watch list)
+ * 			inotify_dev->ev_mutex (protects device's event queue)
+ */
+
+/*
+ * Lifetimes of the main data structures:
+ *
+ * inotify_device: Lifetime is managed by reference count, from
+ * sys_inotify_init() until release.  Additional references can bump the count
+ * via get_inotify_dev() and drop the count via put_inotify_dev().
+ *
+ * inotify_user_watch: Lifetime is from create_watch() to the receipt of an
+ * IN_IGNORED event from inotify, or when using IN_ONESHOT, to receipt of the
+ * first event, or to inotify_destroy().
+ */
+
+/*
+ * struct inotify_device - represents an inotify instance
+ *
+ * This structure is protected by the mutex 'mutex'.
+ */
+struct inotify_device {
+	wait_queue_head_t 	wq;		/* wait queue for i/o */
+	struct mutex		ev_mutex;	/* protects event queue */
+	struct mutex		up_mutex;	/* synchronizes watch updates */
+	struct list_head 	events;		/* list of queued events */
+	atomic_t		count;		/* reference count */
+	struct user_struct	*user;		/* user who opened this dev */
+	struct inotify_handle	*ih;		/* inotify handle */
+	unsigned int		queue_size;	/* size of the queue (bytes) */
+	unsigned int		event_count;	/* number of pending events */
+	unsigned int		max_events;	/* maximum number of events */
+};
+
+/*
+ * struct inotify_kernel_event - An inotify event, originating from a watch and
+ * queued for user-space.  A list of these is attached to each instance of the
+ * device.  In read(), this list is walked and all events that can fit in the
+ * buffer are returned.
+ *
+ * Protected by dev->ev_mutex of the device in which we are queued.
+ */
+struct inotify_kernel_event {
+	struct inotify_event	event;	/* the user-space event */
+	struct list_head        list;	/* entry in inotify_device's list */
+	char			*name;	/* filename, if any */
+};
+
+/*
+ * struct inotify_user_watch - our version of an inotify_watch, we add
+ * a reference to the associated inotify_device.
+ */
+struct inotify_user_watch {
+	struct inotify_device	*dev;	/* associated device */
+	struct inotify_watch	wdata;	/* inotify watch data */
+};
+
+#ifdef CONFIG_SYSCTL
+
+#include <linux/sysctl.h>
+
+static int zero;
+
+ctl_table inotify_table[] = {
+	{
+		.ctl_name	= INOTIFY_MAX_USER_INSTANCES,
+		.procname	= "max_user_instances",
+		.data		= &inotify_max_user_instances,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= &proc_dointvec_minmax,
+		.strategy	= &sysctl_intvec,
+		.extra1		= &zero,
+	},
+	{
+		.ctl_name	= INOTIFY_MAX_USER_WATCHES,
+		.procname	= "max_user_watches",
+		.data		= &inotify_max_user_watches,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= &proc_dointvec_minmax,
+		.strategy	= &sysctl_intvec,
+		.extra1		= &zero,
+	},
+	{
+		.ctl_name	= INOTIFY_MAX_QUEUED_EVENTS,
+		.procname	= "max_queued_events",
+		.data		= &inotify_max_queued_events,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= &proc_dointvec_minmax,
+		.strategy	= &sysctl_intvec,
+		.extra1		= &zero
+	},
+	{ .ctl_name = 0 }
+};
+#endif /* CONFIG_SYSCTL */
+
+static inline void get_inotify_dev(struct inotify_device *dev)
+{
+	atomic_inc(&dev->count);
+}
+
+static inline void put_inotify_dev(struct inotify_device *dev)
+{
+	if (atomic_dec_and_test(&dev->count)) {
+		atomic_dec(&dev->user->inotify_devs);
+		free_uid(dev->user);
+		kfree(dev);
+	}
+}
+
+/*
+ * free_inotify_user_watch - cleans up the watch and its references
+ */
+static void free_inotify_user_watch(struct inotify_watch *w)
+{
+	struct inotify_user_watch *watch;
+	struct inotify_device *dev;
+
+	watch = container_of(w, struct inotify_user_watch, wdata);
+	dev = watch->dev;
+
+	atomic_dec(&dev->user->inotify_watches);
+	put_inotify_dev(dev);
+	kmem_cache_free(watch_cachep, watch);
+}
+
+/*
+ * kernel_event - create a new kernel event with the given parameters
+ *
+ * This function can sleep.
+ */
+static struct inotify_kernel_event * kernel_event(s32 wd, u32 mask, u32 cookie,
+						  const char *name)
+{
+	struct inotify_kernel_event *kevent;
+
+	kevent = kmem_cache_alloc(event_cachep, GFP_NOFS);
+	if (unlikely(!kevent))
+		return NULL;
+
+	/* we hand this out to user-space, so zero it just in case */
+	memset(&kevent->event, 0, sizeof(struct inotify_event));
+
+	kevent->event.wd = wd;
+	kevent->event.mask = mask;
+	kevent->event.cookie = cookie;
+
+	INIT_LIST_HEAD(&kevent->list);
+
+	if (name) {
+		size_t len, rem, event_size = sizeof(struct inotify_event);
+
+		/*
+		 * We need to pad the filename so as to properly align an
+		 * array of inotify_event structures.  Because the structure is
+		 * small and the common case is a small filename, we just round
+		 * up to the next multiple of the structure's sizeof.  This is
+		 * simple and safe for all architectures.
+		 */
+		len = strlen(name) + 1;
+		rem = event_size - len;
+		if (len > event_size) {
+			rem = event_size - (len % event_size);
+			if (len % event_size == 0)
+				rem = 0;
+		}
+
+		kevent->name = kmalloc(len + rem, GFP_KERNEL);
+		if (unlikely(!kevent->name)) {
+			kmem_cache_free(event_cachep, kevent);
+			return NULL;
+		}
+		memcpy(kevent->name, name, len);
+		if (rem)
+			memset(kevent->name + len, 0, rem);
+		kevent->event.len = len + rem;
+	} else {
+		kevent->event.len = 0;
+		kevent->name = NULL;
+	}
+
+	return kevent;
+}
+
+/*
+ * inotify_dev_get_event - return the next event in the given dev's queue
+ *
+ * Caller must hold dev->ev_mutex.
+ */
+static inline struct inotify_kernel_event *
+inotify_dev_get_event(struct inotify_device *dev)
+{
+	return list_entry(dev->events.next, struct inotify_kernel_event, list);
+}
+
+/*
+ * inotify_dev_queue_event - event handler registered with core inotify, adds
+ * a new event to the given device
+ *
+ * Can sleep (calls kernel_event()).
+ */
+static void inotify_dev_queue_event(struct inotify_watch *w, u32 wd, u32 mask,
+				    u32 cookie, const char *name,
+				    struct inode *ignored)
+{
+	struct inotify_user_watch *watch;
+	struct inotify_device *dev;
+	struct inotify_kernel_event *kevent, *last;
+
+	watch = container_of(w, struct inotify_user_watch, wdata);
+	dev = watch->dev;
+
+	mutex_lock(&dev->ev_mutex);
+
+	/* we can safely put the watch as we don't reference it while
+	 * generating the event
+	 */
+	if (mask & IN_IGNORED || mask & IN_ONESHOT)
+		put_inotify_watch(w); /* final put */
+
+	/* coalescing: drop this event if it is a dupe of the previous */
+	last = inotify_dev_get_event(dev);
+	if (last && last->event.mask == mask && last->event.wd == wd &&
+			last->event.cookie == cookie) {
+		const char *lastname = last->name;
+
+		if (!name && !lastname)
+			goto out;
+		if (name && lastname && !strcmp(lastname, name))
+			goto out;
+	}
+
+	/* the queue overflowed and we already sent the Q_OVERFLOW event */
+	if (unlikely(dev->event_count > dev->max_events))
+		goto out;
+
+	/* if the queue overflows, we need to notify user space */
+	if (unlikely(dev->event_count == dev->max_events))
+		kevent = kernel_event(-1, IN_Q_OVERFLOW, cookie, NULL);
+	else
+		kevent = kernel_event(wd, mask, cookie, name);
+
+	if (unlikely(!kevent))
+		goto out;
+
+	/* queue the event and wake up anyone waiting */
+	dev->event_count++;
+	dev->queue_size += sizeof(struct inotify_event) + kevent->event.len;
+	list_add_tail(&kevent->list, &dev->events);
+	wake_up_interruptible(&dev->wq);
+
+out:
+	mutex_unlock(&dev->ev_mutex);
+}
+
+/*
+ * remove_kevent - cleans up and ultimately frees the given kevent
+ *
+ * Caller must hold dev->ev_mutex.
+ */
+static void remove_kevent(struct inotify_device *dev,
+			  struct inotify_kernel_event *kevent)
+{
+	list_del(&kevent->list);
+
+	dev->event_count--;
+	dev->queue_size -= sizeof(struct inotify_event) + kevent->event.len;
+
+	kfree(kevent->name);
+	kmem_cache_free(event_cachep, kevent);
+}
+
+/*
+ * inotify_dev_event_dequeue - destroy an event on the given device
+ *
+ * Caller must hold dev->ev_mutex.
+ */
+static void inotify_dev_event_dequeue(struct inotify_device *dev)
+{
+	if (!list_empty(&dev->events)) {
+		struct inotify_kernel_event *kevent;
+		kevent = inotify_dev_get_event(dev);
+		remove_kevent(dev, kevent);
+	}
+}
+
+/*
+ * find_inode - resolve a user-given path to a specific inode and return a nd
+ */
+static int find_inode(const char __user *dirname, struct nameidata *nd,
+		      unsigned flags)
+{
+	int error;
+
+	error = __user_walk(dirname, flags, nd);
+	if (error)
+		return error;
+	/* you can only watch an inode if you have read permissions on it */
+	error = vfs_permission(nd, MAY_READ);
+	if (error)
+		path_release(nd);
+	return error;
+}
+
+/*
+ * create_watch - creates a watch on the given device.
+ *
+ * Callers must hold dev->up_mutex.
+ */
+static int create_watch(struct inotify_device *dev, struct inode *inode,
+			u32 mask)
+{
+	struct inotify_user_watch *watch;
+	int ret;
+
+	if (atomic_read(&dev->user->inotify_watches) >=
+			inotify_max_user_watches)
+		return -ENOSPC;
+
+	watch = kmem_cache_alloc(watch_cachep, GFP_KERNEL);
+	if (unlikely(!watch))
+		return -ENOMEM;
+
+	/* save a reference to device and bump the count to make it official */
+	get_inotify_dev(dev);
+	watch->dev = dev;
+
+	atomic_inc(&dev->user->inotify_watches);
+
+	inotify_init_watch(&watch->wdata);
+	ret = inotify_add_watch(dev->ih, &watch->wdata, inode, mask);
+	if (ret < 0)
+		free_inotify_user_watch(&watch->wdata);
+
+	return ret;
+}
+
+/* Device Interface */
+
+static unsigned int inotify_poll(struct file *file, poll_table *wait)
+{
+	struct inotify_device *dev = file->private_data;
+	int ret = 0;
+
+	poll_wait(file, &dev->wq, wait);
+	mutex_lock(&dev->ev_mutex);
+	if (!list_empty(&dev->events))
+		ret = POLLIN | POLLRDNORM;
+	mutex_unlock(&dev->ev_mutex);
+
+	return ret;
+}
+
+static ssize_t inotify_read(struct file *file, char __user *buf,
+			    size_t count, loff_t *pos)
+{
+	size_t event_size = sizeof (struct inotify_event);
+	struct inotify_device *dev;
+	char __user *start;
+	int ret;
+	DEFINE_WAIT(wait);
+
+	start = buf;
+	dev = file->private_data;
+
+	while (1) {
+		int events;
+
+		prepare_to_wait(&dev->wq, &wait, TASK_INTERRUPTIBLE);
+
+		mutex_lock(&dev->ev_mutex);
+		events = !list_empty(&dev->events);
+		mutex_unlock(&dev->ev_mutex);
+		if (events) {
+			ret = 0;
+			break;
+		}
+
+		if (file->f_flags & O_NONBLOCK) {
+			ret = -EAGAIN;
+			break;
+		}
+
+		if (signal_pending(current)) {
+			ret = -EINTR;
+			break;
+		}
+
+		schedule();
+	}
+
+	finish_wait(&dev->wq, &wait);
+	if (ret)
+		return ret;
+
+	mutex_lock(&dev->ev_mutex);
+	while (1) {
+		struct inotify_kernel_event *kevent;
+
+		ret = buf - start;
+		if (list_empty(&dev->events))
+			break;
+
+		kevent = inotify_dev_get_event(dev);
+		if (event_size + kevent->event.len > count)
+			break;
+
+		if (copy_to_user(buf, &kevent->event, event_size)) {
+			ret = -EFAULT;
+			break;
+		}
+		buf += event_size;
+		count -= event_size;
+
+		if (kevent->name) {
+			if (copy_to_user(buf, kevent->name, kevent->event.len)){
+				ret = -EFAULT;
+				break;
+			}
+			buf += kevent->event.len;
+			count -= kevent->event.len;
+		}
+
+		remove_kevent(dev, kevent);
+	}
+	mutex_unlock(&dev->ev_mutex);
+
+	return ret;
+}
+
+static int inotify_release(struct inode *ignored, struct file *file)
+{
+	struct inotify_device *dev = file->private_data;
+
+	inotify_destroy(dev->ih);
+
+	/* destroy all of the events on this device */
+	mutex_lock(&dev->ev_mutex);
+	while (!list_empty(&dev->events))
+		inotify_dev_event_dequeue(dev);
+	mutex_unlock(&dev->ev_mutex);
+
+	/* free this device: the put matching the get in inotify_init() */
+	put_inotify_dev(dev);
+
+	return 0;
+}
+
+static long inotify_ioctl(struct file *file, unsigned int cmd,
+			  unsigned long arg)
+{
+	struct inotify_device *dev;
+	void __user *p;
+	int ret = -ENOTTY;
+
+	dev = file->private_data;
+	p = (void __user *) arg;
+
+	switch (cmd) {
+	case FIONREAD:
+		ret = put_user(dev->queue_size, (int __user *) p);
+		break;
+	}
+
+	return ret;
+}
+
+static const struct file_operations inotify_fops = {
+	.poll           = inotify_poll,
+	.read           = inotify_read,
+	.release        = inotify_release,
+	.unlocked_ioctl = inotify_ioctl,
+	.compat_ioctl	= inotify_ioctl,
+};
+
+static const struct inotify_operations inotify_user_ops = {
+	.handle_event	= inotify_dev_queue_event,
+	.destroy_watch	= free_inotify_user_watch,
+};
+
+asmlinkage long sys_inotify_init(void)
+{
+	struct inotify_device *dev;
+	struct inotify_handle *ih;
+	struct user_struct *user;
+	struct file *filp;
+	int fd, ret;
+
+	fd = get_unused_fd();
+	if (fd < 0)
+		return fd;
+
+	filp = get_empty_filp();
+	if (!filp) {
+		ret = -ENFILE;
+		goto out_put_fd;
+	}
+
+	user = get_uid(current->user);
+	if (unlikely(atomic_read(&user->inotify_devs) >=
+			inotify_max_user_instances)) {
+		ret = -EMFILE;
+		goto out_free_uid;
+	}
+
+	dev = kmalloc(sizeof(struct inotify_device), GFP_KERNEL);
+	if (unlikely(!dev)) {
+		ret = -ENOMEM;
+		goto out_free_uid;
+	}
+
+	ih = inotify_init(&inotify_user_ops);
+	if (unlikely(IS_ERR(ih))) {
+		ret = PTR_ERR(ih);
+		goto out_free_dev;
+	}
+	dev->ih = ih;
+
+	filp->f_op = &inotify_fops;
+	filp->f_vfsmnt = mntget(inotify_mnt);
+	filp->f_dentry = dget(inotify_mnt->mnt_root);
+	filp->f_mapping = filp->f_dentry->d_inode->i_mapping;
+	filp->f_mode = FMODE_READ;
+	filp->f_flags = O_RDONLY;
+	filp->private_data = dev;
+
+	INIT_LIST_HEAD(&dev->events);
+	init_waitqueue_head(&dev->wq);
+	mutex_init(&dev->ev_mutex);
+	mutex_init(&dev->up_mutex);
+	dev->event_count = 0;
+	dev->queue_size = 0;
+	dev->max_events = inotify_max_queued_events;
+	dev->user = user;
+	atomic_set(&dev->count, 0);
+
+	get_inotify_dev(dev);
+	atomic_inc(&user->inotify_devs);
+	fd_install(fd, filp);
+
+	return fd;
+out_free_dev:
+	kfree(dev);
+out_free_uid:
+	free_uid(user);
+	put_filp(filp);
+out_put_fd:
+	put_unused_fd(fd);
+	return ret;
+}
+
+asmlinkage long sys_inotify_add_watch(int fd, const char __user *path, u32 mask)
+{
+	struct inode *inode;
+	struct inotify_device *dev;
+	struct nameidata nd;
+	struct file *filp;
+	int ret, fput_needed;
+	unsigned flags = 0;
+
+	filp = fget_light(fd, &fput_needed);
+	if (unlikely(!filp))
+		return -EBADF;
+
+	/* verify that this is indeed an inotify instance */
+	if (unlikely(filp->f_op != &inotify_fops)) {
+		ret = -EINVAL;
+		goto fput_and_out;
+	}
+
+	if (!(mask & IN_DONT_FOLLOW))
+		flags |= LOOKUP_FOLLOW;
+	if (mask & IN_ONLYDIR)
+		flags |= LOOKUP_DIRECTORY;
+
+	ret = find_inode(path, &nd, flags);
+	if (unlikely(ret))
+		goto fput_and_out;
+
+	/* inode held in place by reference to nd; dev by fget on fd */
+	inode = nd.dentry->d_inode;
+	dev = filp->private_data;
+
+	mutex_lock(&dev->up_mutex);
+	ret = inotify_find_update_watch(dev->ih, inode, mask);
+	if (ret == -ENOENT)
+		ret = create_watch(dev, inode, mask);
+	mutex_unlock(&dev->up_mutex);
+
+	path_release(&nd);
+fput_and_out:
+	fput_light(filp, fput_needed);
+	return ret;
+}
+
+asmlinkage long sys_inotify_rm_watch(int fd, u32 wd)
+{
+	struct file *filp;
+	struct inotify_device *dev;
+	int ret, fput_needed;
+
+	filp = fget_light(fd, &fput_needed);
+	if (unlikely(!filp))
+		return -EBADF;
+
+	/* verify that this is indeed an inotify instance */
+	if (unlikely(filp->f_op != &inotify_fops)) {
+		ret = -EINVAL;
+		goto out;
+	}
+
+	dev = filp->private_data;
+
+	/* we free our watch data when we get IN_IGNORED */
+	ret = inotify_rm_wd(dev->ih, wd);
+
+out:
+	fput_light(filp, fput_needed);
+	return ret;
+}
+
+static int
+inotify_get_sb(struct file_system_type *fs_type, int flags,
+	       const char *dev_name, void *data, struct vfsmount *mnt)
+{
+	return get_sb_pseudo(fs_type, "inotify", NULL, 0xBAD1DEA, mnt);
+}
+
+static struct file_system_type inotify_fs_type = {
+    .name           = "inotifyfs",
+    .get_sb         = inotify_get_sb,
+    .kill_sb        = kill_anon_super,
+};
+
+/*
+ * inotify_user_setup - Our initialization function.  Note that we cannnot return
+ * error because we have compiled-in VFS hooks.  So an (unlikely) failure here
+ * must result in panic().
+ */
+static int __init inotify_user_setup(void)
+{
+	int ret;
+
+	ret = register_filesystem(&inotify_fs_type);
+	if (unlikely(ret))
+		panic("inotify: register_filesystem returned %d!\n", ret);
+
+	inotify_mnt = kern_mount(&inotify_fs_type);
+	if (IS_ERR(inotify_mnt))
+		panic("inotify: kern_mount ret %ld!\n", PTR_ERR(inotify_mnt));
+
+	inotify_max_queued_events = 16384;
+	inotify_max_user_instances = 128;
+	inotify_max_user_watches = 8192;
+
+	watch_cachep = kmem_cache_create("inotify_watch_cache",
+					 sizeof(struct inotify_user_watch),
+					 0, SLAB_PANIC, NULL, NULL);
+	event_cachep = kmem_cache_create("inotify_event_cache",
+					 sizeof(struct inotify_kernel_event),
+					 0, SLAB_PANIC, NULL, NULL);
+
+	return 0;
+}
+
+module_init(inotify_user_setup);
diff --git a/fs/jffs2/acl.c b/fs/jffs2/acl.c
new file mode 100644
index 000000000..0ae3cd107
--- /dev/null
+++ b/fs/jffs2/acl.c
@@ -0,0 +1,485 @@
+/*
+ * JFFS2 -- Journalling Flash File System, Version 2.
+ *
+ * Copyright (C) 2006  NEC Corporation
+ *
+ * Created by KaiGai Kohei <kaigai@ak.jp.nec.com>
+ *
+ * For licensing information, see the file 'LICENCE' in this directory.
+ *
+ */
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/fs.h>
+#include <linux/time.h>
+#include <linux/crc32.h>
+#include <linux/jffs2.h>
+#include <linux/xattr.h>
+#include <linux/posix_acl_xattr.h>
+#include <linux/mtd/mtd.h>
+#include "nodelist.h"
+
+static size_t jffs2_acl_size(int count)
+{
+	if (count <= 4) {
+		return sizeof(struct jffs2_acl_header)
+		       + count * sizeof(struct jffs2_acl_entry_short);
+	} else {
+		return sizeof(struct jffs2_acl_header)
+		       + 4 * sizeof(struct jffs2_acl_entry_short)
+		       + (count - 4) * sizeof(struct jffs2_acl_entry);
+	}
+}
+
+static int jffs2_acl_count(size_t size)
+{
+	size_t s;
+
+	size -= sizeof(struct jffs2_acl_header);
+	s = size - 4 * sizeof(struct jffs2_acl_entry_short);
+	if (s < 0) {
+		if (size % sizeof(struct jffs2_acl_entry_short))
+			return -1;
+		return size / sizeof(struct jffs2_acl_entry_short);
+	} else {
+		if (s % sizeof(struct jffs2_acl_entry))
+			return -1;
+		return s / sizeof(struct jffs2_acl_entry) + 4;
+	}
+}
+
+static struct posix_acl *jffs2_acl_from_medium(void *value, size_t size)
+{
+	void *end = value + size;
+	struct jffs2_acl_header *header = value;
+	struct jffs2_acl_entry *entry;
+	struct posix_acl *acl;
+	uint32_t ver;
+	int i, count;
+
+	if (!value)
+		return NULL;
+	if (size < sizeof(struct jffs2_acl_header))
+		return ERR_PTR(-EINVAL);
+	ver = je32_to_cpu(header->a_version);
+	if (ver != JFFS2_ACL_VERSION) {
+		JFFS2_WARNING("Invalid ACL version. (=%u)\n", ver);
+		return ERR_PTR(-EINVAL);
+	}
+
+	value += sizeof(struct jffs2_acl_header);
+	count = jffs2_acl_count(size);
+	if (count < 0)
+		return ERR_PTR(-EINVAL);
+	if (count == 0)
+		return NULL;
+
+	acl = posix_acl_alloc(count, GFP_KERNEL);
+	if (!acl)
+		return ERR_PTR(-ENOMEM);
+
+	for (i=0; i < count; i++) {
+		entry = value;
+		if (value + sizeof(struct jffs2_acl_entry_short) > end)
+			goto fail;
+		acl->a_entries[i].e_tag = je16_to_cpu(entry->e_tag);
+		acl->a_entries[i].e_perm = je16_to_cpu(entry->e_perm);
+		switch (acl->a_entries[i].e_tag) {
+			case ACL_USER_OBJ:
+			case ACL_GROUP_OBJ:
+			case ACL_MASK:
+			case ACL_OTHER:
+				value += sizeof(struct jffs2_acl_entry_short);
+				acl->a_entries[i].e_id = ACL_UNDEFINED_ID;
+				break;
+
+			case ACL_USER:
+			case ACL_GROUP:
+				value += sizeof(struct jffs2_acl_entry);
+				if (value > end)
+					goto fail;
+				acl->a_entries[i].e_id = je32_to_cpu(entry->e_id);
+				break;
+
+			default:
+				goto fail;
+		}
+	}
+	if (value != end)
+		goto fail;
+	return acl;
+ fail:
+	posix_acl_release(acl);
+	return ERR_PTR(-EINVAL);
+}
+
+static void *jffs2_acl_to_medium(const struct posix_acl *acl, size_t *size)
+{
+	struct jffs2_acl_header *header;
+	struct jffs2_acl_entry *entry;
+	void *e;
+	size_t i;
+
+	*size = jffs2_acl_size(acl->a_count);
+	header = kmalloc(sizeof(*header) + acl->a_count * sizeof(*entry), GFP_KERNEL);
+	if (!header)
+		return ERR_PTR(-ENOMEM);
+	header->a_version = cpu_to_je32(JFFS2_ACL_VERSION);
+	e = header + 1;
+	for (i=0; i < acl->a_count; i++) {
+		entry = e;
+		entry->e_tag = cpu_to_je16(acl->a_entries[i].e_tag);
+		entry->e_perm = cpu_to_je16(acl->a_entries[i].e_perm);
+		switch(acl->a_entries[i].e_tag) {
+			case ACL_USER:
+			case ACL_GROUP:
+				entry->e_id = cpu_to_je32(acl->a_entries[i].e_id);
+				e += sizeof(struct jffs2_acl_entry);
+				break;
+
+			case ACL_USER_OBJ:
+			case ACL_GROUP_OBJ:
+			case ACL_MASK:
+			case ACL_OTHER:
+				e += sizeof(struct jffs2_acl_entry_short);
+				break;
+
+			default:
+				goto fail;
+		}
+	}
+	return header;
+ fail:
+	kfree(header);
+	return ERR_PTR(-EINVAL);
+}
+
+static struct posix_acl *jffs2_iget_acl(struct inode *inode, struct posix_acl **i_acl)
+{
+	struct posix_acl *acl = JFFS2_ACL_NOT_CACHED;
+
+	spin_lock(&inode->i_lock);
+	if (*i_acl != JFFS2_ACL_NOT_CACHED)
+		acl = posix_acl_dup(*i_acl);
+	spin_unlock(&inode->i_lock);
+	return acl;
+}
+
+static void jffs2_iset_acl(struct inode *inode, struct posix_acl **i_acl, struct posix_acl *acl)
+{
+	spin_lock(&inode->i_lock);
+	if (*i_acl != JFFS2_ACL_NOT_CACHED)
+		posix_acl_release(*i_acl);
+	*i_acl = posix_acl_dup(acl);
+	spin_unlock(&inode->i_lock);
+}
+
+static struct posix_acl *jffs2_get_acl(struct inode *inode, int type)
+{
+	struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode);
+	struct posix_acl *acl;
+	char *value = NULL;
+	int rc, xprefix;
+
+	switch (type) {
+	case ACL_TYPE_ACCESS:
+		acl = jffs2_iget_acl(inode, &f->i_acl_access);
+		if (acl != JFFS2_ACL_NOT_CACHED)
+			return acl;
+		xprefix = JFFS2_XPREFIX_ACL_ACCESS;
+		break;
+	case ACL_TYPE_DEFAULT:
+		acl = jffs2_iget_acl(inode, &f->i_acl_default);
+		if (acl != JFFS2_ACL_NOT_CACHED)
+			return acl;
+		xprefix = JFFS2_XPREFIX_ACL_DEFAULT;
+		break;
+	default:
+		return ERR_PTR(-EINVAL);
+	}
+	rc = do_jffs2_getxattr(inode, xprefix, "", NULL, 0);
+	if (rc > 0) {
+		value = kmalloc(rc, GFP_KERNEL);
+		if (!value)
+			return ERR_PTR(-ENOMEM);
+		rc = do_jffs2_getxattr(inode, xprefix, "", value, rc);
+	}
+	if (rc > 0) {
+		acl = jffs2_acl_from_medium(value, rc);
+	} else if (rc == -ENODATA || rc == -ENOSYS) {
+		acl = NULL;
+	} else {
+		acl = ERR_PTR(rc);
+	}
+	if (value)
+		kfree(value);
+	if (!IS_ERR(acl)) {
+		switch (type) {
+		case ACL_TYPE_ACCESS:
+			jffs2_iset_acl(inode, &f->i_acl_access, acl);
+			break;
+		case ACL_TYPE_DEFAULT:
+			jffs2_iset_acl(inode, &f->i_acl_default, acl);
+			break;
+		}
+	}
+	return acl;
+}
+
+static int jffs2_set_acl(struct inode *inode, int type, struct posix_acl *acl)
+{
+	struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode);
+	size_t size = 0;
+	char *value = NULL;
+	int rc, xprefix;
+
+	if (S_ISLNK(inode->i_mode))
+		return -EOPNOTSUPP;
+
+	switch (type) {
+	case ACL_TYPE_ACCESS:
+		xprefix = JFFS2_XPREFIX_ACL_ACCESS;
+		if (acl) {
+			mode_t mode = inode->i_mode;
+			rc = posix_acl_equiv_mode(acl, &mode);
+			if (rc < 0)
+				return rc;
+			if (inode->i_mode != mode) {
+				inode->i_mode = mode;
+				jffs2_dirty_inode(inode);
+			}
+			if (rc == 0)
+				acl = NULL;
+		}
+		break;
+	case ACL_TYPE_DEFAULT:
+		xprefix = JFFS2_XPREFIX_ACL_DEFAULT;
+		if (!S_ISDIR(inode->i_mode))
+			return acl ? -EACCES : 0;
+		break;
+	default:
+		return -EINVAL;
+	}
+	if (acl) {
+		value = jffs2_acl_to_medium(acl, &size);
+		if (IS_ERR(value))
+			return PTR_ERR(value);
+	}
+
+	rc = do_jffs2_setxattr(inode, xprefix, "", value, size, 0);
+	if (!value && rc == -ENODATA)
+		rc = 0;
+	if (value)
+		kfree(value);
+	if (!rc) {
+		switch(type) {
+		case ACL_TYPE_ACCESS:
+			jffs2_iset_acl(inode, &f->i_acl_access, acl);
+			break;
+		case ACL_TYPE_DEFAULT:
+			jffs2_iset_acl(inode, &f->i_acl_default, acl);
+			break;
+		}
+	}
+	return rc;
+}
+
+static int jffs2_check_acl(struct inode *inode, int mask)
+{
+	struct posix_acl *acl;
+	int rc;
+
+	acl = jffs2_get_acl(inode, ACL_TYPE_ACCESS);
+	if (IS_ERR(acl))
+		return PTR_ERR(acl);
+	if (acl) {
+		rc = posix_acl_permission(inode, acl, mask);
+		posix_acl_release(acl);
+		return rc;
+	}
+	return -EAGAIN;
+}
+
+int jffs2_permission(struct inode *inode, int mask, struct nameidata *nd)
+{
+	return generic_permission(inode, mask, jffs2_check_acl);
+}
+
+int jffs2_init_acl(struct inode *inode, struct inode *dir)
+{
+	struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode);
+	struct posix_acl *acl = NULL, *clone;
+	mode_t mode;
+	int rc = 0;
+
+	f->i_acl_access = JFFS2_ACL_NOT_CACHED;
+	f->i_acl_default = JFFS2_ACL_NOT_CACHED;
+	if (!S_ISLNK(inode->i_mode)) {
+		acl = jffs2_get_acl(dir, ACL_TYPE_DEFAULT);
+		if (IS_ERR(acl))
+			return PTR_ERR(acl);
+		if (!acl)
+			inode->i_mode &= ~current->fs->umask;
+	}
+	if (acl) {
+		if (S_ISDIR(inode->i_mode)) {
+			rc = jffs2_set_acl(inode, ACL_TYPE_DEFAULT, acl);
+			if (rc)
+				goto cleanup;
+		}
+		clone = posix_acl_clone(acl, GFP_KERNEL);
+		rc = -ENOMEM;
+		if (!clone)
+			goto cleanup;
+		mode = inode->i_mode;
+		rc = posix_acl_create_masq(clone, &mode);
+		if (rc >= 0) {
+			inode->i_mode = mode;
+			if (rc > 0)
+				rc = jffs2_set_acl(inode, ACL_TYPE_ACCESS, clone);
+		}
+		posix_acl_release(clone);
+	}
+ cleanup:
+	posix_acl_release(acl);
+	return rc;
+}
+
+void jffs2_clear_acl(struct jffs2_inode_info *f)
+{
+	if (f->i_acl_access && f->i_acl_access != JFFS2_ACL_NOT_CACHED) {
+		posix_acl_release(f->i_acl_access);
+		f->i_acl_access = JFFS2_ACL_NOT_CACHED;
+	}
+	if (f->i_acl_default && f->i_acl_default != JFFS2_ACL_NOT_CACHED) {
+		posix_acl_release(f->i_acl_default);
+		f->i_acl_default = JFFS2_ACL_NOT_CACHED;
+	}
+}
+
+int jffs2_acl_chmod(struct inode *inode)
+{
+	struct posix_acl *acl, *clone;
+	int rc;
+
+	if (S_ISLNK(inode->i_mode))
+		return -EOPNOTSUPP;
+	acl = jffs2_get_acl(inode, ACL_TYPE_ACCESS);
+	if (IS_ERR(acl) || !acl)
+		return PTR_ERR(acl);
+	clone = posix_acl_clone(acl, GFP_KERNEL);
+	posix_acl_release(acl);
+	if (!clone)
+		return -ENOMEM;
+	rc = posix_acl_chmod_masq(clone, inode->i_mode);
+	if (!rc)
+		rc = jffs2_set_acl(inode, ACL_TYPE_ACCESS, clone);
+	posix_acl_release(clone);
+	return rc;
+}
+
+static size_t jffs2_acl_access_listxattr(struct inode *inode, char *list, size_t list_size,
+					 const char *name, size_t name_len)
+{
+	const int retlen = sizeof(POSIX_ACL_XATTR_ACCESS);
+
+	if (list && retlen <= list_size)
+		strcpy(list, POSIX_ACL_XATTR_ACCESS);
+	return retlen;
+}
+
+static size_t jffs2_acl_default_listxattr(struct inode *inode, char *list, size_t list_size,
+					  const char *name, size_t name_len)
+{
+	const int retlen = sizeof(POSIX_ACL_XATTR_DEFAULT);
+
+	if (list && retlen <= list_size)
+		strcpy(list, POSIX_ACL_XATTR_DEFAULT);
+	return retlen;
+}
+
+static int jffs2_acl_getxattr(struct inode *inode, int type, void *buffer, size_t size)
+{
+	struct posix_acl *acl;
+	int rc;
+
+	acl = jffs2_get_acl(inode, type);
+	if (IS_ERR(acl))
+		return PTR_ERR(acl);
+	if (!acl)
+		return -ENODATA;
+	rc = posix_acl_to_xattr(acl, buffer, size);
+	posix_acl_release(acl);
+
+	return rc;
+}
+
+static int jffs2_acl_access_getxattr(struct inode *inode, const char *name, void *buffer, size_t size)
+{
+	if (name[0] != '\0')
+		return -EINVAL;
+	return jffs2_acl_getxattr(inode, ACL_TYPE_ACCESS, buffer, size);
+}
+
+static int jffs2_acl_default_getxattr(struct inode *inode, const char *name, void *buffer, size_t size)
+{
+	if (name[0] != '\0')
+		return -EINVAL;
+	return jffs2_acl_getxattr(inode, ACL_TYPE_DEFAULT, buffer, size);
+}
+
+static int jffs2_acl_setxattr(struct inode *inode, int type, const void *value, size_t size)
+{
+	struct posix_acl *acl;
+	int rc;
+
+	if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER))
+		return -EPERM;
+
+	if (value) {
+		acl = posix_acl_from_xattr(value, size);
+		if (IS_ERR(acl))
+			return PTR_ERR(acl);
+		if (acl) {
+			rc = posix_acl_valid(acl);
+			if (rc)
+				goto out;
+		}
+	} else {
+		acl = NULL;
+	}
+	rc = jffs2_set_acl(inode, type, acl);
+ out:
+	posix_acl_release(acl);
+	return rc;
+}
+
+static int jffs2_acl_access_setxattr(struct inode *inode, const char *name,
+				     const void *buffer, size_t size, int flags)
+{
+	if (name[0] != '\0')
+		return -EINVAL;
+	return jffs2_acl_setxattr(inode, ACL_TYPE_ACCESS, buffer, size);
+}
+
+static int jffs2_acl_default_setxattr(struct inode *inode, const char *name,
+				      const void *buffer, size_t size, int flags)
+{
+	if (name[0] != '\0')
+		return -EINVAL;
+	return jffs2_acl_setxattr(inode, ACL_TYPE_DEFAULT, buffer, size);
+}
+
+struct xattr_handler jffs2_acl_access_xattr_handler = {
+	.prefix	= POSIX_ACL_XATTR_ACCESS,
+	.list	= jffs2_acl_access_listxattr,
+	.get	= jffs2_acl_access_getxattr,
+	.set	= jffs2_acl_access_setxattr,
+};
+
+struct xattr_handler jffs2_acl_default_xattr_handler = {
+	.prefix	= POSIX_ACL_XATTR_DEFAULT,
+	.list	= jffs2_acl_default_listxattr,
+	.get	= jffs2_acl_default_getxattr,
+	.set	= jffs2_acl_default_setxattr,
+};
diff --git a/fs/jffs2/acl.h b/fs/jffs2/acl.h
new file mode 100644
index 000000000..fa327dbd3
--- /dev/null
+++ b/fs/jffs2/acl.h
@@ -0,0 +1,45 @@
+/*
+ * JFFS2 -- Journalling Flash File System, Version 2.
+ *
+ * Copyright (C) 2006  NEC Corporation
+ *
+ * Created by KaiGai Kohei <kaigai@ak.jp.nec.com>
+ *
+ * For licensing information, see the file 'LICENCE' in this directory.
+ *
+ */
+struct jffs2_acl_entry {
+	jint16_t	e_tag;
+	jint16_t	e_perm;
+	jint32_t	e_id;
+};
+
+struct jffs2_acl_entry_short {
+	jint16_t	e_tag;
+	jint16_t	e_perm;
+};
+
+struct jffs2_acl_header {
+	jint32_t	a_version;
+};
+
+#ifdef CONFIG_JFFS2_FS_POSIX_ACL
+
+#define JFFS2_ACL_NOT_CACHED ((void *)-1)
+
+extern int jffs2_permission(struct inode *, int, struct nameidata *);
+extern int jffs2_acl_chmod(struct inode *);
+extern int jffs2_init_acl(struct inode *, struct inode *);
+extern void jffs2_clear_acl(struct jffs2_inode_info *);
+
+extern struct xattr_handler jffs2_acl_access_xattr_handler;
+extern struct xattr_handler jffs2_acl_default_xattr_handler;
+
+#else
+
+#define jffs2_permission NULL
+#define jffs2_acl_chmod(inode)		(0)
+#define jffs2_init_acl(inode,dir)	(0)
+#define jffs2_clear_acl(f)
+
+#endif	/* CONFIG_JFFS2_FS_POSIX_ACL */
diff --git a/fs/jffs2/jffs2_fs_i.h b/fs/jffs2/jffs2_fs_i.h
new file mode 100644
index 000000000..2e0cc8e00
--- /dev/null
+++ b/fs/jffs2/jffs2_fs_i.h
@@ -0,0 +1,55 @@
+/* $Id: jffs2_fs_i.h,v 1.19 2005/11/07 11:14:52 gleixner Exp $ */
+
+#ifndef _JFFS2_FS_I
+#define _JFFS2_FS_I
+
+#include <linux/version.h>
+#include <linux/rbtree.h>
+#include <linux/posix_acl.h>
+#include <asm/semaphore.h>
+
+struct jffs2_inode_info {
+	/* We need an internal mutex similar to inode->i_mutex.
+	   Unfortunately, we can't used the existing one, because
+	   either the GC would deadlock, or we'd have to release it
+	   before letting GC proceed. Or we'd have to put ugliness
+	   into the GC code so it didn't attempt to obtain the i_mutex
+	   for the inode(s) which are already locked */
+	struct semaphore sem;
+
+	/* The highest (datanode) version number used for this ino */
+	uint32_t highest_version;
+
+	/* List of data fragments which make up the file */
+	struct rb_root fragtree;
+
+	/* There may be one datanode which isn't referenced by any of the
+	   above fragments, if it contains a metadata update but no actual
+	   data - or if this is a directory inode */
+	/* This also holds the _only_ dnode for symlinks/device nodes,
+	   etc. */
+	struct jffs2_full_dnode *metadata;
+
+	/* Directory entries */
+	struct jffs2_full_dirent *dents;
+
+	/* The target path if this is the inode of a symlink */
+	unsigned char *target;
+
+	/* Some stuff we just have to keep in-core at all times, for each inode. */
+	struct jffs2_inode_cache *inocache;
+
+	uint16_t flags;
+	uint8_t usercompr;
+#if !defined (__ECOS)
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,2)
+	struct inode vfs_inode;
+#endif
+#endif
+#ifdef CONFIG_JFFS2_FS_POSIX_ACL
+	struct posix_acl *i_acl_access;
+	struct posix_acl *i_acl_default;
+#endif
+};
+
+#endif /* _JFFS2_FS_I */
diff --git a/fs/jffs2/jffs2_fs_sb.h b/fs/jffs2/jffs2_fs_sb.h
new file mode 100644
index 000000000..b98594992
--- /dev/null
+++ b/fs/jffs2/jffs2_fs_sb.h
@@ -0,0 +1,136 @@
+/* $Id: jffs2_fs_sb.h,v 1.54 2005/09/21 13:37:34 dedekind Exp $ */
+
+#ifndef _JFFS2_FS_SB
+#define _JFFS2_FS_SB
+
+#include <linux/types.h>
+#include <linux/spinlock.h>
+#include <linux/workqueue.h>
+#include <linux/completion.h>
+#include <asm/semaphore.h>
+#include <linux/timer.h>
+#include <linux/wait.h>
+#include <linux/list.h>
+#include <linux/rwsem.h>
+
+#define JFFS2_SB_FLAG_RO 1
+#define JFFS2_SB_FLAG_SCANNING 2 /* Flash scanning is in progress */
+#define JFFS2_SB_FLAG_BUILDING 4 /* File system building is in progress */
+
+struct jffs2_inodirty;
+
+/* A struct for the overall file system control.  Pointers to
+   jffs2_sb_info structs are named `c' in the source code.
+   Nee jffs_control
+*/
+struct jffs2_sb_info {
+	struct mtd_info *mtd;
+
+	uint32_t highest_ino;
+	uint32_t checked_ino;
+
+	unsigned int flags;
+
+	struct task_struct *gc_task;	/* GC task struct */
+	struct completion gc_thread_start; /* GC thread start completion */
+	struct completion gc_thread_exit; /* GC thread exit completion port */
+
+	struct semaphore alloc_sem;	/* Used to protect all the following
+					   fields, and also to protect against
+					   out-of-order writing of nodes. And GC. */
+	uint32_t cleanmarker_size;	/* Size of an _inline_ CLEANMARKER
+					 (i.e. zero for OOB CLEANMARKER */
+
+	uint32_t flash_size;
+	uint32_t used_size;
+	uint32_t dirty_size;
+	uint32_t wasted_size;
+	uint32_t free_size;
+	uint32_t erasing_size;
+	uint32_t bad_size;
+	uint32_t sector_size;
+	uint32_t unchecked_size;
+
+	uint32_t nr_free_blocks;
+	uint32_t nr_erasing_blocks;
+
+	/* Number of free blocks there must be before we... */
+	uint8_t resv_blocks_write;	/* ... allow a normal filesystem write */
+	uint8_t resv_blocks_deletion;	/* ... allow a normal filesystem deletion */
+	uint8_t resv_blocks_gctrigger;	/* ... wake up the GC thread */
+	uint8_t resv_blocks_gcbad;	/* ... pick a block from the bad_list to GC */
+	uint8_t resv_blocks_gcmerge;	/* ... merge pages when garbage collecting */
+
+	uint32_t nospc_dirty_size;
+
+	uint32_t nr_blocks;
+	struct jffs2_eraseblock *blocks;	/* The whole array of blocks. Used for getting blocks
+						 * from the offset (blocks[ofs / sector_size]) */
+	struct jffs2_eraseblock *nextblock;	/* The block we're currently filling */
+
+	struct jffs2_eraseblock *gcblock;	/* The block we're currently garbage-collecting */
+
+	struct list_head clean_list;		/* Blocks 100% full of clean data */
+	struct list_head very_dirty_list;	/* Blocks with lots of dirty space */
+	struct list_head dirty_list;		/* Blocks with some dirty space */
+	struct list_head erasable_list;		/* Blocks which are completely dirty, and need erasing */
+	struct list_head erasable_pending_wbuf_list;	/* Blocks which need erasing but only after the current wbuf is flushed */
+	struct list_head erasing_list;		/* Blocks which are currently erasing */
+	struct list_head erase_pending_list;	/* Blocks which need erasing now */
+	struct list_head erase_complete_list;	/* Blocks which are erased and need the clean marker written to them */
+	struct list_head free_list;		/* Blocks which are free and ready to be used */
+	struct list_head bad_list;		/* Bad blocks. */
+	struct list_head bad_used_list;		/* Bad blocks with valid data in. */
+
+	spinlock_t erase_completion_lock;	/* Protect free_list and erasing_list
+						   against erase completion handler */
+	wait_queue_head_t erase_wait;		/* For waiting for erases to complete */
+
+	wait_queue_head_t inocache_wq;
+	struct jffs2_inode_cache **inocache_list;
+	spinlock_t inocache_lock;
+
+	/* Sem to allow jffs2_garbage_collect_deletion_dirent to
+	   drop the erase_completion_lock while it's holding a pointer
+	   to an obsoleted node. I don't like this. Alternatives welcomed. */
+	struct semaphore erase_free_sem;
+
+	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;
+	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;
+#endif
+
+	struct jffs2_summary *summary;		/* Summary information */
+
+#ifdef CONFIG_JFFS2_FS_XATTR
+#define XATTRINDEX_HASHSIZE	(57)
+	uint32_t highest_xid;
+	uint32_t highest_xseqno;
+	struct list_head xattrindex[XATTRINDEX_HASHSIZE];
+	struct list_head xattr_unchecked;
+	struct list_head xattr_dead_list;
+	struct jffs2_xattr_ref *xref_dead_list;
+	struct jffs2_xattr_ref *xref_temp;
+	struct rw_semaphore xattr_sem;
+	uint32_t xdatum_mem_usage;
+	uint32_t xdatum_mem_threshold;
+#endif
+	/* OS-private pointer for getting back to master superblock info */
+	void *os_priv;
+};
+
+#endif /* _JFFS2_FB_SB */
diff --git a/fs/jffs2/security.c b/fs/jffs2/security.c
new file mode 100644
index 000000000..52a9894a6
--- /dev/null
+++ b/fs/jffs2/security.c
@@ -0,0 +1,82 @@
+/*
+ * JFFS2 -- Journalling Flash File System, Version 2.
+ *
+ * Copyright (C) 2006  NEC Corporation
+ *
+ * Created by KaiGai Kohei <kaigai@ak.jp.nec.com>
+ *
+ * For licensing information, see the file 'LICENCE' in this directory.
+ *
+ */
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/fs.h>
+#include <linux/time.h>
+#include <linux/pagemap.h>
+#include <linux/highmem.h>
+#include <linux/crc32.h>
+#include <linux/jffs2.h>
+#include <linux/xattr.h>
+#include <linux/mtd/mtd.h>
+#include <linux/security.h>
+#include "nodelist.h"
+
+/* ---- Initial Security Label Attachment -------------- */
+int jffs2_init_security(struct inode *inode, struct inode *dir)
+{
+	int rc;
+	size_t len;
+	void *value;
+	char *name;
+
+	rc = security_inode_init_security(inode, dir, &name, &value, &len);
+	if (rc) {
+		if (rc == -EOPNOTSUPP)
+			return 0;
+		return rc;
+	}
+	rc = do_jffs2_setxattr(inode, JFFS2_XPREFIX_SECURITY, name, value, len, 0);
+
+        kfree(name);
+        kfree(value);
+        return rc;
+}
+
+/* ---- XATTR Handler for "security.*" ----------------- */
+static int jffs2_security_getxattr(struct inode *inode, const char *name,
+				   void *buffer, size_t size)
+{
+	if (!strcmp(name, ""))
+		return -EINVAL;
+
+	return do_jffs2_getxattr(inode, JFFS2_XPREFIX_SECURITY, name, buffer, size);
+}
+
+static int jffs2_security_setxattr(struct inode *inode, const char *name, const void *buffer,
+				   size_t size, int flags)
+{
+	if (!strcmp(name, ""))
+		return -EINVAL;
+
+	return do_jffs2_setxattr(inode, JFFS2_XPREFIX_SECURITY, name, buffer, size, flags);
+}
+
+static size_t jffs2_security_listxattr(struct inode *inode, char *list, size_t list_size,
+				       const char *name, size_t name_len)
+{
+	size_t retlen = XATTR_SECURITY_PREFIX_LEN + name_len + 1;
+
+	if (list && retlen <= list_size) {
+		strcpy(list, XATTR_SECURITY_PREFIX);
+		strcpy(list + XATTR_SECURITY_PREFIX_LEN, name);
+	}
+
+	return retlen;
+}
+
+struct xattr_handler jffs2_security_xattr_handler = {
+	.prefix = XATTR_SECURITY_PREFIX,
+	.list = jffs2_security_listxattr,
+	.set = jffs2_security_setxattr,
+	.get = jffs2_security_getxattr
+};
diff --git a/fs/jffs2/xattr.c b/fs/jffs2/xattr.c
new file mode 100644
index 000000000..4da09ce1d
--- /dev/null
+++ b/fs/jffs2/xattr.c
@@ -0,0 +1,1324 @@
+/*
+ * JFFS2 -- Journalling Flash File System, Version 2.
+ *
+ * Copyright (C) 2006  NEC Corporation
+ *
+ * Created by KaiGai Kohei <kaigai@ak.jp.nec.com>
+ *
+ * For licensing information, see the file 'LICENCE' in this directory.
+ *
+ */
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/fs.h>
+#include <linux/time.h>
+#include <linux/pagemap.h>
+#include <linux/highmem.h>
+#include <linux/crc32.h>
+#include <linux/jffs2.h>
+#include <linux/xattr.h>
+#include <linux/mtd/mtd.h>
+#include "nodelist.h"
+/* -------- xdatum related functions ----------------
+ * xattr_datum_hashkey(xprefix, xname, xvalue, xsize)
+ *   is used to calcurate xdatum hashkey. The reminder of hashkey into XATTRINDEX_HASHSIZE is
+ *   the index of the xattr name/value pair cache (c->xattrindex).
+ * is_xattr_datum_unchecked(c, xd)
+ *   returns 1, if xdatum contains any unchecked raw nodes. if all raw nodes are not
+ *   unchecked, it returns 0.
+ * unload_xattr_datum(c, xd)
+ *   is used to release xattr name/value pair and detach from c->xattrindex.
+ * reclaim_xattr_datum(c)
+ *   is used to reclaim xattr name/value pairs on the xattr name/value pair cache when
+ *   memory usage by cache is over c->xdatum_mem_threshold. Currentry, this threshold 
+ *   is hard coded as 32KiB.
+ * do_verify_xattr_datum(c, xd)
+ *   is used to load the xdatum informations without name/value pair from the medium.
+ *   It's necessary once, because those informations are not collected during mounting
+ *   process when EBS is enabled.
+ *   0 will be returned, if success. An negative return value means recoverable error, and
+ *   positive return value means unrecoverable error. Thus, caller must remove this xdatum
+ *   and xref when it returned positive value.
+ * do_load_xattr_datum(c, xd)
+ *   is used to load name/value pair from the medium.
+ *   The meanings of return value is same as do_verify_xattr_datum().
+ * load_xattr_datum(c, xd)
+ *   is used to be as a wrapper of do_verify_xattr_datum() and do_load_xattr_datum().
+ *   If xd need to call do_verify_xattr_datum() at first, it's called before calling
+ *   do_load_xattr_datum(). The meanings of return value is same as do_verify_xattr_datum().
+ * save_xattr_datum(c, xd)
+ *   is used to write xdatum to medium. xd->version will be incremented.
+ * create_xattr_datum(c, xprefix, xname, xvalue, xsize)
+ *   is used to create new xdatum and write to medium.
+ * unrefer_xattr_datum(c, xd)
+ *   is used to delete a xdatum. When nobody refers this xdatum, JFFS2_XFLAGS_DEAD
+ *   is set on xd->flags and chained xattr_dead_list or release it immediately.
+ *   In the first case, the garbage collector release it later.
+ * -------------------------------------------------- */
+static uint32_t xattr_datum_hashkey(int xprefix, const char *xname, const char *xvalue, int xsize)
+{
+	int name_len = strlen(xname);
+
+	return crc32(xprefix, xname, name_len) ^ crc32(xprefix, xvalue, xsize);
+}
+
+static int is_xattr_datum_unchecked(struct jffs2_sb_info *c, struct jffs2_xattr_datum *xd)
+{
+	struct jffs2_raw_node_ref *raw;
+	int rc = 0;
+
+	spin_lock(&c->erase_completion_lock);
+	for (raw=xd->node; raw != (void *)xd; raw=raw->next_in_ino) {
+		if (ref_flags(raw) == REF_UNCHECKED) {
+			rc = 1;
+			break;
+		}
+	}
+	spin_unlock(&c->erase_completion_lock);
+	return rc;
+}
+
+static void unload_xattr_datum(struct jffs2_sb_info *c, struct jffs2_xattr_datum *xd)
+{
+	/* must be called under down_write(xattr_sem) */
+	D1(dbg_xattr("%s: xid=%u, version=%u\n", __FUNCTION__, xd->xid, xd->version));
+	if (xd->xname) {
+		c->xdatum_mem_usage -= (xd->name_len + 1 + xd->value_len);
+		kfree(xd->xname);
+	}
+
+	list_del_init(&xd->xindex);
+	xd->hashkey = 0;
+	xd->xname = NULL;
+	xd->xvalue = NULL;
+}
+
+static void reclaim_xattr_datum(struct jffs2_sb_info *c)
+{
+	/* must be called under down_write(xattr_sem) */
+	struct jffs2_xattr_datum *xd, *_xd;
+	uint32_t target, before;
+	static int index = 0;
+	int count;
+
+	if (c->xdatum_mem_threshold > c->xdatum_mem_usage)
+		return;
+
+	before = c->xdatum_mem_usage;
+	target = c->xdatum_mem_usage * 4 / 5; /* 20% reduction */
+	for (count = 0; count < XATTRINDEX_HASHSIZE; count++) {
+		list_for_each_entry_safe(xd, _xd, &c->xattrindex[index], xindex) {
+			if (xd->flags & JFFS2_XFLAGS_HOT) {
+				xd->flags &= ~JFFS2_XFLAGS_HOT;
+			} else if (!(xd->flags & JFFS2_XFLAGS_BIND)) {
+				unload_xattr_datum(c, xd);
+			}
+			if (c->xdatum_mem_usage <= target)
+				goto out;
+		}
+		index = (index+1) % XATTRINDEX_HASHSIZE;
+	}
+ out:
+	JFFS2_NOTICE("xdatum_mem_usage from %u byte to %u byte (%u byte reclaimed)\n",
+		     before, c->xdatum_mem_usage, before - c->xdatum_mem_usage);
+}
+
+static int do_verify_xattr_datum(struct jffs2_sb_info *c, struct jffs2_xattr_datum *xd)
+{
+	/* must be called under down_write(xattr_sem) */
+	struct jffs2_eraseblock *jeb;
+	struct jffs2_raw_node_ref *raw;
+	struct jffs2_raw_xattr rx;
+	size_t readlen;
+	uint32_t crc, offset, totlen;
+	int rc;
+
+	spin_lock(&c->erase_completion_lock);
+	offset = ref_offset(xd->node);
+	if (ref_flags(xd->node) == REF_PRISTINE)
+		goto complete;
+	spin_unlock(&c->erase_completion_lock);
+
+	rc = jffs2_flash_read(c, offset, sizeof(rx), &readlen, (char *)&rx);
+	if (rc || readlen != sizeof(rx)) {
+		JFFS2_WARNING("jffs2_flash_read()=%d, req=%zu, read=%zu at %#08x\n",
+			      rc, sizeof(rx), readlen, offset);
+		return rc ? rc : -EIO;
+	}
+	crc = crc32(0, &rx, sizeof(rx) - 4);
+	if (crc != je32_to_cpu(rx.node_crc)) {
+		JFFS2_ERROR("node CRC failed at %#08x, read=%#08x, calc=%#08x\n",
+			    offset, je32_to_cpu(rx.hdr_crc), crc);
+		xd->flags |= JFFS2_XFLAGS_INVALID;
+		return EIO;
+	}
+	totlen = PAD(sizeof(rx) + rx.name_len + 1 + je16_to_cpu(rx.value_len));
+	if (je16_to_cpu(rx.magic) != JFFS2_MAGIC_BITMASK
+	    || je16_to_cpu(rx.nodetype) != JFFS2_NODETYPE_XATTR
+	    || je32_to_cpu(rx.totlen) != totlen
+	    || je32_to_cpu(rx.xid) != xd->xid
+	    || je32_to_cpu(rx.version) != xd->version) {
+		JFFS2_ERROR("inconsistent xdatum at %#08x, magic=%#04x/%#04x, "
+			    "nodetype=%#04x/%#04x, totlen=%u/%u, xid=%u/%u, version=%u/%u\n",
+			    offset, je16_to_cpu(rx.magic), JFFS2_MAGIC_BITMASK,
+			    je16_to_cpu(rx.nodetype), JFFS2_NODETYPE_XATTR,
+			    je32_to_cpu(rx.totlen), totlen,
+			    je32_to_cpu(rx.xid), xd->xid,
+			    je32_to_cpu(rx.version), xd->version);
+		xd->flags |= JFFS2_XFLAGS_INVALID;
+		return EIO;
+	}
+	xd->xprefix = rx.xprefix;
+	xd->name_len = rx.name_len;
+	xd->value_len = je16_to_cpu(rx.value_len);
+	xd->data_crc = je32_to_cpu(rx.data_crc);
+
+	spin_lock(&c->erase_completion_lock);
+ complete:
+	for (raw=xd->node; raw != (void *)xd; raw=raw->next_in_ino) {
+		jeb = &c->blocks[ref_offset(raw) / c->sector_size];
+		totlen = PAD(ref_totlen(c, jeb, raw));
+		if (ref_flags(raw) == REF_UNCHECKED) {
+			c->unchecked_size -= totlen; c->used_size += totlen;
+			jeb->unchecked_size -= totlen; jeb->used_size += totlen;
+		}
+		raw->flash_offset = ref_offset(raw) | ((xd->node==raw) ? REF_PRISTINE : REF_NORMAL);
+	}
+	spin_unlock(&c->erase_completion_lock);
+
+	/* unchecked xdatum is chained with c->xattr_unchecked */
+	list_del_init(&xd->xindex);
+
+	dbg_xattr("success on verfying xdatum (xid=%u, version=%u)\n",
+		  xd->xid, xd->version);
+
+	return 0;
+}
+
+static int do_load_xattr_datum(struct jffs2_sb_info *c, struct jffs2_xattr_datum *xd)
+{
+	/* must be called under down_write(xattr_sem) */
+	char *data;
+	size_t readlen;
+	uint32_t crc, length;
+	int i, ret, retry = 0;
+
+	BUG_ON(ref_flags(xd->node) != REF_PRISTINE);
+	BUG_ON(!list_empty(&xd->xindex));
+ retry:
+	length = xd->name_len + 1 + xd->value_len;
+	data = kmalloc(length, GFP_KERNEL);
+	if (!data)
+		return -ENOMEM;
+
+	ret = jffs2_flash_read(c, ref_offset(xd->node)+sizeof(struct jffs2_raw_xattr),
+			       length, &readlen, data);
+
+	if (ret || length!=readlen) {
+		JFFS2_WARNING("jffs2_flash_read() returned %d, request=%d, readlen=%zu, at %#08x\n",
+			      ret, length, readlen, ref_offset(xd->node));
+		kfree(data);
+		return ret ? ret : -EIO;
+	}
+
+	data[xd->name_len] = '\0';
+	crc = crc32(0, data, length);
+	if (crc != xd->data_crc) {
+		JFFS2_WARNING("node CRC failed (JFFS2_NODETYPE_XREF)"
+			      " at %#08x, read: 0x%08x calculated: 0x%08x\n",
+			      ref_offset(xd->node), xd->data_crc, crc);
+		kfree(data);
+		xd->flags |= JFFS2_XFLAGS_INVALID;
+		return EIO;
+	}
+
+	xd->flags |= JFFS2_XFLAGS_HOT;
+	xd->xname = data;
+	xd->xvalue = data + xd->name_len+1;
+
+	c->xdatum_mem_usage += length;
+
+	xd->hashkey = xattr_datum_hashkey(xd->xprefix, xd->xname, xd->xvalue, xd->value_len);
+	i = xd->hashkey % XATTRINDEX_HASHSIZE;
+	list_add(&xd->xindex, &c->xattrindex[i]);
+	if (!retry) {
+		retry = 1;
+		reclaim_xattr_datum(c);
+		if (!xd->xname)
+			goto retry;
+	}
+
+	dbg_xattr("success on loading xdatum (xid=%u, xprefix=%u, xname='%s')\n",
+		  xd->xid, xd->xprefix, xd->xname);
+
+	return 0;
+}
+
+static int load_xattr_datum(struct jffs2_sb_info *c, struct jffs2_xattr_datum *xd)
+{
+	/* must be called under down_write(xattr_sem);
+	 * rc < 0 : recoverable error, try again
+	 * rc = 0 : success
+	 * rc > 0 : Unrecoverable error, this node should be deleted.
+	 */
+	int rc = 0;
+
+	BUG_ON(xd->flags & JFFS2_XFLAGS_DEAD);
+	if (xd->xname)
+		return 0;
+	if (xd->flags & JFFS2_XFLAGS_INVALID)
+		return EIO;
+	if (unlikely(is_xattr_datum_unchecked(c, xd)))
+		rc = do_verify_xattr_datum(c, xd);
+	if (!rc)
+		rc = do_load_xattr_datum(c, xd);
+	return rc;
+}
+
+static int save_xattr_datum(struct jffs2_sb_info *c, struct jffs2_xattr_datum *xd)
+{
+	/* must be called under down_write(xattr_sem) */
+	struct jffs2_raw_xattr rx;
+	struct kvec vecs[2];
+	size_t length;
+	int rc, totlen;
+	uint32_t phys_ofs = write_ofs(c);
+
+	BUG_ON(!xd->xname);
+	BUG_ON(xd->flags & (JFFS2_XFLAGS_DEAD|JFFS2_XFLAGS_INVALID));
+
+	vecs[0].iov_base = &rx;
+	vecs[0].iov_len = sizeof(rx);
+	vecs[1].iov_base = xd->xname;
+	vecs[1].iov_len = xd->name_len + 1 + xd->value_len;
+	totlen = vecs[0].iov_len + vecs[1].iov_len;
+
+	/* Setup raw-xattr */
+	memset(&rx, 0, sizeof(rx));
+	rx.magic = cpu_to_je16(JFFS2_MAGIC_BITMASK);
+	rx.nodetype = cpu_to_je16(JFFS2_NODETYPE_XATTR);
+	rx.totlen = cpu_to_je32(PAD(totlen));
+	rx.hdr_crc = cpu_to_je32(crc32(0, &rx, sizeof(struct jffs2_unknown_node) - 4));
+
+	rx.xid = cpu_to_je32(xd->xid);
+	rx.version = cpu_to_je32(++xd->version);
+	rx.xprefix = xd->xprefix;
+	rx.name_len = xd->name_len;
+	rx.value_len = cpu_to_je16(xd->value_len);
+	rx.data_crc = cpu_to_je32(crc32(0, vecs[1].iov_base, vecs[1].iov_len));
+	rx.node_crc = cpu_to_je32(crc32(0, &rx, sizeof(struct jffs2_raw_xattr) - 4));
+
+	rc = jffs2_flash_writev(c, vecs, 2, phys_ofs, &length, 0);
+	if (rc || totlen != length) {
+		JFFS2_WARNING("jffs2_flash_writev()=%d, req=%u, wrote=%zu, at %#08x\n",
+			      rc, totlen, length, phys_ofs);
+		rc = rc ? rc : -EIO;
+		if (length)
+			jffs2_add_physical_node_ref(c, phys_ofs | REF_OBSOLETE, PAD(totlen), NULL);
+
+		return rc;
+	}
+	/* success */
+	jffs2_add_physical_node_ref(c, phys_ofs | REF_PRISTINE, PAD(totlen), (void *)xd);
+
+	dbg_xattr("success on saving xdatum (xid=%u, version=%u, xprefix=%u, xname='%s')\n",
+		  xd->xid, xd->version, xd->xprefix, xd->xname);
+
+	return 0;
+}
+
+static struct jffs2_xattr_datum *create_xattr_datum(struct jffs2_sb_info *c,
+						    int xprefix, const char *xname,
+						    const char *xvalue, int xsize)
+{
+	/* must be called under down_write(xattr_sem) */
+	struct jffs2_xattr_datum *xd;
+	uint32_t hashkey, name_len;
+	char *data;
+	int i, rc;
+
+	/* Search xattr_datum has same xname/xvalue by index */
+	hashkey = xattr_datum_hashkey(xprefix, xname, xvalue, xsize);
+	i = hashkey % XATTRINDEX_HASHSIZE;
+	list_for_each_entry(xd, &c->xattrindex[i], xindex) {
+		if (xd->hashkey==hashkey
+		    && xd->xprefix==xprefix
+		    && xd->value_len==xsize
+		    && !strcmp(xd->xname, xname)
+		    && !memcmp(xd->xvalue, xvalue, xsize)) {
+			atomic_inc(&xd->refcnt);
+			return xd;
+		}
+	}
+
+	/* Not found, Create NEW XATTR-Cache */
+	name_len = strlen(xname);
+
+	xd = jffs2_alloc_xattr_datum();
+	if (!xd)
+		return ERR_PTR(-ENOMEM);
+
+	data = kmalloc(name_len + 1 + xsize, GFP_KERNEL);
+	if (!data) {
+		jffs2_free_xattr_datum(xd);
+		return ERR_PTR(-ENOMEM);
+	}
+	strcpy(data, xname);
+	memcpy(data + name_len + 1, xvalue, xsize);
+
+	atomic_set(&xd->refcnt, 1);
+	xd->xid = ++c->highest_xid;
+	xd->flags |= JFFS2_XFLAGS_HOT;
+	xd->xprefix = xprefix;
+
+	xd->hashkey = hashkey;
+	xd->xname = data;
+	xd->xvalue = data + name_len + 1;
+	xd->name_len = name_len;
+	xd->value_len = xsize;
+	xd->data_crc = crc32(0, data, xd->name_len + 1 + xd->value_len);
+
+	rc = save_xattr_datum(c, xd);
+	if (rc) {
+		kfree(xd->xname);
+		jffs2_free_xattr_datum(xd);
+		return ERR_PTR(rc);
+	}
+
+	/* Insert Hash Index */
+	i = hashkey % XATTRINDEX_HASHSIZE;
+	list_add(&xd->xindex, &c->xattrindex[i]);
+
+	c->xdatum_mem_usage += (xd->name_len + 1 + xd->value_len);
+	reclaim_xattr_datum(c);
+
+	return xd;
+}
+
+static void unrefer_xattr_datum(struct jffs2_sb_info *c, struct jffs2_xattr_datum *xd)
+{
+	/* must be called under down_write(xattr_sem) */
+	if (atomic_dec_and_lock(&xd->refcnt, &c->erase_completion_lock)) {
+		uint32_t xid = xd->xid, version = xd->version;
+
+		unload_xattr_datum(c, xd);
+		xd->flags |= JFFS2_XFLAGS_DEAD;
+		if (xd->node == (void *)xd) {
+			BUG_ON(!(xd->flags & JFFS2_XFLAGS_INVALID));
+			jffs2_free_xattr_datum(xd);
+		} else {
+			list_add(&xd->xindex, &c->xattr_dead_list);
+		}
+		spin_unlock(&c->erase_completion_lock);
+
+		dbg_xattr("xdatum(xid=%u, version=%u) was removed.\n", xid, version);
+	}
+}
+
+/* -------- xref related functions ------------------
+ * verify_xattr_ref(c, ref)
+ *   is used to load xref information from medium. Because summary data does not
+ *   contain xid/ino, it's necessary to verify once while mounting process.
+ * save_xattr_ref(c, ref)
+ *   is used to write xref to medium. If delete marker is marked, it write
+ *   a delete marker of xref into medium.
+ * create_xattr_ref(c, ic, xd)
+ *   is used to create a new xref and write to medium.
+ * delete_xattr_ref(c, ref)
+ *   is used to delete jffs2_xattr_ref. It marks xref XREF_DELETE_MARKER,
+ *   and allows GC to reclaim those physical nodes.
+ * jffs2_xattr_delete_inode(c, ic)
+ *   is called to remove xrefs related to obsolete inode when inode is unlinked.
+ * jffs2_xattr_free_inode(c, ic)
+ *   is called to release xattr related objects when unmounting. 
+ * check_xattr_ref_inode(c, ic)
+ *   is used to confirm inode does not have duplicate xattr name/value pair.
+ * -------------------------------------------------- */
+static int verify_xattr_ref(struct jffs2_sb_info *c, struct jffs2_xattr_ref *ref)
+{
+	struct jffs2_eraseblock *jeb;
+	struct jffs2_raw_node_ref *raw;
+	struct jffs2_raw_xref rr;
+	size_t readlen;
+	uint32_t crc, offset, totlen;
+	int rc;
+
+	spin_lock(&c->erase_completion_lock);
+	if (ref_flags(ref->node) != REF_UNCHECKED)
+		goto complete;
+	offset = ref_offset(ref->node);
+	spin_unlock(&c->erase_completion_lock);
+
+	rc = jffs2_flash_read(c, offset, sizeof(rr), &readlen, (char *)&rr);
+	if (rc || sizeof(rr) != readlen) {
+		JFFS2_WARNING("jffs2_flash_read()=%d, req=%zu, read=%zu, at %#08x\n",
+			      rc, sizeof(rr), readlen, offset);
+		return rc ? rc : -EIO;
+	}
+	/* obsolete node */
+	crc = crc32(0, &rr, sizeof(rr) - 4);
+	if (crc != je32_to_cpu(rr.node_crc)) {
+		JFFS2_ERROR("node CRC failed at %#08x, read=%#08x, calc=%#08x\n",
+			    offset, je32_to_cpu(rr.node_crc), crc);
+		return EIO;
+	}
+	if (je16_to_cpu(rr.magic) != JFFS2_MAGIC_BITMASK
+	    || je16_to_cpu(rr.nodetype) != JFFS2_NODETYPE_XREF
+	    || je32_to_cpu(rr.totlen) != PAD(sizeof(rr))) {
+		JFFS2_ERROR("inconsistent xref at %#08x, magic=%#04x/%#04x, "
+			    "nodetype=%#04x/%#04x, totlen=%u/%zu\n",
+			    offset, je16_to_cpu(rr.magic), JFFS2_MAGIC_BITMASK,
+			    je16_to_cpu(rr.nodetype), JFFS2_NODETYPE_XREF,
+			    je32_to_cpu(rr.totlen), PAD(sizeof(rr)));
+		return EIO;
+	}
+	ref->ino = je32_to_cpu(rr.ino);
+	ref->xid = je32_to_cpu(rr.xid);
+	ref->xseqno = je32_to_cpu(rr.xseqno);
+	if (ref->xseqno > c->highest_xseqno)
+		c->highest_xseqno = (ref->xseqno & ~XREF_DELETE_MARKER);
+
+	spin_lock(&c->erase_completion_lock);
+ complete:
+	for (raw=ref->node; raw != (void *)ref; raw=raw->next_in_ino) {
+		jeb = &c->blocks[ref_offset(raw) / c->sector_size];
+		totlen = PAD(ref_totlen(c, jeb, raw));
+		if (ref_flags(raw) == REF_UNCHECKED) {
+			c->unchecked_size -= totlen; c->used_size += totlen;
+			jeb->unchecked_size -= totlen; jeb->used_size += totlen;
+		}
+		raw->flash_offset = ref_offset(raw) | ((ref->node==raw) ? REF_PRISTINE : REF_NORMAL);
+	}
+	spin_unlock(&c->erase_completion_lock);
+
+	dbg_xattr("success on verifying xref (ino=%u, xid=%u) at %#08x\n",
+		  ref->ino, ref->xid, ref_offset(ref->node));
+	return 0;
+}
+
+static int save_xattr_ref(struct jffs2_sb_info *c, struct jffs2_xattr_ref *ref)
+{
+	/* must be called under down_write(xattr_sem) */
+	struct jffs2_raw_xref rr;
+	size_t length;
+	uint32_t xseqno, phys_ofs = write_ofs(c);
+	int ret;
+
+	rr.magic = cpu_to_je16(JFFS2_MAGIC_BITMASK);
+	rr.nodetype = cpu_to_je16(JFFS2_NODETYPE_XREF);
+	rr.totlen = cpu_to_je32(PAD(sizeof(rr)));
+	rr.hdr_crc = cpu_to_je32(crc32(0, &rr, sizeof(struct jffs2_unknown_node) - 4));
+
+	xseqno = (c->highest_xseqno += 2);
+	if (is_xattr_ref_dead(ref)) {
+		xseqno |= XREF_DELETE_MARKER;
+		rr.ino = cpu_to_je32(ref->ino);
+		rr.xid = cpu_to_je32(ref->xid);
+	} else {
+		rr.ino = cpu_to_je32(ref->ic->ino);
+		rr.xid = cpu_to_je32(ref->xd->xid);
+	}
+	rr.xseqno = cpu_to_je32(xseqno);
+	rr.node_crc = cpu_to_je32(crc32(0, &rr, sizeof(rr) - 4));
+
+	ret = jffs2_flash_write(c, phys_ofs, sizeof(rr), &length, (char *)&rr);
+	if (ret || sizeof(rr) != length) {
+		JFFS2_WARNING("jffs2_flash_write() returned %d, request=%zu, retlen=%zu, at %#08x\n",
+			      ret, sizeof(rr), length, phys_ofs);
+		ret = ret ? ret : -EIO;
+		if (length)
+			jffs2_add_physical_node_ref(c, phys_ofs | REF_OBSOLETE, PAD(sizeof(rr)), NULL);
+
+		return ret;
+	}
+	/* success */
+	ref->xseqno = xseqno;
+	jffs2_add_physical_node_ref(c, phys_ofs | REF_PRISTINE, PAD(sizeof(rr)), (void *)ref);
+
+	dbg_xattr("success on saving xref (ino=%u, xid=%u)\n", ref->ic->ino, ref->xd->xid);
+
+	return 0;
+}
+
+static struct jffs2_xattr_ref *create_xattr_ref(struct jffs2_sb_info *c, struct jffs2_inode_cache *ic,
+						struct jffs2_xattr_datum *xd)
+{
+	/* must be called under down_write(xattr_sem) */
+	struct jffs2_xattr_ref *ref;
+	int ret;
+
+	ref = jffs2_alloc_xattr_ref();
+	if (!ref)
+		return ERR_PTR(-ENOMEM);
+	ref->ic = ic;
+	ref->xd = xd;
+
+	ret = save_xattr_ref(c, ref);
+	if (ret) {
+		jffs2_free_xattr_ref(ref);
+		return ERR_PTR(ret);
+	}
+
+	/* Chain to inode */
+	ref->next = ic->xref;
+	ic->xref = ref;
+
+	return ref; /* success */
+}
+
+static void delete_xattr_ref(struct jffs2_sb_info *c, struct jffs2_xattr_ref *ref)
+{
+	/* must be called under down_write(xattr_sem) */
+	struct jffs2_xattr_datum *xd;
+
+	xd = ref->xd;
+	ref->xseqno |= XREF_DELETE_MARKER;
+	ref->ino = ref->ic->ino;
+	ref->xid = ref->xd->xid;
+	spin_lock(&c->erase_completion_lock);
+	ref->next = c->xref_dead_list;
+	c->xref_dead_list = ref;
+	spin_unlock(&c->erase_completion_lock);
+
+	dbg_xattr("xref(ino=%u, xid=%u, xseqno=%u) was removed.\n",
+		  ref->ino, ref->xid, ref->xseqno);
+
+	unrefer_xattr_datum(c, xd);
+}
+
+void jffs2_xattr_delete_inode(struct jffs2_sb_info *c, struct jffs2_inode_cache *ic)
+{
+	/* It's called from jffs2_clear_inode() on inode removing.
+	   When an inode with XATTR is removed, those XATTRs must be removed. */
+	struct jffs2_xattr_ref *ref, *_ref;
+
+	if (!ic || ic->nlink > 0)
+		return;
+
+	down_write(&c->xattr_sem);
+	for (ref = ic->xref; ref; ref = _ref) {
+		_ref = ref->next;
+		delete_xattr_ref(c, ref);
+	}
+	ic->xref = NULL;
+	up_write(&c->xattr_sem);
+}
+
+void jffs2_xattr_free_inode(struct jffs2_sb_info *c, struct jffs2_inode_cache *ic)
+{
+	/* It's called from jffs2_free_ino_caches() until unmounting FS. */
+	struct jffs2_xattr_datum *xd;
+	struct jffs2_xattr_ref *ref, *_ref;
+
+	down_write(&c->xattr_sem);
+	for (ref = ic->xref; ref; ref = _ref) {
+		_ref = ref->next;
+		xd = ref->xd;
+		if (atomic_dec_and_test(&xd->refcnt)) {
+			unload_xattr_datum(c, xd);
+			jffs2_free_xattr_datum(xd);
+		}
+		jffs2_free_xattr_ref(ref);
+	}
+	ic->xref = NULL;
+	up_write(&c->xattr_sem);
+}
+
+static int check_xattr_ref_inode(struct jffs2_sb_info *c, struct jffs2_inode_cache *ic)
+{
+	/* success of check_xattr_ref_inode() means taht inode (ic) dose not have
+	 * duplicate name/value pairs. If duplicate name/value pair would be found,
+	 * one will be removed.
+	 */
+	struct jffs2_xattr_ref *ref, *cmp, **pref, **pcmp;
+	int rc = 0;
+
+	if (likely(ic->flags & INO_FLAGS_XATTR_CHECKED))
+		return 0;
+	down_write(&c->xattr_sem);
+ retry:
+	rc = 0;
+	for (ref=ic->xref, pref=&ic->xref; ref; pref=&ref->next, ref=ref->next) {
+		if (!ref->xd->xname) {
+			rc = load_xattr_datum(c, ref->xd);
+			if (unlikely(rc > 0)) {
+				*pref = ref->next;
+				delete_xattr_ref(c, ref);
+				goto retry;
+			} else if (unlikely(rc < 0))
+				goto out;
+		}
+		for (cmp=ref->next, pcmp=&ref->next; cmp; pcmp=&cmp->next, cmp=cmp->next) {
+			if (!cmp->xd->xname) {
+				ref->xd->flags |= JFFS2_XFLAGS_BIND;
+				rc = load_xattr_datum(c, cmp->xd);
+				ref->xd->flags &= ~JFFS2_XFLAGS_BIND;
+				if (unlikely(rc > 0)) {
+					*pcmp = cmp->next;
+					delete_xattr_ref(c, cmp);
+					goto retry;
+				} else if (unlikely(rc < 0))
+					goto out;
+			}
+			if (ref->xd->xprefix == cmp->xd->xprefix
+			    && !strcmp(ref->xd->xname, cmp->xd->xname)) {
+				if (ref->xseqno > cmp->xseqno) {
+					*pcmp = cmp->next;
+					delete_xattr_ref(c, cmp);
+				} else {
+					*pref = ref->next;
+					delete_xattr_ref(c, ref);
+				}
+				goto retry;
+			}
+		}
+	}
+	ic->flags |= INO_FLAGS_XATTR_CHECKED;
+ out:
+	up_write(&c->xattr_sem);
+
+	return rc;
+}
+
+/* -------- xattr subsystem functions ---------------
+ * jffs2_init_xattr_subsystem(c)
+ *   is used to initialize semaphore and list_head, and some variables.
+ * jffs2_find_xattr_datum(c, xid)
+ *   is used to lookup xdatum while scanning process.
+ * jffs2_clear_xattr_subsystem(c)
+ *   is used to release any xattr related objects.
+ * jffs2_build_xattr_subsystem(c)
+ *   is used to associate xdatum and xref while super block building process.
+ * jffs2_setup_xattr_datum(c, xid, version)
+ *   is used to insert xdatum while scanning process.
+ * -------------------------------------------------- */
+void jffs2_init_xattr_subsystem(struct jffs2_sb_info *c)
+{
+	int i;
+
+	for (i=0; i < XATTRINDEX_HASHSIZE; i++)
+		INIT_LIST_HEAD(&c->xattrindex[i]);
+	INIT_LIST_HEAD(&c->xattr_unchecked);
+	INIT_LIST_HEAD(&c->xattr_dead_list);
+	c->xref_dead_list = NULL;
+	c->xref_temp = NULL;
+
+	init_rwsem(&c->xattr_sem);
+	c->highest_xid = 0;
+	c->highest_xseqno = 0;
+	c->xdatum_mem_usage = 0;
+	c->xdatum_mem_threshold = 32 * 1024;	/* Default 32KB */
+}
+
+static struct jffs2_xattr_datum *jffs2_find_xattr_datum(struct jffs2_sb_info *c, uint32_t xid)
+{
+	struct jffs2_xattr_datum *xd;
+	int i = xid % XATTRINDEX_HASHSIZE;
+
+	/* It's only used in scanning/building process. */
+	BUG_ON(!(c->flags & (JFFS2_SB_FLAG_SCANNING|JFFS2_SB_FLAG_BUILDING)));
+
+	list_for_each_entry(xd, &c->xattrindex[i], xindex) {
+		if (xd->xid==xid)
+			return xd;
+	}
+	return NULL;
+}
+
+void jffs2_clear_xattr_subsystem(struct jffs2_sb_info *c)
+{
+	struct jffs2_xattr_datum *xd, *_xd;
+	struct jffs2_xattr_ref *ref, *_ref;
+	int i;
+
+	for (ref=c->xref_temp; ref; ref = _ref) {
+		_ref = ref->next;
+		jffs2_free_xattr_ref(ref);
+	}
+
+	for (ref=c->xref_dead_list; ref; ref = _ref) {
+		_ref = ref->next;
+		jffs2_free_xattr_ref(ref);
+	}
+
+	for (i=0; i < XATTRINDEX_HASHSIZE; i++) {
+		list_for_each_entry_safe(xd, _xd, &c->xattrindex[i], xindex) {
+			list_del(&xd->xindex);
+			if (xd->xname)
+				kfree(xd->xname);
+			jffs2_free_xattr_datum(xd);
+		}
+	}
+
+	list_for_each_entry_safe(xd, _xd, &c->xattr_dead_list, xindex) {
+		list_del(&xd->xindex);
+		jffs2_free_xattr_datum(xd);
+	}
+}
+
+#define XREF_TMPHASH_SIZE	(128)
+void jffs2_build_xattr_subsystem(struct jffs2_sb_info *c)
+{
+	struct jffs2_xattr_ref *ref, *_ref;
+	struct jffs2_xattr_ref *xref_tmphash[XREF_TMPHASH_SIZE];
+	struct jffs2_xattr_datum *xd, *_xd;
+	struct jffs2_inode_cache *ic;
+	struct jffs2_raw_node_ref *raw;
+	int i, xdatum_count = 0, xdatum_unchecked_count = 0, xref_count = 0;
+	int xdatum_orphan_count = 0, xref_orphan_count = 0, xref_dead_count = 0;
+
+	BUG_ON(!(c->flags & JFFS2_SB_FLAG_BUILDING));
+
+	/* Phase.1 : Merge same xref */
+	for (i=0; i < XREF_TMPHASH_SIZE; i++)
+		xref_tmphash[i] = NULL;
+	for (ref=c->xref_temp; ref; ref=_ref) {
+		struct jffs2_xattr_ref *tmp;
+
+		_ref = ref->next;
+		if (ref_flags(ref->node) != REF_PRISTINE) {
+			if (verify_xattr_ref(c, ref)) {
+				BUG_ON(ref->node->next_in_ino != (void *)ref);
+				ref->node->next_in_ino = NULL;
+				jffs2_mark_node_obsolete(c, ref->node);
+				jffs2_free_xattr_ref(ref);
+				continue;
+			}
+		}
+
+		i = (ref->ino ^ ref->xid) % XREF_TMPHASH_SIZE;
+		for (tmp=xref_tmphash[i]; tmp; tmp=tmp->next) {
+			if (tmp->ino == ref->ino && tmp->xid == ref->xid)
+				break;
+		}
+		if (tmp) {
+			raw = ref->node;
+			if (ref->xseqno > tmp->xseqno) {
+				tmp->xseqno = ref->xseqno;
+				raw->next_in_ino = tmp->node;
+				tmp->node = raw;
+			} else {
+				raw->next_in_ino = tmp->node->next_in_ino;
+				tmp->node->next_in_ino = raw;
+			}
+			jffs2_free_xattr_ref(ref);
+			continue;
+		} else {
+			ref->next = xref_tmphash[i];
+			xref_tmphash[i] = ref;
+		}
+	}
+	c->xref_temp = NULL;
+
+	/* Phase.2 : Bind xref with inode_cache and xattr_datum */
+	for (i=0; i < XREF_TMPHASH_SIZE; i++) {
+		for (ref=xref_tmphash[i]; ref; ref=_ref) {
+			xref_count++;
+			_ref = ref->next;
+			if (is_xattr_ref_dead(ref)) {
+				ref->next = c->xref_dead_list;
+				c->xref_dead_list = ref;
+				xref_dead_count++;
+				continue;
+			}
+			/* At this point, ref->xid and ref->ino contain XID and inode number.
+			   ref->xd and ref->ic are not valid yet. */
+			xd = jffs2_find_xattr_datum(c, ref->xid);
+			ic = jffs2_get_ino_cache(c, ref->ino);
+			if (!xd || !ic) {
+				dbg_xattr("xref(ino=%u, xid=%u, xseqno=%u) is orphan.\n",
+					  ref->ino, ref->xid, ref->xseqno);
+				ref->xseqno |= XREF_DELETE_MARKER;
+				ref->next = c->xref_dead_list;
+				c->xref_dead_list = ref;
+				xref_orphan_count++;
+				continue;
+			}
+			ref->xd = xd;
+			ref->ic = ic;
+			atomic_inc(&xd->refcnt);
+			ref->next = ic->xref;
+			ic->xref = ref;
+		}
+	}
+
+	/* Phase.3 : Link unchecked xdatum to xattr_unchecked list */
+	for (i=0; i < XATTRINDEX_HASHSIZE; i++) {
+		list_for_each_entry_safe(xd, _xd, &c->xattrindex[i], xindex) {
+			xdatum_count++;
+			list_del_init(&xd->xindex);
+			if (!atomic_read(&xd->refcnt)) {
+				dbg_xattr("xdatum(xid=%u, version=%u) is orphan.\n",
+					  xd->xid, xd->version);
+				xd->flags |= JFFS2_XFLAGS_DEAD;
+				list_add(&xd->xindex, &c->xattr_unchecked);
+				xdatum_orphan_count++;
+				continue;
+			}
+			if (is_xattr_datum_unchecked(c, xd)) {
+				dbg_xattr("unchecked xdatum(xid=%u, version=%u)\n",
+					  xd->xid, xd->version);
+				list_add(&xd->xindex, &c->xattr_unchecked);
+				xdatum_unchecked_count++;
+			}
+		}
+	}
+	/* build complete */
+	JFFS2_NOTICE("complete building xattr subsystem, %u of xdatum"
+		     " (%u unchecked, %u orphan) and "
+		     "%u of xref (%u dead, %u orphan) found.\n",
+		     xdatum_count, xdatum_unchecked_count, xdatum_orphan_count,
+		     xref_count, xref_dead_count, xref_orphan_count);
+}
+
+struct jffs2_xattr_datum *jffs2_setup_xattr_datum(struct jffs2_sb_info *c,
+						  uint32_t xid, uint32_t version)
+{
+	struct jffs2_xattr_datum *xd;
+
+	xd = jffs2_find_xattr_datum(c, xid);
+	if (!xd) {
+		xd = jffs2_alloc_xattr_datum();
+		if (!xd)
+			return ERR_PTR(-ENOMEM);
+		xd->xid = xid;
+		xd->version = version;
+		if (xd->xid > c->highest_xid)
+			c->highest_xid = xd->xid;
+		list_add_tail(&xd->xindex, &c->xattrindex[xid % XATTRINDEX_HASHSIZE]);
+	}
+	return xd;
+}
+
+/* -------- xattr subsystem functions ---------------
+ * xprefix_to_handler(xprefix)
+ *   is used to translate xprefix into xattr_handler.
+ * jffs2_listxattr(dentry, buffer, size)
+ *   is an implementation of listxattr handler on jffs2.
+ * do_jffs2_getxattr(inode, xprefix, xname, buffer, size)
+ *   is an implementation of getxattr handler on jffs2.
+ * do_jffs2_setxattr(inode, xprefix, xname, buffer, size, flags)
+ *   is an implementation of setxattr handler on jffs2.
+ * -------------------------------------------------- */
+struct xattr_handler *jffs2_xattr_handlers[] = {
+	&jffs2_user_xattr_handler,
+#ifdef CONFIG_JFFS2_FS_SECURITY
+	&jffs2_security_xattr_handler,
+#endif
+#ifdef CONFIG_JFFS2_FS_POSIX_ACL
+	&jffs2_acl_access_xattr_handler,
+	&jffs2_acl_default_xattr_handler,
+#endif
+	&jffs2_trusted_xattr_handler,
+	NULL
+};
+
+static struct xattr_handler *xprefix_to_handler(int xprefix) {
+	struct xattr_handler *ret;
+
+	switch (xprefix) {
+	case JFFS2_XPREFIX_USER:
+		ret = &jffs2_user_xattr_handler;
+		break;
+#ifdef CONFIG_JFFS2_FS_SECURITY
+	case JFFS2_XPREFIX_SECURITY:
+		ret = &jffs2_security_xattr_handler;
+		break;
+#endif
+#ifdef CONFIG_JFFS2_FS_POSIX_ACL
+	case JFFS2_XPREFIX_ACL_ACCESS:
+		ret = &jffs2_acl_access_xattr_handler;
+		break;
+	case JFFS2_XPREFIX_ACL_DEFAULT:
+		ret = &jffs2_acl_default_xattr_handler;
+		break;
+#endif
+	case JFFS2_XPREFIX_TRUSTED:
+		ret = &jffs2_trusted_xattr_handler;
+		break;
+	default:
+		ret = NULL;
+		break;
+	}
+	return ret;
+}
+
+ssize_t jffs2_listxattr(struct dentry *dentry, char *buffer, size_t size)
+{
+	struct inode *inode = dentry->d_inode;
+	struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode);
+	struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb);
+	struct jffs2_inode_cache *ic = f->inocache;
+	struct jffs2_xattr_ref *ref, **pref;
+	struct jffs2_xattr_datum *xd;
+	struct xattr_handler *xhandle;
+	ssize_t len, rc;
+	int retry = 0;
+
+	rc = check_xattr_ref_inode(c, ic);
+	if (unlikely(rc))
+		return rc;
+
+	down_read(&c->xattr_sem);
+ retry:
+	len = 0;
+	for (ref=ic->xref, pref=&ic->xref; ref; pref=&ref->next, ref=ref->next) {
+		BUG_ON(ref->ic != ic);
+		xd = ref->xd;
+		if (!xd->xname) {
+			/* xdatum is unchached */
+			if (!retry) {
+				retry = 1;
+				up_read(&c->xattr_sem);
+				down_write(&c->xattr_sem);
+				goto retry;
+			} else {
+				rc = load_xattr_datum(c, xd);
+				if (unlikely(rc > 0)) {
+					*pref = ref->next;
+					delete_xattr_ref(c, ref);
+					goto retry;
+				} else if (unlikely(rc < 0))
+					goto out;
+			}
+		}
+		xhandle = xprefix_to_handler(xd->xprefix);
+		if (!xhandle)
+			continue;
+		if (buffer) {
+			rc = xhandle->list(inode, buffer+len, size-len, xd->xname, xd->name_len);
+		} else {
+			rc = xhandle->list(inode, NULL, 0, xd->xname, xd->name_len);
+		}
+		if (rc < 0)
+			goto out;
+		len += rc;
+	}
+	rc = len;
+ out:
+	if (!retry) {
+		up_read(&c->xattr_sem);
+	} else {
+		up_write(&c->xattr_sem);
+	}
+	return rc;
+}
+
+int do_jffs2_getxattr(struct inode *inode, int xprefix, const char *xname,
+		      char *buffer, size_t size)
+{
+	struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode);
+	struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb);
+	struct jffs2_inode_cache *ic = f->inocache;
+	struct jffs2_xattr_datum *xd;
+	struct jffs2_xattr_ref *ref, **pref;
+	int rc, retry = 0;
+
+	rc = check_xattr_ref_inode(c, ic);
+	if (unlikely(rc))
+		return rc;
+
+	down_read(&c->xattr_sem);
+ retry:
+	for (ref=ic->xref, pref=&ic->xref; ref; pref=&ref->next, ref=ref->next) {
+		BUG_ON(ref->ic!=ic);
+
+		xd = ref->xd;
+		if (xd->xprefix != xprefix)
+			continue;
+		if (!xd->xname) {
+			/* xdatum is unchached */
+			if (!retry) {
+				retry = 1;
+				up_read(&c->xattr_sem);
+				down_write(&c->xattr_sem);
+				goto retry;
+			} else {
+				rc = load_xattr_datum(c, xd);
+				if (unlikely(rc > 0)) {
+					*pref = ref->next;
+					delete_xattr_ref(c, ref);
+					goto retry;
+				} else if (unlikely(rc < 0)) {
+					goto out;
+				}
+			}
+		}
+		if (!strcmp(xname, xd->xname)) {
+			rc = xd->value_len;
+			if (buffer) {
+				if (size < rc) {
+					rc = -ERANGE;
+				} else {
+					memcpy(buffer, xd->xvalue, rc);
+				}
+			}
+			goto out;
+		}
+	}
+	rc = -ENODATA;
+ out:
+	if (!retry) {
+		up_read(&c->xattr_sem);
+	} else {
+		up_write(&c->xattr_sem);
+	}
+	return rc;
+}
+
+int do_jffs2_setxattr(struct inode *inode, int xprefix, const char *xname,
+		      const char *buffer, size_t size, int flags)
+{
+	struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode);
+	struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb);
+	struct jffs2_inode_cache *ic = f->inocache;
+	struct jffs2_xattr_datum *xd;
+	struct jffs2_xattr_ref *ref, *newref, **pref;
+	uint32_t length, request;
+	int rc;
+
+	rc = check_xattr_ref_inode(c, ic);
+	if (unlikely(rc))
+		return rc;
+
+	request = PAD(sizeof(struct jffs2_raw_xattr) + strlen(xname) + 1 + size);
+	rc = jffs2_reserve_space(c, request, &length,
+				 ALLOC_NORMAL, JFFS2_SUMMARY_XATTR_SIZE);
+	if (rc) {
+		JFFS2_WARNING("jffs2_reserve_space()=%d, request=%u\n", rc, request);
+		return rc;
+	}
+
+	/* Find existing xattr */
+	down_write(&c->xattr_sem);
+ retry:
+	for (ref=ic->xref, pref=&ic->xref; ref; pref=&ref->next, ref=ref->next) {
+		xd = ref->xd;
+		if (xd->xprefix != xprefix)
+			continue;
+		if (!xd->xname) {
+			rc = load_xattr_datum(c, xd);
+			if (unlikely(rc > 0)) {
+				*pref = ref->next;
+				delete_xattr_ref(c, ref);
+				goto retry;
+			} else if (unlikely(rc < 0))
+				goto out;
+		}
+		if (!strcmp(xd->xname, xname)) {
+			if (flags & XATTR_CREATE) {
+				rc = -EEXIST;
+				goto out;
+			}
+			if (!buffer) {
+				ref->ino = ic->ino;
+				ref->xid = xd->xid;
+				ref->xseqno |= XREF_DELETE_MARKER;
+				rc = save_xattr_ref(c, ref);
+				if (!rc) {
+					*pref = ref->next;
+					spin_lock(&c->erase_completion_lock);
+					ref->next = c->xref_dead_list;
+					c->xref_dead_list = ref;
+					spin_unlock(&c->erase_completion_lock);
+					unrefer_xattr_datum(c, xd);
+				} else {
+					ref->ic = ic;
+					ref->xd = xd;
+					ref->xseqno &= ~XREF_DELETE_MARKER;
+				}
+				goto out;
+			}
+			goto found;
+		}
+	}
+	/* not found */
+	if (flags & XATTR_REPLACE) {
+		rc = -ENODATA;
+		goto out;
+	}
+	if (!buffer) {
+		rc = -ENODATA;
+		goto out;
+	}
+ found:
+	xd = create_xattr_datum(c, xprefix, xname, buffer, size);
+	if (IS_ERR(xd)) {
+		rc = PTR_ERR(xd);
+		goto out;
+	}
+	up_write(&c->xattr_sem);
+	jffs2_complete_reservation(c);
+
+	/* create xattr_ref */
+	request = PAD(sizeof(struct jffs2_raw_xref));
+	rc = jffs2_reserve_space(c, request, &length,
+				 ALLOC_NORMAL, JFFS2_SUMMARY_XREF_SIZE);
+	down_write(&c->xattr_sem);
+	if (rc) {
+		JFFS2_WARNING("jffs2_reserve_space()=%d, request=%u\n", rc, request);
+		unrefer_xattr_datum(c, xd);
+		up_write(&c->xattr_sem);
+		return rc;
+	}
+	if (ref)
+		*pref = ref->next;
+	newref = create_xattr_ref(c, ic, xd);
+	if (IS_ERR(newref)) {
+		if (ref) {
+			ref->next = ic->xref;
+			ic->xref = ref;
+		}
+		rc = PTR_ERR(newref);
+		unrefer_xattr_datum(c, xd);
+	} else if (ref) {
+		delete_xattr_ref(c, ref);
+	}
+ out:
+	up_write(&c->xattr_sem);
+	jffs2_complete_reservation(c);
+	return rc;
+}
+
+/* -------- garbage collector functions -------------
+ * jffs2_garbage_collect_xattr_datum(c, xd, raw)
+ *   is used to move xdatum into new node.
+ * jffs2_garbage_collect_xattr_ref(c, ref, raw)
+ *   is used to move xref into new node.
+ * jffs2_verify_xattr(c)
+ *   is used to call do_verify_xattr_datum() before garbage collecting.
+ * jffs2_release_xattr_datum(c, xd)
+ *   is used to release an in-memory object of xdatum.
+ * jffs2_release_xattr_ref(c, ref)
+ *   is used to release an in-memory object of xref.
+ * -------------------------------------------------- */
+int jffs2_garbage_collect_xattr_datum(struct jffs2_sb_info *c, struct jffs2_xattr_datum *xd,
+				      struct jffs2_raw_node_ref *raw)
+{
+	uint32_t totlen, length, old_ofs;
+	int rc = 0;
+
+	down_write(&c->xattr_sem);
+	if (xd->node != raw)
+		goto out;
+	if (xd->flags & (JFFS2_XFLAGS_DEAD|JFFS2_XFLAGS_INVALID))
+		goto out;
+
+	rc = load_xattr_datum(c, xd);
+	if (unlikely(rc)) {
+		rc = (rc > 0) ? 0 : rc;
+		goto out;
+	}
+	old_ofs = ref_offset(xd->node);
+	totlen = PAD(sizeof(struct jffs2_raw_xattr)
+			+ xd->name_len + 1 + xd->value_len);
+	rc = jffs2_reserve_space_gc(c, totlen, &length, JFFS2_SUMMARY_XATTR_SIZE);
+	if (rc) {
+		JFFS2_WARNING("jffs2_reserve_space_gc()=%d, request=%u\n", rc, totlen);
+		goto out;
+	}
+	rc = save_xattr_datum(c, xd);
+	if (!rc)
+		dbg_xattr("xdatum (xid=%u, version=%u) GC'ed from %#08x to %08x\n",
+			  xd->xid, xd->version, old_ofs, ref_offset(xd->node));
+ out:
+	if (!rc)
+		jffs2_mark_node_obsolete(c, raw);
+	up_write(&c->xattr_sem);
+	return rc;
+}
+
+int jffs2_garbage_collect_xattr_ref(struct jffs2_sb_info *c, struct jffs2_xattr_ref *ref,
+				    struct jffs2_raw_node_ref *raw)
+{
+	uint32_t totlen, length, old_ofs;
+	int rc = 0;
+
+	down_write(&c->xattr_sem);
+	BUG_ON(!ref->node);
+
+	if (ref->node != raw)
+		goto out;
+	if (is_xattr_ref_dead(ref) && (raw->next_in_ino == (void *)ref))
+		goto out;
+
+	old_ofs = ref_offset(ref->node);
+	totlen = ref_totlen(c, c->gcblock, ref->node);
+
+	rc = jffs2_reserve_space_gc(c, totlen, &length, JFFS2_SUMMARY_XREF_SIZE);
+	if (rc) {
+		JFFS2_WARNING("%s: jffs2_reserve_space_gc() = %d, request = %u\n",
+			      __FUNCTION__, rc, totlen);
+		rc = rc ? rc : -EBADFD;
+		goto out;
+	}
+	rc = save_xattr_ref(c, ref);
+	if (!rc)
+		dbg_xattr("xref (ino=%u, xid=%u) GC'ed from %#08x to %08x\n",
+			  ref->ic->ino, ref->xd->xid, old_ofs, ref_offset(ref->node));
+ out:
+	if (!rc)
+		jffs2_mark_node_obsolete(c, raw);
+	up_write(&c->xattr_sem);
+	return rc;
+}
+
+int jffs2_verify_xattr(struct jffs2_sb_info *c)
+{
+	struct jffs2_xattr_datum *xd, *_xd;
+	struct jffs2_eraseblock *jeb;
+	struct jffs2_raw_node_ref *raw;
+	uint32_t totlen;
+	int rc;
+
+	down_write(&c->xattr_sem);
+	list_for_each_entry_safe(xd, _xd, &c->xattr_unchecked, xindex) {
+		rc = do_verify_xattr_datum(c, xd);
+		if (rc < 0)
+			continue;
+		list_del_init(&xd->xindex);
+		spin_lock(&c->erase_completion_lock);
+		for (raw=xd->node; raw != (void *)xd; raw=raw->next_in_ino) {
+			if (ref_flags(raw) != REF_UNCHECKED)
+				continue;
+			jeb = &c->blocks[ref_offset(raw) / c->sector_size];
+			totlen = PAD(ref_totlen(c, jeb, raw));
+			c->unchecked_size -= totlen; c->used_size += totlen;
+			jeb->unchecked_size -= totlen; jeb->used_size += totlen;
+			raw->flash_offset = ref_offset(raw)
+				| ((xd->node == (void *)raw) ? REF_PRISTINE : REF_NORMAL);
+		}
+		if (xd->flags & JFFS2_XFLAGS_DEAD)
+			list_add(&xd->xindex, &c->xattr_dead_list);
+		spin_unlock(&c->erase_completion_lock);
+	}
+	up_write(&c->xattr_sem);
+	return list_empty(&c->xattr_unchecked) ? 1 : 0;
+}
+
+void jffs2_release_xattr_datum(struct jffs2_sb_info *c, struct jffs2_xattr_datum *xd)
+{
+	/* must be called under spin_lock(&c->erase_completion_lock) */
+	if (atomic_read(&xd->refcnt) || xd->node != (void *)xd)
+		return;
+
+	list_del(&xd->xindex);
+	jffs2_free_xattr_datum(xd);
+}
+
+void jffs2_release_xattr_ref(struct jffs2_sb_info *c, struct jffs2_xattr_ref *ref)
+{
+	/* must be called under spin_lock(&c->erase_completion_lock) */
+	struct jffs2_xattr_ref *tmp, **ptmp;
+
+	if (ref->node != (void *)ref)
+		return;
+
+	for (tmp=c->xref_dead_list, ptmp=&c->xref_dead_list; tmp; ptmp=&tmp->next, tmp=tmp->next) {
+		if (ref == tmp) {
+			*ptmp = tmp->next;
+			break;
+		}
+	}
+	jffs2_free_xattr_ref(ref);
+}
diff --git a/fs/jffs2/xattr.h b/fs/jffs2/xattr.h
new file mode 100644
index 000000000..06a5c69dc
--- /dev/null
+++ b/fs/jffs2/xattr.h
@@ -0,0 +1,129 @@
+/*
+ * JFFS2 -- Journalling Flash File System, Version 2.
+ *
+ * Copyright (C) 2006  NEC Corporation
+ *
+ * Created by KaiGai Kohei <kaigai@ak.jp.nec.com>
+ *
+ * For licensing information, see the file 'LICENCE' in this directory.
+ *
+ */
+#ifndef _JFFS2_FS_XATTR_H_
+#define _JFFS2_FS_XATTR_H_
+
+#include <linux/xattr.h>
+#include <linux/list.h>
+
+#define JFFS2_XFLAGS_HOT	(0x01)	/* This datum is HOT */
+#define JFFS2_XFLAGS_BIND	(0x02)	/* This datum is not reclaimed */
+#define JFFS2_XFLAGS_DEAD	(0x40)	/* This datum is already dead */
+#define JFFS2_XFLAGS_INVALID	(0x80)	/* This datum contains crc error */
+
+struct jffs2_xattr_datum
+{
+	void *always_null;
+	struct jffs2_raw_node_ref *node;
+	uint8_t class;
+	uint8_t flags;
+	uint16_t xprefix;		/* see JFFS2_XATTR_PREFIX_* */
+
+	struct list_head xindex;	/* chained from c->xattrindex[n] */
+	atomic_t refcnt;		/* # of xattr_ref refers this */
+	uint32_t xid;
+	uint32_t version;
+
+	uint32_t data_crc;
+	uint32_t hashkey;
+	char *xname;		/* XATTR name without prefix */
+	uint32_t name_len;	/* length of xname */
+	char *xvalue;		/* XATTR value */
+	uint32_t value_len;	/* length of xvalue */
+};
+
+struct jffs2_inode_cache;
+struct jffs2_xattr_ref
+{
+	void *always_null;
+	struct jffs2_raw_node_ref *node;
+	uint8_t class;
+	uint8_t flags;		/* Currently unused */
+	u16 unused;
+
+	uint32_t xseqno;
+	union {
+		struct jffs2_inode_cache *ic;	/* reference to jffs2_inode_cache */
+		uint32_t ino;			/* only used in scanning/building  */
+	};
+	union {
+		struct jffs2_xattr_datum *xd;	/* reference to jffs2_xattr_datum */
+		uint32_t xid;			/* only used in sccanning/building */
+	};
+	struct jffs2_xattr_ref *next;		/* chained from ic->xref_list */
+};
+
+#define XREF_DELETE_MARKER	(0x00000001)
+static inline int is_xattr_ref_dead(struct jffs2_xattr_ref *ref)
+{
+	return ((ref->xseqno & XREF_DELETE_MARKER) != 0);
+}
+
+#ifdef CONFIG_JFFS2_FS_XATTR
+
+extern void jffs2_init_xattr_subsystem(struct jffs2_sb_info *c);
+extern void jffs2_build_xattr_subsystem(struct jffs2_sb_info *c);
+extern void jffs2_clear_xattr_subsystem(struct jffs2_sb_info *c);
+
+extern struct jffs2_xattr_datum *jffs2_setup_xattr_datum(struct jffs2_sb_info *c,
+                                                  uint32_t xid, uint32_t version);
+
+extern void jffs2_xattr_delete_inode(struct jffs2_sb_info *c, struct jffs2_inode_cache *ic);
+extern void jffs2_xattr_free_inode(struct jffs2_sb_info *c, struct jffs2_inode_cache *ic);
+
+extern int jffs2_garbage_collect_xattr_datum(struct jffs2_sb_info *c, struct jffs2_xattr_datum *xd,
+					     struct jffs2_raw_node_ref *raw);
+extern int jffs2_garbage_collect_xattr_ref(struct jffs2_sb_info *c, struct jffs2_xattr_ref *ref,
+					   struct jffs2_raw_node_ref *raw);
+extern int jffs2_verify_xattr(struct jffs2_sb_info *c);
+extern void jffs2_release_xattr_datum(struct jffs2_sb_info *c, struct jffs2_xattr_datum *xd);
+extern void jffs2_release_xattr_ref(struct jffs2_sb_info *c, struct jffs2_xattr_ref *ref);
+
+extern int do_jffs2_getxattr(struct inode *inode, int xprefix, const char *xname,
+			     char *buffer, size_t size);
+extern int do_jffs2_setxattr(struct inode *inode, int xprefix, const char *xname,
+			     const char *buffer, size_t size, int flags);
+
+extern struct xattr_handler *jffs2_xattr_handlers[];
+extern struct xattr_handler jffs2_user_xattr_handler;
+extern struct xattr_handler jffs2_trusted_xattr_handler;
+
+extern ssize_t jffs2_listxattr(struct dentry *, char *, size_t);
+#define jffs2_getxattr		generic_getxattr
+#define jffs2_setxattr		generic_setxattr
+#define jffs2_removexattr	generic_removexattr
+
+#else
+
+#define jffs2_init_xattr_subsystem(c)
+#define jffs2_build_xattr_subsystem(c)
+#define jffs2_clear_xattr_subsystem(c)
+
+#define jffs2_xattr_delete_inode(c, ic)
+#define jffs2_xattr_free_inode(c, ic)
+#define jffs2_verify_xattr(c)			(1)
+
+#define jffs2_xattr_handlers	NULL
+#define jffs2_listxattr		NULL
+#define jffs2_getxattr		NULL
+#define jffs2_setxattr		NULL
+#define jffs2_removexattr	NULL
+
+#endif /* CONFIG_JFFS2_FS_XATTR */
+
+#ifdef CONFIG_JFFS2_FS_SECURITY
+extern int jffs2_init_security(struct inode *inode, struct inode *dir);
+extern struct xattr_handler jffs2_security_xattr_handler;
+#else
+#define jffs2_init_security(inode,dir)	(0)
+#endif /* CONFIG_JFFS2_FS_SECURITY */
+
+#endif /* _JFFS2_FS_XATTR_H_ */
diff --git a/fs/jffs2/xattr_trusted.c b/fs/jffs2/xattr_trusted.c
new file mode 100644
index 000000000..ed046e19d
--- /dev/null
+++ b/fs/jffs2/xattr_trusted.c
@@ -0,0 +1,52 @@
+/*
+ * JFFS2 -- Journalling Flash File System, Version 2.
+ *
+ * Copyright (C) 2006  NEC Corporation
+ *
+ * Created by KaiGai Kohei <kaigai@ak.jp.nec.com>
+ *
+ * For licensing information, see the file 'LICENCE' in this directory.
+ *
+ */
+#include <linux/kernel.h>
+#include <linux/fs.h>
+#include <linux/jffs2.h>
+#include <linux/xattr.h>
+#include <linux/mtd/mtd.h>
+#include "nodelist.h"
+
+static int jffs2_trusted_getxattr(struct inode *inode, const char *name,
+				  void *buffer, size_t size)
+{
+	if (!strcmp(name, ""))
+		return -EINVAL;
+	return do_jffs2_getxattr(inode, JFFS2_XPREFIX_TRUSTED, name, buffer, size);
+}
+
+static int jffs2_trusted_setxattr(struct inode *inode, const char *name, const void *buffer,
+				  size_t size, int flags)
+{
+	if (!strcmp(name, ""))
+		return -EINVAL;
+	return do_jffs2_setxattr(inode, JFFS2_XPREFIX_TRUSTED, name, buffer, size, flags);
+}
+
+static size_t jffs2_trusted_listxattr(struct inode *inode, char *list, size_t list_size,
+				      const char *name, size_t name_len)
+{
+	size_t retlen = XATTR_TRUSTED_PREFIX_LEN + name_len + 1;
+
+	if (list && retlen<=list_size) {
+		strcpy(list, XATTR_TRUSTED_PREFIX);
+		strcpy(list + XATTR_TRUSTED_PREFIX_LEN, name);
+	}
+
+	return retlen;
+}
+
+struct xattr_handler jffs2_trusted_xattr_handler = {
+	.prefix = XATTR_TRUSTED_PREFIX,
+	.list = jffs2_trusted_listxattr,
+	.set = jffs2_trusted_setxattr,
+	.get = jffs2_trusted_getxattr
+};
diff --git a/fs/jffs2/xattr_user.c b/fs/jffs2/xattr_user.c
new file mode 100644
index 000000000..2f8e9aa01
--- /dev/null
+++ b/fs/jffs2/xattr_user.c
@@ -0,0 +1,52 @@
+/*
+ * JFFS2 -- Journalling Flash File System, Version 2.
+ *
+ * Copyright (C) 2006  NEC Corporation
+ *
+ * Created by KaiGai Kohei <kaigai@ak.jp.nec.com>
+ *
+ * For licensing information, see the file 'LICENCE' in this directory.
+ *
+ */
+#include <linux/kernel.h>
+#include <linux/fs.h>
+#include <linux/jffs2.h>
+#include <linux/xattr.h>
+#include <linux/mtd/mtd.h>
+#include "nodelist.h"
+
+static int jffs2_user_getxattr(struct inode *inode, const char *name,
+                               void *buffer, size_t size)
+{
+	if (!strcmp(name, ""))
+		return -EINVAL;
+	return do_jffs2_getxattr(inode, JFFS2_XPREFIX_USER, name, buffer, size);
+}
+
+static int jffs2_user_setxattr(struct inode *inode, const char *name, const void *buffer,
+                               size_t size, int flags)
+{
+	if (!strcmp(name, ""))
+		return -EINVAL;
+	return do_jffs2_setxattr(inode, JFFS2_XPREFIX_USER, name, buffer, size, flags);
+}
+
+static size_t jffs2_user_listxattr(struct inode *inode, char *list, size_t list_size,
+				   const char *name, size_t name_len)
+{
+	size_t retlen = XATTR_USER_PREFIX_LEN + name_len + 1;
+
+	if (list && retlen <= list_size) {
+		strcpy(list, XATTR_USER_PREFIX);
+		strcpy(list + XATTR_USER_PREFIX_LEN, name);
+	}
+
+	return retlen;
+}
+
+struct xattr_handler jffs2_user_xattr_handler = {
+	.prefix = XATTR_USER_PREFIX,
+	.list = jffs2_user_listxattr,
+	.set = jffs2_user_setxattr,
+	.get = jffs2_user_getxattr
+};
diff --git a/fs/nfs/client.c b/fs/nfs/client.c
new file mode 100644
index 000000000..aa9e41219
--- /dev/null
+++ b/fs/nfs/client.c
@@ -0,0 +1,1436 @@
+/* client.c: NFS client sharing and management code
+ *
+ * Copyright (C) 2006 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@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.
+ */
+
+
+#include <linux/module.h>
+#include <linux/init.h>
+
+#include <linux/time.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/string.h>
+#include <linux/stat.h>
+#include <linux/errno.h>
+#include <linux/unistd.h>
+#include <linux/sunrpc/clnt.h>
+#include <linux/sunrpc/stats.h>
+#include <linux/sunrpc/metrics.h>
+#include <linux/nfs_fs.h>
+#include <linux/nfs_mount.h>
+#include <linux/nfs4_mount.h>
+#include <linux/lockd/bind.h>
+#include <linux/smp_lock.h>
+#include <linux/seq_file.h>
+#include <linux/mount.h>
+#include <linux/nfs_idmap.h>
+#include <linux/vfs.h>
+#include <linux/inet.h>
+#include <linux/nfs_xdr.h>
+
+#include <asm/system.h>
+
+#include "nfs4_fs.h"
+#include "callback.h"
+#include "delegation.h"
+#include "iostat.h"
+#include "internal.h"
+
+#define NFSDBG_FACILITY		NFSDBG_CLIENT
+
+static DEFINE_SPINLOCK(nfs_client_lock);
+static LIST_HEAD(nfs_client_list);
+static LIST_HEAD(nfs_volume_list);
+static DECLARE_WAIT_QUEUE_HEAD(nfs_client_active_wq);
+
+/*
+ * RPC cruft for NFS
+ */
+static struct rpc_version *nfs_version[5] = {
+	[2]			= &nfs_version2,
+#ifdef CONFIG_NFS_V3
+	[3]			= &nfs_version3,
+#endif
+#ifdef CONFIG_NFS_V4
+	[4]			= &nfs_version4,
+#endif
+};
+
+struct rpc_program nfs_program = {
+	.name			= "nfs",
+	.number			= NFS_PROGRAM,
+	.nrvers			= ARRAY_SIZE(nfs_version),
+	.version		= nfs_version,
+	.stats			= &nfs_rpcstat,
+	.pipe_dir_name		= "/nfs",
+};
+
+struct rpc_stat nfs_rpcstat = {
+	.program		= &nfs_program
+};
+
+
+#ifdef CONFIG_NFS_V3_ACL
+static struct rpc_stat		nfsacl_rpcstat = { &nfsacl_program };
+static struct rpc_version *	nfsacl_version[] = {
+	[3]			= &nfsacl_version3,
+};
+
+struct rpc_program		nfsacl_program = {
+	.name			= "nfsacl",
+	.number			= NFS_ACL_PROGRAM,
+	.nrvers			= ARRAY_SIZE(nfsacl_version),
+	.version		= nfsacl_version,
+	.stats			= &nfsacl_rpcstat,
+};
+#endif  /* CONFIG_NFS_V3_ACL */
+
+/*
+ * Allocate a shared client record
+ *
+ * Since these are allocated/deallocated very rarely, we don't
+ * bother putting them in a slab cache...
+ */
+static struct nfs_client *nfs_alloc_client(const char *hostname,
+					   const struct sockaddr_in *addr,
+					   int nfsversion)
+{
+	struct nfs_client *clp;
+	int error;
+
+	if ((clp = kzalloc(sizeof(*clp), GFP_KERNEL)) == NULL)
+		goto error_0;
+
+	error = rpciod_up();
+	if (error < 0) {
+		dprintk("%s: couldn't start rpciod! Error = %d\n",
+				__FUNCTION__, error);
+		goto error_1;
+	}
+	__set_bit(NFS_CS_RPCIOD, &clp->cl_res_state);
+
+	if (nfsversion == 4) {
+		if (nfs_callback_up() < 0)
+			goto error_2;
+		__set_bit(NFS_CS_CALLBACK, &clp->cl_res_state);
+	}
+
+	atomic_set(&clp->cl_count, 1);
+	clp->cl_cons_state = NFS_CS_INITING;
+
+	clp->cl_nfsversion = nfsversion;
+	memcpy(&clp->cl_addr, addr, sizeof(clp->cl_addr));
+
+	if (hostname) {
+		clp->cl_hostname = kstrdup(hostname, GFP_KERNEL);
+		if (!clp->cl_hostname)
+			goto error_3;
+	}
+
+	INIT_LIST_HEAD(&clp->cl_superblocks);
+	clp->cl_rpcclient = ERR_PTR(-EINVAL);
+
+#ifdef CONFIG_NFS_V4
+	init_rwsem(&clp->cl_sem);
+	INIT_LIST_HEAD(&clp->cl_delegations);
+	INIT_LIST_HEAD(&clp->cl_state_owners);
+	INIT_LIST_HEAD(&clp->cl_unused);
+	spin_lock_init(&clp->cl_lock);
+	INIT_WORK(&clp->cl_renewd, nfs4_renew_state, clp);
+	rpc_init_wait_queue(&clp->cl_rpcwaitq, "NFS client");
+	clp->cl_boot_time = CURRENT_TIME;
+	clp->cl_state = 1 << NFS4CLNT_LEASE_EXPIRED;
+#endif
+
+	nfs_fscache_get_client_cookie(clp);
+
+	return clp;
+
+error_3:
+	if (__test_and_clear_bit(NFS_CS_CALLBACK, &clp->cl_res_state))
+		nfs_callback_down();
+error_2:
+	rpciod_down();
+	__clear_bit(NFS_CS_RPCIOD, &clp->cl_res_state);
+error_1:
+	kfree(clp);
+error_0:
+	return NULL;
+}
+
+static void nfs4_shutdown_client(struct nfs_client *clp)
+{
+#ifdef CONFIG_NFS_V4
+	if (__test_and_clear_bit(NFS_CS_RENEWD, &clp->cl_res_state))
+		nfs4_kill_renewd(clp);
+	while (!list_empty(&clp->cl_unused)) {
+		struct nfs4_state_owner *sp;
+
+		sp = list_entry(clp->cl_unused.next,
+				struct nfs4_state_owner,
+				so_list);
+		list_del(&sp->so_list);
+		kfree(sp);
+	}
+	BUG_ON(!list_empty(&clp->cl_state_owners));
+	if (__test_and_clear_bit(NFS_CS_IDMAP, &clp->cl_res_state))
+		nfs_idmap_delete(clp);
+#endif
+}
+
+/*
+ * Destroy a shared client record
+ */
+static void nfs_free_client(struct nfs_client *clp)
+{
+	dprintk("--> nfs_free_client(%d)\n", clp->cl_nfsversion);
+
+	nfs4_shutdown_client(clp);
+
+	nfs_fscache_release_client_cookie(clp);
+
+	/* -EIO all pending I/O */
+	if (!IS_ERR(clp->cl_rpcclient))
+		rpc_shutdown_client(clp->cl_rpcclient);
+
+	if (__test_and_clear_bit(NFS_CS_CALLBACK, &clp->cl_res_state))
+		nfs_callback_down();
+
+	if (__test_and_clear_bit(NFS_CS_RPCIOD, &clp->cl_res_state))
+		rpciod_down();
+
+	kfree(clp->cl_hostname);
+	kfree(clp);
+
+	dprintk("<-- nfs_free_client()\n");
+}
+
+/*
+ * Release a reference to a shared client record
+ */
+void nfs_put_client(struct nfs_client *clp)
+{
+	if (!clp)
+		return;
+
+	dprintk("--> nfs_put_client({%d})\n", atomic_read(&clp->cl_count));
+
+	if (atomic_dec_and_lock(&clp->cl_count, &nfs_client_lock)) {
+		list_del(&clp->cl_share_link);
+		spin_unlock(&nfs_client_lock);
+
+		BUG_ON(!list_empty(&clp->cl_superblocks));
+
+		nfs_free_client(clp);
+	}
+}
+
+/*
+ * Find a client by address
+ * - caller must hold nfs_client_lock
+ */
+static struct nfs_client *__nfs_find_client(const struct sockaddr_in *addr, int nfsversion)
+{
+	struct nfs_client *clp;
+
+	list_for_each_entry(clp, &nfs_client_list, cl_share_link) {
+		/* Different NFS versions cannot share the same nfs_client */
+		if (clp->cl_nfsversion != nfsversion)
+			continue;
+
+		if (memcmp(&clp->cl_addr.sin_addr, &addr->sin_addr,
+			   sizeof(clp->cl_addr.sin_addr)) != 0)
+			continue;
+
+		if (clp->cl_addr.sin_port == addr->sin_port)
+			goto found;
+	}
+
+	return NULL;
+
+found:
+	atomic_inc(&clp->cl_count);
+	return clp;
+}
+
+/*
+ * Find a client by IP address and protocol version
+ * - returns NULL if no such client
+ */
+struct nfs_client *nfs_find_client(const struct sockaddr_in *addr, int nfsversion)
+{
+	struct nfs_client *clp;
+
+	spin_lock(&nfs_client_lock);
+	clp = __nfs_find_client(addr, nfsversion);
+	spin_unlock(&nfs_client_lock);
+
+	BUG_ON(clp->cl_cons_state == 0);
+
+	return clp;
+}
+
+/*
+ * Look up a client by IP address and protocol version
+ * - creates a new record if one doesn't yet exist
+ */
+static struct nfs_client *nfs_get_client(const char *hostname,
+					 const struct sockaddr_in *addr,
+					 int nfsversion)
+{
+	struct nfs_client *clp, *new = NULL;
+	int error;
+
+	dprintk("--> nfs_get_client(%s,"NIPQUAD_FMT":%d,%d)\n",
+		hostname ?: "", NIPQUAD(addr->sin_addr),
+		addr->sin_port, nfsversion);
+
+	/* see if the client already exists */
+	do {
+		spin_lock(&nfs_client_lock);
+
+		clp = __nfs_find_client(addr, nfsversion);
+		if (clp)
+			goto found_client;
+		if (new)
+			goto install_client;
+
+		spin_unlock(&nfs_client_lock);
+
+		new = nfs_alloc_client(hostname, addr, nfsversion);
+	} while (new);
+
+	return ERR_PTR(-ENOMEM);
+
+	/* install a new client and return with it unready */
+install_client:
+	clp = new;
+	list_add(&clp->cl_share_link, &nfs_client_list);
+	spin_unlock(&nfs_client_lock);
+	dprintk("--> nfs_get_client() = %p [new]\n", clp);
+	return clp;
+
+	/* found an existing client
+	 * - make sure it's ready before returning
+	 */
+found_client:
+	spin_unlock(&nfs_client_lock);
+
+	if (new)
+		nfs_free_client(new);
+
+	error = wait_event_interruptible(nfs_client_active_wq,
+		clp->cl_cons_state != NFS_CS_INITING);
+	if (error < 0) {
+		nfs_put_client(clp);
+		return ERR_PTR(-ERESTARTSYS);
+	}
+
+	if (clp->cl_cons_state < NFS_CS_READY) {
+		error = clp->cl_cons_state;
+		nfs_put_client(clp);
+		return ERR_PTR(error);
+	}
+
+	BUG_ON(clp->cl_cons_state != NFS_CS_READY);
+
+	dprintk("--> nfs_get_client() = %p [share]\n", clp);
+	return clp;
+}
+
+/*
+ * Mark a server as ready or failed
+ */
+static void nfs_mark_client_ready(struct nfs_client *clp, int state)
+{
+	clp->cl_cons_state = state;
+	wake_up_all(&nfs_client_active_wq);
+}
+
+/*
+ * Initialise the timeout values for a connection
+ */
+static void nfs_init_timeout_values(struct rpc_timeout *to, int proto,
+				    unsigned int timeo, unsigned int retrans)
+{
+	to->to_initval = timeo * HZ / 10;
+	to->to_retries = retrans;
+	if (!to->to_retries)
+		to->to_retries = 2;
+
+	switch (proto) {
+	case IPPROTO_TCP:
+		if (!to->to_initval)
+			to->to_initval = 60 * HZ;
+		if (to->to_initval > NFS_MAX_TCP_TIMEOUT)
+			to->to_initval = NFS_MAX_TCP_TIMEOUT;
+		to->to_increment = to->to_initval;
+		to->to_maxval = to->to_initval + (to->to_increment * to->to_retries);
+		to->to_exponential = 0;
+		break;
+	case IPPROTO_UDP:
+	default:
+		if (!to->to_initval)
+			to->to_initval = 11 * HZ / 10;
+		if (to->to_initval > NFS_MAX_UDP_TIMEOUT)
+			to->to_initval = NFS_MAX_UDP_TIMEOUT;
+		to->to_maxval = NFS_MAX_UDP_TIMEOUT;
+		to->to_exponential = 1;
+		break;
+	}
+}
+
+/*
+ * Create an RPC client handle
+ */
+static int nfs_create_rpc_client(struct nfs_client *clp, int proto,
+						unsigned int timeo,
+						unsigned int retrans,
+						rpc_authflavor_t flavor)
+{
+	struct rpc_timeout	timeparms;
+	struct rpc_xprt		*xprt = NULL;
+	struct rpc_clnt		*clnt = NULL;
+
+	if (!IS_ERR(clp->cl_rpcclient))
+		return 0;
+
+	nfs_init_timeout_values(&timeparms, proto, timeo, retrans);
+	clp->retrans_timeo = timeparms.to_initval;
+	clp->retrans_count = timeparms.to_retries;
+
+	/* create transport and client */
+	xprt = xprt_create_proto(proto, &clp->cl_addr, &timeparms);
+	if (IS_ERR(xprt)) {
+		dprintk("%s: cannot create RPC transport. Error = %ld\n",
+				__FUNCTION__, PTR_ERR(xprt));
+		return PTR_ERR(xprt);
+	}
+
+	/* Bind to a reserved port! */
+	xprt->resvport = 1;
+	/* Create the client RPC handle */
+	clnt = rpc_create_client(xprt, clp->cl_hostname, &nfs_program,
+				 clp->rpc_ops->version, RPC_AUTH_UNIX);
+	if (IS_ERR(clnt)) {
+		dprintk("%s: cannot create RPC client. Error = %ld\n",
+				__FUNCTION__, PTR_ERR(clnt));
+		return PTR_ERR(clnt);
+	}
+
+	clnt->cl_intr     = 1;
+	clnt->cl_softrtry = 1;
+	clnt->cl_tagxid   = 1;
+	clp->cl_rpcclient = clnt;
+	return 0;
+}
+
+/*
+ * Version 2 or 3 client destruction
+ */
+static void nfs_destroy_server(struct nfs_server *server)
+{
+	if (!IS_ERR(server->client_acl))
+		rpc_shutdown_client(server->client_acl);
+
+	if (!(server->flags & NFS_MOUNT_NONLM))
+		lockd_down();	/* release rpc.lockd */
+}
+
+/*
+ * Version 2 or 3 lockd setup
+ */
+static int nfs_start_lockd(struct nfs_server *server)
+{
+	int error = 0;
+
+	if (server->nfs_client->cl_nfsversion > 3)
+		goto out;
+	if (server->flags & NFS_MOUNT_NONLM)
+		goto out;
+	error = lockd_up();
+	if (error < 0)
+		server->flags |= NFS_MOUNT_NONLM;
+	else
+		server->destroy = nfs_destroy_server;
+out:
+	return error;
+}
+
+/*
+ * Initialise an NFSv3 ACL client connection
+ */
+#ifdef CONFIG_NFS_V3_ACL
+static void nfs_init_server_aclclient(struct nfs_server *server)
+{
+	if (server->nfs_client->cl_nfsversion != 3)
+		goto out_noacl;
+	if (server->flags & NFS_MOUNT_NOACL)
+		goto out_noacl;
+
+	server->client_acl = rpc_bind_new_program(server->client, &nfsacl_program, 3);
+	if (IS_ERR(server->client_acl))
+		goto out_noacl;
+
+	/* No errors! Assume that Sun nfsacls are supported */
+	server->caps |= NFS_CAP_ACLS;
+	return;
+
+out_noacl:
+	server->caps &= ~NFS_CAP_ACLS;
+}
+#else
+static inline void nfs_init_server_aclclient(struct nfs_server *server)
+{
+	server->flags &= ~NFS_MOUNT_NOACL;
+	server->caps &= ~NFS_CAP_ACLS;
+}
+#endif
+
+/*
+ * Create a general RPC client
+ */
+static int nfs_init_server_rpcclient(struct nfs_server *server, rpc_authflavor_t pseudoflavour)
+{
+	struct nfs_client *clp = server->nfs_client;
+
+	server->client = rpc_clone_client(clp->cl_rpcclient);
+	if (IS_ERR(server->client)) {
+		dprintk("%s: couldn't create rpc_client!\n", __FUNCTION__);
+		return PTR_ERR(server->client);
+	}
+
+	if (pseudoflavour != clp->cl_rpcclient->cl_auth->au_flavor) {
+		struct rpc_auth *auth;
+
+		auth = rpcauth_create(pseudoflavour, server->client);
+		if (IS_ERR(auth)) {
+			dprintk("%s: couldn't create credcache!\n", __FUNCTION__);
+			return PTR_ERR(auth);
+		}
+	}
+	server->client->cl_softrtry = 0;
+	if (server->flags & NFS_MOUNT_SOFT)
+		server->client->cl_softrtry = 1;
+
+	server->client->cl_intr = 0;
+	if (server->flags & NFS4_MOUNT_INTR)
+		server->client->cl_intr = 1;
+
+	server->client->cl_tagxid = (server->flags & NFS_MOUNT_TAGXID) ? 1 : 0;
+
+	return 0;
+}
+
+/*
+ * Initialise an NFS2 or NFS3 client
+ */
+static int nfs_init_client(struct nfs_client *clp, const struct nfs_mount_data *data)
+{
+	int proto = (data->flags & NFS_MOUNT_TCP) ? IPPROTO_TCP : IPPROTO_UDP;
+	int error;
+
+	if (clp->cl_cons_state == NFS_CS_READY) {
+		/* the client is already initialised */
+		dprintk("<-- nfs_init_client() = 0 [already %p]\n", clp);
+		return 0;
+	}
+
+	/* Check NFS protocol revision and initialize RPC op vector */
+	clp->rpc_ops = &nfs_v2_clientops;
+#ifdef CONFIG_NFS_V3
+	if (clp->cl_nfsversion == 3)
+		clp->rpc_ops = &nfs_v3_clientops;
+#endif
+	/*
+	 * Create a client RPC handle for doing FSSTAT with UNIX auth only
+	 * - RFC 2623, sec 2.3.2
+	 */
+	error = nfs_create_rpc_client(clp, proto, data->timeo, data->retrans,
+			RPC_AUTH_UNIX);
+	if (error < 0)
+		goto error;
+	nfs_mark_client_ready(clp, NFS_CS_READY);
+	return 0;
+
+error:
+	nfs_mark_client_ready(clp, error);
+	dprintk("<-- nfs_init_client() = xerror %d\n", error);
+	return error;
+}
+
+/*
+ * Create a version 2 or 3 client
+ */
+static int nfs_init_server(struct nfs_server *server, const struct nfs_mount_data *data)
+{
+	struct nfs_client *clp;
+	int error, nfsvers = 2;
+
+	dprintk("--> nfs_init_server()\n");
+
+#ifdef CONFIG_NFS_V3
+	if (data->flags & NFS_MOUNT_VER3)
+		nfsvers = 3;
+#endif
+
+	/* Allocate or find a client reference we can use */
+	clp = nfs_get_client(data->hostname, &data->addr, nfsvers);
+	if (IS_ERR(clp)) {
+		dprintk("<-- nfs_init_server() = error %ld\n", PTR_ERR(clp));
+		return PTR_ERR(clp);
+	}
+
+	error = nfs_init_client(clp, data);
+	if (error < 0)
+		goto error;
+
+	server->nfs_client = clp;
+
+	/* Initialise the client representation from the mount data */
+	server->flags = data->flags & NFS_MOUNT_FLAGMASK;
+
+	if (data->rsize)
+		server->rsize = nfs_block_size(data->rsize, NULL);
+	if (data->wsize)
+		server->wsize = nfs_block_size(data->wsize, NULL);
+
+	server->acregmin = data->acregmin * HZ;
+	server->acregmax = data->acregmax * HZ;
+	server->acdirmin = data->acdirmin * HZ;
+	server->acdirmax = data->acdirmax * HZ;
+
+	/* Start lockd here, before we might error out */
+	error = nfs_start_lockd(server);
+	if (error < 0)
+		goto error;
+
+	error = nfs_init_server_rpcclient(server, data->pseudoflavor);
+	if (error < 0)
+		goto error;
+
+	server->namelen  = data->namlen;
+	/* Create a client RPC handle for the NFSv3 ACL management interface */
+	nfs_init_server_aclclient(server);
+	if (clp->cl_nfsversion == 3) {
+		if (server->namelen == 0 || server->namelen > NFS3_MAXNAMLEN)
+			server->namelen = NFS3_MAXNAMLEN;
+		server->caps |= NFS_CAP_READDIRPLUS;
+	} else {
+		if (server->namelen == 0 || server->namelen > NFS2_MAXNAMLEN)
+			server->namelen = NFS2_MAXNAMLEN;
+	}
+
+	dprintk("<-- nfs_init_server() = 0 [new %p]\n", clp);
+	return 0;
+
+error:
+	server->nfs_client = NULL;
+	nfs_put_client(clp);
+	dprintk("<-- nfs_init_server() = xerror %d\n", error);
+	return error;
+}
+
+/*
+ * Load up the server record from information gained in an fsinfo record
+ */
+static void nfs_server_set_fsinfo(struct nfs_server *server, struct nfs_fsinfo *fsinfo)
+{
+	unsigned long max_rpc_payload;
+
+	/* Work out a lot of parameters */
+	if (server->rsize == 0)
+		server->rsize = nfs_block_size(fsinfo->rtpref, NULL);
+	if (server->wsize == 0)
+		server->wsize = nfs_block_size(fsinfo->wtpref, NULL);
+
+	if (fsinfo->rtmax >= 512 && server->rsize > fsinfo->rtmax)
+		server->rsize = nfs_block_size(fsinfo->rtmax, NULL);
+	if (fsinfo->wtmax >= 512 && server->wsize > fsinfo->wtmax)
+		server->wsize = nfs_block_size(fsinfo->wtmax, NULL);
+
+	max_rpc_payload = nfs_block_size(rpc_max_payload(server->client), NULL);
+	if (server->rsize > max_rpc_payload)
+		server->rsize = max_rpc_payload;
+	if (server->rsize > NFS_MAX_FILE_IO_SIZE)
+		server->rsize = NFS_MAX_FILE_IO_SIZE;
+	server->rpages = (server->rsize + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
+	server->backing_dev_info.ra_pages = server->rpages * NFS_MAX_READAHEAD;
+
+	if (server->wsize > max_rpc_payload)
+		server->wsize = max_rpc_payload;
+	if (server->wsize > NFS_MAX_FILE_IO_SIZE)
+		server->wsize = NFS_MAX_FILE_IO_SIZE;
+	server->wpages = (server->wsize + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
+	server->wtmult = nfs_block_bits(fsinfo->wtmult, NULL);
+
+	server->dtsize = nfs_block_size(fsinfo->dtpref, NULL);
+	if (server->dtsize > PAGE_CACHE_SIZE)
+		server->dtsize = PAGE_CACHE_SIZE;
+	if (server->dtsize > server->rsize)
+		server->dtsize = server->rsize;
+
+	if (server->flags & NFS_MOUNT_NOAC) {
+		server->acregmin = server->acregmax = 0;
+		server->acdirmin = server->acdirmax = 0;
+	}
+
+	server->maxfilesize = fsinfo->maxfilesize;
+
+	/* We're airborne Set socket buffersize */
+	rpc_setbufsize(server->client, server->wsize + 100, server->rsize + 100);
+}
+
+/*
+ * Probe filesystem information, including the FSID on v2/v3
+ */
+static int nfs_probe_fsinfo(struct nfs_server *server, struct nfs_fh *mntfh, struct nfs_fattr *fattr)
+{
+	struct nfs_fsinfo fsinfo;
+	struct nfs_client *clp = server->nfs_client;
+	int error;
+
+	dprintk("--> nfs_probe_fsinfo()\n");
+
+	if (clp->rpc_ops->set_capabilities != NULL) {
+		error = clp->rpc_ops->set_capabilities(server, mntfh);
+		if (error < 0)
+			goto out_error;
+	}
+
+	fsinfo.fattr = fattr;
+	nfs_fattr_init(fattr);
+	error = clp->rpc_ops->fsinfo(server, mntfh, &fsinfo);
+	if (error < 0)
+		goto out_error;
+
+	nfs_server_set_fsinfo(server, &fsinfo);
+
+	/* Get some general file system info */
+	if (server->namelen == 0) {
+		struct nfs_pathconf pathinfo;
+
+		pathinfo.fattr = fattr;
+		nfs_fattr_init(fattr);
+
+		if (clp->rpc_ops->pathconf(server, mntfh, &pathinfo) >= 0)
+			server->namelen = pathinfo.max_namelen;
+	}
+
+	dprintk("<-- nfs_probe_fsinfo() = 0\n");
+	return 0;
+
+out_error:
+	dprintk("nfs_probe_fsinfo: error = %d\n", -error);
+	return error;
+}
+
+/*
+ * Copy useful information when duplicating a server record
+ */
+static void nfs_server_copy_userdata(struct nfs_server *target, struct nfs_server *source)
+{
+	target->flags = source->flags;
+	target->acregmin = source->acregmin;
+	target->acregmax = source->acregmax;
+	target->acdirmin = source->acdirmin;
+	target->acdirmax = source->acdirmax;
+	target->caps = source->caps;
+}
+
+/*
+ * Allocate and initialise a server record
+ */
+static struct nfs_server *nfs_alloc_server(void)
+{
+	struct nfs_server *server;
+
+	server = kzalloc(sizeof(struct nfs_server), GFP_KERNEL);
+	if (!server)
+		return NULL;
+
+	server->client = server->client_acl = ERR_PTR(-EINVAL);
+
+	/* Zero out the NFS state stuff */
+	INIT_LIST_HEAD(&server->client_link);
+	INIT_LIST_HEAD(&server->master_link);
+
+	server->io_stats = nfs_alloc_iostats();
+	if (!server->io_stats) {
+		kfree(server);
+		return NULL;
+	}
+
+	return server;
+}
+
+/*
+ * Free up a server record
+ */
+void nfs_free_server(struct nfs_server *server)
+{
+	dprintk("--> nfs_free_server()\n");
+
+	spin_lock(&nfs_client_lock);
+	list_del(&server->client_link);
+	list_del(&server->master_link);
+	spin_unlock(&nfs_client_lock);
+
+	if (server->destroy != NULL)
+		server->destroy(server);
+	if (!IS_ERR(server->client))
+		rpc_shutdown_client(server->client);
+
+	nfs_put_client(server->nfs_client);
+
+	nfs_free_iostats(server->io_stats);
+	kfree(server);
+	nfs_release_automount_timer();
+	dprintk("<-- nfs_free_server()\n");
+}
+
+/*
+ * Create a version 2 or 3 volume record
+ * - keyed on server and FSID
+ */
+struct nfs_server *nfs_create_server(const struct nfs_mount_data *data,
+				     struct nfs_fh *mntfh)
+{
+	struct nfs_server *server;
+	struct nfs_fattr fattr;
+	int error;
+
+	server = nfs_alloc_server();
+	if (!server)
+		return ERR_PTR(-ENOMEM);
+
+	/* Get a client representation */
+	error = nfs_init_server(server, data);
+	if (error < 0)
+		goto error;
+
+	BUG_ON(!server->nfs_client);
+	BUG_ON(!server->nfs_client->rpc_ops);
+	BUG_ON(!server->nfs_client->rpc_ops->file_inode_ops);
+
+	/* Probe the root fh to retrieve its FSID */
+	error = nfs_probe_fsinfo(server, mntfh, &fattr);
+	if (error < 0)
+		goto error;
+	if (!(fattr.valid & NFS_ATTR_FATTR)) {
+		error = server->nfs_client->rpc_ops->getattr(server, mntfh, &fattr);
+		if (error < 0) {
+			dprintk("nfs_create_server: getattr error = %d\n", -error);
+			goto error;
+		}
+	}
+	memcpy(&server->fsid, &fattr.fsid, sizeof(server->fsid));
+
+	dprintk("Server FSID: %llx:%llx\n", server->fsid.major, server->fsid.minor);
+
+	BUG_ON(!server->nfs_client);
+	BUG_ON(!server->nfs_client->rpc_ops);
+	BUG_ON(!server->nfs_client->rpc_ops->file_inode_ops);
+
+	spin_lock(&nfs_client_lock);
+	list_add_tail(&server->client_link, &server->nfs_client->cl_superblocks);
+	list_add_tail(&server->master_link, &nfs_volume_list);
+	spin_unlock(&nfs_client_lock);
+
+	server->mount_time = jiffies;
+	return server;
+
+error:
+	nfs_free_server(server);
+	return ERR_PTR(error);
+}
+
+#ifdef CONFIG_NFS_V4
+/*
+ * Initialise an NFS4 client record
+ */
+static int nfs4_init_client(struct nfs_client *clp,
+		int proto, int timeo, int retrans,
+		rpc_authflavor_t authflavour)
+{
+	int error;
+
+	if (clp->cl_cons_state == NFS_CS_READY) {
+		/* the client is initialised already */
+		dprintk("<-- nfs4_init_client() = 0 [already %p]\n", clp);
+		return 0;
+	}
+
+	/* Check NFS protocol revision and initialize RPC op vector */
+	clp->rpc_ops = &nfs_v4_clientops;
+
+	error = nfs_create_rpc_client(clp, proto, timeo, retrans, authflavour);
+	if (error < 0)
+		goto error;
+
+	error = nfs_idmap_new(clp);
+	if (error < 0) {
+		dprintk("%s: failed to create idmapper. Error = %d\n",
+			__FUNCTION__, error);
+		goto error;
+	}
+	__set_bit(NFS_CS_IDMAP, &clp->cl_res_state);
+
+	nfs_mark_client_ready(clp, NFS_CS_READY);
+	return 0;
+
+error:
+	nfs_mark_client_ready(clp, error);
+	dprintk("<-- nfs4_init_client() = xerror %d\n", error);
+	return error;
+}
+
+/*
+ * Set up an NFS4 client
+ */
+static int nfs4_set_client(struct nfs_server *server,
+		const char *hostname, const struct sockaddr_in *addr,
+		rpc_authflavor_t authflavour,
+		int proto, int timeo, int retrans)
+{
+	struct nfs_client *clp;
+	int error;
+
+	dprintk("--> nfs4_set_client()\n");
+
+	/* Allocate or find a client reference we can use */
+	clp = nfs_get_client(hostname, addr, 4);
+	if (IS_ERR(clp)) {
+		error = PTR_ERR(clp);
+		goto error;
+	}
+	error = nfs4_init_client(clp, proto, timeo, retrans, authflavour);
+	if (error < 0)
+		goto error_put;
+
+	server->nfs_client = clp;
+	dprintk("<-- nfs4_set_client() = 0 [new %p]\n", clp);
+	return 0;
+
+error_put:
+	nfs_put_client(clp);
+error:
+	dprintk("<-- nfs4_set_client() = xerror %d\n", error);
+	return error;
+}
+
+/*
+ * Create a version 4 volume record
+ */
+static int nfs4_init_server(struct nfs_server *server,
+		const struct nfs4_mount_data *data, rpc_authflavor_t authflavour)
+{
+	int error;
+
+	dprintk("--> nfs4_init_server()\n");
+
+	/* Initialise the client representation from the mount data */
+	server->flags = data->flags & NFS_MOUNT_FLAGMASK;
+	server->caps |= NFS_CAP_ATOMIC_OPEN;
+
+	if (data->rsize)
+		server->rsize = nfs_block_size(data->rsize, NULL);
+	if (data->wsize)
+		server->wsize = nfs_block_size(data->wsize, NULL);
+
+	server->acregmin = data->acregmin * HZ;
+	server->acregmax = data->acregmax * HZ;
+	server->acdirmin = data->acdirmin * HZ;
+	server->acdirmax = data->acdirmax * HZ;
+
+	error = nfs_init_server_rpcclient(server, authflavour);
+
+	/* Done */
+	dprintk("<-- nfs4_init_server() = %d\n", error);
+	return error;
+}
+
+/*
+ * Create a version 4 volume record
+ * - keyed on server and FSID
+ */
+struct nfs_server *nfs4_create_server(const struct nfs4_mount_data *data,
+				      const char *hostname,
+				      const struct sockaddr_in *addr,
+				      const char *mntpath,
+				      const char *ip_addr,
+				      rpc_authflavor_t authflavour,
+				      struct nfs_fh *mntfh)
+{
+	struct nfs_fattr fattr;
+	struct nfs_server *server;
+	int error;
+
+	dprintk("--> nfs4_create_server()\n");
+
+	server = nfs_alloc_server();
+	if (!server)
+		return ERR_PTR(-ENOMEM);
+
+	/* Get a client record */
+	error = nfs4_set_client(server, hostname, addr, authflavour,
+			data->proto, data->timeo, data->retrans);
+	if (error < 0)
+		goto error;
+
+	/* set up the general RPC client */
+	error = nfs4_init_server(server, data, authflavour);
+	if (error < 0)
+		goto error;
+
+	BUG_ON(!server->nfs_client);
+	BUG_ON(!server->nfs_client->rpc_ops);
+	BUG_ON(!server->nfs_client->rpc_ops->file_inode_ops);
+
+	/* Probe the root fh to retrieve its FSID */
+	error = nfs4_path_walk(server, mntfh, mntpath);
+	if (error < 0)
+		goto error;
+
+	dprintk("Server FSID: %llx:%llx\n", server->fsid.major, server->fsid.minor);
+	dprintk("Mount FH: %d\n", mntfh->size);
+
+	error = nfs_probe_fsinfo(server, mntfh, &fattr);
+	if (error < 0)
+		goto error;
+
+	BUG_ON(!server->nfs_client);
+	BUG_ON(!server->nfs_client->rpc_ops);
+	BUG_ON(!server->nfs_client->rpc_ops->file_inode_ops);
+
+	spin_lock(&nfs_client_lock);
+	list_add_tail(&server->client_link, &server->nfs_client->cl_superblocks);
+	list_add_tail(&server->master_link, &nfs_volume_list);
+	spin_unlock(&nfs_client_lock);
+
+	server->mount_time = jiffies;
+	dprintk("<-- nfs4_create_server() = %p\n", server);
+	return server;
+
+error:
+	nfs_free_server(server);
+	dprintk("<-- nfs4_create_server() = error %d\n", error);
+	return ERR_PTR(error);
+}
+
+/*
+ * Create an NFS4 referral server record
+ */
+struct nfs_server *nfs4_create_referral_server(struct nfs_clone_mount *data,
+					       struct nfs_fh *fh)
+{
+	struct nfs_client *parent_client;
+	struct nfs_server *server, *parent_server;
+	struct nfs_fattr fattr;
+	int error;
+
+	dprintk("--> nfs4_create_referral_server()\n");
+
+	server = nfs_alloc_server();
+	if (!server)
+		return ERR_PTR(-ENOMEM);
+
+	parent_server = NFS_SB(data->sb);
+	parent_client = parent_server->nfs_client;
+
+	/* Get a client representation.
+	 * Note: NFSv4 always uses TCP, */
+	error = nfs4_set_client(server, data->hostname, data->addr,
+			data->authflavor,
+			parent_server->client->cl_xprt->prot,
+			parent_client->retrans_timeo,
+			parent_client->retrans_count);
+
+	/* Initialise the client representation from the parent server */
+	nfs_server_copy_userdata(server, parent_server);
+	server->caps |= NFS_CAP_ATOMIC_OPEN;
+
+	error = nfs_init_server_rpcclient(server, data->authflavor);
+	if (error < 0)
+		goto error;
+
+	BUG_ON(!server->nfs_client);
+	BUG_ON(!server->nfs_client->rpc_ops);
+	BUG_ON(!server->nfs_client->rpc_ops->file_inode_ops);
+
+	/* probe the filesystem info for this server filesystem */
+	error = nfs_probe_fsinfo(server, fh, &fattr);
+	if (error < 0)
+		goto error;
+
+	dprintk("Referral FSID: %llx:%llx\n",
+		server->fsid.major, server->fsid.minor);
+
+	spin_lock(&nfs_client_lock);
+	list_add_tail(&server->client_link, &server->nfs_client->cl_superblocks);
+	list_add_tail(&server->master_link, &nfs_volume_list);
+	spin_unlock(&nfs_client_lock);
+
+	server->mount_time = jiffies;
+
+	dprintk("<-- nfs_create_referral_server() = %p\n", server);
+	return server;
+
+error:
+	nfs_free_server(server);
+	dprintk("<-- nfs4_create_referral_server() = error %d\n", error);
+	return ERR_PTR(error);
+}
+
+#endif /* CONFIG_NFS_V4 */
+
+/*
+ * Clone an NFS2, NFS3 or NFS4 server record
+ */
+struct nfs_server *nfs_clone_server(struct nfs_server *source,
+				    struct nfs_fh *fh,
+				    struct nfs_fattr *fattr)
+{
+	struct nfs_server *server;
+	struct nfs_fattr fattr_fsinfo;
+	int error;
+
+	dprintk("--> nfs_clone_server(,%llx:%llx,)\n",
+		fattr->fsid.major, fattr->fsid.minor);
+
+	server = nfs_alloc_server();
+	if (!server)
+		return ERR_PTR(-ENOMEM);
+
+	/* Copy data from the source */
+	server->nfs_client = source->nfs_client;
+	atomic_inc(&server->nfs_client->cl_count);
+	nfs_server_copy_userdata(server, source);
+
+	server->fsid = fattr->fsid;
+
+	error = nfs_init_server_rpcclient(server, source->client->cl_auth->au_flavor);
+	if (error < 0)
+		goto out_free_server;
+	if (!IS_ERR(source->client_acl))
+		nfs_init_server_aclclient(server);
+
+	/* probe the filesystem info for this server filesystem */
+	error = nfs_probe_fsinfo(server, fh, &fattr_fsinfo);
+	if (error < 0)
+		goto out_free_server;
+
+	dprintk("Cloned FSID: %llx:%llx\n",
+		server->fsid.major, server->fsid.minor);
+
+	error = nfs_start_lockd(server);
+	if (error < 0)
+		goto out_free_server;
+
+	spin_lock(&nfs_client_lock);
+	list_add_tail(&server->client_link, &server->nfs_client->cl_superblocks);
+	list_add_tail(&server->master_link, &nfs_volume_list);
+	spin_unlock(&nfs_client_lock);
+
+	server->mount_time = jiffies;
+
+	dprintk("<-- nfs_clone_server() = %p\n", server);
+	return server;
+
+out_free_server:
+	nfs_free_server(server);
+	dprintk("<-- nfs_clone_server() = error %d\n", error);
+	return ERR_PTR(error);
+}
+
+#ifdef CONFIG_PROC_FS
+static struct proc_dir_entry *proc_fs_nfs;
+
+static int nfs_server_list_open(struct inode *inode, struct file *file);
+static void *nfs_server_list_start(struct seq_file *p, loff_t *pos);
+static void *nfs_server_list_next(struct seq_file *p, void *v, loff_t *pos);
+static void nfs_server_list_stop(struct seq_file *p, void *v);
+static int nfs_server_list_show(struct seq_file *m, void *v);
+
+static struct seq_operations nfs_server_list_ops = {
+	.start	= nfs_server_list_start,
+	.next	= nfs_server_list_next,
+	.stop	= nfs_server_list_stop,
+	.show	= nfs_server_list_show,
+};
+
+static struct file_operations nfs_server_list_fops = {
+	.open		= nfs_server_list_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= seq_release,
+};
+
+static int nfs_volume_list_open(struct inode *inode, struct file *file);
+static void *nfs_volume_list_start(struct seq_file *p, loff_t *pos);
+static void *nfs_volume_list_next(struct seq_file *p, void *v, loff_t *pos);
+static void nfs_volume_list_stop(struct seq_file *p, void *v);
+static int nfs_volume_list_show(struct seq_file *m, void *v);
+
+static struct seq_operations nfs_volume_list_ops = {
+	.start	= nfs_volume_list_start,
+	.next	= nfs_volume_list_next,
+	.stop	= nfs_volume_list_stop,
+	.show	= nfs_volume_list_show,
+};
+
+static struct file_operations nfs_volume_list_fops = {
+	.open		= nfs_volume_list_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= seq_release,
+};
+
+/*
+ * open "/proc/fs/nfsfs/servers" which provides a summary of servers with which
+ * we're dealing
+ */
+static int nfs_server_list_open(struct inode *inode, struct file *file)
+{
+	struct seq_file *m;
+	int ret;
+
+	ret = seq_open(file, &nfs_server_list_ops);
+	if (ret < 0)
+		return ret;
+
+	m = file->private_data;
+	m->private = PDE(inode)->data;
+
+	return 0;
+}
+
+/*
+ * set up the iterator to start reading from the server list and return the first item
+ */
+static void *nfs_server_list_start(struct seq_file *m, loff_t *_pos)
+{
+	struct list_head *_p;
+	loff_t pos = *_pos;
+
+	/* lock the list against modification */
+	spin_lock(&nfs_client_lock);
+
+	/* allow for the header line */
+	if (!pos)
+		return SEQ_START_TOKEN;
+	pos--;
+
+	/* find the n'th element in the list */
+	list_for_each(_p, &nfs_client_list)
+		if (!pos--)
+			break;
+
+	return _p != &nfs_client_list ? _p : NULL;
+}
+
+/*
+ * move to next server
+ */
+static void *nfs_server_list_next(struct seq_file *p, void *v, loff_t *pos)
+{
+	struct list_head *_p;
+
+	(*pos)++;
+
+	_p = v;
+	_p = (v == SEQ_START_TOKEN) ? nfs_client_list.next : _p->next;
+
+	return _p != &nfs_client_list ? _p : NULL;
+}
+
+/*
+ * clean up after reading from the transports list
+ */
+static void nfs_server_list_stop(struct seq_file *p, void *v)
+{
+	spin_unlock(&nfs_client_lock);
+}
+
+/*
+ * display a header line followed by a load of call lines
+ */
+static int nfs_server_list_show(struct seq_file *m, void *v)
+{
+	struct nfs_client *clp;
+
+	/* display header on line 1 */
+	if (v == SEQ_START_TOKEN) {
+		seq_puts(m, "NV SERVER   PORT USE HOSTNAME\n");
+		return 0;
+	}
+
+	/* display one transport per line on subsequent lines */
+	clp = list_entry(v, struct nfs_client, cl_share_link);
+
+	seq_printf(m, "v%d %02x%02x%02x%02x %4hx %3d %s\n",
+		   clp->cl_nfsversion,
+		   NIPQUAD(clp->cl_addr.sin_addr),
+		   ntohs(clp->cl_addr.sin_port),
+		   atomic_read(&clp->cl_count),
+		   clp->cl_hostname);
+
+	return 0;
+}
+
+/*
+ * open "/proc/fs/nfsfs/volumes" which provides a summary of extant volumes
+ */
+static int nfs_volume_list_open(struct inode *inode, struct file *file)
+{
+	struct seq_file *m;
+	int ret;
+
+	ret = seq_open(file, &nfs_volume_list_ops);
+	if (ret < 0)
+		return ret;
+
+	m = file->private_data;
+	m->private = PDE(inode)->data;
+
+	return 0;
+}
+
+/*
+ * set up the iterator to start reading from the volume list and return the first item
+ */
+static void *nfs_volume_list_start(struct seq_file *m, loff_t *_pos)
+{
+	struct list_head *_p;
+	loff_t pos = *_pos;
+
+	/* lock the list against modification */
+	spin_lock(&nfs_client_lock);
+
+	/* allow for the header line */
+	if (!pos)
+		return SEQ_START_TOKEN;
+	pos--;
+
+	/* find the n'th element in the list */
+	list_for_each(_p, &nfs_volume_list)
+		if (!pos--)
+			break;
+
+	return _p != &nfs_volume_list ? _p : NULL;
+}
+
+/*
+ * move to next volume
+ */
+static void *nfs_volume_list_next(struct seq_file *p, void *v, loff_t *pos)
+{
+	struct list_head *_p;
+
+	(*pos)++;
+
+	_p = v;
+	_p = (v == SEQ_START_TOKEN) ? nfs_volume_list.next : _p->next;
+
+	return _p != &nfs_volume_list ? _p : NULL;
+}
+
+/*
+ * clean up after reading from the transports list
+ */
+static void nfs_volume_list_stop(struct seq_file *p, void *v)
+{
+	spin_unlock(&nfs_client_lock);
+}
+
+/*
+ * display a header line followed by a load of call lines
+ */
+static int nfs_volume_list_show(struct seq_file *m, void *v)
+{
+	struct nfs_server *server;
+	struct nfs_client *clp;
+	char dev[8], fsid[17];
+
+	/* display header on line 1 */
+	if (v == SEQ_START_TOKEN) {
+		seq_puts(m, "NV SERVER   PORT DEV     FSID              FSC\n");
+		return 0;
+	}
+	/* display one transport per line on subsequent lines */
+	server = list_entry(v, struct nfs_server, master_link);
+	clp = server->nfs_client;
+
+	snprintf(dev, 8, "%u:%u",
+		 MAJOR(server->s_dev), MINOR(server->s_dev));
+
+	snprintf(fsid, 17, "%llx:%llx",
+		 server->fsid.major, server->fsid.minor);
+
+	seq_printf(m, "v%d %02x%02x%02x%02x %4hx %-7s %-17s %s\n",
+		   clp->cl_nfsversion,
+		   NIPQUAD(clp->cl_addr.sin_addr),
+		   ntohs(clp->cl_addr.sin_port),
+		   dev,
+		   fsid,
+		   nfs_server_fscache_state(server));
+
+	return 0;
+}
+
+/*
+ * initialise the /proc/fs/nfsfs/ directory
+ */
+int __init nfs_fs_proc_init(void)
+{
+	struct proc_dir_entry *p;
+
+	proc_fs_nfs = proc_mkdir("nfsfs", proc_root_fs);
+	if (!proc_fs_nfs)
+		goto error_0;
+
+	proc_fs_nfs->owner = THIS_MODULE;
+
+	/* a file of servers with which we're dealing */
+	p = create_proc_entry("servers", S_IFREG|S_IRUGO, proc_fs_nfs);
+	if (!p)
+		goto error_1;
+
+	p->proc_fops = &nfs_server_list_fops;
+	p->owner = THIS_MODULE;
+
+	/* a file of volumes that we have mounted */
+	p = create_proc_entry("volumes", S_IFREG|S_IRUGO, proc_fs_nfs);
+	if (!p)
+		goto error_2;
+
+	p->proc_fops = &nfs_volume_list_fops;
+	p->owner = THIS_MODULE;
+	return 0;
+
+error_2:
+	remove_proc_entry("servers", proc_fs_nfs);
+error_1:
+	remove_proc_entry("nfsfs", proc_root_fs);
+error_0:
+	return -ENOMEM;
+}
+
+/*
+ * clean up the /proc/fs/nfsfs/ directory
+ */
+void nfs_fs_proc_exit(void)
+{
+	remove_proc_entry("volumes", proc_fs_nfs);
+	remove_proc_entry("servers", proc_fs_nfs);
+	remove_proc_entry("nfsfs", proc_root_fs);
+}
+
+#endif /* CONFIG_PROC_FS */
diff --git a/fs/nfs/fscache.c b/fs/nfs/fscache.c
new file mode 100644
index 000000000..0949bacdb
--- /dev/null
+++ b/fs/nfs/fscache.c
@@ -0,0 +1,345 @@
+/* fscache.c: NFS filesystem cache interface
+ *
+ * Copyright (C) 2006 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@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.
+ */
+
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/nfs_fs.h>
+#include <linux/nfs_fs_sb.h>
+#include <linux/in6.h>
+
+#include "internal.h"
+
+/*
+ * Sysctl variables
+ */
+atomic_t nfs_fscache_to_pages;
+atomic_t nfs_fscache_from_pages;
+atomic_t nfs_fscache_uncache_page;
+int nfs_fscache_from_error;
+int nfs_fscache_to_error;
+
+#define NFSDBG_FACILITY		NFSDBG_FSCACHE
+
+/* the auxiliary data in the cache (used for coherency management) */
+struct nfs_fh_auxdata {
+	struct timespec	i_mtime;
+	struct timespec	i_ctime;
+	loff_t		i_size;
+};
+
+static struct fscache_netfs_operations nfs_cache_ops = {
+};
+
+struct fscache_netfs nfs_cache_netfs = {
+	.name			= "nfs",
+	.version		= 0,
+	.ops			= &nfs_cache_ops,
+};
+
+static const uint8_t nfs_cache_ipv6_wrapper_for_ipv4[12] = {
+	[0 ... 9]	= 0x00,
+	[10 ... 11]	= 0xff
+};
+
+struct nfs_server_key {
+	uint16_t nfsversion;
+	uint16_t port;
+	union {
+		struct {
+			uint8_t		ipv6wrapper[12];
+			struct in_addr	addr;
+		} ipv4_addr;
+		struct in6_addr ipv6_addr;
+	};
+};
+
+static uint16_t nfs_server_get_key(const void *cookie_netfs_data,
+				   void *buffer, uint16_t bufmax)
+{
+	const struct nfs_client *clp = cookie_netfs_data;
+	struct nfs_server_key *key = buffer;
+	uint16_t len = 0;
+
+	key->nfsversion = clp->cl_nfsversion;
+
+	switch (clp->cl_addr.sin_family) {
+	case AF_INET:
+		key->port = clp->cl_addr.sin_port;
+
+		memcpy(&key->ipv4_addr.ipv6wrapper,
+		       &nfs_cache_ipv6_wrapper_for_ipv4,
+		       sizeof(key->ipv4_addr.ipv6wrapper));
+		memcpy(&key->ipv4_addr.addr,
+		       &clp->cl_addr.sin_addr,
+		       sizeof(key->ipv4_addr.addr));
+		len = sizeof(struct nfs_server_key);
+		break;
+
+	case AF_INET6:
+		key->port = clp->cl_addr.sin_port;
+
+		memcpy(&key->ipv6_addr,
+		       &clp->cl_addr.sin_addr,
+		       sizeof(key->ipv6_addr));
+		len = sizeof(struct nfs_server_key);
+		break;
+
+	default:
+		len = 0;
+		printk(KERN_WARNING "NFS: Unknown network family '%d'\n",
+			clp->cl_addr.sin_family);
+		break;
+	}
+
+	return len;
+}
+
+/*
+ * the root index for the filesystem is defined by nfsd IP address and ports
+ */
+struct fscache_cookie_def nfs_cache_server_index_def = {
+	.name		= "NFS.servers",
+	.type 		= FSCACHE_COOKIE_TYPE_INDEX,
+	.get_key	= nfs_server_get_key,
+};
+
+static uint16_t nfs_fh_get_key(const void *cookie_netfs_data,
+		void *buffer, uint16_t bufmax)
+{
+	const struct nfs_inode *nfsi = cookie_netfs_data;
+	uint16_t nsize;
+
+	/* set the file handle */
+	nsize = nfsi->fh.size;
+	memcpy(buffer, nfsi->fh.data, nsize);
+	return nsize;
+}
+
+/*
+ * indication of pages that now have cache metadata retained
+ * - this function should mark the specified pages as now being cached
+ */
+static void nfs_fh_mark_pages_cached(void *cookie_netfs_data,
+				     struct address_space *mapping,
+				     struct pagevec *cached_pvec)
+{
+	struct nfs_inode *nfsi = cookie_netfs_data;
+	unsigned long loop;
+
+	dprintk("NFS: nfs_fh_mark_pages_cached: nfs_inode 0x%p pages %ld\n",
+		nfsi, cached_pvec->nr);
+
+	for (loop = 0; loop < cached_pvec->nr; loop++)
+		SetPageNfsCached(cached_pvec->pages[loop]);
+}
+
+/*
+ * get an extra reference on a read context
+ * - this function can be absent if the completion function doesn't
+ *   require a context
+ */
+static void nfs_fh_get_context(void *cookie_netfs_data, void *context)
+{
+	get_nfs_open_context(context);
+}
+
+/*
+ * release an extra reference on a read context
+ * - this function can be absent if the completion function doesn't
+ *   require a context
+ */
+static void nfs_fh_put_context(void *cookie_netfs_data, void *context)
+{
+	if (context)
+		put_nfs_open_context(context);
+}
+
+/*
+ * indication the cookie is no longer uncached
+ * - this function is called when the backing store currently caching a cookie
+ *   is removed
+ * - the netfs should use this to clean up any markers indicating cached pages
+ * - this is mandatory for any object that may have data
+ */
+static void nfs_fh_now_uncached(void *cookie_netfs_data)
+{
+	struct nfs_inode *nfsi = cookie_netfs_data;
+	struct pagevec pvec;
+	pgoff_t first;
+	int loop, nr_pages;
+
+	pagevec_init(&pvec, 0);
+	first = 0;
+
+	dprintk("NFS: nfs_fh_now_uncached: nfs_inode 0x%p\n", nfsi);
+
+	for (;;) {
+		/* grab a bunch of pages to clean */
+		nr_pages = pagevec_lookup(&pvec,
+					  nfsi->vfs_inode.i_mapping,
+					  first,
+					  PAGEVEC_SIZE - pagevec_count(&pvec));
+		if (!nr_pages)
+			break;
+
+		for (loop = 0; loop < nr_pages; loop++)
+			ClearPageNfsCached(pvec.pages[loop]);
+
+		first = pvec.pages[nr_pages - 1]->index + 1;
+
+		pvec.nr = nr_pages;
+		pagevec_release(&pvec);
+		cond_resched();
+	}
+}
+
+/*
+ * get certain file attributes from the netfs data
+ * - this function can be absent for an index
+ * - not permitted to return an error
+ * - the netfs data from the cookie being used as the source is
+ *   presented
+ */
+static void nfs_fh_get_attr(const void *cookie_netfs_data, uint64_t *size)
+{
+	const struct nfs_inode *nfsi = cookie_netfs_data;
+
+	*size = nfsi->vfs_inode.i_size;
+}
+
+/*
+ * get the auxilliary data from netfs data
+ * - this function can be absent if the index carries no state data
+ * - should store the auxilliary data in the buffer
+ * - should return the amount of amount stored
+ * - not permitted to return an error
+ * - the netfs data from the cookie being used as the source is
+ *   presented
+ */
+static uint16_t nfs_fh_get_aux(const void *cookie_netfs_data,
+			       void *buffer, uint16_t bufmax)
+{
+	struct nfs_fh_auxdata auxdata;
+	const struct nfs_inode *nfsi = cookie_netfs_data;
+
+	auxdata.i_size = nfsi->vfs_inode.i_size;
+	auxdata.i_mtime = nfsi->vfs_inode.i_mtime;
+	auxdata.i_ctime = nfsi->vfs_inode.i_ctime;
+
+	if (bufmax > sizeof(auxdata))
+		bufmax = sizeof(auxdata);
+
+	memcpy(buffer, &auxdata, bufmax);
+	return bufmax;
+}
+
+/*
+ * consult the netfs about the state of an object
+ * - this function can be absent if the index carries no state data
+ * - the netfs data from the cookie being used as the target is
+ *   presented, as is the auxilliary data
+ */
+static fscache_checkaux_t nfs_fh_check_aux(void *cookie_netfs_data,
+					   const void *data, uint16_t datalen)
+{
+	struct nfs_fh_auxdata auxdata;
+	struct nfs_inode *nfsi = cookie_netfs_data;
+
+	if (datalen > sizeof(auxdata))
+		return FSCACHE_CHECKAUX_OBSOLETE;
+
+	auxdata.i_size = nfsi->vfs_inode.i_size;
+	auxdata.i_mtime = nfsi->vfs_inode.i_mtime;
+	auxdata.i_ctime = nfsi->vfs_inode.i_ctime;
+
+	if (memcmp(data, &auxdata, datalen) != 0)
+		return FSCACHE_CHECKAUX_OBSOLETE;
+
+	return FSCACHE_CHECKAUX_OKAY;
+}
+
+/*
+ * the primary index for each server is simply made up of a series of NFS file
+ * handles
+ */
+struct fscache_cookie_def nfs_cache_fh_index_def = {
+	.name			= "NFS.fh",
+	.type			= FSCACHE_COOKIE_TYPE_DATAFILE,
+	.get_key		= nfs_fh_get_key,
+	.get_attr		= nfs_fh_get_attr,
+	.get_aux		= nfs_fh_get_aux,
+	.check_aux		= nfs_fh_check_aux,
+	.get_context		= nfs_fh_get_context,
+	.put_context		= nfs_fh_put_context,
+	.mark_pages_cached	= nfs_fh_mark_pages_cached,
+	.now_uncached		= nfs_fh_now_uncached,
+};
+
+static int nfs_file_page_mkwrite(struct vm_area_struct *vma, struct page *page)
+{
+	wait_on_page_fs_misc(page);
+	return 0;
+}
+
+struct vm_operations_struct nfs_fs_vm_operations = {
+	.nopage		= filemap_nopage,
+	.populate	= filemap_populate,
+	.page_mkwrite	= nfs_file_page_mkwrite,
+};
+
+/*
+ * handle completion of a page being stored in the cache
+ */
+void nfs_readpage_to_fscache_complete(struct page *page, void *data, int error)
+{
+	dfprintk(FSCACHE,
+		"NFS:     readpage_to_fscache_complete (p:%p(i:%lx f:%lx)/%d)\n",
+		page, page->index, page->flags, error);
+
+	end_page_fs_misc(page);
+}
+
+/*
+ * handle completion of a page being read from the cache
+ * - called in process (keventd) context
+ */
+void nfs_readpage_from_fscache_complete(struct page *page,
+					void *context,
+					int error)
+{
+	dfprintk(FSCACHE,
+		 "NFS: readpage_from_fscache_complete (0x%p/0x%p/%d)\n",
+		 page, context, error);
+
+	/* if the read completes with an error, we just unlock the page and let
+	 * the VM reissue the readpage */
+	if (!error) {
+		SetPageUptodate(page);
+		unlock_page(page);
+	} else {
+		error = nfs_readpage_async(context, page->mapping->host, page);
+		if (error)
+			unlock_page(page);
+	}
+}
+
+/*
+ * handle completion of a page being read from the cache
+ * - really need to synchronise the end of writeback, probably using a page
+ *   flag, but for the moment we disable caching on writable files
+ */
+void nfs_writepage_to_fscache_complete(struct page *page,
+				       void *data,
+				       int error)
+{
+}
diff --git a/fs/nfs/fscache.h b/fs/nfs/fscache.h
new file mode 100644
index 000000000..69f0f4041
--- /dev/null
+++ b/fs/nfs/fscache.h
@@ -0,0 +1,466 @@
+/* fscache.h: NFS filesystem cache interface definitions
+ *
+ * Copyright (C) 2006 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@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.
+ */
+
+#ifndef _NFS_FSCACHE_H
+#define _NFS_FSCACHE_H
+
+#include <linux/nfs_fs.h>
+#include <linux/nfs_mount.h>
+#include <linux/nfs4_mount.h>
+
+#ifdef CONFIG_NFS_FSCACHE
+#include <linux/fscache.h>
+
+extern struct fscache_netfs nfs_cache_netfs;
+extern struct fscache_cookie_def nfs_cache_server_index_def;
+extern struct fscache_cookie_def nfs_cache_fh_index_def;
+extern struct vm_operations_struct nfs_fs_vm_operations;
+
+extern void nfs_invalidatepage(struct page *, unsigned long);
+extern int nfs_releasepage(struct page *, gfp_t);
+
+extern atomic_t nfs_fscache_to_pages;
+extern atomic_t nfs_fscache_from_pages;
+extern atomic_t nfs_fscache_uncache_page;
+extern int nfs_fscache_from_error;
+extern int nfs_fscache_to_error;
+
+/*
+ * register NFS for caching
+ */
+static inline int nfs_fscache_register(void)
+{
+	return fscache_register_netfs(&nfs_cache_netfs);
+}
+
+/*
+ * unregister NFS for caching
+ */
+static inline void nfs_fscache_unregister(void)
+{
+	fscache_unregister_netfs(&nfs_cache_netfs);
+}
+
+/*
+ * get the per-client index cookie for an NFS client if the appropriate mount
+ * flag was set
+ * - we always try and get an index cookie for the client, but get filehandle
+ *   cookies on a per-superblock basis, depending on the mount flags
+ */
+static inline void nfs_fscache_get_client_cookie(struct nfs_client *clp)
+{
+	/* create a cache index for looking up filehandles */
+	clp->fscache = fscache_acquire_cookie(nfs_cache_netfs.primary_index,
+					      &nfs_cache_server_index_def,
+					      clp);
+	dfprintk(FSCACHE,"NFS: get client cookie (0x%p/0x%p)\n",
+		 clp, clp->fscache);
+}
+
+/*
+ * dispose of a per-client cookie
+ */
+static inline void nfs_fscache_release_client_cookie(struct nfs_client *clp)
+{
+	dfprintk(FSCACHE,"NFS: releasing client cookie (0x%p/0x%p)\n",
+		clp, clp->fscache);
+
+	fscache_relinquish_cookie(clp->fscache, 0);
+	clp->fscache = NULL;
+}
+
+/*
+ * indicate the client caching state as readable text
+ */
+static inline const char *nfs_server_fscache_state(struct nfs_server *server)
+{
+	if (server->nfs_client->fscache && (server->flags & NFS_MOUNT_FSCACHE))
+		return "yes";
+	return "no ";
+}
+
+/*
+ * get the per-filehandle cookie for an NFS inode
+ */
+static inline void nfs_fscache_get_fh_cookie(struct super_block *sb,
+					     struct nfs_inode *nfsi,
+					     int maycache)
+{
+	nfsi->fscache = NULL;
+	if (maycache && (NFS_SB(sb)->flags & NFS_MOUNT_FSCACHE)) {
+		nfsi->fscache = fscache_acquire_cookie(
+			NFS_SB(sb)->nfs_client->fscache,
+			&nfs_cache_fh_index_def,
+			nfsi);
+
+		fscache_set_i_size(nfsi->fscache, nfsi->vfs_inode.i_size);
+
+		dfprintk(FSCACHE, "NFS: get FH cookie (0x%p/0x%p/0x%p)\n",
+			 sb, nfsi, nfsi->fscache);
+	}
+}
+
+/*
+ * change the filesize associated with a per-filehandle cookie
+ */
+static inline void nfs_fscache_set_size(struct nfs_server *server,
+					struct nfs_inode *nfsi,
+					loff_t i_size)
+{
+	fscache_set_i_size(nfsi->fscache, i_size);
+}
+
+/*
+ * replace a per-filehandle cookie due to revalidation detecting a file having
+ * changed on the server
+ */
+static inline void nfs_fscache_renew_fh_cookie(struct nfs_server *server,
+					       struct nfs_inode *nfsi)
+{
+	struct fscache_cookie *old = nfsi->fscache;
+
+	if (nfsi->fscache) {
+		/* retire the current fscache cache and get a new one */
+		fscache_relinquish_cookie(nfsi->fscache, 1);
+
+		nfsi->fscache = fscache_acquire_cookie(
+			server->nfs_client->fscache,
+			&nfs_cache_fh_index_def,
+			nfsi);
+		fscache_set_i_size(nfsi->fscache, nfsi->vfs_inode.i_size);
+
+		dfprintk(FSCACHE,
+			 "NFS: revalidation new cookie (0x%p/0x%p/0x%p/0x%p)\n",
+			 server, nfsi, old, nfsi->fscache);
+	}
+}
+
+/*
+ * release a per-filehandle cookie
+ */
+static inline void nfs_fscache_release_fh_cookie(struct nfs_server *server,
+						 struct nfs_inode *nfsi)
+{
+	dfprintk(FSCACHE, "NFS: clear cookie (0x%p/0x%p)\n",
+		 nfsi, nfsi->fscache);
+
+	fscache_relinquish_cookie(nfsi->fscache, 0);
+	nfsi->fscache = NULL;
+}
+
+/*
+ * retire a per-filehandle cookie, destroying the data attached to it
+ */
+static inline void nfs_fscache_zap_fh_cookie(struct nfs_server *server,
+					     struct nfs_inode *nfsi)
+{
+	dfprintk(FSCACHE,"NFS: zapping cookie (0x%p/0x%p)\n",
+		nfsi, nfsi->fscache);
+
+	fscache_relinquish_cookie(nfsi->fscache, 1);
+	nfsi->fscache = NULL;
+}
+
+/*
+ * turn off the cache with regard to a filehandle cookie if opened for writing,
+ * invalidating all the pages in the page cache relating to the associated
+ * inode to clear the per-page caching
+ */
+static inline void nfs_fscache_disable_fh_cookie(struct inode *inode)
+{
+	if (NFS_I(inode)->fscache) {
+		dfprintk(FSCACHE,
+			 "NFS: nfsi 0x%p turning cache off\n", NFS_I(inode));
+
+		/* Need to invalided any mapped pages that were read in before
+		 * turning off the cache.
+		 */
+		if (inode->i_mapping && inode->i_mapping->nrpages)
+			invalidate_inode_pages2(inode->i_mapping);
+
+		nfs_fscache_zap_fh_cookie(NFS_SERVER(inode), NFS_I(inode));
+	}
+}
+
+/*
+ * install the VM ops for mmap() of an NFS file so that we can hold up writes
+ * to pages on shared writable mappings until the store to the cache is
+ * complete
+ */
+static inline void nfs_fscache_install_vm_ops(struct inode *inode,
+					      struct vm_area_struct *vma)
+{
+	if (NFS_I(inode)->fscache)
+		vma->vm_ops = &nfs_fs_vm_operations;
+}
+
+/*
+ * release the caching state associated with a page
+ */
+static void nfs_fscache_release_page(struct page *page)
+{
+	if (PageNfsCached(page)) {
+		struct nfs_inode *nfsi = NFS_I(page->mapping->host);
+
+		BUG_ON(nfsi->fscache == NULL);
+
+		dfprintk(FSCACHE, "NFS: fscache releasepage (0x%p/0x%p/0x%p)\n",
+			 nfsi->fscache, page, nfsi);
+
+		wait_on_page_fs_misc(page);
+		fscache_uncache_page(nfsi->fscache, page);
+		atomic_inc(&nfs_fscache_uncache_page);
+		ClearPageNfsCached(page);
+	}
+}
+
+/*
+ * release the caching state associated with a page if undergoing complete page
+ * invalidation
+ */
+static inline void nfs_fscache_invalidate_page(struct page *page,
+					       struct inode *inode,
+					       unsigned long offset)
+{
+	if (PageNfsCached(page)) {
+		struct nfs_inode *nfsi = NFS_I(page->mapping->host);
+
+		BUG_ON(!nfsi->fscache);
+
+		dfprintk(FSCACHE,
+			 "NFS: fscache invalidatepage (0x%p/0x%p/0x%p)\n",
+			 nfsi->fscache, page, nfsi);
+
+		if (offset == 0) {
+			BUG_ON(!PageLocked(page));
+			if (!PageWriteback(page))
+				nfs_fscache_release_page(page);
+		}
+	}
+}
+
+/*
+ * store a newly fetched page in fscache
+ */
+extern void nfs_readpage_to_fscache_complete(struct page *, void *, int);
+
+static inline void nfs_readpage_to_fscache(struct inode *inode,
+					   struct page *page,
+					   int sync)
+{
+	int ret;
+
+	if (PageNfsCached(page)) {
+		dfprintk(FSCACHE,
+			 "NFS: "
+			 "readpage_to_fscache(fsc:%p/p:%p(i:%lx f:%lx)/%d)\n",
+			 NFS_I(inode)->fscache, page, page->index, page->flags,
+			 sync);
+
+		if (TestSetPageFsMisc(page))
+			BUG();
+
+		ret = fscache_write_page(NFS_I(inode)->fscache, page,
+					 nfs_readpage_to_fscache_complete,
+					 NULL, GFP_KERNEL);
+		dfprintk(FSCACHE,
+			 "NFS:     "
+			 "readpage_to_fscache: p:%p(i:%lu f:%lx) ret %d\n",
+			 page, page->index, page->flags, ret);
+
+		if (ret != 0) {
+			fscache_uncache_page(NFS_I(inode)->fscache, page);
+			atomic_inc(&nfs_fscache_uncache_page);
+			ClearPageNfsCached(page);
+			end_page_fs_misc(page);
+			nfs_fscache_to_error = ret;
+		} else {
+			atomic_inc(&nfs_fscache_to_pages);
+		}
+	}
+}
+
+/*
+ * retrieve a page from fscache
+ */
+extern void nfs_readpage_from_fscache_complete(struct page *, void *, int);
+
+static inline
+int nfs_readpage_from_fscache(struct nfs_open_context *ctx,
+			      struct inode *inode,
+			      struct page *page)
+{
+	int ret;
+
+	if (!NFS_I(inode)->fscache)
+		return 1;
+
+	dfprintk(FSCACHE,
+		 "NFS: readpage_from_fscache(fsc:%p/p:%p(i:%lx f:%lx)/0x%p)\n",
+		 NFS_I(inode)->fscache, page, page->index, page->flags, inode);
+
+	ret = fscache_read_or_alloc_page(NFS_I(inode)->fscache,
+					 page,
+					 nfs_readpage_from_fscache_complete,
+					 ctx,
+					 GFP_KERNEL);
+
+	switch (ret) {
+	case 0: /* read BIO submitted (page in fscache) */
+		dfprintk(FSCACHE,
+			 "NFS:    readpage_from_fscache: BIO submitted\n");
+		atomic_inc(&nfs_fscache_from_pages);
+		return ret;
+
+	case -ENOBUFS: /* inode not in cache */
+	case -ENODATA: /* page not in cache */
+		dfprintk(FSCACHE,
+			 "NFS:    readpage_from_fscache error %d\n", ret);
+		return 1;
+
+	default:
+		dfprintk(FSCACHE, "NFS:    readpage_from_fscache %d\n", ret);
+		nfs_fscache_from_error = ret;
+	}
+	return ret;
+}
+
+/*
+ * retrieve a set of pages from fscache
+ */
+static inline int nfs_readpages_from_fscache(struct nfs_open_context *ctx,
+					     struct inode *inode,
+					     struct address_space *mapping,
+					     struct list_head *pages,
+					     unsigned *nr_pages)
+{
+	int ret, npages = *nr_pages;
+
+	if (!NFS_I(inode)->fscache)
+		return 1;
+
+	dfprintk(FSCACHE,
+		 "NFS: nfs_getpages_from_fscache (0x%p/%u/0x%p)\n",
+		 NFS_I(inode)->fscache, *nr_pages, inode);
+
+	ret = fscache_read_or_alloc_pages(NFS_I(inode)->fscache,
+					  mapping, pages, nr_pages,
+					  nfs_readpage_from_fscache_complete,
+					  ctx,
+					  mapping_gfp_mask(mapping));
+
+
+	switch (ret) {
+	case 0: /* read BIO submitted (page in fscache) */
+		BUG_ON(!list_empty(pages));
+		BUG_ON(*nr_pages != 0);
+		dfprintk(FSCACHE,
+			 "NFS: nfs_getpages_from_fscache: BIO submitted\n");
+
+		atomic_add(npages, &nfs_fscache_from_pages);
+		return ret;
+
+	case -ENOBUFS: /* inode not in cache */
+	case -ENODATA: /* page not in cache */
+		dfprintk(FSCACHE,
+			 "NFS: nfs_getpages_from_fscache: no page: %d\n", ret);
+		return 1;
+
+	default:
+		dfprintk(FSCACHE,
+			 "NFS: nfs_getpages_from_fscache: ret  %d\n", ret);
+		nfs_fscache_from_error = ret;
+	}
+
+	return ret;
+}
+
+/*
+ * store an updated page in fscache
+ */
+extern void nfs_writepage_to_fscache_complete(struct page *page, void *data, int error);
+
+static inline void nfs_writepage_to_fscache(struct inode *inode,
+					    struct page *page)
+{
+	int error;
+
+	if (PageNfsCached(page) && NFS_I(inode)->fscache) {
+		dfprintk(FSCACHE,
+			 "NFS: writepage_to_fscache (0x%p/0x%p/0x%p)\n",
+			 NFS_I(inode)->fscache, page, inode);
+
+		error = fscache_write_page(NFS_I(inode)->fscache, page,
+					   nfs_writepage_to_fscache_complete,
+					   NULL, GFP_KERNEL);
+		if (error != 0) {
+			dfprintk(FSCACHE,
+				 "NFS:    fscache_write_page error %d\n",
+				 error);
+			fscache_uncache_page(NFS_I(inode)->fscache, page);
+		}
+	}
+}
+
+#else /* CONFIG_NFS_FSCACHE */
+static inline int nfs_fscache_register(void) { return 0; }
+static inline void nfs_fscache_unregister(void) {}
+static inline void nfs_fscache_get_client_cookie(struct nfs_client *clp) {}
+static inline void nfs4_fscache_get_client_cookie(struct nfs_client *clp) {}
+static inline void nfs_fscache_release_client_cookie(struct nfs_client *clp) {}
+static inline const char *nfs_server_fscache_state(struct nfs_server *server) { return "no "; }
+
+static inline void nfs_fscache_get_fh_cookie(struct super_block *sb,
+					     struct nfs_inode *nfsi,
+					     int maycache)
+{
+}
+static inline void nfs_fscache_set_size(struct nfs_server *server,
+					struct nfs_inode *nfsi,
+					loff_t i_size)
+{
+}
+static inline void nfs_fscache_release_fh_cookie(struct nfs_server *server,
+						 struct nfs_inode *nfsi)
+{
+}
+static inline void nfs_fscache_zap_fh_cookie(struct nfs_server *server, struct nfs_inode *nfsi) {}
+static inline void nfs_fscache_renew_fh_cookie(struct nfs_server *server, struct nfs_inode *nfsi) {}
+static inline void nfs_fscache_disable_fh_cookie(struct inode *inode) {}
+static inline void nfs_fscache_install_vm_ops(struct inode *inode, struct vm_area_struct *vma) {}
+static inline void nfs_fscache_release_page(struct page *page) {}
+static inline void nfs_fscache_invalidate_page(struct page *page,
+					       struct inode *inode,
+					       unsigned long offset)
+{
+}
+static inline void nfs_readpage_to_fscache(struct inode *inode, struct page *page, int sync) {}
+static inline int nfs_readpage_from_fscache(struct nfs_open_context *ctx,
+					    struct inode *inode, struct page *page)
+{
+	return -ENOBUFS;
+}
+static inline int nfs_readpages_from_fscache(struct nfs_open_context *ctx,
+					     struct inode *inode,
+					     struct address_space *mapping,
+					     struct list_head *pages,
+					     unsigned *nr_pages)
+{
+	return -ENOBUFS;
+}
+
+static inline void nfs_writepage_to_fscache(struct inode *inode, struct page *page)
+{
+	BUG_ON(PageNfsCached(page));
+}
+
+#endif /* CONFIG_NFS_FSCACHE */
+#endif /* _NFS_FSCACHE_H */
diff --git a/fs/nfs/getroot.c b/fs/nfs/getroot.c
new file mode 100644
index 000000000..20c6f39ea
--- /dev/null
+++ b/fs/nfs/getroot.c
@@ -0,0 +1,310 @@
+/* getroot.c: get the root dentry for an NFS mount
+ *
+ * Copyright (C) 2006 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@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.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+
+#include <linux/time.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/string.h>
+#include <linux/stat.h>
+#include <linux/errno.h>
+#include <linux/unistd.h>
+#include <linux/sunrpc/clnt.h>
+#include <linux/sunrpc/stats.h>
+#include <linux/nfs_fs.h>
+#include <linux/nfs_mount.h>
+#include <linux/nfs4_mount.h>
+#include <linux/lockd/bind.h>
+#include <linux/smp_lock.h>
+#include <linux/seq_file.h>
+#include <linux/mount.h>
+#include <linux/nfs_idmap.h>
+#include <linux/vfs.h>
+#include <linux/namei.h>
+#include <linux/namespace.h>
+#include <linux/security.h>
+
+#include <asm/system.h>
+#include <asm/uaccess.h>
+
+#include "nfs4_fs.h"
+#include "delegation.h"
+#include "internal.h"
+
+#define NFSDBG_FACILITY		NFSDBG_CLIENT
+#define NFS_PARANOIA 1
+
+/*
+ * get an NFS2/NFS3 root dentry from the root filehandle
+ */
+struct dentry *nfs_get_root(struct super_block *sb, struct nfs_fh *mntfh)
+{
+	struct nfs_server *server = NFS_SB(sb);
+	struct nfs_fsinfo fsinfo;
+	struct nfs_fattr fattr;
+	struct dentry *mntroot;
+	struct inode *inode;
+	int error;
+
+	/* create a dummy root dentry with dummy inode for this superblock */
+	if (!sb->s_root) {
+		struct nfs_fh dummyfh;
+		struct dentry *root;
+		struct inode *iroot;
+
+		memset(&dummyfh, 0, sizeof(dummyfh));
+		memset(&fattr, 0, sizeof(fattr));
+		nfs_fattr_init(&fattr);
+		fattr.valid = NFS_ATTR_FATTR;
+		fattr.type = NFDIR;
+		fattr.mode = S_IFDIR | S_IRUSR | S_IWUSR;
+		fattr.nlink = 2;
+
+		iroot = nfs_fhget(sb, &dummyfh, &fattr);
+		if (IS_ERR(iroot))
+			return ERR_PTR(PTR_ERR(iroot));
+
+		root = d_alloc_root(iroot);
+		if (!root) {
+			iput(iroot);
+			return ERR_PTR(-ENOMEM);
+		}
+
+		sb->s_root = root;
+	}
+
+	/* get the actual root for this mount */
+	fsinfo.fattr = &fattr;
+
+	error = server->nfs_client->rpc_ops->getroot(server, mntfh, &fsinfo);
+	if (error < 0) {
+		dprintk("nfs_get_root: getattr error = %d\n", -error);
+		return ERR_PTR(error);
+	}
+
+	inode = nfs_fhget(sb, mntfh, fsinfo.fattr);
+	if (IS_ERR(inode)) {
+		dprintk("nfs_get_root: get root inode failed\n");
+		return ERR_PTR(PTR_ERR(inode));
+	}
+
+	/* root dentries normally start off anonymous and get spliced in later
+	 * if the dentry tree reaches them; however if the dentry already
+	 * exists, we'll pick it up at this point and use it as the root
+	 */
+	mntroot = d_alloc_anon(inode);
+	if (!mntroot) {
+		iput(inode);
+		dprintk("nfs_get_root: get root dentry failed\n");
+		return ERR_PTR(-ENOMEM);
+	}
+
+	security_d_instantiate(mntroot, inode);
+
+	if (!mntroot->d_op)
+		mntroot->d_op = server->nfs_client->rpc_ops->dentry_ops;
+
+	return mntroot;
+}
+
+#ifdef CONFIG_NFS_V4
+
+/*
+ * Do a simple pathwalk from the root FH of the server to the nominated target
+ * of the mountpoint
+ * - give error on symlinks
+ * - give error on ".." occurring in the path
+ * - follow traversals
+ */
+int nfs4_path_walk(struct nfs_server *server,
+		   struct nfs_fh *mntfh,
+		   const char *path)
+{
+	struct nfs_fsinfo fsinfo;
+	struct nfs_fattr fattr;
+	struct nfs_fh lastfh;
+	struct qstr name;
+	int ret;
+	//int referral_count = 0;
+
+	dprintk("--> nfs4_path_walk(,,%s)\n", path);
+
+	fsinfo.fattr = &fattr;
+	nfs_fattr_init(&fattr);
+
+	if (*path++ != '/') {
+		dprintk("nfs4_get_root: Path does not begin with a slash\n");
+		return -EINVAL;
+	}
+
+	/* Start by getting the root filehandle from the server */
+	ret = server->nfs_client->rpc_ops->getroot(server, mntfh, &fsinfo);
+	if (ret < 0) {
+		dprintk("nfs4_get_root: getroot error = %d\n", -ret);
+		return ret;
+	}
+
+	if (fattr.type != NFDIR) {
+		printk(KERN_ERR "nfs4_get_root:"
+		       " getroot encountered non-directory\n");
+		return -ENOTDIR;
+	}
+
+	if (fattr.valid & NFS_ATTR_FATTR_V4_REFERRAL) {
+		printk(KERN_ERR "nfs4_get_root:"
+		       " getroot obtained referral\n");
+		return -EREMOTE;
+	}
+
+next_component:
+	dprintk("Next: %s\n", path);
+
+	/* extract the next bit of the path */
+	if (!*path)
+		goto path_walk_complete;
+
+	name.name = path;
+	while (*path && *path != '/')
+		path++;
+	name.len = path - (const char *) name.name;
+
+eat_dot_dir:
+	while (*path == '/')
+		path++;
+
+	if (path[0] == '.' && (path[1] == '/' || !path[1])) {
+		path += 2;
+		goto eat_dot_dir;
+	}
+
+	if (path[0] == '.' && path[1] == '.' && (path[2] == '/' || !path[2])
+	    ) {
+		printk(KERN_ERR "nfs4_get_root:"
+		       " Mount path contains reference to \"..\"\n");
+		return -EINVAL;
+	}
+
+	/* lookup the next FH in the sequence */
+	memcpy(&lastfh, mntfh, sizeof(lastfh));
+
+	dprintk("LookupFH: %*.*s [%s]\n", name.len, name.len, name.name, path);
+
+	ret = server->nfs_client->rpc_ops->lookupfh(server, &lastfh, &name,
+						    mntfh, &fattr);
+	if (ret < 0) {
+		dprintk("nfs4_get_root: getroot error = %d\n", -ret);
+		return ret;
+	}
+
+	if (fattr.type != NFDIR) {
+		printk(KERN_ERR "nfs4_get_root:"
+		       " lookupfh encountered non-directory\n");
+		return -ENOTDIR;
+	}
+
+	if (fattr.valid & NFS_ATTR_FATTR_V4_REFERRAL) {
+		printk(KERN_ERR "nfs4_get_root:"
+		       " lookupfh obtained referral\n");
+		return -EREMOTE;
+	}
+
+	goto next_component;
+
+path_walk_complete:
+	memcpy(&server->fsid, &fattr.fsid, sizeof(server->fsid));
+	dprintk("<-- nfs4_path_walk() = 0\n");
+	return 0;
+}
+
+/*
+ * get an NFS4 root dentry from the root filehandle
+ */
+struct dentry *nfs4_get_root(struct super_block *sb, struct nfs_fh *mntfh)
+{
+	struct nfs_server *server = NFS_SB(sb);
+	struct nfs_fattr fattr;
+	struct dentry *mntroot;
+	struct inode *inode;
+	int error;
+
+	dprintk("--> nfs4_get_root()\n");
+
+	/* create a dummy root dentry with dummy inode for this superblock */
+	if (!sb->s_root) {
+		struct nfs_fh dummyfh;
+		struct dentry *root;
+		struct inode *iroot;
+
+		memset(&dummyfh, 0, sizeof(dummyfh));
+		memset(&fattr, 0, sizeof(fattr));
+		nfs_fattr_init(&fattr);
+		fattr.valid = NFS_ATTR_FATTR;
+		fattr.type = NFDIR;
+		fattr.mode = S_IFDIR | S_IRUSR | S_IWUSR;
+		fattr.nlink = 2;
+
+		iroot = nfs_fhget(sb, &dummyfh, &fattr);
+		if (IS_ERR(iroot))
+			return ERR_PTR(PTR_ERR(iroot));
+
+		root = d_alloc_root(iroot);
+		if (!root) {
+			iput(iroot);
+			return ERR_PTR(-ENOMEM);
+		}
+
+		sb->s_root = root;
+	}
+
+	/* get the info about the server and filesystem */
+	error = nfs4_server_capabilities(server, mntfh);
+	if (error < 0) {
+		dprintk("nfs_get_root: getcaps error = %d\n",
+			-error);
+		return ERR_PTR(error);
+	}
+
+	/* get the actual root for this mount */
+	error = server->nfs_client->rpc_ops->getattr(server, mntfh, &fattr);
+	if (error < 0) {
+		dprintk("nfs_get_root: getattr error = %d\n", -error);
+		return ERR_PTR(error);
+	}
+
+	inode = nfs_fhget(sb, mntfh, &fattr);
+	if (IS_ERR(inode)) {
+		dprintk("nfs_get_root: get root inode failed\n");
+		return ERR_PTR(PTR_ERR(inode));
+	}
+
+	/* root dentries normally start off anonymous and get spliced in later
+	 * if the dentry tree reaches them; however if the dentry already
+	 * exists, we'll pick it up at this point and use it as the root
+	 */
+	mntroot = d_alloc_anon(inode);
+	if (!mntroot) {
+		iput(inode);
+		dprintk("nfs_get_root: get root dentry failed\n");
+		return ERR_PTR(-ENOMEM);
+	}
+
+	security_d_instantiate(mntroot, inode);
+
+	if (!mntroot->d_op)
+		mntroot->d_op = server->nfs_client->rpc_ops->dentry_ops;
+
+	dprintk("<-- nfs4_get_root()\n");
+	return mntroot;
+}
+
+#endif /* CONFIG_NFS_V4 */
diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h
new file mode 100644
index 000000000..18febb4c2
--- /dev/null
+++ b/fs/nfs/internal.h
@@ -0,0 +1,248 @@
+/*
+ * NFS internal definitions
+ */
+
+#include <linux/mount.h>
+
+#define NFS_PAGE_WRITING	0
+#define NFS_PAGE_CACHED		1
+
+#define PageNfsBit(bit, page)		test_bit(bit, &(page)->private)
+
+#define SetPageNfsBit(bit, page)		\
+do {						\
+	SetPagePrivate((page));			\
+	set_bit(bit, &(page)->private);		\
+} while(0)
+
+#define ClearPageNfsBit(bit, page)		\
+do {						\
+	clear_bit(bit, &(page)->private);	\
+} while(0)
+
+#define PageNfsWriting(page)		PageNfsBit(NFS_PAGE_WRITING, (page))
+#define SetPageNfsWriting(page)		SetPageNfsBit(NFS_PAGE_WRITING, (page))
+#define ClearPageNfsWriting(page)	ClearPageNfsBit(NFS_PAGE_WRITING, (page))
+
+#define PageNfsCached(page)		PageNfsBit(NFS_PAGE_CACHED, (page))
+#define SetPageNfsCached(page)		SetPageNfsBit(NFS_PAGE_CACHED, (page))
+#define ClearPageNfsCached(page)	ClearPageNfsBit(NFS_PAGE_CACHED, (page))
+
+struct nfs_string;
+struct nfs_mount_data;
+struct nfs4_mount_data;
+
+/* Maximum number of readahead requests
+ * FIXME: this should really be a sysctl so that users may tune it to suit
+ *        their needs. People that do NFS over a slow network, might for
+ *        instance want to reduce it to something closer to 1 for improved
+ *        interactive response.
+ */
+#define NFS_MAX_READAHEAD	(RPC_DEF_SLOT_TABLE - 1)
+
+struct nfs_clone_mount {
+	const struct super_block *sb;
+	const struct dentry *dentry;
+	struct nfs_fh *fh;
+	struct nfs_fattr *fattr;
+	char *hostname;
+	char *mnt_path;
+	struct sockaddr_in *addr;
+	rpc_authflavor_t authflavor;
+};
+
+/*
+ * include filesystem caching stuff here
+ */
+#include "fscache.h"
+
+/* client.c */
+extern struct rpc_program nfs_program;
+
+extern void nfs_put_client(struct nfs_client *);
+extern struct nfs_client *nfs_find_client(const struct sockaddr_in *, int);
+extern struct nfs_server *nfs_create_server(const struct nfs_mount_data *,
+					    struct nfs_fh *);
+extern struct nfs_server *nfs4_create_server(const struct nfs4_mount_data *,
+					     const char *,
+					     const struct sockaddr_in *,
+					     const char *,
+					     const char *,
+					     rpc_authflavor_t,
+					     struct nfs_fh *);
+extern struct nfs_server *nfs4_create_referral_server(struct nfs_clone_mount *,
+						      struct nfs_fh *);
+extern void nfs_free_server(struct nfs_server *server);
+extern struct nfs_server *nfs_clone_server(struct nfs_server *,
+					   struct nfs_fh *,
+					   struct nfs_fattr *);
+#ifdef CONFIG_PROC_FS
+extern int __init nfs_fs_proc_init(void);
+extern void nfs_fs_proc_exit(void);
+#else
+static inline int nfs_fs_proc_init(void)
+{
+	return 0;
+}
+static inline void nfs_fs_proc_exit(void)
+{
+}
+#endif
+
+/* nfs4namespace.c */
+#ifdef CONFIG_NFS_V4
+extern struct vfsmount *nfs_do_refmount(const struct vfsmount *mnt_parent, struct dentry *dentry);
+#else
+static inline
+struct vfsmount *nfs_do_refmount(const struct vfsmount *mnt_parent, struct dentry *dentry)
+{
+	return ERR_PTR(-ENOENT);
+}
+#endif
+
+/* callback_xdr.c */
+extern struct svc_version nfs4_callback_version1;
+
+/* pagelist.c */
+extern int __init nfs_init_nfspagecache(void);
+extern void nfs_destroy_nfspagecache(void);
+extern int __init nfs_init_readpagecache(void);
+extern void nfs_destroy_readpagecache(void);
+extern int __init nfs_init_writepagecache(void);
+extern void nfs_destroy_writepagecache(void);
+
+#ifdef CONFIG_NFS_DIRECTIO
+extern int __init nfs_init_directcache(void);
+extern void nfs_destroy_directcache(void);
+#else
+#define nfs_init_directcache() (0)
+#define nfs_destroy_directcache() do {} while(0)
+#endif
+
+/* nfs2xdr.c */
+extern int nfs_stat_to_errno(int);
+extern struct rpc_procinfo nfs_procedures[];
+extern u32 * nfs_decode_dirent(u32 *, struct nfs_entry *, int);
+
+/* nfs3xdr.c */
+extern struct rpc_procinfo nfs3_procedures[];
+extern u32 *nfs3_decode_dirent(u32 *, struct nfs_entry *, int);
+
+/* nfs4xdr.c */
+#ifdef CONFIG_NFS_V4
+extern u32 *nfs4_decode_dirent(u32 *p, struct nfs_entry *entry, int plus);
+#endif
+
+/* nfs4proc.c */
+#ifdef CONFIG_NFS_V4
+extern struct rpc_procinfo nfs4_procedures[];
+
+extern int nfs4_proc_fs_locations(struct inode *dir, struct dentry *dentry,
+				  struct nfs4_fs_locations *fs_locations,
+				  struct page *page);
+#endif
+
+/* inode.c */
+extern struct inode *nfs_alloc_inode(struct super_block *sb);
+extern void nfs_destroy_inode(struct inode *);
+extern int nfs_write_inode(struct inode *,int);
+extern void nfs_clear_inode(struct inode *);
+#ifdef CONFIG_NFS_V4
+extern void nfs4_clear_inode(struct inode *);
+#endif
+
+/* super.c */
+extern struct file_system_type nfs_xdev_fs_type;
+#ifdef CONFIG_NFS_V4
+extern struct file_system_type nfs4_xdev_fs_type;
+extern struct file_system_type nfs4_referral_fs_type;
+#endif
+
+extern struct rpc_stat nfs_rpcstat;
+
+extern int __init register_nfs_fs(void);
+extern void __exit unregister_nfs_fs(void);
+
+/* namespace.c */
+extern char *nfs_path(const char *base,
+		      const struct dentry *droot,
+		      const struct dentry *dentry,
+		      char *buffer, ssize_t buflen);
+
+/* getroot.c */
+extern struct dentry *nfs_get_root(struct super_block *, struct nfs_fh *);
+#ifdef CONFIG_NFS_V4
+extern struct dentry *nfs4_get_root(struct super_block *, struct nfs_fh *);
+
+extern int nfs4_path_walk(struct nfs_server *server,
+			  struct nfs_fh *mntfh,
+			  const char *path);
+#endif
+
+/* read.c */
+extern int nfs_readpage_async(struct nfs_open_context *, struct inode *, struct page *);
+
+/*
+ * Determine the device name as a string
+ */
+static inline char *nfs_devname(const struct vfsmount *mnt_parent,
+				const struct dentry *dentry,
+				char *buffer, ssize_t buflen)
+{
+	return nfs_path(mnt_parent->mnt_devname, mnt_parent->mnt_root,
+			dentry, buffer, buflen);
+}
+
+/*
+ * Determine the actual block size (and log2 thereof)
+ */
+static inline
+unsigned long nfs_block_bits(unsigned long bsize, unsigned char *nrbitsp)
+{
+	/* make sure blocksize is a power of two */
+	if ((bsize & (bsize - 1)) || nrbitsp) {
+		unsigned char	nrbits;
+
+		for (nrbits = 31; nrbits && !(bsize & (1 << nrbits)); nrbits--)
+			;
+		bsize = 1 << nrbits;
+		if (nrbitsp)
+			*nrbitsp = nrbits;
+	}
+
+	return bsize;
+}
+
+/*
+ * Calculate the number of 512byte blocks used.
+ */
+static inline unsigned long nfs_calc_block_size(u64 tsize)
+{
+	loff_t used = (tsize + 511) >> 9;
+	return (used > ULONG_MAX) ? ULONG_MAX : used;
+}
+
+/*
+ * Compute and set NFS server blocksize
+ */
+static inline
+unsigned long nfs_block_size(unsigned long bsize, unsigned char *nrbitsp)
+{
+	if (bsize < NFS_MIN_FILE_IO_SIZE)
+		bsize = NFS_DEF_FILE_IO_SIZE;
+	else if (bsize >= NFS_MAX_FILE_IO_SIZE)
+		bsize = NFS_MAX_FILE_IO_SIZE;
+
+	return nfs_block_bits(bsize, nrbitsp);
+}
+
+/*
+ * Determine the maximum file size for a superblock
+ */
+static inline
+void nfs_super_set_maxbytes(struct super_block *sb, __u64 maxfilesize)
+{
+	sb->s_maxbytes = (loff_t)maxfilesize;
+	if (sb->s_maxbytes > MAX_LFS_FILESIZE || sb->s_maxbytes <= 0)
+		sb->s_maxbytes = MAX_LFS_FILESIZE;
+}
diff --git a/fs/nfs/namespace.c b/fs/nfs/namespace.c
new file mode 100644
index 000000000..f4763c181
--- /dev/null
+++ b/fs/nfs/namespace.c
@@ -0,0 +1,243 @@
+/*
+ * linux/fs/nfs/namespace.c
+ *
+ * Copyright (C) 2005 Trond Myklebust <Trond.Myklebust@netapp.com>
+ * - Modified by David Howells <dhowells@redhat.com>
+ *
+ * NFS namespace
+ */
+
+#include <linux/dcache.h>
+#include <linux/mount.h>
+#include <linux/namei.h>
+#include <linux/nfs_fs.h>
+#include <linux/string.h>
+#include <linux/sunrpc/clnt.h>
+#include <linux/vfs.h>
+#include "internal.h"
+
+#define NFSDBG_FACILITY		NFSDBG_VFS
+
+static void nfs_expire_automounts(void *list);
+
+LIST_HEAD(nfs_automount_list);
+static DECLARE_WORK(nfs_automount_task, nfs_expire_automounts, &nfs_automount_list);
+int nfs_mountpoint_expiry_timeout = 500 * HZ;
+
+/*
+ * nfs_path - reconstruct the path given an arbitrary dentry
+ * @base - arbitrary string to prepend to the path
+ * @droot - pointer to root dentry for mountpoint
+ * @dentry - pointer to dentry
+ * @buffer - result buffer
+ * @buflen - length of buffer
+ *
+ * Helper function for constructing the path from the
+ * root dentry to an arbitrary hashed dentry.
+ *
+ * This is mainly for use in figuring out the path on the
+ * server side when automounting on top of an existing partition.
+ */
+char *nfs_path(const char *base,
+	       const struct dentry *droot,
+	       const struct dentry *dentry,
+	       char *buffer, ssize_t buflen)
+{
+	char *end = buffer+buflen;
+	int namelen;
+
+	*--end = '\0';
+	buflen--;
+	spin_lock(&dcache_lock);
+	while (!IS_ROOT(dentry) && dentry != droot) {
+		namelen = dentry->d_name.len;
+		buflen -= namelen + 1;
+		if (buflen < 0)
+			goto Elong_unlock;
+		end -= namelen;
+		memcpy(end, dentry->d_name.name, namelen);
+		*--end = '/';
+		dentry = dentry->d_parent;
+	}
+	spin_unlock(&dcache_lock);
+	namelen = strlen(base);
+	/* Strip off excess slashes in base string */
+	while (namelen > 0 && base[namelen - 1] == '/')
+		namelen--;
+	buflen -= namelen;
+	if (buflen < 0)
+		goto Elong;
+	end -= namelen;
+	memcpy(end, base, namelen);
+	return end;
+Elong_unlock:
+	spin_unlock(&dcache_lock);
+Elong:
+	return ERR_PTR(-ENAMETOOLONG);
+}
+
+/*
+ * nfs_follow_mountpoint - handle crossing a mountpoint on the server
+ * @dentry - dentry of mountpoint
+ * @nd - nameidata info
+ *
+ * When we encounter a mountpoint on the server, we want to set up
+ * a mountpoint on the client too, to prevent inode numbers from
+ * colliding, and to allow "df" to work properly.
+ * On NFSv4, we also want to allow for the fact that different
+ * filesystems may be migrated to different servers in a failover
+ * situation, and that different filesystems may want to use
+ * different security flavours.
+ */
+static void * nfs_follow_mountpoint(struct dentry *dentry, struct nameidata *nd)
+{
+	struct vfsmount *mnt;
+	struct nfs_server *server = NFS_SERVER(dentry->d_inode);
+	struct dentry *parent;
+	struct nfs_fh fh;
+	struct nfs_fattr fattr;
+	int err;
+
+	dprintk("--> nfs_follow_mountpoint()\n");
+
+	BUG_ON(IS_ROOT(dentry));
+	dprintk("%s: enter\n", __FUNCTION__);
+	dput(nd->dentry);
+	nd->dentry = dget(dentry);
+
+	/* Look it up again */
+	parent = dget_parent(nd->dentry);
+	err = server->nfs_client->rpc_ops->lookup(parent->d_inode,
+						  &nd->dentry->d_name,
+						  &fh, &fattr);
+	dput(parent);
+	if (err != 0)
+		goto out_err;
+
+	if (fattr.valid & NFS_ATTR_FATTR_V4_REFERRAL)
+		mnt = nfs_do_refmount(nd->mnt, nd->dentry);
+	else
+		mnt = nfs_do_submount(nd->mnt, nd->dentry, &fh, &fattr);
+	err = PTR_ERR(mnt);
+	if (IS_ERR(mnt))
+		goto out_err;
+
+	mntget(mnt);
+	err = do_add_mount(mnt, nd, nd->mnt->mnt_flags|MNT_SHRINKABLE, &nfs_automount_list);
+	if (err < 0) {
+		mntput(mnt);
+		if (err == -EBUSY)
+			goto out_follow;
+		goto out_err;
+	}
+	mntput(nd->mnt);
+	dput(nd->dentry);
+	nd->mnt = mnt;
+	nd->dentry = dget(mnt->mnt_root);
+	schedule_delayed_work(&nfs_automount_task, nfs_mountpoint_expiry_timeout);
+out:
+	dprintk("%s: done, returned %d\n", __FUNCTION__, err);
+
+	dprintk("<-- nfs_follow_mountpoint() = %d\n", err);
+	return ERR_PTR(err);
+out_err:
+	path_release(nd);
+	goto out;
+out_follow:
+	while(d_mountpoint(nd->dentry) && follow_down(&nd->mnt, &nd->dentry))
+		;
+	err = 0;
+	goto out;
+}
+
+struct inode_operations nfs_mountpoint_inode_operations = {
+	.follow_link	= nfs_follow_mountpoint,
+	.getattr	= nfs_getattr,
+};
+
+struct inode_operations nfs_referral_inode_operations = {
+	.follow_link	= nfs_follow_mountpoint,
+};
+
+static void nfs_expire_automounts(void *data)
+{
+	struct list_head *list = (struct list_head *)data;
+
+	mark_mounts_for_expiry(list);
+	if (!list_empty(list))
+		schedule_delayed_work(&nfs_automount_task, nfs_mountpoint_expiry_timeout);
+}
+
+void nfs_release_automount_timer(void)
+{
+	if (list_empty(&nfs_automount_list)) {
+		cancel_delayed_work(&nfs_automount_task);
+		flush_scheduled_work();
+	}
+}
+
+/*
+ * Clone a mountpoint of the appropriate type
+ */
+static struct vfsmount *nfs_do_clone_mount(struct nfs_server *server,
+					   const char *devname,
+					   struct nfs_clone_mount *mountdata)
+{
+#ifdef CONFIG_NFS_V4
+	struct vfsmount *mnt = NULL;
+	switch (server->nfs_client->cl_nfsversion) {
+		case 2:
+		case 3:
+			mnt = vfs_kern_mount(&nfs_xdev_fs_type, 0, devname, mountdata);
+			break;
+		case 4:
+			mnt = vfs_kern_mount(&nfs4_xdev_fs_type, 0, devname, mountdata);
+	}
+	return mnt;
+#else
+	return vfs_kern_mount(&nfs_xdev_fs_type, 0, devname, mountdata);
+#endif
+}
+
+/**
+ * nfs_do_submount - set up mountpoint when crossing a filesystem boundary
+ * @mnt_parent - mountpoint of parent directory
+ * @dentry - parent directory
+ * @fh - filehandle for new root dentry
+ * @fattr - attributes for new root inode
+ *
+ */
+struct vfsmount *nfs_do_submount(const struct vfsmount *mnt_parent,
+		const struct dentry *dentry, struct nfs_fh *fh,
+		struct nfs_fattr *fattr)
+{
+	struct nfs_clone_mount mountdata = {
+		.sb = mnt_parent->mnt_sb,
+		.dentry = dentry,
+		.fh = fh,
+		.fattr = fattr,
+	};
+	struct vfsmount *mnt = ERR_PTR(-ENOMEM);
+	char *page = (char *) __get_free_page(GFP_USER);
+	char *devname;
+
+	dprintk("--> nfs_do_submount()\n");
+
+	dprintk("%s: submounting on %s/%s\n", __FUNCTION__,
+			dentry->d_parent->d_name.name,
+			dentry->d_name.name);
+	if (page == NULL)
+		goto out;
+	devname = nfs_devname(mnt_parent, dentry, page, PAGE_SIZE);
+	mnt = (struct vfsmount *)devname;
+	if (IS_ERR(devname))
+		goto free_page;
+	mnt = nfs_do_clone_mount(NFS_SB(mnt_parent->mnt_sb), devname, &mountdata);
+free_page:
+	free_page((unsigned long)page);
+out:
+	dprintk("%s: done\n", __FUNCTION__);
+
+	dprintk("<-- nfs_do_submount() = %p\n", mnt);
+	return mnt;
+}
diff --git a/fs/nfs/nfs4namespace.c b/fs/nfs/nfs4namespace.c
new file mode 100644
index 000000000..b872779d7
--- /dev/null
+++ b/fs/nfs/nfs4namespace.c
@@ -0,0 +1,259 @@
+/*
+ * linux/fs/nfs/nfs4namespace.c
+ *
+ * Copyright (C) 2005 Trond Myklebust <Trond.Myklebust@netapp.com>
+ * - Modified by David Howells <dhowells@redhat.com>
+ *
+ * NFSv4 namespace
+ */
+
+#include <linux/dcache.h>
+#include <linux/mount.h>
+#include <linux/namei.h>
+#include <linux/nfs_fs.h>
+#include <linux/string.h>
+#include <linux/sunrpc/clnt.h>
+#include <linux/vfs.h>
+#include <linux/inet.h>
+#include "internal.h"
+
+#define NFSDBG_FACILITY		NFSDBG_VFS
+
+/*
+ * Check if fs_root is valid
+ */
+static inline char *nfs4_pathname_string(const struct nfs4_pathname *pathname,
+					 char *buffer, ssize_t buflen)
+{
+	char *end = buffer + buflen;
+	int n;
+
+	*--end = '\0';
+	buflen--;
+
+	n = pathname->ncomponents;
+	while (--n >= 0) {
+		const struct nfs4_string *component = &pathname->components[n];
+		buflen -= component->len + 1;
+		if (buflen < 0)
+			goto Elong;
+		end -= component->len;
+		memcpy(end, component->data, component->len);
+		*--end = '/';
+	}
+	return end;
+Elong:
+	return ERR_PTR(-ENAMETOOLONG);
+}
+
+/*
+ * Determine the mount path as a string
+ */
+static char *nfs4_path(const struct vfsmount *mnt_parent,
+		       const struct dentry *dentry,
+		       char *buffer, ssize_t buflen)
+{
+	const char *srvpath;
+
+	srvpath = strchr(mnt_parent->mnt_devname, ':');
+	if (srvpath)
+		srvpath++;
+	else
+		srvpath = mnt_parent->mnt_devname;
+
+	return nfs_path(srvpath, mnt_parent->mnt_root, dentry, buffer, buflen);
+}
+
+/*
+ * Check that fs_locations::fs_root [RFC3530 6.3] is a prefix for what we
+ * believe to be the server path to this dentry
+ */
+static int nfs4_validate_fspath(const struct vfsmount *mnt_parent,
+				const struct dentry *dentry,
+				const struct nfs4_fs_locations *locations,
+				char *page, char *page2)
+{
+	const char *path, *fs_path;
+
+	path = nfs4_path(mnt_parent, dentry, page, PAGE_SIZE);
+	if (IS_ERR(path))
+		return PTR_ERR(path);
+
+	fs_path = nfs4_pathname_string(&locations->fs_path, page2, PAGE_SIZE);
+	if (IS_ERR(fs_path))
+		return PTR_ERR(fs_path);
+
+	if (strncmp(path, fs_path, strlen(fs_path)) != 0) {
+		dprintk("%s: path %s does not begin with fsroot %s\n",
+			__FUNCTION__, path, fs_path);
+		return -ENOENT;
+	}
+
+	return 0;
+}
+
+/*
+ * Check if the string represents a "valid" IPv4 address
+ */
+static inline int valid_ipaddr4(const char *buf)
+{
+	int rc, count, in[4];
+
+	rc = sscanf(buf, "%d.%d.%d.%d", &in[0], &in[1], &in[2], &in[3]);
+	if (rc != 4)
+		return -EINVAL;
+	for (count = 0; count < 4; count++) {
+		if (in[count] > 255)
+			return -EINVAL;
+	}
+	return 0;
+}
+
+/**
+ * nfs_follow_referral - set up mountpoint when hitting a referral on moved error
+ * @mnt_parent - mountpoint of parent directory
+ * @dentry - parent directory
+ * @fspath - fs path returned in fs_locations
+ * @mntpath - mount path to new server
+ * @hostname - hostname of new server
+ * @addr - host addr of new server
+ *
+ */
+static struct vfsmount *nfs_follow_referral(const struct vfsmount *mnt_parent,
+					    const struct dentry *dentry,
+					    const struct nfs4_fs_locations *locations)
+{
+	struct vfsmount *mnt = ERR_PTR(-ENOENT);
+	struct nfs_clone_mount mountdata = {
+		.sb = mnt_parent->mnt_sb,
+		.dentry = dentry,
+		.authflavor = NFS_SB(mnt_parent->mnt_sb)->client->cl_auth->au_flavor,
+	};
+	char *page = NULL, *page2 = NULL;
+	char *devname;
+	int loc, s, error;
+
+	if (locations == NULL || locations->nlocations <= 0)
+		goto out;
+
+	dprintk("%s: referral at %s/%s\n", __FUNCTION__,
+		dentry->d_parent->d_name.name, dentry->d_name.name);
+
+	page = (char *) __get_free_page(GFP_USER);
+	if (!page)
+		goto out;
+
+	page2 = (char *) __get_free_page(GFP_USER);
+	if (!page2)
+		goto out;
+
+	/* Ensure fs path is a prefix of current dentry path */
+	error = nfs4_validate_fspath(mnt_parent, dentry, locations, page, page2);
+	if (error < 0) {
+		mnt = ERR_PTR(error);
+		goto out;
+	}
+
+	devname = nfs_devname(mnt_parent, dentry, page, PAGE_SIZE);
+	if (IS_ERR(devname)) {
+		mnt = (struct vfsmount *)devname;
+		goto out;
+	}
+
+	loc = 0;
+	while (loc < locations->nlocations && IS_ERR(mnt)) {
+		const struct nfs4_fs_location *location = &locations->locations[loc];
+		char *mnt_path;
+
+		if (location == NULL || location->nservers <= 0 ||
+		    location->rootpath.ncomponents == 0) {
+			loc++;
+			continue;
+		}
+
+		mnt_path = nfs4_pathname_string(&location->rootpath, page2, PAGE_SIZE);
+		if (IS_ERR(mnt_path)) {
+			loc++;
+			continue;
+		}
+		mountdata.mnt_path = mnt_path;
+
+		s = 0;
+		while (s < location->nservers) {
+			struct sockaddr_in addr = {};
+
+			if (location->servers[s].len <= 0 ||
+			    valid_ipaddr4(location->servers[s].data) < 0) {
+				s++;
+				continue;
+			}
+
+			mountdata.hostname = location->servers[s].data;
+			addr.sin_addr.s_addr = in_aton(mountdata.hostname);
+			addr.sin_family = AF_INET;
+			addr.sin_port = htons(NFS_PORT);
+			mountdata.addr = &addr;
+
+			mnt = vfs_kern_mount(&nfs4_referral_fs_type, 0, devname, &mountdata);
+			if (!IS_ERR(mnt)) {
+				break;
+			}
+			s++;
+		}
+		loc++;
+	}
+
+out:
+	free_page((unsigned long) page);
+	free_page((unsigned long) page2);
+	dprintk("%s: done\n", __FUNCTION__);
+	return mnt;
+}
+
+/*
+ * nfs_do_refmount - handle crossing a referral on server
+ * @dentry - dentry of referral
+ * @nd - nameidata info
+ *
+ */
+struct vfsmount *nfs_do_refmount(const struct vfsmount *mnt_parent, struct dentry *dentry)
+{
+	struct vfsmount *mnt = ERR_PTR(-ENOMEM);
+	struct dentry *parent;
+	struct nfs4_fs_locations *fs_locations = NULL;
+	struct page *page;
+	int err;
+
+	/* BUG_ON(IS_ROOT(dentry)); */
+	dprintk("%s: enter\n", __FUNCTION__);
+
+	page = alloc_page(GFP_KERNEL);
+	if (page == NULL)
+		goto out;
+
+	fs_locations = kmalloc(sizeof(struct nfs4_fs_locations), GFP_KERNEL);
+	if (fs_locations == NULL)
+		goto out_free;
+
+	/* Get locations */
+	mnt = ERR_PTR(-ENOENT);
+
+	parent = dget_parent(dentry);
+	dprintk("%s: getting locations for %s/%s\n",
+		__FUNCTION__, parent->d_name.name, dentry->d_name.name);
+
+	err = nfs4_proc_fs_locations(parent->d_inode, dentry, fs_locations, page);
+	dput(parent);
+	if (err != 0 ||
+	    fs_locations->nlocations <= 0 ||
+	    fs_locations->fs_path.ncomponents <= 0)
+		goto out_free;
+
+	mnt = nfs_follow_referral(mnt_parent, dentry, fs_locations);
+out_free:
+	__free_page(page);
+	kfree(fs_locations);
+out:
+	dprintk("%s: done\n", __FUNCTION__);
+	return mnt;
+}
diff --git a/fs/nfs/super.c b/fs/nfs/super.c
new file mode 100644
index 000000000..62e627b47
--- /dev/null
+++ b/fs/nfs/super.c
@@ -0,0 +1,1068 @@
+/*
+ *  linux/fs/nfs/super.c
+ *
+ *  Copyright (C) 1992  Rick Sladkey
+ *
+ *  nfs superblock handling functions
+ *
+ *  Modularised by Alan Cox <Alan.Cox@linux.org>, while hacking some
+ *  experimental NFS changes. Modularisation taken straight from SYS5 fs.
+ *
+ *  Change to nfs_read_super() to permit NFS mounts to multi-homed hosts.
+ *  J.S.Peatfield@damtp.cam.ac.uk
+ *
+ *  Split from inode.c by David Howells <dhowells@redhat.com>
+ *
+ * - superblocks are indexed on server only - all inodes, dentries, etc. associated with a
+ *   particular server are held in the same superblock
+ * - NFS superblocks can have several effective roots to the dentry tree
+ * - directory type roots are spliced into the tree when a path from one root reaches the root
+ *   of another (see nfs_lookup())
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+
+#include <linux/time.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/string.h>
+#include <linux/stat.h>
+#include <linux/errno.h>
+#include <linux/unistd.h>
+#include <linux/sunrpc/clnt.h>
+#include <linux/sunrpc/stats.h>
+#include <linux/sunrpc/metrics.h>
+#include <linux/nfs_fs.h>
+#include <linux/nfs_mount.h>
+#include <linux/nfs4_mount.h>
+#include <linux/lockd/bind.h>
+#include <linux/smp_lock.h>
+#include <linux/seq_file.h>
+#include <linux/mount.h>
+#include <linux/nfs_idmap.h>
+#include <linux/vfs.h>
+#include <linux/inet.h>
+#include <linux/nfs_xdr.h>
+#include <linux/vserver/xid.h>
+
+#include <asm/system.h>
+#include <asm/uaccess.h>
+
+#include "nfs4_fs.h"
+#include "callback.h"
+#include "delegation.h"
+#include "iostat.h"
+#include "internal.h"
+
+#define NFSDBG_FACILITY		NFSDBG_VFS
+
+static void nfs_umount_begin(struct vfsmount *, int);
+static int  nfs_statfs(struct dentry *, struct kstatfs *);
+static int  nfs_show_options(struct seq_file *, struct vfsmount *);
+static int  nfs_show_stats(struct seq_file *, struct vfsmount *);
+static int nfs_get_sb(struct file_system_type *, int, const char *, void *, struct vfsmount *);
+static int nfs_xdev_get_sb(struct file_system_type *fs_type,
+		int flags, const char *dev_name, void *raw_data, struct vfsmount *mnt);
+static void nfs_kill_super(struct super_block *);
+
+static struct file_system_type nfs_fs_type = {
+	.owner		= THIS_MODULE,
+	.name		= "nfs",
+	.get_sb		= nfs_get_sb,
+	.kill_sb	= nfs_kill_super,
+	.fs_flags	= FS_ODD_RENAME|FS_REVAL_DOT|FS_BINARY_MOUNTDATA,
+};
+
+struct file_system_type nfs_xdev_fs_type = {
+	.owner		= THIS_MODULE,
+	.name		= "nfs",
+	.get_sb		= nfs_xdev_get_sb,
+	.kill_sb	= nfs_kill_super,
+	.fs_flags	= FS_ODD_RENAME|FS_REVAL_DOT|FS_BINARY_MOUNTDATA,
+};
+
+static struct super_operations nfs_sops = {
+	.alloc_inode	= nfs_alloc_inode,
+	.destroy_inode	= nfs_destroy_inode,
+	.write_inode	= nfs_write_inode,
+	.statfs		= nfs_statfs,
+	.clear_inode	= nfs_clear_inode,
+	.umount_begin	= nfs_umount_begin,
+	.show_options	= nfs_show_options,
+	.show_stats	= nfs_show_stats,
+};
+
+#ifdef CONFIG_NFS_V4
+static int nfs4_get_sb(struct file_system_type *fs_type,
+	int flags, const char *dev_name, void *raw_data, struct vfsmount *mnt);
+static int nfs4_xdev_get_sb(struct file_system_type *fs_type,
+	int flags, const char *dev_name, void *raw_data, struct vfsmount *mnt);
+static int nfs4_referral_get_sb(struct file_system_type *fs_type,
+	int flags, const char *dev_name, void *raw_data, struct vfsmount *mnt);
+static void nfs4_kill_super(struct super_block *sb);
+
+static struct file_system_type nfs4_fs_type = {
+	.owner		= THIS_MODULE,
+	.name		= "nfs4",
+	.get_sb		= nfs4_get_sb,
+	.kill_sb	= nfs4_kill_super,
+	.fs_flags	= FS_ODD_RENAME|FS_REVAL_DOT|FS_BINARY_MOUNTDATA,
+};
+
+struct file_system_type nfs4_xdev_fs_type = {
+	.owner		= THIS_MODULE,
+	.name		= "nfs4",
+	.get_sb		= nfs4_xdev_get_sb,
+	.kill_sb	= nfs4_kill_super,
+	.fs_flags	= FS_ODD_RENAME|FS_REVAL_DOT|FS_BINARY_MOUNTDATA,
+};
+
+struct file_system_type nfs4_referral_fs_type = {
+	.owner		= THIS_MODULE,
+	.name		= "nfs4",
+	.get_sb		= nfs4_referral_get_sb,
+	.kill_sb	= nfs4_kill_super,
+	.fs_flags	= FS_ODD_RENAME|FS_REVAL_DOT|FS_BINARY_MOUNTDATA,
+};
+
+static struct super_operations nfs4_sops = {
+	.alloc_inode	= nfs_alloc_inode,
+	.destroy_inode	= nfs_destroy_inode,
+	.write_inode	= nfs_write_inode,
+	.statfs		= nfs_statfs,
+	.clear_inode	= nfs4_clear_inode,
+	.umount_begin	= nfs_umount_begin,
+	.show_options	= nfs_show_options,
+	.show_stats	= nfs_show_stats,
+};
+#endif
+
+/*
+ * Register the NFS filesystems
+ */
+int __init register_nfs_fs(void)
+{
+	int ret;
+
+        ret = register_filesystem(&nfs_fs_type);
+	if (ret < 0)
+		goto error_0;
+
+#ifdef CONFIG_NFS_V4
+	ret = nfs_register_sysctl();
+	if (ret < 0)
+		goto error_1;
+	ret = register_filesystem(&nfs4_fs_type);
+	if (ret < 0)
+		goto error_2;
+#endif
+	return 0;
+
+#ifdef CONFIG_NFS_V4
+error_2:
+	nfs_unregister_sysctl();
+error_1:
+	unregister_filesystem(&nfs_fs_type);
+#endif
+error_0:
+	return ret;
+}
+
+/*
+ * Unregister the NFS filesystems
+ */
+void __exit unregister_nfs_fs(void)
+{
+#ifdef CONFIG_NFS_V4
+	unregister_filesystem(&nfs4_fs_type);
+	nfs_unregister_sysctl();
+#endif
+	unregister_filesystem(&nfs_fs_type);
+}
+
+/*
+ * Deliver file system statistics to userspace
+ */
+static int nfs_statfs(struct dentry *dentry, struct kstatfs *buf)
+{
+	struct nfs_server *server = NFS_SB(dentry->d_sb);
+	unsigned char blockbits;
+	unsigned long blockres;
+	struct nfs_fh *fh = NFS_FH(dentry->d_inode);
+	struct nfs_fattr fattr;
+	struct nfs_fsstat res = {
+			.fattr = &fattr,
+	};
+	int error;
+
+	lock_kernel();
+
+	error = server->nfs_client->rpc_ops->statfs(server, fh, &res);
+	buf->f_type = NFS_SUPER_MAGIC;
+	if (error < 0)
+		goto out_err;
+
+	/*
+	 * Current versions of glibc do not correctly handle the
+	 * case where f_frsize != f_bsize.  Eventually we want to
+	 * report the value of wtmult in this field.
+	 */
+	buf->f_frsize = dentry->d_sb->s_blocksize;
+
+	/*
+	 * On most *nix systems, f_blocks, f_bfree, and f_bavail
+	 * are reported in units of f_frsize.  Linux hasn't had
+	 * an f_frsize field in its statfs struct until recently,
+	 * thus historically Linux's sys_statfs reports these
+	 * fields in units of f_bsize.
+	 */
+	buf->f_bsize = dentry->d_sb->s_blocksize;
+	blockbits = dentry->d_sb->s_blocksize_bits;
+	blockres = (1 << blockbits) - 1;
+	buf->f_blocks = (res.tbytes + blockres) >> blockbits;
+	buf->f_bfree = (res.fbytes + blockres) >> blockbits;
+	buf->f_bavail = (res.abytes + blockres) >> blockbits;
+
+	buf->f_files = res.tfiles;
+	buf->f_ffree = res.afiles;
+
+	buf->f_namelen = server->namelen;
+ out:
+	unlock_kernel();
+	return 0;
+
+ out_err:
+	dprintk("%s: statfs error = %d\n", __FUNCTION__, -error);
+	buf->f_bsize = buf->f_blocks = buf->f_bfree = buf->f_bavail = -1;
+	goto out;
+
+}
+
+/*
+ * Map the security flavour number to a name
+ */
+static const char *nfs_pseudoflavour_to_name(rpc_authflavor_t flavour)
+{
+	static const struct {
+		rpc_authflavor_t flavour;
+		const char *str;
+	} sec_flavours[] = {
+		{ RPC_AUTH_NULL, "null" },
+		{ RPC_AUTH_UNIX, "sys" },
+		{ RPC_AUTH_GSS_KRB5, "krb5" },
+		{ RPC_AUTH_GSS_KRB5I, "krb5i" },
+		{ RPC_AUTH_GSS_KRB5P, "krb5p" },
+		{ RPC_AUTH_GSS_LKEY, "lkey" },
+		{ RPC_AUTH_GSS_LKEYI, "lkeyi" },
+		{ RPC_AUTH_GSS_LKEYP, "lkeyp" },
+		{ RPC_AUTH_GSS_SPKM, "spkm" },
+		{ RPC_AUTH_GSS_SPKMI, "spkmi" },
+		{ RPC_AUTH_GSS_SPKMP, "spkmp" },
+		{ -1, "unknown" }
+	};
+	int i;
+
+	for (i=0; sec_flavours[i].flavour != -1; i++) {
+		if (sec_flavours[i].flavour == flavour)
+			break;
+	}
+	return sec_flavours[i].str;
+}
+
+/*
+ * Describe the mount options in force on this server representation
+ */
+static void nfs_show_mount_options(struct seq_file *m, struct nfs_server *nfss, int showdefaults)
+{
+	static const struct proc_nfs_info {
+		int flag;
+		const char *str;
+		const char *nostr;
+	} nfs_info[] = {
+		{ NFS_MOUNT_SOFT, ",soft", ",hard" },
+		{ NFS_MOUNT_INTR, ",intr", "" },
+		{ NFS_MOUNT_NOCTO, ",nocto", "" },
+		{ NFS_MOUNT_NOAC, ",noac", "" },
+		{ NFS_MOUNT_NONLM, ",nolock", "" },
+		{ NFS_MOUNT_NOACL, ",noacl", "" },
+		{ NFS_MOUNT_FSCACHE, ",fsc", "" },
+		{ NFS_MOUNT_TAGXID, ",tagxid", "" },
+		{ 0, NULL, NULL }
+	};
+	const struct proc_nfs_info *nfs_infop;
+	struct nfs_client *clp = nfss->nfs_client;
+	char buf[12];
+	const char *proto;
+
+	seq_printf(m, ",vers=%d", clp->rpc_ops->version);
+	seq_printf(m, ",rsize=%d", nfss->rsize);
+	seq_printf(m, ",wsize=%d", nfss->wsize);
+	if (nfss->acregmin != 3*HZ || showdefaults)
+		seq_printf(m, ",acregmin=%d", nfss->acregmin/HZ);
+	if (nfss->acregmax != 60*HZ || showdefaults)
+		seq_printf(m, ",acregmax=%d", nfss->acregmax/HZ);
+	if (nfss->acdirmin != 30*HZ || showdefaults)
+		seq_printf(m, ",acdirmin=%d", nfss->acdirmin/HZ);
+	if (nfss->acdirmax != 60*HZ || showdefaults)
+		seq_printf(m, ",acdirmax=%d", nfss->acdirmax/HZ);
+	for (nfs_infop = nfs_info; nfs_infop->flag; nfs_infop++) {
+		if (nfss->flags & nfs_infop->flag)
+			seq_puts(m, nfs_infop->str);
+		else
+			seq_puts(m, nfs_infop->nostr);
+	}
+	switch (nfss->client->cl_xprt->prot) {
+		case IPPROTO_TCP:
+			proto = "tcp";
+			break;
+		case IPPROTO_UDP:
+			proto = "udp";
+			break;
+		default:
+			snprintf(buf, sizeof(buf), "%u", nfss->client->cl_xprt->prot);
+			proto = buf;
+	}
+	seq_printf(m, ",proto=%s", proto);
+	seq_printf(m, ",timeo=%lu", 10U * clp->retrans_timeo / HZ);
+	seq_printf(m, ",retrans=%u", clp->retrans_count);
+	seq_printf(m, ",sec=%s", nfs_pseudoflavour_to_name(nfss->client->cl_auth->au_flavor));
+}
+
+/*
+ * Describe the mount options on this VFS mountpoint
+ */
+static int nfs_show_options(struct seq_file *m, struct vfsmount *mnt)
+{
+	struct nfs_server *nfss = NFS_SB(mnt->mnt_sb);
+
+	nfs_show_mount_options(m, nfss, 0);
+
+	seq_puts(m, ",addr=");
+	seq_escape(m, nfss->nfs_client->cl_hostname, " \t\n\\");
+
+	return 0;
+}
+
+/*
+ * Present statistical information for this VFS mountpoint
+ */
+static int nfs_show_stats(struct seq_file *m, struct vfsmount *mnt)
+{
+	int i, cpu;
+	struct nfs_server *nfss = NFS_SB(mnt->mnt_sb);
+	struct rpc_auth *auth = nfss->client->cl_auth;
+	struct nfs_iostats totals = { };
+
+	seq_printf(m, "statvers=%s", NFS_IOSTAT_VERS);
+
+	/*
+	 * Display all mount option settings
+	 */
+	seq_printf(m, "\n\topts:\t");
+	seq_puts(m, mnt->mnt_sb->s_flags & MS_RDONLY ? "ro" : "rw");
+	seq_puts(m, mnt->mnt_sb->s_flags & MS_SYNCHRONOUS ? ",sync" : "");
+	seq_puts(m, mnt->mnt_sb->s_flags & MS_NOATIME ? ",noatime" : "");
+	seq_puts(m, mnt->mnt_sb->s_flags & MS_NODIRATIME ? ",nodiratime" : "");
+	nfs_show_mount_options(m, nfss, 1);
+
+	seq_printf(m, "\n\tage:\t%lu", (jiffies - nfss->mount_time) / HZ);
+
+	seq_printf(m, "\n\tcaps:\t");
+	seq_printf(m, "caps=0x%x", nfss->caps);
+	seq_printf(m, ",wtmult=%d", nfss->wtmult);
+	seq_printf(m, ",dtsize=%d", nfss->dtsize);
+	seq_printf(m, ",bsize=%d", nfss->bsize);
+	seq_printf(m, ",namelen=%d", nfss->namelen);
+
+#ifdef CONFIG_NFS_V4
+	if (nfss->nfs_client->cl_nfsversion == 4) {
+		seq_printf(m, "\n\tnfsv4:\t");
+		seq_printf(m, "bm0=0x%x", nfss->attr_bitmask[0]);
+		seq_printf(m, ",bm1=0x%x", nfss->attr_bitmask[1]);
+		seq_printf(m, ",acl=0x%x", nfss->acl_bitmask);
+	}
+#endif
+
+	/*
+	 * Display security flavor in effect for this mount
+	 */
+	seq_printf(m, "\n\tsec:\tflavor=%d", auth->au_ops->au_flavor);
+	if (auth->au_flavor)
+		seq_printf(m, ",pseudoflavor=%d", auth->au_flavor);
+
+	/*
+	 * Display superblock I/O counters
+	 */
+	for_each_possible_cpu(cpu) {
+		struct nfs_iostats *stats;
+
+		preempt_disable();
+		stats = per_cpu_ptr(nfss->io_stats, cpu);
+
+		for (i = 0; i < __NFSIOS_COUNTSMAX; i++)
+			totals.events[i] += stats->events[i];
+		for (i = 0; i < __NFSIOS_BYTESMAX; i++)
+			totals.bytes[i] += stats->bytes[i];
+
+		preempt_enable();
+	}
+
+	seq_printf(m, "\n\tevents:\t");
+	for (i = 0; i < __NFSIOS_COUNTSMAX; i++)
+		seq_printf(m, "%lu ", totals.events[i]);
+	seq_printf(m, "\n\tbytes:\t");
+	for (i = 0; i < __NFSIOS_BYTESMAX; i++)
+		seq_printf(m, "%Lu ", totals.bytes[i]);
+	seq_printf(m, "\n");
+
+	rpc_print_iostats(m, nfss->client);
+
+	return 0;
+}
+
+/*
+ * Begin unmount by attempting to remove all automounted mountpoints we added
+ * in response to xdev traversals and referrals
+ */
+static void nfs_umount_begin(struct vfsmount *vfsmnt, int flags)
+{
+	shrink_submounts(vfsmnt, &nfs_automount_list);
+}
+
+/*
+ * Validate the NFS2/NFS3 mount data
+ * - fills in the mount root filehandle
+ */
+static int nfs_validate_mount_data(struct nfs_mount_data *data,
+				   struct nfs_fh *mntfh)
+{
+	if (data == NULL) {
+		dprintk("%s: missing data argument\n", __FUNCTION__);
+		return -EINVAL;
+	}
+
+	if (data->version <= 0 || data->version > NFS_MOUNT_VERSION) {
+		dprintk("%s: bad mount version\n", __FUNCTION__);
+		return -EINVAL;
+	}
+
+	switch (data->version) {
+		case 1:
+			data->namlen = 0;
+		case 2:
+			data->bsize  = 0;
+		case 3:
+			if (data->flags & NFS_MOUNT_VER3) {
+				dprintk("%s: mount structure version %d does not support NFSv3\n",
+						__FUNCTION__,
+						data->version);
+				return -EINVAL;
+			}
+			data->root.size = NFS2_FHSIZE;
+			memcpy(data->root.data, data->old_root.data, NFS2_FHSIZE);
+		case 4:
+			if (data->flags & NFS_MOUNT_SECFLAVOUR) {
+				dprintk("%s: mount structure version %d does not support strong security\n",
+						__FUNCTION__,
+						data->version);
+				return -EINVAL;
+			}
+			/* Fill in pseudoflavor for mount version < 5 */
+			data->pseudoflavor = RPC_AUTH_UNIX;
+		case 5:
+			memset(data->context, 0, sizeof(data->context));
+	}
+
+#ifndef CONFIG_NFS_V3
+	/* If NFSv3 is not compiled in, return -EPROTONOSUPPORT */
+	if (data->flags & NFS_MOUNT_VER3) {
+		dprintk("%s: NFSv3 not compiled into kernel\n", __FUNCTION__);
+		return -EPROTONOSUPPORT;
+	}
+#endif /* CONFIG_NFS_V3 */
+
+	/* We now require that the mount process passes the remote address */
+	if (data->addr.sin_addr.s_addr == INADDR_ANY) {
+		dprintk("%s: mount program didn't pass remote address!\n",
+			__FUNCTION__);
+		return -EINVAL;
+	}
+
+	/* Prepare the root filehandle */
+	if (data->flags & NFS_MOUNT_VER3)
+		mntfh->size = data->root.size;
+	else
+		mntfh->size = NFS2_FHSIZE;
+
+	if (mntfh->size > sizeof(mntfh->data)) {
+		dprintk("%s: invalid root filehandle\n", __FUNCTION__);
+		return -EINVAL;
+	}
+
+	memcpy(mntfh->data, data->root.data, mntfh->size);
+	if (mntfh->size < sizeof(mntfh->data))
+		memset(mntfh->data + mntfh->size, 0,
+		       sizeof(mntfh->data) - mntfh->size);
+
+	return 0;
+}
+
+/*
+ * Initialise the common bits of the superblock
+ */
+static inline void nfs_initialise_sb(struct super_block *sb)
+{
+	struct nfs_server *server = NFS_SB(sb);
+
+	sb->s_magic = NFS_SUPER_MAGIC;
+
+	/* We probably want something more informative here */
+	snprintf(sb->s_id, sizeof(sb->s_id),
+		 "%x:%x", MAJOR(sb->s_dev), MINOR(sb->s_dev));
+
+	if (sb->s_blocksize == 0)
+		sb->s_blocksize = nfs_block_bits(server->wsize,
+						 &sb->s_blocksize_bits);
+
+	if (server->flags & NFS_MOUNT_NOAC)
+		sb->s_flags |= MS_SYNCHRONOUS;
+	if (server->flags & NFS_MOUNT_TAGXID)
+		sb->s_flags |= MS_TAGXID;
+
+	nfs_super_set_maxbytes(sb, server->maxfilesize);
+}
+
+/*
+ * Finish setting up an NFS2/3 superblock
+ */
+static void nfs_fill_super(struct super_block *sb, struct nfs_mount_data *data)
+{
+	struct nfs_server *server = NFS_SB(sb);
+
+	sb->s_blocksize_bits = 0;
+	sb->s_blocksize = 0;
+	if (data->bsize)
+		sb->s_blocksize = nfs_block_size(data->bsize, &sb->s_blocksize_bits);
+
+	if (server->flags & NFS_MOUNT_VER3) {
+		/* The VFS shouldn't apply the umask to mode bits. We will do
+		 * so ourselves when necessary.
+		 */
+		sb->s_flags |= MS_POSIXACL;
+		sb->s_time_gran = 1;
+	}
+
+	sb->s_op = &nfs_sops;
+ 	nfs_initialise_sb(sb);
+}
+
+/*
+ * Finish setting up a cloned NFS2/3 superblock
+ */
+static void nfs_clone_super(struct super_block *sb,
+			    const struct super_block *old_sb)
+{
+	struct nfs_server *server = NFS_SB(sb);
+
+	sb->s_blocksize_bits = old_sb->s_blocksize_bits;
+	sb->s_blocksize = old_sb->s_blocksize;
+	sb->s_maxbytes = old_sb->s_maxbytes;
+
+	if (server->flags & NFS_MOUNT_VER3) {
+		/* The VFS shouldn't apply the umask to mode bits. We will do
+		 * so ourselves when necessary.
+		 */
+		sb->s_flags |= MS_POSIXACL;
+		sb->s_time_gran = 1;
+	}
+
+	sb->s_op = old_sb->s_op;
+ 	nfs_initialise_sb(sb);
+}
+
+static int nfs_set_super(struct super_block *s, void *_server)
+{
+	struct nfs_server *server = _server;
+	int ret;
+
+	s->s_fs_info = server;
+	ret = set_anon_super(s, server);
+	if (ret == 0)
+		server->s_dev = s->s_dev;
+	return ret;
+}
+
+static int nfs_compare_super(struct super_block *sb, void *data)
+{
+	struct nfs_server *server = data, *old = NFS_SB(sb);
+
+	if (old->nfs_client != server->nfs_client)
+		return 0;
+	if (memcmp(&old->fsid, &server->fsid, sizeof(old->fsid)) != 0)
+		return 0;
+	return 1;
+}
+
+static int nfs_get_sb(struct file_system_type *fs_type,
+	int flags, const char *dev_name, void *raw_data, struct vfsmount *mnt)
+{
+	struct nfs_server *server = NULL;
+	struct super_block *s;
+	struct nfs_fh mntfh;
+	struct nfs_mount_data *data = raw_data;
+	struct dentry *mntroot;
+	int error;
+
+	/* Validate the mount data */
+	error = nfs_validate_mount_data(data, &mntfh);
+	if (error < 0)
+		return error;
+
+	/* Get a volume representation */
+	server = nfs_create_server(data, &mntfh);
+	if (IS_ERR(server)) {
+		error = PTR_ERR(server);
+		goto out_err_noserver;
+	}
+
+	/* Get a superblock - note that we may end up sharing one that already exists */
+	s = sget(fs_type, nfs_compare_super, nfs_set_super, server);
+	if (IS_ERR(s)) {
+		error = PTR_ERR(s);
+		goto out_err_nosb;
+	}
+
+	if (s->s_fs_info != server) {
+		nfs_free_server(server);
+		server = NULL;
+	}
+
+	if (!s->s_root) {
+		/* initial superblock/root creation */
+		s->s_flags = flags;
+		nfs_fill_super(s, data);
+	}
+
+	mntroot = nfs_get_root(s, &mntfh);
+	if (IS_ERR(mntroot)) {
+		error = PTR_ERR(mntroot);
+		goto error_splat_super;
+	}
+
+	s->s_flags |= MS_ACTIVE;
+	mnt->mnt_sb = s;
+	mnt->mnt_root = mntroot;
+	return 0;
+
+out_err_nosb:
+	nfs_free_server(server);
+out_err_noserver:
+	return error;
+
+error_splat_super:
+	up_write(&s->s_umount);
+	deactivate_super(s);
+	return error;
+}
+
+/*
+ * Destroy an NFS2/3 superblock
+ */
+static void nfs_kill_super(struct super_block *s)
+{
+	struct nfs_server *server = NFS_SB(s);
+
+	kill_anon_super(s);
+	nfs_free_server(server);
+}
+
+/*
+ * Clone an NFS2/3 server record on xdev traversal (FSID-change)
+ */
+static int nfs_xdev_get_sb(struct file_system_type *fs_type, int flags,
+			   const char *dev_name, void *raw_data,
+			   struct vfsmount *mnt)
+{
+	struct nfs_clone_mount *data = raw_data;
+	struct super_block *s;
+	struct nfs_server *server;
+	struct dentry *mntroot;
+	int error;
+
+	dprintk("--> nfs_xdev_get_sb()\n");
+
+	/* create a new volume representation */
+	server = nfs_clone_server(NFS_SB(data->sb), data->fh, data->fattr);
+	if (IS_ERR(server)) {
+		error = PTR_ERR(server);
+		goto out_err_noserver;
+	}
+
+	/* Get a superblock - note that we may end up sharing one that already exists */
+	s = sget(&nfs_fs_type, nfs_compare_super, nfs_set_super, server);
+	if (IS_ERR(s)) {
+		error = PTR_ERR(s);
+		goto out_err_nosb;
+	}
+
+	if (s->s_fs_info != server) {
+		nfs_free_server(server);
+		server = NULL;
+	}
+
+	if (!s->s_root) {
+		/* initial superblock/root creation */
+		s->s_flags = flags;
+		nfs_clone_super(s, data->sb);
+	}
+
+	mntroot = nfs_get_root(s, data->fh);
+	if (IS_ERR(mntroot)) {
+		error = PTR_ERR(mntroot);
+		goto error_splat_super;
+	}
+
+	s->s_flags |= MS_ACTIVE;
+	mnt->mnt_sb = s;
+	mnt->mnt_root = mntroot;
+
+	dprintk("<-- nfs_xdev_get_sb() = 0\n");
+	return 0;
+
+out_err_nosb:
+	nfs_free_server(server);
+out_err_noserver:
+	dprintk("<-- nfs_xdev_get_sb() = %d [error]\n", error);
+	return error;
+
+error_splat_super:
+	up_write(&s->s_umount);
+	deactivate_super(s);
+	dprintk("<-- nfs_xdev_get_sb() = %d [splat]\n", error);
+	return error;
+}
+
+#ifdef CONFIG_NFS_V4
+
+/*
+ * Finish setting up a cloned NFS4 superblock
+ */
+static void nfs4_clone_super(struct super_block *sb,
+			    const struct super_block *old_sb)
+{
+	sb->s_blocksize_bits = old_sb->s_blocksize_bits;
+	sb->s_blocksize = old_sb->s_blocksize;
+	sb->s_maxbytes = old_sb->s_maxbytes;
+	sb->s_time_gran = 1;
+	sb->s_op = old_sb->s_op;
+ 	nfs_initialise_sb(sb);
+}
+
+/*
+ * Set up an NFS4 superblock
+ */
+static void nfs4_fill_super(struct super_block *sb)
+{
+	sb->s_time_gran = 1;
+	sb->s_op = &nfs4_sops;
+	nfs_initialise_sb(sb);
+}
+
+static void *nfs_copy_user_string(char *dst, struct nfs_string *src, int maxlen)
+{
+	void *p = NULL;
+
+	if (!src->len)
+		return ERR_PTR(-EINVAL);
+	if (src->len < maxlen)
+		maxlen = src->len;
+	if (dst == NULL) {
+		p = dst = kmalloc(maxlen + 1, GFP_KERNEL);
+		if (p == NULL)
+			return ERR_PTR(-ENOMEM);
+	}
+	if (copy_from_user(dst, src->data, maxlen)) {
+		kfree(p);
+		return ERR_PTR(-EFAULT);
+	}
+	dst[maxlen] = '\0';
+	return dst;
+}
+
+/*
+ * Get the superblock for an NFS4 mountpoint
+ */
+static int nfs4_get_sb(struct file_system_type *fs_type,
+	int flags, const char *dev_name, void *raw_data, struct vfsmount *mnt)
+{
+	struct nfs4_mount_data *data = raw_data;
+	struct super_block *s;
+	struct nfs_server *server;
+	struct sockaddr_in addr;
+	rpc_authflavor_t authflavour;
+	struct nfs_fh mntfh;
+	struct dentry *mntroot;
+	char *mntpath = NULL, *hostname = NULL, ip_addr[16];
+	void *p;
+	int error;
+
+	if (data == NULL) {
+		dprintk("%s: missing data argument\n", __FUNCTION__);
+		return -EINVAL;
+	}
+	if (data->version <= 0 || data->version > NFS4_MOUNT_VERSION) {
+		dprintk("%s: bad mount version\n", __FUNCTION__);
+		return -EINVAL;
+	}
+
+	/* We now require that the mount process passes the remote address */
+	if (data->host_addrlen != sizeof(addr))
+		return -EINVAL;
+
+	if (copy_from_user(&addr, data->host_addr, sizeof(addr)))
+		return -EFAULT;
+
+	if (addr.sin_family != AF_INET ||
+	    addr.sin_addr.s_addr == INADDR_ANY
+	    ) {
+		dprintk("%s: mount program didn't pass remote IP address!\n",
+				__FUNCTION__);
+		return -EINVAL;
+	}
+
+	/* Grab the authentication type */
+	authflavour = RPC_AUTH_UNIX;
+	if (data->auth_flavourlen != 0) {
+		if (data->auth_flavourlen != 1) {
+			dprintk("%s: Invalid number of RPC auth flavours %d.\n",
+					__FUNCTION__, data->auth_flavourlen);
+			error = -EINVAL;
+			goto out_err_noserver;
+		}
+
+		if (copy_from_user(&authflavour, data->auth_flavours,
+				   sizeof(authflavour))) {
+			error = -EFAULT;
+			goto out_err_noserver;
+		}
+	}
+
+	p = nfs_copy_user_string(NULL, &data->hostname, 256);
+	if (IS_ERR(p))
+		goto out_err;
+	hostname = p;
+
+	p = nfs_copy_user_string(NULL, &data->mnt_path, 1024);
+	if (IS_ERR(p))
+		goto out_err;
+	mntpath = p;
+
+	dprintk("MNTPATH: %s\n", mntpath);
+
+	p = nfs_copy_user_string(ip_addr, &data->client_addr,
+				 sizeof(ip_addr) - 1);
+	if (IS_ERR(p))
+		goto out_err;
+
+	/* Get a volume representation */
+	server = nfs4_create_server(data, hostname, &addr, mntpath, ip_addr,
+				    authflavour, &mntfh);
+	if (IS_ERR(server)) {
+		error = PTR_ERR(server);
+		goto out_err_noserver;
+	}
+
+	/* Get a superblock - note that we may end up sharing one that already exists */
+	s = sget(fs_type, nfs_compare_super, nfs_set_super, server);
+	if (IS_ERR(s)) {
+		error = PTR_ERR(s);
+		goto out_free;
+	}
+
+	if (s->s_fs_info != server) {
+		nfs_free_server(server);
+		server = NULL;
+	}
+
+	if (!s->s_root) {
+		/* initial superblock/root creation */
+		s->s_flags = flags;
+		nfs4_fill_super(s);
+	}
+
+	mntroot = nfs4_get_root(s, &mntfh);
+	if (IS_ERR(mntroot)) {
+		error = PTR_ERR(mntroot);
+		goto error_splat_super;
+	}
+
+	s->s_flags |= MS_ACTIVE;
+	mnt->mnt_sb = s;
+	mnt->mnt_root = mntroot;
+	kfree(mntpath);
+	kfree(hostname);
+	return 0;
+
+out_err:
+	error = PTR_ERR(p);
+	goto out_err_noserver;
+
+out_free:
+	nfs_free_server(server);
+out_err_noserver:
+	kfree(mntpath);
+	kfree(hostname);
+	return error;
+
+error_splat_super:
+	up_write(&s->s_umount);
+	deactivate_super(s);
+	goto out_err_noserver;
+}
+
+static void nfs4_kill_super(struct super_block *sb)
+{
+	struct nfs_server *server = NFS_SB(sb);
+
+	nfs_return_all_delegations(sb);
+	kill_anon_super(sb);
+
+	nfs4_renewd_prepare_shutdown(server);
+	nfs_free_server(server);
+}
+
+/*
+ * Clone an NFS4 server record on xdev traversal (FSID-change)
+ */
+static int nfs4_xdev_get_sb(struct file_system_type *fs_type, int flags,
+			    const char *dev_name, void *raw_data,
+			    struct vfsmount *mnt)
+{
+	struct nfs_clone_mount *data = raw_data;
+	struct super_block *s;
+	struct nfs_server *server;
+	struct dentry *mntroot;
+	int error;
+
+	dprintk("--> nfs4_xdev_get_sb()\n");
+
+	/* create a new volume representation */
+	server = nfs_clone_server(NFS_SB(data->sb), data->fh, data->fattr);
+	if (IS_ERR(server)) {
+		error = PTR_ERR(server);
+		goto out_err_noserver;
+	}
+
+	/* Get a superblock - note that we may end up sharing one that already exists */
+	s = sget(&nfs_fs_type, nfs_compare_super, nfs_set_super, server);
+	if (IS_ERR(s)) {
+		error = PTR_ERR(s);
+		goto out_err_nosb;
+	}
+
+	if (s->s_fs_info != server) {
+		nfs_free_server(server);
+		server = NULL;
+	}
+
+	if (!s->s_root) {
+		/* initial superblock/root creation */
+		s->s_flags = flags;
+		nfs4_clone_super(s, data->sb);
+	}
+
+	mntroot = nfs4_get_root(s, data->fh);
+	if (IS_ERR(mntroot)) {
+		error = PTR_ERR(mntroot);
+		goto error_splat_super;
+	}
+
+	s->s_flags |= MS_ACTIVE;
+	mnt->mnt_sb = s;
+	mnt->mnt_root = mntroot;
+
+	dprintk("<-- nfs4_xdev_get_sb() = 0\n");
+	return 0;
+
+out_err_nosb:
+	nfs_free_server(server);
+out_err_noserver:
+	dprintk("<-- nfs4_xdev_get_sb() = %d [error]\n", error);
+	return error;
+
+error_splat_super:
+	up_write(&s->s_umount);
+	deactivate_super(s);
+	dprintk("<-- nfs4_xdev_get_sb() = %d [splat]\n", error);
+	return error;
+}
+
+/*
+ * Create an NFS4 server record on referral traversal
+ */
+static int nfs4_referral_get_sb(struct file_system_type *fs_type, int flags,
+				const char *dev_name, void *raw_data,
+				struct vfsmount *mnt)
+{
+	struct nfs_clone_mount *data = raw_data;
+	struct super_block *s;
+	struct nfs_server *server;
+	struct dentry *mntroot;
+	struct nfs_fh mntfh;
+	int error;
+
+	dprintk("--> nfs4_referral_get_sb()\n");
+
+	/* create a new volume representation */
+	server = nfs4_create_referral_server(data, &mntfh);
+	if (IS_ERR(server)) {
+		error = PTR_ERR(server);
+		goto out_err_noserver;
+	}
+
+	/* Get a superblock - note that we may end up sharing one that already exists */
+	s = sget(&nfs_fs_type, nfs_compare_super, nfs_set_super, server);
+	if (IS_ERR(s)) {
+		error = PTR_ERR(s);
+		goto out_err_nosb;
+	}
+
+	if (s->s_fs_info != server) {
+		nfs_free_server(server);
+		server = NULL;
+	}
+
+	if (!s->s_root) {
+		/* initial superblock/root creation */
+		s->s_flags = flags;
+		nfs4_fill_super(s);
+	}
+
+	mntroot = nfs4_get_root(s, data->fh);
+	if (IS_ERR(mntroot)) {
+		error = PTR_ERR(mntroot);
+		goto error_splat_super;
+	}
+
+	s->s_flags |= MS_ACTIVE;
+	mnt->mnt_sb = s;
+	mnt->mnt_root = mntroot;
+
+	dprintk("<-- nfs4_referral_get_sb() = 0\n");
+	return 0;
+
+out_err_nosb:
+	nfs_free_server(server);
+out_err_noserver:
+	dprintk("<-- nfs4_referral_get_sb() = %d [error]\n", error);
+	return error;
+
+error_splat_super:
+	up_write(&s->s_umount);
+	deactivate_super(s);
+	dprintk("<-- nfs4_referral_get_sb() = %d [splat]\n", error);
+	return error;
+}
+
+#endif /* CONFIG_NFS_V4 */
diff --git a/fs/squashfs/squashfs.h b/fs/squashfs/squashfs.h
new file mode 100644
index 000000000..dcbef0d11
--- /dev/null
+++ b/fs/squashfs/squashfs.h
@@ -0,0 +1,86 @@
+/*
+ * Squashfs - a compressed read only filesystem for Linux
+ *
+ * Copyright (c) 2002, 2003, 2004, 2005, 2006
+ * Phillip Lougher <phillip@lougher.org.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,
+ * 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * squashfs.h
+ */
+
+#ifdef CONFIG_SQUASHFS_1_0_COMPATIBILITY
+#undef CONFIG_SQUASHFS_1_0_COMPATIBILITY
+#endif
+
+#ifdef SQUASHFS_TRACE
+#define TRACE(s, args...)	printk(KERN_NOTICE "SQUASHFS: "s, ## args)
+#else
+#define TRACE(s, args...)	{}
+#endif
+
+#define ERROR(s, args...)	printk(KERN_ERR "SQUASHFS error: "s, ## args)
+
+#define SERROR(s, args...)	do { \
+				if (!silent) \
+				printk(KERN_ERR "SQUASHFS error: "s, ## args);\
+				} while(0)
+
+#define WARNING(s, args...)	printk(KERN_WARNING "SQUASHFS: "s, ## args)
+
+static inline struct squashfs_inode_info *SQUASHFS_I(struct inode *inode)
+{
+	return list_entry(inode, struct squashfs_inode_info, vfs_inode);
+}
+
+#if defined(CONFIG_SQUASHFS_1_0_COMPATIBILITY ) || defined(CONFIG_SQUASHFS_2_0_COMPATIBILITY)
+#define SQSH_EXTERN
+extern unsigned int squashfs_read_data(struct super_block *s, char *buffer,
+				long long index, unsigned int length,
+				long long *next_index);
+extern int squashfs_get_cached_block(struct super_block *s, char *buffer,
+				long long block, unsigned int offset,
+				int length, long long *next_block,
+				unsigned int *next_offset);
+extern void release_cached_fragment(struct squashfs_sb_info *msblk, struct
+					squashfs_fragment_cache *fragment);
+extern struct squashfs_fragment_cache *get_cached_fragment(struct super_block
+					*s, long long start_block,
+					int length);
+extern struct address_space_operations squashfs_symlink_aops;
+extern struct address_space_operations squashfs_aops;
+extern struct address_space_operations squashfs_aops_4K;
+extern struct inode_operations squashfs_dir_inode_ops;
+#else
+#define SQSH_EXTERN static
+#endif
+
+#ifdef CONFIG_SQUASHFS_1_0_COMPATIBILITY
+extern int squashfs_1_0_supported(struct squashfs_sb_info *msblk);
+#else
+static inline int squashfs_1_0_supported(struct squashfs_sb_info *msblk)
+{
+	return 0;
+}
+#endif
+
+#ifdef CONFIG_SQUASHFS_2_0_COMPATIBILITY
+extern int squashfs_2_0_supported(struct squashfs_sb_info *msblk);
+#else
+static inline int squashfs_2_0_supported(struct squashfs_sb_info *msblk)
+{
+	return 0;
+}
+#endif
diff --git a/fs/squashfs/squashfs2_0.c b/fs/squashfs/squashfs2_0.c
new file mode 100644
index 000000000..53ce95e26
--- /dev/null
+++ b/fs/squashfs/squashfs2_0.c
@@ -0,0 +1,758 @@
+/*
+ * Squashfs - a compressed read only filesystem for Linux
+ *
+ * Copyright (c) 2002, 2003, 2004, 2005, 2006
+ * Phillip Lougher <phillip@lougher.org.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,
+ * 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * squashfs2_0.c
+ */
+
+#include <linux/types.h>
+#include <linux/squashfs_fs.h>
+#include <linux/module.h>
+#include <linux/errno.h>
+#include <linux/slab.h>
+#include <linux/zlib.h>
+#include <linux/fs.h>
+#include <linux/smp_lock.h>
+#include <linux/slab.h>
+#include <linux/squashfs_fs_sb.h>
+#include <linux/squashfs_fs_i.h>
+#include <linux/buffer_head.h>
+#include <linux/vfs.h>
+#include <linux/init.h>
+#include <linux/dcache.h>
+#include <linux/wait.h>
+#include <linux/zlib.h>
+#include <linux/blkdev.h>
+#include <linux/vmalloc.h>
+#include <asm/uaccess.h>
+#include <asm/semaphore.h>
+
+#include "squashfs.h"
+static int squashfs_readdir_2(struct file *file, void *dirent, filldir_t filldir);
+static struct dentry *squashfs_lookup_2(struct inode *, struct dentry *,
+				struct nameidata *);
+
+static struct file_operations squashfs_dir_ops_2 = {
+	.read = generic_read_dir,
+	.readdir = squashfs_readdir_2
+};
+
+static struct inode_operations squashfs_dir_inode_ops_2 = {
+	.lookup = squashfs_lookup_2
+};
+
+static unsigned char squashfs_filetype_table[] = {
+	DT_UNKNOWN, DT_DIR, DT_REG, DT_LNK, DT_BLK, DT_CHR, DT_FIFO, DT_SOCK
+};
+
+static int read_fragment_index_table_2(struct super_block *s)
+{
+	struct squashfs_sb_info *msblk = s->s_fs_info;
+	struct squashfs_super_block *sblk = &msblk->sblk;
+
+	if (!(msblk->fragment_index_2 = kmalloc(SQUASHFS_FRAGMENT_INDEX_BYTES_2
+					(sblk->fragments), GFP_KERNEL))) {
+		ERROR("Failed to allocate uid/gid table\n");
+		return 0;
+	}
+   
+	if (SQUASHFS_FRAGMENT_INDEX_BYTES_2(sblk->fragments) &&
+					!squashfs_read_data(s, (char *)
+					msblk->fragment_index_2,
+					sblk->fragment_table_start,
+					SQUASHFS_FRAGMENT_INDEX_BYTES_2
+					(sblk->fragments) |
+					SQUASHFS_COMPRESSED_BIT_BLOCK, NULL)) {
+		ERROR("unable to read fragment index table\n");
+		return 0;
+	}
+
+	if (msblk->swap) {
+		int i;
+		unsigned int fragment;
+
+		for (i = 0; i < SQUASHFS_FRAGMENT_INDEXES_2(sblk->fragments);
+									i++) {
+			SQUASHFS_SWAP_FRAGMENT_INDEXES_2((&fragment),
+						&msblk->fragment_index_2[i], 1);
+			msblk->fragment_index_2[i] = fragment;
+		}
+	}
+
+	return 1;
+}
+
+
+static int get_fragment_location_2(struct super_block *s, unsigned int fragment,
+				long long *fragment_start_block,
+				unsigned int *fragment_size)
+{
+	struct squashfs_sb_info *msblk = s->s_fs_info;
+	long long start_block =
+		msblk->fragment_index_2[SQUASHFS_FRAGMENT_INDEX_2(fragment)];
+	int offset = SQUASHFS_FRAGMENT_INDEX_OFFSET_2(fragment);
+	struct squashfs_fragment_entry_2 fragment_entry;
+
+	if (msblk->swap) {
+		struct squashfs_fragment_entry_2 sfragment_entry;
+
+		if (!squashfs_get_cached_block(s, (char *) &sfragment_entry,
+					start_block, offset,
+					sizeof(sfragment_entry), &start_block,
+					&offset))
+			goto out;
+		SQUASHFS_SWAP_FRAGMENT_ENTRY_2(&fragment_entry, &sfragment_entry);
+	} else
+		if (!squashfs_get_cached_block(s, (char *) &fragment_entry,
+					start_block, offset,
+					sizeof(fragment_entry), &start_block,
+					&offset))
+			goto out;
+
+	*fragment_start_block = fragment_entry.start_block;
+	*fragment_size = fragment_entry.size;
+
+	return 1;
+
+out:
+	return 0;
+}
+
+
+static struct inode *squashfs_new_inode(struct super_block *s,
+		struct squashfs_base_inode_header_2 *inodeb, unsigned int ino)
+{
+	struct squashfs_sb_info *msblk = s->s_fs_info;
+	struct squashfs_super_block *sblk = &msblk->sblk;
+	struct inode *i = new_inode(s);
+
+	if (i) {
+		i->i_ino = ino;
+		i->i_mtime.tv_sec = sblk->mkfs_time;
+		i->i_atime.tv_sec = sblk->mkfs_time;
+		i->i_ctime.tv_sec = sblk->mkfs_time;
+		i->i_uid = msblk->uid[inodeb->uid];
+		i->i_mode = inodeb->mode;
+		i->i_nlink = 1;
+		i->i_size = 0;
+		if (inodeb->guid == SQUASHFS_GUIDS)
+			i->i_gid = i->i_uid;
+		else
+			i->i_gid = msblk->guid[inodeb->guid];
+	}
+
+	return i;
+}
+
+
+static struct inode *squashfs_iget_2(struct super_block *s, squashfs_inode_t inode)
+{
+	struct inode *i;
+	struct squashfs_sb_info *msblk = s->s_fs_info;
+	struct squashfs_super_block *sblk = &msblk->sblk;
+	unsigned int block = SQUASHFS_INODE_BLK(inode) +
+		sblk->inode_table_start;
+	unsigned int offset = SQUASHFS_INODE_OFFSET(inode);
+	unsigned int ino = SQUASHFS_MK_VFS_INODE(block
+		- sblk->inode_table_start, offset);
+	long long next_block;
+	unsigned int next_offset;
+	union squashfs_inode_header_2 id, sid;
+	struct squashfs_base_inode_header_2 *inodeb = &id.base,
+					  *sinodeb = &sid.base;
+
+	TRACE("Entered squashfs_iget\n");
+
+	if (msblk->swap) {
+		if (!squashfs_get_cached_block(s, (char *) sinodeb, block,
+					offset, sizeof(*sinodeb), &next_block,
+					&next_offset))
+			goto failed_read;
+		SQUASHFS_SWAP_BASE_INODE_HEADER_2(inodeb, sinodeb,
+					sizeof(*sinodeb));
+	} else
+		if (!squashfs_get_cached_block(s, (char *) inodeb, block,
+					offset, sizeof(*inodeb), &next_block,
+					&next_offset))
+			goto failed_read;
+
+	switch(inodeb->inode_type) {
+		case SQUASHFS_FILE_TYPE: {
+			struct squashfs_reg_inode_header_2 *inodep = &id.reg;
+			struct squashfs_reg_inode_header_2 *sinodep = &sid.reg;
+			long long frag_blk;
+			unsigned int frag_size;
+				
+			if (msblk->swap) {
+				if (!squashfs_get_cached_block(s, (char *)
+						sinodep, block, offset,
+						sizeof(*sinodep), &next_block,
+						&next_offset))
+					goto failed_read;
+				SQUASHFS_SWAP_REG_INODE_HEADER_2(inodep, sinodep);
+			} else
+				if (!squashfs_get_cached_block(s, (char *)
+						inodep, block, offset,
+						sizeof(*inodep), &next_block,
+						&next_offset))
+					goto failed_read;
+
+			frag_blk = SQUASHFS_INVALID_BLK;
+			if (inodep->fragment != SQUASHFS_INVALID_FRAG &&
+					!get_fragment_location_2(s,
+					inodep->fragment, &frag_blk, &frag_size))
+				goto failed_read;
+				
+			if((i = squashfs_new_inode(s, inodeb, ino)) == NULL)
+				goto failed_read1;
+
+			i->i_size = inodep->file_size;
+			i->i_fop = &generic_ro_fops;
+			i->i_mode |= S_IFREG;
+			i->i_mtime.tv_sec = inodep->mtime;
+			i->i_atime.tv_sec = inodep->mtime;
+			i->i_ctime.tv_sec = inodep->mtime;
+			i->i_blocks = ((i->i_size - 1) >> 9) + 1;
+			SQUASHFS_I(i)->u.s1.fragment_start_block = frag_blk;
+			SQUASHFS_I(i)->u.s1.fragment_size = frag_size;
+			SQUASHFS_I(i)->u.s1.fragment_offset = inodep->offset;
+			SQUASHFS_I(i)->start_block = inodep->start_block;
+			SQUASHFS_I(i)->u.s1.block_list_start = next_block;
+			SQUASHFS_I(i)->offset = next_offset;
+			if (sblk->block_size > 4096)
+				i->i_data.a_ops = &squashfs_aops;
+			else
+				i->i_data.a_ops = &squashfs_aops_4K;
+
+			TRACE("File inode %x:%x, start_block %x, "
+					"block_list_start %llx, offset %x\n",
+					SQUASHFS_INODE_BLK(inode), offset,
+					inodep->start_block, next_block,
+					next_offset);
+			break;
+		}
+		case SQUASHFS_DIR_TYPE: {
+			struct squashfs_dir_inode_header_2 *inodep = &id.dir;
+			struct squashfs_dir_inode_header_2 *sinodep = &sid.dir;
+
+			if (msblk->swap) {
+				if (!squashfs_get_cached_block(s, (char *)
+						sinodep, block, offset,
+						sizeof(*sinodep), &next_block,
+						&next_offset))
+					goto failed_read;
+				SQUASHFS_SWAP_DIR_INODE_HEADER_2(inodep, sinodep);
+			} else
+				if (!squashfs_get_cached_block(s, (char *)
+						inodep, block, offset,
+						sizeof(*inodep), &next_block,
+						&next_offset))
+					goto failed_read;
+
+			if((i = squashfs_new_inode(s, inodeb, ino)) == NULL)
+				goto failed_read1;
+
+			i->i_size = inodep->file_size;
+			i->i_op = &squashfs_dir_inode_ops_2;
+			i->i_fop = &squashfs_dir_ops_2;
+			i->i_mode |= S_IFDIR;
+			i->i_mtime.tv_sec = inodep->mtime;
+			i->i_atime.tv_sec = inodep->mtime;
+			i->i_ctime.tv_sec = inodep->mtime;
+			SQUASHFS_I(i)->start_block = inodep->start_block;
+			SQUASHFS_I(i)->offset = inodep->offset;
+			SQUASHFS_I(i)->u.s2.directory_index_count = 0;
+			SQUASHFS_I(i)->u.s2.parent_inode = 0;
+
+			TRACE("Directory inode %x:%x, start_block %x, offset "
+					"%x\n", SQUASHFS_INODE_BLK(inode),
+					offset, inodep->start_block,
+					inodep->offset);
+			break;
+		}
+		case SQUASHFS_LDIR_TYPE: {
+			struct squashfs_ldir_inode_header_2 *inodep = &id.ldir;
+			struct squashfs_ldir_inode_header_2 *sinodep = &sid.ldir;
+
+			if (msblk->swap) {
+				if (!squashfs_get_cached_block(s, (char *)
+						sinodep, block, offset,
+						sizeof(*sinodep), &next_block,
+						&next_offset))
+					goto failed_read;
+				SQUASHFS_SWAP_LDIR_INODE_HEADER_2(inodep,
+						sinodep);
+			} else
+				if (!squashfs_get_cached_block(s, (char *)
+						inodep, block, offset,
+						sizeof(*inodep), &next_block,
+						&next_offset))
+					goto failed_read;
+
+			if((i = squashfs_new_inode(s, inodeb, ino)) == NULL)
+				goto failed_read1;
+
+			i->i_size = inodep->file_size;
+			i->i_op = &squashfs_dir_inode_ops_2;
+			i->i_fop = &squashfs_dir_ops_2;
+			i->i_mode |= S_IFDIR;
+			i->i_mtime.tv_sec = inodep->mtime;
+			i->i_atime.tv_sec = inodep->mtime;
+			i->i_ctime.tv_sec = inodep->mtime;
+			SQUASHFS_I(i)->start_block = inodep->start_block;
+			SQUASHFS_I(i)->offset = inodep->offset;
+			SQUASHFS_I(i)->u.s2.directory_index_start = next_block;
+			SQUASHFS_I(i)->u.s2.directory_index_offset =
+								next_offset;
+			SQUASHFS_I(i)->u.s2.directory_index_count =
+								inodep->i_count;
+			SQUASHFS_I(i)->u.s2.parent_inode = 0;
+
+			TRACE("Long directory inode %x:%x, start_block %x, "
+					"offset %x\n",
+					SQUASHFS_INODE_BLK(inode), offset,
+					inodep->start_block, inodep->offset);
+			break;
+		}
+		case SQUASHFS_SYMLINK_TYPE: {
+			struct squashfs_symlink_inode_header_2 *inodep =
+								&id.symlink;
+			struct squashfs_symlink_inode_header_2 *sinodep =
+								&sid.symlink;
+	
+			if (msblk->swap) {
+				if (!squashfs_get_cached_block(s, (char *)
+						sinodep, block, offset,
+						sizeof(*sinodep), &next_block,
+						&next_offset))
+					goto failed_read;
+				SQUASHFS_SWAP_SYMLINK_INODE_HEADER_2(inodep,
+								sinodep);
+			} else
+				if (!squashfs_get_cached_block(s, (char *)
+						inodep, block, offset,
+						sizeof(*inodep), &next_block,
+						&next_offset))
+					goto failed_read;
+
+			if((i = squashfs_new_inode(s, inodeb, ino)) == NULL)
+				goto failed_read1;
+
+			i->i_size = inodep->symlink_size;
+			i->i_op = &page_symlink_inode_operations;
+			i->i_data.a_ops = &squashfs_symlink_aops;
+			i->i_mode |= S_IFLNK;
+			SQUASHFS_I(i)->start_block = next_block;
+			SQUASHFS_I(i)->offset = next_offset;
+
+			TRACE("Symbolic link inode %x:%x, start_block %llx, "
+					"offset %x\n",
+					SQUASHFS_INODE_BLK(inode), offset,
+					next_block, next_offset);
+			break;
+		 }
+		 case SQUASHFS_BLKDEV_TYPE:
+		 case SQUASHFS_CHRDEV_TYPE: {
+			struct squashfs_dev_inode_header_2 *inodep = &id.dev;
+			struct squashfs_dev_inode_header_2 *sinodep = &sid.dev;
+
+			if (msblk->swap) {
+				if (!squashfs_get_cached_block(s, (char *)
+						sinodep, block, offset,
+						sizeof(*sinodep), &next_block,
+						&next_offset))
+					goto failed_read;
+				SQUASHFS_SWAP_DEV_INODE_HEADER_2(inodep, sinodep);
+			} else	
+				if (!squashfs_get_cached_block(s, (char *)
+						inodep, block, offset,
+						sizeof(*inodep), &next_block,
+						&next_offset))
+					goto failed_read;
+
+			if ((i = squashfs_new_inode(s, inodeb, ino)) == NULL)
+				goto failed_read1;
+
+			i->i_mode |= (inodeb->inode_type ==
+					SQUASHFS_CHRDEV_TYPE) ?  S_IFCHR :
+					S_IFBLK;
+			init_special_inode(i, i->i_mode,
+					old_decode_dev(inodep->rdev));
+
+			TRACE("Device inode %x:%x, rdev %x\n",
+					SQUASHFS_INODE_BLK(inode), offset,
+					inodep->rdev);
+			break;
+		 }
+		 case SQUASHFS_FIFO_TYPE:
+		 case SQUASHFS_SOCKET_TYPE: {
+			if ((i = squashfs_new_inode(s, inodeb, ino)) == NULL)
+				goto failed_read1;
+
+			i->i_mode |= (inodeb->inode_type == SQUASHFS_FIFO_TYPE)
+							? S_IFIFO : S_IFSOCK;
+			init_special_inode(i, i->i_mode, 0);
+			break;
+		 }
+		 default:
+			ERROR("Unknown inode type %d in squashfs_iget!\n",
+					inodeb->inode_type);
+			goto failed_read1;
+	}
+	
+	insert_inode_hash(i);
+	return i;
+
+failed_read:
+	ERROR("Unable to read inode [%x:%x]\n", block, offset);
+
+failed_read1:
+	return NULL;
+}
+
+
+static int get_dir_index_using_offset(struct super_block *s, long long 
+				*next_block, unsigned int *next_offset,
+				long long index_start,
+				unsigned int index_offset, int i_count,
+				long long f_pos)
+{
+	struct squashfs_sb_info *msblk = s->s_fs_info;
+	struct squashfs_super_block *sblk = &msblk->sblk;
+	int i, length = 0;
+	struct squashfs_dir_index_2 index;
+
+	TRACE("Entered get_dir_index_using_offset, i_count %d, f_pos %d\n",
+					i_count, (unsigned int) f_pos);
+
+	if (f_pos == 0)
+		goto finish;
+
+	for (i = 0; i < i_count; i++) {
+		if (msblk->swap) {
+			struct squashfs_dir_index_2 sindex;
+			squashfs_get_cached_block(s, (char *) &sindex,
+					index_start, index_offset,
+					sizeof(sindex), &index_start,
+					&index_offset);
+			SQUASHFS_SWAP_DIR_INDEX_2(&index, &sindex);
+		} else
+			squashfs_get_cached_block(s, (char *) &index,
+					index_start, index_offset,
+					sizeof(index), &index_start,
+					&index_offset);
+
+		if (index.index > f_pos)
+			break;
+
+		squashfs_get_cached_block(s, NULL, index_start, index_offset,
+					index.size + 1, &index_start,
+					&index_offset);
+
+		length = index.index;
+		*next_block = index.start_block + sblk->directory_table_start;
+	}
+
+	*next_offset = (length + *next_offset) % SQUASHFS_METADATA_SIZE;
+
+finish:
+	return length;
+}
+
+
+static int get_dir_index_using_name(struct super_block *s, long long
+				*next_block, unsigned int *next_offset,
+				long long index_start,
+				unsigned int index_offset, int i_count,
+				const char *name, int size)
+{
+	struct squashfs_sb_info *msblk = s->s_fs_info;
+	struct squashfs_super_block *sblk = &msblk->sblk;
+	int i, length = 0;
+	char buffer[sizeof(struct squashfs_dir_index_2) + SQUASHFS_NAME_LEN + 1];
+	struct squashfs_dir_index_2 *index = (struct squashfs_dir_index_2 *) buffer;
+	char str[SQUASHFS_NAME_LEN + 1];
+
+	TRACE("Entered get_dir_index_using_name, i_count %d\n", i_count);
+
+	strncpy(str, name, size);
+	str[size] = '\0';
+
+	for (i = 0; i < i_count; i++) {
+		if (msblk->swap) {
+			struct squashfs_dir_index_2 sindex;
+			squashfs_get_cached_block(s, (char *) &sindex,
+					index_start, index_offset,
+					sizeof(sindex), &index_start,
+					&index_offset);
+			SQUASHFS_SWAP_DIR_INDEX_2(index, &sindex);
+		} else
+			squashfs_get_cached_block(s, (char *) index,
+					index_start, index_offset,
+					sizeof(struct squashfs_dir_index_2),
+					&index_start, &index_offset);
+
+		squashfs_get_cached_block(s, index->name, index_start,
+					index_offset, index->size + 1,
+					&index_start, &index_offset);
+
+		index->name[index->size + 1] = '\0';
+
+		if (strcmp(index->name, str) > 0)
+			break;
+
+		length = index->index;
+		*next_block = index->start_block + sblk->directory_table_start;
+	}
+
+	*next_offset = (length + *next_offset) % SQUASHFS_METADATA_SIZE;
+	return length;
+}
+
+		
+static int squashfs_readdir_2(struct file *file, void *dirent, filldir_t filldir)
+{
+	struct inode *i = file->f_dentry->d_inode;
+	struct squashfs_sb_info *msblk = i->i_sb->s_fs_info;
+	struct squashfs_super_block *sblk = &msblk->sblk;
+	long long next_block = SQUASHFS_I(i)->start_block +
+		sblk->directory_table_start;
+	int next_offset = SQUASHFS_I(i)->offset, length = 0, dirs_read = 0,
+		dir_count;
+	struct squashfs_dir_header_2 dirh;
+	char buffer[sizeof(struct squashfs_dir_entry_2) + SQUASHFS_NAME_LEN + 1];
+	struct squashfs_dir_entry_2 *dire = (struct squashfs_dir_entry_2 *) buffer;
+
+	TRACE("Entered squashfs_readdir_2 [%llx:%x]\n", next_block, next_offset);
+
+	length = get_dir_index_using_offset(i->i_sb, &next_block, &next_offset,
+				SQUASHFS_I(i)->u.s2.directory_index_start,
+				SQUASHFS_I(i)->u.s2.directory_index_offset,
+				SQUASHFS_I(i)->u.s2.directory_index_count,
+				file->f_pos);
+
+	while (length < i_size_read(i)) {
+		/* read directory header */
+		if (msblk->swap) {
+			struct squashfs_dir_header_2 sdirh;
+			
+			if (!squashfs_get_cached_block(i->i_sb, (char *) &sdirh,
+					next_block, next_offset, sizeof(sdirh),
+					&next_block, &next_offset))
+				goto failed_read;
+
+			length += sizeof(sdirh);
+			SQUASHFS_SWAP_DIR_HEADER_2(&dirh, &sdirh);
+		} else {
+			if (!squashfs_get_cached_block(i->i_sb, (char *) &dirh,
+					next_block, next_offset, sizeof(dirh),
+					&next_block, &next_offset))
+				goto failed_read;
+
+			length += sizeof(dirh);
+		}
+
+		dir_count = dirh.count + 1;
+		while (dir_count--) {
+			if (msblk->swap) {
+				struct squashfs_dir_entry_2 sdire;
+				if (!squashfs_get_cached_block(i->i_sb, (char *)
+						&sdire, next_block, next_offset,
+						sizeof(sdire), &next_block,
+						&next_offset))
+					goto failed_read;
+				
+				length += sizeof(sdire);
+				SQUASHFS_SWAP_DIR_ENTRY_2(dire, &sdire);
+			} else {
+				if (!squashfs_get_cached_block(i->i_sb, (char *)
+						dire, next_block, next_offset,
+						sizeof(*dire), &next_block,
+						&next_offset))
+					goto failed_read;
+
+				length += sizeof(*dire);
+			}
+
+			if (!squashfs_get_cached_block(i->i_sb, dire->name,
+						next_block, next_offset,
+						dire->size + 1, &next_block,
+						&next_offset))
+				goto failed_read;
+
+			length += dire->size + 1;
+
+			if (file->f_pos >= length)
+				continue;
+
+			dire->name[dire->size + 1] = '\0';
+
+			TRACE("Calling filldir(%x, %s, %d, %d, %x:%x, %d)\n",
+					(unsigned int) dirent, dire->name,
+					dire->size + 1, (int) file->f_pos,
+					dirh.start_block, dire->offset,
+					squashfs_filetype_table[dire->type]);
+
+			if (filldir(dirent, dire->name, dire->size + 1,
+					file->f_pos, SQUASHFS_MK_VFS_INODE(
+					dirh.start_block, dire->offset),
+					squashfs_filetype_table[dire->type])
+					< 0) {
+				TRACE("Filldir returned less than 0\n");
+				goto finish;
+			}
+			file->f_pos = length;
+			dirs_read++;
+		}
+	}
+
+finish:
+	return dirs_read;
+
+failed_read:
+	ERROR("Unable to read directory block [%llx:%x]\n", next_block,
+		next_offset);
+	return 0;
+}
+
+
+static struct dentry *squashfs_lookup_2(struct inode *i, struct dentry *dentry,
+				struct nameidata *nd)
+{
+	const unsigned char *name = dentry->d_name.name;
+	int len = dentry->d_name.len;
+	struct inode *inode = NULL;
+	struct squashfs_sb_info *msblk = i->i_sb->s_fs_info;
+	struct squashfs_super_block *sblk = &msblk->sblk;
+	long long next_block = SQUASHFS_I(i)->start_block +
+				sblk->directory_table_start;
+	int next_offset = SQUASHFS_I(i)->offset, length = 0,
+				dir_count;
+	struct squashfs_dir_header_2 dirh;
+	char buffer[sizeof(struct squashfs_dir_entry_2) + SQUASHFS_NAME_LEN];
+	struct squashfs_dir_entry_2 *dire = (struct squashfs_dir_entry_2 *) buffer;
+	int sorted = sblk->s_major == 2 && sblk->s_minor >= 1;
+
+	TRACE("Entered squashfs_lookup [%llx:%x]\n", next_block, next_offset);
+
+	if (len > SQUASHFS_NAME_LEN)
+		goto exit_loop;
+
+	length = get_dir_index_using_name(i->i_sb, &next_block, &next_offset,
+				SQUASHFS_I(i)->u.s2.directory_index_start,
+				SQUASHFS_I(i)->u.s2.directory_index_offset,
+				SQUASHFS_I(i)->u.s2.directory_index_count, name,
+				len);
+
+	while (length < i_size_read(i)) {
+		/* read directory header */
+		if (msblk->swap) {
+			struct squashfs_dir_header_2 sdirh;
+			if (!squashfs_get_cached_block(i->i_sb, (char *) &sdirh,
+					next_block, next_offset, sizeof(sdirh),
+					&next_block, &next_offset))
+				goto failed_read;
+
+			length += sizeof(sdirh);
+			SQUASHFS_SWAP_DIR_HEADER_2(&dirh, &sdirh);
+		} else {
+			if (!squashfs_get_cached_block(i->i_sb, (char *) &dirh,
+					next_block, next_offset, sizeof(dirh),
+					&next_block, &next_offset))
+				goto failed_read;
+
+			length += sizeof(dirh);
+		}
+
+		dir_count = dirh.count + 1;
+		while (dir_count--) {
+			if (msblk->swap) {
+				struct squashfs_dir_entry_2 sdire;
+				if (!squashfs_get_cached_block(i->i_sb, (char *)
+						&sdire, next_block,next_offset,
+						sizeof(sdire), &next_block,
+						&next_offset))
+					goto failed_read;
+				
+				length += sizeof(sdire);
+				SQUASHFS_SWAP_DIR_ENTRY_2(dire, &sdire);
+			} else {
+				if (!squashfs_get_cached_block(i->i_sb, (char *)
+						dire, next_block,next_offset,
+						sizeof(*dire), &next_block,
+						&next_offset))
+					goto failed_read;
+
+				length += sizeof(*dire);
+			}
+
+			if (!squashfs_get_cached_block(i->i_sb, dire->name,
+					next_block, next_offset, dire->size + 1,
+					&next_block, &next_offset))
+				goto failed_read;
+
+			length += dire->size + 1;
+
+			if (sorted && name[0] < dire->name[0])
+				goto exit_loop;
+
+			if ((len == dire->size + 1) && !strncmp(name,
+						dire->name, len)) {
+				squashfs_inode_t ino =
+					SQUASHFS_MKINODE(dirh.start_block,
+					dire->offset);
+
+				TRACE("calling squashfs_iget for directory "
+					"entry %s, inode %x:%x, %lld\n", name,
+					dirh.start_block, dire->offset, ino);
+
+				inode = (msblk->iget)(i->i_sb, ino);
+
+				goto exit_loop;
+			}
+		}
+	}
+
+exit_loop:
+	d_add(dentry, inode);
+	return ERR_PTR(0);
+
+failed_read:
+	ERROR("Unable to read directory block [%llx:%x]\n", next_block,
+		next_offset);
+	goto exit_loop;
+}
+
+
+int squashfs_2_0_supported(struct squashfs_sb_info *msblk)
+{
+	struct squashfs_super_block *sblk = &msblk->sblk;
+
+	msblk->iget = squashfs_iget_2;
+	msblk->read_fragment_index_table = read_fragment_index_table_2;
+
+	sblk->bytes_used = sblk->bytes_used_2;
+	sblk->uid_start = sblk->uid_start_2;
+	sblk->guid_start = sblk->guid_start_2;
+	sblk->inode_table_start = sblk->inode_table_start_2;
+	sblk->directory_table_start = sblk->directory_table_start_2;
+	sblk->fragment_table_start = sblk->fragment_table_start_2;
+
+	return 1;
+}
diff --git a/include/Kbuild b/include/Kbuild
new file mode 100644
index 000000000..2d03f9958
--- /dev/null
+++ b/include/Kbuild
@@ -0,0 +1,9 @@
+header-y += asm-generic/
+header-y += linux/
+header-y += scsi/
+header-y += sound/
+header-y += mtd/
+header-y += rdma/
+header-y += video/
+
+header-y += asm-$(ARCH)/
diff --git a/include/acpi/acpi_numa.h b/include/acpi/acpi_numa.h
new file mode 100644
index 000000000..1049f2a0a
--- /dev/null
+++ b/include/acpi/acpi_numa.h
@@ -0,0 +1,23 @@
+#ifndef __ACPI_NUMA_H
+#define __ACPI_NUMA_H
+
+#ifdef CONFIG_ACPI_NUMA
+#include <linux/kernel.h>
+
+/* Proximity bitmap length */
+#if MAX_NUMNODES > 256
+#define MAX_PXM_DOMAINS MAX_NUMNODES
+#else
+#define MAX_PXM_DOMAINS (256) /* Old pxm spec is defined 8 bit */
+#endif
+
+extern int __cpuinitdata pxm_to_node_map[MAX_PXM_DOMAINS];
+extern int __cpuinitdata node_to_pxm_map[MAX_NUMNODES];
+
+extern int __cpuinit pxm_to_node(int);
+extern int __cpuinit node_to_pxm(int);
+extern int __cpuinit acpi_map_pxm_to_node(int);
+extern void __cpuinit acpi_unmap_pxm_to_node(int);
+
+#endif				/* CONFIG_ACPI_NUMA */
+#endif				/* __ACP_NUMA_H */
diff --git a/include/asm-alpha/Kbuild b/include/asm-alpha/Kbuild
new file mode 100644
index 000000000..b7c8f188b
--- /dev/null
+++ b/include/asm-alpha/Kbuild
@@ -0,0 +1,11 @@
+include include/asm-generic/Kbuild.asm
+
+header-y += gentrap.h
+header-y += regdef.h
+header-y += pal.h
+header-y += reg.h
+
+unifdef-y += console.h
+unifdef-y += fpu.h
+unifdef-y += sysinfo.h
+unifdef-y += compiler.h
diff --git a/include/asm-arm/Kbuild b/include/asm-arm/Kbuild
new file mode 100644
index 000000000..c68e1680d
--- /dev/null
+++ b/include/asm-arm/Kbuild
@@ -0,0 +1 @@
+include include/asm-generic/Kbuild.asm
diff --git a/include/asm-arm/arch-at91rm9200/at91rm9200_spi.h b/include/asm-arm/arch-at91rm9200/at91rm9200_spi.h
new file mode 100644
index 000000000..bff5ea45f
--- /dev/null
+++ b/include/asm-arm/arch-at91rm9200/at91rm9200_spi.h
@@ -0,0 +1,81 @@
+/*
+ * include/asm-arm/arch-at91rm9200/at91rm9200_spi.h
+ *
+ * Copyright (C) 2005 Ivan Kokshaysky
+ * Copyright (C) SAN People
+ *
+ * Serial Peripheral Interface (SPI) 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 AT91RM9200_SPI_H
+#define AT91RM9200_SPI_H
+
+#define AT91_SPI_CR			0x00		/* Control Register */
+#define		AT91_SPI_SPIEN		(1 <<  0)		/* SPI Enable */
+#define		AT91_SPI_SPIDIS		(1 <<  1)		/* SPI Disable */
+#define		AT91_SPI_SWRST		(1 <<  7)		/* SPI Software Reset */
+#define		AT91_SPI_LASTXFER	(1 << 24)		/* Last Transfer [SAM9261 only] */
+
+#define AT91_SPI_MR			0x04		/* Mode Register */
+#define		AT91_SPI_MSTR		(1    <<  0)		/* Master/Slave Mode */
+#define		AT91_SPI_PS		(1    <<  1)		/* Peripheral Select */
+#define			AT91_SPI_PS_FIXED	(0 << 1)
+#define			AT91_SPI_PS_VARIABLE	(1 << 1)
+#define		AT91_SPI_PCSDEC		(1    <<  2)		/* Chip Select Decode */
+#define		AT91_SPI_DIV32		(1    <<  3)		/* Clock Selection */
+#define		AT91_SPI_MODFDIS	(1    <<  4)		/* Mode Fault Detection */
+#define		AT91_SPI_LLB		(1    <<  7)		/* Local Loopback Enable */
+#define		AT91_SPI_PCS		(0xf  << 16)		/* Peripheral Chip Select */
+#define		AT91_SPI_DLYBCS		(0xff << 24)		/* Delay Between Chip Selects */
+
+#define AT91_SPI_RDR		0x08			/* Receive Data Register */
+#define		AT91_SPI_RD		(0xffff <<  0)		/* Receive Data */
+#define		AT91_SPI_PCS		(0xf	<< 16)		/* Peripheral Chip Select */
+
+#define AT91_SPI_TDR		0x0c			/* Transmit Data Register */
+#define		AT91_SPI_TD		(0xffff <<  0)		/* Transmit Data */
+#define		AT91_SPI_PCS		(0xf	<< 16)		/* Peripheral Chip Select */
+#define		AT91_SPI_LASTXFER	(1	<< 24)		/* Last Transfer [SAM9261 only] */
+
+#define AT91_SPI_SR		0x10			/* Status Register */
+#define		AT91_SPI_RDRF		(1 <<  0)		/* Receive Data Register Full */
+#define		AT91_SPI_TDRE		(1 <<  1)		/* Transmit Data Register Full */
+#define		AT91_SPI_MODF		(1 <<  2)		/* Mode Fault Error */
+#define		AT91_SPI_OVRES		(1 <<  3)		/* Overrun Error Status */
+#define		AT91_SPI_ENDRX		(1 <<  4)		/* End of RX buffer */
+#define		AT91_SPI_ENDTX		(1 <<  5)		/* End of TX buffer */
+#define		AT91_SPI_RXBUFF		(1 <<  6)		/* RX Buffer Full */
+#define		AT91_SPI_TXBUFE		(1 <<  7)		/* TX Buffer Empty */
+#define		AT91_SPI_NSSR		(1 <<  8)		/* NSS Rising [SAM9261 only] */
+#define		AT91_SPI_TXEMPTY	(1 <<  9)		/* Transmission Register Empty [SAM9261 only] */
+#define		AT91_SPI_SPIENS		(1 << 16)		/* SPI Enable Status */
+
+#define AT91_SPI_IER		0x14			/* Interrupt Enable Register */
+#define AT91_SPI_IDR		0x18			/* Interrupt Disable Register */
+#define AT91_SPI_IMR		0x1c			/* Interrupt Mask Register */
+
+#define AT91_SPI_CSR(n)		(0x30 + ((n) * 4))	/* Chip Select Registers 0-3 */
+#define		AT91_SPI_CPOL		(1    <<  0)		/* Clock Polarity */
+#define		AT91_SPI_NCPHA		(1    <<  1)		/* Clock Phase */
+#define		AT91_SPI_CSAAT		(1    <<  3)		/* Chip Select Active After Transfer [SAM9261 only] */
+#define		AT91_SPI_BITS		(0xf  <<  4)		/* Bits Per Transfer */
+#define			AT91_SPI_BITS_8		(0 << 4)
+#define			AT91_SPI_BITS_9		(1 << 4)
+#define			AT91_SPI_BITS_10	(2 << 4)
+#define			AT91_SPI_BITS_11	(3 << 4)
+#define			AT91_SPI_BITS_12	(4 << 4)
+#define			AT91_SPI_BITS_13	(5 << 4)
+#define			AT91_SPI_BITS_14	(6 << 4)
+#define			AT91_SPI_BITS_15	(7 << 4)
+#define			AT91_SPI_BITS_16	(8 << 4)
+#define		AT91_SPI_SCBR		(0xff <<  8)		/* Serial Clock Baud Rate */
+#define		AT91_SPI_DLYBS		(0xff << 16)		/* Delay before SPCK */
+#define		AT91_SPI_DLYBCT		(0xff << 24)		/* Delay between Consecutive Transfers */
+
+#endif
diff --git a/include/asm-arm/arch-at91rm9200/at91rm9200_ssc.h b/include/asm-arm/arch-at91rm9200/at91rm9200_ssc.h
new file mode 100644
index 000000000..ac8802271
--- /dev/null
+++ b/include/asm-arm/arch-at91rm9200/at91rm9200_ssc.h
@@ -0,0 +1,96 @@
+/*
+ * include/asm-arm/arch-at91rm9200/at91rm9200_ssc.h
+ *
+ * Copyright (C) SAN People
+ *
+ * Serial Synchronous Controller (SSC) 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 AT91RM9200_SSC_H
+#define AT91RM9200_SSC_H
+
+#define AT91_SSC_CR		0x00	/* Control Register */
+#define		AT91_SSC_RXEN		(1 <<  0)	/* Receive Enable */
+#define		AT91_SSC_RXDIS		(1 <<  1)	/* Receive Disable */
+#define		AT91_SSC_TXEN		(1 <<  8)	/* Transmit Enable */
+#define		AT91_SSC_TXDIS		(1 <<  9)	/* Transmit Disable */
+#define		AT91_SSC_SWRST		(1 << 15)	/* Software Reset */
+
+#define AT91_SSC_CMR		0x04	/* Clock Mode Register */
+#define		AT91_SSC_CMR_DIV	(0xfff << 0)	/* Clock Divider */
+
+#define AT91_SSC_RCMR		0x10	/* Receive Clock Mode Register */
+#define		AT91_SSC_CKS		(3    <<  0)	/* Clock Selection */
+#define			AT91_SSC_CKS_DIV		(0 << 0)
+#define			AT91_SSC_CKS_CLOCK		(1 << 0)
+#define			AT91_SSC_CKS_PIN		(2 << 0)
+#define		AT91_SSC_CKO		(7    <<  2)	/* Clock Output Mode Selection */
+#define			AT91_SSC_CKO_NONE		(0 << 2)
+#define			AT91_SSC_CKO_CONTINUOUS		(1 << 2)
+#define		AT91_SSC_CKI		(1    <<  5)	/* Clock Inversion */
+#define			AT91_SSC_CKI_FALLING		(0 << 5)
+#define			AT91_SSC_CK_RISING		(1 << 5)
+#define		AT91_SSC_START		(0xf  <<  8)	/* Start Selection */
+#define			AT91_SSC_START_CONTINUOUS	(0 << 8)
+#define			AT91_SSC_START_TX_RX		(1 << 8)
+#define			AT91_SSC_START_LOW_RF		(2 << 8)
+#define			AT91_SSC_START_HIGH_RF		(3 << 8)
+#define			AT91_SSC_START_FALLING_RF	(4 << 8)
+#define			AT91_SSC_START_RISING_RF	(5 << 8)
+#define			AT91_SSC_START_LEVEL_RF		(6 << 8)
+#define			AT91_SSC_START_EDGE_RF		(7 << 8)
+#define		AT91_SSC_STTDLY		(0xff << 16)	/* Start Delay */
+#define		AT91_SSC_PERIOD		(0xff << 24)	/* Period Divider Selection */
+
+#define AT91_SSC_RFMR		0x14	/* Receive Frame Mode Register */
+#define		AT91_SSC_DATALEN	(0x1f <<  0)	/* Data Length */
+#define		AT91_SSC_LOOP		(1    <<  5)	/* Loop Mode */
+#define		AT91_SSC_MSBF		(1    <<  7)	/* Most Significant Bit First */
+#define		AT91_SSC_DATNB		(0xf  <<  8)	/* Data Number per Frame */
+#define		AT91_SSC_FSLEN		(0xf  << 16)	/* Frame Sync Length */
+#define		AT91_SSC_FSOS		(7    << 20)	/* Frame Sync Output Selection */
+#define			AT91_SSC_FSOS_NONE		(0 << 20)
+#define			AT91_SSC_FSOS_NEGATIVE		(1 << 20)
+#define			AT91_SSC_FSOS_POSITIVE		(2 << 20)
+#define			AT91_SSC_FSOS_LOW		(3 << 20)
+#define			AT91_SSC_FSOS_HIGH		(4 << 20)
+#define			AT91_SSC_FSOS_TOGGLE		(5 << 20)
+#define		AT91_SSC_FSEDGE		(1    << 24)	/* Frame Sync Edge Detection */
+#define			AT91_SSC_FSEDGE_POSITIVE	(0 << 24)
+#define			AT91_SSC_FSEDGE_NEGATIVE	(1 << 24)
+
+#define AT91_SSC_TCMR		0x18	/* Transmit Clock Mode Register */
+#define AT91_SSC_TFMR		0x1c	/* Transmit Fram Mode Register */
+#define		AT91_SSC_DATDEF		(1 <<  5)	/* Data Default Value */
+#define		AT91_SSC_FSDEN		(1 << 23)	/* Frame Sync Data Enable */
+
+#define AT91_SSC_RHR		0x20	/* Receive Holding Register */
+#define AT91_SSC_THR		0x24	/* Transmit Holding Register */
+#define AT91_SSC_RSHR		0x30	/* Receive Sync Holding Register */
+#define AT91_SSC_TSHR		0x34	/* Transmit Sync Holding Register */
+
+#define AT91_SSC_SR		0x40	/* Status Register */
+#define		AT91_SSC_TXRDY		(1 <<  0)	/* Transmit Ready */
+#define		AT91_SSC_TXEMPTY	(1 <<  1)	/* Transmit Empty */
+#define		AT91_SSC_ENDTX		(1 <<  2)	/* End of Transmission */
+#define		AT91_SSC_TXBUFE		(1 <<  3)	/* Transmit Buffer Empty */
+#define		AT91_SSC_RXRDY		(1 <<  4)	/* Receive Ready */
+#define		AT91_SSC_OVRUN		(1 <<  5)	/* Receive Overrun */
+#define		AT91_SSC_ENDRX		(1 <<  6)	/* End of Reception */
+#define		AT91_SSC_RXBUFF		(1 <<  7)	/* Receive Buffer Full */
+#define		AT91_SSC_TXSYN		(1 << 10)	/* Transmit Sync */
+#define		AT91_SSC_RXSYN		(1 << 11)	/* Receive Sync */
+#define		AT91_SSC_TXENA		(1 << 16)	/* Transmit Enable */
+#define		AT91_SSC_RXENA		(1 << 17)	/* Receive Enable */
+
+#define AT91_SSC_IER		0x44	/* Interrupt Enable Register */
+#define AT91_SSC_IDR		0x48	/* Interrupt Disable Register */
+#define AT91_SSC_IMR		0x4c	/* Interrupt Mask Register */
+
+#endif
diff --git a/include/asm-arm/arch-at91rm9200/at91rm9200_tc.h b/include/asm-arm/arch-at91rm9200/at91rm9200_tc.h
new file mode 100644
index 000000000..f4da752bb
--- /dev/null
+++ b/include/asm-arm/arch-at91rm9200/at91rm9200_tc.h
@@ -0,0 +1,146 @@
+/*
+ * include/asm-arm/arch-at91rm9200/at91rm9200_tc.h
+ *
+ * Copyright (C) SAN People
+ *
+ * Timer/Counter Unit (TC) 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 AT91RM9200_TC_H
+#define AT91RM9200_TC_H
+
+#define AT91_TC_BCR		0xc0		/* TC Block Control Register */
+#define		AT91_TC_SYNC		(1 << 0)	/* Synchro Command */
+
+#define AT91_TC_BMR		0xc4		/* TC Block Mode Register */
+#define		AT91_TC_TC0XC0S		(3 << 0)	/* External Clock Signal 0 Selection */
+#define			AT91_TC_TC0XC0S_TCLK0		(0 << 0)
+#define			AT91_TC_TC0XC0S_NONE		(1 << 0)
+#define			AT91_TC_TC0XC0S_TIOA1		(2 << 0)
+#define			AT91_TC_TC0XC0S_TIOA2		(3 << 0)
+#define		AT91_TC_TC1XC1S		(3 << 2)	/* External Clock Signal 1 Selection */
+#define			AT91_TC_TC1XC1S_TCLK1		(0 << 2)
+#define			AT91_TC_TC1XC1S_NONE		(1 << 2)
+#define			AT91_TC_TC1XC1S_TIOA0		(2 << 2)
+#define			AT91_TC_TC1XC1S_TIOA2		(3 << 2)
+#define		AT91_TC_TC2XC2S		(3 << 4)	/* External Clock Signal 2 Selection */
+#define			AT91_TC_TC2XC2S_TCLK2		(0 << 4)
+#define			AT91_TC_TC2XC2S_NONE		(1 << 4)
+#define			AT91_TC_TC2XC2S_TIOA0		(2 << 4)
+#define			AT91_TC_TC2XC2S_TIOA1		(3 << 4)
+
+
+#define AT91_TC_CCR		0x00		/* Channel Control Register */
+#define		AT91_TC_CLKEN		(1 << 0)	/* Counter Clock Enable Command */
+#define		AT91_TC_CLKDIS		(1 << 1)	/* Counter CLock Disable Command */
+#define		AT91_TC_SWTRG		(1 << 2)	/* Software Trigger Command */
+
+#define AT91_TC_CMR		0x04		/* Channel Mode Register */
+#define		AT91_TC_TCCLKS		(7 << 0)	/* Capture/Waveform Mode: Clock Selection */
+#define			AT91_TC_TIMER_CLOCK1		(0 << 0)
+#define			AT91_TC_TIMER_CLOCK2		(1 << 0)
+#define			AT91_TC_TIMER_CLOCK3		(2 << 0)
+#define			AT91_TC_TIMER_CLOCK4		(3 << 0)
+#define			AT91_TC_TIMER_CLOCK5		(4 << 0)
+#define			AT91_TC_XC0			(5 << 0)
+#define			AT91_TC_XC1			(6 << 0)
+#define			AT91_TC_XC2			(7 << 0)
+#define		AT91_TC_CLKI		(1 << 3)	/* Capture/Waveform Mode: Clock Invert */
+#define		AT91_TC_BURST		(3 << 4)	/* Capture/Waveform Mode: Burst Signal Selection */
+#define		AT91_TC_LDBSTOP		(1 << 6)	/* Capture Mode: Counter Clock Stopped with TB Loading */
+#define		AT91_TC_LDBDIS		(1 << 7)	/* Capture Mode: Counter Clock Disable with RB Loading */
+#define		AT91_TC_ETRGEDG		(3 << 8)	/* Capture Mode: External Trigger Edge Selection */
+#define		AT91_TC_ABETRG		(1 << 10)	/* Capture Mode: TIOA or TIOB External Trigger Selection */
+#define		AT91_TC_CPCTRG		(1 << 14)	/* Capture Mode: RC Compare Trigger Enable */
+#define		AT91_TC_WAVE		(1 << 15)	/* Capture/Waveform mode */
+#define		AT91_TC_LDRA		(3 << 16)	/* Capture Mode: RA Loading Selection */
+#define		AT91_TC_LDRB		(3 << 18)	/* Capture Mode: RB Loading Selection */
+
+#define		AT91_TC_CPCSTOP		(1 <<  6)	/* Waveform Mode: Counter Clock Stopped with RC Compare */
+#define		AT91_TC_CPCDIS		(1 <<  7)	/* Waveform Mode: Counter Clock Disable with RC Compare */
+#define		AT91_TC_EEVTEDG		(3 <<  8)	/* Waveform Mode: External Event Edge Selection */
+#define			AT91_TC_EEVTEDG_NONE		(0 << 8)
+#define			AT91_TC_EEVTEDG_RISING		(1 << 8)
+#define			AT91_TC_EEVTEDG_FALLING		(2 << 8)
+#define			AT91_TC_EEVTEDG_BOTH		(3 << 8)
+#define		AT91_TC_EEVT		(3 << 10)	/* Waveform Mode: External Event Selection */
+#define			AT91_TC_EEVT_TIOB		(0 << 10)
+#define			AT91_TC_EEVT_XC0		(1 << 10)
+#define			AT91_TC_EEVT_XC1		(2 << 10)
+#define			AT91_TC_EEVT_XC2		(3 << 10)
+#define		AT91_TC_ENETRG		(1 << 12)	/* Waveform Mode: External Event Trigger Enable */
+#define		AT91_TC_WAVESEL		(3 << 13)	/* Waveform Mode: Waveform Selection */
+#define			AT91_TC_WAVESEL_UP		(0 << 13)
+#define			AT91_TC_WAVESEL_UP_AUTO		(2 << 13)
+#define			AT91_TC_WAVESEL_UPDOWN		(1 << 13)
+#define			AT91_TC_WAVESEL_UPDOWN_AUTO	(3 << 13)
+#define		AT91_TC_ACPA		(3 << 16)	/* Waveform Mode: RA Compare Effect on TIOA */
+#define			AT91_TC_ACPA_NONE		(0 << 16)
+#define			AT91_TC_ACPA_SET		(1 << 16)
+#define			AT91_TC_ACPA_CLEAR		(2 << 16)
+#define			AT91_TC_ACPA_TOGGLE		(3 << 16)
+#define		AT91_TC_ACPC		(3 << 18)	/* Waveform Mode: RC Compre Effect on TIOA */
+#define			AT91_TC_ACPC_NONE		(0 << 18)
+#define			AT91_TC_ACPC_SET		(1 << 18)
+#define			AT91_TC_ACPC_CLEAR		(2 << 18)
+#define			AT91_TC_ACPC_TOGGLE		(3 << 18)
+#define		AT91_TC_AEEVT		(3 << 20)	/* Waveform Mode: External Event Effect on TIOA */
+#define			AT91_TC_AEEVT_NONE		(0 << 20)
+#define			AT91_TC_AEEVT_SET		(1 << 20)
+#define			AT91_TC_AEEVT_CLEAR		(2 << 20)
+#define			AT91_TC_AEEVT_TOGGLE		(3 << 20)
+#define		AT91_TC_ASWTRG		(3 << 22)	/* Waveform Mode: Software Trigger Effect on TIOA */
+#define			AT91_TC_ASWTRG_NONE		(0 << 22)
+#define			AT91_TC_ASWTRG_SET		(1 << 22)
+#define			AT91_TC_ASWTRG_CLEAR		(2 << 22)
+#define			AT91_TC_ASWTRG_TOGGLE		(3 << 22)
+#define		AT91_TC_BCPB		(3 << 24)	/* Waveform Mode: RB Compare Effect on TIOB */
+#define			AT91_TC_BCPB_NONE		(0 << 24)
+#define			AT91_TC_BCPB_SET		(1 << 24)
+#define			AT91_TC_BCPB_CLEAR		(2 << 24)
+#define			AT91_TC_BCPB_TOGGLE		(3 << 24)
+#define		AT91_TC_BCPC		(3 << 26)	/* Waveform Mode: RC Compare Effect on TIOB */
+#define			AT91_TC_BCPC_NONE		(0 << 26)
+#define			AT91_TC_BCPC_SET		(1 << 26)
+#define			AT91_TC_BCPC_CLEAR		(2 << 26)
+#define			AT91_TC_BCPC_TOGGLE		(3 << 26)
+#define		AT91_TC_BEEVT		(3 << 28)	/* Waveform Mode: External Event Effect on TIOB */
+#define			AT91_TC_BEEVT_NONE		(0 << 28)
+#define			AT91_TC_BEEVT_SET		(1 << 28)
+#define			AT91_TC_BEEVT_CLEAR		(2 << 28)
+#define			AT91_TC_BEEVT_TOGGLE		(3 << 28)
+#define		AT91_TC_BSWTRG		(3 << 30)	/* Waveform Mode: Software Trigger Effect on TIOB */
+#define			AT91_TC_BSWTRG_NONE		(0 << 30)
+#define			AT91_TC_BSWTRG_SET		(1 << 30)
+#define			AT91_TC_BSWTRG_CLEAR		(2 << 30)
+#define			AT91_TC_BSWTRG_TOGGLE		(3 << 30)
+
+#define AT91_TC_CV		0x10		/* Counter Value */
+#define AT91_TC_RA		0x14		/* Register A */
+#define AT91_TC_RB		0x18		/* Register B */
+#define AT91_TC_RC		0x1c		/* Register C */
+
+#define AT91_TC_SR		0x20		/* Status Register */
+#define		AT91_TC_COVFS		(1 <<  0)	/* Counter Overflow Status */
+#define		AT91_TC_LOVRS		(1 <<  1)	/* Load Overrun Status */
+#define		AT91_TC_CPAS		(1 <<  2)	/* RA Compare Status */
+#define		AT91_TC_CPBS		(1 <<  3)	/* RB Compare Status */
+#define		AT91_TC_CPCS		(1 <<  4)	/* RC Compare Status */
+#define		AT91_TC_LDRAS		(1 <<  5)	/* RA Loading Status */
+#define		AT91_TC_LDRBS		(1 <<  6)	/* RB Loading Status */
+#define		AT91_TC_ETRGS		(1 <<  7)	/* External Trigger Status */
+#define		AT91_TC_CLKSTA		(1 << 16)	/* Clock Enabling Status */
+#define		AT91_TC_MTIOA		(1 << 17)	/* TIOA Mirror */
+#define		AT91_TC_MTIOB		(1 << 18)	/* TIOB Mirror */
+
+#define AT91_TC_IER		0x24		/* Interrupt Enable Register */
+#define AT91_TC_IDR		0x28		/* Interrupt Disable Register */
+#define AT91_TC_IMR		0x2c		/* Interrupt Mask Register */
+
+#endif
diff --git a/include/asm-arm/arch-at91rm9200/at91rm9200_udp.h b/include/asm-arm/arch-at91rm9200/at91rm9200_udp.h
new file mode 100644
index 000000000..951e3f61c
--- /dev/null
+++ b/include/asm-arm/arch-at91rm9200/at91rm9200_udp.h
@@ -0,0 +1,77 @@
+/*
+ * include/asm-arm/arch-at91rm9200/at91rm9200_udp.h
+ *
+ * Copyright (C) 2005 Ivan Kokshaysky
+ * Copyright (C) SAN People
+ *
+ * USB Device Port (UDP) 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 AT91RM9200_UDP_H
+#define AT91RM9200_UDP_H
+
+#define AT91_UDP_FRM_NUM	0x00		/* Frame Number Register */
+#define		AT91_UDP_NUM		(0x7ff <<  0)		/* Frame Number */
+#define		AT91_UDP_FRM_ERR	(1     << 16)		/* Frame Error */
+#define		AT91_UDP_FRM_OK		(1     << 17)		/* Frame OK */
+
+#define AT91_UDP_GLB_STAT	0x04		/* Global State Register */
+#define		AT91_UDP_FADDEN		(1 <<  0)		/* Function Address Enable */
+#define		AT91_UDP_CONFG		(1 <<  1)		/* Configured */
+#define		AT91_UDP_ESR		(1 <<  2)		/* Enable Send Resume */
+#define		AT91_UDP_RSMINPR	(1 <<  3)		/* Resume has been sent */
+#define		AT91_UDP_RMWUPE		(1 <<  4)		/* Remote Wake Up Enable */
+
+#define AT91_UDP_FADDR		0x08		/* Function Address Register */
+#define		AT91_UDP_FADD		(0x7f << 0)		/* Function Address Value */
+#define		AT91_UDP_FEN		(1    << 8)		/* Function Enable */
+
+#define AT91_UDP_IER		0x10		/* Interrupt Enable Register */
+#define AT91_UDP_IDR		0x14		/* Interrupt Disable Register */
+#define AT91_UDP_IMR		0x18		/* Interrupt Mask Register */
+
+#define AT91_UDP_ISR		0x1c		/* Interrupt Status Register */
+#define		AT91_UDP_EP(n)		(1 << (n))		/* Endpoint Interrupt Status */
+#define		AT91_UDP_RXSUSP		(1 <<  8)		/* USB Suspend Interrupt Status */
+#define		AT91_UDP_RXRSM		(1 <<  9)		/* USB Resume Interrupt Status */
+#define		AT91_UDP_EXTRSM		(1 << 10)		/* External Resume Interrupt Status */
+#define		AT91_UDP_SOFINT		(1 << 11)		/* Start of Frame Interrupt Status */
+#define		AT91_UDP_ENDBUSRES	(1 << 12)		/* End of Bus Reset Interrpt Status */
+#define		AT91_UDP_WAKEUP		(1 << 13)		/* USB Wakeup Interrupt Status */
+
+#define AT91_UDP_ICR		0x20		/* Interrupt Clear Register */
+#define AT91_UDP_RST_EP		0x28		/* Reset Endpoint Register */
+
+#define AT91_UDP_CSR(n)		(0x30 + ((n) * 4))	/* Endpoint Control/Status Registers 0-7 */
+#define		AT91_UDP_TXCOMP		(1 <<  0)		/* Generates IN packet with data previously written in DPR */
+#define		AT91_UDP_RX_DATA_BK0	(1 <<  1)		/* Receive Data Bank 0 */
+#define		AT91_UDP_RXSETUP	(1 <<  2)		/* Send STALL to the host */
+#define		AT91_UDP_STALLSENT	(1 <<  3)		/* Stall Sent / Isochronous error (Isochronous endpoints) */
+#define		AT91_UDP_TXPKTRDY	(1 <<  4)		/* Transmit Packet Ready */
+#define		AT91_UDP_FORCESTALL	(1 <<  5)		/* Force Stall */
+#define		AT91_UDP_RX_DATA_BK1	(1 <<  6)		/* Receive Data Bank 1 */
+#define		AT91_UDP_DIR		(1 <<  7)		/* Transfer Direction */
+#define		AT91_UDP_EPTYPE		(7 <<  8)		/* Endpoint Type */
+#define			AT91_UDP_EPTYPE_CTRL		(0 <<  8)
+#define			AT91_UDP_EPTYPE_ISO_OUT		(1 <<  8)
+#define			AT91_UDP_EPTYPE_BULK_OUT	(2 <<  8)
+#define			AT91_UDP_EPTYPE_INT_OUT		(3 <<  8)
+#define			AT91_UDP_EPTYPE_ISO_IN		(5 <<  8)
+#define			AT91_UDP_EPTYPE_BULK_IN		(6 <<  8)
+#define			AT91_UDP_EPTYPE_INT_IN		(7 <<  8)
+#define		AT91_UDP_DTGLE		(1 << 11)		/* Data Toggle */
+#define		AT91_UDP_EPEDS		(1 << 15)		/* Endpoint Enable/Disable */
+#define		AT91_UDP_RXBYTECNT	(0x7ff << 16)		/* Number of bytes in FIFO */
+
+#define AT91_UDP_FDR(n)		(0x50 + ((n) * 4))	/* Endpoint FIFO Data Registers 0-7 */
+
+#define AT91_UDP_TXVC		0x74		/* Transceiver Control Register */
+#define		AT91_UDP_TXVC_TXVDIS	(1 << 8)		/* Transceiver Disable */
+
+#endif
diff --git a/include/asm-arm/arch-lh7a40x/clocks.h b/include/asm-arm/arch-lh7a40x/clocks.h
new file mode 100644
index 000000000..7d0ba18ad
--- /dev/null
+++ b/include/asm-arm/arch-lh7a40x/clocks.h
@@ -0,0 +1,18 @@
+/* include/asm-arm/arch-lh7a40x/clocks.h
+ *
+ *  Copyright (C) 2004 Marc Singer
+ *
+ *  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_CLOCKS_H
+#define __ASM_ARCH_CLOCKS_H
+
+unsigned int fclkfreq_get (void);
+unsigned int hclkfreq_get (void);
+unsigned int pclkfreq_get (void);
+
+#endif  /* _ASM_ARCH_CLOCKS_H */
diff --git a/include/asm-arm/arch-lh7a40x/ssp.h b/include/asm-arm/arch-lh7a40x/ssp.h
new file mode 100644
index 000000000..132b1c4d5
--- /dev/null
+++ b/include/asm-arm/arch-lh7a40x/ssp.h
@@ -0,0 +1,71 @@
+/* ssp.h
+     $Id$
+
+   written by Marc Singer
+   6 Dec 2004
+
+   Copyright (C) 2004 Marc Singer
+
+   -----------
+   DESCRIPTION
+   -----------
+
+   This SSP header is available throughout the kernel, for this
+   machine/architecture, because drivers that use it may be dispersed.
+
+   This file was cloned from the 7952x implementation.  It would be
+   better to share them, but we're taking an easier approach for the
+   time being.
+
+*/
+
+#if !defined (__SSP_H__)
+#    define   __SSP_H__
+
+/* ----- Includes */
+
+/* ----- Types */
+
+struct ssp_driver {
+	int  (*init)		(void);
+	void (*exit)		(void);
+	void (*acquire)		(void);
+	void (*release)		(void);
+	int  (*configure)	(int device, int mode, int speed,
+				 int frame_size_write, int frame_size_read);
+	void (*chip_select)	(int enable);
+	void (*set_callbacks)   (void* handle,
+				 irqreturn_t (*callback_tx)(void*),
+				 irqreturn_t (*callback_rx)(void*));
+	void (*enable)		(void);
+	void (*disable)		(void);
+//	int  (*save_state)	(void*);
+//	void (*restore_state)	(void*);
+	int  (*read)		(void);
+	int  (*write)		(u16 data);
+	int  (*write_read)	(u16 data);
+	void (*flush)		(void);
+	void (*write_async)	(void* pv, size_t cb);
+	size_t (*write_pos)	(void);
+};
+
+	/* These modes are only available on the LH79524 */
+#define SSP_MODE_SPI		(1)
+#define SSP_MODE_SSI		(2)
+#define SSP_MODE_MICROWIRE	(3)
+#define SSP_MODE_I2S		(4)
+
+	/* CPLD SPI devices */
+#define DEVICE_EEPROM	0	/* Configuration eeprom */
+#define DEVICE_MAC	1	/* MAC eeprom (LPD79524) */
+#define DEVICE_CODEC	2	/* Audio codec */
+#define DEVICE_TOUCH	3	/* Touch screen (LPD79520) */
+
+/* ----- Globals */
+
+/* ----- Prototypes */
+
+//extern struct ssp_driver lh79520_i2s_driver;
+extern struct ssp_driver lh7a400_cpld_ssp_driver;
+
+#endif  /* __SSP_H__ */
diff --git a/include/asm-arm/arch-netx/debug-macro.S b/include/asm-arm/arch-netx/debug-macro.S
new file mode 100644
index 000000000..a940d0e80
--- /dev/null
+++ b/include/asm-arm/arch-netx/debug-macro.S
@@ -0,0 +1,38 @@
+/* linux/include/asm-arm/arch-netx/debug-macro.S
+ *
+ * Debugging macro include header
+ *
+ *  Copyright (C) 1994-1999 Russell King
+ *  Moved from linux/arch/arm/kernel/debug.S by Ben Dooks
+ *
+ * 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 "hardware.h"
+
+		.macro	addruart,rx
+		mrc	p15, 0, \rx, c1, c0
+		tst	\rx, #1			@ MMU enabled?
+		moveq	\rx, #0x00100000		@ physical
+		movne	\rx, #io_p2v(0x00100000)	@ virtual
+		orr	\rx, \rx, #0x00000a00
+		.endm
+
+		.macro	senduart,rd,rx
+		str	\rd, [\rx, #0]
+		.endm
+
+		.macro	busyuart,rd,rx
+1002:		ldr	\rd, [\rx, #0x18]
+		tst	\rd, #(1 << 3)
+		bne	1002b
+		.endm
+
+		.macro	waituart,rd,rx
+1001:		ldr	\rd, [\rx, #0x18]
+		tst	\rd, #(1 << 3)
+		bne	1001b
+		.endm
diff --git a/include/asm-arm/arch-netx/dma.h b/include/asm-arm/arch-netx/dma.h
new file mode 100644
index 000000000..4eda5feed
--- /dev/null
+++ b/include/asm-arm/arch-netx/dma.h
@@ -0,0 +1,21 @@
+/*
+ *  linux/include/asm-arm/arch-netx/dma.h
+ *
+ * Copyright (C) 2005 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix
+ *
+ * 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
+ */
+
+#define MAX_DMA_CHANNELS 0
+#define MAX_DMA_ADDRESS ~0
diff --git a/include/asm-arm/arch-netx/entry-macro.S b/include/asm-arm/arch-netx/entry-macro.S
new file mode 100644
index 000000000..658df4d60
--- /dev/null
+++ b/include/asm-arm/arch-netx/entry-macro.S
@@ -0,0 +1,35 @@
+/*
+ * include/asm-arm/arch-netx/entry-macro.S
+ *
+ * Low-level IRQ helper macros for Hilscher netX based platforms
+ *
+ * Copyright (C) 2005 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix
+ *
+ * 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 <asm/hardware.h>
+
+		.macro  disable_fiq
+		.endm
+
+		.macro  get_irqnr_and_base, irqnr, irqstat, base, tmp
+		mov	\base, #io_p2v(0x00100000)
+		add	\base, \base, #0x000ff000
+
+		ldr	\irqstat, [\base, #0]
+		clz	\irqnr, \irqstat
+		rsb     \irqnr, \irqnr, #31
+		cmp	\irqstat, #0
+		.endm
+
diff --git a/include/asm-arm/arch-netx/eth.h b/include/asm-arm/arch-netx/eth.h
new file mode 100644
index 000000000..643c90ef8
--- /dev/null
+++ b/include/asm-arm/arch-netx/eth.h
@@ -0,0 +1,27 @@
+/*
+ * include/asm-arm/arch-netx/eth.h
+ *
+ * Copyright (c) 2005 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix
+ *
+ * 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 ASMARM_ARCH_ETH_H
+#define ASMARM_ARCH_ETH_H
+
+struct netxeth_platform_data {
+	unsigned int xcno;	/* number of xmac/xpec engine this eth uses */
+};
+
+#endif
diff --git a/include/asm-arm/arch-netx/hardware.h b/include/asm-arm/arch-netx/hardware.h
new file mode 100644
index 000000000..7786c4545
--- /dev/null
+++ b/include/asm-arm/arch-netx/hardware.h
@@ -0,0 +1,39 @@
+/*
+ * include/asm-arm/arch-netx/hardware.h
+ *
+ * Copyright (C) 2005 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix
+ *
+ * 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_ARCH_HARDWARE_H
+#define __ASM_ARCH_HARDWARE_H
+
+#define NETX_IO_PHYS	0x00100000
+#define NETX_IO_VIRT	0xe0000000
+#define NETX_IO_SIZE	0x00100000
+
+#define SRAM_INTERNAL_PHYS_0 0x00000
+#define SRAM_INTERNAL_PHYS_1 0x08000
+#define SRAM_INTERNAL_PHYS_2 0x10000
+#define SRAM_INTERNAL_PHYS_3 0x18000
+#define SRAM_INTERNAL_PHYS(no) ((no) * 0x8000)
+
+#define XPEC_MEM_SIZE 0x4000
+#define XMAC_MEM_SIZE 0x1000
+#define SRAM_MEM_SIZE 0x8000
+
+#define io_p2v(x) ((x) - NETX_IO_PHYS + NETX_IO_VIRT)
+#define io_v2p(x) ((x) - NETX_IO_VIRT + NETX_IO_PHYS)
+
+#endif
diff --git a/include/asm-arm/arch-netx/io.h b/include/asm-arm/arch-netx/io.h
new file mode 100644
index 000000000..a7a53f801
--- /dev/null
+++ b/include/asm-arm/arch-netx/io.h
@@ -0,0 +1,28 @@
+/*
+ *  linux/include/asm-arm/arch-netx/io.h
+ *
+ * Copyright (C) 2005 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix
+ *
+ * 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_ARCH_IO_H
+#define __ASM_ARM_ARCH_IO_H
+
+#define IO_SPACE_LIMIT 0xffffffff
+
+#define __io(a)         ((void __iomem *)(a))
+#define __mem_pci(a)            (a)
+
+#endif
diff --git a/include/asm-arm/arch-netx/irqs.h b/include/asm-arm/arch-netx/irqs.h
new file mode 100644
index 000000000..a487dc6e2
--- /dev/null
+++ b/include/asm-arm/arch-netx/irqs.h
@@ -0,0 +1,70 @@
+/*
+ * include/asm-arm/arch-netx/irqs.h
+ *
+ * Copyright (C) 2005 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix
+ *
+ * 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
+ */
+
+#define NETX_IRQ_VIC_START   0
+#define NETX_IRQ_SOFTINT     0
+#define NETX_IRQ_TIMER0      1
+#define NETX_IRQ_TIMER1      2
+#define NETX_IRQ_TIMER2      3
+#define NETX_IRQ_SYSTIME_NS  4
+#define NETX_IRQ_SYSTIME_S   5
+#define NETX_IRQ_GPIO_15     6
+#define NETX_IRQ_WATCHDOG    7
+#define NETX_IRQ_UART0       8
+#define NETX_IRQ_UART1       9
+#define NETX_IRQ_UART2      10
+#define NETX_IRQ_USB        11
+#define NETX_IRQ_SPI        12
+#define NETX_IRQ_I2C        13
+#define NETX_IRQ_LCD        14
+#define NETX_IRQ_HIF        15
+#define NETX_IRQ_GPIO_0_14  16
+#define NETX_IRQ_XPEC0      17
+#define NETX_IRQ_XPEC1      18
+#define NETX_IRQ_XPEC2      19
+#define NETX_IRQ_XPEC3      20
+#define NETX_IRQ_XPEC(no)   (17 + (no))
+#define NETX_IRQ_MSYNC0     21
+#define NETX_IRQ_MSYNC1     22
+#define NETX_IRQ_MSYNC2     23
+#define NETX_IRQ_MSYNC3     24
+#define NETX_IRQ_IRQ_PHY    25
+#define NETX_IRQ_ISO_AREA   26
+/* int 27 is reserved */
+/* int 28 is reserved */
+#define NETX_IRQ_TIMER3     29
+#define NETX_IRQ_TIMER4     30
+/* int 31 is reserved */
+
+#define NETX_IRQS 32
+
+/* for multiplexed irqs on gpio 0..14 */
+#define NETX_IRQ_GPIO(x) (NETX_IRQS + (x))
+#define NETX_IRQ_GPIO_LAST NETX_IRQ_GPIO(14)
+
+/* Host interface interrupts */
+#define NETX_IRQ_HIF_CHAINED(x)    (NETX_IRQ_GPIO_LAST + 1 + (x))
+#define NETX_IRQ_HIF_PIO35         NETX_IRQ_HIF_CHAINED(0)
+#define NETX_IRQ_HIF_PIO36         NETX_IRQ_HIF_CHAINED(1)
+#define NETX_IRQ_HIF_PIO40         NETX_IRQ_HIF_CHAINED(2)
+#define NETX_IRQ_HIF_PIO47         NETX_IRQ_HIF_CHAINED(3)
+#define NETX_IRQ_HIF_PIO72         NETX_IRQ_HIF_CHAINED(4)
+#define NETX_IRQ_HIF_LAST          NETX_IRQ_HIF_CHAINED(4)
+
+#define NR_IRQS (NETX_IRQ_HIF_LAST + 1)
diff --git a/include/asm-arm/arch-netx/memory.h b/include/asm-arm/arch-netx/memory.h
new file mode 100644
index 000000000..6d8d2df3e
--- /dev/null
+++ b/include/asm-arm/arch-netx/memory.h
@@ -0,0 +1,36 @@
+/*
+ *  linux/include/asm-arm/arch-netx/memory.h
+ *
+ * Copyright (C) 2005 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix
+ *
+ * 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_ARCH_MEMORY_H
+#define __ASM_ARCH_MEMORY_H
+
+#define PHYS_OFFSET UL(0x80000000)
+
+/*
+ * Virtual view <-> DMA view memory address translations
+ * virt_to_bus: Used to translate the virtual address to an
+ *              address suitable to be passed to set_dma_addr
+ * bus_to_virt: Used to convert an address for DMA operations
+ *              to an address that the kernel can use.
+ */
+#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-netx/netx-regs.h b/include/asm-arm/arch-netx/netx-regs.h
new file mode 100644
index 000000000..8ab45bea8
--- /dev/null
+++ b/include/asm-arm/arch-netx/netx-regs.h
@@ -0,0 +1,410 @@
+/*
+ * include/asm-arm/arch-netx/netx-regs.h
+ *
+ * Copyright (c) 2005 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix
+ *
+ * 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_ARCH_NETX_REGS_H
+#define __ASM_ARCH_NETX_REGS_H
+
+/* offsets relative to the beginning of the io space */
+#define NETX_OFS_SYSTEM  0x00000
+#define NETX_OFS_MEMCR   0x00100
+#define NETX_OFS_DPMAS   0x03000
+#define NETX_OFS_GPIO    0x00800
+#define NETX_OFS_PIO     0x00900
+#define NETX_OFS_UART0   0x00a00
+#define NETX_OFS_UART1   0x00a40
+#define NETX_OFS_UART2   0x00a80
+#define NETX_OF_MIIMU    0x00b00
+#define NETX_OFS_SPI     0x00c00
+#define NETX_OFS_I2C     0x00d00
+#define NETX_OFS_SYSTIME 0x01100
+#define NETX_OFS_RTC     0x01200
+#define NETX_OFS_EXTBUS  0x03600
+#define NETX_OFS_LCD     0x04000
+#define NETX_OFS_USB     0x20000
+#define NETX_OFS_XMAC0   0x60000
+#define NETX_OFS_XMAC1   0x61000
+#define NETX_OFS_XMAC2   0x62000
+#define NETX_OFS_XMAC3   0x63000
+#define NETX_OFS_XMAC(no) (0x60000 + (no) * 0x1000)
+#define NETX_OFS_PFIFO   0x64000
+#define NETX_OFS_XPEC0   0x70000
+#define NETX_OFS_XPEC1   0x74000
+#define NETX_OFS_XPEC2   0x78000
+#define NETX_OFS_XPEC3   0x7c000
+#define NETX_OFS_XPEC(no) (0x70000 + (no) * 0x4000)
+#define NETX_OFS_VIC     0xff000
+
+/* physical addresses */
+#define NETX_PA_SYSTEM   (NETX_IO_PHYS + NETX_OFS_SYSTEM)
+#define NETX_PA_MEMCR    (NETX_IO_PHYS + NETX_OFS_MEMCR)
+#define NETX_PA_DPMAS    (NETX_IO_PHYS + NETX_OFS_DPMAS)
+#define NETX_PA_GPIO     (NETX_IO_PHYS + NETX_OFS_GPIO)
+#define NETX_PA_PIO      (NETX_IO_PHYS + NETX_OFS_PIO)
+#define NETX_PA_UART0    (NETX_IO_PHYS + NETX_OFS_UART0)
+#define NETX_PA_UART1    (NETX_IO_PHYS + NETX_OFS_UART1)
+#define NETX_PA_UART2    (NETX_IO_PHYS + NETX_OFS_UART2)
+#define NETX_PA_MIIMU    (NETX_IO_PHYS + NETX_OF_MIIMU)
+#define NETX_PA_SPI      (NETX_IO_PHYS + NETX_OFS_SPI)
+#define NETX_PA_I2C      (NETX_IO_PHYS + NETX_OFS_I2C)
+#define NETX_PA_SYSTIME  (NETX_IO_PHYS + NETX_OFS_SYSTIME)
+#define NETX_PA_RTC      (NETX_IO_PHYS + NETX_OFS_RTC)
+#define NETX_PA_EXTBUS   (NETX_IO_PHYS + NETX_OFS_EXTBUS)
+#define NETX_PA_LCD      (NETX_IO_PHYS + NETX_OFS_LCD)
+#define NETX_PA_USB      (NETX_IO_PHYS + NETX_OFS_USB)
+#define NETX_PA_XMAC0    (NETX_IO_PHYS + NETX_OFS_XMAC0)
+#define NETX_PA_XMAC1    (NETX_IO_PHYS + NETX_OFS_XMAC1)
+#define NETX_PA_XMAC2    (NETX_IO_PHYS + NETX_OFS_XMAC2)
+#define NETX_PA_XMAC3    (NETX_IO_PHYS + NETX_OFS_XMAC3)
+#define NETX_PA_XMAC(no) (NETX_IO_PHYS + NETX_OFS_XMAC(no))
+#define NETX_PA_PFIFO    (NETX_IO_PHYS + NETX_OFS_PFIFO)
+#define NETX_PA_XPEC0    (NETX_IO_PHYS + NETX_OFS_XPEC0)
+#define NETX_PA_XPEC1    (NETX_IO_PHYS + NETX_OFS_XPEC1)
+#define NETX_PA_XPEC2    (NETX_IO_PHYS + NETX_OFS_XPEC2)
+#define NETX_PA_XPEC3    (NETX_IO_PHYS + NETX_OFS_XPEC3)
+#define NETX_PA_XPEC(no) (NETX_IO_PHYS + NETX_OFS_XPEC(no))
+#define NETX_PA_VIC      (NETX_IO_PHYS + NETX_OFS_VIC)
+
+/* virual addresses */
+#define NETX_VA_SYSTEM   (NETX_IO_VIRT + NETX_OFS_SYSTEM)
+#define NETX_VA_MEMCR    (NETX_IO_VIRT + NETX_OFS_MEMCR)
+#define NETX_VA_DPMAS    (NETX_IO_VIRT + NETX_OFS_DPMAS)
+#define NETX_VA_GPIO     (NETX_IO_VIRT + NETX_OFS_GPIO)
+#define NETX_VA_PIO      (NETX_IO_VIRT + NETX_OFS_PIO)
+#define NETX_VA_UART0    (NETX_IO_VIRT + NETX_OFS_UART0)
+#define NETX_VA_UART1    (NETX_IO_VIRT + NETX_OFS_UART1)
+#define NETX_VA_UART2    (NETX_IO_VIRT + NETX_OFS_UART2)
+#define NETX_VA_MIIMU    (NETX_IO_VIRT + NETX_OF_MIIMU)
+#define NETX_VA_SPI      (NETX_IO_VIRT + NETX_OFS_SPI)
+#define NETX_VA_I2C      (NETX_IO_VIRT + NETX_OFS_I2C)
+#define NETX_VA_SYSTIME  (NETX_IO_VIRT + NETX_OFS_SYSTIME)
+#define NETX_VA_RTC      (NETX_IO_VIRT + NETX_OFS_RTC)
+#define NETX_VA_EXTBUS   (NETX_IO_VIRT + NETX_OFS_EXTBUS)
+#define NETX_VA_LCD      (NETX_IO_VIRT + NETX_OFS_LCD)
+#define NETX_VA_USB      (NETX_IO_VIRT + NETX_OFS_USB)
+#define NETX_VA_XMAC0    (NETX_IO_VIRT + NETX_OFS_XMAC0)
+#define NETX_VA_XMAC1    (NETX_IO_VIRT + NETX_OFS_XMAC1)
+#define NETX_VA_XMAC2    (NETX_IO_VIRT + NETX_OFS_XMAC2)
+#define NETX_VA_XMAC3    (NETX_IO_VIRT + NETX_OFS_XMAC3)
+#define NETX_VA_XMAC(no) (NETX_IO_VIRT + NETX_OFS_XMAC(no))
+#define NETX_VA_PFIFO    (NETX_IO_VIRT + NETX_OFS_PFIFO)
+#define NETX_VA_XPEC0    (NETX_IO_VIRT + NETX_OFS_XPEC0)
+#define NETX_VA_XPEC1    (NETX_IO_VIRT + NETX_OFS_XPEC1)
+#define NETX_VA_XPEC2    (NETX_IO_VIRT + NETX_OFS_XPEC2)
+#define NETX_VA_XPEC3    (NETX_IO_VIRT + NETX_OFS_XPEC3)
+#define NETX_VA_XPEC(no) (NETX_IO_VIRT + NETX_OFS_XPEC(no))
+#define NETX_VA_VIC      (NETX_IO_VIRT + NETX_OFS_VIC)
+
+/*********************************
+ * System functions              *
+ *********************************/
+
+/* Registers */
+#define NETX_SYSTEM_REG(ofs)            __io(NETX_VA_SYSTEM + (ofs))
+#define NETX_SYSTEM_BOO_SR          NETX_SYSTEM_REG(0x00)
+#define NETX_SYSTEM_IOC_CR          NETX_SYSTEM_REG(0x04)
+#define NETX_SYSTEM_IOC_MR          NETX_SYSTEM_REG(0x08)
+
+/* FIXME: Docs are not consistent */
+#define NETX_SYSTEM_RES_CR          NETX_SYSTEM_REG(0x08)
+/* #define NETX_SYSTEM_RES_CR          NETX_SYSTEM_REG(0x0c) */
+
+#define NETX_SYSTEM_PHY_CONTROL     NETX_SYSTEM_REG(0x10)
+#define NETX_SYSTEM_REV             NETX_SYSTEM_REG(0x34)
+#define NETX_SYSTEM_IOC_ACCESS_KEY  NETX_SYSTEM_REG(0x70)
+#define NETX_SYSTEM_WDG_TR          NETX_SYSTEM_REG(0x200)
+#define NETX_SYSTEM_WDG_CTR         NETX_SYSTEM_REG(0x204)
+#define NETX_SYSTEM_WDG_IRQ_TIMEOUT NETX_SYSTEM_REG(0x208)
+#define NETX_SYSTEM_WDG_RES_TIMEOUT NETX_SYSTEM_REG(0x20c)
+
+/* Bits */
+#define NETX_SYSTEM_RES_CR_RSTIN         (1<<0)
+#define NETX_SYSTEM_RES_CR_WDG_RES       (1<<1)
+#define NETX_SYSTEM_RES_CR_HOST_RES      (1<<2)
+#define NETX_SYSTEM_RES_CR_FIRMW_RES     (1<<3)
+#define NETX_SYSTEM_RES_CR_XPEC0_RES     (1<<4)
+#define NETX_SYSTEM_RES_CR_XPEC1_RES     (1<<5)
+#define NETX_SYSTEM_RES_CR_XPEC2_RES     (1<<6)
+#define NETX_SYSTEM_RES_CR_XPEC3_RES     (1<<7)
+#define NETX_SYSTEM_RES_CR_DIS_XPEC0_RES (1<<16)
+#define NETX_SYSTEM_RES_CR_DIS_XPEC1_RES (1<<17)
+#define NETX_SYSTEM_RES_CR_DIS_XPEC2_RES (1<<18)
+#define NETX_SYSTEM_RES_CR_DIS_XPEC3_RES (1<<19)
+#define NETX_SYSTEM_RES_CR_FIRMW_FLG0    (1<<20)
+#define NETX_SYSTEM_RES_CR_FIRMW_FLG1    (1<<21)
+#define NETX_SYSTEM_RES_CR_FIRMW_FLG2    (1<<22)
+#define NETX_SYSTEM_RES_CR_FIRMW_FLG3    (1<<23)
+#define NETX_SYSTEM_RES_CR_FIRMW_RES_EN  (1<<24)
+#define NETX_SYSTEM_RES_CR_RSTOUT        (1<<25)
+#define NETX_SYSTEM_RES_CR_EN_RSTOUT     (1<<26)
+
+#define PHY_CONTROL_RESET            (1<<31)
+#define PHY_CONTROL_SIM_BYP          (1<<30)
+#define PHY_CONTROL_CLK_XLATIN       (1<<29)
+#define PHY_CONTROL_PHY1_EN          (1<<21)
+#define PHY_CONTROL_PHY1_NP_MSG_CODE
+#define PHY_CONTROL_PHY1_AUTOMDIX    (1<<17)
+#define PHY_CONTROL_PHY1_FIXMODE     (1<<16)
+#define PHY_CONTROL_PHY1_MODE(mode)  (((mode) & 0x7) << 13)
+#define PHY_CONTROL_PHY0_EN          (1<<12)
+#define PHY_CONTROL_PHY0_NP_MSG_CODE
+#define PHY_CONTROL_PHY0_AUTOMDIX    (1<<8)
+#define PHY_CONTROL_PHY0_FIXMODE     (1<<7)
+#define PHY_CONTROL_PHY0_MODE(mode)  (((mode) & 0x7) << 4)
+#define PHY_CONTROL_PHY_ADDRESS(adr) ((adr) & 0xf)
+
+#define PHY_MODE_10BASE_T_HALF      0
+#define PHY_MODE_10BASE_T_FULL      1
+#define PHY_MODE_100BASE_TX_FX_FULL 2
+#define PHY_MODE_100BASE_TX_FX_HALF 3
+#define PHY_MODE_100BASE_TX_HALF    4
+#define PHY_MODE_REPEATER           5
+#define PHY_MODE_POWER_DOWN         6
+#define PHY_MODE_ALL                7
+
+/* Bits */
+#define VECT_CNTL_ENABLE               (1 << 5)
+
+/*******************************
+ * GPIO and timer module       *
+ *******************************/
+
+/* Registers */
+#define NETX_GPIO_REG(ofs)                     __io(NETX_VA_GPIO + (ofs))
+#define NETX_GPIO_CFG(gpio)                NETX_GPIO_REG(0x0  + ((gpio)<<2))
+#define NETX_GPIO_THRESHOLD_CAPTURE(gpio)  NETX_GPIO_REG(0x40 + ((gpio)<<2))
+#define NETX_GPIO_COUNTER_CTRL(counter)    NETX_GPIO_REG(0x80 + ((counter)<<2))
+#define NETX_GPIO_COUNTER_MAX(counter)     NETX_GPIO_REG(0x94 + ((counter)<<2))
+#define NETX_GPIO_COUNTER_CURRENT(counter) NETX_GPIO_REG(0xa8 + ((counter)<<2))
+#define NETX_GPIO_IRQ_ENABLE               NETX_GPIO_REG(0xbc)
+#define NETX_GPIO_IRQ_DISABLE              NETX_GPIO_REG(0xc0)
+#define NETX_GPIO_SYSTIME_NS_CMP           NETX_GPIO_REG(0xc4)
+#define NETX_GPIO_LINE                     NETX_GPIO_REG(0xc8)
+#define NETX_GPIO_IRQ                      NETX_GPIO_REG(0xd0)
+
+/* Bits */
+#define NETX_GPIO_CFG_IOCFG_GP_INPUT                 (0x0)
+#define NETX_GPIO_CFG_IOCFG_GP_OUTPUT                (0x1)
+#define NETX_GPIO_CFG_IOCFG_GP_UART                  (0x2)
+#define NETX_GPIO_CFG_INV                            (1<<2)
+#define NETX_GPIO_CFG_MODE_INPUT_READ                (0<<3)
+#define NETX_GPIO_CFG_MODE_INPUT_CAPTURE_CONT_RISING (1<<3)
+#define NETX_GPIO_CFG_MODE_INPUT_CAPTURE_ONCE_RISING (2<<3)
+#define NETX_GPIO_CFG_MODE_INPUT_CAPTURE_HIGH_LEVEL  (3<<3)
+#define NETX_GPIO_CFG_COUNT_REF_COUNTER0             (0<<5)
+#define NETX_GPIO_CFG_COUNT_REF_COUNTER1             (1<<5)
+#define NETX_GPIO_CFG_COUNT_REF_COUNTER2             (2<<5)
+#define NETX_GPIO_CFG_COUNT_REF_COUNTER3             (3<<5)
+#define NETX_GPIO_CFG_COUNT_REF_COUNTER4             (4<<5)
+#define NETX_GPIO_CFG_COUNT_REF_SYSTIME              (7<<5)
+
+#define NETX_GPIO_COUNTER_CTRL_RUN                   (1<<0)
+#define NETX_GPIO_COUNTER_CTRL_SYM                   (1<<1)
+#define NETX_GPIO_COUNTER_CTRL_ONCE                  (1<<2)
+#define NETX_GPIO_COUNTER_CTRL_IRQ_EN                (1<<3)
+#define NETX_GPIO_COUNTER_CTRL_CNT_EVENT             (1<<4)
+#define NETX_GPIO_COUNTER_CTRL_RST_EN                (1<<5)
+#define NETX_GPIO_COUNTER_CTRL_SEL_EVENT             (1<<6)
+#define NETX_GPIO_COUNTER_CTRL_GPIO_REF /* FIXME */
+
+#define GPIO_BIT(gpio)                     (1<<(gpio))
+#define COUNTER_BIT(counter)               ((1<<16)<<(counter))
+
+/*******************************
+ * PIO                         *
+ *******************************/
+
+/* Registers */
+#define NETX_PIO_REG(ofs)        __io(NETX_VA_PIO + (ofs))
+#define NETX_PIO_INPIO       NETX_PIO_REG(0x0)
+#define NETX_PIO_OUTPIO      NETX_PIO_REG(0x4)
+#define NETX_PIO_OEPIO       NETX_PIO_REG(0x8)
+
+/*******************************
+ * MII Unit                    *
+ *******************************/
+
+/* Registers */
+#define NETX_MIIMU           __io(NETX_VA_MIIMU)
+
+/* Bits */
+#define MIIMU_SNRDY        (1<<0)
+#define MIIMU_PREAMBLE     (1<<1)
+#define MIIMU_OPMODE_WRITE (1<<2)
+#define MIIMU_MDC_PERIOD   (1<<3)
+#define MIIMU_PHY_NRES     (1<<4)
+#define MIIMU_RTA          (1<<5)
+#define MIIMU_REGADDR(adr) (((adr) & 0x1f) << 6)
+#define MIIMU_PHYADDR(adr) (((adr) & 0x1f) << 11)
+#define MIIMU_DATA(data)   (((data) & 0xffff) << 16)
+
+/*******************************
+ * xmac / xpec                 *
+ *******************************/
+
+/* XPEC register offsets relative to NETX_VA_XPEC(no) */
+#define NETX_XPEC_R0_OFS           0x00
+#define NETX_XPEC_R1_OFS           0x04
+#define NETX_XPEC_R2_OFS           0x08
+#define NETX_XPEC_R3_OFS           0x0c
+#define NETX_XPEC_R4_OFS           0x10
+#define NETX_XPEC_R5_OFS           0x14
+#define NETX_XPEC_R6_OFS           0x18
+#define NETX_XPEC_R7_OFS           0x1c
+#define NETX_XPEC_RANGE01_OFS      0x20
+#define NETX_XPEC_RANGE23_OFS      0x24
+#define NETX_XPEC_RANGE45_OFS      0x28
+#define NETX_XPEC_RANGE67_OFS      0x2c
+#define NETX_XPEC_PC_OFS           0x48
+#define NETX_XPEC_TIMER_OFS(timer) (0x30 + ((timer)<<2))
+#define NETX_XPEC_IRQ_OFS          0x8c
+#define NETX_XPEC_SYSTIME_NS_OFS   0x90
+#define NETX_XPEC_FIFO_DATA_OFS    0x94
+#define NETX_XPEC_SYSTIME_S_OFS    0x98
+#define NETX_XPEC_ADC_OFS          0x9c
+#define NETX_XPEC_URX_COUNT_OFS    0x40
+#define NETX_XPEC_UTX_COUNT_OFS    0x44
+#define NETX_XPEC_PC_OFS           0x48
+#define NETX_XPEC_ZERO_OFS         0x4c
+#define NETX_XPEC_STATCFG_OFS      0x50
+#define NETX_XPEC_EC_MASKA_OFS     0x54
+#define NETX_XPEC_EC_MASKB_OFS     0x58
+#define NETX_XPEC_EC_MASK0_OFS     0x5c
+#define NETX_XPEC_EC_MASK8_OFS     0x7c
+#define NETX_XPEC_EC_MASK9_OFS     0x80
+#define NETX_XPEC_XPU_HOLD_PC_OFS  0x100
+#define NETX_XPEC_RAM_START_OFS    0x2000
+
+/* Bits */
+#define XPU_HOLD_PC (1<<0)
+
+/* XMAC register offsets relative to NETX_VA_XMAC(no) */
+#define NETX_XMAC_RPU_PROGRAM_START_OFS       0x000
+#define NETX_XMAC_RPU_PROGRAM_END_OFS         0x3ff
+#define NETX_XMAC_TPU_PROGRAM_START_OFS       0x400
+#define NETX_XMAC_TPU_PROGRAM_END_OFS         0x7ff
+#define NETX_XMAC_RPU_HOLD_PC_OFS             0xa00
+#define NETX_XMAC_TPU_HOLD_PC_OFS             0xa04
+#define NETX_XMAC_STATUS_SHARED0_OFS          0x840
+#define NETX_XMAC_CONFIG_SHARED0_OFS          0x844
+#define NETX_XMAC_STATUS_SHARED1_OFS          0x848
+#define NETX_XMAC_CONFIG_SHARED1_OFS          0x84c
+#define NETX_XMAC_STATUS_SHARED2_OFS          0x850
+#define NETX_XMAC_CONFIG_SHARED2_OFS          0x854
+#define NETX_XMAC_STATUS_SHARED3_OFS          0x858
+#define NETX_XMAC_CONFIG_SHARED3_OFS          0x85c
+
+#define RPU_HOLD_PC            (1<<15)
+#define TPU_HOLD_PC            (1<<15)
+
+/*******************************
+ * Pointer FIFO                *
+ *******************************/
+
+/* Registers */
+#define NETX_PFIFO_REG(ofs)               __io(NETX_VA_PFIFO + (ofs))
+#define NETX_PFIFO_BASE(pfifo)        NETX_PFIFO_REG(0x00 + ((pfifo)<<2))
+#define NETX_PFIFO_BORDER_BASE(pfifo) NETX_PFIFO_REG(0x80 + ((pfifo)<<2))
+#define NETX_PFIFO_RESET              NETX_PFIFO_REG(0x100)
+#define NETX_PFIFO_FULL               NETX_PFIFO_REG(0x104)
+#define NETX_PFIFO_EMPTY              NETX_PFIFO_REG(0x108)
+#define NETX_PFIFO_OVEFLOW            NETX_PFIFO_REG(0x10c)
+#define NETX_PFIFO_UNDERRUN           NETX_PFIFO_REG(0x110)
+#define NETX_PFIFO_FILL_LEVEL(pfifo)  NETX_PFIFO_REG(0x180 + ((pfifo)<<2))
+#define NETX_PFIFO_XPEC_ISR(xpec)     NETX_PFIFO_REG(0x400 + ((xpec) << 2))
+
+/*******************************
+ * Dual Port Memory            *
+ *******************************/
+
+/* Registers */
+#define NETX_DPMAS_REG(ofs)               __io(NETX_VA_DPMAS + (ofs))
+#define NETX_DPMAS_SYS_STAT           NETX_DPMAS_REG(0x4d8)
+#define NETX_DPMAS_INT_STAT           NETX_DPMAS_REG(0x4e0)
+#define NETX_DPMAS_INT_EN             NETX_DPMAS_REG(0x4f0)
+#define NETX_DPMAS_IF_CONF0           NETX_DPMAS_REG(0x608)
+#define NETX_DPMAS_IF_CONF1           NETX_DPMAS_REG(0x60c)
+#define NETX_DPMAS_EXT_CONFIG(cs)     NETX_DPMAS_REG(0x610 + 4 * (cs))
+#define NETX_DPMAS_IO_MODE0           NETX_DPMAS_REG(0x620) /* I/O 32..63 */
+#define NETX_DPMAS_DRV_EN0            NETX_DPMAS_REG(0x624)
+#define NETX_DPMAS_DATA0              NETX_DPMAS_REG(0x628)
+#define NETX_DPMAS_IO_MODE1           NETX_DPMAS_REG(0x630) /* I/O 64..84 */
+#define NETX_DPMAS_DRV_EN1            NETX_DPMAS_REG(0x634)
+#define NETX_DPMAS_DATA1              NETX_DPMAS_REG(0x638)
+
+/* Bits */
+#define NETX_DPMAS_INT_EN_GLB_EN         (1<<31)
+#define NETX_DPMAS_INT_EN_MEM_LCK        (1<<30)
+#define NETX_DPMAS_INT_EN_WDG            (1<<29)
+#define NETX_DPMAS_INT_EN_PIO72          (1<<28)
+#define NETX_DPMAS_INT_EN_PIO47          (1<<27)
+#define NETX_DPMAS_INT_EN_PIO40          (1<<26)
+#define NETX_DPMAS_INT_EN_PIO36          (1<<25)
+#define NETX_DPMAS_INT_EN_PIO35          (1<<24)
+
+#define NETX_DPMAS_IF_CONF0_HIF_DISABLED (0<<28)
+#define NETX_DPMAS_IF_CONF0_HIF_EXT_BUS  (1<<28)
+#define NETX_DPMAS_IF_CONF0_HIF_UP_8BIT  (2<<28)
+#define NETX_DPMAS_IF_CONF0_HIF_UP_16BIT (3<<28)
+#define NETX_DPMAS_IF_CONF0_HIF_IO       (4<<28)
+#define NETX_DPMAS_IF_CONF0_WAIT_DRV_PP  (1<<14)
+#define NETX_DPMAS_IF_CONF0_WAIT_DRV_OD  (2<<14)
+#define NETX_DPMAS_IF_CONF0_WAIT_DRV_TRI (3<<14)
+
+#define NETX_DPMAS_IF_CONF1_IRQ_POL_PIO35 (1<<26)
+#define NETX_DPMAS_IF_CONF1_IRQ_POL_PIO36 (1<<27)
+#define NETX_DPMAS_IF_CONF1_IRQ_POL_PIO40 (1<<28)
+#define NETX_DPMAS_IF_CONF1_IRQ_POL_PIO47 (1<<29)
+#define NETX_DPMAS_IF_CONF1_IRQ_POL_PIO72 (1<<30)
+
+#define NETX_EXT_CONFIG_TALEWIDTH(x) (((x) & 0x7) << 29)
+#define NETX_EXT_CONFIG_TADRHOLD(x)  (((x) & 0x7) << 26)
+#define NETX_EXT_CONFIG_TCSON(x)     (((x) & 0x7) << 23)
+#define NETX_EXT_CONFIG_TRDON(x)     (((x) & 0x7) << 20)
+#define NETX_EXT_CONFIG_TWRON(x)     (((x) & 0x7)  << 17)
+#define NETX_EXT_CONFIG_TWROFF(x)    (((x) & 0x1f) << 12)
+#define NETX_EXT_CONFIG_TRDWRCYC(x)  (((x) & 0x1f) << 7)
+#define NETX_EXT_CONFIG_WAIT_POL     (1<<6)
+#define NETX_EXT_CONFIG_WAIT_EN      (1<<5)
+#define NETX_EXT_CONFIG_NRD_MODE     (1<<4)
+#define NETX_EXT_CONFIG_DS_MODE      (1<<3)
+#define NETX_EXT_CONFIG_NWR_MODE     (1<<2)
+#define NETX_EXT_CONFIG_16BIT        (1<<1)
+#define NETX_EXT_CONFIG_CS_ENABLE    (1<<0)
+
+#define NETX_DPMAS_IO_MODE0_WRL   (1<<13)
+#define NETX_DPMAS_IO_MODE0_WAIT  (1<<14)
+#define NETX_DPMAS_IO_MODE0_READY (1<<15)
+#define NETX_DPMAS_IO_MODE0_CS0   (1<<19)
+#define NETX_DPMAS_IO_MODE0_EXTRD (1<<20)
+
+#define NETX_DPMAS_IO_MODE1_CS2           (1<<15)
+#define NETX_DPMAS_IO_MODE1_CS1           (1<<16)
+#define NETX_DPMAS_IO_MODE1_SAMPLE_NPOR   (0<<30)
+#define NETX_DPMAS_IO_MODE1_SAMPLE_100MHZ (1<<30)
+#define NETX_DPMAS_IO_MODE1_SAMPLE_NPIO36 (2<<30)
+#define NETX_DPMAS_IO_MODE1_SAMPLE_PIO36  (3<<30)
+
+/*******************************
+ * I2C                         *
+ *******************************/
+#define NETX_I2C_REG(ofs)	__io(NETX_VA_I2C, (ofs))
+#define NETX_I2C_CTRL	NETX_I2C_REG(0x0)
+#define NETX_I2C_DATA	NETX_I2C_REG(0x4)
+
+#endif /* __ASM_ARCH_NETX_REGS_H */
diff --git a/include/asm-arm/arch-netx/param.h b/include/asm-arm/arch-netx/param.h
new file mode 100644
index 000000000..7a80c2617
--- /dev/null
+++ b/include/asm-arm/arch-netx/param.h
@@ -0,0 +1,18 @@
+/*
+ *  linux/include/asm-arm/arch-netx/param.h
+ *
+ * Copyright (C) 2005 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix
+ *
+ * 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
+ */
diff --git a/include/asm-arm/arch-netx/pfifo.h b/include/asm-arm/arch-netx/pfifo.h
new file mode 100644
index 000000000..4af2ee4a3
--- /dev/null
+++ b/include/asm-arm/arch-netx/pfifo.h
@@ -0,0 +1,54 @@
+/*
+ * include/asm-arm/arch-netx/pfifo.h
+ *
+ * Copyright (c) 2005 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix
+ *
+ * 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_ARCH_PFIFO_H
+#define ASM_ARCH_PFIFO_H
+
+static inline int pfifo_push(int no, unsigned int pointer)
+{
+	writel(pointer, NETX_PFIFO_BASE(no));
+	return 0;
+}
+
+static inline unsigned int pfifo_pop(int no)
+{
+	return readl(NETX_PFIFO_BASE(no));
+}
+
+static inline int pfifo_fill_level(int no)
+{
+
+	return readl(NETX_PFIFO_FILL_LEVEL(no));
+}
+
+static inline int pfifo_full(int no)
+{
+	return readl(NETX_PFIFO_FULL) & (1<<no) ? 1 : 0;
+}
+
+static inline int pfifo_empty(int no)
+{
+	return readl(NETX_PFIFO_EMPTY) & (1<<no) ? 1 : 0;
+}
+
+int pfifo_request(unsigned int pfifo_mask);
+void pfifo_free(unsigned int pfifo_mask);
+
+#endif /* ASM_ARCH_PFIFO_H */
diff --git a/include/asm-arm/arch-netx/system.h b/include/asm-arm/arch-netx/system.h
new file mode 100644
index 000000000..52adf368d
--- /dev/null
+++ b/include/asm-arm/arch-netx/system.h
@@ -0,0 +1,38 @@
+/*
+ * include/asm-arm/arch-netx/system.h
+ *
+ * Copyright (C) 2005 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix
+ *
+ * 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_ARCH_SYSTEM_H
+#define __ASM_ARCH_SYSTEM_H
+
+#include <asm/io.h>
+#include <asm/hardware.h>
+#include "netx-regs.h"
+
+static inline void arch_idle(void)
+{
+	cpu_do_idle();
+}
+
+static inline void arch_reset(char mode)
+{
+	writel(NETX_SYSTEM_RES_CR_FIRMW_RES_EN | NETX_SYSTEM_RES_CR_FIRMW_RES,
+	       NETX_SYSTEM_RES_CR);
+}
+
+#endif
+
diff --git a/include/asm-arm/arch-netx/timex.h b/include/asm-arm/arch-netx/timex.h
new file mode 100644
index 000000000..7fdb42da0
--- /dev/null
+++ b/include/asm-arm/arch-netx/timex.h
@@ -0,0 +1,20 @@
+/*
+ * include/asm-arm/arch-netx/timex.h
+ *
+ * Copyright (C) 2005 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix
+ *
+ * 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
+ */
+
+#define CLOCK_TICK_RATE 100000000
diff --git a/include/asm-arm/arch-netx/uncompress.h b/include/asm-arm/arch-netx/uncompress.h
new file mode 100644
index 000000000..f89434547
--- /dev/null
+++ b/include/asm-arm/arch-netx/uncompress.h
@@ -0,0 +1,76 @@
+/*
+ * include/asm-arm/arch-netx/uncompress.h
+ *
+ * Copyright (C) 2005 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix
+ *
+ * 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
+ */
+
+/*
+ * The following code assumes the serial port has already been
+ * initialized by the bootloader.  We search for the first enabled
+ * port in the most probable order.  If you didn't setup a port in
+ * your bootloader then nothing will appear (which might be desired).
+ *
+ * This does not append a newline
+ */
+
+#define REG(x) (*(volatile unsigned long *)(x))
+
+#define UART1_BASE 0x100a00
+#define UART2_BASE 0x100a80
+
+#define UART_DR 0x0
+
+#define UART_CR 0x14
+#define CR_UART_EN (1<<0)
+
+#define UART_FR 0x18
+#define FR_BUSY (1<<3)
+#define FR_TXFF (1<<5)
+
+static void putc(char c)
+{
+	unsigned long base;
+
+	if (REG(UART1_BASE + UART_CR) & CR_UART_EN)
+		base = UART1_BASE;
+	else if (REG(UART2_BASE + UART_CR) & CR_UART_EN)
+		base = UART2_BASE;
+	else
+		return;
+
+	while (REG(base + UART_FR) & FR_TXFF);
+	REG(base + UART_DR) = c;
+}
+
+static inline void flush(void)
+{
+	unsigned long base;
+
+	if (REG(UART1_BASE + UART_CR) & CR_UART_EN)
+		base = UART1_BASE;
+	else if (REG(UART2_BASE + UART_CR) & CR_UART_EN)
+		base = UART2_BASE;
+	else
+		return;
+
+	while (REG(base + UART_FR) & FR_BUSY);
+}
+
+/*
+ * nothing to do
+ */
+#define arch_decomp_setup()
+#define arch_decomp_wdog()
diff --git a/include/asm-arm/arch-netx/vmalloc.h b/include/asm-arm/arch-netx/vmalloc.h
new file mode 100644
index 000000000..da2da5a59
--- /dev/null
+++ b/include/asm-arm/arch-netx/vmalloc.h
@@ -0,0 +1,19 @@
+/*
+ *  linux/include/asm-arm/arch-netx/vmalloc.h
+ *
+ * Copyright (C) 2005 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix
+ *
+ * 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
+ */
+#define VMALLOC_END       (PAGE_OFFSET + 0x10000000)
diff --git a/include/asm-arm/arch-netx/xc.h b/include/asm-arm/arch-netx/xc.h
new file mode 100644
index 000000000..659af1951
--- /dev/null
+++ b/include/asm-arm/arch-netx/xc.h
@@ -0,0 +1,42 @@
+/*
+ *  linux/include/asm-arm/arch-netx/xc.h
+ *
+ * Copyright (C) 2005 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix
+ *
+ * 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_ARCH_XC_H
+#define __ASM_ARCH_XC_H
+
+struct xc {
+	int no;
+	unsigned int type;
+	unsigned int version;
+	void __iomem *xpec_base;
+	void __iomem *xmac_base;
+	void __iomem *sram_base;
+	int irq;
+	struct device *dev;
+};
+
+int xc_reset(struct xc *x);
+int xc_stop(struct xc* x);
+int xc_start(struct xc *x);
+int xc_running(struct xc *x);
+int xc_request_firmware(struct xc* x);
+struct xc* request_xc(int xcno, struct device *dev);
+void free_xc(struct xc *x);
+
+#endif /* __ASM_ARCH_XC_H */
diff --git a/include/asm-arm/arch-omap/board-fsample.h b/include/asm-arm/arch-omap/board-fsample.h
new file mode 100644
index 000000000..89a1e529f
--- /dev/null
+++ b/include/asm-arm/arch-omap/board-fsample.h
@@ -0,0 +1,51 @@
+/*
+ * linux/include/asm-arm/arch-omap/board-fsample.h
+ *
+ * Board-specific goodies for TI F-Sample.
+ *
+ * Copyright (C) 2006 Google, Inc.
+ * Author: Brian Swetland <swetland@google.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __ASM_ARCH_OMAP_FSAMPLE_H
+#define __ASM_ARCH_OMAP_FSAMPLE_H
+
+/* fsample is pretty close to p2-sample */
+#include <asm/arch/board-perseus2.h>
+
+#define fsample_cpld_read(reg) __raw_readb(reg)
+#define fsample_cpld_write(val, reg) __raw_writeb(val, reg)
+
+#define FSAMPLE_CPLD_BASE    0xE8100000
+#define FSAMPLE_CPLD_SIZE    SZ_4K
+#define FSAMPLE_CPLD_START   0x05080000
+
+#define FSAMPLE_CPLD_REG_A   (FSAMPLE_CPLD_BASE + 0x00)
+#define FSAMPLE_CPLD_SWITCH  (FSAMPLE_CPLD_BASE + 0x02)
+#define FSAMPLE_CPLD_UART    (FSAMPLE_CPLD_BASE + 0x02)
+#define FSAMPLE_CPLD_REG_B   (FSAMPLE_CPLD_BASE + 0x04)
+#define FSAMPLE_CPLD_VERSION (FSAMPLE_CPLD_BASE + 0x06)
+#define FSAMPLE_CPLD_SET_CLR (FSAMPLE_CPLD_BASE + 0x06)
+
+#define FSAMPLE_CPLD_BIT_BT_RESET         0
+#define FSAMPLE_CPLD_BIT_LCD_RESET        1
+#define FSAMPLE_CPLD_BIT_CAM_PWDN         2
+#define FSAMPLE_CPLD_BIT_CHARGER_ENABLE   3
+#define FSAMPLE_CPLD_BIT_SD_MMC_EN        4
+#define FSAMPLE_CPLD_BIT_aGPS_PWREN       5
+#define FSAMPLE_CPLD_BIT_BACKLIGHT        6
+#define FSAMPLE_CPLD_BIT_aGPS_EN_RESET    7
+#define FSAMPLE_CPLD_BIT_aGPS_SLEEPx_N    8
+#define FSAMPLE_CPLD_BIT_OTG_RESET        9
+
+#define fsample_cpld_set(bit) \
+    fsample_cpld_write((((bit) & 15) << 4) | 0x0f, FSAMPLE_CPLD_SET_CLR)
+
+#define fsample_cpld_clear(bit) \
+    fsample_cpld_write(0xf0 | ((bit) & 15), FSAMPLE_CPLD_SET_CLR)
+
+#endif
diff --git a/include/asm-arm/arch-omap/gpmc.h b/include/asm-arm/arch-omap/gpmc.h
new file mode 100644
index 000000000..1a0a52078
--- /dev/null
+++ b/include/asm-arm/arch-omap/gpmc.h
@@ -0,0 +1,91 @@
+/*
+ * General-Purpose Memory Controller for OMAP2
+ *
+ * Copyright (C) 2005-2006 Nokia Corporation
+ *
+ * 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 __OMAP2_GPMC_H
+#define __OMAP2_GPMC_H
+
+#define GPMC_CS_CONFIG1		0x00
+#define GPMC_CS_CONFIG2		0x04
+#define GPMC_CS_CONFIG3		0x08
+#define GPMC_CS_CONFIG4		0x0c
+#define GPMC_CS_CONFIG5		0x10
+#define GPMC_CS_CONFIG6		0x14
+#define GPMC_CS_CONFIG7		0x18
+#define GPMC_CS_NAND_COMMAND	0x1c
+#define GPMC_CS_NAND_ADDRESS	0x20
+#define GPMC_CS_NAND_DATA	0x24
+
+#define GPMC_CONFIG1_WRAPBURST_SUPP     (1 << 31)
+#define GPMC_CONFIG1_READMULTIPLE_SUPP  (1 << 20)
+#define GPMC_CONFIG1_READTYPE_ASYNC     (0 << 29)
+#define GPMC_CONFIG1_READTYPE_SYNC      (1 << 29)
+#define GPMC_CONFIG1_WRITETYPE_ASYNC    (0 << 27)
+#define GPMC_CONFIG1_WRITETYPE_SYNC     (1 << 27)
+#define GPMC_CONFIG1_CLKACTIVATIONTIME(val) ((val & 3) << 25)
+#define GPMC_CONFIG1_PAGE_LEN(val)      ((val & 3) << 23)
+#define GPMC_CONFIG1_WAIT_READ_MON      (1 << 22)
+#define GPMC_CONFIG1_WAIT_WRITE_MON     (1 << 21)
+#define GPMC_CONFIG1_WAIT_MON_IIME(val) ((val & 3) << 18)
+#define GPMC_CONFIG1_WAIT_PIN_SEL(val)  ((val & 3) << 16)
+#define GPMC_CONFIG1_DEVICESIZE(val)    ((val & 3) << 12)
+#define GPMC_CONFIG1_DEVICESIZE_16      GPMC_CONFIG1_DEVICESIZE(1)
+#define GPMC_CONFIG1_DEVICETYPE(val)    ((val & 3) << 10)
+#define GPMC_CONFIG1_DEVICETYPE_NOR     GPMC_CONFIG1_DEVICETYPE(0)
+#define GPMC_CONFIG1_DEVICETYPE_NAND    GPMC_CONFIG1_DEVICETYPE(1)
+#define GPMC_CONFIG1_MUXADDDATA         (1 << 9)
+#define GPMC_CONFIG1_TIME_PARA_GRAN     (1 << 4)
+#define GPMC_CONFIG1_FCLK_DIV(val)      (val & 3)
+#define GPMC_CONFIG1_FCLK_DIV2          (GPMC_CONFIG1_FCLK_DIV(1))
+#define GPMC_CONFIG1_FCLK_DIV3          (GPMC_CONFIG1_FCLK_DIV(2))
+#define GPMC_CONFIG1_FCLK_DIV4          (GPMC_CONFIG1_FCLK_DIV(3))
+
+/*
+ * Note that all values in this struct are in nanoseconds, while
+ * the register values are in gpmc_fck cycles.
+ */
+struct gpmc_timings {
+	/* Minimum clock period for synchronous mode */
+	u16 sync_clk;
+
+	/* Chip-select signal timings corresponding to GPMC_CS_CONFIG2 */
+	u16 cs_on;		/* Assertion time */
+	u16 cs_rd_off;		/* Read deassertion time */
+	u16 cs_wr_off;		/* Write deassertion time */
+
+	/* ADV signal timings corresponding to GPMC_CONFIG3 */
+	u16 adv_on;		/* Assertion time */
+	u16 adv_rd_off;		/* Read deassertion time */
+	u16 adv_wr_off;		/* Write deassertion time */
+
+	/* WE signals timings corresponding to GPMC_CONFIG4 */
+	u16 we_on;		/* WE assertion time */
+	u16 we_off;		/* WE deassertion time */
+
+	/* OE signals timings corresponding to GPMC_CONFIG4 */
+	u16 oe_on;		/* OE assertion time */
+	u16 oe_off;		/* OE deassertion time */
+
+	/* Access time and cycle time timings corresponding to GPMC_CONFIG5 */
+	u16 page_burst_access;	/* Multiple access word delay */
+	u16 access;		/* Start-cycle to first data valid delay */
+	u16 rd_cycle;		/* Total read cycle time */
+	u16 wr_cycle;		/* Total write cycle time */
+};
+
+extern unsigned int gpmc_ns_to_ticks(unsigned int time_ns);
+
+extern void gpmc_cs_write_reg(int cs, int idx, u32 val);
+extern u32 gpmc_cs_read_reg(int cs, int idx);
+extern int gpmc_cs_calc_divider(int cs, unsigned int sync_clk);
+extern int gpmc_cs_set_timings(int cs, const struct gpmc_timings *t);
+extern unsigned long gpmc_cs_get_base_addr(int cs);
+
+
+#endif
diff --git a/include/asm-arm/arch-pnx4008/clock.h b/include/asm-arm/arch-pnx4008/clock.h
new file mode 100644
index 000000000..91ae0030f
--- /dev/null
+++ b/include/asm-arm/arch-pnx4008/clock.h
@@ -0,0 +1,61 @@
+/*
+ * include/asm-arm/arch-pnx4008/clock.h
+ *
+ * Clock control driver for PNX4008 - header file
+ *
+ * Authors: Vitaly Wool, Dmitry Chigirev <source@mvista.com>
+ *
+ * 2005 (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 __PNX4008_CLOCK_H__
+#define __PNX4008_CLOCK_H__
+
+struct module;
+struct clk;
+
+#define PWRMAN_VA_BASE		IO_ADDRESS(PNX4008_PWRMAN_BASE)
+#define HCLKDIVCTRL_REG		(PWRMAN_VA_BASE + 0x40)
+#define PWRCTRL_REG		(PWRMAN_VA_BASE + 0x44)
+#define PLLCTRL_REG		(PWRMAN_VA_BASE + 0x48)
+#define OSC13CTRL_REG		(PWRMAN_VA_BASE + 0x4c)
+#define SYSCLKCTRL_REG		(PWRMAN_VA_BASE + 0x50)
+#define HCLKPLLCTRL_REG		(PWRMAN_VA_BASE + 0x58)
+#define USBCTRL_REG		(PWRMAN_VA_BASE + 0x64)
+#define SDRAMCLKCTRL_REG	(PWRMAN_VA_BASE + 0x68)
+#define MSCTRL_REG		(PWRMAN_VA_BASE + 0x80)
+#define BTCLKCTRL		(PWRMAN_VA_BASE + 0x84)
+#define DUMCLKCTRL_REG		(PWRMAN_VA_BASE + 0x90)
+#define I2CCLKCTRL_REG		(PWRMAN_VA_BASE + 0xac)
+#define KEYCLKCTRL_REG		(PWRMAN_VA_BASE + 0xb0)
+#define TSCLKCTRL_REG		(PWRMAN_VA_BASE + 0xb4)
+#define PWMCLKCTRL_REG		(PWRMAN_VA_BASE + 0xb8)
+#define SPICTRL_REG		(PWRMAN_VA_BASE + 0xc4)
+#define FLASHCLKCTRL_REG	(PWRMAN_VA_BASE + 0xc8)
+#define UART3CLK_REG		(PWRMAN_VA_BASE + 0xd0)
+#define UARTCLKCTRL_REG		(PWRMAN_VA_BASE + 0xe4)
+#define DMACLKCTRL_REG		(PWRMAN_VA_BASE + 0xe8)
+#define AUTOCLK_CTRL		(PWRMAN_VA_BASE + 0xec)
+#define JPEGCLKCTRL_REG		(PWRMAN_VA_BASE + 0xfc)
+
+#define AUDIOCONFIG_VA_BASE	IO_ADDRESS(PNX4008_AUDIOCONFIG_BASE)
+#define DSPPLLCTRL_REG		(AUDIOCONFIG_VA_BASE + 0x60)
+#define DSPCLKCTRL_REG		(AUDIOCONFIG_VA_BASE + 0x64)
+#define AUDIOCLKCTRL_REG	(AUDIOCONFIG_VA_BASE + 0x68)
+#define AUDIOPLLCTRL_REG	(AUDIOCONFIG_VA_BASE + 0x6C)
+
+#define USB_OTG_CLKCTRL_REG	IO_ADDRESS(PNX4008_USB_CONFIG_BASE + 0xff4)
+
+#define VFP9CLKCTRL_REG		IO_ADDRESS(PNX4008_DEBUG_BASE)
+
+#define CLK_RATE_13MHZ 13000
+#define CLK_RATE_1MHZ 1000
+#define CLK_RATE_208MHZ 208000
+#define CLK_RATE_48MHZ 48000
+#define CLK_RATE_32KHZ 32
+
+#define PNX4008_UART_CLK CLK_RATE_13MHZ * 1000 /* in MHz */
+
+#endif
diff --git a/include/asm-arm/arch-pnx4008/debug-macro.S b/include/asm-arm/arch-pnx4008/debug-macro.S
new file mode 100644
index 000000000..67d18a203
--- /dev/null
+++ b/include/asm-arm/arch-pnx4008/debug-macro.S
@@ -0,0 +1,23 @@
+/* linux/include/asm-arm/arch-pnx4008/debug-macro.S
+ *
+ * Debugging macro include header
+ *
+ *  Copyright (C) 1994-1999 Russell King
+ *  Moved from linux/arch/arm/kernel/debug.S by Ben Dooks
+ *
+ * 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.
+ *
+*/
+
+		.macro	addruart,rx
+		mrc	p15, 0, \rx, c1, c0
+		tst	\rx, #1			@ MMU enabled?
+		mov	\rx, #0x00090000
+		addeq	\rx, \rx, #0x40000000
+		addne	\rx, \rx, #0xf4000000
+		.endm
+
+#define UART_SHIFT	2
+#include <asm/hardware/debug-8250.S>
diff --git a/include/asm-arm/arch-pnx4008/dma.h b/include/asm-arm/arch-pnx4008/dma.h
new file mode 100644
index 000000000..3aee12047
--- /dev/null
+++ b/include/asm-arm/arch-pnx4008/dma.h
@@ -0,0 +1,162 @@
+/*
+ *  linux/include/asm-arm/arch-pnx4008/dma.h
+ *
+ *  PNX4008 DMA header file
+ *
+ *  Author:	Vitaly Wool
+ *  Copyright:	MontaVista Software Inc. (c) 2005
+ *
+ *  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
+
+#include "platform.h"
+
+#define MAX_DMA_ADDRESS		0xffffffff
+
+#define MAX_DMA_CHANNELS	8
+
+#define DMAC_BASE		IO_ADDRESS(PNX4008_DMA_CONFIG_BASE)
+#define DMAC_INT_STAT		(DMAC_BASE + 0x0000)
+#define DMAC_INT_TC_STAT	(DMAC_BASE + 0x0004)
+#define DMAC_INT_TC_CLEAR	(DMAC_BASE + 0x0008)
+#define DMAC_INT_ERR_STAT	(DMAC_BASE + 0x000c)
+#define DMAC_INT_ERR_CLEAR	(DMAC_BASE + 0x0010)
+#define DMAC_SOFT_SREQ		(DMAC_BASE + 0x0024)
+#define DMAC_CONFIG		(DMAC_BASE + 0x0030)
+#define DMAC_Cx_SRC_ADDR(c)	(DMAC_BASE + 0x0100 + (c) * 0x20)
+#define DMAC_Cx_DEST_ADDR(c)	(DMAC_BASE + 0x0104 + (c) * 0x20)
+#define DMAC_Cx_LLI(c)		(DMAC_BASE + 0x0108 + (c) * 0x20)
+#define DMAC_Cx_CONTROL(c)	(DMAC_BASE + 0x010c + (c) * 0x20)
+#define DMAC_Cx_CONFIG(c)	(DMAC_BASE + 0x0110 + (c) * 0x20)
+
+enum {
+	WIDTH_BYTE = 0,
+	WIDTH_HWORD,
+	WIDTH_WORD
+};
+
+enum {
+	FC_MEM2MEM_DMA,
+	FC_MEM2PER_DMA,
+	FC_PER2MEM_DMA,
+	FC_PER2PER_DMA,
+	FC_PER2PER_DPER,
+	FC_MEM2PER_PER,
+	FC_PER2MEM_PER,
+	FC_PER2PER_SPER
+};
+
+enum {
+	DMA_INT_UNKNOWN = 0,
+	DMA_ERR_INT = 1,
+	DMA_TC_INT = 2,
+};
+
+enum {
+	DMA_BUFFER_ALLOCATED = 1,
+	DMA_HAS_LL = 2,
+};
+
+enum {
+	PER_CAM_DMA_1 = 0,
+	PER_NDF_FLASH = 1,
+	PER_MBX_SLAVE_FIFO = 2,
+	PER_SPI2_REC_XMIT = 3,
+	PER_MS_SD_RX_XMIT = 4,
+	PER_HS_UART_1_XMIT = 5,
+	PER_HS_UART_1_RX = 6,
+	PER_HS_UART_2_XMIT = 7,
+	PER_HS_UART_2_RX = 8,
+	PER_HS_UART_7_XMIT = 9,
+	PER_HS_UART_7_RX = 10,
+	PER_SPI1_REC_XMIT = 11,
+	PER_MLC_NDF_SREC = 12,
+	PER_CAM_DMA_2 = 13,
+	PER_PRNG_INFIFO = 14,
+	PER_PRNG_OUTFIFO = 15,
+};
+
+struct pnx4008_dma_ch_ctrl {
+	int tc_mask;
+	int cacheable;
+	int bufferable;
+	int priv_mode;
+	int di;
+	int si;
+	int dest_ahb1;
+	int src_ahb1;
+	int dwidth;
+	int swidth;
+	int dbsize;
+	int sbsize;
+	int tr_size;
+};
+
+struct pnx4008_dma_ch_config {
+	int halt;
+	int active;
+	int lock;
+	int itc;
+	int ie;
+	int flow_cntrl;
+	int dest_per;
+	int src_per;
+};
+
+struct pnx4008_dma_ll {
+	unsigned long src_addr;
+	unsigned long dest_addr;
+	u32 next_dma;
+	unsigned long ch_ctrl;
+	struct pnx4008_dma_ll *next;
+	int flags;
+	void *alloc_data;
+	int (*free) (void *);
+};
+
+struct pnx4008_dma_config {
+	int is_ll;
+	unsigned long src_addr;
+	unsigned long dest_addr;
+	unsigned long ch_ctrl;
+	unsigned long ch_cfg;
+	struct pnx4008_dma_ll *ll;
+	u32 ll_dma;
+	int flags;
+	void *alloc_data;
+	int (*free) (void *);
+};
+
+extern struct pnx4008_dma_ll *pnx4008_alloc_ll_entry(dma_addr_t *);
+extern void pnx4008_free_ll_entry(struct pnx4008_dma_ll *, dma_addr_t);
+extern void pnx4008_free_ll(u32 ll_dma, struct pnx4008_dma_ll *);
+
+extern int pnx4008_request_channel(char *, int,
+				   void (*)(int, int, void *, struct pt_regs *),
+				   void *);
+extern void pnx4008_free_channel(int);
+extern int pnx4008_config_dma(int, int, int);
+extern int pnx4008_dma_pack_control(const struct pnx4008_dma_ch_ctrl *,
+				    unsigned long *);
+extern int pnx4008_dma_parse_control(unsigned long,
+				     struct pnx4008_dma_ch_ctrl *);
+extern int pnx4008_dma_pack_config(const struct pnx4008_dma_ch_config *,
+				   unsigned long *);
+extern int pnx4008_dma_parse_config(unsigned long,
+				    struct pnx4008_dma_ch_config *);
+extern int pnx4008_config_channel(int, struct pnx4008_dma_config *);
+extern int pnx4008_channel_get_config(int, struct pnx4008_dma_config *);
+extern int pnx4008_dma_ch_enable(int);
+extern int pnx4008_dma_ch_disable(int);
+extern int pnx4008_dma_ch_enabled(int);
+extern void pnx4008_dma_split_head_entry(struct pnx4008_dma_config *,
+					 struct pnx4008_dma_ch_ctrl *);
+extern void pnx4008_dma_split_ll_entry(struct pnx4008_dma_ll *,
+				       struct pnx4008_dma_ch_ctrl *);
+
+#endif				/* _ASM_ARCH_DMA_H */
diff --git a/include/asm-arm/arch-pnx4008/entry-macro.S b/include/asm-arm/arch-pnx4008/entry-macro.S
new file mode 100644
index 000000000..c1c198e36
--- /dev/null
+++ b/include/asm-arm/arch-pnx4008/entry-macro.S
@@ -0,0 +1,121 @@
+/*
+ * include/asm-arm/arch-pnx4008/entry-macro.S
+ *
+ * Low-level IRQ helper macros for PNX4008-based platforms
+ *
+ * 2005-2006 (c) MontaVista Software, Inc.
+ * Author: Vitaly Wool <vwool@ru.mvista.com>
+ * 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 "platform.h"
+
+#define IO_BASE         0xF0000000
+#define IO_ADDRESS(x)  (((((x) & 0xff000000) >> 4) | ((x) & 0xfffff)) | IO_BASE)
+
+#define INTRC_MASK			0x00
+#define INTRC_RAW_STAT			0x04
+#define INTRC_STAT			0x08
+#define INTRC_POLAR			0x0C
+#define INTRC_ACT_TYPE			0x10
+#define INTRC_TYPE			0x14
+
+#define SIC1_BASE_INT   32
+#define SIC2_BASE_INT   64
+
+		.macro	disable_fiq
+		.endm
+
+		.macro	get_irqnr_and_base, irqnr, irqstat, base, tmp
+/* decode the MIC interrupt numbers */
+		ldr	\base, =IO_ADDRESS(PNX4008_INTCTRLMIC_BASE)
+		ldr	\irqstat, [\base, #INTRC_STAT]
+
+		cmp	\irqstat,#1<<16
+		movhs	\irqnr,#16
+		movlo	\irqnr,#0
+		movhs	\irqstat,\irqstat,lsr#16
+		cmp	\irqstat,#1<<8
+		addhs	\irqnr,\irqnr,#8
+		movhs	\irqstat,\irqstat,lsr#8
+		cmp	\irqstat,#1<<4
+		addhs	\irqnr,\irqnr,#4
+		movhs	\irqstat,\irqstat,lsr#4
+		cmp	\irqstat,#1<<2
+		addhs	\irqnr,\irqnr,#2
+		movhs	\irqstat,\irqstat,lsr#2
+		cmp	\irqstat,#1<<1
+		addhs	\irqnr,\irqnr,#1
+
+/* was there an interrupt ? if not then drop out with EQ status */
+		teq	\irqstat,#0
+		beq	1003f
+
+/* and now check for extended IRQ reasons */
+		cmp	\irqnr,#1
+		bls	1003f
+		cmp	\irqnr,#30
+		blo	1002f
+
+/* IRQ 31,30  : High priority cascade IRQ handle */
+/* read the correct SIC */
+/* decoding status after compare : eq is 30 (SIC1) , ne is 31 (SIC2) */
+/* set the base IRQ number */
+		ldreq	\base, =IO_ADDRESS(PNX4008_INTCTRLSIC1_BASE)
+		moveq  \irqnr,#SIC1_BASE_INT
+		ldrne	\base, =IO_ADDRESS(PNX4008_INTCTRLSIC2_BASE)
+		movne   \irqnr,#SIC2_BASE_INT
+		ldr	\irqstat, [\base, #INTRC_STAT]
+		ldr	\tmp,	  [\base, #INTRC_TYPE]
+/* and with inverted mask : low priority interrupts  */
+		and	\irqstat,\irqstat,\tmp
+		b	1004f
+
+1003:
+/* IRQ 1,0  : Low priority cascade IRQ handle */
+/* read the correct SIC */
+/* decoding status after compare : eq is 1 (SIC2) , ne is 0 (SIC1)*/
+/* read the correct SIC */
+/* set the base IRQ number  */
+		ldrne	\base, =IO_ADDRESS(PNX4008_INTCTRLSIC1_BASE)
+		movne   \irqnr,#SIC1_BASE_INT
+		ldreq	\base, =IO_ADDRESS(PNX4008_INTCTRLSIC2_BASE)
+		moveq   \irqnr,#SIC2_BASE_INT
+		ldr	\irqstat, [\base, #INTRC_STAT]
+		ldr	\tmp,	  [\base, #INTRC_TYPE]
+/* and with inverted mask : low priority interrupts  */
+		bic	\irqstat,\irqstat,\tmp
+
+1004:
+
+		cmp	\irqstat,#1<<16
+		addhs	\irqnr,\irqnr,#16
+		movhs	\irqstat,\irqstat,lsr#16
+		cmp	\irqstat,#1<<8
+		addhs	\irqnr,\irqnr,#8
+		movhs	\irqstat,\irqstat,lsr#8
+		cmp	\irqstat,#1<<4
+		addhs	\irqnr,\irqnr,#4
+		movhs	\irqstat,\irqstat,lsr#4
+		cmp	\irqstat,#1<<2
+		addhs	\irqnr,\irqnr,#2
+		movhs	\irqstat,\irqstat,lsr#2
+		cmp	\irqstat,#1<<1
+		addhs	\irqnr,\irqnr,#1
+
+
+/* is irqstat not zero */
+
+1002:
+/* we assert that irqstat is not equal to zero and return ne status if true*/
+		teq	\irqstat,#0
+1003:
+		.endm
+
+
+		.macro	irq_prio_table
+		.endm
+
+
diff --git a/include/asm-arm/arch-pnx4008/gpio.h b/include/asm-arm/arch-pnx4008/gpio.h
new file mode 100644
index 000000000..d01bf83d5
--- /dev/null
+++ b/include/asm-arm/arch-pnx4008/gpio.h
@@ -0,0 +1,241 @@
+/*
+ * include/asm-arm/arch-pnx4008/gpio.h
+ *
+ * PNX4008 GPIO driver - header file
+ *
+ * Author: Dmitry Chigirev <source@mvista.com>
+ *
+ * Based on reference code by Iwo Mergler and Z.Tabaaloute from Philips:
+ * Copyright (c) 2005 Koninklijke Philips Electronics N.V.
+ *
+ * 2005 (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 _PNX4008_GPIO_H_
+#define _PNX4008_GPIO_H_
+
+
+/* Block numbers */
+#define GPIO_IN		(0)
+#define GPIO_OUT		(0x100)
+#define GPIO_BID		(0x200)
+#define GPIO_RAM		(0x300)
+#define GPIO_MUX		(0x400)
+
+#define GPIO_TYPE_MASK(K) ((K) & 0x700)
+
+/* INPUT GPIOs */
+/* GPI */
+#define GPI_00		(GPIO_IN | 0)
+#define GPI_01		(GPIO_IN | 1)
+#define GPI_02   	(GPIO_IN | 2)
+#define GPI_03 	 	(GPIO_IN | 3)
+#define GPI_04   	(GPIO_IN | 4)
+#define GPI_05   	(GPIO_IN | 5)
+#define GPI_06   	(GPIO_IN | 6)
+#define GPI_07   	(GPIO_IN | 7)
+#define GPI_08   	(GPIO_IN | 8)
+#define GPI_09   	(GPIO_IN | 9)
+#define U1_RX 		(GPIO_IN | 15)
+#define U2_HTCS 	(GPIO_IN | 16)
+#define U2_RX	 	(GPIO_IN | 17)
+#define U3_RX		(GPIO_IN | 18)
+#define U4_RX		(GPIO_IN | 19)
+#define U5_RX		(GPIO_IN | 20)
+#define U6_IRRX 	(GPIO_IN | 21)
+#define U7_HCTS 	(GPIO_IN | 22)
+#define U7_RX		(GPIO_IN | 23)
+/* MISC IN */
+#define SPI1_DATIN	(GPIO_IN | 25)
+#define DISP_SYNC	(GPIO_IN | 26)
+#define SPI2_DATIN	(GPIO_IN | 27)
+#define GPI_11  	(GPIO_IN | 28)
+
+#define GPIO_IN_MASK   0x1eff83ff
+
+/* OUTPUT GPIOs */
+/* GPO */
+#define GPO_00		(GPIO_OUT | 0)
+#define GPO_01   	(GPIO_OUT | 1)
+#define GPO_02   	(GPIO_OUT | 2)
+#define GPO_03 	 	(GPIO_OUT | 3)
+#define GPO_04   	(GPIO_OUT | 4)
+#define GPO_05   	(GPIO_OUT | 5)
+#define GPO_06   	(GPIO_OUT | 6)
+#define GPO_07   	(GPIO_OUT | 7)
+#define GPO_08		(GPIO_OUT | 8)
+#define GPO_09   	(GPIO_OUT | 9)
+#define GPO_10   	(GPIO_OUT | 10)
+#define GPO_11 	 	(GPIO_OUT | 11)
+#define GPO_12   	(GPIO_OUT | 12)
+#define GPO_13   	(GPIO_OUT | 13)
+#define GPO_14   	(GPIO_OUT | 14)
+#define GPO_15   	(GPIO_OUT | 15)
+#define GPO_16  	(GPIO_OUT | 16)
+#define GPO_17 	 	(GPIO_OUT | 17)
+#define GPO_18   	(GPIO_OUT | 18)
+#define GPO_19   	(GPIO_OUT | 19)
+#define GPO_20   	(GPIO_OUT | 20)
+#define GPO_21   	(GPIO_OUT | 21)
+#define GPO_22   	(GPIO_OUT | 22)
+#define GPO_23   	(GPIO_OUT | 23)
+
+#define GPIO_OUT_MASK   0xffffff
+
+/* BIDIRECTIONAL GPIOs */
+/* RAM pins */
+#define RAM_D19		(GPIO_RAM | 0)
+#define RAM_D20  	(GPIO_RAM | 1)
+#define RAM_D21  	(GPIO_RAM | 2)
+#define RAM_D22 	(GPIO_RAM | 3)
+#define RAM_D23  	(GPIO_RAM | 4)
+#define RAM_D24  	(GPIO_RAM | 5)
+#define RAM_D25  	(GPIO_RAM | 6)
+#define RAM_D26  	(GPIO_RAM | 7)
+#define RAM_D27		(GPIO_RAM | 8)
+#define RAM_D28  	(GPIO_RAM | 9)
+#define RAM_D29  	(GPIO_RAM | 10)
+#define RAM_D30 	(GPIO_RAM | 11)
+#define RAM_D31  	(GPIO_RAM | 12)
+
+#define GPIO_RAM_MASK   0x1fff
+
+/* I/O pins */
+#define GPIO_00  	(GPIO_BID | 25)
+#define GPIO_01 	(GPIO_BID | 26)
+#define GPIO_02  	(GPIO_BID | 27)
+#define GPIO_03  	(GPIO_BID | 28)
+#define GPIO_04 	(GPIO_BID | 29)
+#define GPIO_05  	(GPIO_BID | 30)
+
+#define GPIO_BID_MASK   0x7e000000
+
+/* Non-GPIO multiplexed PIOs. For multiplexing with GPIO, please use GPIO macros */
+#define GPIO_SDRAM_SEL 	(GPIO_MUX | 3)
+
+#define GPIO_MUX_MASK   0x8
+
+/* Extraction/assembly macros */
+#define GPIO_BIT_MASK(K) ((K) & 0x1F)
+#define GPIO_BIT(K) (1 << GPIO_BIT_MASK(K))
+#define GPIO_ISMUX(K) ((GPIO_TYPE_MASK(K) == GPIO_MUX) && (GPIO_BIT(K) & GPIO_MUX_MASK))
+#define GPIO_ISRAM(K) ((GPIO_TYPE_MASK(K) == GPIO_RAM) && (GPIO_BIT(K) & GPIO_RAM_MASK))
+#define GPIO_ISBID(K) ((GPIO_TYPE_MASK(K) == GPIO_BID) && (GPIO_BIT(K) & GPIO_BID_MASK))
+#define GPIO_ISOUT(K) ((GPIO_TYPE_MASK(K) == GPIO_OUT) && (GPIO_BIT(K) & GPIO_OUT_MASK))
+#define GPIO_ISIN(K)  ((GPIO_TYPE_MASK(K) == GPIO_IN) && (GPIO_BIT(K) & GPIO_IN_MASK))
+
+/* Start Enable Pin Interrupts - table 58 page 66 */
+
+#define SE_PIN_BASE_INT   32
+
+#define SE_U7_RX_INT            63
+#define SE_U7_HCTS_INT          62
+#define SE_BT_CLKREQ_INT        61
+#define SE_U6_IRRX_INT          60
+/*59 unused*/
+#define SE_U5_RX_INT            58
+#define SE_GPI_11_INT           57
+#define SE_U3_RX_INT            56
+#define SE_U2_HCTS_INT          55
+#define SE_U2_RX_INT            54
+#define SE_U1_RX_INT            53
+#define SE_DISP_SYNC_INT        52
+/*51 unused*/
+#define SE_SDIO_INT_N           50
+#define SE_MSDIO_START_INT      49
+#define SE_GPI_06_INT           48
+#define SE_GPI_05_INT           47
+#define SE_GPI_04_INT           46
+#define SE_GPI_03_INT           45
+#define SE_GPI_02_INT           44
+#define SE_GPI_01_INT           43
+#define SE_GPI_00_INT           42
+#define SE_SYSCLKEN_PIN_INT     41
+#define SE_SPI1_DATAIN_INT      40
+#define SE_GPI_07_INT           39
+#define SE_SPI2_DATAIN_INT      38
+#define SE_GPI_10_INT           37
+#define SE_GPI_09_INT           36
+#define SE_GPI_08_INT           35
+/*34-32 unused*/
+
+/* Start Enable Internal Interrupts - table 57 page 65 */
+
+#define SE_INT_BASE_INT   0
+
+#define SE_TS_IRQ               31
+#define SE_TS_P_INT             30
+#define SE_TS_AUX_INT           29
+/*27-28 unused*/
+#define SE_USB_AHB_NEED_CLK_INT 26
+#define SE_MSTIMER_INT          25
+#define SE_RTC_INT              24
+#define SE_USB_NEED_CLK_INT     23
+#define SE_USB_INT              22
+#define SE_USB_I2C_INT          21
+#define SE_USB_OTG_TIMER_INT    20
+#define SE_USB_OTG_ATX_INT_N    19
+/*18 unused*/
+#define SE_DSP_GPIO4_INT        17
+#define SE_KEY_IRQ              16
+#define SE_DSP_SLAVEPORT_INT    15
+#define SE_DSP_GPIO1_INT        14
+#define SE_DSP_GPIO0_INT        13
+#define SE_DSP_AHB_INT          12
+/*11-6 unused*/
+#define SE_GPIO_05_INT          5
+#define SE_GPIO_04_INT          4
+#define SE_GPIO_03_INT          3
+#define SE_GPIO_02_INT          2
+#define SE_GPIO_01_INT          1
+#define SE_GPIO_00_INT          0
+
+#define START_INT_REG_BIT(irq) (1<<((irq)&0x1F))
+
+#define START_INT_ER_REG(irq)     IO_ADDRESS((PNX4008_PWRMAN_BASE + 0x20 + (((irq)&(0x1<<5))>>1)))
+#define START_INT_RSR_REG(irq)    IO_ADDRESS((PNX4008_PWRMAN_BASE + 0x24 + (((irq)&(0x1<<5))>>1)))
+#define START_INT_SR_REG(irq)     IO_ADDRESS((PNX4008_PWRMAN_BASE + 0x28 + (((irq)&(0x1<<5))>>1)))
+#define START_INT_APR_REG(irq)    IO_ADDRESS((PNX4008_PWRMAN_BASE + 0x2C + (((irq)&(0x1<<5))>>1)))
+
+extern int pnx4008_gpio_register_pin(unsigned short pin);
+extern int pnx4008_gpio_unregister_pin(unsigned short pin);
+extern unsigned long pnx4008_gpio_read_pin(unsigned short pin);
+extern int pnx4008_gpio_write_pin(unsigned short pin, int output);
+extern int pnx4008_gpio_set_pin_direction(unsigned short pin, int output);
+extern int pnx4008_gpio_read_pin_direction(unsigned short pin);
+extern int pnx4008_gpio_set_pin_mux(unsigned short pin, int output);
+extern int pnx4008_gpio_read_pin_mux(unsigned short pin);
+
+static inline void start_int_umask(u8 irq)
+{
+	__raw_writel(__raw_readl(START_INT_ER_REG(irq)) |
+		     START_INT_REG_BIT(irq), START_INT_ER_REG(irq));
+}
+
+static inline void start_int_mask(u8 irq)
+{
+	__raw_writel(__raw_readl(START_INT_ER_REG(irq)) &
+		     ~START_INT_REG_BIT(irq), START_INT_ER_REG(irq));
+}
+
+static inline void start_int_ack(u8 irq)
+{
+	__raw_writel(START_INT_REG_BIT(irq), START_INT_RSR_REG(irq));
+}
+
+static inline void start_int_set_falling_edge(u8 irq)
+{
+	__raw_writel(__raw_readl(START_INT_APR_REG(irq)) &
+		     ~START_INT_REG_BIT(irq), START_INT_APR_REG(irq));
+}
+
+static inline void start_int_set_rising_edge(u8 irq)
+{
+	__raw_writel(__raw_readl(START_INT_APR_REG(irq)) |
+		     START_INT_REG_BIT(irq), START_INT_APR_REG(irq));
+}
+
+#endif				/* _PNX4008_GPIO_H_ */
diff --git a/include/asm-arm/arch-pnx4008/hardware.h b/include/asm-arm/arch-pnx4008/hardware.h
new file mode 100644
index 000000000..a4410397a
--- /dev/null
+++ b/include/asm-arm/arch-pnx4008/hardware.h
@@ -0,0 +1,32 @@
+/*
+ * linux/include/asm-arm/arch-pnx4008/hardware.h
+ *
+ * Copyright (c) 2005 MontaVista Software, Inc. <source@mvista.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
+ */
+#ifndef __ASM_ARCH_HARDWARE_H
+#define __ASM_ARCH_HARDWARE_H
+
+#include <asm/sizes.h>
+#include <asm/arch/platform.h>
+
+/* Start of virtual addresses for IO devices */
+#define IO_BASE         0xF0000000
+
+/* This macro relies on fact that for all HW i/o addresses bits 20-23 are 0 */
+#define IO_ADDRESS(x)  (((((x) & 0xff000000) >> 4) | ((x) & 0xfffff)) | IO_BASE)
+
+#endif
diff --git a/include/asm-arm/arch-pnx4008/io.h b/include/asm-arm/arch-pnx4008/io.h
new file mode 100644
index 000000000..29ee43955
--- /dev/null
+++ b/include/asm-arm/arch-pnx4008/io.h
@@ -0,0 +1,21 @@
+
+/*
+ *  include/asm-arm/arch-pnx4008/io.h
+ *
+ * Author: Dmitry Chigirev <chigirev@ru.mvista.com>
+ *
+ * 2005 (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_ARM_ARCH_IO_H
+#define __ASM_ARM_ARCH_IO_H
+
+#define IO_SPACE_LIMIT 0xffffffff
+
+#define __io(a)			((void __iomem *)(a))
+#define __mem_pci(a)		(a)
+
+#endif
diff --git a/include/asm-arm/arch-pnx4008/irq.h b/include/asm-arm/arch-pnx4008/irq.h
new file mode 100644
index 000000000..fabff5dc3
--- /dev/null
+++ b/include/asm-arm/arch-pnx4008/irq.h
@@ -0,0 +1,42 @@
+/*
+ * include/asm-arm/arch-pnx4008/irq.h
+ *
+ * PNX4008 IRQ controller driver - header file
+ * this one is used in entry-arnv.S as well so it cannot contain C code
+ *
+ * Copyright (c) 2005 Philips Semiconductors
+ * Copyright (c) 2005 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 as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ */
+#ifndef __PNX4008_IRQ_H__
+#define __PNX4008_IRQ_H__
+
+#define MIC_VA_BASE             IO_ADDRESS(PNX4008_INTCTRLMIC_BASE)
+#define SIC1_VA_BASE            IO_ADDRESS(PNX4008_INTCTRLSIC1_BASE)
+#define SIC2_VA_BASE            IO_ADDRESS(PNX4008_INTCTRLSIC2_BASE)
+
+/* Manual: Chapter 20, page 195 */
+
+#define INTC_BIT(irq) (1<< ((irq) & 0x1F))
+
+#define INTC_ER(irq)    IO_ADDRESS((PNX4008_INTCTRLMIC_BASE + 0x0 + (((irq)&(0x3<<5))<<9)))
+#define INTC_RSR(irq)   IO_ADDRESS((PNX4008_INTCTRLMIC_BASE + 0x4 + (((irq)&(0x3<<5))<<9)))
+#define INTC_SR(irq)    IO_ADDRESS((PNX4008_INTCTRLMIC_BASE + 0x8 + (((irq)&(0x3<<5))<<9)))
+#define INTC_APR(irq)   IO_ADDRESS((PNX4008_INTCTRLMIC_BASE + 0xC + (((irq)&(0x3<<5))<<9)))
+#define INTC_ATR(irq)   IO_ADDRESS((PNX4008_INTCTRLMIC_BASE + 0x10 + (((irq)&(0x3<<5))<<9)))
+#define INTC_ITR(irq)   IO_ADDRESS((PNX4008_INTCTRLMIC_BASE + 0x14 + (((irq)&(0x3<<5))<<9)))
+
+#define START_INT_REG_BIT(irq) (1<<((irq)&0x1F))
+
+#define START_INT_ER_REG(irq)     IO_ADDRESS((PNX4008_PWRMAN_BASE + 0x20 + (((irq)&(0x1<<5))>>1)))
+#define START_INT_RSR_REG(irq)    IO_ADDRESS((PNX4008_PWRMAN_BASE + 0x24 + (((irq)&(0x1<<5))>>1)))
+#define START_INT_SR_REG(irq)     IO_ADDRESS((PNX4008_PWRMAN_BASE + 0x28 + (((irq)&(0x1<<5))>>1)))
+#define START_INT_APR_REG(irq)    IO_ADDRESS((PNX4008_PWRMAN_BASE + 0x2C + (((irq)&(0x1<<5))>>1)))
+
+extern void __init pnx4008_init_irq(void);
+
+#endif /* __PNX4008_IRQ_H__ */
diff --git a/include/asm-arm/arch-pnx4008/irqs.h b/include/asm-arm/arch-pnx4008/irqs.h
new file mode 100644
index 000000000..13ec7ed0f
--- /dev/null
+++ b/include/asm-arm/arch-pnx4008/irqs.h
@@ -0,0 +1,215 @@
+/*
+ * include/asm-arm/arch-pnx4008/irqs.h
+ *
+ * PNX4008 IRQ controller driver - header file
+ *
+ * Author: Dmitry Chigirev <source@mvista.com>
+ *
+ * 2005 (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 __PNX4008_IRQS_h__
+#define __PNX4008_IRQS_h__
+
+#define NR_IRQS         96
+
+/*Manual: table 259, page 199*/
+
+/*SUB2 Interrupt Routing (SIC2)*/
+
+#define SIC2_BASE_INT   64
+
+#define CLK_SWITCH_ARM_INT 95	/*manual: Clkswitch ARM  */
+#define CLK_SWITCH_DSP_INT 94	/*manual: ClkSwitch DSP  */
+#define CLK_SWITCH_AUD_INT 93	/*manual: Clkswitch AUD  */
+#define GPI_06_INT         92
+#define GPI_05_INT         91
+#define GPI_04_INT         90
+#define GPI_03_INT         89
+#define GPI_02_INT         88
+#define GPI_01_INT         87
+#define GPI_00_INT         86
+#define BT_CLKREQ_INT      85
+#define SPI1_DATIN_INT     84
+#define U5_RX_INT          83
+#define SDIO_INT_N         82
+#define CAM_HS_INT         81
+#define CAM_VS_INT         80
+#define GPI_07_INT         79
+#define DISP_SYNC_INT      78
+#define DSP_INT8           77
+#define U7_HCTS_INT        76
+#define GPI_10_INT         75
+#define GPI_09_INT         74
+#define GPI_08_INT         73
+#define DSP_INT7           72
+#define U2_HCTS_INT        71
+#define SPI2_DATIN_INT     70
+#define GPIO_05_INT        69
+#define GPIO_04_INT        68
+#define GPIO_03_INT        67
+#define GPIO_02_INT        66
+#define GPIO_01_INT        65
+#define GPIO_00_INT        64
+
+/*Manual: table 258, page 198*/
+
+/*SUB1 Interrupt Routing (SIC1)*/
+
+#define SIC1_BASE_INT   32
+
+#define USB_I2C_INT        63
+#define USB_DEV_HP_INT     62
+#define USB_DEV_LP_INT     61
+#define USB_DEV_DMA_INT    60
+#define USB_HOST_INT       59
+#define USB_OTG_ATX_INT_N  58
+#define USB_OTG_TIMER_INT  57
+#define SW_INT             56
+#define SPI1_INT           55
+#define KEY_IRQ            54
+#define DSP_M_INT          53
+#define RTC_INT            52
+#define I2C_1_INT          51
+#define I2C_2_INT          50
+#define PLL1_LOCK_INT      49
+#define PLL2_LOCK_INT      48
+#define PLL3_LOCK_INT      47
+#define PLL4_LOCK_INT      46
+#define PLL5_LOCK_INT      45
+#define SPI2_INT           44
+#define DSP_INT1           43
+#define DSP_INT2           42
+#define DSP_TDM_INT2       41
+#define TS_AUX_INT         40
+#define TS_IRQ             39
+#define TS_P_INT           38
+#define UOUT1_TO_PAD_INT   37
+#define GPI_11_INT         36
+#define DSP_INT4           35
+#define JTAG_COMM_RX_INT   34
+#define JTAG_COMM_TX_INT   33
+#define DSP_INT3           32
+
+/*Manual: table 257, page 197*/
+
+/*MAIN Interrupt Routing*/
+
+#define MAIN_BASE_INT   0
+
+#define SUB2_FIQ_N         31	/*active low */
+#define SUB1_FIQ_N         30	/*active low */
+#define JPEG_INT           29
+#define DMA_INT            28
+#define MSTIMER_INT        27
+#define IIR1_INT           26
+#define IIR2_INT           25
+#define IIR7_INT           24
+#define DSP_TDM_INT0       23
+#define DSP_TDM_INT1       22
+#define DSP_P_INT          21
+#define DSP_INT0           20
+#define DUM_INT            19
+#define UOUT0_TO_PAD_INT   18
+#define MP4_ENC_INT        17
+#define MP4_DEC_INT        16
+#define SD0_INT            15
+#define MBX_INT            14
+#define SD1_INT            13
+#define MS_INT_N           12
+#define FLASH_INT          11 /*NAND*/
+#define IIR6_INT           10
+#define IIR5_INT           9
+#define IIR4_INT           8
+#define IIR3_INT           7
+#define WATCH_INT          6
+#define HSTIMER_INT        5
+#define ARCH_TIMER_IRQ     HSTIMER_INT
+#define CAM_INT            4
+#define PRNG_INT           3
+#define CRYPTO_INT         2
+#define SUB2_IRQ_N         1	/*active low */
+#define SUB1_IRQ_N         0	/*active low */
+
+#define PNX4008_IRQ_TYPES \
+{                                           /*IRQ #'s: */         \
+IRQT_LOW,  IRQT_LOW,  IRQT_LOW,  IRQT_HIGH, /*  0, 1, 2, 3 */     \
+IRQT_LOW,  IRQT_HIGH, IRQT_HIGH, IRQT_HIGH, /*  4, 5, 6, 7 */     \
+IRQT_HIGH, IRQT_HIGH, IRQT_HIGH, IRQT_HIGH, /*  8, 9,10,11 */     \
+IRQT_LOW,  IRQT_HIGH, IRQT_HIGH, IRQT_HIGH, /* 12,13,14,15 */     \
+IRQT_HIGH, IRQT_HIGH, IRQT_HIGH, IRQT_HIGH, /* 16,17,18,19 */     \
+IRQT_HIGH, IRQT_HIGH, IRQT_HIGH, IRQT_HIGH, /* 20,21,22,23 */     \
+IRQT_HIGH, IRQT_HIGH, IRQT_HIGH, IRQT_HIGH, /* 24,25,26,27 */     \
+IRQT_HIGH, IRQT_HIGH, IRQT_LOW,  IRQT_LOW,  /* 28,29,30,31 */     \
+IRQT_HIGH, IRQT_LOW,  IRQT_HIGH, IRQT_HIGH, /* 32,33,34,35 */     \
+IRQT_HIGH, IRQT_HIGH, IRQT_FALLING, IRQT_HIGH, /* 36,37,38,39 */  \
+IRQT_HIGH, IRQT_HIGH, IRQT_HIGH, IRQT_HIGH, /* 40,41,42,43 */     \
+IRQT_HIGH, IRQT_HIGH, IRQT_HIGH, IRQT_HIGH, /* 44,45,46,47 */     \
+IRQT_HIGH, IRQT_HIGH, IRQT_LOW,  IRQT_LOW,  /* 48,49,50,51 */     \
+IRQT_HIGH, IRQT_HIGH, IRQT_HIGH, IRQT_HIGH, /* 52,53,54,55 */     \
+IRQT_HIGH, IRQT_HIGH, IRQT_LOW,  IRQT_HIGH, /* 56,57,58,59 */     \
+IRQT_HIGH, IRQT_HIGH, IRQT_HIGH, IRQT_HIGH, /* 60,61,62,63 */     \
+IRQT_HIGH, IRQT_HIGH, IRQT_HIGH, IRQT_HIGH, /* 64,65,66,67 */     \
+IRQT_HIGH, IRQT_HIGH, IRQT_HIGH, IRQT_HIGH, /* 68,69,70,71 */     \
+IRQT_HIGH, IRQT_HIGH, IRQT_HIGH, IRQT_HIGH, /* 72,73,74,75 */     \
+IRQT_HIGH, IRQT_HIGH, IRQT_HIGH, IRQT_HIGH, /* 76,77,78,79 */     \
+IRQT_HIGH, IRQT_HIGH, IRQT_HIGH, IRQT_HIGH, /* 80,81,82,83 */     \
+IRQT_HIGH, IRQT_HIGH, IRQT_HIGH, IRQT_HIGH, /* 84,85,86,87 */     \
+IRQT_HIGH, IRQT_HIGH, IRQT_HIGH, IRQT_HIGH, /* 88,89,90,91 */     \
+IRQT_HIGH, IRQT_HIGH, IRQT_HIGH, IRQT_HIGH, /* 92,93,94,95 */     \
+}
+
+/* Start Enable Pin Interrupts - table 58 page 66 */
+
+#define SE_PIN_BASE_INT   32
+
+#define SE_U7_RX_INT            63
+#define SE_U7_HCTS_INT          62
+#define SE_BT_CLKREQ_INT        61
+#define SE_U6_IRRX_INT          60
+/*59 unused*/
+#define SE_U5_RX_INT            58
+#define SE_GPI_11_INT           57
+#define SE_U3_RX_INT            56
+#define SE_U2_HCTS_INT          55
+#define SE_U2_RX_INT            54
+#define SE_U1_RX_INT            53
+#define SE_DISP_SYNC_INT        52
+/*51 unused*/
+#define SE_SDIO_INT_N           50
+#define SE_MSDIO_START_INT      49
+#define SE_GPI_06_INT           48
+#define SE_GPI_05_INT           47
+#define SE_GPI_04_INT           46
+#define SE_GPI_03_INT           45
+#define SE_GPI_02_INT           44
+#define SE_GPI_01_INT           43
+#define SE_GPI_00_INT           42
+#define SE_SYSCLKEN_PIN_INT     41
+#define SE_SPI1_DATAIN_INT      40
+#define SE_GPI_07_INT           39
+#define SE_SPI2_DATAIN_INT      38
+#define SE_GPI_10_INT           37
+#define SE_GPI_09_INT           36
+#define SE_GPI_08_INT           35
+/*34-32 unused*/
+
+/* Start Enable Internal Interrupts - table 57 page 65 */
+
+#define SE_INT_BASE_INT   0
+
+#define SE_TS_IRQ               31
+#define SE_TS_P_INT             30
+#define SE_TS_AUX_INT           29
+/*27-28 unused*/
+#define SE_USB_AHB_NEED_CLK_INT 26
+#define SE_MSTIMER_INT          25
+#define SE_RTC_INT              24
+#define SE_USB_NEED_CLK_INT     23
+#define SE_USB_INT              22
+#define SE_USB_I2C_INT          21
+#define SE_USB_OTG_TIMER_INT    20
+
+#endif /* __PNX4008_IRQS_h__ */
diff --git a/include/asm-arm/arch-pnx4008/memory.h b/include/asm-arm/arch-pnx4008/memory.h
new file mode 100644
index 000000000..0d8268a95
--- /dev/null
+++ b/include/asm-arm/arch-pnx4008/memory.h
@@ -0,0 +1,24 @@
+/*
+ * linux/include/asm-arm/arch-pnx4008/memory.h
+ *
+ * Copyright (c) 2005 Philips Semiconductors
+ * Copyright (c) 2005 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 as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ */
+
+#ifndef __ASM_ARCH_MEMORY_H
+#define __ASM_ARCH_MEMORY_H
+
+/*
+ * Physical DRAM offset.
+ */
+#define PHYS_OFFSET     (0x80000000)
+
+#define __virt_to_bus(x) ((x) - PAGE_OFFSET + PHYS_OFFSET)
+#define __bus_to_virt(x) ((x) + PAGE_OFFSET - PHYS_OFFSET)
+
+#endif
diff --git a/include/asm-arm/arch-pnx4008/param.h b/include/asm-arm/arch-pnx4008/param.h
new file mode 100644
index 000000000..95d5f547b
--- /dev/null
+++ b/include/asm-arm/arch-pnx4008/param.h
@@ -0,0 +1,21 @@
+/*
+ *  linux/include/asm-arm/arch-pnx4008/param.h
+ *
+ *  Copyright (C) 1999 ARM 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
+ */
+
+#define HZ 100
diff --git a/include/asm-arm/arch-pnx4008/platform.h b/include/asm-arm/arch-pnx4008/platform.h
new file mode 100644
index 000000000..485a3651b
--- /dev/null
+++ b/include/asm-arm/arch-pnx4008/platform.h
@@ -0,0 +1,69 @@
+/*
+ * include/asm-arm/arch-pnx4008/platfrom.h
+ *
+ * PNX4008 Base addresses - header file
+ *
+ * Author: Dmitry Chigirev <source@mvista.com>
+ *
+ * Based on reference code received from Philips:
+ * Copyright (C) 2003 Philips Semiconductors
+ *
+ * 2005 (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_PLATFORM_H__
+#define __ASM_ARCH_PLATFORM_H__
+
+#define PNX4008_IRAM_BASE		0x08000000
+#define PNX4008_IRAM_SIZE		0x00010000
+#define PNX4008_YUV_SLAVE_BASE		0x10000000
+#define PNX4008_DUM_SLAVE_BASE		0x18000000
+#define PNX4008_NDF_FLASH_BASE		0x20020000
+#define PNX4008_SPI1_BASE		0x20088000
+#define PNX4008_SPI2_BASE		0x20090000
+#define PNX4008_SD_CONFIG_BASE		0x20098000
+#define PNX4008_FLASH_DATA		0x200B0000
+#define PNX4008_MLC_FLASH_BASE		0x200B8000
+#define PNX4008_JPEG_CONFIG_BASE	0x300A0000
+#define PNX4008_DMA_CONFIG_BASE		0x31000000
+#define PNX4008_USB_CONFIG_BASE		0x31020000
+#define PNX4008_SDRAM_CFG_BASE		0x31080000
+#define PNX4008_AHB2FAB_BASE		0x40000000
+#define PNX4008_PWRMAN_BASE		0x40004000
+#define PNX4008_INTCTRLMIC_BASE		0x40008000
+#define PNX4008_INTCTRLSIC1_BASE	0x4000C000
+#define PNX4008_INTCTRLSIC2_BASE	0x40010000
+#define PNX4008_HSUART1_BASE		0x40014000
+#define PNX4008_HSUART2_BASE		0x40018000
+#define PNX4008_HSUART7_BASE		0x4001C000
+#define PNX4008_RTC_BASE		0x40024000
+#define PNX4008_PIO_BASE		0x40028000
+#define PNX4008_MSTIMER_BASE		0x40034000
+#define PNX4008_HSTIMER_BASE		0x40038000
+#define PNX4008_WDOG_BASE		0x4003C000
+#define PNX4008_DEBUG_BASE		0x40040000
+#define PNX4008_TOUCH1_BASE		0x40048000
+#define PNX4008_KEYSCAN_BASE		0x40050000
+#define PNX4008_UARTCTRL_BASE		0x40054000
+#define PNX4008_PWM_BASE		0x4005C000
+#define PNX4008_UART3_BASE		0x40080000
+#define PNX4008_UART4_BASE		0x40088000
+#define PNX4008_UART5_BASE		0x40090000
+#define PNX4008_UART6_BASE		0x40098000
+#define PNX4008_I2C1_BASE		0x400A0000
+#define PNX4008_I2C2_BASE		0x400A8000
+#define PNX4008_MAGICGATE_BASE		0x400B0000
+#define PNX4008_DUMCONF_BASE		0x400B8000
+#define PNX4008_DUM_MAINCFG_BASE       	0x400BC000
+#define PNX4008_DSP_BASE		0x400C0000
+#define PNX4008_PROFCOUNTER_BASE	0x400C8000
+#define PNX4008_CRYPTO_BASE		0x400D0000
+#define PNX4008_CAMIFCONF_BASE		0x400D8000
+#define PNX4008_YUV2RGB_BASE		0x400E0000
+#define PNX4008_AUDIOCONFIG_BASE	0x400E8000
+
+#endif
diff --git a/include/asm-arm/arch-pnx4008/pm.h b/include/asm-arm/arch-pnx4008/pm.h
new file mode 100644
index 000000000..bac1634cb
--- /dev/null
+++ b/include/asm-arm/arch-pnx4008/pm.h
@@ -0,0 +1,33 @@
+/*
+ * include/asm-arm/arch-pnx4008/pm.h
+ *
+ * PNX4008 Power Management Routiness - header file
+ *
+ * Authors: Vitaly Wool, Dmitry Chigirev <source@mvista.com>
+ *
+ * 2005 (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_PNX4008_PM_H
+#define __ASM_ARCH_PNX4008_PM_H
+
+#ifndef __ASSEMBLER__
+#include "irq.h"
+#include "irqs.h"
+#include "clock.h"
+
+extern void pnx4008_pm_idle(void);
+extern void pnx4008_pm_suspend(void);
+extern unsigned int pnx4008_cpu_suspend_sz;
+extern void pnx4008_cpu_suspend(void);
+extern unsigned int pnx4008_cpu_standby_sz;
+extern void pnx4008_cpu_standby(void);
+
+extern int pnx4008_startup_pll(struct clk *);
+extern int pnx4008_shutdown_pll(struct clk *);
+
+#endif				/* ASSEMBLER */
+#endif				/* __ASM_ARCH_PNX4008_PM_H */
diff --git a/include/asm-arm/arch-pnx4008/system.h b/include/asm-arm/arch-pnx4008/system.h
new file mode 100644
index 000000000..6e3da70ab
--- /dev/null
+++ b/include/asm-arm/arch-pnx4008/system.h
@@ -0,0 +1,38 @@
+/*
+ * linux/include/asm-arm/arch-pnx4008/system.h
+ *
+ * Copyright (C) 2003 Philips Semiconductors
+ * Copyright (C) 2005 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 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
+ */
+#ifndef __ASM_ARCH_SYSTEM_H
+#define __ASM_ARCH_SYSTEM_H
+
+#include <asm/hardware.h>
+#include <asm/io.h>
+#include <asm/arch/platform.h>
+
+static void arch_idle(void)
+{
+	cpu_do_idle();
+}
+
+static inline void arch_reset(char mode)
+{
+	cpu_reset(0);
+}
+
+#endif
diff --git a/include/asm-arm/arch-pnx4008/timex.h b/include/asm-arm/arch-pnx4008/timex.h
new file mode 100644
index 000000000..ee470a390
--- /dev/null
+++ b/include/asm-arm/arch-pnx4008/timex.h
@@ -0,0 +1,73 @@
+/*
+ * include/asm-arm/arch-pnx4008/timex.h
+ *
+ * PNX4008 timers header file
+ *
+ * Author: Dmitry Chigirev <source@mvista.com>
+ *
+ * 2005 (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 __PNX4008_TIMEX_H
+#define __PNX4008_TIMEX_H
+
+#include <asm/hardware.h>
+#include <asm/io.h>
+
+#define CLOCK_TICK_RATE		1000000
+
+#define TICKS2USECS(x)	(x)
+
+/* MilliSecond Timer - Chapter 21 Page 202 */
+
+#define MSTIM_INT     IO_ADDRESS((PNX4008_MSTIMER_BASE + 0x0))
+#define MSTIM_CTRL    IO_ADDRESS((PNX4008_MSTIMER_BASE + 0x4))
+#define MSTIM_COUNTER IO_ADDRESS((PNX4008_MSTIMER_BASE + 0x8))
+#define MSTIM_MCTRL   IO_ADDRESS((PNX4008_MSTIMER_BASE + 0x14))
+#define MSTIM_MATCH0  IO_ADDRESS((PNX4008_MSTIMER_BASE + 0x18))
+#define MSTIM_MATCH1  IO_ADDRESS((PNX4008_MSTIMER_BASE + 0x1c))
+
+/* High Speed Timer - Chpater 22, Page 205 */
+
+#define HSTIM_INT     IO_ADDRESS((PNX4008_HSTIMER_BASE + 0x0))
+#define HSTIM_CTRL    IO_ADDRESS((PNX4008_HSTIMER_BASE + 0x4))
+#define HSTIM_COUNTER IO_ADDRESS((PNX4008_HSTIMER_BASE + 0x8))
+#define HSTIM_PMATCH  IO_ADDRESS((PNX4008_HSTIMER_BASE + 0xC))
+#define HSTIM_PCOUNT  IO_ADDRESS((PNX4008_HSTIMER_BASE + 0x10))
+#define HSTIM_MCTRL   IO_ADDRESS((PNX4008_HSTIMER_BASE + 0x14))
+#define HSTIM_MATCH0  IO_ADDRESS((PNX4008_HSTIMER_BASE + 0x18))
+#define HSTIM_MATCH1  IO_ADDRESS((PNX4008_HSTIMER_BASE + 0x1c))
+#define HSTIM_MATCH2  IO_ADDRESS((PNX4008_HSTIMER_BASE + 0x20))
+#define HSTIM_CCR     IO_ADDRESS((PNX4008_HSTIMER_BASE + 0x28))
+#define HSTIM_CR0     IO_ADDRESS((PNX4008_HSTIMER_BASE + 0x2C))
+#define HSTIM_CR1     IO_ADDRESS((PNX4008_HSTIMER_BASE + 0x30))
+
+/* IMPORTANT: both timers are UPCOUNTING */
+
+/* xSTIM_MCTRL bit definitions */
+#define MR0_INT        1
+#define RESET_COUNT0   (1<<1)
+#define STOP_COUNT0    (1<<2)
+#define MR1_INT        (1<<3)
+#define RESET_COUNT1   (1<<4)
+#define STOP_COUNT1    (1<<5)
+#define MR2_INT        (1<<6)
+#define RESET_COUNT2   (1<<7)
+#define STOP_COUNT2    (1<<8)
+
+/* xSTIM_CTRL bit definitions */
+#define COUNT_ENAB     1
+#define RESET_COUNT    (1<<1)
+#define DEBUG_EN       (1<<2)
+
+/* xSTIM_INT bit definitions */
+#define MATCH0_INT     1
+#define MATCH1_INT     (1<<1)
+#define MATCH2_INT     (1<<2)
+#define RTC_TICK0      (1<<4)
+#define RTC_TICK1      (1<<5)
+
+#endif
diff --git a/include/asm-arm/arch-pnx4008/uncompress.h b/include/asm-arm/arch-pnx4008/uncompress.h
new file mode 100644
index 000000000..8fa4d24b7
--- /dev/null
+++ b/include/asm-arm/arch-pnx4008/uncompress.h
@@ -0,0 +1,46 @@
+/*
+ *  linux/include/asm-arm/arch-pnx4008/uncompress.h
+ *
+ *  Copyright (C) 1999 ARM Limited
+ *  Copyright (C) 2006 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 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
+ */
+
+#define UART5_BASE 0x40090000
+
+#define UART5_DR    (*(volatile unsigned char *) (UART5_BASE))
+#define UART5_FR    (*(volatile unsigned char *) (UART5_BASE + 18))
+
+static __inline__ void putc(char c)
+{
+	while (UART5_FR & (1 << 5))
+		barrier();
+
+	UART5_DR = c;
+}
+
+/*
+ * This does not append a newline
+ */
+static inline void flush(void)
+{
+}
+
+/*
+ * nothing to do
+ */
+#define arch_decomp_setup()
+#define arch_decomp_wdog()
diff --git a/include/asm-arm/arch-pnx4008/vmalloc.h b/include/asm-arm/arch-pnx4008/vmalloc.h
new file mode 100644
index 000000000..140d925f6
--- /dev/null
+++ b/include/asm-arm/arch-pnx4008/vmalloc.h
@@ -0,0 +1,20 @@
+/*
+ * include/asm-arm/arch-pnx4008/vmalloc.h
+ *
+ * Author: Vitaly Wool <source@mvista.com>
+ *
+ * 2006 (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.
+ */
+
+/*
+ * Just any arbitrary offset to the start of the vmalloc VM area: the
+ * current 8MB value just means that there will be a 8MB "hole" after the
+ * physical memory until the kernel virtual memory starts.  That means that
+ * any out-of-bounds memory accesses will hopefully be caught.
+ * The vmalloc() routines leaves a hole of 4kB between each vmalloced
+ * area for the same reason. ;)
+ */
+#define VMALLOC_END       (PAGE_OFFSET + 0x10000000)
diff --git a/include/asm-arm/arch-pxa/trizeps4.h b/include/asm-arm/arch-pxa/trizeps4.h
new file mode 100644
index 000000000..641d0ec11
--- /dev/null
+++ b/include/asm-arm/arch-pxa/trizeps4.h
@@ -0,0 +1,106 @@
+/************************************************************************
+ * Include file for TRIZEPS4 SoM and ConXS eval-board
+ * Copyright (c) Jürgen Schindele
+ * 2006
+ ************************************************************************/
+
+/*
+ * Includes/Defines
+ */
+#ifndef _TRIPEPS4_H_
+#define _TRIPEPS4_H_
+
+/* physical memory regions */
+#define TRIZEPS4_FLASH_PHYS	(PXA_CS0_PHYS)  /* Flash region */
+#define TRIZEPS4_DISK_PHYS	(PXA_CS1_PHYS)  /* Disk On Chip region */
+#define TRIZEPS4_ETH_PHYS	(PXA_CS2_PHYS)  /* Ethernet DM9000 region */
+#define TRIZEPS4_PIC_PHYS	(PXA_CS3_PHYS)	/* Logic chip on ConXS-Board */
+#define TRIZEPS4_SDRAM_BASE	0xa0000000      /* SDRAM region */
+
+#define TRIZEPS4_CFSR_PHYS	(PXA_CS3_PHYS)			/* Logic chip on ConXS-Board CSFR register */
+#define TRIZEPS4_BOCR_PHYS	(PXA_CS3_PHYS+0x02000000)	/* Logic chip on ConXS-Board BOCR register */
+#define TRIZEPS4_IRCR_PHYS	(PXA_CS3_PHYS+0x02400000)	/* Logic chip on ConXS-Board IRCR register*/
+#define TRIZEPS4_UPSR_PHYS	(PXA_CS3_PHYS+0x02800000)	/* Logic chip on ConXS-Board UPSR register*/
+#define TRIZEPS4_DICR_PHYS	(PXA_CS3_PHYS+0x03800000)	/* Logic chip on ConXS-Board DICR register*/
+
+/* virtual memory regions */
+#define TRIZEPS4_DISK_VIRT	0xF0000000	/* Disk On Chip region */
+
+#define TRIZEPS4_PIC_VIRT	0xF0100000	/* not used */
+#define TRIZEPS4_CFSR_VIRT	0xF0100000
+#define TRIZEPS4_BOCR_VIRT	0xF0200000
+#define TRIZEPS4_DICR_VIRT	0xF0300000
+#define TRIZEPS4_IRCR_VIRT	0xF0400000
+#define TRIZEPS4_UPSR_VIRT	0xF0500000
+
+/* size of flash */
+#define TRIZEPS4_FLASH_SIZE	0x02000000	/* Flash size 32 MB */
+
+/* Ethernet Controller Davicom DM9000 */
+#define GPIO_DM9000		101
+#define TRIZEPS4_ETH_IRQ	IRQ_GPIO(GPIO_DM9000)
+
+/* UCB1400 audio / TS-controller */
+#define GPIO_UCB1400		1
+#define TRIZEPS4_UCB1400_IRQ	IRQ_GPIO(GPIO_UCB1400)
+
+/* PCMCIA socket Compact Flash */
+#define GPIO_PCD		11		/* PCMCIA Card Detect */
+#define TRIZEPS4_CD_IRQ		IRQ_GPIO(GPIO_PCD)
+#define GPIO_PRDY		13		/* READY / nINT */
+#define TRIZEPS4_READY_NINT	IRQ_GPIO(GPIO_PRDY)
+
+/* MMC socket */
+#define GPIO_MMC_DET		12
+#define TRIZEPS4_MMC_IRQ	IRQ_GPIO(GPIO_MMC_DET)
+
+/* LEDS using tx2 / rx2 */
+#define GPIO_SYS_BUSY_LED	46
+#define GPIO_HEARTBEAT_LED	47
+
+/* Off-module PIC on ConXS board */
+#define GPIO_PIC		0
+#define TRIZEPS4_PIC_IRQ	IRQ_GPIO(GPIO_PIC)
+
+#define CFSR_P2V(x)		((x) - TRIZEPS4_CFSR_PHYS + TRIZEPS4_CFSR_VIRT)
+#define CFSR_V2P(x)		((x) - TRIZEPS4_CFSR_VIRT + TRIZEPS4_CFSR_PHYS)
+
+#define BCR_P2V(x)		((x) - TRIZEPS4_BOCR_PHYS + TRIZEPS4_BOCR_VIRT)
+#define BCR_V2P(x)		((x) - TRIZEPS4_BOCR_VIRT + TRIZEPS4_BOCR_PHYS)
+
+#define DCR_P2V(x)		((x) - TRIZEPS4_DICR_PHYS + TRIZEPS4_DICR_VIRT)
+#define DCR_V2P(x)		((x) - TRIZEPS4_DICR_VIRT + TRIZEPS4_DICR_PHYS)
+
+#ifndef __ASSEMBLY__
+#define ConXS_CFSR		(*((volatile unsigned short *)CFSR_P2V(0x0C000000)))
+#define ConXS_BCR		(*((volatile unsigned short *)BCR_P2V(0x0E000000)))
+#define ConXS_DCR		(*((volatile unsigned short *)DCR_P2V(0x0F800000)))
+#else
+#define ConXS_CFSR		CFSR_P2V(0x0C000000)
+#define ConXS_BCR		BCR_P2V(0x0E000000)
+#define ConXS_DCR		DCR_P2V(0x0F800000)
+#endif
+
+#define ConXS_CFSR_BVD_MASK	0x0003
+#define ConXS_CFSR_BVD1		(1 << 0)
+#define ConXS_CFSR_BVD2		(1 << 1)
+#define ConXS_CFSR_VS_MASK	0x000C
+#define ConXS_CFSR_VS1		(1 << 2)
+#define ConXS_CFSR_VS2		(1 << 3)
+#define ConXS_CFSR_VS_5V	(0x3 << 2)
+#define ConXS_CFSR_VS_3V3	0x0
+
+#define ConXS_BCR_S0_POW_EN0	(1 << 0)
+#define ConXS_BCR_S0_POW_EN1	(1 << 1)
+#define ConXS_BCR_L_DISP	(1 << 4)
+#define ConXS_BCR_CF_BUF_EN	(1 << 5)
+#define ConXS_BCR_CF_RESET	(1 << 7)
+#define ConXS_BCR_S0_VCC_3V3	0x1
+#define ConXS_BCR_S0_VCC_5V0	0x2
+#define ConXS_BCR_S0_VPP_12V	0x4
+#define ConXS_BCR_S0_VPP_3V3	0x8
+
+#define ConXS_IRCR_MODE		(1 << 0)
+#define ConXS_IRCR_SD		(1 << 1)
+
+#endif /* _TRIPEPS4_H_ */
diff --git a/include/asm-arm/arch-s3c2410/regs-power.h b/include/asm-arm/arch-s3c2410/regs-power.h
new file mode 100644
index 000000000..6c319ea2a
--- /dev/null
+++ b/include/asm-arm/arch-s3c2410/regs-power.h
@@ -0,0 +1,34 @@
+/* linux/include/asm/arch-s3c2410/regs-power.h
+ *
+ * Copyright (c) 2003,2004,2005,2006 Simtec Electronics <linux@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.
+ *
+ * S3C24XX power control register definitions
+*/
+
+#ifndef __ASM_ARM_REGS_PWR
+#define __ASM_ARM_REGS_PWR __FILE__
+
+#define S3C24XX_PWRREG(x) ((x) + S3C24XX_VA_CLKPWR)
+
+#define S3C2412_PWRMODECON	S3C24XX_PWRREG(0x20)
+#define S3C2412_PWRCFG		S3C24XX_PWRREG(0x24)
+
+#define S3C2412_PWRCFG_BATF_IGNORE		(0<<0)
+#define S3C2412_PWRCFG_BATF_SLEEP		(3<<0)
+#define S3C2412_PWRCFG_BATF_MASK		(3<<0)
+
+#define S3C2412_PWRCFG_STANDBYWFI_IGNORE	(0<<6)
+#define S3C2412_PWRCFG_STANDBYWFI_IDLE		(1<<6)
+#define S3C2412_PWRCFG_STANDBYWFI_STOP		(2<<6)
+#define S3C2412_PWRCFG_STANDBYWFI_SLEEP		(3<<6)
+#define S3C2412_PWRCFG_STANDBYWFI_MASK		(3<<6)
+
+#define S3C2412_PWRCFG_RTC_MASKIRQ		(1<<8)
+#define S3C2412_PWRCFG_NAND_NORST		(1<<9)
+
+#endif /* __ASM_ARM_REGS_PWR */
diff --git a/include/asm-arm/dyntick.h b/include/asm-arm/dyntick.h
new file mode 100644
index 000000000..19fab2d2b
--- /dev/null
+++ b/include/asm-arm/dyntick.h
@@ -0,0 +1,6 @@
+#ifndef _ASMARM_DYNTICK_H
+#define _ASMARM_DYNTICK_H
+
+#include <asm/mach/time.h>
+
+#endif /* _ASMARM_DYNTICK_H */
diff --git a/include/asm-arm/hw_irq.h b/include/asm-arm/hw_irq.h
new file mode 100644
index 000000000..ea8569719
--- /dev/null
+++ b/include/asm-arm/hw_irq.h
@@ -0,0 +1,20 @@
+/*
+ * Nothing to see here yet
+ */
+#ifndef _ARCH_ARM_HW_IRQ_H
+#define _ARCH_ARM_HW_IRQ_H
+
+#include <asm/mach/irq.h>
+
+#if defined(CONFIG_NO_IDLE_HZ)
+# include <asm/dyntick.h>
+# define handle_dynamic_tick(action)					\
+	if (!(action->flags & IRQF_TIMER) && system_timer->dyn_tick) {	\
+		write_seqlock(&xtime_lock);				\
+		if (system_timer->dyn_tick->state & DYN_TICK_ENABLED)	\
+			system_timer->dyn_tick->handler(irq, 0, regs);	\
+		write_sequnlock(&xtime_lock);				\
+	}
+#endif
+
+#endif
diff --git a/include/asm-arm/mach/serial_at91.h b/include/asm-arm/mach/serial_at91.h
new file mode 100644
index 000000000..1290bb328
--- /dev/null
+++ b/include/asm-arm/mach/serial_at91.h
@@ -0,0 +1,33 @@
+/*
+ *  linux/include/asm-arm/mach/serial_at91.h
+ *
+ *  Based on serial_sa1100.h  by Nicolas Pitre
+ *
+ *  Copyright (C) 2002 ATMEL Rousset
+ *
+ *  Low level machine dependent UART functions.
+ */
+
+struct uart_port;
+
+/*
+ * This is a temporary structure for registering these
+ * functions; it is intended to be discarded after boot.
+ */
+struct at91_port_fns {
+	void	(*set_mctrl)(struct uart_port *, u_int);
+	u_int	(*get_mctrl)(struct uart_port *);
+	void	(*enable_ms)(struct uart_port *);
+	void	(*pm)(struct uart_port *, u_int, u_int);
+	int	(*set_wake)(struct uart_port *, u_int);
+	int	(*open)(struct uart_port *);
+	void	(*close)(struct uart_port *);
+};
+
+#if defined(CONFIG_SERIAL_AT91)
+void at91_register_uart_fns(struct at91_port_fns *fns);
+#else
+#define at91_register_uart_fns(fns) do { } while (0)
+#endif
+
+
diff --git a/include/asm-arm/page-nommu.h b/include/asm-arm/page-nommu.h
new file mode 100644
index 000000000..a1bcad060
--- /dev/null
+++ b/include/asm-arm/page-nommu.h
@@ -0,0 +1,51 @@
+/*
+ *  linux/include/asm-arm/page-nommu.h
+ *
+ *  Copyright (C) 2004 Hyok S. Choi
+ *
+ * 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 _ASMARM_PAGE_NOMMU_H
+#define _ASMARM_PAGE_NOMMU_H
+
+#if !defined(CONFIG_SMALL_TASKS) && PAGE_SHIFT < 13
+#define KTHREAD_SIZE (8192)
+#else
+#define KTHREAD_SIZE PAGE_SIZE
+#endif
+ 
+#define get_user_page(vaddr)		__get_free_page(GFP_KERNEL)
+#define free_user_page(page, addr)	free_page(addr)
+
+#define clear_page(page)	memset((page), 0, PAGE_SIZE)
+#define copy_page(to,from)	memcpy((to), (from), PAGE_SIZE)
+
+#define clear_user_page(page, vaddr, pg)	clear_page(page)
+#define copy_user_page(to, from, vaddr, pg)	copy_page(to, from)
+
+/*
+ * These are used to make use of C type-checking..
+ */
+typedef unsigned long pte_t;
+typedef unsigned long pmd_t;
+typedef unsigned long pgd_t[2];
+typedef unsigned long pgprot_t;
+
+#define pte_val(x)      (x)
+#define pmd_val(x)      (x)
+#define pgd_val(x)	((x)[0])
+#define pgprot_val(x)   (x)
+
+#define __pte(x)        (x)
+#define __pmd(x)        (x)
+#define __pgprot(x)     (x)
+
+/* to align the pointer to the (next) page boundary */
+#define PAGE_ALIGN(addr)	(((addr)+PAGE_SIZE-1)&PAGE_MASK)
+
+extern unsigned long memory_start;
+extern unsigned long memory_end;
+
+#endif
diff --git a/include/asm-arm/pgtable-nommu.h b/include/asm-arm/pgtable-nommu.h
new file mode 100644
index 000000000..c1b264dff
--- /dev/null
+++ b/include/asm-arm/pgtable-nommu.h
@@ -0,0 +1,122 @@
+/*
+ *  linux/include/asm-arm/pgtable-nommu.h
+ *
+ *  Copyright (C) 1995-2002 Russell King
+ *  Copyright (C) 2004  Hyok S. Choi
+ *
+ * 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 _ASMARM_PGTABLE_NOMMU_H
+#define _ASMARM_PGTABLE_NOMMU_H
+
+#ifndef __ASSEMBLY__
+
+#include <linux/slab.h>
+#include <asm/processor.h>
+#include <asm/page.h>
+#include <asm/io.h>
+
+/*
+ * Trivial page table functions.
+ */
+#define pgd_present(pgd)	(1)
+#define pgd_none(pgd)		(0)
+#define pgd_bad(pgd)		(0)
+#define pgd_clear(pgdp)
+#define kern_addr_valid(addr)	(1)
+#define	pmd_offset(a, b)	((void *)0)
+/* FIXME */
+/*
+ * PMD_SHIFT determines the size of the area a second-level page table can map
+ * PGDIR_SHIFT determines what a third-level page table entry can map
+ */
+#define PGDIR_SHIFT		21
+
+#define PGDIR_SIZE		(1UL << PGDIR_SHIFT)
+#define PGDIR_MASK		(~(PGDIR_SIZE-1))
+/* FIXME */
+
+#define PAGE_NONE	__pgprot(0)
+#define PAGE_SHARED	__pgprot(0)
+#define PAGE_COPY	__pgprot(0)
+#define PAGE_READONLY	__pgprot(0)
+#define PAGE_KERNEL	__pgprot(0)
+
+//extern void paging_init(struct meminfo *, struct machine_desc *);
+#define swapper_pg_dir ((pgd_t *) 0)
+
+#define __swp_type(x)		(0)
+#define __swp_offset(x)		(0)
+#define __swp_entry(typ,off)	((swp_entry_t) { ((typ) | ((off) << 7)) })
+#define __pte_to_swp_entry(pte)	((swp_entry_t) { pte_val(pte) })
+#define __swp_entry_to_pte(x)	((pte_t) { (x).val })
+
+
+typedef pte_t *pte_addr_t;
+
+static inline int pte_file(pte_t pte) { return 0; }
+
+/*
+ * ZERO_PAGE is a global shared page that is always zero: used
+ * for zero-mapped memory areas etc..
+ */
+#define ZERO_PAGE(vaddr)	(virt_to_page(0))
+
+/*
+ * Mark the prot value as uncacheable and unbufferable.
+ */
+#define pgprot_noncached(prot)	__pgprot(0)
+#define pgprot_writecombine(prot) __pgprot(0)
+
+
+/*
+ * These would be in other places but having them here reduces the diffs.
+ */
+extern unsigned int kobjsize(const void *objp);
+extern int is_in_rom(unsigned long);
+
+/*
+ * No page table caches to initialise.
+ */
+#define pgtable_cache_init()	do { } while (0)
+#define io_remap_page_range	remap_page_range
+#define io_remap_pfn_range	remap_pfn_range
+
+#define MK_IOSPACE_PFN(space, pfn)	(pfn)
+#define GET_IOSPACE(pfn)		0
+#define GET_PFN(pfn)			(pfn)
+
+
+/*
+ * All 32bit addresses are effectively valid for vmalloc...
+ * Sort of meaningless for non-VM targets.
+ */
+#define	VMALLOC_START	0
+#define	VMALLOC_END	0xffffffff
+
+#define FIRST_USER_ADDRESS      (0)
+
+#else 
+
+/*
+ * dummy tlb and user structures.
+ */
+#define v3_tlb_fns	(0)
+#define v4_tlb_fns	(0)
+#define v4wb_tlb_fns	(0)
+#define v4wbi_tlb_fns	(0)
+#define v6_tlb_fns	(0)
+
+#define v3_user_fns	(0)
+#define v4_user_fns	(0)
+#define v4_mc_user_fns	(0)
+#define v4wb_user_fns	(0)
+#define v4wt_user_fns	(0)
+#define v6_user_fns	(0)
+#define xscale_mc_user_fns (0)
+
+#endif /*__ASSEMBLY__*/
+
+#endif /* _ASMARM_PGTABLE_H */
diff --git a/include/asm-arm/thread_notify.h b/include/asm-arm/thread_notify.h
new file mode 100644
index 000000000..8866e5216
--- /dev/null
+++ b/include/asm-arm/thread_notify.h
@@ -0,0 +1,48 @@
+/*
+ *  linux/include/asm-arm/thread_notify.h
+ *
+ *  Copyright (C) 2006 Russell King.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#ifndef ASMARM_THREAD_NOTIFY_H
+#define ASMARM_THREAD_NOTIFY_H
+
+#ifdef __KERNEL__
+
+#ifndef __ASSEMBLY__
+
+#include <linux/notifier.h>
+#include <asm/thread_info.h>
+
+static inline int thread_register_notifier(struct notifier_block *n)
+{
+	extern struct atomic_notifier_head thread_notify_head;
+	return atomic_notifier_chain_register(&thread_notify_head, n);
+}
+
+static inline void thread_unregister_notifier(struct notifier_block *n)
+{
+	extern struct atomic_notifier_head thread_notify_head;
+	atomic_notifier_chain_unregister(&thread_notify_head, n);
+}
+
+static inline void thread_notify(unsigned long rc, struct thread_info *thread)
+{
+	extern struct atomic_notifier_head thread_notify_head;
+	atomic_notifier_call_chain(&thread_notify_head, rc, thread);
+}
+
+#endif
+
+/*
+ * These are the reason codes for the thread notifier.
+ */
+#define THREAD_NOTIFY_FLUSH	0
+#define THREAD_NOTIFY_RELEASE	1
+#define THREAD_NOTIFY_SWITCH	2
+
+#endif
+#endif
diff --git a/include/asm-cris/Kbuild b/include/asm-cris/Kbuild
new file mode 100644
index 000000000..14498d5a2
--- /dev/null
+++ b/include/asm-cris/Kbuild
@@ -0,0 +1,5 @@
+include include/asm-generic/Kbuild.asm
+
+header-y += arch-v10/ arch-v32/
+
+unifdef-y += rs485.h
diff --git a/include/asm-cris/arch-v10/Kbuild b/include/asm-cris/arch-v10/Kbuild
new file mode 100644
index 000000000..d7f27dc09
--- /dev/null
+++ b/include/asm-cris/arch-v10/Kbuild
@@ -0,0 +1,2 @@
+header-y += ptrace.h
+header-y += user.h
diff --git a/include/asm-cris/arch-v32/Kbuild b/include/asm-cris/arch-v32/Kbuild
new file mode 100644
index 000000000..d7f27dc09
--- /dev/null
+++ b/include/asm-cris/arch-v32/Kbuild
@@ -0,0 +1,2 @@
+header-y += ptrace.h
+header-y += user.h
diff --git a/include/asm-frv/Kbuild b/include/asm-frv/Kbuild
new file mode 100644
index 000000000..c68e1680d
--- /dev/null
+++ b/include/asm-frv/Kbuild
@@ -0,0 +1 @@
+include include/asm-generic/Kbuild.asm
diff --git a/include/asm-generic/Kbuild b/include/asm-generic/Kbuild
new file mode 100644
index 000000000..3c06be381
--- /dev/null
+++ b/include/asm-generic/Kbuild
@@ -0,0 +1,12 @@
+header-y += atomic.h
+header-y += errno-base.h
+header-y += errno.h
+header-y += fcntl.h
+header-y += ioctl.h
+header-y += ipc.h
+header-y += mman.h
+header-y += signal.h
+header-y += statfs.h
+
+unifdef-y += resource.h
+unifdef-y += siginfo.h
diff --git a/include/asm-generic/Kbuild.asm b/include/asm-generic/Kbuild.asm
new file mode 100644
index 000000000..a84c3d88a
--- /dev/null
+++ b/include/asm-generic/Kbuild.asm
@@ -0,0 +1,34 @@
+unifdef-y += a.out.h
+unifdef-y += auxvec.h
+unifdef-y += byteorder.h
+unifdef-y += errno.h
+unifdef-y += fcntl.h
+unifdef-y += ioctl.h
+unifdef-y += ioctls.h
+unifdef-y += ipcbuf.h
+unifdef-y += mman.h
+unifdef-y += msgbuf.h
+unifdef-y += param.h
+unifdef-y += poll.h
+unifdef-y += posix_types.h
+unifdef-y += ptrace.h
+unifdef-y += resource.h
+unifdef-y += sembuf.h
+unifdef-y += shmbuf.h
+unifdef-y += sigcontext.h
+unifdef-y += siginfo.h
+unifdef-y += signal.h
+unifdef-y += socket.h
+unifdef-y += sockios.h
+unifdef-y += stat.h
+unifdef-y += statfs.h
+unifdef-y += termbits.h
+unifdef-y += termios.h
+unifdef-y += types.h
+unifdef-y += unistd.h
+unifdef-y += user.h
+
+# These probably shouldn't be exported
+unifdef-y += shmparam.h
+unifdef-y += elf.h
+unifdef-y += page.h
diff --git a/include/asm-generic/audit_change_attr.h b/include/asm-generic/audit_change_attr.h
new file mode 100644
index 000000000..50764550a
--- /dev/null
+++ b/include/asm-generic/audit_change_attr.h
@@ -0,0 +1,22 @@
+__NR_chmod,
+__NR_fchmod,
+#ifdef __NR_chown
+__NR_chown,
+__NR_fchown,
+__NR_lchown,
+#endif
+__NR_setxattr,
+__NR_lsetxattr,
+__NR_fsetxattr,
+__NR_removexattr,
+__NR_lremovexattr,
+__NR_fremovexattr,
+#ifdef __NR_fchownat
+__NR_fchownat,
+__NR_fchmodat,
+#endif
+#ifdef __NR_chown32
+__NR_chown32,
+__NR_fchown32,
+__NR_lchown32,
+#endif
diff --git a/include/asm-generic/audit_dir_write.h b/include/asm-generic/audit_dir_write.h
new file mode 100644
index 000000000..6621bd82c
--- /dev/null
+++ b/include/asm-generic/audit_dir_write.h
@@ -0,0 +1,18 @@
+__NR_rename,
+__NR_mkdir,
+__NR_rmdir,
+#ifdef __NR_creat
+__NR_creat,
+#endif
+__NR_link,
+__NR_unlink,
+__NR_symlink,
+__NR_mknod,
+#ifdef __NR_mkdirat
+__NR_mkdirat,
+__NR_mknodat,
+__NR_unlinkat,
+__NR_renameat,
+__NR_linkat,
+__NR_symlinkat,
+#endif
diff --git a/include/asm-generic/audit_read.h b/include/asm-generic/audit_read.h
new file mode 100644
index 000000000..0e87464d9
--- /dev/null
+++ b/include/asm-generic/audit_read.h
@@ -0,0 +1,8 @@
+__NR_readlink,
+__NR_quotactl,
+__NR_listxattr,
+__NR_llistxattr,
+__NR_flistxattr,
+__NR_getxattr,
+__NR_lgetxattr,
+__NR_fgetxattr,
diff --git a/include/asm-generic/audit_write.h b/include/asm-generic/audit_write.h
new file mode 100644
index 000000000..f10d367fb
--- /dev/null
+++ b/include/asm-generic/audit_write.h
@@ -0,0 +1,11 @@
+#include <asm-generic/audit_dir_write.h>
+__NR_acct,
+__NR_swapon,
+__NR_quotactl,
+__NR_truncate,
+#ifdef __NR_truncate64
+__NR_truncate64,
+#endif
+#ifdef __NR_bind
+__NR_bind,		/* bind can affect fs object only in one way... */
+#endif
diff --git a/include/asm-h8300/Kbuild b/include/asm-h8300/Kbuild
new file mode 100644
index 000000000..c68e1680d
--- /dev/null
+++ b/include/asm-h8300/Kbuild
@@ -0,0 +1 @@
+include include/asm-generic/Kbuild.asm
diff --git a/include/asm-i386/Kbuild b/include/asm-i386/Kbuild
new file mode 100644
index 000000000..b75a348d0
--- /dev/null
+++ b/include/asm-i386/Kbuild
@@ -0,0 +1,10 @@
+include include/asm-generic/Kbuild.asm
+
+header-y += boot.h
+header-y += debugreg.h
+header-y += ldt.h
+header-y += ucontext.h
+
+unifdef-y += mtrr.h
+unifdef-y += setup.h
+unifdef-y += vm86.h
diff --git a/include/asm-i386/dwarf2.h b/include/asm-i386/dwarf2.h
new file mode 100644
index 000000000..5d1a8db5a
--- /dev/null
+++ b/include/asm-i386/dwarf2.h
@@ -0,0 +1,54 @@
+#ifndef _DWARF2_H
+#define _DWARF2_H
+
+#ifndef __ASSEMBLY__
+#warning "asm/dwarf2.h should be only included in pure assembly files"
+#endif
+
+/*
+   Macros for dwarf2 CFI unwind table entries.
+   See "as.info" for details on these pseudo ops. Unfortunately
+   they are only supported in very new binutils, so define them
+   away for older version.
+ */
+
+#ifdef CONFIG_UNWIND_INFO
+
+#define CFI_STARTPROC .cfi_startproc
+#define CFI_ENDPROC .cfi_endproc
+#define CFI_DEF_CFA .cfi_def_cfa
+#define CFI_DEF_CFA_REGISTER .cfi_def_cfa_register
+#define CFI_DEF_CFA_OFFSET .cfi_def_cfa_offset
+#define CFI_ADJUST_CFA_OFFSET .cfi_adjust_cfa_offset
+#define CFI_OFFSET .cfi_offset
+#define CFI_REL_OFFSET .cfi_rel_offset
+#define CFI_REGISTER .cfi_register
+#define CFI_RESTORE .cfi_restore
+#define CFI_REMEMBER_STATE .cfi_remember_state
+#define CFI_RESTORE_STATE .cfi_restore_state
+#define CFI_UNDEFINED .cfi_undefined
+
+#else
+
+/* Due to the structure of pre-exisiting code, don't use assembler line
+   comment character # to ignore the arguments. Instead, use a dummy macro. */
+.macro ignore a=0, b=0, c=0, d=0
+.endm
+
+#define CFI_STARTPROC	ignore
+#define CFI_ENDPROC	ignore
+#define CFI_DEF_CFA	ignore
+#define CFI_DEF_CFA_REGISTER	ignore
+#define CFI_DEF_CFA_OFFSET	ignore
+#define CFI_ADJUST_CFA_OFFSET	ignore
+#define CFI_OFFSET	ignore
+#define CFI_REL_OFFSET	ignore
+#define CFI_REGISTER	ignore
+#define CFI_RESTORE	ignore
+#define CFI_REMEMBER_STATE ignore
+#define CFI_RESTORE_STATE ignore
+#define CFI_UNDEFINED ignore
+
+#endif
+
+#endif
diff --git a/include/asm-i386/intel_arch_perfmon.h b/include/asm-i386/intel_arch_perfmon.h
new file mode 100644
index 000000000..134ea9cc5
--- /dev/null
+++ b/include/asm-i386/intel_arch_perfmon.h
@@ -0,0 +1,19 @@
+#ifndef X86_INTEL_ARCH_PERFMON_H
+#define X86_INTEL_ARCH_PERFMON_H 1
+
+#define MSR_ARCH_PERFMON_PERFCTR0		0xc1
+#define MSR_ARCH_PERFMON_PERFCTR1		0xc2
+
+#define MSR_ARCH_PERFMON_EVENTSEL0		0x186
+#define MSR_ARCH_PERFMON_EVENTSEL1		0x187
+
+#define ARCH_PERFMON_EVENTSEL0_ENABLE      (1 << 22)
+#define ARCH_PERFMON_EVENTSEL_INT          (1 << 20)
+#define ARCH_PERFMON_EVENTSEL_OS           (1 << 17)
+#define ARCH_PERFMON_EVENTSEL_USR          (1 << 16)
+
+#define ARCH_PERFMON_UNHALTED_CORE_CYCLES_SEL	(0x3c)
+#define ARCH_PERFMON_UNHALTED_CORE_CYCLES_UMASK	(0x00 << 8)
+#define ARCH_PERFMON_UNHALTED_CORE_CYCLES_PRESENT (1 << 0)
+
+#endif	/* X86_INTEL_ARCH_PERFMON_H */
diff --git a/include/asm-i386/irqflags.h b/include/asm-i386/irqflags.h
new file mode 100644
index 000000000..e1bdb97c0
--- /dev/null
+++ b/include/asm-i386/irqflags.h
@@ -0,0 +1,127 @@
+/*
+ * include/asm-i386/irqflags.h
+ *
+ * IRQ flags handling
+ *
+ * This file gets included from lowlevel asm headers too, to provide
+ * wrapped versions of the local_irq_*() APIs, based on the
+ * raw_local_irq_*() functions from the lowlevel headers.
+ */
+#ifndef _ASM_IRQFLAGS_H
+#define _ASM_IRQFLAGS_H
+
+#ifndef __ASSEMBLY__
+
+static inline unsigned long __raw_local_save_flags(void)
+{
+	unsigned long flags;
+
+	__asm__ __volatile__(
+		"pushfl ; popl %0"
+		: "=g" (flags)
+		: /* no input */
+	);
+
+	return flags;
+}
+
+#define raw_local_save_flags(flags) \
+		do { (flags) = __raw_local_save_flags(); } while (0)
+
+static inline void raw_local_irq_restore(unsigned long flags)
+{
+	__asm__ __volatile__(
+		"pushl %0 ; popfl"
+		: /* no output */
+		:"g" (flags)
+		:"memory", "cc"
+	);
+}
+
+static inline void raw_local_irq_disable(void)
+{
+	__asm__ __volatile__("cli" : : : "memory");
+}
+
+static inline void raw_local_irq_enable(void)
+{
+	__asm__ __volatile__("sti" : : : "memory");
+}
+
+/*
+ * Used in the idle loop; sti takes one instruction cycle
+ * to complete:
+ */
+static inline void raw_safe_halt(void)
+{
+	__asm__ __volatile__("sti; hlt" : : : "memory");
+}
+
+/*
+ * Used when interrupts are already enabled or to
+ * shutdown the processor:
+ */
+static inline void halt(void)
+{
+	__asm__ __volatile__("hlt": : :"memory");
+}
+
+static inline int raw_irqs_disabled_flags(unsigned long flags)
+{
+	return !(flags & (1 << 9));
+}
+
+static inline int raw_irqs_disabled(void)
+{
+	unsigned long flags = __raw_local_save_flags();
+
+	return raw_irqs_disabled_flags(flags);
+}
+
+/*
+ * For spinlocks, etc:
+ */
+static inline unsigned long __raw_local_irq_save(void)
+{
+	unsigned long flags = __raw_local_save_flags();
+
+	raw_local_irq_disable();
+
+	return flags;
+}
+
+#define raw_local_irq_save(flags) \
+		do { (flags) = __raw_local_irq_save(); } while (0)
+
+#endif /* __ASSEMBLY__ */
+
+/*
+ * Do the CPU's IRQ-state tracing from assembly code. We call a
+ * C function, so save all the C-clobbered registers:
+ */
+#ifdef CONFIG_TRACE_IRQFLAGS
+
+# define TRACE_IRQS_ON				\
+	pushl %eax;				\
+	pushl %ecx;				\
+	pushl %edx;				\
+	call trace_hardirqs_on;			\
+	popl %edx;				\
+	popl %ecx;				\
+	popl %eax;
+
+# define TRACE_IRQS_OFF				\
+	pushl %eax;				\
+	pushl %ecx;				\
+	pushl %edx;				\
+	call trace_hardirqs_off;		\
+	popl %edx;				\
+	popl %ecx;				\
+	popl %eax;
+
+#else
+# define TRACE_IRQS_ON
+# define TRACE_IRQS_OFF
+#endif
+
+#endif
diff --git a/include/asm-i386/k8.h b/include/asm-i386/k8.h
new file mode 100644
index 000000000..dfd88a6e6
--- /dev/null
+++ b/include/asm-i386/k8.h
@@ -0,0 +1 @@
+#include <asm-x86_64/k8.h>
diff --git a/include/asm-i386/mach-default/setup_arch.h b/include/asm-i386/mach-default/setup_arch.h
new file mode 100644
index 000000000..fb42099e7
--- /dev/null
+++ b/include/asm-i386/mach-default/setup_arch.h
@@ -0,0 +1,5 @@
+/* Hook to call BIOS initialisation function */
+
+/* no action for generic */
+
+#define ARCH_SETUP
diff --git a/include/asm-i386/mach-visws/setup_arch.h b/include/asm-i386/mach-visws/setup_arch.h
new file mode 100644
index 000000000..33f700ef6
--- /dev/null
+++ b/include/asm-i386/mach-visws/setup_arch.h
@@ -0,0 +1,8 @@
+/* Hook to call BIOS initialisation function */
+
+extern unsigned long sgivwfb_mem_phys;
+extern unsigned long sgivwfb_mem_size;
+
+/* no action for visws */
+
+#define ARCH_SETUP
diff --git a/include/asm-i386/mach-voyager/setup_arch.h b/include/asm-i386/mach-voyager/setup_arch.h
new file mode 100644
index 000000000..84d01ad33
--- /dev/null
+++ b/include/asm-i386/mach-voyager/setup_arch.h
@@ -0,0 +1,10 @@
+#include <asm/voyager.h>
+#define VOYAGER_BIOS_INFO ((struct voyager_bios_info *)(PARAM+0x40))
+
+/* Hook to call BIOS initialisation function */
+
+/* for voyager, pass the voyager BIOS/SUS info area to the detection
+ * routines */
+
+#define ARCH_SETUP	voyager_detect(VOYAGER_BIOS_INFO);
+
diff --git a/include/asm-i386/mach-xen/asm/irqflags.h b/include/asm-i386/mach-xen/asm/irqflags.h
new file mode 100644
index 000000000..dc7fd071a
--- /dev/null
+++ b/include/asm-i386/mach-xen/asm/irqflags.h
@@ -0,0 +1,80 @@
+/*
+ * include/asm-i386/irqflags.h
+ *
+ * IRQ flags handling
+ *
+ * This file gets included from lowlevel asm headers too, to provide
+ * wrapped versions of the local_irq_*() APIs, based on the
+ * raw_local_irq_*() functions from the lowlevel headers.
+ */
+#ifndef _ASM_IRQFLAGS_H
+#define _ASM_IRQFLAGS_H
+
+#ifndef __ASSEMBLY__
+
+#define raw_local_save_flags(flags) \
+		do { (flags) = __raw_local_save_flags(); } while (0)
+
+unsigned long __raw_local_save_flags(void);
+void raw_local_irq_restore(unsigned long flags);
+void raw_local_irq_disable(void);
+void raw_local_irq_enable(void);
+
+/*
+ * Used in the idle loop; sti takes one instruction cycle
+ * to complete:
+ */
+void raw_safe_halt(void);
+
+/*
+ * Used when interrupts are already enabled or to
+ * shutdown the processor:
+ */
+void halt(void);
+
+static inline int raw_irqs_disabled_flags(unsigned long flags)
+{
+	return flags != 0;
+}
+
+int raw_irqs_disabled(void);
+
+/*
+ * For spinlocks, etc:
+ */
+unsigned long __raw_local_irq_save(void);
+#define raw_local_irq_save(flags) \
+		do { (flags) = __raw_local_irq_save(); } while (0)
+
+#endif /* __ASSEMBLY__ */
+
+/*
+ * Do the CPU's IRQ-state tracing from assembly code. We call a
+ * C function, so save all the C-clobbered registers:
+ */
+#ifdef CONFIG_TRACE_IRQFLAGS
+
+# define TRACE_IRQS_ON				\
+	pushl %eax;				\
+	pushl %ecx;				\
+	pushl %edx;				\
+	call trace_hardirqs_on;			\
+	popl %edx;				\
+	popl %ecx;				\
+	popl %eax;
+
+# define TRACE_IRQS_OFF				\
+	pushl %eax;				\
+	pushl %ecx;				\
+	pushl %edx;				\
+	call trace_hardirqs_off;		\
+	popl %edx;				\
+	popl %ecx;				\
+	popl %eax;
+
+#else
+# define TRACE_IRQS_ON
+# define TRACE_IRQS_OFF
+#endif
+
+#endif
diff --git a/include/asm-i386/mach-xen/asm/maddr.h b/include/asm-i386/mach-xen/asm/maddr.h
new file mode 100644
index 000000000..b467320d5
--- /dev/null
+++ b/include/asm-i386/mach-xen/asm/maddr.h
@@ -0,0 +1,160 @@
+#ifndef _I386_MADDR_H
+#define _I386_MADDR_H
+
+#include <xen/features.h>
+#include <xen/interface/xen.h>
+
+/**** MACHINE <-> PHYSICAL CONVERSION MACROS ****/
+#define INVALID_P2M_ENTRY	(~0UL)
+#define FOREIGN_FRAME_BIT	(1UL<<31)
+#define FOREIGN_FRAME(m)	((m) | FOREIGN_FRAME_BIT)
+
+#ifdef CONFIG_XEN
+
+extern unsigned long *phys_to_machine_mapping;
+
+#undef machine_to_phys_mapping
+extern unsigned long *machine_to_phys_mapping;
+extern unsigned int   machine_to_phys_order;
+
+static inline unsigned long pfn_to_mfn(unsigned long pfn)
+{
+	if (xen_feature(XENFEAT_auto_translated_physmap))
+		return pfn;
+	return phys_to_machine_mapping[(unsigned int)(pfn)] &
+		~FOREIGN_FRAME_BIT;
+}
+
+static inline int phys_to_machine_mapping_valid(unsigned long pfn)
+{
+	if (xen_feature(XENFEAT_auto_translated_physmap))
+		return 1;
+	return (phys_to_machine_mapping[pfn] != INVALID_P2M_ENTRY);
+}
+
+static inline unsigned long mfn_to_pfn(unsigned long mfn)
+{
+	extern unsigned long max_mapnr;
+	unsigned long pfn;
+
+	if (xen_feature(XENFEAT_auto_translated_physmap))
+		return mfn;
+
+	if (unlikely((mfn >> machine_to_phys_order) != 0))
+		return max_mapnr;
+
+	/* The array access can fail (e.g., device space beyond end of RAM). */
+	asm (
+		"1:	movl %1,%0\n"
+		"2:\n"
+		".section .fixup,\"ax\"\n"
+		"3:	movl %2,%0\n"
+		"	jmp  2b\n"
+		".previous\n"
+		".section __ex_table,\"a\"\n"
+		"	.align 4\n"
+		"	.long 1b,3b\n"
+		".previous"
+		: "=r" (pfn)
+		: "m" (machine_to_phys_mapping[mfn]), "m" (max_mapnr) );
+
+	return pfn;
+}
+
+/*
+ * We detect special mappings in one of two ways:
+ *  1. If the MFN is an I/O page then Xen will set the m2p entry
+ *     to be outside our maximum possible pseudophys range.
+ *  2. If the MFN belongs to a different domain then we will certainly
+ *     not have MFN in our p2m table. Conversely, if the page is ours,
+ *     then we'll have p2m(m2p(MFN))==MFN.
+ * If we detect a special mapping then it doesn't have a 'struct page'.
+ * We force !pfn_valid() by returning an out-of-range pointer.
+ *
+ * NB. These checks require that, for any MFN that is not in our reservation,
+ * there is no PFN such that p2m(PFN) == MFN. Otherwise we can get confused if
+ * we are foreign-mapping the MFN, and the other domain as m2p(MFN) == PFN.
+ * Yikes! Various places must poke in INVALID_P2M_ENTRY for safety.
+ *
+ * NB2. When deliberately mapping foreign pages into the p2m table, you *must*
+ *      use FOREIGN_FRAME(). This will cause pte_pfn() to choke on it, as we
+ *      require. In all the cases we care about, the FOREIGN_FRAME bit is
+ *      masked (e.g., pfn_to_mfn()) so behaviour there is correct.
+ */
+static inline unsigned long mfn_to_local_pfn(unsigned long mfn)
+{
+	extern unsigned long max_mapnr;
+	unsigned long pfn = mfn_to_pfn(mfn);
+	if ((pfn < max_mapnr)
+	    && !xen_feature(XENFEAT_auto_translated_physmap)
+	    && (phys_to_machine_mapping[pfn] != mfn))
+		return max_mapnr; /* force !pfn_valid() */
+	return pfn;
+}
+
+static inline void set_phys_to_machine(unsigned long pfn, unsigned long mfn)
+{
+	if (xen_feature(XENFEAT_auto_translated_physmap)) {
+		BUG_ON(pfn != mfn && mfn != INVALID_P2M_ENTRY);
+		return;
+	}
+	phys_to_machine_mapping[pfn] = mfn;
+}
+
+
+#else /* !CONFIG_XEN */
+
+#define pfn_to_mfn(pfn) (pfn)
+#define mfn_to_pfn(mfn) (mfn)
+#define mfn_to_local_pfn(mfn) (mfn)
+#define set_phys_to_machine(pfn, mfn) BUG_ON((pfn) != (mfn))
+#define phys_to_machine_mapping_valid(pfn) (1)
+
+#endif /* !CONFIG_XEN */
+
+/* Definitions for machine and pseudophysical addresses. */
+#ifdef CONFIG_X86_PAE
+typedef unsigned long long paddr_t;
+typedef unsigned long long maddr_t;
+#else
+typedef unsigned long paddr_t;
+typedef unsigned long maddr_t;
+#endif
+
+static inline maddr_t phys_to_machine(paddr_t phys)
+{
+	maddr_t machine = pfn_to_mfn(phys >> PAGE_SHIFT);
+	machine = (machine << PAGE_SHIFT) | (phys & ~PAGE_MASK);
+	return machine;
+}
+static inline paddr_t machine_to_phys(maddr_t machine)
+{
+	paddr_t phys = mfn_to_pfn(machine >> PAGE_SHIFT);
+	phys = (phys << PAGE_SHIFT) | (machine & ~PAGE_MASK);
+	return phys;
+}
+
+/* VIRT <-> MACHINE conversion */
+#define virt_to_machine(v)	(phys_to_machine(__pa(v)))
+#define virt_to_mfn(v)		(pfn_to_mfn(__pa(v) >> PAGE_SHIFT))
+#define mfn_to_virt(m)		(__va(mfn_to_pfn(m) << PAGE_SHIFT))
+
+#ifdef CONFIG_X86_PAE
+static inline pte_t pfn_pte_ma(unsigned long page_nr, pgprot_t pgprot)
+{
+	pte_t pte;
+
+	pte.pte_high = (page_nr >> (32 - PAGE_SHIFT)) | \
+					(pgprot_val(pgprot) >> 32);
+	pte.pte_high &= (__supported_pte_mask >> 32);
+	pte.pte_low = ((page_nr << PAGE_SHIFT) | pgprot_val(pgprot)) & \
+							__supported_pte_mask;
+	return pte;
+}
+#else
+#define pfn_pte_ma(pfn, prot)	__pte_ma(((pfn) << PAGE_SHIFT) | pgprot_val(prot))
+#endif
+
+#define __pte_ma(x)	((pte_t) { (x) } )
+
+#endif /* _I386_MADDR_H */
diff --git a/include/asm-i386/mach-xen/asm/stacktrace.h b/include/asm-i386/mach-xen/asm/stacktrace.h
new file mode 100644
index 000000000..5eb9799be
--- /dev/null
+++ b/include/asm-i386/mach-xen/asm/stacktrace.h
@@ -0,0 +1,18 @@
+#ifndef _ASM_STACKTRACE_H
+#define _ASM_STACKTRACE_H 1
+
+/* Generic stack tracer with callbacks */
+
+struct stacktrace_ops {
+	void (*warning)(void *data, char *msg);
+	/* msg must contain %s for the symbol */
+	void (*warning_symbol)(void *data, char *msg, unsigned long symbol);
+	void (*address)(void *data, unsigned long address);
+	/* On negative return stop dumping */
+	int (*stack)(void *data, char *name);
+};
+
+void dump_trace(struct task_struct *tsk, struct pt_regs *regs, unsigned long *stack,
+		struct stacktrace_ops *ops, void *data);
+
+#endif
diff --git a/include/asm-i386/mach-xen/asm/timer.h b/include/asm-i386/mach-xen/asm/timer.h
new file mode 100644
index 000000000..aed164374
--- /dev/null
+++ b/include/asm-i386/mach-xen/asm/timer.h
@@ -0,0 +1,70 @@
+#ifndef _ASMi386_TIMER_H
+#define _ASMi386_TIMER_H
+#include <linux/init.h>
+#include <linux/pm.h>
+
+/**
+ * struct timer_ops - used to define a timer source
+ *
+ * @name: name of the timer.
+ * @init: Probes and initializes the timer. Takes clock= override 
+ *        string as an argument. Returns 0 on success, anything else
+ *        on failure.
+ * @mark_offset: called by the timer interrupt.
+ * @get_offset:  called by gettimeofday(). Returns the number of microseconds
+ *               since the last timer interupt.
+ * @monotonic_clock: returns the number of nanoseconds since the init of the
+ *                   timer.
+ * @delay: delays this many clock cycles.
+ */
+struct timer_opts {
+	char* name;
+	void (*mark_offset)(void);
+	unsigned long (*get_offset)(void);
+	unsigned long long (*monotonic_clock)(void);
+	void (*delay)(unsigned long);
+	unsigned long (*read_timer)(void);
+	int (*suspend)(pm_message_t state);
+	int (*resume)(void);
+};
+
+struct init_timer_opts {
+	int (*init)(char *override);
+	struct timer_opts *opts;
+};
+
+#define TICK_SIZE (tick_nsec / 1000)
+
+extern struct timer_opts* __init select_timer(void);
+extern void clock_fallback(void);
+void setup_pit_timer(void);
+
+/* Modifiers for buggy PIT handling */
+
+extern int pit_latch_buggy;
+
+extern struct timer_opts *cur_timer;
+extern int timer_ack;
+
+/* list of externed timers */
+extern struct timer_opts timer_none;
+extern struct timer_opts timer_pit;
+extern struct init_timer_opts timer_pit_init;
+extern struct init_timer_opts timer_tsc_init;
+#ifdef CONFIG_X86_CYCLONE_TIMER
+extern struct init_timer_opts timer_cyclone_init;
+#endif
+
+extern unsigned long calibrate_tsc(void);
+extern unsigned long read_timer_tsc(void);
+extern void init_cpu_khz(void);
+extern int recalibrate_cpu_khz(void);
+#ifdef CONFIG_HPET_TIMER
+extern struct init_timer_opts timer_hpet_init;
+extern unsigned long calibrate_tsc_hpet(unsigned long *tsc_hpet_quotient_ptr);
+#endif
+
+#ifdef CONFIG_X86_PM_TIMER
+extern struct init_timer_opts timer_pmtmr_init;
+#endif
+#endif
diff --git a/include/asm-i386/mach-xen/setup_arch.h b/include/asm-i386/mach-xen/setup_arch.h
new file mode 100644
index 000000000..ad1995778
--- /dev/null
+++ b/include/asm-i386/mach-xen/setup_arch.h
@@ -0,0 +1,5 @@
+/* Hook to call BIOS initialisation function */
+
+#define ARCH_SETUP machine_specific_arch_setup();
+
+void __init machine_specific_arch_setup(void);
diff --git a/include/asm-i386/mce.h b/include/asm-i386/mce.h
new file mode 100644
index 000000000..7cc1a973b
--- /dev/null
+++ b/include/asm-i386/mce.h
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_MCE
+extern void mcheck_init(struct cpuinfo_x86 *c);
+#else
+#define mcheck_init(c) do {} while(0)
+#endif
diff --git a/include/asm-i386/stacktrace.h b/include/asm-i386/stacktrace.h
new file mode 100644
index 000000000..7d1f6a5cb
--- /dev/null
+++ b/include/asm-i386/stacktrace.h
@@ -0,0 +1 @@
+#include <asm-x86_64/stacktrace.h>
diff --git a/include/asm-i386/tracehook.h b/include/asm-i386/tracehook.h
new file mode 100644
index 000000000..ca49dbf78
--- /dev/null
+++ b/include/asm-i386/tracehook.h
@@ -0,0 +1,49 @@
+/*
+ * Tracing hooks, i386 CPU support
+ */
+
+#ifndef _ASM_TRACEHOOK_H
+#define _ASM_TRACEHOOK_H	1
+
+#include <linux/sched.h>
+#include <asm/ptrace.h>
+
+/*
+ * See linux/tracehook.h for the descriptions of what these need to do.
+ */
+
+#define ARCH_HAS_SINGLE_STEP	(1)
+
+/* These two are defined in arch/i386/kernel/ptrace.c.  */
+void tracehook_enable_single_step(struct task_struct *tsk);
+void tracehook_disable_single_step(struct task_struct *tsk);
+
+static inline int tracehook_single_step_enabled(struct task_struct *tsk)
+{
+	return test_tsk_thread_flag(tsk, TIF_SINGLESTEP);
+}
+
+static inline void tracehook_enable_syscall_trace(struct task_struct *tsk)
+{
+	set_tsk_thread_flag(tsk, TIF_SYSCALL_TRACE);
+}
+
+static inline void tracehook_disable_syscall_trace(struct task_struct *tsk)
+{
+	clear_tsk_thread_flag(tsk, TIF_SYSCALL_TRACE);
+}
+
+static inline void tracehook_abort_syscall(struct pt_regs *regs)
+{
+	regs->orig_eax = -1;
+}
+
+extern const struct utrace_regset_view utrace_i386_native;
+static inline const struct utrace_regset_view *
+utrace_native_view(struct task_struct *tsk)
+{
+	return &utrace_i386_native;
+}
+
+
+#endif
diff --git a/include/asm-i386/tsc.h b/include/asm-i386/tsc.h
new file mode 100644
index 000000000..c13933185
--- /dev/null
+++ b/include/asm-i386/tsc.h
@@ -0,0 +1,48 @@
+/*
+ * linux/include/asm-i386/tsc.h
+ *
+ * i386 TSC related functions
+ */
+#ifndef _ASM_i386_TSC_H
+#define _ASM_i386_TSC_H
+
+#include <asm/processor.h>
+
+/*
+ * Standard way to access the cycle counter on i586+ CPUs.
+ * Currently only used on SMP.
+ *
+ * If you really have a SMP machine with i486 chips or older,
+ * compile for that, and this will just always return zero.
+ * That's ok, it just means that the nicer scheduling heuristics
+ * won't work for you.
+ *
+ * We only use the low 32 bits, and we'd simply better make sure
+ * that we reschedule before that wraps. Scheduling at least every
+ * four billion cycles just basically sounds like a good idea,
+ * regardless of how fast the machine is.
+ */
+typedef unsigned long long cycles_t;
+
+extern unsigned int cpu_khz;
+extern unsigned int tsc_khz;
+
+static inline cycles_t get_cycles(void)
+{
+	unsigned long long ret = 0;
+
+#ifndef CONFIG_X86_TSC
+	if (!cpu_has_tsc)
+		return 0;
+#endif
+
+#if defined(CONFIG_X86_GENERIC) || defined(CONFIG_X86_TSC)
+	rdtscll(ret);
+#endif
+	return ret;
+}
+
+extern void tsc_init(void);
+extern void mark_tsc_unstable(void);
+
+#endif
diff --git a/include/asm-i386/unwind.h b/include/asm-i386/unwind.h
new file mode 100644
index 000000000..f0ac399ba
--- /dev/null
+++ b/include/asm-i386/unwind.h
@@ -0,0 +1,102 @@
+#ifndef _ASM_I386_UNWIND_H
+#define _ASM_I386_UNWIND_H
+
+/*
+ * Copyright (C) 2002-2006 Novell, Inc.
+ *	Jan Beulich <jbeulich@novell.com>
+ * This code is released under version 2 of the GNU GPL.
+ */
+
+#ifdef CONFIG_STACK_UNWIND
+
+#include <linux/sched.h>
+#include <asm/fixmap.h>
+#include <asm/ptrace.h>
+#include <asm/uaccess.h>
+
+struct unwind_frame_info
+{
+	struct pt_regs regs;
+	struct task_struct *task;
+};
+
+#define UNW_PC(frame)        (frame)->regs.eip
+#define UNW_SP(frame)        (frame)->regs.esp
+#ifdef CONFIG_FRAME_POINTER
+#define UNW_FP(frame)        (frame)->regs.ebp
+#define FRAME_RETADDR_OFFSET 4
+#define FRAME_LINK_OFFSET    0
+#define STACK_BOTTOM(tsk)    STACK_LIMIT((tsk)->thread.esp0)
+#define STACK_TOP(tsk)       ((tsk)->thread.esp0)
+#else
+#define UNW_FP(frame) ((void)(frame), 0)
+#endif
+#define STACK_LIMIT(ptr)     (((ptr) - 1) & ~(THREAD_SIZE - 1))
+
+#define UNW_REGISTER_INFO \
+	PTREGS_INFO(eax), \
+	PTREGS_INFO(ecx), \
+	PTREGS_INFO(edx), \
+	PTREGS_INFO(ebx), \
+	PTREGS_INFO(esp), \
+	PTREGS_INFO(ebp), \
+	PTREGS_INFO(esi), \
+	PTREGS_INFO(edi), \
+	PTREGS_INFO(eip)
+
+static inline void arch_unw_init_frame_info(struct unwind_frame_info *info,
+                                            /*const*/ struct pt_regs *regs)
+{
+	if (user_mode_vm(regs))
+		info->regs = *regs;
+	else {
+		memcpy(&info->regs, regs, offsetof(struct pt_regs, esp));
+		info->regs.esp = (unsigned long)&regs->esp;
+		info->regs.xss = __KERNEL_DS;
+	}
+}
+
+static inline void arch_unw_init_blocked(struct unwind_frame_info *info)
+{
+	memset(&info->regs, 0, sizeof(info->regs));
+	info->regs.eip = info->task->thread.eip;
+	info->regs.xcs = __KERNEL_CS;
+	__get_user(info->regs.ebp, (long *)info->task->thread.esp);
+	info->regs.esp = info->task->thread.esp;
+	info->regs.xss = __KERNEL_DS;
+	info->regs.xds = __USER_DS;
+	info->regs.xes = __USER_DS;
+}
+
+extern asmlinkage int arch_unwind_init_running(struct unwind_frame_info *,
+                                               asmlinkage int (*callback)(struct unwind_frame_info *,
+                                                                          void *arg),
+                                               void *arg);
+
+static inline int arch_unw_user_mode(const struct unwind_frame_info *info)
+{
+#if 0 /* This can only work when selector register and EFLAGS saves/restores
+         are properly annotated (and tracked in UNW_REGISTER_INFO). */
+	return user_mode_vm(&info->regs);
+#else
+	return info->regs.eip < PAGE_OFFSET
+	       || (info->regs.eip >= __fix_to_virt(FIX_VDSO)
+	            && info->regs.eip < __fix_to_virt(FIX_VDSO) + PAGE_SIZE)
+	       || info->regs.esp < PAGE_OFFSET;
+#endif
+}
+
+#else
+
+#define UNW_PC(frame) ((void)(frame), 0)
+#define UNW_SP(frame) ((void)(frame), 0)
+#define UNW_FP(frame) ((void)(frame), 0)
+
+static inline int arch_unw_user_mode(const void *info)
+{
+	return 0;
+}
+
+#endif
+
+#endif /* _ASM_I386_UNWIND_H */
diff --git a/include/asm-ia64/Kbuild b/include/asm-ia64/Kbuild
new file mode 100644
index 000000000..15818a18b
--- /dev/null
+++ b/include/asm-ia64/Kbuild
@@ -0,0 +1,17 @@
+include include/asm-generic/Kbuild.asm
+
+header-y += break.h
+header-y += fpu.h
+header-y += fpswa.h
+header-y += gcc_intrin.h
+header-y += ia64regs.h
+header-y += intel_intrin.h
+header-y += intrinsics.h
+header-y += perfmon_default_smpl.h
+header-y += ptrace_offsets.h
+header-y += rse.h
+header-y += setup.h
+header-y += ucontext.h
+
+unifdef-y += perfmon.h
+unifdef-y += ustack.h
diff --git a/include/asm-ia64/fixmap.h b/include/asm-ia64/fixmap.h
new file mode 100644
index 000000000..4b32a8298
--- /dev/null
+++ b/include/asm-ia64/fixmap.h
@@ -0,0 +1,2 @@
+#define clear_fixmap(x)	do {} while (0)
+#define	set_fixmap(x,y)	do {} while (0)
diff --git a/include/asm-ia64/hypercall.h b/include/asm-ia64/hypercall.h
new file mode 100644
index 000000000..837533694
--- /dev/null
+++ b/include/asm-ia64/hypercall.h
@@ -0,0 +1,423 @@
+/******************************************************************************
+ * hypercall.h
+ * 
+ * Linux-specific hypervisor handling.
+ * 
+ * Copyright (c) 2002-2004, K A Fraser
+ * 
+ * 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; or, when distributed
+ * separately from the Linux kernel or incorporated into other
+ * software packages, subject to the following license:
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this source file (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy, modify,
+ * merge, publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * 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 __HYPERCALL_H__
+#define __HYPERCALL_H__
+
+#include <linux/string.h> /* memcpy() */
+
+#ifndef __HYPERVISOR_H__
+# error "please don't include this file directly"
+#endif
+
+/*
+ * Assembler stubs for hyper-calls.
+ */
+
+#define _hypercall0(type, name)					\
+({								\
+	long __res;						\
+	__asm__ __volatile__ (";;\n"				\
+			      "mov r2=%1\n"			\
+			      "break 0x1000 ;;\n"		\
+			      "mov %0=r8 ;;\n"			\
+			      : "=r" (__res)			\
+			      : "J" (__HYPERVISOR_##name)	\
+			      : "r2","r8",			\
+			        "memory" );			\
+	(type)__res;						\
+})
+
+#define _hypercall1(type, name, a1)				\
+({								\
+	long __res;						\
+	__asm__ __volatile__ (";;\n"				\
+			      "mov r14=%2\n"			\
+			      "mov r2=%1\n"			\
+			      "break 0x1000 ;;\n"		\
+			      "mov %0=r8 ;;\n"			\
+			      : "=r" (__res)			\
+			      : "J" (__HYPERVISOR_##name),	\
+				"rI" ((unsigned long)(a1))	\
+			      : "r14","r2","r8",		\
+				"memory" );			\
+	(type)__res;						\
+})
+
+#define _hypercall2(type, name, a1, a2)				\
+({								\
+	long __res;						\
+	__asm__ __volatile__ (";;\n"				\
+			      "mov r14=%2\n"			\
+			      "mov r15=%3\n"			\
+			      "mov r2=%1\n"			\
+			      "break 0x1000 ;;\n"		\
+			      "mov %0=r8 ;;\n"			\
+			      : "=r" (__res)			\
+			      : "J" (__HYPERVISOR_##name),	\
+				"rI" ((unsigned long)(a1)),	\
+				"rI" ((unsigned long)(a2))	\
+			      : "r14","r15","r2","r8",		\
+				"memory" );			\
+	(type)__res;						\
+})
+
+#define _hypercall3(type, name, a1, a2, a3)			\
+({								\
+	long __res;						\
+	__asm__ __volatile__ (";;\n"                            \
+			      "mov r14=%2\n"                    \
+			      "mov r15=%3\n"                    \
+			      "mov r16=%4\n"                    \
+			      "mov r2=%1\n"                     \
+			      "break 0x1000 ;;\n"               \
+			      "mov %0=r8 ;;\n"                  \
+			      : "=r" (__res)                    \
+			      : "J" (__HYPERVISOR_##name),      \
+				"rI" ((unsigned long)(a1)),     \
+				"rI" ((unsigned long)(a2)),     \
+				"rI" ((unsigned long)(a3))      \
+			      : "r14","r15","r16","r2","r8",	\
+			        "memory" );                     \
+	(type)__res;                                            \
+})
+
+#define _hypercall4(type, name, a1, a2, a3, a4)			\
+({								\
+	long __res;						\
+	__asm__ __volatile__ (";;\n"                            \
+			      "mov r14=%2\n"                    \
+			      "mov r15=%3\n"                    \
+			      "mov r16=%4\n"                    \
+			      "mov r17=%5\n"                    \
+			      "mov r2=%1\n"                     \
+			      "break 0x1000 ;;\n"               \
+			      "mov %0=r8 ;;\n"                  \
+			      : "=r" (__res)                    \
+			      : "J" (__HYPERVISOR_##name),      \
+				"rI" ((unsigned long)(a1)),     \
+				"rI" ((unsigned long)(a2)),     \
+				"rI" ((unsigned long)(a3)),     \
+				"rI" ((unsigned long)(a4))      \
+			      : "r14","r15","r16","r2","r8",	\
+			        "r17","memory" );               \
+	(type)__res;                                            \
+})
+
+#define _hypercall5(type, name, a1, a2, a3, a4, a5)		\
+({								\
+	long __res;						\
+	__asm__ __volatile__ (";;\n"                            \
+			      "mov r14=%2\n"                    \
+			      "mov r15=%3\n"                    \
+			      "mov r16=%4\n"                    \
+			      "mov r17=%5\n"                    \
+			      "mov r18=%6\n"                    \
+			      "mov r2=%1\n"                     \
+			      "break 0x1000 ;;\n"               \
+			      "mov %0=r8 ;;\n"                  \
+			      : "=r" (__res)                    \
+			      : "J" (__HYPERVISOR_##name),      \
+				"rI" ((unsigned long)(a1)),     \
+				"rI" ((unsigned long)(a2)),     \
+				"rI" ((unsigned long)(a3)),     \
+				"rI" ((unsigned long)(a4)),     \
+				"rI" ((unsigned long)(a5))      \
+			      : "r14","r15","r16","r2","r8",	\
+			        "r17","r18","memory" );         \
+	(type)__res;                                            \
+})
+
+static inline int
+HYPERVISOR_sched_op_compat(
+    int cmd, unsigned long arg)
+{
+	return _hypercall2(int, sched_op_compat, cmd, arg);
+}
+
+static inline int
+HYPERVISOR_sched_op(
+	int cmd, void *arg)
+{
+	return _hypercall2(int, sched_op, cmd, arg);
+}
+
+static inline long
+HYPERVISOR_set_timer_op(
+    u64 timeout)
+{
+    unsigned long timeout_hi = (unsigned long)(timeout>>32);
+    unsigned long timeout_lo = (unsigned long)timeout;
+    return _hypercall2(long, set_timer_op, timeout_lo, timeout_hi);
+}
+
+static inline int
+HYPERVISOR_dom0_op(
+    dom0_op_t *dom0_op)
+{
+    dom0_op->interface_version = DOM0_INTERFACE_VERSION;
+    return _hypercall1(int, dom0_op, dom0_op);
+}
+
+static inline int
+HYPERVISOR_multicall(
+    void *call_list, int nr_calls)
+{
+    return _hypercall2(int, multicall, call_list, nr_calls);
+}
+
+//XXX xen/ia64 copy_from_guest() is broken.
+//    This is a temporal work around until it is fixed.
+static inline int
+____HYPERVISOR_memory_op(
+    unsigned int cmd, void *arg)
+{
+    return _hypercall2(int, memory_op, cmd, arg);
+}
+
+#include <xen/interface/memory.h>
+#ifdef CONFIG_VMX_GUEST
+# define ia64_xenmem_reservation_op(op, xmr) (0)
+#else
+int ia64_xenmem_reservation_op(unsigned long op,
+		   struct xen_memory_reservation* reservation__);
+#endif
+static inline int
+HYPERVISOR_memory_op(
+    unsigned int cmd, void *arg)
+{
+    switch (cmd) {
+    case XENMEM_increase_reservation:
+    case XENMEM_decrease_reservation:
+    case XENMEM_populate_physmap:
+        return ia64_xenmem_reservation_op(cmd, 
+                                          (struct xen_memory_reservation*)arg);
+    default:
+        return ____HYPERVISOR_memory_op(cmd, arg);
+    }
+    /* NOTREACHED */
+}
+
+static inline int
+HYPERVISOR_event_channel_op(
+    int cmd, void *arg)
+{
+    int rc = _hypercall2(int, event_channel_op, cmd, arg);
+    if (unlikely(rc == -ENOSYS)) {
+        struct evtchn_op op;
+        op.cmd = cmd;
+        memcpy(&op.u, arg, sizeof(op.u));
+        rc = _hypercall1(int, event_channel_op_compat, &op);
+    }
+    return rc;
+}
+
+static inline int
+HYPERVISOR_acm_op(
+	unsigned int cmd, void *arg)
+{
+    return _hypercall2(int, acm_op, cmd, arg);
+}
+
+static inline int
+HYPERVISOR_xen_version(
+    int cmd, void *arg)
+{
+    return _hypercall2(int, xen_version, cmd, arg);
+}
+
+static inline int
+HYPERVISOR_console_io(
+    int cmd, int count, char *str)
+{
+    return _hypercall3(int, console_io, cmd, count, str);
+}
+
+static inline int
+HYPERVISOR_physdev_op(
+    int cmd, void *arg)
+{
+    int rc = _hypercall2(int, physdev_op, cmd, arg);
+    if (unlikely(rc == -ENOSYS)) {
+        struct physdev_op op;
+        op.cmd = cmd;
+        memcpy(&op.u, arg, sizeof(op.u));
+        rc = _hypercall1(int, physdev_op_compat, &op);
+    }
+    return rc;
+}
+
+//XXX __HYPERVISOR_grant_table_op is used for this hypercall constant.
+static inline int
+____HYPERVISOR_grant_table_op(
+    unsigned int cmd, void *uop, unsigned int count,
+    unsigned long pa1, unsigned long pa2)
+{
+    return _hypercall5(int, grant_table_op, cmd, uop, count, pa1, pa2);
+}
+
+int HYPERVISOR_grant_table_op(unsigned int cmd, void *uop, unsigned int count);
+
+static inline int
+HYPERVISOR_vcpu_op(
+	int cmd, int vcpuid, void *extra_args)
+{
+    return _hypercall3(int, vcpu_op, cmd, vcpuid, extra_args);
+}
+
+extern int HYPERVISOR_suspend(unsigned long srec);
+
+static inline unsigned long
+HYPERVISOR_hvm_op(
+	int cmd, void *arg)
+{
+	return _hypercall2(unsigned long, hvm_op, cmd, arg);
+}
+
+static inline int
+HYPERVISOR_callback_op(
+	int cmd, void *arg)
+{
+	return _hypercall2(int, callback_op, cmd, arg);
+}
+
+extern fastcall unsigned int __do_IRQ(unsigned int irq, struct pt_regs *regs);
+static inline void exit_idle(void) {}
+#define do_IRQ(irq, regs) ({			\
+	irq_enter();				\
+	__do_IRQ((irq), (regs));		\
+	irq_exit();				\
+})
+
+#include <linux/err.h>
+#ifdef CONFIG_XEN
+#include <asm/xen/privop.h>
+#endif /* CONFIG_XEN */
+
+static inline unsigned long
+__HYPERVISOR_ioremap(unsigned long ioaddr, unsigned long size)
+{
+	return _hypercall3(unsigned long, ia64_dom0vp_op,
+	                   IA64_DOM0VP_ioremap, ioaddr, size);
+}
+
+static inline unsigned long
+HYPERVISOR_ioremap(unsigned long ioaddr, unsigned long size)
+{
+	unsigned long ret = ioaddr;
+	if (is_running_on_xen()) {
+		ret = __HYPERVISOR_ioremap(ioaddr, size);
+		if (unlikely(ret == -ENOSYS))
+			panic("hypercall %s failed with %ld. "
+			      "Please check Xen and Linux config mismatch\n",
+			      __func__, -ret);
+		else if (unlikely(IS_ERR_VALUE(ret)))
+			ret = ioaddr;
+	}
+	return ret;
+}
+
+static inline unsigned long
+__HYPERVISOR_phystomach(unsigned long gpfn)
+{
+	return _hypercall2(unsigned long, ia64_dom0vp_op,
+	                   IA64_DOM0VP_phystomach, gpfn);
+}
+
+static inline unsigned long
+HYPERVISOR_phystomach(unsigned long gpfn)
+{
+	unsigned long ret = gpfn;
+	if (is_running_on_xen()) {
+		ret = __HYPERVISOR_phystomach(gpfn);
+	}
+	return ret;
+}
+
+static inline unsigned long
+__HYPERVISOR_machtophys(unsigned long mfn)
+{
+	return _hypercall2(unsigned long, ia64_dom0vp_op,
+	                   IA64_DOM0VP_machtophys, mfn);
+}
+
+static inline unsigned long
+HYPERVISOR_machtophys(unsigned long mfn)
+{
+	unsigned long ret = mfn;
+	if (is_running_on_xen()) {
+		ret = __HYPERVISOR_machtophys(mfn);
+	}
+	return ret;
+}
+
+static inline unsigned long
+__HYPERVISOR_zap_physmap(unsigned long gpfn, unsigned int extent_order)
+{
+	return _hypercall3(unsigned long, ia64_dom0vp_op,
+	                   IA64_DOM0VP_zap_physmap, gpfn, extent_order);
+}
+
+static inline unsigned long
+HYPERVISOR_zap_physmap(unsigned long gpfn, unsigned int extent_order)
+{
+	unsigned long ret = 0;
+	if (is_running_on_xen()) {
+		ret = __HYPERVISOR_zap_physmap(gpfn, extent_order);
+	}
+	return ret;
+}
+
+static inline unsigned long
+__HYPERVISOR_add_physmap(unsigned long gpfn, unsigned long mfn,
+			 unsigned long flags, domid_t domid)
+{
+	return _hypercall5(unsigned long, ia64_dom0vp_op,
+	                   IA64_DOM0VP_add_physmap, gpfn, mfn, flags, domid);
+}
+
+static inline unsigned long
+HYPERVISOR_add_physmap(unsigned long gpfn, unsigned long mfn,
+		       unsigned long flags, domid_t domid)
+{
+	unsigned long ret = 0;
+	BUG_ON(!is_running_on_xen());//XXX
+	if (is_running_on_xen()) {
+		ret = __HYPERVISOR_add_physmap(gpfn, mfn, flags, domid);
+	}
+	return ret;
+}
+
+// for balloon driver
+#define HYPERVISOR_update_va_mapping(va, new_val, flags) (0)
+
+#endif /* __HYPERCALL_H__ */
diff --git a/include/asm-ia64/hypervisor.h b/include/asm-ia64/hypervisor.h
new file mode 100644
index 000000000..3c190aea3
--- /dev/null
+++ b/include/asm-ia64/hypervisor.h
@@ -0,0 +1,218 @@
+/******************************************************************************
+ * hypervisor.h
+ * 
+ * Linux-specific hypervisor handling.
+ * 
+ * Copyright (c) 2002-2004, K A Fraser
+ * 
+ * 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; or, when distributed
+ * separately from the Linux kernel or incorporated into other
+ * software packages, subject to the following license:
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this source file (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy, modify,
+ * merge, publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * 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 __HYPERVISOR_H__
+#define __HYPERVISOR_H__
+
+#ifdef CONFIG_XEN
+extern int running_on_xen;
+#define is_running_on_xen()			(running_on_xen)
+#else /* CONFIG_XEN */
+# ifdef CONFIG_VMX_GUEST
+#  define is_running_on_xen()			(1)
+# else /* CONFIG_VMX_GUEST */
+#  define is_running_on_xen()			(0)
+#  define HYPERVISOR_ioremap(offset, size)	(offset)
+# endif /* CONFIG_VMX_GUEST */
+#endif /* CONFIG_XEN */
+
+#if defined(CONFIG_XEN) || defined(CONFIG_VMX_GUEST)
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/version.h>
+#include <linux/errno.h>
+#include <xen/interface/xen.h>
+#include <xen/interface/dom0_ops.h>
+#include <xen/interface/event_channel.h>
+#include <xen/interface/physdev.h>
+#include <xen/interface/sched.h>
+#include <asm/hypercall.h>
+#include <asm/ptrace.h>
+#include <asm/page.h>
+
+extern shared_info_t *HYPERVISOR_shared_info;
+extern start_info_t *xen_start_info;
+
+void force_evtchn_callback(void);
+
+#ifndef CONFIG_VMX_GUEST
+/* Turn jiffies into Xen system time. XXX Implement me. */
+#define jiffies_to_st(j)	0
+
+static inline int
+HYPERVISOR_yield(
+	void)
+{
+	int rc = HYPERVISOR_sched_op(SCHEDOP_yield, NULL);
+
+	if (rc == -ENOSYS)
+		rc = HYPERVISOR_sched_op_compat(SCHEDOP_yield, 0);
+
+	return rc;
+}
+
+static inline int
+HYPERVISOR_block(
+	void)
+{
+	int rc = HYPERVISOR_sched_op(SCHEDOP_block, NULL);
+
+	if (rc == -ENOSYS)
+		rc = HYPERVISOR_sched_op_compat(SCHEDOP_block, 0);
+
+	return rc;
+}
+
+static inline int
+HYPERVISOR_shutdown(
+	unsigned int reason)
+{
+	struct sched_shutdown sched_shutdown = {
+		.reason = reason
+	};
+
+	int rc = HYPERVISOR_sched_op(SCHEDOP_shutdown, &sched_shutdown);
+
+	if (rc == -ENOSYS)
+		rc = HYPERVISOR_sched_op_compat(SCHEDOP_shutdown, reason);
+
+	return rc;
+}
+
+static inline int
+HYPERVISOR_poll(
+	evtchn_port_t *ports, unsigned int nr_ports, u64 timeout)
+{
+	struct sched_poll sched_poll = {
+		.nr_ports = nr_ports,
+		.timeout = jiffies_to_st(timeout)
+	};
+
+	int rc;
+
+	set_xen_guest_handle(sched_poll.ports, ports);
+	rc = HYPERVISOR_sched_op(SCHEDOP_poll, &sched_poll);
+	if (rc == -ENOSYS)
+		rc = HYPERVISOR_sched_op_compat(SCHEDOP_yield, 0);
+
+	return rc;
+}
+
+#include <asm/hypercall.h>
+
+// for drivers/xen/privcmd/privcmd.c
+#define machine_to_phys_mapping 0
+struct vm_area_struct;
+int direct_remap_pfn_range(struct vm_area_struct *vma,
+			   unsigned long address,
+			   unsigned long mfn,
+			   unsigned long size,
+			   pgprot_t prot,
+			   domid_t  domid);
+struct file;
+int privcmd_mmap(struct file * file, struct vm_area_struct * vma);
+#define HAVE_ARCH_PRIVCMD_MMAP
+
+// for drivers/xen/balloon/balloon.c
+#ifdef CONFIG_XEN_SCRUB_PAGES
+#define scrub_pages(_p,_n) memset((void *)(_p), 0, (_n) << PAGE_SHIFT)
+#else
+#define scrub_pages(_p,_n) ((void)0)
+#endif
+#define	pte_mfn(_x)	pte_pfn(_x)
+#define phys_to_machine_mapping_valid(_x)	(1)
+
+#endif /* !CONFIG_VMX_GUEST */
+
+#define __pte_ma(_x)	((pte_t) {(_x)})        /* unmodified use */
+#define pfn_pte_ma(_x,_y)	__pte_ma(0)     /* unmodified use */
+
+#ifndef CONFIG_VMX_GUEST
+int __xen_create_contiguous_region(unsigned long vstart, unsigned int order, unsigned int address_bits);
+static inline int
+xen_create_contiguous_region(unsigned long vstart,
+                             unsigned int order, unsigned int address_bits)
+{
+	int ret = 0;
+	if (is_running_on_xen()) {
+		ret = __xen_create_contiguous_region(vstart, order,
+		                                     address_bits);
+	}
+	return ret;
+}
+
+void __xen_destroy_contiguous_region(unsigned long vstart, unsigned int order);
+static inline void
+xen_destroy_contiguous_region(unsigned long vstart, unsigned int order)
+{
+	if (is_running_on_xen())
+		__xen_destroy_contiguous_region(vstart, order);
+}
+
+#endif /* !CONFIG_VMX_GUEST */
+
+// for netfront.c, netback.c
+#define MULTI_UVMFLAGS_INDEX 0 //XXX any value
+
+static inline void
+MULTI_update_va_mapping(
+	multicall_entry_t *mcl, unsigned long va,
+	pte_t new_val, unsigned long flags)
+{
+	mcl->op = __HYPERVISOR_update_va_mapping;
+	mcl->result = 0;
+}
+
+static inline void
+MULTI_grant_table_op(multicall_entry_t *mcl, unsigned int cmd,
+	void *uop, unsigned int count)
+{
+	mcl->op = __HYPERVISOR_grant_table_op;
+	mcl->args[0] = cmd;
+	mcl->args[1] = (unsigned long)uop;
+	mcl->args[2] = count;
+}
+
+// for debug
+asmlinkage int xprintk(const char *fmt, ...);
+#define xprintd(fmt, ...)	xprintk("%s:%d " fmt, __func__, __LINE__, \
+					##__VA_ARGS__)
+
+#endif /* CONFIG_XEN || CONFIG_VMX_GUEST */
+
+#ifdef CONFIG_XEN_PRIVILEGED_GUEST
+#define is_initial_xendomain() (xen_start_info->flags & SIF_INITDOMAIN)
+#else
+#define is_initial_xendomain() 0
+#endif
+
+#endif /* __HYPERVISOR_H__ */
diff --git a/include/asm-ia64/maddr.h b/include/asm-ia64/maddr.h
new file mode 100644
index 000000000..55c6f94d1
--- /dev/null
+++ b/include/asm-ia64/maddr.h
@@ -0,0 +1,92 @@
+#ifndef _ASM_IA64_MADDR_H
+#define _ASM_IA64_MADDR_H
+
+#include <linux/kernel.h>
+#include <asm/hypervisor.h>
+#include <xen/features.h>
+#include <xen/interface/xen.h>
+
+#ifdef CONFIG_XEN
+
+#define INVALID_P2M_ENTRY       (~0UL)
+
+/* XXX xen page size != page size */
+static inline unsigned long
+pfn_to_mfn_for_dma(unsigned long pfn)
+{
+	unsigned long mfn;
+	mfn = HYPERVISOR_phystomach(pfn);
+	BUG_ON(mfn == 0); // XXX
+	BUG_ON(mfn == INVALID_P2M_ENTRY); // XXX
+	BUG_ON(mfn == INVALID_MFN);
+	return mfn;
+}
+
+static inline unsigned long
+phys_to_machine_for_dma(unsigned long phys)
+{
+	unsigned long machine =
+	              pfn_to_mfn_for_dma(phys >> PAGE_SHIFT) << PAGE_SHIFT;
+	machine |= (phys & ~PAGE_MASK);
+	return machine;
+}
+
+static inline unsigned long
+mfn_to_pfn_for_dma(unsigned long mfn)
+{
+	unsigned long pfn;
+	pfn = HYPERVISOR_machtophys(mfn);
+	BUG_ON(pfn == 0);
+	//BUG_ON(pfn == INVALID_M2P_ENTRY);
+	return pfn;
+}
+
+static inline unsigned long
+machine_to_phys_for_dma(unsigned long machine)
+{
+	unsigned long phys =
+	              mfn_to_pfn_for_dma(machine >> PAGE_SHIFT) << PAGE_SHIFT;
+	phys |= (machine & ~PAGE_MASK);
+	return phys;
+}
+
+static inline unsigned long
+mfn_to_local_pfn(unsigned long mfn)
+{
+	extern unsigned long max_mapnr;
+	unsigned long pfn = mfn_to_pfn_for_dma(mfn);
+	if (!pfn_valid(pfn))
+		return INVALID_P2M_ENTRY;
+	return pfn;
+}
+
+#else /* !CONFIG_XEN */
+
+#define pfn_to_mfn_for_dma(pfn) (pfn)
+#define mfn_to_pfn_for_dma(mfn) (mfn)
+#define phys_to_machine_for_dma(phys) (phys)
+#define machine_to_phys_for_dma(machine) (machine)
+#define mfn_to_local_pfn(mfn) (mfn)
+
+#endif /* !CONFIG_XEN */
+
+/* XXX to compile set_phys_to_machine(vaddr, FOREIGN_FRAME(m)) */
+#define FOREIGN_FRAME(m)        (INVALID_P2M_ENTRY)
+
+#define mfn_to_pfn(mfn) (mfn)
+#define pfn_to_mfn(pfn) (pfn)
+
+#define mfn_to_virt(mfn) (__va((mfn) << PAGE_SHIFT))
+#define virt_to_mfn(virt) (__pa(virt) >> PAGE_SHIFT)
+#define virt_to_machine(virt) __pa(virt) // for tpmfront.c
+
+#define set_phys_to_machine(pfn, mfn) do { } while (0)
+#ifdef CONFIG_VMX_GUEST
+extern void xen_machphys_update(unsigned long mfn, unsigned long pfn);
+#else /* CONFIG_VMX_GUEST */
+#define xen_machphys_update(mfn, pfn) do { } while (0)
+#endif /* CONFIG_VMX_GUEST */
+
+typedef unsigned long maddr_t;	// to compile netback, netfront
+
+#endif /* _ASM_IA64_MADDR_H */
diff --git a/include/asm-ia64/privop.h b/include/asm-ia64/privop.h
new file mode 100644
index 000000000..28c1e886c
--- /dev/null
+++ b/include/asm-ia64/privop.h
@@ -0,0 +1,59 @@
+#ifndef _ASM_IA64_PRIVOP_H
+#define _ASM_IA64_PRIVOP_H
+
+/*
+ * Copyright (C) 2005 Hewlett-Packard Co
+ *	Dan Magenheimer <dan.magenheimer@hp.com>
+ *
+ */
+
+#ifdef CONFIG_XEN
+#include <asm/xen/privop.h>
+#endif
+
+#ifndef __ASSEMBLY
+
+#ifndef IA64_PARAVIRTUALIZED
+
+#define ia64_getreg			__ia64_getreg
+#define ia64_setreg			__ia64_setreg
+#define ia64_hint			__ia64_hint
+#define ia64_thash			__ia64_thash
+#define ia64_itci			__ia64_itci
+#define ia64_itcd			__ia64_itcd
+#define ia64_itri			__ia64_itri
+#define ia64_itrd			__ia64_itrd
+#define ia64_tpa			__ia64_tpa
+#define ia64_set_ibr			__ia64_set_ibr
+#define ia64_set_pkr			__ia64_set_pkr
+#define ia64_set_pmc			__ia64_set_pmc
+#define ia64_set_pmd			__ia64_set_pmd
+#define ia64_set_rr			__ia64_set_rr
+#define ia64_get_cpuid			__ia64_get_cpuid
+#define ia64_get_ibr			__ia64_get_ibr
+#define ia64_get_pkr			__ia64_get_pkr
+#define ia64_get_pmc			__ia64_get_pmc
+#define ia64_get_pmd			__ia64_get_pmd
+#define ia64_get_rr			__ia64_get_rr
+#define ia64_fc				__ia64_fc
+#define ia64_ssm			__ia64_ssm
+#define ia64_rsm			__ia64_rsm
+#define ia64_ptce			__ia64_ptce
+#define ia64_ptcga			__ia64_ptcga
+#define ia64_ptcl			__ia64_ptcl
+#define ia64_ptri			__ia64_ptri
+#define ia64_ptrd			__ia64_ptrd
+#define ia64_get_psr_i			__ia64_get_psr_i
+#define ia64_intrin_local_irq_restore	__ia64_intrin_local_irq_restore
+#define ia64_pal_halt_light		__ia64_pal_halt_light
+#define ia64_leave_kernel		__ia64_leave_kernel
+#define ia64_leave_syscall		__ia64_leave_syscall
+#define ia64_trace_syscall		__ia64_trace_syscall
+#define ia64_switch_to			__ia64_switch_to
+#define ia64_pal_call_static		__ia64_pal_call_static
+
+#endif /* !IA64_PARAVIRTUALIZED */
+
+#endif /* !__ASSEMBLY */
+
+#endif /* _ASM_IA64_PRIVOP_H */
diff --git a/include/asm-ia64/synch_bitops.h b/include/asm-ia64/synch_bitops.h
new file mode 100644
index 000000000..21b7f8cd1
--- /dev/null
+++ b/include/asm-ia64/synch_bitops.h
@@ -0,0 +1,61 @@
+#ifndef __XEN_SYNCH_BITOPS_H__
+#define __XEN_SYNCH_BITOPS_H__
+
+/*
+ * Copyright 1992, Linus Torvalds.
+ * Heavily modified to provide guaranteed strong synchronisation
+ * when communicating with Xen or other guest OSes running on other CPUs.
+ */
+
+#define ADDR (*(volatile long *) addr)
+
+static __inline__ void synch_set_bit(int nr, volatile void * addr)
+{
+	set_bit(nr, addr);
+}
+
+static __inline__ void synch_clear_bit(int nr, volatile void * addr)
+{
+	clear_bit(nr, addr);
+}
+
+static __inline__ void synch_change_bit(int nr, volatile void * addr)
+{
+	change_bit(nr, addr);
+}
+
+static __inline__ int synch_test_and_set_bit(int nr, volatile void * addr)
+{
+    return test_and_set_bit(nr, addr);
+}
+
+static __inline__ int synch_test_and_clear_bit(int nr, volatile void * addr)
+{
+    return test_and_clear_bit(nr, addr);
+}
+
+static __inline__ int synch_test_and_change_bit(int nr, volatile void * addr)
+{
+    return test_and_change_bit(nr, addr);
+}
+
+static __inline__ int synch_const_test_bit(int nr, const volatile void * addr)
+{
+    return test_bit(nr, addr);
+}
+
+static __inline__ int synch_var_test_bit(int nr, volatile void * addr)
+{
+    return test_bit(nr, addr);
+}
+
+#define synch_cmpxchg	ia64_cmpxchg4_acq
+
+#define synch_test_bit(nr,addr) \
+(__builtin_constant_p(nr) ? \
+ synch_const_test_bit((nr),(addr)) : \
+ synch_var_test_bit((nr),(addr)))
+
+#define synch_cmpxchg_subword synch_cmpxchg
+
+#endif /* __XEN_SYNCH_BITOPS_H__ */
diff --git a/include/asm-ia64/tracehook.h b/include/asm-ia64/tracehook.h
new file mode 100644
index 000000000..ffea9431f
--- /dev/null
+++ b/include/asm-ia64/tracehook.h
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C)2006 Intel Co
+ *	Anil S Keshavamurthy <anil.s.keshavamurthy@intel.com>
+ *	and Bibo Mao <bibo.mao@intel.com> adapted from i386.
+ *
+ * 	Tracing hooks, ia64 CPU support
+ */
+
+#ifndef _ASM_TRACEHOOK_H
+#define _ASM_TRACEHOOK_H	1
+
+#include <linux/sched.h>
+#include <asm/ptrace.h>
+
+/*
+ * See linux/tracehook.h for the descriptions of what these need to do.
+ */
+
+#define ARCH_HAS_SINGLE_STEP	(1)
+#define ARCH_HAS_BLOCK_STEP	(1)
+
+static inline void tracehook_enable_single_step(struct task_struct *tsk)
+{
+	struct pt_regs *pt = task_pt_regs(tsk);
+	ia64_psr(pt)->ss = 1;
+}
+
+static inline void tracehook_disable_single_step(struct task_struct *tsk)
+{
+	struct pt_regs *pt = task_pt_regs(tsk);
+	ia64_psr(pt)->ss = 0;
+}
+
+static inline void tracehook_enable_block_step(struct task_struct *tsk)
+{
+	struct pt_regs *pt = task_pt_regs(tsk);
+	ia64_psr(pt)->tb = 1;
+}
+
+static inline void tracehook_disable_block_step(struct task_struct *tsk)
+{
+	struct pt_regs *pt = task_pt_regs(tsk);
+	ia64_psr(pt)->tb = 0;
+}
+
+static inline void tracehook_enable_syscall_trace(struct task_struct *tsk)
+{
+	set_tsk_thread_flag(tsk, TIF_SYSCALL_TRACE);
+}
+
+static inline void tracehook_disable_syscall_trace(struct task_struct *tsk)
+{
+	clear_tsk_thread_flag(tsk, TIF_SYSCALL_TRACE);
+}
+
+static inline int tracehook_single_step_enabled(struct task_struct *tsk)
+{
+	struct pt_regs *pt = task_pt_regs(tsk);
+	return ia64_psr(pt)->ss;
+}
+
+static inline void tracehook_abort_syscall(struct pt_regs *regs)
+{
+	regs->r15 = -1L;
+}
+
+extern const struct utrace_regset_view utrace_ia64_native;
+static inline const struct utrace_regset_view *
+utrace_native_view(struct task_struct *tsk)
+{
+#if 0 //CONFIG_IA32_SUPPORT
+	extern const struct utrace_regset_view utrace_ia32_view;
+
+	struct pt_regs *pt = task_pt_regs(tsk);
+	if (pt->cr_ipsr & IA64_PSR_IS)
+		return &utrace_ia32_view;
+#endif
+	return &utrace_ia64_native;
+}
+
+#endif
diff --git a/include/asm-ia64/xen/privop.h b/include/asm-ia64/xen/privop.h
new file mode 100644
index 000000000..073b3a2a7
--- /dev/null
+++ b/include/asm-ia64/xen/privop.h
@@ -0,0 +1,304 @@
+#ifndef _ASM_IA64_XEN_PRIVOP_H
+#define _ASM_IA64_XEN_PRIVOP_H
+
+/*
+ * Copyright (C) 2005 Hewlett-Packard Co
+ *	Dan Magenheimer <dan.magenheimer@hp.com>
+ *
+ * Paravirtualizations of privileged operations for Xen/ia64
+ *
+ */
+
+
+#include <xen/interface/arch-ia64.h>
+
+#define IA64_PARAVIRTUALIZED
+
+#if 0
+#undef XSI_BASE
+/* At 1 MB, before per-cpu space but still addressable using addl instead
+   of movl. */
+#define XSI_BASE				0xfffffffffff00000
+#endif
+
+/* Address of mapped regs.  */
+#define XMAPPEDREGS_BASE		(XSI_BASE + XSI_SIZE)
+
+#ifdef __ASSEMBLY__
+#define	XEN_HYPER_RFI			break HYPERPRIVOP_RFI
+#define	XEN_HYPER_RSM_PSR_DT		break HYPERPRIVOP_RSM_DT
+#define	XEN_HYPER_SSM_PSR_DT		break HYPERPRIVOP_SSM_DT
+#define	XEN_HYPER_COVER			break HYPERPRIVOP_COVER
+#define	XEN_HYPER_ITC_D			break HYPERPRIVOP_ITC_D
+#define	XEN_HYPER_ITC_I			break HYPERPRIVOP_ITC_I
+#define	XEN_HYPER_SSM_I			break HYPERPRIVOP_SSM_I
+#define	XEN_HYPER_GET_IVR		break HYPERPRIVOP_GET_IVR
+#define	XEN_HYPER_GET_TPR		break HYPERPRIVOP_GET_TPR
+#define	XEN_HYPER_SET_TPR		break HYPERPRIVOP_SET_TPR
+#define	XEN_HYPER_EOI			break HYPERPRIVOP_EOI
+#define	XEN_HYPER_SET_ITM		break HYPERPRIVOP_SET_ITM
+#define	XEN_HYPER_THASH			break HYPERPRIVOP_THASH
+#define	XEN_HYPER_PTC_GA		break HYPERPRIVOP_PTC_GA
+#define	XEN_HYPER_ITR_D			break HYPERPRIVOP_ITR_D
+#define	XEN_HYPER_GET_RR		break HYPERPRIVOP_GET_RR
+#define	XEN_HYPER_SET_RR		break HYPERPRIVOP_SET_RR
+#define	XEN_HYPER_SET_KR		break HYPERPRIVOP_SET_KR
+#define	XEN_HYPER_FC			break HYPERPRIVOP_FC
+#define	XEN_HYPER_GET_CPUID		break HYPERPRIVOP_GET_CPUID
+#define	XEN_HYPER_GET_PMD		break HYPERPRIVOP_GET_PMD
+#define	XEN_HYPER_GET_EFLAG		break HYPERPRIVOP_GET_EFLAG
+#define	XEN_HYPER_SET_EFLAG		break HYPERPRIVOP_SET_EFLAG
+#define	XEN_HYPER_RSM_BE		break HYPERPRIVOP_RSM_BE
+#define	XEN_HYPER_GET_PSR		break HYPERPRIVOP_GET_PSR
+
+#define XSI_IFS			(XSI_BASE + XSI_IFS_OFS)
+#define XSI_PRECOVER_IFS	(XSI_BASE + XSI_PRECOVER_IFS_OFS)
+#define XSI_INCOMPL_REGFR	(XSI_BASE + XSI_INCOMPL_REGFR_OFS)
+#define XSI_IFA			(XSI_BASE + XSI_IFA_OFS)
+#define XSI_ISR			(XSI_BASE + XSI_ISR_OFS)
+#define XSI_IIM			(XSI_BASE + XSI_IIM_OFS)
+#define XSI_ITIR		(XSI_BASE + XSI_ITIR_OFS)
+#define XSI_PSR_I_ADDR		(XSI_BASE + XSI_PSR_I_ADDR_OFS)
+#define XSI_PSR_IC		(XSI_BASE + XSI_PSR_IC_OFS)
+#define XSI_IPSR		(XSI_BASE + XSI_IPSR_OFS)
+#define XSI_IIP			(XSI_BASE + XSI_IIP_OFS)
+#define XSI_BANK1_R16		(XSI_BASE + XSI_BANK1_R16_OFS)
+#define XSI_BANKNUM		(XSI_BASE + XSI_BANKNUM_OFS)
+#define XSI_IHA			(XSI_BASE + XSI_IHA_OFS)
+#endif
+
+#ifndef __ASSEMBLY__
+#define	XEN_HYPER_SSM_I		asm("break %0" : : "i" (HYPERPRIVOP_SSM_I))
+#define	XEN_HYPER_GET_IVR	asm("break %0" : : "i" (HYPERPRIVOP_GET_IVR))
+
+/************************************************/
+/* Instructions paravirtualized for correctness */
+/************************************************/
+
+/* "fc" and "thash" are privilege-sensitive instructions, meaning they
+ *  may have different semantics depending on whether they are executed
+ *  at PL0 vs PL!=0.  When paravirtualized, these instructions mustn't
+ *  be allowed to execute directly, lest incorrect semantics result. */
+extern unsigned long xen_fc(unsigned long addr);
+#define ia64_fc(addr)			xen_fc((unsigned long)(addr))
+extern unsigned long xen_thash(unsigned long addr);
+#define ia64_thash(addr)		xen_thash((unsigned long)(addr))
+/* Note that "ttag" and "cover" are also privilege-sensitive; "ttag"
+ * is not currently used (though it may be in a long-format VHPT system!)
+ * and the semantics of cover only change if psr.ic is off which is very
+ * rare (and currently non-existent outside of assembly code */
+
+/* There are also privilege-sensitive registers.  These registers are
+ * readable at any privilege level but only writable at PL0. */
+extern unsigned long xen_get_cpuid(int index);
+#define	ia64_get_cpuid(i)		xen_get_cpuid(i)
+extern unsigned long xen_get_pmd(int index);
+#define	ia64_get_pmd(i)			xen_get_pmd(i)
+extern unsigned long xen_get_eflag(void);	/* see xen_ia64_getreg */
+extern void xen_set_eflag(unsigned long);	/* see xen_ia64_setreg */
+
+/************************************************/
+/* Instructions paravirtualized for performance */
+/************************************************/
+
+/* Xen uses memory-mapped virtual privileged registers for access to many
+ * performance-sensitive privileged registers.  Some, like the processor
+ * status register (psr), are broken up into multiple memory locations.
+ * Others, like "pend", are abstractions based on privileged registers.
+ * "Pend" is guaranteed to be set if reading cr.ivr would return a
+ * (non-spurious) interrupt. */
+#define XEN_MAPPEDREGS ((struct mapped_regs *)XMAPPEDREGS_BASE)
+#define XSI_PSR_I			\
+	(*XEN_MAPPEDREGS->interrupt_mask_addr)
+#define xen_get_virtual_psr_i()		\
+	(!XSI_PSR_I)
+#define xen_set_virtual_psr_i(_val)	\
+	({ XSI_PSR_I = (uint8_t)(_val) ? 0 : 1; })
+#define xen_set_virtual_psr_ic(_val)	\
+	({ XEN_MAPPEDREGS->interrupt_collection_enabled = _val ? 1 : 0; })
+#define xen_get_virtual_pend()		(XEN_MAPPEDREGS->pending_interruption)
+
+/* Hyperprivops are "break" instructions with a well-defined API.
+ * In particular, the virtual psr.ic bit must be off; in this way
+ * it is guaranteed to never conflict with a linux break instruction.
+ * Normally, this is done in a xen stub but this one is frequent enough
+ * that we inline it */
+#define xen_hyper_ssm_i()						\
+({									\
+	xen_set_virtual_psr_i(0);					\
+	xen_set_virtual_psr_ic(0);					\
+	XEN_HYPER_SSM_I;						\
+})
+
+/* turning off interrupts can be paravirtualized simply by writing
+ * to a memory-mapped virtual psr.i bit (implemented as a 16-bit bool) */
+#define xen_rsm_i()	xen_set_virtual_psr_i(0)
+
+/* turning on interrupts is a bit more complicated.. write to the
+ * memory-mapped virtual psr.i bit first (to avoid race condition),
+ * then if any interrupts were pending, we have to execute a hyperprivop
+ * to ensure the pending interrupt gets delivered; else we're done! */
+#define xen_ssm_i()							\
+({									\
+	int old = xen_get_virtual_psr_i();				\
+	xen_set_virtual_psr_i(1);					\
+	if (!old && xen_get_virtual_pend()) xen_hyper_ssm_i();		\
+})
+
+#define xen_ia64_intrin_local_irq_restore(x)				\
+{									\
+     if (is_running_on_xen()) {						\
+	if ((x) & IA64_PSR_I) { xen_ssm_i(); }				\
+	else { xen_rsm_i(); }						\
+    }									\
+    else __ia64_intrin_local_irq_restore((x));				\
+}
+
+#define	xen_get_psr_i()							\
+(									\
+	(is_running_on_xen()) ?						\
+		(xen_get_virtual_psr_i() ? IA64_PSR_I : 0)		\
+		: __ia64_get_psr_i()					\
+)
+
+#define xen_ia64_ssm(mask)						\
+{									\
+	if ((mask)==IA64_PSR_I) {					\
+		if (is_running_on_xen()) { xen_ssm_i(); }			\
+		else { __ia64_ssm(mask); }				\
+	}								\
+	else { __ia64_ssm(mask); }					\
+}
+
+#define xen_ia64_rsm(mask)						\
+{									\
+	if ((mask)==IA64_PSR_I) {					\
+		if (is_running_on_xen()) { xen_rsm_i(); }			\
+		else { __ia64_rsm(mask); }				\
+	}								\
+	else { __ia64_rsm(mask); }					\
+}
+
+
+/* Although all privileged operations can be left to trap and will
+ * be properly handled by Xen, some are frequent enough that we use
+ * hyperprivops for performance. */
+
+extern unsigned long xen_get_ivr(void);
+extern unsigned long xen_get_tpr(void);
+extern void xen_set_itm(unsigned long);
+extern void xen_set_tpr(unsigned long);
+extern void xen_eoi(void);
+extern void xen_set_rr(unsigned long index, unsigned long val);
+extern unsigned long xen_get_rr(unsigned long index);
+extern void xen_set_kr(unsigned long index, unsigned long val);
+extern void xen_ptcga(unsigned long addr, unsigned long size);
+
+/* Note: It may look wrong to test for is_running_on_xen() in each case.
+ * However regnum is always a constant so, as written, the compiler
+ * eliminates the switch statement, whereas is_running_on_xen() must be
+ * tested dynamically. */
+#define xen_ia64_getreg(regnum)						\
+({									\
+	__u64 ia64_intri_res;						\
+									\
+	switch(regnum) {						\
+	case _IA64_REG_CR_IVR:						\
+		ia64_intri_res = (is_running_on_xen()) ?			\
+			xen_get_ivr() :					\
+			__ia64_getreg(regnum);				\
+		break;							\
+	case _IA64_REG_CR_TPR:						\
+		ia64_intri_res = (is_running_on_xen()) ?			\
+			xen_get_tpr() :					\
+			__ia64_getreg(regnum);				\
+		break;							\
+	case _IA64_REG_AR_EFLAG:					\
+		ia64_intri_res = (is_running_on_xen()) ?			\
+			xen_get_eflag() :				\
+			__ia64_getreg(regnum);				\
+		break;							\
+	default:							\
+		ia64_intri_res = __ia64_getreg(regnum);			\
+		break;							\
+	}								\
+	ia64_intri_res;							\
+})
+
+#define xen_ia64_setreg(regnum,val)					\
+({									\
+	switch(regnum) {						\
+	case _IA64_REG_AR_KR0 ... _IA64_REG_AR_KR7:			\
+		(is_running_on_xen()) ?					\
+			xen_set_kr((regnum-_IA64_REG_AR_KR0), val) :	\
+			__ia64_setreg(regnum,val);			\
+		break;							\
+	case _IA64_REG_CR_ITM:						\
+		(is_running_on_xen()) ?					\
+			xen_set_itm(val) :				\
+			__ia64_setreg(regnum,val);			\
+		break;							\
+	case _IA64_REG_CR_TPR:						\
+		(is_running_on_xen()) ?					\
+			xen_set_tpr(val) :				\
+			__ia64_setreg(regnum,val);			\
+		break;							\
+	case _IA64_REG_CR_EOI:						\
+		(is_running_on_xen()) ?					\
+			xen_eoi() :					\
+			__ia64_setreg(regnum,val);			\
+		break;							\
+	case _IA64_REG_AR_EFLAG:					\
+		(is_running_on_xen()) ?					\
+			xen_set_eflag(val) :				\
+			__ia64_setreg(regnum,val);			\
+		break;							\
+	default:							\
+		__ia64_setreg(regnum,val);				\
+		break;							\
+	}								\
+})
+
+#define ia64_ssm			xen_ia64_ssm
+#define ia64_rsm			xen_ia64_rsm
+#define ia64_intrin_local_irq_restore	xen_ia64_intrin_local_irq_restore
+#define	ia64_ptcga			xen_ptcga
+#define	ia64_set_rr(index,val)		xen_set_rr(index,val)
+#define	ia64_get_rr(index)		xen_get_rr(index)
+#define ia64_getreg			xen_ia64_getreg
+#define ia64_setreg			xen_ia64_setreg
+#define	ia64_get_psr_i			xen_get_psr_i
+
+/* the remainder of these are not performance-sensitive so its
+ * OK to not paravirtualize and just take a privop trap and emulate */
+#define ia64_hint			__ia64_hint
+#define ia64_set_pmd			__ia64_set_pmd
+#define ia64_itci			__ia64_itci
+#define ia64_itcd			__ia64_itcd
+#define ia64_itri			__ia64_itri
+#define ia64_itrd			__ia64_itrd
+#define ia64_tpa			__ia64_tpa
+#define ia64_set_ibr			__ia64_set_ibr
+#define ia64_set_pkr			__ia64_set_pkr
+#define ia64_set_pmc			__ia64_set_pmc
+#define ia64_get_ibr			__ia64_get_ibr
+#define ia64_get_pkr			__ia64_get_pkr
+#define ia64_get_pmc			__ia64_get_pmc
+#define ia64_ptce			__ia64_ptce
+#define ia64_ptcl			__ia64_ptcl
+#define ia64_ptri			__ia64_ptri
+#define ia64_ptrd			__ia64_ptrd
+
+#endif /* !__ASSEMBLY__ */
+
+/* these routines utilize privilege-sensitive or performance-sensitive
+ * privileged instructions so the code must be replaced with
+ * paravirtualized versions */
+#define ia64_pal_halt_light		xen_pal_halt_light
+#define	ia64_leave_kernel		xen_leave_kernel
+#define	ia64_leave_syscall		xen_leave_syscall
+#define	ia64_trace_syscall		xen_trace_syscall
+#define	ia64_switch_to			xen_switch_to
+#define	ia64_pal_call_static		xen_pal_call_static
+
+#endif /* _ASM_IA64_XEN_PRIVOP_H */
diff --git a/include/asm-m32r/Kbuild b/include/asm-m32r/Kbuild
new file mode 100644
index 000000000..c68e1680d
--- /dev/null
+++ b/include/asm-m32r/Kbuild
@@ -0,0 +1 @@
+include include/asm-generic/Kbuild.asm
diff --git a/include/asm-m68k/Kbuild b/include/asm-m68k/Kbuild
new file mode 100644
index 000000000..c68e1680d
--- /dev/null
+++ b/include/asm-m68k/Kbuild
@@ -0,0 +1 @@
+include include/asm-generic/Kbuild.asm
diff --git a/include/asm-m68knommu/Kbuild b/include/asm-m68knommu/Kbuild
new file mode 100644
index 000000000..c68e1680d
--- /dev/null
+++ b/include/asm-m68knommu/Kbuild
@@ -0,0 +1 @@
+include include/asm-generic/Kbuild.asm
diff --git a/include/asm-m68knommu/m532xsim.h b/include/asm-m68knommu/m532xsim.h
new file mode 100644
index 000000000..1835fd20a
--- /dev/null
+++ b/include/asm-m68knommu/m532xsim.h
@@ -0,0 +1,2238 @@
+/****************************************************************************/
+
+/*
+ *	m532xsim.h -- ColdFire 5329 registers
+ */
+
+/****************************************************************************/
+#ifndef	m532xsim_h
+#define	m532xsim_h
+/****************************************************************************/
+
+#define MCF_REG32(x) (*(volatile unsigned long  *)(x))
+#define MCF_REG16(x) (*(volatile unsigned short *)(x))
+#define MCF_REG08(x) (*(volatile unsigned char  *)(x))
+
+#define MCFINT_VECBASE      64
+#define MCFINT_UART0        26          /* Interrupt number for UART0 */
+#define MCFINT_UART1        27          /* Interrupt number for UART1 */
+
+#define MCF_WTM_WCR	MCF_REG16(0xFC098000)
+
+/*
+ *	Define the 532x SIM register set addresses.
+ */
+#define	MCFSIM_IPRL		0xFC048004
+#define	MCFSIM_IPRH		0xFC048000
+#define	MCFSIM_IPR		MCFSIM_IPRL
+#define	MCFSIM_IMRL		0xFC04800C
+#define	MCFSIM_IMRH		0xFC048008
+#define	MCFSIM_IMR		MCFSIM_IMRL
+#define	MCFSIM_ICR0		0xFC048040	
+#define	MCFSIM_ICR1		0xFC048041	
+#define	MCFSIM_ICR2		0xFC048042	
+#define	MCFSIM_ICR3		0xFC048043	
+#define	MCFSIM_ICR4		0xFC048044	
+#define	MCFSIM_ICR5		0xFC048045	
+#define	MCFSIM_ICR6		0xFC048046	
+#define	MCFSIM_ICR7		0xFC048047	
+#define	MCFSIM_ICR8		0xFC048048	
+#define	MCFSIM_ICR9		0xFC048049	
+#define	MCFSIM_ICR10		0xFC04804A
+#define	MCFSIM_ICR11		0xFC04804B
+
+/*
+ *	Some symbol defines for the above...
+ */
+#define	MCFSIM_SWDICR		MCFSIM_ICR0	/* Watchdog timer ICR */
+#define	MCFSIM_TIMER1ICR	MCFSIM_ICR1	/* Timer 1 ICR */
+#define	MCFSIM_TIMER2ICR	MCFSIM_ICR2	/* Timer 2 ICR */
+#define	MCFSIM_UART1ICR		MCFSIM_ICR4	/* UART 1 ICR */
+#define	MCFSIM_UART2ICR		MCFSIM_ICR5	/* UART 2 ICR */
+#define	MCFSIM_DMA0ICR		MCFSIM_ICR6	/* DMA 0 ICR */
+#define	MCFSIM_DMA1ICR		MCFSIM_ICR7	/* DMA 1 ICR */
+#define	MCFSIM_DMA2ICR		MCFSIM_ICR8	/* DMA 2 ICR */
+#define	MCFSIM_DMA3ICR		MCFSIM_ICR9	/* DMA 3 ICR */
+
+
+#define	MCFSIM_IMR_MASKALL	0xFFFFFFFF	/* All SIM intr sources */
+
+#define MCFSIM_IMR_SIMR0	0xFC04801C
+#define MCFSIM_IMR_SIMR1	0xFC04C01C
+#define MCFSIM_IMR_CIMR0	0xFC04801D
+#define MCFSIM_IMR_CIMR1	0xFC04C01D
+
+#define MCFSIM_ICR_TIMER1	(0xFC048040+32)
+#define MCFSIM_ICR_TIMER2	(0xFC048040+33)
+
+
+/*
+ *	Macro to set IMR register. It is 32 bits on the 5307.
+ */
+#define	mcf_getimr()		\
+	*((volatile unsigned long *) (MCF_MBAR + MCFSIM_IMR))
+
+#define	mcf_setimr(imr)		\
+	*((volatile unsigned long *) (MCF_MBAR + MCFSIM_IMR)) = (imr);
+
+#define	mcf_getipr()		\
+	*((volatile unsigned long *) (MCF_MBAR + MCFSIM_IPR))
+
+#define	mcf_getiprl()		\
+	*((volatile unsigned long *) (MCF_MBAR + MCFSIM_IPRL))
+
+#define	mcf_getiprh()		\
+	*((volatile unsigned long *) (MCF_MBAR + MCFSIM_IPRH))
+
+
+#define mcf_enable_irq0(irq)		\
+	*((volatile unsigned char*) (MCFSIM_IMR_CIMR0)) = (irq);
+
+#define mcf_enable_irq1(irq)		\
+	*((volatile unsigned char*) (MCFSIM_IMR_CIMR1)) = (irq);
+
+#define mcf_disable_irq0(irq)		\
+	*((volatile unsigned char*) (MCFSIM_IMR_SIMR0)) = (irq);
+
+#define mcf_disable_irq1(irq)		\
+	*((volatile unsigned char*) (MCFSIM_IMR_SIMR1)) = (irq);
+
+/*
+ *	Define the Cache register flags.
+ */
+#define	CACR_EC			(1<<31)
+#define	CACR_ESB		(1<<29)
+#define	CACR_DPI		(1<<28)
+#define	CACR_HLCK		(1<<27)
+#define	CACR_CINVA		(1<<24)
+#define	CACR_DNFB		(1<<10)
+#define	CACR_DCM_WTHRU		(0<<8)
+#define	CACR_DCM_WBACK		(1<<8)
+#define	CACR_DCM_OFF_PRE	(2<<8)
+#define	CACR_DCM_OFF_IMP	(3<<8)
+#define	CACR_DW			(1<<5)
+
+#define	ACR_BASE_POS		24
+#define	ACR_MASK_POS		16
+#define	ACR_ENABLE		(1<<15)
+#define	ACR_USER		(0<<13)
+#define	ACR_SUPER		(1<<13)
+#define	ACR_ANY			(2<<13)
+#define	ACR_CM_WTHRU		(0<<5)
+#define	ACR_CM_WBACK		(1<<5)
+#define	ACR_CM_OFF_PRE		(2<<5)
+#define	ACR_CM_OFF_IMP		(3<<5)
+#define	ACR_WPROTECT		(1<<2)
+
+/*********************************************************************
+ *
+ * Inter-IC (I2C) Module
+ *
+ *********************************************************************/
+
+/* Read/Write access macros for general use */
+#define MCF532x_I2C_I2ADR       (volatile u8 *) (0xFC058000) // Address 
+#define MCF532x_I2C_I2FDR       (volatile u8 *) (0xFC058004) // Freq Divider
+#define MCF532x_I2C_I2CR        (volatile u8 *) (0xFC058008) // Control
+#define MCF532x_I2C_I2SR        (volatile u8 *) (0xFC05800C) // Status
+#define MCF532x_I2C_I2DR        (volatile u8 *) (0xFC058010) // Data I/O
+
+/* Bit level definitions and macros */
+#define MCF532x_I2C_I2ADR_ADDR(x)                       (((x)&0x7F)<<0x01)
+
+#define MCF532x_I2C_I2FDR_IC(x)                         (((x)&0x3F))
+
+#define MCF532x_I2C_I2CR_IEN    (0x80)	// I2C enable
+#define MCF532x_I2C_I2CR_IIEN   (0x40)  // interrupt enable
+#define MCF532x_I2C_I2CR_MSTA   (0x20)  // master/slave mode
+#define MCF532x_I2C_I2CR_MTX    (0x10)  // transmit/receive mode
+#define MCF532x_I2C_I2CR_TXAK   (0x08)  // transmit acknowledge enable
+#define MCF532x_I2C_I2CR_RSTA   (0x04)  // repeat start
+
+#define MCF532x_I2C_I2SR_ICF    (0x80)  // data transfer bit
+#define MCF532x_I2C_I2SR_IAAS   (0x40)  // I2C addressed as a slave
+#define MCF532x_I2C_I2SR_IBB    (0x20)  // I2C bus busy
+#define MCF532x_I2C_I2SR_IAL    (0x10)  // aribitration lost
+#define MCF532x_I2C_I2SR_SRW    (0x04)  // slave read/write
+#define MCF532x_I2C_I2SR_IIF    (0x02)  // I2C interrupt
+#define MCF532x_I2C_I2SR_RXAK   (0x01)  // received acknowledge
+
+#define MCF532x_PAR_FECI2C	(volatile u8 *) (0xFC0A4053)
+
+
+/*
+ *	The M5329EVB board needs a help getting its devices initialized 
+ *	at kernel start time if dBUG doesn't set it up (for example 
+ *	it is not used), so we need to do it manually.
+ */
+#ifdef __ASSEMBLER__
+.macro m5329EVB_setup
+	movel	#0xFC098000, %a7
+	movel	#0x0, (%a7)
+#define CORE_SRAM	0x80000000	
+#define CORE_SRAM_SIZE	0x8000
+	movel	#CORE_SRAM, %d0
+	addl	#0x221, %d0
+	movec	%d0,%RAMBAR1
+	movel	#CORE_SRAM, %sp
+	addl	#CORE_SRAM_SIZE, %sp
+	jsr	sysinit
+.endm
+#define	PLATFORM_SETUP	m5329EVB_setup
+
+#endif /* __ASSEMBLER__ */
+
+/*********************************************************************
+ *
+ * Chip Configuration Module (CCM)
+ *
+ *********************************************************************/
+
+/* Register read/write macros */
+#define MCF_CCM_CCR               MCF_REG16(0xFC0A0004)
+#define MCF_CCM_RCON              MCF_REG16(0xFC0A0008)
+#define MCF_CCM_CIR               MCF_REG16(0xFC0A000A)
+#define MCF_CCM_MISCCR            MCF_REG16(0xFC0A0010)
+#define MCF_CCM_CDR               MCF_REG16(0xFC0A0012)
+#define MCF_CCM_UHCSR             MCF_REG16(0xFC0A0014)
+#define MCF_CCM_UOCSR             MCF_REG16(0xFC0A0016)
+
+/* Bit definitions and macros for MCF_CCM_CCR */
+#define MCF_CCM_CCR_RESERVED      (0x0001)
+#define MCF_CCM_CCR_PLL_MODE      (0x0003)
+#define MCF_CCM_CCR_OSC_MODE      (0x0005)
+#define MCF_CCM_CCR_BOOTPS(x)     (((x)&0x0003)<<3|0x0001)
+#define MCF_CCM_CCR_LOAD          (0x0021)
+#define MCF_CCM_CCR_LIMP          (0x0041)
+#define MCF_CCM_CCR_CSC(x)        (((x)&0x0003)<<8|0x0001)
+
+/* Bit definitions and macros for MCF_CCM_RCON */
+#define MCF_CCM_RCON_RESERVED     (0x0001)
+#define MCF_CCM_RCON_PLL_MODE     (0x0003)
+#define MCF_CCM_RCON_OSC_MODE     (0x0005)
+#define MCF_CCM_RCON_BOOTPS(x)    (((x)&0x0003)<<3|0x0001)
+#define MCF_CCM_RCON_LOAD         (0x0021)
+#define MCF_CCM_RCON_LIMP         (0x0041)
+#define MCF_CCM_RCON_CSC(x)       (((x)&0x0003)<<8|0x0001)
+
+/* Bit definitions and macros for MCF_CCM_CIR */
+#define MCF_CCM_CIR_PRN(x)        (((x)&0x003F)<<0)
+#define MCF_CCM_CIR_PIN(x)        (((x)&0x03FF)<<6)
+
+/* Bit definitions and macros for MCF_CCM_MISCCR */
+#define MCF_CCM_MISCCR_USBSRC     (0x0001)
+#define MCF_CCM_MISCCR_USBDIV     (0x0002)
+#define MCF_CCM_MISCCR_SSI_SRC    (0x0010)
+#define MCF_CCM_MISCCR_TIM_DMA   (0x0020)
+#define MCF_CCM_MISCCR_SSI_PUS    (0x0040)
+#define MCF_CCM_MISCCR_SSI_PUE    (0x0080)
+#define MCF_CCM_MISCCR_LCD_CHEN   (0x0100)
+#define MCF_CCM_MISCCR_LIMP       (0x1000)
+#define MCF_CCM_MISCCR_PLL_LOCK   (0x2000)
+
+/* Bit definitions and macros for MCF_CCM_CDR */
+#define MCF_CCM_CDR_SSIDIV(x)     (((x)&0x000F)<<0)
+#define MCF_CCM_CDR_LPDIV(x)      (((x)&0x000F)<<8)
+
+/* Bit definitions and macros for MCF_CCM_UHCSR */
+#define MCF_CCM_UHCSR_XPDE        (0x0001)
+#define MCF_CCM_UHCSR_UHMIE       (0x0002)
+#define MCF_CCM_UHCSR_WKUP        (0x0004)
+#define MCF_CCM_UHCSR_PORTIND(x)  (((x)&0x0003)<<14)
+
+/* Bit definitions and macros for MCF_CCM_UOCSR */
+#define MCF_CCM_UOCSR_XPDE        (0x0001)
+#define MCF_CCM_UOCSR_UOMIE       (0x0002)
+#define MCF_CCM_UOCSR_WKUP        (0x0004)
+#define MCF_CCM_UOCSR_PWRFLT      (0x0008)
+#define MCF_CCM_UOCSR_SEND        (0x0010)
+#define MCF_CCM_UOCSR_VVLD        (0x0020)
+#define MCF_CCM_UOCSR_BVLD        (0x0040)
+#define MCF_CCM_UOCSR_AVLD        (0x0080)
+#define MCF_CCM_UOCSR_DPPU        (0x0100)
+#define MCF_CCM_UOCSR_DCR_VBUS    (0x0200)
+#define MCF_CCM_UOCSR_CRG_VBUS    (0x0400)
+#define MCF_CCM_UOCSR_DRV_VBUS    (0x0800)
+#define MCF_CCM_UOCSR_DMPD        (0x1000)
+#define MCF_CCM_UOCSR_DPPD        (0x2000)
+#define MCF_CCM_UOCSR_PORTIND(x)  (((x)&0x0003)<<14)
+
+/*********************************************************************
+ *
+ * DMA Timers (DTIM)
+ *
+ *********************************************************************/
+
+/* Register read/write macros */
+#define MCF_DTIM0_DTMR           MCF_REG16(0xFC070000)
+#define MCF_DTIM0_DTXMR          MCF_REG08(0xFC070002)
+#define MCF_DTIM0_DTER           MCF_REG08(0xFC070003)
+#define MCF_DTIM0_DTRR           MCF_REG32(0xFC070004)
+#define MCF_DTIM0_DTCR           MCF_REG32(0xFC070008)
+#define MCF_DTIM0_DTCN           MCF_REG32(0xFC07000C)
+#define MCF_DTIM1_DTMR           MCF_REG16(0xFC074000)
+#define MCF_DTIM1_DTXMR          MCF_REG08(0xFC074002)
+#define MCF_DTIM1_DTER           MCF_REG08(0xFC074003)
+#define MCF_DTIM1_DTRR           MCF_REG32(0xFC074004)
+#define MCF_DTIM1_DTCR           MCF_REG32(0xFC074008)
+#define MCF_DTIM1_DTCN           MCF_REG32(0xFC07400C)
+#define MCF_DTIM2_DTMR           MCF_REG16(0xFC078000)
+#define MCF_DTIM2_DTXMR          MCF_REG08(0xFC078002)
+#define MCF_DTIM2_DTER           MCF_REG08(0xFC078003)
+#define MCF_DTIM2_DTRR           MCF_REG32(0xFC078004)
+#define MCF_DTIM2_DTCR           MCF_REG32(0xFC078008)
+#define MCF_DTIM2_DTCN           MCF_REG32(0xFC07800C)
+#define MCF_DTIM3_DTMR           MCF_REG16(0xFC07C000)
+#define MCF_DTIM3_DTXMR          MCF_REG08(0xFC07C002)
+#define MCF_DTIM3_DTER           MCF_REG08(0xFC07C003)
+#define MCF_DTIM3_DTRR           MCF_REG32(0xFC07C004)
+#define MCF_DTIM3_DTCR           MCF_REG32(0xFC07C008)
+#define MCF_DTIM3_DTCN           MCF_REG32(0xFC07C00C)
+#define MCF_DTIM_DTMR(x)         MCF_REG16(0xFC070000+((x)*0x4000))
+#define MCF_DTIM_DTXMR(x)        MCF_REG08(0xFC070002+((x)*0x4000))
+#define MCF_DTIM_DTER(x)         MCF_REG08(0xFC070003+((x)*0x4000))
+#define MCF_DTIM_DTRR(x)         MCF_REG32(0xFC070004+((x)*0x4000))
+#define MCF_DTIM_DTCR(x)         MCF_REG32(0xFC070008+((x)*0x4000))
+#define MCF_DTIM_DTCN(x)         MCF_REG32(0xFC07000C+((x)*0x4000))
+
+/* Bit definitions and macros for MCF_DTIM_DTMR */
+#define MCF_DTIM_DTMR_RST        (0x0001)
+#define MCF_DTIM_DTMR_CLK(x)     (((x)&0x0003)<<1)
+#define MCF_DTIM_DTMR_FRR        (0x0008)
+#define MCF_DTIM_DTMR_ORRI       (0x0010)
+#define MCF_DTIM_DTMR_OM         (0x0020)
+#define MCF_DTIM_DTMR_CE(x)      (((x)&0x0003)<<6)
+#define MCF_DTIM_DTMR_PS(x)      (((x)&0x00FF)<<8)
+#define MCF_DTIM_DTMR_CE_ANY     (0x00C0)
+#define MCF_DTIM_DTMR_CE_FALL    (0x0080)
+#define MCF_DTIM_DTMR_CE_RISE    (0x0040)
+#define MCF_DTIM_DTMR_CE_NONE    (0x0000)
+#define MCF_DTIM_DTMR_CLK_DTIN   (0x0006)
+#define MCF_DTIM_DTMR_CLK_DIV16  (0x0004)
+#define MCF_DTIM_DTMR_CLK_DIV1   (0x0002)
+#define MCF_DTIM_DTMR_CLK_STOP   (0x0000)
+
+/* Bit definitions and macros for MCF_DTIM_DTXMR */
+#define MCF_DTIM_DTXMR_MODE16    (0x01)
+#define MCF_DTIM_DTXMR_DMAEN     (0x80)
+
+/* Bit definitions and macros for MCF_DTIM_DTER */
+#define MCF_DTIM_DTER_CAP        (0x01)
+#define MCF_DTIM_DTER_REF        (0x02)
+
+/* Bit definitions and macros for MCF_DTIM_DTRR */
+#define MCF_DTIM_DTRR_REF(x)     (((x)&0xFFFFFFFF)<<0)
+
+/* Bit definitions and macros for MCF_DTIM_DTCR */
+#define MCF_DTIM_DTCR_CAP(x)     (((x)&0xFFFFFFFF)<<0)
+
+/* Bit definitions and macros for MCF_DTIM_DTCN */
+#define MCF_DTIM_DTCN_CNT(x)     (((x)&0xFFFFFFFF)<<0)
+
+/*********************************************************************
+ *
+ * FlexBus Chip Selects (FBCS)
+ *
+ *********************************************************************/
+
+/* Register read/write macros */
+#define MCF_FBCS0_CSAR		MCF_REG32(0xFC008000)
+#define MCF_FBCS0_CSMR		MCF_REG32(0xFC008004)
+#define MCF_FBCS0_CSCR		MCF_REG32(0xFC008008)
+#define MCF_FBCS1_CSAR		MCF_REG32(0xFC00800C)
+#define MCF_FBCS1_CSMR		MCF_REG32(0xFC008010)
+#define MCF_FBCS1_CSCR		MCF_REG32(0xFC008014)
+#define MCF_FBCS2_CSAR		MCF_REG32(0xFC008018)
+#define MCF_FBCS2_CSMR		MCF_REG32(0xFC00801C)
+#define MCF_FBCS2_CSCR		MCF_REG32(0xFC008020)
+#define MCF_FBCS3_CSAR		MCF_REG32(0xFC008024)
+#define MCF_FBCS3_CSMR		MCF_REG32(0xFC008028)
+#define MCF_FBCS3_CSCR		MCF_REG32(0xFC00802C)
+#define MCF_FBCS4_CSAR		MCF_REG32(0xFC008030)
+#define MCF_FBCS4_CSMR		MCF_REG32(0xFC008034)
+#define MCF_FBCS4_CSCR		MCF_REG32(0xFC008038)
+#define MCF_FBCS5_CSAR		MCF_REG32(0xFC00803C)
+#define MCF_FBCS5_CSMR		MCF_REG32(0xFC008040)
+#define MCF_FBCS5_CSCR		MCF_REG32(0xFC008044)
+#define MCF_FBCS_CSAR(x)	MCF_REG32(0xFC008000+((x)*0x00C))
+#define MCF_FBCS_CSMR(x)	MCF_REG32(0xFC008004+((x)*0x00C))
+#define MCF_FBCS_CSCR(x)	MCF_REG32(0xFC008008+((x)*0x00C))
+
+/* Bit definitions and macros for MCF_FBCS_CSAR */
+#define MCF_FBCS_CSAR_BA(x)	((x)&0xFFFF0000)
+
+/* Bit definitions and macros for MCF_FBCS_CSMR */
+#define MCF_FBCS_CSMR_V		(0x00000001)
+#define MCF_FBCS_CSMR_WP	(0x00000100)
+#define MCF_FBCS_CSMR_BAM(x)	(((x)&0x0000FFFF)<<16)
+#define MCF_FBCS_CSMR_BAM_4G	(0xFFFF0000)
+#define MCF_FBCS_CSMR_BAM_2G	(0x7FFF0000)
+#define MCF_FBCS_CSMR_BAM_1G	(0x3FFF0000)
+#define MCF_FBCS_CSMR_BAM_1024M	(0x3FFF0000)
+#define MCF_FBCS_CSMR_BAM_512M	(0x1FFF0000)
+#define MCF_FBCS_CSMR_BAM_256M	(0x0FFF0000)
+#define MCF_FBCS_CSMR_BAM_128M	(0x07FF0000)
+#define MCF_FBCS_CSMR_BAM_64M	(0x03FF0000)
+#define MCF_FBCS_CSMR_BAM_32M	(0x01FF0000)
+#define MCF_FBCS_CSMR_BAM_16M	(0x00FF0000)
+#define MCF_FBCS_CSMR_BAM_8M	(0x007F0000)
+#define MCF_FBCS_CSMR_BAM_4M	(0x003F0000)
+#define MCF_FBCS_CSMR_BAM_2M	(0x001F0000)
+#define MCF_FBCS_CSMR_BAM_1M	(0x000F0000)
+#define MCF_FBCS_CSMR_BAM_1024K	(0x000F0000)
+#define MCF_FBCS_CSMR_BAM_512K	(0x00070000)
+#define MCF_FBCS_CSMR_BAM_256K	(0x00030000)
+#define MCF_FBCS_CSMR_BAM_128K	(0x00010000)
+#define MCF_FBCS_CSMR_BAM_64K	(0x00000000)
+
+/* Bit definitions and macros for MCF_FBCS_CSCR */
+#define MCF_FBCS_CSCR_BSTW	(0x00000008)
+#define MCF_FBCS_CSCR_BSTR	(0x00000010)
+#define MCF_FBCS_CSCR_BEM	(0x00000020)
+#define MCF_FBCS_CSCR_PS(x)	(((x)&0x00000003)<<6)
+#define MCF_FBCS_CSCR_AA	(0x00000100)
+#define MCF_FBCS_CSCR_SBM	(0x00000200)
+#define MCF_FBCS_CSCR_WS(x)	(((x)&0x0000003F)<<10)
+#define MCF_FBCS_CSCR_WRAH(x)	(((x)&0x00000003)<<16)
+#define MCF_FBCS_CSCR_RDAH(x)	(((x)&0x00000003)<<18)
+#define MCF_FBCS_CSCR_ASET(x)	(((x)&0x00000003)<<20)
+#define MCF_FBCS_CSCR_SWSEN	(0x00800000)
+#define MCF_FBCS_CSCR_SWS(x)	(((x)&0x0000003F)<<26)
+#define MCF_FBCS_CSCR_PS_8	(0x0040)
+#define MCF_FBCS_CSCR_PS_16	(0x0080)
+#define MCF_FBCS_CSCR_PS_32	(0x0000)
+
+/*********************************************************************
+ *
+ * General Purpose I/O (GPIO)
+ *
+ *********************************************************************/
+
+/* Register read/write macros */
+#define MCF_GPIO_PODR_FECH		MCF_REG08(0xFC0A4000)
+#define MCF_GPIO_PODR_FECL		MCF_REG08(0xFC0A4001)
+#define MCF_GPIO_PODR_SSI		MCF_REG08(0xFC0A4002)
+#define MCF_GPIO_PODR_BUSCTL		MCF_REG08(0xFC0A4003)
+#define MCF_GPIO_PODR_BE		MCF_REG08(0xFC0A4004)
+#define MCF_GPIO_PODR_CS		MCF_REG08(0xFC0A4005)
+#define MCF_GPIO_PODR_PWM		MCF_REG08(0xFC0A4006)
+#define MCF_GPIO_PODR_FECI2C		MCF_REG08(0xFC0A4007)
+#define MCF_GPIO_PODR_UART		MCF_REG08(0xFC0A4009)
+#define MCF_GPIO_PODR_QSPI		MCF_REG08(0xFC0A400A)
+#define MCF_GPIO_PODR_TIMER		MCF_REG08(0xFC0A400B)
+#define MCF_GPIO_PODR_LCDDATAH		MCF_REG08(0xFC0A400D)
+#define MCF_GPIO_PODR_LCDDATAM		MCF_REG08(0xFC0A400E)
+#define MCF_GPIO_PODR_LCDDATAL		MCF_REG08(0xFC0A400F)
+#define MCF_GPIO_PODR_LCDCTLH		MCF_REG08(0xFC0A4010)
+#define MCF_GPIO_PODR_LCDCTLL		MCF_REG08(0xFC0A4011)
+#define MCF_GPIO_PDDR_FECH		MCF_REG08(0xFC0A4014)
+#define MCF_GPIO_PDDR_FECL		MCF_REG08(0xFC0A4015)
+#define MCF_GPIO_PDDR_SSI		MCF_REG08(0xFC0A4016)
+#define MCF_GPIO_PDDR_BUSCTL		MCF_REG08(0xFC0A4017)
+#define MCF_GPIO_PDDR_BE		MCF_REG08(0xFC0A4018)
+#define MCF_GPIO_PDDR_CS		MCF_REG08(0xFC0A4019)
+#define MCF_GPIO_PDDR_PWM		MCF_REG08(0xFC0A401A)
+#define MCF_GPIO_PDDR_FECI2C		MCF_REG08(0xFC0A401B)
+#define MCF_GPIO_PDDR_UART		MCF_REG08(0xFC0A401C)
+#define MCF_GPIO_PDDR_QSPI		MCF_REG08(0xFC0A401E)
+#define MCF_GPIO_PDDR_TIMER		MCF_REG08(0xFC0A401F)
+#define MCF_GPIO_PDDR_LCDDATAH		MCF_REG08(0xFC0A4021)
+#define MCF_GPIO_PDDR_LCDDATAM		MCF_REG08(0xFC0A4022)
+#define MCF_GPIO_PDDR_LCDDATAL		MCF_REG08(0xFC0A4023)
+#define MCF_GPIO_PDDR_LCDCTLH		MCF_REG08(0xFC0A4024)
+#define MCF_GPIO_PDDR_LCDCTLL		MCF_REG08(0xFC0A4025)
+#define MCF_GPIO_PPDSDR_FECH		MCF_REG08(0xFC0A4028)
+#define MCF_GPIO_PPDSDR_FECL		MCF_REG08(0xFC0A4029)
+#define MCF_GPIO_PPDSDR_SSI		MCF_REG08(0xFC0A402A)
+#define MCF_GPIO_PPDSDR_BUSCTL		MCF_REG08(0xFC0A402B)
+#define MCF_GPIO_PPDSDR_BE		MCF_REG08(0xFC0A402C)
+#define MCF_GPIO_PPDSDR_CS		MCF_REG08(0xFC0A402D)
+#define MCF_GPIO_PPDSDR_PWM		MCF_REG08(0xFC0A402E)
+#define MCF_GPIO_PPDSDR_FECI2C		MCF_REG08(0xFC0A402F)
+#define MCF_GPIO_PPDSDR_UART		MCF_REG08(0xFC0A4031)
+#define MCF_GPIO_PPDSDR_QSPI		MCF_REG08(0xFC0A4032)
+#define MCF_GPIO_PPDSDR_TIMER		MCF_REG08(0xFC0A4033)
+#define MCF_GPIO_PPDSDR_LCDDATAH	MCF_REG08(0xFC0A4035)
+#define MCF_GPIO_PPDSDR_LCDDATAM	MCF_REG08(0xFC0A4036)
+#define MCF_GPIO_PPDSDR_LCDDATAL	MCF_REG08(0xFC0A4037)
+#define MCF_GPIO_PPDSDR_LCDCTLH		MCF_REG08(0xFC0A4038)
+#define MCF_GPIO_PPDSDR_LCDCTLL		MCF_REG08(0xFC0A4039)
+#define MCF_GPIO_PCLRR_FECH		MCF_REG08(0xFC0A403C)
+#define MCF_GPIO_PCLRR_FECL		MCF_REG08(0xFC0A403D)
+#define MCF_GPIO_PCLRR_SSI		MCF_REG08(0xFC0A403E)
+#define MCF_GPIO_PCLRR_BUSCTL		MCF_REG08(0xFC0A403F)
+#define MCF_GPIO_PCLRR_BE		MCF_REG08(0xFC0A4040)
+#define MCF_GPIO_PCLRR_CS		MCF_REG08(0xFC0A4041)
+#define MCF_GPIO_PCLRR_PWM		MCF_REG08(0xFC0A4042)
+#define MCF_GPIO_PCLRR_FECI2C		MCF_REG08(0xFC0A4043)
+#define MCF_GPIO_PCLRR_UART		MCF_REG08(0xFC0A4045)
+#define MCF_GPIO_PCLRR_QSPI		MCF_REG08(0xFC0A4046)
+#define MCF_GPIO_PCLRR_TIMER		MCF_REG08(0xFC0A4047)
+#define MCF_GPIO_PCLRR_LCDDATAH		MCF_REG08(0xFC0A4049)
+#define MCF_GPIO_PCLRR_LCDDATAM		MCF_REG08(0xFC0A404A)
+#define MCF_GPIO_PCLRR_LCDDATAL		MCF_REG08(0xFC0A404B)
+#define MCF_GPIO_PCLRR_LCDCTLH		MCF_REG08(0xFC0A404C)
+#define MCF_GPIO_PCLRR_LCDCTLL		MCF_REG08(0xFC0A404D)
+#define MCF_GPIO_PAR_FEC		MCF_REG08(0xFC0A4050)
+#define MCF_GPIO_PAR_PWM		MCF_REG08(0xFC0A4051)
+#define MCF_GPIO_PAR_BUSCTL		MCF_REG08(0xFC0A4052)
+#define MCF_GPIO_PAR_FECI2C		MCF_REG08(0xFC0A4053)
+#define MCF_GPIO_PAR_BE			MCF_REG08(0xFC0A4054)
+#define MCF_GPIO_PAR_CS			MCF_REG08(0xFC0A4055)
+#define MCF_GPIO_PAR_SSI		MCF_REG16(0xFC0A4056)
+#define MCF_GPIO_PAR_UART		MCF_REG16(0xFC0A4058)
+#define MCF_GPIO_PAR_QSPI		MCF_REG16(0xFC0A405A)
+#define MCF_GPIO_PAR_TIMER		MCF_REG08(0xFC0A405C)
+#define MCF_GPIO_PAR_LCDDATA		MCF_REG08(0xFC0A405D)
+#define MCF_GPIO_PAR_LCDCTL		MCF_REG16(0xFC0A405E)
+#define MCF_GPIO_PAR_IRQ		MCF_REG16(0xFC0A4060)
+#define MCF_GPIO_MSCR_FLEXBUS		MCF_REG08(0xFC0A4064)
+#define MCF_GPIO_MSCR_SDRAM		MCF_REG08(0xFC0A4065)
+#define MCF_GPIO_DSCR_I2C		MCF_REG08(0xFC0A4068)
+#define MCF_GPIO_DSCR_PWM		MCF_REG08(0xFC0A4069)
+#define MCF_GPIO_DSCR_FEC		MCF_REG08(0xFC0A406A)
+#define MCF_GPIO_DSCR_UART		MCF_REG08(0xFC0A406B)
+#define MCF_GPIO_DSCR_QSPI		MCF_REG08(0xFC0A406C)
+#define MCF_GPIO_DSCR_TIMER		MCF_REG08(0xFC0A406D)
+#define MCF_GPIO_DSCR_SSI		MCF_REG08(0xFC0A406E)
+#define MCF_GPIO_DSCR_LCD		MCF_REG08(0xFC0A406F)
+#define MCF_GPIO_DSCR_DEBUG		MCF_REG08(0xFC0A4070)
+#define MCF_GPIO_DSCR_CLKRST		MCF_REG08(0xFC0A4071)
+#define MCF_GPIO_DSCR_IRQ		MCF_REG08(0xFC0A4072)
+
+/* Bit definitions and macros for MCF_GPIO_PODR_FECH */
+#define MCF_GPIO_PODR_FECH_PODR_FECH0              (0x01)
+#define MCF_GPIO_PODR_FECH_PODR_FECH1              (0x02)
+#define MCF_GPIO_PODR_FECH_PODR_FECH2              (0x04)
+#define MCF_GPIO_PODR_FECH_PODR_FECH3              (0x08)
+#define MCF_GPIO_PODR_FECH_PODR_FECH4              (0x10)
+#define MCF_GPIO_PODR_FECH_PODR_FECH5              (0x20)
+#define MCF_GPIO_PODR_FECH_PODR_FECH6              (0x40)
+#define MCF_GPIO_PODR_FECH_PODR_FECH7              (0x80)
+
+/* Bit definitions and macros for MCF_GPIO_PODR_FECL */
+#define MCF_GPIO_PODR_FECL_PODR_FECL0              (0x01)
+#define MCF_GPIO_PODR_FECL_PODR_FECL1              (0x02)
+#define MCF_GPIO_PODR_FECL_PODR_FECL2              (0x04)
+#define MCF_GPIO_PODR_FECL_PODR_FECL3              (0x08)
+#define MCF_GPIO_PODR_FECL_PODR_FECL4              (0x10)
+#define MCF_GPIO_PODR_FECL_PODR_FECL5              (0x20)
+#define MCF_GPIO_PODR_FECL_PODR_FECL6              (0x40)
+#define MCF_GPIO_PODR_FECL_PODR_FECL7              (0x80)
+
+/* Bit definitions and macros for MCF_GPIO_PODR_SSI */
+#define MCF_GPIO_PODR_SSI_PODR_SSI0                (0x01)
+#define MCF_GPIO_PODR_SSI_PODR_SSI1                (0x02)
+#define MCF_GPIO_PODR_SSI_PODR_SSI2                (0x04)
+#define MCF_GPIO_PODR_SSI_PODR_SSI3                (0x08)
+#define MCF_GPIO_PODR_SSI_PODR_SSI4                (0x10)
+
+/* Bit definitions and macros for MCF_GPIO_PODR_BUSCTL */
+#define MCF_GPIO_PODR_BUSCTL_POSDR_BUSCTL0         (0x01)
+#define MCF_GPIO_PODR_BUSCTL_PODR_BUSCTL1          (0x02)
+#define MCF_GPIO_PODR_BUSCTL_PODR_BUSCTL2          (0x04)
+#define MCF_GPIO_PODR_BUSCTL_PODR_BUSCTL3          (0x08)
+
+/* Bit definitions and macros for MCF_GPIO_PODR_BE */
+#define MCF_GPIO_PODR_BE_PODR_BE0                  (0x01)
+#define MCF_GPIO_PODR_BE_PODR_BE1                  (0x02)
+#define MCF_GPIO_PODR_BE_PODR_BE2                  (0x04)
+#define MCF_GPIO_PODR_BE_PODR_BE3                  (0x08)
+
+/* Bit definitions and macros for MCF_GPIO_PODR_CS */
+#define MCF_GPIO_PODR_CS_PODR_CS1                  (0x02)
+#define MCF_GPIO_PODR_CS_PODR_CS2                  (0x04)
+#define MCF_GPIO_PODR_CS_PODR_CS3                  (0x08)
+#define MCF_GPIO_PODR_CS_PODR_CS4                  (0x10)
+#define MCF_GPIO_PODR_CS_PODR_CS5                  (0x20)
+
+/* Bit definitions and macros for MCF_GPIO_PODR_PWM */
+#define MCF_GPIO_PODR_PWM_PODR_PWM2                (0x04)
+#define MCF_GPIO_PODR_PWM_PODR_PWM3                (0x08)
+#define MCF_GPIO_PODR_PWM_PODR_PWM4                (0x10)
+#define MCF_GPIO_PODR_PWM_PODR_PWM5                (0x20)
+
+/* Bit definitions and macros for MCF_GPIO_PODR_FECI2C */
+#define MCF_GPIO_PODR_FECI2C_PODR_FECI2C0          (0x01)
+#define MCF_GPIO_PODR_FECI2C_PODR_FECI2C1          (0x02)
+#define MCF_GPIO_PODR_FECI2C_PODR_FECI2C2          (0x04)
+#define MCF_GPIO_PODR_FECI2C_PODR_FECI2C3          (0x08)
+
+/* Bit definitions and macros for MCF_GPIO_PODR_UART */
+#define MCF_GPIO_PODR_UART_PODR_UART0              (0x01)
+#define MCF_GPIO_PODR_UART_PODR_UART1              (0x02)
+#define MCF_GPIO_PODR_UART_PODR_UART2              (0x04)
+#define MCF_GPIO_PODR_UART_PODR_UART3              (0x08)
+#define MCF_GPIO_PODR_UART_PODR_UART4              (0x10)
+#define MCF_GPIO_PODR_UART_PODR_UART5              (0x20)
+#define MCF_GPIO_PODR_UART_PODR_UART6              (0x40)
+#define MCF_GPIO_PODR_UART_PODR_UART7              (0x80)
+
+/* Bit definitions and macros for MCF_GPIO_PODR_QSPI */
+#define MCF_GPIO_PODR_QSPI_PODR_QSPI0              (0x01)
+#define MCF_GPIO_PODR_QSPI_PODR_QSPI1              (0x02)
+#define MCF_GPIO_PODR_QSPI_PODR_QSPI2              (0x04)
+#define MCF_GPIO_PODR_QSPI_PODR_QSPI3              (0x08)
+#define MCF_GPIO_PODR_QSPI_PODR_QSPI4              (0x10)
+#define MCF_GPIO_PODR_QSPI_PODR_QSPI5              (0x20)
+
+/* Bit definitions and macros for MCF_GPIO_PODR_TIMER */
+#define MCF_GPIO_PODR_TIMER_PODR_TIMER0            (0x01)
+#define MCF_GPIO_PODR_TIMER_PODR_TIMER1            (0x02)
+#define MCF_GPIO_PODR_TIMER_PODR_TIMER2            (0x04)
+#define MCF_GPIO_PODR_TIMER_PODR_TIMER3            (0x08)
+
+/* Bit definitions and macros for MCF_GPIO_PODR_LCDDATAH */
+#define MCF_GPIO_PODR_LCDDATAH_PODR_LCDDATAH0      (0x01)
+#define MCF_GPIO_PODR_LCDDATAH_PODR_LCDDATAH1      (0x02)
+
+/* Bit definitions and macros for MCF_GPIO_PODR_LCDDATAM */
+#define MCF_GPIO_PODR_LCDDATAM_PODR_LCDDATAM0      (0x01)
+#define MCF_GPIO_PODR_LCDDATAM_PODR_LCDDATAM1      (0x02)
+#define MCF_GPIO_PODR_LCDDATAM_PODR_LCDDATAM2      (0x04)
+#define MCF_GPIO_PODR_LCDDATAM_PODR_LCDDATAM3      (0x08)
+#define MCF_GPIO_PODR_LCDDATAM_PODR_LCDDATAM4      (0x10)
+#define MCF_GPIO_PODR_LCDDATAM_PODR_LCDDATAM5      (0x20)
+#define MCF_GPIO_PODR_LCDDATAM_PODR_LCDDATAM6      (0x40)
+#define MCF_GPIO_PODR_LCDDATAM_PODR_LCDDATAM7      (0x80)
+
+/* Bit definitions and macros for MCF_GPIO_PODR_LCDDATAL */
+#define MCF_GPIO_PODR_LCDDATAL_PODR_LCDDATAL0      (0x01)
+#define MCF_GPIO_PODR_LCDDATAL_PODR_LCDDATAL1      (0x02)
+#define MCF_GPIO_PODR_LCDDATAL_PODR_LCDDATAL2      (0x04)
+#define MCF_GPIO_PODR_LCDDATAL_PODR_LCDDATAL3      (0x08)
+#define MCF_GPIO_PODR_LCDDATAL_PODR_LCDDATAL4      (0x10)
+#define MCF_GPIO_PODR_LCDDATAL_PODR_LCDDATAL5      (0x20)
+#define MCF_GPIO_PODR_LCDDATAL_PODR_LCDDATAL6      (0x40)
+#define MCF_GPIO_PODR_LCDDATAL_PODR_LCDDATAL7      (0x80)
+
+/* Bit definitions and macros for MCF_GPIO_PODR_LCDCTLH */
+#define MCF_GPIO_PODR_LCDCTLH_PODR_LCDCTLH0        (0x01)
+
+/* Bit definitions and macros for MCF_GPIO_PODR_LCDCTLL */
+#define MCF_GPIO_PODR_LCDCTLL_PODR_LCDCTLL0        (0x01)
+#define MCF_GPIO_PODR_LCDCTLL_PODR_LCDCTLL1        (0x02)
+#define MCF_GPIO_PODR_LCDCTLL_PODR_LCDCTLL2        (0x04)
+#define MCF_GPIO_PODR_LCDCTLL_PODR_LCDCTLL3        (0x08)
+#define MCF_GPIO_PODR_LCDCTLL_PODR_LCDCTLL4        (0x10)
+#define MCF_GPIO_PODR_LCDCTLL_PODR_LCDCTLL5        (0x20)
+#define MCF_GPIO_PODR_LCDCTLL_PODR_LCDCTLL6        (0x40)
+#define MCF_GPIO_PODR_LCDCTLL_PODR_LCDCTLL7        (0x80)
+
+/* Bit definitions and macros for MCF_GPIO_PDDR_FECH */
+#define MCF_GPIO_PDDR_FECH_PDDR_FECH0              (0x01)
+#define MCF_GPIO_PDDR_FECH_PDDR_FECH1              (0x02)
+#define MCF_GPIO_PDDR_FECH_PDDR_FECH2              (0x04)
+#define MCF_GPIO_PDDR_FECH_PDDR_FECH3              (0x08)
+#define MCF_GPIO_PDDR_FECH_PDDR_FECH4              (0x10)
+#define MCF_GPIO_PDDR_FECH_PDDR_FECH5              (0x20)
+#define MCF_GPIO_PDDR_FECH_PDDR_FECH6              (0x40)
+#define MCF_GPIO_PDDR_FECH_PDDR_FECH7              (0x80)
+
+/* Bit definitions and macros for MCF_GPIO_PDDR_FECL */
+#define MCF_GPIO_PDDR_FECL_PDDR_FECL0              (0x01)
+#define MCF_GPIO_PDDR_FECL_PDDR_FECL1              (0x02)
+#define MCF_GPIO_PDDR_FECL_PDDR_FECL2              (0x04)
+#define MCF_GPIO_PDDR_FECL_PDDR_FECL3              (0x08)
+#define MCF_GPIO_PDDR_FECL_PDDR_FECL4              (0x10)
+#define MCF_GPIO_PDDR_FECL_PDDR_FECL5              (0x20)
+#define MCF_GPIO_PDDR_FECL_PDDR_FECL6              (0x40)
+#define MCF_GPIO_PDDR_FECL_PDDR_FECL7              (0x80)
+
+/* Bit definitions and macros for MCF_GPIO_PDDR_SSI */
+#define MCF_GPIO_PDDR_SSI_PDDR_SSI0                (0x01)
+#define MCF_GPIO_PDDR_SSI_PDDR_SSI1                (0x02)
+#define MCF_GPIO_PDDR_SSI_PDDR_SSI2                (0x04)
+#define MCF_GPIO_PDDR_SSI_PDDR_SSI3                (0x08)
+#define MCF_GPIO_PDDR_SSI_PDDR_SSI4                (0x10)
+
+/* Bit definitions and macros for MCF_GPIO_PDDR_BUSCTL */
+#define MCF_GPIO_PDDR_BUSCTL_POSDR_BUSCTL0         (0x01)
+#define MCF_GPIO_PDDR_BUSCTL_PDDR_BUSCTL1          (0x02)
+#define MCF_GPIO_PDDR_BUSCTL_PDDR_BUSCTL2          (0x04)
+#define MCF_GPIO_PDDR_BUSCTL_PDDR_BUSCTL3          (0x08)
+
+/* Bit definitions and macros for MCF_GPIO_PDDR_BE */
+#define MCF_GPIO_PDDR_BE_PDDR_BE0                  (0x01)
+#define MCF_GPIO_PDDR_BE_PDDR_BE1                  (0x02)
+#define MCF_GPIO_PDDR_BE_PDDR_BE2                  (0x04)
+#define MCF_GPIO_PDDR_BE_PDDR_BE3                  (0x08)
+
+/* Bit definitions and macros for MCF_GPIO_PDDR_CS */
+#define MCF_GPIO_PDDR_CS_PDDR_CS1                  (0x02)
+#define MCF_GPIO_PDDR_CS_PDDR_CS2                  (0x04)
+#define MCF_GPIO_PDDR_CS_PDDR_CS3                  (0x08)
+#define MCF_GPIO_PDDR_CS_PDDR_CS4                  (0x10)
+#define MCF_GPIO_PDDR_CS_PDDR_CS5                  (0x20)
+
+/* Bit definitions and macros for MCF_GPIO_PDDR_PWM */
+#define MCF_GPIO_PDDR_PWM_PDDR_PWM2                (0x04)
+#define MCF_GPIO_PDDR_PWM_PDDR_PWM3                (0x08)
+#define MCF_GPIO_PDDR_PWM_PDDR_PWM4                (0x10)
+#define MCF_GPIO_PDDR_PWM_PDDR_PWM5                (0x20)
+
+/* Bit definitions and macros for MCF_GPIO_PDDR_FECI2C */
+#define MCF_GPIO_PDDR_FECI2C_PDDR_FECI2C0          (0x01)
+#define MCF_GPIO_PDDR_FECI2C_PDDR_FECI2C1          (0x02)
+#define MCF_GPIO_PDDR_FECI2C_PDDR_FECI2C2          (0x04)
+#define MCF_GPIO_PDDR_FECI2C_PDDR_FECI2C3          (0x08)
+
+/* Bit definitions and macros for MCF_GPIO_PDDR_UART */
+#define MCF_GPIO_PDDR_UART_PDDR_UART0              (0x01)
+#define MCF_GPIO_PDDR_UART_PDDR_UART1              (0x02)
+#define MCF_GPIO_PDDR_UART_PDDR_UART2              (0x04)
+#define MCF_GPIO_PDDR_UART_PDDR_UART3              (0x08)
+#define MCF_GPIO_PDDR_UART_PDDR_UART4              (0x10)
+#define MCF_GPIO_PDDR_UART_PDDR_UART5              (0x20)
+#define MCF_GPIO_PDDR_UART_PDDR_UART6              (0x40)
+#define MCF_GPIO_PDDR_UART_PDDR_UART7              (0x80)
+
+/* Bit definitions and macros for MCF_GPIO_PDDR_QSPI */
+#define MCF_GPIO_PDDR_QSPI_PDDR_QSPI0              (0x01)
+#define MCF_GPIO_PDDR_QSPI_PDDR_QSPI1              (0x02)
+#define MCF_GPIO_PDDR_QSPI_PDDR_QSPI2              (0x04)
+#define MCF_GPIO_PDDR_QSPI_PDDR_QSPI3              (0x08)
+#define MCF_GPIO_PDDR_QSPI_PDDR_QSPI4              (0x10)
+#define MCF_GPIO_PDDR_QSPI_PDDR_QSPI5              (0x20)
+
+/* Bit definitions and macros for MCF_GPIO_PDDR_TIMER */
+#define MCF_GPIO_PDDR_TIMER_PDDR_TIMER0            (0x01)
+#define MCF_GPIO_PDDR_TIMER_PDDR_TIMER1            (0x02)
+#define MCF_GPIO_PDDR_TIMER_PDDR_TIMER2            (0x04)
+#define MCF_GPIO_PDDR_TIMER_PDDR_TIMER3            (0x08)
+
+/* Bit definitions and macros for MCF_GPIO_PDDR_LCDDATAH */
+#define MCF_GPIO_PDDR_LCDDATAH_PDDR_LCDDATAH0      (0x01)
+#define MCF_GPIO_PDDR_LCDDATAH_PDDR_LCDDATAH1      (0x02)
+
+/* Bit definitions and macros for MCF_GPIO_PDDR_LCDDATAM */
+#define MCF_GPIO_PDDR_LCDDATAM_PDDR_LCDDATAM0      (0x01)
+#define MCF_GPIO_PDDR_LCDDATAM_PDDR_LCDDATAM1      (0x02)
+#define MCF_GPIO_PDDR_LCDDATAM_PDDR_LCDDATAM2      (0x04)
+#define MCF_GPIO_PDDR_LCDDATAM_PDDR_LCDDATAM3      (0x08)
+#define MCF_GPIO_PDDR_LCDDATAM_PDDR_LCDDATAM4      (0x10)
+#define MCF_GPIO_PDDR_LCDDATAM_PDDR_LCDDATAM5      (0x20)
+#define MCF_GPIO_PDDR_LCDDATAM_PDDR_LCDDATAM6      (0x40)
+#define MCF_GPIO_PDDR_LCDDATAM_PDDR_LCDDATAM7      (0x80)
+
+/* Bit definitions and macros for MCF_GPIO_PDDR_LCDDATAL */
+#define MCF_GPIO_PDDR_LCDDATAL_PDDR_LCDDATAL0      (0x01)
+#define MCF_GPIO_PDDR_LCDDATAL_PDDR_LCDDATAL1      (0x02)
+#define MCF_GPIO_PDDR_LCDDATAL_PDDR_LCDDATAL2      (0x04)
+#define MCF_GPIO_PDDR_LCDDATAL_PDDR_LCDDATAL3      (0x08)
+#define MCF_GPIO_PDDR_LCDDATAL_PDDR_LCDDATAL4      (0x10)
+#define MCF_GPIO_PDDR_LCDDATAL_PDDR_LCDDATAL5      (0x20)
+#define MCF_GPIO_PDDR_LCDDATAL_PDDR_LCDDATAL6      (0x40)
+#define MCF_GPIO_PDDR_LCDDATAL_PDDR_LCDDATAL7      (0x80)
+
+/* Bit definitions and macros for MCF_GPIO_PDDR_LCDCTLH */
+#define MCF_GPIO_PDDR_LCDCTLH_PDDR_LCDCTLH0        (0x01)
+
+/* Bit definitions and macros for MCF_GPIO_PDDR_LCDCTLL */
+#define MCF_GPIO_PDDR_LCDCTLL_PDDR_LCDCTLL0        (0x01)
+#define MCF_GPIO_PDDR_LCDCTLL_PDDR_LCDCTLL1        (0x02)
+#define MCF_GPIO_PDDR_LCDCTLL_PDDR_LCDCTLL2        (0x04)
+#define MCF_GPIO_PDDR_LCDCTLL_PDDR_LCDCTLL3        (0x08)
+#define MCF_GPIO_PDDR_LCDCTLL_PDDR_LCDCTLL4        (0x10)
+#define MCF_GPIO_PDDR_LCDCTLL_PDDR_LCDCTLL5        (0x20)
+#define MCF_GPIO_PDDR_LCDCTLL_PDDR_LCDCTLL6        (0x40)
+#define MCF_GPIO_PDDR_LCDCTLL_PDDR_LCDCTLL7        (0x80)
+
+/* Bit definitions and macros for MCF_GPIO_PPDSDR_FECH */
+#define MCF_GPIO_PPDSDR_FECH_PPDSDR_FECH0          (0x01)
+#define MCF_GPIO_PPDSDR_FECH_PPDSDR_FECH1          (0x02)
+#define MCF_GPIO_PPDSDR_FECH_PPDSDR_FECH2          (0x04)
+#define MCF_GPIO_PPDSDR_FECH_PPDSDR_FECH3          (0x08)
+#define MCF_GPIO_PPDSDR_FECH_PPDSDR_FECH4          (0x10)
+#define MCF_GPIO_PPDSDR_FECH_PPDSDR_FECH5          (0x20)
+#define MCF_GPIO_PPDSDR_FECH_PPDSDR_FECH6          (0x40)
+#define MCF_GPIO_PPDSDR_FECH_PPDSDR_FECH7          (0x80)
+
+/* Bit definitions and macros for MCF_GPIO_PPDSDR_FECL */
+#define MCF_GPIO_PPDSDR_FECL_PPDSDR_FECL0          (0x01)
+#define MCF_GPIO_PPDSDR_FECL_PPDSDR_FECL1          (0x02)
+#define MCF_GPIO_PPDSDR_FECL_PPDSDR_FECL2          (0x04)
+#define MCF_GPIO_PPDSDR_FECL_PPDSDR_FECL3          (0x08)
+#define MCF_GPIO_PPDSDR_FECL_PPDSDR_FECL4          (0x10)
+#define MCF_GPIO_PPDSDR_FECL_PPDSDR_FECL5          (0x20)
+#define MCF_GPIO_PPDSDR_FECL_PPDSDR_FECL6          (0x40)
+#define MCF_GPIO_PPDSDR_FECL_PPDSDR_FECL7          (0x80)
+
+/* Bit definitions and macros for MCF_GPIO_PPDSDR_SSI */
+#define MCF_GPIO_PPDSDR_SSI_PPDSDR_SSI0            (0x01)
+#define MCF_GPIO_PPDSDR_SSI_PPDSDR_SSI1            (0x02)
+#define MCF_GPIO_PPDSDR_SSI_PPDSDR_SSI2            (0x04)
+#define MCF_GPIO_PPDSDR_SSI_PPDSDR_SSI3            (0x08)
+#define MCF_GPIO_PPDSDR_SSI_PPDSDR_SSI4            (0x10)
+
+/* Bit definitions and macros for MCF_GPIO_PPDSDR_BUSCTL */
+#define MCF_GPIO_PPDSDR_BUSCTL_POSDR_BUSCTL0       (0x01)
+#define MCF_GPIO_PPDSDR_BUSCTL_PPDSDR_BUSCTL1      (0x02)
+#define MCF_GPIO_PPDSDR_BUSCTL_PPDSDR_BUSCTL2      (0x04)
+#define MCF_GPIO_PPDSDR_BUSCTL_PPDSDR_BUSCTL3      (0x08)
+
+/* Bit definitions and macros for MCF_GPIO_PPDSDR_BE */
+#define MCF_GPIO_PPDSDR_BE_PPDSDR_BE0              (0x01)
+#define MCF_GPIO_PPDSDR_BE_PPDSDR_BE1              (0x02)
+#define MCF_GPIO_PPDSDR_BE_PPDSDR_BE2              (0x04)
+#define MCF_GPIO_PPDSDR_BE_PPDSDR_BE3              (0x08)
+
+/* Bit definitions and macros for MCF_GPIO_PPDSDR_CS */
+#define MCF_GPIO_PPDSDR_CS_PPDSDR_CS1              (0x02)
+#define MCF_GPIO_PPDSDR_CS_PPDSDR_CS2              (0x04)
+#define MCF_GPIO_PPDSDR_CS_PPDSDR_CS3              (0x08)
+#define MCF_GPIO_PPDSDR_CS_PPDSDR_CS4              (0x10)
+#define MCF_GPIO_PPDSDR_CS_PPDSDR_CS5              (0x20)
+
+/* Bit definitions and macros for MCF_GPIO_PPDSDR_PWM */
+#define MCF_GPIO_PPDSDR_PWM_PPDSDR_PWM2            (0x04)
+#define MCF_GPIO_PPDSDR_PWM_PPDSDR_PWM3            (0x08)
+#define MCF_GPIO_PPDSDR_PWM_PPDSDR_PWM4            (0x10)
+#define MCF_GPIO_PPDSDR_PWM_PPDSDR_PWM5            (0x20)
+
+/* Bit definitions and macros for MCF_GPIO_PPDSDR_FECI2C */
+#define MCF_GPIO_PPDSDR_FECI2C_PPDSDR_FECI2C0      (0x01)
+#define MCF_GPIO_PPDSDR_FECI2C_PPDSDR_FECI2C1      (0x02)
+#define MCF_GPIO_PPDSDR_FECI2C_PPDSDR_FECI2C2      (0x04)
+#define MCF_GPIO_PPDSDR_FECI2C_PPDSDR_FECI2C3      (0x08)
+
+/* Bit definitions and macros for MCF_GPIO_PPDSDR_UART */
+#define MCF_GPIO_PPDSDR_UART_PPDSDR_UART0          (0x01)
+#define MCF_GPIO_PPDSDR_UART_PPDSDR_UART1          (0x02)
+#define MCF_GPIO_PPDSDR_UART_PPDSDR_UART2          (0x04)
+#define MCF_GPIO_PPDSDR_UART_PPDSDR_UART3          (0x08)
+#define MCF_GPIO_PPDSDR_UART_PPDSDR_UART4          (0x10)
+#define MCF_GPIO_PPDSDR_UART_PPDSDR_UART5          (0x20)
+#define MCF_GPIO_PPDSDR_UART_PPDSDR_UART6          (0x40)
+#define MCF_GPIO_PPDSDR_UART_PPDSDR_UART7          (0x80)
+
+/* Bit definitions and macros for MCF_GPIO_PPDSDR_QSPI */
+#define MCF_GPIO_PPDSDR_QSPI_PPDSDR_QSPI0          (0x01)
+#define MCF_GPIO_PPDSDR_QSPI_PPDSDR_QSPI1          (0x02)
+#define MCF_GPIO_PPDSDR_QSPI_PPDSDR_QSPI2          (0x04)
+#define MCF_GPIO_PPDSDR_QSPI_PPDSDR_QSPI3          (0x08)
+#define MCF_GPIO_PPDSDR_QSPI_PPDSDR_QSPI4          (0x10)
+#define MCF_GPIO_PPDSDR_QSPI_PPDSDR_QSPI5          (0x20)
+
+/* Bit definitions and macros for MCF_GPIO_PPDSDR_TIMER */
+#define MCF_GPIO_PPDSDR_TIMER_PPDSDR_TIMER0        (0x01)
+#define MCF_GPIO_PPDSDR_TIMER_PPDSDR_TIMER1        (0x02)
+#define MCF_GPIO_PPDSDR_TIMER_PPDSDR_TIMER2        (0x04)
+#define MCF_GPIO_PPDSDR_TIMER_PPDSDR_TIMER3        (0x08)
+
+/* Bit definitions and macros for MCF_GPIO_PPDSDR_LCDDATAH */
+#define MCF_GPIO_PPDSDR_LCDDATAH_PPDSDR_LCDDATAH0  (0x01)
+#define MCF_GPIO_PPDSDR_LCDDATAH_PPDSDR_LCDDATAH1  (0x02)
+
+/* Bit definitions and macros for MCF_GPIO_PPDSDR_LCDDATAM */
+#define MCF_GPIO_PPDSDR_LCDDATAM_PPDSDR_LCDDATAM0  (0x01)
+#define MCF_GPIO_PPDSDR_LCDDATAM_PPDSDR_LCDDATAM1  (0x02)
+#define MCF_GPIO_PPDSDR_LCDDATAM_PPDSDR_LCDDATAM2  (0x04)
+#define MCF_GPIO_PPDSDR_LCDDATAM_PPDSDR_LCDDATAM3  (0x08)
+#define MCF_GPIO_PPDSDR_LCDDATAM_PPDSDR_LCDDATAM4  (0x10)
+#define MCF_GPIO_PPDSDR_LCDDATAM_PPDSDR_LCDDATAM5  (0x20)
+#define MCF_GPIO_PPDSDR_LCDDATAM_PPDSDR_LCDDATAM6  (0x40)
+#define MCF_GPIO_PPDSDR_LCDDATAM_PPDSDR_LCDDATAM7  (0x80)
+
+/* Bit definitions and macros for MCF_GPIO_PPDSDR_LCDDATAL */
+#define MCF_GPIO_PPDSDR_LCDDATAL_PPDSDR_LCDDATAL0  (0x01)
+#define MCF_GPIO_PPDSDR_LCDDATAL_PPDSDR_LCDDATAL1  (0x02)
+#define MCF_GPIO_PPDSDR_LCDDATAL_PPDSDR_LCDDATAL2  (0x04)
+#define MCF_GPIO_PPDSDR_LCDDATAL_PPDSDR_LCDDATAL3  (0x08)
+#define MCF_GPIO_PPDSDR_LCDDATAL_PPDSDR_LCDDATAL4  (0x10)
+#define MCF_GPIO_PPDSDR_LCDDATAL_PPDSDR_LCDDATAL5  (0x20)
+#define MCF_GPIO_PPDSDR_LCDDATAL_PPDSDR_LCDDATAL6  (0x40)
+#define MCF_GPIO_PPDSDR_LCDDATAL_PPDSDR_LCDDATAL7  (0x80)
+
+/* Bit definitions and macros for MCF_GPIO_PPDSDR_LCDCTLH */
+#define MCF_GPIO_PPDSDR_LCDCTLH_PPDSDR_LCDCTLH0    (0x01)
+
+/* Bit definitions and macros for MCF_GPIO_PPDSDR_LCDCTLL */
+#define MCF_GPIO_PPDSDR_LCDCTLL_PPDSDR_LCDCTLL0    (0x01)
+#define MCF_GPIO_PPDSDR_LCDCTLL_PPDSDR_LCDCTLL1    (0x02)
+#define MCF_GPIO_PPDSDR_LCDCTLL_PPDSDR_LCDCTLL2    (0x04)
+#define MCF_GPIO_PPDSDR_LCDCTLL_PPDSDR_LCDCTLL3    (0x08)
+#define MCF_GPIO_PPDSDR_LCDCTLL_PPDSDR_LCDCTLL4    (0x10)
+#define MCF_GPIO_PPDSDR_LCDCTLL_PPDSDR_LCDCTLL5    (0x20)
+#define MCF_GPIO_PPDSDR_LCDCTLL_PPDSDR_LCDCTLL6    (0x40)
+#define MCF_GPIO_PPDSDR_LCDCTLL_PPDSDR_LCDCTLL7    (0x80)
+
+/* Bit definitions and macros for MCF_GPIO_PCLRR_FECH */
+#define MCF_GPIO_PCLRR_FECH_PCLRR_FECH0            (0x01)
+#define MCF_GPIO_PCLRR_FECH_PCLRR_FECH1            (0x02)
+#define MCF_GPIO_PCLRR_FECH_PCLRR_FECH2            (0x04)
+#define MCF_GPIO_PCLRR_FECH_PCLRR_FECH3            (0x08)
+#define MCF_GPIO_PCLRR_FECH_PCLRR_FECH4            (0x10)
+#define MCF_GPIO_PCLRR_FECH_PCLRR_FECH5            (0x20)
+#define MCF_GPIO_PCLRR_FECH_PCLRR_FECH6            (0x40)
+#define MCF_GPIO_PCLRR_FECH_PCLRR_FECH7            (0x80)
+
+/* Bit definitions and macros for MCF_GPIO_PCLRR_FECL */
+#define MCF_GPIO_PCLRR_FECL_PCLRR_FECL0            (0x01)
+#define MCF_GPIO_PCLRR_FECL_PCLRR_FECL1            (0x02)
+#define MCF_GPIO_PCLRR_FECL_PCLRR_FECL2            (0x04)
+#define MCF_GPIO_PCLRR_FECL_PCLRR_FECL3            (0x08)
+#define MCF_GPIO_PCLRR_FECL_PCLRR_FECL4            (0x10)
+#define MCF_GPIO_PCLRR_FECL_PCLRR_FECL5            (0x20)
+#define MCF_GPIO_PCLRR_FECL_PCLRR_FECL6            (0x40)
+#define MCF_GPIO_PCLRR_FECL_PCLRR_FECL7            (0x80)
+
+/* Bit definitions and macros for MCF_GPIO_PCLRR_SSI */
+#define MCF_GPIO_PCLRR_SSI_PCLRR_SSI0              (0x01)
+#define MCF_GPIO_PCLRR_SSI_PCLRR_SSI1              (0x02)
+#define MCF_GPIO_PCLRR_SSI_PCLRR_SSI2              (0x04)
+#define MCF_GPIO_PCLRR_SSI_PCLRR_SSI3              (0x08)
+#define MCF_GPIO_PCLRR_SSI_PCLRR_SSI4              (0x10)
+
+/* Bit definitions and macros for MCF_GPIO_PCLRR_BUSCTL */
+#define MCF_GPIO_PCLRR_BUSCTL_POSDR_BUSCTL0        (0x01)
+#define MCF_GPIO_PCLRR_BUSCTL_PCLRR_BUSCTL1        (0x02)
+#define MCF_GPIO_PCLRR_BUSCTL_PCLRR_BUSCTL2        (0x04)
+#define MCF_GPIO_PCLRR_BUSCTL_PCLRR_BUSCTL3        (0x08)
+
+/* Bit definitions and macros for MCF_GPIO_PCLRR_BE */
+#define MCF_GPIO_PCLRR_BE_PCLRR_BE0                (0x01)
+#define MCF_GPIO_PCLRR_BE_PCLRR_BE1                (0x02)
+#define MCF_GPIO_PCLRR_BE_PCLRR_BE2                (0x04)
+#define MCF_GPIO_PCLRR_BE_PCLRR_BE3                (0x08)
+
+/* Bit definitions and macros for MCF_GPIO_PCLRR_CS */
+#define MCF_GPIO_PCLRR_CS_PCLRR_CS1                (0x02)
+#define MCF_GPIO_PCLRR_CS_PCLRR_CS2                (0x04)
+#define MCF_GPIO_PCLRR_CS_PCLRR_CS3                (0x08)
+#define MCF_GPIO_PCLRR_CS_PCLRR_CS4                (0x10)
+#define MCF_GPIO_PCLRR_CS_PCLRR_CS5                (0x20)
+
+/* Bit definitions and macros for MCF_GPIO_PCLRR_PWM */
+#define MCF_GPIO_PCLRR_PWM_PCLRR_PWM2              (0x04)
+#define MCF_GPIO_PCLRR_PWM_PCLRR_PWM3              (0x08)
+#define MCF_GPIO_PCLRR_PWM_PCLRR_PWM4              (0x10)
+#define MCF_GPIO_PCLRR_PWM_PCLRR_PWM5              (0x20)
+
+/* Bit definitions and macros for MCF_GPIO_PCLRR_FECI2C */
+#define MCF_GPIO_PCLRR_FECI2C_PCLRR_FECI2C0        (0x01)
+#define MCF_GPIO_PCLRR_FECI2C_PCLRR_FECI2C1        (0x02)
+#define MCF_GPIO_PCLRR_FECI2C_PCLRR_FECI2C2        (0x04)
+#define MCF_GPIO_PCLRR_FECI2C_PCLRR_FECI2C3        (0x08)
+
+/* Bit definitions and macros for MCF_GPIO_PCLRR_UART */
+#define MCF_GPIO_PCLRR_UART_PCLRR_UART0            (0x01)
+#define MCF_GPIO_PCLRR_UART_PCLRR_UART1            (0x02)
+#define MCF_GPIO_PCLRR_UART_PCLRR_UART2            (0x04)
+#define MCF_GPIO_PCLRR_UART_PCLRR_UART3            (0x08)
+#define MCF_GPIO_PCLRR_UART_PCLRR_UART4            (0x10)
+#define MCF_GPIO_PCLRR_UART_PCLRR_UART5            (0x20)
+#define MCF_GPIO_PCLRR_UART_PCLRR_UART6            (0x40)
+#define MCF_GPIO_PCLRR_UART_PCLRR_UART7            (0x80)
+
+/* Bit definitions and macros for MCF_GPIO_PCLRR_QSPI */
+#define MCF_GPIO_PCLRR_QSPI_PCLRR_QSPI0            (0x01)
+#define MCF_GPIO_PCLRR_QSPI_PCLRR_QSPI1            (0x02)
+#define MCF_GPIO_PCLRR_QSPI_PCLRR_QSPI2            (0x04)
+#define MCF_GPIO_PCLRR_QSPI_PCLRR_QSPI3            (0x08)
+#define MCF_GPIO_PCLRR_QSPI_PCLRR_QSPI4            (0x10)
+#define MCF_GPIO_PCLRR_QSPI_PCLRR_QSPI5            (0x20)
+
+/* Bit definitions and macros for MCF_GPIO_PCLRR_TIMER */
+#define MCF_GPIO_PCLRR_TIMER_PCLRR_TIMER0          (0x01)
+#define MCF_GPIO_PCLRR_TIMER_PCLRR_TIMER1          (0x02)
+#define MCF_GPIO_PCLRR_TIMER_PCLRR_TIMER2          (0x04)
+#define MCF_GPIO_PCLRR_TIMER_PCLRR_TIMER3          (0x08)
+
+/* Bit definitions and macros for MCF_GPIO_PCLRR_LCDDATAH */
+#define MCF_GPIO_PCLRR_LCDDATAH_PCLRR_LCDDATAH0    (0x01)
+#define MCF_GPIO_PCLRR_LCDDATAH_PCLRR_LCDDATAH1    (0x02)
+
+/* Bit definitions and macros for MCF_GPIO_PCLRR_LCDDATAM */
+#define MCF_GPIO_PCLRR_LCDDATAM_PCLRR_LCDDATAM0    (0x01)
+#define MCF_GPIO_PCLRR_LCDDATAM_PCLRR_LCDDATAM1    (0x02)
+#define MCF_GPIO_PCLRR_LCDDATAM_PCLRR_LCDDATAM2    (0x04)
+#define MCF_GPIO_PCLRR_LCDDATAM_PCLRR_LCDDATAM3    (0x08)
+#define MCF_GPIO_PCLRR_LCDDATAM_PCLRR_LCDDATAM4    (0x10)
+#define MCF_GPIO_PCLRR_LCDDATAM_PCLRR_LCDDATAM5    (0x20)
+#define MCF_GPIO_PCLRR_LCDDATAM_PCLRR_LCDDATAM6    (0x40)
+#define MCF_GPIO_PCLRR_LCDDATAM_PCLRR_LCDDATAM7    (0x80)
+
+/* Bit definitions and macros for MCF_GPIO_PCLRR_LCDDATAL */
+#define MCF_GPIO_PCLRR_LCDDATAL_PCLRR_LCDDATAL0    (0x01)
+#define MCF_GPIO_PCLRR_LCDDATAL_PCLRR_LCDDATAL1    (0x02)
+#define MCF_GPIO_PCLRR_LCDDATAL_PCLRR_LCDDATAL2    (0x04)
+#define MCF_GPIO_PCLRR_LCDDATAL_PCLRR_LCDDATAL3    (0x08)
+#define MCF_GPIO_PCLRR_LCDDATAL_PCLRR_LCDDATAL4    (0x10)
+#define MCF_GPIO_PCLRR_LCDDATAL_PCLRR_LCDDATAL5    (0x20)
+#define MCF_GPIO_PCLRR_LCDDATAL_PCLRR_LCDDATAL6    (0x40)
+#define MCF_GPIO_PCLRR_LCDDATAL_PCLRR_LCDDATAL7    (0x80)
+
+/* Bit definitions and macros for MCF_GPIO_PCLRR_LCDCTLH */
+#define MCF_GPIO_PCLRR_LCDCTLH_PCLRR_LCDCTLH0      (0x01)
+
+/* Bit definitions and macros for MCF_GPIO_PCLRR_LCDCTLL */
+#define MCF_GPIO_PCLRR_LCDCTLL_PCLRR_LCDCTLL0      (0x01)
+#define MCF_GPIO_PCLRR_LCDCTLL_PCLRR_LCDCTLL1      (0x02)
+#define MCF_GPIO_PCLRR_LCDCTLL_PCLRR_LCDCTLL2      (0x04)
+#define MCF_GPIO_PCLRR_LCDCTLL_PCLRR_LCDCTLL3      (0x08)
+#define MCF_GPIO_PCLRR_LCDCTLL_PCLRR_LCDCTLL4      (0x10)
+#define MCF_GPIO_PCLRR_LCDCTLL_PCLRR_LCDCTLL5      (0x20)
+#define MCF_GPIO_PCLRR_LCDCTLL_PCLRR_LCDCTLL6      (0x40)
+#define MCF_GPIO_PCLRR_LCDCTLL_PCLRR_LCDCTLL7      (0x80)
+
+/* Bit definitions and macros for MCF_GPIO_PAR_FEC */
+#define MCF_GPIO_PAR_FEC_PAR_FEC_MII(x)            (((x)&0x03)<<0)
+#define MCF_GPIO_PAR_FEC_PAR_FEC_7W(x)             (((x)&0x03)<<2)
+#define MCF_GPIO_PAR_FEC_PAR_FEC_7W_GPIO           (0x00)
+#define MCF_GPIO_PAR_FEC_PAR_FEC_7W_URTS1          (0x04)
+#define MCF_GPIO_PAR_FEC_PAR_FEC_7W_FEC            (0x0C)
+#define MCF_GPIO_PAR_FEC_PAR_FEC_MII_GPIO          (0x00)
+#define MCF_GPIO_PAR_FEC_PAR_FEC_MII_UART          (0x01)
+#define MCF_GPIO_PAR_FEC_PAR_FEC_MII_FEC           (0x03)
+
+/* Bit definitions and macros for MCF_GPIO_PAR_PWM */
+#define MCF_GPIO_PAR_PWM_PAR_PWM1(x)               (((x)&0x03)<<0)
+#define MCF_GPIO_PAR_PWM_PAR_PWM3(x)               (((x)&0x03)<<2)
+#define MCF_GPIO_PAR_PWM_PAR_PWM5                  (0x10)
+#define MCF_GPIO_PAR_PWM_PAR_PWM7                  (0x20)
+
+/* Bit definitions and macros for MCF_GPIO_PAR_BUSCTL */
+#define MCF_GPIO_PAR_BUSCTL_PAR_TS(x)              (((x)&0x03)<<3)
+#define MCF_GPIO_PAR_BUSCTL_PAR_RWB                (0x20)
+#define MCF_GPIO_PAR_BUSCTL_PAR_TA                 (0x40)
+#define MCF_GPIO_PAR_BUSCTL_PAR_OE                 (0x80)
+#define MCF_GPIO_PAR_BUSCTL_PAR_OE_GPIO            (0x00)
+#define MCF_GPIO_PAR_BUSCTL_PAR_OE_OE              (0x80)
+#define MCF_GPIO_PAR_BUSCTL_PAR_TA_GPIO            (0x00)
+#define MCF_GPIO_PAR_BUSCTL_PAR_TA_TA              (0x40)
+#define MCF_GPIO_PAR_BUSCTL_PAR_RWB_GPIO           (0x00)
+#define MCF_GPIO_PAR_BUSCTL_PAR_RWB_RWB            (0x20)
+#define MCF_GPIO_PAR_BUSCTL_PAR_TS_GPIO            (0x00)
+#define MCF_GPIO_PAR_BUSCTL_PAR_TS_DACK0           (0x10)
+#define MCF_GPIO_PAR_BUSCTL_PAR_TS_TS              (0x18)
+
+/* Bit definitions and macros for MCF_GPIO_PAR_FECI2C */
+#define MCF_GPIO_PAR_FECI2C_PAR_SDA(x)             (((x)&0x03)<<0)
+#define MCF_GPIO_PAR_FECI2C_PAR_SCL(x)             (((x)&0x03)<<2)
+#define MCF_GPIO_PAR_FECI2C_PAR_MDIO(x)            (((x)&0x03)<<4)
+#define MCF_GPIO_PAR_FECI2C_PAR_MDC(x)             (((x)&0x03)<<6)
+#define MCF_GPIO_PAR_FECI2C_PAR_MDC_GPIO           (0x00)
+#define MCF_GPIO_PAR_FECI2C_PAR_MDC_UTXD2          (0x40)
+#define MCF_GPIO_PAR_FECI2C_PAR_MDC_SCL            (0x80)
+#define MCF_GPIO_PAR_FECI2C_PAR_MDC_EMDC           (0xC0)
+#define MCF_GPIO_PAR_FECI2C_PAR_MDIO_GPIO          (0x00)
+#define MCF_GPIO_PAR_FECI2C_PAR_MDIO_URXD2         (0x10)
+#define MCF_GPIO_PAR_FECI2C_PAR_MDIO_SDA           (0x20)
+#define MCF_GPIO_PAR_FECI2C_PAR_MDIO_EMDIO         (0x30)
+#define MCF_GPIO_PAR_FECI2C_PAR_SCL_GPIO           (0x00)
+#define MCF_GPIO_PAR_FECI2C_PAR_SCL_UTXD2          (0x04)
+#define MCF_GPIO_PAR_FECI2C_PAR_SCL_SCL            (0x0C)
+#define MCF_GPIO_PAR_FECI2C_PAR_SDA_GPIO           (0x00)
+#define MCF_GPIO_PAR_FECI2C_PAR_SDA_URXD2          (0x02)
+#define MCF_GPIO_PAR_FECI2C_PAR_SDA_SDA            (0x03)
+
+/* Bit definitions and macros for MCF_GPIO_PAR_BE */
+#define MCF_GPIO_PAR_BE_PAR_BE0                    (0x01)
+#define MCF_GPIO_PAR_BE_PAR_BE1                    (0x02)
+#define MCF_GPIO_PAR_BE_PAR_BE2                    (0x04)
+#define MCF_GPIO_PAR_BE_PAR_BE3                    (0x08)
+
+/* Bit definitions and macros for MCF_GPIO_PAR_CS */
+#define MCF_GPIO_PAR_CS_PAR_CS1                    (0x02)
+#define MCF_GPIO_PAR_CS_PAR_CS2                    (0x04)
+#define MCF_GPIO_PAR_CS_PAR_CS3                    (0x08)
+#define MCF_GPIO_PAR_CS_PAR_CS4                    (0x10)
+#define MCF_GPIO_PAR_CS_PAR_CS5                    (0x20)
+#define MCF_GPIO_PAR_CS_PAR_CS_CS1_GPIO            (0x00)
+#define MCF_GPIO_PAR_CS_PAR_CS_CS1_SDCS1           (0x01)
+#define MCF_GPIO_PAR_CS_PAR_CS_CS1_CS1             (0x03)
+
+/* Bit definitions and macros for MCF_GPIO_PAR_SSI */
+#define MCF_GPIO_PAR_SSI_PAR_MCLK                  (0x0080)
+#define MCF_GPIO_PAR_SSI_PAR_TXD(x)                (((x)&0x0003)<<8)
+#define MCF_GPIO_PAR_SSI_PAR_RXD(x)                (((x)&0x0003)<<10)
+#define MCF_GPIO_PAR_SSI_PAR_FS(x)                 (((x)&0x0003)<<12)
+#define MCF_GPIO_PAR_SSI_PAR_BCLK(x)               (((x)&0x0003)<<14)
+
+/* Bit definitions and macros for MCF_GPIO_PAR_UART */
+#define MCF_GPIO_PAR_UART_PAR_UTXD0                (0x0001)
+#define MCF_GPIO_PAR_UART_PAR_URXD0                (0x0002)
+#define MCF_GPIO_PAR_UART_PAR_URTS0                (0x0004)
+#define MCF_GPIO_PAR_UART_PAR_UCTS0                (0x0008)
+#define MCF_GPIO_PAR_UART_PAR_UTXD1(x)             (((x)&0x0003)<<4)
+#define MCF_GPIO_PAR_UART_PAR_URXD1(x)             (((x)&0x0003)<<6)
+#define MCF_GPIO_PAR_UART_PAR_URTS1(x)             (((x)&0x0003)<<8)
+#define MCF_GPIO_PAR_UART_PAR_UCTS1(x)             (((x)&0x0003)<<10)
+#define MCF_GPIO_PAR_UART_PAR_UCTS1_GPIO           (0x0000)
+#define MCF_GPIO_PAR_UART_PAR_UCTS1_SSI_BCLK       (0x0800)
+#define MCF_GPIO_PAR_UART_PAR_UCTS1_ULPI_D7        (0x0400)
+#define MCF_GPIO_PAR_UART_PAR_UCTS1_UCTS1          (0x0C00)
+#define MCF_GPIO_PAR_UART_PAR_URTS1_GPIO           (0x0000)
+#define MCF_GPIO_PAR_UART_PAR_URTS1_SSI_FS         (0x0200)
+#define MCF_GPIO_PAR_UART_PAR_URTS1_ULPI_D6        (0x0100)
+#define MCF_GPIO_PAR_UART_PAR_URTS1_URTS1          (0x0300)
+#define MCF_GPIO_PAR_UART_PAR_URXD1_GPIO           (0x0000)
+#define MCF_GPIO_PAR_UART_PAR_URXD1_SSI_RXD        (0x0080)
+#define MCF_GPIO_PAR_UART_PAR_URXD1_ULPI_D5        (0x0040)
+#define MCF_GPIO_PAR_UART_PAR_URXD1_URXD1          (0x00C0)
+#define MCF_GPIO_PAR_UART_PAR_UTXD1_GPIO           (0x0000)
+#define MCF_GPIO_PAR_UART_PAR_UTXD1_SSI_TXD        (0x0020)
+#define MCF_GPIO_PAR_UART_PAR_UTXD1_ULPI_D4        (0x0010)
+#define MCF_GPIO_PAR_UART_PAR_UTXD1_UTXD1          (0x0030)
+
+/* Bit definitions and macros for MCF_GPIO_PAR_QSPI */
+#define MCF_GPIO_PAR_QSPI_PAR_SCK(x)               (((x)&0x0003)<<4)
+#define MCF_GPIO_PAR_QSPI_PAR_DOUT(x)              (((x)&0x0003)<<6)
+#define MCF_GPIO_PAR_QSPI_PAR_DIN(x)               (((x)&0x0003)<<8)
+#define MCF_GPIO_PAR_QSPI_PAR_PCS0(x)              (((x)&0x0003)<<10)
+#define MCF_GPIO_PAR_QSPI_PAR_PCS1(x)              (((x)&0x0003)<<12)
+#define MCF_GPIO_PAR_QSPI_PAR_PCS2(x)              (((x)&0x0003)<<14)
+
+/* Bit definitions and macros for MCF_GPIO_PAR_TIMER */
+#define MCF_GPIO_PAR_TIMER_PAR_TIN0(x)             (((x)&0x03)<<0)
+#define MCF_GPIO_PAR_TIMER_PAR_TIN1(x)             (((x)&0x03)<<2)
+#define MCF_GPIO_PAR_TIMER_PAR_TIN2(x)             (((x)&0x03)<<4)
+#define MCF_GPIO_PAR_TIMER_PAR_TIN3(x)             (((x)&0x03)<<6)
+#define MCF_GPIO_PAR_TIMER_PAR_TIN3_GPIO           (0x00)
+#define MCF_GPIO_PAR_TIMER_PAR_TIN3_TOUT3          (0x80)
+#define MCF_GPIO_PAR_TIMER_PAR_TIN3_URXD2          (0x40)
+#define MCF_GPIO_PAR_TIMER_PAR_TIN3_TIN3           (0xC0)
+#define MCF_GPIO_PAR_TIMER_PAR_TIN2_GPIO           (0x00)
+#define MCF_GPIO_PAR_TIMER_PAR_TIN2_TOUT2          (0x20)
+#define MCF_GPIO_PAR_TIMER_PAR_TIN2_UTXD2          (0x10)
+#define MCF_GPIO_PAR_TIMER_PAR_TIN2_TIN2           (0x30)
+#define MCF_GPIO_PAR_TIMER_PAR_TIN1_GPIO           (0x00)
+#define MCF_GPIO_PAR_TIMER_PAR_TIN1_TOUT1          (0x08)
+#define MCF_GPIO_PAR_TIMER_PAR_TIN1_DACK1          (0x04)
+#define MCF_GPIO_PAR_TIMER_PAR_TIN1_TIN1           (0x0C)
+#define MCF_GPIO_PAR_TIMER_PAR_TIN0_GPIO           (0x00)
+#define MCF_GPIO_PAR_TIMER_PAR_TIN0_TOUT0          (0x02)
+#define MCF_GPIO_PAR_TIMER_PAR_TIN0_DREQ0          (0x01)
+#define MCF_GPIO_PAR_TIMER_PAR_TIN0_TIN0           (0x03)
+
+/* Bit definitions and macros for MCF_GPIO_PAR_LCDDATA */
+#define MCF_GPIO_PAR_LCDDATA_PAR_LD7_0(x)          (((x)&0x03)<<0)
+#define MCF_GPIO_PAR_LCDDATA_PAR_LD15_8(x)         (((x)&0x03)<<2)
+#define MCF_GPIO_PAR_LCDDATA_PAR_LD16(x)           (((x)&0x03)<<4)
+#define MCF_GPIO_PAR_LCDDATA_PAR_LD17(x)           (((x)&0x03)<<6)
+
+/* Bit definitions and macros for MCF_GPIO_PAR_LCDCTL */
+#define MCF_GPIO_PAR_LCDCTL_PAR_CLS                (0x0001)
+#define MCF_GPIO_PAR_LCDCTL_PAR_PS                 (0x0002)
+#define MCF_GPIO_PAR_LCDCTL_PAR_REV                (0x0004)
+#define MCF_GPIO_PAR_LCDCTL_PAR_SPL_SPR            (0x0008)
+#define MCF_GPIO_PAR_LCDCTL_PAR_CONTRAST           (0x0010)
+#define MCF_GPIO_PAR_LCDCTL_PAR_LSCLK              (0x0020)
+#define MCF_GPIO_PAR_LCDCTL_PAR_LP_HSYNC           (0x0040)
+#define MCF_GPIO_PAR_LCDCTL_PAR_FLM_VSYNC          (0x0080)
+#define MCF_GPIO_PAR_LCDCTL_PAR_ACD_OE             (0x0100)
+
+/* Bit definitions and macros for MCF_GPIO_PAR_IRQ */
+#define MCF_GPIO_PAR_IRQ_PAR_IRQ1(x)               (((x)&0x0003)<<4)
+#define MCF_GPIO_PAR_IRQ_PAR_IRQ2(x)               (((x)&0x0003)<<6)
+#define MCF_GPIO_PAR_IRQ_PAR_IRQ4(x)               (((x)&0x0003)<<8)
+#define MCF_GPIO_PAR_IRQ_PAR_IRQ5(x)               (((x)&0x0003)<<10)
+#define MCF_GPIO_PAR_IRQ_PAR_IRQ6(x)               (((x)&0x0003)<<12)
+
+/* Bit definitions and macros for MCF_GPIO_MSCR_FLEXBUS */
+#define MCF_GPIO_MSCR_FLEXBUS_MSCR_ADDRCTL(x)      (((x)&0x03)<<0)
+#define MCF_GPIO_MSCR_FLEXBUS_MSCR_DLOWER(x)       (((x)&0x03)<<2)
+#define MCF_GPIO_MSCR_FLEXBUS_MSCR_DUPPER(x)       (((x)&0x03)<<4)
+
+/* Bit definitions and macros for MCF_GPIO_MSCR_SDRAM */
+#define MCF_GPIO_MSCR_SDRAM_MSCR_SDRAM(x)          (((x)&0x03)<<0)
+#define MCF_GPIO_MSCR_SDRAM_MSCR_SDCLK(x)          (((x)&0x03)<<2)
+#define MCF_GPIO_MSCR_SDRAM_MSCR_SDCLKB(x)         (((x)&0x03)<<4)
+
+/* Bit definitions and macros for MCF_GPIO_DSCR_I2C */
+#define MCF_GPIO_DSCR_I2C_I2C_DSE(x)               (((x)&0x03)<<0)
+
+/* Bit definitions and macros for MCF_GPIO_DSCR_PWM */
+#define MCF_GPIO_DSCR_PWM_PWM_DSE(x)               (((x)&0x03)<<0)
+
+/* Bit definitions and macros for MCF_GPIO_DSCR_FEC */
+#define MCF_GPIO_DSCR_FEC_FEC_DSE(x)               (((x)&0x03)<<0)
+
+/* Bit definitions and macros for MCF_GPIO_DSCR_UART */
+#define MCF_GPIO_DSCR_UART_UART0_DSE(x)            (((x)&0x03)<<0)
+#define MCF_GPIO_DSCR_UART_UART1_DSE(x)            (((x)&0x03)<<2)
+
+/* Bit definitions and macros for MCF_GPIO_DSCR_QSPI */
+#define MCF_GPIO_DSCR_QSPI_QSPI_DSE(x)             (((x)&0x03)<<0)
+
+/* Bit definitions and macros for MCF_GPIO_DSCR_TIMER */
+#define MCF_GPIO_DSCR_TIMER_TIMER_DSE(x)           (((x)&0x03)<<0)
+
+/* Bit definitions and macros for MCF_GPIO_DSCR_SSI */
+#define MCF_GPIO_DSCR_SSI_SSI_DSE(x)               (((x)&0x03)<<0)
+
+/* Bit definitions and macros for MCF_GPIO_DSCR_LCD */
+#define MCF_GPIO_DSCR_LCD_LCD_DSE(x)               (((x)&0x03)<<0)
+
+/* Bit definitions and macros for MCF_GPIO_DSCR_DEBUG */
+#define MCF_GPIO_DSCR_DEBUG_DEBUG_DSE(x)           (((x)&0x03)<<0)
+
+/* Bit definitions and macros for MCF_GPIO_DSCR_CLKRST */
+#define MCF_GPIO_DSCR_CLKRST_CLKRST_DSE(x)         (((x)&0x03)<<0)
+
+/* Bit definitions and macros for MCF_GPIO_DSCR_IRQ */
+#define MCF_GPIO_DSCR_IRQ_IRQ_DSE(x)               (((x)&0x03)<<0)
+
+/*********************************************************************
+ *
+ * Interrupt Controller (INTC)
+ *
+ *********************************************************************/
+
+/* Register read/write macros */
+#define MCF_INTC0_IPRH             MCF_REG32(0xFC048000)
+#define MCF_INTC0_IPRL             MCF_REG32(0xFC048004)
+#define MCF_INTC0_IMRH             MCF_REG32(0xFC048008)
+#define MCF_INTC0_IMRL             MCF_REG32(0xFC04800C)
+#define MCF_INTC0_INTFRCH          MCF_REG32(0xFC048010)
+#define MCF_INTC0_INTFRCL          MCF_REG32(0xFC048014)
+#define MCF_INTC0_ICONFIG          MCF_REG16(0xFC04801A)
+#define MCF_INTC0_SIMR             MCF_REG08(0xFC04801C)
+#define MCF_INTC0_CIMR             MCF_REG08(0xFC04801D)
+#define MCF_INTC0_CLMASK           MCF_REG08(0xFC04801E)
+#define MCF_INTC0_SLMASK           MCF_REG08(0xFC04801F)
+#define MCF_INTC0_ICR0             MCF_REG08(0xFC048040)
+#define MCF_INTC0_ICR1             MCF_REG08(0xFC048041)
+#define MCF_INTC0_ICR2             MCF_REG08(0xFC048042)
+#define MCF_INTC0_ICR3             MCF_REG08(0xFC048043)
+#define MCF_INTC0_ICR4             MCF_REG08(0xFC048044)
+#define MCF_INTC0_ICR5             MCF_REG08(0xFC048045)
+#define MCF_INTC0_ICR6             MCF_REG08(0xFC048046)
+#define MCF_INTC0_ICR7             MCF_REG08(0xFC048047)
+#define MCF_INTC0_ICR8             MCF_REG08(0xFC048048)
+#define MCF_INTC0_ICR9             MCF_REG08(0xFC048049)
+#define MCF_INTC0_ICR10            MCF_REG08(0xFC04804A)
+#define MCF_INTC0_ICR11            MCF_REG08(0xFC04804B)
+#define MCF_INTC0_ICR12            MCF_REG08(0xFC04804C)
+#define MCF_INTC0_ICR13            MCF_REG08(0xFC04804D)
+#define MCF_INTC0_ICR14            MCF_REG08(0xFC04804E)
+#define MCF_INTC0_ICR15            MCF_REG08(0xFC04804F)
+#define MCF_INTC0_ICR16            MCF_REG08(0xFC048050)
+#define MCF_INTC0_ICR17            MCF_REG08(0xFC048051)
+#define MCF_INTC0_ICR18            MCF_REG08(0xFC048052)
+#define MCF_INTC0_ICR19            MCF_REG08(0xFC048053)
+#define MCF_INTC0_ICR20            MCF_REG08(0xFC048054)
+#define MCF_INTC0_ICR21            MCF_REG08(0xFC048055)
+#define MCF_INTC0_ICR22            MCF_REG08(0xFC048056)
+#define MCF_INTC0_ICR23            MCF_REG08(0xFC048057)
+#define MCF_INTC0_ICR24            MCF_REG08(0xFC048058)
+#define MCF_INTC0_ICR25            MCF_REG08(0xFC048059)
+#define MCF_INTC0_ICR26            MCF_REG08(0xFC04805A)
+#define MCF_INTC0_ICR27            MCF_REG08(0xFC04805B)
+#define MCF_INTC0_ICR28            MCF_REG08(0xFC04805C)
+#define MCF_INTC0_ICR29            MCF_REG08(0xFC04805D)
+#define MCF_INTC0_ICR30            MCF_REG08(0xFC04805E)
+#define MCF_INTC0_ICR31            MCF_REG08(0xFC04805F)
+#define MCF_INTC0_ICR32            MCF_REG08(0xFC048060)
+#define MCF_INTC0_ICR33            MCF_REG08(0xFC048061)
+#define MCF_INTC0_ICR34            MCF_REG08(0xFC048062)
+#define MCF_INTC0_ICR35            MCF_REG08(0xFC048063)
+#define MCF_INTC0_ICR36            MCF_REG08(0xFC048064)
+#define MCF_INTC0_ICR37            MCF_REG08(0xFC048065)
+#define MCF_INTC0_ICR38            MCF_REG08(0xFC048066)
+#define MCF_INTC0_ICR39            MCF_REG08(0xFC048067)
+#define MCF_INTC0_ICR40            MCF_REG08(0xFC048068)
+#define MCF_INTC0_ICR41            MCF_REG08(0xFC048069)
+#define MCF_INTC0_ICR42            MCF_REG08(0xFC04806A)
+#define MCF_INTC0_ICR43            MCF_REG08(0xFC04806B)
+#define MCF_INTC0_ICR44            MCF_REG08(0xFC04806C)
+#define MCF_INTC0_ICR45            MCF_REG08(0xFC04806D)
+#define MCF_INTC0_ICR46            MCF_REG08(0xFC04806E)
+#define MCF_INTC0_ICR47            MCF_REG08(0xFC04806F)
+#define MCF_INTC0_ICR48            MCF_REG08(0xFC048070)
+#define MCF_INTC0_ICR49            MCF_REG08(0xFC048071)
+#define MCF_INTC0_ICR50            MCF_REG08(0xFC048072)
+#define MCF_INTC0_ICR51            MCF_REG08(0xFC048073)
+#define MCF_INTC0_ICR52            MCF_REG08(0xFC048074)
+#define MCF_INTC0_ICR53            MCF_REG08(0xFC048075)
+#define MCF_INTC0_ICR54            MCF_REG08(0xFC048076)
+#define MCF_INTC0_ICR55            MCF_REG08(0xFC048077)
+#define MCF_INTC0_ICR56            MCF_REG08(0xFC048078)
+#define MCF_INTC0_ICR57            MCF_REG08(0xFC048079)
+#define MCF_INTC0_ICR58            MCF_REG08(0xFC04807A)
+#define MCF_INTC0_ICR59            MCF_REG08(0xFC04807B)
+#define MCF_INTC0_ICR60            MCF_REG08(0xFC04807C)
+#define MCF_INTC0_ICR61            MCF_REG08(0xFC04807D)
+#define MCF_INTC0_ICR62            MCF_REG08(0xFC04807E)
+#define MCF_INTC0_ICR63            MCF_REG08(0xFC04807F)
+#define MCF_INTC0_ICR(x)           MCF_REG08(0xFC048040+((x)*0x001))
+#define MCF_INTC0_SWIACK           MCF_REG08(0xFC0480E0)
+#define MCF_INTC0_L1IACK           MCF_REG08(0xFC0480E4)
+#define MCF_INTC0_L2IACK           MCF_REG08(0xFC0480E8)
+#define MCF_INTC0_L3IACK           MCF_REG08(0xFC0480EC)
+#define MCF_INTC0_L4IACK           MCF_REG08(0xFC0480F0)
+#define MCF_INTC0_L5IACK           MCF_REG08(0xFC0480F4)
+#define MCF_INTC0_L6IACK           MCF_REG08(0xFC0480F8)
+#define MCF_INTC0_L7IACK           MCF_REG08(0xFC0480FC)
+#define MCF_INTC0_LIACK(x)         MCF_REG08(0xFC0480E4+((x)*0x004))
+#define MCF_INTC1_IPRH             MCF_REG32(0xFC04C000)
+#define MCF_INTC1_IPRL             MCF_REG32(0xFC04C004)
+#define MCF_INTC1_IMRH             MCF_REG32(0xFC04C008)
+#define MCF_INTC1_IMRL             MCF_REG32(0xFC04C00C)
+#define MCF_INTC1_INTFRCH          MCF_REG32(0xFC04C010)
+#define MCF_INTC1_INTFRCL          MCF_REG32(0xFC04C014)
+#define MCF_INTC1_ICONFIG          MCF_REG16(0xFC04C01A)
+#define MCF_INTC1_SIMR             MCF_REG08(0xFC04C01C)
+#define MCF_INTC1_CIMR             MCF_REG08(0xFC04C01D)
+#define MCF_INTC1_CLMASK           MCF_REG08(0xFC04C01E)
+#define MCF_INTC1_SLMASK           MCF_REG08(0xFC04C01F)
+#define MCF_INTC1_ICR0             MCF_REG08(0xFC04C040)
+#define MCF_INTC1_ICR1             MCF_REG08(0xFC04C041)
+#define MCF_INTC1_ICR2             MCF_REG08(0xFC04C042)
+#define MCF_INTC1_ICR3             MCF_REG08(0xFC04C043)
+#define MCF_INTC1_ICR4             MCF_REG08(0xFC04C044)
+#define MCF_INTC1_ICR5             MCF_REG08(0xFC04C045)
+#define MCF_INTC1_ICR6             MCF_REG08(0xFC04C046)
+#define MCF_INTC1_ICR7             MCF_REG08(0xFC04C047)
+#define MCF_INTC1_ICR8             MCF_REG08(0xFC04C048)
+#define MCF_INTC1_ICR9             MCF_REG08(0xFC04C049)
+#define MCF_INTC1_ICR10            MCF_REG08(0xFC04C04A)
+#define MCF_INTC1_ICR11            MCF_REG08(0xFC04C04B)
+#define MCF_INTC1_ICR12            MCF_REG08(0xFC04C04C)
+#define MCF_INTC1_ICR13            MCF_REG08(0xFC04C04D)
+#define MCF_INTC1_ICR14            MCF_REG08(0xFC04C04E)
+#define MCF_INTC1_ICR15            MCF_REG08(0xFC04C04F)
+#define MCF_INTC1_ICR16            MCF_REG08(0xFC04C050)
+#define MCF_INTC1_ICR17            MCF_REG08(0xFC04C051)
+#define MCF_INTC1_ICR18            MCF_REG08(0xFC04C052)
+#define MCF_INTC1_ICR19            MCF_REG08(0xFC04C053)
+#define MCF_INTC1_ICR20            MCF_REG08(0xFC04C054)
+#define MCF_INTC1_ICR21            MCF_REG08(0xFC04C055)
+#define MCF_INTC1_ICR22            MCF_REG08(0xFC04C056)
+#define MCF_INTC1_ICR23            MCF_REG08(0xFC04C057)
+#define MCF_INTC1_ICR24            MCF_REG08(0xFC04C058)
+#define MCF_INTC1_ICR25            MCF_REG08(0xFC04C059)
+#define MCF_INTC1_ICR26            MCF_REG08(0xFC04C05A)
+#define MCF_INTC1_ICR27            MCF_REG08(0xFC04C05B)
+#define MCF_INTC1_ICR28            MCF_REG08(0xFC04C05C)
+#define MCF_INTC1_ICR29            MCF_REG08(0xFC04C05D)
+#define MCF_INTC1_ICR30            MCF_REG08(0xFC04C05E)
+#define MCF_INTC1_ICR31            MCF_REG08(0xFC04C05F)
+#define MCF_INTC1_ICR32            MCF_REG08(0xFC04C060)
+#define MCF_INTC1_ICR33            MCF_REG08(0xFC04C061)
+#define MCF_INTC1_ICR34            MCF_REG08(0xFC04C062)
+#define MCF_INTC1_ICR35            MCF_REG08(0xFC04C063)
+#define MCF_INTC1_ICR36            MCF_REG08(0xFC04C064)
+#define MCF_INTC1_ICR37            MCF_REG08(0xFC04C065)
+#define MCF_INTC1_ICR38            MCF_REG08(0xFC04C066)
+#define MCF_INTC1_ICR39            MCF_REG08(0xFC04C067)
+#define MCF_INTC1_ICR40            MCF_REG08(0xFC04C068)
+#define MCF_INTC1_ICR41            MCF_REG08(0xFC04C069)
+#define MCF_INTC1_ICR42            MCF_REG08(0xFC04C06A)
+#define MCF_INTC1_ICR43            MCF_REG08(0xFC04C06B)
+#define MCF_INTC1_ICR44            MCF_REG08(0xFC04C06C)
+#define MCF_INTC1_ICR45            MCF_REG08(0xFC04C06D)
+#define MCF_INTC1_ICR46            MCF_REG08(0xFC04C06E)
+#define MCF_INTC1_ICR47            MCF_REG08(0xFC04C06F)
+#define MCF_INTC1_ICR48            MCF_REG08(0xFC04C070)
+#define MCF_INTC1_ICR49            MCF_REG08(0xFC04C071)
+#define MCF_INTC1_ICR50            MCF_REG08(0xFC04C072)
+#define MCF_INTC1_ICR51            MCF_REG08(0xFC04C073)
+#define MCF_INTC1_ICR52            MCF_REG08(0xFC04C074)
+#define MCF_INTC1_ICR53            MCF_REG08(0xFC04C075)
+#define MCF_INTC1_ICR54            MCF_REG08(0xFC04C076)
+#define MCF_INTC1_ICR55            MCF_REG08(0xFC04C077)
+#define MCF_INTC1_ICR56            MCF_REG08(0xFC04C078)
+#define MCF_INTC1_ICR57            MCF_REG08(0xFC04C079)
+#define MCF_INTC1_ICR58            MCF_REG08(0xFC04C07A)
+#define MCF_INTC1_ICR59            MCF_REG08(0xFC04C07B)
+#define MCF_INTC1_ICR60            MCF_REG08(0xFC04C07C)
+#define MCF_INTC1_ICR61            MCF_REG08(0xFC04C07D)
+#define MCF_INTC1_ICR62            MCF_REG08(0xFC04C07E)
+#define MCF_INTC1_ICR63            MCF_REG08(0xFC04C07F)
+#define MCF_INTC1_ICR(x)           MCF_REG08(0xFC04C040+((x)*0x001))
+#define MCF_INTC1_SWIACK           MCF_REG08(0xFC04C0E0)
+#define MCF_INTC1_L1IACK           MCF_REG08(0xFC04C0E4)
+#define MCF_INTC1_L2IACK           MCF_REG08(0xFC04C0E8)
+#define MCF_INTC1_L3IACK           MCF_REG08(0xFC04C0EC)
+#define MCF_INTC1_L4IACK           MCF_REG08(0xFC04C0F0)
+#define MCF_INTC1_L5IACK           MCF_REG08(0xFC04C0F4)
+#define MCF_INTC1_L6IACK           MCF_REG08(0xFC04C0F8)
+#define MCF_INTC1_L7IACK           MCF_REG08(0xFC04C0FC)
+#define MCF_INTC1_LIACK(x)         MCF_REG08(0xFC04C0E4+((x)*0x004))
+#define MCF_INTC_IPRH(x)           MCF_REG32(0xFC048000+((x)*0x4000))
+#define MCF_INTC_IPRL(x)           MCF_REG32(0xFC048004+((x)*0x4000))
+#define MCF_INTC_IMRH(x)           MCF_REG32(0xFC048008+((x)*0x4000))
+#define MCF_INTC_IMRL(x)           MCF_REG32(0xFC04800C+((x)*0x4000))
+#define MCF_INTC_INTFRCH(x)        MCF_REG32(0xFC048010+((x)*0x4000))
+#define MCF_INTC_INTFRCL(x)        MCF_REG32(0xFC048014+((x)*0x4000))
+#define MCF_INTC_ICONFIG(x)        MCF_REG16(0xFC04801A+((x)*0x4000))
+#define MCF_INTC_SIMR(x)           MCF_REG08(0xFC04801C+((x)*0x4000))
+#define MCF_INTC_CIMR(x)           MCF_REG08(0xFC04801D+((x)*0x4000))
+#define MCF_INTC_CLMASK(x)         MCF_REG08(0xFC04801E+((x)*0x4000))
+#define MCF_INTC_SLMASK(x)         MCF_REG08(0xFC04801F+((x)*0x4000))
+#define MCF_INTC_ICR0(x)           MCF_REG08(0xFC048040+((x)*0x4000))
+#define MCF_INTC_ICR1(x)           MCF_REG08(0xFC048041+((x)*0x4000))
+#define MCF_INTC_ICR2(x)           MCF_REG08(0xFC048042+((x)*0x4000))
+#define MCF_INTC_ICR3(x)           MCF_REG08(0xFC048043+((x)*0x4000))
+#define MCF_INTC_ICR4(x)           MCF_REG08(0xFC048044+((x)*0x4000))
+#define MCF_INTC_ICR5(x)           MCF_REG08(0xFC048045+((x)*0x4000))
+#define MCF_INTC_ICR6(x)           MCF_REG08(0xFC048046+((x)*0x4000))
+#define MCF_INTC_ICR7(x)           MCF_REG08(0xFC048047+((x)*0x4000))
+#define MCF_INTC_ICR8(x)           MCF_REG08(0xFC048048+((x)*0x4000))
+#define MCF_INTC_ICR9(x)           MCF_REG08(0xFC048049+((x)*0x4000))
+#define MCF_INTC_ICR10(x)          MCF_REG08(0xFC04804A+((x)*0x4000))
+#define MCF_INTC_ICR11(x)          MCF_REG08(0xFC04804B+((x)*0x4000))
+#define MCF_INTC_ICR12(x)          MCF_REG08(0xFC04804C+((x)*0x4000))
+#define MCF_INTC_ICR13(x)          MCF_REG08(0xFC04804D+((x)*0x4000))
+#define MCF_INTC_ICR14(x)          MCF_REG08(0xFC04804E+((x)*0x4000))
+#define MCF_INTC_ICR15(x)          MCF_REG08(0xFC04804F+((x)*0x4000))
+#define MCF_INTC_ICR16(x)          MCF_REG08(0xFC048050+((x)*0x4000))
+#define MCF_INTC_ICR17(x)          MCF_REG08(0xFC048051+((x)*0x4000))
+#define MCF_INTC_ICR18(x)          MCF_REG08(0xFC048052+((x)*0x4000))
+#define MCF_INTC_ICR19(x)          MCF_REG08(0xFC048053+((x)*0x4000))
+#define MCF_INTC_ICR20(x)          MCF_REG08(0xFC048054+((x)*0x4000))
+#define MCF_INTC_ICR21(x)          MCF_REG08(0xFC048055+((x)*0x4000))
+#define MCF_INTC_ICR22(x)          MCF_REG08(0xFC048056+((x)*0x4000))
+#define MCF_INTC_ICR23(x)          MCF_REG08(0xFC048057+((x)*0x4000))
+#define MCF_INTC_ICR24(x)          MCF_REG08(0xFC048058+((x)*0x4000))
+#define MCF_INTC_ICR25(x)          MCF_REG08(0xFC048059+((x)*0x4000))
+#define MCF_INTC_ICR26(x)          MCF_REG08(0xFC04805A+((x)*0x4000))
+#define MCF_INTC_ICR27(x)          MCF_REG08(0xFC04805B+((x)*0x4000))
+#define MCF_INTC_ICR28(x)          MCF_REG08(0xFC04805C+((x)*0x4000))
+#define MCF_INTC_ICR29(x)          MCF_REG08(0xFC04805D+((x)*0x4000))
+#define MCF_INTC_ICR30(x)          MCF_REG08(0xFC04805E+((x)*0x4000))
+#define MCF_INTC_ICR31(x)          MCF_REG08(0xFC04805F+((x)*0x4000))
+#define MCF_INTC_ICR32(x)          MCF_REG08(0xFC048060+((x)*0x4000))
+#define MCF_INTC_ICR33(x)          MCF_REG08(0xFC048061+((x)*0x4000))
+#define MCF_INTC_ICR34(x)          MCF_REG08(0xFC048062+((x)*0x4000))
+#define MCF_INTC_ICR35(x)          MCF_REG08(0xFC048063+((x)*0x4000))
+#define MCF_INTC_ICR36(x)          MCF_REG08(0xFC048064+((x)*0x4000))
+#define MCF_INTC_ICR37(x)          MCF_REG08(0xFC048065+((x)*0x4000))
+#define MCF_INTC_ICR38(x)          MCF_REG08(0xFC048066+((x)*0x4000))
+#define MCF_INTC_ICR39(x)          MCF_REG08(0xFC048067+((x)*0x4000))
+#define MCF_INTC_ICR40(x)          MCF_REG08(0xFC048068+((x)*0x4000))
+#define MCF_INTC_ICR41(x)          MCF_REG08(0xFC048069+((x)*0x4000))
+#define MCF_INTC_ICR42(x)          MCF_REG08(0xFC04806A+((x)*0x4000))
+#define MCF_INTC_ICR43(x)          MCF_REG08(0xFC04806B+((x)*0x4000))
+#define MCF_INTC_ICR44(x)          MCF_REG08(0xFC04806C+((x)*0x4000))
+#define MCF_INTC_ICR45(x)          MCF_REG08(0xFC04806D+((x)*0x4000))
+#define MCF_INTC_ICR46(x)          MCF_REG08(0xFC04806E+((x)*0x4000))
+#define MCF_INTC_ICR47(x)          MCF_REG08(0xFC04806F+((x)*0x4000))
+#define MCF_INTC_ICR48(x)          MCF_REG08(0xFC048070+((x)*0x4000))
+#define MCF_INTC_ICR49(x)          MCF_REG08(0xFC048071+((x)*0x4000))
+#define MCF_INTC_ICR50(x)          MCF_REG08(0xFC048072+((x)*0x4000))
+#define MCF_INTC_ICR51(x)          MCF_REG08(0xFC048073+((x)*0x4000))
+#define MCF_INTC_ICR52(x)          MCF_REG08(0xFC048074+((x)*0x4000))
+#define MCF_INTC_ICR53(x)          MCF_REG08(0xFC048075+((x)*0x4000))
+#define MCF_INTC_ICR54(x)          MCF_REG08(0xFC048076+((x)*0x4000))
+#define MCF_INTC_ICR55(x)          MCF_REG08(0xFC048077+((x)*0x4000))
+#define MCF_INTC_ICR56(x)          MCF_REG08(0xFC048078+((x)*0x4000))
+#define MCF_INTC_ICR57(x)          MCF_REG08(0xFC048079+((x)*0x4000))
+#define MCF_INTC_ICR58(x)          MCF_REG08(0xFC04807A+((x)*0x4000))
+#define MCF_INTC_ICR59(x)          MCF_REG08(0xFC04807B+((x)*0x4000))
+#define MCF_INTC_ICR60(x)          MCF_REG08(0xFC04807C+((x)*0x4000))
+#define MCF_INTC_ICR61(x)          MCF_REG08(0xFC04807D+((x)*0x4000))
+#define MCF_INTC_ICR62(x)          MCF_REG08(0xFC04807E+((x)*0x4000))
+#define MCF_INTC_ICR63(x)          MCF_REG08(0xFC04807F+((x)*0x4000))
+#define MCF_INTC_SWIACK(x)         MCF_REG08(0xFC0480E0+((x)*0x4000))
+#define MCF_INTC_L1IACK(x)         MCF_REG08(0xFC0480E4+((x)*0x4000))
+#define MCF_INTC_L2IACK(x)         MCF_REG08(0xFC0480E8+((x)*0x4000))
+#define MCF_INTC_L3IACK(x)         MCF_REG08(0xFC0480EC+((x)*0x4000))
+#define MCF_INTC_L4IACK(x)         MCF_REG08(0xFC0480F0+((x)*0x4000))
+#define MCF_INTC_L5IACK(x)         MCF_REG08(0xFC0480F4+((x)*0x4000))
+#define MCF_INTC_L6IACK(x)         MCF_REG08(0xFC0480F8+((x)*0x4000))
+#define MCF_INTC_L7IACK(x)         MCF_REG08(0xFC0480FC+((x)*0x4000))
+
+/* Bit definitions and macros for MCF_INTC_IPRH */
+#define MCF_INTC_IPRH_INT32        (0x00000001)
+#define MCF_INTC_IPRH_INT33        (0x00000002)
+#define MCF_INTC_IPRH_INT34        (0x00000004)
+#define MCF_INTC_IPRH_INT35        (0x00000008)
+#define MCF_INTC_IPRH_INT36        (0x00000010)
+#define MCF_INTC_IPRH_INT37        (0x00000020)
+#define MCF_INTC_IPRH_INT38        (0x00000040)
+#define MCF_INTC_IPRH_INT39        (0x00000080)
+#define MCF_INTC_IPRH_INT40        (0x00000100)
+#define MCF_INTC_IPRH_INT41        (0x00000200)
+#define MCF_INTC_IPRH_INT42        (0x00000400)
+#define MCF_INTC_IPRH_INT43        (0x00000800)
+#define MCF_INTC_IPRH_INT44        (0x00001000)
+#define MCF_INTC_IPRH_INT45        (0x00002000)
+#define MCF_INTC_IPRH_INT46        (0x00004000)
+#define MCF_INTC_IPRH_INT47        (0x00008000)
+#define MCF_INTC_IPRH_INT48        (0x00010000)
+#define MCF_INTC_IPRH_INT49        (0x00020000)
+#define MCF_INTC_IPRH_INT50        (0x00040000)
+#define MCF_INTC_IPRH_INT51        (0x00080000)
+#define MCF_INTC_IPRH_INT52        (0x00100000)
+#define MCF_INTC_IPRH_INT53        (0x00200000)
+#define MCF_INTC_IPRH_INT54        (0x00400000)
+#define MCF_INTC_IPRH_INT55        (0x00800000)
+#define MCF_INTC_IPRH_INT56        (0x01000000)
+#define MCF_INTC_IPRH_INT57        (0x02000000)
+#define MCF_INTC_IPRH_INT58        (0x04000000)
+#define MCF_INTC_IPRH_INT59        (0x08000000)
+#define MCF_INTC_IPRH_INT60        (0x10000000)
+#define MCF_INTC_IPRH_INT61        (0x20000000)
+#define MCF_INTC_IPRH_INT62        (0x40000000)
+#define MCF_INTC_IPRH_INT63        (0x80000000)
+
+/* Bit definitions and macros for MCF_INTC_IPRL */
+#define MCF_INTC_IPRL_INT0         (0x00000001)
+#define MCF_INTC_IPRL_INT1         (0x00000002)
+#define MCF_INTC_IPRL_INT2         (0x00000004)
+#define MCF_INTC_IPRL_INT3         (0x00000008)
+#define MCF_INTC_IPRL_INT4         (0x00000010)
+#define MCF_INTC_IPRL_INT5         (0x00000020)
+#define MCF_INTC_IPRL_INT6         (0x00000040)
+#define MCF_INTC_IPRL_INT7         (0x00000080)
+#define MCF_INTC_IPRL_INT8         (0x00000100)
+#define MCF_INTC_IPRL_INT9         (0x00000200)
+#define MCF_INTC_IPRL_INT10        (0x00000400)
+#define MCF_INTC_IPRL_INT11        (0x00000800)
+#define MCF_INTC_IPRL_INT12        (0x00001000)
+#define MCF_INTC_IPRL_INT13        (0x00002000)
+#define MCF_INTC_IPRL_INT14        (0x00004000)
+#define MCF_INTC_IPRL_INT15        (0x00008000)
+#define MCF_INTC_IPRL_INT16        (0x00010000)
+#define MCF_INTC_IPRL_INT17        (0x00020000)
+#define MCF_INTC_IPRL_INT18        (0x00040000)
+#define MCF_INTC_IPRL_INT19        (0x00080000)
+#define MCF_INTC_IPRL_INT20        (0x00100000)
+#define MCF_INTC_IPRL_INT21        (0x00200000)
+#define MCF_INTC_IPRL_INT22        (0x00400000)
+#define MCF_INTC_IPRL_INT23        (0x00800000)
+#define MCF_INTC_IPRL_INT24        (0x01000000)
+#define MCF_INTC_IPRL_INT25        (0x02000000)
+#define MCF_INTC_IPRL_INT26        (0x04000000)
+#define MCF_INTC_IPRL_INT27        (0x08000000)
+#define MCF_INTC_IPRL_INT28        (0x10000000)
+#define MCF_INTC_IPRL_INT29        (0x20000000)
+#define MCF_INTC_IPRL_INT30        (0x40000000)
+#define MCF_INTC_IPRL_INT31        (0x80000000)
+
+/* Bit definitions and macros for MCF_INTC_IMRH */
+#define MCF_INTC_IMRH_INT_MASK32   (0x00000001)
+#define MCF_INTC_IMRH_INT_MASK33   (0x00000002)
+#define MCF_INTC_IMRH_INT_MASK34   (0x00000004)
+#define MCF_INTC_IMRH_INT_MASK35   (0x00000008)
+#define MCF_INTC_IMRH_INT_MASK36   (0x00000010)
+#define MCF_INTC_IMRH_INT_MASK37   (0x00000020)
+#define MCF_INTC_IMRH_INT_MASK38   (0x00000040)
+#define MCF_INTC_IMRH_INT_MASK39   (0x00000080)
+#define MCF_INTC_IMRH_INT_MASK40   (0x00000100)
+#define MCF_INTC_IMRH_INT_MASK41   (0x00000200)
+#define MCF_INTC_IMRH_INT_MASK42   (0x00000400)
+#define MCF_INTC_IMRH_INT_MASK43   (0x00000800)
+#define MCF_INTC_IMRH_INT_MASK44   (0x00001000)
+#define MCF_INTC_IMRH_INT_MASK45   (0x00002000)
+#define MCF_INTC_IMRH_INT_MASK46   (0x00004000)
+#define MCF_INTC_IMRH_INT_MASK47   (0x00008000)
+#define MCF_INTC_IMRH_INT_MASK48   (0x00010000)
+#define MCF_INTC_IMRH_INT_MASK49   (0x00020000)
+#define MCF_INTC_IMRH_INT_MASK50   (0x00040000)
+#define MCF_INTC_IMRH_INT_MASK51   (0x00080000)
+#define MCF_INTC_IMRH_INT_MASK52   (0x00100000)
+#define MCF_INTC_IMRH_INT_MASK53   (0x00200000)
+#define MCF_INTC_IMRH_INT_MASK54   (0x00400000)
+#define MCF_INTC_IMRH_INT_MASK55   (0x00800000)
+#define MCF_INTC_IMRH_INT_MASK56   (0x01000000)
+#define MCF_INTC_IMRH_INT_MASK57   (0x02000000)
+#define MCF_INTC_IMRH_INT_MASK58   (0x04000000)
+#define MCF_INTC_IMRH_INT_MASK59   (0x08000000)
+#define MCF_INTC_IMRH_INT_MASK60   (0x10000000)
+#define MCF_INTC_IMRH_INT_MASK61   (0x20000000)
+#define MCF_INTC_IMRH_INT_MASK62   (0x40000000)
+#define MCF_INTC_IMRH_INT_MASK63   (0x80000000)
+
+/* Bit definitions and macros for MCF_INTC_IMRL */
+#define MCF_INTC_IMRL_INT_MASK0    (0x00000001)
+#define MCF_INTC_IMRL_INT_MASK1    (0x00000002)
+#define MCF_INTC_IMRL_INT_MASK2    (0x00000004)
+#define MCF_INTC_IMRL_INT_MASK3    (0x00000008)
+#define MCF_INTC_IMRL_INT_MASK4    (0x00000010)
+#define MCF_INTC_IMRL_INT_MASK5    (0x00000020)
+#define MCF_INTC_IMRL_INT_MASK6    (0x00000040)
+#define MCF_INTC_IMRL_INT_MASK7    (0x00000080)
+#define MCF_INTC_IMRL_INT_MASK8    (0x00000100)
+#define MCF_INTC_IMRL_INT_MASK9    (0x00000200)
+#define MCF_INTC_IMRL_INT_MASK10   (0x00000400)
+#define MCF_INTC_IMRL_INT_MASK11   (0x00000800)
+#define MCF_INTC_IMRL_INT_MASK12   (0x00001000)
+#define MCF_INTC_IMRL_INT_MASK13   (0x00002000)
+#define MCF_INTC_IMRL_INT_MASK14   (0x00004000)
+#define MCF_INTC_IMRL_INT_MASK15   (0x00008000)
+#define MCF_INTC_IMRL_INT_MASK16   (0x00010000)
+#define MCF_INTC_IMRL_INT_MASK17   (0x00020000)
+#define MCF_INTC_IMRL_INT_MASK18   (0x00040000)
+#define MCF_INTC_IMRL_INT_MASK19   (0x00080000)
+#define MCF_INTC_IMRL_INT_MASK20   (0x00100000)
+#define MCF_INTC_IMRL_INT_MASK21   (0x00200000)
+#define MCF_INTC_IMRL_INT_MASK22   (0x00400000)
+#define MCF_INTC_IMRL_INT_MASK23   (0x00800000)
+#define MCF_INTC_IMRL_INT_MASK24   (0x01000000)
+#define MCF_INTC_IMRL_INT_MASK25   (0x02000000)
+#define MCF_INTC_IMRL_INT_MASK26   (0x04000000)
+#define MCF_INTC_IMRL_INT_MASK27   (0x08000000)
+#define MCF_INTC_IMRL_INT_MASK28   (0x10000000)
+#define MCF_INTC_IMRL_INT_MASK29   (0x20000000)
+#define MCF_INTC_IMRL_INT_MASK30   (0x40000000)
+#define MCF_INTC_IMRL_INT_MASK31   (0x80000000)
+
+/* Bit definitions and macros for MCF_INTC_INTFRCH */
+#define MCF_INTC_INTFRCH_INTFRC32  (0x00000001)
+#define MCF_INTC_INTFRCH_INTFRC33  (0x00000002)
+#define MCF_INTC_INTFRCH_INTFRC34  (0x00000004)
+#define MCF_INTC_INTFRCH_INTFRC35  (0x00000008)
+#define MCF_INTC_INTFRCH_INTFRC36  (0x00000010)
+#define MCF_INTC_INTFRCH_INTFRC37  (0x00000020)
+#define MCF_INTC_INTFRCH_INTFRC38  (0x00000040)
+#define MCF_INTC_INTFRCH_INTFRC39  (0x00000080)
+#define MCF_INTC_INTFRCH_INTFRC40  (0x00000100)
+#define MCF_INTC_INTFRCH_INTFRC41  (0x00000200)
+#define MCF_INTC_INTFRCH_INTFRC42  (0x00000400)
+#define MCF_INTC_INTFRCH_INTFRC43  (0x00000800)
+#define MCF_INTC_INTFRCH_INTFRC44  (0x00001000)
+#define MCF_INTC_INTFRCH_INTFRC45  (0x00002000)
+#define MCF_INTC_INTFRCH_INTFRC46  (0x00004000)
+#define MCF_INTC_INTFRCH_INTFRC47  (0x00008000)
+#define MCF_INTC_INTFRCH_INTFRC48  (0x00010000)
+#define MCF_INTC_INTFRCH_INTFRC49  (0x00020000)
+#define MCF_INTC_INTFRCH_INTFRC50  (0x00040000)
+#define MCF_INTC_INTFRCH_INTFRC51  (0x00080000)
+#define MCF_INTC_INTFRCH_INTFRC52  (0x00100000)
+#define MCF_INTC_INTFRCH_INTFRC53  (0x00200000)
+#define MCF_INTC_INTFRCH_INTFRC54  (0x00400000)
+#define MCF_INTC_INTFRCH_INTFRC55  (0x00800000)
+#define MCF_INTC_INTFRCH_INTFRC56  (0x01000000)
+#define MCF_INTC_INTFRCH_INTFRC57  (0x02000000)
+#define MCF_INTC_INTFRCH_INTFRC58  (0x04000000)
+#define MCF_INTC_INTFRCH_INTFRC59  (0x08000000)
+#define MCF_INTC_INTFRCH_INTFRC60  (0x10000000)
+#define MCF_INTC_INTFRCH_INTFRC61  (0x20000000)
+#define MCF_INTC_INTFRCH_INTFRC62  (0x40000000)
+#define MCF_INTC_INTFRCH_INTFRC63  (0x80000000)
+
+/* Bit definitions and macros for MCF_INTC_INTFRCL */
+#define MCF_INTC_INTFRCL_INTFRC0   (0x00000001)
+#define MCF_INTC_INTFRCL_INTFRC1   (0x00000002)
+#define MCF_INTC_INTFRCL_INTFRC2   (0x00000004)
+#define MCF_INTC_INTFRCL_INTFRC3   (0x00000008)
+#define MCF_INTC_INTFRCL_INTFRC4   (0x00000010)
+#define MCF_INTC_INTFRCL_INTFRC5   (0x00000020)
+#define MCF_INTC_INTFRCL_INTFRC6   (0x00000040)
+#define MCF_INTC_INTFRCL_INTFRC7   (0x00000080)
+#define MCF_INTC_INTFRCL_INTFRC8   (0x00000100)
+#define MCF_INTC_INTFRCL_INTFRC9   (0x00000200)
+#define MCF_INTC_INTFRCL_INTFRC10  (0x00000400)
+#define MCF_INTC_INTFRCL_INTFRC11  (0x00000800)
+#define MCF_INTC_INTFRCL_INTFRC12  (0x00001000)
+#define MCF_INTC_INTFRCL_INTFRC13  (0x00002000)
+#define MCF_INTC_INTFRCL_INTFRC14  (0x00004000)
+#define MCF_INTC_INTFRCL_INTFRC15  (0x00008000)
+#define MCF_INTC_INTFRCL_INTFRC16  (0x00010000)
+#define MCF_INTC_INTFRCL_INTFRC17  (0x00020000)
+#define MCF_INTC_INTFRCL_INTFRC18  (0x00040000)
+#define MCF_INTC_INTFRCL_INTFRC19  (0x00080000)
+#define MCF_INTC_INTFRCL_INTFRC20  (0x00100000)
+#define MCF_INTC_INTFRCL_INTFRC21  (0x00200000)
+#define MCF_INTC_INTFRCL_INTFRC22  (0x00400000)
+#define MCF_INTC_INTFRCL_INTFRC23  (0x00800000)
+#define MCF_INTC_INTFRCL_INTFRC24  (0x01000000)
+#define MCF_INTC_INTFRCL_INTFRC25  (0x02000000)
+#define MCF_INTC_INTFRCL_INTFRC26  (0x04000000)
+#define MCF_INTC_INTFRCL_INTFRC27  (0x08000000)
+#define MCF_INTC_INTFRCL_INTFRC28  (0x10000000)
+#define MCF_INTC_INTFRCL_INTFRC29  (0x20000000)
+#define MCF_INTC_INTFRCL_INTFRC30  (0x40000000)
+#define MCF_INTC_INTFRCL_INTFRC31  (0x80000000)
+
+/* Bit definitions and macros for MCF_INTC_ICONFIG */
+#define MCF_INTC_ICONFIG_EMASK     (0x0020)
+#define MCF_INTC_ICONFIG_ELVLPRI1  (0x0200)
+#define MCF_INTC_ICONFIG_ELVLPRI2  (0x0400)
+#define MCF_INTC_ICONFIG_ELVLPRI3  (0x0800)
+#define MCF_INTC_ICONFIG_ELVLPRI4  (0x1000)
+#define MCF_INTC_ICONFIG_ELVLPRI5  (0x2000)
+#define MCF_INTC_ICONFIG_ELVLPRI6  (0x4000)
+#define MCF_INTC_ICONFIG_ELVLPRI7  (0x8000)
+
+/* Bit definitions and macros for MCF_INTC_SIMR */
+#define MCF_INTC_SIMR_SIMR(x)      (((x)&0x7F)<<0)
+
+/* Bit definitions and macros for MCF_INTC_CIMR */
+#define MCF_INTC_CIMR_CIMR(x)      (((x)&0x7F)<<0)
+
+/* Bit definitions and macros for MCF_INTC_CLMASK */
+#define MCF_INTC_CLMASK_CLMASK(x)  (((x)&0x0F)<<0)
+
+/* Bit definitions and macros for MCF_INTC_SLMASK */
+#define MCF_INTC_SLMASK_SLMASK(x)  (((x)&0x0F)<<0)
+
+/* Bit definitions and macros for MCF_INTC_ICR */
+#define MCF_INTC_ICR_IL(x)         (((x)&0x07)<<0)
+
+/* Bit definitions and macros for MCF_INTC_SWIACK */
+#define MCF_INTC_SWIACK_VECTOR(x)  (((x)&0xFF)<<0)
+
+/* Bit definitions and macros for MCF_INTC_LIACK */
+#define MCF_INTC_LIACK_VECTOR(x)   (((x)&0xFF)<<0)
+
+/********************************************************************/
+/*********************************************************************
+*
+* LCD Controller (LCDC)
+*
+*********************************************************************/
+
+/* Register read/write macros */
+#define MCF_LCDC_LSSAR                  MCF_REG32(0xFC0AC000)
+#define MCF_LCDC_LSR                    MCF_REG32(0xFC0AC004)
+#define MCF_LCDC_LVPWR                  MCF_REG32(0xFC0AC008)
+#define MCF_LCDC_LCPR                   MCF_REG32(0xFC0AC00C)
+#define MCF_LCDC_LCWHBR                 MCF_REG32(0xFC0AC010)
+#define MCF_LCDC_LCCMR                  MCF_REG32(0xFC0AC014)
+#define MCF_LCDC_LPCR                   MCF_REG32(0xFC0AC018)
+#define MCF_LCDC_LHCR                   MCF_REG32(0xFC0AC01C)
+#define MCF_LCDC_LVCR                   MCF_REG32(0xFC0AC020)
+#define MCF_LCDC_LPOR                   MCF_REG32(0xFC0AC024)
+#define MCF_LCDC_LSCR                   MCF_REG32(0xFC0AC028)
+#define MCF_LCDC_LPCCR                  MCF_REG32(0xFC0AC02C)
+#define MCF_LCDC_LDCR                   MCF_REG32(0xFC0AC030)
+#define MCF_LCDC_LRMCR                  MCF_REG32(0xFC0AC034)
+#define MCF_LCDC_LICR                   MCF_REG32(0xFC0AC038)
+#define MCF_LCDC_LIER                   MCF_REG32(0xFC0AC03C)
+#define MCF_LCDC_LISR                   MCF_REG32(0xFC0AC040)
+#define MCF_LCDC_LGWSAR                 MCF_REG32(0xFC0AC050)
+#define MCF_LCDC_LGWSR                  MCF_REG32(0xFC0AC054)
+#define MCF_LCDC_LGWVPWR                MCF_REG32(0xFC0AC058)
+#define MCF_LCDC_LGWPOR                 MCF_REG32(0xFC0AC05C)
+#define MCF_LCDC_LGWPR                  MCF_REG32(0xFC0AC060)
+#define MCF_LCDC_LGWCR                  MCF_REG32(0xFC0AC064)
+#define MCF_LCDC_LGWDCR                 MCF_REG32(0xFC0AC068)
+#define MCF_LCDC_BPLUT_BASE             MCF_REG32(0xFC0AC800)
+#define MCF_LCDC_GWLUT_BASE             MCF_REG32(0xFC0ACC00)
+
+/* Bit definitions and macros for MCF_LCDC_LSSAR */
+#define MCF_LCDC_LSSAR_SSA(x)           (((x)&0x3FFFFFFF)<<2)
+
+/* Bit definitions and macros for MCF_LCDC_LSR */
+#define MCF_LCDC_LSR_YMAX(x)            (((x)&0x000003FF)<<0)
+#define MCF_LCDC_LSR_XMAX(x)            (((x)&0x0000003F)<<20)
+
+/* Bit definitions and macros for MCF_LCDC_LVPWR */
+#define MCF_LCDC_LVPWR_VPW(x)           (((x)&0x000003FF)<<0)
+
+/* Bit definitions and macros for MCF_LCDC_LCPR */
+#define MCF_LCDC_LCPR_CYP(x)            (((x)&0x000003FF)<<0)
+#define MCF_LCDC_LCPR_CXP(x)            (((x)&0x000003FF)<<16)
+#define MCF_LCDC_LCPR_OP                (0x10000000)
+#define MCF_LCDC_LCPR_CC(x)             (((x)&0x00000003)<<30)
+#define MCF_LCDC_LCPR_CC_TRANSPARENT    (0x00000000)
+#define MCF_LCDC_LCPR_CC_OR             (0x40000000)
+#define MCF_LCDC_LCPR_CC_XOR            (0x80000000)
+#define MCF_LCDC_LCPR_CC_AND            (0xC0000000)
+#define MCF_LCDC_LCPR_OP_ON             (0x10000000)
+#define MCF_LCDC_LCPR_OP_OFF            (0x00000000)
+
+/* Bit definitions and macros for MCF_LCDC_LCWHBR */
+#define MCF_LCDC_LCWHBR_BD(x)           (((x)&0x000000FF)<<0)
+#define MCF_LCDC_LCWHBR_CH(x)           (((x)&0x0000001F)<<16)
+#define MCF_LCDC_LCWHBR_CW(x)           (((x)&0x0000001F)<<24)
+#define MCF_LCDC_LCWHBR_BK_EN           (0x80000000)
+#define MCF_LCDC_LCWHBR_BK_EN_ON        (0x80000000)
+#define MCF_LCDC_LCWHBR_BK_EN_OFF       (0x00000000)
+
+/* Bit definitions and macros for MCF_LCDC_LCCMR */
+#define MCF_LCDC_LCCMR_CUR_COL_B(x)     (((x)&0x0000003F)<<0)
+#define MCF_LCDC_LCCMR_CUR_COL_G(x)     (((x)&0x0000003F)<<6)
+#define MCF_LCDC_LCCMR_CUR_COL_R(x)     (((x)&0x0000003F)<<12)
+
+/* Bit definitions and macros for MCF_LCDC_LPCR */
+#define MCF_LCDC_LPCR_PCD(x)            (((x)&0x0000003F)<<0)
+#define MCF_LCDC_LPCR_SHARP             (0x00000040)
+#define MCF_LCDC_LPCR_SCLKSEL           (0x00000080)
+#define MCF_LCDC_LPCR_ACD(x)            (((x)&0x0000007F)<<8)
+#define MCF_LCDC_LPCR_ACDSEL            (0x00008000)
+#define MCF_LCDC_LPCR_REV_VS            (0x00010000)
+#define MCF_LCDC_LPCR_SWAP_SEL          (0x00020000)
+#define MCF_LCDC_LPCR_ENDSEL            (0x00040000)
+#define MCF_LCDC_LPCR_SCLKIDLE          (0x00080000)
+#define MCF_LCDC_LPCR_OEPOL             (0x00100000)
+#define MCF_LCDC_LPCR_CLKPOL            (0x00200000)
+#define MCF_LCDC_LPCR_LPPOL             (0x00400000)
+#define MCF_LCDC_LPCR_FLM               (0x00800000)
+#define MCF_LCDC_LPCR_PIXPOL            (0x01000000)
+#define MCF_LCDC_LPCR_BPIX(x)           (((x)&0x00000007)<<25)
+#define MCF_LCDC_LPCR_PBSIZ(x)          (((x)&0x00000003)<<28)
+#define MCF_LCDC_LPCR_COLOR             (0x40000000)
+#define MCF_LCDC_LPCR_TFT               (0x80000000)
+#define MCF_LCDC_LPCR_MODE_MONOCGROME   (0x00000000)
+#define MCF_LCDC_LPCR_MODE_CSTN         (0x40000000)
+#define MCF_LCDC_LPCR_MODE_TFT          (0xC0000000)
+#define MCF_LCDC_LPCR_PBSIZ_1           (0x00000000)
+#define MCF_LCDC_LPCR_PBSIZ_2           (0x10000000)
+#define MCF_LCDC_LPCR_PBSIZ_4           (0x20000000)
+#define MCF_LCDC_LPCR_PBSIZ_8           (0x30000000)
+#define MCF_LCDC_LPCR_BPIX_1bpp         (0x00000000)
+#define MCF_LCDC_LPCR_BPIX_2bpp         (0x02000000)
+#define MCF_LCDC_LPCR_BPIX_4bpp         (0x04000000)
+#define MCF_LCDC_LPCR_BPIX_8bpp         (0x06000000)
+#define MCF_LCDC_LPCR_BPIX_12bpp        (0x08000000)
+#define MCF_LCDC_LPCR_BPIX_16bpp        (0x0A000000)
+#define MCF_LCDC_LPCR_BPIX_18bpp        (0x0C000000)
+
+#define MCF_LCDC_LPCR_PANEL_TYPE(x)     (((x)&0x00000003)<<30) 
+
+/* Bit definitions and macros for MCF_LCDC_LHCR */
+#define MCF_LCDC_LHCR_H_WAIT_2(x)       (((x)&0x000000FF)<<0)
+#define MCF_LCDC_LHCR_H_WAIT_1(x)       (((x)&0x000000FF)<<8)
+#define MCF_LCDC_LHCR_H_WIDTH(x)        (((x)&0x0000003F)<<26)
+
+/* Bit definitions and macros for MCF_LCDC_LVCR */
+#define MCF_LCDC_LVCR_V_WAIT_2(x)       (((x)&0x000000FF)<<0)
+#define MCF_LCDC_LVCR_V_WAIT_1(x)       (((x)&0x000000FF)<<8)
+#define MCF_LCDC_LVCR_V_WIDTH(x)      (((x)&0x0000003F)<<26)
+
+/* Bit definitions and macros for MCF_LCDC_LPOR */
+#define MCF_LCDC_LPOR_POS(x)            (((x)&0x0000001F)<<0)
+
+/* Bit definitions and macros for MCF_LCDC_LPCCR */
+#define MCF_LCDC_LPCCR_PW(x)            (((x)&0x000000FF)<<0)
+#define MCF_LCDC_LPCCR_CC_EN            (0x00000100)
+#define MCF_LCDC_LPCCR_SCR(x)           (((x)&0x00000003)<<9)
+#define MCF_LCDC_LPCCR_LDMSK            (0x00008000)
+#define MCF_LCDC_LPCCR_CLS_HI_WIDTH(x)  (((x)&0x000001FF)<<16)
+#define MCF_LCDC_LPCCR_SCR_LINEPULSE    (0x00000000)
+#define MCF_LCDC_LPCCR_SCR_PIXELCLK     (0x00002000)
+#define MCF_LCDC_LPCCR_SCR_LCDCLOCK     (0x00004000)
+
+/* Bit definitions and macros for MCF_LCDC_LDCR */
+#define MCF_LCDC_LDCR_TM(x)             (((x)&0x0000001F)<<0)
+#define MCF_LCDC_LDCR_HM(x)             (((x)&0x0000001F)<<16)
+#define MCF_LCDC_LDCR_BURST             (0x80000000)
+
+/* Bit definitions and macros for MCF_LCDC_LRMCR */
+#define MCF_LCDC_LRMCR_SEL_REF          (0x00000001)
+
+/* Bit definitions and macros for MCF_LCDC_LICR */
+#define MCF_LCDC_LICR_INTCON            (0x00000001)
+#define MCF_LCDC_LICR_INTSYN            (0x00000004)
+#define MCF_LCDC_LICR_GW_INT_CON        (0x00000010)
+
+/* Bit definitions and macros for MCF_LCDC_LIER */
+#define MCF_LCDC_LIER_BOF_EN            (0x00000001)
+#define MCF_LCDC_LIER_EOF_EN            (0x00000002)
+#define MCF_LCDC_LIER_ERR_RES_EN        (0x00000004)
+#define MCF_LCDC_LIER_UDR_ERR_EN        (0x00000008)
+#define MCF_LCDC_LIER_GW_BOF_EN         (0x00000010)
+#define MCF_LCDC_LIER_GW_EOF_EN         (0x00000020)
+#define MCF_LCDC_LIER_GW_ERR_RES_EN     (0x00000040)
+#define MCF_LCDC_LIER_GW_UDR_ERR_EN     (0x00000080)
+
+/* Bit definitions and macros for MCF_LCDC_LISR */
+#define MCF_LCDC_LISR_BOF               (0x00000001)
+#define MCF_LCDC_LISR_EOF               (0x00000002)
+#define MCF_LCDC_LISR_ERR_RES           (0x00000004)
+#define MCF_LCDC_LISR_UDR_ERR           (0x00000008)
+#define MCF_LCDC_LISR_GW_BOF            (0x00000010)
+#define MCF_LCDC_LISR_GW_EOF            (0x00000020)
+#define MCF_LCDC_LISR_GW_ERR_RES        (0x00000040)
+#define MCF_LCDC_LISR_GW_UDR_ERR        (0x00000080)
+
+/* Bit definitions and macros for MCF_LCDC_LGWSAR */
+#define MCF_LCDC_LGWSAR_GWSA(x)         (((x)&0x3FFFFFFF)<<2)
+
+/* Bit definitions and macros for MCF_LCDC_LGWSR */
+#define MCF_LCDC_LGWSR_GWH(x)           (((x)&0x000003FF)<<0)
+#define MCF_LCDC_LGWSR_GWW(x)           (((x)&0x0000003F)<<20)
+
+/* Bit definitions and macros for MCF_LCDC_LGWVPWR */
+#define MCF_LCDC_LGWVPWR_GWVPW(x)       (((x)&0x000003FF)<<0)
+
+/* Bit definitions and macros for MCF_LCDC_LGWPOR */
+#define MCF_LCDC_LGWPOR_GWPO(x)         (((x)&0x0000001F)<<0)
+
+/* Bit definitions and macros for MCF_LCDC_LGWPR */
+#define MCF_LCDC_LGWPR_GWYP(x)          (((x)&0x000003FF)<<0)
+#define MCF_LCDC_LGWPR_GWXP(x)          (((x)&0x000003FF)<<16)
+
+/* Bit definitions and macros for MCF_LCDC_LGWCR */
+#define MCF_LCDC_LGWCR_GWCKB(x)         (((x)&0x0000003F)<<0)
+#define MCF_LCDC_LGWCR_GWCKG(x)         (((x)&0x0000003F)<<6)
+#define MCF_LCDC_LGWCR_GWCKR(x)         (((x)&0x0000003F)<<12)
+#define MCF_LCDC_LGWCR_GW_RVS           (0x00200000)
+#define MCF_LCDC_LGWCR_GWE              (0x00400000)
+#define MCF_LCDC_LGWCR_GWCKE            (0x00800000)
+#define MCF_LCDC_LGWCR_GWAV(x)          (((x)&0x000000FF)<<24)
+
+/* Bit definitions and macros for MCF_LCDC_LGWDCR */
+#define MCF_LCDC_LGWDCR_GWTM(x)         (((x)&0x0000001F)<<0)
+#define MCF_LCDC_LGWDCR_GWHM(x)         (((x)&0x0000001F)<<16)
+#define MCF_LCDC_LGWDCR_GWBT            (0x80000000)
+
+/* Bit definitions and macros for MCF_LCDC_LSCR */
+#define MCF_LCDC_LSCR_PS_RISE_DELAY(x)    (((x)&0x0000003F)<<26)
+#define MCF_LCDC_LSCR_CLS_RISE_DELAY(x)   (((x)&0x000000FF)<<16)
+#define MCF_LCDC_LSCR_REV_TOGGLE_DELAY(x) (((x)&0x0000000F)<<8)
+#define MCF_LCDC_LSCR_GRAY_2(x)  		  (((x)&0x0000000F)<<4)
+#define MCF_LCDC_LSCR_GRAY_1(x)  		  (((x)&0x0000000F)<<0)
+
+/* Bit definitions and macros for MCF_LCDC_BPLUT_BASE */
+#define MCF_LCDC_BPLUT_BASE_BASE(x)     (((x)&0xFFFFFFFF)<<0)
+
+/* Bit definitions and macros for MCF_LCDC_GWLUT_BASE */
+#define MCF_LCDC_GWLUT_BASE_BASE(x)     (((x)&0xFFFFFFFF)<<0)
+
+/*********************************************************************
+ *
+ * Phase Locked Loop (PLL)
+ *
+ *********************************************************************/
+
+/* Register read/write macros */
+#define MCF_PLL_PODR              MCF_REG08(0xFC0C0000)
+#define MCF_PLL_PLLCR             MCF_REG08(0xFC0C0004)
+#define MCF_PLL_PMDR              MCF_REG08(0xFC0C0008)
+#define MCF_PLL_PFDR              MCF_REG08(0xFC0C000C)
+
+/* Bit definitions and macros for MCF_PLL_PODR */
+#define MCF_PLL_PODR_BUSDIV(x)    (((x)&0x0F)<<0)
+#define MCF_PLL_PODR_CPUDIV(x)    (((x)&0x0F)<<4)
+
+/* Bit definitions and macros for MCF_PLL_PLLCR */
+#define MCF_PLL_PLLCR_DITHDEV(x)  (((x)&0x07)<<0)
+#define MCF_PLL_PLLCR_DITHEN      (0x80)
+
+/* Bit definitions and macros for MCF_PLL_PMDR */
+#define MCF_PLL_PMDR_MODDIV(x)    (((x)&0xFF)<<0)
+
+/* Bit definitions and macros for MCF_PLL_PFDR */
+#define MCF_PLL_PFDR_MFD(x)       (((x)&0xFF)<<0)
+
+/*********************************************************************
+ *
+ * System Control Module Registers (SCM)
+ *
+ *********************************************************************/
+
+/* Register read/write macros */
+#define MCF_SCM_MPR			MCF_REG32(0xFC000000)
+#define MCF_SCM_PACRA			MCF_REG32(0xFC000020)
+#define MCF_SCM_PACRB			MCF_REG32(0xFC000024)
+#define MCF_SCM_PACRC			MCF_REG32(0xFC000028)
+#define MCF_SCM_PACRD			MCF_REG32(0xFC00002C)
+#define MCF_SCM_PACRE			MCF_REG32(0xFC000040)
+#define MCF_SCM_PACRF			MCF_REG32(0xFC000044)
+
+#define MCF_SCM_BCR			MCF_REG32(0xFC040024)
+
+/*********************************************************************
+ *
+ * SDRAM Controller (SDRAMC)
+ *
+ *********************************************************************/
+
+/* Register read/write macros */
+#define MCF_SDRAMC_SDMR			MCF_REG32(0xFC0B8000)
+#define MCF_SDRAMC_SDCR			MCF_REG32(0xFC0B8004)
+#define MCF_SDRAMC_SDCFG1		MCF_REG32(0xFC0B8008)
+#define MCF_SDRAMC_SDCFG2		MCF_REG32(0xFC0B800C)
+#define MCF_SDRAMC_LIMP_FIX		MCF_REG32(0xFC0B8080)
+#define MCF_SDRAMC_SDDS			MCF_REG32(0xFC0B8100)
+#define MCF_SDRAMC_SDCS0		MCF_REG32(0xFC0B8110)
+#define MCF_SDRAMC_SDCS1		MCF_REG32(0xFC0B8114)
+#define MCF_SDRAMC_SDCS2		MCF_REG32(0xFC0B8118)
+#define MCF_SDRAMC_SDCS3		MCF_REG32(0xFC0B811C)
+#define MCF_SDRAMC_SDCS(x)		MCF_REG32(0xFC0B8110+((x)*0x004))
+
+/* Bit definitions and macros for MCF_SDRAMC_SDMR */
+#define MCF_SDRAMC_SDMR_CMD		(0x00010000)
+#define MCF_SDRAMC_SDMR_AD(x)		(((x)&0x00000FFF)<<18)
+#define MCF_SDRAMC_SDMR_BNKAD(x)	(((x)&0x00000003)<<30)
+#define MCF_SDRAMC_SDMR_BNKAD_LMR	(0x00000000)
+#define MCF_SDRAMC_SDMR_BNKAD_LEMR	(0x40000000)
+
+/* Bit definitions and macros for MCF_SDRAMC_SDCR */
+#define MCF_SDRAMC_SDCR_IPALL		(0x00000002)
+#define MCF_SDRAMC_SDCR_IREF		(0x00000004)
+#define MCF_SDRAMC_SDCR_DQS_OE(x)	(((x)&0x0000000F)<<8)
+#define MCF_SDRAMC_SDCR_PS(x)		(((x)&0x00000003)<<12)
+#define MCF_SDRAMC_SDCR_RCNT(x)		(((x)&0x0000003F)<<16)
+#define MCF_SDRAMC_SDCR_OE_RULE		(0x00400000)
+#define MCF_SDRAMC_SDCR_MUX(x)		(((x)&0x00000003)<<24)
+#define MCF_SDRAMC_SDCR_REF		(0x10000000)
+#define MCF_SDRAMC_SDCR_DDR		(0x20000000)
+#define MCF_SDRAMC_SDCR_CKE		(0x40000000)
+#define MCF_SDRAMC_SDCR_MODE_EN		(0x80000000)
+#define MCF_SDRAMC_SDCR_PS_16		(0x00002000)
+#define MCF_SDRAMC_SDCR_PS_32		(0x00000000)
+
+/* Bit definitions and macros for MCF_SDRAMC_SDCFG1 */
+#define MCF_SDRAMC_SDCFG1_WTLAT(x)	(((x)&0x00000007)<<4)
+#define MCF_SDRAMC_SDCFG1_REF2ACT(x)	(((x)&0x0000000F)<<8)
+#define MCF_SDRAMC_SDCFG1_PRE2ACT(x)	(((x)&0x00000007)<<12)
+#define MCF_SDRAMC_SDCFG1_ACT2RW(x)	(((x)&0x00000007)<<16)
+#define MCF_SDRAMC_SDCFG1_RDLAT(x)	(((x)&0x0000000F)<<20)
+#define MCF_SDRAMC_SDCFG1_SWT2RD(x)	(((x)&0x00000007)<<24)
+#define MCF_SDRAMC_SDCFG1_SRD2RW(x)	(((x)&0x0000000F)<<28)
+
+/* Bit definitions and macros for MCF_SDRAMC_SDCFG2 */
+#define MCF_SDRAMC_SDCFG2_BL(x)		(((x)&0x0000000F)<<16)
+#define MCF_SDRAMC_SDCFG2_BRD2WT(x)	(((x)&0x0000000F)<<20)
+#define MCF_SDRAMC_SDCFG2_BWT2RW(x)	(((x)&0x0000000F)<<24)
+#define MCF_SDRAMC_SDCFG2_BRD2PRE(x)	(((x)&0x0000000F)<<28)
+
+/* Device Errata - LIMP mode work around */
+#define MCF_SDRAMC_REFRESH		(0x40000000)
+
+/* Bit definitions and macros for MCF_SDRAMC_SDDS */
+#define MCF_SDRAMC_SDDS_SB_D(x)		(((x)&0x00000003)<<0)
+#define MCF_SDRAMC_SDDS_SB_S(x)		(((x)&0x00000003)<<2)
+#define MCF_SDRAMC_SDDS_SB_A(x)		(((x)&0x00000003)<<4)
+#define MCF_SDRAMC_SDDS_SB_C(x)		(((x)&0x00000003)<<6)
+#define MCF_SDRAMC_SDDS_SB_E(x)		(((x)&0x00000003)<<8)
+
+/* Bit definitions and macros for MCF_SDRAMC_SDCS */
+#define MCF_SDRAMC_SDCS_CSSZ(x)		(((x)&0x0000001F)<<0)
+#define MCF_SDRAMC_SDCS_BASE(x)		(((x)&0x00000FFF)<<20)
+#define MCF_SDRAMC_SDCS_BA(x)		((x)&0xFFF00000)
+#define MCF_SDRAMC_SDCS_CSSZ_DIABLE	(0x00000000)
+#define MCF_SDRAMC_SDCS_CSSZ_1MBYTE	(0x00000013)
+#define MCF_SDRAMC_SDCS_CSSZ_2MBYTE	(0x00000014)
+#define MCF_SDRAMC_SDCS_CSSZ_4MBYTE	(0x00000015)
+#define MCF_SDRAMC_SDCS_CSSZ_8MBYTE	(0x00000016)
+#define MCF_SDRAMC_SDCS_CSSZ_16MBYTE	(0x00000017)
+#define MCF_SDRAMC_SDCS_CSSZ_32MBYTE	(0x00000018)
+#define MCF_SDRAMC_SDCS_CSSZ_64MBYTE	(0x00000019)
+#define MCF_SDRAMC_SDCS_CSSZ_128MBYTE	(0x0000001A)
+#define MCF_SDRAMC_SDCS_CSSZ_256MBYTE	(0x0000001B)
+#define MCF_SDRAMC_SDCS_CSSZ_512MBYTE	(0x0000001C)
+#define MCF_SDRAMC_SDCS_CSSZ_1GBYTE	(0x0000001D)
+#define MCF_SDRAMC_SDCS_CSSZ_2GBYTE	(0x0000001E)
+#define MCF_SDRAMC_SDCS_CSSZ_4GBYTE	(0x0000001F)
+
+/*********************************************************************
+ *
+ *      FlexCAN module registers
+ *
+ *********************************************************************/
+#define MCF_FLEXCAN_BASEADDR(x)		(0xFC020000+(x)*0x0800)
+#define MCF_FLEXCAN_CANMCR(x)		MCF_REG32(0xFC020000+(x)*0x0800+0x00)
+#define MCF_FLEXCAN_CANCTRL(x)		MCF_REG32(0xFC020000+(x)*0x0800+0x04)
+#define MCF_FLEXCAN_TIMER(x)		MCF_REG32(0xFC020000+(x)*0x0800+0x08)
+#define MCF_FLEXCAN_RXGMASK(x)		MCF_REG32(0xFC020000+(x)*0x0800+0x10)
+#define MCF_FLEXCAN_RX14MASK(x)		MCF_REG32(0xFC020000+(x)*0x0800+0x14)
+#define MCF_FLEXCAN_RX15MASK(x)		MCF_REG32(0xFC020000+(x)*0x0800+0x18)
+#define MCF_FLEXCAN_ERRCNT(x)		MCF_REG32(0xFC020000+(x)*0x0800+0x1C)
+#define MCF_FLEXCAN_ERRSTAT(x)		MCF_REG32(0xFC020000+(x)*0x0800+0x20)
+#define MCF_FLEXCAN_IMASK(x)		MCF_REG32(0xFC020000+(x)*0x0800+0x28)
+#define MCF_FLEXCAN_IFLAG(x)		MCF_REG32(0xFC020000+(x)*0x0800+0x30)
+
+#define MCF_FLEXCAN_MB_CNT(x,y)		MCF_REG32(0xFC020080+(x)*0x0800+(y)*0x10+0x0)
+#define MCF_FLEXCAN_MB_ID(x,y)		MCF_REG32(0xFC020080+(x)*0x0800+(y)*0x10+0x4)
+#define MCF_FLEXCAN_MB_DB(x,y,z)	MCF_REG08(0xFC020080+(x)*0x0800+(y)*0x10+0x8+(z)*0x1)
+
+/*
+ *      FlexCAN Module Configuration Register
+ */
+#define CANMCR_MDIS		(0x80000000)
+#define CANMCR_FRZ		(0x40000000)
+#define CANMCR_HALT		(0x10000000)
+#define CANMCR_SOFTRST		(0x02000000)
+#define CANMCR_FRZACK		(0x01000000)
+#define CANMCR_SUPV		(0x00800000)
+#define CANMCR_MAXMB(x)         ((x)&0x0F)
+
+/*
+ *      FlexCAN Control Register
+ */
+#define CANCTRL_PRESDIV(x)      (((x)&0xFF)<<24)
+#define CANCTRL_RJW(x)          (((x)&0x03)<<22)
+#define CANCTRL_PSEG1(x)        (((x)&0x07)<<19)
+#define CANCTRL_PSEG2(x)        (((x)&0x07)<<16)
+#define CANCTRL_BOFFMSK         (0x00008000)
+#define CANCTRL_ERRMSK	        (0x00004000)
+#define CANCTRL_CLKSRC		(0x00002000)
+#define CANCTRL_LPB	        (0x00001000)
+#define CANCTRL_SAMP	        (0x00000080)
+#define CANCTRL_BOFFREC         (0x00000040)
+#define CANCTRL_TSYNC           (0x00000020)
+#define CANCTRL_LBUF            (0x00000010)
+#define CANCTRL_LOM             (0x00000008)
+#define CANCTRL_PROPSEG(x)      ((x)&0x07)
+
+/*
+ *      FlexCAN Error Counter Register
+ */
+#define ERRCNT_RXECTR(x)        (((x)&0xFF)<<8)
+#define ERRCNT_TXECTR(x)        ((x)&0xFF)
+
+/*
+ *      FlexCAN Error and Status Register
+ */
+#define ERRSTAT_BITERR(x)       (((x)&0x03)<<14)
+#define ERRSTAT_ACKERR           (0x00002000)
+#define ERRSTAT_CRCERR           (0x00001000)
+#define ERRSTAT_FRMERR           (0x00000800)
+#define ERRSTAT_STFERR           (0x00000400)
+#define ERRSTAT_TXWRN            (0x00000200)
+#define ERRSTAT_RXWRN            (0x00000100)
+#define ERRSTAT_IDLE             (0x00000080)
+#define ERRSTAT_TXRX             (0x00000040)
+#define ERRSTAT_FLTCONF(x)       (((x)&0x03)<<4)
+#define ERRSTAT_BOFFINT          (0x00000004)
+#define ERRSTAT_ERRINT           (0x00000002)
+
+/*
+ *      Interrupt Mask Register
+ */
+#define IMASK_BUF15M		(0x8000)
+#define IMASK_BUF14M		(0x4000)
+#define IMASK_BUF13M		(0x2000)
+#define IMASK_BUF12M		(0x1000)
+#define IMASK_BUF11M		(0x0800)
+#define IMASK_BUF10M		(0x0400)
+#define IMASK_BUF9M		(0x0200)
+#define IMASK_BUF8M		(0x0100)
+#define IMASK_BUF7M		(0x0080)
+#define IMASK_BUF6M		(0x0040)
+#define IMASK_BUF5M		(0x0020)
+#define IMASK_BUF4M		(0x0010)
+#define IMASK_BUF3M		(0x0008)
+#define IMASK_BUF2M		(0x0004)
+#define IMASK_BUF1M		(0x0002)
+#define IMASK_BUF0M		(0x0001)
+#define IMASK_BUFnM(x)		(0x1<<(x))
+#define IMASK_BUFF_ENABLE_ALL	(0x1111)
+#define IMASK_BUFF_DISABLE_ALL	(0x0000)
+
+/*
+ *      Interrupt Flag Register
+ */
+#define IFLAG_BUF15M		(0x8000)
+#define IFLAG_BUF14M		(0x4000)
+#define IFLAG_BUF13M		(0x2000)
+#define IFLAG_BUF12M		(0x1000)
+#define IFLAG_BUF11M		(0x0800)
+#define IFLAG_BUF10M		(0x0400)
+#define IFLAG_BUF9M		(0x0200)
+#define IFLAG_BUF8M		(0x0100)
+#define IFLAG_BUF7M		(0x0080)
+#define IFLAG_BUF6M		(0x0040)
+#define IFLAG_BUF5M		(0x0020)
+#define IFLAG_BUF4M		(0x0010)
+#define IFLAG_BUF3M		(0x0008)
+#define IFLAG_BUF2M		(0x0004)
+#define IFLAG_BUF1M		(0x0002)
+#define IFLAG_BUF0M		(0x0001)
+#define IFLAG_BUFF_SET_ALL	(0xFFFF)
+#define IFLAG_BUFF_CLEAR_ALL	(0x0000)
+#define IFLAG_BUFnM(x)		(0x1<<(x))
+
+/*
+ *      Message Buffers
+ */
+#define MB_CNT_CODE(x)		(((x)&0x0F)<<24)
+#define MB_CNT_SRR		(0x00400000)
+#define MB_CNT_IDE		(0x00200000)
+#define MB_CNT_RTR		(0x00100000)
+#define MB_CNT_LENGTH(x)	(((x)&0x0F)<<16)
+#define MB_CNT_TIMESTAMP(x)	((x)&0xFFFF)
+#define MB_ID_STD(x)		(((x)&0x07FF)<<18)
+#define MB_ID_EXT(x)		((x)&0x3FFFF)
+
+/*********************************************************************
+ *
+ * Edge Port Module (EPORT)
+ *
+ *********************************************************************/
+
+/* Register read/write macros */
+#define MCF_EPORT_EPPAR                MCF_REG16(0xFC094000)
+#define MCF_EPORT_EPDDR                MCF_REG08(0xFC094002)
+#define MCF_EPORT_EPIER                MCF_REG08(0xFC094003)
+#define MCF_EPORT_EPDR                 MCF_REG08(0xFC094004)
+#define MCF_EPORT_EPPDR                MCF_REG08(0xFC094005)
+#define MCF_EPORT_EPFR                 MCF_REG08(0xFC094006)
+
+/* Bit definitions and macros for MCF_EPORT_EPPAR */
+#define MCF_EPORT_EPPAR_EPPA1(x)       (((x)&0x0003)<<2)
+#define MCF_EPORT_EPPAR_EPPA2(x)       (((x)&0x0003)<<4)
+#define MCF_EPORT_EPPAR_EPPA3(x)       (((x)&0x0003)<<6)
+#define MCF_EPORT_EPPAR_EPPA4(x)       (((x)&0x0003)<<8)
+#define MCF_EPORT_EPPAR_EPPA5(x)       (((x)&0x0003)<<10)
+#define MCF_EPORT_EPPAR_EPPA6(x)       (((x)&0x0003)<<12)
+#define MCF_EPORT_EPPAR_EPPA7(x)       (((x)&0x0003)<<14)
+#define MCF_EPORT_EPPAR_LEVEL          (0)
+#define MCF_EPORT_EPPAR_RISING         (1)
+#define MCF_EPORT_EPPAR_FALLING        (2)
+#define MCF_EPORT_EPPAR_BOTH           (3)
+#define MCF_EPORT_EPPAR_EPPA7_LEVEL    (0x0000)
+#define MCF_EPORT_EPPAR_EPPA7_RISING   (0x4000)
+#define MCF_EPORT_EPPAR_EPPA7_FALLING  (0x8000)
+#define MCF_EPORT_EPPAR_EPPA7_BOTH     (0xC000)
+#define MCF_EPORT_EPPAR_EPPA6_LEVEL    (0x0000)
+#define MCF_EPORT_EPPAR_EPPA6_RISING   (0x1000)
+#define MCF_EPORT_EPPAR_EPPA6_FALLING  (0x2000)
+#define MCF_EPORT_EPPAR_EPPA6_BOTH     (0x3000)
+#define MCF_EPORT_EPPAR_EPPA5_LEVEL    (0x0000)
+#define MCF_EPORT_EPPAR_EPPA5_RISING   (0x0400)
+#define MCF_EPORT_EPPAR_EPPA5_FALLING  (0x0800)
+#define MCF_EPORT_EPPAR_EPPA5_BOTH     (0x0C00)
+#define MCF_EPORT_EPPAR_EPPA4_LEVEL    (0x0000)
+#define MCF_EPORT_EPPAR_EPPA4_RISING   (0x0100)
+#define MCF_EPORT_EPPAR_EPPA4_FALLING  (0x0200)
+#define MCF_EPORT_EPPAR_EPPA4_BOTH     (0x0300)
+#define MCF_EPORT_EPPAR_EPPA3_LEVEL    (0x0000)
+#define MCF_EPORT_EPPAR_EPPA3_RISING   (0x0040)
+#define MCF_EPORT_EPPAR_EPPA3_FALLING  (0x0080)
+#define MCF_EPORT_EPPAR_EPPA3_BOTH     (0x00C0)
+#define MCF_EPORT_EPPAR_EPPA2_LEVEL    (0x0000)
+#define MCF_EPORT_EPPAR_EPPA2_RISING   (0x0010)
+#define MCF_EPORT_EPPAR_EPPA2_FALLING  (0x0020)
+#define MCF_EPORT_EPPAR_EPPA2_BOTH     (0x0030)
+#define MCF_EPORT_EPPAR_EPPA1_LEVEL    (0x0000)
+#define MCF_EPORT_EPPAR_EPPA1_RISING   (0x0004)
+#define MCF_EPORT_EPPAR_EPPA1_FALLING  (0x0008)
+#define MCF_EPORT_EPPAR_EPPA1_BOTH     (0x000C)
+
+/* Bit definitions and macros for MCF_EPORT_EPDDR */
+#define MCF_EPORT_EPDDR_EPDD1          (0x02)
+#define MCF_EPORT_EPDDR_EPDD2          (0x04)
+#define MCF_EPORT_EPDDR_EPDD3          (0x08)
+#define MCF_EPORT_EPDDR_EPDD4          (0x10)
+#define MCF_EPORT_EPDDR_EPDD5          (0x20)
+#define MCF_EPORT_EPDDR_EPDD6          (0x40)
+#define MCF_EPORT_EPDDR_EPDD7          (0x80)
+
+/* Bit definitions and macros for MCF_EPORT_EPIER */
+#define MCF_EPORT_EPIER_EPIE1          (0x02)
+#define MCF_EPORT_EPIER_EPIE2          (0x04)
+#define MCF_EPORT_EPIER_EPIE3          (0x08)
+#define MCF_EPORT_EPIER_EPIE4          (0x10)
+#define MCF_EPORT_EPIER_EPIE5          (0x20)
+#define MCF_EPORT_EPIER_EPIE6          (0x40)
+#define MCF_EPORT_EPIER_EPIE7          (0x80)
+
+/* Bit definitions and macros for MCF_EPORT_EPDR */
+#define MCF_EPORT_EPDR_EPD1            (0x02)
+#define MCF_EPORT_EPDR_EPD2            (0x04)
+#define MCF_EPORT_EPDR_EPD3            (0x08)
+#define MCF_EPORT_EPDR_EPD4            (0x10)
+#define MCF_EPORT_EPDR_EPD5            (0x20)
+#define MCF_EPORT_EPDR_EPD6            (0x40)
+#define MCF_EPORT_EPDR_EPD7            (0x80)
+
+/* Bit definitions and macros for MCF_EPORT_EPPDR */
+#define MCF_EPORT_EPPDR_EPPD1          (0x02)
+#define MCF_EPORT_EPPDR_EPPD2          (0x04)
+#define MCF_EPORT_EPPDR_EPPD3          (0x08)
+#define MCF_EPORT_EPPDR_EPPD4          (0x10)
+#define MCF_EPORT_EPPDR_EPPD5          (0x20)
+#define MCF_EPORT_EPPDR_EPPD6          (0x40)
+#define MCF_EPORT_EPPDR_EPPD7          (0x80)
+
+/* Bit definitions and macros for MCF_EPORT_EPFR */
+#define MCF_EPORT_EPFR_EPF1            (0x02)
+#define MCF_EPORT_EPFR_EPF2            (0x04)
+#define MCF_EPORT_EPFR_EPF3            (0x08)
+#define MCF_EPORT_EPFR_EPF4            (0x10)
+#define MCF_EPORT_EPFR_EPF5            (0x20)
+#define MCF_EPORT_EPFR_EPF6            (0x40)
+#define MCF_EPORT_EPFR_EPF7            (0x80)
+
+/********************************************************************/
+#endif	/* m532xsim_h */
diff --git a/include/asm-mips/Kbuild b/include/asm-mips/Kbuild
new file mode 100644
index 000000000..c68e1680d
--- /dev/null
+++ b/include/asm-mips/Kbuild
@@ -0,0 +1 @@
+include include/asm-generic/Kbuild.asm
diff --git a/include/asm-mips/apm.h b/include/asm-mips/apm.h
new file mode 100644
index 000000000..4b99ffc11
--- /dev/null
+++ b/include/asm-mips/apm.h
@@ -0,0 +1,64 @@
+/* -*- linux-c -*-
+ *
+ * (C) 2003 zecke@handhelds.org
+ *
+ * GPL version 2
+ *
+ * based on arch/arm/kernel/apm.c
+ * factor out the information needed by architectures to provide
+ * apm status
+ *
+ *
+ */
+#ifndef MIPS_ASM_SA1100_APM_H
+#define MIPS_ASM_SA1100_APM_H
+
+#include <linux/apm_bios.h>
+
+/*
+ * This structure gets filled in by the machine specific 'get_power_status'
+ * implementation.  Any fields which are not set default to a safe value.
+ */
+struct apm_power_info {
+	unsigned char	ac_line_status;
+#define APM_AC_OFFLINE			0
+#define APM_AC_ONLINE			1
+#define APM_AC_BACKUP			2
+#define APM_AC_UNKNOWN			0xff
+
+	unsigned char	battery_status;
+#define APM_BATTERY_STATUS_HIGH		0
+#define APM_BATTERY_STATUS_LOW		1
+#define APM_BATTERY_STATUS_CRITICAL	2
+#define APM_BATTERY_STATUS_CHARGING	3
+#define APM_BATTERY_STATUS_NOT_PRESENT	4
+#define APM_BATTERY_STATUS_UNKNOWN	0xff
+
+	unsigned char	battery_flag;
+#define APM_BATTERY_FLAG_HIGH		(1 << 0)
+#define APM_BATTERY_FLAG_LOW		(1 << 1)
+#define APM_BATTERY_FLAG_CRITICAL	(1 << 2)
+#define APM_BATTERY_FLAG_CHARGING	(1 << 3)
+#define APM_BATTERY_FLAG_NOT_PRESENT	(1 << 7)
+#define APM_BATTERY_FLAG_UNKNOWN	0xff
+
+	int		battery_life;
+	int		time;
+	int		units;
+#define APM_UNITS_MINS			0
+#define APM_UNITS_SECS			1
+#define APM_UNITS_UNKNOWN		-1
+
+};
+
+/*
+ * This allows machines to provide their own "apm get power status" function.
+ */
+extern void (*apm_get_power_status)(struct apm_power_info *);
+
+/*
+ * Queue an event (APM_SYS_SUSPEND or APM_CRITICAL_SUSPEND)
+ */
+void apm_queue_event(apm_event_t event);
+
+#endif
diff --git a/include/asm-mips/emma2rh/emma2rh.h b/include/asm-mips/emma2rh/emma2rh.h
new file mode 100644
index 000000000..4fb8df71c
--- /dev/null
+++ b/include/asm-mips/emma2rh/emma2rh.h
@@ -0,0 +1,330 @@
+/*
+ *  include/asm-mips/emma2rh/emma2rh.h
+ *      This file is EMMA2RH common header.
+ *
+ *  Copyright (C) NEC Electronics Corporation 2005-2006
+ *
+ *  This file based on include/asm-mips/ddb5xxx/ddb5xxx.h
+ *          Copyright 2001 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 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
+ */
+#ifndef __ASM_EMMA2RH_EMMA2RH_H
+#define __ASM_EMMA2RH_EMMA2RH_H
+
+/*
+ * EMMA2RH registers
+ */
+#define REGBASE 0x10000000
+
+#define EMMA2RH_BHIF_STRAP_0	(0x000010+REGBASE)
+#define EMMA2RH_BHIF_INT_ST_0	(0x000030+REGBASE)
+#define EMMA2RH_BHIF_INT_ST_1	(0x000034+REGBASE)
+#define EMMA2RH_BHIF_INT_ST_2	(0x000038+REGBASE)
+#define EMMA2RH_BHIF_INT_EN_0	(0x000040+REGBASE)
+#define EMMA2RH_BHIF_INT_EN_1	(0x000044+REGBASE)
+#define EMMA2RH_BHIF_INT_EN_2	(0x000048+REGBASE)
+#define EMMA2RH_BHIF_INT1_EN_0	(0x000050+REGBASE)
+#define EMMA2RH_BHIF_INT1_EN_1	(0x000054+REGBASE)
+#define EMMA2RH_BHIF_INT1_EN_2	(0x000058+REGBASE)
+#define EMMA2RH_BHIF_SW_INT	(0x000070+REGBASE)
+#define EMMA2RH_BHIF_SW_INT_EN	(0x000080+REGBASE)
+#define EMMA2RH_BHIF_SW_INT_CLR	(0x000090+REGBASE)
+#define EMMA2RH_BHIF_MAIN_CTRL	(0x0000b4+REGBASE)
+#define EMMA2RH_BHIF_EXCEPT_VECT_BASE_ADDRESS	(0x0000c0+REGBASE)
+#define EMMA2RH_GPIO_DIR	(0x110d20+REGBASE)
+#define EMMA2RH_GPIO_INT_ST	(0x110d30+REGBASE)
+#define EMMA2RH_GPIO_INT_MASK	(0x110d3c+REGBASE)
+#define EMMA2RH_GPIO_INT_MODE	(0x110d48+REGBASE)
+#define EMMA2RH_GPIO_INT_CND_A	(0x110d54+REGBASE)
+#define EMMA2RH_GPIO_INT_CND_B	(0x110d60+REGBASE)
+#define EMMA2RH_PBRD_INT_EN	(0x100010+REGBASE)
+#define EMMA2RH_PBRD_CLKSEL	(0x100028+REGBASE)
+#define EMMA2RH_PFUR0_BASE	(0x101000+REGBASE)
+#define EMMA2RH_PFUR1_BASE	(0x102000+REGBASE)
+#define EMMA2RH_PFUR2_BASE	(0x103000+REGBASE)
+#define EMMA2RH_PIIC0_BASE	(0x107000+REGBASE)
+#define EMMA2RH_PIIC1_BASE	(0x108000+REGBASE)
+#define EMMA2RH_PIIC2_BASE	(0x109000+REGBASE)
+#define EMMA2RH_PCI_CONTROL	(0x200000+REGBASE)
+#define EMMA2RH_PCI_ARBIT_CTR	(0x200004+REGBASE)
+#define EMMA2RH_PCI_IWIN0_CTR	(0x200010+REGBASE)
+#define EMMA2RH_PCI_IWIN1_CTR	(0x200014+REGBASE)
+#define EMMA2RH_PCI_INIT_ESWP	(0x200018+REGBASE)
+#define EMMA2RH_PCI_INT		(0x200020+REGBASE)
+#define EMMA2RH_PCI_INT_EN	(0x200024+REGBASE)
+#define EMMA2RH_PCI_TWIN_CTR	(0x200030+REGBASE)
+#define EMMA2RH_PCI_TWIN_BADR	(0x200034+REGBASE)
+#define EMMA2RH_PCI_TWIN0_DADR	(0x200038+REGBASE)
+#define EMMA2RH_PCI_TWIN1_DADR	(0x20003c+REGBASE)
+
+/*
+ *  Memory map (physical address)
+ *
+ *  Note most of the following address must be properly aligned by the
+ *  corresponding size.  For example, if PCI_IO_SIZE is 16MB, then
+ *  PCI_IO_BASE must be aligned along 16MB boundary.
+ */
+
+/* the actual ram size is detected at run-time */
+#define EMMA2RH_RAM_BASE	0x00000000
+#define EMMA2RH_RAM_SIZE	0x10000000	/* less than 256MB */
+
+#define EMMA2RH_IO_BASE		0x10000000
+#define EMMA2RH_IO_SIZE		0x01000000	/* 16 MB */
+
+#define EMMA2RH_GENERALIO_BASE	0x11000000
+#define EMMA2RH_GENERALIO_SIZE	0x01000000	/* 16 MB */
+
+#define EMMA2RH_PCI_IO_BASE	0x12000000
+#define EMMA2RH_PCI_IO_SIZE	0x02000000	/* 32 MB */
+
+#define EMMA2RH_PCI_MEM_BASE	0x14000000
+#define EMMA2RH_PCI_MEM_SIZE	0x08000000	/* 128 MB */
+
+#define EMMA2RH_ROM_BASE	0x1c000000
+#define EMMA2RH_ROM_SIZE	0x04000000	/* 64 MB */
+
+#define EMMA2RH_PCI_CONFIG_BASE	EMMA2RH_PCI_IO_BASE
+#define EMMA2RH_PCI_CONFIG_SIZE	EMMA2RH_PCI_IO_SIZE
+
+#define NUM_CPU_IRQ		8
+#define NUM_EMMA2RH_IRQ		96
+
+#define CPU_EMMA2RH_CASCADE	2
+#define EMMA2RH_IRQ_BASE	0
+
+/*
+ * emma2rh irq defs
+ */
+
+#define EMMA2RH_IRQ_INT0	(0 + EMMA2RH_IRQ_BASE)
+#define EMMA2RH_IRQ_INT1	(1 + EMMA2RH_IRQ_BASE)
+#define EMMA2RH_IRQ_INT2	(2 + EMMA2RH_IRQ_BASE)
+#define EMMA2RH_IRQ_INT3	(3 + EMMA2RH_IRQ_BASE)
+#define EMMA2RH_IRQ_INT4	(4 + EMMA2RH_IRQ_BASE)
+#define EMMA2RH_IRQ_INT5	(5 + EMMA2RH_IRQ_BASE)
+#define EMMA2RH_IRQ_INT6	(6 + EMMA2RH_IRQ_BASE)
+#define EMMA2RH_IRQ_INT7	(7 + EMMA2RH_IRQ_BASE)
+#define EMMA2RH_IRQ_INT8	(8 + EMMA2RH_IRQ_BASE)
+#define EMMA2RH_IRQ_INT9	(9 + EMMA2RH_IRQ_BASE)
+#define EMMA2RH_IRQ_INT10	(10 + EMMA2RH_IRQ_BASE)
+#define EMMA2RH_IRQ_INT11	(11 + EMMA2RH_IRQ_BASE)
+#define EMMA2RH_IRQ_INT12	(12 + EMMA2RH_IRQ_BASE)
+#define EMMA2RH_IRQ_INT13	(13 + EMMA2RH_IRQ_BASE)
+#define EMMA2RH_IRQ_INT14	(14 + EMMA2RH_IRQ_BASE)
+#define EMMA2RH_IRQ_INT15	(15 + EMMA2RH_IRQ_BASE)
+#define EMMA2RH_IRQ_INT16	(16 + EMMA2RH_IRQ_BASE)
+#define EMMA2RH_IRQ_INT17	(17 + EMMA2RH_IRQ_BASE)
+#define EMMA2RH_IRQ_INT18	(18 + EMMA2RH_IRQ_BASE)
+#define EMMA2RH_IRQ_INT19	(19 + EMMA2RH_IRQ_BASE)
+#define EMMA2RH_IRQ_INT20	(20 + EMMA2RH_IRQ_BASE)
+#define EMMA2RH_IRQ_INT21	(21 + EMMA2RH_IRQ_BASE)
+#define EMMA2RH_IRQ_INT22	(22 + EMMA2RH_IRQ_BASE)
+#define EMMA2RH_IRQ_INT23	(23 + EMMA2RH_IRQ_BASE)
+#define EMMA2RH_IRQ_INT24	(24 + EMMA2RH_IRQ_BASE)
+#define EMMA2RH_IRQ_INT25	(25 + EMMA2RH_IRQ_BASE)
+#define EMMA2RH_IRQ_INT26	(26 + EMMA2RH_IRQ_BASE)
+#define EMMA2RH_IRQ_INT27	(27 + EMMA2RH_IRQ_BASE)
+#define EMMA2RH_IRQ_INT28	(28 + EMMA2RH_IRQ_BASE)
+#define EMMA2RH_IRQ_INT29	(29 + EMMA2RH_IRQ_BASE)
+#define EMMA2RH_IRQ_INT30	(30 + EMMA2RH_IRQ_BASE)
+#define EMMA2RH_IRQ_INT31	(31 + EMMA2RH_IRQ_BASE)
+#define EMMA2RH_IRQ_INT32	(32 + EMMA2RH_IRQ_BASE)
+#define EMMA2RH_IRQ_INT33	(33 + EMMA2RH_IRQ_BASE)
+#define EMMA2RH_IRQ_INT34	(34 + EMMA2RH_IRQ_BASE)
+#define EMMA2RH_IRQ_INT35	(35 + EMMA2RH_IRQ_BASE)
+#define EMMA2RH_IRQ_INT36	(36 + EMMA2RH_IRQ_BASE)
+#define EMMA2RH_IRQ_INT37	(37 + EMMA2RH_IRQ_BASE)
+#define EMMA2RH_IRQ_INT38	(38 + EMMA2RH_IRQ_BASE)
+#define EMMA2RH_IRQ_INT39	(39 + EMMA2RH_IRQ_BASE)
+#define EMMA2RH_IRQ_INT40	(40 + EMMA2RH_IRQ_BASE)
+#define EMMA2RH_IRQ_INT41	(41 + EMMA2RH_IRQ_BASE)
+#define EMMA2RH_IRQ_INT42	(42 + EMMA2RH_IRQ_BASE)
+#define EMMA2RH_IRQ_INT43	(43 + EMMA2RH_IRQ_BASE)
+#define EMMA2RH_IRQ_INT44	(44 + EMMA2RH_IRQ_BASE)
+#define EMMA2RH_IRQ_INT45	(45 + EMMA2RH_IRQ_BASE)
+#define EMMA2RH_IRQ_INT46	(46 + EMMA2RH_IRQ_BASE)
+#define EMMA2RH_IRQ_INT47	(47 + EMMA2RH_IRQ_BASE)
+#define EMMA2RH_IRQ_INT48	(48 + EMMA2RH_IRQ_BASE)
+#define EMMA2RH_IRQ_INT49	(49 + EMMA2RH_IRQ_BASE)
+#define EMMA2RH_IRQ_INT50	(50 + EMMA2RH_IRQ_BASE)
+#define EMMA2RH_IRQ_INT51	(51 + EMMA2RH_IRQ_BASE)
+#define EMMA2RH_IRQ_INT52	(52 + EMMA2RH_IRQ_BASE)
+#define EMMA2RH_IRQ_INT53	(53 + EMMA2RH_IRQ_BASE)
+#define EMMA2RH_IRQ_INT54	(54 + EMMA2RH_IRQ_BASE)
+#define EMMA2RH_IRQ_INT55	(55 + EMMA2RH_IRQ_BASE)
+#define EMMA2RH_IRQ_INT56	(56 + EMMA2RH_IRQ_BASE)
+#define EMMA2RH_IRQ_INT57	(57 + EMMA2RH_IRQ_BASE)
+#define EMMA2RH_IRQ_INT58	(58 + EMMA2RH_IRQ_BASE)
+#define EMMA2RH_IRQ_INT59	(59 + EMMA2RH_IRQ_BASE)
+#define EMMA2RH_IRQ_INT60	(60 + EMMA2RH_IRQ_BASE)
+#define EMMA2RH_IRQ_INT61	(61 + EMMA2RH_IRQ_BASE)
+#define EMMA2RH_IRQ_INT62	(62 + EMMA2RH_IRQ_BASE)
+#define EMMA2RH_IRQ_INT63	(63 + EMMA2RH_IRQ_BASE)
+
+#define EMMA2RH_IRQ_PFUR0	EMMA2RH_IRQ_INT49
+#define EMMA2RH_IRQ_PFUR1	EMMA2RH_IRQ_INT50
+#define EMMA2RH_IRQ_PFUR2	EMMA2RH_IRQ_INT51
+#define EMMA2RH_IRQ_PIIC0	EMMA2RH_IRQ_INT56
+#define EMMA2RH_IRQ_PIIC1	EMMA2RH_IRQ_INT57
+#define EMMA2RH_IRQ_PIIC2	EMMA2RH_IRQ_INT58
+
+/*
+ *  EMMA2RH Register Access
+ */
+
+#define EMMA2RH_BASE (0xa0000000)
+
+static inline void emma2rh_sync(void)
+{
+	volatile u32 *p = (volatile u32 *)0xbfc00000;
+	(void)(*p);
+}
+
+static inline void emma2rh_out32(u32 offset, u32 val)
+{
+	*(volatile u32 *)(EMMA2RH_BASE | offset) = val;
+	emma2rh_sync();
+}
+
+static inline u32 emma2rh_in32(u32 offset)
+{
+	u32 val = *(volatile u32 *)(EMMA2RH_BASE | offset);
+	emma2rh_sync();
+	return val;
+}
+
+static inline void emma2rh_out16(u32 offset, u16 val)
+{
+	*(volatile u16 *)(EMMA2RH_BASE | offset) = val;
+	emma2rh_sync();
+}
+
+static inline u16 emma2rh_in16(u32 offset)
+{
+	u16 val = *(volatile u16 *)(EMMA2RH_BASE | offset);
+	emma2rh_sync();
+	return val;
+}
+
+static inline void emma2rh_out8(u32 offset, u8 val)
+{
+	*(volatile u8 *)(EMMA2RH_BASE | offset) = val;
+	emma2rh_sync();
+}
+
+static inline u8 emma2rh_in8(u32 offset)
+{
+	u8 val = *(volatile u8 *)(EMMA2RH_BASE | offset);
+	emma2rh_sync();
+	return val;
+}
+
+/**
+ * IIC registers map
+ **/
+
+/*---------------------------------------------------------------------------*/
+/* CNT - Control register (00H R/W)                                          */
+/*---------------------------------------------------------------------------*/
+#define SPT         0x00000001
+#define STT         0x00000002
+#define ACKE        0x00000004
+#define WTIM        0x00000008
+#define SPIE        0x00000010
+#define WREL        0x00000020
+#define LREL        0x00000040
+#define IICE        0x00000080
+#define CNT_RESERVED    0x000000ff	/* reserved bit 0 */
+
+#define I2C_EMMA_START      (IICE | STT)
+#define I2C_EMMA_STOP       (IICE | SPT)
+#define I2C_EMMA_REPSTART   I2C_EMMA_START
+
+/*---------------------------------------------------------------------------*/
+/* STA - Status register (10H Read)                                          */
+/*---------------------------------------------------------------------------*/
+#define MSTS        0x00000080
+#define ALD         0x00000040
+#define EXC         0x00000020
+#define COI         0x00000010
+#define TRC         0x00000008
+#define ACKD        0x00000004
+#define STD         0x00000002
+#define SPD         0x00000001
+
+/*---------------------------------------------------------------------------*/
+/* CSEL - Clock select register (20H R/W)                                    */
+/*---------------------------------------------------------------------------*/
+#define FCL         0x00000080
+#define ND50        0x00000040
+#define CLD         0x00000020
+#define DAD         0x00000010
+#define SMC         0x00000008
+#define DFC         0x00000004
+#define CL          0x00000003
+#define CSEL_RESERVED   0x000000ff	/* reserved bit 0 */
+
+#define FAST397     0x0000008b
+#define FAST297     0x0000008a
+#define FAST347     0x0000000b
+#define FAST260     0x0000000a
+#define FAST130     0x00000008
+#define STANDARD108 0x00000083
+#define STANDARD83  0x00000082
+#define STANDARD95  0x00000003
+#define STANDARD73  0x00000002
+#define STANDARD36  0x00000001
+#define STANDARD71  0x00000000
+
+/*---------------------------------------------------------------------------*/
+/* SVA - Slave address register (30H R/W)                                    */
+/*---------------------------------------------------------------------------*/
+#define SVA         0x000000fe
+
+/*---------------------------------------------------------------------------*/
+/* SHR - Shift register (40H R/W)                                            */
+/*---------------------------------------------------------------------------*/
+#define SR          0x000000ff
+
+/*---------------------------------------------------------------------------*/
+/* INT - Interrupt register (50H R/W)                                        */
+/* INTM - Interrupt mask register (60H R/W)                                  */
+/*---------------------------------------------------------------------------*/
+#define INTE0       0x00000001
+
+/***********************************************************************
+ * I2C registers
+ ***********************************************************************
+ */
+#define I2C_EMMA_CNT            0x00
+#define I2C_EMMA_STA            0x10
+#define I2C_EMMA_CSEL           0x20
+#define I2C_EMMA_SVA            0x30
+#define I2C_EMMA_SHR            0x40
+#define I2C_EMMA_INT            0x50
+#define I2C_EMMA_INTM           0x60
+
+/*
+ * include the board dependent part
+ */
+#if defined(CONFIG_MARKEINS)
+#include <asm/emma2rh/markeins.h>
+#else
+#error "Unknown EMMA2RH board!"
+#endif
+
+#endif /* __ASM_EMMA2RH_EMMA2RH_H */
diff --git a/include/asm-mips/emma2rh/markeins.h b/include/asm-mips/emma2rh/markeins.h
new file mode 100644
index 000000000..8fa766795
--- /dev/null
+++ b/include/asm-mips/emma2rh/markeins.h
@@ -0,0 +1,76 @@
+/*
+ *  include/asm-mips/emma2rh/markeins.h
+ *      This file is EMMA2RH board depended header.
+ *
+ *  Copyright (C) NEC Electronics Corporation 2005-2006
+ *
+ *  This file based on include/asm-mips/ddb5xxx/ddb5xxx.h
+ *          Copyright 2001 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 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
+ */
+
+#ifndef MARKEINS_H
+#define MARKEINS_H
+
+#define NUM_EMMA2RH_IRQ_SW	32
+#define NUM_EMMA2RH_IRQ_GPIO	32
+
+#define EMMA2RH_SW_CASCADE	(EMMA2RH_IRQ_INT7 - EMMA2RH_IRQ_INT0)
+#define EMMA2RH_GPIO_CASCADE	(EMMA2RH_IRQ_INT46 - EMMA2RH_IRQ_INT0)
+
+#define EMMA2RH_SW_IRQ_BASE	(EMMA2RH_IRQ_BASE + NUM_EMMA2RH_IRQ)
+#define EMMA2RH_GPIO_IRQ_BASE	(EMMA2RH_SW_IRQ_BASE + NUM_EMMA2RH_IRQ_SW)
+#define CPU_IRQ_BASE		(EMMA2RH_GPIO_IRQ_BASE + NUM_EMMA2RH_IRQ_GPIO)
+
+#define EMMA2RH_SW_IRQ_INT0	(0+EMMA2RH_SW_IRQ_BASE)
+#define EMMA2RH_SW_IRQ_INT1	(1+EMMA2RH_SW_IRQ_BASE)
+#define EMMA2RH_SW_IRQ_INT2	(2+EMMA2RH_SW_IRQ_BASE)
+#define EMMA2RH_SW_IRQ_INT3	(3+EMMA2RH_SW_IRQ_BASE)
+#define EMMA2RH_SW_IRQ_INT4	(4+EMMA2RH_SW_IRQ_BASE)
+#define EMMA2RH_SW_IRQ_INT5	(5+EMMA2RH_SW_IRQ_BASE)
+#define EMMA2RH_SW_IRQ_INT6	(6+EMMA2RH_SW_IRQ_BASE)
+#define EMMA2RH_SW_IRQ_INT7	(7+EMMA2RH_SW_IRQ_BASE)
+#define EMMA2RH_SW_IRQ_INT8	(8+EMMA2RH_SW_IRQ_BASE)
+#define EMMA2RH_SW_IRQ_INT9	(9+EMMA2RH_SW_IRQ_BASE)
+#define EMMA2RH_SW_IRQ_INT10	(10+EMMA2RH_SW_IRQ_BASE)
+#define EMMA2RH_SW_IRQ_INT11	(11+EMMA2RH_SW_IRQ_BASE)
+#define EMMA2RH_SW_IRQ_INT12	(12+EMMA2RH_SW_IRQ_BASE)
+#define EMMA2RH_SW_IRQ_INT13	(13+EMMA2RH_SW_IRQ_BASE)
+#define EMMA2RH_SW_IRQ_INT14	(14+EMMA2RH_SW_IRQ_BASE)
+#define EMMA2RH_SW_IRQ_INT15	(15+EMMA2RH_SW_IRQ_BASE)
+#define EMMA2RH_SW_IRQ_INT16	(16+EMMA2RH_SW_IRQ_BASE)
+#define EMMA2RH_SW_IRQ_INT17	(17+EMMA2RH_SW_IRQ_BASE)
+#define EMMA2RH_SW_IRQ_INT18	(18+EMMA2RH_SW_IRQ_BASE)
+#define EMMA2RH_SW_IRQ_INT19	(19+EMMA2RH_SW_IRQ_BASE)
+#define EMMA2RH_SW_IRQ_INT20	(20+EMMA2RH_SW_IRQ_BASE)
+#define EMMA2RH_SW_IRQ_INT21	(21+EMMA2RH_SW_IRQ_BASE)
+#define EMMA2RH_SW_IRQ_INT22	(22+EMMA2RH_SW_IRQ_BASE)
+#define EMMA2RH_SW_IRQ_INT23	(23+EMMA2RH_SW_IRQ_BASE)
+#define EMMA2RH_SW_IRQ_INT24	(24+EMMA2RH_SW_IRQ_BASE)
+#define EMMA2RH_SW_IRQ_INT25	(25+EMMA2RH_SW_IRQ_BASE)
+#define EMMA2RH_SW_IRQ_INT26	(26+EMMA2RH_SW_IRQ_BASE)
+#define EMMA2RH_SW_IRQ_INT27	(27+EMMA2RH_SW_IRQ_BASE)
+#define EMMA2RH_SW_IRQ_INT28	(28+EMMA2RH_SW_IRQ_BASE)
+#define EMMA2RH_SW_IRQ_INT29	(29+EMMA2RH_SW_IRQ_BASE)
+#define EMMA2RH_SW_IRQ_INT30	(30+EMMA2RH_SW_IRQ_BASE)
+#define EMMA2RH_SW_IRQ_INT31	(31+EMMA2RH_SW_IRQ_BASE)
+
+#define MARKEINS_PCI_IRQ_INTA	EMMA2RH_GPIO_IRQ_BASE+15
+#define MARKEINS_PCI_IRQ_INTB	EMMA2RH_GPIO_IRQ_BASE+16
+#define MARKEINS_PCI_IRQ_INTC	EMMA2RH_GPIO_IRQ_BASE+17
+#define MARKEINS_PCI_IRQ_INTD	EMMA2RH_GPIO_IRQ_BASE+18
+
+#endif /* CONFIG_MARKEINS */
diff --git a/include/asm-mips/irqflags.h b/include/asm-mips/irqflags.h
new file mode 100644
index 000000000..43ca09a3a
--- /dev/null
+++ b/include/asm-mips/irqflags.h
@@ -0,0 +1,225 @@
+/*
+ * 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) 1994, 95, 96, 97, 98, 99, 2003 by Ralf Baechle
+ * Copyright (C) 1996 by Paul M. Antoine
+ * Copyright (C) 1999 Silicon Graphics
+ * Copyright (C) 2000 MIPS Technologies, Inc.
+ */
+#ifndef _ASM_IRQFLAGS_H
+#define _ASM_IRQFLAGS_H
+
+#ifndef __ASSEMBLY__
+
+#include <asm/hazards.h>
+
+__asm__ (
+	"	.macro	raw_local_irq_enable				\n"
+	"	.set	push						\n"
+	"	.set	reorder						\n"
+	"	.set	noat						\n"
+#ifdef CONFIG_MIPS_MT_SMTC
+	"	mfc0	$1, $2, 1	# SMTC - clear TCStatus.IXMT	\n"
+	"	ori	$1, 0x400					\n"
+	"	xori	$1, 0x400					\n"
+	"	mtc0	$1, $2, 1					\n"
+#elif defined(CONFIG_CPU_MIPSR2)
+	"	ei							\n"
+#else
+	"	mfc0	$1,$12						\n"
+	"	ori	$1,0x1f						\n"
+	"	xori	$1,0x1e						\n"
+	"	mtc0	$1,$12						\n"
+#endif
+	"	irq_enable_hazard					\n"
+	"	.set	pop						\n"
+	"	.endm");
+
+static inline void raw_local_irq_enable(void)
+{
+	__asm__ __volatile__(
+		"raw_local_irq_enable"
+		: /* no outputs */
+		: /* no inputs */
+		: "memory");
+}
+
+/*
+ * For cli() we have to insert nops to make sure that the new value
+ * has actually arrived in the status register before the end of this
+ * macro.
+ * R4000/R4400 need three nops, the R4600 two nops and the R10000 needs
+ * no nops at all.
+ */
+/*
+ * For TX49, operating only IE bit is not enough.
+ *
+ * If mfc0 $12 follows store and the mfc0 is last instruction of a
+ * page and fetching the next instruction causes TLB miss, the result
+ * of the mfc0 might wrongly contain EXL bit.
+ *
+ * ERT-TX49H2-027, ERT-TX49H3-012, ERT-TX49HL3-006, ERT-TX49H4-008
+ *
+ * Workaround: mask EXL bit of the result or place a nop before mfc0.
+ */
+__asm__ (
+	"	.macro	raw_local_irq_disable\n"
+	"	.set	push						\n"
+	"	.set	noat						\n"
+#ifdef CONFIG_MIPS_MT_SMTC
+	"	mfc0	$1, $2, 1					\n"
+	"	ori	$1, 0x400					\n"
+	"	.set	noreorder					\n"
+	"	mtc0	$1, $2, 1					\n"
+#elif defined(CONFIG_CPU_MIPSR2)
+	"	di							\n"
+#else
+	"	mfc0	$1,$12						\n"
+	"	ori	$1,0x1f						\n"
+	"	xori	$1,0x1f						\n"
+	"	.set	noreorder					\n"
+	"	mtc0	$1,$12						\n"
+#endif
+	"	irq_disable_hazard					\n"
+	"	.set	pop						\n"
+	"	.endm							\n");
+
+static inline void raw_local_irq_disable(void)
+{
+	__asm__ __volatile__(
+		"raw_local_irq_disable"
+		: /* no outputs */
+		: /* no inputs */
+		: "memory");
+}
+
+__asm__ (
+	"	.macro	raw_local_save_flags flags			\n"
+	"	.set	push						\n"
+	"	.set	reorder						\n"
+#ifdef CONFIG_MIPS_MT_SMTC
+	"	mfc0	\\flags, $2, 1					\n"
+#else
+	"	mfc0	\\flags, $12					\n"
+#endif
+	"	.set	pop						\n"
+	"	.endm							\n");
+
+#define raw_local_save_flags(x)						\
+__asm__ __volatile__(							\
+	"raw_local_save_flags %0"					\
+	: "=r" (x))
+
+__asm__ (
+	"	.macro	raw_local_irq_save result			\n"
+	"	.set	push						\n"
+	"	.set	reorder						\n"
+	"	.set	noat						\n"
+#ifdef CONFIG_MIPS_MT_SMTC
+	"	mfc0	\\result, $2, 1					\n"
+	"	ori	$1, \\result, 0x400				\n"
+	"	.set	noreorder					\n"
+	"	mtc0	$1, $2, 1					\n"
+	"	andi	\\result, \\result, 0x400			\n"
+#elif defined(CONFIG_CPU_MIPSR2)
+	"	di	\\result					\n"
+	"	andi	\\result, 1					\n"
+#else
+	"	mfc0	\\result, $12					\n"
+	"	ori	$1, \\result, 0x1f				\n"
+	"	xori	$1, 0x1f					\n"
+	"	.set	noreorder					\n"
+	"	mtc0	$1, $12						\n"
+#endif
+	"	irq_disable_hazard					\n"
+	"	.set	pop						\n"
+	"	.endm							\n");
+
+#define raw_local_irq_save(x)						\
+__asm__ __volatile__(							\
+	"raw_local_irq_save\t%0"					\
+	: "=r" (x)							\
+	: /* no inputs */						\
+	: "memory")
+
+__asm__ (
+	"	.macro	raw_local_irq_restore flags			\n"
+	"	.set	push						\n"
+	"	.set	noreorder					\n"
+	"	.set	noat						\n"
+#ifdef CONFIG_MIPS_MT_SMTC
+	"mfc0	$1, $2, 1						\n"
+	"andi	\\flags, 0x400						\n"
+	"ori	$1, 0x400						\n"
+	"xori	$1, 0x400						\n"
+	"or	\\flags, $1						\n"
+	"mtc0	\\flags, $2, 1						\n"
+#elif defined(CONFIG_CPU_MIPSR2) && defined(CONFIG_IRQ_CPU)
+	/*
+	 * Slow, but doesn't suffer from a relativly unlikely race
+	 * condition we're having since days 1.
+	 */
+	"	beqz	\\flags, 1f					\n"
+	"	 di							\n"
+	"	ei							\n"
+	"1:								\n"
+#elif defined(CONFIG_CPU_MIPSR2)
+	/*
+	 * Fast, dangerous.  Life is fun, life is good.
+	 */
+	"	mfc0	$1, $12						\n"
+	"	ins	$1, \\flags, 0, 1				\n"
+	"	mtc0	$1, $12						\n"
+#else
+	"	mfc0	$1, $12						\n"
+	"	andi	\\flags, 1					\n"
+	"	ori	$1, 0x1f					\n"
+	"	xori	$1, 0x1f					\n"
+	"	or	\\flags, $1					\n"
+	"	mtc0	\\flags, $12					\n"
+#endif
+	"	irq_disable_hazard					\n"
+	"	.set	pop						\n"
+	"	.endm							\n");
+
+#define raw_local_irq_restore(flags)					\
+do {									\
+	unsigned long __tmp1;						\
+									\
+	__asm__ __volatile__(						\
+		"raw_local_irq_restore\t%0"				\
+		: "=r" (__tmp1)						\
+		: "0" (flags)						\
+		: "memory");						\
+} while(0)
+
+static inline int raw_irqs_disabled_flags(unsigned long flags)
+{
+#ifdef CONFIG_MIPS_MT_SMTC
+	/*
+	 * SMTC model uses TCStatus.IXMT to disable interrupts for a thread/CPU
+	 */
+	return flags & 0x400;
+#else
+	return !(flags & 1);
+#endif
+}
+
+#endif
+
+/*
+ * Do the CPU's IRQ-state tracing from assembly code.
+ */
+#ifdef CONFIG_TRACE_IRQFLAGS
+# define TRACE_IRQS_ON							\
+	jal	trace_hardirqs_on
+# define TRACE_IRQS_OFF							\
+	jal	trace_hardirqs_off
+#else
+# define TRACE_IRQS_ON
+# define TRACE_IRQS_OFF
+#endif
+
+#endif /* _ASM_IRQFLAGS_H */
diff --git a/include/asm-mips/mach-emma2rh/irq.h b/include/asm-mips/mach-emma2rh/irq.h
new file mode 100644
index 000000000..bce64244b
--- /dev/null
+++ b/include/asm-mips/mach-emma2rh/irq.h
@@ -0,0 +1,13 @@
+/*
+ * 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) 2003 by Ralf Baechle
+ */
+#ifndef __ASM_MACH_EMMA2RH_IRQ_H
+#define __ASM_MACH_EMMA2RH_IRQ_H
+
+#define NR_IRQS	256
+
+#endif /* __ASM_MACH_EMMA2RH_IRQ_H */
diff --git a/include/asm-mips/mach-excite/cpu-feature-overrides.h b/include/asm-mips/mach-excite/cpu-feature-overrides.h
new file mode 100644
index 000000000..0d3185422
--- /dev/null
+++ b/include/asm-mips/mach-excite/cpu-feature-overrides.h
@@ -0,0 +1,40 @@
+/*
+ * 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) 2004 Thomas Koeller <thomas.koeller@baslerweb.com>
+ */
+#ifndef __ASM_MACH_EXCITE_CPU_FEATURE_OVERRIDES_H
+#define __ASM_MACH_EXCITE_CPU_FEATURE_OVERRIDES_H
+
+/*
+ * Basler eXcite has an RM9122 processor.
+ */
+#define cpu_has_watch		1
+#define cpu_has_mips16		0
+#define cpu_has_divec		0
+#define cpu_has_vce		0
+#define cpu_has_cache_cdex_p	0
+#define cpu_has_cache_cdex_s	0
+#define cpu_has_prefetch	1
+#define cpu_has_mcheck		0
+#define cpu_has_ejtag		0
+
+#define cpu_has_llsc		1
+#define cpu_has_vtag_icache	0
+#define cpu_has_dc_aliases	0
+#define cpu_has_ic_fills_f_dc	0
+#define cpu_has_dsp		0
+#define cpu_icache_snoops_remote_store	0
+
+#define cpu_has_nofpuex		0
+#define cpu_has_64bits		1
+
+#define cpu_has_inclusive_pcaches	0
+
+#define cpu_dcache_line_size()	32
+#define cpu_icache_line_size()	32
+#define cpu_scache_line_size()	32
+
+#endif /* __ASM_MACH_EXCITE_CPU_FEATURE_OVERRIDES_H */
diff --git a/include/asm-mips/mach-excite/excite.h b/include/asm-mips/mach-excite/excite.h
new file mode 100644
index 000000000..130bd4b8e
--- /dev/null
+++ b/include/asm-mips/mach-excite/excite.h
@@ -0,0 +1,154 @@
+#ifndef __EXCITE_H__
+#define __EXCITE_H__
+
+#include <linux/init.h>
+#include <asm/addrspace.h>
+#include <asm/types.h>
+
+#define EXCITE_CPU_EXT_CLOCK 100000000
+
+#if !defined(__ASSEMBLER__)
+void __init excite_kgdb_init(void);
+void excite_procfs_init(void);
+extern unsigned long memsize;
+extern char modetty[];
+extern u32 unit_id;
+#endif
+
+/* Base name for XICAP devices */
+#define XICAP_NAME	"xicap_gpi"
+
+/* OCD register offsets */
+#define LKB0		0x0038
+#define LKB5		0x0128
+#define LKM5		0x012C
+#define LKB7		0x0138
+#define LKM7		0x013c
+#define LKB8		0x0140
+#define LKM8		0x0144
+#define LKB9		0x0148
+#define LKM9		0x014c
+#define LKB10		0x0150
+#define LKM10		0x0154
+#define LKB11		0x0158
+#define LKM11		0x015c
+#define LKB12		0x0160
+#define LKM12		0x0164
+#define LKB13		0x0168
+#define LKM13		0x016c
+#define LDP0		0x0200
+#define LDP1		0x0210
+#define LDP2		0x0220
+#define LDP3		0x0230
+#define INTPIN0		0x0A40
+#define INTPIN1		0x0A44
+#define INTPIN2		0x0A48
+#define INTPIN3		0x0A4C
+#define INTPIN4		0x0A50
+#define INTPIN5		0x0A54
+#define INTPIN6		0x0A58
+#define INTPIN7		0x0A5C
+
+
+
+
+/* TITAN register offsets */
+#define CPRR		0x0004
+#define CPDSR		0x0008
+#define CPTC0R		0x000c
+#define CPTC1R		0x0010
+#define CPCFG0		0x0020
+#define CPCFG1		0x0024
+#define CPDST0A		0x0028
+#define CPDST0B		0x002c
+#define CPDST1A		0x0030
+#define CPDST1B		0x0034
+#define CPXDSTA		0x0038
+#define CPXDSTB		0x003c
+#define CPXCISRA	0x0048
+#define CPXCISRB	0x004c
+#define CPGIG0ER	0x0050
+#define CPGIG1ER	0x0054
+#define CPGRWL		0x0068
+#define CPURSLMT	0x00f8
+#define UACFG		0x0200
+#define UAINTS		0x0204
+#define SDRXFCIE	0x4828
+#define SDTXFCIE	0x4928
+#define INTP0Status0	0x1B00
+#define INTP0Mask0	0x1B04
+#define INTP0Set0	0x1B08
+#define INTP0Clear0	0x1B0C
+#define GXCFG		0x5000
+#define GXDMADRPFX	0x5018
+#define GXDMA_DESCADR	0x501c
+#define GXCH0TDESSTRT	0x5054
+
+/* IRQ definitions */
+#define NMICONFIG		0xac0
+#define TITAN_MSGINT	0xc4
+#define TITAN_IRQ	((TITAN_MSGINT / 0x20) + 2)
+#define FPGA0_MSGINT	0x5a
+#define FPGA0_IRQ	((FPGA0_MSGINT / 0x20) + 2)
+#define FPGA1_MSGINT	0x7b
+#define FPGA1_IRQ	((FPGA1_MSGINT / 0x20) + 2)
+#define PHY_MSGINT	0x9c
+#define PHY_IRQ		((PHY_MSGINT   / 0x20) + 2)
+
+#if defined(CONFIG_BASLER_EXCITE_PROTOTYPE)
+/* Pre-release units used interrupt pin #9 */
+#define USB_IRQ		11
+#else
+/* Re-designed units use interrupt pin #1 */
+#define USB_MSGINT	0x39
+#define USB_IRQ		((USB_MSGINT / 0x20) + 2)
+#endif
+#define TIMER_IRQ	12
+
+
+/* Device address ranges */
+#define EXCITE_OFFS_OCD		0x1fffc000
+#define	EXCITE_SIZE_OCD		(16 * 1024)
+#define EXCITE_PHYS_OCD		CPHYSADDR(EXCITE_OFFS_OCD)
+#define EXCITE_ADDR_OCD		CKSEG1ADDR(EXCITE_OFFS_OCD)
+
+#define EXCITE_OFFS_SCRAM 	0x1fffa000
+#define	EXCITE_SIZE_SCRAM	(8 << 10)
+#define EXCITE_PHYS_SCRAM 	CPHYSADDR(EXCITE_OFFS_SCRAM)
+#define EXCITE_ADDR_SCRAM 	CKSEG1ADDR(EXCITE_OFFS_SCRAM)
+
+#define EXCITE_OFFS_PCI_IO	0x1fff8000
+#define	EXCITE_SIZE_PCI_IO	(8 << 10)
+#define EXCITE_PHYS_PCI_IO	CPHYSADDR(EXCITE_OFFS_PCI_IO)
+#define EXCITE_ADDR_PCI_IO 	CKSEG1ADDR(EXCITE_OFFS_PCI_IO)
+
+#define EXCITE_OFFS_TITAN	0x1fff0000
+#define EXCITE_SIZE_TITAN	(32 << 10)
+#define EXCITE_PHYS_TITAN	CPHYSADDR(EXCITE_OFFS_TITAN)
+#define EXCITE_ADDR_TITAN	CKSEG1ADDR(EXCITE_OFFS_TITAN)
+
+#define EXCITE_OFFS_PCI_MEM	0x1ffe0000
+#define EXCITE_SIZE_PCI_MEM	(64 << 10)
+#define EXCITE_PHYS_PCI_MEM	CPHYSADDR(EXCITE_OFFS_PCI_MEM)
+#define EXCITE_ADDR_PCI_MEM	CKSEG1ADDR(EXCITE_OFFS_PCI_MEM)
+
+#define EXCITE_OFFS_FPGA	0x1ffdc000
+#define EXCITE_SIZE_FPGA	(16 << 10)
+#define EXCITE_PHYS_FPGA	CPHYSADDR(EXCITE_OFFS_FPGA)
+#define EXCITE_ADDR_FPGA	CKSEG1ADDR(EXCITE_OFFS_FPGA)
+
+#define EXCITE_OFFS_NAND	0x1ffd8000
+#define EXCITE_SIZE_NAND	(16 << 10)
+#define EXCITE_PHYS_NAND	CPHYSADDR(EXCITE_OFFS_NAND)
+#define EXCITE_ADDR_NAND	CKSEG1ADDR(EXCITE_OFFS_NAND)
+
+#define EXCITE_OFFS_BOOTROM	0x1f000000
+#define EXCITE_SIZE_BOOTROM	(8 << 20)
+#define EXCITE_PHYS_BOOTROM	CPHYSADDR(EXCITE_OFFS_BOOTROM)
+#define EXCITE_ADDR_BOOTROM	CKSEG1ADDR(EXCITE_OFFS_BOOTROM)
+
+/* FPGA address offsets */
+#define EXCITE_FPGA_DPR		0x0104	/* dual-ported ram */
+#define EXCITE_FPGA_SYSCTL	0x0200	/* system control register block */
+
+#endif /* __EXCITE_H__ */
diff --git a/include/asm-mips/mach-excite/excite_nandflash.h b/include/asm-mips/mach-excite/excite_nandflash.h
new file mode 100644
index 000000000..c4cf61406
--- /dev/null
+++ b/include/asm-mips/mach-excite/excite_nandflash.h
@@ -0,0 +1,7 @@
+#ifndef __EXCITE_NANDFLASH_H__
+#define __EXCITE_NANDFLASH_H__
+
+/* Resource names */
+#define EXCITE_NANDFLASH_RESOURCE_REGS	"excite_nandflash_regs"
+
+#endif /* __EXCITE_NANDFLASH_H__ */
diff --git a/include/asm-mips/mach-excite/rm9k_eth.h b/include/asm-mips/mach-excite/rm9k_eth.h
new file mode 100644
index 000000000..94705a46f
--- /dev/null
+++ b/include/asm-mips/mach-excite/rm9k_eth.h
@@ -0,0 +1,23 @@
+#if !defined(__RM9K_ETH_H__)
+#define __RM9K_ETH_H__
+
+#define RM9K_GE_NAME			"rm9k_ge"
+
+/* Resource names */
+#define RM9K_GE_RESOURCE_MAC      	"rm9k_ge_mac"
+#define RM9K_GE_RESOURCE_MSTAT      	"rm9k_ge_mstat"
+#define RM9K_GE_RESOURCE_PKTPROC	"rm9k_ge_pktproc"
+#define RM9K_GE_RESOURCE_XDMA		"rm9k_ge_xdma"
+#define RM9K_GE_RESOURCE_FIFO_RX  	"rm9k_ge_fifo_rx"
+#define RM9K_GE_RESOURCE_FIFO_TX  	"rm9k_ge_fifo_tx"
+#define RM9K_GE_RESOURCE_FIFOMEM_RX  	"rm9k_ge_fifo_memory_rx"
+#define RM9K_GE_RESOURCE_FIFOMEM_TX  	"rm9k_ge_fifo_memory_tx"
+#define RM9K_GE_RESOURCE_PHY      	"rm9k_ge_phy"
+#define RM9K_GE_RESOURCE_DMADESC_RX  	"rm9k_ge_dmadesc_rx"
+#define RM9K_GE_RESOURCE_DMADESC_TX  	"rm9k_ge_dmadesc_tx"
+#define RM9K_GE_RESOURCE_IRQ_MAIN	"rm9k_ge_irq_main"
+#define RM9K_GE_RESOURCE_IRQ_PHY	"rm9k_ge_irq_phy"
+#define RM9K_GE_RESOURCE_GPI_SLICE	"rm9k_ge_gpi_slice"
+#define RM9K_GE_RESOURCE_MDIO_CHANNEL	"rm9k_ge_mdio_channel"
+
+#endif /* !defined(__RM9K_ETH_H__) */
diff --git a/include/asm-mips/mach-excite/rm9k_wdt.h b/include/asm-mips/mach-excite/rm9k_wdt.h
new file mode 100644
index 000000000..3fa3c08d2
--- /dev/null
+++ b/include/asm-mips/mach-excite/rm9k_wdt.h
@@ -0,0 +1,12 @@
+#ifndef __RM9K_WDT_H__
+#define __RM9K_WDT_H__
+
+/* Device name */
+#define WDT_NAME		"wdt_gpi"
+
+/* Resource names */
+#define WDT_RESOURCE_REGS	"excite_watchdog_regs"
+#define WDT_RESOURCE_IRQ	"excite_watchdog_irq"
+#define WDT_RESOURCE_COUNTER	"excite_watchdog_counter"
+
+#endif /* __RM9K_WDT_H__ */
diff --git a/include/asm-mips/mach-excite/rm9k_xicap.h b/include/asm-mips/mach-excite/rm9k_xicap.h
new file mode 100644
index 000000000..009577734
--- /dev/null
+++ b/include/asm-mips/mach-excite/rm9k_xicap.h
@@ -0,0 +1,16 @@
+#ifndef __EXCITE_XICAP_H__
+#define __EXCITE_XICAP_H__
+
+
+/* Resource names */
+#define XICAP_RESOURCE_FIFO_RX		"xicap_fifo_rx"
+#define XICAP_RESOURCE_FIFO_TX		"xicap_fifo_tx"
+#define XICAP_RESOURCE_XDMA 		"xicap_xdma"
+#define XICAP_RESOURCE_DMADESC		"xicap_dmadesc"
+#define XICAP_RESOURCE_PKTPROC  	"xicap_pktproc"
+#define XICAP_RESOURCE_IRQ		"xicap_irq"
+#define XICAP_RESOURCE_GPI_SLICE	"xicap_gpi_slice"
+#define XICAP_RESOURCE_FIFO_BLK		"xicap_fifo_blocks"
+#define XICAP_RESOURCE_PKT_STREAM	"xicap_pkt_stream"
+
+#endif /* __EXCITE_XICAP_H__ */
diff --git a/include/asm-mips/mach-wrppmc/mach-gt64120.h b/include/asm-mips/mach-wrppmc/mach-gt64120.h
new file mode 100644
index 000000000..ba9205a04
--- /dev/null
+++ b/include/asm-mips/mach-wrppmc/mach-gt64120.h
@@ -0,0 +1,84 @@
+/*
+ * This is a direct copy of the ev96100.h file, with a global
+ * search and replace.  The numbers are the same.
+ *
+ * The reason I'm duplicating this is so that the 64120/96100
+ * defines won't be confusing in the source code.
+ */
+#ifndef __ASM_MIPS_GT64120_H
+#define __ASM_MIPS_GT64120_H
+
+/*
+ * This is the CPU physical memory map of PPMC Board:
+ *
+ *    0x00000000-0x03FFFFFF      - 64MB SDRAM (SCS[0]#)
+ *    0x1C000000-0x1C000000      - LED (CS0)
+ *    0x1C800000-0x1C800007      - UART 16550 port (CS1)
+ *    0x1F000000-0x1F000000      - MailBox (CS3)
+ *    0x1FC00000-0x20000000      - 4MB Flash (BOOT CS)
+ */
+
+#define WRPPMC_SDRAM_SCS0_BASE	0x00000000
+#define WRPPMC_SDRAM_SCS0_SIZE	0x04000000
+
+#define WRPPMC_UART16550_BASE	0x1C800000
+#define WRPPMC_UART16550_CLOCK	3686400 /* 3.68MHZ */
+
+#define WRPPMC_LED_BASE		0x1C000000
+#define WRPPMC_MBOX_BASE	0x1F000000
+
+#define WRPPMC_BOOTROM_BASE	0x1FC00000
+#define WRPPMC_BOOTROM_SIZE	0x00400000 /* 4M Flash */
+
+#define WRPPMC_MIPS_TIMER_IRQ	7 /* MIPS compare/count timer interrupt */
+#define WRPPMC_UART16550_IRQ	6
+#define WRPPMC_PCI_INTA_IRQ	3
+
+/*
+ * PCI Bus I/O and Memory resources allocation
+ *
+ * NOTE: We only have PCI_0 hose interface
+ */
+#define GT_PCI_MEM_BASE	0x13000000UL
+#define GT_PCI_MEM_SIZE	0x02000000UL
+#define GT_PCI_IO_BASE	0x11000000UL
+#define GT_PCI_IO_SIZE	0x02000000UL
+#define GT_ISA_IO_BASE	PCI_IO_BASE
+
+/*
+ * PCI interrupts will come in on either the INTA or INTD interrups lines,
+ * which are mapped to the #2 and #5 interrupt pins of the MIPS.  On our
+ * boards, they all either come in on IntD or they all come in on IntA, they
+ * aren't mixed. There can be numerous PCI interrupts, so we keep a list of the
+ * "requested" interrupt numbers and go through the list whenever we get an
+ * IntA/D.
+ *
+ * Interrupts < 8 are directly wired to the processor; PCI INTA is 8 and
+ * INTD is 11.
+ */
+#define GT_TIMER	4
+#define GT_INTA		2
+#define GT_INTD		5
+
+#ifndef __ASSEMBLY__
+
+/*
+ * GT64120 internal register space base address
+ */
+extern unsigned long gt64120_base;
+
+#define GT64120_BASE	(gt64120_base)
+
+/* define WRPPMC_EARLY_DEBUG to enable early output something to UART */
+#undef WRPPMC_EARLY_DEBUG
+
+#ifdef WRPPMC_EARLY_DEBUG
+extern void wrppmc_led_on(int mask);
+extern void wrppmc_led_off(int mask);
+extern void wrppmc_early_printk(const char *fmt, ...);
+#else
+#define wrppmc_early_printk(fmt, ...) do {} while (0)
+#endif /* WRPPMC_EARLY_DEBUG */
+
+#endif /* __ASSEMBLY__ */
+#endif /* __ASM_MIPS_GT64120_H */
diff --git a/include/asm-mips/rm9k-ocd.h b/include/asm-mips/rm9k-ocd.h
new file mode 100644
index 000000000..b0b80d9ec
--- /dev/null
+++ b/include/asm-mips/rm9k-ocd.h
@@ -0,0 +1,56 @@
+/*
+ *  Copyright (C) 2004 by Basler Vision Technologies AG
+ *  Author: Thomas Koeller <thomas.koeller@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
+ */
+
+#if !defined(_ASM_RM9K_OCD_H)
+#define _ASM_RM9K_OCD_H
+
+#include <linux/types.h>
+#include <linux/spinlock.h>
+#include <asm/io.h>
+
+extern volatile void __iomem * const ocd_base;
+extern volatile void __iomem * const titan_base;
+
+#define ocd_addr(__x__)		(ocd_base + (__x__))
+#define titan_addr(__x__)	(titan_base + (__x__))
+#define scram_addr(__x__)	(scram_base + (__x__))
+
+/* OCD register access */
+#define ocd_readl(__offs__) __raw_readl(ocd_addr(__offs__))
+#define ocd_readw(__offs__) __raw_readw(ocd_addr(__offs__))
+#define ocd_readb(__offs__) __raw_readb(ocd_addr(__offs__))
+#define ocd_writel(__val__, __offs__) \
+	__raw_writel((__val__), ocd_addr(__offs__))
+#define ocd_writew(__val__, __offs__) \
+	__raw_writew((__val__), ocd_addr(__offs__))
+#define ocd_writeb(__val__, __offs__) \
+	__raw_writeb((__val__), ocd_addr(__offs__))
+
+/* TITAN register access - 32 bit-wide only */
+#define titan_readl(__offs__) __raw_readl(titan_addr(__offs__))
+#define titan_writel(__val__, __offs__) \
+	__raw_writel((__val__), titan_addr(__offs__))
+
+/* Protect access to shared TITAN registers */
+extern spinlock_t titan_lock;
+extern int titan_irqflags;
+#define lock_titan_regs() spin_lock_irqsave(&titan_lock, titan_irqflags)
+#define unlock_titan_regs() spin_unlock_irqrestore(&titan_lock, titan_irqflags)
+
+#endif	/* !defined(_ASM_RM9K_OCD_H) */
diff --git a/include/asm-mips/sn/fru.h b/include/asm-mips/sn/fru.h
new file mode 100644
index 000000000..b3e360672
--- /dev/null
+++ b/include/asm-mips/sn/fru.h
@@ -0,0 +1,44 @@
+/*
+ * 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.
+ *
+ * Derived from IRIX <sys/SN/SN0/sn0_fru.h>
+ *
+ * Copyright (C) 1992 - 1997, 1999 Silcon Graphics, Inc.
+ * Copyright (C) 1999, 2006 Ralf Baechle (ralf@linux-mips)
+ */
+#ifndef __ASM_SN_FRU_H
+#define __ASM_SN_FRU_H
+
+#define MAX_DIMMS			8	 /* max # of dimm banks */
+#define MAX_PCIDEV			8	 /* max # of pci devices on a pci bus */
+
+typedef unsigned char confidence_t;
+
+typedef struct kf_mem_s {
+	confidence_t km_confidence; /* confidence level that the memory is bad
+				     * is this necessary ?
+				     */
+	confidence_t km_dimm[MAX_DIMMS];
+	                            /* confidence level that dimm[i] is bad
+				     *I think this is the right number
+				     */
+
+} kf_mem_t;
+
+typedef struct kf_cpu_s {
+	confidence_t  	kc_confidence; /* confidence level that cpu is bad */
+	confidence_t  	kc_icache; /* confidence level that instr. cache is bad */
+	confidence_t  	kc_dcache; /* confidence level that data   cache is bad */
+	confidence_t  	kc_scache; /* confidence level that sec.   cache is bad */
+	confidence_t	kc_sysbus; /* confidence level that sysad/cmd/state bus is bad */
+} kf_cpu_t;
+
+typedef struct kf_pci_bus_s {
+	confidence_t	kpb_belief;	/* confidence level  that the  pci bus is bad */
+	confidence_t	kpb_pcidev_belief[MAX_PCIDEV];
+	                                /* confidence level that the pci dev is bad */
+} kf_pci_bus_t;
+
+#endif /* __ASM_SN_FRU_H */
diff --git a/include/asm-mips/vr41xx/irq.h b/include/asm-mips/vr41xx/irq.h
new file mode 100644
index 000000000..d315dfbc0
--- /dev/null
+++ b/include/asm-mips/vr41xx/irq.h
@@ -0,0 +1,101 @@
+/*
+ * include/asm-mips/vr41xx/irq.h
+ *
+ * Interrupt numbers for NEC VR4100 series.
+ *
+ * Copyright (C) 1999 Michael Klar
+ * Copyright (C) 2001, 2002 Paul Mundt
+ * Copyright (C) 2002 MontaVista Software, Inc.
+ * Copyright (C) 2002 TimeSys Corp.
+ * Copyright (C) 2003-2006 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.
+ */
+#ifndef __NEC_VR41XX_IRQ_H
+#define __NEC_VR41XX_IRQ_H
+
+/*
+ * CPU core Interrupt Numbers
+ */
+#define MIPS_CPU_IRQ_BASE	0
+#define MIPS_CPU_IRQ(x)		(MIPS_CPU_IRQ_BASE + (x))
+#define MIPS_SOFTINT0_IRQ	MIPS_CPU_IRQ(0)
+#define MIPS_SOFTINT1_IRQ	MIPS_CPU_IRQ(1)
+#define INT0_IRQ		MIPS_CPU_IRQ(2)
+#define INT1_IRQ		MIPS_CPU_IRQ(3)
+#define INT2_IRQ		MIPS_CPU_IRQ(4)
+#define INT3_IRQ		MIPS_CPU_IRQ(5)
+#define INT4_IRQ		MIPS_CPU_IRQ(6)
+#define TIMER_IRQ		MIPS_CPU_IRQ(7)
+
+/*
+ * SYINT1 Interrupt Numbers
+ */
+#define SYSINT1_IRQ_BASE	8
+#define SYSINT1_IRQ(x)		(SYSINT1_IRQ_BASE + (x))
+#define BATTRY_IRQ		SYSINT1_IRQ(0)
+#define POWER_IRQ		SYSINT1_IRQ(1)
+#define RTCLONG1_IRQ		SYSINT1_IRQ(2)
+#define ELAPSEDTIME_IRQ		SYSINT1_IRQ(3)
+/* RFU */
+#define PIU_IRQ			SYSINT1_IRQ(5)
+#define AIU_IRQ			SYSINT1_IRQ(6)
+#define KIU_IRQ			SYSINT1_IRQ(7)
+#define GIUINT_IRQ		SYSINT1_IRQ(8)
+#define SIU_IRQ			SYSINT1_IRQ(9)
+#define BUSERR_IRQ		SYSINT1_IRQ(10)
+#define SOFTINT_IRQ		SYSINT1_IRQ(11)
+#define CLKRUN_IRQ		SYSINT1_IRQ(12)
+#define DOZEPIU_IRQ		SYSINT1_IRQ(13)
+#define SYSINT1_IRQ_LAST	DOZEPIU_IRQ
+
+/*
+ * SYSINT2 Interrupt Numbers
+ */
+#define SYSINT2_IRQ_BASE	24
+#define SYSINT2_IRQ(x)		(SYSINT2_IRQ_BASE + (x))
+#define RTCLONG2_IRQ		SYSINT2_IRQ(0)
+#define LED_IRQ			SYSINT2_IRQ(1)
+#define HSP_IRQ			SYSINT2_IRQ(2)
+#define TCLOCK_IRQ		SYSINT2_IRQ(3)
+#define FIR_IRQ			SYSINT2_IRQ(4)
+#define CEU_IRQ			SYSINT2_IRQ(4)	/* same number as FIR_IRQ */
+#define DSIU_IRQ		SYSINT2_IRQ(5)
+#define PCI_IRQ			SYSINT2_IRQ(6)
+#define SCU_IRQ			SYSINT2_IRQ(7)
+#define CSI_IRQ			SYSINT2_IRQ(8)
+#define BCU_IRQ			SYSINT2_IRQ(9)
+#define ETHERNET_IRQ		SYSINT2_IRQ(10)
+#define SYSINT2_IRQ_LAST	ETHERNET_IRQ
+
+/*
+ * GIU Interrupt Numbers
+ */
+#define GIU_IRQ_BASE		40
+#define GIU_IRQ(x)		(GIU_IRQ_BASE + (x))	/* IRQ 40-71 */
+#define GIU_IRQ_LAST		GIU_IRQ(31)
+
+/*
+ * VRC4173 Interrupt Numbers
+ */
+#define VRC4173_IRQ_BASE	72
+#define VRC4173_IRQ(x)		(VRC4173_IRQ_BASE + (x))
+#define VRC4173_USB_IRQ		VRC4173_IRQ(0)
+#define VRC4173_PCMCIA2_IRQ	VRC4173_IRQ(1)
+#define VRC4173_PCMCIA1_IRQ	VRC4173_IRQ(2)
+#define VRC4173_PS2CH2_IRQ	VRC4173_IRQ(3)
+#define VRC4173_PS2CH1_IRQ	VRC4173_IRQ(4)
+#define VRC4173_PIU_IRQ		VRC4173_IRQ(5)
+#define VRC4173_AIU_IRQ		VRC4173_IRQ(6)
+#define VRC4173_KIU_IRQ		VRC4173_IRQ(7)
+#define VRC4173_GIU_IRQ		VRC4173_IRQ(8)
+#define VRC4173_AC97_IRQ	VRC4173_IRQ(9)
+#define VRC4173_AC97INT1_IRQ	VRC4173_IRQ(10)
+/* RFU */
+#define VRC4173_DOZEPIU_IRQ	VRC4173_IRQ(13)
+#define VRC4173_IRQ_LAST	VRC4173_DOZEPIU_IRQ
+
+#endif /* __NEC_VR41XX_IRQ_H */
diff --git a/include/asm-parisc/Kbuild b/include/asm-parisc/Kbuild
new file mode 100644
index 000000000..c68e1680d
--- /dev/null
+++ b/include/asm-parisc/Kbuild
@@ -0,0 +1 @@
+include include/asm-generic/Kbuild.asm
diff --git a/include/asm-powerpc/Kbuild b/include/asm-powerpc/Kbuild
new file mode 100644
index 000000000..982784995
--- /dev/null
+++ b/include/asm-powerpc/Kbuild
@@ -0,0 +1,41 @@
+include include/asm-generic/Kbuild.asm
+
+header-y += auxvec.h
+header-y += ioctls.h
+header-y += mman.h
+header-y += sembuf.h
+header-y += siginfo.h
+header-y += stat.h
+header-y += errno.h
+header-y += ipcbuf.h
+header-y += msgbuf.h
+header-y += shmbuf.h
+header-y += socket.h
+header-y += termbits.h
+header-y += fcntl.h
+header-y += ipc.h
+header-y += poll.h
+header-y += shmparam.h
+header-y += sockios.h
+header-y += ucontext.h
+header-y += ioctl.h
+header-y += linkage.h
+header-y += resource.h
+header-y += sigcontext.h
+header-y += statfs.h
+
+unifdef-y += a.out.h
+unifdef-y += asm-compat.h
+unifdef-y += bootx.h
+unifdef-y += byteorder.h
+unifdef-y += cputable.h
+unifdef-y += elf.h
+unifdef-y += nvram.h
+unifdef-y += param.h
+unifdef-y += posix_types.h
+unifdef-y += ptrace.h
+unifdef-y += seccomp.h
+unifdef-y += signal.h
+unifdef-y += termios.h
+unifdef-y += types.h
+unifdef-y += unistd.h
diff --git a/include/asm-powerpc/immap_86xx.h b/include/asm-powerpc/immap_86xx.h
new file mode 100644
index 000000000..d905b6622
--- /dev/null
+++ b/include/asm-powerpc/immap_86xx.h
@@ -0,0 +1,199 @@
+/*
+ * MPC86xx Internal Memory Map
+ *
+ * Author: Jeff Brown
+ *
+ * Copyright 2004 Freescale Semiconductor, Inc
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ */
+
+#ifndef __ASM_POWERPC_IMMAP_86XX_H__
+#define __ASM_POWERPC_IMMAP_86XX_H__
+#ifdef __KERNEL__
+
+/* Eventually this should define all the IO block registers in 86xx */
+
+/* PCI Registers */
+typedef struct ccsr_pci {
+	uint	cfg_addr;	/* 0x.000 - PCI Configuration Address Register */
+	uint	cfg_data;	/* 0x.004 - PCI Configuration Data Register */
+	uint	int_ack;	/* 0x.008 - PCI Interrupt Acknowledge Register */
+	char	res1[3060];
+	uint	potar0;		/* 0x.c00 - PCI Outbound Transaction Address Register 0 */
+	uint	potear0;	/* 0x.c04 - PCI Outbound Translation Extended Address Register 0 */
+	uint	powbar0;	/* 0x.c08 - PCI Outbound Window Base Address Register 0 */
+	char	res2[4];
+	uint	powar0;		/* 0x.c10 - PCI Outbound Window Attributes Register 0 */
+	char	res3[12];
+	uint	potar1;		/* 0x.c20 - PCI Outbound Transaction Address Register 1 */
+	uint	potear1;	/* 0x.c24 - PCI Outbound Translation Extended Address Register 1 */
+	uint	powbar1;	/* 0x.c28 - PCI Outbound Window Base Address Register 1 */
+	char	res4[4];
+	uint	powar1;		/* 0x.c30 - PCI Outbound Window Attributes Register 1 */
+	char	res5[12];
+	uint	potar2;		/* 0x.c40 - PCI Outbound Transaction Address Register 2 */
+	uint	potear2;	/* 0x.c44 - PCI Outbound Translation Extended Address Register 2 */
+	uint	powbar2;	/* 0x.c48 - PCI Outbound Window Base Address Register 2 */
+	char	res6[4];
+	uint	powar2;		/* 0x.c50 - PCI Outbound Window Attributes Register 2 */
+	char	res7[12];
+	uint	potar3;		/* 0x.c60 - PCI Outbound Transaction Address Register 3 */
+	uint	potear3;	/* 0x.c64 - PCI Outbound Translation Extended Address Register 3 */
+	uint	powbar3;	/* 0x.c68 - PCI Outbound Window Base Address Register 3 */
+	char	res8[4];
+	uint	powar3;		/* 0x.c70 - PCI Outbound Window Attributes Register 3 */
+	char	res9[12];
+	uint	potar4;		/* 0x.c80 - PCI Outbound Transaction Address Register 4 */
+	uint	potear4;	/* 0x.c84 - PCI Outbound Translation Extended Address Register 4 */
+	uint	powbar4;	/* 0x.c88 - PCI Outbound Window Base Address Register 4 */
+	char	res10[4];
+	uint	powar4;		/* 0x.c90 - PCI Outbound Window Attributes Register 4 */
+	char	res11[268];
+	uint	pitar3;		/* 0x.da0 - PCI Inbound Translation Address Register 3  */
+	char	res12[4];
+	uint	piwbar3;	/* 0x.da8 - PCI Inbound Window Base Address Register 3 */
+	uint	piwbear3;	/* 0x.dac - PCI Inbound Window Base Extended Address Register 3 */
+	uint	piwar3;		/* 0x.db0 - PCI Inbound Window Attributes Register 3 */
+	char	res13[12];
+	uint	pitar2;		/* 0x.dc0 - PCI Inbound Translation Address Register 2  */
+	char	res14[4];
+	uint	piwbar2;	/* 0x.dc8 - PCI Inbound Window Base Address Register 2 */
+	uint	piwbear2;	/* 0x.dcc - PCI Inbound Window Base Extended Address Register 2 */
+	uint	piwar2;		/* 0x.dd0 - PCI Inbound Window Attributes Register 2 */
+	char	res15[12];
+	uint	pitar1;		/* 0x.de0 - PCI Inbound Translation Address Register 1  */
+	char	res16[4];
+	uint	piwbar1;	/* 0x.de8 - PCI Inbound Window Base Address Register 1 */
+	char	res17[4];
+	uint	piwar1;		/* 0x.df0 - PCI Inbound Window Attributes Register 1 */
+	char	res18[12];
+	uint	err_dr;		/* 0x.e00 - PCI Error Detect Register */
+	uint	err_cap_dr;	/* 0x.e04 - PCI Error Capture Disable Register */
+	uint	err_en;		/* 0x.e08 - PCI Error Enable Register */
+	uint	err_attrib;	/* 0x.e0c - PCI Error Attributes Capture Register */
+	uint	err_addr;	/* 0x.e10 - PCI Error Address Capture Register */
+	uint	err_ext_addr;	/* 0x.e14 - PCI Error Extended Address Capture Register */
+	uint	err_dl;		/* 0x.e18 - PCI Error Data Low Capture Register */
+	uint	err_dh;		/* 0x.e1c - PCI Error Data High Capture Register */
+	uint	gas_timr;	/* 0x.e20 - PCI Gasket Timer Register */
+	uint	pci_timr;	/* 0x.e24 - PCI Timer Register */
+	char	res19[472];
+} ccsr_pci_t;
+
+/* PCI Express Registers */
+typedef struct ccsr_pex {
+	uint    pex_config_addr;        /* 0x.000 - PCI Express Configuration Address Register */
+	uint    pex_config_data;        /* 0x.004 - PCI Express Configuration Data Register */
+	char    res1[4];
+	uint    pex_otb_cpl_tor;        /* 0x.00c - PCI Express Outbound completion timeout register */
+	uint    pex_conf_tor;           /* 0x.010 - PCI Express configuration timeout register */
+	char    res2[12];
+	uint    pex_pme_mes_dr;         /* 0x.020 - PCI Express PME and message detect register */
+	uint    pex_pme_mes_disr;       /* 0x.024 - PCI Express PME and message disable register */
+	uint    pex_pme_mes_ier;        /* 0x.028 - PCI Express PME and message interrupt enable register */
+	uint    pex_pmcr;               /* 0x.02c - PCI Express power management command register */
+	char    res3[3024];
+	uint    pexotar0;               /* 0x.c00 - PCI Express outbound translation address register 0 */
+	uint    pexotear0;              /* 0x.c04 - PCI Express outbound translation extended address register 0*/
+	char    res4[8];
+	uint    pexowar0;               /* 0x.c10 - PCI Express outbound window attributes register 0*/
+	char    res5[12];
+	uint    pexotar1;               /* 0x.c20 - PCI Express outbound translation address register 1 */
+	uint    pexotear1;              /* 0x.c24 - PCI Express outbound translation extended address register 1*/
+	uint    pexowbar1;              /* 0x.c28 - PCI Express outbound window base address register 1*/
+	char    res6[4];
+	uint    pexowar1;               /* 0x.c30 - PCI Express outbound window attributes register 1*/
+	char    res7[12];
+	uint    pexotar2;               /* 0x.c40 - PCI Express outbound translation address register 2 */
+	uint    pexotear2;              /* 0x.c44 - PCI Express outbound translation extended address register 2*/
+	uint    pexowbar2;              /* 0x.c48 - PCI Express outbound window base address register 2*/
+	char    res8[4];
+	uint    pexowar2;               /* 0x.c50 - PCI Express outbound window attributes register 2*/
+	char    res9[12];
+	uint    pexotar3;               /* 0x.c60 - PCI Express outbound translation address register 3 */
+	uint    pexotear3;              /* 0x.c64 - PCI Express outbound translation extended address register 3*/
+	uint    pexowbar3;              /* 0x.c68 - PCI Express outbound window base address register 3*/
+	char    res10[4];
+	uint    pexowar3;               /* 0x.c70 - PCI Express outbound window attributes register 3*/
+	char    res11[12];
+	uint    pexotar4;               /* 0x.c80 - PCI Express outbound translation address register 4 */
+	uint    pexotear4;              /* 0x.c84 - PCI Express outbound translation extended address register 4*/
+	uint    pexowbar4;              /* 0x.c88 - PCI Express outbound window base address register 4*/
+	char    res12[4];
+	uint    pexowar4;               /* 0x.c90 - PCI Express outbound window attributes register 4*/
+	char    res13[12];
+	char    res14[256];
+	uint    pexitar3;               /* 0x.da0 - PCI Express inbound translation address register 3 */
+	char    res15[4];
+	uint    pexiwbar3;              /* 0x.da8 - PCI Express inbound window base address register 3 */
+	uint    pexiwbear3;             /* 0x.dac - PCI Express inbound window base extended address register 3 */
+	uint    pexiwar3;               /* 0x.db0 - PCI Express inbound window attributes register 3 */
+	char    res16[12];
+	uint    pexitar2;               /* 0x.dc0 - PCI Express inbound translation address register 2 */
+	char    res17[4];
+	uint    pexiwbar2;              /* 0x.dc8 - PCI Express inbound window base address register 2 */
+	uint    pexiwbear2;             /* 0x.dcc - PCI Express inbound window base extended address register 2 */
+	uint    pexiwar2;               /* 0x.dd0 - PCI Express inbound window attributes register 2 */
+	char    res18[12];
+	uint    pexitar1;               /* 0x.de0 - PCI Express inbound translation address register 2 */
+	char    res19[4];
+	uint    pexiwbar1;              /* 0x.de8 - PCI Express inbound window base address register 2 */
+	uint    pexiwbear1;             /* 0x.dec - PCI Express inbound window base extended address register 2 */
+	uint    pexiwar1;               /* 0x.df0 - PCI Express inbound window attributes register 2 */
+	char    res20[12];
+	uint    pex_err_dr;             /* 0x.e00 - PCI Express error detect register */
+	char    res21[4];
+	uint    pex_err_en;             /* 0x.e08 - PCI Express error interrupt enable register */
+	char    res22[4];
+	uint    pex_err_disr;           /* 0x.e10 - PCI Express error disable register */
+	char    res23[12];
+	uint    pex_err_cap_stat;       /* 0x.e20 - PCI Express error capture status register */
+	char    res24[4];
+	uint    pex_err_cap_r0;         /* 0x.e28 - PCI Express error capture register 0 */
+	uint    pex_err_cap_r1;         /* 0x.e2c - PCI Express error capture register 0 */
+	uint    pex_err_cap_r2;         /* 0x.e30 - PCI Express error capture register 0 */
+	uint    pex_err_cap_r3;         /* 0x.e34 - PCI Express error capture register 0 */
+} ccsr_pex_t;
+
+/* Global Utility Registers */
+typedef struct ccsr_guts {
+	uint	porpllsr;	/* 0x.0000 - POR PLL Ratio Status Register */
+	uint	porbmsr;	/* 0x.0004 - POR Boot Mode Status Register */
+	uint	porimpscr;	/* 0x.0008 - POR I/O Impedance Status and Control Register */
+	uint	pordevsr;	/* 0x.000c - POR I/O Device Status Register */
+	uint	pordbgmsr;	/* 0x.0010 - POR Debug Mode Status Register */
+	char	res1[12];
+	uint	gpporcr;	/* 0x.0020 - General-Purpose POR Configuration Register */
+	char	res2[12];
+	uint	gpiocr;		/* 0x.0030 - GPIO Control Register */
+	char	res3[12];
+	uint	gpoutdr;	/* 0x.0040 - General-Purpose Output Data Register */
+	char	res4[12];
+	uint	gpindr;		/* 0x.0050 - General-Purpose Input Data Register */
+	char	res5[12];
+	uint	pmuxcr;		/* 0x.0060 - Alternate Function Signal Multiplex Control */
+	char	res6[12];
+	uint	devdisr;	/* 0x.0070 - Device Disable Control */
+	char	res7[12];
+	uint	powmgtcsr;	/* 0x.0080 - Power Management Status and Control Register */
+	char	res8[12];
+	uint	mcpsumr;	/* 0x.0090 - Machine Check Summary Register */
+	char	res9[12];
+	uint	pvr;		/* 0x.00a0 - Processor Version Register */
+	uint	svr;		/* 0x.00a4 - System Version Register */
+	char	res10[3416];
+	uint	clkocr;		/* 0x.0e00 - Clock Out Select Register */
+	char	res11[12];
+	uint	ddrdllcr;	/* 0x.0e10 - DDR DLL Control Register */
+	char	res12[12];
+	uint	lbcdllcr;	/* 0x.0e20 - LBC DLL Control Register */
+	char	res13[61916];
+} ccsr_guts_t;
+
+#endif /* __ASM_POWERPC_IMMAP_86XX_H__ */
+#endif /* __KERNEL__ */
diff --git a/include/asm-powerpc/irqflags.h b/include/asm-powerpc/irqflags.h
new file mode 100644
index 000000000..7970cbaea
--- /dev/null
+++ b/include/asm-powerpc/irqflags.h
@@ -0,0 +1,31 @@
+/*
+ * include/asm-powerpc/irqflags.h
+ *
+ * IRQ flags handling
+ *
+ * This file gets included from lowlevel asm headers too, to provide
+ * wrapped versions of the local_irq_*() APIs, based on the
+ * raw_local_irq_*() macros from the lowlevel headers.
+ */
+#ifndef _ASM_IRQFLAGS_H
+#define _ASM_IRQFLAGS_H
+
+/*
+ * Get definitions for raw_local_save_flags(x), etc.
+ */
+#include <asm-powerpc/hw_irq.h>
+
+/*
+ * Do the CPU's IRQ-state tracing from assembly code. We call a
+ * C function, so save all the C-clobbered registers:
+ */
+#ifdef CONFIG_TRACE_IRQFLAGS
+
+#error No support on PowerPC yet for CONFIG_TRACE_IRQFLAGS
+
+#else
+# define TRACE_IRQS_ON
+# define TRACE_IRQS_OFF
+#endif
+
+#endif
diff --git a/include/asm-powerpc/iseries/iommu.h b/include/asm-powerpc/iseries/iommu.h
new file mode 100644
index 000000000..0edbfe10c
--- /dev/null
+++ b/include/asm-powerpc/iseries/iommu.h
@@ -0,0 +1,35 @@
+#ifndef _ASM_POWERPC_ISERIES_IOMMU_H
+#define _ASM_POWERPC_ISERIES_IOMMU_H
+
+/*
+ * Copyright (C) 2005  Stephen Rothwell, 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; 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
+ */
+
+struct device_node;
+struct iommu_table;
+
+/* Creates table for an individual device node */
+extern void iommu_devnode_init_iSeries(struct device_node *dn);
+
+/* Get table parameters from HV */
+extern void iommu_table_getparms_iSeries(unsigned long busno,
+		unsigned char slotno, unsigned char virtbus,
+		struct iommu_table *tbl);
+
+#endif /* _ASM_POWERPC_ISERIES_IOMMU_H */
diff --git a/include/asm-powerpc/mpc86xx.h b/include/asm-powerpc/mpc86xx.h
new file mode 100644
index 000000000..b85df45b1
--- /dev/null
+++ b/include/asm-powerpc/mpc86xx.h
@@ -0,0 +1,39 @@
+/*
+ * MPC86xx definitions
+ *
+ * Author: Jeff Brown
+ *
+ * Copyright 2004 Freescale Semiconductor, Inc
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+#ifdef __KERNEL__
+#ifndef __ASM_POWERPC_MPC86xx_H__
+#define __ASM_POWERPC_MPC86xx_H__
+
+#include <asm/mmu.h>
+
+#ifdef CONFIG_PPC_86xx
+
+#define _IO_BASE        isa_io_base
+#define _ISA_MEM_BASE   isa_mem_base
+#ifdef CONFIG_PCI
+#define PCI_DRAM_OFFSET pci_dram_offset
+#endif
+
+#define CPU0_BOOT_RELEASE 0x01000000
+#define CPU1_BOOT_RELEASE 0x02000000
+#define CPU_ALL_RELEASED (CPU0_BOOT_RELEASE | CPU1_BOOT_RELEASE)
+#define MCM_PORT_CONFIG_OFFSET 0x1010
+
+/* Offset from CCSRBAR */
+#define MPC86xx_MCM_OFFSET      (0x00000)
+#define MPC86xx_MCM_SIZE        (0x02000)
+
+#endif /* CONFIG_PPC_86xx */
+#endif /* __ASM_POWERPC_MPC86xx_H__ */
+#endif /* __KERNEL__ */
diff --git a/include/asm-powerpc/spu_priv1.h b/include/asm-powerpc/spu_priv1.h
new file mode 100644
index 000000000..300c458b6
--- /dev/null
+++ b/include/asm-powerpc/spu_priv1.h
@@ -0,0 +1,182 @@
+/*
+ * Defines an spu hypervisor abstraction layer.
+ *
+ *  Copyright 2006 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
+ */
+
+#if !defined(_SPU_PRIV1_H)
+#define _SPU_PRIV1_H
+#if defined(__KERNEL__)
+
+struct spu;
+
+/* access to priv1 registers */
+
+struct spu_priv1_ops
+{
+	void (*int_mask_and) (struct spu *spu, int class, u64 mask);
+	void (*int_mask_or) (struct spu *spu, int class, u64 mask);
+	void (*int_mask_set) (struct spu *spu, int class, u64 mask);
+	u64 (*int_mask_get) (struct spu *spu, int class);
+	void (*int_stat_clear) (struct spu *spu, int class, u64 stat);
+	u64 (*int_stat_get) (struct spu *spu, int class);
+	void (*cpu_affinity_set) (struct spu *spu, int cpu);
+	u64 (*mfc_dar_get) (struct spu *spu);
+	u64 (*mfc_dsisr_get) (struct spu *spu);
+	void (*mfc_dsisr_set) (struct spu *spu, u64 dsisr);
+	void (*mfc_sdr_set) (struct spu *spu, u64 sdr);
+	void (*mfc_sr1_set) (struct spu *spu, u64 sr1);
+	u64 (*mfc_sr1_get) (struct spu *spu);
+	void (*mfc_tclass_id_set) (struct spu *spu, u64 tclass_id);
+	u64 (*mfc_tclass_id_get) (struct spu *spu);
+	void (*tlb_invalidate) (struct spu *spu);
+	void (*resource_allocation_groupID_set) (struct spu *spu, u64 id);
+	u64 (*resource_allocation_groupID_get) (struct spu *spu);
+	void (*resource_allocation_enable_set) (struct spu *spu, u64 enable);
+	u64 (*resource_allocation_enable_get) (struct spu *spu);
+};
+
+extern const struct spu_priv1_ops* spu_priv1_ops;
+
+static inline void
+spu_int_mask_and (struct spu *spu, int class, u64 mask)
+{
+	spu_priv1_ops->int_mask_and(spu, class, mask);
+}
+
+static inline void
+spu_int_mask_or (struct spu *spu, int class, u64 mask)
+{
+	spu_priv1_ops->int_mask_or(spu, class, mask);
+}
+
+static inline void
+spu_int_mask_set (struct spu *spu, int class, u64 mask)
+{
+	spu_priv1_ops->int_mask_set(spu, class, mask);
+}
+
+static inline u64
+spu_int_mask_get (struct spu *spu, int class)
+{
+	return spu_priv1_ops->int_mask_get(spu, class);
+}
+
+static inline void
+spu_int_stat_clear (struct spu *spu, int class, u64 stat)
+{
+	spu_priv1_ops->int_stat_clear(spu, class, stat);
+}
+
+static inline u64
+spu_int_stat_get (struct spu *spu, int class)
+{
+	return spu_priv1_ops->int_stat_get (spu, class);
+}
+
+static inline void
+spu_cpu_affinity_set (struct spu *spu, int cpu)
+{
+	spu_priv1_ops->cpu_affinity_set(spu, cpu);
+}
+
+static inline u64
+spu_mfc_dar_get (struct spu *spu)
+{
+	return spu_priv1_ops->mfc_dar_get(spu);
+}
+
+static inline u64
+spu_mfc_dsisr_get (struct spu *spu)
+{
+	return spu_priv1_ops->mfc_dsisr_get(spu);
+}
+
+static inline void
+spu_mfc_dsisr_set (struct spu *spu, u64 dsisr)
+{
+	spu_priv1_ops->mfc_dsisr_set(spu, dsisr);
+}
+
+static inline void
+spu_mfc_sdr_set (struct spu *spu, u64 sdr)
+{
+	spu_priv1_ops->mfc_sdr_set(spu, sdr);
+}
+
+static inline void
+spu_mfc_sr1_set (struct spu *spu, u64 sr1)
+{
+	spu_priv1_ops->mfc_sr1_set(spu, sr1);
+}
+
+static inline u64
+spu_mfc_sr1_get (struct spu *spu)
+{
+	return spu_priv1_ops->mfc_sr1_get(spu);
+}
+
+static inline void
+spu_mfc_tclass_id_set (struct spu *spu, u64 tclass_id)
+{
+	spu_priv1_ops->mfc_tclass_id_set(spu, tclass_id);
+}
+
+static inline u64
+spu_mfc_tclass_id_get (struct spu *spu)
+{
+	return spu_priv1_ops->mfc_tclass_id_get(spu);
+}
+
+static inline void
+spu_tlb_invalidate (struct spu *spu)
+{
+	spu_priv1_ops->tlb_invalidate(spu);
+}
+
+static inline void
+spu_resource_allocation_groupID_set (struct spu *spu, u64 id)
+{
+	spu_priv1_ops->resource_allocation_groupID_set(spu, id);
+}
+
+static inline u64
+spu_resource_allocation_groupID_get (struct spu *spu)
+{
+	return spu_priv1_ops->resource_allocation_groupID_get(spu);
+}
+
+static inline void
+spu_resource_allocation_enable_set (struct spu *spu, u64 enable)
+{
+	spu_priv1_ops->resource_allocation_enable_set(spu, enable);
+}
+
+static inline u64
+spu_resource_allocation_enable_get (struct spu *spu)
+{
+	return spu_priv1_ops->resource_allocation_enable_get(spu);
+}
+
+/* The declarations folowing are put here for convenience
+ * and only intended to be used by the platform setup code
+ * for initializing spu_priv1_ops.
+ */
+
+extern const struct spu_priv1_ops spu_priv1_mmio_ops;
+
+#endif /* __KERNEL__ */
+#endif
diff --git a/include/asm-powerpc/systbl.h b/include/asm-powerpc/systbl.h
new file mode 100644
index 000000000..607c1e0a6
--- /dev/null
+++ b/include/asm-powerpc/systbl.h
@@ -0,0 +1,306 @@
+/*
+ * List of powerpc syscalls. For the meaning of the _SPU suffix see
+ * arch/powerpc/platforms/cell/spu_callbacks.c
+ */
+
+SYSCALL(restart_syscall)
+SYSCALL(exit)
+PPC_SYS(fork)
+SYSCALL_SPU(read)
+SYSCALL_SPU(write)
+COMPAT_SYS_SPU(open)
+SYSCALL_SPU(close)
+COMPAT_SYS_SPU(waitpid)
+COMPAT_SYS_SPU(creat)
+SYSCALL_SPU(link)
+SYSCALL_SPU(unlink)
+COMPAT_SYS(execve)
+SYSCALL_SPU(chdir)
+COMPAT_SYS_SPU(time)
+SYSCALL_SPU(mknod)
+SYSCALL_SPU(chmod)
+SYSCALL_SPU(lchown)
+SYSCALL(ni_syscall)
+OLDSYS(stat)
+SYSX_SPU(sys_lseek,ppc32_lseek,sys_lseek)
+SYSCALL_SPU(getpid)
+COMPAT_SYS(mount)
+SYSX(sys_ni_syscall,sys_oldumount,sys_oldumount)
+SYSCALL_SPU(setuid)
+SYSCALL_SPU(getuid)
+COMPAT_SYS_SPU(stime)
+COMPAT_SYS(ptrace)
+SYSCALL_SPU(alarm)
+OLDSYS(fstat)
+COMPAT_SYS(pause)
+COMPAT_SYS(utime)
+SYSCALL(ni_syscall)
+SYSCALL(ni_syscall)
+COMPAT_SYS_SPU(access)
+COMPAT_SYS_SPU(nice)
+SYSCALL(ni_syscall)
+SYSCALL_SPU(sync)
+COMPAT_SYS_SPU(kill)
+SYSCALL_SPU(rename)
+COMPAT_SYS_SPU(mkdir)
+SYSCALL_SPU(rmdir)
+SYSCALL_SPU(dup)
+SYSCALL_SPU(pipe)
+COMPAT_SYS_SPU(times)
+SYSCALL(ni_syscall)
+SYSCALL_SPU(brk)
+SYSCALL_SPU(setgid)
+SYSCALL_SPU(getgid)
+SYSCALL(signal)
+SYSCALL_SPU(geteuid)
+SYSCALL_SPU(getegid)
+SYSCALL(acct)
+SYSCALL(umount)
+SYSCALL(ni_syscall)
+COMPAT_SYS_SPU(ioctl)
+COMPAT_SYS_SPU(fcntl)
+SYSCALL(ni_syscall)
+COMPAT_SYS_SPU(setpgid)
+SYSCALL(ni_syscall)
+SYSX(sys_ni_syscall,sys_olduname, sys_olduname)
+COMPAT_SYS_SPU(umask)
+SYSCALL_SPU(chroot)
+SYSCALL(ustat)
+SYSCALL_SPU(dup2)
+SYSCALL_SPU(getppid)
+SYSCALL_SPU(getpgrp)
+SYSCALL_SPU(setsid)
+SYS32ONLY(sigaction)
+SYSCALL_SPU(sgetmask)
+COMPAT_SYS_SPU(ssetmask)
+SYSCALL_SPU(setreuid)
+SYSCALL_SPU(setregid)
+SYS32ONLY(sigsuspend)
+COMPAT_SYS(sigpending)
+COMPAT_SYS_SPU(sethostname)
+COMPAT_SYS_SPU(setrlimit)
+COMPAT_SYS(old_getrlimit)
+COMPAT_SYS_SPU(getrusage)
+COMPAT_SYS_SPU(gettimeofday)
+COMPAT_SYS_SPU(settimeofday)
+COMPAT_SYS_SPU(getgroups)
+COMPAT_SYS_SPU(setgroups)
+SYSX(sys_ni_syscall,sys_ni_syscall,ppc_select)
+SYSCALL_SPU(symlink)
+OLDSYS(lstat)
+COMPAT_SYS_SPU(readlink)
+SYSCALL(uselib)
+SYSCALL(swapon)
+SYSCALL(reboot)
+SYSX(sys_ni_syscall,old32_readdir,old_readdir)
+SYSCALL_SPU(mmap)
+SYSCALL_SPU(munmap)
+SYSCALL_SPU(truncate)
+SYSCALL_SPU(ftruncate)
+SYSCALL_SPU(fchmod)
+SYSCALL_SPU(fchown)
+COMPAT_SYS_SPU(getpriority)
+COMPAT_SYS_SPU(setpriority)
+SYSCALL(ni_syscall)
+COMPAT_SYS(statfs)
+COMPAT_SYS(fstatfs)
+SYSCALL(ni_syscall)
+COMPAT_SYS_SPU(socketcall)
+COMPAT_SYS_SPU(syslog)
+COMPAT_SYS_SPU(setitimer)
+COMPAT_SYS_SPU(getitimer)
+COMPAT_SYS_SPU(newstat)
+COMPAT_SYS_SPU(newlstat)
+COMPAT_SYS_SPU(newfstat)
+SYSX(sys_ni_syscall,sys_uname,sys_uname)
+SYSCALL(ni_syscall)
+SYSCALL_SPU(vhangup)
+SYSCALL(ni_syscall)
+SYSCALL(ni_syscall)
+COMPAT_SYS_SPU(wait4)
+SYSCALL(swapoff)
+COMPAT_SYS_SPU(sysinfo)
+COMPAT_SYS(ipc)
+SYSCALL_SPU(fsync)
+SYS32ONLY(sigreturn)
+PPC_SYS(clone)
+COMPAT_SYS_SPU(setdomainname)
+PPC_SYS_SPU(newuname)
+SYSCALL(ni_syscall)
+COMPAT_SYS_SPU(adjtimex)
+SYSCALL_SPU(mprotect)
+SYSX(sys_ni_syscall,compat_sys_sigprocmask,sys_sigprocmask)
+SYSCALL(ni_syscall)
+SYSCALL(init_module)
+SYSCALL(delete_module)
+SYSCALL(ni_syscall)
+SYSCALL(quotactl)
+COMPAT_SYS_SPU(getpgid)
+SYSCALL_SPU(fchdir)
+SYSCALL_SPU(bdflush)
+COMPAT_SYS(sysfs)
+SYSX_SPU(ppc64_personality,ppc64_personality,sys_personality)
+SYSCALL(ni_syscall)
+SYSCALL_SPU(setfsuid)
+SYSCALL_SPU(setfsgid)
+SYSCALL_SPU(llseek)
+COMPAT_SYS_SPU(getdents)
+SYSX_SPU(sys_select,ppc32_select,ppc_select)
+SYSCALL_SPU(flock)
+SYSCALL_SPU(msync)
+COMPAT_SYS_SPU(readv)
+COMPAT_SYS_SPU(writev)
+COMPAT_SYS_SPU(getsid)
+SYSCALL_SPU(fdatasync)
+COMPAT_SYS(sysctl)
+SYSCALL_SPU(mlock)
+SYSCALL_SPU(munlock)
+SYSCALL_SPU(mlockall)
+SYSCALL_SPU(munlockall)
+COMPAT_SYS_SPU(sched_setparam)
+COMPAT_SYS_SPU(sched_getparam)
+COMPAT_SYS_SPU(sched_setscheduler)
+COMPAT_SYS_SPU(sched_getscheduler)
+SYSCALL_SPU(sched_yield)
+COMPAT_SYS_SPU(sched_get_priority_max)
+COMPAT_SYS_SPU(sched_get_priority_min)
+COMPAT_SYS_SPU(sched_rr_get_interval)
+COMPAT_SYS_SPU(nanosleep)
+SYSCALL_SPU(mremap)
+SYSCALL_SPU(setresuid)
+SYSCALL_SPU(getresuid)
+SYSCALL(ni_syscall)
+SYSCALL_SPU(poll)
+COMPAT_SYS(nfsservctl)
+SYSCALL_SPU(setresgid)
+SYSCALL_SPU(getresgid)
+COMPAT_SYS_SPU(prctl)
+COMPAT_SYS(rt_sigreturn)
+COMPAT_SYS(rt_sigaction)
+COMPAT_SYS(rt_sigprocmask)
+COMPAT_SYS(rt_sigpending)
+COMPAT_SYS(rt_sigtimedwait)
+COMPAT_SYS(rt_sigqueueinfo)
+COMPAT_SYS(rt_sigsuspend)
+COMPAT_SYS_SPU(pread64)
+COMPAT_SYS_SPU(pwrite64)
+SYSCALL_SPU(chown)
+SYSCALL_SPU(getcwd)
+SYSCALL_SPU(capget)
+SYSCALL_SPU(capset)
+COMPAT_SYS(sigaltstack)
+SYSX_SPU(sys_sendfile64,compat_sys_sendfile,sys_sendfile)
+SYSCALL(ni_syscall)
+SYSCALL(ni_syscall)
+PPC_SYS(vfork)
+COMPAT_SYS_SPU(getrlimit)
+COMPAT_SYS_SPU(readahead)
+SYS32ONLY(mmap2)
+SYS32ONLY(truncate64)
+SYS32ONLY(ftruncate64)
+SYSX(sys_ni_syscall,sys_stat64,sys_stat64)
+SYSX(sys_ni_syscall,sys_lstat64,sys_lstat64)
+SYSX(sys_ni_syscall,sys_fstat64,sys_fstat64)
+SYSCALL(pciconfig_read)
+SYSCALL(pciconfig_write)
+SYSCALL(pciconfig_iobase)
+SYSCALL(ni_syscall)
+SYSCALL_SPU(getdents64)
+SYSCALL_SPU(pivot_root)
+SYSX(sys_ni_syscall,compat_sys_fcntl64,sys_fcntl64)
+SYSCALL_SPU(madvise)
+SYSCALL_SPU(mincore)
+SYSCALL_SPU(gettid)
+SYSCALL_SPU(tkill)
+SYSCALL_SPU(setxattr)
+SYSCALL_SPU(lsetxattr)
+SYSCALL_SPU(fsetxattr)
+SYSCALL_SPU(getxattr)
+SYSCALL_SPU(lgetxattr)
+SYSCALL_SPU(fgetxattr)
+SYSCALL_SPU(listxattr)
+SYSCALL_SPU(llistxattr)
+SYSCALL_SPU(flistxattr)
+SYSCALL_SPU(removexattr)
+SYSCALL_SPU(lremovexattr)
+SYSCALL_SPU(fremovexattr)
+COMPAT_SYS_SPU(futex)
+COMPAT_SYS_SPU(sched_setaffinity)
+COMPAT_SYS_SPU(sched_getaffinity)
+SYSCALL(ni_syscall)
+SYSCALL(ni_syscall)
+SYS32ONLY(sendfile64)
+COMPAT_SYS_SPU(io_setup)
+SYSCALL_SPU(io_destroy)
+COMPAT_SYS_SPU(io_getevents)
+COMPAT_SYS_SPU(io_submit)
+SYSCALL_SPU(io_cancel)
+SYSCALL(set_tid_address)
+SYSX_SPU(sys_fadvise64,ppc32_fadvise64,sys_fadvise64)
+SYSCALL(exit_group)
+SYSX(sys_lookup_dcookie,ppc32_lookup_dcookie,sys_lookup_dcookie)
+SYSCALL_SPU(epoll_create)
+SYSCALL_SPU(epoll_ctl)
+SYSCALL_SPU(epoll_wait)
+SYSCALL_SPU(remap_file_pages)
+SYSX_SPU(sys_timer_create,compat_sys_timer_create,sys_timer_create)
+COMPAT_SYS_SPU(timer_settime)
+COMPAT_SYS_SPU(timer_gettime)
+SYSCALL_SPU(timer_getoverrun)
+SYSCALL_SPU(timer_delete)
+COMPAT_SYS_SPU(clock_settime)
+COMPAT_SYS_SPU(clock_gettime)
+COMPAT_SYS_SPU(clock_getres)
+COMPAT_SYS_SPU(clock_nanosleep)
+SYSX(ppc64_swapcontext,ppc32_swapcontext,ppc_swapcontext)
+COMPAT_SYS_SPU(tgkill)
+COMPAT_SYS_SPU(utimes)
+COMPAT_SYS_SPU(statfs64)
+COMPAT_SYS_SPU(fstatfs64)
+SYSX(sys_ni_syscall, ppc_fadvise64_64, ppc_fadvise64_64)
+PPC_SYS_SPU(rtas)
+OLDSYS(debug_setcontext)
+SYSX(sys_vserver, sys32_vserver, sys_vserver)
+SYSCALL(ni_syscall)
+COMPAT_SYS(mbind)
+COMPAT_SYS(get_mempolicy)
+COMPAT_SYS(set_mempolicy)
+COMPAT_SYS(mq_open)
+SYSCALL(mq_unlink)
+COMPAT_SYS(mq_timedsend)
+COMPAT_SYS(mq_timedreceive)
+COMPAT_SYS(mq_notify)
+COMPAT_SYS(mq_getsetattr)
+COMPAT_SYS(kexec_load)
+COMPAT_SYS(add_key)
+COMPAT_SYS(request_key)
+COMPAT_SYS(keyctl)
+COMPAT_SYS(waitid)
+COMPAT_SYS(ioprio_set)
+COMPAT_SYS(ioprio_get)
+SYSCALL(inotify_init)
+SYSCALL(inotify_add_watch)
+SYSCALL(inotify_rm_watch)
+SYSCALL(spu_run)
+SYSCALL(spu_create)
+COMPAT_SYS(pselect6)
+COMPAT_SYS(ppoll)
+SYSCALL_SPU(unshare)
+SYSCALL_SPU(splice)
+SYSCALL_SPU(tee)
+SYSCALL_SPU(vmsplice)
+COMPAT_SYS_SPU(openat)
+SYSCALL_SPU(mkdirat)
+SYSCALL_SPU(mknodat)
+SYSCALL_SPU(fchownat)
+COMPAT_SYS_SPU(futimesat)
+SYSX_SPU(sys_newfstatat, sys_fstatat64, sys_fstatat64)
+SYSCALL_SPU(unlinkat)
+SYSCALL_SPU(renameat)
+SYSCALL_SPU(linkat)
+SYSCALL_SPU(symlinkat)
+SYSCALL_SPU(readlinkat)
+SYSCALL_SPU(fchmodat)
+SYSCALL_SPU(faccessat)
+COMPAT_SYS_SPU(get_robust_list)
+COMPAT_SYS_SPU(set_robust_list)
diff --git a/include/asm-powerpc/todc.h b/include/asm-powerpc/todc.h
new file mode 100644
index 000000000..60a8c39b8
--- /dev/null
+++ b/include/asm-powerpc/todc.h
@@ -0,0 +1,487 @@
+/*
+ * Definitions for the M48Txx and mc146818 series of Time of day/Real Time
+ * Clock chips.
+ *
+ * Author: Mark A. Greer <mgreer@mvista.com>
+ *
+ * 2001 (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.
+ */
+
+/*
+ * Support for the M48T37/M48T59/.../mc146818 Real Time Clock chips.
+ * Purpose is to make one generic file that handles all of these chips instead
+ * of every platform implementing the same code over & over again.
+ */
+
+#ifndef __PPC_KERNEL_TODC_H
+#define __PPC_KERNEL_TODC_H
+
+typedef struct {
+	uint rtc_type;		/* your particular chip */
+
+	/*
+	 * Following are the addresses of the AS0, AS1, and DATA registers
+	 * of these chips.  Note that these are board-specific.
+	 */
+	unsigned int nvram_as0;
+	unsigned int nvram_as1;
+	unsigned int nvram_data;
+
+	/*
+	 * Define bits to stop external set of regs from changing so
+	 * the chip can be read/written reliably.
+	 */
+	unsigned char enable_read;
+	unsigned char enable_write;
+
+	/*
+	 * Following is the number of AS0 address bits.  This is normally
+	 * 8 but some bad hardware routes address lines incorrectly.
+	 */
+	int as0_bits;
+
+	int nvram_size;	/* Size of NVRAM on chip */
+	int sw_flags;	/* Software control flags */
+
+	/* Following are the register offsets for the particular chip */
+	int year;
+	int month;
+	int day_of_month;
+	int day_of_week;
+	int hours;
+	int minutes;
+	int seconds;
+	int control_b;
+	int control_a;
+	int watchdog;
+	int interrupts;
+	int alarm_date;
+	int alarm_hour;
+	int alarm_minutes;
+	int alarm_seconds;
+	int century;
+	int flags;
+
+	/*
+	 * Some RTC chips have their NVRAM buried behind a addr/data pair of
+	 * regs on the first level/clock registers.  The following fields
+	 * are the addresses for those addr/data regs.
+	 */
+	int nvram_addr_reg;
+	int nvram_data_reg;
+} todc_info_t;
+
+/*
+ * Define the types of TODC/RTC variants that are supported in
+ * arch/ppc/kernel/todc_time.c
+ * Make a new one of these for any chip somehow differs from what's already
+ * defined.  That way, if you ever need to put in code to touch those
+ * bits/registers in todc_time.c, you can put it inside an
+ * 'if (todc_info->rtc_type == TODC_TYPE_XXX)' so you won't break
+ * anyone else.
+ */
+#define TODC_TYPE_MK48T35		1
+#define TODC_TYPE_MK48T37		2
+#define TODC_TYPE_MK48T59		3
+#define TODC_TYPE_DS1693		4	/* Dallas DS1693 RTC */
+#define TODC_TYPE_DS1743		5	/* Dallas DS1743 RTC */
+#define TODC_TYPE_DS1746		6	/* Dallas DS1746 RTC */
+#define TODC_TYPE_DS1747		7	/* Dallas DS1747 RTC */
+#define TODC_TYPE_DS1501		8	/* Dallas DS1501 RTC */
+#define TODC_TYPE_DS1643		9	/* Dallas DS1643 RTC */
+#define TODC_TYPE_PC97307		10	/* PC97307 internal RTC */
+#define TODC_TYPE_DS1557		11	/* Dallas DS1557 RTC */
+#define TODC_TYPE_DS17285		12	/* Dallas DS17285 RTC */
+#define TODC_TYPE_DS1553		13	/* Dallas DS1553 RTC */
+#define TODC_TYPE_MC146818		100	/* Leave room for m48txx's */
+
+/*
+ * Bit to clear/set to enable reads/writes to the chip
+ */
+#define TODC_MK48TXX_CNTL_A_R		0x40
+#define TODC_MK48TXX_CNTL_A_W		0x80
+#define TODC_MK48TXX_DAY_CB		0x80
+
+#define TODC_DS1501_CNTL_B_TE		0x80
+
+/*
+ * Define flag bits used by todc routines.
+ */
+#define TODC_FLAG_2_LEVEL_NVRAM		0x00000001
+
+/*
+ * Define the values for the various RTC's that should to into the todc_info
+ * table.
+ * Note: The XXX_NVRAM_SIZE, XXX_NVRAM_ADDR_REG, and XXX_NVRAM_DATA_REG only
+ * matter if XXX_SW_FLAGS has TODC_FLAG_2_LEVEL_NVRAM set.
+ */
+#define TODC_TYPE_MK48T35_NVRAM_SIZE		0x7ff8
+#define TODC_TYPE_MK48T35_SW_FLAGS		0
+#define TODC_TYPE_MK48T35_YEAR			0x7fff
+#define TODC_TYPE_MK48T35_MONTH			0x7ffe
+#define TODC_TYPE_MK48T35_DOM			0x7ffd	/* Day of Month */
+#define TODC_TYPE_MK48T35_DOW			0x7ffc	/* Day of Week */
+#define TODC_TYPE_MK48T35_HOURS			0x7ffb
+#define TODC_TYPE_MK48T35_MINUTES		0x7ffa
+#define TODC_TYPE_MK48T35_SECONDS		0x7ff9
+#define TODC_TYPE_MK48T35_CNTL_B		0x7ff9
+#define TODC_TYPE_MK48T35_CNTL_A		0x7ff8
+#define TODC_TYPE_MK48T35_WATCHDOG		0x0000
+#define TODC_TYPE_MK48T35_INTERRUPTS		0x0000
+#define TODC_TYPE_MK48T35_ALARM_DATE		0x0000
+#define TODC_TYPE_MK48T35_ALARM_HOUR		0x0000
+#define TODC_TYPE_MK48T35_ALARM_MINUTES		0x0000
+#define TODC_TYPE_MK48T35_ALARM_SECONDS		0x0000
+#define TODC_TYPE_MK48T35_CENTURY		0x0000
+#define TODC_TYPE_MK48T35_FLAGS			0x0000
+#define TODC_TYPE_MK48T35_NVRAM_ADDR_REG	0
+#define TODC_TYPE_MK48T35_NVRAM_DATA_REG	0
+
+#define TODC_TYPE_MK48T37_NVRAM_SIZE		0x7ff0
+#define TODC_TYPE_MK48T37_SW_FLAGS		0
+#define TODC_TYPE_MK48T37_YEAR			0x7fff
+#define TODC_TYPE_MK48T37_MONTH			0x7ffe
+#define TODC_TYPE_MK48T37_DOM			0x7ffd	/* Day of Month */
+#define TODC_TYPE_MK48T37_DOW			0x7ffc	/* Day of Week */
+#define TODC_TYPE_MK48T37_HOURS			0x7ffb
+#define TODC_TYPE_MK48T37_MINUTES		0x7ffa
+#define TODC_TYPE_MK48T37_SECONDS		0x7ff9
+#define TODC_TYPE_MK48T37_CNTL_B		0x7ff9
+#define TODC_TYPE_MK48T37_CNTL_A		0x7ff8
+#define TODC_TYPE_MK48T37_WATCHDOG		0x7ff7
+#define TODC_TYPE_MK48T37_INTERRUPTS		0x7ff6
+#define TODC_TYPE_MK48T37_ALARM_DATE		0x7ff5
+#define TODC_TYPE_MK48T37_ALARM_HOUR		0x7ff4
+#define TODC_TYPE_MK48T37_ALARM_MINUTES		0x7ff3
+#define TODC_TYPE_MK48T37_ALARM_SECONDS		0x7ff2
+#define TODC_TYPE_MK48T37_CENTURY		0x7ff1
+#define TODC_TYPE_MK48T37_FLAGS			0x7ff0
+#define TODC_TYPE_MK48T37_NVRAM_ADDR_REG	0
+#define TODC_TYPE_MK48T37_NVRAM_DATA_REG	0
+
+#define TODC_TYPE_MK48T59_NVRAM_SIZE		0x1ff0
+#define TODC_TYPE_MK48T59_SW_FLAGS		0
+#define TODC_TYPE_MK48T59_YEAR			0x1fff
+#define TODC_TYPE_MK48T59_MONTH			0x1ffe
+#define TODC_TYPE_MK48T59_DOM			0x1ffd	/* Day of Month */
+#define TODC_TYPE_MK48T59_DOW			0x1ffc	/* Day of Week */
+#define TODC_TYPE_MK48T59_HOURS			0x1ffb
+#define TODC_TYPE_MK48T59_MINUTES		0x1ffa
+#define TODC_TYPE_MK48T59_SECONDS		0x1ff9
+#define TODC_TYPE_MK48T59_CNTL_B		0x1ff9
+#define TODC_TYPE_MK48T59_CNTL_A		0x1ff8
+#define TODC_TYPE_MK48T59_WATCHDOG		0x1fff
+#define TODC_TYPE_MK48T59_INTERRUPTS		0x1fff
+#define TODC_TYPE_MK48T59_ALARM_DATE		0x1fff
+#define TODC_TYPE_MK48T59_ALARM_HOUR		0x1fff
+#define TODC_TYPE_MK48T59_ALARM_MINUTES		0x1fff
+#define TODC_TYPE_MK48T59_ALARM_SECONDS		0x1fff
+#define TODC_TYPE_MK48T59_CENTURY		0x1fff
+#define TODC_TYPE_MK48T59_FLAGS			0x1fff
+#define TODC_TYPE_MK48T59_NVRAM_ADDR_REG	0
+#define TODC_TYPE_MK48T59_NVRAM_DATA_REG	0
+
+#define TODC_TYPE_DS1501_NVRAM_SIZE	0x100
+#define TODC_TYPE_DS1501_SW_FLAGS	TODC_FLAG_2_LEVEL_NVRAM
+#define TODC_TYPE_DS1501_YEAR		(TODC_TYPE_DS1501_NVRAM_SIZE + 0x06)
+#define TODC_TYPE_DS1501_MONTH		(TODC_TYPE_DS1501_NVRAM_SIZE + 0x05)
+#define TODC_TYPE_DS1501_DOM		(TODC_TYPE_DS1501_NVRAM_SIZE + 0x04)
+#define TODC_TYPE_DS1501_DOW		(TODC_TYPE_DS1501_NVRAM_SIZE + 0x03)
+#define TODC_TYPE_DS1501_HOURS		(TODC_TYPE_DS1501_NVRAM_SIZE + 0x02)
+#define TODC_TYPE_DS1501_MINUTES	(TODC_TYPE_DS1501_NVRAM_SIZE + 0x01)
+#define TODC_TYPE_DS1501_SECONDS	(TODC_TYPE_DS1501_NVRAM_SIZE + 0x00)
+#define TODC_TYPE_DS1501_CNTL_B		(TODC_TYPE_DS1501_NVRAM_SIZE + 0x0f)
+#define TODC_TYPE_DS1501_CNTL_A		(TODC_TYPE_DS1501_NVRAM_SIZE + 0x0f)
+#define TODC_TYPE_DS1501_WATCHDOG	(TODC_TYPE_DS1501_NVRAM_SIZE + 0xff)
+#define TODC_TYPE_DS1501_INTERRUPTS	(TODC_TYPE_DS1501_NVRAM_SIZE + 0xff)
+#define TODC_TYPE_DS1501_ALARM_DATE	(TODC_TYPE_DS1501_NVRAM_SIZE + 0x0b)
+#define TODC_TYPE_DS1501_ALARM_HOUR	(TODC_TYPE_DS1501_NVRAM_SIZE + 0x0a)
+#define TODC_TYPE_DS1501_ALARM_MINUTES	(TODC_TYPE_DS1501_NVRAM_SIZE + 0x09)
+#define TODC_TYPE_DS1501_ALARM_SECONDS	(TODC_TYPE_DS1501_NVRAM_SIZE + 0x08)
+#define TODC_TYPE_DS1501_CENTURY	(TODC_TYPE_DS1501_NVRAM_SIZE + 0x07)
+#define TODC_TYPE_DS1501_FLAGS		(TODC_TYPE_DS1501_NVRAM_SIZE + 0xff)
+#define TODC_TYPE_DS1501_NVRAM_ADDR_REG	0x10
+#define TODC_TYPE_DS1501_NVRAM_DATA_REG	0x13
+
+#define TODC_TYPE_DS1553_NVRAM_SIZE		0x1ff0
+#define TODC_TYPE_DS1553_SW_FLAGS		0
+#define TODC_TYPE_DS1553_YEAR			0x1fff
+#define TODC_TYPE_DS1553_MONTH			0x1ffe
+#define TODC_TYPE_DS1553_DOM			0x1ffd	/* Day of Month */
+#define TODC_TYPE_DS1553_DOW			0x1ffc	/* Day of Week */
+#define TODC_TYPE_DS1553_HOURS			0x1ffb
+#define TODC_TYPE_DS1553_MINUTES		0x1ffa
+#define TODC_TYPE_DS1553_SECONDS		0x1ff9
+#define TODC_TYPE_DS1553_CNTL_B			0x1ff9
+#define TODC_TYPE_DS1553_CNTL_A			0x1ff8	/* control_a R/W regs */
+#define TODC_TYPE_DS1553_WATCHDOG		0x1ff7
+#define TODC_TYPE_DS1553_INTERRUPTS		0x1ff6
+#define TODC_TYPE_DS1553_ALARM_DATE		0x1ff5
+#define TODC_TYPE_DS1553_ALARM_HOUR		0x1ff4
+#define TODC_TYPE_DS1553_ALARM_MINUTES		0x1ff3
+#define TODC_TYPE_DS1553_ALARM_SECONDS		0x1ff2
+#define TODC_TYPE_DS1553_CENTURY		0x1ff8
+#define TODC_TYPE_DS1553_FLAGS			0x1ff0
+#define TODC_TYPE_DS1553_NVRAM_ADDR_REG		0
+#define TODC_TYPE_DS1553_NVRAM_DATA_REG		0
+
+#define TODC_TYPE_DS1557_NVRAM_SIZE		0x7fff0
+#define TODC_TYPE_DS1557_SW_FLAGS		0
+#define TODC_TYPE_DS1557_YEAR			0x7ffff
+#define TODC_TYPE_DS1557_MONTH			0x7fffe
+#define TODC_TYPE_DS1557_DOM			0x7fffd	/* Day of Month */
+#define TODC_TYPE_DS1557_DOW			0x7fffc	/* Day of Week */
+#define TODC_TYPE_DS1557_HOURS			0x7fffb
+#define TODC_TYPE_DS1557_MINUTES		0x7fffa
+#define TODC_TYPE_DS1557_SECONDS		0x7fff9
+#define TODC_TYPE_DS1557_CNTL_B			0x7fff9
+#define TODC_TYPE_DS1557_CNTL_A			0x7fff8	/* control_a R/W regs */
+#define TODC_TYPE_DS1557_WATCHDOG		0x7fff7
+#define TODC_TYPE_DS1557_INTERRUPTS		0x7fff6
+#define TODC_TYPE_DS1557_ALARM_DATE		0x7fff5
+#define TODC_TYPE_DS1557_ALARM_HOUR		0x7fff4
+#define TODC_TYPE_DS1557_ALARM_MINUTES		0x7fff3
+#define TODC_TYPE_DS1557_ALARM_SECONDS		0x7fff2
+#define TODC_TYPE_DS1557_CENTURY		0x7fff8
+#define TODC_TYPE_DS1557_FLAGS			0x7fff0
+#define TODC_TYPE_DS1557_NVRAM_ADDR_REG		0
+#define TODC_TYPE_DS1557_NVRAM_DATA_REG		0
+
+#define TODC_TYPE_DS1643_NVRAM_SIZE		0x1ff8
+#define TODC_TYPE_DS1643_SW_FLAGS		0
+#define TODC_TYPE_DS1643_YEAR			0x1fff
+#define TODC_TYPE_DS1643_MONTH			0x1ffe
+#define TODC_TYPE_DS1643_DOM			0x1ffd	/* Day of Month */
+#define TODC_TYPE_DS1643_DOW			0x1ffc	/* Day of Week */
+#define TODC_TYPE_DS1643_HOURS			0x1ffb
+#define TODC_TYPE_DS1643_MINUTES		0x1ffa
+#define TODC_TYPE_DS1643_SECONDS		0x1ff9
+#define TODC_TYPE_DS1643_CNTL_B			0x1ff9
+#define TODC_TYPE_DS1643_CNTL_A			0x1ff8	/* control_a R/W regs */
+#define TODC_TYPE_DS1643_WATCHDOG		0x1fff
+#define TODC_TYPE_DS1643_INTERRUPTS		0x1fff
+#define TODC_TYPE_DS1643_ALARM_DATE		0x1fff
+#define TODC_TYPE_DS1643_ALARM_HOUR		0x1fff
+#define TODC_TYPE_DS1643_ALARM_MINUTES		0x1fff
+#define TODC_TYPE_DS1643_ALARM_SECONDS		0x1fff
+#define TODC_TYPE_DS1643_CENTURY		0x1ff8
+#define TODC_TYPE_DS1643_FLAGS			0x1fff
+#define TODC_TYPE_DS1643_NVRAM_ADDR_REG		0
+#define TODC_TYPE_DS1643_NVRAM_DATA_REG		0
+
+#define TODC_TYPE_DS1693_NVRAM_SIZE		0 /* Not handled yet */
+#define TODC_TYPE_DS1693_SW_FLAGS		0
+#define TODC_TYPE_DS1693_YEAR			0x09
+#define TODC_TYPE_DS1693_MONTH			0x08
+#define TODC_TYPE_DS1693_DOM			0x07	/* Day of Month */
+#define TODC_TYPE_DS1693_DOW			0x06	/* Day of Week */
+#define TODC_TYPE_DS1693_HOURS			0x04
+#define TODC_TYPE_DS1693_MINUTES		0x02
+#define TODC_TYPE_DS1693_SECONDS		0x00
+#define TODC_TYPE_DS1693_CNTL_B			0x0b
+#define TODC_TYPE_DS1693_CNTL_A			0x0a
+#define TODC_TYPE_DS1693_WATCHDOG		0xff
+#define TODC_TYPE_DS1693_INTERRUPTS		0xff
+#define TODC_TYPE_DS1693_ALARM_DATE		0x49
+#define TODC_TYPE_DS1693_ALARM_HOUR		0x05
+#define TODC_TYPE_DS1693_ALARM_MINUTES		0x03
+#define TODC_TYPE_DS1693_ALARM_SECONDS		0x01
+#define TODC_TYPE_DS1693_CENTURY		0x48
+#define TODC_TYPE_DS1693_FLAGS			0xff
+#define TODC_TYPE_DS1693_NVRAM_ADDR_REG		0
+#define TODC_TYPE_DS1693_NVRAM_DATA_REG		0
+
+#define TODC_TYPE_DS1743_NVRAM_SIZE		0x1ff8
+#define TODC_TYPE_DS1743_SW_FLAGS		0
+#define TODC_TYPE_DS1743_YEAR			0x1fff
+#define TODC_TYPE_DS1743_MONTH			0x1ffe
+#define TODC_TYPE_DS1743_DOM			0x1ffd	/* Day of Month */
+#define TODC_TYPE_DS1743_DOW			0x1ffc	/* Day of Week */
+#define TODC_TYPE_DS1743_HOURS			0x1ffb
+#define TODC_TYPE_DS1743_MINUTES		0x1ffa
+#define TODC_TYPE_DS1743_SECONDS		0x1ff9
+#define TODC_TYPE_DS1743_CNTL_B			0x1ff9
+#define TODC_TYPE_DS1743_CNTL_A			0x1ff8	/* control_a R/W regs */
+#define TODC_TYPE_DS1743_WATCHDOG		0x1fff
+#define TODC_TYPE_DS1743_INTERRUPTS		0x1fff
+#define TODC_TYPE_DS1743_ALARM_DATE		0x1fff
+#define TODC_TYPE_DS1743_ALARM_HOUR		0x1fff
+#define TODC_TYPE_DS1743_ALARM_MINUTES		0x1fff
+#define TODC_TYPE_DS1743_ALARM_SECONDS		0x1fff
+#define TODC_TYPE_DS1743_CENTURY		0x1ff8
+#define TODC_TYPE_DS1743_FLAGS			0x1fff
+#define TODC_TYPE_DS1743_NVRAM_ADDR_REG		0
+#define TODC_TYPE_DS1743_NVRAM_DATA_REG		0
+
+#define TODC_TYPE_DS1746_NVRAM_SIZE		0x1fff8
+#define TODC_TYPE_DS1746_SW_FLAGS		0
+#define TODC_TYPE_DS1746_YEAR			0x1ffff
+#define TODC_TYPE_DS1746_MONTH			0x1fffe
+#define TODC_TYPE_DS1746_DOM			0x1fffd	/* Day of Month */
+#define TODC_TYPE_DS1746_DOW			0x1fffc	/* Day of Week */
+#define TODC_TYPE_DS1746_HOURS			0x1fffb
+#define TODC_TYPE_DS1746_MINUTES		0x1fffa
+#define TODC_TYPE_DS1746_SECONDS		0x1fff9
+#define TODC_TYPE_DS1746_CNTL_B			0x1fff9
+#define TODC_TYPE_DS1746_CNTL_A			0x1fff8	/* control_a R/W regs */
+#define TODC_TYPE_DS1746_WATCHDOG		0x00000
+#define TODC_TYPE_DS1746_INTERRUPTS		0x00000
+#define TODC_TYPE_DS1746_ALARM_DATE		0x00000
+#define TODC_TYPE_DS1746_ALARM_HOUR		0x00000
+#define TODC_TYPE_DS1746_ALARM_MINUTES		0x00000
+#define TODC_TYPE_DS1746_ALARM_SECONDS		0x00000
+#define TODC_TYPE_DS1746_CENTURY		0x00000
+#define TODC_TYPE_DS1746_FLAGS			0x00000
+#define TODC_TYPE_DS1746_NVRAM_ADDR_REG		0
+#define TODC_TYPE_DS1746_NVRAM_DATA_REG		0
+
+#define TODC_TYPE_DS1747_NVRAM_SIZE		0x7fff8
+#define TODC_TYPE_DS1747_SW_FLAGS		0
+#define TODC_TYPE_DS1747_YEAR			0x7ffff
+#define TODC_TYPE_DS1747_MONTH			0x7fffe
+#define TODC_TYPE_DS1747_DOM			0x7fffd	/* Day of Month */
+#define TODC_TYPE_DS1747_DOW			0x7fffc	/* Day of Week */
+#define TODC_TYPE_DS1747_HOURS			0x7fffb
+#define TODC_TYPE_DS1747_MINUTES		0x7fffa
+#define TODC_TYPE_DS1747_SECONDS		0x7fff9
+#define TODC_TYPE_DS1747_CNTL_B			0x7fff9
+#define TODC_TYPE_DS1747_CNTL_A			0x7fff8	/* control_a R/W regs */
+#define TODC_TYPE_DS1747_WATCHDOG		0x00000
+#define TODC_TYPE_DS1747_INTERRUPTS		0x00000
+#define TODC_TYPE_DS1747_ALARM_DATE		0x00000
+#define TODC_TYPE_DS1747_ALARM_HOUR		0x00000
+#define TODC_TYPE_DS1747_ALARM_MINUTES		0x00000
+#define TODC_TYPE_DS1747_ALARM_SECONDS		0x00000
+#define TODC_TYPE_DS1747_CENTURY		0x00000
+#define TODC_TYPE_DS1747_FLAGS			0x00000
+#define TODC_TYPE_DS1747_NVRAM_ADDR_REG		0
+#define TODC_TYPE_DS1747_NVRAM_DATA_REG		0
+
+#define TODC_TYPE_DS17285_NVRAM_SIZE		(0x1000-0x80) /* 4Kx8 NVRAM (minus RTC regs) */
+#define TODC_TYPE_DS17285_SW_FLAGS		TODC_FLAG_2_LEVEL_NVRAM
+#define TODC_TYPE_DS17285_SECONDS		(TODC_TYPE_DS17285_NVRAM_SIZE + 0x00)
+#define TODC_TYPE_DS17285_ALARM_SECONDS		(TODC_TYPE_DS17285_NVRAM_SIZE + 0x01)
+#define TODC_TYPE_DS17285_MINUTES		(TODC_TYPE_DS17285_NVRAM_SIZE + 0x02)
+#define TODC_TYPE_DS17285_ALARM_MINUTES		(TODC_TYPE_DS17285_NVRAM_SIZE + 0x03)
+#define TODC_TYPE_DS17285_HOURS			(TODC_TYPE_DS17285_NVRAM_SIZE + 0x04)
+#define TODC_TYPE_DS17285_ALARM_HOUR		(TODC_TYPE_DS17285_NVRAM_SIZE + 0x05)
+#define TODC_TYPE_DS17285_DOW			(TODC_TYPE_DS17285_NVRAM_SIZE + 0x06)
+#define TODC_TYPE_DS17285_DOM			(TODC_TYPE_DS17285_NVRAM_SIZE + 0x07)
+#define TODC_TYPE_DS17285_MONTH			(TODC_TYPE_DS17285_NVRAM_SIZE + 0x08)
+#define TODC_TYPE_DS17285_YEAR			(TODC_TYPE_DS17285_NVRAM_SIZE + 0x09)
+#define TODC_TYPE_DS17285_CNTL_A		(TODC_TYPE_DS17285_NVRAM_SIZE + 0x0A)
+#define TODC_TYPE_DS17285_CNTL_B		(TODC_TYPE_DS17285_NVRAM_SIZE + 0x0B)
+#define TODC_TYPE_DS17285_CNTL_C		(TODC_TYPE_DS17285_NVRAM_SIZE + 0x0C)
+#define TODC_TYPE_DS17285_CNTL_D		(TODC_TYPE_DS17285_NVRAM_SIZE + 0x0D)
+#define TODC_TYPE_DS17285_WATCHDOG		0
+#define TODC_TYPE_DS17285_INTERRUPTS		0
+#define TODC_TYPE_DS17285_ALARM_DATE		0
+#define TODC_TYPE_DS17285_CENTURY		0
+#define TODC_TYPE_DS17285_FLAGS			0
+#define TODC_TYPE_DS17285_NVRAM_ADDR_REG	0x50
+#define TODC_TYPE_DS17285_NVRAM_DATA_REG	0x53
+
+#define TODC_TYPE_MC146818_NVRAM_SIZE		0	/* XXXX */
+#define TODC_TYPE_MC146818_SW_FLAGS		0
+#define TODC_TYPE_MC146818_YEAR			0x09
+#define TODC_TYPE_MC146818_MONTH		0x08
+#define TODC_TYPE_MC146818_DOM			0x07	/* Day of Month */
+#define TODC_TYPE_MC146818_DOW			0x06	/* Day of Week */
+#define TODC_TYPE_MC146818_HOURS		0x04
+#define TODC_TYPE_MC146818_MINUTES		0x02
+#define TODC_TYPE_MC146818_SECONDS		0x00
+#define TODC_TYPE_MC146818_CNTL_B		0x0a
+#define TODC_TYPE_MC146818_CNTL_A		0x0b	/* control_a R/W regs */
+#define TODC_TYPE_MC146818_WATCHDOG		0
+#define TODC_TYPE_MC146818_INTERRUPTS		0x0c
+#define TODC_TYPE_MC146818_ALARM_DATE		0xff
+#define TODC_TYPE_MC146818_ALARM_HOUR		0x05
+#define TODC_TYPE_MC146818_ALARM_MINUTES	0x03
+#define TODC_TYPE_MC146818_ALARM_SECONDS	0x01
+#define TODC_TYPE_MC146818_CENTURY		0xff
+#define TODC_TYPE_MC146818_FLAGS		0xff
+#define TODC_TYPE_MC146818_NVRAM_ADDR_REG	0
+#define TODC_TYPE_MC146818_NVRAM_DATA_REG	0
+
+#define TODC_TYPE_PC97307_NVRAM_SIZE		0	/* No NVRAM? */
+#define TODC_TYPE_PC97307_SW_FLAGS		0
+#define TODC_TYPE_PC97307_YEAR			0x09
+#define TODC_TYPE_PC97307_MONTH			0x08
+#define TODC_TYPE_PC97307_DOM			0x07	/* Day of Month */
+#define TODC_TYPE_PC97307_DOW			0x06	/* Day of Week */
+#define TODC_TYPE_PC97307_HOURS			0x04
+#define TODC_TYPE_PC97307_MINUTES		0x02
+#define TODC_TYPE_PC97307_SECONDS		0x00
+#define TODC_TYPE_PC97307_CNTL_B		0x0a
+#define TODC_TYPE_PC97307_CNTL_A		0x0b	/* control_a R/W regs */
+#define TODC_TYPE_PC97307_WATCHDOG		0x0c
+#define TODC_TYPE_PC97307_INTERRUPTS		0x0d
+#define TODC_TYPE_PC97307_ALARM_DATE		0xff
+#define TODC_TYPE_PC97307_ALARM_HOUR		0x05
+#define TODC_TYPE_PC97307_ALARM_MINUTES		0x03
+#define TODC_TYPE_PC97307_ALARM_SECONDS		0x01
+#define TODC_TYPE_PC97307_CENTURY		0xff
+#define TODC_TYPE_PC97307_FLAGS			0xff
+#define TODC_TYPE_PC97307_NVRAM_ADDR_REG	0
+#define TODC_TYPE_PC97307_NVRAM_DATA_REG	0
+
+/*
+ * Define macros to allocate and init the todc_info_t table that will
+ * be used by the todc_time.c routines.
+ */
+#define TODC_ALLOC()							\
+	static todc_info_t todc_info_alloc;				\
+	todc_info_t *todc_info = &todc_info_alloc;
+
+#define TODC_INIT(clock_type, as0, as1, data, bits) {			\
+	todc_info->rtc_type = clock_type;				\
+									\
+	todc_info->nvram_as0 = (unsigned int)(as0);			\
+	todc_info->nvram_as1 = (unsigned int)(as1);			\
+	todc_info->nvram_data = (unsigned int)(data);			\
+									\
+	todc_info->as0_bits = (bits);					\
+									\
+	todc_info->nvram_size = clock_type ##_NVRAM_SIZE;		\
+	todc_info->sw_flags = clock_type ##_SW_FLAGS;			\
+									\
+	todc_info->year = clock_type ##_YEAR;				\
+	todc_info->month = clock_type ##_MONTH;				\
+	todc_info->day_of_month = clock_type ##_DOM;			\
+	todc_info->day_of_week = clock_type ##_DOW;			\
+	todc_info->hours = clock_type ##_HOURS;				\
+	todc_info->minutes = clock_type ##_MINUTES;			\
+	todc_info->seconds = clock_type ##_SECONDS;			\
+	todc_info->control_b = clock_type ##_CNTL_B;			\
+	todc_info->control_a = clock_type ##_CNTL_A;			\
+	todc_info->watchdog = clock_type ##_WATCHDOG;			\
+	todc_info->interrupts = clock_type ##_INTERRUPTS;		\
+	todc_info->alarm_date = clock_type ##_ALARM_DATE;		\
+	todc_info->alarm_hour = clock_type ##_ALARM_HOUR;		\
+	todc_info->alarm_minutes = clock_type ##_ALARM_MINUTES;		\
+	todc_info->alarm_seconds = clock_type ##_ALARM_SECONDS;		\
+	todc_info->century = clock_type ##_CENTURY;			\
+	todc_info->flags = clock_type ##_FLAGS;				\
+									\
+	todc_info->nvram_addr_reg = clock_type ##_NVRAM_ADDR_REG;	\
+	todc_info->nvram_data_reg = clock_type ##_NVRAM_DATA_REG;	\
+}
+
+extern todc_info_t *todc_info;
+
+unsigned char todc_direct_read_val(int addr);
+void todc_direct_write_val(int addr, unsigned char val);
+unsigned char todc_m48txx_read_val(int addr);
+void todc_m48txx_write_val(int addr, unsigned char val);
+unsigned char todc_mc146818_read_val(int addr);
+void todc_mc146818_write_val(int addr, unsigned char val);
+
+long todc_time_init(void);
+void todc_get_rtc_time(struct rtc_time *);
+int todc_set_rtc_time(struct rtc_time *);
+void todc_calibrate_decr(void);
+
+#endif				/* __PPC_KERNEL_TODC_H */
diff --git a/include/asm-powerpc/tracehook.h b/include/asm-powerpc/tracehook.h
new file mode 100644
index 000000000..2cf5dc3bc
--- /dev/null
+++ b/include/asm-powerpc/tracehook.h
@@ -0,0 +1,80 @@
+/*
+ * Tracing hooks, PowerPC CPU support
+ */
+
+#ifndef _ASM_TRACEHOOK_H
+#define _ASM_TRACEHOOK_H	1
+
+#include <linux/sched.h>
+#include <asm/ptrace.h>
+
+/*
+ * See linux/tracehook.h for the descriptions of what these need to do.
+ */
+
+#define ARCH_HAS_SINGLE_STEP	(1)
+
+static inline void tracehook_enable_single_step(struct task_struct *task)
+{
+	struct pt_regs *regs = task->thread.regs;
+	if (regs != NULL) {
+#if defined(CONFIG_PPC32) && (defined(CONFIG_40x) || defined(CONFIG_BOOKE))
+		task->thread.dbcr0 = DBCR0_IDM | DBCR0_IC;
+		regs->msr |= MSR_DE;
+#else
+		regs->msr |= MSR_SE;
+#endif
+	}
+	set_tsk_thread_flag(task, TIF_SINGLESTEP);
+}
+
+static inline void tracehook_disable_single_step(struct task_struct *task)
+{
+	struct pt_regs *regs = task->thread.regs;
+	if (regs != NULL) {
+#if defined(CONFIG_PPC32) && (defined(CONFIG_40x) || defined(CONFIG_BOOKE))
+		task->thread.dbcr0 = 0;
+		regs->msr &= ~MSR_DE;
+#else
+		regs->msr &= ~MSR_SE;
+#endif
+	}
+	clear_tsk_thread_flag(task, TIF_SINGLESTEP);
+}
+
+static inline int tracehook_single_step_enabled(struct task_struct *tsk)
+{
+	return test_tsk_thread_flag(tsk, TIF_SINGLESTEP);
+}
+
+static inline void tracehook_enable_syscall_trace(struct task_struct *tsk)
+{
+	set_tsk_thread_flag(tsk, TIF_SYSCALL_TRACE);
+}
+
+static inline void tracehook_disable_syscall_trace(struct task_struct *tsk)
+{
+	clear_tsk_thread_flag(tsk, TIF_SYSCALL_TRACE);
+}
+
+static inline void tracehook_abort_syscall(struct pt_regs *regs)
+{
+	regs->orig_gpr3 = -1L;
+}
+
+
+extern const struct utrace_regset_view utrace_ppc_native_view;
+static inline const struct utrace_regset_view *
+utrace_native_view(struct task_struct *tsk)
+{
+#ifdef CONFIG_PPC64
+	extern const struct utrace_regset_view utrace_ppc32_view;
+
+	if (test_tsk_thread_flag(tsk, TIF_32BIT))
+		return &utrace_ppc32_view;
+#endif
+	return &utrace_ppc_native_view;
+}
+
+
+#endif
diff --git a/include/asm-powerpc/tsi108.h b/include/asm-powerpc/tsi108.h
new file mode 100644
index 000000000..2c702d35a
--- /dev/null
+++ b/include/asm-powerpc/tsi108.h
@@ -0,0 +1,111 @@
+/*
+ * common routine and memory layout for Tundra TSI108(Grendel) host bridge
+ * memory controller.
+ *
+ * Author: Jacob Pan (jacob.pan@freescale.com)
+ *	   Alex Bounine (alexandreb@tundra.com)
+ *
+ * Copyright 2004-2006 Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#ifndef __PPC_KERNEL_TSI108_H
+#define __PPC_KERNEL_TSI108_H
+
+#include <asm/pci-bridge.h>
+
+/* Size of entire register space */
+#define TSI108_REG_SIZE		(0x10000)
+
+/* Sizes of register spaces for individual blocks */
+#define TSI108_HLP_SIZE		0x1000
+#define TSI108_PCI_SIZE		0x1000
+#define TSI108_CLK_SIZE		0x1000
+#define TSI108_PB_SIZE		0x1000
+#define TSI108_SD_SIZE		0x1000
+#define TSI108_DMA_SIZE		0x1000
+#define TSI108_ETH_SIZE		0x1000
+#define TSI108_I2C_SIZE		0x400
+#define TSI108_MPIC_SIZE	0x400
+#define TSI108_UART0_SIZE	0x200
+#define TSI108_GPIO_SIZE	0x200
+#define TSI108_UART1_SIZE	0x200
+
+/* Offsets within Tsi108(A) CSR space for individual blocks */
+#define TSI108_HLP_OFFSET	0x0000
+#define TSI108_PCI_OFFSET	0x1000
+#define TSI108_CLK_OFFSET	0x2000
+#define TSI108_PB_OFFSET	0x3000
+#define TSI108_SD_OFFSET	0x4000
+#define TSI108_DMA_OFFSET	0x5000
+#define TSI108_ETH_OFFSET	0x6000
+#define TSI108_I2C_OFFSET	0x7000
+#define TSI108_MPIC_OFFSET	0x7400
+#define TSI108_UART0_OFFSET	0x7800
+#define TSI108_GPIO_OFFSET	0x7A00
+#define TSI108_UART1_OFFSET	0x7C00
+
+/* Tsi108 registers used by common code components */
+#define TSI108_PCI_CSR		(0x004)
+#define TSI108_PCI_IRP_CFG_CTL	(0x180)
+#define TSI108_PCI_IRP_STAT	(0x184)
+#define TSI108_PCI_IRP_ENABLE	(0x188)
+#define TSI108_PCI_IRP_INTAD	(0x18C)
+
+#define TSI108_PCI_IRP_STAT_P_INT	(0x00400000)
+#define TSI108_PCI_IRP_ENABLE_P_INT	(0x00400000)
+
+#define TSI108_CG_PWRUP_STATUS	(0x234)
+
+#define TSI108_PB_ISR		(0x00C)
+#define TSI108_PB_ERRCS		(0x404)
+#define TSI108_PB_AERR		(0x408)
+
+#define TSI108_PB_ERRCS_ES		(1 << 1)
+#define TSI108_PB_ISR_PBS_RD_ERR	(1 << 8)
+
+#define TSI108_PCI_CFG_BASE_PHYS	(0xfb000000)
+#define TSI108_PCI_CFG_SIZE		(0x01000000)
+/* Global variables */
+
+extern u32 tsi108_pci_cfg_base;
+/* Exported functions */
+
+extern int tsi108_bridge_init(struct pci_controller *hose, uint phys_csr_base);
+extern unsigned long tsi108_get_mem_size(void);
+extern unsigned long tsi108_get_cpu_clk(void);
+extern unsigned long tsi108_get_sdc_clk(void);
+extern int tsi108_direct_write_config(struct pci_bus *bus, unsigned int devfn,
+				      int offset, int len, u32 val);
+extern int tsi108_direct_read_config(struct pci_bus *bus, unsigned int devfn,
+				     int offset, int len, u32 * val);
+extern void tsi108_clear_pci_error(u32 pci_cfg_base);
+
+extern phys_addr_t get_csrbase(void);
+
+typedef struct {
+	u32 regs;		/* hw registers base address */
+	u32 phyregs;		/* phy registers base address */
+	u16 phy;		/* phy address */
+	u16 irq_num;		/* irq number */
+	u8 mac_addr[6];		/* phy mac address */
+} hw_info;
+
+extern u32 get_vir_csrbase(void);
+extern u32 tsi108_csr_vir_base;
+
+extern inline u32 tsi108_read_reg(u32 reg_offset)
+{
+	return in_be32((volatile u32 *)(tsi108_csr_vir_base + reg_offset));
+}
+
+extern inline void tsi108_write_reg(u32 reg_offset, u32 val)
+{
+	out_be32((volatile u32 *)(tsi108_csr_vir_base + reg_offset), val);
+}
+
+#endif				/* __PPC_KERNEL_TSI108_H */
diff --git a/include/asm-powerpc/tsi108_irq.h b/include/asm-powerpc/tsi108_irq.h
new file mode 100644
index 000000000..3e4d04eff
--- /dev/null
+++ b/include/asm-powerpc/tsi108_irq.h
@@ -0,0 +1,124 @@
+/*
+ * (C) Copyright 2005 Tundra Semiconductor Corp.
+ * Alex Bounine, <alexandreb at tundra.com).
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * 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
+ */
+
+/*
+ * definitions for interrupt controller initialization and external interrupt
+ * demultiplexing on TSI108EMU/SVB boards.
+ */
+
+#ifndef _ASM_PPC_TSI108_IRQ_H
+#define _ASM_PPC_TSI108_IRQ_H
+
+/*
+ * Tsi108 interrupts
+ */
+#ifndef TSI108_IRQ_REG_BASE
+#define TSI108_IRQ_REG_BASE		0
+#endif
+
+#define TSI108_IRQ(x)		(TSI108_IRQ_REG_BASE + (x))
+
+#define TSI108_MAX_VECTORS	(36 + 4)	/* 36 sources + PCI INT demux */
+#define MAX_TASK_PRIO	0xF
+
+#define TSI108_IRQ_SPURIOUS	(TSI108_MAX_VECTORS)
+
+#define DEFAULT_PRIO_LVL	10	/* initial priority level */
+
+/* Interrupt vectors assignment to external and internal
+ * sources of requests. */
+
+/* EXTERNAL INTERRUPT SOURCES */
+
+#define IRQ_TSI108_EXT_INT0	TSI108_IRQ(0)	/* External Source at INT[0] */
+#define IRQ_TSI108_EXT_INT1	TSI108_IRQ(1)	/* External Source at INT[1] */
+#define IRQ_TSI108_EXT_INT2	TSI108_IRQ(2)	/* External Source at INT[2] */
+#define IRQ_TSI108_EXT_INT3	TSI108_IRQ(3)	/* External Source at INT[3] */
+
+/* INTERNAL INTERRUPT SOURCES */
+
+#define IRQ_TSI108_RESERVED0	TSI108_IRQ(4)	/* Reserved IRQ */
+#define IRQ_TSI108_RESERVED1	TSI108_IRQ(5)	/* Reserved IRQ */
+#define IRQ_TSI108_RESERVED2	TSI108_IRQ(6)	/* Reserved IRQ */
+#define IRQ_TSI108_RESERVED3	TSI108_IRQ(7)	/* Reserved IRQ */
+#define IRQ_TSI108_DMA0		TSI108_IRQ(8)	/* DMA0 */
+#define IRQ_TSI108_DMA1		TSI108_IRQ(9)	/* DMA1 */
+#define IRQ_TSI108_DMA2		TSI108_IRQ(10)	/* DMA2 */
+#define IRQ_TSI108_DMA3		TSI108_IRQ(11)	/* DMA3 */
+#define IRQ_TSI108_UART0	TSI108_IRQ(12)	/* UART0 */
+#define IRQ_TSI108_UART1	TSI108_IRQ(13)	/* UART1 */
+#define IRQ_TSI108_I2C		TSI108_IRQ(14)	/* I2C */
+#define IRQ_TSI108_GPIO		TSI108_IRQ(15)	/* GPIO */
+#define IRQ_TSI108_GIGE0	TSI108_IRQ(16)	/* GIGE0 */
+#define IRQ_TSI108_GIGE1	TSI108_IRQ(17)	/* GIGE1 */
+#define IRQ_TSI108_RESERVED4	TSI108_IRQ(18)	/* Reserved IRQ */
+#define IRQ_TSI108_HLP		TSI108_IRQ(19)	/* HLP */
+#define IRQ_TSI108_SDRAM	TSI108_IRQ(20)	/* SDC */
+#define IRQ_TSI108_PROC_IF	TSI108_IRQ(21)	/* Processor IF */
+#define IRQ_TSI108_RESERVED5	TSI108_IRQ(22)	/* Reserved IRQ */
+#define IRQ_TSI108_PCI		TSI108_IRQ(23)	/* PCI/X block */
+
+#define IRQ_TSI108_MBOX0	TSI108_IRQ(24)	/* Mailbox 0 register */
+#define IRQ_TSI108_MBOX1	TSI108_IRQ(25)	/* Mailbox 1 register */
+#define IRQ_TSI108_MBOX2	TSI108_IRQ(26)	/* Mailbox 2 register */
+#define IRQ_TSI108_MBOX3	TSI108_IRQ(27)	/* Mailbox 3 register */
+
+#define IRQ_TSI108_DBELL0	TSI108_IRQ(28)	/* Doorbell 0 */
+#define IRQ_TSI108_DBELL1	TSI108_IRQ(29)	/* Doorbell 1 */
+#define IRQ_TSI108_DBELL2	TSI108_IRQ(30)	/* Doorbell 2 */
+#define IRQ_TSI108_DBELL3	TSI108_IRQ(31)	/* Doorbell 3 */
+
+#define IRQ_TSI108_TIMER0	TSI108_IRQ(32)	/* Global Timer 0 */
+#define IRQ_TSI108_TIMER1	TSI108_IRQ(33)	/* Global Timer 1 */
+#define IRQ_TSI108_TIMER2	TSI108_IRQ(34)	/* Global Timer 2 */
+#define IRQ_TSI108_TIMER3	TSI108_IRQ(35)	/* Global Timer 3 */
+
+/*
+ * PCI bus INTA# - INTD# lines demultiplexor
+ */
+#define IRQ_PCI_INTAD_BASE	TSI108_IRQ(36)
+#define IRQ_PCI_INTA		(IRQ_PCI_INTAD_BASE + 0)
+#define IRQ_PCI_INTB		(IRQ_PCI_INTAD_BASE + 1)
+#define IRQ_PCI_INTC		(IRQ_PCI_INTAD_BASE + 2)
+#define IRQ_PCI_INTD		(IRQ_PCI_INTAD_BASE + 3)
+#define NUM_PCI_IRQS		(4)
+
+/* number of entries in vector dispatch table */
+#define IRQ_TSI108_TAB_SIZE	(TSI108_MAX_VECTORS + 1)
+
+/* Mapping of MPIC outputs to processors' interrupt pins */
+
+#define IDIR_INT_OUT0		0x1
+#define IDIR_INT_OUT1		0x2
+#define IDIR_INT_OUT2		0x4
+#define IDIR_INT_OUT3		0x8
+
+/*---------------------------------------------------------------
+ * IRQ line configuration parameters */
+
+/* Interrupt delivery modes */
+typedef enum {
+	TSI108_IRQ_DIRECTED,
+	TSI108_IRQ_DISTRIBUTED,
+} TSI108_IRQ_MODE;
+#endif				/*  _ASM_PPC_TSI108_IRQ_H */
diff --git a/include/asm-s390/Kbuild b/include/asm-s390/Kbuild
new file mode 100644
index 000000000..14158a4a9
--- /dev/null
+++ b/include/asm-s390/Kbuild
@@ -0,0 +1,11 @@
+include include/asm-generic/Kbuild.asm
+
+header-y += dasd.h
+header-y += qeth.h
+header-y += tape390.h
+header-y += ucontext.h
+header-y += vtoc.h
+header-y += z90crypt.h
+
+unifdef-y += cmb.h
+unifdef-y += debug.h
diff --git a/include/asm-s390/irqflags.h b/include/asm-s390/irqflags.h
new file mode 100644
index 000000000..3b566a5b3
--- /dev/null
+++ b/include/asm-s390/irqflags.h
@@ -0,0 +1,56 @@
+/*
+ *  include/asm-s390/irqflags.h
+ *
+ *    Copyright (C) IBM Corp. 2006
+ *    Author(s): Heiko Carstens <heiko.carstens@de.ibm.com>
+ */
+
+#ifndef __ASM_IRQFLAGS_H
+#define __ASM_IRQFLAGS_H
+
+#ifdef __KERNEL__
+
+/* interrupt control.. */
+#define raw_local_irq_enable() ({ \
+	unsigned long  __dummy; \
+	__asm__ __volatile__ ( \
+		"stosm 0(%1),0x03" \
+		: "=m" (__dummy) : "a" (&__dummy) : "memory" ); \
+	})
+
+#define raw_local_irq_disable() ({ \
+	unsigned long __flags; \
+	__asm__ __volatile__ ( \
+		"stnsm 0(%1),0xfc" : "=m" (__flags) : "a" (&__flags) ); \
+	__flags; \
+	})
+
+#define raw_local_save_flags(x)							\
+do {										\
+	typecheck(unsigned long, x);						\
+	__asm__ __volatile__("stosm 0(%1),0" : "=m" (x) : "a" (&x), "m" (x) );	\
+} while (0)
+
+#define raw_local_irq_restore(x)						\
+do {										\
+	typecheck(unsigned long, x);						\
+	__asm__ __volatile__("ssm   0(%0)" : : "a" (&x), "m" (x) : "memory");	\
+} while (0)
+
+#define raw_irqs_disabled()		\
+({					\
+	unsigned long flags;		\
+	raw_local_save_flags(flags);	\
+	!((flags >> __FLAG_SHIFT) & 3);	\
+})
+
+static inline int raw_irqs_disabled_flags(unsigned long flags)
+{
+	return !((flags >> __FLAG_SHIFT) & 3);
+}
+
+/* For spinlocks etc */
+#define raw_local_irq_save(x)	((x) = raw_local_irq_disable())
+
+#endif /* __KERNEL__ */
+#endif /* __ASM_IRQFLAGS_H */
diff --git a/include/asm-s390/tracehook.h b/include/asm-s390/tracehook.h
new file mode 100644
index 000000000..8fc8c3888
--- /dev/null
+++ b/include/asm-s390/tracehook.h
@@ -0,0 +1,53 @@
+/*
+ * Tracing hooks, s390/s390x support.
+ */
+
+#ifndef _ASM_TRACEHOOK_H
+#define _ASM_TRACEHOOK_H	1
+
+#include <linux/sched.h>
+#include <asm/ptrace.h>
+
+/*
+ * See linux/tracehook.h for the descriptions of what these need to do.
+ */
+
+#define ARCH_HAS_SINGLE_STEP	(1)
+
+/* These three are defined in arch/s390/kernel/ptrace.c.  */
+void tracehook_enable_single_step(struct task_struct *tsk);
+void tracehook_disable_single_step(struct task_struct *tsk);
+int tracehook_single_step_enabled(struct task_struct *tsk);
+
+
+static inline void tracehook_enable_syscall_trace(struct task_struct *tsk)
+{
+	set_tsk_thread_flag(tsk, TIF_SYSCALL_TRACE);
+}
+
+static inline void tracehook_disable_syscall_trace(struct task_struct *tsk)
+{
+	clear_tsk_thread_flag(tsk, TIF_SYSCALL_TRACE);
+}
+
+static inline void tracehook_abort_syscall(struct pt_regs *regs)
+{
+	regs->gprs[2] = -1L;
+}
+
+
+extern const struct utrace_regset_view utrace_s390_native_view;
+static inline const struct utrace_regset_view *
+utrace_native_view(struct task_struct *tsk)
+{
+#ifdef CONFIG_COMPAT
+        extern const struct utrace_regset_view utrace_s390_compat_view;
+
+        if (test_tsk_thread_flag(tsk, TIF_31BIT))
+                return &utrace_s390_compat_view;
+#endif
+        return &utrace_s390_native_view;
+}
+
+
+#endif
diff --git a/include/asm-s390/z90crypt.h b/include/asm-s390/z90crypt.h
new file mode 100644
index 000000000..31a2439b0
--- /dev/null
+++ b/include/asm-s390/z90crypt.h
@@ -0,0 +1,212 @@
+/*
+ *  include/asm-s390/z90crypt.h
+ *
+ *  z90crypt 1.3.3 (user-visible header)
+ *
+ *  Copyright (C)  2001, 2005 IBM Corporation
+ *  Author(s): Robert Burroughs
+ *             Eric Rossman (edrossma@us.ibm.com)
+ *
+ *  Hotplug & misc device support: Jochen Roehrig (roehrig@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.
+ */
+
+#ifndef __ASM_S390_Z90CRYPT_H
+#define __ASM_S390_Z90CRYPT_H
+#include <linux/ioctl.h>
+
+#define z90crypt_VERSION 1
+#define z90crypt_RELEASE 3	// 2 = PCIXCC, 3 = rewrite for coding standards
+#define z90crypt_VARIANT 3	// 3 = CEX2A support
+
+/**
+ * struct ica_rsa_modexpo
+ *
+ * Requirements:
+ * - outputdatalength is at least as large as inputdatalength.
+ * - All key parts are right justified in their fields, padded on
+ *   the left with zeroes.
+ * - length(b_key) = inputdatalength
+ * - length(n_modulus) = inputdatalength
+ */
+struct ica_rsa_modexpo {
+	char __user *	inputdata;
+	unsigned int	inputdatalength;
+	char __user *	outputdata;
+	unsigned int	outputdatalength;
+	char __user *	b_key;
+	char __user *	n_modulus;
+};
+
+/**
+ * struct ica_rsa_modexpo_crt
+ *
+ * Requirements:
+ * - inputdatalength is even.
+ * - outputdatalength is at least as large as inputdatalength.
+ * - All key parts are right justified in their fields, padded on
+ *   the left with zeroes.
+ * - length(bp_key)	= inputdatalength/2 + 8
+ * - length(bq_key)	= inputdatalength/2
+ * - length(np_key)	= inputdatalength/2 + 8
+ * - length(nq_key)	= inputdatalength/2
+ * - length(u_mult_inv) = inputdatalength/2 + 8
+ */
+struct ica_rsa_modexpo_crt {
+	char __user *	inputdata;
+	unsigned int	inputdatalength;
+	char __user *	outputdata;
+	unsigned int	outputdatalength;
+	char __user *	bp_key;
+	char __user *	bq_key;
+	char __user *	np_prime;
+	char __user *	nq_prime;
+	char __user *	u_mult_inv;
+};
+
+#define Z90_IOCTL_MAGIC 'z'  // NOTE:  Need to allocate from linux folks
+
+/**
+ * Interface notes:
+ *
+ * The ioctl()s which are implemented (along with relevant details)
+ * are:
+ *
+ *   ICARSAMODEXPO
+ *     Perform an RSA operation using a Modulus-Exponent pair
+ *     This takes an ica_rsa_modexpo struct as its arg.
+ *
+ *     NOTE: please refer to the comments preceding this structure
+ *           for the implementation details for the contents of the
+ *           block
+ *
+ *   ICARSACRT
+ *     Perform an RSA operation using a Chinese-Remainder Theorem key
+ *     This takes an ica_rsa_modexpo_crt struct as its arg.
+ *
+ *     NOTE: please refer to the comments preceding this structure
+ *           for the implementation details for the contents of the
+ *           block
+ *
+ *   Z90STAT_TOTALCOUNT
+ *     Return an integer count of all device types together.
+ *
+ *   Z90STAT_PCICACOUNT
+ *     Return an integer count of all PCICAs.
+ *
+ *   Z90STAT_PCICCCOUNT
+ *     Return an integer count of all PCICCs.
+ *
+ *   Z90STAT_PCIXCCMCL2COUNT
+ *     Return an integer count of all MCL2 PCIXCCs.
+ *
+ *   Z90STAT_PCIXCCMCL3COUNT
+ *     Return an integer count of all MCL3 PCIXCCs.
+ *
+ *   Z90STAT_CEX2CCOUNT
+ *     Return an integer count of all CEX2Cs.
+ *
+ *   Z90STAT_CEX2ACOUNT
+ *     Return an integer count of all CEX2As.
+ *
+ *   Z90STAT_REQUESTQ_COUNT
+ *     Return an integer count of the number of entries waiting to be
+ *     sent to a device.
+ *
+ *   Z90STAT_PENDINGQ_COUNT
+ *     Return an integer count of the number of entries sent to a
+ *     device awaiting the reply.
+ *
+ *   Z90STAT_TOTALOPEN_COUNT
+ *     Return an integer count of the number of open file handles.
+ *
+ *   Z90STAT_DOMAIN_INDEX
+ *     Return the integer value of the Cryptographic Domain.
+ *
+ *   Z90STAT_STATUS_MASK
+ *     Return an 64 element array of unsigned chars for the status of
+ *     all devices.
+ *       0x01: PCICA
+ *       0x02: PCICC
+ *       0x03: PCIXCC_MCL2
+ *       0x04: PCIXCC_MCL3
+ *       0x05: CEX2C
+ *       0x06: CEX2A
+ *       0x0d: device is disabled via the proc filesystem
+ *
+ *   Z90STAT_QDEPTH_MASK
+ *     Return an 64 element array of unsigned chars for the queue
+ *     depth of all devices.
+ *
+ *   Z90STAT_PERDEV_REQCNT
+ *     Return an 64 element array of unsigned integers for the number
+ *     of successfully completed requests per device since the device
+ *     was detected and made available.
+ *
+ *   ICAZ90STATUS (deprecated)
+ *     Return some device driver status in a ica_z90_status struct
+ *     This takes an ica_z90_status struct as its arg.
+ *
+ *     NOTE: this ioctl() is deprecated, and has been replaced with
+ *           single ioctl()s for each type of status being requested
+ *
+ *   Z90STAT_PCIXCCCOUNT (deprecated)
+ *     Return an integer count of all PCIXCCs (MCL2 + MCL3).
+ *     This is DEPRECATED now that MCL3 PCIXCCs are treated differently from
+ *     MCL2 PCIXCCs.
+ *
+ *   Z90QUIESCE (not recommended)
+ *     Quiesce the driver.  This is intended to stop all new
+ *     requests from being processed.  Its use is NOT recommended,
+ *     except in circumstances where there is no other way to stop
+ *     callers from accessing the driver.  Its original use was to
+ *     allow the driver to be "drained" of work in preparation for
+ *     a system shutdown.
+ *
+ *     NOTE: once issued, this ban on new work cannot be undone
+ *           except by unloading and reloading the driver.
+ */
+
+/**
+ * Supported ioctl calls
+ */
+#define ICARSAMODEXPO	_IOC(_IOC_READ|_IOC_WRITE, Z90_IOCTL_MAGIC, 0x05, 0)
+#define ICARSACRT	_IOC(_IOC_READ|_IOC_WRITE, Z90_IOCTL_MAGIC, 0x06, 0)
+
+/* DEPRECATED status calls (bound for removal at some point) */
+#define ICAZ90STATUS	_IOR(Z90_IOCTL_MAGIC, 0x10, struct ica_z90_status)
+#define Z90STAT_PCIXCCCOUNT	_IOR(Z90_IOCTL_MAGIC, 0x43, int)
+
+/* unrelated to ICA callers */
+#define Z90QUIESCE	_IO(Z90_IOCTL_MAGIC, 0x11)
+
+/* New status calls */
+#define Z90STAT_TOTALCOUNT	_IOR(Z90_IOCTL_MAGIC, 0x40, int)
+#define Z90STAT_PCICACOUNT	_IOR(Z90_IOCTL_MAGIC, 0x41, int)
+#define Z90STAT_PCICCCOUNT	_IOR(Z90_IOCTL_MAGIC, 0x42, int)
+#define Z90STAT_PCIXCCMCL2COUNT	_IOR(Z90_IOCTL_MAGIC, 0x4b, int)
+#define Z90STAT_PCIXCCMCL3COUNT	_IOR(Z90_IOCTL_MAGIC, 0x4c, int)
+#define Z90STAT_CEX2CCOUNT	_IOR(Z90_IOCTL_MAGIC, 0x4d, int)
+#define Z90STAT_CEX2ACOUNT	_IOR(Z90_IOCTL_MAGIC, 0x4e, int)
+#define Z90STAT_REQUESTQ_COUNT	_IOR(Z90_IOCTL_MAGIC, 0x44, int)
+#define Z90STAT_PENDINGQ_COUNT	_IOR(Z90_IOCTL_MAGIC, 0x45, int)
+#define Z90STAT_TOTALOPEN_COUNT _IOR(Z90_IOCTL_MAGIC, 0x46, int)
+#define Z90STAT_DOMAIN_INDEX	_IOR(Z90_IOCTL_MAGIC, 0x47, int)
+#define Z90STAT_STATUS_MASK	_IOR(Z90_IOCTL_MAGIC, 0x48, char[64])
+#define Z90STAT_QDEPTH_MASK	_IOR(Z90_IOCTL_MAGIC, 0x49, char[64])
+#define Z90STAT_PERDEV_REQCNT	_IOR(Z90_IOCTL_MAGIC, 0x4a, int[64])
+
+#endif /* __ASM_S390_Z90CRYPT_H */
diff --git a/include/asm-sh/Kbuild b/include/asm-sh/Kbuild
new file mode 100644
index 000000000..c68e1680d
--- /dev/null
+++ b/include/asm-sh/Kbuild
@@ -0,0 +1 @@
+include include/asm-generic/Kbuild.asm
diff --git a/include/asm-sh64/Kbuild b/include/asm-sh64/Kbuild
new file mode 100644
index 000000000..c68e1680d
--- /dev/null
+++ b/include/asm-sh64/Kbuild
@@ -0,0 +1 @@
+include include/asm-generic/Kbuild.asm
diff --git a/include/asm-sparc/Kbuild b/include/asm-sparc/Kbuild
new file mode 100644
index 000000000..c6a55cf0d
--- /dev/null
+++ b/include/asm-sparc/Kbuild
@@ -0,0 +1,15 @@
+include include/asm-generic/Kbuild.asm
+
+header-y += apc.h
+header-y += asi.h
+header-y += bpp.h
+header-y += jsflash.h
+header-y += openpromio.h
+header-y += pconf.h
+header-y += reg.h
+header-y += traps.h
+header-y += vfc_ioctls.h
+
+unifdef-y += fbio.h
+unifdef-y += perfctr.h
+unifdef-y += psr.h
diff --git a/include/asm-sparc/of_device.h b/include/asm-sparc/of_device.h
new file mode 100644
index 000000000..80ea31f6e
--- /dev/null
+++ b/include/asm-sparc/of_device.h
@@ -0,0 +1,79 @@
+#ifndef _ASM_SPARC_OF_DEVICE_H
+#define _ASM_SPARC_OF_DEVICE_H
+#ifdef __KERNEL__
+
+#include <linux/device.h>
+#include <linux/mod_devicetable.h>
+#include <asm/openprom.h>
+#include <asm/prom.h>
+
+extern struct bus_type ebus_bus_type;
+extern struct bus_type sbus_bus_type;
+extern struct bus_type of_bus_type;
+
+/*
+ * The of_device is a kind of "base class" that is a superset of
+ * struct device for use by devices attached to an OF node and
+ * probed using OF properties.
+ */
+struct of_device
+{
+	struct device_node		*node;
+	struct device			dev;
+	struct resource			resource[PROMREG_MAX];
+	unsigned int			irqs[PROMINTR_MAX];
+	int				num_irqs;
+
+	void				*sysdata;
+
+	int				slot;
+	int				portid;
+	int				clock_freq;
+};
+#define	to_of_device(d) container_of(d, struct of_device, dev)
+
+extern void __iomem *of_ioremap(struct resource *res, unsigned long offset, unsigned long size, char *name);
+extern void of_iounmap(void __iomem *base, unsigned long size);
+
+extern struct of_device *of_find_device_by_node(struct device_node *);
+
+extern const struct of_device_id *of_match_device(
+	const struct of_device_id *matches, const struct of_device *dev);
+
+extern struct of_device *of_dev_get(struct of_device *dev);
+extern void of_dev_put(struct of_device *dev);
+
+/*
+ * An of_platform_driver driver is attached to a basic of_device on
+ * the ISA, EBUS, and SBUS busses on sparc64.
+ */
+struct of_platform_driver
+{
+	char			*name;
+	struct of_device_id	*match_table;
+	struct module		*owner;
+
+	int	(*probe)(struct of_device* dev, const struct of_device_id *match);
+	int	(*remove)(struct of_device* dev);
+
+	int	(*suspend)(struct of_device* dev, pm_message_t state);
+	int	(*resume)(struct of_device* dev);
+	int	(*shutdown)(struct of_device* dev);
+
+	struct device_driver	driver;
+};
+#define	to_of_platform_driver(drv) container_of(drv,struct of_platform_driver, driver)
+
+extern int of_register_driver(struct of_platform_driver *drv,
+			      struct bus_type *bus);
+extern void of_unregister_driver(struct of_platform_driver *drv);
+extern int of_device_register(struct of_device *ofdev);
+extern void of_device_unregister(struct of_device *ofdev);
+extern struct of_device *of_platform_device_create(struct device_node *np,
+						   const char *bus_id,
+						   struct device *parent,
+						   struct bus_type *bus);
+extern void of_release_dev(struct device *dev);
+
+#endif /* __KERNEL__ */
+#endif /* _ASM_SPARC_OF_DEVICE_H */
diff --git a/include/asm-sparc/prom.h b/include/asm-sparc/prom.h
new file mode 100644
index 000000000..86c13dcce
--- /dev/null
+++ b/include/asm-sparc/prom.h
@@ -0,0 +1,104 @@
+#ifndef _SPARC_PROM_H
+#define _SPARC_PROM_H
+#ifdef __KERNEL__
+
+
+/*
+ * Definitions for talking to the Open Firmware PROM on
+ * Power Macintosh computers.
+ *
+ * Copyright (C) 1996-2005 Paul Mackerras.
+ *
+ * Updates for PPC64 by Peter Bergner & David Engebretsen, IBM Corp.
+ * Updates for SPARC32 by David S. Miller
+ *
+ * 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/types.h>
+#include <linux/proc_fs.h>
+#include <asm/atomic.h>
+
+typedef u32 phandle;
+typedef u32 ihandle;
+
+struct property {
+	char	*name;
+	int	length;
+	void	*value;
+	struct property *next;
+	unsigned long _flags;
+	unsigned int unique_id;
+};
+
+struct device_node {
+	char	*name;
+	char	*type;
+	phandle	node;
+	char	*path_component_name;
+	char	*full_name;
+
+	struct	property *properties;
+	struct  property *deadprops; /* removed properties */
+	struct	device_node *parent;
+	struct	device_node *child;
+	struct	device_node *sibling;
+	struct	device_node *next;	/* next device of same type */
+	struct	device_node *allnext;	/* next in list of all nodes */
+	struct  proc_dir_entry *pde;	/* this node's proc directory */
+	struct  kref kref;
+	unsigned long _flags;
+	void	*data;
+	unsigned int unique_id;
+};
+
+/* flag descriptions */
+#define OF_DYNAMIC 1 /* node and properties were allocated via kmalloc */
+
+#define OF_IS_DYNAMIC(x) test_bit(OF_DYNAMIC, &x->_flags)
+#define OF_MARK_DYNAMIC(x) set_bit(OF_DYNAMIC, &x->_flags)
+
+#define OF_BAD_ADDR	((u64)-1)
+
+static inline void set_node_proc_entry(struct device_node *dn, struct proc_dir_entry *de)
+{
+	dn->pde = de;
+}
+
+extern struct device_node *of_find_node_by_name(struct device_node *from,
+	const char *name);
+#define for_each_node_by_name(dn, name) \
+	for (dn = of_find_node_by_name(NULL, name); dn; \
+	     dn = of_find_node_by_name(dn, name))
+extern struct device_node *of_find_node_by_type(struct device_node *from,
+	const char *type);
+#define for_each_node_by_type(dn, type) \
+	for (dn = of_find_node_by_type(NULL, type); dn; \
+	     dn = of_find_node_by_type(dn, type))
+extern struct device_node *of_find_compatible_node(struct device_node *from,
+	const char *type, const char *compat);
+extern struct device_node *of_find_node_by_path(const char *path);
+extern struct device_node *of_find_node_by_phandle(phandle handle);
+extern struct device_node *of_get_parent(const struct device_node *node);
+extern struct device_node *of_get_next_child(const struct device_node *node,
+					     struct device_node *prev);
+extern struct property *of_find_property(struct device_node *np,
+					 const char *name,
+					 int *lenp);
+extern int of_device_is_compatible(struct device_node *device, const char *);
+extern void *of_get_property(struct device_node *node, const char *name,
+			     int *lenp);
+extern int of_set_property(struct device_node *node, const char *name, void *val, int len);
+extern int of_getintprop_default(struct device_node *np,
+				 const char *name,
+				 int def);
+extern int of_n_addr_cells(struct device_node *np);
+extern int of_n_size_cells(struct device_node *np);
+
+extern void prom_build_devicetree(void);
+
+#endif /* __KERNEL__ */
+#endif /* _SPARC_PROM_H */
diff --git a/include/asm-sparc64/Kbuild b/include/asm-sparc64/Kbuild
new file mode 100644
index 000000000..a7f44408c
--- /dev/null
+++ b/include/asm-sparc64/Kbuild
@@ -0,0 +1,26 @@
+include include/asm-generic/Kbuild.asm
+
+ALTARCH := sparc
+ARCHDEF := defined __sparc__ && defined __arch64__
+ALTARCHDEF := defined __sparc__ && !defined __arch64__
+
+header-y += apb.h
+header-y += asi.h
+header-y += bbc.h
+header-y += bpp.h
+header-y += const.h
+header-y += display7seg.h
+header-y += envctrl.h
+header-y += ipc.h
+header-y += openprom.h
+header-y += openpromio.h
+header-y += pconf.h
+header-y += psrcompat.h
+header-y += pstate.h
+header-y += reg.h
+header-y += uctx.h
+header-y += utrap.h
+header-y += watchdog.h
+
+unifdef-y += fbio.h
+unifdef-y += perfctr.h
diff --git a/include/asm-sparc64/of_device.h b/include/asm-sparc64/of_device.h
new file mode 100644
index 000000000..a62c7b997
--- /dev/null
+++ b/include/asm-sparc64/of_device.h
@@ -0,0 +1,80 @@
+#ifndef _ASM_SPARC64_OF_DEVICE_H
+#define _ASM_SPARC64_OF_DEVICE_H
+#ifdef __KERNEL__
+
+#include <linux/device.h>
+#include <linux/mod_devicetable.h>
+#include <asm/openprom.h>
+#include <asm/prom.h>
+
+extern struct bus_type isa_bus_type;
+extern struct bus_type ebus_bus_type;
+extern struct bus_type sbus_bus_type;
+extern struct bus_type of_bus_type;
+
+/*
+ * The of_device is a kind of "base class" that is a superset of
+ * struct device for use by devices attached to an OF node and
+ * probed using OF properties.
+ */
+struct of_device
+{
+	struct device_node		*node;
+	struct device			dev;
+	struct resource			resource[PROMREG_MAX];
+	unsigned int			irqs[PROMINTR_MAX];
+	int				num_irqs;
+
+	void				*sysdata;
+
+	int				slot;
+	int				portid;
+	int				clock_freq;
+};
+#define	to_of_device(d) container_of(d, struct of_device, dev)
+
+extern void __iomem *of_ioremap(struct resource *res, unsigned long offset, unsigned long size, char *name);
+extern void of_iounmap(void __iomem *base, unsigned long size);
+
+extern struct of_device *of_find_device_by_node(struct device_node *);
+
+extern const struct of_device_id *of_match_device(
+	const struct of_device_id *matches, const struct of_device *dev);
+
+extern struct of_device *of_dev_get(struct of_device *dev);
+extern void of_dev_put(struct of_device *dev);
+
+/*
+ * An of_platform_driver driver is attached to a basic of_device on
+ * the ISA, EBUS, and SBUS busses on sparc64.
+ */
+struct of_platform_driver
+{
+	char			*name;
+	struct of_device_id	*match_table;
+	struct module		*owner;
+
+	int	(*probe)(struct of_device* dev, const struct of_device_id *match);
+	int	(*remove)(struct of_device* dev);
+
+	int	(*suspend)(struct of_device* dev, pm_message_t state);
+	int	(*resume)(struct of_device* dev);
+	int	(*shutdown)(struct of_device* dev);
+
+	struct device_driver	driver;
+};
+#define	to_of_platform_driver(drv) container_of(drv,struct of_platform_driver, driver)
+
+extern int of_register_driver(struct of_platform_driver *drv,
+			      struct bus_type *bus);
+extern void of_unregister_driver(struct of_platform_driver *drv);
+extern int of_device_register(struct of_device *ofdev);
+extern void of_device_unregister(struct of_device *ofdev);
+extern struct of_device *of_platform_device_create(struct device_node *np,
+						   const char *bus_id,
+						   struct device *parent,
+						   struct bus_type *bus);
+extern void of_release_dev(struct device *dev);
+
+#endif /* __KERNEL__ */
+#endif /* _ASM_SPARC64_OF_DEVICE_H */
diff --git a/include/asm-sparc64/prom.h b/include/asm-sparc64/prom.h
new file mode 100644
index 000000000..99671ed66
--- /dev/null
+++ b/include/asm-sparc64/prom.h
@@ -0,0 +1,112 @@
+#ifndef _SPARC64_PROM_H
+#define _SPARC64_PROM_H
+#ifdef __KERNEL__
+
+
+/*
+ * Definitions for talking to the Open Firmware PROM on
+ * Power Macintosh computers.
+ *
+ * Copyright (C) 1996-2005 Paul Mackerras.
+ *
+ * Updates for PPC64 by Peter Bergner & David Engebretsen, IBM Corp.
+ * Updates for SPARC64 by David S. Miller
+ *
+ * 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/types.h>
+#include <linux/proc_fs.h>
+#include <asm/atomic.h>
+
+typedef u32 phandle;
+typedef u32 ihandle;
+
+struct property {
+	char	*name;
+	int	length;
+	void	*value;
+	struct property *next;
+	unsigned long _flags;
+	unsigned int unique_id;
+};
+
+struct of_irq_controller;
+struct device_node {
+	char	*name;
+	char	*type;
+	phandle	node;
+	char	*path_component_name;
+	char	*full_name;
+
+	struct	property *properties;
+	struct  property *deadprops; /* removed properties */
+	struct	device_node *parent;
+	struct	device_node *child;
+	struct	device_node *sibling;
+	struct	device_node *next;	/* next device of same type */
+	struct	device_node *allnext;	/* next in list of all nodes */
+	struct  proc_dir_entry *pde;	/* this node's proc directory */
+	struct  kref kref;
+	unsigned long _flags;
+	void	*data;
+	unsigned int unique_id;
+
+	struct of_irq_controller *irq_trans;
+};
+
+struct of_irq_controller {
+	unsigned int	(*irq_build)(struct device_node *, unsigned int, void *);
+	void		*data;
+};
+
+/* flag descriptions */
+#define OF_DYNAMIC 1 /* node and properties were allocated via kmalloc */
+
+#define OF_IS_DYNAMIC(x) test_bit(OF_DYNAMIC, &x->_flags)
+#define OF_MARK_DYNAMIC(x) set_bit(OF_DYNAMIC, &x->_flags)
+
+#define OF_BAD_ADDR	((u64)-1)
+
+static inline void set_node_proc_entry(struct device_node *dn, struct proc_dir_entry *de)
+{
+	dn->pde = de;
+}
+
+extern struct device_node *of_find_node_by_name(struct device_node *from,
+	const char *name);
+#define for_each_node_by_name(dn, name) \
+	for (dn = of_find_node_by_name(NULL, name); dn; \
+	     dn = of_find_node_by_name(dn, name))
+extern struct device_node *of_find_node_by_type(struct device_node *from,
+	const char *type);
+#define for_each_node_by_type(dn, type) \
+	for (dn = of_find_node_by_type(NULL, type); dn; \
+	     dn = of_find_node_by_type(dn, type))
+extern struct device_node *of_find_compatible_node(struct device_node *from,
+	const char *type, const char *compat);
+extern struct device_node *of_find_node_by_path(const char *path);
+extern struct device_node *of_find_node_by_phandle(phandle handle);
+extern struct device_node *of_get_parent(const struct device_node *node);
+extern struct device_node *of_get_next_child(const struct device_node *node,
+					     struct device_node *prev);
+extern struct property *of_find_property(struct device_node *np,
+					 const char *name,
+					 int *lenp);
+extern int of_device_is_compatible(struct device_node *device, const char *);
+extern void *of_get_property(struct device_node *node, const char *name,
+			     int *lenp);
+extern int of_set_property(struct device_node *node, const char *name, void *val, int len);
+extern int of_getintprop_default(struct device_node *np,
+				 const char *name,
+				 int def);
+extern int of_n_addr_cells(struct device_node *np);
+extern int of_n_size_cells(struct device_node *np);
+
+extern void prom_build_devicetree(void);
+
+#endif /* __KERNEL__ */
+#endif /* _SPARC64_PROM_H */
diff --git a/include/asm-sparc64/tracehook.h b/include/asm-sparc64/tracehook.h
new file mode 100644
index 000000000..fbcdae196
--- /dev/null
+++ b/include/asm-sparc64/tracehook.h
@@ -0,0 +1,44 @@
+/*
+ * Tracing hooks, SPARC64 CPU support
+ */
+
+#ifndef _ASM_TRACEHOOK_H
+#define _ASM_TRACEHOOK_H	1
+
+
+#include <linux/sched.h>
+#include <asm/ptrace.h>
+
+/*
+ * See linux/tracehook.h for the descriptions of what these need to do.
+ */
+
+
+static inline void tracehook_enable_syscall_trace(struct task_struct *tsk)
+{
+	set_tsk_thread_flag(tsk, TIF_SYSCALL_TRACE);
+}
+
+static inline void tracehook_disable_syscall_trace(struct task_struct *tsk)
+{
+	clear_tsk_thread_flag(tsk, TIF_SYSCALL_TRACE);
+}
+
+static inline void tracehook_abort_syscall(struct pt_regs *regs)
+{
+	regs->u_regs[UREG_G1] = -1L;
+}
+
+extern const struct utrace_regset_view utrace_sparc64_native_view;
+static inline const struct utrace_regset_view *
+utrace_native_view(struct task_struct *tsk)
+{
+#ifdef CONFIG_COMPAT
+	extern const struct utrace_regset_view utrace_sparc32_view;
+	if (test_tsk_thread_flag(tsk, TIF_32BIT))
+		return &utrace_sparc32_view;
+#endif
+	return &utrace_sparc64_native_view;
+}
+
+#endif
diff --git a/include/asm-v850/Kbuild b/include/asm-v850/Kbuild
new file mode 100644
index 000000000..c68e1680d
--- /dev/null
+++ b/include/asm-v850/Kbuild
@@ -0,0 +1 @@
+include include/asm-generic/Kbuild.asm
diff --git a/include/asm-x86_64/Kbuild b/include/asm-x86_64/Kbuild
new file mode 100644
index 000000000..40f2f13fe
--- /dev/null
+++ b/include/asm-x86_64/Kbuild
@@ -0,0 +1,21 @@
+include include/asm-generic/Kbuild.asm
+
+ALTARCH := i386
+ARCHDEF := defined __x86_64__
+ALTARCHDEF := defined __i386__
+
+header-y += boot.h
+header-y += bootsetup.h
+header-y += cpufeature.h
+header-y += debugreg.h
+header-y += ldt.h
+header-y += msr.h
+header-y += prctl.h
+header-y += setup.h
+header-y += sigcontext32.h
+header-y += ucontext.h
+header-y += vsyscall32.h
+
+unifdef-y += mce.h
+unifdef-y += mtrr.h
+unifdef-y += vsyscall.h
diff --git a/include/asm-x86_64/alternative-asm.i b/include/asm-x86_64/alternative-asm.i
new file mode 100644
index 000000000..0b3f1a2bb
--- /dev/null
+++ b/include/asm-x86_64/alternative-asm.i
@@ -0,0 +1,12 @@
+#ifdef CONFIG_SMP
+	.macro LOCK_PREFIX
+1:	lock
+	.section .smp_locks,"a"
+	.align 8
+	.quad 1b
+	.previous
+	.endm
+#else
+	.macro LOCK_PREFIX
+	.endm
+#endif
diff --git a/include/asm-x86_64/alternative.h b/include/asm-x86_64/alternative.h
new file mode 100644
index 000000000..a584826cc
--- /dev/null
+++ b/include/asm-x86_64/alternative.h
@@ -0,0 +1,136 @@
+#ifndef _X86_64_ALTERNATIVE_H
+#define _X86_64_ALTERNATIVE_H
+
+#ifdef __KERNEL__
+
+#include <linux/types.h>
+#include <asm/cpufeature.h>
+
+struct alt_instr {
+	u8 *instr; 		/* original instruction */
+	u8 *replacement;
+	u8  cpuid;		/* cpuid bit set for replacement */
+	u8  instrlen;		/* length of original instruction */
+	u8  replacementlen; 	/* length of new instruction, <= instrlen */
+	u8  pad[5];
+};
+
+extern void apply_alternatives(struct alt_instr *start, struct alt_instr *end);
+
+struct module;
+
+#ifdef CONFIG_SMP
+extern void alternatives_smp_module_add(struct module *mod, char *name,
+					void *locks, void *locks_end,
+					void *text, void *text_end);
+extern void alternatives_smp_module_del(struct module *mod);
+extern void alternatives_smp_switch(int smp);
+#else
+static inline void alternatives_smp_module_add(struct module *mod, char *name,
+					void *locks, void *locks_end,
+					void *text, void *text_end) {}
+static inline void alternatives_smp_module_del(struct module *mod) {}
+static inline void alternatives_smp_switch(int smp) {}
+#endif
+
+#endif
+
+/*
+ * Alternative instructions for different CPU types or capabilities.
+ *
+ * This allows to use optimized instructions even on generic binary
+ * kernels.
+ *
+ * length of oldinstr must be longer or equal the length of newinstr
+ * It can be padded with nops as needed.
+ *
+ * For non barrier like inlines please define new variants
+ * without volatile and memory clobber.
+ */
+#define alternative(oldinstr, newinstr, feature) 	\
+	asm volatile ("661:\n\t" oldinstr "\n662:\n" 		     \
+		      ".section .altinstructions,\"a\"\n"     	     \
+		      "  .align 8\n"				       \
+		      "  .quad 661b\n"            /* label */          \
+		      "  .quad 663f\n"		  /* new instruction */ \
+		      "  .byte %c0\n"             /* feature bit */    \
+		      "  .byte 662b-661b\n"       /* sourcelen */      \
+		      "  .byte 664f-663f\n"       /* replacementlen */ \
+		      ".previous\n"					\
+		      ".section .altinstr_replacement,\"ax\"\n"		\
+		      "663:\n\t" newinstr "\n664:\n"   /* replacement */ \
+		      ".previous" :: "i" (feature) : "memory")
+
+/*
+ * Alternative inline assembly with input.
+ *
+ * Pecularities:
+ * No memory clobber here.
+ * Argument numbers start with 1.
+ * Best is to use constraints that are fixed size (like (%1) ... "r")
+ * If you use variable sized constraints like "m" or "g" in the
+ * replacement make sure to pad to the worst case length.
+ */
+#define alternative_input(oldinstr, newinstr, feature, input...)	\
+	asm volatile ("661:\n\t" oldinstr "\n662:\n"			\
+		      ".section .altinstructions,\"a\"\n"		\
+		      "  .align 8\n"					\
+		      "  .quad 661b\n"            /* label */		\
+		      "  .quad 663f\n"		  /* new instruction */	\
+		      "  .byte %c0\n"             /* feature bit */	\
+		      "  .byte 662b-661b\n"       /* sourcelen */	\
+		      "  .byte 664f-663f\n"       /* replacementlen */	\
+		      ".previous\n"					\
+		      ".section .altinstr_replacement,\"ax\"\n"		\
+		      "663:\n\t" newinstr "\n664:\n"   /* replacement */ \
+		      ".previous" :: "i" (feature), ##input)
+
+/* Like alternative_input, but with a single output argument */
+#define alternative_io(oldinstr, newinstr, feature, output, input...) \
+	asm volatile ("661:\n\t" oldinstr "\n662:\n"			\
+		      ".section .altinstructions,\"a\"\n"		\
+		      "  .align 8\n"					\
+		      "  .quad 661b\n"            /* label */		\
+		      "  .quad 663f\n"		  /* new instruction */	\
+		      "  .byte %c[feat]\n"        /* feature bit */	\
+		      "  .byte 662b-661b\n"       /* sourcelen */	\
+		      "  .byte 664f-663f\n"       /* replacementlen */	\
+		      ".previous\n"					\
+		      ".section .altinstr_replacement,\"ax\"\n"		\
+		      "663:\n\t" newinstr "\n664:\n"   /* replacement */ \
+		      ".previous" : output : [feat] "i" (feature), ##input)
+
+/*
+ * Alternative inline assembly for SMP.
+ *
+ * The LOCK_PREFIX macro defined here replaces the LOCK and
+ * LOCK_PREFIX macros used everywhere in the source tree.
+ *
+ * SMP alternatives use the same data structures as the other
+ * alternatives and the X86_FEATURE_UP flag to indicate the case of a
+ * UP system running a SMP kernel.  The existing apply_alternatives()
+ * works fine for patching a SMP kernel for UP.
+ *
+ * The SMP alternative tables can be kept after boot and contain both
+ * UP and SMP versions of the instructions to allow switching back to
+ * SMP at runtime, when hotplugging in a new CPU, which is especially
+ * useful in virtualized environments.
+ *
+ * The very common lock prefix is handled as special case in a
+ * separate table which is a pure address list without replacement ptr
+ * and size information.  That keeps the table sizes small.
+ */
+
+#ifdef CONFIG_SMP
+#define LOCK_PREFIX \
+		".section .smp_locks,\"a\"\n"	\
+		"  .align 8\n"			\
+		"  .quad 661f\n" /* address */	\
+		".previous\n"			\
+	       	"661:\n\tlock; "
+
+#else /* ! CONFIG_SMP */
+#define LOCK_PREFIX ""
+#endif
+
+#endif /* _X86_64_ALTERNATIVE_H */
diff --git a/include/asm-x86_64/calgary.h b/include/asm-x86_64/calgary.h
new file mode 100644
index 000000000..82d8de726
--- /dev/null
+++ b/include/asm-x86_64/calgary.h
@@ -0,0 +1,62 @@
+/*
+ * Derived from include/asm-powerpc/iommu.h
+ *
+ * Copyright (C) IBM Corporation, 2006
+ *
+ * Author: Jon Mason <jdmason@us.ibm.com>
+ * Author: Muli Ben-Yehuda <muli@il.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 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
+ */
+
+#ifndef _ASM_X86_64_CALGARY_H
+#define _ASM_X86_64_CALGARY_H
+
+#include <linux/spinlock.h>
+#include <linux/device.h>
+#include <linux/dma-mapping.h>
+#include <asm/types.h>
+
+struct iommu_table {
+	unsigned long  it_base;      /* mapped address of tce table */
+	unsigned long  it_hint;      /* Hint for next alloc */
+	unsigned long *it_map;       /* A simple allocation bitmap for now */
+	spinlock_t     it_lock;      /* Protects it_map */
+	unsigned int   it_size;      /* Size of iommu table in entries */
+	unsigned char  it_busno;     /* Bus number this table belongs to */
+	void __iomem  *bbar;
+	u64	       tar_val;
+	struct timer_list watchdog_timer;
+};
+
+#define TCE_TABLE_SIZE_UNSPECIFIED	~0
+#define TCE_TABLE_SIZE_64K		0
+#define TCE_TABLE_SIZE_128K		1
+#define TCE_TABLE_SIZE_256K		2
+#define TCE_TABLE_SIZE_512K		3
+#define TCE_TABLE_SIZE_1M		4
+#define TCE_TABLE_SIZE_2M		5
+#define TCE_TABLE_SIZE_4M		6
+#define TCE_TABLE_SIZE_8M		7
+
+#ifdef CONFIG_CALGARY_IOMMU
+extern int calgary_iommu_init(void);
+extern void detect_calgary(void);
+#else
+static inline int calgary_iommu_init(void) { return 1; }
+static inline void detect_calgary(void) { return; }
+#endif
+
+#endif /* _ASM_X86_64_CALGARY_H */
diff --git a/include/asm-x86_64/intel_arch_perfmon.h b/include/asm-x86_64/intel_arch_perfmon.h
new file mode 100644
index 000000000..59c396431
--- /dev/null
+++ b/include/asm-x86_64/intel_arch_perfmon.h
@@ -0,0 +1,19 @@
+#ifndef X86_64_INTEL_ARCH_PERFMON_H
+#define X86_64_INTEL_ARCH_PERFMON_H 1
+
+#define MSR_ARCH_PERFMON_PERFCTR0		0xc1
+#define MSR_ARCH_PERFMON_PERFCTR1		0xc2
+
+#define MSR_ARCH_PERFMON_EVENTSEL0		0x186
+#define MSR_ARCH_PERFMON_EVENTSEL1		0x187
+
+#define ARCH_PERFMON_EVENTSEL0_ENABLE      (1 << 22)
+#define ARCH_PERFMON_EVENTSEL_INT          (1 << 20)
+#define ARCH_PERFMON_EVENTSEL_OS           (1 << 17)
+#define ARCH_PERFMON_EVENTSEL_USR          (1 << 16)
+
+#define ARCH_PERFMON_UNHALTED_CORE_CYCLES_SEL	(0x3c)
+#define ARCH_PERFMON_UNHALTED_CORE_CYCLES_UMASK	(0x00 << 8)
+#define ARCH_PERFMON_UNHALTED_CORE_CYCLES_PRESENT (1 << 0)
+
+#endif	/* X86_64_INTEL_ARCH_PERFMON_H */
diff --git a/include/asm-x86_64/irqflags.h b/include/asm-x86_64/irqflags.h
new file mode 100644
index 000000000..cce6937e8
--- /dev/null
+++ b/include/asm-x86_64/irqflags.h
@@ -0,0 +1,141 @@
+/*
+ * include/asm-x86_64/irqflags.h
+ *
+ * IRQ flags handling
+ *
+ * This file gets included from lowlevel asm headers too, to provide
+ * wrapped versions of the local_irq_*() APIs, based on the
+ * raw_local_irq_*() functions from the lowlevel headers.
+ */
+#ifndef _ASM_IRQFLAGS_H
+#define _ASM_IRQFLAGS_H
+
+#ifndef __ASSEMBLY__
+/*
+ * Interrupt control:
+ */
+
+static inline unsigned long __raw_local_save_flags(void)
+{
+	unsigned long flags;
+
+	__asm__ __volatile__(
+		"# __raw_save_flags\n\t"
+		"pushfq ; popq %q0"
+		: "=g" (flags)
+		: /* no input */
+		: "memory"
+	);
+
+	return flags;
+}
+
+#define raw_local_save_flags(flags) \
+		do { (flags) = __raw_local_save_flags(); } while (0)
+
+static inline void raw_local_irq_restore(unsigned long flags)
+{
+	__asm__ __volatile__(
+		"pushq %0 ; popfq"
+		: /* no output */
+		:"g" (flags)
+		:"memory", "cc"
+	);
+}
+
+#ifdef CONFIG_X86_VSMP
+
+/*
+ * Interrupt control for the VSMP architecture:
+ */
+
+static inline void raw_local_irq_disable(void)
+{
+	unsigned long flags = __raw_local_save_flags();
+
+	raw_local_irq_restore((flags & ~(1 << 9)) | (1 << 18));
+}
+
+static inline void raw_local_irq_enable(void)
+{
+	unsigned long flags = __raw_local_save_flags();
+
+	raw_local_irq_restore((flags | (1 << 9)) & ~(1 << 18));
+}
+
+static inline int raw_irqs_disabled_flags(unsigned long flags)
+{
+	return !(flags & (1<<9)) || (flags & (1 << 18));
+}
+
+#else /* CONFIG_X86_VSMP */
+
+static inline void raw_local_irq_disable(void)
+{
+	__asm__ __volatile__("cli" : : : "memory");
+}
+
+static inline void raw_local_irq_enable(void)
+{
+	__asm__ __volatile__("sti" : : : "memory");
+}
+
+static inline int raw_irqs_disabled_flags(unsigned long flags)
+{
+	return !(flags & (1 << 9));
+}
+
+#endif
+
+/*
+ * For spinlocks, etc.:
+ */
+
+static inline unsigned long __raw_local_irq_save(void)
+{
+	unsigned long flags = __raw_local_save_flags();
+
+	raw_local_irq_disable();
+
+	return flags;
+}
+
+#define raw_local_irq_save(flags) \
+		do { (flags) = __raw_local_irq_save(); } while (0)
+
+static inline int raw_irqs_disabled(void)
+{
+	unsigned long flags = __raw_local_save_flags();
+
+	return raw_irqs_disabled_flags(flags);
+}
+
+/*
+ * Used in the idle loop; sti takes one instruction cycle
+ * to complete:
+ */
+static inline void raw_safe_halt(void)
+{
+	__asm__ __volatile__("sti; hlt" : : : "memory");
+}
+
+/*
+ * Used when interrupts are already enabled or to
+ * shutdown the processor:
+ */
+static inline void halt(void)
+{
+	__asm__ __volatile__("hlt": : :"memory");
+}
+
+#else /* __ASSEMBLY__: */
+# ifdef CONFIG_TRACE_IRQFLAGS
+#  define TRACE_IRQS_ON		call trace_hardirqs_on_thunk
+#  define TRACE_IRQS_OFF	call trace_hardirqs_off_thunk
+# else
+#  define TRACE_IRQS_ON
+#  define TRACE_IRQS_OFF
+# endif
+#endif
+
+#endif
diff --git a/include/asm-x86_64/k8.h b/include/asm-x86_64/k8.h
new file mode 100644
index 000000000..699dd6961
--- /dev/null
+++ b/include/asm-x86_64/k8.h
@@ -0,0 +1,14 @@
+#ifndef _ASM_K8_H
+#define _ASM_K8_H 1
+
+#include <linux/pci.h>
+
+extern struct pci_device_id k8_nb_ids[];
+
+extern int early_is_k8_nb(u32 value);
+extern struct pci_dev **k8_northbridges;
+extern int num_k8_northbridges;
+extern int cache_k8_northbridges(void);
+extern void k8_flush_garts(void);
+
+#endif
diff --git a/include/asm-x86_64/mach-xen/asm/irqflags.h b/include/asm-x86_64/mach-xen/asm/irqflags.h
new file mode 100644
index 000000000..7b03e7a73
--- /dev/null
+++ b/include/asm-x86_64/mach-xen/asm/irqflags.h
@@ -0,0 +1,65 @@
+/*
+ * include/asm-x86_64/irqflags.h
+ *
+ * IRQ flags handling
+ *
+ * This file gets included from lowlevel asm headers too, to provide
+ * wrapped versions of the local_irq_*() APIs, based on the
+ * raw_local_irq_*() functions from the lowlevel headers.
+ */
+#ifndef _ASM_IRQFLAGS_H
+#define _ASM_IRQFLAGS_H
+
+#ifndef __ASSEMBLY__
+/*
+ * Interrupt control:
+ */
+
+unsigned long __raw_local_save_flags(void);
+#define raw_local_save_flags(flags) \
+		do { (flags) = __raw_local_save_flags(); } while (0)
+
+void raw_local_irq_restore(unsigned long flags);
+void raw_local_irq_disable(void);
+void raw_local_irq_enable(void);
+
+static inline int raw_irqs_disabled_flags(unsigned long flags)
+{
+	return flags != 0;
+}
+
+/*
+ * For spinlocks, etc.:
+ */
+
+unsigned long __raw_local_irq_save(void);
+
+#define raw_local_irq_save(flags) \
+		do { (flags) = __raw_local_irq_save(); } while (0)
+
+int raw_irqs_disabled(void);
+
+/*
+ * Used in the idle loop; sti takes one instruction cycle
+ * to complete:
+ */
+void raw_safe_halt(void);
+
+
+/*
+ * Used when interrupts are already enabled or to
+ * shutdown the processor:
+ */
+void halt(void);
+
+#else /* __ASSEMBLY__: */
+# ifdef CONFIG_TRACE_IRQFLAGS
+#  define TRACE_IRQS_ON		call trace_hardirqs_on_thunk
+#  define TRACE_IRQS_OFF	call trace_hardirqs_off_thunk
+# else
+#  define TRACE_IRQS_ON
+#  define TRACE_IRQS_OFF
+# endif
+#endif
+
+#endif
diff --git a/include/asm-x86_64/mach-xen/asm/maddr.h b/include/asm-x86_64/mach-xen/asm/maddr.h
new file mode 100644
index 000000000..0104de808
--- /dev/null
+++ b/include/asm-x86_64/mach-xen/asm/maddr.h
@@ -0,0 +1,139 @@
+#ifndef _X86_64_MADDR_H
+#define _X86_64_MADDR_H
+
+#include <xen/features.h>
+#include <xen/interface/xen.h>
+
+/**** MACHINE <-> PHYSICAL CONVERSION MACROS ****/
+#define INVALID_P2M_ENTRY	(~0UL)
+#define FOREIGN_FRAME_BIT	(1UL<<63)
+#define FOREIGN_FRAME(m)	((m) | FOREIGN_FRAME_BIT)
+
+#ifdef CONFIG_XEN
+
+extern unsigned long *phys_to_machine_mapping;
+
+#undef machine_to_phys_mapping
+extern unsigned long *machine_to_phys_mapping;
+extern unsigned int   machine_to_phys_order;
+
+static inline unsigned long pfn_to_mfn(unsigned long pfn)
+{
+	if (xen_feature(XENFEAT_auto_translated_physmap))
+		return pfn;
+	return phys_to_machine_mapping[(unsigned int)(pfn)] &
+		~FOREIGN_FRAME_BIT;
+}
+
+static inline int phys_to_machine_mapping_valid(unsigned long pfn)
+{
+	if (xen_feature(XENFEAT_auto_translated_physmap))
+		return 1;
+	return (phys_to_machine_mapping[pfn] != INVALID_P2M_ENTRY);
+}
+
+static inline unsigned long mfn_to_pfn(unsigned long mfn)
+{
+	unsigned long pfn;
+
+	if (xen_feature(XENFEAT_auto_translated_physmap))
+		return mfn;
+
+	if (unlikely((mfn >> machine_to_phys_order) != 0))
+		return end_pfn;
+
+	/* The array access can fail (e.g., device space beyond end of RAM). */
+	asm (
+		"1:	movq %1,%0\n"
+		"2:\n"
+		".section .fixup,\"ax\"\n"
+		"3:	movq %2,%0\n"
+		"	jmp  2b\n"
+		".previous\n"
+		".section __ex_table,\"a\"\n"
+		"	.align 8\n"
+		"	.quad 1b,3b\n"
+		".previous"
+		: "=r" (pfn)
+		: "m" (machine_to_phys_mapping[mfn]), "m" (end_pfn) );
+
+	return pfn;
+}
+
+/*
+ * We detect special mappings in one of two ways:
+ *  1. If the MFN is an I/O page then Xen will set the m2p entry
+ *     to be outside our maximum possible pseudophys range.
+ *  2. If the MFN belongs to a different domain then we will certainly
+ *     not have MFN in our p2m table. Conversely, if the page is ours,
+ *     then we'll have p2m(m2p(MFN))==MFN.
+ * If we detect a special mapping then it doesn't have a 'struct page'.
+ * We force !pfn_valid() by returning an out-of-range pointer.
+ *
+ * NB. These checks require that, for any MFN that is not in our reservation,
+ * there is no PFN such that p2m(PFN) == MFN. Otherwise we can get confused if
+ * we are foreign-mapping the MFN, and the other domain as m2p(MFN) == PFN.
+ * Yikes! Various places must poke in INVALID_P2M_ENTRY for safety.
+ *
+ * NB2. When deliberately mapping foreign pages into the p2m table, you *must*
+ *      use FOREIGN_FRAME(). This will cause pte_pfn() to choke on it, as we
+ *      require. In all the cases we care about, the FOREIGN_FRAME bit is
+ *      masked (e.g., pfn_to_mfn()) so behaviour there is correct.
+ */
+static inline unsigned long mfn_to_local_pfn(unsigned long mfn)
+{
+	unsigned long pfn = mfn_to_pfn(mfn);
+	if ((pfn < end_pfn)
+	    && !xen_feature(XENFEAT_auto_translated_physmap)
+	    && (phys_to_machine_mapping[pfn] != mfn))
+		return end_pfn; /* force !pfn_valid() */
+	return pfn;
+}
+
+static inline void set_phys_to_machine(unsigned long pfn, unsigned long mfn)
+{
+	if (xen_feature(XENFEAT_auto_translated_physmap)) {
+		BUG_ON(pfn != mfn && mfn != INVALID_P2M_ENTRY);
+		return;
+	}
+	phys_to_machine_mapping[pfn] = mfn;
+}
+
+#else /* !CONFIG_XEN */
+
+#define pfn_to_mfn(pfn) (pfn)
+#define mfn_to_pfn(mfn) (mfn)
+#define mfn_to_local_pfn(mfn) (mfn)
+#define set_phys_to_machine(pfn, mfn) BUG_ON((pfn) != (mfn))
+#define phys_to_machine_mapping_valid(pfn) (1)
+
+#endif /* !CONFIG_XEN */
+
+/* Definitions for machine and pseudophysical addresses. */
+typedef unsigned long paddr_t;
+typedef unsigned long maddr_t;
+
+static inline maddr_t phys_to_machine(paddr_t phys)
+{
+	maddr_t machine = pfn_to_mfn(phys >> PAGE_SHIFT);
+	machine = (machine << PAGE_SHIFT) | (phys & ~PAGE_MASK);
+	return machine;
+}
+
+static inline paddr_t machine_to_phys(maddr_t machine)
+{
+	paddr_t phys = mfn_to_pfn(machine >> PAGE_SHIFT);
+	phys = (phys << PAGE_SHIFT) | (machine & ~PAGE_MASK);
+	return phys;
+}
+
+/* VIRT <-> MACHINE conversion */
+#define virt_to_machine(v)	(phys_to_machine(__pa(v)))
+#define virt_to_mfn(v)		(pfn_to_mfn(__pa(v) >> PAGE_SHIFT))
+#define mfn_to_virt(m)		(__va(mfn_to_pfn(m) << PAGE_SHIFT))
+
+#define __pte_ma(x)     ((pte_t) { (x) } )
+#define pfn_pte_ma(pfn, prot)	__pte_ma((((pfn) << PAGE_SHIFT) | pgprot_val(prot)) & __supported_pte_mask)
+
+#endif /* _X86_64_MADDR_H */
+
diff --git a/include/asm-x86_64/mach-xen/asm/stacktrace.h b/include/asm-x86_64/mach-xen/asm/stacktrace.h
new file mode 100644
index 000000000..5eb9799be
--- /dev/null
+++ b/include/asm-x86_64/mach-xen/asm/stacktrace.h
@@ -0,0 +1,18 @@
+#ifndef _ASM_STACKTRACE_H
+#define _ASM_STACKTRACE_H 1
+
+/* Generic stack tracer with callbacks */
+
+struct stacktrace_ops {
+	void (*warning)(void *data, char *msg);
+	/* msg must contain %s for the symbol */
+	void (*warning_symbol)(void *data, char *msg, unsigned long symbol);
+	void (*address)(void *data, unsigned long address);
+	/* On negative return stop dumping */
+	int (*stack)(void *data, char *name);
+};
+
+void dump_trace(struct task_struct *tsk, struct pt_regs *regs, unsigned long *stack,
+		struct stacktrace_ops *ops, void *data);
+
+#endif
diff --git a/include/asm-x86_64/stacktrace.h b/include/asm-x86_64/stacktrace.h
new file mode 100644
index 000000000..5eb9799be
--- /dev/null
+++ b/include/asm-x86_64/stacktrace.h
@@ -0,0 +1,18 @@
+#ifndef _ASM_STACKTRACE_H
+#define _ASM_STACKTRACE_H 1
+
+/* Generic stack tracer with callbacks */
+
+struct stacktrace_ops {
+	void (*warning)(void *data, char *msg);
+	/* msg must contain %s for the symbol */
+	void (*warning_symbol)(void *data, char *msg, unsigned long symbol);
+	void (*address)(void *data, unsigned long address);
+	/* On negative return stop dumping */
+	int (*stack)(void *data, char *name);
+};
+
+void dump_trace(struct task_struct *tsk, struct pt_regs *regs, unsigned long *stack,
+		struct stacktrace_ops *ops, void *data);
+
+#endif
diff --git a/include/asm-x86_64/tce.h b/include/asm-x86_64/tce.h
new file mode 100644
index 000000000..53e9a68b3
--- /dev/null
+++ b/include/asm-x86_64/tce.h
@@ -0,0 +1,49 @@
+/*
+ * This file is derived from asm-powerpc/tce.h.
+ *
+ * Copyright (C) IBM Corporation, 2006
+ *
+ * Author: Muli Ben-Yehuda <muli@il.ibm.com>
+ * Author: Jon Mason <jdmason@us.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 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
+ */
+
+#ifndef _ASM_X86_64_TCE_H
+#define _ASM_X86_64_TCE_H
+
+extern void* tce_table_kva[];
+extern unsigned int specified_table_size;
+struct iommu_table;
+
+#define TCE_ENTRY_SIZE   8   /* in bytes */
+
+#define TCE_READ_SHIFT   0
+#define TCE_WRITE_SHIFT  1
+#define TCE_HUBID_SHIFT  2   /* unused */
+#define TCE_RSVD_SHIFT   8   /* unused */
+#define TCE_RPN_SHIFT    12
+#define TCE_UNUSED_SHIFT 48  /* unused */
+
+#define TCE_RPN_MASK     0x0000fffffffff000ULL
+
+extern void tce_build(struct iommu_table *tbl, unsigned long index,
+        unsigned int npages, unsigned long uaddr, int direction);
+extern void tce_free(struct iommu_table *tbl, long index, unsigned int npages);
+extern void* alloc_tce_table(void);
+extern void free_tce_table(void *tbl);
+extern int build_tce_table(struct pci_dev *dev, void __iomem *bbar);
+
+#endif /* _ASM_X86_64_TCE_H */
diff --git a/include/asm-x86_64/tracehook.h b/include/asm-x86_64/tracehook.h
new file mode 100644
index 000000000..d7588bf94
--- /dev/null
+++ b/include/asm-x86_64/tracehook.h
@@ -0,0 +1,54 @@
+/*
+ * Tracing hooks, x86-64 CPU support
+ */
+
+#ifndef _ASM_TRACEHOOK_H
+#define _ASM_TRACEHOOK_H	1
+
+#include <linux/sched.h>
+#include <asm/ptrace.h>
+#include <asm/proto.h>
+
+/*
+ * See linux/tracehook.h for the descriptions of what these need to do.
+ */
+
+#define ARCH_HAS_SINGLE_STEP	(1)
+
+/* These two are defined in arch/x86_64/kernel/ptrace.c.  */
+void tracehook_enable_single_step(struct task_struct *tsk);
+void tracehook_disable_single_step(struct task_struct *tsk);
+
+static inline int tracehook_single_step_enabled(struct task_struct *tsk)
+{
+	return test_tsk_thread_flag(tsk, TIF_SINGLESTEP);
+}
+
+static inline void tracehook_enable_syscall_trace(struct task_struct *tsk)
+{
+	set_tsk_thread_flag(tsk, TIF_SYSCALL_TRACE);
+}
+
+static inline void tracehook_disable_syscall_trace(struct task_struct *tsk)
+{
+	clear_tsk_thread_flag(tsk, TIF_SYSCALL_TRACE);
+}
+
+static inline void tracehook_abort_syscall(struct pt_regs *regs)
+{
+	regs->orig_rax = -1L;
+}
+
+extern const struct utrace_regset_view utrace_x86_64_native, utrace_ia32_view;
+static inline const struct utrace_regset_view *
+utrace_native_view(struct task_struct *tsk)
+{
+#ifdef CONFIG_IA32_EMULATION
+	if (test_tsk_thread_flag(tsk, TIF_IA32))
+		return &utrace_ia32_view;
+#endif
+	return &utrace_x86_64_native;
+}
+
+
+#endif
diff --git a/include/asm-x86_64/unwind.h b/include/asm-x86_64/unwind.h
new file mode 100644
index 000000000..3b450601a
--- /dev/null
+++ b/include/asm-x86_64/unwind.h
@@ -0,0 +1,107 @@
+#ifndef _ASM_X86_64_UNWIND_H
+#define _ASM_X86_64_UNWIND_H
+
+/*
+ * Copyright (C) 2002-2006 Novell, Inc.
+ *	Jan Beulich <jbeulich@novell.com>
+ * This code is released under version 2 of the GNU GPL.
+ */
+
+#ifdef CONFIG_STACK_UNWIND
+
+#include <linux/sched.h>
+#include <asm/ptrace.h>
+#include <asm/uaccess.h>
+#include <asm/vsyscall.h>
+
+struct unwind_frame_info
+{
+	struct pt_regs regs;
+	struct task_struct *task;
+};
+
+#define UNW_PC(frame)        (frame)->regs.rip
+#define UNW_SP(frame)        (frame)->regs.rsp
+#ifdef CONFIG_FRAME_POINTER
+#define UNW_FP(frame)        (frame)->regs.rbp
+#define FRAME_RETADDR_OFFSET 8
+#define FRAME_LINK_OFFSET    0
+#define STACK_BOTTOM(tsk)    (((tsk)->thread.rsp0 - 1) & ~(THREAD_SIZE - 1))
+#define STACK_TOP(tsk)       ((tsk)->thread.rsp0)
+#endif
+/* Might need to account for the special exception and interrupt handling
+   stacks here, since normally
+	EXCEPTION_STACK_ORDER < THREAD_ORDER < IRQSTACK_ORDER,
+   but the construct is needed only for getting across the stack switch to
+   the interrupt stack - thus considering the IRQ stack itself is unnecessary,
+   and the overhead of comparing against all exception handling stacks seems
+   not desirable. */
+#define STACK_LIMIT(ptr)     (((ptr) - 1) & ~(THREAD_SIZE - 1))
+
+#define UNW_REGISTER_INFO \
+	PTREGS_INFO(rax), \
+	PTREGS_INFO(rdx), \
+	PTREGS_INFO(rcx), \
+	PTREGS_INFO(rbx), \
+	PTREGS_INFO(rsi), \
+	PTREGS_INFO(rdi), \
+	PTREGS_INFO(rbp), \
+	PTREGS_INFO(rsp), \
+	PTREGS_INFO(r8), \
+	PTREGS_INFO(r9), \
+	PTREGS_INFO(r10), \
+	PTREGS_INFO(r11), \
+	PTREGS_INFO(r12), \
+	PTREGS_INFO(r13), \
+	PTREGS_INFO(r14), \
+	PTREGS_INFO(r15), \
+	PTREGS_INFO(rip)
+
+static inline void arch_unw_init_frame_info(struct unwind_frame_info *info,
+                                            /*const*/ struct pt_regs *regs)
+{
+	info->regs = *regs;
+}
+
+static inline void arch_unw_init_blocked(struct unwind_frame_info *info)
+{
+	extern const char thread_return[];
+
+	memset(&info->regs, 0, sizeof(info->regs));
+	info->regs.rip = (unsigned long)thread_return;
+	info->regs.cs = __KERNEL_CS;
+	__get_user(info->regs.rbp, (unsigned long *)info->task->thread.rsp);
+	info->regs.rsp = info->task->thread.rsp;
+	info->regs.ss = __KERNEL_DS;
+}
+
+extern int arch_unwind_init_running(struct unwind_frame_info *,
+                                    int (*callback)(struct unwind_frame_info *,
+                                                    void *arg),
+                                    void *arg);
+
+static inline int arch_unw_user_mode(const struct unwind_frame_info *info)
+{
+#if 0 /* This can only work when selector register saves/restores
+         are properly annotated (and tracked in UNW_REGISTER_INFO). */
+	return user_mode(&info->regs);
+#else
+	return (long)info->regs.rip >= 0
+	       || (info->regs.rip >= VSYSCALL_START && info->regs.rip < VSYSCALL_END)
+	       || (long)info->regs.rsp >= 0;
+#endif
+}
+
+#else
+
+#define UNW_PC(frame) ((void)(frame), 0UL)
+#define UNW_SP(frame) ((void)(frame), 0UL)
+
+static inline int arch_unw_user_mode(const void *info)
+{
+	return 0;
+}
+
+#endif
+
+#endif /* _ASM_X86_64_UNWIND_H */
diff --git a/include/asm-xtensa/Kbuild b/include/asm-xtensa/Kbuild
new file mode 100644
index 000000000..c68e1680d
--- /dev/null
+++ b/include/asm-xtensa/Kbuild
@@ -0,0 +1 @@
+include include/asm-generic/Kbuild.asm
diff --git a/include/linux/Kbuild b/include/linux/Kbuild
new file mode 100644
index 000000000..10d2ca075
--- /dev/null
+++ b/include/linux/Kbuild
@@ -0,0 +1,343 @@
+header-y += byteorder/
+header-y += dvb/
+header-y += hdlc/
+header-y += isdn/
+header-y += nfsd/
+header-y += raid/
+header-y += sunrpc/
+header-y += tc_act/
+header-y += netfilter/
+header-y += netfilter_arp/
+header-y += netfilter_bridge/
+header-y += netfilter_ipv4/
+header-y += netfilter_ipv6/
+
+header-y += affs_fs.h
+header-y += affs_hardblocks.h
+header-y += aio_abi.h
+header-y += a.out.h
+header-y += arcfb.h
+header-y += atmapi.h
+header-y += atmbr2684.h
+header-y += atmclip.h
+header-y += atm_eni.h
+header-y += atm_he.h
+header-y += atm_idt77105.h
+header-y += atmioc.h
+header-y += atmlec.h
+header-y += atmmpc.h
+header-y += atm_nicstar.h
+header-y += atmppp.h
+header-y += atmsap.h
+header-y += atmsvc.h
+header-y += atm_zatm.h
+header-y += auto_fs4.h
+header-y += auxvec.h
+header-y += awe_voice.h
+header-y += ax25.h
+header-y += b1lli.h
+header-y += baycom.h
+header-y += bfs_fs.h
+header-y += blkpg.h
+header-y += bpqether.h
+header-y += cdk.h
+header-y += chio.h
+header-y += coda_psdev.h
+header-y += coff.h
+header-y += comstats.h
+header-y += consolemap.h
+header-y += cycx_cfm.h
+header-y += dm-ioctl.h
+header-y += dn.h
+header-y += dqblk_v1.h
+header-y += dqblk_v2.h
+header-y += dqblk_xfs.h
+header-y += efs_fs_sb.h
+header-y += elf-fdpic.h
+header-y += elf.h
+header-y += elf-em.h
+header-y += fadvise.h
+header-y += fd.h
+header-y += fdreg.h
+header-y += ftape-header-segment.h
+header-y += ftape-vendors.h
+header-y += fuse.h
+header-y += futex.h
+header-y += genetlink.h
+header-y += gen_stats.h
+header-y += gigaset_dev.h
+header-y += hdsmart.h
+header-y += hpfs_fs.h
+header-y += hysdn_if.h
+header-y += i2c-dev.h
+header-y += i8k.h
+header-y += icmp.h
+header-y += if_arcnet.h
+header-y += if_arp.h
+header-y += if_bonding.h
+header-y += if_cablemodem.h
+header-y += if_fc.h
+header-y += if_fddi.h
+header-y += if.h
+header-y += if_hippi.h
+header-y += if_infiniband.h
+header-y += if_packet.h
+header-y += if_plip.h
+header-y += if_ppp.h
+header-y += if_slip.h
+header-y += if_strip.h
+header-y += if_tunnel.h
+header-y += in6.h
+header-y += in_route.h
+header-y += ioctl.h
+header-y += ip.h
+header-y += ipmi_msgdefs.h
+header-y += ip_mp_alg.h
+header-y += ipsec.h
+header-y += ipx.h
+header-y += irda.h
+header-y += isdn_divertif.h
+header-y += iso_fs.h
+header-y += ite_gpio.h
+header-y += ixjuser.h
+header-y += jffs2.h
+header-y += keyctl.h
+header-y += limits.h
+header-y += major.h
+header-y += matroxfb.h
+header-y += meye.h
+header-y += minix_fs.h
+header-y += mmtimer.h
+header-y += mqueue.h
+header-y += mtio.h
+header-y += ncp_no.h
+header-y += netfilter_arp.h
+header-y += netrom.h
+header-y += nfs2.h
+header-y += nfs4_mount.h
+header-y += nfs_mount.h
+header-y += openprom_fs.h
+header-y += param.h
+header-y += pci_ids.h
+header-y += pci_regs.h
+header-y += personality.h
+header-y += pfkeyv2.h
+header-y += pg.h
+header-y += pkt_cls.h
+header-y += pkt_sched.h
+header-y += posix_types.h
+header-y += ppdev.h
+header-y += prctl.h
+header-y += ps2esdi.h
+header-y += qic117.h
+header-y += qnxtypes.h
+header-y += quotaio_v1.h
+header-y += quotaio_v2.h
+header-y += radeonfb.h
+header-y += raw.h
+header-y += resource.h
+header-y += rose.h
+header-y += sctp.h
+header-y += smbno.h
+header-y += snmp.h
+header-y += sockios.h
+header-y += som.h
+header-y += sound.h
+header-y += synclink.h
+header-y += telephony.h
+header-y += termios.h
+header-y += ticable.h
+header-y += times.h
+header-y += tiocl.h
+header-y += tipc.h
+header-y += toshiba.h
+header-y += ultrasound.h
+header-y += un.h
+header-y += utime.h
+header-y += utsname.h
+header-y += video_decoder.h
+header-y += video_encoder.h
+header-y += videotext.h
+header-y += vt.h
+header-y += wavefront.h
+header-y += wireless.h
+header-y += xattr.h
+header-y += x25.h
+header-y += zorro_ids.h
+
+unifdef-y += acct.h
+unifdef-y += adb.h
+unifdef-y += adfs_fs.h
+unifdef-y += agpgart.h
+unifdef-y += apm_bios.h
+unifdef-y += atalk.h
+unifdef-y += atmarp.h
+unifdef-y += atmdev.h
+unifdef-y += atm.h
+unifdef-y += atm_tcp.h
+unifdef-y += audit.h
+unifdef-y += auto_fs.h
+unifdef-y += binfmts.h
+unifdef-y += capability.h
+unifdef-y += capi.h
+unifdef-y += cciss_ioctl.h
+unifdef-y += cdrom.h
+unifdef-y += cm4000_cs.h
+unifdef-y += cn_proc.h
+unifdef-y += coda.h
+unifdef-y += connector.h
+unifdef-y += cramfs_fs.h
+unifdef-y += cuda.h
+unifdef-y += cyclades.h
+unifdef-y += dccp.h
+unifdef-y += dirent.h
+unifdef-y += divert.h
+unifdef-y += elfcore.h
+unifdef-y += errno.h
+unifdef-y += errqueue.h
+unifdef-y += ethtool.h
+unifdef-y += eventpoll.h
+unifdef-y += ext2_fs.h
+unifdef-y += ext3_fs.h
+unifdef-y += fb.h
+unifdef-y += fcntl.h
+unifdef-y += filter.h
+unifdef-y += flat.h
+unifdef-y += fs.h
+unifdef-y += ftape.h
+unifdef-y += gameport.h
+unifdef-y += generic_serial.h
+unifdef-y += genhd.h
+unifdef-y += hayesesp.h
+unifdef-y += hdlcdrv.h
+unifdef-y += hdlc.h
+unifdef-y += hdreg.h
+unifdef-y += hiddev.h
+unifdef-y += hpet.h
+unifdef-y += i2c.h
+unifdef-y += i2o-dev.h
+unifdef-y += icmpv6.h
+unifdef-y += if_bridge.h
+unifdef-y += if_ec.h
+unifdef-y += if_eql.h
+unifdef-y += if_ether.h
+unifdef-y += if_frad.h
+unifdef-y += if_ltalk.h
+unifdef-y += if_pppox.h
+unifdef-y += if_shaper.h
+unifdef-y += if_tr.h
+unifdef-y += if_tun.h
+unifdef-y += if_vlan.h
+unifdef-y += if_wanpipe.h
+unifdef-y += igmp.h
+unifdef-y += inet_diag.h
+unifdef-y += in.h
+unifdef-y += inotify.h
+unifdef-y += input.h
+unifdef-y += ipc.h
+unifdef-y += ipmi.h
+unifdef-y += ipv6.h
+unifdef-y += ipv6_route.h
+unifdef-y += isdn.h
+unifdef-y += isdnif.h
+unifdef-y += isdn_ppp.h
+unifdef-y += isicom.h
+unifdef-y += jbd.h
+unifdef-y += joystick.h
+unifdef-y += kdev_t.h
+unifdef-y += kd.h
+unifdef-y += kernelcapi.h
+unifdef-y += kernel.h
+unifdef-y += keyboard.h
+unifdef-y += llc.h
+unifdef-y += loop.h
+unifdef-y += lp.h
+unifdef-y += mempolicy.h
+unifdef-y += mii.h
+unifdef-y += mman.h
+unifdef-y += mroute.h
+unifdef-y += msdos_fs.h
+unifdef-y += msg.h
+unifdef-y += nbd.h
+unifdef-y += ncp_fs.h
+unifdef-y += ncp.h
+unifdef-y += ncp_mount.h
+unifdef-y += netdevice.h
+unifdef-y += netfilter_bridge.h
+unifdef-y += netfilter_decnet.h
+unifdef-y += netfilter.h
+unifdef-y += netfilter_ipv4.h
+unifdef-y += netfilter_ipv6.h
+unifdef-y += netfilter_logging.h
+unifdef-y += net.h
+unifdef-y += netlink.h
+unifdef-y += nfs3.h
+unifdef-y += nfs4.h
+unifdef-y += nfsacl.h
+unifdef-y += nfs_fs.h
+unifdef-y += nfs.h
+unifdef-y += nfs_idmap.h
+unifdef-y += n_r3964.h
+unifdef-y += nubus.h
+unifdef-y += nvram.h
+unifdef-y += parport.h
+unifdef-y += patchkey.h
+unifdef-y += pci.h
+unifdef-y += pktcdvd.h
+unifdef-y += pmu.h
+unifdef-y += poll.h
+unifdef-y += ppp_defs.h
+unifdef-y += ppp-comp.h
+unifdef-y += ptrace.h
+unifdef-y += qnx4_fs.h
+unifdef-y += quota.h
+unifdef-y += random.h
+unifdef-y += reboot.h
+unifdef-y += reiserfs_fs.h
+unifdef-y += reiserfs_xattr.h
+unifdef-y += romfs_fs.h
+unifdef-y += route.h
+unifdef-y += rtc.h
+unifdef-y += rtnetlink.h
+unifdef-y += scc.h
+unifdef-y += sched.h
+unifdef-y += sdla.h
+unifdef-y += selinux_netlink.h
+unifdef-y += sem.h
+unifdef-y += serial_core.h
+unifdef-y += serial.h
+unifdef-y += serio.h
+unifdef-y += shm.h
+unifdef-y += signal.h
+unifdef-y += smb_fs.h
+unifdef-y += smb.h
+unifdef-y += smb_mount.h
+unifdef-y += socket.h
+unifdef-y += sonet.h
+unifdef-y += sonypi.h
+unifdef-y += soundcard.h
+unifdef-y += stat.h
+unifdef-y += stddef.h
+unifdef-y += sysctl.h
+unifdef-y += tcp.h
+unifdef-y += time.h
+unifdef-y += timex.h
+unifdef-y += tty.h
+unifdef-y += types.h
+unifdef-y += udf_fs_i.h
+unifdef-y += udp.h
+unifdef-y += uinput.h
+unifdef-y += uio.h
+unifdef-y += unistd.h
+unifdef-y += usb_ch9.h
+unifdef-y += usbdevice_fs.h
+unifdef-y += user.h
+unifdef-y += videodev2.h
+unifdef-y += videodev.h
+unifdef-y += wait.h
+unifdef-y += wanrouter.h
+unifdef-y += watchdog.h
+unifdef-y += xfrm.h
+unifdef-y += zftape.h
+
+objhdr-y += version.h
diff --git a/include/linux/byteorder/Kbuild b/include/linux/byteorder/Kbuild
new file mode 100644
index 000000000..56499ab9e
--- /dev/null
+++ b/include/linux/byteorder/Kbuild
@@ -0,0 +1,7 @@
+header-y += big_endian.h
+header-y += little_endian.h
+header-y += pdp_endian.h
+
+unifdef-y += generic.h
+unifdef-y += swabb.h
+unifdef-y += swab.h
diff --git a/include/linux/clocksource.h b/include/linux/clocksource.h
new file mode 100644
index 000000000..d852024ed
--- /dev/null
+++ b/include/linux/clocksource.h
@@ -0,0 +1,185 @@
+/*  linux/include/linux/clocksource.h
+ *
+ *  This file contains the structure definitions for clocksources.
+ *
+ *  If you are not a clocksource, or timekeeping code, you should
+ *  not be including this file!
+ */
+#ifndef _LINUX_CLOCKSOURCE_H
+#define _LINUX_CLOCKSOURCE_H
+
+#include <linux/types.h>
+#include <linux/timex.h>
+#include <linux/time.h>
+#include <linux/list.h>
+#include <asm/div64.h>
+#include <asm/io.h>
+
+/* clocksource cycle base type */
+typedef u64 cycle_t;
+
+/**
+ * struct clocksource - hardware abstraction for a free running counter
+ *	Provides mostly state-free accessors to the underlying hardware.
+ *
+ * @name:		ptr to clocksource name
+ * @list:		list head for registration
+ * @rating:		rating value for selection (higher is better)
+ *			To avoid rating inflation the following
+ *			list should give you a guide as to how
+ *			to assign your clocksource a rating
+ *			1-99: Unfit for real use
+ *				Only available for bootup and testing purposes.
+ *			100-199: Base level usability.
+ *				Functional for real use, but not desired.
+ *			200-299: Good.
+ *				A correct and usable clocksource.
+ *			300-399: Desired.
+ *				A reasonably fast and accurate clocksource.
+ *			400-499: Perfect
+ *				The ideal clocksource. A must-use where
+ *				available.
+ * @read:		returns a cycle value
+ * @mask:		bitmask for two's complement
+ *			subtraction of non 64 bit counters
+ * @mult:		cycle to nanosecond multiplier
+ * @shift:		cycle to nanosecond divisor (power of two)
+ * @update_callback:	called when safe to alter clocksource values
+ * @is_continuous:	defines if clocksource is free-running.
+ * @cycle_interval:	Used internally by timekeeping core, please ignore.
+ * @xtime_interval:	Used internally by timekeeping core, please ignore.
+ */
+struct clocksource {
+	char *name;
+	struct list_head list;
+	int rating;
+	cycle_t (*read)(void);
+	cycle_t mask;
+	u32 mult;
+	u32 shift;
+	int (*update_callback)(void);
+	int is_continuous;
+
+	/* timekeeping specific data, ignore */
+	cycle_t cycle_last, cycle_interval;
+	u64 xtime_nsec, xtime_interval;
+	s64 error;
+};
+
+/* simplify initialization of mask field */
+#define CLOCKSOURCE_MASK(bits) (cycle_t)(bits<64 ? ((1ULL<<bits)-1) : -1)
+
+/**
+ * clocksource_khz2mult - calculates mult from khz and shift
+ * @khz:		Clocksource frequency in KHz
+ * @shift_constant:	Clocksource shift factor
+ *
+ * Helper functions that converts a khz counter frequency to a timsource
+ * multiplier, given the clocksource shift value
+ */
+static inline u32 clocksource_khz2mult(u32 khz, u32 shift_constant)
+{
+	/*  khz = cyc/(Million ns)
+	 *  mult/2^shift  = ns/cyc
+	 *  mult = ns/cyc * 2^shift
+	 *  mult = 1Million/khz * 2^shift
+	 *  mult = 1000000 * 2^shift / khz
+	 *  mult = (1000000<<shift) / khz
+	 */
+	u64 tmp = ((u64)1000000) << shift_constant;
+
+	tmp += khz/2; /* round for do_div */
+	do_div(tmp, khz);
+
+	return (u32)tmp;
+}
+
+/**
+ * clocksource_hz2mult - calculates mult from hz and shift
+ * @hz:			Clocksource frequency in Hz
+ * @shift_constant:	Clocksource shift factor
+ *
+ * Helper functions that converts a hz counter
+ * frequency to a timsource multiplier, given the
+ * clocksource shift value
+ */
+static inline u32 clocksource_hz2mult(u32 hz, u32 shift_constant)
+{
+	/*  hz = cyc/(Billion ns)
+	 *  mult/2^shift  = ns/cyc
+	 *  mult = ns/cyc * 2^shift
+	 *  mult = 1Billion/hz * 2^shift
+	 *  mult = 1000000000 * 2^shift / hz
+	 *  mult = (1000000000<<shift) / hz
+	 */
+	u64 tmp = ((u64)1000000000) << shift_constant;
+
+	tmp += hz/2; /* round for do_div */
+	do_div(tmp, hz);
+
+	return (u32)tmp;
+}
+
+/**
+ * clocksource_read: - Access the clocksource's current cycle value
+ * @cs:		pointer to clocksource being read
+ *
+ * Uses the clocksource to return the current cycle_t value
+ */
+static inline cycle_t clocksource_read(struct clocksource *cs)
+{
+	return cs->read();
+}
+
+/**
+ * cyc2ns - converts clocksource cycles to nanoseconds
+ * @cs:		Pointer to clocksource
+ * @cycles:	Cycles
+ *
+ * Uses the clocksource and ntp ajdustment to convert cycle_ts to nanoseconds.
+ *
+ * XXX - This could use some mult_lxl_ll() asm optimization
+ */
+static inline s64 cyc2ns(struct clocksource *cs, cycle_t cycles)
+{
+	u64 ret = (u64)cycles;
+	ret = (ret * cs->mult) >> cs->shift;
+	return ret;
+}
+
+/**
+ * clocksource_calculate_interval - Calculates a clocksource interval struct
+ *
+ * @c:		Pointer to clocksource.
+ * @length_nsec: Desired interval length in nanoseconds.
+ *
+ * Calculates a fixed cycle/nsec interval for a given clocksource/adjustment
+ * pair and interval request.
+ *
+ * Unless you're the timekeeping code, you should not be using this!
+ */
+static inline void clocksource_calculate_interval(struct clocksource *c,
+						unsigned long length_nsec)
+{
+	u64 tmp;
+
+	/* XXX - All of this could use a whole lot of optimization */
+	tmp = length_nsec;
+	tmp <<= c->shift;
+	tmp += c->mult/2;
+	do_div(tmp, c->mult);
+
+	c->cycle_interval = (cycle_t)tmp;
+	if (c->cycle_interval == 0)
+		c->cycle_interval = 1;
+
+	c->xtime_interval = (u64)c->cycle_interval * c->mult;
+}
+
+
+/* used to install a new clocksource */
+int clocksource_register(struct clocksource*);
+void clocksource_reselect(void);
+struct clocksource* clocksource_get_next(void);
+
+#endif /* _LINUX_CLOCKSOURCE_H */
diff --git a/include/linux/debug_locks.h b/include/linux/debug_locks.h
new file mode 100644
index 000000000..88dafa246
--- /dev/null
+++ b/include/linux/debug_locks.h
@@ -0,0 +1,71 @@
+#ifndef __LINUX_DEBUG_LOCKING_H
+#define __LINUX_DEBUG_LOCKING_H
+
+struct task_struct;
+
+extern int debug_locks;
+extern int debug_locks_silent;
+
+/*
+ * Generic 'turn off all lock debugging' function:
+ */
+extern int debug_locks_off(void);
+
+/*
+ * In the debug case we carry the caller's instruction pointer into
+ * other functions, but we dont want the function argument overhead
+ * in the nondebug case - hence these macros:
+ */
+#define _RET_IP_		(unsigned long)__builtin_return_address(0)
+#define _THIS_IP_  ({ __label__ __here; __here: (unsigned long)&&__here; })
+
+#define DEBUG_LOCKS_WARN_ON(c)						\
+({									\
+	int __ret = 0;							\
+									\
+	if (unlikely(c)) {						\
+		if (debug_locks_off())					\
+			WARN_ON(1);					\
+		__ret = 1;						\
+	}								\
+	__ret;								\
+})
+
+#ifdef CONFIG_SMP
+# define SMP_DEBUG_LOCKS_WARN_ON(c)			DEBUG_LOCKS_WARN_ON(c)
+#else
+# define SMP_DEBUG_LOCKS_WARN_ON(c)			do { } while (0)
+#endif
+
+#ifdef CONFIG_DEBUG_LOCKING_API_SELFTESTS
+  extern void locking_selftest(void);
+#else
+# define locking_selftest()	do { } while (0)
+#endif
+
+#ifdef CONFIG_LOCKDEP
+extern void debug_show_all_locks(void);
+extern void debug_show_held_locks(struct task_struct *task);
+extern void debug_check_no_locks_freed(const void *from, unsigned long len);
+extern void debug_check_no_locks_held(struct task_struct *task);
+#else
+static inline void debug_show_all_locks(void)
+{
+}
+
+static inline void debug_show_held_locks(struct task_struct *task)
+{
+}
+
+static inline void
+debug_check_no_locks_freed(const void *from, unsigned long len)
+{
+}
+
+static inline void
+debug_check_no_locks_held(struct task_struct *task)
+{
+}
+#endif
+
+#endif
diff --git a/include/linux/delayacct.h b/include/linux/delayacct.h
new file mode 100644
index 000000000..561e2a778
--- /dev/null
+++ b/include/linux/delayacct.h
@@ -0,0 +1,121 @@
+/* delayacct.h - per-task delay accounting
+ *
+ * Copyright (C) Shailabh Nagar, IBM Corp. 2006
+ *
+ * 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.
+ *
+ */
+
+#ifndef _LINUX_DELAYACCT_H
+#define _LINUX_DELAYACCT_H
+
+#include <linux/sched.h>
+#include <linux/taskstats_kern.h>
+
+/*
+ * Per-task flags relevant to delay accounting
+ * maintained privately to avoid exhausting similar flags in sched.h:PF_*
+ * Used to set current->delays->flags
+ */
+#define DELAYACCT_PF_SWAPIN	0x00000001	/* I am doing a swapin */
+
+#ifdef CONFIG_TASK_DELAY_ACCT
+
+extern int delayacct_on;	/* Delay accounting turned on/off */
+extern kmem_cache_t *delayacct_cache;
+extern void delayacct_init(void);
+extern void __delayacct_tsk_init(struct task_struct *);
+extern void __delayacct_tsk_exit(struct task_struct *);
+extern void __delayacct_blkio_start(void);
+extern void __delayacct_blkio_end(void);
+extern int __delayacct_add_tsk(struct taskstats *, struct task_struct *);
+extern __u64 __delayacct_blkio_ticks(struct task_struct *);
+
+static inline void delayacct_set_flag(int flag)
+{
+	if (current->delays)
+		current->delays->flags |= flag;
+}
+
+static inline void delayacct_clear_flag(int flag)
+{
+	if (current->delays)
+		current->delays->flags &= ~flag;
+}
+
+static inline void delayacct_tsk_init(struct task_struct *tsk)
+{
+	/* reinitialize in case parent's non-null pointer was dup'ed*/
+	tsk->delays = NULL;
+	if (delayacct_on)
+		__delayacct_tsk_init(tsk);
+}
+
+/* Free tsk->delays. Called from bad fork and __put_task_struct
+ * where there's no risk of tsk->delays being accessed elsewhere
+ */
+static inline void delayacct_tsk_free(struct task_struct *tsk)
+{
+	if (tsk->delays)
+		kmem_cache_free(delayacct_cache, tsk->delays);
+	tsk->delays = NULL;
+}
+
+static inline void delayacct_blkio_start(void)
+{
+	if (current->delays)
+		__delayacct_blkio_start();
+}
+
+static inline void delayacct_blkio_end(void)
+{
+	if (current->delays)
+		__delayacct_blkio_end();
+}
+
+static inline int delayacct_add_tsk(struct taskstats *d,
+					struct task_struct *tsk)
+{
+	if (!delayacct_on || !tsk->delays)
+		return 0;
+	return __delayacct_add_tsk(d, tsk);
+}
+
+static inline __u64 delayacct_blkio_ticks(struct task_struct *tsk)
+{
+	if (tsk->delays)
+		return __delayacct_blkio_ticks(tsk);
+	return 0;
+}
+
+#else
+static inline void delayacct_set_flag(int flag)
+{}
+static inline void delayacct_clear_flag(int flag)
+{}
+static inline void delayacct_init(void)
+{}
+static inline void delayacct_tsk_init(struct task_struct *tsk)
+{}
+static inline void delayacct_tsk_free(struct task_struct *tsk)
+{}
+static inline void delayacct_blkio_start(void)
+{}
+static inline void delayacct_blkio_end(void)
+{}
+static inline int delayacct_add_tsk(struct taskstats *d,
+					struct task_struct *tsk)
+{ return 0; }
+static inline __u64 delayacct_blkio_ticks(struct task_struct *tsk)
+{ return 0; }
+#endif /* CONFIG_TASK_DELAY_ACCT */
+
+#endif
diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h
new file mode 100644
index 000000000..c94d8f1d6
--- /dev/null
+++ b/include/linux/dmaengine.h
@@ -0,0 +1,366 @@
+/*
+ * Copyright(c) 2004 - 2006 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59
+ * Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called COPYING.
+ */
+#ifndef DMAENGINE_H
+#define DMAENGINE_H
+
+#ifdef CONFIG_DMA_ENGINE
+
+#include <linux/device.h>
+#include <linux/uio.h>
+#include <linux/kref.h>
+#include <linux/completion.h>
+#include <linux/rcupdate.h>
+
+/**
+ * enum dma_event - resource PNP/power managment events
+ * @DMA_RESOURCE_SUSPEND: DMA device going into low power state
+ * @DMA_RESOURCE_RESUME: DMA device returning to full power
+ * @DMA_RESOURCE_ADDED: DMA device added to the system
+ * @DMA_RESOURCE_REMOVED: DMA device removed from the system
+ */
+enum dma_event {
+	DMA_RESOURCE_SUSPEND,
+	DMA_RESOURCE_RESUME,
+	DMA_RESOURCE_ADDED,
+	DMA_RESOURCE_REMOVED,
+};
+
+/**
+ * typedef dma_cookie_t - an opaque DMA cookie
+ *
+ * if dma_cookie_t is >0 it's a DMA request cookie, <0 it's an error code
+ */
+typedef s32 dma_cookie_t;
+
+#define dma_submit_error(cookie) ((cookie) < 0 ? 1 : 0)
+
+/**
+ * enum dma_status - DMA transaction status
+ * @DMA_SUCCESS: transaction completed successfully
+ * @DMA_IN_PROGRESS: transaction not yet processed
+ * @DMA_ERROR: transaction failed
+ */
+enum dma_status {
+	DMA_SUCCESS,
+	DMA_IN_PROGRESS,
+	DMA_ERROR,
+};
+
+/**
+ * struct dma_chan_percpu - the per-CPU part of struct dma_chan
+ * @refcount: local_t used for open-coded "bigref" counting
+ * @memcpy_count: transaction counter
+ * @bytes_transferred: byte counter
+ */
+
+struct dma_chan_percpu {
+	local_t refcount;
+	/* stats */
+	unsigned long memcpy_count;
+	unsigned long bytes_transferred;
+};
+
+/**
+ * struct dma_chan - devices supply DMA channels, clients use them
+ * @client: ptr to the client user of this chan, will be %NULL when unused
+ * @device: ptr to the dma device who supplies this channel, always !%NULL
+ * @cookie: last cookie value returned to client
+ * @chan_id: channel ID for sysfs
+ * @class_dev: class device for sysfs
+ * @refcount: kref, used in "bigref" slow-mode
+ * @slow_ref: indicates that the DMA channel is free
+ * @rcu: the DMA channel's RCU head
+ * @client_node: used to add this to the client chan list
+ * @device_node: used to add this to the device chan list
+ * @local: per-cpu pointer to a struct dma_chan_percpu
+ */
+struct dma_chan {
+	struct dma_client *client;
+	struct dma_device *device;
+	dma_cookie_t cookie;
+
+	/* sysfs */
+	int chan_id;
+	struct class_device class_dev;
+
+	struct kref refcount;
+	int slow_ref;
+	struct rcu_head rcu;
+
+	struct list_head client_node;
+	struct list_head device_node;
+	struct dma_chan_percpu *local;
+};
+
+void dma_chan_cleanup(struct kref *kref);
+
+static inline void dma_chan_get(struct dma_chan *chan)
+{
+	if (unlikely(chan->slow_ref))
+		kref_get(&chan->refcount);
+	else {
+		local_inc(&(per_cpu_ptr(chan->local, get_cpu())->refcount));
+		put_cpu();
+	}
+}
+
+static inline void dma_chan_put(struct dma_chan *chan)
+{
+	if (unlikely(chan->slow_ref))
+		kref_put(&chan->refcount, dma_chan_cleanup);
+	else {
+		local_dec(&(per_cpu_ptr(chan->local, get_cpu())->refcount));
+		put_cpu();
+	}
+}
+
+/*
+ * typedef dma_event_callback - function pointer to a DMA event callback
+ */
+typedef void (*dma_event_callback) (struct dma_client *client,
+		struct dma_chan *chan, enum dma_event event);
+
+/**
+ * struct dma_client - info on the entity making use of DMA services
+ * @event_callback: func ptr to call when something happens
+ * @chan_count: number of chans allocated
+ * @chans_desired: number of chans requested. Can be +/- chan_count
+ * @lock: protects access to the channels list
+ * @channels: the list of DMA channels allocated
+ * @global_node: list_head for global dma_client_list
+ */
+struct dma_client {
+	dma_event_callback	event_callback;
+	unsigned int		chan_count;
+	unsigned int		chans_desired;
+
+	spinlock_t		lock;
+	struct list_head	channels;
+	struct list_head	global_node;
+};
+
+/**
+ * struct dma_device - info on the entity supplying DMA services
+ * @chancnt: how many DMA channels are supported
+ * @channels: the list of struct dma_chan
+ * @global_node: list_head for global dma_device_list
+ * @refcount: reference count
+ * @done: IO completion struct
+ * @dev_id: unique device ID
+ * @device_alloc_chan_resources: allocate resources and return the
+ *	number of allocated descriptors
+ * @device_free_chan_resources: release DMA channel's resources
+ * @device_memcpy_buf_to_buf: memcpy buf pointer to buf pointer
+ * @device_memcpy_buf_to_pg: memcpy buf pointer to struct page
+ * @device_memcpy_pg_to_pg: memcpy struct page/offset to struct page/offset
+ * @device_memcpy_complete: poll the status of an IOAT DMA transaction
+ * @device_memcpy_issue_pending: push appended descriptors to hardware
+ */
+struct dma_device {
+
+	unsigned int chancnt;
+	struct list_head channels;
+	struct list_head global_node;
+
+	struct kref refcount;
+	struct completion done;
+
+	int dev_id;
+
+	int (*device_alloc_chan_resources)(struct dma_chan *chan);
+	void (*device_free_chan_resources)(struct dma_chan *chan);
+	dma_cookie_t (*device_memcpy_buf_to_buf)(struct dma_chan *chan,
+			void *dest, void *src, size_t len);
+	dma_cookie_t (*device_memcpy_buf_to_pg)(struct dma_chan *chan,
+			struct page *page, unsigned int offset, void *kdata,
+			size_t len);
+	dma_cookie_t (*device_memcpy_pg_to_pg)(struct dma_chan *chan,
+			struct page *dest_pg, unsigned int dest_off,
+			struct page *src_pg, unsigned int src_off, size_t len);
+	enum dma_status (*device_memcpy_complete)(struct dma_chan *chan,
+			dma_cookie_t cookie, dma_cookie_t *last,
+			dma_cookie_t *used);
+	void (*device_memcpy_issue_pending)(struct dma_chan *chan);
+};
+
+/* --- public DMA engine API --- */
+
+struct dma_client *dma_async_client_register(dma_event_callback event_callback);
+void dma_async_client_unregister(struct dma_client *client);
+void dma_async_client_chan_request(struct dma_client *client,
+		unsigned int number);
+
+/**
+ * dma_async_memcpy_buf_to_buf - offloaded copy between virtual addresses
+ * @chan: DMA channel to offload copy to
+ * @dest: destination address (virtual)
+ * @src: source address (virtual)
+ * @len: length
+ *
+ * Both @dest and @src must be mappable to a bus address according to the
+ * DMA mapping API rules for streaming mappings.
+ * Both @dest and @src must stay memory resident (kernel memory or locked
+ * user space pages).
+ */
+static inline dma_cookie_t dma_async_memcpy_buf_to_buf(struct dma_chan *chan,
+	void *dest, void *src, size_t len)
+{
+	int cpu = get_cpu();
+	per_cpu_ptr(chan->local, cpu)->bytes_transferred += len;
+	per_cpu_ptr(chan->local, cpu)->memcpy_count++;
+	put_cpu();
+
+	return chan->device->device_memcpy_buf_to_buf(chan, dest, src, len);
+}
+
+/**
+ * dma_async_memcpy_buf_to_pg - offloaded copy from address to page
+ * @chan: DMA channel to offload copy to
+ * @page: destination page
+ * @offset: offset in page to copy to
+ * @kdata: source address (virtual)
+ * @len: length
+ *
+ * Both @page/@offset and @kdata must be mappable to a bus address according
+ * to the DMA mapping API rules for streaming mappings.
+ * Both @page/@offset and @kdata must stay memory resident (kernel memory or
+ * locked user space pages)
+ */
+static inline dma_cookie_t dma_async_memcpy_buf_to_pg(struct dma_chan *chan,
+	struct page *page, unsigned int offset, void *kdata, size_t len)
+{
+	int cpu = get_cpu();
+	per_cpu_ptr(chan->local, cpu)->bytes_transferred += len;
+	per_cpu_ptr(chan->local, cpu)->memcpy_count++;
+	put_cpu();
+
+	return chan->device->device_memcpy_buf_to_pg(chan, page, offset,
+	                                             kdata, len);
+}
+
+/**
+ * dma_async_memcpy_pg_to_pg - offloaded copy from page to page
+ * @chan: DMA channel to offload copy to
+ * @dest_pg: destination page
+ * @dest_off: offset in page to copy to
+ * @src_pg: source page
+ * @src_off: offset in page to copy from
+ * @len: length
+ *
+ * Both @dest_page/@dest_off and @src_page/@src_off must be mappable to a bus
+ * address according to the DMA mapping API rules for streaming mappings.
+ * Both @dest_page/@dest_off and @src_page/@src_off must stay memory resident
+ * (kernel memory or locked user space pages).
+ */
+static inline dma_cookie_t dma_async_memcpy_pg_to_pg(struct dma_chan *chan,
+	struct page *dest_pg, unsigned int dest_off, struct page *src_pg,
+	unsigned int src_off, size_t len)
+{
+	int cpu = get_cpu();
+	per_cpu_ptr(chan->local, cpu)->bytes_transferred += len;
+	per_cpu_ptr(chan->local, cpu)->memcpy_count++;
+	put_cpu();
+
+	return chan->device->device_memcpy_pg_to_pg(chan, dest_pg, dest_off,
+	                                            src_pg, src_off, len);
+}
+
+/**
+ * dma_async_memcpy_issue_pending - flush pending copies to HW
+ * @chan: target DMA channel
+ *
+ * This allows drivers to push copies to HW in batches,
+ * reducing MMIO writes where possible.
+ */
+static inline void dma_async_memcpy_issue_pending(struct dma_chan *chan)
+{
+	return chan->device->device_memcpy_issue_pending(chan);
+}
+
+/**
+ * dma_async_memcpy_complete - poll for transaction completion
+ * @chan: DMA channel
+ * @cookie: transaction identifier to check status of
+ * @last: returns last completed cookie, can be NULL
+ * @used: returns last issued cookie, can be NULL
+ *
+ * If @last and @used are passed in, upon return they reflect the driver
+ * internal state and can be used with dma_async_is_complete() to check
+ * the status of multiple cookies without re-checking hardware state.
+ */
+static inline enum dma_status dma_async_memcpy_complete(struct dma_chan *chan,
+	dma_cookie_t cookie, dma_cookie_t *last, dma_cookie_t *used)
+{
+	return chan->device->device_memcpy_complete(chan, cookie, last, used);
+}
+
+/**
+ * dma_async_is_complete - test a cookie against chan state
+ * @cookie: transaction identifier to test status of
+ * @last_complete: last know completed transaction
+ * @last_used: last cookie value handed out
+ *
+ * dma_async_is_complete() is used in dma_async_memcpy_complete()
+ * the test logic is seperated for lightweight testing of multiple cookies
+ */
+static inline enum dma_status dma_async_is_complete(dma_cookie_t cookie,
+			dma_cookie_t last_complete, dma_cookie_t last_used)
+{
+	if (last_complete <= last_used) {
+		if ((cookie <= last_complete) || (cookie > last_used))
+			return DMA_SUCCESS;
+	} else {
+		if ((cookie <= last_complete) && (cookie > last_used))
+			return DMA_SUCCESS;
+	}
+	return DMA_IN_PROGRESS;
+}
+
+
+/* --- DMA device --- */
+
+int dma_async_device_register(struct dma_device *device);
+void dma_async_device_unregister(struct dma_device *device);
+
+/* --- Helper iov-locking functions --- */
+
+struct dma_page_list {
+	char *base_address;
+	int nr_pages;
+	struct page **pages;
+};
+
+struct dma_pinned_list {
+	int nr_iovecs;
+	struct dma_page_list page_list[0];
+};
+
+struct dma_pinned_list *dma_pin_iovec_pages(struct iovec *iov, size_t len);
+void dma_unpin_iovec_pages(struct dma_pinned_list* pinned_list);
+
+dma_cookie_t dma_memcpy_to_iovec(struct dma_chan *chan, struct iovec *iov,
+	struct dma_pinned_list *pinned_list, unsigned char *kdata, size_t len);
+dma_cookie_t dma_memcpy_pg_to_iovec(struct dma_chan *chan, struct iovec *iov,
+	struct dma_pinned_list *pinned_list, struct page *page,
+	unsigned int offset, size_t len);
+
+#endif /* CONFIG_DMA_ENGINE */
+#endif /* DMAENGINE_H */
diff --git a/include/linux/dvb/Kbuild b/include/linux/dvb/Kbuild
new file mode 100644
index 000000000..d97b3a51e
--- /dev/null
+++ b/include/linux/dvb/Kbuild
@@ -0,0 +1,9 @@
+header-y += ca.h
+header-y += frontend.h
+header-y += net.h
+header-y += osd.h
+header-y += version.h
+
+unifdef-y += audio.h
+unifdef-y += dmx.h
+unifdef-y += video.h
diff --git a/include/linux/elf-em.h b/include/linux/elf-em.h
new file mode 100644
index 000000000..6a5796c81
--- /dev/null
+++ b/include/linux/elf-em.h
@@ -0,0 +1,49 @@
+#ifndef _LINUX_ELF_EM_H
+#define _LINUX_ELF_EM_H
+
+/* These constants define the various ELF target machines */
+#define EM_NONE		0
+#define EM_M32		1
+#define EM_SPARC	2
+#define EM_386		3
+#define EM_68K		4
+#define EM_88K		5
+#define EM_486		6	/* Perhaps disused */
+#define EM_860		7
+#define EM_MIPS		8	/* MIPS R3000 (officially, big-endian only) */
+				/* Next two are historical and binaries and
+				   modules of these types will be rejected by
+				   Linux.  */
+#define EM_MIPS_RS3_LE	10	/* MIPS R3000 little-endian */
+#define EM_MIPS_RS4_BE	10	/* MIPS R4000 big-endian */
+
+#define EM_PARISC	15	/* HPPA */
+#define EM_SPARC32PLUS	18	/* Sun's "v8plus" */
+#define EM_PPC		20	/* PowerPC */
+#define EM_PPC64	21       /* PowerPC64 */
+#define EM_SH		42	/* SuperH */
+#define EM_SPARCV9	43	/* SPARC v9 64-bit */
+#define EM_IA_64	50	/* HP/Intel IA-64 */
+#define EM_X86_64	62	/* AMD x86-64 */
+#define EM_S390		22	/* IBM S/390 */
+#define EM_CRIS		76	/* Axis Communications 32-bit embedded processor */
+#define EM_V850		87	/* NEC v850 */
+#define EM_M32R		88	/* Renesas M32R */
+#define EM_H8_300	46	/* Renesas H8/300,300H,H8S */
+#define EM_FRV		0x5441	/* Fujitsu FR-V */
+
+/*
+ * This is an interim value that we will use until the committee comes
+ * up with a final number.
+ */
+#define EM_ALPHA	0x9026
+
+/* Bogus old v850 magic number, used by old tools. */
+#define EM_CYGNUS_V850	0x9080
+/* Bogus old m32r magic number, used by old tools. */
+#define EM_CYGNUS_M32R	0x9041
+/* This is the old interim value for S/390 architecture */
+#define EM_S390_OLD	0xA390
+
+
+#endif /* _LINUX_ELF_EM_H */
diff --git a/include/linux/elfnote.h b/include/linux/elfnote.h
new file mode 100644
index 000000000..67396db14
--- /dev/null
+++ b/include/linux/elfnote.h
@@ -0,0 +1,90 @@
+#ifndef _LINUX_ELFNOTE_H
+#define _LINUX_ELFNOTE_H
+/*
+ * Helper macros to generate ELF Note structures, which are put into a
+ * PT_NOTE segment of the final vmlinux image.  These are useful for
+ * including name-value pairs of metadata into the kernel binary (or
+ * modules?) for use by external programs.
+ *
+ * Each note has three parts: a name, a type and a desc.  The name is
+ * intended to distinguish the note's originator, so it would be a
+ * company, project, subsystem, etc; it must be in a suitable form for
+ * use in a section name.  The type is an integer which is used to tag
+ * the data, and is considered to be within the "name" namespace (so
+ * "FooCo"'s type 42 is distinct from "BarProj"'s type 42).  The
+ * "desc" field is the actual data.  There are no constraints on the
+ * desc field's contents, though typically they're fairly small.
+ *
+ * All notes from a given NAME are put into a section named
+ * .note.NAME.  When the kernel image is finally linked, all the notes
+ * are packed into a single .notes section, which is mapped into the
+ * PT_NOTE segment.  Because notes for a given name are grouped into
+ * the same section, they'll all be adjacent the output file.
+ *
+ * This file defines macros for both C and assembler use.  Their
+ * syntax is slightly different, but they're semantically similar.
+ *
+ * See the ELF specification for more detail about ELF notes.
+ */
+
+#ifdef __ASSEMBLER__
+/*
+ * Generate a structure with the same shape as Elf{32,64}_Nhdr (which
+ * turn out to be the same size and shape), followed by the name and
+ * desc data with appropriate padding.  The 'desctype' argument is the
+ * assembler pseudo op defining the type of the data e.g. .asciz while
+ * 'descdata' is the data itself e.g.  "hello, world".
+ *
+ * e.g. ELFNOTE(XYZCo, 42, .asciz, "forty-two")
+ *      ELFNOTE(XYZCo, 12, .long, 0xdeadbeef)
+ */
+#define ELFNOTE(name, type, desctype, descdata)	\
+.pushsection .note.name			;	\
+  .align 4				;	\
+  .long 2f - 1f		/* namesz */	;	\
+  .long 4f - 3f		/* descsz */	;	\
+  .long type				;	\
+1:.asciz "name"				;	\
+2:.align 4				;	\
+3:desctype descdata			;	\
+4:.align 4				;	\
+.popsection				;
+#else	/* !__ASSEMBLER__ */
+#include <linux/elf.h>
+/*
+ * Use an anonymous structure which matches the shape of
+ * Elf{32,64}_Nhdr, but includes the name and desc data.  The size and
+ * type of name and desc depend on the macro arguments.  "name" must
+ * be a literal string, and "desc" must be passed by value.  You may
+ * only define one note per line, since __LINE__ is used to generate
+ * unique symbols.
+ */
+#define _ELFNOTE_PASTE(a,b)	a##b
+#define _ELFNOTE(size, name, unique, type, desc)			\
+	static const struct {						\
+		struct elf##size##_note _nhdr;				\
+		unsigned char _name[sizeof(name)]			\
+		__attribute__((aligned(sizeof(Elf##size##_Word))));	\
+		typeof(desc) _desc					\
+			     __attribute__((aligned(sizeof(Elf##size##_Word)))); \
+	} _ELFNOTE_PASTE(_note_, unique)				\
+		__attribute_used__					\
+		__attribute__((section(".note." name),			\
+			       aligned(sizeof(Elf##size##_Word)),	\
+			       unused)) = {				\
+		{							\
+			sizeof(name),					\
+			sizeof(desc),					\
+			type,						\
+		},							\
+		name,							\
+		desc							\
+	}
+#define ELFNOTE(size, name, type, desc)		\
+	_ELFNOTE(size, name, __LINE__, type, desc)
+
+#define ELFNOTE32(name, type, desc) ELFNOTE(32, name, type, desc)
+#define ELFNOTE64(name, type, desc) ELFNOTE(64, name, type, desc)
+#endif	/* __ASSEMBLER__ */
+
+#endif /* _LINUX_ELFNOTE_H */
diff --git a/include/linux/fscache-cache.h b/include/linux/fscache-cache.h
new file mode 100644
index 000000000..e229fed00
--- /dev/null
+++ b/include/linux/fscache-cache.h
@@ -0,0 +1,243 @@
+/* fscache-cache.h: general filesystem caching backing cache interface
+ *
+ * Copyright (C) 2004-6 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@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.
+ *
+ * NOTE!!! See:
+ *
+ *	Documentation/filesystems/caching/backend-api.txt
+ *
+ * for a description of the cache backend interface declared here.
+ */
+
+#ifndef _LINUX_FSCACHE_CACHE_H
+#define _LINUX_FSCACHE_CACHE_H
+
+#include <linux/fscache.h>
+
+#define NR_MAXCACHES BITS_PER_LONG
+
+struct fscache_cache;
+struct fscache_cache_ops;
+struct fscache_object;
+
+/*
+ * cache tag definition
+ */
+struct fscache_cache_tag {
+	struct list_head		link;
+	struct fscache_cache		*cache;		/* cache referred to by this tag */
+	atomic_t			usage;
+	char				name[0];	/* tag name */
+};
+
+/*
+ * cache definition
+ */
+struct fscache_cache {
+	struct fscache_cache_ops	*ops;
+	struct fscache_cache_tag	*tag;		/* tag representing this cache */
+	struct list_head		link;		/* link in list of caches */
+	struct rw_semaphore		withdrawal_sem;	/* withdrawal control sem */
+	size_t				max_index_size;	/* maximum size of index data */
+	char				identifier[32];	/* cache label */
+
+	/* node management */
+	struct list_head		object_list;	/* list of data/index objects */
+	spinlock_t			object_list_lock;
+	struct fscache_object		*fsdef;		/* object for the fsdef index */
+	unsigned long			flags;
+#define FSCACHE_IOERROR			0	/* cache stopped on I/O error */
+};
+
+extern void fscache_init_cache(struct fscache_cache *cache,
+			       struct fscache_cache_ops *ops,
+			       const char *idfmt,
+			       ...) __attribute__ ((format (printf,3,4)));
+
+extern int fscache_add_cache(struct fscache_cache *cache,
+			     struct fscache_object *fsdef,
+			     const char *tagname);
+extern void fscache_withdraw_cache(struct fscache_cache *cache);
+
+extern void fscache_io_error(struct fscache_cache *cache);
+
+/*****************************************************************************/
+/*
+ * cache operations
+ */
+struct fscache_cache_ops {
+	/* name of cache provider */
+	const char *name;
+
+	/* look up the object for a cookie, creating it on disc if necessary */
+	struct fscache_object *(*lookup_object)(struct fscache_cache *cache,
+						struct fscache_object *parent,
+						struct fscache_cookie *cookie);
+
+	/* increment the usage count on this object (may fail if unmounting) */
+	struct fscache_object *(*grab_object)(struct fscache_object *object);
+
+	/* lock a semaphore on an object */
+	void (*lock_object)(struct fscache_object *object);
+
+	/* unlock a semaphore on an object */
+	void (*unlock_object)(struct fscache_object *object);
+
+	/* pin an object in the cache */
+	int (*pin_object)(struct fscache_object *object);
+
+	/* unpin an object in the cache */
+	void (*unpin_object)(struct fscache_object *object);
+
+	/* store the updated auxilliary data on an object */
+	void (*update_object)(struct fscache_object *object);
+
+	/* dispose of a reference to an object */
+	void (*put_object)(struct fscache_object *object);
+
+	/* sync a cache */
+	void (*sync_cache)(struct fscache_cache *cache);
+
+	/* set the data size of an object */
+	int (*set_i_size)(struct fscache_object *object, loff_t i_size);
+
+	/* reserve space for an object's data and associated metadata */
+	int (*reserve_space)(struct fscache_object *object, loff_t i_size);
+
+	/* request a backing block for a page be read or allocated in the
+	 * cache */
+	int (*read_or_alloc_page)(struct fscache_object *object,
+				  struct page *page,
+				  fscache_rw_complete_t end_io_func,
+				  void *context,
+				  unsigned long gfp);
+
+	/* request backing blocks for a list of pages be read or allocated in
+	 * the cache */
+	int (*read_or_alloc_pages)(struct fscache_object *object,
+				   struct address_space *mapping,
+				   struct list_head *pages,
+				   unsigned *nr_pages,
+				   fscache_rw_complete_t end_io_func,
+				   void *context,
+				   unsigned long gfp);
+
+	/* request a backing block for a page be allocated in the cache so that
+	 * it can be written directly */
+	int (*allocate_page)(struct fscache_object *object,
+			     struct page *page,
+			     unsigned long gfp);
+
+	/* write a page to its backing block in the cache */
+	int (*write_page)(struct fscache_object *object,
+			  struct page *page,
+			  fscache_rw_complete_t end_io_func,
+			  void *context,
+			  unsigned long gfp);
+
+	/* write several pages to their backing blocks in the cache */
+	int (*write_pages)(struct fscache_object *object,
+			   struct pagevec *pagevec,
+			   fscache_rw_complete_t end_io_func,
+			   void *context,
+			   unsigned long gfp);
+
+	/* detach backing block from a bunch of pages */
+	void (*uncache_pages)(struct fscache_object *object,
+			     struct pagevec *pagevec);
+
+	/* dissociate a cache from all the pages it was backing */
+	void (*dissociate_pages)(struct fscache_cache *cache);
+};
+
+/*****************************************************************************/
+/*
+ * data file or index object cookie
+ * - a file will only appear in one cache
+ * - a request to cache a file may or may not be honoured, subject to
+ *   constraints such as disc space
+ * - indexes files are created on disc just-in-time
+ */
+struct fscache_cookie {
+	atomic_t			usage;		/* number of users of this cookie */
+	atomic_t			children;	/* number of children of this cookie */
+	struct rw_semaphore		sem;		/* list creation vs scan lock */
+	struct hlist_head		backing_objects; /* object(s) backing this file/index */
+	struct fscache_cookie_def	*def;		/* definition */
+	struct fscache_cookie		*parent;	/* parent of this entry */
+	struct fscache_netfs		*netfs;		/* owner network fs definition */
+	void				*netfs_data;	/* back pointer to netfs */
+};
+
+extern struct fscache_cookie fscache_fsdef_index;
+
+/*****************************************************************************/
+/*
+ * on-disc cache file or index handle
+ */
+struct fscache_object {
+	unsigned long			flags;
+#define FSCACHE_OBJECT_RELEASING	0	/* T if object is being released */
+#define FSCACHE_OBJECT_RECYCLING	1	/* T if object is being retired */
+#define FSCACHE_OBJECT_WITHDRAWN	2	/* T if object has been withdrawn */
+
+	struct list_head		cache_link;	/* link in cache->object_list */
+	struct hlist_node		cookie_link;	/* link in cookie->backing_objects */
+	struct fscache_cache		*cache;		/* cache that supplied this object */
+	struct fscache_cookie		*cookie;	/* netfs's file/index object */
+};
+
+static inline
+void fscache_object_init(struct fscache_object *object)
+{
+	object->flags = 0;
+	INIT_LIST_HEAD(&object->cache_link);
+	INIT_HLIST_NODE(&object->cookie_link);
+	object->cache = NULL;
+	object->cookie = NULL;
+}
+
+/* find the parent index object for a object */
+static inline
+struct fscache_object *fscache_find_parent_object(struct fscache_object *object)
+{
+	struct fscache_object *parent;
+	struct fscache_cookie *cookie = object->cookie;
+	struct fscache_cache *cache = object->cache;
+	struct hlist_node *_p;
+
+	hlist_for_each_entry(parent, _p,
+			     &cookie->parent->backing_objects,
+			     cookie_link
+			     ) {
+		if (parent->cache == cache)
+			return parent;
+	}
+
+	return NULL;
+}
+
+/* get an extra reference to a context */
+static inline
+void *fscache_get_context(struct fscache_cookie *cookie, void *context)
+{
+	if (cookie->def->get_context)
+		cookie->def->get_context(cookie->netfs_data, context);
+	return context;
+}
+
+/* release an extra reference to a context */
+static inline
+void fscache_put_context(struct fscache_cookie *cookie, void *context)
+{
+	if (cookie->def->put_context)
+		cookie->def->put_context(cookie->netfs_data, context);
+}
+
+#endif /* _LINUX_FSCACHE_CACHE_H */
diff --git a/include/linux/fscache.h b/include/linux/fscache.h
new file mode 100644
index 000000000..867ab9e9d
--- /dev/null
+++ b/include/linux/fscache.h
@@ -0,0 +1,495 @@
+/* fscache.h: general filesystem caching interface
+ *
+ * Copyright (C) 2004-5 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@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.
+ *
+ * NOTE!!! See:
+ *
+ *	Documentation/filesystems/caching/netfs-api.txt
+ *
+ * for a description of the network filesystem interface declared here.
+ */
+
+#ifndef _LINUX_FSCACHE_H
+#define _LINUX_FSCACHE_H
+
+#include <linux/fs.h>
+#include <linux/list.h>
+#include <linux/pagemap.h>
+#include <linux/pagevec.h>
+
+struct pagevec;
+struct fscache_cache_tag;
+struct fscache_cookie;
+struct fscache_netfs;
+struct fscache_netfs_operations;
+
+typedef void (*fscache_rw_complete_t)(struct page *page,
+				      void *context,
+				      int error);
+
+/* result of index entry consultation */
+typedef enum {
+	FSCACHE_CHECKAUX_OKAY,		/* entry okay as is */
+	FSCACHE_CHECKAUX_NEEDS_UPDATE,	/* entry requires update */
+	FSCACHE_CHECKAUX_OBSOLETE,	/* entry requires deletion */
+} fscache_checkaux_t;
+
+/*****************************************************************************/
+/*
+ * fscache cookie definition
+ */
+struct fscache_cookie_def
+{
+	/* name of cookie type */
+	char name[16];
+
+	/* cookie type */
+	uint8_t type;
+#define FSCACHE_COOKIE_TYPE_INDEX	0
+#define FSCACHE_COOKIE_TYPE_DATAFILE	1
+
+	/* select the cache into which to insert an entry in this index
+	 * - optional
+	 * - should return a cache identifier or NULL to cause the cache to be
+	 *   inherited from the parent if possible or the first cache picked
+	 *   for a non-index file if not
+	 */
+	struct fscache_cache_tag *(*select_cache)(const void *parent_netfs_data,
+						  const void *cookie_netfs_data);
+
+	/* get an index key
+	 * - should store the key data in the buffer
+	 * - should return the amount of amount stored
+	 * - not permitted to return an error
+	 * - the netfs data from the cookie being used as the source is
+	 *   presented
+	 */
+	uint16_t (*get_key)(const void *cookie_netfs_data,
+			    void *buffer,
+			    uint16_t bufmax);
+
+	/* get certain file attributes from the netfs data
+	 * - this function can be absent for an index
+	 * - not permitted to return an error
+	 * - the netfs data from the cookie being used as the source is
+	 *   presented
+	 */
+	void (*get_attr)(const void *cookie_netfs_data, uint64_t *size);
+
+	/* get the auxilliary data from netfs data
+	 * - this function can be absent if the index carries no state data
+	 * - should store the auxilliary data in the buffer
+	 * - should return the amount of amount stored
+	 * - not permitted to return an error
+	 * - the netfs data from the cookie being used as the source is
+	 *   presented
+	 */
+	uint16_t (*get_aux)(const void *cookie_netfs_data,
+			    void *buffer,
+			    uint16_t bufmax);
+
+	/* consult the netfs about the state of an object
+	 * - this function can be absent if the index carries no state data
+	 * - the netfs data from the cookie being used as the target is
+	 *   presented, as is the auxilliary data
+	 */
+	fscache_checkaux_t (*check_aux)(void *cookie_netfs_data,
+					const void *data,
+					uint16_t datalen);
+
+	/* get an extra reference on a read context
+	 * - this function can be absent if the completion function doesn't
+	 *   require a context
+	 */
+	void (*get_context)(void *cookie_netfs_data, void *context);
+
+	/* release an extra reference on a read context
+	 * - this function can be absent if the completion function doesn't
+	 *   require a context
+	 */
+	void (*put_context)(void *cookie_netfs_data, void *context);
+
+	/* indicate pages that now have cache metadata retained
+	 * - this function should mark the specified pages as now being cached
+	 */
+	void (*mark_pages_cached)(void *cookie_netfs_data,
+				  struct address_space *mapping,
+				  struct pagevec *cached_pvec);
+
+	/* indicate the cookie is no longer cached
+	 * - this function is called when the backing store currently caching
+	 *   a cookie is removed
+	 * - the netfs should use this to clean up any markers indicating
+	 *   cached pages
+	 * - this is mandatory for any object that may have data
+	 */
+	void (*now_uncached)(void *cookie_netfs_data);
+};
+
+/* pattern used to fill dead space in an index entry */
+#define FSCACHE_INDEX_DEADFILL_PATTERN 0x79
+
+#if defined(CONFIG_FSCACHE) || defined(CONFIG_FSCACHE_MODULE)
+extern struct fscache_cookie *__fscache_acquire_cookie(struct fscache_cookie *parent,
+						       struct fscache_cookie_def *def,
+						       void *netfs_data);
+
+extern void __fscache_relinquish_cookie(struct fscache_cookie *cookie,
+					int retire);
+
+extern void __fscache_update_cookie(struct fscache_cookie *cookie);
+#endif
+
+static inline
+struct fscache_cookie *fscache_acquire_cookie(struct fscache_cookie *parent,
+					      struct fscache_cookie_def *def,
+					      void *netfs_data)
+{
+#if defined(CONFIG_FSCACHE) || defined(CONFIG_FSCACHE_MODULE)
+	if (parent)
+		return __fscache_acquire_cookie(parent, def, netfs_data);
+#endif
+	return NULL;
+}
+
+static inline
+void fscache_relinquish_cookie(struct fscache_cookie *cookie,
+			       int retire)
+{
+#if defined(CONFIG_FSCACHE) || defined(CONFIG_FSCACHE_MODULE)
+	if (cookie)
+		__fscache_relinquish_cookie(cookie, retire);
+#endif
+}
+
+static inline
+void fscache_update_cookie(struct fscache_cookie *cookie)
+{
+#if defined(CONFIG_FSCACHE) || defined(CONFIG_FSCACHE_MODULE)
+	if (cookie)
+		__fscache_update_cookie(cookie);
+#endif
+}
+
+/*****************************************************************************/
+/*
+ * pin or unpin a cookie in a cache
+ * - only available for data cookies
+ */
+#if defined(CONFIG_FSCACHE) || defined(CONFIG_FSCACHE_MODULE)
+extern int __fscache_pin_cookie(struct fscache_cookie *cookie);
+extern void __fscache_unpin_cookie(struct fscache_cookie *cookie);
+#endif
+
+static inline
+int fscache_pin_cookie(struct fscache_cookie *cookie)
+{
+#if defined(CONFIG_FSCACHE) || defined(CONFIG_FSCACHE_MODULE)
+	if (cookie)
+		return __fscache_pin_cookie(cookie);
+#endif
+	return -ENOBUFS;
+}
+
+static inline
+void fscache_unpin_cookie(struct fscache_cookie *cookie)
+{
+#if defined(CONFIG_FSCACHE) || defined(CONFIG_FSCACHE_MODULE)
+	if (cookie)
+		__fscache_unpin_cookie(cookie);
+#endif
+}
+
+/*****************************************************************************/
+/*
+ * fscache cached network filesystem type
+ * - name, version and ops must be filled in before registration
+ * - all other fields will be set during registration
+ */
+struct fscache_netfs
+{
+	uint32_t			version;	/* indexing version */
+	const char			*name;		/* filesystem name */
+	struct fscache_cookie		*primary_index;
+	struct fscache_netfs_operations	*ops;
+	struct list_head		link;		/* internal link */
+};
+
+struct fscache_netfs_operations
+{
+};
+
+#if defined(CONFIG_FSCACHE) || defined(CONFIG_FSCACHE_MODULE)
+extern int __fscache_register_netfs(struct fscache_netfs *netfs);
+extern void __fscache_unregister_netfs(struct fscache_netfs *netfs);
+#endif
+
+static inline
+int fscache_register_netfs(struct fscache_netfs *netfs)
+{
+#if defined(CONFIG_FSCACHE) || defined(CONFIG_FSCACHE_MODULE)
+	return __fscache_register_netfs(netfs);
+#else
+	return 0;
+#endif
+}
+
+static inline
+void fscache_unregister_netfs(struct fscache_netfs *netfs)
+{
+#if defined(CONFIG_FSCACHE) || defined(CONFIG_FSCACHE_MODULE)
+	__fscache_unregister_netfs(netfs);
+#endif
+}
+
+/*****************************************************************************/
+/*
+ * look up a cache tag
+ * - cache tags are used to select specific caches in which to cache indexes
+ */
+#if defined(CONFIG_FSCACHE) || defined(CONFIG_FSCACHE_MODULE)
+extern struct fscache_cache_tag *__fscache_lookup_cache_tag(const char *name);
+extern void __fscache_release_cache_tag(struct fscache_cache_tag *tag);
+#endif
+
+static inline
+struct fscache_cache_tag *fscache_lookup_cache_tag(const char *name)
+{
+#if defined(CONFIG_FSCACHE) || defined(CONFIG_FSCACHE_MODULE)
+	return __fscache_lookup_cache_tag(name);
+#else
+	return NULL;
+#endif
+}
+
+static inline
+void fscache_release_cache_tag(struct fscache_cache_tag *tag)
+{
+#if defined(CONFIG_FSCACHE) || defined(CONFIG_FSCACHE_MODULE)
+	__fscache_release_cache_tag(tag);
+#endif
+}
+
+/*****************************************************************************/
+/*
+ * set the data size on a cached object
+ * - no pages beyond the end of the object will be accessible
+ * - returns -ENOBUFS if the file is not backed
+ * - returns -ENOSPC if a pinned file of that size can't be stored
+ * - returns 0 if okay
+ */
+#if defined(CONFIG_FSCACHE) || defined(CONFIG_FSCACHE_MODULE)
+extern int __fscache_set_i_size(struct fscache_cookie *cookie, loff_t i_size);
+#endif
+
+static inline
+int fscache_set_i_size(struct fscache_cookie *cookie, loff_t i_size)
+{
+#if defined(CONFIG_FSCACHE) || defined(CONFIG_FSCACHE_MODULE)
+	if (cookie)
+		return __fscache_set_i_size(cookie, i_size);
+#endif
+	return -ENOBUFS;
+}
+
+/*****************************************************************************/
+/*
+ * reserve data space for a cached object
+ * - returns -ENOBUFS if the file is not backed
+ * - returns -ENOSPC if there isn't enough space to honour the reservation
+ * - returns 0 if okay
+ */
+#if defined(CONFIG_FSCACHE) || defined(CONFIG_FSCACHE_MODULE)
+extern int __fscache_reserve_space(struct fscache_cookie *cookie, loff_t size);
+#endif
+
+static inline
+int fscache_reserve_space(struct fscache_cookie *cookie, loff_t size)
+{
+#if defined(CONFIG_FSCACHE) || defined(CONFIG_FSCACHE_MODULE)
+	if (cookie)
+		return __fscache_reserve_space(cookie, size);
+#endif
+	return -ENOBUFS;
+}
+
+/*****************************************************************************/
+/*
+ * read a page from the cache or allocate a block in which to store it
+ * - if the page is not backed by a file:
+ *   - -ENOBUFS will be returned and nothing more will be done
+ * - else if the page is backed by a block in the cache:
+ *   - a read will be started which will call end_io_func on completion
+ * - else if the page is unbacked:
+ *   - a block will be allocated
+ *   - -ENODATA will be returned
+ */
+#if defined(CONFIG_FSCACHE) || defined(CONFIG_FSCACHE_MODULE)
+extern int __fscache_read_or_alloc_page(struct fscache_cookie *cookie,
+					struct page *page,
+					fscache_rw_complete_t end_io_func,
+					void *context,
+					gfp_t gfp);
+#endif
+
+static inline
+int fscache_read_or_alloc_page(struct fscache_cookie *cookie,
+			       struct page *page,
+			       fscache_rw_complete_t end_io_func,
+			       void *context,
+			       gfp_t gfp)
+{
+#if defined(CONFIG_FSCACHE) || defined(CONFIG_FSCACHE_MODULE)
+	if (cookie)
+		return __fscache_read_or_alloc_page(cookie, page, end_io_func,
+						    context, gfp);
+#endif
+	return -ENOBUFS;
+}
+
+#if defined(CONFIG_FSCACHE) || defined(CONFIG_FSCACHE_MODULE)
+extern int __fscache_read_or_alloc_pages(struct fscache_cookie *cookie,
+					 struct address_space *mapping,
+					 struct list_head *pages,
+					 unsigned *nr_pages,
+					 fscache_rw_complete_t end_io_func,
+					 void *context,
+					 gfp_t gfp);
+#endif
+
+static inline
+int fscache_read_or_alloc_pages(struct fscache_cookie *cookie,
+				struct address_space *mapping,
+				struct list_head *pages,
+				unsigned *nr_pages,
+				fscache_rw_complete_t end_io_func,
+				void *context,
+				gfp_t gfp)
+{
+#if defined(CONFIG_FSCACHE) || defined(CONFIG_FSCACHE_MODULE)
+	if (cookie)
+		return __fscache_read_or_alloc_pages(cookie, mapping, pages,
+						     nr_pages, end_io_func,
+						     context, gfp);
+#endif
+	return -ENOBUFS;
+}
+
+/*
+ * allocate a block in which to store a page
+ * - if the page is not backed by a file:
+ *   - -ENOBUFS will be returned and nothing more will be done
+ * - else
+ *   - a block will be allocated if there isn't one
+ *   - 0 will be returned
+ */
+#if defined(CONFIG_FSCACHE) || defined(CONFIG_FSCACHE_MODULE)
+extern int __fscache_alloc_page(struct fscache_cookie *cookie,
+				struct page *page,
+				gfp_t gfp);
+#endif
+
+static inline
+int fscache_alloc_page(struct fscache_cookie *cookie,
+		       struct page *page,
+		       gfp_t gfp)
+{
+#if defined(CONFIG_FSCACHE) || defined(CONFIG_FSCACHE_MODULE)
+	if (cookie)
+		return __fscache_alloc_page(cookie, page, gfp);
+#endif
+	return -ENOBUFS;
+}
+
+/*
+ * request a page be stored in the cache
+ * - this request may be ignored if no cache block is currently allocated, in
+ *   which case it:
+ *   - returns -ENOBUFS
+ * - if a cache block was already allocated:
+ *   - a BIO will be dispatched to write the page (end_io_func will be called
+ *     from the completion function)
+ *   - returns 0
+ */
+#if defined(CONFIG_FSCACHE) || defined(CONFIG_FSCACHE_MODULE)
+extern int __fscache_write_page(struct fscache_cookie *cookie,
+				struct page *page,
+				fscache_rw_complete_t end_io_func,
+				void *context,
+				gfp_t gfp);
+
+extern int __fscache_write_pages(struct fscache_cookie *cookie,
+				 struct pagevec *pagevec,
+				 fscache_rw_complete_t end_io_func,
+				 void *context,
+				 gfp_t gfp);
+#endif
+
+static inline
+int fscache_write_page(struct fscache_cookie *cookie,
+		       struct page *page,
+		       fscache_rw_complete_t end_io_func,
+		       void *context,
+		       gfp_t gfp)
+{
+#if defined(CONFIG_FSCACHE) || defined(CONFIG_FSCACHE_MODULE)
+	if (cookie)
+		return __fscache_write_page(cookie, page, end_io_func,
+					    context, gfp);
+#endif
+	return -ENOBUFS;
+}
+
+static inline
+int fscache_write_pages(struct fscache_cookie *cookie,
+			struct pagevec *pagevec,
+			fscache_rw_complete_t end_io_func,
+			void *context,
+			gfp_t gfp)
+{
+#if defined(CONFIG_FSCACHE) || defined(CONFIG_FSCACHE_MODULE)
+	if (cookie)
+		return __fscache_write_pages(cookie, pagevec, end_io_func,
+					     context, gfp);
+#endif
+	return -ENOBUFS;
+}
+
+/*
+ * indicate that caching is no longer required on a page
+ * - note: cannot cancel any outstanding BIOs between this page and the cache
+ */
+#if defined(CONFIG_FSCACHE) || defined(CONFIG_FSCACHE_MODULE)
+extern void __fscache_uncache_page(struct fscache_cookie *cookie,
+				   struct page *page);
+extern void __fscache_uncache_pages(struct fscache_cookie *cookie,
+				    struct pagevec *pagevec);
+#endif
+
+static inline
+void fscache_uncache_page(struct fscache_cookie *cookie,
+			  struct page *page)
+{
+#if defined(CONFIG_FSCACHE) || defined(CONFIG_FSCACHE_MODULE)
+	if (cookie)
+		__fscache_uncache_page(cookie, page);
+#endif
+}
+
+static inline
+void fscache_uncache_pagevec(struct fscache_cookie *cookie,
+			     struct pagevec *pagevec)
+{
+#if defined(CONFIG_FSCACHE) || defined(CONFIG_FSCACHE_MODULE)
+	if (cookie)
+		__fscache_uncache_pages(cookie, pagevec);
+#endif
+}
+
+#endif /* _LINUX_FSCACHE_H */
diff --git a/include/linux/hdlc/Kbuild b/include/linux/hdlc/Kbuild
new file mode 100644
index 000000000..1fb26448f
--- /dev/null
+++ b/include/linux/hdlc/Kbuild
@@ -0,0 +1 @@
+header-y += ioctl.h
diff --git a/include/linux/hw_random.h b/include/linux/hw_random.h
new file mode 100644
index 000000000..21ea7610e
--- /dev/null
+++ b/include/linux/hw_random.h
@@ -0,0 +1,50 @@
+/*
+	Hardware Random Number Generator
+
+	Please read Documentation/hw_random.txt for details on use.
+
+	----------------------------------------------------------
+	This software may be used and distributed according to the terms
+        of the GNU General Public License, incorporated herein by reference.
+
+ */
+
+#ifndef LINUX_HWRANDOM_H_
+#define LINUX_HWRANDOM_H_
+#ifdef __KERNEL__
+
+#include <linux/types.h>
+#include <linux/list.h>
+
+/**
+ * struct hwrng - Hardware Random Number Generator driver
+ * @name:		Unique RNG name.
+ * @init:		Initialization callback (can be NULL).
+ * @cleanup:		Cleanup callback (can be NULL).
+ * @data_present:	Callback to determine if data is available
+ *			on the RNG. If NULL, it is assumed that
+ *			there is always data available.
+ * @data_read:		Read data from the RNG device.
+ *			Returns the number of lower random bytes in "data".
+ *			Must not be NULL.
+ * @priv:		Private data, for use by the RNG driver.
+ */
+struct hwrng {
+	const char *name;
+	int (*init)(struct hwrng *rng);
+	void (*cleanup)(struct hwrng *rng);
+	int (*data_present)(struct hwrng *rng);
+	int (*data_read)(struct hwrng *rng, u32 *data);
+	unsigned long priv;
+
+	/* internal. */
+	struct list_head list;
+};
+
+/** Register a new Hardware Random Number Generator driver. */
+extern int hwrng_register(struct hwrng *rng);
+/** Unregister a Hardware Random Number Generator driver. */
+extern void hwrng_unregister(struct hwrng *rng);
+
+#endif /* __KERNEL__ */
+#endif /* LINUX_HWRANDOM_H_ */
diff --git a/include/linux/i2c-ocores.h b/include/linux/i2c-ocores.h
new file mode 100644
index 000000000..8ed591b08
--- /dev/null
+++ b/include/linux/i2c-ocores.h
@@ -0,0 +1,19 @@
+/*
+ * i2c-ocores.h - definitions for the i2c-ocores interface
+ *
+ * Peter Korsgaard <jacmet@sunsite.dk>
+ *
+ * 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 _LINUX_I2C_OCORES_H
+#define _LINUX_I2C_OCORES_H
+
+struct ocores_i2c_platform_data {
+	u32 regstep;   /* distance between registers */
+	u32 clock_khz; /* input clock in kHz */
+};
+
+#endif /* _LINUX_I2C_OCORES_H */
diff --git a/include/linux/irqflags.h b/include/linux/irqflags.h
new file mode 100644
index 000000000..412e025bc
--- /dev/null
+++ b/include/linux/irqflags.h
@@ -0,0 +1,96 @@
+/*
+ * include/linux/irqflags.h
+ *
+ * IRQ flags tracing: follow the state of the hardirq and softirq flags and
+ * provide callbacks for transitions between ON and OFF states.
+ *
+ * This file gets included from lowlevel asm headers too, to provide
+ * wrapped versions of the local_irq_*() APIs, based on the
+ * raw_local_irq_*() macros from the lowlevel headers.
+ */
+#ifndef _LINUX_TRACE_IRQFLAGS_H
+#define _LINUX_TRACE_IRQFLAGS_H
+
+#ifdef CONFIG_TRACE_IRQFLAGS
+  extern void trace_hardirqs_on(void);
+  extern void trace_hardirqs_off(void);
+  extern void trace_softirqs_on(unsigned long ip);
+  extern void trace_softirqs_off(unsigned long ip);
+# define trace_hardirq_context(p)	((p)->hardirq_context)
+# define trace_softirq_context(p)	((p)->softirq_context)
+# define trace_hardirqs_enabled(p)	((p)->hardirqs_enabled)
+# define trace_softirqs_enabled(p)	((p)->softirqs_enabled)
+# define trace_hardirq_enter()	do { current->hardirq_context++; } while (0)
+# define trace_hardirq_exit()	do { current->hardirq_context--; } while (0)
+# define trace_softirq_enter()	do { current->softirq_context++; } while (0)
+# define trace_softirq_exit()	do { current->softirq_context--; } while (0)
+# define INIT_TRACE_IRQFLAGS	.softirqs_enabled = 1,
+#else
+# define trace_hardirqs_on()		do { } while (0)
+# define trace_hardirqs_off()		do { } while (0)
+# define trace_softirqs_on(ip)		do { } while (0)
+# define trace_softirqs_off(ip)		do { } while (0)
+# define trace_hardirq_context(p)	0
+# define trace_softirq_context(p)	0
+# define trace_hardirqs_enabled(p)	0
+# define trace_softirqs_enabled(p)	0
+# define trace_hardirq_enter()		do { } while (0)
+# define trace_hardirq_exit()		do { } while (0)
+# define trace_softirq_enter()		do { } while (0)
+# define trace_softirq_exit()		do { } while (0)
+# define INIT_TRACE_IRQFLAGS
+#endif
+
+#ifdef CONFIG_TRACE_IRQFLAGS_SUPPORT
+
+#include <asm/irqflags.h>
+
+#define local_irq_enable() \
+	do { trace_hardirqs_on(); raw_local_irq_enable(); } while (0)
+#define local_irq_disable() \
+	do { raw_local_irq_disable(); trace_hardirqs_off(); } while (0)
+#define local_irq_save(flags) \
+	do { raw_local_irq_save(flags); trace_hardirqs_off(); } while (0)
+
+#define local_irq_restore(flags)				\
+	do {							\
+		if (raw_irqs_disabled_flags(flags)) {		\
+			raw_local_irq_restore(flags);		\
+			trace_hardirqs_off();			\
+		} else {					\
+			trace_hardirqs_on();			\
+			raw_local_irq_restore(flags);		\
+		}						\
+	} while (0)
+#else /* !CONFIG_TRACE_IRQFLAGS_SUPPORT */
+/*
+ * The local_irq_*() APIs are equal to the raw_local_irq*()
+ * if !TRACE_IRQFLAGS.
+ */
+# define raw_local_irq_disable()	local_irq_disable()
+# define raw_local_irq_enable()		local_irq_enable()
+# define raw_local_irq_save(flags)	local_irq_save(flags)
+# define raw_local_irq_restore(flags)	local_irq_restore(flags)
+#endif /* CONFIG_TRACE_IRQFLAGS_SUPPORT */
+
+#ifdef CONFIG_TRACE_IRQFLAGS_SUPPORT
+#define safe_halt()						\
+	do {							\
+		trace_hardirqs_on();				\
+		raw_safe_halt();				\
+	} while (0)
+
+#define local_save_flags(flags)		raw_local_save_flags(flags)
+
+#define irqs_disabled()						\
+({								\
+	unsigned long flags;					\
+								\
+	raw_local_save_flags(flags);				\
+	raw_irqs_disabled_flags(flags);				\
+})
+
+#define irqs_disabled_flags(flags)	raw_irqs_disabled_flags(flags)
+#endif		/* CONFIG_X86 */
+
+#endif
diff --git a/include/linux/irqreturn.h b/include/linux/irqreturn.h
new file mode 100644
index 000000000..881883c20
--- /dev/null
+++ b/include/linux/irqreturn.h
@@ -0,0 +1,25 @@
+/* irqreturn.h */
+#ifndef _LINUX_IRQRETURN_H
+#define _LINUX_IRQRETURN_H
+
+/*
+ * For 2.4.x compatibility, 2.4.x can use
+ *
+ *	typedef void irqreturn_t;
+ *	#define IRQ_NONE
+ *	#define IRQ_HANDLED
+ *	#define IRQ_RETVAL(x)
+ *
+ * To mix old-style and new-style irq handler returns.
+ *
+ * IRQ_NONE means we didn't handle it.
+ * IRQ_HANDLED means that we did have a valid interrupt and handled it.
+ * IRQ_RETVAL(x) selects on the two depending on x being non-zero (for handled)
+ */
+typedef int irqreturn_t;
+
+#define IRQ_NONE	(0)
+#define IRQ_HANDLED	(1)
+#define IRQ_RETVAL(x)	((x) != 0)
+
+#endif
diff --git a/include/linux/isa.h b/include/linux/isa.h
new file mode 100644
index 000000000..1b855335c
--- /dev/null
+++ b/include/linux/isa.h
@@ -0,0 +1,28 @@
+/*
+ * ISA bus.
+ */
+
+#ifndef __LINUX_ISA_H
+#define __LINUX_ISA_H
+
+#include <linux/device.h>
+#include <linux/kernel.h>
+
+struct isa_driver {
+	int (*match)(struct device *, unsigned int);
+	int (*probe)(struct device *, unsigned int);
+	int (*remove)(struct device *, unsigned int);
+	void (*shutdown)(struct device *, unsigned int);
+	int (*suspend)(struct device *, unsigned int, pm_message_t);
+	int (*resume)(struct device *, unsigned int);
+
+	struct device_driver driver;
+	struct device *devices;
+};
+
+#define to_isa_driver(x) container_of((x), struct isa_driver, driver)
+
+int isa_register_driver(struct isa_driver *, unsigned int);
+void isa_unregister_driver(struct isa_driver *);
+
+#endif /* __LINUX_ISA_H */
diff --git a/include/linux/isdn/Kbuild b/include/linux/isdn/Kbuild
new file mode 100644
index 000000000..991cdb29a
--- /dev/null
+++ b/include/linux/isdn/Kbuild
@@ -0,0 +1 @@
+header-y += capicmd.h
diff --git a/include/linux/license.h b/include/linux/license.h
new file mode 100644
index 000000000..decdbf43c
--- /dev/null
+++ b/include/linux/license.h
@@ -0,0 +1,14 @@
+#ifndef __LICENSE_H
+#define __LICENSE_H
+
+static inline int license_is_gpl_compatible(const char *license)
+{
+	return (strcmp(license, "GPL") == 0
+		|| strcmp(license, "GPL v2") == 0
+		|| strcmp(license, "GPL and additional rights") == 0
+		|| strcmp(license, "Dual BSD/GPL") == 0
+		|| strcmp(license, "Dual MIT/GPL") == 0
+		|| strcmp(license, "Dual MPL/GPL") == 0);
+}
+
+#endif
diff --git a/include/linux/lockdep.h b/include/linux/lockdep.h
new file mode 100644
index 000000000..716787278
--- /dev/null
+++ b/include/linux/lockdep.h
@@ -0,0 +1,357 @@
+/*
+ * Runtime locking correctness validator
+ *
+ *  Copyright (C) 2006 Red Hat, Inc., Ingo Molnar <mingo@redhat.com>
+ *
+ * see Documentation/lockdep-design.txt for more details.
+ */
+#ifndef __LINUX_LOCKDEP_H
+#define __LINUX_LOCKDEP_H
+
+#include <linux/linkage.h>
+#include <linux/list.h>
+#include <linux/debug_locks.h>
+#include <linux/stacktrace.h>
+
+#ifdef CONFIG_LOCKDEP
+
+/*
+ * Lock-class usage-state bits:
+ */
+enum lock_usage_bit
+{
+	LOCK_USED = 0,
+	LOCK_USED_IN_HARDIRQ,
+	LOCK_USED_IN_SOFTIRQ,
+	LOCK_ENABLED_SOFTIRQS,
+	LOCK_ENABLED_HARDIRQS,
+	LOCK_USED_IN_HARDIRQ_READ,
+	LOCK_USED_IN_SOFTIRQ_READ,
+	LOCK_ENABLED_SOFTIRQS_READ,
+	LOCK_ENABLED_HARDIRQS_READ,
+	LOCK_USAGE_STATES
+};
+
+/*
+ * Usage-state bitmasks:
+ */
+#define LOCKF_USED			(1 << LOCK_USED)
+#define LOCKF_USED_IN_HARDIRQ		(1 << LOCK_USED_IN_HARDIRQ)
+#define LOCKF_USED_IN_SOFTIRQ		(1 << LOCK_USED_IN_SOFTIRQ)
+#define LOCKF_ENABLED_HARDIRQS		(1 << LOCK_ENABLED_HARDIRQS)
+#define LOCKF_ENABLED_SOFTIRQS		(1 << LOCK_ENABLED_SOFTIRQS)
+
+#define LOCKF_ENABLED_IRQS (LOCKF_ENABLED_HARDIRQS | LOCKF_ENABLED_SOFTIRQS)
+#define LOCKF_USED_IN_IRQ (LOCKF_USED_IN_HARDIRQ | LOCKF_USED_IN_SOFTIRQ)
+
+#define LOCKF_USED_IN_HARDIRQ_READ	(1 << LOCK_USED_IN_HARDIRQ_READ)
+#define LOCKF_USED_IN_SOFTIRQ_READ	(1 << LOCK_USED_IN_SOFTIRQ_READ)
+#define LOCKF_ENABLED_HARDIRQS_READ	(1 << LOCK_ENABLED_HARDIRQS_READ)
+#define LOCKF_ENABLED_SOFTIRQS_READ	(1 << LOCK_ENABLED_SOFTIRQS_READ)
+
+#define LOCKF_ENABLED_IRQS_READ \
+		(LOCKF_ENABLED_HARDIRQS_READ | LOCKF_ENABLED_SOFTIRQS_READ)
+#define LOCKF_USED_IN_IRQ_READ \
+		(LOCKF_USED_IN_HARDIRQ_READ | LOCKF_USED_IN_SOFTIRQ_READ)
+
+#define MAX_LOCKDEP_SUBCLASSES		8UL
+
+/*
+ * Lock-classes are keyed via unique addresses, by embedding the
+ * lockclass-key into the kernel (or module) .data section. (For
+ * static locks we use the lock address itself as the key.)
+ */
+struct lockdep_subclass_key {
+	char __one_byte;
+} __attribute__ ((__packed__));
+
+struct lock_class_key {
+	struct lockdep_subclass_key	subkeys[MAX_LOCKDEP_SUBCLASSES];
+};
+
+/*
+ * The lock-class itself:
+ */
+struct lock_class {
+	/*
+	 * class-hash:
+	 */
+	struct list_head		hash_entry;
+
+	/*
+	 * global list of all lock-classes:
+	 */
+	struct list_head		lock_entry;
+
+	struct lockdep_subclass_key	*key;
+	unsigned int			subclass;
+
+	/*
+	 * IRQ/softirq usage tracking bits:
+	 */
+	unsigned long			usage_mask;
+	struct stack_trace		usage_traces[LOCK_USAGE_STATES];
+
+	/*
+	 * These fields represent a directed graph of lock dependencies,
+	 * to every node we attach a list of "forward" and a list of
+	 * "backward" graph nodes.
+	 */
+	struct list_head		locks_after, locks_before;
+
+	/*
+	 * Generation counter, when doing certain classes of graph walking,
+	 * to ensure that we check one node only once:
+	 */
+	unsigned int			version;
+
+	/*
+	 * Statistics counter:
+	 */
+	unsigned long			ops;
+
+	const char			*name;
+	int				name_version;
+};
+
+/*
+ * Map the lock object (the lock instance) to the lock-class object.
+ * This is embedded into specific lock instances:
+ */
+struct lockdep_map {
+	struct lock_class_key		*key;
+	struct lock_class		*class_cache;
+	const char			*name;
+};
+
+/*
+ * Every lock has a list of other locks that were taken after it.
+ * We only grow the list, never remove from it:
+ */
+struct lock_list {
+	struct list_head		entry;
+	struct lock_class		*class;
+	struct stack_trace		trace;
+};
+
+/*
+ * We record lock dependency chains, so that we can cache them:
+ */
+struct lock_chain {
+	struct list_head		entry;
+	u64				chain_key;
+};
+
+struct held_lock {
+	/*
+	 * One-way hash of the dependency chain up to this point. We
+	 * hash the hashes step by step as the dependency chain grows.
+	 *
+	 * We use it for dependency-caching and we skip detection
+	 * passes and dependency-updates if there is a cache-hit, so
+	 * it is absolutely critical for 100% coverage of the validator
+	 * to have a unique key value for every unique dependency path
+	 * that can occur in the system, to make a unique hash value
+	 * as likely as possible - hence the 64-bit width.
+	 *
+	 * The task struct holds the current hash value (initialized
+	 * with zero), here we store the previous hash value:
+	 */
+	u64				prev_chain_key;
+	struct lock_class		*class;
+	unsigned long			acquire_ip;
+	struct lockdep_map		*instance;
+
+	/*
+	 * The lock-stack is unified in that the lock chains of interrupt
+	 * contexts nest ontop of process context chains, but we 'separate'
+	 * the hashes by starting with 0 if we cross into an interrupt
+	 * context, and we also keep do not add cross-context lock
+	 * dependencies - the lock usage graph walking covers that area
+	 * anyway, and we'd just unnecessarily increase the number of
+	 * dependencies otherwise. [Note: hardirq and softirq contexts
+	 * are separated from each other too.]
+	 *
+	 * The following field is used to detect when we cross into an
+	 * interrupt context:
+	 */
+	int				irq_context;
+	int				trylock;
+	int				read;
+	int				check;
+	int				hardirqs_off;
+};
+
+/*
+ * Initialization, self-test and debugging-output methods:
+ */
+extern void lockdep_init(void);
+extern void lockdep_info(void);
+extern void lockdep_reset(void);
+extern void lockdep_reset_lock(struct lockdep_map *lock);
+extern void lockdep_free_key_range(void *start, unsigned long size);
+
+extern void lockdep_off(void);
+extern void lockdep_on(void);
+extern int lockdep_internal(void);
+
+/*
+ * These methods are used by specific locking variants (spinlocks,
+ * rwlocks, mutexes and rwsems) to pass init/acquire/release events
+ * to lockdep:
+ */
+
+extern void lockdep_init_map(struct lockdep_map *lock, const char *name,
+			     struct lock_class_key *key, int subclass);
+
+/*
+ * Reinitialize a lock key - for cases where there is special locking or
+ * special initialization of locks so that the validator gets the scope
+ * of dependencies wrong: they are either too broad (they need a class-split)
+ * or they are too narrow (they suffer from a false class-split):
+ */
+#define lockdep_set_class(lock, key) \
+		lockdep_init_map(&(lock)->dep_map, #key, key, 0)
+#define lockdep_set_class_and_name(lock, key, name) \
+		lockdep_init_map(&(lock)->dep_map, name, key, 0)
+#define lockdep_set_class_and_subclass(lock, key, sub) \
+		lockdep_init_map(&(lock)->dep_map, #key, key, sub)
+
+/*
+ * Acquire a lock.
+ *
+ * Values for "read":
+ *
+ *   0: exclusive (write) acquire
+ *   1: read-acquire (no recursion allowed)
+ *   2: read-acquire with same-instance recursion allowed
+ *
+ * Values for check:
+ *
+ *   0: disabled
+ *   1: simple checks (freeing, held-at-exit-time, etc.)
+ *   2: full validation
+ */
+extern void lock_acquire(struct lockdep_map *lock, unsigned int subclass,
+			 int trylock, int read, int check, unsigned long ip);
+
+extern void lock_release(struct lockdep_map *lock, int nested,
+			 unsigned long ip);
+
+# define INIT_LOCKDEP				.lockdep_recursion = 0,
+
+#else /* !LOCKDEP */
+
+static inline void lockdep_off(void)
+{
+}
+
+static inline void lockdep_on(void)
+{
+}
+
+static inline int lockdep_internal(void)
+{
+	return 0;
+}
+
+# define lock_acquire(l, s, t, r, c, i)		do { } while (0)
+# define lock_release(l, n, i)			do { } while (0)
+# define lockdep_init()				do { } while (0)
+# define lockdep_info()				do { } while (0)
+# define lockdep_init_map(lock, name, key, sub)	do { (void)(key); } while (0)
+# define lockdep_set_class(lock, key)		do { (void)(key); } while (0)
+# define lockdep_set_class_and_name(lock, key, name) \
+		do { (void)(key); } while (0)
+#define lockdep_set_class_and_subclass(lock, key, sub) \
+		do { (void)(key); } while (0)
+# define INIT_LOCKDEP
+# define lockdep_reset()		do { debug_locks = 1; } while (0)
+# define lockdep_free_key_range(start, size)	do { } while (0)
+/*
+ * The class key takes no space if lockdep is disabled:
+ */
+struct lock_class_key { };
+#endif /* !LOCKDEP */
+
+#if defined(CONFIG_TRACE_IRQFLAGS) && defined(CONFIG_GENERIC_HARDIRQS)
+extern void early_init_irq_lock_class(void);
+#else
+# define early_init_irq_lock_class()		do { } while (0)
+#endif
+
+#ifdef CONFIG_TRACE_IRQFLAGS
+extern void early_boot_irqs_off(void);
+extern void early_boot_irqs_on(void);
+#else
+# define early_boot_irqs_off()			do { } while (0)
+# define early_boot_irqs_on()			do { } while (0)
+#endif
+
+/*
+ * For trivial one-depth nesting of a lock-class, the following
+ * global define can be used. (Subsystems with multiple levels
+ * of nesting should define their own lock-nesting subclasses.)
+ */
+#define SINGLE_DEPTH_NESTING			1
+
+/*
+ * Map the dependency ops to NOP or to real lockdep ops, depending
+ * on the per lock-class debug mode:
+ */
+
+#ifdef CONFIG_DEBUG_LOCK_ALLOC
+# ifdef CONFIG_PROVE_LOCKING
+#  define spin_acquire(l, s, t, i)		lock_acquire(l, s, t, 0, 2, i)
+# else
+#  define spin_acquire(l, s, t, i)		lock_acquire(l, s, t, 0, 1, i)
+# endif
+# define spin_release(l, n, i)			lock_release(l, n, i)
+#else
+# define spin_acquire(l, s, t, i)		do { } while (0)
+# define spin_release(l, n, i)			do { } while (0)
+#endif
+
+#ifdef CONFIG_DEBUG_LOCK_ALLOC
+# ifdef CONFIG_PROVE_LOCKING
+#  define rwlock_acquire(l, s, t, i)		lock_acquire(l, s, t, 0, 2, i)
+#  define rwlock_acquire_read(l, s, t, i)	lock_acquire(l, s, t, 2, 2, i)
+# else
+#  define rwlock_acquire(l, s, t, i)		lock_acquire(l, s, t, 0, 1, i)
+#  define rwlock_acquire_read(l, s, t, i)	lock_acquire(l, s, t, 2, 1, i)
+# endif
+# define rwlock_release(l, n, i)		lock_release(l, n, i)
+#else
+# define rwlock_acquire(l, s, t, i)		do { } while (0)
+# define rwlock_acquire_read(l, s, t, i)	do { } while (0)
+# define rwlock_release(l, n, i)		do { } while (0)
+#endif
+
+#ifdef CONFIG_DEBUG_LOCK_ALLOC
+# ifdef CONFIG_PROVE_LOCKING
+#  define mutex_acquire(l, s, t, i)		lock_acquire(l, s, t, 0, 2, i)
+# else
+#  define mutex_acquire(l, s, t, i)		lock_acquire(l, s, t, 0, 1, i)
+# endif
+# define mutex_release(l, n, i)			lock_release(l, n, i)
+#else
+# define mutex_acquire(l, s, t, i)		do { } while (0)
+# define mutex_release(l, n, i)			do { } while (0)
+#endif
+
+#ifdef CONFIG_DEBUG_LOCK_ALLOC
+# ifdef CONFIG_PROVE_LOCKING
+#  define rwsem_acquire(l, s, t, i)		lock_acquire(l, s, t, 0, 2, i)
+#  define rwsem_acquire_read(l, s, t, i)	lock_acquire(l, s, t, 1, 2, i)
+# else
+#  define rwsem_acquire(l, s, t, i)		lock_acquire(l, s, t, 0, 1, i)
+#  define rwsem_acquire_read(l, s, t, i)	lock_acquire(l, s, t, 1, 1, i)
+# endif
+# define rwsem_release(l, n, i)			lock_release(l, n, i)
+#else
+# define rwsem_acquire(l, s, t, i)		do { } while (0)
+# define rwsem_acquire_read(l, s, t, i)		do { } while (0)
+# define rwsem_release(l, n, i)			do { } while (0)
+#endif
+
+#endif /* __LINUX_LOCKDEP_H */
diff --git a/include/linux/m41t00.h b/include/linux/m41t00.h
new file mode 100644
index 000000000..b423360ca
--- /dev/null
+++ b/include/linux/m41t00.h
@@ -0,0 +1,50 @@
+/*
+ * Definitions for the ST M41T00 family of i2c rtc chips.
+ *
+ * Author: Mark A. Greer <mgreer@mvista.com>
+ *
+ * 2005, 2006 (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 _M41T00_H
+#define _M41T00_H
+
+#define	M41T00_DRV_NAME		"m41t00"
+#define	M41T00_I2C_ADDR		0x68
+
+#define	M41T00_TYPE_M41T00	0
+#define	M41T00_TYPE_M41T81	81
+#define	M41T00_TYPE_M41T85	85
+
+struct m41t00_platform_data {
+	u8	type;
+	u8	i2c_addr;
+	u8	sqw_freq;
+};
+
+/* SQW output disabled, this is default value by power on */
+#define M41T00_SQW_DISABLE	(0)
+
+#define M41T00_SQW_32KHZ	(1<<4)		/* 32.768 KHz */
+#define M41T00_SQW_8KHZ		(2<<4)		/* 8.192 KHz */
+#define M41T00_SQW_4KHZ		(3<<4)		/* 4.096 KHz */
+#define M41T00_SQW_2KHZ		(4<<4)		/* 2.048 KHz */
+#define M41T00_SQW_1KHZ		(5<<4)		/* 1.024 KHz */
+#define M41T00_SQW_512HZ	(6<<4)		/* 512 Hz */
+#define M41T00_SQW_256HZ	(7<<4)		/* 256 Hz */
+#define M41T00_SQW_128HZ	(8<<4)		/* 128 Hz */
+#define M41T00_SQW_64HZ		(9<<4)		/* 64 Hz */
+#define M41T00_SQW_32HZ		(10<<4)		/* 32 Hz */
+#define M41T00_SQW_16HZ		(11<<4)		/* 16 Hz */
+#define M41T00_SQW_8HZ		(12<<4)		/* 8 Hz */
+#define M41T00_SQW_4HZ		(13<<4)		/* 4 Hz */
+#define M41T00_SQW_2HZ		(14<<4)		/* 2 Hz */
+#define M41T00_SQW_1HZ		(15<<4)		/* 1 Hz */
+
+extern ulong m41t00_get_rtc_time(void);
+extern int m41t00_set_rtc_time(ulong nowtime);
+
+#endif /* _M41T00_H */
diff --git a/include/linux/mtd/ndfc.h b/include/linux/mtd/ndfc.h
new file mode 100644
index 000000000..d0558a982
--- /dev/null
+++ b/include/linux/mtd/ndfc.h
@@ -0,0 +1,67 @@
+/*
+ *  linux/include/linux/mtd/ndfc.h
+ *
+ *  Copyright (c) 2006 Thomas Gleixner <tglx@linutronix.de>
+ *
+ * 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.
+ *
+ *  Info:
+ *   Contains defines, datastructures for ndfc nand controller
+ *
+ */
+#ifndef __LINUX_MTD_NDFC_H
+#define __LINUX_MTD_NDFC_H
+
+/* NDFC Register definitions */
+#define NDFC_CMD		0x00
+#define NDFC_ALE		0x04
+#define NDFC_DATA		0x08
+#define NDFC_ECC		0x10
+#define NDFC_BCFG0		0x30
+#define NDFC_BCFG1		0x34
+#define NDFC_BCFG2		0x38
+#define NDFC_BCFG3		0x3c
+#define NDFC_CCR		0x40
+#define NDFC_STAT		0x44
+#define NDFC_HWCTL		0x48
+#define NDFC_REVID		0x50
+
+#define NDFC_STAT_IS_READY	0x01000000
+
+#define NDFC_CCR_RESET_CE	0x80000000 /* CE Reset */
+#define NDFC_CCR_RESET_ECC	0x40000000 /* ECC Reset */
+#define NDFC_CCR_RIE		0x20000000 /* Interrupt Enable on Device Rdy */
+#define NDFC_CCR_REN		0x10000000 /* Enable wait for Rdy in LinearR */
+#define NDFC_CCR_ROMEN		0x08000000 /* Enable ROM In LinearR */
+#define NDFC_CCR_ARE		0x04000000 /* Auto-Read Enable */
+#define NDFC_CCR_BS(x)		(((x) & 0x3) << 24) /* Select Bank on CE[x] */
+#define NDFC_CCR_BS_MASK	0x03000000 /* Select Bank */
+#define NDFC_CCR_ARAC0		0x00000000 /* 3 Addr, 1 Col 2 Row 512b page */
+#define NDFC_CCR_ARAC1		0x00001000 /* 4 Addr, 1 Col 3 Row 512b page */
+#define NDFC_CCR_ARAC2		0x00002000 /* 4 Addr, 2 Col 2 Row 2K page */
+#define NDFC_CCR_ARAC3		0x00003000 /* 5 Addr, 2 Col 3 Row 2K page */
+#define NDFC_CCR_ARAC_MASK	0x00003000 /* Auto-Read mode Addr Cycles */
+#define NDFC_CCR_RPG		0x0000C000 /* Auto-Read Page */
+#define NDFC_CCR_EBCC		0x00000004 /* EBC Configuration Completed */
+#define NDFC_CCR_DHC		0x00000002 /* Direct Hardware Control Enable */
+
+#define NDFC_BxCFG_EN		0x80000000 /* Bank Enable */
+#define NDFC_BxCFG_CED		0x40000000 /* nCE Style */
+#define NDFC_BxCFG_SZ_MASK	0x08000000 /* Bank Size */
+#define NDFC_BxCFG_SZ_8BIT	0x00000000 /* 8bit */
+#define NDFC_BxCFG_SZ_16BIT	0x08000000 /* 16bit */
+
+#define NDFC_MAX_BANKS		4
+
+struct ndfc_controller_settings {
+	uint32_t	ccr_settings;
+	uint64_t	ndfc_erpn;
+};
+
+struct ndfc_chip_settings {
+	uint32_t	bank_settings;
+};
+
+#endif
diff --git a/include/linux/netfilter/Kbuild b/include/linux/netfilter/Kbuild
new file mode 100644
index 000000000..9a285cecf
--- /dev/null
+++ b/include/linux/netfilter/Kbuild
@@ -0,0 +1,38 @@
+header-y += nf_conntrack_sctp.h
+header-y += nf_conntrack_tuple_common.h
+header-y += nfnetlink_conntrack.h
+header-y += nfnetlink_log.h
+header-y += nfnetlink_queue.h
+header-y += xt_CLASSIFY.h
+header-y += xt_comment.h
+header-y += xt_connbytes.h
+header-y += xt_connmark.h
+header-y += xt_CONNMARK.h
+header-y += xt_conntrack.h
+header-y += xt_dccp.h
+header-y += xt_esp.h
+header-y += xt_helper.h
+header-y += xt_length.h
+header-y += xt_limit.h
+header-y += xt_mac.h
+header-y += xt_mark.h
+header-y += xt_MARK.h
+header-y += xt_multiport.h
+header-y += xt_NFQUEUE.h
+header-y += xt_pkttype.h
+header-y += xt_policy.h
+header-y += xt_realm.h
+header-y += xt_sctp.h
+header-y += xt_state.h
+header-y += xt_string.h
+header-y += xt_tcpmss.h
+header-y += xt_tcpudp.h
+header-y += xt_SECMARK.h
+header-y += xt_CONNSECMARK.h
+
+unifdef-y += nf_conntrack_common.h
+unifdef-y += nf_conntrack_ftp.h
+unifdef-y += nf_conntrack_tcp.h
+unifdef-y += nfnetlink.h
+unifdef-y += x_tables.h
+unifdef-y += xt_physdev.h
diff --git a/include/linux/netfilter/xt_CONNSECMARK.h b/include/linux/netfilter/xt_CONNSECMARK.h
new file mode 100644
index 000000000..c6bd75469
--- /dev/null
+++ b/include/linux/netfilter/xt_CONNSECMARK.h
@@ -0,0 +1,13 @@
+#ifndef _XT_CONNSECMARK_H_target
+#define _XT_CONNSECMARK_H_target
+
+enum {
+	CONNSECMARK_SAVE = 1,
+	CONNSECMARK_RESTORE,
+};
+
+struct xt_connsecmark_target_info {
+	u_int8_t mode;
+};
+
+#endif /*_XT_CONNSECMARK_H_target */
diff --git a/include/linux/netfilter/xt_SECMARK.h b/include/linux/netfilter/xt_SECMARK.h
new file mode 100644
index 000000000..c53fbffa9
--- /dev/null
+++ b/include/linux/netfilter/xt_SECMARK.h
@@ -0,0 +1,26 @@
+#ifndef _XT_SECMARK_H_target
+#define _XT_SECMARK_H_target
+
+/*
+ * This is intended for use by various security subsystems (but not
+ * at the same time).
+ *
+ * 'mode' refers to the specific security subsystem which the
+ * packets are being marked for.
+ */
+#define SECMARK_MODE_SEL	0x01		/* SELinux */
+#define SECMARK_SELCTX_MAX	256
+
+struct xt_secmark_target_selinux_info {
+	u_int32_t selsid;
+	char selctx[SECMARK_SELCTX_MAX];
+};
+
+struct xt_secmark_target_info {
+	u_int8_t mode;
+	union {
+		struct xt_secmark_target_selinux_info sel;
+	} u;
+};
+
+#endif /*_XT_SECMARK_H_target */
diff --git a/include/linux/netfilter/xt_quota.h b/include/linux/netfilter/xt_quota.h
new file mode 100644
index 000000000..acd7fd77b
--- /dev/null
+++ b/include/linux/netfilter/xt_quota.h
@@ -0,0 +1,16 @@
+#ifndef _XT_QUOTA_H
+#define _XT_QUOTA_H
+
+enum xt_quota_flags {
+	XT_QUOTA_INVERT		= 0x1,
+};
+#define XT_QUOTA_MASK		0x1
+
+struct xt_quota_info {
+	u_int32_t		flags;
+	u_int32_t		pad;
+	aligned_u64		quota;
+	struct xt_quota_info	*master;
+};
+
+#endif /* _XT_QUOTA_H */
diff --git a/include/linux/netfilter/xt_statistic.h b/include/linux/netfilter/xt_statistic.h
new file mode 100644
index 000000000..c344e9916
--- /dev/null
+++ b/include/linux/netfilter/xt_statistic.h
@@ -0,0 +1,32 @@
+#ifndef _XT_STATISTIC_H
+#define _XT_STATISTIC_H
+
+enum xt_statistic_mode {
+	XT_STATISTIC_MODE_RANDOM,
+	XT_STATISTIC_MODE_NTH,
+	__XT_STATISTIC_MODE_MAX
+};
+#define XT_STATISTIC_MODE_MAX (__XT_STATISTIC_MODE_MAX - 1)
+
+enum xt_statistic_flags {
+	XT_STATISTIC_INVERT		= 0x1,
+};
+#define XT_STATISTIC_MASK		0x1
+
+struct xt_statistic_info {
+	u_int16_t			mode;
+	u_int16_t			flags;
+	union {
+		struct {
+			u_int32_t	probability;
+		} random;
+		struct {
+			u_int32_t	every;
+			u_int32_t	packet;
+			u_int32_t	count;
+		} nth;
+	} u;
+	struct xt_statistic_info	*master __attribute__((aligned(8)));
+};
+
+#endif /* _XT_STATISTIC_H */
diff --git a/include/linux/netfilter_arp/Kbuild b/include/linux/netfilter_arp/Kbuild
new file mode 100644
index 000000000..4f13dfcb9
--- /dev/null
+++ b/include/linux/netfilter_arp/Kbuild
@@ -0,0 +1,3 @@
+header-y += arpt_mangle.h
+
+unifdef-y += arp_tables.h
diff --git a/include/linux/netfilter_bridge/Kbuild b/include/linux/netfilter_bridge/Kbuild
new file mode 100644
index 000000000..76ff4c47d
--- /dev/null
+++ b/include/linux/netfilter_bridge/Kbuild
@@ -0,0 +1,17 @@
+header-y += ebt_among.h
+header-y += ebt_arp.h
+header-y += ebt_arpreply.h
+header-y += ebt_ip.h
+header-y += ebt_limit.h
+header-y += ebt_log.h
+header-y += ebt_mark_m.h
+header-y += ebt_mark_t.h
+header-y += ebt_nat.h
+header-y += ebt_pkttype.h
+header-y += ebt_redirect.h
+header-y += ebt_stp.h
+header-y += ebt_ulog.h
+header-y += ebt_vlan.h
+
+unifdef-y += ebtables.h
+unifdef-y += ebt_802_3.h
diff --git a/include/linux/netfilter_ipv4/Kbuild b/include/linux/netfilter_ipv4/Kbuild
new file mode 100644
index 000000000..591c1a809
--- /dev/null
+++ b/include/linux/netfilter_ipv4/Kbuild
@@ -0,0 +1,63 @@
+header-y += ip_conntrack_helper.h
+header-y += ip_conntrack_helper_h323_asn1.h
+header-y += ip_conntrack_helper_h323_types.h
+header-y += ip_conntrack_protocol.h
+header-y += ip_conntrack_sctp.h
+header-y += ip_conntrack_tcp.h
+header-y += ip_conntrack_tftp.h
+header-y += ip_nat_pptp.h
+header-y += ipt_addrtype.h
+header-y += ipt_ah.h
+header-y += ipt_CLASSIFY.h
+header-y += ipt_CLUSTERIP.h
+header-y += ipt_comment.h
+header-y += ipt_connbytes.h
+header-y += ipt_connmark.h
+header-y += ipt_CONNMARK.h
+header-y += ipt_conntrack.h
+header-y += ipt_dccp.h
+header-y += ipt_dscp.h
+header-y += ipt_DSCP.h
+header-y += ipt_ecn.h
+header-y += ipt_ECN.h
+header-y += ipt_esp.h
+header-y += ipt_hashlimit.h
+header-y += ipt_helper.h
+header-y += ipt_iprange.h
+header-y += ipt_length.h
+header-y += ipt_limit.h
+header-y += ipt_LOG.h
+header-y += ipt_mac.h
+header-y += ipt_mark.h
+header-y += ipt_MARK.h
+header-y += ipt_multiport.h
+header-y += ipt_NFQUEUE.h
+header-y += ipt_owner.h
+header-y += ipt_physdev.h
+header-y += ipt_pkttype.h
+header-y += ipt_policy.h
+header-y += ipt_realm.h
+header-y += ipt_recent.h
+header-y += ipt_REJECT.h
+header-y += ipt_SAME.h
+header-y += ipt_sctp.h
+header-y += ipt_state.h
+header-y += ipt_string.h
+header-y += ipt_tcpmss.h
+header-y += ipt_TCPMSS.h
+header-y += ipt_tos.h
+header-y += ipt_TOS.h
+header-y += ipt_ttl.h
+header-y += ipt_TTL.h
+header-y += ipt_ULOG.h
+
+unifdef-y += ip_conntrack.h
+unifdef-y += ip_conntrack_h323.h
+unifdef-y += ip_conntrack_irc.h
+unifdef-y += ip_conntrack_pptp.h
+unifdef-y += ip_conntrack_proto_gre.h
+unifdef-y += ip_conntrack_tuple.h
+unifdef-y += ip_nat.h
+unifdef-y += ip_nat_rule.h
+unifdef-y += ip_queue.h
+unifdef-y += ip_tables.h
diff --git a/include/linux/netfilter_ipv4/ip_conntrack_sip.h b/include/linux/netfilter_ipv4/ip_conntrack_sip.h
new file mode 100644
index 000000000..913dad66c
--- /dev/null
+++ b/include/linux/netfilter_ipv4/ip_conntrack_sip.h
@@ -0,0 +1,44 @@
+#ifndef __IP_CONNTRACK_SIP_H__
+#define __IP_CONNTRACK_SIP_H__
+#ifdef __KERNEL__
+
+#define SIP_PORT	5060
+#define SIP_TIMEOUT	3600
+
+#define POS_VIA		0
+#define POS_CONTACT	1
+#define POS_CONTENT	2
+#define POS_MEDIA	3
+#define POS_OWNER	4
+#define POS_CONNECTION	5
+#define POS_REQ_HEADER	6
+#define POS_SDP_HEADER	7
+
+struct sip_header_nfo {
+	const char	*lname;
+	const char	*sname;
+	const char	*ln_str;
+	size_t		lnlen;
+	size_t		snlen;
+	size_t		ln_strlen;
+	int		(*match_len)(const char *, const char *, int *);
+};
+
+extern unsigned int (*ip_nat_sip_hook)(struct sk_buff **pskb,
+				       enum ip_conntrack_info ctinfo,
+				       struct ip_conntrack *ct,
+				       const char **dptr);
+extern unsigned int (*ip_nat_sdp_hook)(struct sk_buff **pskb,
+				       enum ip_conntrack_info ctinfo,
+				       struct ip_conntrack_expect *exp,
+				       const char *dptr);
+
+extern int ct_sip_get_info(const char *dptr, size_t dlen,
+			   unsigned int *matchoff,
+			   unsigned int *matchlen,
+			   struct sip_header_nfo *hnfo);
+extern int ct_sip_lnlen(const char *line, const char *limit);
+extern const char *ct_sip_search(const char *needle, const char *haystack,
+                                 size_t needle_len, size_t haystack_len);
+#endif /* __KERNEL__ */
+#endif /* __IP_CONNTRACK_SIP_H__ */
diff --git a/include/linux/netfilter_ipv6/Kbuild b/include/linux/netfilter_ipv6/Kbuild
new file mode 100644
index 000000000..9dd978d14
--- /dev/null
+++ b/include/linux/netfilter_ipv6/Kbuild
@@ -0,0 +1,21 @@
+header-y += ip6t_HL.h
+header-y += ip6t_LOG.h
+header-y += ip6t_MARK.h
+header-y += ip6t_REJECT.h
+header-y += ip6t_ah.h
+header-y += ip6t_esp.h
+header-y += ip6t_frag.h
+header-y += ip6t_hl.h
+header-y += ip6t_ipv6header.h
+header-y += ip6t_length.h
+header-y += ip6t_limit.h
+header-y += ip6t_mac.h
+header-y += ip6t_mark.h
+header-y += ip6t_multiport.h
+header-y += ip6t_opts.h
+header-y += ip6t_owner.h
+header-y += ip6t_policy.h
+header-y += ip6t_physdev.h
+header-y += ip6t_rt.h
+
+unifdef-y += ip6_tables.h
diff --git a/include/linux/nfsd/Kbuild b/include/linux/nfsd/Kbuild
new file mode 100644
index 000000000..d9c545580
--- /dev/null
+++ b/include/linux/nfsd/Kbuild
@@ -0,0 +1,7 @@
+unifdef-y += const.h
+unifdef-y += export.h
+unifdef-y += stats.h
+unifdef-y += syscall.h
+unifdef-y += nfsfh.h
+unifdef-y += debug.h
+unifdef-y += auth.h
diff --git a/include/linux/nsc_gpio.h b/include/linux/nsc_gpio.h
new file mode 100644
index 000000000..7da0cf370
--- /dev/null
+++ b/include/linux/nsc_gpio.h
@@ -0,0 +1,40 @@
+/**
+   nsc_gpio.c
+
+   National Semiconductor GPIO common access methods.
+
+   struct nsc_gpio_ops abstracts the low-level access
+   operations for the GPIO units on 2 NSC chip families; the GEODE
+   integrated CPU, and the PC-8736[03456] integrated PC-peripheral
+   chips.
+
+   The GPIO units on these chips have the same pin architecture, but
+   the access methods differ.  Thus, scx200_gpio and pc8736x_gpio
+   implement their own versions of these routines; and use the common
+   file-operations routines implemented in nsc_gpio module.
+
+   Copyright (c) 2005 Jim Cromie <jim.cromie@gmail.com>
+
+   NB: this work was tested on the Geode SC-1100 and PC-87366 chips.
+   NSC sold the GEODE line to AMD, and the PC-8736x line to Winbond.
+*/
+
+struct nsc_gpio_ops {
+	struct module*	owner;
+	u32	(*gpio_config)	(unsigned iminor, u32 mask, u32 bits);
+	void	(*gpio_dump)	(struct nsc_gpio_ops *amp, unsigned iminor);
+	int	(*gpio_get)	(unsigned iminor);
+	void	(*gpio_set)	(unsigned iminor, int state);
+	void	(*gpio_change)	(unsigned iminor);
+	int	(*gpio_current)	(unsigned iminor);
+	struct device*	dev;	/* for dev_dbg() support, set in init  */
+};
+
+extern ssize_t nsc_gpio_write(struct file *file, const char __user *data,
+			      size_t len, loff_t *ppos);
+
+extern ssize_t nsc_gpio_read(struct file *file, char __user *buf,
+			     size_t len, loff_t *ppos);
+
+extern void nsc_gpio_dump(struct nsc_gpio_ops *amp, unsigned index);
+
diff --git a/include/linux/plist.h b/include/linux/plist.h
new file mode 100644
index 000000000..b95818a03
--- /dev/null
+++ b/include/linux/plist.h
@@ -0,0 +1,248 @@
+/*
+ * Descending-priority-sorted double-linked list
+ *
+ * (C) 2002-2003 Intel Corp
+ * Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com>.
+ *
+ * 2001-2005 (c) MontaVista Software, Inc.
+ * Daniel Walker <dwalker@mvista.com>
+ *
+ * (C) 2005 Thomas Gleixner <tglx@linutronix.de>
+ *
+ * Simplifications of the original code by
+ * Oleg Nesterov <oleg@tv-sign.ru>
+ *
+ * Licensed under the FSF's GNU Public License v2 or later.
+ *
+ * Based on simple lists (include/linux/list.h).
+ *
+ * This is a priority-sorted list of nodes; each node has a
+ * priority from INT_MIN (highest) to INT_MAX (lowest).
+ *
+ * Addition is O(K), removal is O(1), change of priority of a node is
+ * O(K) and K is the number of RT priority levels used in the system.
+ * (1 <= K <= 99)
+ *
+ * This list is really a list of lists:
+ *
+ *  - The tier 1 list is the prio_list, different priority nodes.
+ *
+ *  - The tier 2 list is the node_list, serialized nodes.
+ *
+ * Simple ASCII art explanation:
+ *
+ * |HEAD          |
+ * |              |
+ * |prio_list.prev|<------------------------------------|
+ * |prio_list.next|<->|pl|<->|pl|<--------------->|pl|<-|
+ * |10            |   |10|   |21|   |21|   |21|   |40|   (prio)
+ * |              |   |  |   |  |   |  |   |  |   |  |
+ * |              |   |  |   |  |   |  |   |  |   |  |
+ * |node_list.next|<->|nl|<->|nl|<->|nl|<->|nl|<->|nl|<-|
+ * |node_list.prev|<------------------------------------|
+ *
+ * The nodes on the prio_list list are sorted by priority to simplify
+ * the insertion of new nodes. There are no nodes with duplicate
+ * priorites on the list.
+ *
+ * The nodes on the node_list is ordered by priority and can contain
+ * entries which have the same priority. Those entries are ordered
+ * FIFO
+ *
+ * Addition means: look for the prio_list node in the prio_list
+ * for the priority of the node and insert it before the node_list
+ * entry of the next prio_list node. If it is the first node of
+ * that priority, add it to the prio_list in the right position and
+ * insert it into the serialized node_list list
+ *
+ * Removal means remove it from the node_list and remove it from
+ * the prio_list if the node_list list_head is non empty. In case
+ * of removal from the prio_list it must be checked whether other
+ * entries of the same priority are on the list or not. If there
+ * is another entry of the same priority then this entry has to
+ * replace the removed entry on the prio_list. If the entry which
+ * is removed is the only entry of this priority then a simple
+ * remove from both list is sufficient.
+ *
+ * INT_MIN is the highest priority, 0 is the medium highest, INT_MAX
+ * is lowest priority.
+ *
+ * No locking is done, up to the caller.
+ *
+ */
+#ifndef _LINUX_PLIST_H_
+#define _LINUX_PLIST_H_
+
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/spinlock_types.h>
+
+struct plist_head {
+	struct list_head prio_list;
+	struct list_head node_list;
+#ifdef CONFIG_DEBUG_PI_LIST
+	spinlock_t *lock;
+#endif
+};
+
+struct plist_node {
+	int			prio;
+	struct plist_head	plist;
+};
+
+#ifdef CONFIG_DEBUG_PI_LIST
+# define PLIST_HEAD_LOCK_INIT(_lock)	.lock = _lock
+#else
+# define PLIST_HEAD_LOCK_INIT(_lock)
+#endif
+
+/**
+ * #PLIST_HEAD_INIT - static struct plist_head initializer
+ *
+ * @head:	struct plist_head variable name
+ */
+#define PLIST_HEAD_INIT(head, _lock)			\
+{							\
+	.prio_list = LIST_HEAD_INIT((head).prio_list),	\
+	.node_list = LIST_HEAD_INIT((head).node_list),	\
+	PLIST_HEAD_LOCK_INIT(&(_lock))			\
+}
+
+/**
+ * #PLIST_NODE_INIT - static struct plist_node initializer
+ *
+ * @node:	struct plist_node variable name
+ * @__prio:	initial node priority
+ */
+#define PLIST_NODE_INIT(node, __prio)			\
+{							\
+	.prio  = (__prio),				\
+	.plist = PLIST_HEAD_INIT((node).plist, NULL),	\
+}
+
+/**
+ * plist_head_init - dynamic struct plist_head initializer
+ *
+ * @head:	&struct plist_head pointer
+ */
+static inline void
+plist_head_init(struct plist_head *head, spinlock_t *lock)
+{
+	INIT_LIST_HEAD(&head->prio_list);
+	INIT_LIST_HEAD(&head->node_list);
+#ifdef CONFIG_DEBUG_PI_LIST
+	head->lock = lock;
+#endif
+}
+
+/**
+ * plist_node_init - Dynamic struct plist_node initializer
+ *
+ * @node:	&struct plist_node pointer
+ * @prio:	initial node priority
+ */
+static inline void plist_node_init(struct plist_node *node, int prio)
+{
+	node->prio = prio;
+	plist_head_init(&node->plist, NULL);
+}
+
+extern void plist_add(struct plist_node *node, struct plist_head *head);
+extern void plist_del(struct plist_node *node, struct plist_head *head);
+
+/**
+ * plist_for_each - iterate over the plist
+ *
+ * @pos1:	the type * to use as a loop counter.
+ * @head:	the head for your list.
+ */
+#define plist_for_each(pos, head)	\
+	 list_for_each_entry(pos, &(head)->node_list, plist.node_list)
+
+/**
+ * plist_for_each_entry_safe - iterate over a plist of given type safe
+ * against removal of list entry
+ *
+ * @pos1:	the type * to use as a loop counter.
+ * @n1:	another type * to use as temporary storage
+ * @head:	the head for your list.
+ */
+#define plist_for_each_safe(pos, n, head)	\
+	 list_for_each_entry_safe(pos, n, &(head)->node_list, plist.node_list)
+
+/**
+ * plist_for_each_entry	- iterate over list of given type
+ *
+ * @pos:	the type * to use as a loop counter.
+ * @head:	the head for your list.
+ * @member:	the name of the list_struct within the struct.
+ */
+#define plist_for_each_entry(pos, head, mem)	\
+	 list_for_each_entry(pos, &(head)->node_list, mem.plist.node_list)
+
+/**
+ * plist_for_each_entry_safe - iterate over list of given type safe against
+ * removal of list entry
+ *
+ * @pos:	the type * to use as a loop counter.
+ * @n:		another type * to use as temporary storage
+ * @head:	the head for your list.
+ * @m:		the name of the list_struct within the struct.
+ */
+#define plist_for_each_entry_safe(pos, n, head, m)	\
+	list_for_each_entry_safe(pos, n, &(head)->node_list, m.plist.node_list)
+
+/**
+ * plist_head_empty - return !0 if a plist_head is empty
+ *
+ * @head:	&struct plist_head pointer
+ */
+static inline int plist_head_empty(const struct plist_head *head)
+{
+	return list_empty(&head->node_list);
+}
+
+/**
+ * plist_node_empty - return !0 if plist_node is not on a list
+ *
+ * @node:	&struct plist_node pointer
+ */
+static inline int plist_node_empty(const struct plist_node *node)
+{
+	return plist_head_empty(&node->plist);
+}
+
+/* All functions below assume the plist_head is not empty. */
+
+/**
+ * plist_first_entry - get the struct for the first entry
+ *
+ * @ptr:	the &struct plist_head pointer.
+ * @type:	the type of the struct this is embedded in.
+ * @member:	the name of the list_struct within the struct.
+ */
+#ifdef CONFIG_DEBUG_PI_LIST
+# define plist_first_entry(head, type, member)	\
+({ \
+	WARN_ON(plist_head_empty(head)); \
+	container_of(plist_first(head), type, member); \
+})
+#else
+# define plist_first_entry(head, type, member)	\
+	container_of(plist_first(head), type, member)
+#endif
+
+/**
+ * plist_first - return the first node (and thus, highest priority)
+ *
+ * @head:	the &struct plist_head pointer
+ *
+ * Assumes the plist is _not_ empty.
+ */
+static inline struct plist_node* plist_first(const struct plist_head *head)
+{
+	return list_entry(head->node_list.next,
+			  struct plist_node, plist.node_list);
+}
+
+#endif
diff --git a/include/linux/poison.h b/include/linux/poison.h
new file mode 100644
index 000000000..3e628f990
--- /dev/null
+++ b/include/linux/poison.h
@@ -0,0 +1,63 @@
+#ifndef _LINUX_POISON_H
+#define _LINUX_POISON_H
+
+/********** include/linux/list.h **********/
+/*
+ * These are non-NULL pointers that will result in page faults
+ * under normal circumstances, used to verify that nobody uses
+ * non-initialized list entries.
+ */
+#define LIST_POISON1  ((void *) 0x00100100)
+#define LIST_POISON2  ((void *) 0x00200200)
+
+/********** mm/slab.c **********/
+/*
+ * Magic nums for obj red zoning.
+ * Placed in the first word before and the first word after an obj.
+ */
+#define	RED_INACTIVE	0x5A2CF071UL	/* when obj is inactive */
+#define	RED_ACTIVE	0x170FC2A5UL	/* when obj is active */
+
+/* ...and for poisoning */
+#define	POISON_INUSE	0x5a	/* for use-uninitialised poisoning */
+#define POISON_FREE	0x6b	/* for use-after-free poisoning */
+#define	POISON_END	0xa5	/* end-byte of poisoning */
+
+/********** arch/$ARCH/mm/init.c **********/
+#define POISON_FREE_INITMEM	0xcc
+
+/********** arch/x86_64/mm/init.c **********/
+#define	POISON_FREE_INITDATA	0xba
+
+/********** arch/ia64/hp/common/sba_iommu.c **********/
+/*
+ * arch/ia64/hp/common/sba_iommu.c uses a 16-byte poison string with a
+ * value of "SBAIOMMU POISON\0" for spill-over poisoning.
+ */
+
+/********** fs/jbd/journal.c **********/
+#define JBD_POISON_FREE	0x5b
+
+/********** drivers/base/dmapool.c **********/
+#define	POOL_POISON_FREED	0xa7	/* !inuse */
+#define	POOL_POISON_ALLOCATED	0xa9	/* !initted */
+
+/********** drivers/atm/ **********/
+#define ATM_POISON_FREE		0x12
+#define ATM_POISON		0xdeadbeef
+
+/********** net/ **********/
+#define NEIGHBOR_DEAD		0xdeadbeef
+#define NETFILTER_LINK_POISON	0xdead57ac
+
+/********** kernel/mutexes **********/
+#define MUTEX_DEBUG_INIT	0x11
+#define MUTEX_DEBUG_FREE	0x22
+
+/********** security/ **********/
+#define KEY_DESTROY		0xbd
+
+/********** sound/oss/ **********/
+#define OSS_POISON_FREE		0xAB
+
+#endif
diff --git a/include/linux/raid/Kbuild b/include/linux/raid/Kbuild
new file mode 100644
index 000000000..2415a64c5
--- /dev/null
+++ b/include/linux/raid/Kbuild
@@ -0,0 +1,2 @@
+header-y += md_p.h
+header-y += md_u.h
diff --git a/include/linux/resume-trace.h b/include/linux/resume-trace.h
new file mode 100644
index 000000000..a376bd4ad
--- /dev/null
+++ b/include/linux/resume-trace.h
@@ -0,0 +1,30 @@
+#ifndef RESUME_TRACE_H
+#define RESUME_TRACE_H
+
+#ifdef CONFIG_PM_TRACE
+
+struct device;
+extern void set_trace_device(struct device *);
+extern void generate_resume_trace(void *tracedata, unsigned int user);
+
+#define TRACE_DEVICE(dev) set_trace_device(dev)
+#define TRACE_RESUME(user) do {				\
+	void *tracedata;				\
+	asm volatile("movl $1f,%0\n"			\
+		".section .tracedata,\"a\"\n"		\
+		"1:\t.word %c1\n"			\
+		"\t.long %c2\n"				\
+		".previous"				\
+		:"=r" (tracedata)			\
+		: "i" (__LINE__), "i" (__FILE__));	\
+	generate_resume_trace(tracedata, user);		\
+} while (0)
+
+#else
+
+#define TRACE_DEVICE(dev) do { } while (0)
+#define TRACE_RESUME(dev) do { } while (0)
+
+#endif
+
+#endif
diff --git a/include/linux/rtc-v3020.h b/include/linux/rtc-v3020.h
new file mode 100644
index 000000000..bf74e63c9
--- /dev/null
+++ b/include/linux/rtc-v3020.h
@@ -0,0 +1,35 @@
+/*
+ * v3020.h - Registers definition and platform data structure for the v3020 RTC.
+ *
+ * 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, 8D Technologies inc.
+ */
+#ifndef __LINUX_V3020_H
+#define __LINUX_V3020_H
+
+/* The v3020 has only one data pin but which one
+ * is used depends on the board. */
+struct v3020_platform_data {
+	int leftshift; /* (1<<(leftshift)) & readl() */
+};
+
+#define V3020_STATUS_0	0x00
+#define V3020_STATUS_1	0x01
+#define V3020_SECONDS	0x02
+#define V3020_MINUTES	0x03
+#define V3020_HOURS		0x04
+#define V3020_MONTH_DAY	0x05
+#define V3020_MONTH		0x06
+#define V3020_YEAR		0x07
+#define V3020_WEEK_DAY	0x08
+#define V3020_WEEK		0x09
+
+#define V3020_IS_COMMAND(val) ((val)>=0x0E)
+
+#define V3020_CMD_RAM2CLOCK	0x0E
+#define V3020_CMD_CLOCK2RAM	0x0F
+
+#endif /* __LINUX_V3020_H */
diff --git a/include/linux/rtmutex.h b/include/linux/rtmutex.h
new file mode 100644
index 000000000..5d41dee82
--- /dev/null
+++ b/include/linux/rtmutex.h
@@ -0,0 +1,107 @@
+/*
+ * RT Mutexes: blocking mutual exclusion locks with PI support
+ *
+ * started by Ingo Molnar and Thomas Gleixner:
+ *
+ *  Copyright (C) 2004-2006 Red Hat, Inc., Ingo Molnar <mingo@redhat.com>
+ *  Copyright (C) 2006, Timesys Corp., Thomas Gleixner <tglx@timesys.com>
+ *
+ * This file contains the public data structure and API definitions.
+ */
+
+#ifndef __LINUX_RT_MUTEX_H
+#define __LINUX_RT_MUTEX_H
+
+#include <linux/linkage.h>
+#include <linux/plist.h>
+#include <linux/spinlock_types.h>
+
+/*
+ * The rt_mutex structure
+ *
+ * @wait_lock:	spinlock to protect the structure
+ * @wait_list:	pilist head to enqueue waiters in priority order
+ * @owner:	the mutex owner
+ */
+struct rt_mutex {
+	spinlock_t		wait_lock;
+	struct plist_head	wait_list;
+	struct task_struct	*owner;
+#ifdef CONFIG_DEBUG_RT_MUTEXES
+	int			save_state;
+	const char 		*name, *file;
+	int			line;
+	void			*magic;
+#endif
+};
+
+struct rt_mutex_waiter;
+struct hrtimer_sleeper;
+
+#ifdef CONFIG_DEBUG_RT_MUTEXES
+ extern int rt_mutex_debug_check_no_locks_freed(const void *from,
+						unsigned long len);
+ extern void rt_mutex_debug_check_no_locks_held(struct task_struct *task);
+#else
+ static inline int rt_mutex_debug_check_no_locks_freed(const void *from,
+						       unsigned long len)
+ {
+	return 0;
+ }
+# define rt_mutex_debug_check_no_locks_held(task)	do { } while (0)
+#endif
+
+#ifdef CONFIG_DEBUG_RT_MUTEXES
+# define __DEBUG_RT_MUTEX_INITIALIZER(mutexname) \
+	, .name = #mutexname, .file = __FILE__, .line = __LINE__
+# define rt_mutex_init(mutex)			__rt_mutex_init(mutex, __FUNCTION__)
+ extern void rt_mutex_debug_task_free(struct task_struct *tsk);
+#else
+# define __DEBUG_RT_MUTEX_INITIALIZER(mutexname)
+# define rt_mutex_init(mutex)			__rt_mutex_init(mutex, NULL)
+# define rt_mutex_debug_task_free(t)			do { } while (0)
+#endif
+
+#define __RT_MUTEX_INITIALIZER(mutexname) \
+	{ .wait_lock = SPIN_LOCK_UNLOCKED \
+	, .wait_list = PLIST_HEAD_INIT(mutexname.wait_list, mutexname.wait_lock) \
+	, .owner = NULL \
+	__DEBUG_RT_MUTEX_INITIALIZER(mutexname)}
+
+#define DEFINE_RT_MUTEX(mutexname) \
+	struct rt_mutex mutexname = __RT_MUTEX_INITIALIZER(mutexname)
+
+/***
+ * rt_mutex_is_locked - is the mutex locked
+ * @lock: the mutex to be queried
+ *
+ * Returns 1 if the mutex is locked, 0 if unlocked.
+ */
+static inline int rt_mutex_is_locked(struct rt_mutex *lock)
+{
+	return lock->owner != NULL;
+}
+
+extern void __rt_mutex_init(struct rt_mutex *lock, const char *name);
+extern void rt_mutex_destroy(struct rt_mutex *lock);
+
+extern void rt_mutex_lock(struct rt_mutex *lock);
+extern int rt_mutex_lock_interruptible(struct rt_mutex *lock,
+						int detect_deadlock);
+extern int rt_mutex_timed_lock(struct rt_mutex *lock,
+					struct hrtimer_sleeper *timeout,
+					int detect_deadlock);
+
+extern int rt_mutex_trylock(struct rt_mutex *lock);
+
+extern void rt_mutex_unlock(struct rt_mutex *lock);
+
+#ifdef CONFIG_RT_MUTEXES
+# define INIT_RT_MUTEXES(tsk)						\
+	.pi_waiters	= PLIST_HEAD_INIT(tsk.pi_waiters, tsk.pi_lock),	\
+	INIT_RT_MUTEX_DEBUG(tsk)
+#else
+# define INIT_RT_MUTEXES(tsk)
+#endif
+
+#endif
diff --git a/include/linux/stacktrace.h b/include/linux/stacktrace.h
new file mode 100644
index 000000000..50e2b01e5
--- /dev/null
+++ b/include/linux/stacktrace.h
@@ -0,0 +1,21 @@
+#ifndef __LINUX_STACKTRACE_H
+#define __LINUX_STACKTRACE_H
+
+#ifdef CONFIG_STACKTRACE
+struct stack_trace {
+	unsigned int nr_entries, max_entries;
+	unsigned long *entries;
+	int skip;	/* input argument: How many entries to skip */
+	int all_contexts; /* input argument: if true do than one stack */
+};
+
+extern void save_stack_trace(struct stack_trace *trace,
+			     struct task_struct *task);
+
+extern void print_stack_trace(struct stack_trace *trace, int spaces);
+#else
+# define save_stack_trace(trace, task)			do { } while (0)
+# define print_stack_trace(trace)			do { } while (0)
+#endif
+
+#endif
diff --git a/include/linux/sunrpc/Kbuild b/include/linux/sunrpc/Kbuild
new file mode 100644
index 000000000..fb438f158
--- /dev/null
+++ b/include/linux/sunrpc/Kbuild
@@ -0,0 +1 @@
+unifdef-y += debug.h
diff --git a/include/linux/taskstats.h b/include/linux/taskstats.h
new file mode 100644
index 000000000..f1cb6cddd
--- /dev/null
+++ b/include/linux/taskstats.h
@@ -0,0 +1,137 @@
+/* taskstats.h - exporting per-task statistics
+ *
+ * Copyright (C) Shailabh Nagar, IBM Corp. 2006
+ *           (C) Balbir Singh,   IBM Corp. 2006
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2.1 of the GNU Lesser General Public License
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it would be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef _LINUX_TASKSTATS_H
+#define _LINUX_TASKSTATS_H
+
+/* Format for per-task data returned to userland when
+ *	- a task exits
+ *	- listener requests stats for a task
+ *
+ * The struct is versioned. Newer versions should only add fields to
+ * the bottom of the struct to maintain backward compatibility.
+ *
+ *
+ * To add new fields
+ *	a) bump up TASKSTATS_VERSION
+ *	b) add comment indicating new version number at end of struct
+ *	c) add new fields after version comment; maintain 64-bit alignment
+ */
+
+#define TASKSTATS_VERSION	1
+
+struct taskstats {
+
+	/* Version 1 */
+	__u16	version;
+	__u16	padding[3];	/* Userspace should not interpret the padding
+				 * field which can be replaced by useful
+				 * fields if struct taskstats is extended.
+				 */
+
+	/* Delay accounting fields start
+	 *
+	 * All values, until comment "Delay accounting fields end" are
+	 * available only if delay accounting is enabled, even though the last
+	 * few fields are not delays
+	 *
+	 * xxx_count is the number of delay values recorded
+	 * xxx_delay_total is the corresponding cumulative delay in nanoseconds
+	 *
+	 * xxx_delay_total wraps around to zero on overflow
+	 * xxx_count incremented regardless of overflow
+	 */
+
+	/* Delay waiting for cpu, while runnable
+	 * count, delay_total NOT updated atomically
+	 */
+	__u64	cpu_count;
+	__u64	cpu_delay_total;
+
+	/* Following four fields atomically updated using task->delays->lock */
+
+	/* Delay waiting for synchronous block I/O to complete
+	 * does not account for delays in I/O submission
+	 */
+	__u64	blkio_count;
+	__u64	blkio_delay_total;
+
+	/* Delay waiting for page fault I/O (swap in only) */
+	__u64	swapin_count;
+	__u64	swapin_delay_total;
+
+	/* cpu "wall-clock" running time
+	 * On some architectures, value will adjust for cpu time stolen
+	 * from the kernel in involuntary waits due to virtualization.
+	 * Value is cumulative, in nanoseconds, without a corresponding count
+	 * and wraps around to zero silently on overflow
+	 */
+	__u64	cpu_run_real_total;
+
+	/* cpu "virtual" running time
+	 * Uses time intervals seen by the kernel i.e. no adjustment
+	 * for kernel's involuntary waits due to virtualization.
+	 * Value is cumulative, in nanoseconds, without a corresponding count
+	 * and wraps around to zero silently on overflow
+	 */
+	__u64	cpu_run_virtual_total;
+	/* Delay accounting fields end */
+	/* version 1 ends here */
+};
+
+
+/*
+ * Commands sent from userspace
+ * Not versioned. New commands should only be inserted at the enum's end
+ * prior to __TASKSTATS_CMD_MAX
+ */
+
+enum {
+	TASKSTATS_CMD_UNSPEC = 0,	/* Reserved */
+	TASKSTATS_CMD_GET,		/* user->kernel request/get-response */
+	TASKSTATS_CMD_NEW,		/* kernel->user event */
+	__TASKSTATS_CMD_MAX,
+};
+
+#define TASKSTATS_CMD_MAX (__TASKSTATS_CMD_MAX - 1)
+
+enum {
+	TASKSTATS_TYPE_UNSPEC = 0,	/* Reserved */
+	TASKSTATS_TYPE_PID,		/* Process id */
+	TASKSTATS_TYPE_TGID,		/* Thread group id */
+	TASKSTATS_TYPE_STATS,		/* taskstats structure */
+	TASKSTATS_TYPE_AGGR_PID,	/* contains pid + stats */
+	TASKSTATS_TYPE_AGGR_TGID,	/* contains tgid + stats */
+	__TASKSTATS_TYPE_MAX,
+};
+
+#define TASKSTATS_TYPE_MAX (__TASKSTATS_TYPE_MAX - 1)
+
+enum {
+	TASKSTATS_CMD_ATTR_UNSPEC = 0,
+	TASKSTATS_CMD_ATTR_PID,
+	TASKSTATS_CMD_ATTR_TGID,
+	TASKSTATS_CMD_ATTR_REGISTER_CPUMASK,
+	TASKSTATS_CMD_ATTR_DEREGISTER_CPUMASK,
+	__TASKSTATS_CMD_ATTR_MAX,
+};
+
+#define TASKSTATS_CMD_ATTR_MAX (__TASKSTATS_CMD_ATTR_MAX - 1)
+
+/* NETLINK_GENERIC related info */
+
+#define TASKSTATS_GENL_NAME	"TASKSTATS"
+#define TASKSTATS_GENL_VERSION	0x1
+
+#endif /* _LINUX_TASKSTATS_H */
diff --git a/include/linux/taskstats_kern.h b/include/linux/taskstats_kern.h
new file mode 100644
index 000000000..16894b7ed
--- /dev/null
+++ b/include/linux/taskstats_kern.h
@@ -0,0 +1,89 @@
+/* taskstats_kern.h - kernel header for per-task statistics interface
+ *
+ * Copyright (C) Shailabh Nagar, IBM Corp. 2006
+ *           (C) Balbir Singh,   IBM Corp. 2006
+ */
+
+#ifndef _LINUX_TASKSTATS_KERN_H
+#define _LINUX_TASKSTATS_KERN_H
+
+#include <linux/taskstats.h>
+#include <linux/sched.h>
+#include <net/genetlink.h>
+
+#ifdef CONFIG_TASKSTATS
+extern kmem_cache_t *taskstats_cache;
+extern struct mutex taskstats_exit_mutex;
+
+static inline void taskstats_exit_free(struct taskstats *tidstats)
+{
+	if (tidstats)
+		kmem_cache_free(taskstats_cache, tidstats);
+}
+
+static inline void taskstats_tgid_init(struct signal_struct *sig)
+{
+	spin_lock_init(&sig->stats_lock);
+	sig->stats = NULL;
+}
+
+static inline void taskstats_tgid_alloc(struct signal_struct *sig)
+{
+	struct taskstats *stats;
+	unsigned long flags;
+
+	stats = kmem_cache_zalloc(taskstats_cache, SLAB_KERNEL);
+	if (!stats)
+		return;
+
+	spin_lock_irqsave(&sig->stats_lock, flags);
+	if (!sig->stats) {
+		sig->stats = stats;
+		stats = NULL;
+	}
+	spin_unlock_irqrestore(&sig->stats_lock, flags);
+
+	if (stats)
+		kmem_cache_free(taskstats_cache, stats);
+}
+
+static inline void taskstats_tgid_free(struct signal_struct *sig)
+{
+	struct taskstats *stats = NULL;
+	unsigned long flags;
+
+	spin_lock_irqsave(&sig->stats_lock, flags);
+	if (sig->stats) {
+		stats = sig->stats;
+		sig->stats = NULL;
+	}
+	spin_unlock_irqrestore(&sig->stats_lock, flags);
+	if (stats)
+		kmem_cache_free(taskstats_cache, stats);
+}
+
+extern void taskstats_exit_alloc(struct taskstats **, unsigned int *);
+extern void taskstats_exit_send(struct task_struct *, struct taskstats *, int, unsigned int);
+extern void taskstats_init_early(void);
+extern void taskstats_tgid_alloc(struct signal_struct *);
+#else
+static inline void taskstats_exit_alloc(struct taskstats **ptidstats, unsigned int *mycpu)
+{}
+static inline void taskstats_exit_free(struct taskstats *ptidstats)
+{}
+static inline void taskstats_exit_send(struct task_struct *tsk,
+				       struct taskstats *tidstats,
+				       int group_dead, unsigned int cpu)
+{}
+static inline void taskstats_tgid_init(struct signal_struct *sig)
+{}
+static inline void taskstats_tgid_alloc(struct signal_struct *sig)
+{}
+static inline void taskstats_tgid_free(struct signal_struct *sig)
+{}
+static inline void taskstats_init_early(void)
+{}
+#endif /* CONFIG_TASKSTATS */
+
+#endif
+
diff --git a/include/linux/tc_act/Kbuild b/include/linux/tc_act/Kbuild
new file mode 100644
index 000000000..78dfbac36
--- /dev/null
+++ b/include/linux/tc_act/Kbuild
@@ -0,0 +1,4 @@
+header-y += tc_gact.h
+header-y += tc_ipt.h
+header-y += tc_mirred.h
+header-y += tc_pedit.h
diff --git a/include/linux/tc_ematch/Kbuild b/include/linux/tc_ematch/Kbuild
new file mode 100644
index 000000000..4a58a1c32
--- /dev/null
+++ b/include/linux/tc_ematch/Kbuild
@@ -0,0 +1,4 @@
+header-y += tc_em_cmp.h
+header-y += tc_em_meta.h
+header-y += tc_em_nbyte.h
+header-y += tc_em_text.h
diff --git a/include/linux/tracehook.h b/include/linux/tracehook.h
new file mode 100644
index 000000000..3cadfa5a6
--- /dev/null
+++ b/include/linux/tracehook.h
@@ -0,0 +1,707 @@
+/*
+ * Tracing hooks
+ *
+ * This file defines hook entry points called by core code where
+ * user tracing/debugging support might need to do something.
+ * These entry points are called tracehook_*.  Each hook declared below
+ * has a detailed comment giving the context (locking et al) from
+ * which it is called, and the meaning of its return value (if any).
+ *
+ * We also declare here tracehook_* functions providing access to low-level
+ * interrogation and control of threads.  These functions must be called
+ * on either the current thread or on a quiescent thread.  We say a
+ * thread is "quiescent" if it is in TASK_STOPPED or TASK_TRACED state,
+ * we are guaranteed it will not be woken up and return to user mode, and
+ * we have called wait_task_inactive on it.
+ */
+
+#ifndef _LINUX_TRACEHOOK_H
+#define _LINUX_TRACEHOOK_H	1
+
+#include <linux/sched.h>
+#include <linux/uaccess.h>
+struct linux_binprm;
+struct pt_regs;
+
+
+/*
+ * The machine-specific asm/tracehook.h file is responsible for declaring
+ * the following entry points.  These can be called only on a quiescent thread,
+ * or the current thread when it is about to return to user mode.
+ *
+ * Single-step control.  When enabled, the next instruction or syscall exit
+ * produces a SIGTRAP.  Enabling or disabling redundantly is harmless.
+ *
+ *	void tracehook_enable_single_step(struct task_struct *tsk);
+ *	void tracehook_disable_single_step(struct task_struct *tsk);
+ *	int tracehook_single_step_enabled(struct task_struct *tsk);
+ *
+ * If those calls are defined, #define ARCH_HAS_SINGLE_STEP to nonzero.
+ * Do not #define it if these calls are never available in this kernel config.
+ * If defined, the value of ARCH_HAS_SINGLE_STEP can be constant or variable.
+ * It should evaluate to nonzero if the hardware is able to support
+ * tracehook_enable_single_step.  If it's a variable expression, it
+ * should be one that can be evaluated in modules, i.e. uses exported symbols.
+ *
+ * Block-step control (trap on control transfer), when available.
+ * tracehook_disable_block_step will be called after tracehook_enable_single_step.
+ * When enabled, the next jump, or other control transfer or syscall exit,
+ * produces a SIGTRAP.  Enabling or disabling redundantly is harmless.
+ *
+ *	void tracehook_enable_block_step(struct task_struct *tsk);
+ *	void tracehook_disable_block_step(struct task_struct *tsk);
+ *	int tracehook_block_step_enabled(struct task_struct *tsk);
+ *
+ * If those calls are defined, #define ARCH_HAS_BLOCK_STEP to nonzero.
+ * Do not #define it if these calls are never available in this kernel config.
+ * If defined, the value of ARCH_HAS_BLOCK_STEP can be constant or variable.
+ * It should evaluate to nonzero if the hardware is able to support
+ * tracehook_enable_block_step.  If it's a variable expression, it
+ * should be one that can be evaluated in modules, i.e. uses exported symbols.
+ *
+ * Control system call tracing.  When enabled a syscall entry or exit
+ * produces a call to tracehook_report_syscall, below.
+ *
+ *	void tracehook_enable_syscall_trace(struct task_struct *tsk);
+ *	void tracehook_disable_syscall_trace(struct task_struct *tsk);
+ *
+ * When stopped in tracehook_report_syscall for syscall entry,
+ * abort the syscall so no kernel function is called.
+ * If the register state was not otherwise updated before,
+ * this produces an -ENOSYS error return as for an invalid syscall number.
+ *
+ *	void tracehook_abort_syscall(struct pt_regs *regs);
+ *
+ * Return the regset view (see below) that is native for the given process.
+ * For example, what it would access when it called ptrace.
+ * Throughout the life of the process, this only changes at exec.
+ *
+ *	const struct utrace_regset_view *utrace_native_view(struct task_struct *);
+ *
+ ***/
+
+
+/*
+ * This data structure describes a machine resource we call a register set.
+ * This is part of the state of an individual thread, not necessarily
+ * actual CPU registers per se.  A register set consists of a number of
+ * similar slots, given by ->n.  Each slot is ->size bytes, and aligned to
+ * ->align bytes (which is at least ->size).
+ *
+ * As described above, these entry points can be called on the current
+ * thread or on a quiescent thread.  The pos argument must be aligned
+ * according to ->align; the count argument must be a multiple of ->size.
+ * These functions are not responsible for checking for invalid arguments.
+ *
+ * When there is a natural value to use as an index, ->bias gives the
+ * difference between the natural index and the slot index for the
+ * register set.  For example, x86 GDT segment descriptors form a regset;
+ * the segment selector produces a natural index, but only a subset of
+ * that index space is available as a regset (the TLS slots); subtracting
+ * ->bias from a segment selector index value computes the regset slot.
+ */
+struct utrace_regset {
+	unsigned int n;		/* Number of slots (registers).  */
+	unsigned int size;	/* Size in bytes of a slot (register).  */
+	unsigned int align;	/* Required alignment, in bytes.  */
+	unsigned int bias;	/* Bias from natural indexing.  */
+
+	/*
+	 * Return -ENODEV if not available on the hardware found.
+	 * Return 0 if no interesting state in this thread.
+	 * Return >0 number of ->size units of interesting state.
+	 * Any get call fetching state beyond that number will
+	 * see the default initialization state for this data,
+	 * so a caller that knows that the default state is need
+	 * not copy it all out.
+	 * This call is optional; the pointer is NULL if there
+	 * so no inexpensive check to yield a value < .n.
+	 */
+	int (*active)(struct task_struct *, const struct utrace_regset *);
+
+	/*
+	 * Fetch and store register values.  Return 0 on success; -EIO or
+	 * -ENODEV are usual failure returns.  The pos and count values are
+	 * in bytes, but must be properly aligned.  If kbuf is non-null,
+	 * that buffer is used and ubuf is ignored.  If kbuf is NULL, then
+	 * ubuf gives a userland pointer to access directly, and an -EFAULT
+	 * return value is possible.
+	 */
+	int (*get)(struct task_struct *, const struct utrace_regset *,
+		   unsigned int pos, unsigned int count,
+		   void *kbuf, void __user *ubuf);
+	int (*set)(struct task_struct *, const struct utrace_regset *,
+		   unsigned int pos, unsigned int count,
+		   const void *kbuf, const void __user *ubuf);
+
+	/*
+	 * This call is optional; usually the pointer is NULL.
+	 * When provided, there is some user memory associated
+	 * with this regset's hardware, such as memory backing
+	 * cached register data on register window machines; the
+	 * regset's data controls what user memory is used
+	 * (e.g. via the stack pointer value).
+	 *
+	 * Write register data back to user memory.  If the
+	 * immediate flag is nonzero, it must be written to the
+	 * user memory so uaccess/access_process_vm can see it
+	 * when this call returns; if zero, then it must be
+	 * written back by the time the task completes a context
+	 * switch (as synchronized with wait_task_inactive).
+	 * Return 0 on success or if there was nothing to do,
+	 * -EFAULT for a memory problem (bad stack pointer or
+	 * whatever), or -EIO for a hardware problem.
+	 */
+	int (*writeback)(struct task_struct *, const struct utrace_regset *,
+			 int immediate);
+};
+
+/*
+ * A regset view is a collection of regsets (struct utrace_regset, above).
+ * This describes all the state of a thread that can be seen from a given
+ * architecture/ABI environment.  More than one view might refer to the
+ * same utrace_regset, or more than one regset might refer to the same
+ * machine-specific state in the thread.  For example, a 32-bit thread's
+ * state could be examined from the 32-bit view or from the 64-bit view.
+ * Either method reaches the same thread register state, doing appropriate
+ * widening or truncation.
+ */
+struct utrace_regset_view {
+	const char *name;	/* Identifier, e.g. ELF_PLATFORM string.  */
+
+	const struct utrace_regset *regsets;
+	unsigned int n;
+
+	/*
+	 * EM_* value for which this is the native view, if any.
+	 */
+	u16 e_machine;
+};
+
+
+/*
+ * These two are helpers for writing regset get/set functions in arch code.
+ * Use one or more calls sequentially for each chunk of regset data stored
+ * contiguously in memory.  Call with constants for start_pos and end_pos,
+ * giving the range of byte positions in the regset that data corresponds
+ * to; end_pos can be -1 if this chunk is at the end of the regset layout.
+ * Each call updates the arguments to point past its chunk.
+ */
+
+static inline int
+utrace_regset_copyout(unsigned int *pos, unsigned int *count,
+		      void **kbuf, void __user **ubuf,
+		      const void *data, int start_pos, int end_pos)
+{
+	if (*count == 0)
+		return 0;
+	BUG_ON(*pos < start_pos);
+	if (end_pos < 0 || *pos < end_pos) {
+		unsigned int copy = (end_pos < 0 ? *count
+				     : min(*count, end_pos - *pos));
+		data += *pos - start_pos;
+		if (*kbuf) {
+			memcpy(*kbuf, data, copy);
+			*kbuf += copy;
+		}
+		else if (copy_to_user(*ubuf, data, copy))
+			return -EFAULT;
+		else
+			*ubuf += copy;
+		*pos += copy;
+		*count -= copy;
+	}
+	return 0;
+}
+
+static inline int
+utrace_regset_copyin(unsigned int *pos, unsigned int *count,
+		     const void **kbuf, const void __user **ubuf,
+		     void *data, int start_pos, int end_pos)
+{
+	if (*count == 0)
+		return 0;
+	BUG_ON(*pos < start_pos);
+	if (end_pos < 0 || *pos < end_pos) {
+		unsigned int copy = (end_pos < 0 ? *count
+				     : min(*count, end_pos - *pos));
+		data += *pos - start_pos;
+		if (*kbuf) {
+			memcpy(data, *kbuf, copy);
+			*kbuf += copy;
+		}
+		else if (copy_from_user(data, *ubuf, copy))
+			return -EFAULT;
+		else
+			*ubuf += copy;
+		*pos += copy;
+		*count -= copy;
+	}
+	return 0;
+}
+
+/*
+ * These two parallel the two above, but for portions of a regset layout
+ * that always read as all-zero or for which writes are ignored.
+ */
+static inline int
+utrace_regset_copyout_zero(unsigned int *pos, unsigned int *count,
+			   void **kbuf, void __user **ubuf,
+			   int start_pos, int end_pos)
+{
+	if (*count == 0)
+		return 0;
+	BUG_ON(*pos < start_pos);
+	if (end_pos < 0 || *pos < end_pos) {
+		unsigned int copy = (end_pos < 0 ? *count
+				     : min(*count, end_pos - *pos));
+		if (*kbuf) {
+			memset(*kbuf, 0, copy);
+			*kbuf += copy;
+		}
+		else if (clear_user(*ubuf, copy))
+			return -EFAULT;
+		else
+			*ubuf += copy;
+		*pos += copy;
+		*count -= copy;
+	}
+	return 0;
+}
+
+static inline int
+utrace_regset_copyin_ignore(unsigned int *pos, unsigned int *count,
+			    const void **kbuf, const void __user **ubuf,
+			    int start_pos, int end_pos)
+{
+	if (*count == 0)
+		return 0;
+	BUG_ON(*pos < start_pos);
+	if (end_pos < 0 || *pos < end_pos) {
+		unsigned int copy = (end_pos < 0 ? *count
+				     : min(*count, end_pos - *pos));
+		if (*kbuf)
+			*kbuf += copy;
+		else
+			*ubuf += copy;
+		*pos += copy;
+		*count -= copy;
+	}
+	return 0;
+}
+
+/**/
+
+
+/***
+ ***
+ *** Following are entry points from core code, where the user debugging
+ *** support can affect the normal behavior.  The locking situation is
+ *** described for each call.
+ ***
+ ***/
+
+#ifdef CONFIG_UTRACE
+#include <linux/utrace.h>
+#endif
+
+
+/*
+ * Called in copy_process when setting up the copied task_struct,
+ * with tasklist_lock held for writing.
+ */
+static inline void tracehook_init_task(struct task_struct *child)
+{
+#ifdef CONFIG_UTRACE
+	child->utrace_flags = 0;
+	child->utrace = NULL;
+#endif
+}
+
+/*
+ * Called from release_task, no locks held.
+ * After this, there should be no tracing entanglements.
+ */
+static inline void tracehook_release_task(struct task_struct *p)
+{
+#ifdef CONFIG_UTRACE
+	smp_mb();
+	if (p->utrace != NULL)
+		utrace_release_task(p);
+#endif
+}
+
+/*
+ * Return nonzero to trigger a BUG_ON crash in release_task.
+ * This should verify that there is no tracing-related state
+ * still affecting the task_struct about to be released.
+ * Called with tasklist_lock held for writing.
+ */
+static inline int tracehook_check_released(struct task_struct *p)
+{
+#ifdef CONFIG_UTRACE
+	return unlikely(p->utrace != NULL);
+#endif
+	return 0;
+}
+
+/*
+ * do_notify_parent_cldstop calls this when it's about to generate a SIGCHLD
+ * for a job control stop.  Return nonzero to prevent that signal generation.
+ * Called with tasklist_lock held for reading, sometimes with irqs disabled.
+ */
+static inline int tracehook_notify_cldstop(struct task_struct *tsk,
+					   const siginfo_t *info)
+{
+#ifdef CONFIG_UTRACE
+	if (tsk->utrace_flags & UTRACE_ACTION_NOREAP)
+		return 1;
+#endif
+	return 0;
+}
+
+/*
+ * exit_notify calls this with tasklist_lock held for writing.
+ * Return nonzero to prevent any normal SIGCHLD generation for this
+ * thread's death (i.e. when it is not ignored and its thread group is
+ * empty).  This call must set *noreap to 0, or to 1 to force this thread
+ * to become a zombie when it would normally reap itself.
+ * The *death_cookie is passed to tracehook_report_death (below).
+ */
+static inline int tracehook_notify_death(struct task_struct *tsk,
+					 int *noreap, void **death_cookie)
+{
+	*death_cookie = NULL;
+#ifdef CONFIG_UTRACE
+	*death_cookie = tsk->utrace;
+	if (tsk->utrace_flags & UTRACE_ACTION_NOREAP) {
+		*noreap = 1;
+		return 1;
+	}
+#endif
+	*noreap = 0;
+	return 0;
+}
+
+/*
+ * Return zero iff tracing doesn't care to examine this fatal signal,
+ * so it can short-circuit normal delivery directly to a group exit.
+ * Called with tsk->sighand->siglock held.
+ */
+static inline int tracehook_consider_fatal_signal(struct task_struct *tsk,
+						  int sig)
+{
+#ifdef CONFIG_UTRACE
+	return (tsk->utrace_flags & (UTRACE_EVENT(SIGNAL_TERM)
+				     | UTRACE_EVENT(SIGNAL_CORE)));
+#endif
+	return 0;
+}
+
+/*
+ * Return zero iff tracing doesn't care to examine this ignored signal,
+ * so it can short-circuit normal delivery and never even get queued.
+ * Either the handler is SIG_DFL and sig's default is ignore, or it's SIG_IGN.
+ * Called with tsk->sighand->siglock held.
+ */
+static inline int tracehook_consider_ignored_signal(struct task_struct *tsk,
+						    int sig, void *handler)
+{
+#ifdef CONFIG_UTRACE
+	return (tsk->utrace_flags & UTRACE_EVENT(SIGNAL_IGN));
+#endif
+	return 0;
+}
+
+
+/*
+ * Called with the siglock held when computing tsk's signal_pending flag.
+ * Return nonzero to force the signal_pending flag on, so that
+ * tracehook_induce_signal will be called before the next return to user mode.
+ */
+static inline int tracehook_induce_sigpending(struct task_struct *tsk)
+{
+#ifdef CONFIG_UTRACE
+	return unlikely(tsk->utrace_flags & UTRACE_ACTION_QUIESCE);
+#endif
+	return 0;
+}
+
+/*
+ * Called with the siglock held before dequeuing pending signals.
+ * Return zero to check for a real pending signal normally.
+ * Return -1 after releasing the siglock to repeat the check.
+ * Return a signal number to induce an artifical signal delivery,
+ * setting *info and *return_ka to specify its details and behavior.
+ */
+static inline int tracehook_get_signal(struct task_struct *tsk,
+				       struct pt_regs *regs,
+				       siginfo_t *info,
+				       struct k_sigaction *return_ka)
+{
+#ifdef CONFIG_UTRACE
+	if (unlikely(tsk->utrace_flags))
+		return utrace_get_signal(tsk, regs, info, return_ka);
+#endif
+	return 0;
+}
+
+/*
+ * Called with no locks held when about to stop for job control;
+ * we are already in TASK_STOPPED state, about to call schedule.
+ * Return zero if the normal SIGCHLD should be generated, which
+ * will happen if last_one is true meaning this is the last thread
+ * in the thread group to stop.
+ */
+static inline int tracehook_finish_stop(int last_one)
+{
+#ifdef CONFIG_UTRACE
+	if (current->utrace_flags & UTRACE_EVENT(JCTL))
+		return utrace_report_jctl(CLD_STOPPED);
+#endif
+
+	return 0;
+}
+
+/*
+ * Called with tasklist_lock held for reading, for an event notification stop.
+ * We are already in TASK_TRACED.  Return zero to go back to running,
+ * or nonzero to actually stop until resumed.
+ */
+static inline int tracehook_stop_now(void)
+{
+	return 0;
+}
+
+
+/*
+ * Return nonzero if the child's parent (current) should be prevented
+ * from seeing its child in TASK_STOPPED state when it waits with WSTOPPED.
+ * Called with tasklist_lock held for reading.
+ */
+static inline int tracehook_inhibit_wait_stopped(struct task_struct *child)
+{
+#ifdef CONFIG_UTRACE
+	return (child->utrace_flags & UTRACE_ACTION_NOREAP);
+#endif
+	return 0;
+}
+
+/*
+ * Return nonzero if the child's parent (current) should be prevented
+ * from seeing its child in TASK_ZOMBIE state when it waits with WEXITED.
+ * Called with tasklist_lock held for reading.
+ */
+static inline int tracehook_inhibit_wait_zombie(struct task_struct *child)
+{
+#ifdef CONFIG_UTRACE
+	return (child->utrace_flags & UTRACE_ACTION_NOREAP);
+#endif
+	return 0;
+}
+
+/*
+ * Return nonzero if the child's parent (current) should be prevented
+ * from seeing its child resuming after job stop when it waits with WCONTINUED.
+ * Called with tasklist_lock held for reading.
+ */
+static inline int tracehook_inhibit_wait_continued(struct task_struct *child)
+{
+#ifdef CONFIG_UTRACE
+	return (child->utrace_flags & UTRACE_ACTION_NOREAP);
+#endif
+	return 0;
+}
+
+
+/*
+ * Return LSM_UNSAFE_* bits applied to an exec because of tracing.
+ * Called with task_lock(tsk) held.
+ */
+static inline int tracehook_unsafe_exec(struct task_struct *tsk)
+{
+#ifdef CONFIG_UTRACE
+	if (tsk->utrace_flags)
+		return utrace_unsafe_exec(tsk);
+#endif
+	return 0;
+}
+
+/*
+ * Return the task_struct for the task using ptrace on this one, or NULL.
+ * Must be called with rcu_read_lock held to keep the returned struct alive.
+ *
+ * At exec time, this may be called with task_lock(p) still held from when
+ * tracehook_unsafe_exec was just called.
+ *
+ * The value is also used to display after "TracerPid:" in /proc/PID/status,
+ * where it is called with only rcu_read_lock held.
+ */
+static inline struct task_struct *tracehook_tracer_task(struct task_struct *p)
+{
+#ifdef CONFIG_UTRACE
+	if (p->utrace_flags)
+		return utrace_tracer_task(p);
+#endif
+	return NULL;
+}
+
+/*
+ * Return nonzero if the current task should be allowed to use
+ * access_process_vm on the given task.
+ */
+static inline int tracehook_allow_access_process_vm(struct task_struct *tsk)
+{
+	if (tsk == current)
+		return 1;
+#ifdef CONFIG_UTRACE
+	if (tsk->utrace_flags)
+		return utrace_allow_access_process_vm(tsk);
+#endif
+	return 0;
+}
+
+
+/***
+ ***
+ *** Following decelarations are hook stubs where core code reports
+ *** events.  These are called without locks, from the thread having the
+ *** event.  In all tracehook_report_* calls, no locks are held and the thread
+ *** is in a state close to returning to user mode with little baggage to
+ *** unwind, except as noted below for tracehook_report_clone.  It is generally
+ *** OK to block in these places if you want the user thread to be suspended.
+ ***
+ ***/
+
+/*
+ * Thread has just become a zombie (exit_state==TASK_ZOMBIE) or is about to
+ * self-reap (exit_state==EXIT_DEAD).  If normal reaping is not inhibited,
+ * tsk->exit_state might be changing in parallel.  The death_cookie was
+ * passed back by tracehook_notify_death (above).
+ */
+static inline void tracehook_report_death(struct task_struct *tsk,
+					  int exit_state, void *death_cookie)
+{
+#ifdef CONFIG_UTRACE
+	smp_mb();
+	if (tsk->utrace_flags & (UTRACE_EVENT(DEATH) | UTRACE_ACTION_QUIESCE))
+		utrace_report_death(tsk, death_cookie);
+#endif
+}
+
+/*
+ * exec completed, we are shortly going to return to user mode.
+ * The freshly initialized register state can be seen and changed here.
+ */
+static inline void tracehook_report_exec(struct linux_binprm *bprm,
+				    struct pt_regs *regs)
+{
+#ifdef CONFIG_UTRACE
+	if (current->utrace_flags & UTRACE_EVENT(EXEC))
+		utrace_report_exec(bprm, regs);
+#endif
+}
+
+/*
+ * Called from do_exit, we are about to exit.  The code returned to the
+ * parent for wait can be changed here.
+ */
+static inline void tracehook_report_exit(long *exit_code)
+{
+#ifdef CONFIG_UTRACE
+	if (current->utrace_flags & UTRACE_EVENT(EXIT))
+		utrace_report_exit(exit_code);
+#endif
+}
+
+/*
+ * Called after a child is set up, but before it has been started or
+ * been given its CLONE_STOPPED initial stop.  (See also tracehook_init_task.)
+ * This is not a good place to block, because the child has not started yet.
+ * Suspend the child here if desired, and block in clone_complete (below).
+ * This must prevent the child from self-reaping if clone_complete uses
+ * the task_struct pointer; otherwise it might have died and been released
+ * by the time tracehook_report_clone_complete is called.
+ */
+static inline void tracehook_report_clone(unsigned long clone_flags,
+					  struct task_struct *child)
+{
+#ifdef CONFIG_UTRACE
+	if (current->utrace_flags & UTRACE_EVENT(CLONE))
+		utrace_report_clone(clone_flags, child);
+#endif
+}
+
+/*
+ * Called after the child has started running, shortly after
+ * tracehook_report_clone.  This is just before the clone/fork syscall
+ * returns, or blocks for vfork child completion if (clone_flags &
+ * CLONE_VFORK).  The child pointer may be invalid if a self-reaping
+ * child died and tracehook_report_clone took no action to prevent it
+ * from self-reaping.
+ */
+static inline void tracehook_report_clone_complete(unsigned long clone_flags,
+						   pid_t pid,
+						   struct task_struct *child)
+{
+#ifdef CONFIG_UTRACE
+	if (current->utrace_flags & UTRACE_ACTION_QUIESCE)
+		utrace_quiescent(current);
+#endif
+}
+
+/*
+ * Called after a CLONE_VFORK parent has waited for the child to complete.
+ * The clone/vfork system call will return immediately after this.
+ * The child pointer may be invalid if a self-reaping child died and
+ * tracehook_report_clone took no action to prevent it from self-reaping.
+ */
+static inline void tracehook_report_vfork_done(struct task_struct *child,
+					       pid_t child_pid)
+{
+#ifdef CONFIG_UTRACE
+	if (current->utrace_flags & UTRACE_EVENT(VFORK_DONE))
+		utrace_report_vfork_done(child_pid);
+#endif
+}
+
+/*
+ * Called for system call entry or exit.
+ */
+static inline void tracehook_report_syscall(struct pt_regs *regs, int is_exit)
+{
+#ifdef CONFIG_UTRACE
+	if (current->utrace_flags & (is_exit ? UTRACE_EVENT(SYSCALL_EXIT)
+				     : UTRACE_EVENT(SYSCALL_ENTRY)))
+		utrace_report_syscall(regs, is_exit);
+#endif
+}
+
+/*
+ * Called after system call exit if single/block-stepped into the syscall.
+ */
+static inline void tracehook_report_syscall_step(struct pt_regs *regs)
+{
+}
+
+/*
+ * Called when a signal handler has been set up.
+ * Register and stack state reflects the user handler about to run.
+ * Signal mask changes have already been made.
+ */
+static inline void tracehook_report_handle_signal(int sig,
+						  const struct k_sigaction *ka,
+						  const sigset_t *oldset,
+						  struct pt_regs *regs)
+{
+#ifdef CONFIG_UTRACE
+	struct task_struct *tsk = current;
+	if ((tsk->utrace_flags & UTRACE_EVENT_SIGNAL_ALL)
+	    && (tsk->utrace_flags & (UTRACE_ACTION_SINGLESTEP
+				     | UTRACE_ACTION_BLOCKSTEP)))
+		utrace_signal_handler_singlestep(tsk, regs);
+#endif
+}
+
+
+#endif	/* <linux/tracehook.h> */
diff --git a/include/linux/uaccess.h b/include/linux/uaccess.h
new file mode 100644
index 000000000..391e7ed1e
--- /dev/null
+++ b/include/linux/uaccess.h
@@ -0,0 +1,22 @@
+#ifndef __LINUX_UACCESS_H__
+#define __LINUX_UACCESS_H__
+
+#include <asm/uaccess.h>
+
+#ifndef ARCH_HAS_NOCACHE_UACCESS
+
+static inline unsigned long __copy_from_user_inatomic_nocache(void *to,
+				const void __user *from, unsigned long n)
+{
+	return __copy_from_user_inatomic(to, from, n);
+}
+
+static inline unsigned long __copy_from_user_nocache(void *to,
+				const void __user *from, unsigned long n)
+{
+	return __copy_from_user(to, from, n);
+}
+
+#endif		/* ARCH_HAS_NOCACHE_UACCESS */
+
+#endif		/* __LINUX_UACCESS_H__ */
diff --git a/include/linux/unwind.h b/include/linux/unwind.h
new file mode 100644
index 000000000..73e1751d0
--- /dev/null
+++ b/include/linux/unwind.h
@@ -0,0 +1,125 @@
+#ifndef _LINUX_UNWIND_H
+#define _LINUX_UNWIND_H
+
+/*
+ * Copyright (C) 2002-2006 Novell, Inc.
+ *	Jan Beulich <jbeulich@novell.com>
+ * This code is released under version 2 of the GNU GPL.
+ *
+ * A simple API for unwinding kernel stacks.  This is used for
+ * debugging and error reporting purposes.  The kernel doesn't need
+ * full-blown stack unwinding with all the bells and whistles, so there
+ * is not much point in implementing the full Dwarf2 unwind API.
+ */
+
+struct module;
+
+#ifdef CONFIG_STACK_UNWIND
+
+#include <asm/unwind.h>
+
+#ifndef ARCH_UNWIND_SECTION_NAME
+#define ARCH_UNWIND_SECTION_NAME ".eh_frame"
+#endif
+
+/*
+ * Initialize unwind support.
+ */
+extern void unwind_init(void);
+
+#ifdef CONFIG_MODULES
+
+extern void *unwind_add_table(struct module *,
+                              const void *table_start,
+                              unsigned long table_size);
+
+extern void unwind_remove_table(void *handle, int init_only);
+
+#endif
+
+extern int unwind_init_frame_info(struct unwind_frame_info *,
+                                  struct task_struct *,
+                                  /*const*/ struct pt_regs *);
+
+/*
+ * Prepare to unwind a blocked task.
+ */
+extern int unwind_init_blocked(struct unwind_frame_info *,
+                               struct task_struct *);
+
+/*
+ * Prepare to unwind the currently running thread.
+ */
+extern int unwind_init_running(struct unwind_frame_info *,
+                               asmlinkage int (*callback)(struct unwind_frame_info *,
+                                                          void *arg),
+                               void *arg);
+
+/*
+ * Unwind to previous to frame.  Returns 0 if successful, negative
+ * number in case of an error.
+ */
+extern int unwind(struct unwind_frame_info *);
+
+/*
+ * Unwind until the return pointer is in user-land (or until an error
+ * occurs).  Returns 0 if successful, negative number in case of
+ * error.
+ */
+extern int unwind_to_user(struct unwind_frame_info *);
+
+#else
+
+struct unwind_frame_info {};
+
+static inline void unwind_init(void) {}
+
+#ifdef CONFIG_MODULES
+
+static inline void *unwind_add_table(struct module *mod,
+                                     const void *table_start,
+                                     unsigned long table_size)
+{
+	return NULL;
+}
+
+#endif
+
+static inline void unwind_remove_table(void *handle, int init_only)
+{
+}
+
+static inline int unwind_init_frame_info(struct unwind_frame_info *info,
+                                         struct task_struct *tsk,
+                                         const struct pt_regs *regs)
+{
+	return -ENOSYS;
+}
+
+static inline int unwind_init_blocked(struct unwind_frame_info *info,
+                                      struct task_struct *tsk)
+{
+	return -ENOSYS;
+}
+
+static inline int unwind_init_running(struct unwind_frame_info *info,
+                                      asmlinkage int (*cb)(struct unwind_frame_info *,
+                                                           void *arg),
+                                      void *arg)
+{
+	return -ENOSYS;
+}
+
+static inline int unwind(struct unwind_frame_info *info)
+{
+	return -ENOSYS;
+}
+
+static inline int unwind_to_user(struct unwind_frame_info *info)
+{
+	return -ENOSYS;
+}
+
+#endif
+
+#endif /* _LINUX_UNWIND_H */
diff --git a/include/linux/usb/cdc.h b/include/linux/usb/cdc.h
new file mode 100644
index 000000000..ba617c372
--- /dev/null
+++ b/include/linux/usb/cdc.h
@@ -0,0 +1,205 @@
+/*
+ * USB Communications Device Class (CDC) definitions
+ *
+ * CDC says how to talk to lots of different types of network adapters,
+ * notably ethernet adapters and various modems.  It's used mostly with
+ * firmware based USB peripherals.
+ */
+
+#define USB_CDC_SUBCLASS_ACM			0x02
+#define USB_CDC_SUBCLASS_ETHERNET		0x06
+#define USB_CDC_SUBCLASS_WHCM			0x08
+#define USB_CDC_SUBCLASS_DMM			0x09
+#define USB_CDC_SUBCLASS_MDLM			0x0a
+#define USB_CDC_SUBCLASS_OBEX			0x0b
+
+#define USB_CDC_PROTO_NONE			0
+
+#define USB_CDC_ACM_PROTO_AT_V25TER		1
+#define USB_CDC_ACM_PROTO_AT_PCCA101		2
+#define USB_CDC_ACM_PROTO_AT_PCCA101_WAKE	3
+#define USB_CDC_ACM_PROTO_AT_GSM		4
+#define USB_CDC_ACM_PROTO_AT_3G			5
+#define USB_CDC_ACM_PROTO_AT_CDMA		6
+#define USB_CDC_ACM_PROTO_VENDOR		0xff
+
+/*-------------------------------------------------------------------------*/
+
+/*
+ * Class-Specific descriptors ... there are a couple dozen of them
+ */
+
+#define USB_CDC_HEADER_TYPE		0x00		/* header_desc */
+#define USB_CDC_CALL_MANAGEMENT_TYPE	0x01		/* call_mgmt_descriptor */
+#define USB_CDC_ACM_TYPE		0x02		/* acm_descriptor */
+#define USB_CDC_UNION_TYPE		0x06		/* union_desc */
+#define USB_CDC_COUNTRY_TYPE		0x07
+#define USB_CDC_NETWORK_TERMINAL_TYPE	0x0a		/* network_terminal_desc */
+#define USB_CDC_ETHERNET_TYPE		0x0f		/* ether_desc */
+#define USB_CDC_WHCM_TYPE		0x11
+#define USB_CDC_MDLM_TYPE		0x12		/* mdlm_desc */
+#define USB_CDC_MDLM_DETAIL_TYPE	0x13		/* mdlm_detail_desc */
+#define USB_CDC_DMM_TYPE		0x14
+#define USB_CDC_OBEX_TYPE		0x15
+
+/* "Header Functional Descriptor" from CDC spec  5.2.3.1 */
+struct usb_cdc_header_desc {
+	__u8	bLength;
+	__u8	bDescriptorType;
+	__u8	bDescriptorSubType;
+
+	__le16	bcdCDC;
+} __attribute__ ((packed));
+
+/* "Call Management Descriptor" from CDC spec  5.2.3.2 */
+struct usb_cdc_call_mgmt_descriptor {
+	__u8	bLength;
+	__u8	bDescriptorType;
+	__u8	bDescriptorSubType;
+
+	__u8	bmCapabilities;
+#define USB_CDC_CALL_MGMT_CAP_CALL_MGMT		0x01
+#define USB_CDC_CALL_MGMT_CAP_DATA_INTF		0x02
+
+	__u8	bDataInterface;
+} __attribute__ ((packed));
+
+/* "Abstract Control Management Descriptor" from CDC spec  5.2.3.3 */
+struct usb_cdc_acm_descriptor {
+	__u8	bLength;
+	__u8	bDescriptorType;
+	__u8	bDescriptorSubType;
+
+	__u8	bmCapabilities;
+} __attribute__ ((packed));
+
+/* "Union Functional Descriptor" from CDC spec 5.2.3.8 */
+struct usb_cdc_union_desc {
+	__u8	bLength;
+	__u8	bDescriptorType;
+	__u8	bDescriptorSubType;
+
+	__u8	bMasterInterface0;
+	__u8	bSlaveInterface0;
+	/* ... and there could be other slave interfaces */
+} __attribute__ ((packed));
+
+/* "Network Channel Terminal Functional Descriptor" from CDC spec 5.2.3.11 */
+struct usb_cdc_network_terminal_desc {
+	__u8	bLength;
+	__u8	bDescriptorType;
+	__u8	bDescriptorSubType;
+
+	__u8	bEntityId;
+	__u8	iName;
+	__u8	bChannelIndex;
+	__u8	bPhysicalInterface;
+} __attribute__ ((packed));
+
+/* "Ethernet Networking Functional Descriptor" from CDC spec 5.2.3.16 */
+struct usb_cdc_ether_desc {
+	__u8	bLength;
+	__u8	bDescriptorType;
+	__u8	bDescriptorSubType;
+
+	__u8	iMACAddress;
+	__le32	bmEthernetStatistics;
+	__le16	wMaxSegmentSize;
+	__le16	wNumberMCFilters;
+	__u8	bNumberPowerFilters;
+} __attribute__ ((packed));
+
+/* "MDLM Functional Descriptor" from CDC WMC spec 6.7.2.3 */
+struct usb_cdc_mdlm_desc {
+	__u8	bLength;
+	__u8	bDescriptorType;
+	__u8	bDescriptorSubType;
+
+	__le16	bcdVersion;
+	__u8	bGUID[16];
+} __attribute__ ((packed));
+
+/* "MDLM Detail Functional Descriptor" from CDC WMC spec 6.7.2.4 */
+struct usb_cdc_mdlm_detail_desc {
+	__u8	bLength;
+	__u8	bDescriptorType;
+	__u8	bDescriptorSubType;
+
+	/* type is associated with mdlm_desc.bGUID */
+	__u8	bGuidDescriptorType;
+	__u8	bDetailData[0];
+} __attribute__ ((packed));
+
+/*-------------------------------------------------------------------------*/
+
+/*
+ * Class-Specific Control Requests (6.2)
+ *
+ * section 3.6.2.1 table 4 has the ACM profile, for modems.
+ * section 3.8.2 table 10 has the ethernet profile.
+ *
+ * Microsoft's RNDIS stack for Ethernet is a vendor-specific CDC ACM variant,
+ * heavily dependent on the encapsulated (proprietary) command mechanism.
+ */
+
+#define USB_CDC_SEND_ENCAPSULATED_COMMAND	0x00
+#define USB_CDC_GET_ENCAPSULATED_RESPONSE	0x01
+#define USB_CDC_REQ_SET_LINE_CODING		0x20
+#define USB_CDC_REQ_GET_LINE_CODING		0x21
+#define USB_CDC_REQ_SET_CONTROL_LINE_STATE	0x22
+#define USB_CDC_REQ_SEND_BREAK			0x23
+#define USB_CDC_SET_ETHERNET_MULTICAST_FILTERS	0x40
+#define USB_CDC_SET_ETHERNET_PM_PATTERN_FILTER	0x41
+#define USB_CDC_GET_ETHERNET_PM_PATTERN_FILTER	0x42
+#define USB_CDC_SET_ETHERNET_PACKET_FILTER	0x43
+#define USB_CDC_GET_ETHERNET_STATISTIC		0x44
+
+/* Line Coding Structure from CDC spec 6.2.13 */
+struct usb_cdc_line_coding {
+	__le32	dwDTERate;
+	__u8	bCharFormat;
+#define USB_CDC_1_STOP_BITS			0
+#define USB_CDC_1_5_STOP_BITS			1
+#define USB_CDC_2_STOP_BITS			2
+
+	__u8	bParityType;
+#define USB_CDC_NO_PARITY			0
+#define USB_CDC_ODD_PARITY			1
+#define USB_CDC_EVEN_PARITY			2
+#define USB_CDC_MARK_PARITY			3
+#define USB_CDC_SPACE_PARITY			4
+
+	__u8	bDataBits;
+} __attribute__ ((packed));
+
+/* table 62; bits in multicast filter */
+#define	USB_CDC_PACKET_TYPE_PROMISCUOUS		(1 << 0)
+#define	USB_CDC_PACKET_TYPE_ALL_MULTICAST	(1 << 1) /* no filter */
+#define	USB_CDC_PACKET_TYPE_DIRECTED		(1 << 2)
+#define	USB_CDC_PACKET_TYPE_BROADCAST		(1 << 3)
+#define	USB_CDC_PACKET_TYPE_MULTICAST		(1 << 4) /* filtered */
+
+
+/*-------------------------------------------------------------------------*/
+
+/*
+ * Class-Specific Notifications (6.3) sent by interrupt transfers
+ *
+ * section 3.8.2 table 11 of the CDC spec lists Ethernet notifications
+ * section 3.6.2.1 table 5 specifies ACM notifications, accepted by RNDIS
+ * RNDIS also defines its own bit-incompatible notifications
+ */
+
+#define USB_CDC_NOTIFY_NETWORK_CONNECTION	0x00
+#define USB_CDC_NOTIFY_RESPONSE_AVAILABLE	0x01
+#define USB_CDC_NOTIFY_SERIAL_STATE		0x20
+#define USB_CDC_NOTIFY_SPEED_CHANGE		0x2a
+
+struct usb_cdc_notification {
+	__u8	bmRequestType;
+	__u8	bNotificationType;
+	__le16	wValue;
+	__le16	wIndex;
+	__le16	wLength;
+} __attribute__ ((packed));
+
diff --git a/include/linux/usb/input.h b/include/linux/usb/input.h
new file mode 100644
index 000000000..716e0cc16
--- /dev/null
+++ b/include/linux/usb/input.h
@@ -0,0 +1,25 @@
+#ifndef __USB_INPUT_H
+#define __USB_INPUT_H
+
+/*
+ * Copyright (C) 2005 Dmitry Torokhov
+ *
+ * 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/usb.h>
+#include <linux/input.h>
+#include <asm/byteorder.h>
+
+static inline void
+usb_to_input_id(const struct usb_device *dev, struct input_id *id)
+{
+	id->bustype = BUS_USB;
+	id->vendor = le16_to_cpu(dev->descriptor.idVendor);
+	id->product = le16_to_cpu(dev->descriptor.idProduct);
+	id->version = le16_to_cpu(dev->descriptor.bcdDevice);
+}
+
+#endif
diff --git a/include/linux/usb/isp116x.h b/include/linux/usb/isp116x.h
new file mode 100644
index 000000000..436dd8a2b
--- /dev/null
+++ b/include/linux/usb/isp116x.h
@@ -0,0 +1,29 @@
+
+/*
+ * Board initialization code should put one of these into dev->platform_data
+ * and place the isp116x onto platform_bus.
+ */
+
+struct isp116x_platform_data {
+	/* Enable internal resistors on downstream ports */
+	unsigned sel15Kres:1;
+	/* On-chip overcurrent detection */
+	unsigned oc_enable:1;
+	/* INT output polarity */
+	unsigned int_act_high:1;
+	/* INT edge or level triggered */
+	unsigned int_edge_triggered:1;
+	/* Enable wakeup by devices on usb bus (e.g. wakeup
+	   by attachment/detachment or by device activity
+	   such as moving a mouse). When chosen, this option
+	   prevents stopping internal clock, increasing
+	   thereby power consumption in suspended state. */
+	unsigned remote_wakeup_enable:1;
+	/* Inter-io delay (ns). The chip is picky about access timings; it
+	   expects at least:
+	   150ns delay between consecutive accesses to DATA_REG,
+	   300ns delay between access to ADDR_REG and DATA_REG
+	   OE, WE MUST NOT be changed during these intervals
+	 */
+	void (*delay) (struct device * dev, int delay);
+};
diff --git a/include/linux/usb/serial.h b/include/linux/usb/serial.h
new file mode 100644
index 000000000..91c983eef
--- /dev/null
+++ b/include/linux/usb/serial.h
@@ -0,0 +1,300 @@
+/*
+ * USB Serial Converter stuff
+ *
+ *	Copyright (C) 1999 - 2005
+ *	    Greg Kroah-Hartman (greg@kroah.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; version 2 of the License.
+ *
+ */
+
+
+#ifndef __LINUX_USB_SERIAL_H
+#define __LINUX_USB_SERIAL_H
+
+#include <linux/kref.h>
+#include <linux/mutex.h>
+
+#define SERIAL_TTY_MAJOR	188	/* Nice legal number now */
+#define SERIAL_TTY_MINORS	255	/* loads of devices :) */
+
+#define MAX_NUM_PORTS		8	/* The maximum number of ports one device can grab at once */
+
+/* parity check flag */
+#define RELEVANT_IFLAG(iflag)	(iflag & (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK))
+
+/**
+ * usb_serial_port: structure for the specific ports of a device.
+ * @serial: pointer back to the struct usb_serial owner of this port.
+ * @tty: pointer to the corresponding tty for this port.
+ * @lock: spinlock to grab when updating portions of this structure.
+ * @mutex: mutex used to synchronize serial_open() and serial_close()
+ *	access for this port.
+ * @number: the number of the port (the minor number).
+ * @interrupt_in_buffer: pointer to the interrupt in buffer for this port.
+ * @interrupt_in_urb: pointer to the interrupt in struct urb for this port.
+ * @interrupt_in_endpointAddress: endpoint address for the interrupt in pipe
+ *	for this port.
+ * @interrupt_out_buffer: pointer to the interrupt out buffer for this port.
+ * @interrupt_out_size: the size of the interrupt_out_buffer, in bytes.
+ * @interrupt_out_urb: pointer to the interrupt out struct urb for this port.
+ * @interrupt_out_endpointAddress: endpoint address for the interrupt out pipe
+ * 	for this port.
+ * @bulk_in_buffer: pointer to the bulk in buffer for this port.
+ * @read_urb: pointer to the bulk in struct urb for this port.
+ * @bulk_in_endpointAddress: endpoint address for the bulk in pipe for this
+ *	port.
+ * @bulk_out_buffer: pointer to the bulk out buffer for this port.
+ * @bulk_out_size: the size of the bulk_out_buffer, in bytes.
+ * @write_urb: pointer to the bulk out struct urb for this port.
+ * @bulk_out_endpointAddress: endpoint address for the bulk out pipe for this
+ *	port.
+ * @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.
+ *
+ * This structure is used by the usb-serial core and drivers for the specific
+ * ports of a device.
+ */
+struct usb_serial_port {
+	struct usb_serial *	serial;
+	struct tty_struct *	tty;
+	spinlock_t		lock;
+	struct mutex            mutex;
+	unsigned char		number;
+
+	unsigned char *		interrupt_in_buffer;
+	struct urb *		interrupt_in_urb;
+	__u8			interrupt_in_endpointAddress;
+
+	unsigned char *		interrupt_out_buffer;
+	int			interrupt_out_size;
+	struct urb *		interrupt_out_urb;
+	__u8			interrupt_out_endpointAddress;
+
+	unsigned char *		bulk_in_buffer;
+	int			bulk_in_size;
+	struct urb *		read_urb;
+	__u8			bulk_in_endpointAddress;
+
+	unsigned char *		bulk_out_buffer;
+	int			bulk_out_size;
+	struct urb *		write_urb;
+	int			write_urb_busy;
+	__u8			bulk_out_endpointAddress;
+
+	wait_queue_head_t	write_wait;
+	struct work_struct	work;
+	int			open_count;
+	struct device		dev;
+};
+#define to_usb_serial_port(d) container_of(d, struct usb_serial_port, dev)
+
+/* get and set the port private data pointer helper functions */
+static inline void *usb_get_serial_port_data (struct usb_serial_port *port)
+{
+	return dev_get_drvdata(&port->dev);
+}
+
+static inline void usb_set_serial_port_data (struct usb_serial_port *port, void *data)
+{
+	dev_set_drvdata(&port->dev, data);
+}
+
+/**
+ * usb_serial - structure used by the usb-serial core for a device
+ * @dev: pointer to the struct usb_device for this device
+ * @type: pointer to the struct usb_serial_driver for this device
+ * @interface: pointer to the struct usb_interface for this device
+ * @minor: the starting minor number for this device
+ * @num_ports: the number of ports this device has
+ * @num_interrupt_in: number of interrupt in endpoints we have
+ * @num_interrupt_out: number of interrupt out endpoints we have
+ * @num_bulk_in: number of bulk in endpoints we have
+ * @num_bulk_out: number of bulk out endpoints we have
+ * @port: array of struct usb_serial_port structures for the different ports.
+ * @private: place to put any driver specific information that is needed.  The
+ *	usb-serial driver is required to manage this data, the usb-serial core
+ *	will not touch this.  Use usb_get_serial_data() and
+ *	usb_set_serial_data() to access this.
+ */
+struct usb_serial {
+	struct usb_device *		dev;
+	struct usb_serial_driver *	type;
+	struct usb_interface *		interface;
+	unsigned char			minor;
+	unsigned char			num_ports;
+	unsigned char			num_port_pointers;
+	char				num_interrupt_in;
+	char				num_interrupt_out;
+	char				num_bulk_in;
+	char				num_bulk_out;
+	struct usb_serial_port *	port[MAX_NUM_PORTS];
+	struct kref			kref;
+	void *				private;
+};
+#define to_usb_serial(d) container_of(d, struct usb_serial, kref)
+
+#define NUM_DONT_CARE	(-1)
+
+/* get and set the serial private data pointer helper functions */
+static inline void *usb_get_serial_data (struct usb_serial *serial)
+{
+	return serial->private;
+}
+
+static inline void usb_set_serial_data (struct usb_serial *serial, void *data)
+{
+	serial->private = data;
+}
+
+/**
+ * usb_serial_driver - describes a usb serial driver
+ * @description: pointer to a string that describes this driver.  This string used
+ *	in the syslog messages when a device is inserted or removed.
+ * @id_table: pointer to a list of usb_device_id structures that define all
+ *	of the devices this structure can support.
+ * @num_interrupt_in: the number of interrupt in endpoints this device will
+ *	have.
+ * @num_interrupt_out: the number of interrupt out endpoints this device will
+ *	have.
+ * @num_bulk_in: the number of bulk in endpoints this device will have.
+ * @num_bulk_out: the number of bulk out endpoints this device will have.
+ * @num_ports: the number of different ports this device will have.
+ * @calc_num_ports: pointer to a function to determine how many ports this
+ *	device has dynamically.  It will be called after the probe()
+ *	callback is called, but before attach()
+ * @probe: pointer to the driver's probe function.
+ *	This will be called when the device is inserted into the system,
+ *	but before the device has been fully initialized by the usb_serial
+ *	subsystem.  Use this function to download any firmware to the device,
+ *	or any other early initialization that might be needed.
+ *	Return 0 to continue on with the initialization sequence.  Anything
+ *	else will abort it.
+ * @attach: pointer to the driver's attach function.
+ *	This will be called when the struct usb_serial structure is fully set
+ *	set up.  Do any local initialization of the device, or any private
+ *	memory structure allocation at this point in time.
+ * @shutdown: pointer to the driver's shutdown function.  This will be
+ *	called when the device is removed from the system.
+ *
+ * This structure is defines a USB Serial driver.  It provides all of
+ * the information that the USB serial core code needs.  If the function
+ * pointers are defined, then the USB serial core code will call them when
+ * the corresponding tty port functions are called.  If they are not
+ * called, the generic serial function will be used instead.
+ *
+ * The driver.owner field should be set to the module owner of this driver.
+ * The driver.name field should be set to the name of this driver (remember
+ * it will show up in sysfs, so it needs to be short and to the point.
+ * Useing the module name is a good idea.)
+ */
+struct usb_serial_driver {
+	const char *description;
+	const struct usb_device_id *id_table;
+	char	num_interrupt_in;
+	char	num_interrupt_out;
+	char	num_bulk_in;
+	char	num_bulk_out;
+	char	num_ports;
+
+	struct list_head	driver_list;
+	struct device_driver	driver;
+
+	int (*probe) (struct usb_serial *serial, const struct usb_device_id *id);
+	int (*attach) (struct usb_serial *serial);
+	int (*calc_num_ports) (struct usb_serial *serial);
+
+	void (*shutdown) (struct usb_serial *serial);
+
+	int (*port_probe) (struct usb_serial_port *port);
+	int (*port_remove) (struct usb_serial_port *port);
+
+	/* serial function calls */
+	int  (*open)		(struct usb_serial_port *port, struct file * filp);
+	void (*close)		(struct usb_serial_port *port, struct file * filp);
+	int  (*write)		(struct usb_serial_port *port, const unsigned char *buf, int count);
+	int  (*write_room)	(struct usb_serial_port *port);
+	int  (*ioctl)		(struct usb_serial_port *port, struct file * file, unsigned int cmd, unsigned long arg);
+	void (*set_termios)	(struct usb_serial_port *port, struct termios * old);
+	void (*break_ctl)	(struct usb_serial_port *port, int break_state);
+	int  (*chars_in_buffer)	(struct usb_serial_port *port);
+	void (*throttle)	(struct usb_serial_port *port);
+	void (*unthrottle)	(struct usb_serial_port *port);
+	int  (*tiocmget)	(struct usb_serial_port *port, struct file *file);
+	int  (*tiocmset)	(struct usb_serial_port *port, struct file *file, unsigned int set, unsigned int clear);
+
+	void (*read_int_callback)(struct urb *urb, struct pt_regs *regs);
+	void (*write_int_callback)(struct urb *urb, struct pt_regs *regs);
+	void (*read_bulk_callback)(struct urb *urb, struct pt_regs *regs);
+	void (*write_bulk_callback)(struct urb *urb, struct pt_regs *regs);
+};
+#define to_usb_serial_driver(d) container_of(d, struct usb_serial_driver, driver)
+
+extern int  usb_serial_register(struct usb_serial_driver *driver);
+extern void usb_serial_deregister(struct usb_serial_driver *driver);
+extern void usb_serial_port_softint(struct usb_serial_port *port);
+
+extern int usb_serial_probe(struct usb_interface *iface, const struct usb_device_id *id);
+extern void usb_serial_disconnect(struct usb_interface *iface);
+
+extern int ezusb_writememory (struct usb_serial *serial, int address, unsigned char *data, int length, __u8 bRequest);
+extern int ezusb_set_reset (struct usb_serial *serial, unsigned char reset_bit);
+
+/* USB Serial console functions */
+#ifdef CONFIG_USB_SERIAL_CONSOLE
+extern void usb_serial_console_init (int debug, int minor);
+extern void usb_serial_console_exit (void);
+extern void usb_serial_console_disconnect(struct usb_serial *serial);
+#else
+static inline void usb_serial_console_init (int debug, int minor) { }
+static inline void usb_serial_console_exit (void) { }
+static inline void usb_serial_console_disconnect(struct usb_serial *serial) {}
+#endif
+
+/* Functions needed by other parts of the usbserial core */
+extern struct usb_serial *usb_serial_get_by_index (unsigned int minor);
+extern void usb_serial_put(struct usb_serial *serial);
+extern int usb_serial_generic_open (struct usb_serial_port *port, struct file *filp);
+extern int usb_serial_generic_write (struct usb_serial_port *port, const unsigned char *buf, int count);
+extern void usb_serial_generic_close (struct usb_serial_port *port, struct file *filp);
+extern int usb_serial_generic_write_room (struct usb_serial_port *port);
+extern int usb_serial_generic_chars_in_buffer (struct usb_serial_port *port);
+extern void usb_serial_generic_read_bulk_callback (struct urb *urb, struct pt_regs *regs);
+extern void usb_serial_generic_write_bulk_callback (struct urb *urb, struct pt_regs *regs);
+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);
+
+extern int usb_serial_bus_register (struct usb_serial_driver *device);
+extern void usb_serial_bus_deregister (struct usb_serial_driver *device);
+
+extern struct usb_serial_driver usb_serial_generic_device;
+extern struct bus_type usb_serial_bus_type;
+extern struct tty_driver *usb_serial_tty_driver;
+
+static inline void usb_serial_debug_data(int debug,
+					 struct device *dev,
+					 const char *function, int size,
+					 const unsigned char *data)
+{
+	int i;
+
+	if (debug) {
+		dev_printk(KERN_DEBUG, dev, "%s - length = %d, data = ", function, size);
+		for (i = 0; i < size; ++i)
+			printk ("%.2x ", data[i]);
+		printk ("\n");
+	}
+}
+
+/* Use our own dbg macro */
+#undef dbg
+#define dbg(format, arg...) do { if (debug) printk(KERN_DEBUG "%s: " format "\n" , __FILE__ , ## arg); } while (0)
+
+
+
+#endif	/* ifdef __LINUX_USB_SERIAL_H */
+
diff --git a/include/linux/usb/sl811.h b/include/linux/usb/sl811.h
new file mode 100644
index 000000000..397ee3b3d
--- /dev/null
+++ b/include/linux/usb/sl811.h
@@ -0,0 +1,26 @@
+
+/*
+ * board initialization should put one of these into dev->platform_data
+ * and place the sl811hs onto platform_bus named "sl811-hcd".
+ */
+
+struct sl811_platform_data {
+	unsigned	can_wakeup:1;
+
+	/* given port_power, msec/2 after power on till power good */
+	u8		potpg;
+
+	/* mA/2 power supplied on this port (max = default = 250) */
+	u8		power;
+
+	/* sl811 relies on an external source of VBUS current */
+	void		(*port_power)(struct device *dev, int is_on);
+
+	/* pulse sl811 nRST (probably with a GPIO) */
+	void		(*reset)(struct device *dev);
+
+	// some boards need something like these:
+	// int		(*check_overcurrent)(struct device *dev);
+	// void		(*clock_enable)(struct device *dev, int is_on);
+};
+
diff --git a/include/linux/utrace.h b/include/linux/utrace.h
new file mode 100644
index 000000000..e0f8ae1cd
--- /dev/null
+++ b/include/linux/utrace.h
@@ -0,0 +1,484 @@
+/*
+ * User Debugging Data & Event Rendezvous
+ *
+ * This interface allows for notification of interesting events in a thread.
+ * It also mediates access to thread state such as registers.
+ * Multiple unrelated users can be associated with a single thread.
+ * We call each of these a tracing engine.
+ *
+ * A tracing engine starts by calling utrace_attach on the chosen thread,
+ * passing in a set of hooks (struct utrace_engine_ops), and some associated
+ * data.  This produces a struct utrace_attached_engine, which is the handle
+ * used for all other operations.  An attached engine has its ops vector,
+ * its data, and a flags word controlled by utrace_set_flags.
+ *
+ * Each engine's flags word contains two kinds of flags: events of
+ * interest, and action state flags.
+ *
+ * For each event flag that is set, that engine will get the
+ * appropriate ops->report_* callback when the event occurs.  The
+ * struct utrace_engine_ops need not provide callbacks for an event
+ * unless the engine sets one of the associated event flags.
+ *
+ * Action state flags change the normal behavior of the thread.
+ * These bits are in UTRACE_ACTION_STATE_MASK; these can be OR'd into
+ * flags set with utrace_set_flags.  Also, every callback that return
+ * an action value can reset these bits for the engine (see below).
+ *
+ * The bits UTRACE_ACTION_STATE_MASK of all attached engines are OR'd
+ * together, so each action is in force as long as any engine requests it.
+ * As long as some engine sets the UTRACE_ACTION_QUIESCE flag, the thread
+ * will block and not resume running user code.  When the last engine
+ * clears its UTRACE_ACTION_QUIESCE flag, the thread will resume running.
+ */
+
+#ifndef _LINUX_UTRACE_H
+#define _LINUX_UTRACE_H	1
+
+#include <linux/list.h>
+#include <linux/rcupdate.h>
+#include <linux/signal.h>
+
+struct linux_binprm;
+struct pt_regs;
+struct utrace_regset;
+struct utrace_regset_view;
+
+
+/*
+ * Flags in task_struct.utrace_flags and utrace_attached_engine.flags.
+ * Low four bits are UTRACE_ACTION_STATE_MASK bits (below).
+ * Higher bits are events of interest.
+ */
+
+#define UTRACE_FIRST_EVENT	4
+#define UTRACE_EVENT_BITS	(BITS_PER_LONG - UTRACE_FIRST_EVENT)
+#define UTRACE_EVENT_MASK	(-1UL &~ UTRACE_ACTION_STATE_MASK)
+
+enum utrace_events {
+	_UTRACE_EVENT_QUIESCE,	/* Tracing requests stop.  */
+	_UTRACE_EVENT_REAP,  	/* Zombie reaped, no more tracing possible.  */
+	_UTRACE_EVENT_CLONE,	/* Successful clone/fork/vfork just done.  */
+	_UTRACE_EVENT_VFORK_DONE, /* vfork woke from waiting for child.  */
+	_UTRACE_EVENT_EXEC,	/* Successful execve just completed.  */
+	_UTRACE_EVENT_EXIT,	/* Thread exit in progress.  */
+	_UTRACE_EVENT_DEATH,	/* Thread has died.  */
+	_UTRACE_EVENT_SYSCALL_ENTRY, /* User entered kernel for system call. */
+	_UTRACE_EVENT_SYSCALL_EXIT, /* Returning to user after system call.  */
+	_UTRACE_EVENT_SIGNAL,	/* Signal delivery will run a user handler.  */
+	_UTRACE_EVENT_SIGNAL_IGN, /* No-op signal to be delivered.  */
+	_UTRACE_EVENT_SIGNAL_STOP, /* Signal delivery will suspend.  */
+	_UTRACE_EVENT_SIGNAL_TERM, /* Signal delivery will terminate.  */
+	_UTRACE_EVENT_SIGNAL_CORE, /* Signal delivery will dump core.  */
+	_UTRACE_EVENT_JCTL,	/* Job control stop or continue completed.  */
+	_UTRACE_NEVENTS
+};
+#define UTRACE_EVENT_BIT(type)	(UTRACE_FIRST_EVENT + _UTRACE_EVENT_##type)
+#define UTRACE_EVENT(type)	(1UL << UTRACE_EVENT_BIT(type))
+
+/*
+ * All the kinds of signal events.  These all use the report_signal callback.
+ */
+#define UTRACE_EVENT_SIGNAL_ALL	(UTRACE_EVENT(SIGNAL) \
+				 | UTRACE_EVENT(SIGNAL_IGN) \
+				 | UTRACE_EVENT(SIGNAL_STOP) \
+				 | UTRACE_EVENT(SIGNAL_TERM) \
+				 | UTRACE_EVENT(SIGNAL_CORE))
+/*
+ * Both kinds of syscall events; these call the report_syscall_entry and
+ * report_syscall_exit callbacks, respectively.
+ */
+#define UTRACE_EVENT_SYSCALL	\
+	(UTRACE_EVENT(SYSCALL_ENTRY) | UTRACE_EVENT(SYSCALL_EXIT))
+
+
+/*
+ * Action flags, in return value of callbacks.
+ *
+ * UTRACE_ACTION_RESUME (zero) is the return value to do nothing special.
+ * For each particular callback, some bits in UTRACE_ACTION_OP_MASK can
+ * be set in the return value to change the thread's behavior (see below).
+ *
+ * If UTRACE_ACTION_NEWSTATE is set, then the UTRACE_ACTION_STATE_MASK
+ * bits in the return value replace the engine's flags as in utrace_set_flags
+ * (but the event flags remained unchanged).
+ *
+ * If UTRACE_ACTION_HIDE is set, then the callbacks to other engines
+ * should be suppressed for this event.  This is appropriate only when
+ * the event was artificially provoked by something this engine did,
+ * such as setting a breakpoint.
+ *
+ * If UTRACE_ACTION_DETACH is set, this engine is detached as by utrace_detach.
+ * The action bits in UTRACE_ACTION_OP_MASK work as normal, but the engine's
+ * UTRACE_ACTION_STATE_MASK bits will no longer affect the thread.
+ */
+#define UTRACE_ACTION_RESUME	0x0000 /* Continue normally after event.  */
+#define UTRACE_ACTION_HIDE	0x0010 /* Hide event from other tracing.  */
+#define UTRACE_ACTION_DETACH	0x0020 /* Detach me, state flags ignored.  */
+#define UTRACE_ACTION_NEWSTATE	0x0040 /* Replace state bits.  */
+
+/*
+ * These flags affect the state of the thread until they are changed via
+ * utrace_set_flags or by the next callback to the same engine that uses
+ * UTRACE_ACTION_NEWSTATE.
+ */
+#define UTRACE_ACTION_QUIESCE	0x0001 /* Stay quiescent after callbacks.  */
+#define UTRACE_ACTION_SINGLESTEP 0x0002 /* Resume for one instruction.  */
+#define UTRACE_ACTION_BLOCKSTEP 0x0004 /* Resume until next branch.  */
+#define UTRACE_ACTION_NOREAP	0x0008 /* Inhibit parent SIGCHLD and wait.  */
+#define UTRACE_ACTION_STATE_MASK 0x000f /* Lasting state bits.  */
+
+/* These flags have meanings specific to the particular event report hook.  */
+#define UTRACE_ACTION_OP_MASK	0xff00
+
+/*
+ * Action flags in return value and argument of report_signal callback.
+ */
+#define UTRACE_SIGNAL_DELIVER	0x0100 /* Deliver according to sigaction.  */
+#define UTRACE_SIGNAL_IGN	0x0200 /* Ignore the signal.  */
+#define UTRACE_SIGNAL_TERM	0x0300 /* Terminate the process.  */
+#define UTRACE_SIGNAL_CORE	0x0400 /* Terminate with core dump.  */
+#define UTRACE_SIGNAL_STOP	0x0500 /* Deliver as absolute stop.  */
+#define UTRACE_SIGNAL_TSTP	0x0600 /* Deliver as job control stop.  */
+#define UTRACE_SIGNAL_HOLD	0x1000 /* Flag, push signal back on queue.  */
+/*
+ * This value is passed to a report_signal callback after a signal
+ * handler is entered while UTRACE_ACTION_SINGLESTEP is in force.
+ * For this callback, no signal will never actually be delivered regardless
+ * of the return value, and the other callback parameters are null.
+ */
+#define UTRACE_SIGNAL_HANDLER	0x0700
+
+/* Action flag in return value of report_jctl.  */
+#define UTRACE_JCTL_NOSIGCHLD	0x0100 /* Do not notify the parent.  */
+
+
+/*
+ * Flags for utrace_attach.  If UTRACE_ATTACH_CREATE is not specified,
+ * you only look up an existing engine already attached to the
+ * thread.  If UTRACE_ATTACH_MATCH_* bits are set, only consider
+ * matching engines.  If UTRACE_ATTACH_EXCLUSIVE is set, attempting to
+ * attach a second (matching) engine fails with -EEXIST.
+ */
+#define UTRACE_ATTACH_CREATE		0x0010 /* Attach a new engine.  */
+#define UTRACE_ATTACH_EXCLUSIVE		0x0020 /* Refuse if existing match.  */
+#define UTRACE_ATTACH_MATCH_OPS		0x0001 /* Match engines on ops.  */
+#define UTRACE_ATTACH_MATCH_DATA	0x0002 /* Match engines on data.  */
+#define UTRACE_ATTACH_MATCH_MASK	0x000f
+
+
+/*
+ * Per-thread structure task_struct.utrace points to.
+ *
+ * The task itself never has to worry about this going away after
+ * some event is found set in task_struct.utrace_flags.
+ * Once created, this pointer is changed only when the task is quiescent
+ * (TASK_TRACED or TASK_STOPPED with the siglock held, or dead).
+ *
+ * For other parties, the pointer to this is protected by RCU and
+ * task_lock.  Since call_rcu is never used while the thread is alive and
+ * using this struct utrace, we can overlay the RCU data structure used
+ * only for a dead struct with some local state used only for a live utrace
+ * on an active thread.
+ */
+struct utrace
+{
+	union {
+		struct rcu_head dead;
+		struct {
+			struct task_struct *cloning;
+			struct utrace_signal *signal;
+		} live;
+		struct {
+			int notified;
+			int reap;
+		} exit;
+	} u;
+
+	struct list_head engines;
+	spinlock_t lock;
+};
+#define utrace_lock(utrace)	spin_lock(&(utrace)->lock)
+#define utrace_unlock(utrace)	spin_unlock(&(utrace)->lock)
+
+
+/*
+ * Per-engine per-thread structure.
+ *
+ * The task itself never has to worry about engines detaching while
+ * it's doing event callbacks.  These structures are freed only when
+ * the task is quiescent.  For other parties, the list is protected
+ * by RCU and utrace_lock.
+ */
+struct utrace_attached_engine
+{
+	struct list_head entry;	/* Entry on thread's utrace.engines list.  */
+	struct rcu_head rhead;
+
+	const struct utrace_engine_ops *ops;
+	unsigned long data;
+
+	unsigned long flags;
+};
+
+
+struct utrace_engine_ops
+{
+	/*
+	 * Event reporting hooks.
+	 *
+	 * Return values contain UTRACE_ACTION_* flag bits.
+	 * The UTRACE_ACTION_OP_MASK bits are specific to each kind of event.
+	 *
+	 * All report_* hooks are called with no locks held, in a generally
+	 * safe environment when we will be returning to user mode soon.
+	 * It is fine to block for memory allocation and the like, but all
+	 * hooks are *asynchronous* and must not block on external events.
+	 * If you want the thread to block, request UTRACE_ACTION_QUIESCE in
+	 * your hook; then later wake it up with utrace_set_flags.
+	 *
+	 */
+
+	/*
+	 * Event reported for parent, before child might run.
+	 * The PF_STARTING flag prevents other engines from attaching
+	 * before this one has its chance.
+	 */
+	u32 (*report_clone)(struct utrace_attached_engine *engine,
+			    struct task_struct *parent,
+			    unsigned long clone_flags,
+			    struct task_struct *child);
+
+	/*
+	 * Event reported for parent using CLONE_VFORK or vfork system call.
+	 * The child has died or exec'd, so the vfork parent has unblocked
+	 * and is about to return child_pid.
+	 */
+	u32 (*report_vfork_done)(struct utrace_attached_engine *engine,
+				 struct task_struct *parent, pid_t child_pid);
+
+	/*
+	 * Event reported after UTRACE_ACTION_QUIESCE is set, when the target
+	 * thread is quiescent.  Either it's the current thread, or it's in
+	 * TASK_TRACED or TASK_STOPPED and will not resume running until the
+	 * UTRACE_ACTION_QUIESCE flag is no longer asserted by any engine.
+	 */
+	u32 (*report_quiesce)(struct utrace_attached_engine *engine,
+			      struct task_struct *tsk);
+
+	/*
+	 * Thread dequeuing a signal to be delivered.
+	 * The action and *return_ka values say what UTRACE_ACTION_RESUME
+	 * will do (possibly already influenced by another tracing engine).
+	 * An UTRACE_SIGNAL_* return value overrides the signal disposition.
+	 * The *info data (including info->si_signo) can be changed at will.
+	 * Changing *return_ka affects the sigaction that be used.
+	 * The *orig_ka value is the one in force before other tracing
+	 * engines intervened.
+	 */
+	u32 (*report_signal)(struct utrace_attached_engine *engine,
+			     struct task_struct *tsk,
+			     struct pt_regs *regs,
+			     u32 action, siginfo_t *info,
+			     const struct k_sigaction *orig_ka,
+			     struct k_sigaction *return_ka);
+
+	/*
+	 * Job control event completing, about to send SIGCHLD to parent
+	 * with CLD_STOPPED or CLD_CONTINUED as given in type.
+	 * UTRACE_JOBSTOP_NOSIGCHLD in the return value inhibits that.
+	 */
+	u32 (*report_jctl)(struct utrace_attached_engine *engine,
+			   struct task_struct *tsk,
+			   int type);
+
+	/*
+	 * Thread has just completed an exec.
+	 * The initial user register state is handy to be tweaked directly.
+	 */
+	u32 (*report_exec)(struct utrace_attached_engine *engine,
+			   struct task_struct *tsk,
+			   const struct linux_binprm *bprm,
+			   struct pt_regs *regs);
+
+	/*
+	 * Thread has entered the kernel to request a system call.
+	 * The user register state is handy to be tweaked directly.
+	 */
+	u32 (*report_syscall_entry)(struct utrace_attached_engine *engine,
+				    struct task_struct *tsk,
+				    struct pt_regs *regs);
+
+	/*
+	 * Thread is about to leave the kernel after a system call request.
+	 * The user register state is handy to be tweaked directly.
+	 */
+	u32 (*report_syscall_exit)(struct utrace_attached_engine *engine,
+				   struct task_struct *tsk,
+				   struct pt_regs *regs);
+
+	/*
+	 * Thread is exiting and cannot be prevented from doing so,
+	 * but all its state is still live.  The *code value will be
+	 * the wait result seen by the parent, and can be changed by
+	 * this engine or others.  The orig_code value is the real
+	 * status, not changed by any tracing engine.
+	 */
+	u32 (*report_exit)(struct utrace_attached_engine *engine,
+			   struct task_struct *tsk,
+			   long orig_code, long *code);
+
+	/*
+	 * Thread is really dead now.  If UTRACE_ACTION_NOREAP is in force,
+	 * it remains an unreported zombie.  Otherwise, it might be reaped
+	 * by its parent, or self-reap immediately.  Though the actual
+	 * reaping may happen in parallel, a report_reap callback will
+	 * always be ordered after a report_death callback.
+	 */
+	u32 (*report_death)(struct utrace_attached_engine *engine,
+			    struct task_struct *tsk);
+
+	/*
+	 * Called when someone reaps the dead task (parent, init, or self).
+	 * No more callbacks are made after this one.
+	 * The engine is always detached.
+	 * There is nothing more a tracing engine can do about this thread.
+	 */
+	void (*report_reap)(struct utrace_attached_engine *engine,
+			    struct task_struct *tsk);
+
+	/*
+	 * Miscellaneous hooks.  These are not associated with event reports.
+	 * Any of these may be null if the engine has nothing to say.
+	 * These hooks are called in more constrained environments and should
+	 * not block or do very much.
+	 */
+
+	/*
+	 * Return nonzero iff the caller task should be allowed to access
+	 * the memory of the target task via /proc/PID/mem and so forth,
+	 * by dint of this engine's attachment to the target.
+	 */
+	int (*allow_access_process_vm)(struct utrace_attached_engine *engine,
+				       struct task_struct *target,
+				       struct task_struct *caller);
+
+	/*
+	 * Return LSM_UNSAFE_* bits that apply to the exec in progress
+	 * due to tracing done by this engine.  These bits indicate that
+	 * someone is able to examine the process and so a set-UID or similar
+	 * privilege escalation may not be safe to permit.
+	 *
+	 * Called with task_lock held.
+	 */
+	int (*unsafe_exec)(struct utrace_attached_engine *engine,
+			   struct task_struct *target);
+
+	/*
+	 * Return the task_struct for the task using ptrace on this one, or
+	 * NULL.  Always called with rcu_read_lock held to keep the
+	 * returned struct alive.
+	 *
+	 * At exec time, this may be called with task_lock(target) still
+	 * held from when unsafe_exec was just called.  In that case it
+	 * must give results consistent with those unsafe_exec results,
+	 * i.e. non-NULL if any LSM_UNSAFE_PTRACE_* bits were set.
+	 *
+	 * The value is also used to display after "TracerPid:" in
+	 * /proc/PID/status, where it is called with only rcu_read_lock held.
+	 *
+	 * If this engine returns NULL, another engine may supply the result.
+	 */
+	struct task_struct *(*tracer_task)(struct utrace_attached_engine *,
+					   struct task_struct *target);
+};
+
+
+/***
+ *** These are the exported entry points for tracing engines to use.
+ ***/
+
+/*
+ * Attach a new tracing engine to a thread, or look up attached engines.
+ * See UTRACE_ATTACH_* flags, above.  The caller must ensure that the
+ * target thread does not get freed, i.e. hold a ref or be its parent.
+ */
+struct utrace_attached_engine *utrace_attach(struct task_struct *target,
+					     int flags,
+					     const struct utrace_engine_ops *,
+					     unsigned long data);
+
+/*
+ * Detach a tracing engine from a thread.  After this, the engine
+ * data structure is no longer accessible, and the thread might be reaped.
+ * The thread will start running again if it was being kept quiescent
+ * and no longer has any attached engines asserting UTRACE_ACTION_QUIESCE.
+ *
+ * If the target thread is not already quiescent, then a callback to this
+ * engine might be in progress or about to start on another CPU.  If it's
+ * quiescent when utrace_detach is called, then after return it's guaranteed
+ * that no more callbacks to the ops vector will be done.
+ */
+void utrace_detach(struct task_struct *target,
+		   struct utrace_attached_engine *engine);
+
+/*
+ * Change the flags for a tracing engine.
+ * This resets the event flags and the action state flags.
+ * If UTRACE_ACTION_QUIESCE and UTRACE_EVENT(QUIESCE) are set,
+ * this will cause a report_quiesce callback soon, maybe immediately.
+ * If UTRACE_ACTION_QUIESCE was set before and is no longer set by
+ * any engine, this will wake the thread up.
+ */
+void utrace_set_flags(struct task_struct *target,
+		      struct utrace_attached_engine *engine,
+		      unsigned long flags);
+
+/*
+ * Cause a specified signal delivery in the target thread, which must be
+ * quiescent (or the current thread).  The action has UTRACE_SIGNAL_* bits
+ * as returned from a report_signal callback.  If ka is non-null, it gives
+ * the sigaction to follow for UTRACE_SIGNAL_DELIVER; otherwise, the
+ * installed sigaction at the time of delivery is used.
+ */
+int utrace_inject_signal(struct task_struct *target,
+			 struct utrace_attached_engine *engine,
+			 u32 action, siginfo_t *info,
+			 const struct k_sigaction *ka);
+
+/*
+ * Prepare to access thread's machine state, see <linux/tracehook.h>.
+ * The given thread must be quiescent (or the current thread).
+ * When this returns, the struct utrace_regset calls may be used to
+ * interrogate or change the thread's state.  Do not cache the returned
+ * pointer when the thread can resume.  You must call utrace_regset to
+ * ensure that context switching has completed and consistent state is
+ * available.
+ */
+const struct utrace_regset *utrace_regset(struct task_struct *target,
+					  struct utrace_attached_engine *,
+					  const struct utrace_regset_view *,
+					  int which);
+
+
+/*
+ * Hooks in <linux/tracehook.h> call these entry points to the utrace dispatch.
+ */
+void utrace_quiescent(struct task_struct *);
+void utrace_release_task(struct task_struct *);
+int utrace_get_signal(struct task_struct *, struct pt_regs *,
+		      siginfo_t *, struct k_sigaction *);
+void utrace_report_clone(unsigned long clone_flags, struct task_struct *child);
+void utrace_report_vfork_done(pid_t child_pid);
+void utrace_report_exit(long *exit_code);
+void utrace_report_death(struct task_struct *, struct utrace *);
+int utrace_report_jctl(int type);
+void utrace_report_exec(struct linux_binprm *bprm, struct pt_regs *regs);
+void utrace_report_syscall(struct pt_regs *regs, int is_exit);
+struct task_struct *utrace_tracer_task(struct task_struct *);
+int utrace_allow_access_process_vm(struct task_struct *);
+int utrace_unsafe_exec(struct task_struct *);
+void utrace_signal_handler_singlestep(struct task_struct *, struct pt_regs *);
+
+
+#endif	/* linux/utrace.h */
diff --git a/include/linux/vmstat.h b/include/linux/vmstat.h
new file mode 100644
index 000000000..198372624
--- /dev/null
+++ b/include/linux/vmstat.h
@@ -0,0 +1,219 @@
+#ifndef _LINUX_VMSTAT_H
+#define _LINUX_VMSTAT_H
+
+#include <linux/types.h>
+#include <linux/percpu.h>
+#include <linux/mmzone.h>
+#include <asm/atomic.h>
+
+#ifdef CONFIG_VM_EVENT_COUNTERS
+/*
+ * Light weight per cpu counter implementation.
+ *
+ * Counters should only be incremented and no critical kernel component
+ * should rely on the counter values.
+ *
+ * Counters are handled completely inline. On many platforms the code
+ * generated will simply be the increment of a global address.
+ */
+
+#define FOR_ALL_ZONES(x) x##_DMA, x##_DMA32, x##_NORMAL, x##_HIGH
+
+enum vm_event_item { PGPGIN, PGPGOUT, PSWPIN, PSWPOUT,
+		FOR_ALL_ZONES(PGALLOC),
+		PGFREE, PGACTIVATE, PGDEACTIVATE,
+		PGFAULT, PGMAJFAULT,
+		FOR_ALL_ZONES(PGREFILL),
+		FOR_ALL_ZONES(PGSTEAL),
+		FOR_ALL_ZONES(PGSCAN_KSWAPD),
+		FOR_ALL_ZONES(PGSCAN_DIRECT),
+		PGINODESTEAL, SLABS_SCANNED, KSWAPD_STEAL, KSWAPD_INODESTEAL,
+		PAGEOUTRUN, ALLOCSTALL, PGROTATED,
+		NR_VM_EVENT_ITEMS
+};
+
+struct vm_event_state {
+	unsigned long event[NR_VM_EVENT_ITEMS];
+};
+
+DECLARE_PER_CPU(struct vm_event_state, vm_event_states);
+
+static inline void __count_vm_event(enum vm_event_item item)
+{
+	__get_cpu_var(vm_event_states).event[item]++;
+}
+
+static inline void count_vm_event(enum vm_event_item item)
+{
+	get_cpu_var(vm_event_states).event[item]++;
+	put_cpu();
+}
+
+static inline void __count_vm_events(enum vm_event_item item, long delta)
+{
+	__get_cpu_var(vm_event_states).event[item] += delta;
+}
+
+static inline void count_vm_events(enum vm_event_item item, long delta)
+{
+	get_cpu_var(vm_event_states).event[item] += delta;
+	put_cpu();
+}
+
+extern void all_vm_events(unsigned long *);
+extern void vm_events_fold_cpu(int cpu);
+
+#else
+
+/* Disable counters */
+#define get_cpu_vm_events(e)	0L
+#define count_vm_event(e)	do { } while (0)
+#define count_vm_events(e,d)	do { } while (0)
+#define __count_vm_event(e)	do { } while (0)
+#define __count_vm_events(e,d)	do { } while (0)
+#define vm_events_fold_cpu(x)	do { } while (0)
+
+#endif /* CONFIG_VM_EVENT_COUNTERS */
+
+#define __count_zone_vm_events(item, zone, delta) \
+			__count_vm_events(item##_DMA + zone_idx(zone), delta)
+
+/*
+ * Zone based page accounting with per cpu differentials.
+ */
+extern atomic_long_t vm_stat[NR_VM_ZONE_STAT_ITEMS];
+
+static inline void zone_page_state_add(long x, struct zone *zone,
+				 enum zone_stat_item item)
+{
+	atomic_long_add(x, &zone->vm_stat[item]);
+	atomic_long_add(x, &vm_stat[item]);
+}
+
+static inline unsigned long global_page_state(enum zone_stat_item item)
+{
+	long x = atomic_long_read(&vm_stat[item]);
+#ifdef CONFIG_SMP
+	if (x < 0)
+		x = 0;
+#endif
+	return x;
+}
+
+static inline unsigned long zone_page_state(struct zone *zone,
+					enum zone_stat_item item)
+{
+	long x = atomic_long_read(&zone->vm_stat[item]);
+#ifdef CONFIG_SMP
+	if (x < 0)
+		x = 0;
+#endif
+	return x;
+}
+
+#ifdef CONFIG_NUMA
+/*
+ * Determine the per node value of a stat item. This function
+ * is called frequently in a NUMA machine, so try to be as
+ * frugal as possible.
+ */
+static inline unsigned long node_page_state(int node,
+				 enum zone_stat_item item)
+{
+	struct zone *zones = NODE_DATA(node)->node_zones;
+
+	return
+#ifndef CONFIG_DMA_IS_NORMAL
+#if !defined(CONFIG_DMA_IS_DMA32) && BITS_PER_LONG >= 64
+		zone_page_state(&zones[ZONE_DMA32], item) +
+#endif
+		zone_page_state(&zones[ZONE_NORMAL], item) +
+#endif
+#ifdef CONFIG_HIGHMEM
+		zone_page_state(&zones[ZONE_HIGHMEM], item) +
+#endif
+		zone_page_state(&zones[ZONE_DMA], item);
+}
+
+extern void zone_statistics(struct zonelist *, struct zone *);
+
+#else
+
+#define node_page_state(node, item) global_page_state(item)
+#define zone_statistics(_zl,_z) do { } while (0)
+
+#endif /* CONFIG_NUMA */
+
+#define __add_zone_page_state(__z, __i, __d)	\
+		__mod_zone_page_state(__z, __i, __d)
+#define __sub_zone_page_state(__z, __i, __d)	\
+		__mod_zone_page_state(__z, __i,-(__d))
+
+#define add_zone_page_state(__z, __i, __d) mod_zone_page_state(__z, __i, __d)
+#define sub_zone_page_state(__z, __i, __d) mod_zone_page_state(__z, __i, -(__d))
+
+static inline void zap_zone_vm_stats(struct zone *zone)
+{
+	memset(zone->vm_stat, 0, sizeof(zone->vm_stat));
+}
+
+extern void inc_zone_state(struct zone *, enum zone_stat_item);
+
+#ifdef CONFIG_SMP
+void __mod_zone_page_state(struct zone *, enum zone_stat_item item, int);
+void __inc_zone_page_state(struct page *, enum zone_stat_item);
+void __dec_zone_page_state(struct page *, enum zone_stat_item);
+
+void mod_zone_page_state(struct zone *, enum zone_stat_item, int);
+void inc_zone_page_state(struct page *, enum zone_stat_item);
+void dec_zone_page_state(struct page *, enum zone_stat_item);
+
+extern void inc_zone_state(struct zone *, enum zone_stat_item);
+
+void refresh_cpu_vm_stats(int);
+void refresh_vm_stats(void);
+
+#else /* CONFIG_SMP */
+
+/*
+ * We do not maintain differentials in a single processor configuration.
+ * The functions directly modify the zone and global counters.
+ */
+static inline void __mod_zone_page_state(struct zone *zone,
+			enum zone_stat_item item, int delta)
+{
+	zone_page_state_add(delta, zone, item);
+}
+
+static inline void __inc_zone_state(struct zone *zone, enum zone_stat_item item)
+{
+	atomic_long_inc(&zone->vm_stat[item]);
+	atomic_long_inc(&vm_stat[item]);
+}
+
+static inline void __inc_zone_page_state(struct page *page,
+			enum zone_stat_item item)
+{
+	__inc_zone_state(page_zone(page), item);
+}
+
+static inline void __dec_zone_page_state(struct page *page,
+			enum zone_stat_item item)
+{
+	atomic_long_dec(&page_zone(page)->vm_stat[item]);
+	atomic_long_dec(&vm_stat[item]);
+}
+
+/*
+ * We only use atomic operations to update counters. So there is no need to
+ * disable interrupts.
+ */
+#define inc_zone_page_state __inc_zone_page_state
+#define dec_zone_page_state __dec_zone_page_state
+#define mod_zone_page_state __mod_zone_page_state
+
+static inline void refresh_cpu_vm_stats(int cpu) { }
+static inline void refresh_vm_stats(void) { }
+#endif
+
+#endif /* _LINUX_VMSTAT_H */
diff --git a/include/linux/vs_cvirt.h.orig b/include/linux/vs_cvirt.h.orig
new file mode 100644
index 000000000..c6aa9d3cf
--- /dev/null
+++ b/include/linux/vs_cvirt.h.orig
@@ -0,0 +1,157 @@
+#ifndef _VX_VS_CVIRT_H
+#define _VX_VS_CVIRT_H
+
+#include "vserver/cvirt.h"
+#include "vserver/debug.h"
+
+
+/* utsname virtualization */
+
+static inline struct new_utsname *vx_new_utsname(void)
+{
+	if (current->vx_info)
+		return &current->vx_info->cvirt.utsname;
+	return &system_utsname;
+}
+
+#define vx_new_uts(x)		((vx_new_utsname())->x)
+
+
+/* pid faking stuff */
+
+
+#define vx_info_map_pid(v,p) \
+	__vx_info_map_pid((v), (p), __FUNC__, __FILE__, __LINE__)
+#define vx_info_map_tgid(v,p)  vx_info_map_pid(v,p)
+#define vx_map_pid(p)	vx_info_map_pid(current->vx_info, p)
+#define vx_map_tgid(p) vx_map_pid(p)
+
+static inline int __vx_info_map_pid(struct vx_info *vxi, int pid,
+	const char *func, const char *file, int line)
+{
+	if (vx_info_flags(vxi, VXF_INFO_INIT, 0)) {
+		vxfprintk(VXD_CBIT(cvirt, 2),
+			"vx_map_tgid: %p/%llx: %d -> %d",
+			vxi, (long long)vxi->vx_flags, pid,
+			(pid && pid == vxi->vx_initpid)?1:pid,
+			func, file, line);
+		if (pid == 0)
+			return 0;
+		if (pid == vxi->vx_initpid)
+			return 1;
+	}
+	return pid;
+}
+
+#define vx_info_rmap_pid(v,p) \
+	__vx_info_rmap_pid((v), (p), __FUNC__, __FILE__, __LINE__)
+#define vx_rmap_pid(p)	vx_info_rmap_pid(current->vx_info, p)
+#define vx_rmap_tgid(p) vx_rmap_pid(p)
+
+static inline int __vx_info_rmap_pid(struct vx_info *vxi, int pid,
+	const char *func, const char *file, int line)
+{
+	if (vx_info_flags(vxi, VXF_INFO_INIT, 0)) {
+		vxfprintk(VXD_CBIT(cvirt, 2),
+			"vx_rmap_tgid: %p/%llx: %d -> %d",
+			vxi, (long long)vxi->vx_flags, pid,
+			(pid == 1)?vxi->vx_initpid:pid,
+			func, file, line);
+		if ((pid == 1) && vxi->vx_initpid)
+			return vxi->vx_initpid;
+		if (pid == vxi->vx_initpid)
+			return ~0U;
+	}
+	return pid;
+}
+
+
+static inline void vx_activate_task(struct task_struct *p)
+{
+	struct vx_info *vxi;
+
+	if ((vxi = p->vx_info)) {
+		vx_update_load(vxi);
+		atomic_inc(&vxi->cvirt.nr_running);
+	}
+}
+
+static inline void vx_deactivate_task(struct task_struct *p)
+{
+	struct vx_info *vxi;
+
+	if ((vxi = p->vx_info)) {
+		vx_update_load(vxi);
+		atomic_dec(&vxi->cvirt.nr_running);
+	}
+}
+
+static inline void vx_uninterruptible_inc(struct task_struct *p)
+{
+	struct vx_info *vxi;
+
+	if ((vxi = p->vx_info))
+		atomic_inc(&vxi->cvirt.nr_uninterruptible);
+}
+
+static inline void vx_uninterruptible_dec(struct task_struct *p)
+{
+	struct vx_info *vxi;
+
+	if ((vxi = p->vx_info))
+		atomic_dec(&vxi->cvirt.nr_uninterruptible);
+}
+
+
+struct inode;
+
+#define VXF_FAKE_INIT	(VXF_INFO_INIT|VXF_STATE_INIT)
+
+static inline
+int proc_pid_visible(struct task_struct *task, int pid)
+{
+	if ((pid == 1) &&
+		!vx_flags(VXF_FAKE_INIT, VXF_FAKE_INIT))
+		/* show a blend through init */
+		goto visible;
+	if (vx_check(vx_task_xid(task), VX_WATCH|VX_IDENT))
+		goto visible;
+	return 0;
+visible:
+	return 1;
+}
+
+static inline
+struct task_struct *find_proc_task_by_pid(int pid)
+{
+	struct task_struct *task = find_task_by_pid(pid);
+
+	if (task && !proc_pid_visible(task, pid)) {
+		vxdprintk(VXD_CBIT(misc, 6),
+			"dropping task %p[#%u,%u] for %p[#%u,%u]",
+			task, task->xid, task->pid,
+			current, current->xid, current->pid);
+		task = NULL;
+	}
+	return task;
+}
+
+static inline
+struct task_struct *vx_get_proc_task(struct inode *inode, struct pid *pid)
+{
+	struct task_struct *task = get_pid_task(pid, PIDTYPE_PID);
+
+	if (task && !proc_pid_visible(task, pid->nr)) {
+		vxdprintk(VXD_CBIT(misc, 6),
+			"dropping task %p[#%u,%u] for %p[#%u,%u]",
+			task, task->xid, task->pid,
+			current, current->xid, current->pid);
+		put_task_struct(task);
+		task = NULL;
+	}
+	return task;
+}
+
+#else
+#warning duplicate inclusion
+#endif
diff --git a/include/linux/xenfb.h b/include/linux/xenfb.h
new file mode 100644
index 000000000..3653c57f6
--- /dev/null
+++ b/include/linux/xenfb.h
@@ -0,0 +1,108 @@
+/*
+ * linux/include/linux/xenfb.h -- Xen virtual frame buffer device
+ *
+ * Copyright (C) 2005
+ *
+ *      Anthony Liguori <aliguori@us.ibm.com>
+ *
+ *  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.
+ */
+
+#ifndef _LINUX_XENFB_H
+#define _LINUX_XENFB_H
+
+#include <asm/types.h>
+
+/* out events */
+
+#define XENFB_OUT_EVENT_SIZE 40
+
+#define XENFB_TYPE_MOTION 1
+#define XENFB_TYPE_UPDATE 2
+
+struct xenfb_motion	    /* currently unused */
+{
+	__u8 type;          /* XENFB_TYPE_MOTION */
+	__u16 x;            /* The new x coordinate */
+	__u16 y;            /* The new y coordinate */
+};
+
+struct xenfb_update
+{
+	__u8 type;          /* XENFB_TYPE_UPDATE */
+	__u16 x;            /* source x */
+	__u16 y;            /* source y */
+	__u16 width;        /* rect width */
+	__u16 height;       /* rect height */
+};
+
+union xenfb_out_event
+{
+	__u8 type;
+	struct xenfb_motion motion;
+	struct xenfb_update update;
+	char _[XENFB_OUT_EVENT_SIZE];
+};
+
+/* in events */
+
+#define XENFB_IN_EVENT_SIZE 40
+
+#define XENFB_TYPE_SET_EVENTS 1
+
+#define XENFB_FLAG_MOTION 1
+#define XENFB_FLAG_UPDATE 2
+#define XENFB_FLAG_COPY 4
+#define XENFB_FLAG_FILL 8
+
+struct xenfb_set_events
+{
+	__u8 type;          /* XENFB_TYPE_SET_EVENTS */
+	__u32 flags;        /* combination of XENFB_FLAG_* */
+};
+
+union xenfb_in_event
+{
+	__u8 type;
+	struct xenfb_set_events set_events;
+	char _[XENFB_OUT_EVENT_SIZE];
+};
+
+/* shared page */
+
+#define XENFB_IN_RING_SIZE 1024
+#define XENFB_IN_RING_LEN (XENFB_IN_RING_SIZE / XENFB_IN_EVENT_SIZE)
+#define XENFB_IN_RING_OFFS 1024
+#define XENFB_IN_RING(page) \
+    ((union xenfb_in_event *)((char *)(page) + XENFB_IN_RING_OFFS))
+#define XENFB_IN_RING_REF(page, idx) \
+    (XENFB_IN_RING((page))[(idx) % XENFB_IN_RING_LEN])
+
+#define XENFB_OUT_RING_SIZE 2048
+#define XENFB_OUT_RING_LEN (XENFB_OUT_RING_SIZE / XENFB_OUT_EVENT_SIZE)
+#define XENFB_OUT_RING_OFFS (XENFB_IN_RING_OFFS + XENFB_IN_RING_SIZE)
+#define XENFB_OUT_RING(page) \
+    ((union xenfb_out_event *)((char *)(page) + XENFB_OUT_RING_OFFS))
+#define XENFB_OUT_RING_REF(page, idx) \
+    (XENFB_OUT_RING((page))[(idx) % XENFB_OUT_RING_LEN])
+
+struct xenfb_page
+{
+	__u16 width;         /* the width of the framebuffer (in pixels) */
+	__u16 height;        /* the height of the framebuffer (in pixels) */
+	__u32 line_length;   /* the length of a row of pixels (in bytes) */
+	__u32 mem_length;    /* the length of the framebuffer (in bytes) */
+	__u8 depth;          /* the depth of a pixel (in bits) */
+
+	unsigned long pd[2];	/* FIXME rename to pgdir? */
+	/* FIXME pd[1] unused at this time, shrink? */
+
+	__u32 in_cons, in_prod;
+	__u32 out_cons, out_prod;
+};
+
+void xenfb_resume(void);
+
+#endif
diff --git a/include/linux/xenkbd.h b/include/linux/xenkbd.h
new file mode 100644
index 000000000..c023c123d
--- /dev/null
+++ b/include/linux/xenkbd.h
@@ -0,0 +1,92 @@
+/*
+ * linux/include/linux/xenkbd.h -- Xen virtual keyboard/mouse
+ *
+ * Copyright (C) 2005
+ *
+ *      Anthony Liguori <aliguori@us.ibm.com>
+ *
+ *  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.
+ */
+
+#ifndef _LINUX_XENKBD_H
+#define _LINUX_XENKBD_H
+
+#include <asm/types.h>
+
+/* in events */
+
+#define XENKBD_IN_EVENT_SIZE 40
+
+#define XENKBD_TYPE_MOTION  1     /* mouse movement event */
+#define XENKBD_TYPE_BUTTON  2     /* mouse button event */
+#define XENKBD_TYPE_KEY     3     /* keyboard event */
+
+struct xenkbd_motion
+{
+	__u8 type;         /* XENKBD_TYPE_MOTION */
+	__s16 rel_x;       /* relative X motion */
+	__s16 rel_y;       /* relative Y motion */
+};
+
+struct xenkbd_button
+{
+	__u8 type;         /* XENKBD_TYPE_BUTTON */
+	__u8 pressed;      /* 1 if pressed; 0 otherwise */
+	__u8 button;       /* the button (0, 1, 2 is right, middle, left) */
+};
+
+struct xenkbd_key
+{
+	__u8 type;         /* XENKBD_TYPE_KEY */
+	__u8 pressed;      /* 1 if pressed; 0 otherwise */
+	__u16 keycode;     /* KEY_* from linux/input.h */
+};
+
+union xenkbd_in_event
+{
+	__u8 type;
+	struct xenkbd_motion motion;
+	struct xenkbd_button button;
+	struct xenkbd_key key;
+	char _[XENKBD_IN_EVENT_SIZE];
+};
+
+/* out events */
+
+#define XENKBD_OUT_EVENT_SIZE 40
+
+union xenkbd_out_event
+{
+	__u8 type;
+	char _[XENKBD_OUT_EVENT_SIZE];
+};
+
+/* shared page */
+
+#define XENKBD_IN_RING_SIZE 2048
+#define XENKBD_IN_RING_LEN (XENKBD_IN_RING_SIZE / XENKBD_IN_EVENT_SIZE)
+#define XENKBD_IN_RING_OFFS 1024
+#define XENKBD_IN_RING(page) \
+    ((union xenkbd_in_event *)((char *)(page) + XENKBD_IN_RING_OFFS))
+#define XENKBD_IN_RING_REF(page, idx) \
+    (XENKBD_IN_RING((page))[(idx) % XENKBD_IN_RING_LEN])
+
+#define XENKBD_OUT_RING_SIZE 1024
+#define XENKBD_OUT_RING_LEN (XENKBD_OUT_RING_SIZE / XENKBD_OUT_EVENT_SIZE)
+#define XENKBD_OUT_RING_OFFS (XENKBD_IN_RING_OFFS + XENKBD_IN_RING_SIZE)
+#define XENKBD_OUT_RING(page) \
+    ((union xenkbd_out_event *)((char *)(page) + XENKBD_OUT_RING_OFFS))
+#define XENKBD_OUT_RING_REF(page, idx) \
+    (XENKBD_OUT_RING((page))[(idx) % XENKBD_OUT_RING_LEN])
+
+struct xenkbd_info
+{
+	__u32 in_cons, in_prod;
+	__u32 out_cons, out_prod;
+};
+
+void xenkbd_resume(void);
+
+#endif
diff --git a/include/media/cx2341x.h b/include/media/cx2341x.h
new file mode 100644
index 000000000..d91d88f93
--- /dev/null
+++ b/include/media/cx2341x.h
@@ -0,0 +1,195 @@
+/*
+    cx23415/6 header containing common defines.
+
+    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
+ */
+
+#ifndef CX2341X_H
+#define CX2341X_H
+
+enum cx2341x_port {
+	CX2341X_PORT_MEMORY    = 0,
+	CX2341X_PORT_STREAMING = 1,
+	CX2341X_PORT_SERIAL    = 2
+};
+
+enum cx2341x_cap {
+	CX2341X_CAP_HAS_SLICED_VBI = 1 << 0,
+};
+
+struct cx2341x_mpeg_params {
+	/* misc */
+	u32 capabilities;
+	enum cx2341x_port port;
+	u16 width;
+	u16 height;
+	u16 is_50hz;
+
+	/* stream */
+	enum v4l2_mpeg_stream_type stream_type;
+	enum v4l2_mpeg_stream_vbi_fmt stream_vbi_fmt;
+
+	/* audio */
+	enum v4l2_mpeg_audio_sampling_freq audio_sampling_freq;
+	enum v4l2_mpeg_audio_encoding audio_encoding;
+	enum v4l2_mpeg_audio_l2_bitrate audio_l2_bitrate;
+	enum v4l2_mpeg_audio_mode audio_mode;
+	enum v4l2_mpeg_audio_mode_extension audio_mode_extension;
+	enum v4l2_mpeg_audio_emphasis audio_emphasis;
+	enum v4l2_mpeg_audio_crc audio_crc;
+	u8 audio_properties;
+
+	/* video */
+	enum v4l2_mpeg_video_encoding video_encoding;
+	enum v4l2_mpeg_video_aspect video_aspect;
+	u16 video_b_frames;
+	u16 video_gop_size;
+	u16 video_gop_closure;
+	u16 video_pulldown;
+	enum v4l2_mpeg_video_bitrate_mode video_bitrate_mode;
+	u32 video_bitrate;
+	u32 video_bitrate_peak;
+	u16 video_temporal_decimation;
+
+	/* encoding filters */
+	enum v4l2_mpeg_cx2341x_video_spatial_filter_mode video_spatial_filter_mode;
+	u16 video_spatial_filter;
+	enum v4l2_mpeg_cx2341x_video_luma_spatial_filter_type video_luma_spatial_filter_type;
+	enum v4l2_mpeg_cx2341x_video_chroma_spatial_filter_type video_chroma_spatial_filter_type;
+	enum v4l2_mpeg_cx2341x_video_temporal_filter_mode video_temporal_filter_mode;
+	u16 video_temporal_filter;
+	enum v4l2_mpeg_cx2341x_video_median_filter_type video_median_filter_type;
+	u16 video_luma_median_filter_top;
+	u16 video_luma_median_filter_bottom;
+	u16 video_chroma_median_filter_top;
+	u16 video_chroma_median_filter_bottom;
+};
+
+#define CX2341X_MBOX_MAX_DATA 16
+
+extern const u32 cx2341x_mpeg_ctrls[];
+typedef int (*cx2341x_mbox_func)(void *priv, int cmd, int in, int out,
+		u32 data[CX2341X_MBOX_MAX_DATA]);
+int cx2341x_update(void *priv, cx2341x_mbox_func func,
+		const struct cx2341x_mpeg_params *old,
+		const struct cx2341x_mpeg_params *new);
+int cx2341x_ctrl_query(struct cx2341x_mpeg_params *params,
+		struct v4l2_queryctrl *qctrl);
+const char **cx2341x_ctrl_get_menu(u32 id);
+int cx2341x_ext_ctrls(struct cx2341x_mpeg_params *params,
+		struct v4l2_ext_controls *ctrls, unsigned int cmd);
+void cx2341x_fill_defaults(struct cx2341x_mpeg_params *p);
+void cx2341x_log_status(struct cx2341x_mpeg_params *p, const char *prefix);
+
+/* Firmware names */
+#define CX2341X_FIRM_ENC_FILENAME "v4l-cx2341x-enc.fw"
+/* Decoder firmware for the cx23415 only */
+#define CX2341X_FIRM_DEC_FILENAME "v4l-cx2341x-dec.fw"
+
+/* Firmware API commands */
+
+/* MPEG decoder API, specific to the cx23415 */
+#define CX2341X_DEC_PING_FW 			0x00
+#define CX2341X_DEC_START_PLAYBACK 		0x01
+#define CX2341X_DEC_STOP_PLAYBACK 		0x02
+#define CX2341X_DEC_SET_PLAYBACK_SPEED 		0x03
+#define CX2341X_DEC_STEP_VIDEO 			0x05
+#define CX2341X_DEC_SET_DMA_BLOCK_SIZE 		0x08
+#define CX2341X_DEC_GET_XFER_INFO		0x09
+#define CX2341X_DEC_GET_DMA_STATUS		0x0a
+#define CX2341X_DEC_SCHED_DMA_FROM_HOST		0x0b
+#define CX2341X_DEC_PAUSE_PLAYBACK 		0x0d
+#define CX2341X_DEC_HALT_FW 			0x0e
+#define CX2341X_DEC_SET_STANDARD 		0x10
+#define CX2341X_DEC_GET_VERSION			0x11
+#define CX2341X_DEC_SET_STREAM_INPUT 		0x14
+#define CX2341X_DEC_GET_TIMING_INFO 		0x15
+#define CX2341X_DEC_SET_AUDIO_MODE 		0x16
+#define CX2341X_DEC_SET_EVENT_NOTIFICATION	0x17
+#define CX2341X_DEC_SET_DISPLAY_BUFFERS		0x18
+#define CX2341X_DEC_EXTRACT_VBI 		0x19
+#define CX2341X_DEC_SET_DECODER_SOURCE 		0x1a
+#define CX2341X_DEC_SET_AUDIO_OUTPUT 		0x1b
+#define CX2341X_DEC_SET_AV_DELAY 		0x1c
+#define CX2341X_DEC_SET_PREBUFFERING		0x1e
+
+/* MPEG encoder API */
+#define CX2341X_ENC_PING_FW 			0x80
+#define CX2341X_ENC_START_CAPTURE 		0x81
+#define CX2341X_ENC_STOP_CAPTURE 		0x82
+#define CX2341X_ENC_SET_AUDIO_ID 		0x89
+#define CX2341X_ENC_SET_VIDEO_ID 		0x8b
+#define CX2341X_ENC_SET_PCR_ID 			0x8d
+#define CX2341X_ENC_SET_FRAME_RATE 		0x8f
+#define CX2341X_ENC_SET_FRAME_SIZE 		0x91
+#define CX2341X_ENC_SET_BIT_RATE 		0x95
+#define CX2341X_ENC_SET_GOP_PROPERTIES 		0x97
+#define CX2341X_ENC_SET_ASPECT_RATIO 		0x99
+#define CX2341X_ENC_SET_DNR_FILTER_MODE 	0x9b
+#define CX2341X_ENC_SET_DNR_FILTER_PROPS 	0x9d
+#define CX2341X_ENC_SET_CORING_LEVELS 		0x9f
+#define CX2341X_ENC_SET_SPATIAL_FILTER_TYPE 	0xa1
+#define CX2341X_ENC_SET_3_2_PULLDOWN 		0xb1
+#define CX2341X_ENC_SET_VBI_LINE 		0xb7
+#define CX2341X_ENC_SET_STREAM_TYPE 		0xb9
+#define CX2341X_ENC_SET_OUTPUT_PORT 		0xbb
+#define CX2341X_ENC_SET_AUDIO_PROPERTIES 	0xbd
+#define CX2341X_ENC_HALT_FW 			0xc3
+#define CX2341X_ENC_GET_VERSION			0xc4
+#define CX2341X_ENC_SET_GOP_CLOSURE 		0xc5
+#define CX2341X_ENC_GET_SEQ_END 		0xc6
+#define CX2341X_ENC_SET_PGM_INDEX_INFO 		0xc7
+#define CX2341X_ENC_SET_VBI_CONFIG		0xc8
+#define CX2341X_ENC_SET_DMA_BLOCK_SIZE 		0xc9
+#define CX2341X_ENC_GET_PREV_DMA_INFO_MB_10	0xca
+#define CX2341X_ENC_GET_PREV_DMA_INFO_MB_9	0xcb
+#define CX2341X_ENC_SCHED_DMA_TO_HOST 		0xcc
+#define CX2341X_ENC_INITIALIZE_INPUT 		0xcd
+#define CX2341X_ENC_SET_FRAME_DROP_RATE 	0xd0
+#define CX2341X_ENC_PAUSE_ENCODER 		0xd2
+#define CX2341X_ENC_REFRESH_INPUT 		0xd3
+#define CX2341X_ENC_SET_COPYRIGHT		0xd4
+#define CX2341X_ENC_SET_EVENT_NOTIFICATION 	0xd5
+#define CX2341X_ENC_SET_NUM_VSYNC_LINES 	0xd6
+#define CX2341X_ENC_SET_PLACEHOLDER 		0xd7
+#define CX2341X_ENC_MUTE_VIDEO 			0xd9
+#define CX2341X_ENC_MUTE_AUDIO 			0xda
+#define CX2341X_ENC_UNKNOWN			0xdb
+#define CX2341X_ENC_MISC 			0xdc
+
+/* OSD API, specific to the cx23415 */
+#define CX2341X_OSD_GET_FRAMEBUFFER 		0x41
+#define CX2341X_OSD_GET_PIXEL_FORMAT 		0x42
+#define CX2341X_OSD_SET_PIXEL_FORMAT 		0x43
+#define CX2341X_OSD_GET_STATE 			0x44
+#define CX2341X_OSD_SET_STATE 			0x45
+#define CX2341X_OSD_GET_OSD_COORDS 		0x46
+#define CX2341X_OSD_SET_OSD_COORDS 		0x47
+#define CX2341X_OSD_GET_SCREEN_COORDS 		0x48
+#define CX2341X_OSD_SET_SCREEN_COORDS 		0x49
+#define CX2341X_OSD_GET_GLOBAL_ALPHA 		0x4a
+#define CX2341X_OSD_SET_GLOBAL_ALPHA 		0x4b
+#define CX2341X_OSD_SET_BLEND_COORDS 		0x4c
+#define CX2341X_OSD_GET_FLICKER_STATE 		0x4f
+#define CX2341X_OSD_SET_FLICKER_STATE 		0x50
+#define CX2341X_OSD_BLT_COPY 			0x52
+#define CX2341X_OSD_BLT_FILL 			0x53
+#define CX2341X_OSD_BLT_TEXT 			0x54
+#define CX2341X_OSD_SET_FRAMEBUFFER_WINDOW 	0x56
+#define CX2341X_OSD_SET_CHROMA_KEY 		0x60
+#define CX2341X_OSD_GET_ALPHA_CONTENT_INDEX 	0x61
+#define CX2341X_OSD_SET_ALPHA_CONTENT_INDEX 	0x62
+
+#endif /* CX2341X_H */
diff --git a/include/media/pwc-ioctl.h b/include/media/pwc-ioctl.h
new file mode 100644
index 000000000..adc1254e8
--- /dev/null
+++ b/include/media/pwc-ioctl.h
@@ -0,0 +1,325 @@
+#ifndef PWC_IOCTL_H
+#define PWC_IOCTL_H
+
+/* (C) 2001-2004 Nemosoft Unv.
+   (C) 2004-2006 Luc Saillard (luc@saillard.org)
+
+   NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx
+   driver and thus may have bugs that are not present in the original version.
+   Please send bug reports and support requests to <luc@saillard.org>.
+   The decompression routines have been implemented by reverse-engineering the
+   Nemosoft binary pwcx module. Caveat emptor.
+
+   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
+*/
+
+/* This is pwc-ioctl.h belonging to PWC 10.0.10
+   It contains structures and defines to communicate from user space
+   directly to the driver.
+ */
+
+/*
+   Changes
+   2001/08/03  Alvarado   Added ioctl constants to access methods for
+			  changing white balance and red/blue gains
+   2002/12/15  G. H. Fernandez-Toribio   VIDIOCGREALSIZE
+   2003/12/13  Nemosft Unv. Some modifications to make interfacing to
+	       PWCX easier
+   2006/01/01  Luc Saillard Add raw format definition
+ */
+
+/* These are private ioctl() commands, specific for the Philips webcams.
+   They contain functions not found in other webcams, and settings not
+   specified in the Video4Linux API.
+
+   The #define names are built up like follows:
+   VIDIOC		VIDeo IOCtl prefix
+	 PWC		Philps WebCam
+	    G           optional: Get
+	    S           optional: Set
+	     ... 	the function
+ */
+
+#include <linux/types.h>
+#include <linux/version.h>
+
+
+ /* Enumeration of image sizes */
+#define PSZ_SQCIF	0x00
+#define PSZ_QSIF	0x01
+#define PSZ_QCIF	0x02
+#define PSZ_SIF		0x03
+#define PSZ_CIF		0x04
+#define PSZ_VGA		0x05
+#define PSZ_MAX		6
+
+
+/* The frame rate is encoded in the video_window.flags parameter using
+   the upper 16 bits, since some flags are defined nowadays. The following
+   defines provide a mask and shift to filter out this value.
+   This value can also be passing using the private flag when using v4l2 and
+   VIDIOC_S_FMT ioctl.
+
+   In 'Snapshot' mode the camera freezes its automatic exposure and colour
+   balance controls.
+ */
+#define PWC_FPS_SHIFT		16
+#define PWC_FPS_MASK		0x00FF0000
+#define PWC_FPS_FRMASK		0x003F0000
+#define PWC_FPS_SNAPSHOT	0x00400000
+#define PWC_QLT_MASK		0x03000000
+#define PWC_QLT_SHIFT		24
+
+
+/* structure for transferring x & y coordinates */
+struct pwc_coord
+{
+	int x, y;		/* guess what */
+	int size;		/* size, or offset */
+};
+
+
+/* Used with VIDIOCPWCPROBE */
+struct pwc_probe
+{
+	char name[32];
+	int type;
+};
+
+struct pwc_serial
+{
+	char serial[30];	/* String with serial number. Contains terminating 0 */
+};
+
+/* pwc_whitebalance.mode values */
+#define PWC_WB_INDOOR		0
+#define PWC_WB_OUTDOOR		1
+#define PWC_WB_FL		2
+#define PWC_WB_MANUAL		3
+#define PWC_WB_AUTO		4
+
+/* Used with VIDIOCPWC[SG]AWB (Auto White Balance).
+   Set mode to one of the PWC_WB_* values above.
+   *red and *blue are the respective gains of these colour components inside
+   the camera; range 0..65535
+   When 'mode' == PWC_WB_MANUAL, 'manual_red' and 'manual_blue' are set or read;
+   otherwise undefined.
+   'read_red' and 'read_blue' are read-only.
+*/
+struct pwc_whitebalance
+{
+	int mode;
+	int manual_red, manual_blue;	/* R/W */
+	int read_red, read_blue;	/* R/O */
+};
+
+/*
+   'control_speed' and 'control_delay' are used in automatic whitebalance mode,
+   and tell the camera how fast it should react to changes in lighting, and
+   with how much delay. Valid values are 0..65535.
+*/
+struct pwc_wb_speed
+{
+	int control_speed;
+	int control_delay;
+
+};
+
+/* Used with VIDIOCPWC[SG]LED */
+struct pwc_leds
+{
+	int led_on;			/* Led on-time; range = 0..25000 */
+	int led_off;			/* Led off-time; range = 0..25000  */
+};
+
+/* Image size (used with GREALSIZE) */
+struct pwc_imagesize
+{
+	int width;
+	int height;
+};
+
+/* Defines and structures for Motorized Pan & Tilt */
+#define PWC_MPT_PAN		0x01
+#define PWC_MPT_TILT		0x02
+#define PWC_MPT_TIMEOUT		0x04 /* for status */
+
+/* Set angles; when absolute != 0, the angle is absolute and the
+   driver calculates the relative offset for you. This can only
+   be used with VIDIOCPWCSANGLE; VIDIOCPWCGANGLE always returns
+   absolute angles.
+ */
+struct pwc_mpt_angles
+{
+	int absolute;		/* write-only */
+	int pan;		/* degrees * 100 */
+	int tilt;		/* degress * 100 */
+};
+
+/* Range of angles of the camera, both horizontally and vertically.
+ */
+struct pwc_mpt_range
+{
+	int pan_min, pan_max;		/* degrees * 100 */
+	int tilt_min, tilt_max;
+};
+
+struct pwc_mpt_status
+{
+	int status;
+	int time_pan;
+	int time_tilt;
+};
+
+
+/* This is used for out-of-kernel decompression. With it, you can get
+   all the necessary information to initialize and use the decompressor
+   routines in standalone applications.
+ */
+struct pwc_video_command
+{
+	int type;		/* camera type (645, 675, 730, etc.) */
+	int release;		/* release number */
+
+	int size;		/* one of PSZ_* */
+	int alternate;
+	int command_len;	/* length of USB video command */
+	unsigned char command_buf[13];	/* Actual USB video command */
+	int bandlength;		/* >0 = compressed */
+	int frame_size;		/* Size of one (un)compressed frame */
+};
+
+/* Flags for PWCX subroutines. Not all modules honour all flags. */
+#define PWCX_FLAG_PLANAR	0x0001
+#define PWCX_FLAG_BAYER		0x0008
+
+
+/* IOCTL definitions */
+
+ /* Restore user settings */
+#define VIDIOCPWCRUSER		_IO('v', 192)
+ /* Save user settings */
+#define VIDIOCPWCSUSER		_IO('v', 193)
+ /* Restore factory settings */
+#define VIDIOCPWCFACTORY	_IO('v', 194)
+
+ /* You can manipulate the compression factor. A compression preference of 0
+    means use uncompressed modes when available; 1 is low compression, 2 is
+    medium and 3 is high compression preferred. Of course, the higher the
+    compression, the lower the bandwidth used but more chance of artefacts
+    in the image. The driver automatically chooses a higher compression when
+    the preferred mode is not available.
+  */
+ /* Set preferred compression quality (0 = uncompressed, 3 = highest compression) */
+#define VIDIOCPWCSCQUAL		_IOW('v', 195, int)
+ /* Get preferred compression quality */
+#define VIDIOCPWCGCQUAL		_IOR('v', 195, int)
+
+
+/* Retrieve serial number of camera */
+#define VIDIOCPWCGSERIAL	_IOR('v', 198, struct pwc_serial)
+
+ /* This is a probe function; since so many devices are supported, it
+    becomes difficult to include all the names in programs that want to
+    check for the enhanced Philips stuff. So in stead, try this PROBE;
+    it returns a structure with the original name, and the corresponding
+    Philips type.
+    To use, fill the structure with zeroes, call PROBE and if that succeeds,
+    compare the name with that returned from VIDIOCGCAP; they should be the
+    same. If so, you can be assured it is a Philips (OEM) cam and the type
+    is valid.
+ */
+#define VIDIOCPWCPROBE		_IOR('v', 199, struct pwc_probe)
+
+ /* Set AGC (Automatic Gain Control); int < 0 = auto, 0..65535 = fixed */
+#define VIDIOCPWCSAGC		_IOW('v', 200, int)
+ /* Get AGC; int < 0 = auto; >= 0 = fixed, range 0..65535 */
+#define VIDIOCPWCGAGC		_IOR('v', 200, int)
+ /* Set shutter speed; int < 0 = auto; >= 0 = fixed, range 0..65535 */
+#define VIDIOCPWCSSHUTTER	_IOW('v', 201, int)
+
+ /* Color compensation (Auto White Balance) */
+#define VIDIOCPWCSAWB           _IOW('v', 202, struct pwc_whitebalance)
+#define VIDIOCPWCGAWB           _IOR('v', 202, struct pwc_whitebalance)
+
+ /* Auto WB speed */
+#define VIDIOCPWCSAWBSPEED	_IOW('v', 203, struct pwc_wb_speed)
+#define VIDIOCPWCGAWBSPEED	_IOR('v', 203, struct pwc_wb_speed)
+
+ /* LEDs on/off/blink; int range 0..65535 */
+#define VIDIOCPWCSLED           _IOW('v', 205, struct pwc_leds)
+#define VIDIOCPWCGLED           _IOR('v', 205, struct pwc_leds)
+
+  /* Contour (sharpness); int < 0 = auto, 0..65536 = fixed */
+#define VIDIOCPWCSCONTOUR	_IOW('v', 206, int)
+#define VIDIOCPWCGCONTOUR	_IOR('v', 206, int)
+
+  /* Backlight compensation; 0 = off, otherwise on */
+#define VIDIOCPWCSBACKLIGHT	_IOW('v', 207, int)
+#define VIDIOCPWCGBACKLIGHT	_IOR('v', 207, int)
+
+  /* Flickerless mode; = 0 off, otherwise on */
+#define VIDIOCPWCSFLICKER	_IOW('v', 208, int)
+#define VIDIOCPWCGFLICKER	_IOR('v', 208, int)
+
+  /* Dynamic noise reduction; 0 off, 3 = high noise reduction */
+#define VIDIOCPWCSDYNNOISE	_IOW('v', 209, int)
+#define VIDIOCPWCGDYNNOISE	_IOR('v', 209, int)
+
+ /* Real image size as used by the camera; tells you whether or not there's a gray border around the image */
+#define VIDIOCPWCGREALSIZE	_IOR('v', 210, struct pwc_imagesize)
+
+ /* Motorized pan & tilt functions */
+#define VIDIOCPWCMPTRESET	_IOW('v', 211, int)
+#define VIDIOCPWCMPTGRANGE	_IOR('v', 211, struct pwc_mpt_range)
+#define VIDIOCPWCMPTSANGLE	_IOW('v', 212, struct pwc_mpt_angles)
+#define VIDIOCPWCMPTGANGLE	_IOR('v', 212, struct pwc_mpt_angles)
+#define VIDIOCPWCMPTSTATUS	_IOR('v', 213, struct pwc_mpt_status)
+
+ /* Get the USB set-video command; needed for initializing libpwcx */
+#define VIDIOCPWCGVIDCMD	_IOR('v', 215, struct pwc_video_command)
+struct pwc_table_init_buffer {
+   int len;
+   char *buffer;
+
+};
+#define VIDIOCPWCGVIDTABLE	_IOR('v', 216, struct pwc_table_init_buffer)
+
+/*
+ * This is private command used when communicating with v4l2.
+ * In the future all private ioctl will be remove/replace to
+ * use interface offer by v4l2.
+ */
+
+#define V4L2_CID_PRIVATE_SAVE_USER       (V4L2_CID_PRIVATE_BASE + 0)
+#define V4L2_CID_PRIVATE_RESTORE_USER    (V4L2_CID_PRIVATE_BASE + 1)
+#define V4L2_CID_PRIVATE_RESTORE_FACTORY (V4L2_CID_PRIVATE_BASE + 2)
+#define V4L2_CID_PRIVATE_COLOUR_MODE     (V4L2_CID_PRIVATE_BASE + 3)
+#define V4L2_CID_PRIVATE_AUTOCONTOUR     (V4L2_CID_PRIVATE_BASE + 4)
+#define V4L2_CID_PRIVATE_CONTOUR         (V4L2_CID_PRIVATE_BASE + 5)
+#define V4L2_CID_PRIVATE_BACKLIGHT       (V4L2_CID_PRIVATE_BASE + 6)
+#define V4L2_CID_PRIVATE_FLICKERLESS     (V4L2_CID_PRIVATE_BASE + 7)
+#define V4L2_CID_PRIVATE_NOISE_REDUCTION (V4L2_CID_PRIVATE_BASE + 8)
+
+struct pwc_raw_frame {
+   __le16 type;		/* type of the webcam */
+   __le16 vbandlength;	/* Size of 4lines compressed (used by the decompressor) */
+   __u8   cmd[4];	/* the four byte of the command (in case of nala,
+			   only the first 3 bytes is filled) */
+   __u8   rawframe[0];	/* frame_size = H/4*vbandlength */
+} __attribute__ ((packed));
+
+
+#endif
diff --git a/include/media/tvp5150.h b/include/media/tvp5150.h
new file mode 100644
index 000000000..72bd2a2b8
--- /dev/null
+++ b/include/media/tvp5150.h
@@ -0,0 +1,34 @@
+/*
+    tvp5150.h - definition for tvp5150 inputs
+
+    Copyright (C) 2006 Hans Verkuil (hverkuil@xs4all.nl)
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef _TVP5150_H_
+#define _TVP5150_H_
+
+/* TVP5150 HW inputs */
+#define TVP5150_COMPOSITE0 0
+#define TVP5150_COMPOSITE1 1
+#define TVP5150_SVIDEO     2
+
+/* TVP5150 HW outputs */
+#define TVP5150_NORMAL       0
+#define TVP5150_BLACK_SCREEN 1
+
+#endif
+
diff --git a/include/media/v4l2-dev.h b/include/media/v4l2-dev.h
new file mode 100644
index 000000000..810462f8a
--- /dev/null
+++ b/include/media/v4l2-dev.h
@@ -0,0 +1,378 @@
+/*
+ *
+ *	V 4 L 2   D R I V E R   H E L P E R   A P I
+ *
+ * Moved from videodev2.h
+ *
+ *	Some commonly needed functions for drivers (v4l2-common.o module)
+ */
+#ifndef _V4L2_DEV_H
+#define _V4L2_DEV_H
+
+#define OBSOLETE_OWNER 1 /* to be removed soon */
+
+#include <linux/poll.h>
+#include <linux/fs.h>
+#include <linux/device.h>
+#include <linux/mutex.h>
+#include <linux/compiler.h> /* need __user */
+#ifdef CONFIG_VIDEO_V4L1_COMPAT
+#include <linux/videodev.h>
+#else
+#include <linux/videodev2.h>
+#endif
+
+#include <linux/fs.h>
+
+#define VIDEO_MAJOR	81
+/* Minor device allocation */
+#define MINOR_VFL_TYPE_GRABBER_MIN   0
+#define MINOR_VFL_TYPE_GRABBER_MAX  63
+#define MINOR_VFL_TYPE_RADIO_MIN    64
+#define MINOR_VFL_TYPE_RADIO_MAX   127
+#define MINOR_VFL_TYPE_VTX_MIN     192
+#define MINOR_VFL_TYPE_VTX_MAX     223
+#define MINOR_VFL_TYPE_VBI_MIN     224
+#define MINOR_VFL_TYPE_VBI_MAX     255
+
+#define VFL_TYPE_GRABBER	0
+#define VFL_TYPE_VBI		1
+#define VFL_TYPE_RADIO		2
+#define VFL_TYPE_VTX		3
+
+/*  Video standard functions  */
+extern unsigned int v4l2_video_std_fps(struct v4l2_standard *vs);
+extern int v4l2_video_std_construct(struct v4l2_standard *vs,
+				    int id, char *name);
+
+/* prority handling */
+struct v4l2_prio_state {
+	atomic_t prios[4];
+};
+int v4l2_prio_init(struct v4l2_prio_state *global);
+int v4l2_prio_change(struct v4l2_prio_state *global, enum v4l2_priority *local,
+		     enum v4l2_priority new);
+int v4l2_prio_open(struct v4l2_prio_state *global, enum v4l2_priority *local);
+int v4l2_prio_close(struct v4l2_prio_state *global, enum v4l2_priority *local);
+enum v4l2_priority v4l2_prio_max(struct v4l2_prio_state *global);
+int v4l2_prio_check(struct v4l2_prio_state *global, enum v4l2_priority *local);
+
+/* names for fancy debug output */
+extern char *v4l2_field_names[];
+extern char *v4l2_type_names[];
+
+/*  Compatibility layer interface  --  v4l1-compat module */
+typedef int (*v4l2_kioctl)(struct inode *inode, struct file *file,
+			   unsigned int cmd, void *arg);
+#ifdef CONFIG_VIDEO_V4L1_COMPAT
+int v4l_compat_translate_ioctl(struct inode *inode, struct file *file,
+			       int cmd, void *arg, v4l2_kioctl driver_ioctl);
+#else
+#define v4l_compat_translate_ioctl(inode,file,cmd,arg,ioctl) -EINVAL
+#endif
+
+/* 32 Bits compatibility layer for 64 bits processors */
+extern long v4l_compat_ioctl32(struct file *file, unsigned int cmd,
+				unsigned long arg);
+
+/*
+ * Newer version of video_device, handled by videodev2.c
+ * 	This version moves redundant code from video device code to
+ *	the common handler
+ */
+struct v4l2_tvnorm {
+	char          *name;
+	v4l2_std_id   id;
+
+	void          *priv_data;
+};
+
+struct video_device
+{
+	/* device ops */
+	const struct file_operations *fops;
+
+	/* device info */
+	struct device *dev;
+	char name[32];
+	int type;       /* v4l1 */
+	int type2;      /* v4l2 */
+	int hardware;
+	int minor;
+
+	int debug;	/* Activates debug level*/
+
+	/* Video standard vars */
+	int tvnormsize;	/* Size of tvnorm array */
+	v4l2_std_id current_norm; /* Current tvnorm */
+	struct v4l2_tvnorm *tvnorms;
+
+	/* callbacks */
+	void (*release)(struct video_device *vfd);
+
+	/* ioctl callbacks */
+
+	/* VIDIOC_QUERYCAP handler */
+	int (*vidioc_querycap)(struct file *file, void *fh, struct v4l2_capability *cap);
+
+	/* Priority handling */
+	int (*vidioc_g_priority)   (struct file *file, void *fh,
+				    enum v4l2_priority *p);
+	int (*vidioc_s_priority)   (struct file *file, void *fh,
+				    enum v4l2_priority p);
+
+	/* VIDIOC_ENUM_FMT handlers */
+	int (*vidioc_enum_fmt_cap)         (struct file *file, void *fh,
+					    struct v4l2_fmtdesc *f);
+	int (*vidioc_enum_fmt_overlay)     (struct file *file, void *fh,
+					    struct v4l2_fmtdesc *f);
+	int (*vidioc_enum_fmt_vbi)         (struct file *file, void *fh,
+					    struct v4l2_fmtdesc *f);
+	int (*vidioc_enum_fmt_vbi_capture) (struct file *file, void *fh,
+					    struct v4l2_fmtdesc *f);
+	int (*vidioc_enum_fmt_video_output)(struct file *file, void *fh,
+					    struct v4l2_fmtdesc *f);
+	int (*vidioc_enum_fmt_vbi_output)  (struct file *file, void *fh,
+					    struct v4l2_fmtdesc *f);
+	int (*vidioc_enum_fmt_type_private)(struct file *file, void *fh,
+					    struct v4l2_fmtdesc *f);
+
+	/* VIDIOC_G_FMT handlers */
+	int (*vidioc_g_fmt_cap)        (struct file *file, void *fh,
+					struct v4l2_format *f);
+	int (*vidioc_g_fmt_overlay)    (struct file *file, void *fh,
+					struct v4l2_format *f);
+	int (*vidioc_g_fmt_vbi)        (struct file *file, void *fh,
+					struct v4l2_format *f);
+	int (*vidioc_g_fmt_vbi_output) (struct file *file, void *fh,
+					struct v4l2_format *f);
+	int (*vidioc_g_fmt_vbi_capture)(struct file *file, void *fh,
+					struct v4l2_format *f);
+	int (*vidioc_g_fmt_video_output)(struct file *file, void *fh,
+					struct v4l2_format *f);
+	int (*vidioc_g_fmt_type_private)(struct file *file, void *fh,
+					struct v4l2_format *f);
+
+	/* VIDIOC_S_FMT handlers */
+	int (*vidioc_s_fmt_cap)        (struct file *file, void *fh,
+					struct v4l2_format *f);
+
+	int (*vidioc_s_fmt_overlay)    (struct file *file, void *fh,
+					struct v4l2_format *f);
+	int (*vidioc_s_fmt_vbi)        (struct file *file, void *fh,
+					struct v4l2_format *f);
+	int (*vidioc_s_fmt_vbi_output) (struct file *file, void *fh,
+					struct v4l2_format *f);
+	int (*vidioc_s_fmt_vbi_capture)(struct file *file, void *fh,
+					struct v4l2_format *f);
+	int (*vidioc_s_fmt_video_output)(struct file *file, void *fh,
+					struct v4l2_format *f);
+	int (*vidioc_s_fmt_type_private)(struct file *file, void *fh,
+					struct v4l2_format *f);
+
+	/* VIDIOC_TRY_FMT handlers */
+	int (*vidioc_try_fmt_cap)        (struct file *file, void *fh,
+					  struct v4l2_format *f);
+	int (*vidioc_try_fmt_overlay)    (struct file *file, void *fh,
+					  struct v4l2_format *f);
+	int (*vidioc_try_fmt_vbi)        (struct file *file, void *fh,
+					  struct v4l2_format *f);
+	int (*vidioc_try_fmt_vbi_output) (struct file *file, void *fh,
+					  struct v4l2_format *f);
+	int (*vidioc_try_fmt_vbi_capture)(struct file *file, void *fh,
+					  struct v4l2_format *f);
+	int (*vidioc_try_fmt_video_output)(struct file *file, void *fh,
+					  struct v4l2_format *f);
+	int (*vidioc_try_fmt_type_private)(struct file *file, void *fh,
+					  struct v4l2_format *f);
+
+	/* Buffer handlers */
+	int (*vidioc_reqbufs) (struct file *file, void *fh, struct v4l2_requestbuffers *b);
+	int (*vidioc_querybuf)(struct file *file, void *fh, struct v4l2_buffer *b);
+	int (*vidioc_qbuf)    (struct file *file, void *fh, struct v4l2_buffer *b);
+	int (*vidioc_dqbuf)   (struct file *file, void *fh, struct v4l2_buffer *b);
+
+
+	int (*vidioc_overlay) (struct file *file, void *fh, unsigned int i);
+#ifdef CONFIG_VIDEO_V4L1_COMPAT
+			/* buffer type is struct vidio_mbuf * */
+	int (*vidiocgmbuf)  (struct file *file, void *fh, struct video_mbuf *p);
+#endif
+	int (*vidioc_g_fbuf)   (struct file *file, void *fh,
+				struct v4l2_framebuffer *a);
+	int (*vidioc_s_fbuf)   (struct file *file, void *fh,
+				struct v4l2_framebuffer *a);
+
+		/* Stream on/off */
+	int (*vidioc_streamon) (struct file *file, void *fh, enum v4l2_buf_type i);
+	int (*vidioc_streamoff)(struct file *file, void *fh, enum v4l2_buf_type i);
+
+		/* Standard handling
+			G_STD and ENUMSTD are handled by videodev.c
+		 */
+	int (*vidioc_s_std)    (struct file *file, void *fh, v4l2_std_id a);
+	int (*vidioc_querystd) (struct file *file, void *fh, v4l2_std_id *a);
+
+		/* Input handling */
+	int (*vidioc_enum_input)(struct file *file, void *fh,
+				 struct v4l2_input *inp);
+	int (*vidioc_g_input)   (struct file *file, void *fh, unsigned int *i);
+	int (*vidioc_s_input)   (struct file *file, void *fh, unsigned int i);
+
+		/* Output handling */
+	int (*vidioc_enumoutput) (struct file *file, void *fh,
+				  struct v4l2_output *a);
+	int (*vidioc_g_output)   (struct file *file, void *fh, unsigned int *i);
+	int (*vidioc_s_output)   (struct file *file, void *fh, unsigned int i);
+
+		/* Control handling */
+	int (*vidioc_queryctrl)        (struct file *file, void *fh,
+					struct v4l2_queryctrl *a);
+	int (*vidioc_g_ctrl)           (struct file *file, void *fh,
+					struct v4l2_control *a);
+	int (*vidioc_s_ctrl)           (struct file *file, void *fh,
+					struct v4l2_control *a);
+	int (*vidioc_g_ext_ctrls)      (struct file *file, void *fh,
+					struct v4l2_ext_controls *a);
+	int (*vidioc_s_ext_ctrls)      (struct file *file, void *fh,
+					struct v4l2_ext_controls *a);
+	int (*vidioc_try_ext_ctrls)    (struct file *file, void *fh,
+					struct v4l2_ext_controls *a);
+	int (*vidioc_querymenu)        (struct file *file, void *fh,
+					struct v4l2_querymenu *a);
+
+	/* Audio ioctls */
+	int (*vidioc_enumaudio)        (struct file *file, void *fh,
+					struct v4l2_audio *a);
+	int (*vidioc_g_audio)          (struct file *file, void *fh,
+					struct v4l2_audio *a);
+	int (*vidioc_s_audio)          (struct file *file, void *fh,
+					struct v4l2_audio *a);
+
+	/* Audio out ioctls */
+	int (*vidioc_enumaudout)       (struct file *file, void *fh,
+					struct v4l2_audioout *a);
+	int (*vidioc_g_audout)         (struct file *file, void *fh,
+					struct v4l2_audioout *a);
+	int (*vidioc_s_audout)         (struct file *file, void *fh,
+					struct v4l2_audioout *a);
+	int (*vidioc_g_modulator)      (struct file *file, void *fh,
+					struct v4l2_modulator *a);
+	int (*vidioc_s_modulator)      (struct file *file, void *fh,
+					struct v4l2_modulator *a);
+	/* Crop ioctls */
+	int (*vidioc_cropcap)          (struct file *file, void *fh,
+					struct v4l2_cropcap *a);
+	int (*vidioc_g_crop)           (struct file *file, void *fh,
+					struct v4l2_crop *a);
+	int (*vidioc_s_crop)           (struct file *file, void *fh,
+					struct v4l2_crop *a);
+	/* Compression ioctls */
+	int (*vidioc_g_mpegcomp)       (struct file *file, void *fh,
+					struct v4l2_mpeg_compression *a);
+	int (*vidioc_s_mpegcomp)       (struct file *file, void *fh,
+					struct v4l2_mpeg_compression *a);
+	int (*vidioc_g_jpegcomp)       (struct file *file, void *fh,
+					struct v4l2_jpegcompression *a);
+	int (*vidioc_s_jpegcomp)       (struct file *file, void *fh,
+					struct v4l2_jpegcompression *a);
+
+	/* Stream type-dependent parameter ioctls */
+	int (*vidioc_g_parm)           (struct file *file, void *fh,
+					struct v4l2_streamparm *a);
+	int (*vidioc_s_parm)           (struct file *file, void *fh,
+					struct v4l2_streamparm *a);
+
+	/* Tuner ioctls */
+	int (*vidioc_g_tuner)          (struct file *file, void *fh,
+					struct v4l2_tuner *a);
+	int (*vidioc_s_tuner)          (struct file *file, void *fh,
+					struct v4l2_tuner *a);
+	int (*vidioc_g_frequency)      (struct file *file, void *fh,
+					struct v4l2_frequency *a);
+	int (*vidioc_s_frequency)      (struct file *file, void *fh,
+					struct v4l2_frequency *a);
+
+	/* Sliced VBI cap */
+	int (*vidioc_g_sliced_vbi_cap) (struct file *file, void *fh,
+					struct v4l2_sliced_vbi_cap *a);
+
+	/* Log status ioctl */
+	int (*vidioc_log_status)       (struct file *file, void *fh);
+
+
+#ifdef OBSOLETE_OWNER /* to be removed soon */
+/* obsolete -- fops->owner is used instead */
+struct module *owner;
+/* dev->driver_data will be used instead some day.
+	* Use the video_{get|set}_drvdata() helper functions,
+	* so the switch over will be transparent for you.
+	* Or use {pci|usb}_{get|set}_drvdata() directly. */
+void *priv;
+#endif
+
+	/* for videodev.c intenal usage -- please don't touch */
+	int users;                     /* video_exclusive_{open|close} ... */
+	struct mutex lock;             /* ... helper function uses these   */
+	struct class_device class_dev; /* sysfs */
+};
+
+/* Version 2 functions */
+extern int video_register_device(struct video_device *vfd, int type, int nr);
+void video_unregister_device(struct video_device *);
+extern int video_ioctl2(struct inode *inode, struct file *file,
+			  unsigned int cmd, unsigned long arg);
+
+/* helper functions to alloc / release struct video_device, the
+   later can be used for video_device->release() */
+struct video_device *video_device_alloc(void);
+void video_device_release(struct video_device *vfd);
+
+/* Include support for obsoleted stuff */
+extern int video_usercopy(struct inode *inode, struct file *file,
+			  unsigned int cmd, unsigned long arg,
+			  int (*func)(struct inode *inode, struct file *file,
+				      unsigned int cmd, void *arg));
+
+
+#ifdef CONFIG_VIDEO_V4L1_COMPAT
+#include <linux/mm.h>
+
+extern struct video_device* video_devdata(struct file*);
+
+#define to_video_device(cd) container_of(cd, struct video_device, class_dev)
+static inline int
+video_device_create_file(struct video_device *vfd,
+			 struct class_device_attribute *attr)
+{
+	int ret = class_device_create_file(&vfd->class_dev, attr);
+	if (ret < 0)
+		printk(KERN_WARNING "%s error: %d\n", __FUNCTION__, ret);
+	return ret;
+}
+static inline void
+video_device_remove_file(struct video_device *vfd,
+			 struct class_device_attribute *attr)
+{
+	class_device_remove_file(&vfd->class_dev, attr);
+}
+
+#endif /* CONFIG_VIDEO_V4L1_COMPAT */
+
+#ifdef OBSOLETE_OWNER /* to be removed soon */
+/* helper functions to access driver private data. */
+static inline void *video_get_drvdata(struct video_device *dev)
+{
+	return dev->priv;
+}
+
+static inline void video_set_drvdata(struct video_device *dev, void *data)
+{
+	dev->priv = data;
+}
+#endif
+
+extern int video_exclusive_open(struct inode *inode, struct file *file);
+extern int video_exclusive_release(struct inode *inode, struct file *file);
+
+#endif /* _V4L2_DEV_H */
diff --git a/include/mtd/Kbuild b/include/mtd/Kbuild
new file mode 100644
index 000000000..13e7a3c6d
--- /dev/null
+++ b/include/mtd/Kbuild
@@ -0,0 +1,6 @@
+header-y += inftl-user.h
+header-y += jffs2-user.h
+header-y += mtd-user.h
+header-y += nftl-user.h
+
+unifdef-y += mtd-abi.h
diff --git a/include/net/netdma.h b/include/net/netdma.h
new file mode 100644
index 000000000..f28c6e064
--- /dev/null
+++ b/include/net/netdma.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright(c) 2004 - 2006 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59
+ * Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called COPYING.
+ */
+#ifndef NETDMA_H
+#define NETDMA_H
+#ifdef CONFIG_NET_DMA
+#include <linux/dmaengine.h>
+#include <linux/skbuff.h>
+
+static inline struct dma_chan *get_softnet_dma(void)
+{
+	struct dma_chan *chan;
+	rcu_read_lock();
+	chan = rcu_dereference(__get_cpu_var(softnet_data).net_dma);
+	if (chan)
+		dma_chan_get(chan);
+	rcu_read_unlock();
+	return chan;
+}
+
+int dma_skb_copy_datagram_iovec(struct dma_chan* chan,
+		struct sk_buff *skb, int offset, struct iovec *to,
+		size_t len, struct dma_pinned_list *pinned_list);
+
+#endif /* CONFIG_NET_DMA */
+#endif /* NETDMA_H */
diff --git a/include/net/netevent.h b/include/net/netevent.h
new file mode 100644
index 000000000..e5d216241
--- /dev/null
+++ b/include/net/netevent.h
@@ -0,0 +1,33 @@
+#ifndef _NET_EVENT_H
+#define _NET_EVENT_H
+
+/*
+ *	Generic netevent notifiers
+ *
+ *	Authors:
+ *      Tom Tucker              <tom@opengridcomputing.com>
+ *      Steve Wise              <swise@opengridcomputing.com>
+ *
+ * 	Changes:
+ */
+#ifdef __KERNEL__
+
+#include <net/dst.h>
+
+struct netevent_redirect {
+	struct dst_entry *old;
+	struct dst_entry *new;
+};
+
+enum netevent_notif_type {
+	NETEVENT_NEIGH_UPDATE = 1, /* arg is struct neighbour ptr */
+	NETEVENT_PMTU_UPDATE,	   /* arg is struct dst_entry ptr */
+	NETEVENT_REDIRECT,	   /* arg is struct netevent_redirect ptr */
+};
+
+extern int register_netevent_notifier(struct notifier_block *nb);
+extern int unregister_netevent_notifier(struct notifier_block *nb);
+extern int call_netevent_notifiers(unsigned long val, void *v);
+
+#endif
+#endif
diff --git a/include/rdma/Kbuild b/include/rdma/Kbuild
new file mode 100644
index 000000000..e7c043216
--- /dev/null
+++ b/include/rdma/Kbuild
@@ -0,0 +1 @@
+header-y += ib_user_mad.h
diff --git a/include/rdma/ib_addr.h b/include/rdma/ib_addr.h
new file mode 100644
index 000000000..0ff673989
--- /dev/null
+++ b/include/rdma/ib_addr.h
@@ -0,0 +1,116 @@
+/*
+ * Copyright (c) 2005 Voltaire Inc.  All rights reserved.
+ * Copyright (c) 2005 Intel Corporation.  All rights reserved.
+ *
+ * This Software is licensed under one of the following licenses:
+ *
+ * 1) under the terms of the "Common Public License 1.0" a copy of which is
+ *    available from the Open Source Initiative, see
+ *    http://www.opensource.org/licenses/cpl.php.
+ *
+ * 2) under the terms of the "The BSD License" a copy of which is
+ *    available from the Open Source Initiative, see
+ *    http://www.opensource.org/licenses/bsd-license.php.
+ *
+ * 3) under the terms of the "GNU General Public License (GPL) Version 2" a
+ *    copy of which is available from the Open Source Initiative, see
+ *    http://www.opensource.org/licenses/gpl-license.php.
+ *
+ * Licensee has the right to choose one of the above licenses.
+ *
+ * Redistributions of source code must retain the above copyright
+ * notice and one of the license notices.
+ *
+ * Redistributions in binary form must reproduce both the above copyright
+ * notice, one of the license notices in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ */
+
+#if !defined(IB_ADDR_H)
+#define IB_ADDR_H
+
+#include <linux/in.h>
+#include <linux/in6.h>
+#include <linux/netdevice.h>
+#include <linux/socket.h>
+#include <rdma/ib_verbs.h>
+
+struct rdma_dev_addr {
+	unsigned char src_dev_addr[MAX_ADDR_LEN];
+	unsigned char dst_dev_addr[MAX_ADDR_LEN];
+	unsigned char broadcast[MAX_ADDR_LEN];
+	enum ib_node_type dev_type;
+};
+
+/**
+ * rdma_translate_ip - Translate a local IP address to an RDMA hardware
+ *   address.
+ */
+int rdma_translate_ip(struct sockaddr *addr, struct rdma_dev_addr *dev_addr);
+
+/**
+ * rdma_resolve_ip - Resolve source and destination IP addresses to
+ *   RDMA hardware addresses.
+ * @src_addr: An optional source address to use in the resolution.  If a
+ *   source address is not provided, a usable address will be returned via
+ *   the callback.
+ * @dst_addr: The destination address to resolve.
+ * @addr: A reference to a data location that will receive the resolved
+ *   addresses.  The data location must remain valid until the callback has
+ *   been invoked.
+ * @timeout_ms: Amount of time to wait for the address resolution to complete.
+ * @callback: Call invoked once address resolution has completed, timed out,
+ *   or been canceled.  A status of 0 indicates success.
+ * @context: User-specified context associated with the call.
+ */
+int rdma_resolve_ip(struct sockaddr *src_addr, struct sockaddr *dst_addr,
+		    struct rdma_dev_addr *addr, int timeout_ms,
+		    void (*callback)(int status, struct sockaddr *src_addr,
+				     struct rdma_dev_addr *addr, void *context),
+		    void *context);
+
+void rdma_addr_cancel(struct rdma_dev_addr *addr);
+
+static inline int ip_addr_size(struct sockaddr *addr)
+{
+	return addr->sa_family == AF_INET6 ?
+	       sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in);
+}
+
+static inline u16 ib_addr_get_pkey(struct rdma_dev_addr *dev_addr)
+{
+	return ((u16)dev_addr->broadcast[8] << 8) | (u16)dev_addr->broadcast[9];
+}
+
+static inline void ib_addr_set_pkey(struct rdma_dev_addr *dev_addr, u16 pkey)
+{
+	dev_addr->broadcast[8] = pkey >> 8;
+	dev_addr->broadcast[9] = (unsigned char) pkey;
+}
+
+static inline void ib_addr_get_sgid(struct rdma_dev_addr *dev_addr,
+				    union ib_gid *gid)
+{
+	memcpy(gid, dev_addr->src_dev_addr + 4, sizeof *gid);
+}
+
+static inline void ib_addr_set_sgid(struct rdma_dev_addr *dev_addr,
+				    union ib_gid *gid)
+{
+	memcpy(dev_addr->src_dev_addr + 4, gid, sizeof *gid);
+}
+
+static inline void ib_addr_get_dgid(struct rdma_dev_addr *dev_addr,
+				    union ib_gid *gid)
+{
+	memcpy(gid, dev_addr->dst_dev_addr + 4, sizeof *gid);
+}
+
+static inline void ib_addr_set_dgid(struct rdma_dev_addr *dev_addr,
+				    union ib_gid *gid)
+{
+	memcpy(dev_addr->dst_dev_addr + 4, gid, sizeof *gid);
+}
+
+#endif /* IB_ADDR_H */
diff --git a/include/rdma/ib_marshall.h b/include/rdma/ib_marshall.h
new file mode 100644
index 000000000..66bf4d7d0
--- /dev/null
+++ b/include/rdma/ib_marshall.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2005 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.
+ */
+
+#if !defined(IB_USER_MARSHALL_H)
+#define IB_USER_MARSHALL_H
+
+#include <rdma/ib_verbs.h>
+#include <rdma/ib_sa.h>
+#include <rdma/ib_user_verbs.h>
+#include <rdma/ib_user_sa.h>
+
+void ib_copy_qp_attr_to_user(struct ib_uverbs_qp_attr *dst,
+			     struct ib_qp_attr *src);
+
+void ib_copy_path_rec_to_user(struct ib_user_path_rec *dst,
+			      struct ib_sa_path_rec *src);
+
+void ib_copy_path_rec_from_user(struct ib_sa_path_rec *dst,
+				struct ib_user_path_rec *src);
+
+#endif /* IB_USER_MARSHALL_H */
diff --git a/include/rdma/ib_user_sa.h b/include/rdma/ib_user_sa.h
new file mode 100644
index 000000000..659120157
--- /dev/null
+++ b/include/rdma/ib_user_sa.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2005 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 IB_USER_SA_H
+#define IB_USER_SA_H
+
+#include <linux/types.h>
+
+struct ib_user_path_rec {
+	__u8	dgid[16];
+	__u8	sgid[16];
+	__be16	dlid;
+	__be16	slid;
+	__u32	raw_traffic;
+	__be32	flow_label;
+	__u32	reversible;
+	__u32	mtu;
+	__be16	pkey;
+	__u8	hop_limit;
+	__u8	traffic_class;
+	__u8	numb_path;
+	__u8	sl;
+	__u8	mtu_selector;
+	__u8	rate_selector;
+	__u8	rate;
+	__u8	packet_life_time_selector;
+	__u8	packet_life_time;
+	__u8	preference;
+};
+
+#endif /* IB_USER_SA_H */
diff --git a/include/rdma/rdma_cm.h b/include/rdma/rdma_cm.h
new file mode 100644
index 000000000..402c63d72
--- /dev/null
+++ b/include/rdma/rdma_cm.h
@@ -0,0 +1,256 @@
+/*
+ * Copyright (c) 2005 Voltaire Inc.  All rights reserved.
+ * Copyright (c) 2005 Intel Corporation.  All rights reserved.
+ *
+ * This Software is licensed under one of the following licenses:
+ *
+ * 1) under the terms of the "Common Public License 1.0" a copy of which is
+ *    available from the Open Source Initiative, see
+ *    http://www.opensource.org/licenses/cpl.php.
+ *
+ * 2) under the terms of the "The BSD License" a copy of which is
+ *    available from the Open Source Initiative, see
+ *    http://www.opensource.org/licenses/bsd-license.php.
+ *
+ * 3) under the terms of the "GNU General Public License (GPL) Version 2" a
+ *    copy of which is available from the Open Source Initiative, see
+ *    http://www.opensource.org/licenses/gpl-license.php.
+ *
+ * Licensee has the right to choose one of the above licenses.
+ *
+ * Redistributions of source code must retain the above copyright
+ * notice and one of the license notices.
+ *
+ * Redistributions in binary form must reproduce both the above copyright
+ * notice, one of the license notices in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ */
+
+#if !defined(RDMA_CM_H)
+#define RDMA_CM_H
+
+#include <linux/socket.h>
+#include <linux/in6.h>
+#include <rdma/ib_addr.h>
+#include <rdma/ib_sa.h>
+
+/*
+ * Upon receiving a device removal event, users must destroy the associated
+ * RDMA identifier and release all resources allocated with the device.
+ */
+enum rdma_cm_event_type {
+	RDMA_CM_EVENT_ADDR_RESOLVED,
+	RDMA_CM_EVENT_ADDR_ERROR,
+	RDMA_CM_EVENT_ROUTE_RESOLVED,
+	RDMA_CM_EVENT_ROUTE_ERROR,
+	RDMA_CM_EVENT_CONNECT_REQUEST,
+	RDMA_CM_EVENT_CONNECT_RESPONSE,
+	RDMA_CM_EVENT_CONNECT_ERROR,
+	RDMA_CM_EVENT_UNREACHABLE,
+	RDMA_CM_EVENT_REJECTED,
+	RDMA_CM_EVENT_ESTABLISHED,
+	RDMA_CM_EVENT_DISCONNECTED,
+	RDMA_CM_EVENT_DEVICE_REMOVAL,
+};
+
+enum rdma_port_space {
+	RDMA_PS_SDP  = 0x0001,
+	RDMA_PS_TCP  = 0x0106,
+	RDMA_PS_UDP  = 0x0111,
+	RDMA_PS_SCTP = 0x0183
+};
+
+struct rdma_addr {
+	struct sockaddr src_addr;
+	u8		src_pad[sizeof(struct sockaddr_in6) -
+				sizeof(struct sockaddr)];
+	struct sockaddr dst_addr;
+	u8		dst_pad[sizeof(struct sockaddr_in6) -
+				sizeof(struct sockaddr)];
+	struct rdma_dev_addr dev_addr;
+};
+
+struct rdma_route {
+	struct rdma_addr addr;
+	struct ib_sa_path_rec *path_rec;
+	int num_paths;
+};
+
+struct rdma_cm_event {
+	enum rdma_cm_event_type	 event;
+	int			 status;
+	void			*private_data;
+	u8			 private_data_len;
+};
+
+struct rdma_cm_id;
+
+/**
+ * rdma_cm_event_handler - Callback used to report user events.
+ *
+ * Notes: Users may not call rdma_destroy_id from this callback to destroy
+ *   the passed in id, or a corresponding listen id.  Returning a
+ *   non-zero value from the callback will destroy the passed in id.
+ */
+typedef int (*rdma_cm_event_handler)(struct rdma_cm_id *id,
+				     struct rdma_cm_event *event);
+
+struct rdma_cm_id {
+	struct ib_device	*device;
+	void			*context;
+	struct ib_qp		*qp;
+	rdma_cm_event_handler	 event_handler;
+	struct rdma_route	 route;
+	enum rdma_port_space	 ps;
+	u8			 port_num;
+};
+
+/**
+ * rdma_create_id - Create an RDMA identifier.
+ *
+ * @event_handler: User callback invoked to report events associated with the
+ *   returned rdma_id.
+ * @context: User specified context associated with the id.
+ * @ps: RDMA port space.
+ */
+struct rdma_cm_id *rdma_create_id(rdma_cm_event_handler event_handler,
+				  void *context, enum rdma_port_space ps);
+
+void rdma_destroy_id(struct rdma_cm_id *id);
+
+/**
+ * rdma_bind_addr - Bind an RDMA identifier to a source address and
+ *   associated RDMA device, if needed.
+ *
+ * @id: RDMA identifier.
+ * @addr: Local address information.  Wildcard values are permitted.
+ *
+ * This associates a source address with the RDMA identifier before calling
+ * rdma_listen.  If a specific local address is given, the RDMA identifier will
+ * be bound to a local RDMA device.
+ */
+int rdma_bind_addr(struct rdma_cm_id *id, struct sockaddr *addr);
+
+/**
+ * rdma_resolve_addr - Resolve destination and optional source addresses
+ *   from IP addresses to an RDMA address.  If successful, the specified
+ *   rdma_cm_id will be bound to a local device.
+ *
+ * @id: RDMA identifier.
+ * @src_addr: Source address information.  This parameter may be NULL.
+ * @dst_addr: Destination address information.
+ * @timeout_ms: Time to wait for resolution to complete.
+ */
+int rdma_resolve_addr(struct rdma_cm_id *id, struct sockaddr *src_addr,
+		      struct sockaddr *dst_addr, int timeout_ms);
+
+/**
+ * rdma_resolve_route - Resolve the RDMA address bound to the RDMA identifier
+ *   into route information needed to establish a connection.
+ *
+ * This is called on the client side of a connection.
+ * Users must have first called rdma_resolve_addr to resolve a dst_addr
+ * into an RDMA address before calling this routine.
+ */
+int rdma_resolve_route(struct rdma_cm_id *id, int timeout_ms);
+
+/**
+ * rdma_create_qp - Allocate a QP and associate it with the specified RDMA
+ * identifier.
+ *
+ * QPs allocated to an rdma_cm_id will automatically be transitioned by the CMA
+ * through their states.
+ */
+int rdma_create_qp(struct rdma_cm_id *id, struct ib_pd *pd,
+		   struct ib_qp_init_attr *qp_init_attr);
+
+/**
+ * rdma_destroy_qp - Deallocate the QP associated with the specified RDMA
+ * identifier.
+ *
+ * Users must destroy any QP associated with an RDMA identifier before
+ * destroying the RDMA ID.
+ */
+void rdma_destroy_qp(struct rdma_cm_id *id);
+
+/**
+ * rdma_init_qp_attr - Initializes the QP attributes for use in transitioning
+ *   to a specified QP state.
+ * @id: Communication identifier associated with the QP attributes to
+ *   initialize.
+ * @qp_attr: On input, specifies the desired QP state.  On output, the
+ *   mandatory and desired optional attributes will be set in order to
+ *   modify the QP to the specified state.
+ * @qp_attr_mask: The QP attribute mask that may be used to transition the
+ *   QP to the specified state.
+ *
+ * Users must set the @qp_attr->qp_state to the desired QP state.  This call
+ * will set all required attributes for the given transition, along with
+ * known optional attributes.  Users may override the attributes returned from
+ * this call before calling ib_modify_qp.
+ *
+ * Users that wish to have their QP automatically transitioned through its
+ * states can associate a QP with the rdma_cm_id by calling rdma_create_qp().
+ */
+int rdma_init_qp_attr(struct rdma_cm_id *id, struct ib_qp_attr *qp_attr,
+		       int *qp_attr_mask);
+
+struct rdma_conn_param {
+	const void *private_data;
+	u8 private_data_len;
+	u8 responder_resources;
+	u8 initiator_depth;
+	u8 flow_control;
+	u8 retry_count;		/* ignored when accepting */
+	u8 rnr_retry_count;
+	/* Fields below ignored if a QP is created on the rdma_cm_id. */
+	u8 srq;
+	u32 qp_num;
+	enum ib_qp_type qp_type;
+};
+
+/**
+ * rdma_connect - Initiate an active connection request.
+ *
+ * Users must have resolved a route for the rdma_cm_id to connect with
+ * by having called rdma_resolve_route before calling this routine.
+ */
+int rdma_connect(struct rdma_cm_id *id, struct rdma_conn_param *conn_param);
+
+/**
+ * rdma_listen - This function is called by the passive side to
+ *   listen for incoming connection requests.
+ *
+ * Users must have bound the rdma_cm_id to a local address by calling
+ * rdma_bind_addr before calling this routine.
+ */
+int rdma_listen(struct rdma_cm_id *id, int backlog);
+
+/**
+ * rdma_accept - Called to accept a connection request or response.
+ * @id: Connection identifier associated with the request.
+ * @conn_param: Information needed to establish the connection.  This must be
+ *   provided if accepting a connection request.  If accepting a connection
+ *   response, this parameter must be NULL.
+ *
+ * Typically, this routine is only called by the listener to accept a connection
+ * request.  It must also be called on the active side of a connection if the
+ * user is performing their own QP transitions.
+ */
+int rdma_accept(struct rdma_cm_id *id, struct rdma_conn_param *conn_param);
+
+/**
+ * rdma_reject - Called to reject a connection request or response.
+ */
+int rdma_reject(struct rdma_cm_id *id, const void *private_data,
+		u8 private_data_len);
+
+/**
+ * rdma_disconnect - This function disconnects the associated QP and
+ *   transitions it into the error state.
+ */
+int rdma_disconnect(struct rdma_cm_id *id);
+
+#endif /* RDMA_CM_H */
+
diff --git a/include/rdma/rdma_cm_ib.h b/include/rdma/rdma_cm_ib.h
new file mode 100644
index 000000000..e8c3af180
--- /dev/null
+++ b/include/rdma/rdma_cm_ib.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2006 Intel Corporation.  All rights reserved.
+ *
+ * This Software is licensed under one of the following licenses:
+ *
+ * 1) under the terms of the "Common Public License 1.0" a copy of which is
+ *    available from the Open Source Initiative, see
+ *    http://www.opensource.org/licenses/cpl.php.
+ *
+ * 2) under the terms of the "The BSD License" a copy of which is
+ *    available from the Open Source Initiative, see
+ *    http://www.opensource.org/licenses/bsd-license.php.
+ *
+ * 3) under the terms of the "GNU General Public License (GPL) Version 2" a
+ *    copy of which is available from the Open Source Initiative, see
+ *    http://www.opensource.org/licenses/gpl-license.php.
+ *
+ * Licensee has the right to choose one of the above licenses.
+ *
+ * Redistributions of source code must retain the above copyright
+ * notice and one of the license notices.
+ *
+ * Redistributions in binary form must reproduce both the above copyright
+ * notice, one of the license notices in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ */
+
+#if !defined(RDMA_CM_IB_H)
+#define RDMA_CM_IB_H
+
+#include <rdma/rdma_cm.h>
+
+/**
+ * rdma_set_ib_paths - Manually sets the path records used to establish a
+ *   connection.
+ * @id: Connection identifier associated with the request.
+ * @path_rec: Reference to the path record
+ *
+ * This call permits a user to specify routing information for rdma_cm_id's
+ * bound to Infiniband devices.  It is called on the client side of a
+ * connection and replaces the call to rdma_resolve_route.
+ */
+int rdma_set_ib_paths(struct rdma_cm_id *id,
+		      struct ib_sa_path_rec *path_rec, int num_paths);
+
+#endif /* RDMA_CM_IB_H */
diff --git a/include/scsi/Kbuild b/include/scsi/Kbuild
new file mode 100644
index 000000000..744f85011
--- /dev/null
+++ b/include/scsi/Kbuild
@@ -0,0 +1,4 @@
+header-y += scsi.h
+
+unifdef-y += scsi_ioctl.h
+unifdef-y += sg.h
diff --git a/include/sound/Kbuild b/include/sound/Kbuild
new file mode 100644
index 000000000..fd054a344
--- /dev/null
+++ b/include/sound/Kbuild
@@ -0,0 +1,10 @@
+header-y += asound_fm.h
+header-y += hdsp.h
+header-y += hdspm.h
+header-y += sfnt_info.h
+header-y += sscape_ioctl.h
+
+unifdef-y += asequencer.h
+unifdef-y += asound.h
+unifdef-y += emu10k1.h
+unifdef-y += sb16_csp.h
diff --git a/include/video/Kbuild b/include/video/Kbuild
new file mode 100644
index 000000000..a14f9c045
--- /dev/null
+++ b/include/video/Kbuild
@@ -0,0 +1 @@
+unifdef-y += sisfb.h
diff --git a/include/video/mbxfb.h b/include/video/mbxfb.h
new file mode 100644
index 000000000..3bde0f5cd
--- /dev/null
+++ b/include/video/mbxfb.h
@@ -0,0 +1,28 @@
+#ifndef __MBX_FB_H
+#define __MBX_FB_H
+
+struct mbxfb_val {
+	unsigned int	defval;
+	unsigned int	min;
+	unsigned int	max;
+};
+
+struct fb_info;
+
+struct mbxfb_platform_data {
+		/* Screen info */
+		struct mbxfb_val xres;
+		struct mbxfb_val yres;
+		struct mbxfb_val bpp;
+
+		/* Memory info */
+		unsigned long memsize; /* if 0 use ODFB? */
+		unsigned long timings1;
+		unsigned long timings2;
+		unsigned long timings3;
+
+		int (*probe)(struct fb_info *fb);
+		int (*remove)(struct fb_info *fb);
+};
+
+#endif /* __MBX_FB_H */
diff --git a/include/xen/hvm.h b/include/xen/hvm.h
new file mode 100644
index 000000000..97bb68a32
--- /dev/null
+++ b/include/xen/hvm.h
@@ -0,0 +1,24 @@
+/* Simple wrappers around HVM functions */
+#ifndef XEN_HVM_H__
+#define XEN_HVM_H__
+
+#include <xen/interface/hvm/params.h>
+#include <asm/hypercall.h>
+
+static inline unsigned long hvm_get_parameter(int idx)
+{
+	struct xen_hvm_param xhv;
+	int r;
+
+	xhv.domid = DOMID_SELF;
+	xhv.index = idx;
+	r = HYPERVISOR_hvm_op(HVMOP_get_param, &xhv);
+	if (r < 0) {
+		printk(KERN_ERR "cannot get hvm parameter %d: %d.\n",
+		       idx, r);
+		return 0;
+	}
+	return xhv.value;
+}
+
+#endif /* XEN_HVM_H__ */
diff --git a/include/xen/interface/arch-ia64.h b/include/xen/interface/arch-ia64.h
new file mode 100644
index 000000000..98bda1d24
--- /dev/null
+++ b/include/xen/interface/arch-ia64.h
@@ -0,0 +1,448 @@
+/******************************************************************************
+ * arch-ia64/hypervisor-if.h
+ * 
+ * Guest OS interface to IA64 Xen.
+ */
+
+#ifndef __HYPERVISOR_IF_IA64_H__
+#define __HYPERVISOR_IF_IA64_H__
+
+/* Structural guest handles introduced in 0x00030201. */
+#if __XEN_INTERFACE_VERSION__ >= 0x00030201
+#define __DEFINE_XEN_GUEST_HANDLE(name, type) \
+    typedef struct { type *p; } __guest_handle_ ## name
+#else
+#define __DEFINE_XEN_GUEST_HANDLE(name, type) \
+    typedef type * __guest_handle_ ## name
+#endif
+
+#define DEFINE_XEN_GUEST_HANDLE(name)   __DEFINE_XEN_GUEST_HANDLE(name, name)
+#define XEN_GUEST_HANDLE(name)          __guest_handle_ ## name
+#define set_xen_guest_handle(hnd, val)  do { (hnd).p = val; } while (0)
+#ifdef __XEN_TOOLS__
+#define get_xen_guest_handle(val, hnd)  do { val = (hnd).p; } while (0)
+#endif
+
+#ifndef __ASSEMBLY__
+/* Guest handles for primitive C types. */
+__DEFINE_XEN_GUEST_HANDLE(uchar, unsigned char);
+__DEFINE_XEN_GUEST_HANDLE(uint,  unsigned int);
+__DEFINE_XEN_GUEST_HANDLE(ulong, unsigned long);
+DEFINE_XEN_GUEST_HANDLE(char);
+DEFINE_XEN_GUEST_HANDLE(int);
+DEFINE_XEN_GUEST_HANDLE(long);
+DEFINE_XEN_GUEST_HANDLE(void);
+
+typedef unsigned long xen_pfn_t;
+DEFINE_XEN_GUEST_HANDLE(xen_pfn_t);
+#endif
+
+/* Arch specific VIRQs definition */
+#define VIRQ_ITC        VIRQ_ARCH_0 /* V. Virtual itc timer */
+
+/* Maximum number of virtual CPUs in multi-processor guests. */
+/* WARNING: before changing this, check that shared_info fits on a page */
+#define MAX_VIRT_CPUS 64
+
+#ifndef __ASSEMBLY__
+
+typedef unsigned long xen_ulong_t;
+
+#define GPFN_MEM          (0UL << 56) /* Guest pfn is normal mem */
+#define GPFN_FRAME_BUFFER (1UL << 56) /* VGA framebuffer */
+#define GPFN_LOW_MMIO     (2UL << 56) /* Low MMIO range */
+#define GPFN_PIB          (3UL << 56) /* PIB base */
+#define GPFN_IOSAPIC      (4UL << 56) /* IOSAPIC base */
+#define GPFN_LEGACY_IO    (5UL << 56) /* Legacy I/O base */
+#define GPFN_GFW          (6UL << 56) /* Guest Firmware */
+#define GPFN_HIGH_MMIO    (7UL << 56) /* High MMIO range */
+
+#define GPFN_IO_MASK     (7UL << 56)  /* Guest pfn is I/O type */
+#define GPFN_INV_MASK    (31UL << 59) /* Guest pfn is invalid */
+
+#define INVALID_MFN       (~0UL)
+
+#define MEM_G   (1UL << 30)
+#define MEM_M   (1UL << 20)
+
+#define MMIO_START       (3 * MEM_G)
+#define MMIO_SIZE        (512 * MEM_M)
+
+#define VGA_IO_START     0xA0000UL
+#define VGA_IO_SIZE      0x20000
+
+#define LEGACY_IO_START  (MMIO_START + MMIO_SIZE)
+#define LEGACY_IO_SIZE   (64*MEM_M)
+
+#define IO_PAGE_START (LEGACY_IO_START + LEGACY_IO_SIZE)
+#define IO_PAGE_SIZE  PAGE_SIZE
+
+#define STORE_PAGE_START (IO_PAGE_START + IO_PAGE_SIZE)
+#define STORE_PAGE_SIZE	 PAGE_SIZE
+
+#define IO_SAPIC_START   0xfec00000UL
+#define IO_SAPIC_SIZE    0x100000
+
+#define PIB_START 0xfee00000UL
+#define PIB_SIZE 0x200000
+
+#define GFW_START        (4*MEM_G -16*MEM_M)
+#define GFW_SIZE         (16*MEM_M)
+
+struct pt_fpreg {
+    union {
+        unsigned long bits[2];
+        long double __dummy;    /* force 16-byte alignment */
+    } u;
+};
+
+struct cpu_user_regs {
+    /* The following registers are saved by SAVE_MIN: */
+    unsigned long b6;  /* scratch */
+    unsigned long b7;  /* scratch */
+
+    unsigned long ar_csd; /* used by cmp8xchg16 (scratch) */
+    unsigned long ar_ssd; /* reserved for future use (scratch) */
+
+    unsigned long r8;  /* scratch (return value register 0) */
+    unsigned long r9;  /* scratch (return value register 1) */
+    unsigned long r10; /* scratch (return value register 2) */
+    unsigned long r11; /* scratch (return value register 3) */
+
+    unsigned long cr_ipsr; /* interrupted task's psr */
+    unsigned long cr_iip;  /* interrupted task's instruction pointer */
+    unsigned long cr_ifs;  /* interrupted task's function state */
+
+    unsigned long ar_unat; /* interrupted task's NaT register (preserved) */
+    unsigned long ar_pfs;  /* prev function state  */
+    unsigned long ar_rsc;  /* RSE configuration */
+    /* The following two are valid only if cr_ipsr.cpl > 0: */
+    unsigned long ar_rnat;  /* RSE NaT */
+    unsigned long ar_bspstore; /* RSE bspstore */
+
+    unsigned long pr;  /* 64 predicate registers (1 bit each) */
+    unsigned long b0;  /* return pointer (bp) */
+    unsigned long loadrs;  /* size of dirty partition << 16 */
+
+    unsigned long r1;  /* the gp pointer */
+    unsigned long r12; /* interrupted task's memory stack pointer */
+    unsigned long r13; /* thread pointer */
+
+    unsigned long ar_fpsr;  /* floating point status (preserved) */
+    unsigned long r15;  /* scratch */
+
+ /* The remaining registers are NOT saved for system calls.  */
+
+    unsigned long r14;  /* scratch */
+    unsigned long r2;  /* scratch */
+    unsigned long r3;  /* scratch */
+    unsigned long r16;  /* scratch */
+    unsigned long r17;  /* scratch */
+    unsigned long r18;  /* scratch */
+    unsigned long r19;  /* scratch */
+    unsigned long r20;  /* scratch */
+    unsigned long r21;  /* scratch */
+    unsigned long r22;  /* scratch */
+    unsigned long r23;  /* scratch */
+    unsigned long r24;  /* scratch */
+    unsigned long r25;  /* scratch */
+    unsigned long r26;  /* scratch */
+    unsigned long r27;  /* scratch */
+    unsigned long r28;  /* scratch */
+    unsigned long r29;  /* scratch */
+    unsigned long r30;  /* scratch */
+    unsigned long r31;  /* scratch */
+    unsigned long ar_ccv;  /* compare/exchange value (scratch) */
+
+    /*
+     * Floating point registers that the kernel considers scratch:
+     */
+    struct pt_fpreg f6;  /* scratch */
+    struct pt_fpreg f7;  /* scratch */
+    struct pt_fpreg f8;  /* scratch */
+    struct pt_fpreg f9;  /* scratch */
+    struct pt_fpreg f10;  /* scratch */
+    struct pt_fpreg f11;  /* scratch */
+    unsigned long r4;  /* preserved */
+    unsigned long r5;  /* preserved */
+    unsigned long r6;  /* preserved */
+    unsigned long r7;  /* preserved */
+    unsigned long eml_unat;    /* used for emulating instruction */
+    unsigned long pad0;     /* alignment pad */
+
+};
+typedef struct cpu_user_regs cpu_user_regs_t;
+
+union vac {
+    unsigned long value;
+    struct {
+        int a_int:1;
+        int a_from_int_cr:1;
+        int a_to_int_cr:1;
+        int a_from_psr:1;
+        int a_from_cpuid:1;
+        int a_cover:1;
+        int a_bsw:1;
+        long reserved:57;
+    };
+};
+typedef union vac vac_t;
+
+union vdc {
+    unsigned long value;
+    struct {
+        int d_vmsw:1;
+        int d_extint:1;
+        int d_ibr_dbr:1;
+        int d_pmc:1;
+        int d_to_pmd:1;
+        int d_itm:1;
+        long reserved:58;
+    };
+};
+typedef union vdc vdc_t;
+
+struct mapped_regs {
+    union vac   vac;
+    union vdc   vdc;
+    unsigned long  virt_env_vaddr;
+    unsigned long  reserved1[29];
+    unsigned long  vhpi;
+    unsigned long  reserved2[95];
+    union {
+        unsigned long  vgr[16];
+        unsigned long bank1_regs[16]; // bank1 regs (r16-r31) when bank0 active
+    };
+    union {
+        unsigned long  vbgr[16];
+        unsigned long bank0_regs[16]; // bank0 regs (r16-r31) when bank1 active
+    };
+    unsigned long  vnat;
+    unsigned long  vbnat;
+    unsigned long  vcpuid[5];
+    unsigned long  reserved3[11];
+    unsigned long  vpsr;
+    unsigned long  vpr;
+    unsigned long  reserved4[76];
+    union {
+        unsigned long  vcr[128];
+        struct {
+            unsigned long dcr;  // CR0
+            unsigned long itm;
+            unsigned long iva;
+            unsigned long rsv1[5];
+            unsigned long pta;  // CR8
+            unsigned long rsv2[7];
+            unsigned long ipsr;  // CR16
+            unsigned long isr;
+            unsigned long rsv3;
+            unsigned long iip;
+            unsigned long ifa;
+            unsigned long itir;
+            unsigned long iipa;
+            unsigned long ifs;
+            unsigned long iim;  // CR24
+            unsigned long iha;
+            unsigned long rsv4[38];
+            unsigned long lid;  // CR64
+            unsigned long ivr;
+            unsigned long tpr;
+            unsigned long eoi;
+            unsigned long irr[4];
+            unsigned long itv;  // CR72
+            unsigned long pmv;
+            unsigned long cmcv;
+            unsigned long rsv5[5];
+            unsigned long lrr0;  // CR80
+            unsigned long lrr1;
+            unsigned long rsv6[46];
+        };
+    };
+    union {
+        unsigned long  reserved5[128];
+        struct {
+            unsigned long precover_ifs;
+            unsigned long unat;  // not sure if this is needed until NaT arch is done
+            int interrupt_collection_enabled; // virtual psr.ic
+            /* virtual interrupt deliverable flag is evtchn_upcall_mask in
+             * shared info area now. interrupt_mask_addr is the address
+             * of evtchn_upcall_mask for current vcpu
+             */
+            unsigned char *interrupt_mask_addr;
+            int pending_interruption;
+            int incomplete_regframe; // see SDM vol2 6.8
+            unsigned char vpsr_pp;
+            unsigned char reserved5_2[7];
+            unsigned long reserved5_1[3];
+            int metaphysical_mode; // 1 = use metaphys mapping, 0 = use virtual
+            int banknum; // 0 or 1, which virtual register bank is active
+            unsigned long rrs[8]; // region registers
+            unsigned long krs[8]; // kernel registers
+            unsigned long pkrs[8]; // protection key registers
+            unsigned long tmp[8]; // temp registers (e.g. for hyperprivops)
+        };
+    };
+};
+typedef struct mapped_regs mapped_regs_t;
+
+struct vpd {
+    struct mapped_regs vpd_low;
+    unsigned long  reserved6[3456];
+    unsigned long  vmm_avail[128];
+    unsigned long  reserved7[4096];
+};
+typedef struct vpd vpd_t;
+
+struct arch_vcpu_info {
+};
+typedef struct arch_vcpu_info arch_vcpu_info_t;
+
+struct arch_shared_info {
+    /* PFN of the start_info page.  */
+    unsigned long start_info_pfn;
+
+    /* Interrupt vector for event channel.  */
+    int evtchn_vector;
+
+    uint64_t pad[32];
+};
+typedef struct arch_shared_info arch_shared_info_t;
+
+typedef unsigned long xen_callback_t;
+
+struct ia64_tr_entry {
+    unsigned long pte;
+    unsigned long itir;
+    unsigned long vadr;
+    unsigned long rid;
+};
+
+struct vcpu_extra_regs {
+    struct ia64_tr_entry itrs[8];
+    struct ia64_tr_entry dtrs[8];
+    unsigned long iva;
+    unsigned long dcr;
+    unsigned long event_callback_ip;
+};
+
+struct vcpu_guest_context {
+#define VGCF_EXTRA_REGS (1<<1)	/* Get/Set extra regs.  */
+    unsigned long flags;       /* VGCF_* flags */
+
+    struct cpu_user_regs user_regs;
+    struct vcpu_extra_regs extra_regs;
+    unsigned long privregs_pfn;
+};
+typedef struct vcpu_guest_context vcpu_guest_context_t;
+DEFINE_XEN_GUEST_HANDLE(vcpu_guest_context_t);
+
+// dom0 vp op
+#define __HYPERVISOR_ia64_dom0vp_op     __HYPERVISOR_arch_0
+#define IA64_DOM0VP_ioremap             0       // map io space in machine
+                                                // address to dom0 physical
+                                                // address space.
+                                                // currently physical
+                                                // assignedg address equals to
+                                                // machine address
+#define IA64_DOM0VP_phystomach          1       // convert a pseudo physical
+                                                // page frame number
+                                                // to the corresponding
+                                                // machine page frame number.
+                                                // if no page is assigned,
+                                                // INVALID_MFN or GPFN_INV_MASK
+                                                // is returned depending on
+                                                // domain's non-vti/vti mode.
+#define IA64_DOM0VP_machtophys          3       // convert a machine page
+                                                // frame number
+                                                // to the corresponding
+                                                // pseudo physical page frame
+                                                // number of the caller domain
+#define IA64_DOM0VP_zap_physmap         17      // unmap and free pages
+                                                // contained in the specified
+                                                // pseudo physical region
+#define IA64_DOM0VP_add_physmap         18      // assigne machine page frane
+                                                // to dom0's pseudo physical
+                                                // address space.
+// flags for page assignement to pseudo physical address space
+#define _ASSIGN_readonly                0
+#define ASSIGN_readonly                 (1UL << _ASSIGN_readonly)
+#define ASSIGN_writable                 (0UL << _ASSIGN_readonly) // dummy flag
+/* Internal only: memory attribute must be WC/UC/UCE.  */
+#define _ASSIGN_nocache                 1
+#define ASSIGN_nocache                  (1UL << _ASSIGN_nocache)
+
+/* This structure has the same layout of struct ia64_boot_param, defined in
+   <asm/system.h>.  It is redefined here to ease use.  */
+struct xen_ia64_boot_param {
+	unsigned long command_line;	/* physical address of cmd line args */
+	unsigned long efi_systab;	/* physical address of EFI system table */
+	unsigned long efi_memmap;	/* physical address of EFI memory map */
+	unsigned long efi_memmap_size;	/* size of EFI memory map */
+	unsigned long efi_memdesc_size;	/* size of an EFI memory map descriptor */
+	unsigned int  efi_memdesc_version;	/* memory descriptor version */
+	struct {
+		unsigned short num_cols;	/* number of columns on console.  */
+		unsigned short num_rows;	/* number of rows on console.  */
+		unsigned short orig_x;	/* cursor's x position */
+		unsigned short orig_y;	/* cursor's y position */
+	} console_info;
+	unsigned long fpswa;		/* physical address of the fpswa interface */
+	unsigned long initrd_start;
+	unsigned long initrd_size;
+	unsigned long domain_start;	/* va where the boot time domain begins */
+	unsigned long domain_size;	/* how big is the boot domain */
+};
+
+#endif /* !__ASSEMBLY__ */
+
+/* Address of shared_info in domain virtual space.
+   This is the default address, for compatibility only.  */
+#define XSI_BASE			0xf100000000000000
+
+/* Size of the shared_info area (this is not related to page size).  */
+#define XSI_SHIFT			14
+#define XSI_SIZE			(1 << XSI_SHIFT)
+/* Log size of mapped_regs area (64 KB - only 4KB is used).  */
+#define XMAPPEDREGS_SHIFT		12
+/* Offset of XASI (Xen arch shared info) wrt XSI_BASE.  */
+#define XMAPPEDREGS_OFS			XSI_SIZE
+
+/* Hyperprivops.  */
+#define HYPERPRIVOP_RFI			0x1
+#define HYPERPRIVOP_RSM_DT		0x2
+#define HYPERPRIVOP_SSM_DT		0x3
+#define HYPERPRIVOP_COVER		0x4
+#define HYPERPRIVOP_ITC_D		0x5
+#define HYPERPRIVOP_ITC_I		0x6
+#define HYPERPRIVOP_SSM_I		0x7
+#define HYPERPRIVOP_GET_IVR		0x8
+#define HYPERPRIVOP_GET_TPR		0x9
+#define HYPERPRIVOP_SET_TPR		0xa
+#define HYPERPRIVOP_EOI			0xb
+#define HYPERPRIVOP_SET_ITM		0xc
+#define HYPERPRIVOP_THASH		0xd
+#define HYPERPRIVOP_PTC_GA		0xe
+#define HYPERPRIVOP_ITR_D		0xf
+#define HYPERPRIVOP_GET_RR		0x10
+#define HYPERPRIVOP_SET_RR		0x11
+#define HYPERPRIVOP_SET_KR		0x12
+#define HYPERPRIVOP_FC			0x13
+#define HYPERPRIVOP_GET_CPUID		0x14
+#define HYPERPRIVOP_GET_PMD		0x15
+#define HYPERPRIVOP_GET_EFLAG		0x16
+#define HYPERPRIVOP_SET_EFLAG		0x17
+#define HYPERPRIVOP_RSM_BE		0x18
+#define HYPERPRIVOP_GET_PSR		0x19
+#define HYPERPRIVOP_MAX			0x19
+
+#endif /* __HYPERVISOR_IF_IA64_H__ */
+
+/*
+ * Local variables:
+ * mode: C
+ * c-set-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/include/xen/interface/domctl.h b/include/xen/interface/domctl.h
new file mode 100644
index 000000000..6ad891875
--- /dev/null
+++ b/include/xen/interface/domctl.h
@@ -0,0 +1,392 @@
+/******************************************************************************
+ * domctl.h
+ * 
+ * Domain management operations. For use by node control stack.
+ * 
+ * Copyright (c) 2002-2003, B Dragovic
+ * Copyright (c) 2002-2006, K Fraser
+ */
+
+#ifndef __XEN_PUBLIC_DOMCTL_H__
+#define __XEN_PUBLIC_DOMCTL_H__
+
+#if !defined(__XEN__) && !defined(__XEN_TOOLS__)
+#error "domctl operations are intended for use by node control tools only"
+#endif
+
+#include "xen.h"
+
+#define XEN_DOMCTL_INTERFACE_VERSION 0x00000003
+
+struct xenctl_cpumap {
+    XEN_GUEST_HANDLE(uint8_t) bitmap;
+    uint32_t nr_cpus;
+};
+
+/*
+ * NB. xen_domctl.domain is an IN/OUT parameter for this operation.
+ * If it is specified as zero, an id is auto-allocated and returned.
+ */
+#define XEN_DOMCTL_createdomain       1
+struct xen_domctl_createdomain {
+    /* IN parameters */
+    uint32_t ssidref;
+    xen_domain_handle_t handle;
+};
+typedef struct xen_domctl_createdomain xen_domctl_createdomain_t;
+DEFINE_XEN_GUEST_HANDLE(xen_domctl_createdomain_t);
+
+#define XEN_DOMCTL_destroydomain      2
+#define XEN_DOMCTL_pausedomain        3
+#define XEN_DOMCTL_unpausedomain      4
+
+#define XEN_DOMCTL_getdomaininfo      5
+struct xen_domctl_getdomaininfo {
+    /* OUT variables. */
+    domid_t  domain;              /* Also echoed in domctl.domain */
+#define DOMFLAGS_DYING     (1<<0) /* Domain is scheduled to die.             */
+#define DOMFLAGS_SHUTDOWN  (1<<2) /* The guest OS has shut down.             */
+#define DOMFLAGS_PAUSED    (1<<3) /* Currently paused by control software.   */
+#define DOMFLAGS_BLOCKED   (1<<4) /* Currently blocked pending an event.     */
+#define DOMFLAGS_RUNNING   (1<<5) /* Domain is currently running.            */
+#define DOMFLAGS_CPUMASK      255 /* CPU to which this domain is bound.      */
+#define DOMFLAGS_CPUSHIFT       8
+#define DOMFLAGS_SHUTDOWNMASK 255 /* DOMFLAGS_SHUTDOWN guest-supplied code.  */
+#define DOMFLAGS_SHUTDOWNSHIFT 16
+    uint32_t flags;
+    uint64_t tot_pages;
+    uint64_t max_pages;
+    uint64_t shared_info_frame;  /* MFN of shared_info struct */
+    uint64_t cpu_time;
+    uint32_t nr_online_vcpus;     /* Number of VCPUs currently online. */
+    uint32_t max_vcpu_id;         /* Maximum VCPUID in use by this domain. */
+    uint32_t ssidref;
+    xen_domain_handle_t handle;
+};
+typedef struct xen_domctl_getdomaininfo xen_domctl_getdomaininfo_t;
+DEFINE_XEN_GUEST_HANDLE(xen_domctl_getdomaininfo_t);
+
+
+#define XEN_DOMCTL_getmemlist         6
+struct xen_domctl_getmemlist {
+    /* IN variables. */
+    /* Max entries to write to output buffer. */
+    uint64_t max_pfns;
+    /* Start index in guest's page list. */
+    uint64_t start_pfn;
+    XEN_GUEST_HANDLE(xen_pfn_t) buffer;
+    /* OUT variables. */
+    uint64_t num_pfns;
+};
+typedef struct xen_domctl_getmemlist xen_domctl_getmemlist_t;
+DEFINE_XEN_GUEST_HANDLE(xen_domctl_getmemlist_t);
+
+
+#define XEN_DOMCTL_getpageframeinfo   7
+
+#define XEN_DOMCTL_PFINFO_LTAB_SHIFT 28
+#define XEN_DOMCTL_PFINFO_NOTAB   (0x0<<28)
+#define XEN_DOMCTL_PFINFO_L1TAB   (0x1<<28)
+#define XEN_DOMCTL_PFINFO_L2TAB   (0x2<<28)
+#define XEN_DOMCTL_PFINFO_L3TAB   (0x3<<28)
+#define XEN_DOMCTL_PFINFO_L4TAB   (0x4<<28)
+#define XEN_DOMCTL_PFINFO_LTABTYPE_MASK (0x7<<28)
+#define XEN_DOMCTL_PFINFO_LPINTAB (0x1<<31)
+#define XEN_DOMCTL_PFINFO_XTAB    (0xf<<28) /* invalid page */
+#define XEN_DOMCTL_PFINFO_LTAB_MASK (0xf<<28)
+
+struct xen_domctl_getpageframeinfo {
+    /* IN variables. */
+    uint64_t gmfn;        /* GMFN to query */
+    /* OUT variables. */
+    /* Is the page PINNED to a type? */
+    uint32_t type;         /* see above type defs */
+};
+typedef struct xen_domctl_getpageframeinfo xen_domctl_getpageframeinfo_t;
+DEFINE_XEN_GUEST_HANDLE(xen_domctl_getpageframeinfo_t);
+
+
+#define XEN_DOMCTL_getpageframeinfo2  8
+struct xen_domctl_getpageframeinfo2 {
+    /* IN variables. */
+    uint64_t num;
+    /* IN/OUT variables. */
+    XEN_GUEST_HANDLE(ulong) array;
+};
+typedef struct xen_domctl_getpageframeinfo2 xen_domctl_getpageframeinfo2_t;
+DEFINE_XEN_GUEST_HANDLE(xen_domctl_getpageframeinfo2_t);
+
+
+/*
+ * Control shadow pagetables operation
+ */
+#define XEN_DOMCTL_shadow_op         10
+
+/* Disable shadow mode. */
+#define XEN_DOMCTL_SHADOW_OP_OFF         0
+
+/* Enable shadow mode (mode contains ORed XEN_DOMCTL_SHADOW_ENABLE_* flags). */
+#define XEN_DOMCTL_SHADOW_OP_ENABLE      32
+
+/* Log-dirty bitmap operations. */
+ /* Return the bitmap and clean internal copy for next round. */
+#define XEN_DOMCTL_SHADOW_OP_CLEAN       11
+ /* Return the bitmap but do not modify internal copy. */
+#define XEN_DOMCTL_SHADOW_OP_PEEK        12
+
+/* Memory allocation accessors. */
+#define XEN_DOMCTL_SHADOW_OP_GET_ALLOCATION   30
+#define XEN_DOMCTL_SHADOW_OP_SET_ALLOCATION   31
+
+/* Legacy enable operations. */
+ /* Equiv. to ENABLE with no mode flags. */
+#define XEN_DOMCTL_SHADOW_OP_ENABLE_TEST       1
+ /* Equiv. to ENABLE with mode flag ENABLE_LOG_DIRTY. */
+#define XEN_DOMCTL_SHADOW_OP_ENABLE_LOGDIRTY   2
+ /* Equiv. to ENABLE with mode flags ENABLE_REFCOUNT and ENABLE_TRANSLATE. */
+#define XEN_DOMCTL_SHADOW_OP_ENABLE_TRANSLATE  3
+
+/* Mode flags for XEN_DOMCTL_SHADOW_OP_ENABLE. */
+ /*
+  * Shadow pagetables are refcounted: guest does not use explicit mmu
+  * operations nor write-protect its pagetables.
+  */
+#define XEN_DOMCTL_SHADOW_ENABLE_REFCOUNT  (1 << 1)
+ /*
+  * Log pages in a bitmap as they are dirtied.
+  * Used for live relocation to determine which pages must be re-sent.
+  */
+#define XEN_DOMCTL_SHADOW_ENABLE_LOG_DIRTY (1 << 2)
+ /*
+  * Automatically translate GPFNs into MFNs.
+  */
+#define XEN_DOMCTL_SHADOW_ENABLE_TRANSLATE (1 << 3)
+ /*
+  * Xen does not steal virtual address space from the guest.
+  * Requires HVM support.
+  */
+#define XEN_DOMCTL_SHADOW_ENABLE_EXTERNAL  (1 << 4)
+
+struct xen_domctl_shadow_op_stats {
+    uint32_t fault_count;
+    uint32_t dirty_count;
+};
+typedef struct xen_domctl_shadow_op_stats xen_domctl_shadow_op_stats_t;
+DEFINE_XEN_GUEST_HANDLE(xen_domctl_shadow_op_stats_t);
+
+struct xen_domctl_shadow_op {
+    /* IN variables. */
+    uint32_t       op;       /* XEN_DOMCTL_SHADOW_OP_* */
+
+    /* OP_ENABLE */
+    uint32_t       mode;     /* XEN_DOMCTL_SHADOW_ENABLE_* */
+
+    /* OP_GET_ALLOCATION / OP_SET_ALLOCATION */
+    uint32_t       mb;       /* Shadow memory allocation in MB */
+
+    /* OP_PEEK / OP_CLEAN */
+    XEN_GUEST_HANDLE(ulong) dirty_bitmap;
+    uint64_t       pages;    /* Size of buffer. Updated with actual size. */
+    struct xen_domctl_shadow_op_stats stats;
+};
+typedef struct xen_domctl_shadow_op xen_domctl_shadow_op_t;
+DEFINE_XEN_GUEST_HANDLE(xen_domctl_shadow_op_t);
+
+
+#define XEN_DOMCTL_max_mem           11
+struct xen_domctl_max_mem {
+    /* IN variables. */
+    uint64_t max_memkb;
+};
+typedef struct xen_domctl_max_mem xen_domctl_max_mem_t;
+DEFINE_XEN_GUEST_HANDLE(xen_domctl_max_mem_t);
+
+
+#define XEN_DOMCTL_setvcpucontext    12
+#define XEN_DOMCTL_getvcpucontext    13
+struct xen_domctl_vcpucontext {
+    uint32_t              vcpu;                  /* IN */
+    XEN_GUEST_HANDLE(vcpu_guest_context_t) ctxt; /* IN/OUT */
+};
+typedef struct xen_domctl_vcpucontext xen_domctl_vcpucontext_t;
+DEFINE_XEN_GUEST_HANDLE(xen_domctl_vcpucontext_t);
+
+
+#define XEN_DOMCTL_getvcpuinfo       14
+struct xen_domctl_getvcpuinfo {
+    /* IN variables. */
+    uint32_t vcpu;
+    /* OUT variables. */
+    uint8_t  online;                  /* currently online (not hotplugged)? */
+    uint8_t  blocked;                 /* blocked waiting for an event? */
+    uint8_t  running;                 /* currently scheduled on its CPU? */
+    uint64_t cpu_time;                /* total cpu time consumed (ns) */
+    uint32_t cpu;                     /* current mapping   */
+};
+typedef struct xen_domctl_getvcpuinfo xen_domctl_getvcpuinfo_t;
+DEFINE_XEN_GUEST_HANDLE(xen_domctl_getvcpuinfo_t);
+
+
+/* Get/set which physical cpus a vcpu can execute on. */
+#define XEN_DOMCTL_setvcpuaffinity    9
+#define XEN_DOMCTL_getvcpuaffinity   25
+struct xen_domctl_vcpuaffinity {
+    uint32_t  vcpu;              /* IN */
+    struct xenctl_cpumap cpumap; /* IN/OUT */
+};
+typedef struct xen_domctl_vcpuaffinity xen_domctl_vcpuaffinity_t;
+DEFINE_XEN_GUEST_HANDLE(xen_domctl_vcpuaffinity_t);
+
+
+#define XEN_DOMCTL_max_vcpus         15
+struct xen_domctl_max_vcpus {
+    uint32_t max;           /* maximum number of vcpus */
+};
+typedef struct xen_domctl_max_vcpus xen_domctl_max_vcpus_t;
+DEFINE_XEN_GUEST_HANDLE(xen_domctl_max_vcpus_t);
+
+
+#define XEN_DOMCTL_scheduler_op      16
+/* Scheduler types. */
+#define XEN_SCHEDULER_SEDF     4
+#define XEN_SCHEDULER_CREDIT   5
+/* Set or get info? */
+#define XEN_DOMCTL_SCHEDOP_putinfo 0
+#define XEN_DOMCTL_SCHEDOP_getinfo 1
+struct xen_domctl_scheduler_op {
+    uint32_t sched_id;  /* XEN_SCHEDULER_* */
+    uint32_t cmd;       /* XEN_DOMCTL_SCHEDOP_* */
+    union {
+        struct xen_domctl_sched_sedf {
+            uint64_t period;
+            uint64_t slice;
+            uint64_t latency;
+            uint32_t extratime;
+            uint32_t weight;
+        } sedf;
+        struct xen_domctl_sched_credit {
+            uint16_t weight;
+            uint16_t cap;
+        } credit;
+    } u;
+};
+typedef struct xen_domctl_scheduler_op xen_domctl_scheduler_op_t;
+DEFINE_XEN_GUEST_HANDLE(xen_domctl_scheduler_op_t);
+
+
+#define XEN_DOMCTL_setdomainhandle   17
+struct xen_domctl_setdomainhandle {
+    xen_domain_handle_t handle;
+};
+typedef struct xen_domctl_setdomainhandle xen_domctl_setdomainhandle_t;
+DEFINE_XEN_GUEST_HANDLE(xen_domctl_setdomainhandle_t);
+
+
+#define XEN_DOMCTL_setdebugging      18
+struct xen_domctl_setdebugging {
+    uint8_t enable;
+};
+typedef struct xen_domctl_setdebugging xen_domctl_setdebugging_t;
+DEFINE_XEN_GUEST_HANDLE(xen_domctl_setdebugging_t);
+
+
+#define XEN_DOMCTL_irq_permission    19
+struct xen_domctl_irq_permission {
+    uint8_t pirq;
+    uint8_t allow_access;    /* flag to specify enable/disable of IRQ access */
+};
+typedef struct xen_domctl_irq_permission xen_domctl_irq_permission_t;
+DEFINE_XEN_GUEST_HANDLE(xen_domctl_irq_permission_t);
+
+
+#define XEN_DOMCTL_iomem_permission  20
+struct xen_domctl_iomem_permission {
+    uint64_t first_mfn;       /* first page (physical page number) in range */
+    uint64_t nr_mfns;         /* number of pages in range (>0) */
+    uint8_t  allow_access;    /* allow (!0) or deny (0) access to range? */
+};
+typedef struct xen_domctl_iomem_permission xen_domctl_iomem_permission_t;
+DEFINE_XEN_GUEST_HANDLE(xen_domctl_iomem_permission_t);
+
+
+#define XEN_DOMCTL_ioport_permission 21
+struct xen_domctl_ioport_permission {
+    uint32_t first_port;              /* first port int range */
+    uint32_t nr_ports;                /* size of port range */
+    uint8_t  allow_access;            /* allow or deny access to range? */
+};
+typedef struct xen_domctl_ioport_permission xen_domctl_ioport_permission_t;
+DEFINE_XEN_GUEST_HANDLE(xen_domctl_ioport_permission_t);
+
+#define XEN_DOMCTL_hypercall_init    22
+struct xen_domctl_hypercall_init {
+    uint64_t  gmfn;            /* GMFN to be initialised */
+};
+typedef struct xen_domctl_hypercall_init xen_domctl_hypercall_init_t;
+DEFINE_XEN_GUEST_HANDLE(xen_domctl_hypercall_init_t);
+
+#define XEN_DOMCTL_arch_setup        23
+#define _XEN_DOMAINSETUP_hvm_guest 0
+#define XEN_DOMAINSETUP_hvm_guest  (1UL<<_XEN_DOMAINSETUP_hvm_guest)
+#define _XEN_DOMAINSETUP_query 1 /* Get parameters (for save)  */
+#define XEN_DOMAINSETUP_query  (1UL<<_XEN_DOMAINSETUP_query)
+typedef struct xen_domctl_arch_setup {
+    uint64_t flags;      /* XEN_DOMAINSETUP_* */
+#ifdef __ia64__
+    uint64_t bp;            /* mpaddr of boot param area */
+    uint64_t maxmem;        /* Highest memory address for MDT.  */
+    uint64_t xsi_va;        /* Xen shared_info area virtual address.  */
+    uint32_t hypercall_imm; /* Break imm for Xen hypercalls.  */
+#endif
+} xen_domctl_arch_setup_t;
+DEFINE_XEN_GUEST_HANDLE(xen_domctl_arch_setup_t);
+
+#define XEN_DOMCTL_settimeoffset     24
+struct xen_domctl_settimeoffset {
+    int32_t  time_offset_seconds; /* applied to domain wallclock time */
+};
+typedef struct xen_domctl_settimeoffset xen_domctl_settimeoffset_t;
+DEFINE_XEN_GUEST_HANDLE(xen_domctl_settimeoffset_t);
+
+struct xen_domctl {
+    uint32_t cmd;
+    uint32_t interface_version; /* XEN_DOMCTL_INTERFACE_VERSION */
+    domid_t  domain;
+    union {
+        struct xen_domctl_createdomain      createdomain;
+        struct xen_domctl_getdomaininfo     getdomaininfo;
+        struct xen_domctl_getmemlist        getmemlist;
+        struct xen_domctl_getpageframeinfo  getpageframeinfo;
+        struct xen_domctl_getpageframeinfo2 getpageframeinfo2;
+        struct xen_domctl_vcpuaffinity      vcpuaffinity;
+        struct xen_domctl_shadow_op         shadow_op;
+        struct xen_domctl_max_mem           max_mem;
+        struct xen_domctl_vcpucontext       vcpucontext;
+        struct xen_domctl_getvcpuinfo       getvcpuinfo;
+        struct xen_domctl_max_vcpus         max_vcpus;
+        struct xen_domctl_scheduler_op      scheduler_op;
+        struct xen_domctl_setdomainhandle   setdomainhandle;
+        struct xen_domctl_setdebugging      setdebugging;
+        struct xen_domctl_irq_permission    irq_permission;
+        struct xen_domctl_iomem_permission  iomem_permission;
+        struct xen_domctl_ioport_permission ioport_permission;
+        struct xen_domctl_hypercall_init    hypercall_init;
+        struct xen_domctl_arch_setup        arch_setup;
+        struct xen_domctl_settimeoffset     settimeoffset;
+        uint8_t                             pad[128];
+    } u;
+};
+typedef struct xen_domctl xen_domctl_t;
+DEFINE_XEN_GUEST_HANDLE(xen_domctl_t);
+
+#endif /* __XEN_PUBLIC_DOMCTL_H__ */
+
+/*
+ * Local variables:
+ * mode: C
+ * c-set-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/include/xen/interface/elfnote.h b/include/xen/interface/elfnote.h
new file mode 100644
index 000000000..a64d3df5b
--- /dev/null
+++ b/include/xen/interface/elfnote.h
@@ -0,0 +1,133 @@
+/******************************************************************************
+ * elfnote.h
+ *
+ * Definitions used for the Xen ELF notes.
+ *
+ * Copyright (c) 2006, Ian Campbell, XenSource Ltd.
+ */
+
+#ifndef __XEN_PUBLIC_ELFNOTE_H__
+#define __XEN_PUBLIC_ELFNOTE_H__
+
+/*
+ * The notes should live in a SHT_NOTE segment and have "Xen" in the
+ * name field.
+ *
+ * Numeric types are either 4 or 8 bytes depending on the content of
+ * the desc field.
+ *
+ * LEGACY indicated the fields in the legacy __xen_guest string which
+ * this a note type replaces.
+ */
+
+/*
+ * NAME=VALUE pair (string).
+ *
+ * LEGACY: FEATURES and PAE
+ */
+#define XEN_ELFNOTE_INFO           0
+
+/*
+ * The virtual address of the entry point (numeric).
+ *
+ * LEGACY: VIRT_ENTRY
+ */
+#define XEN_ELFNOTE_ENTRY          1
+
+/* The virtual address of the hypercall transfer page (numeric).
+ *
+ * LEGACY: HYPERCALL_PAGE. (n.b. legacy value is a physical page
+ * number not a virtual address)
+ */
+#define XEN_ELFNOTE_HYPERCALL_PAGE 2
+
+/* The virtual address where the kernel image should be mapped (numeric).
+ *
+ * Defaults to 0.
+ *
+ * LEGACY: VIRT_BASE
+ */
+#define XEN_ELFNOTE_VIRT_BASE      3
+
+/*
+ * The offset of the ELF paddr field from the acutal required
+ * psuedo-physical address (numeric).
+ *
+ * This is used to maintain backwards compatibility with older kernels
+ * which wrote __PAGE_OFFSET into that field. This field defaults to 0
+ * if not present.
+ *
+ * LEGACY: ELF_PADDR_OFFSET. (n.b. legacy default is VIRT_BASE)
+ */
+#define XEN_ELFNOTE_PADDR_OFFSET   4
+
+/*
+ * The version of Xen that we work with (string).
+ *
+ * LEGACY: XEN_VER
+ */
+#define XEN_ELFNOTE_XEN_VERSION    5
+
+/*
+ * The name of the guest operating system (string).
+ *
+ * LEGACY: GUEST_OS
+ */
+#define XEN_ELFNOTE_GUEST_OS       6
+
+/*
+ * The version of the guest operating system (string).
+ *
+ * LEGACY: GUEST_VER
+ */
+#define XEN_ELFNOTE_GUEST_VERSION  7
+
+/*
+ * The loader type (string).
+ *
+ * LEGACY: LOADER
+ */
+#define XEN_ELFNOTE_LOADER         8
+
+/*
+ * The kernel supports PAE (x86/32 only, string = "yes" or "no").
+ *
+ * LEGACY: PAE (n.b. The legacy interface included a provision to
+ * indicate 'extended-cr3' support allowing L3 page tables to be
+ * placed above 4G. It is assumed that any kernel new enough to use
+ * these ELF notes will include this and therefore "yes" here is
+ * equivalent to "yes[entended-cr3]" in the __xen_guest interface.
+ */
+#define XEN_ELFNOTE_PAE_MODE       9
+
+/*
+ * The features supported/required by this kernel (string).
+ *
+ * The string must consist of a list of feature names (as given in
+ * features.h, without the "XENFEAT_" prefix) separated by '|'
+ * characters. If a feature is required for the kernel to function
+ * then the feature name must be preceded by a '!' character.
+ *
+ * LEGACY: FEATURES
+ */
+#define XEN_ELFNOTE_FEATURES      10
+
+/*
+ * The kernel requires the symbol table to be loaded (string = "yes" or "no")
+ * LEGACY: BSD_SYMTAB (n.b. The legacy treated the presence or absence
+ * of this string as a boolean flag rather than requiring "yes" or
+ * "no".
+ */
+#define XEN_ELFNOTE_BSD_SYMTAB    11
+
+#endif /* __XEN_PUBLIC_ELFNOTE_H__ */
+
+/*
+ * Local variables:
+ * mode: C
+ * c-set-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/include/xen/interface/hvm/e820.h b/include/xen/interface/hvm/e820.h
new file mode 100644
index 000000000..8190c767d
--- /dev/null
+++ b/include/xen/interface/hvm/e820.h
@@ -0,0 +1,32 @@
+#ifndef __XEN_PUBLIC_HVM_E820_H__
+#define __XEN_PUBLIC_HVM_E820_H__
+
+/* PC BIOS standard E820 types. */
+#define E820_RAM          1
+#define E820_RESERVED     2
+#define E820_ACPI         3
+#define E820_NVS          4
+
+/* Xen HVM extended E820 types. */
+#define E820_IO          16
+#define E820_SHARED_PAGE 17
+#define E820_XENSTORE    18
+#define E820_BUFFERED_IO 19
+
+/* E820 location in HVM virtual address space. */
+#define E820_MAP_PAGE        0x00090000
+#define E820_MAP_NR_OFFSET   0x000001E8
+#define E820_MAP_OFFSET      0x000002D0
+
+struct e820entry {
+    uint64_t addr;
+    uint64_t size;
+    uint32_t type;
+} __attribute__((packed));
+
+#define HVM_BELOW_4G_RAM_END        0xF0000000
+
+#define HVM_BELOW_4G_MMIO_START     HVM_BELOW_4G_RAM_END
+#define HVM_BELOW_4G_MMIO_LENGTH    ((1ULL << 32) - HVM_BELOW_4G_MMIO_START)
+
+#endif /* __XEN_PUBLIC_HVM_E820_H__ */
diff --git a/include/xen/interface/platform.h b/include/xen/interface/platform.h
new file mode 100644
index 000000000..46e916091
--- /dev/null
+++ b/include/xen/interface/platform.h
@@ -0,0 +1,125 @@
+/******************************************************************************
+ * platform.h
+ * 
+ * Hardware platform operations. Intended for use by domain-0 kernel.
+ * 
+ * Copyright (c) 2002-2006, K Fraser
+ */
+
+#ifndef __XEN_PUBLIC_PLATFORM_H__
+#define __XEN_PUBLIC_PLATFORM_H__
+
+#include "xen.h"
+
+#define XENPF_INTERFACE_VERSION 0x03000001
+
+/*
+ * Set clock such that it would read <secs,nsecs> after 00:00:00 UTC,
+ * 1 January, 1970 if the current system time was <system_time>.
+ */
+#define XENPF_settime             17
+struct xenpf_settime {
+    /* IN variables. */
+    uint32_t secs;
+    uint32_t nsecs;
+    uint64_t system_time;
+};
+typedef struct xenpf_settime xenpf_settime_t;
+DEFINE_XEN_GUEST_HANDLE(xenpf_settime_t);
+
+/*
+ * Request memory range (@mfn, @mfn+@nr_mfns-1) to have type @type.
+ * On x86, @type is an architecture-defined MTRR memory type.
+ * On success, returns the MTRR that was used (@reg) and a handle that can
+ * be passed to XENPF_DEL_MEMTYPE to accurately tear down the new setting.
+ * (x86-specific).
+ */
+#define XENPF_add_memtype         31
+struct xenpf_add_memtype {
+    /* IN variables. */
+    xen_pfn_t mfn;
+    uint64_t nr_mfns;
+    uint32_t type;
+    /* OUT variables. */
+    uint32_t handle;
+    uint32_t reg;
+};
+typedef struct xenpf_add_memtype xenpf_add_memtype_t;
+DEFINE_XEN_GUEST_HANDLE(xenpf_add_memtype_t);
+
+/*
+ * Tear down an existing memory-range type. If @handle is remembered then it
+ * should be passed in to accurately tear down the correct setting (in case
+ * of overlapping memory regions with differing types). If it is not known
+ * then @handle should be set to zero. In all cases @reg must be set.
+ * (x86-specific).
+ */
+#define XENPF_del_memtype         32
+struct xenpf_del_memtype {
+    /* IN variables. */
+    uint32_t handle;
+    uint32_t reg;
+};
+typedef struct xenpf_del_memtype xenpf_del_memtype_t;
+DEFINE_XEN_GUEST_HANDLE(xenpf_del_memtype_t);
+
+/* Read current type of an MTRR (x86-specific). */
+#define XENPF_read_memtype        33
+struct xenpf_read_memtype {
+    /* IN variables. */
+    uint32_t reg;
+    /* OUT variables. */
+    xen_pfn_t mfn;
+    uint64_t nr_mfns;
+    uint32_t type;
+};
+typedef struct xenpf_read_memtype xenpf_read_memtype_t;
+DEFINE_XEN_GUEST_HANDLE(xenpf_read_memtype_t);
+
+#define XENPF_microcode_update    35
+struct xenpf_microcode_update {
+    /* IN variables. */
+    XEN_GUEST_HANDLE(void) data;      /* Pointer to microcode data */
+    uint32_t length;                  /* Length of microcode data. */
+};
+typedef struct xenpf_microcode_update xenpf_microcode_update_t;
+DEFINE_XEN_GUEST_HANDLE(xenpf_microcode_update_t);
+
+#define XENPF_platform_quirk      39
+#define QUIRK_NOIRQBALANCING      1 /* Do not restrict IO-APIC RTE targets */
+#define QUIRK_IOAPIC_BAD_REGSEL   2 /* IO-APIC REGSEL forgets its value    */
+#define QUIRK_IOAPIC_GOOD_REGSEL  3 /* IO-APIC REGSEL behaves properly     */
+struct xenpf_platform_quirk {
+    /* IN variables. */
+    uint32_t quirk_id;
+};
+typedef struct xenpf_platform_quirk xenpf_platform_quirk_t;
+DEFINE_XEN_GUEST_HANDLE(xenpf_platform_quirk_t);
+
+struct xen_platform_op {
+    uint32_t cmd;
+    uint32_t interface_version; /* XENPF_INTERFACE_VERSION */
+    union {
+        struct xenpf_settime           settime;
+        struct xenpf_add_memtype       add_memtype;
+        struct xenpf_del_memtype       del_memtype;
+        struct xenpf_read_memtype      read_memtype;
+        struct xenpf_microcode_update  microcode;
+        struct xenpf_platform_quirk    platform_quirk;
+        uint8_t                        pad[128];
+    } u;
+};
+typedef struct xen_platform_op xen_platform_op_t;
+DEFINE_XEN_GUEST_HANDLE(xen_platform_op_t);
+
+#endif /* __XEN_PUBLIC_PLATFORM_H__ */
+
+/*
+ * Local variables:
+ * mode: C
+ * c-set-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/include/xen/interface/sysctl.h b/include/xen/interface/sysctl.h
new file mode 100644
index 000000000..d556270a0
--- /dev/null
+++ b/include/xen/interface/sysctl.h
@@ -0,0 +1,151 @@
+/******************************************************************************
+ * sysctl.h
+ * 
+ * System management operations. For use by node control stack.
+ * 
+ * Copyright (c) 2002-2006, K Fraser
+ */
+
+#ifndef __XEN_PUBLIC_SYSCTL_H__
+#define __XEN_PUBLIC_SYSCTL_H__
+
+#if !defined(__XEN__) && !defined(__XEN_TOOLS__)
+#error "sysctl operations are intended for use by node control tools only"
+#endif
+
+#include "xen.h"
+#include "domctl.h"
+
+#define XEN_SYSCTL_INTERFACE_VERSION 0x00000002
+
+/*
+ * Read console content from Xen buffer ring.
+ */
+#define XEN_SYSCTL_readconsole       1
+struct xen_sysctl_readconsole {
+    /* IN variables. */
+    uint32_t clear;                /* Non-zero -> clear after reading. */
+    XEN_GUEST_HANDLE(char) buffer; /* Buffer start */
+    /* IN/OUT variables. */
+    uint32_t count;            /* In: Buffer size;  Out: Used buffer size  */
+};
+typedef struct xen_sysctl_readconsole xen_sysctl_readconsole_t;
+DEFINE_XEN_GUEST_HANDLE(xen_sysctl_readconsole_t);
+
+/* Get trace buffers machine base address */
+#define XEN_SYSCTL_tbuf_op           2
+struct xen_sysctl_tbuf_op {
+    /* IN variables */
+#define XEN_SYSCTL_TBUFOP_get_info     0
+#define XEN_SYSCTL_TBUFOP_set_cpu_mask 1
+#define XEN_SYSCTL_TBUFOP_set_evt_mask 2
+#define XEN_SYSCTL_TBUFOP_set_size     3
+#define XEN_SYSCTL_TBUFOP_enable       4
+#define XEN_SYSCTL_TBUFOP_disable      5
+    uint32_t cmd;
+    /* IN/OUT variables */
+    struct xenctl_cpumap cpu_mask;
+    uint32_t             evt_mask;
+    /* OUT variables */
+    uint64_t buffer_mfn;
+    uint32_t size;
+};
+typedef struct xen_sysctl_tbuf_op xen_sysctl_tbuf_op_t;
+DEFINE_XEN_GUEST_HANDLE(xen_sysctl_tbuf_op_t);
+
+/*
+ * Get physical information about the host machine
+ */
+#define XEN_SYSCTL_physinfo          3
+struct xen_sysctl_physinfo {
+    uint32_t threads_per_core;
+    uint32_t cores_per_socket;
+    uint32_t sockets_per_node;
+    uint32_t nr_nodes;
+    uint32_t cpu_khz;
+    uint64_t total_pages;
+    uint64_t free_pages;
+    uint64_t scrub_pages;
+    uint32_t hw_cap[8];
+};
+typedef struct xen_sysctl_physinfo xen_sysctl_physinfo_t;
+DEFINE_XEN_GUEST_HANDLE(xen_sysctl_physinfo_t);
+
+/*
+ * Get the ID of the current scheduler.
+ */
+#define XEN_SYSCTL_sched_id          4
+struct xen_sysctl_sched_id {
+    /* OUT variable */
+    uint32_t sched_id;
+};
+typedef struct xen_sysctl_sched_id xen_sysctl_sched_id_t;
+DEFINE_XEN_GUEST_HANDLE(xen_sysctl_sched_id_t);
+
+/* Interface for controlling Xen software performance counters. */
+#define XEN_SYSCTL_perfc_op          5
+/* Sub-operations: */
+#define XEN_SYSCTL_PERFCOP_reset 1   /* Reset all counters to zero. */
+#define XEN_SYSCTL_PERFCOP_query 2   /* Get perfctr information. */
+struct xen_sysctl_perfc_desc {
+    char         name[80];             /* name of perf counter */
+    uint32_t     nr_vals;              /* number of values for this counter */
+};
+typedef struct xen_sysctl_perfc_desc xen_sysctl_perfc_desc_t;
+DEFINE_XEN_GUEST_HANDLE(xen_sysctl_perfc_desc_t);
+typedef uint32_t xen_sysctl_perfc_val_t;
+DEFINE_XEN_GUEST_HANDLE(xen_sysctl_perfc_val_t);
+
+struct xen_sysctl_perfc_op {
+    /* IN variables. */
+    uint32_t       cmd;                /*  XEN_SYSCTL_PERFCOP_??? */
+    /* OUT variables. */
+    uint32_t       nr_counters;       /*  number of counters description  */
+    uint32_t       nr_vals;			  /*  number of values  */
+    /* counter information (or NULL) */
+    XEN_GUEST_HANDLE(xen_sysctl_perfc_desc_t) desc;
+    /* counter values (or NULL) */
+    XEN_GUEST_HANDLE(xen_sysctl_perfc_val_t) val;
+};
+typedef struct xen_sysctl_perfc_op xen_sysctl_perfc_op_t;
+DEFINE_XEN_GUEST_HANDLE(xen_sysctl_perfc_op_t);
+
+#define XEN_SYSCTL_getdomaininfolist 6
+struct xen_sysctl_getdomaininfolist {
+    /* IN variables. */
+    domid_t               first_domain;
+    uint32_t              max_domains;
+    XEN_GUEST_HANDLE(xen_domctl_getdomaininfo_t) buffer;
+    /* OUT variables. */
+    uint32_t              num_domains;
+};
+typedef struct xen_sysctl_getdomaininfolist xen_sysctl_getdomaininfolist_t;
+DEFINE_XEN_GUEST_HANDLE(xen_sysctl_getdomaininfolist_t);
+
+struct xen_sysctl {
+    uint32_t cmd;
+    uint32_t interface_version; /* XEN_SYSCTL_INTERFACE_VERSION */
+    union {
+        struct xen_sysctl_readconsole       readconsole;
+        struct xen_sysctl_tbuf_op           tbuf_op;
+        struct xen_sysctl_physinfo          physinfo;
+        struct xen_sysctl_sched_id          sched_id;
+        struct xen_sysctl_perfc_op          perfc_op;
+        struct xen_sysctl_getdomaininfolist getdomaininfolist;
+        uint8_t                             pad[128];
+    } u;
+};
+typedef struct xen_sysctl xen_sysctl_t;
+DEFINE_XEN_GUEST_HANDLE(xen_sysctl_t);
+
+#endif /* __XEN_PUBLIC_SYSCTL_H__ */
+
+/*
+ * Local variables:
+ * mode: C
+ * c-set-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/kernel/delayacct.c b/kernel/delayacct.c
new file mode 100644
index 000000000..36752f124
--- /dev/null
+++ b/kernel/delayacct.c
@@ -0,0 +1,162 @@
+/* delayacct.c - per-task delay accounting
+ *
+ * Copyright (C) Shailabh Nagar, IBM Corp. 2006
+ *
+ * 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 would 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.
+ */
+
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/time.h>
+#include <linux/sysctl.h>
+#include <linux/delayacct.h>
+
+int delayacct_on __read_mostly = 1;	/* Delay accounting turned on/off */
+kmem_cache_t *delayacct_cache;
+
+static int __init delayacct_setup_disable(char *str)
+{
+	delayacct_on = 0;
+	return 1;
+}
+__setup("nodelayacct", delayacct_setup_disable);
+
+void delayacct_init(void)
+{
+	delayacct_cache = kmem_cache_create("delayacct_cache",
+					sizeof(struct task_delay_info),
+					0,
+					SLAB_PANIC,
+					NULL, NULL);
+	delayacct_tsk_init(&init_task);
+}
+
+void __delayacct_tsk_init(struct task_struct *tsk)
+{
+	tsk->delays = kmem_cache_zalloc(delayacct_cache, SLAB_KERNEL);
+	if (tsk->delays)
+		spin_lock_init(&tsk->delays->lock);
+}
+
+/*
+ * Start accounting for a delay statistic using
+ * its starting timestamp (@start)
+ */
+
+static inline void delayacct_start(struct timespec *start)
+{
+	do_posix_clock_monotonic_gettime(start);
+}
+
+/*
+ * Finish delay accounting for a statistic using
+ * its timestamps (@start, @end), accumalator (@total) and @count
+ */
+
+static void delayacct_end(struct timespec *start, struct timespec *end,
+				u64 *total, u32 *count)
+{
+	struct timespec ts;
+	s64 ns;
+
+	do_posix_clock_monotonic_gettime(end);
+	ts = timespec_sub(*end, *start);
+	ns = timespec_to_ns(&ts);
+	if (ns < 0)
+		return;
+
+	spin_lock(&current->delays->lock);
+	*total += ns;
+	(*count)++;
+	spin_unlock(&current->delays->lock);
+}
+
+void __delayacct_blkio_start(void)
+{
+	delayacct_start(&current->delays->blkio_start);
+}
+
+void __delayacct_blkio_end(void)
+{
+	if (current->delays->flags & DELAYACCT_PF_SWAPIN)
+		/* Swapin block I/O */
+		delayacct_end(&current->delays->blkio_start,
+			&current->delays->blkio_end,
+			&current->delays->swapin_delay,
+			&current->delays->swapin_count);
+	else	/* Other block I/O */
+		delayacct_end(&current->delays->blkio_start,
+			&current->delays->blkio_end,
+			&current->delays->blkio_delay,
+			&current->delays->blkio_count);
+}
+
+int __delayacct_add_tsk(struct taskstats *d, struct task_struct *tsk)
+{
+	s64 tmp;
+	struct timespec ts;
+	unsigned long t1,t2,t3;
+
+	/* Though tsk->delays accessed later, early exit avoids
+	 * unnecessary returning of other data
+	 */
+	if (!tsk->delays)
+		goto done;
+
+	tmp = (s64)d->cpu_run_real_total;
+	cputime_to_timespec(tsk->utime + tsk->stime, &ts);
+	tmp += timespec_to_ns(&ts);
+	d->cpu_run_real_total = (tmp < (s64)d->cpu_run_real_total) ? 0 : tmp;
+
+	/*
+	 * No locking available for sched_info (and too expensive to add one)
+	 * Mitigate by taking snapshot of values
+	 */
+	t1 = tsk->sched_info.pcnt;
+	t2 = tsk->sched_info.run_delay;
+	t3 = tsk->sched_info.cpu_time;
+
+	d->cpu_count += t1;
+
+	jiffies_to_timespec(t2, &ts);
+	tmp = (s64)d->cpu_delay_total + timespec_to_ns(&ts);
+	d->cpu_delay_total = (tmp < (s64)d->cpu_delay_total) ? 0 : tmp;
+
+	tmp = (s64)d->cpu_run_virtual_total + (s64)jiffies_to_usecs(t3) * 1000;
+	d->cpu_run_virtual_total =
+		(tmp < (s64)d->cpu_run_virtual_total) ?	0 : tmp;
+
+	/* zero XXX_total, non-zero XXX_count implies XXX stat overflowed */
+
+	spin_lock(&tsk->delays->lock);
+	tmp = d->blkio_delay_total + tsk->delays->blkio_delay;
+	d->blkio_delay_total = (tmp < d->blkio_delay_total) ? 0 : tmp;
+	tmp = d->swapin_delay_total + tsk->delays->swapin_delay;
+	d->swapin_delay_total = (tmp < d->swapin_delay_total) ? 0 : tmp;
+	d->blkio_count += tsk->delays->blkio_count;
+	d->swapin_count += tsk->delays->swapin_count;
+	spin_unlock(&tsk->delays->lock);
+
+done:
+	return 0;
+}
+
+__u64 __delayacct_blkio_ticks(struct task_struct *tsk)
+{
+	__u64 ret;
+
+	spin_lock(&tsk->delays->lock);
+	ret = nsec_to_clock_t(tsk->delays->blkio_delay +
+				tsk->delays->swapin_delay);
+	spin_unlock(&tsk->delays->lock);
+	return ret;
+}
+
diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c
new file mode 100644
index 000000000..ac1f850d4
--- /dev/null
+++ b/kernel/irq/chip.c
@@ -0,0 +1,537 @@
+/*
+ * linux/kernel/irq/chip.c
+ *
+ * Copyright (C) 1992, 1998-2006 Linus Torvalds, Ingo Molnar
+ * Copyright (C) 2005-2006, Thomas Gleixner, Russell King
+ *
+ * This file contains the core interrupt handling code, for irq-chip
+ * based architectures.
+ *
+ * Detailed information is available in Documentation/DocBook/genericirq
+ */
+
+#include <linux/irq.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/kernel_stat.h>
+
+#include "internals.h"
+
+/**
+ *	set_irq_chip - set the irq chip for an irq
+ *	@irq:	irq number
+ *	@chip:	pointer to irq chip description structure
+ */
+int set_irq_chip(unsigned int irq, struct irq_chip *chip)
+{
+	struct irq_desc *desc;
+	unsigned long flags;
+
+	if (irq >= NR_IRQS) {
+		printk(KERN_ERR "Trying to install chip for IRQ%d\n", irq);
+		WARN_ON(1);
+		return -EINVAL;
+	}
+
+	if (!chip)
+		chip = &no_irq_chip;
+
+	desc = irq_desc + irq;
+	spin_lock_irqsave(&desc->lock, flags);
+	irq_chip_set_defaults(chip);
+	desc->chip = chip;
+	/*
+	 * For compatibility only:
+	 */
+	desc->chip = chip;
+	spin_unlock_irqrestore(&desc->lock, flags);
+
+	return 0;
+}
+EXPORT_SYMBOL(set_irq_chip);
+
+/**
+ *	set_irq_type - set the irq type for an irq
+ *	@irq:	irq number
+ *	@type:	interrupt type - see include/linux/interrupt.h
+ */
+int set_irq_type(unsigned int irq, unsigned int type)
+{
+	struct irq_desc *desc;
+	unsigned long flags;
+	int ret = -ENXIO;
+
+	if (irq >= NR_IRQS) {
+		printk(KERN_ERR "Trying to set irq type for IRQ%d\n", irq);
+		return -ENODEV;
+	}
+
+	desc = irq_desc + irq;
+	if (desc->chip->set_type) {
+		spin_lock_irqsave(&desc->lock, flags);
+		ret = desc->chip->set_type(irq, type);
+		spin_unlock_irqrestore(&desc->lock, flags);
+	}
+	return ret;
+}
+EXPORT_SYMBOL(set_irq_type);
+
+/**
+ *	set_irq_data - set irq type data for an irq
+ *	@irq:	Interrupt number
+ *	@data:	Pointer to interrupt specific data
+ *
+ *	Set the hardware irq controller data for an irq
+ */
+int set_irq_data(unsigned int irq, void *data)
+{
+	struct irq_desc *desc;
+	unsigned long flags;
+
+	if (irq >= NR_IRQS) {
+		printk(KERN_ERR
+		       "Trying to install controller data for IRQ%d\n", irq);
+		return -EINVAL;
+	}
+
+	desc = irq_desc + irq;
+	spin_lock_irqsave(&desc->lock, flags);
+	desc->handler_data = data;
+	spin_unlock_irqrestore(&desc->lock, flags);
+	return 0;
+}
+EXPORT_SYMBOL(set_irq_data);
+
+/**
+ *	set_irq_chip_data - set irq chip data for an irq
+ *	@irq:	Interrupt number
+ *	@data:	Pointer to chip specific data
+ *
+ *	Set the hardware irq chip data for an irq
+ */
+int set_irq_chip_data(unsigned int irq, void *data)
+{
+	struct irq_desc *desc = irq_desc + irq;
+	unsigned long flags;
+
+	if (irq >= NR_IRQS || !desc->chip) {
+		printk(KERN_ERR "BUG: bad set_irq_chip_data(IRQ#%d)\n", irq);
+		return -EINVAL;
+	}
+
+	spin_lock_irqsave(&desc->lock, flags);
+	desc->chip_data = data;
+	spin_unlock_irqrestore(&desc->lock, flags);
+
+	return 0;
+}
+EXPORT_SYMBOL(set_irq_chip_data);
+
+/*
+ * default enable function
+ */
+static void default_enable(unsigned int irq)
+{
+	struct irq_desc *desc = irq_desc + irq;
+
+	desc->chip->unmask(irq);
+	desc->status &= ~IRQ_MASKED;
+}
+
+/*
+ * default disable function
+ */
+static void default_disable(unsigned int irq)
+{
+	struct irq_desc *desc = irq_desc + irq;
+
+	if (!(desc->status & IRQ_DELAYED_DISABLE))
+		irq_desc[irq].chip->mask(irq);
+}
+
+/*
+ * default startup function
+ */
+static unsigned int default_startup(unsigned int irq)
+{
+	irq_desc[irq].chip->enable(irq);
+
+	return 0;
+}
+
+/*
+ * Fixup enable/disable function pointers
+ */
+void irq_chip_set_defaults(struct irq_chip *chip)
+{
+	if (!chip->enable)
+		chip->enable = default_enable;
+	if (!chip->disable)
+		chip->disable = default_disable;
+	if (!chip->startup)
+		chip->startup = default_startup;
+	if (!chip->shutdown)
+		chip->shutdown = chip->disable;
+	if (!chip->name)
+		chip->name = chip->typename;
+}
+
+static inline void mask_ack_irq(struct irq_desc *desc, int irq)
+{
+	if (desc->chip->mask_ack)
+		desc->chip->mask_ack(irq);
+	else {
+		desc->chip->mask(irq);
+		desc->chip->ack(irq);
+	}
+}
+
+/**
+ *	handle_simple_irq - Simple and software-decoded IRQs.
+ *	@irq:	the interrupt number
+ *	@desc:	the interrupt description structure for this irq
+ *	@regs:	pointer to a register structure
+ *
+ *	Simple interrupts are either sent from a demultiplexing interrupt
+ *	handler or come from hardware, where no interrupt hardware control
+ *	is necessary.
+ *
+ *	Note: The caller is expected to handle the ack, clear, mask and
+ *	unmask issues if necessary.
+ */
+void fastcall
+handle_simple_irq(unsigned int irq, struct irq_desc *desc, struct pt_regs *regs)
+{
+	struct irqaction *action;
+	irqreturn_t action_ret;
+	const unsigned int cpu = smp_processor_id();
+
+	spin_lock(&desc->lock);
+
+	if (unlikely(desc->status & IRQ_INPROGRESS))
+		goto out_unlock;
+	desc->status &= ~(IRQ_REPLAY | IRQ_WAITING);
+	kstat_cpu(cpu).irqs[irq]++;
+
+	action = desc->action;
+	if (unlikely(!action || (desc->status & IRQ_DISABLED)))
+		goto out_unlock;
+
+	desc->status |= IRQ_INPROGRESS;
+	spin_unlock(&desc->lock);
+
+	action_ret = handle_IRQ_event(irq, regs, action);
+	if (!noirqdebug)
+		note_interrupt(irq, desc, action_ret, regs);
+
+	spin_lock(&desc->lock);
+	desc->status &= ~IRQ_INPROGRESS;
+out_unlock:
+	spin_unlock(&desc->lock);
+}
+
+/**
+ *	handle_level_irq - Level type irq handler
+ *	@irq:	the interrupt number
+ *	@desc:	the interrupt description structure for this irq
+ *	@regs:	pointer to a register structure
+ *
+ *	Level type interrupts are active as long as the hardware line has
+ *	the active level. This may require to mask the interrupt and unmask
+ *	it after the associated handler has acknowledged the device, so the
+ *	interrupt line is back to inactive.
+ */
+void fastcall
+handle_level_irq(unsigned int irq, struct irq_desc *desc, struct pt_regs *regs)
+{
+	unsigned int cpu = smp_processor_id();
+	struct irqaction *action;
+	irqreturn_t action_ret;
+
+	spin_lock(&desc->lock);
+	mask_ack_irq(desc, irq);
+
+	if (unlikely(desc->status & IRQ_INPROGRESS))
+		goto out_unlock;
+	desc->status &= ~(IRQ_REPLAY | IRQ_WAITING);
+	kstat_cpu(cpu).irqs[irq]++;
+
+	/*
+	 * If its disabled or no action available
+	 * keep it masked and get out of here
+	 */
+	action = desc->action;
+	if (unlikely(!action || (desc->status & IRQ_DISABLED))) {
+		desc->status |= IRQ_PENDING;
+		goto out_unlock;
+	}
+
+	desc->status |= IRQ_INPROGRESS;
+	desc->status &= ~IRQ_PENDING;
+	spin_unlock(&desc->lock);
+
+	action_ret = handle_IRQ_event(irq, regs, action);
+	if (!noirqdebug)
+		note_interrupt(irq, desc, action_ret, regs);
+
+	spin_lock(&desc->lock);
+	desc->status &= ~IRQ_INPROGRESS;
+	if (!(desc->status & IRQ_DISABLED) && desc->chip->unmask)
+		desc->chip->unmask(irq);
+out_unlock:
+	spin_unlock(&desc->lock);
+}
+
+/**
+ *	handle_fasteoi_irq - irq handler for transparent controllers
+ *	@irq:	the interrupt number
+ *	@desc:	the interrupt description structure for this irq
+ *	@regs:	pointer to a register structure
+ *
+ *	Only a single callback will be issued to the chip: an ->eoi()
+ *	call when the interrupt has been serviced. This enables support
+ *	for modern forms of interrupt handlers, which handle the flow
+ *	details in hardware, transparently.
+ */
+void fastcall
+handle_fasteoi_irq(unsigned int irq, struct irq_desc *desc,
+		   struct pt_regs *regs)
+{
+	unsigned int cpu = smp_processor_id();
+	struct irqaction *action;
+	irqreturn_t action_ret;
+
+	spin_lock(&desc->lock);
+
+	if (unlikely(desc->status & IRQ_INPROGRESS))
+		goto out;
+
+	desc->status &= ~(IRQ_REPLAY | IRQ_WAITING);
+	kstat_cpu(cpu).irqs[irq]++;
+
+	/*
+	 * If its disabled or no action available
+	 * keep it masked and get out of here
+	 */
+	action = desc->action;
+	if (unlikely(!action || (desc->status & IRQ_DISABLED))) {
+		desc->status |= IRQ_PENDING;
+		goto out;
+	}
+
+	desc->status |= IRQ_INPROGRESS;
+	desc->status &= ~IRQ_PENDING;
+	spin_unlock(&desc->lock);
+
+	action_ret = handle_IRQ_event(irq, regs, action);
+	if (!noirqdebug)
+		note_interrupt(irq, desc, action_ret, regs);
+
+	spin_lock(&desc->lock);
+	desc->status &= ~IRQ_INPROGRESS;
+out:
+	desc->chip->eoi(irq);
+
+	spin_unlock(&desc->lock);
+}
+
+/**
+ *	handle_edge_irq - edge type IRQ handler
+ *	@irq:	the interrupt number
+ *	@desc:	the interrupt description structure for this irq
+ *	@regs:	pointer to a register structure
+ *
+ *	Interrupt occures on the falling and/or rising edge of a hardware
+ *	signal. The occurence is latched into the irq controller hardware
+ *	and must be acked in order to be reenabled. After the ack another
+ *	interrupt can happen on the same source even before the first one
+ *	is handled by the assosiacted event handler. If this happens it
+ *	might be necessary to disable (mask) the interrupt depending on the
+ *	controller hardware. This requires to reenable the interrupt inside
+ *	of the loop which handles the interrupts which have arrived while
+ *	the handler was running. If all pending interrupts are handled, the
+ *	loop is left.
+ */
+void fastcall
+handle_edge_irq(unsigned int irq, struct irq_desc *desc, struct pt_regs *regs)
+{
+	const unsigned int cpu = smp_processor_id();
+
+	spin_lock(&desc->lock);
+
+	desc->status &= ~(IRQ_REPLAY | IRQ_WAITING);
+
+	/*
+	 * If we're currently running this IRQ, or its disabled,
+	 * we shouldn't process the IRQ. Mark it pending, handle
+	 * the necessary masking and go out
+	 */
+	if (unlikely((desc->status & (IRQ_INPROGRESS | IRQ_DISABLED)) ||
+		    !desc->action)) {
+		desc->status |= (IRQ_PENDING | IRQ_MASKED);
+		mask_ack_irq(desc, irq);
+		goto out_unlock;
+	}
+
+	kstat_cpu(cpu).irqs[irq]++;
+
+	/* Start handling the irq */
+	desc->chip->ack(irq);
+
+	/* Mark the IRQ currently in progress.*/
+	desc->status |= IRQ_INPROGRESS;
+
+	do {
+		struct irqaction *action = desc->action;
+		irqreturn_t action_ret;
+
+		if (unlikely(!action)) {
+			desc->chip->mask(irq);
+			goto out_unlock;
+		}
+
+		/*
+		 * When another irq arrived while we were handling
+		 * one, we could have masked the irq.
+		 * Renable it, if it was not disabled in meantime.
+		 */
+		if (unlikely((desc->status &
+			       (IRQ_PENDING | IRQ_MASKED | IRQ_DISABLED)) ==
+			      (IRQ_PENDING | IRQ_MASKED))) {
+			desc->chip->unmask(irq);
+			desc->status &= ~IRQ_MASKED;
+		}
+
+		desc->status &= ~IRQ_PENDING;
+		spin_unlock(&desc->lock);
+		action_ret = handle_IRQ_event(irq, regs, action);
+		if (!noirqdebug)
+			note_interrupt(irq, desc, action_ret, regs);
+		spin_lock(&desc->lock);
+
+	} while ((desc->status & (IRQ_PENDING | IRQ_DISABLED)) == IRQ_PENDING);
+
+	desc->status &= ~IRQ_INPROGRESS;
+out_unlock:
+	spin_unlock(&desc->lock);
+}
+
+#ifdef CONFIG_SMP
+/**
+ *	handle_percpu_IRQ - Per CPU local irq handler
+ *	@irq:	the interrupt number
+ *	@desc:	the interrupt description structure for this irq
+ *	@regs:	pointer to a register structure
+ *
+ *	Per CPU interrupts on SMP machines without locking requirements
+ */
+void fastcall
+handle_percpu_irq(unsigned int irq, struct irq_desc *desc, struct pt_regs *regs)
+{
+	irqreturn_t action_ret;
+
+	kstat_this_cpu.irqs[irq]++;
+
+	if (desc->chip->ack)
+		desc->chip->ack(irq);
+
+	action_ret = handle_IRQ_event(irq, regs, desc->action);
+	if (!noirqdebug)
+		note_interrupt(irq, desc, action_ret, regs);
+
+	if (desc->chip->eoi)
+		desc->chip->eoi(irq);
+}
+
+#endif /* CONFIG_SMP */
+
+void
+__set_irq_handler(unsigned int irq,
+		  void fastcall (*handle)(unsigned int, irq_desc_t *,
+					  struct pt_regs *),
+		  int is_chained)
+{
+	struct irq_desc *desc;
+	unsigned long flags;
+
+	if (irq >= NR_IRQS) {
+		printk(KERN_ERR
+		       "Trying to install type control for IRQ%d\n", irq);
+		return;
+	}
+
+	desc = irq_desc + irq;
+
+	if (!handle)
+		handle = handle_bad_irq;
+
+	if (desc->chip == &no_irq_chip) {
+		printk(KERN_WARNING "Trying to install %sinterrupt handler "
+		       "for IRQ%d\n", is_chained ? "chained " : " ", irq);
+		/*
+		 * Some ARM implementations install a handler for really dumb
+		 * interrupt hardware without setting an irq_chip. This worked
+		 * with the ARM no_irq_chip but the check in setup_irq would
+		 * prevent us to setup the interrupt at all. Switch it to
+		 * dummy_irq_chip for easy transition.
+		 */
+		desc->chip = &dummy_irq_chip;
+	}
+
+	spin_lock_irqsave(&desc->lock, flags);
+
+	/* Uninstall? */
+	if (handle == handle_bad_irq) {
+		if (desc->chip != &no_irq_chip) {
+			desc->chip->mask(irq);
+			desc->chip->ack(irq);
+		}
+		desc->status |= IRQ_DISABLED;
+		desc->depth = 1;
+	}
+	desc->handle_irq = handle;
+
+	if (handle != handle_bad_irq && is_chained) {
+		desc->status &= ~IRQ_DISABLED;
+		desc->status |= IRQ_NOREQUEST | IRQ_NOPROBE;
+		desc->depth = 0;
+		desc->chip->unmask(irq);
+	}
+	spin_unlock_irqrestore(&desc->lock, flags);
+}
+
+void
+set_irq_chip_and_handler(unsigned int irq, struct irq_chip *chip,
+			 void fastcall (*handle)(unsigned int,
+						 struct irq_desc *,
+						 struct pt_regs *))
+{
+	set_irq_chip(irq, chip);
+	__set_irq_handler(irq, handle, 0);
+}
+
+/*
+ * Get a descriptive string for the highlevel handler, for
+ * /proc/interrupts output:
+ */
+const char *
+handle_irq_name(void fastcall (*handle)(unsigned int, struct irq_desc *,
+					struct pt_regs *))
+{
+	if (handle == handle_level_irq)
+		return "level  ";
+	if (handle == handle_fasteoi_irq)
+		return "fasteoi";
+	if (handle == handle_edge_irq)
+		return "edge   ";
+	if (handle == handle_simple_irq)
+		return "simple ";
+#ifdef CONFIG_SMP
+	if (handle == handle_percpu_irq)
+		return "percpu ";
+#endif
+	if (handle == handle_bad_irq)
+		return "bad    ";
+
+	return NULL;
+}
diff --git a/kernel/irq/resend.c b/kernel/irq/resend.c
new file mode 100644
index 000000000..35f10f7ff
--- /dev/null
+++ b/kernel/irq/resend.c
@@ -0,0 +1,77 @@
+/*
+ * linux/kernel/irq/resend.c
+ *
+ * Copyright (C) 1992, 1998-2006 Linus Torvalds, Ingo Molnar
+ * Copyright (C) 2005-2006, Thomas Gleixner
+ *
+ * This file contains the IRQ-resend code
+ *
+ * If the interrupt is waiting to be processed, we try to re-run it.
+ * We can't directly run it from here since the caller might be in an
+ * interrupt-protected region. Not all irq controller chips can
+ * retrigger interrupts at the hardware level, so in those cases
+ * we allow the resending of IRQs via a tasklet.
+ */
+
+#include <linux/irq.h>
+#include <linux/module.h>
+#include <linux/random.h>
+#include <linux/interrupt.h>
+
+#include "internals.h"
+
+#ifdef CONFIG_HARDIRQS_SW_RESEND
+
+/* Bitmap to handle software resend of interrupts: */
+static DECLARE_BITMAP(irqs_resend, NR_IRQS);
+
+/*
+ * Run software resends of IRQ's
+ */
+static void resend_irqs(unsigned long arg)
+{
+	struct irq_desc *desc;
+	int irq;
+
+	while (!bitmap_empty(irqs_resend, NR_IRQS)) {
+		irq = find_first_bit(irqs_resend, NR_IRQS);
+		clear_bit(irq, irqs_resend);
+		desc = irq_desc + irq;
+		local_irq_disable();
+		desc->handle_irq(irq, desc, NULL);
+		local_irq_enable();
+	}
+}
+
+/* Tasklet to handle resend: */
+static DECLARE_TASKLET(resend_tasklet, resend_irqs, 0);
+
+#endif
+
+/*
+ * IRQ resend
+ *
+ * Is called with interrupts disabled and desc->lock held.
+ */
+void check_irq_resend(struct irq_desc *desc, unsigned int irq)
+{
+	unsigned int status = desc->status;
+
+	/*
+	 * Make sure the interrupt is enabled, before resending it:
+	 */
+	desc->chip->enable(irq);
+
+	if ((status & (IRQ_PENDING | IRQ_REPLAY)) == IRQ_PENDING) {
+		desc->status = (status & ~IRQ_PENDING) | IRQ_REPLAY;
+
+		if (!desc->chip || !desc->chip->retrigger ||
+					!desc->chip->retrigger(irq)) {
+#ifdef CONFIG_HARDIRQS_SW_RESEND
+			/* Set it pending and activate the softirq: */
+			set_bit(irq, irqs_resend);
+			tasklet_schedule(&resend_tasklet);
+#endif
+		}
+	}
+}
diff --git a/kernel/lockdep.c b/kernel/lockdep.c
new file mode 100644
index 000000000..3a0c44c60
--- /dev/null
+++ b/kernel/lockdep.c
@@ -0,0 +1,2727 @@
+/*
+ * kernel/lockdep.c
+ *
+ * Runtime locking correctness validator
+ *
+ * Started by Ingo Molnar:
+ *
+ *  Copyright (C) 2006 Red Hat, Inc., Ingo Molnar <mingo@redhat.com>
+ *
+ * this code maps all the lock dependencies as they occur in a live kernel
+ * and will warn about the following classes of locking bugs:
+ *
+ * - lock inversion scenarios
+ * - circular lock dependencies
+ * - hardirq/softirq safe/unsafe locking bugs
+ *
+ * Bugs are reported even if the current locking scenario does not cause
+ * any deadlock at this point.
+ *
+ * I.e. if anytime in the past two locks were taken in a different order,
+ * even if it happened for another task, even if those were different
+ * locks (but of the same class as this lock), this code will detect it.
+ *
+ * Thanks to Arjan van de Ven for coming up with the initial idea of
+ * mapping lock dependencies runtime.
+ */
+#include <linux/mutex.h>
+#include <linux/sched.h>
+#include <linux/delay.h>
+#include <linux/module.h>
+#include <linux/proc_fs.h>
+#include <linux/seq_file.h>
+#include <linux/spinlock.h>
+#include <linux/kallsyms.h>
+#include <linux/interrupt.h>
+#include <linux/stacktrace.h>
+#include <linux/debug_locks.h>
+#include <linux/irqflags.h>
+#include <linux/utsname.h>
+
+#include <asm/sections.h>
+
+#include "lockdep_internals.h"
+
+/*
+ * hash_lock: protects the lockdep hashes and class/list/hash allocators.
+ *
+ * This is one of the rare exceptions where it's justified
+ * to use a raw spinlock - we really dont want the spinlock
+ * code to recurse back into the lockdep code.
+ */
+static raw_spinlock_t hash_lock = (raw_spinlock_t)__RAW_SPIN_LOCK_UNLOCKED;
+
+static int lockdep_initialized;
+
+unsigned long nr_list_entries;
+static struct lock_list list_entries[MAX_LOCKDEP_ENTRIES];
+
+/*
+ * Allocate a lockdep entry. (assumes hash_lock held, returns
+ * with NULL on failure)
+ */
+static struct lock_list *alloc_list_entry(void)
+{
+	if (nr_list_entries >= MAX_LOCKDEP_ENTRIES) {
+		__raw_spin_unlock(&hash_lock);
+		debug_locks_off();
+		printk("BUG: MAX_LOCKDEP_ENTRIES too low!\n");
+		printk("turning off the locking correctness validator.\n");
+		return NULL;
+	}
+	return list_entries + nr_list_entries++;
+}
+
+/*
+ * All data structures here are protected by the global debug_lock.
+ *
+ * Mutex key structs only get allocated, once during bootup, and never
+ * get freed - this significantly simplifies the debugging code.
+ */
+unsigned long nr_lock_classes;
+static struct lock_class lock_classes[MAX_LOCKDEP_KEYS];
+
+/*
+ * We keep a global list of all lock classes. The list only grows,
+ * never shrinks. The list is only accessed with the lockdep
+ * spinlock lock held.
+ */
+LIST_HEAD(all_lock_classes);
+
+/*
+ * The lockdep classes are in a hash-table as well, for fast lookup:
+ */
+#define CLASSHASH_BITS		(MAX_LOCKDEP_KEYS_BITS - 1)
+#define CLASSHASH_SIZE		(1UL << CLASSHASH_BITS)
+#define CLASSHASH_MASK		(CLASSHASH_SIZE - 1)
+#define __classhashfn(key)	((((unsigned long)key >> CLASSHASH_BITS) + (unsigned long)key) & CLASSHASH_MASK)
+#define classhashentry(key)	(classhash_table + __classhashfn((key)))
+
+static struct list_head classhash_table[CLASSHASH_SIZE];
+
+unsigned long nr_lock_chains;
+static struct lock_chain lock_chains[MAX_LOCKDEP_CHAINS];
+
+/*
+ * We put the lock dependency chains into a hash-table as well, to cache
+ * their existence:
+ */
+#define CHAINHASH_BITS		(MAX_LOCKDEP_CHAINS_BITS-1)
+#define CHAINHASH_SIZE		(1UL << CHAINHASH_BITS)
+#define CHAINHASH_MASK		(CHAINHASH_SIZE - 1)
+#define __chainhashfn(chain) \
+		(((chain >> CHAINHASH_BITS) + chain) & CHAINHASH_MASK)
+#define chainhashentry(chain)	(chainhash_table + __chainhashfn((chain)))
+
+static struct list_head chainhash_table[CHAINHASH_SIZE];
+
+/*
+ * The hash key of the lock dependency chains is a hash itself too:
+ * it's a hash of all locks taken up to that lock, including that lock.
+ * It's a 64-bit hash, because it's important for the keys to be
+ * unique.
+ */
+#define iterate_chain_key(key1, key2) \
+	(((key1) << MAX_LOCKDEP_KEYS_BITS/2) ^ \
+	((key1) >> (64-MAX_LOCKDEP_KEYS_BITS/2)) ^ \
+	(key2))
+
+void lockdep_off(void)
+{
+	current->lockdep_recursion++;
+}
+
+EXPORT_SYMBOL(lockdep_off);
+
+void lockdep_on(void)
+{
+	current->lockdep_recursion--;
+}
+
+EXPORT_SYMBOL(lockdep_on);
+
+int lockdep_internal(void)
+{
+	return current->lockdep_recursion != 0;
+}
+
+EXPORT_SYMBOL(lockdep_internal);
+
+/*
+ * Debugging switches:
+ */
+
+#define VERBOSE			0
+#ifdef VERBOSE
+# define VERY_VERBOSE		0
+#endif
+
+#if VERBOSE
+# define HARDIRQ_VERBOSE	1
+# define SOFTIRQ_VERBOSE	1
+#else
+# define HARDIRQ_VERBOSE	0
+# define SOFTIRQ_VERBOSE	0
+#endif
+
+#if VERBOSE || HARDIRQ_VERBOSE || SOFTIRQ_VERBOSE
+/*
+ * Quick filtering for interesting events:
+ */
+static int class_filter(struct lock_class *class)
+{
+#if 0
+	/* Example */
+	if (class->name_version == 1 &&
+			!strcmp(class->name, "lockname"))
+		return 1;
+	if (class->name_version == 1 &&
+			!strcmp(class->name, "&struct->lockfield"))
+		return 1;
+#endif
+	/* Allow everything else. 0 would be filter everything else */
+	return 1;
+}
+#endif
+
+static int verbose(struct lock_class *class)
+{
+#if VERBOSE
+	return class_filter(class);
+#endif
+	return 0;
+}
+
+#ifdef CONFIG_TRACE_IRQFLAGS
+
+static int hardirq_verbose(struct lock_class *class)
+{
+#if HARDIRQ_VERBOSE
+	return class_filter(class);
+#endif
+	return 0;
+}
+
+static int softirq_verbose(struct lock_class *class)
+{
+#if SOFTIRQ_VERBOSE
+	return class_filter(class);
+#endif
+	return 0;
+}
+
+#endif
+
+/*
+ * Stack-trace: tightly packed array of stack backtrace
+ * addresses. Protected by the hash_lock.
+ */
+unsigned long nr_stack_trace_entries;
+static unsigned long stack_trace[MAX_STACK_TRACE_ENTRIES];
+
+static int save_trace(struct stack_trace *trace)
+{
+	trace->nr_entries = 0;
+	trace->max_entries = MAX_STACK_TRACE_ENTRIES - nr_stack_trace_entries;
+	trace->entries = stack_trace + nr_stack_trace_entries;
+
+	trace->skip = 3;
+	trace->all_contexts = 0;
+
+	/* Make sure to not recurse in case the the unwinder needs to tak
+e	   locks. */
+	lockdep_off();
+	save_stack_trace(trace, NULL);
+	lockdep_on();
+
+	trace->max_entries = trace->nr_entries;
+
+	nr_stack_trace_entries += trace->nr_entries;
+	if (DEBUG_LOCKS_WARN_ON(nr_stack_trace_entries > MAX_STACK_TRACE_ENTRIES))
+		return 0;
+
+	if (nr_stack_trace_entries == MAX_STACK_TRACE_ENTRIES) {
+		__raw_spin_unlock(&hash_lock);
+		if (debug_locks_off()) {
+			printk("BUG: MAX_STACK_TRACE_ENTRIES too low!\n");
+			printk("turning off the locking correctness validator.\n");
+			dump_stack();
+		}
+		return 0;
+	}
+
+	return 1;
+}
+
+unsigned int nr_hardirq_chains;
+unsigned int nr_softirq_chains;
+unsigned int nr_process_chains;
+unsigned int max_lockdep_depth;
+unsigned int max_recursion_depth;
+
+#ifdef CONFIG_DEBUG_LOCKDEP
+/*
+ * We cannot printk in early bootup code. Not even early_printk()
+ * might work. So we mark any initialization errors and printk
+ * about it later on, in lockdep_info().
+ */
+static int lockdep_init_error;
+
+/*
+ * Various lockdep statistics:
+ */
+atomic_t chain_lookup_hits;
+atomic_t chain_lookup_misses;
+atomic_t hardirqs_on_events;
+atomic_t hardirqs_off_events;
+atomic_t redundant_hardirqs_on;
+atomic_t redundant_hardirqs_off;
+atomic_t softirqs_on_events;
+atomic_t softirqs_off_events;
+atomic_t redundant_softirqs_on;
+atomic_t redundant_softirqs_off;
+atomic_t nr_unused_locks;
+atomic_t nr_cyclic_checks;
+atomic_t nr_cyclic_check_recursions;
+atomic_t nr_find_usage_forwards_checks;
+atomic_t nr_find_usage_forwards_recursions;
+atomic_t nr_find_usage_backwards_checks;
+atomic_t nr_find_usage_backwards_recursions;
+# define debug_atomic_inc(ptr)		atomic_inc(ptr)
+# define debug_atomic_dec(ptr)		atomic_dec(ptr)
+# define debug_atomic_read(ptr)		atomic_read(ptr)
+#else
+# define debug_atomic_inc(ptr)		do { } while (0)
+# define debug_atomic_dec(ptr)		do { } while (0)
+# define debug_atomic_read(ptr)		0
+#endif
+
+/*
+ * Locking printouts:
+ */
+
+static const char *usage_str[] =
+{
+	[LOCK_USED] =			"initial-use ",
+	[LOCK_USED_IN_HARDIRQ] =	"in-hardirq-W",
+	[LOCK_USED_IN_SOFTIRQ] =	"in-softirq-W",
+	[LOCK_ENABLED_SOFTIRQS] =	"softirq-on-W",
+	[LOCK_ENABLED_HARDIRQS] =	"hardirq-on-W",
+	[LOCK_USED_IN_HARDIRQ_READ] =	"in-hardirq-R",
+	[LOCK_USED_IN_SOFTIRQ_READ] =	"in-softirq-R",
+	[LOCK_ENABLED_SOFTIRQS_READ] =	"softirq-on-R",
+	[LOCK_ENABLED_HARDIRQS_READ] =	"hardirq-on-R",
+};
+
+const char * __get_key_name(struct lockdep_subclass_key *key, char *str)
+{
+	unsigned long offs, size;
+	char *modname;
+
+	return kallsyms_lookup((unsigned long)key, &size, &offs, &modname, str);
+}
+
+void
+get_usage_chars(struct lock_class *class, char *c1, char *c2, char *c3, char *c4)
+{
+	*c1 = '.', *c2 = '.', *c3 = '.', *c4 = '.';
+
+	if (class->usage_mask & LOCKF_USED_IN_HARDIRQ)
+		*c1 = '+';
+	else
+		if (class->usage_mask & LOCKF_ENABLED_HARDIRQS)
+			*c1 = '-';
+
+	if (class->usage_mask & LOCKF_USED_IN_SOFTIRQ)
+		*c2 = '+';
+	else
+		if (class->usage_mask & LOCKF_ENABLED_SOFTIRQS)
+			*c2 = '-';
+
+	if (class->usage_mask & LOCKF_ENABLED_HARDIRQS_READ)
+		*c3 = '-';
+	if (class->usage_mask & LOCKF_USED_IN_HARDIRQ_READ) {
+		*c3 = '+';
+		if (class->usage_mask & LOCKF_ENABLED_HARDIRQS_READ)
+			*c3 = '?';
+	}
+
+	if (class->usage_mask & LOCKF_ENABLED_SOFTIRQS_READ)
+		*c4 = '-';
+	if (class->usage_mask & LOCKF_USED_IN_SOFTIRQ_READ) {
+		*c4 = '+';
+		if (class->usage_mask & LOCKF_ENABLED_SOFTIRQS_READ)
+			*c4 = '?';
+	}
+}
+
+static void print_lock_name(struct lock_class *class)
+{
+	char str[128], c1, c2, c3, c4;
+	const char *name;
+
+	get_usage_chars(class, &c1, &c2, &c3, &c4);
+
+	name = class->name;
+	if (!name) {
+		name = __get_key_name(class->key, str);
+		printk(" (%s", name);
+	} else {
+		printk(" (%s", name);
+		if (class->name_version > 1)
+			printk("#%d", class->name_version);
+		if (class->subclass)
+			printk("/%d", class->subclass);
+	}
+	printk("){%c%c%c%c}", c1, c2, c3, c4);
+}
+
+static void print_lockdep_cache(struct lockdep_map *lock)
+{
+	const char *name;
+	char str[128];
+
+	name = lock->name;
+	if (!name)
+		name = __get_key_name(lock->key->subkeys, str);
+
+	printk("%s", name);
+}
+
+static void print_lock(struct held_lock *hlock)
+{
+	print_lock_name(hlock->class);
+	printk(", at: ");
+	print_ip_sym(hlock->acquire_ip);
+}
+
+static void lockdep_print_held_locks(struct task_struct *curr)
+{
+	int i, depth = curr->lockdep_depth;
+
+	if (!depth) {
+		printk("no locks held by %s/%d.\n", curr->comm, curr->pid);
+		return;
+	}
+	printk("%d lock%s held by %s/%d:\n",
+		depth, depth > 1 ? "s" : "", curr->comm, curr->pid);
+
+	for (i = 0; i < depth; i++) {
+		printk(" #%d: ", i);
+		print_lock(curr->held_locks + i);
+	}
+}
+
+static void print_lock_class_header(struct lock_class *class, int depth)
+{
+	int bit;
+
+	printk("%*s->", depth, "");
+	print_lock_name(class);
+	printk(" ops: %lu", class->ops);
+	printk(" {\n");
+
+	for (bit = 0; bit < LOCK_USAGE_STATES; bit++) {
+		if (class->usage_mask & (1 << bit)) {
+			int len = depth;
+
+			len += printk("%*s   %s", depth, "", usage_str[bit]);
+			len += printk(" at:\n");
+			print_stack_trace(class->usage_traces + bit, len);
+		}
+	}
+	printk("%*s }\n", depth, "");
+
+	printk("%*s ... key      at: ",depth,"");
+	print_ip_sym((unsigned long)class->key);
+}
+
+/*
+ * printk all lock dependencies starting at <entry>:
+ */
+static void print_lock_dependencies(struct lock_class *class, int depth)
+{
+	struct lock_list *entry;
+
+	if (DEBUG_LOCKS_WARN_ON(depth >= 20))
+		return;
+
+	print_lock_class_header(class, depth);
+
+	list_for_each_entry(entry, &class->locks_after, entry) {
+		DEBUG_LOCKS_WARN_ON(!entry->class);
+		print_lock_dependencies(entry->class, depth + 1);
+
+		printk("%*s ... acquired at:\n",depth,"");
+		print_stack_trace(&entry->trace, 2);
+		printk("\n");
+	}
+}
+
+/*
+ * Add a new dependency to the head of the list:
+ */
+static int add_lock_to_list(struct lock_class *class, struct lock_class *this,
+			    struct list_head *head, unsigned long ip)
+{
+	struct lock_list *entry;
+	/*
+	 * Lock not present yet - get a new dependency struct and
+	 * add it to the list:
+	 */
+	entry = alloc_list_entry();
+	if (!entry)
+		return 0;
+
+	entry->class = this;
+	save_trace(&entry->trace);
+
+	/*
+	 * Since we never remove from the dependency list, the list can
+	 * be walked lockless by other CPUs, it's only allocation
+	 * that must be protected by the spinlock. But this also means
+	 * we must make new entries visible only once writes to the
+	 * entry become visible - hence the RCU op:
+	 */
+	list_add_tail_rcu(&entry->entry, head);
+
+	return 1;
+}
+
+/*
+ * Recursive, forwards-direction lock-dependency checking, used for
+ * both noncyclic checking and for hardirq-unsafe/softirq-unsafe
+ * checking.
+ *
+ * (to keep the stackframe of the recursive functions small we
+ *  use these global variables, and we also mark various helper
+ *  functions as noinline.)
+ */
+static struct held_lock *check_source, *check_target;
+
+/*
+ * Print a dependency chain entry (this is only done when a deadlock
+ * has been detected):
+ */
+static noinline int
+print_circular_bug_entry(struct lock_list *target, unsigned int depth)
+{
+	if (debug_locks_silent)
+		return 0;
+	printk("\n-> #%u", depth);
+	print_lock_name(target->class);
+	printk(":\n");
+	print_stack_trace(&target->trace, 6);
+
+	return 0;
+}
+
+static void print_kernel_version(void)
+{
+	printk("%s %.*s\n", system_utsname.release,
+		(int)strcspn(system_utsname.version, " "),
+		system_utsname.version);
+}
+
+/*
+ * When a circular dependency is detected, print the
+ * header first:
+ */
+static noinline int
+print_circular_bug_header(struct lock_list *entry, unsigned int depth)
+{
+	struct task_struct *curr = current;
+
+	__raw_spin_unlock(&hash_lock);
+	debug_locks_off();
+	if (debug_locks_silent)
+		return 0;
+
+	printk("\n=======================================================\n");
+	printk(  "[ INFO: possible circular locking dependency detected ]\n");
+	print_kernel_version();
+	printk(  "-------------------------------------------------------\n");
+	printk("%s/%d is trying to acquire lock:\n",
+		curr->comm, curr->pid);
+	print_lock(check_source);
+	printk("\nbut task is already holding lock:\n");
+	print_lock(check_target);
+	printk("\nwhich lock already depends on the new lock.\n\n");
+	printk("\nthe existing dependency chain (in reverse order) is:\n");
+
+	print_circular_bug_entry(entry, depth);
+
+	return 0;
+}
+
+static noinline int print_circular_bug_tail(void)
+{
+	struct task_struct *curr = current;
+	struct lock_list this;
+
+	if (debug_locks_silent)
+		return 0;
+
+	this.class = check_source->class;
+	save_trace(&this.trace);
+	print_circular_bug_entry(&this, 0);
+
+	printk("\nother info that might help us debug this:\n\n");
+	lockdep_print_held_locks(curr);
+
+	printk("\nstack backtrace:\n");
+	dump_stack();
+
+	return 0;
+}
+
+static int noinline print_infinite_recursion_bug(void)
+{
+	__raw_spin_unlock(&hash_lock);
+	DEBUG_LOCKS_WARN_ON(1);
+
+	return 0;
+}
+
+/*
+ * Prove that the dependency graph starting at <entry> can not
+ * lead to <target>. Print an error and return 0 if it does.
+ */
+static noinline int
+check_noncircular(struct lock_class *source, unsigned int depth)
+{
+	struct lock_list *entry;
+
+	debug_atomic_inc(&nr_cyclic_check_recursions);
+	if (depth > max_recursion_depth)
+		max_recursion_depth = depth;
+	if (depth >= 20)
+		return print_infinite_recursion_bug();
+	/*
+	 * Check this lock's dependency list:
+	 */
+	list_for_each_entry(entry, &source->locks_after, entry) {
+		if (entry->class == check_target->class)
+			return print_circular_bug_header(entry, depth+1);
+		debug_atomic_inc(&nr_cyclic_checks);
+		if (!check_noncircular(entry->class, depth+1))
+			return print_circular_bug_entry(entry, depth+1);
+	}
+	return 1;
+}
+
+static int very_verbose(struct lock_class *class)
+{
+#if VERY_VERBOSE
+	return class_filter(class);
+#endif
+	return 0;
+}
+#ifdef CONFIG_TRACE_IRQFLAGS
+
+/*
+ * Forwards and backwards subgraph searching, for the purposes of
+ * proving that two subgraphs can be connected by a new dependency
+ * without creating any illegal irq-safe -> irq-unsafe lock dependency.
+ */
+static enum lock_usage_bit find_usage_bit;
+static struct lock_class *forwards_match, *backwards_match;
+
+/*
+ * Find a node in the forwards-direction dependency sub-graph starting
+ * at <source> that matches <find_usage_bit>.
+ *
+ * Return 2 if such a node exists in the subgraph, and put that node
+ * into <forwards_match>.
+ *
+ * Return 1 otherwise and keep <forwards_match> unchanged.
+ * Return 0 on error.
+ */
+static noinline int
+find_usage_forwards(struct lock_class *source, unsigned int depth)
+{
+	struct lock_list *entry;
+	int ret;
+
+	if (depth > max_recursion_depth)
+		max_recursion_depth = depth;
+	if (depth >= 20)
+		return print_infinite_recursion_bug();
+
+	debug_atomic_inc(&nr_find_usage_forwards_checks);
+	if (source->usage_mask & (1 << find_usage_bit)) {
+		forwards_match = source;
+		return 2;
+	}
+
+	/*
+	 * Check this lock's dependency list:
+	 */
+	list_for_each_entry(entry, &source->locks_after, entry) {
+		debug_atomic_inc(&nr_find_usage_forwards_recursions);
+		ret = find_usage_forwards(entry->class, depth+1);
+		if (ret == 2 || ret == 0)
+			return ret;
+	}
+	return 1;
+}
+
+/*
+ * Find a node in the backwards-direction dependency sub-graph starting
+ * at <source> that matches <find_usage_bit>.
+ *
+ * Return 2 if such a node exists in the subgraph, and put that node
+ * into <backwards_match>.
+ *
+ * Return 1 otherwise and keep <backwards_match> unchanged.
+ * Return 0 on error.
+ */
+static noinline int
+find_usage_backwards(struct lock_class *source, unsigned int depth)
+{
+	struct lock_list *entry;
+	int ret;
+
+	if (depth > max_recursion_depth)
+		max_recursion_depth = depth;
+	if (depth >= 20)
+		return print_infinite_recursion_bug();
+
+	debug_atomic_inc(&nr_find_usage_backwards_checks);
+	if (source->usage_mask & (1 << find_usage_bit)) {
+		backwards_match = source;
+		return 2;
+	}
+
+	/*
+	 * Check this lock's dependency list:
+	 */
+	list_for_each_entry(entry, &source->locks_before, entry) {
+		debug_atomic_inc(&nr_find_usage_backwards_recursions);
+		ret = find_usage_backwards(entry->class, depth+1);
+		if (ret == 2 || ret == 0)
+			return ret;
+	}
+	return 1;
+}
+
+static int
+print_bad_irq_dependency(struct task_struct *curr,
+			 struct held_lock *prev,
+			 struct held_lock *next,
+			 enum lock_usage_bit bit1,
+			 enum lock_usage_bit bit2,
+			 const char *irqclass)
+{
+	__raw_spin_unlock(&hash_lock);
+	debug_locks_off();
+	if (debug_locks_silent)
+		return 0;
+
+	printk("\n======================================================\n");
+	printk(  "[ INFO: %s-safe -> %s-unsafe lock order detected ]\n",
+		irqclass, irqclass);
+	print_kernel_version();
+	printk(  "------------------------------------------------------\n");
+	printk("%s/%d [HC%u[%lu]:SC%u[%lu]:HE%u:SE%u] is trying to acquire:\n",
+		curr->comm, curr->pid,
+		curr->hardirq_context, hardirq_count() >> HARDIRQ_SHIFT,
+		curr->softirq_context, softirq_count() >> SOFTIRQ_SHIFT,
+		curr->hardirqs_enabled,
+		curr->softirqs_enabled);
+	print_lock(next);
+
+	printk("\nand this task is already holding:\n");
+	print_lock(prev);
+	printk("which would create a new lock dependency:\n");
+	print_lock_name(prev->class);
+	printk(" ->");
+	print_lock_name(next->class);
+	printk("\n");
+
+	printk("\nbut this new dependency connects a %s-irq-safe lock:\n",
+		irqclass);
+	print_lock_name(backwards_match);
+	printk("\n... which became %s-irq-safe at:\n", irqclass);
+
+	print_stack_trace(backwards_match->usage_traces + bit1, 1);
+
+	printk("\nto a %s-irq-unsafe lock:\n", irqclass);
+	print_lock_name(forwards_match);
+	printk("\n... which became %s-irq-unsafe at:\n", irqclass);
+	printk("...");
+
+	print_stack_trace(forwards_match->usage_traces + bit2, 1);
+
+	printk("\nother info that might help us debug this:\n\n");
+	lockdep_print_held_locks(curr);
+
+	printk("\nthe %s-irq-safe lock's dependencies:\n", irqclass);
+	print_lock_dependencies(backwards_match, 0);
+
+	printk("\nthe %s-irq-unsafe lock's dependencies:\n", irqclass);
+	print_lock_dependencies(forwards_match, 0);
+
+	printk("\nstack backtrace:\n");
+	dump_stack();
+
+	return 0;
+}
+
+static int
+check_usage(struct task_struct *curr, struct held_lock *prev,
+	    struct held_lock *next, enum lock_usage_bit bit_backwards,
+	    enum lock_usage_bit bit_forwards, const char *irqclass)
+{
+	int ret;
+
+	find_usage_bit = bit_backwards;
+	/* fills in <backwards_match> */
+	ret = find_usage_backwards(prev->class, 0);
+	if (!ret || ret == 1)
+		return ret;
+
+	find_usage_bit = bit_forwards;
+	ret = find_usage_forwards(next->class, 0);
+	if (!ret || ret == 1)
+		return ret;
+	/* ret == 2 */
+	return print_bad_irq_dependency(curr, prev, next,
+			bit_backwards, bit_forwards, irqclass);
+}
+
+#endif
+
+static int
+print_deadlock_bug(struct task_struct *curr, struct held_lock *prev,
+		   struct held_lock *next)
+{
+	debug_locks_off();
+	__raw_spin_unlock(&hash_lock);
+	if (debug_locks_silent)
+		return 0;
+
+	printk("\n=============================================\n");
+	printk(  "[ INFO: possible recursive locking detected ]\n");
+	print_kernel_version();
+	printk(  "---------------------------------------------\n");
+	printk("%s/%d is trying to acquire lock:\n",
+		curr->comm, curr->pid);
+	print_lock(next);
+	printk("\nbut task is already holding lock:\n");
+	print_lock(prev);
+
+	printk("\nother info that might help us debug this:\n");
+	lockdep_print_held_locks(curr);
+
+	printk("\nstack backtrace:\n");
+	dump_stack();
+
+	return 0;
+}
+
+/*
+ * Check whether we are holding such a class already.
+ *
+ * (Note that this has to be done separately, because the graph cannot
+ * detect such classes of deadlocks.)
+ *
+ * Returns: 0 on deadlock detected, 1 on OK, 2 on recursive read
+ */
+static int
+check_deadlock(struct task_struct *curr, struct held_lock *next,
+	       struct lockdep_map *next_instance, int read)
+{
+	struct held_lock *prev;
+	int i;
+
+	for (i = 0; i < curr->lockdep_depth; i++) {
+		prev = curr->held_locks + i;
+		if (prev->class != next->class)
+			continue;
+		/*
+		 * Allow read-after-read recursion of the same
+		 * lock class (i.e. read_lock(lock)+read_lock(lock)):
+		 */
+		if ((read == 2) && prev->read)
+			return 2;
+		return print_deadlock_bug(curr, prev, next);
+	}
+	return 1;
+}
+
+/*
+ * There was a chain-cache miss, and we are about to add a new dependency
+ * to a previous lock. We recursively validate the following rules:
+ *
+ *  - would the adding of the <prev> -> <next> dependency create a
+ *    circular dependency in the graph? [== circular deadlock]
+ *
+ *  - does the new prev->next dependency connect any hardirq-safe lock
+ *    (in the full backwards-subgraph starting at <prev>) with any
+ *    hardirq-unsafe lock (in the full forwards-subgraph starting at
+ *    <next>)? [== illegal lock inversion with hardirq contexts]
+ *
+ *  - does the new prev->next dependency connect any softirq-safe lock
+ *    (in the full backwards-subgraph starting at <prev>) with any
+ *    softirq-unsafe lock (in the full forwards-subgraph starting at
+ *    <next>)? [== illegal lock inversion with softirq contexts]
+ *
+ * any of these scenarios could lead to a deadlock.
+ *
+ * Then if all the validations pass, we add the forwards and backwards
+ * dependency.
+ */
+static int
+check_prev_add(struct task_struct *curr, struct held_lock *prev,
+	       struct held_lock *next)
+{
+	struct lock_list *entry;
+	int ret;
+
+	/*
+	 * Prove that the new <prev> -> <next> dependency would not
+	 * create a circular dependency in the graph. (We do this by
+	 * forward-recursing into the graph starting at <next>, and
+	 * checking whether we can reach <prev>.)
+	 *
+	 * We are using global variables to control the recursion, to
+	 * keep the stackframe size of the recursive functions low:
+	 */
+	check_source = next;
+	check_target = prev;
+	if (!(check_noncircular(next->class, 0)))
+		return print_circular_bug_tail();
+
+#ifdef CONFIG_TRACE_IRQFLAGS
+	/*
+	 * Prove that the new dependency does not connect a hardirq-safe
+	 * lock with a hardirq-unsafe lock - to achieve this we search
+	 * the backwards-subgraph starting at <prev>, and the
+	 * forwards-subgraph starting at <next>:
+	 */
+	if (!check_usage(curr, prev, next, LOCK_USED_IN_HARDIRQ,
+					LOCK_ENABLED_HARDIRQS, "hard"))
+		return 0;
+
+	/*
+	 * Prove that the new dependency does not connect a hardirq-safe-read
+	 * lock with a hardirq-unsafe lock - to achieve this we search
+	 * the backwards-subgraph starting at <prev>, and the
+	 * forwards-subgraph starting at <next>:
+	 */
+	if (!check_usage(curr, prev, next, LOCK_USED_IN_HARDIRQ_READ,
+					LOCK_ENABLED_HARDIRQS, "hard-read"))
+		return 0;
+
+	/*
+	 * Prove that the new dependency does not connect a softirq-safe
+	 * lock with a softirq-unsafe lock - to achieve this we search
+	 * the backwards-subgraph starting at <prev>, and the
+	 * forwards-subgraph starting at <next>:
+	 */
+	if (!check_usage(curr, prev, next, LOCK_USED_IN_SOFTIRQ,
+					LOCK_ENABLED_SOFTIRQS, "soft"))
+		return 0;
+	/*
+	 * Prove that the new dependency does not connect a softirq-safe-read
+	 * lock with a softirq-unsafe lock - to achieve this we search
+	 * the backwards-subgraph starting at <prev>, and the
+	 * forwards-subgraph starting at <next>:
+	 */
+	if (!check_usage(curr, prev, next, LOCK_USED_IN_SOFTIRQ_READ,
+					LOCK_ENABLED_SOFTIRQS, "soft"))
+		return 0;
+#endif
+	/*
+	 * For recursive read-locks we do all the dependency checks,
+	 * but we dont store read-triggered dependencies (only
+	 * write-triggered dependencies). This ensures that only the
+	 * write-side dependencies matter, and that if for example a
+	 * write-lock never takes any other locks, then the reads are
+	 * equivalent to a NOP.
+	 */
+	if (next->read == 2 || prev->read == 2)
+		return 1;
+	/*
+	 * Is the <prev> -> <next> dependency already present?
+	 *
+	 * (this may occur even though this is a new chain: consider
+	 *  e.g. the L1 -> L2 -> L3 -> L4 and the L5 -> L1 -> L2 -> L3
+	 *  chains - the second one will be new, but L1 already has
+	 *  L2 added to its dependency list, due to the first chain.)
+	 */
+	list_for_each_entry(entry, &prev->class->locks_after, entry) {
+		if (entry->class == next->class)
+			return 2;
+	}
+
+	/*
+	 * Ok, all validations passed, add the new lock
+	 * to the previous lock's dependency list:
+	 */
+	ret = add_lock_to_list(prev->class, next->class,
+			       &prev->class->locks_after, next->acquire_ip);
+	if (!ret)
+		return 0;
+	/*
+	 * Return value of 2 signals 'dependency already added',
+	 * in that case we dont have to add the backlink either.
+	 */
+	if (ret == 2)
+		return 2;
+	ret = add_lock_to_list(next->class, prev->class,
+			       &next->class->locks_before, next->acquire_ip);
+
+	/*
+	 * Debugging printouts:
+	 */
+	if (verbose(prev->class) || verbose(next->class)) {
+		__raw_spin_unlock(&hash_lock);
+		printk("\n new dependency: ");
+		print_lock_name(prev->class);
+		printk(" => ");
+		print_lock_name(next->class);
+		printk("\n");
+		dump_stack();
+		__raw_spin_lock(&hash_lock);
+	}
+	return 1;
+}
+
+/*
+ * Add the dependency to all directly-previous locks that are 'relevant'.
+ * The ones that are relevant are (in increasing distance from curr):
+ * all consecutive trylock entries and the final non-trylock entry - or
+ * the end of this context's lock-chain - whichever comes first.
+ */
+static int
+check_prevs_add(struct task_struct *curr, struct held_lock *next)
+{
+	int depth = curr->lockdep_depth;
+	struct held_lock *hlock;
+
+	/*
+	 * Debugging checks.
+	 *
+	 * Depth must not be zero for a non-head lock:
+	 */
+	if (!depth)
+		goto out_bug;
+	/*
+	 * At least two relevant locks must exist for this
+	 * to be a head:
+	 */
+	if (curr->held_locks[depth].irq_context !=
+			curr->held_locks[depth-1].irq_context)
+		goto out_bug;
+
+	for (;;) {
+		hlock = curr->held_locks + depth-1;
+		/*
+		 * Only non-recursive-read entries get new dependencies
+		 * added:
+		 */
+		if (hlock->read != 2) {
+			check_prev_add(curr, hlock, next);
+			/*
+			 * Stop after the first non-trylock entry,
+			 * as non-trylock entries have added their
+			 * own direct dependencies already, so this
+			 * lock is connected to them indirectly:
+			 */
+			if (!hlock->trylock)
+				break;
+		}
+		depth--;
+		/*
+		 * End of lock-stack?
+		 */
+		if (!depth)
+			break;
+		/*
+		 * Stop the search if we cross into another context:
+		 */
+		if (curr->held_locks[depth].irq_context !=
+				curr->held_locks[depth-1].irq_context)
+			break;
+	}
+	return 1;
+out_bug:
+	__raw_spin_unlock(&hash_lock);
+	DEBUG_LOCKS_WARN_ON(1);
+
+	return 0;
+}
+
+
+/*
+ * Is this the address of a static object:
+ */
+static int static_obj(void *obj)
+{
+	unsigned long start = (unsigned long) &_stext,
+		      end   = (unsigned long) &_end,
+		      addr  = (unsigned long) obj;
+#ifdef CONFIG_SMP
+	int i;
+#endif
+
+	/*
+	 * static variable?
+	 */
+	if ((addr >= start) && (addr < end))
+		return 1;
+
+#ifdef CONFIG_SMP
+	/*
+	 * percpu var?
+	 */
+	for_each_possible_cpu(i) {
+		start = (unsigned long) &__per_cpu_start + per_cpu_offset(i);
+		end   = (unsigned long) &__per_cpu_end   + per_cpu_offset(i);
+
+		if ((addr >= start) && (addr < end))
+			return 1;
+	}
+#endif
+
+	/*
+	 * module var?
+	 */
+	return is_module_address(addr);
+}
+
+/*
+ * To make lock name printouts unique, we calculate a unique
+ * class->name_version generation counter:
+ */
+static int count_matching_names(struct lock_class *new_class)
+{
+	struct lock_class *class;
+	int count = 0;
+
+	if (!new_class->name)
+		return 0;
+
+	list_for_each_entry(class, &all_lock_classes, lock_entry) {
+		if (new_class->key - new_class->subclass == class->key)
+			return class->name_version;
+		if (class->name && !strcmp(class->name, new_class->name))
+			count = max(count, class->name_version);
+	}
+
+	return count + 1;
+}
+
+extern void __error_too_big_MAX_LOCKDEP_SUBCLASSES(void);
+
+/*
+ * Register a lock's class in the hash-table, if the class is not present
+ * yet. Otherwise we look it up. We cache the result in the lock object
+ * itself, so actual lookup of the hash should be once per lock object.
+ */
+static inline struct lock_class *
+look_up_lock_class(struct lockdep_map *lock, unsigned int subclass)
+{
+	struct lockdep_subclass_key *key;
+	struct list_head *hash_head;
+	struct lock_class *class;
+
+#ifdef CONFIG_DEBUG_LOCKDEP
+	/*
+	 * If the architecture calls into lockdep before initializing
+	 * the hashes then we'll warn about it later. (we cannot printk
+	 * right now)
+	 */
+	if (unlikely(!lockdep_initialized)) {
+		lockdep_init();
+		lockdep_init_error = 1;
+	}
+#endif
+
+	/*
+	 * Static locks do not have their class-keys yet - for them the key
+	 * is the lock object itself:
+	 */
+	if (unlikely(!lock->key))
+		lock->key = (void *)lock;
+
+	/*
+	 * NOTE: the class-key must be unique. For dynamic locks, a static
+	 * lock_class_key variable is passed in through the mutex_init()
+	 * (or spin_lock_init()) call - which acts as the key. For static
+	 * locks we use the lock object itself as the key.
+	 */
+	if (sizeof(struct lock_class_key) > sizeof(struct lock_class))
+		__error_too_big_MAX_LOCKDEP_SUBCLASSES();
+
+	key = lock->key->subkeys + subclass;
+
+	hash_head = classhashentry(key);
+
+	/*
+	 * We can walk the hash lockfree, because the hash only
+	 * grows, and we are careful when adding entries to the end:
+	 */
+	list_for_each_entry(class, hash_head, hash_entry)
+		if (class->key == key)
+			return class;
+
+	return NULL;
+}
+
+/*
+ * Register a lock's class in the hash-table, if the class is not present
+ * yet. Otherwise we look it up. We cache the result in the lock object
+ * itself, so actual lookup of the hash should be once per lock object.
+ */
+static inline struct lock_class *
+register_lock_class(struct lockdep_map *lock, unsigned int subclass, int force)
+{
+	struct lockdep_subclass_key *key;
+	struct list_head *hash_head;
+	struct lock_class *class;
+
+	class = look_up_lock_class(lock, subclass);
+	if (likely(class))
+		return class;
+
+	/*
+	 * Debug-check: all keys must be persistent!
+ 	 */
+	if (!static_obj(lock->key)) {
+		debug_locks_off();
+		printk("INFO: trying to register non-static key.\n");
+		printk("the code is fine but needs lockdep annotation.\n");
+		printk("turning off the locking correctness validator.\n");
+		dump_stack();
+
+		return NULL;
+	}
+
+	key = lock->key->subkeys + subclass;
+	hash_head = classhashentry(key);
+
+	__raw_spin_lock(&hash_lock);
+	/*
+	 * We have to do the hash-walk again, to avoid races
+	 * with another CPU:
+	 */
+	list_for_each_entry(class, hash_head, hash_entry)
+		if (class->key == key)
+			goto out_unlock_set;
+	/*
+	 * Allocate a new key from the static array, and add it to
+	 * the hash:
+	 */
+	if (nr_lock_classes >= MAX_LOCKDEP_KEYS) {
+		__raw_spin_unlock(&hash_lock);
+		debug_locks_off();
+		printk("BUG: MAX_LOCKDEP_KEYS too low!\n");
+		printk("turning off the locking correctness validator.\n");
+		return NULL;
+	}
+	class = lock_classes + nr_lock_classes++;
+	debug_atomic_inc(&nr_unused_locks);
+	class->key = key;
+	class->name = lock->name;
+	class->subclass = subclass;
+	INIT_LIST_HEAD(&class->lock_entry);
+	INIT_LIST_HEAD(&class->locks_before);
+	INIT_LIST_HEAD(&class->locks_after);
+	class->name_version = count_matching_names(class);
+	/*
+	 * We use RCU's safe list-add method to make
+	 * parallel walking of the hash-list safe:
+	 */
+	list_add_tail_rcu(&class->hash_entry, hash_head);
+
+	if (verbose(class)) {
+		__raw_spin_unlock(&hash_lock);
+		printk("\nnew class %p: %s", class->key, class->name);
+		if (class->name_version > 1)
+			printk("#%d", class->name_version);
+		printk("\n");
+		dump_stack();
+		__raw_spin_lock(&hash_lock);
+	}
+out_unlock_set:
+	__raw_spin_unlock(&hash_lock);
+
+	if (!subclass || force)
+		lock->class_cache = class;
+
+	DEBUG_LOCKS_WARN_ON(class->subclass != subclass);
+
+	return class;
+}
+
+/*
+ * Look up a dependency chain. If the key is not present yet then
+ * add it and return 0 - in this case the new dependency chain is
+ * validated. If the key is already hashed, return 1.
+ */
+static inline int lookup_chain_cache(u64 chain_key)
+{
+	struct list_head *hash_head = chainhashentry(chain_key);
+	struct lock_chain *chain;
+
+	DEBUG_LOCKS_WARN_ON(!irqs_disabled());
+	/*
+	 * We can walk it lock-free, because entries only get added
+	 * to the hash:
+	 */
+	list_for_each_entry(chain, hash_head, entry) {
+		if (chain->chain_key == chain_key) {
+cache_hit:
+			debug_atomic_inc(&chain_lookup_hits);
+			/*
+			 * In the debugging case, force redundant checking
+			 * by returning 1:
+			 */
+#ifdef CONFIG_DEBUG_LOCKDEP
+			__raw_spin_lock(&hash_lock);
+			return 1;
+#endif
+			return 0;
+		}
+	}
+	/*
+	 * Allocate a new chain entry from the static array, and add
+	 * it to the hash:
+	 */
+	__raw_spin_lock(&hash_lock);
+	/*
+	 * We have to walk the chain again locked - to avoid duplicates:
+	 */
+	list_for_each_entry(chain, hash_head, entry) {
+		if (chain->chain_key == chain_key) {
+			__raw_spin_unlock(&hash_lock);
+			goto cache_hit;
+		}
+	}
+	if (unlikely(nr_lock_chains >= MAX_LOCKDEP_CHAINS)) {
+		__raw_spin_unlock(&hash_lock);
+		debug_locks_off();
+		printk("BUG: MAX_LOCKDEP_CHAINS too low!\n");
+		printk("turning off the locking correctness validator.\n");
+		return 0;
+	}
+	chain = lock_chains + nr_lock_chains++;
+	chain->chain_key = chain_key;
+	list_add_tail_rcu(&chain->entry, hash_head);
+	debug_atomic_inc(&chain_lookup_misses);
+#ifdef CONFIG_TRACE_IRQFLAGS
+	if (current->hardirq_context)
+		nr_hardirq_chains++;
+	else {
+		if (current->softirq_context)
+			nr_softirq_chains++;
+		else
+			nr_process_chains++;
+	}
+#else
+	nr_process_chains++;
+#endif
+
+	return 1;
+}
+
+/*
+ * We are building curr_chain_key incrementally, so double-check
+ * it from scratch, to make sure that it's done correctly:
+ */
+static void check_chain_key(struct task_struct *curr)
+{
+#ifdef CONFIG_DEBUG_LOCKDEP
+	struct held_lock *hlock, *prev_hlock = NULL;
+	unsigned int i, id;
+	u64 chain_key = 0;
+
+	for (i = 0; i < curr->lockdep_depth; i++) {
+		hlock = curr->held_locks + i;
+		if (chain_key != hlock->prev_chain_key) {
+			debug_locks_off();
+			printk("hm#1, depth: %u [%u], %016Lx != %016Lx\n",
+				curr->lockdep_depth, i,
+				(unsigned long long)chain_key,
+				(unsigned long long)hlock->prev_chain_key);
+			WARN_ON(1);
+			return;
+		}
+		id = hlock->class - lock_classes;
+		DEBUG_LOCKS_WARN_ON(id >= MAX_LOCKDEP_KEYS);
+		if (prev_hlock && (prev_hlock->irq_context !=
+							hlock->irq_context))
+			chain_key = 0;
+		chain_key = iterate_chain_key(chain_key, id);
+		prev_hlock = hlock;
+	}
+	if (chain_key != curr->curr_chain_key) {
+		debug_locks_off();
+		printk("hm#2, depth: %u [%u], %016Lx != %016Lx\n",
+			curr->lockdep_depth, i,
+			(unsigned long long)chain_key,
+			(unsigned long long)curr->curr_chain_key);
+		WARN_ON(1);
+	}
+#endif
+}
+
+#ifdef CONFIG_TRACE_IRQFLAGS
+
+/*
+ * print irq inversion bug:
+ */
+static int
+print_irq_inversion_bug(struct task_struct *curr, struct lock_class *other,
+			struct held_lock *this, int forwards,
+			const char *irqclass)
+{
+	__raw_spin_unlock(&hash_lock);
+	debug_locks_off();
+	if (debug_locks_silent)
+		return 0;
+
+	printk("\n=========================================================\n");
+	printk(  "[ INFO: possible irq lock inversion dependency detected ]\n");
+	print_kernel_version();
+	printk(  "---------------------------------------------------------\n");
+	printk("%s/%d just changed the state of lock:\n",
+		curr->comm, curr->pid);
+	print_lock(this);
+	if (forwards)
+		printk("but this lock took another, %s-irq-unsafe lock in the past:\n", irqclass);
+	else
+		printk("but this lock was taken by another, %s-irq-safe lock in the past:\n", irqclass);
+	print_lock_name(other);
+	printk("\n\nand interrupts could create inverse lock ordering between them.\n\n");
+
+	printk("\nother info that might help us debug this:\n");
+	lockdep_print_held_locks(curr);
+
+	printk("\nthe first lock's dependencies:\n");
+	print_lock_dependencies(this->class, 0);
+
+	printk("\nthe second lock's dependencies:\n");
+	print_lock_dependencies(other, 0);
+
+	printk("\nstack backtrace:\n");
+	dump_stack();
+
+	return 0;
+}
+
+/*
+ * Prove that in the forwards-direction subgraph starting at <this>
+ * there is no lock matching <mask>:
+ */
+static int
+check_usage_forwards(struct task_struct *curr, struct held_lock *this,
+		     enum lock_usage_bit bit, const char *irqclass)
+{
+	int ret;
+
+	find_usage_bit = bit;
+	/* fills in <forwards_match> */
+	ret = find_usage_forwards(this->class, 0);
+	if (!ret || ret == 1)
+		return ret;
+
+	return print_irq_inversion_bug(curr, forwards_match, this, 1, irqclass);
+}
+
+/*
+ * Prove that in the backwards-direction subgraph starting at <this>
+ * there is no lock matching <mask>:
+ */
+static int
+check_usage_backwards(struct task_struct *curr, struct held_lock *this,
+		      enum lock_usage_bit bit, const char *irqclass)
+{
+	int ret;
+
+	find_usage_bit = bit;
+	/* fills in <backwards_match> */
+	ret = find_usage_backwards(this->class, 0);
+	if (!ret || ret == 1)
+		return ret;
+
+	return print_irq_inversion_bug(curr, backwards_match, this, 0, irqclass);
+}
+
+static inline void print_irqtrace_events(struct task_struct *curr)
+{
+	printk("irq event stamp: %u\n", curr->irq_events);
+	printk("hardirqs last  enabled at (%u): ", curr->hardirq_enable_event);
+	print_ip_sym(curr->hardirq_enable_ip);
+	printk("hardirqs last disabled at (%u): ", curr->hardirq_disable_event);
+	print_ip_sym(curr->hardirq_disable_ip);
+	printk("softirqs last  enabled at (%u): ", curr->softirq_enable_event);
+	print_ip_sym(curr->softirq_enable_ip);
+	printk("softirqs last disabled at (%u): ", curr->softirq_disable_event);
+	print_ip_sym(curr->softirq_disable_ip);
+}
+
+#else
+static inline void print_irqtrace_events(struct task_struct *curr)
+{
+}
+#endif
+
+static int
+print_usage_bug(struct task_struct *curr, struct held_lock *this,
+		enum lock_usage_bit prev_bit, enum lock_usage_bit new_bit)
+{
+	__raw_spin_unlock(&hash_lock);
+	debug_locks_off();
+	if (debug_locks_silent)
+		return 0;
+
+	printk("\n=================================\n");
+	printk(  "[ INFO: inconsistent lock state ]\n");
+	print_kernel_version();
+	printk(  "---------------------------------\n");
+
+	printk("inconsistent {%s} -> {%s} usage.\n",
+		usage_str[prev_bit], usage_str[new_bit]);
+
+	printk("%s/%d [HC%u[%lu]:SC%u[%lu]:HE%u:SE%u] takes:\n",
+		curr->comm, curr->pid,
+		trace_hardirq_context(curr), hardirq_count() >> HARDIRQ_SHIFT,
+		trace_softirq_context(curr), softirq_count() >> SOFTIRQ_SHIFT,
+		trace_hardirqs_enabled(curr),
+		trace_softirqs_enabled(curr));
+	print_lock(this);
+
+	printk("{%s} state was registered at:\n", usage_str[prev_bit]);
+	print_stack_trace(this->class->usage_traces + prev_bit, 1);
+
+	print_irqtrace_events(curr);
+	printk("\nother info that might help us debug this:\n");
+	lockdep_print_held_locks(curr);
+
+	printk("\nstack backtrace:\n");
+	dump_stack();
+
+	return 0;
+}
+
+/*
+ * Print out an error if an invalid bit is set:
+ */
+static inline int
+valid_state(struct task_struct *curr, struct held_lock *this,
+	    enum lock_usage_bit new_bit, enum lock_usage_bit bad_bit)
+{
+	if (unlikely(this->class->usage_mask & (1 << bad_bit)))
+		return print_usage_bug(curr, this, bad_bit, new_bit);
+	return 1;
+}
+
+#define STRICT_READ_CHECKS	1
+
+/*
+ * Mark a lock with a usage bit, and validate the state transition:
+ */
+static int mark_lock(struct task_struct *curr, struct held_lock *this,
+		     enum lock_usage_bit new_bit, unsigned long ip)
+{
+	unsigned int new_mask = 1 << new_bit, ret = 1;
+
+	/*
+	 * If already set then do not dirty the cacheline,
+	 * nor do any checks:
+	 */
+	if (likely(this->class->usage_mask & new_mask))
+		return 1;
+
+	__raw_spin_lock(&hash_lock);
+	/*
+	 * Make sure we didnt race:
+	 */
+	if (unlikely(this->class->usage_mask & new_mask)) {
+		__raw_spin_unlock(&hash_lock);
+		return 1;
+	}
+
+	this->class->usage_mask |= new_mask;
+
+#ifdef CONFIG_TRACE_IRQFLAGS
+	if (new_bit == LOCK_ENABLED_HARDIRQS ||
+			new_bit == LOCK_ENABLED_HARDIRQS_READ)
+		ip = curr->hardirq_enable_ip;
+	else if (new_bit == LOCK_ENABLED_SOFTIRQS ||
+			new_bit == LOCK_ENABLED_SOFTIRQS_READ)
+		ip = curr->softirq_enable_ip;
+#endif
+	if (!save_trace(this->class->usage_traces + new_bit))
+		return 0;
+
+	switch (new_bit) {
+#ifdef CONFIG_TRACE_IRQFLAGS
+	case LOCK_USED_IN_HARDIRQ:
+		if (!valid_state(curr, this, new_bit, LOCK_ENABLED_HARDIRQS))
+			return 0;
+		if (!valid_state(curr, this, new_bit,
+				 LOCK_ENABLED_HARDIRQS_READ))
+			return 0;
+		/*
+		 * just marked it hardirq-safe, check that this lock
+		 * took no hardirq-unsafe lock in the past:
+		 */
+		if (!check_usage_forwards(curr, this,
+					  LOCK_ENABLED_HARDIRQS, "hard"))
+			return 0;
+#if STRICT_READ_CHECKS
+		/*
+		 * just marked it hardirq-safe, check that this lock
+		 * took no hardirq-unsafe-read lock in the past:
+		 */
+		if (!check_usage_forwards(curr, this,
+				LOCK_ENABLED_HARDIRQS_READ, "hard-read"))
+			return 0;
+#endif
+		if (hardirq_verbose(this->class))
+			ret = 2;
+		break;
+	case LOCK_USED_IN_SOFTIRQ:
+		if (!valid_state(curr, this, new_bit, LOCK_ENABLED_SOFTIRQS))
+			return 0;
+		if (!valid_state(curr, this, new_bit,
+				 LOCK_ENABLED_SOFTIRQS_READ))
+			return 0;
+		/*
+		 * just marked it softirq-safe, check that this lock
+		 * took no softirq-unsafe lock in the past:
+		 */
+		if (!check_usage_forwards(curr, this,
+					  LOCK_ENABLED_SOFTIRQS, "soft"))
+			return 0;
+#if STRICT_READ_CHECKS
+		/*
+		 * just marked it softirq-safe, check that this lock
+		 * took no softirq-unsafe-read lock in the past:
+		 */
+		if (!check_usage_forwards(curr, this,
+				LOCK_ENABLED_SOFTIRQS_READ, "soft-read"))
+			return 0;
+#endif
+		if (softirq_verbose(this->class))
+			ret = 2;
+		break;
+	case LOCK_USED_IN_HARDIRQ_READ:
+		if (!valid_state(curr, this, new_bit, LOCK_ENABLED_HARDIRQS))
+			return 0;
+		/*
+		 * just marked it hardirq-read-safe, check that this lock
+		 * took no hardirq-unsafe lock in the past:
+		 */
+		if (!check_usage_forwards(curr, this,
+					  LOCK_ENABLED_HARDIRQS, "hard"))
+			return 0;
+		if (hardirq_verbose(this->class))
+			ret = 2;
+		break;
+	case LOCK_USED_IN_SOFTIRQ_READ:
+		if (!valid_state(curr, this, new_bit, LOCK_ENABLED_SOFTIRQS))
+			return 0;
+		/*
+		 * just marked it softirq-read-safe, check that this lock
+		 * took no softirq-unsafe lock in the past:
+		 */
+		if (!check_usage_forwards(curr, this,
+					  LOCK_ENABLED_SOFTIRQS, "soft"))
+			return 0;
+		if (softirq_verbose(this->class))
+			ret = 2;
+		break;
+	case LOCK_ENABLED_HARDIRQS:
+		if (!valid_state(curr, this, new_bit, LOCK_USED_IN_HARDIRQ))
+			return 0;
+		if (!valid_state(curr, this, new_bit,
+				 LOCK_USED_IN_HARDIRQ_READ))
+			return 0;
+		/*
+		 * just marked it hardirq-unsafe, check that no hardirq-safe
+		 * lock in the system ever took it in the past:
+		 */
+		if (!check_usage_backwards(curr, this,
+					   LOCK_USED_IN_HARDIRQ, "hard"))
+			return 0;
+#if STRICT_READ_CHECKS
+		/*
+		 * just marked it hardirq-unsafe, check that no
+		 * hardirq-safe-read lock in the system ever took
+		 * it in the past:
+		 */
+		if (!check_usage_backwards(curr, this,
+				   LOCK_USED_IN_HARDIRQ_READ, "hard-read"))
+			return 0;
+#endif
+		if (hardirq_verbose(this->class))
+			ret = 2;
+		break;
+	case LOCK_ENABLED_SOFTIRQS:
+		if (!valid_state(curr, this, new_bit, LOCK_USED_IN_SOFTIRQ))
+			return 0;
+		if (!valid_state(curr, this, new_bit,
+				 LOCK_USED_IN_SOFTIRQ_READ))
+			return 0;
+		/*
+		 * just marked it softirq-unsafe, check that no softirq-safe
+		 * lock in the system ever took it in the past:
+		 */
+		if (!check_usage_backwards(curr, this,
+					   LOCK_USED_IN_SOFTIRQ, "soft"))
+			return 0;
+#if STRICT_READ_CHECKS
+		/*
+		 * just marked it softirq-unsafe, check that no
+		 * softirq-safe-read lock in the system ever took
+		 * it in the past:
+		 */
+		if (!check_usage_backwards(curr, this,
+				   LOCK_USED_IN_SOFTIRQ_READ, "soft-read"))
+			return 0;
+#endif
+		if (softirq_verbose(this->class))
+			ret = 2;
+		break;
+	case LOCK_ENABLED_HARDIRQS_READ:
+		if (!valid_state(curr, this, new_bit, LOCK_USED_IN_HARDIRQ))
+			return 0;
+#if STRICT_READ_CHECKS
+		/*
+		 * just marked it hardirq-read-unsafe, check that no
+		 * hardirq-safe lock in the system ever took it in the past:
+		 */
+		if (!check_usage_backwards(curr, this,
+					   LOCK_USED_IN_HARDIRQ, "hard"))
+			return 0;
+#endif
+		if (hardirq_verbose(this->class))
+			ret = 2;
+		break;
+	case LOCK_ENABLED_SOFTIRQS_READ:
+		if (!valid_state(curr, this, new_bit, LOCK_USED_IN_SOFTIRQ))
+			return 0;
+#if STRICT_READ_CHECKS
+		/*
+		 * just marked it softirq-read-unsafe, check that no
+		 * softirq-safe lock in the system ever took it in the past:
+		 */
+		if (!check_usage_backwards(curr, this,
+					   LOCK_USED_IN_SOFTIRQ, "soft"))
+			return 0;
+#endif
+		if (softirq_verbose(this->class))
+			ret = 2;
+		break;
+#endif
+	case LOCK_USED:
+		/*
+		 * Add it to the global list of classes:
+		 */
+		list_add_tail_rcu(&this->class->lock_entry, &all_lock_classes);
+		debug_atomic_dec(&nr_unused_locks);
+		break;
+	default:
+		debug_locks_off();
+		WARN_ON(1);
+		return 0;
+	}
+
+	__raw_spin_unlock(&hash_lock);
+
+	/*
+	 * We must printk outside of the hash_lock:
+	 */
+	if (ret == 2) {
+		printk("\nmarked lock as {%s}:\n", usage_str[new_bit]);
+		print_lock(this);
+		print_irqtrace_events(curr);
+		dump_stack();
+	}
+
+	return ret;
+}
+
+#ifdef CONFIG_TRACE_IRQFLAGS
+/*
+ * Mark all held locks with a usage bit:
+ */
+static int
+mark_held_locks(struct task_struct *curr, int hardirq, unsigned long ip)
+{
+	enum lock_usage_bit usage_bit;
+	struct held_lock *hlock;
+	int i;
+
+	for (i = 0; i < curr->lockdep_depth; i++) {
+		hlock = curr->held_locks + i;
+
+		if (hardirq) {
+			if (hlock->read)
+				usage_bit = LOCK_ENABLED_HARDIRQS_READ;
+			else
+				usage_bit = LOCK_ENABLED_HARDIRQS;
+		} else {
+			if (hlock->read)
+				usage_bit = LOCK_ENABLED_SOFTIRQS_READ;
+			else
+				usage_bit = LOCK_ENABLED_SOFTIRQS;
+		}
+		if (!mark_lock(curr, hlock, usage_bit, ip))
+			return 0;
+	}
+
+	return 1;
+}
+
+/*
+ * Debugging helper: via this flag we know that we are in
+ * 'early bootup code', and will warn about any invalid irqs-on event:
+ */
+static int early_boot_irqs_enabled;
+
+void early_boot_irqs_off(void)
+{
+	early_boot_irqs_enabled = 0;
+}
+
+void early_boot_irqs_on(void)
+{
+	early_boot_irqs_enabled = 1;
+}
+
+/*
+ * Hardirqs will be enabled:
+ */
+void trace_hardirqs_on(void)
+{
+	struct task_struct *curr = current;
+	unsigned long ip;
+
+	if (unlikely(!debug_locks || current->lockdep_recursion))
+		return;
+
+	if (DEBUG_LOCKS_WARN_ON(unlikely(!early_boot_irqs_enabled)))
+		return;
+
+	if (unlikely(curr->hardirqs_enabled)) {
+		debug_atomic_inc(&redundant_hardirqs_on);
+		return;
+	}
+	/* we'll do an OFF -> ON transition: */
+	curr->hardirqs_enabled = 1;
+	ip = (unsigned long) __builtin_return_address(0);
+
+	if (DEBUG_LOCKS_WARN_ON(!irqs_disabled()))
+		return;
+	if (DEBUG_LOCKS_WARN_ON(current->hardirq_context))
+		return;
+	/*
+	 * We are going to turn hardirqs on, so set the
+	 * usage bit for all held locks:
+	 */
+	if (!mark_held_locks(curr, 1, ip))
+		return;
+	/*
+	 * If we have softirqs enabled, then set the usage
+	 * bit for all held locks. (disabled hardirqs prevented
+	 * this bit from being set before)
+	 */
+	if (curr->softirqs_enabled)
+		if (!mark_held_locks(curr, 0, ip))
+			return;
+
+	curr->hardirq_enable_ip = ip;
+	curr->hardirq_enable_event = ++curr->irq_events;
+	debug_atomic_inc(&hardirqs_on_events);
+}
+
+EXPORT_SYMBOL(trace_hardirqs_on);
+
+/*
+ * Hardirqs were disabled:
+ */
+void trace_hardirqs_off(void)
+{
+	struct task_struct *curr = current;
+
+	if (unlikely(!debug_locks || current->lockdep_recursion))
+		return;
+
+	if (DEBUG_LOCKS_WARN_ON(!irqs_disabled()))
+		return;
+
+	if (curr->hardirqs_enabled) {
+		/*
+		 * We have done an ON -> OFF transition:
+		 */
+		curr->hardirqs_enabled = 0;
+		curr->hardirq_disable_ip = _RET_IP_;
+		curr->hardirq_disable_event = ++curr->irq_events;
+		debug_atomic_inc(&hardirqs_off_events);
+	} else
+		debug_atomic_inc(&redundant_hardirqs_off);
+}
+
+EXPORT_SYMBOL(trace_hardirqs_off);
+
+/*
+ * Softirqs will be enabled:
+ */
+void trace_softirqs_on(unsigned long ip)
+{
+	struct task_struct *curr = current;
+
+	if (unlikely(!debug_locks))
+		return;
+
+	if (DEBUG_LOCKS_WARN_ON(!irqs_disabled()))
+		return;
+
+	if (curr->softirqs_enabled) {
+		debug_atomic_inc(&redundant_softirqs_on);
+		return;
+	}
+
+	/*
+	 * We'll do an OFF -> ON transition:
+	 */
+	curr->softirqs_enabled = 1;
+	curr->softirq_enable_ip = ip;
+	curr->softirq_enable_event = ++curr->irq_events;
+	debug_atomic_inc(&softirqs_on_events);
+	/*
+	 * We are going to turn softirqs on, so set the
+	 * usage bit for all held locks, if hardirqs are
+	 * enabled too:
+	 */
+	if (curr->hardirqs_enabled)
+		mark_held_locks(curr, 0, ip);
+}
+
+/*
+ * Softirqs were disabled:
+ */
+void trace_softirqs_off(unsigned long ip)
+{
+	struct task_struct *curr = current;
+
+	if (unlikely(!debug_locks))
+		return;
+
+	if (DEBUG_LOCKS_WARN_ON(!irqs_disabled()))
+		return;
+
+	if (curr->softirqs_enabled) {
+		/*
+		 * We have done an ON -> OFF transition:
+		 */
+		curr->softirqs_enabled = 0;
+		curr->softirq_disable_ip = ip;
+		curr->softirq_disable_event = ++curr->irq_events;
+		debug_atomic_inc(&softirqs_off_events);
+		DEBUG_LOCKS_WARN_ON(!softirq_count());
+	} else
+		debug_atomic_inc(&redundant_softirqs_off);
+}
+
+#endif
+
+/*
+ * Initialize a lock instance's lock-class mapping info:
+ */
+void lockdep_init_map(struct lockdep_map *lock, const char *name,
+		      struct lock_class_key *key, int subclass)
+{
+	if (unlikely(!debug_locks))
+		return;
+
+	if (DEBUG_LOCKS_WARN_ON(!key))
+		return;
+	if (DEBUG_LOCKS_WARN_ON(!name))
+		return;
+	/*
+	 * Sanity check, the lock-class key must be persistent:
+	 */
+	if (!static_obj(key)) {
+		printk("BUG: key %p not in .data!\n", key);
+		DEBUG_LOCKS_WARN_ON(1);
+		return;
+	}
+	lock->name = name;
+	lock->key = key;
+	lock->class_cache = NULL;
+	if (subclass)
+		register_lock_class(lock, subclass, 1);
+}
+
+EXPORT_SYMBOL_GPL(lockdep_init_map);
+
+/*
+ * This gets called for every mutex_lock*()/spin_lock*() operation.
+ * We maintain the dependency maps and validate the locking attempt:
+ */
+static int __lock_acquire(struct lockdep_map *lock, unsigned int subclass,
+			  int trylock, int read, int check, int hardirqs_off,
+			  unsigned long ip)
+{
+	struct task_struct *curr = current;
+	struct lock_class *class = NULL;
+	struct held_lock *hlock;
+	unsigned int depth, id;
+	int chain_head = 0;
+	u64 chain_key;
+
+	if (unlikely(!debug_locks))
+		return 0;
+
+	if (DEBUG_LOCKS_WARN_ON(!irqs_disabled()))
+		return 0;
+
+	if (unlikely(subclass >= MAX_LOCKDEP_SUBCLASSES)) {
+		debug_locks_off();
+		printk("BUG: MAX_LOCKDEP_SUBCLASSES too low!\n");
+		printk("turning off the locking correctness validator.\n");
+		return 0;
+	}
+
+	if (!subclass)
+		class = lock->class_cache;
+	/*
+	 * Not cached yet or subclass?
+	 */
+	if (unlikely(!class)) {
+		class = register_lock_class(lock, subclass, 0);
+		if (!class)
+			return 0;
+	}
+	debug_atomic_inc((atomic_t *)&class->ops);
+	if (very_verbose(class)) {
+		printk("\nacquire class [%p] %s", class->key, class->name);
+		if (class->name_version > 1)
+			printk("#%d", class->name_version);
+		printk("\n");
+		dump_stack();
+	}
+
+	/*
+	 * Add the lock to the list of currently held locks.
+	 * (we dont increase the depth just yet, up until the
+	 * dependency checks are done)
+	 */
+	depth = curr->lockdep_depth;
+	if (DEBUG_LOCKS_WARN_ON(depth >= MAX_LOCK_DEPTH))
+		return 0;
+
+	hlock = curr->held_locks + depth;
+
+	hlock->class = class;
+	hlock->acquire_ip = ip;
+	hlock->instance = lock;
+	hlock->trylock = trylock;
+	hlock->read = read;
+	hlock->check = check;
+	hlock->hardirqs_off = hardirqs_off;
+
+	if (check != 2)
+		goto out_calc_hash;
+#ifdef CONFIG_TRACE_IRQFLAGS
+	/*
+	 * If non-trylock use in a hardirq or softirq context, then
+	 * mark the lock as used in these contexts:
+	 */
+	if (!trylock) {
+		if (read) {
+			if (curr->hardirq_context)
+				if (!mark_lock(curr, hlock,
+						LOCK_USED_IN_HARDIRQ_READ, ip))
+					return 0;
+			if (curr->softirq_context)
+				if (!mark_lock(curr, hlock,
+						LOCK_USED_IN_SOFTIRQ_READ, ip))
+					return 0;
+		} else {
+			if (curr->hardirq_context)
+				if (!mark_lock(curr, hlock, LOCK_USED_IN_HARDIRQ, ip))
+					return 0;
+			if (curr->softirq_context)
+				if (!mark_lock(curr, hlock, LOCK_USED_IN_SOFTIRQ, ip))
+					return 0;
+		}
+	}
+	if (!hardirqs_off) {
+		if (read) {
+			if (!mark_lock(curr, hlock,
+					LOCK_ENABLED_HARDIRQS_READ, ip))
+				return 0;
+			if (curr->softirqs_enabled)
+				if (!mark_lock(curr, hlock,
+						LOCK_ENABLED_SOFTIRQS_READ, ip))
+					return 0;
+		} else {
+			if (!mark_lock(curr, hlock,
+					LOCK_ENABLED_HARDIRQS, ip))
+				return 0;
+			if (curr->softirqs_enabled)
+				if (!mark_lock(curr, hlock,
+						LOCK_ENABLED_SOFTIRQS, ip))
+					return 0;
+		}
+	}
+#endif
+	/* mark it as used: */
+	if (!mark_lock(curr, hlock, LOCK_USED, ip))
+		return 0;
+out_calc_hash:
+	/*
+	 * Calculate the chain hash: it's the combined has of all the
+	 * lock keys along the dependency chain. We save the hash value
+	 * at every step so that we can get the current hash easily
+	 * after unlock. The chain hash is then used to cache dependency
+	 * results.
+	 *
+	 * The 'key ID' is what is the most compact key value to drive
+	 * the hash, not class->key.
+	 */
+	id = class - lock_classes;
+	if (DEBUG_LOCKS_WARN_ON(id >= MAX_LOCKDEP_KEYS))
+		return 0;
+
+	chain_key = curr->curr_chain_key;
+	if (!depth) {
+		if (DEBUG_LOCKS_WARN_ON(chain_key != 0))
+			return 0;
+		chain_head = 1;
+	}
+
+	hlock->prev_chain_key = chain_key;
+
+#ifdef CONFIG_TRACE_IRQFLAGS
+	/*
+	 * Keep track of points where we cross into an interrupt context:
+	 */
+	hlock->irq_context = 2*(curr->hardirq_context ? 1 : 0) +
+				curr->softirq_context;
+	if (depth) {
+		struct held_lock *prev_hlock;
+
+		prev_hlock = curr->held_locks + depth-1;
+		/*
+		 * If we cross into another context, reset the
+		 * hash key (this also prevents the checking and the
+		 * adding of the dependency to 'prev'):
+		 */
+		if (prev_hlock->irq_context != hlock->irq_context) {
+			chain_key = 0;
+			chain_head = 1;
+		}
+	}
+#endif
+	chain_key = iterate_chain_key(chain_key, id);
+	curr->curr_chain_key = chain_key;
+
+	/*
+	 * Trylock needs to maintain the stack of held locks, but it
+	 * does not add new dependencies, because trylock can be done
+	 * in any order.
+	 *
+	 * We look up the chain_key and do the O(N^2) check and update of
+	 * the dependencies only if this is a new dependency chain.
+	 * (If lookup_chain_cache() returns with 1 it acquires
+	 * hash_lock for us)
+	 */
+	if (!trylock && (check == 2) && lookup_chain_cache(chain_key)) {
+		/*
+		 * Check whether last held lock:
+		 *
+		 * - is irq-safe, if this lock is irq-unsafe
+		 * - is softirq-safe, if this lock is hardirq-unsafe
+		 *
+		 * And check whether the new lock's dependency graph
+		 * could lead back to the previous lock.
+		 *
+		 * any of these scenarios could lead to a deadlock. If
+		 * All validations
+		 */
+		int ret = check_deadlock(curr, hlock, lock, read);
+
+		if (!ret)
+			return 0;
+		/*
+		 * Mark recursive read, as we jump over it when
+		 * building dependencies (just like we jump over
+		 * trylock entries):
+		 */
+		if (ret == 2)
+			hlock->read = 2;
+		/*
+		 * Add dependency only if this lock is not the head
+		 * of the chain, and if it's not a secondary read-lock:
+		 */
+		if (!chain_head && ret != 2)
+			if (!check_prevs_add(curr, hlock))
+				return 0;
+		__raw_spin_unlock(&hash_lock);
+	}
+	curr->lockdep_depth++;
+	check_chain_key(curr);
+	if (unlikely(curr->lockdep_depth >= MAX_LOCK_DEPTH)) {
+		debug_locks_off();
+		printk("BUG: MAX_LOCK_DEPTH too low!\n");
+		printk("turning off the locking correctness validator.\n");
+		return 0;
+	}
+	if (unlikely(curr->lockdep_depth > max_lockdep_depth))
+		max_lockdep_depth = curr->lockdep_depth;
+
+	return 1;
+}
+
+static int
+print_unlock_inbalance_bug(struct task_struct *curr, struct lockdep_map *lock,
+			   unsigned long ip)
+{
+	if (!debug_locks_off())
+		return 0;
+	if (debug_locks_silent)
+		return 0;
+
+	printk("\n=====================================\n");
+	printk(  "[ BUG: bad unlock balance detected! ]\n");
+	printk(  "-------------------------------------\n");
+	printk("%s/%d is trying to release lock (",
+		curr->comm, curr->pid);
+	print_lockdep_cache(lock);
+	printk(") at:\n");
+	print_ip_sym(ip);
+	printk("but there are no more locks to release!\n");
+	printk("\nother info that might help us debug this:\n");
+	lockdep_print_held_locks(curr);
+
+	printk("\nstack backtrace:\n");
+	dump_stack();
+
+	return 0;
+}
+
+/*
+ * Common debugging checks for both nested and non-nested unlock:
+ */
+static int check_unlock(struct task_struct *curr, struct lockdep_map *lock,
+			unsigned long ip)
+{
+	if (unlikely(!debug_locks))
+		return 0;
+	if (DEBUG_LOCKS_WARN_ON(!irqs_disabled()))
+		return 0;
+
+	if (curr->lockdep_depth <= 0)
+		return print_unlock_inbalance_bug(curr, lock, ip);
+
+	return 1;
+}
+
+/*
+ * Remove the lock to the list of currently held locks in a
+ * potentially non-nested (out of order) manner. This is a
+ * relatively rare operation, as all the unlock APIs default
+ * to nested mode (which uses lock_release()):
+ */
+static int
+lock_release_non_nested(struct task_struct *curr,
+			struct lockdep_map *lock, unsigned long ip)
+{
+	struct held_lock *hlock, *prev_hlock;
+	unsigned int depth;
+	int i;
+
+	/*
+	 * Check whether the lock exists in the current stack
+	 * of held locks:
+	 */
+	depth = curr->lockdep_depth;
+	if (DEBUG_LOCKS_WARN_ON(!depth))
+		return 0;
+
+	prev_hlock = NULL;
+	for (i = depth-1; i >= 0; i--) {
+		hlock = curr->held_locks + i;
+		/*
+		 * We must not cross into another context:
+		 */
+		if (prev_hlock && prev_hlock->irq_context != hlock->irq_context)
+			break;
+		if (hlock->instance == lock)
+			goto found_it;
+		prev_hlock = hlock;
+	}
+	return print_unlock_inbalance_bug(curr, lock, ip);
+
+found_it:
+	/*
+	 * We have the right lock to unlock, 'hlock' points to it.
+	 * Now we remove it from the stack, and add back the other
+	 * entries (if any), recalculating the hash along the way:
+	 */
+	curr->lockdep_depth = i;
+	curr->curr_chain_key = hlock->prev_chain_key;
+
+	for (i++; i < depth; i++) {
+		hlock = curr->held_locks + i;
+		if (!__lock_acquire(hlock->instance,
+			hlock->class->subclass, hlock->trylock,
+				hlock->read, hlock->check, hlock->hardirqs_off,
+				hlock->acquire_ip))
+			return 0;
+	}
+
+	if (DEBUG_LOCKS_WARN_ON(curr->lockdep_depth != depth - 1))
+		return 0;
+	return 1;
+}
+
+/*
+ * Remove the lock to the list of currently held locks - this gets
+ * called on mutex_unlock()/spin_unlock*() (or on a failed
+ * mutex_lock_interruptible()). This is done for unlocks that nest
+ * perfectly. (i.e. the current top of the lock-stack is unlocked)
+ */
+static int lock_release_nested(struct task_struct *curr,
+			       struct lockdep_map *lock, unsigned long ip)
+{
+	struct held_lock *hlock;
+	unsigned int depth;
+
+	/*
+	 * Pop off the top of the lock stack:
+	 */
+	depth = curr->lockdep_depth - 1;
+	hlock = curr->held_locks + depth;
+
+	/*
+	 * Is the unlock non-nested:
+	 */
+	if (hlock->instance != lock)
+		return lock_release_non_nested(curr, lock, ip);
+	curr->lockdep_depth--;
+
+	if (DEBUG_LOCKS_WARN_ON(!depth && (hlock->prev_chain_key != 0)))
+		return 0;
+
+	curr->curr_chain_key = hlock->prev_chain_key;
+
+#ifdef CONFIG_DEBUG_LOCKDEP
+	hlock->prev_chain_key = 0;
+	hlock->class = NULL;
+	hlock->acquire_ip = 0;
+	hlock->irq_context = 0;
+#endif
+	return 1;
+}
+
+/*
+ * Remove the lock to the list of currently held locks - this gets
+ * called on mutex_unlock()/spin_unlock*() (or on a failed
+ * mutex_lock_interruptible()). This is done for unlocks that nest
+ * perfectly. (i.e. the current top of the lock-stack is unlocked)
+ */
+static void
+__lock_release(struct lockdep_map *lock, int nested, unsigned long ip)
+{
+	struct task_struct *curr = current;
+
+	if (!check_unlock(curr, lock, ip))
+		return;
+
+	if (nested) {
+		if (!lock_release_nested(curr, lock, ip))
+			return;
+	} else {
+		if (!lock_release_non_nested(curr, lock, ip))
+			return;
+	}
+
+	check_chain_key(curr);
+}
+
+/*
+ * Check whether we follow the irq-flags state precisely:
+ */
+static void check_flags(unsigned long flags)
+{
+#if defined(CONFIG_DEBUG_LOCKDEP) && defined(CONFIG_TRACE_IRQFLAGS)
+	if (!debug_locks)
+		return;
+
+	if (irqs_disabled_flags(flags))
+		DEBUG_LOCKS_WARN_ON(current->hardirqs_enabled);
+	else
+		DEBUG_LOCKS_WARN_ON(!current->hardirqs_enabled);
+
+	/*
+	 * We dont accurately track softirq state in e.g.
+	 * hardirq contexts (such as on 4KSTACKS), so only
+	 * check if not in hardirq contexts:
+	 */
+	if (!hardirq_count()) {
+		if (softirq_count())
+			DEBUG_LOCKS_WARN_ON(current->softirqs_enabled);
+		else
+			DEBUG_LOCKS_WARN_ON(!current->softirqs_enabled);
+	}
+
+	if (!debug_locks)
+		print_irqtrace_events(current);
+#endif
+}
+
+/*
+ * We are not always called with irqs disabled - do that here,
+ * and also avoid lockdep recursion:
+ */
+void lock_acquire(struct lockdep_map *lock, unsigned int subclass,
+		  int trylock, int read, int check, unsigned long ip)
+{
+	unsigned long flags;
+
+	if (unlikely(current->lockdep_recursion))
+		return;
+
+	raw_local_irq_save(flags);
+	check_flags(flags);
+
+	current->lockdep_recursion = 1;
+	__lock_acquire(lock, subclass, trylock, read, check,
+		       irqs_disabled_flags(flags), ip);
+	current->lockdep_recursion = 0;
+	raw_local_irq_restore(flags);
+}
+
+EXPORT_SYMBOL_GPL(lock_acquire);
+
+void lock_release(struct lockdep_map *lock, int nested, unsigned long ip)
+{
+	unsigned long flags;
+
+	if (unlikely(current->lockdep_recursion))
+		return;
+
+	raw_local_irq_save(flags);
+	check_flags(flags);
+	current->lockdep_recursion = 1;
+	__lock_release(lock, nested, ip);
+	current->lockdep_recursion = 0;
+	raw_local_irq_restore(flags);
+}
+
+EXPORT_SYMBOL_GPL(lock_release);
+
+/*
+ * Used by the testsuite, sanitize the validator state
+ * after a simulated failure:
+ */
+
+void lockdep_reset(void)
+{
+	unsigned long flags;
+
+	raw_local_irq_save(flags);
+	current->curr_chain_key = 0;
+	current->lockdep_depth = 0;
+	current->lockdep_recursion = 0;
+	memset(current->held_locks, 0, MAX_LOCK_DEPTH*sizeof(struct held_lock));
+	nr_hardirq_chains = 0;
+	nr_softirq_chains = 0;
+	nr_process_chains = 0;
+	debug_locks = 1;
+	raw_local_irq_restore(flags);
+}
+
+static void zap_class(struct lock_class *class)
+{
+	int i;
+
+	/*
+	 * Remove all dependencies this lock is
+	 * involved in:
+	 */
+	for (i = 0; i < nr_list_entries; i++) {
+		if (list_entries[i].class == class)
+			list_del_rcu(&list_entries[i].entry);
+	}
+	/*
+	 * Unhash the class and remove it from the all_lock_classes list:
+	 */
+	list_del_rcu(&class->hash_entry);
+	list_del_rcu(&class->lock_entry);
+
+}
+
+static inline int within(void *addr, void *start, unsigned long size)
+{
+	return addr >= start && addr < start + size;
+}
+
+void lockdep_free_key_range(void *start, unsigned long size)
+{
+	struct lock_class *class, *next;
+	struct list_head *head;
+	unsigned long flags;
+	int i;
+
+	raw_local_irq_save(flags);
+	__raw_spin_lock(&hash_lock);
+
+	/*
+	 * Unhash all classes that were created by this module:
+	 */
+	for (i = 0; i < CLASSHASH_SIZE; i++) {
+		head = classhash_table + i;
+		if (list_empty(head))
+			continue;
+		list_for_each_entry_safe(class, next, head, hash_entry)
+			if (within(class->key, start, size))
+				zap_class(class);
+	}
+
+	__raw_spin_unlock(&hash_lock);
+	raw_local_irq_restore(flags);
+}
+
+void lockdep_reset_lock(struct lockdep_map *lock)
+{
+	struct lock_class *class, *next;
+	struct list_head *head;
+	unsigned long flags;
+	int i, j;
+
+	raw_local_irq_save(flags);
+
+	/*
+	 * Remove all classes this lock might have:
+	 */
+	for (j = 0; j < MAX_LOCKDEP_SUBCLASSES; j++) {
+		/*
+		 * If the class exists we look it up and zap it:
+		 */
+		class = look_up_lock_class(lock, j);
+		if (class)
+			zap_class(class);
+	}
+	/*
+	 * Debug check: in the end all mapped classes should
+	 * be gone.
+	 */
+	__raw_spin_lock(&hash_lock);
+	for (i = 0; i < CLASSHASH_SIZE; i++) {
+		head = classhash_table + i;
+		if (list_empty(head))
+			continue;
+		list_for_each_entry_safe(class, next, head, hash_entry) {
+			if (unlikely(class == lock->class_cache)) {
+				__raw_spin_unlock(&hash_lock);
+				DEBUG_LOCKS_WARN_ON(1);
+				goto out_restore;
+			}
+		}
+	}
+	__raw_spin_unlock(&hash_lock);
+
+out_restore:
+	raw_local_irq_restore(flags);
+}
+
+void __init lockdep_init(void)
+{
+	int i;
+
+	/*
+	 * Some architectures have their own start_kernel()
+	 * code which calls lockdep_init(), while we also
+	 * call lockdep_init() from the start_kernel() itself,
+	 * and we want to initialize the hashes only once:
+	 */
+	if (lockdep_initialized)
+		return;
+
+	for (i = 0; i < CLASSHASH_SIZE; i++)
+		INIT_LIST_HEAD(classhash_table + i);
+
+	for (i = 0; i < CHAINHASH_SIZE; i++)
+		INIT_LIST_HEAD(chainhash_table + i);
+
+	lockdep_initialized = 1;
+}
+
+void __init lockdep_info(void)
+{
+	printk("Lock dependency validator: Copyright (c) 2006 Red Hat, Inc., Ingo Molnar\n");
+
+	printk("... MAX_LOCKDEP_SUBCLASSES:    %lu\n", MAX_LOCKDEP_SUBCLASSES);
+	printk("... MAX_LOCK_DEPTH:          %lu\n", MAX_LOCK_DEPTH);
+	printk("... MAX_LOCKDEP_KEYS:        %lu\n", MAX_LOCKDEP_KEYS);
+	printk("... CLASSHASH_SIZE:           %lu\n", CLASSHASH_SIZE);
+	printk("... MAX_LOCKDEP_ENTRIES:     %lu\n", MAX_LOCKDEP_ENTRIES);
+	printk("... MAX_LOCKDEP_CHAINS:      %lu\n", MAX_LOCKDEP_CHAINS);
+	printk("... CHAINHASH_SIZE:          %lu\n", CHAINHASH_SIZE);
+
+	printk(" memory used by lock dependency info: %lu kB\n",
+		(sizeof(struct lock_class) * MAX_LOCKDEP_KEYS +
+		sizeof(struct list_head) * CLASSHASH_SIZE +
+		sizeof(struct lock_list) * MAX_LOCKDEP_ENTRIES +
+		sizeof(struct lock_chain) * MAX_LOCKDEP_CHAINS +
+		sizeof(struct list_head) * CHAINHASH_SIZE) / 1024);
+
+	printk(" per task-struct memory footprint: %lu bytes\n",
+		sizeof(struct held_lock) * MAX_LOCK_DEPTH);
+
+#ifdef CONFIG_DEBUG_LOCKDEP
+	if (lockdep_init_error)
+		printk("WARNING: lockdep init error! Arch code didnt call lockdep_init() early enough?\n");
+#endif
+}
+
+static inline int in_range(const void *start, const void *addr, const void *end)
+{
+	return addr >= start && addr <= end;
+}
+
+static void
+print_freed_lock_bug(struct task_struct *curr, const void *mem_from,
+		     const void *mem_to, struct held_lock *hlock)
+{
+	if (!debug_locks_off())
+		return;
+	if (debug_locks_silent)
+		return;
+
+	printk("\n=========================\n");
+	printk(  "[ BUG: held lock freed! ]\n");
+	printk(  "-------------------------\n");
+	printk("%s/%d is freeing memory %p-%p, with a lock still held there!\n",
+		curr->comm, curr->pid, mem_from, mem_to-1);
+	print_lock(hlock);
+	lockdep_print_held_locks(curr);
+
+	printk("\nstack backtrace:\n");
+	dump_stack();
+}
+
+/*
+ * Called when kernel memory is freed (or unmapped), or if a lock
+ * is destroyed or reinitialized - this code checks whether there is
+ * any held lock in the memory range of <from> to <to>:
+ */
+void debug_check_no_locks_freed(const void *mem_from, unsigned long mem_len)
+{
+	const void *mem_to = mem_from + mem_len, *lock_from, *lock_to;
+	struct task_struct *curr = current;
+	struct held_lock *hlock;
+	unsigned long flags;
+	int i;
+
+	if (unlikely(!debug_locks))
+		return;
+
+	local_irq_save(flags);
+	for (i = 0; i < curr->lockdep_depth; i++) {
+		hlock = curr->held_locks + i;
+
+		lock_from = (void *)hlock->instance;
+		lock_to = (void *)(hlock->instance + 1);
+
+		if (!in_range(mem_from, lock_from, mem_to) &&
+					!in_range(mem_from, lock_to, mem_to))
+			continue;
+
+		print_freed_lock_bug(curr, mem_from, mem_to, hlock);
+		break;
+	}
+	local_irq_restore(flags);
+}
+EXPORT_SYMBOL_GPL(debug_check_no_locks_freed);
+
+static void print_held_locks_bug(struct task_struct *curr)
+{
+	if (!debug_locks_off())
+		return;
+	if (debug_locks_silent)
+		return;
+
+	printk("\n=====================================\n");
+	printk(  "[ BUG: lock held at task exit time! ]\n");
+	printk(  "-------------------------------------\n");
+	printk("%s/%d is exiting with locks still held!\n",
+		curr->comm, curr->pid);
+	lockdep_print_held_locks(curr);
+
+	printk("\nstack backtrace:\n");
+	dump_stack();
+}
+
+void debug_check_no_locks_held(struct task_struct *task)
+{
+	if (unlikely(task->lockdep_depth > 0))
+		print_held_locks_bug(task);
+}
+
+void debug_show_all_locks(void)
+{
+	struct task_struct *g, *p;
+	int count = 10;
+	int unlock = 1;
+
+	printk("\nShowing all locks held in the system:\n");
+
+	/*
+	 * Here we try to get the tasklist_lock as hard as possible,
+	 * if not successful after 2 seconds we ignore it (but keep
+	 * trying). This is to enable a debug printout even if a
+	 * tasklist_lock-holding task deadlocks or crashes.
+	 */
+retry:
+	if (!read_trylock(&tasklist_lock)) {
+		if (count == 10)
+			printk("hm, tasklist_lock locked, retrying... ");
+		if (count) {
+			count--;
+			printk(" #%d", 10-count);
+			mdelay(200);
+			goto retry;
+		}
+		printk(" ignoring it.\n");
+		unlock = 0;
+	}
+	if (count != 10)
+		printk(" locked it.\n");
+
+	do_each_thread(g, p) {
+		if (p->lockdep_depth)
+			lockdep_print_held_locks(p);
+		if (!unlock)
+			if (read_trylock(&tasklist_lock))
+				unlock = 1;
+	} while_each_thread(g, p);
+
+	printk("\n");
+	printk("=============================================\n\n");
+
+	if (unlock)
+		read_unlock(&tasklist_lock);
+}
+
+EXPORT_SYMBOL_GPL(debug_show_all_locks);
+
+void debug_show_held_locks(struct task_struct *task)
+{
+	lockdep_print_held_locks(task);
+}
+
+EXPORT_SYMBOL_GPL(debug_show_held_locks);
+
diff --git a/kernel/lockdep_internals.h b/kernel/lockdep_internals.h
new file mode 100644
index 000000000..eab043c83
--- /dev/null
+++ b/kernel/lockdep_internals.h
@@ -0,0 +1,78 @@
+/*
+ * kernel/lockdep_internals.h
+ *
+ * Runtime locking correctness validator
+ *
+ * lockdep subsystem internal functions and variables.
+ */
+
+/*
+ * MAX_LOCKDEP_ENTRIES is the maximum number of lock dependencies
+ * we track.
+ *
+ * We use the per-lock dependency maps in two ways: we grow it by adding
+ * every to-be-taken lock to all currently held lock's own dependency
+ * table (if it's not there yet), and we check it for lock order
+ * conflicts and deadlocks.
+ */
+#define MAX_LOCKDEP_ENTRIES	8192UL
+
+#define MAX_LOCKDEP_KEYS_BITS	11
+#define MAX_LOCKDEP_KEYS	(1UL << MAX_LOCKDEP_KEYS_BITS)
+
+#define MAX_LOCKDEP_CHAINS_BITS	13
+#define MAX_LOCKDEP_CHAINS	(1UL << MAX_LOCKDEP_CHAINS_BITS)
+
+/*
+ * Stack-trace: tightly packed array of stack backtrace
+ * addresses. Protected by the hash_lock.
+ */
+#define MAX_STACK_TRACE_ENTRIES	262144UL
+
+extern struct list_head all_lock_classes;
+
+extern void
+get_usage_chars(struct lock_class *class, char *c1, char *c2, char *c3, char *c4);
+
+extern const char * __get_key_name(struct lockdep_subclass_key *key, char *str);
+
+extern unsigned long nr_lock_classes;
+extern unsigned long nr_list_entries;
+extern unsigned long nr_lock_chains;
+extern unsigned long nr_stack_trace_entries;
+
+extern unsigned int nr_hardirq_chains;
+extern unsigned int nr_softirq_chains;
+extern unsigned int nr_process_chains;
+extern unsigned int max_lockdep_depth;
+extern unsigned int max_recursion_depth;
+
+#ifdef CONFIG_DEBUG_LOCKDEP
+/*
+ * Various lockdep statistics:
+ */
+extern atomic_t chain_lookup_hits;
+extern atomic_t chain_lookup_misses;
+extern atomic_t hardirqs_on_events;
+extern atomic_t hardirqs_off_events;
+extern atomic_t redundant_hardirqs_on;
+extern atomic_t redundant_hardirqs_off;
+extern atomic_t softirqs_on_events;
+extern atomic_t softirqs_off_events;
+extern atomic_t redundant_softirqs_on;
+extern atomic_t redundant_softirqs_off;
+extern atomic_t nr_unused_locks;
+extern atomic_t nr_cyclic_checks;
+extern atomic_t nr_cyclic_check_recursions;
+extern atomic_t nr_find_usage_forwards_checks;
+extern atomic_t nr_find_usage_forwards_recursions;
+extern atomic_t nr_find_usage_backwards_checks;
+extern atomic_t nr_find_usage_backwards_recursions;
+# define debug_atomic_inc(ptr)		atomic_inc(ptr)
+# define debug_atomic_dec(ptr)		atomic_dec(ptr)
+# define debug_atomic_read(ptr)		atomic_read(ptr)
+#else
+# define debug_atomic_inc(ptr)		do { } while (0)
+# define debug_atomic_dec(ptr)		do { } while (0)
+# define debug_atomic_read(ptr)		0
+#endif
diff --git a/kernel/lockdep_proc.c b/kernel/lockdep_proc.c
new file mode 100644
index 000000000..f6e72eaab
--- /dev/null
+++ b/kernel/lockdep_proc.c
@@ -0,0 +1,345 @@
+/*
+ * kernel/lockdep_proc.c
+ *
+ * Runtime locking correctness validator
+ *
+ * Started by Ingo Molnar:
+ *
+ *  Copyright (C) 2006 Red Hat, Inc., Ingo Molnar <mingo@redhat.com>
+ *
+ * Code for /proc/lockdep and /proc/lockdep_stats:
+ *
+ */
+#include <linux/sched.h>
+#include <linux/module.h>
+#include <linux/proc_fs.h>
+#include <linux/seq_file.h>
+#include <linux/kallsyms.h>
+#include <linux/debug_locks.h>
+
+#include "lockdep_internals.h"
+
+static void *l_next(struct seq_file *m, void *v, loff_t *pos)
+{
+	struct lock_class *class = v;
+
+	(*pos)++;
+
+	if (class->lock_entry.next != &all_lock_classes)
+		class = list_entry(class->lock_entry.next, struct lock_class,
+				  lock_entry);
+	else
+		class = NULL;
+	m->private = class;
+
+	return class;
+}
+
+static void *l_start(struct seq_file *m, loff_t *pos)
+{
+	struct lock_class *class = m->private;
+
+	if (&class->lock_entry == all_lock_classes.next)
+		seq_printf(m, "all lock classes:\n");
+
+	return class;
+}
+
+static void l_stop(struct seq_file *m, void *v)
+{
+}
+
+static unsigned long count_forward_deps(struct lock_class *class)
+{
+	struct lock_list *entry;
+	unsigned long ret = 1;
+
+	/*
+	 * Recurse this class's dependency list:
+	 */
+	list_for_each_entry(entry, &class->locks_after, entry)
+		ret += count_forward_deps(entry->class);
+
+	return ret;
+}
+
+static unsigned long count_backward_deps(struct lock_class *class)
+{
+	struct lock_list *entry;
+	unsigned long ret = 1;
+
+	/*
+	 * Recurse this class's dependency list:
+	 */
+	list_for_each_entry(entry, &class->locks_before, entry)
+		ret += count_backward_deps(entry->class);
+
+	return ret;
+}
+
+static int l_show(struct seq_file *m, void *v)
+{
+	unsigned long nr_forward_deps, nr_backward_deps;
+	struct lock_class *class = m->private;
+	char str[128], c1, c2, c3, c4;
+	const char *name;
+
+	seq_printf(m, "%p", class->key);
+#ifdef CONFIG_DEBUG_LOCKDEP
+	seq_printf(m, " OPS:%8ld", class->ops);
+#endif
+	nr_forward_deps = count_forward_deps(class);
+	seq_printf(m, " FD:%5ld", nr_forward_deps);
+
+	nr_backward_deps = count_backward_deps(class);
+	seq_printf(m, " BD:%5ld", nr_backward_deps);
+
+	get_usage_chars(class, &c1, &c2, &c3, &c4);
+	seq_printf(m, " %c%c%c%c", c1, c2, c3, c4);
+
+	name = class->name;
+	if (!name) {
+		name = __get_key_name(class->key, str);
+		seq_printf(m, ": %s", name);
+	} else{
+		seq_printf(m, ": %s", name);
+		if (class->name_version > 1)
+			seq_printf(m, "#%d", class->name_version);
+		if (class->subclass)
+			seq_printf(m, "/%d", class->subclass);
+	}
+	seq_puts(m, "\n");
+
+	return 0;
+}
+
+static struct seq_operations lockdep_ops = {
+	.start	= l_start,
+	.next	= l_next,
+	.stop	= l_stop,
+	.show	= l_show,
+};
+
+static int lockdep_open(struct inode *inode, struct file *file)
+{
+	int res = seq_open(file, &lockdep_ops);
+	if (!res) {
+		struct seq_file *m = file->private_data;
+
+		if (!list_empty(&all_lock_classes))
+			m->private = list_entry(all_lock_classes.next,
+					struct lock_class, lock_entry);
+		else
+			m->private = NULL;
+	}
+	return res;
+}
+
+static struct file_operations proc_lockdep_operations = {
+	.open		= lockdep_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= seq_release,
+};
+
+static void lockdep_stats_debug_show(struct seq_file *m)
+{
+#ifdef CONFIG_DEBUG_LOCKDEP
+	unsigned int hi1 = debug_atomic_read(&hardirqs_on_events),
+		     hi2 = debug_atomic_read(&hardirqs_off_events),
+		     hr1 = debug_atomic_read(&redundant_hardirqs_on),
+		     hr2 = debug_atomic_read(&redundant_hardirqs_off),
+		     si1 = debug_atomic_read(&softirqs_on_events),
+		     si2 = debug_atomic_read(&softirqs_off_events),
+		     sr1 = debug_atomic_read(&redundant_softirqs_on),
+		     sr2 = debug_atomic_read(&redundant_softirqs_off);
+
+	seq_printf(m, " chain lookup misses:           %11u\n",
+		debug_atomic_read(&chain_lookup_misses));
+	seq_printf(m, " chain lookup hits:             %11u\n",
+		debug_atomic_read(&chain_lookup_hits));
+	seq_printf(m, " cyclic checks:                 %11u\n",
+		debug_atomic_read(&nr_cyclic_checks));
+	seq_printf(m, " cyclic-check recursions:       %11u\n",
+		debug_atomic_read(&nr_cyclic_check_recursions));
+	seq_printf(m, " find-mask forwards checks:     %11u\n",
+		debug_atomic_read(&nr_find_usage_forwards_checks));
+	seq_printf(m, " find-mask forwards recursions: %11u\n",
+		debug_atomic_read(&nr_find_usage_forwards_recursions));
+	seq_printf(m, " find-mask backwards checks:    %11u\n",
+		debug_atomic_read(&nr_find_usage_backwards_checks));
+	seq_printf(m, " find-mask backwards recursions:%11u\n",
+		debug_atomic_read(&nr_find_usage_backwards_recursions));
+
+	seq_printf(m, " hardirq on events:             %11u\n", hi1);
+	seq_printf(m, " hardirq off events:            %11u\n", hi2);
+	seq_printf(m, " redundant hardirq ons:         %11u\n", hr1);
+	seq_printf(m, " redundant hardirq offs:        %11u\n", hr2);
+	seq_printf(m, " softirq on events:             %11u\n", si1);
+	seq_printf(m, " softirq off events:            %11u\n", si2);
+	seq_printf(m, " redundant softirq ons:         %11u\n", sr1);
+	seq_printf(m, " redundant softirq offs:        %11u\n", sr2);
+#endif
+}
+
+static int lockdep_stats_show(struct seq_file *m, void *v)
+{
+	struct lock_class *class;
+	unsigned long nr_unused = 0, nr_uncategorized = 0,
+		      nr_irq_safe = 0, nr_irq_unsafe = 0,
+		      nr_softirq_safe = 0, nr_softirq_unsafe = 0,
+		      nr_hardirq_safe = 0, nr_hardirq_unsafe = 0,
+		      nr_irq_read_safe = 0, nr_irq_read_unsafe = 0,
+		      nr_softirq_read_safe = 0, nr_softirq_read_unsafe = 0,
+		      nr_hardirq_read_safe = 0, nr_hardirq_read_unsafe = 0,
+		      sum_forward_deps = 0, factor = 0;
+
+	list_for_each_entry(class, &all_lock_classes, lock_entry) {
+
+		if (class->usage_mask == 0)
+			nr_unused++;
+		if (class->usage_mask == LOCKF_USED)
+			nr_uncategorized++;
+		if (class->usage_mask & LOCKF_USED_IN_IRQ)
+			nr_irq_safe++;
+		if (class->usage_mask & LOCKF_ENABLED_IRQS)
+			nr_irq_unsafe++;
+		if (class->usage_mask & LOCKF_USED_IN_SOFTIRQ)
+			nr_softirq_safe++;
+		if (class->usage_mask & LOCKF_ENABLED_SOFTIRQS)
+			nr_softirq_unsafe++;
+		if (class->usage_mask & LOCKF_USED_IN_HARDIRQ)
+			nr_hardirq_safe++;
+		if (class->usage_mask & LOCKF_ENABLED_HARDIRQS)
+			nr_hardirq_unsafe++;
+		if (class->usage_mask & LOCKF_USED_IN_IRQ_READ)
+			nr_irq_read_safe++;
+		if (class->usage_mask & LOCKF_ENABLED_IRQS_READ)
+			nr_irq_read_unsafe++;
+		if (class->usage_mask & LOCKF_USED_IN_SOFTIRQ_READ)
+			nr_softirq_read_safe++;
+		if (class->usage_mask & LOCKF_ENABLED_SOFTIRQS_READ)
+			nr_softirq_read_unsafe++;
+		if (class->usage_mask & LOCKF_USED_IN_HARDIRQ_READ)
+			nr_hardirq_read_safe++;
+		if (class->usage_mask & LOCKF_ENABLED_HARDIRQS_READ)
+			nr_hardirq_read_unsafe++;
+
+		sum_forward_deps += count_forward_deps(class);
+	}
+#ifdef CONFIG_LOCKDEP_DEBUG
+	DEBUG_LOCKS_WARN_ON(debug_atomic_read(&nr_unused_locks) != nr_unused);
+#endif
+	seq_printf(m, " lock-classes:                  %11lu [max: %lu]\n",
+			nr_lock_classes, MAX_LOCKDEP_KEYS);
+	seq_printf(m, " direct dependencies:           %11lu [max: %lu]\n",
+			nr_list_entries, MAX_LOCKDEP_ENTRIES);
+	seq_printf(m, " indirect dependencies:         %11lu\n",
+			sum_forward_deps);
+
+	/*
+	 * Total number of dependencies:
+	 *
+	 * All irq-safe locks may nest inside irq-unsafe locks,
+	 * plus all the other known dependencies:
+	 */
+	seq_printf(m, " all direct dependencies:       %11lu\n",
+			nr_irq_unsafe * nr_irq_safe +
+			nr_hardirq_unsafe * nr_hardirq_safe +
+			nr_list_entries);
+
+	/*
+	 * Estimated factor between direct and indirect
+	 * dependencies:
+	 */
+	if (nr_list_entries)
+		factor = sum_forward_deps / nr_list_entries;
+
+	seq_printf(m, " dependency chains:             %11lu [max: %lu]\n",
+			nr_lock_chains, MAX_LOCKDEP_CHAINS);
+
+#ifdef CONFIG_TRACE_IRQFLAGS
+	seq_printf(m, " in-hardirq chains:             %11u\n",
+			nr_hardirq_chains);
+	seq_printf(m, " in-softirq chains:             %11u\n",
+			nr_softirq_chains);
+#endif
+	seq_printf(m, " in-process chains:             %11u\n",
+			nr_process_chains);
+	seq_printf(m, " stack-trace entries:           %11lu [max: %lu]\n",
+			nr_stack_trace_entries, MAX_STACK_TRACE_ENTRIES);
+	seq_printf(m, " combined max dependencies:     %11u\n",
+			(nr_hardirq_chains + 1) *
+			(nr_softirq_chains + 1) *
+			(nr_process_chains + 1)
+	);
+	seq_printf(m, " hardirq-safe locks:            %11lu\n",
+			nr_hardirq_safe);
+	seq_printf(m, " hardirq-unsafe locks:          %11lu\n",
+			nr_hardirq_unsafe);
+	seq_printf(m, " softirq-safe locks:            %11lu\n",
+			nr_softirq_safe);
+	seq_printf(m, " softirq-unsafe locks:          %11lu\n",
+			nr_softirq_unsafe);
+	seq_printf(m, " irq-safe locks:                %11lu\n",
+			nr_irq_safe);
+	seq_printf(m, " irq-unsafe locks:              %11lu\n",
+			nr_irq_unsafe);
+
+	seq_printf(m, " hardirq-read-safe locks:       %11lu\n",
+			nr_hardirq_read_safe);
+	seq_printf(m, " hardirq-read-unsafe locks:     %11lu\n",
+			nr_hardirq_read_unsafe);
+	seq_printf(m, " softirq-read-safe locks:       %11lu\n",
+			nr_softirq_read_safe);
+	seq_printf(m, " softirq-read-unsafe locks:     %11lu\n",
+			nr_softirq_read_unsafe);
+	seq_printf(m, " irq-read-safe locks:           %11lu\n",
+			nr_irq_read_safe);
+	seq_printf(m, " irq-read-unsafe locks:         %11lu\n",
+			nr_irq_read_unsafe);
+
+	seq_printf(m, " uncategorized locks:           %11lu\n",
+			nr_uncategorized);
+	seq_printf(m, " unused locks:                  %11lu\n",
+			nr_unused);
+	seq_printf(m, " max locking depth:             %11u\n",
+			max_lockdep_depth);
+	seq_printf(m, " max recursion depth:           %11u\n",
+			max_recursion_depth);
+	lockdep_stats_debug_show(m);
+	seq_printf(m, " debug_locks:                   %11u\n",
+			debug_locks);
+
+	return 0;
+}
+
+static int lockdep_stats_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, lockdep_stats_show, NULL);
+}
+
+static struct file_operations proc_lockdep_stats_operations = {
+	.open		= lockdep_stats_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= seq_release,
+};
+
+static int __init lockdep_proc_init(void)
+{
+	struct proc_dir_entry *entry;
+
+	entry = create_proc_entry("lockdep", S_IRUSR, NULL);
+	if (entry)
+		entry->proc_fops = &proc_lockdep_operations;
+
+	entry = create_proc_entry("lockdep_stats", S_IRUSR, NULL);
+	if (entry)
+		entry->proc_fops = &proc_lockdep_stats_operations;
+
+	return 0;
+}
+
+__initcall(lockdep_proc_init);
+
diff --git a/kernel/rtmutex-debug.c b/kernel/rtmutex-debug.c
new file mode 100644
index 000000000..da8d6bf46
--- /dev/null
+++ b/kernel/rtmutex-debug.c
@@ -0,0 +1,241 @@
+/*
+ * RT-Mutexes: blocking mutual exclusion locks with PI support
+ *
+ * started by Ingo Molnar and Thomas Gleixner:
+ *
+ *  Copyright (C) 2004-2006 Red Hat, Inc., Ingo Molnar <mingo@redhat.com>
+ *  Copyright (C) 2006 Timesys Corp., Thomas Gleixner <tglx@timesys.com>
+ *
+ * This code is based on the rt.c implementation in the preempt-rt tree.
+ * Portions of said code are
+ *
+ *  Copyright (C) 2004  LynuxWorks, Inc., Igor Manyilov, Bill Huey
+ *  Copyright (C) 2006  Esben Nielsen
+ *  Copyright (C) 2006  Kihon Technologies Inc.,
+ *			Steven Rostedt <rostedt@goodmis.org>
+ *
+ * See rt.c in preempt-rt for proper credits and further information
+ */
+#include <linux/sched.h>
+#include <linux/delay.h>
+#include <linux/module.h>
+#include <linux/spinlock.h>
+#include <linux/kallsyms.h>
+#include <linux/syscalls.h>
+#include <linux/interrupt.h>
+#include <linux/plist.h>
+#include <linux/fs.h>
+#include <linux/debug_locks.h>
+
+#include "rtmutex_common.h"
+
+#ifdef CONFIG_DEBUG_RT_MUTEXES
+# include "rtmutex-debug.h"
+#else
+# include "rtmutex.h"
+#endif
+
+# define TRACE_WARN_ON(x)			WARN_ON(x)
+# define TRACE_BUG_ON(x)			BUG_ON(x)
+
+# define TRACE_OFF()						\
+do {								\
+	if (rt_trace_on) {					\
+		rt_trace_on = 0;				\
+		console_verbose();				\
+		if (spin_is_locked(&current->pi_lock))		\
+			spin_unlock(&current->pi_lock);		\
+	}							\
+} while (0)
+
+# define TRACE_OFF_NOLOCK()					\
+do {								\
+	if (rt_trace_on) {					\
+		rt_trace_on = 0;				\
+		console_verbose();				\
+	}							\
+} while (0)
+
+# define TRACE_BUG_LOCKED()			\
+do {						\
+	TRACE_OFF();				\
+	BUG();					\
+} while (0)
+
+# define TRACE_WARN_ON_LOCKED(c)		\
+do {						\
+	if (unlikely(c)) {			\
+		TRACE_OFF();			\
+		WARN_ON(1);			\
+	}					\
+} while (0)
+
+# define TRACE_BUG_ON_LOCKED(c)			\
+do {						\
+	if (unlikely(c))			\
+		TRACE_BUG_LOCKED();		\
+} while (0)
+
+#ifdef CONFIG_SMP
+# define SMP_TRACE_BUG_ON_LOCKED(c)	TRACE_BUG_ON_LOCKED(c)
+#else
+# define SMP_TRACE_BUG_ON_LOCKED(c)	do { } while (0)
+#endif
+
+/*
+ * deadlock detection flag. We turn it off when we detect
+ * the first problem because we dont want to recurse back
+ * into the tracing code when doing error printk or
+ * executing a BUG():
+ */
+int rt_trace_on = 1;
+
+void deadlock_trace_off(void)
+{
+	rt_trace_on = 0;
+}
+
+static void printk_task(struct task_struct *p)
+{
+	if (p)
+		printk("%16s:%5d [%p, %3d]", p->comm, p->pid, p, p->prio);
+	else
+		printk("<none>");
+}
+
+static void printk_lock(struct rt_mutex *lock, int print_owner)
+{
+	if (lock->name)
+		printk(" [%p] {%s}\n",
+			lock, lock->name);
+	else
+		printk(" [%p] {%s:%d}\n",
+			lock, lock->file, lock->line);
+
+	if (print_owner && rt_mutex_owner(lock)) {
+		printk(".. ->owner: %p\n", lock->owner);
+		printk(".. held by:  ");
+		printk_task(rt_mutex_owner(lock));
+		printk("\n");
+	}
+}
+
+void rt_mutex_debug_task_free(struct task_struct *task)
+{
+	WARN_ON(!plist_head_empty(&task->pi_waiters));
+	WARN_ON(task->pi_blocked_on);
+}
+
+/*
+ * We fill out the fields in the waiter to store the information about
+ * the deadlock. We print when we return. act_waiter can be NULL in
+ * case of a remove waiter operation.
+ */
+void debug_rt_mutex_deadlock(int detect, struct rt_mutex_waiter *act_waiter,
+			     struct rt_mutex *lock)
+{
+	struct task_struct *task;
+
+	if (!rt_trace_on || detect || !act_waiter)
+		return;
+
+	task = rt_mutex_owner(act_waiter->lock);
+	if (task && task != current) {
+		act_waiter->deadlock_task_pid = task->pid;
+		act_waiter->deadlock_lock = lock;
+	}
+}
+
+void debug_rt_mutex_print_deadlock(struct rt_mutex_waiter *waiter)
+{
+	struct task_struct *task;
+
+	if (!waiter->deadlock_lock || !rt_trace_on)
+		return;
+
+	task = find_task_by_pid(waiter->deadlock_task_pid);
+	if (!task)
+		return;
+
+	TRACE_OFF_NOLOCK();
+
+	printk("\n============================================\n");
+	printk(  "[ BUG: circular locking deadlock detected! ]\n");
+	printk(  "--------------------------------------------\n");
+	printk("%s/%d is deadlocking current task %s/%d\n\n",
+	       task->comm, task->pid, current->comm, current->pid);
+
+	printk("\n1) %s/%d is trying to acquire this lock:\n",
+	       current->comm, current->pid);
+	printk_lock(waiter->lock, 1);
+
+	printk("\n2) %s/%d is blocked on this lock:\n", task->comm, task->pid);
+	printk_lock(waiter->deadlock_lock, 1);
+
+	debug_show_held_locks(current);
+	debug_show_held_locks(task);
+
+	printk("\n%s/%d's [blocked] stackdump:\n\n", task->comm, task->pid);
+	show_stack(task, NULL);
+	printk("\n%s/%d's [current] stackdump:\n\n",
+	       current->comm, current->pid);
+	dump_stack();
+	debug_show_all_locks();
+
+	printk("[ turning off deadlock detection."
+	       "Please report this trace. ]\n\n");
+	local_irq_disable();
+}
+
+void debug_rt_mutex_lock(struct rt_mutex *lock)
+{
+}
+
+void debug_rt_mutex_unlock(struct rt_mutex *lock)
+{
+	TRACE_WARN_ON_LOCKED(rt_mutex_owner(lock) != current);
+}
+
+void
+debug_rt_mutex_proxy_lock(struct rt_mutex *lock, struct task_struct *powner)
+{
+}
+
+void debug_rt_mutex_proxy_unlock(struct rt_mutex *lock)
+{
+	TRACE_WARN_ON_LOCKED(!rt_mutex_owner(lock));
+}
+
+void debug_rt_mutex_init_waiter(struct rt_mutex_waiter *waiter)
+{
+	memset(waiter, 0x11, sizeof(*waiter));
+	plist_node_init(&waiter->list_entry, MAX_PRIO);
+	plist_node_init(&waiter->pi_list_entry, MAX_PRIO);
+}
+
+void debug_rt_mutex_free_waiter(struct rt_mutex_waiter *waiter)
+{
+	TRACE_WARN_ON(!plist_node_empty(&waiter->list_entry));
+	TRACE_WARN_ON(!plist_node_empty(&waiter->pi_list_entry));
+	TRACE_WARN_ON(waiter->task);
+	memset(waiter, 0x22, sizeof(*waiter));
+}
+
+void debug_rt_mutex_init(struct rt_mutex *lock, const char *name)
+{
+	/*
+	 * Make sure we are not reinitializing a held lock:
+	 */
+	debug_check_no_locks_freed((void *)lock, sizeof(*lock));
+	lock->name = name;
+}
+
+void
+rt_mutex_deadlock_account_lock(struct rt_mutex *lock, struct task_struct *task)
+{
+}
+
+void rt_mutex_deadlock_account_unlock(struct task_struct *task)
+{
+}
+
diff --git a/kernel/rtmutex-debug.h b/kernel/rtmutex-debug.h
new file mode 100644
index 000000000..14193d596
--- /dev/null
+++ b/kernel/rtmutex-debug.h
@@ -0,0 +1,33 @@
+/*
+ * RT-Mutexes: blocking mutual exclusion locks with PI support
+ *
+ * started by Ingo Molnar and Thomas Gleixner:
+ *
+ *  Copyright (C) 2004-2006 Red Hat, Inc., Ingo Molnar <mingo@redhat.com>
+ *  Copyright (C) 2006, Timesys Corp., Thomas Gleixner <tglx@timesys.com>
+ *
+ * This file contains macros used solely by rtmutex.c. Debug version.
+ */
+
+extern void
+rt_mutex_deadlock_account_lock(struct rt_mutex *lock, struct task_struct *task);
+extern void rt_mutex_deadlock_account_unlock(struct task_struct *task);
+extern void debug_rt_mutex_init_waiter(struct rt_mutex_waiter *waiter);
+extern void debug_rt_mutex_free_waiter(struct rt_mutex_waiter *waiter);
+extern void debug_rt_mutex_init(struct rt_mutex *lock, const char *name);
+extern void debug_rt_mutex_lock(struct rt_mutex *lock);
+extern void debug_rt_mutex_unlock(struct rt_mutex *lock);
+extern void debug_rt_mutex_proxy_lock(struct rt_mutex *lock,
+				      struct task_struct *powner);
+extern void debug_rt_mutex_proxy_unlock(struct rt_mutex *lock);
+extern void debug_rt_mutex_deadlock(int detect, struct rt_mutex_waiter *waiter,
+				    struct rt_mutex *lock);
+extern void debug_rt_mutex_print_deadlock(struct rt_mutex_waiter *waiter);
+# define debug_rt_mutex_reset_waiter(w)			\
+	do { (w)->deadlock_lock = NULL; } while (0)
+
+static inline int debug_rt_mutex_detect_deadlock(struct rt_mutex_waiter *waiter,
+						 int detect)
+{
+	return (waiter != NULL);
+}
diff --git a/kernel/rtmutex-tester.c b/kernel/rtmutex-tester.c
new file mode 100644
index 000000000..6dcea9dd8
--- /dev/null
+++ b/kernel/rtmutex-tester.c
@@ -0,0 +1,440 @@
+/*
+ * RT-Mutex-tester: scriptable tester for rt mutexes
+ *
+ * started by Thomas Gleixner:
+ *
+ *  Copyright (C) 2006, Timesys Corp., Thomas Gleixner <tglx@timesys.com>
+ *
+ */
+#include <linux/kthread.h>
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/smp_lock.h>
+#include <linux/spinlock.h>
+#include <linux/sysdev.h>
+#include <linux/timer.h>
+
+#include "rtmutex.h"
+
+#define MAX_RT_TEST_THREADS	8
+#define MAX_RT_TEST_MUTEXES	8
+
+static spinlock_t rttest_lock;
+static atomic_t rttest_event;
+
+struct test_thread_data {
+	int			opcode;
+	int			opdata;
+	int			mutexes[MAX_RT_TEST_MUTEXES];
+	int			bkl;
+	int			event;
+	struct sys_device	sysdev;
+};
+
+static struct test_thread_data thread_data[MAX_RT_TEST_THREADS];
+static struct task_struct *threads[MAX_RT_TEST_THREADS];
+static struct rt_mutex mutexes[MAX_RT_TEST_MUTEXES];
+
+enum test_opcodes {
+	RTTEST_NOP = 0,
+	RTTEST_SCHEDOT,		/* 1 Sched other, data = nice */
+	RTTEST_SCHEDRT,		/* 2 Sched fifo, data = prio */
+	RTTEST_LOCK,		/* 3 Lock uninterruptible, data = lockindex */
+	RTTEST_LOCKNOWAIT,	/* 4 Lock uninterruptible no wait in wakeup, data = lockindex */
+	RTTEST_LOCKINT,		/* 5 Lock interruptible, data = lockindex */
+	RTTEST_LOCKINTNOWAIT,	/* 6 Lock interruptible no wait in wakeup, data = lockindex */
+	RTTEST_LOCKCONT,	/* 7 Continue locking after the wakeup delay */
+	RTTEST_UNLOCK,		/* 8 Unlock, data = lockindex */
+	RTTEST_LOCKBKL,		/* 9 Lock BKL */
+	RTTEST_UNLOCKBKL,	/* 10 Unlock BKL */
+	RTTEST_SIGNAL,		/* 11 Signal other test thread, data = thread id */
+	RTTEST_RESETEVENT = 98,	/* 98 Reset event counter */
+	RTTEST_RESET = 99,	/* 99 Reset all pending operations */
+};
+
+static int handle_op(struct test_thread_data *td, int lockwakeup)
+{
+	int i, id, ret = -EINVAL;
+
+	switch(td->opcode) {
+
+	case RTTEST_NOP:
+		return 0;
+
+	case RTTEST_LOCKCONT:
+		td->mutexes[td->opdata] = 1;
+		td->event = atomic_add_return(1, &rttest_event);
+		return 0;
+
+	case RTTEST_RESET:
+		for (i = 0; i < MAX_RT_TEST_MUTEXES; i++) {
+			if (td->mutexes[i] == 4) {
+				rt_mutex_unlock(&mutexes[i]);
+				td->mutexes[i] = 0;
+			}
+		}
+
+		if (!lockwakeup && td->bkl == 4) {
+			unlock_kernel();
+			td->bkl = 0;
+		}
+		return 0;
+
+	case RTTEST_RESETEVENT:
+		atomic_set(&rttest_event, 0);
+		return 0;
+
+	default:
+		if (lockwakeup)
+			return ret;
+	}
+
+	switch(td->opcode) {
+
+	case RTTEST_LOCK:
+	case RTTEST_LOCKNOWAIT:
+		id = td->opdata;
+		if (id < 0 || id >= MAX_RT_TEST_MUTEXES)
+			return ret;
+
+		td->mutexes[id] = 1;
+		td->event = atomic_add_return(1, &rttest_event);
+		rt_mutex_lock(&mutexes[id]);
+		td->event = atomic_add_return(1, &rttest_event);
+		td->mutexes[id] = 4;
+		return 0;
+
+	case RTTEST_LOCKINT:
+	case RTTEST_LOCKINTNOWAIT:
+		id = td->opdata;
+		if (id < 0 || id >= MAX_RT_TEST_MUTEXES)
+			return ret;
+
+		td->mutexes[id] = 1;
+		td->event = atomic_add_return(1, &rttest_event);
+		ret = rt_mutex_lock_interruptible(&mutexes[id], 0);
+		td->event = atomic_add_return(1, &rttest_event);
+		td->mutexes[id] = ret ? 0 : 4;
+		return ret ? -EINTR : 0;
+
+	case RTTEST_UNLOCK:
+		id = td->opdata;
+		if (id < 0 || id >= MAX_RT_TEST_MUTEXES || td->mutexes[id] != 4)
+			return ret;
+
+		td->event = atomic_add_return(1, &rttest_event);
+		rt_mutex_unlock(&mutexes[id]);
+		td->event = atomic_add_return(1, &rttest_event);
+		td->mutexes[id] = 0;
+		return 0;
+
+	case RTTEST_LOCKBKL:
+		if (td->bkl)
+			return 0;
+		td->bkl = 1;
+		lock_kernel();
+		td->bkl = 4;
+		return 0;
+
+	case RTTEST_UNLOCKBKL:
+		if (td->bkl != 4)
+			break;
+		unlock_kernel();
+		td->bkl = 0;
+		return 0;
+
+	default:
+		break;
+	}
+	return ret;
+}
+
+/*
+ * Schedule replacement for rtsem_down(). Only called for threads with
+ * PF_MUTEX_TESTER set.
+ *
+ * This allows us to have finegrained control over the event flow.
+ *
+ */
+void schedule_rt_mutex_test(struct rt_mutex *mutex)
+{
+	int tid, op, dat;
+	struct test_thread_data *td;
+
+	/* We have to lookup the task */
+	for (tid = 0; tid < MAX_RT_TEST_THREADS; tid++) {
+		if (threads[tid] == current)
+			break;
+	}
+
+	BUG_ON(tid == MAX_RT_TEST_THREADS);
+
+	td = &thread_data[tid];
+
+	op = td->opcode;
+	dat = td->opdata;
+
+	switch (op) {
+	case RTTEST_LOCK:
+	case RTTEST_LOCKINT:
+	case RTTEST_LOCKNOWAIT:
+	case RTTEST_LOCKINTNOWAIT:
+		if (mutex != &mutexes[dat])
+			break;
+
+		if (td->mutexes[dat] != 1)
+			break;
+
+		td->mutexes[dat] = 2;
+		td->event = atomic_add_return(1, &rttest_event);
+		break;
+
+	case RTTEST_LOCKBKL:
+	default:
+		break;
+	}
+
+	schedule();
+
+
+	switch (op) {
+	case RTTEST_LOCK:
+	case RTTEST_LOCKINT:
+		if (mutex != &mutexes[dat])
+			return;
+
+		if (td->mutexes[dat] != 2)
+			return;
+
+		td->mutexes[dat] = 3;
+		td->event = atomic_add_return(1, &rttest_event);
+		break;
+
+	case RTTEST_LOCKNOWAIT:
+	case RTTEST_LOCKINTNOWAIT:
+		if (mutex != &mutexes[dat])
+			return;
+
+		if (td->mutexes[dat] != 2)
+			return;
+
+		td->mutexes[dat] = 1;
+		td->event = atomic_add_return(1, &rttest_event);
+		return;
+
+	case RTTEST_LOCKBKL:
+		return;
+	default:
+		return;
+	}
+
+	td->opcode = 0;
+
+	for (;;) {
+		set_current_state(TASK_INTERRUPTIBLE);
+
+		if (td->opcode > 0) {
+			int ret;
+
+			set_current_state(TASK_RUNNING);
+			ret = handle_op(td, 1);
+			set_current_state(TASK_INTERRUPTIBLE);
+			if (td->opcode == RTTEST_LOCKCONT)
+				break;
+			td->opcode = ret;
+		}
+
+		/* Wait for the next command to be executed */
+		schedule();
+	}
+
+	/* Restore previous command and data */
+	td->opcode = op;
+	td->opdata = dat;
+}
+
+static int test_func(void *data)
+{
+	struct test_thread_data *td = data;
+	int ret;
+
+	current->flags |= PF_MUTEX_TESTER;
+	allow_signal(SIGHUP);
+
+	for(;;) {
+
+		set_current_state(TASK_INTERRUPTIBLE);
+
+		if (td->opcode > 0) {
+			set_current_state(TASK_RUNNING);
+			ret = handle_op(td, 0);
+			set_current_state(TASK_INTERRUPTIBLE);
+			td->opcode = ret;
+		}
+
+		/* Wait for the next command to be executed */
+		schedule();
+		try_to_freeze();
+
+		if (signal_pending(current))
+			flush_signals(current);
+
+		if(kthread_should_stop())
+			break;
+	}
+	return 0;
+}
+
+/**
+ * sysfs_test_command - interface for test commands
+ * @dev:	thread reference
+ * @buf:	command for actual step
+ * @count:	length of buffer
+ *
+ * command syntax:
+ *
+ * opcode:data
+ */
+static ssize_t sysfs_test_command(struct sys_device *dev, const char *buf,
+				  size_t count)
+{
+	struct sched_param schedpar;
+	struct test_thread_data *td;
+	char cmdbuf[32];
+	int op, dat, tid, ret;
+
+	td = container_of(dev, struct test_thread_data, sysdev);
+	tid = td->sysdev.id;
+
+	/* strings from sysfs write are not 0 terminated! */
+	if (count >= sizeof(cmdbuf))
+		return -EINVAL;
+
+	/* strip of \n: */
+	if (buf[count-1] == '\n')
+		count--;
+	if (count < 1)
+		return -EINVAL;
+
+	memcpy(cmdbuf, buf, count);
+	cmdbuf[count] = 0;
+
+	if (sscanf(cmdbuf, "%d:%d", &op, &dat) != 2)
+		return -EINVAL;
+
+	switch (op) {
+	case RTTEST_SCHEDOT:
+		schedpar.sched_priority = 0;
+		ret = sched_setscheduler(threads[tid], SCHED_NORMAL, &schedpar);
+		if (ret)
+			return ret;
+		set_user_nice(current, 0);
+		break;
+
+	case RTTEST_SCHEDRT:
+		schedpar.sched_priority = dat;
+		ret = sched_setscheduler(threads[tid], SCHED_FIFO, &schedpar);
+		if (ret)
+			return ret;
+		break;
+
+	case RTTEST_SIGNAL:
+		send_sig(SIGHUP, threads[tid], 0);
+		break;
+
+	default:
+		if (td->opcode > 0)
+			return -EBUSY;
+		td->opdata = dat;
+		td->opcode = op;
+		wake_up_process(threads[tid]);
+	}
+
+	return count;
+}
+
+/**
+ * sysfs_test_status - sysfs interface for rt tester
+ * @dev:	thread to query
+ * @buf:	char buffer to be filled with thread status info
+ */
+static ssize_t sysfs_test_status(struct sys_device *dev, char *buf)
+{
+	struct test_thread_data *td;
+	struct task_struct *tsk;
+	char *curr = buf;
+	int i;
+
+	td = container_of(dev, struct test_thread_data, sysdev);
+	tsk = threads[td->sysdev.id];
+
+	spin_lock(&rttest_lock);
+
+	curr += sprintf(curr,
+		"O: %4d, E:%8d, S: 0x%08lx, P: %4d, N: %4d, B: %p, K: %d, M:",
+		td->opcode, td->event, tsk->state,
+			(MAX_RT_PRIO - 1) - tsk->prio,
+			(MAX_RT_PRIO - 1) - tsk->normal_prio,
+		tsk->pi_blocked_on, td->bkl);
+
+	for (i = MAX_RT_TEST_MUTEXES - 1; i >=0 ; i--)
+		curr += sprintf(curr, "%d", td->mutexes[i]);
+
+	spin_unlock(&rttest_lock);
+
+	curr += sprintf(curr, ", T: %p, R: %p\n", tsk,
+			mutexes[td->sysdev.id].owner);
+
+	return curr - buf;
+}
+
+static SYSDEV_ATTR(status, 0600, sysfs_test_status, NULL);
+static SYSDEV_ATTR(command, 0600, NULL, sysfs_test_command);
+
+static struct sysdev_class rttest_sysclass = {
+	set_kset_name("rttest"),
+};
+
+static int init_test_thread(int id)
+{
+	thread_data[id].sysdev.cls = &rttest_sysclass;
+	thread_data[id].sysdev.id = id;
+
+	threads[id] = kthread_run(test_func, &thread_data[id], "rt-test-%d", id);
+	if (IS_ERR(threads[id]))
+		return PTR_ERR(threads[id]);
+
+	return sysdev_register(&thread_data[id].sysdev);
+}
+
+static int init_rttest(void)
+{
+	int ret, i;
+
+	spin_lock_init(&rttest_lock);
+
+	for (i = 0; i < MAX_RT_TEST_MUTEXES; i++)
+		rt_mutex_init(&mutexes[i]);
+
+	ret = sysdev_class_register(&rttest_sysclass);
+	if (ret)
+		return ret;
+
+	for (i = 0; i < MAX_RT_TEST_THREADS; i++) {
+		ret = init_test_thread(i);
+		if (ret)
+			break;
+		ret = sysdev_create_file(&thread_data[i].sysdev, &attr_status);
+		if (ret)
+			break;
+		ret = sysdev_create_file(&thread_data[i].sysdev, &attr_command);
+		if (ret)
+			break;
+	}
+
+	printk("Initializing RT-Tester: %s\n", ret ? "Failed" : "OK" );
+
+	return ret;
+}
+
+device_initcall(init_rttest);
diff --git a/kernel/rtmutex.c b/kernel/rtmutex.c
new file mode 100644
index 000000000..3e13a1e58
--- /dev/null
+++ b/kernel/rtmutex.c
@@ -0,0 +1,991 @@
+/*
+ * RT-Mutexes: simple blocking mutual exclusion locks with PI support
+ *
+ * started by Ingo Molnar and Thomas Gleixner.
+ *
+ *  Copyright (C) 2004-2006 Red Hat, Inc., Ingo Molnar <mingo@redhat.com>
+ *  Copyright (C) 2005-2006 Timesys Corp., Thomas Gleixner <tglx@timesys.com>
+ *  Copyright (C) 2005 Kihon Technologies Inc., Steven Rostedt
+ *  Copyright (C) 2006 Esben Nielsen
+ *
+ *  See Documentation/rt-mutex-design.txt for details.
+ */
+#include <linux/spinlock.h>
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/timer.h>
+
+#include "rtmutex_common.h"
+
+#ifdef CONFIG_DEBUG_RT_MUTEXES
+# include "rtmutex-debug.h"
+#else
+# include "rtmutex.h"
+#endif
+
+/*
+ * lock->owner state tracking:
+ *
+ * lock->owner holds the task_struct pointer of the owner. Bit 0 and 1
+ * are used to keep track of the "owner is pending" and "lock has
+ * waiters" state.
+ *
+ * owner	bit1	bit0
+ * NULL		0	0	lock is free (fast acquire possible)
+ * NULL		0	1	invalid state
+ * NULL		1	0	Transitional State*
+ * NULL		1	1	invalid state
+ * taskpointer	0	0	lock is held (fast release possible)
+ * taskpointer	0	1	task is pending owner
+ * taskpointer	1	0	lock is held and has waiters
+ * taskpointer	1	1	task is pending owner and lock has more waiters
+ *
+ * Pending ownership is assigned to the top (highest priority)
+ * waiter of the lock, when the lock is released. The thread is woken
+ * up and can now take the lock. Until the lock is taken (bit 0
+ * cleared) a competing higher priority thread can steal the lock
+ * which puts the woken up thread back on the waiters list.
+ *
+ * The fast atomic compare exchange based acquire and release is only
+ * possible when bit 0 and 1 of lock->owner are 0.
+ *
+ * (*) There's a small time where the owner can be NULL and the
+ * "lock has waiters" bit is set.  This can happen when grabbing the lock.
+ * To prevent a cmpxchg of the owner releasing the lock, we need to set this
+ * bit before looking at the lock, hence the reason this is a transitional
+ * state.
+ */
+
+static void
+rt_mutex_set_owner(struct rt_mutex *lock, struct task_struct *owner,
+		   unsigned long mask)
+{
+	unsigned long val = (unsigned long)owner | mask;
+
+	if (rt_mutex_has_waiters(lock))
+		val |= RT_MUTEX_HAS_WAITERS;
+
+	lock->owner = (struct task_struct *)val;
+}
+
+static inline void clear_rt_mutex_waiters(struct rt_mutex *lock)
+{
+	lock->owner = (struct task_struct *)
+			((unsigned long)lock->owner & ~RT_MUTEX_HAS_WAITERS);
+}
+
+static void fixup_rt_mutex_waiters(struct rt_mutex *lock)
+{
+	if (!rt_mutex_has_waiters(lock))
+		clear_rt_mutex_waiters(lock);
+}
+
+/*
+ * We can speed up the acquire/release, if the architecture
+ * supports cmpxchg and if there's no debugging state to be set up
+ */
+#if defined(__HAVE_ARCH_CMPXCHG) && !defined(CONFIG_DEBUG_RT_MUTEXES)
+# define rt_mutex_cmpxchg(l,c,n)	(cmpxchg(&l->owner, c, n) == c)
+static inline void mark_rt_mutex_waiters(struct rt_mutex *lock)
+{
+	unsigned long owner, *p = (unsigned long *) &lock->owner;
+
+	do {
+		owner = *p;
+	} while (cmpxchg(p, owner, owner | RT_MUTEX_HAS_WAITERS) != owner);
+}
+#else
+# define rt_mutex_cmpxchg(l,c,n)	(0)
+static inline void mark_rt_mutex_waiters(struct rt_mutex *lock)
+{
+	lock->owner = (struct task_struct *)
+			((unsigned long)lock->owner | RT_MUTEX_HAS_WAITERS);
+}
+#endif
+
+/*
+ * Calculate task priority from the waiter list priority
+ *
+ * Return task->normal_prio when the waiter list is empty or when
+ * the waiter is not allowed to do priority boosting
+ */
+int rt_mutex_getprio(struct task_struct *task)
+{
+	if (likely(!task_has_pi_waiters(task)))
+		return task->normal_prio;
+
+	return min(task_top_pi_waiter(task)->pi_list_entry.prio,
+		   task->normal_prio);
+}
+
+/*
+ * Adjust the priority of a task, after its pi_waiters got modified.
+ *
+ * This can be both boosting and unboosting. task->pi_lock must be held.
+ */
+static void __rt_mutex_adjust_prio(struct task_struct *task)
+{
+	int prio = rt_mutex_getprio(task);
+
+	if (task->prio != prio)
+		rt_mutex_setprio(task, prio);
+}
+
+/*
+ * Adjust task priority (undo boosting). Called from the exit path of
+ * rt_mutex_slowunlock() and rt_mutex_slowlock().
+ *
+ * (Note: We do this outside of the protection of lock->wait_lock to
+ * allow the lock to be taken while or before we readjust the priority
+ * of task. We do not use the spin_xx_mutex() variants here as we are
+ * outside of the debug path.)
+ */
+static void rt_mutex_adjust_prio(struct task_struct *task)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&task->pi_lock, flags);
+	__rt_mutex_adjust_prio(task);
+	spin_unlock_irqrestore(&task->pi_lock, flags);
+}
+
+/*
+ * Max number of times we'll walk the boosting chain:
+ */
+int max_lock_depth = 1024;
+
+/*
+ * Adjust the priority chain. Also used for deadlock detection.
+ * Decreases task's usage by one - may thus free the task.
+ * Returns 0 or -EDEADLK.
+ */
+static int rt_mutex_adjust_prio_chain(struct task_struct *task,
+				      int deadlock_detect,
+				      struct rt_mutex *orig_lock,
+				      struct rt_mutex_waiter *orig_waiter,
+				      struct task_struct *top_task)
+{
+	struct rt_mutex *lock;
+	struct rt_mutex_waiter *waiter, *top_waiter = orig_waiter;
+	int detect_deadlock, ret = 0, depth = 0;
+	unsigned long flags;
+
+	detect_deadlock = debug_rt_mutex_detect_deadlock(orig_waiter,
+							 deadlock_detect);
+
+	/*
+	 * The (de)boosting is a step by step approach with a lot of
+	 * pitfalls. We want this to be preemptible and we want hold a
+	 * maximum of two locks per step. So we have to check
+	 * carefully whether things change under us.
+	 */
+ again:
+	if (++depth > max_lock_depth) {
+		static int prev_max;
+
+		/*
+		 * Print this only once. If the admin changes the limit,
+		 * print a new message when reaching the limit again.
+		 */
+		if (prev_max != max_lock_depth) {
+			prev_max = max_lock_depth;
+			printk(KERN_WARNING "Maximum lock depth %d reached "
+			       "task: %s (%d)\n", max_lock_depth,
+			       top_task->comm, top_task->pid);
+		}
+		put_task_struct(task);
+
+		return deadlock_detect ? -EDEADLK : 0;
+	}
+ retry:
+	/*
+	 * Task can not go away as we did a get_task() before !
+	 */
+	spin_lock_irqsave(&task->pi_lock, flags);
+
+	waiter = task->pi_blocked_on;
+	/*
+	 * Check whether the end of the boosting chain has been
+	 * reached or the state of the chain has changed while we
+	 * dropped the locks.
+	 */
+	if (!waiter || !waiter->task)
+		goto out_unlock_pi;
+
+	if (top_waiter && (!task_has_pi_waiters(task) ||
+			   top_waiter != task_top_pi_waiter(task)))
+		goto out_unlock_pi;
+
+	/*
+	 * When deadlock detection is off then we check, if further
+	 * priority adjustment is necessary.
+	 */
+	if (!detect_deadlock && waiter->list_entry.prio == task->prio)
+		goto out_unlock_pi;
+
+	lock = waiter->lock;
+	if (!spin_trylock(&lock->wait_lock)) {
+		spin_unlock_irqrestore(&task->pi_lock, flags);
+		cpu_relax();
+		goto retry;
+	}
+
+	/* Deadlock detection */
+	if (lock == orig_lock || rt_mutex_owner(lock) == top_task) {
+		debug_rt_mutex_deadlock(deadlock_detect, orig_waiter, lock);
+		spin_unlock(&lock->wait_lock);
+		ret = deadlock_detect ? -EDEADLK : 0;
+		goto out_unlock_pi;
+	}
+
+	top_waiter = rt_mutex_top_waiter(lock);
+
+	/* Requeue the waiter */
+	plist_del(&waiter->list_entry, &lock->wait_list);
+	waiter->list_entry.prio = task->prio;
+	plist_add(&waiter->list_entry, &lock->wait_list);
+
+	/* Release the task */
+	spin_unlock_irqrestore(&task->pi_lock, flags);
+	put_task_struct(task);
+
+	/* Grab the next task */
+	task = rt_mutex_owner(lock);
+	spin_lock_irqsave(&task->pi_lock, flags);
+
+	if (waiter == rt_mutex_top_waiter(lock)) {
+		/* Boost the owner */
+		plist_del(&top_waiter->pi_list_entry, &task->pi_waiters);
+		waiter->pi_list_entry.prio = waiter->list_entry.prio;
+		plist_add(&waiter->pi_list_entry, &task->pi_waiters);
+		__rt_mutex_adjust_prio(task);
+
+	} else if (top_waiter == waiter) {
+		/* Deboost the owner */
+		plist_del(&waiter->pi_list_entry, &task->pi_waiters);
+		waiter = rt_mutex_top_waiter(lock);
+		waiter->pi_list_entry.prio = waiter->list_entry.prio;
+		plist_add(&waiter->pi_list_entry, &task->pi_waiters);
+		__rt_mutex_adjust_prio(task);
+	}
+
+	get_task_struct(task);
+	spin_unlock_irqrestore(&task->pi_lock, flags);
+
+	top_waiter = rt_mutex_top_waiter(lock);
+	spin_unlock(&lock->wait_lock);
+
+	if (!detect_deadlock && waiter != top_waiter)
+		goto out_put_task;
+
+	goto again;
+
+ out_unlock_pi:
+	spin_unlock_irqrestore(&task->pi_lock, flags);
+ out_put_task:
+	put_task_struct(task);
+
+	return ret;
+}
+
+/*
+ * Optimization: check if we can steal the lock from the
+ * assigned pending owner [which might not have taken the
+ * lock yet]:
+ */
+static inline int try_to_steal_lock(struct rt_mutex *lock)
+{
+	struct task_struct *pendowner = rt_mutex_owner(lock);
+	struct rt_mutex_waiter *next;
+	unsigned long flags;
+
+	if (!rt_mutex_owner_pending(lock))
+		return 0;
+
+	if (pendowner == current)
+		return 1;
+
+	spin_lock_irqsave(&pendowner->pi_lock, flags);
+	if (current->prio >= pendowner->prio) {
+		spin_unlock_irqrestore(&pendowner->pi_lock, flags);
+		return 0;
+	}
+
+	/*
+	 * Check if a waiter is enqueued on the pending owners
+	 * pi_waiters list. Remove it and readjust pending owners
+	 * priority.
+	 */
+	if (likely(!rt_mutex_has_waiters(lock))) {
+		spin_unlock_irqrestore(&pendowner->pi_lock, flags);
+		return 1;
+	}
+
+	/* No chain handling, pending owner is not blocked on anything: */
+	next = rt_mutex_top_waiter(lock);
+	plist_del(&next->pi_list_entry, &pendowner->pi_waiters);
+	__rt_mutex_adjust_prio(pendowner);
+	spin_unlock_irqrestore(&pendowner->pi_lock, flags);
+
+	/*
+	 * We are going to steal the lock and a waiter was
+	 * enqueued on the pending owners pi_waiters queue. So
+	 * we have to enqueue this waiter into
+	 * current->pi_waiters list. This covers the case,
+	 * where current is boosted because it holds another
+	 * lock and gets unboosted because the booster is
+	 * interrupted, so we would delay a waiter with higher
+	 * priority as current->normal_prio.
+	 *
+	 * Note: in the rare case of a SCHED_OTHER task changing
+	 * its priority and thus stealing the lock, next->task
+	 * might be current:
+	 */
+	if (likely(next->task != current)) {
+		spin_lock_irqsave(&current->pi_lock, flags);
+		plist_add(&next->pi_list_entry, &current->pi_waiters);
+		__rt_mutex_adjust_prio(current);
+		spin_unlock_irqrestore(&current->pi_lock, flags);
+	}
+	return 1;
+}
+
+/*
+ * Try to take an rt-mutex
+ *
+ * This fails
+ * - when the lock has a real owner
+ * - when a different pending owner exists and has higher priority than current
+ *
+ * Must be called with lock->wait_lock held.
+ */
+static int try_to_take_rt_mutex(struct rt_mutex *lock)
+{
+	/*
+	 * We have to be careful here if the atomic speedups are
+	 * enabled, such that, when
+	 *  - no other waiter is on the lock
+	 *  - the lock has been released since we did the cmpxchg
+	 * the lock can be released or taken while we are doing the
+	 * checks and marking the lock with RT_MUTEX_HAS_WAITERS.
+	 *
+	 * The atomic acquire/release aware variant of
+	 * mark_rt_mutex_waiters uses a cmpxchg loop. After setting
+	 * the WAITERS bit, the atomic release / acquire can not
+	 * happen anymore and lock->wait_lock protects us from the
+	 * non-atomic case.
+	 *
+	 * Note, that this might set lock->owner =
+	 * RT_MUTEX_HAS_WAITERS in the case the lock is not contended
+	 * any more. This is fixed up when we take the ownership.
+	 * This is the transitional state explained at the top of this file.
+	 */
+	mark_rt_mutex_waiters(lock);
+
+	if (rt_mutex_owner(lock) && !try_to_steal_lock(lock))
+		return 0;
+
+	/* We got the lock. */
+	debug_rt_mutex_lock(lock);
+
+	rt_mutex_set_owner(lock, current, 0);
+
+	rt_mutex_deadlock_account_lock(lock, current);
+
+	return 1;
+}
+
+/*
+ * Task blocks on lock.
+ *
+ * Prepare waiter and propagate pi chain
+ *
+ * This must be called with lock->wait_lock held.
+ */
+static int task_blocks_on_rt_mutex(struct rt_mutex *lock,
+				   struct rt_mutex_waiter *waiter,
+				   int detect_deadlock)
+{
+	struct task_struct *owner = rt_mutex_owner(lock);
+	struct rt_mutex_waiter *top_waiter = waiter;
+	unsigned long flags;
+	int boost = 0, res;
+
+	spin_lock_irqsave(&current->pi_lock, flags);
+	__rt_mutex_adjust_prio(current);
+	waiter->task = current;
+	waiter->lock = lock;
+	plist_node_init(&waiter->list_entry, current->prio);
+	plist_node_init(&waiter->pi_list_entry, current->prio);
+
+	/* Get the top priority waiter on the lock */
+	if (rt_mutex_has_waiters(lock))
+		top_waiter = rt_mutex_top_waiter(lock);
+	plist_add(&waiter->list_entry, &lock->wait_list);
+
+	current->pi_blocked_on = waiter;
+
+	spin_unlock_irqrestore(&current->pi_lock, flags);
+
+	if (waiter == rt_mutex_top_waiter(lock)) {
+		spin_lock_irqsave(&owner->pi_lock, flags);
+		plist_del(&top_waiter->pi_list_entry, &owner->pi_waiters);
+		plist_add(&waiter->pi_list_entry, &owner->pi_waiters);
+
+		__rt_mutex_adjust_prio(owner);
+		if (owner->pi_blocked_on) {
+			boost = 1;
+			/* gets dropped in rt_mutex_adjust_prio_chain()! */
+			get_task_struct(owner);
+		}
+		spin_unlock_irqrestore(&owner->pi_lock, flags);
+	}
+	else if (debug_rt_mutex_detect_deadlock(waiter, detect_deadlock)) {
+		spin_lock_irqsave(&owner->pi_lock, flags);
+		if (owner->pi_blocked_on) {
+			boost = 1;
+			/* gets dropped in rt_mutex_adjust_prio_chain()! */
+			get_task_struct(owner);
+		}
+		spin_unlock_irqrestore(&owner->pi_lock, flags);
+	}
+	if (!boost)
+		return 0;
+
+	spin_unlock(&lock->wait_lock);
+
+	res = rt_mutex_adjust_prio_chain(owner, detect_deadlock, lock, waiter,
+					 current);
+
+	spin_lock(&lock->wait_lock);
+
+	return res;
+}
+
+/*
+ * Wake up the next waiter on the lock.
+ *
+ * Remove the top waiter from the current tasks waiter list and from
+ * the lock waiter list. Set it as pending owner. Then wake it up.
+ *
+ * Called with lock->wait_lock held.
+ */
+static void wakeup_next_waiter(struct rt_mutex *lock)
+{
+	struct rt_mutex_waiter *waiter;
+	struct task_struct *pendowner;
+	unsigned long flags;
+
+	spin_lock_irqsave(&current->pi_lock, flags);
+
+	waiter = rt_mutex_top_waiter(lock);
+	plist_del(&waiter->list_entry, &lock->wait_list);
+
+	/*
+	 * Remove it from current->pi_waiters. We do not adjust a
+	 * possible priority boost right now. We execute wakeup in the
+	 * boosted mode and go back to normal after releasing
+	 * lock->wait_lock.
+	 */
+	plist_del(&waiter->pi_list_entry, &current->pi_waiters);
+	pendowner = waiter->task;
+	waiter->task = NULL;
+
+	rt_mutex_set_owner(lock, pendowner, RT_MUTEX_OWNER_PENDING);
+
+	spin_unlock_irqrestore(&current->pi_lock, flags);
+
+	/*
+	 * Clear the pi_blocked_on variable and enqueue a possible
+	 * waiter into the pi_waiters list of the pending owner. This
+	 * prevents that in case the pending owner gets unboosted a
+	 * waiter with higher priority than pending-owner->normal_prio
+	 * is blocked on the unboosted (pending) owner.
+	 */
+	spin_lock_irqsave(&pendowner->pi_lock, flags);
+
+	WARN_ON(!pendowner->pi_blocked_on);
+	WARN_ON(pendowner->pi_blocked_on != waiter);
+	WARN_ON(pendowner->pi_blocked_on->lock != lock);
+
+	pendowner->pi_blocked_on = NULL;
+
+	if (rt_mutex_has_waiters(lock)) {
+		struct rt_mutex_waiter *next;
+
+		next = rt_mutex_top_waiter(lock);
+		plist_add(&next->pi_list_entry, &pendowner->pi_waiters);
+	}
+	spin_unlock_irqrestore(&pendowner->pi_lock, flags);
+
+	wake_up_process(pendowner);
+}
+
+/*
+ * Remove a waiter from a lock
+ *
+ * Must be called with lock->wait_lock held
+ */
+static void remove_waiter(struct rt_mutex *lock,
+			  struct rt_mutex_waiter *waiter)
+{
+	int first = (waiter == rt_mutex_top_waiter(lock));
+	struct task_struct *owner = rt_mutex_owner(lock);
+	unsigned long flags;
+	int boost = 0;
+
+	spin_lock_irqsave(&current->pi_lock, flags);
+	plist_del(&waiter->list_entry, &lock->wait_list);
+	waiter->task = NULL;
+	current->pi_blocked_on = NULL;
+	spin_unlock_irqrestore(&current->pi_lock, flags);
+
+	if (first && owner != current) {
+
+		spin_lock_irqsave(&owner->pi_lock, flags);
+
+		plist_del(&waiter->pi_list_entry, &owner->pi_waiters);
+
+		if (rt_mutex_has_waiters(lock)) {
+			struct rt_mutex_waiter *next;
+
+			next = rt_mutex_top_waiter(lock);
+			plist_add(&next->pi_list_entry, &owner->pi_waiters);
+		}
+		__rt_mutex_adjust_prio(owner);
+
+		if (owner->pi_blocked_on) {
+			boost = 1;
+			/* gets dropped in rt_mutex_adjust_prio_chain()! */
+			get_task_struct(owner);
+		}
+		spin_unlock_irqrestore(&owner->pi_lock, flags);
+	}
+
+	WARN_ON(!plist_node_empty(&waiter->pi_list_entry));
+
+	if (!boost)
+		return;
+
+	spin_unlock(&lock->wait_lock);
+
+	rt_mutex_adjust_prio_chain(owner, 0, lock, NULL, current);
+
+	spin_lock(&lock->wait_lock);
+}
+
+/*
+ * Recheck the pi chain, in case we got a priority setting
+ *
+ * Called from sched_setscheduler
+ */
+void rt_mutex_adjust_pi(struct task_struct *task)
+{
+	struct rt_mutex_waiter *waiter;
+	unsigned long flags;
+
+	spin_lock_irqsave(&task->pi_lock, flags);
+
+	waiter = task->pi_blocked_on;
+	if (!waiter || waiter->list_entry.prio == task->prio) {
+		spin_unlock_irqrestore(&task->pi_lock, flags);
+		return;
+	}
+
+	/* gets dropped in rt_mutex_adjust_prio_chain()! */
+	get_task_struct(task);
+	spin_unlock_irqrestore(&task->pi_lock, flags);
+
+	rt_mutex_adjust_prio_chain(task, 0, NULL, NULL, task);
+}
+
+/*
+ * Slow path lock function:
+ */
+static int __sched
+rt_mutex_slowlock(struct rt_mutex *lock, int state,
+		  struct hrtimer_sleeper *timeout,
+		  int detect_deadlock)
+{
+	struct rt_mutex_waiter waiter;
+	int ret = 0;
+
+	debug_rt_mutex_init_waiter(&waiter);
+	waiter.task = NULL;
+
+	spin_lock(&lock->wait_lock);
+
+	/* Try to acquire the lock again: */
+	if (try_to_take_rt_mutex(lock)) {
+		spin_unlock(&lock->wait_lock);
+		return 0;
+	}
+
+	set_current_state(state);
+
+	/* Setup the timer, when timeout != NULL */
+	if (unlikely(timeout))
+		hrtimer_start(&timeout->timer, timeout->timer.expires,
+			      HRTIMER_ABS);
+
+	for (;;) {
+		/* Try to acquire the lock: */
+		if (try_to_take_rt_mutex(lock))
+			break;
+
+		/*
+		 * TASK_INTERRUPTIBLE checks for signals and
+		 * timeout. Ignored otherwise.
+		 */
+		if (unlikely(state == TASK_INTERRUPTIBLE)) {
+			/* Signal pending? */
+			if (signal_pending(current))
+				ret = -EINTR;
+			if (timeout && !timeout->task)
+				ret = -ETIMEDOUT;
+			if (ret)
+				break;
+		}
+
+		/*
+		 * waiter.task is NULL the first time we come here and
+		 * when we have been woken up by the previous owner
+		 * but the lock got stolen by a higher prio task.
+		 */
+		if (!waiter.task) {
+			ret = task_blocks_on_rt_mutex(lock, &waiter,
+						      detect_deadlock);
+			/*
+			 * If we got woken up by the owner then start loop
+			 * all over without going into schedule to try
+			 * to get the lock now:
+			 */
+			if (unlikely(!waiter.task))
+				continue;
+
+			if (unlikely(ret))
+				break;
+		}
+
+		spin_unlock(&lock->wait_lock);
+
+		debug_rt_mutex_print_deadlock(&waiter);
+
+		if (waiter.task)
+			schedule_rt_mutex(lock);
+
+		spin_lock(&lock->wait_lock);
+		set_current_state(state);
+	}
+
+	set_current_state(TASK_RUNNING);
+
+	if (unlikely(waiter.task))
+		remove_waiter(lock, &waiter);
+
+	/*
+	 * try_to_take_rt_mutex() sets the waiter bit
+	 * unconditionally. We might have to fix that up.
+	 */
+	fixup_rt_mutex_waiters(lock);
+
+	spin_unlock(&lock->wait_lock);
+
+	/* Remove pending timer: */
+	if (unlikely(timeout))
+		hrtimer_cancel(&timeout->timer);
+
+	/*
+	 * Readjust priority, when we did not get the lock. We might
+	 * have been the pending owner and boosted. Since we did not
+	 * take the lock, the PI boost has to go.
+	 */
+	if (unlikely(ret))
+		rt_mutex_adjust_prio(current);
+
+	debug_rt_mutex_free_waiter(&waiter);
+
+	return ret;
+}
+
+/*
+ * Slow path try-lock function:
+ */
+static inline int
+rt_mutex_slowtrylock(struct rt_mutex *lock)
+{
+	int ret = 0;
+
+	spin_lock(&lock->wait_lock);
+
+	if (likely(rt_mutex_owner(lock) != current)) {
+
+		ret = try_to_take_rt_mutex(lock);
+		/*
+		 * try_to_take_rt_mutex() sets the lock waiters
+		 * bit unconditionally. Clean this up.
+		 */
+		fixup_rt_mutex_waiters(lock);
+	}
+
+	spin_unlock(&lock->wait_lock);
+
+	return ret;
+}
+
+/*
+ * Slow path to release a rt-mutex:
+ */
+static void __sched
+rt_mutex_slowunlock(struct rt_mutex *lock)
+{
+	spin_lock(&lock->wait_lock);
+
+	debug_rt_mutex_unlock(lock);
+
+	rt_mutex_deadlock_account_unlock(current);
+
+	if (!rt_mutex_has_waiters(lock)) {
+		lock->owner = NULL;
+		spin_unlock(&lock->wait_lock);
+		return;
+	}
+
+	wakeup_next_waiter(lock);
+
+	spin_unlock(&lock->wait_lock);
+
+	/* Undo pi boosting if necessary: */
+	rt_mutex_adjust_prio(current);
+}
+
+/*
+ * debug aware fast / slowpath lock,trylock,unlock
+ *
+ * The atomic acquire/release ops are compiled away, when either the
+ * architecture does not support cmpxchg or when debugging is enabled.
+ */
+static inline int
+rt_mutex_fastlock(struct rt_mutex *lock, int state,
+		  int detect_deadlock,
+		  int (*slowfn)(struct rt_mutex *lock, int state,
+				struct hrtimer_sleeper *timeout,
+				int detect_deadlock))
+{
+	if (!detect_deadlock && likely(rt_mutex_cmpxchg(lock, NULL, current))) {
+		rt_mutex_deadlock_account_lock(lock, current);
+		return 0;
+	} else
+		return slowfn(lock, state, NULL, detect_deadlock);
+}
+
+static inline int
+rt_mutex_timed_fastlock(struct rt_mutex *lock, int state,
+			struct hrtimer_sleeper *timeout, int detect_deadlock,
+			int (*slowfn)(struct rt_mutex *lock, int state,
+				      struct hrtimer_sleeper *timeout,
+				      int detect_deadlock))
+{
+	if (!detect_deadlock && likely(rt_mutex_cmpxchg(lock, NULL, current))) {
+		rt_mutex_deadlock_account_lock(lock, current);
+		return 0;
+	} else
+		return slowfn(lock, state, timeout, detect_deadlock);
+}
+
+static inline int
+rt_mutex_fasttrylock(struct rt_mutex *lock,
+		     int (*slowfn)(struct rt_mutex *lock))
+{
+	if (likely(rt_mutex_cmpxchg(lock, NULL, current))) {
+		rt_mutex_deadlock_account_lock(lock, current);
+		return 1;
+	}
+	return slowfn(lock);
+}
+
+static inline void
+rt_mutex_fastunlock(struct rt_mutex *lock,
+		    void (*slowfn)(struct rt_mutex *lock))
+{
+	if (likely(rt_mutex_cmpxchg(lock, current, NULL)))
+		rt_mutex_deadlock_account_unlock(current);
+	else
+		slowfn(lock);
+}
+
+/**
+ * rt_mutex_lock - lock a rt_mutex
+ *
+ * @lock: the rt_mutex to be locked
+ */
+void __sched rt_mutex_lock(struct rt_mutex *lock)
+{
+	might_sleep();
+
+	rt_mutex_fastlock(lock, TASK_UNINTERRUPTIBLE, 0, rt_mutex_slowlock);
+}
+EXPORT_SYMBOL_GPL(rt_mutex_lock);
+
+/**
+ * rt_mutex_lock_interruptible - lock a rt_mutex interruptible
+ *
+ * @lock: 		the rt_mutex to be locked
+ * @detect_deadlock:	deadlock detection on/off
+ *
+ * Returns:
+ *  0 		on success
+ * -EINTR 	when interrupted by a signal
+ * -EDEADLK	when the lock would deadlock (when deadlock detection is on)
+ */
+int __sched rt_mutex_lock_interruptible(struct rt_mutex *lock,
+						 int detect_deadlock)
+{
+	might_sleep();
+
+	return rt_mutex_fastlock(lock, TASK_INTERRUPTIBLE,
+				 detect_deadlock, rt_mutex_slowlock);
+}
+EXPORT_SYMBOL_GPL(rt_mutex_lock_interruptible);
+
+/**
+ * rt_mutex_lock_interruptible_ktime - lock a rt_mutex interruptible
+ *				       the timeout structure is provided
+ *				       by the caller
+ *
+ * @lock: 		the rt_mutex to be locked
+ * @timeout:		timeout structure or NULL (no timeout)
+ * @detect_deadlock:	deadlock detection on/off
+ *
+ * Returns:
+ *  0 		on success
+ * -EINTR 	when interrupted by a signal
+ * -ETIMEOUT	when the timeout expired
+ * -EDEADLK	when the lock would deadlock (when deadlock detection is on)
+ */
+int
+rt_mutex_timed_lock(struct rt_mutex *lock, struct hrtimer_sleeper *timeout,
+		    int detect_deadlock)
+{
+	might_sleep();
+
+	return rt_mutex_timed_fastlock(lock, TASK_INTERRUPTIBLE, timeout,
+				       detect_deadlock, rt_mutex_slowlock);
+}
+EXPORT_SYMBOL_GPL(rt_mutex_timed_lock);
+
+/**
+ * rt_mutex_trylock - try to lock a rt_mutex
+ *
+ * @lock:	the rt_mutex to be locked
+ *
+ * Returns 1 on success and 0 on contention
+ */
+int __sched rt_mutex_trylock(struct rt_mutex *lock)
+{
+	return rt_mutex_fasttrylock(lock, rt_mutex_slowtrylock);
+}
+EXPORT_SYMBOL_GPL(rt_mutex_trylock);
+
+/**
+ * rt_mutex_unlock - unlock a rt_mutex
+ *
+ * @lock: the rt_mutex to be unlocked
+ */
+void __sched rt_mutex_unlock(struct rt_mutex *lock)
+{
+	rt_mutex_fastunlock(lock, rt_mutex_slowunlock);
+}
+EXPORT_SYMBOL_GPL(rt_mutex_unlock);
+
+/***
+ * rt_mutex_destroy - mark a mutex unusable
+ * @lock: the mutex to be destroyed
+ *
+ * This function marks the mutex uninitialized, and any subsequent
+ * use of the mutex is forbidden. The mutex must not be locked when
+ * this function is called.
+ */
+void rt_mutex_destroy(struct rt_mutex *lock)
+{
+	WARN_ON(rt_mutex_is_locked(lock));
+#ifdef CONFIG_DEBUG_RT_MUTEXES
+	lock->magic = NULL;
+#endif
+}
+
+EXPORT_SYMBOL_GPL(rt_mutex_destroy);
+
+/**
+ * __rt_mutex_init - initialize the rt lock
+ *
+ * @lock: the rt lock to be initialized
+ *
+ * Initialize the rt lock to unlocked state.
+ *
+ * Initializing of a locked rt lock is not allowed
+ */
+void __rt_mutex_init(struct rt_mutex *lock, const char *name)
+{
+	lock->owner = NULL;
+	spin_lock_init(&lock->wait_lock);
+	plist_head_init(&lock->wait_list, &lock->wait_lock);
+
+	debug_rt_mutex_init(lock, name);
+}
+EXPORT_SYMBOL_GPL(__rt_mutex_init);
+
+/**
+ * rt_mutex_init_proxy_locked - initialize and lock a rt_mutex on behalf of a
+ *				proxy owner
+ *
+ * @lock: 	the rt_mutex to be locked
+ * @proxy_owner:the task to set as owner
+ *
+ * No locking. Caller has to do serializing itself
+ * Special API call for PI-futex support
+ */
+void rt_mutex_init_proxy_locked(struct rt_mutex *lock,
+				struct task_struct *proxy_owner)
+{
+	__rt_mutex_init(lock, NULL);
+	debug_rt_mutex_proxy_lock(lock, proxy_owner);
+	rt_mutex_set_owner(lock, proxy_owner, 0);
+	rt_mutex_deadlock_account_lock(lock, proxy_owner);
+}
+
+/**
+ * rt_mutex_proxy_unlock - release a lock on behalf of owner
+ *
+ * @lock: 	the rt_mutex to be locked
+ *
+ * No locking. Caller has to do serializing itself
+ * Special API call for PI-futex support
+ */
+void rt_mutex_proxy_unlock(struct rt_mutex *lock,
+			   struct task_struct *proxy_owner)
+{
+	debug_rt_mutex_proxy_unlock(lock);
+	rt_mutex_set_owner(lock, NULL, 0);
+	rt_mutex_deadlock_account_unlock(proxy_owner);
+}
+
+/**
+ * rt_mutex_next_owner - return the next owner of the lock
+ *
+ * @lock: the rt lock query
+ *
+ * Returns the next owner of the lock or NULL
+ *
+ * Caller has to serialize against other accessors to the lock
+ * itself.
+ *
+ * Special API call for PI-futex support
+ */
+struct task_struct *rt_mutex_next_owner(struct rt_mutex *lock)
+{
+	if (!rt_mutex_has_waiters(lock))
+		return NULL;
+
+	return rt_mutex_top_waiter(lock)->task;
+}
diff --git a/kernel/rtmutex.h b/kernel/rtmutex.h
new file mode 100644
index 000000000..a1a1dd064
--- /dev/null
+++ b/kernel/rtmutex.h
@@ -0,0 +1,26 @@
+/*
+ * RT-Mutexes: blocking mutual exclusion locks with PI support
+ *
+ * started by Ingo Molnar and Thomas Gleixner:
+ *
+ *  Copyright (C) 2004-2006 Red Hat, Inc., Ingo Molnar <mingo@redhat.com>
+ *  Copyright (C) 2006, Timesys Corp., Thomas Gleixner <tglx@timesys.com>
+ *
+ * This file contains macros used solely by rtmutex.c.
+ * Non-debug version.
+ */
+
+#define rt_mutex_deadlock_check(l)			(0)
+#define rt_mutex_deadlock_account_lock(m, t)		do { } while (0)
+#define rt_mutex_deadlock_account_unlock(l)		do { } while (0)
+#define debug_rt_mutex_init_waiter(w)			do { } while (0)
+#define debug_rt_mutex_free_waiter(w)			do { } while (0)
+#define debug_rt_mutex_lock(l)				do { } while (0)
+#define debug_rt_mutex_proxy_lock(l,p)			do { } while (0)
+#define debug_rt_mutex_proxy_unlock(l)			do { } while (0)
+#define debug_rt_mutex_unlock(l)			do { } while (0)
+#define debug_rt_mutex_init(m, n)			do { } while (0)
+#define debug_rt_mutex_deadlock(d, a ,l)		do { } while (0)
+#define debug_rt_mutex_print_deadlock(w)		do { } while (0)
+#define debug_rt_mutex_detect_deadlock(w,d)		(d)
+#define debug_rt_mutex_reset_waiter(w)			do { } while (0)
diff --git a/kernel/rtmutex_common.h b/kernel/rtmutex_common.h
new file mode 100644
index 000000000..9c75856e7
--- /dev/null
+++ b/kernel/rtmutex_common.h
@@ -0,0 +1,123 @@
+/*
+ * RT Mutexes: blocking mutual exclusion locks with PI support
+ *
+ * started by Ingo Molnar and Thomas Gleixner:
+ *
+ *  Copyright (C) 2004-2006 Red Hat, Inc., Ingo Molnar <mingo@redhat.com>
+ *  Copyright (C) 2006, Timesys Corp., Thomas Gleixner <tglx@timesys.com>
+ *
+ * This file contains the private data structure and API definitions.
+ */
+
+#ifndef __KERNEL_RTMUTEX_COMMON_H
+#define __KERNEL_RTMUTEX_COMMON_H
+
+#include <linux/rtmutex.h>
+
+/*
+ * The rtmutex in kernel tester is independent of rtmutex debugging. We
+ * call schedule_rt_mutex_test() instead of schedule() for the tasks which
+ * belong to the tester. That way we can delay the wakeup path of those
+ * threads to provoke lock stealing and testing of  complex boosting scenarios.
+ */
+#ifdef CONFIG_RT_MUTEX_TESTER
+
+extern void schedule_rt_mutex_test(struct rt_mutex *lock);
+
+#define schedule_rt_mutex(_lock)				\
+  do {								\
+	if (!(current->flags & PF_MUTEX_TESTER))		\
+		schedule();					\
+	else							\
+		schedule_rt_mutex_test(_lock);			\
+  } while (0)
+
+#else
+# define schedule_rt_mutex(_lock)			schedule()
+#endif
+
+/*
+ * This is the control structure for tasks blocked on a rt_mutex,
+ * which is allocated on the kernel stack on of the blocked task.
+ *
+ * @list_entry:		pi node to enqueue into the mutex waiters list
+ * @pi_list_entry:	pi node to enqueue into the mutex owner waiters list
+ * @task:		task reference to the blocked task
+ */
+struct rt_mutex_waiter {
+	struct plist_node	list_entry;
+	struct plist_node	pi_list_entry;
+	struct task_struct	*task;
+	struct rt_mutex		*lock;
+#ifdef CONFIG_DEBUG_RT_MUTEXES
+	unsigned long		ip;
+	pid_t			deadlock_task_pid;
+	struct rt_mutex		*deadlock_lock;
+#endif
+};
+
+/*
+ * Various helpers to access the waiters-plist:
+ */
+static inline int rt_mutex_has_waiters(struct rt_mutex *lock)
+{
+	return !plist_head_empty(&lock->wait_list);
+}
+
+static inline struct rt_mutex_waiter *
+rt_mutex_top_waiter(struct rt_mutex *lock)
+{
+	struct rt_mutex_waiter *w;
+
+	w = plist_first_entry(&lock->wait_list, struct rt_mutex_waiter,
+			       list_entry);
+	BUG_ON(w->lock != lock);
+
+	return w;
+}
+
+static inline int task_has_pi_waiters(struct task_struct *p)
+{
+	return !plist_head_empty(&p->pi_waiters);
+}
+
+static inline struct rt_mutex_waiter *
+task_top_pi_waiter(struct task_struct *p)
+{
+	return plist_first_entry(&p->pi_waiters, struct rt_mutex_waiter,
+				  pi_list_entry);
+}
+
+/*
+ * lock->owner state tracking:
+ */
+#define RT_MUTEX_OWNER_PENDING	1UL
+#define RT_MUTEX_HAS_WAITERS	2UL
+#define RT_MUTEX_OWNER_MASKALL	3UL
+
+static inline struct task_struct *rt_mutex_owner(struct rt_mutex *lock)
+{
+	return (struct task_struct *)
+		((unsigned long)lock->owner & ~RT_MUTEX_OWNER_MASKALL);
+}
+
+static inline struct task_struct *rt_mutex_real_owner(struct rt_mutex *lock)
+{
+ 	return (struct task_struct *)
+		((unsigned long)lock->owner & ~RT_MUTEX_HAS_WAITERS);
+}
+
+static inline unsigned long rt_mutex_owner_pending(struct rt_mutex *lock)
+{
+	return (unsigned long)lock->owner & RT_MUTEX_OWNER_PENDING;
+}
+
+/*
+ * PI-futex support (proxy locking functions, etc.):
+ */
+extern struct task_struct *rt_mutex_next_owner(struct rt_mutex *lock);
+extern void rt_mutex_init_proxy_locked(struct rt_mutex *lock,
+				       struct task_struct *proxy_owner);
+extern void rt_mutex_proxy_unlock(struct rt_mutex *lock,
+				  struct task_struct *proxy_owner);
+#endif
diff --git a/kernel/rwsem.c b/kernel/rwsem.c
new file mode 100644
index 000000000..291ded556
--- /dev/null
+++ b/kernel/rwsem.c
@@ -0,0 +1,147 @@
+/* kernel/rwsem.c: R/W semaphores, public implementation
+ *
+ * Written by David Howells (dhowells@redhat.com).
+ * Derived from asm-i386/semaphore.h
+ */
+
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/rwsem.h>
+
+#include <asm/system.h>
+#include <asm/atomic.h>
+
+/*
+ * lock for reading
+ */
+void down_read(struct rw_semaphore *sem)
+{
+	might_sleep();
+	rwsem_acquire_read(&sem->dep_map, 0, 0, _RET_IP_);
+
+	__down_read(sem);
+}
+
+EXPORT_SYMBOL(down_read);
+
+/*
+ * trylock for reading -- returns 1 if successful, 0 if contention
+ */
+int down_read_trylock(struct rw_semaphore *sem)
+{
+	int ret = __down_read_trylock(sem);
+
+	if (ret == 1)
+		rwsem_acquire_read(&sem->dep_map, 0, 1, _RET_IP_);
+	return ret;
+}
+
+EXPORT_SYMBOL(down_read_trylock);
+
+/*
+ * lock for writing
+ */
+void down_write(struct rw_semaphore *sem)
+{
+	might_sleep();
+	rwsem_acquire(&sem->dep_map, 0, 0, _RET_IP_);
+
+	__down_write(sem);
+}
+
+EXPORT_SYMBOL(down_write);
+
+/*
+ * trylock for writing -- returns 1 if successful, 0 if contention
+ */
+int down_write_trylock(struct rw_semaphore *sem)
+{
+	int ret = __down_write_trylock(sem);
+
+	if (ret == 1)
+		rwsem_acquire(&sem->dep_map, 0, 0, _RET_IP_);
+	return ret;
+}
+
+EXPORT_SYMBOL(down_write_trylock);
+
+/*
+ * release a read lock
+ */
+void up_read(struct rw_semaphore *sem)
+{
+	rwsem_release(&sem->dep_map, 1, _RET_IP_);
+
+	__up_read(sem);
+}
+
+EXPORT_SYMBOL(up_read);
+
+/*
+ * release a write lock
+ */
+void up_write(struct rw_semaphore *sem)
+{
+	rwsem_release(&sem->dep_map, 1, _RET_IP_);
+
+	__up_write(sem);
+}
+
+EXPORT_SYMBOL(up_write);
+
+/*
+ * downgrade write lock to read lock
+ */
+void downgrade_write(struct rw_semaphore *sem)
+{
+	/*
+	 * lockdep: a downgraded write will live on as a write
+	 * dependency.
+	 */
+	__downgrade_write(sem);
+}
+
+EXPORT_SYMBOL(downgrade_write);
+
+#ifdef CONFIG_DEBUG_LOCK_ALLOC
+
+void down_read_nested(struct rw_semaphore *sem, int subclass)
+{
+	might_sleep();
+	rwsem_acquire_read(&sem->dep_map, subclass, 0, _RET_IP_);
+
+	__down_read(sem);
+}
+
+EXPORT_SYMBOL(down_read_nested);
+
+void down_read_non_owner(struct rw_semaphore *sem)
+{
+	might_sleep();
+
+	__down_read(sem);
+}
+
+EXPORT_SYMBOL(down_read_non_owner);
+
+void down_write_nested(struct rw_semaphore *sem, int subclass)
+{
+	might_sleep();
+	rwsem_acquire(&sem->dep_map, subclass, 0, _RET_IP_);
+
+	__down_write_nested(sem, subclass);
+}
+
+EXPORT_SYMBOL(down_write_nested);
+
+void up_read_non_owner(struct rw_semaphore *sem)
+{
+	__up_read(sem);
+}
+
+EXPORT_SYMBOL(up_read_non_owner);
+
+#endif
+
+
diff --git a/kernel/stacktrace.c b/kernel/stacktrace.c
new file mode 100644
index 000000000..b71816e47
--- /dev/null
+++ b/kernel/stacktrace.c
@@ -0,0 +1,24 @@
+/*
+ * kernel/stacktrace.c
+ *
+ * Stack trace management functions
+ *
+ *  Copyright (C) 2006 Red Hat, Inc., Ingo Molnar <mingo@redhat.com>
+ */
+#include <linux/sched.h>
+#include <linux/kallsyms.h>
+#include <linux/stacktrace.h>
+
+void print_stack_trace(struct stack_trace *trace, int spaces)
+{
+	int i, j;
+
+	for (i = 0; i < trace->nr_entries; i++) {
+		unsigned long ip = trace->entries[i];
+
+		for (j = 0; j < spaces + 1; j++)
+			printk(" ");
+		print_ip_sym(ip);
+	}
+}
+
diff --git a/kernel/taskstats.c b/kernel/taskstats.c
new file mode 100644
index 000000000..b90b2a7ef
--- /dev/null
+++ b/kernel/taskstats.c
@@ -0,0 +1,567 @@
+/*
+ * taskstats.c - Export per-task statistics to userland
+ *
+ * Copyright (C) Shailabh Nagar, IBM Corp. 2006
+ *           (C) Balbir Singh,   IBM Corp. 2006
+ *
+ * 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.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/taskstats_kern.h>
+#include <linux/delayacct.h>
+#include <linux/cpumask.h>
+#include <linux/percpu.h>
+#include <net/genetlink.h>
+#include <asm/atomic.h>
+
+/*
+ * Maximum length of a cpumask that can be specified in
+ * the TASKSTATS_CMD_ATTR_REGISTER/DEREGISTER_CPUMASK attribute
+ */
+#define TASKSTATS_CPUMASK_MAXLEN	(100+6*NR_CPUS)
+
+static DEFINE_PER_CPU(__u32, taskstats_seqnum) = { 0 };
+static int family_registered;
+kmem_cache_t *taskstats_cache;
+
+static struct genl_family family = {
+	.id		= GENL_ID_GENERATE,
+	.name		= TASKSTATS_GENL_NAME,
+	.version	= TASKSTATS_GENL_VERSION,
+	.maxattr	= TASKSTATS_CMD_ATTR_MAX,
+};
+
+static struct nla_policy taskstats_cmd_get_policy[TASKSTATS_CMD_ATTR_MAX+1]
+__read_mostly = {
+	[TASKSTATS_CMD_ATTR_PID]  = { .type = NLA_U32 },
+	[TASKSTATS_CMD_ATTR_TGID] = { .type = NLA_U32 },
+	[TASKSTATS_CMD_ATTR_REGISTER_CPUMASK] = { .type = NLA_STRING },
+	[TASKSTATS_CMD_ATTR_DEREGISTER_CPUMASK] = { .type = NLA_STRING },};
+
+struct listener {
+	struct list_head list;
+	pid_t pid;
+	char valid;
+};
+
+struct listener_list {
+	struct rw_semaphore sem;
+	struct list_head list;
+};
+static DEFINE_PER_CPU(struct listener_list, listener_array);
+
+enum actions {
+	REGISTER,
+	DEREGISTER,
+	CPU_DONT_CARE
+};
+
+static int prepare_reply(struct genl_info *info, u8 cmd, struct sk_buff **skbp,
+			void **replyp, size_t size)
+{
+	struct sk_buff *skb;
+	void *reply;
+
+	/*
+	 * If new attributes are added, please revisit this allocation
+	 */
+	skb = nlmsg_new(size);
+	if (!skb)
+		return -ENOMEM;
+
+	if (!info) {
+		int seq = get_cpu_var(taskstats_seqnum)++;
+		put_cpu_var(taskstats_seqnum);
+
+		reply = genlmsg_put(skb, 0, seq,
+				family.id, 0, 0,
+				cmd, family.version);
+	} else
+		reply = genlmsg_put(skb, info->snd_pid, info->snd_seq,
+				family.id, 0, 0,
+				cmd, family.version);
+	if (reply == NULL) {
+		nlmsg_free(skb);
+		return -EINVAL;
+	}
+
+	*skbp = skb;
+	*replyp = reply;
+	return 0;
+}
+
+/*
+ * Send taskstats data in @skb to listener with nl_pid @pid
+ */
+static int send_reply(struct sk_buff *skb, pid_t pid)
+{
+	struct genlmsghdr *genlhdr = nlmsg_data((struct nlmsghdr *)skb->data);
+	void *reply = genlmsg_data(genlhdr);
+	int rc;
+
+	rc = genlmsg_end(skb, reply);
+	if (rc < 0) {
+		nlmsg_free(skb);
+		return rc;
+	}
+
+	return genlmsg_unicast(skb, pid);
+}
+
+/*
+ * Send taskstats data in @skb to listeners registered for @cpu's exit data
+ */
+static void send_cpu_listeners(struct sk_buff *skb, unsigned int cpu)
+{
+	struct genlmsghdr *genlhdr = nlmsg_data((struct nlmsghdr *)skb->data);
+	struct listener_list *listeners;
+	struct listener *s, *tmp;
+	struct sk_buff *skb_next, *skb_cur = skb;
+	void *reply = genlmsg_data(genlhdr);
+	int rc, delcount = 0;
+
+	rc = genlmsg_end(skb, reply);
+	if (rc < 0) {
+		nlmsg_free(skb);
+		return;
+	}
+
+	rc = 0;
+	listeners = &per_cpu(listener_array, cpu);
+	down_read(&listeners->sem);
+	list_for_each_entry(s, &listeners->list, list) {
+		skb_next = NULL;
+		if (!list_is_last(&s->list, &listeners->list)) {
+			skb_next = skb_clone(skb_cur, GFP_KERNEL);
+			if (!skb_next)
+				break;
+		}
+		rc = genlmsg_unicast(skb_cur, s->pid);
+		if (rc == -ECONNREFUSED) {
+			s->valid = 0;
+			delcount++;
+		}
+		skb_cur = skb_next;
+	}
+	up_read(&listeners->sem);
+
+	if (skb_cur)
+		nlmsg_free(skb_cur);
+
+	if (!delcount)
+		return;
+
+	/* Delete invalidated entries */
+	down_write(&listeners->sem);
+	list_for_each_entry_safe(s, tmp, &listeners->list, list) {
+		if (!s->valid) {
+			list_del(&s->list);
+			kfree(s);
+		}
+	}
+	up_write(&listeners->sem);
+}
+
+static int fill_pid(pid_t pid, struct task_struct *pidtsk,
+		struct taskstats *stats)
+{
+	int rc = 0;
+	struct task_struct *tsk = pidtsk;
+
+	if (!pidtsk) {
+		read_lock(&tasklist_lock);
+		tsk = find_task_by_pid(pid);
+		if (!tsk) {
+			read_unlock(&tasklist_lock);
+			return -ESRCH;
+		}
+		get_task_struct(tsk);
+		read_unlock(&tasklist_lock);
+	} else
+		get_task_struct(tsk);
+
+	/*
+	 * Each accounting subsystem adds calls to its functions to
+	 * fill in relevant parts of struct taskstsats as follows
+	 *
+	 *	per-task-foo(stats, tsk);
+	 */
+
+	delayacct_add_tsk(stats, tsk);
+	stats->version = TASKSTATS_VERSION;
+
+	/* Define err: label here if needed */
+	put_task_struct(tsk);
+	return rc;
+
+}
+
+static int fill_tgid(pid_t tgid, struct task_struct *tgidtsk,
+		struct taskstats *stats)
+{
+	struct task_struct *tsk, *first;
+	unsigned long flags;
+
+	/*
+	 * Add additional stats from live tasks except zombie thread group
+	 * leaders who are already counted with the dead tasks
+	 */
+	first = tgidtsk;
+	if (!first) {
+		read_lock(&tasklist_lock);
+		first = find_task_by_pid(tgid);
+		if (!first) {
+			read_unlock(&tasklist_lock);
+			return -ESRCH;
+		}
+		get_task_struct(first);
+		read_unlock(&tasklist_lock);
+	} else
+		get_task_struct(first);
+
+
+	tsk = first;
+	read_lock(&tasklist_lock);
+	/* Start with stats from dead tasks */
+	if (first->signal) {
+		spin_lock_irqsave(&first->signal->stats_lock, flags);
+		if (first->signal->stats)
+			memcpy(stats, first->signal->stats, sizeof(*stats));
+		spin_unlock_irqrestore(&first->signal->stats_lock, flags);
+	}
+
+	do {
+		if (tsk->exit_state == EXIT_ZOMBIE && thread_group_leader(tsk))
+			continue;
+		/*
+		 * Accounting subsystem can call its functions here to
+		 * fill in relevant parts of struct taskstsats as follows
+		 *
+		 *	per-task-foo(stats, tsk);
+		 */
+		delayacct_add_tsk(stats, tsk);
+
+	} while_each_thread(first, tsk);
+	read_unlock(&tasklist_lock);
+	stats->version = TASKSTATS_VERSION;
+
+	/*
+	 * Accounting subsytems can also add calls here to modify
+	 * fields of taskstats.
+	 */
+	put_task_struct(first);
+	return 0;
+}
+
+
+static void fill_tgid_exit(struct task_struct *tsk)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&tsk->signal->stats_lock, flags);
+	if (!tsk->signal->stats)
+		goto ret;
+
+	/*
+	 * Each accounting subsystem calls its functions here to
+	 * accumalate its per-task stats for tsk, into the per-tgid structure
+	 *
+	 *	per-task-foo(tsk->signal->stats, tsk);
+	 */
+	delayacct_add_tsk(tsk->signal->stats, tsk);
+ret:
+	spin_unlock_irqrestore(&tsk->signal->stats_lock, flags);
+	return;
+}
+
+static int add_del_listener(pid_t pid, cpumask_t *maskp, int isadd)
+{
+	struct listener_list *listeners;
+	struct listener *s, *tmp;
+	unsigned int cpu;
+	cpumask_t mask = *maskp;
+
+	if (!cpus_subset(mask, cpu_possible_map))
+		return -EINVAL;
+
+	if (isadd == REGISTER) {
+		for_each_cpu_mask(cpu, mask) {
+			s = kmalloc_node(sizeof(struct listener), GFP_KERNEL,
+					 cpu_to_node(cpu));
+			if (!s)
+				goto cleanup;
+			s->pid = pid;
+			INIT_LIST_HEAD(&s->list);
+			s->valid = 1;
+
+			listeners = &per_cpu(listener_array, cpu);
+			down_write(&listeners->sem);
+			list_add(&s->list, &listeners->list);
+			up_write(&listeners->sem);
+		}
+		return 0;
+	}
+
+	/* Deregister or cleanup */
+cleanup:
+	for_each_cpu_mask(cpu, mask) {
+		listeners = &per_cpu(listener_array, cpu);
+		down_write(&listeners->sem);
+		list_for_each_entry_safe(s, tmp, &listeners->list, list) {
+			if (s->pid == pid) {
+				list_del(&s->list);
+				kfree(s);
+				break;
+			}
+		}
+		up_write(&listeners->sem);
+	}
+	return 0;
+}
+
+static int parse(struct nlattr *na, cpumask_t *mask)
+{
+	char *data;
+	int len;
+	int ret;
+
+	if (na == NULL)
+		return 1;
+	len = nla_len(na);
+	if (len > TASKSTATS_CPUMASK_MAXLEN)
+		return -E2BIG;
+	if (len < 1)
+		return -EINVAL;
+	data = kmalloc(len, GFP_KERNEL);
+	if (!data)
+		return -ENOMEM;
+	nla_strlcpy(data, na, len);
+	ret = cpulist_parse(data, *mask);
+	kfree(data);
+	return ret;
+}
+
+static int taskstats_user_cmd(struct sk_buff *skb, struct genl_info *info)
+{
+	int rc = 0;
+	struct sk_buff *rep_skb;
+	struct taskstats stats;
+	void *reply;
+	size_t size;
+	struct nlattr *na;
+	cpumask_t mask;
+
+	rc = parse(info->attrs[TASKSTATS_CMD_ATTR_REGISTER_CPUMASK], &mask);
+	if (rc < 0)
+		return rc;
+	if (rc == 0)
+		return add_del_listener(info->snd_pid, &mask, REGISTER);
+
+	rc = parse(info->attrs[TASKSTATS_CMD_ATTR_DEREGISTER_CPUMASK], &mask);
+	if (rc < 0)
+		return rc;
+	if (rc == 0)
+		return add_del_listener(info->snd_pid, &mask, DEREGISTER);
+
+	/*
+	 * Size includes space for nested attributes
+	 */
+	size = nla_total_size(sizeof(u32)) +
+		nla_total_size(sizeof(struct taskstats)) + nla_total_size(0);
+
+	memset(&stats, 0, sizeof(stats));
+	rc = prepare_reply(info, TASKSTATS_CMD_NEW, &rep_skb, &reply, size);
+	if (rc < 0)
+		return rc;
+
+	if (info->attrs[TASKSTATS_CMD_ATTR_PID]) {
+		u32 pid = nla_get_u32(info->attrs[TASKSTATS_CMD_ATTR_PID]);
+		rc = fill_pid(pid, NULL, &stats);
+		if (rc < 0)
+			goto err;
+
+		na = nla_nest_start(rep_skb, TASKSTATS_TYPE_AGGR_PID);
+		NLA_PUT_U32(rep_skb, TASKSTATS_TYPE_PID, pid);
+		NLA_PUT_TYPE(rep_skb, struct taskstats, TASKSTATS_TYPE_STATS,
+				stats);
+	} else if (info->attrs[TASKSTATS_CMD_ATTR_TGID]) {
+		u32 tgid = nla_get_u32(info->attrs[TASKSTATS_CMD_ATTR_TGID]);
+		rc = fill_tgid(tgid, NULL, &stats);
+		if (rc < 0)
+			goto err;
+
+		na = nla_nest_start(rep_skb, TASKSTATS_TYPE_AGGR_TGID);
+		NLA_PUT_U32(rep_skb, TASKSTATS_TYPE_TGID, tgid);
+		NLA_PUT_TYPE(rep_skb, struct taskstats, TASKSTATS_TYPE_STATS,
+				stats);
+	} else {
+		rc = -EINVAL;
+		goto err;
+	}
+
+	nla_nest_end(rep_skb, na);
+
+	return send_reply(rep_skb, info->snd_pid);
+
+nla_put_failure:
+	return genlmsg_cancel(rep_skb, reply);
+err:
+	nlmsg_free(rep_skb);
+	return rc;
+}
+
+void taskstats_exit_alloc(struct taskstats **ptidstats, unsigned int *mycpu)
+{
+	struct listener_list *listeners;
+	struct taskstats *tmp;
+	/*
+	 * This is the cpu on which the task is exiting currently and will
+	 * be the one for which the exit event is sent, even if the cpu
+	 * on which this function is running changes later.
+	 */
+	*mycpu = raw_smp_processor_id();
+
+	*ptidstats = NULL;
+	tmp = kmem_cache_zalloc(taskstats_cache, SLAB_KERNEL);
+	if (!tmp)
+		return;
+
+	listeners = &per_cpu(listener_array, *mycpu);
+	down_read(&listeners->sem);
+	if (!list_empty(&listeners->list)) {
+		*ptidstats = tmp;
+		tmp = NULL;
+	}
+	up_read(&listeners->sem);
+	kfree(tmp);
+}
+
+/* Send pid data out on exit */
+void taskstats_exit_send(struct task_struct *tsk, struct taskstats *tidstats,
+			int group_dead, unsigned int mycpu)
+{
+	int rc;
+	struct sk_buff *rep_skb;
+	void *reply;
+	size_t size;
+	int is_thread_group;
+	struct nlattr *na;
+	unsigned long flags;
+
+	if (!family_registered || !tidstats)
+		return;
+
+	spin_lock_irqsave(&tsk->signal->stats_lock, flags);
+	is_thread_group = tsk->signal->stats ? 1 : 0;
+	spin_unlock_irqrestore(&tsk->signal->stats_lock, flags);
+
+	rc = 0;
+	/*
+	 * Size includes space for nested attributes
+	 */
+	size = nla_total_size(sizeof(u32)) +
+		nla_total_size(sizeof(struct taskstats)) + nla_total_size(0);
+
+	if (is_thread_group)
+		size = 2 * size;	/* PID + STATS + TGID + STATS */
+
+	rc = prepare_reply(NULL, TASKSTATS_CMD_NEW, &rep_skb, &reply, size);
+	if (rc < 0)
+		goto ret;
+
+	rc = fill_pid(tsk->pid, tsk, tidstats);
+	if (rc < 0)
+		goto err_skb;
+
+	na = nla_nest_start(rep_skb, TASKSTATS_TYPE_AGGR_PID);
+	NLA_PUT_U32(rep_skb, TASKSTATS_TYPE_PID, (u32)tsk->pid);
+	NLA_PUT_TYPE(rep_skb, struct taskstats, TASKSTATS_TYPE_STATS,
+			*tidstats);
+	nla_nest_end(rep_skb, na);
+
+	if (!is_thread_group)
+		goto send;
+
+	/*
+	 * tsk has/had a thread group so fill the tsk->signal->stats structure
+	 * Doesn't matter if tsk is the leader or the last group member leaving
+	 */
+
+	fill_tgid_exit(tsk);
+	if (!group_dead)
+		goto send;
+
+	na = nla_nest_start(rep_skb, TASKSTATS_TYPE_AGGR_TGID);
+	NLA_PUT_U32(rep_skb, TASKSTATS_TYPE_TGID, (u32)tsk->tgid);
+	/* No locking needed for tsk->signal->stats since group is dead */
+	NLA_PUT_TYPE(rep_skb, struct taskstats, TASKSTATS_TYPE_STATS,
+			*tsk->signal->stats);
+	nla_nest_end(rep_skb, na);
+
+send:
+	send_cpu_listeners(rep_skb, mycpu);
+	return;
+
+nla_put_failure:
+	genlmsg_cancel(rep_skb, reply);
+	goto ret;
+err_skb:
+	nlmsg_free(rep_skb);
+ret:
+	return;
+}
+
+static struct genl_ops taskstats_ops = {
+	.cmd		= TASKSTATS_CMD_GET,
+	.doit		= taskstats_user_cmd,
+	.policy		= taskstats_cmd_get_policy,
+};
+
+/* Needed early in initialization */
+void __init taskstats_init_early(void)
+{
+	unsigned int i;
+
+	taskstats_cache = kmem_cache_create("taskstats_cache",
+						sizeof(struct taskstats),
+						0, SLAB_PANIC, NULL, NULL);
+	for_each_possible_cpu(i) {
+		INIT_LIST_HEAD(&(per_cpu(listener_array, i).list));
+		init_rwsem(&(per_cpu(listener_array, i).sem));
+	}
+}
+
+static int __init taskstats_init(void)
+{
+	int rc;
+
+	rc = genl_register_family(&family);
+	if (rc)
+		return rc;
+
+	rc = genl_register_ops(&family, &taskstats_ops);
+	if (rc < 0)
+		goto err;
+
+	family_registered = 1;
+	return 0;
+err:
+	genl_unregister_family(&family);
+	return rc;
+}
+
+/*
+ * late initcall ensures initialization of statistics collection
+ * mechanisms precedes initialization of the taskstats interface
+ */
+late_initcall(taskstats_init);
diff --git a/kernel/time/Makefile b/kernel/time/Makefile
new file mode 100644
index 000000000..e1dfd8e86
--- /dev/null
+++ b/kernel/time/Makefile
@@ -0,0 +1 @@
+obj-y += clocksource.o jiffies.o
diff --git a/kernel/time/clocksource.c b/kernel/time/clocksource.c
new file mode 100644
index 000000000..74eca5939
--- /dev/null
+++ b/kernel/time/clocksource.c
@@ -0,0 +1,349 @@
+/*
+ * linux/kernel/time/clocksource.c
+ *
+ * This file contains the functions which manage clocksource drivers.
+ *
+ * Copyright (C) 2004, 2005 IBM, John Stultz (johnstul@us.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 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.
+ *
+ * TODO WishList:
+ *   o Allow clocksource drivers to be unregistered
+ *   o get rid of clocksource_jiffies extern
+ */
+
+#include <linux/clocksource.h>
+#include <linux/sysdev.h>
+#include <linux/init.h>
+#include <linux/module.h>
+
+/* XXX - Would like a better way for initializing curr_clocksource */
+extern struct clocksource clocksource_jiffies;
+
+/*[Clocksource internal variables]---------
+ * curr_clocksource:
+ *	currently selected clocksource. Initialized to clocksource_jiffies.
+ * next_clocksource:
+ *	pending next selected clocksource.
+ * clocksource_list:
+ *	linked list with the registered clocksources
+ * clocksource_lock:
+ *	protects manipulations to curr_clocksource and next_clocksource
+ *	and the clocksource_list
+ * override_name:
+ *	Name of the user-specified clocksource.
+ */
+static struct clocksource *curr_clocksource = &clocksource_jiffies;
+static struct clocksource *next_clocksource;
+static LIST_HEAD(clocksource_list);
+static DEFINE_SPINLOCK(clocksource_lock);
+static char override_name[32];
+static int finished_booting;
+
+/* clocksource_done_booting - Called near the end of bootup
+ *
+ * Hack to avoid lots of clocksource churn at boot time
+ */
+static int __init clocksource_done_booting(void)
+{
+	finished_booting = 1;
+	return 0;
+}
+
+late_initcall(clocksource_done_booting);
+
+/**
+ * clocksource_get_next - Returns the selected clocksource
+ *
+ */
+struct clocksource *clocksource_get_next(void)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&clocksource_lock, flags);
+	if (next_clocksource && finished_booting) {
+		curr_clocksource = next_clocksource;
+		next_clocksource = NULL;
+	}
+	spin_unlock_irqrestore(&clocksource_lock, flags);
+
+	return curr_clocksource;
+}
+
+/**
+ * select_clocksource - Finds the best registered clocksource.
+ *
+ * Private function. Must hold clocksource_lock when called.
+ *
+ * Looks through the list of registered clocksources, returning
+ * the one with the highest rating value. If there is a clocksource
+ * name that matches the override string, it returns that clocksource.
+ */
+static struct clocksource *select_clocksource(void)
+{
+	struct clocksource *best = NULL;
+	struct list_head *tmp;
+
+	list_for_each(tmp, &clocksource_list) {
+		struct clocksource *src;
+
+		src = list_entry(tmp, struct clocksource, list);
+		if (!best)
+			best = src;
+
+		/* check for override: */
+		if (strlen(src->name) == strlen(override_name) &&
+		    !strcmp(src->name, override_name)) {
+			best = src;
+			break;
+		}
+		/* pick the highest rating: */
+		if (src->rating > best->rating)
+		 	best = src;
+	}
+
+	return best;
+}
+
+/**
+ * is_registered_source - Checks if clocksource is registered
+ * @c:		pointer to a clocksource
+ *
+ * Private helper function. Must hold clocksource_lock when called.
+ *
+ * Returns one if the clocksource is already registered, zero otherwise.
+ */
+static int is_registered_source(struct clocksource *c)
+{
+	int len = strlen(c->name);
+	struct list_head *tmp;
+
+	list_for_each(tmp, &clocksource_list) {
+		struct clocksource *src;
+
+		src = list_entry(tmp, struct clocksource, list);
+		if (strlen(src->name) == len &&	!strcmp(src->name, c->name))
+			return 1;
+	}
+
+	return 0;
+}
+
+/**
+ * clocksource_register - Used to install new clocksources
+ * @t:		clocksource to be registered
+ *
+ * Returns -EBUSY if registration fails, zero otherwise.
+ */
+int clocksource_register(struct clocksource *c)
+{
+	int ret = 0;
+	unsigned long flags;
+
+	spin_lock_irqsave(&clocksource_lock, flags);
+	/* check if clocksource is already registered */
+	if (is_registered_source(c)) {
+		printk("register_clocksource: Cannot register %s. "
+			"Already registered!", c->name);
+		ret = -EBUSY;
+	} else {
+		/* register it */
+ 		list_add(&c->list, &clocksource_list);
+		/* scan the registered clocksources, and pick the best one */
+		next_clocksource = select_clocksource();
+	}
+	spin_unlock_irqrestore(&clocksource_lock, flags);
+	return ret;
+}
+EXPORT_SYMBOL(clocksource_register);
+
+/**
+ * clocksource_reselect - Rescan list for next clocksource
+ *
+ * A quick helper function to be used if a clocksource changes its
+ * rating. Forces the clocksource list to be re-scanned for the best
+ * clocksource.
+ */
+void clocksource_reselect(void)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&clocksource_lock, flags);
+	next_clocksource = select_clocksource();
+	spin_unlock_irqrestore(&clocksource_lock, flags);
+}
+EXPORT_SYMBOL(clocksource_reselect);
+
+/**
+ * sysfs_show_current_clocksources - sysfs interface for current clocksource
+ * @dev:	unused
+ * @buf:	char buffer to be filled with clocksource list
+ *
+ * Provides sysfs interface for listing current clocksource.
+ */
+static ssize_t
+sysfs_show_current_clocksources(struct sys_device *dev, char *buf)
+{
+	char *curr = buf;
+
+	spin_lock_irq(&clocksource_lock);
+	curr += sprintf(curr, "%s ", curr_clocksource->name);
+	spin_unlock_irq(&clocksource_lock);
+
+	curr += sprintf(curr, "\n");
+
+	return curr - buf;
+}
+
+/**
+ * sysfs_override_clocksource - interface for manually overriding clocksource
+ * @dev:	unused
+ * @buf:	name of override clocksource
+ * @count:	length of buffer
+ *
+ * Takes input from sysfs interface for manually overriding the default
+ * clocksource selction.
+ */
+static ssize_t sysfs_override_clocksource(struct sys_device *dev,
+					  const char *buf, size_t count)
+{
+	size_t ret = count;
+	/* strings from sysfs write are not 0 terminated! */
+	if (count >= sizeof(override_name))
+		return -EINVAL;
+
+	/* strip of \n: */
+	if (buf[count-1] == '\n')
+		count--;
+	if (count < 1)
+		return -EINVAL;
+
+	spin_lock_irq(&clocksource_lock);
+
+	/* copy the name given: */
+	memcpy(override_name, buf, count);
+	override_name[count] = 0;
+
+	/* try to select it: */
+	next_clocksource = select_clocksource();
+
+	spin_unlock_irq(&clocksource_lock);
+
+	return ret;
+}
+
+/**
+ * sysfs_show_available_clocksources - sysfs interface for listing clocksource
+ * @dev:	unused
+ * @buf:	char buffer to be filled with clocksource list
+ *
+ * Provides sysfs interface for listing registered clocksources
+ */
+static ssize_t
+sysfs_show_available_clocksources(struct sys_device *dev, char *buf)
+{
+	struct list_head *tmp;
+	char *curr = buf;
+
+	spin_lock_irq(&clocksource_lock);
+	list_for_each(tmp, &clocksource_list) {
+		struct clocksource *src;
+
+		src = list_entry(tmp, struct clocksource, list);
+		curr += sprintf(curr, "%s ", src->name);
+	}
+	spin_unlock_irq(&clocksource_lock);
+
+	curr += sprintf(curr, "\n");
+
+	return curr - buf;
+}
+
+/*
+ * Sysfs setup bits:
+ */
+static SYSDEV_ATTR(current_clocksource, 0600, sysfs_show_current_clocksources,
+			sysfs_override_clocksource);
+
+static SYSDEV_ATTR(available_clocksource, 0600,
+			sysfs_show_available_clocksources, NULL);
+
+static struct sysdev_class clocksource_sysclass = {
+	set_kset_name("clocksource"),
+};
+
+static struct sys_device device_clocksource = {
+	.id	= 0,
+	.cls	= &clocksource_sysclass,
+};
+
+static int __init init_clocksource_sysfs(void)
+{
+	int error = sysdev_class_register(&clocksource_sysclass);
+
+	if (!error)
+		error = sysdev_register(&device_clocksource);
+	if (!error)
+		error = sysdev_create_file(
+				&device_clocksource,
+				&attr_current_clocksource);
+	if (!error)
+		error = sysdev_create_file(
+				&device_clocksource,
+				&attr_available_clocksource);
+	return error;
+}
+
+device_initcall(init_clocksource_sysfs);
+
+/**
+ * boot_override_clocksource - boot clock override
+ * @str:	override name
+ *
+ * Takes a clocksource= boot argument and uses it
+ * as the clocksource override name.
+ */
+static int __init boot_override_clocksource(char* str)
+{
+	unsigned long flags;
+	spin_lock_irqsave(&clocksource_lock, flags);
+	if (str)
+		strlcpy(override_name, str, sizeof(override_name));
+	spin_unlock_irqrestore(&clocksource_lock, flags);
+	return 1;
+}
+
+__setup("clocksource=", boot_override_clocksource);
+
+/**
+ * boot_override_clock - Compatibility layer for deprecated boot option
+ * @str:	override name
+ *
+ * DEPRECATED! Takes a clock= boot argument and uses it
+ * as the clocksource override name
+ */
+static int __init boot_override_clock(char* str)
+{
+	if (!strcmp(str, "pmtmr")) {
+		printk("Warning: clock=pmtmr is deprecated. "
+			"Use clocksource=acpi_pm.\n");
+		return boot_override_clocksource("acpi_pm");
+	}
+	printk("Warning! clock= boot option is deprecated. "
+		"Use clocksource=xyz\n");
+	return boot_override_clocksource(str);
+}
+
+__setup("clock=", boot_override_clock);
diff --git a/kernel/time/jiffies.c b/kernel/time/jiffies.c
new file mode 100644
index 000000000..126bb30c4
--- /dev/null
+++ b/kernel/time/jiffies.c
@@ -0,0 +1,73 @@
+/***********************************************************************
+* linux/kernel/time/jiffies.c
+*
+* This file contains the jiffies based clocksource.
+*
+* Copyright (C) 2004, 2005 IBM, John Stultz (johnstul@us.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 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/clocksource.h>
+#include <linux/jiffies.h>
+#include <linux/init.h>
+
+/* The Jiffies based clocksource is the lowest common
+ * denominator clock source which should function on
+ * all systems. It has the same coarse resolution as
+ * the timer interrupt frequency HZ and it suffers
+ * inaccuracies caused by missed or lost timer
+ * interrupts and the inability for the timer
+ * interrupt hardware to accuratly tick at the
+ * requested HZ value. It is also not reccomended
+ * for "tick-less" systems.
+ */
+#define NSEC_PER_JIFFY	((u32)((((u64)NSEC_PER_SEC)<<8)/ACTHZ))
+
+/* Since jiffies uses a simple NSEC_PER_JIFFY multiplier
+ * conversion, the .shift value could be zero. However
+ * this would make NTP adjustments impossible as they are
+ * in units of 1/2^.shift. Thus we use JIFFIES_SHIFT to
+ * shift both the nominator and denominator the same
+ * amount, and give ntp adjustments in units of 1/2^8
+ *
+ * The value 8 is somewhat carefully chosen, as anything
+ * larger can result in overflows. NSEC_PER_JIFFY grows as
+ * HZ shrinks, so values greater then 8 overflow 32bits when
+ * HZ=100.
+ */
+#define JIFFIES_SHIFT	8
+
+static cycle_t jiffies_read(void)
+{
+	return (cycle_t) jiffies;
+}
+
+struct clocksource clocksource_jiffies = {
+	.name		= "jiffies",
+	.rating		= 0, /* lowest rating*/
+	.read		= jiffies_read,
+	.mask		= 0xffffffff, /*32bits*/
+	.mult		= NSEC_PER_JIFFY << JIFFIES_SHIFT, /* details above */
+	.shift		= JIFFIES_SHIFT,
+	.is_continuous	= 0, /* tick based, not free running */
+};
+
+static int __init init_jiffies_clocksource(void)
+{
+	return clocksource_register(&clocksource_jiffies);
+}
+
+module_init(init_jiffies_clocksource);
diff --git a/kernel/unwind.c b/kernel/unwind.c
new file mode 100644
index 000000000..47281af3f
--- /dev/null
+++ b/kernel/unwind.c
@@ -0,0 +1,920 @@
+/*
+ * Copyright (C) 2002-2006 Novell, Inc.
+ *	Jan Beulich <jbeulich@novell.com>
+ * This code is released under version 2 of the GNU GPL.
+ *
+ * A simple API for unwinding kernel stacks.  This is used for
+ * debugging and error reporting purposes.  The kernel doesn't need
+ * full-blown stack unwinding with all the bells and whistles, so there
+ * is not much point in implementing the full Dwarf2 unwind API.
+ */
+
+#include <linux/unwind.h>
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/stop_machine.h>
+#include <asm/sections.h>
+#include <asm/uaccess.h>
+#include <asm/unaligned.h>
+
+extern char __start_unwind[], __end_unwind[];
+
+#define MAX_STACK_DEPTH 8
+
+#define EXTRA_INFO(f) { \
+		BUILD_BUG_ON_ZERO(offsetof(struct unwind_frame_info, f) \
+		                  % FIELD_SIZEOF(struct unwind_frame_info, f)) \
+		+ offsetof(struct unwind_frame_info, f) \
+		  / FIELD_SIZEOF(struct unwind_frame_info, f), \
+		FIELD_SIZEOF(struct unwind_frame_info, f) \
+	}
+#define PTREGS_INFO(f) EXTRA_INFO(regs.f)
+
+static const struct {
+	unsigned offs:BITS_PER_LONG / 2;
+	unsigned width:BITS_PER_LONG / 2;
+} reg_info[] = {
+	UNW_REGISTER_INFO
+};
+
+#undef PTREGS_INFO
+#undef EXTRA_INFO
+
+#ifndef REG_INVALID
+#define REG_INVALID(r) (reg_info[r].width == 0)
+#endif
+
+#define DW_CFA_nop                          0x00
+#define DW_CFA_set_loc                      0x01
+#define DW_CFA_advance_loc1                 0x02
+#define DW_CFA_advance_loc2                 0x03
+#define DW_CFA_advance_loc4                 0x04
+#define DW_CFA_offset_extended              0x05
+#define DW_CFA_restore_extended             0x06
+#define DW_CFA_undefined                    0x07
+#define DW_CFA_same_value                   0x08
+#define DW_CFA_register                     0x09
+#define DW_CFA_remember_state               0x0a
+#define DW_CFA_restore_state                0x0b
+#define DW_CFA_def_cfa                      0x0c
+#define DW_CFA_def_cfa_register             0x0d
+#define DW_CFA_def_cfa_offset               0x0e
+#define DW_CFA_def_cfa_expression           0x0f
+#define DW_CFA_expression                   0x10
+#define DW_CFA_offset_extended_sf           0x11
+#define DW_CFA_def_cfa_sf                   0x12
+#define DW_CFA_def_cfa_offset_sf            0x13
+#define DW_CFA_val_offset                   0x14
+#define DW_CFA_val_offset_sf                0x15
+#define DW_CFA_val_expression               0x16
+#define DW_CFA_lo_user                      0x1c
+#define DW_CFA_GNU_window_save              0x2d
+#define DW_CFA_GNU_args_size                0x2e
+#define DW_CFA_GNU_negative_offset_extended 0x2f
+#define DW_CFA_hi_user                      0x3f
+
+#define DW_EH_PE_FORM     0x07
+#define DW_EH_PE_native   0x00
+#define DW_EH_PE_leb128   0x01
+#define DW_EH_PE_data2    0x02
+#define DW_EH_PE_data4    0x03
+#define DW_EH_PE_data8    0x04
+#define DW_EH_PE_signed   0x08
+#define DW_EH_PE_ADJUST   0x70
+#define DW_EH_PE_abs      0x00
+#define DW_EH_PE_pcrel    0x10
+#define DW_EH_PE_textrel  0x20
+#define DW_EH_PE_datarel  0x30
+#define DW_EH_PE_funcrel  0x40
+#define DW_EH_PE_aligned  0x50
+#define DW_EH_PE_indirect 0x80
+#define DW_EH_PE_omit     0xff
+
+typedef unsigned long uleb128_t;
+typedef   signed long sleb128_t;
+
+static struct unwind_table {
+	struct {
+		unsigned long pc;
+		unsigned long range;
+	} core, init;
+	const void *address;
+	unsigned long size;
+	struct unwind_table *link;
+	const char *name;
+} root_table;
+
+struct unwind_item {
+	enum item_location {
+		Nowhere,
+		Memory,
+		Register,
+		Value
+	} where;
+	uleb128_t value;
+};
+
+struct unwind_state {
+	uleb128_t loc, org;
+	const u8 *cieStart, *cieEnd;
+	uleb128_t codeAlign;
+	sleb128_t dataAlign;
+	struct cfa {
+		uleb128_t reg, offs;
+	} cfa;
+	struct unwind_item regs[ARRAY_SIZE(reg_info)];
+	unsigned stackDepth:8;
+	unsigned version:8;
+	const u8 *label;
+	const u8 *stack[MAX_STACK_DEPTH];
+};
+
+static const struct cfa badCFA = { ARRAY_SIZE(reg_info), 1 };
+
+static struct unwind_table *find_table(unsigned long pc)
+{
+	struct unwind_table *table;
+
+	for (table = &root_table; table; table = table->link)
+		if ((pc >= table->core.pc
+		     && pc < table->core.pc + table->core.range)
+		    || (pc >= table->init.pc
+		        && pc < table->init.pc + table->init.range))
+			break;
+
+	return table;
+}
+
+static void init_unwind_table(struct unwind_table *table,
+                              const char *name,
+                              const void *core_start,
+                              unsigned long core_size,
+                              const void *init_start,
+                              unsigned long init_size,
+                              const void *table_start,
+                              unsigned long table_size)
+{
+	table->core.pc = (unsigned long)core_start;
+	table->core.range = core_size;
+	table->init.pc = (unsigned long)init_start;
+	table->init.range = init_size;
+	table->address = table_start;
+	table->size = table_size;
+	table->link = NULL;
+	table->name = name;
+}
+
+void __init unwind_init(void)
+{
+	init_unwind_table(&root_table, "kernel",
+	                  _text, _end - _text,
+	                  NULL, 0,
+	                  __start_unwind, __end_unwind - __start_unwind);
+}
+
+#ifdef CONFIG_MODULES
+
+static struct unwind_table *last_table;
+
+/* Must be called with module_mutex held. */
+void *unwind_add_table(struct module *module,
+                       const void *table_start,
+                       unsigned long table_size)
+{
+	struct unwind_table *table;
+
+	if (table_size <= 0)
+		return NULL;
+
+	table = kmalloc(sizeof(*table), GFP_KERNEL);
+	if (!table)
+		return NULL;
+
+	init_unwind_table(table, module->name,
+	                  module->module_core, module->core_size,
+	                  module->module_init, module->init_size,
+	                  table_start, table_size);
+
+	if (last_table)
+		last_table->link = table;
+	else
+		root_table.link = table;
+	last_table = table;
+
+	return table;
+}
+
+struct unlink_table_info
+{
+	struct unwind_table *table;
+	int init_only;
+};
+
+static int unlink_table(void *arg)
+{
+	struct unlink_table_info *info = arg;
+	struct unwind_table *table = info->table, *prev;
+
+	for (prev = &root_table; prev->link && prev->link != table; prev = prev->link)
+		;
+
+	if (prev->link) {
+		if (info->init_only) {
+			table->init.pc = 0;
+			table->init.range = 0;
+			info->table = NULL;
+		} else {
+			prev->link = table->link;
+			if (!prev->link)
+				last_table = prev;
+		}
+	} else
+		info->table = NULL;
+
+	return 0;
+}
+
+/* Must be called with module_mutex held. */
+void unwind_remove_table(void *handle, int init_only)
+{
+	struct unwind_table *table = handle;
+	struct unlink_table_info info;
+
+	if (!table || table == &root_table)
+		return;
+
+	if (init_only && table == last_table) {
+		table->init.pc = 0;
+		table->init.range = 0;
+		return;
+	}
+
+	info.table = table;
+	info.init_only = init_only;
+	stop_machine_run(unlink_table, &info, NR_CPUS);
+
+	if (info.table)
+		kfree(table);
+}
+
+#endif /* CONFIG_MODULES */
+
+static uleb128_t get_uleb128(const u8 **pcur, const u8 *end)
+{
+	const u8 *cur = *pcur;
+	uleb128_t value;
+	unsigned shift;
+
+	for (shift = 0, value = 0; cur < end; shift += 7) {
+		if (shift + 7 > 8 * sizeof(value)
+		    && (*cur & 0x7fU) >= (1U << (8 * sizeof(value) - shift))) {
+			cur = end + 1;
+			break;
+		}
+		value |= (uleb128_t)(*cur & 0x7f) << shift;
+		if (!(*cur++ & 0x80))
+			break;
+	}
+	*pcur = cur;
+
+	return value;
+}
+
+static sleb128_t get_sleb128(const u8 **pcur, const u8 *end)
+{
+	const u8 *cur = *pcur;
+	sleb128_t value;
+	unsigned shift;
+
+	for (shift = 0, value = 0; cur < end; shift += 7) {
+		if (shift + 7 > 8 * sizeof(value)
+		    && (*cur & 0x7fU) >= (1U << (8 * sizeof(value) - shift))) {
+			cur = end + 1;
+			break;
+		}
+		value |= (sleb128_t)(*cur & 0x7f) << shift;
+		if (!(*cur & 0x80)) {
+			value |= -(*cur++ & 0x40) << shift;
+			break;
+		}
+	}
+	*pcur = cur;
+
+	return value;
+}
+
+static unsigned long read_pointer(const u8 **pLoc,
+                                  const void *end,
+                                  signed ptrType)
+{
+	unsigned long value = 0;
+	union {
+		const u8 *p8;
+		const u16 *p16u;
+		const s16 *p16s;
+		const u32 *p32u;
+		const s32 *p32s;
+		const unsigned long *pul;
+	} ptr;
+
+	if (ptrType < 0 || ptrType == DW_EH_PE_omit)
+		return 0;
+	ptr.p8 = *pLoc;
+	switch(ptrType & DW_EH_PE_FORM) {
+	case DW_EH_PE_data2:
+		if (end < (const void *)(ptr.p16u + 1))
+			return 0;
+		if(ptrType & DW_EH_PE_signed)
+			value = get_unaligned(ptr.p16s++);
+		else
+			value = get_unaligned(ptr.p16u++);
+		break;
+	case DW_EH_PE_data4:
+#ifdef CONFIG_64BIT
+		if (end < (const void *)(ptr.p32u + 1))
+			return 0;
+		if(ptrType & DW_EH_PE_signed)
+			value = get_unaligned(ptr.p32s++);
+		else
+			value = get_unaligned(ptr.p32u++);
+		break;
+	case DW_EH_PE_data8:
+		BUILD_BUG_ON(sizeof(u64) != sizeof(value));
+#else
+		BUILD_BUG_ON(sizeof(u32) != sizeof(value));
+#endif
+	case DW_EH_PE_native:
+		if (end < (const void *)(ptr.pul + 1))
+			return 0;
+		value = get_unaligned(ptr.pul++);
+		break;
+	case DW_EH_PE_leb128:
+		BUILD_BUG_ON(sizeof(uleb128_t) > sizeof(value));
+		value = ptrType & DW_EH_PE_signed
+		        ? get_sleb128(&ptr.p8, end)
+		        : get_uleb128(&ptr.p8, end);
+		if ((const void *)ptr.p8 > end)
+			return 0;
+		break;
+	default:
+		return 0;
+	}
+	switch(ptrType & DW_EH_PE_ADJUST) {
+	case DW_EH_PE_abs:
+		break;
+	case DW_EH_PE_pcrel:
+		value += (unsigned long)*pLoc;
+		break;
+	default:
+		return 0;
+	}
+	if ((ptrType & DW_EH_PE_indirect)
+	    && __get_user(value, (unsigned long *)value))
+		return 0;
+	*pLoc = ptr.p8;
+
+	return value;
+}
+
+static signed fde_pointer_type(const u32 *cie)
+{
+	const u8 *ptr = (const u8 *)(cie + 2);
+	unsigned version = *ptr;
+
+	if (version != 1)
+		return -1; /* unsupported */
+	if (*++ptr) {
+		const char *aug;
+		const u8 *end = (const u8 *)(cie + 1) + *cie;
+		uleb128_t len;
+
+		/* check if augmentation size is first (and thus present) */
+		if (*ptr != 'z')
+			return -1;
+		/* check if augmentation string is nul-terminated */
+		if ((ptr = memchr(aug = (const void *)ptr, 0, end - ptr)) == NULL)
+			return -1;
+		++ptr; /* skip terminator */
+		get_uleb128(&ptr, end); /* skip code alignment */
+		get_sleb128(&ptr, end); /* skip data alignment */
+		/* skip return address column */
+		version <= 1 ? (void)++ptr : (void)get_uleb128(&ptr, end);
+		len = get_uleb128(&ptr, end); /* augmentation length */
+		if (ptr + len < ptr || ptr + len > end)
+			return -1;
+		end = ptr + len;
+		while (*++aug) {
+			if (ptr >= end)
+				return -1;
+			switch(*aug) {
+			case 'L':
+				++ptr;
+				break;
+			case 'P': {
+					signed ptrType = *ptr++;
+
+					if (!read_pointer(&ptr, end, ptrType) || ptr > end)
+						return -1;
+				}
+				break;
+			case 'R':
+				return *ptr;
+			default:
+				return -1;
+			}
+		}
+	}
+	return DW_EH_PE_native|DW_EH_PE_abs;
+}
+
+static int advance_loc(unsigned long delta, struct unwind_state *state)
+{
+	state->loc += delta * state->codeAlign;
+
+	return delta > 0;
+}
+
+static void set_rule(uleb128_t reg,
+                     enum item_location where,
+                     uleb128_t value,
+                     struct unwind_state *state)
+{
+	if (reg < ARRAY_SIZE(state->regs)) {
+		state->regs[reg].where = where;
+		state->regs[reg].value = value;
+	}
+}
+
+static int processCFI(const u8 *start,
+                      const u8 *end,
+                      unsigned long targetLoc,
+                      signed ptrType,
+                      struct unwind_state *state)
+{
+	union {
+		const u8 *p8;
+		const u16 *p16;
+		const u32 *p32;
+	} ptr;
+	int result = 1;
+
+	if (start != state->cieStart) {
+		state->loc = state->org;
+		result = processCFI(state->cieStart, state->cieEnd, 0, ptrType, state);
+		if (targetLoc == 0 && state->label == NULL)
+			return result;
+	}
+	for (ptr.p8 = start; result && ptr.p8 < end; ) {
+		switch(*ptr.p8 >> 6) {
+			uleb128_t value;
+
+		case 0:
+			switch(*ptr.p8++) {
+			case DW_CFA_nop:
+				break;
+			case DW_CFA_set_loc:
+				if ((state->loc = read_pointer(&ptr.p8, end, ptrType)) == 0)
+					result = 0;
+				break;
+			case DW_CFA_advance_loc1:
+				result = ptr.p8 < end && advance_loc(*ptr.p8++, state);
+				break;
+			case DW_CFA_advance_loc2:
+				result = ptr.p8 <= end + 2
+				         && advance_loc(*ptr.p16++, state);
+				break;
+			case DW_CFA_advance_loc4:
+				result = ptr.p8 <= end + 4
+				         && advance_loc(*ptr.p32++, state);
+				break;
+			case DW_CFA_offset_extended:
+				value = get_uleb128(&ptr.p8, end);
+				set_rule(value, Memory, get_uleb128(&ptr.p8, end), state);
+				break;
+			case DW_CFA_val_offset:
+				value = get_uleb128(&ptr.p8, end);
+				set_rule(value, Value, get_uleb128(&ptr.p8, end), state);
+				break;
+			case DW_CFA_offset_extended_sf:
+				value = get_uleb128(&ptr.p8, end);
+				set_rule(value, Memory, get_sleb128(&ptr.p8, end), state);
+				break;
+			case DW_CFA_val_offset_sf:
+				value = get_uleb128(&ptr.p8, end);
+				set_rule(value, Value, get_sleb128(&ptr.p8, end), state);
+				break;
+			case DW_CFA_restore_extended:
+			case DW_CFA_undefined:
+			case DW_CFA_same_value:
+				set_rule(get_uleb128(&ptr.p8, end), Nowhere, 0, state);
+				break;
+			case DW_CFA_register:
+				value = get_uleb128(&ptr.p8, end);
+				set_rule(value,
+				         Register,
+				         get_uleb128(&ptr.p8, end), state);
+				break;
+			case DW_CFA_remember_state:
+				if (ptr.p8 == state->label) {
+					state->label = NULL;
+					return 1;
+				}
+				if (state->stackDepth >= MAX_STACK_DEPTH)
+					return 0;
+				state->stack[state->stackDepth++] = ptr.p8;
+				break;
+			case DW_CFA_restore_state:
+				if (state->stackDepth) {
+					const uleb128_t loc = state->loc;
+					const u8 *label = state->label;
+
+					state->label = state->stack[state->stackDepth - 1];
+					memcpy(&state->cfa, &badCFA, sizeof(state->cfa));
+					memset(state->regs, 0, sizeof(state->regs));
+					state->stackDepth = 0;
+					result = processCFI(start, end, 0, ptrType, state);
+					state->loc = loc;
+					state->label = label;
+				} else
+					return 0;
+				break;
+			case DW_CFA_def_cfa:
+				state->cfa.reg = get_uleb128(&ptr.p8, end);
+				/*nobreak*/
+			case DW_CFA_def_cfa_offset:
+				state->cfa.offs = get_uleb128(&ptr.p8, end);
+				break;
+			case DW_CFA_def_cfa_sf:
+				state->cfa.reg = get_uleb128(&ptr.p8, end);
+				/*nobreak*/
+			case DW_CFA_def_cfa_offset_sf:
+				state->cfa.offs = get_sleb128(&ptr.p8, end)
+				                  * state->dataAlign;
+				break;
+			case DW_CFA_def_cfa_register:
+				state->cfa.reg = get_uleb128(&ptr.p8, end);
+				break;
+			/*todo case DW_CFA_def_cfa_expression: */
+			/*todo case DW_CFA_expression: */
+			/*todo case DW_CFA_val_expression: */
+			case DW_CFA_GNU_args_size:
+				get_uleb128(&ptr.p8, end);
+				break;
+			case DW_CFA_GNU_negative_offset_extended:
+				value = get_uleb128(&ptr.p8, end);
+				set_rule(value,
+				         Memory,
+				         (uleb128_t)0 - get_uleb128(&ptr.p8, end), state);
+				break;
+			case DW_CFA_GNU_window_save:
+			default:
+				result = 0;
+				break;
+			}
+			break;
+		case 1:
+			result = advance_loc(*ptr.p8++ & 0x3f, state);
+			break;
+		case 2:
+			value = *ptr.p8++ & 0x3f;
+			set_rule(value, Memory, get_uleb128(&ptr.p8, end), state);
+			break;
+		case 3:
+			set_rule(*ptr.p8++ & 0x3f, Nowhere, 0, state);
+			break;
+		}
+		if (ptr.p8 > end)
+			result = 0;
+		if (result && targetLoc != 0 && targetLoc < state->loc)
+			return 1;
+	}
+
+	return result
+	   && ptr.p8 == end
+	   && (targetLoc == 0
+	    || (/*todo While in theory this should apply, gcc in practice omits
+	          everything past the function prolog, and hence the location
+	          never reaches the end of the function.
+	        targetLoc < state->loc &&*/ state->label == NULL));
+}
+
+/* Unwind to previous to frame.  Returns 0 if successful, negative
+ * number in case of an error. */
+int unwind(struct unwind_frame_info *frame)
+{
+#define FRAME_REG(r, t) (((t *)frame)[reg_info[r].offs])
+	const u32 *fde = NULL, *cie = NULL;
+	const u8 *ptr = NULL, *end = NULL;
+	unsigned long startLoc = 0, endLoc = 0, cfa;
+	unsigned i;
+	signed ptrType = -1;
+	uleb128_t retAddrReg = 0;
+	struct unwind_table *table;
+	struct unwind_state state;
+
+	if (UNW_PC(frame) == 0)
+		return -EINVAL;
+	if ((table = find_table(UNW_PC(frame))) != NULL
+	    && !(table->size & (sizeof(*fde) - 1))) {
+		unsigned long tableSize = table->size;
+
+		for (fde = table->address;
+		     tableSize > sizeof(*fde) && tableSize - sizeof(*fde) >= *fde;
+		     tableSize -= sizeof(*fde) + *fde,
+		     fde += 1 + *fde / sizeof(*fde)) {
+			if (!*fde || (*fde & (sizeof(*fde) - 1)))
+				break;
+			if (!fde[1])
+				continue; /* this is a CIE */
+			if ((fde[1] & (sizeof(*fde) - 1))
+			    || fde[1] > (unsigned long)(fde + 1)
+			                - (unsigned long)table->address)
+				continue; /* this is not a valid FDE */
+			cie = fde + 1 - fde[1] / sizeof(*fde);
+			if (*cie <= sizeof(*cie) + 4
+			    || *cie >= fde[1] - sizeof(*fde)
+			    || (*cie & (sizeof(*cie) - 1))
+			    || cie[1]
+			    || (ptrType = fde_pointer_type(cie)) < 0) {
+				cie = NULL; /* this is not a (valid) CIE */
+				continue;
+			}
+			ptr = (const u8 *)(fde + 2);
+			startLoc = read_pointer(&ptr,
+			                        (const u8 *)(fde + 1) + *fde,
+			                        ptrType);
+			endLoc = startLoc
+			         + read_pointer(&ptr,
+			                        (const u8 *)(fde + 1) + *fde,
+			                        ptrType & DW_EH_PE_indirect
+			                        ? ptrType
+			                        : ptrType & (DW_EH_PE_FORM|DW_EH_PE_signed));
+			if (UNW_PC(frame) >= startLoc && UNW_PC(frame) < endLoc)
+				break;
+			cie = NULL;
+		}
+	}
+	if (cie != NULL) {
+		memset(&state, 0, sizeof(state));
+		state.cieEnd = ptr; /* keep here temporarily */
+		ptr = (const u8 *)(cie + 2);
+		end = (const u8 *)(cie + 1) + *cie;
+		if ((state.version = *ptr) != 1)
+			cie = NULL; /* unsupported version */
+		else if (*++ptr) {
+			/* check if augmentation size is first (and thus present) */
+			if (*ptr == 'z') {
+				/* check for ignorable (or already handled)
+				 * nul-terminated augmentation string */
+				while (++ptr < end && *ptr)
+					if (strchr("LPR", *ptr) == NULL)
+						break;
+			}
+			if (ptr >= end || *ptr)
+				cie = NULL;
+		}
+		++ptr;
+	}
+	if (cie != NULL) {
+		/* get code aligment factor */
+		state.codeAlign = get_uleb128(&ptr, end);
+		/* get data aligment factor */
+		state.dataAlign = get_sleb128(&ptr, end);
+		if (state.codeAlign == 0 || state.dataAlign == 0 || ptr >= end)
+			cie = NULL;
+		else {
+			retAddrReg = state.version <= 1 ? *ptr++ : get_uleb128(&ptr, end);
+			/* skip augmentation */
+			if (((const char *)(cie + 2))[1] == 'z')
+				ptr += get_uleb128(&ptr, end);
+			if (ptr > end
+			   || retAddrReg >= ARRAY_SIZE(reg_info)
+			   || REG_INVALID(retAddrReg)
+			   || reg_info[retAddrReg].width != sizeof(unsigned long))
+				cie = NULL;
+		}
+	}
+	if (cie != NULL) {
+		state.cieStart = ptr;
+		ptr = state.cieEnd;
+		state.cieEnd = end;
+		end = (const u8 *)(fde + 1) + *fde;
+		/* skip augmentation */
+		if (((const char *)(cie + 2))[1] == 'z') {
+			uleb128_t augSize = get_uleb128(&ptr, end);
+
+			if ((ptr += augSize) > end)
+				fde = NULL;
+		}
+	}
+	if (cie == NULL || fde == NULL) {
+#ifdef CONFIG_FRAME_POINTER
+		unsigned long top, bottom;
+#endif
+
+#ifdef CONFIG_FRAME_POINTER
+		top = STACK_TOP(frame->task);
+		bottom = STACK_BOTTOM(frame->task);
+# if FRAME_RETADDR_OFFSET < 0
+		if (UNW_SP(frame) < top
+		    && UNW_FP(frame) <= UNW_SP(frame)
+		    && bottom < UNW_FP(frame)
+# else
+		if (UNW_SP(frame) > top
+		    && UNW_FP(frame) >= UNW_SP(frame)
+		    && bottom > UNW_FP(frame)
+# endif
+		   && !((UNW_SP(frame) | UNW_FP(frame))
+		        & (sizeof(unsigned long) - 1))) {
+			unsigned long link;
+
+			if (!__get_user(link,
+			                (unsigned long *)(UNW_FP(frame)
+			                                  + FRAME_LINK_OFFSET))
+# if FRAME_RETADDR_OFFSET < 0
+			   && link > bottom && link < UNW_FP(frame)
+# else
+			   && link > UNW_FP(frame) && link < bottom
+# endif
+			   && !(link & (sizeof(link) - 1))
+			   && !__get_user(UNW_PC(frame),
+			                  (unsigned long *)(UNW_FP(frame)
+			                                    + FRAME_RETADDR_OFFSET))) {
+				UNW_SP(frame) = UNW_FP(frame) + FRAME_RETADDR_OFFSET
+# if FRAME_RETADDR_OFFSET < 0
+					-
+# else
+					+
+# endif
+					  sizeof(UNW_PC(frame));
+				UNW_FP(frame) = link;
+				return 0;
+			}
+		}
+#endif
+		return -ENXIO;
+	}
+	state.org = startLoc;
+	memcpy(&state.cfa, &badCFA, sizeof(state.cfa));
+	/* process instructions */
+	if (!processCFI(ptr, end, UNW_PC(frame), ptrType, &state)
+	   || state.loc > endLoc
+	   || state.regs[retAddrReg].where == Nowhere
+	   || state.cfa.reg >= ARRAY_SIZE(reg_info)
+	   || reg_info[state.cfa.reg].width != sizeof(unsigned long)
+	   || state.cfa.offs % sizeof(unsigned long))
+		return -EIO;
+	/* update frame */
+	cfa = FRAME_REG(state.cfa.reg, unsigned long) + state.cfa.offs;
+	startLoc = min((unsigned long)UNW_SP(frame), cfa);
+	endLoc = max((unsigned long)UNW_SP(frame), cfa);
+	if (STACK_LIMIT(startLoc) != STACK_LIMIT(endLoc)) {
+		startLoc = min(STACK_LIMIT(cfa), cfa);
+		endLoc = max(STACK_LIMIT(cfa), cfa);
+	}
+#ifndef CONFIG_64BIT
+# define CASES CASE(8); CASE(16); CASE(32)
+#else
+# define CASES CASE(8); CASE(16); CASE(32); CASE(64)
+#endif
+	for (i = 0; i < ARRAY_SIZE(state.regs); ++i) {
+		if (REG_INVALID(i)) {
+			if (state.regs[i].where == Nowhere)
+				continue;
+			return -EIO;
+		}
+		switch(state.regs[i].where) {
+		default:
+			break;
+		case Register:
+			if (state.regs[i].value >= ARRAY_SIZE(reg_info)
+			   || REG_INVALID(state.regs[i].value)
+			   || reg_info[i].width > reg_info[state.regs[i].value].width)
+				return -EIO;
+			switch(reg_info[state.regs[i].value].width) {
+#define CASE(n) \
+			case sizeof(u##n): \
+				state.regs[i].value = FRAME_REG(state.regs[i].value, \
+				                                const u##n); \
+				break
+			CASES;
+#undef CASE
+			default:
+				return -EIO;
+			}
+			break;
+		}
+	}
+	for (i = 0; i < ARRAY_SIZE(state.regs); ++i) {
+		if (REG_INVALID(i))
+			continue;
+		switch(state.regs[i].where) {
+		case Nowhere:
+			if (reg_info[i].width != sizeof(UNW_SP(frame))
+			   || &FRAME_REG(i, __typeof__(UNW_SP(frame)))
+			      != &UNW_SP(frame))
+				continue;
+			UNW_SP(frame) = cfa;
+			break;
+		case Register:
+			switch(reg_info[i].width) {
+#define CASE(n) case sizeof(u##n): \
+				FRAME_REG(i, u##n) = state.regs[i].value; \
+				break
+			CASES;
+#undef CASE
+			default:
+				return -EIO;
+			}
+			break;
+		case Value:
+			if (reg_info[i].width != sizeof(unsigned long))
+				return -EIO;
+			FRAME_REG(i, unsigned long) = cfa + state.regs[i].value
+			                                    * state.dataAlign;
+			break;
+		case Memory: {
+				unsigned long addr = cfa + state.regs[i].value
+				                           * state.dataAlign;
+
+				if ((state.regs[i].value * state.dataAlign)
+				    % sizeof(unsigned long)
+				    || addr < startLoc
+				    || addr + sizeof(unsigned long) < addr
+				    || addr + sizeof(unsigned long) > endLoc)
+					return -EIO;
+				switch(reg_info[i].width) {
+#define CASE(n)     case sizeof(u##n): \
+					__get_user(FRAME_REG(i, u##n), (u##n *)addr); \
+					break
+				CASES;
+#undef CASE
+				default:
+					return -EIO;
+				}
+			}
+			break;
+		}
+	}
+
+	return 0;
+#undef CASES
+#undef FRAME_REG
+}
+EXPORT_SYMBOL(unwind);
+
+int unwind_init_frame_info(struct unwind_frame_info *info,
+                           struct task_struct *tsk,
+                           /*const*/ struct pt_regs *regs)
+{
+	info->task = tsk;
+	arch_unw_init_frame_info(info, regs);
+
+	return 0;
+}
+EXPORT_SYMBOL(unwind_init_frame_info);
+
+/*
+ * Prepare to unwind a blocked task.
+ */
+int unwind_init_blocked(struct unwind_frame_info *info,
+                        struct task_struct *tsk)
+{
+	info->task = tsk;
+	arch_unw_init_blocked(info);
+
+	return 0;
+}
+EXPORT_SYMBOL(unwind_init_blocked);
+
+/*
+ * Prepare to unwind the currently running thread.
+ */
+int unwind_init_running(struct unwind_frame_info *info,
+                        asmlinkage int (*callback)(struct unwind_frame_info *,
+                                                   void *arg),
+                        void *arg)
+{
+	info->task = current;
+
+	return arch_unwind_init_running(info, callback, arg);
+}
+EXPORT_SYMBOL(unwind_init_running);
+
+/*
+ * Unwind until the return pointer is in user-land (or until an error
+ * occurs).  Returns 0 if successful, negative number in case of
+ * error.
+ */
+int unwind_to_user(struct unwind_frame_info *info)
+{
+	while (!arch_unw_user_mode(info)) {
+		int err = unwind(info);
+
+		if (err < 0)
+			return err;
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL(unwind_to_user);
diff --git a/kernel/utrace.c b/kernel/utrace.c
new file mode 100644
index 000000000..52d9b0059
--- /dev/null
+++ b/kernel/utrace.c
@@ -0,0 +1,1598 @@
+#include <linux/utrace.h>
+#include <linux/tracehook.h>
+#include <linux/err.h>
+#include <linux/sched.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <asm/tracehook.h>
+
+
+static kmem_cache_t *utrace_cachep;
+static kmem_cache_t *utrace_engine_cachep;
+
+static int __init
+utrace_init(void)
+{
+	utrace_cachep =
+		kmem_cache_create("utrace_cache",
+				  sizeof(struct utrace), 0,
+				  SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL, NULL);
+	utrace_engine_cachep =
+		kmem_cache_create("utrace_engine_cache",
+				  sizeof(struct utrace_attached_engine), 0,
+				  SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL, NULL);
+	return 0;
+}
+subsys_initcall(utrace_init);
+
+
+/*
+ * Make sure target->utrace is allocated, and return with it locked on
+ * success.  This function mediates startup races.  The creating parent
+ * task has priority, and other callers will delay here to let its call
+ * succeed and take the new utrace lock first.
+ */
+static struct utrace *
+utrace_first_engine(struct task_struct *target,
+		    struct utrace_attached_engine *engine)
+{
+	struct utrace *utrace, *ret;
+
+	/*
+	 * If this is a newborn thread and we are not the creator,
+	 * we have to wait for it.  The creator gets the first chance
+	 * to attach.  The PF_STARTING flag is cleared after its
+	 * report_clone hook has had a chance to run.
+	 */
+	if ((target->flags & PF_STARTING)
+	    && (current->utrace == NULL
+		|| current->utrace->u.live.cloning != target)) {
+		yield();
+		return (signal_pending(current)
+			? ERR_PTR(-ERESTARTNOINTR) : NULL);
+	}
+
+	utrace = kmem_cache_alloc(utrace_cachep, SLAB_KERNEL);
+	if (unlikely(utrace == NULL))
+		return ERR_PTR(-ENOMEM);
+
+	utrace->u.live.cloning = NULL;
+	utrace->u.live.signal = NULL;
+	INIT_LIST_HEAD(&utrace->engines);
+	list_add(&engine->entry, &utrace->engines);
+	spin_lock_init(&utrace->lock);
+
+	ret = utrace;
+	utrace_lock(utrace);
+	task_lock(target);
+	if (likely(target->utrace == NULL)) {
+		rcu_assign_pointer(target->utrace, utrace);
+		/*
+		 * The task_lock protects us against another thread doing
+		 * the same thing.  We might still be racing against
+		 * tracehook_release_task.  It's called with ->exit_state
+		 * set to EXIT_DEAD and then checks ->utrace with an
+		 * smp_mb() in between.  If EXIT_DEAD is set, then
+		 * release_task might have checked ->utrace already and saw
+		 * it NULL; we can't attach.  If we see EXIT_DEAD not yet
+		 * set after our barrier, then we know release_task will
+		 * see our target->utrace pointer.
+		 */
+		smp_mb();
+		if (target->exit_state == EXIT_DEAD) {
+			/*
+			 * The target has already been through release_task.
+			 */
+			target->utrace = NULL;
+			goto cannot_attach;
+		}
+		task_unlock(target);
+
+		/*
+		 * If the thread is already dead when we attach, then its
+		 * parent was notified already and we shouldn't repeat the
+		 * notification later after a detach or NOREAP flag change.
+		 */
+		if (target->exit_state)
+			utrace->u.exit.notified = 1;
+	}
+	else {
+		/*
+		 * Another engine attached first, so there is a struct already.
+		 * A null return says to restart looking for the existing one.
+		 */
+	cannot_attach:
+		ret = NULL;
+		task_unlock(target);
+		utrace_unlock(utrace);
+		kmem_cache_free(utrace_cachep, utrace);
+	}
+
+	return ret;
+}
+
+static void
+utrace_free(struct rcu_head *rhead)
+{
+	struct utrace *utrace = container_of(rhead, struct utrace, u.dead);
+	kmem_cache_free(utrace_cachep, utrace);
+}
+
+static void
+rcu_utrace_free(struct utrace *utrace)
+{
+	INIT_RCU_HEAD(&utrace->u.dead);
+	call_rcu(&utrace->u.dead, utrace_free);
+}
+
+static void
+utrace_engine_free(struct rcu_head *rhead)
+{
+	struct utrace_attached_engine *engine =
+		container_of(rhead, struct utrace_attached_engine, rhead);
+	kmem_cache_free(utrace_engine_cachep, engine);
+}
+
+/*
+ * Called with utrace locked and the target quiescent (maybe current).
+ * If this was the last engine, utrace is left locked and not freed,
+ * but is removed from the task.
+ */
+static void
+remove_engine(struct utrace_attached_engine *engine,
+	      struct task_struct *tsk, struct utrace *utrace)
+{
+	list_del_rcu(&engine->entry);
+	if (list_empty(&utrace->engines)) {
+		task_lock(tsk);
+		if (likely(tsk->utrace != NULL)) {
+			rcu_assign_pointer(tsk->utrace, NULL);
+			tsk->utrace_flags = 0;
+		}
+		task_unlock(tsk);
+	}
+	call_rcu(&engine->rhead, utrace_engine_free);
+}
+
+/*
+ * This is pointed to by the utrace struct, but it's really a private
+ * structure between utrace_get_signal and utrace_inject_signal.
+ */
+struct utrace_signal
+{
+	siginfo_t *const info;
+	struct k_sigaction *return_ka;
+	int signr;
+};
+
+/*
+ * Called with utrace locked, after remove_engine may have run.
+ * Passed the flags from all remaining engines, i.e. zero if none left.
+ * Install the flags in tsk->utrace_flags and return with utrace unlocked.
+ * If no engines are left, utrace is freed and we return NULL.
+ */
+static struct utrace *
+check_dead_utrace(struct task_struct *tsk, struct utrace *utrace,
+		 unsigned long flags)
+{
+	if (flags) {
+		tsk->utrace_flags = flags;
+		utrace_unlock(utrace);
+		return utrace;
+	}
+
+	if (utrace->u.live.signal && utrace->u.live.signal->signr != 0) {
+		utrace_unlock(utrace);
+		return utrace;
+	}
+
+	utrace_unlock(utrace);
+	rcu_utrace_free(utrace);
+	return NULL;
+}
+
+
+
+/*
+ * Get the target thread to quiesce.  Return nonzero if it's already quiescent.
+ * Return zero if it will report a QUIESCE event soon.
+ * If interrupt is nonzero, wake it like a signal would so it quiesces ASAP.
+ * If interrupt is zero, just make sure it quiesces before going to user mode.
+ */
+static int
+quiesce(struct task_struct *target, int interrupt)
+{
+	int quiescent;
+
+	target->utrace_flags |= UTRACE_ACTION_QUIESCE;
+	read_barrier_depends();
+
+	quiescent = (target->exit_state
+		     || target->state & (TASK_TRACED | TASK_STOPPED));
+
+	if (!quiescent) {
+		spin_lock_irq(&target->sighand->siglock);
+		quiescent = (unlikely(target->exit_state)
+			     || unlikely(target->state
+					 & (TASK_TRACED | TASK_STOPPED)));
+		if (!quiescent) {
+			if (interrupt)
+				signal_wake_up(target, 0);
+			else {
+				set_tsk_thread_flag(target, TIF_SIGPENDING);
+				kick_process(target);
+			}
+		}
+		spin_unlock_irq(&target->sighand->siglock);
+	}
+
+	return quiescent;
+}
+
+
+static struct utrace_attached_engine *
+matching_engine(struct utrace *utrace, int flags,
+		const struct utrace_engine_ops *ops, unsigned long data)
+{
+	struct utrace_attached_engine *engine;
+	list_for_each_entry_rcu(engine, &utrace->engines, entry) {
+		if ((flags & UTRACE_ATTACH_MATCH_OPS)
+		    && engine->ops != ops)
+			continue;
+		if ((flags & UTRACE_ATTACH_MATCH_DATA)
+		    && engine->data != data)
+			continue;
+		if (flags & UTRACE_ATTACH_EXCLUSIVE)
+			engine = ERR_PTR(-EEXIST);
+		return engine;
+	}
+	return NULL;
+}
+
+/*
+  option to stop it?
+  option to match existing on ops, ops+data, return it; nocreate:lookup only
+ */
+struct utrace_attached_engine *
+utrace_attach(struct task_struct *target, int flags,
+	     const struct utrace_engine_ops *ops, unsigned long data)
+{
+	struct utrace *utrace;
+	struct utrace_attached_engine *engine;
+
+restart:
+	rcu_read_lock();
+	utrace = rcu_dereference(target->utrace);
+	smp_rmb();
+	if (utrace == NULL) {
+		rcu_read_unlock();
+
+		if (!(flags & UTRACE_ATTACH_CREATE)) {
+			return ERR_PTR(-ENOENT);
+		}
+
+		engine = kmem_cache_alloc(utrace_engine_cachep, SLAB_KERNEL);
+		if (unlikely(engine == NULL))
+			return ERR_PTR(-ENOMEM);
+		engine->flags = 0;
+
+	first:
+		utrace = utrace_first_engine(target, engine);
+		if (IS_ERR(utrace)) {
+			kmem_cache_free(utrace_engine_cachep, engine);
+			return ERR_PTR(PTR_ERR(utrace));
+		}
+		if (unlikely(utrace == NULL)) /* Race condition.  */
+			goto restart;
+	}
+	else if (unlikely(target->exit_state == EXIT_DEAD)) {
+		/*
+		 * The target has already been reaped.
+		 */
+		rcu_read_unlock();
+		return ERR_PTR(-ESRCH);
+	}
+	else {
+		if (!(flags & UTRACE_ATTACH_CREATE)) {
+			engine = matching_engine(utrace, flags, ops, data);
+			rcu_read_unlock();
+			return engine;
+		}
+
+		engine = kmem_cache_alloc(utrace_engine_cachep, SLAB_KERNEL);
+		if (unlikely(engine == NULL))
+			return ERR_PTR(-ENOMEM);
+		engine->flags = ops->report_reap ? UTRACE_EVENT(REAP) : 0;
+
+		rcu_read_lock();
+		utrace = rcu_dereference(target->utrace);
+		if (unlikely(utrace == NULL)) { /* Race with detach.  */
+			rcu_read_unlock();
+			goto first;
+		}
+
+		utrace_lock(utrace);
+		if (flags & UTRACE_ATTACH_EXCLUSIVE) {
+			struct utrace_attached_engine *old;
+			old = matching_engine(utrace, flags, ops, data);
+			if (old != NULL) {
+				utrace_unlock(utrace);
+				rcu_read_unlock();
+				kmem_cache_free(utrace_engine_cachep, engine);
+				return ERR_PTR(-EEXIST);
+			}
+		}
+
+		if (unlikely(rcu_dereference(target->utrace) != utrace)) {
+			/*
+			 * We lost a race with other CPUs doing a sequence
+			 * of detach and attach before we got in.
+			 */
+			utrace_unlock(utrace);
+			rcu_read_unlock();
+			kmem_cache_free(utrace_engine_cachep, engine);
+			goto restart;
+		}
+		list_add_tail_rcu(&engine->entry, &utrace->engines);
+	}
+
+	engine->ops = ops;
+	engine->data = data;
+
+	utrace_unlock(utrace);
+
+	return engine;
+}
+EXPORT_SYMBOL_GPL(utrace_attach);
+
+/*
+ * When an engine is detached, the target thread may still see it and make
+ * callbacks until it quiesces.  We reset its event flags to just QUIESCE
+ * and install a special ops vector whose callback is dead_engine_delete.
+ * When the target thread quiesces, it can safely free the engine itself.
+ */
+static u32
+dead_engine_delete(struct utrace_attached_engine *engine,
+		   struct task_struct *tsk)
+{
+	return UTRACE_ACTION_DETACH;
+}
+
+static const struct utrace_engine_ops dead_engine_ops =
+{
+	.report_quiesce = &dead_engine_delete
+};
+
+
+/*
+ * If tracing was preventing a SIGCHLD or self-reaping
+ * and is no longer, do that report or reaping right now.
+ */
+static void
+check_noreap(struct task_struct *target, struct utrace *utrace,
+	     u32 old_action, u32 action)
+{
+	if ((action | ~old_action) & UTRACE_ACTION_NOREAP)
+		return;
+
+	if (utrace && xchg(&utrace->u.exit.notified, 1))
+		return;
+
+	if (target->exit_signal == -1)
+		release_task(target);
+	else if (thread_group_empty(target)) {
+		read_lock(&tasklist_lock);
+		do_notify_parent(target, target->exit_signal);
+		read_unlock(&tasklist_lock);
+	}
+}
+
+/*
+ * We may have been the one keeping the target thread quiescent.
+ * Check if it should wake up now.
+ * Called with utrace locked, and unlocks it on return.
+ * If we were keeping it stopped, resume it.
+ * If we were keeping its zombie from reporting/self-reap, do it now.
+ */
+static void
+wake_quiescent(unsigned long old_flags,
+	       struct utrace *utrace, struct task_struct *target)
+{
+	unsigned long flags;
+	struct utrace_attached_engine *engine;
+
+	if (target->exit_state) {
+		/*
+		 * Update the set of events of interest from the union
+		 * of the interests of the remaining tracing engines.
+		 */
+		flags = 0;
+		list_for_each_entry(engine, &utrace->engines, entry)
+			flags |= engine->flags | UTRACE_EVENT(REAP);
+		utrace = check_dead_utrace(target, utrace, flags);
+
+		check_noreap(target, utrace, old_flags, flags);
+		return;
+	}
+
+	/*
+	 * Update the set of events of interest from the union
+	 * of the interests of the remaining tracing engines.
+	 */
+	flags = 0;
+	list_for_each_entry(engine, &utrace->engines, entry)
+		flags |= engine->flags | UTRACE_EVENT(REAP);
+	utrace = check_dead_utrace(target, utrace, flags);
+
+	if (flags & UTRACE_ACTION_QUIESCE)
+		return;
+
+	read_lock(&tasklist_lock);
+	if (!target->exit_state) {
+		/*
+		 * The target is not dead and should not be in tracing stop
+		 * any more.  Wake it unless it's in job control stop.
+		 */
+		spin_lock_irq(&target->sighand->siglock);
+		if (target->signal->flags & SIGNAL_STOP_STOPPED) {
+			int stop_count = target->signal->group_stop_count;
+			target->state = TASK_STOPPED;
+			spin_unlock_irq(&target->sighand->siglock);
+
+			/*
+			 * If tracing was preventing a CLD_STOPPED report
+			 * and is no longer, do that report right now.
+			 */
+			if (stop_count == 0
+			    && 0
+			    /*&& (events &~ interest) & UTRACE_INHIBIT_CLDSTOP*/
+				)
+				do_notify_parent_cldstop(target, CLD_STOPPED);
+		}
+		else {
+			/*
+			 * Wake the task up.
+			 */
+			recalc_sigpending_tsk(target);
+			wake_up_state(target, TASK_STOPPED | TASK_TRACED);
+			spin_unlock_irq(&target->sighand->siglock);
+		}
+	}
+	read_unlock(&tasklist_lock);
+}
+
+void
+utrace_detach(struct task_struct *target,
+	      struct utrace_attached_engine *engine)
+{
+	struct utrace *utrace;
+	unsigned long flags;
+
+	rcu_read_lock();
+	utrace = rcu_dereference(target->utrace);
+	smp_rmb();
+	if (unlikely(target->exit_state == EXIT_DEAD)) {
+		/*
+		 * Called after utrace_release_task might have started.
+		 * A call to this engine's report_reap callback might
+		 * already be in progress or engine might even have been
+		 * freed already.
+		 */
+		rcu_read_unlock();
+		return;
+	}
+	utrace_lock(utrace);
+	rcu_read_unlock();
+
+	flags = engine->flags;
+	engine->flags = UTRACE_EVENT(QUIESCE) | UTRACE_ACTION_QUIESCE;
+	rcu_assign_pointer(engine->ops, &dead_engine_ops);
+
+	if (quiesce(target, 1)) {
+		remove_engine(engine, target, utrace);
+		wake_quiescent(flags, utrace, target);
+	}
+	else
+		utrace_unlock(utrace);
+}
+EXPORT_SYMBOL_GPL(utrace_detach);
+
+
+/*
+ * Called with utrace->lock held.
+ * Notify and clean up all engines, then free utrace.
+ */
+static void
+utrace_reap(struct task_struct *target, struct utrace *utrace)
+{
+	struct utrace_attached_engine *engine, *next;
+	const struct utrace_engine_ops *ops;
+
+restart:
+	list_for_each_entry_safe(engine, next, &utrace->engines, entry) {
+		list_del_rcu(&engine->entry);
+
+		/*
+		 * Now nothing else refers to this engine.
+		 */
+		if (engine->flags & UTRACE_EVENT(REAP)) {
+			ops = rcu_dereference(engine->ops);
+			if (ops != &dead_engine_ops) {
+				utrace_unlock(utrace);
+				(*ops->report_reap)(engine, target);
+				call_rcu(&engine->rhead, utrace_engine_free);
+				utrace_lock(utrace);
+				goto restart;
+			}
+		}
+		call_rcu(&engine->rhead, utrace_engine_free);
+	}
+	utrace_unlock(utrace);
+
+	rcu_utrace_free(utrace);
+}
+
+/*
+ * Called by release_task.  After this, target->utrace must be cleared.
+ */
+void
+utrace_release_task(struct task_struct *target)
+{
+	struct utrace *utrace;
+
+	task_lock(target);
+	utrace = target->utrace;
+	rcu_assign_pointer(target->utrace, NULL);
+	task_unlock(target);
+
+	if (unlikely(utrace == NULL))
+		return;
+
+	utrace_lock(utrace);
+
+	if (!utrace->u.exit.notified
+	    && (target->utrace_flags & (UTRACE_EVENT(DEATH)
+					| UTRACE_EVENT(QUIESCE)))) {
+		/*
+		 * The target will do some final callbacks but hasn't
+		 * finished them yet.  We know because it clears these
+		 * event bits after it's done.  Instead of cleaning up here
+		 * and requiring utrace_report_death to cope with it, we
+		 * delay the REAP report and the teardown until after the
+		 * target finishes its death reports.
+		 */
+		utrace->u.exit.reap = 1;
+		utrace_unlock(utrace);
+	}
+	else
+		utrace_reap(target, utrace); /* Unlocks and frees.  */
+}
+
+
+void
+utrace_set_flags(struct task_struct *target,
+		 struct utrace_attached_engine *engine,
+		 unsigned long flags)
+{
+	struct utrace *utrace;
+	int report = 0;
+	unsigned long old_flags, old_utrace_flags;
+
+#ifdef ARCH_HAS_SINGLE_STEP
+	if (! ARCH_HAS_SINGLE_STEP)
+#endif
+		WARN_ON(flags & UTRACE_ACTION_SINGLESTEP);
+#ifdef ARCH_HAS_BLOCK_STEP
+	if (! ARCH_HAS_BLOCK_STEP)
+#endif
+		WARN_ON(flags & UTRACE_ACTION_BLOCKSTEP);
+
+	rcu_read_lock();
+	utrace = rcu_dereference(target->utrace);
+	smp_rmb();
+	if (unlikely(target->exit_state == EXIT_DEAD)) {
+		/*
+		 * Race with reaping.
+		 */
+		rcu_read_unlock();
+		return;
+	}
+
+	utrace_lock(utrace);
+	rcu_read_unlock();
+
+	old_utrace_flags = target->utrace_flags;
+	old_flags = engine->flags;
+	engine->flags = flags;
+	target->utrace_flags |= flags;
+
+	if ((old_flags ^ flags) & UTRACE_ACTION_QUIESCE) {
+		if (flags & UTRACE_ACTION_QUIESCE) {
+			report = (quiesce(target, 1)
+				  && (flags & UTRACE_EVENT(QUIESCE)));
+			utrace_unlock(utrace);
+		}
+		else
+			wake_quiescent(old_flags, utrace, target);
+	}
+	else {
+		/*
+		 * If we're asking for single-stepping or syscall tracing,
+		 * we need to pass through utrace_quiescent before resuming
+		 * in user mode to get those effects, even if the target is
+		 * not going to be quiescent right now.
+		 */
+		if (!(target->utrace_flags & UTRACE_ACTION_QUIESCE)
+		    && ((flags &~ old_utrace_flags)
+			& (UTRACE_ACTION_SINGLESTEP | UTRACE_ACTION_BLOCKSTEP
+			   | UTRACE_EVENT_SYSCALL)))
+			quiesce(target, 0);
+		utrace_unlock(utrace);
+	}
+
+	if (report)	     /* Already quiescent, won't report itself.  */
+		(*engine->ops->report_quiesce)(engine, target);
+}
+EXPORT_SYMBOL_GPL(utrace_set_flags);
+
+/*
+ * While running an engine callback, no locks are held.
+ * If a callback updates its engine's action state, then
+ * we need to take the utrace lock to install the flags update.
+ */
+static inline u32
+update_action(struct task_struct *tsk, struct utrace *utrace,
+	      struct utrace_attached_engine *engine,
+	      u32 ret)
+{
+	if (ret & UTRACE_ACTION_DETACH)
+		rcu_assign_pointer(engine->ops, &dead_engine_ops);
+	else if ((ret & UTRACE_ACTION_NEWSTATE)
+		 && ((ret ^ engine->flags) & UTRACE_ACTION_STATE_MASK)) {
+#ifdef ARCH_HAS_SINGLE_STEP
+		if (! ARCH_HAS_SINGLE_STEP)
+#endif
+			WARN_ON(ret & UTRACE_ACTION_SINGLESTEP);
+#ifdef ARCH_HAS_BLOCK_STEP
+		if (! ARCH_HAS_BLOCK_STEP)
+#endif
+			WARN_ON(ret & UTRACE_ACTION_BLOCKSTEP);
+		utrace_lock(utrace);
+		/*
+		 * If we're changing something other than just QUIESCE,
+		 * make sure we pass through utrace_quiescent before
+		 * resuming even if we aren't going to stay quiescent.
+		 * That's where we get the correct union of all engines'
+		 * flags after they've finished changing, and apply changes.
+		 */
+		if (((ret ^ engine->flags) & (UTRACE_ACTION_STATE_MASK
+					      & ~UTRACE_ACTION_QUIESCE)))
+			tsk->utrace_flags |= UTRACE_ACTION_QUIESCE;
+		engine->flags &= ~UTRACE_ACTION_STATE_MASK;
+		engine->flags |= ret & UTRACE_ACTION_STATE_MASK;
+		tsk->utrace_flags |= engine->flags;
+		utrace_unlock(utrace);
+	}
+	else
+		ret |= engine->flags & UTRACE_ACTION_STATE_MASK;
+	return ret;
+}
+
+#define REPORT(callback, ...) do { \
+	u32 ret = (*rcu_dereference(engine->ops)->callback) \
+		(engine, tsk, ##__VA_ARGS__); \
+	action = update_action(tsk, utrace, engine, ret); \
+	} while (0)
+
+
+/*
+ * Called with utrace->lock held, returns with it released.
+ */
+static u32
+remove_detached(struct task_struct *tsk, struct utrace *utrace,
+		struct utrace **utracep, u32 action)
+{
+	struct utrace_attached_engine *engine, *next;
+	unsigned long flags;
+
+	flags = 0;
+	list_for_each_entry_safe(engine, next, &utrace->engines, entry) {
+		if (engine->ops == &dead_engine_ops)
+			remove_engine(engine, tsk, utrace);
+		else
+			flags |= engine->flags | UTRACE_EVENT(REAP);
+	}
+	utrace = check_dead_utrace(tsk, utrace, flags);
+	if (utracep)
+		*utracep = utrace;
+
+	flags &= UTRACE_ACTION_STATE_MASK;
+	return flags | (action & UTRACE_ACTION_OP_MASK);
+}
+
+/*
+ * Called after an event report loop.  Remove any engines marked for detach.
+ */
+static inline u32
+check_detach(struct task_struct *tsk, u32 action)
+{
+	if (action & UTRACE_ACTION_DETACH) {
+		utrace_lock(tsk->utrace);
+		action = remove_detached(tsk, tsk->utrace, NULL, action);
+	}
+	return action;
+}
+
+static inline void
+check_quiescent(struct task_struct *tsk, u32 action)
+{
+	if (action & UTRACE_ACTION_STATE_MASK)
+		utrace_quiescent(tsk);
+}
+
+/*
+ * Called iff UTRACE_EVENT(CLONE) flag is set.
+ * This notification call blocks the wake_up_new_task call on the child.
+ * So we must not quiesce here.  tracehook_report_clone_complete will do
+ * a quiescence check momentarily.
+ */
+void
+utrace_report_clone(unsigned long clone_flags, struct task_struct *child)
+{
+	struct task_struct *tsk = current;
+	struct utrace *utrace = tsk->utrace;
+	struct list_head *pos, *next;
+	struct utrace_attached_engine *engine;
+	unsigned long action;
+
+	utrace->u.live.cloning = child;
+
+	/* XXX must change for sharing */
+	action = UTRACE_ACTION_RESUME;
+	list_for_each_safe_rcu(pos, next, &utrace->engines) {
+		engine = list_entry(pos, struct utrace_attached_engine, entry);
+		if (engine->flags & UTRACE_EVENT(CLONE))
+			REPORT(report_clone, clone_flags, child);
+		if (action & UTRACE_ACTION_HIDE)
+			break;
+	}
+
+	utrace->u.live.cloning = NULL;
+
+	check_detach(tsk, action);
+}
+
+static unsigned long
+report_quiescent(struct task_struct *tsk, struct utrace *utrace, u32 action)
+{
+	struct list_head *pos, *next;
+	struct utrace_attached_engine *engine;
+
+	list_for_each_safe_rcu(pos, next, &utrace->engines) {
+		engine = list_entry(pos, struct utrace_attached_engine, entry);
+		if (engine->flags & UTRACE_EVENT(QUIESCE))
+			REPORT(report_quiesce);
+		action |= engine->flags & UTRACE_ACTION_STATE_MASK;
+	}
+
+	return check_detach(tsk, action);
+}
+
+/*
+ * Called iff UTRACE_EVENT(JCTL) flag is set.
+ */
+int
+utrace_report_jctl(int what)
+{
+	struct task_struct *tsk = current;
+	struct utrace *utrace = tsk->utrace;
+	struct list_head *pos, *next;
+	struct utrace_attached_engine *engine;
+	unsigned long action;
+
+	/* XXX must change for sharing */
+	action = UTRACE_ACTION_RESUME;
+	list_for_each_safe_rcu(pos, next, &utrace->engines) {
+		engine = list_entry(pos, struct utrace_attached_engine, entry);
+		if (engine->flags & UTRACE_EVENT(JCTL))
+			REPORT(report_jctl, what);
+		if (action & UTRACE_ACTION_HIDE)
+			break;
+	}
+
+	/*
+	 * We are becoming quiescent, so report it now.
+	 * We don't block in utrace_quiescent because we are stopping anyway.
+	 * We know that upon resuming we'll go through tracehook_induce_signal,
+	 * which will keep us quiescent or set us up to resume with tracing.
+	 */
+	action = report_quiescent(tsk, utrace, action);
+
+	if (what == CLD_STOPPED && tsk->state != TASK_STOPPED) {
+		/*
+		 * The event report hooks could have blocked, though
+		 * it should have been briefly.  Make sure we're in
+		 * TASK_STOPPED state again to block properly, unless
+		 * we've just come back out of job control stop.
+		 */
+		spin_lock_irq(&tsk->sighand->siglock);
+		if (tsk->signal->flags & SIGNAL_STOP_STOPPED)
+			set_current_state(TASK_STOPPED);
+		spin_unlock_irq(&tsk->sighand->siglock);
+	}
+
+	return action & UTRACE_JCTL_NOSIGCHLD;
+}
+
+
+/*
+ * Called if UTRACE_EVENT(QUIESCE) or UTRACE_ACTION_QUIESCE flag is set.
+ * Also called after other event reports.
+ * It is a good time to block.
+ */
+void
+utrace_quiescent(struct task_struct *tsk)
+{
+	struct utrace *utrace = tsk->utrace;
+	unsigned long action;
+
+restart:
+	/* XXX must change for sharing */
+
+	action = report_quiescent(tsk, utrace, UTRACE_ACTION_RESUME);
+
+	/*
+	 * If some engines want us quiescent, we block here.
+	 */
+	if (action & UTRACE_ACTION_QUIESCE) {
+		spin_lock_irq(&tsk->sighand->siglock);
+		/*
+		 * If wake_quiescent is trying to wake us up now, it will
+		 * have cleared the QUIESCE flag before trying to take the
+		 * siglock.  Now we have the siglock, so either it has
+		 * already cleared the flag, or it will wake us up after we
+		 * release the siglock it's waiting for.
+		 * Never stop when there is a SIGKILL bringing us down.
+		 */
+		if ((tsk->utrace_flags & UTRACE_ACTION_QUIESCE)
+		    /*&& !(tsk->signal->flags & SIGNAL_GROUP_SIGKILL)*/) {
+			set_current_state(TASK_TRACED);
+			/*
+			 * If there is a group stop in progress,
+			 * we must participate in the bookkeeping.
+			 */
+			if (tsk->signal->group_stop_count > 0)
+				--tsk->signal->group_stop_count;
+			spin_unlock_irq(&tsk->sighand->siglock);
+			schedule();
+		}
+		else
+			spin_unlock_irq(&tsk->sighand->siglock);
+
+		/*
+		 * We've woken up.  One engine could be waking us up while
+		 * another has asked us to quiesce.  So check afresh.  We
+		 * could have been detached while quiescent.  Now we are no
+		 * longer quiescent, so don't need to do any RCU locking.
+		 * But we do need to check our utrace pointer anew.
+		 */
+		utrace = tsk->utrace;
+		if (tsk->utrace_flags
+		    & (UTRACE_EVENT(QUIESCE) | UTRACE_ACTION_STATE_MASK))
+			goto restart;
+	}
+	else if (tsk->utrace_flags & UTRACE_ACTION_QUIESCE) {
+		/*
+		 * Our flags are out of date.
+		 * Update the set of events of interest from the union
+		 * of the interests of the remaining tracing engines.
+		 */
+		struct utrace_attached_engine *engine;
+		unsigned long flags = 0;
+		utrace = rcu_dereference(tsk->utrace);
+		utrace_lock(utrace);
+		list_for_each_entry(engine, &utrace->engines, entry)
+			flags |= engine->flags | UTRACE_EVENT(REAP);
+		tsk->utrace_flags = flags;
+		utrace_unlock(utrace);
+	}
+
+	/*
+	 * We're resuming.  Update the machine layer tracing state and then go.
+	 */
+#ifdef ARCH_HAS_SINGLE_STEP
+	if (action & UTRACE_ACTION_SINGLESTEP)
+		tracehook_enable_single_step(tsk);
+	else
+		tracehook_disable_single_step(tsk);
+#endif
+#ifdef ARCH_HAS_BLOCK_STEP
+	if ((action & (UTRACE_ACTION_BLOCKSTEP|UTRACE_ACTION_SINGLESTEP))
+	    == UTRACE_ACTION_BLOCKSTEP)
+		tracehook_enable_block_step(tsk);
+	else
+		tracehook_disable_block_step(tsk);
+#endif
+	if (tsk->utrace_flags & UTRACE_EVENT_SYSCALL)
+		tracehook_enable_syscall_trace(tsk);
+	else
+		tracehook_disable_syscall_trace(tsk);
+}
+
+
+/*
+ * Called iff UTRACE_EVENT(EXIT) flag is set.
+ */
+void
+utrace_report_exit(long *exit_code)
+{
+	struct task_struct *tsk = current;
+	struct utrace *utrace = tsk->utrace;
+	struct list_head *pos, *next;
+	struct utrace_attached_engine *engine;
+	unsigned long action;
+	long orig_code = *exit_code;
+
+	/* XXX must change for sharing */
+	action = UTRACE_ACTION_RESUME;
+	list_for_each_safe_rcu(pos, next, &utrace->engines) {
+		engine = list_entry(pos, struct utrace_attached_engine, entry);
+		if (engine->flags & UTRACE_EVENT(EXIT))
+			REPORT(report_exit, orig_code, exit_code);
+	}
+	action = check_detach(tsk, action);
+	check_quiescent(tsk, action);
+}
+
+/*
+ * Called iff UTRACE_EVENT(DEATH) flag is set.
+ *
+ * It is always possible that we are racing with utrace_release_task here,
+ * if UTRACE_ACTION_NOREAP is not set, or in the case of non-leader exec
+ * where the old leader will get released regardless of NOREAP.  For this
+ * reason, utrace_release_task checks for the event bits that get us here,
+ * and delays its cleanup for us to do.
+ */
+void
+utrace_report_death(struct task_struct *tsk, struct utrace *utrace)
+{
+	struct list_head *pos, *next;
+	struct utrace_attached_engine *engine;
+	u32 action, oaction;
+
+	BUG_ON(!tsk->exit_state);
+
+	oaction = tsk->utrace_flags;
+
+	/* XXX must change for sharing */
+	action = UTRACE_ACTION_RESUME;
+	list_for_each_safe_rcu(pos, next, &utrace->engines) {
+		engine = list_entry(pos, struct utrace_attached_engine, entry);
+		if (engine->flags & UTRACE_EVENT(DEATH))
+			REPORT(report_death);
+		if (engine->flags & UTRACE_EVENT(QUIESCE))
+			REPORT(report_quiesce);
+	}
+	/*
+	 * Unconditionally lock and recompute the flags.
+	 * This may notice that there are no engines left and
+	 * free the utrace struct.
+	 */
+	utrace_lock(utrace);
+	if (utrace->u.exit.reap) {
+		/*
+		 * utrace_release_task was already called in parallel.
+		 * We must complete its work now.
+		 */
+	reap:
+		utrace_reap(tsk, utrace);
+	}
+	else {
+		action = remove_detached(tsk, utrace, &utrace, action);
+
+		if (utrace != NULL) {
+			utrace_lock(utrace);
+			if (utrace->u.exit.reap)
+				goto reap;
+
+			/*
+			 * Clear event bits we can't see any more.  This
+			 * tells utrace_release_task we have already
+			 * finished, if it comes along later.
+			 */
+			tsk->utrace_flags &= (UTRACE_EVENT(REAP)
+					      | UTRACE_ACTION_NOREAP);
+
+			utrace_unlock(utrace);
+		}
+
+		check_noreap(tsk, utrace, oaction, action);
+	}
+}
+
+/*
+ * Called iff UTRACE_EVENT(VFORK_DONE) flag is set.
+ */
+void
+utrace_report_vfork_done(pid_t child_pid)
+{
+	struct task_struct *tsk = current;
+	struct utrace *utrace = tsk->utrace;
+	struct list_head *pos, *next;
+	struct utrace_attached_engine *engine;
+	unsigned long action;
+
+	/* XXX must change for sharing */
+	action = UTRACE_ACTION_RESUME;
+	list_for_each_safe_rcu(pos, next, &utrace->engines) {
+		engine = list_entry(pos, struct utrace_attached_engine, entry);
+		if (engine->flags & UTRACE_EVENT(VFORK_DONE))
+			REPORT(report_vfork_done, child_pid);
+		if (action & UTRACE_ACTION_HIDE)
+			break;
+	}
+	action = check_detach(tsk, action);
+	check_quiescent(tsk, action);
+}
+
+/*
+ * Called iff UTRACE_EVENT(EXEC) flag is set.
+ */
+void
+utrace_report_exec(struct linux_binprm *bprm, struct pt_regs *regs)
+{
+	struct task_struct *tsk = current;
+	struct utrace *utrace = tsk->utrace;
+	struct list_head *pos, *next;
+	struct utrace_attached_engine *engine;
+	unsigned long action;
+
+	/* XXX must change for sharing */
+	action = UTRACE_ACTION_RESUME;
+	list_for_each_safe_rcu(pos, next, &utrace->engines) {
+		engine = list_entry(pos, struct utrace_attached_engine, entry);
+		if (engine->flags & UTRACE_EVENT(EXEC))
+			REPORT(report_exec, bprm, regs);
+		if (action & UTRACE_ACTION_HIDE)
+			break;
+	}
+	action = check_detach(tsk, action);
+	check_quiescent(tsk, action);
+}
+
+/*
+ * Called iff UTRACE_EVENT(SYSCALL_{ENTRY,EXIT}) flag is set.
+ */
+void
+utrace_report_syscall(struct pt_regs *regs, int is_exit)
+{
+	struct task_struct *tsk = current;
+	struct utrace *utrace = tsk->utrace;
+	struct list_head *pos, *next;
+	struct utrace_attached_engine *engine;
+	unsigned long action, ev;
+
+/*
+  XXX pass syscall # to engine hook directly, let it return inhibit-action
+  to reset to -1
+	long syscall = tracehook_syscall_number(regs, is_exit);
+*/
+
+	ev = is_exit ? UTRACE_EVENT(SYSCALL_EXIT) : UTRACE_EVENT(SYSCALL_ENTRY);
+
+	/* XXX must change for sharing */
+	action = UTRACE_ACTION_RESUME;
+	list_for_each_safe_rcu(pos, next, &utrace->engines) {
+		engine = list_entry(pos, struct utrace_attached_engine, entry);
+		if (engine->flags & ev) {
+			if (is_exit)
+				REPORT(report_syscall_exit, regs);
+			else
+				REPORT(report_syscall_entry, regs);
+		}
+		if (action & UTRACE_ACTION_HIDE)
+			break;
+	}
+	action = check_detach(tsk, action);
+	check_quiescent(tsk, action);
+}
+
+// XXX copied from signal.c
+#ifdef SIGEMT
+#define M_SIGEMT	M(SIGEMT)
+#else
+#define M_SIGEMT	0
+#endif
+
+#if SIGRTMIN > BITS_PER_LONG
+#define M(sig) (1ULL << ((sig)-1))
+#else
+#define M(sig) (1UL << ((sig)-1))
+#endif
+#define T(sig, mask) (M(sig) & (mask))
+
+#define SIG_KERNEL_ONLY_MASK (\
+	M(SIGKILL)   |  M(SIGSTOP)                                   )
+
+#define SIG_KERNEL_STOP_MASK (\
+	M(SIGSTOP)   |  M(SIGTSTP)   |  M(SIGTTIN)   |  M(SIGTTOU)   )
+
+#define SIG_KERNEL_COREDUMP_MASK (\
+        M(SIGQUIT)   |  M(SIGILL)    |  M(SIGTRAP)   |  M(SIGABRT)   | \
+        M(SIGFPE)    |  M(SIGSEGV)   |  M(SIGBUS)    |  M(SIGSYS)    | \
+        M(SIGXCPU)   |  M(SIGXFSZ)   |  M_SIGEMT                     )
+
+#define SIG_KERNEL_IGNORE_MASK (\
+        M(SIGCONT)   |  M(SIGCHLD)   |  M(SIGWINCH)  |  M(SIGURG)    )
+
+#define sig_kernel_only(sig) \
+		(((sig) < SIGRTMIN)  && T(sig, SIG_KERNEL_ONLY_MASK))
+#define sig_kernel_coredump(sig) \
+		(((sig) < SIGRTMIN)  && T(sig, SIG_KERNEL_COREDUMP_MASK))
+#define sig_kernel_ignore(sig) \
+		(((sig) < SIGRTMIN)  && T(sig, SIG_KERNEL_IGNORE_MASK))
+#define sig_kernel_stop(sig) \
+		(((sig) < SIGRTMIN)  && T(sig, SIG_KERNEL_STOP_MASK))
+
+
+/*
+ * Call each interested tracing engine's report_signal callback.
+ */
+static u32
+report_signal(struct task_struct *tsk, struct pt_regs *regs,
+	      struct utrace *utrace, u32 action,
+	      unsigned long flags1, unsigned long flags2, siginfo_t *info,
+	      const struct k_sigaction *ka, struct k_sigaction *return_ka)
+{
+	struct list_head *pos, *next;
+	struct utrace_attached_engine *engine;
+
+	/* XXX must change for sharing */
+	list_for_each_safe_rcu(pos, next, &utrace->engines) {
+		engine = list_entry(pos, struct utrace_attached_engine, entry);
+		if ((engine->flags & flags1) && (engine->flags & flags2)) {
+			u32 disp = action & UTRACE_ACTION_OP_MASK;
+			action &= ~UTRACE_ACTION_OP_MASK;
+			REPORT(report_signal, regs, disp, info, ka, return_ka);
+			if ((action & UTRACE_ACTION_OP_MASK) == 0)
+				action |= disp;
+			if (action & UTRACE_ACTION_HIDE)
+				break;
+		}
+	}
+
+	return action;
+}
+
+void
+utrace_signal_handler_singlestep(struct task_struct *tsk, struct pt_regs *regs)
+{
+	u32 action;
+	action = report_signal(tsk, regs, tsk->utrace, UTRACE_SIGNAL_HANDLER,
+			       UTRACE_EVENT_SIGNAL_ALL,
+			       UTRACE_ACTION_SINGLESTEP|UTRACE_ACTION_BLOCKSTEP,
+			       NULL, NULL, NULL);
+	action = check_detach(tsk, action);
+	check_quiescent(tsk, action);
+}
+
+
+/*
+ * This is the hook from the signals code, called with the siglock held.
+ * Here is the ideal place to quiesce.  We also dequeue and intercept signals.
+ */
+int
+utrace_get_signal(struct task_struct *tsk, struct pt_regs *regs,
+		  siginfo_t *info, struct k_sigaction *return_ka)
+{
+	struct utrace *utrace = tsk->utrace;
+	struct utrace_signal signal = { info, return_ka, 0 };
+	struct k_sigaction *ka;
+	unsigned long action, event;
+
+#if 0				/* XXX */
+	if (tsk->signal->flags & SIGNAL_GROUP_SIGKILL)
+		return 0;
+#endif
+
+	/*
+	 * If we should quiesce, now is the time.
+	 * First stash a pointer to the state on our stack,
+	 * so that utrace_inject_signal can tell us what to do.
+	 */
+	if (utrace->u.live.signal == NULL)
+		utrace->u.live.signal = &signal;
+
+	if (tsk->utrace_flags & UTRACE_ACTION_QUIESCE) {
+		spin_unlock_irq(&tsk->sighand->siglock);
+		utrace_quiescent(tsk);
+		if (signal.signr == 0)
+			/*
+			 * This return value says to reacquire the siglock
+			 * and check again.  This will check for a pending
+			 * group stop and process it before coming back here.
+			 */
+			return -1;
+		spin_lock_irq(&tsk->sighand->siglock);
+	}
+
+	/*
+	 * If a signal was injected previously, it could not use our
+	 * stack space directly.  It had to allocate a data structure,
+	 * which we can now copy out of and free.
+	 */
+	if (utrace->u.live.signal != &signal) {
+		signal.signr = utrace->u.live.signal->signr;
+		copy_siginfo(info, utrace->u.live.signal->info);
+		if (utrace->u.live.signal->return_ka)
+			*return_ka = *utrace->u.live.signal->return_ka;
+		else
+			signal.return_ka = NULL;
+		kfree(utrace->u.live.signal);
+	}
+	utrace->u.live.signal = NULL;
+
+	/*
+	 * If a signal was injected, everything is in place now.  Go do it.
+	 */
+	if (signal.signr != 0) {
+		if (signal.return_ka == NULL) {
+			ka = &tsk->sighand->action[signal.signr - 1];
+			if (ka->sa.sa_flags & SA_ONESHOT)
+				ka->sa.sa_handler = SIG_DFL;
+			*return_ka = *ka;
+		}
+		else
+			BUG_ON(signal.return_ka != return_ka);
+		return signal.signr;
+	}
+
+	/*
+	 * If noone is interested in intercepting signals, let the caller
+	 * just dequeue them normally.
+	 */
+	if ((tsk->utrace_flags & UTRACE_EVENT_SIGNAL_ALL) == 0)
+		return 0;
+
+	/*
+	 * Steal the next signal so we can let tracing engines examine it.
+	 * From the signal number and sigaction, determine what normal
+	 * delivery would do.  If no engine perturbs it, we'll do that
+	 * by returning the signal number after setting *return_ka.
+	 */
+	signal.signr = dequeue_signal(tsk, &tsk->blocked, info);
+	if (signal.signr == 0)
+		return 0;
+
+	BUG_ON(signal.signr != info->si_signo);
+
+	ka = &tsk->sighand->action[signal.signr - 1];
+	*return_ka = *ka;
+
+	if (signal.signr == SIGKILL)
+		return signal.signr;
+
+	if (ka->sa.sa_handler == SIG_IGN) {
+		event = UTRACE_EVENT(SIGNAL_IGN);
+		action = UTRACE_SIGNAL_IGN;
+	}
+	else if (ka->sa.sa_handler != SIG_DFL) {
+		event = UTRACE_EVENT(SIGNAL);
+		action = UTRACE_ACTION_RESUME;
+	}
+	else if (sig_kernel_coredump(signal.signr)) {
+		event = UTRACE_EVENT(SIGNAL_CORE);
+		action = UTRACE_SIGNAL_CORE;
+	}
+	else if (sig_kernel_ignore(signal.signr)) {
+		event = UTRACE_EVENT(SIGNAL_IGN);
+		action = UTRACE_SIGNAL_IGN;
+	}
+	else if (sig_kernel_stop(signal.signr)) {
+		event = UTRACE_EVENT(SIGNAL_STOP);
+		action = (signal.signr == SIGSTOP
+			  ? UTRACE_SIGNAL_STOP : UTRACE_SIGNAL_TSTP);
+	}
+	else {
+		event = UTRACE_EVENT(SIGNAL_TERM);
+		action = UTRACE_SIGNAL_TERM;
+	}
+
+	if (tsk->utrace_flags & event) {
+		/*
+		 * We have some interested engines, so tell them about the
+		 * signal and let them change its disposition.
+		 */
+
+		spin_unlock_irq(&tsk->sighand->siglock);
+
+		action = report_signal(tsk, regs, utrace, action, event, event,
+				       info, ka, return_ka);
+		action &= UTRACE_ACTION_OP_MASK;
+
+		if (action & UTRACE_SIGNAL_HOLD) {
+			struct sigqueue *q = sigqueue_alloc();
+			if (likely(q != NULL)) {
+				q->flags = 0;
+				copy_siginfo(&q->info, info);
+			}
+			action &= ~UTRACE_SIGNAL_HOLD;
+			spin_lock_irq(&tsk->sighand->siglock);
+			sigaddset(&tsk->pending.signal, info->si_signo);
+			if (likely(q != NULL))
+				list_add(&q->list, &tsk->pending.list);
+		}
+		else
+			spin_lock_irq(&tsk->sighand->siglock);
+
+		recalc_sigpending_tsk(tsk);
+	}
+
+	if (tsk->utrace != utrace)
+		rcu_utrace_free(utrace);
+
+	/*
+	 * We express the chosen action to the signals code in terms
+	 * of a representative signal whose default action does it.
+	 */
+	switch (action) {
+	case UTRACE_SIGNAL_IGN:
+		/*
+		 * We've eaten the signal.  That's all we do.
+		 * Tell the caller to restart.
+		 */
+		spin_unlock_irq(&tsk->sighand->siglock);
+		return -1;
+
+	case UTRACE_ACTION_RESUME:
+	case UTRACE_SIGNAL_DELIVER:
+		/*
+		 * The handler will run.  We do the SA_ONESHOT work here
+		 * since the normal path will only touch *return_ka now.
+		 */
+		if (return_ka->sa.sa_flags & SA_ONESHOT)
+			ka->sa.sa_handler = SIG_DFL;
+		break;
+
+	case UTRACE_SIGNAL_TSTP:
+		signal.signr = SIGTSTP;
+		tsk->signal->flags |= SIGNAL_STOP_DEQUEUED;
+		return_ka->sa.sa_handler = SIG_DFL;
+		break;
+
+	case UTRACE_SIGNAL_STOP:
+		signal.signr = SIGSTOP;
+		tsk->signal->flags |= SIGNAL_STOP_DEQUEUED;
+		return_ka->sa.sa_handler = SIG_DFL;
+		break;
+
+	case UTRACE_SIGNAL_TERM:
+		signal.signr = SIGTERM;
+		return_ka->sa.sa_handler = SIG_DFL;
+		break;
+
+	case UTRACE_SIGNAL_CORE:
+		signal.signr = SIGQUIT;
+		return_ka->sa.sa_handler = SIG_DFL;
+		break;
+
+	default:
+		BUG();
+	}
+
+	return signal.signr;
+}
+
+
+/*
+ * Cause a specified signal delivery in the target thread,
+ * which must be quiescent.  The action has UTRACE_SIGNAL_* bits
+ * as returned from a report_signal callback.  If ka is non-null,
+ * it gives the sigaction to follow for UTRACE_SIGNAL_DELIVER;
+ * otherwise, the installed sigaction at the time of delivery is used.
+ */
+int
+utrace_inject_signal(struct task_struct *target,
+		    struct utrace_attached_engine *engine,
+		    u32 action, siginfo_t *info,
+		    const struct k_sigaction *ka)
+{
+	struct utrace *utrace;
+	struct utrace_signal *signal;
+	int ret;
+
+	if (info->si_signo == 0 || !valid_signal(info->si_signo))
+		return -EINVAL;
+
+	rcu_read_lock();
+	utrace = rcu_dereference(target->utrace);
+	if (utrace == NULL) {
+		rcu_read_unlock();
+		return -ESRCH;
+	}
+	utrace_lock(utrace);
+	rcu_read_unlock();
+
+	ret = 0;
+	signal = utrace->u.live.signal;
+	if (signal == NULL) {
+		ret = -ENOSYS;	/* XXX */
+	}
+	else if (signal->signr != 0)
+		ret = -EAGAIN;
+	else {
+		if (info != signal->info)
+			copy_siginfo(signal->info, info);
+
+		switch (action) {
+		default:
+			ret = -EINVAL;
+			break;
+
+		case UTRACE_SIGNAL_IGN:
+			break;
+
+		case UTRACE_ACTION_RESUME:
+		case UTRACE_SIGNAL_DELIVER:
+			/*
+			 * The handler will run.  We do the SA_ONESHOT work
+			 * here since the normal path will not touch the
+			 * real sigaction when using an injected signal.
+			 */
+			if (ka == NULL)
+				signal->return_ka = NULL;
+			else if (ka != signal->return_ka)
+				*signal->return_ka = *ka;
+			if (ka && ka->sa.sa_flags & SA_ONESHOT) {
+				struct k_sigaction *a;
+				a = &target->sighand->action[info->si_signo-1];
+				spin_lock_irq(&target->sighand->siglock);
+				a->sa.sa_handler = SIG_DFL;
+				spin_unlock_irq(&target->sighand->siglock);
+			}
+			signal->signr = info->si_signo;
+			break;
+
+		case UTRACE_SIGNAL_TSTP:
+			signal->signr = SIGTSTP;
+			spin_lock_irq(&target->sighand->siglock);
+			target->signal->flags |= SIGNAL_STOP_DEQUEUED;
+			spin_unlock_irq(&target->sighand->siglock);
+			signal->return_ka->sa.sa_handler = SIG_DFL;
+			break;
+
+		case UTRACE_SIGNAL_STOP:
+			signal->signr = SIGSTOP;
+			spin_lock_irq(&target->sighand->siglock);
+			target->signal->flags |= SIGNAL_STOP_DEQUEUED;
+			spin_unlock_irq(&target->sighand->siglock);
+			signal->return_ka->sa.sa_handler = SIG_DFL;
+			break;
+
+		case UTRACE_SIGNAL_TERM:
+			signal->signr = SIGTERM;
+			signal->return_ka->sa.sa_handler = SIG_DFL;
+			break;
+
+		case UTRACE_SIGNAL_CORE:
+			signal->signr = SIGQUIT;
+			signal->return_ka->sa.sa_handler = SIG_DFL;
+			break;
+		}
+	}
+
+	utrace_unlock(utrace);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(utrace_inject_signal);
+
+
+const struct utrace_regset *
+utrace_regset(struct task_struct *target,
+	      struct utrace_attached_engine *engine,
+	      const struct utrace_regset_view *view, int which)
+{
+	if (unlikely((unsigned) which >= view->n))
+		return NULL;
+
+	if (target != current)
+		wait_task_inactive(target);
+
+	return &view->regsets[which];
+}
+EXPORT_SYMBOL_GPL(utrace_regset);
+
+
+/*
+ * Return the task_struct for the task using ptrace on this one, or NULL.
+ * Must be called with rcu_read_lock held to keep the returned struct alive.
+ *
+ * At exec time, this may be called with task_lock(p) still held from when
+ * tracehook_unsafe_exec was just called.  In that case it must give
+ * results consistent with those unsafe_exec results, i.e. non-NULL if
+ * any LSM_UNSAFE_PTRACE_* bits were set.
+ *
+ * The value is also used to display after "TracerPid:" in /proc/PID/status,
+ * where it is called with only rcu_read_lock held.
+ */
+struct task_struct *
+utrace_tracer_task(struct task_struct *target)
+{
+	struct utrace *utrace;
+	struct task_struct *tracer = NULL;
+
+	utrace = rcu_dereference(target->utrace);
+	if (utrace != NULL) {
+		struct list_head *pos, *next;
+		struct utrace_attached_engine *engine;
+		const struct utrace_engine_ops *ops;
+		list_for_each_safe_rcu(pos, next, &utrace->engines) {
+			engine = list_entry(pos, struct utrace_attached_engine,
+					    entry);
+			ops = rcu_dereference(engine->ops);
+			if (ops->tracer_task) {
+				tracer = (*ops->tracer_task)(engine, target);
+				if (tracer != NULL)
+					break;
+			}
+		}
+	}
+
+	return tracer;
+}
+
+int
+utrace_allow_access_process_vm(struct task_struct *target)
+{
+	struct utrace *utrace;
+	int ret = 0;
+
+	rcu_read_lock();
+	utrace = rcu_dereference(target->utrace);
+	if (utrace != NULL) {
+		struct list_head *pos, *next;
+		struct utrace_attached_engine *engine;
+		const struct utrace_engine_ops *ops;
+		list_for_each_safe_rcu(pos, next, &utrace->engines) {
+			engine = list_entry(pos, struct utrace_attached_engine,
+					    entry);
+			ops = rcu_dereference(engine->ops);
+			if (ops->allow_access_process_vm) {
+				ret = (*ops->allow_access_process_vm)(engine,
+								      target,
+								      current);
+				if (ret)
+					break;
+			}
+		}
+	}
+	rcu_read_unlock();
+
+	return ret;
+}
+
+/*
+ * Called on the current task to return LSM_UNSAFE_* bits implied by tracing.
+ * Called with task_lock held.
+ */
+int
+utrace_unsafe_exec(struct task_struct *tsk)
+{
+	struct utrace *utrace = tsk->utrace;
+	struct list_head *pos, *next;
+	struct utrace_attached_engine *engine;
+	const struct utrace_engine_ops *ops;
+	int unsafe = 0;
+
+	/* XXX must change for sharing */
+	list_for_each_safe_rcu(pos, next, &utrace->engines) {
+		engine = list_entry(pos, struct utrace_attached_engine, entry);
+		ops = rcu_dereference(engine->ops);
+		if (ops->unsafe_exec)
+			unsafe |= (*ops->unsafe_exec)(engine, tsk);
+	}
+
+	return unsafe;
+}
diff --git a/lib/audit.c b/lib/audit.c
new file mode 100644
index 000000000..3b1289fad
--- /dev/null
+++ b/lib/audit.c
@@ -0,0 +1,55 @@
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/audit.h>
+#include <asm/unistd.h>
+
+static unsigned dir_class[] = {
+#include <asm-generic/audit_dir_write.h>
+~0U
+};
+
+static unsigned read_class[] = {
+#include <asm-generic/audit_read.h>
+~0U
+};
+
+static unsigned write_class[] = {
+#include <asm-generic/audit_write.h>
+~0U
+};
+
+static unsigned chattr_class[] = {
+#include <asm-generic/audit_change_attr.h>
+~0U
+};
+
+int audit_classify_syscall(int abi, unsigned syscall)
+{
+	switch(syscall) {
+	case __NR_open:
+		return 2;
+#ifdef __NR_openat
+	case __NR_openat:
+		return 3;
+#endif
+#ifdef __NR_socketcall
+	case __NR_socketcall:
+		return 4;
+#endif
+	case __NR_execve:
+		return 5;
+	default:
+		return 0;
+	}
+}
+
+static int __init audit_classes_init(void)
+{
+	audit_register_class(AUDIT_CLASS_WRITE, write_class);
+	audit_register_class(AUDIT_CLASS_READ, read_class);
+	audit_register_class(AUDIT_CLASS_DIR_WRITE, dir_class);
+	audit_register_class(AUDIT_CLASS_CHATTR, chattr_class);
+	return 0;
+}
+
+__initcall(audit_classes_init);
diff --git a/lib/debug_locks.c b/lib/debug_locks.c
new file mode 100644
index 000000000..0ef01d147
--- /dev/null
+++ b/lib/debug_locks.c
@@ -0,0 +1,45 @@
+/*
+ * lib/debug_locks.c
+ *
+ * Generic place for common debugging facilities for various locks:
+ * spinlocks, rwlocks, mutexes and rwsems.
+ *
+ * Started by Ingo Molnar:
+ *
+ *  Copyright (C) 2006 Red Hat, Inc., Ingo Molnar <mingo@redhat.com>
+ */
+#include <linux/rwsem.h>
+#include <linux/mutex.h>
+#include <linux/module.h>
+#include <linux/spinlock.h>
+#include <linux/debug_locks.h>
+
+/*
+ * We want to turn all lock-debugging facilities on/off at once,
+ * via a global flag. The reason is that once a single bug has been
+ * detected and reported, there might be cascade of followup bugs
+ * that would just muddy the log. So we report the first one and
+ * shut up after that.
+ */
+int debug_locks = 1;
+
+/*
+ * The locking-testsuite uses <debug_locks_silent> to get a
+ * 'silent failure': nothing is printed to the console when
+ * a locking bug is detected.
+ */
+int debug_locks_silent;
+
+/*
+ * Generic 'turn off all lock debugging' function:
+ */
+int debug_locks_off(void)
+{
+	if (xchg(&debug_locks, 0)) {
+		if (!debug_locks_silent) {
+			console_verbose();
+			return 1;
+		}
+	}
+	return 0;
+}
diff --git a/lib/list_debug.c b/lib/list_debug.c
new file mode 100644
index 000000000..1aae85cef
--- /dev/null
+++ b/lib/list_debug.c
@@ -0,0 +1,77 @@
+/*
+ * Copyright 2006, Red Hat, Inc., Dave Jones
+ * Released under the General Public License (GPL).
+ *
+ * This file contains the linked list implementations for
+ * DEBUG_LIST.
+ */
+
+#include <linux/module.h>
+#include <linux/list.h>
+
+/*
+ * Insert a new entry between two known consecutive entries.
+ *
+ * This is only for internal list manipulation where we know
+ * the prev/next entries already!
+ */
+
+void __list_add(struct list_head *new,
+			      struct list_head *prev,
+			      struct list_head *next)
+{
+	if (unlikely(next->prev != prev)) {
+		printk(KERN_ERR "list_add corruption. next->prev should be %p, but was %p\n",
+			prev, next->prev);
+		BUG();
+	}
+	if (unlikely(prev->next != next)) {
+		printk(KERN_ERR "list_add corruption. prev->next should be %p, but was %p\n",
+			next, prev->next);
+		BUG();
+	}
+	next->prev = new;
+	new->next = next;
+	new->prev = prev;
+	prev->next = new;
+}
+EXPORT_SYMBOL(__list_add);
+
+/**
+ * list_add - add a new entry
+ * @new: new entry to be added
+ * @head: list head to add it after
+ *
+ * Insert a new entry after the specified head.
+ * This is good for implementing stacks.
+ */
+void list_add(struct list_head *new, struct list_head *head)
+{
+	__list_add(new, head, head->next);
+}
+EXPORT_SYMBOL(list_add);
+
+/**
+ * list_del - deletes entry from list.
+ * @entry: the element to delete from the list.
+ * Note: list_empty on entry does not return true after this, the entry is
+ * in an undefined state.
+ */
+void list_del(struct list_head *entry)
+{
+	if (unlikely(entry->prev->next != entry)) {
+		printk(KERN_ERR "list_del corruption. prev->next should be %p, but was %p\n",
+			entry, entry->prev->next);
+		BUG();
+	}
+	if (unlikely(entry->next->prev != entry)) {
+		printk(KERN_ERR "list_del corruption. next->prev should be %p, but was %p\n",
+			entry, entry->next->prev);
+		BUG();
+	}
+	__list_del(entry->prev, entry->next);
+	entry->next = LIST_POISON1;
+	entry->prev = LIST_POISON2;
+}
+EXPORT_SYMBOL(list_del);
+
diff --git a/lib/locking-selftest-hardirq.h b/lib/locking-selftest-hardirq.h
new file mode 100644
index 000000000..10d4a150b
--- /dev/null
+++ b/lib/locking-selftest-hardirq.h
@@ -0,0 +1,9 @@
+#undef IRQ_DISABLE
+#undef IRQ_ENABLE
+#undef IRQ_ENTER
+#undef IRQ_EXIT
+
+#define IRQ_ENABLE		HARDIRQ_ENABLE
+#define IRQ_DISABLE		HARDIRQ_DISABLE
+#define IRQ_ENTER		HARDIRQ_ENTER
+#define IRQ_EXIT		HARDIRQ_EXIT
diff --git a/lib/locking-selftest-mutex.h b/lib/locking-selftest-mutex.h
new file mode 100644
index 000000000..68601b6f5
--- /dev/null
+++ b/lib/locking-selftest-mutex.h
@@ -0,0 +1,11 @@
+#undef LOCK
+#define LOCK		ML
+
+#undef UNLOCK
+#define UNLOCK		MU
+
+#undef RLOCK
+#undef WLOCK
+
+#undef INIT
+#define INIT		MI
diff --git a/lib/locking-selftest-rlock-hardirq.h b/lib/locking-selftest-rlock-hardirq.h
new file mode 100644
index 000000000..9f517ebcb
--- /dev/null
+++ b/lib/locking-selftest-rlock-hardirq.h
@@ -0,0 +1,2 @@
+#include "locking-selftest-rlock.h"
+#include "locking-selftest-hardirq.h"
diff --git a/lib/locking-selftest-rlock-softirq.h b/lib/locking-selftest-rlock-softirq.h
new file mode 100644
index 000000000..981455db7
--- /dev/null
+++ b/lib/locking-selftest-rlock-softirq.h
@@ -0,0 +1,2 @@
+#include "locking-selftest-rlock.h"
+#include "locking-selftest-softirq.h"
diff --git a/lib/locking-selftest-rlock.h b/lib/locking-selftest-rlock.h
new file mode 100644
index 000000000..6789044f4
--- /dev/null
+++ b/lib/locking-selftest-rlock.h
@@ -0,0 +1,14 @@
+#undef LOCK
+#define LOCK		RL
+
+#undef UNLOCK
+#define UNLOCK		RU
+
+#undef RLOCK
+#define RLOCK		RL
+
+#undef WLOCK
+#define WLOCK		WL
+
+#undef INIT
+#define INIT		RWI
diff --git a/lib/locking-selftest-rsem.h b/lib/locking-selftest-rsem.h
new file mode 100644
index 000000000..62da88668
--- /dev/null
+++ b/lib/locking-selftest-rsem.h
@@ -0,0 +1,14 @@
+#undef LOCK
+#define LOCK		RSL
+
+#undef UNLOCK
+#define UNLOCK		RSU
+
+#undef RLOCK
+#define RLOCK		RSL
+
+#undef WLOCK
+#define WLOCK		WSL
+
+#undef INIT
+#define INIT		RWSI
diff --git a/lib/locking-selftest-softirq.h b/lib/locking-selftest-softirq.h
new file mode 100644
index 000000000..a83de2a04
--- /dev/null
+++ b/lib/locking-selftest-softirq.h
@@ -0,0 +1,9 @@
+#undef IRQ_DISABLE
+#undef IRQ_ENABLE
+#undef IRQ_ENTER
+#undef IRQ_EXIT
+
+#define IRQ_DISABLE		SOFTIRQ_DISABLE
+#define IRQ_ENABLE		SOFTIRQ_ENABLE
+#define IRQ_ENTER		SOFTIRQ_ENTER
+#define IRQ_EXIT		SOFTIRQ_EXIT
diff --git a/lib/locking-selftest-spin-hardirq.h b/lib/locking-selftest-spin-hardirq.h
new file mode 100644
index 000000000..693198dce
--- /dev/null
+++ b/lib/locking-selftest-spin-hardirq.h
@@ -0,0 +1,2 @@
+#include "locking-selftest-spin.h"
+#include "locking-selftest-hardirq.h"
diff --git a/lib/locking-selftest-spin-softirq.h b/lib/locking-selftest-spin-softirq.h
new file mode 100644
index 000000000..c472e2a87
--- /dev/null
+++ b/lib/locking-selftest-spin-softirq.h
@@ -0,0 +1,2 @@
+#include "locking-selftest-spin.h"
+#include "locking-selftest-softirq.h"
diff --git a/lib/locking-selftest-spin.h b/lib/locking-selftest-spin.h
new file mode 100644
index 000000000..ccd1b4b09
--- /dev/null
+++ b/lib/locking-selftest-spin.h
@@ -0,0 +1,11 @@
+#undef LOCK
+#define LOCK		L
+
+#undef UNLOCK
+#define UNLOCK		U
+
+#undef RLOCK
+#undef WLOCK
+
+#undef INIT
+#define INIT		SI
diff --git a/lib/locking-selftest-wlock-hardirq.h b/lib/locking-selftest-wlock-hardirq.h
new file mode 100644
index 000000000..2dd2e5122
--- /dev/null
+++ b/lib/locking-selftest-wlock-hardirq.h
@@ -0,0 +1,2 @@
+#include "locking-selftest-wlock.h"
+#include "locking-selftest-hardirq.h"
diff --git a/lib/locking-selftest-wlock-softirq.h b/lib/locking-selftest-wlock-softirq.h
new file mode 100644
index 000000000..cb80d1cb9
--- /dev/null
+++ b/lib/locking-selftest-wlock-softirq.h
@@ -0,0 +1,2 @@
+#include "locking-selftest-wlock.h"
+#include "locking-selftest-softirq.h"
diff --git a/lib/locking-selftest-wlock.h b/lib/locking-selftest-wlock.h
new file mode 100644
index 000000000..0815322d9
--- /dev/null
+++ b/lib/locking-selftest-wlock.h
@@ -0,0 +1,14 @@
+#undef LOCK
+#define LOCK		WL
+
+#undef UNLOCK
+#define UNLOCK		WU
+
+#undef RLOCK
+#define RLOCK		RL
+
+#undef WLOCK
+#define WLOCK		WL
+
+#undef INIT
+#define INIT		RWI
diff --git a/lib/locking-selftest-wsem.h b/lib/locking-selftest-wsem.h
new file mode 100644
index 000000000..b88c5f2dc
--- /dev/null
+++ b/lib/locking-selftest-wsem.h
@@ -0,0 +1,14 @@
+#undef LOCK
+#define LOCK		WSL
+
+#undef UNLOCK
+#define UNLOCK		WSU
+
+#undef RLOCK
+#define RLOCK		RSL
+
+#undef WLOCK
+#define WLOCK		WSL
+
+#undef INIT
+#define INIT		RWSI
diff --git a/lib/locking-selftest.c b/lib/locking-selftest.c
new file mode 100644
index 000000000..7945787f4
--- /dev/null
+++ b/lib/locking-selftest.c
@@ -0,0 +1,1216 @@
+/*
+ * lib/locking-selftest.c
+ *
+ * Testsuite for various locking APIs: spinlocks, rwlocks,
+ * mutexes and rw-semaphores.
+ *
+ * It is checking both false positives and false negatives.
+ *
+ * Started by Ingo Molnar:
+ *
+ *  Copyright (C) 2006 Red Hat, Inc., Ingo Molnar <mingo@redhat.com>
+ */
+#include <linux/rwsem.h>
+#include <linux/mutex.h>
+#include <linux/sched.h>
+#include <linux/delay.h>
+#include <linux/module.h>
+#include <linux/lockdep.h>
+#include <linux/spinlock.h>
+#include <linux/kallsyms.h>
+#include <linux/interrupt.h>
+#include <linux/debug_locks.h>
+#include <linux/irqflags.h>
+
+/*
+ * Change this to 1 if you want to see the failure printouts:
+ */
+static unsigned int debug_locks_verbose;
+
+static int __init setup_debug_locks_verbose(char *str)
+{
+	get_option(&str, &debug_locks_verbose);
+
+	return 1;
+}
+
+__setup("debug_locks_verbose=", setup_debug_locks_verbose);
+
+#define FAILURE		0
+#define SUCCESS		1
+
+#define LOCKTYPE_SPIN	0x1
+#define LOCKTYPE_RWLOCK	0x2
+#define LOCKTYPE_MUTEX	0x4
+#define LOCKTYPE_RWSEM	0x8
+
+/*
+ * Normal standalone locks, for the circular and irq-context
+ * dependency tests:
+ */
+static DEFINE_SPINLOCK(lock_A);
+static DEFINE_SPINLOCK(lock_B);
+static DEFINE_SPINLOCK(lock_C);
+static DEFINE_SPINLOCK(lock_D);
+
+static DEFINE_RWLOCK(rwlock_A);
+static DEFINE_RWLOCK(rwlock_B);
+static DEFINE_RWLOCK(rwlock_C);
+static DEFINE_RWLOCK(rwlock_D);
+
+static DEFINE_MUTEX(mutex_A);
+static DEFINE_MUTEX(mutex_B);
+static DEFINE_MUTEX(mutex_C);
+static DEFINE_MUTEX(mutex_D);
+
+static DECLARE_RWSEM(rwsem_A);
+static DECLARE_RWSEM(rwsem_B);
+static DECLARE_RWSEM(rwsem_C);
+static DECLARE_RWSEM(rwsem_D);
+
+/*
+ * Locks that we initialize dynamically as well so that
+ * e.g. X1 and X2 becomes two instances of the same class,
+ * but X* and Y* are different classes. We do this so that
+ * we do not trigger a real lockup:
+ */
+static DEFINE_SPINLOCK(lock_X1);
+static DEFINE_SPINLOCK(lock_X2);
+static DEFINE_SPINLOCK(lock_Y1);
+static DEFINE_SPINLOCK(lock_Y2);
+static DEFINE_SPINLOCK(lock_Z1);
+static DEFINE_SPINLOCK(lock_Z2);
+
+static DEFINE_RWLOCK(rwlock_X1);
+static DEFINE_RWLOCK(rwlock_X2);
+static DEFINE_RWLOCK(rwlock_Y1);
+static DEFINE_RWLOCK(rwlock_Y2);
+static DEFINE_RWLOCK(rwlock_Z1);
+static DEFINE_RWLOCK(rwlock_Z2);
+
+static DEFINE_MUTEX(mutex_X1);
+static DEFINE_MUTEX(mutex_X2);
+static DEFINE_MUTEX(mutex_Y1);
+static DEFINE_MUTEX(mutex_Y2);
+static DEFINE_MUTEX(mutex_Z1);
+static DEFINE_MUTEX(mutex_Z2);
+
+static DECLARE_RWSEM(rwsem_X1);
+static DECLARE_RWSEM(rwsem_X2);
+static DECLARE_RWSEM(rwsem_Y1);
+static DECLARE_RWSEM(rwsem_Y2);
+static DECLARE_RWSEM(rwsem_Z1);
+static DECLARE_RWSEM(rwsem_Z2);
+
+/*
+ * non-inlined runtime initializers, to let separate locks share
+ * the same lock-class:
+ */
+#define INIT_CLASS_FUNC(class) 				\
+static noinline void					\
+init_class_##class(spinlock_t *lock, rwlock_t *rwlock, struct mutex *mutex, \
+		 struct rw_semaphore *rwsem)		\
+{							\
+	spin_lock_init(lock);				\
+	rwlock_init(rwlock);				\
+	mutex_init(mutex);				\
+	init_rwsem(rwsem);				\
+}
+
+INIT_CLASS_FUNC(X)
+INIT_CLASS_FUNC(Y)
+INIT_CLASS_FUNC(Z)
+
+static void init_shared_classes(void)
+{
+	init_class_X(&lock_X1, &rwlock_X1, &mutex_X1, &rwsem_X1);
+	init_class_X(&lock_X2, &rwlock_X2, &mutex_X2, &rwsem_X2);
+
+	init_class_Y(&lock_Y1, &rwlock_Y1, &mutex_Y1, &rwsem_Y1);
+	init_class_Y(&lock_Y2, &rwlock_Y2, &mutex_Y2, &rwsem_Y2);
+
+	init_class_Z(&lock_Z1, &rwlock_Z1, &mutex_Z1, &rwsem_Z1);
+	init_class_Z(&lock_Z2, &rwlock_Z2, &mutex_Z2, &rwsem_Z2);
+}
+
+/*
+ * For spinlocks and rwlocks we also do hardirq-safe / softirq-safe tests.
+ * The following functions use a lock from a simulated hardirq/softirq
+ * context, causing the locks to be marked as hardirq-safe/softirq-safe:
+ */
+
+#define HARDIRQ_DISABLE		local_irq_disable
+#define HARDIRQ_ENABLE		local_irq_enable
+
+#define HARDIRQ_ENTER()				\
+	local_irq_disable();			\
+	irq_enter();				\
+	WARN_ON(!in_irq());
+
+#define HARDIRQ_EXIT()				\
+	__irq_exit();				\
+	local_irq_enable();
+
+#define SOFTIRQ_DISABLE		local_bh_disable
+#define SOFTIRQ_ENABLE		local_bh_enable
+
+#define SOFTIRQ_ENTER()				\
+		local_bh_disable();		\
+		local_irq_disable();		\
+		trace_softirq_enter();		\
+		WARN_ON(!in_softirq());
+
+#define SOFTIRQ_EXIT()				\
+		trace_softirq_exit();		\
+		local_irq_enable();		\
+		local_bh_enable();
+
+/*
+ * Shortcuts for lock/unlock API variants, to keep
+ * the testcases compact:
+ */
+#define L(x)			spin_lock(&lock_##x)
+#define U(x)			spin_unlock(&lock_##x)
+#define LU(x)			L(x); U(x)
+#define SI(x)			spin_lock_init(&lock_##x)
+
+#define WL(x)			write_lock(&rwlock_##x)
+#define WU(x)			write_unlock(&rwlock_##x)
+#define WLU(x)			WL(x); WU(x)
+
+#define RL(x)			read_lock(&rwlock_##x)
+#define RU(x)			read_unlock(&rwlock_##x)
+#define RLU(x)			RL(x); RU(x)
+#define RWI(x)			rwlock_init(&rwlock_##x)
+
+#define ML(x)			mutex_lock(&mutex_##x)
+#define MU(x)			mutex_unlock(&mutex_##x)
+#define MI(x)			mutex_init(&mutex_##x)
+
+#define WSL(x)			down_write(&rwsem_##x)
+#define WSU(x)			up_write(&rwsem_##x)
+
+#define RSL(x)			down_read(&rwsem_##x)
+#define RSU(x)			up_read(&rwsem_##x)
+#define RWSI(x)			init_rwsem(&rwsem_##x)
+
+#define LOCK_UNLOCK_2(x,y)	LOCK(x); LOCK(y); UNLOCK(y); UNLOCK(x)
+
+/*
+ * Generate different permutations of the same testcase, using
+ * the same basic lock-dependency/state events:
+ */
+
+#define GENERATE_TESTCASE(name)			\
+						\
+static void name(void) { E(); }
+
+#define GENERATE_PERMUTATIONS_2_EVENTS(name)	\
+						\
+static void name##_12(void) { E1(); E2(); }	\
+static void name##_21(void) { E2(); E1(); }
+
+#define GENERATE_PERMUTATIONS_3_EVENTS(name)		\
+							\
+static void name##_123(void) { E1(); E2(); E3(); }	\
+static void name##_132(void) { E1(); E3(); E2(); }	\
+static void name##_213(void) { E2(); E1(); E3(); }	\
+static void name##_231(void) { E2(); E3(); E1(); }	\
+static void name##_312(void) { E3(); E1(); E2(); }	\
+static void name##_321(void) { E3(); E2(); E1(); }
+
+/*
+ * AA deadlock:
+ */
+
+#define E()					\
+						\
+	LOCK(X1);				\
+	LOCK(X2); /* this one should fail */
+
+/*
+ * 6 testcases:
+ */
+#include "locking-selftest-spin.h"
+GENERATE_TESTCASE(AA_spin)
+#include "locking-selftest-wlock.h"
+GENERATE_TESTCASE(AA_wlock)
+#include "locking-selftest-rlock.h"
+GENERATE_TESTCASE(AA_rlock)
+#include "locking-selftest-mutex.h"
+GENERATE_TESTCASE(AA_mutex)
+#include "locking-selftest-wsem.h"
+GENERATE_TESTCASE(AA_wsem)
+#include "locking-selftest-rsem.h"
+GENERATE_TESTCASE(AA_rsem)
+
+#undef E
+
+/*
+ * Special-case for read-locking, they are
+ * allowed to recurse on the same lock class:
+ */
+static void rlock_AA1(void)
+{
+	RL(X1);
+	RL(X1); // this one should NOT fail
+}
+
+static void rlock_AA1B(void)
+{
+	RL(X1);
+	RL(X2); // this one should NOT fail
+}
+
+static void rsem_AA1(void)
+{
+	RSL(X1);
+	RSL(X1); // this one should fail
+}
+
+static void rsem_AA1B(void)
+{
+	RSL(X1);
+	RSL(X2); // this one should fail
+}
+/*
+ * The mixing of read and write locks is not allowed:
+ */
+static void rlock_AA2(void)
+{
+	RL(X1);
+	WL(X2); // this one should fail
+}
+
+static void rsem_AA2(void)
+{
+	RSL(X1);
+	WSL(X2); // this one should fail
+}
+
+static void rlock_AA3(void)
+{
+	WL(X1);
+	RL(X2); // this one should fail
+}
+
+static void rsem_AA3(void)
+{
+	WSL(X1);
+	RSL(X2); // this one should fail
+}
+
+/*
+ * ABBA deadlock:
+ */
+
+#define E()					\
+						\
+	LOCK_UNLOCK_2(A, B);			\
+	LOCK_UNLOCK_2(B, A); /* fail */
+
+/*
+ * 6 testcases:
+ */
+#include "locking-selftest-spin.h"
+GENERATE_TESTCASE(ABBA_spin)
+#include "locking-selftest-wlock.h"
+GENERATE_TESTCASE(ABBA_wlock)
+#include "locking-selftest-rlock.h"
+GENERATE_TESTCASE(ABBA_rlock)
+#include "locking-selftest-mutex.h"
+GENERATE_TESTCASE(ABBA_mutex)
+#include "locking-selftest-wsem.h"
+GENERATE_TESTCASE(ABBA_wsem)
+#include "locking-selftest-rsem.h"
+GENERATE_TESTCASE(ABBA_rsem)
+
+#undef E
+
+/*
+ * AB BC CA deadlock:
+ */
+
+#define E()					\
+						\
+	LOCK_UNLOCK_2(A, B);			\
+	LOCK_UNLOCK_2(B, C);			\
+	LOCK_UNLOCK_2(C, A); /* fail */
+
+/*
+ * 6 testcases:
+ */
+#include "locking-selftest-spin.h"
+GENERATE_TESTCASE(ABBCCA_spin)
+#include "locking-selftest-wlock.h"
+GENERATE_TESTCASE(ABBCCA_wlock)
+#include "locking-selftest-rlock.h"
+GENERATE_TESTCASE(ABBCCA_rlock)
+#include "locking-selftest-mutex.h"
+GENERATE_TESTCASE(ABBCCA_mutex)
+#include "locking-selftest-wsem.h"
+GENERATE_TESTCASE(ABBCCA_wsem)
+#include "locking-selftest-rsem.h"
+GENERATE_TESTCASE(ABBCCA_rsem)
+
+#undef E
+
+/*
+ * AB CA BC deadlock:
+ */
+
+#define E()					\
+						\
+	LOCK_UNLOCK_2(A, B);			\
+	LOCK_UNLOCK_2(C, A);			\
+	LOCK_UNLOCK_2(B, C); /* fail */
+
+/*
+ * 6 testcases:
+ */
+#include "locking-selftest-spin.h"
+GENERATE_TESTCASE(ABCABC_spin)
+#include "locking-selftest-wlock.h"
+GENERATE_TESTCASE(ABCABC_wlock)
+#include "locking-selftest-rlock.h"
+GENERATE_TESTCASE(ABCABC_rlock)
+#include "locking-selftest-mutex.h"
+GENERATE_TESTCASE(ABCABC_mutex)
+#include "locking-selftest-wsem.h"
+GENERATE_TESTCASE(ABCABC_wsem)
+#include "locking-selftest-rsem.h"
+GENERATE_TESTCASE(ABCABC_rsem)
+
+#undef E
+
+/*
+ * AB BC CD DA deadlock:
+ */
+
+#define E()					\
+						\
+	LOCK_UNLOCK_2(A, B);			\
+	LOCK_UNLOCK_2(B, C);			\
+	LOCK_UNLOCK_2(C, D);			\
+	LOCK_UNLOCK_2(D, A); /* fail */
+
+/*
+ * 6 testcases:
+ */
+#include "locking-selftest-spin.h"
+GENERATE_TESTCASE(ABBCCDDA_spin)
+#include "locking-selftest-wlock.h"
+GENERATE_TESTCASE(ABBCCDDA_wlock)
+#include "locking-selftest-rlock.h"
+GENERATE_TESTCASE(ABBCCDDA_rlock)
+#include "locking-selftest-mutex.h"
+GENERATE_TESTCASE(ABBCCDDA_mutex)
+#include "locking-selftest-wsem.h"
+GENERATE_TESTCASE(ABBCCDDA_wsem)
+#include "locking-selftest-rsem.h"
+GENERATE_TESTCASE(ABBCCDDA_rsem)
+
+#undef E
+
+/*
+ * AB CD BD DA deadlock:
+ */
+#define E()					\
+						\
+	LOCK_UNLOCK_2(A, B);			\
+	LOCK_UNLOCK_2(C, D);			\
+	LOCK_UNLOCK_2(B, D);			\
+	LOCK_UNLOCK_2(D, A); /* fail */
+
+/*
+ * 6 testcases:
+ */
+#include "locking-selftest-spin.h"
+GENERATE_TESTCASE(ABCDBDDA_spin)
+#include "locking-selftest-wlock.h"
+GENERATE_TESTCASE(ABCDBDDA_wlock)
+#include "locking-selftest-rlock.h"
+GENERATE_TESTCASE(ABCDBDDA_rlock)
+#include "locking-selftest-mutex.h"
+GENERATE_TESTCASE(ABCDBDDA_mutex)
+#include "locking-selftest-wsem.h"
+GENERATE_TESTCASE(ABCDBDDA_wsem)
+#include "locking-selftest-rsem.h"
+GENERATE_TESTCASE(ABCDBDDA_rsem)
+
+#undef E
+
+/*
+ * AB CD BC DA deadlock:
+ */
+#define E()					\
+						\
+	LOCK_UNLOCK_2(A, B);			\
+	LOCK_UNLOCK_2(C, D);			\
+	LOCK_UNLOCK_2(B, C);			\
+	LOCK_UNLOCK_2(D, A); /* fail */
+
+/*
+ * 6 testcases:
+ */
+#include "locking-selftest-spin.h"
+GENERATE_TESTCASE(ABCDBCDA_spin)
+#include "locking-selftest-wlock.h"
+GENERATE_TESTCASE(ABCDBCDA_wlock)
+#include "locking-selftest-rlock.h"
+GENERATE_TESTCASE(ABCDBCDA_rlock)
+#include "locking-selftest-mutex.h"
+GENERATE_TESTCASE(ABCDBCDA_mutex)
+#include "locking-selftest-wsem.h"
+GENERATE_TESTCASE(ABCDBCDA_wsem)
+#include "locking-selftest-rsem.h"
+GENERATE_TESTCASE(ABCDBCDA_rsem)
+
+#undef E
+
+/*
+ * Double unlock:
+ */
+#define E()					\
+						\
+	LOCK(A);				\
+	UNLOCK(A);				\
+	UNLOCK(A); /* fail */
+
+/*
+ * 6 testcases:
+ */
+#include "locking-selftest-spin.h"
+GENERATE_TESTCASE(double_unlock_spin)
+#include "locking-selftest-wlock.h"
+GENERATE_TESTCASE(double_unlock_wlock)
+#include "locking-selftest-rlock.h"
+GENERATE_TESTCASE(double_unlock_rlock)
+#include "locking-selftest-mutex.h"
+GENERATE_TESTCASE(double_unlock_mutex)
+#include "locking-selftest-wsem.h"
+GENERATE_TESTCASE(double_unlock_wsem)
+#include "locking-selftest-rsem.h"
+GENERATE_TESTCASE(double_unlock_rsem)
+
+#undef E
+
+/*
+ * Bad unlock ordering:
+ */
+#define E()					\
+						\
+	LOCK(A);				\
+	LOCK(B);				\
+	UNLOCK(A); /* fail */			\
+	UNLOCK(B);
+
+/*
+ * 6 testcases:
+ */
+#include "locking-selftest-spin.h"
+GENERATE_TESTCASE(bad_unlock_order_spin)
+#include "locking-selftest-wlock.h"
+GENERATE_TESTCASE(bad_unlock_order_wlock)
+#include "locking-selftest-rlock.h"
+GENERATE_TESTCASE(bad_unlock_order_rlock)
+#include "locking-selftest-mutex.h"
+GENERATE_TESTCASE(bad_unlock_order_mutex)
+#include "locking-selftest-wsem.h"
+GENERATE_TESTCASE(bad_unlock_order_wsem)
+#include "locking-selftest-rsem.h"
+GENERATE_TESTCASE(bad_unlock_order_rsem)
+
+#undef E
+
+/*
+ * initializing a held lock:
+ */
+#define E()					\
+						\
+	LOCK(A);				\
+	INIT(A); /* fail */
+
+/*
+ * 6 testcases:
+ */
+#include "locking-selftest-spin.h"
+GENERATE_TESTCASE(init_held_spin)
+#include "locking-selftest-wlock.h"
+GENERATE_TESTCASE(init_held_wlock)
+#include "locking-selftest-rlock.h"
+GENERATE_TESTCASE(init_held_rlock)
+#include "locking-selftest-mutex.h"
+GENERATE_TESTCASE(init_held_mutex)
+#include "locking-selftest-wsem.h"
+GENERATE_TESTCASE(init_held_wsem)
+#include "locking-selftest-rsem.h"
+GENERATE_TESTCASE(init_held_rsem)
+
+#undef E
+
+/*
+ * locking an irq-safe lock with irqs enabled:
+ */
+#define E1()				\
+					\
+	IRQ_ENTER();			\
+	LOCK(A);			\
+	UNLOCK(A);			\
+	IRQ_EXIT();
+
+#define E2()				\
+					\
+	LOCK(A);			\
+	UNLOCK(A);
+
+/*
+ * Generate 24 testcases:
+ */
+#include "locking-selftest-spin-hardirq.h"
+GENERATE_PERMUTATIONS_2_EVENTS(irqsafe1_hard_spin)
+
+#include "locking-selftest-rlock-hardirq.h"
+GENERATE_PERMUTATIONS_2_EVENTS(irqsafe1_hard_rlock)
+
+#include "locking-selftest-wlock-hardirq.h"
+GENERATE_PERMUTATIONS_2_EVENTS(irqsafe1_hard_wlock)
+
+#include "locking-selftest-spin-softirq.h"
+GENERATE_PERMUTATIONS_2_EVENTS(irqsafe1_soft_spin)
+
+#include "locking-selftest-rlock-softirq.h"
+GENERATE_PERMUTATIONS_2_EVENTS(irqsafe1_soft_rlock)
+
+#include "locking-selftest-wlock-softirq.h"
+GENERATE_PERMUTATIONS_2_EVENTS(irqsafe1_soft_wlock)
+
+#undef E1
+#undef E2
+
+/*
+ * Enabling hardirqs with a softirq-safe lock held:
+ */
+#define E1()				\
+					\
+	SOFTIRQ_ENTER();		\
+	LOCK(A);			\
+	UNLOCK(A);			\
+	SOFTIRQ_EXIT();
+
+#define E2()				\
+					\
+	HARDIRQ_DISABLE();		\
+	LOCK(A);			\
+	HARDIRQ_ENABLE();		\
+	UNLOCK(A);
+
+/*
+ * Generate 12 testcases:
+ */
+#include "locking-selftest-spin.h"
+GENERATE_PERMUTATIONS_2_EVENTS(irqsafe2A_spin)
+
+#include "locking-selftest-wlock.h"
+GENERATE_PERMUTATIONS_2_EVENTS(irqsafe2A_wlock)
+
+#include "locking-selftest-rlock.h"
+GENERATE_PERMUTATIONS_2_EVENTS(irqsafe2A_rlock)
+
+#undef E1
+#undef E2
+
+/*
+ * Enabling irqs with an irq-safe lock held:
+ */
+#define E1()				\
+					\
+	IRQ_ENTER();			\
+	LOCK(A);			\
+	UNLOCK(A);			\
+	IRQ_EXIT();
+
+#define E2()				\
+					\
+	IRQ_DISABLE();			\
+	LOCK(A);			\
+	IRQ_ENABLE();			\
+	UNLOCK(A);
+
+/*
+ * Generate 24 testcases:
+ */
+#include "locking-selftest-spin-hardirq.h"
+GENERATE_PERMUTATIONS_2_EVENTS(irqsafe2B_hard_spin)
+
+#include "locking-selftest-rlock-hardirq.h"
+GENERATE_PERMUTATIONS_2_EVENTS(irqsafe2B_hard_rlock)
+
+#include "locking-selftest-wlock-hardirq.h"
+GENERATE_PERMUTATIONS_2_EVENTS(irqsafe2B_hard_wlock)
+
+#include "locking-selftest-spin-softirq.h"
+GENERATE_PERMUTATIONS_2_EVENTS(irqsafe2B_soft_spin)
+
+#include "locking-selftest-rlock-softirq.h"
+GENERATE_PERMUTATIONS_2_EVENTS(irqsafe2B_soft_rlock)
+
+#include "locking-selftest-wlock-softirq.h"
+GENERATE_PERMUTATIONS_2_EVENTS(irqsafe2B_soft_wlock)
+
+#undef E1
+#undef E2
+
+/*
+ * Acquiring a irq-unsafe lock while holding an irq-safe-lock:
+ */
+#define E1()				\
+					\
+	LOCK(A);			\
+	LOCK(B);			\
+	UNLOCK(B);			\
+	UNLOCK(A);			\
+
+#define E2()				\
+					\
+	LOCK(B);			\
+	UNLOCK(B);
+
+#define E3()				\
+					\
+	IRQ_ENTER();			\
+	LOCK(A);			\
+	UNLOCK(A);			\
+	IRQ_EXIT();
+
+/*
+ * Generate 36 testcases:
+ */
+#include "locking-selftest-spin-hardirq.h"
+GENERATE_PERMUTATIONS_3_EVENTS(irqsafe3_hard_spin)
+
+#include "locking-selftest-rlock-hardirq.h"
+GENERATE_PERMUTATIONS_3_EVENTS(irqsafe3_hard_rlock)
+
+#include "locking-selftest-wlock-hardirq.h"
+GENERATE_PERMUTATIONS_3_EVENTS(irqsafe3_hard_wlock)
+
+#include "locking-selftest-spin-softirq.h"
+GENERATE_PERMUTATIONS_3_EVENTS(irqsafe3_soft_spin)
+
+#include "locking-selftest-rlock-softirq.h"
+GENERATE_PERMUTATIONS_3_EVENTS(irqsafe3_soft_rlock)
+
+#include "locking-selftest-wlock-softirq.h"
+GENERATE_PERMUTATIONS_3_EVENTS(irqsafe3_soft_wlock)
+
+#undef E1
+#undef E2
+#undef E3
+
+/*
+ * If a lock turns into softirq-safe, but earlier it took
+ * a softirq-unsafe lock:
+ */
+
+#define E1()				\
+	IRQ_DISABLE();			\
+	LOCK(A);			\
+	LOCK(B);			\
+	UNLOCK(B);			\
+	UNLOCK(A);			\
+	IRQ_ENABLE();
+
+#define E2()				\
+	LOCK(B);			\
+	UNLOCK(B);
+
+#define E3()				\
+	IRQ_ENTER();			\
+	LOCK(A);			\
+	UNLOCK(A);			\
+	IRQ_EXIT();
+
+/*
+ * Generate 36 testcases:
+ */
+#include "locking-selftest-spin-hardirq.h"
+GENERATE_PERMUTATIONS_3_EVENTS(irqsafe4_hard_spin)
+
+#include "locking-selftest-rlock-hardirq.h"
+GENERATE_PERMUTATIONS_3_EVENTS(irqsafe4_hard_rlock)
+
+#include "locking-selftest-wlock-hardirq.h"
+GENERATE_PERMUTATIONS_3_EVENTS(irqsafe4_hard_wlock)
+
+#include "locking-selftest-spin-softirq.h"
+GENERATE_PERMUTATIONS_3_EVENTS(irqsafe4_soft_spin)
+
+#include "locking-selftest-rlock-softirq.h"
+GENERATE_PERMUTATIONS_3_EVENTS(irqsafe4_soft_rlock)
+
+#include "locking-selftest-wlock-softirq.h"
+GENERATE_PERMUTATIONS_3_EVENTS(irqsafe4_soft_wlock)
+
+#undef E1
+#undef E2
+#undef E3
+
+/*
+ * read-lock / write-lock irq inversion.
+ *
+ * Deadlock scenario:
+ *
+ * CPU#1 is at #1, i.e. it has write-locked A, but has not
+ * taken B yet.
+ *
+ * CPU#2 is at #2, i.e. it has locked B.
+ *
+ * Hardirq hits CPU#2 at point #2 and is trying to read-lock A.
+ *
+ * The deadlock occurs because CPU#1 will spin on B, and CPU#2
+ * will spin on A.
+ */
+
+#define E1()				\
+					\
+	IRQ_DISABLE();			\
+	WL(A);				\
+	LOCK(B);			\
+	UNLOCK(B);			\
+	WU(A);				\
+	IRQ_ENABLE();
+
+#define E2()				\
+					\
+	LOCK(B);			\
+	UNLOCK(B);
+
+#define E3()				\
+					\
+	IRQ_ENTER();			\
+	RL(A);				\
+	RU(A);				\
+	IRQ_EXIT();
+
+/*
+ * Generate 36 testcases:
+ */
+#include "locking-selftest-spin-hardirq.h"
+GENERATE_PERMUTATIONS_3_EVENTS(irq_inversion_hard_spin)
+
+#include "locking-selftest-rlock-hardirq.h"
+GENERATE_PERMUTATIONS_3_EVENTS(irq_inversion_hard_rlock)
+
+#include "locking-selftest-wlock-hardirq.h"
+GENERATE_PERMUTATIONS_3_EVENTS(irq_inversion_hard_wlock)
+
+#include "locking-selftest-spin-softirq.h"
+GENERATE_PERMUTATIONS_3_EVENTS(irq_inversion_soft_spin)
+
+#include "locking-selftest-rlock-softirq.h"
+GENERATE_PERMUTATIONS_3_EVENTS(irq_inversion_soft_rlock)
+
+#include "locking-selftest-wlock-softirq.h"
+GENERATE_PERMUTATIONS_3_EVENTS(irq_inversion_soft_wlock)
+
+#undef E1
+#undef E2
+#undef E3
+
+/*
+ * read-lock / write-lock recursion that is actually safe.
+ */
+
+#define E1()				\
+					\
+	IRQ_DISABLE();			\
+	WL(A);				\
+	WU(A);				\
+	IRQ_ENABLE();
+
+#define E2()				\
+					\
+	RL(A);				\
+	RU(A);				\
+
+#define E3()				\
+					\
+	IRQ_ENTER();			\
+	RL(A);				\
+	L(B);				\
+	U(B);				\
+	RU(A);				\
+	IRQ_EXIT();
+
+/*
+ * Generate 12 testcases:
+ */
+#include "locking-selftest-hardirq.h"
+GENERATE_PERMUTATIONS_3_EVENTS(irq_read_recursion_hard)
+
+#include "locking-selftest-softirq.h"
+GENERATE_PERMUTATIONS_3_EVENTS(irq_read_recursion_soft)
+
+#undef E1
+#undef E2
+#undef E3
+
+/*
+ * read-lock / write-lock recursion that is unsafe.
+ */
+
+#define E1()				\
+					\
+	IRQ_DISABLE();			\
+	L(B);				\
+	WL(A);				\
+	WU(A);				\
+	U(B);				\
+	IRQ_ENABLE();
+
+#define E2()				\
+					\
+	RL(A);				\
+	RU(A);				\
+
+#define E3()				\
+					\
+	IRQ_ENTER();			\
+	L(B);				\
+	U(B);				\
+	IRQ_EXIT();
+
+/*
+ * Generate 12 testcases:
+ */
+#include "locking-selftest-hardirq.h"
+// GENERATE_PERMUTATIONS_3_EVENTS(irq_read_recursion2_hard)
+
+#include "locking-selftest-softirq.h"
+// GENERATE_PERMUTATIONS_3_EVENTS(irq_read_recursion2_soft)
+
+#ifdef CONFIG_DEBUG_LOCK_ALLOC
+# define I_SPINLOCK(x)	lockdep_reset_lock(&lock_##x.dep_map)
+# define I_RWLOCK(x)	lockdep_reset_lock(&rwlock_##x.dep_map)
+# define I_MUTEX(x)	lockdep_reset_lock(&mutex_##x.dep_map)
+# define I_RWSEM(x)	lockdep_reset_lock(&rwsem_##x.dep_map)
+#else
+# define I_SPINLOCK(x)
+# define I_RWLOCK(x)
+# define I_MUTEX(x)
+# define I_RWSEM(x)
+#endif
+
+#define I1(x)					\
+	do {					\
+		I_SPINLOCK(x);			\
+		I_RWLOCK(x);			\
+		I_MUTEX(x);			\
+		I_RWSEM(x);			\
+	} while (0)
+
+#define I2(x)					\
+	do {					\
+		spin_lock_init(&lock_##x);	\
+		rwlock_init(&rwlock_##x);	\
+		mutex_init(&mutex_##x);		\
+		init_rwsem(&rwsem_##x);		\
+	} while (0)
+
+static void reset_locks(void)
+{
+	local_irq_disable();
+	I1(A); I1(B); I1(C); I1(D);
+	I1(X1); I1(X2); I1(Y1); I1(Y2); I1(Z1); I1(Z2);
+	lockdep_reset();
+	I2(A); I2(B); I2(C); I2(D);
+	init_shared_classes();
+	local_irq_enable();
+}
+
+#undef I
+
+static int testcase_total;
+static int testcase_successes;
+static int expected_testcase_failures;
+static int unexpected_testcase_failures;
+
+static void dotest(void (*testcase_fn)(void), int expected, int lockclass_mask)
+{
+	unsigned long saved_preempt_count = preempt_count();
+	int expected_failure = 0;
+
+	WARN_ON(irqs_disabled());
+
+	testcase_fn();
+	/*
+	 * Filter out expected failures:
+	 */
+#ifndef CONFIG_PROVE_LOCKING
+	if ((lockclass_mask & LOCKTYPE_SPIN) && debug_locks != expected)
+		expected_failure = 1;
+	if ((lockclass_mask & LOCKTYPE_RWLOCK) && debug_locks != expected)
+		expected_failure = 1;
+	if ((lockclass_mask & LOCKTYPE_MUTEX) && debug_locks != expected)
+		expected_failure = 1;
+	if ((lockclass_mask & LOCKTYPE_RWSEM) && debug_locks != expected)
+		expected_failure = 1;
+#endif
+	if (debug_locks != expected) {
+		if (expected_failure) {
+			expected_testcase_failures++;
+			printk("failed|");
+		} else {
+			unexpected_testcase_failures++;
+			printk("FAILED|");
+		}
+	} else {
+		testcase_successes++;
+		printk("  ok  |");
+	}
+	testcase_total++;
+
+	if (debug_locks_verbose)
+		printk(" lockclass mask: %x, debug_locks: %d, expected: %d\n",
+			lockclass_mask, debug_locks, expected);
+	/*
+	 * Some tests (e.g. double-unlock) might corrupt the preemption
+	 * count, so restore it:
+	 */
+	preempt_count() = saved_preempt_count;
+#ifdef CONFIG_TRACE_IRQFLAGS
+	if (softirq_count())
+		current->softirqs_enabled = 0;
+	else
+		current->softirqs_enabled = 1;
+#endif
+
+	reset_locks();
+}
+
+static inline void print_testname(const char *testname)
+{
+	printk("%33s:", testname);
+}
+
+#define DO_TESTCASE_1(desc, name, nr)				\
+	print_testname(desc"/"#nr);				\
+	dotest(name##_##nr, SUCCESS, LOCKTYPE_RWLOCK);		\
+	printk("\n");
+
+#define DO_TESTCASE_1B(desc, name, nr)				\
+	print_testname(desc"/"#nr);				\
+	dotest(name##_##nr, FAILURE, LOCKTYPE_RWLOCK);		\
+	printk("\n");
+
+#define DO_TESTCASE_3(desc, name, nr)				\
+	print_testname(desc"/"#nr);				\
+	dotest(name##_spin_##nr, FAILURE, LOCKTYPE_SPIN);	\
+	dotest(name##_wlock_##nr, FAILURE, LOCKTYPE_RWLOCK);	\
+	dotest(name##_rlock_##nr, SUCCESS, LOCKTYPE_RWLOCK);	\
+	printk("\n");
+
+#define DO_TESTCASE_3RW(desc, name, nr)				\
+	print_testname(desc"/"#nr);				\
+	dotest(name##_spin_##nr, FAILURE, LOCKTYPE_SPIN|LOCKTYPE_RWLOCK);\
+	dotest(name##_wlock_##nr, FAILURE, LOCKTYPE_RWLOCK);	\
+	dotest(name##_rlock_##nr, SUCCESS, LOCKTYPE_RWLOCK);	\
+	printk("\n");
+
+#define DO_TESTCASE_6(desc, name)				\
+	print_testname(desc);					\
+	dotest(name##_spin, FAILURE, LOCKTYPE_SPIN);		\
+	dotest(name##_wlock, FAILURE, LOCKTYPE_RWLOCK);		\
+	dotest(name##_rlock, FAILURE, LOCKTYPE_RWLOCK);		\
+	dotest(name##_mutex, FAILURE, LOCKTYPE_MUTEX);		\
+	dotest(name##_wsem, FAILURE, LOCKTYPE_RWSEM);		\
+	dotest(name##_rsem, FAILURE, LOCKTYPE_RWSEM);		\
+	printk("\n");
+
+#define DO_TESTCASE_6_SUCCESS(desc, name)			\
+	print_testname(desc);					\
+	dotest(name##_spin, SUCCESS, LOCKTYPE_SPIN);		\
+	dotest(name##_wlock, SUCCESS, LOCKTYPE_RWLOCK);		\
+	dotest(name##_rlock, SUCCESS, LOCKTYPE_RWLOCK);		\
+	dotest(name##_mutex, SUCCESS, LOCKTYPE_MUTEX);		\
+	dotest(name##_wsem, SUCCESS, LOCKTYPE_RWSEM);		\
+	dotest(name##_rsem, SUCCESS, LOCKTYPE_RWSEM);		\
+	printk("\n");
+
+/*
+ * 'read' variant: rlocks must not trigger.
+ */
+#define DO_TESTCASE_6R(desc, name)				\
+	print_testname(desc);					\
+	dotest(name##_spin, FAILURE, LOCKTYPE_SPIN);		\
+	dotest(name##_wlock, FAILURE, LOCKTYPE_RWLOCK);		\
+	dotest(name##_rlock, SUCCESS, LOCKTYPE_RWLOCK);		\
+	dotest(name##_mutex, FAILURE, LOCKTYPE_MUTEX);		\
+	dotest(name##_wsem, FAILURE, LOCKTYPE_RWSEM);		\
+	dotest(name##_rsem, FAILURE, LOCKTYPE_RWSEM);		\
+	printk("\n");
+
+#define DO_TESTCASE_2I(desc, name, nr)				\
+	DO_TESTCASE_1("hard-"desc, name##_hard, nr);		\
+	DO_TESTCASE_1("soft-"desc, name##_soft, nr);
+
+#define DO_TESTCASE_2IB(desc, name, nr)				\
+	DO_TESTCASE_1B("hard-"desc, name##_hard, nr);		\
+	DO_TESTCASE_1B("soft-"desc, name##_soft, nr);
+
+#define DO_TESTCASE_6I(desc, name, nr)				\
+	DO_TESTCASE_3("hard-"desc, name##_hard, nr);		\
+	DO_TESTCASE_3("soft-"desc, name##_soft, nr);
+
+#define DO_TESTCASE_6IRW(desc, name, nr)			\
+	DO_TESTCASE_3RW("hard-"desc, name##_hard, nr);		\
+	DO_TESTCASE_3RW("soft-"desc, name##_soft, nr);
+
+#define DO_TESTCASE_2x3(desc, name)				\
+	DO_TESTCASE_3(desc, name, 12);				\
+	DO_TESTCASE_3(desc, name, 21);
+
+#define DO_TESTCASE_2x6(desc, name)				\
+	DO_TESTCASE_6I(desc, name, 12);				\
+	DO_TESTCASE_6I(desc, name, 21);
+
+#define DO_TESTCASE_6x2(desc, name)				\
+	DO_TESTCASE_2I(desc, name, 123);			\
+	DO_TESTCASE_2I(desc, name, 132);			\
+	DO_TESTCASE_2I(desc, name, 213);			\
+	DO_TESTCASE_2I(desc, name, 231);			\
+	DO_TESTCASE_2I(desc, name, 312);			\
+	DO_TESTCASE_2I(desc, name, 321);
+
+#define DO_TESTCASE_6x2B(desc, name)				\
+	DO_TESTCASE_2IB(desc, name, 123);			\
+	DO_TESTCASE_2IB(desc, name, 132);			\
+	DO_TESTCASE_2IB(desc, name, 213);			\
+	DO_TESTCASE_2IB(desc, name, 231);			\
+	DO_TESTCASE_2IB(desc, name, 312);			\
+	DO_TESTCASE_2IB(desc, name, 321);
+
+#define DO_TESTCASE_6x6(desc, name)				\
+	DO_TESTCASE_6I(desc, name, 123);			\
+	DO_TESTCASE_6I(desc, name, 132);			\
+	DO_TESTCASE_6I(desc, name, 213);			\
+	DO_TESTCASE_6I(desc, name, 231);			\
+	DO_TESTCASE_6I(desc, name, 312);			\
+	DO_TESTCASE_6I(desc, name, 321);
+
+#define DO_TESTCASE_6x6RW(desc, name)				\
+	DO_TESTCASE_6IRW(desc, name, 123);			\
+	DO_TESTCASE_6IRW(desc, name, 132);			\
+	DO_TESTCASE_6IRW(desc, name, 213);			\
+	DO_TESTCASE_6IRW(desc, name, 231);			\
+	DO_TESTCASE_6IRW(desc, name, 312);			\
+	DO_TESTCASE_6IRW(desc, name, 321);
+
+
+void locking_selftest(void)
+{
+	/*
+	 * Got a locking failure before the selftest ran?
+	 */
+	if (!debug_locks) {
+		printk("----------------------------------\n");
+		printk("| Locking API testsuite disabled |\n");
+		printk("----------------------------------\n");
+		return;
+	}
+
+	/*
+	 * Run the testsuite:
+	 */
+	printk("------------------------\n");
+	printk("| Locking API testsuite:\n");
+	printk("----------------------------------------------------------------------------\n");
+	printk("                                 | spin |wlock |rlock |mutex | wsem | rsem |\n");
+	printk("  --------------------------------------------------------------------------\n");
+
+	init_shared_classes();
+	debug_locks_silent = !debug_locks_verbose;
+
+	DO_TESTCASE_6R("A-A deadlock", AA);
+	DO_TESTCASE_6R("A-B-B-A deadlock", ABBA);
+	DO_TESTCASE_6R("A-B-B-C-C-A deadlock", ABBCCA);
+	DO_TESTCASE_6R("A-B-C-A-B-C deadlock", ABCABC);
+	DO_TESTCASE_6R("A-B-B-C-C-D-D-A deadlock", ABBCCDDA);
+	DO_TESTCASE_6R("A-B-C-D-B-D-D-A deadlock", ABCDBDDA);
+	DO_TESTCASE_6R("A-B-C-D-B-C-D-A deadlock", ABCDBCDA);
+	DO_TESTCASE_6("double unlock", double_unlock);
+	DO_TESTCASE_6("initialize held", init_held);
+	DO_TESTCASE_6_SUCCESS("bad unlock order", bad_unlock_order);
+
+	printk("  --------------------------------------------------------------------------\n");
+	print_testname("recursive read-lock");
+	printk("             |");
+	dotest(rlock_AA1, SUCCESS, LOCKTYPE_RWLOCK);
+	printk("             |");
+	dotest(rsem_AA1, FAILURE, LOCKTYPE_RWSEM);
+	printk("\n");
+
+	print_testname("recursive read-lock #2");
+	printk("             |");
+	dotest(rlock_AA1B, SUCCESS, LOCKTYPE_RWLOCK);
+	printk("             |");
+	dotest(rsem_AA1B, FAILURE, LOCKTYPE_RWSEM);
+	printk("\n");
+
+	print_testname("mixed read-write-lock");
+	printk("             |");
+	dotest(rlock_AA2, FAILURE, LOCKTYPE_RWLOCK);
+	printk("             |");
+	dotest(rsem_AA2, FAILURE, LOCKTYPE_RWSEM);
+	printk("\n");
+
+	print_testname("mixed write-read-lock");
+	printk("             |");
+	dotest(rlock_AA3, FAILURE, LOCKTYPE_RWLOCK);
+	printk("             |");
+	dotest(rsem_AA3, FAILURE, LOCKTYPE_RWSEM);
+	printk("\n");
+
+	printk("  --------------------------------------------------------------------------\n");
+
+	/*
+	 * irq-context testcases:
+	 */
+	DO_TESTCASE_2x6("irqs-on + irq-safe-A", irqsafe1);
+	DO_TESTCASE_2x3("sirq-safe-A => hirqs-on", irqsafe2A);
+	DO_TESTCASE_2x6("safe-A + irqs-on", irqsafe2B);
+	DO_TESTCASE_6x6("safe-A + unsafe-B #1", irqsafe3);
+	DO_TESTCASE_6x6("safe-A + unsafe-B #2", irqsafe4);
+	DO_TESTCASE_6x6RW("irq lock-inversion", irq_inversion);
+
+	DO_TESTCASE_6x2("irq read-recursion", irq_read_recursion);
+//	DO_TESTCASE_6x2B("irq read-recursion #2", irq_read_recursion2);
+
+	if (unexpected_testcase_failures) {
+		printk("-----------------------------------------------------------------\n");
+		debug_locks = 0;
+		printk("BUG: %3d unexpected failures (out of %3d) - debugging disabled! |\n",
+			unexpected_testcase_failures, testcase_total);
+		printk("-----------------------------------------------------------------\n");
+	} else if (expected_testcase_failures && testcase_successes) {
+		printk("--------------------------------------------------------\n");
+		printk("%3d out of %3d testcases failed, as expected. |\n",
+			expected_testcase_failures, testcase_total);
+		printk("----------------------------------------------------\n");
+		debug_locks = 1;
+	} else if (expected_testcase_failures && !testcase_successes) {
+		printk("--------------------------------------------------------\n");
+		printk("All %3d testcases failed, as expected. |\n",
+			expected_testcase_failures);
+		printk("----------------------------------------\n");
+		debug_locks = 1;
+	} else {
+		printk("-------------------------------------------------------\n");
+		printk("Good, all %3d testcases passed! |\n",
+			testcase_successes);
+		printk("---------------------------------\n");
+		debug_locks = 1;
+	}
+	debug_locks_silent = 0;
+}
diff --git a/lib/percpu_counter.c b/lib/percpu_counter.c
new file mode 100644
index 000000000..850449080
--- /dev/null
+++ b/lib/percpu_counter.c
@@ -0,0 +1,46 @@
+/*
+ * Fast batching percpu counters.
+ */
+
+#include <linux/percpu_counter.h>
+#include <linux/module.h>
+
+void percpu_counter_mod(struct percpu_counter *fbc, s32 amount)
+{
+	long count;
+	s32 *pcount;
+	int cpu = get_cpu();
+
+	pcount = per_cpu_ptr(fbc->counters, cpu);
+	count = *pcount + amount;
+	if (count >= FBC_BATCH || count <= -FBC_BATCH) {
+		spin_lock(&fbc->lock);
+		fbc->count += count;
+		*pcount = 0;
+		spin_unlock(&fbc->lock);
+	} else {
+		*pcount = count;
+	}
+	put_cpu();
+}
+EXPORT_SYMBOL(percpu_counter_mod);
+
+/*
+ * Add up all the per-cpu counts, return the result.  This is a more accurate
+ * but much slower version of percpu_counter_read_positive()
+ */
+s64 percpu_counter_sum(struct percpu_counter *fbc)
+{
+	s64 ret;
+	int cpu;
+
+	spin_lock(&fbc->lock);
+	ret = fbc->count;
+	for_each_possible_cpu(cpu) {
+		s32 *pcount = per_cpu_ptr(fbc->counters, cpu);
+		ret += *pcount;
+	}
+	spin_unlock(&fbc->lock);
+	return ret < 0 ? 0 : ret;
+}
+EXPORT_SYMBOL(percpu_counter_sum);
diff --git a/lib/plist.c b/lib/plist.c
new file mode 100644
index 000000000..3074a0227
--- /dev/null
+++ b/lib/plist.c
@@ -0,0 +1,118 @@
+/*
+ * lib/plist.c
+ *
+ * Descending-priority-sorted double-linked list
+ *
+ * (C) 2002-2003 Intel Corp
+ * Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com>.
+ *
+ * 2001-2005 (c) MontaVista Software, Inc.
+ * Daniel Walker <dwalker@mvista.com>
+ *
+ * (C) 2005 Thomas Gleixner <tglx@linutronix.de>
+ *
+ * Simplifications of the original code by
+ * Oleg Nesterov <oleg@tv-sign.ru>
+ *
+ * Licensed under the FSF's GNU Public License v2 or later.
+ *
+ * Based on simple lists (include/linux/list.h).
+ *
+ * This file contains the add / del functions which are considered to
+ * be too large to inline. See include/linux/plist.h for further
+ * information.
+ */
+
+#include <linux/plist.h>
+#include <linux/spinlock.h>
+
+#ifdef CONFIG_DEBUG_PI_LIST
+
+static void plist_check_prev_next(struct list_head *t, struct list_head *p,
+				  struct list_head *n)
+{
+	if (n->prev != p || p->next != n) {
+		printk("top: %p, n: %p, p: %p\n", t, t->next, t->prev);
+		printk("prev: %p, n: %p, p: %p\n", p, p->next, p->prev);
+		printk("next: %p, n: %p, p: %p\n", n, n->next, n->prev);
+		WARN_ON(1);
+	}
+}
+
+static void plist_check_list(struct list_head *top)
+{
+	struct list_head *prev = top, *next = top->next;
+
+	plist_check_prev_next(top, prev, next);
+	while (next != top) {
+		prev = next;
+		next = prev->next;
+		plist_check_prev_next(top, prev, next);
+	}
+}
+
+static void plist_check_head(struct plist_head *head)
+{
+	WARN_ON(!head->lock);
+	if (head->lock)
+		WARN_ON_SMP(!spin_is_locked(head->lock));
+	plist_check_list(&head->prio_list);
+	plist_check_list(&head->node_list);
+}
+
+#else
+# define plist_check_head(h)	do { } while (0)
+#endif
+
+/**
+ * plist_add - add @node to @head
+ *
+ * @node:	&struct plist_node pointer
+ * @head:	&struct plist_head pointer
+ */
+void plist_add(struct plist_node *node, struct plist_head *head)
+{
+	struct plist_node *iter;
+
+	plist_check_head(head);
+	WARN_ON(!plist_node_empty(node));
+
+	list_for_each_entry(iter, &head->prio_list, plist.prio_list) {
+		if (node->prio < iter->prio)
+			goto lt_prio;
+		else if (node->prio == iter->prio) {
+			iter = list_entry(iter->plist.prio_list.next,
+					struct plist_node, plist.prio_list);
+			goto eq_prio;
+		}
+	}
+
+lt_prio:
+	list_add_tail(&node->plist.prio_list, &iter->plist.prio_list);
+eq_prio:
+	list_add_tail(&node->plist.node_list, &iter->plist.node_list);
+
+	plist_check_head(head);
+}
+
+/**
+ * plist_del - Remove a @node from plist.
+ *
+ * @node:	&struct plist_node pointer - entry to be removed
+ * @head:	&struct plist_head pointer - list head
+ */
+void plist_del(struct plist_node *node, struct plist_head *head)
+{
+	plist_check_head(head);
+
+	if (!list_empty(&node->plist.prio_list)) {
+		struct plist_node *next = plist_first(&node->plist);
+
+		list_move_tail(&next->plist.prio_list, &node->plist.prio_list);
+		list_del_init(&node->plist.prio_list);
+	}
+
+	list_del_init(&node->plist.node_list);
+
+	plist_check_head(head);
+}
diff --git a/lib/zlib_inflate/inflate.h b/lib/zlib_inflate/inflate.h
new file mode 100644
index 000000000..df8a6c920
--- /dev/null
+++ b/lib/zlib_inflate/inflate.h
@@ -0,0 +1,107 @@
+/* inflate.h -- internal inflate state definition
+ * Copyright (C) 1995-2004 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+   part of the implementation of the compression library and is
+   subject to change. Applications should only use zlib.h.
+ */
+
+/* Possible inflate modes between inflate() calls */
+typedef enum {
+    HEAD,       /* i: waiting for magic header */
+    FLAGS,      /* i: waiting for method and flags (gzip) */
+    TIME,       /* i: waiting for modification time (gzip) */
+    OS,         /* i: waiting for extra flags and operating system (gzip) */
+    EXLEN,      /* i: waiting for extra length (gzip) */
+    EXTRA,      /* i: waiting for extra bytes (gzip) */
+    NAME,       /* i: waiting for end of file name (gzip) */
+    COMMENT,    /* i: waiting for end of comment (gzip) */
+    HCRC,       /* i: waiting for header crc (gzip) */
+    DICTID,     /* i: waiting for dictionary check value */
+    DICT,       /* waiting for inflateSetDictionary() call */
+        TYPE,       /* i: waiting for type bits, including last-flag bit */
+        TYPEDO,     /* i: same, but skip check to exit inflate on new block */
+        STORED,     /* i: waiting for stored size (length and complement) */
+        COPY,       /* i/o: waiting for input or output to copy stored block */
+        TABLE,      /* i: waiting for dynamic block table lengths */
+        LENLENS,    /* i: waiting for code length code lengths */
+        CODELENS,   /* i: waiting for length/lit and distance code lengths */
+            LEN,        /* i: waiting for length/lit code */
+            LENEXT,     /* i: waiting for length extra bits */
+            DIST,       /* i: waiting for distance code */
+            DISTEXT,    /* i: waiting for distance extra bits */
+            MATCH,      /* o: waiting for output space to copy string */
+            LIT,        /* o: waiting for output space to write literal */
+    CHECK,      /* i: waiting for 32-bit check value */
+    LENGTH,     /* i: waiting for 32-bit length (gzip) */
+    DONE,       /* finished check, done -- remain here until reset */
+    BAD,        /* got a data error -- remain here until reset */
+    MEM,        /* got an inflate() memory error -- remain here until reset */
+    SYNC        /* looking for synchronization bytes to restart inflate() */
+} inflate_mode;
+
+/*
+    State transitions between above modes -
+
+    (most modes can go to the BAD or MEM mode -- not shown for clarity)
+
+    Process header:
+        HEAD -> (gzip) or (zlib)
+        (gzip) -> FLAGS -> TIME -> OS -> EXLEN -> EXTRA -> NAME
+        NAME -> COMMENT -> HCRC -> TYPE
+        (zlib) -> DICTID or TYPE
+        DICTID -> DICT -> TYPE
+    Read deflate blocks:
+            TYPE -> STORED or TABLE or LEN or CHECK
+            STORED -> COPY -> TYPE
+            TABLE -> LENLENS -> CODELENS -> LEN
+    Read deflate codes:
+                LEN -> LENEXT or LIT or TYPE
+                LENEXT -> DIST -> DISTEXT -> MATCH -> LEN
+                LIT -> LEN
+    Process trailer:
+        CHECK -> LENGTH -> DONE
+ */
+
+/* state maintained between inflate() calls.  Approximately 7K bytes. */
+struct inflate_state {
+    inflate_mode mode;          /* current inflate mode */
+    int last;                   /* true if processing last block */
+    int wrap;                   /* bit 0 true for zlib, bit 1 true for gzip */
+    int havedict;               /* true if dictionary provided */
+    int flags;                  /* gzip header method and flags (0 if zlib) */
+    unsigned dmax;              /* zlib header max distance (INFLATE_STRICT) */
+    unsigned long check;        /* protected copy of check value */
+    unsigned long total;        /* protected copy of output count */
+ /*   gz_headerp head; */           /* where to save gzip header information */
+        /* sliding window */
+    unsigned wbits;             /* log base 2 of requested window size */
+    unsigned wsize;             /* window size or zero if not using window */
+    unsigned whave;             /* valid bytes in the window */
+    unsigned write;             /* window write index */
+    unsigned char *window;  /* allocated sliding window, if needed */
+        /* bit accumulator */
+    unsigned long hold;         /* input bit accumulator */
+    unsigned bits;              /* number of bits in "in" */
+        /* for string and stored block copying */
+    unsigned length;            /* literal or length of data to copy */
+    unsigned offset;            /* distance back to copy string from */
+        /* for table and code decoding */
+    unsigned extra;             /* extra bits needed */
+        /* fixed and dynamic code tables */
+    code const *lencode;    /* starting table for length/literal codes */
+    code const *distcode;   /* starting table for distance codes */
+    unsigned lenbits;           /* index bits for lencode */
+    unsigned distbits;          /* index bits for distcode */
+        /* dynamic table building */
+    unsigned ncode;             /* number of code length code lengths */
+    unsigned nlen;              /* number of length code lengths */
+    unsigned ndist;             /* number of distance code lengths */
+    unsigned have;              /* number of code lengths in lens[] */
+    code *next;             /* next available space in codes[] */
+    unsigned short lens[320];   /* temporary storage for code lengths */
+    unsigned short work[288];   /* work area for code table building */
+    code codes[ENOUGH];         /* space for code tables */
+};
diff --git a/mm/vmstat.c b/mm/vmstat.c
new file mode 100644
index 000000000..321668aa6
--- /dev/null
+++ b/mm/vmstat.c
@@ -0,0 +1,701 @@
+/*
+ *  linux/mm/vmstat.c
+ *
+ *  Manages VM statistics
+ *  Copyright (C) 1991, 1992, 1993, 1994  Linus Torvalds
+ *
+ *  zoned VM statistics
+ *  Copyright (C) 2006 Silicon Graphics, Inc.,
+ *		Christoph Lameter <christoph@lameter.com>
+ */
+
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/cpu.h>
+
+void __get_zone_counts(unsigned long *active, unsigned long *inactive,
+			unsigned long *free, struct pglist_data *pgdat)
+{
+	struct zone *zones = pgdat->node_zones;
+	int i;
+
+	*active = 0;
+	*inactive = 0;
+	*free = 0;
+	for (i = 0; i < MAX_NR_ZONES; i++) {
+		*active += zones[i].nr_active;
+		*inactive += zones[i].nr_inactive;
+		*free += zones[i].free_pages;
+	}
+}
+
+void get_zone_counts(unsigned long *active,
+		unsigned long *inactive, unsigned long *free)
+{
+	struct pglist_data *pgdat;
+
+	*active = 0;
+	*inactive = 0;
+	*free = 0;
+	for_each_online_pgdat(pgdat) {
+		unsigned long l, m, n;
+		__get_zone_counts(&l, &m, &n, pgdat);
+		*active += l;
+		*inactive += m;
+		*free += n;
+	}
+}
+
+#ifdef CONFIG_VM_EVENT_COUNTERS
+DEFINE_PER_CPU(struct vm_event_state, vm_event_states) = {{0}};
+EXPORT_PER_CPU_SYMBOL(vm_event_states);
+
+static void sum_vm_events(unsigned long *ret, cpumask_t *cpumask)
+{
+	int cpu = 0;
+	int i;
+
+	memset(ret, 0, NR_VM_EVENT_ITEMS * sizeof(unsigned long));
+
+	cpu = first_cpu(*cpumask);
+	while (cpu < NR_CPUS) {
+		struct vm_event_state *this = &per_cpu(vm_event_states, cpu);
+
+		cpu = next_cpu(cpu, *cpumask);
+
+		if (cpu < NR_CPUS)
+			prefetch(&per_cpu(vm_event_states, cpu));
+
+
+		for (i = 0; i < NR_VM_EVENT_ITEMS; i++)
+			ret[i] += this->event[i];
+	}
+}
+
+/*
+ * Accumulate the vm event counters across all CPUs.
+ * The result is unavoidably approximate - it can change
+ * during and after execution of this function.
+*/
+void all_vm_events(unsigned long *ret)
+{
+	sum_vm_events(ret, &cpu_online_map);
+}
+EXPORT_SYMBOL_GPL(all_vm_events);
+
+#ifdef CONFIG_HOTPLUG
+/*
+ * Fold the foreign cpu events into our own.
+ *
+ * This is adding to the events on one processor
+ * but keeps the global counts constant.
+ */
+void vm_events_fold_cpu(int cpu)
+{
+	struct vm_event_state *fold_state = &per_cpu(vm_event_states, cpu);
+	int i;
+
+	for (i = 0; i < NR_VM_EVENT_ITEMS; i++) {
+		count_vm_events(i, fold_state->event[i]);
+		fold_state->event[i] = 0;
+	}
+}
+#endif /* CONFIG_HOTPLUG */
+
+#endif /* CONFIG_VM_EVENT_COUNTERS */
+
+/*
+ * Manage combined zone based / global counters
+ *
+ * vm_stat contains the global counters
+ */
+atomic_long_t vm_stat[NR_VM_ZONE_STAT_ITEMS];
+EXPORT_SYMBOL(vm_stat);
+
+#ifdef CONFIG_SMP
+
+static int calculate_threshold(struct zone *zone)
+{
+	int threshold;
+	int mem;	/* memory in 128 MB units */
+
+	/*
+	 * The threshold scales with the number of processors and the amount
+	 * of memory per zone. More memory means that we can defer updates for
+	 * longer, more processors could lead to more contention.
+ 	 * fls() is used to have a cheap way of logarithmic scaling.
+	 *
+	 * Some sample thresholds:
+	 *
+	 * Threshold	Processors	(fls)	Zonesize	fls(mem+1)
+	 * ------------------------------------------------------------------
+	 * 8		1		1	0.9-1 GB	4
+	 * 16		2		2	0.9-1 GB	4
+	 * 20 		2		2	1-2 GB		5
+	 * 24		2		2	2-4 GB		6
+	 * 28		2		2	4-8 GB		7
+	 * 32		2		2	8-16 GB		8
+	 * 4		2		2	<128M		1
+	 * 30		4		3	2-4 GB		5
+	 * 48		4		3	8-16 GB		8
+	 * 32		8		4	1-2 GB		4
+	 * 32		8		4	0.9-1GB		4
+	 * 10		16		5	<128M		1
+	 * 40		16		5	900M		4
+	 * 70		64		7	2-4 GB		5
+	 * 84		64		7	4-8 GB		6
+	 * 108		512		9	4-8 GB		6
+	 * 125		1024		10	8-16 GB		8
+	 * 125		1024		10	16-32 GB	9
+	 */
+
+	mem = zone->present_pages >> (27 - PAGE_SHIFT);
+
+	threshold = 2 * fls(num_online_cpus()) * (1 + fls(mem));
+
+	/*
+	 * Maximum threshold is 125
+	 */
+	threshold = min(125, threshold);
+
+	return threshold;
+}
+
+/*
+ * Refresh the thresholds for each zone.
+ */
+static void refresh_zone_stat_thresholds(void)
+{
+	struct zone *zone;
+	int cpu;
+	int threshold;
+
+	for_each_zone(zone) {
+
+		if (!zone->present_pages)
+			continue;
+
+		threshold = calculate_threshold(zone);
+
+		for_each_online_cpu(cpu)
+			zone_pcp(zone, cpu)->stat_threshold = threshold;
+	}
+}
+
+/*
+ * For use when we know that interrupts are disabled.
+ */
+void __mod_zone_page_state(struct zone *zone, enum zone_stat_item item,
+				int delta)
+{
+	struct per_cpu_pageset *pcp = zone_pcp(zone, smp_processor_id());
+	s8 *p = pcp->vm_stat_diff + item;
+	long x;
+
+	x = delta + *p;
+
+	if (unlikely(x > pcp->stat_threshold || x < -pcp->stat_threshold)) {
+		zone_page_state_add(x, zone, item);
+		x = 0;
+	}
+	*p = x;
+}
+EXPORT_SYMBOL(__mod_zone_page_state);
+
+/*
+ * For an unknown interrupt state
+ */
+void mod_zone_page_state(struct zone *zone, enum zone_stat_item item,
+					int delta)
+{
+	unsigned long flags;
+
+	local_irq_save(flags);
+	__mod_zone_page_state(zone, item, delta);
+	local_irq_restore(flags);
+}
+EXPORT_SYMBOL(mod_zone_page_state);
+
+/*
+ * Optimized increment and decrement functions.
+ *
+ * These are only for a single page and therefore can take a struct page *
+ * argument instead of struct zone *. This allows the inclusion of the code
+ * generated for page_zone(page) into the optimized functions.
+ *
+ * No overflow check is necessary and therefore the differential can be
+ * incremented or decremented in place which may allow the compilers to
+ * generate better code.
+ * The increment or decrement is known and therefore one boundary check can
+ * be omitted.
+ *
+ * NOTE: These functions are very performance sensitive. Change only
+ * with care.
+ *
+ * Some processors have inc/dec instructions that are atomic vs an interrupt.
+ * However, the code must first determine the differential location in a zone
+ * based on the processor number and then inc/dec the counter. There is no
+ * guarantee without disabling preemption that the processor will not change
+ * in between and therefore the atomicity vs. interrupt cannot be exploited
+ * in a useful way here.
+ */
+static void __inc_zone_state(struct zone *zone, enum zone_stat_item item)
+{
+	struct per_cpu_pageset *pcp = zone_pcp(zone, smp_processor_id());
+	s8 *p = pcp->vm_stat_diff + item;
+
+	(*p)++;
+
+	if (unlikely(*p > pcp->stat_threshold)) {
+		int overstep = pcp->stat_threshold / 2;
+
+		zone_page_state_add(*p + overstep, zone, item);
+		*p = -overstep;
+	}
+}
+
+void __inc_zone_page_state(struct page *page, enum zone_stat_item item)
+{
+	__inc_zone_state(page_zone(page), item);
+}
+EXPORT_SYMBOL(__inc_zone_page_state);
+
+void __dec_zone_page_state(struct page *page, enum zone_stat_item item)
+{
+	struct zone *zone = page_zone(page);
+	struct per_cpu_pageset *pcp = zone_pcp(zone, smp_processor_id());
+	s8 *p = pcp->vm_stat_diff + item;
+
+	(*p)--;
+
+	if (unlikely(*p < - pcp->stat_threshold)) {
+		int overstep = pcp->stat_threshold / 2;
+
+		zone_page_state_add(*p - overstep, zone, item);
+		*p = overstep;
+	}
+}
+EXPORT_SYMBOL(__dec_zone_page_state);
+
+void inc_zone_state(struct zone *zone, enum zone_stat_item item)
+{
+	unsigned long flags;
+
+	local_irq_save(flags);
+	__inc_zone_state(zone, item);
+	local_irq_restore(flags);
+}
+
+void inc_zone_page_state(struct page *page, enum zone_stat_item item)
+{
+	unsigned long flags;
+	struct zone *zone;
+
+	zone = page_zone(page);
+	local_irq_save(flags);
+	__inc_zone_state(zone, item);
+	local_irq_restore(flags);
+}
+EXPORT_SYMBOL(inc_zone_page_state);
+
+void dec_zone_page_state(struct page *page, enum zone_stat_item item)
+{
+	unsigned long flags;
+
+	local_irq_save(flags);
+	__dec_zone_page_state(page, item);
+	local_irq_restore(flags);
+}
+EXPORT_SYMBOL(dec_zone_page_state);
+
+/*
+ * Update the zone counters for one cpu.
+ */
+void refresh_cpu_vm_stats(int cpu)
+{
+	struct zone *zone;
+	int i;
+	unsigned long flags;
+
+	for_each_zone(zone) {
+		struct per_cpu_pageset *pcp;
+
+		pcp = zone_pcp(zone, cpu);
+
+		for (i = 0; i < NR_VM_ZONE_STAT_ITEMS; i++)
+			if (pcp->vm_stat_diff[i]) {
+				local_irq_save(flags);
+				zone_page_state_add(pcp->vm_stat_diff[i],
+					zone, i);
+				pcp->vm_stat_diff[i] = 0;
+				local_irq_restore(flags);
+			}
+	}
+}
+
+static void __refresh_cpu_vm_stats(void *dummy)
+{
+	refresh_cpu_vm_stats(smp_processor_id());
+}
+
+/*
+ * Consolidate all counters.
+ *
+ * Note that the result is less inaccurate but still inaccurate
+ * if concurrent processes are allowed to run.
+ */
+void refresh_vm_stats(void)
+{
+	on_each_cpu(__refresh_cpu_vm_stats, NULL, 0, 1);
+}
+EXPORT_SYMBOL(refresh_vm_stats);
+
+#endif
+
+#ifdef CONFIG_NUMA
+/*
+ * zonelist = the list of zones passed to the allocator
+ * z 	    = the zone from which the allocation occurred.
+ *
+ * Must be called with interrupts disabled.
+ */
+void zone_statistics(struct zonelist *zonelist, struct zone *z)
+{
+	if (z->zone_pgdat == zonelist->zones[0]->zone_pgdat) {
+		__inc_zone_state(z, NUMA_HIT);
+	} else {
+		__inc_zone_state(z, NUMA_MISS);
+		__inc_zone_state(zonelist->zones[0], NUMA_FOREIGN);
+	}
+	if (z->zone_pgdat == NODE_DATA(numa_node_id()))
+		__inc_zone_state(z, NUMA_LOCAL);
+	else
+		__inc_zone_state(z, NUMA_OTHER);
+}
+#endif
+
+#ifdef CONFIG_PROC_FS
+
+#include <linux/seq_file.h>
+
+static void *frag_start(struct seq_file *m, loff_t *pos)
+{
+	pg_data_t *pgdat;
+	loff_t node = *pos;
+	for (pgdat = first_online_pgdat();
+	     pgdat && node;
+	     pgdat = next_online_pgdat(pgdat))
+		--node;
+
+	return pgdat;
+}
+
+static void *frag_next(struct seq_file *m, void *arg, loff_t *pos)
+{
+	pg_data_t *pgdat = (pg_data_t *)arg;
+
+	(*pos)++;
+	return next_online_pgdat(pgdat);
+}
+
+static void frag_stop(struct seq_file *m, void *arg)
+{
+}
+
+/*
+ * This walks the free areas for each zone.
+ */
+static int frag_show(struct seq_file *m, void *arg)
+{
+	pg_data_t *pgdat = (pg_data_t *)arg;
+	struct zone *zone;
+	struct zone *node_zones = pgdat->node_zones;
+	unsigned long flags;
+	int order;
+
+	for (zone = node_zones; zone - node_zones < MAX_NR_ZONES; ++zone) {
+		if (!populated_zone(zone))
+			continue;
+
+		spin_lock_irqsave(&zone->lock, flags);
+		seq_printf(m, "Node %d, zone %8s ", pgdat->node_id, zone->name);
+		for (order = 0; order < MAX_ORDER; ++order)
+			seq_printf(m, "%6lu ", zone->free_area[order].nr_free);
+		spin_unlock_irqrestore(&zone->lock, flags);
+		seq_putc(m, '\n');
+	}
+	return 0;
+}
+
+struct seq_operations fragmentation_op = {
+	.start	= frag_start,
+	.next	= frag_next,
+	.stop	= frag_stop,
+	.show	= frag_show,
+};
+
+static char *vmstat_text[] = {
+	/* Zoned VM counters */
+	"nr_anon_pages",
+	"nr_mapped",
+	"nr_file_pages",
+	"nr_slab",
+	"nr_page_table_pages",
+	"nr_dirty",
+	"nr_writeback",
+	"nr_unstable",
+	"nr_bounce",
+
+#ifdef CONFIG_NUMA
+	"numa_hit",
+	"numa_miss",
+	"numa_foreign",
+	"numa_interleave",
+	"numa_local",
+	"numa_other",
+#endif
+
+#ifdef CONFIG_VM_EVENT_COUNTERS
+	"pgpgin",
+	"pgpgout",
+	"pswpin",
+	"pswpout",
+
+	"pgalloc_dma",
+	"pgalloc_dma32",
+	"pgalloc_normal",
+	"pgalloc_high",
+
+	"pgfree",
+	"pgactivate",
+	"pgdeactivate",
+
+	"pgfault",
+	"pgmajfault",
+
+	"pgrefill_dma",
+	"pgrefill_dma32",
+	"pgrefill_normal",
+	"pgrefill_high",
+
+	"pgsteal_dma",
+	"pgsteal_dma32",
+	"pgsteal_normal",
+	"pgsteal_high",
+
+	"pgscan_kswapd_dma",
+	"pgscan_kswapd_dma32",
+	"pgscan_kswapd_normal",
+	"pgscan_kswapd_high",
+
+	"pgscan_direct_dma",
+	"pgscan_direct_dma32",
+	"pgscan_direct_normal",
+	"pgscan_direct_high",
+
+	"pginodesteal",
+	"slabs_scanned",
+	"kswapd_steal",
+	"kswapd_inodesteal",
+	"pageoutrun",
+	"allocstall",
+
+	"pgrotated",
+#endif
+};
+
+/*
+ * Output information about zones in @pgdat.
+ */
+static int zoneinfo_show(struct seq_file *m, void *arg)
+{
+	pg_data_t *pgdat = arg;
+	struct zone *zone;
+	struct zone *node_zones = pgdat->node_zones;
+	unsigned long flags;
+
+	for (zone = node_zones; zone - node_zones < MAX_NR_ZONES; zone++) {
+		int i;
+
+		if (!populated_zone(zone))
+			continue;
+
+		spin_lock_irqsave(&zone->lock, flags);
+		seq_printf(m, "Node %d, zone %8s", pgdat->node_id, zone->name);
+		seq_printf(m,
+			   "\n  pages free     %lu"
+			   "\n        min      %lu"
+			   "\n        low      %lu"
+			   "\n        high     %lu"
+			   "\n        active   %lu"
+			   "\n        inactive %lu"
+			   "\n        scanned  %lu (a: %lu i: %lu)"
+			   "\n        spanned  %lu"
+			   "\n        present  %lu",
+			   zone->free_pages,
+			   zone->pages_min,
+			   zone->pages_low,
+			   zone->pages_high,
+			   zone->nr_active,
+			   zone->nr_inactive,
+			   zone->pages_scanned,
+			   zone->nr_scan_active, zone->nr_scan_inactive,
+			   zone->spanned_pages,
+			   zone->present_pages);
+
+		for (i = 0; i < NR_VM_ZONE_STAT_ITEMS; i++)
+			seq_printf(m, "\n    %-12s %lu", vmstat_text[i],
+					zone_page_state(zone, i));
+
+		seq_printf(m,
+			   "\n        protection: (%lu",
+			   zone->lowmem_reserve[0]);
+		for (i = 1; i < ARRAY_SIZE(zone->lowmem_reserve); i++)
+			seq_printf(m, ", %lu", zone->lowmem_reserve[i]);
+		seq_printf(m,
+			   ")"
+			   "\n  pagesets");
+		for_each_online_cpu(i) {
+			struct per_cpu_pageset *pageset;
+			int j;
+
+			pageset = zone_pcp(zone, i);
+			for (j = 0; j < ARRAY_SIZE(pageset->pcp); j++) {
+				if (pageset->pcp[j].count)
+					break;
+			}
+			if (j == ARRAY_SIZE(pageset->pcp))
+				continue;
+			for (j = 0; j < ARRAY_SIZE(pageset->pcp); j++) {
+				seq_printf(m,
+					   "\n    cpu: %i pcp: %i"
+					   "\n              count: %i"
+					   "\n              high:  %i"
+					   "\n              batch: %i",
+					   i, j,
+					   pageset->pcp[j].count,
+					   pageset->pcp[j].high,
+					   pageset->pcp[j].batch);
+			}
+#ifdef CONFIG_SMP
+			seq_printf(m, "\n  vm stats threshold: %d",
+					pageset->stat_threshold);
+#endif
+		}
+		seq_printf(m,
+			   "\n  all_unreclaimable: %u"
+			   "\n  prev_priority:     %i"
+			   "\n  start_pfn:         %lu",
+			   zone->all_unreclaimable,
+			   zone->prev_priority,
+			   zone->zone_start_pfn);
+		spin_unlock_irqrestore(&zone->lock, flags);
+		seq_putc(m, '\n');
+	}
+	return 0;
+}
+
+struct seq_operations zoneinfo_op = {
+	.start	= frag_start, /* iterate over all zones. The same as in
+			       * fragmentation. */
+	.next	= frag_next,
+	.stop	= frag_stop,
+	.show	= zoneinfo_show,
+};
+
+static void *vmstat_start(struct seq_file *m, loff_t *pos)
+{
+	unsigned long *v;
+#ifdef CONFIG_VM_EVENT_COUNTERS
+	unsigned long *e;
+#endif
+	int i;
+
+	if (*pos >= ARRAY_SIZE(vmstat_text))
+		return NULL;
+
+#ifdef CONFIG_VM_EVENT_COUNTERS
+	v = kmalloc(NR_VM_ZONE_STAT_ITEMS * sizeof(unsigned long)
+			+ sizeof(struct vm_event_state), GFP_KERNEL);
+#else
+	v = kmalloc(NR_VM_ZONE_STAT_ITEMS * sizeof(unsigned long),
+			GFP_KERNEL);
+#endif
+	m->private = v;
+	if (!v)
+		return ERR_PTR(-ENOMEM);
+	for (i = 0; i < NR_VM_ZONE_STAT_ITEMS; i++)
+		v[i] = global_page_state(i);
+#ifdef CONFIG_VM_EVENT_COUNTERS
+	e = v + NR_VM_ZONE_STAT_ITEMS;
+	all_vm_events(e);
+	e[PGPGIN] /= 2;		/* sectors -> kbytes */
+	e[PGPGOUT] /= 2;
+#endif
+	return v + *pos;
+}
+
+static void *vmstat_next(struct seq_file *m, void *arg, loff_t *pos)
+{
+	(*pos)++;
+	if (*pos >= ARRAY_SIZE(vmstat_text))
+		return NULL;
+	return (unsigned long *)m->private + *pos;
+}
+
+static int vmstat_show(struct seq_file *m, void *arg)
+{
+	unsigned long *l = arg;
+	unsigned long off = l - (unsigned long *)m->private;
+
+	seq_printf(m, "%s %lu\n", vmstat_text[off], *l);
+	return 0;
+}
+
+static void vmstat_stop(struct seq_file *m, void *arg)
+{
+	kfree(m->private);
+	m->private = NULL;
+}
+
+struct seq_operations vmstat_op = {
+	.start	= vmstat_start,
+	.next	= vmstat_next,
+	.stop	= vmstat_stop,
+	.show	= vmstat_show,
+};
+
+#endif /* CONFIG_PROC_FS */
+
+#ifdef CONFIG_SMP
+/*
+ * Use the cpu notifier to insure that the thresholds are recalculated
+ * when necessary.
+ */
+static int __cpuinit vmstat_cpuup_callback(struct notifier_block *nfb,
+		unsigned long action,
+		void *hcpu)
+{
+	switch (action) {
+		case CPU_UP_PREPARE:
+		case CPU_UP_CANCELED:
+		case CPU_DEAD:
+			refresh_zone_stat_thresholds();
+			break;
+		default:
+			break;
+	}
+	return NOTIFY_OK;
+}
+
+static struct notifier_block __cpuinitdata vmstat_notifier =
+	{ &vmstat_cpuup_callback, NULL, 0 };
+
+int __init setup_vmstat(void)
+{
+	refresh_zone_stat_thresholds();
+	register_cpu_notifier(&vmstat_notifier);
+	return 0;
+}
+module_init(setup_vmstat)
+#endif
diff --git a/net/atm/atm_sysfs.c b/net/atm/atm_sysfs.c
new file mode 100644
index 000000000..c0a4ae28f
--- /dev/null
+++ b/net/atm/atm_sysfs.c
@@ -0,0 +1,175 @@
+/* ATM driver model support. */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/kobject.h>
+#include <linux/atmdev.h>
+#include "common.h"
+#include "resources.h"
+
+#define to_atm_dev(cldev) container_of(cldev, struct atm_dev, class_dev)
+
+static ssize_t show_type(struct class_device *cdev, char *buf)
+{
+	struct atm_dev *adev = to_atm_dev(cdev);
+	return sprintf(buf, "%s\n", adev->type);
+}
+
+static ssize_t show_address(struct class_device *cdev, char *buf)
+{
+	char *pos = buf;
+	struct atm_dev *adev = to_atm_dev(cdev);
+	int i;
+
+	for (i = 0; i < (ESI_LEN - 1); i++)
+		pos += sprintf(pos, "%02x:", adev->esi[i]);
+	pos += sprintf(pos, "%02x\n", adev->esi[i]);
+
+	return pos - buf;
+}
+
+static ssize_t show_atmaddress(struct class_device *cdev, char *buf)
+{
+        unsigned long flags;
+	char *pos = buf;
+	struct atm_dev *adev = to_atm_dev(cdev);
+        struct atm_dev_addr *aaddr;
+	int bin[] = { 1, 2, 10, 6, 1 }, *fmt = bin;
+	int i, j;
+
+        spin_lock_irqsave(&adev->lock, flags);
+        list_for_each_entry(aaddr, &adev->local, entry) {
+		for(i = 0, j = 0; i < ATM_ESA_LEN; ++i, ++j) {
+			if (j == *fmt) {
+				pos += sprintf(pos, ".");
+				++fmt;
+				j = 0;
+			}
+			pos += sprintf(pos, "%02x", aaddr->addr.sas_addr.prv[i]);
+		}
+		pos += sprintf(pos, "\n");
+	}
+        spin_unlock_irqrestore(&adev->lock, flags);
+
+	return pos - buf;
+}
+
+static ssize_t show_carrier(struct class_device *cdev, char *buf)
+{
+	char *pos = buf;
+	struct atm_dev *adev = to_atm_dev(cdev);
+
+	pos += sprintf(pos, "%d\n",
+		       adev->signal == ATM_PHY_SIG_LOST ? 0 : 1);
+		
+	return pos - buf;
+}
+
+static ssize_t show_link_rate(struct class_device *cdev, char *buf)
+{
+	char *pos = buf;
+	struct atm_dev *adev = to_atm_dev(cdev);
+	int link_rate;
+
+	/* show the link rate, not the data rate */
+	switch (adev->link_rate) {
+		case ATM_OC3_PCR:
+			link_rate = 155520000;
+			break;
+		case ATM_OC12_PCR:
+			link_rate = 622080000;
+			break;
+		case ATM_25_PCR:
+			link_rate = 25600000;
+			break;
+		default:
+			link_rate = adev->link_rate * 8 * 53;
+	}
+	pos += sprintf(pos, "%d\n", link_rate);
+		
+	return pos - buf;
+}
+
+static CLASS_DEVICE_ATTR(address, S_IRUGO, show_address, NULL);
+static CLASS_DEVICE_ATTR(atmaddress, S_IRUGO, show_atmaddress, NULL);
+static CLASS_DEVICE_ATTR(carrier, S_IRUGO, show_carrier, NULL);
+static CLASS_DEVICE_ATTR(type, S_IRUGO, show_type, NULL);
+static CLASS_DEVICE_ATTR(link_rate, S_IRUGO, show_link_rate, NULL);
+
+static struct class_device_attribute *atm_attrs[] = {
+	&class_device_attr_atmaddress,
+	&class_device_attr_address,
+	&class_device_attr_carrier,
+	&class_device_attr_type,
+	&class_device_attr_link_rate,
+	NULL
+};
+
+static int atm_uevent(struct class_device *cdev, char **envp, int num_envp, char *buf, int size)
+{
+	struct atm_dev *adev;
+	int i = 0, len = 0;
+
+	if (!cdev)
+		return -ENODEV;
+
+	adev = to_atm_dev(cdev);
+	if (!adev)
+		return -ENODEV;
+
+	if (add_uevent_var(envp, num_envp, &i, buf, size, &len,
+			   "NAME=%s%d", adev->type, adev->number))
+		return -ENOMEM;
+
+	envp[i] = NULL;
+	return 0;
+}
+
+static void atm_release(struct class_device *cdev)
+{
+	struct atm_dev *adev = to_atm_dev(cdev);
+
+	kfree(adev);
+}
+
+static struct class atm_class = {
+	.name		= "atm",
+	.release	= atm_release,
+	.uevent		= atm_uevent,
+};
+
+int atm_register_sysfs(struct atm_dev *adev)
+{
+	struct class_device *cdev = &adev->class_dev;
+	int i, err;
+
+	cdev->class = &atm_class;
+	class_set_devdata(cdev, adev);
+
+	snprintf(cdev->class_id, BUS_ID_SIZE, "%s%d", adev->type, adev->number);
+	err = class_device_register(cdev);
+	if (err < 0)
+		return err;
+
+	for (i = 0; atm_attrs[i]; i++)
+		class_device_create_file(cdev, atm_attrs[i]);
+
+	return 0;
+}
+
+void atm_unregister_sysfs(struct atm_dev *adev)
+{
+	struct class_device *cdev = &adev->class_dev;
+
+	class_device_del(cdev);
+}
+
+int __init atm_sysfs_init(void)
+{
+	return class_register(&atm_class);
+}
+
+void __exit atm_sysfs_exit(void)
+{
+	class_unregister(&atm_class);
+}
diff --git a/net/bridge/br_netlink.c b/net/bridge/br_netlink.c
new file mode 100644
index 000000000..53086fb75
--- /dev/null
+++ b/net/bridge/br_netlink.c
@@ -0,0 +1,200 @@
+/*
+ *	Bridge netlink control interface
+ *
+ *	Authors:
+ *	Stephen Hemminger		<shemminger@osdl.org>
+ *
+ *	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/kernel.h>
+#include <linux/rtnetlink.h>
+#include "br_private.h"
+
+/*
+ * Create one netlink message for one interface
+ * Contains port and master info as well as carrier and bridge state.
+ */
+static int br_fill_ifinfo(struct sk_buff *skb, const struct net_bridge_port *port,
+			  u32 pid, u32 seq, int event, unsigned int flags)
+{
+	const struct net_bridge *br = port->br;
+	const struct net_device *dev = port->dev;
+	struct ifinfomsg *r;
+	struct nlmsghdr *nlh;
+	unsigned char *b = skb->tail;
+	u32 mtu = dev->mtu;
+	u8 operstate = netif_running(dev) ? dev->operstate : IF_OPER_DOWN;
+	u8 portstate = port->state;
+
+	pr_debug("br_fill_info event %d port %s master %s\n",
+		 event, dev->name, br->dev->name);
+
+	nlh = NLMSG_NEW(skb, pid, seq, event, sizeof(*r), flags);
+	r = NLMSG_DATA(nlh);
+	r->ifi_family = AF_BRIDGE;
+	r->__ifi_pad = 0;
+	r->ifi_type = dev->type;
+	r->ifi_index = dev->ifindex;
+	r->ifi_flags = dev_get_flags(dev);
+	r->ifi_change = 0;
+
+	RTA_PUT(skb, IFLA_IFNAME, strlen(dev->name)+1, dev->name);
+
+	RTA_PUT(skb, IFLA_MASTER, sizeof(int), &br->dev->ifindex);
+
+	if (dev->addr_len)
+		RTA_PUT(skb, IFLA_ADDRESS, dev->addr_len, dev->dev_addr);
+
+	RTA_PUT(skb, IFLA_MTU, sizeof(mtu), &mtu);
+	if (dev->ifindex != dev->iflink)
+		RTA_PUT(skb, IFLA_LINK, sizeof(int), &dev->iflink);
+
+
+	RTA_PUT(skb, IFLA_OPERSTATE, sizeof(operstate), &operstate);
+
+	if (event == RTM_NEWLINK)
+		RTA_PUT(skb, IFLA_PROTINFO, sizeof(portstate), &portstate);
+
+	nlh->nlmsg_len = skb->tail - b;
+
+	return skb->len;
+
+nlmsg_failure:
+rtattr_failure:
+
+	skb_trim(skb, b - skb->data);
+	return -EINVAL;
+}
+
+/*
+ * Notify listeners of a change in port information
+ */
+void br_ifinfo_notify(int event, struct net_bridge_port *port)
+{
+	struct sk_buff *skb;
+	int err = -ENOMEM;
+
+	pr_debug("bridge notify event=%d\n", event);
+	skb = alloc_skb(NLMSG_SPACE(sizeof(struct ifinfomsg) + 128),
+			GFP_ATOMIC);
+	if (!skb)
+		goto err_out;
+
+	err = br_fill_ifinfo(skb, port, current->pid, 0, event, 0);
+	if (err < 0)
+		goto err_kfree;
+
+	NETLINK_CB(skb).dst_group = RTNLGRP_LINK;
+	netlink_broadcast(rtnl, skb, 0, RTNLGRP_LINK, GFP_ATOMIC);
+	return;
+
+err_kfree:
+	kfree_skb(skb);
+err_out:
+	netlink_set_err(rtnl, 0, RTNLGRP_LINK, err);
+}
+
+/*
+ * Dump information about all ports, in response to GETLINK
+ */
+static int br_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb)
+{
+	struct net_device *dev;
+	int idx;
+	int s_idx = cb->args[0];
+	int err = 0;
+
+	read_lock(&dev_base_lock);
+	for (dev = dev_base, idx = 0; dev; dev = dev->next) {
+		struct net_bridge_port *p = dev->br_port;
+
+		/* not a bridge port */
+		if (!p)
+			continue;
+
+		if (idx < s_idx)
+			goto cont;
+
+		err = br_fill_ifinfo(skb, p, NETLINK_CB(cb->skb).pid,
+				     cb->nlh->nlmsg_seq, RTM_NEWLINK, NLM_F_MULTI);
+		if (err <= 0)
+			break;
+cont:
+		++idx;
+	}
+	read_unlock(&dev_base_lock);
+
+	cb->args[0] = idx;
+
+	return skb->len;
+}
+
+/*
+ * Change state of port (ie from forwarding to blocking etc)
+ * Used by spanning tree in user space.
+ */
+static int br_rtm_setlink(struct sk_buff *skb,  struct nlmsghdr *nlh, void *arg)
+{
+	struct rtattr  **rta = arg;
+	struct ifinfomsg *ifm = NLMSG_DATA(nlh);
+	struct net_device *dev;
+	struct net_bridge_port *p;
+	u8 new_state;
+
+	if (ifm->ifi_family != AF_BRIDGE)
+		return -EPFNOSUPPORT;
+
+	/* Must pass valid state as PROTINFO */
+	if (rta[IFLA_PROTINFO-1]) {
+		u8 *pstate = RTA_DATA(rta[IFLA_PROTINFO-1]);
+		new_state = *pstate;
+	} else
+		return -EINVAL;
+
+	if (new_state > BR_STATE_BLOCKING)
+		return -EINVAL;
+
+	/* Find bridge port */
+	dev = __dev_get_by_index(ifm->ifi_index);
+	if (!dev)
+		return -ENODEV;
+
+	p = dev->br_port;
+	if (!p)
+		return -EINVAL;
+
+	/* if kernel STP is running, don't allow changes */
+	if (p->br->stp_enabled)
+		return -EBUSY;
+
+	if (!netif_running(dev))
+		return -ENETDOWN;
+
+	if (!netif_carrier_ok(dev) && new_state != BR_STATE_DISABLED)
+		return -ENETDOWN;
+
+	p->state = new_state;
+	br_log_state(p);
+	return 0;
+}
+
+
+static struct rtnetlink_link bridge_rtnetlink_table[RTM_NR_MSGTYPES] = {
+	[RTM_GETLINK - RTM_BASE] = { .dumpit	= br_dump_ifinfo, },
+	[RTM_SETLINK - RTM_BASE] = { .doit      = br_rtm_setlink, },
+};
+
+void __init br_netlink_init(void)
+{
+	rtnetlink_links[PF_BRIDGE] = bridge_rtnetlink_table;
+}
+
+void __exit br_netlink_fini(void)
+{
+	rtnetlink_links[PF_BRIDGE] = NULL;
+}
+
diff --git a/net/core/netevent.c b/net/core/netevent.c
new file mode 100644
index 000000000..35d02c385
--- /dev/null
+++ b/net/core/netevent.c
@@ -0,0 +1,69 @@
+/*
+ *	Network event notifiers
+ *
+ *	Authors:
+ *      Tom Tucker             <tom@opengridcomputing.com>
+ *      Steve Wise             <swise@opengridcomputing.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.
+ *
+ *	Fixes:
+ */
+
+#include <linux/rtnetlink.h>
+#include <linux/notifier.h>
+
+static ATOMIC_NOTIFIER_HEAD(netevent_notif_chain);
+
+/**
+ *	register_netevent_notifier - register a netevent notifier block
+ *	@nb: notifier
+ *
+ *	Register a notifier to be called when a netevent occurs.
+ *	The notifier passed is linked into the kernel structures and must
+ *	not be reused until it has been unregistered. A negative errno code
+ *	is returned on a failure.
+ */
+int register_netevent_notifier(struct notifier_block *nb)
+{
+	int err;
+
+	err = atomic_notifier_chain_register(&netevent_notif_chain, nb);
+	return err;
+}
+
+/**
+ *	netevent_unregister_notifier - unregister a netevent notifier block
+ *	@nb: notifier
+ *
+ *	Unregister a notifier previously registered by
+ *	register_neigh_notifier(). The notifier is unlinked into the
+ *	kernel structures and may then be reused. A negative errno code
+ *	is returned on a failure.
+ */
+
+int unregister_netevent_notifier(struct notifier_block *nb)
+{
+	return atomic_notifier_chain_unregister(&netevent_notif_chain, nb);
+}
+
+/**
+ *	call_netevent_notifiers - call all netevent notifier blocks
+ *      @val: value passed unmodified to notifier function
+ *      @v:   pointer passed unmodified to notifier function
+ *
+ *	Call all neighbour notifier blocks.  Parameters and return value
+ *	are as for notifier_call_chain().
+ */
+
+int call_netevent_notifiers(unsigned long val, void *v)
+{
+	return atomic_notifier_call_chain(&netevent_notif_chain, val, v);
+}
+
+EXPORT_SYMBOL_GPL(register_netevent_notifier);
+EXPORT_SYMBOL_GPL(unregister_netevent_notifier);
+EXPORT_SYMBOL_GPL(call_netevent_notifiers);
diff --git a/net/core/user_dma.c b/net/core/user_dma.c
new file mode 100644
index 000000000..248a6b666
--- /dev/null
+++ b/net/core/user_dma.c
@@ -0,0 +1,132 @@
+/*
+ * Copyright(c) 2004 - 2006 Intel Corporation. All rights reserved.
+ * Portions based on net/core/datagram.c and copyrighted by their 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., 59
+ * Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called COPYING.
+ */
+
+/*
+ * This code allows the net stack to make use of a DMA engine for
+ * skb to iovec copies.
+ */
+
+#include <linux/dmaengine.h>
+#include <linux/socket.h>
+#include <linux/rtnetlink.h> /* for BUG_TRAP */
+#include <net/tcp.h>
+#include <net/netdma.h>
+
+#define NET_DMA_DEFAULT_COPYBREAK 4096
+
+int sysctl_tcp_dma_copybreak = NET_DMA_DEFAULT_COPYBREAK;
+
+/**
+ *	dma_skb_copy_datagram_iovec - Copy a datagram to an iovec.
+ *	@skb - buffer to copy
+ *	@offset - offset in the buffer to start copying from
+ *	@iovec - io vector to copy to
+ *	@len - amount of data to copy from buffer to iovec
+ *	@pinned_list - locked iovec buffer data
+ *
+ *	Note: the iovec is modified during the copy.
+ */
+int dma_skb_copy_datagram_iovec(struct dma_chan *chan,
+			struct sk_buff *skb, int offset, struct iovec *to,
+			size_t len, struct dma_pinned_list *pinned_list)
+{
+	int start = skb_headlen(skb);
+	int i, copy = start - offset;
+	dma_cookie_t cookie = 0;
+
+	/* Copy header. */
+	if (copy > 0) {
+		if (copy > len)
+			copy = len;
+		cookie = dma_memcpy_to_iovec(chan, to, pinned_list,
+		                            skb->data + offset, copy);
+		if (cookie < 0)
+			goto fault;
+		len -= copy;
+		if (len == 0)
+			goto end;
+		offset += copy;
+	}
+
+	/* Copy paged appendix. Hmm... why does this look so complicated? */
+	for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
+		int end;
+
+		BUG_TRAP(start <= offset + len);
+
+		end = start + skb_shinfo(skb)->frags[i].size;
+		copy = end - offset;
+		if ((copy = end - offset) > 0) {
+			skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
+			struct page *page = frag->page;
+
+			if (copy > len)
+				copy = len;
+
+			cookie = dma_memcpy_pg_to_iovec(chan, to, pinned_list, page,
+					frag->page_offset + offset - start, copy);
+			if (cookie < 0)
+				goto fault;
+			len -= copy;
+			if (len == 0)
+				goto end;
+			offset += copy;
+		}
+		start = end;
+	}
+
+	if (skb_shinfo(skb)->frag_list) {
+		struct sk_buff *list = skb_shinfo(skb)->frag_list;
+
+		for (; list; list = list->next) {
+			int end;
+
+			BUG_TRAP(start <= offset + len);
+
+			end = start + list->len;
+			copy = end - offset;
+			if (copy > 0) {
+				if (copy > len)
+					copy = len;
+				cookie = dma_skb_copy_datagram_iovec(chan, list,
+				                offset - start, to, copy,
+				                pinned_list);
+				if (cookie < 0)
+					goto fault;
+				len -= copy;
+				if (len == 0)
+					goto end;
+				offset += copy;
+			}
+			start = end;
+		}
+	}
+
+end:
+	if (!len) {
+		skb->dma_cookie = cookie;
+		return cookie;
+	}
+
+fault:
+ 	return -EFAULT;
+}
diff --git a/net/ipv4/netfilter/ip_conntrack_sip.c b/net/ipv4/netfilter/ip_conntrack_sip.c
new file mode 100644
index 000000000..2893e9c74
--- /dev/null
+++ b/net/ipv4/netfilter/ip_conntrack_sip.c
@@ -0,0 +1,470 @@
+/* SIP extension for IP connection tracking.
+ *
+ * (C) 2005 by Christian Hentschel <chentschel@arnet.com.ar>
+ * based on RR's ip_conntrack_ftp.c and other modules.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/ctype.h>
+#include <linux/skbuff.h>
+#include <linux/in.h>
+#include <linux/ip.h>
+#include <linux/udp.h>
+
+#include <linux/netfilter.h>
+#include <linux/netfilter_ipv4.h>
+#include <linux/netfilter_ipv4/ip_conntrack_helper.h>
+#include <linux/netfilter_ipv4/ip_conntrack_sip.h>
+
+#if 0
+#define DEBUGP printk
+#else
+#define DEBUGP(format, args...)
+#endif
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Christian Hentschel <chentschel@arnet.com.ar>");
+MODULE_DESCRIPTION("SIP connection tracking helper");
+
+#define MAX_PORTS	8
+static unsigned short ports[MAX_PORTS];
+static int ports_c;
+module_param_array(ports, ushort, &ports_c, 0400);
+MODULE_PARM_DESC(ports, "port numbers of sip servers");
+
+static unsigned int sip_timeout = SIP_TIMEOUT;
+module_param(sip_timeout, uint, 0600);
+MODULE_PARM_DESC(sip_timeout, "timeout for the master SIP session");
+
+unsigned int (*ip_nat_sip_hook)(struct sk_buff **pskb,
+				enum ip_conntrack_info ctinfo,
+				struct ip_conntrack *ct,
+				const char **dptr);
+EXPORT_SYMBOL_GPL(ip_nat_sip_hook);
+
+unsigned int (*ip_nat_sdp_hook)(struct sk_buff **pskb,
+				enum ip_conntrack_info ctinfo,
+				struct ip_conntrack_expect *exp,
+				const char *dptr);
+EXPORT_SYMBOL_GPL(ip_nat_sdp_hook);
+
+int ct_sip_get_info(const char *dptr, size_t dlen,
+				unsigned int *matchoff,
+				unsigned int *matchlen,
+				struct sip_header_nfo *hnfo);
+EXPORT_SYMBOL_GPL(ct_sip_get_info);
+
+
+static int digits_len(const char *dptr, const char *limit, int *shift);
+static int epaddr_len(const char *dptr, const char *limit, int *shift);
+static int skp_digits_len(const char *dptr, const char *limit, int *shift);
+static int skp_epaddr_len(const char *dptr, const char *limit, int *shift);
+
+struct sip_header_nfo ct_sip_hdrs[] = {
+	{ 	/* Via header */
+		.lname		= "Via:",
+		.lnlen		= sizeof("Via:") - 1,
+		.sname		= "\r\nv:",
+		.snlen		= sizeof("\r\nv:") - 1, /* rfc3261 "\r\n" */
+		.ln_str		= "UDP ",
+		.ln_strlen	= sizeof("UDP ") - 1,
+		.match_len	= epaddr_len,
+	},
+	{ 	/* Contact header */
+		.lname		= "Contact:",
+		.lnlen		= sizeof("Contact:") - 1,
+		.sname		= "\r\nm:",
+		.snlen		= sizeof("\r\nm:") - 1,
+		.ln_str		= "sip:",
+		.ln_strlen	= sizeof("sip:") - 1,
+		.match_len	= skp_epaddr_len
+	},
+	{ 	/* Content length header */
+		.lname		= "Content-Length:",
+		.lnlen		= sizeof("Content-Length:") - 1,
+		.sname		= "\r\nl:",
+		.snlen		= sizeof("\r\nl:") - 1,
+		.ln_str		= ":",
+		.ln_strlen	= sizeof(":") - 1,
+		.match_len	= skp_digits_len
+	},
+	{	/* SDP media info */
+		.lname		= "\nm=",
+		.lnlen		= sizeof("\nm=") - 1,
+		.sname		= "\rm=",
+		.snlen		= sizeof("\rm=") - 1,
+		.ln_str		= "audio ",
+		.ln_strlen	= sizeof("audio ") - 1,
+		.match_len	= digits_len
+	},
+	{ 	/* SDP owner address*/
+		.lname		= "\no=",
+		.lnlen		= sizeof("\no=") - 1,
+		.sname		= "\ro=",
+		.snlen		= sizeof("\ro=") - 1,
+		.ln_str		= "IN IP4 ",
+		.ln_strlen	= sizeof("IN IP4 ") - 1,
+		.match_len	= epaddr_len
+	},
+	{ 	/* SDP connection info */
+		.lname		= "\nc=",
+		.lnlen		= sizeof("\nc=") - 1,
+		.sname		= "\rc=",
+		.snlen		= sizeof("\rc=") - 1,
+		.ln_str		= "IN IP4 ",
+		.ln_strlen	= sizeof("IN IP4 ") - 1,
+		.match_len	= epaddr_len
+	},
+	{ 	/* Requests headers */
+		.lname		= "sip:",
+		.lnlen		= sizeof("sip:") - 1,
+		.sname		= "sip:",
+		.snlen		= sizeof("sip:") - 1, /* yes, i know.. ;) */
+		.ln_str		= "@",
+		.ln_strlen	= sizeof("@") - 1,
+		.match_len	= epaddr_len
+	},
+	{ 	/* SDP version header */
+		.lname		= "\nv=",
+		.lnlen		= sizeof("\nv=") - 1,
+		.sname		= "\rv=",
+		.snlen		= sizeof("\rv=") - 1,
+		.ln_str		= "=",
+		.ln_strlen	= sizeof("=") - 1,
+		.match_len	= digits_len
+	}
+};
+EXPORT_SYMBOL_GPL(ct_sip_hdrs);
+
+/* get line lenght until first CR or LF seen. */
+int ct_sip_lnlen(const char *line, const char *limit)
+{
+	const char *k = line;
+
+	while ((line <= limit) && (*line == '\r' || *line == '\n'))
+		line++;
+
+	while (line <= limit) {
+		if (*line == '\r' || *line == '\n')
+			break;
+		line++;
+	}
+	return line - k;
+}
+EXPORT_SYMBOL_GPL(ct_sip_lnlen);
+
+/* Linear string search, case sensitive. */
+const char *ct_sip_search(const char *needle, const char *haystack,
+                          size_t needle_len, size_t haystack_len)
+{
+	const char *limit = haystack + (haystack_len - needle_len);
+
+	while (haystack <= limit) {
+		if (memcmp(haystack, needle, needle_len) == 0)
+			return haystack;
+		haystack++;
+	}
+	return NULL;
+}
+EXPORT_SYMBOL_GPL(ct_sip_search);
+
+static int digits_len(const char *dptr, const char *limit, int *shift)
+{
+	int len = 0;
+	while (dptr <= limit && isdigit(*dptr)) {
+		dptr++;
+		len++;
+	}
+	return len;
+}
+
+/* get digits lenght, skiping blank spaces. */
+static int skp_digits_len(const char *dptr, const char *limit, int *shift)
+{
+	for (; dptr <= limit && *dptr == ' '; dptr++)
+		(*shift)++;
+
+	return digits_len(dptr, limit, shift);
+}
+
+/* Simple ipaddr parser.. */
+static int parse_ipaddr(const char *cp,	const char **endp,
+			u_int32_t *ipaddr, const char *limit)
+{
+	unsigned long int val;
+	int i, digit = 0;
+
+	for (i = 0, *ipaddr = 0; cp <= limit && i < 4; i++) {
+		digit = 0;
+		if (!isdigit(*cp))
+			break;
+
+		val = simple_strtoul(cp, (char **)&cp, 10);
+		if (val > 0xFF)
+			return -1;
+
+		((u_int8_t *)ipaddr)[i] = val;
+		digit = 1;
+
+		if (*cp != '.')
+			break;
+		cp++;
+	}
+	if (!digit)
+		return -1;
+
+	if (endp)
+		*endp = cp;
+
+	return 0;
+}
+
+/* skip ip address. returns it lenght. */
+static int epaddr_len(const char *dptr, const char *limit, int *shift)
+{
+	const char *aux = dptr;
+	u_int32_t ip;
+
+	if (parse_ipaddr(dptr, &dptr, &ip, limit) < 0) {
+		DEBUGP("ip: %s parse failed.!\n", dptr);
+		return 0;
+	}
+
+	/* Port number */
+	if (*dptr == ':') {
+		dptr++;
+		dptr += digits_len(dptr, limit, shift);
+	}
+	return dptr - aux;
+}
+
+/* get address length, skiping user info. */
+static int skp_epaddr_len(const char *dptr, const char *limit, int *shift)
+{
+	int s = *shift;
+
+	for (; dptr <= limit && *dptr != '@'; dptr++)
+		(*shift)++;
+
+	if (*dptr == '@') {
+		dptr++;
+		(*shift)++;
+	} else
+		*shift = s;
+
+	return epaddr_len(dptr, limit, shift);
+}
+
+/* Returns 0 if not found, -1 error parsing. */
+int ct_sip_get_info(const char *dptr, size_t dlen,
+		    unsigned int *matchoff,
+		    unsigned int *matchlen,
+		    struct sip_header_nfo *hnfo)
+{
+	const char *limit, *aux, *k = dptr;
+	int shift = 0;
+
+	limit = dptr + (dlen - hnfo->lnlen);
+
+	while (dptr <= limit) {
+		if ((strncmp(dptr, hnfo->lname, hnfo->lnlen) != 0) &&
+		    (strncmp(dptr, hnfo->sname, hnfo->snlen) != 0)) {
+			dptr++;
+			continue;
+		}
+		aux = ct_sip_search(hnfo->ln_str, dptr, hnfo->ln_strlen,
+		                    ct_sip_lnlen(dptr, limit));
+		if (!aux) {
+			DEBUGP("'%s' not found in '%s'.\n", hnfo->ln_str,
+			       hnfo->lname);
+			return -1;
+		}
+		aux += hnfo->ln_strlen;
+
+		*matchlen = hnfo->match_len(aux, limit, &shift);
+		if (!*matchlen)
+			return -1;
+
+		*matchoff = (aux - k) + shift;
+
+		DEBUGP("%s match succeeded! - len: %u\n", hnfo->lname,
+		       *matchlen);
+		return 1;
+	}
+	DEBUGP("%s header not found.\n", hnfo->lname);
+	return 0;
+}
+
+static int set_expected_rtp(struct sk_buff **pskb,
+			    struct ip_conntrack *ct,
+			    enum ip_conntrack_info ctinfo,
+			    u_int32_t ipaddr, u_int16_t port,
+			    const char *dptr)
+{
+	struct ip_conntrack_expect *exp;
+	enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
+	int ret;
+
+	exp = ip_conntrack_expect_alloc(ct);
+	if (exp == NULL)
+		return NF_DROP;
+
+	exp->tuple.src.ip = ct->tuplehash[!dir].tuple.src.ip;
+	exp->tuple.src.u.udp.port = 0;
+	exp->tuple.dst.ip = ipaddr;
+	exp->tuple.dst.u.udp.port = htons(port);
+	exp->tuple.dst.protonum = IPPROTO_UDP;
+
+	exp->mask.src.ip = 0xFFFFFFFF;
+	exp->mask.src.u.udp.port = 0;
+	exp->mask.dst.ip = 0xFFFFFFFF;
+	exp->mask.dst.u.udp.port = 0xFFFF;
+	exp->mask.dst.protonum = 0xFF;
+
+	exp->expectfn = NULL;
+	exp->flags = 0;
+
+	if (ip_nat_sdp_hook)
+		ret = ip_nat_sdp_hook(pskb, ctinfo, exp, dptr);
+	else {
+		if (ip_conntrack_expect_related(exp) != 0)
+			ret = NF_DROP;
+		else
+			ret = NF_ACCEPT;
+	}
+	ip_conntrack_expect_put(exp);
+
+	return ret;
+}
+
+static int sip_help(struct sk_buff **pskb,
+		    struct ip_conntrack *ct,
+		    enum ip_conntrack_info ctinfo)
+{
+	unsigned int dataoff, datalen;
+	const char *dptr;
+	int ret = NF_ACCEPT;
+	int matchoff, matchlen;
+	u_int32_t ipaddr;
+	u_int16_t port;
+
+	/* No Data ? */
+	dataoff = (*pskb)->nh.iph->ihl*4 + sizeof(struct udphdr);
+	if (dataoff >= (*pskb)->len) {
+		DEBUGP("skb->len = %u\n", (*pskb)->len);
+		return NF_ACCEPT;
+        }
+
+	ip_ct_refresh(ct, *pskb, sip_timeout * HZ);
+
+	if (!skb_is_nonlinear(*pskb))
+		dptr = (*pskb)->data + dataoff;
+	else {
+		DEBUGP("Copy of skbuff not supported yet.\n");
+		goto out;
+	}
+
+	if (ip_nat_sip_hook) {
+		if (!ip_nat_sip_hook(pskb, ctinfo, ct, &dptr)) {
+			ret = NF_DROP;
+			goto out;
+		}
+	}
+
+	/* After this point NAT, could have mangled skb, so
+	   we need to recalculate payload lenght. */
+	datalen = (*pskb)->len - dataoff;
+
+	if (datalen < (sizeof("SIP/2.0 200") - 1))
+		goto out;
+
+	/* RTP info only in some SDP pkts */
+	if (memcmp(dptr, "INVITE", sizeof("INVITE") - 1) != 0 &&
+	    memcmp(dptr, "SIP/2.0 200", sizeof("SIP/2.0 200") - 1) != 0) {
+		goto out;
+	}
+	/* Get ip and port address from SDP packet. */
+	if (ct_sip_get_info(dptr, datalen, &matchoff, &matchlen,
+	                    &ct_sip_hdrs[POS_CONNECTION]) > 0) {
+
+		/* We'll drop only if there are parse problems. */
+		if (parse_ipaddr(dptr + matchoff, NULL, &ipaddr,
+		                 dptr + datalen) < 0) {
+			ret = NF_DROP;
+			goto out;
+		}
+		if (ct_sip_get_info(dptr, datalen, &matchoff, &matchlen,
+		                    &ct_sip_hdrs[POS_MEDIA]) > 0) {
+
+			port = simple_strtoul(dptr + matchoff, NULL, 10);
+			if (port < 1024) {
+				ret = NF_DROP;
+				goto out;
+			}
+			ret = set_expected_rtp(pskb, ct, ctinfo,
+					       ipaddr, port, dptr);
+		}
+	}
+out:
+	return ret;
+}
+
+static struct ip_conntrack_helper sip[MAX_PORTS];
+static char sip_names[MAX_PORTS][10];
+
+static void fini(void)
+{
+	int i;
+	for (i = 0; i < ports_c; i++) {
+		DEBUGP("unregistering helper for port %d\n", ports[i]);
+		ip_conntrack_helper_unregister(&sip[i]);
+	}
+}
+
+static int __init init(void)
+{
+	int i, ret;
+	char *tmpname;
+
+	if (ports_c == 0)
+		ports[ports_c++] = SIP_PORT;
+
+	for (i = 0; i < ports_c; i++) {
+		/* Create helper structure */
+		memset(&sip[i], 0, sizeof(struct ip_conntrack_helper));
+
+		sip[i].tuple.dst.protonum = IPPROTO_UDP;
+		sip[i].tuple.src.u.udp.port = htons(ports[i]);
+		sip[i].mask.src.u.udp.port = 0xFFFF;
+		sip[i].mask.dst.protonum = 0xFF;
+		sip[i].max_expected = 2;
+		sip[i].timeout = 3 * 60; /* 3 minutes */
+		sip[i].me = THIS_MODULE;
+		sip[i].help = sip_help;
+
+		tmpname = &sip_names[i][0];
+		if (ports[i] == SIP_PORT)
+			sprintf(tmpname, "sip");
+		else
+			sprintf(tmpname, "sip-%d", i);
+		sip[i].name = tmpname;
+
+		DEBUGP("port #%d: %d\n", i, ports[i]);
+
+		ret = ip_conntrack_helper_register(&sip[i]);
+		if (ret) {
+			printk("ERROR registering helper for port %d\n",
+				ports[i]);
+			fini();
+			return ret;
+		}
+	}
+	return 0;
+}
+
+module_init(init);
+module_exit(fini);
diff --git a/net/ipv4/netfilter/ip_nat_sip.c b/net/ipv4/netfilter/ip_nat_sip.c
new file mode 100644
index 000000000..6ffba63ad
--- /dev/null
+++ b/net/ipv4/netfilter/ip_nat_sip.c
@@ -0,0 +1,249 @@
+/* SIP extension for UDP NAT alteration.
+ *
+ * (C) 2005 by Christian Hentschel <chentschel@arnet.com.ar>
+ * based on RR's ip_nat_ftp.c and other modules.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/skbuff.h>
+#include <linux/ip.h>
+#include <linux/udp.h>
+
+#include <linux/netfilter_ipv4.h>
+#include <linux/netfilter_ipv4/ip_nat.h>
+#include <linux/netfilter_ipv4/ip_nat_helper.h>
+#include <linux/netfilter_ipv4/ip_conntrack_helper.h>
+#include <linux/netfilter_ipv4/ip_conntrack_sip.h>
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Christian Hentschel <chentschel@arnet.com.ar>");
+MODULE_DESCRIPTION("SIP NAT helper");
+
+#if 0
+#define DEBUGP printk
+#else
+#define DEBUGP(format, args...)
+#endif
+
+extern struct sip_header_nfo ct_sip_hdrs[];
+
+static unsigned int mangle_sip_packet(struct sk_buff **pskb,
+				      enum ip_conntrack_info ctinfo,
+				      struct ip_conntrack *ct,
+				      const char **dptr, size_t dlen,
+				      char *buffer, int bufflen,
+				      struct sip_header_nfo *hnfo)
+{
+	unsigned int matchlen, matchoff;
+
+	if (ct_sip_get_info(*dptr, dlen, &matchoff, &matchlen, hnfo) <= 0)
+		return 0;
+
+	if (!ip_nat_mangle_udp_packet(pskb, ct, ctinfo,
+	                              matchoff, matchlen, buffer, bufflen))
+		return 0;
+
+	/* We need to reload this. Thanks Patrick. */
+	*dptr = (*pskb)->data + (*pskb)->nh.iph->ihl*4 + sizeof(struct udphdr);
+	return 1;
+}
+
+static unsigned int ip_nat_sip(struct sk_buff **pskb,
+			       enum ip_conntrack_info ctinfo,
+			       struct ip_conntrack *ct,
+			       const char **dptr)
+{
+	enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
+	char buffer[sizeof("nnn.nnn.nnn.nnn:nnnnn")];
+	unsigned int bufflen, dataoff;
+	u_int32_t ip;
+	u_int16_t port;
+
+	dataoff = (*pskb)->nh.iph->ihl*4 + sizeof(struct udphdr);
+
+	ip   = ct->tuplehash[!dir].tuple.dst.ip;
+	port = ct->tuplehash[!dir].tuple.dst.u.udp.port;
+	bufflen = sprintf(buffer, "%u.%u.%u.%u:%u", NIPQUAD(ip), ntohs(port));
+
+	/* short packet ? */
+	if (((*pskb)->len - dataoff) < (sizeof("SIP/2.0") - 1))
+		return 0;
+
+	/* Basic rules: requests and responses. */
+	if (memcmp(*dptr, "SIP/2.0", sizeof("SIP/2.0") - 1) == 0) {
+		const char *aux;
+
+		if ((ctinfo) < IP_CT_IS_REPLY) {
+			mangle_sip_packet(pskb, ctinfo, ct, dptr,
+			                  (*pskb)->len - dataoff,
+			                  buffer, bufflen,
+			                  &ct_sip_hdrs[POS_CONTACT]);
+			return 1;
+		}
+
+		if (!mangle_sip_packet(pskb, ctinfo, ct, dptr,
+				       (*pskb)->len - dataoff,
+		                       buffer, bufflen, &ct_sip_hdrs[POS_VIA]))
+			return 0;
+
+		/* This search should ignore case, but later.. */
+		aux = ct_sip_search("CSeq:", *dptr, sizeof("CSeq:") - 1,
+		                    (*pskb)->len - dataoff);
+		if (!aux)
+			return 0;
+
+		if (!ct_sip_search("REGISTER", aux, sizeof("REGISTER"),
+		    ct_sip_lnlen(aux, *dptr + (*pskb)->len - dataoff)))
+			return 1;
+
+		return mangle_sip_packet(pskb, ctinfo, ct, dptr,
+					 (*pskb)->len - dataoff,
+		                         buffer, bufflen,
+					 &ct_sip_hdrs[POS_CONTACT]);
+	}
+	if ((ctinfo) < IP_CT_IS_REPLY) {
+		if (!mangle_sip_packet(pskb, ctinfo, ct, dptr,
+				       (*pskb)->len - dataoff,
+		                       buffer, bufflen, &ct_sip_hdrs[POS_VIA]))
+			return 0;
+
+		/* Mangle Contact if exists only. - watch udp_nat_mangle()! */
+		mangle_sip_packet(pskb, ctinfo, ct, dptr, (*pskb)->len - dataoff,
+		                  buffer, bufflen, &ct_sip_hdrs[POS_CONTACT]);
+		return 1;
+	}
+	/* This mangle requests headers. */
+	return mangle_sip_packet(pskb, ctinfo, ct, dptr,
+	                         ct_sip_lnlen(*dptr,
+				              *dptr + (*pskb)->len - dataoff),
+	                         buffer, bufflen, &ct_sip_hdrs[POS_REQ_HEADER]);
+}
+
+static int mangle_content_len(struct sk_buff **pskb,
+			      enum ip_conntrack_info ctinfo,
+			      struct ip_conntrack *ct,
+			      const char *dptr)
+{
+	unsigned int dataoff, matchoff, matchlen;
+	char buffer[sizeof("65536")];
+	int bufflen;
+
+	dataoff = (*pskb)->nh.iph->ihl*4 + sizeof(struct udphdr);
+
+	/* Get actual SDP lenght */
+	if (ct_sip_get_info(dptr, (*pskb)->len - dataoff, &matchoff,
+	                    &matchlen, &ct_sip_hdrs[POS_SDP_HEADER]) > 0) {
+
+		/* since ct_sip_get_info() give us a pointer passing 'v='
+		   we need to add 2 bytes in this count. */
+		int c_len = (*pskb)->len - dataoff - matchoff + 2;
+
+		/* Now, update SDP lenght */
+		if (ct_sip_get_info(dptr, (*pskb)->len - dataoff, &matchoff,
+		                    &matchlen, &ct_sip_hdrs[POS_CONTENT]) > 0) {
+
+			bufflen = sprintf(buffer, "%u", c_len);
+
+			return ip_nat_mangle_udp_packet(pskb, ct, ctinfo,
+							matchoff, matchlen,
+							buffer, bufflen);
+		}
+	}
+	return 0;
+}
+
+static unsigned int mangle_sdp(struct sk_buff **pskb,
+			       enum ip_conntrack_info ctinfo,
+			       struct ip_conntrack *ct,
+			       u_int32_t newip, u_int16_t port,
+			       const char *dptr)
+{
+	char buffer[sizeof("nnn.nnn.nnn.nnn")];
+	unsigned int dataoff, bufflen;
+
+	dataoff = (*pskb)->nh.iph->ihl*4 + sizeof(struct udphdr);
+
+	/* Mangle owner and contact info. */
+	bufflen = sprintf(buffer, "%u.%u.%u.%u", NIPQUAD(newip));
+	if (!mangle_sip_packet(pskb, ctinfo, ct, &dptr, (*pskb)->len - dataoff,
+	                       buffer, bufflen, &ct_sip_hdrs[POS_OWNER]))
+		return 0;
+
+	if (!mangle_sip_packet(pskb, ctinfo, ct, &dptr, (*pskb)->len - dataoff,
+	                       buffer, bufflen, &ct_sip_hdrs[POS_CONNECTION]))
+		return 0;
+
+	/* Mangle media port. */
+	bufflen = sprintf(buffer, "%u", port);
+	if (!mangle_sip_packet(pskb, ctinfo, ct, &dptr, (*pskb)->len - dataoff,
+	                       buffer, bufflen, &ct_sip_hdrs[POS_MEDIA]))
+		return 0;
+
+	return mangle_content_len(pskb, ctinfo, ct, dptr);
+}
+
+/* So, this packet has hit the connection tracking matching code.
+   Mangle it, and change the expectation to match the new version. */
+static unsigned int ip_nat_sdp(struct sk_buff **pskb,
+			       enum ip_conntrack_info ctinfo,
+			       struct ip_conntrack_expect *exp,
+			       const char *dptr)
+{
+	struct ip_conntrack *ct = exp->master;
+	enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
+	u_int32_t newip;
+	u_int16_t port;
+
+	DEBUGP("ip_nat_sdp():\n");
+
+	/* Connection will come from reply */
+	newip = ct->tuplehash[!dir].tuple.dst.ip;
+
+	exp->tuple.dst.ip = newip;
+	exp->saved_proto.udp.port = exp->tuple.dst.u.udp.port;
+	exp->dir = !dir;
+
+	/* When you see the packet, we need to NAT it the same as the
+	   this one. */
+	exp->expectfn = ip_nat_follow_master;
+
+	/* Try to get same port: if not, try to change it. */
+	for (port = ntohs(exp->saved_proto.udp.port); port != 0; port++) {
+		exp->tuple.dst.u.udp.port = htons(port);
+		if (ip_conntrack_expect_related(exp) == 0)
+			break;
+	}
+
+	if (port == 0)
+		return NF_DROP;
+
+	if (!mangle_sdp(pskb, ctinfo, ct, newip, port, dptr)) {
+		ip_conntrack_unexpect_related(exp);
+		return NF_DROP;
+	}
+	return NF_ACCEPT;
+}
+
+static void __exit fini(void)
+{
+	ip_nat_sip_hook = NULL;
+	ip_nat_sdp_hook = NULL;
+	/* Make sure noone calls it, meanwhile. */
+	synchronize_net();
+}
+
+static int __init init(void)
+{
+	BUG_ON(ip_nat_sip_hook);
+	BUG_ON(ip_nat_sdp_hook);
+	ip_nat_sip_hook = ip_nat_sip;
+	ip_nat_sdp_hook = ip_nat_sdp;
+	return 0;
+}
+
+module_init(init);
+module_exit(fini);
diff --git a/net/ipv4/tcp_lp.c b/net/ipv4/tcp_lp.c
new file mode 100644
index 000000000..649ebaed1
--- /dev/null
+++ b/net/ipv4/tcp_lp.c
@@ -0,0 +1,344 @@
+/*
+ * TCP Low Priority (TCP-LP)
+ *
+ * TCP Low Priority is a distributed algorithm whose goal is to utilize only
+ *   the excess network bandwidth as compared to the ``fair share`` of
+ *   bandwidth as targeted by TCP.
+ *
+ * As of 2.6.13, Linux supports pluggable congestion control algorithms.
+ * Due to the limitation of the API, we take the following changes from
+ * the original TCP-LP implementation:
+ *   o We use newReno in most core CA handling. Only add some checking
+ *     within cong_avoid.
+ *   o Error correcting in remote HZ, therefore remote HZ will be keeped
+ *     on checking and updating.
+ *   o Handling calculation of One-Way-Delay (OWD) within rtt_sample, sicne
+ *     OWD have a similar meaning as RTT. Also correct the buggy formular.
+ *   o Handle reaction for Early Congestion Indication (ECI) within
+ *     pkts_acked, as mentioned within pseudo code.
+ *   o OWD is handled in relative format, where local time stamp will in
+ *     tcp_time_stamp format.
+ *
+ * Original Author:
+ *   Aleksandar Kuzmanovic <akuzma@northwestern.edu>
+ * Available from:
+ *   http://www.ece.rice.edu/~akuzma/Doc/akuzma/TCP-LP.pdf
+ * Original implementation for 2.4.19:
+ *   http://www-ece.rice.edu/networks/TCP-LP/
+ *
+ * 2.6.x module Authors:
+ *   Wong Hoi Sing, Edison <hswong3i@gmail.com>
+ *   Hung Hing Lun, Mike <hlhung3i@gmail.com>
+ * SourceForge project page:
+ *   http://tcp-lp-mod.sourceforge.net/
+ *
+ * Version: $Id: tcp_lp.c,v 1.24 2006/09/05 20:22:53 hswong3i Exp $
+ */
+
+#include <linux/module.h>
+#include <net/tcp.h>
+
+/* resolution of owd */
+#define LP_RESOL       1000
+
+/**
+ * enum tcp_lp_state
+ * @LP_VALID_RHZ: is remote HZ valid?
+ * @LP_VALID_OWD: is OWD valid?
+ * @LP_WITHIN_THR: are we within threshold?
+ * @LP_WITHIN_INF: are we within inference?
+ *
+ * TCP-LP's state flags.
+ * We create this set of state flag mainly for debugging.
+ */
+enum tcp_lp_state {
+	LP_VALID_RHZ = (1 << 0),
+	LP_VALID_OWD = (1 << 1),
+	LP_WITHIN_THR = (1 << 3),
+	LP_WITHIN_INF = (1 << 4),
+};
+
+/**
+ * struct lp
+ * @flag: TCP-LP state flag
+ * @sowd: smoothed OWD << 3
+ * @owd_min: min OWD
+ * @owd_max: max OWD
+ * @owd_max_rsv: resrved max owd
+ * @remote_hz: estimated remote HZ
+ * @remote_ref_time: remote reference time
+ * @local_ref_time: local reference time
+ * @last_drop: time for last active drop
+ * @inference: current inference
+ *
+ * TCP-LP's private struct.
+ * We get the idea from original TCP-LP implementation where only left those we
+ * found are really useful.
+ */
+struct lp {
+	u32 flag;
+	u32 sowd;
+	u32 owd_min;
+	u32 owd_max;
+	u32 owd_max_rsv;
+	u32 remote_hz;
+	u32 remote_ref_time;
+	u32 local_ref_time;
+	u32 last_drop;
+	u32 inference;
+};
+
+/**
+ * tcp_lp_init
+ *
+ * Init all required variables.
+ * Clone the handling from Vegas module implementation.
+ */
+static void tcp_lp_init(struct sock *sk)
+{
+	struct lp *lp = inet_csk_ca(sk);
+
+	lp->flag = 0;
+	lp->sowd = 0;
+	lp->owd_min = 0xffffffff;
+	lp->owd_max = 0;
+	lp->owd_max_rsv = 0;
+	lp->remote_hz = 0;
+	lp->remote_ref_time = 0;
+	lp->local_ref_time = 0;
+	lp->last_drop = 0;
+	lp->inference = 0;
+}
+
+/**
+ * tcp_lp_cong_avoid
+ *
+ * Implementation of cong_avoid.
+ * Will only call newReno CA when away from inference.
+ * From TCP-LP's paper, this will be handled in additive increasement.
+ */
+static void tcp_lp_cong_avoid(struct sock *sk, u32 ack, u32 rtt, u32 in_flight,
+			      int flag)
+{
+	struct lp *lp = inet_csk_ca(sk);
+
+	if (!(lp->flag & LP_WITHIN_INF))
+		tcp_reno_cong_avoid(sk, ack, rtt, in_flight, flag);
+}
+
+/**
+ * tcp_lp_remote_hz_estimator
+ *
+ * Estimate remote HZ.
+ * We keep on updating the estimated value, where original TCP-LP
+ * implementation only guest it for once and use forever.
+ */
+static u32 tcp_lp_remote_hz_estimator(struct sock *sk)
+{
+	struct tcp_sock *tp = tcp_sk(sk);
+	struct lp *lp = inet_csk_ca(sk);
+	s64 rhz = lp->remote_hz << 6;	/* remote HZ << 6 */
+	s64 m = 0;
+
+	/* not yet record reference time
+	 * go away!! record it before come back!! */
+	if (lp->remote_ref_time == 0 || lp->local_ref_time == 0)
+		goto out;
+
+	/* we can't calc remote HZ with no different!! */
+	if (tp->rx_opt.rcv_tsval == lp->remote_ref_time
+	    || tp->rx_opt.rcv_tsecr == lp->local_ref_time)
+		goto out;
+
+	m = HZ * (tp->rx_opt.rcv_tsval -
+		  lp->remote_ref_time) / (tp->rx_opt.rcv_tsecr -
+					  lp->local_ref_time);
+	if (m < 0)
+		m = -m;
+
+	if (rhz > 0) {
+		m -= rhz >> 6;	/* m is now error in remote HZ est */
+		rhz += m;	/* 63/64 old + 1/64 new */
+	} else
+		rhz = m << 6;
+
+ out:
+	/* record time for successful remote HZ calc */
+	if (rhz > 0)
+		lp->flag |= LP_VALID_RHZ;
+	else
+		lp->flag &= ~LP_VALID_RHZ;
+
+	/* record reference time stamp */
+	lp->remote_ref_time = tp->rx_opt.rcv_tsval;
+	lp->local_ref_time = tp->rx_opt.rcv_tsecr;
+
+	return rhz >> 6;
+}
+
+/**
+ * tcp_lp_owd_calculator
+ *
+ * Calculate one way delay (in relative format).
+ * Original implement OWD as minus of remote time difference to local time
+ * difference directly. As this time difference just simply equal to RTT, when
+ * the network status is stable, remote RTT will equal to local RTT, and result
+ * OWD into zero.
+ * It seems to be a bug and so we fixed it.
+ */
+static u32 tcp_lp_owd_calculator(struct sock *sk)
+{
+	struct tcp_sock *tp = tcp_sk(sk);
+	struct lp *lp = inet_csk_ca(sk);
+	s64 owd = 0;
+
+	lp->remote_hz = tcp_lp_remote_hz_estimator(sk);
+
+	if (lp->flag & LP_VALID_RHZ) {
+		owd =
+		    tp->rx_opt.rcv_tsval * (LP_RESOL / lp->remote_hz) -
+		    tp->rx_opt.rcv_tsecr * (LP_RESOL / HZ);
+		if (owd < 0)
+			owd = -owd;
+	}
+
+	if (owd > 0)
+		lp->flag |= LP_VALID_OWD;
+	else
+		lp->flag &= ~LP_VALID_OWD;
+
+	return owd;
+}
+
+/**
+ * tcp_lp_rtt_sample
+ *
+ * Implementation or rtt_sample.
+ * Will take the following action,
+ *   1. calc OWD,
+ *   2. record the min/max OWD,
+ *   3. calc smoothed OWD (SOWD).
+ * Most ideas come from the original TCP-LP implementation.
+ */
+static void tcp_lp_rtt_sample(struct sock *sk, u32 usrtt)
+{
+	struct lp *lp = inet_csk_ca(sk);
+	s64 mowd = tcp_lp_owd_calculator(sk);
+
+	/* sorry that we don't have valid data */
+	if (!(lp->flag & LP_VALID_RHZ) || !(lp->flag & LP_VALID_OWD))
+		return;
+
+	/* record the next min owd */
+	if (mowd < lp->owd_min)
+		lp->owd_min = mowd;
+
+	/* always forget the max of the max
+	 * we just set owd_max as one below it */
+	if (mowd > lp->owd_max) {
+		if (mowd > lp->owd_max_rsv) {
+			if (lp->owd_max_rsv == 0)
+				lp->owd_max = mowd;
+			else
+				lp->owd_max = lp->owd_max_rsv;
+			lp->owd_max_rsv = mowd;
+		} else
+			lp->owd_max = mowd;
+	}
+
+	/* calc for smoothed owd */
+	if (lp->sowd != 0) {
+		mowd -= lp->sowd >> 3;	/* m is now error in owd est */
+		lp->sowd += mowd;	/* owd = 7/8 owd + 1/8 new */
+	} else
+		lp->sowd = mowd << 3;	/* take the measured time be owd */
+}
+
+/**
+ * tcp_lp_pkts_acked
+ *
+ * Implementation of pkts_acked.
+ * Deal with active drop under Early Congestion Indication.
+ * Only drop to half and 1 will be handle, because we hope to use back
+ * newReno in increase case.
+ * We work it out by following the idea from TCP-LP's paper directly
+ */
+static void tcp_lp_pkts_acked(struct sock *sk, u32 num_acked)
+{
+	struct tcp_sock *tp = tcp_sk(sk);
+	struct lp *lp = inet_csk_ca(sk);
+
+	/* calc inference */
+	if (tcp_time_stamp > tp->rx_opt.rcv_tsecr)
+		lp->inference = 3 * (tcp_time_stamp - tp->rx_opt.rcv_tsecr);
+
+	/* test if within inference */
+	if (lp->last_drop && (tcp_time_stamp - lp->last_drop < lp->inference))
+		lp->flag |= LP_WITHIN_INF;
+	else
+		lp->flag &= ~LP_WITHIN_INF;
+
+	/* test if within threshold */
+	if (lp->sowd >> 3 <
+	    lp->owd_min + 15 * (lp->owd_max - lp->owd_min) / 100)
+		lp->flag |= LP_WITHIN_THR;
+	else
+		lp->flag &= ~LP_WITHIN_THR;
+
+	pr_debug("TCP-LP: %05o|%5u|%5u|%15u|%15u|%15u\n", lp->flag,
+		 tp->snd_cwnd, lp->remote_hz, lp->owd_min, lp->owd_max,
+		 lp->sowd >> 3);
+
+	if (lp->flag & LP_WITHIN_THR)
+		return;
+
+	/* FIXME: try to reset owd_min and owd_max here
+	 * so decrease the chance the min/max is no longer suitable
+	 * and will usually within threshold when whithin inference */
+	lp->owd_min = lp->sowd >> 3;
+	lp->owd_max = lp->sowd >> 2;
+	lp->owd_max_rsv = lp->sowd >> 2;
+
+	/* happened within inference
+	 * drop snd_cwnd into 1 */
+	if (lp->flag & LP_WITHIN_INF)
+		tp->snd_cwnd = 1U;
+
+	/* happened after inference
+	 * cut snd_cwnd into half */
+	else
+		tp->snd_cwnd = max(tp->snd_cwnd >> 1U, 1U);
+
+	/* record this drop time */
+	lp->last_drop = tcp_time_stamp;
+}
+
+static struct tcp_congestion_ops tcp_lp = {
+	.init = tcp_lp_init,
+	.ssthresh = tcp_reno_ssthresh,
+	.cong_avoid = tcp_lp_cong_avoid,
+	.min_cwnd = tcp_reno_min_cwnd,
+	.rtt_sample = tcp_lp_rtt_sample,
+	.pkts_acked = tcp_lp_pkts_acked,
+
+	.owner = THIS_MODULE,
+	.name = "lp"
+};
+
+static int __init tcp_lp_register(void)
+{
+	BUG_ON(sizeof(struct lp) > ICSK_CA_PRIV_SIZE);
+	return tcp_register_congestion_control(&tcp_lp);
+}
+
+static void __exit tcp_lp_unregister(void)
+{
+	tcp_unregister_congestion_control(&tcp_lp);
+}
+
+module_init(tcp_lp_register);
+module_exit(tcp_lp_unregister);
+
+MODULE_AUTHOR("Wong Hoi Sing Edison, Hung Hing Lun Mike");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("TCP Low Priority");
diff --git a/net/ipv4/tcp_probe.c b/net/ipv4/tcp_probe.c
new file mode 100644
index 000000000..dab37d2f6
--- /dev/null
+++ b/net/ipv4/tcp_probe.c
@@ -0,0 +1,182 @@
+/*
+ * tcpprobe - Observe the TCP flow with kprobes.
+ *
+ * The idea for this came from Werner Almesberger's umlsim
+ * Copyright (C) 2004, Stephen Hemminger <shemminger@osdl.org>
+ *
+ * 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/kprobes.h>
+#include <linux/socket.h>
+#include <linux/tcp.h>
+#include <linux/proc_fs.h>
+#include <linux/module.h>
+#include <linux/kfifo.h>
+#include <linux/vmalloc.h>
+
+#include <net/tcp.h>
+
+MODULE_AUTHOR("Stephen Hemminger <shemminger@osdl.org>");
+MODULE_DESCRIPTION("TCP cwnd snooper");
+MODULE_LICENSE("GPL");
+
+static int port = 0;
+MODULE_PARM_DESC(port, "Port to match (0=all)");
+module_param(port, int, 0);
+
+static int bufsize = 64*1024;
+MODULE_PARM_DESC(bufsize, "Log buffer size (default 64k)");
+module_param(bufsize, int, 0);
+
+static const char procname[] = "tcpprobe";
+
+struct {
+	struct kfifo  *fifo;
+	spinlock_t    lock;
+	wait_queue_head_t wait;
+	struct timeval tstart;
+} tcpw;
+
+static void printl(const char *fmt, ...)
+{
+	va_list args;
+	int len;
+	struct timeval now;
+	char tbuf[256];
+
+	va_start(args, fmt);
+	do_gettimeofday(&now);
+
+	now.tv_sec -= tcpw.tstart.tv_sec;
+	now.tv_usec -= tcpw.tstart.tv_usec;
+	if (now.tv_usec < 0) {
+		--now.tv_sec;
+		now.tv_usec += 1000000;
+	}
+
+	len = sprintf(tbuf, "%lu.%06lu ",
+		      (unsigned long) now.tv_sec,
+		      (unsigned long) now.tv_usec);
+	len += vscnprintf(tbuf+len, sizeof(tbuf)-len, fmt, args);
+	va_end(args);
+
+	kfifo_put(tcpw.fifo, tbuf, len);
+	wake_up(&tcpw.wait);
+}
+
+static int jtcp_sendmsg(struct kiocb *iocb, struct sock *sk,
+			struct msghdr *msg, size_t size)
+{
+	const struct tcp_sock *tp = tcp_sk(sk);
+	const struct inet_sock *inet = inet_sk(sk);
+
+	if (port == 0 || ntohs(inet->dport) == port ||
+	    ntohs(inet->sport) == port) {
+		printl("%d.%d.%d.%d:%u %d.%d.%d.%d:%u %d %#x %#x %u %u %u\n",
+		       NIPQUAD(inet->saddr), ntohs(inet->sport),
+		       NIPQUAD(inet->daddr), ntohs(inet->dport),
+		       size, tp->snd_nxt, tp->snd_una,
+		       tp->snd_cwnd, tcp_current_ssthresh(sk),
+		       tp->snd_wnd);
+	}
+
+	jprobe_return();
+	return 0;
+}
+
+static struct jprobe tcp_send_probe = {
+	.kp = { .addr = (kprobe_opcode_t *) &tcp_sendmsg, },
+	.entry = (kprobe_opcode_t *) &jtcp_sendmsg,
+};
+
+
+static int tcpprobe_open(struct inode * inode, struct file * file)
+{
+	kfifo_reset(tcpw.fifo);
+	do_gettimeofday(&tcpw.tstart);
+	return 0;
+}
+
+static ssize_t tcpprobe_read(struct file *file, char __user *buf,
+			     size_t len, loff_t *ppos)
+{
+	int error = 0, cnt = 0;
+	unsigned char *tbuf;
+
+	if (!buf || len < 0)
+		return -EINVAL;
+
+	if (len == 0)
+		return 0;
+
+	tbuf = vmalloc(len);
+	if (!tbuf)
+		return -ENOMEM;
+
+	error = wait_event_interruptible(tcpw.wait,
+					 __kfifo_len(tcpw.fifo) != 0);
+	if (error)
+		goto out_free;
+
+	cnt = kfifo_get(tcpw.fifo, tbuf, len);
+	error = copy_to_user(buf, tbuf, cnt);
+
+out_free:
+	vfree(tbuf);
+
+	return error ? error : cnt;
+}
+
+static struct file_operations tcpprobe_fops = {
+	.owner	 = THIS_MODULE,
+	.open	 = tcpprobe_open,
+	.read    = tcpprobe_read,
+};
+
+static __init int tcpprobe_init(void)
+{
+	int ret = -ENOMEM;
+
+	init_waitqueue_head(&tcpw.wait);
+	spin_lock_init(&tcpw.lock);
+	tcpw.fifo = kfifo_alloc(bufsize, GFP_KERNEL, &tcpw.lock);
+
+	if (!proc_net_fops_create(procname, S_IRUSR, &tcpprobe_fops))
+		goto err0;
+
+	ret = register_jprobe(&tcp_send_probe);
+	if (ret)
+		goto err1;
+
+	pr_info("TCP watch registered (port=%d)\n", port);
+	return 0;
+ err1:
+	proc_net_remove(procname);
+ err0:
+	kfifo_free(tcpw.fifo);
+	return ret;
+}
+module_init(tcpprobe_init);
+
+static __exit void tcpprobe_exit(void)
+{
+	kfifo_free(tcpw.fifo);
+	proc_net_remove(procname);
+	unregister_jprobe(&tcp_send_probe);
+
+}
+module_exit(tcpprobe_exit);
diff --git a/net/ipv4/tcp_veno.c b/net/ipv4/tcp_veno.c
new file mode 100644
index 000000000..5b2fe6d2a
--- /dev/null
+++ b/net/ipv4/tcp_veno.c
@@ -0,0 +1,230 @@
+/*
+ * TCP Veno congestion control
+ *
+ * This is based on the congestion detection/avoidance scheme described in
+ *    C. P. Fu, S. C. Liew.
+ *    "TCP Veno: TCP Enhancement for Transmission over Wireless Access Networks."
+ *    IEEE Journal on Selected Areas in Communication,
+ *    Feb. 2003.
+ * 	See http://www.ntu.edu.sg/home5/ZHOU0022/papers/CPFu03a.pdf
+ */
+
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/skbuff.h>
+#include <linux/inet_diag.h>
+
+#include <net/tcp.h>
+
+/* Default values of the Veno variables, in fixed-point representation
+ * with V_PARAM_SHIFT bits to the right of the binary point.
+ */
+#define V_PARAM_SHIFT 1
+static const int beta = 3 << V_PARAM_SHIFT;
+
+/* Veno variables */
+struct veno {
+	u8 doing_veno_now;	/* if true, do veno for this rtt */
+	u16 cntrtt;		/* # of rtts measured within last rtt */
+	u32 minrtt;		/* min of rtts measured within last rtt (in usec) */
+	u32 basertt;		/* the min of all Veno rtt measurements seen (in usec) */
+	u32 inc;		/* decide whether to increase cwnd */
+	u32 diff;		/* calculate the diff rate */
+};
+
+/* There are several situations when we must "re-start" Veno:
+ *
+ *  o when a connection is established
+ *  o after an RTO
+ *  o after fast recovery
+ *  o when we send a packet and there is no outstanding
+ *    unacknowledged data (restarting an idle connection)
+ *
+ */
+static inline void veno_enable(struct sock *sk)
+{
+	struct veno *veno = inet_csk_ca(sk);
+
+	/* turn on Veno */
+	veno->doing_veno_now = 1;
+
+	veno->minrtt = 0x7fffffff;
+}
+
+static inline void veno_disable(struct sock *sk)
+{
+	struct veno *veno = inet_csk_ca(sk);
+
+	/* turn off Veno */
+	veno->doing_veno_now = 0;
+}
+
+static void tcp_veno_init(struct sock *sk)
+{
+	struct veno *veno = inet_csk_ca(sk);
+
+	veno->basertt = 0x7fffffff;
+	veno->inc = 1;
+	veno_enable(sk);
+}
+
+/* Do rtt sampling needed for Veno. */
+static void tcp_veno_rtt_calc(struct sock *sk, u32 usrtt)
+{
+	struct veno *veno = inet_csk_ca(sk);
+	u32 vrtt = usrtt + 1;	/* Never allow zero rtt or basertt */
+
+	/* Filter to find propagation delay: */
+	if (vrtt < veno->basertt)
+		veno->basertt = vrtt;
+
+	/* Find the min rtt during the last rtt to find
+	 * the current prop. delay + queuing delay:
+	 */
+	veno->minrtt = min(veno->minrtt, vrtt);
+	veno->cntrtt++;
+}
+
+static void tcp_veno_state(struct sock *sk, u8 ca_state)
+{
+	if (ca_state == TCP_CA_Open)
+		veno_enable(sk);
+	else
+		veno_disable(sk);
+}
+
+/*
+ * If the connection is idle and we are restarting,
+ * then we don't want to do any Veno calculations
+ * until we get fresh rtt samples.  So when we
+ * restart, we reset our Veno state to a clean
+ * state. After we get acks for this flight of
+ * packets, _then_ we can make Veno calculations
+ * again.
+ */
+static void tcp_veno_cwnd_event(struct sock *sk, enum tcp_ca_event event)
+{
+	if (event == CA_EVENT_CWND_RESTART || event == CA_EVENT_TX_START)
+		tcp_veno_init(sk);
+}
+
+static void tcp_veno_cong_avoid(struct sock *sk, u32 ack,
+				u32 seq_rtt, u32 in_flight, int flag)
+{
+	struct tcp_sock *tp = tcp_sk(sk);
+	struct veno *veno = inet_csk_ca(sk);
+
+	if (!veno->doing_veno_now)
+		return tcp_reno_cong_avoid(sk, ack, seq_rtt, in_flight, flag);
+
+	/* limited by applications */
+	if (!tcp_is_cwnd_limited(sk, in_flight))
+		return;
+
+	/* We do the Veno calculations only if we got enough rtt samples */
+	if (veno->cntrtt <= 2) {
+		/* We don't have enough rtt samples to do the Veno
+		 * calculation, so we'll behave like Reno.
+		 */
+		tcp_reno_cong_avoid(sk, ack, seq_rtt, in_flight, flag);
+	} else {
+		u32 rtt, target_cwnd;
+
+		/* We have enough rtt samples, so, using the Veno
+		 * algorithm, we determine the state of the network.
+		 */
+
+		rtt = veno->minrtt;
+
+		target_cwnd = ((tp->snd_cwnd * veno->basertt)
+			       << V_PARAM_SHIFT) / rtt;
+
+		veno->diff = (tp->snd_cwnd << V_PARAM_SHIFT) - target_cwnd;
+
+		if (tp->snd_cwnd <= tp->snd_ssthresh) {
+			/* Slow start.  */
+			tcp_slow_start(tp);
+		} else {
+			/* Congestion avoidance. */
+			if (veno->diff < beta) {
+				/* In the "non-congestive state", increase cwnd
+				 *  every rtt.
+				 */
+				if (tp->snd_cwnd_cnt >= tp->snd_cwnd) {
+					if (tp->snd_cwnd < tp->snd_cwnd_clamp)
+						tp->snd_cwnd++;
+					tp->snd_cwnd_cnt = 0;
+				} else
+					tp->snd_cwnd_cnt++;
+			} else {
+				/* In the "congestive state", increase cwnd
+				 * every other rtt.
+				 */
+				if (tp->snd_cwnd_cnt >= tp->snd_cwnd) {
+					if (veno->inc
+					    && tp->snd_cwnd <
+					    tp->snd_cwnd_clamp) {
+						tp->snd_cwnd++;
+						veno->inc = 0;
+					} else
+						veno->inc = 1;
+					tp->snd_cwnd_cnt = 0;
+				} else
+					tp->snd_cwnd_cnt++;
+			}
+
+		}
+		if (tp->snd_cwnd < 2)
+			tp->snd_cwnd = 2;
+		else if (tp->snd_cwnd > tp->snd_cwnd_clamp)
+			tp->snd_cwnd = tp->snd_cwnd_clamp;
+	}
+	/* Wipe the slate clean for the next rtt. */
+	/* veno->cntrtt = 0; */
+	veno->minrtt = 0x7fffffff;
+}
+
+/* Veno MD phase */
+static u32 tcp_veno_ssthresh(struct sock *sk)
+{
+	const struct tcp_sock *tp = tcp_sk(sk);
+	struct veno *veno = inet_csk_ca(sk);
+
+	if (veno->diff < beta)
+		/* in "non-congestive state", cut cwnd by 1/5 */
+		return max(tp->snd_cwnd * 4 / 5, 2U);
+	else
+		/* in "congestive state", cut cwnd by 1/2 */
+		return max(tp->snd_cwnd >> 1U, 2U);
+}
+
+static struct tcp_congestion_ops tcp_veno = {
+	.init		= tcp_veno_init,
+	.ssthresh	= tcp_veno_ssthresh,
+	.cong_avoid	= tcp_veno_cong_avoid,
+	.rtt_sample	= tcp_veno_rtt_calc,
+	.set_state	= tcp_veno_state,
+	.cwnd_event	= tcp_veno_cwnd_event,
+
+	.owner		= THIS_MODULE,
+	.name		= "veno",
+};
+
+static int __init tcp_veno_register(void)
+{
+	BUG_ON(sizeof(struct veno) > ICSK_CA_PRIV_SIZE);
+	tcp_register_congestion_control(&tcp_veno);
+	return 0;
+}
+
+static void __exit tcp_veno_unregister(void)
+{
+	tcp_unregister_congestion_control(&tcp_veno);
+}
+
+module_init(tcp_veno_register);
+module_exit(tcp_veno_unregister);
+
+MODULE_AUTHOR("Bin Zhou, Cheng Peng Fu");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("TCP Veno");
diff --git a/net/ipv4/xfrm4_mode_transport.c b/net/ipv4/xfrm4_mode_transport.c
new file mode 100644
index 000000000..a9e6b3dd1
--- /dev/null
+++ b/net/ipv4/xfrm4_mode_transport.c
@@ -0,0 +1,83 @@
+/*
+ * xfrm4_mode_transport.c - Transport mode encapsulation for IPv4.
+ *
+ * Copyright (c) 2004-2006 Herbert Xu <herbert@gondor.apana.org.au>
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/skbuff.h>
+#include <linux/stringify.h>
+#include <net/dst.h>
+#include <net/ip.h>
+#include <net/xfrm.h>
+
+/* Add encapsulation header.
+ *
+ * The IP header will be moved forward to make space for the encapsulation
+ * header.
+ *
+ * On exit, skb->h will be set to the start of the payload to be processed
+ * by x->type->output and skb->nh will be set to the top IP header.
+ */
+static int xfrm4_transport_output(struct sk_buff *skb)
+{
+	struct xfrm_state *x;
+	struct iphdr *iph;
+	int ihl;
+
+	iph = skb->nh.iph;
+	skb->h.ipiph = iph;
+
+	ihl = iph->ihl * 4;
+	skb->h.raw += ihl;
+
+	x = skb->dst->xfrm;
+	skb->nh.raw = memmove(skb_push(skb, x->props.header_len), iph, ihl);
+	return 0;
+}
+
+/* Remove encapsulation header.
+ *
+ * The IP header will be moved over the top of the encapsulation header.
+ *
+ * On entry, skb->h shall point to where the IP header should be and skb->nh
+ * shall be set to where the IP header currently is.  skb->data shall point
+ * to the start of the payload.
+ */
+static int xfrm4_transport_input(struct xfrm_state *x, struct sk_buff *skb)
+{
+	int ihl = skb->data - skb->h.raw;
+
+	if (skb->h.raw != skb->nh.raw)
+		skb->nh.raw = memmove(skb->h.raw, skb->nh.raw, ihl);
+	skb->nh.iph->tot_len = htons(skb->len + ihl);
+	skb->h.raw = skb->data;
+	return 0;
+}
+
+static struct xfrm_mode xfrm4_transport_mode = {
+	.input = xfrm4_transport_input,
+	.output = xfrm4_transport_output,
+	.owner = THIS_MODULE,
+	.encap = XFRM_MODE_TRANSPORT,
+};
+
+static int __init xfrm4_transport_init(void)
+{
+	return xfrm_register_mode(&xfrm4_transport_mode, AF_INET);
+}
+
+static void __exit xfrm4_transport_exit(void)
+{
+	int err;
+
+	err = xfrm_unregister_mode(&xfrm4_transport_mode, AF_INET);
+	BUG_ON(err);
+}
+
+module_init(xfrm4_transport_init);
+module_exit(xfrm4_transport_exit);
+MODULE_LICENSE("GPL");
+MODULE_ALIAS_XFRM_MODE(AF_INET, XFRM_MODE_TRANSPORT);
diff --git a/net/ipv4/xfrm4_mode_tunnel.c b/net/ipv4/xfrm4_mode_tunnel.c
new file mode 100644
index 000000000..13cafbe56
--- /dev/null
+++ b/net/ipv4/xfrm4_mode_tunnel.c
@@ -0,0 +1,124 @@
+/*
+ * xfrm4_mode_tunnel.c - Tunnel mode encapsulation for IPv4.
+ *
+ * Copyright (c) 2004-2006 Herbert Xu <herbert@gondor.apana.org.au>
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/skbuff.h>
+#include <linux/stringify.h>
+#include <net/dst.h>
+#include <net/inet_ecn.h>
+#include <net/ip.h>
+#include <net/xfrm.h>
+
+static inline void ipip_ecn_decapsulate(struct sk_buff *skb)
+{
+	struct iphdr *outer_iph = skb->nh.iph;
+	struct iphdr *inner_iph = skb->h.ipiph;
+
+	if (INET_ECN_is_ce(outer_iph->tos))
+		IP_ECN_set_ce(inner_iph);
+}
+
+/* Add encapsulation header.
+ *
+ * The top IP header will be constructed per RFC 2401.  The following fields
+ * in it shall be filled in by x->type->output:
+ *      tot_len
+ *      check
+ *
+ * On exit, skb->h will be set to the start of the payload to be processed
+ * by x->type->output and skb->nh will be set to the top IP header.
+ */
+static int xfrm4_tunnel_output(struct sk_buff *skb)
+{
+	struct dst_entry *dst = skb->dst;
+	struct xfrm_state *x = dst->xfrm;
+	struct iphdr *iph, *top_iph;
+	int flags;
+
+	iph = skb->nh.iph;
+	skb->h.ipiph = iph;
+
+	skb->nh.raw = skb_push(skb, x->props.header_len);
+	top_iph = skb->nh.iph;
+
+	top_iph->ihl = 5;
+	top_iph->version = 4;
+
+	/* DS disclosed */
+	top_iph->tos = INET_ECN_encapsulate(iph->tos, iph->tos);
+
+	flags = x->props.flags;
+	if (flags & XFRM_STATE_NOECN)
+		IP_ECN_clear(top_iph);
+
+	top_iph->frag_off = (flags & XFRM_STATE_NOPMTUDISC) ?
+		0 : (iph->frag_off & htons(IP_DF));
+	if (!top_iph->frag_off)
+		__ip_select_ident(top_iph, dst->child, 0);
+
+	top_iph->ttl = dst_metric(dst->child, RTAX_HOPLIMIT);
+
+	top_iph->saddr = x->props.saddr.a4;
+	top_iph->daddr = x->id.daddr.a4;
+	top_iph->protocol = IPPROTO_IPIP;
+
+	memset(&(IPCB(skb)->opt), 0, sizeof(struct ip_options));
+	return 0;
+}
+
+static int xfrm4_tunnel_input(struct xfrm_state *x, struct sk_buff *skb)
+{
+	struct iphdr *iph = skb->nh.iph;
+	int err = -EINVAL;
+
+	if (iph->protocol != IPPROTO_IPIP)
+		goto out;
+	if (!pskb_may_pull(skb, sizeof(struct iphdr)))
+		goto out;
+
+	if (skb_cloned(skb) &&
+	    (err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC)))
+		goto out;
+
+	if (x->props.flags & XFRM_STATE_DECAP_DSCP)
+		ipv4_copy_dscp(iph, skb->h.ipiph);
+	if (!(x->props.flags & XFRM_STATE_NOECN))
+		ipip_ecn_decapsulate(skb);
+	skb->mac.raw = memmove(skb->data - skb->mac_len,
+			       skb->mac.raw, skb->mac_len);
+	skb->nh.raw = skb->data;
+	err = 0;
+
+out:
+	return err;
+}
+
+static struct xfrm_mode xfrm4_tunnel_mode = {
+	.input = xfrm4_tunnel_input,
+	.output = xfrm4_tunnel_output,
+	.owner = THIS_MODULE,
+	.encap = XFRM_MODE_TUNNEL,
+};
+
+static int __init xfrm4_tunnel_init(void)
+{
+	return xfrm_register_mode(&xfrm4_tunnel_mode, AF_INET);
+}
+
+static void __exit xfrm4_tunnel_exit(void)
+{
+	int err;
+
+	err = xfrm_unregister_mode(&xfrm4_tunnel_mode, AF_INET);
+	BUG_ON(err);
+}
+
+module_init(xfrm4_tunnel_init);
+module_exit(xfrm4_tunnel_exit);
+MODULE_LICENSE("GPL");
+MODULE_ALIAS_XFRM_MODE(AF_INET, XFRM_MODE_TUNNEL);
diff --git a/net/ipv6/xfrm6_mode_transport.c b/net/ipv6/xfrm6_mode_transport.c
new file mode 100644
index 000000000..711d713e3
--- /dev/null
+++ b/net/ipv6/xfrm6_mode_transport.c
@@ -0,0 +1,88 @@
+/*
+ * xfrm6_mode_transport.c - Transport mode encapsulation for IPv6.
+ *
+ * Copyright (C) 2002 USAGI/WIDE Project
+ * Copyright (c) 2004-2006 Herbert Xu <herbert@gondor.apana.org.au>
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/skbuff.h>
+#include <linux/stringify.h>
+#include <net/dst.h>
+#include <net/ipv6.h>
+#include <net/xfrm.h>
+
+/* Add encapsulation header.
+ *
+ * The IP header and mutable extension headers will be moved forward to make
+ * space for the encapsulation header.
+ *
+ * On exit, skb->h will be set to the start of the encapsulation header to be
+ * filled in by x->type->output and skb->nh will be set to the nextheader field
+ * of the extension header directly preceding the encapsulation header, or in
+ * its absence, that of the top IP header.  The value of skb->data will always
+ * point to the top IP header.
+ */
+static int xfrm6_transport_output(struct sk_buff *skb)
+{
+	struct xfrm_state *x = skb->dst->xfrm;
+	struct ipv6hdr *iph;
+	u8 *prevhdr;
+	int hdr_len;
+
+	skb_push(skb, x->props.header_len);
+	iph = skb->nh.ipv6h;
+
+	hdr_len = ip6_find_1stfragopt(skb, &prevhdr);
+	skb->nh.raw = prevhdr - x->props.header_len;
+	skb->h.raw = skb->data + hdr_len;
+	memmove(skb->data, iph, hdr_len);
+	return 0;
+}
+
+/* Remove encapsulation header.
+ *
+ * The IP header will be moved over the top of the encapsulation header.
+ *
+ * On entry, skb->h shall point to where the IP header should be and skb->nh
+ * shall be set to where the IP header currently is.  skb->data shall point
+ * to the start of the payload.
+ */
+static int xfrm6_transport_input(struct xfrm_state *x, struct sk_buff *skb)
+{
+	int ihl = skb->data - skb->h.raw;
+
+	if (skb->h.raw != skb->nh.raw)
+		skb->nh.raw = memmove(skb->h.raw, skb->nh.raw, ihl);
+	skb->nh.ipv6h->payload_len = htons(skb->len + ihl -
+					   sizeof(struct ipv6hdr));
+	skb->h.raw = skb->data;
+	return 0;
+}
+
+static struct xfrm_mode xfrm6_transport_mode = {
+	.input = xfrm6_transport_input,
+	.output = xfrm6_transport_output,
+	.owner = THIS_MODULE,
+	.encap = XFRM_MODE_TRANSPORT,
+};
+
+static int __init xfrm6_transport_init(void)
+{
+	return xfrm_register_mode(&xfrm6_transport_mode, AF_INET6);
+}
+
+static void __exit xfrm6_transport_exit(void)
+{
+	int err;
+
+	err = xfrm_unregister_mode(&xfrm6_transport_mode, AF_INET6);
+	BUG_ON(err);
+}
+
+module_init(xfrm6_transport_init);
+module_exit(xfrm6_transport_exit);
+MODULE_LICENSE("GPL");
+MODULE_ALIAS_XFRM_MODE(AF_INET6, XFRM_MODE_TRANSPORT);
diff --git a/net/ipv6/xfrm6_mode_tunnel.c b/net/ipv6/xfrm6_mode_tunnel.c
new file mode 100644
index 000000000..8af79be2e
--- /dev/null
+++ b/net/ipv6/xfrm6_mode_tunnel.c
@@ -0,0 +1,121 @@
+/*
+ * xfrm6_mode_tunnel.c - Tunnel mode encapsulation for IPv6.
+ *
+ * Copyright (C) 2002 USAGI/WIDE Project
+ * Copyright (c) 2004-2006 Herbert Xu <herbert@gondor.apana.org.au>
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/skbuff.h>
+#include <linux/stringify.h>
+#include <net/dsfield.h>
+#include <net/dst.h>
+#include <net/inet_ecn.h>
+#include <net/ipv6.h>
+#include <net/xfrm.h>
+
+static inline void ipip6_ecn_decapsulate(struct sk_buff *skb)
+{
+	struct ipv6hdr *outer_iph = skb->nh.ipv6h;
+	struct ipv6hdr *inner_iph = skb->h.ipv6h;
+
+	if (INET_ECN_is_ce(ipv6_get_dsfield(outer_iph)))
+		IP6_ECN_set_ce(inner_iph);
+}
+
+/* Add encapsulation header.
+ *
+ * The top IP header will be constructed per RFC 2401.  The following fields
+ * in it shall be filled in by x->type->output:
+ *	payload_len
+ *
+ * On exit, skb->h will be set to the start of the encapsulation header to be
+ * filled in by x->type->output and skb->nh will be set to the nextheader field
+ * of the extension header directly preceding the encapsulation header, or in
+ * its absence, that of the top IP header.  The value of skb->data will always
+ * point to the top IP header.
+ */
+static int xfrm6_tunnel_output(struct sk_buff *skb)
+{
+	struct dst_entry *dst = skb->dst;
+	struct xfrm_state *x = dst->xfrm;
+	struct ipv6hdr *iph, *top_iph;
+	int dsfield;
+
+	skb_push(skb, x->props.header_len);
+	iph = skb->nh.ipv6h;
+
+	skb->nh.raw = skb->data;
+	top_iph = skb->nh.ipv6h;
+	skb->nh.raw = &top_iph->nexthdr;
+	skb->h.ipv6h = top_iph + 1;
+
+	top_iph->version = 6;
+	top_iph->priority = iph->priority;
+	top_iph->flow_lbl[0] = iph->flow_lbl[0];
+	top_iph->flow_lbl[1] = iph->flow_lbl[1];
+	top_iph->flow_lbl[2] = iph->flow_lbl[2];
+	dsfield = ipv6_get_dsfield(top_iph);
+	dsfield = INET_ECN_encapsulate(dsfield, dsfield);
+	if (x->props.flags & XFRM_STATE_NOECN)
+		dsfield &= ~INET_ECN_MASK;
+	ipv6_change_dsfield(top_iph, 0, dsfield);
+	top_iph->nexthdr = IPPROTO_IPV6; 
+	top_iph->hop_limit = dst_metric(dst->child, RTAX_HOPLIMIT);
+	ipv6_addr_copy(&top_iph->saddr, (struct in6_addr *)&x->props.saddr);
+	ipv6_addr_copy(&top_iph->daddr, (struct in6_addr *)&x->id.daddr);
+	return 0;
+}
+
+static int xfrm6_tunnel_input(struct xfrm_state *x, struct sk_buff *skb)
+{
+	int err = -EINVAL;
+
+	if (skb->nh.raw[IP6CB(skb)->nhoff] != IPPROTO_IPV6)
+		goto out;
+	if (!pskb_may_pull(skb, sizeof(struct ipv6hdr)))
+		goto out;
+
+	if (skb_cloned(skb) &&
+	    (err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC)))
+		goto out;
+
+	if (x->props.flags & XFRM_STATE_DECAP_DSCP)
+		ipv6_copy_dscp(skb->nh.ipv6h, skb->h.ipv6h);
+	if (!(x->props.flags & XFRM_STATE_NOECN))
+		ipip6_ecn_decapsulate(skb);
+	skb->mac.raw = memmove(skb->data - skb->mac_len,
+			       skb->mac.raw, skb->mac_len);
+	skb->nh.raw = skb->data;
+	err = 0;
+
+out:
+	return err;
+}
+
+static struct xfrm_mode xfrm6_tunnel_mode = {
+	.input = xfrm6_tunnel_input,
+	.output = xfrm6_tunnel_output,
+	.owner = THIS_MODULE,
+	.encap = XFRM_MODE_TUNNEL,
+};
+
+static int __init xfrm6_tunnel_init(void)
+{
+	return xfrm_register_mode(&xfrm6_tunnel_mode, AF_INET6);
+}
+
+static void __exit xfrm6_tunnel_exit(void)
+{
+	int err;
+
+	err = xfrm_unregister_mode(&xfrm6_tunnel_mode, AF_INET6);
+	BUG_ON(err);
+}
+
+module_init(xfrm6_tunnel_init);
+module_exit(xfrm6_tunnel_exit);
+MODULE_LICENSE("GPL");
+MODULE_ALIAS_XFRM_MODE(AF_INET6, XFRM_MODE_TUNNEL);
diff --git a/net/netfilter/xt_CONNSECMARK.c b/net/netfilter/xt_CONNSECMARK.c
new file mode 100644
index 000000000..8c011e020
--- /dev/null
+++ b/net/netfilter/xt_CONNSECMARK.c
@@ -0,0 +1,155 @@
+/*
+ * This module is used to copy security markings from packets
+ * to connections, and restore security markings from connections
+ * back to packets.  This would normally be performed in conjunction
+ * with the SECMARK target and state match.
+ *
+ * Based somewhat on CONNMARK:
+ *   Copyright (C) 2002,2004 MARA Systems AB <http://www.marasystems.com>
+ *    by Henrik Nordstrom <hno@marasystems.com>
+ *
+ * (C) 2006 Red Hat, Inc., James Morris <jmorris@redhat.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+#include <linux/module.h>
+#include <linux/skbuff.h>
+#include <linux/netfilter/x_tables.h>
+#include <linux/netfilter/xt_CONNSECMARK.h>
+#include <net/netfilter/nf_conntrack_compat.h>
+
+#define PFX "CONNSECMARK: "
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("James Morris <jmorris@redhat.com>");
+MODULE_DESCRIPTION("ip[6]tables CONNSECMARK module");
+MODULE_ALIAS("ipt_CONNSECMARK");
+MODULE_ALIAS("ip6t_CONNSECMARK");
+
+/*
+ * If the packet has a security mark and the connection does not, copy
+ * the security mark from the packet to the connection.
+ */
+static void secmark_save(struct sk_buff *skb)
+{
+	if (skb->secmark) {
+		u32 *connsecmark;
+		enum ip_conntrack_info ctinfo;
+
+		connsecmark = nf_ct_get_secmark(skb, &ctinfo);
+		if (connsecmark && !*connsecmark)
+			if (*connsecmark != skb->secmark)
+				*connsecmark = skb->secmark;
+	}
+}
+
+/*
+ * If packet has no security mark, and the connection does, restore the
+ * security mark from the connection to the packet.
+ */
+static void secmark_restore(struct sk_buff *skb)
+{
+	if (!skb->secmark) {
+		u32 *connsecmark;
+		enum ip_conntrack_info ctinfo;
+
+		connsecmark = nf_ct_get_secmark(skb, &ctinfo);
+		if (connsecmark && *connsecmark)
+			if (skb->secmark != *connsecmark)
+				skb->secmark = *connsecmark;
+	}
+}
+
+static unsigned int target(struct sk_buff **pskb, const struct net_device *in,
+			   const struct net_device *out, unsigned int hooknum,
+			   const struct xt_target *target,
+			   const void *targinfo, void *userinfo)
+{
+	struct sk_buff *skb = *pskb;
+	const struct xt_connsecmark_target_info *info = targinfo;
+
+	switch (info->mode) {
+	case CONNSECMARK_SAVE:
+		secmark_save(skb);
+		break;
+
+	case CONNSECMARK_RESTORE:
+		secmark_restore(skb);
+		break;
+
+	default:
+		BUG();
+	}
+
+	return XT_CONTINUE;
+}
+
+static int checkentry(const char *tablename, const void *entry,
+		      const struct xt_target *target, void *targinfo,
+		      unsigned int targinfosize, unsigned int hook_mask)
+{
+	struct xt_connsecmark_target_info *info = targinfo;
+
+	switch (info->mode) {
+	case CONNSECMARK_SAVE:
+	case CONNSECMARK_RESTORE:
+		break;
+
+	default:
+		printk(KERN_INFO PFX "invalid mode: %hu\n", info->mode);
+		return 0;
+	}
+
+	return 1;
+}
+
+static struct xt_target ipt_connsecmark_reg = {
+	.name		= "CONNSECMARK",
+	.target		= target,
+	.targetsize	= sizeof(struct xt_connsecmark_target_info),
+	.table		= "mangle",
+	.checkentry	= checkentry,
+	.me		= THIS_MODULE,
+	.family		= AF_INET,
+	.revision	= 0,
+};
+
+static struct xt_target ip6t_connsecmark_reg = {
+	.name		= "CONNSECMARK",
+	.target		= target,
+	.targetsize	= sizeof(struct xt_connsecmark_target_info),
+	.table		= "mangle",
+	.checkentry	= checkentry,
+	.me		= THIS_MODULE,
+	.family		= AF_INET6,
+	.revision	= 0,
+};
+
+static int __init xt_connsecmark_init(void)
+{
+	int err;
+
+	need_conntrack();
+
+	err = xt_register_target(&ipt_connsecmark_reg);
+	if (err)
+		return err;
+
+	err = xt_register_target(&ip6t_connsecmark_reg);
+	if (err)
+		xt_unregister_target(&ipt_connsecmark_reg);
+
+	return err;
+}
+
+static void __exit xt_connsecmark_fini(void)
+{
+	xt_unregister_target(&ip6t_connsecmark_reg);
+	xt_unregister_target(&ipt_connsecmark_reg);
+}
+
+module_init(xt_connsecmark_init);
+module_exit(xt_connsecmark_fini);
diff --git a/net/netfilter/xt_SECMARK.c b/net/netfilter/xt_SECMARK.c
new file mode 100644
index 000000000..de9537ad9
--- /dev/null
+++ b/net/netfilter/xt_SECMARK.c
@@ -0,0 +1,158 @@
+/*
+ * Module for modifying the secmark field of the skb, for use by
+ * security subsystems.
+ *
+ * Based on the nfmark match by:
+ * (C) 1999-2001 Marc Boucher <marc@mbsi.ca>
+ *
+ * (C) 2006 Red Hat, Inc., James Morris <jmorris@redhat.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+#include <linux/module.h>
+#include <linux/skbuff.h>
+#include <linux/selinux.h>
+#include <linux/netfilter/x_tables.h>
+#include <linux/netfilter/xt_SECMARK.h>
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("James Morris <jmorris@redhat.com>");
+MODULE_DESCRIPTION("ip[6]tables SECMARK modification module");
+MODULE_ALIAS("ipt_SECMARK");
+MODULE_ALIAS("ip6t_SECMARK");
+
+#define PFX "SECMARK: "
+
+static u8 mode;
+
+static unsigned int target(struct sk_buff **pskb, const struct net_device *in,
+			   const struct net_device *out, unsigned int hooknum,
+			   const struct xt_target *target,
+			   const void *targinfo, void *userinfo)
+{
+	u32 secmark = 0;
+	const struct xt_secmark_target_info *info = targinfo;
+
+	BUG_ON(info->mode != mode);
+
+	switch (mode) {
+	case SECMARK_MODE_SEL:
+		secmark = info->u.sel.selsid;
+		break;
+
+	default:
+		BUG();
+	}
+
+	if ((*pskb)->secmark != secmark)
+		(*pskb)->secmark = secmark;
+
+	return XT_CONTINUE;
+}
+
+static int checkentry_selinux(struct xt_secmark_target_info *info)
+{
+	int err;
+	struct xt_secmark_target_selinux_info *sel = &info->u.sel;
+	
+	sel->selctx[SECMARK_SELCTX_MAX - 1] = '\0';
+
+	err = selinux_string_to_sid(sel->selctx, &sel->selsid);
+	if (err) {
+		if (err == -EINVAL)
+			printk(KERN_INFO PFX "invalid SELinux context \'%s\'\n",
+			       sel->selctx);
+		return 0;
+	}
+
+	if (!sel->selsid) {
+		printk(KERN_INFO PFX "unable to map SELinux context \'%s\'\n",
+		       sel->selctx);
+		return 0;
+	}
+
+	err = selinux_relabel_packet_permission(sel->selsid);
+	if (err) {
+		printk(KERN_INFO PFX "unable to obtain relabeling permission\n");
+		return 0;
+	}
+
+	return 1;
+}
+
+static int checkentry(const char *tablename, const void *entry,
+		      const struct xt_target *target, void *targinfo,
+		      unsigned int targinfosize, unsigned int hook_mask)
+{
+	struct xt_secmark_target_info *info = targinfo;
+
+	if (mode && mode != info->mode) {
+		printk(KERN_INFO PFX "mode already set to %hu cannot mix with "
+		       "rules for mode %hu\n", mode, info->mode);
+		return 0;
+	}
+
+	switch (info->mode) {
+	case SECMARK_MODE_SEL:
+		if (!checkentry_selinux(info))
+			return 0;
+		break;
+
+	default:
+		printk(KERN_INFO PFX "invalid mode: %hu\n", info->mode);
+		return 0;
+	}
+
+	if (!mode)
+		mode = info->mode;
+	return 1;
+}
+
+static struct xt_target ipt_secmark_reg = {
+	.name		= "SECMARK",
+	.target		= target,
+	.targetsize	= sizeof(struct xt_secmark_target_info),
+	.table		= "mangle",
+	.checkentry	= checkentry,
+	.me		= THIS_MODULE,
+	.family		= AF_INET,
+	.revision	= 0,
+};
+
+static struct xt_target ip6t_secmark_reg = {
+	.name		= "SECMARK",
+	.target		= target,
+	.targetsize	= sizeof(struct xt_secmark_target_info),
+	.table		= "mangle",
+	.checkentry	= checkentry,
+	.me		= THIS_MODULE,
+	.family		= AF_INET6,
+	.revision	= 0,
+};
+
+static int __init xt_secmark_init(void)
+{
+	int err;
+
+	err = xt_register_target(&ipt_secmark_reg);
+	if (err)
+		return err;
+
+	err = xt_register_target(&ip6t_secmark_reg);
+	if (err)
+		xt_unregister_target(&ipt_secmark_reg);
+
+	return err;
+}
+
+static void __exit xt_secmark_fini(void)
+{
+	xt_unregister_target(&ip6t_secmark_reg);
+	xt_unregister_target(&ipt_secmark_reg);
+}
+
+module_init(xt_secmark_init);
+module_exit(xt_secmark_fini);
diff --git a/net/netfilter/xt_quota.c b/net/netfilter/xt_quota.c
new file mode 100644
index 000000000..be8d3c26b
--- /dev/null
+++ b/net/netfilter/xt_quota.c
@@ -0,0 +1,98 @@
+/*
+ * netfilter module to enforce network quotas
+ *
+ * Sam Johnston <samj@samj.net>
+ */
+#include <linux/skbuff.h>
+#include <linux/spinlock.h>
+
+#include <linux/netfilter/x_tables.h>
+#include <linux/netfilter/xt_quota.h>
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Sam Johnston <samj@samj.net>");
+MODULE_ALIAS("ipt_quota");
+MODULE_ALIAS("ip6t_quota");
+
+static DEFINE_SPINLOCK(quota_lock);
+
+static int
+match(const struct sk_buff *skb,
+      const struct net_device *in, const struct net_device *out,
+      const struct xt_match *match, const void *matchinfo,
+      int offset, unsigned int protoff, int *hotdrop)
+{
+	struct xt_quota_info *q = ((struct xt_quota_info *)matchinfo)->master;
+	int ret = q->flags & XT_QUOTA_INVERT ? 1 : 0;
+
+	spin_lock_bh(&quota_lock);
+	if (q->quota >= skb->len) {
+		q->quota -= skb->len;
+		ret ^= 1;
+	} else {
+	        /* we do not allow even small packets from now on */
+	        q->quota = 0;
+	}
+	spin_unlock_bh(&quota_lock);
+
+	return ret;
+}
+
+static int
+checkentry(const char *tablename, const void *entry,
+	   const struct xt_match *match, void *matchinfo,
+	   unsigned int matchsize, unsigned int hook_mask)
+{
+	struct xt_quota_info *q = (struct xt_quota_info *)matchinfo;
+
+	if (q->flags & ~XT_QUOTA_MASK)
+		return 0;
+	/* For SMP, we only want to use one set of counters. */
+	q->master = q;
+	return 1;
+}
+
+static struct xt_match quota_match = {
+	.name		= "quota",
+	.family		= AF_INET,
+	.match		= match,
+	.matchsize	= sizeof(struct xt_quota_info),
+	.checkentry	= checkentry,
+	.me		= THIS_MODULE
+};
+
+static struct xt_match quota_match6 = {
+	.name		= "quota",
+	.family		= AF_INET6,
+	.match		= match,
+	.matchsize	= sizeof(struct xt_quota_info),
+	.checkentry	= checkentry,
+	.me		= THIS_MODULE
+};
+
+static int __init xt_quota_init(void)
+{
+	int ret;
+
+	ret = xt_register_match(&quota_match);
+	if (ret)
+		goto err1;
+	ret = xt_register_match(&quota_match6);
+	if (ret)
+		goto err2;
+	return ret;
+
+err2:
+	xt_unregister_match(&quota_match);
+err1:
+	return ret;
+}
+
+static void __exit xt_quota_fini(void)
+{
+	xt_unregister_match(&quota_match6);
+	xt_unregister_match(&quota_match);
+}
+
+module_init(xt_quota_init);
+module_exit(xt_quota_fini);
diff --git a/net/netfilter/xt_statistic.c b/net/netfilter/xt_statistic.c
new file mode 100644
index 000000000..de1037f58
--- /dev/null
+++ b/net/netfilter/xt_statistic.c
@@ -0,0 +1,112 @@
+/*
+ * Copyright (c) 2006 Patrick McHardy <kaber@trash.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.
+ *
+ * Based on ipt_random and ipt_nth by Fabrice MARIE <fabrice@netfilter.org>.
+ */
+
+#include <linux/init.h>
+#include <linux/spinlock.h>
+#include <linux/skbuff.h>
+#include <linux/net.h>
+
+#include <linux/netfilter/xt_statistic.h>
+#include <linux/netfilter/x_tables.h>
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>");
+MODULE_DESCRIPTION("xtables statistical match module");
+MODULE_ALIAS("ipt_statistic");
+MODULE_ALIAS("ip6t_statistic");
+
+static DEFINE_SPINLOCK(nth_lock);
+
+static int
+match(const struct sk_buff *skb,
+      const struct net_device *in, const struct net_device *out,
+      const struct xt_match *match, const void *matchinfo,
+      int offset, unsigned int protoff, int *hotdrop)
+{
+	struct xt_statistic_info *info = (struct xt_statistic_info *)matchinfo;
+	int ret = info->flags & XT_STATISTIC_INVERT ? 1 : 0;
+
+	switch (info->mode) {
+	case XT_STATISTIC_MODE_RANDOM:
+		if ((net_random() & 0x7FFFFFFF) < info->u.random.probability)
+			ret ^= 1;
+		break;
+	case XT_STATISTIC_MODE_NTH:
+		info = info->master;
+		spin_lock_bh(&nth_lock);
+		if (info->u.nth.count++ == info->u.nth.every) {
+			info->u.nth.count = 0;
+			ret ^= 1;
+		}
+		spin_unlock_bh(&nth_lock);
+		break;
+	}
+
+	return ret;
+}
+
+static int
+checkentry(const char *tablename, const void *entry,
+	   const struct xt_match *match, void *matchinfo,
+	   unsigned int matchsize, unsigned int hook_mask)
+{
+	struct xt_statistic_info *info = (struct xt_statistic_info *)matchinfo;
+
+	if (info->mode > XT_STATISTIC_MODE_MAX ||
+	    info->flags & ~XT_STATISTIC_MASK)
+		return 0;
+	info->master = info;
+	return 1;
+}
+
+static struct xt_match statistic_match = {
+	.name		= "statistic",
+	.match		= match,
+	.matchsize	= sizeof(struct xt_statistic_info),
+	.checkentry	= checkentry,
+	.family		= AF_INET,
+	.me		= THIS_MODULE,
+};
+
+static struct xt_match statistic_match6 = {
+	.name		= "statistic",
+	.match		= match,
+	.matchsize	= sizeof(struct xt_statistic_info),
+	.checkentry	= checkentry,
+	.family		= AF_INET6,
+	.me		= THIS_MODULE,
+};
+
+static int __init xt_statistic_init(void)
+{
+	int ret;
+
+	ret = xt_register_match(&statistic_match);
+	if (ret)
+		goto err1;
+
+	ret = xt_register_match(&statistic_match6);
+	if (ret)
+		goto err2;
+	return ret;
+err2:
+	xt_unregister_match(&statistic_match);
+err1:
+	return ret;
+}
+
+static void __exit xt_statistic_fini(void)
+{
+	xt_unregister_match(&statistic_match6);
+	xt_unregister_match(&statistic_match);
+}
+
+module_init(xt_statistic_init);
+module_exit(xt_statistic_fini);
diff --git a/scripts/Makefile.headersinst b/scripts/Makefile.headersinst
new file mode 100644
index 000000000..12e1daf87
--- /dev/null
+++ b/scripts/Makefile.headersinst
@@ -0,0 +1,160 @@
+# ==========================================================================
+# Installing headers
+#
+# header-y files will be installed verbatim
+# unifdef-y are the files where unifdef will be run before installing files
+# objhdr-y are generated files that will be installed verbatim
+#
+# ==========================================================================
+
+UNIFDEF := unifdef -U__KERNEL__
+
+# Eliminate the contents of (and inclusions of) compiler.h
+HDRSED  := sed 	-e "s/ inline / __inline__ /g" \
+		-e "s/[[:space:]]__user[[:space:]]\+/ /g" \
+		-e "s/(__user[[:space:]]\+/ (/g" \
+		-e "s/[[:space:]]__force[[:space:]]\+/ /g" \
+		-e "s/(__force[[:space:]]\+/ (/g" \
+		-e "s/[[:space:]]__iomem[[:space:]]\+/ /g" \
+		-e "s/(__iomem[[:space:]]\+/ (/g" \
+		-e "s/[[:space:]]__attribute_const__[[:space:]]\+/\ /g" \
+		-e "s/[[:space:]]__attribute_const__$$//" \
+		-e "/^\#include <linux\/compiler.h>/d"
+
+_dst := $(if $(dst),$(dst),$(obj))
+
+.PHONY: __headersinst
+__headersinst:
+
+
+ifeq (,$(patsubst include/asm/%,,$(obj)/))
+# For producing the generated stuff in include/asm for biarch builds, include
+# both sets of Kbuild files; we'll generate anything which is mentioned in
+# _either_ arch, and recurse into subdirectories which are mentioned in either
+# arch. Since some directories may exist in one but not the other, we must
+# use '-include'.
+GENASM := 1
+archasm	   := $(subst include/asm,asm-$(ARCH),$(obj))
+altarchasm := $(subst include/asm,asm-$(ALTARCH),$(obj))
+-include $(srctree)/include/$(archasm)/Kbuild
+-include $(srctree)/include/$(altarchasm)/Kbuild
+else
+include $(srctree)/$(obj)/Kbuild
+endif
+
+include scripts/Kbuild.include
+
+# If this is include/asm-$(ARCH) and there's no $(ALTARCH), then
+# override $(_dst) so that we install to include/asm directly.
+ifeq ($(obj)$(ALTARCH),include/asm-$(ARCH))
+     _dst := include/asm
+endif
+
+header-y	:= $(sort $(header-y))
+unifdef-y	:= $(sort $(unifdef-y))
+subdir-y	:= $(patsubst %/,%,$(filter %/, $(header-y)))
+header-y	:= $(filter-out %/, $(header-y))
+header-y	:= $(filter-out $(unifdef-y),$(header-y))
+
+ifdef ALTARCH
+ifeq ($(obj),include/asm-$(ARCH))
+altarch-y	:= altarch-dir
+endif
+endif
+
+# Make the definitions visible for recursive make invocations
+export ALTARCH
+export ARCHDEF
+export ALTARCHDEF
+
+quiet_cmd_o_hdr_install   = INSTALL $(_dst)/$@
+      cmd_o_hdr_install   = cp $(objtree)/$(obj)/$@ $(INSTALL_HDR_PATH)/$(_dst)
+
+quiet_cmd_headers_install = INSTALL $(_dst)/$@
+      cmd_headers_install = $(HDRSED) $(srctree)/$(obj)/$@		\
+			    > $(INSTALL_HDR_PATH)/$(_dst)/$@
+
+quiet_cmd_unifdef	  = UNIFDEF $(_dst)/$@
+      cmd_unifdef	  = $(UNIFDEF) $(srctree)/$(obj)/$@ | $(HDRSED)	\
+                            > $(INSTALL_HDR_PATH)/$(_dst)/$@ || :
+
+quiet_cmd_check		  = CHECK   $(_dst)/$@
+      cmd_check		  = $(srctree)/scripts/hdrcheck.sh		\
+                              $(INSTALL_HDR_PATH)/include		\
+			      $(INSTALL_HDR_PATH)/$(_dst)/$@
+
+quiet_cmd_mkdir		  = MKDIR   $@
+      cmd_mkdir		  = mkdir -p $(INSTALL_HDR_PATH)/$@
+
+quiet_cmd_gen		  = GEN     $(_dst)/$@
+      cmd_gen		  = \
+STUBDEF=__ASM_STUB_`echo $@ | tr a-z. A-Z_`;				\
+(echo "/* File autogenerated by 'make headers_install' */" ;		\
+echo "\#ifndef $$STUBDEF" ;						\
+echo "\#define $$STUBDEF" ;						\
+echo "\# if $(ARCHDEF)" ;						\
+if [ -r $(INSTALL_HDR_PATH)/include/$(archasm)/$@ ]; then		\
+	echo "\#  include <$(archasm)/$@>" ;				\
+else									\
+	echo "\#  error $(archasm)/$@ does not exist in"		\
+			"the $(ARCH) architecture" ;			\
+fi ;									\
+echo "\# elif $(ALTARCHDEF)" ;						\
+if [ -r $(INSTALL_HDR_PATH)/include/$(altarchasm)/$@ ]; then		\
+	echo "\#  include <$(altarchasm)/$@>" ;				\
+else									\
+	echo "\#  error $(altarchasm)/$@ does not exist in"		\
+			"the $(ALTARCH) architecture" ;			\
+fi ;									\
+echo "\# else" ;							\
+echo "\#  warning This machine appears to be"				\
+		 "neither $(ARCH) nor $(ALTARCH)." ;			\
+echo "\# endif" ;							\
+echo "\#endif /* $$STUBDEF */" ;					\
+) > $(INSTALL_HDR_PATH)/$(_dst)/$@
+
+__headersinst: $(subdir-y) $(header-y) $(unifdef-y) $(altarch-y) $(objhdr-y)
+
+.PHONY: $(header-y) $(unifdef-y) $(subdir-y)
+
+ifdef HDRCHECK
+# Rules for checking headers
+$(objhdr-y) $(header-y) $(unifdef-y):
+	$(call cmd,check)
+else
+# Rules for installing headers
+
+$(objhdr-y) $(subdir-y) $(header-y) $(unifdef-y): $(_dst)
+
+.PHONY: $(_dst)
+$(_dst):
+	$(call cmd,mkdir)
+
+ifdef GENASM
+$(objhdr-y) $(header-y) $(unifdef-y):
+	$(call cmd,gen)
+
+else
+$(objhdr-y):
+	$(call cmd,o_hdr_install)
+
+$(header-y):
+	$(call cmd,headers_install)
+
+$(unifdef-y):
+	$(call cmd,unifdef)
+endif
+endif
+
+hdrinst := -rR -f $(srctree)/scripts/Makefile.headersinst obj
+
+.PHONY: altarch-dir
+# All the files in the normal arch dir must be created first, since we test
+# for their existence.
+altarch-dir: $(subdir-y) $(header-y) $(unifdef-y) $(objhdr-y)
+	$(Q)$(MAKE) $(hdrinst)=include/asm-$(ALTARCH) dst=include/asm-$(ALTARCH)
+	$(Q)$(MAKE) $(hdrinst)=include/asm dst=include/asm
+
+# Recursion
+$(subdir-y):
+	$(Q)$(MAKE) $(hdrinst)=$(obj)/$@ dst=$(_dst)/$@ rel=../$(rel)
diff --git a/scripts/export_report.pl b/scripts/export_report.pl
new file mode 100644
index 000000000..9ed00d9bb
--- /dev/null
+++ b/scripts/export_report.pl
@@ -0,0 +1,169 @@
+#!/usr/bin/perl -w
+#
+# (C) Copyright IBM Corporation 2006.
+#	Released under GPL v2.
+#	Author : Ram Pai (linuxram@us.ibm.com)
+#
+# Usage: export_report.pl -k Module.symvers [-o report_file ] -f *.mod.c
+#
+
+use Getopt::Std;
+use strict;
+
+sub numerically {
+	my $no1 = (split /\s+/, $a)[1];
+	my $no2 = (split /\s+/, $b)[1];
+	return $no1 <=> $no2;
+}
+
+sub alphabetically {
+	my ($module1, $value1) = @{$a};
+	my ($module2, $value2) = @{$b};
+	return $value1 <=> $value2 || $module2 cmp $module1;
+}
+
+sub print_depends_on {
+	my ($href) = @_;
+	print "\n";
+	while (my ($mod, $list) = each %$href) {
+		print "\t$mod:\n";
+		foreach my $sym (sort numerically @{$list}) {
+			my ($symbol, $no) = split /\s+/, $sym;
+			printf("\t\t%-25s\t%-25d\n", $symbol, $no);
+		}
+		print "\n";
+	}
+	print "\n";
+	print "~"x80 , "\n";
+}
+
+sub usage {
+        print "Usage: @_ -h -k Module.symvers  [ -o outputfile ] \n",
+	      "\t-f: treat all the non-option argument as .mod.c files. ",
+	      "Recommend using this as the last option\n",
+	      "\t-h: print detailed help\n",
+	      "\t-k: the path to Module.symvers file. By default uses ",
+	      "the file from the current directory\n",
+	      "\t-o outputfile: output the report to outputfile\n";
+	exit 0;
+}
+
+sub collectcfiles {
+        my @file = `cat .tmp_versions/*.mod | grep '.*\.ko\$'`;
+        @file = grep {s/\.ko/.mod.c/} @file;
+	chomp @file;
+        return @file;
+}
+
+my (%SYMBOL, %MODULE, %opt, @allcfiles);
+
+if (not getopts('hk:o:f',\%opt) or defined $opt{'h'}) {
+        usage($0);
+}
+
+if (defined $opt{'f'}) {
+	@allcfiles = @ARGV;
+} else {
+	@allcfiles = collectcfiles();
+}
+
+if (not defined $opt{'k'}) {
+	$opt{'k'} = "Module.symvers";
+}
+
+unless (open(MODULE_SYMVERS, $opt{'k'})) {
+	die "Sorry, cannot open $opt{'k'}: $!\n";
+}
+
+if (defined $opt{'o'}) {
+	unless (open(OUTPUT_HANDLE, ">$opt{'o'}")) {
+		die "Sorry, cannot open $opt{'o'} $!\n";
+	}
+	select OUTPUT_HANDLE;
+}
+#
+# collect all the symbols and their attributes from the
+# Module.symvers file
+#
+while ( <MODULE_SYMVERS> ) {
+	chomp;
+	my (undef, $symbol, $module, $gpl) = split;
+	$SYMBOL { $symbol } =  [ $module , "0" , $symbol, $gpl];
+}
+close(MODULE_SYMVERS);
+
+#
+# collect the usage count of each symbol.
+#
+foreach my $thismod (@allcfiles) {
+	unless (open(MODULE_MODULE, $thismod)) {
+		print "Sorry, cannot open $thismod: $!\n";
+		next;
+	}
+	my $state=0;
+	while ( <MODULE_MODULE> ) {
+		chomp;
+		if ($state eq 0) {
+			$state = 1 if ($_ =~ /static const struct modversion_info/);
+			next;
+		}
+		if ($state eq 1) {
+			$state = 2 if ($_ =~ /__attribute__\(\(section\("__versions"\)\)\)/);
+			next;
+		}
+		if ($state eq 2) {
+			if ( $_ !~ /0x[0-9a-f]{7,8},/ ) {
+				next;
+			}
+			my $sym = (split /([,"])/,)[4];
+			my ($module, $value, $symbol, $gpl) = @{$SYMBOL{$sym}};
+			$SYMBOL{ $sym } =  [ $module, $value+1, $symbol, $gpl];
+			push(@{$MODULE{$thismod}} , $sym);
+		}
+	}
+	if ($state ne 2) {
+		print "WARNING:$thismod is not built with CONFIG_MODVERSION enabled\n";
+	}
+	close(MODULE_MODULE);
+}
+
+print "\tThis file reports the exported symbols usage patterns by in-tree\n",
+	"\t\t\t\tmodules\n";
+printf("%s\n\n\n","x"x80);
+printf("\t\t\t\tINDEX\n\n\n");
+printf("SECTION 1: Usage counts of all exported symbols\n");
+printf("SECTION 2: List of modules and the exported symbols they use\n");
+printf("%s\n\n\n","x"x80);
+printf("SECTION 1:\tThe exported symbols and their usage count\n\n");
+printf("%-25s\t%-25s\t%-5s\t%-25s\n", "Symbol", "Module", "Usage count",
+	"export type");
+
+#
+# print the list of unused exported symbols
+#
+foreach my $list (sort alphabetically values(%SYMBOL)) {
+	my ($module, $value, $symbol, $gpl) = @{$list};
+	printf("%-25s\t%-25s\t%-10s\t", $symbol, $module, $value);
+	if (defined $gpl) {
+		printf("%-25s\n",$gpl);
+	} else {
+		printf("\n");
+	}
+}
+printf("%s\n\n\n","x"x80);
+
+printf("SECTION 2:\n\tThis section reports export-symbol-usage of in-kernel
+modules. Each module lists the modules, and the symbols from that module that
+it uses.  Each listed symbol reports the number of modules using it\n");
+
+print "~"x80 , "\n";
+while (my ($thismod, $list) = each %MODULE) {
+	my %depends;
+	$thismod =~ s/\.mod\.c/.ko/;
+	print "\t\t\t$thismod\n";
+	foreach my $symbol (@{$list}) {
+		my ($module, $value, undef, $gpl) = @{$SYMBOL{$symbol}};
+		push (@{$depends{"$module"}}, "$symbol $value");
+	}
+	print_depends_on(\%depends);
+}
diff --git a/scripts/hdrcheck.sh b/scripts/hdrcheck.sh
new file mode 100755
index 000000000..b5ca35aa1
--- /dev/null
+++ b/scripts/hdrcheck.sh
@@ -0,0 +1,8 @@
+#!/bin/sh
+
+for FILE in `grep '^[ \t]*#[ \t]*include[ \t]*<' $2 | cut -f2 -d\< | cut -f1 -d\> | egrep ^linux\|^asm` ; do
+    if [ ! -r $1/$FILE ]; then
+	echo $2 requires $FILE, which does not exist in exported headers
+	exit 1
+    fi
+done
diff --git a/scripts/rt-tester/check-all.sh b/scripts/rt-tester/check-all.sh
new file mode 100644
index 000000000..43098afe7
--- /dev/null
+++ b/scripts/rt-tester/check-all.sh
@@ -0,0 +1,22 @@
+
+
+function testit ()
+{
+ printf "%-30s: " $1
+ ./rt-tester.py $1 | grep Pass
+}
+
+testit t2-l1-2rt-sameprio.tst
+testit t2-l1-pi.tst
+testit t2-l1-signal.tst
+#testit t2-l2-2rt-deadlock.tst
+testit t3-l1-pi-1rt.tst
+testit t3-l1-pi-2rt.tst
+testit t3-l1-pi-3rt.tst
+testit t3-l1-pi-signal.tst
+testit t3-l1-pi-steal.tst
+testit t3-l2-pi.tst
+testit t4-l2-pi-deboost.tst
+testit t5-l4-pi-boost-deboost.tst
+testit t5-l4-pi-boost-deboost-setsched.tst
+
diff --git a/scripts/rt-tester/rt-tester.py b/scripts/rt-tester/rt-tester.py
new file mode 100644
index 000000000..4c7966079
--- /dev/null
+++ b/scripts/rt-tester/rt-tester.py
@@ -0,0 +1,222 @@
+#!/usr/bin/env python
+#
+# rt-mutex tester
+#
+# (C) 2006 Thomas Gleixner <tglx@linutronix.de>
+#
+# 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.
+#
+import os
+import sys
+import getopt
+import shutil
+import string
+
+# Globals
+quiet = 0
+test = 0
+comments = 0
+
+sysfsprefix = "/sys/devices/system/rttest/rttest"
+statusfile = "/status"
+commandfile = "/command"
+
+# Command opcodes
+cmd_opcodes = {
+    "schedother"    : "1",
+    "schedfifo"     : "2",
+    "lock"          : "3",
+    "locknowait"    : "4",
+    "lockint"       : "5",
+    "lockintnowait" : "6",
+    "lockcont"      : "7",
+    "unlock"        : "8",
+    "lockbkl"       : "9",
+    "unlockbkl"     : "10",
+    "signal"        : "11",
+    "resetevent"    : "98",
+    "reset"         : "99",
+    }
+
+test_opcodes = {
+    "prioeq"        : ["P" , "eq" , None],
+    "priolt"        : ["P" , "lt" , None],
+    "priogt"        : ["P" , "gt" , None],
+    "nprioeq"       : ["N" , "eq" , None],
+    "npriolt"       : ["N" , "lt" , None],
+    "npriogt"       : ["N" , "gt" , None],
+    "unlocked"      : ["M" , "eq" , 0],
+    "trylock"       : ["M" , "eq" , 1],
+    "blocked"       : ["M" , "eq" , 2],
+    "blockedwake"   : ["M" , "eq" , 3],
+    "locked"        : ["M" , "eq" , 4],
+    "opcodeeq"      : ["O" , "eq" , None],
+    "opcodelt"      : ["O" , "lt" , None],
+    "opcodegt"      : ["O" , "gt" , None],
+    "eventeq"       : ["E" , "eq" , None],
+    "eventlt"       : ["E" , "lt" , None],
+    "eventgt"       : ["E" , "gt" , None],
+    }
+
+# Print usage information
+def usage():
+    print "rt-tester.py <-c -h -q -t> <testfile>"
+    print " -c    display comments after first command"
+    print " -h    help"
+    print " -q    quiet mode"
+    print " -t    test mode (syntax check)"
+    print " testfile: read test specification from testfile"
+    print " otherwise from stdin"
+    return
+
+# Print progress when not in quiet mode
+def progress(str):
+    if not quiet:
+        print str
+
+# Analyse a status value
+def analyse(val, top, arg):
+
+    intval = int(val)
+
+    if top[0] == "M":
+        intval = intval / (10 ** int(arg))
+	intval = intval % 10
+        argval = top[2]
+    elif top[0] == "O":
+        argval = int(cmd_opcodes.get(arg, arg))
+    else:
+        argval = int(arg)
+
+    # progress("%d %s %d" %(intval, top[1], argval))
+
+    if top[1] == "eq" and intval == argval:
+	return 1
+    if top[1] == "lt" and intval < argval:
+        return 1
+    if top[1] == "gt" and intval > argval:
+	return 1
+    return 0
+
+# Parse the commandline
+try:
+    (options, arguments) = getopt.getopt(sys.argv[1:],'chqt')
+except getopt.GetoptError, ex:
+    usage()
+    sys.exit(1)
+
+# Parse commandline options
+for option, value in options:
+    if option == "-c":
+        comments = 1
+    elif option == "-q":
+        quiet = 1
+    elif option == "-t":
+        test = 1
+    elif option == '-h':
+        usage()
+        sys.exit(0)
+
+# Select the input source
+if arguments:
+    try:
+        fd = open(arguments[0])
+    except Exception,ex:
+        sys.stderr.write("File not found %s\n" %(arguments[0]))
+        sys.exit(1)
+else:
+    fd = sys.stdin
+
+linenr = 0
+
+# Read the test patterns
+while 1:
+
+    linenr = linenr + 1
+    line = fd.readline()
+    if not len(line):
+        break
+
+    line = line.strip()
+    parts = line.split(":")
+
+    if not parts or len(parts) < 1:
+        continue
+
+    if len(parts[0]) == 0:
+        continue
+
+    if parts[0].startswith("#"):
+	if comments > 1:
+	    progress(line)
+	continue
+
+    if comments == 1:
+	comments = 2
+
+    progress(line)
+
+    cmd = parts[0].strip().lower()
+    opc = parts[1].strip().lower()
+    tid = parts[2].strip()
+    dat = parts[3].strip()
+
+    try:
+        # Test or wait for a status value
+        if cmd == "t" or cmd == "w":
+            testop = test_opcodes[opc]
+
+            fname = "%s%s%s" %(sysfsprefix, tid, statusfile)
+            if test:
+		print fname
+                continue
+
+            while 1:
+                query = 1
+                fsta = open(fname, 'r')
+                status = fsta.readline().strip()
+                fsta.close()
+                stat = status.split(",")
+                for s in stat:
+		    s = s.strip()
+                    if s.startswith(testop[0]):
+                        # Seperate status value
+                        val = s[2:].strip()
+                        query = analyse(val, testop, dat)
+                        break
+                if query or cmd == "t":
+                    break
+
+            progress("   " + status)
+
+            if not query:
+                sys.stderr.write("Test failed in line %d\n" %(linenr))
+		sys.exit(1)
+
+        # Issue a command to the tester
+        elif cmd == "c":
+            cmdnr = cmd_opcodes[opc]
+            # Build command string and sys filename
+            cmdstr = "%s:%s" %(cmdnr, dat)
+            fname = "%s%s%s" %(sysfsprefix, tid, commandfile)
+            if test:
+		print fname
+                continue
+            fcmd = open(fname, 'w')
+            fcmd.write(cmdstr)
+            fcmd.close()
+
+    except Exception,ex:
+    	sys.stderr.write(str(ex))
+        sys.stderr.write("\nSyntax error in line %d\n" %(linenr))
+        if not test:
+            fd.close()
+            sys.exit(1)
+
+# Normal exit pass
+print "Pass"
+sys.exit(0)
+
+
diff --git a/scripts/rt-tester/t2-l1-2rt-sameprio.tst b/scripts/rt-tester/t2-l1-2rt-sameprio.tst
new file mode 100644
index 000000000..8821f27cc
--- /dev/null
+++ b/scripts/rt-tester/t2-l1-2rt-sameprio.tst
@@ -0,0 +1,99 @@
+#
+# RT-Mutex test
+#
+# Op: C(ommand)/T(est)/W(ait)
+# |  opcode
+# |  |     threadid: 0-7
+# |  |     |  opcode argument
+# |  |     |  |
+# C: lock: 0: 0
+#
+# Commands
+#
+# opcode	opcode argument
+# schedother	nice value
+# schedfifo	priority
+# lock		lock nr (0-7)
+# locknowait	lock nr (0-7)
+# lockint	lock nr (0-7)
+# lockintnowait	lock nr (0-7)
+# lockcont	lock nr (0-7)
+# unlock	lock nr (0-7)
+# lockbkl	lock nr (0-7)
+# unlockbkl	lock nr (0-7)
+# signal	0
+# reset		0
+# resetevent	0
+#
+# Tests / Wait
+#
+# opcode	opcode argument
+#
+# prioeq	priority
+# priolt	priority
+# priogt	priority
+# nprioeq	normal priority
+# npriolt	normal priority
+# npriogt	normal priority
+# locked	lock nr (0-7)
+# blocked	lock nr (0-7)
+# blockedwake	lock nr (0-7)
+# unlocked	lock nr (0-7)
+# lockedbkl	dont care
+# blockedbkl	dont care
+# unlockedbkl	dont care
+# opcodeeq	command opcode or number
+# opcodelt	number
+# opcodegt	number
+# eventeq	number
+# eventgt	number
+# eventlt	number
+
+#
+# 2 threads 1 lock
+#
+C: resetevent:		0: 	0
+W: opcodeeq:		0: 	0
+
+# Set schedulers
+C: schedfifo:		0: 	80
+C: schedfifo:		1: 	80
+
+# T0 lock L0
+C: locknowait:		0: 	0
+C: locknowait:		1:	0
+W: locked:		0: 	0
+W: blocked:		1: 	0
+T: prioeq:		0: 	80
+
+# T0 unlock L0
+C: unlock:		0: 	0
+W: locked:		1: 	0
+
+# Verify T0
+W: unlocked:		0: 	0
+T: prioeq:		0: 	80
+
+# Unlock
+C: unlock:		1: 	0
+W: unlocked:		1: 	0
+
+# T1,T0 lock L0
+C: locknowait:		1: 	0
+C: locknowait:		0:	0
+W: locked:		1: 	0
+W: blocked:		0: 	0
+T: prioeq:		1: 	80
+
+# T1 unlock L0
+C: unlock:		1: 	0
+W: locked:		0: 	0
+
+# Verify T1
+W: unlocked:		1: 	0
+T: prioeq:		1: 	80
+
+# Unlock and exit
+C: unlock:		0: 	0
+W: unlocked:		0: 	0
+
diff --git a/scripts/rt-tester/t2-l1-pi.tst b/scripts/rt-tester/t2-l1-pi.tst
new file mode 100644
index 000000000..cde1f189a
--- /dev/null
+++ b/scripts/rt-tester/t2-l1-pi.tst
@@ -0,0 +1,82 @@
+#
+# RT-Mutex test
+#
+# Op: C(ommand)/T(est)/W(ait)
+# |  opcode
+# |  |     threadid: 0-7
+# |  |     |  opcode argument
+# |  |     |  |
+# C: lock: 0: 0
+#
+# Commands
+#
+# opcode	opcode argument
+# schedother	nice value
+# schedfifo	priority
+# lock		lock nr (0-7)
+# locknowait	lock nr (0-7)
+# lockint	lock nr (0-7)
+# lockintnowait	lock nr (0-7)
+# lockcont	lock nr (0-7)
+# unlock	lock nr (0-7)
+# lockbkl	lock nr (0-7)
+# unlockbkl	lock nr (0-7)
+# signal	0
+# reset		0
+# resetevent	0
+#
+# Tests / Wait
+#
+# opcode	opcode argument
+#
+# prioeq	priority
+# priolt	priority
+# priogt	priority
+# nprioeq	normal priority
+# npriolt	normal priority
+# npriogt	normal priority
+# locked	lock nr (0-7)
+# blocked	lock nr (0-7)
+# blockedwake	lock nr (0-7)
+# unlocked	lock nr (0-7)
+# lockedbkl	dont care
+# blockedbkl	dont care
+# unlockedbkl	dont care
+# opcodeeq	command opcode or number
+# opcodelt	number
+# opcodegt	number
+# eventeq	number
+# eventgt	number
+# eventlt	number
+
+#
+# 2 threads 1 lock with priority inversion
+#
+C: resetevent:		0: 	0
+W: opcodeeq:		0: 	0
+
+# Set schedulers
+C: schedother:		0: 	0
+C: schedfifo:		1: 	80
+
+# T0 lock L0
+C: locknowait:		0: 	0
+W: locked:		0: 	0
+
+# T1 lock L0
+C: locknowait:		1: 	0
+W: blocked:		1: 	0
+T: prioeq:		0: 	80
+
+# T0 unlock L0
+C: unlock:		0: 	0
+W: locked:		1: 	0
+
+# Verify T1
+W: unlocked:		0: 	0
+T: priolt:		0: 	1
+
+# Unlock and exit
+C: unlock:		1: 	0
+W: unlocked:		1: 	0
+
diff --git a/scripts/rt-tester/t2-l1-signal.tst b/scripts/rt-tester/t2-l1-signal.tst
new file mode 100644
index 000000000..3ab0bfc49
--- /dev/null
+++ b/scripts/rt-tester/t2-l1-signal.tst
@@ -0,0 +1,77 @@
+#
+# RT-Mutex test
+#
+# Op: C(ommand)/T(est)/W(ait)
+# |  opcode
+# |  |     threadid: 0-7
+# |  |     |  opcode argument
+# |  |     |  |
+# C: lock: 0: 0
+#
+# Commands
+#
+# opcode	opcode argument
+# schedother	nice value
+# schedfifo	priority
+# lock		lock nr (0-7)
+# locknowait	lock nr (0-7)
+# lockint	lock nr (0-7)
+# lockintnowait	lock nr (0-7)
+# lockcont	lock nr (0-7)
+# unlock	lock nr (0-7)
+# lockbkl	lock nr (0-7)
+# unlockbkl	lock nr (0-7)
+# signal	0
+# reset		0
+# resetevent	0
+#
+# Tests / Wait
+#
+# opcode	opcode argument
+#
+# prioeq	priority
+# priolt	priority
+# priogt	priority
+# nprioeq	normal priority
+# npriolt	normal priority
+# npriogt	normal priority
+# locked	lock nr (0-7)
+# blocked	lock nr (0-7)
+# blockedwake	lock nr (0-7)
+# unlocked	lock nr (0-7)
+# lockedbkl	dont care
+# blockedbkl	dont care
+# unlockedbkl	dont care
+# opcodeeq	command opcode or number
+# opcodelt	number
+# opcodegt	number
+# eventeq	number
+# eventgt	number
+# eventlt	number
+
+#
+# 2 threads 1 lock with priority inversion
+#
+C: resetevent:		0: 	0
+W: opcodeeq:		0: 	0
+
+# Set schedulers
+C: schedother:		0: 	0
+C: schedother:		1: 	0
+
+# T0 lock L0
+C: locknowait:		0: 	0
+W: locked:		0: 	0
+
+# T1 lock L0
+C: lockintnowait:	1: 	0
+W: blocked:		1: 	0
+
+# Interrupt T1
+C: signal:		1:	0
+W: unlocked:		1: 	0
+T: opcodeeq:		1:	-4
+
+# Unlock and exit
+C: unlock:		0: 	0
+W: unlocked:		0: 	0
diff --git a/scripts/rt-tester/t2-l2-2rt-deadlock.tst b/scripts/rt-tester/t2-l2-2rt-deadlock.tst
new file mode 100644
index 000000000..f4b5d5d62
--- /dev/null
+++ b/scripts/rt-tester/t2-l2-2rt-deadlock.tst
@@ -0,0 +1,89 @@
+#
+# RT-Mutex test
+#
+# Op: C(ommand)/T(est)/W(ait)
+# |  opcode
+# |  |     threadid: 0-7
+# |  |     |  opcode argument
+# |  |     |  |
+# C: lock: 0: 0
+#
+# Commands
+#
+# opcode	opcode argument
+# schedother	nice value
+# schedfifo	priority
+# lock		lock nr (0-7)
+# locknowait	lock nr (0-7)
+# lockint	lock nr (0-7)
+# lockintnowait	lock nr (0-7)
+# lockcont	lock nr (0-7)
+# unlock	lock nr (0-7)
+# lockbkl	lock nr (0-7)
+# unlockbkl	lock nr (0-7)
+# signal	0
+# reset		0
+# resetevent	0
+#
+# Tests / Wait
+#
+# opcode	opcode argument
+#
+# prioeq	priority
+# priolt	priority
+# priogt	priority
+# nprioeq	normal priority
+# npriolt	normal priority
+# npriogt	normal priority
+# locked	lock nr (0-7)
+# blocked	lock nr (0-7)
+# blockedwake	lock nr (0-7)
+# unlocked	lock nr (0-7)
+# lockedbkl	dont care
+# blockedbkl	dont care
+# unlockedbkl	dont care
+# opcodeeq	command opcode or number
+# opcodelt	number
+# opcodegt	number
+# eventeq	number
+# eventgt	number
+# eventlt	number
+
+#
+# 2 threads 2 lock
+#
+C: resetevent:		0: 	0
+W: opcodeeq:		0: 	0
+
+# Set schedulers
+C: schedfifo:		0: 	80
+C: schedfifo:		1: 	80
+
+# T0 lock L0
+C: locknowait:		0: 	0
+W: locked:		0: 	0
+
+# T1 lock L1
+C: locknowait:		1:	1
+W: locked:		1: 	1
+
+# T0 lock L1
+C: lockintnowait:	0: 	1
+W: blocked:		0: 	1
+
+# T1 lock L0
+C: lockintnowait:	1: 	0
+W: blocked:		1: 	0
+
+# Make deadlock go away
+C: signal:		1:	0
+W: unlocked:		1:	0
+C: signal:		0:	0
+W: unlocked:		0:	1
+
+# Unlock and exit
+C: unlock:		0: 	0
+W: unlocked:		0: 	0
+C: unlock:		1: 	1
+W: unlocked:		1: 	1
+
diff --git a/scripts/rt-tester/t3-l1-pi-1rt.tst b/scripts/rt-tester/t3-l1-pi-1rt.tst
new file mode 100644
index 000000000..63440ca2c
--- /dev/null
+++ b/scripts/rt-tester/t3-l1-pi-1rt.tst
@@ -0,0 +1,92 @@
+#
+# rt-mutex test
+#
+# Op: C(ommand)/T(est)/W(ait)
+# |  opcode
+# |  |     threadid: 0-7
+# |  |     |  opcode argument
+# |  |     |  |
+# C: lock: 0: 0
+#
+# Commands
+#
+# opcode	opcode argument
+# schedother	nice value
+# schedfifo	priority
+# lock		lock nr (0-7)
+# locknowait	lock nr (0-7)
+# lockint	lock nr (0-7)
+# lockintnowait	lock nr (0-7)
+# lockcont	lock nr (0-7)
+# unlock	lock nr (0-7)
+# lockbkl	lock nr (0-7)
+# unlockbkl	lock nr (0-7)
+# signal	thread to signal (0-7)
+# reset		0
+# resetevent	0
+#
+# Tests / Wait
+#
+# opcode	opcode argument
+#
+# prioeq	priority
+# priolt	priority
+# priogt	priority
+# nprioeq	normal priority
+# npriolt	normal priority
+# npriogt	normal priority
+# locked	lock nr (0-7)
+# blocked	lock nr (0-7)
+# blockedwake	lock nr (0-7)
+# unlocked	lock nr (0-7)
+# lockedbkl	dont care
+# blockedbkl	dont care
+# unlockedbkl	dont care
+# opcodeeq	command opcode or number
+# opcodelt	number
+# opcodegt	number
+# eventeq	number
+# eventgt	number
+# eventlt	number
+
+#
+# 3 threads 1 lock PI
+#
+C: resetevent:		0: 	0
+W: opcodeeq:		0: 	0
+
+# Set schedulers
+C: schedother:		0: 	0
+C: schedother:		1: 	0
+C: schedfifo:		2: 	82
+
+# T0 lock L0
+C: locknowait:		0: 	0
+W: locked:		0: 	0
+
+# T1 lock L0
+C: locknowait:		1: 	0
+W: blocked:		1: 	0
+T: priolt:		0: 	1
+
+# T2 lock L0
+C: locknowait:		2: 	0
+W: blocked:		2: 	0
+T: prioeq:		0: 	82
+
+# T0 unlock L0
+C: unlock:		0: 	0
+
+# Wait until T2 got the lock
+W: locked:		2: 	0
+W: unlocked:		0:	0
+T: priolt:		0:	1
+
+# T2 unlock L0
+C: unlock:		2: 	0
+
+W: unlocked:		2: 	0
+W: locked:		1: 	0
+
+C: unlock:		1: 	0
+W: unlocked:		1: 	0
diff --git a/scripts/rt-tester/t3-l1-pi-2rt.tst b/scripts/rt-tester/t3-l1-pi-2rt.tst
new file mode 100644
index 000000000..e5816fe67
--- /dev/null
+++ b/scripts/rt-tester/t3-l1-pi-2rt.tst
@@ -0,0 +1,93 @@
+#
+# rt-mutex test
+#
+# Op: C(ommand)/T(est)/W(ait)
+# |  opcode
+# |  |     threadid: 0-7
+# |  |     |  opcode argument
+# |  |     |  |
+# C: lock: 0: 0
+#
+# Commands
+#
+# opcode	opcode argument
+# schedother	nice value
+# schedfifo	priority
+# lock		lock nr (0-7)
+# locknowait	lock nr (0-7)
+# lockint	lock nr (0-7)
+# lockintnowait	lock nr (0-7)
+# lockcont	lock nr (0-7)
+# unlock	lock nr (0-7)
+# lockbkl	lock nr (0-7)
+# unlockbkl	lock nr (0-7)
+# signal	thread to signal (0-7)
+# reset		0
+# resetevent	0
+#
+# Tests / Wait
+#
+# opcode	opcode argument
+#
+# prioeq	priority
+# priolt	priority
+# priogt	priority
+# nprioeq	normal priority
+# npriolt	normal priority
+# npriogt	normal priority
+# locked	lock nr (0-7)
+# blocked	lock nr (0-7)
+# blockedwake	lock nr (0-7)
+# unlocked	lock nr (0-7)
+# lockedbkl	dont care
+# blockedbkl	dont care
+# unlockedbkl	dont care
+# opcodeeq	command opcode or number
+# opcodelt	number
+# opcodegt	number
+# eventeq	number
+# eventgt	number
+# eventlt	number
+
+#
+# 3 threads 1 lock PI
+#
+C: resetevent:		0: 	0
+W: opcodeeq:		0: 	0
+
+# Set schedulers
+C: schedother:		0: 	0
+C: schedfifo:		1: 	81
+C: schedfifo:		2: 	82
+
+# T0 lock L0
+C: locknowait:		0: 	0
+W: locked:		0: 	0
+
+# T1 lock L0
+C: locknowait:		1: 	0
+W: blocked:		1: 	0
+T: prioeq:		0: 	81
+
+# T2 lock L0
+C: locknowait:		2: 	0
+W: blocked:		2: 	0
+T: prioeq:		0: 	82
+T: prioeq:		1:	81
+
+# T0 unlock L0
+C: unlock:		0: 	0
+
+# Wait until T2 got the lock
+W: locked:		2: 	0
+W: unlocked:		0:	0
+T: priolt:		0:	1
+
+# T2 unlock L0
+C: unlock:		2: 	0
+
+W: unlocked:		2: 	0
+W: locked:		1: 	0
+
+C: unlock:		1: 	0
+W: unlocked:		1: 	0
diff --git a/scripts/rt-tester/t3-l1-pi-3rt.tst b/scripts/rt-tester/t3-l1-pi-3rt.tst
new file mode 100644
index 000000000..718b82b5d
--- /dev/null
+++ b/scripts/rt-tester/t3-l1-pi-3rt.tst
@@ -0,0 +1,92 @@
+#
+# rt-mutex test
+#
+# Op: C(ommand)/T(est)/W(ait)
+# |  opcode
+# |  |     threadid: 0-7
+# |  |     |  opcode argument
+# |  |     |  |
+# C: lock: 0: 0
+#
+# Commands
+#
+# opcode	opcode argument
+# schedother	nice value
+# schedfifo	priority
+# lock		lock nr (0-7)
+# locknowait	lock nr (0-7)
+# lockint	lock nr (0-7)
+# lockintnowait	lock nr (0-7)
+# lockcont	lock nr (0-7)
+# unlock	lock nr (0-7)
+# lockbkl	lock nr (0-7)
+# unlockbkl	lock nr (0-7)
+# signal	thread to signal (0-7)
+# reset		0
+# resetevent	0
+#
+# Tests / Wait
+#
+# opcode	opcode argument
+#
+# prioeq	priority
+# priolt	priority
+# priogt	priority
+# nprioeq	normal priority
+# npriolt	normal priority
+# npriogt	normal priority
+# locked	lock nr (0-7)
+# blocked	lock nr (0-7)
+# blockedwake	lock nr (0-7)
+# unlocked	lock nr (0-7)
+# lockedbkl	dont care
+# blockedbkl	dont care
+# unlockedbkl	dont care
+# opcodeeq	command opcode or number
+# opcodelt	number
+# opcodegt	number
+# eventeq	number
+# eventgt	number
+# eventlt	number
+
+#
+# 3 threads 1 lock PI
+#
+C: resetevent:		0: 	0
+W: opcodeeq:		0: 	0
+
+# Set schedulers
+C: schedfifo:		0: 	80
+C: schedfifo:		1: 	81
+C: schedfifo:		2: 	82
+
+# T0 lock L0
+C: locknowait:		0: 	0
+W: locked:		0: 	0
+
+# T1 lock L0
+C: locknowait:		1: 	0
+W: blocked:		1: 	0
+T: prioeq:		0: 	81
+
+# T2 lock L0
+C: locknowait:		2: 	0
+W: blocked:		2: 	0
+T: prioeq:		0: 	82
+
+# T0 unlock L0
+C: unlock:		0: 	0
+
+# Wait until T2 got the lock
+W: locked:		2: 	0
+W: unlocked:		0:	0
+T: prioeq:		0:	80
+
+# T2 unlock L0
+C: unlock:		2: 	0
+
+W: locked:		1: 	0
+W: unlocked:		2: 	0
+
+C: unlock:		1: 	0
+W: unlocked:		1: 	0
diff --git a/scripts/rt-tester/t3-l1-pi-signal.tst b/scripts/rt-tester/t3-l1-pi-signal.tst
new file mode 100644
index 000000000..c6e213563
--- /dev/null
+++ b/scripts/rt-tester/t3-l1-pi-signal.tst
@@ -0,0 +1,98 @@
+#
+# rt-mutex test
+#
+# Op: C(ommand)/T(est)/W(ait)
+# |  opcode
+# |  |     threadid: 0-7
+# |  |     |  opcode argument
+# |  |     |  |
+# C: lock: 0: 0
+#
+# Commands
+#
+# opcode	opcode argument
+# schedother	nice value
+# schedfifo	priority
+# lock		lock nr (0-7)
+# locknowait	lock nr (0-7)
+# lockint	lock nr (0-7)
+# lockintnowait	lock nr (0-7)
+# lockcont	lock nr (0-7)
+# unlock	lock nr (0-7)
+# lockbkl	lock nr (0-7)
+# unlockbkl	lock nr (0-7)
+# signal	thread to signal (0-7)
+# reset		0
+# resetevent	0
+#
+# Tests / Wait
+#
+# opcode	opcode argument
+#
+# prioeq	priority
+# priolt	priority
+# priogt	priority
+# nprioeq	normal priority
+# npriolt	normal priority
+# npriogt	normal priority
+# locked	lock nr (0-7)
+# blocked	lock nr (0-7)
+# blockedwake	lock nr (0-7)
+# unlocked	lock nr (0-7)
+# lockedbkl	dont care
+# blockedbkl	dont care
+# unlockedbkl	dont care
+# opcodeeq	command opcode or number
+# opcodelt	number
+# opcodegt	number
+# eventeq	number
+# eventgt	number
+# eventlt	number
+
+# Reset event counter
+C: resetevent:		0: 	0
+W: opcodeeq:		0: 	0
+
+# Set priorities
+C: schedother:		0: 	0
+C: schedfifo:		1: 	80
+C: schedfifo:		2: 	81
+
+# T0 lock L0
+C: lock:		0:	0
+W: locked:		0: 	0
+
+# T1 lock L0, no wait in the wakeup path
+C: locknowait:		1: 	0
+W: blocked:		1: 	0
+T: prioeq:		0:	80
+T: prioeq:		1:	80
+
+# T2 lock L0 interruptible, no wait in the wakeup path
+C: lockintnowait:	2:	0
+W: blocked:		2: 	0
+T: prioeq:		0:	81
+T: prioeq:		1:	80
+
+# Interrupt T2
+C: signal:		2:	2
+W: unlocked:		2:	0
+T: prioeq:		1:	80
+T: prioeq:		0:	80
+
+T: locked:		0:	0
+T: blocked:		1:	0
+
+# T0 unlock L0
+C: unlock:		0: 	0
+
+# Wait until T1 has locked L0 and exit
+W: locked:		1:	0
+W: unlocked:		0: 	0
+T: priolt:		0:	1
+
+C: unlock:		1: 	0
+W: unlocked:		1: 	0
+
+
+
diff --git a/scripts/rt-tester/t3-l1-pi-steal.tst b/scripts/rt-tester/t3-l1-pi-steal.tst
new file mode 100644
index 000000000..f53749d59
--- /dev/null
+++ b/scripts/rt-tester/t3-l1-pi-steal.tst
@@ -0,0 +1,96 @@
+#
+# rt-mutex test
+#
+# Op: C(ommand)/T(est)/W(ait)
+# |  opcode
+# |  |     threadid: 0-7
+# |  |     |  opcode argument
+# |  |     |  |
+# C: lock: 0: 0
+#
+# Commands
+#
+# opcode	opcode argument
+# schedother	nice value
+# schedfifo	priority
+# lock		lock nr (0-7)
+# locknowait	lock nr (0-7)
+# lockint	lock nr (0-7)
+# lockintnowait	lock nr (0-7)
+# lockcont	lock nr (0-7)
+# unlock	lock nr (0-7)
+# lockbkl	lock nr (0-7)
+# unlockbkl	lock nr (0-7)
+# signal	thread to signal (0-7)
+# reset		0
+# resetevent	0
+#
+# Tests / Wait
+#
+# opcode	opcode argument
+#
+# prioeq	priority
+# priolt	priority
+# priogt	priority
+# nprioeq	normal priority
+# npriolt	normal priority
+# npriogt	normal priority
+# locked	lock nr (0-7)
+# blocked	lock nr (0-7)
+# blockedwake	lock nr (0-7)
+# unlocked	lock nr (0-7)
+# lockedbkl	dont care
+# blockedbkl	dont care
+# unlockedbkl	dont care
+# opcodeeq	command opcode or number
+# opcodelt	number
+# opcodegt	number
+# eventeq	number
+# eventgt	number
+# eventlt	number
+
+#
+# 3 threads 1 lock PI steal pending ownership
+#
+C: resetevent:		0: 	0
+W: opcodeeq:		0: 	0
+
+# Set schedulers
+C: schedother:		0: 	0
+C: schedfifo:		1: 	80
+C: schedfifo:		2: 	81
+
+# T0 lock L0
+C: lock:		0: 	0
+W: locked:		0: 	0
+
+# T1 lock L0
+C: lock:		1: 	0
+W: blocked:		1: 	0
+T: prioeq:		0: 	80
+
+# T0 unlock L0
+C: unlock:		0: 	0
+
+# Wait until T1 is in the wakeup loop
+W: blockedwake:		1: 	0
+T: priolt:		0: 	1
+
+# T2 lock L0
+C: lock:		2: 	0
+# T1 leave wakeup loop
+C: lockcont:		1: 	0
+
+# T2 must have the lock and T1 must be blocked
+W: locked:		2: 	0
+W: blocked:		1: 	0
+
+# T2 unlock L0
+C: unlock:		2: 	0
+
+# Wait until T1 is in the wakeup loop and let it run
+W: blockedwake:		1: 	0
+C: lockcont:		1: 	0
+W: locked:		1: 	0
+C: unlock:		1: 	0
+W: unlocked:		1: 	0
diff --git a/scripts/rt-tester/t3-l2-pi.tst b/scripts/rt-tester/t3-l2-pi.tst
new file mode 100644
index 000000000..cdc3e4fd7
--- /dev/null
+++ b/scripts/rt-tester/t3-l2-pi.tst
@@ -0,0 +1,92 @@
+#
+# rt-mutex test
+#
+# Op: C(ommand)/T(est)/W(ait)
+# |  opcode
+# |  |     threadid: 0-7
+# |  |     |  opcode argument
+# |  |     |  |
+# C: lock: 0: 0
+#
+# Commands
+#
+# opcode	opcode argument
+# schedother	nice value
+# schedfifo	priority
+# lock		lock nr (0-7)
+# locknowait	lock nr (0-7)
+# lockint	lock nr (0-7)
+# lockintnowait	lock nr (0-7)
+# lockcont	lock nr (0-7)
+# unlock	lock nr (0-7)
+# lockbkl	lock nr (0-7)
+# unlockbkl	lock nr (0-7)
+# signal	thread to signal (0-7)
+# reset		0
+# resetevent	0
+#
+# Tests / Wait
+#
+# opcode	opcode argument
+#
+# prioeq	priority
+# priolt	priority
+# priogt	priority
+# nprioeq	normal priority
+# npriolt	normal priority
+# npriogt	normal priority
+# locked	lock nr (0-7)
+# blocked	lock nr (0-7)
+# blockedwake	lock nr (0-7)
+# unlocked	lock nr (0-7)
+# lockedbkl	dont care
+# blockedbkl	dont care
+# unlockedbkl	dont care
+# opcodeeq	command opcode or number
+# opcodelt	number
+# opcodegt	number
+# eventeq	number
+# eventgt	number
+# eventlt	number
+
+#
+# 3 threads 2 lock PI
+#
+C: resetevent:		0: 	0
+W: opcodeeq:		0: 	0
+
+# Set schedulers
+C: schedother:		0: 	0
+C: schedother:		1: 	0
+C: schedfifo:		2: 	82
+
+# T0 lock L0
+C: locknowait:		0: 	0
+W: locked:		0: 	0
+
+# T1 lock L0
+C: locknowait:		1: 	0
+W: blocked:		1: 	0
+T: priolt:		0: 	1
+
+# T2 lock L0
+C: locknowait:		2: 	0
+W: blocked:		2: 	0
+T: prioeq:		0: 	82
+
+# T0 unlock L0
+C: unlock:		0: 	0
+
+# Wait until T2 got the lock
+W: locked:		2: 	0
+W: unlocked:		0:	0
+T: priolt:		0:	1
+
+# T2 unlock L0
+C: unlock:		2: 	0
+
+W: unlocked:		2: 	0
+W: locked:		1: 	0
+
+C: unlock:		1: 	0
+W: unlocked:		1: 	0
diff --git a/scripts/rt-tester/t4-l2-pi-deboost.tst b/scripts/rt-tester/t4-l2-pi-deboost.tst
new file mode 100644
index 000000000..baa14137f
--- /dev/null
+++ b/scripts/rt-tester/t4-l2-pi-deboost.tst
@@ -0,0 +1,123 @@
+#
+# rt-mutex test
+#
+# Op: C(ommand)/T(est)/W(ait)
+# |  opcode
+# |  |     threadid: 0-7
+# |  |     |  opcode argument
+# |  |     |  |
+# C: lock: 0: 0
+#
+# Commands
+#
+# opcode	opcode argument
+# schedother	nice value
+# schedfifo	priority
+# lock		lock nr (0-7)
+# locknowait	lock nr (0-7)
+# lockint	lock nr (0-7)
+# lockintnowait	lock nr (0-7)
+# lockcont	lock nr (0-7)
+# unlock	lock nr (0-7)
+# lockbkl	lock nr (0-7)
+# unlockbkl	lock nr (0-7)
+# signal	thread to signal (0-7)
+# reset		0
+# resetevent	0
+#
+# Tests / Wait
+#
+# opcode	opcode argument
+#
+# prioeq	priority
+# priolt	priority
+# priogt	priority
+# nprioeq	normal priority
+# npriolt	normal priority
+# npriogt	normal priority
+# locked	lock nr (0-7)
+# blocked	lock nr (0-7)
+# blockedwake	lock nr (0-7)
+# unlocked	lock nr (0-7)
+# lockedbkl	dont care
+# blockedbkl	dont care
+# unlockedbkl	dont care
+# opcodeeq	command opcode or number
+# opcodelt	number
+# opcodegt	number
+# eventeq	number
+# eventgt	number
+# eventlt	number
+
+#
+# 4 threads 2 lock PI
+#
+C: resetevent:		0: 	0
+W: opcodeeq:		0: 	0
+
+# Set schedulers
+C: schedother:		0: 	0
+C: schedother:		1: 	0
+C: schedfifo:		2: 	82
+C: schedfifo:		3: 	83
+
+# T0 lock L0
+C: locknowait:		0: 	0
+W: locked:		0: 	0
+
+# T1 lock L1
+C: locknowait:		1: 	1
+W: locked:		1: 	1
+
+# T3 lock L0
+C: lockintnowait:	3: 	0
+W: blocked:		3: 	0
+T: prioeq:		0: 	83
+
+# T0 lock L1
+C: lock:		0: 	1
+W: blocked:		0: 	1
+T: prioeq:		1: 	83
+
+# T1 unlock L1
+C: unlock:		1:	1
+
+# Wait until T0 is in the wakeup code
+W: blockedwake:		0:	1
+
+# Verify that T1 is unboosted
+W: unlocked:		1: 	1
+T: priolt:		1: 	1
+
+# T2 lock L1 (T0 is boosted and pending owner !)
+C: locknowait:		2:	1
+W: blocked:		2: 	1
+T: prioeq:		0: 	83
+
+# Interrupt T3 and wait until T3 returned
+C: signal:		3:	0
+W: unlocked:		3:	0
+
+# Verify prio of T0 (still pending owner,
+# but T2 is enqueued due to the previous boost by T3
+T: prioeq:		0:	82
+
+# Let T0 continue
+C: lockcont:		0:	1
+W: locked:		0:	1
+
+# Unlock L1 and let T2 get L1
+C: unlock:		0:	1
+W: locked:		2:	1
+
+# Verify that T0 is unboosted
+W: unlocked:		0:	1
+T: priolt:		0:	1
+
+# Unlock everything and exit
+C: unlock:		2:	1
+W: unlocked:		2:	1
+
+C: unlock:		0:	0
+W: unlocked:		0:	0
+
diff --git a/scripts/rt-tester/t5-l4-pi-boost-deboost-setsched.tst b/scripts/rt-tester/t5-l4-pi-boost-deboost-setsched.tst
new file mode 100644
index 000000000..e6ec0c81b
--- /dev/null
+++ b/scripts/rt-tester/t5-l4-pi-boost-deboost-setsched.tst
@@ -0,0 +1,183 @@
+#
+# rt-mutex test
+#
+# Op: C(ommand)/T(est)/W(ait)
+# |  opcode
+# |  |     threadid: 0-7
+# |  |     |  opcode argument
+# |  |     |  |
+# C: lock: 0: 0
+#
+# Commands
+#
+# opcode	opcode argument
+# schedother	nice value
+# schedfifo	priority
+# lock		lock nr (0-7)
+# locknowait	lock nr (0-7)
+# lockint	lock nr (0-7)
+# lockintnowait	lock nr (0-7)
+# lockcont	lock nr (0-7)
+# unlock	lock nr (0-7)
+# lockbkl	lock nr (0-7)
+# unlockbkl	lock nr (0-7)
+# signal	thread to signal (0-7)
+# reset		0
+# resetevent	0
+#
+# Tests / Wait
+#
+# opcode	opcode argument
+#
+# prioeq	priority
+# priolt	priority
+# priogt	priority
+# nprioeq	normal priority
+# npriolt	normal priority
+# npriogt	normal priority
+# locked	lock nr (0-7)
+# blocked	lock nr (0-7)
+# blockedwake	lock nr (0-7)
+# unlocked	lock nr (0-7)
+# lockedbkl	dont care
+# blockedbkl	dont care
+# unlockedbkl	dont care
+# opcodeeq	command opcode or number
+# opcodelt	number
+# opcodegt	number
+# eventeq	number
+# eventgt	number
+# eventlt	number
+
+#
+# 5 threads 4 lock PI - modify priority of blocked threads
+#
+C: resetevent:		0: 	0
+W: opcodeeq:		0: 	0
+
+# Set schedulers
+C: schedother:		0: 	0
+C: schedfifo:		1: 	81
+C: schedfifo:		2: 	82
+C: schedfifo:		3: 	83
+C: schedfifo:		4: 	84
+
+# T0 lock L0
+C: locknowait:		0: 	0
+W: locked:		0: 	0
+
+# T1 lock L1
+C: locknowait:		1: 	1
+W: locked:		1: 	1
+
+# T1 lock L0
+C: lockintnowait:	1: 	0
+W: blocked:		1: 	0
+T: prioeq:		0: 	81
+
+# T2 lock L2
+C: locknowait:		2: 	2
+W: locked:		2: 	2
+
+# T2 lock L1
+C: lockintnowait:	2: 	1
+W: blocked:		2: 	1
+T: prioeq:		0: 	82
+T: prioeq:		1:	82
+
+# T3 lock L3
+C: locknowait:		3: 	3
+W: locked:		3: 	3
+
+# T3 lock L2
+C: lockintnowait:	3: 	2
+W: blocked:		3: 	2
+T: prioeq:		0: 	83
+T: prioeq:		1:	83
+T: prioeq:		2:	83
+
+# T4 lock L3
+C: lockintnowait:	4:	3
+W: blocked:		4: 	3
+T: prioeq:		0: 	84
+T: prioeq:		1:	84
+T: prioeq:		2:	84
+T: prioeq:		3:	84
+
+# Reduce prio of T4
+C: schedfifo:		4: 	80
+T: prioeq:		0: 	83
+T: prioeq:		1:	83
+T: prioeq:		2:	83
+T: prioeq:		3:	83
+T: prioeq:		4:	80
+
+# Increase prio of T4
+C: schedfifo:		4: 	84
+T: prioeq:		0: 	84
+T: prioeq:		1:	84
+T: prioeq:		2:	84
+T: prioeq:		3:	84
+T: prioeq:		4:	84
+
+# Reduce prio of T3
+C: schedfifo:		3: 	80
+T: prioeq:		0: 	84
+T: prioeq:		1:	84
+T: prioeq:		2:	84
+T: prioeq:		3:	84
+T: prioeq:		4:	84
+
+# Increase prio of T3
+C: schedfifo:		3: 	85
+T: prioeq:		0: 	85
+T: prioeq:		1:	85
+T: prioeq:		2:	85
+T: prioeq:		3:	85
+T: prioeq:		4:	84
+
+# Reduce prio of T3
+C: schedfifo:		3: 	83
+T: prioeq:		0: 	84
+T: prioeq:		1:	84
+T: prioeq:		2:	84
+T: prioeq:		3:	84
+T: prioeq:		4:	84
+
+# Signal T4
+C: signal:		4: 	0
+W: unlocked:		4: 	3
+T: prioeq:		0: 	83
+T: prioeq:		1:	83
+T: prioeq:		2:	83
+T: prioeq:		3:	83
+
+# Signal T3
+C: signal:		3: 	0
+W: unlocked:		3: 	2
+T: prioeq:		0: 	82
+T: prioeq:		1:	82
+T: prioeq:		2:	82
+
+# Signal T2
+C: signal:		2: 	0
+W: unlocked:		2: 	1
+T: prioeq:		0: 	81
+T: prioeq:		1:	81
+
+# Signal T1
+C: signal:		1: 	0
+W: unlocked:		1: 	0
+T: priolt:		0: 	1
+
+# Unlock and exit
+C: unlock:		3:	3
+C: unlock:		2:	2
+C: unlock:		1:	1
+C: unlock:		0:	0
+
+W: unlocked:		3:	3
+W: unlocked:		2:	2
+W: unlocked:		1:	1
+W: unlocked:		0:	0
+
diff --git a/scripts/rt-tester/t5-l4-pi-boost-deboost.tst b/scripts/rt-tester/t5-l4-pi-boost-deboost.tst
new file mode 100644
index 000000000..ca64f8bbf
--- /dev/null
+++ b/scripts/rt-tester/t5-l4-pi-boost-deboost.tst
@@ -0,0 +1,143 @@
+#
+# rt-mutex test
+#
+# Op: C(ommand)/T(est)/W(ait)
+# |  opcode
+# |  |     threadid: 0-7
+# |  |     |  opcode argument
+# |  |     |  |
+# C: lock: 0: 0
+#
+# Commands
+#
+# opcode	opcode argument
+# schedother	nice value
+# schedfifo	priority
+# lock		lock nr (0-7)
+# locknowait	lock nr (0-7)
+# lockint	lock nr (0-7)
+# lockintnowait	lock nr (0-7)
+# lockcont	lock nr (0-7)
+# unlock	lock nr (0-7)
+# lockbkl	lock nr (0-7)
+# unlockbkl	lock nr (0-7)
+# signal	thread to signal (0-7)
+# reset		0
+# resetevent	0
+#
+# Tests / Wait
+#
+# opcode	opcode argument
+#
+# prioeq	priority
+# priolt	priority
+# priogt	priority
+# nprioeq	normal priority
+# npriolt	normal priority
+# npriogt	normal priority
+# locked	lock nr (0-7)
+# blocked	lock nr (0-7)
+# blockedwake	lock nr (0-7)
+# unlocked	lock nr (0-7)
+# lockedbkl	dont care
+# blockedbkl	dont care
+# unlockedbkl	dont care
+# opcodeeq	command opcode or number
+# opcodelt	number
+# opcodegt	number
+# eventeq	number
+# eventgt	number
+# eventlt	number
+
+#
+# 5 threads 4 lock PI
+#
+C: resetevent:		0: 	0
+W: opcodeeq:		0: 	0
+
+# Set schedulers
+C: schedother:		0: 	0
+C: schedfifo:		1: 	81
+C: schedfifo:		2: 	82
+C: schedfifo:		3: 	83
+C: schedfifo:		4: 	84
+
+# T0 lock L0
+C: locknowait:		0: 	0
+W: locked:		0: 	0
+
+# T1 lock L1
+C: locknowait:		1: 	1
+W: locked:		1: 	1
+
+# T1 lock L0
+C: lockintnowait:	1: 	0
+W: blocked:		1: 	0
+T: prioeq:		0: 	81
+
+# T2 lock L2
+C: locknowait:		2: 	2
+W: locked:		2: 	2
+
+# T2 lock L1
+C: lockintnowait:	2: 	1
+W: blocked:		2: 	1
+T: prioeq:		0: 	82
+T: prioeq:		1:	82
+
+# T3 lock L3
+C: locknowait:		3: 	3
+W: locked:		3: 	3
+
+# T3 lock L2
+C: lockintnowait:	3: 	2
+W: blocked:		3: 	2
+T: prioeq:		0: 	83
+T: prioeq:		1:	83
+T: prioeq:		2:	83
+
+# T4 lock L3
+C: lockintnowait:	4:	3
+W: blocked:		4: 	3
+T: prioeq:		0: 	84
+T: prioeq:		1:	84
+T: prioeq:		2:	84
+T: prioeq:		3:	84
+
+# Signal T4
+C: signal:		4: 	0
+W: unlocked:		4: 	3
+T: prioeq:		0: 	83
+T: prioeq:		1:	83
+T: prioeq:		2:	83
+T: prioeq:		3:	83
+
+# Signal T3
+C: signal:		3: 	0
+W: unlocked:		3: 	2
+T: prioeq:		0: 	82
+T: prioeq:		1:	82
+T: prioeq:		2:	82
+
+# Signal T2
+C: signal:		2: 	0
+W: unlocked:		2: 	1
+T: prioeq:		0: 	81
+T: prioeq:		1:	81
+
+# Signal T1
+C: signal:		1: 	0
+W: unlocked:		1: 	0
+T: priolt:		0: 	1
+
+# Unlock and exit
+C: unlock:		3:	3
+C: unlock:		2:	2
+C: unlock:		1:	1
+C: unlock:		0:	0
+
+W: unlocked:		3:	3
+W: unlocked:		2:	2
+W: unlocked:		1:	1
+W: unlocked:		0:	0
+
diff --git a/sound/aoa/Kconfig b/sound/aoa/Kconfig
new file mode 100644
index 000000000..2f4334d19
--- /dev/null
+++ b/sound/aoa/Kconfig
@@ -0,0 +1,18 @@
+menu "Apple Onboard Audio driver"
+	depends on SND!=n && PPC
+
+config SND_AOA
+	tristate "Apple Onboard Audio driver"
+	depends on SND
+	select SND_PCM
+	---help---
+	This option enables the new driver for the various
+	Apple Onboard Audio components.
+
+source "sound/aoa/fabrics/Kconfig"
+
+source "sound/aoa/codecs/Kconfig"
+
+source "sound/aoa/soundbus/Kconfig"
+
+endmenu
diff --git a/sound/aoa/Makefile b/sound/aoa/Makefile
new file mode 100644
index 000000000..a8c037f90
--- /dev/null
+++ b/sound/aoa/Makefile
@@ -0,0 +1,4 @@
+obj-$(CONFIG_SND_AOA) += core/
+obj-$(CONFIG_SND_AOA_SOUNDBUS) += soundbus/
+obj-$(CONFIG_SND_AOA) += fabrics/
+obj-$(CONFIG_SND_AOA) += codecs/
diff --git a/sound/aoa/aoa-gpio.h b/sound/aoa/aoa-gpio.h
new file mode 100644
index 000000000..3a61f3115
--- /dev/null
+++ b/sound/aoa/aoa-gpio.h
@@ -0,0 +1,81 @@
+/*
+ * Apple Onboard Audio GPIO definitions
+ *
+ * Copyright 2006 Johannes Berg <johannes@sipsolutions.net>
+ *
+ * GPL v2, can be found in COPYING.
+ */
+
+#ifndef __AOA_GPIO_H
+#define __AOA_GPIO_H
+#include <linux/workqueue.h>
+#include <linux/mutex.h>
+#include <asm/prom.h>
+
+typedef void (*notify_func_t)(void *data);
+
+enum notify_type {
+	AOA_NOTIFY_HEADPHONE,
+	AOA_NOTIFY_LINE_IN,
+	AOA_NOTIFY_LINE_OUT,
+};
+
+struct gpio_runtime;
+struct gpio_methods {
+	/* for initialisation/de-initialisation of the GPIO layer */
+	void (*init)(struct gpio_runtime *rt);
+	void (*exit)(struct gpio_runtime *rt);
+
+	/* turn off headphone, speakers, lineout */
+	void (*all_amps_off)(struct gpio_runtime *rt);
+	/* turn headphone, speakers, lineout back to previous setting */
+	void (*all_amps_restore)(struct gpio_runtime *rt);
+
+	void (*set_headphone)(struct gpio_runtime *rt, int on);
+	void (*set_speakers)(struct gpio_runtime *rt, int on);
+	void (*set_lineout)(struct gpio_runtime *rt, int on);
+
+	int (*get_headphone)(struct gpio_runtime *rt);
+	int (*get_speakers)(struct gpio_runtime *rt);
+	int (*get_lineout)(struct gpio_runtime *rt);
+
+	void (*set_hw_reset)(struct gpio_runtime *rt, int on);
+
+	/* use this to be notified of any events. The notification
+	 * function is passed the data, and is called in process
+	 * context by the use of schedule_work.
+	 * The interface for it is that setting a function to NULL
+	 * removes it, and they return 0 if the operation succeeded,
+	 * and -EBUSY if the notification is already assigned by
+	 * someone else. */
+	int (*set_notify)(struct gpio_runtime *rt,
+			  enum notify_type type,
+			  notify_func_t notify,
+			  void *data);
+	/* returns 0 if not plugged in, 1 if plugged in
+	 * or a negative error code */
+	int (*get_detect)(struct gpio_runtime *rt,
+			  enum notify_type type);
+};
+
+struct gpio_notification {
+	notify_func_t notify;
+	void *data;
+	void *gpio_private;
+	struct work_struct work;
+	struct mutex mutex;
+};
+
+struct gpio_runtime {
+	/* to be assigned by fabric */
+	struct device_node *node;
+	/* since everyone needs this pointer anyway... */
+	struct gpio_methods *methods;
+	/* to be used by the gpio implementation */
+	int implementation_private;
+	struct gpio_notification headphone_notify;
+	struct gpio_notification line_in_notify;
+	struct gpio_notification line_out_notify;
+};
+
+#endif /* __AOA_GPIO_H */
diff --git a/sound/aoa/aoa.h b/sound/aoa/aoa.h
new file mode 100644
index 000000000..378ef1e98
--- /dev/null
+++ b/sound/aoa/aoa.h
@@ -0,0 +1,131 @@
+/*
+ * Apple Onboard Audio definitions
+ *
+ * Copyright 2006 Johannes Berg <johannes@sipsolutions.net>
+ *
+ * GPL v2, can be found in COPYING.
+ */
+
+#ifndef __AOA_H
+#define __AOA_H
+#include <asm/prom.h>
+#include <linux/module.h>
+/* So apparently there's a reason for requiring driver.h to be included first! */
+#include <sound/driver.h>
+#include <sound/core.h>
+#include <sound/asound.h>
+#include <sound/control.h>
+#include "aoa-gpio.h"
+#include "soundbus/soundbus.h"
+
+#define MAX_CODEC_NAME_LEN	32
+
+struct aoa_codec {
+	char	name[MAX_CODEC_NAME_LEN];
+
+	struct module *owner;
+
+	/* called when the fabric wants to init this codec.
+	 * Do alsa card manipulations from here. */
+	int (*init)(struct aoa_codec *codec);
+
+	/* called when the fabric is done with the codec.
+	 * The alsa card will be cleaned up so don't bother. */
+	void (*exit)(struct aoa_codec *codec);
+
+	/* May be NULL, but can be used by the fabric.
+	 * Refcounting is the codec driver's responsibility */
+	struct device_node *node;
+
+	/* assigned by fabric before init() is called, points
+	 * to the soundbus device. Cannot be NULL. */
+	struct soundbus_dev *soundbus_dev;
+
+	/* assigned by the fabric before init() is called, points
+	 * to the fabric's gpio runtime record for the relevant
+	 * device. */
+	struct gpio_runtime *gpio;
+
+	/* assigned by the fabric before init() is called, contains
+	 * a codec specific bitmask of what outputs and inputs are
+	 * actually connected */
+	u32 connected;
+
+	/* data the fabric can associate with this structure */
+	void *fabric_data;
+
+	/* private! */
+	struct list_head list;
+	struct aoa_fabric *fabric;
+};
+
+/* return 0 on success */
+extern int
+aoa_codec_register(struct aoa_codec *codec);
+extern void
+aoa_codec_unregister(struct aoa_codec *codec);
+
+#define MAX_LAYOUT_NAME_LEN	32
+
+struct aoa_fabric {
+	char	name[MAX_LAYOUT_NAME_LEN];
+
+	struct module *owner;
+
+	/* once codecs register, they are passed here after.
+	 * They are of course not initialised, since the
+	 * fabric is responsible for initialising some fields
+	 * in the codec structure! */
+	int (*found_codec)(struct aoa_codec *codec);
+	/* called for each codec when it is removed,
+	 * also in the case that aoa_fabric_unregister
+	 * is called and all codecs are removed
+	 * from this fabric.
+	 * Also called if found_codec returned 0 but
+	 * the codec couldn't initialise. */
+	void (*remove_codec)(struct aoa_codec *codec);
+	/* If found_codec returned 0, and the codec
+	 * could be initialised, this is called. */
+	void (*attached_codec)(struct aoa_codec *codec);
+};
+
+/* return 0 on success, -EEXIST if another fabric is
+ * registered, -EALREADY if the same fabric is registered.
+ * Passing NULL can be used to test for the presence
+ * of another fabric, if -EALREADY is returned there is
+ * no other fabric present.
+ * In the case that the function returns -EALREADY
+ * and the fabric passed is not NULL, all codecs
+ * that are not assigned yet are passed to the fabric
+ * again for reconsideration. */
+extern int
+aoa_fabric_register(struct aoa_fabric *fabric);
+
+/* it is vital to call this when the fabric exits!
+ * When calling, the remove_codec will be called
+ * for all codecs, unless it is NULL. */
+extern void
+aoa_fabric_unregister(struct aoa_fabric *fabric);
+
+/* if for some reason you want to get rid of a codec
+ * before the fabric is removed, use this.
+ * Note that remove_codec is called for it! */
+extern void
+aoa_fabric_unlink_codec(struct aoa_codec *codec);
+
+/* alsa help methods */
+struct aoa_card {
+	struct snd_card *alsa_card;
+};
+        
+extern int aoa_snd_device_new(snd_device_type_t type,
+	void * device_data, struct snd_device_ops * ops);
+extern struct snd_card *aoa_get_card(void);
+extern int aoa_snd_ctl_add(struct snd_kcontrol* control);
+
+/* GPIO stuff */
+extern struct gpio_methods *pmf_gpio_methods;
+extern struct gpio_methods *ftr_gpio_methods;
+/* extern struct gpio_methods *map_gpio_methods; */
+
+#endif /* __AOA_H */
diff --git a/sound/aoa/codecs/Kconfig b/sound/aoa/codecs/Kconfig
new file mode 100644
index 000000000..90cf58f68
--- /dev/null
+++ b/sound/aoa/codecs/Kconfig
@@ -0,0 +1,32 @@
+config SND_AOA_ONYX
+	tristate "support Onyx chip"
+	depends on SND_AOA
+	---help---
+	This option enables support for the Onyx (pcm3052)
+	codec chip found in the latest Apple machines
+	(most of those with digital audio output).
+
+#config SND_AOA_TOPAZ
+#	tristate "support Topaz chips"
+#	depends on SND_AOA
+#	---help---
+#	This option enables support for the Topaz (CS84xx)
+#	codec chips found in the latest Apple machines,
+#	these chips do the digital input and output on
+#	some PowerMacs.
+
+config SND_AOA_TAS
+	tristate "support TAS chips"
+	depends on SND_AOA
+	---help---
+	This option enables support for the tas chips
+	found in a lot of Apple Machines, especially
+	iBooks and PowerBooks without digital.
+
+config SND_AOA_TOONIE
+	tristate "support Toonie chip"
+	depends on SND_AOA
+	---help---
+	This option enables support for the toonie codec
+	found in the Mac Mini. If you have a Mac Mini and
+	want to hear sound, select this option.
diff --git a/sound/aoa/codecs/Makefile b/sound/aoa/codecs/Makefile
new file mode 100644
index 000000000..31cbe68fd
--- /dev/null
+++ b/sound/aoa/codecs/Makefile
@@ -0,0 +1,3 @@
+obj-$(CONFIG_SND_AOA_ONYX) += snd-aoa-codec-onyx.o
+obj-$(CONFIG_SND_AOA_TAS) += snd-aoa-codec-tas.o
+obj-$(CONFIG_SND_AOA_TOONIE) += snd-aoa-codec-toonie.o
diff --git a/sound/aoa/codecs/snd-aoa-codec-onyx.c b/sound/aoa/codecs/snd-aoa-codec-onyx.c
new file mode 100644
index 000000000..0b7650788
--- /dev/null
+++ b/sound/aoa/codecs/snd-aoa-codec-onyx.c
@@ -0,0 +1,1113 @@
+/*
+ * Apple Onboard Audio driver for Onyx codec
+ *
+ * Copyright 2006 Johannes Berg <johannes@sipsolutions.net>
+ *
+ * GPL v2, can be found in COPYING.
+ *
+ *
+ * This is a driver for the pcm3052 codec chip (codenamed Onyx)
+ * that is present in newer Apple hardware (with digital output).
+ *
+ * The Onyx codec has the following connections (listed by the bit
+ * to be used in aoa_codec.connected):
+ *  0: analog output
+ *  1: digital output
+ *  2: line input
+ *  3: microphone input
+ * Note that even though I know of no machine that has for example
+ * the digital output connected but not the analog, I have handled
+ * all the different cases in the code so that this driver may serve
+ * as a good example of what to do.
+ *
+ * NOTE: This driver assumes that there's at most one chip to be
+ * 	 used with one alsa card, in form of creating all kinds
+ *	 of mixer elements without regard for their existence.
+ *	 But snd-aoa assumes that there's at most one card, so
+ *	 this means you can only have one onyx on a system. This
+ *	 should probably be fixed by changing the assumption of
+ *	 having just a single card on a system, and making the
+ *	 'card' pointer accessible to anyone who needs it instead
+ *	 of hiding it in the aoa_snd_* functions...
+ *
+ */
+#include <linux/delay.h>
+#include <linux/module.h>
+MODULE_AUTHOR("Johannes Berg <johannes@sipsolutions.net>");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("pcm3052 (onyx) codec driver for snd-aoa");
+
+#include "snd-aoa-codec-onyx.h"
+#include "../aoa.h"
+#include "../soundbus/soundbus.h"
+
+
+#define PFX "snd-aoa-codec-onyx: "
+
+struct onyx {
+	/* cache registers 65 to 80, they are write-only! */
+	u8			cache[16];
+	struct i2c_client	i2c;
+	struct aoa_codec	codec;
+	u32			initialised:1,
+				spdif_locked:1,
+				analog_locked:1,
+				original_mute:2;
+	int			open_count;
+	struct codec_info	*codec_info;
+
+	/* mutex serializes concurrent access to the device
+	 * and this structure.
+	 */
+	struct mutex mutex;
+};
+#define codec_to_onyx(c) container_of(c, struct onyx, codec)
+
+/* both return 0 if all ok, else on error */
+static int onyx_read_register(struct onyx *onyx, u8 reg, u8 *value)
+{
+	s32 v;
+
+	if (reg != ONYX_REG_CONTROL) {
+		*value = onyx->cache[reg-FIRSTREGISTER];
+		return 0;
+	}
+	v = i2c_smbus_read_byte_data(&onyx->i2c, reg);
+	if (v < 0)
+		return -1;
+	*value = (u8)v;
+	onyx->cache[ONYX_REG_CONTROL-FIRSTREGISTER] = *value;
+	return 0;
+}
+
+static int onyx_write_register(struct onyx *onyx, u8 reg, u8 value)
+{
+	int result;
+
+	result = i2c_smbus_write_byte_data(&onyx->i2c, reg, value);
+	if (!result)
+		onyx->cache[reg-FIRSTREGISTER] = value;
+	return result;
+}
+
+/* alsa stuff */
+
+static int onyx_dev_register(struct snd_device *dev)
+{
+	return 0;
+}
+
+static struct snd_device_ops ops = {
+	.dev_register = onyx_dev_register,
+};
+
+/* this is necessary because most alsa mixer programs
+ * can't properly handle the negative range */
+#define VOLUME_RANGE_SHIFT	128
+
+static int onyx_snd_vol_info(struct snd_kcontrol *kcontrol,
+	struct snd_ctl_elem_info *uinfo)
+{
+	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
+	uinfo->count = 2;
+	uinfo->value.integer.min = -128 + VOLUME_RANGE_SHIFT;
+	uinfo->value.integer.max = -1 + VOLUME_RANGE_SHIFT;
+	return 0;
+}
+
+static int onyx_snd_vol_get(struct snd_kcontrol *kcontrol,
+	struct snd_ctl_elem_value *ucontrol)
+{
+	struct onyx *onyx = snd_kcontrol_chip(kcontrol);
+	s8 l, r;
+
+	mutex_lock(&onyx->mutex);
+	onyx_read_register(onyx, ONYX_REG_DAC_ATTEN_LEFT, &l);
+	onyx_read_register(onyx, ONYX_REG_DAC_ATTEN_RIGHT, &r);
+	mutex_unlock(&onyx->mutex);
+
+	ucontrol->value.integer.value[0] = l + VOLUME_RANGE_SHIFT;
+	ucontrol->value.integer.value[1] = r + VOLUME_RANGE_SHIFT;
+
+	return 0;
+}
+
+static int onyx_snd_vol_put(struct snd_kcontrol *kcontrol,
+	struct snd_ctl_elem_value *ucontrol)
+{
+	struct onyx *onyx = snd_kcontrol_chip(kcontrol);
+	s8 l, r;
+
+	mutex_lock(&onyx->mutex);
+	onyx_read_register(onyx, ONYX_REG_DAC_ATTEN_LEFT, &l);
+	onyx_read_register(onyx, ONYX_REG_DAC_ATTEN_RIGHT, &r);
+
+	if (l + VOLUME_RANGE_SHIFT == ucontrol->value.integer.value[0] &&
+	    r + VOLUME_RANGE_SHIFT == ucontrol->value.integer.value[1]) {
+		mutex_unlock(&onyx->mutex);
+		return 0;
+	}
+
+	onyx_write_register(onyx, ONYX_REG_DAC_ATTEN_LEFT,
+			    ucontrol->value.integer.value[0]
+			     - VOLUME_RANGE_SHIFT);
+	onyx_write_register(onyx, ONYX_REG_DAC_ATTEN_RIGHT,
+			    ucontrol->value.integer.value[1]
+			     - VOLUME_RANGE_SHIFT);
+	mutex_unlock(&onyx->mutex);
+
+	return 1;
+}
+
+static struct snd_kcontrol_new volume_control = {
+	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+	.name = "Master Playback Volume",
+	.access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
+	.info = onyx_snd_vol_info,
+	.get = onyx_snd_vol_get,
+	.put = onyx_snd_vol_put,
+};
+
+/* like above, this is necessary because a lot
+ * of alsa mixer programs don't handle ranges
+ * that don't start at 0 properly.
+ * even alsamixer is one of them... */
+#define INPUTGAIN_RANGE_SHIFT	(-3)
+
+static int onyx_snd_inputgain_info(struct snd_kcontrol *kcontrol,
+	struct snd_ctl_elem_info *uinfo)
+{
+	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
+	uinfo->count = 1;
+	uinfo->value.integer.min = 3 + INPUTGAIN_RANGE_SHIFT;
+	uinfo->value.integer.max = 28 + INPUTGAIN_RANGE_SHIFT;
+	return 0;
+}
+
+static int onyx_snd_inputgain_get(struct snd_kcontrol *kcontrol,
+	struct snd_ctl_elem_value *ucontrol)
+{
+	struct onyx *onyx = snd_kcontrol_chip(kcontrol);
+	u8 ig;
+
+	mutex_lock(&onyx->mutex);
+	onyx_read_register(onyx, ONYX_REG_ADC_CONTROL, &ig);
+	mutex_unlock(&onyx->mutex);
+
+	ucontrol->value.integer.value[0] =
+		(ig & ONYX_ADC_PGA_GAIN_MASK) + INPUTGAIN_RANGE_SHIFT;
+
+	return 0;
+}
+
+static int onyx_snd_inputgain_put(struct snd_kcontrol *kcontrol,
+	struct snd_ctl_elem_value *ucontrol)
+{
+	struct onyx *onyx = snd_kcontrol_chip(kcontrol);
+	u8 v, n;
+
+	mutex_lock(&onyx->mutex);
+	onyx_read_register(onyx, ONYX_REG_ADC_CONTROL, &v);
+	n = v;
+	n &= ~ONYX_ADC_PGA_GAIN_MASK;
+	n |= (ucontrol->value.integer.value[0] - INPUTGAIN_RANGE_SHIFT)
+		& ONYX_ADC_PGA_GAIN_MASK;
+	onyx_write_register(onyx, ONYX_REG_ADC_CONTROL, n);
+	mutex_unlock(&onyx->mutex);
+
+	return n != v;
+}
+
+static struct snd_kcontrol_new inputgain_control = {
+	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+	.name = "Master Capture Volume",
+	.access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
+	.info = onyx_snd_inputgain_info,
+	.get = onyx_snd_inputgain_get,
+	.put = onyx_snd_inputgain_put,
+};
+
+static int onyx_snd_capture_source_info(struct snd_kcontrol *kcontrol,
+	struct snd_ctl_elem_info *uinfo)
+{
+	static char *texts[] = { "Line-In", "Microphone" };
+
+	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
+	uinfo->count = 1;
+	uinfo->value.enumerated.items = 2;
+	if (uinfo->value.enumerated.item > 1)
+		uinfo->value.enumerated.item = 1;
+	strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
+	return 0;
+}
+
+static int onyx_snd_capture_source_get(struct snd_kcontrol *kcontrol,
+	struct snd_ctl_elem_value *ucontrol)
+{
+	struct onyx *onyx = snd_kcontrol_chip(kcontrol);
+	s8 v;
+
+	mutex_lock(&onyx->mutex);
+	onyx_read_register(onyx, ONYX_REG_ADC_CONTROL, &v);
+	mutex_unlock(&onyx->mutex);
+
+	ucontrol->value.enumerated.item[0] = !!(v&ONYX_ADC_INPUT_MIC);
+
+	return 0;
+}
+
+static void onyx_set_capture_source(struct onyx *onyx, int mic)
+{
+	s8 v;
+
+	mutex_lock(&onyx->mutex);
+	onyx_read_register(onyx, ONYX_REG_ADC_CONTROL, &v);
+	v &= ~ONYX_ADC_INPUT_MIC;
+	if (mic)
+		v |= ONYX_ADC_INPUT_MIC;
+	onyx_write_register(onyx, ONYX_REG_ADC_CONTROL, v);
+	mutex_unlock(&onyx->mutex);
+}
+
+static int onyx_snd_capture_source_put(struct snd_kcontrol *kcontrol,
+	struct snd_ctl_elem_value *ucontrol)
+{
+	onyx_set_capture_source(snd_kcontrol_chip(kcontrol),
+				ucontrol->value.enumerated.item[0]);
+	return 1;
+}
+
+static struct snd_kcontrol_new capture_source_control = {
+	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+	/* If we name this 'Input Source', it properly shows up in
+	 * alsamixer as a selection, * but it's shown under the 
+	 * 'Playback' category.
+	 * If I name it 'Capture Source', it shows up in strange
+	 * ways (two bools of which one can be selected at a
+	 * time) but at least it's shown in the 'Capture'
+	 * category.
+	 * I was told that this was due to backward compatibility,
+	 * but I don't understand then why the mangling is *not*
+	 * done when I name it "Input Source".....
+	 */
+	.name = "Capture Source",
+	.access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
+	.info = onyx_snd_capture_source_info,
+	.get = onyx_snd_capture_source_get,
+	.put = onyx_snd_capture_source_put,
+};
+
+static int onyx_snd_mute_info(struct snd_kcontrol *kcontrol,
+	struct snd_ctl_elem_info *uinfo)
+{
+	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
+	uinfo->count = 2;
+	uinfo->value.integer.min = 0;
+	uinfo->value.integer.max = 1;
+	return 0;
+}
+
+static int onyx_snd_mute_get(struct snd_kcontrol *kcontrol,
+	struct snd_ctl_elem_value *ucontrol)
+{
+	struct onyx *onyx = snd_kcontrol_chip(kcontrol);
+	u8 c;
+
+	mutex_lock(&onyx->mutex);
+	onyx_read_register(onyx, ONYX_REG_DAC_CONTROL, &c);
+	mutex_unlock(&onyx->mutex);
+
+	ucontrol->value.integer.value[0] = !(c & ONYX_MUTE_LEFT);
+	ucontrol->value.integer.value[1] = !(c & ONYX_MUTE_RIGHT);
+
+	return 0;
+}
+
+static int onyx_snd_mute_put(struct snd_kcontrol *kcontrol,
+	struct snd_ctl_elem_value *ucontrol)
+{
+	struct onyx *onyx = snd_kcontrol_chip(kcontrol);
+	u8 v = 0, c = 0;
+	int err = -EBUSY;
+
+	mutex_lock(&onyx->mutex);
+	if (onyx->analog_locked)
+		goto out_unlock;
+
+	onyx_read_register(onyx, ONYX_REG_DAC_CONTROL, &v);
+	c = v;
+	c &= ~(ONYX_MUTE_RIGHT | ONYX_MUTE_LEFT);
+	if (!ucontrol->value.integer.value[0])
+		c |= ONYX_MUTE_LEFT;
+	if (!ucontrol->value.integer.value[1])
+		c |= ONYX_MUTE_RIGHT;
+	err = onyx_write_register(onyx, ONYX_REG_DAC_CONTROL, c);
+
+ out_unlock:
+	mutex_unlock(&onyx->mutex);
+
+	return !err ? (v != c) : err;
+}
+
+static struct snd_kcontrol_new mute_control = {
+	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+	.name = "Master Playback Switch",
+	.access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
+	.info = onyx_snd_mute_info,
+	.get = onyx_snd_mute_get,
+	.put = onyx_snd_mute_put,
+};
+
+
+static int onyx_snd_single_bit_info(struct snd_kcontrol *kcontrol,
+	struct snd_ctl_elem_info *uinfo)
+{
+	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
+	uinfo->count = 1;
+	uinfo->value.integer.min = 0;
+	uinfo->value.integer.max = 1;
+	return 0;
+}
+
+#define FLAG_POLARITY_INVERT	1
+#define FLAG_SPDIFLOCK		2
+
+static int onyx_snd_single_bit_get(struct snd_kcontrol *kcontrol,
+	struct snd_ctl_elem_value *ucontrol)
+{
+	struct onyx *onyx = snd_kcontrol_chip(kcontrol);
+	u8 c;
+	long int pv = kcontrol->private_value;
+	u8 polarity = (pv >> 16) & FLAG_POLARITY_INVERT;
+	u8 address = (pv >> 8) & 0xff;
+	u8 mask = pv & 0xff;
+
+	mutex_lock(&onyx->mutex);
+	onyx_read_register(onyx, address, &c);
+	mutex_unlock(&onyx->mutex);
+
+	ucontrol->value.integer.value[0] = !!(c & mask) ^ polarity;
+
+	return 0;
+}
+
+static int onyx_snd_single_bit_put(struct snd_kcontrol *kcontrol,
+	struct snd_ctl_elem_value *ucontrol)
+{
+	struct onyx *onyx = snd_kcontrol_chip(kcontrol);
+	u8 v = 0, c = 0;
+	int err;
+	long int pv = kcontrol->private_value;
+	u8 polarity = (pv >> 16) & FLAG_POLARITY_INVERT;
+	u8 spdiflock = (pv >> 16) & FLAG_SPDIFLOCK;
+	u8 address = (pv >> 8) & 0xff;
+	u8 mask = pv & 0xff;
+
+	mutex_lock(&onyx->mutex);
+	if (spdiflock && onyx->spdif_locked) {
+		/* even if alsamixer doesn't care.. */
+		err = -EBUSY;
+		goto out_unlock;
+	}
+	onyx_read_register(onyx, address, &v);
+	c = v;
+	c &= ~(mask);
+	if (!!ucontrol->value.integer.value[0] ^ polarity)
+		c |= mask;
+	err = onyx_write_register(onyx, address, c);
+
+ out_unlock:
+	mutex_unlock(&onyx->mutex);
+
+	return !err ? (v != c) : err;
+}
+
+#define SINGLE_BIT(n, type, description, address, mask, flags)	 	\
+static struct snd_kcontrol_new n##_control = {				\
+	.iface = SNDRV_CTL_ELEM_IFACE_##type,				\
+	.name = description,						\
+	.access = SNDRV_CTL_ELEM_ACCESS_READWRITE,			\
+	.info = onyx_snd_single_bit_info,				\
+	.get = onyx_snd_single_bit_get,					\
+	.put = onyx_snd_single_bit_put,					\
+	.private_value = (flags << 16) | (address << 8) | mask		\
+}
+
+SINGLE_BIT(spdif,
+	   MIXER,
+	   SNDRV_CTL_NAME_IEC958("", PLAYBACK, SWITCH),
+	   ONYX_REG_DIG_INFO4,
+	   ONYX_SPDIF_ENABLE,
+	   FLAG_SPDIFLOCK);
+SINGLE_BIT(ovr1,
+	   MIXER,
+	   "Oversampling Rate",
+	   ONYX_REG_DAC_CONTROL,
+	   ONYX_OVR1,
+	   0);
+SINGLE_BIT(flt0,
+	   MIXER,
+	   "Fast Digital Filter Rolloff",
+	   ONYX_REG_DAC_FILTER,
+	   ONYX_ROLLOFF_FAST,
+	   FLAG_POLARITY_INVERT);
+SINGLE_BIT(hpf,
+	   MIXER,
+	   "Highpass Filter",
+	   ONYX_REG_ADC_HPF_BYPASS,
+	   ONYX_HPF_DISABLE,
+	   FLAG_POLARITY_INVERT);
+SINGLE_BIT(dm12,
+	   MIXER,
+	   "Digital De-Emphasis",
+	   ONYX_REG_DAC_DEEMPH,
+	   ONYX_DIGDEEMPH_CTRL,
+	   0);
+
+static int onyx_spdif_info(struct snd_kcontrol *kcontrol,
+			   struct snd_ctl_elem_info *uinfo)
+{
+	uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
+	uinfo->count = 1;
+	return 0;
+}
+
+static int onyx_spdif_mask_get(struct snd_kcontrol *kcontrol,
+			       struct snd_ctl_elem_value *ucontrol)
+{
+	/* datasheet page 30, all others are 0 */
+	ucontrol->value.iec958.status[0] = 0x3e;
+	ucontrol->value.iec958.status[1] = 0xff;
+
+	ucontrol->value.iec958.status[3] = 0x3f;
+	ucontrol->value.iec958.status[4] = 0x0f;
+	
+	return 0;
+}
+
+static struct snd_kcontrol_new onyx_spdif_mask = {
+	.access =	SNDRV_CTL_ELEM_ACCESS_READ,
+	.iface =	SNDRV_CTL_ELEM_IFACE_PCM,
+	.name =		SNDRV_CTL_NAME_IEC958("",PLAYBACK,CON_MASK),
+	.info =		onyx_spdif_info,
+	.get =		onyx_spdif_mask_get,
+};
+
+static int onyx_spdif_get(struct snd_kcontrol *kcontrol,
+			  struct snd_ctl_elem_value *ucontrol)
+{
+	struct onyx *onyx = snd_kcontrol_chip(kcontrol);
+	u8 v;
+
+	mutex_lock(&onyx->mutex);
+	onyx_read_register(onyx, ONYX_REG_DIG_INFO1, &v);
+	ucontrol->value.iec958.status[0] = v & 0x3e;
+
+	onyx_read_register(onyx, ONYX_REG_DIG_INFO2, &v);
+	ucontrol->value.iec958.status[1] = v;
+
+	onyx_read_register(onyx, ONYX_REG_DIG_INFO3, &v);
+	ucontrol->value.iec958.status[3] = v & 0x3f;
+
+	onyx_read_register(onyx, ONYX_REG_DIG_INFO4, &v);
+	ucontrol->value.iec958.status[4] = v & 0x0f;
+	mutex_unlock(&onyx->mutex);
+
+	return 0;
+}
+
+static int onyx_spdif_put(struct snd_kcontrol *kcontrol,
+			  struct snd_ctl_elem_value *ucontrol)
+{
+	struct onyx *onyx = snd_kcontrol_chip(kcontrol);
+	u8 v;
+
+	mutex_lock(&onyx->mutex);
+	onyx_read_register(onyx, ONYX_REG_DIG_INFO1, &v);
+	v = (v & ~0x3e) | (ucontrol->value.iec958.status[0] & 0x3e);
+	onyx_write_register(onyx, ONYX_REG_DIG_INFO1, v);
+
+	v = ucontrol->value.iec958.status[1];
+	onyx_write_register(onyx, ONYX_REG_DIG_INFO2, v);
+
+	onyx_read_register(onyx, ONYX_REG_DIG_INFO3, &v);
+	v = (v & ~0x3f) | (ucontrol->value.iec958.status[3] & 0x3f);
+	onyx_write_register(onyx, ONYX_REG_DIG_INFO3, v);
+
+	onyx_read_register(onyx, ONYX_REG_DIG_INFO4, &v);
+	v = (v & ~0x0f) | (ucontrol->value.iec958.status[4] & 0x0f);
+	onyx_write_register(onyx, ONYX_REG_DIG_INFO4, v);
+	mutex_unlock(&onyx->mutex);
+
+	return 1;
+}
+
+static struct snd_kcontrol_new onyx_spdif_ctrl = {
+	.access =	SNDRV_CTL_ELEM_ACCESS_READWRITE,
+	.iface =	SNDRV_CTL_ELEM_IFACE_PCM,
+	.name =		SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT),
+	.info =		onyx_spdif_info,
+	.get =		onyx_spdif_get,
+	.put =		onyx_spdif_put,
+};
+
+/* our registers */
+
+static u8 register_map[] = {
+	ONYX_REG_DAC_ATTEN_LEFT,
+	ONYX_REG_DAC_ATTEN_RIGHT,
+	ONYX_REG_CONTROL,
+	ONYX_REG_DAC_CONTROL,
+	ONYX_REG_DAC_DEEMPH,
+	ONYX_REG_DAC_FILTER,
+	ONYX_REG_DAC_OUTPHASE,
+	ONYX_REG_ADC_CONTROL,
+	ONYX_REG_ADC_HPF_BYPASS,
+	ONYX_REG_DIG_INFO1,
+	ONYX_REG_DIG_INFO2,
+	ONYX_REG_DIG_INFO3,
+	ONYX_REG_DIG_INFO4
+};
+
+static u8 initial_values[ARRAY_SIZE(register_map)] = {
+	0x80, 0x80, /* muted */
+	ONYX_MRST | ONYX_SRST, /* but handled specially! */
+	ONYX_MUTE_LEFT | ONYX_MUTE_RIGHT,
+	0, /* no deemphasis */
+	ONYX_DAC_FILTER_ALWAYS,
+	ONYX_OUTPHASE_INVERTED,
+	(-1 /*dB*/ + 8) & 0xF, /* line in selected, -1 dB gain*/
+	ONYX_ADC_HPF_ALWAYS,
+	(1<<2),	/* pcm audio */
+	2,	/* category: pcm coder */
+	0,	/* sampling frequency 44.1 kHz, clock accuracy level II */
+	1	/* 24 bit depth */
+};
+
+/* reset registers of chip, either to initial or to previous values */
+static int onyx_register_init(struct onyx *onyx)
+{
+	int i;
+	u8 val;
+	u8 regs[sizeof(initial_values)];
+
+	if (!onyx->initialised) {
+		memcpy(regs, initial_values, sizeof(initial_values));
+		if (onyx_read_register(onyx, ONYX_REG_CONTROL, &val))
+			return -1;
+		val &= ~ONYX_SILICONVERSION;
+		val |= initial_values[3];
+		regs[3] = val;
+	} else {
+		for (i=0; i<sizeof(register_map); i++)
+			regs[i] = onyx->cache[register_map[i]-FIRSTREGISTER];
+	}
+
+	for (i=0; i<sizeof(register_map); i++) {
+		if (onyx_write_register(onyx, register_map[i], regs[i]))
+			return -1;
+	}
+	onyx->initialised = 1;
+	return 0;
+}
+
+static struct transfer_info onyx_transfers[] = {
+	/* this is first so we can skip it if no input is present...
+	 * No hardware exists with that, but it's here as an example
+	 * of what to do :) */
+	{
+		/* analog input */
+		.formats = SNDRV_PCM_FMTBIT_S8 |
+			   SNDRV_PCM_FMTBIT_S16_BE |
+			   SNDRV_PCM_FMTBIT_S24_BE,
+		.rates = SNDRV_PCM_RATE_8000_96000,
+		.transfer_in = 1,
+		.must_be_clock_source = 0,
+		.tag = 0,
+	},
+	{
+		/* if analog and digital are currently off, anything should go,
+		 * so this entry describes everything we can do... */
+		.formats = SNDRV_PCM_FMTBIT_S8 |
+			   SNDRV_PCM_FMTBIT_S16_BE |
+			   SNDRV_PCM_FMTBIT_S24_BE
+#ifdef SNDRV_PCM_FMTBIT_COMPRESSED_16BE
+			   | SNDRV_PCM_FMTBIT_COMPRESSED_16BE
+#endif
+		,
+		.rates = SNDRV_PCM_RATE_8000_96000,
+		.tag = 0,
+	},
+	{
+		/* analog output */
+		.formats = SNDRV_PCM_FMTBIT_S8 |
+			   SNDRV_PCM_FMTBIT_S16_BE |
+			   SNDRV_PCM_FMTBIT_S24_BE,
+		.rates = SNDRV_PCM_RATE_8000_96000,
+		.transfer_in = 0,
+		.must_be_clock_source = 0,
+		.tag = 1,
+	},
+	{
+		/* digital pcm output, also possible for analog out */
+		.formats = SNDRV_PCM_FMTBIT_S8 |
+			   SNDRV_PCM_FMTBIT_S16_BE |
+			   SNDRV_PCM_FMTBIT_S24_BE,
+		.rates = SNDRV_PCM_RATE_32000 |
+			 SNDRV_PCM_RATE_44100 |
+			 SNDRV_PCM_RATE_48000,
+		.transfer_in = 0,
+		.must_be_clock_source = 0,
+		.tag = 2,
+	},
+#ifdef SNDRV_PCM_FMTBIT_COMPRESSED_16BE
+Once alsa gets supports for this kind of thing we can add it...
+	{
+		/* digital compressed output */
+		.formats =  SNDRV_PCM_FMTBIT_COMPRESSED_16BE,
+		.rates = SNDRV_PCM_RATE_32000 |
+			 SNDRV_PCM_RATE_44100 |
+			 SNDRV_PCM_RATE_48000,
+		.tag = 2,
+	},
+#endif
+	{}
+};
+
+static int onyx_usable(struct codec_info_item *cii,
+		       struct transfer_info *ti,
+		       struct transfer_info *out)
+{
+	u8 v;
+	struct onyx *onyx = cii->codec_data;
+	int spdif_enabled, analog_enabled;
+
+	mutex_lock(&onyx->mutex);
+	onyx_read_register(onyx, ONYX_REG_DIG_INFO4, &v);
+	spdif_enabled = !!(v & ONYX_SPDIF_ENABLE);
+	onyx_read_register(onyx, ONYX_REG_DAC_CONTROL, &v);
+	analog_enabled = 
+		(v & (ONYX_MUTE_RIGHT|ONYX_MUTE_LEFT))
+		 != (ONYX_MUTE_RIGHT|ONYX_MUTE_LEFT);
+	mutex_unlock(&onyx->mutex);
+
+	switch (ti->tag) {
+	case 0: return 1;
+	case 1:	return analog_enabled;
+	case 2: return spdif_enabled;
+	}
+	return 1;
+}
+
+static int onyx_prepare(struct codec_info_item *cii,
+			struct bus_info *bi,
+			struct snd_pcm_substream *substream)
+{
+	u8 v;
+	struct onyx *onyx = cii->codec_data;
+	int err = -EBUSY;
+
+	mutex_lock(&onyx->mutex);
+
+#ifdef SNDRV_PCM_FMTBIT_COMPRESSED_16BE
+	if (substream->runtime->format == SNDRV_PCM_FMTBIT_COMPRESSED_16BE) {
+		/* mute and lock analog output */
+		onyx_read_register(onyx, ONYX_REG_DAC_CONTROL, &v);
+		if (onyx_write_register(onyx
+					ONYX_REG_DAC_CONTROL,
+					v | ONYX_MUTE_RIGHT | ONYX_MUTE_LEFT))
+			goto out_unlock;
+		onyx->analog_locked = 1;
+		err = 0;
+		goto out_unlock;
+	}
+#endif
+	switch (substream->runtime->rate) {
+	case 32000:
+	case 44100:
+	case 48000:
+		/* these rates are ok for all outputs */
+		/* FIXME: program spdif channel control bits here so that
+		 *	  userspace doesn't have to if it only plays pcm! */
+		err = 0;
+		goto out_unlock;
+	default:
+		/* got some rate that the digital output can't do,
+		 * so disable and lock it */
+		onyx_read_register(cii->codec_data, ONYX_REG_DIG_INFO4, &v);
+		if (onyx_write_register(onyx,
+					ONYX_REG_DIG_INFO4,
+					v & ~ONYX_SPDIF_ENABLE))
+			goto out_unlock;
+		onyx->spdif_locked = 1;
+		err = 0;
+		goto out_unlock;
+	}
+
+ out_unlock:
+	mutex_unlock(&onyx->mutex);
+
+	return err;
+}
+
+static int onyx_open(struct codec_info_item *cii,
+		     struct snd_pcm_substream *substream)
+{
+	struct onyx *onyx = cii->codec_data;
+
+	mutex_lock(&onyx->mutex);
+	onyx->open_count++;
+	mutex_unlock(&onyx->mutex);
+
+	return 0;
+}
+
+static int onyx_close(struct codec_info_item *cii,
+		      struct snd_pcm_substream *substream)
+{
+	struct onyx *onyx = cii->codec_data;
+
+	mutex_lock(&onyx->mutex);
+	onyx->open_count--;
+	if (!onyx->open_count)
+		onyx->spdif_locked = onyx->analog_locked = 0;
+	mutex_unlock(&onyx->mutex);
+
+	return 0;
+}
+
+static int onyx_switch_clock(struct codec_info_item *cii,
+			     enum clock_switch what)
+{
+	struct onyx *onyx = cii->codec_data;
+
+	mutex_lock(&onyx->mutex);
+	/* this *MUST* be more elaborate later... */
+	switch (what) {
+	case CLOCK_SWITCH_PREPARE_SLAVE:
+		onyx->codec.gpio->methods->all_amps_off(onyx->codec.gpio);
+		break;
+	case CLOCK_SWITCH_SLAVE:
+		onyx->codec.gpio->methods->all_amps_restore(onyx->codec.gpio);
+		break;
+	default: /* silence warning */
+		break;
+	}
+	mutex_unlock(&onyx->mutex);
+
+	return 0;
+}
+
+#ifdef CONFIG_PM
+
+static int onyx_suspend(struct codec_info_item *cii, pm_message_t state)
+{
+	struct onyx *onyx = cii->codec_data;
+	u8 v;
+	int err = -ENXIO;
+
+	mutex_lock(&onyx->mutex);
+	if (onyx_read_register(onyx, ONYX_REG_CONTROL, &v))
+		goto out_unlock;
+	onyx_write_register(onyx, ONYX_REG_CONTROL, v | ONYX_ADPSV | ONYX_DAPSV);
+	/* Apple does a sleep here but the datasheet says to do it on resume */
+	err = 0;
+ out_unlock:
+	mutex_unlock(&onyx->mutex);
+
+	return err;
+}
+
+static int onyx_resume(struct codec_info_item *cii)
+{
+	struct onyx *onyx = cii->codec_data;
+	u8 v;
+	int err = -ENXIO;
+
+	mutex_lock(&onyx->mutex);
+	/* take codec out of suspend */
+	if (onyx_read_register(onyx, ONYX_REG_CONTROL, &v))
+		goto out_unlock;
+	onyx_write_register(onyx, ONYX_REG_CONTROL, v & ~(ONYX_ADPSV | ONYX_DAPSV));
+	/* FIXME: should divide by sample rate, but 8k is the lowest we go */
+	msleep(2205000/8000);
+	/* reset all values */
+	onyx_register_init(onyx);
+	err = 0;
+ out_unlock:
+	mutex_unlock(&onyx->mutex);
+
+	return err;
+}
+
+#endif /* CONFIG_PM */
+
+static struct codec_info onyx_codec_info = {
+	.transfers = onyx_transfers,
+	.sysclock_factor = 256,
+	.bus_factor = 64,
+	.owner = THIS_MODULE,
+	.usable = onyx_usable,
+	.prepare = onyx_prepare,
+	.open = onyx_open,
+	.close = onyx_close,
+	.switch_clock = onyx_switch_clock,
+#ifdef CONFIG_PM
+	.suspend = onyx_suspend,
+	.resume = onyx_resume,
+#endif
+};
+
+static int onyx_init_codec(struct aoa_codec *codec)
+{
+	struct onyx *onyx = codec_to_onyx(codec);
+	struct snd_kcontrol *ctl;
+	struct codec_info *ci = &onyx_codec_info;
+	u8 v;
+	int err;
+
+	if (!onyx->codec.gpio || !onyx->codec.gpio->methods) {
+		printk(KERN_ERR PFX "gpios not assigned!!\n");
+		return -EINVAL;
+	}
+
+	onyx->codec.gpio->methods->set_hw_reset(onyx->codec.gpio, 0);
+	msleep(1);
+	onyx->codec.gpio->methods->set_hw_reset(onyx->codec.gpio, 1);
+	msleep(1);
+	onyx->codec.gpio->methods->set_hw_reset(onyx->codec.gpio, 0);
+	msleep(1);
+	
+	if (onyx_register_init(onyx)) {
+		printk(KERN_ERR PFX "failed to initialise onyx registers\n");
+		return -ENODEV;
+	}
+
+	if (aoa_snd_device_new(SNDRV_DEV_LOWLEVEL, onyx, &ops)) {
+		printk(KERN_ERR PFX "failed to create onyx snd device!\n");
+		return -ENODEV;
+	}
+
+	/* nothing connected? what a joke! */
+	if ((onyx->codec.connected & 0xF) == 0)
+		return -ENOTCONN;
+
+	/* if no inputs are present... */
+	if ((onyx->codec.connected & 0xC) == 0) {
+		if (!onyx->codec_info)
+			onyx->codec_info = kmalloc(sizeof(struct codec_info), GFP_KERNEL);
+		if (!onyx->codec_info)
+			return -ENOMEM;
+		ci = onyx->codec_info;
+		*ci = onyx_codec_info;
+		ci->transfers++;
+	}
+
+	/* if no outputs are present... */
+	if ((onyx->codec.connected & 3) == 0) {
+		if (!onyx->codec_info)
+			onyx->codec_info = kmalloc(sizeof(struct codec_info), GFP_KERNEL);
+		if (!onyx->codec_info)
+			return -ENOMEM;
+		ci = onyx->codec_info;
+		/* this is fine as there have to be inputs
+		 * if we end up in this part of the code */
+		*ci = onyx_codec_info;
+		ci->transfers[1].formats = 0;
+	}
+
+	if (onyx->codec.soundbus_dev->attach_codec(onyx->codec.soundbus_dev,
+						   aoa_get_card(),
+						   ci, onyx)) {
+		printk(KERN_ERR PFX "error creating onyx pcm\n");
+		return -ENODEV;
+	}
+#define ADDCTL(n)							\
+	do {								\
+		ctl = snd_ctl_new1(&n, onyx);				\
+		if (ctl) {						\
+			ctl->id.device =				\
+				onyx->codec.soundbus_dev->pcm->device;	\
+			err = aoa_snd_ctl_add(ctl);			\
+			if (err)					\
+				goto error;				\
+		}							\
+	} while (0)
+
+	if (onyx->codec.soundbus_dev->pcm) {
+		/* give the user appropriate controls
+		 * depending on what inputs are connected */
+		if ((onyx->codec.connected & 0xC) == 0xC)
+			ADDCTL(capture_source_control);
+		else if (onyx->codec.connected & 4)
+			onyx_set_capture_source(onyx, 0);
+		else
+			onyx_set_capture_source(onyx, 1);
+		if (onyx->codec.connected & 0xC)
+			ADDCTL(inputgain_control);
+
+		/* depending on what output is connected,
+		 * give the user appropriate controls */
+		if (onyx->codec.connected & 1) {
+			ADDCTL(volume_control);
+			ADDCTL(mute_control);
+			ADDCTL(ovr1_control);
+			ADDCTL(flt0_control);
+			ADDCTL(hpf_control);
+			ADDCTL(dm12_control);
+			/* spdif control defaults to off */
+		}
+		if (onyx->codec.connected & 2) {
+			ADDCTL(onyx_spdif_mask);
+			ADDCTL(onyx_spdif_ctrl);
+		}
+		if ((onyx->codec.connected & 3) == 3)
+			ADDCTL(spdif_control);
+		/* if only S/PDIF is connected, enable it unconditionally */
+		if ((onyx->codec.connected & 3) == 2) {
+			onyx_read_register(onyx, ONYX_REG_DIG_INFO4, &v);
+			v |= ONYX_SPDIF_ENABLE;
+			onyx_write_register(onyx, ONYX_REG_DIG_INFO4, v);
+		}
+	}
+#undef ADDCTL
+	printk(KERN_INFO PFX "attached to onyx codec via i2c\n");
+
+	return 0;
+ error:
+	onyx->codec.soundbus_dev->detach_codec(onyx->codec.soundbus_dev, onyx);
+	snd_device_free(aoa_get_card(), onyx);
+	return err;
+}
+
+static void onyx_exit_codec(struct aoa_codec *codec)
+{
+	struct onyx *onyx = codec_to_onyx(codec);
+
+	if (!onyx->codec.soundbus_dev) {
+		printk(KERN_ERR PFX "onyx_exit_codec called without soundbus_dev!\n");
+		return;
+	}
+	onyx->codec.soundbus_dev->detach_codec(onyx->codec.soundbus_dev, onyx);
+}
+
+static struct i2c_driver onyx_driver;
+
+static int onyx_create(struct i2c_adapter *adapter,
+		       struct device_node *node,
+		       int addr)
+{
+	struct onyx *onyx;
+	u8 dummy;
+
+	onyx = kzalloc(sizeof(struct onyx), GFP_KERNEL);
+
+	if (!onyx)
+		return -ENOMEM;
+
+	mutex_init(&onyx->mutex);
+	onyx->i2c.driver = &onyx_driver;
+	onyx->i2c.adapter = adapter;
+	onyx->i2c.addr = addr & 0x7f;
+	strlcpy(onyx->i2c.name, "onyx audio codec", I2C_NAME_SIZE-1);
+
+	if (i2c_attach_client(&onyx->i2c)) {
+		printk(KERN_ERR PFX "failed to attach to i2c\n");
+		goto fail;
+	}
+
+	/* we try to read from register ONYX_REG_CONTROL
+	 * to check if the codec is present */
+	if (onyx_read_register(onyx, ONYX_REG_CONTROL, &dummy) != 0) {
+		i2c_detach_client(&onyx->i2c);
+		printk(KERN_ERR PFX "failed to read control register\n");
+		goto fail;
+	}
+
+	strlcpy(onyx->codec.name, "onyx", MAX_CODEC_NAME_LEN-1);
+	onyx->codec.owner = THIS_MODULE;
+	onyx->codec.init = onyx_init_codec;
+	onyx->codec.exit = onyx_exit_codec;
+	onyx->codec.node = of_node_get(node);
+
+	if (aoa_codec_register(&onyx->codec)) {
+		i2c_detach_client(&onyx->i2c);
+		goto fail;
+	}
+	printk(KERN_DEBUG PFX "created and attached onyx instance\n");
+	return 0;
+ fail:
+	kfree(onyx);
+	return -EINVAL;
+}
+
+static int onyx_i2c_attach(struct i2c_adapter *adapter)
+{
+	struct device_node *busnode, *dev = NULL;
+	struct pmac_i2c_bus *bus;
+
+	bus = pmac_i2c_adapter_to_bus(adapter);
+	if (bus == NULL)
+		return -ENODEV;
+	busnode = pmac_i2c_get_bus_node(bus);
+
+	while ((dev = of_get_next_child(busnode, dev)) != NULL) {
+		if (device_is_compatible(dev, "pcm3052")) {
+			u32 *addr;
+			printk(KERN_DEBUG PFX "found pcm3052\n");
+			addr = (u32 *) get_property(dev, "reg", NULL);
+			if (!addr)
+				return -ENODEV;
+			return onyx_create(adapter, dev, (*addr)>>1);
+		}
+	}
+
+	/* if that didn't work, try desperate mode for older
+	 * machines that have stuff missing from the device tree */
+	
+	if (!device_is_compatible(busnode, "k2-i2c"))
+		return -ENODEV;
+
+	printk(KERN_DEBUG PFX "found k2-i2c, checking if onyx chip is on it\n");
+	/* probe both possible addresses for the onyx chip */
+	if (onyx_create(adapter, NULL, 0x46) == 0)
+		return 0;
+	return onyx_create(adapter, NULL, 0x47);
+}
+
+static int onyx_i2c_detach(struct i2c_client *client)
+{
+	struct onyx *onyx = container_of(client, struct onyx, i2c);
+	int err;
+
+	if ((err = i2c_detach_client(client)))
+		return err;
+	aoa_codec_unregister(&onyx->codec);
+	of_node_put(onyx->codec.node);
+	if (onyx->codec_info)
+		kfree(onyx->codec_info);
+	kfree(onyx);
+	return 0;
+}
+
+static struct i2c_driver onyx_driver = {
+	.driver = {
+		.name = "aoa_codec_onyx",
+		.owner = THIS_MODULE,
+	},
+	.attach_adapter = onyx_i2c_attach,
+	.detach_client = onyx_i2c_detach,
+};
+
+static int __init onyx_init(void)
+{
+	return i2c_add_driver(&onyx_driver);
+}
+
+static void __exit onyx_exit(void)
+{
+	i2c_del_driver(&onyx_driver);
+}
+
+module_init(onyx_init);
+module_exit(onyx_exit);
diff --git a/sound/aoa/codecs/snd-aoa-codec-onyx.h b/sound/aoa/codecs/snd-aoa-codec-onyx.h
new file mode 100644
index 000000000..aeedda773
--- /dev/null
+++ b/sound/aoa/codecs/snd-aoa-codec-onyx.h
@@ -0,0 +1,76 @@
+/*
+ * Apple Onboard Audio driver for Onyx codec (header)
+ *
+ * Copyright 2006 Johannes Berg <johannes@sipsolutions.net>
+ *
+ * GPL v2, can be found in COPYING.
+ */
+#ifndef __SND_AOA_CODEC_ONYX_H
+#define __SND_AOA_CODEC_ONYX_H
+#include <stddef.h>
+#include <linux/i2c.h>
+#include <linux/i2c-dev.h>
+#include <asm/pmac_low_i2c.h>
+#include <asm/prom.h>
+
+/* PCM3052 register definitions */
+
+/* the attenuation registers take values from
+ * -1 (0dB) to -127 (-63.0 dB) or others (muted) */
+#define ONYX_REG_DAC_ATTEN_LEFT		65
+#define FIRSTREGISTER			ONYX_REG_DAC_ATTEN_LEFT
+#define ONYX_REG_DAC_ATTEN_RIGHT	66
+
+#define ONYX_REG_CONTROL		67
+#	define ONYX_MRST		(1<<7)
+#	define ONYX_SRST		(1<<6)
+#	define ONYX_ADPSV		(1<<5)
+#	define ONYX_DAPSV		(1<<4)
+#	define ONYX_SILICONVERSION	(1<<0)
+/* all others reserved */
+
+#define ONYX_REG_DAC_CONTROL		68
+#	define ONYX_OVR1		(1<<6)
+#	define ONYX_MUTE_RIGHT		(1<<1)
+#	define ONYX_MUTE_LEFT		(1<<0)
+
+#define ONYX_REG_DAC_DEEMPH		69
+#	define ONYX_DIGDEEMPH_SHIFT	5
+#	define ONYX_DIGDEEMPH_MASK	(3<<ONYX_DIGDEEMPH_SHIFT)
+#	define ONYX_DIGDEEMPH_CTRL	(1<<4)
+
+#define ONYX_REG_DAC_FILTER		70
+#	define ONYX_ROLLOFF_FAST	(1<<5)
+#	define ONYX_DAC_FILTER_ALWAYS	(1<<2)
+
+#define	ONYX_REG_DAC_OUTPHASE		71
+#	define ONYX_OUTPHASE_INVERTED	(1<<0)
+
+#define ONYX_REG_ADC_CONTROL		72
+#	define ONYX_ADC_INPUT_MIC	(1<<5)
+/* 8 + input gain in dB, valid range for input gain is -4 .. 20 dB */
+#	define ONYX_ADC_PGA_GAIN_MASK	0x1f
+
+#define ONYX_REG_ADC_HPF_BYPASS		75
+#	define ONYX_HPF_DISABLE		(1<<3)
+#	define ONYX_ADC_HPF_ALWAYS	(1<<2)
+
+#define ONYX_REG_DIG_INFO1		77
+#	define ONYX_MASK_DIN_TO_BPZ	(1<<7)
+/* bits 1-5 control channel bits 1-5 */
+#	define ONYX_DIGOUT_DISABLE	(1<<0)
+
+#define ONYX_REG_DIG_INFO2		78
+/* controls channel bits 8-15 */
+
+#define ONYX_REG_DIG_INFO3		79
+/* control channel bits 24-29, high 2 bits reserved */
+
+#define ONYX_REG_DIG_INFO4		80
+#	define ONYX_VALIDL		(1<<7)
+#	define ONYX_VALIDR		(1<<6)
+#	define ONYX_SPDIF_ENABLE	(1<<5)
+/* lower 4 bits control bits 32-35 of channel control and word length */
+#	define ONYX_WORDLEN_MASK	(0xF)
+
+#endif /* __SND_AOA_CODEC_ONYX_H */
diff --git a/sound/aoa/codecs/snd-aoa-codec-tas-basstreble.h b/sound/aoa/codecs/snd-aoa-codec-tas-basstreble.h
new file mode 100644
index 000000000..69b61136f
--- /dev/null
+++ b/sound/aoa/codecs/snd-aoa-codec-tas-basstreble.h
@@ -0,0 +1,134 @@
+/*
+ * This file is only included exactly once!
+ *
+ * The tables here are derived from the tas3004 datasheet,
+ * modulo typo corrections and some smoothing...
+ */
+
+#define TAS3004_TREBLE_MIN	0
+#define TAS3004_TREBLE_MAX	72
+#define TAS3004_BASS_MIN	0
+#define TAS3004_BASS_MAX	72
+#define TAS3004_TREBLE_ZERO	36
+#define TAS3004_BASS_ZERO	36
+
+static u8 tas3004_treble_table[] = {
+	150, /* -18 dB */
+	149,
+	148,
+	147,
+	146,
+	145,
+	144,
+	143,
+	142,
+	141,
+	140,
+	139,
+	138,
+	137,
+	136,
+	135,
+	134,
+	133,
+	132,
+	131,
+	130,
+	129,
+	128,
+	127,
+	126,
+	125,
+	124,
+	123,
+	122,
+	121,
+	120,
+	119,
+	118,
+	117,
+	116,
+	115,
+	114, /* 0 dB */
+	113,
+	112,
+	111,
+	109,
+	108,
+	107,
+	105,
+	104,
+	103,
+	101,
+	99,
+	98,
+	96,
+	93,
+	91,
+	89,
+	86,
+	83,
+	81,
+	77,
+	74,
+	71,
+	67,
+	63,
+	59,
+	54,
+	49,
+	44,
+	38,
+	32,
+	26,
+	19,
+	10,
+	4,
+	2,
+	1, /* +18 dB */
+};
+
+static inline u8 tas3004_treble(int idx)
+{
+	return tas3004_treble_table[idx];
+}
+
+/* I only save the difference here to the treble table
+ * so that the binary is smaller...
+ * I have also ignored completely differences of
+ * +/- 1
+ */
+static s8 tas3004_bass_diff_to_treble[] = {
+	2, /* 7 dB, offset 50 */
+	2,
+	2,
+	2,
+	2,
+	1,
+	2,
+	2,
+	2,
+	3,
+	4,
+	4,
+	5,
+	6,
+	7,
+	8,
+	9,
+	10,
+	11,
+	14,
+	13,
+	8,
+	1, /* 18 dB */
+};
+
+static inline u8 tas3004_bass(int idx)
+{
+	u8 result = tas3004_treble_table[idx];
+
+	if (idx >= 50)
+		result += tas3004_bass_diff_to_treble[idx-50];
+	return result;
+}
diff --git a/sound/aoa/codecs/snd-aoa-codec-tas-gain-table.h b/sound/aoa/codecs/snd-aoa-codec-tas-gain-table.h
new file mode 100644
index 000000000..4cfa67577
--- /dev/null
+++ b/sound/aoa/codecs/snd-aoa-codec-tas-gain-table.h
@@ -0,0 +1,209 @@
+/*
+ This is the program used to generate below table.
+
+#include <stdio.h>
+#include <math.h>
+int main() {
+  int dB2;
+  printf("/" "* This file is only included exactly once!\n");
+  printf(" *\n");
+  printf(" * If they'd only tell us that generating this table was\n");
+  printf(" * as easy as calculating\n");
+  printf(" *      hwvalue = 1048576.0*exp(0.057564628*dB*2)\n");
+  printf(" * :) *" "/\n");
+  printf("static int tas_gaintable[] = {\n");
+  printf("	0x000000, /" "* -infinity dB *" "/\n");
+  for (dB2=-140;dB2<=36;dB2++)
+    printf("	0x%.6x, /" "* %-02.1f dB *" "/\n", (int)(1048576.0*exp(0.057564628*dB2)), dB2/2.0);
+  printf("};\n\n");
+}
+
+*/
+
+/* This file is only included exactly once!
+ *
+ * If they'd only tell us that generating this table was
+ * as easy as calculating
+ *      hwvalue = 1048576.0*exp(0.057564628*dB*2)
+ * :) */
+static int tas_gaintable[] = {
+	0x000000, /* -infinity dB */
+	0x00014b, /* -70.0 dB */
+	0x00015f, /* -69.5 dB */
+	0x000174, /* -69.0 dB */
+	0x00018a, /* -68.5 dB */
+	0x0001a1, /* -68.0 dB */
+	0x0001ba, /* -67.5 dB */
+	0x0001d4, /* -67.0 dB */
+	0x0001f0, /* -66.5 dB */
+	0x00020d, /* -66.0 dB */
+	0x00022c, /* -65.5 dB */
+	0x00024d, /* -65.0 dB */
+	0x000270, /* -64.5 dB */
+	0x000295, /* -64.0 dB */
+	0x0002bc, /* -63.5 dB */
+	0x0002e6, /* -63.0 dB */
+	0x000312, /* -62.5 dB */
+	0x000340, /* -62.0 dB */
+	0x000372, /* -61.5 dB */
+	0x0003a6, /* -61.0 dB */
+	0x0003dd, /* -60.5 dB */
+	0x000418, /* -60.0 dB */
+	0x000456, /* -59.5 dB */
+	0x000498, /* -59.0 dB */
+	0x0004de, /* -58.5 dB */
+	0x000528, /* -58.0 dB */
+	0x000576, /* -57.5 dB */
+	0x0005c9, /* -57.0 dB */
+	0x000620, /* -56.5 dB */
+	0x00067d, /* -56.0 dB */
+	0x0006e0, /* -55.5 dB */
+	0x000748, /* -55.0 dB */
+	0x0007b7, /* -54.5 dB */
+	0x00082c, /* -54.0 dB */
+	0x0008a8, /* -53.5 dB */
+	0x00092b, /* -53.0 dB */
+	0x0009b6, /* -52.5 dB */
+	0x000a49, /* -52.0 dB */
+	0x000ae5, /* -51.5 dB */
+	0x000b8b, /* -51.0 dB */
+	0x000c3a, /* -50.5 dB */
+	0x000cf3, /* -50.0 dB */
+	0x000db8, /* -49.5 dB */
+	0x000e88, /* -49.0 dB */
+	0x000f64, /* -48.5 dB */
+	0x00104e, /* -48.0 dB */
+	0x001145, /* -47.5 dB */
+	0x00124b, /* -47.0 dB */
+	0x001361, /* -46.5 dB */
+	0x001487, /* -46.0 dB */
+	0x0015be, /* -45.5 dB */
+	0x001708, /* -45.0 dB */
+	0x001865, /* -44.5 dB */
+	0x0019d8, /* -44.0 dB */
+	0x001b60, /* -43.5 dB */
+	0x001cff, /* -43.0 dB */
+	0x001eb7, /* -42.5 dB */
+	0x002089, /* -42.0 dB */
+	0x002276, /* -41.5 dB */
+	0x002481, /* -41.0 dB */
+	0x0026ab, /* -40.5 dB */
+	0x0028f5, /* -40.0 dB */
+	0x002b63, /* -39.5 dB */
+	0x002df5, /* -39.0 dB */
+	0x0030ae, /* -38.5 dB */
+	0x003390, /* -38.0 dB */
+	0x00369e, /* -37.5 dB */
+	0x0039db, /* -37.0 dB */
+	0x003d49, /* -36.5 dB */
+	0x0040ea, /* -36.0 dB */
+	0x0044c3, /* -35.5 dB */
+	0x0048d6, /* -35.0 dB */
+	0x004d27, /* -34.5 dB */
+	0x0051b9, /* -34.0 dB */
+	0x005691, /* -33.5 dB */
+	0x005bb2, /* -33.0 dB */
+	0x006121, /* -32.5 dB */
+	0x0066e3, /* -32.0 dB */
+	0x006cfb, /* -31.5 dB */
+	0x007370, /* -31.0 dB */
+	0x007a48, /* -30.5 dB */
+	0x008186, /* -30.0 dB */
+	0x008933, /* -29.5 dB */
+	0x009154, /* -29.0 dB */
+	0x0099f1, /* -28.5 dB */
+	0x00a310, /* -28.0 dB */
+	0x00acba, /* -27.5 dB */
+	0x00b6f6, /* -27.0 dB */
+	0x00c1cd, /* -26.5 dB */
+	0x00cd49, /* -26.0 dB */
+	0x00d973, /* -25.5 dB */
+	0x00e655, /* -25.0 dB */
+	0x00f3fb, /* -24.5 dB */
+	0x010270, /* -24.0 dB */
+	0x0111c0, /* -23.5 dB */
+	0x0121f9, /* -23.0 dB */
+	0x013328, /* -22.5 dB */
+	0x01455b, /* -22.0 dB */
+	0x0158a2, /* -21.5 dB */
+	0x016d0e, /* -21.0 dB */
+	0x0182af, /* -20.5 dB */
+	0x019999, /* -20.0 dB */
+	0x01b1de, /* -19.5 dB */
+	0x01cb94, /* -19.0 dB */
+	0x01e6cf, /* -18.5 dB */
+	0x0203a7, /* -18.0 dB */
+	0x022235, /* -17.5 dB */
+	0x024293, /* -17.0 dB */
+	0x0264db, /* -16.5 dB */
+	0x02892c, /* -16.0 dB */
+	0x02afa3, /* -15.5 dB */
+	0x02d862, /* -15.0 dB */
+	0x03038a, /* -14.5 dB */
+	0x033142, /* -14.0 dB */
+	0x0361af, /* -13.5 dB */
+	0x0394fa, /* -13.0 dB */
+	0x03cb50, /* -12.5 dB */
+	0x0404de, /* -12.0 dB */
+	0x0441d5, /* -11.5 dB */
+	0x048268, /* -11.0 dB */
+	0x04c6d0, /* -10.5 dB */
+	0x050f44, /* -10.0 dB */
+	0x055c04, /* -9.5 dB */
+	0x05ad50, /* -9.0 dB */
+	0x06036e, /* -8.5 dB */
+	0x065ea5, /* -8.0 dB */
+	0x06bf44, /* -7.5 dB */
+	0x07259d, /* -7.0 dB */
+	0x079207, /* -6.5 dB */
+	0x0804dc, /* -6.0 dB */
+	0x087e80, /* -5.5 dB */
+	0x08ff59, /* -5.0 dB */
+	0x0987d5, /* -4.5 dB */
+	0x0a1866, /* -4.0 dB */
+	0x0ab189, /* -3.5 dB */
+	0x0b53be, /* -3.0 dB */
+	0x0bff91, /* -2.5 dB */
+	0x0cb591, /* -2.0 dB */
+	0x0d765a, /* -1.5 dB */
+	0x0e4290, /* -1.0 dB */
+	0x0f1adf, /* -0.5 dB */
+	0x100000, /* 0.0 dB */
+	0x10f2b4, /* 0.5 dB */
+	0x11f3c9, /* 1.0 dB */
+	0x13041a, /* 1.5 dB */
+	0x14248e, /* 2.0 dB */
+	0x15561a, /* 2.5 dB */
+	0x1699c0, /* 3.0 dB */
+	0x17f094, /* 3.5 dB */
+	0x195bb8, /* 4.0 dB */
+	0x1adc61, /* 4.5 dB */
+	0x1c73d5, /* 5.0 dB */
+	0x1e236d, /* 5.5 dB */
+	0x1fec98, /* 6.0 dB */
+	0x21d0d9, /* 6.5 dB */
+	0x23d1cd, /* 7.0 dB */
+	0x25f125, /* 7.5 dB */
+	0x2830af, /* 8.0 dB */
+	0x2a9254, /* 8.5 dB */
+	0x2d1818, /* 9.0 dB */
+	0x2fc420, /* 9.5 dB */
+	0x3298b0, /* 10.0 dB */
+	0x35982f, /* 10.5 dB */
+	0x38c528, /* 11.0 dB */
+	0x3c224c, /* 11.5 dB */
+	0x3fb278, /* 12.0 dB */
+	0x4378b0, /* 12.5 dB */
+	0x477829, /* 13.0 dB */
+	0x4bb446, /* 13.5 dB */
+	0x5030a1, /* 14.0 dB */
+	0x54f106, /* 14.5 dB */
+	0x59f980, /* 15.0 dB */
+	0x5f4e52, /* 15.5 dB */
+	0x64f403, /* 16.0 dB */
+	0x6aef5e, /* 16.5 dB */
+	0x714575, /* 17.0 dB */
+	0x77fbaa, /* 17.5 dB */
+	0x7f17af, /* 18.0 dB */
+};
+
diff --git a/sound/aoa/codecs/snd-aoa-codec-tas.c b/sound/aoa/codecs/snd-aoa-codec-tas.c
new file mode 100644
index 000000000..16c0b6b0a
--- /dev/null
+++ b/sound/aoa/codecs/snd-aoa-codec-tas.c
@@ -0,0 +1,935 @@
+/*
+ * Apple Onboard Audio driver for tas codec
+ *
+ * Copyright 2006 Johannes Berg <johannes@sipsolutions.net>
+ *
+ * GPL v2, can be found in COPYING.
+ *
+ * Open questions:
+ *  - How to distinguish between 3004 and versions?
+ *
+ * FIXMEs:
+ *  - This codec driver doesn't honour the 'connected'
+ *    property of the aoa_codec struct, hence if
+ *    it is used in machines where not everything is
+ *    connected it will display wrong mixer elements.
+ *  - Driver assumes that the microphone is always
+ *    monaureal and connected to the right channel of
+ *    the input. This should also be a codec-dependent
+ *    flag, maybe the codec should have 3 different
+ *    bits for the three different possibilities how
+ *    it can be hooked up...
+ *    But as long as I don't see any hardware hooked
+ *    up that way...
+ *  - As Apple notes in their code, the tas3004 seems
+ *    to delay the right channel by one sample. You can
+ *    see this when for example recording stereo in
+ *    audacity, or recording the tas output via cable
+ *    on another machine (use a sinus generator or so).
+ *    I tried programming the BiQuads but couldn't
+ *    make the delay work, maybe someone can read the
+ *    datasheet and fix it. The relevant Apple comment
+ *    is in AppleTAS3004Audio.cpp lines 1637 ff. Note
+ *    that their comment describing how they program
+ *    the filters sucks...
+ *
+ * Other things:
+ *  - this should actually register *two* aoa_codec
+ *    structs since it has two inputs. Then it must
+ *    use the prepare callback to forbid running the
+ *    secondary output on a different clock.
+ *    Also, whatever bus knows how to do this must
+ *    provide two soundbus_dev devices and the fabric
+ *    must be able to link them correctly.
+ *
+ *    I don't even know if Apple ever uses the second
+ *    port on the tas3004 though, I don't think their
+ *    i2s controllers can even do it. OTOH, they all
+ *    derive the clocks from common clocks, so it
+ *    might just be possible. The framework allows the
+ *    codec to refine the transfer_info items in the
+ *    usable callback, so we can simply remove the
+ *    rates the second instance is not using when it
+ *    actually is in use.
+ *    Maybe we'll need to make the sound busses have
+ *    a 'clock group id' value so the codec can
+ *    determine if the two outputs can be driven at
+ *    the same time. But that is likely overkill, up
+ *    to the fabric to not link them up incorrectly,
+ *    and up to the hardware designer to not wire
+ *    them up in some weird unusable way.
+ */
+#include <stddef.h>
+#include <linux/i2c.h>
+#include <linux/i2c-dev.h>
+#include <asm/pmac_low_i2c.h>
+#include <asm/prom.h>
+#include <linux/delay.h>
+#include <linux/module.h>
+MODULE_AUTHOR("Johannes Berg <johannes@sipsolutions.net>");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("tas codec driver for snd-aoa");
+
+#include "snd-aoa-codec-tas.h"
+#include "snd-aoa-codec-tas-gain-table.h"
+#include "snd-aoa-codec-tas-basstreble.h"
+#include "../aoa.h"
+#include "../soundbus/soundbus.h"
+
+#define PFX "snd-aoa-codec-tas: "
+
+
+struct tas {
+	struct aoa_codec	codec;
+	struct i2c_client	i2c;
+	u32			mute_l:1, mute_r:1 ,
+				controls_created:1 ,
+				drc_enabled:1,
+				hw_enabled:1;
+	u8			cached_volume_l, cached_volume_r;
+	u8			mixer_l[3], mixer_r[3];
+	u8			bass, treble;
+	u8			acr;
+	int			drc_range;
+};
+
+static int tas_reset_init(struct tas *tas);
+
+static struct tas *codec_to_tas(struct aoa_codec *codec)
+{
+	return container_of(codec, struct tas, codec);
+}
+
+static inline int tas_write_reg(struct tas *tas, u8 reg, u8 len, u8 *data)
+{
+	if (len == 1)
+		return i2c_smbus_write_byte_data(&tas->i2c, reg, *data);
+	else
+		return i2c_smbus_write_i2c_block_data(&tas->i2c, reg, len, data);
+}
+
+static void tas3004_set_drc(struct tas *tas)
+{
+	unsigned char val[6];
+
+	if (tas->drc_enabled)
+		val[0] = 0x50; /* 3:1 above threshold */
+	else
+		val[0] = 0x51; /* disabled */
+	val[1] = 0x02; /* 1:1 below threshold */
+	if (tas->drc_range > 0xef)
+		val[2] = 0xef;
+	else if (tas->drc_range < 0)
+		val[2] = 0x00;
+	else
+		val[2] = tas->drc_range;
+	val[3] = 0xb0;
+	val[4] = 0x60;
+	val[5] = 0xa0;
+
+	tas_write_reg(tas, TAS_REG_DRC, 6, val);
+}
+
+static void tas_set_treble(struct tas *tas)
+{
+	u8 tmp;
+
+	tmp = tas3004_treble(tas->treble);
+	tas_write_reg(tas, TAS_REG_TREBLE, 1, &tmp);
+}
+
+static void tas_set_bass(struct tas *tas)
+{
+	u8 tmp;
+
+	tmp = tas3004_bass(tas->bass);
+	tas_write_reg(tas, TAS_REG_BASS, 1, &tmp);
+}
+
+static void tas_set_volume(struct tas *tas)
+{
+	u8 block[6];
+	int tmp;
+	u8 left, right;
+
+	left = tas->cached_volume_l;
+	right = tas->cached_volume_r;
+
+	if (left > 177) left = 177;
+	if (right > 177) right = 177;
+
+	if (tas->mute_l) left = 0;
+	if (tas->mute_r) right = 0;
+
+	/* analysing the volume and mixer tables shows
+	 * that they are similar enough when we shift
+	 * the mixer table down by 4 bits. The error
+	 * is miniscule, in just one item the error
+	 * is 1, at a value of 0x07f17b (mixer table
+	 * value is 0x07f17a) */
+	tmp = tas_gaintable[left];
+	block[0] = tmp>>20;
+	block[1] = tmp>>12;
+	block[2] = tmp>>4;
+	tmp = tas_gaintable[right];
+	block[3] = tmp>>20;
+	block[4] = tmp>>12;
+	block[5] = tmp>>4;
+	tas_write_reg(tas, TAS_REG_VOL, 6, block);
+}
+
+static void tas_set_mixer(struct tas *tas)
+{
+	u8 block[9];
+	int tmp, i;
+	u8 val;
+
+	for (i=0;i<3;i++) {
+		val = tas->mixer_l[i];
+		if (val > 177) val = 177;
+		tmp = tas_gaintable[val];
+		block[3*i+0] = tmp>>16;
+		block[3*i+1] = tmp>>8;
+		block[3*i+2] = tmp;
+	}
+	tas_write_reg(tas, TAS_REG_LMIX, 9, block);
+
+	for (i=0;i<3;i++) {
+		val = tas->mixer_r[i];
+		if (val > 177) val = 177;
+		tmp = tas_gaintable[val];
+		block[3*i+0] = tmp>>16;
+		block[3*i+1] = tmp>>8;
+		block[3*i+2] = tmp;
+	}
+	tas_write_reg(tas, TAS_REG_RMIX, 9, block);
+}
+
+/* alsa stuff */
+
+static int tas_dev_register(struct snd_device *dev)
+{
+	return 0;
+}
+
+static struct snd_device_ops ops = {
+	.dev_register = tas_dev_register,
+};
+
+static int tas_snd_vol_info(struct snd_kcontrol *kcontrol,
+	struct snd_ctl_elem_info *uinfo)
+{
+	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
+	uinfo->count = 2;
+	uinfo->value.integer.min = 0;
+	uinfo->value.integer.max = 177;
+	return 0;
+}
+
+static int tas_snd_vol_get(struct snd_kcontrol *kcontrol,
+	struct snd_ctl_elem_value *ucontrol)
+{
+	struct tas *tas = snd_kcontrol_chip(kcontrol);
+
+	ucontrol->value.integer.value[0] = tas->cached_volume_l;
+	ucontrol->value.integer.value[1] = tas->cached_volume_r;
+	return 0;
+}
+
+static int tas_snd_vol_put(struct snd_kcontrol *kcontrol,
+	struct snd_ctl_elem_value *ucontrol)
+{
+	struct tas *tas = snd_kcontrol_chip(kcontrol);
+
+	if (tas->cached_volume_l == ucontrol->value.integer.value[0]
+	 && tas->cached_volume_r == ucontrol->value.integer.value[1])
+		return 0;
+
+	tas->cached_volume_l = ucontrol->value.integer.value[0];
+	tas->cached_volume_r = ucontrol->value.integer.value[1];
+	if (tas->hw_enabled)
+		tas_set_volume(tas);
+	return 1;
+}
+
+static struct snd_kcontrol_new volume_control = {
+	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+	.name = "Master Playback Volume",
+	.access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
+	.info = tas_snd_vol_info,
+	.get = tas_snd_vol_get,
+	.put = tas_snd_vol_put,
+};
+
+static int tas_snd_mute_info(struct snd_kcontrol *kcontrol,
+	struct snd_ctl_elem_info *uinfo)
+{
+	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
+	uinfo->count = 2;
+	uinfo->value.integer.min = 0;
+	uinfo->value.integer.max = 1;
+	return 0;
+}
+
+static int tas_snd_mute_get(struct snd_kcontrol *kcontrol,
+	struct snd_ctl_elem_value *ucontrol)
+{
+	struct tas *tas = snd_kcontrol_chip(kcontrol);
+
+	ucontrol->value.integer.value[0] = !tas->mute_l;
+	ucontrol->value.integer.value[1] = !tas->mute_r;
+	return 0;
+}
+
+static int tas_snd_mute_put(struct snd_kcontrol *kcontrol,
+	struct snd_ctl_elem_value *ucontrol)
+{
+	struct tas *tas = snd_kcontrol_chip(kcontrol);
+
+	if (tas->mute_l == !ucontrol->value.integer.value[0]
+	 && tas->mute_r == !ucontrol->value.integer.value[1])
+		return 0;
+
+	tas->mute_l = !ucontrol->value.integer.value[0];
+	tas->mute_r = !ucontrol->value.integer.value[1];
+	if (tas->hw_enabled)
+		tas_set_volume(tas);
+	return 1;
+}
+
+static struct snd_kcontrol_new mute_control = {
+	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+	.name = "Master Playback Switch",
+	.access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
+	.info = tas_snd_mute_info,
+	.get = tas_snd_mute_get,
+	.put = tas_snd_mute_put,
+};
+
+static int tas_snd_mixer_info(struct snd_kcontrol *kcontrol,
+	struct snd_ctl_elem_info *uinfo)
+{
+	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
+	uinfo->count = 2;
+	uinfo->value.integer.min = 0;
+	uinfo->value.integer.max = 177;
+	return 0;
+}
+
+static int tas_snd_mixer_get(struct snd_kcontrol *kcontrol,
+	struct snd_ctl_elem_value *ucontrol)
+{
+	struct tas *tas = snd_kcontrol_chip(kcontrol);
+	int idx = kcontrol->private_value;
+
+	ucontrol->value.integer.value[0] = tas->mixer_l[idx];
+	ucontrol->value.integer.value[1] = tas->mixer_r[idx];
+
+	return 0;
+}
+
+static int tas_snd_mixer_put(struct snd_kcontrol *kcontrol,
+	struct snd_ctl_elem_value *ucontrol)
+{
+	struct tas *tas = snd_kcontrol_chip(kcontrol);
+	int idx = kcontrol->private_value;
+
+	if (tas->mixer_l[idx] == ucontrol->value.integer.value[0]
+	 && tas->mixer_r[idx] == ucontrol->value.integer.value[1])
+		return 0;
+
+	tas->mixer_l[idx] = ucontrol->value.integer.value[0];
+	tas->mixer_r[idx] = ucontrol->value.integer.value[1];
+
+	if (tas->hw_enabled)
+		tas_set_mixer(tas);
+	return 1;
+}
+
+#define MIXER_CONTROL(n,descr,idx)			\
+static struct snd_kcontrol_new n##_control = {		\
+	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,		\
+	.name = descr " Playback Volume",		\
+	.access = SNDRV_CTL_ELEM_ACCESS_READWRITE,	\
+	.info = tas_snd_mixer_info,			\
+	.get = tas_snd_mixer_get,			\
+	.put = tas_snd_mixer_put,			\
+	.private_value = idx,				\
+}
+
+MIXER_CONTROL(pcm1, "PCM", 0);
+MIXER_CONTROL(monitor, "Monitor", 2);
+
+static int tas_snd_drc_range_info(struct snd_kcontrol *kcontrol,
+	struct snd_ctl_elem_info *uinfo)
+{
+	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
+	uinfo->count = 1;
+	uinfo->value.integer.min = 0;
+	uinfo->value.integer.max = TAS3004_DRC_MAX;
+	return 0;
+}
+
+static int tas_snd_drc_range_get(struct snd_kcontrol *kcontrol,
+	struct snd_ctl_elem_value *ucontrol)
+{
+	struct tas *tas = snd_kcontrol_chip(kcontrol);
+
+	ucontrol->value.integer.value[0] = tas->drc_range;
+	return 0;
+}
+
+static int tas_snd_drc_range_put(struct snd_kcontrol *kcontrol,
+	struct snd_ctl_elem_value *ucontrol)
+{
+	struct tas *tas = snd_kcontrol_chip(kcontrol);
+
+	if (tas->drc_range == ucontrol->value.integer.value[0])
+		return 0;
+
+	tas->drc_range = ucontrol->value.integer.value[0];
+	if (tas->hw_enabled)
+		tas3004_set_drc(tas);
+	return 1;
+}
+
+static struct snd_kcontrol_new drc_range_control = {
+	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+	.name = "DRC Range",
+	.access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
+	.info = tas_snd_drc_range_info,
+	.get = tas_snd_drc_range_get,
+	.put = tas_snd_drc_range_put,
+};
+
+static int tas_snd_drc_switch_info(struct snd_kcontrol *kcontrol,
+	struct snd_ctl_elem_info *uinfo)
+{
+	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
+	uinfo->count = 1;
+	uinfo->value.integer.min = 0;
+	uinfo->value.integer.max = 1;
+	return 0;
+}
+
+static int tas_snd_drc_switch_get(struct snd_kcontrol *kcontrol,
+	struct snd_ctl_elem_value *ucontrol)
+{
+	struct tas *tas = snd_kcontrol_chip(kcontrol);
+
+	ucontrol->value.integer.value[0] = tas->drc_enabled;
+	return 0;
+}
+
+static int tas_snd_drc_switch_put(struct snd_kcontrol *kcontrol,
+	struct snd_ctl_elem_value *ucontrol)
+{
+	struct tas *tas = snd_kcontrol_chip(kcontrol);
+
+	if (tas->drc_enabled == ucontrol->value.integer.value[0])
+		return 0;
+
+	tas->drc_enabled = ucontrol->value.integer.value[0];
+	if (tas->hw_enabled)
+		tas3004_set_drc(tas);
+	return 1;
+}
+
+static struct snd_kcontrol_new drc_switch_control = {
+	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+	.name = "DRC Range Switch",
+	.access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
+	.info = tas_snd_drc_switch_info,
+	.get = tas_snd_drc_switch_get,
+	.put = tas_snd_drc_switch_put,
+};
+
+static int tas_snd_capture_source_info(struct snd_kcontrol *kcontrol,
+	struct snd_ctl_elem_info *uinfo)
+{
+	static char *texts[] = { "Line-In", "Microphone" };
+
+	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
+	uinfo->count = 1;
+	uinfo->value.enumerated.items = 2;
+	if (uinfo->value.enumerated.item > 1)
+		uinfo->value.enumerated.item = 1;
+	strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
+	return 0;
+}
+
+static int tas_snd_capture_source_get(struct snd_kcontrol *kcontrol,
+	struct snd_ctl_elem_value *ucontrol)
+{
+	struct tas *tas = snd_kcontrol_chip(kcontrol);
+
+	ucontrol->value.enumerated.item[0] = !!(tas->acr & TAS_ACR_INPUT_B);
+	return 0;
+}
+
+static int tas_snd_capture_source_put(struct snd_kcontrol *kcontrol,
+	struct snd_ctl_elem_value *ucontrol)
+{
+	struct tas *tas = snd_kcontrol_chip(kcontrol);
+	int oldacr = tas->acr;
+
+	tas->acr &= ~TAS_ACR_INPUT_B;
+	if (ucontrol->value.enumerated.item[0])
+		tas->acr |= TAS_ACR_INPUT_B;
+	if (oldacr == tas->acr)
+		return 0;
+	if (tas->hw_enabled)
+		tas_write_reg(tas, TAS_REG_ACR, 1, &tas->acr);
+	return 1;
+}
+
+static struct snd_kcontrol_new capture_source_control = {
+	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+	/* If we name this 'Input Source', it properly shows up in
+	 * alsamixer as a selection, * but it's shown under the
+	 * 'Playback' category.
+	 * If I name it 'Capture Source', it shows up in strange
+	 * ways (two bools of which one can be selected at a
+	 * time) but at least it's shown in the 'Capture'
+	 * category.
+	 * I was told that this was due to backward compatibility,
+	 * but I don't understand then why the mangling is *not*
+	 * done when I name it "Input Source".....
+	 */
+	.name = "Capture Source",
+	.access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
+	.info = tas_snd_capture_source_info,
+	.get = tas_snd_capture_source_get,
+	.put = tas_snd_capture_source_put,
+};
+
+static int tas_snd_treble_info(struct snd_kcontrol *kcontrol,
+	struct snd_ctl_elem_info *uinfo)
+{
+	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
+	uinfo->count = 1;
+	uinfo->value.integer.min = TAS3004_TREBLE_MIN;
+	uinfo->value.integer.max = TAS3004_TREBLE_MAX;
+	return 0;
+}
+
+static int tas_snd_treble_get(struct snd_kcontrol *kcontrol,
+	struct snd_ctl_elem_value *ucontrol)
+{
+	struct tas *tas = snd_kcontrol_chip(kcontrol);
+
+	ucontrol->value.integer.value[0] = tas->treble;
+	return 0;
+}
+
+static int tas_snd_treble_put(struct snd_kcontrol *kcontrol,
+	struct snd_ctl_elem_value *ucontrol)
+{
+	struct tas *tas = snd_kcontrol_chip(kcontrol);
+
+	if (tas->treble == ucontrol->value.integer.value[0])
+		return 0;
+
+	tas->treble = ucontrol->value.integer.value[0];
+	if (tas->hw_enabled)
+		tas_set_treble(tas);
+	return 1;
+}
+
+static struct snd_kcontrol_new treble_control = {
+	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+	.name = "Treble",
+	.access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
+	.info = tas_snd_treble_info,
+	.get = tas_snd_treble_get,
+	.put = tas_snd_treble_put,
+};
+
+static int tas_snd_bass_info(struct snd_kcontrol *kcontrol,
+	struct snd_ctl_elem_info *uinfo)
+{
+	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
+	uinfo->count = 1;
+	uinfo->value.integer.min = TAS3004_BASS_MIN;
+	uinfo->value.integer.max = TAS3004_BASS_MAX;
+	return 0;
+}
+
+static int tas_snd_bass_get(struct snd_kcontrol *kcontrol,
+	struct snd_ctl_elem_value *ucontrol)
+{
+	struct tas *tas = snd_kcontrol_chip(kcontrol);
+
+	ucontrol->value.integer.value[0] = tas->bass;
+	return 0;
+}
+
+static int tas_snd_bass_put(struct snd_kcontrol *kcontrol,
+	struct snd_ctl_elem_value *ucontrol)
+{
+	struct tas *tas = snd_kcontrol_chip(kcontrol);
+
+	if (tas->bass == ucontrol->value.integer.value[0])
+		return 0;
+
+	tas->bass = ucontrol->value.integer.value[0];
+	if (tas->hw_enabled)
+		tas_set_bass(tas);
+	return 1;
+}
+
+static struct snd_kcontrol_new bass_control = {
+	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+	.name = "Bass",
+	.access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
+	.info = tas_snd_bass_info,
+	.get = tas_snd_bass_get,
+	.put = tas_snd_bass_put,
+};
+
+static struct transfer_info tas_transfers[] = {
+	{
+		/* input */
+		.formats = SNDRV_PCM_FMTBIT_S16_BE | SNDRV_PCM_FMTBIT_S16_BE |
+			   SNDRV_PCM_FMTBIT_S24_BE | SNDRV_PCM_FMTBIT_S24_BE,
+		.rates = SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000,
+		.transfer_in = 1,
+	},
+	{
+		/* output */
+		.formats = SNDRV_PCM_FMTBIT_S16_BE | SNDRV_PCM_FMTBIT_S16_BE |
+			   SNDRV_PCM_FMTBIT_S24_BE | SNDRV_PCM_FMTBIT_S24_BE,
+		.rates = SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000,
+		.transfer_in = 0,
+	},
+	{}
+};
+
+static int tas_usable(struct codec_info_item *cii,
+		      struct transfer_info *ti,
+		      struct transfer_info *out)
+{
+	return 1;
+}
+
+static int tas_reset_init(struct tas *tas)
+{
+	u8 tmp;
+
+	tas->codec.gpio->methods->all_amps_off(tas->codec.gpio);
+	msleep(5);
+	tas->codec.gpio->methods->set_hw_reset(tas->codec.gpio, 0);
+	msleep(5);
+	tas->codec.gpio->methods->set_hw_reset(tas->codec.gpio, 1);
+	msleep(20);
+	tas->codec.gpio->methods->set_hw_reset(tas->codec.gpio, 0);
+	msleep(10);
+	tas->codec.gpio->methods->all_amps_restore(tas->codec.gpio);
+
+	tmp = TAS_MCS_SCLK64 | TAS_MCS_SPORT_MODE_I2S | TAS_MCS_SPORT_WL_24BIT;
+	if (tas_write_reg(tas, TAS_REG_MCS, 1, &tmp))
+		return -ENODEV;
+
+	tas->acr |= TAS_ACR_ANALOG_PDOWN | TAS_ACR_B_MONAUREAL |
+		TAS_ACR_B_MON_SEL_RIGHT;
+	if (tas_write_reg(tas, TAS_REG_ACR, 1, &tas->acr))
+		return -ENODEV;
+
+	tmp = 0;
+	if (tas_write_reg(tas, TAS_REG_MCS2, 1, &tmp))
+		return -ENODEV;
+
+	tas3004_set_drc(tas);
+
+	/* Set treble & bass to 0dB */
+	tas->treble = TAS3004_TREBLE_ZERO;
+	tas->bass = TAS3004_BASS_ZERO;
+	tas_set_treble(tas);
+	tas_set_bass(tas);
+
+	tas->acr &= ~TAS_ACR_ANALOG_PDOWN;
+	if (tas_write_reg(tas, TAS_REG_ACR, 1, &tas->acr))
+		return -ENODEV;
+
+	return 0;
+}
+
+static int tas_switch_clock(struct codec_info_item *cii, enum clock_switch clock)
+{
+	struct tas *tas = cii->codec_data;
+
+	switch(clock) {
+	case CLOCK_SWITCH_PREPARE_SLAVE:
+		/* Clocks are going away, mute mute mute */
+		tas->codec.gpio->methods->all_amps_off(tas->codec.gpio);
+		tas->hw_enabled = 0;
+		break;
+	case CLOCK_SWITCH_SLAVE:
+		/* Clocks are back, re-init the codec */
+		tas_reset_init(tas);
+		tas_set_volume(tas);
+		tas_set_mixer(tas);
+		tas->hw_enabled = 1;
+		tas->codec.gpio->methods->all_amps_restore(tas->codec.gpio);
+		break;
+	default:
+		/* doesn't happen as of now */
+		return -EINVAL;
+	}
+	return 0;
+}
+
+/* we are controlled via i2c and assume that is always up
+ * If that wasn't the case, we'd have to suspend once
+ * our i2c device is suspended, and then take note of that! */
+static int tas_suspend(struct tas *tas)
+{
+	tas->hw_enabled = 0;
+	tas->acr |= TAS_ACR_ANALOG_PDOWN;
+	tas_write_reg(tas, TAS_REG_ACR, 1, &tas->acr);
+	return 0;
+}
+
+static int tas_resume(struct tas *tas)
+{
+	/* reset codec */
+	tas_reset_init(tas);
+	tas_set_volume(tas);
+	tas_set_mixer(tas);
+	tas->hw_enabled = 1;
+	return 0;
+}
+
+#ifdef CONFIG_PM
+static int _tas_suspend(struct codec_info_item *cii, pm_message_t state)
+{
+	return tas_suspend(cii->codec_data);
+}
+
+static int _tas_resume(struct codec_info_item *cii)
+{
+	return tas_resume(cii->codec_data);
+}
+#endif
+
+static struct codec_info tas_codec_info = {
+	.transfers = tas_transfers,
+	/* in theory, we can drive it at 512 too...
+	 * but so far the framework doesn't allow
+	 * for that and I don't see much point in it. */
+	.sysclock_factor = 256,
+	/* same here, could be 32 for just one 16 bit format */
+	.bus_factor = 64,
+	.owner = THIS_MODULE,
+	.usable = tas_usable,
+	.switch_clock = tas_switch_clock,
+#ifdef CONFIG_PM
+	.suspend = _tas_suspend,
+	.resume = _tas_resume,
+#endif
+};
+
+static int tas_init_codec(struct aoa_codec *codec)
+{
+	struct tas *tas = codec_to_tas(codec);
+	int err;
+
+	if (!tas->codec.gpio || !tas->codec.gpio->methods) {
+		printk(KERN_ERR PFX "gpios not assigned!!\n");
+		return -EINVAL;
+	}
+
+	if (tas_reset_init(tas)) {
+		printk(KERN_ERR PFX "tas failed to initialise\n");
+		return -ENXIO;
+	}
+	tas->hw_enabled = 1;
+
+	if (tas->codec.soundbus_dev->attach_codec(tas->codec.soundbus_dev,
+						   aoa_get_card(),
+						   &tas_codec_info, tas)) {
+		printk(KERN_ERR PFX "error attaching tas to soundbus\n");
+		return -ENODEV;
+	}
+
+	if (aoa_snd_device_new(SNDRV_DEV_LOWLEVEL, tas, &ops)) {
+		printk(KERN_ERR PFX "failed to create tas snd device!\n");
+		return -ENODEV;
+	}
+	err = aoa_snd_ctl_add(snd_ctl_new1(&volume_control, tas));
+	if (err)
+		goto error;
+
+	err = aoa_snd_ctl_add(snd_ctl_new1(&mute_control, tas));
+	if (err)
+		goto error;
+
+	err = aoa_snd_ctl_add(snd_ctl_new1(&pcm1_control, tas));
+	if (err)
+		goto error;
+
+	err = aoa_snd_ctl_add(snd_ctl_new1(&monitor_control, tas));
+	if (err)
+		goto error;
+
+	err = aoa_snd_ctl_add(snd_ctl_new1(&capture_source_control, tas));
+	if (err)
+		goto error;
+
+	err = aoa_snd_ctl_add(snd_ctl_new1(&drc_range_control, tas));
+	if (err)
+		goto error;
+
+	err = aoa_snd_ctl_add(snd_ctl_new1(&drc_switch_control, tas));
+	if (err)
+		goto error;
+
+	err = aoa_snd_ctl_add(snd_ctl_new1(&treble_control, tas));
+	if (err)
+		goto error;
+
+	err = aoa_snd_ctl_add(snd_ctl_new1(&bass_control, tas));
+	if (err)
+		goto error;
+
+	return 0;
+ error:
+	tas->codec.soundbus_dev->detach_codec(tas->codec.soundbus_dev, tas);
+	snd_device_free(aoa_get_card(), tas);
+	return err;
+}
+
+static void tas_exit_codec(struct aoa_codec *codec)
+{
+	struct tas *tas = codec_to_tas(codec);
+
+	if (!tas->codec.soundbus_dev)
+		return;
+	tas->codec.soundbus_dev->detach_codec(tas->codec.soundbus_dev, tas);
+}
+	
+
+static struct i2c_driver tas_driver;
+
+static int tas_create(struct i2c_adapter *adapter,
+		       struct device_node *node,
+		       int addr)
+{
+	struct tas *tas;
+
+	tas = kzalloc(sizeof(struct tas), GFP_KERNEL);
+
+	if (!tas)
+		return -ENOMEM;
+
+	tas->i2c.driver = &tas_driver;
+	tas->i2c.adapter = adapter;
+	tas->i2c.addr = addr;
+	/* seems that half is a saner default */
+	tas->drc_range = TAS3004_DRC_MAX / 2;
+	strlcpy(tas->i2c.name, "tas audio codec", I2C_NAME_SIZE-1);
+
+	if (i2c_attach_client(&tas->i2c)) {
+		printk(KERN_ERR PFX "failed to attach to i2c\n");
+		goto fail;
+	}
+
+	strlcpy(tas->codec.name, "tas", MAX_CODEC_NAME_LEN-1);
+	tas->codec.owner = THIS_MODULE;
+	tas->codec.init = tas_init_codec;
+	tas->codec.exit = tas_exit_codec;
+	tas->codec.node = of_node_get(node);
+
+	if (aoa_codec_register(&tas->codec)) {
+		goto detach;
+	}
+	printk(KERN_DEBUG
+	       "snd-aoa-codec-tas: tas found, addr 0x%02x on %s\n",
+	       addr, node->full_name);
+	return 0;
+ detach:
+	i2c_detach_client(&tas->i2c);
+ fail:
+	kfree(tas);
+	return -EINVAL;
+}
+
+static int tas_i2c_attach(struct i2c_adapter *adapter)
+{
+	struct device_node *busnode, *dev = NULL;
+	struct pmac_i2c_bus *bus;
+
+	bus = pmac_i2c_adapter_to_bus(adapter);
+	if (bus == NULL)
+		return -ENODEV;
+	busnode = pmac_i2c_get_bus_node(bus);
+
+	while ((dev = of_get_next_child(busnode, dev)) != NULL) {
+		if (device_is_compatible(dev, "tas3004")) {
+			u32 *addr;
+			printk(KERN_DEBUG PFX "found tas3004\n");
+			addr = (u32 *) get_property(dev, "reg", NULL);
+			if (!addr)
+				continue;
+			return tas_create(adapter, dev, ((*addr) >> 1) & 0x7f);
+		}
+		/* older machines have no 'codec' node with a 'compatible'
+		 * property that says 'tas3004', they just have a 'deq'
+		 * node without any such property... */
+		if (strcmp(dev->name, "deq") == 0) {
+			u32 *_addr, addr;
+			printk(KERN_DEBUG PFX "found 'deq' node\n");
+			_addr = (u32 *) get_property(dev, "i2c-address", NULL);
+			if (!_addr)
+				continue;
+			addr = ((*_addr) >> 1) & 0x7f;
+			/* now, if the address doesn't match any of the two
+			 * that a tas3004 can have, we cannot handle this.
+			 * I doubt it ever happens but hey. */
+			if (addr != 0x34 && addr != 0x35)
+				continue;
+			return tas_create(adapter, dev, addr);
+		}
+	}
+	return -ENODEV;
+}
+
+static int tas_i2c_detach(struct i2c_client *client)
+{
+	struct tas *tas = container_of(client, struct tas, i2c);
+	int err;
+	u8 tmp = TAS_ACR_ANALOG_PDOWN;
+
+	if ((err = i2c_detach_client(client)))
+		return err;
+	aoa_codec_unregister(&tas->codec);
+	of_node_put(tas->codec.node);
+
+	/* power down codec chip */
+	tas_write_reg(tas, TAS_REG_ACR, 1, &tmp);
+
+	kfree(tas);
+	return 0;
+}
+
+static struct i2c_driver tas_driver = {
+	.driver = {
+		.name = "aoa_codec_tas",
+		.owner = THIS_MODULE,
+	},
+	.attach_adapter = tas_i2c_attach,
+	.detach_client = tas_i2c_detach,
+};
+
+static int __init tas_init(void)
+{
+	return i2c_add_driver(&tas_driver);
+}
+
+static void __exit tas_exit(void)
+{
+	i2c_del_driver(&tas_driver);
+}
+
+module_init(tas_init);
+module_exit(tas_exit);
diff --git a/sound/aoa/codecs/snd-aoa-codec-tas.h b/sound/aoa/codecs/snd-aoa-codec-tas.h
new file mode 100644
index 000000000..ae177e346
--- /dev/null
+++ b/sound/aoa/codecs/snd-aoa-codec-tas.h
@@ -0,0 +1,55 @@
+/*
+ * Apple Onboard Audio driver for tas codec (header)
+ *
+ * Copyright 2006 Johannes Berg <johannes@sipsolutions.net>
+ *
+ * GPL v2, can be found in COPYING.
+ */
+#ifndef __SND_AOA_CODECTASH
+#define __SND_AOA_CODECTASH
+
+#define TAS_REG_MCS	0x01	/* main control */
+#	define TAS_MCS_FASTLOAD		(1<<7)
+#	define TAS_MCS_SCLK64		(1<<6)
+#	define TAS_MCS_SPORT_MODE_MASK	(3<<4)
+#	define TAS_MCS_SPORT_MODE_I2S	(2<<4)
+#	define TAS_MCS_SPORT_MODE_RJ	(1<<4)
+#	define TAS_MCS_SPORT_MODE_LJ	(0<<4)
+#	define TAS_MCS_SPORT_WL_MASK	(3<<0)
+#	define TAS_MCS_SPORT_WL_16BIT	(0<<0)
+#	define TAS_MCS_SPORT_WL_18BIT	(1<<0)
+#	define TAS_MCS_SPORT_WL_20BIT	(2<<0)
+#	define TAS_MCS_SPORT_WL_24BIT	(3<<0)
+
+#define TAS_REG_DRC	0x02
+#define TAS_REG_VOL	0x04
+#define TAS_REG_TREBLE	0x05
+#define TAS_REG_BASS	0x06
+#define TAS_REG_LMIX	0x07
+#define TAS_REG_RMIX	0x08
+
+#define TAS_REG_ACR	0x40	/* analog control */
+#	define TAS_ACR_B_MONAUREAL	(1<<7)
+#	define TAS_ACR_B_MON_SEL_RIGHT	(1<<6)
+#	define TAS_ACR_DEEMPH_MASK	(3<<2)
+#	define TAS_ACR_DEEMPH_OFF	(0<<2)
+#	define TAS_ACR_DEEMPH_48KHz	(1<<2)
+#	define TAS_ACR_DEEMPH_44KHz	(2<<2)
+#	define TAS_ACR_INPUT_B		(1<<1)
+#	define TAS_ACR_ANALOG_PDOWN	(1<<0)
+
+#define TAS_REG_MCS2	0x43	/* main control 2 */
+#	define TAS_MCS2_ALLPASS		(1<<1)
+
+#define TAS_REG_LEFT_BIQUAD6	0x10
+#define TAS_REG_RIGHT_BIQUAD6	0x19
+
+#define TAS_REG_LEFT_LOUDNESS		0x21
+#define TAS_REG_RIGHT_LOUDNESS		0x22
+#define TAS_REG_LEFT_LOUDNESS_GAIN	0x23
+#define TAS_REG_RIGHT_LOUDNESS_GAIN	0x24
+
+#define TAS3001_DRC_MAX		0x5f
+#define TAS3004_DRC_MAX		0xef
+
+#endif /* __SND_AOA_CODECTASH */
diff --git a/sound/aoa/codecs/snd-aoa-codec-toonie.c b/sound/aoa/codecs/snd-aoa-codec-toonie.c
new file mode 100644
index 000000000..3c7d1d8a9
--- /dev/null
+++ b/sound/aoa/codecs/snd-aoa-codec-toonie.c
@@ -0,0 +1,150 @@
+/*
+ * Apple Onboard Audio driver for Toonie codec
+ *
+ * Copyright 2006 Johannes Berg <johannes@sipsolutions.net>
+ *
+ * GPL v2, can be found in COPYING.
+ *
+ *
+ * This is a driver for the toonie codec chip. This chip is present
+ * on the Mac Mini and is nothing but a DAC.
+ */
+#include <linux/delay.h>
+#include <linux/module.h>
+MODULE_AUTHOR("Johannes Berg <johannes@sipsolutions.net>");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("toonie codec driver for snd-aoa");
+
+#include "../aoa.h"
+#include "../soundbus/soundbus.h"
+
+
+#define PFX "snd-aoa-codec-toonie: "
+
+struct toonie {
+	struct aoa_codec	codec;
+};
+#define codec_to_toonie(c) container_of(c, struct toonie, codec)
+
+static int toonie_dev_register(struct snd_device *dev)
+{
+	return 0;
+}
+
+static struct snd_device_ops ops = {
+	.dev_register = toonie_dev_register,
+};
+
+static struct transfer_info toonie_transfers[] = {
+	/* This thing *only* has analog output,
+	 * the rates are taken from Info.plist
+	 * from Darwin. */
+	{
+		.formats = SNDRV_PCM_FMTBIT_S16_BE |
+			   SNDRV_PCM_FMTBIT_S24_BE,
+		.rates = SNDRV_PCM_RATE_32000 |
+			 SNDRV_PCM_RATE_44100 |
+			 SNDRV_PCM_RATE_48000 |
+			 SNDRV_PCM_RATE_88200 |
+			 SNDRV_PCM_RATE_96000,
+	},
+	{}
+};
+
+static int toonie_usable(struct codec_info_item *cii,
+			 struct transfer_info *ti,
+			 struct transfer_info *out)
+{
+	return 1;
+}
+
+#ifdef CONFIG_PM
+static int toonie_suspend(struct codec_info_item *cii, pm_message_t state)
+{
+	/* can we turn it off somehow? */
+	return 0;
+}
+
+static int toonie_resume(struct codec_info_item *cii)
+{
+	return 0;
+}
+#endif /* CONFIG_PM */
+
+static struct codec_info toonie_codec_info = {
+	.transfers = toonie_transfers,
+	.sysclock_factor = 256,
+	.bus_factor = 64,
+	.owner = THIS_MODULE,
+	.usable = toonie_usable,
+#ifdef CONFIG_PM
+	.suspend = toonie_suspend,
+	.resume = toonie_resume,
+#endif
+};
+
+static int toonie_init_codec(struct aoa_codec *codec)
+{
+	struct toonie *toonie = codec_to_toonie(codec);
+
+	/* nothing connected? what a joke! */
+	if (toonie->codec.connected != 1)
+		return -ENOTCONN;
+
+	if (aoa_snd_device_new(SNDRV_DEV_LOWLEVEL, toonie, &ops)) {
+		printk(KERN_ERR PFX "failed to create toonie snd device!\n");
+		return -ENODEV;
+	}
+
+	if (toonie->codec.soundbus_dev->attach_codec(toonie->codec.soundbus_dev,
+						     aoa_get_card(),
+						     &toonie_codec_info, toonie)) {
+		printk(KERN_ERR PFX "error creating toonie pcm\n");
+		snd_device_free(aoa_get_card(), toonie);
+		return -ENODEV;
+	}
+
+	return 0;
+}
+
+static void toonie_exit_codec(struct aoa_codec *codec)
+{
+	struct toonie *toonie = codec_to_toonie(codec);
+
+	if (!toonie->codec.soundbus_dev) {
+		printk(KERN_ERR PFX "toonie_exit_codec called without soundbus_dev!\n");
+		return;
+	}
+	toonie->codec.soundbus_dev->detach_codec(toonie->codec.soundbus_dev, toonie);
+}
+
+static struct toonie *toonie;
+
+static int __init toonie_init(void)
+{
+	toonie = kzalloc(sizeof(struct toonie), GFP_KERNEL);
+
+	if (!toonie)
+		return -ENOMEM;
+
+	strlcpy(toonie->codec.name, "toonie", sizeof(toonie->codec.name));
+	toonie->codec.owner = THIS_MODULE;
+	toonie->codec.init = toonie_init_codec;
+	toonie->codec.exit = toonie_exit_codec;
+                                        
+	if (aoa_codec_register(&toonie->codec)) {
+		kfree(toonie);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static void __exit toonie_exit(void)
+{
+	aoa_codec_unregister(&toonie->codec);
+	kfree(toonie);
+}
+
+module_init(toonie_init);
+module_exit(toonie_exit);
diff --git a/sound/aoa/core/Makefile b/sound/aoa/core/Makefile
new file mode 100644
index 000000000..62dc7287f
--- /dev/null
+++ b/sound/aoa/core/Makefile
@@ -0,0 +1,5 @@
+obj-$(CONFIG_SND_AOA) += snd-aoa.o
+snd-aoa-objs := snd-aoa-core.o \
+		snd-aoa-alsa.o \
+		snd-aoa-gpio-pmf.o \
+		snd-aoa-gpio-feature.o
diff --git a/sound/aoa/core/snd-aoa-alsa.c b/sound/aoa/core/snd-aoa-alsa.c
new file mode 100644
index 000000000..b42fdea77
--- /dev/null
+++ b/sound/aoa/core/snd-aoa-alsa.c
@@ -0,0 +1,98 @@
+/*
+ * Apple Onboard Audio Alsa helpers
+ *
+ * Copyright 2006 Johannes Berg <johannes@sipsolutions.net>
+ *
+ * GPL v2, can be found in COPYING.
+ */
+#include <linux/module.h>
+#include "snd-aoa-alsa.h"
+
+static int index = -1;
+module_param(index, int, 0444);
+MODULE_PARM_DESC(index, "index for AOA sound card.");
+
+static struct aoa_card *aoa_card;
+
+int aoa_alsa_init(char *name, struct module *mod)
+{
+	struct snd_card *alsa_card;
+	int err;
+
+	if (aoa_card)
+		/* cannot be EEXIST due to usage in aoa_fabric_register */
+		return -EBUSY;
+
+	alsa_card = snd_card_new(index, name, mod, sizeof(struct aoa_card));
+	if (!alsa_card)
+		return -ENOMEM;
+	aoa_card = alsa_card->private_data;
+	aoa_card->alsa_card = alsa_card;
+	strlcpy(alsa_card->driver, "AppleOnbdAudio", sizeof(alsa_card->driver));
+	strlcpy(alsa_card->shortname, name, sizeof(alsa_card->shortname));
+	strlcpy(alsa_card->longname, name, sizeof(alsa_card->longname));
+	strlcpy(alsa_card->mixername, name, sizeof(alsa_card->mixername));
+	err = snd_card_register(aoa_card->alsa_card);
+	if (err < 0) {
+		printk(KERN_ERR "snd-aoa: couldn't register alsa card\n");
+		snd_card_free(aoa_card->alsa_card);
+		aoa_card = NULL;
+		return err;
+	}
+	return 0;
+}
+
+struct snd_card *aoa_get_card(void)
+{
+	if (aoa_card)
+		return aoa_card->alsa_card;
+	return NULL;
+}
+EXPORT_SYMBOL_GPL(aoa_get_card);
+
+void aoa_alsa_cleanup(void)
+{
+	if (aoa_card) {
+		snd_card_free(aoa_card->alsa_card);
+		aoa_card = NULL;
+	}
+}
+
+int aoa_snd_device_new(snd_device_type_t type,
+        void * device_data, struct snd_device_ops * ops)
+{
+	struct snd_card *card = aoa_get_card();
+	int err;
+	
+	if (!card) return -ENOMEM;
+
+	err = snd_device_new(card, type, device_data, ops);
+	if (err) {
+		printk(KERN_ERR "snd-aoa: failed to create snd device (%d)\n", err);
+		return err;
+	}
+	err = snd_device_register(card, device_data);
+	if (err) {
+		printk(KERN_ERR "snd-aoa: failed to register "
+				"snd device (%d)\n", err);
+		printk(KERN_ERR "snd-aoa: have you forgotten the "
+				"dev_register callback?\n");
+		snd_device_free(card, device_data);
+	}
+	return err;
+}
+EXPORT_SYMBOL_GPL(aoa_snd_device_new);
+
+int aoa_snd_ctl_add(struct snd_kcontrol* control)
+{
+	int err;
+
+	if (!aoa_card) return -ENODEV;
+
+	err = snd_ctl_add(aoa_card->alsa_card, control);
+	if (err)
+		printk(KERN_ERR "snd-aoa: failed to add alsa control (%d)\n",
+		       err);
+	return err;
+}
+EXPORT_SYMBOL_GPL(aoa_snd_ctl_add);
diff --git a/sound/aoa/core/snd-aoa-alsa.h b/sound/aoa/core/snd-aoa-alsa.h
new file mode 100644
index 000000000..660d2f179
--- /dev/null
+++ b/sound/aoa/core/snd-aoa-alsa.h
@@ -0,0 +1,16 @@
+/*
+ * Apple Onboard Audio Alsa private helpers
+ *
+ * Copyright 2006 Johannes Berg <johannes@sipsolutions.net>
+ *
+ * GPL v2, can be found in COPYING.
+ */
+
+#ifndef __SND_AOA_ALSA_H
+#define __SND_AOA_ALSA_H
+#include "../aoa.h"
+
+extern int aoa_alsa_init(char *name, struct module *mod);
+extern void aoa_alsa_cleanup(void);
+
+#endif /* __SND_AOA_ALSA_H */
diff --git a/sound/aoa/core/snd-aoa-core.c b/sound/aoa/core/snd-aoa-core.c
new file mode 100644
index 000000000..ecd2d8263
--- /dev/null
+++ b/sound/aoa/core/snd-aoa-core.c
@@ -0,0 +1,162 @@
+/*
+ * Apple Onboard Audio driver core
+ *
+ * Copyright 2006 Johannes Berg <johannes@sipsolutions.net>
+ *
+ * GPL v2, can be found in COPYING.
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/list.h>
+#include "../aoa.h"
+#include "snd-aoa-alsa.h"
+
+MODULE_DESCRIPTION("Apple Onboard Audio Sound Driver");
+MODULE_AUTHOR("Johannes Berg <johannes@sipsolutions.net>");
+MODULE_LICENSE("GPL");
+
+/* We allow only one fabric. This simplifies things,
+ * and more don't really make that much sense */
+static struct aoa_fabric *fabric;
+static LIST_HEAD(codec_list);
+
+static int attach_codec_to_fabric(struct aoa_codec *c)
+{
+	int err;
+
+	if (!try_module_get(c->owner))
+		return -EBUSY;
+	/* found_codec has to be assigned */
+	err = -ENOENT;
+	if (fabric->found_codec)
+		err = fabric->found_codec(c);
+	if (err) {
+		module_put(c->owner);
+		printk(KERN_ERR "snd-aoa: fabric didn't like codec %s\n",
+				c->name);
+		return err;
+	}
+	c->fabric = fabric;
+
+	err = 0;
+	if (c->init)
+		err = c->init(c);
+	if (err) {
+		printk(KERN_ERR "snd-aoa: codec %s didn't init\n", c->name);
+		c->fabric = NULL;
+		if (fabric->remove_codec)
+			fabric->remove_codec(c);
+		module_put(c->owner);
+		return err;
+	}
+	if (fabric->attached_codec)
+		fabric->attached_codec(c);
+	return 0;
+}
+
+int aoa_codec_register(struct aoa_codec *codec)
+{
+	int err = 0;
+
+	/* if there's a fabric already, we can tell if we
+	 * will want to have this codec, so propagate error
+	 * through. Otherwise, this will happen later... */
+	if (fabric)
+		err = attach_codec_to_fabric(codec);
+	if (!err)
+		list_add(&codec->list, &codec_list);
+	return err;
+}
+EXPORT_SYMBOL_GPL(aoa_codec_register);
+
+void aoa_codec_unregister(struct aoa_codec *codec)
+{
+	list_del(&codec->list);
+	if (codec->fabric && codec->exit)
+		codec->exit(codec);
+	if (fabric && fabric->remove_codec)
+		fabric->remove_codec(codec);
+	codec->fabric = NULL;
+	module_put(codec->owner);
+}
+EXPORT_SYMBOL_GPL(aoa_codec_unregister);
+
+int aoa_fabric_register(struct aoa_fabric *new_fabric)
+{
+	struct aoa_codec *c;
+	int err;
+
+	/* allow querying for presence of fabric
+	 * (i.e. do this test first!) */
+	if (new_fabric == fabric) {
+		err = -EALREADY;
+		goto attach;
+	}
+	if (fabric)
+		return -EEXIST;
+	if (!new_fabric)
+		return -EINVAL;
+
+	err = aoa_alsa_init(new_fabric->name, new_fabric->owner);
+	if (err)
+		return err;
+
+	fabric = new_fabric;
+
+ attach:
+	list_for_each_entry(c, &codec_list, list) {
+		if (c->fabric != fabric)
+			attach_codec_to_fabric(c);
+	}
+	return err;
+}
+EXPORT_SYMBOL_GPL(aoa_fabric_register);
+
+void aoa_fabric_unregister(struct aoa_fabric *old_fabric)
+{
+	struct aoa_codec *c;
+
+	if (fabric != old_fabric)
+		return;
+
+	list_for_each_entry(c, &codec_list, list) {
+		if (c->fabric)
+			aoa_fabric_unlink_codec(c);
+	}
+
+	aoa_alsa_cleanup();
+
+	fabric = NULL;
+}
+EXPORT_SYMBOL_GPL(aoa_fabric_unregister);
+
+void aoa_fabric_unlink_codec(struct aoa_codec *codec)
+{
+	if (!codec->fabric) {
+		printk(KERN_ERR "snd-aoa: fabric unassigned "
+				"in aoa_fabric_unlink_codec\n");
+		dump_stack();
+		return;
+	}
+	if (codec->exit)
+		codec->exit(codec);
+	if (codec->fabric->remove_codec)
+		codec->fabric->remove_codec(codec);
+	codec->fabric = NULL;
+	module_put(codec->owner);
+}
+EXPORT_SYMBOL_GPL(aoa_fabric_unlink_codec);
+
+static int __init aoa_init(void)
+{
+	return 0;
+}
+
+static void __exit aoa_exit(void)
+{
+	aoa_alsa_cleanup();
+}
+
+module_init(aoa_init);
+module_exit(aoa_exit);
diff --git a/sound/aoa/core/snd-aoa-gpio-feature.c b/sound/aoa/core/snd-aoa-gpio-feature.c
new file mode 100644
index 000000000..f69d33357
--- /dev/null
+++ b/sound/aoa/core/snd-aoa-gpio-feature.c
@@ -0,0 +1,412 @@
+/*
+ * Apple Onboard Audio feature call GPIO control
+ *
+ * Copyright 2006 Johannes Berg <johannes@sipsolutions.net>
+ *
+ * GPL v2, can be found in COPYING.
+ *
+ * This file contains the GPIO control routines for 
+ * direct (through feature calls) access to the GPIO
+ * registers.
+ */
+
+#include <asm/pmac_feature.h>
+#include <linux/interrupt.h>
+#include "../aoa.h"
+
+/* TODO: these are 20 global variables
+ * that aren't used on most machines...
+ * Move them into a dynamically allocated
+ * structure and use that.
+ */
+
+/* these are the GPIO numbers (register addresses as offsets into
+ * the GPIO space) */
+static int headphone_mute_gpio;
+static int amp_mute_gpio;
+static int lineout_mute_gpio;
+static int hw_reset_gpio;
+static int lineout_detect_gpio;
+static int headphone_detect_gpio;
+static int linein_detect_gpio;
+
+/* see the SWITCH_GPIO macro */
+static int headphone_mute_gpio_activestate;
+static int amp_mute_gpio_activestate;
+static int lineout_mute_gpio_activestate;
+static int hw_reset_gpio_activestate;
+static int lineout_detect_gpio_activestate;
+static int headphone_detect_gpio_activestate;
+static int linein_detect_gpio_activestate;
+
+/* node pointers that we save when getting the GPIO number
+ * to get the interrupt later */
+static struct device_node *lineout_detect_node;
+static struct device_node *linein_detect_node;
+static struct device_node *headphone_detect_node;
+
+static int lineout_detect_irq;
+static int linein_detect_irq;
+static int headphone_detect_irq;
+
+static struct device_node *get_gpio(char *name,
+				    char *altname,
+				    int *gpioptr,
+				    int *gpioactiveptr)
+{
+	struct device_node *np, *gpio;
+	u32 *reg;
+	char *audio_gpio;
+
+	*gpioptr = -1;
+
+	/* check if we can get it the easy way ... */
+	np = of_find_node_by_name(NULL, name);
+	if (!np) {
+		/* some machines have only gpioX/extint-gpioX nodes,
+		 * and an audio-gpio property saying what it is ...
+		 * So what we have to do is enumerate all children
+		 * of the gpio node and check them all. */
+		gpio = of_find_node_by_name(NULL, "gpio");
+		if (!gpio)
+			return NULL;
+		while ((np = of_get_next_child(gpio, np))) {
+			audio_gpio = get_property(np, "audio-gpio", NULL);
+			if (!audio_gpio)
+				continue;
+			if (strcmp(audio_gpio, name) == 0)
+				break;
+			if (altname && (strcmp(audio_gpio, altname) == 0))
+				break;
+		}
+		/* still not found, assume not there */
+		if (!np)
+			return NULL;
+	}
+
+	reg = (u32 *)get_property(np, "reg", NULL);
+	if (!reg)
+		return NULL;
+
+	*gpioptr = *reg;
+
+	/* this is a hack, usually the GPIOs 'reg' property
+	 * should have the offset based from the GPIO space
+	 * which is at 0x50, but apparently not always... */
+	if (*gpioptr < 0x50)
+		*gpioptr += 0x50;
+
+	reg = (u32 *)get_property(np, "audio-gpio-active-state", NULL);
+	if (!reg)
+		/* Apple seems to default to 1, but
+		 * that doesn't seem right at least on most
+		 * machines. So until proven that the opposite
+		 * is necessary, we default to 0
+		 * (which, incidentally, snd-powermac also does...) */
+		*gpioactiveptr = 0;
+	else
+		*gpioactiveptr = *reg;
+
+	return np;
+}
+
+static void get_irq(struct device_node * np, int *irqptr)
+{
+	if (np)
+		*irqptr = irq_of_parse_and_map(np, 0);
+	else
+		*irqptr = NO_IRQ;
+}
+
+/* 0x4 is outenable, 0x1 is out, thus 4 or 5 */
+#define SWITCH_GPIO(name, v, on)				\
+	(((v)&~1) | ((on)?					\
+			(name##_gpio_activestate==0?4:5):	\
+			(name##_gpio_activestate==0?5:4)))
+
+#define FTR_GPIO(name, bit)					\
+static void ftr_gpio_set_##name(struct gpio_runtime *rt, int on)\
+{								\
+	int v;							\
+								\
+	if (unlikely(!rt)) return;				\
+								\
+	if (name##_mute_gpio < 0)				\
+		return;						\
+								\
+	v = pmac_call_feature(PMAC_FTR_READ_GPIO, NULL,		\
+			      name##_mute_gpio,			\
+			      0);				\
+								\
+	/* muted = !on... */					\
+	v = SWITCH_GPIO(name##_mute, v, !on);			\
+								\
+	pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL,		\
+			  name##_mute_gpio, v);			\
+								\
+	rt->implementation_private &= ~(1<<bit);		\
+	rt->implementation_private |= (!!on << bit);		\
+}								\
+static int ftr_gpio_get_##name(struct gpio_runtime *rt)		\
+{								\
+	if (unlikely(!rt)) return 0;				\
+	return (rt->implementation_private>>bit)&1;		\
+}
+
+FTR_GPIO(headphone, 0);
+FTR_GPIO(amp, 1);
+FTR_GPIO(lineout, 2);
+
+static void ftr_gpio_set_hw_reset(struct gpio_runtime *rt, int on)
+{
+	int v;
+
+	if (unlikely(!rt)) return;
+	if (hw_reset_gpio < 0)
+		return;
+
+	v = pmac_call_feature(PMAC_FTR_READ_GPIO, NULL,
+			      hw_reset_gpio, 0);
+	v = SWITCH_GPIO(hw_reset, v, on);
+	pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL,
+			  hw_reset_gpio, v);
+}
+
+static void ftr_gpio_all_amps_off(struct gpio_runtime *rt)
+{
+	int saved;
+
+	if (unlikely(!rt)) return;
+	saved = rt->implementation_private;
+	ftr_gpio_set_headphone(rt, 0);
+	ftr_gpio_set_amp(rt, 0);
+	ftr_gpio_set_lineout(rt, 0);
+	rt->implementation_private = saved;
+}
+
+static void ftr_gpio_all_amps_restore(struct gpio_runtime *rt)
+{
+	int s;
+
+	if (unlikely(!rt)) return;
+	s = rt->implementation_private;
+	ftr_gpio_set_headphone(rt, (s>>0)&1);
+	ftr_gpio_set_amp(rt, (s>>1)&1);
+	ftr_gpio_set_lineout(rt, (s>>2)&1);
+}
+
+static void ftr_handle_notify(void *data)
+{
+	struct gpio_notification *notif = data;
+
+	mutex_lock(&notif->mutex);
+	if (notif->notify)
+		notif->notify(notif->data);
+	mutex_unlock(&notif->mutex);
+}
+
+static void gpio_enable_dual_edge(int gpio)
+{
+	int v;
+
+	if (gpio == -1)
+		return;
+	v = pmac_call_feature(PMAC_FTR_READ_GPIO, NULL, gpio, 0);
+	v |= 0x80; /* enable dual edge */
+	pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, gpio, v);
+}
+
+static void ftr_gpio_init(struct gpio_runtime *rt)
+{
+	get_gpio("headphone-mute", NULL,
+		 &headphone_mute_gpio,
+		 &headphone_mute_gpio_activestate);
+	get_gpio("amp-mute", NULL,
+		 &amp_mute_gpio,
+		 &amp_mute_gpio_activestate);
+	get_gpio("lineout-mute", NULL,
+		 &lineout_mute_gpio,
+		 &lineout_mute_gpio_activestate);
+	get_gpio("hw-reset", "audio-hw-reset",
+		 &hw_reset_gpio,
+		 &hw_reset_gpio_activestate);
+
+	headphone_detect_node = get_gpio("headphone-detect", NULL,
+					 &headphone_detect_gpio,
+					 &headphone_detect_gpio_activestate);
+	/* go Apple, and thanks for giving these different names
+	 * across the board... */
+	lineout_detect_node = get_gpio("lineout-detect", "line-output-detect",
+				       &lineout_detect_gpio,
+				       &lineout_detect_gpio_activestate);
+	linein_detect_node = get_gpio("linein-detect", "line-input-detect",
+				      &linein_detect_gpio,
+				      &linein_detect_gpio_activestate);
+
+	gpio_enable_dual_edge(headphone_detect_gpio);
+	gpio_enable_dual_edge(lineout_detect_gpio);
+	gpio_enable_dual_edge(linein_detect_gpio);
+
+	get_irq(headphone_detect_node, &headphone_detect_irq);
+	get_irq(lineout_detect_node, &lineout_detect_irq);
+	get_irq(linein_detect_node, &linein_detect_irq);
+
+	ftr_gpio_all_amps_off(rt);
+	rt->implementation_private = 0;
+	INIT_WORK(&rt->headphone_notify.work, ftr_handle_notify,
+		  &rt->headphone_notify);
+	INIT_WORK(&rt->line_in_notify.work, ftr_handle_notify,
+		  &rt->line_in_notify);
+	INIT_WORK(&rt->line_out_notify.work, ftr_handle_notify,
+		  &rt->line_out_notify);
+	mutex_init(&rt->headphone_notify.mutex);
+	mutex_init(&rt->line_in_notify.mutex);
+	mutex_init(&rt->line_out_notify.mutex);
+}
+
+static void ftr_gpio_exit(struct gpio_runtime *rt)
+{
+	ftr_gpio_all_amps_off(rt);
+	rt->implementation_private = 0;
+	if (rt->headphone_notify.notify)
+		free_irq(headphone_detect_irq, &rt->headphone_notify);
+	if (rt->line_in_notify.gpio_private)
+		free_irq(linein_detect_irq, &rt->line_in_notify);
+	if (rt->line_out_notify.gpio_private)
+		free_irq(lineout_detect_irq, &rt->line_out_notify);
+	cancel_delayed_work(&rt->headphone_notify.work);
+	cancel_delayed_work(&rt->line_in_notify.work);
+	cancel_delayed_work(&rt->line_out_notify.work);
+	flush_scheduled_work();
+	mutex_destroy(&rt->headphone_notify.mutex);
+	mutex_destroy(&rt->line_in_notify.mutex);
+	mutex_destroy(&rt->line_out_notify.mutex);
+}
+
+static irqreturn_t ftr_handle_notify_irq(int xx,
+					 void *data,
+					 struct pt_regs *regs)
+{
+	struct gpio_notification *notif = data;
+
+	schedule_work(&notif->work);
+
+	return IRQ_HANDLED;
+}
+
+static int ftr_set_notify(struct gpio_runtime *rt,
+			  enum notify_type type,
+			  notify_func_t notify,
+			  void *data)
+{
+	struct gpio_notification *notif;
+	notify_func_t old;
+	int irq;
+	char *name;
+	int err = -EBUSY;
+
+	switch (type) {
+	case AOA_NOTIFY_HEADPHONE:
+		notif = &rt->headphone_notify;
+		name = "headphone-detect";
+		irq = headphone_detect_irq;
+		break;
+	case AOA_NOTIFY_LINE_IN:
+		notif = &rt->line_in_notify;
+		name = "linein-detect";
+		irq = linein_detect_irq;
+		break;
+	case AOA_NOTIFY_LINE_OUT:
+		notif = &rt->line_out_notify;
+		name = "lineout-detect";
+		irq = lineout_detect_irq;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	if (irq == NO_IRQ)
+		return -ENODEV;
+
+	mutex_lock(&notif->mutex);
+
+	old = notif->notify;
+
+	if (!old && !notify) {
+		err = 0;
+		goto out_unlock;
+	}
+
+	if (old && notify) {
+		if (old == notify && notif->data == data)
+			err = 0;
+		goto out_unlock;
+	}
+
+	if (old && !notify)
+		free_irq(irq, notif);
+
+	if (!old && notify) {
+		err = request_irq(irq, ftr_handle_notify_irq, 0, name, notif);
+		if (err)
+			goto out_unlock;
+	}
+
+	notif->notify = notify;
+	notif->data = data;
+
+	err = 0;
+ out_unlock:
+	mutex_unlock(&notif->mutex);
+	return err;
+}
+
+static int ftr_get_detect(struct gpio_runtime *rt,
+			  enum notify_type type)
+{
+	int gpio, ret, active;
+
+	switch (type) {
+	case AOA_NOTIFY_HEADPHONE:
+		gpio = headphone_detect_gpio;
+		active = headphone_detect_gpio_activestate;
+		break;
+	case AOA_NOTIFY_LINE_IN:
+		gpio = linein_detect_gpio;
+		active = linein_detect_gpio_activestate;
+		break;
+	case AOA_NOTIFY_LINE_OUT:
+		gpio = lineout_detect_gpio;
+		active = lineout_detect_gpio_activestate;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	if (gpio == -1)
+		return -ENODEV;
+
+	ret = pmac_call_feature(PMAC_FTR_READ_GPIO, NULL, gpio, 0);
+	if (ret < 0)
+		return ret;
+	return ((ret >> 1) & 1) == active;
+}
+
+static struct gpio_methods methods = {
+	.init			= ftr_gpio_init,
+	.exit			= ftr_gpio_exit,
+	.all_amps_off		= ftr_gpio_all_amps_off,
+	.all_amps_restore	= ftr_gpio_all_amps_restore,
+	.set_headphone		= ftr_gpio_set_headphone,
+	.set_speakers		= ftr_gpio_set_amp,
+	.set_lineout		= ftr_gpio_set_lineout,
+	.set_hw_reset		= ftr_gpio_set_hw_reset,
+	.get_headphone		= ftr_gpio_get_headphone,
+	.get_speakers		= ftr_gpio_get_amp,
+	.get_lineout		= ftr_gpio_get_lineout,
+	.set_notify		= ftr_set_notify,
+	.get_detect		= ftr_get_detect,
+};
+
+struct gpio_methods *ftr_gpio_methods = &methods;
+EXPORT_SYMBOL_GPL(ftr_gpio_methods);
diff --git a/sound/aoa/core/snd-aoa-gpio-pmf.c b/sound/aoa/core/snd-aoa-gpio-pmf.c
new file mode 100644
index 000000000..2836c3218
--- /dev/null
+++ b/sound/aoa/core/snd-aoa-gpio-pmf.c
@@ -0,0 +1,254 @@
+/*
+ * Apple Onboard Audio pmf GPIOs
+ *
+ * Copyright 2006 Johannes Berg <johannes@sipsolutions.net>
+ *
+ * GPL v2, can be found in COPYING.
+ */
+
+#include <asm/pmac_feature.h>
+#include <asm/pmac_pfunc.h>
+#include "../aoa.h"
+
+#define PMF_GPIO(name, bit)					\
+static void pmf_gpio_set_##name(struct gpio_runtime *rt, int on)\
+{								\
+	struct pmf_args args = { .count = 1, .u[0].v = !on };	\
+	int rc;							\
+							\
+	if (unlikely(!rt)) return;				\
+	rc = pmf_call_function(rt->node, #name "-mute", &args);	\
+	if (rc && rc != -ENODEV)				\
+		printk(KERN_WARNING "pmf_gpio_set_" #name	\
+		" failed, rc: %d\n", rc);			\
+	rt->implementation_private &= ~(1<<bit);		\
+	rt->implementation_private |= (!!on << bit);		\
+}								\
+static int pmf_gpio_get_##name(struct gpio_runtime *rt)		\
+{								\
+	if (unlikely(!rt)) return 0;				\
+	return (rt->implementation_private>>bit)&1;		\
+}
+
+PMF_GPIO(headphone, 0);
+PMF_GPIO(amp, 1);
+PMF_GPIO(lineout, 2);
+
+static void pmf_gpio_set_hw_reset(struct gpio_runtime *rt, int on)
+{
+	struct pmf_args args = { .count = 1, .u[0].v = !!on };
+	int rc;
+
+	if (unlikely(!rt)) return;
+	rc = pmf_call_function(rt->node, "hw-reset", &args);
+	if (rc)
+		printk(KERN_WARNING "pmf_gpio_set_hw_reset"
+		       " failed, rc: %d\n", rc);
+}
+
+static void pmf_gpio_all_amps_off(struct gpio_runtime *rt)
+{
+	int saved;
+
+	if (unlikely(!rt)) return;
+	saved = rt->implementation_private;
+	pmf_gpio_set_headphone(rt, 0);
+	pmf_gpio_set_amp(rt, 0);
+	pmf_gpio_set_lineout(rt, 0);
+	rt->implementation_private = saved;
+}
+
+static void pmf_gpio_all_amps_restore(struct gpio_runtime *rt)
+{
+	int s;
+
+	if (unlikely(!rt)) return;
+	s = rt->implementation_private;
+	pmf_gpio_set_headphone(rt, (s>>0)&1);
+	pmf_gpio_set_amp(rt, (s>>1)&1);
+	pmf_gpio_set_lineout(rt, (s>>2)&1);
+}
+
+static void pmf_handle_notify(void *data)
+{
+	struct gpio_notification *notif = data;
+
+	mutex_lock(&notif->mutex);
+	if (notif->notify)
+		notif->notify(notif->data);
+	mutex_unlock(&notif->mutex);
+}
+
+static void pmf_gpio_init(struct gpio_runtime *rt)
+{
+	pmf_gpio_all_amps_off(rt);
+	rt->implementation_private = 0;
+	INIT_WORK(&rt->headphone_notify.work, pmf_handle_notify,
+		  &rt->headphone_notify);
+	INIT_WORK(&rt->line_in_notify.work, pmf_handle_notify,
+		  &rt->line_in_notify);
+	INIT_WORK(&rt->line_out_notify.work, pmf_handle_notify,
+		  &rt->line_out_notify);
+	mutex_init(&rt->headphone_notify.mutex);
+	mutex_init(&rt->line_in_notify.mutex);
+	mutex_init(&rt->line_out_notify.mutex);
+}
+
+static void pmf_gpio_exit(struct gpio_runtime *rt)
+{
+	pmf_gpio_all_amps_off(rt);
+	rt->implementation_private = 0;
+
+	if (rt->headphone_notify.gpio_private)
+		pmf_unregister_irq_client(rt->headphone_notify.gpio_private);
+	if (rt->line_in_notify.gpio_private)
+		pmf_unregister_irq_client(rt->line_in_notify.gpio_private);
+	if (rt->line_out_notify.gpio_private)
+		pmf_unregister_irq_client(rt->line_out_notify.gpio_private);
+
+	/* make sure no work is pending before freeing
+	 * all things */
+	cancel_delayed_work(&rt->headphone_notify.work);
+	cancel_delayed_work(&rt->line_in_notify.work);
+	cancel_delayed_work(&rt->line_out_notify.work);
+	flush_scheduled_work();
+
+	mutex_destroy(&rt->headphone_notify.mutex);
+	mutex_destroy(&rt->line_in_notify.mutex);
+	mutex_destroy(&rt->line_out_notify.mutex);
+
+	if (rt->headphone_notify.gpio_private)
+		kfree(rt->headphone_notify.gpio_private);
+	if (rt->line_in_notify.gpio_private)
+		kfree(rt->line_in_notify.gpio_private);
+	if (rt->line_out_notify.gpio_private)
+		kfree(rt->line_out_notify.gpio_private);
+}
+
+static void pmf_handle_notify_irq(void *data)
+{
+	struct gpio_notification *notif = data;
+
+	schedule_work(&notif->work);
+}
+
+static int pmf_set_notify(struct gpio_runtime *rt,
+			  enum notify_type type,
+			  notify_func_t notify,
+			  void *data)
+{
+	struct gpio_notification *notif;
+	notify_func_t old;
+	struct pmf_irq_client *irq_client;
+	char *name;
+	int err = -EBUSY;
+
+	switch (type) {
+	case AOA_NOTIFY_HEADPHONE:
+		notif = &rt->headphone_notify;
+		name = "headphone-detect";
+		break;
+	case AOA_NOTIFY_LINE_IN:
+		notif = &rt->line_in_notify;
+		name = "linein-detect";
+		break;
+	case AOA_NOTIFY_LINE_OUT:
+		notif = &rt->line_out_notify;
+		name = "lineout-detect";
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	mutex_lock(&notif->mutex);
+
+	old = notif->notify;
+
+	if (!old && !notify) {
+		err = 0;
+		goto out_unlock;
+	}
+
+	if (old && notify) {
+		if (old == notify && notif->data == data)
+			err = 0;
+		goto out_unlock;
+	}
+
+	if (old && !notify) {
+		irq_client = notif->gpio_private;
+		pmf_unregister_irq_client(irq_client);
+		kfree(irq_client);
+		notif->gpio_private = NULL;
+	}
+	if (!old && notify) {
+		irq_client = kzalloc(sizeof(struct pmf_irq_client),
+				     GFP_KERNEL);
+		irq_client->data = notif;
+		irq_client->handler = pmf_handle_notify_irq;
+		irq_client->owner = THIS_MODULE;
+		err = pmf_register_irq_client(rt->node,
+					      name,
+					      irq_client);
+		if (err) {
+			printk(KERN_ERR "snd-aoa: gpio layer failed to"
+					" register %s irq (%d)\n", name, err);
+			kfree(irq_client);
+			goto out_unlock;
+		}
+		notif->gpio_private = irq_client;
+	}
+	notif->notify = notify;
+	notif->data = data;
+
+	err = 0;
+ out_unlock:
+	mutex_unlock(&notif->mutex);
+	return err;
+}
+
+static int pmf_get_detect(struct gpio_runtime *rt,
+			  enum notify_type type)
+{
+	char *name;
+	int err = -EBUSY, ret;
+	struct pmf_args args = { .count = 1, .u[0].p = &ret };
+
+	switch (type) {
+	case AOA_NOTIFY_HEADPHONE:
+		name = "headphone-detect";
+		break;
+	case AOA_NOTIFY_LINE_IN:
+		name = "linein-detect";
+		break;
+	case AOA_NOTIFY_LINE_OUT:
+		name = "lineout-detect";
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	err = pmf_call_function(rt->node, name, &args);
+	if (err)
+		return err;
+	return ret;
+}
+
+static struct gpio_methods methods = {
+	.init			= pmf_gpio_init,
+	.exit			= pmf_gpio_exit,
+	.all_amps_off		= pmf_gpio_all_amps_off,
+	.all_amps_restore	= pmf_gpio_all_amps_restore,
+	.set_headphone		= pmf_gpio_set_headphone,
+	.set_speakers		= pmf_gpio_set_amp,
+	.set_lineout		= pmf_gpio_set_lineout,
+	.set_hw_reset		= pmf_gpio_set_hw_reset,
+	.get_headphone		= pmf_gpio_get_headphone,
+	.get_speakers		= pmf_gpio_get_amp,
+	.get_lineout		= pmf_gpio_get_lineout,
+	.set_notify		= pmf_set_notify,
+	.get_detect		= pmf_get_detect,
+};
+
+struct gpio_methods *pmf_gpio_methods = &methods;
+EXPORT_SYMBOL_GPL(pmf_gpio_methods);
diff --git a/sound/aoa/fabrics/Kconfig b/sound/aoa/fabrics/Kconfig
new file mode 100644
index 000000000..c3bc7705c
--- /dev/null
+++ b/sound/aoa/fabrics/Kconfig
@@ -0,0 +1,12 @@
+config SND_AOA_FABRIC_LAYOUT
+	tristate "layout-id fabric"
+	depends SND_AOA
+	select SND_AOA_SOUNDBUS
+	select SND_AOA_SOUNDBUS_I2S
+	---help---
+	This enables the layout-id fabric for the Apple Onboard
+	Audio driver, the module holding it all together
+	based on the device-tree's layout-id property.
+	
+	If you are unsure and have a later Apple machine,
+	compile it as a module.
diff --git a/sound/aoa/fabrics/Makefile b/sound/aoa/fabrics/Makefile
new file mode 100644
index 000000000..55fc5e7e5
--- /dev/null
+++ b/sound/aoa/fabrics/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_SND_AOA_FABRIC_LAYOUT) += snd-aoa-fabric-layout.o
diff --git a/sound/aoa/fabrics/snd-aoa-fabric-layout.c b/sound/aoa/fabrics/snd-aoa-fabric-layout.c
new file mode 100644
index 000000000..172eb9547
--- /dev/null
+++ b/sound/aoa/fabrics/snd-aoa-fabric-layout.c
@@ -0,0 +1,1129 @@
+/*
+ * Apple Onboard Audio driver -- layout fabric
+ *
+ * Copyright 2006 Johannes Berg <johannes@sipsolutions.net>
+ *
+ * GPL v2, can be found in COPYING.
+ *
+ *
+ * This fabric module looks for sound codecs
+ * based on the layout-id property in the device tree.
+ *
+ */
+
+#include <asm/prom.h>
+#include <linux/list.h>
+#include <linux/module.h>
+#include "../aoa.h"
+#include "../soundbus/soundbus.h"
+
+MODULE_AUTHOR("Johannes Berg <johannes@sipsolutions.net>");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Layout-ID fabric for snd-aoa");
+
+#define MAX_CODECS_PER_BUS	2
+
+/* These are the connections the layout fabric
+ * knows about. It doesn't really care about the
+ * input ones, but I thought I'd separate them
+ * to give them proper names. The thing is that
+ * Apple usually will distinguish the active output
+ * by GPIOs, while the active input is set directly
+ * on the codec. Hence we here tell the codec what
+ * we think is connected. This information is hard-
+ * coded below ... */
+#define CC_SPEAKERS	(1<<0)
+#define CC_HEADPHONE	(1<<1)
+#define CC_LINEOUT	(1<<2)
+#define CC_DIGITALOUT	(1<<3)
+#define CC_LINEIN	(1<<4)
+#define CC_MICROPHONE	(1<<5)
+#define CC_DIGITALIN	(1<<6)
+/* pretty bogus but users complain...
+ * This is a flag saying that the LINEOUT
+ * should be renamed to HEADPHONE.
+ * be careful with input detection! */
+#define CC_LINEOUT_LABELLED_HEADPHONE	(1<<7)
+
+struct codec_connection {
+	/* CC_ flags from above */
+	int connected;
+	/* codec dependent bit to be set in the aoa_codec.connected field.
+	 * This intentionally doesn't have any generic flags because the
+	 * fabric has to know the codec anyway and all codecs might have
+	 * different connectors */
+	int codec_bit;
+};
+
+struct codec_connect_info {
+	char *name;
+	struct codec_connection *connections;
+};
+
+#define LAYOUT_FLAG_COMBO_LINEOUT_SPDIF	(1<<0)
+
+struct layout {
+	unsigned int layout_id;
+	struct codec_connect_info codecs[MAX_CODECS_PER_BUS];
+	int flags;
+	
+	/* if busname is not assigned, we use 'Master' below,
+	 * so that our layout table doesn't need to be filled
+	 * too much.
+	 * We only assign these two if we expect to find more
+	 * than one soundbus, i.e. on those machines with
+	 * multiple layout-ids */
+	char *busname;
+	int pcmid;
+};
+
+MODULE_ALIAS("sound-layout-36");
+MODULE_ALIAS("sound-layout-41");
+MODULE_ALIAS("sound-layout-45");
+MODULE_ALIAS("sound-layout-47");
+MODULE_ALIAS("sound-layout-48");
+MODULE_ALIAS("sound-layout-49");
+MODULE_ALIAS("sound-layout-50");
+MODULE_ALIAS("sound-layout-51");
+MODULE_ALIAS("sound-layout-56");
+MODULE_ALIAS("sound-layout-57");
+MODULE_ALIAS("sound-layout-58");
+MODULE_ALIAS("sound-layout-60");
+MODULE_ALIAS("sound-layout-61");
+MODULE_ALIAS("sound-layout-62");
+MODULE_ALIAS("sound-layout-64");
+MODULE_ALIAS("sound-layout-65");
+MODULE_ALIAS("sound-layout-66");
+MODULE_ALIAS("sound-layout-67");
+MODULE_ALIAS("sound-layout-68");
+MODULE_ALIAS("sound-layout-69");
+MODULE_ALIAS("sound-layout-70");
+MODULE_ALIAS("sound-layout-72");
+MODULE_ALIAS("sound-layout-76");
+MODULE_ALIAS("sound-layout-80");
+MODULE_ALIAS("sound-layout-82");
+MODULE_ALIAS("sound-layout-84");
+MODULE_ALIAS("sound-layout-86");
+MODULE_ALIAS("sound-layout-90");
+MODULE_ALIAS("sound-layout-92");
+MODULE_ALIAS("sound-layout-94");
+MODULE_ALIAS("sound-layout-96");
+MODULE_ALIAS("sound-layout-98");
+MODULE_ALIAS("sound-layout-100");
+
+/* onyx with all but microphone connected */
+static struct codec_connection onyx_connections_nomic[] = {
+	{
+		.connected = CC_SPEAKERS | CC_HEADPHONE | CC_LINEOUT,
+		.codec_bit = 0,
+	},
+	{
+		.connected = CC_DIGITALOUT,
+		.codec_bit = 1,
+	},
+	{
+		.connected = CC_LINEIN,
+		.codec_bit = 2,
+	},
+	{} /* terminate array by .connected == 0 */
+};
+
+/* onyx on machines without headphone */
+static struct codec_connection onyx_connections_noheadphones[] = {
+	{
+		.connected = CC_SPEAKERS | CC_LINEOUT |
+			     CC_LINEOUT_LABELLED_HEADPHONE,
+		.codec_bit = 0,
+	},
+	{
+		.connected = CC_DIGITALOUT,
+		.codec_bit = 1,
+	},
+	/* FIXME: are these correct? probably not for all the machines
+	 * below ... If not this will need separating. */
+	{
+		.connected = CC_LINEIN,
+		.codec_bit = 2,
+	},
+	{
+		.connected = CC_MICROPHONE,
+		.codec_bit = 3,
+	},
+	{} /* terminate array by .connected == 0 */
+};
+
+/* onyx on machines with real line-out */
+static struct codec_connection onyx_connections_reallineout[] = {
+	{
+		.connected = CC_SPEAKERS | CC_LINEOUT | CC_HEADPHONE,
+		.codec_bit = 0,
+	},
+	{
+		.connected = CC_DIGITALOUT,
+		.codec_bit = 1,
+	},
+	{
+		.connected = CC_LINEIN,
+		.codec_bit = 2,
+	},
+	{} /* terminate array by .connected == 0 */
+};
+
+/* tas on machines without line out */
+static struct codec_connection tas_connections_nolineout[] = {
+	{
+		.connected = CC_SPEAKERS | CC_HEADPHONE,
+		.codec_bit = 0,
+	},
+	{
+		.connected = CC_LINEIN,
+		.codec_bit = 2,
+	},
+	{
+		.connected = CC_MICROPHONE,
+		.codec_bit = 3,
+	},
+	{} /* terminate array by .connected == 0 */
+};
+
+/* tas on machines with neither line out nor line in */
+static struct codec_connection tas_connections_noline[] = {
+	{
+		.connected = CC_SPEAKERS | CC_HEADPHONE,
+		.codec_bit = 0,
+	},
+	{
+		.connected = CC_MICROPHONE,
+		.codec_bit = 3,
+	},
+	{} /* terminate array by .connected == 0 */
+};
+
+/* tas on machines without microphone */
+static struct codec_connection tas_connections_nomic[] = {
+	{
+		.connected = CC_SPEAKERS | CC_HEADPHONE | CC_LINEOUT,
+		.codec_bit = 0,
+	},
+	{
+		.connected = CC_LINEIN,
+		.codec_bit = 2,
+	},
+	{} /* terminate array by .connected == 0 */
+};
+
+/* tas on machines with everything connected */
+static struct codec_connection tas_connections_all[] = {
+	{
+		.connected = CC_SPEAKERS | CC_HEADPHONE | CC_LINEOUT,
+		.codec_bit = 0,
+	},
+	{
+		.connected = CC_LINEIN,
+		.codec_bit = 2,
+	},
+	{
+		.connected = CC_MICROPHONE,
+		.codec_bit = 3,
+	},
+	{} /* terminate array by .connected == 0 */
+};
+
+static struct codec_connection toonie_connections[] = {
+	{
+		.connected = CC_SPEAKERS | CC_HEADPHONE,
+		.codec_bit = 0,
+	},
+	{} /* terminate array by .connected == 0 */
+};
+
+static struct codec_connection topaz_input[] = {
+	{
+		.connected = CC_DIGITALIN,
+		.codec_bit = 0,
+	},
+	{} /* terminate array by .connected == 0 */
+};
+
+static struct codec_connection topaz_output[] = {
+	{
+		.connected = CC_DIGITALOUT,
+		.codec_bit = 1,
+	},
+	{} /* terminate array by .connected == 0 */
+};
+
+static struct codec_connection topaz_inout[] = {
+	{
+		.connected = CC_DIGITALIN,
+		.codec_bit = 0,
+	},
+	{
+		.connected = CC_DIGITALOUT,
+		.codec_bit = 1,
+	},
+	{} /* terminate array by .connected == 0 */
+};
+
+static struct layout layouts[] = {
+	/* last PowerBooks (15" Oct 2005) */
+	{ .layout_id = 82,
+	  .flags = LAYOUT_FLAG_COMBO_LINEOUT_SPDIF,
+	  .codecs[0] = {
+		.name = "onyx",
+		.connections = onyx_connections_noheadphones,
+	  },
+	  .codecs[1] = {
+		.name = "topaz",
+		.connections = topaz_input,
+	  },
+	},
+	/* PowerMac9,1 */
+	{ .layout_id = 60,
+	  .codecs[0] = {
+		.name = "onyx",
+		.connections = onyx_connections_reallineout,
+	  },
+	},
+	/* PowerMac9,1 */
+	{ .layout_id = 61,
+	  .codecs[0] = {
+		.name = "topaz",
+		.connections = topaz_input,
+	  },
+	},
+	/* PowerBook5,7 */
+	{ .layout_id = 64,
+	  .flags = LAYOUT_FLAG_COMBO_LINEOUT_SPDIF,
+	  .codecs[0] = {
+		.name = "onyx",
+		.connections = onyx_connections_noheadphones,
+	  },
+	},
+	/* PowerBook5,7 */
+	{ .layout_id = 65,
+	  .codecs[0] = {
+		.name = "topaz",
+		.connections = topaz_input,
+	  },
+	},
+	/* PowerBook5,9 [17" Oct 2005] */
+	{ .layout_id = 84,
+	  .flags = LAYOUT_FLAG_COMBO_LINEOUT_SPDIF,
+	  .codecs[0] = {
+		.name = "onyx",
+		.connections = onyx_connections_noheadphones,
+	  },
+	  .codecs[1] = {
+		.name = "topaz",
+		.connections = topaz_input,
+	  },
+	},
+	/* PowerMac8,1 */
+	{ .layout_id = 45,
+	  .codecs[0] = {
+		.name = "onyx",
+		.connections = onyx_connections_noheadphones,
+	  },
+	  .codecs[1] = {
+		.name = "topaz",
+		.connections = topaz_input,
+	  },
+	},
+	/* Quad PowerMac (analog in, analog/digital out) */
+	{ .layout_id = 68,
+	  .codecs[0] = {
+		.name = "onyx",
+		.connections = onyx_connections_nomic,
+	  },
+	},
+	/* Quad PowerMac (digital in) */
+	{ .layout_id = 69,
+	  .codecs[0] = {
+		.name = "topaz",
+		.connections = topaz_input,
+	  },
+	  .busname = "digital in", .pcmid = 1 },
+	/* Early 2005 PowerBook (PowerBook 5,6) */
+	{ .layout_id = 70,
+	  .codecs[0] = {
+		.name = "tas",
+		.connections = tas_connections_nolineout,
+	  },
+	},
+	/* PowerBook 5,4 */
+	{ .layout_id = 51,
+	  .codecs[0] = {
+		.name = "tas",
+		.connections = tas_connections_nolineout,
+	  },
+	},
+	/* PowerBook6,7 */
+	{ .layout_id = 80,
+	  .codecs[0] = {
+		.name = "tas",
+		.connections = tas_connections_noline,
+	  },
+	},
+	/* PowerBook6,8 */
+	{ .layout_id = 72,
+	  .codecs[0] = {
+		.name = "tas",
+		.connections = tas_connections_nolineout,
+	  },
+	},
+	/* PowerMac8,2 */
+	{ .layout_id = 86,
+	  .codecs[0] = {
+		.name = "onyx",
+		.connections = onyx_connections_nomic,
+	  },
+	  .codecs[1] = {
+		.name = "topaz",
+		.connections = topaz_input,
+	  },
+	},
+	/* PowerBook6,7 */
+	{ .layout_id = 92,
+	  .codecs[0] = {
+		.name = "tas",
+		.connections = tas_connections_nolineout,
+	  },
+	},
+	/* PowerMac10,1 (Mac Mini) */
+	{ .layout_id = 58,
+	  .codecs[0] = {
+		.name = "toonie",
+		.connections = toonie_connections,
+	  },
+	},
+	{
+	  .layout_id = 96,
+	  .codecs[0] = {
+	  	.name = "onyx",
+	  	.connections = onyx_connections_noheadphones,
+	  },
+	},
+	/* unknown, untested, but this comes from Apple */
+	{ .layout_id = 41,
+	  .codecs[0] = {
+		.name = "tas",
+		.connections = tas_connections_all,
+	  },
+	},
+	{ .layout_id = 36,
+	  .codecs[0] = {
+		.name = "tas",
+		.connections = tas_connections_nomic,
+	  },
+	  .codecs[1] = {
+		.name = "topaz",
+		.connections = topaz_inout,
+	  },
+	},
+	{ .layout_id = 47,
+	  .codecs[0] = {
+		.name = "onyx",
+		.connections = onyx_connections_noheadphones,
+	  },
+	},
+	{ .layout_id = 48,
+	  .codecs[0] = {
+		.name = "topaz",
+		.connections = topaz_input,
+	  },
+	},
+	{ .layout_id = 49,
+	  .codecs[0] = {
+		.name = "onyx",
+		.connections = onyx_connections_nomic,
+	  },
+	},
+	{ .layout_id = 50,
+	  .codecs[0] = {
+		.name = "topaz",
+		.connections = topaz_input,
+	  },
+	},
+	{ .layout_id = 56,
+	  .codecs[0] = {
+		.name = "onyx",
+		.connections = onyx_connections_noheadphones,
+	  },
+	},
+	{ .layout_id = 57,
+	  .codecs[0] = {
+		.name = "topaz",
+		.connections = topaz_input,
+	  },
+	},
+	{ .layout_id = 62,
+	  .codecs[0] = {
+		.name = "onyx",
+		.connections = onyx_connections_noheadphones,
+	  },
+	  .codecs[1] = {
+		.name = "topaz",
+		.connections = topaz_output,
+	  },
+	},
+	{ .layout_id = 66,
+	  .codecs[0] = {
+		.name = "onyx",
+		.connections = onyx_connections_noheadphones,
+	  },
+	},
+	{ .layout_id = 67,
+	  .codecs[0] = {
+		.name = "topaz",
+		.connections = topaz_input,
+	  },
+	},
+	{ .layout_id = 76,
+	  .codecs[0] = {
+		.name = "tas",
+		.connections = tas_connections_nomic,
+	  },
+	  .codecs[1] = {
+		.name = "topaz",
+		.connections = topaz_inout,
+	  },
+	},
+	{ .layout_id = 90,
+	  .codecs[0] = {
+		.name = "tas",
+		.connections = tas_connections_noline,
+	  },
+	},
+	{ .layout_id = 94,
+	  .codecs[0] = {
+		.name = "onyx",
+		/* but it has an external mic?? how to select? */
+		.connections = onyx_connections_noheadphones,
+	  },
+	},
+	{ .layout_id = 98,
+	  .codecs[0] = {
+		.name = "toonie",
+		.connections = toonie_connections,
+	  },
+	},
+	{ .layout_id = 100,
+	  .codecs[0] = {
+		.name = "topaz",
+		.connections = topaz_input,
+	  },
+	  .codecs[1] = {
+		.name = "onyx",
+		.connections = onyx_connections_noheadphones,
+	  },
+	},
+	{}
+};
+
+static struct layout *find_layout_by_id(unsigned int id)
+{
+	struct layout *l;
+
+	l = layouts;
+	while (l->layout_id) {
+		if (l->layout_id == id)
+			return l;
+		l++;
+	}
+	return NULL;
+}
+
+static void use_layout(struct layout *l)
+{
+	int i;
+
+	for (i=0; i<MAX_CODECS_PER_BUS; i++) {
+		if (l->codecs[i].name) {
+			request_module("snd-aoa-codec-%s", l->codecs[i].name);
+		}
+	}
+	/* now we wait for the codecs to call us back */
+}
+
+struct layout_dev;
+
+struct layout_dev_ptr {
+	struct layout_dev *ptr;
+};
+
+struct layout_dev {
+	struct list_head list;
+	struct soundbus_dev *sdev;
+	struct device_node *sound;
+	struct aoa_codec *codecs[MAX_CODECS_PER_BUS];
+	struct layout *layout;
+	struct gpio_runtime gpio;
+
+	/* we need these for headphone/lineout detection */
+	struct snd_kcontrol *headphone_ctrl;
+	struct snd_kcontrol *lineout_ctrl;
+	struct snd_kcontrol *speaker_ctrl;
+	struct snd_kcontrol *headphone_detected_ctrl;
+	struct snd_kcontrol *lineout_detected_ctrl;
+
+	struct layout_dev_ptr selfptr_headphone;
+	struct layout_dev_ptr selfptr_lineout;
+
+	u32 have_lineout_detect:1,
+	    have_headphone_detect:1,
+	    switch_on_headphone:1,
+	    switch_on_lineout:1;
+};
+
+static LIST_HEAD(layouts_list);
+static int layouts_list_items;
+/* this can go away but only if we allow multiple cards,
+ * make the fabric handle all the card stuff, etc... */
+static struct layout_dev *layout_device;
+
+static int control_info(struct snd_kcontrol *kcontrol,
+			struct snd_ctl_elem_info *uinfo)
+{
+	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
+	uinfo->count = 1;
+	uinfo->value.integer.min = 0;
+	uinfo->value.integer.max = 1;
+	return 0;
+}
+
+#define AMP_CONTROL(n, description)					\
+static int n##_control_get(struct snd_kcontrol *kcontrol,		\
+			   struct snd_ctl_elem_value *ucontrol)		\
+{									\
+	struct gpio_runtime *gpio = snd_kcontrol_chip(kcontrol);	\
+	if (gpio->methods && gpio->methods->get_##n)			\
+		ucontrol->value.integer.value[0] =			\
+			gpio->methods->get_##n(gpio);			\
+	return 0;							\
+}									\
+static int n##_control_put(struct snd_kcontrol *kcontrol,		\
+			   struct snd_ctl_elem_value *ucontrol)		\
+{									\
+	struct gpio_runtime *gpio = snd_kcontrol_chip(kcontrol);	\
+	if (gpio->methods && gpio->methods->get_##n)			\
+		gpio->methods->set_##n(gpio,				\
+			ucontrol->value.integer.value[0]);		\
+	return 1;							\
+}									\
+static struct snd_kcontrol_new n##_ctl = {				\
+	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,				\
+	.name = description,						\
+	.access = SNDRV_CTL_ELEM_ACCESS_READWRITE,                      \
+	.info = control_info,						\
+	.get = n##_control_get,						\
+	.put = n##_control_put,						\
+}
+
+AMP_CONTROL(headphone, "Headphone Switch");
+AMP_CONTROL(speakers, "Speakers Switch");
+AMP_CONTROL(lineout, "Line-Out Switch");
+
+static int detect_choice_get(struct snd_kcontrol *kcontrol,
+			     struct snd_ctl_elem_value *ucontrol)
+{
+	struct layout_dev *ldev = snd_kcontrol_chip(kcontrol);
+
+	switch (kcontrol->private_value) {
+	case 0:
+		ucontrol->value.integer.value[0] = ldev->switch_on_headphone;
+		break;
+	case 1:
+		ucontrol->value.integer.value[0] = ldev->switch_on_lineout;
+		break;
+	default:
+		return -ENODEV;
+	}
+	return 0;
+}
+
+static int detect_choice_put(struct snd_kcontrol *kcontrol,
+			     struct snd_ctl_elem_value *ucontrol)
+{
+	struct layout_dev *ldev = snd_kcontrol_chip(kcontrol);
+
+	switch (kcontrol->private_value) {
+	case 0:
+		ldev->switch_on_headphone = !!ucontrol->value.integer.value[0];
+		break;
+	case 1:
+		ldev->switch_on_lineout = !!ucontrol->value.integer.value[0];
+		break;
+	default:
+		return -ENODEV;
+	}
+	return 1;
+}
+
+static struct snd_kcontrol_new headphone_detect_choice = {
+	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+	.name = "Headphone Detect Autoswitch",
+	.info = control_info,
+	.access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
+	.get = detect_choice_get,
+	.put = detect_choice_put,
+	.private_value = 0,
+};
+
+static struct snd_kcontrol_new lineout_detect_choice = {
+	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+	.name = "Line-Out Detect Autoswitch",
+	.info = control_info,
+	.access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
+	.get = detect_choice_get,
+	.put = detect_choice_put,
+	.private_value = 1,
+};
+
+static int detected_get(struct snd_kcontrol *kcontrol,
+			struct snd_ctl_elem_value *ucontrol)
+{
+	struct layout_dev *ldev = snd_kcontrol_chip(kcontrol);
+	int v;
+
+	switch (kcontrol->private_value) {
+	case 0:
+		v = ldev->gpio.methods->get_detect(&ldev->gpio,
+						   AOA_NOTIFY_HEADPHONE);
+		break;
+	case 1:
+		v = ldev->gpio.methods->get_detect(&ldev->gpio,
+						   AOA_NOTIFY_LINE_OUT);
+		break;
+	default:
+		return -ENODEV;
+	}
+	ucontrol->value.integer.value[0] = v;
+	return 0;
+}
+
+static struct snd_kcontrol_new headphone_detected = {
+	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+	.name = "Headphone Detected",
+	.info = control_info,
+	.access = SNDRV_CTL_ELEM_ACCESS_READ,
+	.get = detected_get,
+	.private_value = 0,
+};
+
+static struct snd_kcontrol_new lineout_detected = {
+	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+	.name = "Line-Out Detected",
+	.info = control_info,
+	.access = SNDRV_CTL_ELEM_ACCESS_READ,
+	.get = detected_get,
+	.private_value = 1,
+};
+
+static int check_codec(struct aoa_codec *codec,
+		       struct layout_dev *ldev,
+		       struct codec_connect_info *cci)
+{
+	u32 *ref;
+	char propname[32];
+	struct codec_connection *cc;
+
+	/* if the codec has a 'codec' node, we require a reference */
+	if (codec->node && (strcmp(codec->node->name, "codec") == 0)) {
+		snprintf(propname, sizeof(propname),
+			 "platform-%s-codec-ref", codec->name);
+		ref = (u32*)get_property(ldev->sound, propname, NULL);
+		if (!ref) {
+			printk(KERN_INFO "snd-aoa-fabric-layout: "
+				"required property %s not present\n", propname);
+			return -ENODEV;
+		}
+		if (*ref != codec->node->linux_phandle) {
+			printk(KERN_INFO "snd-aoa-fabric-layout: "
+				"%s doesn't match!\n", propname);
+			return -ENODEV;
+		}
+	} else {
+		if (layouts_list_items != 1) {
+			printk(KERN_INFO "snd-aoa-fabric-layout: "
+				"more than one soundbus, but no references.\n");
+			return -ENODEV;
+		}
+	}
+	codec->soundbus_dev = ldev->sdev;
+	codec->gpio = &ldev->gpio;
+
+	cc = cci->connections;
+	if (!cc)
+		return -EINVAL;
+
+	printk(KERN_INFO "snd-aoa-fabric-layout: can use this codec\n");
+
+	codec->connected = 0;
+	codec->fabric_data = cc;
+
+	while (cc->connected) {
+		codec->connected |= 1<<cc->codec_bit;
+		cc++;
+	}
+
+	return 0;
+}
+
+static int layout_found_codec(struct aoa_codec *codec)
+{
+	struct layout_dev *ldev;
+	int i;
+
+	list_for_each_entry(ldev, &layouts_list, list) {
+		for (i=0; i<MAX_CODECS_PER_BUS; i++) {
+			if (!ldev->layout->codecs[i].name)
+				continue;
+			if (strcmp(ldev->layout->codecs[i].name, codec->name) == 0) {
+				if (check_codec(codec,
+						ldev,
+						&ldev->layout->codecs[i]) == 0)
+					return 0;
+			}
+		}
+	}
+	return -ENODEV;
+}
+
+static void layout_remove_codec(struct aoa_codec *codec)
+{
+	int i;
+	/* here remove the codec from the layout dev's
+	 * codec reference */
+
+	codec->soundbus_dev = NULL;
+	codec->gpio = NULL;
+	for (i=0; i<MAX_CODECS_PER_BUS; i++) {
+	}
+}
+
+static void layout_notify(void *data)
+{
+	struct layout_dev_ptr *dptr = data;
+	struct layout_dev *ldev;
+	int v, update;
+	struct snd_kcontrol *detected, *c;
+	struct snd_card *card = aoa_get_card();
+
+	ldev = dptr->ptr;
+	if (data == &ldev->selfptr_headphone) {
+		v = ldev->gpio.methods->get_detect(&ldev->gpio, AOA_NOTIFY_HEADPHONE);
+		detected = ldev->headphone_detected_ctrl;
+		update = ldev->switch_on_headphone;
+		if (update) {
+			ldev->gpio.methods->set_speakers(&ldev->gpio, !v);
+			ldev->gpio.methods->set_headphone(&ldev->gpio, v);
+			ldev->gpio.methods->set_lineout(&ldev->gpio, 0);
+		}
+	} else if (data == &ldev->selfptr_lineout) {
+		v = ldev->gpio.methods->get_detect(&ldev->gpio, AOA_NOTIFY_LINE_OUT);
+		detected = ldev->lineout_detected_ctrl;
+		update = ldev->switch_on_lineout;
+		if (update) {
+			ldev->gpio.methods->set_speakers(&ldev->gpio, !v);
+			ldev->gpio.methods->set_headphone(&ldev->gpio, 0);
+			ldev->gpio.methods->set_lineout(&ldev->gpio, v);
+		}
+	} else
+		return;
+
+	if (detected)
+		snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE, &detected->id);
+	if (update) {
+		c = ldev->headphone_ctrl;
+		if (c)
+			snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE, &c->id);
+		c = ldev->speaker_ctrl;
+		if (c)
+			snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE, &c->id);
+		c = ldev->lineout_ctrl;
+		if (c)
+			snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE, &c->id);
+	}
+}
+
+static void layout_attached_codec(struct aoa_codec *codec)
+{
+	struct codec_connection *cc;
+	struct snd_kcontrol *ctl;
+	int headphones, lineout;
+	struct layout_dev *ldev = layout_device;
+
+	/* need to add this codec to our codec array! */
+
+	cc = codec->fabric_data;
+
+	headphones = codec->gpio->methods->get_detect(codec->gpio,
+						      AOA_NOTIFY_HEADPHONE);
+ 	lineout = codec->gpio->methods->get_detect(codec->gpio,
+						   AOA_NOTIFY_LINE_OUT);
+
+	while (cc->connected) {
+		if (cc->connected & CC_SPEAKERS) {
+			if (headphones <= 0 && lineout <= 0)
+				ldev->gpio.methods->set_speakers(codec->gpio, 1);
+			ctl = snd_ctl_new1(&speakers_ctl, codec->gpio);
+			ldev->speaker_ctrl = ctl;
+			aoa_snd_ctl_add(ctl);
+		}
+		if (cc->connected & CC_HEADPHONE) {
+			if (headphones == 1)
+				ldev->gpio.methods->set_headphone(codec->gpio, 1);
+			ctl = snd_ctl_new1(&headphone_ctl, codec->gpio);
+			ldev->headphone_ctrl = ctl;
+			aoa_snd_ctl_add(ctl);
+			ldev->have_headphone_detect =
+				!ldev->gpio.methods
+					->set_notify(&ldev->gpio,
+						     AOA_NOTIFY_HEADPHONE,
+						     layout_notify,
+						     &ldev->selfptr_headphone);
+			if (ldev->have_headphone_detect) {
+				ctl = snd_ctl_new1(&headphone_detect_choice,
+						   ldev);
+				aoa_snd_ctl_add(ctl);
+				ctl = snd_ctl_new1(&headphone_detected,
+						   ldev);
+				ldev->headphone_detected_ctrl = ctl;
+				aoa_snd_ctl_add(ctl);
+			}
+		}
+		if (cc->connected & CC_LINEOUT) {
+			if (lineout == 1)
+				ldev->gpio.methods->set_lineout(codec->gpio, 1);
+			ctl = snd_ctl_new1(&lineout_ctl, codec->gpio);
+			if (cc->connected & CC_LINEOUT_LABELLED_HEADPHONE)
+				strlcpy(ctl->id.name,
+					"Headphone Switch", sizeof(ctl->id.name));
+			ldev->lineout_ctrl = ctl;
+			aoa_snd_ctl_add(ctl);
+			ldev->have_lineout_detect =
+				!ldev->gpio.methods
+					->set_notify(&ldev->gpio,
+						     AOA_NOTIFY_LINE_OUT,
+						     layout_notify,
+						     &ldev->selfptr_lineout);
+			if (ldev->have_lineout_detect) {
+				ctl = snd_ctl_new1(&lineout_detect_choice,
+						   ldev);
+				if (cc->connected & CC_LINEOUT_LABELLED_HEADPHONE)
+					strlcpy(ctl->id.name,
+						"Headphone Detect Autoswitch",
+						sizeof(ctl->id.name));
+				aoa_snd_ctl_add(ctl);
+				ctl = snd_ctl_new1(&lineout_detected,
+						   ldev);
+				if (cc->connected & CC_LINEOUT_LABELLED_HEADPHONE)
+					strlcpy(ctl->id.name,
+						"Headphone Detected",
+						sizeof(ctl->id.name));
+				ldev->lineout_detected_ctrl = ctl;
+				aoa_snd_ctl_add(ctl);
+			}
+		}
+		cc++;
+	}
+	/* now update initial state */
+	if (ldev->have_headphone_detect)
+		layout_notify(&ldev->selfptr_headphone);
+	if (ldev->have_lineout_detect)
+		layout_notify(&ldev->selfptr_lineout);
+}
+
+static struct aoa_fabric layout_fabric = {
+	.name = "SoundByLayout",
+	.owner = THIS_MODULE,
+	.found_codec = layout_found_codec,
+	.remove_codec = layout_remove_codec,
+	.attached_codec = layout_attached_codec,
+};
+
+static int aoa_fabric_layout_probe(struct soundbus_dev *sdev)
+{
+	struct device_node *sound = NULL;
+	unsigned int *layout_id;
+	struct layout *layout;
+	struct layout_dev *ldev = NULL;
+	int err;
+
+	/* hm, currently we can only have one ... */
+	if (layout_device)
+		return -ENODEV;
+
+	/* by breaking out we keep a reference */
+	while ((sound = of_get_next_child(sdev->ofdev.node, sound))) {
+		if (sound->type && strcasecmp(sound->type, "soundchip") == 0)
+			break;
+	}
+	if (!sound) return -ENODEV;
+
+	layout_id = (unsigned int *) get_property(sound, "layout-id", NULL);
+	if (!layout_id)
+		goto outnodev;
+	printk(KERN_INFO "snd-aoa-fabric-layout: found bus with layout %d\n",
+	       *layout_id);
+
+	layout = find_layout_by_id(*layout_id);
+	if (!layout) {
+		printk(KERN_ERR "snd-aoa-fabric-layout: unknown layout\n");
+		goto outnodev;
+	}
+
+	ldev = kzalloc(sizeof(struct layout_dev), GFP_KERNEL);
+	if (!ldev)
+		goto outnodev;
+
+	layout_device = ldev;
+	ldev->sdev = sdev;
+	ldev->sound = sound;
+	ldev->layout = layout;
+	ldev->gpio.node = sound->parent;
+	switch (layout->layout_id) {
+	case 41: /* that unknown machine no one seems to have */
+	case 51: /* PowerBook5,4 */
+	case 58: /* Mac Mini */
+		ldev->gpio.methods = ftr_gpio_methods;
+		printk(KERN_DEBUG
+		       "snd-aoa-fabric-layout: Using direct GPIOs\n");
+		break;
+	default:
+		ldev->gpio.methods = pmf_gpio_methods;
+		printk(KERN_DEBUG
+		       "snd-aoa-fabric-layout: Using PMF GPIOs\n");
+	}
+	ldev->selfptr_headphone.ptr = ldev;
+	ldev->selfptr_lineout.ptr = ldev;
+	sdev->ofdev.dev.driver_data = ldev;
+	list_add(&ldev->list, &layouts_list);
+	layouts_list_items++;
+
+	/* assign these before registering ourselves, so
+	 * callbacks that are done during registration
+	 * already have the values */
+	sdev->pcmid = ldev->layout->pcmid;
+	if (ldev->layout->busname) {
+		sdev->pcmname = ldev->layout->busname;
+	} else {
+		sdev->pcmname = "Master";
+	}
+
+	ldev->gpio.methods->init(&ldev->gpio);
+
+	err = aoa_fabric_register(&layout_fabric);
+	if (err && err != -EALREADY) {
+		printk(KERN_INFO "snd-aoa-fabric-layout: can't use,"
+				 " another fabric is active!\n");
+		goto outlistdel;
+	}
+
+	use_layout(layout);
+	ldev->switch_on_headphone = 1;
+	ldev->switch_on_lineout = 1;
+	return 0;
+ outlistdel:
+	/* we won't be using these then... */
+	ldev->gpio.methods->exit(&ldev->gpio);
+	/* reset if we didn't use it */
+	sdev->pcmname = NULL;
+	sdev->pcmid = -1;
+	list_del(&ldev->list);
+	layouts_list_items--;
+ outnodev:
+ 	if (sound) of_node_put(sound);
+ 	layout_device = NULL;
+ 	if (ldev) kfree(ldev);
+	return -ENODEV;
+}
+
+static int aoa_fabric_layout_remove(struct soundbus_dev *sdev)
+{
+	struct layout_dev *ldev = sdev->ofdev.dev.driver_data;
+	int i;
+
+	for (i=0; i<MAX_CODECS_PER_BUS; i++) {
+		if (ldev->codecs[i]) {
+			aoa_fabric_unlink_codec(ldev->codecs[i]);
+		}
+		ldev->codecs[i] = NULL;
+	}
+	list_del(&ldev->list);
+	layouts_list_items--;
+	of_node_put(ldev->sound);
+
+	ldev->gpio.methods->set_notify(&ldev->gpio,
+				       AOA_NOTIFY_HEADPHONE,
+				       NULL,
+				       NULL);
+	ldev->gpio.methods->set_notify(&ldev->gpio,
+				       AOA_NOTIFY_LINE_OUT,
+				       NULL,
+				       NULL);
+
+	ldev->gpio.methods->exit(&ldev->gpio);
+	layout_device = NULL;
+	kfree(ldev);
+	sdev->pcmid = -1;
+	sdev->pcmname = NULL;
+	return 0;
+}
+
+#ifdef CONFIG_PM
+static int aoa_fabric_layout_suspend(struct soundbus_dev *sdev, pm_message_t state)
+{
+	struct layout_dev *ldev = sdev->ofdev.dev.driver_data;
+
+	printk("aoa_fabric_layout_suspend()\n");
+
+	if (ldev->gpio.methods && ldev->gpio.methods->all_amps_off)
+		ldev->gpio.methods->all_amps_off(&ldev->gpio);
+
+	return 0;
+}
+
+static int aoa_fabric_layout_resume(struct soundbus_dev *sdev)
+{
+	struct layout_dev *ldev = sdev->ofdev.dev.driver_data;
+
+	printk("aoa_fabric_layout_resume()\n");
+
+	if (ldev->gpio.methods && ldev->gpio.methods->all_amps_off)
+		ldev->gpio.methods->all_amps_restore(&ldev->gpio);
+
+	return 0;
+}
+#endif
+
+static struct soundbus_driver aoa_soundbus_driver = {
+	.name = "snd_aoa_soundbus_drv",
+	.owner = THIS_MODULE,
+	.probe = aoa_fabric_layout_probe,
+	.remove = aoa_fabric_layout_remove,
+#ifdef CONFIG_PM
+	.suspend = aoa_fabric_layout_suspend,
+	.resume = aoa_fabric_layout_resume,
+#endif
+};
+
+static int __init aoa_fabric_layout_init(void)
+{
+	int err;
+
+	err = soundbus_register_driver(&aoa_soundbus_driver);
+	if (err)
+		return err;
+	return 0;
+}
+
+static void __exit aoa_fabric_layout_exit(void)
+{
+	soundbus_unregister_driver(&aoa_soundbus_driver);
+	aoa_fabric_unregister(&layout_fabric);
+}
+
+module_init(aoa_fabric_layout_init);
+module_exit(aoa_fabric_layout_exit);
diff --git a/sound/aoa/soundbus/Kconfig b/sound/aoa/soundbus/Kconfig
new file mode 100644
index 000000000..7368b7ddf
--- /dev/null
+++ b/sound/aoa/soundbus/Kconfig
@@ -0,0 +1,15 @@
+config SND_AOA_SOUNDBUS
+	tristate "Apple Soundbus support"
+	depends on SOUND
+	select SND_PCM
+	---help---
+	This option enables the generic driver for the soundbus
+	support on Apple machines.
+	
+	It is required for the sound bus implementations.
+
+config SND_AOA_SOUNDBUS_I2S
+	tristate "I2S bus support"
+	depends on SND_AOA_SOUNDBUS && PCI
+	---help---
+	This option enables support for Apple I2S busses.
diff --git a/sound/aoa/soundbus/Makefile b/sound/aoa/soundbus/Makefile
new file mode 100644
index 000000000..0e61f5aa0
--- /dev/null
+++ b/sound/aoa/soundbus/Makefile
@@ -0,0 +1,3 @@
+obj-$(CONFIG_SND_AOA_SOUNDBUS) += snd-aoa-soundbus.o
+snd-aoa-soundbus-objs := core.o sysfs.o
+obj-$(CONFIG_SND_AOA_SOUNDBUS_I2S) += i2sbus/
diff --git a/sound/aoa/soundbus/core.c b/sound/aoa/soundbus/core.c
new file mode 100644
index 000000000..47b3e3768
--- /dev/null
+++ b/sound/aoa/soundbus/core.c
@@ -0,0 +1,250 @@
+/*
+ * soundbus
+ *
+ * Copyright 2006 Johannes Berg <johannes@sipsolutions.net>
+ *
+ * GPL v2, can be found in COPYING.
+ */
+
+#include <linux/module.h>
+#include "soundbus.h"
+
+MODULE_AUTHOR("Johannes Berg <johannes@sipsolutions.net>");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Apple Soundbus");
+
+struct soundbus_dev *soundbus_dev_get(struct soundbus_dev *dev)
+{
+	struct device *tmp;
+
+	if (!dev)
+		return NULL;
+	tmp = get_device(&dev->ofdev.dev);
+	if (tmp)
+		return to_soundbus_device(tmp);
+	else
+		return NULL;
+}
+EXPORT_SYMBOL_GPL(soundbus_dev_get);
+
+void soundbus_dev_put(struct soundbus_dev *dev)
+{
+	if (dev)
+		put_device(&dev->ofdev.dev);
+}
+EXPORT_SYMBOL_GPL(soundbus_dev_put);
+
+static int soundbus_probe(struct device *dev)
+{
+	int error = -ENODEV;
+	struct soundbus_driver *drv;
+	struct soundbus_dev *soundbus_dev;
+
+	drv = to_soundbus_driver(dev->driver);
+	soundbus_dev = to_soundbus_device(dev);
+
+	if (!drv->probe)
+		return error;
+
+	soundbus_dev_get(soundbus_dev);
+
+	error = drv->probe(soundbus_dev);
+	if (error)
+		soundbus_dev_put(soundbus_dev);
+
+	return error;
+}
+
+
+static int soundbus_uevent(struct device *dev, char **envp, int num_envp,
+			   char *buffer, int buffer_size)
+{
+	struct soundbus_dev * soundbus_dev;
+	struct of_device * of;
+	char *scratch, *compat, *compat2;
+	int i = 0;
+	int length, cplen, cplen2, seen = 0;
+
+	if (!dev)
+		return -ENODEV;
+
+	soundbus_dev = to_soundbus_device(dev);
+	if (!soundbus_dev)
+		return -ENODEV;
+
+	of = &soundbus_dev->ofdev;
+
+	/* stuff we want to pass to /sbin/hotplug */
+	envp[i++] = scratch = buffer;
+	length = scnprintf (scratch, buffer_size, "OF_NAME=%s", of->node->name);
+	++length;
+	buffer_size -= length;
+	if ((buffer_size <= 0) || (i >= num_envp))
+		return -ENOMEM;
+	scratch += length;
+
+	envp[i++] = scratch;
+	length = scnprintf (scratch, buffer_size, "OF_TYPE=%s", of->node->type);
+	++length;
+	buffer_size -= length;
+	if ((buffer_size <= 0) || (i >= num_envp))
+		return -ENOMEM;
+	scratch += length;
+
+	/* Since the compatible field can contain pretty much anything
+	 * it's not really legal to split it out with commas. We split it
+	 * up using a number of environment variables instead. */
+
+	compat = (char *) get_property(of->node, "compatible", &cplen);
+	compat2 = compat;
+	cplen2= cplen;
+	while (compat && cplen > 0) {
+		envp[i++] = scratch;
+		length = scnprintf (scratch, buffer_size,
+				     "OF_COMPATIBLE_%d=%s", seen, compat);
+		++length;
+		buffer_size -= length;
+		if ((buffer_size <= 0) || (i >= num_envp))
+			return -ENOMEM;
+		scratch += length;
+		length = strlen (compat) + 1;
+		compat += length;
+		cplen -= length;
+		seen++;
+	}
+
+	envp[i++] = scratch;
+	length = scnprintf (scratch, buffer_size, "OF_COMPATIBLE_N=%d", seen);
+	++length;
+	buffer_size -= length;
+	if ((buffer_size <= 0) || (i >= num_envp))
+		return -ENOMEM;
+	scratch += length;
+
+	envp[i++] = scratch;
+	length = scnprintf (scratch, buffer_size, "MODALIAS=%s",
+			soundbus_dev->modalias);
+
+	buffer_size -= length;
+	if ((buffer_size <= 0) || (i >= num_envp))
+		return -ENOMEM;
+
+	envp[i] = NULL;
+
+	return 0;
+}
+
+static int soundbus_device_remove(struct device *dev)
+{
+	struct soundbus_dev * soundbus_dev = to_soundbus_device(dev);
+	struct soundbus_driver * drv = to_soundbus_driver(dev->driver);
+
+	if (dev->driver && drv->remove)
+		drv->remove(soundbus_dev);
+	soundbus_dev_put(soundbus_dev);
+
+	return 0;
+}
+
+static void soundbus_device_shutdown(struct device *dev)
+{
+	struct soundbus_dev * soundbus_dev = to_soundbus_device(dev);
+	struct soundbus_driver * drv = to_soundbus_driver(dev->driver);
+
+	if (dev->driver && drv->shutdown)
+		drv->shutdown(soundbus_dev);
+}
+
+#ifdef CONFIG_PM
+
+static int soundbus_device_suspend(struct device *dev, pm_message_t state)
+{
+	struct soundbus_dev * soundbus_dev = to_soundbus_device(dev);
+	struct soundbus_driver * drv = to_soundbus_driver(dev->driver);
+
+	if (dev->driver && drv->suspend)
+		return drv->suspend(soundbus_dev, state);
+	return 0;
+}
+
+static int soundbus_device_resume(struct device * dev)
+{
+	struct soundbus_dev * soundbus_dev = to_soundbus_device(dev);
+	struct soundbus_driver * drv = to_soundbus_driver(dev->driver);
+
+	if (dev->driver && drv->resume)
+		return drv->resume(soundbus_dev);
+	return 0;
+}
+
+#endif /* CONFIG_PM */
+
+extern struct device_attribute soundbus_dev_attrs[];
+
+static struct bus_type soundbus_bus_type = {
+	.name		= "aoa-soundbus",
+	.probe		= soundbus_probe,
+	.uevent		= soundbus_uevent,
+	.remove		= soundbus_device_remove,
+	.shutdown	= soundbus_device_shutdown,
+#ifdef CONFIG_PM
+	.suspend	= soundbus_device_suspend,
+	.resume		= soundbus_device_resume,
+#endif
+	.dev_attrs	= soundbus_dev_attrs,
+};
+
+int soundbus_add_one(struct soundbus_dev *dev)
+{
+	static int devcount;
+
+	/* sanity checks */
+	if (!dev->attach_codec ||
+	    !dev->ofdev.node ||
+	    dev->pcmname ||
+	    dev->pcmid != -1) {
+		printk(KERN_ERR "soundbus: adding device failed sanity check!\n");
+		return -EINVAL;
+	}
+
+	snprintf(dev->ofdev.dev.bus_id, BUS_ID_SIZE, "soundbus:%x", ++devcount);
+	dev->ofdev.dev.bus = &soundbus_bus_type;
+	return of_device_register(&dev->ofdev);
+}
+EXPORT_SYMBOL_GPL(soundbus_add_one);
+
+void soundbus_remove_one(struct soundbus_dev *dev)
+{
+	of_device_unregister(&dev->ofdev);
+}
+EXPORT_SYMBOL_GPL(soundbus_remove_one);
+
+int soundbus_register_driver(struct soundbus_driver *drv)
+{
+	/* initialize common driver fields */
+	drv->driver.name = drv->name;
+	drv->driver.bus = &soundbus_bus_type;
+
+	/* register with core */
+	return driver_register(&drv->driver);
+}
+EXPORT_SYMBOL_GPL(soundbus_register_driver);
+
+void soundbus_unregister_driver(struct soundbus_driver *drv)
+{
+	driver_unregister(&drv->driver);
+}
+EXPORT_SYMBOL_GPL(soundbus_unregister_driver);
+
+static int __init soundbus_init(void)
+{
+	return bus_register(&soundbus_bus_type);
+}
+
+static void __exit soundbus_exit(void)
+{
+	bus_unregister(&soundbus_bus_type);
+}
+
+subsys_initcall(soundbus_init);
+module_exit(soundbus_exit);
diff --git a/sound/aoa/soundbus/i2sbus/Makefile b/sound/aoa/soundbus/i2sbus/Makefile
new file mode 100644
index 000000000..e57a5cf65
--- /dev/null
+++ b/sound/aoa/soundbus/i2sbus/Makefile
@@ -0,0 +1,2 @@
+obj-$(CONFIG_SND_AOA_SOUNDBUS_I2S) += snd-aoa-i2sbus.o
+snd-aoa-i2sbus-objs := i2sbus-core.o i2sbus-pcm.o i2sbus-control.o
diff --git a/sound/aoa/soundbus/i2sbus/i2sbus-control.c b/sound/aoa/soundbus/i2sbus/i2sbus-control.c
new file mode 100644
index 000000000..87beb4ad4
--- /dev/null
+++ b/sound/aoa/soundbus/i2sbus/i2sbus-control.c
@@ -0,0 +1,193 @@
+/*
+ * i2sbus driver -- bus control routines
+ *
+ * Copyright 2006 Johannes Berg <johannes@sipsolutions.net>
+ *
+ * GPL v2, can be found in COPYING.
+ */
+
+#include <linux/kernel.h>
+#include <linux/delay.h>
+
+#include <asm/io.h>
+#include <asm/prom.h>
+#include <asm/macio.h>
+#include <asm/pmac_feature.h>
+#include <asm/pmac_pfunc.h>
+#include <asm/keylargo.h>
+
+#include "i2sbus.h"
+
+int i2sbus_control_init(struct macio_dev* dev, struct i2sbus_control **c)
+{
+	*c = kzalloc(sizeof(struct i2sbus_control), GFP_KERNEL);
+	if (!*c)
+		return -ENOMEM;
+
+	INIT_LIST_HEAD(&(*c)->list);
+
+	(*c)->macio = dev->bus->chip;
+	return 0;
+}
+
+void i2sbus_control_destroy(struct i2sbus_control *c)
+{
+	kfree(c);
+}
+
+/* this is serialised externally */
+int i2sbus_control_add_dev(struct i2sbus_control *c,
+			   struct i2sbus_dev *i2sdev)
+{
+	struct device_node *np;
+
+	np = i2sdev->sound.ofdev.node;
+	i2sdev->enable = pmf_find_function(np, "enable");
+	i2sdev->cell_enable = pmf_find_function(np, "cell-enable");
+	i2sdev->clock_enable = pmf_find_function(np, "clock-enable");
+	i2sdev->cell_disable = pmf_find_function(np, "cell-disable");
+	i2sdev->clock_disable = pmf_find_function(np, "clock-disable");
+
+	/* if the bus number is not 0 or 1 we absolutely need to use
+	 * the platform functions -- there's nothing in Darwin that
+	 * would allow seeing a system behind what the FCRs are then,
+	 * and I don't want to go parsing a bunch of platform functions
+	 * by hand to try finding a system... */
+	if (i2sdev->bus_number != 0 && i2sdev->bus_number != 1 &&
+	    (!i2sdev->enable ||
+	     !i2sdev->cell_enable || !i2sdev->clock_enable ||
+	     !i2sdev->cell_disable || !i2sdev->clock_disable)) {
+		pmf_put_function(i2sdev->enable);
+		pmf_put_function(i2sdev->cell_enable);
+		pmf_put_function(i2sdev->clock_enable);
+		pmf_put_function(i2sdev->cell_disable);
+		pmf_put_function(i2sdev->clock_disable);
+		return -ENODEV;
+	}
+
+	list_add(&i2sdev->item, &c->list);
+
+	return 0;
+}
+
+void i2sbus_control_remove_dev(struct i2sbus_control *c,
+			       struct i2sbus_dev *i2sdev)
+{
+	/* this is serialised externally */
+	list_del(&i2sdev->item);
+	if (list_empty(&c->list))
+		i2sbus_control_destroy(c);
+}
+
+int i2sbus_control_enable(struct i2sbus_control *c,
+			  struct i2sbus_dev *i2sdev)
+{
+	struct pmf_args args = { .count = 0 };
+	struct macio_chip *macio = c->macio;
+
+	if (i2sdev->enable)
+		return pmf_call_one(i2sdev->enable, &args);
+
+	if (macio == NULL || macio->base == NULL)
+		return -ENODEV;
+
+	switch (i2sdev->bus_number) {
+	case 0:
+		/* these need to be locked or done through
+		 * newly created feature calls! */
+		MACIO_BIS(KEYLARGO_FCR1, KL1_I2S0_ENABLE);
+		break;
+	case 1:
+		MACIO_BIS(KEYLARGO_FCR1, KL1_I2S1_ENABLE);
+		break;
+	default:
+		return -ENODEV;
+	}
+	return 0;
+}
+
+int i2sbus_control_cell(struct i2sbus_control *c,
+			struct i2sbus_dev *i2sdev,
+			int enable)
+{
+	struct pmf_args args = { .count = 0 };
+	struct macio_chip *macio = c->macio;
+
+	switch (enable) {
+	case 0:
+		if (i2sdev->cell_disable)
+			return pmf_call_one(i2sdev->cell_disable, &args);
+		break;
+	case 1:
+		if (i2sdev->cell_enable)
+			return pmf_call_one(i2sdev->cell_enable, &args);
+		break;
+	default:
+		printk(KERN_ERR "i2sbus: INVALID CELL ENABLE VALUE\n");
+		return -ENODEV;
+	}
+
+	if (macio == NULL || macio->base == NULL)
+		return -ENODEV;
+
+	switch (i2sdev->bus_number) {
+	case 0:
+		if (enable)
+			MACIO_BIS(KEYLARGO_FCR1, KL1_I2S0_CELL_ENABLE);
+		else
+			MACIO_BIC(KEYLARGO_FCR1, KL1_I2S0_CELL_ENABLE);
+		break;
+	case 1:
+		if (enable)
+			MACIO_BIS(KEYLARGO_FCR1, KL1_I2S1_CELL_ENABLE);
+		else
+			MACIO_BIC(KEYLARGO_FCR1, KL1_I2S1_CELL_ENABLE);
+		break;
+	default:
+		return -ENODEV;
+	}
+	return 0;
+}
+
+int i2sbus_control_clock(struct i2sbus_control *c,
+			 struct i2sbus_dev *i2sdev,
+			 int enable)
+{
+	struct pmf_args args = { .count = 0 };
+	struct macio_chip *macio = c->macio;
+
+	switch (enable) {
+	case 0:
+		if (i2sdev->clock_disable)
+			return pmf_call_one(i2sdev->clock_disable, &args);
+		break;
+	case 1:
+		if (i2sdev->clock_enable)
+			return pmf_call_one(i2sdev->clock_enable, &args);
+		break;
+	default:
+		printk(KERN_ERR "i2sbus: INVALID CLOCK ENABLE VALUE\n");
+		return -ENODEV;
+	}
+
+	if (macio == NULL || macio->base == NULL)
+		return -ENODEV;
+
+	switch (i2sdev->bus_number) {
+	case 0:
+		if (enable)
+			MACIO_BIS(KEYLARGO_FCR1, KL1_I2S0_CLK_ENABLE_BIT);
+		else
+			MACIO_BIC(KEYLARGO_FCR1, KL1_I2S0_CLK_ENABLE_BIT);
+		break;
+	case 1:
+		if (enable)
+			MACIO_BIS(KEYLARGO_FCR1, KL1_I2S1_CLK_ENABLE_BIT);
+		else
+			MACIO_BIC(KEYLARGO_FCR1, KL1_I2S1_CLK_ENABLE_BIT);
+		break;
+	default:
+		return -ENODEV;
+	}
+	return 0;
+}
diff --git a/sound/aoa/soundbus/i2sbus/i2sbus-core.c b/sound/aoa/soundbus/i2sbus/i2sbus-core.c
new file mode 100644
index 000000000..23190aa6b
--- /dev/null
+++ b/sound/aoa/soundbus/i2sbus/i2sbus-core.c
@@ -0,0 +1,455 @@
+/*
+ * i2sbus driver
+ *
+ * Copyright 2006 Johannes Berg <johannes@sipsolutions.net>
+ *
+ * GPL v2, can be found in COPYING.
+ */
+
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/interrupt.h>
+#include <linux/dma-mapping.h>
+
+#include <sound/driver.h>
+#include <sound/core.h>
+
+#include <asm/macio.h>
+#include <asm/dbdma.h>
+
+#include "../soundbus.h"
+#include "i2sbus.h"
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Johannes Berg <johannes@sipsolutions.net>");
+MODULE_DESCRIPTION("Apple Soundbus: I2S support");
+/* for auto-loading, declare that we handle this weird
+ * string that macio puts into the relevant device */
+MODULE_ALIAS("of:Ni2sTi2sC");
+
+static int force;
+module_param(force, int, 0444);
+MODULE_PARM_DESC(force, "Force loading i2sbus even when"
+			" no layout-id property is present");
+
+static struct of_device_id i2sbus_match[] = {
+	{ .name = "i2s" },
+	{ }
+};
+
+static int alloc_dbdma_descriptor_ring(struct i2sbus_dev *i2sdev,
+				       struct dbdma_command_mem *r,
+				       int numcmds)
+{
+	/* one more for rounding */
+	r->size = (numcmds+1) * sizeof(struct dbdma_cmd);
+	/* We use the PCI APIs for now until the generic one gets fixed
+	 * enough or until we get some macio-specific versions
+	 */
+	r->space = dma_alloc_coherent(
+			&macio_get_pci_dev(i2sdev->macio)->dev,
+			r->size,
+			&r->bus_addr,
+			GFP_KERNEL);
+
+	if (!r->space) return -ENOMEM;
+
+	memset(r->space, 0, r->size);
+	r->cmds = (void*)DBDMA_ALIGN(r->space);
+	r->bus_cmd_start = r->bus_addr +
+			   (dma_addr_t)((char*)r->cmds - (char*)r->space);
+
+	return 0;
+}
+
+static void free_dbdma_descriptor_ring(struct i2sbus_dev *i2sdev,
+				       struct dbdma_command_mem *r)
+{
+	if (!r->space) return;
+	
+	dma_free_coherent(&macio_get_pci_dev(i2sdev->macio)->dev,
+			    r->size, r->space, r->bus_addr);
+}
+
+static void i2sbus_release_dev(struct device *dev)
+{
+	struct i2sbus_dev *i2sdev;
+	int i;
+
+	i2sdev = container_of(dev, struct i2sbus_dev, sound.ofdev.dev);
+
+ 	if (i2sdev->intfregs) iounmap(i2sdev->intfregs);
+ 	if (i2sdev->out.dbdma) iounmap(i2sdev->out.dbdma);
+ 	if (i2sdev->in.dbdma) iounmap(i2sdev->in.dbdma);
+	for (i = aoa_resource_i2smmio; i <= aoa_resource_rxdbdma; i++)
+		if (i2sdev->allocated_resource[i])
+			release_and_free_resource(i2sdev->allocated_resource[i]);
+	free_dbdma_descriptor_ring(i2sdev, &i2sdev->out.dbdma_ring);
+	free_dbdma_descriptor_ring(i2sdev, &i2sdev->in.dbdma_ring);
+	for (i = aoa_resource_i2smmio; i <= aoa_resource_rxdbdma; i++)
+		free_irq(i2sdev->interrupts[i], i2sdev);
+	i2sbus_control_remove_dev(i2sdev->control, i2sdev);
+	mutex_destroy(&i2sdev->lock);
+	kfree(i2sdev);
+}
+
+static irqreturn_t i2sbus_bus_intr(int irq, void *devid, struct pt_regs *regs)
+{
+	struct i2sbus_dev *dev = devid;
+	u32 intreg;
+
+	spin_lock(&dev->low_lock);
+	intreg = in_le32(&dev->intfregs->intr_ctl);
+
+	/* acknowledge interrupt reasons */
+	out_le32(&dev->intfregs->intr_ctl, intreg);
+
+	spin_unlock(&dev->low_lock);
+
+	return IRQ_HANDLED;
+}
+
+
+/*
+ * XXX FIXME: We test the layout_id's here to get the proper way of
+ * mapping in various registers, thanks to bugs in Apple device-trees.
+ * We could instead key off the machine model and the name of the i2s
+ * node (i2s-a). This we'll do when we move it all to macio_asic.c
+ * and have that export items for each sub-node too.
+ */
+static int i2sbus_get_and_fixup_rsrc(struct device_node *np, int index,
+				     int layout, struct resource *res)
+{
+	struct device_node *parent;
+	int pindex, rc = -ENXIO;
+	u32 *reg;
+
+	/* Machines with layout 76 and 36 (K2 based) have a weird device
+	 * tree what we need to special case.
+	 * Normal machines just fetch the resource from the i2s-X node.
+	 * Darwin further divides normal machines into old and new layouts
+	 * with a subtely different code path but that doesn't seem necessary
+	 * in practice, they just bloated it. In addition, even on our K2
+	 * case the i2s-modem node, if we ever want to handle it, uses the
+	 * normal layout
+	 */
+	if (layout != 76 && layout != 36)
+		return of_address_to_resource(np, index, res);
+
+	parent = of_get_parent(np);
+	pindex = (index == aoa_resource_i2smmio) ? 0 : 1;
+	rc = of_address_to_resource(parent, pindex, res);
+	if (rc)
+		goto bail;
+	reg = (u32 *)get_property(np, "reg", NULL);
+	if (reg == NULL) {
+		rc = -ENXIO;
+		goto bail;
+	}
+	res->start += reg[index * 2];
+	res->end = res->start + reg[index * 2 + 1] - 1;
+ bail:
+	of_node_put(parent);
+	return rc;
+}
+
+/* FIXME: look at device node refcounting */
+static int i2sbus_add_dev(struct macio_dev *macio,
+			  struct i2sbus_control *control,
+			  struct device_node *np)
+{
+	struct i2sbus_dev *dev;
+	struct device_node *child = NULL, *sound = NULL;
+	struct resource *r;
+	int i, layout = 0, rlen;
+	static const char *rnames[] = { "i2sbus: %s (control)",
+					"i2sbus: %s (tx)",
+					"i2sbus: %s (rx)" };
+	static irqreturn_t (*ints[])(int irq, void *devid,
+				     struct pt_regs *regs) = {
+		i2sbus_bus_intr,
+		i2sbus_tx_intr,
+		i2sbus_rx_intr
+	};
+
+	if (strlen(np->name) != 5)
+		return 0;
+	if (strncmp(np->name, "i2s-", 4))
+		return 0;
+
+	dev = kzalloc(sizeof(struct i2sbus_dev), GFP_KERNEL);
+	if (!dev)
+		return 0;
+
+	i = 0;
+	while ((child = of_get_next_child(np, child))) {
+		if (strcmp(child->name, "sound") == 0) {
+			i++;
+			sound = child;
+		}
+	}
+	if (i == 1) {
+		u32 *layout_id;
+		layout_id = (u32*) get_property(sound, "layout-id", NULL);
+		if (layout_id) {
+			layout = *layout_id;
+			snprintf(dev->sound.modalias, 32,
+				 "sound-layout-%d", layout);
+			force = 1;
+		}
+	}
+	/* for the time being, until we can handle non-layout-id
+	 * things in some fabric, refuse to attach if there is no
+	 * layout-id property or we haven't been forced to attach.
+	 * When there are two i2s busses and only one has a layout-id,
+	 * then this depends on the order, but that isn't important
+	 * either as the second one in that case is just a modem. */
+	if (!force) {
+		kfree(dev);
+		return -ENODEV;
+	}
+
+	mutex_init(&dev->lock);
+	spin_lock_init(&dev->low_lock);
+	dev->sound.ofdev.node = np;
+	dev->sound.ofdev.dma_mask = macio->ofdev.dma_mask;
+	dev->sound.ofdev.dev.dma_mask = &dev->sound.ofdev.dma_mask;
+	dev->sound.ofdev.dev.parent = &macio->ofdev.dev;
+	dev->sound.ofdev.dev.release = i2sbus_release_dev;
+	dev->sound.attach_codec = i2sbus_attach_codec;
+	dev->sound.detach_codec = i2sbus_detach_codec;
+	dev->sound.pcmid = -1;
+	dev->macio = macio;
+	dev->control = control;
+	dev->bus_number = np->name[4] - 'a';
+	INIT_LIST_HEAD(&dev->sound.codec_list);
+
+	for (i = aoa_resource_i2smmio; i <= aoa_resource_rxdbdma; i++) {
+		dev->interrupts[i] = -1;
+		snprintf(dev->rnames[i], sizeof(dev->rnames[i]),
+			 rnames[i], np->name);
+	}
+	for (i = aoa_resource_i2smmio; i <= aoa_resource_rxdbdma; i++) {
+		int irq = irq_of_parse_and_map(np, i);
+		if (request_irq(irq, ints[i], 0, dev->rnames[i], dev))
+			goto err;
+		dev->interrupts[i] = irq;
+	}
+
+
+	/* Resource handling is problematic as some device-trees contain
+	 * useless crap (ugh ugh ugh). We work around that here by calling
+	 * specific functions for calculating the appropriate resources.
+	 *
+	 * This will all be moved to macio_asic.c at one point
+	 */
+	for (i = aoa_resource_i2smmio; i <= aoa_resource_rxdbdma; i++) {
+		if (i2sbus_get_and_fixup_rsrc(np,i,layout,&dev->resources[i]))
+			goto err;
+		/* If only we could use our resource dev->resources[i]...
+		 * but request_resource doesn't know about parents and
+		 * contained resources...
+		 */
+		dev->allocated_resource[i] = 
+			request_mem_region(dev->resources[i].start,
+					   dev->resources[i].end -
+					   dev->resources[i].start + 1,
+					   dev->rnames[i]);
+		if (!dev->allocated_resource[i]) {
+			printk(KERN_ERR "i2sbus: failed to claim resource %d!\n", i);
+			goto err;
+		}
+	}
+
+	r = &dev->resources[aoa_resource_i2smmio];
+	rlen = r->end - r->start + 1;
+	if (rlen < sizeof(struct i2s_interface_regs))
+		goto err;
+	dev->intfregs = ioremap(r->start, rlen);
+
+	r = &dev->resources[aoa_resource_txdbdma];
+	rlen = r->end - r->start + 1;
+	if (rlen < sizeof(struct dbdma_regs))
+		goto err;
+	dev->out.dbdma = ioremap(r->start, rlen);
+
+	r = &dev->resources[aoa_resource_rxdbdma];
+	rlen = r->end - r->start + 1;
+	if (rlen < sizeof(struct dbdma_regs))
+		goto err;
+	dev->in.dbdma = ioremap(r->start, rlen);
+
+	if (!dev->intfregs || !dev->out.dbdma || !dev->in.dbdma)
+		goto err;
+
+	if (alloc_dbdma_descriptor_ring(dev, &dev->out.dbdma_ring,
+					MAX_DBDMA_COMMANDS))
+		goto err;
+	if (alloc_dbdma_descriptor_ring(dev, &dev->in.dbdma_ring,
+					MAX_DBDMA_COMMANDS))
+		goto err;
+
+	if (i2sbus_control_add_dev(dev->control, dev)) {
+		printk(KERN_ERR "i2sbus: control layer didn't like bus\n");
+		goto err;
+	}
+
+	if (soundbus_add_one(&dev->sound)) {
+		printk(KERN_DEBUG "i2sbus: device registration error!\n");
+		goto err;
+	}
+
+	/* enable this cell */
+	i2sbus_control_cell(dev->control, dev, 1);
+	i2sbus_control_enable(dev->control, dev);
+	i2sbus_control_clock(dev->control, dev, 1);
+
+	return 1;
+ err:
+	for (i=0;i<3;i++)
+		if (dev->interrupts[i] != -1)
+			free_irq(dev->interrupts[i], dev);
+	free_dbdma_descriptor_ring(dev, &dev->out.dbdma_ring);
+	free_dbdma_descriptor_ring(dev, &dev->in.dbdma_ring);
+	if (dev->intfregs) iounmap(dev->intfregs);
+	if (dev->out.dbdma) iounmap(dev->out.dbdma);
+	if (dev->in.dbdma) iounmap(dev->in.dbdma);
+	for (i=0;i<3;i++)
+		if (dev->allocated_resource[i])
+			release_and_free_resource(dev->allocated_resource[i]);
+	mutex_destroy(&dev->lock);
+	kfree(dev);
+	return 0;
+}
+
+static int i2sbus_probe(struct macio_dev* dev, const struct of_device_id *match)
+{
+	struct device_node *np = NULL;
+	int got = 0, err;
+	struct i2sbus_control *control = NULL;
+
+	err = i2sbus_control_init(dev, &control);
+	if (err)
+		return err;
+	if (!control) {
+		printk(KERN_ERR "i2sbus_control_init API breakage\n");
+		return -ENODEV;
+	}
+
+	while ((np = of_get_next_child(dev->ofdev.node, np))) {
+		if (device_is_compatible(np, "i2sbus") ||
+		    device_is_compatible(np, "i2s-modem")) {
+			got += i2sbus_add_dev(dev, control, np);
+		}
+	}
+
+	if (!got) {
+		/* found none, clean up */
+		i2sbus_control_destroy(control);
+		return -ENODEV;
+	}
+
+	dev->ofdev.dev.driver_data = control;
+
+	return 0;
+}
+
+static int i2sbus_remove(struct macio_dev* dev)
+{
+	struct i2sbus_control *control = dev->ofdev.dev.driver_data;
+	struct i2sbus_dev *i2sdev, *tmp;
+
+	list_for_each_entry_safe(i2sdev, tmp, &control->list, item)
+		soundbus_remove_one(&i2sdev->sound);
+
+	return 0;
+}
+
+#ifdef CONFIG_PM
+static int i2sbus_suspend(struct macio_dev* dev, pm_message_t state)
+{
+	struct i2sbus_control *control = dev->ofdev.dev.driver_data;
+	struct codec_info_item *cii;
+	struct i2sbus_dev* i2sdev;
+	int err, ret = 0;
+
+	list_for_each_entry(i2sdev, &control->list, item) {
+		/* Notify Alsa */
+		if (i2sdev->sound.pcm) {
+			/* Suspend PCM streams */
+			snd_pcm_suspend_all(i2sdev->sound.pcm);
+			/* Probably useless as we handle
+			 * power transitions ourselves */
+			snd_power_change_state(i2sdev->sound.pcm->card,
+					       SNDRV_CTL_POWER_D3hot);
+		}
+		/* Notify codecs */
+		list_for_each_entry(cii, &i2sdev->sound.codec_list, list) {
+			err = 0;
+			if (cii->codec->suspend)
+				err = cii->codec->suspend(cii, state);
+			if (err)
+				ret = err;
+		}
+	}
+	return ret;
+}
+
+static int i2sbus_resume(struct macio_dev* dev)
+{
+	struct i2sbus_control *control = dev->ofdev.dev.driver_data;
+	struct codec_info_item *cii;
+	struct i2sbus_dev* i2sdev;
+	int err, ret = 0;
+
+	list_for_each_entry(i2sdev, &control->list, item) {
+		/* Notify codecs so they can re-initialize */
+		list_for_each_entry(cii, &i2sdev->sound.codec_list, list) {
+			err = 0;
+			if (cii->codec->resume)
+				err = cii->codec->resume(cii);
+			if (err)
+				ret = err;
+		}
+		/* Notify Alsa */
+		if (i2sdev->sound.pcm) {
+			/* Same comment as above, probably useless */
+			snd_power_change_state(i2sdev->sound.pcm->card,
+					       SNDRV_CTL_POWER_D0);
+		}
+	}
+
+	return ret;
+}
+#endif /* CONFIG_PM */
+
+static int i2sbus_shutdown(struct macio_dev* dev)
+{
+	return 0;
+}
+
+static struct macio_driver i2sbus_drv = {
+	.name = "soundbus-i2s",
+	.owner = THIS_MODULE,
+	.match_table = i2sbus_match,
+	.probe = i2sbus_probe,
+	.remove = i2sbus_remove,
+#ifdef CONFIG_PM
+	.suspend = i2sbus_suspend,
+	.resume = i2sbus_resume,
+#endif
+	.shutdown = i2sbus_shutdown,
+};
+
+static int __init soundbus_i2sbus_init(void)
+{
+	return macio_register_driver(&i2sbus_drv);
+}
+
+static void __exit soundbus_i2sbus_exit(void)
+{
+	macio_unregister_driver(&i2sbus_drv);
+}
+
+module_init(soundbus_i2sbus_init);
+module_exit(soundbus_i2sbus_exit);
diff --git a/sound/aoa/soundbus/i2sbus/i2sbus-interface.h b/sound/aoa/soundbus/i2sbus/i2sbus-interface.h
new file mode 100644
index 000000000..c6b5f5452
--- /dev/null
+++ b/sound/aoa/soundbus/i2sbus/i2sbus-interface.h
@@ -0,0 +1,187 @@
+/*
+ * i2sbus driver -- interface register definitions
+ *
+ * Copyright 2006 Johannes Berg <johannes@sipsolutions.net>
+ *
+ * GPL v2, can be found in COPYING.
+ */
+#ifndef __I2SBUS_INTERFACE_H
+#define __I2SBUS_INTERFACE_H
+
+/* i2s bus control registers, at least what we know about them */
+
+#define __PAD(m,n) u8 __pad##m[n]
+#define _PAD(line, n) __PAD(line, n)
+#define PAD(n) _PAD(__LINE__, (n))
+struct i2s_interface_regs {
+	__le32 intr_ctl;	/* 0x00 */
+	PAD(12);
+	__le32 serial_format;	/* 0x10 */
+	PAD(12);
+	__le32 codec_msg_out;	/* 0x20 */
+	PAD(12);
+	__le32 codec_msg_in;	/* 0x30 */
+	PAD(12);
+	__le32 frame_count;	/* 0x40 */
+	PAD(12);
+	__le32 frame_match;	/* 0x50 */
+	PAD(12);
+	__le32 data_word_sizes;	/* 0x60 */
+	PAD(12);
+	__le32 peak_level_sel;	/* 0x70 */
+	PAD(12);
+	__le32 peak_level_in0;	/* 0x80 */
+	PAD(12);
+	__le32 peak_level_in1;	/* 0x90 */
+	PAD(12);
+	/* total size: 0x100 bytes */
+}  __attribute__((__packed__));
+
+/* interrupt register is just a bitfield with
+ * interrupt enable and pending bits */
+#define I2S_REG_INTR_CTL		0x00
+#	define I2S_INT_FRAME_COUNT		(1<<31)
+#	define I2S_PENDING_FRAME_COUNT		(1<<30)
+#	define I2S_INT_MESSAGE_FLAG		(1<<29)
+#	define I2S_PENDING_MESSAGE_FLAG		(1<<28)
+#	define I2S_INT_NEW_PEAK			(1<<27)
+#	define I2S_PENDING_NEW_PEAK		(1<<26)
+#	define I2S_INT_CLOCKS_STOPPED		(1<<25)
+#	define I2S_PENDING_CLOCKS_STOPPED	(1<<24)
+#	define I2S_INT_EXTERNAL_SYNC_ERROR	(1<<23)
+#	define I2S_PENDING_EXTERNAL_SYNC_ERROR	(1<<22)
+#	define I2S_INT_EXTERNAL_SYNC_OK		(1<<21)
+#	define I2S_PENDING_EXTERNAL_SYNC_OK	(1<<20)
+#	define I2S_INT_NEW_SAMPLE_RATE		(1<<19)
+#	define I2S_PENDING_NEW_SAMPLE_RATE	(1<<18)
+#	define I2S_INT_STATUS_FLAG		(1<<17)
+#	define I2S_PENDING_STATUS_FLAG		(1<<16)
+
+/* serial format register is more interesting :)
+ * It contains:
+ *  - clock source
+ *  - MClk divisor
+ *  - SClk divisor
+ *  - SClk master flag
+ *  - serial format (sony, i2s 64x, i2s 32x, dav, silabs)
+ *  - external sample frequency interrupt (don't understand)
+ *  - external sample frequency
+ */
+#define I2S_REG_SERIAL_FORMAT		0x10
+/* clock source. You get either 18.432, 45.1584 or 49.1520 MHz */
+#	define I2S_SF_CLOCK_SOURCE_SHIFT	30
+#	define I2S_SF_CLOCK_SOURCE_MASK		(3<<I2S_SF_CLOCK_SOURCE_SHIFT)
+#	define I2S_SF_CLOCK_SOURCE_18MHz	(0<<I2S_SF_CLOCK_SOURCE_SHIFT)
+#	define I2S_SF_CLOCK_SOURCE_45MHz	(1<<I2S_SF_CLOCK_SOURCE_SHIFT)
+#	define I2S_SF_CLOCK_SOURCE_49MHz	(2<<I2S_SF_CLOCK_SOURCE_SHIFT)
+/* also, let's define the exact clock speeds here, in Hz */
+#define I2S_CLOCK_SPEED_18MHz	18432000
+#define I2S_CLOCK_SPEED_45MHz	45158400
+#define I2S_CLOCK_SPEED_49MHz	49152000
+/* MClk is the clock that drives the codec, usually called its 'system clock'.
+ * It is derived by taking only every 'divisor' tick of the clock.
+ */
+#	define I2S_SF_MCLKDIV_SHIFT		24
+#	define I2S_SF_MCLKDIV_MASK		(0x1F<<I2S_SF_MCLKDIV_SHIFT)
+#	define I2S_SF_MCLKDIV_1			(0x14<<I2S_SF_MCLKDIV_SHIFT)
+#	define I2S_SF_MCLKDIV_3			(0x13<<I2S_SF_MCLKDIV_SHIFT)
+#	define I2S_SF_MCLKDIV_5			(0x12<<I2S_SF_MCLKDIV_SHIFT)
+#	define I2S_SF_MCLKDIV_14		(0x0E<<I2S_SF_MCLKDIV_SHIFT)
+#	define I2S_SF_MCLKDIV_OTHER(div)	(((div/2-1)<<I2S_SF_MCLKDIV_SHIFT)&I2S_SF_MCLKDIV_MASK)
+static inline int i2s_sf_mclkdiv(int div, int *out)
+{
+	int d;
+
+	switch(div) {
+	case 1: *out |= I2S_SF_MCLKDIV_1; return 0;
+	case 3: *out |= I2S_SF_MCLKDIV_3; return 0;
+	case 5: *out |= I2S_SF_MCLKDIV_5; return 0;
+	case 14: *out |= I2S_SF_MCLKDIV_14; return 0;
+	default:
+		if (div%2) return -1;
+		d = div/2-1;
+		if (d == 0x14 || d == 0x13 || d == 0x12 || d == 0x0E)
+			return -1;
+		*out |= I2S_SF_MCLKDIV_OTHER(div);
+		return 0;
+	}
+}
+/* SClk is the clock that drives the i2s wire bus. Note that it is
+ * derived from the MClk above by taking only every 'divisor' tick
+ * of MClk.
+ */
+#	define I2S_SF_SCLKDIV_SHIFT		20
+#	define I2S_SF_SCLKDIV_MASK		(0xF<<I2S_SF_SCLKDIV_SHIFT)
+#	define I2S_SF_SCLKDIV_1			(8<<I2S_SF_SCLKDIV_SHIFT)
+#	define I2S_SF_SCLKDIV_3			(9<<I2S_SF_SCLKDIV_SHIFT)
+#	define I2S_SF_SCLKDIV_OTHER(div)	(((div/2-1)<<I2S_SF_SCLKDIV_SHIFT)&I2S_SF_SCLKDIV_MASK)
+static inline int i2s_sf_sclkdiv(int div, int *out)
+{
+	int d;
+
+	switch(div) {
+	case 1: *out |= I2S_SF_SCLKDIV_1; return 0;
+	case 3: *out |= I2S_SF_SCLKDIV_3; return 0;
+	default:
+		if (div%2) return -1;
+		d = div/2-1;
+		if (d == 8 || d == 9) return -1;
+		*out |= I2S_SF_SCLKDIV_OTHER(div);
+		return 0;
+	}
+}
+#	define I2S_SF_SCLK_MASTER		(1<<19)
+/* serial format is the way the data is put to the i2s wire bus */
+#	define I2S_SF_SERIAL_FORMAT_SHIFT	16
+#	define I2S_SF_SERIAL_FORMAT_MASK	(7<<I2S_SF_SERIAL_FORMAT_SHIFT)
+#	define I2S_SF_SERIAL_FORMAT_SONY	(0<<I2S_SF_SERIAL_FORMAT_SHIFT)
+#	define I2S_SF_SERIAL_FORMAT_I2S_64X	(1<<I2S_SF_SERIAL_FORMAT_SHIFT)
+#	define I2S_SF_SERIAL_FORMAT_I2S_32X	(2<<I2S_SF_SERIAL_FORMAT_SHIFT)
+#	define I2S_SF_SERIAL_FORMAT_I2S_DAV	(4<<I2S_SF_SERIAL_FORMAT_SHIFT)
+#	define I2S_SF_SERIAL_FORMAT_I2S_SILABS	(5<<I2S_SF_SERIAL_FORMAT_SHIFT)
+/* unknown */
+#	define I2S_SF_EXT_SAMPLE_FREQ_INT_SHIFT	12
+#	define I2S_SF_EXT_SAMPLE_FREQ_INT_MASK	(0xF<<I2S_SF_SAMPLE_FREQ_INT_SHIFT)
+/* probably gives external frequency? */
+#	define I2S_SF_EXT_SAMPLE_FREQ_MASK	0xFFF
+
+/* used to send codec messages, but how isn't clear */
+#define I2S_REG_CODEC_MSG_OUT		0x20
+
+/* used to receive codec messages, but how isn't clear */
+#define I2S_REG_CODEC_MSG_IN		0x30
+
+/* frame count reg isn't clear to me yet, but probably useful */
+#define I2S_REG_FRAME_COUNT		0x40
+
+/* program to some value, and get interrupt if frame count reaches it */
+#define I2S_REG_FRAME_MATCH		0x50
+
+/* this register describes how the bus transfers data */
+#define I2S_REG_DATA_WORD_SIZES		0x60
+/* number of interleaved input channels */
+#	define I2S_DWS_NUM_CHANNELS_IN_SHIFT	24
+#	define I2S_DWS_NUM_CHANNELS_IN_MASK	(0x1F<<I2S_DWS_NUM_CHANNELS_IN_SHIFT)
+/* word size of input data */
+#	define I2S_DWS_DATA_IN_SIZE_SHIFT	16
+#	define I2S_DWS_DATA_IN_16BIT		(0<<I2S_DWS_DATA_IN_SIZE_SHIFT)
+#	define I2S_DWS_DATA_IN_24BIT		(3<<I2S_DWS_DATA_IN_SIZE_SHIFT)
+/* number of interleaved output channels */
+#	define I2S_DWS_NUM_CHANNELS_OUT_SHIFT	8
+#	define I2S_DWS_NUM_CHANNELS_OUT_MASK	(0x1F<<I2S_DWS_NUM_CHANNELS_OUT_SHIFT)
+/* word size of output data */
+#	define I2S_DWS_DATA_OUT_SIZE_SHIFT	0
+#	define I2S_DWS_DATA_OUT_16BIT		(0<<I2S_DWS_DATA_OUT_SIZE_SHIFT)
+#	define I2S_DWS_DATA_OUT_24BIT		(3<<I2S_DWS_DATA_OUT_SIZE_SHIFT)
+
+
+/* unknown */
+#define I2S_REG_PEAK_LEVEL_SEL		0x70
+
+/* unknown */
+#define I2S_REG_PEAK_LEVEL_IN0		0x80
+
+/* unknown */
+#define I2S_REG_PEAK_LEVEL_IN1		0x90
+
+#endif /* __I2SBUS_INTERFACE_H */
diff --git a/sound/aoa/soundbus/i2sbus/i2sbus-pcm.c b/sound/aoa/soundbus/i2sbus/i2sbus-pcm.c
new file mode 100644
index 000000000..3049015a0
--- /dev/null
+++ b/sound/aoa/soundbus/i2sbus/i2sbus-pcm.c
@@ -0,0 +1,1021 @@
+/*
+ * i2sbus driver -- pcm routines
+ *
+ * Copyright 2006 Johannes Berg <johannes@sipsolutions.net>
+ *
+ * GPL v2, can be found in COPYING.
+ */
+
+#include <asm/io.h>
+#include <linux/delay.h>
+/* So apparently there's a reason for requiring driver.h
+ * to be included first, even if I don't know it... */
+#include <sound/driver.h>
+#include <sound/core.h>
+#include <asm/macio.h>
+#include <linux/pci.h>
+#include "../soundbus.h"
+#include "i2sbus.h"
+
+static inline void get_pcm_info(struct i2sbus_dev *i2sdev, int in,
+				struct pcm_info **pi, struct pcm_info **other)
+{
+	if (in) {
+		if (pi)
+			*pi = &i2sdev->in;
+		if (other)
+			*other = &i2sdev->out;
+	} else {
+		if (pi)
+			*pi = &i2sdev->out;
+		if (other)
+			*other = &i2sdev->in;
+	}
+}
+
+static int clock_and_divisors(int mclk, int sclk, int rate, int *out)
+{
+	/* sclk must be derived from mclk! */
+	if (mclk % sclk)
+		return -1;
+	/* derive sclk register value */
+	if (i2s_sf_sclkdiv(mclk / sclk, out))
+		return -1;
+
+	if (I2S_CLOCK_SPEED_18MHz % (rate * mclk) == 0) {
+		if (!i2s_sf_mclkdiv(I2S_CLOCK_SPEED_18MHz / (rate * mclk), out)) {
+			*out |= I2S_SF_CLOCK_SOURCE_18MHz;
+			return 0;
+		}
+	}
+	if (I2S_CLOCK_SPEED_45MHz % (rate * mclk) == 0) {
+		if (!i2s_sf_mclkdiv(I2S_CLOCK_SPEED_45MHz / (rate * mclk), out)) {
+			*out |= I2S_SF_CLOCK_SOURCE_45MHz;
+			return 0;
+		}
+	}
+	if (I2S_CLOCK_SPEED_49MHz % (rate * mclk) == 0) {
+		if (!i2s_sf_mclkdiv(I2S_CLOCK_SPEED_49MHz / (rate * mclk), out)) {
+			*out |= I2S_SF_CLOCK_SOURCE_49MHz;
+			return 0;
+		}
+	}
+	return -1;
+}
+
+#define CHECK_RATE(rate)						\
+	do { if (rates & SNDRV_PCM_RATE_ ##rate) {			\
+		int dummy;						\
+		if (clock_and_divisors(sysclock_factor,			\
+				       bus_factor, rate, &dummy))	\
+			rates &= ~SNDRV_PCM_RATE_ ##rate;		\
+	} } while (0)
+
+static int i2sbus_pcm_open(struct i2sbus_dev *i2sdev, int in)
+{
+	struct pcm_info *pi, *other;
+	struct soundbus_dev *sdev;
+	int masks_inited = 0, err;
+	struct codec_info_item *cii, *rev;
+	struct snd_pcm_hardware *hw;
+	u64 formats = 0;
+	unsigned int rates = 0;
+	struct transfer_info v;
+	int result = 0;
+	int bus_factor = 0, sysclock_factor = 0;
+	int found_this;
+
+	mutex_lock(&i2sdev->lock);
+
+	get_pcm_info(i2sdev, in, &pi, &other);
+
+	hw = &pi->substream->runtime->hw;
+	sdev = &i2sdev->sound;
+
+	if (pi->active) {
+		/* alsa messed up */
+		result = -EBUSY;
+		goto out_unlock;
+	}
+
+	/* we now need to assign the hw */
+	list_for_each_entry(cii, &sdev->codec_list, list) {
+		struct transfer_info *ti = cii->codec->transfers;
+		bus_factor = cii->codec->bus_factor;
+		sysclock_factor = cii->codec->sysclock_factor;
+		while (ti->formats && ti->rates) {
+			v = *ti;
+			if (ti->transfer_in == in
+			    && cii->codec->usable(cii, ti, &v)) {
+				if (masks_inited) {
+					formats &= v.formats;
+					rates &= v.rates;
+				} else {
+					formats = v.formats;
+					rates = v.rates;
+					masks_inited = 1;
+				}
+			}
+			ti++;
+		}
+	}
+	if (!masks_inited || !bus_factor || !sysclock_factor) {
+		result = -ENODEV;
+		goto out_unlock;
+	}
+	/* bus dependent stuff */
+	hw->info = SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID |
+		   SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_RESUME;
+
+	CHECK_RATE(5512);
+	CHECK_RATE(8000);
+	CHECK_RATE(11025);
+	CHECK_RATE(16000);
+	CHECK_RATE(22050);
+	CHECK_RATE(32000);
+	CHECK_RATE(44100);
+	CHECK_RATE(48000);
+	CHECK_RATE(64000);
+	CHECK_RATE(88200);
+	CHECK_RATE(96000);
+	CHECK_RATE(176400);
+	CHECK_RATE(192000);
+	hw->rates = rates;
+
+	/* well. the codec might want 24 bits only, and we'll
+	 * ever only transfer 24 bits, but they are top-aligned!
+	 * So for alsa, we claim that we're doing full 32 bit
+	 * while in reality we'll ignore the lower 8 bits of
+	 * that when doing playback (they're transferred as 0
+	 * as far as I know, no codecs we have are 32-bit capable
+	 * so I can't really test) and when doing recording we'll
+	 * always have those lower 8 bits recorded as 0 */
+	if (formats & SNDRV_PCM_FMTBIT_S24_BE)
+		formats |= SNDRV_PCM_FMTBIT_S32_BE;
+	if (formats & SNDRV_PCM_FMTBIT_U24_BE)
+		formats |= SNDRV_PCM_FMTBIT_U32_BE;
+	/* now mask off what we can support. I suppose we could
+	 * also support S24_3LE and some similar formats, but I
+	 * doubt there's a codec that would be able to use that,
+	 * so we don't support it here. */
+	hw->formats = formats & (SNDRV_PCM_FMTBIT_S16_BE |
+				 SNDRV_PCM_FMTBIT_U16_BE |
+				 SNDRV_PCM_FMTBIT_S32_BE |
+				 SNDRV_PCM_FMTBIT_U32_BE);
+
+	/* we need to set the highest and lowest rate possible.
+	 * These are the highest and lowest rates alsa can
+	 * support properly in its bitfield.
+	 * Below, we'll use that to restrict to the rate
+	 * currently in use (if any). */
+	hw->rate_min = 5512;
+	hw->rate_max = 192000;
+	/* if the other stream is active, then we can only
+	 * support what it is currently using.
+	 * FIXME: I lied. This comment is wrong. We can support
+	 * anything that works with the same serial format, ie.
+	 * when recording 24 bit sound we can well play 16 bit
+	 * sound at the same time iff using the same transfer mode.
+	 */
+	if (other->active) {
+		/* FIXME: is this guaranteed by the alsa api? */
+		hw->formats &= (1ULL << i2sdev->format);
+		/* see above, restrict rates to the one we already have */
+		hw->rate_min = i2sdev->rate;
+		hw->rate_max = i2sdev->rate;
+	}
+
+	hw->channels_min = 2;
+	hw->channels_max = 2;
+	/* these are somewhat arbitrary */
+	hw->buffer_bytes_max = 131072;
+	hw->period_bytes_min = 256;
+	hw->period_bytes_max = 16384;
+	hw->periods_min = 3;
+	hw->periods_max = MAX_DBDMA_COMMANDS;
+	list_for_each_entry(cii, &sdev->codec_list, list) {
+		if (cii->codec->open) {
+			err = cii->codec->open(cii, pi->substream);
+			if (err) {
+				result = err;
+				/* unwind */
+				found_this = 0;
+				list_for_each_entry_reverse(rev,
+				    &sdev->codec_list, list) {
+					if (found_this && rev->codec->close) {
+						rev->codec->close(rev,
+								pi->substream);
+					}
+					if (rev == cii)
+						found_this = 1;
+				}
+				goto out_unlock;
+			}
+		}
+	}
+
+ out_unlock:
+	mutex_unlock(&i2sdev->lock);
+	return result;
+}
+
+#undef CHECK_RATE
+
+static int i2sbus_pcm_close(struct i2sbus_dev *i2sdev, int in)
+{
+	struct codec_info_item *cii;
+	struct pcm_info *pi;
+	int err = 0, tmp;
+
+	mutex_lock(&i2sdev->lock);
+
+	get_pcm_info(i2sdev, in, &pi, NULL);
+
+	list_for_each_entry(cii, &i2sdev->sound.codec_list, list) {
+		if (cii->codec->close) {
+			tmp = cii->codec->close(cii, pi->substream);
+			if (tmp)
+				err = tmp;
+		}
+	}
+
+	pi->substream = NULL;
+	pi->active = 0;
+	mutex_unlock(&i2sdev->lock);
+	return err;
+}
+
+static int i2sbus_hw_params(struct snd_pcm_substream *substream,
+			    struct snd_pcm_hw_params *params)
+{
+	return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(params));
+}
+
+static int i2sbus_hw_free(struct snd_pcm_substream *substream)
+{
+	snd_pcm_lib_free_pages(substream);
+	return 0;
+}
+
+static int i2sbus_pcm_prepare(struct i2sbus_dev *i2sdev, int in)
+{
+	/* whee. Hard work now. The user has selected a bitrate
+	 * and bit format, so now we have to program our
+	 * I2S controller appropriately. */
+	struct snd_pcm_runtime *runtime;
+	struct dbdma_cmd *command;
+	int i, periodsize;
+	dma_addr_t offset;
+	struct bus_info bi;
+	struct codec_info_item *cii;
+	int sfr = 0;		/* serial format register */
+	int dws = 0;		/* data word sizes reg */
+	int input_16bit;
+	struct pcm_info *pi, *other;
+	int cnt;
+	int result = 0;
+
+	mutex_lock(&i2sdev->lock);
+
+	get_pcm_info(i2sdev, in, &pi, &other);
+
+	if (pi->dbdma_ring.running) {
+		result = -EBUSY;
+		goto out_unlock;
+	}
+
+	runtime = pi->substream->runtime;
+	pi->active = 1;
+	if (other->active &&
+	    ((i2sdev->format != runtime->format)
+	     || (i2sdev->rate != runtime->rate))) {
+		result = -EINVAL;
+		goto out_unlock;
+	}
+
+	i2sdev->format = runtime->format;
+	i2sdev->rate = runtime->rate;
+
+	periodsize = snd_pcm_lib_period_bytes(pi->substream);
+	pi->current_period = 0;
+
+	/* generate dbdma command ring first */
+	command = pi->dbdma_ring.cmds;
+	offset = runtime->dma_addr;
+	for (i = 0; i < pi->substream->runtime->periods;
+	     i++, command++, offset += periodsize) {
+		memset(command, 0, sizeof(struct dbdma_cmd));
+		command->command =
+		    cpu_to_le16((in ? INPUT_MORE : OUTPUT_MORE) | INTR_ALWAYS);
+		command->phy_addr = cpu_to_le32(offset);
+		command->req_count = cpu_to_le16(periodsize);
+		command->xfer_status = cpu_to_le16(0);
+	}
+	/* last one branches back to first */
+	command--;
+	command->command |= cpu_to_le16(BR_ALWAYS);
+	command->cmd_dep = cpu_to_le32(pi->dbdma_ring.bus_cmd_start);
+
+	/* ok, let's set the serial format and stuff */
+	switch (runtime->format) {
+	/* 16 bit formats */
+	case SNDRV_PCM_FORMAT_S16_BE:
+	case SNDRV_PCM_FORMAT_U16_BE:
+		/* FIXME: if we add different bus factors we need to
+		 * do more here!! */
+		bi.bus_factor = 0;
+		list_for_each_entry(cii, &i2sdev->sound.codec_list, list) {
+			bi.bus_factor = cii->codec->bus_factor;
+			break;
+		}
+		if (!bi.bus_factor) {
+			result = -ENODEV;
+			goto out_unlock;
+		}
+		input_16bit = 1;
+		break;
+	case SNDRV_PCM_FORMAT_S32_BE:
+	case SNDRV_PCM_FORMAT_U32_BE:
+		/* force 64x bus speed, otherwise the data cannot be
+		 * transferred quickly enough! */
+		bi.bus_factor = 64;
+		input_16bit = 0;
+		break;
+	default:
+		result = -EINVAL;
+		goto out_unlock;
+	}
+	/* we assume all sysclocks are the same! */
+	list_for_each_entry(cii, &i2sdev->sound.codec_list, list) {
+		bi.sysclock_factor = cii->codec->sysclock_factor;
+		break;
+	}
+
+	if (clock_and_divisors(bi.sysclock_factor,
+			       bi.bus_factor,
+			       runtime->rate,
+			       &sfr) < 0) {
+		result = -EINVAL;
+		goto out_unlock;
+	}
+	switch (bi.bus_factor) {
+	case 32:
+		sfr |= I2S_SF_SERIAL_FORMAT_I2S_32X;
+		break;
+	case 64:
+		sfr |= I2S_SF_SERIAL_FORMAT_I2S_64X;
+		break;
+	}
+	/* FIXME: THIS ASSUMES MASTER ALL THE TIME */
+	sfr |= I2S_SF_SCLK_MASTER;
+
+	list_for_each_entry(cii, &i2sdev->sound.codec_list, list) {
+		int err = 0;
+		if (cii->codec->prepare)
+			err = cii->codec->prepare(cii, &bi, pi->substream);
+		if (err) {
+			result = err;
+			goto out_unlock;
+		}
+	}
+	/* codecs are fine with it, so set our clocks */
+	if (input_16bit)
+		dws =	(2 << I2S_DWS_NUM_CHANNELS_IN_SHIFT) |
+			(2 << I2S_DWS_NUM_CHANNELS_OUT_SHIFT) |
+			I2S_DWS_DATA_IN_16BIT | I2S_DWS_DATA_OUT_16BIT;
+	else
+		dws =	(2 << I2S_DWS_NUM_CHANNELS_IN_SHIFT) |
+			(2 << I2S_DWS_NUM_CHANNELS_OUT_SHIFT) |
+			I2S_DWS_DATA_IN_24BIT | I2S_DWS_DATA_OUT_24BIT;
+
+	/* early exit if already programmed correctly */
+	/* not locking these is fine since we touch them only in this function */
+	if (in_le32(&i2sdev->intfregs->serial_format) == sfr
+	 && in_le32(&i2sdev->intfregs->data_word_sizes) == dws)
+		goto out_unlock;
+
+	/* let's notify the codecs about clocks going away.
+	 * For now we only do mastering on the i2s cell... */
+	list_for_each_entry(cii, &i2sdev->sound.codec_list, list)
+		if (cii->codec->switch_clock)
+			cii->codec->switch_clock(cii, CLOCK_SWITCH_PREPARE_SLAVE);
+
+	i2sbus_control_enable(i2sdev->control, i2sdev);
+	i2sbus_control_cell(i2sdev->control, i2sdev, 1);
+
+	out_le32(&i2sdev->intfregs->intr_ctl, I2S_PENDING_CLOCKS_STOPPED);
+
+	i2sbus_control_clock(i2sdev->control, i2sdev, 0);
+
+	msleep(1);
+
+	/* wait for clock stopped. This can apparently take a while... */
+	cnt = 100;
+	while (cnt-- &&
+	    !(in_le32(&i2sdev->intfregs->intr_ctl) & I2S_PENDING_CLOCKS_STOPPED)) {
+		msleep(5);
+	}
+	out_le32(&i2sdev->intfregs->intr_ctl, I2S_PENDING_CLOCKS_STOPPED);
+
+	/* not locking these is fine since we touch them only in this function */
+	out_le32(&i2sdev->intfregs->serial_format, sfr);
+	out_le32(&i2sdev->intfregs->data_word_sizes, dws);
+
+        i2sbus_control_enable(i2sdev->control, i2sdev);
+        i2sbus_control_cell(i2sdev->control, i2sdev, 1);
+        i2sbus_control_clock(i2sdev->control, i2sdev, 1);
+	msleep(1);
+
+	list_for_each_entry(cii, &i2sdev->sound.codec_list, list)
+		if (cii->codec->switch_clock)
+			cii->codec->switch_clock(cii, CLOCK_SWITCH_SLAVE);
+
+ out_unlock:
+	mutex_unlock(&i2sdev->lock);
+	return result;
+}
+
+static struct dbdma_cmd STOP_CMD = {
+	.command = __constant_cpu_to_le16(DBDMA_STOP),
+};
+
+static int i2sbus_pcm_trigger(struct i2sbus_dev *i2sdev, int in, int cmd)
+{
+	struct codec_info_item *cii;
+	struct pcm_info *pi;
+	int timeout;
+	struct dbdma_cmd tmp;
+	int result = 0;
+	unsigned long flags;
+
+	spin_lock_irqsave(&i2sdev->low_lock, flags);
+
+	get_pcm_info(i2sdev, in, &pi, NULL);
+
+	switch (cmd) {
+	case SNDRV_PCM_TRIGGER_START:
+	case SNDRV_PCM_TRIGGER_RESUME:
+		if (pi->dbdma_ring.running) {
+			result = -EALREADY;
+			goto out_unlock;
+		}
+		list_for_each_entry(cii, &i2sdev->sound.codec_list, list)
+			if (cii->codec->start)
+				cii->codec->start(cii, pi->substream);
+		pi->dbdma_ring.running = 1;
+
+		/* reset dma engine */
+		out_le32(&pi->dbdma->control,
+			 0 | (RUN | PAUSE | FLUSH | WAKE) << 16);
+		timeout = 100;
+		while (in_le32(&pi->dbdma->status) & RUN && timeout--)
+			udelay(1);
+		if (timeout <= 0) {
+			printk(KERN_ERR
+			       "i2sbus: error waiting for dma reset\n");
+			result = -ENXIO;
+			goto out_unlock;
+		}
+
+		/* write dma command buffer address to the dbdma chip */
+		out_le32(&pi->dbdma->cmdptr, pi->dbdma_ring.bus_cmd_start);
+		/* post PCI write */
+		mb();
+		(void)in_le32(&pi->dbdma->status);
+
+		/* change first command to STOP */
+		tmp = *pi->dbdma_ring.cmds;
+		*pi->dbdma_ring.cmds = STOP_CMD;
+
+		/* set running state, remember that the first command is STOP */
+		out_le32(&pi->dbdma->control, RUN | (RUN << 16));
+		timeout = 100;
+		/* wait for STOP to be executed */
+		while (in_le32(&pi->dbdma->status) & ACTIVE && timeout--)
+			udelay(1);
+		if (timeout <= 0) {
+			printk(KERN_ERR "i2sbus: error waiting for dma stop\n");
+			result = -ENXIO;
+			goto out_unlock;
+		}
+		/* again, write dma command buffer address to the dbdma chip,
+		 * this time of the first real command */
+		*pi->dbdma_ring.cmds = tmp;
+		out_le32(&pi->dbdma->cmdptr, pi->dbdma_ring.bus_cmd_start);
+		/* post write */
+		mb();
+		(void)in_le32(&pi->dbdma->status);
+
+		/* reset dma engine again */
+		out_le32(&pi->dbdma->control,
+			 0 | (RUN | PAUSE | FLUSH | WAKE) << 16);
+		timeout = 100;
+		while (in_le32(&pi->dbdma->status) & RUN && timeout--)
+			udelay(1);
+		if (timeout <= 0) {
+			printk(KERN_ERR
+			       "i2sbus: error waiting for dma reset\n");
+			result = -ENXIO;
+			goto out_unlock;
+		}
+
+		/* wake up the chip with the next descriptor */
+		out_le32(&pi->dbdma->control,
+			 (RUN | WAKE) | ((RUN | WAKE) << 16));
+		/* get the frame count  */
+		pi->frame_count = in_le32(&i2sdev->intfregs->frame_count);
+
+		/* off you go! */
+		break;
+	case SNDRV_PCM_TRIGGER_STOP:
+	case SNDRV_PCM_TRIGGER_SUSPEND:
+		if (!pi->dbdma_ring.running) {
+			result = -EALREADY;
+			goto out_unlock;
+		}
+
+		/* turn off all relevant bits */
+		out_le32(&pi->dbdma->control,
+			 (RUN | WAKE | FLUSH | PAUSE) << 16);
+		{
+			/* FIXME: move to own function */
+			int timeout = 5000;
+			while ((in_le32(&pi->dbdma->status) & RUN)
+			       && --timeout > 0)
+				udelay(1);
+			if (!timeout)
+				printk(KERN_ERR
+				       "i2sbus: timed out turning "
+				       "off dbdma engine!\n");
+		}
+
+		pi->dbdma_ring.running = 0;
+		list_for_each_entry(cii, &i2sdev->sound.codec_list, list)
+			if (cii->codec->stop)
+				cii->codec->stop(cii, pi->substream);
+		break;
+	default:
+		result = -EINVAL;
+		goto out_unlock;
+	}
+
+ out_unlock:
+	spin_unlock_irqrestore(&i2sdev->low_lock, flags);
+	return result;
+}
+
+static snd_pcm_uframes_t i2sbus_pcm_pointer(struct i2sbus_dev *i2sdev, int in)
+{
+	struct pcm_info *pi;
+	u32 fc;
+
+	get_pcm_info(i2sdev, in, &pi, NULL);
+
+	fc = in_le32(&i2sdev->intfregs->frame_count);
+	fc = fc - pi->frame_count;
+
+	return (bytes_to_frames(pi->substream->runtime,
+			pi->current_period *
+			snd_pcm_lib_period_bytes(pi->substream))
+		+ fc) % pi->substream->runtime->buffer_size;
+}
+
+static inline void handle_interrupt(struct i2sbus_dev *i2sdev, int in)
+{
+	struct pcm_info *pi;
+	u32 fc;
+	u32 delta;
+
+	spin_lock(&i2sdev->low_lock);
+	get_pcm_info(i2sdev, in, &pi, NULL);
+
+	if (!pi->dbdma_ring.running) {
+		/* there was still an interrupt pending
+		 * while we stopped. or maybe another
+		 * processor (not the one that was stopping
+		 * the DMA engine) was spinning above
+		 * waiting for the lock. */
+		goto out_unlock;
+	}
+
+	fc = in_le32(&i2sdev->intfregs->frame_count);
+	/* a counter overflow does not change the calculation. */
+	delta = fc - pi->frame_count;
+
+	/* update current_period */
+	while (delta >= pi->substream->runtime->period_size) {
+		pi->current_period++;
+		delta = delta - pi->substream->runtime->period_size;
+	}
+
+	if (unlikely(delta)) {
+		/* Some interrupt came late, so check the dbdma.
+		 * This special case exists to syncronize the frame_count with
+		 * the dbdma transfer, but is hit every once in a while. */
+		int period;
+
+		period = (in_le32(&pi->dbdma->cmdptr)
+		        - pi->dbdma_ring.bus_cmd_start)
+				/ sizeof(struct dbdma_cmd);
+		pi->current_period = pi->current_period
+					% pi->substream->runtime->periods;
+
+		while (pi->current_period != period) {
+			pi->current_period++;
+			pi->current_period %= pi->substream->runtime->periods;
+			/* Set delta to zero, as the frame_count value is too
+			 * high (otherwise the code path will not be executed).
+			 * This corrects the fact that the frame_count is too
+			 * low at the beginning due to buffering. */
+			delta = 0;
+		}
+	}
+
+	pi->frame_count = fc - delta;
+	pi->current_period %= pi->substream->runtime->periods;
+
+	spin_unlock(&i2sdev->low_lock);
+	/* may call _trigger again, hence needs to be unlocked */
+	snd_pcm_period_elapsed(pi->substream);
+	return;
+ out_unlock:
+	spin_unlock(&i2sdev->low_lock);
+}
+
+irqreturn_t i2sbus_tx_intr(int irq, void *devid, struct pt_regs *regs)
+{
+	handle_interrupt((struct i2sbus_dev *)devid, 0);
+	return IRQ_HANDLED;
+}
+
+irqreturn_t i2sbus_rx_intr(int irq, void *devid, struct pt_regs * regs)
+{
+	handle_interrupt((struct i2sbus_dev *)devid, 1);
+	return IRQ_HANDLED;
+}
+
+static int i2sbus_playback_open(struct snd_pcm_substream *substream)
+{
+	struct i2sbus_dev *i2sdev = snd_pcm_substream_chip(substream);
+
+	if (!i2sdev)
+		return -EINVAL;
+	i2sdev->out.substream = substream;
+	return i2sbus_pcm_open(i2sdev, 0);
+}
+
+static int i2sbus_playback_close(struct snd_pcm_substream *substream)
+{
+	struct i2sbus_dev *i2sdev = snd_pcm_substream_chip(substream);
+	int err;
+
+	if (!i2sdev)
+		return -EINVAL;
+	if (i2sdev->out.substream != substream)
+		return -EINVAL;
+	err = i2sbus_pcm_close(i2sdev, 0);
+	if (!err)
+		i2sdev->out.substream = NULL;
+	return err;
+}
+
+static int i2sbus_playback_prepare(struct snd_pcm_substream *substream)
+{
+	struct i2sbus_dev *i2sdev = snd_pcm_substream_chip(substream);
+
+	if (!i2sdev)
+		return -EINVAL;
+	if (i2sdev->out.substream != substream)
+		return -EINVAL;
+	return i2sbus_pcm_prepare(i2sdev, 0);
+}
+
+static int i2sbus_playback_trigger(struct snd_pcm_substream *substream, int cmd)
+{
+	struct i2sbus_dev *i2sdev = snd_pcm_substream_chip(substream);
+
+	if (!i2sdev)
+		return -EINVAL;
+	if (i2sdev->out.substream != substream)
+		return -EINVAL;
+	return i2sbus_pcm_trigger(i2sdev, 0, cmd);
+}
+
+static snd_pcm_uframes_t i2sbus_playback_pointer(struct snd_pcm_substream
+						 *substream)
+{
+	struct i2sbus_dev *i2sdev = snd_pcm_substream_chip(substream);
+
+	if (!i2sdev)
+		return -EINVAL;
+	if (i2sdev->out.substream != substream)
+		return 0;
+	return i2sbus_pcm_pointer(i2sdev, 0);
+}
+
+static struct snd_pcm_ops i2sbus_playback_ops = {
+	.open =		i2sbus_playback_open,
+	.close =	i2sbus_playback_close,
+	.ioctl =	snd_pcm_lib_ioctl,
+	.hw_params =	i2sbus_hw_params,
+	.hw_free =	i2sbus_hw_free,
+	.prepare =	i2sbus_playback_prepare,
+	.trigger =	i2sbus_playback_trigger,
+	.pointer =	i2sbus_playback_pointer,
+};
+
+static int i2sbus_record_open(struct snd_pcm_substream *substream)
+{
+	struct i2sbus_dev *i2sdev = snd_pcm_substream_chip(substream);
+
+	if (!i2sdev)
+		return -EINVAL;
+	i2sdev->in.substream = substream;
+	return i2sbus_pcm_open(i2sdev, 1);
+}
+
+static int i2sbus_record_close(struct snd_pcm_substream *substream)
+{
+	struct i2sbus_dev *i2sdev = snd_pcm_substream_chip(substream);
+	int err;
+
+	if (!i2sdev)
+		return -EINVAL;
+	if (i2sdev->in.substream != substream)
+		return -EINVAL;
+	err = i2sbus_pcm_close(i2sdev, 1);
+	if (!err)
+		i2sdev->in.substream = NULL;
+	return err;
+}
+
+static int i2sbus_record_prepare(struct snd_pcm_substream *substream)
+{
+	struct i2sbus_dev *i2sdev = snd_pcm_substream_chip(substream);
+
+	if (!i2sdev)
+		return -EINVAL;
+	if (i2sdev->in.substream != substream)
+		return -EINVAL;
+	return i2sbus_pcm_prepare(i2sdev, 1);
+}
+
+static int i2sbus_record_trigger(struct snd_pcm_substream *substream, int cmd)
+{
+	struct i2sbus_dev *i2sdev = snd_pcm_substream_chip(substream);
+
+	if (!i2sdev)
+		return -EINVAL;
+	if (i2sdev->in.substream != substream)
+		return -EINVAL;
+	return i2sbus_pcm_trigger(i2sdev, 1, cmd);
+}
+
+static snd_pcm_uframes_t i2sbus_record_pointer(struct snd_pcm_substream
+					       *substream)
+{
+	struct i2sbus_dev *i2sdev = snd_pcm_substream_chip(substream);
+
+	if (!i2sdev)
+		return -EINVAL;
+	if (i2sdev->in.substream != substream)
+		return 0;
+	return i2sbus_pcm_pointer(i2sdev, 1);
+}
+
+static struct snd_pcm_ops i2sbus_record_ops = {
+	.open =		i2sbus_record_open,
+	.close =	i2sbus_record_close,
+	.ioctl =	snd_pcm_lib_ioctl,
+	.hw_params =	i2sbus_hw_params,
+	.hw_free =	i2sbus_hw_free,
+	.prepare =	i2sbus_record_prepare,
+	.trigger =	i2sbus_record_trigger,
+	.pointer =	i2sbus_record_pointer,
+};
+
+static void i2sbus_private_free(struct snd_pcm *pcm)
+{
+	struct i2sbus_dev *i2sdev = snd_pcm_chip(pcm);
+	struct codec_info_item *p, *tmp;
+
+	i2sdev->sound.pcm = NULL;
+	i2sdev->out.created = 0;
+	i2sdev->in.created = 0;
+	list_for_each_entry_safe(p, tmp, &i2sdev->sound.codec_list, list) {
+		printk(KERN_ERR "i2sbus: a codec didn't unregister!\n");
+		list_del(&p->list);
+		module_put(p->codec->owner);
+		kfree(p);
+	}
+	soundbus_dev_put(&i2sdev->sound);
+	module_put(THIS_MODULE);
+}
+
+/* FIXME: this function needs an error handling strategy with labels */
+int
+i2sbus_attach_codec(struct soundbus_dev *dev, struct snd_card *card,
+		    struct codec_info *ci, void *data)
+{
+	int err, in = 0, out = 0;
+	struct transfer_info *tmp;
+	struct i2sbus_dev *i2sdev = soundbus_dev_to_i2sbus_dev(dev);
+	struct codec_info_item *cii;
+
+	if (!dev->pcmname || dev->pcmid == -1) {
+		printk(KERN_ERR "i2sbus: pcm name and id must be set!\n");
+		return -EINVAL;
+	}
+
+	list_for_each_entry(cii, &dev->codec_list, list) {
+		if (cii->codec_data == data)
+			return -EALREADY;
+	}
+
+	if (!ci->transfers || !ci->transfers->formats
+	    || !ci->transfers->rates || !ci->usable)
+		return -EINVAL;
+
+	/* we currently code the i2s transfer on the clock, and support only
+	 * 32 and 64 */
+	if (ci->bus_factor != 32 && ci->bus_factor != 64)
+		return -EINVAL;
+
+	/* If you want to fix this, you need to keep track of what transport infos
+	 * are to be used, which codecs they belong to, and then fix all the
+	 * sysclock/busclock stuff above to depend on which is usable */
+	list_for_each_entry(cii, &dev->codec_list, list) {
+		if (cii->codec->sysclock_factor != ci->sysclock_factor) {
+			printk(KERN_DEBUG
+			       "cannot yet handle multiple different sysclocks!\n");
+			return -EINVAL;
+		}
+		if (cii->codec->bus_factor != ci->bus_factor) {
+			printk(KERN_DEBUG
+			       "cannot yet handle multiple different bus clocks!\n");
+			return -EINVAL;
+		}
+	}
+
+	tmp = ci->transfers;
+	while (tmp->formats && tmp->rates) {
+		if (tmp->transfer_in)
+			in = 1;
+		else
+			out = 1;
+		tmp++;
+	}
+
+	cii = kzalloc(sizeof(struct codec_info_item), GFP_KERNEL);
+	if (!cii) {
+		printk(KERN_DEBUG "i2sbus: failed to allocate cii\n");
+		return -ENOMEM;
+	}
+
+	/* use the private data to point to the codec info */
+	cii->sdev = soundbus_dev_get(dev);
+	cii->codec = ci;
+	cii->codec_data = data;
+
+	if (!cii->sdev) {
+		printk(KERN_DEBUG
+		       "i2sbus: failed to get soundbus dev reference\n");
+		kfree(cii);
+		return -ENODEV;
+	}
+
+	if (!try_module_get(THIS_MODULE)) {
+		printk(KERN_DEBUG "i2sbus: failed to get module reference!\n");
+		soundbus_dev_put(dev);
+		kfree(cii);
+		return -EBUSY;
+	}
+
+	if (!try_module_get(ci->owner)) {
+		printk(KERN_DEBUG
+		       "i2sbus: failed to get module reference to codec owner!\n");
+		module_put(THIS_MODULE);
+		soundbus_dev_put(dev);
+		kfree(cii);
+		return -EBUSY;
+	}
+
+	if (!dev->pcm) {
+		err = snd_pcm_new(card,
+				  dev->pcmname,
+				  dev->pcmid,
+				  0,
+				  0,
+				  &dev->pcm);
+		if (err) {
+			printk(KERN_DEBUG "i2sbus: failed to create pcm\n");
+			kfree(cii);
+			module_put(ci->owner);
+			soundbus_dev_put(dev);
+			module_put(THIS_MODULE);
+			return err;
+		}
+	}
+
+	/* ALSA yet again sucks.
+	 * If it is ever fixed, remove this line. See below. */
+	out = in = 1;
+
+	if (!i2sdev->out.created && out) {
+		if (dev->pcm->card != card) {
+			/* eh? */
+			printk(KERN_ERR
+			       "Can't attach same bus to different cards!\n");
+			module_put(ci->owner);
+			kfree(cii);
+			soundbus_dev_put(dev);
+			module_put(THIS_MODULE);
+			return -EINVAL;
+		}
+		if ((err =
+		     snd_pcm_new_stream(dev->pcm, SNDRV_PCM_STREAM_PLAYBACK, 1))) {
+			module_put(ci->owner);
+			kfree(cii);
+			soundbus_dev_put(dev);
+			module_put(THIS_MODULE);
+			return err;
+		}
+		snd_pcm_set_ops(dev->pcm, SNDRV_PCM_STREAM_PLAYBACK,
+				&i2sbus_playback_ops);
+		i2sdev->out.created = 1;
+	}
+
+	if (!i2sdev->in.created && in) {
+		if (dev->pcm->card != card) {
+			printk(KERN_ERR
+			       "Can't attach same bus to different cards!\n");
+			module_put(ci->owner);
+			kfree(cii);
+			soundbus_dev_put(dev);
+			module_put(THIS_MODULE);
+			return -EINVAL;
+		}
+		if ((err =
+		     snd_pcm_new_stream(dev->pcm, SNDRV_PCM_STREAM_CAPTURE, 1))) {
+			module_put(ci->owner);
+			kfree(cii);
+			soundbus_dev_put(dev);
+			module_put(THIS_MODULE);
+			return err;
+		}
+		snd_pcm_set_ops(dev->pcm, SNDRV_PCM_STREAM_CAPTURE,
+				&i2sbus_record_ops);
+		i2sdev->in.created = 1;
+	}
+
+	/* so we have to register the pcm after adding any substream
+	 * to it because alsa doesn't create the devices for the
+	 * substreams when we add them later.
+	 * Therefore, force in and out on both busses (above) and
+	 * register the pcm now instead of just after creating it.
+	 */
+	err = snd_device_register(card, dev->pcm);
+	if (err) {
+		printk(KERN_ERR "i2sbus: error registering new pcm\n");
+		module_put(ci->owner);
+		kfree(cii);
+		soundbus_dev_put(dev);
+		module_put(THIS_MODULE);
+		return err;
+	}
+	/* no errors any more, so let's add this to our list */
+	list_add(&cii->list, &dev->codec_list);
+
+	dev->pcm->private_data = i2sdev;
+	dev->pcm->private_free = i2sbus_private_free;
+
+	/* well, we really should support scatter/gather DMA */
+	snd_pcm_lib_preallocate_pages_for_all(
+		dev->pcm, SNDRV_DMA_TYPE_DEV,
+		snd_dma_pci_data(macio_get_pci_dev(i2sdev->macio)),
+		64 * 1024, 64 * 1024);
+
+	return 0;
+}
+
+void i2sbus_detach_codec(struct soundbus_dev *dev, void *data)
+{
+	struct codec_info_item *cii = NULL, *i;
+
+	list_for_each_entry(i, &dev->codec_list, list) {
+		if (i->codec_data == data) {
+			cii = i;
+			break;
+		}
+	}
+	if (cii) {
+		list_del(&cii->list);
+		module_put(cii->codec->owner);
+		kfree(cii);
+	}
+	/* no more codecs, but still a pcm? */
+	if (list_empty(&dev->codec_list) && dev->pcm) {
+		/* the actual cleanup is done by the callback above! */
+		snd_device_free(dev->pcm->card, dev->pcm);
+	}
+}
diff --git a/sound/aoa/soundbus/i2sbus/i2sbus.h b/sound/aoa/soundbus/i2sbus/i2sbus.h
new file mode 100644
index 000000000..0c69d209b
--- /dev/null
+++ b/sound/aoa/soundbus/i2sbus/i2sbus.h
@@ -0,0 +1,120 @@
+/*
+ * i2sbus driver -- private definitions
+ *
+ * Copyright 2006 Johannes Berg <johannes@sipsolutions.net>
+ *
+ * GPL v2, can be found in COPYING.
+ */
+#ifndef __I2SBUS_H
+#define __I2SBUS_H
+#include <linux/interrupt.h>
+#include <linux/spinlock.h>
+#include <linux/mutex.h>
+
+#include <sound/pcm.h>
+
+#include <asm/prom.h>
+#include <asm/pmac_feature.h>
+#include <asm/dbdma.h>
+
+#include "i2sbus-interface.h"
+#include "../soundbus.h"
+
+struct i2sbus_control {
+	struct list_head list;
+	struct macio_chip *macio;
+};
+
+#define MAX_DBDMA_COMMANDS	32
+
+struct dbdma_command_mem {
+	dma_addr_t bus_addr;
+	dma_addr_t bus_cmd_start;
+	struct dbdma_cmd *cmds;
+	void *space;
+	int size;
+	u32 running:1;
+};
+
+struct pcm_info {
+	u32 created:1, /* has this direction been created with alsa? */
+	    active:1;  /* is this stream active? */
+	/* runtime information */
+	struct snd_pcm_substream *substream;
+	int current_period;
+	u32 frame_count;
+	struct dbdma_command_mem dbdma_ring;
+	volatile struct dbdma_regs __iomem *dbdma;
+};
+
+enum {
+	aoa_resource_i2smmio = 0,
+	aoa_resource_txdbdma,
+	aoa_resource_rxdbdma,
+};
+
+struct i2sbus_dev {
+	struct soundbus_dev sound;
+	struct macio_dev *macio;
+	struct i2sbus_control *control;
+	volatile struct i2s_interface_regs __iomem *intfregs;
+
+	struct resource resources[3];
+	struct resource *allocated_resource[3];
+	int interrupts[3];
+	char rnames[3][32];
+
+	/* info about currently active substreams */
+	struct pcm_info out, in;
+	snd_pcm_format_t format;
+	unsigned int rate;
+
+	/* list for a single controller */
+	struct list_head item;
+	/* number of bus on controller */
+	int bus_number;
+	/* for use by control layer */
+	struct pmf_function *enable,
+			    *cell_enable,
+			    *cell_disable,
+			    *clock_enable,
+			    *clock_disable;
+
+	/* locks */
+	/* spinlock for low-level interrupt locking */
+	spinlock_t low_lock;
+	/* mutex for high-level consistency */
+	struct mutex lock;
+};
+
+#define soundbus_dev_to_i2sbus_dev(sdev) \
+		container_of(sdev, struct i2sbus_dev, sound)
+
+/* pcm specific functions */
+extern int
+i2sbus_attach_codec(struct soundbus_dev *dev, struct snd_card *card,
+		    struct codec_info *ci, void *data);
+extern void
+i2sbus_detach_codec(struct soundbus_dev *dev, void *data);
+extern irqreturn_t
+i2sbus_tx_intr(int irq, void *devid, struct pt_regs *regs);
+extern irqreturn_t
+i2sbus_rx_intr(int irq, void *devid, struct pt_regs *regs);
+
+/* control specific functions */
+extern int i2sbus_control_init(struct macio_dev* dev,
+			       struct i2sbus_control **c);
+extern void i2sbus_control_destroy(struct i2sbus_control *c);
+extern int i2sbus_control_add_dev(struct i2sbus_control *c,
+				  struct i2sbus_dev *i2sdev);
+extern void i2sbus_control_remove_dev(struct i2sbus_control *c,
+				      struct i2sbus_dev *i2sdev);
+extern int i2sbus_control_enable(struct i2sbus_control *c,
+				 struct i2sbus_dev *i2sdev);
+extern int i2sbus_control_cell(struct i2sbus_control *c,
+			       struct i2sbus_dev *i2sdev,
+			       int enable);
+extern int i2sbus_control_clock(struct i2sbus_control *c,
+				struct i2sbus_dev *i2sdev,
+				int enable);
+#endif /* __I2SBUS_H */
diff --git a/sound/aoa/soundbus/soundbus.h b/sound/aoa/soundbus/soundbus.h
new file mode 100644
index 000000000..5c2729783
--- /dev/null
+++ b/sound/aoa/soundbus/soundbus.h
@@ -0,0 +1,202 @@
+/*
+ * soundbus generic definitions
+ *
+ * Copyright 2006 Johannes Berg <johannes@sipsolutions.net>
+ *
+ * GPL v2, can be found in COPYING.
+ */
+#ifndef __SOUNDBUS_H
+#define __SOUNDBUS_H
+
+#include <asm/of_device.h>
+#include <sound/pcm.h>
+#include <linux/list.h>
+
+
+/* When switching from master to slave or the other way around,
+ * you don't want to have the codec chip acting as clock source
+ * while the bus still is.
+ * More importantly, while switch from slave to master, you need
+ * to turn off the chip's master function first, but then there's
+ * no clock for a while and other chips might reset, so we notify
+ * their drivers after having switched.
+ * The constants here are codec-point of view, so when we switch
+ * the soundbus to master we tell the codec we're going to switch
+ * and give it CLOCK_SWITCH_PREPARE_SLAVE!
+ */
+enum clock_switch {
+	CLOCK_SWITCH_PREPARE_SLAVE,
+	CLOCK_SWITCH_PREPARE_MASTER,
+	CLOCK_SWITCH_SLAVE,
+	CLOCK_SWITCH_MASTER,
+	CLOCK_SWITCH_NOTIFY,
+};
+
+/* information on a transfer the codec can take */
+struct transfer_info {
+	u64 formats;		/* SNDRV_PCM_FMTBIT_* */
+	unsigned int rates;	/* SNDRV_PCM_RATE_* */
+	/* flags */
+	u32 transfer_in:1, /* input = 1, output = 0 */
+	    must_be_clock_source:1;
+	/* for codecs to distinguish among their TIs */
+	int tag;
+};
+
+struct codec_info_item {
+	struct codec_info *codec;
+	void *codec_data;
+	struct soundbus_dev *sdev;
+	/* internal, to be used by the soundbus provider */
+	struct list_head list;
+};
+
+/* for prepare, where the codecs need to know
+ * what we're going to drive the bus with */
+struct bus_info {
+	/* see below */
+	int sysclock_factor;
+	int bus_factor;
+};
+
+/* information on the codec itself, plus function pointers */
+struct codec_info {
+	/* the module this lives in */
+	struct module *owner;
+
+	/* supported transfer possibilities, array terminated by
+	 * formats or rates being 0. */
+	struct transfer_info *transfers;
+
+	/* Master clock speed factor
+	 * to be used (master clock speed = sysclock_factor * sampling freq)
+	 * Unused if the soundbus provider has no such notion.
+	 */
+	int sysclock_factor;
+
+	/* Bus factor, bus clock speed = bus_factor * sampling freq)
+	 * Unused if the soundbus provider has no such notion.
+	 */
+	int bus_factor;
+
+	/* operations */
+	/* clock switching, see above */
+	int (*switch_clock)(struct codec_info_item *cii,
+			    enum clock_switch clock);
+
+	/* called for each transfer_info when the user
+	 * opens the pcm device to determine what the
+	 * hardware can support at this point in time.
+	 * That can depend on other user-switchable controls.
+	 * Return 1 if usable, 0 if not.
+	 * out points to another instance of a transfer_info
+	 * which is initialised to the values in *ti, and
+	 * it's format and rate values can be modified by
+	 * the callback if it is necessary to further restrict
+	 * the formats that can be used at the moment, for
+	 * example when one codec has multiple logical codec
+	 * info structs for multiple inputs.
+	 */
+	int (*usable)(struct codec_info_item *cii,
+		      struct transfer_info *ti,
+		      struct transfer_info *out);
+
+	/* called when pcm stream is opened, probably not implemented
+	 * most of the time since it isn't too useful */
+	int (*open)(struct codec_info_item *cii,
+		    struct snd_pcm_substream *substream);
+
+	/* called when the pcm stream is closed, at this point
+	 * the user choices can all be unlocked (see below) */
+	int (*close)(struct codec_info_item *cii,
+		     struct snd_pcm_substream *substream);
+
+	/* if the codec must forbid some user choices because
+	 * they are not valid with the substream/transfer info,
+	 * it must do so here. Example: no digital output for
+	 * incompatible framerate, say 8KHz, on Onyx.
+	 * If the selected stuff in the substream is NOT
+	 * compatible, you have to reject this call! */
+	int (*prepare)(struct codec_info_item *cii,
+		       struct bus_info *bi,
+		       struct snd_pcm_substream *substream);
+
+	/* start() is called before data is pushed to the codec.
+	 * Note that start() must be atomic! */
+	int (*start)(struct codec_info_item *cii,
+		     struct snd_pcm_substream *substream);
+
+	/* stop() is called after data is no longer pushed to the codec.
+	 * Note that stop() must be atomic! */
+	int (*stop)(struct codec_info_item *cii,
+		    struct snd_pcm_substream *substream);
+
+	int (*suspend)(struct codec_info_item *cii, pm_message_t state);
+	int (*resume)(struct codec_info_item *cii);
+};
+
+/* information on a soundbus device */
+struct soundbus_dev {
+	/* the bus it belongs to */
+	struct list_head onbuslist;
+
+	/* the of device it represents */
+	struct of_device ofdev;
+
+	/* what modules go by */
+	char modalias[32];
+
+	/* These fields must be before attach_codec can be called.
+	 * They should be set by the owner of the alsa card object
+	 * that is needed, and whoever sets them must make sure
+	 * that they are unique within that alsa card object. */
+	char *pcmname;
+	int pcmid;
+
+	/* this is assigned by the soundbus provider in attach_codec */
+	struct snd_pcm *pcm;
+
+	/* operations */
+	/* attach a codec to this soundbus, give the alsa
+	 * card object the PCMs for this soundbus should be in.
+	 * The 'data' pointer must be unique, it is used as the
+	 * key for detach_codec(). */
+	int (*attach_codec)(struct soundbus_dev *dev, struct snd_card *card,
+			    struct codec_info *ci, void *data);
+	void (*detach_codec)(struct soundbus_dev *dev, void *data);
+	/* TODO: suspend/resume */
+
+	/* private for the soundbus provider */
+	struct list_head codec_list;
+	u32 have_out:1, have_in:1;
+};
+#define to_soundbus_device(d) container_of(d, struct soundbus_dev, ofdev.dev)
+#define of_to_soundbus_device(d) container_of(d, struct soundbus_dev, ofdev)
+
+extern int soundbus_add_one(struct soundbus_dev *dev);
+extern void soundbus_remove_one(struct soundbus_dev *dev);
+
+extern struct soundbus_dev *soundbus_dev_get(struct soundbus_dev *dev);
+extern void soundbus_dev_put(struct soundbus_dev *dev);
+
+struct soundbus_driver {
+	char *name;
+	struct module *owner;
+
+	/* we don't implement any matching at all */
+
+	int	(*probe)(struct soundbus_dev* dev);
+	int	(*remove)(struct soundbus_dev* dev);
+
+	int	(*suspend)(struct soundbus_dev* dev, pm_message_t state);
+	int	(*resume)(struct soundbus_dev* dev);
+	int	(*shutdown)(struct soundbus_dev* dev);
+
+	struct device_driver driver;
+};
+#define to_soundbus_driver(drv) container_of(drv,struct soundbus_driver, driver)
+
+extern int soundbus_register_driver(struct soundbus_driver *drv);
+extern void soundbus_unregister_driver(struct soundbus_driver *drv);
+
+#endif /* __SOUNDBUS_H */
diff --git a/sound/aoa/soundbus/sysfs.c b/sound/aoa/soundbus/sysfs.c
new file mode 100644
index 000000000..f580942b5
--- /dev/null
+++ b/sound/aoa/soundbus/sysfs.c
@@ -0,0 +1,42 @@
+#include <linux/kernel.h>
+#include <linux/stat.h>
+/* FIX UP */
+#include "soundbus.h"
+
+#define soundbus_config_of_attr(field, format_string)			\
+static ssize_t								\
+field##_show (struct device *dev, struct device_attribute *attr,	\
+              char *buf)						\
+{									\
+	struct soundbus_dev *mdev = to_soundbus_device (dev);		\
+	return sprintf (buf, format_string, mdev->ofdev.node->field);	\
+}
+
+static ssize_t modalias_show(struct device *dev, struct device_attribute *attr,
+			     char *buf)
+{
+	struct soundbus_dev *sdev = to_soundbus_device(dev);
+	struct of_device *of = &sdev->ofdev;
+	int length;
+
+	if (*sdev->modalias) {
+		strlcpy(buf, sdev->modalias, sizeof(sdev->modalias) + 1);
+		strcat(buf, "\n");
+		length = strlen(buf);
+	} else {
+		length = sprintf(buf, "of:N%sT%s\n",
+				 of->node->name, of->node->type);
+	}
+
+	return length;
+}
+
+soundbus_config_of_attr (name, "%s\n");
+soundbus_config_of_attr (type, "%s\n");
+
+struct device_attribute soundbus_dev_attrs[] = {
+	__ATTR_RO(name),
+	__ATTR_RO(type),
+	__ATTR_RO(modalias),
+	__ATTR_NULL
+};
diff --git a/sound/pci/cs5535audio/cs5535audio_pm.c b/sound/pci/cs5535audio/cs5535audio_pm.c
new file mode 100644
index 000000000..aad0e69db
--- /dev/null
+++ b/sound/pci/cs5535audio/cs5535audio_pm.c
@@ -0,0 +1,123 @@
+/*
+ * Power management for audio on multifunction CS5535 companion device
+ * Copyright (C) Jaya Kumar
+ *
+ * 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/slab.h>
+#include <linux/pci.h>
+#include <linux/delay.h>
+#include <sound/driver.h>
+#include <sound/core.h>
+#include <sound/control.h>
+#include <sound/initval.h>
+#include <sound/asoundef.h>
+#include <sound/pcm.h>
+#include <sound/ac97_codec.h>
+#include "cs5535audio.h"
+
+static void snd_cs5535audio_stop_hardware(struct cs5535audio *cs5535au)
+{
+	/* 
+	we depend on snd_ac97_suspend to tell the
+	AC97 codec to shutdown. the amd spec suggests
+	that the LNK_SHUTDOWN be done at the same time
+	that the codec power-down is issued. instead,
+	we do it just after rather than at the same 
+	time. excluding codec specific build_ops->suspend
+	ac97 powerdown hits:
+	0x8000 EAPD 
+	0x4000 Headphone amplifier 
+	0x0300 ADC & DAC 
+	0x0400 Analog Mixer powerdown (Vref on) 
+	I am not sure if this is the best that we can do.
+	The remainder to be investigated are:
+	- analog mixer (vref off) 0x0800
+	- AC-link powerdown 0x1000
+	- codec internal clock 0x2000
+	*/
+
+	/* set LNK_SHUTDOWN to shutdown AC link */
+	cs_writel(cs5535au, ACC_CODEC_CNTL, ACC_CODEC_CNTL_LNK_SHUTDOWN);
+
+}
+
+int snd_cs5535audio_suspend(struct pci_dev *pci, pm_message_t state)
+{
+	struct snd_card *card = pci_get_drvdata(pci);
+	struct cs5535audio *cs5535au = card->private_data;
+	int i;
+
+	snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
+	for (i = 0; i < NUM_CS5535AUDIO_DMAS; i++) {
+		struct cs5535audio_dma *dma = &cs5535au->dmas[i];
+		if (dma && dma->substream && !dma->suspended) 
+			dma->saved_prd = dma->ops->read_prd(cs5535au);
+	}
+	snd_pcm_suspend_all(cs5535au->pcm);
+	snd_ac97_suspend(cs5535au->ac97);
+	/* save important regs, then disable aclink in hw */
+	snd_cs5535audio_stop_hardware(cs5535au);
+	pci_disable_device(pci);
+	pci_save_state(pci);
+
+	return 0;
+}
+
+int snd_cs5535audio_resume(struct pci_dev *pci)
+{
+	struct snd_card *card = pci_get_drvdata(pci);
+	struct cs5535audio *cs5535au = card->private_data;
+	u32 tmp;
+	int timeout;
+	int i;
+
+	pci_restore_state(pci);
+	pci_enable_device(pci);
+	pci_set_master(pci);
+
+	/* set LNK_WRM_RST to reset AC link */
+	cs_writel(cs5535au, ACC_CODEC_CNTL, ACC_CODEC_CNTL_LNK_WRM_RST);
+
+	timeout = 50;
+	do {
+		tmp = cs_readl(cs5535au, ACC_CODEC_STATUS);
+		if (tmp & PRM_RDY_STS)
+			break;
+		udelay(1);
+	} while (--timeout);
+
+	if (!timeout)
+		snd_printk(KERN_ERR "Failure getting AC Link ready\n");
+
+	/* we depend on ac97 to perform the codec power up */
+	snd_ac97_resume(cs5535au->ac97);
+	/* set up rate regs, dma. actual initiation is done in trig */
+	for (i = 0; i < NUM_CS5535AUDIO_DMAS; i++) {
+		struct cs5535audio_dma *dma = &cs5535au->dmas[i];
+		if (dma && dma->substream && dma->suspended) {
+			dma->substream->ops->prepare(dma->substream);
+			dma->ops->setup_prd(cs5535au, dma->saved_prd);
+		}
+	}
+		
+	snd_power_change_state(card, SNDRV_CTL_POWER_D0);
+
+	return 0;
+}
+
diff --git a/sound/pci/echoaudio/Makefile b/sound/pci/echoaudio/Makefile
new file mode 100644
index 000000000..7b576aeb3
--- /dev/null
+++ b/sound/pci/echoaudio/Makefile
@@ -0,0 +1,30 @@
+#
+# Makefile for ALSA Echoaudio soundcard drivers
+# Copyright (c) 2003 by Giuliano Pochini <pochini@shiny.it>
+#
+
+snd-darla20-objs := darla20.o
+snd-gina20-objs := gina20.o
+snd-layla20-objs := layla20.o
+snd-darla24-objs := darla24.o
+snd-gina24-objs := gina24.o
+snd-layla24-objs := layla24.o
+snd-mona-objs := mona.o
+snd-mia-objs := mia.o
+snd-echo3g-objs := echo3g.o
+snd-indigo-objs := indigo.o
+snd-indigoio-objs := indigoio.o
+snd-indigodj-objs := indigodj.o
+
+obj-$(CONFIG_SND_DARLA20) += snd-darla20.o
+obj-$(CONFIG_SND_GINA20) += snd-gina20.o
+obj-$(CONFIG_SND_LAYLA20) += snd-layla20.o
+obj-$(CONFIG_SND_DARLA24) += snd-darla24.o
+obj-$(CONFIG_SND_GINA24) += snd-gina24.o
+obj-$(CONFIG_SND_LAYLA24) += snd-layla24.o
+obj-$(CONFIG_SND_MONA) += snd-mona.o
+obj-$(CONFIG_SND_MIA) += snd-mia.o
+obj-$(CONFIG_SND_ECHO3G) += snd-echo3g.o
+obj-$(CONFIG_SND_INDIGO) += snd-indigo.o
+obj-$(CONFIG_SND_INDIGOIO) += snd-indigoio.o
+obj-$(CONFIG_SND_INDIGODJ) += snd-indigodj.o
diff --git a/sound/pci/echoaudio/darla20.c b/sound/pci/echoaudio/darla20.c
new file mode 100644
index 000000000..b7108e29a
--- /dev/null
+++ b/sound/pci/echoaudio/darla20.c
@@ -0,0 +1,99 @@
+/*
+ *  ALSA driver for Echoaudio soundcards.
+ *  Copyright (C) 2003-2004 Giuliano Pochini <pochini@shiny.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; 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.
+ */
+
+#define ECHOGALS_FAMILY
+#define ECHOCARD_DARLA20
+#define ECHOCARD_NAME "Darla20"
+#define ECHOCARD_HAS_MONITOR
+
+/* Pipe indexes */
+#define PX_ANALOG_OUT	0	/* 8 */
+#define PX_DIGITAL_OUT	8	/* 0 */
+#define PX_ANALOG_IN	8	/* 2 */
+#define PX_DIGITAL_IN	10	/* 0 */
+#define PX_NUM		10
+
+/* Bus indexes */
+#define BX_ANALOG_OUT	0	/* 8 */
+#define BX_DIGITAL_OUT	8	/* 0 */
+#define BX_ANALOG_IN	8	/* 2 */
+#define BX_DIGITAL_IN	10	/* 0 */
+#define BX_NUM		10
+
+
+#include <sound/driver.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/pci.h>
+#include <linux/slab.h>
+#include <linux/moduleparam.h>
+#include <linux/firmware.h>
+#include <sound/core.h>
+#include <sound/info.h>
+#include <sound/control.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/asoundef.h>
+#include <sound/initval.h>
+#include <asm/io.h>
+#include <asm/atomic.h>
+#include "echoaudio.h"
+
+#define FW_DARLA20_DSP	0
+
+static const struct firmware card_fw[] = {
+	{0, "darla20_dsp.fw"}
+};
+
+static struct pci_device_id snd_echo_ids[] = {
+	{0x1057, 0x1801, 0xECC0, 0x0010, 0, 0, 0},	/* DSP 56301 Darla20 rev.0 */
+	{0,}
+};
+
+static struct snd_pcm_hardware pcm_hardware_skel = {
+	.info = SNDRV_PCM_INFO_MMAP |
+		SNDRV_PCM_INFO_INTERLEAVED |
+		SNDRV_PCM_INFO_BLOCK_TRANSFER |
+		SNDRV_PCM_INFO_MMAP_VALID |
+		SNDRV_PCM_INFO_PAUSE |
+		SNDRV_PCM_INFO_SYNC_START,
+	.formats =	SNDRV_PCM_FMTBIT_U8 |
+			SNDRV_PCM_FMTBIT_S16_LE |
+			SNDRV_PCM_FMTBIT_S24_3LE |
+			SNDRV_PCM_FMTBIT_S32_LE |
+			SNDRV_PCM_FMTBIT_S32_BE,
+	.rates = SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000,
+	.rate_min = 44100,
+	.rate_max = 48000,
+	.channels_min = 1,
+	.channels_max = 2,
+	.buffer_bytes_max = 262144,
+	.period_bytes_min = 32,
+	.period_bytes_max = 131072,
+	.periods_min = 2,
+	.periods_max = 220,
+	/* One page (4k) contains 512 instructions. I don't know if the hw
+	supports lists longer than this. In this case periods_max=220 is a
+	safe limit to make sure the list never exceeds 512 instructions. */
+};
+
+
+#include "darla20_dsp.c"
+#include "echoaudio_dsp.c"
+#include "echoaudio.c"
diff --git a/sound/pci/echoaudio/darla20_dsp.c b/sound/pci/echoaudio/darla20_dsp.c
new file mode 100644
index 000000000..4159e3bc1
--- /dev/null
+++ b/sound/pci/echoaudio/darla20_dsp.c
@@ -0,0 +1,125 @@
+/***************************************************************************
+
+   Copyright Echo Digital Audio Corporation (c) 1998 - 2004
+   All rights reserved
+   www.echoaudio.com
+
+   This file is part of Echo Digital Audio's generic driver library.
+
+   Echo Digital Audio's generic driver library 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.
+
+   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.
+
+   *************************************************************************
+
+ Translation from C++ and adaptation for use in ALSA-Driver
+ were made by Giuliano Pochini <pochini@shiny.it>
+
+****************************************************************************/
+
+
+static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
+{
+	int err;
+
+	DE_INIT(("init_hw() - Darla20\n"));
+	snd_assert((subdevice_id & 0xfff0) == DARLA20, return -ENODEV);
+
+	if ((err = init_dsp_comm_page(chip))) {
+		DE_INIT(("init_hw - could not initialize DSP comm page\n"));
+		return err;
+	}
+
+	chip->device_id = device_id;
+	chip->subdevice_id = subdevice_id;
+	chip->bad_board = TRUE;
+	chip->dsp_code_to_load = &card_fw[FW_DARLA20_DSP];
+	chip->spdif_status = GD_SPDIF_STATUS_UNDEF;
+	chip->clock_state = GD_CLOCK_UNDEF;
+	/* Since this card has no ASIC, mark it as loaded so everything
+	   works OK */
+	chip->asic_loaded = TRUE;
+	chip->input_clock_types = ECHO_CLOCK_BIT_INTERNAL;
+
+	if ((err = load_firmware(chip)) < 0)
+		return err;
+	chip->bad_board = FALSE;
+
+	if ((err = init_line_levels(chip)) < 0)
+		return err;
+
+	DE_INIT(("init_hw done\n"));
+	return err;
+}
+
+
+
+/* The Darla20 has no external clock sources */
+static u32 detect_input_clocks(const struct echoaudio *chip)
+{
+	return ECHO_CLOCK_BIT_INTERNAL;
+}
+
+
+
+/* The Darla20 has no ASIC. Just do nothing */
+static int load_asic(struct echoaudio *chip)
+{
+	return 0;
+}
+
+
+
+static int set_sample_rate(struct echoaudio *chip, u32 rate)
+{
+	u8 clock_state, spdif_status;
+
+	if (wait_handshake(chip))
+		return -EIO;
+
+	switch (rate) {
+	case 44100:
+		clock_state = GD_CLOCK_44;
+		spdif_status = GD_SPDIF_STATUS_44;
+		break;
+	case 48000:
+		clock_state = GD_CLOCK_48;
+		spdif_status = GD_SPDIF_STATUS_48;
+		break;
+	default:
+		clock_state = GD_CLOCK_NOCHANGE;
+		spdif_status = GD_SPDIF_STATUS_NOCHANGE;
+		break;
+	}
+
+	if (chip->clock_state == clock_state)
+		clock_state = GD_CLOCK_NOCHANGE;
+	if (spdif_status == chip->spdif_status)
+		spdif_status = GD_SPDIF_STATUS_NOCHANGE;
+
+	chip->comm_page->sample_rate = cpu_to_le32(rate);
+	chip->comm_page->gd_clock_state = clock_state;
+	chip->comm_page->gd_spdif_status = spdif_status;
+	chip->comm_page->gd_resampler_state = 3;	/* magic number - should always be 3 */
+
+	/* Save the new audio state if it changed */
+	if (clock_state != GD_CLOCK_NOCHANGE)
+		chip->clock_state = clock_state;
+	if (spdif_status != GD_SPDIF_STATUS_NOCHANGE)
+		chip->spdif_status = spdif_status;
+	chip->sample_rate = rate;
+
+	clear_handshake(chip);
+	return send_vector(chip, DSP_VC_SET_GD_AUDIO_STATE);
+}
diff --git a/sound/pci/echoaudio/darla24.c b/sound/pci/echoaudio/darla24.c
new file mode 100644
index 000000000..e59a982ee
--- /dev/null
+++ b/sound/pci/echoaudio/darla24.c
@@ -0,0 +1,106 @@
+/*
+ *  ALSA driver for Echoaudio soundcards.
+ *  Copyright (C) 2003-2004 Giuliano Pochini <pochini@shiny.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; 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.
+ */
+
+#define ECHOGALS_FAMILY
+#define ECHOCARD_DARLA24
+#define ECHOCARD_NAME "Darla24"
+#define ECHOCARD_HAS_MONITOR
+#define ECHOCARD_HAS_INPUT_NOMINAL_LEVEL
+#define ECHOCARD_HAS_OUTPUT_NOMINAL_LEVEL
+#define ECHOCARD_HAS_EXTERNAL_CLOCK
+#define ECHOCARD_HAS_SUPER_INTERLEAVE
+
+/* Pipe indexes */
+#define PX_ANALOG_OUT	0	/* 8 */
+#define PX_DIGITAL_OUT	8	/* 0 */
+#define PX_ANALOG_IN	8	/* 2 */
+#define PX_DIGITAL_IN	10	/* 0 */
+#define PX_NUM		10
+
+/* Bus indexes */
+#define BX_ANALOG_OUT	0	/* 8 */
+#define BX_DIGITAL_OUT	8	/* 0 */
+#define BX_ANALOG_IN	8	/* 2 */
+#define BX_DIGITAL_IN	10	/* 0 */
+#define BX_NUM		10
+
+
+#include <sound/driver.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/pci.h>
+#include <linux/slab.h>
+#include <linux/moduleparam.h>
+#include <linux/firmware.h>
+#include <sound/core.h>
+#include <sound/info.h>
+#include <sound/control.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/asoundef.h>
+#include <sound/initval.h>
+#include <asm/io.h>
+#include <asm/atomic.h>
+#include "echoaudio.h"
+
+#define FW_DARLA24_DSP	0
+
+static const struct firmware card_fw[] = {
+	{0, "darla24_dsp.fw"}
+};
+
+static struct pci_device_id snd_echo_ids[] = {
+	{0x1057, 0x1801, 0xECC0, 0x0040, 0, 0, 0},	/* DSP 56301 Darla24 rev.0 */
+	{0x1057, 0x1801, 0xECC0, 0x0041, 0, 0, 0},	/* DSP 56301 Darla24 rev.1 */
+	{0,}
+};
+
+static struct snd_pcm_hardware pcm_hardware_skel = {
+	.info = SNDRV_PCM_INFO_MMAP |
+		SNDRV_PCM_INFO_INTERLEAVED |
+		SNDRV_PCM_INFO_BLOCK_TRANSFER |
+		SNDRV_PCM_INFO_MMAP_VALID |
+		SNDRV_PCM_INFO_PAUSE |
+		SNDRV_PCM_INFO_SYNC_START,
+	.formats =	SNDRV_PCM_FMTBIT_U8 |
+			SNDRV_PCM_FMTBIT_S16_LE |
+			SNDRV_PCM_FMTBIT_S24_3LE |
+			SNDRV_PCM_FMTBIT_S32_LE |
+			SNDRV_PCM_FMTBIT_S32_BE,
+	.rates =	SNDRV_PCM_RATE_8000_48000 |
+			SNDRV_PCM_RATE_88200 |
+			SNDRV_PCM_RATE_96000,
+	.rate_min = 8000,
+	.rate_max = 96000,
+	.channels_min = 1,
+	.channels_max = 8,
+	.buffer_bytes_max = 262144,
+	.period_bytes_min = 32,
+	.period_bytes_max = 131072,
+	.periods_min = 2,
+	.periods_max = 220,
+	/* One page (4k) contains 512 instructions. I don't know if the hw
+	supports lists longer than this. In this case periods_max=220 is a
+	safe limit to make sure the list never exceeds 512 instructions. */
+};
+
+
+#include "darla24_dsp.c"
+#include "echoaudio_dsp.c"
+#include "echoaudio.c"
diff --git a/sound/pci/echoaudio/darla24_dsp.c b/sound/pci/echoaudio/darla24_dsp.c
new file mode 100644
index 000000000..79938eed7
--- /dev/null
+++ b/sound/pci/echoaudio/darla24_dsp.c
@@ -0,0 +1,156 @@
+/***************************************************************************
+
+   Copyright Echo Digital Audio Corporation (c) 1998 - 2004
+   All rights reserved
+   www.echoaudio.com
+
+   This file is part of Echo Digital Audio's generic driver library.
+
+   Echo Digital Audio's generic driver library 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.
+
+   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.
+
+   *************************************************************************
+
+ Translation from C++ and adaptation for use in ALSA-Driver
+ were made by Giuliano Pochini <pochini@shiny.it>
+
+****************************************************************************/
+
+
+static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
+{
+	int err;
+
+	DE_INIT(("init_hw() - Darla24\n"));
+	snd_assert((subdevice_id & 0xfff0) == DARLA24, return -ENODEV);
+
+	if ((err = init_dsp_comm_page(chip))) {
+		DE_INIT(("init_hw - could not initialize DSP comm page\n"));
+		return err;
+	}
+
+	chip->device_id = device_id;
+	chip->subdevice_id = subdevice_id;
+	chip->bad_board = TRUE;
+	chip->dsp_code_to_load = &card_fw[FW_DARLA24_DSP];
+	/* Since this card has no ASIC, mark it as loaded so everything
+	   works OK */
+	chip->asic_loaded = TRUE;
+	chip->input_clock_types = ECHO_CLOCK_BIT_INTERNAL |
+		ECHO_CLOCK_BIT_ESYNC;
+
+	if ((err = load_firmware(chip)) < 0)
+		return err;
+	chip->bad_board = FALSE;
+
+	if ((err = init_line_levels(chip)) < 0)
+		return err;
+
+	DE_INIT(("init_hw done\n"));
+	return err;
+}
+
+
+
+static u32 detect_input_clocks(const struct echoaudio *chip)
+{
+	u32 clocks_from_dsp, clock_bits;
+
+	/* Map the DSP clock detect bits to the generic driver clock
+	   detect bits */
+	clocks_from_dsp = le32_to_cpu(chip->comm_page->status_clocks);
+
+	clock_bits = ECHO_CLOCK_BIT_INTERNAL;
+
+	if (clocks_from_dsp & GLDM_CLOCK_DETECT_BIT_ESYNC)
+		clock_bits |= ECHO_CLOCK_BIT_ESYNC;
+
+	return clock_bits;
+}
+
+
+
+/* The Darla24 has no ASIC. Just do nothing */
+static int load_asic(struct echoaudio *chip)
+{
+	return 0;
+}
+
+
+
+static int set_sample_rate(struct echoaudio *chip, u32 rate)
+{
+	u8 clock;
+
+	switch (rate) {
+	case 96000:
+		clock = GD24_96000;
+		break;
+	case 88200:
+		clock = GD24_88200;
+		break;
+	case 48000:
+		clock = GD24_48000;
+		break;
+	case 44100:
+		clock = GD24_44100;
+		break;
+	case 32000:
+		clock = GD24_32000;
+		break;
+	case 22050:
+		clock = GD24_22050;
+		break;
+	case 16000:
+		clock = GD24_16000;
+		break;
+	case 11025:
+		clock = GD24_11025;
+		break;
+	case 8000:
+		clock = GD24_8000;
+		break;
+	default:
+		DE_ACT(("set_sample_rate: Error, invalid sample rate %d\n",
+			rate));
+		return -EINVAL;
+	}
+
+	if (wait_handshake(chip))
+		return -EIO;
+
+	DE_ACT(("set_sample_rate: %d clock %d\n", rate, clock));
+	chip->sample_rate = rate;
+
+	/* Override the sample rate if this card is set to Echo sync. */
+	if (chip->input_clock == ECHO_CLOCK_ESYNC)
+		clock = GD24_EXT_SYNC;
+
+	chip->comm_page->sample_rate = cpu_to_le32(rate);	/* ignored by the DSP ? */
+	chip->comm_page->gd_clock_state = clock;
+	clear_handshake(chip);
+	return send_vector(chip, DSP_VC_SET_GD_AUDIO_STATE);
+}
+
+
+
+static int set_input_clock(struct echoaudio *chip, u16 clock)
+{
+	snd_assert(clock == ECHO_CLOCK_INTERNAL ||
+		   clock == ECHO_CLOCK_ESYNC, return -EINVAL);
+	chip->input_clock = clock;
+	return set_sample_rate(chip, chip->sample_rate);
+}
+
diff --git a/sound/pci/echoaudio/echo3g.c b/sound/pci/echoaudio/echo3g.c
new file mode 100644
index 000000000..12099fe15
--- /dev/null
+++ b/sound/pci/echoaudio/echo3g.c
@@ -0,0 +1,118 @@
+/*
+ *  ALSA driver for Echoaudio soundcards.
+ *  Copyright (C) 2003-2004 Giuliano Pochini <pochini@shiny.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; 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.
+ */
+
+#define ECHO3G_FAMILY
+#define ECHOCARD_ECHO3G
+#define ECHOCARD_NAME "Echo3G"
+#define ECHOCARD_HAS_MONITOR
+#define ECHOCARD_HAS_ASIC
+#define ECHOCARD_HAS_INPUT_NOMINAL_LEVEL
+#define ECHOCARD_HAS_OUTPUT_NOMINAL_LEVEL
+#define ECHOCARD_HAS_SUPER_INTERLEAVE
+#define ECHOCARD_HAS_DIGITAL_IO
+#define ECHOCARD_HAS_DIGITAL_MODE_SWITCH
+#define ECHOCARD_HAS_ADAT	6
+#define ECHOCARD_HAS_EXTERNAL_CLOCK
+#define ECHOCARD_HAS_STEREO_BIG_ENDIAN32
+#define ECHOCARD_HAS_MIDI
+#define ECHOCARD_HAS_PHANTOM_POWER
+
+/* Pipe indexes */
+#define PX_ANALOG_OUT	0
+#define PX_DIGITAL_OUT	chip->px_digital_out
+#define PX_ANALOG_IN	chip->px_analog_in
+#define PX_DIGITAL_IN	chip->px_digital_in
+#define PX_NUM		chip->px_num
+
+/* Bus indexes */
+#define BX_ANALOG_OUT	0
+#define BX_DIGITAL_OUT	chip->bx_digital_out
+#define BX_ANALOG_IN	chip->bx_analog_in
+#define BX_DIGITAL_IN	chip->bx_digital_in
+#define BX_NUM		chip->bx_num
+
+
+#include <sound/driver.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/pci.h>
+#include <linux/slab.h>
+#include <linux/moduleparam.h>
+#include <linux/firmware.h>
+#include <sound/core.h>
+#include <sound/info.h>
+#include <sound/control.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/asoundef.h>
+#include <sound/initval.h>
+#include <sound/rawmidi.h>
+#include <asm/io.h>
+#include <asm/atomic.h>
+#include "echoaudio.h"
+
+#define FW_361_LOADER	0
+#define FW_ECHO3G_DSP	1
+#define FW_3G_ASIC	2
+
+static const struct firmware card_fw[] = {
+	{0, "loader_dsp.fw"},
+	{0, "echo3g_dsp.fw"},
+	{0, "3g_asic.fw"}
+};
+
+static struct pci_device_id snd_echo_ids[] = {
+	{0x1057, 0x3410, 0xECC0, 0x0100, 0, 0, 0},	/* Echo 3G */
+	{0,}
+};
+
+static struct snd_pcm_hardware pcm_hardware_skel = {
+	.info = SNDRV_PCM_INFO_MMAP |
+		SNDRV_PCM_INFO_INTERLEAVED |
+		SNDRV_PCM_INFO_BLOCK_TRANSFER |
+		SNDRV_PCM_INFO_MMAP_VALID |
+		SNDRV_PCM_INFO_PAUSE |
+		SNDRV_PCM_INFO_SYNC_START,
+	.formats =	SNDRV_PCM_FMTBIT_U8 |
+			SNDRV_PCM_FMTBIT_S16_LE |
+			SNDRV_PCM_FMTBIT_S24_3LE |
+			SNDRV_PCM_FMTBIT_S32_LE |
+			SNDRV_PCM_FMTBIT_S32_BE,
+	.rates = 	SNDRV_PCM_RATE_32000 |
+			SNDRV_PCM_RATE_44100 |
+			SNDRV_PCM_RATE_48000 |
+			SNDRV_PCM_RATE_88200 |
+			SNDRV_PCM_RATE_96000 |
+			SNDRV_PCM_RATE_CONTINUOUS,
+	.rate_min = 32000,
+	.rate_max = 100000,
+	.channels_min = 1,
+	.channels_max = 8,
+	.buffer_bytes_max = 262144,
+	.period_bytes_min = 32,
+	.period_bytes_max = 131072,
+	.periods_min = 2,
+	.periods_max = 220,
+};
+
+#include "echo3g_dsp.c"
+#include "echoaudio_dsp.c"
+#include "echoaudio_3g.c"
+#include "echoaudio.c"
+#include "midi.c"
diff --git a/sound/pci/echoaudio/echo3g_dsp.c b/sound/pci/echoaudio/echo3g_dsp.c
new file mode 100644
index 000000000..d26a1d1f3
--- /dev/null
+++ b/sound/pci/echoaudio/echo3g_dsp.c
@@ -0,0 +1,131 @@
+/****************************************************************************
+
+   Copyright Echo Digital Audio Corporation (c) 1998 - 2004
+   All rights reserved
+   www.echoaudio.com
+
+   This file is part of Echo Digital Audio's generic driver library.
+
+   Echo Digital Audio's generic driver library 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.
+
+   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.
+
+   *************************************************************************
+
+ Translation from C++ and adaptation for use in ALSA-Driver
+ were made by Giuliano Pochini <pochini@shiny.it>
+
+****************************************************************************/
+
+static int load_asic(struct echoaudio *chip);
+static int dsp_set_digital_mode(struct echoaudio *chip, u8 mode);
+static int set_digital_mode(struct echoaudio *chip, u8 mode);
+static int check_asic_status(struct echoaudio *chip);
+static int set_sample_rate(struct echoaudio *chip, u32 rate);
+static int set_input_clock(struct echoaudio *chip, u16 clock);
+static int set_professional_spdif(struct echoaudio *chip, char prof);
+static int set_phantom_power(struct echoaudio *chip, char on);
+static int write_control_reg(struct echoaudio *chip, u32 ctl, u32 frq,
+			     char force);
+
+#include <linux/irq.h>
+
+static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
+{
+	int err;
+
+	local_irq_enable();
+	DE_INIT(("init_hw() - Echo3G\n"));
+	snd_assert((subdevice_id & 0xfff0) == ECHO3G, return -ENODEV);
+
+	if ((err = init_dsp_comm_page(chip))) {
+		DE_INIT(("init_hw - could not initialize DSP comm page\n"));
+		return err;
+	}
+
+	chip->comm_page->e3g_frq_register =
+		__constant_cpu_to_le32((E3G_MAGIC_NUMBER / 48000) - 2);
+	chip->device_id = device_id;
+	chip->subdevice_id = subdevice_id;
+	chip->bad_board = TRUE;
+	chip->has_midi = TRUE;
+	chip->dsp_code_to_load = &card_fw[FW_ECHO3G_DSP];
+
+	/* Load the DSP code and the ASIC on the PCI card and get
+	what type of external box is attached */
+	err = load_firmware(chip);
+
+	if (err < 0) {
+		return err;
+	} else if (err == E3G_GINA3G_BOX_TYPE) {
+		chip->input_clock_types =	ECHO_CLOCK_BIT_INTERNAL |
+						ECHO_CLOCK_BIT_SPDIF |
+						ECHO_CLOCK_BIT_ADAT;
+		chip->card_name = "Gina3G";
+		chip->px_digital_out = chip->bx_digital_out = 6;
+		chip->px_analog_in = chip->bx_analog_in = 14;
+		chip->px_digital_in = chip->bx_digital_in = 16;
+		chip->px_num = chip->bx_num = 24;
+		chip->has_phantom_power = TRUE;
+		chip->hasnt_input_nominal_level = TRUE;
+	} else if (err == E3G_LAYLA3G_BOX_TYPE) {
+		chip->input_clock_types =	ECHO_CLOCK_BIT_INTERNAL |
+						ECHO_CLOCK_BIT_SPDIF |
+						ECHO_CLOCK_BIT_ADAT |
+						ECHO_CLOCK_BIT_WORD;
+		chip->card_name = "Layla3G";
+		chip->px_digital_out = chip->bx_digital_out = 8;
+		chip->px_analog_in = chip->bx_analog_in = 16;
+		chip->px_digital_in = chip->bx_digital_in = 24;
+		chip->px_num = chip->bx_num = 32;
+	} else {
+		return -ENODEV;
+	}
+
+	chip->digital_modes =	ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_RCA |
+				ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_OPTICAL |
+				ECHOCAPS_HAS_DIGITAL_MODE_ADAT;
+	chip->digital_mode =	DIGITAL_MODE_SPDIF_RCA;
+	chip->professional_spdif = FALSE;
+	chip->non_audio_spdif = FALSE;
+	chip->bad_board = FALSE;
+
+	if ((err = init_line_levels(chip)) < 0)
+		return err;
+	err = set_digital_mode(chip, DIGITAL_MODE_SPDIF_RCA);
+	snd_assert(err >= 0, return err);
+	err = set_phantom_power(chip, 0);
+	snd_assert(err >= 0, return err);
+	err = set_professional_spdif(chip, TRUE);
+
+	DE_INIT(("init_hw done\n"));
+	return err;
+}
+
+
+
+static int set_phantom_power(struct echoaudio *chip, char on)
+{
+	u32 control_reg = le32_to_cpu(chip->comm_page->control_register);
+
+	if (on)
+		control_reg |= E3G_PHANTOM_POWER;
+	else
+		control_reg &= ~E3G_PHANTOM_POWER;
+
+	chip->phantom_power = on;
+	return write_control_reg(chip, control_reg,
+				 le32_to_cpu(chip->comm_page->e3g_frq_register),
+				 0);
+}
diff --git a/sound/pci/echoaudio/echoaudio.c b/sound/pci/echoaudio/echoaudio.c
new file mode 100644
index 000000000..c3dafa290
--- /dev/null
+++ b/sound/pci/echoaudio/echoaudio.c
@@ -0,0 +1,2196 @@
+/*
+ *  ALSA driver for Echoaudio soundcards.
+ *  Copyright (C) 2003-2004 Giuliano Pochini <pochini@shiny.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; 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.
+ */
+
+MODULE_AUTHOR("Giuliano Pochini <pochini@shiny.it>");
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("Echoaudio " ECHOCARD_NAME " soundcards driver");
+MODULE_SUPPORTED_DEVICE("{{Echoaudio," ECHOCARD_NAME "}}");
+MODULE_DEVICE_TABLE(pci, snd_echo_ids);
+
+static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
+static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
+static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
+
+module_param_array(index, int, NULL, 0444);
+MODULE_PARM_DESC(index, "Index value for " ECHOCARD_NAME " soundcard.");
+module_param_array(id, charp, NULL, 0444);
+MODULE_PARM_DESC(id, "ID string for " ECHOCARD_NAME " soundcard.");
+module_param_array(enable, bool, NULL, 0444);
+MODULE_PARM_DESC(enable, "Enable " ECHOCARD_NAME " soundcard.");
+
+static unsigned int channels_list[10] = {1, 2, 4, 6, 8, 10, 12, 14, 16, 999999};
+
+static int get_firmware(const struct firmware **fw_entry,
+			const struct firmware *frm, struct echoaudio *chip)
+{
+	int err;
+	char name[30];
+	DE_ACT(("firmware requested: %s\n", frm->data));
+	snprintf(name, sizeof(name), "ea/%s", frm->data);
+	if ((err = request_firmware(fw_entry, name, pci_device(chip))) < 0)
+		snd_printk(KERN_ERR "get_firmware(): Firmware not available (%d)\n", err);
+	return err;
+}
+
+static void free_firmware(const struct firmware *fw_entry)
+{
+	release_firmware(fw_entry);
+	DE_ACT(("firmware released\n"));
+}
+
+
+
+/******************************************************************************
+	PCM interface
+******************************************************************************/
+
+static void audiopipe_free(struct snd_pcm_runtime *runtime)
+{
+	struct audiopipe *pipe = runtime->private_data;
+
+	if (pipe->sgpage.area)
+		snd_dma_free_pages(&pipe->sgpage);
+	kfree(pipe);
+}
+
+
+
+static int hw_rule_capture_format_by_channels(struct snd_pcm_hw_params *params,
+					      struct snd_pcm_hw_rule *rule)
+{
+	struct snd_interval *c = hw_param_interval(params,
+						   SNDRV_PCM_HW_PARAM_CHANNELS);
+	struct snd_mask *f = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
+	struct snd_mask fmt;
+
+	snd_mask_any(&fmt);
+
+#ifndef ECHOCARD_HAS_STEREO_BIG_ENDIAN32
+	/* >=2 channels cannot be S32_BE */
+	if (c->min == 2) {
+		fmt.bits[0] &= ~SNDRV_PCM_FMTBIT_S32_BE;
+		return snd_mask_refine(f, &fmt);
+	}
+#endif
+	/* > 2 channels cannot be U8 and S32_BE */
+	if (c->min > 2) {
+		fmt.bits[0] &= ~(SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S32_BE);
+		return snd_mask_refine(f, &fmt);
+	}
+	/* Mono is ok with any format */
+	return 0;
+}
+
+
+
+static int hw_rule_capture_channels_by_format(struct snd_pcm_hw_params *params,
+					      struct snd_pcm_hw_rule *rule)
+{
+	struct snd_interval *c = hw_param_interval(params,
+						   SNDRV_PCM_HW_PARAM_CHANNELS);
+	struct snd_mask *f = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
+	struct snd_interval ch;
+
+	snd_interval_any(&ch);
+
+	/* S32_BE is mono (and stereo) only */
+	if (f->bits[0] == SNDRV_PCM_FMTBIT_S32_BE) {
+		ch.min = 1;
+#ifdef ECHOCARD_HAS_STEREO_BIG_ENDIAN32
+		ch.max = 2;
+#else
+		ch.max = 1;
+#endif
+		ch.integer = 1;
+		return snd_interval_refine(c, &ch);
+	}
+	/* U8 can be only mono or stereo */
+	if (f->bits[0] == SNDRV_PCM_FMTBIT_U8) {
+		ch.min = 1;
+		ch.max = 2;
+		ch.integer = 1;
+		return snd_interval_refine(c, &ch);
+	}
+	/* S16_LE, S24_3LE and S32_LE support any number of channels. */
+	return 0;
+}
+
+
+
+static int hw_rule_playback_format_by_channels(struct snd_pcm_hw_params *params,
+					       struct snd_pcm_hw_rule *rule)
+{
+	struct snd_interval *c = hw_param_interval(params,
+						   SNDRV_PCM_HW_PARAM_CHANNELS);
+	struct snd_mask *f = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
+	struct snd_mask fmt;
+	u64 fmask;
+	snd_mask_any(&fmt);
+
+	fmask = fmt.bits[0] + ((u64)fmt.bits[1] << 32);
+
+	/* >2 channels must be S16_LE, S24_3LE or S32_LE */
+	if (c->min > 2) {
+		fmask &= SNDRV_PCM_FMTBIT_S16_LE |
+			 SNDRV_PCM_FMTBIT_S24_3LE |
+			 SNDRV_PCM_FMTBIT_S32_LE;
+	/* 1 channel must be S32_BE or S32_LE */
+	} else if (c->max == 1)
+		fmask &= SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S32_BE;
+#ifndef ECHOCARD_HAS_STEREO_BIG_ENDIAN32
+	/* 2 channels cannot be S32_BE */
+	else if (c->min == 2 && c->max == 2)
+		fmask &= ~SNDRV_PCM_FMTBIT_S32_BE;
+#endif
+	else
+		return 0;
+
+	fmt.bits[0] &= (u32)fmask;
+	fmt.bits[1] &= (u32)(fmask >> 32);
+	return snd_mask_refine(f, &fmt);
+}
+
+
+
+static int hw_rule_playback_channels_by_format(struct snd_pcm_hw_params *params,
+					       struct snd_pcm_hw_rule *rule)
+{
+	struct snd_interval *c = hw_param_interval(params,
+						   SNDRV_PCM_HW_PARAM_CHANNELS);
+	struct snd_mask *f = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
+	struct snd_interval ch;
+	u64 fmask;
+
+	snd_interval_any(&ch);
+	ch.integer = 1;
+	fmask = f->bits[0] + ((u64)f->bits[1] << 32);
+
+	/* S32_BE is mono (and stereo) only */
+	if (fmask == SNDRV_PCM_FMTBIT_S32_BE) {
+		ch.min = 1;
+#ifdef ECHOCARD_HAS_STEREO_BIG_ENDIAN32
+		ch.max = 2;
+#else
+		ch.max = 1;
+#endif
+	/* U8 is stereo only */
+	} else if (fmask == SNDRV_PCM_FMTBIT_U8)
+		ch.min = ch.max = 2;
+	/* S16_LE and S24_3LE must be at least stereo */
+	else if (!(fmask & ~(SNDRV_PCM_FMTBIT_S16_LE |
+			       SNDRV_PCM_FMTBIT_S24_3LE)))
+		ch.min = 2;
+	else
+		return 0;
+
+	return snd_interval_refine(c, &ch);
+}
+
+
+
+/* Since the sample rate is a global setting, do allow the user to change the
+sample rate only if there is only one pcm device open. */
+static int hw_rule_sample_rate(struct snd_pcm_hw_params *params,
+			       struct snd_pcm_hw_rule *rule)
+{
+	struct snd_interval *rate = hw_param_interval(params,
+						      SNDRV_PCM_HW_PARAM_RATE);
+	struct echoaudio *chip = rule->private;
+	struct snd_interval fixed;
+
+	if (!chip->can_set_rate) {
+		snd_interval_any(&fixed);
+		fixed.min = fixed.max = chip->sample_rate;
+		return snd_interval_refine(rate, &fixed);
+	}
+	return 0;
+}
+
+
+static int pcm_open(struct snd_pcm_substream *substream,
+		    signed char max_channels)
+{
+	struct echoaudio *chip;
+	struct snd_pcm_runtime *runtime;
+	struct audiopipe *pipe;
+	int err, i;
+
+	if (max_channels <= 0)
+		return -EAGAIN;
+
+	chip = snd_pcm_substream_chip(substream);
+	runtime = substream->runtime;
+
+	pipe = kzalloc(sizeof(struct audiopipe), GFP_KERNEL);
+	if (!pipe)
+		return -ENOMEM;
+	pipe->index = -1;		/* Not configured yet */
+
+	/* Set up hw capabilities and contraints */
+	memcpy(&pipe->hw, &pcm_hardware_skel, sizeof(struct snd_pcm_hardware));
+	DE_HWP(("max_channels=%d\n", max_channels));
+	pipe->constr.list = channels_list;
+	pipe->constr.mask = 0;
+	for (i = 0; channels_list[i] <= max_channels; i++);
+	pipe->constr.count = i;
+	if (pipe->hw.channels_max > max_channels)
+		pipe->hw.channels_max = max_channels;
+	if (chip->digital_mode == DIGITAL_MODE_ADAT) {
+		pipe->hw.rate_max = 48000;
+		pipe->hw.rates &= SNDRV_PCM_RATE_8000_48000;
+	}
+
+	runtime->hw = pipe->hw;
+	runtime->private_data = pipe;
+	runtime->private_free = audiopipe_free;
+	snd_pcm_set_sync(substream);
+
+	/* Only mono and any even number of channels are allowed */
+	if ((err = snd_pcm_hw_constraint_list(runtime, 0,
+					      SNDRV_PCM_HW_PARAM_CHANNELS,
+					      &pipe->constr)) < 0)
+		return err;
+
+	/* All periods should have the same size */
+	if ((err = snd_pcm_hw_constraint_integer(runtime,
+						 SNDRV_PCM_HW_PARAM_PERIODS)) < 0)
+		return err;
+
+	/* The hw accesses memory in chunks 32 frames long and they should be
+	32-bytes-aligned. It's not a requirement, but it seems that IRQs are
+	generated with a resolution of 32 frames. Thus we need the following */
+	if ((err = snd_pcm_hw_constraint_step(runtime, 0,
+					      SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
+					      32)) < 0)
+		return err;
+	if ((err = snd_pcm_hw_constraint_step(runtime, 0,
+					      SNDRV_PCM_HW_PARAM_BUFFER_SIZE,
+					      32)) < 0)
+		return err;
+
+	if ((err = snd_pcm_hw_rule_add(substream->runtime, 0,
+				       SNDRV_PCM_HW_PARAM_RATE,
+					hw_rule_sample_rate, chip,
+				       SNDRV_PCM_HW_PARAM_RATE, -1)) < 0)
+		return err;
+
+	/* Finally allocate a page for the scatter-gather list */
+	if ((err = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV,
+				       snd_dma_pci_data(chip->pci),
+				       PAGE_SIZE, &pipe->sgpage)) < 0) {
+		DE_HWP(("s-g list allocation failed\n"));
+		return err;
+	}
+
+	return 0;
+}
+
+
+
+static int pcm_analog_in_open(struct snd_pcm_substream *substream)
+{
+	struct echoaudio *chip = snd_pcm_substream_chip(substream);
+	int err;
+
+	DE_ACT(("pcm_analog_in_open\n"));
+	if ((err = pcm_open(substream, num_analog_busses_in(chip) -
+			    substream->number)) < 0)
+		return err;
+	if ((err = snd_pcm_hw_rule_add(substream->runtime, 0,
+				       SNDRV_PCM_HW_PARAM_CHANNELS,
+				       hw_rule_capture_channels_by_format, NULL,
+				       SNDRV_PCM_HW_PARAM_FORMAT, -1)) < 0)
+		return err;
+	if ((err = snd_pcm_hw_rule_add(substream->runtime, 0,
+				       SNDRV_PCM_HW_PARAM_FORMAT,
+				       hw_rule_capture_format_by_channels, NULL,
+				       SNDRV_PCM_HW_PARAM_CHANNELS, -1)) < 0)
+		return err;
+	atomic_inc(&chip->opencount);
+	if (atomic_read(&chip->opencount) > 1 && chip->rate_set)
+		chip->can_set_rate=0;
+	DE_HWP(("pcm_analog_in_open  cs=%d  oc=%d  r=%d\n",
+		chip->can_set_rate, atomic_read(&chip->opencount),
+		chip->sample_rate));
+	return 0;
+}
+
+
+
+static int pcm_analog_out_open(struct snd_pcm_substream *substream)
+{
+	struct echoaudio *chip = snd_pcm_substream_chip(substream);
+	int max_channels, err;
+
+#ifdef ECHOCARD_HAS_VMIXER
+	max_channels = num_pipes_out(chip);
+#else
+	max_channels = num_analog_busses_out(chip);
+#endif
+	DE_ACT(("pcm_analog_out_open\n"));
+	if ((err = pcm_open(substream, max_channels - substream->number)) < 0)
+		return err;
+	if ((err = snd_pcm_hw_rule_add(substream->runtime, 0,
+				       SNDRV_PCM_HW_PARAM_CHANNELS,
+				       hw_rule_playback_channels_by_format,
+				       NULL,
+				       SNDRV_PCM_HW_PARAM_FORMAT, -1)) < 0)
+		return err;
+	if ((err = snd_pcm_hw_rule_add(substream->runtime, 0,
+				       SNDRV_PCM_HW_PARAM_FORMAT,
+				       hw_rule_playback_format_by_channels,
+				       NULL,
+				       SNDRV_PCM_HW_PARAM_CHANNELS, -1)) < 0)
+		return err;
+	atomic_inc(&chip->opencount);
+	if (atomic_read(&chip->opencount) > 1 && chip->rate_set)
+		chip->can_set_rate=0;
+	DE_HWP(("pcm_analog_out_open  cs=%d  oc=%d  r=%d\n",
+		chip->can_set_rate, atomic_read(&chip->opencount),
+		chip->sample_rate));
+	return 0;
+}
+
+
+
+#ifdef ECHOCARD_HAS_DIGITAL_IO
+
+static int pcm_digital_in_open(struct snd_pcm_substream *substream)
+{
+	struct echoaudio *chip = snd_pcm_substream_chip(substream);
+	int err, max_channels;
+
+	DE_ACT(("pcm_digital_in_open\n"));
+	max_channels = num_digital_busses_in(chip) - substream->number;
+	down(&chip->mode_mutex);
+	if (chip->digital_mode == DIGITAL_MODE_ADAT)
+		err = pcm_open(substream, max_channels);
+	else	/* If the card has ADAT, subtract the 6 channels
+		 * that S/PDIF doesn't have
+		 */
+		err = pcm_open(substream, max_channels - ECHOCARD_HAS_ADAT);
+
+	if (err < 0)
+		goto din_exit;
+
+	if ((err = snd_pcm_hw_rule_add(substream->runtime, 0,
+				       SNDRV_PCM_HW_PARAM_CHANNELS,
+				       hw_rule_capture_channels_by_format, NULL,
+				       SNDRV_PCM_HW_PARAM_FORMAT, -1)) < 0)
+		goto din_exit;
+	if ((err = snd_pcm_hw_rule_add(substream->runtime, 0,
+				       SNDRV_PCM_HW_PARAM_FORMAT,
+				       hw_rule_capture_format_by_channels, NULL,
+				       SNDRV_PCM_HW_PARAM_CHANNELS, -1)) < 0)
+		goto din_exit;
+
+	atomic_inc(&chip->opencount);
+	if (atomic_read(&chip->opencount) > 1 && chip->rate_set)
+		chip->can_set_rate=0;
+
+din_exit:
+	up(&chip->mode_mutex);
+	return err;
+}
+
+
+
+#ifndef ECHOCARD_HAS_VMIXER	/* See the note in snd_echo_new_pcm() */
+
+static int pcm_digital_out_open(struct snd_pcm_substream *substream)
+{
+	struct echoaudio *chip = snd_pcm_substream_chip(substream);
+	int err, max_channels;
+
+	DE_ACT(("pcm_digital_out_open\n"));
+	max_channels = num_digital_busses_out(chip) - substream->number;
+	down(&chip->mode_mutex);
+	if (chip->digital_mode == DIGITAL_MODE_ADAT)
+		err = pcm_open(substream, max_channels);
+	else	/* If the card has ADAT, subtract the 6 channels
+		 * that S/PDIF doesn't have
+		 */
+		err = pcm_open(substream, max_channels - ECHOCARD_HAS_ADAT);
+
+	if (err < 0)
+		goto dout_exit;
+
+	if ((err = snd_pcm_hw_rule_add(substream->runtime, 0,
+				       SNDRV_PCM_HW_PARAM_CHANNELS,
+				       hw_rule_playback_channels_by_format,
+				       NULL, SNDRV_PCM_HW_PARAM_FORMAT,
+				       -1)) < 0)
+		goto dout_exit;
+	if ((err = snd_pcm_hw_rule_add(substream->runtime, 0,
+				       SNDRV_PCM_HW_PARAM_FORMAT,
+				       hw_rule_playback_format_by_channels,
+				       NULL, SNDRV_PCM_HW_PARAM_CHANNELS,
+				       -1)) < 0)
+		goto dout_exit;
+	atomic_inc(&chip->opencount);
+	if (atomic_read(&chip->opencount) > 1 && chip->rate_set)
+		chip->can_set_rate=0;
+dout_exit:
+	up(&chip->mode_mutex);
+	return err;
+}
+
+#endif /* !ECHOCARD_HAS_VMIXER */
+
+#endif /* ECHOCARD_HAS_DIGITAL_IO */
+
+
+
+static int pcm_close(struct snd_pcm_substream *substream)
+{
+	struct echoaudio *chip = snd_pcm_substream_chip(substream);
+	int oc;
+
+	/* Nothing to do here. Audio is already off and pipe will be
+	 * freed by its callback
+	 */
+	DE_ACT(("pcm_close\n"));
+
+	atomic_dec(&chip->opencount);
+	oc = atomic_read(&chip->opencount);
+	DE_ACT(("pcm_close  oc=%d  cs=%d  rs=%d\n", oc,
+		chip->can_set_rate, chip->rate_set));
+	if (oc < 2)
+		chip->can_set_rate = 1;
+	if (oc == 0)
+		chip->rate_set = 0;
+	DE_ACT(("pcm_close2 oc=%d  cs=%d  rs=%d\n", oc,
+		chip->can_set_rate,chip->rate_set));
+
+	return 0;
+}
+
+
+
+/* Channel allocation and scatter-gather list setup */
+static int init_engine(struct snd_pcm_substream *substream,
+		       struct snd_pcm_hw_params *hw_params,
+		       int pipe_index, int interleave)
+{
+	struct echoaudio *chip;
+	int err, per, rest, page, edge, offs;
+	struct snd_sg_buf *sgbuf;
+	struct audiopipe *pipe;
+
+	chip = snd_pcm_substream_chip(substream);
+	pipe = (struct audiopipe *) substream->runtime->private_data;
+
+	/* Sets up che hardware. If it's already initialized, reset and
+	 * redo with the new parameters
+	 */
+	spin_lock_irq(&chip->lock);
+	if (pipe->index >= 0) {
+		DE_HWP(("hwp_ie free(%d)\n", pipe->index));
+		err = free_pipes(chip, pipe);
+		snd_assert(!err);
+		chip->substream[pipe->index] = NULL;
+	}
+
+	err = allocate_pipes(chip, pipe, pipe_index, interleave);
+	if (err < 0) {
+		spin_unlock_irq(&chip->lock);
+		DE_ACT((KERN_NOTICE "allocate_pipes(%d) err=%d\n",
+			pipe_index, err));
+		return err;
+	}
+	spin_unlock_irq(&chip->lock);
+	DE_ACT((KERN_NOTICE "allocate_pipes()=%d\n", pipe_index));
+
+	DE_HWP(("pcm_hw_params (bufsize=%dB periods=%d persize=%dB)\n",
+		params_buffer_bytes(hw_params), params_periods(hw_params),
+		params_period_bytes(hw_params)));
+	err = snd_pcm_lib_malloc_pages(substream,
+				       params_buffer_bytes(hw_params));
+	if (err < 0) {
+		snd_printk(KERN_ERR "malloc_pages err=%d\n", err);
+		spin_lock_irq(&chip->lock);
+		free_pipes(chip, pipe);
+		spin_unlock_irq(&chip->lock);
+		pipe->index = -1;
+		return err;
+	}
+
+	sgbuf = snd_pcm_substream_sgbuf(substream);
+
+	DE_HWP(("pcm_hw_params table size=%d pages=%d\n",
+		sgbuf->size, sgbuf->pages));
+	sglist_init(chip, pipe);
+	edge = PAGE_SIZE;
+	for (offs = page = per = 0; offs < params_buffer_bytes(hw_params);
+	     per++) {
+		rest = params_period_bytes(hw_params);
+		if (offs + rest > params_buffer_bytes(hw_params))
+			rest = params_buffer_bytes(hw_params) - offs;
+		while (rest) {
+			if (rest <= edge - offs) {
+				sglist_add_mapping(chip, pipe,
+						   snd_sgbuf_get_addr(sgbuf, offs),
+						   rest);
+				sglist_add_irq(chip, pipe);
+				offs += rest;
+				rest = 0;
+			} else {
+				sglist_add_mapping(chip, pipe,
+						   snd_sgbuf_get_addr(sgbuf, offs),
+						   edge - offs);
+				rest -= edge - offs;
+				offs = edge;
+			}
+			if (offs == edge) {
+				edge += PAGE_SIZE;
+				page++;
+			}
+		}
+	}
+
+	/* Close the ring buffer */
+	sglist_wrap(chip, pipe);
+
+	/* This stuff is used by the irq handler, so it must be
+	 * initialized before chip->substream
+	 */
+	chip->last_period[pipe_index] = 0;
+	pipe->last_counter = 0;
+	pipe->position = 0;
+	smp_wmb();
+	chip->substream[pipe_index] = substream;
+	chip->rate_set = 1;
+	spin_lock_irq(&chip->lock);
+	set_sample_rate(chip, hw_params->rate_num / hw_params->rate_den);
+	spin_unlock_irq(&chip->lock);
+	DE_HWP(("pcm_hw_params ok\n"));
+	return 0;
+}
+
+
+
+static int pcm_analog_in_hw_params(struct snd_pcm_substream *substream,
+				   struct snd_pcm_hw_params *hw_params)
+{
+	struct echoaudio *chip = snd_pcm_substream_chip(substream);
+
+	return init_engine(substream, hw_params, px_analog_in(chip) +
+			substream->number, params_channels(hw_params));
+}
+
+
+
+static int pcm_analog_out_hw_params(struct snd_pcm_substream *substream,
+				    struct snd_pcm_hw_params *hw_params)
+{
+	return init_engine(substream, hw_params, substream->number,
+			   params_channels(hw_params));
+}
+
+
+
+#ifdef ECHOCARD_HAS_DIGITAL_IO
+
+static int pcm_digital_in_hw_params(struct snd_pcm_substream *substream,
+				    struct snd_pcm_hw_params *hw_params)
+{
+	struct echoaudio *chip = snd_pcm_substream_chip(substream);
+
+	return init_engine(substream, hw_params, px_digital_in(chip) +
+			substream->number, params_channels(hw_params));
+}
+
+
+
+#ifndef ECHOCARD_HAS_VMIXER	/* See the note in snd_echo_new_pcm() */
+static int pcm_digital_out_hw_params(struct snd_pcm_substream *substream,
+				     struct snd_pcm_hw_params *hw_params)
+{
+	struct echoaudio *chip = snd_pcm_substream_chip(substream);
+
+	return init_engine(substream, hw_params, px_digital_out(chip) +
+			substream->number, params_channels(hw_params));
+}
+#endif /* !ECHOCARD_HAS_VMIXER */
+
+#endif /* ECHOCARD_HAS_DIGITAL_IO */
+
+
+
+static int pcm_hw_free(struct snd_pcm_substream *substream)
+{
+	struct echoaudio *chip;
+	struct audiopipe *pipe;
+
+	chip = snd_pcm_substream_chip(substream);
+	pipe = (struct audiopipe *) substream->runtime->private_data;
+
+	spin_lock_irq(&chip->lock);
+	if (pipe->index >= 0) {
+		DE_HWP(("pcm_hw_free(%d)\n", pipe->index));
+		free_pipes(chip, pipe);
+		chip->substream[pipe->index] = NULL;
+		pipe->index = -1;
+	}
+	spin_unlock_irq(&chip->lock);
+
+	DE_HWP(("pcm_hw_freed\n"));
+	snd_pcm_lib_free_pages(substream);
+	return 0;
+}
+
+
+
+static int pcm_prepare(struct snd_pcm_substream *substream)
+{
+	struct echoaudio *chip = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct audioformat format;
+	int pipe_index = ((struct audiopipe *)runtime->private_data)->index;
+
+	DE_HWP(("Prepare rate=%d format=%d channels=%d\n",
+		runtime->rate, runtime->format, runtime->channels));
+	format.interleave = runtime->channels;
+	format.data_are_bigendian = 0;
+	format.mono_to_stereo = 0;
+	switch (runtime->format) {
+	case SNDRV_PCM_FORMAT_U8:
+		format.bits_per_sample = 8;
+		break;
+	case SNDRV_PCM_FORMAT_S16_LE:
+		format.bits_per_sample = 16;
+		break;
+	case SNDRV_PCM_FORMAT_S24_3LE:
+		format.bits_per_sample = 24;
+		break;
+	case SNDRV_PCM_FORMAT_S32_BE:
+		format.data_are_bigendian = 1;
+	case SNDRV_PCM_FORMAT_S32_LE:
+		format.bits_per_sample = 32;
+		break;
+	default:
+		DE_HWP(("Prepare error: unsupported format %d\n",
+			runtime->format));
+		return -EINVAL;
+	}
+
+	snd_assert(pipe_index < px_num(chip), return -EINVAL);
+	snd_assert(is_pipe_allocated(chip, pipe_index), return -EINVAL);
+	set_audio_format(chip, pipe_index, &format);
+	return 0;
+}
+
+
+
+static int pcm_trigger(struct snd_pcm_substream *substream, int cmd)
+{
+	struct echoaudio *chip = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct audiopipe *pipe = runtime->private_data;
+	int i, err;
+	u32 channelmask = 0;
+	struct list_head *pos;
+	struct snd_pcm_substream *s;
+
+	snd_pcm_group_for_each(pos, substream) {
+		s = snd_pcm_group_substream_entry(pos);
+		for (i = 0; i < DSP_MAXPIPES; i++) {
+			if (s == chip->substream[i]) {
+				channelmask |= 1 << i;
+				snd_pcm_trigger_done(s, substream);
+			}
+		}
+	}
+
+	spin_lock(&chip->lock);
+	switch (cmd) {
+	case SNDRV_PCM_TRIGGER_START:
+	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
+		DE_ACT(("pcm_trigger start\n"));
+		for (i = 0; i < DSP_MAXPIPES; i++) {
+			if (channelmask & (1 << i)) {
+				pipe = chip->substream[i]->runtime->private_data;
+				switch (pipe->state) {
+				case PIPE_STATE_STOPPED:
+					chip->last_period[i] = 0;
+					pipe->last_counter = 0;
+					pipe->position = 0;
+					*pipe->dma_counter = 0;
+				case PIPE_STATE_PAUSED:
+					pipe->state = PIPE_STATE_STARTED;
+					break;
+				case PIPE_STATE_STARTED:
+					break;
+				}
+			}
+		}
+		err = start_transport(chip, channelmask,
+				      chip->pipe_cyclic_mask);
+		break;
+	case SNDRV_PCM_TRIGGER_STOP:
+		DE_ACT(("pcm_trigger stop\n"));
+		for (i = 0; i < DSP_MAXPIPES; i++) {
+			if (channelmask & (1 << i)) {
+				pipe = chip->substream[i]->runtime->private_data;
+				pipe->state = PIPE_STATE_STOPPED;
+			}
+		}
+		err = stop_transport(chip, channelmask);
+		break;
+	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
+		DE_ACT(("pcm_trigger pause\n"));
+		for (i = 0; i < DSP_MAXPIPES; i++) {
+			if (channelmask & (1 << i)) {
+				pipe = chip->substream[i]->runtime->private_data;
+				pipe->state = PIPE_STATE_PAUSED;
+			}
+		}
+		err = pause_transport(chip, channelmask);
+		break;
+	default:
+		err = -EINVAL;
+	}
+	spin_unlock(&chip->lock);
+	return err;
+}
+
+
+
+static snd_pcm_uframes_t pcm_pointer(struct snd_pcm_substream *substream)
+{
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct audiopipe *pipe = runtime->private_data;
+	size_t cnt, bufsize, pos;
+
+	cnt = le32_to_cpu(*pipe->dma_counter);
+	pipe->position += cnt - pipe->last_counter;
+	pipe->last_counter = cnt;
+	bufsize = substream->runtime->buffer_size;
+	pos = bytes_to_frames(substream->runtime, pipe->position);
+
+	while (pos >= bufsize) {
+		pipe->position -= frames_to_bytes(substream->runtime, bufsize);
+		pos -= bufsize;
+	}
+	return pos;
+}
+
+
+
+/* pcm *_ops structures */
+static struct snd_pcm_ops analog_playback_ops = {
+	.open = pcm_analog_out_open,
+	.close = pcm_close,
+	.ioctl = snd_pcm_lib_ioctl,
+	.hw_params = pcm_analog_out_hw_params,
+	.hw_free = pcm_hw_free,
+	.prepare = pcm_prepare,
+	.trigger = pcm_trigger,
+	.pointer = pcm_pointer,
+	.page = snd_pcm_sgbuf_ops_page,
+};
+static struct snd_pcm_ops analog_capture_ops = {
+	.open = pcm_analog_in_open,
+	.close = pcm_close,
+	.ioctl = snd_pcm_lib_ioctl,
+	.hw_params = pcm_analog_in_hw_params,
+	.hw_free = pcm_hw_free,
+	.prepare = pcm_prepare,
+	.trigger = pcm_trigger,
+	.pointer = pcm_pointer,
+	.page = snd_pcm_sgbuf_ops_page,
+};
+#ifdef ECHOCARD_HAS_DIGITAL_IO
+#ifndef ECHOCARD_HAS_VMIXER
+static struct snd_pcm_ops digital_playback_ops = {
+	.open = pcm_digital_out_open,
+	.close = pcm_close,
+	.ioctl = snd_pcm_lib_ioctl,
+	.hw_params = pcm_digital_out_hw_params,
+	.hw_free = pcm_hw_free,
+	.prepare = pcm_prepare,
+	.trigger = pcm_trigger,
+	.pointer = pcm_pointer,
+	.page = snd_pcm_sgbuf_ops_page,
+};
+#endif /* !ECHOCARD_HAS_VMIXER */
+static struct snd_pcm_ops digital_capture_ops = {
+	.open = pcm_digital_in_open,
+	.close = pcm_close,
+	.ioctl = snd_pcm_lib_ioctl,
+	.hw_params = pcm_digital_in_hw_params,
+	.hw_free = pcm_hw_free,
+	.prepare = pcm_prepare,
+	.trigger = pcm_trigger,
+	.pointer = pcm_pointer,
+	.page = snd_pcm_sgbuf_ops_page,
+};
+#endif /* ECHOCARD_HAS_DIGITAL_IO */
+
+
+
+/* Preallocate memory only for the first substream because it's the most
+ * used one
+ */
+static int snd_echo_preallocate_pages(struct snd_pcm *pcm, struct device *dev)
+{
+	struct snd_pcm_substream *ss;
+	int stream, err;
+
+	for (stream = 0; stream < 2; stream++)
+		for (ss = pcm->streams[stream].substream; ss; ss = ss->next) {
+			err = snd_pcm_lib_preallocate_pages(ss, SNDRV_DMA_TYPE_DEV_SG,
+							    dev,
+							    ss->number ? 0 : 128<<10,
+							    256<<10);
+			if (err < 0)
+				return err;
+		}
+	return 0;
+}
+
+
+
+/*<--snd_echo_probe() */
+static int __devinit snd_echo_new_pcm(struct echoaudio *chip)
+{
+	struct snd_pcm *pcm;
+	int err;
+
+#ifdef ECHOCARD_HAS_VMIXER
+	/* This card has a Vmixer, that is there is no direct mapping from PCM
+	streams to physical outputs. The user can mix the streams as he wishes
+	via control interface and it's possible to send any stream to any
+	output, thus it makes no sense to keep analog and digital outputs
+	separated */
+
+	/* PCM#0 Virtual outputs and analog inputs */
+	if ((err = snd_pcm_new(chip->card, "PCM", 0, num_pipes_out(chip),
+				num_analog_busses_in(chip), &pcm)) < 0)
+		return err;
+	pcm->private_data = chip;
+	chip->analog_pcm = pcm;
+	strcpy(pcm->name, chip->card->shortname);
+	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &analog_playback_ops);
+	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &analog_capture_ops);
+	if ((err = snd_echo_preallocate_pages(pcm, snd_dma_pci_data(chip->pci))) < 0)
+		return err;
+	DE_INIT(("Analog PCM ok\n"));
+
+#ifdef ECHOCARD_HAS_DIGITAL_IO
+	/* PCM#1 Digital inputs, no outputs */
+	if ((err = snd_pcm_new(chip->card, "Digital PCM", 1, 0,
+			       num_digital_busses_in(chip), &pcm)) < 0)
+		return err;
+	pcm->private_data = chip;
+	chip->digital_pcm = pcm;
+	strcpy(pcm->name, chip->card->shortname);
+	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &digital_capture_ops);
+	if ((err = snd_echo_preallocate_pages(pcm, snd_dma_pci_data(chip->pci))) < 0)
+		return err;
+	DE_INIT(("Digital PCM ok\n"));
+#endif /* ECHOCARD_HAS_DIGITAL_IO */
+
+#else /* ECHOCARD_HAS_VMIXER */
+
+	/* The card can manage substreams formed by analog and digital channels
+	at the same time, but I prefer to keep analog and digital channels
+	separated, because that mixed thing is confusing and useless. So we
+	register two PCM devices: */
+
+	/* PCM#0 Analog i/o */
+	if ((err = snd_pcm_new(chip->card, "Analog PCM", 0,
+			       num_analog_busses_out(chip),
+			       num_analog_busses_in(chip), &pcm)) < 0)
+		return err;
+	pcm->private_data = chip;
+	chip->analog_pcm = pcm;
+	strcpy(pcm->name, chip->card->shortname);
+	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &analog_playback_ops);
+	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &analog_capture_ops);
+	if ((err = snd_echo_preallocate_pages(pcm, snd_dma_pci_data(chip->pci))) < 0)
+		return err;
+	DE_INIT(("Analog PCM ok\n"));
+
+#ifdef ECHOCARD_HAS_DIGITAL_IO
+	/* PCM#1 Digital i/o */
+	if ((err = snd_pcm_new(chip->card, "Digital PCM", 1,
+			       num_digital_busses_out(chip),
+			       num_digital_busses_in(chip), &pcm)) < 0)
+		return err;
+	pcm->private_data = chip;
+	chip->digital_pcm = pcm;
+	strcpy(pcm->name, chip->card->shortname);
+	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &digital_playback_ops);
+	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &digital_capture_ops);
+	if ((err = snd_echo_preallocate_pages(pcm, snd_dma_pci_data(chip->pci))) < 0)
+		return err;
+	DE_INIT(("Digital PCM ok\n"));
+#endif /* ECHOCARD_HAS_DIGITAL_IO */
+
+#endif /* ECHOCARD_HAS_VMIXER */
+
+	return 0;
+}
+
+
+
+
+/******************************************************************************
+	Control interface
+******************************************************************************/
+
+/******************* PCM output volume *******************/
+static int snd_echo_output_gain_info(struct snd_kcontrol *kcontrol,
+				     struct snd_ctl_elem_info *uinfo)
+{
+	struct echoaudio *chip;
+
+	chip = snd_kcontrol_chip(kcontrol);
+	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
+	uinfo->count = num_busses_out(chip);
+	uinfo->value.integer.min = ECHOGAIN_MINOUT;
+	uinfo->value.integer.max = ECHOGAIN_MAXOUT;
+	return 0;
+}
+
+static int snd_echo_output_gain_get(struct snd_kcontrol *kcontrol,
+				    struct snd_ctl_elem_value *ucontrol)
+{
+	struct echoaudio *chip;
+	int c;
+
+	chip = snd_kcontrol_chip(kcontrol);
+	for (c = 0; c < num_busses_out(chip); c++)
+		ucontrol->value.integer.value[c] = chip->output_gain[c];
+	return 0;
+}
+
+static int snd_echo_output_gain_put(struct snd_kcontrol *kcontrol,
+				    struct snd_ctl_elem_value *ucontrol)
+{
+	struct echoaudio *chip;
+	int c, changed, gain;
+
+	changed = 0;
+	chip = snd_kcontrol_chip(kcontrol);
+	spin_lock_irq(&chip->lock);
+	for (c = 0; c < num_busses_out(chip); c++) {
+		gain = ucontrol->value.integer.value[c];
+		/* Ignore out of range values */
+		if (gain < ECHOGAIN_MINOUT || gain > ECHOGAIN_MAXOUT)
+			continue;
+		if (chip->output_gain[c] != gain) {
+			set_output_gain(chip, c, gain);
+			changed = 1;
+		}
+	}
+	if (changed)
+		update_output_line_level(chip);
+	spin_unlock_irq(&chip->lock);
+	return changed;
+}
+
+#ifdef ECHOCARD_HAS_VMIXER
+/* On Vmixer cards this one controls the line-out volume */
+static struct snd_kcontrol_new snd_echo_line_output_gain __devinitdata = {
+	.name = "Line Playback Volume",
+	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+	.info = snd_echo_output_gain_info,
+	.get = snd_echo_output_gain_get,
+	.put = snd_echo_output_gain_put,
+};
+#else
+static struct snd_kcontrol_new snd_echo_pcm_output_gain __devinitdata = {
+	.name = "PCM Playback Volume",
+	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+	.info = snd_echo_output_gain_info,
+	.get = snd_echo_output_gain_get,
+	.put = snd_echo_output_gain_put,
+};
+#endif
+
+
+
+#ifdef ECHOCARD_HAS_INPUT_GAIN
+
+/******************* Analog input volume *******************/
+static int snd_echo_input_gain_info(struct snd_kcontrol *kcontrol,
+				    struct snd_ctl_elem_info *uinfo)
+{
+	struct echoaudio *chip;
+
+	chip = snd_kcontrol_chip(kcontrol);
+	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
+	uinfo->count = num_analog_busses_in(chip);
+	uinfo->value.integer.min = ECHOGAIN_MININP;
+	uinfo->value.integer.max = ECHOGAIN_MAXINP;
+	return 0;
+}
+
+static int snd_echo_input_gain_get(struct snd_kcontrol *kcontrol,
+				   struct snd_ctl_elem_value *ucontrol)
+{
+	struct echoaudio *chip;
+	int c;
+
+	chip = snd_kcontrol_chip(kcontrol);
+	for (c = 0; c < num_analog_busses_in(chip); c++)
+		ucontrol->value.integer.value[c] = chip->input_gain[c];
+	return 0;
+}
+
+static int snd_echo_input_gain_put(struct snd_kcontrol *kcontrol,
+				   struct snd_ctl_elem_value *ucontrol)
+{
+	struct echoaudio *chip;
+	int c, gain, changed;
+
+	changed = 0;
+	chip = snd_kcontrol_chip(kcontrol);
+	spin_lock_irq(&chip->lock);
+	for (c = 0; c < num_analog_busses_in(chip); c++) {
+		gain = ucontrol->value.integer.value[c];
+		/* Ignore out of range values */
+		if (gain < ECHOGAIN_MININP || gain > ECHOGAIN_MAXINP)
+			continue;
+		if (chip->input_gain[c] != gain) {
+			set_input_gain(chip, c, gain);
+			changed = 1;
+		}
+	}
+	if (changed)
+		update_input_line_level(chip);
+	spin_unlock_irq(&chip->lock);
+	return changed;
+}
+
+static struct snd_kcontrol_new snd_echo_line_input_gain __devinitdata = {
+	.name = "Line Capture Volume",
+	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+	.info = snd_echo_input_gain_info,
+	.get = snd_echo_input_gain_get,
+	.put = snd_echo_input_gain_put,
+};
+
+#endif /* ECHOCARD_HAS_INPUT_GAIN */
+
+
+
+#ifdef ECHOCARD_HAS_OUTPUT_NOMINAL_LEVEL
+
+/************ Analog output nominal level (+4dBu / -10dBV) ***************/
+static int snd_echo_output_nominal_info (struct snd_kcontrol *kcontrol,
+					 struct snd_ctl_elem_info *uinfo)
+{
+	struct echoaudio *chip;
+
+	chip = snd_kcontrol_chip(kcontrol);
+	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
+	uinfo->count = num_analog_busses_out(chip);
+	uinfo->value.integer.min = 0;
+	uinfo->value.integer.max = 1;
+	return 0;
+}
+
+static int snd_echo_output_nominal_get(struct snd_kcontrol *kcontrol,
+				       struct snd_ctl_elem_value *ucontrol)
+{
+	struct echoaudio *chip;
+	int c;
+
+	chip = snd_kcontrol_chip(kcontrol);
+	for (c = 0; c < num_analog_busses_out(chip); c++)
+		ucontrol->value.integer.value[c] = chip->nominal_level[c];
+	return 0;
+}
+
+static int snd_echo_output_nominal_put(struct snd_kcontrol *kcontrol,
+				       struct snd_ctl_elem_value *ucontrol)
+{
+	struct echoaudio *chip;
+	int c, changed;
+
+	changed = 0;
+	chip = snd_kcontrol_chip(kcontrol);
+	spin_lock_irq(&chip->lock);
+	for (c = 0; c < num_analog_busses_out(chip); c++) {
+		if (chip->nominal_level[c] != ucontrol->value.integer.value[c]) {
+			set_nominal_level(chip, c,
+					  ucontrol->value.integer.value[c]);
+			changed = 1;
+		}
+	}
+	if (changed)
+		update_output_line_level(chip);
+	spin_unlock_irq(&chip->lock);
+	return changed;
+}
+
+static struct snd_kcontrol_new snd_echo_output_nominal_level __devinitdata = {
+	.name = "Line Playback Switch (-10dBV)",
+	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+	.info = snd_echo_output_nominal_info,
+	.get = snd_echo_output_nominal_get,
+	.put = snd_echo_output_nominal_put,
+};
+
+#endif /* ECHOCARD_HAS_OUTPUT_NOMINAL_LEVEL */
+
+
+
+#ifdef ECHOCARD_HAS_INPUT_NOMINAL_LEVEL
+
+/*************** Analog input nominal level (+4dBu / -10dBV) ***************/
+static int snd_echo_input_nominal_info(struct snd_kcontrol *kcontrol,
+				       struct snd_ctl_elem_info *uinfo)
+{
+	struct echoaudio *chip;
+
+	chip = snd_kcontrol_chip(kcontrol);
+	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
+	uinfo->count = num_analog_busses_in(chip);
+	uinfo->value.integer.min = 0;
+	uinfo->value.integer.max = 1;
+	return 0;
+}
+
+static int snd_echo_input_nominal_get(struct snd_kcontrol *kcontrol,
+				      struct snd_ctl_elem_value *ucontrol)
+{
+	struct echoaudio *chip;
+	int c;
+
+	chip = snd_kcontrol_chip(kcontrol);
+	for (c = 0; c < num_analog_busses_in(chip); c++)
+		ucontrol->value.integer.value[c] =
+			chip->nominal_level[bx_analog_in(chip) + c];
+	return 0;
+}
+
+static int snd_echo_input_nominal_put(struct snd_kcontrol *kcontrol,
+				      struct snd_ctl_elem_value *ucontrol)
+{
+	struct echoaudio *chip;
+	int c, changed;
+
+	changed = 0;
+	chip = snd_kcontrol_chip(kcontrol);
+	spin_lock_irq(&chip->lock);
+	for (c = 0; c < num_analog_busses_in(chip); c++) {
+		if (chip->nominal_level[bx_analog_in(chip) + c] !=
+		    ucontrol->value.integer.value[c]) {
+			set_nominal_level(chip, bx_analog_in(chip) + c,
+					  ucontrol->value.integer.value[c]);
+			changed = 1;
+		}
+	}
+	if (changed)
+		update_output_line_level(chip);	/* "Output" is not a mistake
+						 * here.
+						 */
+	spin_unlock_irq(&chip->lock);
+	return changed;
+}
+
+static struct snd_kcontrol_new snd_echo_intput_nominal_level __devinitdata = {
+	.name = "Line Capture Switch (-10dBV)",
+	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+	.info = snd_echo_input_nominal_info,
+	.get = snd_echo_input_nominal_get,
+	.put = snd_echo_input_nominal_put,
+};
+
+#endif /* ECHOCARD_HAS_INPUT_NOMINAL_LEVEL */
+
+
+
+#ifdef ECHOCARD_HAS_MONITOR
+
+/******************* Monitor mixer *******************/
+static int snd_echo_mixer_info(struct snd_kcontrol *kcontrol,
+			       struct snd_ctl_elem_info *uinfo)
+{
+	struct echoaudio *chip;
+
+	chip = snd_kcontrol_chip(kcontrol);
+	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
+	uinfo->count = 1;
+	uinfo->value.integer.min = ECHOGAIN_MINOUT;
+	uinfo->value.integer.max = ECHOGAIN_MAXOUT;
+	uinfo->dimen.d[0] = num_busses_out(chip);
+	uinfo->dimen.d[1] = num_busses_in(chip);
+	return 0;
+}
+
+static int snd_echo_mixer_get(struct snd_kcontrol *kcontrol,
+			      struct snd_ctl_elem_value *ucontrol)
+{
+	struct echoaudio *chip;
+
+	chip = snd_kcontrol_chip(kcontrol);
+	ucontrol->value.integer.value[0] =
+		chip->monitor_gain[ucontrol->id.index / num_busses_in(chip)]
+			[ucontrol->id.index % num_busses_in(chip)];
+	return 0;
+}
+
+static int snd_echo_mixer_put(struct snd_kcontrol *kcontrol,
+			      struct snd_ctl_elem_value *ucontrol)
+{
+	struct echoaudio *chip;
+	int changed,  gain;
+	short out, in;
+
+	changed = 0;
+	chip = snd_kcontrol_chip(kcontrol);
+	out = ucontrol->id.index / num_busses_in(chip);
+	in = ucontrol->id.index % num_busses_in(chip);
+	gain = ucontrol->value.integer.value[0];
+	if (gain < ECHOGAIN_MINOUT || gain > ECHOGAIN_MAXOUT)
+		return -EINVAL;
+	if (chip->monitor_gain[out][in] != gain) {
+		spin_lock_irq(&chip->lock);
+		set_monitor_gain(chip, out, in, gain);
+		update_output_line_level(chip);
+		spin_unlock_irq(&chip->lock);
+		changed = 1;
+	}
+	return changed;
+}
+
+static struct snd_kcontrol_new snd_echo_monitor_mixer __devinitdata = {
+	.name = "Monitor Mixer Volume",
+	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+	.info = snd_echo_mixer_info,
+	.get = snd_echo_mixer_get,
+	.put = snd_echo_mixer_put,
+};
+
+#endif /* ECHOCARD_HAS_MONITOR */
+
+
+
+#ifdef ECHOCARD_HAS_VMIXER
+
+/******************* Vmixer *******************/
+static int snd_echo_vmixer_info(struct snd_kcontrol *kcontrol,
+				struct snd_ctl_elem_info *uinfo)
+{
+	struct echoaudio *chip;
+
+	chip = snd_kcontrol_chip(kcontrol);
+	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
+	uinfo->count = 1;
+	uinfo->value.integer.min = ECHOGAIN_MINOUT;
+	uinfo->value.integer.max = ECHOGAIN_MAXOUT;
+	uinfo->dimen.d[0] = num_busses_out(chip);
+	uinfo->dimen.d[1] = num_pipes_out(chip);
+	return 0;
+}
+
+static int snd_echo_vmixer_get(struct snd_kcontrol *kcontrol,
+			       struct snd_ctl_elem_value *ucontrol)
+{
+	struct echoaudio *chip;
+
+	chip = snd_kcontrol_chip(kcontrol);
+	ucontrol->value.integer.value[0] =
+		chip->vmixer_gain[ucontrol->id.index / num_pipes_out(chip)]
+			[ucontrol->id.index % num_pipes_out(chip)];
+	return 0;
+}
+
+static int snd_echo_vmixer_put(struct snd_kcontrol *kcontrol,
+			       struct snd_ctl_elem_value *ucontrol)
+{
+	struct echoaudio *chip;
+	int gain, changed;
+	short vch, out;
+
+	changed = 0;
+	chip = snd_kcontrol_chip(kcontrol);
+	out = ucontrol->id.index / num_pipes_out(chip);
+	vch = ucontrol->id.index % num_pipes_out(chip);
+	gain = ucontrol->value.integer.value[0];
+	if (gain < ECHOGAIN_MINOUT || gain > ECHOGAIN_MAXOUT)
+		return -EINVAL;
+	if (chip->vmixer_gain[out][vch] != ucontrol->value.integer.value[0]) {
+		spin_lock_irq(&chip->lock);
+		set_vmixer_gain(chip, out, vch, ucontrol->value.integer.value[0]);
+		update_vmixer_level(chip);
+		spin_unlock_irq(&chip->lock);
+		changed = 1;
+	}
+	return changed;
+}
+
+static struct snd_kcontrol_new snd_echo_vmixer __devinitdata = {
+	.name = "VMixer Volume",
+	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+	.info = snd_echo_vmixer_info,
+	.get = snd_echo_vmixer_get,
+	.put = snd_echo_vmixer_put,
+};
+
+#endif /* ECHOCARD_HAS_VMIXER */
+
+
+
+#ifdef ECHOCARD_HAS_DIGITAL_MODE_SWITCH
+
+/******************* Digital mode switch *******************/
+static int snd_echo_digital_mode_info(struct snd_kcontrol *kcontrol,
+				      struct snd_ctl_elem_info *uinfo)
+{
+	static char *names[4] = {
+		"S/PDIF Coaxial", "S/PDIF Optical", "ADAT Optical",
+		"S/PDIF Cdrom"
+	};
+	struct echoaudio *chip;
+
+	chip = snd_kcontrol_chip(kcontrol);
+	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
+	uinfo->value.enumerated.items = chip->num_digital_modes;
+	uinfo->count = 1;
+	if (uinfo->value.enumerated.item >= chip->num_digital_modes)
+		uinfo->value.enumerated.item = chip->num_digital_modes - 1;
+	strcpy(uinfo->value.enumerated.name, names[
+			chip->digital_mode_list[uinfo->value.enumerated.item]]);
+	return 0;
+}
+
+static int snd_echo_digital_mode_get(struct snd_kcontrol *kcontrol,
+				     struct snd_ctl_elem_value *ucontrol)
+{
+	struct echoaudio *chip;
+	int i, mode;
+
+	chip = snd_kcontrol_chip(kcontrol);
+	mode = chip->digital_mode;
+	for (i = chip->num_digital_modes - 1; i >= 0; i--)
+		if (mode == chip->digital_mode_list[i]) {
+			ucontrol->value.enumerated.item[0] = i;
+			break;
+		}
+	return 0;
+}
+
+static int snd_echo_digital_mode_put(struct snd_kcontrol *kcontrol,
+				     struct snd_ctl_elem_value *ucontrol)
+{
+	struct echoaudio *chip;
+	int changed;
+	unsigned short emode, dmode;
+
+	changed = 0;
+	chip = snd_kcontrol_chip(kcontrol);
+
+	emode = ucontrol->value.enumerated.item[0];
+	if (emode >= chip->num_digital_modes)
+		return -EINVAL;
+	dmode = chip->digital_mode_list[emode];
+
+	if (dmode != chip->digital_mode) {
+		/* mode_mutex is required to make this operation atomic wrt
+		pcm_digital_*_open() and set_input_clock() functions. */
+		down(&chip->mode_mutex);
+
+		/* Do not allow the user to change the digital mode when a pcm
+		device is open because it also changes the number of channels
+		and the allowed sample rates */
+		if (atomic_read(&chip->opencount)) {
+			changed = -EAGAIN;
+		} else {
+			changed = set_digital_mode(chip, dmode);
+			/* If we had to change the clock source, report it */
+			if (changed > 0 && chip->clock_src_ctl) {
+				snd_ctl_notify(chip->card,
+					       SNDRV_CTL_EVENT_MASK_VALUE,
+					       &chip->clock_src_ctl->id);
+				DE_ACT(("SDM() =%d\n", changed));
+			}
+			if (changed >= 0)
+				changed = 1;	/* No errors */
+		}
+		up(&chip->mode_mutex);
+	}
+	return changed;
+}
+
+static struct snd_kcontrol_new snd_echo_digital_mode_switch __devinitdata = {
+	.name = "Digital mode Switch",
+	.iface = SNDRV_CTL_ELEM_IFACE_CARD,
+	.info = snd_echo_digital_mode_info,
+	.get = snd_echo_digital_mode_get,
+	.put = snd_echo_digital_mode_put,
+};
+
+#endif /* ECHOCARD_HAS_DIGITAL_MODE_SWITCH */
+
+
+
+#ifdef ECHOCARD_HAS_DIGITAL_IO
+
+/******************* S/PDIF mode switch *******************/
+static int snd_echo_spdif_mode_info(struct snd_kcontrol *kcontrol,
+				    struct snd_ctl_elem_info *uinfo)
+{
+	static char *names[2] = {"Consumer", "Professional"};
+
+	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
+	uinfo->value.enumerated.items = 2;
+	uinfo->count = 1;
+	if (uinfo->value.enumerated.item)
+		uinfo->value.enumerated.item = 1;
+	strcpy(uinfo->value.enumerated.name,
+	       names[uinfo->value.enumerated.item]);
+	return 0;
+}
+
+static int snd_echo_spdif_mode_get(struct snd_kcontrol *kcontrol,
+				   struct snd_ctl_elem_value *ucontrol)
+{
+	struct echoaudio *chip;
+
+	chip = snd_kcontrol_chip(kcontrol);
+	ucontrol->value.enumerated.item[0] = !!chip->professional_spdif;
+	return 0;
+}
+
+static int snd_echo_spdif_mode_put(struct snd_kcontrol *kcontrol,
+				   struct snd_ctl_elem_value *ucontrol)
+{
+	struct echoaudio *chip;
+	int mode;
+
+	chip = snd_kcontrol_chip(kcontrol);
+	mode = !!ucontrol->value.enumerated.item[0];
+	if (mode != chip->professional_spdif) {
+		spin_lock_irq(&chip->lock);
+		set_professional_spdif(chip, mode);
+		spin_unlock_irq(&chip->lock);
+		return 1;
+	}
+	return 0;
+}
+
+static struct snd_kcontrol_new snd_echo_spdif_mode_switch __devinitdata = {
+	.name = "S/PDIF mode Switch",
+	.iface = SNDRV_CTL_ELEM_IFACE_CARD,
+	.info = snd_echo_spdif_mode_info,
+	.get = snd_echo_spdif_mode_get,
+	.put = snd_echo_spdif_mode_put,
+};
+
+#endif /* ECHOCARD_HAS_DIGITAL_IO */
+
+
+
+#ifdef ECHOCARD_HAS_EXTERNAL_CLOCK
+
+/******************* Select input clock source *******************/
+static int snd_echo_clock_source_info(struct snd_kcontrol *kcontrol,
+				      struct snd_ctl_elem_info *uinfo)
+{
+	static char *names[8] = {
+		"Internal", "Word", "Super", "S/PDIF", "ADAT", "ESync",
+		"ESync96", "MTC"
+	};
+	struct echoaudio *chip;
+
+	chip = snd_kcontrol_chip(kcontrol);
+	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
+	uinfo->value.enumerated.items = chip->num_clock_sources;
+	uinfo->count = 1;
+	if (uinfo->value.enumerated.item >= chip->num_clock_sources)
+		uinfo->value.enumerated.item = chip->num_clock_sources - 1;
+	strcpy(uinfo->value.enumerated.name, names[
+			chip->clock_source_list[uinfo->value.enumerated.item]]);
+	return 0;
+}
+
+static int snd_echo_clock_source_get(struct snd_kcontrol *kcontrol,
+				     struct snd_ctl_elem_value *ucontrol)
+{
+	struct echoaudio *chip;
+	int i, clock;
+
+	chip = snd_kcontrol_chip(kcontrol);
+	clock = chip->input_clock;
+
+	for (i = 0; i < chip->num_clock_sources; i++)
+		if (clock == chip->clock_source_list[i])
+			ucontrol->value.enumerated.item[0] = i;
+
+	return 0;
+}
+
+static int snd_echo_clock_source_put(struct snd_kcontrol *kcontrol,
+				     struct snd_ctl_elem_value *ucontrol)
+{
+	struct echoaudio *chip;
+	int changed;
+	unsigned int eclock, dclock;
+
+	changed = 0;
+	chip = snd_kcontrol_chip(kcontrol);
+	eclock = ucontrol->value.enumerated.item[0];
+	if (eclock >= chip->input_clock_types)
+		return -EINVAL;
+	dclock = chip->clock_source_list[eclock];
+	if (chip->input_clock != dclock) {
+		down(&chip->mode_mutex);
+		spin_lock_irq(&chip->lock);
+		if ((changed = set_input_clock(chip, dclock)) == 0)
+			changed = 1;	/* no errors */
+		spin_unlock_irq(&chip->lock);
+		up(&chip->mode_mutex);
+	}
+
+	if (changed < 0)
+		DE_ACT(("seticlk val%d err 0x%x\n", dclock, changed));
+
+	return changed;
+}
+
+static struct snd_kcontrol_new snd_echo_clock_source_switch __devinitdata = {
+	.name = "Sample Clock Source",
+	.iface = SNDRV_CTL_ELEM_IFACE_PCM,
+	.info = snd_echo_clock_source_info,
+	.get = snd_echo_clock_source_get,
+	.put = snd_echo_clock_source_put,
+};
+
+#endif /* ECHOCARD_HAS_EXTERNAL_CLOCK */
+
+
+
+#ifdef ECHOCARD_HAS_PHANTOM_POWER
+
+/******************* Phantom power switch *******************/
+static int snd_echo_phantom_power_info(struct snd_kcontrol *kcontrol,
+				       struct snd_ctl_elem_info *uinfo)
+{
+	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
+	uinfo->count = 1;
+	uinfo->value.integer.min = 0;
+	uinfo->value.integer.max = 1;
+	return 0;
+}
+
+static int snd_echo_phantom_power_get(struct snd_kcontrol *kcontrol,
+				      struct snd_ctl_elem_value *ucontrol)
+{
+	struct echoaudio *chip = snd_kcontrol_chip(kcontrol);
+
+	ucontrol->value.integer.value[0] = chip->phantom_power;
+	return 0;
+}
+
+static int snd_echo_phantom_power_put(struct snd_kcontrol *kcontrol,
+				      struct snd_ctl_elem_value *ucontrol)
+{
+	struct echoaudio *chip = snd_kcontrol_chip(kcontrol);
+	int power, changed = 0;
+
+	power = !!ucontrol->value.integer.value[0];
+	if (chip->phantom_power != power) {
+		spin_lock_irq(&chip->lock);
+		changed = set_phantom_power(chip, power);
+		spin_unlock_irq(&chip->lock);
+		if (changed == 0)
+			changed = 1;	/* no errors */
+	}
+	return changed;
+}
+
+static struct snd_kcontrol_new snd_echo_phantom_power_switch __devinitdata = {
+	.name = "Phantom power Switch",
+	.iface = SNDRV_CTL_ELEM_IFACE_CARD,
+	.info = snd_echo_phantom_power_info,
+	.get = snd_echo_phantom_power_get,
+	.put = snd_echo_phantom_power_put,
+};
+
+#endif /* ECHOCARD_HAS_PHANTOM_POWER */
+
+
+
+#ifdef ECHOCARD_HAS_DIGITAL_IN_AUTOMUTE
+
+/******************* Digital input automute switch *******************/
+static int snd_echo_automute_info(struct snd_kcontrol *kcontrol,
+				  struct snd_ctl_elem_info *uinfo)
+{
+	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
+	uinfo->count = 1;
+	uinfo->value.integer.min = 0;
+	uinfo->value.integer.max = 1;
+	return 0;
+}
+
+static int snd_echo_automute_get(struct snd_kcontrol *kcontrol,
+				 struct snd_ctl_elem_value *ucontrol)
+{
+	struct echoaudio *chip = snd_kcontrol_chip(kcontrol);
+
+	ucontrol->value.integer.value[0] = chip->digital_in_automute;
+	return 0;
+}
+
+static int snd_echo_automute_put(struct snd_kcontrol *kcontrol,
+				 struct snd_ctl_elem_value *ucontrol)
+{
+	struct echoaudio *chip = snd_kcontrol_chip(kcontrol);
+	int automute, changed = 0;
+
+	automute = !!ucontrol->value.integer.value[0];
+	if (chip->digital_in_automute != automute) {
+		spin_lock_irq(&chip->lock);
+		changed = set_input_auto_mute(chip, automute);
+		spin_unlock_irq(&chip->lock);
+		if (changed == 0)
+			changed = 1;	/* no errors */
+	}
+	return changed;
+}
+
+static struct snd_kcontrol_new snd_echo_automute_switch __devinitdata = {
+	.name = "Digital Capture Switch (automute)",
+	.iface = SNDRV_CTL_ELEM_IFACE_CARD,
+	.info = snd_echo_automute_info,
+	.get = snd_echo_automute_get,
+	.put = snd_echo_automute_put,
+};
+
+#endif /* ECHOCARD_HAS_DIGITAL_IN_AUTOMUTE */
+
+
+
+/******************* VU-meters switch *******************/
+static int snd_echo_vumeters_switch_info(struct snd_kcontrol *kcontrol,
+					 struct snd_ctl_elem_info *uinfo)
+{
+	struct echoaudio *chip;
+
+	chip = snd_kcontrol_chip(kcontrol);
+	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
+	uinfo->count = 1;
+	uinfo->value.integer.min = 0;
+	uinfo->value.integer.max = 1;
+	return 0;
+}
+
+static int snd_echo_vumeters_switch_put(struct snd_kcontrol *kcontrol,
+					struct snd_ctl_elem_value *ucontrol)
+{
+	struct echoaudio *chip;
+
+	chip = snd_kcontrol_chip(kcontrol);
+	spin_lock_irq(&chip->lock);
+	set_meters_on(chip, ucontrol->value.integer.value[0]);
+	spin_unlock_irq(&chip->lock);
+	return 1;
+}
+
+static struct snd_kcontrol_new snd_echo_vumeters_switch __devinitdata = {
+	.name = "VU-meters Switch",
+	.iface = SNDRV_CTL_ELEM_IFACE_CARD,
+	.access = SNDRV_CTL_ELEM_ACCESS_WRITE,
+	.info = snd_echo_vumeters_switch_info,
+	.put = snd_echo_vumeters_switch_put,
+};
+
+
+
+/***** Read VU-meters (input, output, analog and digital together) *****/
+static int snd_echo_vumeters_info(struct snd_kcontrol *kcontrol,
+				  struct snd_ctl_elem_info *uinfo)
+{
+	struct echoaudio *chip;
+
+	chip = snd_kcontrol_chip(kcontrol);
+	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
+	uinfo->count = 96;
+	uinfo->value.integer.min = ECHOGAIN_MINOUT;
+	uinfo->value.integer.max = 0;
+#ifdef ECHOCARD_HAS_VMIXER
+	uinfo->dimen.d[0] = 3;	/* Out, In, Virt */
+#else
+	uinfo->dimen.d[0] = 2;	/* Out, In */
+#endif
+	uinfo->dimen.d[1] = 16;	/* 16 channels */
+	uinfo->dimen.d[2] = 2;	/* 0=level, 1=peak */
+	return 0;
+}
+
+static int snd_echo_vumeters_get(struct snd_kcontrol *kcontrol,
+				 struct snd_ctl_elem_value *ucontrol)
+{
+	struct echoaudio *chip;
+
+	chip = snd_kcontrol_chip(kcontrol);
+	get_audio_meters(chip, ucontrol->value.integer.value);
+	return 0;
+}
+
+static struct snd_kcontrol_new snd_echo_vumeters __devinitdata = {
+	.name = "VU-meters",
+	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+	.access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
+	.info = snd_echo_vumeters_info,
+	.get = snd_echo_vumeters_get,
+};
+
+
+
+/*** Channels info - it exports informations about the number of channels ***/
+static int snd_echo_channels_info_info(struct snd_kcontrol *kcontrol,
+				       struct snd_ctl_elem_info *uinfo)
+{
+	struct echoaudio *chip;
+
+	chip = snd_kcontrol_chip(kcontrol);
+	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
+	uinfo->count = 6;
+	uinfo->value.integer.min = 0;
+	uinfo->value.integer.max = 1 << ECHO_CLOCK_NUMBER;
+	return 0;
+}
+
+static int snd_echo_channels_info_get(struct snd_kcontrol *kcontrol,
+				      struct snd_ctl_elem_value *ucontrol)
+{
+	struct echoaudio *chip;
+	int detected, clocks, bit, src;
+
+	chip = snd_kcontrol_chip(kcontrol);
+	ucontrol->value.integer.value[0] = num_busses_in(chip);
+	ucontrol->value.integer.value[1] = num_analog_busses_in(chip);
+	ucontrol->value.integer.value[2] = num_busses_out(chip);
+	ucontrol->value.integer.value[3] = num_analog_busses_out(chip);
+	ucontrol->value.integer.value[4] = num_pipes_out(chip);
+
+	/* Compute the bitmask of the currently valid input clocks */
+	detected = detect_input_clocks(chip);
+	clocks = 0;
+	src = chip->num_clock_sources - 1;
+	for (bit = ECHO_CLOCK_NUMBER - 1; bit >= 0; bit--)
+		if (detected & (1 << bit))
+			for (; src >= 0; src--)
+				if (bit == chip->clock_source_list[src]) {
+					clocks |= 1 << src;
+					break;
+				}
+	ucontrol->value.integer.value[5] = clocks;
+
+	return 0;
+}
+
+static struct snd_kcontrol_new snd_echo_channels_info __devinitdata = {
+	.name = "Channels info",
+	.iface = SNDRV_CTL_ELEM_IFACE_HWDEP,
+	.access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
+	.info = snd_echo_channels_info_info,
+	.get = snd_echo_channels_info_get,
+};
+
+
+
+
+/******************************************************************************
+	IRQ Handler
+******************************************************************************/
+
+static irqreturn_t snd_echo_interrupt(int irq, void *dev_id,
+				      struct pt_regs *regs)
+{
+	struct echoaudio *chip = dev_id;
+	struct snd_pcm_substream *substream;
+	int period, ss, st;
+
+	spin_lock(&chip->lock);
+	st = service_irq(chip);
+	if (st < 0) {
+		spin_unlock(&chip->lock);
+		return IRQ_NONE;
+	}
+	/* The hardware doesn't tell us which substream caused the irq,
+	thus we have to check all running substreams. */
+	for (ss = 0; ss < DSP_MAXPIPES; ss++) {
+		if ((substream = chip->substream[ss])) {
+			period = pcm_pointer(substream) /
+				substream->runtime->period_size;
+			if (period != chip->last_period[ss]) {
+				chip->last_period[ss] = period;
+				spin_unlock(&chip->lock);
+				snd_pcm_period_elapsed(substream);
+				spin_lock(&chip->lock);
+			}
+		}
+	}
+	spin_unlock(&chip->lock);
+
+#ifdef ECHOCARD_HAS_MIDI
+	if (st > 0 && chip->midi_in) {
+		snd_rawmidi_receive(chip->midi_in, chip->midi_buffer, st);
+		DE_MID(("rawmidi_iread=%d\n", st));
+	}
+#endif
+	return IRQ_HANDLED;
+}
+
+
+
+
+/******************************************************************************
+	Module construction / destruction
+******************************************************************************/
+
+static int snd_echo_free(struct echoaudio *chip)
+{
+	DE_INIT(("Stop DSP...\n"));
+	if (chip->comm_page) {
+		rest_in_peace(chip);
+		snd_dma_free_pages(&chip->commpage_dma_buf);
+	}
+	DE_INIT(("Stopped.\n"));
+
+	if (chip->irq >= 0)
+		free_irq(chip->irq, (void *)chip);
+
+	if (chip->dsp_registers)
+		iounmap(chip->dsp_registers);
+
+	if (chip->iores)
+		release_and_free_resource(chip->iores);
+
+	DE_INIT(("MMIO freed.\n"));
+
+	pci_disable_device(chip->pci);
+
+	/* release chip data */
+	kfree(chip);
+	DE_INIT(("Chip freed.\n"));
+	return 0;
+}
+
+
+
+static int snd_echo_dev_free(struct snd_device *device)
+{
+	struct echoaudio *chip = device->device_data;
+
+	DE_INIT(("snd_echo_dev_free()...\n"));
+	return snd_echo_free(chip);
+}
+
+
+
+/* <--snd_echo_probe() */
+static __devinit int snd_echo_create(struct snd_card *card,
+				     struct pci_dev *pci,
+				     struct echoaudio **rchip)
+{
+	struct echoaudio *chip;
+	int err;
+	size_t sz;
+	static struct snd_device_ops ops = {
+		.dev_free = snd_echo_dev_free,
+	};
+
+	*rchip = NULL;
+
+	pci_write_config_byte(pci, PCI_LATENCY_TIMER, 0xC0);
+
+	if ((err = pci_enable_device(pci)) < 0)
+		return err;
+	pci_set_master(pci);
+
+	/* allocate a chip-specific data */
+	chip = kzalloc(sizeof(*chip), GFP_KERNEL);
+	if (!chip) {
+		pci_disable_device(pci);
+		return -ENOMEM;
+	}
+	DE_INIT(("chip=%p\n", chip));
+
+	spin_lock_init(&chip->lock);
+	chip->card = card;
+	chip->pci = pci;
+	chip->irq = -1;
+
+	/* PCI resource allocation */
+	chip->dsp_registers_phys = pci_resource_start(pci, 0);
+	sz = pci_resource_len(pci, 0);
+	if (sz > PAGE_SIZE)
+		sz = PAGE_SIZE;		/* We map only the required part */
+
+	if ((chip->iores = request_mem_region(chip->dsp_registers_phys, sz,
+					      ECHOCARD_NAME)) == NULL) {
+		snd_echo_free(chip);
+		snd_printk(KERN_ERR "cannot get memory region\n");
+		return -EBUSY;
+	}
+	chip->dsp_registers = (volatile u32 __iomem *)
+		ioremap_nocache(chip->dsp_registers_phys, sz);
+
+	if (request_irq(pci->irq, snd_echo_interrupt, IRQF_DISABLED | IRQF_SHARED,
+						ECHOCARD_NAME, (void *)chip)) {
+		snd_echo_free(chip);
+		snd_printk(KERN_ERR "cannot grab irq\n");
+		return -EBUSY;
+	}
+	chip->irq = pci->irq;
+	DE_INIT(("pci=%p irq=%d subdev=%04x Init hardware...\n",
+		 chip->pci, chip->irq, chip->pci->subsystem_device));
+
+	/* Create the DSP comm page - this is the area of memory used for most
+	of the communication with the DSP, which accesses it via bus mastering */
+	if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(chip->pci),
+				sizeof(struct comm_page),
+				&chip->commpage_dma_buf) < 0) {
+		snd_echo_free(chip);
+		snd_printk(KERN_ERR "cannot allocate the comm page\n");
+		return -ENOMEM;
+	}
+	chip->comm_page_phys = chip->commpage_dma_buf.addr;
+	chip->comm_page = (struct comm_page *)chip->commpage_dma_buf.area;
+
+	err = init_hw(chip, chip->pci->device, chip->pci->subsystem_device);
+	if (err) {
+		DE_INIT(("init_hw err=%d\n", err));
+		snd_echo_free(chip);
+		return err;
+	}
+	DE_INIT(("Card init OK\n"));
+
+	if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) {
+		snd_echo_free(chip);
+		return err;
+	}
+	atomic_set(&chip->opencount, 0);
+	init_MUTEX(&chip->mode_mutex);
+	chip->can_set_rate = 1;
+	*rchip = chip;
+	/* Init done ! */
+	return 0;
+}
+
+
+
+/* constructor */
+static int __devinit snd_echo_probe(struct pci_dev *pci,
+				    const struct pci_device_id *pci_id)
+{
+	static int dev;
+	struct snd_card *card;
+	struct echoaudio *chip;
+	char *dsp;
+	int i, err;
+
+	if (dev >= SNDRV_CARDS)
+		return -ENODEV;
+	if (!enable[dev]) {
+		dev++;
+		return -ENOENT;
+	}
+
+	DE_INIT(("Echoaudio driver starting...\n"));
+	i = 0;
+	card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
+	if (card == NULL)
+		return -ENOMEM;
+
+	if ((err = snd_echo_create(card, pci, &chip)) < 0) {
+		snd_card_free(card);
+		return err;
+	}
+
+	strcpy(card->driver, "Echo_" ECHOCARD_NAME);
+	strcpy(card->shortname, chip->card_name);
+
+	dsp = "56301";
+	if (pci_id->device == 0x3410)
+		dsp = "56361";
+
+	sprintf(card->longname, "%s rev.%d (DSP%s) at 0x%lx irq %i",
+		card->shortname, pci_id->subdevice & 0x000f, dsp,
+		chip->dsp_registers_phys, chip->irq);
+
+	if ((err = snd_echo_new_pcm(chip)) < 0) {
+		snd_printk(KERN_ERR "new pcm error %d\n", err);
+		snd_card_free(card);
+		return err;
+	}
+
+#ifdef ECHOCARD_HAS_MIDI
+	if (chip->has_midi) {	/* Some Mia's do not have midi */
+		if ((err = snd_echo_midi_create(card, chip)) < 0) {
+			snd_printk(KERN_ERR "new midi error %d\n", err);
+			snd_card_free(card);
+			return err;
+		}
+	}
+#endif
+
+#ifdef ECHOCARD_HAS_VMIXER
+	snd_echo_vmixer.count = num_pipes_out(chip) * num_busses_out(chip);
+	if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_echo_line_output_gain, chip))) < 0)
+		goto ctl_error;
+	if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_echo_vmixer, chip))) < 0)
+		goto ctl_error;
+#else
+	if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_echo_pcm_output_gain, chip))) < 0)
+		goto ctl_error;
+#endif
+
+#ifdef ECHOCARD_HAS_INPUT_GAIN
+	if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_echo_line_input_gain, chip))) < 0)
+		goto ctl_error;
+#endif
+
+#ifdef ECHOCARD_HAS_INPUT_NOMINAL_LEVEL
+	if (!chip->hasnt_input_nominal_level)
+		if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_echo_intput_nominal_level, chip))) < 0)
+			goto ctl_error;
+#endif
+
+#ifdef ECHOCARD_HAS_OUTPUT_NOMINAL_LEVEL
+	if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_echo_output_nominal_level, chip))) < 0)
+		goto ctl_error;
+#endif
+
+	if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_echo_vumeters_switch, chip))) < 0)
+		goto ctl_error;
+
+	if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_echo_vumeters, chip))) < 0)
+		goto ctl_error;
+
+#ifdef ECHOCARD_HAS_MONITOR
+	snd_echo_monitor_mixer.count = num_busses_in(chip) * num_busses_out(chip);
+	if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_echo_monitor_mixer, chip))) < 0)
+		goto ctl_error;
+#endif
+
+#ifdef ECHOCARD_HAS_DIGITAL_IN_AUTOMUTE
+	if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_echo_automute_switch, chip))) < 0)
+		goto ctl_error;
+#endif
+
+	if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_echo_channels_info, chip))) < 0)
+		goto ctl_error;
+
+#ifdef ECHOCARD_HAS_DIGITAL_MODE_SWITCH
+	/* Creates a list of available digital modes */
+	chip->num_digital_modes = 0;
+	for (i = 0; i < 6; i++)
+		if (chip->digital_modes & (1 << i))
+			chip->digital_mode_list[chip->num_digital_modes++] = i;
+
+	if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_echo_digital_mode_switch, chip))) < 0)
+		goto ctl_error;
+#endif /* ECHOCARD_HAS_DIGITAL_MODE_SWITCH */
+
+#ifdef ECHOCARD_HAS_EXTERNAL_CLOCK
+	/* Creates a list of available clock sources */
+	chip->num_clock_sources = 0;
+	for (i = 0; i < 10; i++)
+		if (chip->input_clock_types & (1 << i))
+			chip->clock_source_list[chip->num_clock_sources++] = i;
+
+	if (chip->num_clock_sources > 1) {
+		chip->clock_src_ctl = snd_ctl_new1(&snd_echo_clock_source_switch, chip);
+		if ((err = snd_ctl_add(chip->card, chip->clock_src_ctl)) < 0)
+			goto ctl_error;
+	}
+#endif /* ECHOCARD_HAS_EXTERNAL_CLOCK */
+
+#ifdef ECHOCARD_HAS_DIGITAL_IO
+	if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_echo_spdif_mode_switch, chip))) < 0)
+		goto ctl_error;
+#endif
+
+#ifdef ECHOCARD_HAS_PHANTOM_POWER
+	if (chip->has_phantom_power)
+		if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_echo_phantom_power_switch, chip))) < 0)
+			goto ctl_error;
+#endif
+
+	if ((err = snd_card_register(card)) < 0) {
+		snd_card_free(card);
+		goto ctl_error;
+	}
+	snd_printk(KERN_INFO "Card registered: %s\n", card->longname);
+
+	pci_set_drvdata(pci, chip);
+	dev++;
+	return 0;
+
+ctl_error:
+	snd_printk(KERN_ERR "new control error %d\n", err);
+	snd_card_free(card);
+	return err;
+}
+
+
+
+static void __devexit snd_echo_remove(struct pci_dev *pci)
+{
+	struct echoaudio *chip;
+
+	chip = pci_get_drvdata(pci);
+	if (chip)
+		snd_card_free(chip->card);
+	pci_set_drvdata(pci, NULL);
+}
+
+
+
+/******************************************************************************
+	Everything starts and ends here
+******************************************************************************/
+
+/* pci_driver definition */
+static struct pci_driver driver = {
+	.name = "Echoaudio " ECHOCARD_NAME,
+	.id_table = snd_echo_ids,
+	.probe = snd_echo_probe,
+	.remove = __devexit_p(snd_echo_remove),
+};
+
+
+
+/* initialization of the module */
+static int __init alsa_card_echo_init(void)
+{
+	return pci_register_driver(&driver);
+}
+
+
+
+/* clean up the module */
+static void __exit alsa_card_echo_exit(void)
+{
+	pci_unregister_driver(&driver);
+}
+
+
+module_init(alsa_card_echo_init)
+module_exit(alsa_card_echo_exit)
diff --git a/sound/pci/echoaudio/echoaudio.h b/sound/pci/echoaudio/echoaudio.h
new file mode 100644
index 000000000..7e88c968e
--- /dev/null
+++ b/sound/pci/echoaudio/echoaudio.h
@@ -0,0 +1,590 @@
+/****************************************************************************
+
+   Copyright Echo Digital Audio Corporation (c) 1998 - 2004
+   All rights reserved
+   www.echoaudio.com
+
+   This file is part of Echo Digital Audio's generic driver library.
+
+   Echo Digital Audio's generic driver library 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.
+
+   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.
+
+ ****************************************************************************
+
+ Translation from C++ and adaptation for use in ALSA-Driver
+ were made by Giuliano Pochini <pochini@shiny.it>
+
+ ****************************************************************************
+
+
+   Here's a block diagram of how most of the cards work:
+
+                  +-----------+
+           record |           |<-------------------- Inputs
+          <-------|           |        |
+     PCI          | Transport |        |
+     bus          |  engine   |       \|/
+          ------->|           |    +-------+
+            play  |           |--->|monitor|-------> Outputs
+                  +-----------+    | mixer |
+                                   +-------+
+
+   The lines going to and from the PCI bus represent "pipes".  A pipe performs
+   audio transport - moving audio data to and from buffers on the host via
+   bus mastering.
+
+   The inputs and outputs on the right represent input and output "busses."
+   A bus is a physical, real connection to the outside world.  An example
+   of a bus would be the 1/4" analog connectors on the back of Layla or
+   an RCA S/PDIF connector.
+
+   For most cards, there is a one-to-one correspondence between outputs
+   and busses; that is, each individual pipe is hard-wired to a single bus.
+
+   Cards that work this way are Darla20, Gina20, Layla20, Darla24, Gina24,
+   Layla24, Mona, and Indigo.
+
+
+   Mia has a feature called "virtual outputs."
+
+
+                  +-----------+
+           record |           |<----------------------------- Inputs
+          <-------|           |                  |
+     PCI          | Transport |                  |
+     bus          |  engine   |                 \|/
+          ------->|           |   +------+   +-------+
+            play  |           |-->|vmixer|-->|monitor|-------> Outputs
+                  +-----------+   +------+   | mixer |
+                                             +-------+
+
+
+   Obviously, the difference here is the box labeled "vmixer."  Vmixer is
+   short for "virtual output mixer."  For Mia, pipes are *not* hard-wired
+   to a single bus; the vmixer lets you mix any pipe to any bus in any
+   combination.
+
+   Note, however, that the left-hand side of the diagram is unchanged.
+   Transport works exactly the same way - the difference is in the mixer stage.
+
+
+   Pipes and busses are numbered starting at zero.
+
+
+
+   Pipe index
+   ==========
+
+   A number of calls in CEchoGals refer to a "pipe index".  A pipe index is
+   a unique number for a pipe that unambiguously refers to a playback or record
+   pipe.  Pipe indices are numbered starting with analog outputs, followed by
+   digital outputs, then analog inputs, then digital inputs.
+
+   Take Gina24 as an example:
+
+   Pipe index
+
+   0-7            Analog outputs (0 .. FirstDigitalBusOut-1)
+   8-15           Digital outputs (FirstDigitalBusOut .. NumBussesOut-1)
+   16-17          Analog inputs
+   18-25          Digital inputs
+
+
+   You get the pipe index by calling CEchoGals::OpenAudio; the other transport
+   functions take the pipe index as a parameter.  If you need a pipe index for
+   some other reason, use the handy Makepipe_index method.
+
+
+   Some calls take a CChannelMask parameter; CChannelMask is a handy way to
+   group pipe indices.
+
+
+
+   Digital mode switch
+   ===================
+
+   Some cards (right now, Gina24, Layla24, and Mona) have a Digital Mode Switch
+   or DMS.  Cards with a DMS can be set to one of three mutually exclusive
+   digital modes: S/PDIF RCA, S/PDIF optical, or ADAT optical.
+
+   This may create some confusion since ADAT optical is 8 channels wide and
+   S/PDIF is only two channels wide.  Gina24, Layla24, and Mona handle this
+   by acting as if they always have 8 digital outs and ins.  If you are in
+   either S/PDIF mode, the last 6 channels don't do anything - data sent
+   out these channels is thrown away and you will always record zeros.
+
+   Note that with Gina24, Layla24, and Mona, sample rates above 50 kHz are
+   only available if you have the card configured for S/PDIF optical or S/PDIF
+   RCA.
+
+
+
+   Double speed mode
+   =================
+
+   Some of the cards support 88.2 kHz and 96 kHz sampling (Darla24, Gina24,
+   Layla24, Mona, Mia, and Indigo).  For these cards, the driver sometimes has
+   to worry about "double speed mode"; double speed mode applies whenever the
+   sampling rate is above 50 kHz.
+
+   For instance, Mona and Layla24 support word clock sync.  However, they
+   actually support two different word clock modes - single speed (below
+   50 kHz) and double speed (above 50 kHz).  The hardware detects if a single
+   or double speed word clock signal is present; the generic code uses that
+   information to determine which mode to use.
+
+   The generic code takes care of all this for you.
+*/
+
+
+#ifndef _ECHOAUDIO_H_
+#define _ECHOAUDIO_H_
+
+
+#define TRUE 1
+#define FALSE 0
+
+#include "echoaudio_dsp.h"
+
+
+
+/***********************************************************************
+
+	PCI configuration space
+
+***********************************************************************/
+
+/*
+ * PCI vendor ID and device IDs for the hardware
+ */
+#define VENDOR_ID		0x1057
+#define DEVICE_ID_56301		0x1801
+#define DEVICE_ID_56361		0x3410
+#define SUBVENDOR_ID		0xECC0
+
+
+/*
+ * Valid Echo PCI subsystem card IDs
+ */
+#define DARLA20			0x0010
+#define GINA20			0x0020
+#define LAYLA20			0x0030
+#define DARLA24			0x0040
+#define GINA24			0x0050
+#define LAYLA24			0x0060
+#define MONA			0x0070
+#define MIA			0x0080
+#define INDIGO			0x0090
+#define INDIGO_IO		0x00a0
+#define INDIGO_DJ		0x00b0
+#define ECHO3G			0x0100
+
+
+/************************************************************************
+
+	Array sizes and so forth
+
+***********************************************************************/
+
+/*
+ * Sizes
+ */
+#define ECHO_MAXAUDIOINPUTS	32	/* Max audio input channels */
+#define ECHO_MAXAUDIOOUTPUTS	32	/* Max audio output channels */
+#define ECHO_MAXAUDIOPIPES	32	/* Max number of input and output
+					 * pipes */
+#define E3G_MAX_OUTPUTS		16
+#define ECHO_MAXMIDIJACKS	1	/* Max MIDI ports */
+#define ECHO_MIDI_QUEUE_SZ 	512	/* Max MIDI input queue entries */
+#define ECHO_MTC_QUEUE_SZ	32	/* Max MIDI time code input queue
+					 * entries */
+
+/*
+ * MIDI activity indicator timeout
+ */
+#define MIDI_ACTIVITY_TIMEOUT_USEC	200000
+
+
+/****************************************************************************
+ 
+   Clocks
+
+*****************************************************************************/
+
+/*
+ * Clock numbers
+ */
+#define ECHO_CLOCK_INTERNAL		0
+#define ECHO_CLOCK_WORD			1
+#define ECHO_CLOCK_SUPER		2
+#define ECHO_CLOCK_SPDIF		3
+#define ECHO_CLOCK_ADAT			4
+#define ECHO_CLOCK_ESYNC		5
+#define ECHO_CLOCK_ESYNC96		6
+#define ECHO_CLOCK_MTC			7
+#define ECHO_CLOCK_NUMBER		8
+#define ECHO_CLOCKS			0xffff
+
+/*
+ * Clock bit numbers - used to report capabilities and whatever clocks
+ * are being detected dynamically.
+ */
+#define ECHO_CLOCK_BIT_INTERNAL		(1 << ECHO_CLOCK_INTERNAL)
+#define ECHO_CLOCK_BIT_WORD		(1 << ECHO_CLOCK_WORD)
+#define ECHO_CLOCK_BIT_SUPER		(1 << ECHO_CLOCK_SUPER)
+#define ECHO_CLOCK_BIT_SPDIF		(1 << ECHO_CLOCK_SPDIF)
+#define ECHO_CLOCK_BIT_ADAT		(1 << ECHO_CLOCK_ADAT)
+#define ECHO_CLOCK_BIT_ESYNC		(1 << ECHO_CLOCK_ESYNC)
+#define ECHO_CLOCK_BIT_ESYNC96		(1 << ECHO_CLOCK_ESYNC96)
+#define ECHO_CLOCK_BIT_MTC		(1<<ECHO_CLOCK_MTC)
+
+
+/***************************************************************************
+
+   Digital modes
+
+****************************************************************************/
+
+/*
+ * Digital modes for Mona, Layla24, and Gina24
+ */
+#define DIGITAL_MODE_NONE			0xFF
+#define DIGITAL_MODE_SPDIF_RCA			0
+#define DIGITAL_MODE_SPDIF_OPTICAL		1
+#define DIGITAL_MODE_ADAT			2
+#define DIGITAL_MODE_SPDIF_CDROM		3
+#define DIGITAL_MODES				4
+
+/*
+ * Digital mode capability masks
+ */
+#define ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_RCA	(1 << DIGITAL_MODE_SPDIF_RCA)
+#define ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_OPTICAL	(1 << DIGITAL_MODE_SPDIF_OPTICAL)
+#define ECHOCAPS_HAS_DIGITAL_MODE_ADAT		(1 << DIGITAL_MODE_ADAT)
+#define ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_CDROM	(1 << DIGITAL_MODE_SPDIF_CDROM)
+
+
+#define EXT_3GBOX_NC			0x01	/* 3G box not connected */
+#define EXT_3GBOX_NOT_SET		0x02	/* 3G box not detected yet */
+
+
+#define ECHOGAIN_MUTED		(-128)	/* Minimum possible gain */
+#define ECHOGAIN_MINOUT		(-128)	/* Min output gain (dB) */
+#define ECHOGAIN_MAXOUT		(6)	/* Max output gain (dB) */
+#define ECHOGAIN_MININP		(-50)	/* Min input gain (0.5 dB) */
+#define ECHOGAIN_MAXINP		(50)	/* Max input gain (0.5 dB) */
+
+#define PIPE_STATE_STOPPED	0	/* Pipe has been reset */
+#define PIPE_STATE_PAUSED	1	/* Pipe has been stopped */
+#define PIPE_STATE_STARTED	2	/* Pipe has been started */
+#define PIPE_STATE_PENDING	3	/* Pipe has pending start */
+
+
+/* Debug initialization */
+#ifdef CONFIG_SND_DEBUG
+#define DE_INIT(x) snd_printk x
+#else
+#define DE_INIT(x)
+#endif
+
+/* Debug hw_params callbacks */
+#ifdef CONFIG_SND_DEBUG
+#define DE_HWP(x) snd_printk x
+#else
+#define DE_HWP(x)
+#endif
+
+/* Debug normal activity (open, start, stop...) */
+#ifdef CONFIG_SND_DEBUG
+#define DE_ACT(x) snd_printk x
+#else
+#define DE_ACT(x)
+#endif
+
+/* Debug midi activity */
+#ifdef CONFIG_SND_DEBUG
+#define DE_MID(x) snd_printk x
+#else
+#define DE_MID(x)
+#endif
+
+
+struct audiopipe {
+	volatile u32 *dma_counter;	/* Commpage register that contains
+					 * the current dma position
+					 * (lower 32 bits only)
+					 */
+	u32 last_counter;		/* The last position, which is used
+					 * to compute...
+					 */
+	u32 position;			/* ...the number of bytes tranferred
+					 * by the DMA engine, modulo the
+					 * buffer size
+					 */
+	short index;			/* Index of the first channel or <0
+					 * if hw is not configured yet
+					 */
+	short interleave;
+	struct snd_dma_buffer sgpage;	/* Room for the scatter-gather list */
+	struct snd_pcm_hardware hw;
+	struct snd_pcm_hw_constraint_list constr;
+	short sglist_head;
+	char state;			/* pipe state */
+};
+
+
+struct audioformat {
+	u8 interleave;			/* How the data is arranged in memory:
+					 * mono = 1, stereo = 2, ...
+					 */
+	u8 bits_per_sample;		/* 8, 16, 24, 32 (24 bits left aligned) */
+	char mono_to_stereo;		/* Only used if interleave is 1 and
+					 * if this is an output pipe.
+					 */
+	char data_are_bigendian;	/* 1 = big endian, 0 = little endian */
+};
+
+
+struct echoaudio {
+	spinlock_t lock;
+	struct snd_pcm_substream *substream[DSP_MAXPIPES];
+	int last_period[DSP_MAXPIPES];
+	struct semaphore mode_mutex;
+	u16 num_digital_modes, digital_mode_list[6];
+	u16 num_clock_sources, clock_source_list[10];
+	atomic_t opencount;
+	struct snd_kcontrol *clock_src_ctl;
+	struct snd_pcm *analog_pcm, *digital_pcm;
+	struct snd_card *card;
+	const char *card_name;
+	struct pci_dev *pci;
+	unsigned long dsp_registers_phys;
+	struct resource *iores;
+	struct snd_dma_buffer commpage_dma_buf;
+	int irq;
+#ifdef ECHOCARD_HAS_MIDI
+	struct snd_rawmidi *rmidi;
+	struct snd_rawmidi_substream *midi_in, *midi_out;
+#endif
+	struct timer_list timer;
+	char tinuse;				/* Timer in use */
+	char midi_full;				/* MIDI output buffer is full */
+	char can_set_rate;
+	char rate_set;
+
+	/* This stuff is used mainly by the lowlevel code */
+	struct comm_page *comm_page;	/* Virtual address of the memory
+					 * seen by DSP
+					 */
+	u32 pipe_alloc_mask;		/* Bitmask of allocated pipes */
+	u32 pipe_cyclic_mask;		/* Bitmask of pipes with cyclic
+					 * buffers
+					 */
+	u32 sample_rate;		/* Card sample rate in Hz */
+	u8 digital_mode;		/* Current digital mode
+					 * (see DIGITAL_MODE_*)
+					 */
+	u8 spdif_status;		/* Gina20, Darla20, Darla24 - only */
+	u8 clock_state;			/* Gina20, Darla20, Darla24 - only */
+	u8 input_clock;			/* Currently selected sample clock
+					 * source
+					 */
+	u8 output_clock;		/* Layla20 only */
+	char meters_enabled;		/* VU-meters status */
+	char asic_loaded;		/* Set TRUE when ASIC loaded */
+	char bad_board;			/* Set TRUE if DSP won't load */
+	char professional_spdif;	/* 0 = consumer; 1 = professional */
+	char non_audio_spdif;		/* 3G - only */
+	char digital_in_automute;	/* Gina24, Layla24, Mona - only */
+	char has_phantom_power;
+	char hasnt_input_nominal_level;	/* Gina3G */
+	char phantom_power;		/* Gina3G - only */
+	char has_midi;
+	char midi_input_enabled;
+
+#ifdef ECHOCARD_ECHO3G
+	/* External module -dependent pipe and bus indexes */
+	char px_digital_out, px_analog_in, px_digital_in, px_num;
+	char bx_digital_out, bx_analog_in, bx_digital_in, bx_num;
+#endif
+
+	char nominal_level[ECHO_MAXAUDIOPIPES];	/* True == -10dBV
+						 * False == +4dBu */
+	s8 input_gain[ECHO_MAXAUDIOINPUTS];	/* Input level -50..+50
+						 * unit is 0.5dB */
+	s8 output_gain[ECHO_MAXAUDIOOUTPUTS];	/* Output level -128..+6 dB
+						 * (-128=muted) */
+	s8 monitor_gain[ECHO_MAXAUDIOOUTPUTS][ECHO_MAXAUDIOINPUTS];
+		/* -128..+6 dB */
+	s8 vmixer_gain[ECHO_MAXAUDIOOUTPUTS][ECHO_MAXAUDIOOUTPUTS];
+		/* -128..+6 dB */
+
+	u16 digital_modes;		/* Bitmask of supported modes
+					 * (see ECHOCAPS_HAS_DIGITAL_MODE_*) */
+	u16 input_clock_types;		/* Suppoted input clock types */
+	u16 output_clock_types;		/* Suppoted output clock types -
+					 * Layla20 only */
+	u16 device_id, subdevice_id;
+	u16 *dsp_code;			/* Current DSP code loaded,
+					 * NULL if nothing loaded */
+	const struct firmware *dsp_code_to_load;/* DSP code to load */
+	const struct firmware *asic_code;	/* Current ASIC code */
+	u32 comm_page_phys;			/* Physical address of the
+						 * memory seen by DSP */
+	volatile u32 __iomem *dsp_registers;	/* DSP's register base */
+	u32 active_mask;			/* Chs. active mask or
+						 * punks out */
+
+#ifdef ECHOCARD_HAS_MIDI
+	u16 mtc_state;				/* State for MIDI input parsing state machine */
+	u8 midi_buffer[MIDI_IN_BUFFER_SIZE];
+#endif
+};
+
+
+static int init_dsp_comm_page(struct echoaudio *chip);
+static int init_line_levels(struct echoaudio *chip);
+static int free_pipes(struct echoaudio *chip, struct audiopipe *pipe);
+static int load_firmware(struct echoaudio *chip);
+static int wait_handshake(struct echoaudio *chip);
+static int send_vector(struct echoaudio *chip, u32 command);
+static int get_firmware(const struct firmware **fw_entry,
+			const struct firmware *frm, struct echoaudio *chip);
+static void free_firmware(const struct firmware *fw_entry);
+
+#ifdef ECHOCARD_HAS_MIDI
+static int enable_midi_input(struct echoaudio *chip, char enable);
+static int midi_service_irq(struct echoaudio *chip);
+static int __devinit snd_echo_midi_create(struct snd_card *card,
+					  struct echoaudio *chip);
+#endif
+
+
+static inline void clear_handshake(struct echoaudio *chip)
+{
+	chip->comm_page->handshake = 0;
+}
+
+static inline u32 get_dsp_register(struct echoaudio *chip, u32 index)
+{
+	return readl(&chip->dsp_registers[index]);
+}
+
+static inline void set_dsp_register(struct echoaudio *chip, u32 index,
+				    u32 value)
+{
+	writel(value, &chip->dsp_registers[index]);
+}
+
+
+/* Pipe and bus indexes. PX_* and BX_* are defined as chip->px_* and chip->bx_*
+for 3G cards because they depend on the external box. They are integer
+constants for all other cards.
+Never use those defines directly, use the following functions instead. */
+
+static inline int px_digital_out(const struct echoaudio *chip)
+{
+	return PX_DIGITAL_OUT;
+}
+
+static inline int px_analog_in(const struct echoaudio *chip)
+{
+	return PX_ANALOG_IN;
+}
+
+static inline int px_digital_in(const struct echoaudio *chip)
+{
+	return PX_DIGITAL_IN;
+}
+
+static inline int px_num(const struct echoaudio *chip)
+{
+	return PX_NUM;
+}
+
+static inline int bx_digital_out(const struct echoaudio *chip)
+{
+	return BX_DIGITAL_OUT;
+}
+
+static inline int bx_analog_in(const struct echoaudio *chip)
+{
+	return BX_ANALOG_IN;
+}
+
+static inline int bx_digital_in(const struct echoaudio *chip)
+{
+	return BX_DIGITAL_IN;
+}
+
+static inline int bx_num(const struct echoaudio *chip)
+{
+	return BX_NUM;
+}
+
+static inline int num_pipes_out(const struct echoaudio *chip)
+{
+	return px_analog_in(chip);
+}
+
+static inline int num_pipes_in(const struct echoaudio *chip)
+{
+	return px_num(chip) - px_analog_in(chip);
+}
+
+static inline int num_busses_out(const struct echoaudio *chip)
+{
+	return bx_analog_in(chip);
+}
+
+static inline int num_busses_in(const struct echoaudio *chip)
+{
+	return bx_num(chip) - bx_analog_in(chip);
+}
+
+static inline int num_analog_busses_out(const struct echoaudio *chip)
+{
+	return bx_digital_out(chip);
+}
+
+static inline int num_analog_busses_in(const struct echoaudio *chip)
+{
+	return bx_digital_in(chip) - bx_analog_in(chip);
+}
+
+static inline int num_digital_busses_out(const struct echoaudio *chip)
+{
+	return num_busses_out(chip) - num_analog_busses_out(chip);
+}
+
+static inline int num_digital_busses_in(const struct echoaudio *chip)
+{
+	return num_busses_in(chip) - num_analog_busses_in(chip);
+}
+
+/* The monitor array is a one-dimensional array; compute the offset
+ * into the array */
+static inline int monitor_index(const struct echoaudio *chip, int out, int in)
+{
+	return out * num_busses_in(chip) + in;
+}
+
+
+#ifndef pci_device
+#define pci_device(chip) (&chip->pci->dev)
+#endif
+
+
+#endif /* _ECHOAUDIO_H_ */
diff --git a/sound/pci/echoaudio/echoaudio_3g.c b/sound/pci/echoaudio/echoaudio_3g.c
new file mode 100644
index 000000000..9f439ea45
--- /dev/null
+++ b/sound/pci/echoaudio/echoaudio_3g.c
@@ -0,0 +1,431 @@
+/****************************************************************************
+
+   Copyright Echo Digital Audio Corporation (c) 1998 - 2004
+   All rights reserved
+   www.echoaudio.com
+
+   This file is part of Echo Digital Audio's generic driver library.
+
+   Echo Digital Audio's generic driver library 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.
+
+   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.
+
+   *************************************************************************
+
+ Translation from C++ and adaptation for use in ALSA-Driver
+ were made by Giuliano Pochini <pochini@shiny.it>
+
+****************************************************************************/
+
+
+
+/* These functions are common for all "3G" cards */
+
+
+static int check_asic_status(struct echoaudio *chip)
+{
+	u32 box_status;
+
+	if (wait_handshake(chip))
+		return -EIO;
+
+	chip->comm_page->ext_box_status =
+		__constant_cpu_to_le32(E3G_ASIC_NOT_LOADED);
+	chip->asic_loaded = FALSE;
+	clear_handshake(chip);
+	send_vector(chip, DSP_VC_TEST_ASIC);
+
+	if (wait_handshake(chip)) {
+		chip->dsp_code = NULL;
+		return -EIO;
+	}
+
+	box_status = le32_to_cpu(chip->comm_page->ext_box_status);
+	DE_INIT(("box_status=%x\n", box_status));
+	if (box_status == E3G_ASIC_NOT_LOADED)
+		return -ENODEV;
+
+	chip->asic_loaded = TRUE;
+	return box_status & E3G_BOX_TYPE_MASK;
+}
+
+
+
+static inline u32 get_frq_reg(struct echoaudio *chip)
+{
+	return le32_to_cpu(chip->comm_page->e3g_frq_register);
+}
+
+
+
+/* Most configuration of 3G cards is accomplished by writing the control
+register. write_control_reg sends the new control register value to the DSP. */
+static int write_control_reg(struct echoaudio *chip, u32 ctl, u32 frq,
+			     char force)
+{
+	if (wait_handshake(chip))
+		return -EIO;
+
+	DE_ACT(("WriteControlReg: Setting 0x%x, 0x%x\n", ctl, frq));
+
+	ctl = cpu_to_le32(ctl);
+	frq = cpu_to_le32(frq);
+
+	if (ctl != chip->comm_page->control_register ||
+	    frq != chip->comm_page->e3g_frq_register || force) {
+		chip->comm_page->e3g_frq_register = frq;
+		chip->comm_page->control_register = ctl;
+		clear_handshake(chip);
+		return send_vector(chip, DSP_VC_WRITE_CONTROL_REG);
+	}
+
+	DE_ACT(("WriteControlReg: not written, no change\n"));
+	return 0;
+}
+
+
+
+/* Set the digital mode - currently for Gina24, Layla24, Mona, 3G */
+static int set_digital_mode(struct echoaudio *chip, u8 mode)
+{
+	u8 previous_mode;
+	int err, i, o;
+
+	/* All audio channels must be closed before changing the digital mode */
+	snd_assert(!chip->pipe_alloc_mask, return -EAGAIN);
+
+	snd_assert(chip->digital_modes & (1 << mode), return -EINVAL);
+
+	previous_mode = chip->digital_mode;
+	err = dsp_set_digital_mode(chip, mode);
+
+	/* If we successfully changed the digital mode from or to ADAT,
+	 * then make sure all output, input and monitor levels are
+	 * updated by the DSP comm object. */
+	if (err >= 0 && previous_mode != mode &&
+	    (previous_mode == DIGITAL_MODE_ADAT || mode == DIGITAL_MODE_ADAT)) {
+		spin_lock_irq(&chip->lock);
+		for (o = 0; o < num_busses_out(chip); o++)
+			for (i = 0; i < num_busses_in(chip); i++)
+				set_monitor_gain(chip, o, i,
+						 chip->monitor_gain[o][i]);
+
+#ifdef ECHOCARD_HAS_INPUT_GAIN
+		for (i = 0; i < num_busses_in(chip); i++)
+			set_input_gain(chip, i, chip->input_gain[i]);
+		update_input_line_level(chip);
+#endif
+
+		for (o = 0; o < num_busses_out(chip); o++)
+			set_output_gain(chip, o, chip->output_gain[o]);
+		update_output_line_level(chip);
+		spin_unlock_irq(&chip->lock);
+	}
+
+	return err;
+}
+
+
+
+static u32 set_spdif_bits(struct echoaudio *chip, u32 control_reg, u32 rate)
+{
+	control_reg &= E3G_SPDIF_FORMAT_CLEAR_MASK;
+
+	switch (rate) {
+	case 32000 :
+		control_reg |= E3G_SPDIF_SAMPLE_RATE0 | E3G_SPDIF_SAMPLE_RATE1;
+		break;
+	case 44100 :
+		if (chip->professional_spdif)
+			control_reg |= E3G_SPDIF_SAMPLE_RATE0;
+		break;
+	case 48000 :
+		control_reg |= E3G_SPDIF_SAMPLE_RATE1;
+		break;
+	}
+
+	if (chip->professional_spdif)
+		control_reg |= E3G_SPDIF_PRO_MODE;
+
+	if (chip->non_audio_spdif)
+		control_reg |= E3G_SPDIF_NOT_AUDIO;
+
+	control_reg |= E3G_SPDIF_24_BIT | E3G_SPDIF_TWO_CHANNEL |
+		E3G_SPDIF_COPY_PERMIT;
+
+	return control_reg;
+}
+
+
+
+/* Set the S/PDIF output format */
+static int set_professional_spdif(struct echoaudio *chip, char prof)
+{
+	u32 control_reg;
+
+	control_reg = le32_to_cpu(chip->comm_page->control_register);
+	chip->professional_spdif = prof;
+	control_reg = set_spdif_bits(chip, control_reg, chip->sample_rate);
+	return write_control_reg(chip, control_reg, get_frq_reg(chip), 0);
+}
+
+
+
+/* detect_input_clocks() returns a bitmask consisting of all the input clocks
+currently connected to the hardware; this changes as the user connects and
+disconnects clock inputs. You should use this information to determine which
+clocks the user is allowed to select. */
+static u32 detect_input_clocks(const struct echoaudio *chip)
+{
+	u32 clocks_from_dsp, clock_bits;
+
+	/* Map the DSP clock detect bits to the generic driver clock
+	 * detect bits */
+	clocks_from_dsp = le32_to_cpu(chip->comm_page->status_clocks);
+
+	clock_bits = ECHO_CLOCK_BIT_INTERNAL;
+
+	if (clocks_from_dsp & E3G_CLOCK_DETECT_BIT_WORD)
+		clock_bits |= ECHO_CLOCK_BIT_WORD;
+
+	switch(chip->digital_mode) {
+	case DIGITAL_MODE_SPDIF_RCA:
+	case DIGITAL_MODE_SPDIF_OPTICAL:
+		if (clocks_from_dsp & E3G_CLOCK_DETECT_BIT_SPDIF)
+			clock_bits |= ECHO_CLOCK_BIT_SPDIF;
+		break;
+	case DIGITAL_MODE_ADAT:
+		if (clocks_from_dsp & E3G_CLOCK_DETECT_BIT_ADAT)
+			clock_bits |= ECHO_CLOCK_BIT_ADAT;
+		break;
+	}
+
+	return clock_bits;
+}
+
+
+
+static int load_asic(struct echoaudio *chip)
+{
+	int box_type, err;
+
+	if (chip->asic_loaded)
+		return 0;
+
+	/* Give the DSP a few milliseconds to settle down */
+	mdelay(2);
+
+	err = load_asic_generic(chip, DSP_FNC_LOAD_3G_ASIC,
+				&card_fw[FW_3G_ASIC]);
+	if (err < 0)
+		return err;
+
+	chip->asic_code = &card_fw[FW_3G_ASIC];
+
+	/* Now give the new ASIC a little time to set up */
+	mdelay(2);
+	/* See if it worked */
+	box_type = check_asic_status(chip);
+
+	/* Set up the control register if the load succeeded -
+	 * 48 kHz, internal clock, S/PDIF RCA mode */
+	if (box_type >= 0) {
+		err = write_control_reg(chip, E3G_48KHZ,
+					E3G_FREQ_REG_DEFAULT, TRUE);
+		if (err < 0)
+			return err;
+	}
+
+	return box_type;
+}
+
+
+
+static int set_sample_rate(struct echoaudio *chip, u32 rate)
+{
+	u32 control_reg, clock, base_rate, frq_reg;
+
+	/* Only set the clock for internal mode. */
+	if (chip->input_clock != ECHO_CLOCK_INTERNAL) {
+		DE_ACT(("set_sample_rate: Cannot set sample rate - "
+			"clock not set to CLK_CLOCKININTERNAL\n"));
+		/* Save the rate anyhow */
+		chip->comm_page->sample_rate = cpu_to_le32(rate);
+		chip->sample_rate = rate;
+		set_input_clock(chip, chip->input_clock);
+		return 0;
+	}
+
+	snd_assert(rate < 50000 || chip->digital_mode != DIGITAL_MODE_ADAT,
+		   return -EINVAL);
+
+	clock = 0;
+	control_reg = le32_to_cpu(chip->comm_page->control_register);
+	control_reg &= E3G_CLOCK_CLEAR_MASK;
+
+	switch (rate) {
+	case 96000:
+		clock = E3G_96KHZ;
+		break;
+	case 88200:
+		clock = E3G_88KHZ;
+		break;
+	case 48000:
+		clock = E3G_48KHZ;
+		break;
+	case 44100:
+		clock = E3G_44KHZ;
+		break;
+	case 32000:
+		clock = E3G_32KHZ;
+		break;
+	default:
+		clock = E3G_CONTINUOUS_CLOCK;
+		if (rate > 50000)
+			clock |= E3G_DOUBLE_SPEED_MODE;
+		break;
+	}
+
+	control_reg |= clock;
+	control_reg = set_spdif_bits(chip, control_reg, rate);
+
+	base_rate = rate;
+	if (base_rate > 50000)
+		base_rate /= 2;
+	if (base_rate < 32000)
+		base_rate = 32000;
+
+	frq_reg = E3G_MAGIC_NUMBER / base_rate - 2;
+	if (frq_reg > E3G_FREQ_REG_MAX)
+		frq_reg = E3G_FREQ_REG_MAX;
+
+	chip->comm_page->sample_rate = cpu_to_le32(rate);	/* ignored by the DSP */
+	chip->sample_rate = rate;
+	DE_ACT(("SetSampleRate: %d clock %x\n", rate, control_reg));
+
+	/* Tell the DSP about it - DSP reads both control reg & freq reg */
+	return write_control_reg(chip, control_reg, frq_reg, 0);
+}
+
+
+
+/* Set the sample clock source to internal, S/PDIF, ADAT */
+static int set_input_clock(struct echoaudio *chip, u16 clock)
+{
+	u32 control_reg, clocks_from_dsp;
+
+	DE_ACT(("set_input_clock:\n"));
+
+	/* Mask off the clock select bits */
+	control_reg = le32_to_cpu(chip->comm_page->control_register) &
+		E3G_CLOCK_CLEAR_MASK;
+	clocks_from_dsp = le32_to_cpu(chip->comm_page->status_clocks);
+
+	switch (clock) {
+	case ECHO_CLOCK_INTERNAL:
+		DE_ACT(("Set Echo3G clock to INTERNAL\n"));
+		chip->input_clock = ECHO_CLOCK_INTERNAL;
+		return set_sample_rate(chip, chip->sample_rate);
+	case ECHO_CLOCK_SPDIF:
+		if (chip->digital_mode == DIGITAL_MODE_ADAT)
+			return -EAGAIN;
+		DE_ACT(("Set Echo3G clock to SPDIF\n"));
+		control_reg |= E3G_SPDIF_CLOCK;
+		if (clocks_from_dsp & E3G_CLOCK_DETECT_BIT_SPDIF96)
+			control_reg |= E3G_DOUBLE_SPEED_MODE;
+		else
+			control_reg &= ~E3G_DOUBLE_SPEED_MODE;
+		break;
+	case ECHO_CLOCK_ADAT:
+		if (chip->digital_mode != DIGITAL_MODE_ADAT)
+			return -EAGAIN;
+		DE_ACT(("Set Echo3G clock to ADAT\n"));
+		control_reg |= E3G_ADAT_CLOCK;
+		control_reg &= ~E3G_DOUBLE_SPEED_MODE;
+		break;
+	case ECHO_CLOCK_WORD:
+		DE_ACT(("Set Echo3G clock to WORD\n"));
+		control_reg |= E3G_WORD_CLOCK;
+		if (clocks_from_dsp & E3G_CLOCK_DETECT_BIT_WORD96)
+			control_reg |= E3G_DOUBLE_SPEED_MODE;
+		else
+			control_reg &= ~E3G_DOUBLE_SPEED_MODE;
+		break;
+	default:
+		DE_ACT(("Input clock 0x%x not supported for Echo3G\n", clock));
+		return -EINVAL;
+	}
+
+	chip->input_clock = clock;
+	return write_control_reg(chip, control_reg, get_frq_reg(chip), 1);
+}
+
+
+
+static int dsp_set_digital_mode(struct echoaudio *chip, u8 mode)
+{
+	u32 control_reg;
+	int err, incompatible_clock;
+
+	/* Set clock to "internal" if it's not compatible with the new mode */
+	incompatible_clock = FALSE;
+	switch (mode) {
+	case DIGITAL_MODE_SPDIF_OPTICAL:
+	case DIGITAL_MODE_SPDIF_RCA:
+		if (chip->input_clock == ECHO_CLOCK_ADAT)
+			incompatible_clock = TRUE;
+		break;
+	case DIGITAL_MODE_ADAT:
+		if (chip->input_clock == ECHO_CLOCK_SPDIF)
+			incompatible_clock = TRUE;
+		break;
+	default:
+		DE_ACT(("Digital mode not supported: %d\n", mode));
+		return -EINVAL;
+	}
+
+	spin_lock_irq(&chip->lock);
+
+	if (incompatible_clock) {
+		chip->sample_rate = 48000;
+		set_input_clock(chip, ECHO_CLOCK_INTERNAL);
+	}
+
+	/* Clear the current digital mode */
+	control_reg = le32_to_cpu(chip->comm_page->control_register);
+	control_reg &= E3G_DIGITAL_MODE_CLEAR_MASK;
+
+	/* Tweak the control reg */
+	switch (mode) {
+	case DIGITAL_MODE_SPDIF_OPTICAL:
+		control_reg |= E3G_SPDIF_OPTICAL_MODE;
+		break;
+	case DIGITAL_MODE_SPDIF_RCA:
+		/* E3G_SPDIF_OPTICAL_MODE bit cleared */
+		break;
+	case DIGITAL_MODE_ADAT:
+		control_reg |= E3G_ADAT_MODE;
+		control_reg &= ~E3G_DOUBLE_SPEED_MODE;	/* @@ useless */
+		break;
+	}
+
+	err = write_control_reg(chip, control_reg, get_frq_reg(chip), 1);
+	spin_unlock_irq(&chip->lock);
+	if (err < 0)
+		return err;
+	chip->digital_mode = mode;
+
+	DE_ACT(("set_digital_mode(%d)\n", chip->digital_mode));
+	return incompatible_clock;
+}
diff --git a/sound/pci/echoaudio/echoaudio_dsp.c b/sound/pci/echoaudio/echoaudio_dsp.c
new file mode 100644
index 000000000..42afa837d
--- /dev/null
+++ b/sound/pci/echoaudio/echoaudio_dsp.c
@@ -0,0 +1,1125 @@
+/****************************************************************************
+
+   Copyright Echo Digital Audio Corporation (c) 1998 - 2004
+   All rights reserved
+   www.echoaudio.com
+
+   This file is part of Echo Digital Audio's generic driver library.
+
+   Echo Digital Audio's generic driver library 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.
+
+   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.
+
+   *************************************************************************
+
+ Translation from C++ and adaptation for use in ALSA-Driver
+ were made by Giuliano Pochini <pochini@shiny.it>
+
+****************************************************************************/
+
+#if PAGE_SIZE < 4096
+#error PAGE_SIZE is < 4k
+#endif
+
+static int restore_dsp_rettings(struct echoaudio *chip);
+
+
+/* Some vector commands involve the DSP reading or writing data to and from the
+comm page; if you send one of these commands to the DSP, it will complete the
+command and then write a non-zero value to the Handshake field in the
+comm page.  This function waits for the handshake to show up. */
+static int wait_handshake(struct echoaudio *chip)
+{
+	int i;
+
+	/* Wait up to 10ms for the handshake from the DSP */
+	for (i = 0; i < HANDSHAKE_TIMEOUT; i++) {
+		/* Look for the handshake value */
+		if (chip->comm_page->handshake) {
+			/*if (i)  DE_ACT(("Handshake time: %d\n", i));*/
+			return 0;
+		}
+		udelay(1);
+	}
+
+	snd_printk(KERN_ERR "wait_handshake(): Timeout waiting for DSP\n");
+	return -EBUSY;
+}
+
+
+
+/* Much of the interaction between the DSP and the driver is done via vector
+commands; send_vector writes a vector command to the DSP.  Typically, this
+causes the DSP to read or write fields in the comm page.
+PCI posting is not required thanks to the handshake logic. */
+static int send_vector(struct echoaudio *chip, u32 command)
+{
+	int i;
+
+	wmb();	/* Flush all pending writes before sending the command */
+
+	/* Wait up to 100ms for the "vector busy" bit to be off */
+	for (i = 0; i < VECTOR_BUSY_TIMEOUT; i++) {
+		if (!(get_dsp_register(chip, CHI32_VECTOR_REG) &
+		      CHI32_VECTOR_BUSY)) {
+			set_dsp_register(chip, CHI32_VECTOR_REG, command);
+			/*if (i)  DE_ACT(("send_vector time: %d\n", i));*/
+			return 0;
+		}
+		udelay(1);
+	}
+
+	DE_ACT((KERN_ERR "timeout on send_vector\n"));
+	return -EBUSY;
+}
+
+
+
+/* write_dsp writes a 32-bit value to the DSP; this is used almost
+exclusively for loading the DSP. */
+static int write_dsp(struct echoaudio *chip, u32 data)
+{
+	u32 status, i;
+
+	for (i = 0; i < 10000000; i++) {	/* timeout = 10s */
+		status = get_dsp_register(chip, CHI32_STATUS_REG);
+		if ((status & CHI32_STATUS_HOST_WRITE_EMPTY) != 0) {
+			set_dsp_register(chip, CHI32_DATA_REG, data);
+			wmb();			/* write it immediately */
+			return 0;
+		}
+		udelay(1);
+		cond_resched();
+	}
+
+	chip->bad_board = TRUE;		/* Set TRUE until DSP re-loaded */
+	DE_ACT((KERN_ERR "write_dsp: Set bad_board to TRUE\n"));
+	return -EIO;
+}
+
+
+
+/* read_dsp reads a 32-bit value from the DSP; this is used almost
+exclusively for loading the DSP and checking the status of the ASIC. */
+static int read_dsp(struct echoaudio *chip, u32 *data)
+{
+	u32 status, i;
+
+	for (i = 0; i < READ_DSP_TIMEOUT; i++) {
+		status = get_dsp_register(chip, CHI32_STATUS_REG);
+		if ((status & CHI32_STATUS_HOST_READ_FULL) != 0) {
+			*data = get_dsp_register(chip, CHI32_DATA_REG);
+			return 0;
+		}
+		udelay(1);
+		cond_resched();
+	}
+
+	chip->bad_board = TRUE;		/* Set TRUE until DSP re-loaded */
+	DE_INIT((KERN_ERR "read_dsp: Set bad_board to TRUE\n"));
+	return -EIO;
+}
+
+
+
+/****************************************************************************
+	Firmware loading functions
+ ****************************************************************************/
+
+/* This function is used to read back the serial number from the DSP;
+this is triggered by the SET_COMMPAGE_ADDR command.
+Only some early Echogals products have serial numbers in the ROM;
+the serial number is not used, but you still need to do this as
+part of the DSP load process. */
+static int read_sn(struct echoaudio *chip)
+{
+	int i;
+	u32 sn[6];
+
+	for (i = 0; i < 5; i++) {
+		if (read_dsp(chip, &sn[i])) {
+			snd_printk(KERN_ERR "Failed to read serial number\n");
+			return -EIO;
+		}
+	}
+	DE_INIT(("Read serial number %08x %08x %08x %08x %08x\n",
+		 sn[0], sn[1], sn[2], sn[3], sn[4]));
+	return 0;
+}
+
+
+
+#ifndef ECHOCARD_HAS_ASIC
+/* This card has no ASIC, just return ok */
+static inline int check_asic_status(struct echoaudio *chip)
+{
+	chip->asic_loaded = TRUE;
+	return 0;
+}
+
+#endif /* !ECHOCARD_HAS_ASIC */
+
+
+
+#ifdef ECHOCARD_HAS_ASIC
+
+/* Load ASIC code - done after the DSP is loaded */
+static int load_asic_generic(struct echoaudio *chip, u32 cmd,
+			     const struct firmware *asic)
+{
+	const struct firmware *fw;
+	int err;
+	u32 i, size;
+	u8 *code;
+
+	if ((err = get_firmware(&fw, asic, chip)) < 0) {
+		snd_printk(KERN_WARNING "Firmware not found !\n");
+		return err;
+	}
+
+	code = (u8 *)fw->data;
+	size = fw->size;
+
+	/* Send the "Here comes the ASIC" command */
+	if (write_dsp(chip, cmd) < 0)
+		goto la_error;
+
+	/* Write length of ASIC file in bytes */
+	if (write_dsp(chip, size) < 0)
+		goto la_error;
+
+	for (i = 0; i < size; i++) {
+		if (write_dsp(chip, code[i]) < 0)
+			goto la_error;
+	}
+
+	DE_INIT(("ASIC loaded\n"));
+	free_firmware(fw);
+	return 0;
+
+la_error:
+	DE_INIT(("failed on write_dsp\n"));
+	free_firmware(fw);
+	return -EIO;
+}
+
+#endif /* ECHOCARD_HAS_ASIC */
+
+
+
+#ifdef DSP_56361
+
+/* Install the resident loader for 56361 DSPs;  The resident loader is on
+the EPROM on the board for 56301 DSP. The resident loader is a tiny little
+program that is used to load the real DSP code. */
+static int install_resident_loader(struct echoaudio *chip)
+{
+	u32 address;
+	int index, words, i;
+	u16 *code;
+	u32 status;
+	const struct firmware *fw;
+
+	/* 56361 cards only!  This check is required by the old 56301-based
+	Mona and Gina24 */
+	if (chip->device_id != DEVICE_ID_56361)
+		return 0;
+
+	/* Look to see if the resident loader is present.  If the resident
+	loader is already installed, host flag 5 will be on. */
+	status = get_dsp_register(chip, CHI32_STATUS_REG);
+	if (status & CHI32_STATUS_REG_HF5) {
+		DE_INIT(("Resident loader already installed; status is 0x%x\n",
+			 status));
+		return 0;
+	}
+
+	if ((i = get_firmware(&fw, &card_fw[FW_361_LOADER], chip)) < 0) {
+		snd_printk(KERN_WARNING "Firmware not found !\n");
+		return i;
+	}
+
+	/* The DSP code is an array of 16 bit words.  The array is divided up
+	into sections.  The first word of each section is the size in words,
+	followed by the section type.
+	Since DSP addresses and data are 24 bits wide, they each take up two
+	16 bit words in the array.
+	This is a lot like the other loader loop, but it's not a loop, you
+	don't write the memory type, and you don't write a zero at the end. */
+
+	/* Set DSP format bits for 24 bit mode */
+	set_dsp_register(chip, CHI32_CONTROL_REG,
+			 get_dsp_register(chip, CHI32_CONTROL_REG) | 0x900);
+
+	code = (u16 *)fw->data;
+
+	/* Skip the header section; the first word in the array is the size
+	of the first section, so the first real section of code is pointed
+	to by Code[0]. */
+	index = code[0];
+
+	/* Skip the section size, LRS block type, and DSP memory type */
+	index += 3;
+
+	/* Get the number of DSP words to write */
+	words = code[index++];
+
+	/* Get the DSP address for this block; 24 bits, so build from two words */
+	address = ((u32)code[index] << 16) + code[index + 1];
+	index += 2;
+
+	/* Write the count to the DSP */
+	if (write_dsp(chip, words)) {
+		DE_INIT(("install_resident_loader: Failed to write word count!\n"));
+		goto irl_error;
+	}
+	/* Write the DSP address */
+	if (write_dsp(chip, address)) {
+		DE_INIT(("install_resident_loader: Failed to write DSP address!\n"));
+		goto irl_error;
+	}
+	/* Write out this block of code to the DSP */
+	for (i = 0; i < words; i++) {
+		u32 data;
+
+		data = ((u32)code[index] << 16) + code[index + 1];
+		if (write_dsp(chip, data)) {
+			DE_INIT(("install_resident_loader: Failed to write DSP code\n"));
+			goto irl_error;
+		}
+		index += 2;
+	}
+
+	/* Wait for flag 5 to come up */
+	for (i = 0; i < 200; i++) {	/* Timeout is 50us * 200 = 10ms */
+		udelay(50);
+		status = get_dsp_register(chip, CHI32_STATUS_REG);
+		if (status & CHI32_STATUS_REG_HF5)
+			break;
+	}
+
+	if (i == 200) {
+		DE_INIT(("Resident loader failed to set HF5\n"));
+		goto irl_error;
+	}
+
+	DE_INIT(("Resident loader successfully installed\n"));
+	free_firmware(fw);
+	return 0;
+
+irl_error:
+	free_firmware(fw);
+	return -EIO;
+}
+
+#endif /* DSP_56361 */
+
+
+static int load_dsp(struct echoaudio *chip, u16 *code)
+{
+	u32 address, data;
+	int index, words, i;
+
+	if (chip->dsp_code == code) {
+		DE_INIT(("DSP is already loaded!\n"));
+		return 0;
+	}
+	chip->bad_board = TRUE;		/* Set TRUE until DSP loaded */
+	chip->dsp_code = NULL;		/* Current DSP code not loaded */
+	chip->asic_loaded = FALSE;	/* Loading the DSP code will reset the ASIC */
+
+	DE_INIT(("load_dsp: Set bad_board to TRUE\n"));
+
+	/* If this board requires a resident loader, install it. */
+#ifdef DSP_56361
+	if ((i = install_resident_loader(chip)) < 0)
+		return i;
+#endif
+
+	/* Send software reset command */
+	if (send_vector(chip, DSP_VC_RESET) < 0) {
+		DE_INIT(("LoadDsp: send_vector DSP_VC_RESET failed, Critical Failure\n"));
+		return -EIO;
+	}
+	/* Delay 10us */
+	udelay(10);
+
+	/* Wait 10ms for HF3 to indicate that software reset is complete */
+	for (i = 0; i < 1000; i++) {	/* Timeout is 10us * 1000 = 10ms */
+		if (get_dsp_register(chip, CHI32_STATUS_REG) &
+		    CHI32_STATUS_REG_HF3)
+			break;
+		udelay(10);
+	}
+
+	if (i == 1000) {
+		DE_INIT(("load_dsp: Timeout waiting for CHI32_STATUS_REG_HF3\n"));
+		return -EIO;
+	}
+
+	/* Set DSP format bits for 24 bit mode now that soft reset is done */
+	set_dsp_register(chip, CHI32_CONTROL_REG,
+			 get_dsp_register(chip, CHI32_CONTROL_REG) | 0x900);
+
+	/* Main loader loop */
+
+	index = code[0];
+	for (;;) {
+		int block_type, mem_type;
+
+		/* Total Block Size */
+		index++;
+
+		/* Block Type */
+		block_type = code[index];
+		if (block_type == 4)	/* We're finished */
+			break;
+
+		index++;
+
+		/* Memory Type  P=0,X=1,Y=2 */
+		mem_type = code[index++];
+
+		/* Block Code Size */
+		words = code[index++];
+		if (words == 0)		/* We're finished */
+			break;
+
+		/* Start Address */
+		address = ((u32)code[index] << 16) + code[index + 1];
+		index += 2;
+
+		if (write_dsp(chip, words) < 0) {
+			DE_INIT(("load_dsp: failed to write number of DSP words\n"));
+			return -EIO;
+		}
+		if (write_dsp(chip, address) < 0) {
+			DE_INIT(("load_dsp: failed to write DSP address\n"));
+			return -EIO;
+		}
+		if (write_dsp(chip, mem_type) < 0) {
+			DE_INIT(("load_dsp: failed to write DSP memory type\n"));
+			return -EIO;
+		}
+		/* Code */
+		for (i = 0; i < words; i++, index+=2) {
+			data = ((u32)code[index] << 16) + code[index + 1];
+			if (write_dsp(chip, data) < 0) {
+				DE_INIT(("load_dsp: failed to write DSP data\n"));
+				return -EIO;
+			}
+		}
+	}
+
+	if (write_dsp(chip, 0) < 0) {	/* We're done!!! */
+		DE_INIT(("load_dsp: Failed to write final zero\n"));
+		return -EIO;
+	}
+	udelay(10);
+
+	for (i = 0; i < 5000; i++) {	/* Timeout is 100us * 5000 = 500ms */
+		/* Wait for flag 4 - indicates that the DSP loaded OK */
+		if (get_dsp_register(chip, CHI32_STATUS_REG) &
+		    CHI32_STATUS_REG_HF4) {
+			set_dsp_register(chip, CHI32_CONTROL_REG,
+					 get_dsp_register(chip, CHI32_CONTROL_REG) & ~0x1b00);
+
+			if (write_dsp(chip, DSP_FNC_SET_COMMPAGE_ADDR) < 0) {
+				DE_INIT(("load_dsp: Failed to write DSP_FNC_SET_COMMPAGE_ADDR\n"));
+				return -EIO;
+			}
+
+			if (write_dsp(chip, chip->comm_page_phys) < 0) {
+				DE_INIT(("load_dsp: Failed to write comm page address\n"));
+				return -EIO;
+			}
+
+			/* Get the serial number via slave mode.
+			This is triggered by the SET_COMMPAGE_ADDR command.
+			We don't actually use the serial number but we have to
+			get it as part of the DSP init voodoo. */
+			if (read_sn(chip) < 0) {
+				DE_INIT(("load_dsp: Failed to read serial number\n"));
+				return -EIO;
+			}
+
+			chip->dsp_code = code;		/* Show which DSP code loaded */
+			chip->bad_board = FALSE;	/* DSP OK */
+			DE_INIT(("load_dsp: OK!\n"));
+			return 0;
+		}
+		udelay(100);
+	}
+
+	DE_INIT(("load_dsp: DSP load timed out waiting for HF4\n"));
+	return -EIO;
+}
+
+
+
+/* load_firmware takes care of loading the DSP and any ASIC code. */
+static int load_firmware(struct echoaudio *chip)
+{
+	const struct firmware *fw;
+	int box_type, err;
+
+	snd_assert(chip->dsp_code_to_load && chip->comm_page, return -EPERM);
+
+	/* See if the ASIC is present and working - only if the DSP is already loaded */
+	if (chip->dsp_code) {
+		if ((box_type = check_asic_status(chip)) >= 0)
+			return box_type;
+		/* ASIC check failed; force the DSP to reload */
+		chip->dsp_code = NULL;
+	}
+
+	if ((err = get_firmware(&fw, chip->dsp_code_to_load, chip)) < 0)
+		return err;
+	err = load_dsp(chip, (u16 *)fw->data);
+	free_firmware(fw);
+	if (err < 0)
+		return err;
+
+	if ((box_type = load_asic(chip)) < 0)
+		return box_type;	/* error */
+
+	if ((err = restore_dsp_rettings(chip)) < 0)
+		return err;
+
+	return box_type;
+}
+
+
+
+/****************************************************************************
+	Mixer functions
+ ****************************************************************************/
+
+#if defined(ECHOCARD_HAS_INPUT_NOMINAL_LEVEL) || \
+	defined(ECHOCARD_HAS_OUTPUT_NOMINAL_LEVEL)
+
+/* Set the nominal level for an input or output bus (true = -10dBV, false = +4dBu) */
+static int set_nominal_level(struct echoaudio *chip, u16 index, char consumer)
+{
+	snd_assert(index < num_busses_out(chip) + num_busses_in(chip),
+		   return -EINVAL);
+
+	/* Wait for the handshake (OK even if ASIC is not loaded) */
+	if (wait_handshake(chip))
+		return -EIO;
+
+	chip->nominal_level[index] = consumer;
+
+	if (consumer)
+		chip->comm_page->nominal_level_mask |= cpu_to_le32(1 << index);
+	else
+		chip->comm_page->nominal_level_mask &= ~cpu_to_le32(1 << index);
+
+	return 0;
+}
+
+#endif /* ECHOCARD_HAS_*_NOMINAL_LEVEL */
+
+
+
+/* Set the gain for a single physical output channel (dB). */
+static int set_output_gain(struct echoaudio *chip, u16 channel, s8 gain)
+{
+	snd_assert(channel < num_busses_out(chip), return -EINVAL);
+
+	if (wait_handshake(chip))
+		return -EIO;
+
+	/* Save the new value */
+	chip->output_gain[channel] = gain;
+	chip->comm_page->line_out_level[channel] = gain;
+	return 0;
+}
+
+
+
+#ifdef ECHOCARD_HAS_MONITOR
+/* Set the monitor level from an input bus to an output bus. */
+static int set_monitor_gain(struct echoaudio *chip, u16 output, u16 input,
+			    s8 gain)
+{
+	snd_assert(output < num_busses_out(chip) &&
+		   input < num_busses_in(chip), return -EINVAL);
+
+	if (wait_handshake(chip))
+		return -EIO;
+
+	chip->monitor_gain[output][input] = gain;
+	chip->comm_page->monitors[monitor_index(chip, output, input)] = gain;
+	return 0;
+}
+#endif /* ECHOCARD_HAS_MONITOR */
+
+
+/* Tell the DSP to read and update output, nominal & monitor levels in comm page. */
+static int update_output_line_level(struct echoaudio *chip)
+{
+	if (wait_handshake(chip))
+		return -EIO;
+	clear_handshake(chip);
+	return send_vector(chip, DSP_VC_UPDATE_OUTVOL);
+}
+
+
+
+/* Tell the DSP to read and update input levels in comm page */
+static int update_input_line_level(struct echoaudio *chip)
+{
+	if (wait_handshake(chip))
+		return -EIO;
+	clear_handshake(chip);
+	return send_vector(chip, DSP_VC_UPDATE_INGAIN);
+}
+
+
+
+/* set_meters_on turns the meters on or off.  If meters are turned on, the DSP
+will write the meter and clock detect values to the comm page at about 30Hz */
+static void set_meters_on(struct echoaudio *chip, char on)
+{
+	if (on && !chip->meters_enabled) {
+		send_vector(chip, DSP_VC_METERS_ON);
+		chip->meters_enabled = 1;
+	} else if (!on && chip->meters_enabled) {
+		send_vector(chip, DSP_VC_METERS_OFF);
+		chip->meters_enabled = 0;
+		memset((s8 *)chip->comm_page->vu_meter, ECHOGAIN_MUTED,
+		       DSP_MAXPIPES);
+		memset((s8 *)chip->comm_page->peak_meter, ECHOGAIN_MUTED,
+		       DSP_MAXPIPES);
+	}
+}
+
+
+
+/* Fill out an the given array using the current values in the comm page.
+Meters are written in the comm page by the DSP in this order:
+ Output busses
+ Input busses
+ Output pipes (vmixer cards only)
+
+This function assumes there are no more than 16 in/out busses or pipes
+Meters is an array [3][16][2] of long. */
+static void get_audio_meters(struct echoaudio *chip, long *meters)
+{
+	int i, m, n;
+
+	m = 0;
+	n = 0;
+	for (i = 0; i < num_busses_out(chip); i++, m++) {
+		meters[n++] = chip->comm_page->vu_meter[m];
+		meters[n++] = chip->comm_page->peak_meter[m];
+	}
+	for (; n < 32; n++)
+		meters[n] = 0;
+
+#ifdef ECHOCARD_ECHO3G
+	m = E3G_MAX_OUTPUTS;	/* Skip unused meters */
+#endif
+
+	for (i = 0; i < num_busses_in(chip); i++, m++) {
+		meters[n++] = chip->comm_page->vu_meter[m];
+		meters[n++] = chip->comm_page->peak_meter[m];
+	}
+	for (; n < 64; n++)
+		meters[n] = 0;
+
+#ifdef ECHOCARD_HAS_VMIXER
+	for (i = 0; i < num_pipes_out(chip); i++, m++) {
+		meters[n++] = chip->comm_page->vu_meter[m];
+		meters[n++] = chip->comm_page->peak_meter[m];
+	}
+#endif
+	for (; n < 96; n++)
+		meters[n] = 0;
+}
+
+
+
+static int restore_dsp_rettings(struct echoaudio *chip)
+{
+	int err;
+	DE_INIT(("restore_dsp_settings\n"));
+
+	if ((err = check_asic_status(chip)) < 0)
+		return err;
+
+	/* @ Gina20/Darla20 only. Should be harmless for other cards. */
+	chip->comm_page->gd_clock_state = GD_CLOCK_UNDEF;
+	chip->comm_page->gd_spdif_status = GD_SPDIF_STATUS_UNDEF;
+	chip->comm_page->handshake = 0xffffffff;
+
+	if ((err = set_sample_rate(chip, chip->sample_rate)) < 0)
+		return err;
+
+	if (chip->meters_enabled)
+		if (send_vector(chip, DSP_VC_METERS_ON) < 0)
+			return -EIO;
+
+#ifdef ECHOCARD_HAS_EXTERNAL_CLOCK
+	if (set_input_clock(chip, chip->input_clock) < 0)
+		return -EIO;
+#endif
+
+#ifdef ECHOCARD_HAS_OUTPUT_CLOCK_SWITCH
+	if (set_output_clock(chip, chip->output_clock) < 0)
+		return -EIO;
+#endif
+
+	if (update_output_line_level(chip) < 0)
+		return -EIO;
+
+	if (update_input_line_level(chip) < 0)
+		return -EIO;
+
+#ifdef ECHOCARD_HAS_VMIXER
+	if (update_vmixer_level(chip) < 0)
+		return -EIO;
+#endif
+
+	if (wait_handshake(chip) < 0)
+		return -EIO;
+	clear_handshake(chip);
+
+	DE_INIT(("restore_dsp_rettings done\n"));
+	return send_vector(chip, DSP_VC_UPDATE_FLAGS);
+}
+
+
+
+/****************************************************************************
+	Transport functions
+ ****************************************************************************/
+
+/* set_audio_format() sets the format of the audio data in host memory for
+this pipe.  Note that _MS_ (mono-to-stereo) playback modes are not used by ALSA
+but they are here because they are just mono while capturing */
+static void set_audio_format(struct echoaudio *chip, u16 pipe_index,
+			     const struct audioformat *format)
+{
+	u16 dsp_format;
+
+	dsp_format = DSP_AUDIOFORM_SS_16LE;
+
+	/* Look for super-interleave (no big-endian and 8 bits) */
+	if (format->interleave > 2) {
+		switch (format->bits_per_sample) {
+		case 16:
+			dsp_format = DSP_AUDIOFORM_SUPER_INTERLEAVE_16LE;
+			break;
+		case 24:
+			dsp_format = DSP_AUDIOFORM_SUPER_INTERLEAVE_24LE;
+			break;
+		case 32:
+			dsp_format = DSP_AUDIOFORM_SUPER_INTERLEAVE_32LE;
+			break;
+		}
+		dsp_format |= format->interleave;
+	} else if (format->data_are_bigendian) {
+		/* For big-endian data, only 32 bit samples are supported */
+		switch (format->interleave) {
+		case 1:
+			dsp_format = DSP_AUDIOFORM_MM_32BE;
+			break;
+#ifdef ECHOCARD_HAS_STEREO_BIG_ENDIAN32
+		case 2:
+			dsp_format = DSP_AUDIOFORM_SS_32BE;
+			break;
+#endif
+		}
+	} else if (format->interleave == 1 &&
+		   format->bits_per_sample == 32 && !format->mono_to_stereo) {
+		/* 32 bit little-endian mono->mono case */
+		dsp_format = DSP_AUDIOFORM_MM_32LE;
+	} else {
+		/* Handle the other little-endian formats */
+		switch (format->bits_per_sample) {
+		case 8:
+			if (format->interleave == 2)
+				dsp_format = DSP_AUDIOFORM_SS_8;
+			else
+				dsp_format = DSP_AUDIOFORM_MS_8;
+			break;
+		default:
+		case 16:
+			if (format->interleave == 2)
+				dsp_format = DSP_AUDIOFORM_SS_16LE;
+			else
+				dsp_format = DSP_AUDIOFORM_MS_16LE;
+			break;
+		case 24:
+			if (format->interleave == 2)
+				dsp_format = DSP_AUDIOFORM_SS_24LE;
+			else
+				dsp_format = DSP_AUDIOFORM_MS_24LE;
+			break;
+		case 32:
+			if (format->interleave == 2)
+				dsp_format = DSP_AUDIOFORM_SS_32LE;
+			else
+				dsp_format = DSP_AUDIOFORM_MS_32LE;
+			break;
+		}
+	}
+	DE_ACT(("set_audio_format[%d] = %x\n", pipe_index, dsp_format));
+	chip->comm_page->audio_format[pipe_index] = cpu_to_le16(dsp_format);
+}
+
+
+
+/* start_transport starts transport for a set of pipes.
+The bits 1 in channel_mask specify what pipes to start. Only the bit of the
+first channel must be set, regardless its interleave.
+Same thing for pause_ and stop_ -trasport below. */
+static int start_transport(struct echoaudio *chip, u32 channel_mask,
+			   u32 cyclic_mask)
+{
+	DE_ACT(("start_transport %x\n", channel_mask));
+
+	if (wait_handshake(chip))
+		return -EIO;
+
+	chip->comm_page->cmd_start |= cpu_to_le32(channel_mask);
+
+	if (chip->comm_page->cmd_start) {
+		clear_handshake(chip);
+		send_vector(chip, DSP_VC_START_TRANSFER);
+		if (wait_handshake(chip))
+			return -EIO;
+		/* Keep track of which pipes are transporting */
+		chip->active_mask |= channel_mask;
+		chip->comm_page->cmd_start = 0;
+		return 0;
+	}
+
+	DE_ACT(("start_transport: No pipes to start!\n"));
+	return -EINVAL;
+}
+
+
+
+static int pause_transport(struct echoaudio *chip, u32 channel_mask)
+{
+	DE_ACT(("pause_transport %x\n", channel_mask));
+
+	if (wait_handshake(chip))
+		return -EIO;
+
+	chip->comm_page->cmd_stop |= cpu_to_le32(channel_mask);
+	chip->comm_page->cmd_reset = 0;
+	if (chip->comm_page->cmd_stop) {
+		clear_handshake(chip);
+		send_vector(chip, DSP_VC_STOP_TRANSFER);
+		if (wait_handshake(chip))
+			return -EIO;
+		/* Keep track of which pipes are transporting */
+		chip->active_mask &= ~channel_mask;
+		chip->comm_page->cmd_stop = 0;
+		chip->comm_page->cmd_reset = 0;
+		return 0;
+	}
+
+	DE_ACT(("pause_transport: No pipes to stop!\n"));
+	return 0;
+}
+
+
+
+static int stop_transport(struct echoaudio *chip, u32 channel_mask)
+{
+	DE_ACT(("stop_transport %x\n", channel_mask));
+
+	if (wait_handshake(chip))
+		return -EIO;
+
+	chip->comm_page->cmd_stop |= cpu_to_le32(channel_mask);
+	chip->comm_page->cmd_reset |= cpu_to_le32(channel_mask);
+	if (chip->comm_page->cmd_reset) {
+		clear_handshake(chip);
+		send_vector(chip, DSP_VC_STOP_TRANSFER);
+		if (wait_handshake(chip))
+			return -EIO;
+		/* Keep track of which pipes are transporting */
+		chip->active_mask &= ~channel_mask;
+		chip->comm_page->cmd_stop = 0;
+		chip->comm_page->cmd_reset = 0;
+		return 0;
+	}
+
+	DE_ACT(("stop_transport: No pipes to stop!\n"));
+	return 0;
+}
+
+
+
+static inline int is_pipe_allocated(struct echoaudio *chip, u16 pipe_index)
+{
+	return (chip->pipe_alloc_mask & (1 << pipe_index));
+}
+
+
+
+/* Stops everything and turns off the DSP. All pipes should be already
+stopped and unallocated. */
+static int rest_in_peace(struct echoaudio *chip)
+{
+	DE_ACT(("rest_in_peace() open=%x\n", chip->pipe_alloc_mask));
+
+	/* Stops all active pipes (just to be sure) */
+	stop_transport(chip, chip->active_mask);
+
+	set_meters_on(chip, FALSE);
+
+#ifdef ECHOCARD_HAS_MIDI
+	enable_midi_input(chip, FALSE);
+#endif
+
+	/* Go to sleep */
+	if (chip->dsp_code) {
+		/* Make load_firmware do a complete reload */
+		chip->dsp_code = NULL;
+		/* Put the DSP to sleep */
+		return send_vector(chip, DSP_VC_GO_COMATOSE);
+	}
+	return 0;
+}
+
+
+
+/* Fills the comm page with default values */
+static int init_dsp_comm_page(struct echoaudio *chip)
+{
+	/* Check if the compiler added extra padding inside the structure */
+	if (offsetof(struct comm_page, midi_output) != 0xbe0) {
+		DE_INIT(("init_dsp_comm_page() - Invalid struct comm_page structure\n"));
+		return -EPERM;
+	}
+
+	/* Init all the basic stuff */
+	chip->card_name = ECHOCARD_NAME;
+	chip->bad_board = TRUE;	/* Set TRUE until DSP loaded */
+	chip->dsp_code = NULL;	/* Current DSP code not loaded */
+	chip->digital_mode = DIGITAL_MODE_NONE;
+	chip->input_clock = ECHO_CLOCK_INTERNAL;
+	chip->output_clock = ECHO_CLOCK_WORD;
+	chip->asic_loaded = FALSE;
+	memset(chip->comm_page, 0, sizeof(struct comm_page));
+
+	/* Init the comm page */
+	chip->comm_page->comm_size =
+		__constant_cpu_to_le32(sizeof(struct comm_page));
+	chip->comm_page->handshake = 0xffffffff;
+	chip->comm_page->midi_out_free_count =
+		__constant_cpu_to_le32(DSP_MIDI_OUT_FIFO_SIZE);
+	chip->comm_page->sample_rate = __constant_cpu_to_le32(44100);
+	chip->sample_rate = 44100;
+
+	/* Set line levels so we don't blast any inputs on startup */
+	memset(chip->comm_page->monitors, ECHOGAIN_MUTED, MONITOR_ARRAY_SIZE);
+	memset(chip->comm_page->vmixer, ECHOGAIN_MUTED, VMIXER_ARRAY_SIZE);
+
+	return 0;
+}
+
+
+
+/* This function initializes the several volume controls for busses and pipes.
+This MUST be called after the DSP is up and running ! */
+static int init_line_levels(struct echoaudio *chip)
+{
+	int st, i, o;
+
+	DE_INIT(("init_line_levels\n"));
+
+	/* Mute output busses */
+	for (i = 0; i < num_busses_out(chip); i++)
+		if ((st = set_output_gain(chip, i, ECHOGAIN_MUTED)))
+			return st;
+	if ((st = update_output_line_level(chip)))
+		return st;
+
+#ifdef ECHOCARD_HAS_VMIXER
+	/* Mute the Vmixer */
+	for (i = 0; i < num_pipes_out(chip); i++)
+		for (o = 0; o < num_busses_out(chip); o++)
+			if ((st = set_vmixer_gain(chip, o, i, ECHOGAIN_MUTED)))
+				return st;
+	if ((st = update_vmixer_level(chip)))
+		return st;
+#endif /* ECHOCARD_HAS_VMIXER */
+
+#ifdef ECHOCARD_HAS_MONITOR
+	/* Mute the monitor mixer */
+	for (o = 0; o < num_busses_out(chip); o++)
+		for (i = 0; i < num_busses_in(chip); i++)
+			if ((st = set_monitor_gain(chip, o, i, ECHOGAIN_MUTED)))
+				return st;
+	if ((st = update_output_line_level(chip)))
+		return st;
+#endif /* ECHOCARD_HAS_MONITOR */
+
+#ifdef ECHOCARD_HAS_INPUT_GAIN
+	for (i = 0; i < num_busses_in(chip); i++)
+		if ((st = set_input_gain(chip, i, ECHOGAIN_MUTED)))
+			return st;
+	if ((st = update_input_line_level(chip)))
+		return st;
+#endif /* ECHOCARD_HAS_INPUT_GAIN */
+
+	return 0;
+}
+
+
+
+/* This is low level part of the interrupt handler.
+It returns -1 if the IRQ is not ours, or N>=0 if it is, where N is the number
+of midi data in the input queue. */
+static int service_irq(struct echoaudio *chip)
+{
+	int st;
+
+	/* Read the DSP status register and see if this DSP generated this interrupt */
+	if (get_dsp_register(chip, CHI32_STATUS_REG) & CHI32_STATUS_IRQ) {
+		st = 0;
+#ifdef ECHOCARD_HAS_MIDI
+		/* Get and parse midi data if present */
+		if (chip->comm_page->midi_input[0])	/* The count is at index 0 */
+			st = midi_service_irq(chip);	/* Returns how many midi bytes we received */
+#endif
+		/* Clear the hardware interrupt */
+		chip->comm_page->midi_input[0] = 0;
+		send_vector(chip, DSP_VC_ACK_INT);
+		return st;
+	}
+	return -1;
+}
+
+
+
+
+/******************************************************************************
+	Functions for opening and closing pipes
+ ******************************************************************************/
+
+/* allocate_pipes is used to reserve audio pipes for your exclusive use.
+The call will fail if some pipes are already allocated. */
+static int allocate_pipes(struct echoaudio *chip, struct audiopipe *pipe,
+			  int pipe_index, int interleave)
+{
+	int i;
+	u32 channel_mask;
+	char is_cyclic;
+
+	DE_ACT(("allocate_pipes: ch=%d int=%d\n", pipe_index, interleave));
+
+	if (chip->bad_board)
+		return -EIO;
+
+	is_cyclic = 1;	/* This driver uses cyclic buffers only */
+
+	for (channel_mask = i = 0; i < interleave; i++)
+		channel_mask |= 1 << (pipe_index + i);
+	if (chip->pipe_alloc_mask & channel_mask) {
+		DE_ACT(("allocate_pipes: channel already open\n"));
+		return -EAGAIN;
+	}
+
+	chip->comm_page->position[pipe_index] = 0;
+	chip->pipe_alloc_mask |= channel_mask;
+	if (is_cyclic)
+		chip->pipe_cyclic_mask |= channel_mask;
+	pipe->index = pipe_index;
+	pipe->interleave = interleave;
+	pipe->state = PIPE_STATE_STOPPED;
+
+	/* The counter register is where the DSP writes the 32 bit DMA
+	position for a pipe.  The DSP is constantly updating this value as
+	it moves data. The DMA counter is in units of bytes, not samples. */
+	pipe->dma_counter = &chip->comm_page->position[pipe_index];
+	*pipe->dma_counter = 0;
+	DE_ACT(("allocate_pipes: ok\n"));
+	return pipe_index;
+}
+
+
+
+static int free_pipes(struct echoaudio *chip, struct audiopipe *pipe)
+{
+	u32 channel_mask;
+	int i;
+
+	DE_ACT(("free_pipes: Pipe %d\n", pipe->index));
+	snd_assert(is_pipe_allocated(chip, pipe->index), return -EINVAL);
+	snd_assert(pipe->state == PIPE_STATE_STOPPED, return -EINVAL);
+
+	for (channel_mask = i = 0; i < pipe->interleave; i++)
+		channel_mask |= 1 << (pipe->index + i);
+
+	chip->pipe_alloc_mask &= ~channel_mask;
+	chip->pipe_cyclic_mask &= ~channel_mask;
+	return 0;
+}
+
+
+
+/******************************************************************************
+	Functions for managing the scatter-gather list
+******************************************************************************/
+
+static int sglist_init(struct echoaudio *chip, struct audiopipe *pipe)
+{
+	pipe->sglist_head = 0;
+	memset(pipe->sgpage.area, 0, PAGE_SIZE);
+	chip->comm_page->sglist_addr[pipe->index].addr =
+		cpu_to_le32(pipe->sgpage.addr);
+	return 0;
+}
+
+
+
+static int sglist_add_mapping(struct echoaudio *chip, struct audiopipe *pipe,
+				dma_addr_t address, size_t length)
+{
+	int head = pipe->sglist_head;
+	struct sg_entry *list = (struct sg_entry *)pipe->sgpage.area;
+
+	if (head < MAX_SGLIST_ENTRIES - 1) {
+		list[head].addr = cpu_to_le32(address);
+		list[head].size = cpu_to_le32(length);
+		pipe->sglist_head++;
+	} else {
+		DE_ACT(("SGlist: too many fragments\n"));
+		return -ENOMEM;
+	}
+	return 0;
+}
+
+
+
+static inline int sglist_add_irq(struct echoaudio *chip, struct audiopipe *pipe)
+{
+	return sglist_add_mapping(chip, pipe, 0, 0);
+}
+
+
+
+static inline int sglist_wrap(struct echoaudio *chip, struct audiopipe *pipe)
+{
+	return sglist_add_mapping(chip, pipe, pipe->sgpage.addr, 0);
+}
diff --git a/sound/pci/echoaudio/echoaudio_dsp.h b/sound/pci/echoaudio/echoaudio_dsp.h
new file mode 100644
index 000000000..e55ee0099
--- /dev/null
+++ b/sound/pci/echoaudio/echoaudio_dsp.h
@@ -0,0 +1,694 @@
+/****************************************************************************
+
+   Copyright Echo Digital Audio Corporation (c) 1998 - 2004
+   All rights reserved
+   www.echoaudio.com
+
+   This file is part of Echo Digital Audio's generic driver library.
+
+   Echo Digital Audio's generic driver library 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.
+
+   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.
+
+   *************************************************************************
+
+ Translation from C++ and adaptation for use in ALSA-Driver
+ were made by Giuliano Pochini <pochini@shiny.it>
+
+****************************************************************************/
+
+#ifndef _ECHO_DSP_
+#define _ECHO_DSP_
+
+
+/**** Echogals: Darla20, Gina20, Layla20, and Darla24 ****/
+#if defined(ECHOGALS_FAMILY)
+
+#define NUM_ASIC_TESTS		5
+#define READ_DSP_TIMEOUT	1000000L	/* one second */
+
+/**** Echo24: Gina24, Layla24, Mona, Mia, Mia-midi ****/
+#elif defined(ECHO24_FAMILY)
+
+#define DSP_56361			/* Some Echo24 cards use the 56361 DSP */
+#define READ_DSP_TIMEOUT	100000L		/* .1 second */
+
+/**** 3G: Gina3G, Layla3G ****/
+#elif defined(ECHO3G_FAMILY)
+
+#define DSP_56361
+#define READ_DSP_TIMEOUT 	100000L		/* .1 second */
+#define MIN_MTC_1X_RATE		32000
+
+/**** Indigo: Indigo, Indigo IO, Indigo DJ ****/
+#elif defined(INDIGO_FAMILY)
+
+#define DSP_56361
+#define READ_DSP_TIMEOUT	100000L		/* .1 second */
+
+#else
+
+#error No family is defined
+
+#endif
+
+
+
+/*
+ *
+ *  Max inputs and outputs
+ *
+ */
+
+#define DSP_MAXAUDIOINPUTS		16	/* Max audio input channels */
+#define DSP_MAXAUDIOOUTPUTS		16	/* Max audio output channels */
+#define DSP_MAXPIPES			32	/* Max total pipes (input + output) */
+
+
+/*
+ *
+ * These are the offsets for the memory-mapped DSP registers; the DSP base
+ * address is treated as the start of a u32 array.
+ */
+
+#define CHI32_CONTROL_REG		4
+#define CHI32_STATUS_REG		5
+#define CHI32_VECTOR_REG		6
+#define CHI32_DATA_REG			7
+
+
+/*
+ *
+ * Interesting bits within the DSP registers
+ *
+ */
+
+#define CHI32_VECTOR_BUSY		0x00000001
+#define CHI32_STATUS_REG_HF3		0x00000008
+#define CHI32_STATUS_REG_HF4		0x00000010
+#define CHI32_STATUS_REG_HF5		0x00000020
+#define CHI32_STATUS_HOST_READ_FULL	0x00000004
+#define CHI32_STATUS_HOST_WRITE_EMPTY	0x00000002
+#define CHI32_STATUS_IRQ		0x00000040
+
+
+/* 
+ *
+ * DSP commands sent via slave mode; these are sent to the DSP by write_dsp()
+ *
+ */
+
+#define DSP_FNC_SET_COMMPAGE_ADDR		0x02
+#define DSP_FNC_LOAD_LAYLA_ASIC			0xa0
+#define DSP_FNC_LOAD_GINA24_ASIC		0xa0
+#define DSP_FNC_LOAD_MONA_PCI_CARD_ASIC		0xa0
+#define DSP_FNC_LOAD_LAYLA24_PCI_CARD_ASIC	0xa0
+#define DSP_FNC_LOAD_MONA_EXTERNAL_ASIC		0xa1
+#define DSP_FNC_LOAD_LAYLA24_EXTERNAL_ASIC	0xa1
+#define DSP_FNC_LOAD_3G_ASIC			0xa0
+
+
+/*
+ *
+ * Defines to handle the MIDI input state engine; these are used to properly
+ * extract MIDI time code bytes and their timestamps from the MIDI input stream.
+ *
+ */
+
+#define MIDI_IN_STATE_NORMAL	0
+#define MIDI_IN_STATE_TS_HIGH	1
+#define MIDI_IN_STATE_TS_LOW	2
+#define MIDI_IN_STATE_F1_DATA 	3
+#define MIDI_IN_SKIP_DATA	(-1)
+
+
+/*----------------------------------------------------------------------------
+
+Setting the sample rates on Layla24 is somewhat schizophrenic.
+
+For standard rates, it works exactly like Mona and Gina24.  That is, for
+8, 11.025, 16, 22.05, 32, 44.1, 48, 88.2, and 96 kHz, you just set the
+appropriate bits in the control register and write the control register.
+
+In order to support MIDI time code sync (and possibly SMPTE LTC sync in
+the future), Layla24 also has "continuous sample rate mode".  In this mode,
+Layla24 can generate any sample rate between 25 and 50 kHz inclusive, or
+50 to 100 kHz inclusive for double speed mode.
+
+To use continuous mode:
+
+-Set the clock select bits in the control register to 0xe (see the #define
+ below)
+
+-Set double-speed mode if you want to use sample rates above 50 kHz
+
+-Write the control register as you would normally
+
+-Now, you need to set the frequency register. First, you need to determine the
+ value for the frequency register.  This is given by the following formula:
+
+frequency_reg = (LAYLA24_MAGIC_NUMBER / sample_rate) - 2
+
+Note the #define below for the magic number
+
+-Wait for the DSP handshake
+-Write the frequency_reg value to the .SampleRate field of the comm page
+-Send the vector command SET_LAYLA24_FREQUENCY_REG (see vmonkey.h)
+
+Once you have set the control register up for continuous mode, you can just
+write the frequency register to change the sample rate.  This could be
+used for MIDI time code sync. For MTC sync, the control register is set for
+continuous mode.  The driver then just keeps writing the
+SET_LAYLA24_FREQUENCY_REG command.
+
+-----------------------------------------------------------------------------*/
+
+#define LAYLA24_MAGIC_NUMBER			677376000
+#define LAYLA24_CONTINUOUS_CLOCK		0x000e
+
+
+/*
+ *
+ * DSP vector commands
+ *
+ */
+
+#define DSP_VC_RESET				0x80ff
+
+#ifndef DSP_56361
+
+#define DSP_VC_ACK_INT				0x8073
+#define DSP_VC_SET_VMIXER_GAIN			0x0000	/* Not used, only for compile */
+#define DSP_VC_START_TRANSFER			0x0075	/* Handshke rqd. */
+#define DSP_VC_METERS_ON			0x0079
+#define DSP_VC_METERS_OFF			0x007b
+#define DSP_VC_UPDATE_OUTVOL			0x007d	/* Handshke rqd. */
+#define DSP_VC_UPDATE_INGAIN			0x007f	/* Handshke rqd. */
+#define DSP_VC_ADD_AUDIO_BUFFER			0x0081	/* Handshke rqd. */
+#define DSP_VC_TEST_ASIC			0x00eb
+#define DSP_VC_UPDATE_CLOCKS			0x00ef	/* Handshke rqd. */
+#define DSP_VC_SET_LAYLA_SAMPLE_RATE		0x00f1	/* Handshke rqd. */
+#define DSP_VC_SET_GD_AUDIO_STATE		0x00f1	/* Handshke rqd. */
+#define DSP_VC_WRITE_CONTROL_REG		0x00f1	/* Handshke rqd. */
+#define DSP_VC_MIDI_WRITE			0x00f5	/* Handshke rqd. */
+#define DSP_VC_STOP_TRANSFER			0x00f7	/* Handshke rqd. */
+#define DSP_VC_UPDATE_FLAGS			0x00fd	/* Handshke rqd. */
+#define DSP_VC_GO_COMATOSE			0x00f9
+
+#else /* !DSP_56361 */
+
+/* Vector commands for families that use either the 56301 or 56361 */
+#define DSP_VC_ACK_INT				0x80F5
+#define DSP_VC_SET_VMIXER_GAIN			0x00DB	/* Handshke rqd. */
+#define DSP_VC_START_TRANSFER			0x00DD	/* Handshke rqd. */
+#define DSP_VC_METERS_ON			0x00EF
+#define DSP_VC_METERS_OFF			0x00F1
+#define DSP_VC_UPDATE_OUTVOL			0x00E3	/* Handshke rqd. */
+#define DSP_VC_UPDATE_INGAIN			0x00E5	/* Handshke rqd. */
+#define DSP_VC_ADD_AUDIO_BUFFER			0x00E1	/* Handshke rqd. */
+#define DSP_VC_TEST_ASIC			0x00ED
+#define DSP_VC_UPDATE_CLOCKS			0x00E9	/* Handshke rqd. */
+#define DSP_VC_SET_LAYLA24_FREQUENCY_REG	0x00E9	/* Handshke rqd. */
+#define DSP_VC_SET_LAYLA_SAMPLE_RATE		0x00EB	/* Handshke rqd. */
+#define DSP_VC_SET_GD_AUDIO_STATE		0x00EB	/* Handshke rqd. */
+#define DSP_VC_WRITE_CONTROL_REG		0x00EB	/* Handshke rqd. */
+#define DSP_VC_MIDI_WRITE			0x00E7	/* Handshke rqd. */
+#define DSP_VC_STOP_TRANSFER			0x00DF	/* Handshke rqd. */
+#define DSP_VC_UPDATE_FLAGS			0x00FB	/* Handshke rqd. */
+#define DSP_VC_GO_COMATOSE			0x00d9
+
+#endif /* !DSP_56361 */
+
+
+/*
+ *
+ * Timeouts
+ *
+ */
+
+#define HANDSHAKE_TIMEOUT		20000	/* send_vector command timeout (20ms) */
+#define VECTOR_BUSY_TIMEOUT		100000	/* 100ms */
+#define MIDI_OUT_DELAY_USEC		2000	/* How long to wait after MIDI fills up */
+
+
+/*
+ *
+ * Flags for .Flags field in the comm page
+ *
+ */
+
+#define DSP_FLAG_MIDI_INPUT		0x0001	/* Enable MIDI input */
+#define DSP_FLAG_SPDIF_NONAUDIO		0x0002	/* Sets the "non-audio" bit
+						 * in the S/PDIF out status
+						 * bits.  Clear this flag for
+						 * audio data;
+						 * set it for AC3 or WMA or
+						 * some such */
+#define DSP_FLAG_PROFESSIONAL_SPDIF	0x0008	/* 1 Professional, 0 Consumer */
+
+
+/*
+ *
+ * Clock detect bits reported by the DSP for Gina20, Layla20, Darla24, and Mia
+ *
+ */
+
+#define GLDM_CLOCK_DETECT_BIT_WORD	0x0002
+#define GLDM_CLOCK_DETECT_BIT_SUPER	0x0004
+#define GLDM_CLOCK_DETECT_BIT_SPDIF	0x0008
+#define GLDM_CLOCK_DETECT_BIT_ESYNC	0x0010
+
+
+/*
+ *
+ * Clock detect bits reported by the DSP for Gina24, Mona, and Layla24
+ *
+ */
+
+#define GML_CLOCK_DETECT_BIT_WORD96	0x0002
+#define GML_CLOCK_DETECT_BIT_WORD48	0x0004
+#define GML_CLOCK_DETECT_BIT_SPDIF48	0x0008
+#define GML_CLOCK_DETECT_BIT_SPDIF96	0x0010
+#define GML_CLOCK_DETECT_BIT_WORD	(GML_CLOCK_DETECT_BIT_WORD96 | GML_CLOCK_DETECT_BIT_WORD48)
+#define GML_CLOCK_DETECT_BIT_SPDIF	(GML_CLOCK_DETECT_BIT_SPDIF48 | GML_CLOCK_DETECT_BIT_SPDIF96)
+#define GML_CLOCK_DETECT_BIT_ESYNC	0x0020
+#define GML_CLOCK_DETECT_BIT_ADAT	0x0040
+
+
+/*
+ *
+ * Layla clock numbers to send to DSP
+ *
+ */
+
+#define LAYLA20_CLOCK_INTERNAL		0
+#define LAYLA20_CLOCK_SPDIF		1
+#define LAYLA20_CLOCK_WORD		2
+#define LAYLA20_CLOCK_SUPER		3
+
+
+/*
+ *
+ * Gina/Darla clock states
+ *
+ */
+
+#define GD_CLOCK_NOCHANGE		0
+#define GD_CLOCK_44			1
+#define GD_CLOCK_48			2
+#define GD_CLOCK_SPDIFIN		3
+#define GD_CLOCK_UNDEF			0xff
+
+
+/*
+ *
+ * Gina/Darla S/PDIF status bits
+ *
+ */
+
+#define GD_SPDIF_STATUS_NOCHANGE	0
+#define GD_SPDIF_STATUS_44		1
+#define GD_SPDIF_STATUS_48		2
+#define GD_SPDIF_STATUS_UNDEF		0xff
+
+
+/*
+ *
+ * Layla20 output clocks
+ *
+ */
+
+#define LAYLA20_OUTPUT_CLOCK_SUPER	0
+#define LAYLA20_OUTPUT_CLOCK_WORD	1
+
+
+/****************************************************************************
+
+   Magic constants for the Darla24 hardware
+
+ ****************************************************************************/
+
+#define GD24_96000	0x0
+#define GD24_48000	0x1
+#define GD24_44100	0x2
+#define GD24_32000	0x3
+#define GD24_22050	0x4
+#define GD24_16000	0x5
+#define GD24_11025	0x6
+#define GD24_8000	0x7
+#define GD24_88200	0x8
+#define GD24_EXT_SYNC	0x9
+
+
+/*
+ *
+ * Return values from the DSP when ASIC is loaded
+ *
+ */
+
+#define ASIC_ALREADY_LOADED	0x1
+#define ASIC_NOT_LOADED		0x0
+
+
+/*
+ *
+ * DSP Audio formats
+ *
+ * These are the audio formats that the DSP can transfer
+ * via input and output pipes.  LE means little-endian,
+ * BE means big-endian.
+ *
+ * DSP_AUDIOFORM_MS_8   
+ *
+ *    8-bit mono unsigned samples.  For playback,
+ *    mono data is duplicated out the left and right channels
+ *    of the output bus.  The "MS" part of the name
+ *    means mono->stereo.
+ *
+ * DSP_AUDIOFORM_MS_16LE
+ *
+ *    16-bit signed little-endian mono samples.  Playback works
+ *    like the previous code.
+ *
+ * DSP_AUDIOFORM_MS_24LE
+ *
+ *    24-bit signed little-endian mono samples.  Data is packed
+ *    three bytes per sample; if you had two samples 0x112233 and 0x445566
+ *    they would be stored in memory like this: 33 22 11 66 55 44.
+ *
+ * DSP_AUDIOFORM_MS_32LE
+ * 
+ *    24-bit signed little-endian mono samples in a 32-bit 
+ *    container.  In other words, each sample is a 32-bit signed 
+ *    integer, where the actual audio data is left-justified 
+ *    in the 32 bits and only the 24 most significant bits are valid.
+ *
+ * DSP_AUDIOFORM_SS_8
+ * DSP_AUDIOFORM_SS_16LE
+ * DSP_AUDIOFORM_SS_24LE
+ * DSP_AUDIOFORM_SS_32LE
+ *
+ *    Like the previous ones, except now with stereo interleaved
+ *    data.  "SS" means stereo->stereo.
+ *
+ * DSP_AUDIOFORM_MM_32LE
+ *
+ *    Similar to DSP_AUDIOFORM_MS_32LE, except that the mono
+ *    data is not duplicated out both the left and right outputs.
+ *    This mode is used by the ASIO driver.  Here, "MM" means
+ *    mono->mono.
+ *
+ * DSP_AUDIOFORM_MM_32BE
+ *
+ *    Just like DSP_AUDIOFORM_MM_32LE, but now the data is
+ *    in big-endian format.
+ *
+ */
+
+#define DSP_AUDIOFORM_MS_8	0	/* 8 bit mono */
+#define DSP_AUDIOFORM_MS_16LE	1	/* 16 bit mono */
+#define DSP_AUDIOFORM_MS_24LE	2	/* 24 bit mono */
+#define DSP_AUDIOFORM_MS_32LE	3	/* 32 bit mono */
+#define DSP_AUDIOFORM_SS_8	4	/* 8 bit stereo */
+#define DSP_AUDIOFORM_SS_16LE	5	/* 16 bit stereo */
+#define DSP_AUDIOFORM_SS_24LE	6	/* 24 bit stereo */
+#define DSP_AUDIOFORM_SS_32LE	7	/* 32 bit stereo */
+#define DSP_AUDIOFORM_MM_32LE	8	/* 32 bit mono->mono little-endian */
+#define DSP_AUDIOFORM_MM_32BE	9	/* 32 bit mono->mono big-endian */
+#define DSP_AUDIOFORM_SS_32BE	10	/* 32 bit stereo big endian */
+#define DSP_AUDIOFORM_INVALID	0xFF	/* Invalid audio format */
+
+
+/*
+ *
+ * Super-interleave is defined as interleaving by 4 or more.  Darla20 and Gina20
+ * do not support super interleave.
+ *
+ * 16 bit, 24 bit, and 32 bit little endian samples are supported for super 
+ * interleave.  The interleave factor must be even.  16 - way interleave is the 
+ * current maximum, so you can interleave by 4, 6, 8, 10, 12, 14, and 16.
+ *
+ * The actual format code is derived by taking the define below and or-ing with
+ * the interleave factor.  So, 32 bit interleave by 6 is 0x86 and
+ * 16 bit interleave by 16 is (0x40 | 0x10) = 0x50.
+ *
+ */
+
+#define DSP_AUDIOFORM_SUPER_INTERLEAVE_16LE	0x40
+#define DSP_AUDIOFORM_SUPER_INTERLEAVE_24LE	0xc0
+#define DSP_AUDIOFORM_SUPER_INTERLEAVE_32LE	0x80
+
+
+/*
+ *
+ * Gina24, Mona, and Layla24 control register defines
+ *
+ */
+
+#define GML_CONVERTER_ENABLE	0x0010
+#define GML_SPDIF_PRO_MODE	0x0020	/* Professional S/PDIF == 1,
+					   consumer == 0 */
+#define GML_SPDIF_SAMPLE_RATE0	0x0040
+#define GML_SPDIF_SAMPLE_RATE1	0x0080
+#define GML_SPDIF_TWO_CHANNEL	0x0100	/* 1 == two channels,
+					   0 == one channel */
+#define GML_SPDIF_NOT_AUDIO	0x0200
+#define GML_SPDIF_COPY_PERMIT	0x0400
+#define GML_SPDIF_24_BIT	0x0800	/* 1 == 24 bit, 0 == 20 bit */
+#define GML_ADAT_MODE		0x1000	/* 1 == ADAT mode, 0 == S/PDIF mode */
+#define GML_SPDIF_OPTICAL_MODE	0x2000	/* 1 == optical mode, 0 == RCA mode */
+#define GML_SPDIF_CDROM_MODE	0x3000	/* 1 == CDROM mode,
+					 * 0 == RCA or optical mode */
+#define GML_DOUBLE_SPEED_MODE	0x4000	/* 1 == double speed,
+					   0 == single speed */
+
+#define GML_DIGITAL_IN_AUTO_MUTE 0x800000
+
+#define GML_96KHZ		(0x0 | GML_DOUBLE_SPEED_MODE)
+#define GML_88KHZ		(0x1 | GML_DOUBLE_SPEED_MODE)
+#define GML_48KHZ		0x2
+#define GML_44KHZ		0x3
+#define GML_32KHZ		0x4
+#define GML_22KHZ		0x5
+#define GML_16KHZ		0x6
+#define GML_11KHZ		0x7
+#define GML_8KHZ		0x8
+#define GML_SPDIF_CLOCK		0x9
+#define GML_ADAT_CLOCK		0xA
+#define GML_WORD_CLOCK		0xB
+#define GML_ESYNC_CLOCK		0xC
+#define GML_ESYNCx2_CLOCK	0xD
+
+#define GML_CLOCK_CLEAR_MASK		0xffffbff0
+#define GML_SPDIF_RATE_CLEAR_MASK	(~(GML_SPDIF_SAMPLE_RATE0|GML_SPDIF_SAMPLE_RATE1))
+#define GML_DIGITAL_MODE_CLEAR_MASK	0xffffcfff
+#define GML_SPDIF_FORMAT_CLEAR_MASK	0xfffff01f
+
+
+/*
+ *
+ * Mia sample rate and clock setting constants
+ *
+ */
+
+#define MIA_32000	0x0040
+#define MIA_44100	0x0042
+#define MIA_48000	0x0041
+#define MIA_88200	0x0142
+#define MIA_96000	0x0141
+
+#define MIA_SPDIF	0x00000044
+#define MIA_SPDIF96	0x00000144
+
+#define MIA_MIDI_REV	1	/* Must be Mia rev 1 for MIDI support */
+
+
+/*
+ *
+ * 3G register bits
+ *
+ */
+
+#define E3G_CONVERTER_ENABLE	0x0010
+#define E3G_SPDIF_PRO_MODE	0x0020	/* Professional S/PDIF == 1,
+					   consumer == 0 */
+#define E3G_SPDIF_SAMPLE_RATE0	0x0040
+#define E3G_SPDIF_SAMPLE_RATE1	0x0080
+#define E3G_SPDIF_TWO_CHANNEL	0x0100	/* 1 == two channels,
+					   0 == one channel */
+#define E3G_SPDIF_NOT_AUDIO	0x0200
+#define E3G_SPDIF_COPY_PERMIT	0x0400
+#define E3G_SPDIF_24_BIT	0x0800	/* 1 == 24 bit, 0 == 20 bit */
+#define E3G_DOUBLE_SPEED_MODE	0x4000	/* 1 == double speed,
+					   0 == single speed */
+#define E3G_PHANTOM_POWER	0x8000	/* 1 == phantom power on,
+					   0 == phantom power off */
+
+#define E3G_96KHZ		(0x0 | E3G_DOUBLE_SPEED_MODE)
+#define E3G_88KHZ		(0x1 | E3G_DOUBLE_SPEED_MODE)
+#define E3G_48KHZ		0x2
+#define E3G_44KHZ		0x3
+#define E3G_32KHZ		0x4
+#define E3G_22KHZ		0x5
+#define E3G_16KHZ		0x6
+#define E3G_11KHZ		0x7
+#define E3G_8KHZ		0x8
+#define E3G_SPDIF_CLOCK		0x9
+#define E3G_ADAT_CLOCK		0xA
+#define E3G_WORD_CLOCK		0xB
+#define E3G_CONTINUOUS_CLOCK	0xE
+
+#define E3G_ADAT_MODE		0x1000
+#define E3G_SPDIF_OPTICAL_MODE	0x2000
+
+#define E3G_CLOCK_CLEAR_MASK		0xbfffbff0
+#define E3G_DIGITAL_MODE_CLEAR_MASK	0xffffcfff
+#define E3G_SPDIF_FORMAT_CLEAR_MASK	0xfffff01f
+
+/* Clock detect bits reported by the DSP */
+#define E3G_CLOCK_DETECT_BIT_WORD96	0x0001
+#define E3G_CLOCK_DETECT_BIT_WORD48	0x0002
+#define E3G_CLOCK_DETECT_BIT_SPDIF48	0x0004
+#define E3G_CLOCK_DETECT_BIT_ADAT	0x0004
+#define E3G_CLOCK_DETECT_BIT_SPDIF96	0x0008
+#define E3G_CLOCK_DETECT_BIT_WORD	(E3G_CLOCK_DETECT_BIT_WORD96|E3G_CLOCK_DETECT_BIT_WORD48)
+#define E3G_CLOCK_DETECT_BIT_SPDIF	(E3G_CLOCK_DETECT_BIT_SPDIF48|E3G_CLOCK_DETECT_BIT_SPDIF96)
+
+/* Frequency control register */
+#define E3G_MAGIC_NUMBER		677376000
+#define E3G_FREQ_REG_DEFAULT		(E3G_MAGIC_NUMBER / 48000 - 2)
+#define E3G_FREQ_REG_MAX		0xffff
+
+/* 3G external box types */
+#define E3G_GINA3G_BOX_TYPE		0x00
+#define E3G_LAYLA3G_BOX_TYPE		0x10
+#define E3G_ASIC_NOT_LOADED		0xffff
+#define E3G_BOX_TYPE_MASK		0xf0
+
+#define EXT_3GBOX_NC			0x01
+#define EXT_3GBOX_NOT_SET		0x02
+
+
+/*
+ *
+ * Gina20 & Layla20 have input gain controls for the analog inputs;
+ * this is the magic number for the hardware that gives you 0 dB at -10.
+ *
+ */
+
+#define GL20_INPUT_GAIN_MAGIC_NUMBER	0xC8
+
+
+/*
+ *
+ * Defines how much time must pass between DSP load attempts
+ *
+ */
+
+#define DSP_LOAD_ATTEMPT_PERIOD		1000000L	/* One second */
+
+
+/*
+ *
+ * Size of arrays for the comm page.  MAX_PLAY_TAPS and MAX_REC_TAPS are
+ * no longer used, but the sizes must still be right for the DSP to see
+ * the comm page correctly.
+ *
+ */
+
+#define MONITOR_ARRAY_SIZE	0x180
+#define VMIXER_ARRAY_SIZE	0x40
+#define MIDI_OUT_BUFFER_SIZE	32
+#define MIDI_IN_BUFFER_SIZE	256
+#define MAX_PLAY_TAPS		168
+#define MAX_REC_TAPS		192
+#define DSP_MIDI_OUT_FIFO_SIZE	64
+
+
+/* sg_entry is a single entry for the scatter-gather list.  The array of struct
+sg_entry struct is read by the DSP, so all values must be little-endian. */
+
+#define MAX_SGLIST_ENTRIES 512
+
+struct sg_entry {
+	u32 addr;
+	u32 size;
+};
+
+
+/****************************************************************************
+
+  The comm page.  This structure is read and written by the DSP; the
+  DSP code is a firm believer in the byte offsets written in the comments
+  at the end of each line.  This structure should not be changed.
+
+  Any reads from or writes to this structure should be in little-endian format.
+
+ ****************************************************************************/
+
+struct comm_page {		/*				Base	Length*/
+	u32 comm_size;		/* size of this object		0x000	4 */
+	u32 flags;		/* See Appendix A below		0x004	4 */
+	u32 unused;		/* Unused entry			0x008	4 */
+	u32 sample_rate;	/* Card sample rate in Hz	0x00c	4 */
+	volatile u32 handshake;	/* DSP command handshake	0x010	4 */
+	u32 cmd_start;		/* Chs. to start mask		0x014	4 */
+	u32 cmd_stop;		/* Chs. to stop mask		0x018	4 */
+	u32 cmd_reset;		/* Chs. to reset mask		0x01c	4 */
+	u16 audio_format[DSP_MAXPIPES];	/* Chs. audio format	0x020	32*2 */
+	struct sg_entry sglist_addr[DSP_MAXPIPES];
+				/* Chs. Physical sglist addrs	0x060	32*8 */
+	volatile u32 position[DSP_MAXPIPES];
+				/* Positions for ea. ch.	0x160	32*4 */
+	volatile s8 vu_meter[DSP_MAXPIPES];
+				/* VU meters			0x1e0	32*1 */
+	volatile s8 peak_meter[DSP_MAXPIPES];
+				/* Peak meters			0x200	32*1 */
+	s8 line_out_level[DSP_MAXAUDIOOUTPUTS];
+				/* Output gain			0x220	16*1 */
+	s8 line_in_level[DSP_MAXAUDIOINPUTS];
+				/* Input gain			0x230	16*1 */
+	s8 monitors[MONITOR_ARRAY_SIZE];
+				/* Monitor map			0x240	0x180 */
+	u32 play_coeff[MAX_PLAY_TAPS];
+			/* Gina/Darla play filters - obsolete	0x3c0	168*4 */
+	u32 rec_coeff[MAX_REC_TAPS];
+			/* Gina/Darla record filters - obsolete	0x660	192*4 */
+	volatile u16 midi_input[MIDI_IN_BUFFER_SIZE];
+			/* MIDI input data transfer buffer	0x960	256*2 */
+	u8 gd_clock_state;	/* Chg Gina/Darla clock state	0xb60	1 */
+	u8 gd_spdif_status;	/* Chg. Gina/Darla S/PDIF state	0xb61	1 */
+	u8 gd_resampler_state;	/* Should always be 3		0xb62	1 */
+	u8 filler2;		/*				0xb63	1 */
+	u32 nominal_level_mask;	/* -10 level enable mask	0xb64	4 */
+	u16 input_clock;	/* Chg. Input clock state	0xb68	2 */
+	u16 output_clock;	/* Chg. Output clock state	0xb6a	2 */
+	volatile u32 status_clocks;
+				/* Current Input clock state	0xb6c	4 */
+	u32 ext_box_status;	/* External box status		0xb70	4 */
+	u32 cmd_add_buffer;	/* Pipes to add (obsolete)	0xb74	4 */
+	volatile u32 midi_out_free_count;
+			/* # of bytes free in MIDI output FIFO	0xb78	4 */
+	u32 unused2;		/* Cyclic pipes			0xb7c	4 */
+	u32 control_register;
+			/* Mona, Gina24, Layla24, 3G ctrl reg	0xb80	4 */
+	u32 e3g_frq_register;	/* 3G frequency register	0xb84	4 */
+	u8 filler[24];		/* filler			0xb88	24*1 */
+	s8 vmixer[VMIXER_ARRAY_SIZE];
+				/* Vmixer levels		0xba0	64*1 */
+	u8 midi_output[MIDI_OUT_BUFFER_SIZE];
+				/* MIDI output data		0xbe0	32*1 */
+};
+
+#endif /* _ECHO_DSP_ */
diff --git a/sound/pci/echoaudio/echoaudio_gml.c b/sound/pci/echoaudio/echoaudio_gml.c
new file mode 100644
index 000000000..3aa37e76e
--- /dev/null
+++ b/sound/pci/echoaudio/echoaudio_gml.c
@@ -0,0 +1,198 @@
+/****************************************************************************
+
+   Copyright Echo Digital Audio Corporation (c) 1998 - 2004
+   All rights reserved
+   www.echoaudio.com
+
+   This file is part of Echo Digital Audio's generic driver library.
+
+   Echo Digital Audio's generic driver library 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.
+
+   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.
+
+   *************************************************************************
+
+ Translation from C++ and adaptation for use in ALSA-Driver
+ were made by Giuliano Pochini <pochini@shiny.it>
+
+****************************************************************************/
+
+
+/* These functions are common for Gina24, Layla24 and Mona cards */
+
+
+/* ASIC status check - some cards have one or two ASICs that need to be
+loaded.  Once that load is complete, this function is called to see if
+the load was successful.
+If this load fails, it does not necessarily mean that the hardware is
+defective - the external box may be disconnected or turned off. */
+static int check_asic_status(struct echoaudio *chip)
+{
+	u32 asic_status;
+
+	send_vector(chip, DSP_VC_TEST_ASIC);
+
+	/* The DSP will return a value to indicate whether or not the
+	   ASIC is currently loaded */
+	if (read_dsp(chip, &asic_status) < 0) {
+		DE_INIT(("check_asic_status: failed on read_dsp\n"));
+		chip->asic_loaded = FALSE;
+		return -EIO;
+	}
+
+	chip->asic_loaded = (asic_status == ASIC_ALREADY_LOADED);
+	return chip->asic_loaded ? 0 : -EIO;
+}
+
+
+
+/* Most configuration of Gina24, Layla24, or Mona is accomplished by writing
+the control register.  write_control_reg sends the new control register
+value to the DSP. */
+static int write_control_reg(struct echoaudio *chip, u32 value, char force)
+{
+	/* Handle the digital input auto-mute */
+	if (chip->digital_in_automute)
+		value |= GML_DIGITAL_IN_AUTO_MUTE;
+	else
+		value &= ~GML_DIGITAL_IN_AUTO_MUTE;
+
+	DE_ACT(("write_control_reg: 0x%x\n", value));
+
+	/* Write the control register */
+	value = cpu_to_le32(value);
+	if (value != chip->comm_page->control_register || force) {
+		if (wait_handshake(chip))
+			return -EIO;
+		chip->comm_page->control_register = value;
+		clear_handshake(chip);
+		return send_vector(chip, DSP_VC_WRITE_CONTROL_REG);
+	}
+	return 0;
+}
+
+
+
+/* Gina24, Layla24, and Mona support digital input auto-mute.  If the digital
+input auto-mute is enabled, the DSP will only enable the digital inputs if
+the card is syncing to a valid clock on the ADAT or S/PDIF inputs.
+If the auto-mute is disabled, the digital inputs are enabled regardless of
+what the input clock is set or what is connected. */
+static int set_input_auto_mute(struct echoaudio *chip, int automute)
+{
+	DE_ACT(("set_input_auto_mute %d\n", automute));
+
+	chip->digital_in_automute = automute;
+
+	/* Re-set the input clock to the current value - indirectly causes
+	the auto-mute flag to be sent to the DSP */
+	return set_input_clock(chip, chip->input_clock);
+}
+
+
+
+/* S/PDIF coax / S/PDIF optical / ADAT - switch */
+static int set_digital_mode(struct echoaudio *chip, u8 mode)
+{
+	u8 previous_mode;
+	int err, i, o;
+
+	if (chip->bad_board)
+		return -EIO;
+
+	/* All audio channels must be closed before changing the digital mode */
+	snd_assert(!chip->pipe_alloc_mask, return -EAGAIN);
+
+	snd_assert(chip->digital_modes & (1 << mode), return -EINVAL);
+
+	previous_mode = chip->digital_mode;
+	err = dsp_set_digital_mode(chip, mode);
+
+	/* If we successfully changed the digital mode from or to ADAT,
+	   then make sure all output, input and monitor levels are
+	   updated by the DSP comm object. */
+	if (err >= 0 && previous_mode != mode &&
+	    (previous_mode == DIGITAL_MODE_ADAT || mode == DIGITAL_MODE_ADAT)) {
+		spin_lock_irq(&chip->lock);
+		for (o = 0; o < num_busses_out(chip); o++)
+			for (i = 0; i < num_busses_in(chip); i++)
+				set_monitor_gain(chip, o, i,
+						 chip->monitor_gain[o][i]);
+
+#ifdef ECHOCARD_HAS_INPUT_GAIN
+		for (i = 0; i < num_busses_in(chip); i++)
+			set_input_gain(chip, i, chip->input_gain[i]);
+		update_input_line_level(chip);
+#endif
+
+		for (o = 0; o < num_busses_out(chip); o++)
+			set_output_gain(chip, o, chip->output_gain[o]);
+		update_output_line_level(chip);
+		spin_unlock_irq(&chip->lock);
+	}
+
+	return err;
+}
+
+
+
+/* Set the S/PDIF output format */
+static int set_professional_spdif(struct echoaudio *chip, char prof)
+{
+	u32 control_reg;
+	int err;
+
+	/* Clear the current S/PDIF flags */
+	control_reg = le32_to_cpu(chip->comm_page->control_register);
+	control_reg &= GML_SPDIF_FORMAT_CLEAR_MASK;
+
+	/* Set the new S/PDIF flags depending on the mode */
+	control_reg |= GML_SPDIF_TWO_CHANNEL | GML_SPDIF_24_BIT |
+		GML_SPDIF_COPY_PERMIT;
+	if (prof) {
+		/* Professional mode */
+		control_reg |= GML_SPDIF_PRO_MODE;
+
+		switch (chip->sample_rate) {
+		case 32000:
+			control_reg |= GML_SPDIF_SAMPLE_RATE0 |
+				GML_SPDIF_SAMPLE_RATE1;
+			break;
+		case 44100:
+			control_reg |= GML_SPDIF_SAMPLE_RATE0;
+			break;
+		case 48000:
+			control_reg |= GML_SPDIF_SAMPLE_RATE1;
+			break;
+		}
+	} else {
+		/* Consumer mode */
+		switch (chip->sample_rate) {
+		case 32000:
+			control_reg |= GML_SPDIF_SAMPLE_RATE0 |
+				GML_SPDIF_SAMPLE_RATE1;
+			break;
+		case 48000:
+			control_reg |= GML_SPDIF_SAMPLE_RATE1;
+			break;
+		}
+	}
+
+	if ((err = write_control_reg(chip, control_reg, FALSE)))
+		return err;
+	chip->professional_spdif = prof;
+	DE_ACT(("set_professional_spdif to %s\n",
+		prof ? "Professional" : "Consumer"));
+	return 0;
+}
diff --git a/sound/pci/echoaudio/gina20.c b/sound/pci/echoaudio/gina20.c
new file mode 100644
index 000000000..29d6d12f8
--- /dev/null
+++ b/sound/pci/echoaudio/gina20.c
@@ -0,0 +1,103 @@
+/*
+ *  ALSA driver for Echoaudio soundcards.
+ *  Copyright (C) 2003-2004 Giuliano Pochini <pochini@shiny.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; 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.
+ */
+
+#define ECHOGALS_FAMILY
+#define ECHOCARD_GINA20
+#define ECHOCARD_NAME "Gina20"
+#define ECHOCARD_HAS_MONITOR
+#define ECHOCARD_HAS_INPUT_GAIN
+#define ECHOCARD_HAS_DIGITAL_IO
+#define ECHOCARD_HAS_EXTERNAL_CLOCK
+#define ECHOCARD_HAS_ADAT	FALSE
+
+/* Pipe indexes */
+#define PX_ANALOG_OUT	0	/* 8 */
+#define PX_DIGITAL_OUT	8	/* 2 */
+#define PX_ANALOG_IN	10	/* 2 */
+#define PX_DIGITAL_IN	12	/* 2 */
+#define PX_NUM		14
+
+/* Bus indexes */
+#define BX_ANALOG_OUT	0	/* 8 */
+#define BX_DIGITAL_OUT	8	/* 2 */
+#define BX_ANALOG_IN	10	/* 2 */
+#define BX_DIGITAL_IN	12	/* 2 */
+#define BX_NUM		14
+
+
+#include <sound/driver.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/pci.h>
+#include <linux/slab.h>
+#include <linux/moduleparam.h>
+#include <linux/firmware.h>
+#include <sound/core.h>
+#include <sound/info.h>
+#include <sound/control.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/asoundef.h>
+#include <sound/initval.h>
+#include <asm/io.h>
+#include <asm/atomic.h>
+#include "echoaudio.h"
+
+#define FW_GINA20_DSP	0
+
+static const struct firmware card_fw[] = {
+	{0, "gina20_dsp.fw"}
+};
+
+static struct pci_device_id snd_echo_ids[] = {
+	{0x1057, 0x1801, 0xECC0, 0x0020, 0, 0, 0},	/* DSP 56301 Gina20 rev.0 */
+	{0,}
+};
+
+static struct snd_pcm_hardware pcm_hardware_skel = {
+	.info = SNDRV_PCM_INFO_MMAP |
+		SNDRV_PCM_INFO_INTERLEAVED |
+		SNDRV_PCM_INFO_BLOCK_TRANSFER |
+		SNDRV_PCM_INFO_MMAP_VALID |
+		SNDRV_PCM_INFO_PAUSE |
+		SNDRV_PCM_INFO_SYNC_START,
+	.formats =	SNDRV_PCM_FMTBIT_U8 |
+			SNDRV_PCM_FMTBIT_S16_LE |
+			SNDRV_PCM_FMTBIT_S24_3LE |
+			SNDRV_PCM_FMTBIT_S32_LE |
+			SNDRV_PCM_FMTBIT_S32_BE,
+	.rates = SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000,
+	.rate_min = 44100,
+	.rate_max = 48000,
+	.channels_min = 1,
+	.channels_max = 2,
+	.buffer_bytes_max = 262144,
+	.period_bytes_min = 32,
+	.period_bytes_max = 131072,
+	.periods_min = 2,
+	.periods_max = 220,
+	/* One page (4k) contains 512 instructions. I don't know if the hw
+	supports lists longer than this. In this case periods_max=220 is a
+	safe limit to make sure the list never exceeds 512 instructions. */
+};
+
+
+#include "gina20_dsp.c"
+#include "echoaudio_dsp.c"
+#include "echoaudio.c"
diff --git a/sound/pci/echoaudio/gina20_dsp.c b/sound/pci/echoaudio/gina20_dsp.c
new file mode 100644
index 000000000..2757c8960
--- /dev/null
+++ b/sound/pci/echoaudio/gina20_dsp.c
@@ -0,0 +1,215 @@
+/****************************************************************************
+
+   Copyright Echo Digital Audio Corporation (c) 1998 - 2004
+   All rights reserved
+   www.echoaudio.com
+
+   This file is part of Echo Digital Audio's generic driver library.
+
+   Echo Digital Audio's generic driver library 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.
+
+   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.
+
+   *************************************************************************
+
+ Translation from C++ and adaptation for use in ALSA-Driver
+ were made by Giuliano Pochini <pochini@shiny.it>
+
+****************************************************************************/
+
+
+static int set_professional_spdif(struct echoaudio *chip, char prof);
+static int update_flags(struct echoaudio *chip);
+
+
+static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
+{
+	int err;
+
+	DE_INIT(("init_hw() - Gina20\n"));
+	snd_assert((subdevice_id & 0xfff0) == GINA20, return -ENODEV);
+
+	if ((err = init_dsp_comm_page(chip))) {
+		DE_INIT(("init_hw - could not initialize DSP comm page\n"));
+		return err;
+	}
+
+	chip->device_id = device_id;
+	chip->subdevice_id = subdevice_id;
+	chip->bad_board = TRUE;
+	chip->dsp_code_to_load = &card_fw[FW_GINA20_DSP];
+	chip->spdif_status = GD_SPDIF_STATUS_UNDEF;
+	chip->clock_state = GD_CLOCK_UNDEF;
+	/* Since this card has no ASIC, mark it as loaded so everything
+	   works OK */
+	chip->asic_loaded = TRUE;
+	chip->input_clock_types = ECHO_CLOCK_BIT_INTERNAL |
+		ECHO_CLOCK_BIT_SPDIF;
+
+	if ((err = load_firmware(chip)) < 0)
+		return err;
+	chip->bad_board = FALSE;
+
+	if ((err = init_line_levels(chip)) < 0)
+		return err;
+
+	err = set_professional_spdif(chip, TRUE);
+
+	DE_INIT(("init_hw done\n"));
+	return err;
+}
+
+
+
+static u32 detect_input_clocks(const struct echoaudio *chip)
+{
+	u32 clocks_from_dsp, clock_bits;
+
+	/* Map the DSP clock detect bits to the generic driver clock
+	   detect bits */
+	clocks_from_dsp = le32_to_cpu(chip->comm_page->status_clocks);
+
+	clock_bits = ECHO_CLOCK_BIT_INTERNAL;
+
+	if (clocks_from_dsp & GLDM_CLOCK_DETECT_BIT_SPDIF)
+		clock_bits |= ECHO_CLOCK_BIT_SPDIF;
+
+	return clock_bits;
+}
+
+
+
+/* The Gina20 has no ASIC. Just do nothing */
+static int load_asic(struct echoaudio *chip)
+{
+	return 0;
+}
+
+
+
+static int set_sample_rate(struct echoaudio *chip, u32 rate)
+{
+	u8 clock_state, spdif_status;
+
+	if (wait_handshake(chip))
+		return -EIO;
+
+	switch (rate) {
+	case 44100:
+		clock_state = GD_CLOCK_44;
+		spdif_status = GD_SPDIF_STATUS_44;
+		break;
+	case 48000:
+		clock_state = GD_CLOCK_48;
+		spdif_status = GD_SPDIF_STATUS_48;
+		break;
+	default:
+		clock_state = GD_CLOCK_NOCHANGE;
+		spdif_status = GD_SPDIF_STATUS_NOCHANGE;
+		break;
+	}
+
+	if (chip->clock_state == clock_state)
+		clock_state = GD_CLOCK_NOCHANGE;
+	if (spdif_status == chip->spdif_status)
+		spdif_status = GD_SPDIF_STATUS_NOCHANGE;
+
+	chip->comm_page->sample_rate = cpu_to_le32(rate);
+	chip->comm_page->gd_clock_state = clock_state;
+	chip->comm_page->gd_spdif_status = spdif_status;
+	chip->comm_page->gd_resampler_state = 3;	/* magic number - should always be 3 */
+
+	/* Save the new audio state if it changed */
+	if (clock_state != GD_CLOCK_NOCHANGE)
+		chip->clock_state = clock_state;
+	if (spdif_status != GD_SPDIF_STATUS_NOCHANGE)
+		chip->spdif_status = spdif_status;
+	chip->sample_rate = rate;
+
+	clear_handshake(chip);
+	return send_vector(chip, DSP_VC_SET_GD_AUDIO_STATE);
+}
+
+
+
+static int set_input_clock(struct echoaudio *chip, u16 clock)
+{
+	DE_ACT(("set_input_clock:\n"));
+
+	switch (clock) {
+	case ECHO_CLOCK_INTERNAL:
+		/* Reset the audio state to unknown (just in case) */
+		chip->clock_state = GD_CLOCK_UNDEF;
+		chip->spdif_status = GD_SPDIF_STATUS_UNDEF;
+		set_sample_rate(chip, chip->sample_rate);
+		chip->input_clock = clock;
+		DE_ACT(("Set Gina clock to INTERNAL\n"));
+		break;
+	case ECHO_CLOCK_SPDIF:
+		chip->comm_page->gd_clock_state = GD_CLOCK_SPDIFIN;
+		chip->comm_page->gd_spdif_status = GD_SPDIF_STATUS_NOCHANGE;
+		clear_handshake(chip);
+		send_vector(chip, DSP_VC_SET_GD_AUDIO_STATE);
+		chip->clock_state = GD_CLOCK_SPDIFIN;
+		DE_ACT(("Set Gina20 clock to SPDIF\n"));
+		chip->input_clock = clock;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+
+
+/* Set input bus gain (one unit is 0.5dB !) */
+static int set_input_gain(struct echoaudio *chip, u16 input, int gain)
+{
+	snd_assert(input < num_busses_in(chip), return -EINVAL);
+
+	if (wait_handshake(chip))
+		return -EIO;
+
+	chip->input_gain[input] = gain;
+	gain += GL20_INPUT_GAIN_MAGIC_NUMBER;
+	chip->comm_page->line_in_level[input] = gain;
+	return 0;
+}
+
+
+
+/* Tell the DSP to reread the flags from the comm page */
+static int update_flags(struct echoaudio *chip)
+{
+	if (wait_handshake(chip))
+		return -EIO;
+	clear_handshake(chip);
+	return send_vector(chip, DSP_VC_UPDATE_FLAGS);
+}
+
+
+
+static int set_professional_spdif(struct echoaudio *chip, char prof)
+{
+	DE_ACT(("set_professional_spdif %d\n", prof));
+	if (prof)
+		chip->comm_page->flags |=
+			__constant_cpu_to_le32(DSP_FLAG_PROFESSIONAL_SPDIF);
+	else
+		chip->comm_page->flags &=
+			~__constant_cpu_to_le32(DSP_FLAG_PROFESSIONAL_SPDIF);
+	chip->professional_spdif = prof;
+	return update_flags(chip);
+}
diff --git a/sound/pci/echoaudio/gina24.c b/sound/pci/echoaudio/gina24.c
new file mode 100644
index 000000000..e464d720d
--- /dev/null
+++ b/sound/pci/echoaudio/gina24.c
@@ -0,0 +1,123 @@
+/*
+ *  ALSA driver for Echoaudio soundcards.
+ *  Copyright (C) 2003-2004 Giuliano Pochini <pochini@shiny.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; 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.
+ */
+
+#define ECHO24_FAMILY
+#define ECHOCARD_GINA24
+#define ECHOCARD_NAME "Gina24"
+#define ECHOCARD_HAS_MONITOR
+#define ECHOCARD_HAS_ASIC
+#define ECHOCARD_HAS_INPUT_NOMINAL_LEVEL
+#define ECHOCARD_HAS_OUTPUT_NOMINAL_LEVEL
+#define ECHOCARD_HAS_SUPER_INTERLEAVE
+#define ECHOCARD_HAS_DIGITAL_IO
+#define ECHOCARD_HAS_DIGITAL_IN_AUTOMUTE
+#define ECHOCARD_HAS_DIGITAL_MODE_SWITCH
+#define ECHOCARD_HAS_EXTERNAL_CLOCK
+#define ECHOCARD_HAS_ADAT	6
+#define ECHOCARD_HAS_STEREO_BIG_ENDIAN32
+
+/* Pipe indexes */
+#define PX_ANALOG_OUT	0	/* 8 */
+#define PX_DIGITAL_OUT	8	/* 8 */
+#define PX_ANALOG_IN	16	/* 2 */
+#define PX_DIGITAL_IN	18	/* 8 */
+#define PX_NUM		26
+
+/* Bus indexes */
+#define BX_ANALOG_OUT	0	/* 8 */
+#define BX_DIGITAL_OUT	8	/* 8 */
+#define BX_ANALOG_IN	16	/* 2 */
+#define BX_DIGITAL_IN	18	/* 8 */
+#define BX_NUM		26
+
+
+#include <sound/driver.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/pci.h>
+#include <linux/slab.h>
+#include <linux/moduleparam.h>
+#include <linux/firmware.h>
+#include <sound/core.h>
+#include <sound/info.h>
+#include <sound/control.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/asoundef.h>
+#include <sound/initval.h>
+#include <asm/io.h>
+#include <asm/atomic.h>
+#include "echoaudio.h"
+
+#define FW_361_LOADER		0
+#define FW_GINA24_301_DSP	1
+#define FW_GINA24_361_DSP	2
+#define FW_GINA24_301_ASIC	3
+#define FW_GINA24_361_ASIC	4
+
+static const struct firmware card_fw[] = {
+	{0, "loader_dsp.fw"},
+	{0, "gina24_301_dsp.fw"},
+	{0, "gina24_361_dsp.fw"},
+	{0, "gina24_301_asic.fw"},
+	{0, "gina24_361_asic.fw"}
+};
+
+static struct pci_device_id snd_echo_ids[] = {
+	{0x1057, 0x1801, 0xECC0, 0x0050, 0, 0, 0},	/* DSP 56301 Gina24 rev.0 */
+	{0x1057, 0x1801, 0xECC0, 0x0051, 0, 0, 0},	/* DSP 56301 Gina24 rev.1 */
+	{0x1057, 0x3410, 0xECC0, 0x0050, 0, 0, 0},	/* DSP 56361 Gina24 rev.0 */
+	{0x1057, 0x3410, 0xECC0, 0x0051, 0, 0, 0},	/* DSP 56361 Gina24 rev.1 */
+	{0,}
+};
+
+static struct snd_pcm_hardware pcm_hardware_skel = {
+	.info = SNDRV_PCM_INFO_MMAP |
+		SNDRV_PCM_INFO_INTERLEAVED |
+		SNDRV_PCM_INFO_BLOCK_TRANSFER |
+		SNDRV_PCM_INFO_MMAP_VALID |
+		SNDRV_PCM_INFO_PAUSE |
+		SNDRV_PCM_INFO_SYNC_START,
+	.formats =	SNDRV_PCM_FMTBIT_U8 |
+			SNDRV_PCM_FMTBIT_S16_LE |
+			SNDRV_PCM_FMTBIT_S24_3LE |
+			SNDRV_PCM_FMTBIT_S32_LE |
+			SNDRV_PCM_FMTBIT_S32_BE,
+	.rates = 	SNDRV_PCM_RATE_8000_48000 |
+			SNDRV_PCM_RATE_88200 |
+			SNDRV_PCM_RATE_96000,
+	.rate_min = 8000,
+	.rate_max = 96000,
+	.channels_min = 1,
+	.channels_max = 8,
+	.buffer_bytes_max = 262144,
+	.period_bytes_min = 32,
+	.period_bytes_max = 131072,
+	.periods_min = 2,
+	.periods_max = 220,
+	/* One page (4k) contains 512 instructions. I don't know if the hw
+	supports lists longer than this. In this case periods_max=220 is a
+	safe limit to make sure the list never exceeds 512 instructions.
+	220 ~= (512 - 1 - (BUFFER_BYTES_MAX / PAGE_SIZE)) / 2 */
+};
+
+#include "gina24_dsp.c"
+#include "echoaudio_dsp.c"
+#include "echoaudio_gml.c"
+#include "echoaudio.c"
diff --git a/sound/pci/echoaudio/gina24_dsp.c b/sound/pci/echoaudio/gina24_dsp.c
new file mode 100644
index 000000000..144fc567b
--- /dev/null
+++ b/sound/pci/echoaudio/gina24_dsp.c
@@ -0,0 +1,346 @@
+/****************************************************************************
+
+   Copyright Echo Digital Audio Corporation (c) 1998 - 2004
+   All rights reserved
+   www.echoaudio.com
+
+   This file is part of Echo Digital Audio's generic driver library.
+
+   Echo Digital Audio's generic driver library 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.
+
+   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.
+
+   *************************************************************************
+
+ Translation from C++ and adaptation for use in ALSA-Driver
+ were made by Giuliano Pochini <pochini@shiny.it>
+
+****************************************************************************/
+
+
+static int write_control_reg(struct echoaudio *chip, u32 value, char force);
+static int set_input_clock(struct echoaudio *chip, u16 clock);
+static int set_professional_spdif(struct echoaudio *chip, char prof);
+static int set_digital_mode(struct echoaudio *chip, u8 mode);
+static int load_asic_generic(struct echoaudio *chip, u32 cmd,
+			     const struct firmware *asic);
+static int check_asic_status(struct echoaudio *chip);
+
+
+static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
+{
+	int err;
+
+	DE_INIT(("init_hw() - Gina24\n"));
+	snd_assert((subdevice_id & 0xfff0) == GINA24, return -ENODEV);
+
+	if ((err = init_dsp_comm_page(chip))) {
+		DE_INIT(("init_hw - could not initialize DSP comm page\n"));
+		return err;
+	}
+
+	chip->device_id = device_id;
+	chip->subdevice_id = subdevice_id;
+	chip->bad_board = TRUE;
+	chip->input_clock_types =
+		ECHO_CLOCK_BIT_INTERNAL | ECHO_CLOCK_BIT_SPDIF |
+		ECHO_CLOCK_BIT_ESYNC | ECHO_CLOCK_BIT_ESYNC96 |
+		ECHO_CLOCK_BIT_ADAT;
+	chip->professional_spdif = FALSE;
+	chip->digital_in_automute = TRUE;
+	chip->digital_mode = DIGITAL_MODE_SPDIF_RCA;
+
+	/* Gina24 comes in both '301 and '361 flavors */
+	if (chip->device_id == DEVICE_ID_56361) {
+		chip->dsp_code_to_load = &card_fw[FW_GINA24_361_DSP];
+		chip->digital_modes =
+			ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_RCA |
+			ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_OPTICAL |
+			ECHOCAPS_HAS_DIGITAL_MODE_ADAT;
+	} else {
+		chip->dsp_code_to_load = &card_fw[FW_GINA24_301_DSP];
+		chip->digital_modes =
+			ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_RCA |
+			ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_OPTICAL |
+			ECHOCAPS_HAS_DIGITAL_MODE_ADAT |
+			ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_CDROM;
+	}
+
+	if ((err = load_firmware(chip)) < 0)
+		return err;
+	chip->bad_board = FALSE;
+
+	if ((err = init_line_levels(chip)) < 0)
+		return err;
+	err = set_digital_mode(chip, DIGITAL_MODE_SPDIF_RCA);
+	snd_assert(err >= 0, return err);
+	err = set_professional_spdif(chip, TRUE);
+
+	DE_INIT(("init_hw done\n"));
+	return err;
+}
+
+
+
+static u32 detect_input_clocks(const struct echoaudio *chip)
+{
+	u32 clocks_from_dsp, clock_bits;
+
+	/* Map the DSP clock detect bits to the generic driver clock
+	   detect bits */
+	clocks_from_dsp = le32_to_cpu(chip->comm_page->status_clocks);
+
+	clock_bits = ECHO_CLOCK_BIT_INTERNAL;
+
+	if (clocks_from_dsp & GML_CLOCK_DETECT_BIT_SPDIF)
+		clock_bits |= ECHO_CLOCK_BIT_SPDIF;
+
+	if (clocks_from_dsp & GML_CLOCK_DETECT_BIT_ADAT)
+		clock_bits |= ECHO_CLOCK_BIT_ADAT;
+
+	if (clocks_from_dsp & GML_CLOCK_DETECT_BIT_ESYNC)
+		clock_bits |= ECHO_CLOCK_BIT_ESYNC | ECHO_CLOCK_BIT_ESYNC96;
+
+	return clock_bits;
+}
+
+
+
+/* Gina24 has an ASIC on the PCI card which must be loaded for anything
+interesting to happen. */
+static int load_asic(struct echoaudio *chip)
+{
+	u32 control_reg;
+	int err;
+	const struct firmware *fw;
+
+	if (chip->asic_loaded)
+		return 1;
+
+	/* Give the DSP a few milliseconds to settle down */
+	mdelay(10);
+
+	/* Pick the correct ASIC for '301 or '361 Gina24 */
+	if (chip->device_id == DEVICE_ID_56361)
+		fw = &card_fw[FW_GINA24_361_ASIC];
+	else
+		fw = &card_fw[FW_GINA24_301_ASIC];
+
+	if ((err = load_asic_generic(chip, DSP_FNC_LOAD_GINA24_ASIC, fw)) < 0)
+		return err;
+
+	chip->asic_code = fw;
+
+	/* Now give the new ASIC a little time to set up */
+	mdelay(10);
+	/* See if it worked */
+	err = check_asic_status(chip);
+
+	/* Set up the control register if the load succeeded -
+	   48 kHz, internal clock, S/PDIF RCA mode */
+	if (!err) {
+		control_reg = GML_CONVERTER_ENABLE | GML_48KHZ;
+		err = write_control_reg(chip, control_reg, TRUE);
+	}
+	DE_INIT(("load_asic() done\n"));
+	return err;
+}
+
+
+
+static int set_sample_rate(struct echoaudio *chip, u32 rate)
+{
+	u32 control_reg, clock;
+
+	snd_assert(rate < 50000 || chip->digital_mode != DIGITAL_MODE_ADAT,
+		   return -EINVAL);
+
+	/* Only set the clock for internal mode. */
+	if (chip->input_clock != ECHO_CLOCK_INTERNAL) {
+		DE_ACT(("set_sample_rate: Cannot set sample rate - "
+			"clock not set to CLK_CLOCKININTERNAL\n"));
+		/* Save the rate anyhow */
+		chip->comm_page->sample_rate = cpu_to_le32(rate);
+		chip->sample_rate = rate;
+		return 0;
+	}
+
+	clock = 0;
+
+	control_reg = le32_to_cpu(chip->comm_page->control_register);
+	control_reg &= GML_CLOCK_CLEAR_MASK & GML_SPDIF_RATE_CLEAR_MASK;
+
+	switch (rate) {
+	case 96000:
+		clock = GML_96KHZ;
+		break;
+	case 88200:
+		clock = GML_88KHZ;
+		break;
+	case 48000:
+		clock = GML_48KHZ | GML_SPDIF_SAMPLE_RATE1;
+		break;
+	case 44100:
+		clock = GML_44KHZ;
+		/* Professional mode ? */
+		if (control_reg & GML_SPDIF_PRO_MODE)
+			clock |= GML_SPDIF_SAMPLE_RATE0;
+		break;
+	case 32000:
+		clock = GML_32KHZ | GML_SPDIF_SAMPLE_RATE0 |
+			GML_SPDIF_SAMPLE_RATE1;
+		break;
+	case 22050:
+		clock = GML_22KHZ;
+		break;
+	case 16000:
+		clock = GML_16KHZ;
+		break;
+	case 11025:
+		clock = GML_11KHZ;
+		break;
+	case 8000:
+		clock = GML_8KHZ;
+		break;
+	default:
+		DE_ACT(("set_sample_rate: %d invalid!\n", rate));
+		return -EINVAL;
+	}
+
+	control_reg |= clock;
+
+	chip->comm_page->sample_rate = cpu_to_le32(rate);	/* ignored by the DSP */
+	chip->sample_rate = rate;
+	DE_ACT(("set_sample_rate: %d clock %d\n", rate, clock));
+
+	return write_control_reg(chip, control_reg, FALSE);
+}
+
+
+
+static int set_input_clock(struct echoaudio *chip, u16 clock)
+{
+	u32 control_reg, clocks_from_dsp;
+
+	DE_ACT(("set_input_clock:\n"));
+
+	/* Mask off the clock select bits */
+	control_reg = le32_to_cpu(chip->comm_page->control_register) &
+		GML_CLOCK_CLEAR_MASK;
+	clocks_from_dsp = le32_to_cpu(chip->comm_page->status_clocks);
+
+	switch (clock) {
+	case ECHO_CLOCK_INTERNAL:
+		DE_ACT(("Set Gina24 clock to INTERNAL\n"));
+		chip->input_clock = ECHO_CLOCK_INTERNAL;
+		return set_sample_rate(chip, chip->sample_rate);
+	case ECHO_CLOCK_SPDIF:
+		if (chip->digital_mode == DIGITAL_MODE_ADAT)
+			return -EAGAIN;
+		DE_ACT(("Set Gina24 clock to SPDIF\n"));
+		control_reg |= GML_SPDIF_CLOCK;
+		if (clocks_from_dsp & GML_CLOCK_DETECT_BIT_SPDIF96)
+			control_reg |= GML_DOUBLE_SPEED_MODE;
+		else
+			control_reg &= ~GML_DOUBLE_SPEED_MODE;
+		break;
+	case ECHO_CLOCK_ADAT:
+		if (chip->digital_mode != DIGITAL_MODE_ADAT)
+			return -EAGAIN;
+		DE_ACT(("Set Gina24 clock to ADAT\n"));
+		control_reg |= GML_ADAT_CLOCK;
+		control_reg &= ~GML_DOUBLE_SPEED_MODE;
+		break;
+	case ECHO_CLOCK_ESYNC:
+		DE_ACT(("Set Gina24 clock to ESYNC\n"));
+		control_reg |= GML_ESYNC_CLOCK;
+		control_reg &= ~GML_DOUBLE_SPEED_MODE;
+		break;
+	case ECHO_CLOCK_ESYNC96:
+		DE_ACT(("Set Gina24 clock to ESYNC96\n"));
+		control_reg |= GML_ESYNC_CLOCK | GML_DOUBLE_SPEED_MODE;
+		break;
+	default:
+		DE_ACT(("Input clock 0x%x not supported for Gina24\n", clock));
+		return -EINVAL;
+	}
+
+	chip->input_clock = clock;
+	return write_control_reg(chip, control_reg, TRUE);
+}
+
+
+
+static int dsp_set_digital_mode(struct echoaudio *chip, u8 mode)
+{
+	u32 control_reg;
+	int err, incompatible_clock;
+
+	/* Set clock to "internal" if it's not compatible with the new mode */
+	incompatible_clock = FALSE;
+	switch (mode) {
+	case DIGITAL_MODE_SPDIF_OPTICAL:
+	case DIGITAL_MODE_SPDIF_CDROM:
+	case DIGITAL_MODE_SPDIF_RCA:
+		if (chip->input_clock == ECHO_CLOCK_ADAT)
+			incompatible_clock = TRUE;
+		break;
+	case DIGITAL_MODE_ADAT:
+		if (chip->input_clock == ECHO_CLOCK_SPDIF)
+			incompatible_clock = TRUE;
+		break;
+	default:
+		DE_ACT(("Digital mode not supported: %d\n", mode));
+		return -EINVAL;
+	}
+
+	spin_lock_irq(&chip->lock);
+
+	if (incompatible_clock) {	/* Switch to 48KHz, internal */
+		chip->sample_rate = 48000;
+		set_input_clock(chip, ECHO_CLOCK_INTERNAL);
+	}
+
+	/* Clear the current digital mode */
+	control_reg = le32_to_cpu(chip->comm_page->control_register);
+	control_reg &= GML_DIGITAL_MODE_CLEAR_MASK;
+
+	/* Tweak the control reg */
+	switch (mode) {
+	case DIGITAL_MODE_SPDIF_OPTICAL:
+		control_reg |= GML_SPDIF_OPTICAL_MODE;
+		break;
+	case DIGITAL_MODE_SPDIF_CDROM:
+		/* '361 Gina24 cards do not have the S/PDIF CD-ROM mode */
+		if (chip->device_id == DEVICE_ID_56301)
+			control_reg |= GML_SPDIF_CDROM_MODE;
+		break;
+	case DIGITAL_MODE_SPDIF_RCA:
+		/* GML_SPDIF_OPTICAL_MODE bit cleared */
+		break;
+	case DIGITAL_MODE_ADAT:
+		control_reg |= GML_ADAT_MODE;
+		control_reg &= ~GML_DOUBLE_SPEED_MODE;
+		break;
+	}
+
+	err = write_control_reg(chip, control_reg, TRUE);
+	spin_unlock_irq(&chip->lock);
+	if (err < 0)
+		return err;
+	chip->digital_mode = mode;
+
+	DE_ACT(("set_digital_mode to %d\n", chip->digital_mode));
+	return incompatible_clock;
+}
diff --git a/sound/pci/echoaudio/indigo.c b/sound/pci/echoaudio/indigo.c
new file mode 100644
index 000000000..bfd246709
--- /dev/null
+++ b/sound/pci/echoaudio/indigo.c
@@ -0,0 +1,104 @@
+/*
+ *  ALSA driver for Echoaudio soundcards.
+ *  Copyright (C) 2003-2004 Giuliano Pochini <pochini@shiny.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; 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.
+ */
+
+#define INDIGO_FAMILY
+#define ECHOCARD_INDIGO
+#define ECHOCARD_NAME "Indigo"
+#define ECHOCARD_HAS_SUPER_INTERLEAVE
+#define ECHOCARD_HAS_VMIXER
+#define ECHOCARD_HAS_STEREO_BIG_ENDIAN32
+
+/* Pipe indexes */
+#define PX_ANALOG_OUT	0	/* 8 */
+#define PX_DIGITAL_OUT	8	/* 0 */
+#define PX_ANALOG_IN	8	/* 0 */
+#define PX_DIGITAL_IN	8	/* 0 */
+#define PX_NUM		8
+
+/* Bus indexes */
+#define BX_ANALOG_OUT	0	/* 2 */
+#define BX_DIGITAL_OUT	2	/* 0 */
+#define BX_ANALOG_IN	2	/* 0 */
+#define BX_DIGITAL_IN	2	/* 0 */
+#define BX_NUM		2
+
+
+#include <sound/driver.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/pci.h>
+#include <linux/slab.h>
+#include <linux/moduleparam.h>
+#include <linux/firmware.h>
+#include <sound/core.h>
+#include <sound/info.h>
+#include <sound/control.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/asoundef.h>
+#include <sound/initval.h>
+#include <asm/io.h>
+#include <asm/atomic.h>
+#include "echoaudio.h"
+
+#define FW_361_LOADER	0
+#define FW_INDIGO_DSP	1
+
+static const struct firmware card_fw[] = {
+	{0, "loader_dsp.fw"},
+	{0, "indigo_dsp.fw"}
+};
+
+static struct pci_device_id snd_echo_ids[] = {
+	{0x1057, 0x3410, 0xECC0, 0x0090, 0, 0, 0},	/* Indigo */
+	{0,}
+};
+
+static struct snd_pcm_hardware pcm_hardware_skel = {
+	.info = SNDRV_PCM_INFO_MMAP |
+		SNDRV_PCM_INFO_INTERLEAVED |
+		SNDRV_PCM_INFO_BLOCK_TRANSFER |
+		SNDRV_PCM_INFO_MMAP_VALID |
+		SNDRV_PCM_INFO_PAUSE |
+		SNDRV_PCM_INFO_SYNC_START,
+	.formats =	SNDRV_PCM_FMTBIT_U8 |
+			SNDRV_PCM_FMTBIT_S16_LE |
+			SNDRV_PCM_FMTBIT_S24_3LE |
+			SNDRV_PCM_FMTBIT_S32_LE |
+			SNDRV_PCM_FMTBIT_S32_BE,
+	.rates = 	SNDRV_PCM_RATE_32000 |
+			SNDRV_PCM_RATE_44100 |
+			SNDRV_PCM_RATE_48000 |
+			SNDRV_PCM_RATE_88200 |
+			SNDRV_PCM_RATE_96000,
+	.rate_min = 32000,
+	.rate_max = 96000,
+	.channels_min = 1,
+	.channels_max = 8,
+	.buffer_bytes_max = 262144,
+	.period_bytes_min = 32,
+	.period_bytes_max = 131072,
+	.periods_min = 2,
+	.periods_max = 220,
+};
+
+#include "indigo_dsp.c"
+#include "echoaudio_dsp.c"
+#include "echoaudio.c"
+
diff --git a/sound/pci/echoaudio/indigo_dsp.c b/sound/pci/echoaudio/indigo_dsp.c
new file mode 100644
index 000000000..d6ac77346
--- /dev/null
+++ b/sound/pci/echoaudio/indigo_dsp.c
@@ -0,0 +1,170 @@
+/****************************************************************************
+
+   Copyright Echo Digital Audio Corporation (c) 1998 - 2004
+   All rights reserved
+   www.echoaudio.com
+
+   This file is part of Echo Digital Audio's generic driver library.
+
+   Echo Digital Audio's generic driver library 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.
+
+   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.
+
+   *************************************************************************
+
+ Translation from C++ and adaptation for use in ALSA-Driver
+ were made by Giuliano Pochini <pochini@shiny.it>
+
+****************************************************************************/
+
+
+static int set_vmixer_gain(struct echoaudio *chip, u16 output, u16 pipe,
+			   int gain);
+static int update_vmixer_level(struct echoaudio *chip);
+
+
+static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
+{
+	int err;
+
+	DE_INIT(("init_hw() - Indigo\n"));
+	snd_assert((subdevice_id & 0xfff0) == INDIGO, return -ENODEV);
+
+	if ((err = init_dsp_comm_page(chip))) {
+		DE_INIT(("init_hw - could not initialize DSP comm page\n"));
+		return err;
+	}
+
+	chip->device_id = device_id;
+	chip->subdevice_id = subdevice_id;
+	chip->bad_board = TRUE;
+	chip->dsp_code_to_load = &card_fw[FW_INDIGO_DSP];
+	/* Since this card has no ASIC, mark it as loaded so everything
+	   works OK */
+	chip->asic_loaded = TRUE;
+	chip->input_clock_types = ECHO_CLOCK_BIT_INTERNAL;
+
+	if ((err = load_firmware(chip)) < 0)
+		return err;
+	chip->bad_board = FALSE;
+
+	if ((err = init_line_levels(chip)) < 0)
+		return err;
+
+	/* Default routing of the virtual channels: all vchannels are routed
+	to the stereo output */
+	set_vmixer_gain(chip, 0, 0, 0);
+	set_vmixer_gain(chip, 1, 1, 0);
+	set_vmixer_gain(chip, 0, 2, 0);
+	set_vmixer_gain(chip, 1, 3, 0);
+	set_vmixer_gain(chip, 0, 4, 0);
+	set_vmixer_gain(chip, 1, 5, 0);
+	set_vmixer_gain(chip, 0, 6, 0);
+	set_vmixer_gain(chip, 1, 7, 0);
+	err = update_vmixer_level(chip);
+
+	DE_INIT(("init_hw done\n"));
+	return err;
+}
+
+
+
+static u32 detect_input_clocks(const struct echoaudio *chip)
+{
+	return ECHO_CLOCK_BIT_INTERNAL;
+}
+
+
+
+/* The Indigo has no ASIC. Just do nothing */
+static int load_asic(struct echoaudio *chip)
+{
+	return 0;
+}
+
+
+
+static int set_sample_rate(struct echoaudio *chip, u32 rate)
+{
+	u32 control_reg;
+
+	switch (rate) {
+	case 96000:
+		control_reg = MIA_96000;
+		break;
+	case 88200:
+		control_reg = MIA_88200;
+		break;
+	case 48000:
+		control_reg = MIA_48000;
+		break;
+	case 44100:
+		control_reg = MIA_44100;
+		break;
+	case 32000:
+		control_reg = MIA_32000;
+		break;
+	default:
+		DE_ACT(("set_sample_rate: %d invalid!\n", rate));
+		return -EINVAL;
+	}
+
+	/* Set the control register if it has changed */
+	if (control_reg != le32_to_cpu(chip->comm_page->control_register)) {
+		if (wait_handshake(chip))
+			return -EIO;
+
+		chip->comm_page->sample_rate = cpu_to_le32(rate);	/* ignored by the DSP */
+		chip->comm_page->control_register = cpu_to_le32(control_reg);
+		chip->sample_rate = rate;
+
+		clear_handshake(chip);
+		return send_vector(chip, DSP_VC_UPDATE_CLOCKS);
+	}
+	return 0;
+}
+
+
+
+/* This function routes the sound from a virtual channel to a real output */
+static int set_vmixer_gain(struct echoaudio *chip, u16 output, u16 pipe,
+			   int gain)
+{
+	int index;
+
+	snd_assert(pipe < num_pipes_out(chip) &&
+		   output < num_busses_out(chip), return -EINVAL);
+
+	if (wait_handshake(chip))
+		return -EIO;
+
+	chip->vmixer_gain[output][pipe] = gain;
+	index = output * num_pipes_out(chip) + pipe;
+	chip->comm_page->vmixer[index] = gain;
+
+	DE_ACT(("set_vmixer_gain: pipe %d, out %d = %d\n", pipe, output, gain));
+	return 0;
+}
+
+
+
+/* Tell the DSP to read and update virtual mixer levels in comm page. */
+static int update_vmixer_level(struct echoaudio *chip)
+{
+	if (wait_handshake(chip))
+		return -EIO;
+	clear_handshake(chip);
+	return send_vector(chip, DSP_VC_SET_VMIXER_GAIN);
+}
+
diff --git a/sound/pci/echoaudio/indigodj.c b/sound/pci/echoaudio/indigodj.c
new file mode 100644
index 000000000..8ed7ff1fd
--- /dev/null
+++ b/sound/pci/echoaudio/indigodj.c
@@ -0,0 +1,104 @@
+/*
+ *  ALSA driver for Echoaudio soundcards.
+ *  Copyright (C) 2003-2004 Giuliano Pochini <pochini@shiny.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; 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.
+ */
+
+#define INDIGO_FAMILY
+#define ECHOCARD_INDIGO_DJ
+#define ECHOCARD_NAME "Indigo DJ"
+#define ECHOCARD_HAS_SUPER_INTERLEAVE
+#define ECHOCARD_HAS_VMIXER
+#define ECHOCARD_HAS_STEREO_BIG_ENDIAN32
+
+/* Pipe indexes */
+#define PX_ANALOG_OUT	0	/* 8 */
+#define PX_DIGITAL_OUT	8	/* 0 */
+#define PX_ANALOG_IN	8	/* 0 */
+#define PX_DIGITAL_IN	8	/* 0 */
+#define PX_NUM		8
+
+/* Bus indexes */
+#define BX_ANALOG_OUT	0	/* 4 */
+#define BX_DIGITAL_OUT	4	/* 0 */
+#define BX_ANALOG_IN	4	/* 0 */
+#define BX_DIGITAL_IN	4	/* 0 */
+#define BX_NUM		4
+
+
+#include <sound/driver.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/pci.h>
+#include <linux/slab.h>
+#include <linux/moduleparam.h>
+#include <linux/firmware.h>
+#include <sound/core.h>
+#include <sound/info.h>
+#include <sound/control.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/asoundef.h>
+#include <sound/initval.h>
+#include <asm/io.h>
+#include <asm/atomic.h>
+#include "echoaudio.h"
+
+#define FW_361_LOADER		0
+#define FW_INDIGO_DJ_DSP	1
+
+static const struct firmware card_fw[] = {
+	{0, "loader_dsp.fw"},
+	{0, "indigo_dj_dsp.fw"}
+};
+
+static struct pci_device_id snd_echo_ids[] = {
+	{0x1057, 0x3410, 0xECC0, 0x00B0, 0, 0, 0},	/* Indigo DJ*/
+	{0,}
+};
+
+static struct snd_pcm_hardware pcm_hardware_skel = {
+	.info = SNDRV_PCM_INFO_MMAP |
+		SNDRV_PCM_INFO_INTERLEAVED |
+		SNDRV_PCM_INFO_BLOCK_TRANSFER |
+		SNDRV_PCM_INFO_MMAP_VALID |
+		SNDRV_PCM_INFO_PAUSE |
+		SNDRV_PCM_INFO_SYNC_START,
+	.formats =	SNDRV_PCM_FMTBIT_U8 |
+			SNDRV_PCM_FMTBIT_S16_LE |
+			SNDRV_PCM_FMTBIT_S24_3LE |
+			SNDRV_PCM_FMTBIT_S32_LE |
+			SNDRV_PCM_FMTBIT_S32_BE,
+	.rates = 	SNDRV_PCM_RATE_32000 |
+			SNDRV_PCM_RATE_44100 |
+			SNDRV_PCM_RATE_48000 |
+			SNDRV_PCM_RATE_88200 |
+			SNDRV_PCM_RATE_96000,
+	.rate_min = 32000,
+	.rate_max = 96000,
+	.channels_min = 1,
+	.channels_max = 4,
+	.buffer_bytes_max = 262144,
+	.period_bytes_min = 32,
+	.period_bytes_max = 131072,
+	.periods_min = 2,
+	.periods_max = 220,
+};
+
+#include "indigodj_dsp.c"
+#include "echoaudio_dsp.c"
+#include "echoaudio.c"
+
diff --git a/sound/pci/echoaudio/indigodj_dsp.c b/sound/pci/echoaudio/indigodj_dsp.c
new file mode 100644
index 000000000..500e150b4
--- /dev/null
+++ b/sound/pci/echoaudio/indigodj_dsp.c
@@ -0,0 +1,170 @@
+/****************************************************************************
+
+   Copyright Echo Digital Audio Corporation (c) 1998 - 2004
+   All rights reserved
+   www.echoaudio.com
+
+   This file is part of Echo Digital Audio's generic driver library.
+
+   Echo Digital Audio's generic driver library 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.
+
+   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.
+
+   *************************************************************************
+
+ Translation from C++ and adaptation for use in ALSA-Driver
+ were made by Giuliano Pochini <pochini@shiny.it>
+
+****************************************************************************/
+
+
+static int set_vmixer_gain(struct echoaudio *chip, u16 output, u16 pipe,
+			   int gain);
+static int update_vmixer_level(struct echoaudio *chip);
+
+
+static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
+{
+	int err;
+
+	DE_INIT(("init_hw() - Indigo DJ\n"));
+	snd_assert((subdevice_id & 0xfff0) == INDIGO_DJ, return -ENODEV);
+
+	if ((err = init_dsp_comm_page(chip))) {
+		DE_INIT(("init_hw - could not initialize DSP comm page\n"));
+		return err;
+	}
+
+	chip->device_id = device_id;
+	chip->subdevice_id = subdevice_id;
+	chip->bad_board = TRUE;
+	chip->dsp_code_to_load = &card_fw[FW_INDIGO_DJ_DSP];
+	/* Since this card has no ASIC, mark it as loaded so everything
+	   works OK */
+	chip->asic_loaded = TRUE;
+	chip->input_clock_types = ECHO_CLOCK_BIT_INTERNAL;
+
+	if ((err = load_firmware(chip)) < 0)
+		return err;
+	chip->bad_board = FALSE;
+
+	if ((err = init_line_levels(chip)) < 0)
+		return err;
+
+	/* Default routing of the virtual channels: vchannels 0-3 and
+	vchannels 4-7 are routed to real channels 0-4 */
+	set_vmixer_gain(chip, 0, 0, 0);
+	set_vmixer_gain(chip, 1, 1, 0);
+	set_vmixer_gain(chip, 2, 2, 0);
+	set_vmixer_gain(chip, 3, 3, 0);
+	set_vmixer_gain(chip, 0, 4, 0);
+	set_vmixer_gain(chip, 1, 5, 0);
+	set_vmixer_gain(chip, 2, 6, 0);
+	set_vmixer_gain(chip, 3, 7, 0);
+	err = update_vmixer_level(chip);
+
+	DE_INIT(("init_hw done\n"));
+	return err;
+}
+
+
+
+static u32 detect_input_clocks(const struct echoaudio *chip)
+{
+	return ECHO_CLOCK_BIT_INTERNAL;
+}
+
+
+
+/* The IndigoDJ has no ASIC. Just do nothing */
+static int load_asic(struct echoaudio *chip)
+{
+	return 0;
+}
+
+
+
+static int set_sample_rate(struct echoaudio *chip, u32 rate)
+{
+	u32 control_reg;
+
+	switch (rate) {
+	case 96000:
+		control_reg = MIA_96000;
+		break;
+	case 88200:
+		control_reg = MIA_88200;
+		break;
+	case 48000:
+		control_reg = MIA_48000;
+		break;
+	case 44100:
+		control_reg = MIA_44100;
+		break;
+	case 32000:
+		control_reg = MIA_32000;
+		break;
+	default:
+		DE_ACT(("set_sample_rate: %d invalid!\n", rate));
+		return -EINVAL;
+	}
+
+	/* Set the control register if it has changed */
+	if (control_reg != le32_to_cpu(chip->comm_page->control_register)) {
+		if (wait_handshake(chip))
+			return -EIO;
+
+		chip->comm_page->sample_rate = cpu_to_le32(rate);	/* ignored by the DSP */
+		chip->comm_page->control_register = cpu_to_le32(control_reg);
+		chip->sample_rate = rate;
+
+		clear_handshake(chip);
+		return send_vector(chip, DSP_VC_UPDATE_CLOCKS);
+	}
+	return 0;
+}
+
+
+
+/* This function routes the sound from a virtual channel to a real output */
+static int set_vmixer_gain(struct echoaudio *chip, u16 output, u16 pipe,
+			   int gain)
+{
+	int index;
+
+	snd_assert(pipe < num_pipes_out(chip) &&
+		   output < num_busses_out(chip), return -EINVAL);
+
+	if (wait_handshake(chip))
+		return -EIO;
+
+	chip->vmixer_gain[output][pipe] = gain;
+	index = output * num_pipes_out(chip) + pipe;
+	chip->comm_page->vmixer[index] = gain;
+
+	DE_ACT(("set_vmixer_gain: pipe %d, out %d = %d\n", pipe, output, gain));
+	return 0;
+}
+
+
+
+/* Tell the DSP to read and update virtual mixer levels in comm page. */
+static int update_vmixer_level(struct echoaudio *chip)
+{
+	if (wait_handshake(chip))
+		return -EIO;
+	clear_handshake(chip);
+	return send_vector(chip, DSP_VC_SET_VMIXER_GAIN);
+}
+
diff --git a/sound/pci/echoaudio/indigoio.c b/sound/pci/echoaudio/indigoio.c
new file mode 100644
index 000000000..a8788e959
--- /dev/null
+++ b/sound/pci/echoaudio/indigoio.c
@@ -0,0 +1,105 @@
+/*
+ *  ALSA driver for Echoaudio soundcards.
+ *  Copyright (C) 2003-2004 Giuliano Pochini <pochini@shiny.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; 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.
+ */
+
+#define INDIGO_FAMILY
+#define ECHOCARD_INDIGO_IO
+#define ECHOCARD_NAME "Indigo IO"
+#define ECHOCARD_HAS_MONITOR
+#define ECHOCARD_HAS_SUPER_INTERLEAVE
+#define ECHOCARD_HAS_VMIXER
+#define ECHOCARD_HAS_STEREO_BIG_ENDIAN32
+
+/* Pipe indexes */
+#define PX_ANALOG_OUT	0	/* 8 */
+#define PX_DIGITAL_OUT	8	/* 0 */
+#define PX_ANALOG_IN	8	/* 2 */
+#define PX_DIGITAL_IN	10	/* 0 */
+#define PX_NUM		10
+
+/* Bus indexes */
+#define BX_ANALOG_OUT	0	/* 2 */
+#define BX_DIGITAL_OUT	2	/* 0 */
+#define BX_ANALOG_IN	2	/* 2 */
+#define BX_DIGITAL_IN	4	/* 0 */
+#define BX_NUM		4
+
+
+#include <sound/driver.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/pci.h>
+#include <linux/slab.h>
+#include <linux/moduleparam.h>
+#include <linux/firmware.h>
+#include <sound/core.h>
+#include <sound/info.h>
+#include <sound/control.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/asoundef.h>
+#include <sound/initval.h>
+#include <asm/io.h>
+#include <asm/atomic.h>
+#include "echoaudio.h"
+
+#define FW_361_LOADER		0
+#define FW_INDIGO_IO_DSP	1
+
+static const struct firmware card_fw[] = {
+	{0, "loader_dsp.fw"},
+	{0, "indigo_io_dsp.fw"}
+};
+
+static struct pci_device_id snd_echo_ids[] = {
+	{0x1057, 0x3410, 0xECC0, 0x00A0, 0, 0, 0},	/* Indigo IO*/
+	{0,}
+};
+
+static struct snd_pcm_hardware pcm_hardware_skel = {
+	.info = SNDRV_PCM_INFO_MMAP |
+		SNDRV_PCM_INFO_INTERLEAVED |
+		SNDRV_PCM_INFO_BLOCK_TRANSFER |
+		SNDRV_PCM_INFO_MMAP_VALID |
+		SNDRV_PCM_INFO_PAUSE |
+		SNDRV_PCM_INFO_SYNC_START,
+	.formats =	SNDRV_PCM_FMTBIT_U8 |
+			SNDRV_PCM_FMTBIT_S16_LE |
+			SNDRV_PCM_FMTBIT_S24_3LE |
+			SNDRV_PCM_FMTBIT_S32_LE |
+			SNDRV_PCM_FMTBIT_S32_BE,
+	.rates = 	SNDRV_PCM_RATE_32000 |
+			SNDRV_PCM_RATE_44100 |
+			SNDRV_PCM_RATE_48000 |
+			SNDRV_PCM_RATE_88200 |
+			SNDRV_PCM_RATE_96000,
+	.rate_min = 32000,
+	.rate_max = 96000,
+	.channels_min = 1,
+	.channels_max = 8,
+	.buffer_bytes_max = 262144,
+	.period_bytes_min = 32,
+	.period_bytes_max = 131072,
+	.periods_min = 2,
+	.periods_max = 220,
+};
+
+#include "indigoio_dsp.c"
+#include "echoaudio_dsp.c"
+#include "echoaudio.c"
+
diff --git a/sound/pci/echoaudio/indigoio_dsp.c b/sound/pci/echoaudio/indigoio_dsp.c
new file mode 100644
index 000000000..f3ad13d06
--- /dev/null
+++ b/sound/pci/echoaudio/indigoio_dsp.c
@@ -0,0 +1,141 @@
+/****************************************************************************
+
+   Copyright Echo Digital Audio Corporation (c) 1998 - 2004
+   All rights reserved
+   www.echoaudio.com
+
+   This file is part of Echo Digital Audio's generic driver library.
+
+   Echo Digital Audio's generic driver library 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.
+
+   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.
+
+   *************************************************************************
+
+ Translation from C++ and adaptation for use in ALSA-Driver
+ were made by Giuliano Pochini <pochini@shiny.it>
+
+****************************************************************************/
+
+
+static int set_vmixer_gain(struct echoaudio *chip, u16 output, u16 pipe,
+			   int gain);
+static int update_vmixer_level(struct echoaudio *chip);
+
+
+static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
+{
+	int err;
+
+	DE_INIT(("init_hw() - Indigo IO\n"));
+	snd_assert((subdevice_id & 0xfff0) == INDIGO_IO, return -ENODEV);
+
+	if ((err = init_dsp_comm_page(chip))) {
+		DE_INIT(("init_hw - could not initialize DSP comm page\n"));
+		return err;
+	}
+
+	chip->device_id = device_id;
+	chip->subdevice_id = subdevice_id;
+	chip->bad_board = TRUE;
+	chip->dsp_code_to_load = &card_fw[FW_INDIGO_IO_DSP];
+	/* Since this card has no ASIC, mark it as loaded so everything
+	   works OK */
+	chip->asic_loaded = TRUE;
+	chip->input_clock_types = ECHO_CLOCK_BIT_INTERNAL;
+
+	if ((err = load_firmware(chip)) < 0)
+		return err;
+	chip->bad_board = FALSE;
+
+	if ((err = init_line_levels(chip)) < 0)
+		return err;
+
+	/* Default routing of the virtual channels: all vchannels are routed
+	to the stereo output */
+	set_vmixer_gain(chip, 0, 0, 0);
+	set_vmixer_gain(chip, 1, 1, 0);
+	set_vmixer_gain(chip, 0, 2, 0);
+	set_vmixer_gain(chip, 1, 3, 0);
+	set_vmixer_gain(chip, 0, 4, 0);
+	set_vmixer_gain(chip, 1, 5, 0);
+	set_vmixer_gain(chip, 0, 6, 0);
+	set_vmixer_gain(chip, 1, 7, 0);
+	err = update_vmixer_level(chip);
+
+	DE_INIT(("init_hw done\n"));
+	return err;
+}
+
+
+
+static u32 detect_input_clocks(const struct echoaudio *chip)
+{
+	return ECHO_CLOCK_BIT_INTERNAL;
+}
+
+
+
+/* The IndigoIO has no ASIC. Just do nothing */
+static int load_asic(struct echoaudio *chip)
+{
+	return 0;
+}
+
+
+
+static int set_sample_rate(struct echoaudio *chip, u32 rate)
+{
+	if (wait_handshake(chip))
+		return -EIO;
+
+	chip->sample_rate = rate;
+	chip->comm_page->sample_rate = cpu_to_le32(rate);
+	clear_handshake(chip);
+	return send_vector(chip, DSP_VC_UPDATE_CLOCKS);
+}
+
+
+
+/* This function routes the sound from a virtual channel to a real output */
+static int set_vmixer_gain(struct echoaudio *chip, u16 output, u16 pipe,
+			   int gain)
+{
+	int index;
+
+	snd_assert(pipe < num_pipes_out(chip) &&
+		   output < num_busses_out(chip), return -EINVAL);
+
+	if (wait_handshake(chip))
+		return -EIO;
+
+	chip->vmixer_gain[output][pipe] = gain;
+	index = output * num_pipes_out(chip) + pipe;
+	chip->comm_page->vmixer[index] = gain;
+
+	DE_ACT(("set_vmixer_gain: pipe %d, out %d = %d\n", pipe, output, gain));
+	return 0;
+}
+
+
+
+/* Tell the DSP to read and update virtual mixer levels in comm page. */
+static int update_vmixer_level(struct echoaudio *chip)
+{
+	if (wait_handshake(chip))
+		return -EIO;
+	clear_handshake(chip);
+	return send_vector(chip, DSP_VC_SET_VMIXER_GAIN);
+}
+
diff --git a/sound/pci/echoaudio/layla20.c b/sound/pci/echoaudio/layla20.c
new file mode 100644
index 000000000..e503d74b3
--- /dev/null
+++ b/sound/pci/echoaudio/layla20.c
@@ -0,0 +1,112 @@
+/*
+ *  ALSA driver for Echoaudio soundcards.
+ *  Copyright (C) 2003-2004 Giuliano Pochini <pochini@shiny.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; 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.
+ */
+
+#define ECHOGALS_FAMILY
+#define ECHOCARD_LAYLA20
+#define ECHOCARD_NAME "Layla20"
+#define ECHOCARD_HAS_MONITOR
+#define ECHOCARD_HAS_ASIC
+#define ECHOCARD_HAS_INPUT_GAIN
+#define ECHOCARD_HAS_OUTPUT_NOMINAL_LEVEL
+#define ECHOCARD_HAS_SUPER_INTERLEAVE
+#define ECHOCARD_HAS_DIGITAL_IO
+#define ECHOCARD_HAS_EXTERNAL_CLOCK
+#define ECHOCARD_HAS_ADAT	FALSE
+#define ECHOCARD_HAS_OUTPUT_CLOCK_SWITCH
+#define ECHOCARD_HAS_MIDI
+
+/* Pipe indexes */
+#define PX_ANALOG_OUT	0	/* 10 */
+#define PX_DIGITAL_OUT	10	/*  2 */
+#define PX_ANALOG_IN	12	/*  8 */
+#define PX_DIGITAL_IN	20	/*  2 */
+#define PX_NUM		22
+
+/* Bus indexes */
+#define BX_ANALOG_OUT	0	/* 10 */
+#define BX_DIGITAL_OUT	10	/*  2 */
+#define BX_ANALOG_IN	12	/*  8 */
+#define BX_DIGITAL_IN	20	/*  2 */
+#define BX_NUM		22
+
+
+#include <sound/driver.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/pci.h>
+#include <linux/slab.h>
+#include <linux/moduleparam.h>
+#include <linux/firmware.h>
+#include <sound/core.h>
+#include <sound/info.h>
+#include <sound/control.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/asoundef.h>
+#include <sound/initval.h>
+#include <sound/rawmidi.h>
+#include <asm/io.h>
+#include <asm/atomic.h>
+#include "echoaudio.h"
+
+#define FW_LAYLA20_DSP	0
+#define FW_LAYLA20_ASIC	1
+
+static const struct firmware card_fw[] = {
+	{0, "layla20_dsp.fw"},
+	{0, "layla20_asic.fw"}
+};
+
+static struct pci_device_id snd_echo_ids[] = {
+	{0x1057, 0x1801, 0xECC0, 0x0030, 0, 0, 0},	/* DSP 56301 Layla20 rev.0 */
+	{0x1057, 0x1801, 0xECC0, 0x0031, 0, 0, 0},	/* DSP 56301 Layla20 rev.1 */
+	{0,}
+};
+
+static struct snd_pcm_hardware pcm_hardware_skel = {
+	.info = SNDRV_PCM_INFO_MMAP |
+		SNDRV_PCM_INFO_INTERLEAVED |
+		SNDRV_PCM_INFO_BLOCK_TRANSFER |
+		SNDRV_PCM_INFO_MMAP_VALID |
+		SNDRV_PCM_INFO_PAUSE |
+		SNDRV_PCM_INFO_SYNC_START,
+	.formats =	SNDRV_PCM_FMTBIT_U8 |
+			SNDRV_PCM_FMTBIT_S16_LE |
+			SNDRV_PCM_FMTBIT_S24_3LE |
+			SNDRV_PCM_FMTBIT_S32_LE |
+			SNDRV_PCM_FMTBIT_S32_BE,
+	.rates = SNDRV_PCM_RATE_8000_48000 | SNDRV_PCM_RATE_CONTINUOUS,
+	.rate_min = 8000,
+	.rate_max = 50000,
+	.channels_min = 1,
+	.channels_max = 10,
+	.buffer_bytes_max = 262144,
+	.period_bytes_min = 32,
+	.period_bytes_max = 131072,
+	.periods_min = 2,
+	.periods_max = 220,
+	/* One page (4k) contains 512 instructions. I don't know if the hw
+	supports lists longer than this. In this case periods_max=220 is a
+	safe limit to make sure the list never exceeds 512 instructions. */
+};
+
+#include "layla20_dsp.c"
+#include "echoaudio_dsp.c"
+#include "echoaudio.c"
+#include "midi.c"
diff --git a/sound/pci/echoaudio/layla20_dsp.c b/sound/pci/echoaudio/layla20_dsp.c
new file mode 100644
index 000000000..990c9a60a
--- /dev/null
+++ b/sound/pci/echoaudio/layla20_dsp.c
@@ -0,0 +1,290 @@
+/****************************************************************************
+
+   Copyright Echo Digital Audio Corporation (c) 1998 - 2004
+   All rights reserved
+   www.echoaudio.com
+
+   This file is part of Echo Digital Audio's generic driver library.
+
+   Echo Digital Audio's generic driver library 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.
+
+   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.
+
+   *************************************************************************
+
+ Translation from C++ and adaptation for use in ALSA-Driver
+ were made by Giuliano Pochini <pochini@shiny.it>
+
+****************************************************************************/
+
+
+static int read_dsp(struct echoaudio *chip, u32 *data);
+static int set_professional_spdif(struct echoaudio *chip, char prof);
+static int load_asic_generic(struct echoaudio *chip, u32 cmd,
+			     const struct firmware *asic);
+static int check_asic_status(struct echoaudio *chip);
+static int update_flags(struct echoaudio *chip);
+
+
+static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
+{
+	int err;
+
+	DE_INIT(("init_hw() - Layla20\n"));
+	snd_assert((subdevice_id & 0xfff0) == LAYLA20, return -ENODEV);
+
+	if ((err = init_dsp_comm_page(chip))) {
+		DE_INIT(("init_hw - could not initialize DSP comm page\n"));
+		return err;
+	}
+
+	chip->device_id = device_id;
+	chip->subdevice_id = subdevice_id;
+	chip->bad_board = TRUE;
+	chip->has_midi = TRUE;
+	chip->dsp_code_to_load = &card_fw[FW_LAYLA20_DSP];
+	chip->input_clock_types =
+		ECHO_CLOCK_BIT_INTERNAL | ECHO_CLOCK_BIT_SPDIF |
+		ECHO_CLOCK_BIT_WORD | ECHO_CLOCK_BIT_SUPER;
+	chip->output_clock_types =
+		ECHO_CLOCK_BIT_WORD | ECHO_CLOCK_BIT_SUPER;
+
+	if ((err = load_firmware(chip)) < 0)
+		return err;
+	chip->bad_board = FALSE;
+
+	if ((err = init_line_levels(chip)) < 0)
+		return err;
+
+	err = set_professional_spdif(chip, TRUE);
+
+	DE_INIT(("init_hw done\n"));
+	return err;
+}
+
+
+
+static u32 detect_input_clocks(const struct echoaudio *chip)
+{
+	u32 clocks_from_dsp, clock_bits;
+
+	/* Map the DSP clock detect bits to the generic driver clock detect bits */
+	clocks_from_dsp = le32_to_cpu(chip->comm_page->status_clocks);
+
+	clock_bits = ECHO_CLOCK_BIT_INTERNAL;
+
+	if (clocks_from_dsp & GLDM_CLOCK_DETECT_BIT_SPDIF)
+		clock_bits |= ECHO_CLOCK_BIT_SPDIF;
+
+	if (clocks_from_dsp & GLDM_CLOCK_DETECT_BIT_WORD) {
+		if (clocks_from_dsp & GLDM_CLOCK_DETECT_BIT_SUPER)
+			clock_bits |= ECHO_CLOCK_BIT_SUPER;
+		else
+			clock_bits |= ECHO_CLOCK_BIT_WORD;
+	}
+
+	return clock_bits;
+}
+
+
+
+/* ASIC status check - some cards have one or two ASICs that need to be
+loaded.  Once that load is complete, this function is called to see if
+the load was successful.
+If this load fails, it does not necessarily mean that the hardware is
+defective - the external box may be disconnected or turned off.
+This routine sometimes fails for Layla20; for Layla20, the loop runs
+5 times and succeeds if it wins on three of the loops. */
+static int check_asic_status(struct echoaudio *chip)
+{
+	u32 asic_status;
+	int goodcnt, i;
+
+	chip->asic_loaded = FALSE;
+	for (i = goodcnt = 0; i < 5; i++) {
+		send_vector(chip, DSP_VC_TEST_ASIC);
+
+		/* The DSP will return a value to indicate whether or not
+		   the ASIC is currently loaded */
+		if (read_dsp(chip, &asic_status) < 0) {
+			DE_ACT(("check_asic_status: failed on read_dsp\n"));
+			return -EIO;
+		}
+
+		if (asic_status == ASIC_ALREADY_LOADED) {
+			if (++goodcnt == 3) {
+				chip->asic_loaded = TRUE;
+				return 0;
+			}
+		}
+	}
+	return -EIO;
+}
+
+
+
+/* Layla20 has an ASIC in the external box */
+static int load_asic(struct echoaudio *chip)
+{
+	int err;
+
+	if (chip->asic_loaded)
+		return 0;
+
+	err = load_asic_generic(chip, DSP_FNC_LOAD_LAYLA_ASIC,
+				&card_fw[FW_LAYLA20_ASIC]);
+	if (err < 0)
+		return err;
+
+	/* Check if ASIC is alive and well. */
+	return check_asic_status(chip);
+}
+
+
+
+static int set_sample_rate(struct echoaudio *chip, u32 rate)
+{
+	snd_assert(rate >= 8000 && rate <= 50000, return -EINVAL);
+
+	/* Only set the clock for internal mode. Do not return failure,
+	   simply treat it as a non-event. */
+	if (chip->input_clock != ECHO_CLOCK_INTERNAL) {
+		DE_ACT(("set_sample_rate: Cannot set sample rate - "
+			"clock not set to CLK_CLOCKININTERNAL\n"));
+		chip->comm_page->sample_rate = cpu_to_le32(rate);
+		chip->sample_rate = rate;
+		return 0;
+	}
+
+	if (wait_handshake(chip))
+		return -EIO;
+
+	DE_ACT(("set_sample_rate(%d)\n", rate));
+	chip->sample_rate = rate;
+	chip->comm_page->sample_rate = cpu_to_le32(rate);
+	clear_handshake(chip);
+	return send_vector(chip, DSP_VC_SET_LAYLA_SAMPLE_RATE);
+}
+
+
+
+static int set_input_clock(struct echoaudio *chip, u16 clock_source)
+{
+	u16 clock;
+	u32 rate;
+
+	DE_ACT(("set_input_clock:\n"));
+	rate = 0;
+	switch (clock_source) {
+	case ECHO_CLOCK_INTERNAL:
+		DE_ACT(("Set Layla20 clock to INTERNAL\n"));
+		rate = chip->sample_rate;
+		clock = LAYLA20_CLOCK_INTERNAL;
+		break;
+	case ECHO_CLOCK_SPDIF:
+		DE_ACT(("Set Layla20 clock to SPDIF\n"));
+		clock = LAYLA20_CLOCK_SPDIF;
+		break;
+	case ECHO_CLOCK_WORD:
+		DE_ACT(("Set Layla20 clock to WORD\n"));
+		clock = LAYLA20_CLOCK_WORD;
+		break;
+	case ECHO_CLOCK_SUPER:
+		DE_ACT(("Set Layla20 clock to SUPER\n"));
+		clock = LAYLA20_CLOCK_SUPER;
+		break;
+	default:
+		DE_ACT(("Input clock 0x%x not supported for Layla24\n",
+			clock_source));
+		return -EINVAL;
+	}
+	chip->input_clock = clock_source;
+
+	chip->comm_page->input_clock = cpu_to_le16(clock);
+	clear_handshake(chip);
+	send_vector(chip, DSP_VC_UPDATE_CLOCKS);
+
+	if (rate)
+		set_sample_rate(chip, rate);
+
+	return 0;
+}
+
+
+
+static int set_output_clock(struct echoaudio *chip, u16 clock)
+{
+	DE_ACT(("set_output_clock: %d\n", clock));
+	switch (clock) {
+	case ECHO_CLOCK_SUPER:
+		clock = LAYLA20_OUTPUT_CLOCK_SUPER;
+		break;
+	case ECHO_CLOCK_WORD:
+		clock = LAYLA20_OUTPUT_CLOCK_WORD;
+		break;
+	default:
+		DE_ACT(("set_output_clock wrong clock\n"));
+		return -EINVAL;
+	}
+
+	if (wait_handshake(chip))
+		return -EIO;
+
+	chip->comm_page->output_clock = cpu_to_le16(clock);
+	chip->output_clock = clock;
+	clear_handshake(chip);
+	return send_vector(chip, DSP_VC_UPDATE_CLOCKS);
+}
+
+
+
+/* Set input bus gain (one unit is 0.5dB !) */
+static int set_input_gain(struct echoaudio *chip, u16 input, int gain)
+{
+	snd_assert(input < num_busses_in(chip), return -EINVAL);
+
+	if (wait_handshake(chip))
+		return -EIO;
+
+	chip->input_gain[input] = gain;
+	gain += GL20_INPUT_GAIN_MAGIC_NUMBER;
+	chip->comm_page->line_in_level[input] = gain;
+	return 0;
+}
+
+
+
+/* Tell the DSP to reread the flags from the comm page */
+static int update_flags(struct echoaudio *chip)
+{
+	if (wait_handshake(chip))
+		return -EIO;
+	clear_handshake(chip);
+	return send_vector(chip, DSP_VC_UPDATE_FLAGS);
+}
+
+
+
+static int set_professional_spdif(struct echoaudio *chip, char prof)
+{
+	DE_ACT(("set_professional_spdif %d\n", prof));
+	if (prof)
+		chip->comm_page->flags |=
+			__constant_cpu_to_le32(DSP_FLAG_PROFESSIONAL_SPDIF);
+	else
+		chip->comm_page->flags &=
+			~__constant_cpu_to_le32(DSP_FLAG_PROFESSIONAL_SPDIF);
+	chip->professional_spdif = prof;
+	return update_flags(chip);
+}
diff --git a/sound/pci/echoaudio/layla24.c b/sound/pci/echoaudio/layla24.c
new file mode 100644
index 000000000..d4581fdc8
--- /dev/null
+++ b/sound/pci/echoaudio/layla24.c
@@ -0,0 +1,121 @@
+/*
+ *  ALSA driver for Echoaudio soundcards.
+ *  Copyright (C) 2003-2004 Giuliano Pochini <pochini@shiny.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; 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.
+ */
+
+#define ECHO24_FAMILY
+#define ECHOCARD_LAYLA24
+#define ECHOCARD_NAME "Layla24"
+#define ECHOCARD_HAS_MONITOR
+#define ECHOCARD_HAS_ASIC
+#define ECHOCARD_HAS_INPUT_NOMINAL_LEVEL
+#define ECHOCARD_HAS_OUTPUT_NOMINAL_LEVEL
+#define ECHOCARD_HAS_SUPER_INTERLEAVE
+#define ECHOCARD_HAS_DIGITAL_IO
+#define ECHOCARD_HAS_DIGITAL_IN_AUTOMUTE
+#define ECHOCARD_HAS_DIGITAL_MODE_SWITCH
+#define ECHOCARD_HAS_EXTERNAL_CLOCK
+#define ECHOCARD_HAS_ADAT	6
+#define ECHOCARD_HAS_STEREO_BIG_ENDIAN32
+#define ECHOCARD_HAS_MIDI
+
+/* Pipe indexes */
+#define PX_ANALOG_OUT	0	/* 8 */
+#define PX_DIGITAL_OUT	8	/* 8 */
+#define PX_ANALOG_IN	16	/* 8 */
+#define PX_DIGITAL_IN	24	/* 8 */
+#define PX_NUM		32
+
+/* Bus indexes */
+#define BX_ANALOG_OUT	0	/* 8 */
+#define BX_DIGITAL_OUT	8	/* 8 */
+#define BX_ANALOG_IN	16	/* 8 */
+#define BX_DIGITAL_IN	24	/* 8 */
+#define BX_NUM		32
+
+
+#include <sound/driver.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/pci.h>
+#include <linux/slab.h>
+#include <linux/moduleparam.h>
+#include <linux/firmware.h>
+#include <sound/core.h>
+#include <sound/info.h>
+#include <sound/control.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/asoundef.h>
+#include <sound/initval.h>
+#include <sound/rawmidi.h>
+#include <asm/io.h>
+#include <asm/atomic.h>
+#include "echoaudio.h"
+
+#define FW_361_LOADER		0
+#define FW_LAYLA24_DSP		1
+#define FW_LAYLA24_1_ASIC	2
+#define FW_LAYLA24_2A_ASIC	3
+#define FW_LAYLA24_2S_ASIC	4
+
+static const struct firmware card_fw[] = {
+	{0, "loader_dsp.fw"},
+	{0, "layla24_dsp.fw"},
+	{0, "layla24_1_asic.fw"},
+	{0, "layla24_2A_asic.fw"},
+	{0, "layla24_2S_asic.fw"}
+};
+
+static struct pci_device_id snd_echo_ids[] = {
+	{0x1057, 0x3410, 0xECC0, 0x0060, 0, 0, 0},	/* DSP 56361 Layla24 rev.0 */
+	{0,}
+};
+
+static struct snd_pcm_hardware pcm_hardware_skel = {
+	.info = SNDRV_PCM_INFO_MMAP |
+		SNDRV_PCM_INFO_INTERLEAVED |
+		SNDRV_PCM_INFO_BLOCK_TRANSFER |
+		SNDRV_PCM_INFO_MMAP_VALID |
+		SNDRV_PCM_INFO_PAUSE |
+		SNDRV_PCM_INFO_SYNC_START,
+	.formats =	SNDRV_PCM_FMTBIT_U8 |
+			SNDRV_PCM_FMTBIT_S16_LE |
+			SNDRV_PCM_FMTBIT_S24_3LE |
+			SNDRV_PCM_FMTBIT_S32_LE |
+			SNDRV_PCM_FMTBIT_S32_BE,
+	.rates =	SNDRV_PCM_RATE_8000_96000,
+	.rate_min = 8000,
+	.rate_max = 100000,
+	.channels_min = 1,
+	.channels_max = 8,
+	.buffer_bytes_max = 262144,
+	.period_bytes_min = 32,
+	.period_bytes_max = 131072,
+	.periods_min = 2,
+	.periods_max = 220,
+	/* One page (4k) contains 512 instructions. I don't know if the hw
+	supports lists longer than this. In this case periods_max=220 is a
+	safe limit to make sure the list never exceeds 512 instructions. */
+};
+
+
+#include "layla24_dsp.c"
+#include "echoaudio_dsp.c"
+#include "echoaudio_gml.c"
+#include "echoaudio.c"
+#include "midi.c"
diff --git a/sound/pci/echoaudio/layla24_dsp.c b/sound/pci/echoaudio/layla24_dsp.c
new file mode 100644
index 000000000..7ec5b63d0
--- /dev/null
+++ b/sound/pci/echoaudio/layla24_dsp.c
@@ -0,0 +1,394 @@
+/****************************************************************************
+
+   Copyright Echo Digital Audio Corporation (c) 1998 - 2004
+   All rights reserved
+   www.echoaudio.com
+
+   This file is part of Echo Digital Audio's generic driver library.
+
+   Echo Digital Audio's generic driver library 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.
+
+   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.
+
+   *************************************************************************
+
+ Translation from C++ and adaptation for use in ALSA-Driver
+ were made by Giuliano Pochini <pochini@shiny.it>
+
+****************************************************************************/
+
+
+static int write_control_reg(struct echoaudio *chip, u32 value, char force);
+static int set_input_clock(struct echoaudio *chip, u16 clock);
+static int set_professional_spdif(struct echoaudio *chip, char prof);
+static int set_digital_mode(struct echoaudio *chip, u8 mode);
+static int load_asic_generic(struct echoaudio *chip, u32 cmd,
+			     const struct firmware *asic);
+static int check_asic_status(struct echoaudio *chip);
+
+
+static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
+{
+	int err;
+
+	DE_INIT(("init_hw() - Layla24\n"));
+	snd_assert((subdevice_id & 0xfff0) == LAYLA24, return -ENODEV);
+
+	if ((err = init_dsp_comm_page(chip))) {
+		DE_INIT(("init_hw - could not initialize DSP comm page\n"));
+		return err;
+	}
+
+	chip->device_id = device_id;
+	chip->subdevice_id = subdevice_id;
+	chip->bad_board = TRUE;
+	chip->has_midi = TRUE;
+	chip->dsp_code_to_load = &card_fw[FW_LAYLA24_DSP];
+	chip->input_clock_types =
+		ECHO_CLOCK_BIT_INTERNAL | ECHO_CLOCK_BIT_SPDIF |
+		ECHO_CLOCK_BIT_WORD | ECHO_CLOCK_BIT_ADAT;
+	chip->digital_modes =
+		ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_RCA |
+		ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_OPTICAL |
+		ECHOCAPS_HAS_DIGITAL_MODE_ADAT;
+	chip->digital_mode =		DIGITAL_MODE_SPDIF_RCA;
+	chip->professional_spdif = FALSE;
+	chip->digital_in_automute = TRUE;
+
+	if ((err = load_firmware(chip)) < 0)
+		return err;
+	chip->bad_board = FALSE;
+
+	if ((err = init_line_levels(chip)) < 0)
+		return err;
+
+	err = set_digital_mode(chip, DIGITAL_MODE_SPDIF_RCA);
+	snd_assert(err >= 0, return err);
+	err = set_professional_spdif(chip, TRUE);
+
+	DE_INIT(("init_hw done\n"));
+	return err;
+}
+
+
+
+static u32 detect_input_clocks(const struct echoaudio *chip)
+{
+	u32 clocks_from_dsp, clock_bits;
+
+	/* Map the DSP clock detect bits to the generic driver clock detect bits */
+	clocks_from_dsp = le32_to_cpu(chip->comm_page->status_clocks);
+
+	clock_bits = ECHO_CLOCK_BIT_INTERNAL;
+
+	if (clocks_from_dsp & GML_CLOCK_DETECT_BIT_SPDIF)
+		clock_bits |= ECHO_CLOCK_BIT_SPDIF;
+
+	if (clocks_from_dsp & GML_CLOCK_DETECT_BIT_ADAT)
+		clock_bits |= ECHO_CLOCK_BIT_ADAT;
+
+	if (clocks_from_dsp & GML_CLOCK_DETECT_BIT_WORD)
+		clock_bits |= ECHO_CLOCK_BIT_WORD;
+
+	return clock_bits;
+}
+
+
+
+/* Layla24 has an ASIC on the PCI card and another ASIC in the external box;
+both need to be loaded. */
+static int load_asic(struct echoaudio *chip)
+{
+	int err;
+
+	if (chip->asic_loaded)
+		return 1;
+
+	DE_INIT(("load_asic\n"));
+
+	/* Give the DSP a few milliseconds to settle down */
+	mdelay(10);
+
+	/* Load the ASIC for the PCI card */
+	err = load_asic_generic(chip, DSP_FNC_LOAD_LAYLA24_PCI_CARD_ASIC,
+				&card_fw[FW_LAYLA24_1_ASIC]);
+	if (err < 0)
+		return err;
+
+	chip->asic_code = &card_fw[FW_LAYLA24_2S_ASIC];
+
+	/* Now give the new ASIC a little time to set up */
+	mdelay(10);
+
+	/* Do the external one */
+	err = load_asic_generic(chip, DSP_FNC_LOAD_LAYLA24_EXTERNAL_ASIC,
+				&card_fw[FW_LAYLA24_2S_ASIC]);
+	if (err < 0)
+		return FALSE;
+
+	/* Now give the external ASIC a little time to set up */
+	mdelay(10);
+
+	/* See if it worked */
+	err = check_asic_status(chip);
+
+	/* Set up the control register if the load succeeded -
+	   48 kHz, internal clock, S/PDIF RCA mode */
+	if (!err)
+		err = write_control_reg(chip, GML_CONVERTER_ENABLE | GML_48KHZ,
+					TRUE);
+	
+	DE_INIT(("load_asic() done\n"));
+	return err;
+}
+
+
+
+static int set_sample_rate(struct echoaudio *chip, u32 rate)
+{
+	u32 control_reg, clock, base_rate;
+
+	snd_assert(rate < 50000 || chip->digital_mode != DIGITAL_MODE_ADAT,
+		   return -EINVAL);
+
+	/* Only set the clock for internal mode. */
+	if (chip->input_clock != ECHO_CLOCK_INTERNAL) {
+		DE_ACT(("set_sample_rate: Cannot set sample rate - "
+			"clock not set to CLK_CLOCKININTERNAL\n"));
+		/* Save the rate anyhow */
+		chip->comm_page->sample_rate = cpu_to_le32(rate);
+		chip->sample_rate = rate;
+		return 0;
+	}
+
+	/* Get the control register & clear the appropriate bits */
+	control_reg = le32_to_cpu(chip->comm_page->control_register);
+	control_reg &= GML_CLOCK_CLEAR_MASK & GML_SPDIF_RATE_CLEAR_MASK;
+
+	clock = 0;
+
+	switch (rate) {
+	case 96000:
+		clock = GML_96KHZ;
+		break;
+	case 88200:
+		clock = GML_88KHZ;
+		break;
+	case 48000:
+		clock = GML_48KHZ | GML_SPDIF_SAMPLE_RATE1;
+		break;
+	case 44100:
+		clock = GML_44KHZ;
+		/* Professional mode */
+		if (control_reg & GML_SPDIF_PRO_MODE)
+			clock |= GML_SPDIF_SAMPLE_RATE0;
+		break;
+	case 32000:
+		clock = GML_32KHZ | GML_SPDIF_SAMPLE_RATE0 |
+			GML_SPDIF_SAMPLE_RATE1;
+		break;
+	case 22050:
+		clock = GML_22KHZ;
+		break;
+	case 16000:
+		clock = GML_16KHZ;
+		break;
+	case 11025:
+		clock = GML_11KHZ;
+		break;
+	case 8000:
+		clock = GML_8KHZ;
+		break;
+	default:
+		/* If this is a non-standard rate, then the driver needs to
+		use Layla24's special "continuous frequency" mode */
+		clock = LAYLA24_CONTINUOUS_CLOCK;
+		if (rate > 50000) {
+			base_rate = rate >> 1;
+			control_reg |= GML_DOUBLE_SPEED_MODE;
+		} else {
+			base_rate = rate;
+		}
+
+		if (base_rate < 25000)
+			base_rate = 25000;
+
+		if (wait_handshake(chip))
+			return -EIO;
+
+		chip->comm_page->sample_rate =
+			cpu_to_le32(LAYLA24_MAGIC_NUMBER / base_rate - 2);
+
+		clear_handshake(chip);
+		send_vector(chip, DSP_VC_SET_LAYLA24_FREQUENCY_REG);
+	}
+
+	control_reg |= clock;
+
+	chip->comm_page->sample_rate = cpu_to_le32(rate);	/* ignored by the DSP ? */
+	chip->sample_rate = rate;
+	DE_ACT(("set_sample_rate: %d clock %d\n", rate, control_reg));
+
+	return write_control_reg(chip, control_reg, FALSE);
+}
+
+
+
+static int set_input_clock(struct echoaudio *chip, u16 clock)
+{
+	u32 control_reg, clocks_from_dsp;
+
+	/* Mask off the clock select bits */
+	control_reg = le32_to_cpu(chip->comm_page->control_register) &
+		GML_CLOCK_CLEAR_MASK;
+	clocks_from_dsp = le32_to_cpu(chip->comm_page->status_clocks);
+
+	/* Pick the new clock */
+	switch (clock) {
+	case ECHO_CLOCK_INTERNAL:
+		DE_ACT(("Set Layla24 clock to INTERNAL\n"));
+		chip->input_clock = ECHO_CLOCK_INTERNAL;
+		return set_sample_rate(chip, chip->sample_rate);
+	case ECHO_CLOCK_SPDIF:
+		if (chip->digital_mode == DIGITAL_MODE_ADAT)
+			return -EAGAIN;
+		control_reg |= GML_SPDIF_CLOCK;
+		/* Layla24 doesn't support 96KHz S/PDIF */
+		control_reg &= ~GML_DOUBLE_SPEED_MODE;
+		DE_ACT(("Set Layla24 clock to SPDIF\n"));
+		break;
+	case ECHO_CLOCK_WORD:
+		control_reg |= GML_WORD_CLOCK;
+		if (clocks_from_dsp & GML_CLOCK_DETECT_BIT_WORD96)
+			control_reg |= GML_DOUBLE_SPEED_MODE;
+		else
+			control_reg &= ~GML_DOUBLE_SPEED_MODE;
+		DE_ACT(("Set Layla24 clock to WORD\n"));
+		break;
+	case ECHO_CLOCK_ADAT:
+		if (chip->digital_mode != DIGITAL_MODE_ADAT)
+			return -EAGAIN;
+		control_reg |= GML_ADAT_CLOCK;
+		control_reg &= ~GML_DOUBLE_SPEED_MODE;
+		DE_ACT(("Set Layla24 clock to ADAT\n"));
+		break;
+	default:
+		DE_ACT(("Input clock 0x%x not supported for Layla24\n", clock));
+		return -EINVAL;
+	}
+
+	chip->input_clock = clock;
+	return write_control_reg(chip, control_reg, TRUE);
+}
+
+
+
+/* Depending on what digital mode you want, Layla24 needs different ASICs
+loaded.  This function checks the ASIC needed for the new mode and sees
+if it matches the one already loaded. */
+static int switch_asic(struct echoaudio *chip, const struct firmware *asic)
+{
+	s8 *monitors;
+
+	/*  Check to see if this is already loaded */
+	if (asic != chip->asic_code) {
+		monitors = kmalloc(MONITOR_ARRAY_SIZE, GFP_KERNEL);
+		if (! monitors)
+			return -ENOMEM;
+
+		memcpy(monitors, chip->comm_page->monitors, MONITOR_ARRAY_SIZE);
+		memset(chip->comm_page->monitors, ECHOGAIN_MUTED,
+		       MONITOR_ARRAY_SIZE);
+
+		/* Load the desired ASIC */
+		if (load_asic_generic(chip, DSP_FNC_LOAD_LAYLA24_EXTERNAL_ASIC,
+				      asic) < 0) {
+			memcpy(chip->comm_page->monitors, monitors,
+			       MONITOR_ARRAY_SIZE);
+			kfree(monitors);
+			return -EIO;
+		}
+		chip->asic_code = asic;
+		memcpy(chip->comm_page->monitors, monitors, MONITOR_ARRAY_SIZE);
+		kfree(monitors);
+	}
+
+	return 0;
+}
+
+
+
+static int dsp_set_digital_mode(struct echoaudio *chip, u8 mode)
+{
+	u32 control_reg;
+	int err, incompatible_clock;
+	const struct firmware *asic;
+
+	/* Set clock to "internal" if it's not compatible with the new mode */
+	incompatible_clock = FALSE;
+	switch (mode) {
+	case DIGITAL_MODE_SPDIF_OPTICAL:
+	case DIGITAL_MODE_SPDIF_RCA:
+		if (chip->input_clock == ECHO_CLOCK_ADAT)
+			incompatible_clock = TRUE;
+		asic = &card_fw[FW_LAYLA24_2S_ASIC];
+		break;
+	case DIGITAL_MODE_ADAT:
+		if (chip->input_clock == ECHO_CLOCK_SPDIF)
+			incompatible_clock = TRUE;
+		asic = &card_fw[FW_LAYLA24_2A_ASIC];
+		break;
+	default:
+		DE_ACT(("Digital mode not supported: %d\n", mode));
+		return -EINVAL;
+	}
+
+	if (incompatible_clock) {	/* Switch to 48KHz, internal */
+		chip->sample_rate = 48000;
+		spin_lock_irq(&chip->lock);
+		set_input_clock(chip, ECHO_CLOCK_INTERNAL);
+		spin_unlock_irq(&chip->lock);
+	}
+
+	/* switch_asic() can sleep */
+	if (switch_asic(chip, asic) < 0)
+		return -EIO;
+
+	spin_lock_irq(&chip->lock);
+
+	/* Tweak the control register */
+	control_reg = le32_to_cpu(chip->comm_page->control_register);
+	control_reg &= GML_DIGITAL_MODE_CLEAR_MASK;
+
+	switch (mode) {
+	case DIGITAL_MODE_SPDIF_OPTICAL:
+		control_reg |= GML_SPDIF_OPTICAL_MODE;
+		break;
+	case DIGITAL_MODE_SPDIF_RCA:
+		/* GML_SPDIF_OPTICAL_MODE bit cleared */
+		break;
+	case DIGITAL_MODE_ADAT:
+		control_reg |= GML_ADAT_MODE;
+		control_reg &= ~GML_DOUBLE_SPEED_MODE;
+		break;
+	}
+
+	err = write_control_reg(chip, control_reg, TRUE);
+	spin_unlock_irq(&chip->lock);
+	if (err < 0)
+		return err;
+	chip->digital_mode = mode;
+
+	DE_ACT(("set_digital_mode to %d\n", mode));
+	return incompatible_clock;
+}
diff --git a/sound/pci/echoaudio/mia.c b/sound/pci/echoaudio/mia.c
new file mode 100644
index 000000000..be40c6426
--- /dev/null
+++ b/sound/pci/echoaudio/mia.c
@@ -0,0 +1,117 @@
+/*
+ *  ALSA driver for Echoaudio soundcards.
+ *  Copyright (C) 2003-2004 Giuliano Pochini <pochini@shiny.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; 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.
+ */
+
+#define ECHO24_FAMILY
+#define ECHOCARD_MIA
+#define ECHOCARD_NAME "Mia"
+#define ECHOCARD_HAS_MONITOR
+#define ECHOCARD_HAS_INPUT_NOMINAL_LEVEL
+#define ECHOCARD_HAS_OUTPUT_NOMINAL_LEVEL
+#define ECHOCARD_HAS_SUPER_INTERLEAVE
+#define ECHOCARD_HAS_VMIXER
+#define ECHOCARD_HAS_DIGITAL_IO
+#define ECHOCARD_HAS_EXTERNAL_CLOCK
+#define ECHOCARD_HAS_ADAT	FALSE
+#define ECHOCARD_HAS_STEREO_BIG_ENDIAN32
+#define ECHOCARD_HAS_MIDI
+
+/* Pipe indexes */
+#define PX_ANALOG_OUT	0	/* 8 */
+#define PX_DIGITAL_OUT	8	/* 0 */
+#define PX_ANALOG_IN	8	/* 2 */
+#define PX_DIGITAL_IN	10	/* 2 */
+#define PX_NUM		12
+
+/* Bus indexes */
+#define BX_ANALOG_OUT	0	/* 2 */
+#define BX_DIGITAL_OUT	2	/* 2 */
+#define BX_ANALOG_IN	4	/* 2 */
+#define BX_DIGITAL_IN	6	/* 2 */
+#define BX_NUM		8
+
+
+#include <sound/driver.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/pci.h>
+#include <linux/slab.h>
+#include <linux/moduleparam.h>
+#include <linux/firmware.h>
+#include <sound/core.h>
+#include <sound/info.h>
+#include <sound/control.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/asoundef.h>
+#include <sound/initval.h>
+#include <sound/rawmidi.h>
+#include <asm/io.h>
+#include <asm/atomic.h>
+#include "echoaudio.h"
+
+#define FW_361_LOADER	0
+#define FW_MIA_DSP	1
+
+static const struct firmware card_fw[] = {
+	{0, "loader_dsp.fw"},
+	{0, "mia_dsp.fw"}
+};
+
+static struct pci_device_id snd_echo_ids[] = {
+	{0x1057, 0x3410, 0xECC0, 0x0080, 0, 0, 0},	/* DSP 56361 Mia rev.0 */
+	{0x1057, 0x3410, 0xECC0, 0x0081, 0, 0, 0},	/* DSP 56361 Mia rev.1 */
+	{0,}
+};
+
+static struct snd_pcm_hardware pcm_hardware_skel = {
+	.info = SNDRV_PCM_INFO_MMAP |
+		SNDRV_PCM_INFO_INTERLEAVED |
+		SNDRV_PCM_INFO_BLOCK_TRANSFER |
+		SNDRV_PCM_INFO_MMAP_VALID |
+		SNDRV_PCM_INFO_PAUSE |
+		SNDRV_PCM_INFO_SYNC_START,
+	.formats =	SNDRV_PCM_FMTBIT_U8 |
+			SNDRV_PCM_FMTBIT_S16_LE |
+			SNDRV_PCM_FMTBIT_S24_3LE |
+			SNDRV_PCM_FMTBIT_S32_LE |
+			SNDRV_PCM_FMTBIT_S32_BE,
+	.rates = 	SNDRV_PCM_RATE_32000 |
+			SNDRV_PCM_RATE_44100 |
+			SNDRV_PCM_RATE_48000 |
+			SNDRV_PCM_RATE_88200 |
+			SNDRV_PCM_RATE_96000,
+	.rate_min = 8000,
+	.rate_max = 96000,
+	.channels_min = 1,
+	.channels_max = 8,
+	.buffer_bytes_max = 262144,
+	.period_bytes_min = 32,
+	.period_bytes_max = 131072,
+	.periods_min = 2,
+	.periods_max = 220,
+	/* One page (4k) contains 512 instructions. I don't know if the hw
+	supports lists longer than this. In this case periods_max=220 is a
+	safe limit to make sure the list never exceeds 512 instructions. */
+};
+
+
+#include "mia_dsp.c"
+#include "echoaudio_dsp.c"
+#include "echoaudio.c"
+#include "midi.c"
diff --git a/sound/pci/echoaudio/mia_dsp.c b/sound/pci/echoaudio/mia_dsp.c
new file mode 100644
index 000000000..891c70519
--- /dev/null
+++ b/sound/pci/echoaudio/mia_dsp.c
@@ -0,0 +1,229 @@
+/****************************************************************************
+
+   Copyright Echo Digital Audio Corporation (c) 1998 - 2004
+   All rights reserved
+   www.echoaudio.com
+
+   This file is part of Echo Digital Audio's generic driver library.
+
+   Echo Digital Audio's generic driver library 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.
+
+   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.
+
+   *************************************************************************
+
+ Translation from C++ and adaptation for use in ALSA-Driver
+ were made by Giuliano Pochini <pochini@shiny.it>
+
+****************************************************************************/
+
+
+static int set_input_clock(struct echoaudio *chip, u16 clock);
+static int set_professional_spdif(struct echoaudio *chip, char prof);
+static int update_flags(struct echoaudio *chip);
+static int set_vmixer_gain(struct echoaudio *chip, u16 output, u16 pipe,
+			   int gain);
+static int update_vmixer_level(struct echoaudio *chip);
+
+
+static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
+{
+	int err;
+
+	DE_INIT(("init_hw() - Mia\n"));
+	snd_assert((subdevice_id & 0xfff0) == MIA, return -ENODEV);
+
+	if ((err = init_dsp_comm_page(chip))) {
+		DE_INIT(("init_hw - could not initialize DSP comm page\n"));
+		return err;
+	}
+
+	chip->device_id = device_id;
+	chip->subdevice_id = subdevice_id;
+	chip->bad_board = TRUE;
+	chip->dsp_code_to_load = &card_fw[FW_MIA_DSP];
+	/* Since this card has no ASIC, mark it as loaded so everything
+	   works OK */
+	chip->asic_loaded = TRUE;
+	if ((subdevice_id & 0x0000f) == MIA_MIDI_REV)
+		chip->has_midi = TRUE;
+	chip->input_clock_types = ECHO_CLOCK_BIT_INTERNAL |
+		ECHO_CLOCK_BIT_SPDIF;
+
+	if ((err = load_firmware(chip)) < 0)
+		return err;
+	chip->bad_board = FALSE;
+
+	if ((err = init_line_levels(chip)))
+		return err;
+
+	/* Default routing of the virtual channels: vchannels 0-3 go to analog
+	outputs and vchannels 4-7 go to S/PDIF outputs */
+	set_vmixer_gain(chip, 0, 0, 0);
+	set_vmixer_gain(chip, 1, 1, 0);
+	set_vmixer_gain(chip, 0, 2, 0);
+	set_vmixer_gain(chip, 1, 3, 0);
+	set_vmixer_gain(chip, 2, 4, 0);
+	set_vmixer_gain(chip, 3, 5, 0);
+	set_vmixer_gain(chip, 2, 6, 0);
+	set_vmixer_gain(chip, 3, 7, 0);
+	err = update_vmixer_level(chip);
+
+	DE_INIT(("init_hw done\n"));
+	return err;
+}
+
+
+
+static u32 detect_input_clocks(const struct echoaudio *chip)
+{
+	u32 clocks_from_dsp, clock_bits;
+
+	/* Map the DSP clock detect bits to the generic driver clock
+	   detect bits */
+	clocks_from_dsp = le32_to_cpu(chip->comm_page->status_clocks);
+
+	clock_bits = ECHO_CLOCK_BIT_INTERNAL;
+
+	if (clocks_from_dsp & GLDM_CLOCK_DETECT_BIT_SPDIF)
+		clock_bits |= ECHO_CLOCK_BIT_SPDIF;
+
+	return clock_bits;
+}
+
+
+
+/* The Mia has no ASIC. Just do nothing */
+static int load_asic(struct echoaudio *chip)
+{
+	return 0;
+}
+
+
+
+static int set_sample_rate(struct echoaudio *chip, u32 rate)
+{
+	u32 control_reg;
+
+	switch (rate) {
+	case 96000:
+		control_reg = MIA_96000;
+		break;
+	case 88200:
+		control_reg = MIA_88200;
+		break;
+	case 48000:
+		control_reg = MIA_48000;
+		break;
+	case 44100:
+		control_reg = MIA_44100;
+		break;
+	case 32000:
+		control_reg = MIA_32000;
+		break;
+	default:
+		DE_ACT(("set_sample_rate: %d invalid!\n", rate));
+		return -EINVAL;
+	}
+
+	/* Override the clock setting if this Mia is set to S/PDIF clock */
+	if (chip->input_clock == ECHO_CLOCK_SPDIF)
+		control_reg |= MIA_SPDIF;
+
+	/* Set the control register if it has changed */
+	if (control_reg != le32_to_cpu(chip->comm_page->control_register)) {
+		if (wait_handshake(chip))
+			return -EIO;
+
+		chip->comm_page->sample_rate = cpu_to_le32(rate);	/* ignored by the DSP */
+		chip->comm_page->control_register = cpu_to_le32(control_reg);
+		chip->sample_rate = rate;
+
+		clear_handshake(chip);
+		return send_vector(chip, DSP_VC_UPDATE_CLOCKS);
+	}
+	return 0;
+}
+
+
+
+static int set_input_clock(struct echoaudio *chip, u16 clock)
+{
+	DE_ACT(("set_input_clock(%d)\n", clock));
+	snd_assert(clock == ECHO_CLOCK_INTERNAL || clock == ECHO_CLOCK_SPDIF,
+		   return -EINVAL);
+
+	chip->input_clock = clock;
+	return set_sample_rate(chip, chip->sample_rate);
+}
+
+
+
+/* This function routes the sound from a virtual channel to a real output */
+static int set_vmixer_gain(struct echoaudio *chip, u16 output, u16 pipe,
+			   int gain)
+{
+	int index;
+
+	snd_assert(pipe < num_pipes_out(chip) &&
+		   output < num_busses_out(chip), return -EINVAL);
+
+	if (wait_handshake(chip))
+		return -EIO;
+
+	chip->vmixer_gain[output][pipe] = gain;
+	index = output * num_pipes_out(chip) + pipe;
+	chip->comm_page->vmixer[index] = gain;
+
+	DE_ACT(("set_vmixer_gain: pipe %d, out %d = %d\n", pipe, output, gain));
+	return 0;
+}
+
+
+
+/* Tell the DSP to read and update virtual mixer levels in comm page. */
+static int update_vmixer_level(struct echoaudio *chip)
+{
+	if (wait_handshake(chip))
+		return -EIO;
+	clear_handshake(chip);
+	return send_vector(chip, DSP_VC_SET_VMIXER_GAIN);
+}
+
+
+
+/* Tell the DSP to reread the flags from the comm page */
+static int update_flags(struct echoaudio *chip)
+{
+	if (wait_handshake(chip))
+		return -EIO;
+	clear_handshake(chip);
+	return send_vector(chip, DSP_VC_UPDATE_FLAGS);
+}
+
+
+
+static int set_professional_spdif(struct echoaudio *chip, char prof)
+{
+	DE_ACT(("set_professional_spdif %d\n", prof));
+	if (prof)
+		chip->comm_page->flags |=
+			__constant_cpu_to_le32(DSP_FLAG_PROFESSIONAL_SPDIF);
+	else
+		chip->comm_page->flags &=
+			~__constant_cpu_to_le32(DSP_FLAG_PROFESSIONAL_SPDIF);
+	chip->professional_spdif = prof;
+	return update_flags(chip);
+}
+
diff --git a/sound/pci/echoaudio/midi.c b/sound/pci/echoaudio/midi.c
new file mode 100644
index 000000000..e31f0f11e
--- /dev/null
+++ b/sound/pci/echoaudio/midi.c
@@ -0,0 +1,327 @@
+/****************************************************************************
+
+   Copyright Echo Digital Audio Corporation (c) 1998 - 2004
+   All rights reserved
+   www.echoaudio.com
+
+   This file is part of Echo Digital Audio's generic driver library.
+
+   Echo Digital Audio's generic driver library 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.
+
+   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.
+
+   *************************************************************************
+
+ Translation from C++ and adaptation for use in ALSA-Driver
+ were made by Giuliano Pochini <pochini@shiny.it>
+
+****************************************************************************/
+
+
+/******************************************************************************
+	MIDI lowlevel code
+******************************************************************************/
+
+/* Start and stop Midi input */
+static int enable_midi_input(struct echoaudio *chip, char enable)
+{
+	DE_MID(("enable_midi_input(%d)\n", enable));
+
+	if (wait_handshake(chip))
+		return -EIO;
+
+	if (enable) {
+		chip->mtc_state = MIDI_IN_STATE_NORMAL;
+		chip->comm_page->flags |=
+			__constant_cpu_to_le32(DSP_FLAG_MIDI_INPUT);
+	} else
+		chip->comm_page->flags &=
+			~__constant_cpu_to_le32(DSP_FLAG_MIDI_INPUT);
+
+	clear_handshake(chip);
+	return send_vector(chip, DSP_VC_UPDATE_FLAGS);
+}
+
+
+
+/* Send a buffer full of MIDI data to the DSP
+Returns how many actually written or < 0 on error */
+static int write_midi(struct echoaudio *chip, u8 *data, int bytes)
+{
+	snd_assert(bytes > 0 && bytes < MIDI_OUT_BUFFER_SIZE, return -EINVAL);
+
+	if (wait_handshake(chip))
+		return -EIO;
+
+	/* HF4 indicates that it is safe to write MIDI output data */
+	if (! (get_dsp_register(chip, CHI32_STATUS_REG) & CHI32_STATUS_REG_HF4))
+		return 0;
+
+	chip->comm_page->midi_output[0] = bytes;
+	memcpy(&chip->comm_page->midi_output[1], data, bytes);
+	chip->comm_page->midi_out_free_count = 0;
+	clear_handshake(chip);
+	send_vector(chip, DSP_VC_MIDI_WRITE);
+	DE_MID(("write_midi: %d\n", bytes));
+	return bytes;
+}
+
+
+
+/* Run the state machine for MIDI input data
+MIDI time code sync isn't supported by this code right now, but you still need
+this state machine to parse the incoming MIDI data stream.  Every time the DSP
+sees a 0xF1 byte come in, it adds the DSP sample position to the MIDI data
+stream. The DSP sample position is represented as a 32 bit unsigned value,
+with the high 16 bits first, followed by the low 16 bits. Since these aren't
+real MIDI bytes, the following logic is needed to skip them. */
+static inline int mtc_process_data(struct echoaudio *chip, short midi_byte)
+{
+	switch (chip->mtc_state) {
+	case MIDI_IN_STATE_NORMAL:
+		if (midi_byte == 0xF1)
+			chip->mtc_state = MIDI_IN_STATE_TS_HIGH;
+		break;
+	case MIDI_IN_STATE_TS_HIGH:
+		chip->mtc_state = MIDI_IN_STATE_TS_LOW;
+		return MIDI_IN_SKIP_DATA;
+		break;
+	case MIDI_IN_STATE_TS_LOW:
+		chip->mtc_state = MIDI_IN_STATE_F1_DATA;
+		return MIDI_IN_SKIP_DATA;
+		break;
+	case MIDI_IN_STATE_F1_DATA:
+		chip->mtc_state = MIDI_IN_STATE_NORMAL;
+		break;
+	}
+	return 0;
+}
+
+
+
+/* This function is called from the IRQ handler and it reads the midi data
+from the DSP's buffer.  It returns the number of bytes received. */
+static int midi_service_irq(struct echoaudio *chip)
+{
+	short int count, midi_byte, i, received;
+
+	/* The count is at index 0, followed by actual data */
+	count = le16_to_cpu(chip->comm_page->midi_input[0]);
+
+	snd_assert(count < MIDI_IN_BUFFER_SIZE, return 0);
+
+	/* Get the MIDI data from the comm page */
+	i = 1;
+	received = 0;
+	for (i = 1; i <= count; i++) {
+		/* Get the MIDI byte */
+		midi_byte = le16_to_cpu(chip->comm_page->midi_input[i]);
+
+		/* Parse the incoming MIDI stream. The incoming MIDI data
+		consists of MIDI bytes and timestamps for the MIDI time code
+		0xF1 bytes. mtc_process_data() is a little state machine that
+		parses the stream. If you get MIDI_IN_SKIP_DATA back, then
+		this is a timestamp byte, not a MIDI byte, so don't store it
+		in the MIDI input buffer. */
+		if (mtc_process_data(chip, midi_byte) == MIDI_IN_SKIP_DATA)
+			continue;
+
+		chip->midi_buffer[received++] = (u8)midi_byte;
+	}
+
+	return received;
+}
+
+
+
+
+/******************************************************************************
+	MIDI interface
+******************************************************************************/
+
+static int snd_echo_midi_input_open(struct snd_rawmidi_substream *substream)
+{
+	struct echoaudio *chip = substream->rmidi->private_data;
+
+	chip->midi_in = substream;
+	DE_MID(("rawmidi_iopen\n"));
+	return 0;
+}
+
+
+
+static void snd_echo_midi_input_trigger(struct snd_rawmidi_substream *substream,
+					int up)
+{
+	struct echoaudio *chip = substream->rmidi->private_data;
+
+	if (up != chip->midi_input_enabled) {
+		spin_lock_irq(&chip->lock);
+		enable_midi_input(chip, up);
+		spin_unlock_irq(&chip->lock);
+		chip->midi_input_enabled = up;
+	}
+}
+
+
+
+static int snd_echo_midi_input_close(struct snd_rawmidi_substream *substream)
+{
+	struct echoaudio *chip = substream->rmidi->private_data;
+
+	chip->midi_in = NULL;
+	DE_MID(("rawmidi_iclose\n"));
+	return 0;
+}
+
+
+
+static int snd_echo_midi_output_open(struct snd_rawmidi_substream *substream)
+{
+	struct echoaudio *chip = substream->rmidi->private_data;
+
+	chip->tinuse = 0;
+	chip->midi_full = 0;
+	chip->midi_out = substream;
+	DE_MID(("rawmidi_oopen\n"));
+	return 0;
+}
+
+
+
+static void snd_echo_midi_output_write(unsigned long data)
+{
+	struct echoaudio *chip = (struct echoaudio *)data;
+	unsigned long flags;
+	int bytes, sent, time;
+	unsigned char buf[MIDI_OUT_BUFFER_SIZE - 1];
+
+	DE_MID(("snd_echo_midi_output_write\n"));
+	/* No interrupts are involved: we have to check at regular intervals
+	if the card's output buffer has room for new data. */
+	sent = bytes = 0;
+	spin_lock_irqsave(&chip->lock, flags);
+	chip->midi_full = 0;
+	if (chip->midi_out && !snd_rawmidi_transmit_empty(chip->midi_out)) {
+		bytes = snd_rawmidi_transmit_peek(chip->midi_out, buf,
+						  MIDI_OUT_BUFFER_SIZE - 1);
+		DE_MID(("Try to send %d bytes...\n", bytes));
+		sent = write_midi(chip, buf, bytes);
+		if (sent < 0) {
+			snd_printk(KERN_ERR "write_midi() error %d\n", sent);
+			/* retry later */
+			sent = 9000;
+			chip->midi_full = 1;
+		} else if (sent > 0) {
+			DE_MID(("%d bytes sent\n", sent));
+			snd_rawmidi_transmit_ack(chip->midi_out, sent);
+		} else {
+			/* Buffer is full. DSP's internal buffer is 64 (128 ?)
+			bytes long. Let's wait until half of them are sent */
+			DE_MID(("Full\n"));
+			sent = 32;
+			chip->midi_full = 1;
+		}
+	}
+
+	/* We restart the timer only if there is some data left to send */
+	if (!snd_rawmidi_transmit_empty(chip->midi_out) && chip->tinuse) {
+		/* The timer will expire slightly after the data has been
+		   sent */
+		time = (sent << 3) / 25 + 1;	/* 8/25=0.32ms to send a byte */
+		mod_timer(&chip->timer, jiffies + (time * HZ + 999) / 1000);
+		DE_MID(("Timer armed(%d)\n", ((time * HZ + 999) / 1000)));
+	}
+	spin_unlock_irqrestore(&chip->lock, flags);
+}
+
+
+
+static void snd_echo_midi_output_trigger(struct snd_rawmidi_substream *substream,
+					 int up)
+{
+	struct echoaudio *chip = substream->rmidi->private_data;
+
+	DE_MID(("snd_echo_midi_output_trigger(%d)\n", up));
+	spin_lock_irq(&chip->lock);
+	if (up) {
+		if (!chip->tinuse) {
+			init_timer(&chip->timer);
+			chip->timer.function = snd_echo_midi_output_write;
+			chip->timer.data = (unsigned long)chip;
+			chip->tinuse = 1;
+		}
+	} else {
+		if (chip->tinuse) {
+			del_timer(&chip->timer);
+			chip->tinuse = 0;
+			DE_MID(("Timer removed\n"));
+		}
+	}
+	spin_unlock_irq(&chip->lock);
+
+	if (up && !chip->midi_full)
+		snd_echo_midi_output_write((unsigned long)chip);
+}
+
+
+
+static int snd_echo_midi_output_close(struct snd_rawmidi_substream *substream)
+{
+	struct echoaudio *chip = substream->rmidi->private_data;
+
+	chip->midi_out = NULL;
+	DE_MID(("rawmidi_oclose\n"));
+	return 0;
+}
+
+
+
+static struct snd_rawmidi_ops snd_echo_midi_input = {
+	.open = snd_echo_midi_input_open,
+	.close = snd_echo_midi_input_close,
+	.trigger = snd_echo_midi_input_trigger,
+};
+
+static struct snd_rawmidi_ops snd_echo_midi_output = {
+	.open = snd_echo_midi_output_open,
+	.close = snd_echo_midi_output_close,
+	.trigger = snd_echo_midi_output_trigger,
+};
+
+
+
+/* <--snd_echo_probe() */
+static int __devinit snd_echo_midi_create(struct snd_card *card,
+					  struct echoaudio *chip)
+{
+	int err;
+
+	if ((err = snd_rawmidi_new(card, card->shortname, 0, 1, 1,
+				   &chip->rmidi)) < 0)
+		return err;
+
+	strcpy(chip->rmidi->name, card->shortname);
+	chip->rmidi->private_data = chip;
+
+	snd_rawmidi_set_ops(chip->rmidi, SNDRV_RAWMIDI_STREAM_INPUT,
+			    &snd_echo_midi_input);
+	snd_rawmidi_set_ops(chip->rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT,
+			    &snd_echo_midi_output);
+
+	chip->rmidi->info_flags |= SNDRV_RAWMIDI_INFO_OUTPUT |
+		SNDRV_RAWMIDI_INFO_INPUT | SNDRV_RAWMIDI_INFO_DUPLEX;
+	DE_INIT(("MIDI ok\n"));
+	return 0;
+}
diff --git a/sound/pci/echoaudio/mona.c b/sound/pci/echoaudio/mona.c
new file mode 100644
index 000000000..5dc512add
--- /dev/null
+++ b/sound/pci/echoaudio/mona.c
@@ -0,0 +1,129 @@
+/*
+ *  ALSA driver for Echoaudio soundcards.
+ *  Copyright (C) 2003-2004 Giuliano Pochini <pochini@shiny.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; 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.
+ */
+
+#define ECHO24_FAMILY
+#define ECHOCARD_MONA
+#define ECHOCARD_NAME "Mona"
+#define ECHOCARD_HAS_MONITOR
+#define ECHOCARD_HAS_ASIC
+#define ECHOCARD_HAS_SUPER_INTERLEAVE
+#define ECHOCARD_HAS_DIGITAL_IO
+#define ECHOCARD_HAS_DIGITAL_IN_AUTOMUTE
+#define ECHOCARD_HAS_DIGITAL_MODE_SWITCH
+#define ECHOCARD_HAS_EXTERNAL_CLOCK
+#define ECHOCARD_HAS_ADAT	6
+#define ECHOCARD_HAS_STEREO_BIG_ENDIAN32
+
+/* Pipe indexes */
+#define PX_ANALOG_OUT	0	/* 6 */
+#define PX_DIGITAL_OUT	6	/* 8 */
+#define PX_ANALOG_IN	14	/* 4 */
+#define PX_DIGITAL_IN	18	/* 8 */
+#define PX_NUM		26
+
+/* Bus indexes */
+#define BX_ANALOG_OUT	0	/* 6 */
+#define BX_DIGITAL_OUT	6	/* 8 */
+#define BX_ANALOG_IN	14	/* 4 */
+#define BX_DIGITAL_IN	18	/* 8 */
+#define BX_NUM		26
+
+
+#include <sound/driver.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/pci.h>
+#include <linux/slab.h>
+#include <linux/moduleparam.h>
+#include <linux/firmware.h>
+#include <sound/core.h>
+#include <sound/info.h>
+#include <sound/control.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/asoundef.h>
+#include <sound/initval.h>
+#include <asm/io.h>
+#include <asm/atomic.h>
+#include "echoaudio.h"
+
+#define FW_361_LOADER		0
+#define FW_MONA_301_DSP		1
+#define FW_MONA_361_DSP		2
+#define FW_MONA_301_1_ASIC48	3
+#define FW_MONA_301_1_ASIC96	4
+#define FW_MONA_361_1_ASIC48	5
+#define FW_MONA_361_1_ASIC96	6
+#define FW_MONA_2_ASIC		7
+
+static const struct firmware card_fw[] = {
+	{0, "loader_dsp.fw"},
+	{0, "mona_301_dsp.fw"},
+	{0, "mona_361_dsp.fw"},
+	{0, "mona_301_1_asic_48.fw"},
+	{0, "mona_301_1_asic_96.fw"},
+	{0, "mona_361_1_asic_48.fw"},
+	{0, "mona_361_1_asic_96.fw"},
+	{0, "mona_2_asic.fw"}
+};
+
+static struct pci_device_id snd_echo_ids[] = {
+	{0x1057, 0x1801, 0xECC0, 0x0070, 0, 0, 0},	/* DSP 56301 Mona rev.0 */
+	{0x1057, 0x1801, 0xECC0, 0x0071, 0, 0, 0},	/* DSP 56301 Mona rev.1 */
+	{0x1057, 0x1801, 0xECC0, 0x0072, 0, 0, 0},	/* DSP 56301 Mona rev.2 */
+	{0x1057, 0x3410, 0xECC0, 0x0070, 0, 0, 0},	/* DSP 56361 Mona rev.0 */
+	{0x1057, 0x3410, 0xECC0, 0x0071, 0, 0, 0},	/* DSP 56361 Mona rev.1 */
+	{0x1057, 0x3410, 0xECC0, 0x0072, 0, 0, 0},	/* DSP 56361 Mona rev.2 */
+	{0,}
+};
+
+static struct snd_pcm_hardware pcm_hardware_skel = {
+	.info = SNDRV_PCM_INFO_MMAP |
+		SNDRV_PCM_INFO_INTERLEAVED |
+		SNDRV_PCM_INFO_BLOCK_TRANSFER |
+		SNDRV_PCM_INFO_MMAP_VALID |
+		SNDRV_PCM_INFO_PAUSE |
+		SNDRV_PCM_INFO_SYNC_START,
+	.formats =	SNDRV_PCM_FMTBIT_U8 |
+			SNDRV_PCM_FMTBIT_S16_LE |
+			SNDRV_PCM_FMTBIT_S24_3LE |
+			SNDRV_PCM_FMTBIT_S32_LE |
+			SNDRV_PCM_FMTBIT_S32_BE,
+	.rates = 	SNDRV_PCM_RATE_8000_48000 |
+			SNDRV_PCM_RATE_88200 |
+			SNDRV_PCM_RATE_96000,
+	.rate_min = 8000,
+	.rate_max = 96000,
+	.channels_min = 1,
+	.channels_max = 8,
+	.buffer_bytes_max = 262144,
+	.period_bytes_min = 32,
+	.period_bytes_max = 131072,
+	.periods_min = 2,
+	.periods_max = 220,
+	/* One page (4k) contains 512 instructions. I don't know if the hw
+	supports lists longer than this. In this case periods_max=220 is a
+	safe limit to make sure the list never exceeds 512 instructions. */
+};
+
+
+#include "mona_dsp.c"
+#include "echoaudio_dsp.c"
+#include "echoaudio_gml.c"
+#include "echoaudio.c"
diff --git a/sound/pci/echoaudio/mona_dsp.c b/sound/pci/echoaudio/mona_dsp.c
new file mode 100644
index 000000000..c0b4bf0be
--- /dev/null
+++ b/sound/pci/echoaudio/mona_dsp.c
@@ -0,0 +1,428 @@
+/****************************************************************************
+
+   Copyright Echo Digital Audio Corporation (c) 1998 - 2004
+   All rights reserved
+   www.echoaudio.com
+
+   This file is part of Echo Digital Audio's generic driver library.
+
+   Echo Digital Audio's generic driver library 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.
+
+   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.
+
+   *************************************************************************
+
+ Translation from C++ and adaptation for use in ALSA-Driver
+ were made by Giuliano Pochini <pochini@shiny.it>
+
+****************************************************************************/
+
+
+static int write_control_reg(struct echoaudio *chip, u32 value, char force);
+static int set_input_clock(struct echoaudio *chip, u16 clock);
+static int set_professional_spdif(struct echoaudio *chip, char prof);
+static int set_digital_mode(struct echoaudio *chip, u8 mode);
+static int load_asic_generic(struct echoaudio *chip, u32 cmd,
+			     const struct firmware *asic);
+static int check_asic_status(struct echoaudio *chip);
+
+
+static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
+{
+	int err;
+
+	DE_INIT(("init_hw() - Mona\n"));
+	snd_assert((subdevice_id & 0xfff0) == MONA, return -ENODEV);
+
+	if ((err = init_dsp_comm_page(chip))) {
+		DE_INIT(("init_hw - could not initialize DSP comm page\n"));
+		return err;
+	}
+
+	chip->device_id = device_id;
+	chip->subdevice_id = subdevice_id;
+	chip->bad_board = TRUE;
+	chip->input_clock_types =
+		ECHO_CLOCK_BIT_INTERNAL | ECHO_CLOCK_BIT_SPDIF |
+		ECHO_CLOCK_BIT_WORD | ECHO_CLOCK_BIT_ADAT;
+	chip->digital_modes =
+		ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_RCA |
+		ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_OPTICAL |
+		ECHOCAPS_HAS_DIGITAL_MODE_ADAT;
+
+	/* Mona comes in both '301 and '361 flavors */
+	if (chip->device_id == DEVICE_ID_56361)
+		chip->dsp_code_to_load = &card_fw[FW_MONA_361_DSP];
+	else
+		chip->dsp_code_to_load = &card_fw[FW_MONA_301_DSP];
+
+	chip->digital_mode = DIGITAL_MODE_SPDIF_RCA;
+	chip->professional_spdif = FALSE;
+	chip->digital_in_automute = TRUE;
+
+	if ((err = load_firmware(chip)) < 0)
+		return err;
+	chip->bad_board = FALSE;
+
+	if ((err = init_line_levels(chip)) < 0)
+		return err;
+
+	err = set_digital_mode(chip, DIGITAL_MODE_SPDIF_RCA);
+	snd_assert(err >= 0, return err);
+	err = set_professional_spdif(chip, TRUE);
+
+	DE_INIT(("init_hw done\n"));
+	return err;
+}
+
+
+
+static u32 detect_input_clocks(const struct echoaudio *chip)
+{
+	u32 clocks_from_dsp, clock_bits;
+
+	/* Map the DSP clock detect bits to the generic driver clock
+	   detect bits */
+	clocks_from_dsp = le32_to_cpu(chip->comm_page->status_clocks);
+
+	clock_bits = ECHO_CLOCK_BIT_INTERNAL;
+
+	if (clocks_from_dsp & GML_CLOCK_DETECT_BIT_SPDIF)
+		clock_bits |= ECHO_CLOCK_BIT_SPDIF;
+
+	if (clocks_from_dsp & GML_CLOCK_DETECT_BIT_ADAT)
+		clock_bits |= ECHO_CLOCK_BIT_ADAT;
+
+	if (clocks_from_dsp & GML_CLOCK_DETECT_BIT_WORD)
+		clock_bits |= ECHO_CLOCK_BIT_WORD;
+
+	return clock_bits;
+}
+
+
+
+/* Mona has an ASIC on the PCI card and another ASIC in the external box; 
+both need to be loaded. */
+static int load_asic(struct echoaudio *chip)
+{
+	u32 control_reg;
+	int err;
+	const struct firmware *asic;
+
+	if (chip->asic_loaded)
+		return 0;
+
+	mdelay(10);
+
+	if (chip->device_id == DEVICE_ID_56361)
+		asic = &card_fw[FW_MONA_361_1_ASIC48];
+	else
+		asic = &card_fw[FW_MONA_301_1_ASIC48];
+
+	err = load_asic_generic(chip, DSP_FNC_LOAD_MONA_PCI_CARD_ASIC, asic);
+	if (err < 0)
+		return err;
+
+	chip->asic_code = asic;
+	mdelay(10);
+
+	/* Do the external one */
+	err = load_asic_generic(chip, DSP_FNC_LOAD_MONA_EXTERNAL_ASIC,
+				&card_fw[FW_MONA_2_ASIC]);
+	if (err < 0)
+		return err;
+
+	mdelay(10);
+	err = check_asic_status(chip);
+
+	/* Set up the control register if the load succeeded -
+	   48 kHz, internal clock, S/PDIF RCA mode */
+	if (!err) {
+		control_reg = GML_CONVERTER_ENABLE | GML_48KHZ;
+		err = write_control_reg(chip, control_reg, TRUE);
+	}
+
+	return err;
+}
+
+
+
+/* Depending on what digital mode you want, Mona needs different ASICs
+loaded.  This function checks the ASIC needed for the new mode and sees
+if it matches the one already loaded. */
+static int switch_asic(struct echoaudio *chip, char double_speed)
+{
+	const struct firmware *asic;
+	int err;
+
+	/* Check the clock detect bits to see if this is
+	a single-speed clock or a double-speed clock; load
+	a new ASIC if necessary. */
+	if (chip->device_id == DEVICE_ID_56361) {
+		if (double_speed)
+			asic = &card_fw[FW_MONA_361_1_ASIC96];
+		else
+			asic = &card_fw[FW_MONA_361_1_ASIC48];
+	} else {
+		if (double_speed)
+			asic = &card_fw[FW_MONA_301_1_ASIC96];
+		else
+			asic = &card_fw[FW_MONA_301_1_ASIC48];
+	}
+
+	if (asic != chip->asic_code) {
+		/* Load the desired ASIC */
+		err = load_asic_generic(chip, DSP_FNC_LOAD_MONA_PCI_CARD_ASIC,
+					asic);
+		if (err < 0)
+			return err;
+		chip->asic_code = asic;
+	}
+
+	return 0;
+}
+
+
+
+static int set_sample_rate(struct echoaudio *chip, u32 rate)
+{
+	u32 control_reg, clock;
+	const struct firmware *asic;
+	char force_write;
+
+	/* Only set the clock for internal mode. */
+	if (chip->input_clock != ECHO_CLOCK_INTERNAL) {
+		DE_ACT(("set_sample_rate: Cannot set sample rate - "
+			"clock not set to CLK_CLOCKININTERNAL\n"));
+		/* Save the rate anyhow */
+		chip->comm_page->sample_rate = cpu_to_le32(rate);
+		chip->sample_rate = rate;
+		return 0;
+	}
+
+	/* Now, check to see if the required ASIC is loaded */
+	if (rate >= 88200) {
+		if (chip->digital_mode == DIGITAL_MODE_ADAT)
+			return -EINVAL;
+		if (chip->device_id == DEVICE_ID_56361)
+			asic = &card_fw[FW_MONA_361_1_ASIC96];
+		else
+			asic = &card_fw[FW_MONA_301_1_ASIC96];
+	} else {
+		if (chip->device_id == DEVICE_ID_56361)
+			asic = &card_fw[FW_MONA_361_1_ASIC48];
+		else
+			asic = &card_fw[FW_MONA_301_1_ASIC48];
+	}
+
+	force_write = 0;
+	if (asic != chip->asic_code) {
+		int err;
+		/* Load the desired ASIC (load_asic_generic() can sleep) */
+		spin_unlock_irq(&chip->lock);
+		err = load_asic_generic(chip, DSP_FNC_LOAD_MONA_PCI_CARD_ASIC,
+					asic);
+		spin_lock_irq(&chip->lock);
+
+		if (err < 0)
+			return err;
+		chip->asic_code = asic;
+		force_write = 1;
+	}
+
+	/* Compute the new control register value */
+	clock = 0;
+	control_reg = le32_to_cpu(chip->comm_page->control_register);
+	control_reg &= GML_CLOCK_CLEAR_MASK;
+	control_reg &= GML_SPDIF_RATE_CLEAR_MASK;
+
+	switch (rate) {
+	case 96000:
+		clock = GML_96KHZ;
+		break;
+	case 88200:
+		clock = GML_88KHZ;
+		break;
+	case 48000:
+		clock = GML_48KHZ | GML_SPDIF_SAMPLE_RATE1;
+		break;
+	case 44100:
+		clock = GML_44KHZ;
+		/* Professional mode */
+		if (control_reg & GML_SPDIF_PRO_MODE)
+			clock |= GML_SPDIF_SAMPLE_RATE0;
+		break;
+	case 32000:
+		clock = GML_32KHZ | GML_SPDIF_SAMPLE_RATE0 |
+			GML_SPDIF_SAMPLE_RATE1;
+		break;
+	case 22050:
+		clock = GML_22KHZ;
+		break;
+	case 16000:
+		clock = GML_16KHZ;
+		break;
+	case 11025:
+		clock = GML_11KHZ;
+		break;
+	case 8000:
+		clock = GML_8KHZ;
+		break;
+	default:
+		DE_ACT(("set_sample_rate: %d invalid!\n", rate));
+		return -EINVAL;
+	}
+
+	control_reg |= clock;
+
+	chip->comm_page->sample_rate = cpu_to_le32(rate);	/* ignored by the DSP */
+	chip->sample_rate = rate;
+	DE_ACT(("set_sample_rate: %d clock %d\n", rate, clock));
+
+	return write_control_reg(chip, control_reg, force_write);
+}
+
+
+
+static int set_input_clock(struct echoaudio *chip, u16 clock)
+{
+	u32 control_reg, clocks_from_dsp;
+	int err;
+
+	DE_ACT(("set_input_clock:\n"));
+
+	/* Prevent two simultaneous calls to switch_asic() */
+	if (atomic_read(&chip->opencount))
+		return -EAGAIN;
+
+	/* Mask off the clock select bits */
+	control_reg = le32_to_cpu(chip->comm_page->control_register) &
+		GML_CLOCK_CLEAR_MASK;
+	clocks_from_dsp = le32_to_cpu(chip->comm_page->status_clocks);
+
+	switch (clock) {
+	case ECHO_CLOCK_INTERNAL:
+		DE_ACT(("Set Mona clock to INTERNAL\n"));
+		chip->input_clock = ECHO_CLOCK_INTERNAL;
+		return set_sample_rate(chip, chip->sample_rate);
+	case ECHO_CLOCK_SPDIF:
+		if (chip->digital_mode == DIGITAL_MODE_ADAT)
+			return -EAGAIN;
+		spin_unlock_irq(&chip->lock);
+		err = switch_asic(chip, clocks_from_dsp &
+				  GML_CLOCK_DETECT_BIT_SPDIF96);
+		spin_lock_irq(&chip->lock);
+		if (err < 0)
+			return err;
+		DE_ACT(("Set Mona clock to SPDIF\n"));
+		control_reg |= GML_SPDIF_CLOCK;
+		if (clocks_from_dsp & GML_CLOCK_DETECT_BIT_SPDIF96)
+			control_reg |= GML_DOUBLE_SPEED_MODE;
+		else
+			control_reg &= ~GML_DOUBLE_SPEED_MODE;
+		break;
+	case ECHO_CLOCK_WORD:
+		DE_ACT(("Set Mona clock to WORD\n"));
+		spin_unlock_irq(&chip->lock);
+		err = switch_asic(chip, clocks_from_dsp &
+				  GML_CLOCK_DETECT_BIT_WORD96);
+		spin_lock_irq(&chip->lock);
+		if (err < 0)
+			return err;
+		control_reg |= GML_WORD_CLOCK;
+		if (clocks_from_dsp & GML_CLOCK_DETECT_BIT_WORD96)
+			control_reg |= GML_DOUBLE_SPEED_MODE;
+		else
+			control_reg &= ~GML_DOUBLE_SPEED_MODE;
+		break;
+	case ECHO_CLOCK_ADAT:
+		DE_ACT(("Set Mona clock to ADAT\n"));
+		if (chip->digital_mode != DIGITAL_MODE_ADAT)
+			return -EAGAIN;
+		control_reg |= GML_ADAT_CLOCK;
+		control_reg &= ~GML_DOUBLE_SPEED_MODE;
+		break;
+	default:
+		DE_ACT(("Input clock 0x%x not supported for Mona\n", clock));
+		return -EINVAL;
+	}
+
+	chip->input_clock = clock;
+	return write_control_reg(chip, control_reg, TRUE);
+}
+
+
+
+static int dsp_set_digital_mode(struct echoaudio *chip, u8 mode)
+{
+	u32 control_reg;
+	int err, incompatible_clock;
+
+	/* Set clock to "internal" if it's not compatible with the new mode */
+	incompatible_clock = FALSE;
+	switch (mode) {
+	case DIGITAL_MODE_SPDIF_OPTICAL:
+	case DIGITAL_MODE_SPDIF_RCA:
+		if (chip->input_clock == ECHO_CLOCK_ADAT)
+			incompatible_clock = TRUE;
+		break;
+	case DIGITAL_MODE_ADAT:
+		if (chip->input_clock == ECHO_CLOCK_SPDIF)
+			incompatible_clock = TRUE;
+		break;
+	default:
+		DE_ACT(("Digital mode not supported: %d\n", mode));
+		return -EINVAL;
+	}
+
+	spin_lock_irq(&chip->lock);
+
+	if (incompatible_clock) {	/* Switch to 48KHz, internal */
+		chip->sample_rate = 48000;
+		set_input_clock(chip, ECHO_CLOCK_INTERNAL);
+	}
+
+	/* Clear the current digital mode */
+	control_reg = le32_to_cpu(chip->comm_page->control_register);
+	control_reg &= GML_DIGITAL_MODE_CLEAR_MASK;
+
+	/* Tweak the control reg */
+	switch (mode) {
+	case DIGITAL_MODE_SPDIF_OPTICAL:
+		control_reg |= GML_SPDIF_OPTICAL_MODE;
+		break;
+	case DIGITAL_MODE_SPDIF_RCA:
+		/* GML_SPDIF_OPTICAL_MODE bit cleared */
+		break;
+	case DIGITAL_MODE_ADAT:
+		/* If the current ASIC is the 96KHz ASIC, switch the ASIC
+		   and set to 48 KHz */
+		if (chip->asic_code == &card_fw[FW_MONA_361_1_ASIC96] ||
+		    chip->asic_code == &card_fw[FW_MONA_301_1_ASIC96]) {
+			set_sample_rate(chip, 48000);
+		}
+		control_reg |= GML_ADAT_MODE;
+		control_reg &= ~GML_DOUBLE_SPEED_MODE;
+		break;
+	}
+
+	err = write_control_reg(chip, control_reg, FALSE);
+	spin_unlock_irq(&chip->lock);
+	if (err < 0)
+		return err;
+	chip->digital_mode = mode;
+
+	DE_ACT(("set_digital_mode to %d\n", mode));
+	return incompatible_clock;
+}
diff --git a/sound/pci/emu10k1/p17v.h b/sound/pci/emu10k1/p17v.h
new file mode 100644
index 000000000..7ddb5be63
--- /dev/null
+++ b/sound/pci/emu10k1/p17v.h
@@ -0,0 +1,111 @@
+/*
+ *  Copyright (c) by James Courtier-Dutton <James@superbug.demon.co.uk>
+ *  Driver p17v chips
+ *  Version: 0.01
+ *
+ *   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
+ *
+ */
+
+/******************************************************************************/
+/* Audigy2Value Tina (P17V) pointer-offset register set,
+ * accessed through the PTR20 and DATA24 registers  */
+/******************************************************************************/
+
+/* 00 - 07: Not used */
+#define P17V_PLAYBACK_FIFO_PTR	0x08	/* Current playback fifo pointer
+					 * and number of sound samples in cache.
+					 */  
+/* 09 - 12: Not used */
+#define P17V_CAPTURE_FIFO_PTR	0x13	/* Current capture fifo pointer
+					 * and number of sound samples in cache.
+					 */  
+/* 14 - 17: Not used */
+#define P17V_PB_CHN_SEL		0x18	/* P17v playback channel select */
+#define P17V_SE_SLOT_SEL_L	0x19	/* Sound Engine slot select low */
+#define P17V_SE_SLOT_SEL_H	0x1a	/* Sound Engine slot select high */
+/* 1b - 1f: Not used */
+/* 20 - 2f: Not used */
+/* 30 - 3b: Not used */
+#define P17V_SPI		0x3c	/* SPI interface register */
+#define P17V_I2C_ADDR		0x3d	/* I2C Address */
+#define P17V_I2C_0		0x3e	/* I2C Data */
+#define P17V_I2C_1		0x3f	/* I2C Data */
+
+#define P17V_START_AUDIO	0x40	/* Start Audio bit */
+/* 41 - 47: Reserved */
+#define P17V_START_CAPTURE	0x48	/* Start Capture bit */
+#define P17V_CAPTURE_FIFO_BASE	0x49	/* Record FIFO base address */
+#define P17V_CAPTURE_FIFO_SIZE	0x4a	/* Record FIFO buffer size */
+#define P17V_CAPTURE_FIFO_INDEX	0x4b	/* Record FIFO capture index */
+#define P17V_CAPTURE_VOL_H	0x4c	/* P17v capture volume control */
+#define P17V_CAPTURE_VOL_L	0x4d	/* P17v capture volume control */
+/* 4e - 4f: Not used */
+/* 50 - 5f: Not used */
+#define P17V_SRCSel		0x60	/* SRC48 and SRCMulti sample rate select
+					 * and output select
+					 */
+#define P17V_MIXER_AC97_10K1_VOL_L	0x61	/* 10K to Mixer_AC97 input volume control */
+#define P17V_MIXER_AC97_10K1_VOL_H	0x62	/* 10K to Mixer_AC97 input volume control */
+#define P17V_MIXER_AC97_P17V_VOL_L	0x63	/* P17V to Mixer_AC97 input volume control */
+#define P17V_MIXER_AC97_P17V_VOL_H	0x64	/* P17V to Mixer_AC97 input volume control */
+#define P17V_MIXER_AC97_SRP_REC_VOL_L	0x65	/* SRP Record to Mixer_AC97 input volume control */
+#define P17V_MIXER_AC97_SRP_REC_VOL_H	0x66	/* SRP Record to Mixer_AC97 input volume control */
+/* 67 - 68: Reserved */
+#define P17V_MIXER_Spdif_10K1_VOL_L	0x69	/* 10K to Mixer_Spdif input volume control */
+#define P17V_MIXER_Spdif_10K1_VOL_H	0x6A	/* 10K to Mixer_Spdif input volume control */
+#define P17V_MIXER_Spdif_P17V_VOL_L	0x6B	/* P17V to Mixer_Spdif input volume control */
+#define P17V_MIXER_Spdif_P17V_VOL_H	0x6C	/* P17V to Mixer_Spdif input volume control */
+#define P17V_MIXER_Spdif_SRP_REC_VOL_L	0x6D	/* SRP Record to Mixer_Spdif input volume control */
+#define P17V_MIXER_Spdif_SRP_REC_VOL_H	0x6E	/* SRP Record to Mixer_Spdif input volume control */
+/* 6f - 70: Reserved */
+#define P17V_MIXER_I2S_10K1_VOL_L	0x71	/* 10K to Mixer_I2S input volume control */
+#define P17V_MIXER_I2S_10K1_VOL_H	0x72	/* 10K to Mixer_I2S input volume control */
+#define P17V_MIXER_I2S_P17V_VOL_L	0x73	/* P17V to Mixer_I2S input volume control */
+#define P17V_MIXER_I2S_P17V_VOL_H	0x74	/* P17V to Mixer_I2S input volume control */
+#define P17V_MIXER_I2S_SRP_REC_VOL_L	0x75	/* SRP Record to Mixer_I2S input volume control */
+#define P17V_MIXER_I2S_SRP_REC_VOL_H	0x76	/* SRP Record to Mixer_I2S input volume control */
+/* 77 - 78: Reserved */
+#define P17V_MIXER_AC97_ENABLE		0x79	/* Mixer AC97 input audio enable */
+#define P17V_MIXER_SPDIF_ENABLE		0x7A	/* Mixer SPDIF input audio enable */
+#define P17V_MIXER_I2S_ENABLE		0x7B	/* Mixer I2S input audio enable */
+#define P17V_AUDIO_OUT_ENABLE		0x7C	/* Audio out enable */
+#define P17V_MIXER_ATT			0x7D	/* SRP Mixer Attenuation Select */
+#define P17V_SRP_RECORD_SRR		0x7E	/* SRP Record channel source Select */
+#define P17V_SOFT_RESET_SRP_MIXER	0x7F	/* SRP and mixer soft reset */
+
+#define P17V_AC97_OUT_MASTER_VOL_L	0x80	/* AC97 Output master volume control */
+#define P17V_AC97_OUT_MASTER_VOL_H	0x81	/* AC97 Output master volume control */
+#define P17V_SPDIF_OUT_MASTER_VOL_L	0x82	/* SPDIF Output master volume control */
+#define P17V_SPDIF_OUT_MASTER_VOL_H	0x83	/* SPDIF Output master volume control */
+#define P17V_I2S_OUT_MASTER_VOL_L	0x84	/* I2S Output master volume control */
+#define P17V_I2S_OUT_MASTER_VOL_H	0x85	/* I2S Output master volume control */
+/* 86 - 87: Not used */
+#define P17V_I2S_CHANNEL_SWAP_PHASE_INVERSE	0x88	/* I2S out mono channel swap
+							 * and phase inverse */
+#define P17V_SPDIF_CHANNEL_SWAP_PHASE_INVERSE	0x89	/* SPDIF out mono channel swap
+							 * and phase inverse */
+/* 8A: Not used */
+#define P17V_SRP_P17V_ESR		0x8B	/* SRP_P17V estimated sample rate and rate lock */
+#define P17V_SRP_REC_ESR		0x8C	/* SRP_REC estimated sample rate and rate lock */
+#define P17V_SRP_BYPASS			0x8D	/* srps channel bypass and srps bypass */
+/* 8E - 92: Not used */
+#define P17V_I2S_SRC_SEL		0x93	/* I2SIN mode sel */
+
+
+
+
+
+
diff --git a/sound/pci/hda/patch_atihdmi.c b/sound/pci/hda/patch_atihdmi.c
new file mode 100644
index 000000000..a27440ffd
--- /dev/null
+++ b/sound/pci/hda/patch_atihdmi.c
@@ -0,0 +1,165 @@
+/*
+ * Universal Interface for Intel High Definition Audio Codec
+ *
+ * HD audio interface patch for ATI HDMI codecs
+ *
+ * Copyright (c) 2006 ATI Technologies Inc.
+ *
+ *
+ *  This driver 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 driver 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 <sound/driver.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/slab.h>
+#include <linux/pci.h>
+#include <sound/core.h>
+#include "hda_codec.h"
+#include "hda_local.h"
+
+struct atihdmi_spec {
+	struct hda_multi_out multiout;
+
+	struct hda_pcm pcm_rec;
+};
+
+static struct hda_verb atihdmi_basic_init[] = {
+	/* enable digital output on pin widget */
+	{ 0x03, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
+	{} /* terminator */
+};
+
+/*
+ * Controls
+ */
+static int atihdmi_build_controls(struct hda_codec *codec)
+{
+	struct atihdmi_spec *spec = codec->spec;
+	int err;
+
+	err = snd_hda_create_spdif_out_ctls(codec, spec->multiout.dig_out_nid);
+	if (err < 0)
+		return err;
+
+	return 0;
+}
+
+static int atihdmi_init(struct hda_codec *codec)
+{
+	snd_hda_sequence_write(codec, atihdmi_basic_init);
+	return 0;
+}
+
+#ifdef CONFIG_PM
+/*
+ * resume
+ */
+static int atihdmi_resume(struct hda_codec *codec)
+{
+	atihdmi_init(codec);
+	snd_hda_resume_spdif_out(codec);
+
+	return 0;
+}
+#endif
+
+/*
+ * Digital out
+ */
+static int atihdmi_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
+				     struct hda_codec *codec,
+				     struct snd_pcm_substream *substream)
+{
+	struct atihdmi_spec *spec = codec->spec;
+	return snd_hda_multi_out_dig_open(codec, &spec->multiout);
+}
+
+static int atihdmi_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
+				      struct hda_codec *codec,
+				      struct snd_pcm_substream *substream)
+{
+	struct atihdmi_spec *spec = codec->spec;
+	return snd_hda_multi_out_dig_close(codec, &spec->multiout);
+}
+
+static struct hda_pcm_stream atihdmi_pcm_digital_playback = {
+	.substreams = 1,
+	.channels_min = 2,
+	.channels_max = 2,
+	.nid = 0x2, /* NID to query formats and rates and setup streams */
+	.ops = {
+		.open = atihdmi_dig_playback_pcm_open,
+		.close = atihdmi_dig_playback_pcm_close
+	},
+};
+
+static int atihdmi_build_pcms(struct hda_codec *codec)
+{
+	struct atihdmi_spec *spec = codec->spec;
+	struct hda_pcm *info = &spec->pcm_rec;
+
+	codec->num_pcms = 1;
+	codec->pcm_info = info;
+
+	info->name = "ATI HDMI";
+	info->stream[SNDRV_PCM_STREAM_PLAYBACK] = atihdmi_pcm_digital_playback;
+
+	return 0;
+}
+
+static void atihdmi_free(struct hda_codec *codec)
+{
+	kfree(codec->spec);
+}
+
+static struct hda_codec_ops atihdmi_patch_ops = {
+	.build_controls = atihdmi_build_controls,
+	.build_pcms = atihdmi_build_pcms,
+	.init = atihdmi_init,
+	.free = atihdmi_free,
+#ifdef CONFIG_PM
+	.resume = atihdmi_resume,
+#endif
+};
+
+static int patch_atihdmi(struct hda_codec *codec)
+{
+	struct atihdmi_spec *spec;
+
+	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
+	if (spec == NULL)
+		return -ENOMEM;
+
+	codec->spec = spec;
+
+	spec->multiout.num_dacs = 0;	  /* no analog */
+	spec->multiout.max_channels = 2;
+	spec->multiout.dig_out_nid = 0x2; /* NID for copying analog to digital,
+					   * seems to be unused in pure-digital
+					   * case. */
+
+	codec->patch_ops = atihdmi_patch_ops;
+
+	return 0;
+}
+
+/*
+ * patch entries
+ */
+struct hda_codec_preset snd_hda_preset_atihdmi[] = {
+	{ .id = 0x1002793c, .name = "ATI RS600 HDMI", .patch = patch_atihdmi },
+	{} /* terminator */
+};